diff --git a/pathauto.services.yml b/pathauto.services.yml index 748de19..3d3a760 100644 --- a/pathauto.services.yml +++ b/pathauto.services.yml @@ -10,7 +10,7 @@ services: arguments: ['@config.factory', '@path.alias_storage', '@database','@pathauto.verbose_messenger', '@string_translation'] pathauto.alias_uniquifier: class: Drupal\pathauto\AliasUniquifier - arguments: ['@config.factory', '@pathauto.alias_storage_helper','@module_handler', '@router.no_access_checks', '@path.alias_manager'] + arguments: ['@config.factory', '@pathauto.alias_storage_helper','@module_handler', '@router.route_provider', '@path.alias_manager'] pathauto.verbose_messenger: class: Drupal\pathauto\VerboseMessenger arguments: ['@config.factory', '@current_user'] diff --git a/src/AliasUniquifier.php b/src/AliasUniquifier.php index 902a03e..98ac166 100644 --- a/src/AliasUniquifier.php +++ b/src/AliasUniquifier.php @@ -12,9 +12,7 @@ use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Path\AliasManagerInterface; -use Drupal\Core\Path\AliasStorageInterface; -use Symfony\Component\Routing\Exception\ResourceNotFoundException; -use Symfony\Component\Routing\Matcher\UrlMatcherInterface; +use Drupal\Core\Routing\RouteProviderInterface; /** * Provides a utility for creating a unique path alias. @@ -43,11 +41,11 @@ class AliasUniquifier implements AliasUniquifierInterface { protected $moduleHandler; /** - * The url matcher service. + * The route provider service. * - * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface + * @var \Drupal\Core\Routing\RouteProviderInterface. */ - protected $urlMatcher; + protected $routeProvider; /** * The alias manager. @@ -57,15 +55,6 @@ class AliasUniquifier implements AliasUniquifierInterface { protected $aliasManager; /** - * Stores the last matching route name. - * - * Used to prevent a loop if the same route matches a given pattern. - * - * @var - */ - protected $lastRouteName; - - /** * Creates a new AliasUniquifier. * * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory @@ -74,14 +63,14 @@ class AliasUniquifier implements AliasUniquifierInterface { * The alias storage helper. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. - * @param \Symfony\Component\Routing\Matcher\UrlMatcherInterface $url_matcher - * The url matcher service. + * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider + * The route provider service. */ - public function __construct(ConfigFactoryInterface $config_factory, AliasStorageHelperInterface $alias_storage_helper, ModuleHandlerInterface $module_handler, UrlMatcherInterface $url_matcher, AliasManagerInterface $alias_manager) { + public function __construct(ConfigFactoryInterface $config_factory, AliasStorageHelperInterface $alias_storage_helper, ModuleHandlerInterface $module_handler, RouteProviderInterface $route_provider, AliasManagerInterface $alias_manager) { $this->configFactory = $config_factory; $this->aliasStorageHelper = $alias_storage_helper; $this->moduleHandler = $module_handler; - $this->urlMatcher = $url_matcher; + $this->routeProvider = $route_provider; $this->aliasManager = $alias_manager; } @@ -167,20 +156,17 @@ class AliasUniquifier implements AliasUniquifierInterface { return TRUE; } - try { - $route = $this->urlMatcher->match($path); + $routes = $this->routeProvider->getRoutesByPattern($path); - if ($route['_route'] == $this->lastRouteName) { - throw new \InvalidArgumentException('The path "' . $path . '" collides with the route with identifier ' . $this->lastRouteName . ', whose path is ' . $route['_route_object']->getPath()); + // Only return true for an exact match, ignore placeholders. + foreach ($routes as $route) { + if ($route->getPath() == $path) { + return TRUE; } - - $this->lastRouteName = $route['_route']; - return TRUE; - } - catch (ResourceNotFoundException $e) { - $this->lastRouteName = NULL; - return FALSE; } + + return FALSE; + } } diff --git a/src/Tests/PathautoLocaleTest.php b/src/Tests/PathautoLocaleTest.php index 7ec7c78..ba1e3c7 100644 --- a/src/Tests/PathautoLocaleTest.php +++ b/src/Tests/PathautoLocaleTest.php @@ -83,9 +83,9 @@ class PathautoLocaleTest extends WebTestBase { // specifying a language. $node = $this->drupalCreateNode(array('title' => 'English node', 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED)); - // Check that the new node had a unique alias generated with the '-1' + // Check that the new node had a unique alias generated with the '-0' // suffix. - $this->assertEntityAlias($node, '/content/english-node-1', LanguageInterface::LANGCODE_NOT_SPECIFIED); + $this->assertEntityAlias($node, '/content/english-node-0', LanguageInterface::LANGCODE_NOT_SPECIFIED); } /** diff --git a/src/Tests/PathautoNodeWebTest.php b/src/Tests/PathautoNodeWebTest.php index 825b679..9ab37ec 100644 --- a/src/Tests/PathautoNodeWebTest.php +++ b/src/Tests/PathautoNodeWebTest.php @@ -285,28 +285,4 @@ class PathautoNodeWebTest extends WebTestBase { $this->assertResponse(200); } - /** - * Tests that patterns can coexist with routes with arguments. - * - * A common case is to have a view with a term name as a contextual filter, - * and a pattern that matches the view's path. - */ - public function testPatternMatchingDynamicRoute() { - $this->drupalLogin($this->rootUser); - - // Create a pattern for nodes that matches with a view path defined at - // pathauto_views_test module. - $this->createPattern('node', '/articles/[node:title]', -1); - - // Create an article. - $edit = array( - 'title[0][value]' => 'Sample article', - ); - $this->drupalPostForm('node/add/article', $edit, t('Save and publish')); - - // Check that the alias was not created and an alert was shown. - $this->assertText('collides with the route with identifier'); - $this->assertNoAliasExists(array('alias' => '/articles/sample-article')); - } - } diff --git a/tests/src/Kernel/PathautoKernelTest.php b/tests/src/Kernel/PathautoKernelTest.php index 42e29c2..40c12f2 100644 --- a/tests/src/Kernel/PathautoKernelTest.php +++ b/tests/src/Kernel/PathautoKernelTest.php @@ -165,6 +165,29 @@ class PathautoKernelTest extends KernelTestBase { } /** + * Test potential conflicts with the same alias in different languages. + */ + public function testSameTitleDifferentLanguages() { + // Create two English articles with the same title. + $edit = [ + 'title' => 'Sample page', + 'type' => 'page', + 'langcode' => 'en', + ]; + $node1 = $this->drupalCreateNode($edit); + $this->assertEntityAlias($node1, '/content/sample-page', 'en'); + + $node2 = $this->drupalCreateNode($edit); + $this->assertEntityAlias($node2, '/content/sample-page-0', 'en'); + + // Now, create a French article with the same title, and verify that it gets + // the basic alias with the correct langcode. + $edit['langcode'] = 'fr'; + $node3 = $this->drupalCreateNode($edit); + $this->assertEntityAlias($node3, '/content/sample-page', 'fr'); + } + + /** * Test pathauto_cleanstring(). */ public function testCleanString() {