Completed
Pull Request — 186-backend-auth (#212)
by Claudiu
01:37
created

Drupal8::configGetOriginal()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
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\User;
17
use Symfony\Component\HttpFoundation\Request;
18
19
/**
20
 * Drupal 8 core.
21
 */
22
class Drupal8 extends AbstractCore implements CoreAuthenticationInterface {
23
24
  /**
25
   * Tracks original configuration values.
26
   *
27
   * This is necessary since configurations modified here are actually saved so
28
   * that they persist values across bootstraps.
29
   *
30
   * @var array
31
   *   An array of data, keyed by configuration name.
32
   */
33
  protected $originalConfiguration = [];
34
35
  /**
36
   * {@inheritdoc}
37
   */
38
  public function bootstrap() {
39
    // Validate, and prepare environment for Drupal bootstrap.
40
    if (!defined('DRUPAL_ROOT')) {
41
      define('DRUPAL_ROOT', $this->drupalRoot);
42
    }
43
44
    // Bootstrap Drupal.
45
    chdir(DRUPAL_ROOT);
46
    $autoloader = require DRUPAL_ROOT . '/autoload.php';
47
    require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
48
    $this->validateDrupalSite();
49
50
    $request = Request::createFromGlobals();
51
    $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
52
    $kernel->boot();
53
    $kernel->prepareLegacyRequest($request);
54
55
    // Initialise an anonymous session. required for the bootstrap.
56
    \Drupal::service('session_manager')->start();
57
  }
58
59
  /**
60
   * {@inheritdoc}
61
   */
62
  public function clearCache() {
63
    // Need to change into the Drupal root directory or the registry explodes.
64
    drupal_flush_all_caches();
65
  }
66
67
  /**
68
   * {@inheritdoc}
69
   */
70
  public function nodeCreate($node) {
71
    // Throw an exception if the node type is missing or does not exist.
72
    if (!isset($node->type) || !$node->type) {
73
      throw new \Exception("Cannot create content because it is missing the required property 'type'.");
74
    }
75
    $bundles = \Drupal::entityManager()->getBundleInfo('node');
76
    if (!in_array($node->type, array_keys($bundles))) {
77
      throw new \Exception("Cannot create content because provided content type '$node->type' does not exist.");
78
    }
79
    // If 'author' is set, remap it to 'uid'.
80
    if (isset($node->author)) {
81
      $user = user_load_by_name($node->author);
82
      if ($user) {
83
        $node->uid = $user->id();
84
      }
85
    }
86
    $this->expandEntityFields('node', $node);
87
    $entity = Node::create((array) $node);
88
    $entity->save();
89
90
    $node->nid = $entity->id();
91
92
    return $node;
93
  }
94
95
  /**
96
   * {@inheritdoc}
97
   */
98
  public function nodeDelete($node) {
99
    $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...
100
    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...
101
      $node->delete();
102
    }
103
  }
104
105
  /**
106
   * {@inheritdoc}
107
   */
108
  public function runCron() {
109
    return \Drupal::service('cron')->run();
110
  }
111
112
  /**
113
   * {@inheritdoc}
114
   */
115
  public function userCreate(\stdClass $user) {
116
    $this->validateDrupalSite();
117
118
    // Default status to TRUE if not explicitly creating a blocked user.
119
    if (!isset($user->status)) {
120
      $user->status = 1;
121
    }
122
123
    // Clone user object, otherwise user_save() changes the password to the
124
    // hashed password.
125
    $this->expandEntityFields('user', $user);
126
    $account = entity_create('user', (array) $user);
127
    $account->save();
128
129
    // Store UID.
130
    $user->uid = $account->id();
131
  }
132
133
  /**
134
   * {@inheritdoc}
135
   */
136
  public function roleCreate(array $permissions) {
137
    // Generate a random, lowercase machine name.
138
    $rid = strtolower($this->random->name(8, TRUE));
139
140
    // Generate a random label.
141
    $name = trim($this->random->name(8, TRUE));
142
143
    // Convert labels to machine names.
144
    $this->convertPermissions($permissions);
145
146
    // Check the all the permissions strings are valid.
147
    $this->checkPermissions($permissions);
148
149
    // Create new role.
150
    $role = entity_create('user_role', array(
151
      'id' => $rid,
152
      'label' => $name,
153
    ));
154
    $result = $role->save();
155
156
    if ($result === SAVED_NEW) {
157
      // Grant the specified permissions to the role, if any.
158
      if (!empty($permissions)) {
159
        user_role_grant_permissions($role->id(), $permissions);
160
      }
161
      return $role->id();
162
    }
163
164
    throw new \RuntimeException(sprintf('Failed to create a role with "%s" permission(s).', implode(', ', $permissions)));
165
  }
166
167
  /**
168
   * {@inheritdoc}
169
   */
170
  public function roleDelete($role_name) {
171
    $role = user_role_load($role_name);
172
173
    if (!$role) {
174
      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
175
    }
176
177
    $role->delete();
178
  }
179
180
  /**
181
   * {@inheritdoc}
182
   */
183
  public function processBatch() {
184
    $this->validateDrupalSite();
185
    $batch =& batch_get();
186
    $batch['progressive'] = FALSE;
187
    batch_process();
188
  }
189
190
  /**
191
   * Retrieve all permissions.
192
   *
193
   * @return array
194
   *   Array of all defined permissions.
195
   */
196
  protected function getAllPermissions() {
197
    $permissions = &drupal_static(__FUNCTION__);
198
199
    if (!isset($permissions)) {
200
      $permissions = \Drupal::service('user.permissions')->getPermissions();
201
    }
202
203
    return $permissions;
204
  }
205
206
  /**
207
   * Convert any permission labels to machine name.
208
   *
209
   * @param array &$permissions
210
   *   Array of permission names.
211
   */
212
  protected function convertPermissions(array &$permissions) {
213
    $all_permissions = $this->getAllPermissions();
214
215
    foreach ($all_permissions as $name => $definition) {
216
      $key = array_search($definition['title'], $permissions);
217
      if (FALSE !== $key) {
218
        $permissions[$key] = $name;
219
      }
220
    }
221
  }
222
223
  /**
224
   * Check to make sure that the array of permissions are valid.
225
   *
226
   * @param array $permissions
227
   *   Permissions to check.
228
   */
229
  protected function checkPermissions(array &$permissions) {
230
    $available = array_keys($this->getAllPermissions());
231
232
    foreach ($permissions as $permission) {
233
      if (!in_array($permission, $available)) {
234
        throw new \RuntimeException(sprintf('Invalid permission "%s".', $permission));
235
      }
236
    }
237
  }
238
239
  /**
240
   * {@inheritdoc}
241
   */
242
  public function userDelete(\stdClass $user) {
243
    user_cancel(array(), $user->uid, 'user_cancel_delete');
244
  }
245
246
  /**
247
   * {@inheritdoc}
248
   */
249
  public function userAddRole(\stdClass $user, $role_name) {
250
    // Allow both machine and human role names.
251
    $roles = user_role_names();
252
    $id = array_search($role_name, $roles);
253
    if (FALSE !== $id) {
254
      $role_name = $id;
255
    }
256
257
    if (!$role = user_role_load($role_name)) {
258
      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
259
    }
260
261
    $account = \user_load($user->uid);
262
    $account->addRole($role->id());
263
    $account->save();
264
  }
265
266
  /**
267
   * {@inheritdoc}
268
   */
269
  public function validateDrupalSite() {
270
    if ('default' !== $this->uri) {
271
      // Fake the necessary HTTP headers that Drupal needs:
272
      $drupal_base_url = parse_url($this->uri);
273
      // If there's no url scheme set, add http:// and re-parse the url
274
      // so the host and path values are set accurately.
275
      if (!array_key_exists('scheme', $drupal_base_url)) {
276
        $drupal_base_url = parse_url($this->uri);
277
      }
278
      // Fill in defaults.
279
      $drupal_base_url += array(
280
        'path' => NULL,
281
        'host' => NULL,
282
        'port' => NULL,
283
      );
284
      $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
285
286
      if ($drupal_base_url['port']) {
287
        $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
288
      }
289
      $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
290
291
      if (array_key_exists('path', $drupal_base_url)) {
292
        $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
293
      }
294
      else {
295
        $_SERVER['PHP_SELF'] = '/index.php';
296
      }
297
    }
298
    else {
299
      $_SERVER['HTTP_HOST'] = 'default';
300
      $_SERVER['PHP_SELF'] = '/index.php';
301
    }
302
303
    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
304
    $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
305
    $_SERVER['REQUEST_METHOD'] = NULL;
306
307
    $_SERVER['SERVER_SOFTWARE'] = NULL;
308
    $_SERVER['HTTP_USER_AGENT'] = NULL;
309
310
    $conf_path = DrupalKernel::findSitePath(Request::createFromGlobals());
311
    $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
312
    if (!file_exists($conf_file)) {
313
      throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
314
    }
315
    $drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php";
316
    if (file_exists($drushrc_file)) {
317
      require_once $drushrc_file;
318
    }
319
  }
320
321
  /**
322
   * {@inheritdoc}
323
   */
324
  public function termCreate(\stdClass $term) {
325
    $term->vid = $term->vocabulary_machine_name;
326
327 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...
328
      $parent = \taxonomy_term_load_multiple_by_name($term->parent, $term->vocabulary_machine_name);
329
      if (!empty($parent)) {
330
        $parent = reset($parent);
331
        $term->parent = $parent->id();
332
      }
333
    }
334
335
    $this->expandEntityFields('taxonomy_term', $term);
336
    $entity = Term::create((array) $term);
337
    $entity->save();
338
339
    $term->tid = $entity->id();
340
    return $term;
341
  }
342
343
  /**
344
   * {@inheritdoc}
345
   */
346
  public function termDelete(\stdClass $term) {
347
    $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...
348
    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...
349
      $term->delete();
350
    }
351
  }
352
353
  /**
354
   * {@inheritdoc}
355
   */
356
  public function getModuleList() {
357
    return array_keys(\Drupal::moduleHandler()->getModuleList());
358
  }
359
360
  /**
361
   * {@inheritdoc}
362
   */
363
  public function getExtensionPathList() {
364
    $paths = array();
365
366
    // Get enabled modules.
367
    foreach (\Drupal::moduleHandler()->getModuleList() as $module) {
368
      $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . $module->getPath();
369
    }
370
371
    return $paths;
372
  }
373
374
  /**
375
   * Expands specified base fields on the entity object.
376
   *
377
   * @param string $entity_type
378
   *   The entity type for which to return the field types.
379
   * @param \stdClass $entity
380
   *   Entity object.
381
   * @param array $base_fields
382
   *   Base fields to be expanded in addition to user defined fields.
383
   */
384
  public function expandEntityBaseFields($entity_type, \stdClass $entity, array $base_fields) {
385
    $this->expandEntityFields($entity_type, $entity, $base_fields);
386
  }
387
388
  /**
389
   * {@inheritdoc}
390
   */
391
  public function getEntityFieldTypes($entity_type, array $base_fields = array()) {
392
    $return = array();
393
    $fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);
394
    foreach ($fields as $field_name => $field) {
395
      if ($this->isField($entity_type, $field_name)
396
        || (in_array($field_name, $base_fields) && $this->isBaseField($entity_type, $field_name))) {
397
        $return[$field_name] = $field->getType();
398
      }
399
    }
400
    return $return;
401
  }
402
403
  /**
404
   * {@inheritdoc}
405
   */
406
  public function isField($entity_type, $field_name) {
407
    $fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);
408
    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...
409
  }
410
411
  /**
412
   * {@inheritdoc}
413
   */
414
  public function isBaseField($entity_type, $field_name) {
415
    $fields = \Drupal::entityManager()->getFieldStorageDefinitions($entity_type);
416
    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...
417
  }
418
419
  /**
420
   * {@inheritdoc}
421
   */
422
  public function languageCreate(\stdClass $language) {
423
    $langcode = $language->langcode;
424
425
    // Enable a language only if it has not been enabled already.
426
    if (!ConfigurableLanguage::load($langcode)) {
427
      $created_language = ConfigurableLanguage::createFromLangcode($language->langcode);
428
      if (!$created_language) {
429
        throw new InvalidArgumentException("There is no predefined language with langcode '{$langcode}'.");
430
      }
431
      $created_language->save();
432
      return $language;
433
    }
434
435
    return FALSE;
436
  }
437
438
  /**
439
   * {@inheritdoc}
440
   */
441
  public function languageDelete(\stdClass $language) {
442
    $configurable_language = ConfigurableLanguage::load($language->langcode);
443
    $configurable_language->delete();
444
  }
445
446
  /**
447
   * {@inheritdoc}
448
   */
449
  public function clearStaticCaches() {
450
    drupal_static_reset();
451
    \Drupal::service('cache_tags.invalidator')->resetChecksums();
452
  }
453
454
  /**
455
   * {@inheritdoc}
456
   */
457
  public function configGet($name, $key = '') {
458
    return \Drupal::config($name)->get($key);
459
  }
460
461
  /**
462
   * {@inheritdoc}
463
   */
464
  public function configGetOriginal($name, $key = '') {
465
    return \Drupal::config($name)->getOriginal($key, FALSE);
466
  }
467
468
  /**
469
   * {@inheritdoc}
470
   */
471
  public function configSet($name, $key, $value) {
472
    \Drupal::configFactory()->getEditable($name)
473
      ->set($key, $value)
474
      ->save();
475
  }
476
477
  /**
478
   * {@inheritdoc}
479
   */
480
  public function entityCreate($entity_type, $entity) {
481
    // If the bundle field is empty, put the inferred bundle value in it.
482
    $bundle_key = \Drupal::entityManager()->getDefinition($entity_type)->getKey('bundle');
483 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...
484
      $entity->$bundle_key = $entity->step_bundle;
485
    }
486
487
    // Throw an exception if a bundle is specified but does not exist.
488 View Code Duplication
    if (isset($entity->$bundle_key) && ($entity->$bundle_key !== NULL)) {
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...
489
      $bundles = \Drupal::entityManager()->getBundleInfo($entity_type);
490
      if (!in_array($entity->$bundle_key, array_keys($bundles))) {
491
        throw new \Exception("Cannot create entity because provided bundle '$entity->$bundle_key' does not exist.");
492
      }
493
    }
494
    if (empty($entity_type)) {
495
      throw new \Exception("You must specify an entity type to create an entity.");
496
    }
497
498
    $this->expandEntityFields($entity_type, $entity);
499
    $createdEntity = entity_create($entity_type, (array) $entity);
500
    $createdEntity->save();
501
502
    $entity->id = $createdEntity->id();
503
504
    return $entity;
505
  }
506
507
  /**
508
   * {@inheritdoc}
509
   */
510
  public function entityDelete($entity_type, $entity) {
511
    $entity = $entity instanceof EntityInterface ? $entity : entity_load($entity_type, $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...
512
    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...
513
      $entity->delete();
514
    }
515
  }
516
517
  /**
518
   * {@inheritdoc}
519
   */
520
  public function startCollectingMail() {
521
    $config = \Drupal::configFactory()->getEditable('system.mail');
522
    $data = $config->getRawData();
523
524
    // Save the values for restoration after.
525
    $this->storeOriginalConfiguration('system.mail', $data);
526
527
    // @todo Use a collector that supports html after D#2223967 lands.
528
    $data['interface'] = ['default' => 'test_mail_collector'];
529
    $config->setData($data)->save();
530
    // Disable the mail system module's mail if enabled.
531
    $this->startCollectingMailSystemMail();
532
  }
533
534
  /**
535
   * {@inheritdoc}
536
   */
537
  public function stopCollectingMail() {
538
    $config = \Drupal::configFactory()->getEditable('system.mail');
539
    $config->setData($this->originalConfiguration['system.mail'])->save();
540
    // Re-enable the mailsystem module's mail if enabled.
541
    $this->stopCollectingMailSystemMail();
542
  }
543
544
  /**
545
   * {@inheritdoc}
546
   */
547
  public function getMail() {
548
    \Drupal::state()->resetCache();
549
    $mail = \Drupal::state()->get('system.test_mail_collector') ?: [];
550
    // Discard cancelled mail.
551
    $mail = array_values(array_filter($mail, function ($mailItem) {
552
      return ($mailItem['send'] == TRUE);
553
    }));
554
    return $mail;
555
  }
556
557
  /**
558
   * {@inheritdoc}
559
   */
560
  public function clearMail() {
561
    \Drupal::state()->set('system.test_mail_collector', []);
562
  }
563
564
  /**
565
   * {@inheritdoc}
566
   */
567
  public function sendMail($body = '', $subject = '', $to = '', $langcode = '') {
568
    // Send the mail, via the system module's hook_mail.
569
    $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...
570
    $params['context']['subject'] = $subject;
571
    $mailManager = \Drupal::service('plugin.manager.mail');
572
    $result = $mailManager->mail('system', '', $to, $langcode, $params, NULL, TRUE);
573
    return $result;
574
  }
575
576
  /**
577
   * If the Mail System module is enabled, collect that mail too.
578
   *
579
   * @see MailsystemManager::getPluginInstance()
580
   */
581
  protected function startCollectingMailSystemMail() {
582
    if (\Drupal::moduleHandler()->moduleExists('mailsystem')) {
583
      $config = \Drupal::configFactory()->getEditable('mailsystem.settings');
584
      $data = $config->getRawData();
585
586
      // Track original data for restoration.
587
      $this->storeOriginalConfiguration('mailsystem.settings', $data);
588
589
      // Convert all of the 'senders' to the test collector.
590
      $data = $this->findMailSystemSenders($data);
591
      $config->setData($data)->save();
592
    }
593
  }
594
595
  /**
596
   * Find and replace all the mail system sender plugins with the test plugin.
597
   *
598
   * This method calls itself recursively.
599
   */
600
  protected function findMailSystemSenders(array $data) {
601
    foreach ($data as $key => $values) {
602
      if (is_array($values)) {
603
        if (isset($values[MailsystemManager::MAILSYSTEM_TYPE_SENDING])) {
604
          $data[$key][MailsystemManager::MAILSYSTEM_TYPE_SENDING] = 'test_mail_collector';
605
        }
606
        else {
607
          $data[$key] = $this->findMailSystemSenders($values);
608
        }
609
      }
610
    }
611
    return $data;
612
  }
613
614
  /**
615
   * If the Mail System module is enabled, stop collecting those mails.
616
   */
617
  protected function stopCollectingMailSystemMail() {
618
    if (\Drupal::moduleHandler()->moduleExists('mailsystem')) {
619
      \Drupal::configFactory()->getEditable('mailsystem.settings')->setData($this->originalConfiguration['mailsystem.settings'])->save();
620
    }
621
  }
622
623
  /**
624
   * {@inheritdoc}
625
   */
626
  public function login(\stdClass $user) {
627
    $account = User::load($user->uid);
628
    \Drupal::service('account_switcher')->switchTo($account);
629
  }
630
631
  /**
632
   * {@inheritdoc}
633
   */
634
  public function logout() {
635
    try {
636
      while (TRUE) {
637
        \Drupal::service('account_switcher')->switchBack();
638
      }
639
    }
640
    catch (\RuntimeException $e) {
641
      // No more users are logged in.
642
    }
643
  }
644
645
  /**
646
   * Store the original value for a piece of configuration.
647
   *
648
   * If an original value has previously been stored, it is not updated.
649
   *
650
   * @param string $name
651
   *   The name of the configuration.
652
   * @param mixed $value
653
   *   The original value of the configuration.
654
   */
655
  protected function storeOriginalConfiguration($name, $value) {
656
    if (!isset($this->originalConfiguration[$name])) {
657
      $this->originalConfiguration[$name] = $value;
658
    }
659
  }
660
661
}
662