Ich habe versucht, mithilfe der Entity Metadata Wrapper-Klassen (definiert durch das Entity-Modul in Drupal 7) auf Feldwerte zuzugreifen, da dies eine saubere Methode zu sein scheint.
Es gibt ein paar Dinge, die dies jedoch etwas umständlich machen. Angenommen, ich habe einen Wrapper für einen Inhaltstyp, der ein Feld mit folgendem Namen definiert field_something
:
$wrapper = entity_metadata_wrapper('node', node_load($nid));
$value = $wrapper->field_something->value();
Das erste Problem, das ich habe, ist, dass ich vorher nicht wissen kann, ob ich einen tatsächlichen Wert (eine Zeichenfolge, eine Entität usw.), einen anderen Metadatenstruktur-Wrapper (wenn Felder mehrere Werte haben) oder ein Array (wenn) erhalte Felder haben mehrere Eigenschaften).
Ich habe einen Weg gefunden, diese Fragen mit der info()
Methode zu beantworten :
$info = $wrapper->field_something->info();
$is_multi_value = (strpos($info['type'], 'list<') === 0);
$has_multiple_properties = isset($info['property info']]);
Das ist jedoch kaum praktikabel. Wenn ich ein Feld verwenden möchte, ohne vorher die Definition zu kennen, muss ich mehrere Fälle berücksichtigen. Das macht meinen Code ziemlich schwer.
Um damit umzugehen, habe ich einen Code geschrieben, der:
- Stellt sicher, dass immer ein Array zurückgegeben wird, auch wenn es sich um ein einzelnes Wertefeld handelt.
- Wenn mehrere Eigenschaften vorhanden sind, geben Sie den Wert der ersten Spalte zurück.
Punkt 1. hier wird immer funktionieren, es sei denn, der Anrufer möchte wissen, ob dies ein einzelnes Wertefeld war oder nicht. Punkt 2 funktioniert in einigen Fällen nicht bei allen, ist aber praktisch, wenn es zutrifft.
Hier ist der 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;
}
Meine Frage lautet daher: Gibt es einfachere / bessere Möglichkeiten, um dieses Problem des Abrufs von Werten aus dem Metadaten-Wrapper zu lösen, wenn der Feldtyp nicht bekannt ist?
Da niemand eine andere Lösung gefunden hat, beantworte ich meine eigene Frage:
Es gibt keine einfachere Möglichkeit, auf Werte unbekannter Feldtypen zuzugreifen, wenn Entitätsmetadaten-Wrapper verwendet werden.
Es gibt alternative Methoden zu der, die ich anfangs beschrieben habe (zum Beispiel jene, auf die @thepearson hingewiesen hat). Insbesondere ist diese Methode nützlich:
Es gibt den aufgelisteten Typ zurück, wenn Ihr Typ eine Liste ist (z. B. 'Ganzzahl', wenn Ihr Typ 'Liste <Ganzzahl>' ist) oder false, wenn Ihr Typ keine Liste ist. Intern funktioniert ein strpos genau wie der Code, den ich ursprünglich gepostet habe, aber ich denke, es ist zukunftssicherer.
Die Schlussfolgerung ist, dass:
Entitäts-Metadaten-Wrapper funktionieren gut, wenn Sie keine Ahnung von Ihren Feldtypen haben und jeden möglichen Fall sorgfältig behandeln möchten.
Entitätsmetadaten-Wrapper funktionieren gut, wenn Sie genau wissen, welche Typen Ihre Felder haben und diese verwenden möchten.
Wenn Sie nur eine Vorstellung davon haben, wie Ihre Feldtypen aussehen (z. B. der gesamte Text, aber Sie wissen nicht, ob sie formatiert sind oder nicht, und Sie wissen nicht, ob sie ein- oder mehrwertige Metadaten-Wrapper sind), verwenden Sie Entity-Metadaten-Wrapper Geben Sie keine Abkürzungen an, und Sie müssen Ihre eigenen schreiben, wie ich es in der ersten Frage getan habe.
quelle
Für die Einzel- / Mehrfachfeldprüfung habe ich es nützlich gefunden, den Typ des Wrapper-Objekts zu testen, der
EntityListWrapper
für ein mehrwertiges Feld undEntityValueWrapper
für ein einwertiges Feld gilt:quelle
if($wrapper->field_name instanceof EntityListWrapper) {...}