Passed
Push — 8.x-2.x ( 9af07d...3011f1 )
by Frédéric G.
05:35
created

OverviewController::getEventSource()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 23
c 0
b 0
f 0
nc 6
nop 1
dl 0
loc 37
rs 8.9297
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Drupal\mongodb_watchdog\Controller;
6
7
use Drupal\Component\Render\FormattableMarkup;
0 ignored issues
show
Bug introduced by
The type Drupal\Component\Render\FormattableMarkup was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Drupal\Component\Utility\Unicode;
0 ignored issues
show
Bug introduced by
The type Drupal\Component\Utility\Unicode was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Drupal\Core\Config\ImmutableConfig;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Config\ImmutableConfig was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Drupal\Core\Datetime\DateFormatterInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Datetime\DateFormatterInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Drupal\Core\Extension\ModuleHandlerInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Extension\ModuleHandlerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Drupal\Core\Form\FormBuilderInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Form\FormBuilderInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Drupal\Core\Link;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Link was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Drupal\Core\Logger\RfcLogLevel;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Logger\RfcLogLevel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Drupal\Core\Pager\PagerManagerInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Pager\PagerManagerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Drupal\Core\Render\RenderableInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Render\RenderableInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Drupal\mongodb_watchdog\Event;
18
use Drupal\mongodb_watchdog\EventTemplate;
19
use Drupal\mongodb_watchdog\Form\OverviewFilterForm;
20
use Drupal\mongodb_watchdog\Logger;
21
use Psr\Log\LogLevel;
0 ignored issues
show
Bug introduced by
The type Psr\Log\LogLevel was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use Psr\Log\LoggerInterface;
0 ignored issues
show
Bug introduced by
The type Psr\Log\LoggerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use Symfony\Component\DependencyInjection\ContainerInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Depend...tion\ContainerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use Symfony\Component\HttpFoundation\Request;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\HttpFoundation\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
26
/**
27
 * The controller for the logger overview page.
28
 *
29
 * D8 has no session API, so use of $_SESSION is required, so ignore warnings.
30
 *
31
 * @SuppressWarnings("PHPMD.Superglobals")
32
 */
33
class OverviewController extends ControllerBase {
34
  const EVENT_TYPE_MAP = [
35
    'typeMap' => [
36
      'array' => 'array',
37
      'document' => 'array',
38
      'root' => 'Drupal\mongodb_watchdog\Event',
39
    ],
40
  ];
41
  const SEVERITY_PREFIX = 'mongodb-watchdog__severity--';
42
  const SEVERITY_CLASSES = [
43
    RfcLogLevel::DEBUG => self::SEVERITY_PREFIX . LogLevel::DEBUG,
44
    RfcLogLevel::INFO => self::SEVERITY_PREFIX . LogLevel::INFO,
45
    RfcLogLevel::NOTICE => self::SEVERITY_PREFIX . LogLevel::NOTICE,
46
    RfcLogLevel::WARNING => self::SEVERITY_PREFIX . LogLevel::WARNING,
47
    RfcLogLevel::ERROR => self::SEVERITY_PREFIX . LogLevel::ERROR,
48
    RfcLogLevel::CRITICAL => self::SEVERITY_PREFIX . LogLevel::CRITICAL,
49
    RfcLogLevel::ALERT => self::SEVERITY_PREFIX . LogLevel::ALERT,
50
    RfcLogLevel::EMERGENCY => self::SEVERITY_PREFIX . LogLevel::EMERGENCY,
51
  ];
52
53
  /**
54
   * The core date.formatter service.
55
   *
56
   * @var \Drupal\Core\Datetime\DateFormatterInterface
57
   */
58
  protected $dateFormatter;
59
60
  /**
61
   * The form builder service.
62
   *
63
   * @var \Drupal\Core\Form\FormBuilderInterface
64
   */
65
  protected $formBuilder;
66
67
  /**
68
   * The module handler service.
69
   *
70
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
71
   */
72
  protected $moduleHandler;
73
74
  /**
75
   * The length of the disk path to DRUPAL_ROOT.
76
   *
77
   * @var int
78
   *
79
   * @see \Drupal\mongodb_watchdog\Controller\OverviewController::getEventSource()
80
   */
81
  protected $rootLength;
82
83
  /**
84
   * Controller constructor.
85
   *
86
   * @param \Psr\Log\LoggerInterface $logger
87
   *   The logger service, to log intervening events.
88
   * @param \Drupal\mongodb_watchdog\Logger $watchdog
89
   *   The MongoDB logger, to load stored events.
90
   * @param \Drupal\Core\Config\ImmutableConfig $config
91
   *   The module configuration.
92
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
93
   *   A module handler.
94
   * @param \Drupal\Core\Form\FormBuilderInterface $formBuilder
95
   *   The form builder service.
96
   * @param \Drupal\Core\Datetime\DateFormatterInterface $dateFormatter
97
   *   The core date_formatter service.
98
   * @param \Drupal\Core\Pager\PagerManagerInterface $pagerManager
99
   *   The core pager.manager service.
100
   */
101
  public function __construct(
102
    LoggerInterface $logger,
103
    Logger $watchdog,
104
    ImmutableConfig $config,
105
    ModuleHandlerInterface $moduleHandler,
106
    FormBuilderInterface $formBuilder,
107
    DateFormatterInterface $dateFormatter,
108
    PagerManagerInterface $pagerManager) {
109
    parent::__construct($logger, $watchdog, $pagerManager, $config);
110
111
    $this->dateFormatter = $dateFormatter;
112
    $this->formBuilder = $formBuilder;
113
    $this->moduleHandler = $moduleHandler;
114
115
    // Add terminal "/".
116
    $this->rootLength = mb_strlen(DRUPAL_ROOT);
0 ignored issues
show
Bug introduced by
The constant Drupal\mongodb_watchdog\Controller\DRUPAL_ROOT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
117
  }
118
119
  /**
120
   * Controller.
121
   *
122
   * @param \Symfony\Component\HttpFoundation\Request $request
123
   *   The current request.
124
   *
125
   * @return array
126
   *   A render array.
127
   *
128
   * @throws \ReflectionException
129
   */
130
  public function build(Request $request): array {
131
    $top = $this->getTop();
132
133
    $rows = $this->getRowData($request);
134
    $main = empty($rows)
135
      ? $this->buildEmpty($this->t('No event found in logger.'))
136
      : $this->buildMainTable($rows);
137
138
    $ret = $this->buildDefaults($main, $top);
139
    return $ret;
140
  }
141
142
  /**
143
   * Build the main table.
144
   *
145
   * @param \Drupal\mongodb_watchdog\EventTemplate[] $rows
146
   *   The template data.
147
   *
148
   * @return array
149
   *   A render array for the main table.
150
   */
151
  protected function buildMainTable(array $rows): array {
152
    $ret = [
153
      '#header' => $this->buildMainTableHeader(),
154
      '#rows' => $this->buildMainTableRows($rows),
155
      '#type' => 'table',
156
    ];
157
158
    return $ret;
159
  }
160
161
  /**
162
   * Build the main table header.
163
   *
164
   * @return \Drupal\Core\StringTranslation\TranslatableMarkup[]
165
   *   A table header array.
166
   */
167
  protected function buildMainTableHeader(): array {
168
    $header = [
169
      $this->t('#'),
170
      $this->t('Latest'),
171
      $this->t('Severity'),
172
      $this->t('Type'),
173
      $this->t('Message'),
174
      $this->t('Source'),
175
    ];
176
177
    return $header;
178
  }
179
180
  /**
181
   * Build the main table rows.
182
   *
183
   * @param \Drupal\mongodb_watchdog\EventTemplate[] $templates
184
   *   The event template data.
185
   *
186
   * @return array
187
   *   A render array for a table.
188
   */
189
  protected function buildMainTableRows(array $templates): array {
190
    $rows = [];
191
    $levels = RfcLogLevel::getLevels();
192
193
    foreach ($templates as $template) {
194
      $row = [];
195
      $row[] = $template->count;
196
      $row[] = $this->dateFormatter->format($template->changed, 'short');
197
      $row[] = [
198
        'class' => static::SEVERITY_CLASSES[$template->severity],
199
        'data' => $levels[$template->severity],
200
      ];
201
      $row[] = $template->type;
202
      $row[] = $this->getEventLink($template);
203
      $row[] = [
204
        'data' => $this->getEventSource($template),
205
      ];
206
207
      $rows[] = $row;
208
    }
209
210
    return $rows;
211
  }
212
213
  /**
214
   * {@inheritdoc}
215
   */
216
  public static function create(ContainerInterface $container): self {
217
    /** @var \Psr\Log\LoggerInterface $logger */
218
    $logger = $container->get('logger.channel.mongodb_watchdog');
219
220
    /** @var \Drupal\mongodb_watchdog\Logger $watchdog */
221
    $watchdog = $container->get(Logger::SERVICE_LOGGER);
222
223
    /** @var \Drupal\Core\Config\ImmutableConfig $config */
224
    $config = $container->get('config.factory')->get('mongodb_watchdog.settings');
225
226
    /** @var \Drupal\Core\Datetime\DateFormatterInterface $dateFormatter */
227
    $dateFormatter = $container->get('date.formatter');
228
229
    /** @var \Drupal\Core\Form\FormBuilderInterface $formBuilder */
230
    $formBuilder = $container->get('form_builder');
231
232
    /** @var \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler */
233
    $moduleHandler = $container->get('module_handler');
234
235
    /** @var \Drupal\Core\Pager\PagerManagerInterface $pagerManager */
236
    $pagerManager = $container->get('pager.manager');
237
238
    return new static($logger, $watchdog, $config, $moduleHandler, $formBuilder, $dateFormatter, $pagerManager);
239
  }
240
241
  /**
242
   * Build the link to the event or top report for the event template.
243
   *
244
   * @param \Drupal\mongodb_watchdog\EventTemplate $template
245
   *   The event template for which to buildl the link.
246
   *
247
   * @return \Drupal\Core\Render\RenderableInterface
248
   *   An internal link in renderable form.
249
   */
250
  protected function getEventLink(EventTemplate $template): RenderableInterface {
251
    switch ($template->type) {
252
      case 'page not found':
253
        $cell = Link::createFromRoute($this->t('( Top 404 )'), 'mongodb_watchdog.reports.top404');
254
        break;
255
256
      case 'access denied':
257
        $cell = Link::createFromRoute($this->t('( Top 403 )'), 'mongodb_watchdog.reports.top403');
258
        break;
259
260
      // Limited-length message.
261
      default:
262
        $markup = new FormattableMarkup($template->message, []);
263
        $message = Unicode::truncate(strip_tags($markup->__toString()),
264
          56, TRUE, TRUE);
265
        $cell = Link::createFromRoute($message, 'mongodb_watchdog.reports.detail', [
266
          'eventTemplate' => $template->_id,
267
        ]);
268
        break;
269
    }
270
271
    return $cell;
272
  }
273
274
  /**
275
   * Get the location in source code where the event was logged.
276
   *
277
   * @param \Drupal\mongodb_watchdog\EventTemplate $template
278
   *   The template for which to find a source location.
279
   *
280
   * @return array
281
   *   A render array for the source location, possibly empty or wrong.
282
   */
283
  protected function getEventSource(EventTemplate $template): array {
284
    $cell = ['#markup' => ''];
285
286
    if (in_array($template->type, TopController::TYPES)) {
287
      return $cell;
288
    }
289
290
    $eventCollection = $this->watchdog->eventCollection($template->_id);
291
    $event = $eventCollection->findOne([], static::EVENT_TYPE_MAP);
292
    if (!($event instanceof Event)) {
293
      return $cell;
294
    }
295
296
    $file = $event->variables['%file'] ?? '';
297
    if ($file && strncmp($file, DRUPAL_ROOT, $this->rootLength) === 0) {
0 ignored issues
show
Bug introduced by
The constant Drupal\mongodb_watchdog\Controller\DRUPAL_ROOT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
298
      $hover = mb_substr($file, $this->rootLength + 1);
299
      $file = Unicode::truncate(basename($file), 30);
300
    }
301
    else {
302
      $hover = '';
303
    }
304
305
    $line = $event->variables['%line'] ?? '';
306
    $cell = [
307
      '#type' => 'html_tag',
308
      '#tag' => 'span',
309
      '#value' => implode("#", [$file, $line]),
310
    ];
311
312
    if ($hover !== '') {
313
      $cell['#attributes'] = [
314
        'class' => 'mongodb-watchdog__code-path',
315
        'title' => $hover,
316
      ];
317
    }
318
319
    return $cell;
320
  }
321
322
  /**
323
   * Obtain the data from the logger.
324
   *
325
   * @param \Symfony\Component\HttpFoundation\Request $request
326
   *   The current request. Needed for paging.
327
   *
328
   * @return \Drupal\mongodb_watchdog\EventTemplate
329
   *   The data array.
330
   *
331
   * @throws \ReflectionException
332
   */
333
  protected function getRowData(Request $request): array {
334
    $count = $this->watchdog->templatesCount();
335
    $page = $this->setupPager($request, $count);
336
    $skip = $page * $this->itemsPerPage;
337
    $limit = $this->itemsPerPage;
338
339
    $filters = $_SESSION[OverviewFilterForm::SESSION_KEY] ?? NULL;
340
341
    $rows = $this->watchdog
342
      ->templates($filters['type'] ?? [], $filters['severity'] ?? [], $skip, $limit)
343
      ->toArray();
344
345
    return $rows;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $rows returns the type array which is incompatible with the documented return type Drupal\mongodb_watchdog\EventTemplate.
Loading history...
346
  }
347
348
  /**
349
   * Return the top element.
350
   *
351
   * @return array
352
   *   A render array for the top filter form.
353
   */
354
  protected function getTop(): array {
355
    $top = $this->formBuilder->getForm('Drupal\mongodb_watchdog\Form\OverviewFilterForm');
356
    return $top;
357
  }
358
359
}
360