3 namespace Drupal\Driver\Cores;
5 use Drupal\Driver\Exception\BootstrapException;
10 class Drupal6 extends AbstractCore {
13 * The available permissions.
17 protected $availablePermissons;
22 public function bootstrap() {
23 // Validate, and prepare environment for Drupal bootstrap.
24 if (!defined('DRUPAL_ROOT')) {
25 define('DRUPAL_ROOT', $this->drupalRoot);
26 require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
27 $this->validateDrupalSite();
31 $current_path = getcwd();
33 drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
34 if (empty($GLOBALS['db_url'])) {
35 throw new BootstrapException('Missing database setting, verify the database configuration in settings.php.');
37 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
44 public function clearCache() {
45 // Need to change into the Drupal root directory or the registry explodes.
46 $current_path = getcwd();
48 drupal_flush_all_caches();
55 public function nodeCreate($node) {
56 $current_path = getcwd();
59 // Set original if not set.
60 if (!isset($node->original)) {
61 $node->original = clone $node;
64 // Assign authorship if none exists and `author` is passed.
65 if (!isset($node->uid) && !empty($node->author) && ($user = user_load(array('name' => $node->author)))) {
66 $node->uid = $user->uid;
69 // Convert properties to expected structure.
70 $this->expandEntityProperties($node);
72 // Attempt to decipher any fields that may be specified.
73 $this->expandEntityFields('node', $node);
75 // Set defaults that haven't already been set.
76 $defaults = clone $node;
77 module_load_include('inc', 'node', 'node.pages');
78 node_object_prepare($defaults);
79 $node = (object) array_merge((array) $defaults, (array) $node);
91 public function nodeDelete($node) {
92 node_delete($node->nid);
96 * Implements CoreInterface::runCron().
98 public function runCron() {
99 return drupal_cron_run();
105 public function userCreate(\stdClass $user) {
106 // Default status to TRUE if not explicitly creating a blocked user.
107 if (!isset($user->status)) {
111 // Clone user object, otherwise user_save() changes the password to the
113 $account = clone $user;
114 // Convert role array to a keyed array.
115 if (isset($user->roles)) {
117 foreach ($user->roles as $rid) {
120 $user->roles = $roles;
122 $account = user_save((array) $account, (array) $account);
124 $user->uid = $account->uid;
131 public function userDelete(\stdClass $user) {
132 $current_path = getcwd();
134 user_delete((array) $user, $user->uid);
135 chdir($current_path);
141 public function processBatch() {
147 public function userAddRole(\stdClass $user, $role_name) {
148 $roles = array_flip(user_roles());
149 $role = $roles[$role_name];
151 throw new \RuntimeException(sprintf('No role "%s" exists.', $role_name));
153 user_multiple_role_edit(array($user->uid), 'add_role', $role);
157 * Fetches a user role by role name.
159 * @param string $role_name
160 * A string representing the role name.
163 * A fully-loaded role object if a role with the given name exists, or FALSE
166 * @see user_role_load()
168 protected function userRoleLoadByName($role_name) {
169 $result = db_query('SELECT * FROM {role} WHERE name = "%s"', $role_name);
170 return db_fetch_object($result);
174 * Check to make sure that the array of permissions are valid.
176 * @param array $permissions
177 * Permissions to check.
179 * Reset cached available permissions.
182 * TRUE or FALSE depending on whether the permissions are valid.
184 protected function checkPermissions(array $permissions, $reset = FALSE) {
186 if (!isset($this->availablePermissons) || $reset) {
187 $this->availablePermissons = array_keys(module_invoke_all('permission'));
191 foreach ($permissions as $permission) {
192 if (!in_array($permission, $this->availablePermissons)) {
202 public function roleCreate(array $permissions) {
203 // Verify permissions exist.
204 $all_permissions = module_invoke_all('perm');
205 foreach ($permissions as $name) {
206 $search = array_search($name, $all_permissions);
208 throw new \RuntimeException(sprintf("No permission '%s' exists.", $name));
212 $name = $this->random->name(8);
213 db_query("INSERT INTO {role} SET name = '%s'", $name);
214 // Add permissions to role.
215 $rid = db_last_insert_id('role', 'rid');
216 db_query("INSERT INTO {permission} (rid, perm) VALUES (%d, '%s')", $rid, implode(', ', $permissions));
223 public function roleDelete($role_name) {
224 $roles = array_flip(user_roles());
225 $rid = $roles[$role_name];
226 db_query('DELETE FROM {role} WHERE rid = %d', $rid);
227 if (!db_affected_rows()) {
228 throw new \RuntimeException(sprintf('No role "%s" exists.', $rid));
235 public function validateDrupalSite() {
236 if ('default' !== $this->uri) {
237 // Fake the necessary HTTP headers that Drupal needs:
238 $drupal_base_url = parse_url($this->uri);
239 // If there's no url scheme set, add http:// and re-parse the url
240 // so the host and path values are set accurately.
241 if (!array_key_exists('scheme', $drupal_base_url)) {
242 $drupal_base_url = parse_url($this->uri);
245 $drupal_base_url += array(
250 $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
252 if ($drupal_base_url['port']) {
253 $_SERVER['HTTP_HOST'] .= ':' . $drupal_base_url['port'];
255 $_SERVER['SERVER_PORT'] = $drupal_base_url['port'];
257 if (array_key_exists('path', $drupal_base_url)) {
258 $_SERVER['PHP_SELF'] = $drupal_base_url['path'] . '/index.php';
261 $_SERVER['PHP_SELF'] = '/index.php';
265 $_SERVER['HTTP_HOST'] = 'default';
266 $_SERVER['PHP_SELF'] = '/index.php';
269 $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
270 $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
271 $_SERVER['REQUEST_METHOD'] = NULL;
273 $_SERVER['SERVER_SOFTWARE'] = NULL;
274 $_SERVER['HTTP_USER_AGENT'] = NULL;
276 $conf_path = conf_path(TRUE, TRUE);
277 $conf_file = $this->drupalRoot . "/$conf_path/settings.php";
278 if (!file_exists($conf_file)) {
279 throw new BootstrapException(sprintf('Could not find a Drupal settings.php file at "%s"', $conf_file));
281 $drushrc_file = $this->drupalRoot . "/$conf_path/drushrc.php";
282 if (file_exists($drushrc_file)) {
283 require_once $drushrc_file;
288 * Expands properties on the given entity object to the expected structure.
290 * @param \stdClass $entity
293 protected function expandEntityProperties(\stdClass $entity) {
294 // The created field may come in as a readable date, rather than a
296 if (isset($entity->created) && !is_numeric($entity->created)) {
297 $entity->created = strtotime($entity->created);
300 // Map human-readable node types to machine node types.
301 $types = node_get_types();
302 foreach ($types as $type) {
303 if ($entity->type == $type->name) {
304 $entity->type = $type->type;
311 * Load vocabularies, optional by VIDs.
317 * An array of vocabulary objects
319 protected function taxonomyVocabularyLoadMultiple($vids = array()) {
320 $vocabularies = taxonomy_get_vocabularies();
322 return array_intersect_key($vocabularies, array_flip($vids));
324 return $vocabularies;
330 public function termCreate(\stdClass $term) {
331 // Map vocabulary names to vid, these take precedence over machine names.
332 if (!isset($term->vid)) {
333 $vocabularies = \taxonomy_get_vocabularies();
334 foreach ($vocabularies as $vid => $vocabulary) {
335 if ($vocabulary->name == $term->vocabulary_machine_name) {
336 $term->vid = $vocabulary->vid;
341 if (!isset($term->vid)) {
343 // Try to load vocabulary by machine name.
344 $vocabularies = $this->taxonomyVocabularyLoadMultiple(array($term->vid));
345 if (!empty($vocabularies)) {
346 $vids = array_keys($vocabularies);
347 $term->vid = reset($vids);
351 // If `parent` is set, look up a term in this vocab with that name.
352 if (isset($term->parent)) {
353 $parent = \taxonomy_get_term_by_name($term->parent);
354 if (!empty($parent)) {
355 $parent = reset($parent);
356 $term->parent = $parent->tid;
360 if (empty($term->vid)) {
361 throw new \Exception(sprintf('No "%s" vocabulary found.'));
364 // Attempt to decipher any fields that may be specified.
365 $this->expandEntityFields('taxonomy_term', $term);
367 // Protect against a failure from hook_taxonomy_term_insert() in pathauto.
368 $current_path = getcwd();
370 $term_array = (array) $term;
371 \taxonomy_save_term($term_array);
372 chdir($current_path);
374 // Loading a term by name returns an array of term objects, but there should
375 // only be one matching term in a testing context, so take the first match
376 // by reset()'ing $matches.
377 $matches = \taxonomy_get_term_by_name($term->name);
378 $saved_term = reset($matches);
386 public function termDelete(\stdClass $term) {
388 if (isset($term->tid)) {
389 $status = \taxonomy_del_term($term->tid);
391 // Will be SAVED_DELETED (3) on success.
396 * Helper function to get all permissions.
399 * Array keyed by permission name, with the human-readable title as the
402 protected function getAllPermissions() {
403 $permissions = array();
404 foreach (module_invoke_all('permission') as $name => $permission) {
405 $permissions[$name] = $permission['title'];
413 public function getModuleList() {
414 return module_list();
420 public function getExtensionPathList() {
423 // Get enabled modules.
424 $modules = $this->getModuleList();
425 foreach ($modules as $module) {
426 $paths[] = $this->drupalRoot . DIRECTORY_SEPARATOR . \drupal_get_path('module', $module);
435 protected function expandEntityFields($entity_type, \stdClass $entity) {
436 return parent::expandEntityFields($entity_type, $entity);
442 public function getEntityFieldTypes($entity_type) {
443 $taxonomy_fields = array('taxonomy' => 'taxonomy');
444 if (!module_exists('content')) {
445 return $taxonomy_fields;
448 $fields = content_fields();
449 foreach ($fields as $field_name => $field) {
450 if ($this->isField($entity_type, $field_name)) {
451 $return[$field_name] = $field['type'];
455 $return += $taxonomy_fields;
463 public function isField($entity_type, $field_name) {
464 if ($field_name === 'taxonomy') {
467 if (!module_exists('content')) {
470 $map = content_fields();
471 return isset($map[$field_name]);
477 public function languageCreate(\stdClass $language) {
478 throw new \Exception('Creating languages is not yet implemented for Drupal 6.');
484 public function languageDelete(\stdClass $language) {
485 throw new \Exception('Deleting languages is not yet implemented for Drupal 6.');
491 public function configGet($name, $key = '') {
492 throw new \Exception('Getting config is not yet implemented for Drupal 6.');
498 public function configSet($name, $key, $value) {
499 throw new \Exception('Setting config is not yet implemented for Drupal 6.');
505 public function clearStaticCaches() {
506 // Drupal 6 doesn't have a way of clearing all static caches.