Доступ до значень невідомих типів полів при використанні ent_metadata_wrapper


12

Я розглядав можливість використання класів обертання метаданих Entity (визначених модулем сутності в Drupal 7) для доступу до значень поля, оскільки це здається чистим способом.

Однак є кілька речей, які роблять це трохи незручно. Припустимо, у мене є обгортка для типу вмісту, яка визначає поле, назване field_somethingяк таке:

$wrapper = entity_metadata_wrapper('node', node_load($nid));
$value = $wrapper->field_something->value();

Перша проблема, яку я маю, полягає в тому, що я не маю можливості знати наперед, чи є те, що я отримую - це фактичне значення (рядок, сутність тощо), інша обгортка структури метаданих (коли поля мають кілька значень) або масив (коли поля мають кілька властивостей).

Я знайшов спосіб відповісти на ці запитання info()методом:

$info = $wrapper->field_something->info();
$is_multi_value = (strpos($info['type'], 'list<') === 0);
$has_multiple_properties = isset($info['property info']]);

Однак це навряд чи практично. Кожен раз, коли я хочу використовувати поле, не знаючи його визначення перед рукою, я повинен враховувати кілька випадків. Це робить мій код досить важким.

Для вирішення цього питання я написав код, який:

  1. Забезпечує, що нам завжди повертається масив, навіть якщо це єдине поле значення;
  2. Коли є кілька властивостей, поверніть значення першого стовпця.

Точка 1. тут завжди працюватиме, якщо тільки абонент не хоче знати, чи це поле єдиного значення чи ні. Точка 2 працює в деяких випадках не всі, але зручна, коли вона застосовується.

Ось код:

function entity_metadata_simple_values($field) {
  $fields = array();
  $values = array();
  $info = $field->info();
  if (strpos($info['type'], 'list<') === 0) {
    foreach ($field->getIterator() as $field_iteration) {
      $fields[] = $field_iteration;
    }
  } else {
    $fields[] = $field;
  }
  foreach ($fields as $final_field) {
    $ff_info = $final_field->info();
    if (isset($ff_info['property info'])) {
      $column = reset(array_keys($ff_info['property info']));
      $values[] = $final_field->{$column}->value();
    } else {
      $values[] = $final_field->value();
    }
  }

  return $values;
}

Отже, моє запитання: чи існують простіші / кращі способи вирішити цю проблему отримання значень із обгортки метаданих, коли тип поля не відомий?

Відповіді:


4

Ось кілька пропозицій, щоб полегшити цей процес.

$wrapper->field_something->type();

повертає тип поля, тобто node, taxonomy_term, integer, і textт.д. Потім можна обробити значення , повернене $wrapper->field_something->value()правильно.

Також

$wrapper->field_something->raw()

поверне необроблену вартість поля. Що буде або arrayу випадку багатозначних полів справедливого значення. Наприклад, ідентифікатором entity_referenceбуде nid(або ідентифікатор сутності) посилається об'єкта, або arrayідентифікатор ідентифікованого об'єкта.


Ой, я ввійшов до цього занадто швидко! Я хотів додати: $ wrapper-> field_something-> type () повертає ту саму інформацію, що й елемент 'type' масиву, повернутий $ wrapper-> field_something-> info (). Принципово важливо, що він все ще повертає рядок "list <type>" для багатозначних типів, тому мені все ж потрібні strpos (або еквівалент), щоб розробити його багатозначним (якщо я хочу його розробити, перш ніж отримати його).
Аліса Хітон

Що стосується другого моменту: я дійсно можу розібратися, якщо це багатозначне тестування повернення -> raw () або - - value (), однак я краще знаю, перш ніж отримувати значення, як якщо б воно було багатозначним, то Я хочу запустити його через цикл foreach з -> getIterator (), а не вручну пройти масив, який вимагає від мене знову створити обгортку для кожного елемента.
Аліса Хітон

3

Тож як ніхто не придумав іншого рішення, я відповім на власне запитання:

Не існує більш простого способу доступу до значень невідомих типів полів при використанні обгортки метаданих особи.

Існують альтернативні методи, які я описав спочатку (наприклад, ті, які вказав @thepearson). Зокрема, цей метод корисний:

 entity_property_list_extract_type($type)

Він поверне вказаний тип, якщо ваш тип є списком (наприклад, 'integer', якщо ваш тип 'list <integer>'), або false, якщо ваш тип не є списком. Внутрішньо він робить strpos так само, як і код, який я спочатку розмістив, але я думаю, що це більше докази в майбутньому.

Висновок такий:

  • Обгортки метаданих особи добре працюють, якщо ви не маєте уявлення про типи своїх полів і хочете ретельно вирішити кожен можливий випадок;

  • Обгортки метаданих Entity добре працюють, якщо ви точно знаєте, які типи поля ваші, і ви хочете їх використовувати;

  • Якщо у вас є лише деякі уявлення про те, як виглядають ваші поля (наприклад, весь текст, але ви не знаєте, чи вони відформатовані чи ні, і ви не знаєте, чи є однозначними або багатозначними), тоді обгортки метаданих Entity не надайте жодних скорочень, і вам потрібно написати свої власні, як я це робив у першому запитанні.


1

Для перевірки одиночного / декількох полів я вважаю корисним перевірити тип об’єкта обгортки, який буде EntityListWrapperдля поля багатозначного та EntityValueWrapperдля однозначного поля:

<?php
...
$wrapper = entity_metadata_wrapper('user', $account);
// Get address, or first address if a multi-value field instance.
if (get_class($wrapper->field_address) == 'EntityListWrapper') {
  $value = $wrapper->field_address[0]->value();
}
else {
  $value = $wrapper->field_address->value();
}

Або навітьif($wrapper->field_name instanceof EntityListWrapper) {...}
rudolfbyker
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.