function install_begin_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.

Parameters

$install_state: An array of information about the current installation state. This is modified with information gleaned from the beginning of the page request.

1 call to install_begin_request()
install_drupal in drupal/core/includes/install.core.inc
Installs Drupal either interactively or via an array of passed-in settings.

File

drupal/core/includes/install.core.inc, line 251
API functions for installing Drupal.

Code

function install_begin_request(&$install_state) {

  // Add any installation parameters passed in via the URL.
  if ($install_state['interactive']) {
    $install_state['parameters'] += $_GET;
  }

  // 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($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
    exit;
  }

  // A request object from the HTTPFoundation to tell us about the request.
  $request = Request::createFromGlobals();

  // This must go after drupal_bootstrap(), which unsets globals!
  global $conf;

  // 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.
  if (!empty($install_state['parameters']['langcode']) && language_default()->langcode != $install_state['parameters']['langcode']) {
    $GLOBALS['conf']['language_default'] = array(
      'langcode' => $install_state['parameters']['langcode'],
    );
  }
  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');

  // Load module basics (needed for hook invokes).
  include_once __DIR__ . '/module.inc';
  include_once __DIR__ . '/session.inc';
  require_once __DIR__ . '/entity.inc';

  // Determine whether the configuration system is ready to operate.
  $install_state['config_verified'] = install_verify_config_directory(CONFIG_ACTIVE_DIRECTORY) && install_verify_config_directory(CONFIG_STAGING_DIRECTORY);

  // Check existing settings.php.
  $install_state['database_verified'] = install_verify_database_settings();
  $install_state['settings_verified'] = $install_state['config_verified'] && $install_state['database_verified'];

  // If it is not, replace the configuration storage with the InstallStorage
  // implementation, for the following reasons:
  // - The first call into drupal_container() will try to set up the regular
  //   runtime configuration storage, using the CachedStorage by default. It
  //   calls config_get_config_directory() to retrieve the config directory to
  //   use, but that throws an exception, since $config_directories is not
  //   defined since there is no settings.php yet. If there is a prepared
  //   settings.php already, then the returned directory still cannot be used,
  //   because it does not necessarily exist. The installer ensures that it
  //   exists and is writeable in a later step.
  // - The installer outputs maintenance theme pages and performs many other
  //   operations, which try to load configuration. Since there is no active
  //   configuration yet, and because the configuration system does not have a
  //   notion of default values at runtime, data is missing in many places. The
  //   lack of data does not trigger errors, but results in a broken user
  //   interface (e.g., missing page title, etc).
  // - The actual configuration data to read during installation is essentially
  //   the default configuration provided by the installation profile and
  //   modules (most notably System module). The InstallStorage therefore reads
  //   from the default configuration directories of extensions.
  // This override is reverted as soon as the config directory and the
  // database has been set up successfully.
  // @see drupal_install_config_directories()
  // @see install_settings_form_submit()
  if ($install_state['settings_verified']) {
    $kernel = new DrupalKernel('install', FALSE, drupal_classloader(), FALSE);
    $kernel
      ->boot();

    // Set the request in the kernel to the new created Request above
    // so it is available to the rest of the installation process.
    $kernel
      ->getContainer()
      ->set('request', $request);
  }
  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.context.factory', 'Drupal\\Core\\Config\\Context\\ConfigContextFactory')
      ->addArgument(new Reference('event_dispatcher'));
    $container
      ->register('config.context', 'Drupal\\Core\\Config\\Context\\ContextInterface')
      ->setFactoryService(new Reference('config.context.factory'))
      ->setFactoryMethod('get');
    $container
      ->register('config.factory', 'Drupal\\Core\\Config\\ConfigFactory')
      ->addArgument(new Reference('config.storage'))
      ->addArgument(new Reference('config.context'));

    // Register the 'language_manager' service.
    $container
      ->register('language_manager', 'Drupal\\Core\\Language\\LanguageManager');

    // Register the translation services.
    $container
      ->register('string_translator.custom_strings', 'Drupal\\Core\\StringTranslation\\Translator\\CustomStrings')
      ->addTag('string_translator');
    $container
      ->register('string_translation', 'Drupal\\Core\\StringTranslation\\TranslationManager');
    foreach (array(
      'bootstrap',
      'config',
      'cache',
      'menu',
      'page',
      'path',
    ) as $bin) {
      $container
        ->register("cache.{$bin}", 'Drupal\\Core\\Cache\\MemoryBackend')
        ->addArgument($bin);
    }

    // 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');

    // 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/)',
    ));

    // Register the expirable key value store used by form cache.
    $container
      ->register('keyvalue.expirable', 'Drupal\\Core\\KeyValueStore\\KeyValueExpirableFactory')
      ->addArgument(new Reference('service_container'));
    $container
      ->register('keyvalue.expirable.null', 'Drupal\\Core\\KeyValueStore\\KeyValueNullExpirableFactory');
    $conf['keyvalue_expirable_default'] = 'keyvalue.expirable.null';

    // Register Twig template engine for use during install.
    CoreBundle::registerTwig($container);
    $container
      ->register('url_generator', 'Drupal\\Core\\Routing\\NullGenerator');
    Drupal::setContainer($container);
  }

  // Set up $language, so t() caller functions will still work.
  drupal_language_initialize();

  // Append file translation to the translation chain.
  Drupal::translation()
    ->addTranslator(install_file_translation_service());

  // Add in installation language if present.
  if (isset($install_state['parameters']['langcode'])) {
    Drupal::translation()
      ->setDefaultLangcode($install_state['parameters']['langcode']);
  }
  require_once __DIR__ . '/ajax.inc';
  $module_handler = Drupal::moduleHandler();
  if (!$module_handler
    ->moduleExists('system')) {

    // Override the module list with a minimal set of modules.
    $module_handler
      ->setModuleList(array(
      'system' => 'core/modules/system/system.module',
    ));
  }
  $module_handler
    ->load('system');
  require_once __DIR__ . '/cache.inc';

  // 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
  // need to run it even in the case of command-line installations, to prevent
  // any code in the installer that happens to initialize the theme system from
  // accessing the database before it is set up yet.)
  drupal_maintenance_theme();
  if ($install_state['database_verified']) {

    // Initialize the database system. Note that the connection
    // won't be initialized until it is actually requested.
    require_once __DIR__ . '/database.inc';

    // Verify the last completed task in the database, if there is one.
    $task = install_verify_completed_task();
  }
  else {
    $task = NULL;

    // Do not install over a configured settings.php.
    if (!empty($GLOBALS['databases'])) {
      throw new Exception(install_already_done_error());
    }
  }

  // Ensure that the active configuration directory is empty before installation
  // starts.
  if ($install_state['config_verified'] && empty($task)) {
    $config = glob(config_get_config_directory(CONFIG_ACTIVE_DIRECTORY) . '/*.' . FileStorage::getFileExtension());
    if (!empty($config)) {
      $task = NULL;
      throw new Exception(install_already_done_error());
    }
  }

  // Modify the installation state as appropriate.
  $install_state['completed_task'] = $task;
  $install_state['database_tables_exist'] = !empty($task);

  // Add the list of available profiles to the installation state.
  $install_state['profiles'] += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\\.profile$/', 'profiles');
}