summaryrefslogtreecommitdiffstats
path: root/core/lib/Drupal/Core/Installer/InstallerServiceProvider.php
blob: f5fcf786a5a6534156efbcb21a5827eb2dd7f8d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?php

namespace Drupal\Core\Installer;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Drupal\Core\Messenger\StaticMessenger;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Service provider for the early installer environment.
 *
 * This class is manually added by install_begin_request() via
 * $conf['container_service_providers'] and required to prevent various services
 * from trying to retrieve data from storages that do not exist yet.
 */
class InstallerServiceProvider implements ServiceProviderInterface, ServiceModifierInterface {

  /**
   * {@inheritdoc}
   */
  public function register(ContainerBuilder $container) {
    // Inject the special configuration storage for the installer.
    // This special implementation MUST NOT be used anywhere else than the early
    // installer environment.
    $container->register('config.storage', 'Drupal\Core\Config\InstallStorage');

    // Replace services with in-memory implementations.
    $definition = $container->getDefinition('cache_factory');
    $definition->setClass('Drupal\Core\Cache\MemoryBackendFactory');
    $definition->setArguments(array());
    $definition->setMethodCalls(array());
    $container
      ->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueMemoryFactory');
    $container
      ->register('keyvalue.expirable', 'Drupal\Core\KeyValueStore\KeyValueNullExpirableFactory');
    $definition = $container->getDefinition('messenger');
    $definition->setClass(StaticMessenger::class);
    $definition->setArguments([new Reference('page_cache_kill_switch')]);

    // Replace services with no-op implementations.
    $container
      ->register('lock', 'Drupal\Core\Lock\NullLockBackend');
    $container
      ->register('url_generator', 'Drupal\Core\Routing\NullGenerator')
      ->addArgument(new Reference('request_stack'));
    $container
      ->register('path_processor_manager', 'Drupal\Core\PathProcessor\NullPathProcessorManager');
    $container
      ->register('router.dumper', 'Drupal\Core\Routing\NullMatcherDumper');

    // Remove the cache tags invalidator tag from the cache tags storage, so
    // that we don't call it when cache tags are invalidated very early in the
    // installer.
    $container->getDefinition('cache_tags.invalidator.checksum')
      ->clearTag('cache_tags_invalidator');

    // Replace the route builder with an empty implementation.
    // @todo Convert installer steps into routes; add an installer.routing.yml.
    $definition = $container->getDefinition('router.builder');
    $definition->setClass('Drupal\Core\Installer\InstallerRouteBuilder')
      // The core router builder, but there is no reason here to be lazy, so
      // we don't need to ship with a custom proxy class.
      ->setLazy(FALSE);
  }

  /**
   * {@inheritdoc}
   */
  public function alter(ContainerBuilder $container) {
    // Disable Twig cache (php storage does not exist yet).
    $twig_config = $container->getParameter('twig.config');
    $twig_config['cache'] = FALSE;
    $container->setParameter('twig.config', $twig_config);

    // No service may persist when the early installer kernel is rebooted into
    // the production environment.
    // @todo The DrupalKernel reboot performed by drupal_install_system() is
    //   actually not a "regular" reboot (like ModuleInstaller::install()), so
    //   services are not actually persisted.
    foreach ($container->findTaggedServiceIds('persist') as $id => $tags) {
      $definition = $container->getDefinition($id);
      $definition->clearTag('persist');
    }
  }

}