Code Coverage |
||||||||||||||||
Lines |
Branches |
Paths |
Functions and Methods |
Classes and Traits |
||||||||||||
| Total | |
0.00% |
0 / 63 |
|
0.00% |
0 / 29 |
|
0.00% |
0 / 26 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
| LogsPanel | |
0.00% |
0 / 56 |
|
0.00% |
0 / 29 |
|
0.00% |
0 / 26 |
|
0.00% |
0 / 7 |
240 | |
0.00% |
0 / 1 |
| create | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| keyboardShortcuts | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| build | |
0.00% |
0 / 16 |
|
0.00% |
0 / 4 |
|
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
| onPublish | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| buildRows | |
0.00% |
0 / 8 |
|
0.00% |
0 / 7 |
|
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
| buildRow | |
0.00% |
0 / 12 |
|
0.00% |
0 / 9 |
|
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 | |||
| printSaveAlert | |
0.00% |
0 / 12 |
|
0.00% |
0 / 6 |
|
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Drupal\display_builder\Plugin\display_builder\Island; |
| 6 | |
| 7 | use Drupal\Core\Datetime\DateFormatterInterface; |
| 8 | use Drupal\Core\StringTranslation\TranslatableMarkup; |
| 9 | use Drupal\display_builder\Attribute\Island; |
| 10 | use Drupal\display_builder\DisplayBuilderHelpers; |
| 11 | use Drupal\display_builder\InstanceInterface; |
| 12 | use Drupal\display_builder\Island\IslandPluginBase; |
| 13 | use Drupal\display_builder\Island\IslandReloadEventsTrait; |
| 14 | use Drupal\display_builder\Island\IslandType; |
| 15 | use Symfony\Component\DependencyInjection\ContainerInterface; |
| 16 | |
| 17 | /** |
| 18 | * Logs island plugin implementation. |
| 19 | */ |
| 20 | #[Island( |
| 21 | id: 'logs', |
| 22 | label: new TranslatableMarkup('Logs'), |
| 23 | description: new TranslatableMarkup('Logs based on changes history.'), |
| 24 | type: IslandType::View, |
| 25 | default_region: 'main', |
| 26 | icon: 'list-columns-reverse', |
| 27 | )] |
| 28 | class LogsPanel extends IslandPluginBase { |
| 29 | |
| 30 | use IslandReloadEventsTrait; |
| 31 | |
| 32 | /** |
| 33 | * The date formatter. |
| 34 | */ |
| 35 | protected DateFormatterInterface $dateFormatter; |
| 36 | |
| 37 | /** |
| 38 | * {@inheritdoc} |
| 39 | */ |
| 40 | public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static { |
| 41 | $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); |
| 42 | $instance->dateFormatter = $container->get('date.formatter'); |
| 43 | |
| 44 | return $instance; |
| 45 | } |
| 46 | |
| 47 | /** |
| 48 | * {@inheritdoc} |
| 49 | */ |
| 50 | public static function keyboardShortcuts(): array { |
| 51 | return [ |
| 52 | 'key' => 'o', |
| 53 | 'help' => t('Show the logs'), |
| 54 | ]; |
| 55 | } |
| 56 | |
| 57 | /** |
| 58 | * {@inheritdoc} |
| 59 | */ |
| 60 | public function build(InstanceInterface $builder, array $data = [], array $options = []): array { |
| 61 | $published_hash = $builder->getPublishedHash(); |
| 62 | |
| 63 | $table = [ |
| 64 | '#theme' => 'table', |
| 65 | '#header' => [ |
| 66 | ['data' => $this->t('Step')], |
| 67 | ['data' => $this->t('Published')], |
| 68 | ['data' => $this->t('Time')], |
| 69 | ['data' => $this->t('User')], |
| 70 | ['data' => $this->t('Message')], |
| 71 | ], |
| 72 | '#rows' => $this->buildRows($builder, $published_hash), |
| 73 | ]; |
| 74 | |
| 75 | return [ |
| 76 | $table, |
| 77 | $published_hash ? $this->printSaveAlert($builder) : [], |
| 78 | ]; |
| 79 | } |
| 80 | |
| 81 | /** |
| 82 | * {@inheritdoc} |
| 83 | */ |
| 84 | public function onPublish(InstanceInterface $instance): array { |
| 85 | return $this->reloadWithGlobalData($instance); |
| 86 | } |
| 87 | |
| 88 | /** |
| 89 | * Build rows for the logs table. |
| 90 | * |
| 91 | * @param \Drupal\display_builder\InstanceInterface $builder |
| 92 | * The instance entity. |
| 93 | * @param ?int $published_hash |
| 94 | * The hash of the published content, if any. |
| 95 | * |
| 96 | * @return array |
| 97 | * A renderable array representing a table row. |
| 98 | */ |
| 99 | protected function buildRows(InstanceInterface $builder, ?int $published_hash): array { |
| 100 | $rows = []; |
| 101 | // Reindex the array numerically so 0 will always be the 'present' (the |
| 102 | // default revision). |
| 103 | $past = \array_values($builder->getPast()); |
| 104 | |
| 105 | foreach ($past as $index => $step) { |
| 106 | /** @var \Drupal\display_builder\InstanceInterface $step */ |
| 107 | $rows[] = $this->buildRow(-\count($past) + $index, $step, $published_hash); |
| 108 | } |
| 109 | |
| 110 | // Present data. |
| 111 | $rows[] = $this->buildRow(0, $builder, $published_hash); |
| 112 | |
| 113 | // Reindex the array numerically so 0 will always be the 'present' (the |
| 114 | // default revision). |
| 115 | foreach (\array_values($builder->getFuture()) as $index => $step) { |
| 116 | /** @var \Drupal\display_builder\InstanceInterface $step */ |
| 117 | $rows[] = $this->buildRow($index + 1, $step, $published_hash); |
| 118 | } |
| 119 | |
| 120 | return $rows; |
| 121 | } |
| 122 | |
| 123 | /** |
| 124 | * Build a single row for the logs table. |
| 125 | * |
| 126 | * @param int $index |
| 127 | * The row index. |
| 128 | * @param \Drupal\display_builder\InstanceInterface $step |
| 129 | * The step data containing time and log message. |
| 130 | * @param ?int $published_hash |
| 131 | * The hash of the published content, if any. |
| 132 | * |
| 133 | * @return array |
| 134 | * A renderable array representing a table row. |
| 135 | */ |
| 136 | private function buildRow(int $index, InstanceInterface $step, ?int $published_hash): array { |
| 137 | $hash = $step->getHash(); |
| 138 | |
| 139 | return [ |
| 140 | 'hash' => $hash, |
| 141 | 'data' => [ |
| 142 | (string) $index, |
| 143 | $published_hash && ($hash === $published_hash) ? '✅' : '', |
| 144 | DisplayBuilderHelpers::formatTime($this->dateFormatter, (int) $step->getRevisionCreationTime()), |
| 145 | $step->getRevisionUser()?->getDisplayName(), |
| 146 | $step->getRevisionLogMessage(), |
| 147 | ], |
| 148 | 'style' => ($index === 0) ? 'font-weight: bold;' : '', |
| 149 | ]; |
| 150 | } |
| 151 | |
| 152 | /** |
| 153 | * Print an alert if the saved step is not in the history. |
| 154 | * |
| 155 | * @param \Drupal\display_builder\InstanceInterface $builder |
| 156 | * The instance entity. |
| 157 | * |
| 158 | * @return array |
| 159 | * A renderable array. |
| 160 | */ |
| 161 | private function printSaveAlert(InstanceInterface $builder): array { |
| 162 | $steps = \array_merge($builder->getPast(), [$builder], $builder->getFuture()); |
| 163 | |
| 164 | foreach ($steps as $step) { |
| 165 | /** @var \Drupal\display_builder\InstanceInterface $step */ |
| 166 | if ($step->isPublishedPresent()) { |
| 167 | return []; |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | $params = [ |
| 172 | '%time' => DisplayBuilderHelpers::formatTime($this->dateFormatter, (int) $builder->getPublishedTime()), |
| 173 | ]; |
| 174 | |
| 175 | return [ |
| 176 | '#type' => 'html_tag', |
| 177 | '#tag' => 'p', |
| 178 | '#value' => $this->t('Published at %time but not visible in logs', $params), |
| 179 | ]; |
| 180 | } |
| 181 | |
| 182 | } |
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.
| 60 | public function build(InstanceInterface $builder, array $data = [], array $options = []): array { |
| 61 | $published_hash = $builder->getPublishedHash(); |
| 62 | |
| 63 | $table = [ |
| 64 | '#theme' => 'table', |
| 65 | '#header' => [ |
| 66 | ['data' => $this->t('Step')], |
| 67 | ['data' => $this->t('Published')], |
| 68 | ['data' => $this->t('Time')], |
| 69 | ['data' => $this->t('User')], |
| 70 | ['data' => $this->t('Message')], |
| 71 | ], |
| 72 | '#rows' => $this->buildRows($builder, $published_hash), |
| 73 | ]; |
| 74 | |
| 75 | return [ |
| 76 | $table, |
| 77 | $published_hash ? $this->printSaveAlert($builder) : [], |
| 77 | $published_hash ? $this->printSaveAlert($builder) : [], |
| 76 | $table, |
| 76 | $table, |
| 77 | $published_hash ? $this->printSaveAlert($builder) : [], |
| 78 | ]; |
| 79 | } |
| 136 | private function buildRow(int $index, InstanceInterface $step, ?int $published_hash): array { |
| 137 | $hash = $step->getHash(); |
| 138 | |
| 139 | return [ |
| 140 | 'hash' => $hash, |
| 141 | 'data' => [ |
| 142 | (string) $index, |
| 143 | $published_hash && ($hash === $published_hash) ? '✅' : '', |
| 143 | $published_hash && ($hash === $published_hash) ? '✅' : '', |
| 143 | $published_hash && ($hash === $published_hash) ? '✅' : '', |
| 143 | $published_hash && ($hash === $published_hash) ? '✅' : '', |
| 143 | $published_hash && ($hash === $published_hash) ? '✅' : '', |
| 143 | $published_hash && ($hash === $published_hash) ? '✅' : '', |
| 144 | DisplayBuilderHelpers::formatTime($this->dateFormatter, (int) $step->getRevisionCreationTime()), |
| 145 | $step->getRevisionUser()?->getDisplayName(), |
| 146 | $step->getRevisionLogMessage(), |
| 147 | ], |
| 148 | 'style' => ($index === 0) ? 'font-weight: bold;' : '', |
| 148 | 'style' => ($index === 0) ? 'font-weight: bold;' : '', |
| 148 | 'style' => ($index === 0) ? 'font-weight: bold;' : '', |
| 148 | 'style' => ($index === 0) ? 'font-weight: bold;' : '', |
| 149 | ]; |
| 150 | } |
| 99 | protected function buildRows(InstanceInterface $builder, ?int $published_hash): array { |
| 100 | $rows = []; |
| 101 | // Reindex the array numerically so 0 will always be the 'present' (the |
| 102 | // default revision). |
| 103 | $past = \array_values($builder->getPast()); |
| 104 | |
| 105 | foreach ($past as $index => $step) { |
| 105 | foreach ($past as $index => $step) { |
| 105 | foreach ($past as $index => $step) { |
| 105 | foreach ($past as $index => $step) { |
| 106 | /** @var \Drupal\display_builder\InstanceInterface $step */ |
| 107 | $rows[] = $this->buildRow(-\count($past) + $index, $step, $published_hash); |
| 108 | } |
| 109 | |
| 110 | // Present data. |
| 111 | $rows[] = $this->buildRow(0, $builder, $published_hash); |
| 112 | |
| 113 | // Reindex the array numerically so 0 will always be the 'present' (the |
| 114 | // default revision). |
| 115 | foreach (\array_values($builder->getFuture()) as $index => $step) { |
| 115 | foreach (\array_values($builder->getFuture()) as $index => $step) { |
| 115 | foreach (\array_values($builder->getFuture()) as $index => $step) { |
| 115 | foreach (\array_values($builder->getFuture()) as $index => $step) { |
| 116 | /** @var \Drupal\display_builder\InstanceInterface $step */ |
| 117 | $rows[] = $this->buildRow($index + 1, $step, $published_hash); |
| 118 | } |
| 119 | |
| 120 | return $rows; |
| 121 | } |
| 40 | public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static { |
| 41 | $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); |
| 42 | $instance->dateFormatter = $container->get('date.formatter'); |
| 43 | |
| 44 | return $instance; |
| 45 | } |
| 52 | 'key' => 'o', |
| 53 | 'help' => t('Show the logs'), |
| 54 | ]; |
| 55 | } |
| 84 | public function onPublish(InstanceInterface $instance): array { |
| 85 | return $this->reloadWithGlobalData($instance); |
| 86 | } |
| 161 | private function printSaveAlert(InstanceInterface $builder): array { |
| 162 | $steps = \array_merge($builder->getPast(), [$builder], $builder->getFuture()); |
| 163 | |
| 164 | foreach ($steps as $step) { |
| 164 | foreach ($steps as $step) { |
| 166 | if ($step->isPublishedPresent()) { |
| 167 | return []; |
| 164 | foreach ($steps as $step) { |
| 164 | foreach ($steps as $step) { |
| 165 | /** @var \Drupal\display_builder\InstanceInterface $step */ |
| 166 | if ($step->isPublishedPresent()) { |
| 167 | return []; |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | $params = [ |
| 172 | '%time' => DisplayBuilderHelpers::formatTime($this->dateFormatter, (int) $builder->getPublishedTime()), |
| 173 | ]; |
| 174 | |
| 175 | return [ |
| 176 | '#type' => 'html_tag', |
| 177 | '#tag' => 'p', |
| 178 | '#value' => $this->t('Published at %time but not visible in logs', $params), |
| 179 | ]; |
| 180 | } |