예제 #1
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);
     }
 }
예제 #2
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;
 }
예제 #3
0
 public function __construct(Profiler $profiler = null, \Twig_Environment $twig, UrlMatcherInterface $matcher = null, RouteCollection $routes = null)
 {
     $this->profiler = $profiler;
     $this->twig = $twig;
     $this->matcher = $matcher;
     $this->routes = null === $routes && $matcher instanceof RouterInterface ? $matcher->getRouteCollection() : $routes;
 }
예제 #4
0
파일: Router.php 프로젝트: igez/gaiaehr
 /**
  * {@inheritdoc}
  * @throws \UnexpectedValueException If a controller is not \Ratchet\Http\HttpServerInterface
  */
 public function onOpen(ConnectionInterface $conn, RequestInterface $request = null)
 {
     if (null === $request) {
         throw new \UnexpectedValueException('$request can not be null');
     }
     $context = $this->_matcher->getContext();
     $context->setMethod($request->getMethod());
     $context->setHost($request->getHost());
     try {
         $route = $this->_matcher->match($request->getPath());
     } catch (MethodNotAllowedException $nae) {
         return $this->close($conn, 403);
     } catch (ResourceNotFoundException $nfe) {
         return $this->close($conn, 404);
     }
     if (is_string($route['_controller']) && class_exists($route['_controller'])) {
         $route['_controller'] = new $route['_controller']();
     }
     if (!$route['_controller'] instanceof HttpServerInterface) {
         throw new \UnexpectedValueException('All routes must implement Ratchet\\Http\\HttpServerInterface');
     }
     $parameters = array();
     foreach ($route as $key => $value) {
         if (is_string($key) && '_' !== substr($key, 0, 1)) {
             $parameters[$key] = $value;
         }
     }
     $url = Url::factory($request->getPath());
     $url->setQuery($parameters);
     $request->setUrl($url);
     $conn->controller = $route['_controller'];
     $conn->controller->onOpen($conn, $request);
 }
예제 #5
0
 function it_throws_an_exception_if_neither_create_nor_update_key_word_has_been_found(Session $session, SymfonyPageInterface $createPage, SymfonyPageInterface $updatePage, UrlMatcherInterface $urlMatcher)
 {
     $session->getCurrentUrl()->willReturn('https://sylius.com/resource/show');
     $urlMatcher->match('/resource/show')->willReturn(['_route' => 'sylius_resource_show']);
     $createPage->getRouteName()->willReturn('sylius_resource_create');
     $updatePage->getRouteName()->willReturn('sylius_resource_update');
     $this->shouldThrow(\LogicException::class)->during('getCurrentPageWithForm', [[$createPage, $updatePage]]);
 }
예제 #6
0
 /**
  * {@inheritdoc}
  * 
  * @throws \LogicException
  */
 public function getCurrentPageWithForm(array $pages)
 {
     $routeParameters = $this->urlMatcher->match(parse_url($this->session->getCurrentUrl(), PHP_URL_PATH));
     Assert::allIsInstanceOf($pages, SymfonyPageInterface::class);
     foreach ($pages as $page) {
         if ($routeParameters['_route'] === $page->getRouteName()) {
             return $page;
         }
     }
     throw new \LogicException('Route name could not be matched to provided pages.');
 }
예제 #7
0
 /**
  * {@inheritdoc}
  * 
  * @throws \LogicException
  */
 public function getCurrentPageWithForm(CreatePageInterface $createPage, UpdatePageInterface $updatePage)
 {
     $routeParameters = $this->urlMatcher->match($this->session->getCurrentUrl());
     if (false !== strpos($routeParameters['_route'], 'create')) {
         return $createPage;
     }
     if (false !== strpos($routeParameters['_route'], 'update')) {
         return $updatePage;
     }
     throw new \LogicException('Route name does not have any of "update" or "create" keyword, so matcher was unable to match proper page.');
 }
예제 #8
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;
 }
 /**
  * {@inheritdoc}
  */
 protected function setUp()
 {
     $this->configFactory = $this->getConfigFactoryStub(['system.site' => ['page.403' => '/access-denied-page', 'page.404' => '/not-found-page']]);
     $this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface');
     $this->logger = $this->getMock('Psr\\Log\\LoggerInterface');
     $this->redirectDestination = $this->getMock('\\Drupal\\Core\\Routing\\RedirectDestinationInterface');
     $this->redirectDestination->expects($this->any())->method('getAsArray')->willReturn(['destination' => 'test']);
     $this->accessUnawareRouter = $this->getMock('Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface');
     $this->accessUnawareRouter->expects($this->any())->method('match')->willReturn(['_controller' => 'mocked']);
     $this->customPageSubscriber = new CustomPageExceptionHtmlSubscriber($this->configFactory, $this->kernel, $this->logger, $this->redirectDestination, $this->accessUnawareRouter);
     // You can't create an exception in PHP without throwing it. Store the
     // current error_log, and disable it temporarily.
     $this->errorLog = ini_set('error_log', file_exists('/dev/null') ? '/dev/null' : 'nul');
 }
예제 #10
0
 /**
  * Gets the UrlMatcher instance associated with this Router.
  *
  * @return UrlMatcherInterface A UrlMatcherInterface instance
  */
 public function getMatcher()
 {
     if (null !== $this->matcher) {
         return $this->matcher;
     }
     if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
         $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
         if (method_exists($this->matcher, 'addExpressionLanguageProvider')) {
             foreach ($this->expressionLanguageProviders as $provider) {
                 $this->matcher->addExpressionLanguageProvider($provider);
             }
         }
         return $this->matcher;
     }
     $class = $this->options['matcher_cache_class'];
     $baseClass = $this->options['matcher_base_class'];
     $expressionLanguageProviders = $this->expressionLanguageProviders;
     $that = $this;
     // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
     $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'] . '/' . $class . '.php', function (ConfigCacheInterface $cache) use($that, $class, $baseClass, $expressionLanguageProviders) {
         $dumper = $that->getMatcherDumperInstance();
         if (method_exists($dumper, 'addExpressionLanguageProvider')) {
             foreach ($expressionLanguageProviders as $provider) {
                 $dumper->addExpressionLanguageProvider($provider);
             }
         }
         $options = array('class' => $class, 'base_class' => $baseClass);
         $cache->write($dumper->dump($options), $that->getRouteCollection()->getResources());
     });
     require_once $cache->getPath();
     return $this->matcher = new $class($this->context);
 }
 /**
  * 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;
 }
예제 #12
0
 /**
  * Gets the UrlMatcher instance associated with this Router.
  *
  * @return UrlMatcherInterface A UrlMatcherInterface instance
  */
 public function getMatcher()
 {
     if (null !== $this->matcher) {
         return $this->matcher;
     }
     if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
         $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
         if (method_exists($this->matcher, 'addExpressionLanguageProvider')) {
             foreach ($this->expressionLanguageProviders as $provider) {
                 $this->matcher->addExpressionLanguageProvider($provider);
             }
         }
         return $this->matcher;
     }
     $class = $this->options['matcher_cache_class'];
     $cache = new ConfigCache($this->options['cache_dir'] . '/' . $class . '.php', $this->options['debug']);
     if (!$cache->isFresh()) {
         $dumper = $this->getMatcherDumperInstance();
         if (method_exists($dumper, 'addExpressionLanguageProvider')) {
             foreach ($this->expressionLanguageProviders as $provider) {
                 $dumper->addExpressionLanguageProvider($provider);
             }
         }
         $options = array('class' => $class, 'base_class' => $this->options['matcher_base_class']);
         $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
     }
     require_once $cache;
     return $this->matcher = new $class($this->context);
 }
 /**
  * Checks whether the given path is an administrative one.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object.
  *
  * @return bool
  *   TRUE if the path is administrative, FALSE otherwise.
  */
 protected function isAdminPath(Request $request)
 {
     $result = FALSE;
     if ($request && $this->adminContext) {
         // If called from an event subscriber, the request may not have the route
         // object yet (it is still being built), so use the router to look up
         // based on the path.
         $route_match = $this->stackedRouteMatch->getRouteMatchFromRequest($request);
         if ($route_match && !($route_object = $route_match->getRouteObject())) {
             try {
                 // Process the path as an inbound path. This will remove any language
                 // prefixes and other path components that inbound processing would
                 // clear out, so we can attempt to load the route clearly.
                 $path = $this->pathProcessorManager->processInbound(urldecode(rtrim($request->getPathInfo(), '/')), $request);
                 $attributes = $this->router->match($path);
             } catch (ResourceNotFoundException $e) {
                 return FALSE;
             } catch (AccessDeniedHttpException $e) {
                 return FALSE;
             }
             $route_object = $attributes[RouteObjectInterface::ROUTE_OBJECT];
         }
         $result = $this->adminContext->isAdminRoute($route_object);
     }
     return $result;
 }
예제 #14
0
 /**
  * @override
  * @inheritDoc
  */
 public function handleMessage(IoConnectionInterface $conn, IoMessageInterface $message)
 {
     if (!$message instanceof HttpRequestInterface) {
         $conn->controller->handleMessage($conn, $message);
         return;
     }
     if (($header = $message->getHeaderLine('Origin')) !== '') {
         $origin = parse_url($header, PHP_URL_HOST) ?: $header;
         if ($origin !== '' && $this->isBlocked($origin)) {
             return $this->close($conn, 403);
         }
     }
     $context = $this->matcher->getContext();
     $context->setMethod($message->getMethod());
     $context->setHost($message->getUri()->getHost());
     $route = [];
     try {
         $route = $this->matcher->match($message->getUri()->getPath());
     } catch (Error $ex) {
         return $this->close($conn, 500);
     } catch (MethodNotAllowedException $nae) {
         return $this->close($conn, 403);
     } catch (ResourceNotFoundException $nfe) {
         return $this->close($conn, 404);
     }
     $conn->controller = $route['_controller'];
     try {
         $conn->controller->handleConnect($conn);
         $conn->controller->handleMessage($conn, $message);
     } catch (Error $ex) {
         $conn->controller->handleError($conn, $ex);
     } catch (Exception $ex) {
         $conn->controller->handleError($conn, $ex);
     }
 }
 /**
  * Tests the isValid() method with a not existing path.
  *
  * @covers ::isValid
  */
 public function testIsValidWithNotExistingPath()
 {
     $this->account->expects($this->once())->method('hasPermission')->with('link to any page')->willReturn(FALSE);
     $this->accessUnawareRouter->expects($this->never())->method('match');
     $this->accessAwareRouter->expects($this->once())->method('match')->with('/not-existing-path')->willThrowException(new ResourceNotFoundException());
     $this->pathProcessor->expects($this->once())->method('processInbound')->willReturnArgument(0);
     $this->assertFalse($this->pathValidator->isValid('not-existing-path'));
 }
예제 #16
0
 public function setUp()
 {
     $this->urlMatcher = $this->getMockForAbstractClass(UrlMatcherInterface::class);
     $this->resourceTransformer = $this->getMockForAbstractClass(TransformerInterface::class);
     $this->kernel = $this->getMockForAbstractClass(HttpKernelInterface::class);
     $this->context = $this->getMockBuilder(RequestContext::class)->disableOriginalConstructor()->getMock();
     $this->urlMatcher->method('getContext')->willReturn($this->context);
 }
예제 #17
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());
 }
예제 #18
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;
 }
 /**
  * {@inheritdoc}
  */
 protected function setUp()
 {
     $this->configFactory = $this->getConfigFactoryStub(['system.site' => ['page.403' => '/access-denied-page', 'page.404' => '/not-found-page']]);
     $this->kernel = $this->getMock('Symfony\\Component\\HttpKernel\\HttpKernelInterface');
     $this->logger = $this->getMock('Psr\\Log\\LoggerInterface');
     $this->redirectDestination = $this->getMock('\\Drupal\\Core\\Routing\\RedirectDestinationInterface');
     $this->redirectDestination->expects($this->any())->method('getAsArray')->willReturn(['destination' => 'test']);
     $this->accessUnawareRouter = $this->getMock('Symfony\\Component\\Routing\\Matcher\\UrlMatcherInterface');
     $this->accessUnawareRouter->expects($this->any())->method('match')->willReturn(['_controller' => 'mocked']);
     $this->accessManager = $this->getMock('Drupal\\Core\\Access\\AccessManagerInterface');
     $this->accessManager->expects($this->any())->method('checkNamedRoute')->willReturn(AccessResult::allowed()->addCacheTags(['foo', 'bar']));
     $this->customPageSubscriber = new CustomPageExceptionHtmlSubscriber($this->configFactory, $this->kernel, $this->logger, $this->redirectDestination, $this->accessUnawareRouter, $this->accessManager);
     $path_validator = $this->getMock('Drupal\\Core\\Path\\PathValidatorInterface');
     $path_validator->expects($this->any())->method('getUrlIfValidWithoutAccessCheck')->willReturn(Url::fromRoute('foo', ['foo' => 'bar']));
     $container = new ContainerBuilder();
     $container->set('path.validator', $path_validator);
     \Drupal::setContainer($container);
     // You can't create an exception in PHP without throwing it. Store the
     // current error_log, and disable it temporarily.
     $this->errorLog = ini_set('error_log', file_exists('/dev/null') ? '/dev/null' : 'nul');
 }
 /**
  * Checks whether the given path is an administrative one.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request object.
  *
  * @return bool
  *   TRUE if the path is administrative, FALSE otherwise.
  */
 public function isAdminPath(Request $request)
 {
     $result = FALSE;
     if ($request && $this->adminContext) {
         // If called from an event subscriber, the request may not the route info
         // yet, so use the router to look up the path first.
         if (!($route_object = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT))) {
             $attributes = $this->router->match('/' . urldecode(trim($request->getPathInfo(), '/')));
             $route_object = $attributes[RouteObjectInterface::ROUTE_OBJECT];
         }
         $result = $this->adminContext->isAdminRoute($route_object);
     }
     return $result;
 }
예제 #21
0
 /**
  * Verify if the given path is a valid route.
  *
  * Taken from menu_execute_active_handler().
  *
  * @param string $path
  *   A string containing a relative path.
  *
  * @return bool
  *   TRUE if the path already exists.
  */
 public function isRoute($path)
 {
     if (is_file(DRUPAL_ROOT . '/' . $path) || is_dir(DRUPAL_ROOT . '/' . $path)) {
         // Do not allow existing files or directories to get assigned an automatic
         // alias. Note that we do not need to use is_link() to check for symbolic
         // links since this returns TRUE for either is_file() or is_dir() already.
         return TRUE;
     }
     try {
         $this->urlMatcher->match('/' . $path);
         return TRUE;
     } catch (ResourceNotFoundException $e) {
         return FALSE;
     }
 }
예제 #22
0
 /**
  * {@inheritdoc}
  * @throws \UnexpectedValueException If a controller is not \Ratchet\Http\HttpServerInterface
  */
 public function onOpen(ConnectionInterface $conn, RequestInterface $request = null)
 {
     if (null === $request) {
         throw new \UnexpectedValueException('$request can not be null');
     }
     $context = $this->_matcher->getContext();
     $context->setMethod($request->getMethod());
     $context->setHost($request->getHost());
     try {
         $route = $this->_matcher->match($request->getPath());
     } catch (MethodNotAllowedException $nae) {
         return $this->close($conn, 403);
     } catch (ResourceNotFoundException $nfe) {
         return $this->close($conn, 404);
     }
     if (is_string($route['_controller']) && class_exists($route['_controller'])) {
         $route['_controller'] = new $route['_controller']();
     }
     if (!$route['_controller'] instanceof HttpServerInterface) {
         throw new \UnexpectedValueException('All routes must implement Ratchet\\Http\\HttpServerInterface');
     }
     $conn->controller = $route['_controller'];
     $conn->controller->onOpen($conn, $request);
 }
예제 #23
0
 public function onKernelRequest(KernelEvent $event)
 {
     if (strtoupper($event->getRequest()->getMethod()) !== 'LINK' && strtoupper($event->getRequest()->getMethod()) !== 'UNLINK') {
         return;
     }
     if (!$event->getRequest()->headers->has('link')) {
         throw new BadRequestHttpException('Please specify at least one Link.');
     }
     $requestMethod = $this->urlMatcher->getContext()->getMethod();
     $this->urlMatcher->getContext()->setMethod('GET');
     $links = [];
     /*
      * Due to limitations, multiple same-name headers are sent as comma
      * separated values.
      *
      * This breaks those headers into Link headers following the format
      * http://tools.ietf.org/html/rfc2068#section-19.6.2.4
      */
     foreach (explode(',', $event->getRequest()->headers->get('link')) as $header) {
         $header = trim($header);
         $link = new LinkHeader($header);
         try {
             if ($urlParameters = $this->urlMatcher->match($link->getValue())) {
                 $link->setUrlParameters($urlParameters);
             }
         } catch (ResourceNotFoundException $exception) {
         }
         try {
             $link->setResource($this->resourceTransformer->getResourceProxy($link->getValue()));
         } catch (InvalidArgumentException $e) {
         }
         $links[] = $link;
     }
     $this->urlMatcher->getContext()->setMethod($requestMethod);
     $event->getRequest()->attributes->set('links', $links);
 }
 /**
  * Makes a subrequest to retrieve the default error page.
  *
  * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
  *   The event to process.
  * @param string $url
  *   The path/url to which to make a subrequest for this error message.
  * @param int $status_code
  *   The status code for the error being handled.
  */
 protected function makeSubrequest(GetResponseForExceptionEvent $event, $url, $status_code)
 {
     $request = $event->getRequest();
     $exception = $event->getException();
     try {
         // Reuse the exact same request (so keep the same URL, keep the access
         // result, the exception, et cetera) but override the routing information.
         // This means that aside from routing, this is identical to the master
         // request. This allows us to generate a response that is executed on
         // behalf of the master request, i.e. for the original URL. This is what
         // allows us to e.g. generate a 404 response for the original URL; if we
         // would execute a subrequest with the 404 route's URL, then it'd be
         // generated for *that* URL, not the *original* URL.
         $sub_request = clone $request;
         // The routing to the 404 page should be done as GET request because it is
         // restricted to GET and POST requests only. Otherwise a DELETE request
         // would for example trigger a method not allowed exception.
         $request_context = clone $this->accessUnawareRouter->getContext();
         $request_context->setMethod('GET');
         $this->accessUnawareRouter->setContext($request_context);
         $sub_request->attributes->add($this->accessUnawareRouter->match($url));
         // Add to query (GET) or request (POST) parameters:
         // - 'destination' (to ensure e.g. the login form in a 403 response
         //   redirects to the original URL)
         // - '_exception_statuscode'
         $parameters = $sub_request->isMethod('GET') ? $sub_request->query : $sub_request->request;
         $parameters->add($this->redirectDestination->getAsArray() + ['_exception_statuscode' => $status_code]);
         $response = $this->httpKernel->handle($sub_request, HttpKernelInterface::SUB_REQUEST);
         // Only 2xx responses should have their status code overridden; any
         // other status code should be passed on: redirects (3xx), error (5xx)…
         // @see https://www.drupal.org/node/2603788#comment-10504916
         if ($response->isSuccessful()) {
             $response->setStatusCode($status_code);
         }
         // Persist any special HTTP headers that were set on the exception.
         if ($exception instanceof HttpExceptionInterface) {
             $response->headers->add($exception->getHeaders());
         }
         $event->setResponse($response);
     } catch (\Exception $e) {
         // If an error happened in the subrequest we can't do much else. Instead,
         // just log it. The DefaultExceptionSubscriber will catch the original
         // exception and handle it normally.
         $error = Error::decodeException($e);
         $this->logger->log($error['severity_level'], '%type: @message in %function (line %line of %file).', $error);
     }
 }
 /**
  * Tests onHandleException with a GET request.
  */
 public function testHandleWithGetRequest()
 {
     $request = Request::create('/test', 'GET', array('name' => 'druplicon', 'pass' => '12345'));
     $request->attributes->set(AccessAwareRouterInterface::ACCESS_RESULT, AccessResult::forbidden()->addCacheTags(['druplicon']));
     $request_context = new RequestContext();
     $request_context->fromRequest($request);
     $this->accessUnawareRouter->expects($this->any())->method('getContext')->willReturn($request_context);
     $this->kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) {
         return new Response($request->getMethod() . ' ' . UrlHelper::buildQuery($request->query->all()));
     }));
     $event = new GetResponseForExceptionEvent($this->kernel, $request, 'foo', new NotFoundHttpException('foo'));
     $this->customPageSubscriber->onException($event);
     $response = $event->getResponse();
     $result = $response->getContent() . " " . UrlHelper::buildQuery($request->request->all());
     $this->assertEquals('GET name=druplicon&pass=12345&destination=test&_exception_statuscode=404 ', $result);
     $this->assertEquals(AccessResult::forbidden()->addCacheTags(['druplicon', 'foo', 'bar']), $request->attributes->get(AccessAwareRouterInterface::ACCESS_RESULT));
 }
예제 #26
0
 /**
  * Verify if the given path is a valid route.
  *
  * @param string $path
  *   A string containing a relative path.
  *
  * @return bool
  *   TRUE if the path already exists.
  *
  * @throws \InvalidArgumentException
  */
 public function isRoute($path)
 {
     if (is_file(DRUPAL_ROOT . '/' . $path) || is_dir(DRUPAL_ROOT . '/' . $path)) {
         // Do not allow existing files or directories to get assigned an automatic
         // alias. Note that we do not need to use is_link() to check for symbolic
         // links since this returns TRUE for either is_file() or is_dir() already.
         return TRUE;
     }
     try {
         $route = $this->urlMatcher->match($path);
         if ($route['_route'] == $this->lastRouteName) {
             throw new \InvalidArgumentException('The given alias pattern (' . $path . ') always matches the route ' . $this->lastRouteName);
         }
         $this->lastRouteName = $route['_route'];
         return TRUE;
     } catch (ResourceNotFoundException $e) {
         $this->lastRouteName = NULL;
         return FALSE;
     }
 }
예제 #27
0
파일: Router.php 프로젝트: evaneos/pyrite
 /**
  * @param string $pathinfo
  *
  * @return array
  */
 public function match($pathinfo)
 {
     return $this->matcher->match($pathinfo);
 }
 /**
  * @param GetResponseEvent $event
  *
  * @return array
  */
 public function onKernelRequest(GetResponseEvent $event, $eventName, EventDispatcherInterface $dispatcher)
 {
     if (!$event->getRequest()->headers->has('link')) {
         return;
     }
     $links = [];
     $header = $event->getRequest()->headers->get('link');
     /*
      * Due to limitations, multiple same-name headers are sent as comma
      * separated values.
      *
      * This breaks those headers into Link headers following the format
      * http://tools.ietf.org/html/rfc2068#section-19.6.2.4
      */
     while (preg_match('/^((?:[^"]|"[^"]*")*?),/', $header, $matches)) {
         $header = trim(substr($header, strlen($matches[0])));
         $links[] = $matches[1];
     }
     if ($header) {
         $links[] = $header;
     }
     $requestMethod = $this->urlMatcher->getContext()->getMethod();
     // The controller resolver needs a request to resolve the controller.
     $stubRequest = new Request();
     foreach ($links as $idx => $link) {
         // Force the GET method to avoid the use of the previous method (LINK/UNLINK)
         $this->urlMatcher->getContext()->setMethod('GET');
         $linkParams = explode(';', trim($link));
         $resourceType = null;
         if (count($linkParams) > 1) {
             $resourceType = trim(preg_replace('/<|>/', '', $linkParams[1]));
             $resourceType = str_replace('"', '', str_replace('rel=', '', $resourceType));
         }
         $resource = array_shift($linkParams);
         $resource = preg_replace('/<|>/', '', $resource);
         // Assume that no resource is specified here if there is no path separator, because urlMatcher will return homepage
         if (strpos($resource, '/') === false) {
             continue;
         }
         $tempRequest = Request::create($resource);
         try {
             $route = $this->urlMatcher->match($tempRequest->getRequestUri());
         } catch (\Exception $e) {
             // If we don't have a matching route we return the original Link header
             continue;
         }
         $stubRequest->attributes->replace($route);
         $stubRequest->server = $event->getRequest()->server;
         if (false === ($controller = $this->resolver->getController($stubRequest))) {
             continue;
         }
         $subEvent = new FilterControllerEvent($event->getKernel(), $controller, $stubRequest, HttpKernelInterface::SUB_REQUEST);
         $kernelSubEvent = new GetResponseEvent($event->getKernel(), $stubRequest, HttpKernelInterface::SUB_REQUEST);
         $dispatcher->dispatch(KernelEvents::REQUEST, $kernelSubEvent);
         $dispatcher->dispatch(KernelEvents::CONTROLLER, $subEvent);
         $controller = $subEvent->getController();
         $arguments = $this->resolver->getArguments($stubRequest, $controller);
         if (!isset($arguments[0])) {
             continue;
         }
         $arguments[0]->attributes->set('_link_request', true);
         try {
             $result = call_user_func_array($controller, $arguments);
             // Our api returns objects for single resources
             if (!is_object($result)) {
                 continue;
             }
             $links[$idx] = ['object' => $result, 'resourceType' => $resourceType];
         } catch (\Exception $e) {
             $links[$idx] = ['object' => $e, 'resourceType' => 'exception'];
             continue;
         }
     }
     $event->getRequest()->attributes->set('links', $links);
     $this->urlMatcher->getContext()->setMethod($requestMethod);
     return $links;
 }
 public function onKernelRequest(GetResponseEvent $event)
 {
     if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
         return;
     }
     if (!$event->getRequest()->headers->has('link')) {
         return;
     }
     $links = array();
     $header = $event->getRequest()->headers->get('link');
     /*
      * Due to limitations, multiple same-name headers are sent as comma
      * separated values.
      *
      * This breaks those headers into Link headers following the format
      * http://tools.ietf.org/html/rfc2068#section-19.6.2.4
      */
     while (preg_match('/^((?:[^"]|"[^"]*")*?),/', $header, $matches)) {
         $header = trim(substr($header, strlen($matches[0])));
         $links[] = $matches[1];
     }
     if ($header) {
         $links[] = $header;
     }
     $requestMethod = $this->urlMatcher->getContext()->getMethod();
     // Force the GET method to avoid the use of the
     // previous method (LINK/UNLINK)
     $this->urlMatcher->getContext()->setMethod('GET');
     // The controller resolver needs a request to resolve the controller.
     $stubRequest = new Request();
     foreach ($links as $idx => $link) {
         $linkHeader = $this->parseLinkHeader($link);
         $resource = $this->parseResource($linkHeader, $event->getRequest());
         try {
             $route = $this->urlMatcher->match($resource);
         } catch (\Exception $e) {
             // If we don't have a matching route we return
             // the original Link header
             continue;
         }
         $stubRequest->attributes->replace($route);
         if (false === ($controller = $this->resolver->getController($stubRequest))) {
             continue;
         }
         // Make sure @ParamConverter and some other annotations are called
         $subEvent = new FilterControllerEvent($event->getKernel(), $controller, $stubRequest, HttpKernelInterface::SUB_REQUEST);
         $event->getDispatcher()->dispatch(KernelEvents::CONTROLLER, $subEvent);
         $controller = $subEvent->getController();
         $arguments = $this->resolver->getArguments($stubRequest, $controller);
         try {
             $result = call_user_func_array($controller, $arguments);
             $value = is_array($result) ? current($result) : $result;
             if ($linkHeader->hasRel()) {
                 unset($links[$idx]);
                 $links[$linkHeader->getRel()][] = $value;
             } else {
                 $links[$idx] = $value;
             }
         } catch (\Exception $e) {
             continue;
         }
     }
     $event->getRequest()->attributes->set('links', $links);
     $this->urlMatcher->getContext()->setMethod($requestMethod);
 }
 /**
  * @param FilterControllerEvent $event A FilterControllerEvent instance
  */
 public function onKernelController(FilterControllerEvent $event)
 {
     if (!$event->getRequest()->headers->has('link')) {
         return;
     }
     $links = array();
     $header = $event->getRequest()->headers->get('link');
     /*
      * Due to limitations, multiple same-name headers are sent as comma
      * separated values.
      *
      * This breaks those headers into Link headers following the format
      * http://tools.ietf.org/html/rfc2068#section-19.6.2.4
      */
     while (preg_match('/^((?:[^"]|"[^"]*")*?),/', $header, $matches)) {
         $header = trim(substr($header, strlen($matches[0])));
         $links[] = $matches[1];
     }
     if ($header) {
         $links[] = $header;
     }
     $requestMethod = $this->urlMatcher->getContext()->getMethod();
     // Force the GET method to avoid the use of the
     // previous method (LINK/UNLINK)
     $this->urlMatcher->getContext()->setMethod('GET');
     // The controller resolver needs a request to resolve the controller.
     $stubRequest = new Request();
     foreach ($links as $idx => $link) {
         $linkParams = explode(';', trim($link));
         $resource = array_shift($linkParams);
         $resource = preg_replace('/<|>/', '', $resource);
         if (preg_match('#^/|https?://#', $resource) === 0) {
             $resource = '/' . $resource;
         }
         try {
             $route = $this->urlMatcher->match($resource);
         } catch (\Exception $e) {
             // If we don't have a matching route we return
             // the original Link header
             continue;
         }
         $stubRequest->attributes->replace($route);
         if (false === ($controller = $this->resolver->getController($stubRequest))) {
             continue;
         }
         try {
             $stubEvent = new FilterControllerEvent($this->httpKernel, $controller, $stubRequest, HttpKernelInterface::SUB_REQUEST);
             $this->eventDispatcher->dispatch(KernelEvents::CONTROLLER, $stubEvent);
             $arguments = $this->resolver->getArguments($stubRequest, $controller);
             $result = call_user_func_array($controller, $arguments);
             // By convention the controller action must return an array
             if (!is_array($result)) {
                 continue;
             }
             // The key of first item is discarded
             $links[$idx] = current($result);
         } catch (\Exception $e) {
             continue;
         }
     }
     $event->getRequest()->attributes->set('link', $links);
     $this->urlMatcher->getContext()->setMethod($requestMethod);
 }