Vérification de l'existence d'un champ sur un objet entity_metadata_wrapper

22

J'itère à travers une collection de champs et j'enveloppe les éléments de la collection de champs avec un entity_metadata_wrapper. Je voudrais vérifier l'existence d'un champ avant d'appeler sa valueméthode (ce qui entraîne une erreur sur les champs qui n'ont pas de valeur), mais je ne trouve pas de moyen de le faire.

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

Ma solution de contournement actuelle consiste à utiliser field_get_itemspour voir si le champ est vide, mais j'aimerais pouvoir le faire via le wrapper de métadonnées si possible.

Nick Tomlin
la source

Réponses:

26

Appelez simplement la fonction PHP isset():

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

EntityStructureWrapper implémente la __isset()fonction selon le principe de la surcharge .

piouPiouM
la source
Oui, c'est toujours comme ça que je l'ai fait, moins lié aux internes et plus facile à lire IMO. A voté!
Cottser
9

Chaque fois qu'il existe une référence d'entité ou une collection de champs, isset () n'a jamais fonctionné pour moi. Ce qui semble fonctionner chaque fois que nous avons une référence d'entité, c'est:

if($wrapped_entity->entity_reference_field->getIdentifier()) {
  // This code only fires if there is an entity reference or field collection set.
}
Atomox
la source
Cette réponse et le post suivant ont fonctionné pour moi: dropbucket.org/node/1201
tyler.frankenstein
4

Il semble que vous ayez un entity_referenceendroit quelque part en raison du chaînage de la méthode. Mais, regardez la méthode __isset () pour EntityStructureWrapper .

Vérifiez comme:

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

puis utilisez un IFbloc pour faire votre logique ...

MODIFIER:

$has_headshot est maintenant valide, contrôle souhaité.

tenken
la source
Je ne suis pas sûr de ce que vous entendez par "il semble que vous ayez une référence d'entité quelque part", si vous pouviez expliquer un peu plus je l'apprécierais. __issetfonctionne très bien sur la collection de champs, bien que je doive ajouter le nom complet du champ: field_contrib_headshotau lieu decontrib_headshot
Nick Tomlin
les champs sont des valeurs; une chaîne, un nombre, peu importe. field_contributorfait référence à un autre domaine field_contrib_headshot... vous y êtes imbriqué d'une manière ou d'une autre. Je suppose que vous utilisez entity_reference ou quelque chose d'autre comme field_group pour imbriquer ces choses ... c'est tout ce que je voulais dire.
tenken
quel est le morceau de code __isset () qui a fonctionné pour vous?
tenken
C'était:$item_wrapper->field_contributor->__isset('field_contrib_headshot')
Nick Tomlin
Cela me fait bizarre d'appeler directement le __isset (), pourquoi pas: $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.
}

Champs de référence d'entité et collections de champs

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

Copié et collé directement depuis http://dropbucket.org/node/1201 mais semble être un meilleur exemple que toute autre réponse jusqu'à présent ...

Felix Eve
la source
1

Pour EntityMetadataWrapper:

Si vous avez des blocs de code en cours d'exécution qui ne devraient pas ou si vous avez rencontré des erreurs PHP, regardez certains des exemples ci-dessous. Cet exemple utilise la propriété nid.

PEUT TOUT ERREUR

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

OU

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

OU

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

Vous constaterez peut-être que l'utilisation de isset like so peut être évaluée à true même si le nid n'est pas présent. Le -> getIdentifier (), ou -> value (), ou -> raw () peut lever des exceptions.

PROBABLEMENT TOUJOURS VRAI

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

UTILISEZ CECI AU LIEU

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

J'ai trouvé que isset () ne peut pas être utilisé sur le résultat d'un appel de fonction. Puisqu'un booléen est renvoyé avec l'instruction suivante, j'ai pu vérifier que l'élément encapsulé avait en fait une valeur.

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

Les gens se trompent souvent. Lorsque vous appelez isset sur un wrapper de métadonnées d'entité, vous vérifiez si le groupe d' entités prend en charge cette propriété. Cela n'a rien à voir avec la valeur réelle du champ.

Il n'y a pas vraiment de méthode indépendante pour vérifier si une valeur est définie. Il vous suffit d'évaluer value () ou, de préférence, raw (). (Vous pouvez également appeler count () s'il s'agit d'un champ à plusieurs valeurs, mais raw () renverra un tableau vide de sorte qu'il n'est pas réellement requis.)

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

Pour réitérer, raw () est la valeur que vous devez utiliser pour vérifier si un champ existe. C'est fiable et bon marché sur le plan des calculs.

Scott Armstrong
la source
0

Voici ma fonction d'aide personnelle pour obtenir une valeur à partir d'une chaîne potentiellement non définie de références d'entité:

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

$ gotity est l'entité enveloppée, $ field_chain est un tableau de noms de champs comme ceci:

[
  'field_reference_from_the_wentity',
  'field_wanted_field_from_the_referenced_entity'
] 

vous pouvez également faire:

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

ça va marcher!

Thony
la source