Example #1
5
 /**
  * @param HttpRequest $httpRequest
  *
  * @return Response
  */
 public function handle(HttpRequest $httpRequest)
 {
     try {
         $routeParameters = $this->urlMatcher->matchRequest($httpRequest);
         $httpRequest->attributes->add($routeParameters);
         $request = $this->extractRequestFromRouteParameters($routeParameters);
         $controller = $this->extractControllerFromRouteParameters($routeParameters);
         return $controller->handleRequest($request, $this->serviceContainer);
     } catch (ValidationExceptionSet $exception) {
         return $this->errorResponseFactory->createBadRequestResponse($exception);
     } catch (BadRequestHttpException $exception) {
         return $this->errorResponseFactory->createBadRequestResponse($exception);
     } catch (NotFoundHttpException $exception) {
         return $this->errorResponseFactory->createNotFoundResponse($exception);
     } catch (MethodNotAllowedException $exception) {
         $exception = new MethodNotAllowedHttpException($exception->getAllowedMethods(), 'Used request method not allowed. Allowed: ' . implode(', ', $exception->getAllowedMethods()));
         return $this->errorResponseFactory->createMethodNotAllowedResponse($exception);
     } catch (\Exception $exception) {
         return $this->errorResponseFactory->createInternalServerErrorResponse($exception);
     }
 }
Example #2
0
 /**
  * @param Request $request
  */
 public function match(Request $request)
 {
     // Initialize the context that is also used by the generator (assuming matcher and generator share the same
     // context instance).
     $this->context->fromRequest($request);
     if ($request->attributes->has('_controller')) {
         // Routing is already done.
         return;
     }
     // Add attributes based on the request (routing).
     try {
         // Matching a request is more powerful than matching a URL path + context, so try that first.
         if ($this->matcher instanceof RequestMatcherInterface) {
             $parameters = $this->matcher->matchRequest($request);
         } else {
             $parameters = $this->matcher->match($request->getPathInfo());
         }
         if (null !== $this->logger) {
             $this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], $this->parametersToString($parameters)));
         }
         $request->attributes->add($parameters);
         unset($parameters['_route']);
         unset($parameters['_controller']);
         $request->attributes->set('_route_params', $parameters);
     } catch (ResourceNotFoundException $e) {
         $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getPathInfo());
         throw new NotFoundHttpException($message, $e);
     } catch (MethodNotAllowedException $e) {
         $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getPathInfo(), strtoupper(implode(', ', $e->getAllowedMethods())));
         throw new MethodNotAllowedException($e->getAllowedMethods(), $message);
     }
 }
Example #3
0
 /**
  * Constructor.
  *
  * RequestStack will become required in 3.0.
  *
  * @param UrlMatcherInterface|RequestMatcherInterface $matcher      The Url or Request matcher
  * @param RequestStack                                $requestStack A RequestStack instance
  * @param RequestContext|null                         $context      The RequestContext (can be null when $matcher implements RequestContextAwareInterface)
  * @param LoggerInterface|null                        $logger       The logger
  *
  * @throws \InvalidArgumentException
  */
 public function __construct($matcher, $requestStack = null, $context = null, $logger = null)
 {
     if ($requestStack instanceof RequestContext || $context instanceof LoggerInterface || $logger instanceof RequestStack) {
         $tmp = $requestStack;
         $requestStack = $logger;
         $logger = $context;
         $context = $tmp;
         @trigger_error('The ' . __METHOD__ . ' method now requires a RequestStack to be given as second argument as ' . __CLASS__ . '::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
     } elseif (!$requestStack instanceof RequestStack) {
         @trigger_error('The ' . __METHOD__ . ' method now requires a RequestStack instance as ' . __CLASS__ . '::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
     }
     if (null !== $requestStack && !$requestStack instanceof RequestStack) {
         throw new \InvalidArgumentException('RequestStack instance expected.');
     }
     if (null !== $context && !$context instanceof RequestContext) {
         throw new \InvalidArgumentException('RequestContext instance expected.');
     }
     if (null !== $logger && !$logger instanceof LoggerInterface) {
         throw new \InvalidArgumentException('Logger must implement LoggerInterface.');
     }
     if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
         throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
     }
     if (null === $context && !$matcher instanceof RequestContextAwareInterface) {
         throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.');
     }
     $this->matcher = $matcher;
     $this->context = $context ?: $matcher->getContext();
     $this->requestStack = $requestStack;
     $this->logger = $logger;
 }
Example #4
0
 /**
  * Constructor.
  *
  * @param UrlMatcherInterface|RequestMatcherInterface $matcher The Url or Request matcher
  * @param RequestContext|null                         $context The RequestContext (can be null when $matcher implements RequestContextAwareInterface)
  * @param LoggerInterface|null                        $logger  The logger
  *
  * @throws \InvalidArgumentException
  */
 public function __construct($matcher, RequestContext $context = null, LoggerInterface $logger = null)
 {
     if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
         throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
     }
     if (null === $context && !$matcher instanceof RequestContextAwareInterface) {
         throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.');
     }
     $this->matcher = $matcher;
     $this->context = $context ?: $matcher->getContext();
     $this->logger = $logger;
 }
Example #5
0
 protected function getAllowedMethods($uri)
 {
     try {
         $route = $this->requestMatcher->matchRequest(Request::create($uri, 'OPTIONS'));
         if (isset($route['allowedMethods'])) {
             return explode(',', $route['allowedMethods']);
         }
     } catch (ResourceNotFoundException $e) {
         // the provider doesn't care about a not found
     } catch (MethodNotAllowedException $e) {
         // neither does it care about a method not allowed
     }
     return array();
 }
 /**
  * Constructor.
  *
  * RequestStack will become required in 3.0.
  *
  * @param UrlMatcherInterface|RequestMatcherInterface $matcher      The Url or Request matcher
  * @param RequestContext|null                         $context      The RequestContext (can be null when $matcher implements RequestContextAwareInterface)
  * @param LoggerInterface|null                        $logger       The logger
  * @param RequestStack|null                           $requestStack A RequestStack instance
  *
  * @throws \InvalidArgumentException
  */
 public function __construct($matcher, RequestContext $context = null, LoggerInterface $logger = null, RequestStack $requestStack = null)
 {
     if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
         throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
     }
     if (null === $context && !$matcher instanceof RequestContextAwareInterface) {
         throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.');
     }
     if (!$requestStack instanceof RequestStack) {
         @trigger_error('The ' . __METHOD__ . ' method now requires a RequestStack instance as ' . __CLASS__ . '::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
     }
     $this->matcher = $matcher;
     $this->context = $context ?: $matcher->getContext();
     $this->requestStack = $requestStack;
     $this->logger = $logger;
 }
 /**
  * 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;
     }
 }
Example #8
0
 /**
  * {@inheritdoc}
  */
 public function isValid($path)
 {
     // External URLs and the front page are always valid.
     if ($path == '<front>' || UrlHelper::isExternal($path)) {
         return TRUE;
     }
     // Check the routing system.
     $collection = $this->routeProvider->getRoutesByPattern('/' . $path);
     if ($collection->count() == 0) {
         return FALSE;
     }
     $request = RequestHelper::duplicate($this->requestStack->getCurrentRequest(), '/' . $path);
     $request->attributes->set('_system_path', $path);
     // We indicate that a menu administrator is running the menu access check.
     $request->attributes->set('_menu_admin', TRUE);
     // Attempt to match this path to provide a fully built request to the
     // access checker.
     try {
         $request->attributes->add($this->requestMatcher->matchRequest($request));
     } catch (ParamNotConvertedException $e) {
         return FALSE;
     }
     // Consult the access manager.
     $routes = $collection->all();
     $route = reset($routes);
     return $this->accessManager->check($route, $request, $this->account);
 }
Example #9
0
 /**
  * @return RequestMatcherInterface|UrlMatcherInterface
  */
 public function getMatcher()
 {
     /* we may not set the context in DynamicRouter::setContext as this
      * would lead to symfony cache warmup problems.
      * a request matcher does not need the request context separately as it
      * can get it from the request.
      */
     if ($this->matcher instanceof RequestContextAwareInterface) {
         $this->matcher->setContext($this->getContext());
     }
     return $this->matcher;
 }
 /**
  * Tests the breadcrumb for a user path.
  *
  * @covers ::build()
  * @covers ::getRequestForPath()
  */
 public function testBuildWithUserPath()
 {
     $this->context->expects($this->once())->method('getPathInfo')->will($this->returnValue('/user/1/edit'));
     $this->setupStubPathProcessor();
     $route_1 = new Route('/user/1');
     $this->requestMatcher->expects($this->exactly(1))->method('matchRequest')->will($this->returnCallback(function (Request $request) use($route_1) {
         if ($request->getPathInfo() == '/user/1') {
             return array(RouteObjectInterface::ROUTE_NAME => 'user_page', RouteObjectInterface::ROUTE_OBJECT => $route_1, '_raw_variables' => new ParameterBag(array()));
         }
     }));
     $this->setupAccessManagerToAllow();
     $this->titleResolver->expects($this->once())->method('getTitle')->with($this->anything(), $route_1)->will($this->returnValue('Admin'));
     $links = $this->builder->build($this->getMock('Drupal\\Core\\Routing\\RouteMatchInterface'));
     $this->assertEquals(array(0 => new Link('Home', new Url('<front>')), 1 => new Link('Admin', new Url('user_page'))), $links);
 }
 /**
  * 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;
     }
 }
 /**
  * Tests the breadcrumb for a user path.
  *
  * @covers ::build()
  * @covers ::getRequestForPath()
  */
 public function testBuildWithUserPath()
 {
     $this->context->expects($this->once())->method('getPathInfo')->will($this->returnValue('/user/1/edit'));
     $this->setupStubPathProcessor();
     $route_1 = new Route('/user/1');
     $this->requestMatcher->expects($this->exactly(1))->method('matchRequest')->will($this->returnCallback(function (Request $request) use($route_1) {
         if ($request->getPathInfo() == '/user/1') {
             return array(RouteObjectInterface::ROUTE_NAME => 'user_page', RouteObjectInterface::ROUTE_OBJECT => $route_1, '_raw_variables' => new ParameterBag(array()));
         }
     }));
     $link_user = '******';
     $link_front = '<a href="/">Home</a>';
     $this->linkGenerator->expects($this->at(0))->method('generate')->with('Admin', 'user_page', array(), array('html' => TRUE))->will($this->returnValue($link_user));
     $this->linkGenerator->expects($this->at(1))->method('generate')->with('Home', '<front>', array(), array())->will($this->returnValue($link_front));
     $this->setupAccessManagerWithTrue();
     $this->titleResolver->expects($this->once())->method('getTitle')->with($this->anything(), $route_1)->will($this->returnValue('Admin'));
     $links = $this->builder->build($this->getMock('Drupal\\Core\\Routing\\RouteMatchInterface'));
     $this->assertEquals(array(0 => '<a href="/">Home</a>', 1 => $link_user), $links);
 }