Drupal - Как программно обновить поле CCK NodeReference? - PullRequest
7 голосов
/ 27 апреля 2010

Я пытаюсь создать узел (тип B) и назначить его для поля ссылки на узел CCK узла типа A, используя метод 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, но ссылка на узел типа A не будет назначена. любая помощь будет оценена.

Ответы [ 5 ]

6 голосов
/ 05 мая 2010

GApple правильно, формат правильный, но есть пара вещей, о которых вы можете позаботиться.

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

GApple снова верно, вы должны точно сказать, куда добавить новую ссылку. Получив это значение delta , вы можете точно сказать, куда добавить (delta + 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);

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

4 голосов
/ 27 апреля 2010

Я только что проверил один из моих собственных модулей, который делает что-то похожее для формата объекта, и $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]) , Попробуйте явно указать ключ массива, если это возможно.

3 голосов
/ 31 марта 2012

Отличный пост, но одно исправление: не очищайте записи в кеше, запрашивая базу данных вручную. Если кто-то использует memcache или любой другой внешний кеш, он потерпит неудачу.

cache_clear_all () ваш друг для очистки.

Предлагаемый код, прямо из модуля CCK:

cache_clear_all('content:'. $node_type_A->nid .':'. $node_type_A->vid, content_cache_tablename());
0 голосов
/ 24 мая 2010

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

0 голосов
/ 27 апреля 2010

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

...