Overview

Namespaces

  • Evenement
  • None
  • PHP
  • Psr
    • Http
      • Message
  • Ratchet
    • Http
    • RFC6455
      • Handshake
      • Messaging
    • Server
    • Session
      • Serialize
      • Storage
        • Proxy
    • Wamp
    • WebSocket
  • React
    • EventLoop
      • Tick
      • Timer
    • Socket
    • Stream
  • Symfony
    • Component
      • HttpFoundation
        • Session
          • Attribute
          • Flash
          • Storage
            • Handler
            • Proxy
      • Routing
        • Annotation
        • Exception
        • Generator
          • Dumper
        • Loader
          • DependencyInjection
        • Matcher
          • Dumper
        • Tests
          • Annotation
          • Fixtures
            • AnnotatedClasses
            • OtherAnnotatedClasses
          • Generator
            • Dumper
          • Loader
          • Matcher
            • Dumper

Classes

  • CompiledRoute
  • RequestContext
  • Route
  • RouteCollection
  • RouteCollectionBuilder
  • RouteCompiler
  • Router

Interfaces

  • RequestContextAwareInterface
  • RouteCompilerInterface
  • RouterInterface
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: /*
  4:  * This file is part of the Symfony package.
  5:  *
  6:  * (c) Fabien Potencier <[email protected]>
  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\Component\Routing;
 13: 
 14: use Symfony\Component\Config\Loader\LoaderInterface;
 15: use Symfony\Component\Config\ConfigCacheInterface;
 16: use Symfony\Component\Config\ConfigCacheFactoryInterface;
 17: use Symfony\Component\Config\ConfigCacheFactory;
 18: use Psr\Log\LoggerInterface;
 19: use Symfony\Component\Routing\Generator\ConfigurableRequirementsInterface;
 20: use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
 21: use Symfony\Component\Routing\Generator\Dumper\GeneratorDumperInterface;
 22: use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
 23: use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
 24: use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
 25: use Symfony\Component\HttpFoundation\Request;
 26: use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
 27: 
 28: /**
 29:  * The Router class is an example of the integration of all pieces of the
 30:  * routing system for easier use.
 31:  *
 32:  * @author Fabien Potencier <[email protected]>
 33:  */
 34: class Router implements RouterInterface, RequestMatcherInterface
 35: {
 36:     /**
 37:      * @var UrlMatcherInterface|null
 38:      */
 39:     protected $matcher;
 40: 
 41:     /**
 42:      * @var UrlGeneratorInterface|null
 43:      */
 44:     protected $generator;
 45: 
 46:     /**
 47:      * @var RequestContext
 48:      */
 49:     protected $context;
 50: 
 51:     /**
 52:      * @var LoaderInterface
 53:      */
 54:     protected $loader;
 55: 
 56:     /**
 57:      * @var RouteCollection|null
 58:      */
 59:     protected $collection;
 60: 
 61:     /**
 62:      * @var mixed
 63:      */
 64:     protected $resource;
 65: 
 66:     /**
 67:      * @var array
 68:      */
 69:     protected $options = array();
 70: 
 71:     /**
 72:      * @var LoggerInterface|null
 73:      */
 74:     protected $logger;
 75: 
 76:     /**
 77:      * @var ConfigCacheFactoryInterface|null
 78:      */
 79:     private $configCacheFactory;
 80: 
 81:     /**
 82:      * @var ExpressionFunctionProviderInterface[]
 83:      */
 84:     private $expressionLanguageProviders = array();
 85: 
 86:     /**
 87:      * Constructor.
 88:      *
 89:      * @param LoaderInterface $loader   A LoaderInterface instance
 90:      * @param mixed           $resource The main resource to load
 91:      * @param array           $options  An array of options
 92:      * @param RequestContext  $context  The context
 93:      * @param LoggerInterface $logger   A logger instance
 94:      */
 95:     public function __construct(LoaderInterface $loader, $resource, array $options = array(), RequestContext $context = null, LoggerInterface $logger = null)
 96:     {
 97:         $this->loader = $loader;
 98:         $this->resource = $resource;
 99:         $this->logger = $logger;
100:         $this->context = $context ?: new RequestContext();
101:         $this->setOptions($options);
102:     }
103: 
104:     /**
105:      * Sets options.
106:      *
107:      * Available options:
108:      *
109:      *   * cache_dir:              The cache directory (or null to disable caching)
110:      *   * debug:                  Whether to enable debugging or not (false by default)
111:      *   * generator_class:        The name of a UrlGeneratorInterface implementation
112:      *   * generator_base_class:   The base class for the dumped generator class
113:      *   * generator_cache_class:  The class name for the dumped generator class
114:      *   * generator_dumper_class: The name of a GeneratorDumperInterface implementation
115:      *   * matcher_class:          The name of a UrlMatcherInterface implementation
116:      *   * matcher_base_class:     The base class for the dumped matcher class
117:      *   * matcher_dumper_class:   The class name for the dumped matcher class
118:      *   * matcher_cache_class:    The name of a MatcherDumperInterface implementation
119:      *   * resource_type:          Type hint for the main resource (optional)
120:      *   * strict_requirements:    Configure strict requirement checking for generators
121:      *                             implementing ConfigurableRequirementsInterface (default is true)
122:      *
123:      * @param array $options An array of options
124:      *
125:      * @throws \InvalidArgumentException When unsupported option is provided
126:      */
127:     public function setOptions(array $options)
128:     {
129:         $this->options = array(
130:             'cache_dir' => null,
131:             'debug' => false,
132:             'generator_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
133:             'generator_base_class' => 'Symfony\\Component\\Routing\\Generator\\UrlGenerator',
134:             'generator_dumper_class' => 'Symfony\\Component\\Routing\\Generator\\Dumper\\PhpGeneratorDumper',
135:             'generator_cache_class' => 'ProjectUrlGenerator',
136:             'matcher_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
137:             'matcher_base_class' => 'Symfony\\Component\\Routing\\Matcher\\UrlMatcher',
138:             'matcher_dumper_class' => 'Symfony\\Component\\Routing\\Matcher\\Dumper\\PhpMatcherDumper',
139:             'matcher_cache_class' => 'ProjectUrlMatcher',
140:             'resource_type' => null,
141:             'strict_requirements' => true,
142:         );
143: 
144:         // check option names and live merge, if errors are encountered Exception will be thrown
145:         $invalid = array();
146:         foreach ($options as $key => $value) {
147:             if (array_key_exists($key, $this->options)) {
148:                 $this->options[$key] = $value;
149:             } else {
150:                 $invalid[] = $key;
151:             }
152:         }
153: 
154:         if ($invalid) {
155:             throw new \InvalidArgumentException(sprintf('The Router does not support the following options: "%s".', implode('", "', $invalid)));
156:         }
157:     }
158: 
159:     /**
160:      * Sets an option.
161:      *
162:      * @param string $key   The key
163:      * @param mixed  $value The value
164:      *
165:      * @throws \InvalidArgumentException
166:      */
167:     public function setOption($key, $value)
168:     {
169:         if (!array_key_exists($key, $this->options)) {
170:             throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
171:         }
172: 
173:         $this->options[$key] = $value;
174:     }
175: 
176:     /**
177:      * Gets an option value.
178:      *
179:      * @param string $key The key
180:      *
181:      * @return mixed The value
182:      *
183:      * @throws \InvalidArgumentException
184:      */
185:     public function getOption($key)
186:     {
187:         if (!array_key_exists($key, $this->options)) {
188:             throw new \InvalidArgumentException(sprintf('The Router does not support the "%s" option.', $key));
189:         }
190: 
191:         return $this->options[$key];
192:     }
193: 
194:     /**
195:      * {@inheritdoc}
196:      */
197:     public function getRouteCollection()
198:     {
199:         if (null === $this->collection) {
200:             $this->collection = $this->loader->load($this->resource, $this->options['resource_type']);
201:         }
202: 
203:         return $this->collection;
204:     }
205: 
206:     /**
207:      * {@inheritdoc}
208:      */
209:     public function setContext(RequestContext $context)
210:     {
211:         $this->context = $context;
212: 
213:         if (null !== $this->matcher) {
214:             $this->getMatcher()->setContext($context);
215:         }
216:         if (null !== $this->generator) {
217:             $this->getGenerator()->setContext($context);
218:         }
219:     }
220: 
221:     /**
222:      * {@inheritdoc}
223:      */
224:     public function getContext()
225:     {
226:         return $this->context;
227:     }
228: 
229:     /**
230:      * Sets the ConfigCache factory to use.
231:      *
232:      * @param ConfigCacheFactoryInterface $configCacheFactory The factory to use
233:      */
234:     public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
235:     {
236:         $this->configCacheFactory = $configCacheFactory;
237:     }
238: 
239:     /**
240:      * {@inheritdoc}
241:      */
242:     public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
243:     {
244:         return $this->getGenerator()->generate($name, $parameters, $referenceType);
245:     }
246: 
247:     /**
248:      * {@inheritdoc}
249:      */
250:     public function match($pathinfo)
251:     {
252:         return $this->getMatcher()->match($pathinfo);
253:     }
254: 
255:     /**
256:      * {@inheritdoc}
257:      */
258:     public function matchRequest(Request $request)
259:     {
260:         $matcher = $this->getMatcher();
261:         if (!$matcher instanceof RequestMatcherInterface) {
262:             // fallback to the default UrlMatcherInterface
263:             return $matcher->match($request->getPathInfo());
264:         }
265: 
266:         return $matcher->matchRequest($request);
267:     }
268: 
269:     /**
270:      * Gets the UrlMatcher instance associated with this Router.
271:      *
272:      * @return UrlMatcherInterface A UrlMatcherInterface instance
273:      */
274:     public function getMatcher()
275:     {
276:         if (null !== $this->matcher) {
277:             return $this->matcher;
278:         }
279: 
280:         if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
281:             $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
282:             if (method_exists($this->matcher, 'addExpressionLanguageProvider')) {
283:                 foreach ($this->expressionLanguageProviders as $provider) {
284:                     $this->matcher->addExpressionLanguageProvider($provider);
285:                 }
286:             }
287: 
288:             return $this->matcher;
289:         }
290: 
291:         $class = $this->options['matcher_cache_class'];
292:         $baseClass = $this->options['matcher_base_class'];
293:         $expressionLanguageProviders = $this->expressionLanguageProviders;
294:         $that = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
295: 
296:         $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php',
297:             function (ConfigCacheInterface $cache) use ($that, $class, $baseClass, $expressionLanguageProviders) {
298:                 $dumper = $that->getMatcherDumperInstance();
299:                 if (method_exists($dumper, 'addExpressionLanguageProvider')) {
300:                     foreach ($expressionLanguageProviders as $provider) {
301:                         $dumper->addExpressionLanguageProvider($provider);
302:                     }
303:                 }
304: 
305:                 $options = array(
306:                     'class' => $class,
307:                     'base_class' => $baseClass,
308:                 );
309: 
310:                 $cache->write($dumper->dump($options), $that->getRouteCollection()->getResources());
311:             }
312:         );
313: 
314:         require_once $cache->getPath();
315: 
316:         return $this->matcher = new $class($this->context);
317:     }
318: 
319:     /**
320:      * Gets the UrlGenerator instance associated with this Router.
321:      *
322:      * @return UrlGeneratorInterface A UrlGeneratorInterface instance
323:      */
324:     public function getGenerator()
325:     {
326:         if (null !== $this->generator) {
327:             return $this->generator;
328:         }
329: 
330:         if (null === $this->options['cache_dir'] || null === $this->options['generator_cache_class']) {
331:             $this->generator = new $this->options['generator_class']($this->getRouteCollection(), $this->context, $this->logger);
332:         } else {
333:             $class = $this->options['generator_cache_class'];
334:             $baseClass = $this->options['generator_base_class'];
335:             $that = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
336:             $cache = $this->getConfigCacheFactory()->cache($this->options['cache_dir'].'/'.$class.'.php',
337:                 function (ConfigCacheInterface $cache) use ($that, $class, $baseClass) {
338:                     $dumper = $that->getGeneratorDumperInstance();
339: 
340:                     $options = array(
341:                         'class' => $class,
342:                         'base_class' => $baseClass,
343:                     );
344: 
345:                     $cache->write($dumper->dump($options), $that->getRouteCollection()->getResources());
346:                 }
347:             );
348: 
349:             require_once $cache->getPath();
350: 
351:             $this->generator = new $class($this->context, $this->logger);
352:         }
353: 
354:         if ($this->generator instanceof ConfigurableRequirementsInterface) {
355:             $this->generator->setStrictRequirements($this->options['strict_requirements']);
356:         }
357: 
358:         return $this->generator;
359:     }
360: 
361:     public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
362:     {
363:         $this->expressionLanguageProviders[] = $provider;
364:     }
365: 
366:     /**
367:      * This method is public because it needs to be callable from a closure in PHP 5.3. It should be converted back to protected in 3.0.
368:      *
369:      * @internal
370:      *
371:      * @return GeneratorDumperInterface
372:      */
373:     public function getGeneratorDumperInstance()
374:     {
375:         return new $this->options['generator_dumper_class']($this->getRouteCollection());
376:     }
377: 
378:     /**
379:      * This method is public because it needs to be callable from a closure in PHP 5.3. It should be converted back to protected in 3.0.
380:      *
381:      * @internal
382:      *
383:      * @return MatcherDumperInterface
384:      */
385:     public function getMatcherDumperInstance()
386:     {
387:         return new $this->options['matcher_dumper_class']($this->getRouteCollection());
388:     }
389: 
390:     /**
391:      * Provides the ConfigCache factory implementation, falling back to a
392:      * default implementation if necessary.
393:      *
394:      * @return ConfigCacheFactoryInterface $configCacheFactory
395:      */
396:     private function getConfigCacheFactory()
397:     {
398:         if (null === $this->configCacheFactory) {
399:             $this->configCacheFactory = new ConfigCacheFactory($this->options['debug']);
400:         }
401: 
402:         return $this->configCacheFactory;
403:     }
404: }
405: 
Ratchet API documentation generated by ApiGen 2.8.0