Accesso a valori di tipi di campo sconosciuti quando si utilizza entity_metadata_wrapper


12

Ho cercato di utilizzare le classi di wrapper di metadati di entità (definite dal modulo entità in Drupal 7) per accedere ai valori dei campi, poiché questo sembra essere un modo pulito per farlo.

Ci sono un paio di cose che lo rendono un po 'imbarazzante comunque. Supponiamo di avere un wrapper per un tipo di contenuto che definisce un campo denominato field_somethingcome tale:

$wrapper = entity_metadata_wrapper('node', node_load($nid));
$value = $wrapper->field_something->value();

Il primo problema che ho è che non ho modo di sapere in anticipo se ciò che ottengo è un valore effettivo (una stringa, un'entità, ecc.), Un altro wrapper di struttura di metadati (quando i campi hanno più valori) o un array (quando i campi hanno più proprietà).

Ho trovato il modo di rispondere a queste domande usando il info()metodo:

$info = $wrapper->field_something->info();
$is_multi_value = (strpos($info['type'], 'list<') === 0);
$has_multiple_properties = isset($info['property info']]);

Tuttavia, questo non è pratico. Ogni volta che voglio usare un campo senza conoscerne prima la definizione, devo prendere in considerazione diversi casi. Questo rende il mio codice abbastanza pesante.

Per far fronte a questo ho scritto un codice che:

  1. Assicura che venga sempre restituito un array, anche se si tratta di un campo a valore singolo;
  2. Quando sono presenti più proprietà, restituisce il valore della prima colonna.

Il punto 1. qui funzionerà sempre, a meno che il chiamante non voglia sapere se si tratta o meno di un campo a valore singolo. Il punto 2 funziona in alcuni casi, non tutti, ma è conveniente quando si applica.

Ecco il codice:

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

Quindi la mia domanda è: ci sono modi più semplici / migliori per affrontare questo problema di ottenere valori dal wrapper dei metadati quando il tipo di campo non è noto?

Risposte:


4

Ecco alcuni suggerimenti per rendere questo processo un po 'più semplice.

$wrapper->field_something->type();

restituirà il tipo di campo, vale a dire node, taxonomy_term, integer, textecc Si potrebbe quindi gestire il valore restituito da $wrapper->field_something->value()correttamente.

Anche

$wrapper->field_something->raw()

restituirà il valore grezzo del campo. Che sarà o arraynel caso di campi multivalore del solo valore. Ad esempio, un entity_referencesarà l' nidID (o l'entità) dell'entità referenziata o un arrayID dell'entità referenziata.


Ops, l'ho inserito troppo in fretta! Volevo aggiungere: $ wrapper-> field_something-> type () restituisce le stesse informazioni dell'elemento 'type' dell'array restituito da $ wrapper-> field_something-> info (). Fondamentalmente, restituisce comunque una stringa "list <type>" per i tipi a più valori, quindi ho ancora bisogno di uno strpos (o equivalente) per capire che è multivalore (se voglio elaborarlo prima di recuperarlo).
Alice Heaton,

Per quanto riguarda il secondo punto: posso davvero capire se è multivalore testando il ritorno di -> raw () o di -> value (), tuttavia preferirei sapere prima di recuperare il valore, come se fosse multivalore Voglio eseguirlo attraverso un ciclo foreach con -> getIterator () piuttosto che passare manualmente attraverso l'array che mi richiede di ricreare un wrapper per ciascun elemento.
Alice Heaton,

3

Quindi, poiché nessuno ha trovato un'altra soluzione, risponderò alla mia domanda:

Non esiste un modo più semplice per accedere a valori di tipi di campo sconosciuti quando si utilizzano wrapper di metadati di entità.

Esistono metodi alternativi a quello che ho inizialmente descritto (ad esempio quelli indicati da @thepearson). In particolare questo metodo è utile:

 entity_property_list_extract_type($type)

Restituirà il tipo elencato se il tuo tipo è un elenco (ad es. 'Intero' se il tuo tipo è 'list <intero>'), o falso se il tuo tipo non è un elenco. Internamente fa uno strpos proprio come il codice che ho inizialmente pubblicato, ma immagino che sia più a prova di futuro.

La conclusione è che:

  • I wrapper di metadati delle entità funzionano bene se non si ha idea dei tipi di campo e si desidera affrontare attentamente ogni possibile caso;

  • I wrapper dei metadati delle entità funzionano bene se sai esattamente quali tipi sono i tuoi campi e vuoi usarli;

  • Se hai solo alcune idee su come sono i tuoi tipi di campo (ad esempio tutto il testo, ma non sai se sono formattati o meno e non sai se sono singoli o multivalore), allora i wrapper dei metadati delle entità non fornire scorciatoie e devi scrivere le tue come ho fatto nella domanda iniziale.


1

Per il controllo del campo singolo / multiplo ho trovato utile testare il tipo di oggetto wrapper, che sarà EntityListWrapperper un campo a più valori e EntityValueWrapperper un campo a valore singolo:

<?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();
}

O addiritturaif($wrapper->field_name instanceof EntityListWrapper) {...}
Rudolfbyker,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.