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

Drupal7::nodeAlter()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 4
Ratio 20 %

Importance

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