参照されたエンティティのインスタンスを取得する方法は?


35

という名前の画像フィールドを持つノードオブジェクトがありますfield_image。私がする時

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

エンティティオブジェクトではなく、いくつかのプロパティを持つ配列を取得します。配列は次のようになります。

'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

を使用してファイルエンティティを手動でロードするtarget_id必要がありますか、またはのインスタンスから参照エンティティオブジェクトを自動的に取得する方法はありDrupal\image\Plugin\Field\FieldType\ImageItemますか?

参照されたエンティティにゲッター経由でアクセスできないのはなぜですか?すぐに使用できない場合は、遅延ロードされる可能性があります。


$ node-> get( 'imagefield')-> first()-> getTarget()アイテムが1つしかない場合、または$ node-> get( 'imagefield')-> referencedEntities()...実際には最後のアイテムが必要なものすべて。

@IvanJaros正確には:PHP Fatal error: Call to undefined method Drupal\image\Plugin\Field\FieldType\ImageItem::getTarget()。ただし $node->get('imagefield')->referencedEntities()、実際にメソッドを実装する$node->get('imagefield')インスタンスを返すおかげで機能します。したがって、あなたのソリューションは部分的です-それはリストに対して機能しますが、単一のフィールドに対しては機能しません。EntityReferenceFieldItemListreferencedEntities()
SiliconMind

ええ、getTargetはフィールド項目ではなくエンティティ参照データ型にあります。

回答:


63

参照されるエンティティへのパスは非常に長いです:

// $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.

もちろん、1回のライナーコールで取得できますが、それでも面倒でありEntityReferenceItem、参照エンティティオブジェクトを返すメソッドを提供しないのはなぜでしょうか。

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

また、参照されているすべてのエンティティの配列を取得するのは非常に簡単であることに注意してください。

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

エンティティ参照フィールドの$node->get($field)場合、メソッドEntityReferenceFieldItemListを実装referencedEntities()するインスタンスを返すため、機能します。


33

次を使用できます。

$node->field_image->entity

最初の値が必要な場合


9
これが魔法の方法が悪い理由です。これをコードで文書化する方法はなく、実装されたインターフェースを見てこれを把握する方法もありません。
SiliconMind

6
それは多分コードで文書化することは困難ですが、そこにあるドキュメント:wizzlern.nl/sites/wizzlern.nl/files/artikel/...が。動的構造のため、メソッドは実際にはうまく機能せず、すべてが動的に一緒に構築されるため、どのクラスを使用しているか正確に把握できません。初めて見つけるのは難しいかもしれませんが、一度覚えたら簡単です。
ベルディール

1
IDEの自動補完を支援するdrupal.org/project/agcobcauがあります-larowlan
1

11
@Berdir私は理解していますが、これはまだ悪い設計です。これを見てください:エンティティを$node->get('field_image')->entity返しFileます。ただし、$node->get('field_image')->getEntity()Nodeエンティティを返します!魔法のメソッドが使えるかもしれないことは理解していますが、大規模なプロジェクトではPITAです。とにかくマジックを使用することが推奨されているのに、なぜインターフェイスとooコードを書くのが面倒ですか?一度覚えたら簡単に覚えられると書いていますが、そうは思いません。これを開始すると、コードの可読性と保守性が低下する、非常に悪い習慣が発生します。
SiliconMind

4
ダウン投票。以前はこのようにしていました。ただし、エンティティ参照が以前にロードされていない場合、これは時々壊れます(結果は、インスタンス化されたエンティティの代わりにtarget_idを持つ配列になります)。SiliconMindで概説されているメソッドは、すべてのケースを適切に処理し、フィールドが空でない場合は常にインスタンス化されたエンティティクラスを返します。
アレクサンダーヴァールワイク

8

私のために働いたのは:

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

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

他の答えは、私が期待していたエンティティフィールド配列を生成しませんでした


8

参照フィールドからエンティティを取得する方法。referedEntitiesについて@SiliconMindに同意し、フィールドアイテムのデルタによってキー設定されたエンティティオブジェクトの配列を返します。

単純な:

$node->get('field_name')->referencedEntities();

EntityReferenceFieldItemList :: referencedEntities

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.