Verificando a existência de um campo em um entity_metadata_wrapper

22

Estou percorrendo uma coleção de campos e agrupando os itens da coleção de campos com um entity_metadata_wrapper. Gostaria de verificar a existência de campo antes de chamar seu valuemétodo (o que resulta em um erro nos campos que não têm valor), mas não consigo encontrar uma maneira de fazê-lo.

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

Minha solução atual é usar field_get_itemspara ver se o campo está vazio, mas eu adoraria poder fazer isso através do wrapper de metadados, se possível.

Nick Tomlin
fonte

Respostas:

26

Simplesmente chame a função PHP isset():

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

EntityStructureWrapper implementa a __isset()função de acordo com o princípio de Sobrecarga .

piouPiouM
fonte
Sim, é sempre assim que eu faço, menos vinculado aos internos e mais fácil de ler IMO. Voto a favor!
Cottser
9

Sempre que houver uma referência de entidade ou coleção de campos, isset () nunca funcionou para mim. O que parece funcionar sempre que uma referência de entidade está fazendo:

if($wrapped_entity->entity_reference_field->getIdentifier()) {
  // This code only fires if there is an entity reference or field collection set.
}
Atomox
fonte
Esta resposta e a seguinte postagem funcionaram para mim: dropbucket.org/node/1201
tyler.frankenstein 16/15
4

Parece que você tem um entity_referencelugar lá devido ao encadeamento do método. Mas, observe o método __isset () para EntityStructureWrapper .

Verifique como:

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

e depois use um IFbloco para fazer sua lógica ...

EDITAR:

$has_headshot agora é a verificação válida desejada.

tenken
fonte
Não sei ao certo o que você quer dizer com "parece que você tem uma referência de entidade em algum lugar", se você pudesse explicar um pouco mais, eu apreciaria. __issetfunciona muito bem na coleção de campos, embora eu precise adicionar o nome completo do campo: em field_contrib_headshotvez decontrib_headshot
Nick Tomlin
campos são valores; uma string, um número, qualquer que seja. field_contributorestá referenciando outro campo field_contrib_headshot... você está aninhando lá de alguma forma. Estou assumindo que você está usando entity_reference ou algo mais como field_group para aninhar essas coisas ... foi tudo o que eu quis dizer.
Tenken #
qual foi o código __isset () que funcionou para você?
Tenken #
Foi:$item_wrapper->field_contributor->__isset('field_contrib_headshot')
Nick Tomlin
É estranho para mim para chamar a __isset () diretamente, por que não: $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 referência da entidade e coleções 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 e colado diretamente de http://dropbucket.org/node/1201, mas parece ser um exemplo melhor do que qualquer outra resposta até agora ...

Felix Eve
fonte
1

Para EntityMetadataWrapper:

Se você tem blocos de código em execução que não deveriam ou se encontrou erros de PHP, veja alguns dos exemplos abaixo. Este exemplo usa a propriedade nid.

PODE TUDO ERRO

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

Você pode achar que usar isset como esse pode ser avaliado como verdadeiro mesmo se o nid não estiver presente. O -> getIdentifier () ou -> value () ou -> raw () podem gerar exceções.

SEMPRE VERDADEIRO VERDADEIRO

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

USE ESTE INSTRUMENTO

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

Descobri que isset () não pode ser usado no resultado de uma chamada de função. Como um booleano é retornado com a seguinte instrução, eu pude verificar se o elemento agrupado, de fato, tinha um valor.

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

As pessoas geralmente entendem errado. Quando você chama isset em um wrapper de metadados da entidade, está verificando se o pacote configurável da entidade suporta essa propriedade. Não tem nada a ver com o valor real do campo.

Não existe realmente um método independente para verificar se um valor está definido. Você apenas precisa avaliar value () ou, preferencialmente, raw (). (Você também pode chamar count () se for um campo com vários valores, mas raw () retornará uma matriz vazia, para que não seja realmente necessário.)

$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 () é o valor que você deve usar para verificar se existe um campo. É confiável e computacionalmente barato.

Scott Armstrong
fonte
0

Aqui está minha função de ajudante pessoal para obter um valor de uma cadeia potencialmente não definida de referências de entidades:

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

$ goneity é a entidade agrupada, $ field_chain é uma matriz de field_names da seguinte forma:

[
  'field_reference_from_the_wentity',
  'field_wanted_field_from_the_referenced_entity'
] 

você também pode fazer:

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

vai dar certo!

Thony
fonte