diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 8bbdd91..5cb7e88 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -1927,6 +1927,8 @@ function _drupal_exception_handler($exception) { * Sets up the script environment and loads settings.php. */ function _drupal_bootstrap_configuration() { + + drupal_environment_initialize(); // Initialize the configuration, including variables from settings.php. drupal_settings_initialize(); diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 0259cec..975b259 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -23,480 +23,480 @@ use Guzzle\Http\Exception\RequestException; /** - * @file - * API functions for installing Drupal. - */ +* @file +* API functions for installing Drupal. +*/ /** - * Do not run the task during the current installation request. - * - * This can be used to skip running an installation task when certain - * conditions are met, even though the task may still show on the list of - * installation tasks presented to the user. For example, the Drupal installer - * uses this flag to skip over the database configuration form when valid - * database connection information is already available from settings.php. It - * also uses this flag to skip language import tasks when the installation is - * being performed in English. - */ +* Do not run the task during the current installation request. +* +* This can be used to skip running an installation task when certain +* conditions are met, even though the task may still show on the list of +* installation tasks presented to the user. For example, the Drupal installer +* uses this flag to skip over the database configuration form when valid +* database connection information is already available from settings.php. It +* also uses this flag to skip language import tasks when the installation is +* being performed in English. +*/ const INSTALL_TASK_SKIP = 1; /** - * Run the task on each installation request that reaches it. - * - * This is primarily used by the Drupal installer for bootstrap-related tasks. - */ +* Run the task on each installation request that reaches it. +* +* This is primarily used by the Drupal installer for bootstrap-related tasks. +*/ const INSTALL_TASK_RUN_IF_REACHED = 2; /** - * Run the task on each installation request until the database is set up. - * - * This is the default method for running tasks and should be used for most - * tasks that occur after the database is set up; these tasks will then run - * once and be marked complete once they are successfully finished. For - * example, the Drupal installer uses this flag for the batch installation of - * modules on the new site, and also for the configuration form that collects - * basic site information and sets up the site maintenance account. - */ +* Run the task on each installation request until the database is set up. +* +* This is the default method for running tasks and should be used for most +* tasks that occur after the database is set up; these tasks will then run +* once and be marked complete once they are successfully finished. For +* example, the Drupal installer uses this flag for the batch installation of +* modules on the new site, and also for the configuration form that collects +* basic site information and sets up the site maintenance account. +*/ const INSTALL_TASK_RUN_IF_NOT_COMPLETED = 3; /** - * Installs Drupal either interactively or via an array of passed-in settings. - * - * The Drupal installation happens in a series of steps, which may be spread - * out over multiple page requests. Each request begins by trying to determine - * the last completed installation step (also known as a "task"), if one is - * available from a previous request. Control is then passed to the task - * handler, which processes the remaining tasks that need to be run until (a) - * an error is thrown, (b) a new page needs to be displayed, or (c) the - * installation finishes (whichever happens first). - * - * @param $settings - * An optional array of installation settings. Leave this empty for a normal, - * interactive, browser-based installation intended to occur over multiple - * page requests. Alternatively, if an array of settings is passed in, the - * installer will attempt to use it to perform the installation in a single - * page request (optimized for the command line) and not send any output - * intended for the web browser. See install_state_defaults() for a list of - * elements that are allowed to appear in this array. - * - * @see install_state_defaults() - */ +* Installs Drupal either interactively or via an array of passed-in settings. +* +* The Drupal installation happens in a series of steps, which may be spread +* out over multiple page requests. Each request begins by trying to determine +* the last completed installation step (also known as a "task"), if one is +* available from a previous request. Control is then passed to the task +* handler, which processes the remaining tasks that need to be run until (a) +* an error is thrown, (b) a new page needs to be displayed, or (c) the +* installation finishes (whichever happens first). +* +* @param $settings +* An optional array of installation settings. Leave this empty for a normal, +* interactive, browser-based installation intended to occur over multiple +* page requests. Alternatively, if an array of settings is passed in, the +* installer will attempt to use it to perform the installation in a single +* page request (optimized for the command line) and not send any output +* intended for the web browser. See install_state_defaults() for a list of +* elements that are allowed to appear in this array. +* +* @see install_state_defaults() +*/ function install_drupal($settings = array()) { - global $install_state; - // Initialize the installation state with the settings that were passed in, - // as well as a boolean indicating whether or not this is an interactive - // installation. - $interactive = empty($settings); - $install_state = $settings + array('interactive' => $interactive) + install_state_defaults(); - try { - // Begin the page request. This adds information about the current state of - // the Drupal installation to the passed-in array. - install_begin_request($install_state); - // Based on the installation state, run the remaining tasks for this page - // request, and collect any output. - $output = install_run_tasks($install_state); - } - catch (Exception $e) { - // When an installation error occurs, either send the error to the web - // browser or pass on the exception so the calling script can use it. - if ($install_state['interactive']) { - install_display_output($e->getMessage(), $install_state); - } - else { - throw $e; - } - } - // After execution, all tasks might be complete, in which case - // $install_state['installation_finished'] is TRUE. In case the last task - // has been processed, remove the global $install_state, so other code can - // reliably check whether it is running during the installer. - // @see drupal_installation_attempted() - $state = $install_state; - if (!empty($install_state['installation_finished'])) { - unset($GLOBALS['install_state']); - } - - // All available tasks for this page request are now complete. Interactive - // installations can send output to the browser or redirect the user to the - // next page. - if ($state['interactive']) { - if ($state['parameters_changed']) { - // Redirect to the correct page if the URL parameters have changed. - install_goto(install_redirect_url($state)); - } - elseif (isset($output)) { - // Display a page only if some output is available. Otherwise it is - // possible that we are printing a JSON page and theme output should - // not be shown. - install_display_output($output, $state); - } - } +global $install_state; +// Initialize the installation state with the settings that were passed in, +// as well as a boolean indicating whether or not this is an interactive +// installation. +$interactive = empty($settings); +$install_state = $settings + array('interactive' => $interactive) + install_state_defaults(); +try { +// Begin the page request. This adds information about the current state of +// the Drupal installation to the passed-in array. +install_begin_request($install_state); +// Based on the installation state, run the remaining tasks for this page +// request, and collect any output. +$output = install_run_tasks($install_state); +} +catch (Exception $e) { +// When an installation error occurs, either send the error to the web +// browser or pass on the exception so the calling script can use it. +if ($install_state['interactive']) { +install_display_output($e->getMessage(), $install_state); +} +else { +throw $e; +} +} +// After execution, all tasks might be complete, in which case +// $install_state['installation_finished'] is TRUE. In case the last task +// has been processed, remove the global $install_state, so other code can +// reliably check whether it is running during the installer. +// @see drupal_installation_attempted() +$state = $install_state; +if (!empty($install_state['installation_finished'])) { +unset($GLOBALS['install_state']); +} + +// All available tasks for this page request are now complete. Interactive +// installations can send output to the browser or redirect the user to the +// next page. +if ($state['interactive']) { +if ($state['parameters_changed']) { +// Redirect to the correct page if the URL parameters have changed. +install_goto(install_redirect_url($state)); +} +elseif (isset($output)) { +// Display a page only if some output is available. Otherwise it is +// possible that we are printing a JSON page and theme output should +// not be shown. +install_display_output($output, $state); +} +} } /** - * Returns an array of default settings for the global installation state. - * - * The installation state is initialized with these settings at the beginning - * of each page request. They may evolve during the page request, but they are - * initialized again once the next request begins. - * - * Non-interactive Drupal installations can override some of these default - * settings by passing in an array to the installation script, most notably - * 'parameters' (which contains one-time parameters such as 'profile' and - * 'langcode' that are normally passed in via the URL) and 'forms' (which can - * be used to programmatically submit forms during the installation; the keys - * of each element indicate the name of the installation task that the form - * submission is for, and the values are used as the $form_state['values'] - * array that is passed on to the form submission via drupal_form_submit()). - * - * @see drupal_form_submit() - */ +* Returns an array of default settings for the global installation state. +* +* The installation state is initialized with these settings at the beginning +* of each page request. They may evolve during the page request, but they are +* initialized again once the next request begins. +* +* Non-interactive Drupal installations can override some of these default +* settings by passing in an array to the installation script, most notably +* 'parameters' (which contains one-time parameters such as 'profile' and +* 'langcode' that are normally passed in via the URL) and 'forms' (which can +* be used to programmatically submit forms during the installation; the keys +* of each element indicate the name of the installation task that the form +* submission is for, and the values are used as the $form_state['values'] +* array that is passed on to the form submission via drupal_form_submit()). +* +* @see drupal_form_submit() +*/ function install_state_defaults() { - $defaults = array( - // The current task being processed. - 'active_task' => NULL, - // The last task that was completed during the previous installation - // request. - 'completed_task' => NULL, - // TRUE when there are valid config directories. - 'config_verified' => FALSE, - // TRUE when there is a valid database connection. - 'database_verified' => FALSE, - // TRUE when a valid settings.php exists (containing both database - // connection information and config directory names). - 'settings_verified' => FALSE, - // TRUE when the base system has been installed and is ready to operate. - 'base_system_verified' => FALSE, - // Whether a translation file for the selected language will be downloaded - // from the translation server. - 'download_translation' => FALSE, - // An array of forms to be programmatically submitted during the - // installation. The keys of each element indicate the name of the - // installation task that the form submission is for, and the values are - // used as the $form_state['values'] array that is passed on to the form - // submission via drupal_form_submit(). - 'forms' => array(), - // This becomes TRUE only at the end of the installation process, after - // all available tasks have been completed and Drupal is fully installed. - // It is used by the installer to store correct information in the database - // about the completed installation, as well as to inform theme functions - // that all tasks are finished (so that the task list can be displayed - // correctly). - 'installation_finished' => FALSE, - // Whether or not this installation is interactive. By default this will - // be set to FALSE if settings are passed in to install_drupal(). - 'interactive' => TRUE, - // An array of parameters for the installation, pre-populated by the URL - // or by the settings passed in to install_drupal(). This is primarily - // used to store 'profile' (the name of the chosen installation profile) - // and 'langcode' (the code of the chosen installation language), since - // these settings need to persist from page request to page request before - // the database is available for storage. - 'parameters' => array(), - // Whether or not the parameters have changed during the current page - // request. For interactive installations, this will trigger a page - // redirect. - 'parameters_changed' => FALSE, - // An array of information about the chosen installation profile. This will - // be filled in based on the profile's .info.yml file. - 'profile_info' => array(), - // An array of available installation profiles. - 'profiles' => array(), - // An array of server variables that will be substituted into the global - // $_SERVER array via drupal_override_server_variables(). Used by - // non-interactive installations only. - 'server' => array(), - // The server URL where the interface translation files can be downloaded. - // Tokens in the pattern will be replaced by appropriate values for the - // required translation file. - 'server_pattern' => 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po', - // Installation tasks can set this to TRUE to force the page request to - // end (even if there is no themable output), in the case of an interactive - // installation. This is needed only rarely; for example, it would be used - // by an installation task that prints JSON output rather than returning a - // themed page. The most common example of this is during batch processing, - // but the Drupal installer automatically takes care of setting this - // parameter properly in that case, so that individual installation tasks - // which implement the batch API do not need to set it themselves. - 'stop_page_request' => FALSE, - // Installation tasks can set this to TRUE to indicate that the task should - // be run again, even if it normally wouldn't be. This can be used, for - // example, if a single task needs to be spread out over multiple page - // requests, or if it needs to perform some validation before allowing - // itself to be marked complete. The most common examples of this are batch - // processing and form submissions, but the Drupal installer automatically - // takes care of setting this parameter properly in those cases, so that - // individual installation tasks which implement the batch API or form API - // do not need to set it themselves. - 'task_not_complete' => FALSE, - // A list of installation tasks which have already been performed during - // the current page request. - 'tasks_performed' => array(), - // An array of translation files URIs available for the installation. Keyed - // by the translation language code. - 'translations' => array(), - ); - return $defaults; +$defaults = array( +// The current task being processed. +'active_task' => NULL, +// The last task that was completed during the previous installation +// request. +'completed_task' => NULL, +// TRUE when there are valid config directories. +'config_verified' => FALSE, +// TRUE when there is a valid database connection. +'database_verified' => FALSE, +// TRUE when a valid settings.php exists (containing both database +// connection information and config directory names). +'settings_verified' => FALSE, +// TRUE when the base system has been installed and is ready to operate. +'base_system_verified' => FALSE, +// Whether a translation file for the selected language will be downloaded +// from the translation server. +'download_translation' => FALSE, +// An array of forms to be programmatically submitted during the +// installation. The keys of each element indicate the name of the +// installation task that the form submission is for, and the values are +// used as the $form_state['values'] array that is passed on to the form +// submission via drupal_form_submit(). +'forms' => array(), +// This becomes TRUE only at the end of the installation process, after +// all available tasks have been completed and Drupal is fully installed. +// It is used by the installer to store correct information in the database +// about the completed installation, as well as to inform theme functions +// that all tasks are finished (so that the task list can be displayed +// correctly). +'installation_finished' => FALSE, +// Whether or not this installation is interactive. By default this will +// be set to FALSE if settings are passed in to install_drupal(). +'interactive' => TRUE, +// An array of parameters for the installation, pre-populated by the URL +// or by the settings passed in to install_drupal(). This is primarily +// used to store 'profile' (the name of the chosen installation profile) +// and 'langcode' (the code of the chosen installation language), since +// these settings need to persist from page request to page request before +// the database is available for storage. +'parameters' => array(), +// Whether or not the parameters have changed during the current page +// request. For interactive installations, this will trigger a page +// redirect. +'parameters_changed' => FALSE, +// An array of information about the chosen installation profile. This will +// be filled in based on the profile's .info.yml file. +'profile_info' => array(), +// An array of available installation profiles. +'profiles' => array(), +// An array of server variables that will be substituted into the global +// $_SERVER array via drupal_override_server_variables(). Used by +// non-interactive installations only. +'server' => array(), +// The server URL where the interface translation files can be downloaded. +// Tokens in the pattern will be replaced by appropriate values for the +// required translation file. +'server_pattern' => 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po', +// Installation tasks can set this to TRUE to force the page request to +// end (even if there is no themable output), in the case of an interactive +// installation. This is needed only rarely; for example, it would be used +// by an installation task that prints JSON output rather than returning a +// themed page. The most common example of this is during batch processing, +// but the Drupal installer automatically takes care of setting this +// parameter properly in that case, so that individual installation tasks +// which implement the batch API do not need to set it themselves. +'stop_page_request' => FALSE, +// Installation tasks can set this to TRUE to indicate that the task should +// be run again, even if it normally wouldn't be. This can be used, for +// example, if a single task needs to be spread out over multiple page +// requests, or if it needs to perform some validation before allowing +// itself to be marked complete. The most common examples of this are batch +// processing and form submissions, but the Drupal installer automatically +// takes care of setting this parameter properly in those cases, so that +// individual installation tasks which implement the batch API or form API +// do not need to set it themselves. +'task_not_complete' => FALSE, +// A list of installation tasks which have already been performed during +// the current page request. +'tasks_performed' => array(), +// An array of translation files URIs available for the installation. Keyed +// by the translation language code. +'translations' => array(), +); +return $defaults; } /** - * Begins an installation request, modifying the installation state as needed. - * - * This function performs commands that must run at the beginning of every page - * request. It throws an exception if the installation should not proceed. - * - * @param $install_state - * An array of information about the current installation state. This is - * modified with information gleaned from the beginning of the page request. - */ +* Begins an installation request, modifying the installation state as needed. +* +* This function performs commands that must run at the beginning of every page +* request. It throws an exception if the installation should not proceed. +* +* @param $install_state +* An array of information about the current installation state. This is +* modified with information gleaned from the beginning of the page request. +*/ function install_begin_request(&$install_state) { - // A request object from the HTTPFoundation to tell us about the request. - $request = Request::createFromGlobals(); - - // Create a minimal container so that t() and $request will work. This - // container will be overriden but it's needed for the very early installation - // process when database tasks run. - $container = new ContainerBuilder(); - $container->set('request', $request); - \Drupal::setContainer($container); - - // Add any installation parameters passed in via the URL. - if ($install_state['interactive']) { - $install_state['parameters'] += $request->query->all(); - } - - // Validate certain core settings that are used throughout the installation. - if (!empty($install_state['parameters']['profile'])) { - $install_state['parameters']['profile'] = preg_replace('/[^a-zA-Z_0-9]/', '', $install_state['parameters']['profile']); - } - if (!empty($install_state['parameters']['langcode'])) { - $install_state['parameters']['langcode'] = preg_replace('/[^a-zA-Z_0-9\-]/', '', $install_state['parameters']['langcode']); - } - - // Allow command line scripts to override server variables used by Drupal. - require_once __DIR__ . '/bootstrap.inc'; - - if (!$install_state['interactive']) { - drupal_override_server_variables($install_state['server']); - } - - // Initialize conf_path(). - // This primes the site path to be used during installation. By not requiring - // settings.php, a bare site folder can be prepared in the /sites directory, - // which will be used for installing Drupal. - conf_path(FALSE); - - drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION); - - // If the hash salt leaks, it becomes possible to forge a valid testing user - // agent, install a new copy of Drupal, and take over the original site. To - // avoid this yet allow for automated testing of the installer, make sure - // there is also a special test-specific settings.php overriding conf_path(). - // _drupal_load_test_overrides() sets the simpletest_conf_path in-memory - // setting in this case. - if ($install_state['interactive'] && drupal_valid_test_ua() && !settings()->get('simpletest_conf_path')) { - header($request->server->get('SERVER_PROTOCOL') . ' 403 Forbidden'); - exit; - } - - // If we have a language selected and it is not yet saved in the system (eg. - // pre-database data screens we are unable to persistently store the default - // language), we should set language_default so the proper language is used to - // display installer pages as early as possible. - $default_language_values = Language::$defaultValues; - if (!empty($install_state['parameters']['langcode']) && $default_language_values['id'] != $install_state['parameters']['langcode']) { - $default_language_values = array('id' => $install_state['parameters']['langcode']); - } - // Register the 'language_manager' service. - $container->setParameter('language.default_values', $default_language_values); - $container->register('language.default', 'Drupal\Core\Language\LanguageDefault') - ->addArgument('%language.default_values%'); - $container->register('language_manager', 'Drupal\Core\Language\LanguageManager') - ->addArgument(new Reference('language.default')); - - require_once __DIR__ . '/../modules/system/system.install'; - require_once __DIR__ . '/common.inc'; - require_once __DIR__ . '/file.inc'; - require_once __DIR__ . '/install.inc'; - require_once __DIR__ . '/schema.inc'; - require_once __DIR__ . '/../../' . settings()->get('path_inc', 'core/includes/path.inc'); - require_once __DIR__ . '/cache.inc'; - require_once __DIR__ . '/database.inc'; - require_once __DIR__ . '/form.inc'; - require_once __DIR__ . '/batch.inc'; - require_once __DIR__ . '/ajax.inc'; - - // Load module basics (needed for hook invokes). - include_once __DIR__ . '/module.inc'; - include_once __DIR__ . '/session.inc'; - require_once __DIR__ . '/entity.inc'; - - // Register the translation services. - install_register_translation_service($container); - \Drupal::setContainer($container); - - // Determine whether base system services are ready to operate. - $install_state['config_verified'] = install_verify_config_directory(CONFIG_ACTIVE_DIRECTORY) && install_verify_config_directory(CONFIG_STAGING_DIRECTORY); - $install_state['database_verified'] = install_verify_database_settings(); - $install_state['settings_verified'] = $install_state['config_verified'] && $install_state['database_verified']; - - if ($install_state['settings_verified']) { - try { - $system_schema = system_schema(); - end($system_schema); - $table = key($system_schema); - $install_state['base_system_verified'] = Database::getConnection()->schema()->tableExists($table); - } - catch (DatabaseExceptionWrapper $e) { - // The last defined table of the base system_schema() does not exist yet. - // $install_state['base_system_verified'] defaults to FALSE, so the code - // following below will use the minimal installer service container. - // As soon as the base system is verified here, the installer operates in - // a full and regular Drupal environment, without any kind of exceptions. - } - } +// A request object from the HTTPFoundation to tell us about the request. +$request = Request::createFromGlobals(); + +// Create a minimal container so that t() and $request will work. This +// container will be overriden but it's needed for the very early installation +// process when database tasks run. +$container = new ContainerBuilder(); +$container->set('request', $request); +\Drupal::setContainer($container); + +// Add any installation parameters passed in via the URL. +if ($install_state['interactive']) { +$install_state['parameters'] += $request->query->all(); +} - if ($install_state['base_system_verified']) { - $kernel = new DrupalKernel('install', drupal_classloader(), FALSE); - $kernel->boot(); - $container = $kernel->getContainer(); - // Add the file translation service to the container. - $container->set('string_translator.file_translation', install_file_translation_service()); - $container->get('string_translation')->addTranslator($container->get('string_translator.file_translation')); - } - // Replace services with in-memory implementations and specialized installer - // implementations. This service container is reverted to a regular - // DrupalKernel in install_bootstrap_full(). - else { - // @todo Move into a proper Drupal\Core\DependencyInjection\InstallContainerBuilder. - $container = new ContainerBuilder(); - $container->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher'); +// Validate certain core settings that are used throughout the installation. +if (!empty($install_state['parameters']['profile'])) { +$install_state['parameters']['profile'] = preg_replace('/[^a-zA-Z_0-9]/', '', $install_state['parameters']['profile']); +} +if (!empty($install_state['parameters']['langcode'])) { +$install_state['parameters']['langcode'] = preg_replace('/[^a-zA-Z_0-9\-]/', '', $install_state['parameters']['langcode']); +} - $container->register('config.storage', 'Drupal\Core\Config\InstallStorage'); +// Allow command line scripts to override server variables used by Drupal. +require_once __DIR__ . '/bootstrap.inc'; - $container->register('config.storage.schema', 'Drupal\Core\Config\Schema\SchemaStorage'); +if (!$install_state['interactive']) { +drupal_override_server_variables($install_state['server']); +} - $container->register('config.typed', 'Drupal\Core\Config\TypedConfigManager') - ->addArgument(new Reference('config.storage')) - ->addArgument(new Reference('config.storage.schema')) - ->addArgument(new Reference('cache.config')); +// Initialize conf_path(). +// This primes the site path to be used during installation. By not requiring +// settings.php, a bare site folder can be prepared in the /sites directory, +// which will be used for installing Drupal. +conf_path(FALSE); + +drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION); + +// If the hash salt leaks, it becomes possible to forge a valid testing user +// agent, install a new copy of Drupal, and take over the original site. To +// avoid this yet allow for automated testing of the installer, make sure +// there is also a special test-specific settings.php overriding conf_path(). +// _drupal_load_test_overrides() sets the simpletest_conf_path in-memory +// setting in this case. +if ($install_state['interactive'] && drupal_valid_test_ua() && !settings()->get('simpletest_conf_path')) { +header($request->server->get('SERVER_PROTOCOL') . ' 403 Forbidden'); +exit; +} - $container->setParameter('language.default_values', Language::$defaultValues); - $container->register('language.default', 'Drupal\Core\Language\LanguageDefault') - ->addArgument('%language.default_values%'); +// If we have a language selected and it is not yet saved in the system (eg. +// pre-database data screens we are unable to persistently store the default +// language), we should set language_default so the proper language is used to +// display installer pages as early as possible. +$default_language_values = Language::$defaultValues; +if (!empty($install_state['parameters']['langcode']) && $default_language_values['id'] != $install_state['parameters']['langcode']) { +$default_language_values = array('id' => $install_state['parameters']['langcode']); +} +// Register the 'language_manager' service. +$container->setParameter('language.default_values', $default_language_values); +$container->register('language.default', 'Drupal\Core\Language\LanguageDefault') +->addArgument('%language.default_values%'); +$container->register('language_manager', 'Drupal\Core\Language\LanguageManager') +->addArgument(new Reference('language.default')); + +require_once __DIR__ . '/../modules/system/system.install'; +require_once __DIR__ . '/common.inc'; +require_once __DIR__ . '/file.inc'; +require_once __DIR__ . '/install.inc'; +require_once __DIR__ . '/schema.inc'; +require_once __DIR__ . '/../../' . settings()->get('path_inc', 'core/includes/path.inc'); +require_once __DIR__ . '/cache.inc'; +require_once __DIR__ . '/database.inc'; +require_once __DIR__ . '/form.inc'; +require_once __DIR__ . '/batch.inc'; +require_once __DIR__ . '/ajax.inc'; + +// Load module basics (needed for hook invokes). +include_once __DIR__ . '/module.inc'; +include_once __DIR__ . '/session.inc'; +require_once __DIR__ . '/entity.inc'; + +// Register the translation services. +install_register_translation_service($container); +\Drupal::setContainer($container); + +// Determine whether base system services are ready to operate. +$install_state['config_verified'] = install_verify_config_directory(CONFIG_ACTIVE_DIRECTORY) && install_verify_config_directory(CONFIG_STAGING_DIRECTORY); +$install_state['database_verified'] = install_verify_database_settings(); +$install_state['settings_verified'] = $install_state['config_verified'] && $install_state['database_verified']; + +if ($install_state['settings_verified']) { +try { +$system_schema = system_schema(); +end($system_schema); +$table = key($system_schema); +$install_state['base_system_verified'] = Database::getConnection()->schema()->tableExists($table); +} +catch (DatabaseExceptionWrapper $e) { +// The last defined table of the base system_schema() does not exist yet. +// $install_state['base_system_verified'] defaults to FALSE, so the code +// following below will use the minimal installer service container. +// As soon as the base system is verified here, the installer operates in +// a full and regular Drupal environment, without any kind of exceptions. +} +} - $container->register('config.factory', 'Drupal\Core\Config\ConfigFactory') - ->addArgument(new Reference('config.storage')) - ->addArgument(new Reference('event_dispatcher')) - ->addArgument(new Reference('config.typed')); +if ($install_state['base_system_verified']) { +$kernel = new DrupalKernel('install', drupal_classloader(), FALSE); +$kernel->boot(); +$container = $kernel->getContainer(); +// Add the file translation service to the container. +$container->set('string_translator.file_translation', install_file_translation_service()); +$container->get('string_translation')->addTranslator($container->get('string_translator.file_translation')); +} +// Replace services with in-memory implementations and specialized installer +// implementations. This service container is reverted to a regular +// DrupalKernel in install_bootstrap_full(). +else { +// @todo Move into a proper Drupal\Core\DependencyInjection\InstallContainerBuilder. +$container = new ContainerBuilder(); +$container->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher'); + +$container->register('config.storage', 'Drupal\Core\Config\InstallStorage'); + +$container->register('config.storage.schema', 'Drupal\Core\Config\Schema\SchemaStorage'); + +$container->register('config.typed', 'Drupal\Core\Config\TypedConfigManager') +->addArgument(new Reference('config.storage')) +->addArgument(new Reference('config.storage.schema')) +->addArgument(new Reference('cache.config')); + +$container->setParameter('language.default_values', Language::$defaultValues); +$container->register('language.default', 'Drupal\Core\Language\LanguageDefault') +->addArgument('%language.default_values%'); + +$container->register('config.factory', 'Drupal\Core\Config\ConfigFactory') +->addArgument(new Reference('config.storage')) +->addArgument(new Reference('event_dispatcher')) +->addArgument(new Reference('config.typed')); + +// Register the 'language_manager' service. +$container->register('language_manager', 'Drupal\Core\Language\LanguageManager') +->addArgument(new Reference('language.default')); + +// Register the translation services. +install_register_translation_service($container); + +foreach (array('bootstrap', 'config', 'cache', 'menu', 'page', 'path') as $bin) { +$container +->register("cache.$bin", 'Drupal\Core\Cache\MemoryBackend') +->addArgument($bin); +} - // Register the 'language_manager' service. - $container->register('language_manager', 'Drupal\Core\Language\LanguageManager') - ->addArgument(new Reference('language.default')); +// The install process cannot use the database lock backend since the database +// is not fully up, so we use a null backend implementation during the +// installation process. This will also speed up the installation process. +// The site being installed will use the real lock backend when doing AJAX +// requests but, except for a WSOD, there is no chance for a a lock to stall +// (as opposed to the cache backend) so we can afford having a null +// implementation here. +$container->register('lock', 'Drupal\Core\Lock\NullLockBackend'); + +$container +->register('theme.registry', 'Drupal\Core\Theme\Registry') +->addArgument(new Reference('cache.cache')) +->addArgument(new Reference('lock')) +->addArgument(new Reference('module_handler')) +->addTag('needs_destruction'); + +// Register a module handler for managing enabled modules. +$container +->register('module_handler', 'Drupal\Core\Extension\ModuleHandler'); + +// Register the Guzzle HTTP client for fetching translation files from a +// remote translation server such as localization.drupal.org. +$container->register('http_default_client', 'Guzzle\Http\Client') +->addArgument(NULL) +->addArgument(array( +'curl.CURLOPT_TIMEOUT' => 30.0, +'curl.CURLOPT_MAXREDIRS' => 3, +)) +->addMethodCall('setUserAgent', array('Drupal (+http://drupal.org/)')); + +$container->register('settings', 'Drupal\Component\Utility\Settings') +->setFactoryClass('Drupal\Component\Utility\Settings') +->setFactoryMethod('getSingleton'); + +$container +->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory'); +$container +->register('keyvalue.expirable', 'Drupal\Core\KeyValueStore\KeyValueNullExpirableFactory'); + +$container->register('state', 'Drupal\Core\KeyValueStore\State') +->addArgument(new Reference('keyvalue')); + +// Register Twig template engine for use during install. +CoreServiceProvider::registerTwig($container); + +$container->register('url_generator', 'Drupal\Core\Routing\NullGenerator'); + +$container->register('form_builder', 'Drupal\Core\Form\FormBuilder') +->addArgument(new Reference('module_handler')) +->addArgument(new Reference('keyvalue.expirable')) +->addArgument(new Reference('event_dispatcher')) +->addArgument(new Reference('url_generator')) +->addArgument(new Reference('string_translation')) +->addArgument(new Reference('csrf_token', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) +->addArgument(new Reference('http_kernel', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) +->addMethodCall('setRequest', array(new Reference('request'))); + +// Register UUID. +CoreServiceProvider::registerUuid($container); + +// Register the CSS and JavaScript asset collection renderers. +$container->register('asset.css.collection_renderer', 'Drupal\Core\Asset\CssCollectionRenderer') +->addArgument(new Reference('state')); +$container->register('asset.js.collection_renderer', 'Drupal\Core\Asset\JsCollectionRenderer') +->addArgument(new Reference('state')); + +// Register the info parser. +$container->register('info_parser', 'Drupal\Core\Extension\InfoParser'); + +$container->register('theme_handler', 'Drupal\Core\Extension\ThemeHandler') +->addArgument(new Reference('config.factory')) +->addArgument(new Reference('module_handler')) +->addArgument(new Reference('cache.cache')) +->addArgument(new Reference('info_parser')); + +// Overrides can not work at this point since this would cause the +// ConfigFactory to try to load language override configuration which is not +// supported by \Drupal\Core\Config\InstallStorage since loading a +// non-existing file would throw an exception. +$container->get('config.factory')->disableOverrides(); +} - // Register the translation services. - install_register_translation_service($container); +// Set the request in the kernel to the new created Request above +// so it is available to the rest of the installation process. +$container->set('request', $request); - foreach (array('bootstrap', 'config', 'cache', 'menu', 'page', 'path') as $bin) { - $container - ->register("cache.$bin", 'Drupal\Core\Cache\MemoryBackend') - ->addArgument($bin); - } +\Drupal::setContainer($container); - // The install process cannot use the database lock backend since the database - // is not fully up, so we use a null backend implementation during the - // installation process. This will also speed up the installation process. - // The site being installed will use the real lock backend when doing AJAX - // requests but, except for a WSOD, there is no chance for a a lock to stall - // (as opposed to the cache backend) so we can afford having a null - // implementation here. - $container->register('lock', 'Drupal\Core\Lock\NullLockBackend'); - - $container - ->register('theme.registry', 'Drupal\Core\Theme\Registry') - ->addArgument(new Reference('cache.cache')) - ->addArgument(new Reference('lock')) - ->addArgument(new Reference('module_handler')) - ->addTag('needs_destruction'); - - // Register a module handler for managing enabled modules. - $container - ->register('module_handler', 'Drupal\Core\Extension\ModuleHandler'); - - // Register the Guzzle HTTP client for fetching translation files from a - // remote translation server such as localization.drupal.org. - $container->register('http_default_client', 'Guzzle\Http\Client') - ->addArgument(NULL) - ->addArgument(array( - 'curl.CURLOPT_TIMEOUT' => 30.0, - 'curl.CURLOPT_MAXREDIRS' => 3, - )) - ->addMethodCall('setUserAgent', array('Drupal (+http://drupal.org/)')); - - $container->register('settings', 'Drupal\Component\Utility\Settings') - ->setFactoryClass('Drupal\Component\Utility\Settings') - ->setFactoryMethod('getSingleton'); - - $container - ->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory'); - $container - ->register('keyvalue.expirable', 'Drupal\Core\KeyValueStore\KeyValueNullExpirableFactory'); - - $container->register('state', 'Drupal\Core\KeyValueStore\State') - ->addArgument(new Reference('keyvalue')); - - // Register Twig template engine for use during install. - CoreServiceProvider::registerTwig($container); - - $container->register('url_generator', 'Drupal\Core\Routing\NullGenerator'); - - $container->register('form_builder', 'Drupal\Core\Form\FormBuilder') - ->addArgument(new Reference('module_handler')) - ->addArgument(new Reference('keyvalue.expirable')) - ->addArgument(new Reference('event_dispatcher')) - ->addArgument(new Reference('url_generator')) - ->addArgument(new Reference('string_translation')) - ->addArgument(new Reference('csrf_token', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) - ->addArgument(new Reference('http_kernel', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) - ->addMethodCall('setRequest', array(new Reference('request'))); - - // Register UUID. - CoreServiceProvider::registerUuid($container); - - // Register the CSS and JavaScript asset collection renderers. - $container->register('asset.css.collection_renderer', 'Drupal\Core\Asset\CssCollectionRenderer') - ->addArgument(new Reference('state')); - $container->register('asset.js.collection_renderer', 'Drupal\Core\Asset\JsCollectionRenderer') - ->addArgument(new Reference('state')); - - // Register the info parser. - $container->register('info_parser', 'Drupal\Core\Extension\InfoParser'); - - $container->register('theme_handler', 'Drupal\Core\Extension\ThemeHandler') - ->addArgument(new Reference('config.factory')) - ->addArgument(new Reference('module_handler')) - ->addArgument(new Reference('cache.cache')) - ->addArgument(new Reference('info_parser')); - - // Overrides can not work at this point since this would cause the - // ConfigFactory to try to load language override configuration which is not - // supported by \Drupal\Core\Config\InstallStorage since loading a - // non-existing file would throw an exception. - $container->get('config.factory')->disableOverrides(); - } - - // Set the request in the kernel to the new created Request above - // so it is available to the rest of the installation process. - $container->set('request', $request); - - \Drupal::setContainer($container); - - // Set up $language, so t() caller functions will still work. - drupal_language_initialize(); - // Add in installation language if present. - if (isset($install_state['parameters']['langcode'])) { - \Drupal::translation()->setDefaultLangcode($install_state['parameters']['langcode']); - } +// Set up $language, so t() caller functions will still work. +drupal_language_initialize(); +// Add in installation language if present. +if (isset($install_state['parameters']['langcode'])) { +\Drupal::translation()->setDefaultLangcode($install_state['parameters']['langcode']); +} $module_handler = \Drupal::moduleHandler(); if (!$module_handler->moduleExists('system')) { @@ -504,6 +504,42 @@ function install_begin_request(&$install_state) { $module_handler->setModuleList(array('system' => 'core/modules/system/system.module')); } $module_handler->load('system'); + + require_once DRUPAL_ROOT . '/core/includes/ajax.inc'; + // Locale module is required to locate and read string translation files. + $module_list['system']['filename'] = 'core/modules/system/system.module'; + $module_list['user']['filename'] = 'core/modules/user/user.module'; + $module_list['locale']['filename'] = 'core/modules/locale/locale.module'; + module_list(NULL, $module_list); + drupal_load('module', 'system'); + drupal_load('module', 'user'); + drupal_load('module', 'locale'); + + // At least Locale module requires its classes to be loadable. + foreach ($module_list as $name => $module) { + drupal_classloader_register($name, dirname($module['filename'])); + } + + // Load the cache infrastructure using a "fake" cache implementation that + // does not attempt to write to the database. We need this during the initial + // part of the installer because the database is not available yet. We + // continue to use it even when the database does become available, in order + // to preserve consistency between interactive and command-line installations + // (the latter complete in one page request and therefore are forced to + // continue using the cache implementation they started with) and also + // because any data put in the cache during the installer is inherently + // suspect, due to the fact that Drupal is not fully set up yet. + require_once DRUPAL_ROOT . '/core/includes/cache.inc'; + $conf['cache_classes'] = array('cache' => 'Drupal\Core\Cache\InstallBackend'); + + // The install process cannot use the database lock backend since the database + // is not fully up, so we use a null backend implementation during the + // installation process. This will also speed up the installation process. + // The site being installed will use the real lock backend when doing AJAX + // requests but, except for a WSOD, there is no chance for a a lock to stall + // (as opposed to the cache backend) so we can afford having a null + // implementation here. + $conf['lock_backend'] = 'Drupal\Core\Lock\NullLockBackend'; // Prepare for themed output. We need to run this at the beginning of the // page request to avoid a different theme accidentally getting set. (We also diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index a23ad91..9d2b674 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -288,10 +288,40 @@ function locale_language_delete($language) { * Array of installed languages keyed by language name. English is omitted * unless it is marked as translatable. */ + function locale_translatable_language_list() { $languages = language_list(); if (!locale_translate_english()) { unset($languages['en']); + +function locale($string = NULL, $context = NULL, $langcode = NULL) { + $language_interface = language(LANGUAGE_TYPE_INTERFACE); + + // Use the advanced drupal_static() pattern, since this is called very often. + static $drupal_static_fast; + if (!isset($drupal_static_fast)) { + $drupal_static_fast['locale'] = &drupal_static(__FUNCTION__, array('cache' => array(), 'exists' => NULL)); + } + $locale_t = &$drupal_static_fast['locale']['cache']; + $locale_exists = &$drupal_static_fast['locale']['exists']; + + // Check whether Locale module is actually installed and operational. + // The mere existence of locale() does not imply that Locale module is + // actually enabled and its database tables are installed. Since PHP code + // cannot be unloaded, this is typically the case in the environment that + // is executing a test. Well. And also in the installer, in which case Locale + // module is loaded in order import translations via the translations:// + // stream wrapper. However, Locale module's database tables do not actually + // exist yet, because language selection happens in the very first screen of + // the installer already, even before the bare minimal system is installed. + // Thus, we want to locate and read translation files, and we want to use st() + // to translate user interface strings, but when it comes to t() and the + // actual, regular behavior of locale() serving string translations, this must + // be avoided at all costs in the installer, since it cannot reasonably work + // just yet. If you read this far, you likely want to add this to your list of + // things you didn't want to know. + if (!isset($locale_exists)) { + $locale_exists = function_exists('module_exists') && module_exists('locale') && !drupal_installation_attempted(); } return $languages; } @@ -518,6 +548,7 @@ function locale_system_update(array $components) { * An array of arrays of component (theme and/or module) names to import * translations for, indexed by type. */ +<<<<<<< HEAD function locale_system_remove($components) { $components += array('module' => array(), 'theme' => array()); $list = array_merge($components['module'], $components['theme']); @@ -542,6 +573,14 @@ function locale_system_remove($components) { db_delete('locale_project') ->condition('name', $list) ->execute(); +======= +function locale_js_alter(&$javascript) { + // There is no database before Drupal. + if (drupal_installation_attempted()) { + return; + } + $language_interface = language(LANGUAGE_TYPE_INTERFACE); +>>>>>>> Applying patch from issue 6521362 comment 6521362 // Clear the translation status. locale_translation_status_delete_projects($list);