คุณจะล้างค่าฟิลด์ด้วย entity_metadata_wrapper () ได้อย่างไร?


20

สมมติว่าฉันมีเอนทิตีที่มีเขตข้อมูลfield_fooอยู่และฉันต้องการล้างค่าของเขตข้อมูลนั้น

ฉันควรส่งผ่านไปยัง$wrapper->set()อะไร?

ฉันลองNULLแล้วarray()และทั้งคู่ก็เกิดข้อความแสดงข้อผิดพลาด


1
คุณกำลังมองหาวิธีการEntityStructureWrapper::clear()หรือEntityValueWrapper::clear()บางที?
ไคลฟ์

การโทร::clearโดยตรงไม่เท่ากับการตั้งค่าเขตข้อมูลเป็นค่าว่างเนื่องจากจะไม่เรียกupdateParentในลักษณะการโทรsetด้วยค่าว่าง ท่ามกลางสิ่งอื่น ๆupdateParentตรวจสอบให้แน่ใจว่ามีการเรียกข้อมูลที่setter callbackกำหนดไว้ในข้อมูลทรัพย์สิน (ดูdrupalcontrib.org/api/drupal/ … )
อลิซ Heaton

คำตอบ:


24

ปัญหาคือคุณต้องตั้งค่าว่างที่เข้ากันได้กับชนิดข้อมูลของเขตข้อมูลของคุณ หากคุณไม่ทำคุณจะได้รับการยกเว้น การผ่านNULLหรือarray()เมื่อคาดว่าจะมีสตริงจะทำให้เกิดข้อผิดพลาด

สิ่งที่ควรทราบก็คือข้อมูลที่คุณส่งจะขึ้นอยู่กับว่าเขตข้อมูลของคุณเป็นค่าเดียวเขตข้อมูลหลายค่าหรือเขตข้อมูลที่มีคุณสมบัติหลายอย่าง

ถ้าเขตของคุณเป็นค่าเดียว (และเสื้อคลุมสำหรับฟิลด์เป็นตัวอย่างของEntityValueWrapper ) แล้วคุณควรกำหนดค่าว่างเข้ากันได้กับชนิดข้อมูลในคำถาม เช่นวิธีการสองวิธีต่อไปนี้เทียบเท่ากัน:

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

อย่างไรก็ตามตัวอย่างสามตัวอย่างต่อไปนี้จะยกข้อยกเว้นเนื่องจากชนิดข้อมูลไม่เข้ากันกับtitleเขตข้อมูล:

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

ถ้าเขตของคุณเป็นเขตที่มีคุณสมบัติหลาย (เช่นสนามจัดรูปแบบข้อความที่กำหนดไว้ทั้งสองvalueและformatอสังหาริมทรัพย์) และทำให้เป็นตัวอย่างของEntityStructureWrapperแล้วarray()หรือNULLจะเป็นค่าที่ว่างเปล่าที่ถูกต้อง ดังนั้นคุณสามารถทำสิ่งต่อไปนี้:

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

แต่ในกรณีนั้นการส่งสตริงว่างจะทำให้เกิดข้อผิดพลาด โปรดทราบว่าคุณสามารถเลือกที่จะทำให้valueคุณสมบัติว่างเปล่าแทนซึ่งในกรณีนี้สตริงเป็นชนิดข้อมูลที่ถูกต้อง:

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

ในที่สุดถ้าเขตข้อมูลของคุณเป็นเขตข้อมูลที่มีหลายค่า (และทำให้ wrapper ของคุณเป็นตัวอย่างของEntityListWrapper ) ดังนั้นarrayหรือNULLเป็นค่าว่างที่ถูกต้องและสามบรรทัดต่อไปนี้เทียบเท่ากัน:

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

หมายเหตุ: การเรียกใช้clearเมธอดบนตัวตัดคำไม่เทียบเท่ากับการตั้งค่าฟิลด์เป็นค่าว่าง เมื่อเขตข้อมูลถูกตั้งค่าเป็นค่าว่างมันจะเรียกEntityMetadataWrapper :: updateParentบน wrapper หลักของเขตข้อมูล สิ่งนี้ทำให้แน่ใจได้ว่ามีสิ่งอื่น ๆ ที่hook_entity_property_infosetter callbackกำหนดไว้ถูกเรียก การโทรไม่ได้ทำเช่นนั้นclear


1
โปรดทราบว่าหากฟิลด์มีหลายรายการและจำเป็นต้องตั้งค่าเป็นarray()หรือNULLอาจล้มเหลวเนื่องจากฟิลด์ไม่สามารถว่างเปล่าได้ ซึ่งแตกต่างจากการ$nodeกำหนดฟิลด์ปกติซึ่งคุณสามารถบันทึกฟิลด์ที่ต้องการโดยทางโปรแกรมไว้ (โดยจะไม่บันทึกผ่าน UI ของ Drupal เอง) ในกรณีนี้การแก้ปัญหาคือarray(N)โดยที่ N คือ ID ของเอนทิตีที่ยังไม่มีอยู่ที่อ้างอิง โปรดทราบว่ามันจะบันทึกด้วย ID นั้นดังนั้นข้อมูลของคุณจึง "เสีย" อย่างมีเหตุผล แต่จะไม่ส่งผลกระทบต่อเลเยอร์ของธีมหากคุณทำสิ่งที่ถูกต้องทั้งหมดที่นั่น (เช่นใช้ Display Suite หรือ Panels)
JP

$w->field_allowed_regions->set(array(null));เป็นตัวเลือกเดียวที่ทำงานกับเขตข้อมูลอ้างอิงอนุกรมวิธานหลายค่าของฉัน
เหลือเชื่อ

ในกรณีของฉันฉันมีเขตข้อมูลอ้างอิงเอนทิตีที่มีค่าเดียว การทำงานต่อไปนี้สำหรับฉัน: $ wrapper-> field_entity_reference-> set (NULL);
Marcos Buarque

3

นอกเหนือจากคำตอบและความคิดเห็นอื่น ๆ หากฟิลด์มีความหลากหลายและจำเป็นตามที่ระบุไว้ก่อนหน้านี้คุณไม่สามารถใช้

$wrapper->field_example_multiple->set()

$wrapper->field_example_multiple->set(NULL)

หรือแม้กระทั่ง$wrapper->field_example_multiple->set(array()),

แต่คุณสามารถใช้สิ่งต่อไปนี้แทนหากคุณต้องการล้างฟิลด์ของค่าทั้งหมด:

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

อันที่จริงมันใช้งานได้หรือไม่ว่าฟิลด์หลายค่าถูกตั้งค่าเป็น 'จำเป็น' และดังนั้นฉันขอแนะนำให้ใช้สิ่งนี้เสมอเพื่อให้แน่ใจว่ารหัสของคุณมีความสมบูรณ์

(แน่นอนถ้าฟิลด์ 'จำเป็น' คุณอาจไม่ควรล้างมันทั้งหมด แต่รหัสของคุณอาจทำเช่นนี้เป็นขั้นตอนเบื้องต้นในการลบเอนทิตีทั้งหมดหรือสิ่งที่คล้ายกันดังนั้นจึงมีบางครั้งที่มันอาจจะ เพียงแค่ถูกต้องตามกฎหมาย)


ระวังให้ดีว่าการใช้ `$ wrapper-> field_example_multiple-> set (array (NULL))` จะนำไปสู่การมีองค์ประกอบ NULL ในอาร์เรย์ข้อมูล วิธีการนี้ไม่ได้ล้างค่า แต่ตั้งค่าอาร์เรย์เป็นNULLค่าเดียว
Alex Skrypnyk

จุดดี. ฉันเดาว่าจะให้เรากลับไปที่คำพูดของฉันเกี่ยวกับการไม่ล้างค่าที่ต้องการ มันอาจจะทำให้เป็นไปไม่ได้โดยเจตนา
Martin Q

ในความเป็นจริงฟิลด์ที่จำเป็นต้องมีอย่างน้อยหนึ่งค่าที่ไม่ใช่ศูนย์ หากคุณต้องการรีเซ็ตฟิลด์ที่มีหลายค่าตามต้องการเพียงเขียนทับด้วยค่าใหม่ เช่น:$product_display->field_product = array($product_id);
ดูแลระหว่าง

2

ปรากฏว่าความซับซ้อนที่ระบุไว้ในความคิดเห็นอื่นจะเกี่ยวข้องเฉพาะกับฟิลด์ที่จำเป็น หากไม่จำเป็นต้องใช้ฟิลด์สิ่งนี้ควรเป็นเรื่องง่าย:

$wrapper->field_foo = NULL;

คุณสามารถใช้ wrapper เพื่อตรวจสอบคุณสมบัติของฟิลด์:

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

ขึ้นอยู่กับบริบทคุณสามารถรับคุณสมบัติของเขตข้อมูลเดียวโดยใช้:

$wrapper->getPropertyInfo('field_foo');

1

วิธีแก้ไขปัญหาอื่นอาจเป็น EntityMetadataWrapper::clear

$entity_wrapper->field->clear()


EntityMetadataWrapper :: เมธอด clear ถูกประกาศเป็น "ป้องกัน" ดังนั้นจึงไม่สามารถเรียกได้จากรหัสของคุณ: มีเพียงวิธี "สาธารณะ" เท่านั้นที่สามารถเข้าถึงได้โดยตรงจากภายนอกวัตถุ
Interdruper
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.