Completed
Push — master ( 92af5e...e903af )
by Jonathan
14s queued 10s
created

Drupal8::logout()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 3
nc 3
nop 0
1
<?php
2
3
namespace Drupal\Driver\Cores;
4
5
use Drupal\Core\DrupalKernel;
6
use Drupal\Core\Field\BaseFieldDefinition;
7
use Drupal\Driver\Exception\BootstrapException;
8
use Drupal\field\Entity\FieldStorageConfig;
9
use Drupal\language\Entity\ConfigurableLanguage;
10
use Drupal\mailsystem\MailsystemManager;
11
use Drupal\node\Entity\Node;
12
use Drupal\node\NodeInterface;
13
use Drupal\Core\Entity\EntityInterface;
14
use Drupal\taxonomy\Entity\Term;
15
use Drupal\taxonomy\TermInterface;
16
use Drupal\user\Entity\Role;
17
use Drupal\user\Entity\User;
18
use Symfony\Component\HttpFoundation\Request;
19
20
/**
21
 * Drupal 8 core.
22
 */
23
class Drupal8 extends AbstractCore implements CoreAuthenticationInterface {
24
25
  /**
26
   * Tracks original configuration values.
27
   *
28
   * This is necessary since configurations modified here are actually saved so
29
   * that they persist values across bootstraps.
30
   *
31
   * @var array
32
   *   An array of data, keyed by configuration name.
33
   */
34
  protected $originalConfiguration = [];
35
36
  /**
37
   * {@inheritdoc}
38
   */
39
  public function bootstrap() {
40
    // Validate, and prepare environment for Drupal bootstrap.
41
    if (!defined('DRUPAL_ROOT')) {
42
      define('DRUPAL_ROOT', $this->drupalRoot);
43
    }
44
45
    // Bootstrap Drupal.
46
    chdir(DRUPAL_ROOT);
47
    $autoloader = require DRUPAL_ROOT . '/autoload.php';
48
    require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
49
    $this->validateDrupalSite();
50
51
    $request = Request::createFromGlobals();
52
    $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
53
    $kernel->boot();
54
    $kernel->prepareLegacyRequest($request);
55
56
    // Initialise an anonymous session. required for the bootstrap.
57
    \Drupal::service('session_manager')->start();
58
  }
59
60
  /**
61
   * {@inheritdoc}
62
   */
63
  public function clearCache() {
64
    // Need to change into the Drupal root directory or the registry explodes.
65
    drupal_flush_all_caches();
66
  }
67
68
  /**
69
   * {@inheritdoc}
70
   */
71
  public function nodeCreate($node) {
72
    // Throw an exception if the node type is missing or does not exist.
73
    if (!isset($node->type) || !$node->type) {
74
      throw new \Exception("Cannot create content because it is missing the required property 'type'.");
75
    }
76
77
    /** @var \Drupal\Core\Entity\EntityTypeBundleInfo $bundle_info */
78
    $bundle_info = \Drupal::service('entity_type.bundle.info');
79
    $bundles = $bundle_info->getBundleInfo('node');
80
    if (!in_array($node->type, array_keys($bundles))) {
81
      throw new \Exception("Cannot create content because provided content type '$node->type' does not exist.");
82
    }
83
    // If 'author' is set, remap it to 'uid'.
84
    if (isset($node->author)) {
85
      $user = user_load_by_name($node->author);
86
      if ($user) {
87
        $node->uid = $user->id();
88
      }
89
    }
90
    $this->expandEntityFields('node', $node);
91
    $entity = Node::create((array) $node);
92
    $entity->save();
93
94
    $node->nid = $entity->id();
95
96
    return $node;
97
  }
98
99
  /**
100
   * {@inheritdoc}
101
   */
102
  public function nodeDelete($node) {
103
    $node = $node instanceof NodeInterface ? $node : Node::load($node->nid);
0 ignored issues
show
Bug introduced by
The class Drupal\node\NodeInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
104
    if ($node instanceof NodeInterface) {
0 ignored issues
show
Bug introduced by
The class Drupal\node\NodeInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
105
      $node->delete();
106
    }
107
  }
108
109
  /**
110
   * {@inheritdoc}
111
   */
112
  public function runCron() {
113
    return \Drupal::service('cron')->run();
114
  }
115
116
  /**
117
   * {@inheritdoc}
118
   */
119
  public function userCreate(\stdClass $user) {
120
    $this->validateDrupalSite();
121
122
    // Default status to TRUE if not explicitly creating a blocked user.
123
    if (!isset($user->status)) {
124
      $user->status = 1;
125
    }
126
127
    // Clone user object, otherwise user_save() changes the password to the
128
    // hashed password.
129
    $this->expandEntityFields('user', $user);
130
    $account = \Drupal::entityTypeManager()->getStorage('user')->create((array) $user);
131
    $account->save();
132
133
    // Store UID.
134
    $user->uid = $account->id();
135
  }
136
137
  /**
138
   * {@inheritdoc}
139
   */
140
  public function roleCreate(array $permissions) {
141
    // Generate a random, lowercase machine name.
142
    $rid = strtolower($this->random->name(8, TRUE));
143
144
    // Generate a random label.
145
    $name = trim($this->random->name(8, TRUE));
146
147
    // Convert labels to machine names.
148
    $this->convertPermissions($permissions);
149
150
    // Check the all the permissions strings are valid.
151
    $this->checkPermissions($permissions);
152
153
    // Create new role.
154
    $role = \Drupal::entityTypeManager()->getStorage('user_role')->create(array(
155
      'id' => $rid,
156
      'label' => $name,
157
    ));
158
    $result = $role->save();
159
160
    if ($result === SAVED_NEW) {
161
      // Grant the specified permissions to the role, if any.
162
      if (!empty($permissions)) {
163
        user_role_grant_permissions($role->id(), $permissions);
164
      }
165
      return $role->id();
166
    }
167
168
    throw new \RuntimeException(sprintf('Failed to create a role with "%s" permission(s).', implode(', ', $permissions)));
169
  }
170
171
  /**
172
   * {@inheritdoc}
173
   */
174
  public function roleDelete($role_name) {
175
    $role = Role::load($role_name);
176
177
    if (!$role) {
178
      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
179
    }
180
181
    $role->delete();
182
  }
183
184
  /**
185
   * {@inheritdoc}
186
   */
187
  public function processBatch() {
188
    $this->validateDrupalSite();
189
    $batch =& batch_get();
190
    $batch['progressive'] = FALSE;
191
    batch_process();
192
  }
193
194
  /**
195
   * Retrieve all permissions.
196
   *
197
   * @return array
198
   *   Array of all defined permissions.
199
   */
200
  protected function getAllPermissions() {
201
    $permissions = &drupal_static(__FUNCTION__);
202
203
    if (!isset($permissions)) {
204
      $permissions = \Drupal::service('user.permissions')->getPermissions();
205
    }
206
207
    return $permissions;
208
  }
209
210
  /**
211
   * Convert any permission labels to machine name.
212
   *
213
   * @param array &$permissions
214
   *   Array of permission names.
215
   */
216
  protected function convertPermissions(array &$permissions) {
217
    $all_permissions = $this->getAllPermissions();
218
219
    foreach ($all_permissions as $name => $definition) {
220
      $key = array_search($definition['title'], $permissions);
221
      if (FALSE !== $key) {
222
        $permissions[$key] = $name;
223
      }
224
    }
225
  }
226
227
  /**
228
   * Check to make sure that the array of permissions are valid.
229
   *
230
   * @param array $permissions
231
   *   Permissions to check.
232
   */
233
  protected function checkPermissions(array &$permissions) {
234
    $available = array_keys($this->getAllPermissions());
235
236
    foreach ($permissions as $permission) {
237
      if (!in_array($permission, $available)) {
238
        throw new \RuntimeException(sprintf('Invalid permission "%s".', $permission));
239
      }
240
    }
241
  }
242
243
  /**
244
   * {@inheritdoc}
245
   */
246
  public function userDelete(\stdClass $user) {
247
    user_cancel(array(), $user->uid, 'user_cancel_delete');
248
  }
249
250
  /**
251
   * {@inheritdoc}
252
   */
253
  public function userAddRole(\stdClass $user, $role_name) {
254
    // Allow both machine and human role names.
255
    $roles = user_role_names();
256
    $id = array_search($role_name, $roles);
257
    if (FALSE !== $id) {
258
      $role_name = $id;
259
    }
260
261
    if (!$role = Role::load($role_name)) {
262
      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
263
    }
264
265
    $account = User::load($user->uid);
266
    $account->addRole($role->id());
267
    $account->save();
268
  }
269
270
  /**
271
   * {@inheritdoc}
272
   */
273
  public function validateDrupalSite() {
274
    if ('default' !== $this->uri) {
275
      // Fake the necessary HTTP headers that Drupal needs:
276
      $drupal_base_url = parse_url($this->uri);
277
      // If there's no url scheme set, add http:// and re-parse the url
278
      // so the host and path values are set accurately.
279
      if (!array_key_exists('scheme', $drupal_base_url)) {
280
        $drupal_base_url = parse_url($this->uri);
281
      }
282
      // Fill in defaults.
283
      $drupal_base_url += array(
284
        'path' => NULL,
285
        'host' => NULL,
286
        'port' => NULL,
287
      );
288
      $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
289
290
      if ($drupal_base_url['port']) {
291
        $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
292
      }
293
      $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
294
295
      if (array_key_exists('path', $drupal_base_url)) {
296
        $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
297
      }
298
      else {
299
        $_SERVER['PHP_SELF'] = '/index.php';
300
      }
301
    }
302
    else {
303
      $_SERVER['HTTP_HOST'] = 'default';
304
      $_SERVER['PHP_SELF'] = '/index.php';
305
    }
306
307
    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
308
    $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
309
    $_SERVER['REQUEST_METHOD'] = NULL;
310
311
    $_SERVER['SERVER_SOFTWARE'] = NULL;
312
    $_SERVER['HTTP_USER_AGENT'] = NULL;
313
314
    $conf_path = DrupalKernel::findSitePath(Request::createFromGlobals());
315
    $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
316
    if (!file_exists($conf_file)) {
317
      throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
318
    }
319
    $drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php";
320
    if (file_exists($drushrc_file)) {
321
      require_once $drushrc_file;
322
    }
323
  }
324
325
  /**
326
   * {@inheritdoc}
327
   */
328
  public function termCreate(\stdClass $term) {
329
    $term->vid = $term->vocabulary_machine_name;
330
331 View Code Duplication
    if (isset($term->parent)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
332
      $parent = \taxonomy_term_load_multiple_by_name($term->parent, $term->vocabulary_machine_name);
333
      if (!empty($parent)) {
334
        $parent = reset($parent);
335
        $term->parent = $parent->id();
336
      }
337
    }
338
339
    $this->expandEntityFields('taxonomy_term', $term);
340
    $entity = Term::create((array) $term);
341
    $entity->save();
342
343
    $term->tid = $entity->id();
344
    return $term;
345
  }
346
347
  /**
348
   * {@inheritdoc}
349
   */
350
  public function termDelete(\stdClass $term) {
351
    $term = $term instanceof TermInterface ? $term : Term::load($term->tid);
0 ignored issues
show
Bug introduced by
The class Drupal\taxonomy\TermInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
352
    if ($term instanceof TermInterface) {
0 ignored issues
show
Bug introduced by
The class Drupal\taxonomy\TermInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
353
      $term->delete();
354
    }
355
  }
356
357
  /**
358
   * {@inheritdoc}
359
   */
360
  public function getModuleList() {
361
    return array_keys(\Drupal::moduleHandler()->getModuleList());
362
  }
363
364
  /**
365
   * {@inheritdoc}
366
   */
367
  public function getExtensionPathList() {
368
    $paths = array();
369
370
    // Get enabled modules.
371
    foreach (\Drupal::moduleHandler()->getModuleList() as $module) {
372
      $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . $module->getPath();
373
    }
374
375
    return $paths;
376
  }
377
378
  /**
379
   * Expands specified base fields on the entity object.
380
   *
381
   * @param string $entity_type
382
   *   The entity type for which to return the field types.
383
   * @param \stdClass $entity
384
   *   Entity object.
385
   * @param array $base_fields
386
   *   Base fields to be expanded in addition to user defined fields.
387
   */
388
  public function expandEntityBaseFields($entity_type, \stdClass $entity, array $base_fields) {
389
    $this->expandEntityFields($entity_type, $entity, $base_fields);
390
  }
391
392
  /**
393
   * {@inheritdoc}
394
   */
395
  public function getEntityFieldTypes($entity_type, array $base_fields = array()) {
396
    $return = array();
397
    /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
398
    $entity_field_manager = \Drupal::service('entity_field.manager');
399
    $fields = $entity_field_manager->getFieldStorageDefinitions($entity_type);
400
    foreach ($fields as $field_name => $field) {
401
      if ($this->isField($entity_type, $field_name)
402
        || (in_array($field_name, $base_fields) && $this->isBaseField($entity_type, $field_name))) {
403
        $return[$field_name] = $field->getType();
404
      }
405
    }
406
    return $return;
407
  }
408
409
  /**
410
   * {@inheritdoc}
411
   */
412
  public function isField($entity_type, $field_name) {
413
    /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
414
    $entity_field_manager = \Drupal::service('entity_field.manager');
415
    $fields = $entity_field_manager->getFieldStorageDefinitions($entity_type);
416
    return (isset($fields[$field_name]) && $fields[$field_name] instanceof FieldStorageConfig);
0 ignored issues
show
Bug introduced by
The class Drupal\field\Entity\FieldStorageConfig does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
417
  }
418
419
  /**
420
   * {@inheritdoc}
421
   */
422
  public function isBaseField($entity_type, $field_name) {
423
    /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager */
424
    $entity_field_manager = \Drupal::service('entity_field.manager');
425
    $fields = $entity_field_manager->getFieldStorageDefinitions($entity_type);
426
    return (isset($fields[$field_name]) && $fields[$field_name] instanceof BaseFieldDefinition);
0 ignored issues
show
Bug introduced by
The class Drupal\Core\Field\BaseFieldDefinition does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
427
  }
428
429
  /**
430
   * {@inheritdoc}
431
   */
432
  public function languageCreate(\stdClass $language) {
433
    $langcode = $language->langcode;
434
435
    // Enable a language only if it has not been enabled already.
436
    if (!ConfigurableLanguage::load($langcode)) {
437
      $created_language = ConfigurableLanguage::createFromLangcode($language->langcode);
438
      if (!$created_language) {
439
        throw new InvalidArgumentException("There is no predefined language with langcode '{$langcode}'.");
440
      }
441
      $created_language->save();
442
      return $language;
443
    }
444
445
    return FALSE;
446
  }
447
448
  /**
449
   * {@inheritdoc}
450
   */
451
  public function languageDelete(\stdClass $language) {
452
    $configurable_language = ConfigurableLanguage::load($language->langcode);
453
    $configurable_language->delete();
454
  }
455
456
  /**
457
   * {@inheritdoc}
458
   */
459
  public function clearStaticCaches() {
460
    drupal_static_reset();
461
    \Drupal::service('cache_tags.invalidator')->resetChecksums();
462
  }
463
464
  /**
465
   * {@inheritdoc}
466
   */
467
  public function configGet($name, $key = '') {
468
    return \Drupal::config($name)->get($key);
469
  }
470
471
  /**
472
   * {@inheritdoc}
473
   */
474
  public function configGetOriginal($name, $key = '') {
475
    return \Drupal::config($name)->getOriginal($key, FALSE);
476
  }
477
478
  /**
479
   * {@inheritdoc}
480
   */
481
  public function configSet($name, $key, $value) {
482
    \Drupal::configFactory()->getEditable($name)
483
      ->set($key, $value)
484
      ->save();
485
  }
486
487
  /**
488
   * {@inheritdoc}
489
   */
490
  public function entityCreate($entity_type, $entity) {
491
    // If the bundle field is empty, put the inferred bundle value in it.
492
    $bundle_key = \Drupal::entityTypeManager()->getDefinition($entity_type)->getKey('bundle');
493 View Code Duplication
    if (!isset($entity->$bundle_key) && isset($entity->step_bundle)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
494
      $entity->$bundle_key = $entity->step_bundle;
495
    }
496
497
    // Throw an exception if a bundle is specified but does not exist.
498
    if (isset($entity->$bundle_key) && ($entity->$bundle_key !== NULL)) {
499
      /** @var \Drupal\Core\Entity\EntityTypeBundleInfo $bundle_info */
500
      $bundle_info = \Drupal::service('entity_type.bundle.info');
501
      $bundles = $bundle_info->getBundleInfo($entity_type);
502 View Code Duplication
      if (!in_array($entity->$bundle_key, array_keys($bundles))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
503
        throw new \Exception("Cannot create entity because provided bundle '$entity->$bundle_key' does not exist.");
504
      }
505
    }
506
    if (empty($entity_type)) {
507
      throw new \Exception("You must specify an entity type to create an entity.");
508
    }
509
510
    $this->expandEntityFields($entity_type, $entity);
511
    $createdEntity = \Drupal::entityTypeManager()->getStorage($entity_type)->create((array) $entity);
512
    $createdEntity->save();
513
514
    $entity->id = $createdEntity->id();
515
516
    return $entity;
517
  }
518
519
  /**
520
   * {@inheritdoc}
521
   */
522
  public function entityDelete($entity_type, $entity) {
523
    $entity = $entity instanceof EntityInterface ? $entity : \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity->id);
0 ignored issues
show
Bug introduced by
The class Drupal\Core\Entity\EntityInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
524
    if ($entity instanceof EntityInterface) {
0 ignored issues
show
Bug introduced by
The class Drupal\Core\Entity\EntityInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
525
      $entity->delete();
526
    }
527
  }
528
529
  /**
530
   * {@inheritdoc}
531
   */
532
  public function startCollectingMail() {
533
    $config = \Drupal::configFactory()->getEditable('system.mail');
534
    $data = $config->getRawData();
535
536
    // Save the values for restoration after.
537
    $this->storeOriginalConfiguration('system.mail', $data);
538
539
    // @todo Use a collector that supports html after D#2223967 lands.
540
    $data['interface'] = ['default' => 'test_mail_collector'];
541
    $config->setData($data)->save();
542
    // Disable the mail system module's mail if enabled.
543
    $this->startCollectingMailSystemMail();
544
  }
545
546
  /**
547
   * {@inheritdoc}
548
   */
549
  public function stopCollectingMail() {
550
    $config = \Drupal::configFactory()->getEditable('system.mail');
551
    $config->setData($this->originalConfiguration['system.mail'])->save();
552
    // Re-enable the mailsystem module's mail if enabled.
553
    $this->stopCollectingMailSystemMail();
554
  }
555
556
  /**
557
   * {@inheritdoc}
558
   */
559
  public function getMail() {
560
    \Drupal::state()->resetCache();
561
    $mail = \Drupal::state()->get('system.test_mail_collector') ?: [];
562
    // Discard cancelled mail.
563
    $mail = array_values(array_filter($mail, function ($mailItem) {
564
      return ($mailItem['send'] == TRUE);
565
    }));
566
    return $mail;
567
  }
568
569
  /**
570
   * {@inheritdoc}
571
   */
572
  public function clearMail() {
573
    \Drupal::state()->set('system.test_mail_collector', []);
574
  }
575
576
  /**
577
   * {@inheritdoc}
578
   */
579
  public function sendMail($body = '', $subject = '', $to = '', $langcode = '') {
580
    // Send the mail, via the system module's hook_mail.
581
    $params['context']['message'] = $body;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
582
    $params['context']['subject'] = $subject;
583
    $mailManager = \Drupal::service('plugin.manager.mail');
584
    $result = $mailManager->mail('system', '', $to, $langcode, $params, NULL, TRUE);
585
    return $result;
586
  }
587
588
  /**
589
   * If the Mail System module is enabled, collect that mail too.
590
   *
591
   * @see MailsystemManager::getPluginInstance()
592
   */
593
  protected function startCollectingMailSystemMail() {
594
    if (\Drupal::moduleHandler()->moduleExists('mailsystem')) {
595
      $config = \Drupal::configFactory()->getEditable('mailsystem.settings');
596
      $data = $config->getRawData();
597
598
      // Track original data for restoration.
599
      $this->storeOriginalConfiguration('mailsystem.settings', $data);
600
601
      // Convert all of the 'senders' to the test collector.
602
      $data = $this->findMailSystemSenders($data);
603
      $config->setData($data)->save();
604
    }
605
  }
606
607
  /**
608
   * Find and replace all the mail system sender plugins with the test plugin.
609
   *
610
   * This method calls itself recursively.
611
   */
612
  protected function findMailSystemSenders(array $data) {
613
    foreach ($data as $key => $values) {
614
      if (is_array($values)) {
615
        if (isset($values[MailsystemManager::MAILSYSTEM_TYPE_SENDING])) {
616
          $data[$key][MailsystemManager::MAILSYSTEM_TYPE_SENDING] = 'test_mail_collector';
617
        }
618
        else {
619
          $data[$key] = $this->findMailSystemSenders($values);
620
        }
621
      }
622
    }
623
    return $data;
624
  }
625
626
  /**
627
   * If the Mail System module is enabled, stop collecting those mails.
628
   */
629
  protected function stopCollectingMailSystemMail() {
630
    if (\Drupal::moduleHandler()->moduleExists('mailsystem')) {
631
      \Drupal::configFactory()->getEditable('mailsystem.settings')->setData($this->originalConfiguration['mailsystem.settings'])->save();
632
    }
633
  }
634
635
  /**
636
   * {@inheritdoc}
637
   */
638
  public function login(\stdClass $user) {
639
    $account = User::load($user->uid);
640
    \Drupal::service('account_switcher')->switchTo($account);
641
  }
642
643
  /**
644
   * {@inheritdoc}
645
   */
646
  public function logout() {
647
    try {
648
      while (TRUE) {
649
        \Drupal::service('account_switcher')->switchBack();
650
      }
651
    }
652
    catch (\RuntimeException $e) {
653
      // No more users are logged in.
654
    }
655
  }
656
657
  /**
658
   * Store the original value for a piece of configuration.
659
   *
660
   * If an original value has previously been stored, it is not updated.
661
   *
662
   * @param string $name
663
   *   The name of the configuration.
664
   * @param mixed $value
665
   *   The original value of the configuration.
666
   */
667
  protected function storeOriginalConfiguration($name, $value) {
668
    if (!isset($this->originalConfiguration[$name])) {
669
      $this->originalConfiguration[$name] = $value;
670
    }
671
  }
672
673
}
674