Herkese açık yöntemleri nasıl bulabilirim?


9

Drupal 8 ile çalışmanın en büyük probleminin ihtiyacım olan verileri elde edemiyorum. Drupal 8, bir nesneyi manuel olarak delmek yerine genel yöntemleri kullanmamı istiyor. Sorun şu ki, mevcut yöntemlerin bir listesini almak için tutarlı bir yol bulamıyorum! (sihirli bir şekilde var olurlar ve sadece onlar hakkında bilgi sahibi olmam gerektiğini hissediyorum). =

Bu örnekte, video alanına sahip bir içerik türüm olduğunu varsayalım. Bu alanda video dosyasının ham URL'sini almam gerekiyor.

Bu yüzden bir düğüm kimliği ($ nid) ile başlayacağım ve bir şekilde düğümü nasıl yükleyeceğimi bulmalıyım. Bu çok kötü değil çünkü birçok örnek var. Ben de böyle bir şey yapıyorum $node = \Drupal\node\Entity\Node::load($nid);.

Çok uzak çok iyi. Sonra benim video alanı (field_main_video) değerini almak gerekir. Bu beni net olarak anladım çünkü 'net'in etrafında çelişen belgeler var. Sonunda ben böyle bir şey yapmak zorunda anladım (çünkü çok değerli bir öğe):

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

... sonra dizi vb döngü. Çünkü, örneğin, ben kint($node)ve yöntemlerin altına bakarsanız, getValue () öğesini orada bir öğe olarak görmüyorum. Hala korkunç değil, çünkü anlamaya yetecek kadar örnek vardı.

Daha derine inerken, bilmediğim şey (bu önemli kısımdır) video alanı varlık kimliğini almak, sonra varlığı yüklemek, ardından varlıktaki "uri" alanını bulmaktan (vb.) Ben D7) olurdu: URI tüm bu aynı kod satırı almak sağlayan bir yöntem vardı!

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

Ama bu getFileUri () 'nin var olduğunu nasıl bilebilirdim? Bir blog gönderisinde rastladım. Bu gerçekten bir URI'yi D7'den daha kolay hale getirir ... ancak sadece bir nesnenin her 'seviyesi' için hangi yöntemleri (sihirli bir şekilde) biliyorsanız.

Sonunda, bu örnekle soruyorum: Bir nesnenin her seviyesi için tüm genel yöntemleri, okunması ve anlaşılması kolay bir şekilde nasıl buluyorsunuz? Api.drupal.org'u manuel olarak aramak veya IDE'ye özgü bir şey kullanmak yerine bunu yapmanın bir drupal merkezli (yani devel modülü) bir yolu olması gerektiğini unutmayın.


1
Resmi belgeler api.drupal.org adresindedir. Kullandığınız nesnenin sınıfını anladıktan sonra, miras alınanlar da dahil olmak üzere tüm yöntemleri elde edersiniz.
kiamlaluno

1
... ama api.drupal.org'daki her şeye bakmak yerine, php / devel'de mevcut yöntemleri komut ekranına dökmenin bir yolu var mı?
Bobby

Yanıtlar:


14

İçerik varlıkları, çoğu zaman yapılandırılabilir alanlar için değil, genellikle yöntemlere ve uygun arayüzlere sahip olmamaları nedeniyle diğer birçok şeyden farklıdır .

İçerik varlıkları ve alanları söz konusu olduğunda, genel yöntemler gerçekten bilmek istediğiniz şey değildir, alanlar ve özellikler hakkında bilmek istediğiniz şeydir. Ve sadece bir varlığa bir referans yoluyla tekrar ulaştığınızda yöntemler önemlidir.

Genel bir bakış için her zaman harika Entity API Cheat Sheet'e başvuruyorum .

İçerik varlıklarının sabit bir yapısı vardır: Varlık> Alan (FieldItemList)> FieldItem -> Özellik. Bir özellik, skaler veya başka bir şeye referanstır, örneğin başka bir varlık, bir dil nesnesi, bir tarih nesnesi, ...

Belirtilen birkaç örnek için bazı yararlı snippet'ler:

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

Güzel! Bu sindirmek biraz zaman alacak, ama ben kabul edilen cevap bu eğilimi. Teşekkürler! Soruyu tam olarak cevaplamıyor, ancak bu sadece sorum ve örneğim 2 farklı şey soruyordu. Teşekkür ederim!
Bobby

1
@Berdir, bu çiviyi gerçekten vuran muhteşem örneklerin listesi. Ben sadece bazı bilgi, herhangi bir bilgi ve hatta buna yakın bir şey için google oldu. Harika cevap, kitap malzemesi.
Marko Blazekovic

4

Sorunuza tamamen cevap verip vermeyeceğinden emin değilim ama bana çok yardımcı olan şey PhpStorm'daki diyagramlar özelliğini kullanıyor.

Örneğin, hiyerarşiyi gösteren resim açıklamasını buraya girin

Ayrıca yöntem adlarını gösterme seçenekleriniz vardır

resim açıklamasını buraya girin

Umarım bu size bir şekilde yardımcı olur.


Aynı bilgiyi UML'yi açmadan hızlıca taramak için sınıf yapısını (proje dizini görünümünüzün nerede olacağı) görmek için command + click, sonra command + 7 ile bir sınıf açabilir veya Yapı sekmesine tıklayabilirsiniz.
Kevin

Ben phpstorm kullanmıyorum, ama gelecekteki referans için bilmek iyidir. Bunu devel veya drupal merkezli bir şey kullanarak yapmanın bir yolunu arıyorum. şüphesiz bir yere bir şeyler inşa edilmelidir?
Bobby

Bunu söylediğim için üzgünüm, ancak şu anda bu IDE'yi kullanmadan API ile verimli bir şekilde çalışabileceğinizi düşünmüyorum.
Oleg Videnov

NetBeans ayrıca bazı PHP hiyerarşi diyagramları içerir. Muhtemelen çok havalı değil, ama NetBeans Özgür Yazılım (PHP Storm kapalı kaynak ve IMHO pahalı) ve ücretsiz olarak indirebilirsiniz.
sanzante

Tuzlarına değecek herhangi bir IDE bunu yapabilir. BTW PHPStorm, sunduklarını kullanırsanız pahalı değildir. Ücretsiz EAP sürümünü kullanabilirsiniz ve açık kaynaklı bir proje (Drupal modülleri veya temalar) üzerinde çalışıyorsanız, JetBrains size ücretsiz bir lisans verecektir. Yine de burada bir tartışma değil.
Kevin

4

Kendimi var_dump(get_class_methods($object)), verilen sınıf için mevcut yöntemlerin bir listesini elde etmek için sıklıkla kullandığımı buldum .

Daha api.drupal.orgfazla ayrıntı için de sık sık araştırıyorum .


2
Bu şimdiye kadar aradığım şeyle en yakından ilişkili cevap gibi görünüyor. Teşekkürler!
Bobby

0

Zaten çok yakınsın.

İlk olarak, yöntemin tanımına bakalım: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/function/File%3A%3AgetFileUri/8.2.x

Buradan, bunun bir parçası olduğu sınıfı görebiliriz ve bunun bir bağlantısı vardır:

Class

File
Defines the file entity class.

Tıklamak bizi şu adrese götürür: https://api.drupal.org/api/drupal/core%21modules%21file%21src%21Entity%21File.php/class/File/8.2.x

IDE'nizde \Drupal\file\Entity\Filesınıfı da arayabilirsiniz . Bunun doğru sınıf olduğundan emin olmanın bir yolu ek açıklamaya bakmaktır:

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

Dikkat edin id- öyle file. Muhtemelen, hata ayıklama durumunda, içeriğine bakabilir field_main_video->entityve bu kimliği bir yerde görürsünüz. Sonra sadece IDE'nizde arayın. Bununla birlikte, genellikle kişi, doğru sınıfa giden yolu tahmin etmek için kullanılan varlık türleri hakkında yeterli bilgiye sahiptir (bundan sonra ek açıklamanın doğru kimliği içerdiğini doğrulayabilir).

Bu özel durumda, yapılandırma (yapılandırma varlığı) yerine veritabanı içeriğine (içerik varlığı) benzediğinden File, muhtemelen genişleyen bir sınıf olduğunu da biliyorum ContentEntityBase. Varsayımlarımın doğrulandığını gördüğümde, bu doğru sınıfı bulduğumu bilmeme yardımcı oluyor.

Kısacası: IDE'niz, stratejik debug()ifadeleriniz ve bazı tahminleriniz Drupal 8'i keşfetmenin en iyi yoludur.

PS Değişiklik kayıtları da yardımcı olabilir. Onlar https://www.drupal.org/list-changes/drupal adresinde


OP'nin problemini tersine alıyorum: bir sınıfın hangi genel yöntemleri uyguladığını / kullanabildiğini bilmek.
kiamlaluno

Evet, bunu tekrar okumak zorunda kalabilirim, ama aradığımın bu olduğunu sanmıyorum. Nasıl getFileUri () bile ilk etapta var anlamaya çalışıyorum!
Bobby

@Bobby Bir dosya varlık tipidir, bu yüzden kaynağına bakarsınız, sonra listelendikten ve tam olarak belgelendirdiğiniz yöntemi bulabilirsin. Bir dosyanın varlık türü olduğunu bilmiyor muydunuz? Veya kodda varlık türünü bulma kuralını bilmiyor musunuz? Yoksa zincirden başka bir şey mi? D8'deki her şey için birçok soyutlama katmanı var, bu symfony yolu, bu yüzden koda girmeden önce ihtiyacınız olan bir çok "temel" bilgi var
Clive

0

PHP get_class_methods işlevini kullanabilirsiniz. Aşağıdaki örnekte kullanıcılar dosya yükleme:

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

Bu işlem $ file nesnesinin kullanabileceği tüm yöntemleri $ yöntemler dizinize ekleyecektir; bu, yazdırabileceğiniz ve daha sonra kullanılabilir tüm yöntemleri görebileceğiniz bir yöntemdir. Bu, sadece Drupal için değil, PHP'deki tüm nesneler için geçerlidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.