/** * Constructs a new DatabaseLockBackend. * * @param \Drupal\Core\Database\Connection $database * The database connection. */ public function __construct(Connection $database) { // __destruct() is causing problems with garbage collections, register a // shutdown function instead. drupal_register_shutdown_function(array($this, 'releaseAll')); $this->database = $database; }
/** * {@inheritdoc} */ public function set(AcquiaPurgeStateItemInterface $item) { if (!$this->commit) { $this->commit = TRUE; drupal_register_shutdown_function(array($this, 'commit')); } $this->items[$item->getKey()] = $item; $this->buffer[$item->getKey()] = $item->get(); }
/** * Default implementation from actual Drupal core. * * @see Redis_Lock_BackendInterface::getLockId() */ public function getLockId() { if (!isset($this->_lockId)) { $this->_lockId = uniqid(mt_rand(), TRUE); // We only register a shutdown function if a lock is used. drupal_register_shutdown_function('lock_release_all', $this->_lockId); } return $this->_lockId; }
/** * Registers a unique function call for execution on shutdown. * * Wrapper for drupal_register_shutdown_function() that does not add the * function call if it already exists in the shutdown function stack. * * @param callable $callback * The shutdown function to register. * @param ... * Additional arguments to pass to the shutdown function. * * @return bool * TRUE if the function was added, or FALSE if it was already in the stack. * * @see drupal_register_shutdown_function() */ public static function registerUniqueShutdownFunction($callback = NULL) { $args = func_get_args(); array_shift($args); $existing_callbacks = drupal_register_shutdown_function(); foreach ($existing_callbacks as $existing_callback) { if ($existing_callback['callback'] === $callback && $existing_callback['arguments'] === $args) { return FALSE; } } array_unshift($args, $callback); call_user_func_array('drupal_register_shutdown_function', $args); return TRUE; }
/** * {@inheritdoc} */ public function __construct($cid, $bin = 'default', $expire = Cache::PERMANENT, $tags = [Bootstrap::CACHE_TAG]) { $this->cid = "theme_registry:storage:{$cid}"; $this->bin = $bin; $this->changed = FALSE; $this->expire = $expire; $this->tags = $tags; // Register the cache object to save, if it's needed, on shutdown. drupal_register_shutdown_function([$this, 'save']); // Retrieve the cached data. $data = ($cached = \Drupal::cache($bin)->get($this->cid)) && !empty($cached->data) ? $cached->data : []; // Set the data. $this->setMultiple($data); // Cache has been initialized. $this->initialized = TRUE; }
/** * Perform setup tasks for all page requests. * * This hook is run at the beginning of the page request. It is typically * used to set up global parameters that are needed later in the request. * * Only use this hook if your code must run even for cached page views. This * hook is called before the theme, modules, or most include files are loaded * into memory. It happens while Drupal is still in bootstrap mode. * * @see hook_init() */ function hook_boot() { // We need user_access() in the shutdown function. Make sure it gets loaded. drupal_load('module', 'user'); drupal_register_shutdown_function('devel_shutdown'); }
/** * Initializes devel module requirements. */ public function onRequest(GetResponseEvent $event) { if (!devel_silent()) { if ($this->config->get('memory')) { global $memory_init; $memory_init = memory_get_usage(); } if (devel_query_enabled()) { Database::startLog('devel'); } if ($this->account->hasPermission('access devel information')) { devel_set_handler(devel_get_handlers()); // We want to include the class early so that anyone may call krumo() // as needed. See http://krumo.sourceforge.net/ has_krumo(); // See http://www.firephp.org/HQ/Install.htm $path = NULL; if (@(include_once 'fb.php') || @(include_once 'FirePHPCore/fb.php')) { // FirePHPCore is in include_path. Probably a PEAR installation. $path = ''; } elseif ($this->moduleHandler->moduleExists('libraries')) { // Support Libraries API - http://drupal.org/project/libraries $firephp_path = libraries_get_path('FirePHPCore'); $firephp_path = $firephp_path ? $firephp_path . '/lib/FirePHPCore/' : ''; $chromephp_path = libraries_get_path('chromephp'); } else { $firephp_path = DRUPAL_ROOT . '/libraries/FirePHPCore/lib/FirePHPCore/'; $chromephp_path = './' . drupal_get_path('module', 'devel') . '/chromephp'; } // Include FirePHP if it exists. if (!empty($firephp_path) && file_exists($firephp_path . 'fb.php')) { include_once $firephp_path . 'fb.php'; include_once $firephp_path . 'FirePHP.class.php'; } // Include ChromePHP if it exists. if (!empty($chromephp_path) && file_exists($chromephp_path .= '/ChromePhp.php')) { include_once $chromephp_path; } } } if ($this->config->get('rebuild_theme')) { drupal_theme_rebuild(); // Ensure that the active theme object is cleared. $theme_name = \Drupal::theme()->getActiveTheme()->getName(); \Drupal::state()->delete('theme.active_theme.' . $theme_name); \Drupal::theme()->resetActiveTheme(); /** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler*/ $theme_handler = \Drupal::service('theme_handler'); $theme_handler->refreshInfo(); // @todo This is not needed after https://www.drupal.org/node/2330755 $list = $theme_handler->listInfo(); $theme_handler->addTheme($list[$theme_name]); if (\Drupal::service('flood')->isAllowed('devel.rebuild_theme_warning', 1)) { \Drupal::service('flood')->register('devel.rebuild_theme_warning'); if (!devel_silent() && $this->account->hasPermission('access devel information')) { drupal_set_message(t('The theme information is being rebuilt on every request. Remember to <a href="!url">turn off</a> this feature on production websites.', array("!url" => $this->urlGenerator->generateFromRoute('devel.admin_settings')))); } } } drupal_register_shutdown_function('devel_shutdown'); }
/** * Cleans up the test environment and restores the original environment. * * Deletes created files, database tables, and reverts environment changes. * * This method needs to be invoked for both unit and integration tests. * * @see TestBase::prepareDatabasePrefix() * @see TestBase::changeDatabasePrefix() * @see TestBase::prepareEnvironment() */ private function restoreEnvironment() { // Destroy the session if one was started during the test-run. $_SESSION = array(); if (PHP_SAPI !== 'cli' && session_status() === PHP_SESSION_ACTIVE) { session_destroy(); $params = session_get_cookie_params(); setcookie(session_name(), '', REQUEST_TIME - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']); } session_name($this->originalSessionName); // Reset all static variables. // Unsetting static variables will potentially invoke destruct methods, // which might call into functions that prime statics and caches again. // In that case, all functions are still operating on the test environment, // which means they may need to access its filesystem and database. drupal_static_reset(); if ($this->container && $this->container->has('state') && ($state = $this->container->get('state'))) { $captured_emails = $state->get('system.test_mail_collector') ?: array(); $emailCount = count($captured_emails); if ($emailCount) { $message = $emailCount == 1 ? '1 email was sent during this test.' : $emailCount . ' emails were sent during this test.'; $this->pass($message, 'Email'); } } // Sleep for 50ms to allow shutdown functions and terminate events to // complete. Further information: https://www.drupal.org/node/2194357. usleep(50000); // Remove all prefixed tables. $original_connection_info = Database::getConnectionInfo('simpletest_original_default'); $original_prefix = $original_connection_info['default']['prefix']['default']; $test_connection_info = Database::getConnectionInfo('default'); $test_prefix = $test_connection_info['default']['prefix']['default']; if ($original_prefix != $test_prefix) { $tables = Database::getConnection()->schema()->findTables('%'); foreach ($tables as $table) { if (Database::getConnection()->schema()->dropTable($table)) { unset($tables[$table]); } } } // 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)); // Restore original dependency injection container. $this->container = $this->originalContainer; \Drupal::setContainer($this->originalContainer); // Delete test site directory. file_unmanaged_delete_recursive($this->siteDirectory, array($this, 'filePreDeleteCallback')); // Restore original database connection. Database::removeConnection('default'); Database::renameConnection('simpletest_original_default', 'default'); // Reset all static variables. // All destructors of statically cached objects have been invoked above; // this second reset is guaranteed to reset everything to nothing. drupal_static_reset(); // Restore original in-memory configuration. $GLOBALS['config'] = $this->originalConfig; $GLOBALS['conf'] = $this->originalConf; new Settings($this->originalSettings); // Restore original statics and globals. $GLOBALS['config_directories'] = $this->originalConfigDirectories; // Re-initialize original stream wrappers of the parent site. // This must happen after static variables have been reset and the original // container and $config_directories are restored, as simpletest_log_read() // uses the public stream wrapper to locate the error.log. $this->originalContainer->get('stream_wrapper_manager')->register(); if (isset($this->originalPrefix)) { drupal_valid_test_ua($this->originalPrefix); } else { drupal_valid_test_ua(FALSE); } // Restore original shutdown callbacks. $callbacks =& drupal_register_shutdown_function(); $callbacks = $this->originalShutdownCallbacks; }
/** * {@inheritdoc} */ protected function assertPostConditions() { // Execute registered Drupal shutdown functions prior to tearing down. // @see _drupal_shutdown_function() $callbacks =& drupal_register_shutdown_function(); while ($callback = array_shift($callbacks)) { call_user_func_array($callback['callback'], $callback['arguments']); } // Shut down the kernel (if bootKernel() was called). // @see \Drupal\system\Tests\DrupalKernel\DrupalKernelTest if ($this->container) { $this->container->get('kernel')->shutdown(); } // Fail in case any (new) shutdown functions exist. $this->assertCount(0, drupal_register_shutdown_function(), 'Unexpected Drupal shutdown callbacks exist after running shutdown functions.'); parent::assertPostConditions(); }
/** * Prepares the current environment for running the test. * * Also sets up new resources for the testing environment, such as the public * filesystem and configuration directories. * * This method is private as it must only be called once by * BrowserTestBase::setUp() (multiple invocations for the same test would have * unpredictable consequences) and it must not be callable or overridable by * test classes. */ protected function prepareEnvironment() { // Bootstrap Drupal so we can use Drupal's built in functions. $this->classLoader = (require __DIR__ . '/../../../../autoload.php'); $request = Request::createFromGlobals(); $kernel = TestRunnerKernel::createFromRequest($request, $this->classLoader); // TestRunnerKernel expects the working directory to be DRUPAL_ROOT. chdir(DRUPAL_ROOT); $kernel->prepareLegacyRequest($request); $this->prepareDatabasePrefix(); $this->originalSiteDirectory = $kernel->findSitePath($request); // Create test directory ahead of installation so fatal errors and debug // information can be logged during installation process. file_prepare_directory($this->siteDirectory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); // Prepare filesystem directory paths. $this->publicFilesDirectory = $this->siteDirectory . '/files'; $this->privateFilesDirectory = $this->siteDirectory . '/private'; $this->tempFilesDirectory = $this->siteDirectory . '/temp'; $this->translationFilesDirectory = $this->siteDirectory . '/translations'; // Ensure the configImporter is refreshed for each test. $this->configImporter = NULL; // Unregister all custom stream wrappers of the parent site. $wrappers = \Drupal::service('stream_wrapper_manager')->getWrappers(StreamWrapperInterface::ALL); foreach ($wrappers as $scheme => $info) { stream_wrapper_unregister($scheme); } // Reset statics. drupal_static_reset(); // Ensure there is no service container. $this->container = NULL; \Drupal::unsetContainer(); // Unset globals. unset($GLOBALS['config_directories']); unset($GLOBALS['config']); unset($GLOBALS['conf']); // Log fatal errors. ini_set('log_errors', 1); ini_set('error_log', DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log'); // Change the database prefix. $this->changeDatabasePrefix(); // After preparing the environment and changing the database prefix, we are // in a valid test environment. drupal_valid_test_ua($this->databasePrefix); // Reset settings. new Settings(array('hash_salt' => $this->databasePrefix)); drupal_set_time_limit($this->timeLimit); // Save and clean the shutdown callbacks array because it is static cached // and will be changed by the test run. Otherwise it will contain callbacks // from both environments and the testing environment will try to call the // handlers defined by the original one. $callbacks =& drupal_register_shutdown_function(); $this->originalShutdownCallbacks = $callbacks; $callbacks = []; }
/** * A simple page callback which adds a register shutdown function. */ public function shutdownFunctions($arg1, $arg2) { drupal_register_shutdown_function('_system_test_first_shutdown_function', $arg1, $arg2); // If using PHP-FPM then fastcgi_finish_request() will have been fired // preventing further output to the browser which means that the escaping of // the exception message can not be tested. // @see _drupal_shutdown_function() // @see \Drupal\system\Tests\System\ShutdownFunctionsTest if (function_exists('fastcgi_finish_request')) { return ['#markup' => 'The function fastcgi_finish_request exists when serving the request.']; } return []; }
/** * {@inheritdoc} */ public function __construct($service) { parent::__construct($service); drupal_register_shutdown_function(array($this, 'onShutdown')); }
/** * Fully initializes the git clone entity after it has been created or loaded. * * @param bool $force * Toggle determining whether or not to force a reinitialization. * * @return GitClone * The current GitClone entity instance. * * @see GitClone::save() * @see EntityController::load() * * @chainable */ public function init($force = FALSE) { if (!$force && isset($this->initialized)) { return $this; } $this->initialized = TRUE; // Ensure a Gitonomy repository is instantiated. if (!$force && !isset($this->repository)) { $options = _git_clone_gitonomy_options(); if (($path = $this->getPath(FALSE)) && !empty($this->url)) { $git_exists = file_exists("{$path}/.git"); if (!$git_exists && in_array($this->refType, self::$allowedRefs)) { try { $this->repository = Admin::init($path, FALSE, $options); $this->run('remote', array('add', 'origin', $this->url)); } catch (\Exception $e) { drupal_set_message($e->getMessage(), 'error'); } } elseif ($git_exists && in_array($this->refType, self::$allowedRefs)) { $this->repository = new Repository($path, $options); } } else { $temp_dir = 'temporary://git_clone-' . drupal_hash_base64(REQUEST_TIME); if (file_prepare_directory($temp_dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) { $temp_dir = drupal_realpath($temp_dir); drupal_register_shutdown_function(function () use($temp_dir) { if (file_exists($temp_dir)) { file_unmanaged_delete_recursive($temp_dir); } }); try { $this->repository = Admin::init($temp_dir, FALSE, $options); } catch (\Exception $e) { watchdog('git_clone', $e->getMessage(), WATCHDOG_ERROR); } } if (!$this->repository) { drupal_set_message(t('Unable to create temporary git clone repository: @directory. Please verify your system temporary directory is writable.', array('@directory' => $temp_dir)), 'error'); } } } // Initialize the settings. $this->getSettings(); // Initialize the refs. $this->getRefs($force); return $this; }
/** * Initializes devel module requirements. */ public function onRequest(GetResponseEvent $event) { if (!devel_silent()) { if ($this->config->get('memory')) { global $memory_init; $memory_init = memory_get_usage(); } if (devel_query_enabled()) { Database::startLog('devel'); } if ($this->account->hasPermission('access devel information')) { devel_set_handler(devel_get_handlers()); // We want to include the class early so that anyone may call krumo() // as needed. See http://krumo.sourceforge.net/ has_krumo(); // See http://www.firephp.org/HQ/Install.htm $path = NULL; if (@(include_once 'fb.php') || @(include_once 'FirePHPCore/fb.php')) { // FirePHPCore is in include_path. Probably a PEAR installation. $path = ''; } elseif ($this->moduleHandler->moduleExists('libraries')) { // Support Libraries API - http://drupal.org/project/libraries $firephp_path = libraries_get_path('FirePHPCore'); $firephp_path = $firephp_path ? $firephp_path . '/lib/FirePHPCore/' : ''; $chromephp_path = libraries_get_path('chromephp'); } else { $firephp_path = DRUPAL_ROOT . '/libraries/FirePHPCore/lib/FirePHPCore/'; $chromephp_path = './' . drupal_get_path('module', 'devel') . '/chromephp'; } // Include FirePHP if it exists. if (!empty($firephp_path) && file_exists($firephp_path . 'fb.php')) { include_once $firephp_path . 'fb.php'; include_once $firephp_path . 'FirePHP.class.php'; } // Include ChromePHP if it exists. if (!empty($chromephp_path) && file_exists($chromephp_path .= '/ChromePhp.php')) { include_once $chromephp_path; } } } if ($this->config->get('rebuild_theme_registry')) { drupal_theme_rebuild(); if (\Drupal::service('flood')->isAllowed('devel.rebuild_registry_warning', 1)) { \Drupal::service('flood')->register('devel.rebuild_registry_warning'); if (!devel_silent() && $this->account->hasPermission('access devel information')) { drupal_set_message(t('The theme registry is being rebuilt on every request. Remember to <a href="!url">turn off</a> this feature on production websites.', array("!url" => url('admin/config/development/devel')))); } } } drupal_register_shutdown_function('devel_shutdown'); }
/** * Overrides SearchApiEntityDataSourceController::startTracking(). * * Reverts the behavior to always use getAllItemIds(), instead of taking a * shortcut via "base table". * * This method will also be called when the multilingual configuration of an * index changes, to take care of new and/or out-dated IDs. */ public function startTracking(array $indexes) { if (!$this->table) { return; } // We first clear the tracking table for all indexes, so we can just insert // all items again without any key conflicts. $this->stopTracking($indexes); $operations = array(); // Find out number of all entities to be processed. foreach ($indexes as $index) { $entity_ids = $this->getTrackableEntityIds($index); $steps = ceil(count($entity_ids) / $index->options['cron_limit']); for ($step = 0; $step < $steps; $step++) { $operations[] = array('search_api_et_batch_queue_entities', array($index, $entity_ids, $step)); } } // This might be called both from web interface as well as from drush. $t = drupal_is_cli() ? 'dt' : 't'; $batch = array('title' => $t('Adding items to the index queue'), 'operations' => $operations, 'finished' => 'search_api_et_batch_queue_entities_finished', 'progress_message' => $t('Completed about @percentage% of the queueing operation.'), 'file' => drupal_get_path('module', 'search_api_et') . '/search_api_et.batch.inc'); batch_set($batch); if (drupal_is_cli()) { // Calling drush_backend_batch_process() to start batch execution directly // from here doesn't work for some unknown reason, so we need to call it // from a shutdown function instead. drupal_register_shutdown_function('search_api_et_shutdown_batch_process'); } else { batch_process(); } }
/** * 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; }
/** * @Given I update the moderation state of :named_entity to :state * @Given I update the moderation state of :named_entity to :state on date :date * @Given :workflow_user updates the moderation state of :named_entity to :state * @Given :workflow_user updates the moderation state of :named_entity to :state on date :date * * Transition a Moderated Node from one state to another. * * @param String|null $user The string of the username. * @param String $named_entity A named entity stored in the entity store. * @param String $state The state that you want to transition to. * @param String|null $date A valid php datetime string. Supports relative dates. * @throws \Exception */ public function transitionModerationState($workflow_user = null, $named_entity, $state, $date = null) { global $user; // Save the original user to set it back later $global_user = $user; $node = $this->getModerationNode($named_entity); $possible_states = workbench_moderation_state_labels(); $state_key = array_search($state, $possible_states); if (!$state_key) { $possible_states = implode(", ", $possible_states); throw new \Exception("State '{$state}' is not available. All possible states are [{$possible_states}]."); } $current_user = $workflow_user ? user_load_by_name($workflow_user) : $this->getCurrentUser(); if (!$current_user) { throw new \Exception("No user is logged in."); } $my_revision = $node->workbench_moderation['my_revision']; $state_machine_name = array_search($state, $possible_states); // If node is moderated to the same state but with different time, then the moderation isn't performed but the time is updated. if ($my_revision->state != $state_machine_name) { $next_states = workbench_moderation_states_next($my_revision->state, $current_user, $node); if (empty($next_states)) { $next_states = array(); } if (!isset($next_states[$state_key])) { $next_states = implode(", ", $next_states); throw new \Exception("State '{$possible_states[$state_key]}' is not available to transition to. Transitions available to user '{$current_user->name}' are [{$next_states}]"); } // Change global user to the current user in order to allow // workflow moderation to get the right user. $user = $current_user; // This function actually updates the transition. workbench_moderation_moderate($node, $state_key); // the workbench_moderation_moderate defer some status updates on the // node (currently the "Publish" status) to the process shutdown. Which // does not work well on Behat since scenarios are run on a single drupal // bootstrap. // To work around this setup. After calling the // `workbench_moderation_moderate` callback we check if a call to the // `workbench_moderation_store` function is part of the shutdown // execution and run it. $callbacks =& drupal_register_shutdown_function(); while (list($key, $callback) = each($callbacks)) { if ($callback['callback'] == 'workbench_moderation_store') { call_user_func_array($callback['callback'], $callback['arguments']); unset($callbacks[$key]); } } // Back global user to the original user. Probably an anonymous. $user = $global_user; } // If a specific date is requested, then updated it after the fact. if (isset($date)) { $timestamp = strtotime($date, REQUEST_TIME); if (!$timestamp) { throw new \Exception("Error creating datetime from string '{$date}'"); } db_update('workbench_moderation_node_history')->fields(array('stamp' => $timestamp))->condition('nid', $node->nid, '=')->condition('vid', $node->vid, '=')->execute(); } }
/** * 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(); }
/** * 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. $tables = db_find_tables($this->databasePrefix . '%'); $connection_info = Database::getConnectionInfo('default'); $tables = db_find_tables($connection_info['default']['prefix']['default'] . '%'); if (empty($tables)) { $this->fail('Failed to find test tables to drop.'); } $prefix_length = strlen($connection_info['default']['prefix']['default']); foreach ($tables as $table) { if (db_drop_table(substr($table, $prefix_length))) { unset($tables[$table]); } } if (!empty($tables)) { $this->fail('Failed to drop all prefixed tables.'); } // 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 public files directory. $GLOBALS['conf']['file_public_path'] = $this->originalFileDirectory; // Reset language. $language = $this->originalLanguage; if ($this->originalLanguageDefault) { $GLOBALS['conf']['language_default'] = $this->originalLanguageDefault; } // Close the CURL handler and reset the cookies array so test classes // containing multiple tests are not polluted. $this->curlClose(); $this->cookies = array(); }