Come si cancella un valore di campo con entity_metadata_wrapper ()?


20

Supponiamo di avere un'entità con un campo field_foosu di essa e desidero cancellare il valore di quel campo.

A cosa dovrei passare $wrapper->set()?

Ho provato NULLed array()entrambi producono un messaggio di errore.



Chiamare ::cleardirettamente non equivale a impostare il campo su un valore vuoto, poiché non chiama come fa updateParentla chiamata setcon un valore vuoto. Tra le altre cose, updateParentassicura che venga chiamato il setter callbackdefinito nelle informazioni sulla proprietà (vedi drupalcontrib.org/api/drupal/… ).
Alice Heaton,

Risposte:


24

Il problema è che devi impostare un valore vuoto compatibile con il tipo di dati del tuo campo. In caso contrario, verrà generata un'eccezione. Il passaggio NULLo array()quando è prevista una stringa genererà quindi un errore.

Un'altra cosa da tenere a mente è che i dati che passi dipenderanno anche dal fatto che il tuo campo sia un singolo valore, un campo multi-valore o un campo con più proprietà.

Se il tuo campo è un valore singolo (e quindi il wrapper per il campo è un'istanza di EntityValueWrapper ), devi assegnargli un valore vuoto compatibile con il tipo di dati in questione . Ad esempio i due seguenti metodi sono equivalenti:

$wrapper->title = '';
$wrapper->title->set('');

Tuttavia, i seguenti tre esempi solleveranno un'eccezione, poiché i tipi di dati non sono compatibili con il titlecampo:

$wrapper->title->set();
$wrapper->title->set(NULL);
$wrapper->title->set(array());

Se il tuo campo è un campo con più proprietà (ad esempio un campo di testo formattato, che ha definito sia a valueche formatproprietà) e quindi un'istanza di EntityStructureWrapper , allora array()o NULLsarà il valore vuoto corretto. Quindi puoi fare quanto segue:

$wrapper->field_formatted_text = array();
$wrapper->field_formatted_text = NULL;

Ma in quel caso, passare una stringa vuota avrebbe generato un errore. Nota che avresti potuto scegliere di rendere valuevuota la proprietà, nel qual caso una stringa è il tipo di dati corretto:

$wrapper->field_formatted_text->value = '';

Infine, se il tuo campo è un campo multi-valore (e quindi il tuo wrapper è un'istanza di EntityListWrapper ) allora arrayo NULLsono i valori vuoti corretti e le seguenti tre righe sono equivalenti:

$wrapper->field_example_multiple->set();
$wrapper->field_example_multiple = array();
$wrapper->field_example_multiple = NULL;

Nota: la chiamata del clearmetodo sui wrapper non equivale a impostare il campo su un valore vuoto. Quando il campo è impostato su un valore vuoto, chiama EntityMetadataWrapper :: updateParent sul wrapper principale del campo. Questo assicura tra l'altro che viene chiamato il setter callbackdefinito da hook_entity_property_info . La chiamata clearnon lo fa.


1
Si noti che se il campo è multiplo e obbligatorio, l'impostazione come array()o NULLpuò non riuscire, poiché il campo non può essere vuoto. Ciò è diverso dalla normale $nodeassegnazione di campo, in cui è possibile salvare a livello di programmazione un campo obbligatorio vuoto (semplicemente non verrà salvato tramite l'interfaccia utente di Drupal). In questo caso, una soluzione alternativa è array(N), dove N è l'ID di un'entità inesistente ma referenziata. Nota che salverà con quell'ID, quindi i tuoi dati sono probabilmente "rotti" in senso relazionale; ma non dovrebbe influire sul livello del tema se stai facendo tutte le cose giuste lì (ad esempio utilizzando Display Suite o pannelli).
JP

$w->field_allowed_regions->set(array(null));è l'unica opzione che ha funzionato per il mio campo di riferimento tassonomia multi-valore.
Incredibile

Nel mio caso ho un campo di riferimento dell'entità con un singolo valore. Per me ha funzionato: $ wrapper-> field_entity_reference-> set (NULL);
Marcos Buarque,

3

Oltre ad altre risposte e commenti, se il campo è multiplo e obbligatorio, come precedentemente indicato non è possibile utilizzare

$wrapper->field_example_multiple->set()

$wrapper->field_example_multiple->set(NULL)

e nemmeno $wrapper->field_example_multiple->set(array()),

ma invece puoi usare quanto segue se vuoi cancellare il campo da tutti i suoi valori:

$wrapper->field_example_multiple->set(array(NULL));

In effetti, questo funziona indipendentemente dal fatto che il campo a più valori sia impostato su "obbligatorio", e quindi ti consiglio di utilizzarlo sempre, per garantire che il tuo codice sia solido.

(Naturalmente, se il campo è 'obbligatorio', forse non dovresti comunque cancellarlo completamente, ma il tuo codice potrebbe farlo come un passaggio preliminare per eliminare l'intera entità o qualcosa di simile, quindi ci sono momenti in cui potrebbe sii legittimo.)


Tenere presente che l'uso di `$ wrapper-> field_example_multiple-> set (array (NULL))` comporterà la presenza di un elemento NULL nell'array di dati. Questo metodo non cancella i valori ma piuttosto imposta l'array dei valori su un singolo NULLvalore.
Alex Skrypnyk,

Buon punto. Immagino che ciò ci ritorni alla mia osservazione sul non cancellare un valore richiesto. Probabilmente è stato reso intenzionalmente impossibile.
Martin Q,

In effetti, un campo obbligatorio deve avere almeno un valore non nullo. Se si desidera ripristinare un campo multivalore richiesto, sovrascriverlo semplicemente con il nuovo valore. $product_display->field_product = array($product_id);
Vale a

2

Sembra che le complessità elencate negli altri commenti siano rilevanti solo per un campo obbligatorio. Se il campo non è richiesto, questo dovrebbe essere piuttosto semplice:

$wrapper->field_foo = NULL;

È possibile utilizzare il wrapper per verificare le proprietà del campo:

$properties = $wrapper->getPropertyInfo();
$field_required = !empty($properties['field_foo']['required']);

A seconda del contesto, puoi anche ottenere le proprietà di un campo usando:

$wrapper->getPropertyInfo('field_foo');

1

Un'altra soluzione per questo problema potrebbe essere EntityMetadataWrapper::clear

$entity_wrapper->field->clear()


Il metodo EntityMetadataWrapper :: clear è dichiarato "protetto", quindi non può essere chiamato dal tuo codice: solo i metodi "pubblici" sono accessibili direttamente dall'esterno dell'oggetto.
Interdruper
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.