Оновлення поля програмно, прив’язка_на_відкриття


13

В даний час намагаються оновлювати поле кожного разу, коли створюється або оновлюється вузол. Однак значення не заповнюється у вузлі, чи маю я доступ до об'єкта вузла саме цим гаком? Що я міг бракувати?

  function vbtoken_node_update($node) {


      entity_get_controller('node')->resetCache(array($node->nid));


      $types = node_type_get_types(); //What are the current Node Content Types?
      $yes = ($types['volunteer_project']->type);

      if($node->type === $yes){


        $hash = md5($node->title . $node->nid . $node->nid);
        $hashed = substr($hash, 0, 6);
        $node = node_load($node->nid);
        $node->tcode[$node->language][0]['value'] = $hashed;
        node_save($node);

        watchdog('vbtoken', 'Added a new Token code to %nid', array('%nid' => $node->nid));

        }
        else 
        {
          dpm('not working dude');
        }

    }

Відповіді:


16

Обгортки метаданих особи

API сутності надає деякі класи обгортки, які ви можете використовувати для легкого спілкування з об'єктами та для використання наданих модулів інформації про властивості сутності. За допомогою обгортки ви можете отримати доступ до інформації про властивості, перевести цикл на відомі властивості або просто отримати / встановити описані значення даних тощо.

Ось кілька простих прикладів використання, знайдених у програмі README:

Для використання цієї інформації (метаданих) модуль надає кілька класів обгортки, які полегшують отримання та встановлення значень. Обгортка підтримує ланцюгове використання для отримання обгортки властивостей об'єкта, наприклад, щоб отримати електронну адресу автора вузла, яку можна використовувати:

$wrapper = entity_metadata_wrapper('node', $node);
$wrapper->author->mail->value();

Для оновлення поштової адреси користувача можна було б скористатися

$wrapper->author->mail->set('sepp@example.com');

або

$wrapper->author->mail = 'sepp@example.com';

Обгортки завжди повертають дані, як описано в інформації про властивості, які можуть бути отримані безпосередньо через entity_get_property_info () або з обгортки:

$mail_info = $wrapper->author->mail->info();

Для того, щоб змусити отримувати текстове значення, деанімоване для виводу, можна використовувати, наприклад

$wrapper->title->value(array('sanitize' => TRUE));

щоб отримати санізований заголовок вузла. Коли властивість уже повертається за замовчуванням, як і тіло вузла, можливо, хоче отримати несанітовані дані, як це було б у браузері для інших випадків використання. Для цього можна ввімкнути опцію 'декодування', яка забезпечує для будь-яких санізованих даних теги позбавлені та HTML-об'єкти розшифровуються перед поверненням властивості:

$wrapper->body->value->value(array('decode' => TRUE));

Таким чином завжди можна отримувати дані, як показано користувачеві. Однак якщо ви дійсно хочете отримати необроблене, необроблене значення, навіть для санітарних текстових даних, це можна зробити за допомогою:

$wrapper->body->value->raw();

Більше прикладів:

$wrapper->body->set(array('value' => "content"));
$wrapper->field_text[0] = 'the text';
$wrapper->field_text[0]->set(array('value' => "content"));
$wrapper->field_text2->summary = 'the summary';
$wrapper->field_text2->value = 'the text';

$wrapper->save();
$wrapper->delete();

Більше документів : http://drupal.org/node/1021556


Дуже дякую. Ваша відповідь допомогла дати мені певний напрямок до того, що я повинен був зробити. :) Громадські скелі !! \ m /
SGhosh

Це буде працювати на kuk_node_update, але не на гачку_node_insert (). Ви отримаєте дублюючу помилку первинного ключа від mysql, оскільки і модуль вузла, і ваш власний код будуть намагатися вставити один і той же вузол двічі (використовуючи той самий ідентифікатор вузла).
leon.nk

14

Телефонування field_attach_update('node', $node)наприкінці hook_node_updateвідпрацьованого для мене. Я припускаю, що field_attach_insert('node', $node)в кінці hook_node_insertбуде теж працювати. Отже, зразок функції виглядатиме так:

function mymodule_node_update($node) {
  $new_value = // ...do some stuff to compute a new value for the field.
  $node->field_my_field[LANGUAGE_NONE][0]['value'] = $new_value;
  field_attach_update('node', $node);
}

Не потрібно нічого дзвонити node_load node_saveчи повертати.

Я думаю, що причина цього полягає в тому node_save, що , звідки hook_node_updateі hook_node_insertвикликаються, обгортає всі запити бази даних в транзакції. (Зверніть увагу на перший рядок node_save:. $transaction = db_transaction()) Ці запити не викликаються до node_saveзавершення. Останній запит, який node_saveдодається до транзакції, викликається з field_attach_update, який використовує об'єкт $ node так, як це було раніше hook_node_update . Тому вам потрібно встановити чергу на інший запит, зателефонувавши field_attach_updateще раз. Принаймні, це моє розуміння того, що відбувається.

Якщо у вас виникають проблеми зі зміною атрибутів, що не поля, вузла (наприклад, $node->log), спробуйте також зателефонувати _node_save_revision($node, $user->uid, 'vid');. Це не створить нову редакцію.


2

Ось як ви змінюєте значення на вузлі:

$node = node_load($nodeID);
$node->field_fieldname['und'][0]['value'] = $val;
node_save($node);

4
undне дуже підходить тут, OP вже вказав у коді, який вони використовують $node->languageдля мовного коду
Clive

Це дуже корисно, дякую Клайву та Лансу, але я хочу переконатися, що значення поля зберігається кожного разу, коли вузол зберігається, отже, моє використання kuke_node_update. Чи можна було б повернути вузол $ у цьому гачку чи мені абсолютно потрібно зробити node_load? Я дійсно думав , що об'єкт вузол передається безпосередньо через hook_node_update ....
generalconsensus

Гаразд, я оновив код відповідно до вашої рекомендації - він знаходиться в оригінальному корпусі. Проблема: нескінченний цикл, у якому сторінка не завантажується, і mysql і apache починають набирати 85% завантаження на процесор. Однозначно, тут відбувається якась петля. Будь-які інші пропозиції?
загальний консенсус

Я не можу сказати тобі, що відбувається. Але, ймовірно, ви спробуєте один раз просто завантажити вузол, ввести щось у поле та зберегти його за допомогою node_save (). Або просто завантажте, надрукуйте щось (використовуючи сторожовий або dpm () та збережіть його знову, щоб побачити, чи це працює.
Lance

Проблема виникла із збереження вузла перед його збереженням, що призводило до рекурсивного циклу. Поганий вибір гака та поганий
збір

1

Поліпшення рішення Lance вище, уникаючи збереження цілого вузла, коли лише кілька значень поля змінено:

$node = node_load($nodeID);
// for each field whose value remains unchanged
unset($node->field_<field-name>); 
// for each field whose value changes
$node->field_<field-name>[LANGUAGE_NONE][0]['value'] = <new-value>;
field_attach_update('node', $node);
entity_get_controller('node')->resetCache(array($node->nid));

Це також може бути корисним, щоб уникнути побічних ефектів node_save().

Джерело: Збереження полів вузла без збереження самого вузла

https://www.urbaninsight.com/2011/10/24/saving-nodes-fields-without-saving-node-itself

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.