Как очистить значение поля с 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/… ).
Алиса Хитон

Ответы:


24

Проблема в том, что вы должны установить пустое значение, которое совместимо с типом данных вашего поля. Если вы этого не сделаете, вы получите исключение. Поэтому передача NULLили array()ожидание строки вызовет ошибку.

Следует также помнить, что передаваемые данные также будут зависеть от того, является ли ваше поле одним значением, полем с несколькими значениями или полем с несколькими свойствами.

Если ваше поле представляет собой одно значение (и, следовательно, оболочка для поля является экземпляром EntityValueWrapper ), вам следует присвоить ему пустое значение, совместимое с данным типом данных . Например, два следующих метода эквивалентны:

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

Однако следующие три примера вызовут исключение, потому что типы данных не совместимы с titleполем:

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

Если ваше поле является полем с несколькими свойствами (например, форматированным текстовым полем, в котором определены как a, так valueи formatсвойством) и, таким образом, экземпляром EntityStructureWrapper , то array()или NULLбудет правильным пустым значением. Таким образом, вы можете сделать следующее:

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

Но в этом случае передача пустой строки вызвала бы ошибку. Обратите внимание, что вы могли бы valueвместо этого сделать свойство пустым, и в этом случае строка является правильным типом данных:

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

Наконец, если ваше поле является полем с несколькими значениями (и, следовательно, ваша обертка является экземпляром EntityListWrapper ), то arrayили NULLявляются правильными пустыми значениями, и следующие три строки эквивалентны:

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

Примечание. Вызов clearметода для оболочек не эквивалентен установке поля в пустое значение. Когда для поля установлено пустое значение, оно вызывает EntityMetadataWrapper :: updateParent для родительской оболочки поля. Это обеспечивает, помимо прочего, то, что setter callbackопределено в hook_entity_property_info . Звонок clearне делает этого.


1
Обратите внимание, что если поле является множественным и обязательным, установка как array()или NULLможет завершиться ошибкой, поскольку поле не может быть пустым. Это отличается от обычного $nodeназначения полей, где вы можете программно сохранить пустое обязательное поле (оно просто не будет сохраняться через собственный пользовательский интерфейс Drupal). В этом случае обходной путь - это array(N), где N - это идентификатор несуществующего, но на который ссылаются объекта. Обратите внимание, что он будет сохранен с этим идентификатором, поэтому ваши данные могут быть «сломаны» в реляционном смысле; но это не должно влиять на слой темы, если вы все делаете правильно (например, используете Display Suite или Panels).
JP

$w->field_allowed_regions->set(array(null));это единственный вариант, который работал для моего справочного поля многозначной таксономии.
Невероятно,

В моем случае у меня есть поле ссылки на сущность с одним значением. У меня сработало следующее: $ wrapper-> field_entity_reference-> set (NULL);
Маркос Бурке

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значение.
Алексей Скрипник,

Хорошая точка зрения. Я предполагаю, что это возвращает нас к моему замечанию о том, что мы не очищаем требуемое значение. Это, вероятно, сделано невозможным намеренно.
Мартин К

Фактически, обязательное поле должно иметь хотя бы одно ненулевое значение. Если вы хотите сбросить обязательное многозначное поле, просто замените его новым значением. $product_display->field_product = array($product_id);
То

2

Похоже, что сложности, перечисленные в других комментариях, относятся только к обязательному полю. Если поле не является обязательным, то это должно быть довольно просто:

$wrapper->field_foo = NULL;

Вы можете использовать оболочку, чтобы проверить свойства поля:

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

В зависимости от контекста, вы также можете просто получить свойства одного поля, используя:

$wrapper->getPropertyInfo('field_foo');

1

Другое решение этой проблемы может быть EntityMetadataWrapper::clear

$entity_wrapper->field->clear()


EntityMetadataWrapper :: clear метод объявлен как «защищенный», поэтому он не может быть вызван из вашего кода: только «публичные» методы могут быть доступны напрямую из-за пределов объекта.
Interdruper
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.