Chris@0: setRouteProvider($provider); Chris@0: } Chris@0: if (null !== $final) { Chris@0: $this->setFinalMatcher($final); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the route provider for the matching plan. Chris@0: * Chris@0: * @param RouteProviderInterface $provider A source of routes. Chris@0: * Chris@0: * @return NestedMatcher this object to have a fluent interface Chris@0: */ Chris@0: public function setRouteProvider(RouteProviderInterface $provider) Chris@0: { Chris@0: $this->routeProvider = $provider; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a partial matcher to the matching plan. Chris@0: * Chris@0: * Partial matchers will be run in the order in which they are added. Chris@0: * Chris@0: * @param RouteFilterInterface $filter Chris@0: * @param int $priority (optional) The priority of the Chris@0: * filter. Higher number filters will Chris@0: * be used first. Defaults to 0. Chris@0: * Chris@0: * @return NestedMatcher this object to have a fluent interface Chris@0: */ Chris@0: public function addRouteFilter(RouteFilterInterface $filter, $priority = 0) Chris@0: { Chris@0: if (empty($this->filters[$priority])) { Chris@0: $this->filters[$priority] = array(); Chris@0: } Chris@0: Chris@0: $this->filters[$priority][] = $filter; Chris@0: $this->sortedFilters = array(); Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the final matcher for the matching plan. Chris@0: * Chris@0: * @param FinalMatcherInterface $final The final matcher that will have to Chris@0: * pick the route that will be used. Chris@0: * Chris@0: * @return NestedMatcher this object to have a fluent interface Chris@0: */ Chris@0: public function setFinalMatcher(FinalMatcherInterface $final) Chris@0: { Chris@0: $this->finalMatcher = $final; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function matchRequest(Request $request) Chris@0: { Chris@0: $collection = $this->routeProvider->getRouteCollectionForRequest($request); Chris@0: if (!count($collection)) { Chris@0: throw new ResourceNotFoundException(); Chris@0: } Chris@0: Chris@0: // Route filters are expected to throw an exception themselves if they Chris@0: // end up filtering the list down to 0. Chris@0: foreach ($this->getRouteFilters() as $filter) { Chris@0: $collection = $filter->filter($collection, $request); Chris@0: } Chris@0: Chris@0: $attributes = $this->finalMatcher->finalMatch($collection, $request); Chris@0: Chris@0: return $attributes; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sorts the filters and flattens them. Chris@0: * Chris@0: * @return RouteFilterInterface[] the filters ordered by priority Chris@0: */ Chris@0: public function getRouteFilters() Chris@0: { Chris@0: if (empty($this->sortedFilters)) { Chris@0: $this->sortedFilters = $this->sortFilters(); Chris@0: } Chris@0: Chris@0: return $this->sortedFilters; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sort filters by priority. Chris@0: * Chris@0: * The highest priority number is the highest priority (reverse sorting). Chris@0: * Chris@0: * @return RouteFilterInterface[] the sorted filters Chris@0: */ Chris@0: protected function sortFilters() Chris@0: { Chris@0: $sortedFilters = array(); Chris@0: krsort($this->filters); Chris@0: Chris@0: foreach ($this->filters as $filters) { Chris@0: $sortedFilters = array_merge($sortedFilters, $filters); Chris@0: } Chris@0: Chris@0: return $sortedFilters; Chris@0: } Chris@0: }