Issue #3084983 by plach, amateescu, catch, Berdir, xjm: Move all the code related to path aliases to a new (required) "path_alias" module

merge-requests/64/head
catch 2019-11-07 19:48:33 +00:00
parent 3834d60f1a
commit 0a7bb284bc
96 changed files with 1055 additions and 235 deletions

View File

@ -322,6 +322,9 @@ Page Cache
Path
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Path Alias
- Nathaniel Catchpole 'catch' https://www.drupal.org/u/catch
Plugin
- Kris Vanderwater 'EclipseGc' https://www.drupal.org/u/eclipseGc
- Alex Bronstein 'effulgentsia' https://www.drupal.org/u/effulgentsia

View File

@ -138,6 +138,7 @@
"drupal/options": "self.version",
"drupal/page_cache": "self.version",
"drupal/path": "self.version",
"drupal/path_alias": "self.version",
"drupal/quickedit": "self.version",
"drupal/rdf": "self.version",
"drupal/responsive_image": "self.version",

View File

@ -762,8 +762,8 @@
* A typical service definition in a *.services.yml file looks like this:
* @code
* path.alias_manager:
* class: Drupal\Core\Path\AliasManager
* arguments: ['@path.crud', '@path.alias_whitelist', '@language_manager']
* class: Drupal\path_alias\AliasManager
* arguments: ['@path.crud', '@path_alias.whitelist', '@language_manager']
* @endcode
* Some services use other services as factories; a typical service definition
* is:

View File

@ -461,14 +461,18 @@ services:
queue.database:
class: Drupal\Core\Queue\QueueDatabaseFactory
arguments: ['@database']
# @deprecated in Drupal 8.8.x and will be removed before 9.0.0. Use the
# "path_alias.whitelist" service instead.
# See https://www.drupal.org/node/3092086
path.alias_whitelist:
class: Drupal\Core\Path\AliasWhitelist
tags:
- { name: needs_destruction }
arguments: [path_alias_whitelist, '@cache.bootstrap', '@lock', '@state', '@path.alias_repository']
alias: path_alias.whitelist
deprecated: 'The "%alias_id%" service alias is deprecated. Use "path_alias.whitelist" instead. See https://drupal.org/node/3092086'
# @deprecated in Drupal 8.8.x and will be removed before 9.0.0. Use the
# "path_alias.manager" service instead.
# See https://www.drupal.org/node/3092086
path.alias_manager:
class: Drupal\Core\Path\AliasManager
arguments: ['@path.alias_repository', '@path.alias_whitelist', '@language_manager', '@cache.data']
arguments: ['@path_alias.repository', '@path_alias.whitelist', '@language_manager', '@cache.data']
path.current:
class: Drupal\Core\Path\CurrentPathStack
arguments: ['@request_stack']
@ -960,17 +964,12 @@ services:
arguments: ['@lock', '@plugin.manager.menu.link', '@database', '@database.replica_kill_switch']
tags:
- { name: event_subscriber }
path.alias_repository:
class: Drupal\Core\Path\AliasRepository
arguments: ['@database']
tags:
- { name: backend_overridable }
path.alias_storage:
class: Drupal\Core\Path\AliasStorage
arguments: ['@database', '@module_handler', '@entity_type.manager']
tags:
- { name: backend_overridable }
deprecated: The "%service_id%" service is deprecated. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865
deprecated: The "%service_id%" service is deprecated. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865
path.matcher:
class: Drupal\Core\Path\PathMatcher
arguments: ['@config.factory', '@current_route_match']
@ -1222,11 +1221,6 @@ services:
arguments: ['@maintenance_mode', '@config.factory', '@string_translation', '@url_generator', '@current_user', '@bare_html_page_renderer', '@messenger']
tags:
- { name: event_subscriber }
path_subscriber:
class: Drupal\Core\EventSubscriber\PathSubscriber
tags:
- { name: event_subscriber }
arguments: ['@path.alias_manager', '@path.current']
route_access_response_subscriber:
class: Drupal\Core\EventSubscriber\RouteAccessResponseSubscriber
tags:
@ -1357,12 +1351,6 @@ services:
arguments: ['@current_route_match']
tags:
- { name: route_processor_outbound, priority: 200 }
path_processor_alias:
class: Drupal\Core\PathProcessor\PathProcessorAlias
tags:
- { name: path_processor_inbound, priority: 100 }
- { name: path_processor_outbound, priority: 300 }
arguments: ['@path.alias_manager']
route_processor_csrf:
class: Drupal\Core\Access\RouteProcessorCsrf
tags:
@ -1755,3 +1743,34 @@ services:
pager.parameters:
class: Drupal\Core\Pager\PagerParameters
arguments: ['@request_stack']
# Path Alias services, defined here to be available even when "path_alias" is
# not enabled yet. These will replace the legacy core services, which are now
# deprecated and will be removed in Drupal 9.
# See https://www.drupal.org/node/3092086
# @todo Move these to "path_alias" once core fully supports it as an optional
# module. See https://www.drupal.org/node/3092090.
path_alias.subscriber:
class: Drupal\Core\EventSubscriber\PathSubscriber
tags:
- { name: event_subscriber }
arguments: ['@path.alias_manager', '@path.current']
path_alias.path_processor:
class: Drupal\Core\PathProcessor\PathProcessorAlias
tags:
- { name: path_processor_inbound, priority: 100 }
- { name: path_processor_outbound, priority: 300 }
arguments: ['@path.alias_manager']
path_alias.manager:
class: Drupal\Core\Path\AliasManager
arguments: ['@path_alias.repository', '@path_alias.whitelist', '@language_manager', '@cache.data']
path_alias.repository:
class: Drupal\Core\Path\AliasRepository
arguments: ['@database']
tags:
- { name: backend_overridable }
path_alias.whitelist:
class: Drupal\Core\Path\AliasWhitelist
tags:
- { name: needs_destruction }
arguments: [path_alias_whitelist, '@cache.bootstrap', '@lock', '@state', '@path_alias.repository']

View File

@ -11,6 +11,11 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Provides a path subscriber that converts path aliases.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
* Use \Drupal\path_alias\EventSubscriber\PathAliasSubscriber.
*
* @see https://www.drupal.org/node/3092086
*/
class PathSubscriber implements EventSubscriberInterface {
@ -39,6 +44,13 @@ class PathSubscriber implements EventSubscriberInterface {
public function __construct(AliasManagerInterface $alias_manager, CurrentPathStack $current_path) {
$this->aliasManager = $alias_manager;
$this->currentPath = $current_path;
// This is used as base class by the new class, so we do not trigger
// deprecation notices when that or any child class is instantiated.
$new_class = 'Drupal\path_alias\EventSubscriber\PathAliasSubscriber';
if (!is_a($this, $new_class) && class_exists($new_class)) {
@trigger_error('The \\' . __CLASS__ . ' class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \\' . $new_class . '. See https://drupal.org/node/3092086', E_USER_DEPRECATED);
}
}
/**

View File

@ -7,9 +7,15 @@ use Drupal\Core\CacheDecorator\CacheDecoratorInterface;
use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
/**
* The default alias manager implementation.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
* Use \Drupal\path_alias\AliasManager.
*
* @see https://www.drupal.org/node/3092086
*/
class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
@ -115,12 +121,37 @@ class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
public function __construct($alias_repository, AliasWhitelistInterface $whitelist, LanguageManagerInterface $language_manager, CacheBackendInterface $cache) {
if (!$alias_repository instanceof AliasRepositoryInterface) {
@trigger_error('Passing the path.alias_storage service to AliasManager::__construct() is deprecated in drupal:8.8.0 and will be removed before drupal:9.0.0. Pass the new dependencies instead. See https://www.drupal.org/node/3013865.', E_USER_DEPRECATED);
$alias_repository = \Drupal::service('path.alias_repository');
$alias_repository = \Drupal::service('path_alias.repository');
}
$this->pathAliasRepository = $alias_repository;
$this->languageManager = $language_manager;
$this->whitelist = $whitelist;
$this->cache = $cache;
// This is used as base class by the new class, so we do not trigger
// deprecation notices when that or any child class is instantiated.
$new_class = 'Drupal\path_alias\AliasManager';
if (!is_a($this, $new_class) && class_exists($new_class)) {
@trigger_error('The \\' . __CLASS__ . ' class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \\' . $new_class . '. See https://drupal.org/node/3092086', E_USER_DEPRECATED);
// Despite being two different services, hence two different class
// instances, both the new and the legacy alias managers need to share the
// same internal state to keep the path/alias lookup optimizations
// working.
try {
$alias_manager = \Drupal::service('path_alias.manager');
if ($alias_manager instanceof $new_class) {
$synced_properties = ['cacheKey', 'langcodePreloaded', 'lookupMap', 'noAlias', 'noPath', 'preloadedPathLookups'];
foreach ($synced_properties as $property) {
$this->{$property} = &$alias_manager->{$property};
}
}
}
catch (ServiceCircularReferenceException $e) {
// This may happen during installation when "path_alias" has not swapped
// the alias manager class yet. Nothing to do in this case.
}
}
}
/**

View File

@ -4,6 +4,11 @@ namespace Drupal\Core\Path;
/**
* Find an alias for a path and vice versa.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
* Use \Drupal\path_alias\AliasManagerInterface.
*
* @see https://www.drupal.org/node/3092086
*/
interface AliasManagerInterface {

View File

@ -9,6 +9,11 @@ use Drupal\Core\Language\LanguageInterface;
/**
* Provides the default path alias lookup operations.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
* Use \Drupal\path_alias\AliasRepository.
*
* @see https://www.drupal.org/node/3092086
*/
class AliasRepository implements AliasRepositoryInterface {
@ -27,6 +32,13 @@ class AliasRepository implements AliasRepositoryInterface {
*/
public function __construct(Connection $connection) {
$this->connection = $connection;
// This is used as base class by the new class, so we do not trigger
// deprecation notices when that or any child class is instantiated.
$new_class = 'Drupal\path_alias\AliasRepository';
if (!is_a($this, $new_class) && class_exists($new_class)) {
@trigger_error('The \\' . __CLASS__ . ' class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \\' . $new_class . '. See https://drupal.org/node/3092086', E_USER_DEPRECATED);
}
}
/**

View File

@ -5,15 +5,10 @@ namespace Drupal\Core\Path;
/**
* Provides an interface for path alias lookup operations.
*
* The path alias repository service is only used internally in order to
* optimize alias lookup queries needed in the critical path of each request.
* However, it is not marked as an internal service because alternative storage
* backends still need to override it if they provide a different storage class
* for the PathAlias entity type.
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
* Use \Drupal\path_alias\AliasRepositoryInterface.
*
* Whenever you need to determine whether an alias exists for a system path, or
* whether a system path has an alias, the 'path.alias_manager' service should
* be used instead.
* @see https://www.drupal.org/node/3092086
*/
interface AliasRepositoryInterface {

View File

@ -9,7 +9,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageInterface;
@trigger_error('\Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.', E_USER_DEPRECATED);
@trigger_error('\Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.', E_USER_DEPRECATED);
/**
* Provides a class for CRUD operations on path aliases.
@ -19,7 +19,7 @@ use Drupal\Core\Language\LanguageInterface;
* the same, and will both refer to the same internal system path.
*
* @deprecated \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and
* is removed from drupal:9.0.0. Use the "path.alias_repository" service
* is removed from drupal:9.0.0. Use the "path_alias.repository" service
* instead, or the entity storage handler for the "path_alias" entity type
* for CRUD methods.
*
@ -82,7 +82,7 @@ class AliasStorage implements AliasStorageInterface {
}
if ($pid) {
/** @var \Drupal\Core\Path\PathAliasInterface $path_alias */
/** @var \Drupal\path_alias\PathAliasInterface $path_alias */
$path_alias = $this->getPathAliasEntityStorage()->load($pid);
$original_values = [
'source' => $path_alias->getPath(),
@ -142,7 +142,7 @@ class AliasStorage implements AliasStorageInterface {
->execute();
$entities = $this->getPathAliasEntityStorage()->loadMultiple($result);
/** @var \Drupal\Core\Path\PathAliasInterface $path_alias */
/** @var \Drupal\path_alias\PathAliasInterface $path_alias */
$path_alias = reset($entities);
if ($path_alias) {
return [
@ -326,6 +326,10 @@ class AliasStorage implements AliasStorageInterface {
* {@inheritdoc}
*/
public function pathHasMatchingAlias($initial_substring) {
if (!$this->moduleHandler->moduleExists('path_alias')) {
return FALSE;
}
$query = $this->getBaseQuery();
$query->addExpression(1);

View File

@ -8,7 +8,7 @@ use Drupal\Core\Language\LanguageInterface;
* Provides a class for CRUD operations on path aliases.
*
* @deprecated \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and
* is removed from drupal:9.0.0. Use the "path.alias_repository" service
* is removed from drupal:9.0.0. Use the "path_alias.repository" service
* instead, or the entity storage handler for the "path_alias" entity type
* for CRUD methods.
*

View File

@ -10,6 +10,11 @@ use Drupal\Core\Lock\LockBackendInterface;
/**
* Extends CacheCollector to build the path alias whitelist over time.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
* Use \Drupal\path_alias\AliasWhitelist.
*
* @see https://www.drupal.org/node/3092086
*/
class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface {
@ -54,9 +59,16 @@ class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface {
if (!$alias_repository instanceof AliasRepositoryInterface) {
@trigger_error('Passing the path.alias_storage service to AliasWhitelist::__construct() is deprecated in drupal:8.8.0 and will be removed before drupal:9.0.0. Pass the new dependencies instead. See https://www.drupal.org/node/3013865.', E_USER_DEPRECATED);
$alias_repository = \Drupal::service('path.alias_repository');
$alias_repository = \Drupal::service('path_alias.repository');
}
$this->pathAliasRepository = $alias_repository;
// This is used as base class by the new class, so we do not trigger
// deprecation notices when that or any child class is instantiated.
$new_class = 'Drupal\path_alias\AliasWhitelist';
if (!is_a($this, $new_class) && class_exists($new_class)) {
@trigger_error('The \\' . __CLASS__ . ' class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \\' . $new_class . '. See https://drupal.org/node/3092086', E_USER_DEPRECATED);
}
}
/**

View File

@ -7,9 +7,9 @@ use Drupal\Core\Cache\CacheCollectorInterface;
/**
* Cache the alias whitelist.
*
* The whitelist contains the first element of the router paths of all
* aliases. For example, if /node/12345 has an alias then "node" is added to
* the whitelist. This optimization allows skipping the lookup for every
* /user/{user} path if "user" is not in the whitelist.
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
* Use \Drupal\path_alias\AliasWhitelistInterface.
*
* @see https://www.drupal.org/node/3092086
*/
interface AliasWhitelistInterface extends CacheCollectorInterface {}

View File

@ -43,7 +43,7 @@ class UniquePathAliasConstraintValidator extends ConstraintValidator implements
* {@inheritdoc}
*/
public function validate($entity, Constraint $constraint) {
/** @var \Drupal\Core\Path\PathAliasInterface $entity */
/** @var \Drupal\path_alias\PathAliasInterface $entity */
$path = $entity->getPath();
$alias = $entity->getAlias();
$langcode = $entity->language()->getId();

View File

@ -8,6 +8,11 @@ use Symfony\Component\HttpFoundation\Request;
/**
* Processes the inbound path using path alias lookups.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0.
* Use \Drupal\path_alias\PathProcessor\AliasPathProcessor.
*
* @see https://www.drupal.org/node/3092086
*/
class PathProcessorAlias implements InboundPathProcessorInterface, OutboundPathProcessorInterface {
@ -26,6 +31,13 @@ class PathProcessorAlias implements InboundPathProcessorInterface, OutboundPathP
*/
public function __construct(AliasManagerInterface $alias_manager) {
$this->aliasManager = $alias_manager;
// This is used as base class by the new class, so we do not trigger
// deprecation notices when that or any child class is instantiated.
$new_class = 'Drupal\path_alias\PathProcessor\AliasPathProcessor';
if (!is_a($this, $new_class) && class_exists($new_class)) {
@trigger_error('The \\' . __CLASS__ . ' class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \\' . $new_class . '. See https://drupal.org/node/3092086', E_USER_DEPRECATED);
}
}
/**

View File

@ -490,8 +490,8 @@ class RouteProvider implements CacheableRouteProviderInterface, PreloadableRoute
*/
protected function getCurrentLanguageCacheIdPart() {
// This must be in sync with the language logic in
// \Drupal\Core\PathProcessor\PathProcessorAlias::processInbound() and
// \Drupal\Core\Path\AliasManager::getPathByAlias().
// \Drupal\path_alias\PathProcessor\AliasPathProcessor::processInbound() and
// \Drupal\path_alias\AliasManager::getPathByAlias().
// @todo Update this if necessary in https://www.drupal.org/node/1125428.
return $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId();
}

View File

@ -41,8 +41,8 @@ class UpdateServiceProvider implements ServiceProviderInterface, ServiceModifier
// manager. We do this by removing the tags that the compiler pass looks
// for. This means that the URL generator can safely be used during the
// database update process.
if ($container->hasDefinition('path_processor_alias')) {
$container->getDefinition('path_processor_alias')
if ($container->hasDefinition('path_alias.path_processor')) {
$container->getDefinition('path_alias.path_processor')
->clearTag('path_processor_inbound')
->clearTag('path_processor_outbound');
}

View File

@ -24,6 +24,7 @@ class MigrateBlockContentTranslationTest extends MigrateDrupal6TestBase {
'block_content',
'content_translation',
'language',
'path_alias',
'statistics',
'taxonomy',
// Required for translation migrations.

View File

@ -26,6 +26,7 @@ class MigrateBlockTest extends MigrateDrupal6TestBase {
'aggregator',
'book',
'forum',
'path_alias',
'statistics',
];

View File

@ -28,6 +28,7 @@ class MigrateBlockContentTranslationTest extends MigrateDrupal7TestBase {
'config_translation',
'content_translation',
'language',
'path_alias',
'statistics',
'taxonomy',
// Required for translation migrations.

View File

@ -25,6 +25,7 @@ class MigrateBlockTest extends MigrateDrupal7TestBase {
'node',
'text',
'filter',
'path_alias',
'user',
];

View File

@ -90,7 +90,7 @@ class ConfigImportAllTest extends ModuleTestBase {
// Ensure that only core required modules and the install profile can not be uninstalled.
$validation_reasons = \Drupal::service('module_installer')->validateUninstall(array_keys($all_modules));
$this->assertEquals(['system', 'user', 'standard'], array_keys($validation_reasons));
$this->assertEquals(['path_alias', 'system', 'user', 'standard'], array_keys($validation_reasons));
$modules_to_uninstall = array_filter($all_modules, function ($module) use ($validation_reasons) {
// Filter required and not enabled modules.

View File

@ -2,7 +2,7 @@
namespace Drupal\Tests\jsonapi\Functional;
use Drupal\Core\Path\Entity\PathAlias;
use Drupal\path_alias\Entity\PathAlias;
use Drupal\Core\Url;
/**

View File

@ -7,7 +7,7 @@
use Drupal\Core\Url;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Path\PathAliasInterface;
use Drupal\path_alias\PathAliasInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\system\MenuInterface;

View File

@ -21,7 +21,7 @@ class PathAliasMenuLinkContentTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['menu_link_content', 'system', 'link', 'test_page_test', 'user'];
public static $modules = ['menu_link_content', 'system', 'link', 'path_alias', 'test_page_test', 'user'];
/**
* {@inheritdoc}
@ -44,7 +44,7 @@ class PathAliasMenuLinkContentTest extends KernelTestBase {
public function register(ContainerBuilder $container) {
parent::register($container);
$definition = $container->getDefinition('path_processor_alias');
$definition = $container->getDefinition('path_alias.path_processor');
$definition
->addTag('path_processor_inbound', ['priority' => 100]);
}

View File

@ -1,6 +1,8 @@
langcode: en
status: true
dependencies: { }
dependencies:
module:
- path_alias
id: path_alias.path_alias
target_entity_type_id: path_alias
target_bundle: path_alias

View File

@ -5,3 +5,5 @@ package: Core
version: VERSION
core: 8.x
configure: entity.path_alias.collection
dependencies:
- drupal:path_alias

View File

@ -47,15 +47,19 @@ function path_help($route_name, RouteMatchInterface $route_match) {
* Implements hook_entity_type_alter().
*/
function path_entity_type_alter(array &$entity_types) {
// @todo Remove the conditional once core fully supports "path_alias" as an
// optional module. See https://drupal.org/node/3092090.
/** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
$entity_types['path_alias']->setFormClass('default', PathAliasForm::class);
$entity_types['path_alias']->setFormClass('delete', ContentEntityDeleteForm::class);
$entity_types['path_alias']->setHandlerClass('route_provider', ['html' => AdminHtmlRouteProvider::class]);
$entity_types['path_alias']->setListBuilderClass(PathAliasListBuilder::class);
$entity_types['path_alias']->setLinkTemplate('collection', '/admin/config/search/path');
$entity_types['path_alias']->setLinkTemplate('add-form', '/admin/config/search/path/add');
$entity_types['path_alias']->setLinkTemplate('edit-form', '/admin/config/search/path/edit/{path_alias}');
$entity_types['path_alias']->setLinkTemplate('delete-form', '/admin/config/search/path/delete/{path_alias}');
if (isset($entity_types['path_alias'])) {
$entity_types['path_alias']->setFormClass('default', PathAliasForm::class);
$entity_types['path_alias']->setFormClass('delete', ContentEntityDeleteForm::class);
$entity_types['path_alias']->setHandlerClass('route_provider', ['html' => AdminHtmlRouteProvider::class]);
$entity_types['path_alias']->setListBuilderClass(PathAliasListBuilder::class);
$entity_types['path_alias']->setLinkTemplate('collection', '/admin/config/search/path');
$entity_types['path_alias']->setLinkTemplate('add-form', '/admin/config/search/path/add');
$entity_types['path_alias']->setLinkTemplate('edit-form', '/admin/config/search/path/edit/{path_alias}');
$entity_types['path_alias']->setLinkTemplate('delete-form', '/admin/config/search/path/delete/{path_alias}');
}
}
/**

View File

@ -15,7 +15,7 @@ class PathAliasForm extends ContentEntityForm {
/**
* The path_alias entity.
*
* @var \Drupal\Core\Path\PathAliasInterface
* @var \Drupal\path_alias\PathAliasInterface
*/
protected $entity;

View File

@ -27,7 +27,7 @@ class PathFieldItemList extends FieldItemList {
$entity = $this->getEntity();
if (!$entity->isNew()) {
/** @var \Drupal\Core\Path\AliasRepositoryInterface $path_alias_repository */
$path_alias_repository = \Drupal::service('path.alias_repository');
$path_alias_repository = \Drupal::service('path_alias.repository');
if ($path_alias = $path_alias_repository->lookupBySystemPath('/' . $entity->toUrl()->getInternalPath(), $this->getLangcode())) {
$value = [

View File

@ -87,7 +87,7 @@ class PathWidget extends WidgetBase {
if (!empty($alias)) {
$form_state->setValueForElement($element['alias'], $alias);
/** @var \Drupal\Core\Path\PathAliasInterface $path_alias */
/** @var \Drupal\path_alias\PathAliasInterface $path_alias */
$path_alias = \Drupal::entityTypeManager()->getStorage('path_alias')->create([
'path' => $element['source']['#value'],
'alias' => $alias,

View File

@ -326,7 +326,7 @@ class PathAliasTest extends PathTestBase {
// Delete the node and check that the path alias is also deleted.
$node5->delete();
$path_alias = \Drupal::service('path.alias_repository')->lookUpBySystemPath('/node/' . $node5->id(), $node5->language()->getId());
$path_alias = \Drupal::service('path_alias.repository')->lookUpBySystemPath('/node/' . $node5->id(), $node5->language()->getId());
$this->assertFalse($path_alias, 'Alias was successfully deleted when the referenced node was deleted.');
// Create sixth test node.

View File

@ -2,7 +2,7 @@
namespace Drupal\Tests\path\Kernel\Migrate\d6;
use Drupal\Core\Path\PathAliasInterface;
use Drupal\path_alias\PathAliasInterface;
use Drupal\migrate\Plugin\MigrateIdMapInterface;
use Drupal\Core\Database\Database;
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
@ -24,6 +24,7 @@ class MigrateUrlAliasTest extends MigrateDrupal6TestBase {
'language',
'content_translation',
'path',
'path_alias',
'menu_ui',
// Required for translation migrations.
'migrate_drupal_multilingual',
@ -57,7 +58,7 @@ class MigrateUrlAliasTest extends MigrateDrupal6TestBase {
* The path alias ID.
* @param array $conditions
* The path conditions.
* @param \Drupal\Core\Path\PathAliasInterface $path_alias
* @param \Drupal\path_alias\PathAliasInterface $path_alias
* The path alias.
*/
private function assertPath($pid, $conditions, PathAliasInterface $path_alias) {

View File

@ -13,6 +13,7 @@ class MigrateUrlAliasTest extends MigrateUrlAliasTestBase {
* {@inheritdoc}
*/
public static $modules = [
'path_alias',
'content_translation',
'migrate_drupal_multilingual',
];

View File

@ -22,6 +22,7 @@ abstract class MigrateUrlAliasTestBase extends MigrateDrupal7TestBase {
'menu_ui',
'node',
'path',
'path_alias',
'text',
];

View File

@ -19,7 +19,7 @@ class PathItemTest extends KernelTestBase {
*
* @var array
*/
public static $modules = ['path', 'node', 'user', 'system', 'language', 'content_translation'];
public static $modules = ['path', 'path_alias', 'node', 'user', 'system', 'language', 'content_translation'];
/**
* {@inheritdoc}
@ -45,7 +45,7 @@ class PathItemTest extends KernelTestBase {
*/
public function testPathItem() {
/** @var \Drupal\Core\Path\AliasRepositoryInterface $alias_repository */
$alias_repository = \Drupal::service('path.alias_repository');
$alias_repository = \Drupal::service('path_alias.repository');
$node_storage = \Drupal::entityTypeManager()->getStorage('node');

View File

@ -16,7 +16,7 @@ class PathLegacyRoutesKernelTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['path'];
protected static $modules = ['path', 'path_alias'];
/**
* @expectedDeprecation The 'path.admin_add' route is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the 'entity.path_alias.add_form' route instead. See https://www.drupal.org/node/3013865

View File

@ -0,0 +1,7 @@
name: Path alias
type: module
description: 'Provides the API allowing to rename URLs.'
package: Core
version: VERSION
required: true
hidden: true

View File

@ -0,0 +1,10 @@
<?php
namespace Drupal\path_alias;
use Drupal\Core\Path\AliasManager as CoreAliasManager;
/**
* The default alias manager implementation.
*/
class AliasManager extends CoreAliasManager implements AliasManagerInterface {}

View File

@ -0,0 +1,12 @@
<?php
namespace Drupal\path_alias;
use Drupal\Core\Path\AliasManagerInterface as CoreAliasManagerInterface;
/**
* Find an alias for a path and vice versa.
*
* @see \Drupal\Core\Path\AliasStorageInterface
*/
interface AliasManagerInterface extends CoreAliasManagerInterface {}

View File

@ -0,0 +1,10 @@
<?php
namespace Drupal\path_alias;
use Drupal\Core\Path\AliasRepository as CoreAliasRepository;
/**
* Provides the default path alias lookup operations.
*/
class AliasRepository extends CoreAliasRepository implements AliasRepositoryInterface {}

View File

@ -0,0 +1,20 @@
<?php
namespace Drupal\path_alias;
use Drupal\Core\Path\AliasRepositoryInterface as CoreAliasRepositoryInterface;
/**
* Provides an interface for path alias lookup operations.
*
* The path alias repository service is only used internally in order to
* optimize alias lookup queries needed in the critical path of each request.
* However, it is not marked as an internal service because alternative storage
* backends still need to override it if they provide a different storage class
* for the PathAlias entity type.
*
* Whenever you need to determine whether an alias exists for a system path, or
* whether a system path has an alias, the 'path_alias.manager' service should
* be used instead.
*/
interface AliasRepositoryInterface extends CoreAliasRepositoryInterface {}

View File

@ -0,0 +1,10 @@
<?php
namespace Drupal\path_alias;
use Drupal\Core\Path\AliasWhitelist as CoreAliasWhitelist;
/**
* Extends CacheCollector to build the path alias whitelist over time.
*/
class AliasWhitelist extends CoreAliasWhitelist implements AliasWhitelistInterface {}

View File

@ -0,0 +1,15 @@
<?php
namespace Drupal\path_alias;
use Drupal\Core\Path\AliasWhitelistInterface as CoreAliasWhitelistInterface;
/**
* Cache the alias whitelist.
*
* The whitelist contains the first element of the router paths of all
* aliases. For example, if /node/12345 has an alias then "node" is added to
* the whitelist. This optimization allows skipping the lookup for every
* /user/{user} path if "user" is not in the whitelist.
*/
interface AliasWhitelistInterface extends CoreAliasWhitelistInterface {}

View File

@ -1,6 +1,6 @@
<?php
namespace Drupal\Core\Path\Entity;
namespace Drupal\path_alias\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityPublishedTrait;
@ -9,7 +9,7 @@ use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Path\PathAliasInterface;
use Drupal\path_alias\PathAliasInterface;
/**
* Defines the path_alias entity class.
@ -25,8 +25,8 @@ use Drupal\Core\Path\PathAliasInterface;
* plural = "@count URL aliases"
* ),
* handlers = {
* "storage" = "Drupal\Core\Path\PathAliasStorage",
* "storage_schema" = "Drupal\Core\Path\PathAliasStorageSchema",
* "storage" = "Drupal\path_alias\PathAliasStorage",
* "storage_schema" = "Drupal\path_alias\PathAliasStorageSchema",
* },
* base_table = "path_alias",
* revision_table = "path_alias_revision",

View File

@ -0,0 +1,10 @@
<?php
namespace Drupal\path_alias\EventSubscriber;
use Drupal\Core\EventSubscriber\PathSubscriber;
/**
* Provides a path subscriber that converts path aliases.
*/
class PathAliasSubscriber extends PathSubscriber {}

View File

@ -1,6 +1,6 @@
<?php
namespace Drupal\Core\Path;
namespace Drupal\path_alias;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityPublishedInterface;

View File

@ -0,0 +1,79 @@
<?php
namespace Drupal\path_alias;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Drupal\Core\EventSubscriber\PathSubscriber;
use Drupal\Core\Path\AliasManager as CoreAliasManager;
use Drupal\Core\Path\AliasRepository as CoreAliasRepository;
use Drupal\Core\Path\AliasWhitelist as CoreAliasWhitelist;
use Drupal\Core\PathProcessor\PathProcessorAlias;
use Drupal\path_alias\EventSubscriber\PathAliasSubscriber;
use Drupal\path_alias\PathProcessor\AliasPathProcessor;
/**
* Path Alias service provider.
*
* Updates core path alias service definitions to use the new classes provided
* by "path_alias" and marks the old ones as deprecated. The "path_alias.*"
* services defined in "core.services.yml" will bridge the gap.
*
* @see https://www.drupal.org/node/3092086
*
* @todo Remove this once core fully supports "path_alias" as an optional
* module. See https://www.drupal.org/node/3092090.
*/
class PathAliasServiceProvider implements ServiceModifierInterface {
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
$service_map = [
'path_subscriber' => [
'class' => PathAliasSubscriber::class,
'core_class' => PathSubscriber::class,
'new_service' => 'path_alias.subscriber',
],
'path_processor_alias' => [
'class' => AliasPathProcessor::class,
'core_class' => PathProcessorAlias::class,
'new_service' => 'path_alias.path_processor',
],
'path.alias_manager' => [
'class' => AliasManager::class,
'core_class' => CoreAliasManager::class,
'new_service' => 'path_alias.manager',
],
'path.alias_whitelist' => [
'class' => AliasWhitelist::class,
'core_class' => CoreAliasWhitelist::class,
'new_service' => 'path_alias.whitelist',
],
'path_alias.repository' => [
'class' => AliasRepository::class,
'core_class' => CoreAliasRepository::class,
'new_service' => 'path_alias.repository',
],
];
// Replace services only if core classes are implementing them to avoid
// overriding customizations not relying on decoration.
foreach ($service_map as $id => $info) {
// Mark legacy services as "deprecated".
$definition = $id !== $info['new_service'] && $container->hasDefinition($id) ? $container->getDefinition($id) : NULL;
if ($definition && $definition->getClass() === $info['core_class']) {
$definition->setDeprecated(TRUE, 'The "%service_id%" service is deprecated. Use "' . $info['new_service'] . '" instead. See https://drupal.org/node/3092086');
}
// Also the new service's class is initially set to the legacy one, to
// avoid errors when the "path_alias" module is not enabled yet. Here we
// need to replace that as well.
$definition = $container->getDefinition($info['new_service']);
if ($definition && $definition->getClass() === $info['core_class']) {
$definition->setClass($info['class']);
}
}
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace Drupal\Core\Path;
namespace Drupal\path_alias;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;

View File

@ -1,6 +1,6 @@
<?php
namespace Drupal\Core\Path;
namespace Drupal\path_alias;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema;

View File

@ -0,0 +1,10 @@
<?php
namespace Drupal\path_alias\PathProcessor;
use Drupal\Core\PathProcessor\PathProcessorAlias;
/**
* Processes the inbound path using path alias lookups.
*/
class AliasPathProcessor extends PathProcessorAlias {}

View File

@ -0,0 +1,5 @@
name: 'Path Alias deprecated test'
type: module
description: 'Support module for testing deprecated functionality for path aliases.'
package: Testing
version: VERSION

View File

@ -0,0 +1,5 @@
services:
path_alias_deprecated_test.path.alias_manager:
class: Drupal\path_alias_deprecated_test\AliasManagerDecorator
decorates: path.alias_manager
arguments: ['@path_alias_deprecated_test.path.alias_manager.inner']

View File

@ -0,0 +1,50 @@
<?php
namespace Drupal\path_alias_deprecated_test;
use Drupal\Core\Path\AliasManagerInterface;
/**
* Test alias manager decorator.
*/
class AliasManagerDecorator implements AliasManagerInterface {
/**
* The decorated alias manager.
*
* @var \Drupal\Core\Path\AliasManagerInterface
*/
protected $aliasManager;
/**
* AliasManagerDecorator constructor.
*
* @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
* The decorated alias manager.
*/
public function __construct(AliasManagerInterface $alias_manager) {
$this->aliasManager = $alias_manager;
}
/**
* {@inheritdoc}
*/
public function getPathByAlias($alias, $langcode = NULL) {
$this->aliasManager->getPathByAlias($alias, $langcode);
}
/**
* {@inheritdoc}
*/
public function getAliasByPath($path, $langcode = NULL) {
return $this->aliasManager->getAliasByPath($path, $langcode);
}
/**
* {@inheritdoc}
*/
public function cacheClear($source = NULL) {
$this->aliasManager->cacheClear($source);
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace Drupal\path_alias_deprecated_test;
use Drupal\Core\Path\AliasManagerInterface;
/**
* New test implementation for the alias manager.
*/
class NewAliasManager implements AliasManagerInterface {
/**
* {@inheritdoc}
*/
public function getPathByAlias($alias, $langcode = NULL) {
}
/**
* {@inheritdoc}
*/
public function getAliasByPath($path, $langcode = NULL) {
}
/**
* {@inheritdoc}
*/
public function cacheClear($source = NULL) {
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Drupal\path_alias_deprecated_test;
use Drupal\Core\Path\AliasManager;
/**
* Overridden test implementation for the alias manager.
*/
class OverriddenAliasManager extends AliasManager {}

View File

@ -0,0 +1,44 @@
<?php
namespace Drupal\path_alias_deprecated_test;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
/**
* Test service provider to test path alias deprecated services BC logic.
*/
class PathAliasDeprecatedTestServiceProvider implements ServiceModifierInterface {
/**
* The name of the new implementation class for the alias manager.
*
* @var string
*/
public static $newClass;
/**
* Whether to use a decorator to wrap the alias manager implementation.
*
* @var bool
*/
public static $useDecorator = FALSE;
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
if (isset(static::$newClass)) {
$definition = $container->getDefinition('path.alias_manager');
$definition->setClass(static::$newClass);
}
if (!static::$useDecorator) {
$decorator_id = 'path_alias_deprecated_test.path.alias_manager';
if ($container->hasDefinition($decorator_id)) {
$container->removeDefinition($decorator_id);
}
}
}
}

View File

@ -1,11 +1,12 @@
<?php
namespace Drupal\FunctionalTests\Hal;
namespace Drupal\Tests\path_alias\Functional\Hal;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* @group hal
* @group path_alias
*/
class PathAliasHalJsonAnonTest extends PathAliasHalJsonTestBase {

View File

@ -1,11 +1,12 @@
<?php
namespace Drupal\FunctionalTests\Hal;
namespace Drupal\Tests\path_alias\Functional\Hal;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* @group hal
* @group path_alias
*/
class PathAliasHalJsonBasicAuthTest extends PathAliasHalJsonTestBase {

View File

@ -1,11 +1,12 @@
<?php
namespace Drupal\FunctionalTests\Hal;
namespace Drupal\Tests\path_alias\Functional\Hal;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* @group hal
* @group path_alias
*/
class PathAliasHalJsonCookieTest extends PathAliasHalJsonTestBase {

View File

@ -1,9 +1,9 @@
<?php
namespace Drupal\FunctionalTests\Hal;
namespace Drupal\Tests\path_alias\Functional\Hal;
use Drupal\FunctionalTests\Rest\PathAliasResourceTestBase;
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
use Drupal\Tests\path_alias\Functional\Rest\PathAliasResourceTestBase;
/**
* Base hal_json test class for the path_alias entity type.

View File

@ -1,13 +1,13 @@
<?php
namespace Drupal\FunctionalTests\Rest;
namespace Drupal\Tests\path_alias\Functional\Rest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
/**
* Test path_alias entities for unauthenticated JSON requests.
*
* @group path
* @group path_alias
*/
class PathAliasJsonAnonTest extends PathAliasResourceTestBase {

View File

@ -1,13 +1,13 @@
<?php
namespace Drupal\FunctionalTests\Rest;
namespace Drupal\Tests\path_alias\Functional\Rest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
/**
* Test path_alias entities for JSON requests via basic auth.
*
* @group path
* @group path_alias
*/
class PathAliasJsonBasicAuthTest extends PathAliasResourceTestBase {

View File

@ -1,13 +1,13 @@
<?php
namespace Drupal\FunctionalTests\Rest;
namespace Drupal\Tests\path_alias\Functional\Rest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
/**
* Test path_alias entities for JSON requests with cookie authentication.
*
* @group path
* @group path_alias
*/
class PathAliasJsonCookieTest extends PathAliasResourceTestBase {

View File

@ -1,9 +1,9 @@
<?php
namespace Drupal\FunctionalTests\Rest;
namespace Drupal\Tests\path_alias\Functional\Rest;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Path\Entity\PathAlias;
use Drupal\path_alias\Entity\PathAlias;
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
@ -14,6 +14,11 @@ abstract class PathAliasResourceTestBase extends EntityResourceTestBase {
use BcTimestampNormalizerUnixTestTrait;
/**
* {@inheritdoc}
*/
public static $modules = ['path_alias'];
/**
* {@inheritdoc}
*/

View File

@ -1,6 +1,6 @@
<?php
namespace Drupal\FunctionalTests\Rest;
namespace Drupal\Tests\path_alias\Functional\Rest;
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
@ -8,7 +8,7 @@ use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrai
/**
* Test path_alias entities for unauthenticated XML requests.
*
* @group path
* @group path_alias
*/
class PathAliasXmlAnonTest extends PathAliasResourceTestBase {

View File

@ -1,6 +1,6 @@
<?php
namespace Drupal\FunctionalTests\Rest;
namespace Drupal\Tests\path_alias\Functional\Rest;
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
@ -8,7 +8,7 @@ use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrai
/**
* Test path_alias entities for XML requests with cookie authentication.
*
* @group path
* @group path_alias
*/
class PathAliasXmlBasicAuthTest extends PathAliasResourceTestBase {

View File

@ -1,6 +1,6 @@
<?php
namespace Drupal\FunctionalTests\Rest;
namespace Drupal\Tests\path_alias\Functional\Rest;
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
@ -8,7 +8,7 @@ use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrai
/**
* Test path_alias entities for XML requests.
*
* @group path
* @group path_alias
*/
class PathAliasXmlCookieTest extends PathAliasResourceTestBase {

View File

@ -1,6 +1,6 @@
<?php
namespace Drupal\Tests\system\Functional\Path;
namespace Drupal\Tests\path_alias\Functional;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Database\Database;
@ -12,7 +12,7 @@ use Drupal\Tests\Traits\Core\PathAliasTestTrait;
/**
* Tests altering the inbound path and the outbound path.
*
* @group path
* @group path_alias
*/
class UrlAlterFunctionalTest extends BrowserTestBase {

View File

@ -1,12 +1,12 @@
<?php
namespace Drupal\KernelTests\Core\Path;
namespace Drupal\Tests\path_alias\Kernel;
use Drupal\Core\Cache\MemoryCounterBackend;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Path\AliasManager;
use Drupal\Core\Path\AliasWhitelist;
use Drupal\KernelTests\KernelTestBase;
use Drupal\path_alias\AliasManager;
use Drupal\path_alias\AliasWhitelist;
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
/**
@ -14,12 +14,17 @@ use Drupal\Tests\Traits\Core\PathAliasTestTrait;
*
* @coversDefaultClass \Drupal\Core\Path\AliasRepository
*
* @group path
* @group path_alias
*/
class AliasTest extends KernelTestBase {
use PathAliasTestTrait;
/**
* {@inheritdoc}
*/
protected static $modules = ['path_alias'];
/**
* {@inheritdoc}
*/
@ -39,7 +44,7 @@ class AliasTest extends KernelTestBase {
public function testLookupBySystemPath() {
$this->createPathAlias('/test-source-Case', '/test-alias');
$path_alias_repository = $this->container->get('path.alias_repository');
$path_alias_repository = $this->container->get('path_alias.repository');
$this->assertEquals('/test-alias', $path_alias_repository->lookupBySystemPath('/test-source-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED)['alias']);
$this->assertEquals('/test-alias', $path_alias_repository->lookupBySystemPath('/test-source-case', LanguageInterface::LANGCODE_NOT_SPECIFIED)['alias']);
}
@ -50,7 +55,7 @@ class AliasTest extends KernelTestBase {
public function testLookupByAlias() {
$this->createPathAlias('/test-source', '/test-alias-Case');
$path_alias_repository = $this->container->get('path.alias_repository');
$path_alias_repository = $this->container->get('path_alias.repository');
$this->assertEquals('/test-source', $path_alias_repository->lookupByAlias('/test-alias-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED)['path']);
$this->assertEquals('/test-source', $path_alias_repository->lookupByAlias('/test-alias-case', LanguageInterface::LANGCODE_NOT_SPECIFIED)['path']);
}
@ -112,8 +117,8 @@ class AliasTest extends KernelTestBase {
$memoryCounterBackend = new MemoryCounterBackend();
// Create AliasManager and Path object.
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path.alias_repository'));
$aliasManager = new AliasManager($this->container->get('path.alias_repository'), $whitelist, $this->container->get('language_manager'), $memoryCounterBackend);
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository'));
$aliasManager = new AliasManager($this->container->get('path_alias.repository'), $whitelist, $this->container->get('language_manager'), $memoryCounterBackend);
// No alias for user and admin yet, so should be NULL.
$this->assertNull($whitelist->get('user'));
@ -153,7 +158,7 @@ class AliasTest extends KernelTestBase {
// Re-initialize the whitelist using the same cache backend, should load
// from cache.
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path.alias_repository'));
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository'));
$this->assertNull($whitelist->get('user'));
$this->assertTrue($whitelist->get('admin'));
$this->assertNull($whitelist->get($this->randomMachineName()));
@ -173,8 +178,8 @@ class AliasTest extends KernelTestBase {
$memoryCounterBackend = new MemoryCounterBackend();
// Create AliasManager and Path object.
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path.alias_repository'));
$aliasManager = new AliasManager($this->container->get('path.alias_repository'), $whitelist, $this->container->get('language_manager'), $memoryCounterBackend);
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository'));
$aliasManager = new AliasManager($this->container->get('path_alias.repository'), $whitelist, $this->container->get('language_manager'), $memoryCounterBackend);
// Whitelist cache should not exist at all yet.
$this->assertFalse($memoryCounterBackend->get('path_alias_whitelist'));
@ -201,7 +206,7 @@ class AliasTest extends KernelTestBase {
// Whitelist should load data from its cache, see that it hasn't done a
// check for 'user' yet, perform the check, then mark the result to be
// persisted to cache.
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path.alias_repository'));
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository'));
$this->assertTrue($whitelist->get('user'));
// Delete the whitelist cache. This could happen from an outside process,

View File

@ -0,0 +1,186 @@
<?php
namespace Drupal\Tests\path_alias\Kernel;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Core\Path\AliasManager as CoreAliasManager;
use Drupal\path_alias\AliasManager;
use Drupal\path_alias\Entity\PathAlias;
use Drupal\path_alias_deprecated_test\AliasManagerDecorator;
use Drupal\path_alias_deprecated_test\NewAliasManager;
use Drupal\path_alias_deprecated_test\OverriddenAliasManager;
use Drupal\path_alias_deprecated_test\PathAliasDeprecatedTestServiceProvider;
/**
* Tests deprecation of path alias core services and the related BC logic.
*
* @group path_alias
* @group legacy
*/
class DeprecatedServicesTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['path_alias', 'path_alias_deprecated_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('path_alias');
}
/**
* @expectedDeprecation The "path.alias_manager" service is deprecated. Use "path_alias.manager" instead. See https://drupal.org/node/3092086
*/
public function testAliasManagerDeprecation() {
$this->container->get('path.alias_manager');
}
/**
* @expectedDeprecation The "path.alias_manager" service is deprecated. Use "path_alias.manager" instead. See https://drupal.org/node/3092086
* @expectedDeprecation The \Drupal\Core\Path\AliasManager class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\AliasManager. See https://drupal.org/node/3092086
*/
public function testOverriddenServiceImplementation() {
$class = $this->setServiceClass(OverriddenAliasManager::class);
$this->assertServiceClass('path.alias_manager', $class);
$this->assertServiceClass('path_alias.manager', AliasManager::class);
}
/**
* @expectedDeprecation The "path.alias_manager" service is deprecated. Use "path_alias.manager" instead. See https://drupal.org/node/3092086
*/
public function testNewServiceImplementation() {
$class = $this->setServiceClass(NewAliasManager::class);
$this->assertServiceClass('path.alias_manager', $class);
$this->assertServiceClass('path_alias.manager', AliasManager::class);
}
/**
* @expectedDeprecation The "path_alias_deprecated_test.path.alias_manager.inner" service is deprecated. Use "path_alias.manager" instead. See https://drupal.org/node/3092086
* @expectedDeprecation The \Drupal\Core\Path\AliasManager class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\AliasManager. See https://drupal.org/node/3092086
*/
public function testDecoratorForOverriddenServiceImplementation() {
$this->setServiceClass(OverriddenAliasManager::class, TRUE);
$this->assertServiceClass('path.alias_manager', AliasManagerDecorator::class);
$this->assertServiceClass('path_alias.manager', AliasManager::class);
}
/**
* @expectedDeprecation The "path_alias_deprecated_test.path.alias_manager.inner" service is deprecated. Use "path_alias.manager" instead. See https://drupal.org/node/3092086
*/
public function testDecoratorForNewServiceImplementation() {
$this->setServiceClass(NewAliasManager::class, TRUE);
$this->assertServiceClass('path.alias_manager', AliasManagerDecorator::class);
$this->assertServiceClass('path_alias.manager', AliasManager::class);
}
/**
* @expectedDeprecation The "path.alias_manager" service is deprecated. Use "path_alias.manager" instead. See https://drupal.org/node/3092086
*/
public function testDefaultImplementations() {
$this->assertServiceClass('path.alias_manager', CoreAliasManager::class);
$this->assertServiceClass('path_alias.manager', AliasManager::class);
}
/**
* No deprecation message expected.
*/
public function testRegularImplementation() {
$this->assertServiceClass('path_alias.manager', AliasManager::class);
}
/**
* Test that the new alias manager and the legacy ones share the same state.
*
* @expectedDeprecation The \Drupal\Core\Path\AliasManager class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\AliasManager. See https://drupal.org/node/3092086
*/
public function testAliasManagerSharedState() {
/** @var \Drupal\Core\Path\AliasManager $legacy_alias_manager */
$legacy_alias_manager = $this->container->get('path.alias_manager');
/** @var \Drupal\path_alias\AliasManager $alias_manager */
$alias_manager = $this->container->get('path_alias.manager');
$cache_key = $this->randomMachineName();
$alias_manager->setCacheKey($cache_key);
$this->assertSharedProperty('preload-paths:' . $cache_key, $legacy_alias_manager, 'cacheKey');
$invalid_alias = '/' . $this->randomMachineName();
$alias_manager->getPathByAlias($invalid_alias);
$this->assertSharedProperty(['en' => [$invalid_alias => TRUE]], $legacy_alias_manager, 'noPath');
$this->assertSharedProperty(FALSE, $legacy_alias_manager, 'preloadedPathLookups');
/** @var \Drupal\path_alias\Entity\PathAlias $alias */
$alias = PathAlias::create([
'path' => '/' . $this->randomMachineName(),
'alias' => $invalid_alias . '2',
]);
$alias->save();
$this->assertSharedProperty([], $legacy_alias_manager, 'preloadedPathLookups');
/** @var \Drupal\Core\State\StateInterface $state */
$state = $this->container->get('state');
$state->set('router.path_roots', [ltrim($alias->getPath(), '/')]);
$alias_manager->getAliasByPath($alias->getPath());
$this->assertSharedProperty(['en' => [$alias->getPath() => $alias->getAlias()]], $legacy_alias_manager, 'lookupMap');
$invalid_path = $alias->getPath() . '/' . $this->randomMachineName();
$alias_manager->getAliasByPath($invalid_path);
$this->assertSharedProperty(['en' => [$invalid_path => TRUE]], $legacy_alias_manager, 'noAlias');
}
/**
* Asserts that a shared property has the expected value.
*
* @param mixed $expected
* The property expected value.
* @param \Drupal\Core\Path\AliasManager $legacy_alias_manager
* An instance of the legacy alias manager.
* @param string $property
* The property name.
*/
protected function assertSharedProperty($expected, CoreAliasManager $legacy_alias_manager, $property) {
$reflector = new \ReflectionProperty(get_class($legacy_alias_manager), $property);
$reflector->setAccessible(TRUE);
$this->assertSame($expected, $reflector->getValue($legacy_alias_manager));
}
/**
* Asserts that the specified service is implemented by the expected class.
*
* @param string $service_id
* A service ID.
* @param string $expected_class
* The name of the expected class.
*/
protected function assertServiceClass($service_id, $expected_class) {
$service = $this->container->get($service_id);
$this->assertSame(get_class($service), $expected_class);
}
/**
* Sets the specified implementation for the service being tested.
*
* @param string $class
* The name of the implementation class.
* @param bool $use_decorator
* (optional) Whether using a decorator service to wrap the specified class.
* Defaults to no decorator.
*
* @return string
* The specified class name.
*/
protected function setServiceClass($class, $use_decorator = FALSE) {
PathAliasDeprecatedTestServiceProvider::$newClass = $class;
PathAliasDeprecatedTestServiceProvider::$useDecorator = $use_decorator;
$this->container->get('kernel')->rebuildContainer();
return $class;
}
}

View File

@ -1,23 +1,23 @@
<?php
namespace Drupal\Tests\system\Kernel;
namespace Drupal\Tests\path_alias\Kernel;
use Drupal\Core\Path\AliasManagerInterface;
use Drupal\Core\Path\Entity\PathAlias;
use Drupal\KernelTests\KernelTestBase;
use Drupal\path_alias\AliasManagerInterface;
use Drupal\path_alias\Entity\PathAlias;
use Prophecy\Argument;
/**
* @coversDefaultClass \Drupal\Core\Path\Entity\PathAlias
* @coversDefaultClass \Drupal\path_alias\Entity\PathAlias
*
* @group path
* @group path_alias
*/
class PathHooksTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system'];
public static $modules = ['path_alias'];
/**
* {@inheritdoc}

View File

@ -1,23 +1,23 @@
<?php
namespace Drupal\Tests\Core\Path;
namespace Drupal\Tests\path_alias\Unit;
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Path\AliasManager;
use Drupal\Core\Path\AliasRepositoryInterface;
use Drupal\path_alias\AliasManager;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\Core\Path\AliasManager
* @group path
* @coversDefaultClass \Drupal\path_alias\AliasManager
* @group path_alias
*/
class AliasManagerTest extends UnitTestCase {
/**
* The alias manager.
*
* @var \Drupal\Core\Path\AliasManager
* @var \Drupal\path_alias\AliasManager
*/
protected $aliasManager;
@ -38,7 +38,7 @@ class AliasManagerTest extends UnitTestCase {
/**
* Alias whitelist.
*
* @var \Drupal\Core\Path\AliasWhitelistInterface|\PHPUnit\Framework\MockObject\MockObject
* @var \Drupal\path_alias\AliasWhitelistInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $aliasWhitelist;
@ -77,7 +77,7 @@ class AliasManagerTest extends UnitTestCase {
parent::setUp();
$this->aliasRepository = $this->createMock(AliasRepositoryInterface::class);
$this->aliasWhitelist = $this->createMock('Drupal\Core\Path\AliasWhitelistInterface');
$this->aliasWhitelist = $this->createMock('Drupal\path_alias\AliasWhitelistInterface');
$this->languageManager = $this->createMock('Drupal\Core\Language\LanguageManagerInterface');
$this->cache = $this->createMock('Drupal\Core\Cache\CacheBackendInterface');

View File

@ -0,0 +1,170 @@
<?php
namespace Drupal\Tests\path_alias\Unit;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\EventSubscriber\PathSubscriber;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\Path\AliasManager as CoreAliasManager;
use Drupal\Core\Path\AliasWhitelist as CoreAliasWhitelist;
use Drupal\Core\Path\CurrentPathStack;
use Drupal\Core\PathProcessor\PathProcessorAlias;
use Drupal\Core\State\StateInterface;
use Drupal\path_alias\AliasManager;
use Drupal\path_alias\AliasManagerInterface;
use Drupal\path_alias\AliasRepositoryInterface;
use Drupal\path_alias\AliasWhitelist;
use Drupal\path_alias\AliasWhitelistInterface;
use Drupal\path_alias\EventSubscriber\PathAliasSubscriber;
use Drupal\path_alias\PathProcessor\AliasPathProcessor;
use Drupal\Tests\UnitTestCase;
/**
* Tests deprecation of path alias core service classes.
*
* @group path_alias
* @group legacy
*/
class DeprecatedClassesTest extends UnitTestCase {
/**
* @var \Drupal\path_alias\AliasManagerInterface
*/
protected $aliasManager;
/**
* @var \Drupal\path_alias\AliasRepositoryInterface
*/
protected $aliasRepository;
/**
* @var \Drupal\path_alias\AliasWhitelistInterface
*/
protected $aliasWhitelist;
/**
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* @var \Drupal\Core\Path\CurrentPathStack
*/
protected $currentPathStack;
/**
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* @var \Drupal\Core\Lock\LockBackendInterface
*/
protected $lock;
/**
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->aliasManager = $this->prophesize(AliasManagerInterface::class)
->reveal();
$this->aliasRepository = $this->prophesize(AliasRepositoryInterface::class)
->reveal();
$this->aliasWhitelist = $this->prophesize(AliasWhitelistInterface::class)
->reveal();
$this->cache = $this->prophesize(CacheBackendInterface::class)
->reveal();
$this->currentPathStack = $this->prophesize(CurrentPathStack::class)
->reveal();
$this->languageManager = $this->prophesize(LanguageManagerInterface::class)
->reveal();
$this->lock = $this->prophesize(LockBackendInterface::class)
->reveal();
$this->state = $this->prophesize(StateInterface::class)
->reveal();
/** @var \Prophecy\Prophecy\ObjectProphecy $container */
$container = $this->prophesize(ContainerBuilder::class);
$container->get('path_alias.manager')
->willReturn($this->aliasManager);
\Drupal::setContainer($container->reveal());
}
/**
* @covers \Drupal\Core\EventSubscriber\PathSubscriber::__construct
*
* @expectedDeprecation The \Drupal\Core\EventSubscriber\PathSubscriber class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\EventSubscriber\PathAliasSubscriber. See https://drupal.org/node/3092086
*/
public function testPathSubscriber() {
new PathSubscriber($this->aliasManager, $this->currentPathStack);
}
/**
* @covers \Drupal\path_alias\EventSubscriber\PathAliasSubscriber::__construct
*/
public function testPathAliasSubscriber() {
$object = new PathAliasSubscriber($this->aliasManager, $this->currentPathStack);
$this->assertInstanceOf(PathSubscriber::class, $object);
}
/**
* @covers \Drupal\Core\PathProcessor\PathProcessorAlias::__construct
*
* @expectedDeprecation The \Drupal\Core\PathProcessor\PathProcessorAlias class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\PathProcessor\AliasPathProcessor. See https://drupal.org/node/3092086
*/
public function testPathProcessorAlias() {
new PathProcessorAlias($this->aliasManager);
}
/**
* @covers \Drupal\path_alias\PathProcessor\AliasPathProcessor::__construct
*/
public function testAliasPathProcessor() {
$object = new AliasPathProcessor($this->aliasManager);
$this->assertInstanceOf(PathProcessorAlias::class, $object);
}
/**
* @covers \Drupal\Core\Path\AliasManager::__construct
*
* @expectedDeprecation The \Drupal\Core\Path\AliasManager class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\AliasManager. See https://drupal.org/node/3092086
*/
public function testCoreAliasManager() {
new CoreAliasManager($this->aliasRepository, $this->aliasWhitelist, $this->languageManager, $this->cache);
}
/**
* @covers \Drupal\path_alias\AliasManager::__construct
*/
public function testAliasManager() {
$object = new AliasManager($this->aliasRepository, $this->aliasWhitelist, $this->languageManager, $this->cache);
$this->assertInstanceOf(CoreAliasManager::class, $object);
}
/**
* @covers \Drupal\Core\Path\AliasWhitelist::__construct
*
* @expectedDeprecation The \Drupal\Core\Path\AliasWhitelist class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\AliasWhitelist. See https://drupal.org/node/3092086
*/
public function testCoreAliasWhitelist() {
new CoreAliasWhitelist('path_alias_whitelist', $this->cache, $this->lock, $this->state, $this->aliasRepository);
}
/**
* @covers \Drupal\path_alias\AliasWhitelist::__construct
*/
public function testAliasWhitelist() {
$object = new AliasWhitelist('path_alias_whitelist', $this->cache, $this->lock, $this->state, $this->aliasRepository);
$this->assertInstanceOf(CoreAliasWhitelist::class, $object);
}
}

View File

@ -1,42 +1,43 @@
<?php
namespace Drupal\Tests\Core\PathProcessor;
namespace Drupal\Tests\path_alias\Unit\PathProcessor;
use Drupal\Core\Cache\Cache;
use Drupal\Core\PathProcessor\PathProcessorAlias;
use Drupal\path_alias\PathProcessor\AliasPathProcessor;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\HttpFoundation\Request;
/**
* @coversDefaultClass \Drupal\Core\PathProcessor\PathProcessorAlias
* @coversDefaultClass \Drupal\path_alias\PathProcessor\AliasPathProcessor
* @group PathProcessor
* @group path_alias
*/
class PathProcessorAliasTest extends UnitTestCase {
class AliasPathProcessorTest extends UnitTestCase {
/**
* The mocked alias manager.
*
* @var \Drupal\Core\Path\AliasManagerInterface|\PHPUnit\Framework\MockObject\MockObject
* @var \Drupal\path_alias\AliasManagerInterface|\PHPUnit\Framework\MockObject\MockObject
*/
protected $aliasManager;
/**
* The tested path processor.
*
* @var \Drupal\Core\PathProcessor\PathProcessorAlias
* @var \Drupal\path_alias\PathProcessor\AliasPathProcessor
*/
protected $pathProcessor;
protected function setUp() {
$this->aliasManager = $this->createMock('Drupal\Core\Path\AliasManagerInterface');
$this->pathProcessor = new PathProcessorAlias($this->aliasManager);
$this->aliasManager = $this->createMock('Drupal\path_alias\AliasManagerInterface');
$this->pathProcessor = new AliasPathProcessor($this->aliasManager);
}
/**
* Tests the processInbound method.
*
* @see \Drupal\Core\PathProcessor\PathProcessorAlias::processInbound
* @see \Drupal\path_alias\PathProcessor\AliasPathProcessor::processInbound
*/
public function testProcessInbound() {
$this->aliasManager->expects($this->exactly(2))

View File

@ -385,12 +385,12 @@ EOD;
->addArgument(new Reference('keyvalue'));
}
if ($container->hasDefinition('path_processor_alias')) {
if ($container->hasDefinition('path_alias.path_processor')) {
// The alias-based processor requires the path_alias entity schema to be
// installed, so we prevent it from being registered to the path processor
// manager. We do this by removing the tags that the compiler pass looks
// for. This means that the URL generator can safely be used within tests.
$definition = $container->getDefinition('path_processor_alias');
$definition = $container->getDefinition('path_alias.path_processor');
$definition->clearTag('path_processor_inbound')->clearTag('path_processor_outbound');
}

View File

@ -13,17 +13,14 @@ use Drupal\Component\Utility\Unicode;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Database\Database;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Entity\ContentEntityType;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Extension\Extension;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Path\Entity\PathAlias;
use Drupal\Core\Path\PathAliasStorage;
use Drupal\Core\Path\PathAliasStorageSchema;
use Drupal\path_alias\Entity\PathAlias;
use Drupal\path_alias\PathAliasStorage;
use Drupal\Core\Site\Settings;
use Drupal\Core\StreamWrapper\PrivateStream;
use Drupal\Core\StreamWrapper\PublicStream;
@ -2395,71 +2392,9 @@ function system_update_8802() {
* Install the 'path_alias' entity type.
*/
function system_update_8803() {
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
if (!$entity_definition_update_manager->getEntityType('path_alias')) {
$entity_type = new ContentEntityType([
'id' => 'path_alias',
'class' => PathAlias::class,
'label' => new TranslatableMarkup('Path alias'),
'handlers' => [
'storage' => PathAliasStorage::class,
'storage_schema' => PathAliasStorageSchema::class,
],
'base_table' => 'path_alias',
'revision_table' => 'path_alias_revision',
'entity_keys' => [
'id' => 'id',
'revision' => 'revision_id',
'langcode' => 'langcode',
'uuid' => 'uuid',
'published' => 'status',
],
]);
$field_storage_definitions['id'] = BaseFieldDefinition::create('integer')
->setLabel(new TranslatableMarkup('ID'))
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);
$field_storage_definitions['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(new TranslatableMarkup('UUID'))
->setReadOnly(TRUE);
$field_storage_definitions['revision_id'] = BaseFieldDefinition::create('integer')
->setLabel(new TranslatableMarkup('Revision ID'))
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);
$field_storage_definitions['langcode'] = BaseFieldDefinition::create('language')
->setLabel(new TranslatableMarkup('Language'))
->setRevisionable(TRUE)
->setDefaultValue(LanguageInterface::LANGCODE_NOT_SPECIFIED);
$field_storage_definitions['revision_default'] = BaseFieldDefinition::create('boolean')
->setLabel(new TranslatableMarkup('Default revision'))
->setStorageRequired(TRUE)
->setInternal(TRUE)
->setRevisionable(TRUE);
$field_storage_definitions['status'] = BaseFieldDefinition::create('boolean')
->setLabel(new TranslatableMarkup('Published'))
->setRevisionable(TRUE)
->setDefaultValue(TRUE);
$field_storage_definitions['path'] = BaseFieldDefinition::create('string')
->setLabel(new TranslatableMarkup('System path'))
->setDescription(new TranslatableMarkup('The path that this alias belongs to.'))
->setRequired(TRUE)
->setRevisionable(TRUE);
$field_storage_definitions['alias'] = BaseFieldDefinition::create('string')
->setLabel(new TranslatableMarkup('Path alias'))
->setDescription(new TranslatableMarkup('An alias used with this path.'))
->setRequired(TRUE)
->setRevisionable(TRUE);
$entity_definition_update_manager->installFieldableEntityType($entity_type, $field_storage_definitions);
// Enable the Path Alias module if needed.
if (!\Drupal::moduleHandler()->moduleExists('path_alias')) {
\Drupal::service('module_installer')->install(['path_alias'], FALSE);
return t('The "path_alias" entity type has been installed.');
}
}
@ -2550,3 +2485,39 @@ function system_update_8804(&$sandbox = NULL) {
return t('Path aliases have been converted to entities.');
}
}
/**
* Change the provider of the 'path_alias' entity type and its base fields.
*/
function system_update_8805() {
// If the path alias module is not installed, it means that
// system_update_8803() ran as part of Drupal 8.8.0-alpha1, in which case we
// need to enable the module and change the provider of the 'path_alias'
// entity type.
if (!\Drupal::moduleHandler()->moduleExists('path_alias')) {
\Drupal::service('module_installer')->install(['path_alias'], FALSE);
/** @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $last_installed_schema_repository */
$last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository');
$entity_type = $last_installed_schema_repository->getLastInstalledDefinition('path_alias');
// Set the new class for the entity type.
$entity_type->setClass(PathAlias::class);
// Set the new provider for the entity type.
$reflection = new ReflectionClass($entity_type);
$property = $reflection->getProperty('provider');
$property->setAccessible(TRUE);
$property->setValue($entity_type, 'path_alias');
$last_installed_schema_repository->setLastInstalledDefinition($entity_type);
$field_storage_definitions = $last_installed_schema_repository->getLastInstalledFieldStorageDefinitions('path_alias');
foreach ($field_storage_definitions as $field_storage_definition) {
if ($field_storage_definition->isBaseField()) {
$field_storage_definition->setProvider('path_alias');
$last_installed_schema_repository->setLastInstalledFieldStorageDefinition($field_storage_definition);
}
}
}
}

View File

@ -3,6 +3,7 @@
namespace Drupal\Tests\system\Functional\Update;
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
use Drupal\path_alias\Entity\PathAlias;
/**
* Tests the conversion of path aliases to entities.
@ -52,6 +53,23 @@ class PathAliasToEntityUpdateTest extends UpdatePathTestBase {
$this->runUpdates();
/** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
$module_handler = $this->container->get('module_handler');
$this->assertTrue($module_handler->moduleExists('path_alias'));
$entity_type = \Drupal::entityDefinitionUpdateManager()->getEntityType('path_alias');
$this->assertEquals('path_alias', $entity_type->getProvider());
$this->assertEquals(PathAlias::class, $entity_type->getClass());
$field_storage_definitions = \Drupal::service('entity.last_installed_schema.repository')->getLastInstalledFieldStorageDefinitions('path_alias');
$this->assertEquals('path_alias', $field_storage_definitions['id']->getProvider());
$this->assertEquals('path_alias', $field_storage_definitions['revision_id']->getProvider());
$this->assertEquals('path_alias', $field_storage_definitions['langcode']->getProvider());
$this->assertEquals('path_alias', $field_storage_definitions['uuid']->getProvider());
$this->assertEquals('path_alias', $field_storage_definitions['status']->getProvider());
$this->assertEquals('path_alias', $field_storage_definitions['path']->getProvider());
$this->assertEquals('path_alias', $field_storage_definitions['alias']->getProvider());
// Check that the 'path_alias' entity tables have been created and the
// 'url_alias' table has been deleted.
$this->assertTrue($schema->tableExists('path_alias'));

View File

@ -16,7 +16,7 @@ class DeprecatedPathHooksTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'path_deprecated_test'];
public static $modules = ['system', 'path_alias', 'path_deprecated_test'];
/**
* {@inheritdoc}

View File

@ -23,6 +23,7 @@ class ArgumentValidateTest extends ViewsKernelTestBase {
*/
public static $modules = [
'node',
'path_alias',
'user_test_views',
];

View File

@ -28,7 +28,7 @@ abstract class ViewsKernelTestBase extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'views', 'views_test_config', 'views_test_data', 'user'];
public static $modules = ['path_alias', 'system', 'views', 'views_test_config', 'views_test_data', 'user'];
/**
* {@inheritdoc}

View File

@ -2,7 +2,7 @@
namespace Drupal\workspaces;
use Drupal\Core\Path\AliasRepository;
use Drupal\path_alias\AliasRepository;
/**
* Provides workspace-specific path alias lookup queries.

View File

@ -20,8 +20,8 @@ class WorkspacesServiceProvider extends ServiceProviderBase {
$renderer_config['required_cache_contexts'][] = 'workspace';
$container->setParameter('renderer.config', $renderer_config);
// Replace the class of the 'path.alias_repository' service.
$container->getDefinition('path.alias_repository')
// Replace the class of the 'path_alias.repository' service.
$container->getDefinition('path_alias.repository')
->setClass(WorkspacesAliasRepository::class)
->addMethodCall('setWorkspacesManager', [new Reference('workspaces.manager')]);
}

View File

@ -86,7 +86,7 @@ class ResolvedLibraryDefinitionsFilesMatchTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'user'];
public static $modules = ['system', 'user', 'path_alias'];
/**
* {@inheritdoc}
@ -124,6 +124,7 @@ class ResolvedLibraryDefinitionsFilesMatchTest extends KernelTestBase {
$this->allModules = array_keys($all_modules);
$this->allModules[] = 'system';
$this->allModules[] = 'user';
$this->allModules[] = 'path_alias';
sort($this->allModules);
$this->container->get('module_installer')->install($this->allModules);

View File

@ -25,7 +25,7 @@ class DbDumpTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'config', 'dblog', 'menu_link_content', 'link', 'block_content', 'file', 'user'];
public static $modules = ['system', 'config', 'dblog', 'menu_link_content', 'link', 'block_content', 'file', 'path_alias', 'user'];
/**
* Test data to write into config.

View File

@ -20,6 +20,7 @@ class CacheabilityMetadataConfigOverrideTest extends KernelTestBase {
'block_content',
'config',
'config_override_test',
'path_alias',
'system',
'user',
];

View File

@ -25,7 +25,7 @@ class CreateSampleEntityTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'field', 'filter', 'text', 'file', 'user', 'node', 'comment', 'taxonomy'];
public static $modules = ['path_alias', 'system', 'field', 'filter', 'text', 'file', 'user', 'node', 'comment', 'taxonomy'];
/**
* {@inheritdoc}

View File

@ -15,7 +15,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system'];
public static $modules = ['system', 'path_alias'];
/**
* @var \Drupal\Core\Path\AliasStorage
@ -34,7 +34,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
/**
* @covers ::load
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
*/
public function testLoad() {
$this->storage->save('/test-source-Case', '/test-alias-Case');
@ -56,7 +56,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
* @covers ::load
* @covers ::save
* @covers ::delete
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
*/
public function testCRUD() {
$entity_storage = \Drupal::entityTypeManager()->getStorage('path_alias');
@ -148,7 +148,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
/**
* @covers ::preloadPathAlias
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
*/
public function testPreLoadPathAlias() {
$this->storage->save('/test-source-Case', '/test-alias');
@ -158,7 +158,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
/**
* @covers ::lookupPathAlias
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
*/
public function testLookupPathAlias() {
$this->storage->save('/test-source-Case', '/test-alias');
@ -169,7 +169,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
/**
* @covers ::lookupPathSource
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
*/
public function testLookupPathSource() {
$this->storage->save('/test-source', '/test-alias-Case');
@ -180,7 +180,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
/**
* @covers ::aliasExists
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
*/
public function testAliasExists() {
$this->storage->save('/test-source-Case', '/test-alias-Case');
@ -191,7 +191,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
/**
* @covers ::languageAliasExists
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
*/
public function testLanguageAliasExists() {
$this->assertFalse($this->storage->languageAliasExists());
@ -202,7 +202,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
/**
* @covers ::getAliasesForAdminListing
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
*/
public function testGetAliasesForAdminListing() {
$this->storage->save('/test-source-Case', '/test-alias-Case');
@ -226,7 +226,7 @@ class LegacyAliasStorageTest extends KernelTestBase {
/**
* @covers ::pathHasMatchingAlias
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path.alias_repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
* @expectedDeprecation \Drupal\Core\Path\AliasStorage is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the "path_alias.repository" service instead, or the entity storage handler for the "path_alias" entity type for CRUD methods. See https://www.drupal.org/node/3013865.
*/
public function testPathHasMatchingAlias() {
$this->storage->save('/test-source-Case', '/test-alias-Case');

View File

@ -20,7 +20,7 @@ class ContentNegotiationRoutingTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['conneg_test'];
public static $modules = ['conneg_test', 'path_alias'];
/**
* {@inheritdoc}
@ -39,8 +39,8 @@ class ContentNegotiationRoutingTest extends KernelTestBase {
// \Drupal\KernelTests\KernelTestBase::register() removes the alias path
// processor.
if ($container->hasDefinition('path_processor_alias')) {
$definition = $container->getDefinition('path_processor_alias');
if ($container->hasDefinition('path_alias.path_processor')) {
$definition = $container->getDefinition('path_alias.path_processor');
$definition->addTag('path_processor_inbound', ['priority' => 100])->addTag('path_processor_outbound', ['priority' => 300]);
}
}

View File

@ -38,7 +38,7 @@ class RouteProviderTest extends KernelTestBase {
/**
* Modules to enable.
*/
public static $modules = ['url_alter_test', 'system', 'language'];
public static $modules = ['url_alter_test', 'system', 'language', 'path_alias'];
/**
* A collection of shared fixture data for tests.
@ -100,8 +100,8 @@ class RouteProviderTest extends KernelTestBase {
parent::register($container);
// Read the incoming path alias for these tests.
if ($container->hasDefinition('path_processor_alias')) {
$definition = $container->getDefinition('path_processor_alias');
if ($container->hasDefinition('path_alias.path_processor')) {
$definition = $container->getDefinition('path_alias.path_processor');
$definition->addTag('path_processor_inbound');
}
}

View File

@ -49,7 +49,7 @@ class StableLibraryOverrideTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'user'];
public static $modules = ['system', 'user', 'path_alias'];
/**
* {@inheritdoc}
@ -72,6 +72,7 @@ class StableLibraryOverrideTest extends KernelTestBase {
$this->allModules = array_keys($all_modules);
$this->allModules[] = 'system';
$this->allModules[] = 'user';
$this->allModules[] = 'path_alias';
sort($this->allModules);
$this->container->get('module_installer')->install($this->allModules);

View File

@ -538,12 +538,12 @@ abstract class KernelTestBase extends TestCase implements ServiceProviderInterfa
->addTag('event_subscriber');
}
if ($container->hasDefinition('path_processor_alias')) {
if ($container->hasDefinition('path_alias.path_processor')) {
// The alias-based processor requires the path_alias entity schema to be
// installed, so we prevent it from being registered to the path processor
// manager. We do this by removing the tags that the compiler pass looks
// for. This means that the URL generator can safely be used within tests.
$container->getDefinition('path_processor_alias')
$container->getDefinition('path_alias.path_processor')
->clearTag('path_processor_inbound')
->clearTag('path_processor_outbound');
}

View File

@ -149,6 +149,15 @@ trait DeprecationListenerTrait {
'The "core/classList" asset library is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use the the native browser implementation instead. See https://www.drupal.org/node/3089511',
'The "core/jquery.ui.datepicker" asset library is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. See https://www.drupal.org/node/3081864',
'The "locale/drupal.locale.datepicker" asset library is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. See https://www.drupal.org/node/3081864',
// These deprecations are triggered when instantiating path alias
// services. The new versions live in the "path_alias" module.
// @todo Remove in https://www.drupal.org/node/3092090.
'The "path.alias_manager" service is deprecated. Use "path_alias.manager" instead. See https://drupal.org/node/3092086',
'The \Drupal\Core\EventSubscriber\PathSubscriber class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\EventSubscriber\PathAliasSubscriber. See https://drupal.org/node/3092086',
'The \Drupal\Core\PathProcessor\PathProcessorAlias class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\PathProcessor\AliasPathProcessor. See https://drupal.org/node/3092086',
'The \Drupal\Core\Path\AliasManager class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\AliasManager. See https://drupal.org/node/3092086',
'The \Drupal\Core\Path\AliasRepository class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\AliasRepository. See https://drupal.org/node/3092086',
'The \Drupal\Core\Path\AliasWhitelist class is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Instead, use \Drupal\path_alias\AliasWhitelist. See https://drupal.org/node/3092086',
];
}

View File

@ -22,11 +22,11 @@ trait PathAliasTestTrait {
* (optional) A language code for the path alias. Defaults to
* \Drupal\Core\Language\LanguageInterface::LANGCODE_NOT_SPECIFIED.
*
* @return \Drupal\Core\Path\PathAliasInterface
* @return \Drupal\path_alias\PathAliasInterface
* A path alias entity.
*/
protected function createPathAlias($path, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED) {
/** @var \Drupal\Core\Path\PathAliasInterface $path_alias */
/** @var \Drupal\path_alias\PathAliasInterface $path_alias */
$path_alias = \Drupal::entityTypeManager()->getStorage('path_alias')->create([
'path' => $path,
'alias' => $alias,
@ -43,7 +43,7 @@ trait PathAliasTestTrait {
* @param array $conditions
* An array of query conditions.
*
* @return \Drupal\Core\Path\PathAliasInterface|null
* @return \Drupal\path_alias\PathAliasInterface|null
* A path alias entity or NULL.
*/
protected function loadPathAliasByConditions($conditions) {