Zugriff auf Werte unbekannter Feldtypen bei Verwendung von entity_metadata_wrapper

12

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:

  1. Stellt sicher, dass immer ein Array zurückgegeben wird, auch wenn es sich um ein einzelnes Wertefeld handelt.
  2. 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?

Alice Heaton
quelle

Antworten:

4

Hier sind einige Vorschläge, um diesen Vorgang ein wenig zu vereinfachen.

$wrapper->field_something->type();

die Art des Feldes zurückkehren wird, das heißt node, taxonomy_term, integer, textetc. Sie dann wird der Wert von zurück umgehen konnte $wrapper->field_something->value()richtig.

Ebenfalls

$wrapper->field_something->raw()

Gibt den Rohwert des Feldes zurück. Welches wird entweder ein arrayim Fall von mehrwertigen Feldern nur der Wert sein. Beispielsweise ist ein entity_referencedie nid(oder Entitäts-ID) der Entität, auf die verwiesen wird, oder eine arrayder Entitäts-IDs, auf die verwiesen wird.

thepearson
quelle
Hoppla, das habe ich zu schnell eingegeben! Ich wollte hinzufügen: $ wrapper-> field_something-> type () gibt die gleichen Informationen zurück wie das 'type'-Element des Arrays, das von $ wrapper-> field_something-> info () zurückgegeben wurde. Entscheidend ist, dass es für mehrwertige Typen immer noch eine Zeichenfolge "list <type>" zurückgibt. Daher benötige ich immer noch ein strpos (oder ein Äquivalent), um zu ermitteln, ob es mehrwertig ist (wenn ich es vor dem Abrufen herausfinden möchte).
Alice Heaton
Was den zweiten Punkt betrifft: Ich kann in der Tat durch Testen der Rückgabe von -> raw () oder von -> value () herausfinden, ob der Wert mehrwertig ist Ich möchte es durch eine foreach-Schleife mit -> getIterator () ausführen, anstatt manuell durch das Array zu gehen, was erfordert, dass ich für jedes Element einen Wrapper neu erstelle.
Alice Heaton
3

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:

 entity_property_list_extract_type($type)

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.

Alice Heaton
quelle
1

Für die Einzel- / Mehrfachfeldprüfung habe ich es nützlich gefunden, den Typ des Wrapper-Objekts zu testen, der EntityListWrapperfür ein mehrwertiges Feld und EntityValueWrapperfür ein einwertiges Feld gilt:

<?php
...
$wrapper = entity_metadata_wrapper('user', $account);
// Get address, or first address if a multi-value field instance.
if (get_class($wrapper->field_address) == 'EntityListWrapper') {
  $value = $wrapper->field_address[0]->value();
}
else {
  $value = $wrapper->field_address->value();
}
Fonant
quelle
Oder sogarif($wrapper->field_name instanceof EntityListWrapper) {...}
Rudolfbyker