Программное заполнение полей

Главные вкладки

Аватар пользователя molp molp 21 мая 2016 в 9:29

upd: Все зашло слишком далеко. Можно читать с этого комментария.

Вообще задача заключается в том чтобы после создания материала типа B, прикрепить его к ранее созданному материалу типа A.

Я написал правило rules, которое реагирует на событие создания нового материала типа A и в action "Execute custom PHP code" программно создает материал типа B.

Пишу правило (в том же самом rules добавляю второй action "Execute custom PHP code"), которое после создания материала типа B, прикрепит его к материалу типа A, указав в поле Entity Reference - Autocomplete его заголовок.

<?php
$nid 
$node->nid;
$node node_load($nid);
$node->field_test['und'][0]['value'] = '[node:title]'// Для тестового <em>Text - Text field</em>
$node->field_location['und'][0]['target_id'] = '[node:title]'// Для <em>Entity Reference - Autocomplete</em>
node_save($node);
?>

Данный код прекрасно работает с обычным текстовым полем, подставляя значение и сохраняя материал, но с полем Entity Reference - Autocomplete получаю ошибку:

PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: 'Title' for column 'field_location_target_id' at row 1: INSERT INTO {field_data_field_location} (entity_type, entity_id, revision_id, bundle, delta, language, field_location_target_id) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6); Array ( [:db_insert_placeholder_0] => node [:db_insert_placeholder_1] => 136 [:db_insert_placeholder_2] => 136 [:db_insert_placeholder_3] => server [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => und [:db_insert_placeholder_6] => Title ) in field_sql_storage_field_storage_write() (line 514 of C:\OpenServer\domains\domain.local\modules\field\modules\field_sql_storage\field_sql_storage.module).

ps: field_test['und'][0]['value'] и field_location['und'][0]['target_id'] беру из разметки страницы, как значение аргумента name для input

upd: Поле Entity Reference - Autocomplete в коде представлено двумя полями. Возможно в этом дело?

Комментарии

Аватар пользователя molp molp 21 мая 2016 в 11:06

<a href="mailto:sas@drupal.org">sas@drupal.org</a> wrote:

->target_id = nid


Большое спасибо. Получилось!

<?php
$nid 
$node->nid;
$nid2 $nid 1;
$node node_load($nid);
$node->field_location['und'][0]['target_id'] = $nid2;
node_save($node);
?>

Правильно ли я понимаю, что данный способ является совершенно ненадежным из-за способа получения $nid2?

Аватар пользователя gun_dose gun_dose 21 мая 2016 в 14:04
1

А зачем повторно вызавать node_load, если нода уже загружена изначально? Это большой удар по производительности, т.к. есть референсы и эта функция подтянет ноду вместе с референсами и референсами референсов

Аватар пользователя molp molp 21 мая 2016 в 14:46

gun_dose wrote:

А зачем повторно вызавать node_load, если нода уже загружена изначально? Это большой удар по производительности, т.к. есть референсы и эта функция подтянет ноду вместе с референсами и референсами референсов


Спасибо, уберу.
А что касается правила rules для добавления одного материала к другому не подскажете? Потому что мой способ неправильный скорее всего.

Аватар пользователя molp molp 21 мая 2016 в 15:50

Возможно для моей задачи избыточно создание двух типов материала и манипуляции с ними.

Объясню на примере что требуется

1. Создать материал и заполнить поле заголовок "Котопёс"
2. После сохранения получить материал содержащий опрос

  • Скорее кот чем пёс
  • Скорее пёс чем кот
  • Скорее пёсокот чем котопёс

То есть посетитель создает материал, где заполняет одно единственное поле, а вопросы голосования создаются автоматически.

Аватар пользователя molp molp 21 мая 2016 в 19:52

Небольшой прогресс, программно заполняю временными значениями два дефолтных обязательных поля.

<?php
function mymodule_form_node_form_alter(&$form, &$form_state$form_id) {
    if (
$form['type']['#value'] == 'poll') {
        
$form['choice_wrapper']['choice']['new:0']['chtext']['#default_value'] = '1';
        
$form['choice_wrapper']['choice']['new:1']['chtext']['#default_value'] = '2';
    }
}
?>

Ищу способ добавить больше полей с вариантами ответов.

Аватар пользователя molp molp 21 мая 2016 в 19:54

В Rules создал правило, которое после сохранения материала, должно добавить нужные мне варианты ответов в опрос (модуль poll)

<?php
$options 
= array(
  
=> 'vote 1',
  
=> 'vote 2',
  
=> 'vote 3',
  
=> 'vote 4',
);

$node node_load($node->nid);

foreach (

$options as $key=>$value) {
  
$node->choice[$key] = array(
    
'chid' => dechex(time() * rand(550)),
    
'chtext' => $value,
    
'chvotes' => 0,
    
'weight' => $key,
  );
}

node_save($node);
?>
Аватар пользователя molp molp 21 мая 2016 в 19:40

Финишная прямая, последнее препятствие.

Работа производится с материалом модуля poll.

  • При создании материала, пользователь не должен вручную заполнять поля голосования, поэтому я написал мини-модуль который во время создания материала заполняет поля голосования временными значениями http://www.drupal.ru/comment/668957#comment-668957 Эти поля я потом скрою при помощи css.
  • После создания материала у меня срабатывает правило Rules http://www.drupal.ru/comment/668959#comment-668959 которое и должно автоматически создавать поля опроса.

Проблема заключается в том что данное правило не заменяет существующие (временные, созданные модулем) значения, а дописывает новые.
Пробовал очистить при помощи unset($node->choice); вроде чистит массив но после сохранения все ровно остаются временные поля.

Хелп!

Аватар пользователя gun_dose gun_dose 22 мая 2016 в 12:38
1

Ансет свойств объекта ноды действительно чистит только объект. Чтобы удалить поля в базе, полям объекта надо присвоить пустые значения, а не сбрасывать их. А скрывать поля лучше не в цсс, а в настройках отображения. Но учитывая постановку задачи, имеет смысл задуматься об альтере формы создания ноды, чтобы опрос сразу из полей формы делался

Аватар пользователя sas@drupal.org sas@drupal.org 22 мая 2016 в 10:01
1

Создавать и скрывать, чтобы потом переопределить, - не лучший вариант. Создавать надо в нужном месте с нужными значениями. По коду для poll надо смотреть в модуль, но создание нового материала, задача несложная по коду, например:

$node = array(
      'title' => $title,
      'body' => array(LANGUAGE_NONE => array(array('value' => 'test body'))),
      'uid' => $user->uid,
      'type' => 'article',
    );
$node = node_submit((object) $node);