diff --git a/docroot/profiles/humsci/su_humsci_profile/su_humsci_profile.profile b/docroot/profiles/humsci/su_humsci_profile/su_humsci_profile.profile index d4bd1eef6..ee1dac6ab 100644 --- a/docroot/profiles/humsci/su_humsci_profile/su_humsci_profile.profile +++ b/docroot/profiles/humsci/su_humsci_profile/su_humsci_profile.profile @@ -18,11 +18,53 @@ use Drupal\config_pages\ConfigPagesInterface; use Drupal\menu_link_content\MenuLinkContentInterface; use Drupal\menu_position\Entity\MenuPositionRule; use Drupal\node\NodeInterface; +use Drupal\pathauto\PathautoPatternInterface; use Drupal\su_humsci_profile\HumsciCleanup; use Drupal\user\Entity\Role; use Drupal\user\RoleInterface; use Drupal\user\UserInterface; +/** + * Implements hook_pathauto_pattern_alter(). + */ +function su_humsci_profile_pathauto_pattern_alter(PathautoPatternInterface $pattern, array $context) { + // Only adjust node path aliases. + if ($context['module'] != 'node' || !isset($context['data']['node'])) { + return; + } + /** @var \Drupal\node\NodeInterface $node */ + $node = $context['data']['node']; + // If a node doesn't allow menu settings, we exit. + if (!isset($node->menu)) { + return; + } + $parent = explode(':', $node->menu['menu_parent']); + + // Make sure the parent menu item is a link content entity. The common form + // of the parent is `[menu_name]:[type]:[uuid]`. + if ( + count($parent) >= 3 && + $parent[0] == 'main' && + $parent[1] == 'menu_link_content' + ) { + $parent_menu_item = \Drupal::entityTypeManager() + ->getStorage('menu_link_content') + ->loadByProperties(['uuid' => $parent[2]]); + $parent_menu_item = reset($parent_menu_item); + $link_uri = $parent_menu_item->get('link') + ->get(0) + ->get('uri') + ->getString(); + + // If the parent menu item is a no-link, change the path alias pattern. + if ($link_uri == 'route:') { + $search = '[node:menu-link:parent:url:relative]'; + $replacement = '[node:menu-link:parents:join-path]'; + $pattern->setPattern(str_replace($search, $replacement, $pattern->getPattern())); + } + } +} + /** * Implements hook_entity_presave(). */ diff --git a/tests/codeception/acceptance/MenuItemsCest.php b/tests/codeception/acceptance/MenuItemsCest.php index 0b83ce145..d3fd7ff75 100644 --- a/tests/codeception/acceptance/MenuItemsCest.php +++ b/tests/codeception/acceptance/MenuItemsCest.php @@ -1,6 +1,7 @@ faker = Factory::create(); + } + + /** + * Cleanup menu links after the test. + */ + public function _after(AcceptanceTester $I) { + foreach ($this->menuLinks as $link) { + $link->delete(); + } + } + /** * Every main menu item should not error. */ @@ -21,6 +52,71 @@ public function testMenuItems(AcceptanceTester $I) { } } + /** + * Path auto settings should work correctly. + * + * @group pathauto + * @group install + */ + public function testPathAuto(AcceptanceTester $I) { + $url = parse_url($this->faker->url); + $manual_url = $url['path']; + + $I->logInWithRole('administrator'); + $auto_alias = $I->createEntity([ + 'title' => $this->faker->words(3, TRUE), + 'type' => 'hs_basic_page', + ]); + $I->amOnPage($auto_alias->toUrl('edit-form')->toString()); + $I->checkOption('Provide a menu link'); + $I->fillField('Menu link title', $auto_alias->label()); + $I->click('Save'); + $I->canSee($auto_alias->label(), 'h1'); + + $manual_alias = $I->createEntity([ + 'title' => $this->faker->words(3, TRUE), + 'type' => 'hs_basic_page', + ]); + $I->amOnPage($manual_alias->toUrl('edit-form')->toString()); + $I->checkOption('Provide a menu link'); + $I->fillField('Menu link title', $manual_alias->label()); + $I->uncheckOption('Generate automatic URL alias'); + $I->fillField('URL alias', $manual_url); + $I->click('Save'); + + $nolink = $I->createEntity([ + 'title' => 'Foo Bar', + 'link' => 'route:', + 'weight' => 0, + 'menu_name' => 'main', + ], 'menu_link_content'); + $this->menuLinks[] = $nolink; + + $node = $I->createEntity([ + 'title' => $this->faker->words(3, TRUE), + 'type' => 'hs_basic_page', + ]); + $I->amOnPage($node->toUrl('edit-form')->toString()); + $I->checkOption('Provide a menu link'); + $I->fillField('Menu link title', $node->label()); + $I->selectOption('Parent link', '-- ' . $auto_alias->label()); + $I->click('Change parent (update list of weights)'); + $I->click('Save'); + $I->canSeeInCurrentUrl($auto_alias->toUrl()->toString() . '/'); + + $I->amOnPage($node->toUrl('edit-form')->toString()); + $I->selectOption('Parent link', '-- ' . $manual_alias->label()); + $I->click('Change parent (update list of weights)'); + $I->click('Save'); + $I->canSeeInCurrentUrl($manual_alias->toUrl()->toString() . '/'); + + $I->amOnPage($node->toUrl('edit-form')->toString()); + $I->selectOption('Parent link', '-- ' . $nolink->label()); + $I->click('Change parent (update list of weights)'); + $I->click('Save'); + $I->canSeeInCurrentUrl('/foo-bar/'); + } + /** * Get all relative url paths to test. *