Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
router.php
001 <?php
002 /**
003 *
004 * This file is part of the phpBB Forum Software package.
005 *
006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
007 * @license GNU General Public License, version 2 (GPL-2.0)
008 *
009 * For full copyright and license information, please see
010 * the docs/CREDITS.txt file.
011 *
012 */
013
014 namespace phpbb\routing;
015
016 use phpbb\routing\resources_locator\resources_locator_interface;
017 use Symfony\Component\Config\ConfigCache;
018 use Symfony\Component\Config\Loader\LoaderInterface;
019 use Symfony\Component\DependencyInjection\ContainerInterface;
020 use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
021 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
022 use Symfony\Component\Filesystem\Exception\IOException;
023 use Symfony\Component\Routing\Generator\Dumper\PhpGeneratorDumper;
024 use Symfony\Component\Routing\Generator\UrlGenerator;
025 use Symfony\Component\Routing\Matcher\Dumper\PhpMatcherDumper;
026 use Symfony\Component\Routing\Matcher\UrlMatcher;
027 use Symfony\Component\Routing\RequestContext;
028 use Symfony\Component\Routing\RouteCollection;
029 use Symfony\Component\Routing\RouterInterface;
030
031 /**
032 * Integration of all pieces of the routing system for easier use.
033 */
034 class router implements RouterInterface
035 {
036 /**
037 * @var ContainerInterface
038 */
039 protected $container;
040
041 /**
042 * @var resources_locator_interface
043 */
044 protected $resources_locator;
045
046 /**
047 * @var LoaderInterface
048 */
049 protected $loader;
050
051 /**
052 * PHP file extensions
053 *
054 * @var string
055 */
056 protected $php_ext;
057
058 /**
059 * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface|null
060 */
061 protected $matcher;
062
063 /**
064 * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface|null
065 */
066 protected $generator;
067
068 /**
069 * @var RequestContext
070 */
071 protected $context;
072
073 /**
074 * @var RouteCollection
075 */
076 protected $route_collection;
077
078 /**
079 * @var string
080 */
081 protected $cache_dir;
082
083 /**
084 * Construct method
085 *
086 * @param ContainerInterface $container DI container
087 * @param resources_locator_interface $resources_locator Resources locator
088 * @param LoaderInterface $loader Resources loader
089 * @param string $php_ext PHP file extension
090 * @param string $cache_dir phpBB cache directory
091 */
092 public function __construct(ContainerInterface $container, resources_locator_interface $resources_locator, LoaderInterface $loader, $php_ext, $cache_dir)
093 {
094 $this->container = $container;
095 $this->resources_locator = $resources_locator;
096 $this->loader = $loader;
097 $this->php_ext = $php_ext;
098 $this->context = new RequestContext();
099 $this->cache_dir = $cache_dir;
100 }
101
102 /**
103 * Get the list of routes
104 *
105 * @return RouteCollection Get the route collection
106 */
107 public function get_routes()
108 {
109 if ($this->route_collection === null /*|| $this->route_collection->count() === 0*/)
110 {
111 $this->route_collection = new RouteCollection;
112 foreach ($this->resources_locator->locate_resources() as $resource)
113 {
114 if (is_array($resource))
115 {
116 $this->route_collection->addCollection($this->loader->load($resource[0], $resource[1]));
117 }
118 else
119 {
120 $this->route_collection->addCollection($this->loader->load($resource));
121 }
122 }
123
124 $this->resolveParameters($this->route_collection);
125 }
126
127 return $this->route_collection;
128 }
129
130 /**
131 * {@inheritdoc}
132 */
133 public function getRouteCollection()
134 {
135 return $this->get_routes();
136 }
137
138 /**
139 * {@inheritdoc}
140 */
141 public function setContext(RequestContext $context)
142 {
143 $this->context = $context;
144
145 if ($this->matcher !== null)
146 {
147 $this->get_matcher()->setContext($context);
148 }
149 if ($this->generator !== null)
150 {
151 $this->get_generator()->setContext($context);
152 }
153 }
154
155 /**
156 * {@inheritdoc}
157 */
158 public function getContext()
159 {
160 return $this->context;
161 }
162
163 /**
164 * {@inheritdoc}
165 */
166 public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
167 {
168 return $this->get_generator()->generate($name, $parameters, $referenceType);
169 }
170
171 /**
172 * {@inheritdoc}
173 */
174 public function match($pathinfo)
175 {
176 return $this->get_matcher()->match($pathinfo);
177 }
178
179 /**
180 * Gets the UrlMatcher instance associated with this Router.
181 *
182 * @return \Symfony\Component\Routing\Matcher\UrlMatcherInterface A UrlMatcherInterface instance
183 */
184 public function get_matcher()
185 {
186 if ($this->matcher !== null)
187 {
188 return $this->matcher;
189 }
190
191 $this->create_dumped_url_matcher();
192
193 return $this->matcher;
194 }
195
196 /**
197 * Creates a new dumped URL Matcher (dump it if necessary)
198 */
199 protected function create_dumped_url_matcher()
200 {
201 try
202 {
203 $cache = new ConfigCache("{$this->cache_dir}url_matcher.{$this->php_ext}", defined('DEBUG'));
204 if (!$cache->isFresh())
205 {
206 $dumper = new PhpMatcherDumper($this->get_routes());
207
208 $options = array(
209 'class' => 'phpbb_url_matcher',
210 'base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
211 );
212
213 $cache->write($dumper->dump($options), $this->get_routes()->getResources());
214 }
215
216 require_once($cache->getPath());
217
218 $this->matcher = new \phpbb_url_matcher($this->context);
219 }
220 catch (IOException $e)
221 {
222 $this->create_new_url_matcher();
223 }
224 }
225
226 /**
227 * Creates a new URL Matcher
228 */
229 protected function create_new_url_matcher()
230 {
231 $this->matcher = new UrlMatcher($this->get_routes(), $this->context);
232 }
233
234 /**
235 * Gets the UrlGenerator instance associated with this Router.
236 *
237 * @return \Symfony\Component\Routing\Generator\UrlGeneratorInterface A UrlGeneratorInterface instance
238 */
239 public function get_generator()
240 {
241 if ($this->generator !== null)
242 {
243 return $this->generator;
244 }
245
246 $this->create_dumped_url_generator();
247
248 return $this->generator;
249 }
250
251 /**
252 * Creates a new dumped URL Generator (dump it if necessary)
253 */
254 protected function create_dumped_url_generator()
255 {
256 try
257 {
258 $cache = new ConfigCache("{$this->cache_dir}url_generator.{$this->php_ext}", defined('DEBUG'));
259 if (!$cache->isFresh())
260 {
261 $dumper = new PhpGeneratorDumper($this->get_routes());
262
263 $options = array(
264 'class' => 'phpbb_url_generator',
265 'base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
266 );
267
268 $cache->write($dumper->dump($options), $this->get_routes()->getResources());
269 }
270
271 require_once($cache->getPath());
272
273 $this->generator = new \phpbb_url_generator($this->context);
274 }
275 catch (IOException $e)
276 {
277 $this->create_new_url_generator();
278 }
279 }
280
281 /**
282 * Creates a new URL Generator
283 */
284 protected function create_new_url_generator()
285 {
286 $this->generator = new UrlGenerator($this->get_routes(), $this->context);
287 }
288
289 /**
290 * Replaces placeholders with service container parameter values in:
291 * - the route defaults,
292 * - the route requirements,
293 * - the route path,
294 * - the route host,
295 * - the route schemes,
296 * - the route methods.
297 *
298 * @param RouteCollection $collection
299 */
300 protected function resolveParameters(RouteCollection $collection)
301 {
302 /** @var \Symfony\Component\Routing\Route $route */
303 foreach ($collection as $route)
304 {
305 foreach ($route->getDefaults() as $name => $value)
306 {
307 $route->setDefault($name, $this->resolve($value));
308 }
309
310 $requirements = $route->getRequirements();
311 unset($requirements['_scheme']);
312 unset($requirements['_method']);
313
314 foreach ($requirements as $name => $value)
315 {
316 $route->setRequirement($name, $this->resolve($value));
317 }
318
319 $route->setPath($this->resolve($route->getPath()));
320 $route->setHost($this->resolve($route->getHost()));
321
322 $schemes = array();
323 foreach ($route->getSchemes() as $scheme)
324 {
325 $schemes = array_merge($schemes, explode('|', $this->resolve($scheme)));
326 }
327
328 $route->setSchemes($schemes);
329 $methods = array();
330 foreach ($route->getMethods() as $method)
331 {
332 $methods = array_merge($methods, explode('|', $this->resolve($method)));
333 }
334
335 $route->setMethods($methods);
336 $route->setCondition($this->resolve($route->getCondition()));
337 }
338 }
339
340 /**
341 * Recursively replaces placeholders with the service container parameters.
342 *
343 * @param mixed $value The source which might contain "%placeholders%"
344 *
345 * @return mixed The source with the placeholders replaced by the container
346 * parameters. Arrays are resolved recursively.
347 *
348 * @throws ParameterNotFoundException When a placeholder does not exist as a container parameter
349 * @throws RuntimeException When a container value is not a string or a numeric value
350 */
351 private function resolve($value)
352 {
353 if (is_array($value))
354 {
355 foreach ($value as $key => $val)
356 {
357 $value[$key] = $this->resolve($val);
358 }
359
360 return $value;
361 }
362
363 if (!is_string($value))
364 {
365 return $value;
366 }
367
368 $container = $this->container;
369 $escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value)
370 {
371 // skip %%
372 if (!isset($match[1]))
373 {
374 return '%%';
375 }
376
377 $resolved = $container->getParameter($match[1]);
378 if (is_string($resolved) || is_numeric($resolved))
379 {
380 return (string) $resolved;
381 }
382
383 throw new RuntimeException(sprintf(
384 'The container parameter "%s", used in the route configuration value "%s", '.
385 'must be a string or numeric, but it is of type %s.',
386 $match[1],
387 $value,
388 gettype($resolved)
389 )
390 );
391 }, $value);
392
393 return str_replace('%%', '%', $escapedValue);
394 }
395 }
396