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