Completed
Push — 2761013-watchdog_pager ( 08c90e...bc8aba )
by Frédéric G.
02:49
created

RequestController   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 242
Duplicated Lines 12.4 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 30
loc 242
rs 10
wmc 15
lcom 1
cbo 3

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
B buildTrackRequest() 0 34 4
B buildTrackRows() 0 42 2
A create() 12 12 1
A setupPager() 18 18 3
A simplifyPath() 0 6 2
A track() 0 22 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Drupal\mongodb_watchdog\Controller;
4
5
use Drupal\Component\Utility\Unicode;
6
use Drupal\Core\Datetime\DateFormatterInterface;
7
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
8
use Drupal\Core\Link;
9
use Drupal\Core\Logger\RfcLogLevel;
10
use Drupal\mongodb_watchdog\Logger;
11
use Symfony\Component\DependencyInjection\ContainerInterface;
12
use Symfony\Component\HttpFoundation\Request;
13
14
/**
15
 * Implements the controller for the request events page.
16
 */
17
class RequestController implements ContainerInjectionInterface {
18
19
  /**
20
   * The core date.formatter service.
21
   *
22
   * @var \Drupal\Core\Datetime\DateFormatterInterface
23
   */
24
  protected $dateFormatter;
25
26
  /**
27
   * The items_per_page configuration value.
28
   *
29
   * @var int
30
   */
31
  protected $itemsPerPage;
32
33
  /**
34
   * The length of the absolute path to the site root, in runes.
35
   *
36
   * @var int
37
   */
38
  protected $rootLength;
39
40
  /**
41
   * The mongodb_watchdog logger, to access events.
42
   *
43
   * @var \Drupal\mongodb_watchdog\Logger
44
   */
45
  protected $watchdog;
46
47
  /**
48
   * RequestController constructor.
49
   *
50
   * @param \Drupal\mongodb_watchdog\Logger $watchdog
51
   *   The MongoDB logger service, to load event data.
52
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
53
   *   The core date.formatter service.
54
   * @param int $items_per_page
55
   *   The items_per_page configuration value.
56
   */
57
  public function __construct(Logger $watchdog, DateFormatterInterface $date_formatter, $items_per_page) {
58
    $this->dateFormatter = $date_formatter;
59
    $this->itemsPerPage = $items_per_page;
60
    $this->watchdog = $watchdog;
61
62
    // Add terminal "/".
63
    $this->rootLength = Unicode::strlen(DRUPAL_ROOT) + 1;
64
  }
65
66
  /**
67
   * Build the top part of the page, about the request.
68
   *
69
   * @param string $unique_id
70
   *   The unique request id.
71
   * @param array<\Drupal\mongodb_watchdog\EventTemplate\Drupal\mongodb_watchdog\Event[]> $events
72
   *   A fully loaded array of events and their templates.
73
   *
74
   * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string|array[]>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
75
   *   A render array for a table.
76
   */
77
  public function buildTrackRequest($unique_id, array $events) {
78
    if ($events) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $events of type Drupal\mongodb_watchdog\...godb_watchdog\Event[][] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
79
      $row = array_slice($events, 0, 1);
80
      /** @var \Drupal\mongodb_watchdog\Event $first */
81
      list($template, $first) = reset($row);
0 ignored issues
show
Unused Code introduced by
The assignment to $template is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
introduced by
Unused variable $template.
Loading history...
82
83
      $location = $first->location;
84
      $timestamp = isset($first->timestamp)
85
        ? $this->dateFormatter->format($first->timestamp, 'long')
86
        : t('No information');
87
    }
88
    else {
89
      $location = $timestamp = t('No information');
90
    }
91
92
    $rows = [
93
      [t('Request ID'), $unique_id],
94
      [t('Location'), $location],
95
      [t('Date/time'), $timestamp],
96
    ];
97
98
    foreach ($rows as &$row) {
99
      $row[0] = [
100
        'data' => $row[0],
101
        'header' => TRUE,
102
      ];
103
    }
104
105
    $ret = [
106
      '#type' => 'table',
107
      '#rows' => $rows,
108
    ];
109
    return $ret;
110
  }
111
112
  /**
113
   * Build the bottom part of the page, about the events during the request.
114
   *
115
   * @param array<\Drupal\mongodb_watchdog\EventTemplate\Drupal\mongodb_watchdog\Event[]> $events
116
   *   A fully loaded array of events and their templates.
117
   *
118
   * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string|array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
119
   *   A render array for a table.
120
   */
121
  public function buildTrackRows(array $events) {
122
    $header = [
123
      t('Sequence'),
124
      t('Type'),
125
      t('Severity'),
126
      t('Event'),
127
      t('File'),
128
      t('Line'),
129
    ];
130
    $rows = [];
131
    $levels = RfcLogLevel::getLevels();
132
133
    /**
134
     * @var \Drupal\mongodb_watchdog\EventTemplate $template
135
     * @var \Drupal\mongodb_watchdog\Event $event
136
     */
137
    foreach ($events as list($template, $event)) {
0 ignored issues
show
introduced by
Variable $template is undefined.
Loading history...
introduced by
Variable $event is undefined.
Loading history...
138
      $row = [
139
        ['data' => $event->requestTracking_sequence],
0 ignored issues
show
introduced by
Variable $event is undefined.
Loading history...
140
        $template->type,
0 ignored issues
show
introduced by
Variable $template is undefined.
Loading history...
141
        [
142
          'data' => $levels[$template->severity],
0 ignored issues
show
introduced by
Variable $template is undefined.
Loading history...
143
          'class' => OverviewController::SEVERITY_CLASSES[$template->severity],
0 ignored issues
show
introduced by
Variable $template is undefined.
Loading history...
144
        ],
145
        [
146
          'data' => Link::createFromRoute($template->asString($event->variables), 'mongodb_watchdog.reports.detail', [
0 ignored issues
show
introduced by
Variable $template is undefined.
Loading history...
introduced by
Variable $event is undefined.
Loading history...
147
            'event_template' => $template->_id,
0 ignored issues
show
introduced by
Variable $template is undefined.
Loading history...
148
          ]),
149
        ],
150
        $this->simplifyPath($event->variables['%file']),
0 ignored issues
show
introduced by
Variable $event is undefined.
Loading history...
151
        $event->variables['%line'],
0 ignored issues
show
introduced by
Variable $event is undefined.
Loading history...
152
      ];
153
      $rows[] = $row;
154
    }
155
156
    $ret = [
157
      '#type' => 'table',
158
      '#rows' => $rows,
159
      '#header' => $header,
160
    ];
161
    return $ret;
162
  }
163
164
  /**
165
   * {@inheritdoc}
166
   */
167 View Code Duplication
  public static function create(ContainerInterface $container) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
    /** @var \Drupal\mongodb_watchdog\Logger $watchdog */
169
    $watchdog = $container->get('mongodb.logger');
170
171
    /** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */
172
    $date_formatter = $container->get('date.formatter');
173
174
    /** @var \Drupal\Core\Config\ConfigFactoryInterface $config_factory */
175
    $config_factory = $container->get('config.factory');
176
    $items_per_page = $config_factory->get('mongodb_watchdog.settings')->get('items_per_page');
177
    return new static($watchdog, $date_formatter, $items_per_page);
178
  }
179
180
  /**
181
   * Set up the templates pager.
182
   *
183
   * @param \Symfony\Component\HttpFoundation\Request $request
184
   *   The current request.
185
   * @param int $uniqueId
186
   *   The uniqueId of the current request.
187
   *
188
   * @return int
189
   *   The number of the page to display, starting at 0.
190
   */
191 View Code Duplication
  public function setupPager(Request $request, $uniqueId) {
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
introduced by
Variable "uniqueId" is camel caps format. do not use mixed case (camelCase), use lower case and _
Loading history...
192
    $count = $this->watchdog->requestEventsCount($uniqueId);
1 ignored issue
show
introduced by
Variable "uniqueId" is camel caps format. do not use mixed case (camelCase), use lower case and _
Loading history...
193
    $height = $this->itemsPerPage;
194
    pager_default_initialize($count, $height);
195
196
    $page = intval($request->query->get('page'));
197
    if ($page < 0) {
198
      $page = 0;
199
    }
200
    else {
201
      $page_max = intval(min(ceil($count / $height), PHP_INT_MAX) - 1);
202
      if ($page > $page_max) {
203
        $page = $page_max;
204
      }
205
    }
206
207
    return $page;
208
  }
209
210
  /**
211
   * Convert an absolute path to a relative one if below the site root.
212
   *
213
   * @param string $path
214
   *   An absolute path on the filesystem.
215
   *
216
   * @return string
217
   *   A relative path if possible, otherwise the input path.
218
   */
219
  public function simplifyPath($path) {
220
    $ret = (Unicode::strpos($path, DRUPAL_ROOT) === 0)
221
      ? Unicode::substr($path, $this->rootLength)
222
      : $path;
223
    return $ret;
224
  }
225
226
  /**
227
   * Controller.
228
   *
229
   * @param string $uniqueId
230
   *   The unique request id from mod_unique_id. Unsafe.
231
   *
232
   * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string|array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
233
   *   A render array.
234
   */
235
  public function track(Request $request, $uniqueId) {
1 ignored issue
show
introduced by
Variable "uniqueId" is camel caps format. do not use mixed case (camelCase), use lower case and _
Loading history...
236
    if (!preg_match('/[\w-]+/', $uniqueId)) {
1 ignored issue
show
introduced by
Variable "uniqueId" is camel caps format. do not use mixed case (camelCase), use lower case and _
Loading history...
237
      return ['#markup' => ''];
238
    }
239
240
    $page = $this->setupPager($request, $uniqueId);
1 ignored issue
show
introduced by
Variable "uniqueId" is camel caps format. do not use mixed case (camelCase), use lower case and _
Loading history...
241
    $skip = $page * $this->itemsPerPage;
242
    $height = $this->itemsPerPage;
243
244
    $events = $this->watchdog->requestEvents($uniqueId, $skip, $height);
1 ignored issue
show
introduced by
Variable "uniqueId" is camel caps format. do not use mixed case (camelCase), use lower case and _
Loading history...
245
    $ret = [
246
      '#attached' => [
247
        'library' => ['mongodb_watchdog/styling'],
248
      ],
249
      'request' => $this->buildTrackRequest($uniqueId, $events),
1 ignored issue
show
introduced by
Variable "uniqueId" is camel caps format. do not use mixed case (camelCase), use lower case and _
Loading history...
250
      'events' => $this->buildTrackRows($events),
251
      'pager' => [
252
        '#type' => 'pager',
253
      ],
254
    ];
255
    return $ret;
256
  }
257
258
}
0 ignored issues
show
Coding Style introduced by
As per coding style, files should not end with a newline character.

This check marks files that end in a newline character, i.e. an empy line.

Loading history...
259