Chris@0: context = $context; Chris@0: if (!$matcher instanceof RequestMatcherInterface && !$matcher instanceof UrlMatcherInterface) { Chris@0: throw new \InvalidArgumentException('Matcher must implement either Symfony\Component\Routing\Matcher\RequestMatcherInterface or Symfony\Component\Routing\Matcher\UrlMatcherInterface'); Chris@0: } Chris@0: $this->matcher = $matcher; Chris@0: $this->generator = $generator; Chris@0: $this->eventDispatcher = $eventDispatcher; Chris@0: $this->uriFilterRegexp = $uriFilterRegexp; Chris@0: $this->provider = $provider; Chris@0: Chris@0: $this->generator->setContext($context); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getRouteCollection() Chris@0: { Chris@0: if (!$this->routeCollection instanceof RouteCollection) { Chris@0: $this->routeCollection = $this->provider Chris@0: ? new LazyRouteCollection($this->provider) : new RouteCollection(); Chris@0: } Chris@0: Chris@0: return $this->routeCollection; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @return RequestMatcherInterface|UrlMatcherInterface Chris@0: */ Chris@0: public function getMatcher() Chris@0: { Chris@0: /* we may not set the context in DynamicRouter::setContext as this Chris@0: * would lead to symfony cache warmup problems. Chris@0: * a request matcher does not need the request context separately as it Chris@0: * can get it from the request. Chris@0: */ Chris@0: if ($this->matcher instanceof RequestContextAwareInterface) { Chris@0: $this->matcher->setContext($this->getContext()); Chris@0: } Chris@0: Chris@0: return $this->matcher; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @return UrlGeneratorInterface Chris@0: */ Chris@0: public function getGenerator() Chris@0: { Chris@0: $this->generator->setContext($this->getContext()); Chris@0: Chris@0: return $this->generator; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Generates a URL from the given parameters. Chris@0: * Chris@0: * If the generator is not able to generate the url, it must throw the Chris@0: * RouteNotFoundException as documented below. Chris@0: * Chris@0: * @param string|Route $name The name of the route or the Route instance Chris@0: * @param mixed $parameters An array of parameters Chris@0: * @param bool|string $referenceType The type of reference to be generated (one of the constants in UrlGeneratorInterface) Chris@0: * Chris@0: * @return string The generated URL Chris@0: * Chris@0: * @throws RouteNotFoundException if route doesn't exist Chris@0: * Chris@0: * @api Chris@0: */ Chris@0: public function generate($name, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH) Chris@0: { Chris@0: if ($this->eventDispatcher) { Chris@0: $event = new RouterGenerateEvent($name, $parameters, $referenceType); Chris@0: $this->eventDispatcher->dispatch(Events::PRE_DYNAMIC_GENERATE, $event); Chris@0: $name = $event->getRoute(); Chris@0: $parameters = $event->getParameters(); Chris@0: $referenceType = $event->getReferenceType(); Chris@0: } Chris@0: Chris@0: return $this->getGenerator()->generate($name, $parameters, $referenceType); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Delegate to our generator. Chris@0: * Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function supports($name) Chris@0: { Chris@0: if ($this->generator instanceof VersatileGeneratorInterface) { Chris@0: return $this->generator->supports($name); Chris@0: } Chris@0: Chris@0: return is_string($name); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tries to match a URL path with a set of routes. Chris@0: * Chris@0: * If the matcher can not find information, it must throw one of the Chris@0: * exceptions documented below. Chris@0: * Chris@0: * @param string $pathinfo The path info to be parsed (raw format, i.e. not Chris@0: * urldecoded) Chris@0: * Chris@0: * @return array An array of parameters Chris@0: * Chris@0: * @throws ResourceNotFoundException If the resource could not be found Chris@0: * @throws MethodNotAllowedException If the resource was found but the Chris@0: * request method is not allowed Chris@0: * Chris@0: * @deprecated Use matchRequest exclusively to avoid problems. This method will be removed in version 2.0 Chris@0: * Chris@0: * @api Chris@0: */ Chris@0: public function match($pathinfo) Chris@0: { Chris@0: @trigger_error(__METHOD__.'() is deprecated since version 1.3 and will be removed in 2.0. Use matchRequest() instead.', E_USER_DEPRECATED); Chris@0: Chris@0: $request = Request::create($pathinfo); Chris@0: if ($this->eventDispatcher) { Chris@0: $event = new RouterMatchEvent(); Chris@0: $this->eventDispatcher->dispatch(Events::PRE_DYNAMIC_MATCH, $event); Chris@0: } Chris@0: Chris@0: if (!empty($this->uriFilterRegexp) && !preg_match($this->uriFilterRegexp, $pathinfo)) { Chris@0: throw new ResourceNotFoundException("$pathinfo does not match the '{$this->uriFilterRegexp}' pattern"); Chris@0: } Chris@0: Chris@0: $matcher = $this->getMatcher(); Chris@0: if (!$matcher instanceof UrlMatcherInterface) { Chris@0: throw new \InvalidArgumentException('Wrong matcher type, you need to call matchRequest'); Chris@0: } Chris@0: Chris@0: $defaults = $matcher->match($pathinfo); Chris@0: Chris@0: return $this->applyRouteEnhancers($defaults, $request); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tries to match a request with a set of routes and returns the array of Chris@0: * information for that route. Chris@0: * Chris@0: * If the matcher can not find information, it must throw one of the Chris@0: * exceptions documented below. Chris@0: * Chris@0: * @param Request $request The request to match Chris@0: * Chris@0: * @return array An array of parameters Chris@0: * Chris@0: * @throws ResourceNotFoundException If no matching resource could be found Chris@0: * @throws MethodNotAllowedException If a matching resource was found but Chris@0: * the request method is not allowed Chris@0: */ Chris@0: public function matchRequest(Request $request) Chris@0: { Chris@0: if ($this->eventDispatcher) { Chris@0: $event = new RouterMatchEvent($request); Chris@0: $this->eventDispatcher->dispatch(Events::PRE_DYNAMIC_MATCH_REQUEST, $event); Chris@0: } Chris@0: Chris@0: if (!empty($this->uriFilterRegexp) Chris@0: && !preg_match($this->uriFilterRegexp, $request->getPathInfo()) Chris@0: ) { Chris@0: throw new ResourceNotFoundException("{$request->getPathInfo()} does not match the '{$this->uriFilterRegexp}' pattern"); Chris@0: } Chris@0: Chris@0: $matcher = $this->getMatcher(); Chris@0: if ($matcher instanceof UrlMatcherInterface) { Chris@0: $defaults = $matcher->match($request->getPathInfo()); Chris@0: } else { Chris@0: $defaults = $matcher->matchRequest($request); Chris@0: } Chris@0: Chris@0: return $this->applyRouteEnhancers($defaults, $request); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Apply the route enhancers to the defaults, according to priorities. Chris@0: * Chris@0: * @param array $defaults Chris@0: * @param Request $request Chris@0: * Chris@0: * @return array Chris@0: */ Chris@0: protected function applyRouteEnhancers($defaults, Request $request) Chris@0: { Chris@0: foreach ($this->getRouteEnhancers() as $enhancer) { Chris@0: $defaults = $enhancer->enhance($defaults, $request); Chris@0: } Chris@0: Chris@0: return $defaults; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Add route enhancers to the router to let them generate information on Chris@0: * matched routes. Chris@0: * Chris@0: * The order of the enhancers is determined by the priority, the higher the Chris@0: * value, the earlier the enhancer is run. Chris@0: * Chris@0: * @param RouteEnhancerInterface $enhancer Chris@0: * @param int $priority Chris@0: */ Chris@0: public function addRouteEnhancer(RouteEnhancerInterface $enhancer, $priority = 0) Chris@0: { Chris@0: if (empty($this->enhancers[$priority])) { Chris@0: $this->enhancers[$priority] = array(); Chris@0: } Chris@0: Chris@0: $this->enhancers[$priority][] = $enhancer; Chris@0: $this->sortedEnhancers = array(); Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sorts the enhancers and flattens them. Chris@0: * Chris@0: * @return RouteEnhancerInterface[] the enhancers ordered by priority Chris@0: */ Chris@0: public function getRouteEnhancers() Chris@0: { Chris@0: if (empty($this->sortedEnhancers)) { Chris@0: $this->sortedEnhancers = $this->sortRouteEnhancers(); Chris@0: } Chris@0: Chris@0: return $this->sortedEnhancers; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sort enhancers by priority. Chris@0: * Chris@0: * The highest priority number is the highest priority (reverse sorting). Chris@0: * Chris@0: * @return RouteEnhancerInterface[] the sorted enhancers Chris@0: */ Chris@0: protected function sortRouteEnhancers() Chris@0: { Chris@0: $sortedEnhancers = array(); Chris@0: krsort($this->enhancers); Chris@0: Chris@0: foreach ($this->enhancers as $enhancers) { Chris@0: $sortedEnhancers = array_merge($sortedEnhancers, $enhancers); Chris@0: } Chris@0: Chris@0: return $sortedEnhancers; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the request context. Chris@0: * Chris@0: * @param RequestContext $context The context Chris@0: * Chris@0: * @api Chris@0: */ Chris@0: public function setContext(RequestContext $context) Chris@0: { Chris@0: $this->context = $context; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the request context. Chris@0: * Chris@0: * @return RequestContext The context Chris@0: * Chris@0: * @api Chris@0: */ Chris@0: public function getContext() Chris@0: { Chris@0: return $this->context; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: * Chris@0: * Forwards to the generator. Chris@0: */ Chris@0: public function getRouteDebugMessage($name, array $parameters = array()) Chris@0: { Chris@0: if ($this->generator instanceof VersatileGeneratorInterface) { Chris@0: return $this->generator->getRouteDebugMessage($name, $parameters); Chris@0: } Chris@0: Chris@0: return "Route '$name' not found"; Chris@0: } Chris@0: }