Як очистити значення поля за допомогою_данних__данних_)?


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визначеним hoke_entity_property_info . Дзвінки clearцього не роблять.


1
Зауважте, що якщо поле декілька і потрібне, встановлення як array()або NULLможе бути невдалим, оскільки поле не може бути порожнім. Це відрізняється від звичайного $nodeпризначення поля, де ви можете програмно зберегти порожнє необхідне поле (воно просто не збережеться через власний інтерфейс Drupal). У цьому випадку вирішується спосіб array(N), де N - ідентифікатор неіснуючого, ще посилається сутності. Зауважте, що це збереже за допомогою цього ідентифікатора, тому ваші дані, ймовірно, "порушені" у реляційному сенсі; але це не повинно впливати на рівень теми, якщо ви робите там усі потрібні речі (наприклад, використовуючи Медіа-пакет або Панелі).
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 (масив (NULL))" призведе до появи елемента NULL в масиві даних. Цей метод не очищує значення, а встановлює масив значень на одне NULLзначення.
Олексій Скрипник

Гарна думка. Я думаю, що це повертає нас до мого зауваження про не очищення необхідного значення. Це, мабуть, умисне неможливо.
Мартін Q

Фактично, обов'язкове поле повинно мати принаймні одне ненулеве значення. Якщо ви хочете скинути необхідне багатозначне поле, просто перезапишіть його новим значенням. Тобто:$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.