Başvurulan varlık örneği nasıl elde edilir?


35

Resim alanı olan bir düğüm nesnesine sahibim field_image. Ben yaparken

$node
  ->get('field_image')
  ->first()
  ->getValue()

Varlık nesnesi yerine bazı özelliklere sahip bir dizi alıyorum. Dizi şöyle görünür:

'target_id' => string '8' (length=1)
'alt' => string '' (length=0)
'title' => string '' (length=0)
'width' => string '587' (length=3)
'height' => string '458' (length=3)
'_loaded' => boolean true
  '_accessCacheability' => 
    object(Drupal\Core\Cache\CacheableMetadata)[1092]
      protected 'cacheContexts' => 
        array (size=0)
          ...
      protected 'cacheTags' => 
        array (size=0)
          ...
      protected 'cacheMaxAge' => int -1

Kullanarak dosya varlığını yüklemek zorunda mıyım target_idyoksa otomatik olarak başvurulan varlık nesnesini örnek almanın bir yolu var Drupal\image\Plugin\Field\FieldType\ImageItemmı?

Başvurulan varlığa neden alıcı aracılığıyla erişilemiyor? Hemen mevcut değilse tembel yüklü olabilir.


$ node-> get ('imagefield') -> first () -> getTarget () sadece bir öğe varsa veya $ node-> get ('imagefield') -> referenceEntities () ... aslında sonuncusu tüm istediğin.

Tam olarak @IvanJaros: PHP Fatal error: Call to undefined method Drupal\image\Plugin\Field\FieldType\ImageItem::getTarget(). Ancak bu yöntem uygulayan örneği döndürür $node->get('imagefield')->referencedEntities()gerçeği sayesinde çalışır . Bu nedenle çözümünüz yalnızca kısmi - listelerde çalışır, ancak tek alanlar için değil. $node->get('imagefield')EntityReferenceFieldItemListreferencedEntities()
SiliconMind

Evet, getTarget alan öğesi değil varlık referans veri türü üzerinde.

Yanıtlar:


63

Başvurulan varlığa giden yol çok uzun:

// $id = some node ID
// $field = field name for entity reference field
$node = Node::load($id);

/** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $referenceItem */
$referenceItem = $node->get($field)->first();

/** @var \Drupal\Core\Entity\Plugin\DataType\EntityReference $entityReference */
$entityReference = $referenceItem->get('entity');

/** @var \Drupal\Core\Entity\Plugin\DataType\EntityAdapter $entityAdapter */
$entityAdapter = $entityReference->getTarget();

/** @var \Drupal\Core\Entity\EntityInterface $referencedEntity */
$referencedEntity = $entityAdapter->getValue();

// At this point $referencedEntity is the referenced entity object.

Tabii ki, kişi onu bir liner çağrısı yoluyla hala alabilir, ancak yine de hantaldır ve neden EntityReferenceItemreferans varlık nesnesini döndürecek bir yöntem sağlamadığını merak ediyorum .

$referencedEntity = $node
  ->get($field)
  ->first()
  ->get('entity')
  ->getTarget()
  ->getValue()
;

Ayrıca başvurulan tüm varlıkların dizisini almanın oldukça kolay olduğunu belirtmek gerekir:

$node->get($field)->referencedEntities();

Varlık başvuru alanları için yöntemi uygulayan $node->get($field)örneğini döndürdüğü için çalışır .EntityReferenceFieldItemListreferencedEntities()


33

Kullanabilirsiniz:

$node->field_image->entity

ilk değeri istiyorsan


9
Bu yüzden sihir yöntemleri kötüdür. Bunu kodlamada belgelemenin bir yolu yoktur ve uygulanan arayüzlere bakarak bunu çözmenin bir yolu yoktur.
SiliconMind

6
Belki kodunda belgelemek zor, ama orada olduğunu belgeleri: wizzlern.nl/sites/wizzlern.nl/files/artikel/... . Dinamik yapı nedeniyle, yöntemler gerçekten daha iyi işe yaramaz, tam olarak hangi sınıfla çalıştığınızı tam olarak çözemezsiniz, her şey dinamik bir şekilde bir araya getirildiğinde. İlk defa bulmak zor olabilir, ancak bir kez hatırlamanız yeterince kolay.
Berdir

1
Orada drupal.org/project/agcobcau IDE otomatik tamamlama ile yardımcı olacaktır
larowlan

11
@Berdir Anlıyorum, ancak bu hala kötü bir tasarım. Şuna bakın: varlık $node->get('field_image')->entitydöndürür File. Ancak $node->get('field_image')->getEntity()ana Nodevarlık döndürür ! Sihirli yöntemlerin kullanılabilir olabileceğini anlıyorum, ancak daha büyük projelerde PITA'lar. Yine de sihir kullanmaya teşvik edilirsek neden arayüz yazmayı ve oo kodunu yazmıyorsun? Bir kere yaptıktan sonra hatırlamak yeterince kolay yazmıştım - katılmıyorum. Bunu yapmaya başladığınızda, kodunuzu daha az okunabilir ve daha az bakım yapılabilir kılacak çok kötü bir alışkanlık geliştireceksiniz.
SiliconMind,

4
Downvoted. Bunu bu şekilde yapardım. Bununla birlikte, eğer varlık referansları daha önce yüklenmemişse bu zaman zaman bozulacaktır (sonuç, somutlaştırılmış varlık yerine target_id ile bir dizi olacaktır). SiliconMind tarafından belirtilen yöntem tüm durumlara uygun şekilde çalışacak ve alan boş değilse, her zaman bir hazır varlık sınıfı döndürecektir.
Alexander Varwijk

8

Benim için çalışan şey şuydu:

$entity_id = $node->get('field_contact')->first()->getValue()['target_id'];

$entity = Node::load($entity_id)->toArray();

Diğer cevaplar beklediğim varlık alanları dizisini üretmedi


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.