Làm thế nào để có được ví dụ của thực thể được tham chiếu?


35

Tôi có một đối tượng nút với trường hình ảnh được đặt tên field_image. Khi tôi làm

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

Tôi nhận được mảng với một số thuộc tính thay vì đối tượng thực thể. Mảng trông như thế này:

'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

Tôi có phải tải dữ liệu thực thể tệp bằng cách sử dụng không target_idhoặc có cách nào để tự động nhận đối tượng thực thể được tham chiếu từ thể hiện của Drupal\image\Plugin\Field\FieldType\ImageItem?

Tại sao thực thể được tham chiếu không thể truy cập thông qua getter? Nó có thể được tải lười biếng nếu nó không có sẵn ngay lập tức.


$ node-> get ('imagefield') -> first () -> getTarget () nếu chỉ có một mục hoặc $ node-> get ('imagefield') -> tham chiếuEntities () ... thực sự đó là mục cuối cùng tất cả những gì bạn cần.

@IvanJaros Không chính xác : PHP Fatal error: Call to undefined method Drupal\image\Plugin\Field\FieldType\ImageItem::getTarget(). Tuy nhiên $node->get('imagefield')->referencedEntities()hoạt động nhờ thực tế $node->get('imagefield')trả về EntityReferenceFieldItemListthực hiện referencedEntities()phương thức thực hiện . Vì vậy, giải pháp của bạn chỉ là một phần - nó hoạt động cho các danh sách nhưng không phải cho các trường đơn lẻ.
SiliconMind

Vâng đúng, getTarget nằm trên kiểu dữ liệu tham chiếu thực thể, không phải mục trường.

Câu trả lời:


63

Đường dẫn đến thực thể được tham chiếu rất dài:

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

Tất nhiên người ta vẫn có thể nhận được nó thông qua một cuộc gọi lót, nhưng vẫn còn cồng kềnh và tôi tự hỏi tại sao EntityReferenceItemkhông cung cấp phương thức sẽ trả về đối tượng thực thể tham chiếu.

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

Cũng đáng lưu ý rằng khá dễ dàng để có được mảng của tất cả các thực thể được tham chiếu:

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

Nó hoạt động vì đối với các trường tham chiếu thực thể $node->get($field)trả về thể EntityReferenceFieldItemListhiện của referencedEntities()phương thức thực hiện .


33

Bạn có thể dùng:

$node->field_image->entity

nếu bạn muốn giá trị đầu tiên


9
Đây là lý do tại sao các phương pháp ma thuật là xấu. Không có cách nào để ghi lại điều này trong mã và không có cách nào để tìm ra điều này bằng cách nhìn vào các giao diện được thực hiện.
SiliconMind

6
Thật khó để ghi lại trong mã có thể, nhưng có tài liệu hướng dẫn: wizzlern.nl/sites/wizzlern.nl/files/artikel/... . Do cấu trúc động, các phương thức sẽ không thực sự hoạt động tốt hơn, bạn không thể tìm ra lớp nào bạn đang làm việc chính xác như mọi thứ được xây dựng cùng nhau một cách linh hoạt. Có thể khó tìm thấy lần đầu tiên, nhưng nó đủ dễ để nhớ một khi bạn đã làm.
Berdir

1
drupal.org/project/agcobcau sẽ giúp hoàn thành tự động trong IDE
larowlan

11
@Berdir Tôi hiểu điều đó, tuy nhiên đây vẫn là thiết kế tồi. Nhìn vào điều này: $node->get('field_image')->entitytrả về Filethực thể. Tuy nhiên $node->get('field_image')->getEntity()trả về Nodethực thể cha mẹ ! Tôi hiểu rằng các phương pháp ma thuật có thể sử dụng được, nhưng chúng là PITA trong các dự án lớn hơn. Tại sao phải viết giao diện và mã oo nếu chúng ta được khuyến khích sử dụng phép thuật? Bạn đã viết nó đủ dễ để nhớ một khi bạn đã làm - tôi không đồng ý. Khi bạn bắt đầu thực hiện việc này, bạn sẽ phát triển thói quen thực sự xấu sẽ khiến mã của bạn ít đọc hơn và ít bảo trì hơn.
SiliconMind

4
Bị hạ bệ. Tôi đã từng làm theo cách này. Tuy nhiên, điều này đôi khi sẽ bị phá vỡ nếu các tham chiếu thực thể chưa được tải trước đó (kết quả sẽ là một mảng với target_id thay vì một thực thể được khởi tạo). Phương thức được SiliconMind vạch ra sẽ xử lý đúng tất cả các trường hợp và sẽ luôn trả về một lớp thực thể được khởi tạo nếu trường không trống.
Alexander Varwijk

8

Những gì làm việc cho tôi là:

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

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

Các câu trả lời khác không tạo ra mảng trường thực thể mà tôi đang mong đợi


8

Để biết cách lấy thực thể từ trường được tham chiếu. Tôi đồng ý với @SiliconMind về tham chiếuEntities, nó trả về một mảng các đối tượng thực thể được khóa bởi deltas mục trường.

Rất đơn giản:

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

EntityReferenceFieldItemList :: tham chiếuEntities

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.