Как мне найти доступные общедоступные методы?


Я нахожу, что самая большая проблема в работе с Drupal 8 заключается в том, что я не могу получить нужные мне данные. Drupal 8 хочет, чтобы я использовал общедоступные методы, а не вручную детализировал объект. Проблема в том, что я не могу найти последовательный способ получения списка доступных методов! (они волшебным образом существуют, и я чувствую, что я просто должен знать о них).=

Для этого примера предположим, что у меня есть тип контента с полем видео. Мне нужно получить исходный URL-адрес видеофайла в этом поле.

Поэтому я бы начал с идентификатора узла ($nid), и каким-то образом мне нужно выяснить, как загрузить узел. Это не так уж плохо, потому что есть много примеров. Поэтому я делаю что-то вроде $node = \Drupal\node\Entity\Node::load($nid);.

Пока все идет хорошо. Затем мне нужно получить значение моего поля видео (field_main_video). Мне потребовалась ЦЕЛАЯ вечность, чтобы понять это, потому что в сети есть противоречивая документация. Наконец я понял, что мне придется сделать что-то подобное (потому что это многозначное пункт):

$video = \Drupal\node\Entity\Node::load($nid)->field_main_video->getValue();

...затем выполните цикл через массив и т. Д. Использование кинта тоже не помогло мне найти это. Потому что, например, если я kint($node) и посмотрю в разделе методы, я не увижу там GetValue() в качестве элемента. Все еще не страшно, потому что вокруг было достаточно примеров, чтобы понять это.

Однако по мере того, как я углубляюсь, я не знал (это важная часть), что вместо того, чтобы получать идентификатор сущности поля видео, затем загружать сущность, затем находить поле "uri" в сущности и т.Д (как я сделал бы в D7): Был метод, который позволяет мне получить URI в одной и той же строке кода!

$url = \Drupal\node\Entity\Node::load($nid)->field_main_video->entity->getFileUri();

Но как я мог знать, что этот getFileUri() существует? Я случайно наткнулся на это в своем блоге. Это действительно облегчает получение URI, чем в D7... но только если вы знаете (волшебным образом), какие методы существуют для каждого "уровня" объекта.

В конце концов, в этом примере я спрашиваю: Как вы находите все общедоступные методы для каждого уровня возражать так, чтобы было легко читать и понимать? Обратите внимание, что, похоже, должен быть ориентированный на drupal (т.Е. модуль разработки) способ сделать это, а не искать вручную api.drupal.org или использовать что-то специфичное для IDE?

 10
Author: Bobby, 2017-03-14

5 answers

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

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

Для общего обзора я всегда ссылаюсь на великую сущность Шпаргалка по API.

Сущности содержимого имеют фиксированную структуру, Сущность > Поле (список полей) > Элемент поля -> Свойство. Свойство является либо скалярным, либо ссылкой на что-то другое, например, на другую сущность, объект языка, объект даты,...

Для нескольких определенных примеров, некоторые полезные фрагменты:

// List of fields that an entity has, the field definitions also have a lot of information like the type.
array_keys($entity->getFieldDefinitions())

// Use get() instead of the magic __get() on the entity level then you at least get some type hints.
$entity->get('field_name').

// Get the list of properties a certain field has, use array_keys() again for just the names, but the definitions also have the type and if it's computed or not.
$entity->getFieldDefinition('field_name')->getFieldStorageDefinition()->getPropertyDefinitions()

// Most field types have value property, but e.g. entity references have target_id and the computed entity. as you found. File and Image fields have additional properties like title/alt/description.
$entity->get('field_name')->value
$entity->get('field_name')->target_id
$entity->get('field_name')->entity

// Note that get('value') is not the same as ->value on the field item level, get() returns a typed data object, get('value')->getValue() is the same as ->value.

// When not specified, the delta 0 is assumed (all fields are a list internally, even something like the node id), you can use array access or the delta to access another delta, make sure it exists.
$entity->get('field_name')[1]->value
$entity->get('field_name')->get(1)->value

// When you have an entity reference, you can get the entity type and class like this:
$entity->get('field_name')->entity->getEntityTypeId()
$entity->get('field_name')->entity->getEntityType()->getClass()
// or 
get_class($entity->get('field_name')->entity)

// From there you can look up the interface and type hint against that, to a) make sure you have a valid, loadable reference and get type hints in an IDE:
$file = $entity->get('field_name')->entity;
if ($file instanceof \Drupal\file\FileInterface) {
  $file->getFileUri();
}
 14
Author: Berdir, 2017-03-21 13:05:19

Не уверен, что это полностью ответит на ваш вопрос, но что мне очень помогает, так это использование функции диаграмм в PhpStorm.

Например, показывающий иерархию enter image description here

У вас есть варианты отображения также имен методов

enter image description here

Я надеюсь, что это в какой-то степени поможет вам.

 4
Author: Oleg Videnov, 2017-03-14 14:47:51

Ну, я обнаружил, что довольно часто использую комбинацию var_dump(get_class_methods($object)), чтобы иметь список доступных методов для данного класса.

Я также довольно часто заглядываю в api.drupal.org для получения более подробной информации.

 4
Author: yvan, 2017-03-14 15:25:05

Вы уже очень близки.

Во-первых, давайте рассмотрим определение метода: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/function/File%3A%3AgetFileUri/8.2.x

Отсюда мы можем видеть класс, частью которого он является, и на него есть ссылка:

Class

File
Defines the file entity class.

Переход по ссылке приведет нас к: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/class/File/8.2.x

В вашей IDE вы также можете выполнить поиск класса \Drupal\file\Entity\File. Один из способов убедиться, что это правильный класс, - взглянуть на аннотацию:

@ContentEntityType(
  id = "file",
  label = @Translation("File"),
  handlers = {
    "storage" = "Drupal\file\FileStorage",
    "storage_schema" = "Drupal\file\FileStorageSchema",
    "access" = "Drupal\file\FileAccessControlHandler",
    "views_data" = "Drupal\file\FileViewsData",
  },
  base_table = "file_managed",
  entity_keys = {
    "id" = "fid",
    "label" = "filename",
    "langcode" = "langcode",
    "uuid" = "uuid"
  }
) 

Обратите внимание на id - это file. Предположительно, при отладке вы могли бы просмотреть содержимое field_main_video->entity и где-нибудь увидеть этот идентификатор. Затем вы просто ищете его в своей среде разработки. Обычно, однако, человек знает достаточно о типы сущностей, которые используются для определения пути к нужному классу (после чего можно проверить, что аннотация содержит правильный идентификатор).

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

Итак, короче говоря: ваша IDE, стратегическая debug() утверждения и некоторые догадки - лучшие способы открыть для себя Drupal 8.

P.S. Записи изменений также могут быть полезны. Они находятся в https://www.drupal.org/list-changes/drupal

 0
Author: wizonesolutions, 2017-03-14 14:51:01

Вы можете использовать функцию PHP get_class_methods. В приведенном ниже примере пользователи загружают файл:

$image = $form_state->getValue('image_field_name_from_form');
$file = File::load( $image[0] );
$file->setPermanent();
$file->save();

$methods = [];
foreach (get_class_methods($file) as $method) {
        $methods[] = $method;
}
print_r($methods);

Это добавит все методы, доступные для файла object$, в ваш массив $methods, который вы можете распечатать, а затем просмотреть все доступные методы. Это справедливо для любых объектов в PHP, а не только для Drupal.

 0
Author: Cristian Cordeiro, 2018-04-13 20:01:50