Skip to content
Snippets Groups Projects
Commit 27948b06 authored by catch's avatar catch
Browse files

Issue #3151086 by quietone, neclimdul, webchick, KapilV, alexpott, smustgrave:...

Issue #3151086 by quietone, neclimdul, webchick, KapilV, alexpott, smustgrave: Replace use of whitelist/blacklist in the path_alias module
parent 09613541
No related branches found
No related tags found
No related merge requests found
Showing
with 270 additions and 221 deletions
...@@ -65,9 +65,9 @@ public function testPathCache(): void { ...@@ -65,9 +65,9 @@ public function testPathCache(): void {
$this->submitForm($edit, 'Save'); $this->submitForm($edit, 'Save');
// Check the path alias whitelist cache. // Check the path alias whitelist cache.
$whitelist = \Drupal::cache('bootstrap')->get('path_alias_whitelist'); $prefix_list = \Drupal::cache('bootstrap')->get('path_alias_prefix_list');
$this->assertTrue($whitelist->data['node']); $this->assertTrue($prefix_list->data['node']);
$this->assertFalse($whitelist->data['admin']); $this->assertFalse($prefix_list->data['admin']);
// Visit the system path for the node and confirm a cache entry is // Visit the system path for the node and confirm a cache entry is
// created. // created.
......
...@@ -12,7 +12,7 @@ services: ...@@ -12,7 +12,7 @@ services:
arguments: ['@path_alias.manager'] arguments: ['@path_alias.manager']
path_alias.manager: path_alias.manager:
class: Drupal\path_alias\AliasManager class: Drupal\path_alias\AliasManager
arguments: ['@path_alias.repository', '@path_alias.whitelist', '@language_manager', '@cache.data', '@datetime.time'] arguments: ['@path_alias.repository', '@path_alias.prefix_list', '@language_manager', '@cache.data', '@datetime.time']
Drupal\path_alias\AliasManagerInterface: '@path_alias.manager' Drupal\path_alias\AliasManagerInterface: '@path_alias.manager'
path_alias.repository: path_alias.repository:
class: Drupal\path_alias\AliasRepository class: Drupal\path_alias\AliasRepository
...@@ -25,4 +25,11 @@ services: ...@@ -25,4 +25,11 @@ services:
tags: tags:
- { name: needs_destruction } - { name: needs_destruction }
arguments: [path_alias_whitelist, '@cache.bootstrap', '@lock', '@state', '@path_alias.repository'] arguments: [path_alias_whitelist, '@cache.bootstrap', '@lock', '@state', '@path_alias.repository']
deprecated: The "%service_id%" service is deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use the 'router.prefix_list' service instead. See https://www.drupal.org/node/3467559
Drupal\path_alias\AliasWhitelistInterface: '@path_alias.whitelist' Drupal\path_alias\AliasWhitelistInterface: '@path_alias.whitelist'
path_alias.prefix_list:
class: Drupal\path_alias\AliasPrefixList
tags:
- { name: needs_destruction }
arguments: [path_alias_prefix_list, '@cache.bootstrap', '@lock', '@state', '@path_alias.repository']
Drupal\path_alias\AliasPrefixListInterface: '@path_alias.prefix_list'
...@@ -66,7 +66,7 @@ class AliasManager implements AliasManagerInterface { ...@@ -66,7 +66,7 @@ class AliasManager implements AliasManagerInterface {
public function __construct( public function __construct(
protected AliasRepositoryInterface $pathAliasRepository, protected AliasRepositoryInterface $pathAliasRepository,
protected AliasWhitelistInterface $whitelist, protected AliasPrefixListInterface $pathPrefixes,
protected LanguageManagerInterface $languageManager, protected LanguageManagerInterface $languageManager,
protected CacheBackendInterface $cache, protected CacheBackendInterface $cache,
protected TimeInterface $time, protected TimeInterface $time,
...@@ -153,10 +153,10 @@ public function getAliasByPath($path, $langcode = NULL) { ...@@ -153,10 +153,10 @@ public function getAliasByPath($path, $langcode = NULL) {
// alias matching the URL path. // alias matching the URL path.
$langcode = $langcode ?: $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId(); $langcode = $langcode ?: $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId();
// Check the path whitelist, if the top-level part before the first / // Check the path prefix, if the top-level part before the first / is not in
// is not in the list, then there is no need to do anything further, // the list, then there is no need to do anything further, it is not in the
// it is not in the database. // database.
if ($path === '/' || !$this->whitelist->get(strtok(trim($path, '/'), '/'))) { if ($path === '/' || !$this->pathPrefixes->get(strtok(trim($path, '/'), '/'))) {
return $path; return $path;
} }
...@@ -230,24 +230,40 @@ public function cacheClear($source = NULL) { ...@@ -230,24 +230,40 @@ public function cacheClear($source = NULL) {
$this->noAlias = []; $this->noAlias = [];
$this->langcodePreloaded = []; $this->langcodePreloaded = [];
$this->preloadedPathLookups = []; $this->preloadedPathLookups = [];
$this->pathAliasWhitelistRebuild($source); $this->pathAliasPrefixListRebuild($source);
} }
/** /**
* Rebuild the path alias white list. * Rebuild the path alias prefix list.
* *
* @param string $path * @param string $path
* An optional path for which an alias is being inserted. * An optional path for which an alias is being inserted.
*/ */
protected function pathAliasWhitelistRebuild($path = NULL) { protected function pathAliasPrefixListRebuild($path = NULL) {
// When paths are inserted, only rebuild the whitelist if the path has a top // When paths are inserted, only rebuild the prefix list if the path has a top
// level component which is not already in the whitelist. // level component which is not already in the prefix list.
if (!empty($path)) { if (!empty($path)) {
if ($this->whitelist->get(strtok($path, '/'))) { if ($this->pathPrefixes->get(strtok($path, '/'))) {
return; return;
} }
} }
$this->whitelist->clear(); $this->pathPrefixes->clear();
}
/**
* Rebuild the path alias prefix list.
*
* @param string $path
* An optional path for which an alias is being inserted.
*
* @deprecated in drupal:11.1.0 and is removed from drupal:12.0.0.
* Use \Drupal\path_alias\AliasManager::pathAliasPrefixListRebuild instead.
*
* @see https://www.drupal.org/node/3467559
*/
protected function pathAliasWhitelistRebuild($path = NULL) {
@trigger_error(__METHOD__ . '() is deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use \Drupal\path_alias\AliasManager::pathAliasPrefixListRebuild() instead. See https://www.drupal.org/node/3467559', E_USER_DEPRECATED);
$this->pathAliasPrefixListRebuild($path);
} }
} }
...@@ -42,11 +42,11 @@ public function getPathByAlias($alias, $langcode = NULL); ...@@ -42,11 +42,11 @@ public function getPathByAlias($alias, $langcode = NULL);
public function getAliasByPath($path, $langcode = NULL); public function getAliasByPath($path, $langcode = NULL);
/** /**
* Clears the static caches in alias manager and rebuilds the whitelist. * Clears the static caches in alias manager and rebuilds the prefix list.
* *
* @param $source * @param $source
* Source path of the alias that is being inserted/updated. If omitted, the * Source path of the alias that is being inserted/updated. If omitted, the
* entire lookup static cache will be cleared and the whitelist will be * entire lookup static cache will be cleared and the prefix list will be
* rebuilt. * rebuilt.
*/ */
public function cacheClear($source = NULL); public function cacheClear($source = NULL);
......
<?php
namespace Drupal\path_alias;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheCollector;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\State\StateInterface;
/**
* Cache a list of valid alias prefixes.
*/
class AliasPrefixList extends CacheCollector implements AliasPrefixListInterface {
/**
* The Key/Value Store to use for state.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* The path alias repository.
*
* @var \Drupal\path_alias\AliasRepositoryInterface
*/
protected $pathAliasRepository;
/**
* Constructs an AliasPrefixList object.
*
* @param string $cid
* The cache id to use.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend.
* @param \Drupal\Core\Lock\LockBackendInterface $lock
* The lock backend.
* @param \Drupal\Core\State\StateInterface $state
* The state keyvalue store.
* @param \Drupal\path_alias\AliasRepositoryInterface $alias_repository
* The path alias repository.
*/
public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, StateInterface $state, AliasRepositoryInterface $alias_repository) {
parent::__construct($cid, $cache, $lock);
$this->state = $state;
$this->pathAliasRepository = $alias_repository;
}
/**
* {@inheritdoc}
*/
protected function lazyLoadCache() {
parent::lazyLoadCache();
// On a cold start $this->storage will be empty and the prefix list will
// need to be rebuilt from scratch. The prefix list is initialized from the
// list of all valid path roots stored in the 'router.path_roots' state,
// with values initialized to NULL. During the request, each path requested
// that matches one of these keys will be looked up and the array value set
// to either TRUE or FALSE. This ensures that paths which do not exist in
// the router are not looked up, and that paths that do exist in the router
// are only looked up once.
if (empty($this->storage)) {
$this->loadMenuPathRoots();
}
}
/**
* Loads menu path roots to prepopulate cache.
*/
protected function loadMenuPathRoots() {
if ($roots = $this->state->get('router.path_roots')) {
foreach ($roots as $root) {
$this->storage[$root] = NULL;
$this->persist($root);
}
}
}
/**
* {@inheritdoc}
*/
public function get($offset) {
$this->lazyLoadCache();
// This may be called with paths that are not represented by menu router
// items such as paths that will be rewritten by hook_url_outbound_alter().
// Therefore internally TRUE is used to indicate valid paths. FALSE is
// used to indicate paths that have already been checked but are not
// valid, and NULL indicates paths that have not been checked yet.
if (isset($this->storage[$offset])) {
if ($this->storage[$offset]) {
return TRUE;
}
}
elseif (array_key_exists($offset, $this->storage)) {
return $this->resolveCacheMiss($offset);
}
}
/**
* {@inheritdoc}
*/
public function resolveCacheMiss($root) {
$exists = $this->pathAliasRepository->pathHasMatchingAlias('/' . $root);
$this->storage[$root] = $exists;
$this->persist($root);
if ($exists) {
return TRUE;
}
}
/**
* {@inheritdoc}
*/
public function clear() {
parent::clear();
$this->loadMenuPathRoots();
}
}
<?php
namespace Drupal\path_alias;
use Drupal\Core\Cache\CacheCollectorInterface;
/**
* Cache a list of valid alias prefixes.
*
* The list contains the first element of the router paths of all aliases. For
* example, if /node/12345 has an alias then "node" is added to the prefix list.
* This optimization allows skipping the lookup for every /user/{user} path if
* "user" is not in the list.
*/
interface AliasPrefixListInterface extends CacheCollectorInterface {}
...@@ -2,119 +2,12 @@ ...@@ -2,119 +2,12 @@
namespace Drupal\path_alias; namespace Drupal\path_alias;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\CacheCollector;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\State\StateInterface;
/** /**
* Extends CacheCollector to build the path alias whitelist over time. * Cache a list of valid alias prefixes.
*
* @deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use
* \Drupal\path_alias\AliasPrefixList instead.
*
* @see https://www.drupal.org/node/3467559
*/ */
class AliasWhitelist extends CacheCollector implements AliasWhitelistInterface { class AliasWhitelist extends AliasPrefixList {}
/**
* The Key/Value Store to use for state.
*
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* The path alias repository.
*
* @var \Drupal\path_alias\AliasRepositoryInterface
*/
protected $pathAliasRepository;
/**
* Constructs an AliasWhitelist object.
*
* @param string $cid
* The cache id to use.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend.
* @param \Drupal\Core\Lock\LockBackendInterface $lock
* The lock backend.
* @param \Drupal\Core\State\StateInterface $state
* The state keyvalue store.
* @param \Drupal\path_alias\AliasRepositoryInterface $alias_repository
* The path alias repository.
*/
public function __construct($cid, CacheBackendInterface $cache, LockBackendInterface $lock, StateInterface $state, AliasRepositoryInterface $alias_repository) {
parent::__construct($cid, $cache, $lock);
$this->state = $state;
$this->pathAliasRepository = $alias_repository;
}
/**
* {@inheritdoc}
*/
protected function lazyLoadCache() {
parent::lazyLoadCache();
// On a cold start $this->storage will be empty and the whitelist will
// need to be rebuilt from scratch. The whitelist is initialized from the
// list of all valid path roots stored in the 'router.path_roots' state,
// with values initialized to NULL. During the request, each path requested
// that matches one of these keys will be looked up and the array value set
// to either TRUE or FALSE. This ensures that paths which do not exist in
// the router are not looked up, and that paths that do exist in the router
// are only looked up once.
if (empty($this->storage)) {
$this->loadMenuPathRoots();
}
}
/**
* Loads menu path roots to prepopulate cache.
*/
protected function loadMenuPathRoots() {
if ($roots = $this->state->get('router.path_roots')) {
foreach ($roots as $root) {
$this->storage[$root] = NULL;
$this->persist($root);
}
}
}
/**
* {@inheritdoc}
*/
public function get($offset) {
$this->lazyLoadCache();
// This may be called with paths that are not represented by menu router
// items such as paths that will be rewritten by hook_url_outbound_alter().
// Therefore internally TRUE is used to indicate whitelisted paths. FALSE is
// used to indicate paths that have already been checked but are not
// whitelisted, and NULL indicates paths that have not been checked yet.
if (isset($this->storage[$offset])) {
if ($this->storage[$offset]) {
return TRUE;
}
}
elseif (array_key_exists($offset, $this->storage)) {
return $this->resolveCacheMiss($offset);
}
}
/**
* {@inheritdoc}
*/
public function resolveCacheMiss($root) {
$exists = $this->pathAliasRepository->pathHasMatchingAlias('/' . $root);
$this->storage[$root] = $exists;
$this->persist($root);
if ($exists) {
return TRUE;
}
}
/**
* {@inheritdoc}
*/
public function clear() {
parent::clear();
$this->loadMenuPathRoots();
}
}
...@@ -2,14 +2,12 @@ ...@@ -2,14 +2,12 @@
namespace Drupal\path_alias; namespace Drupal\path_alias;
use Drupal\Core\Cache\CacheCollectorInterface;
/** /**
* Cache the alias whitelist. * Cache a list of valid alias prefixes.
*
* @deprecated in drupal:11.1.0 and is removed from drupal:12.0.0.
* Use \Drupal\path_alias\AliasPrefixListInterface instead.
* *
* The whitelist contains the first element of the router paths of all * @see https://www.drupal.org/node/3467559
* aliases. For example, if /node/12345 has an alias then "node" is added to
* the whitelist. This optimization allows skipping the lookup for every
* /user/{user} path if "user" is not in the whitelist.
*/ */
interface AliasWhitelistInterface extends CacheCollectorInterface {} interface AliasWhitelistInterface extends AliasPrefixListInterface {}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageInterface;
use Drupal\KernelTests\KernelTestBase; use Drupal\KernelTests\KernelTestBase;
use Drupal\path_alias\AliasManager; use Drupal\path_alias\AliasManager;
use Drupal\path_alias\AliasWhitelist; use Drupal\path_alias\AliasPrefixList;
use Drupal\Tests\Traits\Core\PathAliasTestTrait; use Drupal\Tests\Traits\Core\PathAliasTestTrait;
/** /**
...@@ -34,7 +34,7 @@ class AliasTest extends KernelTestBase { ...@@ -34,7 +34,7 @@ class AliasTest extends KernelTestBase {
protected function setUp(): void { protected function setUp(): void {
parent::setUp(); parent::setUp();
// The alias whitelist expects that the menu path roots are set by a // The alias prefix list expects that the menu path roots are set by a
// menu router rebuild. // menu router rebuild.
\Drupal::state()->set('router.path_roots', ['user', 'admin']); \Drupal::state()->set('router.path_roots', ['user', 'admin']);
...@@ -358,114 +358,114 @@ public function testLookupPath(): void { ...@@ -358,114 +358,114 @@ public function testLookupPath(): void {
} }
/** /**
* Tests the alias whitelist. * Tests the alias prefix.
*/ */
public function testWhitelist(): void { public function testPrefixList(): void {
$memoryCounterBackend = new MemoryCounterBackend(\Drupal::service(TimeInterface::class)); $memoryCounterBackend = new MemoryCounterBackend(\Drupal::service(TimeInterface::class));
// Create AliasManager and Path object. // Create AliasManager and Path object.
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository')); $prefix_list = new AliasPrefixList('path_alias_prefix_list', $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, $this->container->get(TimeInterface::class)); $aliasManager = new AliasManager($this->container->get('path_alias.repository'), $prefix_list, $this->container->get('language_manager'), $memoryCounterBackend, $this->container->get(TimeInterface::class));
// No alias for user and admin yet, so should be NULL. // No alias for user and admin yet, so should be NULL.
$this->assertNull($whitelist->get('user')); $this->assertNull($prefix_list->get('user'));
$this->assertNull($whitelist->get('admin')); $this->assertNull($prefix_list->get('admin'));
// Non-existing path roots should be NULL too. Use a length of 7 to avoid // Non-existing path roots should be NULL too. Use a length of 7 to avoid
// possible conflict with random aliases below. // possible conflict with random aliases below.
$this->assertNull($whitelist->get($this->randomMachineName())); $this->assertNull($prefix_list->get($this->randomMachineName()));
// Add an alias for user/1, user should get whitelisted now. // Add an alias for user/1, user should get cached now.
$this->createPathAlias('/user/1', '/' . $this->randomMachineName()); $this->createPathAlias('/user/1', '/' . $this->randomMachineName());
$aliasManager->cacheClear(); $aliasManager->cacheClear();
$this->assertTrue($whitelist->get('user')); $this->assertTrue($prefix_list->get('user'));
$this->assertNull($whitelist->get('admin')); $this->assertNull($prefix_list->get('admin'));
$this->assertNull($whitelist->get($this->randomMachineName())); $this->assertNull($prefix_list->get($this->randomMachineName()));
// Add an alias for admin, both should get whitelisted now. // Add an alias for admin, both should get cached now.
$this->createPathAlias('/admin/something', '/' . $this->randomMachineName()); $this->createPathAlias('/admin/something', '/' . $this->randomMachineName());
$aliasManager->cacheClear(); $aliasManager->cacheClear();
$this->assertTrue($whitelist->get('user')); $this->assertTrue($prefix_list->get('user'));
$this->assertTrue($whitelist->get('admin')); $this->assertTrue($prefix_list->get('admin'));
$this->assertNull($whitelist->get($this->randomMachineName())); $this->assertNull($prefix_list->get($this->randomMachineName()));
// Remove the user alias again, whitelist entry should be removed. // Remove the user alias again, prefix list entry should be removed.
$path_alias_storage = $this->container->get('entity_type.manager')->getStorage('path_alias'); $path_alias_storage = $this->container->get('entity_type.manager')->getStorage('path_alias');
$entities = $path_alias_storage->loadByProperties(['path' => '/user/1']); $entities = $path_alias_storage->loadByProperties(['path' => '/user/1']);
$path_alias_storage->delete($entities); $path_alias_storage->delete($entities);
$aliasManager->cacheClear(); $aliasManager->cacheClear();
$this->assertNull($whitelist->get('user')); $this->assertNull($prefix_list->get('user'));
$this->assertTrue($whitelist->get('admin')); $this->assertTrue($prefix_list->get('admin'));
$this->assertNull($whitelist->get($this->randomMachineName())); $this->assertNull($prefix_list->get($this->randomMachineName()));
// Destruct the whitelist so that the caches are written. // Destruct the prefix list so that the caches are written.
$whitelist->destruct(); $prefix_list->destruct();
$this->assertEquals(1, $memoryCounterBackend->getCounter('set', 'path_alias_whitelist')); $this->assertEquals(1, $memoryCounterBackend->getCounter('set', 'path_alias_prefix_list'));
$memoryCounterBackend->resetCounter(); $memoryCounterBackend->resetCounter();
// Re-initialize the whitelist using the same cache backend, should load // Re-initialize the prefix list using the same cache backend, should load
// from cache. // from cache.
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository')); $prefix_list = new AliasPrefixList('path_alias_prefix_list', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository'));
$this->assertNull($whitelist->get('user')); $this->assertNull($prefix_list->get('user'));
$this->assertTrue($whitelist->get('admin')); $this->assertTrue($prefix_list->get('admin'));
$this->assertNull($whitelist->get($this->randomMachineName())); $this->assertNull($prefix_list->get($this->randomMachineName()));
$this->assertEquals(1, $memoryCounterBackend->getCounter('get', 'path_alias_whitelist')); $this->assertEquals(1, $memoryCounterBackend->getCounter('get', 'path_alias_prefix_list'));
$this->assertEquals(0, $memoryCounterBackend->getCounter('set', 'path_alias_whitelist')); $this->assertEquals(0, $memoryCounterBackend->getCounter('set', 'path_alias_prefix_list'));
// Destruct the whitelist, should not attempt to write the cache again. // Destruct the prefix list, should not attempt to write the cache again.
$whitelist->destruct(); $prefix_list->destruct();
$this->assertEquals(1, $memoryCounterBackend->getCounter('get', 'path_alias_whitelist')); $this->assertEquals(1, $memoryCounterBackend->getCounter('get', 'path_alias_prefix_list'));
$this->assertEquals(0, $memoryCounterBackend->getCounter('set', 'path_alias_whitelist')); $this->assertEquals(0, $memoryCounterBackend->getCounter('set', 'path_alias_prefix_list'));
} }
/** /**
* Tests situation where the whitelist cache is deleted mid-request. * Tests situation where the prefix list cache is deleted mid-request.
*/ */
public function testWhitelistCacheDeletionMidRequest(): void { public function testPrefixListCacheDeletionMidRequest() {
$memoryCounterBackend = new MemoryCounterBackend(\Drupal::service(TimeInterface::class)); $memoryCounterBackend = new MemoryCounterBackend(\Drupal::service(TimeInterface::class));
// Create AliasManager and Path object. // Create AliasManager and Path object.
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository')); $prefix_list = new AliasPrefixList('path_alias_prefix_list', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository'));
// Whitelist cache should not exist at all yet. // Prefix list cache should not exist at all yet.
$this->assertFalse($memoryCounterBackend->get('path_alias_whitelist')); $this->assertFalse($memoryCounterBackend->get('path_alias_prefix_list'));
// Add some aliases for both menu routes we have. // Add some aliases for both menu routes we have.
$this->createPathAlias('/admin/something', '/' . $this->randomMachineName()); $this->createPathAlias('/admin/something', '/' . $this->randomMachineName());
$this->createPathAlias('/user/something', '/' . $this->randomMachineName()); $this->createPathAlias('/user/something', '/' . $this->randomMachineName());
// Lookup admin path in whitelist. It will query the DB and figure out // Lookup admin path in prefix list. It will query the DB and figure out
// that it indeed has an alias, and add it to the internal whitelist and // that it indeed has an alias, and add it to the internal prefix list and
// flag it to be persisted to cache. // flag it to be persisted to cache.
$this->assertTrue($whitelist->get('admin')); $this->assertTrue($prefix_list->get('admin'));
// Destruct the whitelist so it persists its cache. // Destruct the prefix list so it persists its cache.
$whitelist->destruct(); $prefix_list->destruct();
$this->assertEquals(1, $memoryCounterBackend->getCounter('set', 'path_alias_whitelist')); $this->assertEquals(1, $memoryCounterBackend->getCounter('set', 'path_alias_prefix_list'));
// Cache data should have data for 'user' and 'admin', even though just // Cache data should have data for 'user' and 'admin', even though just
// 'admin' was looked up. This is because the cache is primed with all // 'admin' was looked up. This is because the cache is primed with all
// menu router base paths. // menu router base paths.
$this->assertEquals(['user' => FALSE, 'admin' => TRUE], $memoryCounterBackend->get('path_alias_whitelist')->data); $this->assertEquals(['user' => FALSE, 'admin' => TRUE], $memoryCounterBackend->get('path_alias_prefix_list')->data);
$memoryCounterBackend->resetCounter(); $memoryCounterBackend->resetCounter();
// Re-initialize the whitelist and lookup an alias for the 'user' path. // Re-initialize the prefix list and lookup an alias for the 'user' path.
// Whitelist should load data from its cache, see that it hasn't done a // Prefix list 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 // check for 'user' yet, perform the check, then mark the result to be
// persisted to cache. // persisted to cache.
$whitelist = new AliasWhitelist('path_alias_whitelist', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository')); $prefix_list = new AliasPrefixList('path_alias_prefix_list', $memoryCounterBackend, $this->container->get('lock'), $this->container->get('state'), $this->container->get('path_alias.repository'));
$this->assertTrue($whitelist->get('user')); $this->assertTrue($prefix_list->get('user'));
// Delete the whitelist cache. This could happen from an outside process, // Delete the prefix list cache. This could happen from an outside process,
// like a code deployment that performs a cache rebuild. // like a code deployment that performs a cache rebuild.
$memoryCounterBackend->delete('path_alias_whitelist'); $memoryCounterBackend->delete('path_alias_prefix_list');
// Destruct whitelist so it attempts to save the whitelist data to cache. // Destruct prefix list so it attempts to save the prefix list data to
// However it should recognize that the previous cache entry was deleted // cache. However it should recognize that the previous cache entry was
// from underneath it and not save anything to cache, to protect from // deleted from underneath it and not save anything to cache, to protect
// cache corruption. // from cache corruption.
$whitelist->destruct(); $prefix_list->destruct();
$this->assertEquals(0, $memoryCounterBackend->getCounter('set', 'path_alias_whitelist')); $this->assertEquals(0, $memoryCounterBackend->getCounter('set', 'path_alias_prefix_list'));
$this->assertFalse($memoryCounterBackend->get('path_alias_whitelist')); $this->assertFalse($memoryCounterBackend->get('path_alias_prefix_list'));
$memoryCounterBackend->resetCounter(); $memoryCounterBackend->resetCounter();
} }
......
...@@ -32,11 +32,11 @@ class AliasManagerTest extends UnitTestCase { ...@@ -32,11 +32,11 @@ class AliasManagerTest extends UnitTestCase {
protected $aliasRepository; protected $aliasRepository;
/** /**
* Alias whitelist. * Alias prefix list.
* *
* @var \Drupal\path_alias\AliasWhitelistInterface|\PHPUnit\Framework\MockObject\MockObject * @var \Drupal\path_alias\AliasPrefixListInterface|\PHPUnit\Framework\MockObject\MockObject
*/ */
protected $aliasWhitelist; protected $aliasPrefixList;
/** /**
* Language manager. * Language manager.
...@@ -73,11 +73,11 @@ protected function setUp(): void { ...@@ -73,11 +73,11 @@ protected function setUp(): void {
parent::setUp(); parent::setUp();
$this->aliasRepository = $this->createMock(AliasRepositoryInterface::class); $this->aliasRepository = $this->createMock(AliasRepositoryInterface::class);
$this->aliasWhitelist = $this->createMock('Drupal\path_alias\AliasWhitelistInterface'); $this->aliasPrefixList = $this->createMock('Drupal\path_alias\AliasPrefixListInterface');
$this->languageManager = $this->createMock('Drupal\Core\Language\LanguageManagerInterface'); $this->languageManager = $this->createMock('Drupal\Core\Language\LanguageManagerInterface');
$this->cache = $this->createMock('Drupal\Core\Cache\CacheBackendInterface'); $this->cache = $this->createMock('Drupal\Core\Cache\CacheBackendInterface');
$this->aliasManager = new AliasManager($this->aliasRepository, $this->aliasWhitelist, $this->languageManager, $this->cache, new Time()); $this->aliasManager = new AliasManager($this->aliasRepository, $this->aliasPrefixList, $this->languageManager, $this->cache, new Time());
} }
...@@ -150,23 +150,23 @@ public function testGetPathByAliasLangcode(): void { ...@@ -150,23 +150,23 @@ public function testGetPathByAliasLangcode(): void {
} }
/** /**
* Tests the getAliasByPath method for a path that is not in the whitelist. * Tests the getAliasByPath method for a path that is not in the prefix list.
* *
* @covers ::getAliasByPath * @covers ::getAliasByPath
*/ */
public function testGetAliasByPathWhitelist(): void { public function testGetAliasByPathPrefixList() {
$path_part1 = $this->randomMachineName(); $path_part1 = $this->randomMachineName();
$path_part2 = $this->randomMachineName(); $path_part2 = $this->randomMachineName();
$path = '/' . $path_part1 . '/' . $path_part2; $path = '/' . $path_part1 . '/' . $path_part2;
$this->setUpCurrentLanguage(); $this->setUpCurrentLanguage();
$this->aliasWhitelist->expects($this->any()) $this->aliasPrefixList->expects($this->any())
->method('get') ->method('get')
->with($path_part1) ->with($path_part1)
->willReturn(FALSE); ->willReturn(FALSE);
// The whitelist returns FALSE for that path part, so the storage should // The prefix list returns FALSE for that path part, so the storage should
// never be called. // never be called.
$this->aliasRepository->expects($this->never()) $this->aliasRepository->expects($this->never())
->method('lookupBySystemPath'); ->method('lookupBySystemPath');
...@@ -188,7 +188,7 @@ public function testGetAliasByPathNoMatch(): void { ...@@ -188,7 +188,7 @@ public function testGetAliasByPathNoMatch(): void {
$this->aliasManager->setCacheKey($this->path); $this->aliasManager->setCacheKey($this->path);
$this->aliasWhitelist->expects($this->any()) $this->aliasPrefixList->expects($this->any())
->method('get') ->method('get')
->with($path_part1) ->with($path_part1)
->willReturn(TRUE); ->willReturn(TRUE);
...@@ -236,7 +236,7 @@ public function testGetAliasByPathMatch(): void { ...@@ -236,7 +236,7 @@ public function testGetAliasByPathMatch(): void {
$this->aliasManager->setCacheKey($this->path); $this->aliasManager->setCacheKey($this->path);
$this->aliasWhitelist->expects($this->any()) $this->aliasPrefixList->expects($this->any())
->method('get') ->method('get')
->with($path_part1) ->with($path_part1)
->willReturn(TRUE); ->willReturn(TRUE);
...@@ -288,7 +288,7 @@ public function testGetAliasByPathCachedMatch(): void { ...@@ -288,7 +288,7 @@ public function testGetAliasByPathCachedMatch(): void {
// Simulate a request so that the preloaded paths are fetched. // Simulate a request so that the preloaded paths are fetched.
$this->aliasManager->setCacheKey($this->path); $this->aliasManager->setCacheKey($this->path);
$this->aliasWhitelist->expects($this->any()) $this->aliasPrefixList->expects($this->any())
->method('get') ->method('get')
->with($path_part1) ->with($path_part1)
->willReturn(TRUE); ->willReturn(TRUE);
...@@ -336,7 +336,7 @@ public function testGetAliasByPathCachedMissLanguage(): void { ...@@ -336,7 +336,7 @@ public function testGetAliasByPathCachedMissLanguage(): void {
// Simulate a request so that the preloaded paths are fetched. // Simulate a request so that the preloaded paths are fetched.
$this->aliasManager->setCacheKey($this->path); $this->aliasManager->setCacheKey($this->path);
$this->aliasWhitelist->expects($this->any()) $this->aliasPrefixList->expects($this->any())
->method('get') ->method('get')
->with($path_part1) ->with($path_part1)
->willReturn(TRUE); ->willReturn(TRUE);
...@@ -385,7 +385,7 @@ public function testGetAliasByPathCachedMissNoAlias(): void { ...@@ -385,7 +385,7 @@ public function testGetAliasByPathCachedMissNoAlias(): void {
// Simulate a request so that the preloaded paths are fetched. // Simulate a request so that the preloaded paths are fetched.
$this->aliasManager->setCacheKey($this->path); $this->aliasManager->setCacheKey($this->path);
$this->aliasWhitelist->expects($this->any()) $this->aliasPrefixList->expects($this->any())
->method('get') ->method('get')
->with($path_part1) ->with($path_part1)
->willReturn(TRUE); ->willReturn(TRUE);
...@@ -433,7 +433,7 @@ public function testGetAliasByPathUncachedMissNoAlias(): void { ...@@ -433,7 +433,7 @@ public function testGetAliasByPathUncachedMissNoAlias(): void {
// Simulate a request so that the preloaded paths are fetched. // Simulate a request so that the preloaded paths are fetched.
$this->aliasManager->setCacheKey($this->path); $this->aliasManager->setCacheKey($this->path);
$this->aliasWhitelist->expects($this->any()) $this->aliasPrefixList->expects($this->any())
->method('get') ->method('get')
->with($path_part1) ->with($path_part1)
->willReturn(TRUE); ->willReturn(TRUE);
...@@ -470,7 +470,7 @@ public function testCacheClear(): void { ...@@ -470,7 +470,7 @@ public function testCacheClear(): void {
->method('lookupBySystemPath') ->method('lookupBySystemPath')
->with($path, $language->getId()) ->with($path, $language->getId())
->willReturn(['alias' => $alias]); ->willReturn(['alias' => $alias]);
$this->aliasWhitelist->expects($this->any()) $this->aliasPrefixList->expects($this->any())
->method('get') ->method('get')
->willReturn(TRUE); ->willReturn(TRUE);
...@@ -519,7 +519,7 @@ public function testGetAliasByPathUncachedMissWithAlias(): void { ...@@ -519,7 +519,7 @@ public function testGetAliasByPathUncachedMissWithAlias(): void {
// Simulate a request so that the preloaded paths are fetched. // Simulate a request so that the preloaded paths are fetched.
$this->aliasManager->setCacheKey($this->path); $this->aliasManager->setCacheKey($this->path);
$this->aliasWhitelist->expects($this->any()) $this->aliasPrefixList->expects($this->any())
->method('get') ->method('get')
->with($path_part1) ->with($path_part1)
->willReturn(TRUE); ->willReturn(TRUE);
......
...@@ -120,8 +120,8 @@ protected function testAnonymous(): void { ...@@ -120,8 +120,8 @@ protected function testAnonymous(): void {
'DELETE FROM "semaphore" WHERE ("name" = "theme_registry:runtime:stark:Drupal\Core\Utility\ThemeRegistry") AND ("value" = "LOCK_ID")', 'DELETE FROM "semaphore" WHERE ("name" = "theme_registry:runtime:stark:Drupal\Core\Utility\ThemeRegistry") AND ("value" = "LOCK_ID")',
'INSERT INTO "semaphore" ("name", "value", "expire") VALUES ("library_info:stark:Drupal\Core\Cache\CacheCollector", "LOCK_ID", "EXPIRE")', 'INSERT INTO "semaphore" ("name", "value", "expire") VALUES ("library_info:stark:Drupal\Core\Cache\CacheCollector", "LOCK_ID", "EXPIRE")',
'DELETE FROM "semaphore" WHERE ("name" = "library_info:stark:Drupal\Core\Cache\CacheCollector") AND ("value" = "LOCK_ID")', 'DELETE FROM "semaphore" WHERE ("name" = "library_info:stark:Drupal\Core\Cache\CacheCollector") AND ("value" = "LOCK_ID")',
'INSERT INTO "semaphore" ("name", "value", "expire") VALUES ("path_alias_whitelist:Drupal\Core\Cache\CacheCollector", "LOCK_ID", "EXPIRE")', 'INSERT INTO "semaphore" ("name", "value", "expire") VALUES ("path_alias_prefix_list:Drupal\Core\Cache\CacheCollector", "LOCK_ID", "EXPIRE")',
'DELETE FROM "semaphore" WHERE ("name" = "path_alias_whitelist:Drupal\Core\Cache\CacheCollector") AND ("value" = "LOCK_ID")', 'DELETE FROM "semaphore" WHERE ("name" = "path_alias_prefix_list:Drupal\Core\Cache\CacheCollector") AND ("value" = "LOCK_ID")',
]; ];
$recorded_queries = $performance_data->getQueries(); $recorded_queries = $performance_data->getQueries();
$this->assertSame($expected_queries, $recorded_queries); $this->assertSame($expected_queries, $recorded_queries);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment