/** * Validate the settings form. */ public function validateSettings(&$element, &$form_state) { $schema = drupal_get_schema('membership_entity'); if ($element['length']['#value'] > $schema['fields']['member_id']['length']) { form_error($element['length'], t('Member ID length cannot exceed %max.', array('%max' => $schema['fields']['member_id']['length']))); } }
/** * Tests that we can insert fields with values and defaults in the same query. */ function testDefaultInsertWithFields() { $query = db_insert('test')->fields(array('name' => 'Bob'))->useDefaults(array('job')); $id = $query->execute(); $schema = drupal_get_schema('test'); $job = db_query('SELECT job FROM {test} WHERE id = :id', array(':id' => $id))->fetchField(); $this->assertEqual($job, $schema['fields']['job']['default'], 'Default field value is set.'); }
/** * Overrides Drupal\configuration\Config\Configuration::findRequiredModules(). */ public function findRequiredModules() { $this->addToModules('views'); $view = $this->getData(); // We get the module that creates the table for the view query. $schema = drupal_get_schema($view->base_table); $this->addToModules($schema['module']); foreach (views_object_types() as $type => $info) { foreach ($view->display as $display_id => $display) { // Views with a display provided by views_content module. if ($display->display_plugin == 'panel_pane') { $this->addToModules('views_content'); } $view->set_display($display_id); foreach ($view->display_handler->get_handlers($type) as $handler_id => $handler) { if ($type == 'field') { if (!empty($handler->field_info) && !empty($handler->field_info['module'])) { $this->addToModules($handler->field_info['module']); } } } } } }
/** * Installation task; perform final steps and display a 'finished' page. * * @param $install_state * An array of information about the current installation state. * @return * A message informing the user that the installation is complete. */ function install_finished(&$install_state) { drupal_set_title(st('@drupal installation complete', array('@drupal' => drupal_install_profile_name())), PASS_THROUGH); $messages = drupal_set_message(); $output = '<p>' . st('Congratulations, @drupal has been successfully installed.', array('@drupal' => drupal_install_profile_name())) . '</p>'; $output .= '<p>' . (isset($messages['error']) ? st('Review the messages above before continuing on to <a href="@url">your new site</a>.', array('@url' => url(''))) : st('You may now visit <a href="@url">your new site</a>.', array('@url' => url('')))) . '</p>'; if (module_exists('help')) { $output .= '<p>' . st('For more information on configuring Drupal, refer to the <a href="@help">help section</a>.', array('@help' => url('admin/help'))) . '</p>'; } // Rebuild the module and theme data, in case any newly-installed modules // need to modify it via hook_system_info_alter(). We need to clear the // theme static cache first, to make sure that the theme data is actually // rebuilt. drupal_static_reset('_system_rebuild_theme_data'); system_rebuild_module_data(); system_rebuild_theme_data(); // Rebuild menu and registry to get content type links registered by the // profile, and possibly any other menu items created through the tasks. menu_rebuild(); // Rebuild the database cache of node types, so that any node types added // by newly installed modules are registered correctly and initialized with // the necessary fields. node_types_rebuild(); // Register actions declared by any modules. actions_synchronize(); // Randomize query-strings on css/js files, to hide the fact that this is a // new install, not upgraded yet. _drupal_flush_css_js(); // Remember the profile which was used. variable_set('install_profile', drupal_get_profile()); // Install profiles are always loaded last db_update('system')->fields(array('weight' => 1000))->condition('type', 'module')->condition('name', drupal_get_profile())->execute(); // Cache a fully-built schema. drupal_get_schema(NULL, TRUE); // Run cron to populate update status tables (if available) so that users // will be warned if they've installed an out of date Drupal version. // Will also trigger indexing of profile-supplied content or feeds. drupal_cron_run(); return $output; }
/** * Delete created files and temporary files directory, delete the tables created by setUp(), * and reset the database prefix. */ protected function tearDown() { global $db_prefix; if (preg_match('/simpletest\\d+/', $db_prefix)) { // Delete temporary files directory and reset files directory path. simpletest_clean_temporary_directory(file_directory_path()); variable_set('file_directory_path', $this->originalFileDirectory); // Remove all prefixed tables (all the tables in the schema). $schema = drupal_get_schema(NULL, TRUE); $ret = array(); foreach ($schema as $name => $table) { db_drop_table($ret, $name); } // Return the database prefix to the original. $db_prefix = $this->originalPrefix; // Ensure that the internal logged in variable is reset. $this->isLoggedIn = FALSE; // Reload module list and implementations to ensure that test module hooks // aren't called after tests. module_list(TRUE); module_implements(MODULE_IMPLEMENTS_CLEAR_CACHE); // Rebuild caches. $this->refreshVariables(); // Close the CURL handler. $this->curlClose(); } }
/** * Installs Atrium instead of Drupal * * Generates a random database prefix, runs the install scripts on the * prefixed database and enable the specified modules. After installation * many caches are flushed and the internal browser is setup so that the * page requests will run on the new prefix. A temporary files directory * is created with the same name as the database prefix. * * @param ... * List of modules to enable for the duration of the test. */ protected function setUp() { global $db_prefix, $user, $language, $profile, $install_locale; // $language (Drupal 6). // Store necessary current values before switching to prefixed database. $this->originalPrefix = $db_prefix; $this->originalLanguage = clone $language; $clean_url_original = variable_get('clean_url', 0); // Must reset locale here, since schema calls t(). (Drupal 6) if (module_exists('locale')) { $language = (object) array('language' => 'en', 'name' => 'English', 'native' => 'English', 'direction' => 0, 'enabled' => 1, 'plurals' => 0, 'formula' => '', 'domain' => '', 'prefix' => '', 'weight' => 0, 'javascript' => ''); locale(NULL, NULL, TRUE); } // Generate temporary prefixed database to ensure that tests have a clean starting point. // $db_prefix = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}'); $db_prefix = 'simpletest' . mt_rand(1000, 1000000); $install_locale = $this->install_locale; $profile = $this->install_profile; // include_once DRUPAL_ROOT . '/includes/install.inc'; include_once './includes/install.inc'; drupal_install_system(); // $this->preloadRegistry(); // Set up theme system for the maintenance page. // Otherwise we have trouble: https://ds.openatrium.com/dsi/node/18426#comment-38118 // @todo simpletest module patch drupal_maintenance_theme(); // Add the specified modules to the list of modules in the default profile. $args = func_get_args(); // $modules = array_unique(array_merge(drupal_get_profile_modules('default', 'en'), $args)); $modules = array_unique(array_merge(drupal_verify_profile($this->install_profile, $this->install_locale), $args)); // drupal_install_modules($modules, TRUE); drupal_install_modules($modules); // Because the schema is static cached, we need to flush // it between each run. If we don't, then it will contain // stale data for the previous run's database prefix and all // calls to it will fail. drupal_get_schema(NULL, TRUE); if ($this->install_profile == 'openatrium') { // Download and import translation if needed if ($this->install_locale != 'en') { $this->installLanguage($this->install_locale); } // Install more modules $modules = _openatrium_atrium_modules(); drupal_install_modules($modules); // Configure intranet // $profile_tasks = $this->install_profile . '_profile_tasks'; _openatrium_intranet_configure(); _openatrium_intranet_configure_check(); variable_set('atrium_install', 1); // Clear views cache before rebuilding menu tree. Requires patch // [patch_here] to Views, as new modules have been included and // default views need to be re-detected. module_exists('views') ? views_get_all_views(TRUE) : TRUE; menu_rebuild(); } _drupal_flush_css_js(); $this->refreshVariables(); $this->checkPermissions(array(), TRUE); user_access(NULL, NULL, TRUE); // Drupal 6. // Log in with a clean $user. $this->originalUser = $user; // drupal_save_session(FALSE); // $user = user_load(1); session_save_session(FALSE); $user = user_load(array('uid' => 1)); // Restore necessary variables. variable_set('install_profile', $this->install_profile); variable_set('install_task', 'profile-finished'); variable_set('clean_url', $clean_url_original); variable_set('site_mail', '*****@*****.**'); // Use temporary files directory with the same prefix as database. $this->originalFileDirectory = file_directory_path(); variable_set('file_directory_path', file_directory_path() . '/' . $db_prefix); $directory = file_directory_path(); // Create the files directory. file_check_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); set_time_limit($this->timeLimit); }
/** * Installation task; perform final steps and display a 'finished' page. * * @param $install_state * An array of information about the current installation state. * @return * A message informing the user that the installation is complete. */ function install_finished(&$install_state) { drupal_set_title(st('@drupal installation complete', array('@drupal' => drupal_install_profile_name()))); $messages = drupal_set_message(); $output = '<p>' . st('Congratulations, @drupal has been successfully installed.', array('@drupal' => drupal_install_profile_name())) . '</p>'; $output .= '<p>' . (isset($messages['error']) ? st('Please review the messages above before continuing on to <a href="@url">your new site</a>.', array('@url' => url(''))) : st('You may now visit <a href="@url">your new site</a>.', array('@url' => url('')))) . '</p>'; if (module_exists('help')) { $output .= '<p>' . st('For more information on configuring Drupal, please refer to the <a href="@help">help section</a>.', array('@help' => url('admin/help'))) . '</p>'; } // Rebuild menu and registry to get content type links registered by the // profile, and possibly any other menu items created through the tasks. menu_rebuild(); // Register actions declared by any modules. actions_synchronize(); // Randomize query-strings on css/js files, to hide the fact that this is a // new install, not upgraded yet. _drupal_flush_css_js(); // Remember the profile which was used. variable_set('install_profile', $install_state['parameters']['profile']); // Cache a fully-built schema. drupal_get_schema(NULL, TRUE); // Run cron to populate update status tables (if available) so that users // will be warned if they've installed an out of date Drupal version. // Will also trigger indexing of profile-supplied content or feeds. drupal_cron_run(); return $output; }
/** * {@inheritdoc} */ public function install(array $module_list, $enable_dependencies = TRUE) { $extension_config = \Drupal::config('core.extension'); if ($enable_dependencies) { // Get all module data so we can find dependencies and sort. $module_data = system_rebuild_module_data(); $module_list = $module_list ? array_combine($module_list, $module_list) : array(); if (array_diff_key($module_list, $module_data)) { // One or more of the given modules doesn't exist. return FALSE; } // Only process currently uninstalled modules. $installed_modules = $extension_config->get('module') ?: array(); if (!($module_list = array_diff_key($module_list, $installed_modules))) { // Nothing to do. All modules already installed. return TRUE; } // Add dependencies to the list. The new modules will be processed as // the while loop continues. while (list($module) = each($module_list)) { foreach (array_keys($module_data[$module]->requires) as $dependency) { if (!isset($module_data[$dependency])) { // The dependency does not exist. return FALSE; } // Skip already installed modules. if (!isset($module_list[$dependency]) && !isset($installed_modules[$dependency])) { $module_list[$dependency] = $dependency; } } } // Set the actual module weights. $module_list = array_map(function ($module) use($module_data) { return $module_data[$module]->sort; }, $module_list); // Sort the module list by their weights (reverse). arsort($module_list); $module_list = array_keys($module_list); } // Required for module installation checks. include_once DRUPAL_ROOT . '/core/includes/install.inc'; /** @var \Drupal\Core\Config\ConfigInstaller $config_installer */ $config_installer = \Drupal::service('config.installer'); $sync_status = $config_installer->isSyncing(); if ($sync_status) { $source_storage = $config_installer->getSourceStorage(); } $modules_installed = array(); foreach ($module_list as $module) { $enabled = $extension_config->get("module.{$module}") !== NULL; if (!$enabled) { // Throw an exception if the module name is too long. if (strlen($module) > DRUPAL_EXTENSION_NAME_MAX_LENGTH) { throw new ExtensionNameLengthException(format_string('Module name %name is over the maximum allowed length of @max characters.', array('%name' => $module, '@max' => DRUPAL_EXTENSION_NAME_MAX_LENGTH))); } $extension_config->set("module.{$module}", 0)->set('module', module_config_sort($extension_config->get('module')))->save(); // Prepare the new module list, sorted by weight, including filenames. // This list is used for both the ModuleHandler and DrupalKernel. It // needs to be kept in sync between both. A DrupalKernel reboot or // rebuild will automatically re-instantiate a new ModuleHandler that // uses the new module list of the kernel. However, DrupalKernel does // not cause any modules to be loaded. // Furthermore, the currently active (fixed) module list can be // different from the configured list of enabled modules. For all active // modules not contained in the configured enabled modules, we assume a // weight of 0. $current_module_filenames = $this->getModuleList(); $current_modules = array_fill_keys(array_keys($current_module_filenames), 0); $current_modules = module_config_sort(array_merge($current_modules, $extension_config->get('module'))); $module_filenames = array(); foreach ($current_modules as $name => $weight) { if (isset($current_module_filenames[$name])) { $module_filenames[$name] = $current_module_filenames[$name]; } else { $module_path = drupal_get_path('module', $name); $pathname = "{$module_path}/{$name}.info.yml"; $filename = file_exists($module_path . "/{$name}.module") ? "{$name}.module" : NULL; $module_filenames[$name] = new Extension('module', $pathname, $filename); } } // Update the module handler in order to load the module's code. // This allows the module to participate in hooks and its existence to // be discovered by other modules. // The current ModuleHandler instance is obsolete with the kernel // rebuild below. $this->setModuleList($module_filenames); $this->load($module); module_load_install($module); // Clear the static cache of system_rebuild_module_data() to pick up the // new module, since it merges the installation status of modules into // its statically cached list. drupal_static_reset('system_rebuild_module_data'); // Update the kernel to include it. // This reboots the kernel to register the module's bundle and its // services in the service container. The $module_filenames argument is // taken over as %container.modules% parameter, which is passed to a // fresh ModuleHandler instance upon first retrieval. // @todo install_begin_request() creates a container without a kernel. if ($kernel = \Drupal::service('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) { $kernel->updateModules($module_filenames, $module_filenames); } // Refresh the schema to include it. drupal_get_schema(NULL, TRUE); // Allow modules to react prior to the installation of a module. $this->invokeAll('module_preinstall', array($module)); // Now install the module's schema if necessary. drupal_install_schema($module); // Clear plugin manager caches and flag router to rebuild if requested. \Drupal::getContainer()->get('plugin.cache_clearer')->clearCachedDefinitions(); \Drupal::service('router.builder_indicator')->setRebuildNeeded(); // Set the schema version to the number of the last update provided by // the module, or the minimum core schema version. $version = \Drupal::CORE_MINIMUM_SCHEMA_VERSION; $versions = drupal_get_schema_versions($module); if ($versions) { $version = max(max($versions), $version); } // Notify the entity manager that this module's entity types are new, // so that it can notify all interested handlers. For example, a // SQL-based storage handler can use this as an opportunity to create // the necessary database tables. $entity_manager = \Drupal::entityManager(); foreach ($entity_manager->getDefinitions() as $entity_type) { if ($entity_type->getProvider() == $module) { $entity_manager->onEntityTypeCreate($entity_type); } } // Install default configuration of the module. $config_installer = \Drupal::service('config.installer'); if ($sync_status) { $config_installer->setSyncing(TRUE)->setSourceStorage($source_storage); } else { // If we're not in a config synchronisation reset the source storage // so that the extension install storage will pick up the new // configuration. $config_installer->resetSourceStorage(); } \Drupal::service('config.installer')->installDefaultConfig('module', $module); // If the module has no current updates, but has some that were // previously removed, set the version to the value of // hook_update_last_removed(). if ($last_removed = $this->invoke($module, 'update_last_removed')) { $version = max($version, $last_removed); } drupal_set_installed_schema_version($module, $version); // Record the fact that it was installed. $modules_installed[] = $module; // file_get_stream_wrappers() needs to re-register Drupal's stream // wrappers in case a module-provided stream wrapper is used later in // the same request. In particular, this happens when installing Drupal // via Drush, as the 'translations' stream wrapper is provided by // Interface Translation module and is later used to import // translations. \Drupal::service('stream_wrapper_manager')->register(); // Update the theme registry to include it. drupal_theme_rebuild(); // Modules can alter theme info, so refresh theme data. // @todo ThemeHandler cannot be injected into ModuleHandler, since that // causes a circular service dependency. // @see https://drupal.org/node/2208429 \Drupal::service('theme_handler')->refreshInfo(); // Allow the module to perform install tasks. $this->invoke($module, 'install'); // Record the fact that it was installed. \Drupal::logger('system')->info('%module module installed.', array('%module' => $module)); } } // If any modules were newly installed, invoke hook_modules_installed(). if (!empty($modules_installed)) { $this->invokeAll('modules_installed', array($modules_installed)); } return TRUE; }
/** * Act on deletion of a field. * * This hook is invoked from field_delete_field() to ask the field storage * module to mark all information stored in the field for deletion. * * @param $field * The field being deleted. */ function hook_field_storage_delete_field($field) { // Mark all data associated with the field for deletion. $field['deleted'] = 0; $table = _field_sql_storage_tablename($field); $revision_table = _field_sql_storage_revision_tablename($field); db_update($table)->fields(array('deleted' => 1))->execute(); // Move the table to a unique name while the table contents are being deleted. $field['deleted'] = 1; $new_table = _field_sql_storage_tablename($field); $revision_new_table = _field_sql_storage_revision_tablename($field); db_rename_table($table, $new_table); db_rename_table($revision_table, $revision_new_table); drupal_get_schema(NULL, TRUE); }
protected function setUpInstall() { global $db_prefix; // Store new database prefix. $db_prefix_new = $db_prefix; $db_prefix = $this->originalPrefix; // Rebuild schema based on prefixed database and such. $schemas = drupal_get_schema(NULL, TRUE); // Create a list of prefixed source table names. $sources = array(); foreach ($schemas as $name => $schema) { $sources[$name] = Database::getConnection()->prefixTables('{' . $name . '}'); } // Return to new prefix before performing cloning. $db_prefix = $db_prefix_new; // Clone each table into the new database. foreach ($schemas as $name => $schema) { $this->cloneTable($name, $sources[$name], $schema); } }
/** * Installs a specific table from a module schema definition. * * @param string $module * The name of the module that defines the table's schema. * @param string|array $tables * The name or an array of the names of the tables to install. * * @throws \RuntimeException * Thrown when $module is not enabled or when the table schema cannot be * found in the module specified. */ protected function installSchema($module, $tables) { // drupal_get_schema_unprocessed() is technically able to install a schema // of a non-enabled module, but its ability to load the module's .install // file depends on many other factors. To prevent differences in test // behavior and non-reproducible test failures, we only allow the schema of // explicitly loaded/enabled modules to be installed. if (!$this->container->get('module_handler')->moduleExists($module)) { throw new \RuntimeException(format_string("'@module' module is not enabled.", array('@module' => $module))); } $tables = (array) $tables; foreach ($tables as $table) { $schema = drupal_get_schema_unprocessed($module, $table); if (empty($schema)) { throw new \RuntimeException(format_string("Unknown '@table' table schema in '@module' module.", array('@module' => $module, '@table' => $table))); } $this->container->get('database')->schema()->createTable($table, $schema); } // We need to refresh the schema cache, as any call to drupal_get_schema() // would not know of/return the schema otherwise. // @todo Refactor Schema API to make this obsolete. drupal_get_schema(NULL, TRUE); $this->pass(format_string('Installed %module tables: %tables.', array('%tables' => '{' . implode('}, {', $tables) . '}', '%module' => $module))); }
/** * Delete created files and temporary files directory, delete the tables created by setUp(), * and reset the database prefix. */ protected function tearDown() { global $db_prefix, $user; if (preg_match('/simpletest\\d+/', $db_prefix)) { // Delete temporary files directory and reset files directory path. file_unmanaged_delete_recursive(file_directory_path()); variable_set('file_directory_path', $this->originalFileDirectory); // Remove all prefixed tables (all the tables in the schema). $schema = drupal_get_schema(NULL, TRUE); $ret = array(); foreach ($schema as $name => $table) { db_drop_table($ret, $name); } // Return the database prefix to the original. $db_prefix = $this->originalPrefix; // Return the user to the original one. $user = $this->originalUser; drupal_save_session(TRUE); // Ensure that internal logged in variable and cURL options are reset. $this->loggedInUser = FALSE; $this->additionalCurlOptions = array(); // Reload module list and implementations to ensure that test module hooks // aren't called after tests. module_list(TRUE); module_implements(MODULE_IMPLEMENTS_CLEAR_CACHE); // Reset the Field API. field_cache_clear(); // Rebuild caches. $this->refreshVariables(); // Close the CURL handler. $this->curlClose(); } }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $form['#title'] = $this->t('Configure site'); // Warn about settings.php permissions risk $settings_dir = conf_path(); $settings_file = $settings_dir . '/settings.php'; // Check that $_POST is empty so we only show this message when the form is // first displayed, not on the next page after it is submitted. (We do not // want to repeat it multiple times because it is a general warning that is // not related to the rest of the installation process; it would also be // especially out of place on the last page of the installer, where it would // distract from the message that the Drupal installation has completed // successfully.) $post_params = $this->getRequest()->request->all(); if (empty($post_params) && (!drupal_verify_install_file($this->root . '/' . $settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE) || !drupal_verify_install_file($this->root . '/' . $settings_dir, FILE_NOT_WRITABLE, 'dir'))) { drupal_set_message(t('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the <a href="@handbook_url">online handbook</a>.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/server-permissions')), 'warning'); } $form['#attached']['library'][] = 'system/drupal.system'; // Add JavaScript time zone detection. $form['#attached']['library'][] = 'core/drupal.timezone'; // We add these strings as settings because JavaScript translation does not // work during installation. $form['#attached']['drupalSettings']['copyFieldValue']['edit-site-mail'] = ['edit-account-mail']; // Cache a fully-built schema. This is necessary for any invocation of // index.php because: (1) setting cache table entries requires schema // information, (2) that occurs during bootstrap before any module are // loaded, so (3) if there is no cached schema, drupal_get_schema() will // try to generate one but with no loaded modules will return nothing. // // @todo Move this to the 'install_finished' task? drupal_get_schema(NULL, TRUE); $form['site_information'] = array('#type' => 'fieldgroup', '#title' => $this->t('Site information')); $form['site_information']['site_name'] = array('#type' => 'textfield', '#title' => $this->t('Site name'), '#required' => TRUE, '#weight' => -20); $form['site_information']['site_mail'] = array('#type' => 'email', '#title' => $this->t('Site email address'), '#default_value' => ini_get('sendmail_from'), '#description' => $this->t("Automated emails, such as registration information, will be sent from this address. Use an address ending in your site's domain to help prevent these emails from being flagged as spam."), '#required' => TRUE, '#weight' => -15); $form['admin_account'] = array('#type' => 'fieldgroup', '#title' => $this->t('Site maintenance account')); $form['admin_account']['account']['name'] = array('#type' => 'textfield', '#title' => $this->t('Username'), '#maxlength' => USERNAME_MAX_LENGTH, '#description' => $this->t('Spaces are allowed; punctuation is not allowed except for periods, hyphens, and underscores.'), '#required' => TRUE, '#attributes' => array('class' => array('username'))); $form['admin_account']['account']['pass'] = array('#type' => 'password_confirm', '#required' => TRUE, '#size' => 25); $form['admin_account']['account']['#tree'] = TRUE; $form['admin_account']['account']['mail'] = array('#type' => 'email', '#title' => $this->t('Email address'), '#required' => TRUE); $form['regional_settings'] = array('#type' => 'fieldgroup', '#title' => $this->t('Regional settings')); $countries = $this->countryManager->getList(); $form['regional_settings']['site_default_country'] = array('#type' => 'select', '#title' => $this->t('Default country'), '#empty_value' => '', '#default_value' => $this->config('system.date')->get('country.default'), '#options' => $countries, '#description' => $this->t('Select the default country for the site.'), '#weight' => 0); $form['regional_settings']['date_default_timezone'] = array('#type' => 'select', '#title' => $this->t('Default time zone'), '#default_value' => date_default_timezone_get(), '#options' => system_time_zones(), '#description' => $this->t('By default, dates in this site will be displayed in the chosen time zone.'), '#weight' => 5, '#attributes' => array('class' => array('timezone-detect'))); $form['update_notifications'] = array('#type' => 'fieldgroup', '#title' => $this->t('Update notifications')); $form['update_notifications']['update_status_module'] = array('#type' => 'checkboxes', '#title' => $this->t('Update notifications'), '#options' => array(1 => $this->t('Check for updates automatically'), 2 => $this->t('Receive email notifications')), '#default_value' => array(1, 2), '#description' => $this->t('The system will notify you when updates and important security releases are available for installed components. Anonymous information about your site is sent to <a href="@drupal">Drupal.org</a>.', array('@drupal' => 'http://drupal.org')), '#weight' => 15); $form['update_notifications']['update_status_module'][2] = array('#states' => array('visible' => array('input[name="update_status_module[1]"]' => array('checked' => TRUE)))); $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save and continue'), '#weight' => 15, '#button_type' => 'primary'); return $form; }
/** * Delete created files and temporary files directory, delete the tables created by setUp(), * and reset the database prefix. */ protected function tearDown() { global $db_prefix, $user, $language; $emailCount = count(variable_get('simpletest_emails', array())); if ($emailCount) { $message = format_plural($emailCount, t('!count e-mail was sent during this test.'), t('!count e-mails were sent during this test.'), array('!count' => $emailCount)); $this->pass($message, t('E-mail')); } if (preg_match('/simpletest\\d+/', $db_prefix)) { // Delete temporary files directory and reset files directory path. file_unmanaged_delete_recursive(file_directory_path()); variable_set('file_directory_path', $this->originalFileDirectory); // Remove all prefixed tables (all the tables in the schema). $schema = drupal_get_schema(NULL, TRUE); $ret = array(); foreach ($schema as $name => $table) { db_drop_table($ret, $name); } // Return the database prefix to the original. $db_prefix = $this->originalPrefix; // Return the user to the original one. $user = $this->originalUser; drupal_save_session(TRUE); // Ensure that internal logged in variable and cURL options are reset. $this->loggedInUser = FALSE; $this->additionalCurlOptions = array(); // Reload module list and implementations to ensure that test module hooks // aren't called after tests. module_list(TRUE); module_implements(MODULE_IMPLEMENTS_CLEAR_CACHE); // Reset the Field API. field_cache_clear(); // Rebuild caches. $this->refreshVariables(); // Reset language. $language = $this->originalLanguage; if ($this->originalLanguageDefault) { $GLOBALS['conf']['language_default'] = $this->originalLanguageDefault; } // Close the CURL handler. $this->curlClose(); } }
/** * Don't create test db via install, instead copy existing db. */ protected function setUp() { // Copy of parent::setUp(); global $user, $language, $conf; // Generate a temporary prefixed database to ensure that tests have a clean starting point. $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000); db_update('simpletest_test_id')->fields(array('last_prefix' => $this->databasePrefix))->condition('test_id', $this->testId)->execute(); // Store necessary current values before switching to prefixed database. $this->originalLanguage = $language; $this->originalLanguageDefault = variable_get('language_default'); $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files'); $this->originalProfile = drupal_get_profile(); $clean_url_original = variable_get('clean_url', 0); // Save and clean shutdown callbacks array because it static cached and // will be changed by the test run. If we don't, then it will contain // callbacks from both environments. So testing environment will try // to call handlers from original environment. $callbacks =& drupal_register_shutdown_function(); $this->originalShutdownCallbacks = $callbacks; $callbacks = array(); // Create test directory ahead of installation so fatal errors and debug // information can be logged during installation process. // Use temporary files directory with the same prefix as the database. $this->public_files_directory = $this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10); $this->private_files_directory = $this->public_files_directory . '/private'; $this->temp_files_directory = $this->private_files_directory . '/temp'; // Create the directories file_prepare_directory($this->public_files_directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); file_prepare_directory($this->private_files_directory, FILE_CREATE_DIRECTORY); file_prepare_directory($this->temp_files_directory, FILE_CREATE_DIRECTORY); $this->generatedTestFiles = FALSE; // Log fatal errors. ini_set('log_errors', 1); ini_set('error_log', $this->public_files_directory . '/error.log'); // Set the test information for use in other parts of Drupal. $test_info =& $GLOBALS['drupal_test_info']; $test_info['test_run_id'] = $this->databasePrefix; $test_info['in_child_site'] = FALSE; // Rebuild schema based on prefixed database and such. $schemas = drupal_get_schema(NULL, TRUE); // Create a list of prefixed source table names. $sources = array(); foreach ($schemas as $name => $schema) { $sources[$name] = Database::getConnection()->prefixTables('{' . $name . '}'); } // Clone the current connection and replace the current prefix. $connection_info = Database::getConnectionInfo('default'); Database::renameConnection('default', 'simpletest_original_default'); foreach ($connection_info as $target => $value) { $connection_info[$target]['prefix'] = array('default' => $value['prefix']['default'] . $this->databasePrefix); } Database::addConnectionInfo('default', 'default', $connection_info['default']); // Clone each table into the new database. foreach ($schemas as $name => $schema) { $this->cloneTable($name, $sources[$name], $schema); } // Log in with a clean $user. $this->originalUser = $user; drupal_save_session(FALSE); $user = user_load(1); // Set up English language. unset($GLOBALS['conf']['language_default']); $language = language_default(); // Use the test mail class instead of the default mail handler class. variable_set('mail_system', array('default-system' => 'TestingMailSystem')); drupal_set_time_limit($this->timeLimit); $this->resetAll(); $this->refreshVariables(); $this->setup = TRUE; }
/** * Copy of propertyQuery() without the finishQuery execution. * * @see \EntityFieldQuery::propertyQuery() */ protected function prePropertyQuery() { if (empty($this->entityConditions['entity_type'])) { throw new \EntityFieldQueryException(t('For this query an entity type must be specified.')); } $entity_type = $this->entityConditions['entity_type']['value']; $entity_info = entity_get_info($entity_type); if (empty($entity_info['base table'])) { throw new \EntityFieldQueryException(t('Entity %entity has no base table.', array('%entity' => $entity_type))); } $base_table = $entity_info['base table']; $base_table_schema = drupal_get_schema($base_table); $select_query = db_select($base_table); $select_query->addExpression(':entity_type', 'entity_type', array(':entity_type' => $entity_type)); // Process the property conditions. foreach ($this->propertyConditions as $property_condition) { $this->addCondition($select_query, $base_table . '.' . $property_condition['column'], $property_condition); } // Process the four possible entity condition. // The id field is always present in entity keys. $sql_field = $entity_info['entity keys']['id']; $this->addMetaData('base_table', $base_table); $this->addMetaData('entity_id_key', $sql_field); $id_map['entity_id'] = $sql_field; $select_query->addField($base_table, $sql_field, 'entity_id'); if (isset($this->entityConditions['entity_id'])) { $this->addCondition($select_query, $base_table . '.' . $sql_field, $this->entityConditions['entity_id']); } // If there is a revision key defined, use it. if (!empty($entity_info['entity keys']['revision'])) { $sql_field = $entity_info['entity keys']['revision']; $select_query->addField($base_table, $sql_field, 'revision_id'); if (isset($this->entityConditions['revision_id'])) { $this->addCondition($select_query, $base_table . '.' . $sql_field, $this->entityConditions['revision_id']); } } else { $sql_field = 'revision_id'; $select_query->addExpression('NULL', 'revision_id'); } $id_map['revision_id'] = $sql_field; // Handle bundles. if (!empty($entity_info['entity keys']['bundle'])) { $sql_field = $entity_info['entity keys']['bundle']; $having = FALSE; if (!empty($base_table_schema['fields'][$sql_field])) { $select_query->addField($base_table, $sql_field, 'bundle'); } } else { $sql_field = 'bundle'; $select_query->addExpression(':bundle', 'bundle', array(':bundle' => $entity_type)); $having = TRUE; } $id_map['bundle'] = $sql_field; if (isset($this->entityConditions['bundle'])) { if (!empty($entity_info['entity keys']['bundle'])) { $this->addCondition($select_query, $base_table . '.' . $sql_field, $this->entityConditions['bundle'], $having); } else { // This entity has no bundle, so invalidate the query. $select_query->where('1 = 0'); } } // Order the query. foreach ($this->order as $order) { if ($order['type'] == 'entity') { $key = $order['specifier']; if (!isset($id_map[$key])) { throw new \EntityFieldQueryException(t('Do not know how to order on @key for @entity_type', array('@key' => $key, '@entity_type' => $entity_type))); } $select_query->orderBy($id_map[$key], $order['direction']); } elseif ($order['type'] == 'property') { $select_query->orderBy($base_table . '.' . $order['specifier'], $order['direction']); } } return $select_query; }
/** * Tasks performed after the database is initialized. */ function install_tasks($profile, $task) { global $base_url, $install_locale; // Bootstrap newly installed Drupal, while preserving existing messages. $messages = isset($_SESSION['messages']) ? $_SESSION['messages'] : ''; drupal_install_init_database(); drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); drupal_set_session('messages', $messages); // URL used to direct page requests. $url = $base_url . '/install.php?locale=' . $install_locale . '&profile=' . $profile; // Build a page for final tasks. if (empty($task)) { variable_set('install_task', 'profile-install'); $task = 'profile-install'; } // We are using a list of if constructs here to allow for // passing from one task to the other in the same request. // Install profile modules. if ($task == 'profile-install') { $modules = variable_get('install_profile_modules', array()); $files = module_rebuild_cache(); variable_del('install_profile_modules'); $operations = array(); foreach ($modules as $module) { $operations[] = array('_install_module_batch', array($module, $files[$module]->info['name'])); } $batch = array('operations' => $operations, 'finished' => '_install_profile_batch_finished', 'title' => st('Installing @drupal', array('@drupal' => drupal_install_profile_name())), 'error_message' => st('The installation has encountered an error.')); // Start a batch, switch to 'profile-install-batch' task. We need to // set the variable here, because batch_process() redirects. variable_set('install_task', 'profile-install-batch'); batch_set($batch); batch_process($url, $url); } // We are running a batch install of the profile's modules. // This might run in multiple HTTP requests, constantly redirecting // to the same address, until the batch finished callback is invoked // and the task advances to 'locale-initial-import'. if ($task == 'profile-install-batch') { include_once DRUPAL_ROOT . '/includes/batch.inc'; $output = _batch_page(); } // Import interface translations for the enabled modules. if ($task == 'locale-initial-import') { if (!empty($install_locale) && $install_locale != 'en') { include_once DRUPAL_ROOT . '/includes/locale.inc'; // Enable installation language as default site language. locale_add_language($install_locale, NULL, NULL, NULL, '', NULL, 1, TRUE); // Collect files to import for this language. $batch = locale_batch_by_language($install_locale, '_install_locale_initial_batch_finished'); if (!empty($batch)) { // Remember components we cover in this batch set. variable_set('install_locale_batch_components', $batch['#components']); // Start a batch, switch to 'locale-batch' task. We need to // set the variable here, because batch_process() redirects. variable_set('install_task', 'locale-initial-batch'); batch_set($batch); batch_process($url, $url); } } // Found nothing to import or not foreign language, go to next task. $task = 'configure'; } if ($task == 'locale-initial-batch') { include_once DRUPAL_ROOT . '/includes/batch.inc'; include_once DRUPAL_ROOT . '/includes/locale.inc'; $output = _batch_page(); } if ($task == 'configure') { if (variable_get('site_name', FALSE) || variable_get('site_mail', FALSE)) { // Site already configured: This should never happen, means re-running // the installer, possibly by an attacker after the 'install_task' variable // got accidentally blown somewhere. Stop it now. install_already_done_error(); } $form = drupal_get_form('install_configure_form', $url); if (!variable_get('site_name', FALSE) && !variable_get('site_mail', FALSE)) { // Not submitted yet: Prepare to display the form. $output = $form; drupal_set_title(st('Configure site')); // Warn about settings.php permissions risk $settings_dir = './' . conf_path(); $settings_file = $settings_dir . '/settings.php'; if (!drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_NOT_WRITABLE) || !drupal_verify_install_file($settings_dir, FILE_NOT_WRITABLE, 'dir')) { drupal_set_message(st('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, please consult the <a href="@handbook_url">online handbook</a>.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/getting-started')), 'error'); } else { drupal_set_message(st('All necessary changes to %dir and %file have been made. They have been set to read-only for security.', array('%dir' => $settings_dir, '%file' => $settings_file))); } // Add JavaScript validation. _user_password_dynamic_validation(); drupal_add_js(drupal_get_path('module', 'system') . '/system.js'); // Add JavaScript time zone detection. drupal_add_js('misc/timezone.js'); // We add these strings as settings because JavaScript translation does not // work on install time. drupal_add_js(array('copyFieldValue' => array('edit-site-mail' => array('edit-account-mail')), 'cleanURL' => array('success' => st('Your server has been successfully tested to support this feature.'), 'failure' => st('Your system configuration does not currently support this feature. The <a href="http://drupal.org/node/15365">handbook page on Clean URLs</a> has additional troubleshooting information.'), 'testing' => st('Testing clean URLs...'))), 'setting'); drupal_add_js(' // Global Killswitch if (Drupal.jsEnabled) { $(document).ready(function() { Drupal.cleanURLsInstallCheck(); }); }', 'inline'); // Build menu to allow clean URL check. menu_rebuild(); // Cache a fully-built schema. This is necessary for any // invocation of index.php because: (1) setting cache table // entries requires schema information, (2) that occurs during // bootstrap before any module are loaded, so (3) if there is no // cached schema, drupal_get_schema() will try to generate one // but with no loaded modules will return nothing. // // This logically could be done during task 'done' but the clean // URL check requires it now. drupal_get_schema(NULL, TRUE); } else { $task = 'profile'; } } // If found an unknown task or the 'profile' task, which is // reserved for profiles, hand over the control to the profile, // so it can run any number of custom tasks it defines. if (!in_array($task, install_reserved_tasks())) { $function = $profile . '_profile_tasks'; if (function_exists($function)) { // The profile needs to run more code, maybe even more tasks. // $task is sent through as a reference and may be changed! $output = $function($task, $url); } // If the profile doesn't move on to a new task we assume // that it is done. if ($task == 'profile') { $task = 'profile-finished'; } } // Profile custom tasks are done, so let the installer regain // control and proceed with importing the remaining translations. if ($task == 'profile-finished') { if (!empty($install_locale) && $install_locale != 'en') { include_once DRUPAL_ROOT . '/includes/locale.inc'; // Collect files to import for this language. Skip components // already covered in the initial batch set. $batch = locale_batch_by_language($install_locale, '_install_locale_remaining_batch_finished', variable_get('install_locale_batch_components', array())); // Remove temporary variable. variable_del('install_locale_batch_components'); if (!empty($batch)) { // Start a batch, switch to 'locale-remaining-batch' task. We need to // set the variable here, because batch_process() redirects. variable_set('install_task', 'locale-remaining-batch'); batch_set($batch); batch_process($url, $url); } } // Found nothing to import or not foreign language, go to next task. $task = 'finished'; } if ($task == 'locale-remaining-batch') { include_once DRUPAL_ROOT . '/includes/batch.inc'; include_once DRUPAL_ROOT . '/includes/locale.inc'; $output = _batch_page(); } // Display a 'finished' page to user. if ($task == 'finished') { drupal_set_title(st('@drupal installation complete', array('@drupal' => drupal_install_profile_name()))); $messages = drupal_set_message(); $output = '<p>' . st('Congratulations, @drupal has been successfully installed.', array('@drupal' => drupal_install_profile_name())) . '</p>'; $output .= '<p>' . (isset($messages['error']) ? st('Please review the messages above before continuing on to <a href="@url">your new site</a>.', array('@url' => url(''))) : st('You may now visit <a href="@url">your new site</a>.', array('@url' => url('')))) . '</p>'; $task = 'done'; } // The end of the install process. Remember profile used. if ($task == 'done') { // Rebuild menu and registry to get content type links registered by the // profile, and possibly any other menu items created through the tasks. menu_rebuild(); // Register actions declared by any modules. actions_synchronize(); // Randomize query-strings on css/js files, to hide the fact that // this is a new install, not upgraded yet. _drupal_flush_css_js(); variable_set('install_profile', $profile); // Cache a fully-built schema. drupal_get_schema(NULL, TRUE); } // Set task for user, and remember the task in the database. install_task_list($task); variable_set('install_task', $task); // Run cron to populate update status tables (if available) so that users // will be warned if they've installed an out of date Drupal version. // Will also trigger indexing of profile-supplied content or feeds. drupal_cron_run(); // Output page, if some output was required. Otherwise it is possible // that we are printing a JSON page and theme output should not be there. if (isset($output)) { print theme('maintenance_page', $output); } }
/** * Update the storage information for a field. * * This is invoked on the field's storage module from field_update_field(), * before the new field information is saved to the database. The field storage * module should update its storage tables to agree with the new field * information. If there is a problem, the field storage module should throw an * exception. * * @param $field * The updated field structure to be saved. * @param $prior_field * The previously-saved field structure. * @param $has_data * TRUE if the field has data in storage currently. */ function hook_field_storage_update_field($field, $prior_field, $has_data) { if (!$has_data) { // There is no data. Re-create the tables completely. $prior_schema = _field_sql_storage_schema($prior_field); foreach ($prior_schema as $name => $table) { db_drop_table($name, $table); } $schema = _field_sql_storage_schema($field); foreach ($schema as $name => $table) { db_create_table($name, $table); } } else { // There is data. See field_sql_storage_field_storage_update_field() for // an example of what to do to modify the schema in place, preserving the // old data as much as possible. } drupal_get_schema(NULL, TRUE); }
/** * Delete created files and temporary files directory, delete the tables created by setUp(), * and reset the database prefix. */ function tearDown() { global $db_prefix; if (preg_match('/simpletest\\d+/', $db_prefix)) { // Delete temporary files directory and reset files directory path. simpletest_clean_temporary_directory(file_directory_path()); variable_set('file_directory_path', $this->original_file_directory); $schema = drupal_get_schema(NULL, TRUE); $ret = array(); foreach ($schema as $name => $table) { db_drop_table($ret, $name); } $db_prefix = $this->db_prefix_original; $this->_logged_in = FALSE; $this->curlClose(); } parent::tearDown(); }
/** * Tests expected behavior of installSchema(). */ function testInstallSchema() { $module = 'entity_test'; $table = 'entity_test_example'; // Verify that we can install a table from the module schema. $this->installSchema($module, $table); $this->assertTrue(db_table_exists($table), "'{$table}' database table found."); // Verify that the schema is known to Schema API. $schema = drupal_get_schema(); $this->assertTrue($schema[$table], "'{$table}' table found in schema."); $schema = drupal_get_schema($table); $this->assertTrue($schema, "'{$table}' table schema found."); // Verify that a unknown table from an enabled module throws an error. $table = 'unknown_entity_test_table'; try { $this->installSchema($module, $table); $this->fail('Exception for non-retrievable schema found.'); } catch (\Exception $e) { $this->pass('Exception for non-retrievable schema found.'); } $this->assertFalse(db_table_exists($table), "'{$table}' database table not found."); $schema = drupal_get_schema($table); $this->assertFalse($schema, "'{$table}' table schema not found."); // Verify that a table from a unknown module cannot be installed. $module = 'database_test'; $table = 'test'; try { $this->installSchema($module, $table); $this->fail('Exception for non-retrievable schema found.'); } catch (\Exception $e) { $this->pass('Exception for non-retrievable schema found.'); } $this->assertFalse(db_table_exists($table), "'{$table}' database table not found."); $schema = drupal_get_schema($table); $this->assertFalse($schema, "'{$table}' table schema not found."); // Verify that the same table can be installed after enabling the module. $this->enableModules(array($module)); $this->installSchema($module, $table); $this->assertTrue(db_table_exists($table), "'{$table}' database table found."); $schema = drupal_get_schema($table); $this->assertTrue($schema, "'{$table}' table schema found."); }
/** * Delete created files and temporary files directory, delete the tables created by setUp(), * and reset the database prefix. */ protected function tearDown() { global $db_prefix, $user, $language; // In case a fatal error occured that was not in the test process read the // log to pick up any fatal errors. $db_prefix_temp = $db_prefix; $db_prefix = $this->originalPrefix; simpletest_log_read($this->testId, $db_prefix, get_class($this), TRUE); $db_prefix = $db_prefix_temp; $emailCount = count(variable_get('drupal_test_email_collector', array())); if ($emailCount) { $message = format_plural($emailCount, t('!count e-mail was sent during this test.'), t('!count e-mails were sent during this test.'), array('!count' => $emailCount)); $this->pass($message, t('E-mail')); } if (preg_match('/simpletest\\d+/', $db_prefix)) { // Delete temporary files directory. file_unmanaged_delete_recursive($this->originalFileDirectory . '/simpletest/' . substr($db_prefix, 10)); // Remove all prefixed tables (all the tables in the schema). $schema = drupal_get_schema(NULL, TRUE); $ret = array(); foreach ($schema as $name => $table) { db_drop_table($name); } // Return the database prefix to the original. $db_prefix = $this->originalPrefix; // Return the user to the original one. $user = $this->originalUser; drupal_save_session(TRUE); // Ensure that internal logged in variable and cURL options are reset. $this->loggedInUser = FALSE; $this->additionalCurlOptions = array(); // Reload module list and implementations to ensure that test module hooks // aren't called after tests. module_list(TRUE); module_implements('', FALSE, TRUE); // Reset the Field API. field_cache_clear(); // Rebuild caches. $this->refreshVariables(); // Reset language. $language = $this->originalLanguage; if ($this->originalLanguageDefault) { $GLOBALS['conf']['language_default'] = $this->originalLanguageDefault; } // Close the CURL handler. $this->curlClose(); } }
/** * Installation task; perform final steps and display a 'finished' page. * * @param $install_state * An array of information about the current installation state. * @return * A message informing the user that the installation is complete. */ function install_finished(&$install_state) { drupal_set_title(st('@drupal installation complete', array('@drupal' => drupal_install_profile_distribution_name())), PASS_THROUGH); $messages = drupal_set_message(); $output = '<p>' . st('Congratulations, you installed @drupal!', array('@drupal' => drupal_install_profile_distribution_name())) . '</p>'; $output .= '<p>' . (isset($messages['error']) ? st('Review the messages above before visiting <a href="@url">your new site</a>.', array('@url' => url(''))) : st('<a href="@url">Visit your new site</a>.', array('@url' => url('')))) . '</p>'; // Rebuild the module and theme data, in case any newly-installed modules // need to modify it via hook_system_info_alter(). We need to clear the // theme static cache first, to make sure that the theme data is actually // rebuilt. drupal_static_reset('_system_rebuild_theme_data'); system_rebuild_module_data(); system_rebuild_theme_data(); // Flush all caches to ensure that any full bootstraps during the installer // do not leave stale cached data, and that any content types or other items // registered by the install profile are registered correctly. drupal_flush_all_caches(); // Register actions declared by any modules. actions_synchronize(); // Remember the profile which was used. variable_set('install_profile', drupal_get_profile()); // Install profiles are always loaded last db_update('system')->fields(array('weight' => 1000))->condition('type', 'module')->condition('name', drupal_get_profile())->execute(); // Cache a fully-built schema. drupal_get_schema(NULL, TRUE); // Run cron to populate update status tables (if available) so that users // will be warned if they've installed an out of date Drupal version. // Will also trigger indexing of profile-supplied content or feeds. drupal_cron_run(); return $output; }
/** * Reset all data structures after having enabled new modules. * * This method is called by DrupalWebTestCase::setUp() after enabling * the requested modules. It must be called again when additional modules * are enabled later. */ protected function resetAll() { // Reset all static variables. drupal_static_reset(); // Reset the list of enabled modules. module_list(TRUE); // Reset cached schema for new database prefix. This must be done before // drupal_flush_all_caches() so rebuilds can make use of the schema of // modules enabled on the cURL side. drupal_get_schema(NULL, TRUE); // Perform rebuilds and flush remaining caches. drupal_flush_all_caches(); // Reload global $conf array and permissions. $this->refreshVariables(); $this->checkPermissions(array(), TRUE); }
/** * Returns TRUE if field is part of the schema. * * @param string $fieldName * The name of the field whose existence we want to check. * * @access public * @static * @return boolean * TRUE if addresses have a field with the given name. * FALSE otherwise. */ public static function schemaFieldExists($fieldName) { $schema = drupal_get_schema('uc_addresses'); if (!empty($schema['fields']) && is_array($schema['fields'])) { return isset($schema['fields'][$fieldName]); } return FALSE; }
/** * Delete created files and temporary files directory, delete the tables created by setUp(), * and reset the database prefix. */ protected function tearDown() { global $user, $language; // In case a fatal error occurred that was not in the test process read the // log to pick up any fatal errors. simpletest_log_read($this->testId, $this->databasePrefix, get_class($this), TRUE); $emailCount = count(variable_get('drupal_test_email_collector', array())); if ($emailCount) { $message = format_plural($emailCount, '1 e-mail was sent during this test.', '@count e-mails were sent during this test.'); $this->pass($message, t('E-mail')); } // Delete temporary files directory. file_unmanaged_delete_recursive($this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10)); // Remove all prefixed tables (all the tables in the schema). $schema = drupal_get_schema(NULL, TRUE); foreach ($schema as $name => $table) { db_drop_table($name); } // Get back to the original connection. Database::removeConnection('default'); Database::renameConnection('simpletest_original_default', 'default'); // Restore original shutdown callbacks array to prevent original // environment of calling handlers from test run. $callbacks =& drupal_register_shutdown_function(); $callbacks = $this->originalShutdownCallbacks; // Return the user to the original one. $user = $this->originalUser; drupal_save_session(TRUE); // Ensure that internal logged in variable and cURL options are reset. $this->loggedInUser = FALSE; $this->additionalCurlOptions = array(); // Reload module list and implementations to ensure that test module hooks // aren't called after tests. module_list(TRUE); module_implements('', FALSE, TRUE); // Reset the Field API. field_cache_clear(); // Rebuild caches. $this->refreshVariables(); // Reset language. $language = $this->originalLanguage; if ($this->originalLanguageDefault) { $GLOBALS['conf']['language_default'] = $this->originalLanguageDefault; } // Close the CURL handler. $this->curlClose(); }
/** * Wraps drupal_get_schema(). */ protected function drupalGetSchema($table = NULL, $rebuild = FALSE) { return drupal_get_schema($table, $rebuild); }
function unl_remove_site($site_path, $uri, $db_prefix, $site_id) { // Grab the list of tables we need to drop. $schema = drupal_get_schema(NULL, TRUE); $tables = array_keys($schema); sort($tables); $database = $GLOBALS['databases']['default']['default']; $db_prefix .= '_' . $database['prefix']; $sites_subdir = unl_get_sites_subdir($uri); $sites_subdir = DRUPAL_ROOT . '/sites/' . $sites_subdir; $sites_subdir = realpath($sites_subdir); // A couple checks to make sure we aren't deleting something we shouldn't be. if (substr($sites_subdir, 0, strlen(DRUPAL_ROOT . '/sites/')) != DRUPAL_ROOT . '/sites/') { throw new Exception('Attempt to delete a directory outside DRUPAL_ROOT was aborted.'); } if (strlen($sites_subdir) <= strlen(DRUPAL_ROOT . '/sites/')) { throw new Exception('Attempt to delete a directory outside DRUPAL_ROOT was aborted.'); } // Drop the site's tables foreach ($tables as $table) { $table = $db_prefix . $table; try { db_query("DROP TABLE {$table}"); } catch (PDOException $e) { // probably already gone? } } // Do our best to remove the sites shell_exec('chmod -R u+w ' . escapeshellarg($sites_subdir)); shell_exec('rm -rf ' . escapeshellarg($sites_subdir)); // Remove the rewrite rules from .htaccess for this site. unl_remove_site_from_htaccess($site_id, FALSE); // If we were using memcache, flush its cache so new sites don't have stale data. if (class_exists('MemCacheDrupal', FALSE)) { dmemcache_flush(); } }
/** * Returns the schema for the given table. * * @param string $table * The table name. * * @return array|bool * The table field mapping for the given table or FALSE if not available. */ protected function getTableMapping($table, $entity_type_id) { $storage = $this->entityManager->getStorage($entity_type_id); if ($storage instanceof SqlEntityStorageInterface) { $mapping = $storage->getTableMapping()->getAllColumns($table); } else { // @todo Stop calling drupal_get_schema() once menu links are converted // to the Entity Field API. See https://drupal.org/node/1842858. $schema = drupal_get_schema($table); $mapping = array_keys($schema['fields']); } return array_flip($mapping); }