Drupal → Работа с сущностями с помощью Entity metadata wrappers
Модуль Entity API позволяет работать с сущностями с помощью своей абстракции под названием Entity metadata wrappers.
Для чего это нужно:
— унифицированный способ доступа к свойствам и полям
— ленивая загрузка дочерних сущностей (например автор материала)
— валидация значений при записи свойств
— простая проверка разрешений
Примеры:
// Создание враппера для ноды по её nid $node_wrapper = entity_metadata_wrapper('node', $nid); // Вторым параметром можно передать объект ноды $node_wrapper = entity_metadata_wrapper('node', $node); // Получить значение свойства $nid = $node_wrapper->nid->value(); // или $node_wrapper->getIdentifier(); $title = $node_wrapper->title->value(); // Получить значение свойства, пропущенного через check_plain() $title = $node_wrapper->title->value(array('sanitize' => TRUE)); // Получить значение поля $field_value = $node_wrapper->field_name->value(); // Получить первое значение multiple-value поля $field_value = $node_wrapper->field_name[0]->value(); // Получить значение составного поля if ($node_wrapper->body->value()) { $teaser = $node_wrapper->body->summary->value(); $body = $node_wrapper->body->value->value(); } // Получить первое значение составного multiple-value поля if ($node_wrapper->field_tags->value()) { $first_tag_name = $node_wrapper->field_tags[0]->name->value(); } // Получить значение поля для определённого языка $field_value = $node_wrapper->language('ru')->field_name->value(); // Обойти значения multiple-value поля foreach ($node_wrapper->field_tags as $tag_wrapper) { $tid = $tag_wrapper->tid->value(); $tag_name = $tag_wrapper->name->value(); } // Получить значение свойства у связанной сущности $author = $node_wrapper->author->name->value(); $author_email = $node_wrapper->author->mail->value(); $author_roles = $node_wrapper->author->roles->optionsList(); $image_url = $node_wrapper->field_image->file->url->value(); // Изменить свойство $node_wrapper->title = 'New title' $node_wrapper->save(); // Изменить свойство у связанной сущности $node_wrapper->author->mail = 'newmail@gmail.com'; $node_wrapper->author->save(); // Изменить поле $node_wrapper->field_text = 'New value'; $node_wrapper->field_term = 123; $node_wrapper->save(); // Удалить значения поля $node_wrapper->field_image->set(NULL); // Удалить одно значение multi-value поля $node_wrapper->field_image[0]->set(NULL); // Проверить наличие поля у бандла (не наличие значения поля, // а именно существование поля у конкретного бандла) if (isset($node_wrapper->field_name)) { ... } // Отличить single-value поле от multi-value if ($node_wrapper->field_name instanceof EntityListWrapper) { // Поле multi-value } else { // Поле single-value } // Получить список доступных свойств $node_properties = $node_wrapper->getPropertyInfo(); $body_properties = $node_wrapper->body->getPropertyInfo(); // Получить список доступных свойств у определённого типа сущности $node_properties = entity_get_property_info('node');
Стоит заметить, что эта штука активно используется в Drupal Commerce и Rules.
Хорошая статья на английском — Write better code with EntityMetadataWrapper
Комментарии
выглядит круто. Всегда хотел с Entity API разобраться.
Как можно создать новую node со всеми ее полями?
P.S. не новый node type, а просто новую новость или товар
http://xandeadx.ru/blog/drupal/132
Можно ли создать WRAPPER для термина таксономии?
например $term_wrapper = entity_metadata_wrapper('taxonomy', $tid);
термин это сущность. можно
Добрый день. Подскажите, как вывести изображение в составном поле?
foreach ($node_wrapper->field_tags as $tag_wrapper) {
$tid = $tag_wrapper->tid->value();
$tag_name = $tag_wrapper->name->value();
}
С этим все понятно, у текстового поля есть value... А как быть с изображением в этой конструкции?
Заранее спасибо
Изображение можно вывести через render array
нужно только получить URI.
http://drupal.stackexchange.com/a/30769
обертка для термина таксономии:
$term_wrapper = entity_metadata_wrapper('taxonomy_term', $tid);
С таксономией все просто. У меня не получается выдернуть поле с изображением в field collections (с текстовым полем тоже просто) :)
@Николай
В очередной раз спасибо! Понятно, подробно и по делу!
Кстати, по поводу вывода картинки в данном случае.
У меня в таблице клиентов картинка хранится в поле field_client_logo.
И вывести её получилось таким вот образом.
И если нужно добавить alt или еще какой-нибудь атрибут, то после $img= ...
следует дописать
URI картинки
Debug:
array (
'fid' => '1885',
'alt' => '',
'title' => '',
'width' => '270',
'height' => '180',
'uid' => '1',
'filename' => 'thumb-video-270x180-689e.jpg',
'uri' => 'public://thumb-video-270x180-689e.jpg',
'filemime' => 'image/jpeg',
'filesize' => '21893',
'status' => '1',
'timestamp' => '1365335160',
)
Отсюда чтобы получить uri картинки нужно .
в статье есть пример правильного получения адреса картинки
А как работать с полями котрые пустые?
Ведь не всегда есть даные в поле. А постоянно получаю если поле пустое:
Как то не очень кошерно. Пользователь не ввел данные в поле и сайт падает. В принципе некоторые модули для комерца этим страдают (commerce_product_key).
Может какую то проверку проводить перед обращением к свойству? Я такой не нашел.
Ну а если через if isset(Ваше_свойство) делать проверку ?
Это не поможет так как такое свойство присутвует
Пока считаю это кривизной проектирования так как и схему поля commerce_price которое не позволяет корректно разрабатывать сайты где есть "дешевые валюты" по отношению к USD типа RUB. В случае рублей пользователю очень легко набрать в корзину по ошибке много товара и он уде не увидит сайт пока администратор и програмисты не удалят его ордер.
На сколько я знаю entity, commerce, field_collection - все эти модули делала толи одна комманда толи один человек (поправьте меня если это не так) и все присутвует та или иная кривизна в проектировании(опять же поправьте если есть другое мнение или факты). Не понимаю почему они не реагируют на те issue которыми кишит d.org по отношению к их модулям.
Работу с entity_metadata_wrapper нужно всегда проверять на EntityMetadataWrapperException.
Обычно в catch я пишу в watchdog сообщение где вылезла ошибка:
Если нужно проверить не пусто ли значение пока никакого другого способа не нашел, как загрузка объекта и проверка полей вручную:
@Alex, спасибо за развернутый ответ.
Жалко только что он подверждает мое прдеположение о недоделаности entity API. (я о дополнительной проверке поля на пустоту).
@Dima, согласен, что проблема есть. Если есть идеи как это можно улучшить, можешь предложить патч.
Можно ссылочку на issue на drupal.org, меня этот вопрос тоже интересует?
@Alex
Много их, вот что гугл выдает http://goo.gl/nPIIuu.
У меня лично первый раз появилась проблема когда одновременно включил commerce_discount и commerce_product_key.
Что бы патч написать нужно время, которым сейчас к сожалению не обладаю. Но проблему хотелось бы поправить.
@Alex еще раз спасибо, с тем что ты дал уже можно работать.
Очень странное и непредсказеемое поведение, конечно, у объектов этих классов (EntityMetadataWrapper, EntityValueWrapper, EntityStructureWrapper, EntityDrupalWrapper и тд.)
Воспользовался твоим примером:
В случаеш пустого поля получаю массив информации о поле, а в случае не пустого пулчаю массив колонком поля (у меня это amount и currency_code).
Это так для информации.
Есть идеи, как получить tnid через metadata wrapper в случае использования i18n?
Привет! есть два кода:
и
Почему первый вызывает 502-ую ошибку, а второй работает нормально?
потому что после $node_wrapper->save() вызывается hook_node_presave
Добрый вечер! Можно подробнее о выводе картинок товара!
$commerce_order_wrapper = entity_metadata_wrapper('commerce_order', $commerce_order);
$img = $commerce_order_wrapper->commerce_product->field_dress_img->value();
выводит - Array!
Здравствуйте!
Присутствует ли возможность записывать/читать в поле data объекта user с помощю врапера?
смотрите два последних примера
Похоже что ЕМВ не предоставляет доступ к data объекта $user, либо из за того, что поле сериализуется, либо потому, что возвращаемый объект имеет собственное свойство data.
Проверить наличие поля у бандла - есть в статье
А как узнать(увидеть) все поля у бандла?
Это можно как то вывести?
А дальше как?
а то так не работает:
заранее спасибо.
Для того чтобы получить данные свойства picture у юзера
$user_wrapper->value()->picture
А как правильно проверить - что это мультипле поле или может иметь только одно значение?
Как правильно сохранить поле с несколькими значениями поля.
Не прокатывает
Fatal error: Cannot use object of type stdClass as array in /sites/all/modules/entity/modules/callbacks.inc on line 638
...помогло...
Для того чтобы установить новое значение для неограниченного поля
$node_wrapper->field_user_photos[$key]->set( array( 'fid'=> $values['photos'][$key]['fid'] ) );
А вот как удалить одно из значений?
$node_wrapper->field_user_photos[$key]->set(null);
пробовал разные варианты ->set(array), file->set(null)
https://www.drupal.org/docs/7/api/entity-api/entity-metadata-wrappers#de...
Если вы используете поле которое ссылается на сущность и оно будет пустое, то вылезет ошибка:
EntityMetadataWrapperException: Unable to get the data property name as the parent data structure is not set.
isset() не поможет используйте getIdentifier()
Оставить комментарий