Один раз начав работать с EntityFieldQuery, вы уже не захотите городить SQL запросы с джойнами таблиц полей сущностей. Что то сложное, возможно, сделать будет слишком трудно на этом конструкторе, но типовые выборки данных делать приятно, быстро и удобно.
Правда, как это часто бывает в Drupal, очень мало примеров использования этого contributed API.
Пример №1 : выбор публикаций с условием к одному из полей сущности.
Здесь я выбираю публикации типа dstr (карточки дистрибьюторов), фильтруя их по названию и значению поля field_site (адрес сайта в карточке дистрибьютора).
1 2 3 4 5 6 7 8 9 10 11 12 |
$distrQuery = new EntityFieldQuery(); // указываем тип сущности - node $distrQuery->entityCondition('entity_type', 'node') // тип публикации ->propertyCondition('type', 'dstr') // фильтр по названию ( используется тоже propertyCondition, // т.к. title находится в таблице самой сущности) ->propertyCondition('title', $Name); // фильтр по значению в поле field_site ->fieldCondition('field_site', 'value', $website); // получим значение(-ия) $distr = $distrQuery->execute(); |
Вот пример работы с результатом запроса:
1 2 3 4 5 6 7 8 9 10 |
if (empty($distr)) { // если пустой запрос - выведем сообщение drupal_set_message('No distributor `' . $Name . '` with website `' . $website . '` is in database.', 'error'); } else { // иначе загрузим объект публикации $node = node_load(array_shift($distr['node'])->nid); // выполним с ним какие то действия ... } |
Пример №2 : используем EntityFieldQuery для поиска в таксономии.
Для запроса может понадобится код (vid) словаря. Получите его по имени следующим образом:
1 2 |
// в данном примере `metro` машинное имя словаря со станциями метро $vocab_obj = taxonomy_vocabulary_machine_name_load('metro'); |
Найдем в словаре станцию метро (термин) с заданным названием и городом:
1 2 3 4 5 6 7 8 9 10 11 |
$metroQuery = new EntityFieldQuery(); // теперь сущность - это термин таксономии $metroTerm = $metroQuery->entityCondition('entity_type', 'taxonomy_term') // укажем словарь ->propertyCondition('vid', $vocab_obj->vid) // фильтр по имени термина ->propertyCondition('name', $Metro) // фильтр по полю Город ->fieldCondition('field_city', 'value', $CityName) // выполним запрос ->execute(); |
Пример очень похож на предыдущий. Практически EntityFieldQuery уравнивает работу с таксономией и нодами.
Пример обработки результата:
1 2 3 4 5 6 7 8 9 |
if (empty($metroTerm)) { // термин не найден drupal_set_message('Can`t find metro station', 'error'); } else { // возьмем код первого термина из массива результатов $MetroTid = array_shift($metroTerm['taxonomy_term'])->tid; // что то с ним делаем ... } |
Пример №3 : используем EntityFieldQuery для поиска в field collection.
EntityFieldQuery отлично работает с коллекциями. Есть определенные сложности в том, чтобы отфильтровать только экземпляры, связанные только с определенной сущностью. Я покажу вам как я решаю эту проблему, но если у вас есть другие варианты — делитесь в комментариях.
В первом примере мы искали среди node типа ‘дистрибьютор’. У данной публикации одно из полей field_addr оказалось сформировано модулем field_collection — набор карточек адресов данного дистрибьютора.
Давайте поищем среди этого набора карточек.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$addrQuery = new EntityFieldQuery(); // Теперь сущностью является field_collection_item $addr = $addrQuery->entityCondition('entity_type', 'field_collection_item') // укажите имя поля, в моем случае это - field_addr ->propertyCondition('field_name', 'field_addr') // статус, нас не нужны архивные данные ->propertyCondition('archived', 0) // и тут я реализую фильтр только по конкретной, связанной с // с коллекцией сущностью, перечисляя все значения item_id коллекции // данной публикации ->propertyCondition('item_id', $node->field_addr[LANGUAGE_NONE]) // добавляю фильтр по одному из полей ->fieldCondition('field_city', 'value', $CityName) // выполняю запрос ->execute(); |