Commit 00797235 authored by Angie Byron's avatar Angie Byron
Browse files

Issue #2417837 by pwolanin, larowlan, dawehner, kgoel: Update menu link...

Issue #2417837 by pwolanin, larowlan, dawehner, kgoel: Update menu link definitions when aliases change
parent a2ad3487
Loading
Loading
Loading
Loading
+3 −0
Changes for core/modules/link/src/Plugin/Field/FieldType/LinkItem.php: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -81,6 +81,9 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
          'serialize' => TRUE,
        ),
      ),
      'indexes' => array(
        'uri' => array(array('uri', 30)),
      ),
    );
  }

+18 −0
Changes for core/modules/menu_link_content/menu_link_content.install: 18 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?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);
}
+47 −0
Changes for core/modules/menu_link_content/menu_link_content.module: 47 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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']);
}
+90 −0
Changes for core/modules/menu_link_content/src/Tests/PathAliasMenuLinkContentTest.php: 90 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?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());
  }

}