Completed
Pull Request — master (#76)
by
unknown
02:19
created

Drupal7   C

Complexity

Total Complexity 72

Size/Duplication

Total Lines 474
Duplicated Lines 21.73 %

Coupling/Cohesion

Components 3
Dependencies 3

Importance

Changes 16
Bugs 4 Features 5
Metric Value
wmc 72
c 16
b 4
f 5
lcom 3
cbo 3
dl 103
loc 474
rs 5.5667

26 Methods

Rating   Name   Duplication   Size   Complexity  
A clearCache() 0 3 1
A nodeDelete() 0 3 1
A runCron() 0 3 1
A userDelete() 0 3 1
A roleDelete() 0 4 1
A bootstrap() 0 16 3
B nodeCreate() 3 25 5
A userCreate() 0 18 2
A processBatch() 0 5 1
A userAddRole() 0 12 2
B checkPermissions() 0 15 5
B roleCreate() 0 27 6
C validateDrupalSite() 51 51 7
B expandEntityProperties() 16 16 5
D termCreate() 15 43 9
A termDelete() 0 8 2
A languageCreate() 0 21 3
B languageDelete() 0 34 4
A configGet() 0 3 1
A configSet() 0 3 1
A getAllPermissions() 7 7 2
A getModuleList() 0 3 1
A getExtensionPathList() 11 11 2
A getEntityFieldTypes() 0 10 3
A isField() 0 4 2
A clearStaticCaches() 0 3 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Drupal7 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Drupal7, and based on these observations, apply Extract Interface, too.

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