/**
  * Converts the request path to a system path.
  *
  * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
  *   The Event to process.
  */
 public function onKernelRequestConvertPath(GetResponseEvent $event)
 {
     $request = $event->getRequest();
     $path = trim($request->getPathInfo(), '/');
     $path = $this->pathProcessor->processInbound($path, $request);
     $request->attributes->set('_system_path', $path);
     // Set the cache key on the alias manager cache decorator.
     if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
         $this->aliasManager->setCacheKey($path);
     }
 }
예제 #2
0
 /**
  * Handles the redirect if any found.
  *
  * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
  *   The event to process.
  */
 public function onKernelRequestCheckRedirect(GetResponseEvent $event)
 {
     $request = $event->getRequest();
     if (!$this->checker->canRedirect($request)) {
         return;
     }
     // Get URL info and process it to be used for hash generation.
     parse_str($request->getQueryString(), $request_query);
     // Do the inbound processing so that for example language prefixes are
     // removed.
     $path = $this->pathProcessor->processInbound($request->getPathInfo(), $request);
     $path = ltrim($path, '/');
     $this->context->fromRequest($request);
     try {
         $redirect = $this->redirectRepository->findMatchingRedirect($path, $request_query, $this->languageManager->getCurrentLanguage()->getId());
     } catch (RedirectLoopException $e) {
         \Drupal::logger('redirect')->warning($e->getMessage());
         $response = new Response();
         $response->setStatusCode(503);
         $response->setContent('Service unavailable');
         $event->setResponse($response);
         return;
     }
     if (!empty($redirect)) {
         // Handle internal path.
         $url = $redirect->getRedirectUrl();
         if ($this->config->get('passthrough_querystring')) {
             $url->setOption('query', (array) $url->getOption('query') + $request_query);
         }
         $headers = ['X-Redirect-ID' => $redirect->id()];
         $response = new TrustedRedirectResponse($url->setAbsolute()->toString(), $redirect->getStatusCode(), $headers);
         $response->addCacheableDependency($redirect);
         $event->setResponse($response);
     }
 }
 /**
  * Matches a path in the router.
  *
  * @param string $path
  *   The request path.
  * @param array $exclude
  *   An array of paths or system paths to skip.
  *
  * @return \Symfony\Component\HttpFoundation\Request
  *   A populated request object or NULL if the path couldn't be matched.
  */
 protected function getRequestForPath($path, array $exclude)
 {
     if (!empty($exclude[$path])) {
         return NULL;
     }
     // @todo Use the RequestHelper once https://drupal.org/node/2090293 is
     //   fixed.
     $request = Request::create($this->context->getBaseUrl() . '/' . $path);
     // Performance optimization: set a short accept header to reduce overhead in
     // AcceptHeaderMatcher when matching the request.
     $request->headers->set('Accept', 'text/html');
     // Find the system path by resolving aliases, language prefix, etc.
     $processed = $this->pathProcessor->processInbound($path, $request);
     if (empty($processed) || !empty($exclude[$processed])) {
         // This resolves to the front page, which we already add.
         return NULL;
     }
     $request->attributes->set('_system_path', $processed);
     // Attempt to match this path to provide a fully built request.
     try {
         $request->attributes->add($this->router->matchRequest($request));
         return $request;
     } catch (ParamNotConvertedException $e) {
         return NULL;
     } catch (ResourceNotFoundException $e) {
         return NULL;
     } catch (MethodNotAllowedException $e) {
         return NULL;
     } catch (AccessDeniedHttpException $e) {
         return NULL;
     }
 }
 /**
  * Tests the getUrlIfValid() method where there is no access.
  */
 public function testGetUrlIfValidWithoutAccess()
 {
     $this->account->expects($this->once())->method('hasPermission')->with('link to any page')->willReturn(FALSE);
     $this->accessAwareRouter->expects($this->once())->method('match')->with('/test-path')->willThrowException(new AccessDeniedHttpException());
     $this->pathProcessor->expects($this->once())->method('processInbound')->willReturnArgument(0);
     $url = $this->pathValidator->getUrlIfValid('test-path');
     $this->assertFalse($url);
 }
예제 #5
0
 /**
  * Tests the getUrlIfValidWithoutAccessCheck() method.
  *
  * @covers ::getUrlIfValidWithoutAccessCheck
  */
 public function testGetUrlIfValidWithoutAccessCheck()
 {
     $this->account->expects($this->never())->method('hasPermission')->with('link to any page');
     $this->accessAwareRouter->expects($this->never())->method('match');
     $this->accessUnawareRouter->expects($this->once())->method('match')->with('/test-path')->willReturn([RouteObjectInterface::ROUTE_NAME => 'test_route', '_raw_variables' => new ParameterBag(['key' => 'value'])]);
     $this->pathProcessor->expects($this->once())->method('processInbound')->willReturnArgument(0);
     $url = $this->pathValidator->getUrlIfValidWithoutAccessCheck('test-path');
     $this->assertInstanceOf('Drupal\\Core\\Url', $url);
     $this->assertEquals('test_route', $url->getRouteName());
     $this->assertEquals(['key' => 'value'], $url->getRouteParameters());
 }
 /**
  * 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 {
         return $router->match('/' . $path);
     } catch (ResourceNotFoundException $e) {
         return FALSE;
     } catch (ParamNotConvertedException $e) {
         return FALSE;
     } catch (AccessDeniedHttpException $e) {
         return FALSE;
     }
 }
 /**
  * Matches a path in the router.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   Page request object.
  * @param string $path
  *   Path to look up.
  *
  * @return \Symfony\Component\HttpFoundation\Request|null
  *   A populated request object or NULL if the patch could not be matched.
  */
 protected function getRequestForPath(Request $request, $path)
 {
     // @todo Use RequestHelper::duplicate once https://drupal.org/node/2090293
     //   is fixed.
     $route_request = Request::create($request->getBaseUrl() . '/' . $path);
     // Find the system path by resolving aliases, language prefix, etc.
     $processed = $this->pathProcessor->processInbound($path, $route_request);
     $route_request->attributes->set('_system_path', $processed);
     // Attempt to match this path to provide a fully built request.
     try {
         $route_request->attributes->add($this->router->matchRequest($route_request));
         return $route_request;
     } catch (ParamNotConvertedException $e) {
         return NULL;
     } catch (ResourceNotFoundException $e) {
         return NULL;
     }
 }
예제 #8
0
 /**
  * Finds routes that may potentially match the request.
  *
  * This may return a mixed list of class instances, but all routes returned
  * must extend the core symfony route. The classes may also implement
  * RouteObjectInterface to link to a content document.
  *
  * This method may not throw an exception based on implementation specific
  * restrictions on the url. That case is considered a not found - returning
  * an empty array. Exceptions are only used to abort the whole request in
  * case something is seriously broken, like the storage backend being down.
  *
  * Note that implementations may not implement an optimal matching
  * algorithm, simply a reasonable first pass.  That allows for potentially
  * very large route sets to be filtered down to likely candidates, which
  * may then be filtered in memory more completely.
  *
  * @param Request $request A request against which to match.
  *
  * @return \Symfony\Component\Routing\RouteCollection with all urls that
  *      could potentially match $request. Empty collection if nothing can
  *      match.
  */
 public function getRouteCollectionForRequest(Request $request)
 {
     // Cache both the system path as well as route parameters and matching
     // routes.
     $cid = 'route:' . $request->getPathInfo() . ':' . $request->getQueryString();
     if ($cached = $this->cache->get($cid)) {
         $this->currentPath->setPath($cached->data['path'], $request);
         $request->query->replace($cached->data['query']);
         return $cached->data['routes'];
     } else {
         // 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);
         // Incoming path processors may also set query parameters.
         $query_parameters = $request->query->all();
         $routes = $this->getRoutesByPath(rtrim($path, '/'));
         $cache_value = ['path' => $path, 'query' => $query_parameters, 'routes' => $routes];
         $this->cache->set($cid, $cache_value, CacheBackendInterface::CACHE_PERMANENT, ['route_match']);
         return $routes;
     }
 }
예제 #9
0
  /**
   * {@inheritdoc}
   */
  public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleableMetadata = NULL) {
    if (isset($options['absolute']) && $options['absolute']) {
      return $path;
    }
    $original_path = $path;
    $subpath = [];
    $max_depth = $this->getMaxDepth();
    $i = 0;
    while (($path_array = explode('/', ltrim($path, '/'))) && ($max_depth === 0 || $i < $max_depth)) {
      $i++;
      $subpath[] = array_pop($path_array);
      if (empty($path_array)) {
        break;
      }
      $path = '/' . implode('/', $path_array);
      $processed_path = $this->pathProcessor->processOutbound($path, $options, $request);
      if ($processed_path !== $path) {
        $path = $processed_path . '/' . implode('/', array_reverse($subpath));
        return $path;
      }
    }

    return $original_path;
  }
 protected function setupStubPathProcessor()
 {
     $this->pathProcessor->expects($this->any())->method('processInbound')->will($this->returnArgument(0));
 }