Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
0.00% |
0 / 134 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
||
| EntityViewDisplayFormTrait | |
0.00% |
0 / 134 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 8 |
870 | |
0.00% |
0 / 1 |
||
| submitForm | |
0.00% |
0 / 16 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
20 | |||||
| entityViewDisplayForm | |
0.00% |
0 / 26 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
20 | |||||
| buildOverridesForm | |
0.00% |
0 / 55 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
12 | |||||
| getAlreadyMappedFields | |
0.00% |
0 / 11 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
30 | |||||
| getSourceFieldAsOptions | |
0.00% |
0 / 14 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
42 | |||||
| buildExtraFieldRow | |
0.00% |
0 / 3 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
6 | |||||
| buildFieldRow | |
0.00% |
0 / 3 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
6 | |||||
| copyFormValuesToEntity | |
0.00% |
0 / 6 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
12 | |||||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Drupal\display_builder_entity_view\Form; |
| 6 | |
| 7 | use Drupal\Core\Entity\Display\EntityViewDisplayInterface; |
| 8 | use Drupal\Core\Entity\EntityInterface; |
| 9 | use Drupal\Core\Field\FieldDefinitionInterface; |
| 10 | use Drupal\Core\Form\FormStateInterface; |
| 11 | use Drupal\Core\Url; |
| 12 | use Drupal\display_builder\ConfigFormBuilderInterface; |
| 13 | use Drupal\display_builder_entity_view\Entity\DisplayBuilderEntityDisplayInterface; |
| 14 | use Drupal\display_builder_entity_view\Entity\DisplayBuilderOverridableInterface; |
| 15 | |
| 16 | /** |
| 17 | * Common methods for entity view display form. |
| 18 | */ |
| 19 | trait EntityViewDisplayFormTrait { |
| 20 | |
| 21 | /** |
| 22 | * Form submission handler. |
| 23 | * |
| 24 | * @param array $form |
| 25 | * An associative array containing the structure of the form. |
| 26 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
| 27 | * The current state of the form. |
| 28 | */ |
| 29 | public function submitForm(array &$form, FormStateInterface $form_state): void { |
| 30 | parent::submitForm($form, $form_state); |
| 31 | |
| 32 | // @todo we should have always a fallback. |
| 33 | $display_builder_config = $form_state->getValue([ConfigFormBuilderInterface::PROFILE_PROPERTY]) ?? 'default'; |
| 34 | |
| 35 | // Empty means disabled. |
| 36 | if (empty($display_builder_config)) { |
| 37 | $this->entity->unsetThirdPartySetting('display_builder', ConfigFormBuilderInterface::PROFILE_PROPERTY); |
| 38 | } |
| 39 | else { |
| 40 | $this->entity->setThirdPartySetting('display_builder', ConfigFormBuilderInterface::PROFILE_PROPERTY, $display_builder_config); |
| 41 | } |
| 42 | |
| 43 | $display_builder_override = $form_state->getValue([ConfigFormBuilderInterface::OVERRIDE_FIELD_PROPERTY]) ?? ''; |
| 44 | |
| 45 | // Empty means disabled. |
| 46 | if (empty($display_builder_override)) { |
| 47 | $this->entity->unsetThirdPartySetting('display_builder', ConfigFormBuilderInterface::OVERRIDE_FIELD_PROPERTY); |
| 48 | } |
| 49 | else { |
| 50 | $this->entity->setThirdPartySetting('display_builder', ConfigFormBuilderInterface::OVERRIDE_FIELD_PROPERTY, $display_builder_override); |
| 51 | } |
| 52 | |
| 53 | $display_builder_override_profile = $form_state->getValue([ConfigFormBuilderInterface::OVERRIDE_PROFILE_PROPERTY]) ?? ''; |
| 54 | |
| 55 | // Empty means disabled. |
| 56 | if (empty($display_builder_override_profile)) { |
| 57 | $this->entity->unsetThirdPartySetting('display_builder', ConfigFormBuilderInterface::OVERRIDE_PROFILE_PROPERTY); |
| 58 | } |
| 59 | else { |
| 60 | $this->entity->setThirdPartySetting('display_builder', ConfigFormBuilderInterface::OVERRIDE_PROFILE_PROPERTY, $display_builder_override_profile); |
| 61 | } |
| 62 | |
| 63 | $this->entity->save(); |
| 64 | $this->localTaskManager->clearCachedDefinitions(); |
| 65 | $this->routeBuilder->rebuild(); |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * Provides form elements to enable Display Builder. |
| 70 | * |
| 71 | * @param array $form |
| 72 | * The form structure. |
| 73 | * |
| 74 | * @return array |
| 75 | * The modified form. |
| 76 | */ |
| 77 | protected function entityViewDisplayForm(array $form): array { |
| 78 | $is_display_builder_enabled = $this->entity->isDisplayBuilderEnabled(); |
| 79 | |
| 80 | if ($is_display_builder_enabled) { |
| 81 | // Hide the table of fields. |
| 82 | $form['fields']['#access'] = FALSE; |
| 83 | $form['#fields'] = []; |
| 84 | $form['#extra'] = []; |
| 85 | } |
| 86 | |
| 87 | $form['manage_display_builder'] = [ |
| 88 | '#type' => 'link', |
| 89 | '#title' => $this->t('Display builder'), |
| 90 | '#weight' => -11, |
| 91 | '#attributes' => ['class' => ['button']], |
| 92 | '#url' => $this->entity->getBuilderUrl(), |
| 93 | '#access' => $is_display_builder_enabled, |
| 94 | ]; |
| 95 | |
| 96 | if (isset($form['modes'])) { |
| 97 | $form['modes']['#weight'] = 0; |
| 98 | } |
| 99 | |
| 100 | $form['display_builder_wrapper'] = [ |
| 101 | '#type' => 'details', |
| 102 | '#open' => TRUE, |
| 103 | '#title' => $this->t('Display builder'), |
| 104 | '#weight' => 1, |
| 105 | ]; |
| 106 | |
| 107 | $form['display_builder_wrapper'][ConfigFormBuilderInterface::PROFILE_PROPERTY] = $this->configFormBuilder->build($this->entity, FALSE); |
| 108 | |
| 109 | /** @var \Drupal\display_builder_entity_view\Entity\DisplayBuilderEntityDisplayInterface $entity */ |
| 110 | $entity = $this->getEntity(); |
| 111 | |
| 112 | if ($entity instanceof DisplayBuilderOverridableInterface) { |
| 113 | $form['display_builder_wrapper'][ConfigFormBuilderInterface::PROFILE_PROPERTY]['override_form'] = $this->buildOverridesForm($entity); |
| 114 | } |
| 115 | |
| 116 | return $form; |
| 117 | } |
| 118 | |
| 119 | /** |
| 120 | * Build the form for entity display overrides per content. |
| 121 | * |
| 122 | * @param \Drupal\display_builder_entity_view\Entity\DisplayBuilderEntityDisplayInterface $entity |
| 123 | * The entity. |
| 124 | * |
| 125 | * @return array |
| 126 | * The renderable form array. |
| 127 | */ |
| 128 | protected function buildOverridesForm(DisplayBuilderEntityDisplayInterface|DisplayBuilderOverridableInterface $entity): array { |
| 129 | $entity_type_id = $entity->getTargetEntityTypeId(); |
| 130 | $options = $this->getSourceFieldAsOptions(); |
| 131 | $target_entity_type_id = $this->entityTypeManager->getDefinition($entity_type_id)->getBundleEntityType(); |
| 132 | $description = [ |
| 133 | '#title' => $this->t('Add a UI Patterns Source field'), |
| 134 | '#type' => 'link', |
| 135 | '#attributes' => [ |
| 136 | 'data-dialog-type' => 'modal', |
| 137 | 'data-dialog-options' => \json_encode([ |
| 138 | 'title' => 'Add field: Source (UI Patterns)', |
| 139 | 'width' => '800', |
| 140 | ]), |
| 141 | 'class' => ['use-ajax'], |
| 142 | ], |
| 143 | '#url' => Url::fromRoute("field_ui.field_storage_config_add_sub_{$entity_type_id}", [ |
| 144 | $target_entity_type_id => $entity->getTargetBundle(), |
| 145 | 'display_as_group' => 'Group', |
| 146 | 'selected_field_type' => 'ui_patterns_source', |
| 147 | ]), |
| 148 | '#suffix' => '.', |
| 149 | ]; |
| 150 | |
| 151 | if (empty($options)) { |
| 152 | $description = [ |
| 153 | [ |
| 154 | '#plain_text' => $this->t('No eligible field found.') . ' ', |
| 155 | ], |
| 156 | $description, |
| 157 | ]; |
| 158 | } |
| 159 | /** @var \Drupal\display_builder_entity_view\Entity\DisplayBuilderOverridableInterface $overridable */ |
| 160 | $overridable = $entity; |
| 161 | $form = []; |
| 162 | $form[ConfigFormBuilderInterface::OVERRIDE_FIELD_PROPERTY] = [ |
| 163 | '#type' => 'select', |
| 164 | '#title' => $this->t('Select a field to override this display per content'), |
| 165 | '#options' => $options, |
| 166 | '#empty_option' => $this->t('- Disabled -'), |
| 167 | '#default_value' => $overridable->getDisplayBuilderOverrideField(), |
| 168 | '#description' => $description, |
| 169 | ]; |
| 170 | |
| 171 | $form[ConfigFormBuilderInterface::OVERRIDE_PROFILE_PROPERTY] = [ |
| 172 | '#type' => 'select', |
| 173 | '#title' => $this->t('Override profile'), |
| 174 | '#description' => $this->t('The profile used for content overrides.'), |
| 175 | '#options' => $this->configFormBuilder->getAllowedProfiles(), |
| 176 | '#default_value' => $overridable->getDisplayBuilderOverrideProfile()?->id(), |
| 177 | '#states' => [ |
| 178 | 'invisible' => [ |
| 179 | ':input[name="' . ConfigFormBuilderInterface::OVERRIDE_FIELD_PROPERTY . '"]' => ['filled' => FALSE], |
| 180 | ], |
| 181 | ], |
| 182 | ]; |
| 183 | |
| 184 | if (!$this->configFormBuilder->isAllowed($entity)) { |
| 185 | $form[ConfigFormBuilderInterface::OVERRIDE_FIELD_PROPERTY]['#disabled'] = TRUE; |
| 186 | unset($form[ConfigFormBuilderInterface::OVERRIDE_FIELD_PROPERTY]['#description']); |
| 187 | $form[ConfigFormBuilderInterface::OVERRIDE_PROFILE_PROPERTY]['#disabled'] = TRUE; |
| 188 | } |
| 189 | |
| 190 | return $form; |
| 191 | } |
| 192 | |
| 193 | /** |
| 194 | * Returns an array of UI Patterns Source fields which are already mapped. |
| 195 | * |
| 196 | * @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $current_display |
| 197 | * The current display. |
| 198 | * |
| 199 | * @return array |
| 200 | * An array of field names that are already mapped to the current display. |
| 201 | */ |
| 202 | protected function getAlreadyMappedFields(EntityViewDisplayInterface $current_display): array { |
| 203 | /** @var \Drupal\display_builder_entity_view\Entity\DisplayBuilderEntityDisplayInterface[] $displays */ |
| 204 | $displays = $this->entityTypeManager->getStorage('entity_view_display')->loadByProperties([ |
| 205 | 'targetEntityType' => $current_display->getTargetEntityTypeId(), |
| 206 | 'bundle' => $current_display->getTargetBundle(), |
| 207 | ]); |
| 208 | $field_names = []; |
| 209 | |
| 210 | foreach ($displays as $display) { |
| 211 | if ($display instanceof DisplayBuilderOverridableInterface) { |
| 212 | if ($display->isDisplayBuilderOverridable() |
| 213 | && $current_display->id() !== $display->id()) { |
| 214 | $field_names[] = $display->getDisplayBuilderOverrideField(); |
| 215 | } |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | return $field_names; |
| 220 | } |
| 221 | |
| 222 | /** |
| 223 | * Returns UI Patterns source fields as options. |
| 224 | * |
| 225 | * @return array |
| 226 | * An associative array of field names and labels. |
| 227 | */ |
| 228 | protected function getSourceFieldAsOptions(): array { |
| 229 | /** @var \Drupal\display_builder_entity_view\Entity\DisplayBuilderEntityDisplayInterface $display */ |
| 230 | $display = $this->getEntity(); |
| 231 | $field_definitions = $this->entityFieldManager->getFieldDefinitions( |
| 232 | $display->getTargetEntityTypeId(), |
| 233 | $display->getTargetBundle(), |
| 234 | ); |
| 235 | $fields = []; |
| 236 | |
| 237 | if ($display instanceof DisplayBuilderOverridableInterface |
| 238 | && $display instanceof EntityViewDisplayInterface |
| 239 | ) { |
| 240 | $already_mapped = $this->getAlreadyMappedFields($display); |
| 241 | |
| 242 | foreach ($field_definitions as $field_name => $field_definition) { |
| 243 | if ($field_definition->getType() === 'ui_patterns_source' |
| 244 | && !\in_array($field_name, $already_mapped, TRUE) |
| 245 | ) { |
| 246 | $fields[$field_name] = $field_definition->getLabel(); |
| 247 | } |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | return $fields; |
| 252 | } |
| 253 | |
| 254 | /** |
| 255 | * Builds the table row structure for a single extra field. |
| 256 | * |
| 257 | * @param string $field_id |
| 258 | * The field ID. |
| 259 | * @param array $extra_field |
| 260 | * The pseudo-field element. |
| 261 | * |
| 262 | * @return array |
| 263 | * A table row array. |
| 264 | */ |
| 265 | protected function buildExtraFieldRow($field_id, $extra_field): array { |
| 266 | if ($this->entity->isDisplayBuilderEnabled()) { |
| 267 | return []; |
| 268 | } |
| 269 | |
| 270 | return parent::buildExtraFieldRow($field_id, $extra_field); |
| 271 | } |
| 272 | |
| 273 | /** |
| 274 | * Builds the table row structure for a single field. |
| 275 | * |
| 276 | * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition |
| 277 | * The field definition. |
| 278 | * @param array $form |
| 279 | * An associative array containing the structure of the form. |
| 280 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
| 281 | * The current state of the form. |
| 282 | * |
| 283 | * @return array |
| 284 | * A table row array. |
| 285 | */ |
| 286 | protected function buildFieldRow(FieldDefinitionInterface $field_definition, array $form, FormStateInterface $form_state): array { |
| 287 | if ($this->entity->isDisplayBuilderEnabled()) { |
| 288 | return []; |
| 289 | } |
| 290 | |
| 291 | return parent::buildFieldRow($field_definition, $form, $form_state); |
| 292 | } |
| 293 | |
| 294 | /** |
| 295 | * Copies top-level form values to entity properties. |
| 296 | * |
| 297 | * This should not change existing entity properties that are not being edited |
| 298 | * by this form. |
| 299 | * |
| 300 | * @param \Drupal\Core\Entity\EntityInterface $entity |
| 301 | * The entity the current form should operate upon. |
| 302 | * @param array $form |
| 303 | * A nested array of form elements comprising the form. |
| 304 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
| 305 | * The current state of the form. |
| 306 | * |
| 307 | * @see \Drupal\Core\Form\ConfigFormBase::copyFormValuesToConfig() |
| 308 | */ |
| 309 | protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state): void { |
| 310 | /** @var \Drupal\display_builder_entity_view\Entity\DisplayBuilderEntityDisplayInterface $entity */ |
| 311 | // Do not process field values if Display Builder is or will be enabled. |
| 312 | $set_enabled = (bool) $form_state->getValue(['display_builder', 'enabled'], FALSE); |
| 313 | $already_enabled = $entity->isDisplayBuilderEnabled(); |
| 314 | |
| 315 | if ($already_enabled || $set_enabled) { |
| 316 | $form['#fields'] = []; |
| 317 | $form['#extra'] = []; |
| 318 | } |
| 319 | |
| 320 | parent::copyFormValuesToEntity($entity, $form, $form_state); |
| 321 | } |
| 322 | |
| 323 | } |
Below are the source code lines that represent each code path as identified by Xdebug. Please note a path is not
necessarily coterminous with a line, a line may contain multiple paths and therefore show up more than once.
Please also be aware that some paths may include implicit rather than explicit branches, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.