Completed
Pull Request — master (#85)
by
unknown
07:39
created

Drupal7::nodeAlter()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 4
Ratio 20 %

Importance

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