Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
0.00% |
0 / 73 |
|
0.00% |
0 / 40 |
|
0.00% |
0 / 49 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
| HistoryButtons | |
0.00% |
0 / 66 |
|
0.00% |
0 / 40 |
|
0.00% |
0 / 49 |
|
0.00% |
0 / 5 |
380 | |
0.00% |
0 / 1 |
| build | |
0.00% |
0 / 15 |
|
0.00% |
0 / 12 |
|
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
30 | |||
| hasButtons | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| buildUndoButton | |
0.00% |
0 / 11 |
|
0.00% |
0 / 8 |
|
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 | |||
| buildRedoButton | |
0.00% |
0 / 11 |
|
0.00% |
0 / 8 |
|
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 | |||
| buildClearButton | |
0.00% |
0 / 12 |
|
0.00% |
0 / 11 |
|
0.00% |
0 / 16 |
|
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\Island\IslandPluginToolbarButtonConfigurationBase; |
| 11 | use Drupal\display_builder\Island\IslandReloadEventsTrait; |
| 12 | use Drupal\display_builder\Island\IslandType; |
| 13 | |
| 14 | /** |
| 15 | * History buttons island plugin implementation. |
| 16 | */ |
| 17 | #[Island( |
| 18 | id: 'history', |
| 19 | enabled_by_default: TRUE, |
| 20 | label: new TranslatableMarkup('History'), |
| 21 | description: new TranslatableMarkup('Undo and redo changes.'), |
| 22 | type: IslandType::Button, |
| 23 | default_region: 'end', |
| 24 | )] |
| 25 | class HistoryButtons extends IslandPluginToolbarButtonConfigurationBase { |
| 26 | |
| 27 | use IslandReloadEventsTrait; |
| 28 | |
| 29 | /** |
| 30 | * {@inheritdoc} |
| 31 | */ |
| 32 | public function build(InstanceInterface $builder, array $data = [], array $options = []): array { |
| 33 | $builder_id = (string) $builder->id(); |
| 34 | $buttons = [ |
| 35 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 36 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 37 | $this->isButtonEnabled('clear') ? $this->buildClearButton($builder, $builder_id) : [], |
| 38 | ]; |
| 39 | |
| 40 | if (empty(\array_filter($buttons))) { |
| 41 | return []; |
| 42 | } |
| 43 | |
| 44 | return [ |
| 45 | '#type' => 'component', |
| 46 | '#component' => 'display_builder:button_group', |
| 47 | '#slots' => [ |
| 48 | 'buttons' => $buttons, |
| 49 | ], |
| 50 | ]; |
| 51 | } |
| 52 | |
| 53 | /** |
| 54 | * {@inheritdoc} |
| 55 | */ |
| 56 | protected function hasButtons(): array { |
| 57 | return [ |
| 58 | 'undo' => [ |
| 59 | 'title' => $this->t('Undo'), |
| 60 | 'description' => $this->t('Undo action, icon is always visible, label is number of undo.'), |
| 61 | 'default' => 'icon_label', |
| 62 | ], |
| 63 | 'redo' => [ |
| 64 | 'title' => $this->t('Redo'), |
| 65 | 'description' => $this->t('Redo action, icon is always visible, label is number of redo.'), |
| 66 | 'default' => 'icon_label', |
| 67 | ], |
| 68 | 'clear' => [ |
| 69 | 'title' => $this->t('Clear'), |
| 70 | 'description' => $this->t('A button to clear the logs history (past and future).'), |
| 71 | 'default' => 'hidden', |
| 72 | ], |
| 73 | ]; |
| 74 | } |
| 75 | |
| 76 | /** |
| 77 | * Builds the undo button. |
| 78 | * |
| 79 | * @param \Drupal\display_builder\InstanceInterface $instance |
| 80 | * The builder instance. |
| 81 | * @param string $builder_id |
| 82 | * The builder ID. |
| 83 | * |
| 84 | * @return array |
| 85 | * The undo button render array. |
| 86 | */ |
| 87 | private function buildUndoButton(InstanceInterface $instance, string $builder_id): array { |
| 88 | $past = $instance->getPast(); |
| 89 | $undo = $this->buildButton( |
| 90 | ($this->showLabel('undo') && $past) ? (string) \count($past) : '', |
| 91 | 'undo', |
| 92 | 'arrow-counterclockwise', |
| 93 | $this->t('Undo (shortcut: u)'), |
| 94 | ['u' => $this->t('Undo last change')] |
| 95 | ); |
| 96 | |
| 97 | if (empty($past)) { |
| 98 | $undo['#attributes']['disabled'] = 'disabled'; |
| 99 | } |
| 100 | |
| 101 | return $this->htmxEvents->onUndo($undo, $builder_id); |
| 102 | } |
| 103 | |
| 104 | /** |
| 105 | * Builds the redo button. |
| 106 | * |
| 107 | * @param \Drupal\display_builder\InstanceInterface $builder |
| 108 | * The builder instance. |
| 109 | * @param string $builder_id |
| 110 | * The builder ID. |
| 111 | * |
| 112 | * @return array |
| 113 | * The redo button render array. |
| 114 | */ |
| 115 | private function buildRedoButton(InstanceInterface $builder, string $builder_id): array { |
| 116 | $future = $builder->getFuture(); |
| 117 | $redo = $this->buildButton( |
| 118 | ($this->showLabel('redo') && $future) ? (string) \count($future) : '', |
| 119 | 'redo', |
| 120 | 'arrow-clockwise', |
| 121 | $this->t('Redo (shortcut: r)'), |
| 122 | ['r' => $this->t('Redo last undone change')] |
| 123 | ); |
| 124 | |
| 125 | if (empty($future)) { |
| 126 | $redo['#attributes']['disabled'] = 'disabled'; |
| 127 | } |
| 128 | |
| 129 | return $this->htmxEvents->onRedo($redo, $builder_id); |
| 130 | } |
| 131 | |
| 132 | /** |
| 133 | * Builds the clear button. |
| 134 | * |
| 135 | * @param \Drupal\display_builder\InstanceInterface $builder |
| 136 | * The builder instance. |
| 137 | * @param string $builder_id |
| 138 | * The builder ID. |
| 139 | * |
| 140 | * @return array |
| 141 | * The clear button render array. |
| 142 | */ |
| 143 | private function buildClearButton(InstanceInterface $builder, string $builder_id): array { |
| 144 | $clear = $this->buildButton( |
| 145 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 146 | 'clear', |
| 147 | $this->showIcon('clear') ? 'clock-history' : '', |
| 148 | $this->t('Clear history (shortcut: Shift+C)'), |
| 149 | ['C' => $this->t('Clear all changes history (Shift+C)')] |
| 150 | ); |
| 151 | $clear['#props']['variant'] = 'warning'; |
| 152 | $clear['#attributes']['outline'] = TRUE; |
| 153 | |
| 154 | if (empty($builder->getPast()) && empty($builder->getFuture())) { |
| 155 | $clear['#attributes']['class'] = ['hidden']; |
| 156 | } |
| 157 | |
| 158 | return $this->htmxEvents->onClear($clear, $builder_id); |
| 159 | } |
| 160 | |
| 161 | } |
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.
| 32 | public function build(InstanceInterface $builder, array $data = [], array $options = []): array { |
| 33 | $builder_id = (string) $builder->id(); |
| 34 | $buttons = [ |
| 35 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 35 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 35 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 35 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 36 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 36 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 35 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 35 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 36 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 37 | $this->isButtonEnabled('clear') ? $this->buildClearButton($builder, $builder_id) : [], |
| 37 | $this->isButtonEnabled('clear') ? $this->buildClearButton($builder, $builder_id) : [], |
| 35 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 35 | $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder, $builder_id) : [], |
| 36 | $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder, $builder_id) : [], |
| 37 | $this->isButtonEnabled('clear') ? $this->buildClearButton($builder, $builder_id) : [], |
| 38 | ]; |
| 39 | |
| 40 | if (empty(\array_filter($buttons))) { |
| 41 | return []; |
| 45 | '#type' => 'component', |
| 46 | '#component' => 'display_builder:button_group', |
| 47 | '#slots' => [ |
| 48 | 'buttons' => $buttons, |
| 49 | ], |
| 50 | ]; |
| 51 | } |
| 143 | private function buildClearButton(InstanceInterface $builder, string $builder_id): array { |
| 144 | $clear = $this->buildButton( |
| 145 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 145 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 145 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 145 | $this->showLabel('clear') ? $this->t('Clear') : '', |
| 146 | 'clear', |
| 147 | $this->showIcon('clear') ? 'clock-history' : '', |
| 147 | $this->showIcon('clear') ? 'clock-history' : '', |
| 147 | $this->showIcon('clear') ? 'clock-history' : '', |
| 147 | $this->showIcon('clear') ? 'clock-history' : '', |
| 148 | $this->t('Clear history (shortcut: Shift+C)'), |
| 149 | ['C' => $this->t('Clear all changes history (Shift+C)')] |
| 150 | ); |
| 151 | $clear['#props']['variant'] = 'warning'; |
| 152 | $clear['#attributes']['outline'] = TRUE; |
| 153 | |
| 154 | if (empty($builder->getPast()) && empty($builder->getFuture())) { |
| 154 | if (empty($builder->getPast()) && empty($builder->getFuture())) { |
| 154 | if (empty($builder->getPast()) && empty($builder->getFuture())) { |
| 155 | $clear['#attributes']['class'] = ['hidden']; |
| 156 | } |
| 157 | |
| 158 | return $this->htmxEvents->onClear($clear, $builder_id); |
| 158 | return $this->htmxEvents->onClear($clear, $builder_id); |
| 159 | } |
| 115 | private function buildRedoButton(InstanceInterface $builder, string $builder_id): array { |
| 116 | $future = $builder->getFuture(); |
| 117 | $redo = $this->buildButton( |
| 118 | ($this->showLabel('redo') && $future) ? (string) \count($future) : '', |
| 118 | ($this->showLabel('redo') && $future) ? (string) \count($future) : '', |
| 118 | ($this->showLabel('redo') && $future) ? (string) \count($future) : '', |
| 118 | ($this->showLabel('redo') && $future) ? (string) \count($future) : '', |
| 118 | ($this->showLabel('redo') && $future) ? (string) \count($future) : '', |
| 118 | ($this->showLabel('redo') && $future) ? (string) \count($future) : '', |
| 119 | 'redo', |
| 120 | 'arrow-clockwise', |
| 121 | $this->t('Redo (shortcut: r)'), |
| 122 | ['r' => $this->t('Redo last undone change')] |
| 123 | ); |
| 124 | |
| 125 | if (empty($future)) { |
| 126 | $redo['#attributes']['disabled'] = 'disabled'; |
| 127 | } |
| 128 | |
| 129 | return $this->htmxEvents->onRedo($redo, $builder_id); |
| 129 | return $this->htmxEvents->onRedo($redo, $builder_id); |
| 130 | } |
| 87 | private function buildUndoButton(InstanceInterface $instance, string $builder_id): array { |
| 88 | $past = $instance->getPast(); |
| 89 | $undo = $this->buildButton( |
| 90 | ($this->showLabel('undo') && $past) ? (string) \count($past) : '', |
| 90 | ($this->showLabel('undo') && $past) ? (string) \count($past) : '', |
| 90 | ($this->showLabel('undo') && $past) ? (string) \count($past) : '', |
| 90 | ($this->showLabel('undo') && $past) ? (string) \count($past) : '', |
| 90 | ($this->showLabel('undo') && $past) ? (string) \count($past) : '', |
| 90 | ($this->showLabel('undo') && $past) ? (string) \count($past) : '', |
| 91 | 'undo', |
| 92 | 'arrow-counterclockwise', |
| 93 | $this->t('Undo (shortcut: u)'), |
| 94 | ['u' => $this->t('Undo last change')] |
| 95 | ); |
| 96 | |
| 97 | if (empty($past)) { |
| 98 | $undo['#attributes']['disabled'] = 'disabled'; |
| 99 | } |
| 100 | |
| 101 | return $this->htmxEvents->onUndo($undo, $builder_id); |
| 101 | return $this->htmxEvents->onUndo($undo, $builder_id); |
| 102 | } |
| 59 | 'title' => $this->t('Undo'), |
| 60 | 'description' => $this->t('Undo action, icon is always visible, label is number of undo.'), |
| 61 | 'default' => 'icon_label', |
| 62 | ], |
| 63 | 'redo' => [ |
| 64 | 'title' => $this->t('Redo'), |
| 65 | 'description' => $this->t('Redo action, icon is always visible, label is number of redo.'), |
| 66 | 'default' => 'icon_label', |
| 67 | ], |
| 68 | 'clear' => [ |
| 69 | 'title' => $this->t('Clear'), |
| 70 | 'description' => $this->t('A button to clear the logs history (past and future).'), |
| 71 | 'default' => 'hidden', |
| 72 | ], |
| 73 | ]; |
| 74 | } |