Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony-cmf/routing/NestedMatcher/NestedMatcher.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 /* | |
4 * This file is part of the Symfony CMF package. | |
5 * | |
6 * (c) 2011-2015 Symfony CMF | |
7 * | |
8 * For the full copyright and license information, please view the LICENSE | |
9 * file that was distributed with this source code. | |
10 */ | |
11 | |
12 namespace Symfony\Cmf\Component\Routing\NestedMatcher; | |
13 | |
14 use Symfony\Component\HttpFoundation\Request; | |
15 use Symfony\Component\Routing\Exception\ResourceNotFoundException; | |
16 use Symfony\Component\Routing\Matcher\RequestMatcherInterface; | |
17 use Symfony\Cmf\Component\Routing\RouteProviderInterface; | |
18 | |
19 /** | |
20 * A more flexible approach to matching. The route collection to match against | |
21 * can be dynamically determined based on the request and users can inject | |
22 * their own filters or use a custom final matching strategy. | |
23 * | |
24 * The nested matcher splits matching into three configurable steps: | |
25 * | |
26 * 1) Get potential matches from a RouteProviderInterface | |
27 * 2) Apply any RouteFilterInterface to reduce the route collection | |
28 * 3) Have FinalMatcherInterface select the best match of the remaining routes | |
29 * | |
30 * @author Larry Garfield | |
31 * @author David Buchmann | |
32 */ | |
33 class NestedMatcher implements RequestMatcherInterface | |
34 { | |
35 /** | |
36 * The route provider responsible for the first-pass match. | |
37 * | |
38 * @var RouteProviderInterface | |
39 */ | |
40 protected $routeProvider; | |
41 | |
42 /** | |
43 * The final matcher. | |
44 * | |
45 * @var FinalMatcherInterface | |
46 */ | |
47 protected $finalMatcher; | |
48 | |
49 /** | |
50 * An array of RouteFilterInterface objects. | |
51 * | |
52 * @var RouteFilterInterface[] | |
53 */ | |
54 protected $filters = array(); | |
55 | |
56 /** | |
57 * Array of RouteFilterInterface objects, sorted. | |
58 * | |
59 * @var RouteFilterInterface[] | |
60 */ | |
61 protected $sortedFilters = array(); | |
62 | |
63 /** | |
64 * Constructs a new NestedMatcher. | |
65 * | |
66 * @param RouteProviderInterface $provider The route provider this matcher | |
67 * should use | |
68 * @param FinalMatcherInterface $final The Final Matcher to match the | |
69 * routes | |
70 */ | |
71 public function __construct( | |
72 RouteProviderInterface $provider = null, | |
73 FinalMatcherInterface $final = null | |
74 ) { | |
75 if (null !== $provider) { | |
76 $this->setRouteProvider($provider); | |
77 } | |
78 if (null !== $final) { | |
79 $this->setFinalMatcher($final); | |
80 } | |
81 } | |
82 | |
83 /** | |
84 * Sets the route provider for the matching plan. | |
85 * | |
86 * @param RouteProviderInterface $provider A source of routes. | |
87 * | |
88 * @return NestedMatcher this object to have a fluent interface | |
89 */ | |
90 public function setRouteProvider(RouteProviderInterface $provider) | |
91 { | |
92 $this->routeProvider = $provider; | |
93 | |
94 return $this; | |
95 } | |
96 | |
97 /** | |
98 * Adds a partial matcher to the matching plan. | |
99 * | |
100 * Partial matchers will be run in the order in which they are added. | |
101 * | |
102 * @param RouteFilterInterface $filter | |
103 * @param int $priority (optional) The priority of the | |
104 * filter. Higher number filters will | |
105 * be used first. Defaults to 0. | |
106 * | |
107 * @return NestedMatcher this object to have a fluent interface | |
108 */ | |
109 public function addRouteFilter(RouteFilterInterface $filter, $priority = 0) | |
110 { | |
111 if (empty($this->filters[$priority])) { | |
112 $this->filters[$priority] = array(); | |
113 } | |
114 | |
115 $this->filters[$priority][] = $filter; | |
116 $this->sortedFilters = array(); | |
117 | |
118 return $this; | |
119 } | |
120 | |
121 /** | |
122 * Sets the final matcher for the matching plan. | |
123 * | |
124 * @param FinalMatcherInterface $final The final matcher that will have to | |
125 * pick the route that will be used. | |
126 * | |
127 * @return NestedMatcher this object to have a fluent interface | |
128 */ | |
129 public function setFinalMatcher(FinalMatcherInterface $final) | |
130 { | |
131 $this->finalMatcher = $final; | |
132 | |
133 return $this; | |
134 } | |
135 | |
136 /** | |
137 * {@inheritdoc} | |
138 */ | |
139 public function matchRequest(Request $request) | |
140 { | |
141 $collection = $this->routeProvider->getRouteCollectionForRequest($request); | |
142 if (!count($collection)) { | |
143 throw new ResourceNotFoundException(); | |
144 } | |
145 | |
146 // Route filters are expected to throw an exception themselves if they | |
147 // end up filtering the list down to 0. | |
148 foreach ($this->getRouteFilters() as $filter) { | |
149 $collection = $filter->filter($collection, $request); | |
150 } | |
151 | |
152 $attributes = $this->finalMatcher->finalMatch($collection, $request); | |
153 | |
154 return $attributes; | |
155 } | |
156 | |
157 /** | |
158 * Sorts the filters and flattens them. | |
159 * | |
160 * @return RouteFilterInterface[] the filters ordered by priority | |
161 */ | |
162 public function getRouteFilters() | |
163 { | |
164 if (empty($this->sortedFilters)) { | |
165 $this->sortedFilters = $this->sortFilters(); | |
166 } | |
167 | |
168 return $this->sortedFilters; | |
169 } | |
170 | |
171 /** | |
172 * Sort filters by priority. | |
173 * | |
174 * The highest priority number is the highest priority (reverse sorting). | |
175 * | |
176 * @return RouteFilterInterface[] the sorted filters | |
177 */ | |
178 protected function sortFilters() | |
179 { | |
180 $sortedFilters = array(); | |
181 krsort($this->filters); | |
182 | |
183 foreach ($this->filters as $filters) { | |
184 $sortedFilters = array_merge($sortedFilters, $filters); | |
185 } | |
186 | |
187 return $sortedFilters; | |
188 } | |
189 } |