Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
PrimaryEntityReferenceFieldItemList
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 3
42
0.00% covered (danger)
0.00%
0 / 1
 __get
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 preSave
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 primary
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\primary_entity_reference\Plugin\Field;
6
7use Drupal\Core\Field\EntityReferenceFieldItemList;
8use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
9
10/**
11 * Defines an item list class for entity reference fields.
12 */
13class PrimaryEntityReferenceFieldItemList extends EntityReferenceFieldItemList implements EntityReferenceFieldItemListInterface {
14
15  /**
16   * Magic method to get the primary item.
17   */
18  public function __get($name) {
19    // This enables $item->primary to call $this->primary()
20    if ($name === 'primary') {
21      return $this->primary();
22    }
23
24    // Fallback to parent for other dynamic properties.
25    return parent::__get($name);
26  }
27
28  /**
29   * {@inheritdoc}
30   */
31  public function preSave() {
32    usort($this->list, function ($a, $b) {
33      return $b->get('primary')->getValue() <=> $a->get('primary')->getValue();
34    });
35
36    parent::preSave();
37  }
38
39  /**
40   * Gets the primary item, or the first item if none marked.
41   *
42   * @return \Drupal\Core\Field\FieldItemInterface|null
43   *   The primary item, or NULL if none exist.
44   */
45  public function primary() {
46    foreach ($this->list as $item) {
47      if ($item->get('primary')->getValue()) {
48        return $item;
49      }
50    }
51    // Fallback to first item.
52    return $this->list[0] ?? NULL;
53  }
54
55}