Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
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 Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\Routing;
013
014 use Psr\Log\LoggerInterface;
015 use Symfony\Component\Config\ConfigCacheFactory;
016 use Symfony\Component\Config\ConfigCacheFactoryInterface;
017 use Symfony\Component\Config\ConfigCacheInterface;
018 use Symfony\Component\Config\Loader\LoaderInterface;
019 use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
020 use Symfony\Component\HttpFoundation\Request;
021 use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
022 use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface;
023 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
024 use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
025 use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
026 use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
027
028 /**
029 * The Router class is an example of the integration of all pieces of the
030 * routing system for easier use.
031 *
032 * @author Fabien Potencier <fabien@symfony.com>
033 */
034 class Router implements RouterInterface, RequestMatcherInterface
035 {
036 /**
037 * @var UrlMatcherInterface|null
038 */
039 protected $matcher;
040
041 /**
042 * @var UrlGeneratorInterface|null
043 */
044 protected $generator;
045
046 /**
047 * @var RequestContext
048 */
049 protected $context;
050
051 /**
052 * @var LoaderInterface
053 */
054 protected $loader;
055
056 /**
057 * @var RouteCollection|null
058 */
059 protected $collection;
060
061 /**
062 * @var mixed
063 */
064 protected $resource;
065
066 /**
067 * @var array
068 */
069 protected $options = [];
070
071 /**
072 * @var LoggerInterface|null
073 */
074 protected $logger;
075
076 /**
077 * @var ConfigCacheFactoryInterface|null
078 */
079 private $configCacheFactory;
080
081 /**
082 * @var ExpressionFunctionProviderInterface[]
083 */
084 private $expressionLanguageProviders = [];
085
086 /**
087 * @param LoaderInterface $loader A LoaderInterface instance
088 * @param mixed $resource The main resource to load
089 * @param array $options An array of options
090 * @param RequestContext $context The context
091 * @param LoggerInterface $logger A logger instance
092 */
093 public function __construct(LoaderInterface $loader, $resource, array $options = [], RequestContext $context = null, LoggerInterface $logger = null)
094 {
095 $this->loader = $loader;
096 $this->resource = $resource;
097 $this->logger = $logger;
098 $this->context = $context ?: new RequestContext();
099 $this->setOptions($options);
100 }
101
102 /**
103 * Sets options.
104 *
105 * Available options:
106 *
107 * * cache_dir: The cache directory (or null to disable caching)
108 * * debug: Whether to enable debugging or not (false by default)
109 * * generator_class: The name of a UrlGeneratorInterface implementation
110 * * generator_base_class: The base class for the dumped generator class
111 * * generator_cache_class: The class name for the dumped generator class
112 * * generator_dumper_class: The name of a GeneratorDumperInterface implementation
113 * * matcher_class: The name of a UrlMatcherInterface implementation
114 * * matcher_base_class: The base class for the dumped matcher class
115 * * matcher_dumper_class: The class name for the dumped matcher class
116 * * matcher_cache_class: The name of a MatcherDumperInterface implementation
117 * * resource_type: Type hint for the main resource (optional)
118 * * strict_requirements: Configure strict requirement checking for generators
119 * implementing ConfigurableRequirementsInterface (default is true)
120 *
121 * @param array $options An array of options
122 *
123 * @throws \InvalidArgumentException When unsupported option is provided
124 */
125 public function setOptions(array $options)
126 {
127 $this->options = [
128 'cache_dir' => null,
129 'debug' => false,
130 'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
131 'generator_base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
132 'generator_dumper_class' => 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper',
133 'generator_cache_class' => 'ProjectUrlGenerator',
134 'matcher_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
135 'matcher_base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
136 'matcher_dumper_class' => 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper',
137 'matcher_cache_class' => 'ProjectUrlMatcher',
138 'resource_type' => null,
139 'strict_requirements' => true,
140 ];
141
142 // check option names and live merge, if errors are encountered Exception will be thrown
143 $invalid = [];
144 foreach ($options as $key => $value) {
145 if (\array_key_exists($key, $this->options)) {
146 $this->options[$key] = $value;
147 } else {
148 $invalid[] = $key;
149 }
150 }
151
152 if ($invalid) {
153 throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('", "', $invalid)));
154 }
155 }
156
157 /**
158 * Sets an option.
159 *
160 * @param string $key The key
161 * @param mixed $value The value
162 *
163 * @throws \InvalidArgumentException
164 */
165 public function setOption($key, $value)
166 {
167 if (!\array_key_exists($key, $this->options)) {
168 throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
169 }
170
171 $this->options[$key] = $value;
172 }
173
174 /**
175 * Gets an option value.
176 *
177 * @param string $key The key
178 *
179 * @return mixed The value
180 *
181 * @throws \InvalidArgumentException
182 */
183 public function getOption($key)
184 {
185 if (!\array_key_exists($key, $this->options)) {
186 throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
187 }
188
189 return $this->options[$key];
190 }
191
192 /**
193 * {@inheritdoc}
194 */
195 public function getRouteCollection()
196 {
197 if (null === $this->collection) {
198 $this->collection = $this->loader->load($this->resource, $this->options['resource_type']);
199 }
200
201 return $this->collection;
202 }
203
204 /**
205 * {@inheritdoc}
206 */
207 public function setContext(RequestContext $context)
208 {
209 $this->context = $context;
210
211 if (null !== $this->matcher) {
212 $this->getMatcher()->setContext($context);
213 }
214 if (null !== $this->generator) {
215 $this->getGenerator()->setContext($context);
216 }
217 }
218
219 /**
220 * {@inheritdoc}
221 */
222 public function getContext()
223 {
224 return $this->context;
225 }
226
227 /**
228 * Sets the ConfigCache factory to use.
229 */
230 public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
231 {
232 $this->configCacheFactory = $configCacheFactory;
233 }
234
235 /**
236 * {@inheritdoc}
237 */
238 public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
239 {
240 return $this->getGenerator()->generate($name, $parameters, $referenceType);
241 }
242
243 /**
244 * {@inheritdoc}
245 */
246 public function match($pathinfo)
247 {
248 return $this->getMatcher()->match($pathinfo);
249 }
250
251 /**
252 * {@inheritdoc}
253 */
254 public function matchRequest(Request $request)
255 {
256 $matcher = $this->getMatcher();
257 if (!$matcher instanceof RequestMatcherInterface) {
258 // fallback to the default UrlMatcherInterface
259 return $matcher->match($request->getPathInfo());
260 }
261
262 return $matcher->matchRequest($request);
263 }
264
265 /**
266 * Gets the UrlMatcher or RequestMatcher instance associated with this Router.
267 *
268 * @return UrlMatcherInterface|RequestMatcherInterface
269 */
270 public function getMatcher()
271 {
272 if (null !== $this->matcher) {
273 return $this->matcher;
274 }
275
276 if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
277 $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
278 if (method_exists($this->matcher, 'addExpressionLanguageProvider')) {
279 foreach ($this->expressionLanguageProviders as $provider) {
280 $this->matcher->addExpressionLanguageProvider($provider);
281 }
282 }
283
284 return $this->matcher;
285 }
286
287 $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['matcher_cache_class'].'.php',
288 function (ConfigCacheInterface $cache) {
289 $dumper = $this->getMatcherDumperInstance();
290 if (method_exists($dumper, 'addExpressionLanguageProvider')) {
291 foreach ($this->expressionLanguageProviders as $provider) {
292 $dumper->addExpressionLanguageProvider($provider);
293 }
294 }
295
296 $options = [
297 'class' => $this->options['matcher_cache_class'],
298 'base_class' => $this->options['matcher_base_class'],
299 ];
300
301 $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
302 }
303 );
304
305 if (!class_exists($this->options['matcher_cache_class'], false)) {
306 require_once $cache->getPath();
307 }
308
309 return $this->matcher = new $this->options['matcher_cache_class']($this->context);
310 }
311
312 /**
313 * Gets the UrlGenerator instance associated with this Router.
314 *
315 * @return UrlGeneratorInterface A UrlGeneratorInterface instance
316 */
317 public function getGenerator()
318 {
319 if (null !== $this->generator) {
320 return $this->generator;
321 }
322
323 if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
324 $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
325 } else {
326 $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$this->options['generator_cache_class'].'.php',
327 function (ConfigCacheInterface $cache) {
328 $dumper = $this->getGeneratorDumperInstance();
329
330 $options = [
331 'class' => $this->options['generator_cache_class'],
332 'base_class' => $this->options['generator_base_class'],
333 ];
334
335 $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
336 }
337 );
338
339 if (!class_exists($this->options['generator_cache_class'], false)) {
340 require_once $cache->getPath();
341 }
342
343 $this->generator = new $this->options['generator_cache_class']($this->context, $this->logger);
344 }
345
346 if ($this->generator instanceof ConfigurableRequirementsInterface) {
347 $this->generator->setStrictRequirements($this->options['strict_requirements']);
348 }
349
350 return $this->generator;
351 }
352
353 public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
354 {
355 $this->expressionLanguageProviders[] = $provider;
356 }
357
358 /**
359 * @return GeneratorDumperInterface
360 */
361 protected function getGeneratorDumperInstance()
362 {
363 return new $this->options['generator_dumper_class']($this->getRouteCollection());
364 }
365
366 /**
367 * @return MatcherDumperInterface
368 */
369 protected function getMatcherDumperInstance()
370 {
371 return new $this->options['matcher_dumper_class']($this->getRouteCollection());
372 }
373
374 /**
375 * Provides the ConfigCache factory implementation, falling back to a
376 * default implementation if necessary.
377 *
378 * @return ConfigCacheFactoryInterface
379 */
380 private function getConfigCacheFactory()
381 {
382 if (null === $this->configCacheFactory) {
383 $this->configCacheFactory = new ConfigCacheFactory($this->options['debug']);
384 }
385
386 return $this->configCacheFactory;
387 }
388 }
389