Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
68f576fe
Commit
68f576fe
authored
Aug 28, 2014
by
Angie Byron
Browse files
Issue
#2323721
by dawehner, chx: Fixed [sechole] Link field item and menu link information leakage.
parent
aca1ec38
Changes
28
Hide whitespace changes
Inline
Side-by-side
core/core.services.yml
View file @
68f576fe
...
...
@@ -506,7 +506,7 @@ services:
arguments
:
[
'
@config.factory'
]
path.validator
:
class
:
Drupal\Core\Path\PathValidator
arguments
:
[
'
@router'
,
'
@router.
route_provider'
,
'
@request_stack
'
]
arguments
:
[
'
@router'
,
'
@router.
no_access_checks'
,
'
@current_user'
,
'
@path_processor_manager
'
]
# The argument to the hashing service defined in services.yml, to the
# constructor of PhpassHashedPassword is the log2 number of iterations for
...
...
core/lib/Drupal.php
View file @
68f576fe
...
...
@@ -666,4 +666,13 @@ public static function menuTree() {
return
static
::
$container
->
get
(
'menu.link_tree'
);
}
/**
* Returns the path validator.
*
* @return \Drupal\Core\Path\PathValidatorInterface
*/
public
static
function
pathValidator
()
{
return
static
::
$container
->
get
(
'path.validator'
);
}
}
core/lib/Drupal/Component/Utility/UrlHelper.php
View file @
68f576fe
...
...
@@ -151,7 +151,12 @@ public static function parse($url) {
if
(
strpos
(
$url
,
'://'
)
!==
FALSE
)
{
// Split off everything before the query string into 'path'.
$parts
=
explode
(
'?'
,
$url
);
$options
[
'path'
]
=
$parts
[
0
];
// Don't support URLs without a path, like 'http://'.
list
(,
$path
)
=
explode
(
'://'
,
$parts
[
0
],
2
);
if
(
$path
!=
''
)
{
$options
[
'path'
]
=
$parts
[
0
];
}
// If there is a query string, transform it into keyed query parameters.
if
(
isset
(
$parts
[
1
]))
{
$query_parts
=
explode
(
'#'
,
$parts
[
1
]);
...
...
core/lib/Drupal/Core/Menu/DefaultMenuLinkTreeManipulators.php
View file @
68f576fe
...
...
@@ -8,6 +8,7 @@
namespace
Drupal\Core\Menu
;
use
Drupal\Core\Access\AccessManagerInterface
;
use
Drupal\Core\Path\PathValidator
;
use
Drupal\Core\Session\AccountInterface
;
/**
...
...
@@ -93,6 +94,9 @@ public function checkAccess(array $tree) {
* TRUE if the current user can access the link, FALSE otherwise.
*/
protected
function
menuLinkCheckAccess
(
MenuLinkInterface
$instance
)
{
if
(
$this
->
account
->
hasPermission
(
'link to any page'
))
{
return
TRUE
;
}
// Use the definition here since that's a lot faster than creating a Url
// object that we don't need.
$definition
=
$instance
->
getPluginDefinition
();
...
...
core/lib/Drupal/Core/Path/PathValidator.php
View file @
68f576fe
...
...
@@ -2,18 +2,22 @@
/**
* @file
* Contains Drupal\Core\Path\PathValidator
* Contains
\
Drupal\Core\Path\PathValidator
*/
namespace
Drupal\Core\Path
;
use
Drupal\Component\Utility\UrlHelper
;
use
Drupal\Core\ParamConverter\ParamNotConvertedException
;
use
Drupal\Core\Routing\RequestHelper
;
use
Drupal\Core\Routing\RouteProviderInterface
;
use
Symfony\Component\HttpFoundation\RequestStack
;
use
Drupal\Core\PathProcessor\InboundPathProcessorInterface
;
use
Drupal\Core\Routing\AccessAwareRouterInterface
;
use
Drupal\Core\Session\AccountInterface
;
use
Drupal\Core\Url
;
use
Symfony\Cmf\Component\Routing\RouteObjectInterface
;
use
Symfony\Component\HttpFoundation\Request
;
use
Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
;
use
Symfony\Component\Routing\Matcher\RequestMatcherInterface
;
use
Symfony\Component\Routing\Exception\ResourceNotFoundException
;
use
Symfony\Component\Routing\Matcher\UrlMatcherInterface
;
/**
* Provides a default path validator and access checker.
...
...
@@ -21,66 +25,122 @@
class
PathValidator
implements
PathValidatorInterface
{
/**
* The
request match
er.
* The
access aware rout
er.
*
* @var \
Symfony\Component\Routing\Matcher\RequestMatch
erInterface
* @var \
Drupal\Core\Routing\AccessAwareRout
erInterface
*/
protected
$
requestMatch
er
;
protected
$
accessAwareRout
er
;
/**
*
The
route
provider
.
*
A
route
r implementation which does not check access
.
*
* @var \
Drupal\Core\Routing\RouteProvid
erInterface
* @var \
Symfony\Component\Routing\Matcher\UrlMatch
erInterface
*/
protected
$
routeProvid
er
;
protected
$
accessUnawareRout
er
;
/**
* The
request stack
.
* The
current user
.
*
* @var \
Symfony\Component\HttpFoundation\RequestSt
ac
k
* @var \
Drupal\Core\Session\AccountInterf
ac
e
*/
protected
$requestStack
;
protected
$account
;
/**
* The path processor.
*
* @var \Drupal\Core\PathProcessor\InboundPathProcessorInterface
*/
protected
$pathProcessor
;
/**
* Creates a new PathValidator.
*
* @param \Symfony\Component\Routing\Matcher\RequestMatcherInterface $request_matcher
* The request matcher.
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
* @param \Drupal\Core\Routing\AccessAwareRouterInterface $access_aware_router
* The access aware router.
* @param \Symfony\Component\Routing\Matcher\UrlMatcherInterface $access_unaware_router
* A router implementation which does not check access.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
* @param \Drupal\Core\PathProcessor\InboundPathProcessorInterface $path_processor
* The path processor;
*/
public
function
__construct
(
RequestMatcherInterface
$request_matcher
,
RouteProviderInterface
$route_provider
,
RequestStack
$request_stack
)
{
$this
->
requestMatcher
=
$request_matcher
;
$this
->
routeProvider
=
$route_provider
;
$this
->
requestStack
=
$request_stack
;
public
function
__construct
(
AccessAwareRouterInterface
$access_aware_router
,
UrlMatcherInterface
$access_unaware_router
,
AccountInterface
$account
,
InboundPathProcessorInterface
$path_processor
)
{
$this
->
accessAwareRouter
=
$access_aware_router
;
$this
->
accessUnawareRouter
=
$access_unaware_router
;
$this
->
account
=
$account
;
$this
->
pathProcessor
=
$path_processor
;
}
/**
* {@inheritdoc}
*/
public
function
isValid
(
$path
)
{
// External URLs and the front page are always valid.
if
(
$path
==
'<front>'
||
UrlHelper
::
isExternal
(
$path
))
{
return
TRUE
;
return
(
bool
)
$this
->
getUrlIfValid
(
$path
);
}
/**
* {@inheritdoc}
*/
public
function
getUrlIfValid
(
$path
)
{
$parsed_url
=
UrlHelper
::
parse
(
$path
);
$options
=
[];
if
(
!
empty
(
$parsed_url
[
'query'
]))
{
$options
[
'query'
]
=
$parsed_url
[
'query'
];
}
if
(
!
empty
(
$parsed_url
[
'fragment'
]))
{
$options
[
'fragment'
]
=
$parsed_url
[
'fragment'
];
}
if
(
$parsed_url
[
'path'
]
==
'<front>'
)
{
return
new
Url
(
'<front>'
,
[],
$options
);
}
elseif
(
UrlHelper
::
isExternal
(
$path
)
&&
UrlHelper
::
isValid
(
$path
))
{
if
(
empty
(
$parsed_url
[
'path'
]))
{
return
FALSE
;
}
return
Url
::
createFromPath
(
$path
);
}
// Check the routing system.
$collection
=
$this
->
routeProvider
->
getRoutesByPattern
(
'/'
.
$path
);
if
(
$collection
->
count
()
==
0
)
{
$request
=
Request
::
create
(
'/'
.
$path
);
$attributes
=
$this
->
getPathAttributes
(
$path
,
$request
);
if
(
!
$attributes
)
{
return
FALSE
;
}
// We can not use $this->requestMatcher->match() because we need to set
// the _menu_admin attribute to indicate a menu administrator is running
// the menu access check.
$request
=
RequestHelper
::
duplicate
(
$this
->
requestStack
->
getCurrentRequest
(),
'/'
.
$path
);
$request
->
attributes
->
set
(
'_system_path'
,
$path
);
$request
->
attributes
->
set
(
'_menu_admin'
,
TRUE
);
$route_name
=
$attributes
[
RouteObjectInterface
::
ROUTE_NAME
];
$route_parameters
=
$attributes
[
'_raw_variables'
]
->
all
();
return
new
Url
(
$route_name
,
$route_parameters
,
$options
+
[
'query'
=>
$request
->
query
->
all
()]);
}
/**
* Gets the matched attributes for a given path.
*
* @param string $path
* The path to check.
* @param \Symfony\Component\HttpFoundation\Request $request
* A request object with the given path.
*
* @return array|bool
* An array of request attributes of FALSE if an exception was thrown.
*/
protected
function
getPathAttributes
(
$path
,
Request
$request
)
{
if
(
$this
->
account
->
hasPermission
(
'link to any page'
))
{
$router
=
$this
->
accessUnawareRouter
;
}
else
{
$router
=
$this
->
accessAwareRouter
;
}
$path
=
$this
->
pathProcessor
->
processInbound
(
$path
,
$request
);
try
{
$this
->
requestMatcher
->
matchRequest
(
$request
);
return
$router
->
match
(
'/'
.
$path
);
}
catch
(
ResourceNotFoundException
$e
)
{
return
FALSE
;
}
catch
(
ParamNotConvertedException
$e
)
{
return
FALSE
;
...
...
@@ -88,7 +148,6 @@ public function isValid($path) {
catch
(
AccessDeniedHttpException
$e
)
{
return
FALSE
;
}
return
TRUE
;
}
}
core/lib/Drupal/Core/Path/PathValidatorInterface.php
View file @
68f576fe
...
...
@@ -2,7 +2,7 @@
/**
* @file
* Contains Drupal\Core\Path\PathValidatorInterface
* Contains
\
Drupal\Core\Path\PathValidatorInterface
*/
namespace
Drupal\Core\Path
;
...
...
@@ -12,6 +12,17 @@
*/
interface
PathValidatorInterface
{
/**
* Returns an URL object, if the path is valid and accessible.
*
* @param string $path
* The path to check.
*
* @return \Drupal\Core\Url|false
* The url object, or FALSE if the path is not valid.
*/
public
function
getUrlIfValid
(
$path
);
/**
* Checks if the URL path is valid and accessible by the current user.
*
...
...
core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php
View file @
68f576fe
...
...
@@ -22,6 +22,9 @@ interface InboundPathProcessorInterface {
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The HttpRequest object representing the current request.
*
* @return string
* The processed path.
*/
public
function
processInbound
(
$path
,
Request
$request
);
...
...
core/lib/Drupal/Core/Url.php
View file @
68f576fe
...
...
@@ -9,11 +9,9 @@
use
Drupal\Component\Utility\UrlHelper
;
use
Drupal\Core\DependencyInjection\DependencySerializationTrait
;
use
Drupal\Core\Routing\MatchingRouteNotFoundException
;
use
Drupal\Core\Routing\UrlGeneratorInterface
;
use
Symfony\Cmf\Component\Routing\RouteObjectInterface
;
use
Symfony\Component\HttpFoundation\Request
;
use
Symfony\Component\Routing\Exception\ResourceNotFoundException
;
/**
* Defines an object that holds information about a URL.
...
...
@@ -97,7 +95,15 @@ public function __construct($route_name, $route_parameters = array(), $options =
}
/**
* Returns the Url object matching a path.
* Returns the Url object matching a path. READ THE FOLLOWING SECURITY NOTE.
*
* SECURITY NOTE: The path is not checked to be valid and accessible by the
* current user to allow storing and reusing Url objects by different users.
* The 'path.validator' service getUrlIfValid() method should be used instead
* of this one if validation and access check is desired. Otherwise,
* 'access_manager' service checkNamedRoute() method should be used on the
* router name and parameters stored in the Url object returned by this
* method.
*
* @param string $path
* A path (e.g. 'node/1', 'http://drupal.org').
...
...
@@ -118,27 +124,15 @@ public static function createFromPath($path) {
// Special case the front page route.
if
(
$path
==
'<front>'
)
{
$route_name
=
$path
;
$route_parameters
=
array
();
return
new
static
(
$path
);
}
else
{
// Look up the route name and parameters used for the given path.
try
{
// We use the router without access checks because URL objects might be
// created and stored for different users.
$result
=
\
Drupal
::
service
(
'router.no_access_checks'
)
->
match
(
'/'
.
$path
);
}
catch
(
ResourceNotFoundException
$e
)
{
throw
new
MatchingRouteNotFoundException
(
sprintf
(
'No matching route could be found for the path "%s"'
,
$path
),
0
,
$e
);
}
$route_name
=
$result
[
RouteObjectInterface
::
ROUTE_NAME
];
$route_parameters
=
$result
[
'_raw_variables'
]
->
all
();
return
static
::
createFromRequest
(
Request
::
create
(
"/
$path
"
));
}
return
new
static
(
$route_name
,
$route_parameters
);
}
/**
* Returns the Url object matching a request.
* Returns the Url object matching a request.
READ THE SECURITY NOTE ON createFromPath().
*
* @param \Symfony\Component\HttpFoundation\Request $request
* A request object.
...
...
@@ -152,14 +146,9 @@ public static function createFromPath($path) {
* Thrown when the request cannot be matched.
*/
public
static
function
createFromRequest
(
Request
$request
)
{
try
{
// We use the router without access checks because URL objects might be
// created and stored for different users.
$result
=
\
Drupal
::
service
(
'router.no_access_checks'
)
->
matchRequest
(
$request
);
}
catch
(
ResourceNotFoundException
$e
)
{
throw
new
MatchingRouteNotFoundException
(
sprintf
(
'No matching route could be found for the request: %s'
,
$request
),
0
,
$e
);
}
// We use the router without access checks because URL objects might be
// created and stored for different users.
$result
=
\
Drupal
::
service
(
'router.no_access_checks'
)
->
matchRequest
(
$request
);
$route_name
=
$result
[
RouteObjectInterface
::
ROUTE_NAME
];
$route_parameters
=
$result
[
'_raw_variables'
]
->
all
();
return
new
static
(
$route_name
,
$route_parameters
);
...
...
core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
View file @
68f576fe
...
...
@@ -7,15 +7,10 @@
namespace
Drupal\link\Plugin\Field\FieldWidget
;
use
Drupal\Component\Utility\UrlHelper
;
use
Drupal\Core\Field\FieldItemListInterface
;
use
Drupal\Core\Field\WidgetBase
;
use
Drupal\Core\Form\FormStateInterface
;
use
Drupal\Core\ParamConverter\ParamNotConvertedException
;
use
Drupal\Core\Routing\MatchingRouteNotFoundException
;
use
Drupal\Core\Url
;
use
Drupal\link\LinkItemInterface
;
use
Symfony\Component\HttpKernel\Exception\NotFoundHttpException
;
/**
* Plugin implementation of the 'link' widget.
...
...
@@ -47,9 +42,10 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
$default_url_value
=
NULL
;
if
(
isset
(
$items
[
$delta
]
->
url
))
{
$url
=
Url
::
createFromPath
(
$items
[
$delta
]
->
url
);
$url
->
setOptions
(
$items
[
$delta
]
->
options
);
$default_url_value
=
ltrim
(
$url
->
toString
(),
'/'
);
if
(
$url
=
\
Drupal
::
pathValidator
()
->
getUrlIfValid
(
$items
[
$delta
]
->
url
))
{
$url
->
setOptions
(
$items
[
$delta
]
->
options
);
$default_url_value
=
ltrim
(
$url
->
toString
(),
'/'
);
}
}
$element
[
'url'
]
=
array
(
'#type'
=>
'url'
,
...
...
@@ -204,32 +200,16 @@ public function validateTitle(&$element, FormStateInterface $form_state, $form)
public
function
massageFormValues
(
array
$values
,
array
$form
,
FormStateInterface
$form_state
)
{
foreach
(
$values
as
&
$value
)
{
if
(
!
empty
(
$value
[
'url'
]))
{
try
{
$parsed_url
=
UrlHelper
::
parse
(
$value
[
'url'
]);
// If internal links are supported, look up whether the given value is
// a path alias and store the system path instead.
if
(
$this
->
supportsInternalLinks
()
&&
!
UrlHelper
::
isExternal
(
$value
[
'url'
]))
{
$parsed_url
[
'path'
]
=
\
Drupal
::
service
(
'path.alias_manager'
)
->
getPathByAlias
(
$parsed_url
[
'path'
]);
}
$url
=
Url
::
createFromPath
(
$parsed_url
[
'path'
]);
$url
->
setOption
(
'query'
,
$parsed_url
[
'query'
]);
$url
->
setOption
(
'fragment'
,
$parsed_url
[
'fragment'
]);
$url
->
setOption
(
'attributes'
,
$value
[
'attributes'
]);
$value
+=
$url
->
toArray
();
// Reset the URL value to contain only the path.
$value
[
'url'
]
=
$parsed_url
[
'path'
];
}
catch
(
NotFoundHttpException
$e
)
{
// Nothing to do here, LinkTypeConstraintValidator emits errors.
}
catch
(
MatchingRouteNotFoundException
$e
)
{
// Nothing to do here, LinkTypeConstraintValidator emits errors.
$url
=
\
Drupal
::
pathValidator
()
->
getUrlIfValid
(
$value
[
'url'
]);
if
(
!
$url
)
{
return
$values
;
}
catch
(
ParamNotConvertedException
$e
)
{
// Nothing to do here, LinkTypeConstraintValidator emits errors.
$value
+=
$url
->
toArray
();
// Reset the URL value to contain only the path.
if
(
!
$url
->
isExternal
()
&&
$this
->
supportsInternalLinks
())
{
$value
[
'url'
]
=
substr
(
$url
->
toString
(),
strlen
(
\
Drupal
::
request
()
->
getBasePath
()
.
'/'
));
}
}
}
...
...
core/modules/link/src/Plugin/Validation/Constraint/LinkTypeConstraint.php
View file @
68f576fe
...
...
@@ -8,14 +8,9 @@
namespace
Drupal\link\Plugin\Validation\Constraint
;
use
Drupal\link\LinkItemInterface
;
use
Drupal\Core\Url
;
use
Drupal\Core\Routing\MatchingRouteNotFoundException
;
use
Drupal\Core\ParamConverter\ParamNotConvertedException
;
use
Drupal\Component\Utility\UrlHelper
;
use
Symfony\Component\Validator\Constraint
;
use
Symfony\Component\Validator\ConstraintValidatorInterface
;
use
Symfony\Component\Validator\ExecutionContextInterface
;
use
Symfony\Component\HttpKernel\Exception\NotFoundHttpException
;
/**
* Validation constraint for links receiving data allowed by its settings.
...
...
@@ -53,36 +48,20 @@ public function validatedBy() {
*/
public
function
validate
(
$value
,
Constraint
$constraint
)
{
if
(
isset
(
$value
))
{
$url_is_valid
=
TRU
E
;
$url_is_valid
=
FALS
E
;
/** @var $link_item \Drupal\link\LinkItemInterface */
$link_item
=
$value
;
$link_type
=
$link_item
->
getFieldDefinition
()
->
getSetting
(
'link_type'
);
$url_string
=
$link_item
->
url
;
// Validate the url property.
if
(
$url_string
!==
''
)
{
try
{
// @todo This shouldn't be needed, but massageFormValues() may not
// run.
$parsed_url
=
UrlHelper
::
parse
(
$url_string
);
if
(
$url
=
\
Drupal
::
pathValidator
()
->
getUrlIfValid
(
$url_string
))
{
$url_is_valid
=
(
bool
)
$url
;
$url
=
Url
::
createFromPath
(
$parsed_url
[
'path'
]);
if
(
$url
->
isExternal
()
&&
!
UrlHelper
::
isValid
(
$url_string
,
TRUE
))
{
$url_is_valid
=
FALSE
;
}
elseif
(
$url
->
isExternal
()
&&
!
(
$link_type
&
LinkItemInterface
::
LINK_EXTERNAL
))
{
if
(
$url
->
isExternal
()
&&
!
(
$link_type
&
LinkItemInterface
::
LINK_EXTERNAL
))
{
$url_is_valid
=
FALSE
;
}
}
catch
(
NotFoundHttpException
$e
)
{
$url_is_valid
=
FALSE
;
}
catch
(
MatchingRouteNotFoundException
$e
)
{
$url_is_valid
=
FALSE
;
}
catch
(
ParamNotConvertedException
$e
)
{
$url_is_valid
=
FALSE
;
}
}
if
(
!
$url_is_valid
)
{
$this
->
context
->
addViolation
(
$this
->
message
,
array
(
'%url'
=>
$url_string
));
...
...
core/modules/link/src/Tests/LinkFieldTest.php
View file @
68f576fe
...
...
@@ -52,6 +52,7 @@ protected function setUp() {
$this
->
web_user
=
$this
->
drupalCreateUser
(
array
(
'view test entity'
,
'administer entity_test content'
,
'link to any page'
,
));
$this
->
drupalLogin
(
$this
->
web_user
);
}
...
...
core/modules/menu_link_content/src/Form/MenuLinkContentForm.php
View file @
68f576fe
...
...
@@ -18,11 +18,9 @@
use
Drupal\Core\Menu\Form\MenuLinkFormInterface
;
use
Drupal\Core\Menu\MenuLinkInterface
;
use
Drupal\Core\Menu\MenuParentFormSelectorInterface
;
use
Drupal\Core\ParamConverter\ParamNotConvertedException
;
use
Drupal\Core\Path\AliasManagerInterface
;
use
Drupal\Core\
Routing\MatchingRouteNotFoundException
;
use
Drupal\Core\
Path\PathValidatorInterface
;
use
Drupal\Core\Session\AccountInterface
;
use
Drupal\Core\Url
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
use
Symfony\Component\Routing\RequestContext
;
...
...
@@ -77,6 +75,13 @@ class MenuLinkContentForm extends ContentEntityForm implements MenuLinkFormInter
*/
protected
$account
;
/**
* The path validator.
*
* @var \Drupal\Core\Path\PathValidatorInterface
*/
protected
$pathValidator
;
/**
* Constructs a MenuLinkContentForm object.
*
...
...
@@ -96,8 +101,10 @@ class MenuLinkContentForm extends ContentEntityForm implements MenuLinkFormInter
* The access manager.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
* @param \Drupal\Core\Path\PathValidatorInterface $path_validator
* The path validator.
*/
public
function
__construct
(
EntityManagerInterface
$entity_manager
,
MenuParentFormSelectorInterface
$menu_parent_selector
,
AliasManagerInterface
$alias_manager
,
ModuleHandlerInterface
$module_handler
,
RequestContext
$request_context
,
LanguageManagerInterface
$language_manager
,
AccessManagerInterface
$access_manager
,
AccountInterface
$account
)
{
public
function
__construct
(
EntityManagerInterface
$entity_manager
,
MenuParentFormSelectorInterface
$menu_parent_selector
,
AliasManagerInterface
$alias_manager
,
ModuleHandlerInterface
$module_handler
,
RequestContext
$request_context
,
LanguageManagerInterface
$language_manager
,
AccessManagerInterface
$access_manager
,
AccountInterface
$account
,
PathValidatorInterface
$path_validator
)
{
parent
::
__construct
(
$entity_manager
,
$language_manager
);
$this
->
menuParentSelector
=
$menu_parent_selector
;
$this
->
pathAliasManager
=
$alias_manager
;
...
...
@@ -106,6 +113,7 @@ public function __construct(EntityManagerInterface $entity_manager, MenuParentFo
$this
->
languageManager
=
$language_manager
;
$this
->
accessManager
=
$access_manager
;
$this
->
account
=
$account
;
$this
->
pathValidator
=
$path_validator
;
}
/**
...
...
@@ -120,7 +128,8 @@ public static function create(ContainerInterface $container) {
$container
->
get
(
'router.request_context'
),
$container
->
get
(
'language_manager'
),
$container
->
get
(
'access_manager'
),
$container
->
get
(
'current_user'
)
$container
->
get
(
'current_user'
),
$container
->
get
(
'path.validator'
)
);
}
...
...
@@ -167,46 +176,6 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
$this
->
save
(
$form
,
$form_state
);
}
/**
* Breaks up a user-entered URL or path into all the relevant parts.
*
* @param string $url
* The user-entered URL or path.
*
* @return array
* The extracted parts.
*/
protected
function
extractUrl
(
$url
)
{
$extracted
=
UrlHelper
::
parse
(
$url
);
$external
=
UrlHelper
::
isExternal
(
$url
);
if
(
$external
)
{
$extracted
[
'url'
]
=
$extracted
[
'path'
];
$extracted
[
'route_name'
]
=
NULL
;
$extracted
[
'route_parameters'
]
=
array
();
}
else
{
$extracted
[
'url'
]
=
''
;
// If the path doesn't match a Drupal path, the route should end up empty.
$extracted
[
'route_name'
]
=
NULL
;
$extracted
[
'route_parameters'
]
=
array
();
try
{
// Find the route_name.
$normal_path
=
$this
->
pathAliasManager
->
getPathByAlias
(
$extracted
[
'path'
]);
$url_obj
=
Url
::
createFromPath
(
$normal_path
);
$extracted
[
'route_name'
]
=
$url_obj
->
getRouteName
();
$extracted
[
'route_parameters'
]
=
$url_obj
->
getRouteParameters
();
}
catch
(
MatchingRouteNotFoundException
$e
)
{
// The path doesn't match a Drupal path.
}
catch
(
ParamNotConvertedException
$e
)
{
// A path like node/99 matched a route, but the route parameter was
// invalid (e.g. node with ID 99 does not exist).
}
}
return
$extracted
;
}
/**
* {@inheritdoc}
*/
...
...
@@ -220,17 +189,24 @@ public function extractFormValues(array &$form, FormStateInterface $form_state)
}
$new_definition
[
'parent'
]
=
isset
(
$parent
)
?
$parent
:
''
;