Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
147 / 147
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
NameFormDisplaySettingsTrait
100.00% covered (success)
100.00%
147 / 147
100.00% covered (success)
100.00%
4 / 4
8
100.00% covered (success)
100.00%
1 / 1
 getDefaultNameFormDisplaySettings
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
1 / 1
1
 buildNameFormDisplayPerComponentElements
100.00% covered (success)
100.00%
47 / 47
100.00% covered (success)
100.00%
1 / 1
2
 buildNameFormDisplayLayoutElements
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
1 / 1
3
 getDefaultNameFormDisplaySettingsForm
100.00% covered (success)
100.00%
39 / 39
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\name\Traits;
6
7use Symfony\Component\DependencyInjection\ContainerInterface;
8
9/**
10 * Name form display settings trait.
11 *
12 * General form display settings.
13 */
14trait NameFormDisplaySettingsTrait {
15
16  /**
17   * Gets the default settings for controlling a name element.
18   *
19   * @return array
20   *   Default settings.
21   */
22  protected static function getDefaultNameFormDisplaySettings() {
23    return [
24      'labels' => [
25        'title' => t('Title'),
26        'given' => t('Given'),
27        'middle' => t('Middle name(s)'),
28        'family' => t('Family'),
29        'generational' => t('Generational'),
30        'credentials' => t('Credentials'),
31      ],
32      'size' => [
33        'title' => 6,
34        'given' => 20,
35        'middle' => 20,
36        'family' => 20,
37        'generational' => 5,
38        'credentials' => 35,
39      ],
40      'title_display' => [
41        'title' => 'description',
42        'given' => 'description',
43        'middle' => 'description',
44        'family' => 'description',
45        'generational' => 'description',
46        'credentials' => 'description',
47      ],
48      'widget_layout' => 'stacked',
49      'field_title_display' => 'before',
50      'show_component_required_marker' => FALSE,
51      'flag_required_input' => FALSE,
52      'credentials_inline' => FALSE,
53    ];
54  }
55
56  /**
57   * Builds per-component display form elements.
58   *
59   * @param array $settings
60   *   The display settings.
61   * @param array $components
62   *   Translated component labels.
63   * @param array $title_options
64   *   Label display radio options.
65   *
66   * @return array
67   *   Per-component labels, size, and title_display elements.
68   */
69  private function buildNameFormDisplayPerComponentElements(array $settings, array $components, array $title_options): array {
70    $element = [
71      'labels' => [
72        '#title' => $this->t('Labels'),
73        '#description' => $this->t('The labels are used to distinguish the components.'),
74      ],
75      'title_display' => [
76        '#title' => $this->t('Label display'),
77        '#description' => $this->t('The title display controls how the label of the name component is displayed in the form:<br>"%above" is the standard title;<br>"%below" is the standard description;<br>"%placeholder" uses the placeholder attribute, select lists do not support this option;<br>"%attribute" adds a title attribute to create a tooltip rather than a label.<br>"%hidden" removes the label.', [
78          '%above' => t('above'),
79          '%below' => t('below'),
80          '%placeholder' => t('placeholder'),
81          '%attribute' => t('attribute'),
82          '%hidden' => t('hidden'),
83        ]),
84      ],
85      'size' => [
86        '#title' => $this->t('HTML size'),
87        '#description' => $this->t('The HTML size property tells the browser what the width of the field should be when it is rendered. This gets overridden by the themes CSS properties. This must be between 1 and 255.'),
88      ],
89    ];
90    foreach ($components as $key => $title) {
91      $element['labels'][$key] = [
92        '#type' => 'textfield',
93        '#title' => $this->t('Label for @title', ['@title' => $title]),
94        '#title_display' => 'invisible',
95        '#default_value' => $settings['labels'][$key],
96        '#required' => TRUE,
97        '#size' => 10,
98      ];
99      $element['size'][$key] = [
100        '#type' => 'number',
101        '#min' => 1,
102        '#max' => 255,
103        '#title' => $this->t('HTML size property for @title', ['@title' => $title]),
104        '#title_display' => 'invisible',
105        '#default_value' => $settings['size'][$key],
106        '#required' => FALSE,
107        '#size' => 10,
108      ];
109      $element['title_display'][$key] = [
110        '#type' => 'radios',
111        '#title' => $this->t('Label display for @title', ['@title' => $title]),
112        '#title_display' => 'invisible',
113        '#default_value' => $settings['title_display'][$key],
114        '#options' => $title_options,
115      ];
116    }
117    return $element;
118  }
119
120  /**
121   * Builds widget layout and field title display elements.
122   *
123   * @return array
124   *   Layout-related form elements.
125   */
126  private function buildNameFormDisplayLayoutElements(): array {
127    $layout_options = [];
128    $widget_layouts = \Drupal::getContainer()
129      ->get('name.widget_layouts', ContainerInterface::NULL_ON_INVALID_REFERENCE);
130    if ($widget_layouts) {
131      foreach ($widget_layouts->getLayouts() as $layout => $info) {
132        $layout_options[$layout] = $info['label'];
133      }
134    }
135
136    return [
137      'field_title_display' => [
138        '#type' => 'select',
139        '#title' => $this->t('Title Display'),
140        '#description' => $this->t('Whether to show or hide the top-level field label.'),
141        '#default_value' => $this->getSetting('field_title_display'),
142        '#table_group' => 'above',
143        '#options' => [
144          'before' => $this->t('Before'),
145          'invisible' => $this->t('Visually hidden'),
146          'none' => $this->t('Hidden'),
147        ],
148        '#weight' => -49,
149      ],
150      'widget_layout' => [
151        '#type' => 'radios',
152        '#title' => $this->t('Widget layout'),
153        '#default_value' => $this->getSetting('widget_layout'),
154        '#options' => $layout_options,
155        '#table_group' => 'above',
156        '#required' => TRUE,
157        '#weight' => -50,
158      ],
159    ];
160  }
161
162  /**
163   * Returns a form for the default settings defined above.
164   *
165   * The following keys are closely tied to the pre-render function to theme
166   * the settings into a nicer table.
167   * - #indent_row: Adds an empty TD cell and adds an 'elements' child that
168   *   contains the children (if given).
169   * - #table_group: Used to either position within the table by the element
170   *   key, or set to 'none', to append it below the table.
171   *
172   * Any element within the table should have component keyed children.
173   *
174   * Other elements are rendered directly.
175   *
176   * @param array $settings
177   *   The settings.
178   *
179   * @return array
180   *   The form definition for the field settings.
181   */
182  protected function getDefaultNameFormDisplaySettingsForm(array $settings) {
183    $metadata = \Drupal::getContainer()
184      ->get('name.component_metadata', ContainerInterface::NULL_ON_INVALID_REFERENCE);
185    $components = $metadata ? $metadata->getTranslations() : [];
186
187    $title_options = [
188      'title' => $this->t('above'),
189      'description' => $this->t('below'),
190      'placeholder' => $this->t('placeholder'),
191      'attribute' => $this->t('attribute'),
192      'none' => $this->t('hidden'),
193    ];
194
195    $element = [];
196    $element['components_extra'] = [
197      '#indent_row' => TRUE,
198    ];
199    $element['show_component_required_marker'] = [
200      '#type' => 'checkbox',
201      '#title' => $this->t('Show component required marker'),
202      '#default_value' => $this->getSetting('show_component_required_marker'),
203      '#description' => $this->t('Appends an asterisk after the component title if the component is required as part of a complete name.'),
204      '#table_group' => 'components_extra',
205    ];
206    $element['flag_required_input'] = [
207      '#type' => 'checkbox',
208      '#title' => $this->t('Flags inputs as required'),
209      '#default_value' => $this->getSetting('flag_required_input'),
210      '#description' => $this->t('This automatically validates for empty fields, and flags inputs as required.'),
211      '#table_group' => 'components_extra',
212    ];
213    $element['credentials_inline'] = [
214      '#type' => 'checkbox',
215      '#title' => $this->t('Show the credentials inline'),
216      '#default_value' => $this->getSetting('credentials_inline'),
217      '#description' => $this->t('The default position is to show the credentials on a line by themselves. This option overrides this to render the component inline.'),
218      '#table_group' => 'components_extra',
219    ];
220
221    return array_merge(
222      $element,
223      $this->buildNameFormDisplayPerComponentElements($settings, $components, $title_options),
224      $this->buildNameFormDisplayLayoutElements(),
225    );
226  }
227
228}