Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
PrimaryEntityReferenceOptionsButtonsWidget
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 2
156
0.00% covered (danger)
0.00%
0 / 1
 formElement
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
20
 massageFormValues
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2
3namespace Drupal\primary_entity_reference\Plugin\Field\FieldWidget;
4
5use Drupal\Core\Field\Attribute\FieldWidget;
6use Drupal\Core\Field\FieldItemListInterface;
7use Drupal\Core\Form\FormStateInterface;
8use Drupal\Core\StringTranslation\TranslatableMarkup;
9use Drupal\Core\Field\Plugin\Field\FieldWidget\OptionsButtonsWidget;
10
11/**
12 * Plugin implementation of the 'options_buttons' widget.
13 */
14#[FieldWidget(
15  id: 'primary_entity_reference_options_buttons',
16  label: new TranslatableMarkup('Check boxes/radio buttons'),
17  field_types: [
18    'primary_entity_reference',
19  ],
20  multiple_values: TRUE,
21)]
22class PrimaryEntityReferenceOptionsButtonsWidget extends OptionsButtonsWidget {
23
24  /**
25   * {@inheritdoc}
26   */
27  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
28    $el = parent::formElement($items, $delta, $element, $form, $form_state);
29    // Alter the checkboxes to include a radio per option.
30    $values = $items->getValue();
31    $options = $this->getOptions($items->getEntity());
32    $default_values = array_column($values, 'target_id');
33
34    $primary = $default_values[0] ?? NULL;
35
36    $field_name = $this->fieldDefinition->getName();
37    $elements['#type'] = 'container';
38    $elements['#tree'] = TRUE;
39
40    foreach ($options as $key => $label) {
41      $elements[$key] = [
42        '#type' => 'container',
43        '#attributes' => ['class' => ['checkbox-radio-pair']],
44        'primary' => [
45          '#type' => 'radio',
46          '#title' => '',
47          '#return_value' => $key,
48          '#parents' => [$field_name, 0, 'primary'],
49          '#default_value' => ($key == $primary) ? $key : 0,
50          '#attributes' => [
51            'style' => 'margin-right: 35px;',
52          ],
53        ],
54        'target_id' => [
55          '#type' => 'checkbox',
56          '#title' => $label,
57          "#key_column" => "target_id",
58          '#return_value' => $key,
59          '#default_value' => in_array($key, $default_values) ? $key : 0,
60        ],
61
62      ];
63    }
64
65    return $elements;
66  }
67
68  /**
69   * {@inheritdoc}
70   */
71  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
72    $values = parent::massageFormValues($values, $form, $form_state);
73    $primary = 0;
74    foreach ($values as $delta => $value) {
75      if (isset($value['primary']) && $value['primary']) {
76        $primary = (int) $value['primary'];
77      }
78    }
79
80    $vals = [];
81    $i = 0;
82    foreach ($values as $value) {
83      if (isset($value['primary']) && $value['primary']) {
84        continue;
85      }
86      $vals[$i]['target_id'] = $value['target_id'];
87      $vals[$i]['primary'] = 0;
88      if ($value['target_id'] == $primary) {
89        $vals[$i]['primary'] = 1;
90      }
91
92      $i += 1;
93    }
94
95    return $vals;
96  }
97
98}