class UpdateKernel
Same name in other branches
- 9 core/lib/Drupal/Core/Update/UpdateKernel.php \Drupal\Core\Update\UpdateKernel
- 10 core/lib/Drupal/Core/Update/UpdateKernel.php \Drupal\Core\Update\UpdateKernel
- 11.x core/lib/Drupal/Core/Update/UpdateKernel.php \Drupal\Core\Update\UpdateKernel
Defines a kernel which is used primarily to run the update of Drupal.
We use a dedicated kernel + front controller (update.php) in order to be able to repair Drupal if it is in a broken state.
Hierarchy
- class \Drupal\Core\DrupalKernel implements \Drupal\Core\DrupalKernelInterface, \Symfony\Component\HttpKernel\TerminableInterface uses \Drupal\Core\Installer\InstallerRedirectTrait
- class \Drupal\Core\Update\UpdateKernel extends \Drupal\Core\DrupalKernel
Expanded class hierarchy of UpdateKernel
See also
\Drupal\system\Controller\DbUpdateController
4 files declare their use of UpdateKernel
- update.inc in core/
includes/ update.inc - Drupal database update API.
- update.php in ./
update.php - The PHP page that handles updating the Drupal installation.
- update.php in core/
assets/ scaffold/ files/ update.php - The PHP page that handles updating the Drupal installation.
- WorkspacesServiceProvider.php in core/
modules/ workspaces/ src/ WorkspacesServiceProvider.php
File
-
core/
lib/ Drupal/ Core/ Update/ UpdateKernel.php, line 24
Namespace
Drupal\Core\UpdateView source
class UpdateKernel extends DrupalKernel {
/**
* {@inheritdoc}
*/
public function discoverServiceProviders() {
parent::discoverServiceProviders();
$this->serviceProviderClasses['app']['update_kernel'] = 'Drupal\\Core\\Update\\UpdateServiceProvider';
}
/**
* {@inheritdoc}
*/
protected function initializeContainer() {
// Always force a container rebuild, in order to be able to override some
// services, see \Drupal\Core\Update\UpdateServiceProvider.
$this->containerNeedsRebuild = TRUE;
$container = parent::initializeContainer();
return $container;
}
/**
* {@inheritdoc}
*/
protected function cacheDrupalContainer(array $container_definition) {
// Don't save this particular container to cache, so it does not leak into
// the main site at all.
return FALSE;
}
/**
* {@inheritdoc}
*/
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
try {
static::bootEnvironment();
// First boot up basic things, like loading the include files.
$this->initializeSettings($request);
ReverseProxyMiddleware::setSettingsOnRequest($request, Settings::getInstance());
$this->boot();
$container = $this->getContainer();
/** @var \Symfony\Component\HttpFoundation\RequestStack $request_stack */
$request_stack = $container->get('request_stack');
$request_stack->push($request);
$this->preHandle($request);
// Handle the actual request. We need the session both for authentication
// as well as the DB update, like
// \Drupal\system\Controller\DbUpdateController::batchFinished.
$this->bootSession($request, $type);
$result = $this->handleRaw($request);
$this->shutdownSession($request);
return $result;
} catch (\Exception $e) {
return $this->handleException($e, $request, $type);
}
}
/**
* Generates the actual result of update.php.
*
* The actual logic of the update is done in the db update controller.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
*
* @return \Symfony\Component\HttpFoundation\Response
* A response object.
*
* @see \Drupal\system\Controller\DbUpdateController
*/
protected function handleRaw(Request $request) {
$container = $this->getContainer();
$this->handleAccess($request, $container);
/** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */
$controller_resolver = $container->get('controller_resolver');
/** @var callable $db_update_controller */
$db_update_controller = $controller_resolver->getControllerFromDefinition('\\Drupal\\system\\Controller\\DbUpdateController::handle');
$this->setupRequestMatch($request);
/** @var \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface $argument_resolver */
$argument_resolver = $container->get('http_kernel.controller.argument_resolver');
$arguments = $argument_resolver->getArguments($request, $db_update_controller);
return call_user_func_array($db_update_controller, $arguments);
}
/**
* Boots up the session.
*
* This method + shutdownSession() basically simulates what
* \Drupal\Core\StackMiddleware\Session does.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
*/
protected function bootSession(Request $request) {
$container = $this->getContainer();
/** @var \Symfony\Component\HttpFoundation\Session\SessionInterface $session */
$session = $container->get('session');
$session->start();
$request->setSession($session);
}
/**
* Ensures that the session is saved.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
*/
protected function shutdownSession(Request $request) {
if ($request->hasSession()) {
$request->getSession()
->save();
}
}
/**
* Set up the request with fake routing data for update.php.
*
* This fake routing data is needed in order to make batch API work properly.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
*/
protected function setupRequestMatch(Request $request) {
$path = $request->getPathInfo();
$args = explode('/', ltrim($path, '/'));
$request->attributes
->set(RouteObjectInterface::ROUTE_NAME, 'system.db_update');
$request->attributes
->set(RouteObjectInterface::ROUTE_OBJECT, $this->getContainer()
->get('router.route_provider')
->getRouteByName('system.db_update'));
$op = $args[0] ?: 'info';
$request->attributes
->set('op', $op);
$request->attributes
->set('_raw_variables', new ParameterBag([
'op' => $op,
]));
}
/**
* Checks if the current user has rights to access updates page.
*
* If the current user does not have the rights, an exception is thrown.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The incoming request.
*
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
* Thrown when update.php should not be accessible.
*/
protected function handleAccess(Request $request) {
/** @var \Drupal\Core\Authentication\AuthenticationManager $authentication_manager */
$authentication_manager = $this->getContainer()
->get('authentication');
$account = $authentication_manager->authenticate($request) ?: new AnonymousUserSession();
/** @var \Drupal\Core\Session\AccountProxyInterface $current_user */
$current_user = $this->getContainer()
->get('current_user');
$current_user->setAccount($account);
/** @var \Drupal\system\Access\DbUpdateAccessCheck $db_update_access */
$db_update_access = $this->getContainer()
->get('access_check.db_update');
if (!Settings::get('update_free_access', FALSE) && !$db_update_access->access($account)
->isAllowed()) {
throw new AccessDeniedHttpException('In order to run update.php you need to either have "Administer software updates" permission or have set $settings[\'update_free_access\'] in your settings.php.');
}
}
/**
* {@inheritdoc}
*/
public function loadLegacyIncludes() {
parent::loadLegacyIncludes();
static::fixSerializedExtensionObjects($this->container);
}
/**
* Fixes caches and theme info if they contain old Extension objects.
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The container.
*
* @internal
* This function is only to be called by the Drupal core update process.
* Additionally, this function will be removed in minor release of Drupal.
*
* @todo https://www.drupal.org/project/drupal/issues/3031322 Remove once
* Drupal 8.6.x is not supported.
*/
public static function fixSerializedExtensionObjects(ContainerInterface $container) {
// Create a custom error handler that will clear caches if a warning occurs
// while getting 'system.theme.data' from state. If this state value was
// created by Drupal <= 8.6.7 then when it is read by Drupal >= 8.6.8 there
// will be PHP warnings. This silently fixes Drupal so that the update can
// continue.
$clear_caches = FALSE;
$callable = function ($errno, $errstr) use ($container, &$clear_caches) {
if ($errstr === 'Class Drupal\\Core\\Extension\\Extension has no unserializer') {
$clear_caches = TRUE;
}
};
set_error_handler($callable, E_ERROR | E_WARNING);
$container->get('state')
->get('system.theme.data', []);
restore_error_handler();
if ($clear_caches) {
// Reset static caches in profile list so the module list is rebuilt
// correctly.
$container->get('extension.list.profile')
->reset();
foreach ($container->getParameter('cache_bins') as $service_id => $bin) {
$container->get($service_id)
->deleteAll();
}
// The system.theme.data key is no longer used in Drupal 8.7.x.
$container->get('state')
->delete('system.theme.data');
// Also rebuild themes because it uses state as cache.
$container->get('theme_handler')
->refreshInfo();
}
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
---|---|---|---|---|---|
DrupalKernel::$allowDumping | protected | property | Whether the container can be dumped. | ||
DrupalKernel::$booted | protected | property | Whether the kernel has been booted. | ||
DrupalKernel::$bootstrapContainer | protected | property | Holds the bootstrap container. | ||
DrupalKernel::$bootstrapContainerClass | protected | property | Holds the class used for instantiating the bootstrap container. | ||
DrupalKernel::$classLoader | protected | property | The class loader object. | ||
DrupalKernel::$configStorage | protected | property | Config storage object used for reading enabled modules configuration. | ||
DrupalKernel::$container | protected | property | Holds the container instance. | ||
DrupalKernel::$containerNeedsDumping | protected | property | Whether the container needs to be dumped once booting is complete. | ||
DrupalKernel::$containerNeedsRebuild | protected | property | Whether the container needs to be rebuilt the next time it is initialized. | ||
DrupalKernel::$defaultBootstrapContainerDefinition | protected | property | Holds the default bootstrap container definition. | ||
DrupalKernel::$environment | protected | property | The environment, e.g. 'testing', 'install'. | ||
DrupalKernel::$isEnvironmentInitialized | protected static | property | Whether the PHP environment has been initialized. | ||
DrupalKernel::$moduleData | protected | property | List of available modules and installation profiles. | ||
DrupalKernel::$moduleList | protected | property | Holds the list of enabled modules. | ||
DrupalKernel::$phpArrayDumperClass | protected | property | Holds the class used for dumping the container to a PHP array. | ||
DrupalKernel::$prepared | protected | property | Whether essential services have been set up properly by preHandle(). | ||
DrupalKernel::$root | protected | property | The app root. | ||
DrupalKernel::$serviceProviderClasses | protected | property | List of discovered service provider class names or objects. | ||
DrupalKernel::$serviceProviders | protected | property | List of instantiated service provider classes. | ||
DrupalKernel::$serviceYamls | protected | property | List of discovered services.yml pathnames. | ||
DrupalKernel::$sitePath | protected | property | The site directory. | ||
DrupalKernel::addServiceFiles | protected | function | Add service files. | ||
DrupalKernel::attachSynthetic | protected | function | Attach synthetic values on to kernel. | ||
DrupalKernel::boot | public | function | Boots the current kernel. | Overrides DrupalKernelInterface::boot | 1 |
DrupalKernel::bootEnvironment | public static | function | Setup a consistent PHP environment. | ||
DrupalKernel::classLoaderAddMultiplePsr4 | protected | function | Registers a list of namespaces with PSR-4 directories for class loading. | ||
DrupalKernel::compileContainer | protected | function | Compiles a new service container. | ||
DrupalKernel::createFromRequest | public static | function | Create a DrupalKernel object from a request. | 1 | |
DrupalKernel::findSitePath | public static | function | Returns the appropriate site directory for a request. | ||
DrupalKernel::getAppRoot | public | function | Gets the app root. | Overrides DrupalKernelInterface::getAppRoot | |
DrupalKernel::getCachedContainerDefinition | public | function | Returns the cached container definition - if any. | Overrides DrupalKernelInterface::getCachedContainerDefinition | |
DrupalKernel::getConfigStorage | protected | function | Returns the active configuration storage to use during building the container. | 1 | |
DrupalKernel::getContainer | public | function | Gets the current container. | Overrides DrupalKernelInterface::getContainer | |
DrupalKernel::getContainerBuilder | protected | function | Gets a new ContainerBuilder instance used to build the service container. | ||
DrupalKernel::getContainerCacheKey | protected | function | Returns the container cache key based on the environment. | ||
DrupalKernel::getHttpKernel | protected | function | Gets a http kernel from the container | ||
DrupalKernel::getInstallProfile | protected | function | Gets the active install profile. | 1 | |
DrupalKernel::getKernelParameters | protected | function | Returns the kernel parameters. | ||
DrupalKernel::getModuleFileNames | protected | function | Gets the file name for each enabled module. | ||
DrupalKernel::getModuleNamespacesPsr4 | protected | function | Gets the PSR-4 base directories for module namespaces. | ||
DrupalKernel::getModulesParameter | protected | function | Returns an array of Extension class parameters for all enabled modules. | ||
DrupalKernel::getServiceProviders | public | function | Returns all registered service providers. | Overrides DrupalKernelInterface::getServiceProviders | |
DrupalKernel::getServicesToPersist | protected | function | Returns service instances to persist from an old container to a new one. | ||
DrupalKernel::getSitePath | public | function | Get the site path. | Overrides DrupalKernelInterface::getSitePath | |
DrupalKernel::guessApplicationRoot | protected static | function | Determine the application root directory based on this file's location. | ||
DrupalKernel::handleException | protected | function | Converts an exception into a response. | ||
DrupalKernel::initializeRequestGlobals | protected | function | Bootstraps the legacy global request variables. | ||
DrupalKernel::initializeServiceProviders | protected | function | Registers all service providers to the kernel. | ||
DrupalKernel::initializeSettings | protected | function | Locate site path and initialize settings singleton. | ||
DrupalKernel::invalidateContainer | public | function | Invalidate the service container for the next request. | Overrides DrupalKernelInterface::invalidateContainer | |
DrupalKernel::moduleData | protected | function | Returns module data on the filesystem. | ||
DrupalKernel::persistServices | protected | function | Moves persistent service instances into a new container. | ||
DrupalKernel::preHandle | public | function | Helper method that does request related initialization. | Overrides DrupalKernelInterface::preHandle | |
DrupalKernel::prepareLegacyRequest | public | function | Prepare the kernel for handling a request without handling the request. | Overrides DrupalKernelInterface::prepareLegacyRequest | |
DrupalKernel::rebuildContainer | public | function | Force a container rebuild. | Overrides DrupalKernelInterface::rebuildContainer | |
DrupalKernel::setContainer | public | function | |||
DrupalKernel::setSitePath | public | function | Set the current site path. | Overrides DrupalKernelInterface::setSitePath | |
DrupalKernel::setupTrustedHosts | protected static | function | Sets up the lists of trusted HTTP Host headers. | ||
DrupalKernel::shutdown | public | function | Shuts down the kernel. | Overrides DrupalKernelInterface::shutdown | |
DrupalKernel::terminate | public | function | |||
DrupalKernel::updateModules | public | function | Implements Drupal\Core\DrupalKernelInterface::updateModules(). | Overrides DrupalKernelInterface::updateModules | |
DrupalKernel::validateHostname | public static | function | Validates the hostname supplied from the HTTP request. | ||
DrupalKernel::validateHostnameLength | protected static | function | Validates a hostname length. | ||
DrupalKernel::__construct | public | function | Constructs a DrupalKernel object. | 2 | |
DrupalKernelInterface::CONTAINER_INITIALIZE_SUBREQUEST_FINISHED | constant | Event fired when the service container finished initializing in subrequest. | |||
InstallerRedirectTrait::isCli | protected | function | Returns whether the current PHP process runs on CLI. | ||
InstallerRedirectTrait::shouldRedirectToInstaller | protected | function | Determines if an exception handler should redirect to the installer. | ||
UpdateKernel::bootSession | protected | function | Boots up the session. | ||
UpdateKernel::cacheDrupalContainer | protected | function | Stores the container definition in a cache. | Overrides DrupalKernel::cacheDrupalContainer | |
UpdateKernel::discoverServiceProviders | public | function | Discovers available serviceProviders. | Overrides DrupalKernel::discoverServiceProviders | |
UpdateKernel::fixSerializedExtensionObjects | public static | function | Fixes caches and theme info if they contain old Extension objects. | ||
UpdateKernel::handle | public | function | Overrides DrupalKernel::handle | ||
UpdateKernel::handleAccess | protected | function | Checks if the current user has rights to access updates page. | ||
UpdateKernel::handleRaw | protected | function | Generates the actual result of update.php. | ||
UpdateKernel::initializeContainer | protected | function | Initializes the service container. | Overrides DrupalKernel::initializeContainer | |
UpdateKernel::loadLegacyIncludes | public | function | Helper method that loads legacy Drupal include files. | Overrides DrupalKernel::loadLegacyIncludes | |
UpdateKernel::setupRequestMatch | protected | function | Set up the request with fake routing data for update.php. | ||
UpdateKernel::shutdownSession | protected | function | Ensures that the session is saved. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.