Модуль 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 7.x-1.0-rc1
Комментарии
выглядит круто. Всегда хотел с 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#d…
Если вы используете поле которое ссылается на сущность и оно будет пустое, то вылезет ошибка:
EntityMetadataWrapperException: Unable to get the data property name as the parent data structure is not set.
isset() не поможет используйте getIdentifier()
Добавить комментарий