Issue #2233595 by amateescu, marcingy, SpartyDan, visabhishek, Sharique, carletex, slashrsm, hanoii, plach, Berdir, xjm: Deprecate the custom path alias storage
parent
bf51490e46
commit
bdf48170cd
|
@ -465,10 +465,10 @@ services:
|
|||
class: Drupal\Core\Path\AliasWhitelist
|
||||
tags:
|
||||
- { name: needs_destruction }
|
||||
arguments: [path_alias_whitelist, '@cache.bootstrap', '@lock', '@state', '@path.alias_storage']
|
||||
arguments: [path_alias_whitelist, '@cache.bootstrap', '@lock', '@state', '@path.alias_repository']
|
||||
path.alias_manager:
|
||||
class: Drupal\Core\Path\AliasManager
|
||||
arguments: ['@path.alias_storage', '@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,11 +960,17 @@ 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
|
||||
path.matcher:
|
||||
class: Drupal\Core\Path\PathMatcher
|
||||
arguments: ['@config.factory', '@current_route_match']
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\Core\Path;
|
|||
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\CacheDecorator\CacheDecoratorInterface;
|
||||
use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
|
||||
|
@ -12,12 +13,19 @@ use Drupal\Core\Language\LanguageManagerInterface;
|
|||
*/
|
||||
class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
|
||||
|
||||
use DeprecatedServicePropertyTrait;
|
||||
|
||||
/**
|
||||
* The alias storage service.
|
||||
*
|
||||
* @var \Drupal\Core\Path\AliasStorageInterface
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $storage;
|
||||
protected $deprecatedProperties = ['storage' => 'path.alias_storage'];
|
||||
|
||||
/**
|
||||
* The path alias repository.
|
||||
*
|
||||
* @var \Drupal\Core\Path\AliasRepositoryInterface
|
||||
*/
|
||||
protected $pathAliasRepository;
|
||||
|
||||
/**
|
||||
* Cache backend service.
|
||||
|
@ -95,8 +103,8 @@ class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
|
|||
/**
|
||||
* Constructs an AliasManager.
|
||||
*
|
||||
* @param \Drupal\Core\Path\AliasStorageInterface $storage
|
||||
* The alias storage service.
|
||||
* @param \Drupal\Core\Path\AliasRepositoryInterface $alias_repository
|
||||
* The path alias repository.
|
||||
* @param \Drupal\Core\Path\AliasWhitelistInterface $whitelist
|
||||
* The whitelist implementation to use.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
|
@ -104,8 +112,12 @@ class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
|
|||
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
|
||||
* Cache backend.
|
||||
*/
|
||||
public function __construct(AliasStorageInterface $storage, AliasWhitelistInterface $whitelist, LanguageManagerInterface $language_manager, CacheBackendInterface $cache) {
|
||||
$this->storage = $storage;
|
||||
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');
|
||||
}
|
||||
$this->pathAliasRepository = $alias_repository;
|
||||
$this->languageManager = $language_manager;
|
||||
$this->whitelist = $whitelist;
|
||||
$this->cache = $cache;
|
||||
|
@ -166,9 +178,9 @@ class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
|
|||
}
|
||||
|
||||
// Look for path in storage.
|
||||
if ($path = $this->storage->lookupPathSource($alias, $langcode)) {
|
||||
$this->lookupMap[$langcode][$path] = $alias;
|
||||
return $path;
|
||||
if ($path_alias = $this->pathAliasRepository->lookupByAlias($alias, $langcode)) {
|
||||
$this->lookupMap[$langcode][$path_alias['path']] = $alias;
|
||||
return $path_alias['path'];
|
||||
}
|
||||
|
||||
// We can't record anything into $this->lookupMap because we didn't find any
|
||||
|
@ -220,7 +232,7 @@ class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
|
|||
|
||||
// Load paths from cache.
|
||||
if (!empty($this->preloadedPathLookups[$langcode])) {
|
||||
$this->lookupMap[$langcode] = $this->storage->preloadPathAlias($this->preloadedPathLookups[$langcode], $langcode);
|
||||
$this->lookupMap[$langcode] = $this->pathAliasRepository->preloadPathAlias($this->preloadedPathLookups[$langcode], $langcode);
|
||||
// Keep a record of paths with no alias to avoid querying twice.
|
||||
$this->noAlias[$langcode] = array_flip(array_diff_key($this->preloadedPathLookups[$langcode], array_keys($this->lookupMap[$langcode])));
|
||||
}
|
||||
|
@ -237,9 +249,9 @@ class AliasManager implements AliasManagerInterface, CacheDecoratorInterface {
|
|||
}
|
||||
|
||||
// Try to load alias from storage.
|
||||
if ($alias = $this->storage->lookupPathAlias($path, $langcode)) {
|
||||
$this->lookupMap[$langcode][$path] = $alias;
|
||||
return $alias;
|
||||
if ($path_alias = $this->pathAliasRepository->lookupBySystemPath($path, $langcode)) {
|
||||
$this->lookupMap[$langcode][$path] = $path_alias['alias'];
|
||||
return $path_alias['alias'];
|
||||
}
|
||||
|
||||
// We can't record anything into $this->lookupMap because we didn't find any
|
||||
|
|
|
@ -4,8 +4,6 @@ namespace Drupal\Core\Path;
|
|||
|
||||
/**
|
||||
* Find an alias for a path and vice versa.
|
||||
*
|
||||
* @see \Drupal\Core\Path\AliasStorageInterface
|
||||
*/
|
||||
interface AliasManagerInterface {
|
||||
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Path;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
|
||||
/**
|
||||
* Provides the default path alias lookup operations.
|
||||
*/
|
||||
class AliasRepository implements AliasRepositoryInterface {
|
||||
|
||||
/**
|
||||
* The database connection.
|
||||
*
|
||||
* @var \Drupal\Core\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* Constructs an AliasRepository object.
|
||||
*
|
||||
* @param \Drupal\Core\Database\Connection $connection
|
||||
* A database connection for reading and writing path aliases.
|
||||
*/
|
||||
public function __construct(Connection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preloadPathAlias($preloaded, $langcode) {
|
||||
$select = $this->getBaseQuery()
|
||||
->fields('base_table', ['path', 'alias']);
|
||||
|
||||
if (!empty($preloaded)) {
|
||||
$conditions = new Condition('OR');
|
||||
foreach ($preloaded as $preloaded_item) {
|
||||
$conditions->condition('base_table.path', $this->connection->escapeLike($preloaded_item), 'LIKE');
|
||||
}
|
||||
$select->condition($conditions);
|
||||
}
|
||||
|
||||
$this->addLanguageFallback($select, $langcode);
|
||||
|
||||
// We order by ID ASC so that fetchAllKeyed() returns the most recently
|
||||
// created alias for each source. Subsequent queries using fetchField() must
|
||||
// use ID DESC to have the same effect.
|
||||
$select->orderBy('base_table.id', 'ASC');
|
||||
|
||||
return $select->execute()->fetchAllKeyed();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function lookupBySystemPath($path, $langcode) {
|
||||
// See the queries above. Use LIKE for case-insensitive matching.
|
||||
$select = $this->getBaseQuery()
|
||||
->fields('base_table', ['id', 'path', 'alias', 'langcode'])
|
||||
->condition('base_table.path', $this->connection->escapeLike($path), 'LIKE');
|
||||
|
||||
$this->addLanguageFallback($select, $langcode);
|
||||
|
||||
$select->orderBy('base_table.id', 'DESC');
|
||||
|
||||
return $select->execute()->fetchAssoc() ?: NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function lookupByAlias($alias, $langcode) {
|
||||
// See the queries above. Use LIKE for case-insensitive matching.
|
||||
$select = $this->getBaseQuery()
|
||||
->fields('base_table', ['id', 'path', 'alias', 'langcode'])
|
||||
->condition('base_table.alias', $this->connection->escapeLike($alias), 'LIKE');
|
||||
|
||||
$this->addLanguageFallback($select, $langcode);
|
||||
|
||||
$select->orderBy('base_table.id', 'DESC');
|
||||
|
||||
return $select->execute()->fetchAssoc() ?: NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function pathHasMatchingAlias($initial_substring) {
|
||||
$query = $this->getBaseQuery();
|
||||
$query->addExpression(1);
|
||||
|
||||
return (bool) $query
|
||||
->condition('base_table.path', $this->connection->escapeLike($initial_substring) . '%', 'LIKE')
|
||||
->range(0, 1)
|
||||
->execute()
|
||||
->fetchField();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a SELECT query for the path_alias base table.
|
||||
*
|
||||
* @return \Drupal\Core\Database\Query\SelectInterface
|
||||
* A Select query object.
|
||||
*/
|
||||
protected function getBaseQuery() {
|
||||
$query = $this->connection->select('path_alias', 'base_table');
|
||||
$query->condition('base_table.status', 1);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds path alias language fallback conditions to a select query object.
|
||||
*
|
||||
* @param \Drupal\Core\Database\Query\SelectInterface $query
|
||||
* A Select query object.
|
||||
* @param string $langcode
|
||||
* Language code to search the path with. If there's no path defined for
|
||||
* that language it will search paths without language.
|
||||
*/
|
||||
protected function addLanguageFallback(SelectInterface $query, $langcode) {
|
||||
// Always get the language-specific alias before the language-neutral one.
|
||||
// For example 'de' is less than 'und' so the order needs to be ASC, while
|
||||
// 'xx-lolspeak' is more than 'und' so the order needs to be DESC.
|
||||
$langcode_list = [$langcode, LanguageInterface::LANGCODE_NOT_SPECIFIED];
|
||||
if ($langcode === LanguageInterface::LANGCODE_NOT_SPECIFIED) {
|
||||
array_pop($langcode_list);
|
||||
}
|
||||
elseif ($langcode > LanguageInterface::LANGCODE_NOT_SPECIFIED) {
|
||||
$query->orderBy('base_table.langcode', 'DESC');
|
||||
}
|
||||
else {
|
||||
$query->orderBy('base_table.langcode', 'ASC');
|
||||
}
|
||||
$query->condition('base_table.langcode', $langcode_list, 'IN');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
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.
|
||||
*
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Pre-loads path alias information for a given list of system paths.
|
||||
*
|
||||
* @param array $preloaded
|
||||
* System paths that need preloading of aliases.
|
||||
* @param string $langcode
|
||||
* Language code to search the path with. If there's no path defined for
|
||||
* that language it will search paths without language.
|
||||
*
|
||||
* @return string[]
|
||||
* System paths (keys) to alias (values) mapping.
|
||||
*/
|
||||
public function preloadPathAlias($preloaded, $langcode);
|
||||
|
||||
/**
|
||||
* Searches a path alias for a given Drupal system path.
|
||||
*
|
||||
* The default implementation performs case-insensitive matching on the
|
||||
* 'path' and 'alias' strings.
|
||||
*
|
||||
* @param string $path
|
||||
* The system path to investigate for corresponding path aliases.
|
||||
* @param string $langcode
|
||||
* Language code to search the path with. If there's no path defined for
|
||||
* that language it will search paths without language.
|
||||
*
|
||||
* @return array|null
|
||||
* An array containing the 'id', 'path', 'alias' and 'langcode' properties
|
||||
* of a path alias, or NULL if none was found.
|
||||
*/
|
||||
public function lookupBySystemPath($path, $langcode);
|
||||
|
||||
/**
|
||||
* Searches a path alias for a given alias.
|
||||
*
|
||||
* The default implementation performs case-insensitive matching on the
|
||||
* 'path' and 'alias' strings.
|
||||
*
|
||||
* @param string $alias
|
||||
* The alias to investigate for corresponding system paths.
|
||||
* @param string $langcode
|
||||
* Language code to search the alias with. If there's no alias defined for
|
||||
* that language it will search aliases without language.
|
||||
*
|
||||
* @return array|null
|
||||
* An array containing the 'id', 'path', 'alias' and 'langcode' properties
|
||||
* of a path alias, or NULL if none was found.
|
||||
*/
|
||||
public function lookupByAlias($alias, $langcode);
|
||||
|
||||
/**
|
||||
* Check if any alias exists starting with $initial_substring.
|
||||
*
|
||||
* @param string $initial_substring
|
||||
* Initial system path substring to test against.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if any alias exists, FALSE otherwise.
|
||||
*/
|
||||
public function pathHasMatchingAlias($initial_substring);
|
||||
|
||||
}
|
|
@ -9,12 +9,21 @@ 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);
|
||||
|
||||
/**
|
||||
* Provides a class for CRUD operations on path aliases.
|
||||
*
|
||||
* All queries perform case-insensitive matching on the 'source' and 'alias'
|
||||
* fields, so the aliases '/test-alias' and '/test-Alias' are considered to be
|
||||
* 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
|
||||
* instead, or the entity storage handler for the "path_alias" entity type
|
||||
* for CRUD methods.
|
||||
*
|
||||
* @see https://www.drupal.org/node/3013865
|
||||
*/
|
||||
class AliasStorage implements AliasStorageInterface {
|
||||
|
||||
|
|
|
@ -6,6 +6,13 @@ 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
|
||||
* instead, or the entity storage handler for the "path_alias" entity type
|
||||
* for CRUD methods.
|
||||
*
|
||||
* @see https://www.drupal.org/node/3013865
|
||||
*/
|
||||
interface AliasStorageInterface {
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\Core\Path;
|
|||
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Cache\CacheCollector;
|
||||
use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
|
||||
use Drupal\Core\State\StateInterface;
|
||||
use Drupal\Core\Lock\LockBackendInterface;
|
||||
|
||||
|
@ -12,6 +13,13 @@ use Drupal\Core\Lock\LockBackendInterface;
|
|||
*/
|
||||
class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface {
|
||||
|
||||
use DeprecatedServicePropertyTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $deprecatedProperties = ['aliasStorage' => 'path.alias_storage'];
|
||||
|
||||
/**
|
||||
* The Key/Value Store to use for state.
|
||||
*
|
||||
|
@ -20,11 +28,11 @@ class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface {
|
|||
protected $state;
|
||||
|
||||
/**
|
||||
* The Path CRUD service.
|
||||
* The path alias repository.
|
||||
*
|
||||
* @var \Drupal\Core\Path\AliasStorageInterface
|
||||
* @var \Drupal\Core\Path\AliasRepositoryInterface
|
||||
*/
|
||||
protected $aliasStorage;
|
||||
protected $pathAliasRepository;
|
||||
|
||||
/**
|
||||
* Constructs an AliasWhitelist object.
|
||||
|
@ -37,13 +45,18 @@ class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface {
|
|||
* The lock backend.
|
||||
* @param \Drupal\Core\State\StateInterface $state
|
||||
* The state keyvalue store.
|
||||
* @param \Drupal\Core\Path\AliasStorageInterface $alias_storage
|
||||
* The alias storage service.
|
||||
* @param \Drupal\Core\Path\AliasRepositoryInterface $alias_repository
|
||||
* The path alias repository.
|
||||
*/
|
||||
public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, StateInterface $state, AliasStorageInterface $alias_storage) {
|
||||
public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, StateInterface $state, $alias_repository) {
|
||||
parent::__construct($cid, $cache, $lock);
|
||||
$this->state = $state;
|
||||
$this->aliasStorage = $alias_storage;
|
||||
|
||||
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');
|
||||
}
|
||||
$this->pathAliasRepository = $alias_repository;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,7 +114,7 @@ class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolveCacheMiss($root) {
|
||||
$exists = $this->aliasStorage->pathHasMatchingAlias('/' . $root);
|
||||
$exists = $this->pathAliasRepository->pathHasMatchingAlias('/' . $root);
|
||||
$this->storage[$root] = $exists;
|
||||
$this->persist($root);
|
||||
if ($exists) {
|
||||
|
|
|
@ -13,6 +13,7 @@ use Drupal\link\LinkItemInterface;
|
|||
use Drupal\node\NodeInterface;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Tests link field widgets and formatters.
|
||||
|
@ -21,6 +22,8 @@ use Drupal\field\Entity\FieldStorageConfig;
|
|||
*/
|
||||
class LinkFieldTest extends BrowserTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
|
@ -100,7 +103,7 @@ class LinkFieldTest extends BrowserTestBase {
|
|||
$this->assertRaw('placeholder="http://example.com"');
|
||||
|
||||
// Create a path alias.
|
||||
\Drupal::service('path.alias_storage')->save('/admin', '/a/path/alias');
|
||||
$this->createPathAlias('/admin', '/a/path/alias');
|
||||
|
||||
// Create a node to test the link widget.
|
||||
$node = $this->drupalCreateNode();
|
||||
|
|
|
@ -5,14 +5,18 @@ namespace Drupal\Tests\locale\Functional;
|
|||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Tests you can configure a language for individual URL aliases.
|
||||
*
|
||||
* @group locale
|
||||
* @group path
|
||||
*/
|
||||
class LocalePathTest extends BrowserTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
|
@ -96,44 +100,24 @@ class LocalePathTest extends BrowserTestBase {
|
|||
$custom_path = $this->randomMachineName(8);
|
||||
|
||||
// Check priority of language for alias by source path.
|
||||
$edit = [
|
||||
'path[0][value]' => '/node/' . $node->id(),
|
||||
'alias[0][value]' => '/' . $custom_path,
|
||||
'langcode[0][value]' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
];
|
||||
$this->container->get('path.alias_storage')->save($edit['path[0][value]'], $edit['alias[0][value]'], $edit['langcode[0][value]']);
|
||||
$path_alias = $this->createPathAlias('/node/' . $node->id(), '/' . $custom_path, LanguageInterface::LANGCODE_NOT_SPECIFIED);
|
||||
$lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $node->id(), 'en');
|
||||
$this->assertEqual('/' . $english_path, $lookup_path, 'English language alias has priority.');
|
||||
// Same check for language 'xx'.
|
||||
$lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $node->id(), $prefix);
|
||||
$this->assertEqual('/' . $custom_language_path, $lookup_path, 'Custom language alias has priority.');
|
||||
$path_alias = [
|
||||
'path' => $edit['path[0][value]'],
|
||||
'alias' => $edit['alias[0][value]'],
|
||||
'langcode' => $edit['langcode[0][value]'],
|
||||
];
|
||||
$this->container->get('path.alias_storage')->delete($path_alias);
|
||||
$path_alias->delete();
|
||||
|
||||
// Create language nodes to check priority of aliases.
|
||||
$first_node = $this->drupalCreateNode(['type' => 'page', 'promote' => 1, 'langcode' => 'en']);
|
||||
$second_node = $this->drupalCreateNode(['type' => 'page', 'promote' => 1, 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED]);
|
||||
|
||||
// Assign a custom path alias to the first node with the English language.
|
||||
$edit = [
|
||||
'path[0][value]' => '/node/' . $first_node->id(),
|
||||
'alias[0][value]' => '/' . $custom_path,
|
||||
'langcode[0][value]' => $first_node->language()->getId(),
|
||||
];
|
||||
$this->container->get('path.alias_storage')->save($edit['path[0][value]'], $edit['alias[0][value]'], $edit['langcode[0][value]']);
|
||||
$this->createPathAlias('/node/' . $first_node->id(), '/' . $custom_path, $first_node->language()->getId());
|
||||
|
||||
// Assign a custom path alias to second node with
|
||||
// LanguageInterface::LANGCODE_NOT_SPECIFIED.
|
||||
$edit = [
|
||||
'path[0][value]' => '/node/' . $second_node->id(),
|
||||
'alias[0][value]' => '/' . $custom_path,
|
||||
'langcode[0][value]' => $second_node->language()->getId(),
|
||||
];
|
||||
$this->container->get('path.alias_storage')->save($edit['path[0][value]'], $edit['alias[0][value]'], $edit['langcode[0][value]']);
|
||||
$this->createPathAlias('/node/' . $second_node->id(), '/' . $custom_path, $second_node->language()->getId());
|
||||
|
||||
// Test that both node titles link to our path alias.
|
||||
$this->drupalGet('admin/content');
|
||||
|
|
|
@ -3,18 +3,21 @@
|
|||
namespace Drupal\Tests\menu_link_content\Kernel;
|
||||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Menu\MenuTreeParameters;
|
||||
use Drupal\menu_link_content\Entity\MenuLinkContent;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Ensures that the menu tree adapts to path alias changes.
|
||||
*
|
||||
* @group menu_link_content
|
||||
* @group path
|
||||
*/
|
||||
class PathAliasMenuLinkContentTest extends KernelTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -52,11 +55,7 @@ class PathAliasMenuLinkContentTest extends KernelTestBase {
|
|||
public function testPathAliasChange() {
|
||||
\Drupal::service('router.builder')->rebuild();
|
||||
|
||||
/** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
|
||||
$path_alias_storage = \Drupal::service('path.alias_storage');
|
||||
$alias = $path_alias_storage->save('/test-page', '/my-blog');
|
||||
$pid = $alias['pid'];
|
||||
|
||||
$path_alias = $this->createPathAlias('/test-page', '/my-blog');
|
||||
$menu_link_content = MenuLinkContent::create([
|
||||
'title' => 'Menu title',
|
||||
'link' => ['uri' => 'internal:/my-blog'],
|
||||
|
@ -68,13 +67,15 @@ class PathAliasMenuLinkContentTest extends KernelTestBase {
|
|||
$this->assertEqual('test_page_test.test_page', $tree[$menu_link_content->getPluginId()]->link->getPluginDefinition()['route_name']);
|
||||
|
||||
// Saving an alias should clear the alias manager cache.
|
||||
$path_alias_storage->save('/test-render-title', '/my-blog', LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid);
|
||||
$path_alias->setPath('/test-render-title');
|
||||
$path_alias->setAlias('/my-blog');
|
||||
$path_alias->save();
|
||||
|
||||
$tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters());
|
||||
$this->assertEqual('test_page_test.render_title', $tree[$menu_link_content->getPluginId()]->link->getPluginDefinition()['route_name']);
|
||||
|
||||
// Delete the alias.
|
||||
$path_alias_storage->delete(['pid' => $pid]);
|
||||
$path_alias->delete();
|
||||
$tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters());
|
||||
$this->assertTrue(isset($tree[$menu_link_content->getPluginId()]));
|
||||
$this->assertEqual('', $tree[$menu_link_content->getPluginId()]->link->getRouteName());
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace Drupal\path\Plugin\Field\FieldType;
|
|||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Field\FieldItemList;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\TypedData\ComputedItemListTrait;
|
||||
|
||||
|
@ -27,21 +26,15 @@ class PathFieldItemList extends FieldItemList {
|
|||
|
||||
$entity = $this->getEntity();
|
||||
if (!$entity->isNew()) {
|
||||
$conditions = [
|
||||
'source' => '/' . $entity->toUrl()->getInternalPath(),
|
||||
'langcode' => $this->getLangcode(),
|
||||
];
|
||||
$alias = \Drupal::service('path.alias_storage')->load($conditions);
|
||||
if ($alias === FALSE) {
|
||||
// Fall back to non-specific language.
|
||||
if ($this->getLangcode() !== LanguageInterface::LANGCODE_NOT_SPECIFIED) {
|
||||
$conditions['langcode'] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
|
||||
$alias = \Drupal::service('path.alias_storage')->load($conditions);
|
||||
}
|
||||
}
|
||||
/** @var \Drupal\Core\Path\AliasRepositoryInterface $path_alias_repository */
|
||||
$path_alias_repository = \Drupal::service('path.alias_repository');
|
||||
|
||||
if ($alias) {
|
||||
$value = $alias;
|
||||
if ($path_alias = $path_alias_repository->lookupBySystemPath('/' . $entity->toUrl()->getInternalPath(), $this->getLangcode())) {
|
||||
$value = [
|
||||
'alias' => $path_alias['alias'],
|
||||
'pid' => $path_alias['id'],
|
||||
'langcode' => $path_alias['langcode'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,11 +57,12 @@ class PathFieldItemList extends FieldItemList {
|
|||
public function delete() {
|
||||
// Delete all aliases associated with this entity in the current language.
|
||||
$entity = $this->getEntity();
|
||||
$conditions = [
|
||||
'source' => '/' . $entity->toUrl()->getInternalPath(),
|
||||
$path_alias_storage = \Drupal::entityTypeManager()->getStorage('path_alias');
|
||||
$entities = $path_alias_storage->loadByProperties([
|
||||
'path' => '/' . $entity->toUrl()->getInternalPath(),
|
||||
'langcode' => $entity->language()->getId(),
|
||||
];
|
||||
\Drupal::service('path.alias_storage')->delete($conditions);
|
||||
]);
|
||||
$path_alias_storage->delete($entities);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -87,15 +87,22 @@ class PathWidget extends WidgetBase {
|
|||
if (!empty($alias)) {
|
||||
$form_state->setValueForElement($element['alias'], $alias);
|
||||
|
||||
// Validate that the submitted alias does not exist yet.
|
||||
$is_exists = \Drupal::service('path.alias_storage')->aliasExists($alias, $element['langcode']['#value'], $element['source']['#value']);
|
||||
if ($is_exists) {
|
||||
$form_state->setError($element['alias'], t('The alias is already in use.'));
|
||||
}
|
||||
}
|
||||
/** @var \Drupal\Core\Path\PathAliasInterface $path_alias */
|
||||
$path_alias = \Drupal::entityTypeManager()->getStorage('path_alias')->create([
|
||||
'path' => $element['source']['#value'],
|
||||
'alias' => $alias,
|
||||
'langcode' => $element['langcode']['#value'],
|
||||
]);
|
||||
$violations = $path_alias->validate();
|
||||
|
||||
if ($alias && $alias[0] !== '/') {
|
||||
$form_state->setError($element['alias'], t('The alias needs to start with a slash.'));
|
||||
foreach ($violations as $violation) {
|
||||
// Newly created entities do not have a system path yet, so we need to
|
||||
// disregard some violations.
|
||||
if (!$path_alias->getPath() && $violation->getPropertyPath() === 'path') {
|
||||
continue;
|
||||
}
|
||||
$form_state->setError($element['alias'], $violation->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ abstract class UrlAliasBase extends DrupalSqlBase {
|
|||
*/
|
||||
public function query() {
|
||||
// The order of the migration is significant since
|
||||
// \Drupal\Core\Path\AliasStorage::lookupPathAlias() orders by pid before
|
||||
// \Drupal\Core\Path\AliasRepository::lookupPathAlias() orders by pid before
|
||||
// returning a result. Postgres does not automatically order by primary key
|
||||
// therefore we need to add a specific order by.
|
||||
return $this->select('url_alias', 'ua')->fields('ua')->orderBy('pid');
|
||||
|
|
|
@ -283,7 +283,7 @@ class PathAliasTest extends PathTestBase {
|
|||
$this->drupalPostForm('node/' . $node2->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
// Confirm that the alias didn't make a duplicate.
|
||||
$this->assertText(t('The alias is already in use.'), 'Attempt to moved alias was rejected.');
|
||||
$this->assertSession()->pageTextContains("The alias {$edit['path[0][alias]']} is already in use in this language.");
|
||||
|
||||
// Delete alias.
|
||||
$this->drupalPostForm('node/' . $node1->id() . '/edit', ['path[0][alias]' => ''], t('Save'));
|
||||
|
@ -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_storage')->lookupPathAlias('/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.
|
||||
|
@ -388,7 +388,7 @@ class PathAliasTest extends PathTestBase {
|
|||
// Now create another node and try to set the same alias.
|
||||
$node_two = $this->drupalCreateNode();
|
||||
$this->drupalPostForm('node/' . $node_two->id() . '/edit', $edit, t('Save'));
|
||||
$this->assertText(t('The alias is already in use.'));
|
||||
$this->assertSession()->pageTextContains("The alias {$edit['path[0][alias]']} is already in use in this language.");
|
||||
$this->assertFieldByXPath("//input[@name='path[0][alias]' and contains(@class, 'error')]", $edit['path[0][alias]'], 'Textfield exists and has the error class.');
|
||||
|
||||
// Behavior here differs with the inline_form_errors module enabled.
|
||||
|
@ -399,7 +399,7 @@ class PathAliasTest extends PathTestBase {
|
|||
// Attempt to edit the second node again, as before.
|
||||
$this->drupalPostForm('node/' . $node_two->id() . '/edit', $edit, t('Preview'));
|
||||
// This error should still be present next to the field.
|
||||
$this->assertSession()->pageTextContains(t('The alias is already in use.'), 'Field error found with expected text.');
|
||||
$this->assertSession()->pageTextContains("The alias {$edit['path[0][alias]']} is already in use in this language.");
|
||||
// The validation error set for the page should include this text.
|
||||
$this->assertSession()->pageTextContains(t('1 error has been found: URL alias'), 'Form error found with expected text.');
|
||||
// The text 'URL alias' should be a link.
|
||||
|
|
|
@ -184,11 +184,11 @@ class PathLanguageTest extends PathTestBase {
|
|||
// Confirm that the alias is removed if the translation is deleted.
|
||||
$english_node->removeTranslation('fr');
|
||||
$english_node->save();
|
||||
$this->assertFalse($this->container->get('path.alias_storage')->aliasExists('/' . $french_alias, 'fr'), 'Alias for French translation is removed when translation is deleted.');
|
||||
$this->assertPathAliasNotExists('/' . $french_alias, 'fr', NULL, 'Alias for French translation is removed when translation is deleted.');
|
||||
|
||||
// Check that the English alias still works.
|
||||
$this->drupalGet($english_alias);
|
||||
$this->assertTrue($this->container->get('path.alias_storage')->aliasExists('/' . $english_alias, 'en'), 'English alias is not deleted when French translation is removed.');
|
||||
$this->assertPathAliasExists('/' . $english_alias, 'en', NULL, 'English alias is not deleted when French translation is removed.');
|
||||
$this->assertText($english_node->body->value, 'English alias still works');
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
namespace Drupal\Tests\path\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Provides a base class for testing the Path module.
|
||||
*/
|
||||
abstract class PathTestBase extends BrowserTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
namespace Drupal\Tests\path\Kernel\Migrate\d6;
|
||||
|
||||
use Drupal\Core\Path\PathAliasInterface;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* URL alias migration.
|
||||
|
@ -13,6 +15,8 @@ use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
|
|||
*/
|
||||
class MigrateUrlAliasTest extends MigrateDrupal6TestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -47,20 +51,20 @@ class MigrateUrlAliasTest extends MigrateDrupal6TestBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Assert a path.
|
||||
* Asserts that a path alias matches a set of conditions.
|
||||
*
|
||||
* @param string $pid
|
||||
* The path id.
|
||||
* @param int $pid
|
||||
* The path alias ID.
|
||||
* @param array $conditions
|
||||
* The path conditions.
|
||||
* @param array $path
|
||||
* The path.
|
||||
* @param \Drupal\Core\Path\PathAliasInterface $path_alias
|
||||
* The path alias.
|
||||
*/
|
||||
private function assertPath($pid, $conditions, $path) {
|
||||
$this->assertTrue($path, "Path alias for " . $conditions['source'] . " successfully loaded.");
|
||||
$this->assertIdentical($conditions['alias'], $path['alias']);
|
||||
$this->assertIdentical($conditions['langcode'], $path['langcode']);
|
||||
$this->assertIdentical($conditions['source'], $path['source']);
|
||||
private function assertPath($pid, $conditions, PathAliasInterface $path_alias) {
|
||||
$this->assertSame($pid, (int) $path_alias->id());
|
||||
$this->assertSame($conditions['alias'], $path_alias->getAlias());
|
||||
$this->assertSame($conditions['langcode'], $path_alias->get('langcode')->value);
|
||||
$this->assertSame($conditions['path'], $path_alias->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,21 +74,21 @@ class MigrateUrlAliasTest extends MigrateDrupal6TestBase {
|
|||
$id_map = $this->getMigration('d6_url_alias')->getIdMap();
|
||||
// Test that the field exists.
|
||||
$conditions = [
|
||||
'source' => '/node/1',
|
||||
'path' => '/node/1',
|
||||
'alias' => '/alias-one',
|
||||
'langcode' => 'af',
|
||||
];
|
||||
$path = \Drupal::service('path.alias_storage')->load($conditions);
|
||||
$this->assertPath('1', $conditions, $path);
|
||||
$this->assertIdentical($id_map->lookupDestinationIds([$path['pid']]), [['1']], "Test IdMap");
|
||||
$path_alias = $this->loadPathAliasByConditions($conditions);
|
||||
$this->assertPath(1, $conditions, $path_alias);
|
||||
$this->assertSame([['1']], $id_map->lookupDestinationIds([$path_alias->id()]), "Test IdMap");
|
||||
|
||||
$conditions = [
|
||||
'source' => '/node/2',
|
||||
'path' => '/node/2',
|
||||
'alias' => '/alias-two',
|
||||
'langcode' => 'en',
|
||||
];
|
||||
$path = \Drupal::service('path.alias_storage')->load($conditions);
|
||||
$this->assertPath('2', $conditions, $path);
|
||||
$path_alias = $this->loadPathAliasByConditions($conditions);
|
||||
$this->assertPath(2, $conditions, $path_alias);
|
||||
|
||||
// Test that we can re-import using the UrlAlias destination.
|
||||
Database::getConnection('default', 'migrate')
|
||||
|
@ -100,54 +104,53 @@ class MigrateUrlAliasTest extends MigrateDrupal6TestBase {
|
|||
$migration = $this->getMigration('d6_url_alias');
|
||||
$this->executeMigration($migration);
|
||||
|
||||
$path = \Drupal::service('path.alias_storage')->load(['pid' => $path['pid']]);
|
||||
$path_alias = $this->loadPathAliasByConditions(['id' => $path_alias->id()]);
|
||||
$conditions['alias'] = '/new-url-alias';
|
||||
$this->assertPath('2', $conditions, $path);
|
||||
$this->assertPath(2, $conditions, $path_alias);
|
||||
|
||||
$conditions = [
|
||||
'source' => '/node/3',
|
||||
'path' => '/node/3',
|
||||
'alias' => '/alias-three',
|
||||
'langcode' => 'und',
|
||||
];
|
||||
$path = \Drupal::service('path.alias_storage')->load($conditions);
|
||||
$this->assertPath('3', $conditions, $path);
|
||||
$path_alias = $this->loadPathAliasByConditions($conditions);
|
||||
$this->assertPath(3, $conditions, $path_alias);
|
||||
|
||||
$path = \Drupal::service('path.alias_storage')->load(['alias' => '/source-noslash']);
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/source-noslash']);
|
||||
$conditions = [
|
||||
'source' => '/admin',
|
||||
'path' => '/admin',
|
||||
'alias' => '/source-noslash',
|
||||
'langcode' => 'und',
|
||||
];
|
||||
$this->assertPath('2', $conditions, $path);
|
||||
$this->assertPath(8, $conditions, $path_alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the URL alias migration with translated nodes.
|
||||
*/
|
||||
public function testUrlAliasWithTranslatedNodes() {
|
||||
$alias_storage = $this->container->get('path.alias_storage');
|
||||
|
||||
// Alias for the 'The Real McCoy' node in English.
|
||||
$path = $alias_storage->load(['alias' => '/the-real-mccoy']);
|
||||
$this->assertSame('/node/10', $path['source']);
|
||||
$this->assertSame('en', $path['langcode']);
|
||||
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/the-real-mccoy']);
|
||||
$this->assertSame('/node/10', $path_alias->getPath());
|
||||
$this->assertSame('en', $path_alias->get('langcode')->value);
|
||||
|
||||
// Alias for the 'The Real McCoy' French translation,
|
||||
// which should now point to node/10 instead of node/11.
|
||||
$path = $alias_storage->load(['alias' => '/le-vrai-mccoy']);
|
||||
$this->assertSame('/node/10', $path['source']);
|
||||
$this->assertSame('fr', $path['langcode']);
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/le-vrai-mccoy']);
|
||||
$this->assertSame('/node/10', $path_alias->getPath());
|
||||
$this->assertSame('fr', $path_alias->get('langcode')->value);
|
||||
|
||||
// Alias for the 'Abantu zulu' node in Zulu.
|
||||
$path = $alias_storage->load(['alias' => '/abantu-zulu']);
|
||||
$this->assertSame('/node/12', $path['source']);
|
||||
$this->assertSame('zu', $path['langcode']);
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/abantu-zulu']);
|
||||
$this->assertSame('/node/12', $path_alias->getPath());
|
||||
$this->assertSame('zu', $path_alias->get('langcode')->value);
|
||||
|
||||
// Alias for the 'Abantu zulu' English translation,
|
||||
// which should now point to node/12 instead of node/13.
|
||||
$path = $alias_storage->load(['alias' => '/the-zulu-people']);
|
||||
$this->assertSame('/node/12', $path['source']);
|
||||
$this->assertSame('en', $path['langcode']);
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/the-zulu-people']);
|
||||
$this->assertSame('/node/12', $path_alias->getPath());
|
||||
$this->assertSame('en', $path_alias->get('langcode')->value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,29 +32,27 @@ class MigrateUrlAliasTest extends MigrateUrlAliasTestBase {
|
|||
* Test the URL alias migration with translated nodes.
|
||||
*/
|
||||
public function testUrlAliasWithTranslatedNodes() {
|
||||
$alias_storage = $this->container->get('path.alias_storage');
|
||||
|
||||
// Alias for the 'The thing about Deep Space 9' node in English.
|
||||
$path = $alias_storage->load(['alias' => '/deep-space-9']);
|
||||
$this->assertSame('/node/2', $path['source']);
|
||||
$this->assertSame('en', $path['langcode']);
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/deep-space-9']);
|
||||
$this->assertSame('/node/2', $path_alias->getPath());
|
||||
$this->assertSame('en', $path_alias->get('langcode')->value);
|
||||
|
||||
// Alias for the 'The thing about Deep Space 9' Icelandic translation,
|
||||
// which should now point to node/2 instead of node/3.
|
||||
$path = $alias_storage->load(['alias' => '/deep-space-9-is']);
|
||||
$this->assertSame('/node/2', $path['source']);
|
||||
$this->assertSame('is', $path['langcode']);
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/deep-space-9-is']);
|
||||
$this->assertSame('/node/2', $path_alias->getPath());
|
||||
$this->assertSame('is', $path_alias->get('langcode')->value);
|
||||
|
||||
// Alias for the 'The thing about Firefly' node in Icelandic.
|
||||
$path = $alias_storage->load(['alias' => '/firefly-is']);
|
||||
$this->assertSame('/node/4', $path['source']);
|
||||
$this->assertSame('is', $path['langcode']);
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/firefly-is']);
|
||||
$this->assertSame('/node/4', $path_alias->getPath());
|
||||
$this->assertSame('is', $path_alias->get('langcode')->value);
|
||||
|
||||
// Alias for the 'The thing about Firefly' English translation,
|
||||
// which should now point to node/4 instead of node/5.
|
||||
$path = $alias_storage->load(['alias' => '/firefly']);
|
||||
$this->assertSame('/node/4', $path['source']);
|
||||
$this->assertSame('en', $path['langcode']);
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/firefly']);
|
||||
$this->assertSame('/node/4', $path_alias->getPath());
|
||||
$this->assertSame('en', $path_alias->get('langcode')->value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\Tests\path\Kernel\Migrate\d7;
|
||||
|
||||
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Tests URL alias migration.
|
||||
|
@ -11,6 +12,8 @@ use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
|
|||
*/
|
||||
abstract class MigrateUrlAliasTestBase extends MigrateDrupal7TestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -45,21 +48,19 @@ abstract class MigrateUrlAliasTestBase extends MigrateDrupal7TestBase {
|
|||
* Test the URL alias migration.
|
||||
*/
|
||||
public function testUrlAlias() {
|
||||
$alias_storage = $this->container->get('path.alias_storage');
|
||||
|
||||
$path = $alias_storage->load([
|
||||
'source' => '/taxonomy/term/4',
|
||||
$path_alias = $this->loadPathAliasByConditions([
|
||||
'path' => '/taxonomy/term/4',
|
||||
'alias' => '/term33',
|
||||
'langcode' => 'und',
|
||||
]);
|
||||
$this->assertIdentical('/taxonomy/term/4', $path['source']);
|
||||
$this->assertIdentical('/term33', $path['alias']);
|
||||
$this->assertIdentical('und', $path['langcode']);
|
||||
$this->assertIdentical('/taxonomy/term/4', $path_alias->getPath());
|
||||
$this->assertIdentical('/term33', $path_alias->getAlias());
|
||||
$this->assertIdentical('und', $path_alias->language()->getId());
|
||||
|
||||
// Alias with no slash.
|
||||
$path = $alias_storage->load(['alias' => '/source-noslash']);
|
||||
$this->assertSame('/admin', $path['source']);
|
||||
$this->assertSame('und', $path['langcode']);
|
||||
$path_alias = $this->loadPathAliasByConditions(['alias' => '/source-noslash']);
|
||||
$this->assertSame('/admin', $path_alias->getPath());
|
||||
$this->assertSame('und', $path_alias->language()->getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,9 +44,8 @@ class PathItemTest extends KernelTestBase {
|
|||
* Test creating, loading, updating and deleting aliases through PathItem.
|
||||
*/
|
||||
public function testPathItem() {
|
||||
|
||||
/** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */
|
||||
$alias_storage = \Drupal::service('path.alias_storage');
|
||||
/** @var \Drupal\Core\Path\AliasRepositoryInterface $alias_repository */
|
||||
$alias_repository = \Drupal::service('path.alias_repository');
|
||||
|
||||
$node_storage = \Drupal::entityTypeManager()->getStorage('node');
|
||||
|
||||
|
@ -62,8 +61,8 @@ class PathItemTest extends KernelTestBase {
|
|||
$this->assertFalse($node->get('path')->isEmpty());
|
||||
$this->assertEquals('/foo', $node->get('path')->alias);
|
||||
|
||||
$stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foo', $stored_alias);
|
||||
$stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foo', $stored_alias['alias']);
|
||||
|
||||
$node_storage->resetCache();
|
||||
|
||||
|
@ -97,10 +96,10 @@ class PathItemTest extends KernelTestBase {
|
|||
$translation = $loaded_node->getTranslation('de');
|
||||
$this->assertEquals('/furchtbar', $translation->path->alias);
|
||||
|
||||
$stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foo', $stored_alias);
|
||||
$stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $translation->language()->getId());
|
||||
$this->assertEquals('/furchtbar', $stored_alias);
|
||||
$stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foo', $stored_alias['alias']);
|
||||
$stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $translation->language()->getId());
|
||||
$this->assertEquals('/furchtbar', $stored_alias['alias']);
|
||||
|
||||
$loaded_node->get('path')->alias = '/bar';
|
||||
$this->assertFalse($loaded_node->get('path')->isEmpty());
|
||||
|
@ -123,11 +122,11 @@ class PathItemTest extends KernelTestBase {
|
|||
$this->assertFalse($loaded_node->get('path')->isEmpty());
|
||||
$this->assertEquals('/bar', $loaded_node->get('path')->alias);
|
||||
|
||||
$stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/bar', $stored_alias);
|
||||
$stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/bar', $stored_alias['alias']);
|
||||
|
||||
$old_alias = $alias_storage->lookupPathSource('/foo', $node->language()->getId());
|
||||
$this->assertFalse($old_alias);
|
||||
$old_alias = $alias_repository->lookupByAlias('/foo', $node->language()->getId());
|
||||
$this->assertNull($old_alias);
|
||||
|
||||
// Reload the node to make sure that it is possible to set a value
|
||||
// immediately after loading.
|
||||
|
@ -140,19 +139,19 @@ class PathItemTest extends KernelTestBase {
|
|||
$loaded_node = $node_storage->load($node->id());
|
||||
$this->assertFalse($loaded_node->get('path')->isEmpty());
|
||||
$this->assertEquals('/foobar', $loaded_node->get('path')->alias);
|
||||
$stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foobar', $stored_alias);
|
||||
$stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foobar', $stored_alias['alias']);
|
||||
|
||||
$old_alias = $alias_storage->lookupPathSource('/bar', $node->language()->getId());
|
||||
$this->assertFalse($old_alias);
|
||||
$old_alias = $alias_repository->lookupByAlias('/bar', $node->language()->getId());
|
||||
$this->assertNull($old_alias);
|
||||
|
||||
$loaded_node->get('path')->alias = '';
|
||||
$this->assertEquals('', $loaded_node->get('path')->alias);
|
||||
|
||||
$loaded_node->save();
|
||||
|
||||
$stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertFalse($stored_alias);
|
||||
$stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertNull($stored_alias);
|
||||
|
||||
// Check that reading, updating and reading the computed alias again in the
|
||||
// same request works without clearing any caches in between.
|
||||
|
@ -162,16 +161,16 @@ class PathItemTest extends KernelTestBase {
|
|||
|
||||
$this->assertFalse($loaded_node->get('path')->isEmpty());
|
||||
$this->assertEquals('/foo', $loaded_node->get('path')->alias);
|
||||
$stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foo', $stored_alias);
|
||||
$stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foo', $stored_alias['alias']);
|
||||
|
||||
$loaded_node->get('path')->alias = '/foobar';
|
||||
$loaded_node->save();
|
||||
|
||||
$this->assertFalse($loaded_node->get('path')->isEmpty());
|
||||
$this->assertEquals('/foobar', $loaded_node->get('path')->alias);
|
||||
$stored_alias = $alias_storage->lookupPathAlias('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foobar', $stored_alias);
|
||||
$stored_alias = $alias_repository->lookupBySystemPath('/' . $node->toUrl()->getInternalPath(), $node->language()->getId());
|
||||
$this->assertEquals('/foobar', $stored_alias['alias']);
|
||||
|
||||
// Check that \Drupal\Core\Field\FieldItemList::equals() for the path field
|
||||
// type.
|
||||
|
|
|
@ -8,6 +8,7 @@ use Drupal\Core\Url;
|
|||
use Drupal\shortcut\Entity\Shortcut;
|
||||
use Drupal\shortcut\Entity\ShortcutSet;
|
||||
use Drupal\Tests\block\Functional\AssertBlockAppearsTrait;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
use Drupal\views\Entity\View;
|
||||
|
||||
/**
|
||||
|
@ -18,6 +19,7 @@ use Drupal\views\Entity\View;
|
|||
class ShortcutLinksTest extends ShortcutTestBase {
|
||||
|
||||
use AssertBlockAppearsTrait;
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
|
@ -42,11 +44,7 @@ class ShortcutLinksTest extends ShortcutTestBase {
|
|||
$set = $this->set;
|
||||
|
||||
// Create an alias for the node so we can test aliases.
|
||||
$path = [
|
||||
'source' => '/node/' . $this->node->id(),
|
||||
'alias' => '/' . $this->randomMachineName(8),
|
||||
];
|
||||
$this->container->get('path.alias_storage')->save($path['source'], $path['alias']);
|
||||
$path_alias = $this->createPathAlias('/node/' . $this->node->id(), '/' . $this->randomMachineName(8));
|
||||
|
||||
// Create some paths to test.
|
||||
$test_cases = [
|
||||
|
@ -54,7 +52,7 @@ class ShortcutLinksTest extends ShortcutTestBase {
|
|||
'/admin',
|
||||
'/admin/config/system/site-information',
|
||||
'/node/' . $this->node->id() . '/edit',
|
||||
$path['alias'],
|
||||
$path_alias->getAlias(),
|
||||
'/router_test/test2',
|
||||
'/router_test/test3/value',
|
||||
];
|
||||
|
|
|
@ -7,14 +7,17 @@ use Drupal\Core\Database\Database;
|
|||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\taxonomy\Entity\Term;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Tests altering the inbound path and the outbound path.
|
||||
*
|
||||
* @group Path
|
||||
* @group path
|
||||
*/
|
||||
class UrlAlterFunctionalTest extends BrowserTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
|
@ -43,8 +46,7 @@ class UrlAlterFunctionalTest extends BrowserTestBase {
|
|||
$this->assertUrlOutboundAlter("/user/$uid", "/user/$name");
|
||||
|
||||
// Test that a path always uses its alias.
|
||||
$path = ['source' => "/user/$uid/test1", 'alias' => '/alias/test1'];
|
||||
$this->container->get('path.alias_storage')->save($path['source'], $path['alias']);
|
||||
$this->createPathAlias("/user/$uid/test1", '/alias/test1');
|
||||
$this->rebuildContainer();
|
||||
$this->assertUrlInboundAlter('/alias/test1', "/user/$uid/test1");
|
||||
$this->assertUrlOutboundAlter("/user/$uid/test1", '/alias/test1');
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
|
||||
namespace Drupal\Tests\system\Kernel;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Path\AliasManagerInterface;
|
||||
use Drupal\Core\Path\Entity\PathAlias;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @group Drupal
|
||||
* @coversDefaultClass \Drupal\Core\Path\Entity\PathAlias
|
||||
*
|
||||
* @group path
|
||||
*/
|
||||
class PathHooksTest extends KernelTestBase {
|
||||
|
||||
|
@ -27,38 +29,43 @@ class PathHooksTest extends KernelTestBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* Test system_path_alias_*() correctly clears caches.
|
||||
* Tests that the PathAlias entity clears caches correctly.
|
||||
*
|
||||
* @covers ::postSave
|
||||
* @covers ::postDelete
|
||||
*/
|
||||
public function testPathHooks() {
|
||||
$source = '/' . $this->randomMachineName();
|
||||
$alias = '/' . $this->randomMachineName();
|
||||
$path_alias = PathAlias::create([
|
||||
'path' => '/' . $this->randomMachineName(),
|
||||
'alias' => '/' . $this->randomMachineName(),
|
||||
]);
|
||||
|
||||
// Check system_path_alias_insert();
|
||||
// Check \Drupal\Core\Path\Entity\PathAlias::postSave() for new path alias
|
||||
// entities.
|
||||
$alias_manager = $this->prophesize(AliasManagerInterface::class);
|
||||
$alias_manager->cacheClear(Argument::any())->shouldBeCalledTimes(1);
|
||||
$alias_manager->cacheClear($source)->shouldBeCalledTimes(1);
|
||||
$alias_manager->cacheClear($path_alias->getPath())->shouldBeCalledTimes(1);
|
||||
\Drupal::getContainer()->set('path.alias_manager', $alias_manager->reveal());
|
||||
$alias_storage = \Drupal::service('path.alias_storage');
|
||||
$alias_storage->save($source, $alias);
|
||||
$path_alias->save();
|
||||
|
||||
$new_source = '/' . $this->randomMachineName();
|
||||
$path = $alias_storage->load(['source' => $source]);
|
||||
|
||||
// Check system_path_alias_update();
|
||||
// Check \Drupal\Core\Path\Entity\PathAlias::postSave() for existing path
|
||||
// alias entities.
|
||||
$alias_manager = $this->prophesize(AliasManagerInterface::class);
|
||||
$alias_manager->cacheClear(Argument::any())->shouldBeCalledTimes(2);
|
||||
$alias_manager->cacheClear($source)->shouldBeCalledTimes(1);
|
||||
$alias_manager->cacheClear($path_alias->getPath())->shouldBeCalledTimes(1);
|
||||
$alias_manager->cacheClear($new_source)->shouldBeCalledTimes(1);
|
||||
\Drupal::getContainer()->set('path.alias_manager', $alias_manager->reveal());
|
||||
$alias_storage->save($new_source, $alias, LanguageInterface::LANGCODE_NOT_SPECIFIED, $path['pid']);
|
||||
$path_alias->setPath($new_source);
|
||||
$path_alias->save();
|
||||
|
||||
// Check system_path_alias_delete();
|
||||
// Check \Drupal\Core\Path\Entity\PathAlias::postDelete().
|
||||
$alias_manager = $this->prophesize(AliasManagerInterface::class);
|
||||
$alias_manager->cacheClear(Argument::any())->shouldBeCalledTimes(1);
|
||||
$alias_manager->cacheClear($new_source)->shouldBeCalledTimes(1);
|
||||
\Drupal::getContainer()->set('path.alias_manager', $alias_manager->reveal());
|
||||
$alias_storage->delete(['pid' => $path['pid']]);
|
||||
|
||||
$path_alias->delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,15 +2,12 @@
|
|||
|
||||
namespace Drupal\workspaces;
|
||||
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Path\AliasStorage as CoreAliasStorage;
|
||||
use Drupal\Core\Path\AliasRepository;
|
||||
|
||||
/**
|
||||
* Provides workspace-specific path alias lookup queries.
|
||||
*/
|
||||
class AliasStorage extends CoreAliasStorage {
|
||||
class WorkspacesAliasRepository extends AliasRepository {
|
||||
|
||||
/**
|
||||
* The workspace manager.
|
||||
|
@ -20,20 +17,16 @@ class AliasStorage extends CoreAliasStorage {
|
|||
protected $workspaceManager;
|
||||
|
||||
/**
|
||||
* AliasStorage constructor.
|
||||
* Sets the workspace manager.
|
||||
*
|
||||
* @param \Drupal\Core\Database\Connection $connection
|
||||
* A database connection for reading and writing path aliases.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
* @param \Drupal\workspaces\WorkspaceManagerInterface $workspace_manager
|
||||
* The workspace manager service.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function __construct(Connection $connection, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, WorkspaceManagerInterface $workspace_manager) {
|
||||
parent::__construct($connection, $module_handler, $entity_type_manager);
|
||||
public function setWorkspacesManager(WorkspaceManagerInterface $workspace_manager) {
|
||||
$this->workspaceManager = $workspace_manager;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
|
@ -20,10 +20,10 @@ class WorkspacesServiceProvider extends ServiceProviderBase {
|
|||
$renderer_config['required_cache_contexts'][] = 'workspace';
|
||||
$container->setParameter('renderer.config', $renderer_config);
|
||||
|
||||
// Replace the class of the 'path.alias_storage' service.
|
||||
$container->getDefinition('path.alias_storage')
|
||||
->setClass(AliasStorage::class)
|
||||
->addArgument(new Reference('workspaces.manager'));
|
||||
// Replace the class of the 'path.alias_repository' service.
|
||||
$container->getDefinition('path.alias_repository')
|
||||
->setClass(WorkspacesAliasRepository::class)
|
||||
->addMethodCall('setWorkspacesManager', [new Reference('workspaces.manager')]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class DistributionProfileTest extends InstallerTestBase {
|
|||
$path = $this->siteDirectory . '/profiles/mydistro';
|
||||
mkdir($path, 0777, TRUE);
|
||||
file_put_contents("$path/mydistro.info.yml", Yaml::encode($this->info));
|
||||
file_put_contents("$path/mydistro.install", "<?php function mydistro_install() {\Drupal::service('path.alias_storage')->save('/user/1', '/myrootuser');}");
|
||||
file_put_contents("$path/mydistro.install", "<?php function mydistro_install() {\Drupal::entityTypeManager()->getStorage('path_alias')->create(['path' => '/user/1', 'alias' => '/myrootuser'])->save();}");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,14 +4,18 @@ namespace Drupal\FunctionalTests\Routing;
|
|||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Tests url generation and routing for route paths with encoded characters.
|
||||
*
|
||||
* @group path
|
||||
* @group routing
|
||||
*/
|
||||
class PathEncodedTest extends BrowserTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -35,12 +39,10 @@ class PathEncodedTest extends BrowserTestBase {
|
|||
'path_encoded_test.atsign' => '/bloggy/@Dries',
|
||||
'path_encoded_test.parens' => '/cat(box)',
|
||||
];
|
||||
/** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */
|
||||
$alias_storage = $this->container->get('path.alias_storage');
|
||||
$aliases = [];
|
||||
foreach ($route_paths as $route_name => $path) {
|
||||
$aliases[$route_name] = $this->randomMachineName();
|
||||
$alias_storage->save($path, '/' . $aliases[$route_name]);
|
||||
$this->createPathAlias($path, '/' . $aliases[$route_name]);
|
||||
}
|
||||
foreach ($route_paths as $route_name => $path) {
|
||||
// The alias may be only a suffix of the generated path when the test is
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Drupal\FunctionalTests\Routing;
|
|||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the route cache when the language is not in the path.
|
||||
|
@ -13,6 +14,8 @@ use Drupal\Tests\BrowserTestBase;
|
|||
*/
|
||||
class RouteCachingNonPathLanguageNegotiationTest extends BrowserTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
|
@ -71,7 +74,7 @@ class RouteCachingNonPathLanguageNegotiationTest extends BrowserTestBase {
|
|||
// on the french page exist in english, no matter which language is
|
||||
// checked first. Create the alias after visiting frontpage to make sure
|
||||
// there is no existing cache entry for this that affects the tests.
|
||||
\Drupal::service('path.alias_storage')->save('/user/' . $this->adminUser->id(), '/user-page', 'en');
|
||||
$this->createPathAlias('/user/' . $this->adminUser->id(), '/user-page', 'en');
|
||||
|
||||
$this->clickLink('French');
|
||||
$this->drupalGet('user-page');
|
||||
|
|
|
@ -8,6 +8,7 @@ use Drupal\Core\Config\DatabaseStorage;
|
|||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
use Drupal\user\Entity\User;
|
||||
use Symfony\Component\Console\Tester\CommandTester;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
@ -19,6 +20,8 @@ use Symfony\Component\DependencyInjection\Reference;
|
|||
*/
|
||||
class DbDumpTest extends KernelTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -109,7 +112,7 @@ class DbDumpTest extends KernelTestBase {
|
|||
$account->save();
|
||||
|
||||
// Create a path alias.
|
||||
$this->container->get('path.alias_storage')->save('/user/' . $account->id(), '/user/example');
|
||||
$this->createPathAlias('/user/' . $account->id(), '/user/example');
|
||||
|
||||
// Create a cache table (this will create 'cache_discovery').
|
||||
\Drupal::cache('discovery')->set('test', $this->data);
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Path;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Path\AliasStorage
|
||||
* @group path
|
||||
*/
|
||||
class AliasStorageTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Path\AliasStorage
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('path_alias');
|
||||
$this->storage = $this->container->get('path.alias_storage');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::load
|
||||
*/
|
||||
public function testLoad() {
|
||||
$this->storage->save('/test-source-Case', '/test-alias-Case');
|
||||
|
||||
$expected = [
|
||||
'pid' => 1,
|
||||
'alias' => '/test-alias-Case',
|
||||
'source' => '/test-source-Case',
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $this->storage->load(['alias' => '/test-alias-Case']));
|
||||
$this->assertEquals($expected, $this->storage->load(['alias' => '/test-alias-case']));
|
||||
$this->assertEquals($expected, $this->storage->load(['source' => '/test-source-Case']));
|
||||
$this->assertEquals($expected, $this->storage->load(['source' => '/test-source-case']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::lookupPathAlias
|
||||
*/
|
||||
public function testLookupPathAlias() {
|
||||
$this->storage->save('/test-source-Case', '/test-alias');
|
||||
|
||||
$this->assertEquals('/test-alias', $this->storage->lookupPathAlias('/test-source-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
$this->assertEquals('/test-alias', $this->storage->lookupPathAlias('/test-source-case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::lookupPathSource
|
||||
*/
|
||||
public function testLookupPathSource() {
|
||||
$this->storage->save('/test-source', '/test-alias-Case');
|
||||
|
||||
$this->assertEquals('/test-source', $this->storage->lookupPathSource('/test-alias-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
$this->assertEquals('/test-source', $this->storage->lookupPathSource('/test-alias-case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::aliasExists
|
||||
*/
|
||||
public function testAliasExists() {
|
||||
$this->storage->save('/test-source-Case', '/test-alias-Case');
|
||||
|
||||
$this->assertTrue($this->storage->aliasExists('/test-alias-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
$this->assertTrue($this->storage->aliasExists('/test-alias-case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
}
|
||||
|
||||
}
|
|
@ -2,20 +2,24 @@
|
|||
|
||||
namespace Drupal\KernelTests\Core\Path;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Cache\MemoryCounterBackend;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Path\AliasManager;
|
||||
use Drupal\Core\Path\AliasWhitelist;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Tests path alias CRUD and lookup functionality.
|
||||
*
|
||||
* @group Path
|
||||
* @coversDefaultClass \Drupal\Core\Path\AliasRepository
|
||||
*
|
||||
* @group path
|
||||
*/
|
||||
class AliasTest extends KernelTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -29,166 +33,76 @@ class AliasTest extends KernelTestBase {
|
|||
$this->installEntitySchema('path_alias');
|
||||
}
|
||||
|
||||
public function testCRUD() {
|
||||
// Prepare database table.
|
||||
$connection = Database::getConnection();
|
||||
/**
|
||||
* @covers ::lookupBySystemPath
|
||||
*/
|
||||
public function testLookupBySystemPath() {
|
||||
$this->createPathAlias('/test-source-Case', '/test-alias');
|
||||
|
||||
// Create Path object.
|
||||
$aliasStorage = $this->container->get('path.alias_storage');
|
||||
|
||||
$aliases = $this->sampleUrlAliases();
|
||||
|
||||
// Create a few aliases
|
||||
foreach ($aliases as $idx => $alias) {
|
||||
$aliasStorage->save($alias['source'], $alias['alias'], $alias['langcode']);
|
||||
|
||||
$result = $connection->query('SELECT * FROM {path_alias} WHERE path = :path AND alias= :alias AND langcode = :langcode', [':path' => $alias['source'], ':alias' => $alias['alias'], ':langcode' => $alias['langcode']]);
|
||||
$rows = $result->fetchAll();
|
||||
|
||||
$this->assertEqual(count($rows), 1, new FormattableMarkup('Created an entry for %alias.', ['%alias' => $alias['alias']]));
|
||||
|
||||
// Cache the pid for further tests.
|
||||
$aliases[$idx]['pid'] = $rows[0]->id;
|
||||
}
|
||||
|
||||
// Load a few aliases
|
||||
foreach ($aliases as $alias) {
|
||||
$pid = $alias['pid'];
|
||||
$loadedAlias = $aliasStorage->load(['pid' => $pid]);
|
||||
$this->assertEqual($loadedAlias, $alias, new FormattableMarkup('Loaded the expected path with pid %pid.', ['%pid' => $pid]));
|
||||
}
|
||||
|
||||
// Load alias by source path.
|
||||
$loadedAlias = $aliasStorage->load(['source' => '/node/1']);
|
||||
$this->assertEqual($loadedAlias['alias'], '/alias_for_node_1_und', 'The last created alias loaded by default.');
|
||||
|
||||
// Update a few aliases
|
||||
foreach ($aliases as $alias) {
|
||||
$fields = $aliasStorage->save($alias['source'], $alias['alias'] . '_updated', $alias['langcode'], $alias['pid']);
|
||||
|
||||
$this->assertEqual($alias['alias'], $fields['original']['alias']);
|
||||
|
||||
$result = $connection->query('SELECT id FROM {path_alias} WHERE path = :path AND alias= :alias AND langcode = :langcode', [':path' => $alias['source'], ':alias' => $alias['alias'] . '_updated', ':langcode' => $alias['langcode']]);
|
||||
$pid = $result->fetchField();
|
||||
|
||||
$this->assertEqual($pid, $alias['pid'], new FormattableMarkup('Updated entry for pid %pid.', ['%pid' => $pid]));
|
||||
}
|
||||
|
||||
// Delete a few aliases
|
||||
foreach ($aliases as $alias) {
|
||||
$pid = $alias['pid'];
|
||||
$aliasStorage->delete(['pid' => $pid]);
|
||||
|
||||
$result = $connection->query('SELECT * FROM {path_alias} WHERE id = :id', [':id' => $pid]);
|
||||
$rows = $result->fetchAll();
|
||||
|
||||
$this->assertEqual(count($rows), 0, new FormattableMarkup('Deleted entry with pid %pid.', ['%pid' => $pid]));
|
||||
}
|
||||
$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']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of URL aliases for testing.
|
||||
*
|
||||
* @return array of URL alias definitions.
|
||||
* @covers ::lookupByAlias
|
||||
*/
|
||||
protected function sampleUrlAliases() {
|
||||
return [
|
||||
[
|
||||
'source' => '/node/1',
|
||||
'alias' => '/alias_for_node_1_en',
|
||||
'langcode' => 'en',
|
||||
],
|
||||
[
|
||||
'source' => '/node/2',
|
||||
'alias' => '/alias_for_node_2_en',
|
||||
'langcode' => 'en',
|
||||
],
|
||||
[
|
||||
'source' => '/node/1',
|
||||
'alias' => '/alias_for_node_1_fr',
|
||||
'langcode' => 'fr',
|
||||
],
|
||||
[
|
||||
'source' => '/node/1',
|
||||
'alias' => '/alias_for_node_1_und',
|
||||
'langcode' => 'und',
|
||||
],
|
||||
];
|
||||
public function testLookupByAlias() {
|
||||
$this->createPathAlias('/test-source', '/test-alias-Case');
|
||||
|
||||
$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']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers \Drupal\Core\Path\AliasManager::getPathByAlias
|
||||
* @covers \Drupal\Core\Path\AliasManager::getAliasByPath
|
||||
*/
|
||||
public function testLookupPath() {
|
||||
// Create AliasManager and Path object.
|
||||
$aliasManager = $this->container->get('path.alias_manager');
|
||||
$aliasStorage = $this->container->get('path.alias_storage');
|
||||
|
||||
// Test the situation where the source is the same for multiple aliases.
|
||||
// Start with a language-neutral alias, which we will override.
|
||||
$path = [
|
||||
'source' => "/user/1",
|
||||
'alias' => '/foo',
|
||||
];
|
||||
|
||||
$aliasStorage->save($path['source'], $path['alias']);
|
||||
$this->assertEqual($aliasManager->getAliasByPath($path['source']), $path['alias'], 'Basic alias lookup works.');
|
||||
$this->assertEqual($aliasManager->getPathByAlias($path['alias']), $path['source'], 'Basic source lookup works.');
|
||||
$path_alias = $this->createPathAlias('/user/1', '/foo');
|
||||
$this->assertEquals($path_alias->getAlias(), $aliasManager->getAliasByPath($path_alias->getPath()), 'Basic alias lookup works.');
|
||||
$this->assertEquals($path_alias->getPath(), $aliasManager->getPathByAlias($path_alias->getAlias()), 'Basic source lookup works.');
|
||||
|
||||
// Create a language specific alias for the default language (English).
|
||||
$path = [
|
||||
'source' => "/user/1",
|
||||
'alias' => "/users/Dries",
|
||||
'langcode' => 'en',
|
||||
];
|
||||
$aliasStorage->save($path['source'], $path['alias'], $path['langcode']);
|
||||
// Hook that clears cache is not executed with unit tests.
|
||||
\Drupal::service('path.alias_manager')->cacheClear();
|
||||
$this->assertEqual($aliasManager->getAliasByPath($path['source']), $path['alias'], 'English alias overrides language-neutral alias.');
|
||||
$this->assertEqual($aliasManager->getPathByAlias($path['alias']), $path['source'], 'English source overrides language-neutral source.');
|
||||
$path_alias = $this->createPathAlias('/user/1', '/users/Dries', 'en');
|
||||
|
||||
$this->assertEquals($path_alias->getAlias(), $aliasManager->getAliasByPath($path_alias->getPath()), 'English alias overrides language-neutral alias.');
|
||||
$this->assertEquals($path_alias->getPath(), $aliasManager->getPathByAlias($path_alias->getAlias()), 'English source overrides language-neutral source.');
|
||||
|
||||
// Create a language-neutral alias for the same path, again.
|
||||
$path = [
|
||||
'source' => "/user/1",
|
||||
'alias' => '/bar',
|
||||
];
|
||||
$aliasStorage->save($path['source'], $path['alias']);
|
||||
$this->assertEqual($aliasManager->getAliasByPath($path['source']), "/users/Dries", 'English alias still returned after entering a language-neutral alias.');
|
||||
$path_alias = $this->createPathAlias('/user/1', '/bar');
|
||||
$this->assertEquals("/users/Dries", $aliasManager->getAliasByPath($path_alias->getPath()), 'English alias still returned after entering a language-neutral alias.');
|
||||
|
||||
// Create a language-specific (xx-lolspeak) alias for the same path.
|
||||
$path = [
|
||||
'source' => "/user/1",
|
||||
'alias' => '/LOL',
|
||||
'langcode' => 'xx-lolspeak',
|
||||
];
|
||||
$aliasStorage->save($path['source'], $path['alias'], $path['langcode']);
|
||||
$this->assertEqual($aliasManager->getAliasByPath($path['source']), "/users/Dries", 'English alias still returned after entering a LOLspeak alias.');
|
||||
$path_alias = $this->createPathAlias('/user/1', '/LOL', 'xx-lolspeak');
|
||||
$this->assertEquals("/users/Dries", $aliasManager->getAliasByPath($path_alias->getPath()), 'English alias still returned after entering a LOLspeak alias.');
|
||||
// The LOLspeak alias should be returned if we really want LOLspeak.
|
||||
$this->assertEqual($aliasManager->getAliasByPath($path['source'], 'xx-lolspeak'), '/LOL', 'LOLspeak alias returned if we specify xx-lolspeak to the alias manager.');
|
||||
$this->assertEquals('/LOL', $aliasManager->getAliasByPath($path_alias->getPath(), 'xx-lolspeak'), 'LOLspeak alias returned if we specify xx-lolspeak to the alias manager.');
|
||||
|
||||
// Create a new alias for this path in English, which should override the
|
||||
// previous alias for "user/1".
|
||||
$path = [
|
||||
'source' => "/user/1",
|
||||
'alias' => '/users/my-new-path',
|
||||
'langcode' => 'en',
|
||||
];
|
||||
$aliasStorage->save($path['source'], $path['alias'], $path['langcode']);
|
||||
// Hook that clears cache is not executed with unit tests.
|
||||
$aliasManager->cacheClear();
|
||||
$this->assertEqual($aliasManager->getAliasByPath($path['source']), $path['alias'], 'Recently created English alias returned.');
|
||||
$this->assertEqual($aliasManager->getPathByAlias($path['alias']), $path['source'], 'Recently created English source returned.');
|
||||
$path_alias = $this->createPathAlias('/user/1', '/users/my-new-path', 'en');
|
||||
$this->assertEquals($path_alias->getAlias(), $aliasManager->getAliasByPath($path_alias->getPath()), 'Recently created English alias returned.');
|
||||
$this->assertEquals($path_alias->getPath(), $aliasManager->getPathByAlias($path_alias->getAlias()), 'Recently created English source returned.');
|
||||
|
||||
// Remove the English aliases, which should cause a fallback to the most
|
||||
// recently created language-neutral alias, 'bar'.
|
||||
$aliasStorage->delete(['langcode' => 'en']);
|
||||
// Hook that clears cache is not executed with unit tests.
|
||||
$aliasManager->cacheClear();
|
||||
$this->assertEqual($aliasManager->getAliasByPath($path['source']), '/bar', 'Path lookup falls back to recently created language-neutral alias.');
|
||||
$path_alias_storage = $this->container->get('entity_type.manager')->getStorage('path_alias');
|
||||
$entities = $path_alias_storage->loadByProperties(['langcode' => 'en']);
|
||||
$path_alias_storage->delete($entities);
|
||||
$this->assertEquals('/bar', $aliasManager->getAliasByPath($path_alias->getPath()), 'Path lookup falls back to recently created language-neutral alias.');
|
||||
|
||||
// Test the situation where the alias and language are the same, but
|
||||
// the source differs. The newer alias record should be returned.
|
||||
$aliasStorage->save('/user/2', '/bar');
|
||||
// Hook that clears cache is not executed with unit tests.
|
||||
$this->createPathAlias('/user/2', '/bar');
|
||||
$aliasManager->cacheClear();
|
||||
$this->assertEqual($aliasManager->getPathByAlias('/bar'), '/user/2', 'Newer alias record is returned when comparing two LanguageInterface::LANGCODE_NOT_SPECIFIED paths with the same alias.');
|
||||
$this->assertEquals('/user/2', $aliasManager->getPathByAlias('/bar'), 'Newer alias record is returned when comparing two LanguageInterface::LANGCODE_NOT_SPECIFIED paths with the same alias.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,9 +112,8 @@ class AliasTest extends KernelTestBase {
|
|||
$memoryCounterBackend = new MemoryCounterBackend();
|
||||
|
||||
// Create AliasManager and Path object.
|
||||
$aliasStorage = $this->container->get('path.alias_storage');
|
||||
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage);
|
||||
$aliasManager = new AliasManager($aliasStorage, $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'));
|
||||
|
@ -211,21 +124,23 @@ class AliasTest extends KernelTestBase {
|
|||
$this->assertNull($whitelist->get($this->randomMachineName()));
|
||||
|
||||
// Add an alias for user/1, user should get whitelisted now.
|
||||
$aliasStorage->save('/user/1', '/' . $this->randomMachineName());
|
||||
$this->createPathAlias('/user/1', '/' . $this->randomMachineName());
|
||||
$aliasManager->cacheClear();
|
||||
$this->assertTrue($whitelist->get('user'));
|
||||
$this->assertNull($whitelist->get('admin'));
|
||||
$this->assertNull($whitelist->get($this->randomMachineName()));
|
||||
|
||||
// Add an alias for admin, both should get whitelisted now.
|
||||
$aliasStorage->save('/admin/something', '/' . $this->randomMachineName());
|
||||
$this->createPathAlias('/admin/something', '/' . $this->randomMachineName());
|
||||
$aliasManager->cacheClear();
|
||||
$this->assertTrue($whitelist->get('user'));
|
||||
$this->assertTrue($whitelist->get('admin'));
|
||||
$this->assertNull($whitelist->get($this->randomMachineName()));
|
||||
|
||||
// Remove the user alias again, whitelist entry should be removed.
|
||||
$aliasStorage->delete(['source' => '/user/1']);
|
||||
$path_alias_storage = $this->container->get('entity_type.manager')->getStorage('path_alias');
|
||||
$entities = $path_alias_storage->loadByProperties(['path' => '/user/1']);
|
||||
$path_alias_storage->delete($entities);
|
||||
$aliasManager->cacheClear();
|
||||
$this->assertNull($whitelist->get('user'));
|
||||
$this->assertTrue($whitelist->get('admin'));
|
||||
|
@ -238,7 +153,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'), $aliasStorage);
|
||||
$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()));
|
||||
|
@ -258,17 +173,15 @@ class AliasTest extends KernelTestBase {
|
|||
$memoryCounterBackend = new MemoryCounterBackend();
|
||||
|
||||
// Create AliasManager and Path object.
|
||||
$aliasStorage = $this->container->get('path.alias_storage');
|
||||
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $aliasStorage);
|
||||
$aliasManager = new AliasManager($aliasStorage, $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'));
|
||||
|
||||
// Add some aliases for both menu routes we have.
|
||||
$aliasStorage->save('/admin/something', '/' . $this->randomMachineName());
|
||||
$aliasStorage->save('/user/something', '/' . $this->randomMachineName());
|
||||
$aliasManager->cacheClear();
|
||||
$this->createPathAlias('/admin/something', '/' . $this->randomMachineName());
|
||||
$this->createPathAlias('/user/something', '/' . $this->randomMachineName());
|
||||
|
||||
// Lookup admin path in whitelist. It will query the DB and figure out
|
||||
// that it indeed has an alias, and add it to the internal whitelist and
|
||||
|
@ -288,7 +201,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'), $aliasStorage);
|
||||
$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,
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Path;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Path\AliasStorage
|
||||
* @group path
|
||||
* @group legacy
|
||||
*/
|
||||
class LegacyAliasStorageTest extends KernelTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system'];
|
||||
|
||||
/**
|
||||
* @var \Drupal\Core\Path\AliasStorage
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('path_alias');
|
||||
$this->storage = $this->container->get('path.alias_storage');
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
public function testLoad() {
|
||||
$this->storage->save('/test-source-Case', '/test-alias-Case');
|
||||
|
||||
$expected = [
|
||||
'pid' => 1,
|
||||
'alias' => '/test-alias-Case',
|
||||
'source' => '/test-source-Case',
|
||||
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $this->storage->load(['alias' => '/test-alias-Case']));
|
||||
$this->assertEquals($expected, $this->storage->load(['alias' => '/test-alias-case']));
|
||||
$this->assertEquals($expected, $this->storage->load(['source' => '/test-source-Case']));
|
||||
$this->assertEquals($expected, $this->storage->load(['source' => '/test-source-case']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
public function testCRUD() {
|
||||
$entity_storage = \Drupal::entityTypeManager()->getStorage('path_alias');
|
||||
$aliases = $this->sampleUrlAliases();
|
||||
|
||||
// Create a few aliases
|
||||
foreach ($aliases as $idx => $alias) {
|
||||
$this->storage->save($alias['source'], $alias['alias'], $alias['langcode']);
|
||||
|
||||
$result = $entity_storage->getQuery()
|
||||
->condition('path', $alias['source'])
|
||||
->condition('alias', $alias['alias'])
|
||||
->condition('langcode', $alias['langcode'])
|
||||
->execute();
|
||||
|
||||
$this->assertCount(1, $result, "Created an entry for {$alias['alias']}.");
|
||||
|
||||
// Cache the pid for further tests.
|
||||
$aliases[$idx]['pid'] = reset($result);
|
||||
}
|
||||
|
||||
// Load a few aliases
|
||||
foreach ($aliases as $alias) {
|
||||
$pid = $alias['pid'];
|
||||
$loadedAlias = $this->storage->load(['pid' => $pid]);
|
||||
$this->assertEquals($alias, $loadedAlias, "Loaded the expected path with pid $pid.");
|
||||
}
|
||||
|
||||
// Load alias by source path.
|
||||
$loadedAlias = $this->storage->load(['source' => '/node/1']);
|
||||
$this->assertEquals('/alias_for_node_1_und', $loadedAlias['alias'], 'The last created alias loaded by default.');
|
||||
|
||||
// Update a few aliases
|
||||
foreach ($aliases as $alias) {
|
||||
$fields = $this->storage->save($alias['source'], $alias['alias'] . '_updated', $alias['langcode'], $alias['pid']);
|
||||
|
||||
$this->assertEquals($alias['alias'], $fields['original']['alias']);
|
||||
|
||||
$result = $entity_storage->getQuery()
|
||||
->condition('path', $alias['source'])
|
||||
->condition('alias', $alias['alias'] . '_updated')
|
||||
->condition('langcode', $alias['langcode'])
|
||||
->execute();
|
||||
$pid = reset($result);
|
||||
|
||||
$this->assertEquals($alias['pid'], $pid, "Updated entry for pid $pid.");
|
||||
}
|
||||
|
||||
// Delete a few aliases
|
||||
foreach ($aliases as $alias) {
|
||||
$pid = $alias['pid'];
|
||||
$this->storage->delete(['pid' => $pid]);
|
||||
|
||||
$result = $entity_storage->getQuery()->condition('id', $pid)->execute();
|
||||
|
||||
$this->assertCount(0, $result, "Deleted entry with pid $pid.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of URL aliases for testing.
|
||||
*
|
||||
* @return array of URL alias definitions.
|
||||
*/
|
||||
protected function sampleUrlAliases() {
|
||||
return [
|
||||
[
|
||||
'source' => '/node/1',
|
||||
'alias' => '/alias_for_node_1_en',
|
||||
'langcode' => 'en',
|
||||
],
|
||||
[
|
||||
'source' => '/node/2',
|
||||
'alias' => '/alias_for_node_2_en',
|
||||
'langcode' => 'en',
|
||||
],
|
||||
[
|
||||
'source' => '/node/1',
|
||||
'alias' => '/alias_for_node_1_fr',
|
||||
'langcode' => 'fr',
|
||||
],
|
||||
[
|
||||
'source' => '/node/1',
|
||||
'alias' => '/alias_for_node_1_und',
|
||||
'langcode' => 'und',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
public function testPreLoadPathAlias() {
|
||||
$this->storage->save('/test-source-Case', '/test-alias');
|
||||
|
||||
$this->assertEquals(['/test-source-Case' => '/test-alias'], $this->storage->preloadPathAlias(['/test-source-Case'], LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
public function testLookupPathAlias() {
|
||||
$this->storage->save('/test-source-Case', '/test-alias');
|
||||
|
||||
$this->assertEquals('/test-alias', $this->storage->lookupPathAlias('/test-source-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
$this->assertEquals('/test-alias', $this->storage->lookupPathAlias('/test-source-case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
public function testLookupPathSource() {
|
||||
$this->storage->save('/test-source', '/test-alias-Case');
|
||||
|
||||
$this->assertEquals('/test-source', $this->storage->lookupPathSource('/test-alias-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
$this->assertEquals('/test-source', $this->storage->lookupPathSource('/test-alias-case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
public function testAliasExists() {
|
||||
$this->storage->save('/test-source-Case', '/test-alias-Case');
|
||||
|
||||
$this->assertTrue($this->storage->aliasExists('/test-alias-Case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
$this->assertTrue($this->storage->aliasExists('/test-alias-case', LanguageInterface::LANGCODE_NOT_SPECIFIED));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
public function testLanguageAliasExists() {
|
||||
$this->assertFalse($this->storage->languageAliasExists());
|
||||
|
||||
$this->storage->save('/test-source-Case', '/test-alias-Case', 'en');
|
||||
$this->assertTrue($this->storage->languageAliasExists());
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
public function testGetAliasesForAdminListing() {
|
||||
$this->storage->save('/test-source-Case', '/test-alias-Case');
|
||||
$this->storage->save('/another-test', '/another-test-alias');
|
||||
|
||||
$expected_alias_1 = new \stdClass();
|
||||
$expected_alias_1->pid = '2';
|
||||
$expected_alias_1->source = '/another-test';
|
||||
$expected_alias_1->alias = '/another-test-alias';
|
||||
$expected_alias_1->langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
|
||||
|
||||
$expected_alias_2 = new \stdClass();
|
||||
$expected_alias_2->pid = '1';
|
||||
$expected_alias_2->source = '/test-source-Case';
|
||||
$expected_alias_2->alias = '/test-alias-Case';
|
||||
$expected_alias_2->langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
|
||||
|
||||
$header = [['field' => 'alias', 'sort' => 'asc']];
|
||||
$this->assertEquals([$expected_alias_1, $expected_alias_2], $this->storage->getAliasesForAdminListing($header));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
public function testPathHasMatchingAlias() {
|
||||
$this->storage->save('/test-source-Case', '/test-alias-Case');
|
||||
|
||||
$this->assertTrue($this->storage->pathHasMatchingAlias('/test'));
|
||||
$this->assertFalse($this->storage->pathHasMatchingAlias('/another'));
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ namespace Drupal\KernelTests\Core\Routing;
|
|||
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
|
@ -14,6 +15,8 @@ use Symfony\Component\HttpFoundation\Response;
|
|||
*/
|
||||
class ContentNegotiationRoutingTest extends KernelTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -46,13 +49,11 @@ class ContentNegotiationRoutingTest extends KernelTestBase {
|
|||
* Tests the content negotiation aspect of routing.
|
||||
*/
|
||||
public function testContentRouting() {
|
||||
/** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
|
||||
$path_alias_storage = $this->container->get('path.alias_storage');
|
||||
// Alias with extension pointing to no extension/constant content-type.
|
||||
$path_alias_storage->save('/conneg/html', '/alias.html');
|
||||
$this->createPathAlias('/conneg/html', '/alias.html');
|
||||
|
||||
// Alias with extension pointing to dynamic extension/linked content-type.
|
||||
$path_alias_storage->save('/conneg/html?_format=json', '/alias.json');
|
||||
$this->createPathAlias('/conneg/html?_format=json', '/alias.json');
|
||||
|
||||
$tests = [
|
||||
// ['path', 'accept', 'content-type'],
|
||||
|
|
|
@ -18,6 +18,7 @@ use Drupal\Core\State\State;
|
|||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\Core\Routing\RoutingFixtures;
|
||||
use Drupal\Tests\Traits\Core\PathAliasTestTrait;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
|
@ -32,6 +33,8 @@ use Symfony\Component\Routing\RouteCollection;
|
|||
*/
|
||||
class RouteProviderTest extends KernelTestBase {
|
||||
|
||||
use PathAliasTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*/
|
||||
|
@ -572,9 +575,7 @@ class RouteProviderTest extends KernelTestBase {
|
|||
$this->assertEqual(2, count($cache->data['routes']));
|
||||
|
||||
// A path with a path alias.
|
||||
/** @var \Drupal\Core\Path\AliasStorageInterface $path_storage */
|
||||
$path_storage = \Drupal::service('path.alias_storage');
|
||||
$path_storage->save('/path/add/one', '/path/add-one');
|
||||
$this->createPathAlias('/path/add/one', '/path/add-one');
|
||||
/** @var \Drupal\Core\Path\AliasManagerInterface $alias_manager */
|
||||
$alias_manager = \Drupal::service('path.alias_manager');
|
||||
$alias_manager->cacheClear();
|
||||
|
|
|
@ -5,11 +5,12 @@ namespace Drupal\Tests\Core\Path;
|
|||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Path\AliasManager;
|
||||
use Drupal\Core\Path\AliasRepositoryInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Path\AliasManager
|
||||
* @group Path
|
||||
* @group path
|
||||
*/
|
||||
class AliasManagerTest extends UnitTestCase {
|
||||
|
||||
|
@ -27,6 +28,13 @@ class AliasManagerTest extends UnitTestCase {
|
|||
*/
|
||||
protected $aliasStorage;
|
||||
|
||||
/**
|
||||
* Alias repository.
|
||||
*
|
||||
* @var \Drupal\Core\Path\AliasRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject
|
||||
*/
|
||||
protected $aliasRepository;
|
||||
|
||||
/**
|
||||
* Alias whitelist.
|
||||
*
|
||||
|
@ -68,12 +76,12 @@ class AliasManagerTest extends UnitTestCase {
|
|||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->aliasStorage = $this->createMock('Drupal\Core\Path\AliasStorageInterface');
|
||||
$this->aliasRepository = $this->createMock(AliasRepositoryInterface::class);
|
||||
$this->aliasWhitelist = $this->createMock('Drupal\Core\Path\AliasWhitelistInterface');
|
||||
$this->languageManager = $this->createMock('Drupal\Core\Language\LanguageManagerInterface');
|
||||
$this->cache = $this->createMock('Drupal\Core\Cache\CacheBackendInterface');
|
||||
|
||||
$this->aliasManager = new AliasManager($this->aliasStorage, $this->aliasWhitelist, $this->languageManager, $this->cache);
|
||||
$this->aliasManager = new AliasManager($this->aliasRepository, $this->aliasWhitelist, $this->languageManager, $this->cache);
|
||||
|
||||
}
|
||||
|
||||
|
@ -92,8 +100,8 @@ class AliasManagerTest extends UnitTestCase {
|
|||
->with(LanguageInterface::TYPE_URL)
|
||||
->will($this->returnValue($language));
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
->method('lookupPathSource')
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('lookupByAlias')
|
||||
->with($alias, $language->getId())
|
||||
->will($this->returnValue(NULL));
|
||||
|
||||
|
@ -113,10 +121,10 @@ class AliasManagerTest extends UnitTestCase {
|
|||
|
||||
$language = $this->setUpCurrentLanguage();
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
->method('lookupPathSource')
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('lookupByAlias')
|
||||
->with($alias, $language->getId())
|
||||
->will($this->returnValue($path));
|
||||
->will($this->returnValue(['path' => $path]));
|
||||
|
||||
$this->assertEquals($path, $this->aliasManager->getPathByAlias($alias));
|
||||
// Call it twice to test the static cache.
|
||||
|
@ -135,10 +143,10 @@ class AliasManagerTest extends UnitTestCase {
|
|||
$this->languageManager->expects($this->never())
|
||||
->method('getCurrentLanguage');
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
->method('lookupPathSource')
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('lookupByAlias')
|
||||
->with($alias, 'de')
|
||||
->will($this->returnValue($path));
|
||||
->will($this->returnValue(['path' => $path]));
|
||||
|
||||
$this->assertEquals($path, $this->aliasManager->getPathByAlias($alias, 'de'));
|
||||
// Call it twice to test the static cache.
|
||||
|
@ -164,8 +172,8 @@ class AliasManagerTest extends UnitTestCase {
|
|||
|
||||
// The whitelist returns FALSE for that path part, so the storage should
|
||||
// never be called.
|
||||
$this->aliasStorage->expects($this->never())
|
||||
->method('lookupPathAlias');
|
||||
$this->aliasRepository->expects($this->never())
|
||||
->method('lookupBySystemPath');
|
||||
|
||||
$this->assertEquals($path, $this->aliasManager->getAliasByPath($path));
|
||||
}
|
||||
|
@ -189,8 +197,8 @@ class AliasManagerTest extends UnitTestCase {
|
|||
->with($path_part1)
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
->method('lookupPathAlias')
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('lookupBySystemPath')
|
||||
->with($path, $language->getId())
|
||||
->will($this->returnValue(NULL));
|
||||
|
||||
|
@ -227,10 +235,10 @@ class AliasManagerTest extends UnitTestCase {
|
|||
->with($path_part1)
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
->method('lookupPathAlias')
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('lookupBySystemPath')
|
||||
->with($path, $language->getId())
|
||||
->will($this->returnValue($alias));
|
||||
->will($this->returnValue(['alias' => $alias]));
|
||||
|
||||
$this->assertEquals($alias, $this->aliasManager->getAliasByPath($path));
|
||||
// Call it twice to test the static cache.
|
||||
|
@ -272,14 +280,14 @@ class AliasManagerTest extends UnitTestCase {
|
|||
->with($path_part1)
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('preloadPathAlias')
|
||||
->with($cached_paths[$language->getId()], $language->getId())
|
||||
->will($this->returnValue([$path => $alias]));
|
||||
|
||||
// LookupPathAlias should not be called.
|
||||
$this->aliasStorage->expects($this->never())
|
||||
->method('lookupPathAlias');
|
||||
$this->aliasRepository->expects($this->never())
|
||||
->method('lookupBySystemPath');
|
||||
|
||||
$this->assertEquals($alias, $this->aliasManager->getAliasByPath($path));
|
||||
// Call it twice to test the static cache.
|
||||
|
@ -322,12 +330,12 @@ class AliasManagerTest extends UnitTestCase {
|
|||
|
||||
// The requested language is different than the cached, so this will
|
||||
// need to load.
|
||||
$this->aliasStorage->expects($this->never())
|
||||
$this->aliasRepository->expects($this->never())
|
||||
->method('preloadPathAlias');
|
||||
$this->aliasStorage->expects($this->once())
|
||||
->method('lookupPathAlias')
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('lookupBySystemPath')
|
||||
->with($path, $language->getId())
|
||||
->will($this->returnValue($alias));
|
||||
->will($this->returnValue(['alias' => $alias]));
|
||||
|
||||
$this->assertEquals($alias, $this->aliasManager->getAliasByPath($path));
|
||||
// Call it twice to test the static cache.
|
||||
|
@ -369,14 +377,14 @@ class AliasManagerTest extends UnitTestCase {
|
|||
->with($path_part1)
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('preloadPathAlias')
|
||||
->with($cached_paths[$language->getId()], $language->getId())
|
||||
->will($this->returnValue([$cached_path => $cached_alias]));
|
||||
|
||||
// LookupPathAlias() should not be called.
|
||||
$this->aliasStorage->expects($this->never())
|
||||
->method('lookupPathAlias');
|
||||
$this->aliasRepository->expects($this->never())
|
||||
->method('lookupBySystemPath');
|
||||
|
||||
$this->assertEquals($path, $this->aliasManager->getAliasByPath($path));
|
||||
// Call it twice to test the static cache.
|
||||
|
@ -417,13 +425,13 @@ class AliasManagerTest extends UnitTestCase {
|
|||
->with($path_part1)
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('preloadPathAlias')
|
||||
->with($cached_paths[$language->getId()], $language->getId())
|
||||
->will($this->returnValue([$cached_path => $cached_alias]));
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
->method('lookupPathAlias')
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('lookupBySystemPath')
|
||||
->with($path, $language->getId())
|
||||
->will($this->returnValue(NULL));
|
||||
|
||||
|
@ -445,10 +453,10 @@ class AliasManagerTest extends UnitTestCase {
|
|||
$path = '/path';
|
||||
$alias = '/alias';
|
||||
$language = $this->setUpCurrentLanguage();
|
||||
$this->aliasStorage->expects($this->exactly(2))
|
||||
->method('lookupPathAlias')
|
||||
$this->aliasRepository->expects($this->exactly(2))
|
||||
->method('lookupBySystemPath')
|
||||
->with($path, $language->getId())
|
||||
->willReturn($alias);
|
||||
->willReturn(['alias' => $alias]);
|
||||
$this->aliasWhitelist->expects($this->any())
|
||||
->method('get')
|
||||
->willReturn(TRUE);
|
||||
|
@ -457,9 +465,8 @@ class AliasManagerTest extends UnitTestCase {
|
|||
$this->assertEquals($alias, $this->aliasManager->getAliasByPath($path, $language->getId()));
|
||||
|
||||
// Check that the cache is populated.
|
||||
$original_storage = clone $this->aliasStorage;
|
||||
$this->aliasStorage->expects($this->never())
|
||||
->method('lookupPathSource');
|
||||
$this->aliasRepository->expects($this->never())
|
||||
->method('lookupByAlias');
|
||||
$this->assertEquals($path, $this->aliasManager->getPathByAlias($alias, $language->getId()));
|
||||
|
||||
// Clear specific source.
|
||||
|
@ -506,15 +513,15 @@ class AliasManagerTest extends UnitTestCase {
|
|||
->with($path_part1)
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('preloadPathAlias')
|
||||
->with($cached_paths[$language->getId()], $language->getId())
|
||||
->will($this->returnValue([$cached_path => $cached_alias]));
|
||||
|
||||
$this->aliasStorage->expects($this->once())
|
||||
->method('lookupPathAlias')
|
||||
$this->aliasRepository->expects($this->once())
|
||||
->method('lookupBySystemPath')
|
||||
->with($path, $language->getId())
|
||||
->will($this->returnValue($new_alias));
|
||||
->will($this->returnValue(['alias' => $new_alias]));
|
||||
|
||||
$this->assertEquals($new_alias, $this->aliasManager->getAliasByPath($path));
|
||||
// Call it twice to test the static cache.
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\Traits\Core;
|
||||
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
|
||||
/**
|
||||
* Provides methods to create and assert path_alias entities.
|
||||
*
|
||||
* This trait is meant to be used only by test classes.
|
||||
*/
|
||||
trait PathAliasTestTrait {
|
||||
|
||||
/**
|
||||
* Creates a new path alias.
|
||||
*
|
||||
* @param string $path
|
||||
* The system path.
|
||||
* @param string $alias
|
||||
* The alias for the system path.
|
||||
* @param string $langcode
|
||||
* (optional) A language code for the path alias. Defaults to
|
||||
* \Drupal\Core\Language\LanguageInterface::LANGCODE_NOT_SPECIFIED.
|
||||
*
|
||||
* @return \Drupal\Core\Path\PathAliasInterface
|
||||
* A path alias entity.
|
||||
*/
|
||||
protected function createPathAlias($path, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED) {
|
||||
/** @var \Drupal\Core\Path\PathAliasInterface $path_alias */
|
||||
$path_alias = \Drupal::entityTypeManager()->getStorage('path_alias')->create([
|
||||
'path' => $path,
|
||||
'alias' => $alias,
|
||||
'langcode' => $langcode,
|
||||
]);
|
||||
$path_alias->save();
|
||||
|
||||
return $path_alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first result from a 'load by properties' storage call.
|
||||
*
|
||||
* @param array $conditions
|
||||
* An array of query conditions.
|
||||
*
|
||||
* @return \Drupal\Core\Path\PathAliasInterface|null
|
||||
* A path alias entity or NULL.
|
||||
*/
|
||||
protected function loadPathAliasByConditions($conditions) {
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('path_alias');
|
||||
$query = $storage->getQuery();
|
||||
foreach ($conditions as $field => $value) {
|
||||
$query->condition($field, $value);
|
||||
}
|
||||
$entities = $storage->loadMultiple($query->execute());
|
||||
|
||||
return $entities ? reset($entities) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a path alias exists in the storage.
|
||||
*
|
||||
* @param string $alias
|
||||
* The path alias.
|
||||
* @param string|null $langcode
|
||||
* (optional) The language code of the path alias.
|
||||
* @param string|null $path
|
||||
* (optional) The system path of the path alias.
|
||||
* @param string|null $message
|
||||
* (optional) A message to display with the assertion.
|
||||
*/
|
||||
protected function assertPathAliasExists($alias, $langcode = NULL, $path = NULL, $message = NULL) {
|
||||
$query = \Drupal::entityTypeManager()->getStorage('path_alias')->getQuery();
|
||||
$query->condition('alias', $alias, '=');
|
||||
if ($langcode) {
|
||||
$query->condition('langcode', $langcode, '=');
|
||||
}
|
||||
if ($path) {
|
||||
$query->condition('path', $path, '=');
|
||||
}
|
||||
$query->count();
|
||||
|
||||
$this->assertTrue((bool) $query->execute(), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that a path alias does not exist in the storage.
|
||||
*
|
||||
* @param string $alias
|
||||
* The path alias.
|
||||
* @param string|null $langcode
|
||||
* (optional) The language code of the path alias.
|
||||
* @param string|null $path
|
||||
* (optional) The system path of the path alias.
|
||||
* @param string|null $message
|
||||
* (optional) A message to display with the assertion.
|
||||
*/
|
||||
protected function assertPathAliasNotExists($alias, $langcode = NULL, $path = NULL, $message = NULL) {
|
||||
$query = \Drupal::entityTypeManager()->getStorage('path_alias')->getQuery();
|
||||
$query->condition('alias', $alias, '=');
|
||||
if ($langcode) {
|
||||
$query->condition('langcode', $langcode, '=');
|
||||
}
|
||||
if ($path) {
|
||||
$query->condition('path', $path, '=');
|
||||
}
|
||||
$query->count();
|
||||
|
||||
$this->assertFalse((bool) $query->execute(), $message);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue