diff --git a/core/core.services.yml b/core/core.services.yml index 9baa90c..ef20e47 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -306,12 +306,10 @@ services: arguments: ['@router.dumper', '@lock', '@event_dispatcher', '@module_handler', '@controller_resolver'] path.alias_manager.cached: class: Drupal\Core\CacheDecorator\AliasManagerCacheDecorator - tags: - - { name: event_subscriber } arguments: ['@path.alias_manager', '@cache.path'] path.crud: class: Drupal\Core\Path\Path - arguments: ['@database', '@event_dispatcher'] + arguments: ['@database', '@module_handler'] # The argument to the hashing service defined in services.yml, to the # constructor of PhpassHashedPassword is the log2 number of iterations for # password stretching. diff --git a/core/lib/Drupal/Core/CacheDecorator/AliasManagerCacheDecorator.php b/core/lib/Drupal/Core/CacheDecorator/AliasManagerCacheDecorator.php index 56b9fdc..cf46231 100644 --- a/core/lib/Drupal/Core/CacheDecorator/AliasManagerCacheDecorator.php +++ b/core/lib/Drupal/Core/CacheDecorator/AliasManagerCacheDecorator.php @@ -9,13 +9,11 @@ use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Path\AliasManagerInterface; -use Drupal\Core\Path\PathEvents; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Class used by the PathSubscriber to get the system path and cache path lookups. */ -class AliasManagerCacheDecorator implements CacheDecoratorInterface, AliasManagerInterface, EventSubscriberInterface { +class AliasManagerCacheDecorator implements CacheDecoratorInterface, AliasManagerInterface { /** * @var \Drupal\Core\Path\AliasManagerInterface @@ -127,14 +125,4 @@ public function cacheClear() { $this->cache->delete($this->cacheKey); $this->aliasManager->cacheClear(); } - - /** - * {@inheritdoc} - */ - static function getSubscribedEvents() { - $events[PathEvents::UPDATE][] = array('cacheClear'); - $events[PathEvents::INSERT][] = array('cacheClear'); - $events[PathEvents::DELETE][] = array('cacheClear'); - return $events; - } } diff --git a/core/lib/Drupal/Core/Path/AliasManagerInterface.php b/core/lib/Drupal/Core/Path/AliasManagerInterface.php index 3dedd3e..e9920fb 100644 --- a/core/lib/Drupal/Core/Path/AliasManagerInterface.php +++ b/core/lib/Drupal/Core/Path/AliasManagerInterface.php @@ -54,4 +54,9 @@ public function getPathLookups(); * An array of system paths. */ public function preloadPathLookups(array $path_list); + + /** + * Clear internal caches in alias manager. + */ + public function cacheClear(); } diff --git a/core/lib/Drupal/Core/Path/Path.php b/core/lib/Drupal/Core/Path/Path.php index f381e82..731daf0 100644 --- a/core/lib/Drupal/Core/Path/Path.php +++ b/core/lib/Drupal/Core/Path/Path.php @@ -8,8 +8,8 @@ namespace Drupal\Core\Path; use Drupal\Core\Database\Connection; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Language\Language; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** * Defines a class for CRUD operations on path aliases. @@ -24,11 +24,11 @@ class Path { protected $connection; /** - * An event dispatcher instance to use for configuration events. + * The module handler. * - * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface + * @var \Drupal\Core\Extension\ModuleHandlerInterface */ - protected $eventDispatcher; + protected $moduleHandler; /** * Constructs a Path CRUD object. @@ -36,12 +36,12 @@ class Path { * @param \Drupal\Core\Database\Connection $connection * A database connection for reading and writing path aliases. * - * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher - * An event dispatcher instance to use for configuration events. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler. */ - public function __construct(Connection $connection, EventDispatcherInterface $event_dispatcher) { + public function __construct(Connection $connection, ModuleHandlerInterface $module_handler) { $this->connection = $connection; - $this->eventDispatcher = $event_dispatcher; + $this->moduleHandler = $module_handler; } /** @@ -92,8 +92,7 @@ public function save($source, $alias, $langcode = Language::LANGCODE_NOT_SPECIFI $operation = 'update'; } if ($pid) { - $event = $operation == 'update' ? PathEvents::UPDATE : PathEvents::INSERT; - $this->eventDispatcher->dispatch($event, new PathInsertUpdateEvent($fields)); + $this->moduleHandler->invokeAll('path_' . $operation, $fields); return $fields; } return FALSE; @@ -137,7 +136,7 @@ public function delete($conditions) { $query->condition($field, $value); } $deleted = $query->execute(); - $this->eventDispatcher->dispatch(PathEvents::DELETE, new PathDeleteEvent($path)); + $this->moduleHandler->invokeAll('path_delete', $path); return $deleted; } } diff --git a/core/lib/Drupal/Core/Path/PathDeleteEvent.php b/core/lib/Drupal/Core/Path/PathDeleteEvent.php deleted file mode 100644 index fd927be..0000000 --- a/core/lib/Drupal/Core/Path/PathDeleteEvent.php +++ /dev/null @@ -1,40 +0,0 @@ -path = $path; - } - - /** - * Returns path that is being deleted at this event. - * - * @return string - * Path being deleted. - */ - public function getPath() { - return $this->path; - } -} diff --git a/core/lib/Drupal/Core/Path/PathEvents.php b/core/lib/Drupal/Core/Path/PathEvents.php deleted file mode 100644 index c2e8db4..0000000 --- a/core/lib/Drupal/Core/Path/PathEvents.php +++ /dev/null @@ -1,34 +0,0 @@ -fields = $fields; - } - - /** - * Returns path alias information. - * - * @return array - * Array containing path alias information. - */ - public function getFields() { - return $this->fields; - } -} diff --git a/core/modules/path/path.api.php b/core/modules/path/path.api.php new file mode 100644 index 0000000..c69b97d --- /dev/null +++ b/core/modules/path/path.api.php @@ -0,0 +1,73 @@ +fields(array( + 'alias' => $path['alias'], + 'pid' => $path['pid'], + )) + ->execute(); +} + +/** + * Respond to a path being updated. + * + * @param $path + * An associative array containing the following keys: + * - source: The internal system path. + * - alias: The URL alias. + * - pid: Unique path alias identifier. + * - langcode: The language code of the alias. + * + * @see \Drupal\Core\Path\Path::save() + */ +function hook_path_update($path) { + db_update('mytable') + ->fields(array('alias' => $path['alias'])) + ->condition('pid', $path['pid']) + ->execute(); +} + +/** + * Respond to a path being deleted. + * + * @param $path + * An associative array containing the following keys: + * - source: The internal system path. + * - alias: The URL alias. + * - pid: Unique path alias identifier. + * - langcode: The language code of the alias. + * + * @see \Drupal\Core\Path\Path::delete() + */ +function hook_path_delete($path) { + db_delete('mytable') + ->condition('pid', $path['pid']) + ->execute(); +} + +/** + * @} End of "addtogroup hooks". + */ diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php index d155418..18f13ba 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php @@ -32,7 +32,7 @@ function testCRUD() { $this->fixtures->createTables($connection); //Create Path object. - $path = new Path($connection, $this->container->get('event_dispatcher')); + $path = new Path($connection, $this->container->get('module_handler')); $aliases = $this->fixtures->sampleUrlAliases(); @@ -85,7 +85,7 @@ function testLookupPath() { //Create AliasManager and Path object. $aliasManager = $this->container->get('path.alias_manager'); - $pathObject = new Path($connection, $this->container->get('event_dispatcher')); + $pathObject = new Path($connection, $this->container->get('module_handler')); // Test the situation where the source is the same for multiple aliases. // Start with a language-neutral alias, which we will override. @@ -162,7 +162,7 @@ function testWhitelist() { // Create AliasManager and Path object. $whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $connection); $aliasManager = new AliasManager($connection, $whitelist, $this->container->get('language_manager')); - $path = new Path($connection, $this->container->get('event_dispatcher')); + $path = new Path($connection, $this->container->get('module_handler')); // No alias for user and admin yet, so should be NULL. $this->assertNull($whitelist->get('user')); diff --git a/core/modules/system/system.module b/core/modules/system/system.module index fc6f61c..9d4b4a8 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -2890,3 +2890,24 @@ function system_admin_paths() { ); return $paths; } + +/** + * Implements hook_path_update(). + */ +function system_path_update() { + \Drupal::service('path.alias_manager')->cacheClear(); +} + +/** + * Implements hook_path_insert(). + */ +function system_path_insert() { + \Drupal::service('path.alias_manager')->cacheClear(); +} + +/** + * Implements hook_path_delete(). + */ +function system_path_delete($path) { + \Drupal::service('path.alias_manager')->cacheClear(); +} diff --git a/core/modules/system/tests/modules/path_test/path_test.info.yml b/core/modules/system/tests/modules/path_test/path_test.info.yml new file mode 100644 index 0000000..57a5893 --- /dev/null +++ b/core/modules/system/tests/modules/path_test/path_test.info.yml @@ -0,0 +1,7 @@ +name: 'Hook path tests' +type: module +description: 'Support module for path hook testing.' +package: Testing +version: VERSION +core: 8.x +hidden: true diff --git a/core/modules/system/tests/modules/path_test/path_test.module b/core/modules/system/tests/modules/path_test/path_test.module new file mode 100644 index 0000000..df03931 --- /dev/null +++ b/core/modules/system/tests/modules/path_test/path_test.module @@ -0,0 +1,22 @@ +set('path_test.results', array()); +} + +/** + * Implements hook_path_update(). + */ +function path_test_path_update($path) { + $results = \Drupal::state()->get('path_test.results') ?: array(); + $results['hook_path_update'] = $path; + \Drupal::state()->set('path_test.results', $results); +}