Requirements   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 243
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 91
c 1
b 0
f 0
dl 0
loc 243
rs 10
wmc 20

7 Methods

Rating   Name   Duplication   Size   Complexity  
A hasUniqueId() 0 3 2
B checkDatabaseAliasConsistency() 0 33 6
A loadConfig() 0 10 2
A check() 0 20 3
A create() 0 7 1
A __construct() 0 12 1
A checkRequestTracking() 0 46 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Drupal\mongodb_watchdog\Install;
6
7
use Drupal\Component\Serialization\SerializationInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Component\Seriali...\SerializationInterface 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\Core\Config\Config;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Config\Config 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\ConfigFactoryInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Config\ConfigFactoryInterface 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\DependencyInjection\ContainerInjectionInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\DependencyIn...ainerInjectionInterface 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\Messenger\MessengerInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Messenger\MessengerInterface 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\Site\Settings;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Site\Settings 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\StringTranslation\StringTranslationTrait;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\StringTransl...\StringTranslationTrait 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\Url;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Url 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\mongodb\MongoDb;
16
use Drupal\mongodb_watchdog\Logger;
17
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...
18
use Symfony\Component\HttpFoundation\RequestStack;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\HttpFoundation\RequestStack 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...
19
20
/**
21
 * Class Requirements implements hook_requirements().
22
 */
23
class Requirements implements ContainerInjectionInterface {
24
  use StringTranslationTrait;
25
26
  /**
27
   * The module configuration.
28
   *
29
   * @var \Drupal\Core\Config\Config
30
   */
31
  protected Config $config;
32
33
  /**
34
   * The config.factory service.
35
   *
36
   * @var \Drupal\Core\Config\ConfigFactoryInterface
37
   */
38
  protected ConfigFactoryInterface $configFactory;
39
40
  /**
41
   * The messenger service.
42
   *
43
   * @var \Drupal\Core\Messenger\MessengerInterface
44
   */
45
  protected MessengerInterface $messenger;
46
47
  /**
48
   * The request_stack service.
49
   *
50
   * @var \Symfony\Component\HttpFoundation\RequestStack
51
   */
52
  protected RequestStack $requestStack;
53
54
  /**
55
   * The serialization.yaml service.
56
   *
57
   * @var \Drupal\Component\Serialization\SerializationInterface
58
   */
59
  protected SerializationInterface $serialization;
60
61
  /**
62
   * The section of Settings related to the MongoDB package.
63
   *
64
   * @var array{clients: array<string,array<string,mixed>>, databases: array<string,array{0:string,1:string}>}
65
   */
66
  protected array $settings;
67
68
  /**
69
   * Requirements constructor.
70
   *
71
   * @param \Drupal\Core\Site\Settings $settings
72
   *   The settings service.
73
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
74
   *   The config.factory service.
75
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
76
   *   The request_stack service.
77
   * @param \Drupal\Component\Serialization\SerializationInterface $serialization
78
   *   The serialization.yaml service.
79
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
80
   *   The messenger service.
81
   */
82
  public function __construct(
83
    Settings $settings,
84
    ConfigFactoryInterface $configFactory,
85
    RequestStack $requestStack,
86
    SerializationInterface $serialization,
87
    MessengerInterface $messenger
88
  ) {
89
    $this->serialization = $serialization;
90
    $this->configFactory = $configFactory;
91
    $this->requestStack = $requestStack;
92
    $this->settings = $settings->get(MongoDb::MODULE);
93
    $this->messenger = $messenger;
94
  }
95
96
  /**
97
   * {@inheritdoc}
98
   */
99
  public static function create(ContainerInterface $container): self {
100
    return new static(
101
      $container->get('settings'),
102
      $container->get('config.factory'),
103
      $container->get('request_stack'),
104
      $container->get('serialization.yaml'),
105
      $container->get('messenger'));
106
  }
107
108
  /**
109
   * Apply database aliases consistency checks.
110
   *
111
   * @param array<string,array<string,mixed>> $state
112
   *   The current state of requirements checks.
113
   *
114
   * @return array{array<string,mixed>,bool}
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{array<string,mixed>,bool} at position 2 could not be parsed: Expected ':' at position 2, but found 'array'.
Loading history...
115
   *   - array: The current state of requirements checks.
116
   *   - bool: true if the checks added an error, false otherwise
117
   */
118
  protected function checkDatabaseAliasConsistency(array $state) : array {
119
    $databases = $this->settings['databases'];
120
    if (!isset($databases[Logger::DB_LOGGER])) {
121
      $state[Logger::MODULE] += [
122
        'severity' => REQUIREMENT_ERROR,
0 ignored issues
show
Bug introduced by
The constant Drupal\mongodb_watchdog\Install\REQUIREMENT_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
123
        'value' => $this->t('Missing `@alias` database alias in settings.',
124
          ['@alias' => Logger::DB_LOGGER]),
125
      ];
126
      return [$state, TRUE];
127
    }
128
129
    [$loggerClient, $loggerDb] = $databases[Logger::DB_LOGGER];
130
    unset($databases[Logger::DB_LOGGER]);
131
    $duplicates = [];
132
    foreach ($databases as $alias => $list) {
133
      [$client, $database] = $list;
134
      if ($loggerClient == $client && $loggerDb == $database) {
135
        $duplicates[] = "`$alias`";
136
      }
137
    }
138
    if (!empty($duplicates)) {
139
      $state[Logger::MODULE] += [
140
        'severity' => REQUIREMENT_ERROR,
141
        'value' => $this->t('The `@alias` alias points to the same database as @others.', [
142
          '@alias' => Logger::DB_LOGGER,
143
          '@others' => implode(', ', $duplicates),
144
        ]),
145
        'description' => $this->t('Those databases would also be dropped when uninstalling the watchdog module.'),
146
      ];
147
      return [$state, TRUE];
148
    }
149
150
    return [$state, FALSE];
151
  }
152
153
  /**
154
   * Load the configuration from default or from active configuration.
155
   *
156
   * @param bool $useDefault
157
   *   Use default configuration ?
158
   */
159
  protected function loadConfig(bool $useDefault): void {
160
    if ($useDefault) {
161
      $rawDefaultConfig = file_get_contents(__DIR__ . '/../../config/install/mongodb_watchdog.settings.yml');
162
      $defaultConfigData = $this->serialization->decode($rawDefaultConfig);
163
      $this->config = $this->configFactory->getEditable(Logger::MODULE);
164
      $this->config->initWithData($defaultConfigData);
165
      return;
166
    }
167
168
    $this->config = $this->configFactory->get(Logger::CONFIG_NAME);
169
  }
170
171
  /**
172
   * Check the consistency of request tracking vs configuration and environment.
173
   *
174
   * @param array<string,array<string,mixed>> $state
175
   *   The current state of requirements.
176
   *
177
   * @return array{array<string,mixed>,bool}
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{array<string,mixed>,bool} at position 2 could not be parsed: Expected ':' at position 2, but found 'array'.
Loading history...
178
   *   - array: The current state of requirements checks.
179
   *   - bool: true if the checks added an error, false otherwise
180
   */
181
  protected function checkRequestTracking(array $state) : array {
182
    $requestTracking = $this->config->get('request_tracking');
183
    if ($this->hasUniqueId()) {
184
      $state[Logger::MODULE] += $requestTracking
185
        ? [
186
          'value' => $this->t('Mod_unique_id available and used'),
187
          'severity' => REQUIREMENT_OK,
0 ignored issues
show
Bug introduced by
The constant Drupal\mongodb_watchdog\Install\REQUIREMENT_OK was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
188
          'description' => $this->t('Request tracking is available and active.'),
189
        ]
190
        : [
191
          'value' => $this->t('Unused mod_unique_id'),
192
          'severity' => REQUIREMENT_INFO,
0 ignored issues
show
Bug introduced by
The constant Drupal\mongodb_watchdog\Install\REQUIREMENT_INFO was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
193
          'description' => $this->t('The site could track requests, but request tracking is not enabled. You could disable mod_unique_id to save resources, or enable request tracking</a> for a better logging experience.'),
194
        ];
195
196
      return [$state, FALSE];
197
    }
198
199
    $state[Logger::MODULE] += [
200
      'value' => $this->t('No mod_unique_id'),
201
    ];
202
    if ($requestTracking) {
203
      if (php_sapi_name() === 'cli') {
204
        $message = $this->t('Request tracking is configured, but the site cannot check the working mod_unique_id configuration from the CLI. Be sure to validate configuration on the <a href=":report">status page</a>.', [
205
          ':report' => Url::fromRoute('system.status')->toString(),
206
        ]);
207
        $state[Logger::MODULE] += [
208
          'severity' => REQUIREMENT_WARNING,
0 ignored issues
show
Bug introduced by
The constant Drupal\mongodb_watchdog\...all\REQUIREMENT_WARNING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
209
          'description' => $message,
210
        ];
211
        $this->messenger->addWarning($message);
212
        return [$state, FALSE];
213
      }
214
215
      $state[Logger::MODULE] += [
216
        'severity' => REQUIREMENT_ERROR,
0 ignored issues
show
Bug introduced by
The constant Drupal\mongodb_watchdog\Install\REQUIREMENT_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
217
        'description' => $this->t('Request tracking is configured, but the site is not served by Apache with a working mod_unique_id.'),
218
      ];
219
      return [$state, TRUE];
220
    }
221
222
    $state[Logger::MODULE] += [
223
      'severity' => REQUIREMENT_OK,
224
      'description' => $this->t('Request tracking is not configured.'),
225
    ];
226
    return [$state, FALSE];
227
  }
228
229
  /**
230
   * Implements hook_requirements().
231
   *
232
   * @return array<string,array<string,mixed>>
233
   *   The requirements array.
234
   */
235
  public function check(string $phase): array {
236
    $state = [
237
      Logger::MODULE => [
238
        'title' => 'MongoDB watchdog',
239
      ],
240
    ];
241
242
    [$state, $err] = $this->checkDatabaseAliasConsistency($state);
243
    if ($err) {
244
      return $state;
245
    }
246
247
    $this->loadConfig($phase !== 'runtime');
248
249
    [$state, $err] = $this->checkRequestTracking($state);
250
    if ($err) {
251
      return $state;
252
    }
253
254
    return $state;
255
  }
256
257
  /**
258
   * Is mod_unique_id available on this instance ?
259
   *
260
   * @return bool
261
   *   Is it ?
262
   */
263
  protected function hasUniqueId(): bool {
264
    $server = $this->requestStack->getCurrentRequest()->server;
265
    return $server->has('UNIQUE_ID') || $server->has('REDIRECT_UNIQUE_ID');
266
  }
267
268
}
269