Пример программного изменения значения поля field_category
у материала типа article
:
Способ 1
$node = node_load(123);
$node->original = $node;
$node->field_category['und'][0]['tid'] = 456;
foreach (field_info_instances('node', 'article') as $field_name => $field_info) {
// Удаляем все поля кроме field_category
if ($field_name != 'field_category') {
unset($node->{$field_name});
}
}
field_attach_presave('node', $node);
field_attach_update('node', $node);
Замечание: способ обнуляет значения полей типа File или Image. Обойти баг можно не удаляя из $node
эти поля.
По материалам Saving node's fields without saving the node itself.
Способ 2
$node = node_load(123);
$node->field_category['und'][0]['tid'] = 456;
$field_info = field_info_field('field_category');
field_sql_storage_field_storage_write('node', $node, 'update', array($field_info['id']));
cache_clear_all("field:node:{$node->nid}", 'cache_field');
Замечание: при таком способе не вызывается никаких хуков из Field API, т.е. обновлённое поле не будет проиндексировано и т.п.
По тестам, обновление поля у 2000 нод занимает около 7 секунд с учётом node_load()
. Если отказаться от node_load()
, то тот же тест будет выполняться уже за 4 секунды:
$node = (object)array(
'nid' => 123,
'vid' => 123,
'type' => 'article',
);
$node->field_category['und'][0]['tid'] = 456;
$field_info = field_info_field('field_category');
field_sql_storage_field_storage_write('node', $node, 'update', array($field_info['id']));
cache_clear_all("field:node:{$node->nid}", 'cache_field');
По материалам How To Insert and Update Only Specific Fields Of Your Entity In Drupal 7.
Написанное актуально для
Drupal 7
Комментарии
Если hook_entity_update не вызывается при таком трюке, то я бы воздержался от его использования.
Кстати, может через field_update_field будет проще?
field_update_field для другого
Чёрт, лоханулся )
ерунда) если найдёшь более красивый рабочий способ, буду только рад ;)
Есть ещё варианты с field_sql_storage_*:
1. http://timonweb.com/how-insert-and-update-only-specific-fields-your-ent…
2. http://greenash.net.au/thoughts/2012/11/batch-updating-drupal-7-field-d…
3. не нашла ссылку :(
О, нашла http://blog.artemshymko.com/perform-certain-field-instances-updates-avo…
kalabro, спасибо, потестирую
еще есть некоторое кол-во оберток у ctools, которые используются в fape
полагаю, что лучше копать в их сторону так как именно они взяты командой spark для edit
Это: $node->original = $node; - точно нужно?
У меня сущность через ECK сделана и работает без этого?!
можно без этого
А так можно загрузить только одно поле (взято здесь)
Правда, у меня цепляются все поля. Не пойму, как сделать, чтобы было только одно. $field_id вроде бы указан :/
Когда использовал ваш метод при создании rules components для использования через Views BO, то поля не обновлялись. Cработал только node_save(). Интересно почему?
Добрый день!
Существует ли способ изменения entity properties без вызова функции сохранения entity?
нет
А почему field_update_field не подходит?
http://drupal.stackexchange.com/questions/64833/fast-saving-single-fiel…
Спасибо, способ 2 очень помогло.
Кстати, там кэш не правильно чистится, должно быть
cache_clear_all("field:node:{$node->nid}", 'cache_field');
Все бы хорошо, да только при изменении поля, Rules абсолютно не реагирует на событие "После обновления существующего материала"
Поддерживаю, как сделать чтобы рулсы срабатывали при изменении полей программно?
Для 8-го будет решение?)
Добрый день.
Подскажите пожалуйста, как правильно программно удалить значение кастомного поля пользователя.
Если удалять значение при редактировании пользователя на сайте, то из таблицы field_data_field_customfield удаляется строка со значением. Если я удаляю значение поля через unset($user->field_customfield[LANGUAGE_NONE][0]['value']); или через $user->field_customfield[LANGUAGE_NONE][0]['value'] = ''; ,строка из таблицы field_data_field_customfield не удаляется.
Спасибо.
Помогло unset($user->field_customfield[LANGUAGE_NONE][0]); Спасибо))
Добавить комментарий