Проверка наличия поля в оболочке метаданных сущности


Я перебираю коллекцию полей и обертываю элементы коллекции полей с помощью entity_metadata_wrapper. Я хотел бы проверить наличие поля перед вызовом его метода value (что приводит к ошибке в полях, которые не имеют значения), но я не могу найти способ сделать это.

$field_collection_item = field_collection_item_load($id);
$item_wrapper = entity_metadata_wrapper('field_collection_item', $field_collection_item);

// this results in an error if the field_contrib_headshot field is empty
$headshot = $item_wrapper->field_contributor->field_contrib_headshot->value();

Мой текущий обходной путь - использовать field_get_items, чтобы проверить, пустое ли поле, но я хотел бы иметь возможность сделать это с помощью оболочки метаданных, если это возможно.

 22
Author: Nick Tomlin, 2013-11-19

8 answers

Просто вызовите функцию PHP isset():

$headshot = array();
if (isset($item_wrapper->field_contributor->field_contrib_headshot)) {
  $headshot = $item_wrapper->field_contributor->field_contrib_headshot->value();
}

Entitystructurewrapper реализует функцию __isset() в соответствии с принципом перегрузки.

 27
Author: piouPiouM, 2014-01-21 15:30:37

Всякий раз, когда есть ссылка на сущность или коллекция полей, isset() никогда не работал на меня. Что, кажется, работает в любое время, когда у нас есть ссылка на сущность, так это:

if($wrapped_entity->entity_reference_field->getIdentifier()) {
  // This code only fires if there is an entity reference or field collection set.
}
 9
Author: Atomox, 2014-07-09 16:18:43

Похоже, что у вас где-то есть entity_reference из-за цепочки методов. Но посмотрите на метод __isset() для EntityStructureWrapper.

Проверьте, как:

$has_headshot = $item_wrapper->field_contributor->__isset('field_contrib_headshot');

, А затем используйте блок IF для выполнения своей логики...

РЕДАКТИРОВАТЬ:

$has_headshot теперь действительна желаемая проверка.

 4
Author: tenken, 2013-11-19 19:28:55
$wrapper = entity_metadata_wrapper('node', 123);
if($wrapper->__isset('field_middle_name')) {
    // Do something awesome with the middle name.
} else {
    // Don't do anything awesome, they don't have a middle name.
}

Поля ссылок на сущности и коллекции полей

// also check if there is an identifier, __isset alone is not enough!
if ($wrapper->__isset('field_project_number') && $wrapper->field_project_number->getIdentifier()) {
    $number =  $wrapper->field_project_number->field_project_number_complete->value();
    return $number;
}

Скопировано и вставлено прямо из http://dropbucket.org/node/1201 но, похоже, это лучший пример, чем любой другой ответ до сих пор...

 1
Author: Felix Eve, 2015-08-19 23:54:40

Для EntityMetadataWrapper:

Если у вас запущены блоки кода, которые не должны выполняться, или если вы столкнулись с ошибками PHP, посмотрите на некоторые примеры ниже. В этом примере используется свойство nid.

МОГУТ ВСЕ ОШИБКИ

if ($wrapper->__isset('nid')) {
  $var = $wrapper->nid->value();
}
else {
  // Do something it's FALSE;
}

ИЛИ

if ($wrapper->__isset('nid')) {
  $var = $wrapper->nid->getIdentifier();
}
else {
  // Do something it's FALSE;
}

ИЛИ

if ($wrapper->nid->value()) {
  // Do something it's TRUE.
}
else {
  // Do something it's FALSE;
}

Вы можете обнаружить, что использование isset подобным образом может привести к истине, даже если nid отсутствует. ->getIdentifier(), или ->значение(), или ->необработанный() может вызывать исключения.

ВЕРОЯТНО, ВСЕГДА ВЕРНО

if (isset($wrapper->nid)) {
  // Do something it must be TRUE....Ah Hem wait.. this runs every time.
}

ИСПОЛЬЗУЙТЕ ЭТО ВМЕСТО

try {
  $var = $wrapper->nid->raw();
} 
catch (EntityMetadataWrapperException $e) {
  $var = FALSE;
}
 1
Author: daveferrara1, 2017-01-12 21:05:20

Я обнаружил, что isset() нельзя использовать в результате вызова функции. Поскольку логическое значение возвращается со следующим оператором, я смог проверить, что завернутый элемент на самом деле имеет значение.

if ( $wrapper->field_media_alternate[0]->value() ) {
  //...valid logic...
} else {
  //...not valid logic...
}
 0
Author: knice, 2016-01-05 14:52:12

Люди часто понимают это неправильно. Когда вы вызываете isset в оболочке метаданных сущности, вы проверяете, поддерживает ли пакет сущностей это свойство. Это не имеет никакого отношения к фактическому значению поля.

На самом деле не существует независимого метода проверки того, установлено ли значение. Вам просто нужно оценить значение() или, предпочтительно, необработанное(). (Вы также можете вызвать count(), если это поле с несколькими значениями, но raw() вернет пустой массив, поэтому на самом деле это не так требуется.)

$w = entity_metadata_wrapper('node', $nid);
//Start by checking whether the node bundle supports field_entityref_myfield.
if (isset($w->field_entityref_myfield)) {
  //If we called value(), then that would cause the referenced entity
  //to be loaded, whereas raw() just gives us the entity_id if the value
  //is set, and Null if it isn't.
  if ($w->field_entityref_myfield->raw()) {
    //Do some things based on the entity-reference being set.
  } else {
    //Do some other things based on the entity-reference NOT being set.
  }
}

Повторяю, raw() - это значение, которое вы должны использовать, чтобы проверить, существует ли поле. Это надежно и вычислительно дешево.

 0
Author: Scott Armstrong, 2017-01-03 23:39:40

Вот моя личная вспомогательная функция для получения значения из потенциально не заданной цепочки ссылок на сущности:

function _get_wrapped_value_ifset($wentity, $field_chain){
  $root = $wentity;
  try{
    foreach ( $field_chain as $field_name ) {
      $root = $root->{$field_name};
    }
    return $root->value();
  }
  catch (EntityMetadataWrapperException $e){
    return null;
  }
}

$wentity - это обернутая сущность, $field_chain - это массив имен полей, например:

[
  'field_reference_from_the_wentity',
  'field_wanted_field_from_the_referenced_entity'
] 

Вы также можете сделать:

[
  'field_reference_from_the_wentity', 
  'field_reference_from_the_referenced_entity',
  ... 
  'field_wanted_field_from_the_N_referenced_entity'
]

Это сработает!

 0
Author: Thony, 2018-08-08 15:45:59