Commit e044adb0 authored by alexpott's avatar alexpott

Issue #2509300 by dawehner, catch, larowlan: Path alias UI allows node/1 and...

Issue #2509300 by dawehner, catch, larowlan: Path alias UI allows node/1 and /node/1 as system path then fatals
parent 131d5772
......@@ -66,7 +66,7 @@ protected static function getPriority() {
*/
public function on403(GetResponseForExceptionEvent $event) {
$path = $this->aliasManager->getPathByAlias($this->configFactory->get('system.site')->get('page.403'));
$this->makeSubrequest($event, $path, Response::HTTP_FORBIDDEN);
$this->makeSubrequest($event, trim($path, '/'), Response::HTTP_FORBIDDEN);
}
/**
......@@ -74,7 +74,7 @@ public function on403(GetResponseForExceptionEvent $event) {
*/
public function on404(GetResponseForExceptionEvent $event) {
$path = $this->aliasManager->getPathByAlias($this->configFactory->get('system.site')->get('page.404'));
$this->makeSubrequest($event, $path, Response::HTTP_NOT_FOUND);
$this->makeSubrequest($event, trim($path, '/'), Response::HTTP_NOT_FOUND);
}
}
......@@ -58,7 +58,7 @@ public function __construct(AliasManagerInterface $alias_manager, CurrentPathSta
public function onKernelController(FilterControllerEvent $event) {
// Set the cache key on the alias manager cache decorator.
if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
$this->aliasManager->setCacheKey(trim($this->currentPath->getPath($event->getRequest()), '/'));
$this->aliasManager->setCacheKey(rtrim($this->currentPath->getPath($event->getRequest()), '/'));
}
}
......
......@@ -187,6 +187,9 @@ public function getPathByAlias($alias, $langcode = NULL) {
* {@inheritdoc}
*/
public function getAliasByPath($path, $langcode = NULL) {
if ($path[0] !== '/') {
throw new \InvalidArgumentException(sprintf('Source path %s has to start with a slash.', $path));
}
// If no language is explicitly specified we default to the current URL
// language. If we used a language different from the one conveyed by the
// requested URL, we might end up being unable to check if there is a path
......@@ -196,7 +199,7 @@ public function getAliasByPath($path, $langcode = NULL) {
// Check the path whitelist, if the top-level part before the first /
// is not in the list, then there is no need to do anything further,
// it is not in the database.
if (empty($path) || !$this->whitelist->get(strtok($path, '/'))) {
if ($path === '/' || !$this->whitelist->get(strtok(trim($path, '/'), '/'))) {
return $path;
}
......
......@@ -19,6 +19,9 @@ interface AliasManagerInterface {
*
* @return string
* The path represented by alias, or the alias if no path was found.
*
* @throws \InvalidArgumentException
* Thrown when the path does not start with a slash.
*/
public function getPathByAlias($alias, $langcode = NULL);
......@@ -32,6 +35,9 @@ public function getPathByAlias($alias, $langcode = NULL);
*
* @return string
* An alias that represents the path, or path if no alias was found.
*
* @throws \InvalidArgumentException
* Thrown when the path does not start with a slash.
*/
public function getAliasByPath($path, $langcode = NULL);
......
......@@ -49,6 +49,14 @@ public function __construct(Connection $connection, ModuleHandlerInterface $modu
*/
public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid = NULL) {
if ($source[0] !== '/') {
throw new \InvalidArgumentException(sprintf('Source path %s has to start with a slash.', $source));
}
if ($alias[0] !== '/') {
throw new \InvalidArgumentException(sprintf('Alias path %s has to start with a slash.', $alias));
}
$fields = array(
'source' => $source,
'alias' => $alias,
......
......@@ -29,12 +29,15 @@ interface AliasStorageInterface {
* @return array|false
* FALSE if the path could not be saved or an associative array containing
* the following keys:
* - source (string): The internal system path.
* - alias (string): The URL alias.
* - source (string): The internal system path with a starting slash.
* - alias (string): The URL alias with a starting slash.
* - pid (int): Unique path alias identifier.
* - langcode (string): The language code of the alias.
* - original: For updates, an array with source, alias and langcode with
* the previous values.
*
* @thrown \InvalidArgumentException
* Thrown when either the source or alias has not a starting slash.
*/
public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED, $pid = NULL);
......@@ -47,8 +50,8 @@ public function save($source, $alias, $langcode = LanguageInterface::LANGCODE_NO
* @return array|false
* FALSE if no alias was found or an associative array containing the
* following keys:
* - source (string): The internal system path.
* - alias (string): The URL alias.
* - source (string): The internal system path with a starting slash.
* - alias (string): The URL alias with a starting slash.
* - pid (int): Unique path alias identifier.
* - langcode (string): The language code of the alias.
*/
......
......@@ -107,7 +107,7 @@ public function get($offset) {
* {@inheritdoc}
*/
public function resolveCacheMiss($root) {
$exists = $this->aliasStorage->pathHasMatchingAlias($root);
$exists = $this->aliasStorage->pathHasMatchingAlias('/' . $root);
$this->storage[$root] = $exists;
$this->persist($root);
if ($exists) {
......
......@@ -101,7 +101,7 @@ public function isFrontPage() {
// route match, like on exception responses.
if ($this->routeMatch->getRouteName()) {
$url = Url::fromRouteMatch($this->routeMatch);
$this->isCurrentFrontPage = ($url->getRouteName() && $url->getInternalPath() === $this->getFrontPagePath());
$this->isCurrentFrontPage = ($url->getRouteName() && '/' . $url->getInternalPath() === $this->getFrontPagePath());
}
}
return $this->isCurrentFrontPage;
......@@ -116,8 +116,6 @@ public function isFrontPage() {
protected function getFrontPagePath() {
// Lazy-load front page config.
if (!isset($this->frontPage)) {
// @todo page.front should store the route name, see
// https://www.drupal.org/node/2371823
$this->frontPage = $this->configFactory->get('system.site')
->get('page.front');
}
......
......@@ -96,6 +96,8 @@ public function getUrlIfValidWithoutAccessCheck($path) {
* Helper for getUrlIfValid() and getUrlIfValidWithoutAccessCheck().
*/
protected function getUrl($path, $access_check) {
$path = ltrim($path, '/');
$parsed_url = UrlHelper::parse($path);
$options = [];
......@@ -119,7 +121,6 @@ protected function getUrl($path, $access_check) {
return Url::fromUri($path);
}
$path = ltrim($path, '/');
$request = Request::create('/' . $path);
$attributes = $this->getPathAttributes($path, $request, $access_check);
......@@ -155,10 +156,10 @@ protected function getPathAttributes($path, Request $request, $access_check) {
$router = $this->accessAwareRouter;
}
$path = $this->pathProcessor->processInbound($path, $request);
$path = $this->pathProcessor->processInbound('/' . $path, $request);
try {
return $router->match('/' . $path);
return $router->match($path);
}
catch (ResourceNotFoundException $e) {
return FALSE;
......
......@@ -18,7 +18,7 @@ interface InboundPathProcessorInterface {
* Processes the inbound path.
*
* @param string $path
* The path to process.
* The path to process, with a starting slash.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The HttpRequest object representing the current request.
......
......@@ -39,7 +39,7 @@ public function __construct(ConfigFactoryInterface $config) {
* Implements Drupal\Core\PathProcessor\InboundPathProcessorInterface::processInbound().
*/
public function processInbound($path, Request $request) {
if (empty($path)) {
if ($path === '/') {
$path = $this->config->get('system.site')->get('page.front');
}
return $path;
......@@ -50,8 +50,8 @@ public function processInbound($path, Request $request) {
*/
public function processOutbound($path, &$options = array(), Request $request = NULL, CacheableMetadata $cacheable_metadata = NULL) {
// The special path '<front>' links to the default front page.
if ($path == '<front>') {
$path = '';
if ($path === '/<front>') {
$path = '/';
}
return $path;
}
......
......@@ -140,14 +140,16 @@ public function getRouteCollectionForRequest(Request $request) {
return $cached->data['routes'];
}
else {
$path = trim($request->getPathInfo(), '/');
// Just trim on the right side.
$path = $request->getPathInfo();
$path = $path === '/' ? $path : rtrim($request->getPathInfo(), '/');
$path = $this->pathProcessor->processInbound($path, $request);
$this->currentPath->setPath('/' . $path, $request);
$this->currentPath->setPath($path, $request);
// Incoming path processors may also set query parameters.
$query_parameters = $request->query->all();
$routes = $this->getRoutesByPath('/' . rtrim($path, '/'));
$routes = $this->getRoutesByPath(rtrim($path, '/'));
$cache_value = [
'path' => '/' . $path,
'path' => $path,
'query' => $query_parameters,
'routes' => $routes,
];
......
......@@ -435,7 +435,7 @@ public function generateFromPath($path = NULL, $options = array(), $collect_cach
return $collect_cacheability_metadata ? $generated_url->setGeneratedUrl($url) : $url;
}
else {
$path = ltrim($this->processPath($path, $options, $generated_url), '/');
$path = ltrim($this->processPath('/' . $path, $options, $generated_url), '/');
}
if (!isset($options['script'])) {
......@@ -488,7 +488,7 @@ protected function processPath($path, &$options = array(), CacheableMetadata $ca
$actual_path = $path;
$query_string = '';
}
$path = '/' . $this->pathProcessor->processOutbound(trim($actual_path, '/'), $options, $this->requestStack->getCurrentRequest(), $cacheable_metadata);
$path = $this->pathProcessor->processOutbound($actual_path === '/' ? $actual_path : rtrim($actual_path, '/'), $options, $this->requestStack->getCurrentRequest(), $cacheable_metadata);
$path .= $query_string;
return $path;
}
......
......@@ -35,7 +35,7 @@ function testBlockVisibility() {
);
// Set the block to be hidden on any user path, and to be shown only to
// authenticated users.
$edit['visibility[request_path][pages]'] = 'user*';
$edit['visibility[request_path][pages]'] = '/user*';
$edit['visibility[request_path][negate]'] = TRUE;
$edit['visibility[user_role][roles][' . RoleInterface::AUTHENTICATED_ID . ']'] = TRUE;
$this->drupalGet('admin/structure/block/add/' . $block_name . '/' . $default_theme);
......
......@@ -39,7 +39,7 @@ protected function setUp() {
parent::setUp();
// Use the test page as the front page.
$this->config('system.site')->set('page.front', 'test-page')->save();
$this->config('system.site')->set('page.front', '/test-page')->save();
// Create Full HTML text format.
$full_html_format = entity_create('filter_format', array(
......
......@@ -293,7 +293,7 @@ function testSchemaData() {
$meta = \Drupal::service('config.typed')->get('system.site');
$property = $meta->get('page')->get('front');
$this->assertTrue($property instanceof StringInterface, 'Got the right wrapper fo the page.front property.');
$this->assertEqual($property->getValue(), 'user/login', 'Got the right value for page.front data.');
$this->assertEqual($property->getValue(), '/user/login', 'Got the right value for page.front data.');
$definition = $property->getDataDefinition();
$this->assertTrue(empty($definition['translatable']), 'Got the right translatability setting for page.front data.');
......@@ -301,13 +301,13 @@ function testSchemaData() {
$list = $meta->get('page')->getElements();
$this->assertEqual(count($list), 3, 'Got a list with the right number of properties for site page data');
$this->assertTrue(isset($list['front']) && isset($list['403']) && isset($list['404']), 'Got a list with the right properties for site page data.');
$this->assertEqual($list['front']->getValue(), 'user/login', 'Got the right value for page.front data from the list.');
$this->assertEqual($list['front']->getValue(), '/user/login', 'Got the right value for page.front data from the list.');
// And test some TypedConfigInterface methods.
$properties = $list;
$this->assertTrue(count($properties) == 3 && $properties['front'] == $list['front'], 'Got the right properties for site page.');
$values = $meta->get('page')->toArray();
$this->assertTrue(count($values) == 3 && $values['front'] == 'user/login', 'Got the right property values for site page.');
$this->assertTrue(count($values) == 3 && $values['front'] == '/user/login', 'Got the right property values for site page.');
// Now let's try something more complex, with nested objects.
$wrapper = \Drupal::service('config.typed')->get('image.style.large');
......
......@@ -134,7 +134,7 @@ public function testImportSimpleConfiguration() {
$this->drupalPostForm('admin/config/development/configuration/single/import', $edit, t('Import'));
$this->assertRaw(t('Are you sure you want to update the %name @type?', array('%name' => $config->getName(), '@type' => 'simple configuration')));
$this->drupalPostForm(NULL, array(), t('Confirm'));
$this->drupalGet('/');
$this->drupalGet('');
$this->assertText('Test simple import');
}
......
......@@ -32,11 +32,11 @@ class PathProcessorImageStyles implements InboundPathProcessorInterface {
*/
public function processInbound($path, Request $request) {
$directory_path = file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath();
if (strpos($path, $directory_path . '/styles/') === 0) {
$path_prefix = $directory_path . '/styles/';
if (strpos($path, '/' . $directory_path . '/styles/') === 0) {
$path_prefix = '/' . $directory_path . '/styles/';
}
elseif (strpos($path, 'system/files/styles/') === 0) {
$path_prefix = 'system/files/styles/';
elseif (strpos($path, '/system/files/styles/') === 0) {
$path_prefix = '/system/files/styles/';
}
else {
return $path;
......
......@@ -105,14 +105,14 @@ public function getLangcode(Request $request = NULL) {
*/
public function processInbound($path, Request $request) {
$config = $this->config->get('language.negotiation')->get('url');
$parts = explode('/', $path);
$parts = explode('/', trim($path, '/'));
$prefix = array_shift($parts);
// Search prefix within added languages.
foreach ($this->languageManager->getLanguages() as $language) {
if (isset($config['prefixes'][$language->getId()]) && $config['prefixes'][$language->getId()] == $prefix) {
// Rebuild $path with the language removed.
$path = implode('/', $parts);
$path = '/' . implode('/', $parts);
break;
}
}
......
......@@ -92,7 +92,7 @@ function testURLValidation() {
$this->assertRaw('placeholder="http://example.com"');
// Create a path alias.
\Drupal::service('path.alias_storage')->save('admin', 'a/path/alias');
\Drupal::service('path.alias_storage')->save('/admin', '/a/path/alias');
// Create a node to test the link widget.
$node = $this->drupalCreateNode();
......
......@@ -32,7 +32,7 @@ protected function setUp() {
parent::setUp();
$this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
$this->config('system.site')->set('page.front', 'node')->save();
$this->config('system.site')->set('page.front', '/node')->save();
}
/**
......@@ -74,8 +74,8 @@ public function testPathLanguageConfiguration() {
$path = 'admin/config/search/path/add';
$english_path = $this->randomMachineName(8);
$edit = array(
'source' => 'node/' . $node->id(),
'alias' => $english_path,
'source' => '/node/' . $node->id(),
'alias' => '/' . $english_path,
'langcode' => 'en',
);
$this->drupalPostForm($path, $edit, t('Save'));
......@@ -83,8 +83,8 @@ public function testPathLanguageConfiguration() {
// Create a path alias in new custom language.
$custom_language_path = $this->randomMachineName(8);
$edit = array(
'source' => 'node/' . $node->id(),
'alias' => $custom_language_path,
'source' => '/node/' . $node->id(),
'alias' => '/' . $custom_language_path,
'langcode' => $langcode,
);
$this->drupalPostForm($path, $edit, t('Save'));
......@@ -102,16 +102,16 @@ public function testPathLanguageConfiguration() {
// Check priority of language for alias by source path.
$edit = array(
'source' => 'node/' . $node->id(),
'alias' => $custom_path,
'source' => '/node/' . $node->id(),
'alias' => '/' . $custom_path,
'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
);
$this->container->get('path.alias_storage')->save($edit['source'], $edit['alias'], $edit['langcode']);
$lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('node/' . $node->id(), 'en');
$this->assertEqual($english_path, $lookup_path, 'English language alias has priority.');
$lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $node->id(), 'en');
$this->assertEqual('/' . $english_path, $lookup_path, 'English language alias has priority.');
// Same check for language 'xx'.
$lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('node/' . $node->id(), $prefix);
$this->assertEqual($custom_language_path, $lookup_path, 'Custom language alias has priority.');
$lookup_path = $this->container->get('path.alias_manager')->getAliasByPath('/node/' . $node->id(), $prefix);
$this->assertEqual('/' . $custom_language_path, $lookup_path, 'Custom language alias has priority.');
$this->container->get('path.alias_storage')->delete($edit);
// Create language nodes to check priority of aliases.
......@@ -120,8 +120,8 @@ public function testPathLanguageConfiguration() {
// Assign a custom path alias to the first node with the English language.
$edit = array(
'source' => 'node/' . $first_node->id(),
'alias' => $custom_path,
'source' => '/node/' . $first_node->id(),
'alias' => '/' . $custom_path,
'langcode' => $first_node->language()->getId(),
);
$this->container->get('path.alias_storage')->save($edit['source'], $edit['alias'], $edit['langcode']);
......@@ -129,8 +129,8 @@ public function testPathLanguageConfiguration() {
// Assign a custom path alias to second node with
// LanguageInterface::LANGCODE_NOT_SPECIFIED.
$edit = array(
'source' => 'node/' . $second_node->id(),
'alias' => $custom_path,
'source' => '/node/' . $second_node->id(),
'alias' => '/' . $custom_path,
'langcode' => $second_node->language()->getId(),
);
$this->container->get('path.alias_storage')->save($edit['source'], $edit['alias'], $edit['langcode']);
......
......@@ -57,7 +57,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' => 'internal:/' . $path]);
->loadByProperties(['link.uri' => 'internal:' . $path]);
foreach ($entities as $menu_link) {
$menu_link_manager->updateDefinition($menu_link->getPluginId(), $menu_link->getPluginDefinition(), FALSE);
}
......
......@@ -59,7 +59,7 @@ public function testPathAliasChange() {
/** @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');
$alias = $path_alias_storage->save('/test-page', '/my-blog');
$pid = $alias['pid'];
$menu_link_content = MenuLinkContent::create([
......@@ -73,7 +73,7 @@ public function testPathAliasChange() {
$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);
$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']);
......
......@@ -289,7 +289,7 @@ function doMenuTests() {
$node5 = $this->drupalCreateNode(array(
'type' => 'article',
'path' => array(
'alias' => 'node5',
'alias' => '/node5',
),
));
......
......@@ -14,6 +14,10 @@ migrate_destination:
migrate_source:
type: migrate_plugin
label: 'Source'
mapping:
constants:
type: ignore
label: 'Constants'
# Base schema for migrate source plugins that extend
# \Drupal\migrate\Plugin\migrate\source\SqlBase.
......
......@@ -11,6 +11,3 @@ migrate.source.empty:
provider:
type: string
label: 'Provider'
constants:
type: ignore
label: 'Constants'
......@@ -4,6 +4,8 @@ migration_tags:
- Drupal 6
source:
plugin: variable
constants:
slash: '/'
variables:
- site_name
- site_mail
......@@ -17,9 +19,21 @@ process:
name: site_name
mail: site_mail
slogan: site_slogan
'page/front': site_frontpage
'page/403': site_403
'page/404': site_404
'page/front':
plugin: concat
source:
- constants/slash
- site_frontpage
'page/403':
plugin: concat
source:
- constants/slash
- site_403
'page/404':
plugin: concat
source:
- constants/slash
- site_404
weight_select_max: drupal_weight_select_max
admin_compact_mode: admin_compact_mode
destination:
......
......@@ -4,10 +4,20 @@ migration_tags:
- Drupal 6
source:
plugin: d6_url_alias
constants:
slash: '/'
process:
source: src
alias: dst
source:
plugin: concat
source:
- constants/slash
- src
alias:
plugin: concat
source:
- constants/slash
- dst
langcode: language
destination:
......
......@@ -35,6 +35,9 @@ migrate.source.variable:
status:
type: boolean
label: 'Status'
slash:
type: string
label: 'Slash'
migrate.source.d6_comment:
type: migrate_source_sql
......
......@@ -40,9 +40,9 @@ public function testSystemSite() {
$this->assertIdentical('site_name', $config->get('name'));
$this->assertIdentical('site_mail@example.com', $config->get('mail'));
$this->assertIdentical('Migrate rocks', $config->get('slogan'));
$this->assertIdentical('user', $config->get('page.403'));
$this->assertIdentical('page-not-found', $config->get('page.404'));
$this->assertIdentical('node', $config->get('page.front'));
$this->assertIdentical('/user', $config->get('page.403'));
$this->assertIdentical('/page-not-found', $config->get('page.404'));
$this->assertIdentical('/node', $config->get('page.front'));
$this->assertIdentical(FALSE, $config->get('admin_compact_mode'));
}
......
......@@ -43,16 +43,16 @@ public function testUrlAlias() {
$migration = entity_load('migration', 'd6_url_alias');
// Test that the field exists.
$conditions = array(
'source' => 'node/1',
'alias' => 'alias-one',
'source' => '/node/1',
'alias' => '/alias-one',
'langcode' => 'en',
);
$path = \Drupal::service('path.alias_storage')->load($conditions);
$this->assertNotNull($path, "Path alias for node/1 successfully loaded.");
$this->assertIdentical($migration->getIdMap()->lookupDestinationID(array($path['pid'])), array('1'), "Test IdMap");
$conditions = array(
'source' => 'node/2',
'alias' => 'alias-two',
'source' => '/node/2',
'alias' => '/alias-two',
'langcode' => 'en',
);
$path = \Drupal::service('path.alias_storage')->load($conditions);
......@@ -73,7 +73,7 @@ public function testUrlAlias() {
$executable->import();
$path = \Drupal::service('path.alias_storage')->load(array('pid' => $path['pid']));
$this->assertIdentical('new-url-alias', $path['alias']);
$this->assertIdentical('/new-url-alias', $path['alias']);
}
}
......@@ -122,7 +122,7 @@ function testFailedPageCreation() {
*/
function testUnpublishedNodeCreation() {
// Set the front page to the test page.
$this->config('system.site')->set('page.front', 'test-page')->save();
$this->config('system.site')->set('page.front', '/test-page')->save();
// Set "Basic page" content type to be unpublished by default.
$fields = \Drupal::entityManager()->getFieldDefinitions('node', 'page');
......
......@@ -64,7 +64,7 @@ function testPageCacheTags() {
$block = $this->drupalPlaceBlock('views_block:comments_recent-block_1', array(
'visibility' => array(
'request_path' => array(
'pages' => 'node/' . $node_2->id(),
'pages' => '/node/' . $node_2->id(),
),
),
));
......
......@@ -39,7 +39,7 @@ protected function setUp() {
$this->config('system.site')
->set('name', 'Drupal')
->set('page.front', 'test-page')
->set('page.front', '/test-page')
->save();
}
......
......@@ -84,6 +84,6 @@ function path_entity_base_field_info(EntityTypeInterface $entity_type) {
*/
function path_entity_translation_delete(EntityInterface $translation) {
$path = $translation->urlInfo()->getInternalPath();
$conditions = array('source' => $path, 'langcode' => $translation->language()->getId());
$conditions = array('source' => '/' . $path, 'langcode' => $translation->language()->getId());
\Drupal::service('path.alias_storage')->delete($conditions);
}
......@@ -88,10 +88,10 @@ public function adminOverview(Request $request) {
$row = array();
// @todo Should Path module store leading slashes? See
// https://www.drupal.org/node/2430593.
$row['data']['alias'] = $this->l(Unicode::truncate($data->alias, 50, FALSE, TRUE), Url::fromUserInput('/' . $data->source, array(
$row['data']['alias'] = $this->l(Unicode::truncate($data->alias, 50, FALSE, TRUE), Url::fromUserInput($data->source, array(
'attributes' => array('title' => $data->alias),
)));
$row['data']['source'] = $this->l(Unicode::truncate($data->source, 50, FALSE, TRUE), Url::fromUserInput('/' . $data->source, array(
$row['data']['source'] = $this->l(Unicode::truncate($data->source, 50, FALSE, TRUE), Url::fromUserInput($data->source, array(
'alias' => TRUE,
'attributes' => array('title' => $data->source),
)));
......
......@@ -13,6 +13,7 @@
use Drupal\Core\Path\AliasManagerInterface;
use Drupal\Core\Path\AliasStorageInterface;
use Drupal\Core\Path\PathValidatorInterface;
use Drupal\Core\Routing\RequestContext;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
......@@ -48,6 +49,13 @@ abstract class PathFormBase extends FormBase {
*/
protected $pathValidator;
/**
* The request context.
*
* @var \Drupal\Core\Routing\RequestContext
*/
protected $requestContext;
/**
* Constructs a new PathController.
*
......@@ -57,11 +65,14 @@ abstract class PathFormBase extends FormBase {
* The path alias manager.
* @param \Drupal\Core\Path\PathValidatorInterface $path_validator