Lab / Drupal

Drupal7: Массовое изменение значения поля у нод

Сегодня я поделюсь рецептом, как сделать выборку определённых нод и массово заменить у них одно значение на другое.

Для начала вам поребуется установить модуль Devel если он у вас ещё не установлен. Затем перейти по адресу devel/php и далее по контексту вашей задачи сконструировать query запрос.

Привожу пример из практики, у меня в работе туристический сайт, изначально предлагавший туры только по Франции. В последствии клиент решил расшарить географию на Испанию. В результате необходимо было создать новое поле select с выбором страны при создании материала. Разумеется никто не захотел бы присваивать значения "Франция" уже залитым паре тысяч туров на сайте. На помощь нам спешит Devel и вот такая конструкция:

drupal_set_time_limit(600);
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'node');
$query->propertyCondition('type', 'tour'); // фильтр по типу ноды
$result = $query->execute();
foreach (array_keys($result['node']) as $nid) {
 $node = node_load($nid, NULL, TRUE);
 $node->field_country[LANGUAGE_NONE][0]['value'] = 'france'; // новое значение поля
 node_save($node);
}
drupal_set_message('Обновлено ' . count($result['node']) . ' нод');

Как вы видите из кода, мы выбираем объекты из БД те у которых тип материала "Тур" и призсаиваем полю field_country ключ страны у меня это: france|Франция и spain|Испания.

А что делать если клиент захочет потом ещё добавить Андорру или Португалию? На саом деле всё очеь просто, нужно будет добавить всего лишь одно условие, что бы не затирать уже созданные поля. Например так, всем материалам типа "Тур" у которых не задано значение будут присвоено значение Андорра:

$query->fieldCondition('field_country', 'value', 'NULL'); // фильтр по пустому полю

В вашем случае можно так же расширить возможности этого фильтра. Например всем турам в Андорре задать одинааковую стоимость:

$query->fieldCondition('field_country', 'value', 'andorra'); // фильтр по ключу страны
//... 
$node->field_price[LANGUAGE_NONE][0]['value'] = 500; // задаём массово стоимость