Completed
Pull Request — master (#85)
by
unknown
02:28
created

Drupal7::termLoad()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 2
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 nodeLoad($nid) {
43
    return node_load($nid);
44
  }
45
46
  /**
47
   * {@inheritdoc}
48
   */
49
  public function nodeCreate($node) {
50
    // Set original if not set.
51
    if (!isset($node->original)) {
52
      $node->original = clone $node;
53
    }
54
55
    // Assign authorship if none exists and `author` is passed.
56 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...
57
      $node->uid = $user->uid;
58
    }
59
60
    // Convert properties to expected structure.
61
    $this->expandEntityProperties($node);
62
63
    // Attempt to decipher any fields that may be specified.
64
    $this->expandEntityFields('node', $node);
65
66
    // Set defaults that haven't already been set.
67
    $defaults = clone $node;
68
    node_object_prepare($defaults);
69
    $node = (object) array_merge((array) $defaults, (array) $node);
70
71
    node_save($node);
72
    return $node;
73
  }
74
75
  /**
76
   * {@inheritdoc}
77
   */
78
  public function nodeDelete($node) {
79
    return node_delete($node->nid);
80
  }
81
82
  /**
83
   * {@inheritdoc}
84
   */
85
  public function nodeDeleteMultiple(array $nids) {
86
    return node_delete_multiple($nids);
87
  }
88
89
  /**
90
   * {@inheritdoc}
91
   *
92
   * @param object $node
93
   *   A drupal node object.
94
   * @param object $values
95
   *   An object with field/value parameters.
96
   */
97
  public function nodeAlter($node, $values) {
98 View Code Duplication
    if (empty($node) || !isset($node->nid)) {
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...
99
      throw new \Exception(sprintf("%s::%s: Node was empty or had no id", get_class($this), __FUNCTION__));
100
    }
101
    // Assign type (really, bundle) to values so that expansion functions will
102
    // work properly.
103
    $values->type = $node->type;
104
    // Reload node object to ensure only passed values get overwritten.
105
    // $node = node_load($node->nid, TRUE);.
106
    $this->expandEntityProperties($values);
107
108
    // Attempt to decipher any fields that may be specified.
109
    $this->expandEntityFields('node', $values);
110 View Code Duplication
    foreach ($values as $k => $v) {
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...
111
      if (!property_exists($node, $k)) {
112
        throw new \Exception(sprintf("%s::%s line %s: Attempt to modify an invalid field: %s", get_class($this), __LINE__, __FUNCTION__, $k));
113
      }
114
      $node->{$k} = $v;
115
    }
116
    node_save($node);
117
  }
118
119
  /**
120
   * Implements CoreInterface::runCron().
121
   */
122
  public function runCron() {
123
    return drupal_cron_run();
124
  }
125
126
  /**
127
   * {@inheritdoc}
128
   */
129
  public function userLoad($uid) {
130
    return user_load($uid);
131
  }
132
133
  /**
134
   * {@inheritdoc}
135
   */
136
  public function userCreate(\stdClass $user) {
137
    // Default status to TRUE if not explicitly creating a blocked user.
138
    if (!isset($user->status)) {
139
      $user->status = 1;
140
    }
141
    if (isset($user->roles) && is_string($user->roles)) {
142
      $user->roles = array_map('trim', explode(',', $user->roles));
143
    }
144
    // Clone user object, otherwise user_save() changes the password to the
145
    // hashed password.
146
    $account = clone $user;
147
148
    // Attempt to decipher any fields that may be specified.
149
    $this->expandEntityFields('user', $account);
150
151
    user_save($account, (array) $account);
152
153
    // Store UID.
154
    $user->uid = $account->uid;
155
  }
156
157
  /**
158
   * {@inheritdoc}
159
   *
160
   * @param object $user
161
   *   A drupal user object.
162
   * @param object $values
163
   *   An object with field/value parameters.
164
   */
165
  public function userAlter($user, $values) {
166
    if (empty($user) || !isset($user->uid)) {
167
      var_dump(array_keys(get_object_vars($user)));
0 ignored issues
show
Security Debugging Code introduced by
var_dump(array_keys(get_object_vars($user))); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
168
      throw new \Exception(sprintf("%s::%s: User was empty or had no id", get_class($this), __FUNCTION__));
169
    }
170
    // Reload user from the db so we ensure we're dealing with an unmodified
171
    // version of the user.  Reset flag is critical here.
172
    $user = user_load($user->uid, TRUE);
173
    // Attempt to decipher any fields that may be specified in values.
174
    $this->expandEntityFields('user', $values);
175 View Code Duplication
    foreach ($values as $k => $v) {
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...
176
      if (!property_exists($user, $k)) {
177
        throw new \Exception(sprintf("%s::%s line %s: Attempt to modify an invalid field: %s", get_class($this), __LINE__, __FUNCTION__, $k));
178
      }
179
      $user->{$k} = $v;
180
    }
181
    user_save($user);
182
  }
183
184
  /**
185
   * {@inheritdoc}
186
   */
187
  public function userDelete(\stdClass $user) {
188
    user_cancel(array(), $user->uid, 'user_cancel_delete');
189
  }
190
191
  /**
192
   * {@inheritdoc}
193
   */
194
  public function userDeleteMultiple(array $uids) {
195
    user_delete_multiple($uids);
196
  }
197
198
  /**
199
   * {@inheritdoc}
200
   */
201
  public function processBatch() {
202
    $batch =& batch_get();
203
    $batch['progressive'] = FALSE;
204
    batch_process();
205
  }
206
207
  /**
208
   * {@inheritdoc}
209
   */
210
  public function userAddRole(\stdClass $user, $role_name) {
211
    $role = user_role_load_by_name($role_name);
212
213
    if (!$role) {
214
      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
215
    }
216
217
    user_multiple_role_edit(array($user->uid), 'add_role', $role->rid);
218
    $account = user_load($user->uid);
219
    $user->roles = $account->roles;
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
   * @param bool $reset
229
   *   Reset cached available permissions.
230
   *
231
   * @return bool
232
   *   TRUE or FALSE depending on whether the permissions are valid.
233
   */
234
  protected function checkPermissions(array $permissions, $reset = FALSE) {
235
    $available = &drupal_static(__FUNCTION__);
236
237
    if (!isset($available) || $reset) {
238
      $available = array_keys(module_invoke_all('permission'));
239
    }
240
241
    $valid = TRUE;
242
    foreach ($permissions as $permission) {
243
      if (!in_array($permission, $available)) {
244
        $valid = FALSE;
245
      }
246
    }
247
    return $valid;
248
  }
249
250
  /**
251
   * {@inheritdoc}
252
   */
253
  public function roleCreate(array $permissions) {
254
255
    // Both machine name and permission title are allowed.
256
    $all_permissions = $this->getAllPermissions();
257
258
    foreach ($permissions as $key => $name) {
259
      if (!isset($all_permissions[$name])) {
260
        $search = array_search($name, $all_permissions);
261
        if (!$search) {
262
          throw new \RuntimeException(sprintf("No permission '%s' exists.", $name));
263
        }
264
        $permissions[$key] = $search;
265
      }
266
    }
267
268
    // Create new role.
269
    $role = new \stdClass();
270
    $role->name = $this->random->name(8);
271
    user_role_save($role);
272
    user_role_grant_permissions($role->rid, $permissions);
273
274
    if ($role && !empty($role->rid)) {
275
      return $role->name;
276
    }
277
278
    throw new \RuntimeException(sprintf('Failed to create a role with "" permission(s).', implode(', ', $permissions)));
279
  }
280
281
  /**
282
   * {@inheritdoc}
283
   */
284
  public function roleDelete($role_name) {
285
    $role = user_role_load_by_name($role_name);
286
    user_role_delete((int) $role->rid);
287
  }
288
289
  /**
290
   * {@inheritdoc}
291
   */
292 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...
293
    if ('default' !== $this->uri) {
294
      // Fake the necessary HTTP headers that Drupal needs:
295
      $drupal_base_url = parse_url($this->uri);
296
      // If there's no url scheme set, add http:// and re-parse the url
297
      // so the host and path values are set accurately.
298
      if (!array_key_exists('scheme', $drupal_base_url)) {
299
        $drupal_base_url = parse_url($this->uri);
300
      }
301
      // Fill in defaults.
302
      $drupal_base_url += array(
303
        'path' => NULL,
304
        'host' => NULL,
305
        'port' => NULL,
306
      );
307
      $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
308
309
      if ($drupal_base_url['port']) {
310
        $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
311
      }
312
      $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
313
314
      if (array_key_exists('path', $drupal_base_url)) {
315
        $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
316
      }
317
      else {
318
        $_SERVER['PHP_SELF'] = '/index.php';
319
      }
320
    }
321
    else {
322
      $_SERVER['HTTP_HOST'] = 'default';
323
      $_SERVER['PHP_SELF'] = '/index.php';
324
    }
325
326
    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
327
    $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
328
    $_SERVER['REQUEST_METHOD']  = NULL;
329
330
    $_SERVER['SERVER_SOFTWARE'] = NULL;
331
    $_SERVER['HTTP_USER_AGENT'] = NULL;
332
333
    $conf_path = conf_path(TRUE, TRUE);
334
    $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
335
    if (!file_exists($conf_file)) {
336
      throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
337
    }
338
    $drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php";
339
    if (file_exists($drushrc_file)) {
340
      require_once $drushrc_file;
341
    }
342
  }
343
344
  /**
345
   * Expands properties on the given entity object to the expected structure.
346
   *
347
   * @param \stdClass $entity
348
   *   The entity object.
349
   */
350
  protected function expandEntityProperties(\stdClass $entity) {
351 View Code Duplication
    if (!isset($entity->type)) {
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...
352
      throw new \Exception(sprintf("%s::%s line %s: Entity argument is missing a value for the key 'type'", get_class($this), __FUNCTION__, __LINE__));
353
    }
354
    // The created field may come in as a readable date, rather than a
355
    // timestamp.
356
    if (isset($entity->created) && !is_numeric($entity->created)) {
357
      $entity->created = strtotime($entity->created);
358
    }
359
360
    // Map human-readable node types to machine node types.
361
    $types = \node_type_get_types();
362
    foreach ($types as $type) {
363
      if ($entity->type == $type->name) {
364
        $entity->type = $type->type;
365
        continue;
366
      }
367
    }
368
  }
369
370
  /**
371
   * {@inheritdoc}
372
   */
373
  public function termLoad($tid, $vocabulary = NULL) {
374
    if (is_numeric($tid)) {
375
      return taxonomy_term_load($tid);
376
    }
377
    return taxonomy_get_term_by_name($tid, $vocabulary);
378
  }
379
380
  /**
381
   * {@inheritdoc}
382
   */
383
  public function termCreate(\stdClass $term) {
384
    // Map vocabulary names to vid, these take precedence over machine names.
385 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...
386
      $vocabularies = \taxonomy_get_vocabularies();
387
      foreach ($vocabularies as $vid => $vocabulary) {
388
        if ($vocabulary->name == $term->vocabulary_machine_name) {
389
          $term->vid = $vocabulary->vid;
390
        }
391
      }
392
    }
393
394
    if (!isset($term->vid)) {
395
396
      // Try to load vocabulary by machine name.
397
      $vocabularies = \taxonomy_vocabulary_load_multiple(FALSE, array(
398
        'machine_name' => $term->vocabulary_machine_name,
399
      ));
400
      if (!empty($vocabularies)) {
401
        $vids = array_keys($vocabularies);
402
        $term->vid = reset($vids);
403
      }
404
    }
405
406
    // If `parent` is set, look up a term in this vocab with that name.
407 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...
408
      $parent = \taxonomy_get_term_by_name($term->parent, $term->vocabulary_machine_name);
409
      if (!empty($parent)) {
410
        $parent = reset($parent);
411
        $term->parent = $parent->tid;
412
      }
413
    }
414
415
    if (empty($term->vid)) {
416
      throw new \Exception(sprintf('%s::%s line %s: Could not load term.', get_class($this), __FUNCTION__, __LINE__));
417
    }
418
419
    // Attempt to decipher any fields that may be specified.
420
    $this->expandEntityFields('taxonomy_term', $term);
421
422
    \taxonomy_term_save($term);
423
424
    return $term;
425
  }
426
427
  /**
428
   * {@inheritdoc}
429
   */
430
  public function termDelete(\stdClass $term) {
431
    $status = 0;
432
    if (isset($term->tid)) {
433
      $status = \taxonomy_term_delete($term->tid);
434
    }
435
    // Will be SAVED_DELETED (3) on success.
436
    return $status;
437
  }
438
439
  /**
440
   * {@inheritdoc}
441
   */
442
  public function languageCreate(\stdClass $language) {
443
    if (!module_exists('locale')) {
444
      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__));
445
    }
446
    include_once DRUPAL_ROOT . '/includes/iso.inc';
447
    include_once DRUPAL_ROOT . '/includes/locale.inc';
448
    // Get all predefined languages, regardless if they are enabled or not.
449
    $predefined_languages = _locale_get_predefined_list();
450
451
    // If the language code is not valid then throw an InvalidArgumentException.
452
    if (!isset($predefined_languages[$language->langcode])) {
453
      throw new InvalidArgumentException("There is no predefined language with langcode '{$language->langcode}'.");
454
    }
455
456
    // Enable a language only if it has not been enabled already.
457
    $enabled_languages = locale_language_list();
458
    if (!isset($enabled_languages[$language->langcode])) {
459
      locale_add_language($language->langcode);
460
      return $language;
461
    }
462
463
    return FALSE;
464
  }
465
466
  /**
467
   * {@inheritdoc}
468
   */
469
  public function languageDelete(\stdClass $language) {
470
    $langcode = $language->langcode;
471
    // Do not remove English or the default language.
472
    if (!in_array($langcode, array(language_default('language'), 'en'))) {
473
      // @see locale_languages_delete_form_submit().
474
      $languages = language_list();
475
      if (isset($languages[$langcode])) {
476
        // Remove translations first.
477
        db_delete('locales_target')
478
          ->condition('language', $langcode)
479
          ->execute();
480
        cache_clear_all('locale:' . $langcode, 'cache');
481
        // With no translations, this removes existing JavaScript translations
482
        // file.
483
        _locale_rebuild_js($langcode);
484
        // Remove the language.
485
        db_delete('languages')
486
          ->condition('language', $langcode)
487
          ->execute();
488
        db_update('node')
489
          ->fields(array('language' => ''))
490
          ->condition('language', $langcode)
491
          ->execute();
492
        if ($languages[$langcode]->enabled) {
493
          variable_set('language_count', variable_get('language_count', 1) - 1);
494
        }
495
        module_invoke_all('multilingual_settings_changed');
496
        drupal_static_reset('language_list');
497
      }
498
499
      // Changing the language settings impacts the interface:
500
      cache_clear_all('*', 'cache_page', TRUE);
501
    }
502
  }
503
504
  /**
505
   * {@inheritdoc}
506
   */
507
  public function configGet($name, $key = '') {
508
    throw new \Exception('Getting config is not yet implemented for Drupal 7.');
509
  }
510
511
  /**
512
   * {@inheritdoc}
513
   */
514
  public function configSet($name, $key, $value) {
515
    throw new \Exception('Setting config is not yet implemented for Drupal 7.');
516
  }
517
518
  /**
519
   * Helper function to get all permissions.
520
   *
521
   * @return array
522
   *   Array keyed by permission name, with the human-readable title as the
523
   *   value.
524
   */
525 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...
526
    $permissions = array();
527
    foreach (module_invoke_all('permission') as $name => $permission) {
528
      $permissions[$name] = $permission['title'];
529
    }
530
    return $permissions;
531
  }
532
533
  /**
534
   * {@inheritdoc}
535
   */
536
  public function getModuleList() {
537
    return module_list();
538
  }
539
540
  /**
541
   * {@inheritdoc}
542
   */
543 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...
544
    $paths = array();
545
546
    // Get enabled modules.
547
    $modules = $this->getModuleList();
548
    foreach ($modules as $module) {
549
      $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . \drupal_get_path('module', $module);
550
    }
551
552
    return $paths;
553
  }
554
555
  /**
556
   * {@inheritdoc}
557
   */
558
  public function getEntityFieldTypes($entity_type) {
559
    $return = array();
560
    $fields = field_info_field_map();
561
    foreach ($fields as $field_name => $field) {
562
      if (array_key_exists($entity_type, $field['bundles'])) {
563
        $return[$field_name] = $field['type'];
564
      }
565
    }
566
    return $return;
567
  }
568
569
  /**
570
   * {@inheritdoc}
571
   */
572
  public function isField($entity_type, $field_name) {
573
    $map = field_info_field_map();
574
    return !empty($map[$field_name]) && array_key_exists($entity_type, $map[$field_name]['bundles']);
575
  }
576
577
  /**
578
   * {@inheritdoc}
579
   */
580
  public function clearStaticCaches() {
581
    drupal_static_reset();
582
  }
583
584
}
585