Completed
Push — master ( ef3bca...8ad209 )
by Jonathan
02:53 queued 01:19
created

Drupal7::startCollectingMail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Drupal\Driver\Cores;
4
5
use Drupal\Driver\Exception\BootstrapException;
6
7
/**
8
 * Drupal 7 core.
9
 */
10
class Drupal7 extends AbstractCore {
11
12
  /**
13
   * {@inheritdoc}
14
   */
15
  public function bootstrap() {
16
    // Validate, and prepare environment for Drupal bootstrap.
17 View Code Duplication
    if (!defined('DRUPAL_ROOT')) {
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...
18
      define('DRUPAL_ROOT', $this->drupalRoot);
19
      require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
20
      $this->validateDrupalSite();
21
    }
22
23
    // Bootstrap Drupal.
24
    chdir(DRUPAL_ROOT);
25
    drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
26
    if (empty($GLOBALS['databases'])) {
27
      throw new BootstrapException('Missing database setting, verify the database configuration in settings.php.');
28
    }
29
    drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
30
  }
31
32
  /**
33
   * {@inheritdoc}
34
   */
35
  public function clearCache() {
36
    drupal_flush_all_caches();
37
  }
38
39
  /**
40
   * {@inheritdoc}
41
   */
42
  public function nodeCreate($node) {
43
    // Set original if not set.
44
    if (!isset($node->original)) {
45
      $node->original = clone $node;
46
    }
47
48
    // Assign authorship if none exists and `author` is passed.
49 View Code Duplication
    if (!isset($node->uid) && !empty($node->author) && ($user = user_load_by_name($node->author))) {
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...
50
      $node->uid = $user->uid;
51
    }
52
53
    // Convert properties to expected structure.
54
    $this->expandEntityProperties($node);
55
56
    // Attempt to decipher any fields that may be specified.
57
    $this->expandEntityFields('node', $node);
58
59
    // Set defaults that haven't already been set.
60
    $defaults = clone $node;
61
    node_object_prepare($defaults);
62
    $node = (object) array_merge((array) $defaults, (array) $node);
63
64
    node_save($node);
65
    return $node;
66
  }
67
68
  /**
69
   * {@inheritdoc}
70
   */
71
  public function nodeDelete($node) {
72
    node_delete($node->nid);
73
  }
74
75
  /**
76
   * Implements CoreInterface::runCron().
77
   */
78
  public function runCron() {
79
    return drupal_cron_run();
80
  }
81
82
  /**
83
   * {@inheritdoc}
84
   */
85
  public function userCreate(\stdClass $user) {
86
    // Default status to TRUE if not explicitly creating a blocked user.
87
    if (!isset($user->status)) {
88
      $user->status = 1;
89
    }
90
91
    // Clone user object, otherwise user_save() changes the password to the
92
    // hashed password.
93
    $account = clone $user;
94
95
    // Attempt to decipher any fields that may be specified.
96
    $this->expandEntityFields('user', $account);
97
98
    user_save($account, (array) $account);
99
100
    // Store UID.
101
    $user->uid = $account->uid;
102
  }
103
104
  /**
105
   * {@inheritdoc}
106
   */
107
  public function userDelete(\stdClass $user) {
108
    user_cancel(array(), $user->uid, 'user_cancel_delete');
109
  }
110
111
  /**
112
   * {@inheritdoc}
113
   */
114
  public function processBatch() {
115
    $batch =& batch_get();
116
    $batch['progressive'] = FALSE;
117
    batch_process();
118
  }
119
120
  /**
121
   * {@inheritdoc}
122
   */
123
  public function userAddRole(\stdClass $user, $role_name) {
124
    $role = user_role_load_by_name($role_name);
125
126
    if (!$role) {
127
      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
128
    }
129
130
    user_multiple_role_edit(array($user->uid), 'add_role', $role->rid);
131
    $account = user_load($user->uid);
132
    $user->roles = $account->roles;
133
134
  }
135
136
  /**
137
   * Check to make sure that the array of permissions are valid.
138
   *
139
   * @param array $permissions
140
   *   Permissions to check.
141
   * @param bool $reset
142
   *   Reset cached available permissions.
143
   *
144
   * @return bool
145
   *   TRUE or FALSE depending on whether the permissions are valid.
146
   */
147
  protected function checkPermissions(array $permissions, $reset = FALSE) {
148
    $available = &drupal_static(__FUNCTION__);
149
150
    if (!isset($available) || $reset) {
151
      $available = array_keys(module_invoke_all('permission'));
152
    }
153
154
    $valid = TRUE;
155
    foreach ($permissions as $permission) {
156
      if (!in_array($permission, $available)) {
157
        $valid = FALSE;
158
      }
159
    }
160
    return $valid;
161
  }
162
163
  /**
164
   * {@inheritdoc}
165
   */
166
  public function roleCreate(array $permissions) {
167
168
    // Both machine name and permission title are allowed.
169
    $all_permissions = $this->getAllPermissions();
170
171
    foreach ($permissions as $key => $name) {
172
      if (!isset($all_permissions[$name])) {
173
        $search = array_search($name, $all_permissions);
174
        if (!$search) {
175
          throw new \RuntimeException(sprintf("No permission '%s' exists.", $name));
176
        }
177
        $permissions[$key] = $search;
178
      }
179
    }
180
181
    // Create new role.
182
    $role = new \stdClass();
183
    $role->name = $this->random->name(8);
184
    user_role_save($role);
185
    user_role_grant_permissions($role->rid, $permissions);
186
187
    if ($role && !empty($role->rid)) {
188
      return $role->name;
189
    }
190
191
    throw new \RuntimeException(sprintf('Failed to create a role with "" permission(s).', implode(', ', $permissions)));
192
  }
193
194
  /**
195
   * {@inheritdoc}
196
   */
197
  public function roleDelete($role_name) {
198
    $role = user_role_load_by_name($role_name);
199
    user_role_delete((int) $role->rid);
200
  }
201
202
  /**
203
   * {@inheritdoc}
204
   */
205 View Code Duplication
  public function validateDrupalSite() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
206
    if ('default' !== $this->uri) {
207
      // Fake the necessary HTTP headers that Drupal needs:
208
      $drupal_base_url = parse_url($this->uri);
209
      // If there's no url scheme set, add http:// and re-parse the url
210
      // so the host and path values are set accurately.
211
      if (!array_key_exists('scheme', $drupal_base_url)) {
212
        $drupal_base_url = parse_url($this->uri);
213
      }
214
      // Fill in defaults.
215
      $drupal_base_url += array(
216
        'path' => NULL,
217
        'host' => NULL,
218
        'port' => NULL,
219
      );
220
      $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
221
222
      if ($drupal_base_url['port']) {
223
        $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
224
      }
225
      $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
226
227
      if (array_key_exists('path', $drupal_base_url)) {
228
        $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
229
      }
230
      else {
231
        $_SERVER['PHP_SELF'] = '/index.php';
232
      }
233
    }
234
    else {
235
      $_SERVER['HTTP_HOST'] = 'default';
236
      $_SERVER['PHP_SELF'] = '/index.php';
237
    }
238
239
    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
240
    $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
241
    $_SERVER['REQUEST_METHOD'] = NULL;
242
243
    $_SERVER['SERVER_SOFTWARE'] = NULL;
244
    $_SERVER['HTTP_USER_AGENT'] = NULL;
245
246
    $conf_path = conf_path(TRUE, TRUE);
247
    $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
248
    if (!file_exists($conf_file)) {
249
      throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
250
    }
251
    $drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php";
252
    if (file_exists($drushrc_file)) {
253
      require_once $drushrc_file;
254
    }
255
  }
256
257
  /**
258
   * Expands properties on the given entity object to the expected structure.
259
   *
260
   * @param \stdClass $entity
261
   *   The entity object.
262
   */
263 View Code Duplication
  protected function expandEntityProperties(\stdClass $entity) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
264
    // The created field may come in as a readable date, rather than a
265
    // timestamp.
266
    if (isset($entity->created) && !is_numeric($entity->created)) {
267
      $entity->created = strtotime($entity->created);
268
    }
269
270
    // Map human-readable node types to machine node types.
271
    $types = \node_type_get_types();
272
    foreach ($types as $type) {
273
      if ($entity->type == $type->name) {
274
        $entity->type = $type->type;
275
        continue;
276
      }
277
    }
278
  }
279
280
  /**
281
   * {@inheritdoc}
282
   */
283
  public function termCreate(\stdClass $term) {
284
    // Map vocabulary names to vid, these take precedence over machine names.
285 View Code Duplication
    if (!isset($term->vid)) {
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...
286
      $vocabularies = \taxonomy_get_vocabularies();
287
      foreach ($vocabularies as $vid => $vocabulary) {
288
        if ($vocabulary->name == $term->vocabulary_machine_name) {
289
          $term->vid = $vocabulary->vid;
290
        }
291
      }
292
    }
293
294
    if (!isset($term->vid)) {
295
296
      // Try to load vocabulary by machine name.
297
      $vocabularies = \taxonomy_vocabulary_load_multiple(FALSE, array(
298
        'machine_name' => $term->vocabulary_machine_name,
299
      ));
300
      if (!empty($vocabularies)) {
301
        $vids = array_keys($vocabularies);
302
        $term->vid = reset($vids);
303
      }
304
    }
305
306
    // If `parent` is set, look up a term in this vocab with that name.
307 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...
308
      $parent = \taxonomy_get_term_by_name($term->parent, $term->vocabulary_machine_name);
309
      if (!empty($parent)) {
310
        $parent = reset($parent);
311
        $term->parent = $parent->tid;
312
      }
313
    }
314
315
    if (empty($term->vid)) {
316
      throw new \Exception(sprintf('No "%s" vocabulary found.'));
317
    }
318
319
    // Attempt to decipher any fields that may be specified.
320
    $this->expandEntityFields('taxonomy_term', $term);
321
322
    \taxonomy_term_save($term);
323
324
    return $term;
325
  }
326
327
  /**
328
   * {@inheritdoc}
329
   */
330
  public function termDelete(\stdClass $term) {
331
    $status = 0;
332
    if (isset($term->tid)) {
333
      $status = \taxonomy_term_delete($term->tid);
334
    }
335
    // Will be SAVED_DELETED (3) on success.
336
    return $status;
337
  }
338
339
  /**
340
   * {@inheritdoc}
341
   */
342
  public function languageCreate(\stdClass $language) {
343
    if (!module_exists('locale')) {
344
      throw new \Exception(sprintf("%s::%s line %s: This driver requires the 'locale' module be enabled in order to create languages", get_class($this), __FUNCTION__, __LINE__));
345
    }
346
    include_once DRUPAL_ROOT . '/includes/iso.inc';
347
    include_once DRUPAL_ROOT . '/includes/locale.inc';
348
349
    // Get all predefined languages, regardless if they are enabled or not.
350
    $predefined_languages = _locale_get_predefined_list();
351
352
    // If the language code is not valid then throw an InvalidArgumentException.
353
    if (!isset($predefined_languages[$language->langcode])) {
354
      throw new InvalidArgumentException("There is no predefined language with langcode '{$language->langcode}'.");
355
    }
356
357
    // Enable a language only if it has not been enabled already.
358
    $enabled_languages = locale_language_list();
359
    if (!isset($enabled_languages[$language->langcode])) {
360
      locale_add_language($language->langcode);
361
      return $language;
362
    }
363
364
    return FALSE;
365
  }
366
367
  /**
368
   * {@inheritdoc}
369
   */
370
  public function languageDelete(\stdClass $language) {
371
    $langcode = $language->langcode;
372
    // Do not remove English or the default language.
373
    if (!in_array($langcode, array(language_default('language'), 'en'))) {
374
      // @see locale_languages_delete_form_submit().
375
      $languages = language_list();
376
      if (isset($languages[$langcode])) {
377
        // Remove translations first.
378
        db_delete('locales_target')
379
          ->condition('language', $langcode)
380
          ->execute();
381
        cache_clear_all('locale:' . $langcode, 'cache');
382
        // With no translations, this removes existing JavaScript translations
383
        // file.
384
        _locale_rebuild_js($langcode);
385
        // Remove the language.
386
        db_delete('languages')
387
          ->condition('language', $langcode)
388
          ->execute();
389
        db_update('node')
390
          ->fields(array('language' => ''))
391
          ->condition('language', $langcode)
392
          ->execute();
393
        if ($languages[$langcode]->enabled) {
394
          variable_set('language_count', variable_get('language_count', 1) - 1);
395
        }
396
        module_invoke_all('multilingual_settings_changed');
397
        drupal_static_reset('language_list');
398
      }
399
400
      // Changing the language settings impacts the interface:
401
      cache_clear_all('*', 'cache_page', TRUE);
402
    }
403
  }
404
405
  /**
406
   * {@inheritdoc}
407
   */
408
  public function configGet($name, $key = '') {
409
    throw new \Exception('Getting config is not yet implemented for Drupal 7.');
410
  }
411
412
  /**
413
   * {@inheritdoc}
414
   */
415
  public function configSet($name, $key, $value) {
416
    throw new \Exception('Setting config is not yet implemented for Drupal 7.');
417
  }
418
419
  /**
420
   * Helper function to get all permissions.
421
   *
422
   * @return array
423
   *   Array keyed by permission name, with the human-readable title as the
424
   *   value.
425
   */
426 View Code Duplication
  protected function getAllPermissions() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
427
    $permissions = array();
428
    foreach (module_invoke_all('permission') as $name => $permission) {
429
      $permissions[$name] = $permission['title'];
430
    }
431
    return $permissions;
432
  }
433
434
  /**
435
   * {@inheritdoc}
436
   */
437
  public function getModuleList() {
438
    return module_list();
439
  }
440
441
  /**
442
   * {@inheritdoc}
443
   */
444 View Code Duplication
  public function getExtensionPathList() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
445
    $paths = array();
446
447
    // Get enabled modules.
448
    $modules = $this->getModuleList();
449
    foreach ($modules as $module) {
450
      $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . \drupal_get_path('module', $module);
451
    }
452
453
    return $paths;
454
  }
455
456
  /**
457
   * {@inheritdoc}
458
   */
459
  public function getEntityFieldTypes($entity_type, array $base_fields = array()) {
460
    $return = array();
461
    $fields = field_info_field_map();
462
    foreach ($fields as $field_name => $field) {
463
      if (array_key_exists($entity_type, $field['bundles'])) {
464
        $return[$field_name] = $field['type'];
465
      }
466
    }
467
    return $return;
468
  }
469
470
  /**
471
   * {@inheritdoc}
472
   */
473
  public function isField($entity_type, $field_name) {
474
    $map = field_info_field_map();
475
    return !empty($map[$field_name]) && array_key_exists($entity_type, $map[$field_name]['bundles']);
476
  }
477
478
  /**
479
   * {@inheritdoc}
480
   */
481
  public function clearStaticCaches() {
482
    drupal_static_reset();
483
  }
484
485
  /**
486
   * {@inheritdoc}
487
   */
488
  public function entityCreate($entity_type, $entity) {
489
    $info = entity_get_info($entity_type);
490
    // If the bundle field is empty, put the inferred bundle value in it.
491
    $bundle_key = $info['entity keys']['bundle'];
492 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...
493
      $entity->$bundle_key = $entity->step_bundle;
494
    }
495
496
    // Throw an exception if a bundle is specified but does not exist.
497 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...
498
      $bundles = $info['bundles'];
499
      if (!in_array($entity->$bundle_key, array_keys($bundles))) {
500
        throw new \Exception("Cannot create entity because provided bundle {$entity->$bundle_key} does not exist.");
501
      }
502
    }
503
    if (empty($entity_type)) {
504
      throw new \Exception("You must specify an entity type to create an entity.");
505
    }
506
507
    $this->expandEntityFields($entity_type, $entity);
508
    $createdEntity = entity_create($entity_type, (array) $entity);
509
510
    // In D7 it's possible that $createdEntity is not of class Entity, so we
511
    // must use entity_save().
512
    entity_save($entity_type, $createdEntity);
513
514
    list($id) = entity_extract_ids($entity_type, $createdEntity);
515
    $createdEntity->id = $id;
516
517
    return $createdEntity;
518
  }
519
520
  /**
521
   * {@inheritdoc}
522
   */
523
  public function entityDelete($entity_type, $entity) {
524
    // In D7 it's possible that $entity is not of class Entity, so we must use
525
    // entity_delete().
526
    list($id) = entity_extract_ids($entity_type, $entity);
527
    entity_delete($entity_type, $id);
528
  }
529
530
  /**
531
   * {@inheritdoc}
532
   */
533
  public function startCollectingMail() {
534
    // @todo: create a D7 version of this function
535
    throw new \Exception('Mail testing is not yet implemented for Drupal 7.');
536
  }
537
538
  /**
539
   * {@inheritdoc}
540
   */
541
  public function stopCollectingMail() {
542
    // @todo: create a D7 version of this function
543
    throw new \Exception('Mail testing is not yet implemented for Drupal 7.');
544
  }
545
546
  /**
547
   * {@inheritdoc}
548
   */
549
  public function getMail() {
550
    // @todo: create a D7 version of this function
551
    throw new \Exception('Mail testing is not yet implemented for Drupal 7.');
552
  }
553
554
  /**
555
   * {@inheritdoc}
556
   */
557
  public function clearMail() {
558
    // @todo: create a D7 version of this function
559
    throw new \Exception('Mail testing is not yet implemented for Drupal 7.');
560
  }
561
562
  /**
563
   * {@inheritdoc}
564
   */
565
  public function sendMail($body, $subject = '', $to = '', $langcode = '') {
566
    // @todo: create a D7 version of this function
567
    throw new \Exception('Mail testing is not yet implemented for Drupal 7.');
568
  }
569
570
}
571