Bagaimana cara menemukan metode publik yang tersedia?


9

Saya menemukan bahwa masalah terbesar dalam bekerja dengan Drupal 8 adalah saya tidak bisa mendapatkan data yang saya butuhkan. Drupal 8 ingin saya menggunakan metode publik daripada secara manual menelusuri objek. Masalahnya adalah, saya tidak dapat menemukan cara yang konsisten untuk mendapatkan daftar metode yang tersedia! (mereka secara ajaib ada, dan saya merasa seperti saya seharusnya tahu tentang mereka). =

Untuk contoh ini, katakanlah saya memiliki tipe konten dengan bidang video. Saya perlu mendapatkan URL mentah dari file video di bidang itu.

Jadi saya akan mulai dengan id node ($ nid), dan entah bagaimana saya harus mencari cara untuk memuat node. Ini tidak terlalu buruk karena ada banyak contoh. Jadi saya melakukan sesuatu seperti $node = \Drupal\node\Entity\Node::load($nid);.

Sejauh ini baik. Maka saya perlu mendapatkan nilai dari bidang video saya (field_main_video). Ini mengambil saya SELAMANYA untuk mencari tahu karena ada dokumentasi yang saling bertentangan di sekitar 'net. Akhirnya saya tahu saya harus melakukan sesuatu seperti ini (karena ini adalah item bernilai ganda):

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

... lalu loop melalui array dll. Menggunakan kint tidak membantu saya menemukan ini juga. Karena, misalnya, jika saya kint($node)dan mencari di bawah metode, saya tidak melihat getValue () sebagai item di sana. Masih tidak mengerikan, karena ada cukup banyak contoh untuk mencari tahu.

Ketika saya masuk lebih dalam, apa yang saya tidak tahu (ini adalah bagian yang penting) adalah bahwa alih-alih mendapatkan id entitas bidang video, lalu memuat entitas, lalu menemukan bidang "uri" di entitas, dll (seperti Saya akan di D7): Ada metode yang memungkinkan saya mendapatkan URI semua dalam baris kode yang sama!

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

Tapi bagaimana mungkin saya tahu getFileUri () ini ada? Saya kebetulan menemukannya di sebuah posting blog. Ini benar-benar TIDAK membuat mendapatkan URI lebih mudah daripada di D7 ... tetapi hanya jika Anda tahu (secara ajaib) metode apa yang ada untuk setiap 'level' dari suatu objek.

Pada akhirnya, dengan contoh ini saya bertanya: Bagaimana Anda menemukan semua metode publik untuk setiap tingkat objek dengan cara yang mudah dibaca dan dipahami? Perhatikan bahwa tampaknya harus ada cara drupal-centric (mis. Devel module) untuk melakukan ini daripada mencari secara manual api.drupal.org atau menggunakan sesuatu yang spesifik IDE?


1
Dokumentasi resmi ada di api.drupal.org. Setelah Anda memahami kelas objek yang Anda tangani, Anda mendapatkan semua metode, termasuk yang diwarisi.
kiamlaluno

1
... tapi alih-alih mencari semuanya di api.drupal.org, pasti ada cara di php / devel untuk membuang metode yang tersedia ke layar sesuai perintah?
Bobby

Jawaban:


14

Entitas konten berbeda dari kebanyakan hal lain karena mereka sering tidak memiliki metode dan antarmuka yang tepat, setidaknya tidak untuk bidang yang dapat dikonfigurasi.

Dalam hal entitas dan bidang konten, metode publik tidak benar-benar ingin Anda ketahui, apa yang Anda ingin ketahui tentang bidang dan properti. Dan hanya ketika Anda mendapatkan entitas lagi melalui referensi maka metode itu penting.

Untuk gambaran umum, saya selalu merujuk ke Lembar Cheat API Entitas yang hebat .

Entitas konten memiliki struktur tetap, Entitas> Bidang (FieldItemList)> FieldItem -> Properti. Properti adalah skalar atau referensi ke sesuatu yang lain, misalnya entitas lain, objek bahasa, objek tanggal, ...

Untuk beberapa contoh tertentu, beberapa cuplikan berguna:

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

Bagus! Ini akan membutuhkan sedikit waktu untuk dicerna, tetapi saya condong ke arah ini sebagai jawaban yang diterima. Terima kasih! Itu tidak persis menjawab pertanyaan tapi itu hanya karena pertanyaan saya dan contoh saya semacam menanyakan 2 hal yang berbeda. Terima kasih!
Bobby

1
@Berdir, ini daftar contoh yang luar biasa, benar-benar mengenai paku. Saya hanya google untuk beberapa info, info dan bahkan tidak ada yang dekat dengan ini. Jawaban bagus, bahan buku.
Marko Blazekovic

4

Tidak yakin apakah itu akan sepenuhnya menjawab pertanyaan Anda, tetapi yang banyak membantu saya adalah menggunakan fitur diagram di PhpStorm.

Misalnya menunjukkan hierarki masukkan deskripsi gambar di sini

Anda memiliki opsi untuk menampilkan juga nama metode

masukkan deskripsi gambar di sini

Saya harap ini membantu Anda.


Anda juga dapat membuka kelas dengan perintah + klik, lalu perintah + 7 atau klik tab Struktur untuk melihat struktur kelas (tempat tampilan direktori proyek Anda) untuk memindai dengan cepat informasi yang sama tanpa membuka UML.
Kevin

Saya tidak menggunakan phpstorm, tetapi ini bagus untuk diketahui sebagai referensi di masa depan. Saya mencari cara untuk melakukan ini menggunakan devel atau sesuatu yang drupal-sentris. pasti ada sesuatu yang harus dibangun di suatu tempat?
Bobby

Saya minta maaf untuk mengatakan itu, tapi saya benar-benar tidak berpikir saat ini Anda dapat mengotak-atik API secara efisien tanpa menggunakan IDE ini.
Oleg Videnov

NetBeans juga menyertakan beberapa diagram hierarki PHP. Mungkin tidak begitu keren, tetapi NetBeans adalah Perangkat Lunak Bebas (PHP Storm adalah sumber tertutup dan IMHO mahal) dan Anda dapat mengunduhnya secara gratis.
sanzante

Setiap IDE yang bernilai garam dapat melakukan ini. BTW PHPStorm tidak mahal jika Anda memanfaatkan apa yang ditawarkan. Anda dapat menggunakan versi EAP gratis, dan jika Anda bekerja pada proyek sumber terbuka (modul Drupal atau tema), JetBrains akan memberi Anda lisensi gratis. Bukan diskusi untuk di sini.
Kevin

4

Yah, saya menemukan diri saya cukup sering menggunakan kombinasi var_dump(get_class_methods($object))untuk memiliki daftar metode yang tersedia untuk kelas yang diberikan.

Saya juga sering melihat api.drupal.orgdetail lebih lanjut.


2
Ini sepertinya jawaban yang paling dekat hubungannya dengan apa yang saya cari sejauh ini. Terima kasih!
Bobby

0

Anda sudah sangat dekat.

Pertama, mari kita lihat definisi metode ini: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/function/File%3A%3AgetFileUri/8.2.x

Dari sini, kita bisa melihat kelas ini bagiannya, dan ada tautannya:

Class

File
Defines the file entity class.

Mengklik melalui membawa kita ke: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/class/File/8.2.x

Di IDE Anda, Anda juga bisa mencari \Drupal\file\Entity\Filekelas. Salah satu cara untuk memastikan ini adalah kelas yang benar adalah dengan melihat penjelasannya:

@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"
  }
) 

Perhatikan id- itu file. Agaknya, jika debugging, Anda bisa melihat konten field_main_video->entitydan Anda akan melihat ID ini di suatu tempat. Maka Anda cukup mencarinya di IDE Anda. Namun, biasanya, orang cukup tahu tentang tipe entitas yang digunakan untuk menebak jalan ke kelas yang benar (setelah itu orang dapat memverifikasi bahwa anotasi berisi ID yang benar).

Dalam kasus ini, saya juga tahu bahwa Fileadalah mungkin kelas yang meluas ContentEntityBase, karena itu lebih seperti isi database (badan konten) dari konfigurasi (entitas konfigurasi). Jadi ketika saya melihat asumsi saya menegaskan, itu membantu saya tahu saya telah menemukan kelas yang tepat.

Jadi, singkatnya: IDE Anda, debug()pernyataan strategis , dan beberapa tebakan adalah cara terbaik untuk menemukan Drupal 8.

Catatan perubahan PS juga bisa membantu. Mereka ada di https://www.drupal.org/list-changes/drupal


Saya mengambil masalah OP adalah kebalikannya: mengetahui metode publik mana yang diterapkan / telah tersedia kelas.
kiamlaluno

Ya, saya mungkin harus membaca ini lagi, tetapi saya tidak berpikir itu yang saya cari. Saya mencoba mencari tahu bagaimana getFileUri () bahkan ada di tempat pertama!
Bobby

@ Bobby File adalah tipe entitas, jadi Anda cukup melihat sumbernya , tempat Anda akan menemukan metode yang Anda cari setelah terdaftar dan didokumentasikan sepenuhnya. Apakah hanya karena Anda tidak tahu file adalah tipe entitas? Atau Anda tidak tahu konvensi untuk menemukan jenis entitas dalam kode? Atau sesuatu yang lebih jauh dalam rantai? Ada banyak lapisan abstraksi untuk semua yang ada di D8, ini cara simfoni, jadi ada banyak "dasar" pengetahuan yang Anda butuhkan terlebih dahulu sebelum mempelajari kode
Clive

0

Anda dapat menggunakan fungsi get_class_methods PHP. Contoh di bawah pengguna mengunggah file:

$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);

Ini akan menambahkan semua metode yang tersedia ke objek $ file ke dalam array $ methods Anda, yang dapat Anda cetak dan kemudian lihat semua metode yang tersedia. Ini berlaku untuk objek apa pun di PHP, bukan hanya Drupal.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.