alekseyasherbondarenko
@alekseyasherbondarenko

Как программно в drupal7 предзаполнить множественное поле несколькими Items типа FieldColelction при создании нового материала?

Я потратил много времени чтобы найти решение следующей задачи
Есть тип материала: $node->type == 'product_template'
скриншот: Product_template%20%7C%20Drupal%20Defaul
Каждый элемент (Item) в Field Сollection (field_properties) состоит из - скриншот: Field%20collection%20field_properties%20

Задача: программно сделать, чтобы при добавлении новой ноды этого типа материала
в форме добавления было так как на скриншоте: Create%20Product_template%20%7C%20Drupal
из гугла нарыл вот этот материал: drupal.cocomore.com/blog/field-collections-exposed
но не получается, слишком много куда нужно сохранить привязки в структурах массивов $form и $form_state
Пример моего кода который альтерит форму добавления материала и добавляет как в шаблонной ноде 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;
              }
            }
         }

    }

  }

}

но при попытке сохранить или добавить очередной элемент в FieldCollection выскакивает ошибка
  • Вопрос задан
  • 2852 просмотра
Решения вопроса 1
alekseyasherbondarenko
@alekseyasherbondarenko Автор вопроса
Нашел решение самостоятельно - может кому пригодится.
1) создаем новую ноду которая будет служить в качестве заготовки с предустановленным набором элементов в
$node_template->field_properties['und'][0..2] у меня три свойства для продукта по умолчанию
$node_template->nid==22
2) Хардкодно присваиваем эту же структуру объекту создаваемой ноды (еще без ее nid) в хуке:
/**
 * 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;
    }
  }

}


Смотреть результат: Create%20Product%20%7C%20Drupal%20Defaul

Сделаю до ума поделюсь модулем. dev-alexmazaltov.pantheon.io
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы