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

Drupal7::nodeCreate()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 25
Code Lines 12

Duplication

Lines 3
Ratio 12 %
Metric Value
dl 3
loc 25
rs 8.439
cc 5
eloc 12
nc 4
nop 1
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
    if (!defined('DRUPAL_ROOT')) {
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
    if (!isset($node->uid) && !empty($node->author) && ($user = user_load_by_name($node->author))) {
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
    return node_delete($node->nid);
73
  }
74
75
  /**
76
   * {@inheritdoc}
77
   */
78
  public function nodeDeleteMultiple(array $nids) {
79
    return node_delete_multiple($nids);
80
  }
81
82
  /**
83
   * {@inheritdoc}
84
   *
85
   * @param object $node
86
   *   A drupal node object.
87
   * @param object $values
88
   *   An object with field/value parameters.
89
   */
90
  public function nodeAlter($node, $values) {
91
    if (empty($node) || !isset($node->nid)) {
92
      var_dump(array_keys(get_object_vars($node)));
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
  /**
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
  public function userAlter($user, $values) {
151
    if (empty($user) || !isset($user->uid)) {
152
      var_dump(array_keys(get_object_vars($user)));
153
      throw new \Exception(sprintf("%s::%s: User was empty or had no id", get_class($this), __FUNCTION__));
154
    }
155
    // Attempt to decipher any fields that may be specified.
156
    $this->expandEntityFields('user', $values);
157
    foreach ($values as $k => $v) {
158
      $user->{$k} = $v;
159
    }
160
    user_save($user);
161
  }
162
163
  /**
164
   * {@inheritdoc}
165
   */
166
  public function userDelete(\stdClass $user) {
167
    user_cancel(array(), $user->uid, 'user_cancel_delete');
168
  }
169
170
  /**
171
   * {@inheritdoc}
172
   */
173
  public function userDeleteMultiple(array $uids) {
174
    return user_delete_multiple($uids);
175
  }
176
177
  /**
178
   * {@inheritdoc}
179
   */
180
  public function processBatch() {
181
    $batch =& batch_get();
182
    $batch['progressive'] = FALSE;
183
    batch_process();
184
  }
185
186
  /**
187
   * {@inheritdoc}
188
   */
189
  public function userAddRole(\stdClass $user, $role_name) {
190
    $role = user_role_load_by_name($role_name);
191
192
    if (!$role) {
193
      throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
194
    }
195
196
    user_multiple_role_edit(array($user->uid), 'add_role', $role->rid);
197
    $account = user_load($user->uid);
198
    $user->roles = $account->roles;
199
200
  }
201
202
  /**
203
   * Check to make sure that the array of permissions are valid.
204
   *
205
   * @param array $permissions
206
   *   Permissions to check.
207
   * @param bool $reset
208
   *   Reset cached available permissions.
209
   *
210
   * @return bool
211
   *   TRUE or FALSE depending on whether the permissions are valid.
212
   */
213
  protected function checkPermissions(array $permissions, $reset = FALSE) {
214
    $available = &drupal_static(__FUNCTION__);
215
216
    if (!isset($available) || $reset) {
217
      $available = array_keys(module_invoke_all('permission'));
218
    }
219
220
    $valid = TRUE;
221
    foreach ($permissions as $permission) {
222
      if (!in_array($permission, $available)) {
223
        $valid = FALSE;
224
      }
225
    }
226
    return $valid;
227
  }
228
229
  /**
230
   * {@inheritdoc}
231
   */
232
  public function roleCreate(array $permissions) {
233
234
    // Both machine name and permission title are allowed.
235
    $all_permissions = $this->getAllPermissions();
236
237
    foreach ($permissions as $key => $name) {
238
      if (!isset($all_permissions[$name])) {
239
        $search = array_search($name, $all_permissions);
240
        if (!$search) {
241
          throw new \RuntimeException(sprintf("No permission '%s' exists.", $name));
242
        }
243
        $permissions[$key] = $search;
244
      }
245
    }
246
247
    // Create new role.
248
    $role = new \stdClass();
249
    $role->name = $this->random->name(8);
250
    user_role_save($role);
251
    user_role_grant_permissions($role->rid, $permissions);
252
253
    if ($role && !empty($role->rid)) {
254
      return $role->name;
255
    }
256
257
    throw new \RuntimeException(sprintf('Failed to create a role with "" permission(s).', implode(', ', $permissions)));
258
  }
259
260
  /**
261
   * {@inheritdoc}
262
   */
263
  public function roleDelete($role_name) {
264
    $role = user_role_load_by_name($role_name);
265
    user_role_delete((int) $role->rid);
266
  }
267
268
  /**
269
   * {@inheritdoc}
270
   */
271
  public function validateDrupalSite() {
272
    if ('default' !== $this->uri) {
273
      // Fake the necessary HTTP headers that Drupal needs:
274
      $drupal_base_url = parse_url($this->uri);
275
      // If there's no url scheme set, add http:// and re-parse the url
276
      // so the host and path values are set accurately.
277
      if (!array_key_exists('scheme', $drupal_base_url)) {
278
        $drupal_base_url = parse_url($this->uri);
279
      }
280
      // Fill in defaults.
281
      $drupal_base_url += array(
282
        'path' => NULL,
283
        'host' => NULL,
284
        'port' => NULL,
285
      );
286
      $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
287
288
      if ($drupal_base_url['port']) {
289
        $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
290
      }
291
      $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
292
293
      if (array_key_exists('path', $drupal_base_url)) {
294
        $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
295
      }
296
      else {
297
        $_SERVER['PHP_SELF'] = '/index.php';
298
      }
299
    }
300
    else {
301
      $_SERVER['HTTP_HOST'] = 'default';
302
      $_SERVER['PHP_SELF'] = '/index.php';
303
    }
304
305
    $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
306
    $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
307
    $_SERVER['REQUEST_METHOD']  = NULL;
308
309
    $_SERVER['SERVER_SOFTWARE'] = NULL;
310
    $_SERVER['HTTP_USER_AGENT'] = NULL;
311
312
    $conf_path = conf_path(TRUE, TRUE);
313
    $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
314
    if (!file_exists($conf_file)) {
315
      throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
316
    }
317
    $drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php";
318
    if (file_exists($drushrc_file)) {
319
      require_once $drushrc_file;
320
    }
321
  }
322
323
  /**
324
   * Expands properties on the given entity object to the expected structure.
325
   *
326
   * @param \stdClass $entity
327
   *   The entity object.
328
   */
329
  protected function expandEntityProperties(\stdClass $entity) {
330
    if (!isset($entity->type)) {
331
      throw new \Exception(sprintf("%s::%s line %s: Entity argument is missing a value for the key 'type'", get_class($this), __FUNCTION__, __LINE__))
332
    }
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected '}'
Loading history...
333
    // The created field may come in as a readable date, rather than a
334
    // timestamp.
335
    if (isset($entity->created) && !is_numeric($entity->created)) {
336
      $entity->created = strtotime($entity->created);
337
    }
338
339
    // Map human-readable node types to machine node types.
340
    $types = \node_type_get_types();
341
    foreach ($types as $type) {
342
      if ($entity->type == $type->name) {
343
        $entity->type = $type->type;
344
        continue;
345
      }
346
    }
347
  }
348
349
  /**
350
   * {@inheritdoc}
351
   */
352
  public function termCreate(\stdClass $term) {
353
    // Map vocabulary names to vid, these take precedence over machine names.
354
    if (!isset($term->vid)) {
355
      $vocabularies = \taxonomy_get_vocabularies();
356
      foreach ($vocabularies as $vid => $vocabulary) {
357
        if ($vocabulary->name == $term->vocabulary_machine_name) {
358
          $term->vid = $vocabulary->vid;
359
        }
360
      }
361
    }
362
363
    if (!isset($term->vid)) {
364
365
      // Try to load vocabulary by machine name.
366
      $vocabularies = \taxonomy_vocabulary_load_multiple(FALSE, array(
367
        'machine_name' => $term->vocabulary_machine_name,
368
      ));
369
      if (!empty($vocabularies)) {
370
        $vids = array_keys($vocabularies);
371
        $term->vid = reset($vids);
372
      }
373
    }
374
375
    // If `parent` is set, look up a term in this vocab with that name.
376
    if (isset($term->parent)) {
377
      $parent = \taxonomy_get_term_by_name($term->parent, $term->vocabulary_machine_name);
378
      if (!empty($parent)) {
379
        $parent = reset($parent);
380
        $term->parent = $parent->tid;
381
      }
382
    }
383
384
    if (empty($term->vid)) {
385
      throw new \Exception(sprintf('No "%s" vocabulary found.'));
386
    }
387
388
    // Attempt to decipher any fields that may be specified.
389
    $this->expandEntityFields('taxonomy_term', $term);
390
391
    \taxonomy_term_save($term);
392
393
    return $term;
394
  }
395
396
  /**
397
   * {@inheritdoc}
398
   */
399
  public function termDelete(\stdClass $term) {
400
    $status = 0;
401
    if (isset($term->tid)) {
402
      $status = \taxonomy_term_delete($term->tid);
403
    }
404
    // Will be SAVED_DELETED (3) on success.
405
    return $status;
406
  }
407
408
  /**
409
   * {@inheritdoc}
410
   */
411
  public function languageCreate(\stdClass $language) {
412
    include_once DRUPAL_ROOT . '/includes/iso.inc';
413
    include_once DRUPAL_ROOT . '/includes/locale.inc';
414
415
    // Get all predefined languages, regardless if they are enabled or not.
416
    $predefined_languages = _locale_get_predefined_list();
417
418
    // If the language code is not valid then throw an InvalidArgumentException.
419
    if (!isset($predefined_languages[$language->langcode])) {
420
      throw new InvalidArgumentException("There is no predefined language with langcode '{$language->langcode}'.");
421
    }
422
423
    // Enable a language only if it has not been enabled already.
424
    $enabled_languages = locale_language_list();
425
    if (!isset($enabled_languages[$language->langcode])) {
426
      locale_add_language($language->langcode);
427
      return $language;
428
    }
429
430
    return FALSE;
431
  }
432
433
  /**
434
   * {@inheritdoc}
435
   */
436
  public function languageDelete(\stdClass $language) {
437
    $langcode = $language->langcode;
438
    // Do not remove English or the default language.
439
    if (!in_array($langcode, array(language_default('language'), 'en'))) {
440
      // @see locale_languages_delete_form_submit().
441
      $languages = language_list();
442
      if (isset($languages[$langcode])) {
443
        // Remove translations first.
444
        db_delete('locales_target')
445
          ->condition('language', $langcode)
446
          ->execute();
447
        cache_clear_all('locale:' . $langcode, 'cache');
448
        // With no translations, this removes existing JavaScript translations
449
        // file.
450
        _locale_rebuild_js($langcode);
451
        // Remove the language.
452
        db_delete('languages')
453
          ->condition('language', $langcode)
454
          ->execute();
455
        db_update('node')
456
          ->fields(array('language' => ''))
457
          ->condition('language', $langcode)
458
          ->execute();
459
        if ($languages[$langcode]->enabled) {
460
          variable_set('language_count', variable_get('language_count', 1) - 1);
461
        }
462
        module_invoke_all('multilingual_settings_changed');
463
        drupal_static_reset('language_list');
464
      }
465
466
      // Changing the language settings impacts the interface:
467
      cache_clear_all('*', 'cache_page', TRUE);
468
    }
469
  }
470
471
  /**
472
   * {@inheritdoc}
473
   */
474
  public function configGet($name, $key = '') {
475
    throw new \Exception('Getting config is not yet implemented for Drupal 7.');
476
  }
477
478
  /**
479
   * {@inheritdoc}
480
   */
481
  public function configSet($name, $key, $value) {
482
    throw new \Exception('Setting config is not yet implemented for Drupal 7.');
483
  }
484
485
  /**
486
   * Helper function to get all permissions.
487
   *
488
   * @return array
489
   *   Array keyed by permission name, with the human-readable title as the
490
   *   value.
491
   */
492
  protected function getAllPermissions() {
493
    $permissions = array();
494
    foreach (module_invoke_all('permission') as $name => $permission) {
495
      $permissions[$name] = $permission['title'];
496
    }
497
    return $permissions;
498
  }
499
500
  /**
501
   * {@inheritdoc}
502
   */
503
  public function getModuleList() {
504
    return module_list();
505
  }
506
507
  /**
508
   * {@inheritdoc}
509
   */
510
  public function getExtensionPathList() {
511
    $paths = array();
512
513
    // Get enabled modules.
514
    $modules = $this->getModuleList();
515
    foreach ($modules as $module) {
516
      $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . \drupal_get_path('module', $module);
517
    }
518
519
    return $paths;
520
  }
521
522
  /**
523
   * {@inheritdoc}
524
   */
525
  public function getEntityFieldTypes($entity_type) {
526
    $return = array();
527
    $fields = field_info_field_map();
528
    foreach ($fields as $field_name => $field) {
529
      if (array_key_exists($entity_type, $field['bundles'])) {
530
        $return[$field_name] = $field['type'];
531
      }
532
    }
533
    return $return;
534
  }
535
536
  /**
537
   * {@inheritdoc}
538
   */
539
  public function isField($entity_type, $field_name) {
540
    $map = field_info_field_map();
541
    return !empty($map[$field_name]) && array_key_exists($entity_type, $map[$field_name]['bundles']);
542
  }
543
544
  /**
545
   * {@inheritdoc}
546
   */
547
  public function clearStaticCaches() {
548
    drupal_static_reset();
549
  }
550
551
}
552