123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- <?php
- namespace Drupal\Core\Path;
- use Drupal\Component\Utility\UrlHelper;
- use Drupal\Core\ParamConverter\ParamNotConvertedException;
- use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
- use Drupal\Core\Routing\AccessAwareRouterInterface;
- use Drupal\Core\Routing\RequestContext;
- 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\Exception\MethodNotAllowedException;
- use Symfony\Component\Routing\Exception\ResourceNotFoundException;
- use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
- /**
- * Provides a default path validator and access checker.
- */
- class PathValidator implements PathValidatorInterface {
- /**
- * The access aware router.
- *
- * @var \Drupal\Core\Routing\AccessAwareRouterInterface
- */
- protected $accessAwareRouter;
- /**
- * A router implementation which does not check access.
- *
- * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface
- */
- protected $accessUnawareRouter;
- /**
- * The current user.
- *
- * @var \Drupal\Core\Session\AccountInterface
- */
- protected $account;
- /**
- * The path processor.
- *
- * @var \Drupal\Core\PathProcessor\InboundPathProcessorInterface
- */
- protected $pathProcessor;
- /**
- * Creates a new PathValidator.
- *
- * @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(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) {
- return (bool) $this->getUrlIfValid($path);
- }
- /**
- * {@inheritdoc}
- */
- public function getUrlIfValid($path) {
- return $this->getUrl($path, TRUE);
- }
- /**
- * {@inheritdoc}
- */
- public function getUrlIfValidWithoutAccessCheck($path) {
- return $this->getUrl($path, FALSE);
- }
- /**
- * Helper for getUrlIfValid() and getUrlIfValidWithoutAccessCheck().
- */
- protected function getUrl($path, $access_check) {
- $path = ltrim($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 ($parsed_url['path'] == '<none>') {
- return new Url('<none>', [], $options);
- }
- elseif (UrlHelper::isExternal($path) && UrlHelper::isValid($path)) {
- if (empty($parsed_url['path'])) {
- return FALSE;
- }
- return Url::fromUri($path);
- }
- $request = Request::create('/' . $path);
- $attributes = $this->getPathAttributes($path, $request, $access_check);
- if (!$attributes) {
- return FALSE;
- }
- $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.
- * @param bool $access_check
- * If FALSE then skip access check and check only whether the path is
- * valid.
- *
- * @return array|bool
- * An array of request attributes of FALSE if an exception was thrown.
- */
- protected function getPathAttributes($path, Request $request, $access_check) {
- if (!$access_check || $this->account->hasPermission('link to any page')) {
- $router = $this->accessUnawareRouter;
- }
- else {
- $router = $this->accessAwareRouter;
- }
- $initial_request_context = $router->getContext() ? $router->getContext() : new RequestContext();
- $path = $this->pathProcessor->processInbound('/' . $path, $request);
- try {
- $request_context = new RequestContext();
- $request_context->fromRequest($request);
- $router->setContext($request_context);
- $result = $router->match($path);
- }
- catch (ResourceNotFoundException $e) {
- $result = FALSE;
- }
- catch (ParamNotConvertedException $e) {
- $result = FALSE;
- }
- catch (AccessDeniedHttpException $e) {
- $result = FALSE;
- }
- catch (MethodNotAllowedException $e) {
- $result = FALSE;
- }
- $router->setContext($initial_request_context);
- return $result;
- }
- }
|