Issue #2417647 by Wim Leers, effulgentsia: Add leading slash to paths within 'user-path:' URIs, to allow 'user-path:' URIs to point to the <none> route
parent
7c05a8b5db
commit
d5304a46c6
|
@ -34,7 +34,7 @@ class ConfirmFormHelper {
|
|||
// If a destination is specified, that serves as the cancel link.
|
||||
if ($query->has('destination')) {
|
||||
$options = UrlHelper::parse($query->get('destination'));
|
||||
$url = Url::fromUri('user-path:' . $options['path'], $options);
|
||||
$url = Url::fromUri('user-path:/' . $options['path'], $options);
|
||||
}
|
||||
// Check for a route-based cancel link.
|
||||
else {
|
||||
|
|
|
@ -109,6 +109,9 @@ class PathValidator implements PathValidatorInterface {
|
|||
if ($parsed_url['path'] == '<front>') {
|
||||
return new Url('<front>', [], $options);
|
||||
}
|
||||
elseif ($parsed_url['path'] == '<none>') {
|
||||
return new Url('<none>', [], $options);
|
||||
}
|
||||
elseif (UrlHelper::isExternal($path) && UrlHelper::isValid($path)) {
|
||||
if (empty($parsed_url['path'])) {
|
||||
return FALSE;
|
||||
|
|
|
@ -319,6 +319,33 @@ class Url {
|
|||
/**
|
||||
* Creates a new Url object for 'user-path:' URIs.
|
||||
*
|
||||
* Important note: the URI minus the scheme can NOT simply be validated by a
|
||||
* \Drupal\Core\Path\PathValidatorInterface implementation. The semantics of
|
||||
* the 'user-path:' URI scheme are different:
|
||||
* - PathValidatorInterface accepts paths without a leading slash (e.g.
|
||||
* 'node/add') as well as 2 special paths: '<front>' and '<none>', which are
|
||||
* mapped to the correspondingly named routes.
|
||||
* - 'user-path:' URIs store paths with a leading slash that represents the
|
||||
* root — i.e. the front page — (e.g. 'user-path:/node/add'), and doesn't
|
||||
* have any exceptions.
|
||||
*
|
||||
* To clarify, a few examples of path plus corresponding 'user-path:' URI:
|
||||
* - 'node/add' -> 'user-path:/node/add'
|
||||
* - 'node/add?foo=bar' -> 'user-path:/node/add?foo=bar'
|
||||
* - 'node/add#kitten' -> 'user-path:/node/add#kitten'
|
||||
* - '<front>' -> 'user-path:/'
|
||||
* - '<front>foo=bar' -> 'user-path:/?foo=bar'
|
||||
* - '<front>#kitten' -> 'user-path:/#kitten'
|
||||
* - '<none>' -> 'user-path:'
|
||||
* - '<none>foo=bar' -> 'user-path:?foo=bar'
|
||||
* - '<none>#kitten' -> 'user-path:#kitten'
|
||||
*
|
||||
* Therefore, when using a PathValidatorInterface to validate 'user-path:'
|
||||
* URIs, we must map:
|
||||
* - 'user-path:' (path component is '') to the special '<none>' path
|
||||
* - 'user-path:/' (path component is '/') to the special '<front>' path
|
||||
* - 'user-path:/some-path' (path component is '/some-path') to 'some-path'
|
||||
*
|
||||
* @param array $uri_parts
|
||||
* Parts from an URI of the form user-path:{path} as from parse_url().
|
||||
* @param array $options
|
||||
|
@ -328,6 +355,21 @@ class Url {
|
|||
* A new Url object for a 'user-path:' URI.
|
||||
*/
|
||||
protected static function fromUserPathUri(array $uri_parts, array $options) {
|
||||
// Both PathValidator::getUrlIfValidWithoutAccessCheck() and 'base:' URIs
|
||||
// only accept/contain paths without a leading slash, unlike 'user-path:'
|
||||
// URIs, for which the leading slash means "relative to Drupal root" and
|
||||
// "relative to Symfony app root" (just like in Symfony/Drupal 8 routes).
|
||||
if (empty($uri_parts['path'])) {
|
||||
$uri_parts['path'] = '<none>';
|
||||
}
|
||||
elseif ($uri_parts['path'] === '/') {
|
||||
$uri_parts['path'] = '<front>';
|
||||
}
|
||||
else {
|
||||
// Remove the leading slash.
|
||||
$uri_parts['path'] = substr($uri_parts['path'], 1);
|
||||
}
|
||||
|
||||
$url = \Drupal::pathValidator()
|
||||
->getUrlIfValidWithoutAccessCheck($uri_parts['path']) ?: static::fromUri('base:' . $uri_parts['path'], $options);
|
||||
// Allow specifying additional options.
|
||||
|
|
|
@ -61,7 +61,7 @@ class FieldUI {
|
|||
$options['query']['destinations'] = $destinations;
|
||||
}
|
||||
// Redirect to any given path within the same domain.
|
||||
$next_destination = Url::fromUri('user-path:' . $options['path']);
|
||||
$next_destination = Url::fromUri('user-path:/' . $options['path']);
|
||||
}
|
||||
return $next_destination;
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ class LinkFormatter extends FormatterBase implements ContainerFactoryPluginInter
|
|||
// attribute.
|
||||
// @todo Does RDF need a URL rather than an internal URI here?
|
||||
// @see \Drupal\rdf\Tests\Field\LinkFieldRdfaTest.
|
||||
$content = str_replace('user-path:', '', $item->uri);
|
||||
$content = str_replace('user-path:/', '', $item->uri);
|
||||
$item->_attributes += array('content' => $content);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,20 @@ class LinkWidget extends WidgetBase {
|
|||
$scheme = parse_url($uri, PHP_URL_SCHEME);
|
||||
if ($scheme === 'user-path') {
|
||||
$uri_reference = explode(':', $uri, 2)[1];
|
||||
// @todo Present the leading slash to the user and hence delete the next
|
||||
// block in https://www.drupal.org/node/2418017. There, we will also
|
||||
// remove the ability to enter '<front>' or '<none>', we'll expect '/'
|
||||
// and '' instead respectively.
|
||||
$path = parse_url($uri, PHP_URL_PATH);
|
||||
if ($path === '/') {
|
||||
$uri_reference = '<front>' . substr($uri_reference, 1);
|
||||
}
|
||||
elseif (empty($path)) {
|
||||
$uri_reference = '<none>' . $uri_reference;
|
||||
}
|
||||
else {
|
||||
$uri_reference = ltrim($uri_reference, '/');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$uri_reference = $uri;
|
||||
|
@ -76,6 +90,31 @@ class LinkWidget extends WidgetBase {
|
|||
// Users can enter relative URLs, but we need a valid URI, so add an
|
||||
// explicit scheme when necessary.
|
||||
if (parse_url($string, PHP_URL_SCHEME) === NULL) {
|
||||
// @todo Present the leading slash to the user and hence delete the next
|
||||
// block in https://www.drupal.org/node/2418017. There, we will also
|
||||
// remove the ability to enter '<front>' or '<none>', we'll expect '/'
|
||||
// and '' instead respectively.
|
||||
// Users can enter paths that don't start with a leading slash, we
|
||||
// want to normalize them to have a leading slash. However, we don't
|
||||
// want to add a leading slash if it already starts with one, or if it
|
||||
// contains only a querystring or a fragment. Examples:
|
||||
// - 'foo' -> '/foo'
|
||||
// - '?foo=bar' -> '/?foo=bar'
|
||||
// - '#foo' -> '/#foo'
|
||||
// - '<front>' -> '/'
|
||||
// - '<front>#foo' -> '/#foo'
|
||||
// - '<none>' -> ''
|
||||
// - '<none>#foo' -> '#foo'
|
||||
if (strpos($string, '<front>') === 0) {
|
||||
$string = '/' . substr($string, strlen('<front>'));
|
||||
}
|
||||
elseif (strpos($string, '<none>') === 0) {
|
||||
$string = substr($string, strlen('<none>'));
|
||||
}
|
||||
elseif (!in_array($string[0], ['/', '?', '#'])) {
|
||||
$string = '/' . $string;
|
||||
}
|
||||
|
||||
return 'user-path:' . $string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ function _menu_link_content_update_path_alias($path) {
|
|||
/** @var \Drupal\menu_link_content\MenuLinkContentInterface[] $entities */
|
||||
$entities = \Drupal::entityManager()
|
||||
->getStorage('menu_link_content')
|
||||
->loadByProperties(['link__uri' => 'user-path:' . $path]);
|
||||
->loadByProperties(['link__uri' => 'user-path:/' . $path]);
|
||||
foreach ($entities as $menu_link) {
|
||||
$menu_link_manager->updateDefinition($menu_link->getPluginId(), $menu_link->getPluginDefinition(), FALSE);
|
||||
}
|
||||
|
|
|
@ -67,14 +67,14 @@ class LinksTest extends WebTestBase {
|
|||
);
|
||||
|
||||
$parent = $base_options + array(
|
||||
'link' => ['uri' => 'user-path:menu-test/hierarchy/parent'],
|
||||
'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent'],
|
||||
);
|
||||
$link = entity_create('menu_link_content', $parent);
|
||||
$link->save();
|
||||
$links['parent'] = $link->getPluginId();
|
||||
|
||||
$child_1 = $base_options + array(
|
||||
'link' => ['uri' => 'user-path:menu-test/hierarchy/parent/child'],
|
||||
'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent/child'],
|
||||
'parent' => $links['parent'],
|
||||
);
|
||||
$link = entity_create('menu_link_content', $child_1);
|
||||
|
@ -82,7 +82,7 @@ class LinksTest extends WebTestBase {
|
|||
$links['child-1'] = $link->getPluginId();
|
||||
|
||||
$child_1_1 = $base_options + array(
|
||||
'link' => ['uri' => 'user-path:menu-test/hierarchy/parent/child2/child'],
|
||||
'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent/child2/child'],
|
||||
'parent' => $links['child-1'],
|
||||
);
|
||||
$link = entity_create('menu_link_content', $child_1_1);
|
||||
|
@ -90,7 +90,7 @@ class LinksTest extends WebTestBase {
|
|||
$links['child-1-1'] = $link->getPluginId();
|
||||
|
||||
$child_1_2 = $base_options + array(
|
||||
'link' => ['uri' => 'user-path:menu-test/hierarchy/parent/child2/child'],
|
||||
'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent/child2/child'],
|
||||
'parent' => $links['child-1'],
|
||||
);
|
||||
$link = entity_create('menu_link_content', $child_1_2);
|
||||
|
@ -98,7 +98,7 @@ class LinksTest extends WebTestBase {
|
|||
$links['child-1-2'] = $link->getPluginId();
|
||||
|
||||
$child_2 = $base_options + array(
|
||||
'link' => ['uri' => 'user-path:menu-test/hierarchy/parent/child'],
|
||||
'link' => ['uri' => 'user-path:/menu-test/hierarchy/parent/child'],
|
||||
'parent' => $links['parent'],
|
||||
);
|
||||
$link = entity_create('menu_link_content', $child_2);
|
||||
|
@ -128,7 +128,7 @@ class LinksTest extends WebTestBase {
|
|||
$options = array(
|
||||
'menu_name' => 'menu_test',
|
||||
'bundle' => 'menu_link_content',
|
||||
'link' => [['uri' => 'user-path:<front>']],
|
||||
'link' => [['uri' => 'user-path:/']],
|
||||
);
|
||||
$link = entity_create('menu_link_content', $options);
|
||||
$link->save();
|
||||
|
|
|
@ -46,7 +46,7 @@ class MenuLinkContentDeriverTest extends KernelTestBase {
|
|||
// Set up a custom menu link pointing to a specific path.
|
||||
MenuLinkContent::create([
|
||||
'title' => 'Example',
|
||||
'link' => [['uri' => 'user-path:example-path']],
|
||||
'link' => [['uri' => 'user-path:/example-path']],
|
||||
'menu_name' => 'tools',
|
||||
])->save();
|
||||
$menu_tree = \Drupal::menuTree()->load('tools', new MenuTreeParameters());
|
||||
|
|
|
@ -57,7 +57,7 @@ class MenuLinkContentUITest extends ContentTranslationUITest {
|
|||
*/
|
||||
protected function createEntity($values, $langcode, $bundle_name = NULL) {
|
||||
$values['menu_name'] = 'tools';
|
||||
$values['link']['uri'] = 'user-path:admin/structure/menu';
|
||||
$values['link']['uri'] = 'user-path:/admin/structure/menu';
|
||||
$values['title'] = 'Test title';
|
||||
|
||||
return parent::createEntity($values, $langcode, $bundle_name);
|
||||
|
@ -70,7 +70,7 @@ class MenuLinkContentUITest extends ContentTranslationUITest {
|
|||
$this->drupalGet('admin/structure/menu/manage/tools');
|
||||
$this->assertNoLink(t('Translate'));
|
||||
|
||||
$menu_link_content = MenuLinkContent::create(['menu_name' => 'tools', 'link' => ['uri' => 'user-path:admin/structure/menu']]);
|
||||
$menu_link_content = MenuLinkContent::create(['menu_name' => 'tools', 'link' => ['uri' => 'user-path:/admin/structure/menu']]);
|
||||
$menu_link_content->save();
|
||||
$this->drupalGet('admin/structure/menu/manage/tools');
|
||||
$this->assertLink(t('Translate'));
|
||||
|
|
|
@ -64,7 +64,7 @@ class PathAliasMenuLinkContentTest extends KernelTestBase {
|
|||
|
||||
$menu_link_content = MenuLinkContent::create([
|
||||
'title' => 'Menu title',
|
||||
'link' => ['uri' => 'user-path:my-blog'],
|
||||
'link' => ['uri' => 'user-path:/my-blog'],
|
||||
'menu_name' => 'tools',
|
||||
]);
|
||||
$menu_link_content->save();
|
||||
|
|
|
@ -83,7 +83,7 @@ class MenuCacheTagsTest extends PageCacheTagsTestBase {
|
|||
'title' => 'Alpaca',
|
||||
'menu_name' => 'llama',
|
||||
'link' => [[
|
||||
'uri' => 'user-path:<front>',
|
||||
'uri' => 'user-path:/',
|
||||
]],
|
||||
'bundle' => 'menu_name',
|
||||
));
|
||||
|
|
|
@ -105,8 +105,8 @@ class MenuTest extends MenuWebTestBase {
|
|||
$this->verifyAccess(403);
|
||||
|
||||
foreach ($this->items as $item) {
|
||||
// Paths were set as 'node/$nid'.
|
||||
$node = Node::load(str_replace('user-path:node/', '', $item->link->uri));
|
||||
// Menu link URIs are stored as 'user-path:/node/$nid'.
|
||||
$node = Node::load(str_replace('user-path:/node/', '', $item->link->uri));
|
||||
$this->verifyMenuLink($item, $node);
|
||||
}
|
||||
|
||||
|
@ -640,7 +640,7 @@ class MenuTest extends MenuWebTestBase {
|
|||
* Attempts to add menu link with invalid path or no access permission.
|
||||
*/
|
||||
function addInvalidMenuLink() {
|
||||
foreach (array('-&-', 'admin/people/permissions', '#') as $link_path) {
|
||||
foreach (array('-&-', 'admin/people/permissions') as $link_path) {
|
||||
$edit = array(
|
||||
'link[0][uri]' => $link_path,
|
||||
'title[0][value]' => 'title',
|
||||
|
|
|
@ -27,7 +27,7 @@ class UserPathUri extends ProcessPluginBase {
|
|||
list($path) = $value;
|
||||
|
||||
if (parse_url($path, PHP_URL_SCHEME) === NULL) {
|
||||
return 'user-path:' . $path;
|
||||
return 'user-path:/' . $path;
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ class MigrateMenuLinkTest extends MigrateDrupalTestBase {
|
|||
$this->assertIdentical($menu_link->isEnabled(), TRUE);
|
||||
$this->assertIdentical($menu_link->isExpanded(), FALSE);
|
||||
$this->assertIdentical($menu_link->link->options, ['attributes' => ['title' => 'Test menu link 1']]);
|
||||
$this->assertIdentical($menu_link->link->uri, 'user-path:user/login');
|
||||
$this->assertIdentical($menu_link->link->uri, 'user-path:/user/login');
|
||||
$this->assertIdentical($menu_link->getWeight(), 15);
|
||||
|
||||
$menu_link = entity_load('menu_link_content', 139);
|
||||
|
@ -67,7 +67,7 @@ class MigrateMenuLinkTest extends MigrateDrupalTestBase {
|
|||
$this->assertIdentical($menu_link->isEnabled(), TRUE);
|
||||
$this->assertIdentical($menu_link->isExpanded(), TRUE);
|
||||
$this->assertIdentical($menu_link->link->options, ['query' => 'foo=bar', 'attributes' => ['title' => 'Test menu link 2']]);
|
||||
$this->assertIdentical($menu_link->link->uri, 'user-path:admin');
|
||||
$this->assertIdentical($menu_link->link->uri, 'user-path:/admin');
|
||||
$this->assertIdentical($menu_link->getWeight(), 12);
|
||||
|
||||
$menu_link = entity_load('menu_link_content', 140);
|
||||
|
|
|
@ -67,7 +67,7 @@ class LinkFieldRdfaTest extends FieldRdfaTestBase {
|
|||
// Set up test values.
|
||||
$this->testValue = 'admin';
|
||||
$this->entity = entity_create('entity_test', array());
|
||||
$this->entity->{$this->fieldName}->uri = 'user-path:admin';
|
||||
$this->entity->{$this->fieldName}->uri = 'user-path:/admin';
|
||||
|
||||
// Set up the expected result.
|
||||
// AssertFormatterRdfa looks for a full path.
|
||||
|
@ -84,9 +84,9 @@ class LinkFieldRdfaTest extends FieldRdfaTestBase {
|
|||
*/
|
||||
public function testAllFormattersFront() {
|
||||
// Set up test values.
|
||||
$this->testValue = '<front>';
|
||||
$this->testValue = '/';
|
||||
$this->entity = entity_create('entity_test', array());
|
||||
$this->entity->{$this->fieldName}->uri = 'user-path:<front>';
|
||||
$this->entity->{$this->fieldName}->uri = 'user-path:/';
|
||||
|
||||
// Set up the expected result.
|
||||
$expected_rdf = array(
|
||||
|
|
|
@ -65,7 +65,7 @@ class ShortcutSetController extends ControllerBase {
|
|||
'title' => $name,
|
||||
'shortcut_set' => $shortcut_set->id(),
|
||||
'link' => array(
|
||||
'uri' => 'user-path:' . $link,
|
||||
'uri' => 'user-path:/' . $link,
|
||||
),
|
||||
));
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ class ShortcutCacheTagsTest extends EntityCacheTagsTestBase {
|
|||
'shortcut_set' => 'default',
|
||||
'title' => t('Llama'),
|
||||
'weight' => 0,
|
||||
'link' => [['uri' => 'user-path:admin']],
|
||||
'link' => [['uri' => 'user-path:/admin']],
|
||||
));
|
||||
$shortcut->save();
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class ShortcutLinksTest extends ShortcutTestBase {
|
|||
$this->assertResponse(200);
|
||||
$saved_set = ShortcutSet::load($set->id());
|
||||
$paths = $this->getShortcutInformation($saved_set, 'link');
|
||||
$this->assertTrue(in_array('user-path:' . $test_path, $paths), 'Shortcut created: ' . $test_path);
|
||||
$this->assertTrue(in_array('user-path:/' . ($test_path == '<front>' ? '' : $test_path), $paths), 'Shortcut created: ' . $test_path);
|
||||
|
||||
if (in_array($test_path, $test_cases_non_access)) {
|
||||
$this->assertNoLink($title, String::format('Shortcut link %url not accessible on the page.', ['%url' => $test_path]));
|
||||
|
@ -168,7 +168,7 @@ class ShortcutLinksTest extends ShortcutTestBase {
|
|||
$this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $shortcut->getTitle(), 'link[0][uri]' => $new_link_path), t('Save'));
|
||||
$saved_set = ShortcutSet::load($set->id());
|
||||
$paths = $this->getShortcutInformation($saved_set, 'link');
|
||||
$this->assertTrue(in_array('user-path:' . $new_link_path, $paths), 'Shortcut path changed: ' . $new_link_path);
|
||||
$this->assertTrue(in_array('user-path:/' . $new_link_path, $paths), 'Shortcut path changed: ' . $new_link_path);
|
||||
$this->assertLinkByHref($new_link_path, 0, 'Shortcut with new path appears on the page.');
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ abstract class ShortcutTestBase extends WebTestBase {
|
|||
'title' => t('Add content'),
|
||||
'weight' => -20,
|
||||
'link' => array(
|
||||
'uri' => 'user-path:node/add',
|
||||
'uri' => 'user-path:/node/add',
|
||||
),
|
||||
));
|
||||
$shortcut->save();
|
||||
|
@ -76,7 +76,7 @@ abstract class ShortcutTestBase extends WebTestBase {
|
|||
'title' => t('All content'),
|
||||
'weight' => -19,
|
||||
'link' => array(
|
||||
'uri' => 'user-path:admin/content',
|
||||
'uri' => 'user-path:/admin/content',
|
||||
),
|
||||
));
|
||||
$shortcut->save();
|
||||
|
|
|
@ -50,7 +50,7 @@ class ShortcutTranslationUITest extends ContentTranslationUITest {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity($values, $langcode, $bundle_name = NULL) {
|
||||
$values['link']['uri'] = 'user-path:user';
|
||||
$values['link']['uri'] = 'user-path:/user';
|
||||
return parent::createEntity($values, $langcode, $bundle_name);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class UrlTest extends WebTestBase {
|
|||
// Test \Drupal::l().
|
||||
$text = $this->randomMachineName();
|
||||
$path = "<SCRIPT>alert('XSS')</SCRIPT>";
|
||||
$link = \Drupal::l($text, Url::fromUri('user-path:' . $path));
|
||||
$link = \Drupal::l($text, Url::fromUri('user-path:/' . $path));
|
||||
$sanitized_path = check_url(Url::fromUri('base:' . $path)->toString());
|
||||
$this->assertTrue(strpos($link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by _l().', array('@path' => $path)));
|
||||
|
||||
|
|
|
@ -248,7 +248,7 @@ class BreadcrumbTest extends MenuTestBase {
|
|||
$menu_links = entity_load_multiple_by_properties('menu_link_content', array(
|
||||
'title' => $edit['title[0][value]'],
|
||||
// @todo Use link.uri once https://www.drupal.org/node/2391217 is in.
|
||||
'link__uri' => 'user-path:taxonomy/term/' . $term->id(),
|
||||
'link__uri' => 'user-path:/taxonomy/term/' . $term->id(),
|
||||
));
|
||||
$tags[$name]['link'] = reset($menu_links);
|
||||
$parent_mlid = $tags[$name]['link']->getPluginId();
|
||||
|
|
|
@ -67,9 +67,9 @@ class MenuLinkTreeTest extends KernelTestBase {
|
|||
\Drupal::entityManager()->getStorage('menu')->create(array('id' => 'menu1'))->save();
|
||||
\Drupal::entityManager()->getStorage('menu')->create(array('id' => 'menu2'))->save();
|
||||
|
||||
\Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save();
|
||||
\Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save();
|
||||
\Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:menu_name_test'], 'menu_name' => 'menu2', 'bundle' => 'menu_link_content'))->save();
|
||||
\Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save();
|
||||
\Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:/menu_name_test'], 'menu_name' => 'menu1', 'bundle' => 'menu_link_content'))->save();
|
||||
\Drupal::entityManager()->getStorage('menu_link_content')->create(array('link' => ['uri' => 'user-path:/menu_name_test'], 'menu_name' => 'menu2', 'bundle' => 'menu_link_content'))->save();
|
||||
|
||||
$output = $this->linkTree->load('menu1', new MenuTreeParameters());
|
||||
$this->assertEqual(count($output), 2);
|
||||
|
|
|
@ -55,7 +55,7 @@ class FormTestRedirectForm extends FormBase {
|
|||
if (!$form_state->isValueEmpty('redirection')) {
|
||||
if (!$form_state->isValueEmpty('destination')) {
|
||||
// The destination is a random URL, so we can't use routed URLs.
|
||||
$form_state->setRedirectUrl(Url::fromUri('user-path:' . $form_state->getValue('destination')));
|
||||
$form_state->setRedirectUrl(Url::fromUri('user-path:/' . $form_state->getValue('destination')));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1248,7 +1248,7 @@ abstract class FieldPluginBase extends HandlerBase implements FieldHandlerInterf
|
|||
$more_link_path = Unicode::substr($more_link_path, Unicode::strlen($base_path));
|
||||
}
|
||||
|
||||
$more_link = \Drupal::l($more_link_text, CoreUrl::fromUri('user-path:' . $more_link_path), array('attributes' => array('class' => array('views-more-link'))));
|
||||
$more_link = \Drupal::l($more_link_text, CoreUrl::fromUri('user-path:/' . $more_link_path), array('attributes' => array('class' => array('views-more-link'))));
|
||||
|
||||
$suffix .= " " . $more_link;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class Url extends FieldPluginBase {
|
|||
public function render(ResultRow $values) {
|
||||
$value = $this->getValue($values);
|
||||
if (!empty($this->options['display_as_link'])) {
|
||||
return \Drupal::l($this->sanitizeValue($value), CoreUrl::fromUri('user-path:' . $value), array('html' => TRUE));
|
||||
return \Drupal::l($this->sanitizeValue($value), CoreUrl::fromUri('user-path:/' . $value), array('html' => TRUE));
|
||||
}
|
||||
else {
|
||||
return $this->sanitizeValue($value, 'url');
|
||||
|
|
|
@ -263,7 +263,7 @@ class ViewListBuilder extends ConfigEntityListBuilder {
|
|||
if ($display->hasPath()) {
|
||||
$path = $display->getPath();
|
||||
if ($view->status() && strpos($path, '%') === FALSE) {
|
||||
$all_paths[] = \Drupal::l('/' . $path, Url::fromUri('user-path:' . $path));
|
||||
$all_paths[] = \Drupal::l('/' . $path, Url::fromUri('user-path:/' . $path));
|
||||
}
|
||||
else {
|
||||
$all_paths[] = String::checkPlain('/' . $path);
|
||||
|
|
|
@ -723,7 +723,7 @@ class ViewUI implements ViewEntityInterface {
|
|||
Xss::filterAdmin($this->executable->getTitle()),
|
||||
);
|
||||
if (isset($path)) {
|
||||
$path = \Drupal::l($path, Url::fromUri('user-path:' . $path));
|
||||
$path = \Drupal::l($path, Url::fromUri('user-path:/' . $path));
|
||||
}
|
||||
else {
|
||||
$path = t('This display has no path.');
|
||||
|
|
|
@ -58,7 +58,7 @@ function standard_install() {
|
|||
'shortcut_set' => 'default',
|
||||
'title' => t('Add content'),
|
||||
'weight' => -20,
|
||||
'link' => array('uri' => 'user-path:node/add'),
|
||||
'link' => array('uri' => 'user-path:/node/add'),
|
||||
));
|
||||
$shortcut->save();
|
||||
|
||||
|
@ -66,7 +66,7 @@ function standard_install() {
|
|||
'shortcut_set' => 'default',
|
||||
'title' => t('All content'),
|
||||
'weight' => -19,
|
||||
'link' => array('uri' => 'user-path:admin/content'),
|
||||
'link' => array('uri' => 'user-path:/admin/content'),
|
||||
));
|
||||
$shortcut->save();
|
||||
|
||||
|
|
|
@ -80,6 +80,18 @@ class PathValidatorTest extends UnitTestCase {
|
|||
$this->assertTrue($this->pathValidator->isValid('<front>'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the isValid() method for <none> (used for jumplinks).
|
||||
*
|
||||
* @covers ::isValid
|
||||
*/
|
||||
public function testIsValidWithNone() {
|
||||
$this->accessAwareRouter->expects($this->never())
|
||||
->method('match');
|
||||
|
||||
$this->assertTrue($this->pathValidator->isValid('<none>'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the isValid() method for an external URL.
|
||||
*
|
||||
|
|
|
@ -180,7 +180,7 @@ class UrlTest extends UnitTestCase {
|
|||
->method('getUrlIfValidWithoutAccessCheck')
|
||||
->with('invalid-path')
|
||||
->willReturn(FALSE);
|
||||
$url = Url::fromUri('user-path:invalid-path');
|
||||
$url = Url::fromUri('user-path:/invalid-path');
|
||||
$this->assertSame(FALSE, $url->isRouted());
|
||||
$this->assertSame('base:invalid-path', $url->getUri());
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ class UrlTest extends UnitTestCase {
|
|||
->method('getUrlIfValidWithoutAccessCheck')
|
||||
->with('valid-path')
|
||||
->willReturn($url);
|
||||
$result_url = Url::fromUri('user-path:valid-path');
|
||||
$result_url = Url::fromUri('user-path:/valid-path');
|
||||
$this->assertSame($url, $result_url);
|
||||
}
|
||||
|
||||
|
@ -602,8 +602,11 @@ class UrlTest extends UnitTestCase {
|
|||
$url = Url::fromRoute('entity.test_entity.canonical', ['test_entity' => '1']);
|
||||
$this->pathValidator->expects($this->any())
|
||||
->method('getUrlIfValidWithoutAccessCheck')
|
||||
->with('test-entity/1')
|
||||
->willReturn($url);
|
||||
->willReturnMap([
|
||||
['test-entity/1', $url],
|
||||
['<front>', Url::fromRoute('<front>')],
|
||||
['<none>', Url::fromRoute('<none>')],
|
||||
]);
|
||||
$url = Url::fromUri($uri, $options);
|
||||
$this->assertSame($url->toUriString(), $uri_string);
|
||||
}
|
||||
|
@ -613,10 +616,23 @@ class UrlTest extends UnitTestCase {
|
|||
*/
|
||||
public function providerTestToUriStringForUserPath() {
|
||||
return [
|
||||
['user-path:test-entity/1', [], 'route:entity.test_entity.canonical;test_entity=1'],
|
||||
['user-path:test-entity/1', ['fragment' => 'top'], 'route:entity.test_entity.canonical;test_entity=1#top'],
|
||||
['user-path:test-entity/1', ['fragment' => 'top', 'query' => ['page' => '2']], 'route:entity.test_entity.canonical;test_entity=1?page=2#top'],
|
||||
['user-path:test-entity/1?page=2#top', [], 'route:entity.test_entity.canonical;test_entity=1?page=2#top'],
|
||||
// The four permutations of a regular path.
|
||||
['user-path:/test-entity/1', [], 'route:entity.test_entity.canonical;test_entity=1'],
|
||||
['user-path:/test-entity/1', ['fragment' => 'top'], 'route:entity.test_entity.canonical;test_entity=1#top'],
|
||||
['user-path:/test-entity/1', ['fragment' => 'top', 'query' => ['page' => '2']], 'route:entity.test_entity.canonical;test_entity=1?page=2#top'],
|
||||
['user-path:/test-entity/1?page=2#top', [], 'route:entity.test_entity.canonical;test_entity=1?page=2#top'],
|
||||
|
||||
// The four permutations of the special '<front>' path.
|
||||
['user-path:/', [], 'route:<front>'],
|
||||
['user-path:/', ['fragment' => 'top'], 'route:<front>#top'],
|
||||
['user-path:/', ['fragment' => 'top', 'query' => ['page' => '2']], 'route:<front>?page=2#top'],
|
||||
['user-path:/?page=2#top', [], 'route:<front>?page=2#top'],
|
||||
|
||||
// The four permutations of the special '<none>' path.
|
||||
['user-path:', [], 'route:<none>'],
|
||||
['user-path:', ['fragment' => 'top'], 'route:<none>#top'],
|
||||
['user-path:', ['fragment' => 'top', 'query' => ['page' => '2']], 'route:<none>?page=2#top'],
|
||||
['user-path:?page=2#top', [], 'route:<none>?page=2#top'],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue