How to create Field Collection Item by code in Drupal 8 - drupal

How to create a Field Collection item for a node by program in Drupal 8. I have tried with below code, but it doesn't work. 'field_abc_inside' is the field of the Field Collection 'field_abc'.
$field_collection_item = entity_create('field_collection_item', array(
'field_name' => 'field_abc',
'field_abc_inside' => array('value'=> 'Test data'),
));
$field_collection_item->setHostEntity($node);
$field_collection_item->save();

$user_id = \Drupal::currentUser()->getAccount()->id();
$user = User::load($user_id);
$fc = FieldCollectionItem::create(array(
"field_name" => "field_hobbies",
));
$fc->set('field_hobby_name', 'Watch TV');
$fc->setHostEntity($user);

That code helped me but I have one observation.
\Drupal::currentUser() is the user object, which is clear since it is using it to retrieve the id().
Therefore no need to User::load() it again in line 2, redundant processing that will cause the function to take longer to run.
// Get the current user object
$user = \Drupal::currentUser();
// Prepare the new Field Collection Item object
$fc = FieldCollectionItem::create(array(
"field_name" => "field_hobbies",
));
// Sets more field values
$fc->set('field_hobby_name', 'Watch TV');
// Sets the host record; where the field collection will be attached into
$fc->setHostEntity($user);
// Saves it into an actual field collection record
$fc->save();

Related

Use VBO in Drupal to update custom user field

I want to perform bulk update of users with a Approved users, the table
field_user_status_value
-----------------------
entity_type, entity_id, field_user_status_value
The entity_id is the user id which does not exist in the table, below is the custom module I wrote to update the table:
function bulkapprove_action_info() {
return array(
'bulkapprove_action_callback_name' => array(
'type' => 'user', // Can be file, term, user, etc.
'label' => t('Approve User'),
'configurable' => FALSE, // Doesn't need config form
'behavior' => array('view_property'), // Uses view access rights ,
'pass rows' => TRUE,
'triggers' => array('any'), // Works always
),
);
}
function bulkapprove_action_callback_name($entity, $context)
{
db_update('field_data_field_user_status')->fields(array('field_user_status_value' => 'Approved'))->condition('entity_id', $context->entity_id)->execute();
}
But it is not inserting the values in this table
In Drupal you do not want to update the database fields directly unless you created the table. Drupal's internal APIs provide a collection of tools to ensure you update the values correctly and that all supporting modules get notified of changes as needed through the hook system.
In this case the callback gets the actual entity to run your action against (in this case the user object). You want to take action on that entity and then save the entity.
function bulkapprove_action_callback_name($entity, $context)
{
$entity->status = 1;
entity_save('user', $entity);
}

How to add / update a field collection without updating parent node/entity drupal 7

I needed to to add / update field collections to node entities without updating the node entities. I tried two ways listed in https://www.drupal.org/node/1842304 and http://alexrayu.com/blog/saveupdate-field-collection-without-nodesave but none of them seems to be working exactly the way I want.
I tried as follows:
$node = node_load($nid);
$field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_college_rating_data'));
$field_collection_item->setHostEntity('node', $node);
$field_collection_item->field_text1['und'][0]['tid'] = $form_state['input']['field_text1']['und'];
$field_collection_item->field_text2['und'][0]['value'] = $form_state['input']['field_text2']['und'];
$field_collection_item->save();
It added a field collection but it updates the node.
I also tried to alter the field collection form submit and used custom submit handler as follows:
function own_custom_field_collection_submit($form,$form_state) {
$field_collection_item = field_collection_item_form_submit_build_field_collection($form, $form_state);
$field_collection_item->save(TRUE);
drupal_set_message(t('The changes have been saved.'));
$form_state['redirect'] = $field_collection_item->path();
}
I have copied this code from core field collection module to change the default argument to "TRUE" in the save function. It added the field collection but didn't associated with the parent node.
I need to save the field collection separately since my node entity form is very large with 50 to 60 fields and field collections and I don't want to update it as many times as I add / update any field collections to the node.
Any help will be much appreciated.
Thanks
You have to pragmatically relate your field collection to the host entity by the following code.
$field_collection_item = field_collection_item_form_submit_build_field_collection($form, $form_state);
$field_collection_item->save(TRUE);
$host_entity = $field_collection_item->hostEntity();
$lang = 'und';
if (isset($host_entity->nid) && isset($host_entity->vid) && isset($lang) && isset($field_collection_item->item_id) && isset($field_collection_item->revision_id)) {
$query = db_select('field_data_field_text1', 'fd');
$query->addExpression('max(fd.delta)', 'total_row');
$query->condition('fd.entity_id', $host_entity->nid);
$max_delta = $query->execute()->fetchField();
if (isset($max_delta)) {
$max_delta = $max_delta + 1;
} else {
$max_delta = 0;
}
db_insert('field_data_{field_collection}')->fields(array(
'entity_type' => 'node',
'bundle' => '{node_type}',
'entity_id' => $host_entity->nid,
'revision_id' => $host_entity->vid,
'language' => $lang,
'delta' => $max_delta,
'field_text' => $field_collection_item->item_id,
'field_text_revision_id' => $field_collection_item->revision_id
))
->execute();
}
Replace your content type and field type in { } and then you just have your field collection relate to your host entity.
Thanks

Drupal custom user registration form

I have built a custom registration form using module_form_alter hook. I have also added the required new fields to the database with db_add_field. Now I'm able to add the values to the table in user registration/ user profile edit and the values are also getting stored in the database.. But what I'm not able to do is get the values that are stored in the database in the user profile edit form is displayed. Is there a hook to load the values from database to form on form load? Or is there any other way?
function customUser_schema_alter(&$schema) {
// Add field to existing schema.
$schema['users']['fields']['detail'] = array(
'type' => 'varchar',
'length' => 100,
);
}
function customUser_install() {
$schema = drupal_get_schema('users');
db_add_field('users', 'detail', $schema['fields']['detail']);
}
function customUser_form_alter(&$form, &$form_state, $form_id) {
// check to see if the form is the user registration or user profile form
// if not then return and don’t do anything
if (!($form_id == 'user_register_form' || $form_id == 'user_profile_form')) {
return;
}
$form['account']['detail'] = array(
'#type' => 'textfield',
'#title' => t('Additional Detail'),
);
}
A proper answer needs more details. I can only assume what you did.
You added fields to the {users} table. You didn't update the database schema which made drupal_write_record not be aware of the new fields, that being the reason they are not populated.
You created a new table {my_table} with the fields.
In both cases you need hook_user_insert()
/**
* Implements hook_user_insert().
*/
function mymodule_user_insert(&$edit, $account, $category) {
// Here you add the code to update the entry in {users} table,
// or int your custom table.
// $edit has the values from the form, $account->uid has the
// uid of the newly created user.
}
Note: If my first assumption is true that's not the drupal way to do it. You should have done the 2nd way instead. And even in that case use the hook_schema to create your table in mymodule.install instead of doing db_add_field().
For drupal 7 you could have uses the profile module (core) or profile2 to achieve that.
Based on that code
Try to change to this inside the form alter.
$account = $form['#user'];
$form['account']['detail'] = array(
'#type' => 'textfield',
'#title' => t('Additional Detail'),
'#default_value' => $account->detail,
);

Change fields in node from code

How do I access the fields in a node in Drupal 7.
I have tried this but that do not work.
$node=node_load($nid);
$node->field_num[LANGUAGE_NONE][0]['value']=$num;
I think I have to be more specific:
I first create a node and set values on some fields like this:
$values = array(
'type' => 'scorings',
'uid' => $user->uid,
'status' => 1,
'comment' => 0,
'promote' => 0,
);
$entity = entity_create('node', $values);
$ewrapper = entity_metadata_wrapper('node', $entity);
$entity->field_rond_nid[LANGUAGE_NONE][0]['value']=$nid_scorekort;
$entity->field_golfid[LANGUAGE_NONE][0]['value']=$form_state['values']['golfid_1'];
$ewrapper->save(true);
entity_save('node', $entity);
$nid=$entity->nid;
This works fine. Then I want to access this node from another function (passing the nid to it) end set value to another field (field_score_1). I have tried this:
$node=node_load($nid, 'my_content type');
$node->field_score_1[LANGUAGE_NONE][]['value'] = $my_value;
But this do not work. Seams that node_load do not give me access to the fields.
Your node_load() call is incorrect.
From the Drupal API documentation for node_load() the function declaration is:
node.module node_load($nid = NULL, $vid = NULL, $reset = FALSE)
Your second parameter is a string, not a number, as $vid would be.
If node_load() returns a FALSE then it failed.
Perhaps you were wanting to use EntityFieldQuery() instead?

calling user_save from within hook_init failing on Drupal6

I have a module that implements hook_init.
Within that I have a case where I try to call user_save like save
user_save ('');
I figure this should work since I am not setting a uid, so it should create a new one. It also says that the $array should be allowed to be empty.
However, this always returns FALSE. ??
I have also tried setting these values in $array but this doesn't work either:
$foo = array(
'name' => 'the new user',
'mail' => 'the new user mail',
'pass' => user_password(),
'status' => 1,
);
$new_user = user_save ('', $foo);
Look at the documentation:
Parameters
$account The $user object for the user to modify or add. If $user->uid is omitted, a new user will be added.
$array (optional) An array of fields and values to save. For example, array('name' => 'My name'); Setting a field to NULL deletes it from the data column.
So when you call user_save() the first parameter must be a user object. If that user object doesn't have a uid, or is a string like in your case, a new user will be created. Here the 2nd parameter is necessary. It's not required to use the function, but as it holds all the values you want to save, you wont get far trying to create a user with no data at all. What use is a user without password, username etc. So a minimum of data is required as well, so Drupal will know what to save.

Resources