J'ai cherché à utiliser les classes Entity Metadata Wrapper (définies par le module d'entité dans Drupal 7) pour accéder aux valeurs de champ, car cela semble être une manière propre de le faire.
Il y a quelques choses qui rendent cela un peu gênant cependant. Supposons que j'ai un wrapper pour un type de contenu qui définit un champ nommé field_something
comme tel:
$wrapper = entity_metadata_wrapper('node', node_load($nid));
$value = $wrapper->field_something->value();
Le premier problème que j'ai est que je n'ai aucun moyen de savoir à l'avance si ce que j'obtiens est une valeur réelle (une chaîne, une entité, etc.), un autre wrapper de structure de métadonnées (lorsque les champs ont plusieurs valeurs) ou un tableau (lorsque les champs ont plusieurs propriétés).
J'ai trouvé un moyen de répondre à ces questions en utilisant la info()
méthode:
$info = $wrapper->field_something->info();
$is_multi_value = (strpos($info['type'], 'list<') === 0);
$has_multiple_properties = isset($info['property info']]);
Mais ce n'est guère pratique. Chaque fois que je veux utiliser un champ sans connaître sa définition au préalable, je dois prendre en compte plusieurs cas. Cela rend mon code assez lourd.
Pour y faire face, j'ai écrit du code qui:
- Garantit que nous recevons toujours un tableau, même s'il s'agit d'un champ à valeur unique;
- Lorsqu'il existe plusieurs propriétés, renvoyez la valeur de la première colonne.
Le point 1 ici fonctionnera toujours, à moins que l'appelant ne veuille savoir s'il s'agit d'un champ à valeur unique ou non. Le point 2 fonctionne dans certains cas, pas tous, mais est pratique lorsqu'il s'applique.
Voici le code:
function entity_metadata_simple_values($field) {
$fields = array();
$values = array();
$info = $field->info();
if (strpos($info['type'], 'list<') === 0) {
foreach ($field->getIterator() as $field_iteration) {
$fields[] = $field_iteration;
}
} else {
$fields[] = $field;
}
foreach ($fields as $final_field) {
$ff_info = $final_field->info();
if (isset($ff_info['property info'])) {
$column = reset(array_keys($ff_info['property info']));
$values[] = $final_field->{$column}->value();
} else {
$values[] = $final_field->value();
}
}
return $values;
}
Ma question est donc la suivante: existe-t-il des moyens plus simples / meilleurs de résoudre ce problème d'obtention de valeurs à partir du wrapper de métadonnées lorsque le type de champ n'est pas connu?
Donc, comme personne n'a trouvé une autre solution, je répondrai à ma propre question:
Il n'y a pas de moyen plus simple d'accéder aux valeurs de types de champs inconnus lors de l'utilisation d'encapsuleurs de métadonnées d'entité.
Il existe des méthodes alternatives à celle que j'ai décrite initialement (par exemple celles indiquées par @thepearson). En particulier, cette méthode est utile:
Il renverra le type répertorié si votre type est une liste (par exemple, «entier» si votre type est «liste <entier>»), ou faux si votre type n'est pas une liste. En interne, il fait une strpos, tout comme le code que j'ai initialement publié, mais je suppose que c'est plus à l'épreuve du temps.
La conclusion est que:
Les wrappers de métadonnées d'entité fonctionnent bien si vous n'avez aucune idée de vos types de champs et que vous souhaitez traiter soigneusement chaque cas possible;
Les wrappers de métadonnées d'entité fonctionnent bien si vous savez exactement de quels types sont vos champs et que vous souhaitez les utiliser;
Si vous n'avez que quelques idées sur la nature de vos types de champs (par exemple, tout le texte, mais vous ne savez pas s'ils sont formatés ou non, et vous ne savez pas s'ils sont à valeur unique ou multiple), alors les wrappers de métadonnées d'entité ne fournissez aucun raccourci et vous devez écrire le vôtre comme je l'ai fait dans la question initiale.
la source
Pour la vérification de champ unique / multiple, j'ai trouvé utile de tester le type de l'objet wrapper, qui sera
EntityListWrapper
pour un champ à valeurs multiples etEntityValueWrapper
pour un champ à valeur unique:la source
if($wrapper->field_name instanceof EntityListWrapper) {...}