Як знайти доступні загальнодоступні методи?


9

Я вважаю, що найбільшою проблемою в роботі з 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 теж не допомогло мені знайти це. Тому що, наприклад, якщо я kint($node)переглядаю методи, я не бачу getValue () як елемент там. Все ще не страшно, адже навколо було достатньо прикладів, щоб це зрозуміти.

У міру того, як я заглиблююсь, те, що я не знав (це важлива частина), це те, що замість того, щоб отримати ідентифікатор сутності відеополя, потім завантажити сутність, потім знайти поле "урі" в об'єкті тощо (наприклад, Я б у D7): Існував метод, який дозволяє мені отримати URI все в цьому ж рядку коду!

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

Але як я міг би знати, що існування цього файлаFileUri ()? Я випадково натрапив на це в дописі в блозі. Це дійсно робить УРІ простішим, ніж у D7 ... але тільки якщо ви (магічно) знаєте, які методи існують для кожного "рівня" об'єкта.

Зрештою, в цьому прикладі я запитую: Як ви знаходите всі публічні методи для кожного рівня об’єкта таким чином, щоб його легко читати та розуміти? Зауважте, що, здається, має бути спосіб, орієнтований на друпа (наприклад, модуль devel), щоб це зробити, а не шукати api.drupal.org вручну або використовувати щось специфічне для IDE?


1
Офіційна документація знаходиться на сайті api.drupal.org. Після того, як ви зрозумієте клас об'єкта, з яким обробляєтесь, ви отримуєте всі методи, включаючи успадковані.
kiamlaluno

1
... але замість того, щоб шукати все на api.drupal.org, напевно, існує спосіб у php / devel скинути доступні методи на екран за командою?
Боббі

Відповіді:


14

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

Що стосується об'єктів і полів вмісту, публічні методи - це насправді не те, що ви насправді хочете знати, що ви хочете знати про поля та властивості. І лише коли ви знову потрапите до сутності через посилання, тоді методи мають значення.

Для огляду я завжди посилаюсь на чудовий чіт-лист API Entity .

Суб'єкти вмісту мають фіксовану структуру, Entity> Field (FieldItemList)> FieldItem -> Properties. Властивість є або скалярною, або посиланням на щось інше, наприклад, іншу сутність, мовний об'єкт, об'єкт дати, ...

Кілька конкретних прикладів, кілька корисних фрагментів:

// 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();
}

Приємно! Це знадобиться трохи перетравити, але я схиляюся до цього, як це прийнята відповідь. Дякую! Це не точно відповідає на питання, але це тільки тому, що моє запитання та мій приклад були начебто запитання 2 різних речей. Дякую!
Боббі

1
@Berdir, це дивовижний список прикладів, що насправді вдарило за ніготь. Я був просто google для деякої інформації, будь-якої інформації і нічого навіть близького до цього. Чудова відповідь, матеріал книги.
Марко Блажекович

4

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

Наприклад, показ ієрархії введіть тут опис зображення

У вас є варіанти показувати також імена методів

введіть тут опис зображення

Я сподіваюся, що це допоможе вам певним чином.


Ви також можете відкрити клас із командою + клацання, потім команда + 7 або клацніть на вкладці Структура, щоб побачити структуру класів (де буде перегляд каталогу вашого проекту), щоб швидко просканувати ту саму інформацію, не відкриваючи UML.
Кевін

Я не використовую phpstorm, але це добре знати для подальшої довідки. Я шукаю спосіб це зробити, використовуючи devel або щось, орієнтоване на компанію. напевно щось десь має бути вбудовано?
Боббі

Пробачте, що сказати це, але я дійсно не думаю, що в цей момент ви не можете ефективно попрацювати з API, не використовуючи цю IDE.
Олег Відєнов

NetBeans також включає деякі діаграми ієрархії PHP. Напевно, не так круто, але NetBeans - це вільне програмне забезпечення (PHP Storm є закритим джерелом, а IMHO дорогим), і ви можете завантажити його безкоштовно.
sanzante

Будь-яка ІДЕ, яка коштує своєї солі, може це зробити. BTW PHPStorm недешевий, якщо ви використовуєте те, що він може запропонувати. Ви можете використовувати безкоштовну версію EAP, і якщо ви працюєте над проектом з відкритим кодом (модулі або теми Drupal), JetBrains надасть вам безкоштовну ліцензію. Тут не обговорення.
Кевін

4

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

Я також досить часто шукаю api.drupal.orgдеталі для отримання детальної інформації.


2
Це здається, що відповідь, найбільш тісно пов'язаний з тим, що я шукав поки що. Дякую!
Боббі

0

Ви вже дуже близько.

Спочатку розглянемо визначення методу: 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і ви б десь побачили цей ідентифікатор. Тоді ви просто шукаєте його у своїй IDE. Однак, як правило, достатньо відомо про типи сутностей, які використовує, щоб відгадати свій шлях до потрібного класу (після чого можна було б перевірити, чи анотація містить правильний ідентифікатор).

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

Отже, коротше: ваші IDE, стратегічні debug()заяви та деякі здогадки - найкращі способи виявити Drupal 8.

Записи змін PS також можуть бути корисними. Вони є за адресою https://www.drupal.org/list-changes/drupal


Я вважаю, що проблема ОП - це зворотне: знати, які публічні методи клас / реалізує / має.
kiamlaluno

Так, мені, можливо, доведеться прочитати це ще раз, але я не думаю, що це те, що я шукаю. Я намагаюся розібратися, як getFileUri () взагалі існує в першу чергу!
Боббі

@Bobby Файл - це форма сутності, тому ви просто подивіться на його джерело , де ви знайдете метод, який ви перераховуєте, та повністю задокументований. Це просто те, що ви не знали, що файл - це тип сутності? Або ви не знаєте домовленості розміщення типу сутності в коді? Або щось ще далі по ланцюгу? У D8 є багато шарів абстрагування, це симфонічний шлях, тому є багато "базових" знань, які вам потрібно спочатку, перш ніж заглиблюватися в код
Клайв

0

Ви можете використовувати функцію 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);

Це додасть усі методи, доступні до об’єктного файлу $, у ваш масив методів $, який ви можете надрукувати та переглянути всі доступні методи. Це справедливо для будь-яких об'єктів PHP, не тільки для Drupal.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.