Как получить список типов полей?


10

Я портирую модуль из Drupal 7 в Drupal 8. В настройках конфигурации этого модуля мне нужно получить список существующих в настоящее время типов полей.

В Drupal 7 это было достигнуто с помощью field_info_field_types()функции.

В Drupal 8 (8.0.0-rc3) я получаю сообщение об ошибке «функция не существует», несмотря на то, что информация, указанная на справочной странице Drupal API , явно устарела.

Затем, исследуя, я нашел страницу DrupalContrib , где функция объявлена ​​устаревшей, и предложил ее использовать Drupal::service('plugin.manager.entity.field.field_type')->getDefinitions().

Но его использование вызывает еще одну ошибку «Неизвестный сервис plugin.manager.entity.field.field_type», к счастью связанный с предложением «Вы имеете в виду plugin.manager.field.field_type?»

Поэтому я попытался использовать Drupal::service('plugin.manager.field.field_type')->getDefinitions()и ничего себе: я получил ожидаемый массив типов полей.

Но каждый член массива (один тип поля) теперь является объектом (а не дочерним массивом), и искомые данные вложены в защищенные свойства, поэтому я не могу получить к ним доступ.

На этом этапе я застрял. Я подумал, что может существовать некоторый класс, который я мог бы расширить, чтобы перемещаться по этим данным, но без удачи: я даже не мог понять, какой компонент в Drupal 8, где определения типов полей централизованы.


Лучше вы посмотрите на api.drupal.org, который является более обновленным. На самом деле, нет страницы для этой функции .
kiamlaluno

Спасибо за подсказку "посмотрите на api.drupal.org". С другой стороны (и это довольно мета релевантно, извините), если я легко понимаю, что вы отредактировали мои сокращения (D7 -> Drupal 7), мне интересно, почему вы уронили «Drupal 8» в названии? Я склонен думать, что было бы какое-то правило, гласящее, что оно повторяется с тегом «8». Но как читатель я использую, чтобы найти меня гораздо более уверенно информированным по названию, чем по тегу: на мой взгляд, теги по сути относятся к процессу поиска, при последовательном чтении я редко обращаю на них внимание.
cFreed

Нет необходимости повторять теги в заголовке, так как они всегда видны везде, где есть вопрос. Пользователи Stack Exchange обращают внимание на теги.
kiamlaluno

Ответы:


16

Первый уровень - это массив. Ключи - это идентификаторы плагина. Вы можете перечислить их:

$defs = Drupal::service('plugin.manager.field.field_type')->getDefinitions();
foreach ( $defs as $key => $value ) {
   echo $key, "\n";
}

Это результат:

comment
datetime
file
image
link
list_string
list_float
list_integer
path
text_with_summary
text
text_long
email
boolean
created
changed
timestamp
string_long
language
decimal
uri
float
password
string
integer
entity_reference
uuid
map
taxonomy_term_reference

Вы можете выбрать один и сбросить определение плагина.

var_dump($defs['comment']);

Если вас интересует особый объект, вы можете копать глубже с помощью api.drupal.org. Но это будет проще, если вы будете искать плагин в основной директории.

Чтобы получить доступ к объекту, найдите его в var_dump и используйте метод:

$defs['comment']['description']->render();

В данном случае это объект TranslatableMarkup , который имеет метод render для доступа к переведенной строке.


Спасибо, но это то, что я уже сделал. Кроме того, моя проблема остается: как я могу программно получить доступ к данным внутри этих объектов?
cFreed

Что вы хотите найти в определениях полей? Обычно вы просматриваете свойства и методы объекта в API, а затем получаете к ним доступ с помощью `-> '. Определения полей легче найти в источнике.
4k4

Извлечь label, descriptionи moduleи отображать их в виде конфигурации , где пользователь может проверить те , для которых он хочет мой модуль ( MMS ) создает клонированных маркеры для соответствующих полей.
cFreed

Я добавляю пример.
4k4

К сожалению! Я видел ваш последний комментарий, но не заметил вашего редактирования, поэтому продолжал ждать. Я попробую ваше предложение. Спасибо.
cFreed

4

Каждая строка, которая передается через t (), теперь является объектом. Вы можете получить к ним доступ в виде строк, на самом деле, вы должны это сделать.

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

PS: Официальная документация по API - http://api.drupal.org/api/drupal/8 . Используйте это для ядра.

Еще один полезный ресурс - записи изменений: https://www.drupal.org/list-changes/published?keywords_description=field_info_field_types&to_branch=&version=&created_op=%3E%3D&created%5Bvalue%5D=&created%5Bmin%5D=&maxreated% 5D =

Изменить: Отвечая на ваш комментарий, я не совсем понимаю, что вы имеете в виду. Вся необходимая информация находится здесь, просто используйте ее.

$definitions = Drupal::service('plugin.manager.field.field_type')->getDefinitions();
foreach ( $definitions as $field_type => $definition) {
  print $definition['label'];
  print $definition['description'];
  print $definition['provider'];
}

Опять же, просто игнорируйте, что метка / описание являются объектами. У них есть методы __toString (), которые автоматически вызываются при их печати / использовании.


Спасибо за этот ответ. Ваша последняя предложенная ссылка выглядит очень многообещающе, и я проведу расследование на основе этой информации. Коротко сказал, я не прав , если я думаю , что для моих нужд (выписок label, description, moduleстроки каждого поля типа) следует: 1) получить список из , Drupal::service('plugin.manager.field.field_type')->getDefinitions()как уже сделано; 2) затем используйте каждый ключ возвращаемого массива (имя типа поля) для вызова определенного класса (найдите, какой и где, что я должен исследовать глубже), который предоставит методы для получения необходимой информации? TIA для этой точности.
cFreed

Обновил мой ответ.
Бердир

Упс ... не понимаю! То, что вы предложили в своем редактировании, это просто то, что я сделал в D7. И это не работает в D8, так как $definitionэто не массив строк в D8, а массив объектов! Я использовал ДПЙ () , чтобы изучить их, и увидел , что каждый из необходимых строк появляется вложенным таким образом: 'label' => array(..., 'label' => Drupal\Core\StringTranslation\TranslatableMarkup Object {..., string, ...}, ...). Я что-то упускаю из виду?
cFreed

Только что обнаружил (в последнее время) последнее редактирование 4k4, которое работает. На самом деле проблема для меня состояла в том, чтобы узнать, где найти TranslatableMarkupкласс, и о доступности render()метода. Наконец, правильный способ получить мои данные print $definition['label']->render();. Тем не менее, спасибо за вашу другую информацию.
cFreed

Нет, опять же, вам не нужно -> render (). используйте $ definition ['label'], он просто работает, поверьте мне :)
Berdir

1

Обновленная версия для ответа @Berdir. Используйте в оболочке.

$definitions = Drupal::service('plugin.manager.field.field_type')->getDefinitions();
foreach ( $definitions as $field_type => $definition) {
  print 'Label: '. $definition['label']. PHP_EOL;
  print 'Machine name: '. $field_type. PHP_EOL;
  print 'Descritpion: '. $definition['description']. PHP_EOL;
  print 'Provider: '. $definition['provider']. PHP_EOL . ' ---' . PHP_EOL;
}

Вывод здесь: https://gist.github.com/sobi3ch/70635cc62defff606242


1

Google, кажется, находит этот вопрос при поиске этих

Если вы используете консоль Drupal, вы также можете использовать:

drupal plugin:debug field.field_type

На Drupal.org также есть это, которое также может помочь:

Определение и использование определений Content Entity Field

Это не легко найти примеры полезных, хотя

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.