Skip to content
Snippets Groups Projects
Commit 60cb95ff authored by Adam G-H's avatar Adam G-H
Browse files

Issue #3260669 by phenaproxima: automatic_updates_9_3_shim should add update_hook_registry service

parent c441c332
No related branches found
No related tags found
1 merge request!187Issue #3260669: automatic_updates_9_3_shim should add update_hook_registry service
<?php
namespace Drupal\automatic_updates_9_3_shim;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Symfony\Component\DependencyInjection\Reference;
/**
* Modifies container service definitions.
*/
class AutomaticUpdates93ShimServiceProvider extends ServiceProviderBase {
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
parent::alter($container);
$service_id = 'update.update_hook_registry_factory';
if ($container->hasDefinition($service_id)) {
$container->getDefinition($service_id)
->setClass(UpdateHookRegistryFactory::class);
}
else {
$container->register($service_id, UpdateHookRegistryFactory::class)
->addMethodCall('setContainer', [
new Reference('service_container'),
]);
}
$service_id = 'update.update_hook_registry';
if ($container->hasDefinition($service_id)) {
$container->getDefinition($service_id)
->setClass(UpdateHookRegistry::class);
}
else {
$container->register($service_id, UpdateHookRegistry::class)
->setFactory([
new Reference($service_id . '_factory'),
'create',
]);
}
$container->getDefinition('module_installer')
->setClass(ModuleInstaller::class);
}
}
<?php
namespace Drupal\automatic_updates_9_3_shim;
use Drupal\Core\Database\Connection;
use Drupal\Core\DrupalKernelInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Extension\ModuleInstaller as CoreModuleInstaller;
/**
* A module installer which accepts our update registry shim in its constructor.
*/
class ModuleInstaller extends CoreModuleInstaller {
/**
* {@inheritdoc}
*/
public function __construct($root, ModuleHandlerInterface $module_handler, DrupalKernelInterface $kernel, Connection $connection = NULL, UpdateHookRegistry $update_registry = NULL) {
$this->root = $root;
$this->moduleHandler = $module_handler;
$this->kernel = $kernel;
if (!$connection) {
@trigger_error('The database connection must be passed to ' . __METHOD__ . '(). Creating ' . __CLASS__ . ' without it is deprecated in drupal:9.2.0 and will be required in drupal:10.0.0. See https://www.drupal.org/node/2970993', E_USER_DEPRECATED);
$connection = \Drupal::service('database');
}
$this->connection = $connection;
if (!$update_registry) {
@trigger_error('Calling ' . __METHOD__ . '() without the $update_registry argument is deprecated in drupal:9.3.0 and $update_registry argument will be required in drupal:10.0.0. See https://www.drupal.org/node/2124069', E_USER_DEPRECATED);
$update_registry = \Drupal::service('update.update_hook_registry');
}
$this->updateRegistry = $update_registry;
}
}
<?php
// phpcs:ignoreFile
/**
* This file was generated via php core/scripts/generate-proxy-class.php 'Drupal\automatic_updates_9_3_shim\ModuleInstaller' "modules/contrib/automatic_updates/automatic_updates_9_3_shim/src".
*/
namespace Drupal\automatic_updates_9_3_shim\ProxyClass {
/**
* Provides a proxy class for \Drupal\automatic_updates_9_3_shim\ModuleInstaller.
*
* @see \Drupal\Component\ProxyBuilder
*/
class ModuleInstaller implements \Drupal\Core\Extension\ModuleInstallerInterface
{
use \Drupal\Core\DependencyInjection\DependencySerializationTrait;
/**
* The id of the original proxied service.
*
* @var string
*/
protected $drupalProxyOriginalServiceId;
/**
* The real proxied service, after it was lazy loaded.
*
* @var \Drupal\automatic_updates_9_3_shim\ModuleInstaller
*/
protected $service;
/**
* The service container.
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
/**
* Constructs a ProxyClass Drupal proxy object.
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The container.
* @param string $drupal_proxy_original_service_id
* The service ID of the original service.
*/
public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container, $drupal_proxy_original_service_id)
{
$this->container = $container;
$this->drupalProxyOriginalServiceId = $drupal_proxy_original_service_id;
}
/**
* Lazy loads the real service from the container.
*
* @return object
* Returns the constructed real service.
*/
protected function lazyLoadItself()
{
if (!isset($this->service)) {
$this->service = $this->container->get($this->drupalProxyOriginalServiceId);
}
return $this->service;
}
/**
* {@inheritdoc}
*/
public function addUninstallValidator(\Drupal\Core\Extension\ModuleUninstallValidatorInterface $uninstall_validator)
{
return $this->lazyLoadItself()->addUninstallValidator($uninstall_validator);
}
/**
* {@inheritdoc}
*/
public function install(array $module_list, $enable_dependencies = true)
{
return $this->lazyLoadItself()->install($module_list, $enable_dependencies);
}
/**
* {@inheritdoc}
*/
public function uninstall(array $module_list, $uninstall_dependents = true)
{
return $this->lazyLoadItself()->uninstall($module_list, $uninstall_dependents);
}
/**
* {@inheritdoc}
*/
public function validateUninstall(array $module_list)
{
return $this->lazyLoadItself()->validateUninstall($module_list);
}
}
}
<?php
namespace Drupal\automatic_updates_9_3_shim;
use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
/**
* Provides module updates versions handling.
*/
class UpdateHookRegistry {
/**
* Indicates that a module has not been installed yet.
*/
public const SCHEMA_UNINSTALLED = -1;
/**
* A list of enabled modules.
*
* @var string[]
*/
protected $enabledModules;
/**
* The key value storage.
*
* @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
*/
protected $keyValue;
/**
* A static cache of schema currentVersions per module.
*
* Stores schema versions of the modules based on their defined hook_update_N
* implementations.
* Example:
* ```
* [
* 'example_module' => [
* 8000,
* 8001,
* 8002
* ]
* ]
* ```
*
* @var int[][]
* @see \Drupal\Core\Update\UpdateHookRegistry::getAvailableUpdates()
*/
protected $allAvailableSchemaVersions = [];
/**
* Constructs a new UpdateRegistry.
*
* @param string[] $enabled_modules
* A list of enabled modules.
* @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $key_value
* The key value store.
*/
public function __construct(array $enabled_modules, KeyValueStoreInterface $key_value) {
$this->enabledModules = $enabled_modules;
$this->keyValue = $key_value;
}
/**
* Returns an array of available schema versions for a module.
*
* @param string $module
* A module name.
*
* @return int[]
* An array of available updates sorted by version. Empty array returned if
* no updates available.
*/
public function getAvailableUpdates(string $module): array {
if (!isset($this->allAvailableSchemaVersions[$module])) {
$this->allAvailableSchemaVersions[$module] = [];
foreach ($this->enabledModules as $enabled_module) {
$this->allAvailableSchemaVersions[$enabled_module] = [];
}
// Prepare regular expression to match all possible defined
// hook_update_N().
$regexp = '/^(?<module>.+)_update_(?<version>\d+)$/';
$functions = get_defined_functions();
// Narrow this down to functions ending with an integer, since all
// hook_update_N() functions end this way, and there are other
// possible functions which match '_update_'. We use preg_grep() here
// since looping through all PHP functions can take significant page
// execution time and this function is called on every administrative page
// via system_requirements().
foreach (preg_grep('/_\d+$/', $functions['user']) as $function) {
// If this function is a module update function, add it to the list of
// module updates.
if (preg_match($regexp, $function, $matches)) {
$this->allAvailableSchemaVersions[$matches['module']][] = (int) $matches['version'];
}
}
// Ensure that updates are applied in numerical order.
array_walk(
$this->allAvailableSchemaVersions,
static function (&$module_updates) {
sort($module_updates, SORT_NUMERIC);
}
);
}
return $this->allAvailableSchemaVersions[$module];
}
/**
* Returns the currently installed schema version for a module.
*
* @param string $module
* A module name.
*
* @return int
* The currently installed schema version, or self::SCHEMA_UNINSTALLED if the
* module is not installed.
*/
public function getInstalledVersion(string $module): int {
return $this->keyValue->get($module, self::SCHEMA_UNINSTALLED);
}
/**
* Updates the installed version information for a module.
*
* @param string $module
* A module name.
* @param int $version
* The new schema version.
*
* @return self
* Returns self to support chained method calls.
*/
public function setInstalledVersion(string $module, int $version): self {
$this->keyValue->set($module, $version);
return $this;
}
/**
* Deletes the installed version information for the module.
*
* @param string $module
* The module name to delete.
*/
public function deleteInstalledVersion(string $module): void {
$this->keyValue->delete($module);
}
/**
* Returns the currently installed schema version for all modules.
*
* @return int[]
* Array of modules as the keys and values as the currently installed
* schema version of corresponding module, or self::SCHEMA_UNINSTALLED if the
* module is not installed.
*/
public function getAllInstalledVersions(): array {
return $this->keyValue->getAll();
}
}
<?php
namespace Drupal\automatic_updates_9_3_shim;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
/**
* Service factory for the versioning update registry.
*/
class UpdateHookRegistryFactory implements ContainerAwareInterface {
use ContainerAwareTrait;
/**
* Creates a new UpdateHookRegistry instance.
*
* @return \Drupal\Core\Update\UpdateHookRegistry
* The update registry instance.
*/
public function create() {
return new UpdateHookRegistry(
array_keys($this->container->get('module_handler')->getModuleList()),
$this->container->get('keyvalue')->get('system.schema')
);
}
}
......@@ -2,8 +2,8 @@
namespace Drupal\automatic_updates\Controller;
use Drupal\automatic_updates_9_3_shim\UpdateHookRegistry;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Update\UpdateHookRegistry;
use Drupal\Core\Update\UpdateRegistry;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -20,7 +20,7 @@ class UpdateController extends ControllerBase {
/**
* The update hook registry service.
*
* @var \Drupal\Core\Update\UpdateHookRegistry
* @var \Drupal\automatic_updates_9_3_shim\UpdateHookRegistry
*/
protected $updateHookRegistry;
......@@ -34,7 +34,7 @@ class UpdateController extends ControllerBase {
/**
* Constructs an UpdateController object.
*
* @param \Drupal\Core\Update\UpdateHookRegistry $update_hook_registry
* @param \Drupal\automatic_updates_9_3_shim\UpdateHookRegistry $update_hook_registry
* The update hook registry service.
* @param \Drupal\Core\Update\UpdateRegistry $post_update_registry
* The post-update registry service.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment