Klemens Heinen, Drupal-Entwickler

Erklärung enity-Modul

Keine Angst vor "entity_metadata_wrapper"

Jeder, der in Drupal 7 auf Feldinhalte zugreifen musste, hat sich schon mal über den komplizierten Array-Aufbau gewundert oder sogar geärgert.

Verführerisch aber leider völlig falsch ist der Zugriff nach diesen Methoden:

$node->field_name['und'][0]['value'];
// oder
$node->field_name['de'][0]['value'];
// oder
$node->field_name[$node->language][0]['safe_value'];

Der erste Index steht für die aktuelle Sprache - und das kann sich ändern. Manchmal reicht es, einen Node auf Mehrsprachig und zurück auf einsprachig zu stellen und aus 'und' wird 'de'.

Zugriff über einfache Funktion

Es gibt eine nette Funktionen im Core, die genau das Gewünschte tut, aber etwas unkommod in der Anwendung ist.

Hier ein Beispiel:

// Wir holen uns alle Elemente eines Feldes
$items = field_get_items('node', $node, 'field_name');
// Value für das vierte Element des Feldes
$x = items [3];

Allgemein:

field_get_items(entity-typ, entity, feldname) liefert ein einfaches Array eines (Multi-)Feldinhalts und achtet auf die Sprache.

Das funktioniert zuverlässig, man braucht aber jedesmal einen Zweizeiler.

Hier ist das ganze sehr einleuchtend von Felix erklärt!

Zugriff über entity_metadata_wrapper()

Das entity Modul bietet auf Objektbasis eine gigantisch praktische Schreibweise an, die nach alter Drupal-Sitte reichlich undokumentiert ist.

Zuerst braucht man den Wrapper (hier um den Entity-Typen 'node' - könnte auch 'profile2' oder 'user' oder oder oder sein):

// Create wrapper around the node.
$wrapper = entity_metadata_wrapper('node', $node);

// We can do it also using only $nid.
$wrapper = entity_metadata_wrapper('node', $nid);

Der Wrapper ist ein Objekt über das jetzt zugegriffen werden kann:

// Get the value of field_name.
$wrapper->field_name->value();

// Value of the node's summary in german language.
$wrapper->language('de')->body->summary->value();

Erstaunlicherweise kann auch über References hinweg zugegriffen werden:

// Get the value of field_name of the nodes author's profile.
$wrapper = entity_metadata_wrapper('node', $ni);
$wrapper->author->profile->field_name->value();
$wrapper->author->profile->field_name->set('New name');

// Node hat Entity-Referenz zu Profil. Hole uid vom User des Profils
$uid = $wrapper->field_ref_label->profile_label->user->uid->value();

Und es gibt noch mehr Möglichkeiten:

// Check whether we can edit node's author email address.
$ok = $wrapper->author->mail->access('edit') ? TRUE : FALSE;

// Get possible roles of node's author.
$wrapper->author->roles->optionsList(); // Array aller Möglichkeiten

// Set description of the node's first file in field field_files.
$wrapper->field_files[0]->description = 'The first file';
$wrapper->save();

// Get node object.
$node = $wrapper->value();

Das Einzige was hilft, weil ja nix dokumentiert ist - untersuchen, welche Werte es gibt:

// Alle Properties ermitteln
$wrapper->getPropertyInfo();
$wrapper->field_ref_label->profile_label->getPropertyInfo();

Auf diese Weise kann man sich etwas herantasten.

Viel Spaß beim Experimentieren - es lohnt sich: diese Funktion soll Standard werden in Drupal 8.

PS: ohne Debugger ist man hier aufgeschmissen - is ja klar...

Kommentare

Bernhard - 12. Februar 2014 - 17:27
...zumindest, wenn man kein try...catch verwendet. EntityMetadataWrapper wirft gnadenlos Fehler beim Zugriff auf nicht vorhandene Werte. Es sollte daher immer in ein try...catch gekapselt werden: https://drupal.org/node/1021556
Micha - 22. Oktober 2012 - 9:55
Gefällt mir viel besser.
Klemens Heinen - 21. Oktober 2012 - 22:23
<p>... und falls Du noch weiteres rausfindest - mein Ohr+Aug ist gespitzt !</p>
Yannick - 21. Oktober 2012 - 12:15
Ich danke dir Klemens für diese kleine Zusammenfassung :)