A
A
Alexey Bondarenko2015-01-27 12:38:11
Drupal
Alexey Bondarenko, 2015-01-27 12:38:11

How to programmatically prepopulate a multiple field in drupal7 with several Items of the FieldColelction type when creating a new material?

I spent a lot of time to find a solution to the following problem
There is a material type: $node->type == 'product_template'
screenshot: Product_template%20%7C%20Drupal%20Defaul
Each item (Item) in the Field Сollection (field_properties) consists of - screenshot: field%20collection%20field_properties%20
Task: programmatically make that when adding a new the nodes of this type of material
in the add form were as in the screenshot: Create%20Product_template%20%7C%20Drupal
I dug up this material from Google : drupal.cocomore.com/blog/field-collections-exposed
form_state
An example of my code that alters the form for adding material and adds as in the template node nid==22.

/**
 * Implements hook_form_alter().
 */
function nxte_database_form_alter(&$form, &$form_state, $form_id) {

  if($form_id == 'product_template_node_form'){

    if(!isset($form['nid']['#value'])){
      dsm('is_new');
      dsm($form);
      dsm($form_state);
    
    //unset($form['#node']);
    //unset($form['#entity']);
    //var_dump($form);
    //exit;

        $original_node = node_load(22);

          // Get the fields defined for this node type;
          $node_fields =  field_info_instances('node', $node_type);

          // Re-create the fields for the original node, like when editing it
          $tmpform = array();
          $tmpform['#node'] = $original_node;
          $tmpform['type']['#value'] = $node_type;
          $tmpform_state = array( 'build_info' => array('form_id' => $form['#form_id']) );
          field_attach_form('node', $original_node, $tmpform, $tmpform_state, entity_language('node', $original_node));

          // Here we have on $tmpform the form structure we need and with the default values.
          // We can choose what fields to clone, but in this example we will loop over all the node fields and clone all of them
          foreach($node_fields as $field_name => $field_settings) {
            // Copy the form structure
            $form[$field_name] = $tmpform[$field_name];
            // Copy state information about this field
            $form_state['field'][$field_name] = $tmpform_state['field'][$field_name];

            // When copying the field_collection structure, reset the id of the entities and
            // they will be created again with a new id.
            $langcode = field_language('node', $original_node, $field_name);
            if ($form_state['field'][$field_name][$langcode]['field']['type'] == 'field_collection') {
              $field_childs = &$form_state['field'][$field_name][$langcode]['entity'];
              foreach(element_children($field_childs) as $idx => $fc_entity) {
                $field_childs[$idx]->item_id = NULL;
                $field_childs[$idx]->revision_id = NULL;
              }
            }
         }

    }

  }

}

but when trying to save or add another element to the FieldCollection, an error pops up

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Bondarenko, 2015-01-27
@alekseyasherbondarenko

I found the solution myself - maybe it will be useful to someone.
1) create a new node that will serve as a blank with a preset set of elements in
$node_template->field_properties['und'][0..2] I have three properties for the default product
$node_template->nid==22
2) We hardcode the same structure to the object of the created node (without its nid yet) in the hook:

/**
 * Implements hook_node_prepare().
 */
function nxte_database_node_prepare($node) {
//Изменяем объект ноды перед тем как друпал построит для него форму добавления материала
if($node->type == 'product' && !isset($node->nid)){
  $node_array_hardcoded =array(
      'body' => array(
            'und' => array(
                    0 => array(
                            'value' => 'Description of product',
                            'format' => 'full_html',
                            'safe_value' =>  'Description of product',
                        ),

                ),

        ),
      'field_properties' => array(
            'und' => array(
                    0 => array(
                            'value' => 46, //это значение будет изменено после сохранения новой ноды (сейчас это existing_filed_collection_item_ID)
                            'revision_id' => 46,
                        ),

                    1 => array(
                            'value' => 47, //это значение будет изменено после сохранения новой ноды (сейчас это existing_filed_collection_item_ID)
                            'revision_id' => 47,
                        ),

                    2 => array(
                            'value' => 48, //это значение будет изменено после сохранения новой ноды (сейчас это existing_filed_collection_item_ID)
                            'revision_id' => 48,
                        ),

                ),

        ),

      );
    foreach ($node_array_hardcoded as $key => $value){
      $node->$key = $value;
    }
  }

}

See the result: Create%20Product%20%7C%20Drupal%20Defaul
I will do it to my mind and share the module. dev-alexmazaltov.pantheon.io

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question