Jak wyczyścić wartość pola za pomocą entity_metadata_wrapper ()?


20

Załóżmy, że mam byt z polem field_fooi chcę wyczyścić wartość tego pola.

Co mam przekazać $wrapper->set()?

Próbowałem NULLi array()oba wyświetlają komunikat o błędzie.



Wywołanie ::clearbezpośrednie nie jest równoznaczne z ustawieniem pustej wartości w polu, ponieważ nie wywołuje updateParentsię tak , jak robi to wywołanie setz pustą wartością. Między innymi updateParentzapewnia wywołaniesetter callback zdefiniowanej w informacji o właściwości (patrz drupalcontrib.org/api/drupal/… ).
Alice Heaton

Odpowiedzi:


24

Problem polega na tym, że musisz ustawić pustą wartość, która jest zgodna z typem danych twojego pola. Jeśli tego nie zrobisz, pojawi się wyjątek. Przekazanie NULLlub array()oczekiwanie ciągu spowoduje zatem błąd.

Inną rzeczą, o której należy pamiętać, jest to, że przekazywane dane będą również zależeć od tego, czy twoje pole jest pojedynczą wartością, polem o wielu wartościach, czy polem o wielu właściwościach.

Jeśli twoje pole ma pojedynczą wartość (a zatem opakowanie dla tego pola jest instancją EntityValueWrapper ), powinieneś przypisać mu pustą wartość zgodną z danym typem danych . Na przykład dwie następujące metody są równoważne:

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

Jednak następujące trzy przykłady spowodują wyjątek, ponieważ typy danych nie są zgodne z titlepolem:

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

Jeśli twoje pole jest polem z wieloma właściwościami (na przykład sformatowanym polem tekstowym, które zdefiniowało zarówno a, jak valuei formatwłaściwość), a zatem wystąpieniem EntityStructureWrapper , wówczas array()lub NULLbędzie poprawna pusta wartość. Możesz więc wykonać następujące czynności:

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

Ale w takim przypadku przekazanie pustego ciągu spowodowałoby błąd. Zauważ, że możesz valuezamiast tego wybrać, aby właściwość była pusta, w którym to przypadku łańcuch jest poprawnym typem danych:

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

Wreszcie, jeśli twoje pole jest polem o wielu wartościach (a zatem twoje opakowanie jest instancją EntityListWrapper ), to arraylub NULLsą poprawnymi pustymi wartościami, a następujące trzy wiersze są równoważne:

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

Uwaga: Wywołanie clearmetody na opakowaniach nie jest równoważne ustawieniu pola na pustą wartość. Gdy pole jest ustawione na pustą wartość, wywołuje EntityMetadataWrapper :: updateParent na opakowaniu nadrzędnym pola. Zapewnia to między innymi, że wywoływane jest setter callbackzdefiniowane przez hook_entity_property_info . Dzwonienie cleartego nie robi.


1
Pamiętaj, że jeśli pole jest wielokrotne i wymagane, ustawienie jako array()lub NULLmoże się nie powieść, ponieważ pole nie może być puste. Różni się to od zwykłego $nodeprzypisania pola, w którym można programowo zapisać puste wymagane pole (po prostu nie będzie zapisywane przez własny interfejs użytkownika Drupala). W takim przypadku obejściem jest array(N), gdzie N jest identyfikatorem nieistniejącej jeszcze, do której istnieje odwołanie. Zauważ, że oszczędza się z tym identyfikatorem, więc twoje dane są prawdopodobnie „uszkodzone” w sensie relacyjnym; ale nie powinno to wpływać na warstwę motywu, jeśli robisz tam wszystkie właściwe rzeczy (np. używając Display Suite lub paneli).
JP

$w->field_allowed_regions->set(array(null));jest jedyną opcją, która działała w moim polu referencyjnym systematyki wielu wartości.
Incredible

W moim przypadku mam pole odniesienia encji z jedną wartością. Dla mnie działało: $ wrapper-> field_entity_reference-> set (NULL);
Marcos Buarque

3

Oprócz innych odpowiedzi i komentarzy, jeśli pole jest wielokrotne i wymagane, jak wspomniano wcześniej, nie można użyć

$wrapper->field_example_multiple->set()

$wrapper->field_example_multiple->set(NULL)

ani nawet $wrapper->field_example_multiple->set(array()),

ale zamiast tego możesz użyć następujących, jeśli chcesz wyczyścić pole wszystkich jego wartości:

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

W rzeczywistości działa to niezależnie od tego, czy pole wielokrotnej wartości jest ustawione na „wymagane”, dlatego zalecam zawsze używanie tego, aby mieć pewność, że kod jest niezawodny.

(Oczywiście, jeśli pole jest „wymagane”, być może nie powinieneś i tak całkowicie go wyczyścić, ale twój kod może to robić jako wstępny krok do usunięcia całej encji lub czegoś podobnego, więc są chwile, kiedy może po prostu bądź uzasadniony.)


Należy pamiętać, że użycie `$ wrapper-> field_example_multiple-> set (array (NULL))` prowadzi do posiadania elementu NULL w tablicy danych. Ta metoda nie usuwa wartości, ale ustawia tablicę wartości na jedną NULLwartość.
Alex Skrypnyk

Słuszna uwaga. Myślę, że to powraca do mojej uwagi na temat niezrealizowania wymaganej wartości. Prawdopodobnie jest to celowo niemożliwe.
Martin Q

W rzeczywistości wymagane pole musi mieć co najmniej jedną wartość inną niż null. Jeśli chcesz zresetować wymagane pole wielowartościowe, po prostu zastąp je nową wartością. To $product_display->field_product = array($product_id);
znaczy

2

Wydaje się, że złożoność wymieniona w innych komentarzach dotyczy tylko wymaganego pola. Jeśli pole nie jest wymagane, powinno to być dość proste:

$wrapper->field_foo = NULL;

Możesz użyć opakowania, aby sprawdzić właściwości pola:

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

W zależności od kontekstu możesz także uzyskać właściwości jednego pola za pomocą:

$wrapper->getPropertyInfo('field_foo');

1

Innym rozwiązaniem tego problemu może być EntityMetadataWrapper::clear

$entity_wrapper->field->clear()


Metoda EntityMetadataWrapper :: clear jest zadeklarowana jako „chroniona”, więc nie można jej wywołać z kodu: tylko metody „publiczne” są dostępne bezpośrednio z zewnątrz obiektu.
Interdruper
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.