Comprobando la existencia de un campo en una entidad_metadata_envoltura

22

Estoy iterando a través de una colección de campos y envolviendo los elementos de la colección de campos con una entidad_metadata_wrapper. Me gustaría verificar la existencia de un campo antes de llamar a su valuemétodo (que da como resultado un error en los campos que no tienen un valor), pero no puedo encontrar una manera de hacerlo.

$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();

Mi solución actual es usar field_get_itemspara ver si el campo está vacío, pero me encantaría poder hacerlo a través del contenedor de metadatos si es posible.

Nick Tomlin
fuente

Respuestas:

26

Simplemente llame a la función PHP isset():

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

EntityStructureWrapper implementa la __isset()función según el principio de sobrecarga .

piouPiouM
fuente
Sí, así es como lo he hecho, menos ligado a lo interno y más fácil de leer en mi opinión. ¡Votado!
Cottser
9

Cada vez que hay una referencia de entidad o colección de campos, isset () nunca me ha funcionado. Lo que parece funcionar cada vez que tenemos una referencia de entidad está haciendo:

if($wrapped_entity->entity_reference_field->getIdentifier()) {
  // This code only fires if there is an entity reference or field collection set.
}
Atomox
fuente
Esta respuesta y la siguiente publicación funcionaron para mí: dropbucket.org/node/1201
tyler.frankenstein
4

Parece que tienes un entity_referencelugar allí debido al método de encadenamiento. Pero, mire el método __isset () para EntityStructureWrapper .

Comprobar como:

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

y luego usa un IFbloque para hacer tu lógica ...

EDITAR:

$has_headshot ahora es válido el cheque deseado.

Tenken
fuente
No estoy seguro de lo que quieres decir con "parece que tienes una referencia de entidad en alguna parte", si pudieras explicar eso un poco más, te lo agradecería. __issetfunciona muy bien en la colección de campo, aunque necesito agregar el nombre completo del campo: en field_contrib_headshotlugar decontrib_headshot
Nick Tomlin
los campos son valores; una cadena, un número, lo que sea. field_contributorestá haciendo referencia a otro campo field_contrib_headshot... tienes anidando allí de alguna manera. Supongo que estás usando entity_reference o algo más como field_group para anidar estas cosas ... eso es todo lo que quise decir.
Tenken
¿Cuál fue el código __isset () que funcionó para usted?
Tenken
Fue:$item_wrapper->field_contributor->__isset('field_contrib_headshot')
Nick Tomlin
Me parece extraño llamar al __isset () directamente, por qué no: $has_headshot = isset($item_wrapper->field_contributor->field_contrib_headshot);
Cottser
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.
}

Campos de referencia de entidad y colecciones de campos.

// 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;
}

Copiado y pegado directamente de http://dropbucket.org/node/1201, pero parece ser un mejor ejemplo que cualquier otra respuesta hasta ahora ...

Felix Eve
fuente
1

Para EntityMetadataWrapper:

Si tiene bloques de código en ejecución que no deberían o si ha encontrado errores de PHP, mire algunos de los ejemplos a continuación. Este ejemplo usa la propiedad nid.

PUEDE TODO ERROR

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

O

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

O

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

Puede encontrar que el uso de isset like así podría evaluarse como verdadero incluso si el nid no está presente. El -> getIdentifier (), o -> value (), o -> raw () puede lanzar excepciones.

PROBABLEMENTE SIEMPRE VERDADERO

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

UTILICE ESTE EN LUGAR

try {
  $var = $wrapper->nid->raw();
} 
catch (EntityMetadataWrapperException $e) {
  $var = FALSE;
}
daveferrara1
fuente
0

Descubrí que isset () no se puede usar en el resultado de una llamada de función. Como se devuelve un booleano con la siguiente declaración, pude verificar que el elemento envuelto, de hecho, tenía un valor.

if ( $wrapper->field_media_alternate[0]->value() ) {
  //...valid logic...
} else {
  //...not valid logic...
}
cuchillo
fuente
0

La gente a menudo se equivoca. Cuando llama a isset en un contenedor de metadatos de entidad, está verificando si el paquete de entidades admite esa propiedad. No tiene nada que ver con el valor real del campo.

Realmente no hay un método independiente para verificar si se establece un valor. Solo tiene que evaluar value () o, preferiblemente, raw (). (También puede llamar a count () si es un campo de valores múltiples, pero raw () devolverá una matriz vacía, por lo que no es realmente necesario).

$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.
  }
}

Para reiterar, raw () es el valor que debe usar para verificar si existe un campo. Es confiable y computacionalmente barato.

Scott Armstrong
fuente
0

Aquí está mi función de ayuda personal para obtener un valor de una cadena de referencias de entidad potencialmente no establecida:

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 es la entidad envuelta, $ field_chain es una matriz de field_names así:

[
  'field_reference_from_the_wentity',
  'field_wanted_field_from_the_referenced_entity'
] 

también puedes hacer:

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

¡Funcionará!

Thony
fuente