Проверка существования поля в entity_metadata_wrapper

22

Я перебираю коллекцию полей и упаковываю элементы коллекции полей 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чтобы видеть, является ли поле пустым, но я хотел бы быть в состоянии сделать это через оболочку метаданных, если это возможно.

Ник Томлин
источник

Ответы:

26

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

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

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

piouPiouM
источник
Да, я всегда так делал, меньше привязан к внутренностям и легче читал ИМО. Upvoted!
Котцер
9

Каждый раз, когда есть ссылка на сущность или коллекция полей, isset () никогда не работал для меня. То, что, кажется, работает каждый раз, когда у нас есть ссылка на сущность, делает:

if($wrapped_entity->entity_reference_field->getIdentifier()) {
  // This code only fires if there is an entity reference or field collection set.
}
Atomox
источник
Этот ответ и следующий пост работали для меня: dropbucket.org/node/1201
tyler.frankenstein
4

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

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

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

а затем использовать IFблок, чтобы сделать вашу логику ...

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

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

tenken
источник
Я не уверен, что вы подразумеваете под «похоже, что у вас есть ссылка на сущность», если бы вы могли объяснить это немного больше, я был бы признателен. __issetотлично работает на полевой коллекции, хотя мне нужно добавить полное имя поля: field_contrib_headshotвместоcontrib_headshot
Ник Томлин
поля являются значениями; строка, число, что угодно. field_contributorссылается на другое поле field_contrib_headshot... у вас там как-то вложено. Я предполагаю, что вы используете entity_reference или что-то еще, например field_group, для вложения этих вещей ... это все, что я имел в виду.
Tenken
какой кусок кода __isset () работал для вас?
Tenken
Было:$item_wrapper->field_contributor->__isset('field_contrib_headshot')
Ник Томлин,
Мне странно напрямую вызывать __isset (), почему бы и нет: $has_headshot = isset($item_wrapper->field_contributor->field_contrib_headshot);
Котцер
1
$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

Для 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, как и так, может принимать значение true, даже если nid отсутствует. -> getIdentifier (), или -> value (), или -> raw () могут выдавать исключения.

ВСЕГДА ВСЕГДА ИСТИНА

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;
}
daveferrara1
источник
0

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

if ( $wrapper->field_media_alternate[0]->value() ) {
  //...valid logic...
} else {
  //...not valid logic...
}
knice
источник
0

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

На самом деле не существует независимого метода для проверки, установлено ли значение. Вам просто нужно оценить value () или, желательно, raw (). (Вы также можете вызвать 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

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

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_name, например:

[
  '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'
]

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

Thony
источник