Memanggil ::clearsecara langsung tidak setara dengan menyetel bidang ke nilai kosong, karena tidak memanggil updateParentseperti halnya panggilan setdengan nilai kosong. Di antara hal-hal lainnya, updateParentpastikan bahwa yang setter callbackdidefinisikan dalam info properti (lihat drupalcontrib.org/api/drupal/… ) dipanggil.
Alice Heaton
Jawaban:
24
Masalahnya adalah Anda harus menetapkan nilai kosong yang kompatibel dengan tipe data bidang Anda. Jika tidak, Anda akan mendapatkan pengecualian yang diajukan. Lewat NULLatau array()saat string diharapkan akan memunculkan kesalahan.
Hal lain yang perlu diingat adalah bahwa data yang Anda lewati juga akan bergantung pada apakah bidang Anda adalah nilai tunggal, bidang multi-nilai, atau bidang dengan beberapa properti.
Jika bidang Anda adalah nilai tunggal (dan karenanya pembungkus untuk bidang tersebut adalah turunan dari EntityValueWrapper ) maka Anda harus menetapkannya sebagai nilai kosong yang kompatibel dengan tipe data yang dimaksud . Misalnya, dua metode berikut ini setara:
$wrapper->title ='';
$wrapper->title->set('');
Namun tiga contoh berikut ini akan memunculkan pengecualian, karena tipe data tidak kompatibel dengan titlebidang:
Jika bidang Anda adalah bidang dengan beberapa properti (misalnya bidang teks yang diformat, yang mendefinisikan a valuedan formatproperti) dan dengan demikian merupakan contoh dari EntityStructureWrapper , maka array()atau NULLakan menjadi nilai kosong yang benar. Jadi, Anda dapat melakukan hal berikut:
Tetapi dalam kasus itu, melewatkan string kosong akan menimbulkan kesalahan. Perhatikan bahwa Anda bisa memilih untuk membuat valueproperti itu kosong, dalam hal ini string adalah tipe data yang benar:
$wrapper->field_formatted_text->value ='';
Akhirnya, jika bidang Anda adalah bidang multi-nilai (dan karenanya pembungkus Anda adalah turunan dari EntityListWrapper ) maka arrayatau NULLadalah nilai kosong yang benar, dan tiga baris berikut ini setara:
Catatan: Memanggil clearmetode pada pembungkus tidak sama dengan menyetel bidang ke nilai kosong. Ketika bidang diatur ke nilai kosong, maka panggilan EntityMetadataWrapper :: updateParent pada pembungkus induk bidang. Ini memastikan antara lain bahwa yang setter callbackdidefinisikan oleh hook_entity_property_info disebut. Memanggil cleartidak melakukan itu.
Perhatikan bahwa jika bidangnya banyak dan diperlukan, tetapkan sebagai array()atau NULLbisa gagal, karena bidang itu tidak boleh kosong. Ini berbeda dari $nodepenugasan bidang normal , di mana Anda secara terprogram dapat menyimpan bidang wajib yang kosong (tidak akan menghemat melalui UI Drupal sendiri). Dalam kasus ini, solusinya adalah array(N), di mana N adalah ID dari entitas yang belum ada yang direferensikan. Perhatikan bahwa ini akan disimpan dengan ID itu, sehingga data Anda bisa dibilang "rusak" dalam arti relasional; tetapi seharusnya tidak memengaruhi lapisan tema jika Anda melakukan semua hal yang benar di sana (misalnya menggunakan Display Suite atau Panel).
JP
$w->field_allowed_regions->set(array(null));adalah satu-satunya opsi yang berfungsi untuk bidang referensi taksonomi multi-nilai saya.
Luar biasa
Dalam kasus saya, saya memiliki bidang referensi entitas dengan nilai tunggal. Berikut ini bekerja untuk saya: $ wrapper-> field_entity_reference-> set (NULL);
Marcos Buarque
3
Selanjutnya untuk jawaban dan komentar lain, jika bidangnya banyak dan diperlukan, seperti yang disebutkan sebelumnya Anda tidak dapat menggunakan
$wrapper->field_example_multiple->set()
$wrapper->field_example_multiple->set(NULL)
bahkan tidak $wrapper->field_example_multiple->set(array()),
tetapi Anda dapat menggunakan yang berikut jika Anda ingin menghapus bidang semua nilainya:
Bahkan, ini berfungsi baik atau tidaknya bidang nilai berganda diatur ke 'wajib', jadi saya sarankan selalu gunakan ini, untuk memastikan bahwa kode Anda kuat.
(Tentu saja, jika bidangnya 'wajib' maka Anda mungkin tidak boleh benar-benar membersihkannya, tetapi kode Anda mungkin melakukan ini sebagai langkah awal untuk menghapus seluruh entitas atau sesuatu yang serupa, jadi ada kalanya mungkin sah saja.)
Ketahuilah bahwa menggunakan set `$ wrapper-> field_example_multiple-> (array (NULL))` akan menghasilkan elemen NULL dalam array data. Metode ini tidak menghapus nilai melainkan menetapkan array nilai ke NULLnilai tunggal .
Alex Skrypnyk
Poin bagus. Saya kira itu mengembalikan kita ke komentar saya tentang tidak membersihkan nilai yang diperlukan. Mungkin sengaja dibuat mustahil.
Martin Q
Pada kenyataannya, bidang yang diperlukan harus memiliki setidaknya satu nilai bukan nol. Jika Anda ingin mengatur ulang bidang multinilai yang diperlukan, cukup timpa dengan nilai baru. Yaitu:$product_display->field_product = array($product_id);
Interdruper
2
Tampaknya kompleksitas yang tercantum dalam komentar lain hanya relevan dengan bidang yang diperlukan. Jika bidang tidak diperlukan, maka ini seharusnya cukup sederhana:
$wrapper->field_foo = NULL;
Anda bisa menggunakan pembungkus untuk memeriksa properti bidang:
Metode EntityMetadataWrapper :: clear dinyatakan sebagai "protected", sehingga tidak dapat dipanggil dari kode Anda: hanya metode "publik" yang dapat diakses langsung dari luar objek.
EntityStructureWrapper::clear()
atauEntityValueWrapper::clear()
mungkin?::clear
secara langsung tidak setara dengan menyetel bidang ke nilai kosong, karena tidak memanggilupdateParent
seperti halnya panggilanset
dengan nilai kosong. Di antara hal-hal lainnya,updateParent
pastikan bahwa yangsetter callback
didefinisikan dalam info properti (lihat drupalcontrib.org/api/drupal/… ) dipanggil.Jawaban:
Masalahnya adalah Anda harus menetapkan nilai kosong yang kompatibel dengan tipe data bidang Anda. Jika tidak, Anda akan mendapatkan pengecualian yang diajukan. Lewat
NULL
atauarray()
saat string diharapkan akan memunculkan kesalahan.Hal lain yang perlu diingat adalah bahwa data yang Anda lewati juga akan bergantung pada apakah bidang Anda adalah nilai tunggal, bidang multi-nilai, atau bidang dengan beberapa properti.
Jika bidang Anda adalah nilai tunggal (dan karenanya pembungkus untuk bidang tersebut adalah turunan dari EntityValueWrapper ) maka Anda harus menetapkannya sebagai nilai kosong yang kompatibel dengan tipe data yang dimaksud . Misalnya, dua metode berikut ini setara:
Namun tiga contoh berikut ini akan memunculkan pengecualian, karena tipe data tidak kompatibel dengan
title
bidang:Jika bidang Anda adalah bidang dengan beberapa properti (misalnya bidang teks yang diformat, yang mendefinisikan a
value
danformat
properti) dan dengan demikian merupakan contoh dari EntityStructureWrapper , makaarray()
atauNULL
akan menjadi nilai kosong yang benar. Jadi, Anda dapat melakukan hal berikut:Tetapi dalam kasus itu, melewatkan string kosong akan menimbulkan kesalahan. Perhatikan bahwa Anda bisa memilih untuk membuat
value
properti itu kosong, dalam hal ini string adalah tipe data yang benar:Akhirnya, jika bidang Anda adalah bidang multi-nilai (dan karenanya pembungkus Anda adalah turunan dari EntityListWrapper ) maka
array
atauNULL
adalah nilai kosong yang benar, dan tiga baris berikut ini setara:Catatan: Memanggil
clear
metode pada pembungkus tidak sama dengan menyetel bidang ke nilai kosong. Ketika bidang diatur ke nilai kosong, maka panggilan EntityMetadataWrapper :: updateParent pada pembungkus induk bidang. Ini memastikan antara lain bahwa yangsetter callback
didefinisikan oleh hook_entity_property_info disebut. Memanggilclear
tidak melakukan itu.sumber
array()
atauNULL
bisa gagal, karena bidang itu tidak boleh kosong. Ini berbeda dari$node
penugasan bidang normal , di mana Anda secara terprogram dapat menyimpan bidang wajib yang kosong (tidak akan menghemat melalui UI Drupal sendiri). Dalam kasus ini, solusinya adalaharray(N)
, di mana N adalah ID dari entitas yang belum ada yang direferensikan. Perhatikan bahwa ini akan disimpan dengan ID itu, sehingga data Anda bisa dibilang "rusak" dalam arti relasional; tetapi seharusnya tidak memengaruhi lapisan tema jika Anda melakukan semua hal yang benar di sana (misalnya menggunakan Display Suite atau Panel).$w->field_allowed_regions->set(array(null));
adalah satu-satunya opsi yang berfungsi untuk bidang referensi taksonomi multi-nilai saya.Selanjutnya untuk jawaban dan komentar lain, jika bidangnya banyak dan diperlukan, seperti yang disebutkan sebelumnya Anda tidak dapat menggunakan
$wrapper->field_example_multiple->set()
$wrapper->field_example_multiple->set(NULL)
bahkan tidak
$wrapper->field_example_multiple->set(array())
,tetapi Anda dapat menggunakan yang berikut jika Anda ingin menghapus bidang semua nilainya:
Bahkan, ini berfungsi baik atau tidaknya bidang nilai berganda diatur ke 'wajib', jadi saya sarankan selalu gunakan ini, untuk memastikan bahwa kode Anda kuat.
(Tentu saja, jika bidangnya 'wajib' maka Anda mungkin tidak boleh benar-benar membersihkannya, tetapi kode Anda mungkin melakukan ini sebagai langkah awal untuk menghapus seluruh entitas atau sesuatu yang serupa, jadi ada kalanya mungkin sah saja.)
sumber
NULL
nilai tunggal .$product_display->field_product = array($product_id);
Tampaknya kompleksitas yang tercantum dalam komentar lain hanya relevan dengan bidang yang diperlukan. Jika bidang tidak diperlukan, maka ini seharusnya cukup sederhana:
Anda bisa menggunakan pembungkus untuk memeriksa properti bidang:
Bergantung pada konteksnya, Anda juga bisa mendapatkan properti dari satu bidang menggunakan:
sumber
Solusi lain untuk masalah ini bisa jadi
EntityMetadataWrapper::clear
$entity_wrapper->field->clear()
sumber