Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
0.00% |
0 / 91 |
|
0.00% |
0 / 46 |
|
0.00% |
0 / 49 |
|
0.00% |
0 / 12 |
CRAP | |
0.00% |
0 / 1 |
| HistoryButtons | |
0.00% |
0 / 85 |
|
0.00% |
0 / 46 |
|
0.00% |
0 / 49 |
|
0.00% |
0 / 12 |
756 | |
0.00% |
0 / 1 |
| build | |
0.00% |
0 / 15 |
|
0.00% |
0 / 12 |
|
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
30 | |||
| onAttachToRoot | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| onAttachToSlot | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| onMove | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| onHistoryChange | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| onUpdate | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| onDelete | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| hasButtons | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| rebuild | |
0.00% |
0 / 8 |
|
0.00% |
0 / 3 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| buildUndoButton | |
0.00% |
0 / 11 |
|
0.00% |
0 / 7 |
|
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
20 | |||
| buildRedoButton | |
0.00% |
0 / 11 |
|
0.00% |
0 / 7 |
|
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
20 | |||
| buildClearButton | |
0.00% |
0 / 14 |
|
0.00% |
0 / 10 |
|
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
30 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Drupal\display_builder\Plugin\display_builder\Island; |
| 6 | |
| 7 | use Drupal\Core\StringTranslation\TranslatableMarkup; |
| 8 | use Drupal\display_builder\Attribute\Island; |
| 9 | use Drupal\display_builder\InstanceInterface; |
| 10 | use Drupal\display_builder\IslandPluginToolbarButtonConfigurationBase; |
| 11 | use Drupal\display_builder\IslandType; |
| 12 | |
| 13 | /** |
| 14 | * History buttons island plugin implementation. |
| 15 | */ |
| 16 | #[Island( |
| 17 | id: 'history', |
| 18 | enabled_by_default: TRUE, |
| 19 | label: new TranslatableMarkup('History'), |
| 20 | description: new TranslatableMarkup('Undo and redo changes.'), |
| 21 | type: IslandType::Button, |
| 22 | )] |
| 23 | class HistoryButtons extends IslandPluginToolbarButtonConfigurationBase { |
| 24 | |
| 25 | /** |
| 26 | * {@inheritdoc} |
| 27 | */ |
| 28 | public function build(InstanceInterface $builder, array $data = [], array $options = []): array { |
| 29 | $builder_id = (string) $builder->id(); |
| 30 | $buttons = [ |
| 31 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 32 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 33 | $this->isButtonEnabled('clear') ? $this->buildClearButton($builder, $builder_id) : [], |
| 34 | ]; |
| 35 | |
| 36 | if (empty(\array_filter($buttons))) { |
| 37 | return []; |
| 38 | } |
| 39 | |
| 40 | return [ |
| 41 | '#type' => 'component', |
| 42 | '#component' => 'display_builder:button_group', |
| 43 | '#slots' => [ |
| 44 | 'buttons' => $buttons, |
| 45 | ], |
| 46 | ]; |
| 47 | } |
| 48 | |
| 49 | /** |
| 50 | * {@inheritdoc} |
| 51 | */ |
| 52 | public function onAttachToRoot(string $builder_id, string $instance_id): array { |
| 53 | return $this->rebuild($builder_id); |
| 54 | } |
| 55 | |
| 56 | /** |
| 57 | * {@inheritdoc} |
| 58 | */ |
| 59 | public function onAttachToSlot(string $builder_id, string $instance_id, string $parent_id): array { |
| 60 | return $this->rebuild($builder_id); |
| 61 | } |
| 62 | |
| 63 | /** |
| 64 | * {@inheritdoc} |
| 65 | */ |
| 66 | public function onMove(string $builder_id, string $instance_id): array { |
| 67 | return $this->rebuild($builder_id); |
| 68 | } |
| 69 | |
| 70 | /** |
| 71 | * {@inheritdoc} |
| 72 | */ |
| 73 | public function onHistoryChange(string $builder_id): array { |
| 74 | return $this->rebuild($builder_id); |
| 75 | } |
| 76 | |
| 77 | /** |
| 78 | * {@inheritdoc} |
| 79 | */ |
| 80 | public function onUpdate(string $builder_id, string $instance_id): array { |
| 81 | return $this->rebuild($builder_id); |
| 82 | } |
| 83 | |
| 84 | /** |
| 85 | * {@inheritdoc} |
| 86 | */ |
| 87 | public function onDelete(string $builder_id, string $parent_id): array { |
| 88 | return $this->rebuild($builder_id); |
| 89 | } |
| 90 | |
| 91 | /** |
| 92 | * {@inheritdoc} |
| 93 | */ |
| 94 | protected function hasButtons(): array { |
| 95 | return [ |
| 96 | 'undo' => [ |
| 97 | 'title' => $this->t('Undo'), |
| 98 | 'description' => $this->t('Undo action, icon is always visible, label is number of undo.'), |
| 99 | 'default' => 'icon_label', |
| 100 | 'remove' => 'icon', |
| 101 | ], |
| 102 | 'redo' => [ |
| 103 | 'title' => $this->t('Redo'), |
| 104 | 'description' => $this->t('Redo action, icon is always visible, label is number of redo.'), |
| 105 | 'default' => 'icon_label', |
| 106 | 'remove' => 'icon', |
| 107 | ], |
| 108 | 'clear' => [ |
| 109 | 'title' => $this->t('Clear'), |
| 110 | 'description' => $this->t('A button to clear the logs history (past and future).'), |
| 111 | 'default' => 'hidden', |
| 112 | 'remove' => 'icon', |
| 113 | ], |
| 114 | ]; |
| 115 | } |
| 116 | |
| 117 | /** |
| 118 | * Rebuilds the island with the given builder ID. |
| 119 | * |
| 120 | * @param string $builder_id |
| 121 | * The ID of the builder. |
| 122 | * |
| 123 | * @return array |
| 124 | * The rebuilt island. |
| 125 | */ |
| 126 | private function rebuild(string $builder_id): array { |
| 127 | if (!$this->builder) { |
| 128 | // @todo pass \Drupal\display_builder\InstanceInterface object in |
| 129 | // parameters instead of loading again. |
| 130 | /** @var \Drupal\display_builder\InstanceInterface $builder */ |
| 131 | $builder = $this->entityTypeManager->getStorage('display_builder_instance')->load($builder_id); |
| 132 | $this->builder = $builder; |
| 133 | } |
| 134 | |
| 135 | return $this->addOutOfBand( |
| 136 | $this->build($this->builder), |
| 137 | '#' . $this->getHtmlId($builder_id), |
| 138 | 'innerHTML' |
| 139 | ); |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * Builds the undo button. |
| 144 | * |
| 145 | * @param \Drupal\display_builder\InstanceInterface $builder |
| 146 | * The builder instance. |
| 147 | * @param string $builder_id |
| 148 | * The builder ID. |
| 149 | * |
| 150 | * @return array |
| 151 | * The undo button render array. |
| 152 | */ |
| 153 | private function buildUndoButton(InstanceInterface $builder, string $builder_id): array { |
| 154 | $past = $builder->getCountPast(); |
| 155 | $undo = $this->buildButton( |
| 156 | ($this->showLabel('undo') && $past) ? (string) $past : '', |
| 157 | 'undo', |
| 158 | 'arrow-counterclockwise', |
| 159 | $this->t('Undo (shortcut: u)'), |
| 160 | ['u' => $this->t('Undo last change')] |
| 161 | ); |
| 162 | |
| 163 | if (empty($past)) { |
| 164 | $undo['#attributes']['disabled'] = 'disabled'; |
| 165 | } |
| 166 | |
| 167 | return $this->htmxEvents->onUndo($undo, $builder_id); |
| 168 | } |
| 169 | |
| 170 | /** |
| 171 | * Builds the redo button. |
| 172 | * |
| 173 | * @param \Drupal\display_builder\InstanceInterface $builder |
| 174 | * The builder instance. |
| 175 | * @param string $builder_id |
| 176 | * The builder ID. |
| 177 | * |
| 178 | * @return array |
| 179 | * The redo button render array. |
| 180 | */ |
| 181 | private function buildRedoButton(InstanceInterface $builder, string $builder_id): array { |
| 182 | $future = $builder->getCountFuture(); |
| 183 | $redo = $this->buildButton( |
| 184 | ($this->showLabel('redo') && $future) ? (string) $future : '', |
| 185 | 'redo', |
| 186 | 'arrow-clockwise', |
| 187 | $this->t('Redo (shortcut: r)'), |
| 188 | ['r' => $this->t('Redo last undone change')] |
| 189 | ); |
| 190 | |
| 191 | if (empty($future)) { |
| 192 | $redo['#attributes']['disabled'] = 'disabled'; |
| 193 | } |
| 194 | |
| 195 | return $this->htmxEvents->onRedo($redo, $builder_id); |
| 196 | } |
| 197 | |
| 198 | /** |
| 199 | * Builds the clear button. |
| 200 | * |
| 201 | * @param \Drupal\display_builder\InstanceInterface $builder |
| 202 | * The builder instance. |
| 203 | * @param string $builder_id |
| 204 | * The builder ID. |
| 205 | * |
| 206 | * @return array |
| 207 | * The clear button render array. |
| 208 | */ |
| 209 | private function buildClearButton(InstanceInterface $builder, string $builder_id): array { |
| 210 | $past = $builder->getCountPast(); |
| 211 | $future = $builder->getCountFuture(); |
| 212 | $clear = $this->buildButton( |
| 213 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 214 | 'clear', |
| 215 | $this->showIcon('clear') ? 'clock-history' : '', |
| 216 | $this->t('Clear history (shortcut: C)'), |
| 217 | ['C' => $this->t('Clear all changes history')] |
| 218 | ); |
| 219 | $clear['#props']['variant'] = 'warning'; |
| 220 | $clear['#attributes']['outline'] = TRUE; |
| 221 | |
| 222 | if (empty($past) && empty($future)) { |
| 223 | $clear['#attributes']['class'] = ['hidden']; |
| 224 | } |
| 225 | |
| 226 | return $this->htmxEvents->onClear($clear, $builder_id); |
| 227 | } |
| 228 | |
| 229 | } |
Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not
necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once.
Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement
always has an else as part of its logical flow even if you didn't write one.
| 28 | public function build(InstanceInterface $builder, array $data = [], array $options = []): array { |
| 29 | $builder_id = (string) $builder->id(); |
| 30 | $buttons = [ |
| 31 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 31 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 31 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 31 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 32 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 32 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 31 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 31 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 32 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 33 | $this->isButtonEnabled('clear') ? $this->buildClearButton($builder, $builder_id) : [], |
| 33 | $this->isButtonEnabled('clear') ? $this->buildClearButton($builder, $builder_id) : [], |
| 31 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 31 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 32 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 33 | $this->isButtonEnabled('clear') ? $this->buildClearButton($builder, $builder_id) : [], |
| 34 | ]; |
| 35 | |
| 36 | if (empty(\array_filter($buttons))) { |
| 37 | return []; |
| 41 | '#type' => 'component', |
| 42 | '#component' => 'display_builder:button_group', |
| 43 | '#slots' => [ |
| 44 | 'buttons' => $buttons, |
| 209 | private function buildClearButton(InstanceInterface $builder, string $builder_id): array { |
| 210 | $past = $builder->getCountPast(); |
| 211 | $future = $builder->getCountFuture(); |
| 212 | $clear = $this->buildButton( |
| 213 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 213 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 213 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 213 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 214 | 'clear', |
| 215 | $this->showIcon('clear') ? 'clock-history' : '', |
| 215 | $this->showIcon('clear') ? 'clock-history' : '', |
| 215 | $this->showIcon('clear') ? 'clock-history' : '', |
| 215 | $this->showIcon('clear') ? 'clock-history' : '', |
| 216 | $this->t('Clear history (shortcut: C)'), |
| 217 | ['C' => $this->t('Clear all changes history')] |
| 218 | ); |
| 219 | $clear['#props']['variant'] = 'warning'; |
| 220 | $clear['#attributes']['outline'] = TRUE; |
| 221 | |
| 222 | if (empty($past) && empty($future)) { |
| 222 | if (empty($past) && empty($future)) { |
| 223 | $clear['#attributes']['class'] = ['hidden']; |
| 224 | } |
| 225 | |
| 226 | return $this->htmxEvents->onClear($clear, $builder_id); |
| 226 | return $this->htmxEvents->onClear($clear, $builder_id); |
| 181 | private function buildRedoButton(InstanceInterface $builder, string $builder_id): array { |
| 182 | $future = $builder->getCountFuture(); |
| 183 | $redo = $this->buildButton( |
| 184 | ($this->showLabel('redo') && $future) ? (string) $future : '', |
| 184 | ($this->showLabel('redo') && $future) ? (string) $future : '', |
| 184 | ($this->showLabel('redo') && $future) ? (string) $future : '', |
| 184 | ($this->showLabel('redo') && $future) ? (string) $future : '', |
| 184 | ($this->showLabel('redo') && $future) ? (string) $future : '', |
| 185 | 'redo', |
| 186 | 'arrow-clockwise', |
| 187 | $this->t('Redo (shortcut: r)'), |
| 188 | ['r' => $this->t('Redo last undone change')] |
| 189 | ); |
| 190 | |
| 191 | if (empty($future)) { |
| 192 | $redo['#attributes']['disabled'] = 'disabled'; |
| 193 | } |
| 194 | |
| 195 | return $this->htmxEvents->onRedo($redo, $builder_id); |
| 195 | return $this->htmxEvents->onRedo($redo, $builder_id); |
| 153 | private function buildUndoButton(InstanceInterface $builder, string $builder_id): array { |
| 154 | $past = $builder->getCountPast(); |
| 155 | $undo = $this->buildButton( |
| 156 | ($this->showLabel('undo') && $past) ? (string) $past : '', |
| 156 | ($this->showLabel('undo') && $past) ? (string) $past : '', |
| 156 | ($this->showLabel('undo') && $past) ? (string) $past : '', |
| 156 | ($this->showLabel('undo') && $past) ? (string) $past : '', |
| 156 | ($this->showLabel('undo') && $past) ? (string) $past : '', |
| 157 | 'undo', |
| 158 | 'arrow-counterclockwise', |
| 159 | $this->t('Undo (shortcut: u)'), |
| 160 | ['u' => $this->t('Undo last change')] |
| 161 | ); |
| 162 | |
| 163 | if (empty($past)) { |
| 164 | $undo['#attributes']['disabled'] = 'disabled'; |
| 165 | } |
| 166 | |
| 167 | return $this->htmxEvents->onUndo($undo, $builder_id); |
| 167 | return $this->htmxEvents->onUndo($undo, $builder_id); |
| 97 | 'title' => $this->t('Undo'), |
| 98 | 'description' => $this->t('Undo action, icon is always visible, label is number of undo.'), |
| 99 | 'default' => 'icon_label', |
| 100 | 'remove' => 'icon', |
| 101 | ], |
| 102 | 'redo' => [ |
| 103 | 'title' => $this->t('Redo'), |
| 104 | 'description' => $this->t('Redo action, icon is always visible, label is number of redo.'), |
| 105 | 'default' => 'icon_label', |
| 106 | 'remove' => 'icon', |
| 107 | ], |
| 108 | 'clear' => [ |
| 109 | 'title' => $this->t('Clear'), |
| 110 | 'description' => $this->t('A button to clear the logs history (past and future).'), |
| 111 | 'default' => 'hidden', |
| 112 | 'remove' => 'icon', |
| 52 | public function onAttachToRoot(string $builder_id, string $instance_id): array { |
| 53 | return $this->rebuild($builder_id); |
| 59 | public function onAttachToSlot(string $builder_id, string $instance_id, string $parent_id): array { |
| 60 | return $this->rebuild($builder_id); |
| 87 | public function onDelete(string $builder_id, string $parent_id): array { |
| 88 | return $this->rebuild($builder_id); |
| 73 | public function onHistoryChange(string $builder_id): array { |
| 74 | return $this->rebuild($builder_id); |
| 66 | public function onMove(string $builder_id, string $instance_id): array { |
| 67 | return $this->rebuild($builder_id); |
| 80 | public function onUpdate(string $builder_id, string $instance_id): array { |
| 81 | return $this->rebuild($builder_id); |
| 126 | private function rebuild(string $builder_id): array { |
| 127 | if (!$this->builder) { |
| 131 | $builder = $this->entityTypeManager->getStorage('display_builder_instance')->load($builder_id); |
| 132 | $this->builder = $builder; |
| 133 | } |
| 134 | |
| 135 | return $this->addOutOfBand( |
| 135 | return $this->addOutOfBand( |
| 136 | $this->build($this->builder), |
| 137 | '#' . $this->getHtmlId($builder_id), |
| 138 | 'innerHTML' |