Drupal - Как обновить поле CCK NodeReference программно?

Я пытаюсь создать узел (B тип) и присвоить его CCK узла типа nodereference поле с помощью node_save () метод.

$node_type_A = node_load($some_nid);
$node_type_A->field_type_B_node_ref[]['nid'] = $node_type_B_nid;

$node_type_A = node_submit($node_type_A);
node_save($node_type_A);

Как результат, будет создан новый узел типа B, но никакая ссылка не будет присвоена узел типа. любая справка ценилась бы.

7
задан 27 April 2010 в 17:42
поделиться

4 ответа

GApple прав, формат правильный, но есть пара вещей, которые могут вас заинтересовать.

Значение дельты
Сначала вам нужно знать значение дельты последней ссылки на узел, прикрепленной к $ node_type_A , дельта на самом деле является частичным index, в сочетании с полем vid в $ node_type_A , они становятся индексом для таблицы ссылок на узлы в базе данных. Другими словами, это счетчик для $ node_type_B , на которые есть ссылка в $ node_type_A , хорошо?

GApple снова прав, вы должны точно сказать, куда добавить новую ссылку. Когда вы получили значение дельта , вы можете точно сказать, куда добавить (дельта + 1) новую ссылку. Вот он:

function get_current_delta($node_vid){
    return db_result(db_query("SELECT delta FROM {content_field_type_A_node_ref}
                               WHERE vid = '%d'
                               ORDER BY delta DESC
                               LIMIT 1", $node_vid));
}

Добавление новой ссылки
Мы получили дельта ! поэтому мы можем присоединить новый узел $ node_type_B к нашему узлу $ node_type_A :

// Loading type_A node.
$node_type_A = node_load($some_nid);

// Getting current delta value.
$current_delta = get_current_delta($node_type_A->vid);

// "Appending" a node reference based on delta. 
$node_type_A->field_type_B_node_ref += array($current_delta + 1 => array('nid' => $node_type_B_nid));

Повторное сохранение обновленного узла
При необходимости вызовите node_submit () для заполнения некоторые важные поля в объекте узла и сохраните его, используя node_save () . В конце концов, вам нужно вызвать content_insert () , чтобы полностью сохранить узел вместе с его полями CCK:

// Resaving the updated node.
$node_type_A = node_submit($node_type_A);
node_save($node_type_A);
content_insert($node_type_A);

Очистка кеша содержимого
Вероятно, самая важная часть, это убило меня из-за пару дней.CCK имеет кеш-таблицу в базе данных под названием cache_content (посмотрите на ее структуру) , после повторного сохранения обновленного узла вы заметите, что ничего не изменилось в $ node_type_A ] вывод темы, даже если таблицы обновлены. Мы должны удалить запись из этой таблицы кэша контента, это заставит Drupal показать последний снимок данных. Вы можете определить следующее как функцию:

db_query("DELETE FROM {cache_content} WHERE cid = '%s'", 'content:' . $node_type_A->nid . ':' . $node_type_A->vid);

Надеюсь, это поможет;)

6
ответ дан 6 December 2019 в 19:34
поделиться

Я показываю CCK, сохраняющий ссылки на узлы как $ node-> field_node_reference [0] ['items'] [0] ['nid'] , а не $ node-> field_node_reference [0] ['nid'] . Вы пробовали имитировать это?

0
ответ дан 6 December 2019 в 19:34
поделиться

Я только что проверил один из моих собственных модулей, который делает что-то подобное для формата объекта, и $ node_type_A-> field_type_B_node_ref [] ['nid'] должно быть правильным.

Следует проверить, что при загрузке узла CCK может предварительно заполнить массив ссылок узла пустым значением. Если вы настроили поле, чтобы разрешить только одно значение, с помощью оператора добавления массива ( field_type_B_node_ref [] ) будет создана вторая запись, которая будет проигнорирована ( field_type_B_node_ref [1] ) вместо перезаписи существующего значения ( field_type_B_node_ref [0] ). Если возможно, попробуйте явно указать ключ массива.

4
ответ дан 6 December 2019 в 19:34
поделиться

«Очистка кеша содержимого» Это работает для меня, особенно если вы получаете данные из node_load ()

0
ответ дан 6 December 2019 в 19:34
поделиться
Другие вопросы по тегам:

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