Wie löscht man einen Feldwert mit entity_metadata_wrapper ()?

20

Angenommen, ich habe eine Entität mit einem Feld field_foound möchte den Wert dieses Felds löschen.

Was soll ich weitergeben $wrapper->set()?

Ich habe versucht NULLund array()und beide erzeugen eine Fehlermeldung.

joachim
quelle
1
Suchst du vielleicht die EntityStructureWrapper::clear()oder EntityValueWrapper::clear()Methoden?
Clive
Ein ::cleardirekter Aufruf entspricht nicht dem Festlegen eines leeren Werts für das Feld, da er nicht updateParentauf die Weise aufgerufen wird, wie dies setbei einem Aufruf mit einem leeren Wert der Fall ist. Unter anderem wird updateParentsichergestellt, dass das setter callbackin der Eigenschaft definierte Info (siehe drupalcontrib.org/api/drupal/… ) aufgerufen wird.
Alice Heaton

Antworten:

24

Das Problem ist, dass Sie einen leeren Wert festlegen müssen, der mit dem Datentyp Ihres Felds kompatibel ist. Wenn Sie dies nicht tun, wird eine Ausnahme ausgelöst. Übergeben NULLoder array()wenn eine Zeichenfolge erwartet wird, wird daher ein Fehler ausgelöst.

Beachten Sie außerdem, dass die übergebenen Daten auch davon abhängen, ob es sich bei Ihrem Feld um einen einzelnen Wert, ein mehrwertiges Feld oder ein Feld mit mehreren Eigenschaften handelt.

Wenn Ihr Feld ein einzelner Wert ist (und der Wrapper für das Feld daher eine Instanz von EntityValueWrapper ist ), sollten Sie ihm einen leeren Wert zuweisen, der mit dem betreffenden Datentyp kompatibel ist . Zum Beispiel sind die beiden folgenden Methoden äquivalent:

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

Die folgenden drei Beispiele lösen jedoch eine Ausnahme aus, da die Datentypen nicht mit dem titleFeld kompatibel sind:

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

Wenn Ihr Feld ein Feld mit mehreren Eigenschaften ist (z. B. ein formatiertes Textfeld, das sowohl eine valueals auch eine formatEigenschaft definiert) und somit eine Instanz von EntityStructureWrapper , ist array()oder NULList dies der richtige leere Wert. Sie können also Folgendes tun:

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

In diesem Fall hätte die Übergabe einer leeren Zeichenfolge jedoch einen Fehler ausgelöst. Beachten Sie, dass Sie die valueEigenschaft auch leer lassen könnten. In diesem Fall ist eine Zeichenfolge der richtige Datentyp:

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

Wenn Ihr Feld ein Feld mit mehreren Werten ist (und Ihr Wrapper somit eine Instanz von EntityListWrapper ist ), dann sind arrayoder NULLdie richtigen leeren Werte und die folgenden drei Zeilen sind äquivalent:

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

Hinweis: Das Aufrufen der clearMethode für die Wrapper entspricht nicht dem Festlegen eines leeren Werts für das Feld. Wenn für das Feld ein leerer Wert festgelegt ist, wird EntityMetadataWrapper :: updateParent für den übergeordneten Wrapper des Felds aufgerufen . Dies stellt unter anderem sicher, dass das setter callbackdurch hook_entity_property_info definierte aufgerufen wird. Anrufen clearmacht das nicht.

Alice Heaton
quelle
1
Beachten Sie, dass bei mehreren und erforderlichen Feldern das Festlegen als array()oder NULLfehlschlagen kann, da das Feld nicht leer sein darf. Dies unterscheidet sich von der normalen $nodeFeldzuweisung, bei der Sie ein leeres erforderliches Feld programmgesteuert speichern können (es wird nur nicht über die Drupal-eigene Benutzeroberfläche gespeichert). In diesem Fall handelt es sich um eine Problemumgehung array(N), bei der N die ID einer noch nicht vorhandenen Entität ist , auf die verwiesen wird. Beachten Sie, dass es mit dieser ID gespeichert wird, sodass Ihre Daten im relationalen Sinne möglicherweise "defekt" sind. Dies sollte sich jedoch nicht auf die Designebene auswirken, wenn Sie dort die richtigen Schritte ausführen (z. B. mithilfe von Display Suite oder Panels).
JP
$w->field_allowed_regions->set(array(null));ist die einzige Option, die für mein mehrwertiges Taxonomie-Referenzfeld funktioniert hat.
Unglaubliche
In meinem Fall habe ich ein Entitätsreferenzfeld mit einem einzelnen Wert. Folgendes hat für mich funktioniert: $ wrapper-> field_entity_reference-> set (NULL);
Marcos Buarque
3

Zusätzlich zu anderen Antworten und Kommentaren können Sie dieses Feld nicht verwenden , wenn es mehrere Felder enthält und wie bereits erwähnt erforderlich ist

$wrapper->field_example_multiple->set()

$wrapper->field_example_multiple->set(NULL)

noch einmal $wrapper->field_example_multiple->set(array()),

Stattdessen können Sie Folgendes verwenden, um alle Werte aus dem Feld zu entfernen:

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

Tatsächlich funktioniert dies unabhängig davon, ob das Feld mit mehreren Werten auf "Erforderlich" gesetzt ist oder nicht. Daher würde ich empfehlen, dieses Feld immer zu verwenden, um sicherzustellen, dass Ihr Code robust ist.

(Wenn das Feld "erforderlich" ist, sollten Sie es möglicherweise trotzdem nicht vollständig löschen, aber Ihr Code tut dies möglicherweise als Vorstufe zum Löschen der gesamten Entität oder Ähnlichem. Es kann also vorkommen, dass dies erforderlich ist sei einfach legitim.)

Martin Q
quelle
Beachten Sie, dass die Verwendung von "$ wrapper-> field_example_multiple-> set (array (NULL))" dazu führt, dass das Datenarray ein NULL-Element enthält. Diese Methode löscht keine Werte, sondern setzt das Wertearray auf einen einzelnen NULLWert.
Alex Skrypnyk
Guter Punkt. Ich denke, das bringt uns zu meiner Bemerkung zurück, dass ein erforderlicher Wert nicht gelöscht wird. Es wird wahrscheinlich absichtlich unmöglich gemacht.
Martin Q
Tatsächlich muss ein erforderliches Feld mindestens einen Wert ungleich Null haben. Wenn Sie ein erforderliches mehrwertiges Feld zurücksetzen möchten, überschreiben Sie es einfach mit dem neuen Wert. Dh:$product_display->field_product = array($product_id);
Interdruper
2

Es scheint, dass die in den anderen Kommentaren aufgeführten Komplexitäten nur für ein erforderliches Feld relevant sind. Wenn das Feld nicht erforderlich ist, sollte dies ziemlich einfach sein:

$wrapper->field_foo = NULL;

Mit dem Wrapper können Sie die Eigenschaften des Felds überprüfen:

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

Abhängig vom Kontext können Sie auch nur die Eigenschaften des einen Felds abrufen, indem Sie Folgendes verwenden:

$wrapper->getPropertyInfo('field_foo');
Giles B
quelle
1

Eine andere Lösung für dieses Problem könnte sein EntityMetadataWrapper::clear

$entity_wrapper->field->clear()

Mouneer
quelle
Die EntityMetadataWrapper :: clear-Methode ist als "protected" deklariert, daher kann sie nicht aus Ihrem Code aufgerufen werden: Nur auf "public" -Methoden kann direkt von außerhalb des Objekts zugegriffen werden.
Interdruper