Issue #2417837 by pwolanin, larowlan, dawehner, kgoel: Update menu link definitions when aliases change

8.0.x
webchick 2015-02-01 20:01:37 -08:00
parent a2ad34879c
commit 0079723571
4 changed files with 158 additions and 0 deletions

View File

@ -81,6 +81,9 @@ class LinkItem extends FieldItemBase implements LinkItemInterface {
'serialize' => TRUE,
),
),
'indexes' => array(
'uri' => array(array('uri', 30)),
),
);
}

View File

@ -0,0 +1,18 @@
<?php
/**
* @file
* Install, update and uninstall functions for the menu_link_content module.
*/
/**
* Implements hook_install().
*/
function menu_link_content_install() {
// Add a higher weight so that menu_link_content_path_update() is called after
// system_path_update() clears the path alias cache.
// @todo remove this when the cache clearing is moved to path module or if
// caching is removed for path aliases due to
// https://www.drupal.org/node/1965074
module_set_weight('menu_link_content', 1);
}

View File

@ -36,3 +36,50 @@ function menu_link_content_menu_delete(MenuInterface $menu) {
$menu_links = $storage->loadByProperties(array('menu_name' => $menu->id()));
$storage->delete($menu_links);
}
/**
* Implements hook_path_insert().
*/
function menu_link_content_path_insert($path) {
_menu_link_content_update_path_alias($path['alias']);
}
/**
* Helper function to update plugin definition using user-path scheme.
*
* @param string $path
* The path alias.
*
*/
function _menu_link_content_update_path_alias($path) {
/** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
// @todo Use link.uri once https://www.drupal.org/node/2391217 is in.
/** @var \Drupal\menu_link_content\MenuLinkContentInterface[] $entities */
$entities = \Drupal::entityManager()
->getStorage('menu_link_content')
->loadByProperties(['link__uri' => 'user-path:' . $path]);
foreach ($entities as $menu_link) {
$menu_link_manager->updateDefinition($menu_link->getPluginId(), $menu_link->getPluginDefinition(), FALSE);
}
}
/**
* Implements hook_path_update().
*/
function menu_link_content_path_update($path) {
if ($path['alias'] != $path['original']['alias']) {
_menu_link_content_update_path_alias($path['alias']);
_menu_link_content_update_path_alias($path['original']['alias']);
}
elseif ($path['source'] != $path['original']['source']) {
_menu_link_content_update_path_alias($path['alias']);
}
}
/**
* Implements hook_path_delete().
*/
function menu_link_content_path_delete($path) {
_menu_link_content_update_path_alias($path['alias']);
}

View File

@ -0,0 +1,90 @@
<?php
/**
* @file
* Contains \Drupal\menu_link_content\Tests\PathAliasMenuLinkContentTest.
*/
namespace Drupal\menu_link_content\Tests;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\menu_link_content\Entity\MenuLinkContent;
use Drupal\simpletest\KernelTestBase;
/**
* Ensures that the menu tree adapts to path alias changes.
*
* @group menu_link_content
*/
class PathAliasMenuLinkContentTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['menu_link_content', 'system', 'link', 'test_page_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('menu_link_content');
$this->installSchema('system', ['url_alias', 'router']);
// Ensure that the weight of module_link_content is higher than system.
// @see menu_link_content_install()
module_set_weight('menu_link_content', 1);
}
/**
* {@inheritdoc}
*/
public function containerBuild(ContainerBuilder $container) {
parent::containerBuild($container);
$definition = $container->getDefinition('path_processor_alias');
$definition
->addTag('path_processor_inbound', ['priority' => 100]);
}
/**
* Tests the path aliasing changing.
*/
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'];
$menu_link_content = MenuLinkContent::create([
'title' => 'Menu title',
'link' => ['uri' => 'user-path:my-blog'],
'menu_name' => 'tools',
]);
$menu_link_content->save();
$tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters());
$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);
$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]);
$tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters());
$this->assertTrue(isset($tree[$menu_link_content->getPluginId()]));
$this->assertEqual('', $tree[$menu_link_content->getPluginId()]->link->getRouteName());
// Verify the plugin now references a path that does not match any route.
$this->assertEqual('base:my-blog', $tree[$menu_link_content->getPluginId()]->link->getUrlObject()->getUri());
}
}