Passed
Pull Request — 8.x-2.x (#71)
by Frédéric G.
05:50
created

Requirements::checkDatabaseAliasConsistency()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 33
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

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