Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
0.00% |
0 / 92 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
||
| PageLayoutForm | |
0.00% |
0 / 92 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 8 |
506 | |
0.00% |
0 / 1 |
||
| __construct | |
0.00% |
0 / 1 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
2 | |||||
| form | |
0.00% |
0 / 28 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
2 | |||||
| save | |
0.00% |
0 / 10 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
12 | |||||
| submitForm | |
0.00% |
0 / 2 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
2 | |||||
| actionsElement | |
0.00% |
0 / 6 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
12 | |||||
| buildConditionsForm | |
0.00% |
0 / 27 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
72 | |||||
| alterConditionsForm | |
0.00% |
0 / 12 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
12 | |||||
| submitConditions | |
0.00% |
0 / 6 |
n/a |
0 / 0 |
n/a |
0 / 0 |
|
0.00% |
0 / 1 |
6 | |||||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Drupal\display_builder_page_layout\Form; |
| 6 | |
| 7 | use Drupal\Core\DependencyInjection\AutowireTrait; |
| 8 | use Drupal\Core\Entity\EntityForm; |
| 9 | use Drupal\Core\Executable\ExecutableManagerInterface; |
| 10 | use Drupal\Core\Form\FormStateInterface; |
| 11 | use Drupal\Core\Form\SubformState; |
| 12 | use Drupal\Core\Language\LanguageManagerInterface; |
| 13 | use Drupal\Core\Plugin\Context\ContextRepositoryInterface; |
| 14 | use Drupal\display_builder\DisplayBuildablePluginManager; |
| 15 | use Drupal\display_builder_page_layout\Entity\PageLayout; |
| 16 | use Symfony\Component\DependencyInjection\Attribute\Autowire; |
| 17 | |
| 18 | /** |
| 19 | * Page layout form. |
| 20 | */ |
| 21 | final class PageLayoutForm extends EntityForm { |
| 22 | |
| 23 | use AutowireTrait; |
| 24 | |
| 25 | public function __construct( |
| 26 | private readonly ContextRepositoryInterface $contextRepository, |
| 27 | #[Autowire(service: 'plugin.manager.condition')] |
| 28 | private readonly ExecutableManagerInterface $conditionManager, |
| 29 | private readonly LanguageManagerInterface $languageManager, |
| 30 | #[Autowire(service: 'plugin.manager.display_buildable')] |
| 31 | private readonly DisplayBuildablePluginManager $displayBuildableManager, |
| 32 | ) {} |
| 33 | |
| 34 | /** |
| 35 | * {@inheritdoc} |
| 36 | */ |
| 37 | public function form(array $form, FormStateInterface $form_state): array { |
| 38 | $form = parent::form($form, $form_state); |
| 39 | |
| 40 | /** @var \Drupal\display_builder_page_layout\PageLayoutInterface $entity */ |
| 41 | $entity = $this->entity; |
| 42 | |
| 43 | // Store the gathered contexts in the form state for other objects to use |
| 44 | // during form building. |
| 45 | $form_state->setTemporaryValue('gathered_contexts', $this->contextRepository->getAvailableContexts()); |
| 46 | |
| 47 | // Because of $form['conditions']. |
| 48 | $form['#tree'] = TRUE; |
| 49 | |
| 50 | $form['label'] = [ |
| 51 | '#type' => 'textfield', |
| 52 | '#title' => $this->t('Label'), |
| 53 | '#maxlength' => 255, |
| 54 | '#default_value' => $entity->label(), |
| 55 | '#required' => TRUE, |
| 56 | ]; |
| 57 | |
| 58 | $form['id'] = [ |
| 59 | '#type' => 'machine_name', |
| 60 | '#default_value' => $entity->id(), |
| 61 | '#machine_name' => [ |
| 62 | 'exists' => [PageLayout::class, 'load'], |
| 63 | ], |
| 64 | '#disabled' => !$entity->isNew(), |
| 65 | ]; |
| 66 | |
| 67 | /** @var \Drupal\display_builder\DisplayBuildableInterface $buildable */ |
| 68 | $buildable = $this->displayBuildableManager->createInstance('page_layout', ['entity' => $entity]); |
| 69 | $form = \array_merge($form, $buildable->buildInstanceForm()); |
| 70 | |
| 71 | $form['conditions'] = $this->buildConditionsForm([], $form_state); |
| 72 | $form['status'] = [ |
| 73 | '#type' => 'checkbox', |
| 74 | '#title' => $this->t('Enabled'), |
| 75 | '#default_value' => $entity->status(), |
| 76 | ]; |
| 77 | |
| 78 | return $form; |
| 79 | } |
| 80 | |
| 81 | /** |
| 82 | * {@inheritdoc} |
| 83 | */ |
| 84 | public function save(array $form, FormStateInterface $form_state): int { |
| 85 | $result = parent::save($form, $form_state); |
| 86 | $message_args = ['%label' => $this->entity->label()]; |
| 87 | $this->messenger()->addStatus( |
| 88 | match ($result) { |
| 89 | SAVED_NEW => $this->t('Created new page layout %label.', $message_args), |
| 90 | default => $this->t('Updated page layout %label.', $message_args), |
| 91 | } |
| 92 | ); |
| 93 | $form_state->setRedirectUrl($this->entity->toUrl('collection')); |
| 94 | |
| 95 | return $result; |
| 96 | } |
| 97 | |
| 98 | /** |
| 99 | * {@inheritdoc} |
| 100 | */ |
| 101 | public function submitForm(array &$form, FormStateInterface $form_state): void { |
| 102 | parent::submitForm($form, $form_state); |
| 103 | $this->submitConditions($form, $form_state); |
| 104 | } |
| 105 | |
| 106 | /** |
| 107 | * {@inheritdoc} |
| 108 | */ |
| 109 | protected function actionsElement(array $form, FormStateInterface $form_state): array { |
| 110 | $form = parent::actionsElement($form, $form_state); |
| 111 | /** @var \Drupal\display_builder_page_layout\PageLayoutInterface $page_layout */ |
| 112 | $page_layout = $this->entity; |
| 113 | |
| 114 | /** @var \Drupal\display_builder\DisplayBuildableInterface $buildable */ |
| 115 | $buildable = $this->displayBuildableManager->createInstance('page_layout', ['entity' => $page_layout]); |
| 116 | |
| 117 | if ($page_layout->isNew() && !$buildable->isAllowed()) { |
| 118 | $form['submit']['#disabled'] = TRUE; |
| 119 | } |
| 120 | |
| 121 | return $form; |
| 122 | } |
| 123 | |
| 124 | /** |
| 125 | * Helper function for building the conditions UI form. |
| 126 | * |
| 127 | * @param array $form |
| 128 | * An associative array containing the structure of the form. |
| 129 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
| 130 | * The current state of the form. |
| 131 | * |
| 132 | * @return array |
| 133 | * The form array with the conditions UI added in. |
| 134 | */ |
| 135 | private function buildConditionsForm(array $form, FormStateInterface $form_state) { |
| 136 | $form['visibility_tabs'] = [ |
| 137 | '#type' => 'vertical_tabs', |
| 138 | '#title' => $this->t('Conditions'), |
| 139 | '#parents' => ['visibility_tabs'], |
| 140 | ]; |
| 141 | |
| 142 | /** @var \Drupal\display_builder_page_layout\PageLayoutInterface $entity */ |
| 143 | $entity = $this->entity; |
| 144 | // @todo \PluginNotFoundException: |
| 145 | $conditions = $entity->getConditions()->getConfiguration(); |
| 146 | |
| 147 | // Important to filter with contexts to have ContextAware working. |
| 148 | $definitions = $this->conditionManager->getFilteredDefinitions('page_layout', $form_state->getTemporaryValue('gathered_contexts'), ['page_layout' => $entity]); |
| 149 | |
| 150 | foreach ($definitions as $condition_id => $definition) { |
| 151 | // Don't display the current theme condition. |
| 152 | if ($condition_id === 'current_theme') { |
| 153 | continue; |
| 154 | } |
| 155 | |
| 156 | // Don't display the language condition until we have multiple languages. |
| 157 | if ($condition_id === 'language' && !$this->languageManager->isMultilingual()) { |
| 158 | continue; |
| 159 | } |
| 160 | |
| 161 | if (\str_starts_with($condition_id, 'entity_bundle:')) { |
| 162 | $entity_type_id = \str_replace('entity_bundle:', '', $condition_id); |
| 163 | $entity_type = $this->entityTypeManager->getDefinition($entity_type_id); |
| 164 | $url = $entity_type->getLinkTemplate('canonical'); |
| 165 | |
| 166 | if (!$url || \str_starts_with((string) $url, '/admin')) { |
| 167 | continue; |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | /** @var \Drupal\Core\Condition\ConditionInterface $condition */ |
| 172 | $condition = $this->conditionManager->createInstance($condition_id, $conditions[$condition_id] ?? []); |
| 173 | $form_state->set(['conditions', $condition_id], $condition); |
| 174 | $condition_form = $condition->buildConfigurationForm([], $form_state); |
| 175 | $condition_form['#type'] = 'details'; |
| 176 | $condition_form['#title'] = $definition['label']; |
| 177 | $condition_form['#group'] = 'visibility_tabs'; |
| 178 | $form[$condition_id] = $condition_form; |
| 179 | } |
| 180 | |
| 181 | return $this->alterConditionsForm($form); |
| 182 | } |
| 183 | |
| 184 | /** |
| 185 | * Alter conditions form. |
| 186 | * |
| 187 | * @param array $form |
| 188 | * An associative array containing the structure of the form. |
| 189 | */ |
| 190 | private function alterConditionsForm(array $form): array { |
| 191 | if (isset($form['user_role'])) { |
| 192 | $form['user_role']['#title'] = $this->t('User roles'); |
| 193 | } |
| 194 | |
| 195 | if (isset($form['request_path'])) { |
| 196 | $form['request_path']['#title'] = $this->t('Pages'); |
| 197 | $form['request_path']['negate']['#type'] = 'radios'; |
| 198 | $form['request_path']['negate']['#default_value'] = (int) $form['request_path']['negate']['#default_value']; |
| 199 | $form['request_path']['negate']['#title_display'] = 'invisible'; |
| 200 | $form['request_path']['negate']['#options'] = [ |
| 201 | $this->t('Activate on the listed pages'), |
| 202 | $this->t('Skip for the listed pages'), |
| 203 | ]; |
| 204 | } |
| 205 | |
| 206 | return $form; |
| 207 | } |
| 208 | |
| 209 | /** |
| 210 | * Helper function to independently submit the conditions UI. |
| 211 | * |
| 212 | * @param array $form |
| 213 | * A nested array form elements comprising the form. |
| 214 | * @param \Drupal\Core\Form\FormStateInterface $form_state |
| 215 | * The current state of the form. |
| 216 | */ |
| 217 | private function submitConditions(array $form, FormStateInterface $form_state): void { |
| 218 | foreach (\array_keys($form_state->getValue('conditions')) as $condition_id) { |
| 219 | // Allow the condition to submit the form. |
| 220 | $condition = $form_state->get(['conditions', $condition_id]); |
| 221 | $condition->submitConfigurationForm($form['conditions'][$condition_id], SubformState::createForSubform($form['conditions'][$condition_id], $form, $form_state)); |
| 222 | |
| 223 | $condition_configuration = $condition->getConfiguration(); |
| 224 | // Update the visibility conditions on the block. |
| 225 | /** @var \Drupal\display_builder_page_layout\PageLayoutInterface $entity */ |
| 226 | $entity = $this->entity; |
| 227 | $entity->getConditions()->addInstanceId((string) $condition_id, $condition_configuration); |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | } |
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.