Completed
Pull Request — master (#69)
by Pieter
02:08
created

Drupal6::uninstallModules()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 6
rs 9.4286
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
/**
4
 * @file
5
 * Contains \Drupal\Driver\Cores\Drupal6.
6
 */
7
8
namespace Drupal\Driver\Cores;
9
10
use Drupal\Driver\Exception\BootstrapException;
11
12
/**
13
 * Drupal 6 core.
14
 */
15
class Drupal6 extends AbstractCore {
16
17
  /**
18
   * The available permissions.
19
   *
20
   * @var array
21
   */
22
  protected $availablePermissons;
23
24
  /**
25
   * {@inheritdoc}
26
   */
27
  public function bootstrap() {
28
    // Validate, and prepare environment for Drupal bootstrap.
29 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...
30
      define('DRUPAL_ROOT', $this->drupalRoot);
31
      require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
32
      $this->validateDrupalSite();
33
    }
34
35
    // Bootstrap Drupal.
36
    $current_path = getcwd();
37
    chdir(DRUPAL_ROOT);
38
    drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
39
    if (empty($GLOBALS['db_url'])) {
40
      throw new BootstrapException('Missing database setting, verify the database configuration in settings.php.');
41
    }
42
    drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
43
    chdir($current_path);
44
  }
45
46
  /**
47
   * {@inheritdoc}
48
   */
49
  public function clearCache() {
50
    // Need to change into the Drupal root directory or the registry explodes.
51
    $current_path = getcwd();
52
    chdir(DRUPAL_ROOT);
53
    drupal_flush_all_caches();
54
    chdir($current_path);
55
  }
56
57
  /**
58
   * {@inheritdoc}
59
   */
60
  public function nodeCreate($node) {
61
    $current_path = getcwd();
62
    chdir(DRUPAL_ROOT);
63
64
    // Set original if not set.
65
    if (!isset($node->original)) {
66
      $node->original = clone $node;
67
    }
68
69
    // Assign authorship if none exists and `author` is passed.
70 View Code Duplication
    if (!isset($node->uid) && !empty($node->author) && ($user = user_load(array('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...
71
      $node->uid = $user->uid;
72
    }
73
74
    // Convert properties to expected structure.
75
    $this->expandEntityProperties($node);
76
77
    // Attempt to decipher any fields that may be specified.
78
    $this->expandEntityFields('node', $node);
79
80
    // Set defaults that haven't already been set.
81
    $defaults = clone $node;
82
    module_load_include('inc', 'node', 'node.pages');
83
    node_object_prepare($defaults);
84
    $node = (object) array_merge((array) $defaults, (array) $node);
85
86
    node_save($node);
87
88
    chdir($current_path);
89
    return $node;
90
91
  }
92
93
  /**
94
   * {@inheritdoc}
95
   */
96
  public function nodeDelete($node) {
97
    node_delete($node->nid);
98
  }
99
100
  /**
101
   * Implements CoreInterface::runCron().
102
   */
103
  public function runCron() {
104
    return drupal_cron_run();
105
  }
106
107
  /**
108
   * {@inheritdoc}
109
   */
110
  public function userCreate(\stdClass $user) {
111
    // Default status to TRUE if not explicitly creating a blocked user.
112
    if (!isset($user->status)) {
113
      $user->status = 1;
114
    }
115
116
    // Clone user object, otherwise user_save() changes the password to the
117
    // hashed password.
118
    $account = clone $user;
119
    // Convert role array to a keyed array.
120
    if (isset($user->roles)) {
121
      $roles = array();
122
      foreach ($user->roles as $rid) {
123
        $roles[$rid] = $rid;
124
      }
125
      $user->roles = $roles;
126
    }
127
    $account = user_save((array) $account, (array) $account);
128
    // Store the UID.
129
    $user->uid = $account->uid;
130
    return $user;
131
  }
132
133
  /**
134
   * {@inheritdoc}
135
   */
136
  public function userDelete(\stdClass $user) {
137
    $current_path = getcwd();
138
    chdir(DRUPAL_ROOT);
139
    user_delete((array) $user, $user->uid);
140
    chdir($current_path);
141
  }
142
143
  /**
144
   * {@inheritdoc}
145
   */
146
  public function processBatch() {
147
  }
148
149
  /**
150
   * {@inheritdoc}
151
   */
152
  public function userAddRole(\stdClass $user, $role_name) {
153
    $roles = array_flip(user_roles());
154
    $role = $roles[$role_name];
155
    if (!$role) {
156
      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
157
    }
158
    user_multiple_role_edit(array($user->uid), 'add_role', $role);
159
  }
160
161
  /**
162
   * Fetches a user role by role name.
163
   *
164
   * @param string $role_name
165
   *   A string representing the role name.
166
   *
167
   * @return object
168
   *   A fully-loaded role object if a role with the given name exists, or FALSE
169
   *   otherwise.
170
   *
171
   * @see user_role_load()
172
   */
173
  protected function userRoleLoadByName($role_name) {
174
    $result = db_query('SELECT * FROM {role} WHERE name = "%s"', $role_name);
175
    return db_fetch_object($result);
176
  }
177
178
  /**
179
   * Check to make sure that the array of permissions are valid.
180
   *
181
   * @param array $permissions
182
   *   Permissions to check.
183
   * @param bool $reset
184
   *   Reset cached available permissions.
185
   *
186
   * @return bool
187
   *   TRUE or FALSE depending on whether the permissions are valid.
188
   */
189
  protected function checkPermissions(array $permissions, $reset = FALSE) {
190
191
    if (!isset($this->availablePermissons) || $reset) {
192
      $this->availablePermissons = array_keys(module_invoke_all('permission'));
193
    }
194
195
    $valid = TRUE;
196
    foreach ($permissions as $permission) {
197
      if (!in_array($permission, $this->availablePermissons)) {
198
        $valid = FALSE;
199
      }
200
    }
201
    return $valid;
202
  }
203
204
  /**
205
   * {@inheritdoc}
206
   */
207
  public function roleCreate(array $permissions) {
208
    // Verify permissions exist.
209
    $all_permissions = module_invoke_all('perm');
210
    foreach ($permissions as $name) {
211
      $search = array_search($name, $all_permissions);
212
      if (!$search) {
213
        throw new \RuntimeException(sprintf("No permission '%s' exists.", $name));
214
      }
215
    }
216
    // Create new role.
217
    $name = $this->random->name(8);
218
    db_query("INSERT INTO {role} SET name = '%s'", $name);
219
    // Add permissions to role.
220
    $rid = db_last_insert_id('role', 'rid');
221
    db_query("INSERT INTO {permission} (rid, perm) VALUES (%d, '%s')", $rid, implode(', ', $permissions));
222
    return $name;
223
  }
224
225
  /**
226
   * {@inheritdoc}
227
   */
228
  public function roleDelete($role_name) {
229
    $roles = array_flip(user_roles());
230
    $rid = $roles[$role_name];
231
    db_query('DELETE FROM {role} WHERE rid = %d', $rid);
232
    if (!db_affected_rows()) {
233
      throw new \RuntimeException(sprintf('No role "%s" exists.', $rid));
234
    }
235
  }
236
237
  /**
238
   * {@inheritdoc}
239
   */
240 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...
241
    if ('default' !== $this->uri) {
242
      // Fake the necessary HTTP headers that Drupal needs:
243
      $drupal_base_url = parse_url($this->uri);
244
      // If there's no url scheme set, add http:// and re-parse the url
245
      // so the host and path values are set accurately.
246
      if (!array_key_exists('scheme', $drupal_base_url)) {
247
        $drupal_base_url = parse_url($this->uri);
248
      }
249
      // Fill in defaults.
250
      $drupal_base_url += array(
251
        'path' => NULL,
252
        'host' => NULL,
253
        'port' => NULL,
254
      );
255
      $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
256
257
      if ($drupal_base_url['port']) {
258
        $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
259
      }
260
      $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
261
262
      if (array_key_exists('path', $drupal_base_url)) {
263
        $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
264
      }
265
      else {
266
        $_SERVER['PHP_SELF'] = '/index.php';
267
      }
268
    }
269
    else {
270
      $_SERVER['HTTP_HOST'] = 'default';
271
      $_SERVER['PHP_SELF'] = '/index.php';
272
    }
273
274
    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
275
    $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
276
    $_SERVER['REQUEST_METHOD']  = NULL;
277
278
    $_SERVER['SERVER_SOFTWARE'] = NULL;
279
    $_SERVER['HTTP_USER_AGENT'] = NULL;
280
281
    $conf_path = conf_path(TRUE, TRUE);
282
    $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
283
    if (!file_exists($conf_file)) {
284
      throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
285
    }
286
    $drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php";
287
    if (file_exists($drushrc_file)) {
288
      require_once $drushrc_file;
289
    }
290
  }
291
292
  /**
293
   * Expands properties on the given entity object to the expected structure.
294
   *
295
   * @param \stdClass $entity
296
   *   The entity object.
297
   */
298 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...
299
    // The created field may come in as a readable date, rather than a
300
    // timestamp.
301
    if (isset($entity->created) && !is_numeric($entity->created)) {
302
      $entity->created = strtotime($entity->created);
303
    }
304
305
    // Map human-readable node types to machine node types.
306
    $types = node_get_types();
307
    foreach ($types as $type) {
308
      if ($entity->type == $type->name) {
309
        $entity->type = $type->type;
310
        continue;
311
      }
312
    }
313
  }
314
315
  /**
316
   * Load vocabularies, optional by VIDs.
317
   *
318
   * @param array $vids
319
   *   The vids to load.
320
   *
321
   * @return array
322
   *   An array of vocabulary objects
323
   */
324
  protected function taxonomyVocabularyLoadMultiple($vids = array()) {
325
    $vocabularies = taxonomy_get_vocabularies();
326
    if ($vids) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $vids of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
327
      return array_intersect_key($vocabularies, array_flip($vids));
328
    }
329
    return $vocabularies;
330
  }
331
332
  /**
333
   * {@inheritdoc}
334
   */
335
  public function termCreate(\stdClass $term) {
336
    // Map vocabulary names to vid, these take precedence over machine names.
337 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...
338
      $vocabularies = \taxonomy_get_vocabularies();
339
      foreach ($vocabularies as $vid => $vocabulary) {
340
        if ($vocabulary->name == $term->vocabulary_machine_name) {
341
          $term->vid = $vocabulary->vid;
342
        }
343
      }
344
    }
345
346
    if (!isset($term->vid)) {
347
348
      // Try to load vocabulary by machine name.
349
      $vocabularies = $this->taxonomyVocabularyLoadMultiple(array($term->vid));
350
      if (!empty($vocabularies)) {
351
        $vids = array_keys($vocabularies);
352
        $term->vid = reset($vids);
353
      }
354
    }
355
356
    // If `parent` is set, look up a term in this vocab with that name.
357 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...
358
      $parent = \taxonomy_get_term_by_name($term->parent);
359
      if (!empty($parent)) {
360
        $parent = reset($parent);
361
        $term->parent = $parent->tid;
362
      }
363
    }
364
365
    if (empty($term->vid)) {
366
      throw new \Exception(sprintf('No "%s" vocabulary found.'));
367
    }
368
369
    // Attempt to decipher any fields that may be specified.
370
    $this->expandEntityFields('taxonomy_term', $term);
371
372
    // Protect against a failure from hook_taxonomy_term_insert() in pathauto.
373
    $current_path = getcwd();
374
    chdir(DRUPAL_ROOT);
375
    $term_array = (array) $term;
376
    \taxonomy_save_term($term_array);
377
    chdir($current_path);
378
379
    // Loading a term by name returns an array of term objects, but there should
380
    // only be one matching term in a testing context, so take the first match
381
    // by reset()'ing $matches.
382
    $matches = \taxonomy_get_term_by_name($term->name);
383
    $saved_term = reset($matches);
384
385
    return $saved_term;
386
  }
387
388
  /**
389
   * {@inheritdoc}
390
   */
391
  public function termDelete(\stdClass $term) {
392
    $status = 0;
393
    if (isset($term->tid)) {
394
      $status = \taxonomy_del_term($term->tid);
395
    }
396
    // Will be SAVED_DELETED (3) on success.
397
    return $status;
398
  }
399
400
  /**
401
   * Helper function to get all permissions.
402
   *
403
   * @return array
404
   *   Array keyed by permission name, with the human-readable title as the
405
   *   value.
406
   */
407 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...
408
    $permissions = array();
409
    foreach (module_invoke_all('permission') as $name => $permission) {
410
      $permissions[$name] = $permission['title'];
411
    }
412
    return $permissions;
413
  }
414
415
  /**
416
   * {@inheritdoc}
417
   */
418
  public function getModuleList() {
419
    return module_list();
420
  }
421
422
  /**
423
   * {@inheritdoc}
424
   */
425
  public function installModules(array $modules, $install_dependencies = TRUE) {
426
    // Drupal 6 does not support the optional installation of dependencies. This
427
    // does not have a return value so we cannot detect if the installation was
428
    // successful.
429
    module_enable($modules);
430
  }
431
432
  /**
433
   * {@inheritdoc}
434
   */
435
  public function uninstallModules(array $modules) {
436
    // Drupal 6 doesn't actually uninstall modules, they can only be disabled.
437
    // Since no value is returned we cannot know if the uninstallation was
438
    // successful.
439
    module_disable($modules);
440
  }
441
442
  /**
443
   * {@inheritdoc}
444
   */
445 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...
446
    $paths = array();
447
448
    // Get enabled modules.
449
    $modules = $this->getModuleList();
450
    foreach ($modules as $module) {
451
      $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . \drupal_get_path('module', $module);
452
    }
453
454
    return $paths;
455
  }
456
457
  /**
458
   * {@inheritdoc}
459
   */
460
  protected function expandEntityFields($entity_type, \stdClass $entity) {
461
    return parent::expandEntityFields($entity_type, $entity);
462
  }
463
464
  /**
465
   * {@inheritdoc}
466
   */
467
  public function getEntityFieldTypes($entity_type) {
468
    $taxonomy_fields = array('taxonomy' => 'taxonomy');
469
    if (!module_exists('content')) {
470
      return $taxonomy_fields;
471
    }
472
    $return = array();
473
    $fields = content_fields();
474
    foreach ($fields as $field_name => $field) {
475
      if ($this->isField($entity_type, $field_name)) {
476
        $return[$field_name] = $field['type'];
477
      }
478
    }
479
480
    $return += $taxonomy_fields;
481
482
    return $return;
483
  }
484
485
  /**
486
   * {@inheritdoc}
487
   */
488
  public function isField($entity_type, $field_name) {
489
    if ($field_name === 'taxonomy') {
490
      return TRUE;
491
    }
492
    if (!module_exists('content')) {
493
      return FALSE;
494
    }
495
    $map = content_fields();
496
    return isset($map[$field_name]);
497
  }
498
499
  /**
500
   * {@inheritdoc}
501
   */
502
  public function languageCreate(\stdClass $language) {
503
    throw new \Exception('Creating languages is not yet implemented for Drupal 6.');
504
  }
505
506
  /**
507
   * {@inheritdoc}
508
   */
509
  public function languageDelete(\stdClass $language) {
510
    throw new \Exception('Deleting languages is not yet implemented for Drupal 6.');
511
  }
512
513
  /**
514
   * {@inheritdoc}
515
   */
516
  public function clearStaticCaches() {
517
    // Drupal 6 doesn't have a way of clearing all static caches.
518
  }
519
520
}
521