Làm thế nào để bạn xóa một giá trị trường với entity_metadata_wrapper ()?


20

Giả sử tôi có một thực thể với một trường field_footrên đó và tôi muốn xóa giá trị của trường đó.

Tôi nên vượt qua để làm $wrapper->set()gì?

Tôi đã thử NULLarray()cả hai đều tạo ra một thông báo lỗi.


1
Bạn đang tìm kiếm EntityStructureWrapper::clear()hoặc EntityValueWrapper::clear()phương pháp có lẽ?
Clive

Gọi ::cleartrực tiếp không tương đương với việc đặt trường thành một giá trị trống, vì nó không gọi updateParenttheo cách gọi setvới giá trị trống. Trong số những thứ khác, updateParentđảm bảo rằng setter callbackđịnh nghĩa trong thông tin thuộc tính (xem drupalcontrib.org/api/drupal/ mẹo ) được gọi.
Alice Heaton

Câu trả lời:


24

Vấn đề là bạn phải đặt một giá trị trống tương thích với kiểu dữ liệu của trường của bạn. Nếu bạn không, bạn sẽ có một ngoại lệ được nêu ra. Do đó, việc vượt qua NULLhoặc array()khi một chuỗi được mong đợi sẽ gây ra lỗi.

Một lưu ý khác là dữ liệu bạn truyền cũng sẽ phụ thuộc vào việc trường của bạn là một giá trị đơn, trường đa giá trị hay trường có nhiều thuộc tính.

Nếu trường của bạn là một giá trị duy nhất (và do đó, trình bao bọc cho trường là một thể hiện của EntityValueWrapper ) thì bạn nên gán cho nó một giá trị trống tương thích với loại dữ liệu được đề cập . Ví dụ, hai phương thức sau là tương đương:

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

Tuy nhiên, ba ví dụ sau đây sẽ đưa ra một ngoại lệ, vì các kiểu dữ liệu không tương thích với titletrường:

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

Nếu trường của bạn là một trường có nhiều thuộc tính (ví dụ: trường văn bản được định dạng, xác định cả a valuevà thuộc formattính) và do đó, một thể hiện của EntityStr structWrapper , thì array()hoặc NULLsẽ là giá trị trống chính xác. Vì vậy, bạn có thể làm như sau:

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

Nhưng trong trường hợp đó, việc truyền một chuỗi rỗng sẽ gây ra lỗi. Lưu ý rằng bạn có thể đã chọn làm cho thuộc valuetính trống thay vào đó, trong trường hợp đó, một chuỗi là kiểu dữ liệu chính xác:

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

Cuối cùng, nếu trường của bạn là trường đa giá trị (và do đó, trình bao bọc của bạn là một thể hiện của EntityListWrapper ) thì arrayhoặc NULLlà các giá trị trống chính xác và ba dòng sau là tương đương:

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

Lưu ý: Gọi clearphương thức trên các hàm bao không tương đương với việc đặt trường thành một giá trị trống. Khi trường được đặt thành một giá trị trống, nó sẽ gọi EntityMetadataWrapper :: updateParent trên trình bao bọc cha của trường. Điều này đảm bảo trong số những thứ khác setter callbackđược định nghĩa bởi hook_entity_property_info được gọi. Gọi điện thoại clearkhông làm điều đó.


1
Lưu ý rằng nếu trường là nhiều bắt buộc, cài đặt là array()hoặc NULLcó thể thất bại, vì trường không thể để trống. Điều này khác với $nodephân công trường bình thường , nơi bạn có thể lập trình lưu một trường bắt buộc trống (nó sẽ không lưu thông qua UI của Drupal). Trong trường hợp này, một cách giải quyết là array(N), trong đó N là ID của một thực thể chưa được tham chiếu. Lưu ý rằng nó sẽ lưu với ID đó, vì vậy dữ liệu của bạn được cho là "bị hỏng" theo nghĩa quan hệ; nhưng nó không ảnh hưởng đến lớp chủ đề nếu bạn đang thực hiện tất cả những điều đúng ở đó (ví dụ: sử dụng Display Suite hoặc Bảng điều khiển).
JP

$w->field_allowed_regions->set(array(null));là tùy chọn duy nhất hoạt động cho trường tham chiếu phân loại đa giá trị của tôi.
Không thể tin được vào

Trong trường hợp của tôi, tôi có một trường tham chiếu thực thể với một giá trị duy nhất. Các công việc sau đây đối với tôi: $ Wrapper-> field_entity_Vference-> set (NULL);
Marcos Buarque

3

Hơn nữa với các câu trả lời và nhận xét khác, nếu trường là nhiều bắt buộc, như đã lưu ý trước đó, bạn không thể sử dụng

$wrapper->field_example_multiple->set()

$wrapper->field_example_multiple->set(NULL)

hay thậm chí $wrapper->field_example_multiple->set(array()),

nhưng thay vào đó, bạn có thể sử dụng các mục sau nếu bạn muốn xóa trường của tất cả các giá trị của nó:

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

Trên thực tế, điều này hoạt động cho dù trường nhiều giá trị có được đặt thành 'bắt buộc' hay không, và vì vậy tôi khuyên bạn nên luôn luôn sử dụng điều này, để đảm bảo rằng mã của bạn mạnh mẽ.

(Tất nhiên, nếu trường là 'bắt buộc' thì có lẽ bạn không nên xóa hoàn toàn nó, nhưng mã của bạn có thể thực hiện điều này như một bước sơ bộ để xóa toàn bộ thực thể hoặc một cái gì đó tương tự, vì vậy đôi khi nó có thể chỉ cần hợp pháp.)


Xin lưu ý rằng việc sử dụng `$ Wrapper-> field_example_mult Môn-> set (mảng (NULL))` sẽ dẫn đến việc có một phần tử NULL trong mảng dữ liệu. Phương thức này không xóa các giá trị mà chỉ đặt mảng giá trị thành một NULLgiá trị.
Alex Skrypnyk

Điểm tốt. Tôi đoán điều đó trả lại cho chúng tôi nhận xét của tôi về việc không xóa một giá trị bắt buộc. Nó có thể được thực hiện không thể cố ý.
Martin Q

Trong thực tế, một trường bắt buộc phải có ít nhất một giá trị khác không. Nếu bạn muốn đặt lại một trường đa trị bắt buộc, chỉ cần ghi đè lên nó bằng giá trị mới. Tức là:$product_display->field_product = array($product_id);
Interdruper

2

Dường như sự phức tạp được liệt kê trong các bình luận khác chỉ liên quan đến một trường bắt buộc. Nếu trường không bắt buộc, thì điều này sẽ khá đơn giản:

$wrapper->field_foo = NULL;

Bạn có thể sử dụng trình bao bọc để kiểm tra các thuộc tính của trường:

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

Tùy thuộc vào ngữ cảnh, bạn cũng có thể lấy các thuộc tính của một trường bằng cách sử dụng:

$wrapper->getPropertyInfo('field_foo');

1

Một giải pháp khác cho vấn đề này có thể là EntityMetadataWrapper::clear

$entity_wrapper->field->clear()


EntityMetadataWrapper :: phương thức xóa được khai báo là "được bảo vệ", do đó không thể gọi nó từ mã của bạn: chỉ các phương thức "công khai" có thể được truy cập trực tiếp từ bên ngoài đối tượng.
Interdruper
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.