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: /**
 15:  * A Route describes a route and its parameters.
 16:  *
 17:  * @author Fabien Potencier <[email protected]>
 18:  * @author Tobias Schultze <http://tobion.de>
 19:  */
 20: class Route implements \Serializable
 21: {
 22:     /**
 23:      * @var string
 24:      */
 25:     private $path = '/';
 26: 
 27:     /**
 28:      * @var string
 29:      */
 30:     private $host = '';
 31: 
 32:     /**
 33:      * @var array
 34:      */
 35:     private $schemes = array();
 36: 
 37:     /**
 38:      * @var array
 39:      */
 40:     private $methods = array();
 41: 
 42:     /**
 43:      * @var array
 44:      */
 45:     private $defaults = array();
 46: 
 47:     /**
 48:      * @var array
 49:      */
 50:     private $requirements = array();
 51: 
 52:     /**
 53:      * @var array
 54:      */
 55:     private $options = array();
 56: 
 57:     /**
 58:      * @var null|CompiledRoute
 59:      */
 60:     private $compiled;
 61: 
 62:     /**
 63:      * @var string
 64:      */
 65:     private $condition = '';
 66: 
 67:     /**
 68:      * Constructor.
 69:      *
 70:      * Available options:
 71:      *
 72:      *  * compiler_class: A class name able to compile this route instance (RouteCompiler by default)
 73:      *
 74:      * @param string       $path         The path pattern to match
 75:      * @param array        $defaults     An array of default parameter values
 76:      * @param array        $requirements An array of requirements for parameters (regexes)
 77:      * @param array        $options      An array of options
 78:      * @param string       $host         The host pattern to match
 79:      * @param string|array $schemes      A required URI scheme or an array of restricted schemes
 80:      * @param string|array $methods      A required HTTP method or an array of restricted methods
 81:      * @param string       $condition    A condition that should evaluate to true for the route to match
 82:      */
 83:     public function __construct($path, array $defaults = array(), array $requirements = array(), array $options = array(), $host = '', $schemes = array(), $methods = array(), $condition = '')
 84:     {
 85:         $this->setPath($path);
 86:         $this->setDefaults($defaults);
 87:         $this->setRequirements($requirements);
 88:         $this->setOptions($options);
 89:         $this->setHost($host);
 90:         // The conditions make sure that an initial empty $schemes/$methods does not override the corresponding requirement.
 91:         // They can be removed when the BC layer is removed.
 92:         if ($schemes) {
 93:             $this->setSchemes($schemes);
 94:         }
 95:         if ($methods) {
 96:             $this->setMethods($methods);
 97:         }
 98:         $this->setCondition($condition);
 99:     }
100: 
101:     /**
102:      * {@inheritdoc}
103:      */
104:     public function serialize()
105:     {
106:         return serialize(array(
107:             'path' => $this->path,
108:             'host' => $this->host,
109:             'defaults' => $this->defaults,
110:             'requirements' => $this->requirements,
111:             'options' => $this->options,
112:             'schemes' => $this->schemes,
113:             'methods' => $this->methods,
114:             'condition' => $this->condition,
115:             'compiled' => $this->compiled,
116:         ));
117:     }
118: 
119:     /**
120:      * {@inheritdoc}
121:      */
122:     public function unserialize($serialized)
123:     {
124:         $data = unserialize($serialized);
125:         $this->path = $data['path'];
126:         $this->host = $data['host'];
127:         $this->defaults = $data['defaults'];
128:         $this->requirements = $data['requirements'];
129:         $this->options = $data['options'];
130:         $this->schemes = $data['schemes'];
131:         $this->methods = $data['methods'];
132: 
133:         if (isset($data['condition'])) {
134:             $this->condition = $data['condition'];
135:         }
136:         if (isset($data['compiled'])) {
137:             $this->compiled = $data['compiled'];
138:         }
139:     }
140: 
141:     /**
142:      * Returns the pattern for the path.
143:      *
144:      * @return string The pattern
145:      *
146:      * @deprecated since version 2.2, to be removed in 3.0. Use getPath instead.
147:      */
148:     public function getPattern()
149:     {
150:         @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Use the getPath() method instead.', E_USER_DEPRECATED);
151: 
152:         return $this->path;
153:     }
154: 
155:     /**
156:      * Sets the pattern for the path.
157:      *
158:      * This method implements a fluent interface.
159:      *
160:      * @param string $pattern The path pattern
161:      *
162:      * @return $this
163:      *
164:      * @deprecated since version 2.2, to be removed in 3.0. Use setPath instead.
165:      */
166:     public function setPattern($pattern)
167:     {
168:         @trigger_error('The '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Use the setPath() method instead.', E_USER_DEPRECATED);
169: 
170:         return $this->setPath($pattern);
171:     }
172: 
173:     /**
174:      * Returns the pattern for the path.
175:      *
176:      * @return string The path pattern
177:      */
178:     public function getPath()
179:     {
180:         return $this->path;
181:     }
182: 
183:     /**
184:      * Sets the pattern for the path.
185:      *
186:      * This method implements a fluent interface.
187:      *
188:      * @param string $pattern The path pattern
189:      *
190:      * @return $this
191:      */
192:     public function setPath($pattern)
193:     {
194:         // A pattern must start with a slash and must not have multiple slashes at the beginning because the
195:         // generated path for this route would be confused with a network path, e.g. '//domain.com/path'.
196:         $this->path = '/'.ltrim(trim($pattern), '/');
197:         $this->compiled = null;
198: 
199:         return $this;
200:     }
201: 
202:     /**
203:      * Returns the pattern for the host.
204:      *
205:      * @return string The host pattern
206:      */
207:     public function getHost()
208:     {
209:         return $this->host;
210:     }
211: 
212:     /**
213:      * Sets the pattern for the host.
214:      *
215:      * This method implements a fluent interface.
216:      *
217:      * @param string $pattern The host pattern
218:      *
219:      * @return $this
220:      */
221:     public function setHost($pattern)
222:     {
223:         $this->host = (string) $pattern;
224:         $this->compiled = null;
225: 
226:         return $this;
227:     }
228: 
229:     /**
230:      * Returns the lowercased schemes this route is restricted to.
231:      * So an empty array means that any scheme is allowed.
232:      *
233:      * @return array The schemes
234:      */
235:     public function getSchemes()
236:     {
237:         return $this->schemes;
238:     }
239: 
240:     /**
241:      * Sets the schemes (e.g. 'https') this route is restricted to.
242:      * So an empty array means that any scheme is allowed.
243:      *
244:      * This method implements a fluent interface.
245:      *
246:      * @param string|array $schemes The scheme or an array of schemes
247:      *
248:      * @return $this
249:      */
250:     public function setSchemes($schemes)
251:     {
252:         $this->schemes = array_map('strtolower', (array) $schemes);
253: 
254:         // this is to keep BC and will be removed in a future version
255:         if ($this->schemes) {
256:             $this->requirements['_scheme'] = implode('|', $this->schemes);
257:         } else {
258:             unset($this->requirements['_scheme']);
259:         }
260: 
261:         $this->compiled = null;
262: 
263:         return $this;
264:     }
265: 
266:     /**
267:      * Checks if a scheme requirement has been set.
268:      *
269:      * @param string $scheme
270:      *
271:      * @return bool true if the scheme requirement exists, otherwise false
272:      */
273:     public function hasScheme($scheme)
274:     {
275:         return in_array(strtolower($scheme), $this->schemes, true);
276:     }
277: 
278:     /**
279:      * Returns the uppercased HTTP methods this route is restricted to.
280:      * So an empty array means that any method is allowed.
281:      *
282:      * @return array The methods
283:      */
284:     public function getMethods()
285:     {
286:         return $this->methods;
287:     }
288: 
289:     /**
290:      * Sets the HTTP methods (e.g. 'POST') this route is restricted to.
291:      * So an empty array means that any method is allowed.
292:      *
293:      * This method implements a fluent interface.
294:      *
295:      * @param string|array $methods The method or an array of methods
296:      *
297:      * @return $this
298:      */
299:     public function setMethods($methods)
300:     {
301:         $this->methods = array_map('strtoupper', (array) $methods);
302: 
303:         // this is to keep BC and will be removed in a future version
304:         if ($this->methods) {
305:             $this->requirements['_method'] = implode('|', $this->methods);
306:         } else {
307:             unset($this->requirements['_method']);
308:         }
309: 
310:         $this->compiled = null;
311: 
312:         return $this;
313:     }
314: 
315:     /**
316:      * Returns the options.
317:      *
318:      * @return array The options
319:      */
320:     public function getOptions()
321:     {
322:         return $this->options;
323:     }
324: 
325:     /**
326:      * Sets the options.
327:      *
328:      * This method implements a fluent interface.
329:      *
330:      * @param array $options The options
331:      *
332:      * @return $this
333:      */
334:     public function setOptions(array $options)
335:     {
336:         $this->options = array(
337:             'compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler',
338:         );
339: 
340:         return $this->addOptions($options);
341:     }
342: 
343:     /**
344:      * Adds options.
345:      *
346:      * This method implements a fluent interface.
347:      *
348:      * @param array $options The options
349:      *
350:      * @return $this
351:      */
352:     public function addOptions(array $options)
353:     {
354:         foreach ($options as $name => $option) {
355:             $this->options[$name] = $option;
356:         }
357:         $this->compiled = null;
358: 
359:         return $this;
360:     }
361: 
362:     /**
363:      * Sets an option value.
364:      *
365:      * This method implements a fluent interface.
366:      *
367:      * @param string $name  An option name
368:      * @param mixed  $value The option value
369:      *
370:      * @return $this
371:      */
372:     public function setOption($name, $value)
373:     {
374:         $this->options[$name] = $value;
375:         $this->compiled = null;
376: 
377:         return $this;
378:     }
379: 
380:     /**
381:      * Get an option value.
382:      *
383:      * @param string $name An option name
384:      *
385:      * @return mixed The option value or null when not given
386:      */
387:     public function getOption($name)
388:     {
389:         return isset($this->options[$name]) ? $this->options[$name] : null;
390:     }
391: 
392:     /**
393:      * Checks if an option has been set.
394:      *
395:      * @param string $name An option name
396:      *
397:      * @return bool true if the option is set, false otherwise
398:      */
399:     public function hasOption($name)
400:     {
401:         return array_key_exists($name, $this->options);
402:     }
403: 
404:     /**
405:      * Returns the defaults.
406:      *
407:      * @return array The defaults
408:      */
409:     public function getDefaults()
410:     {
411:         return $this->defaults;
412:     }
413: 
414:     /**
415:      * Sets the defaults.
416:      *
417:      * This method implements a fluent interface.
418:      *
419:      * @param array $defaults The defaults
420:      *
421:      * @return $this
422:      */
423:     public function setDefaults(array $defaults)
424:     {
425:         $this->defaults = array();
426: 
427:         return $this->addDefaults($defaults);
428:     }
429: 
430:     /**
431:      * Adds defaults.
432:      *
433:      * This method implements a fluent interface.
434:      *
435:      * @param array $defaults The defaults
436:      *
437:      * @return $this
438:      */
439:     public function addDefaults(array $defaults)
440:     {
441:         foreach ($defaults as $name => $default) {
442:             $this->defaults[$name] = $default;
443:         }
444:         $this->compiled = null;
445: 
446:         return $this;
447:     }
448: 
449:     /**
450:      * Gets a default value.
451:      *
452:      * @param string $name A variable name
453:      *
454:      * @return mixed The default value or null when not given
455:      */
456:     public function getDefault($name)
457:     {
458:         return isset($this->defaults[$name]) ? $this->defaults[$name] : null;
459:     }
460: 
461:     /**
462:      * Checks if a default value is set for the given variable.
463:      *
464:      * @param string $name A variable name
465:      *
466:      * @return bool true if the default value is set, false otherwise
467:      */
468:     public function hasDefault($name)
469:     {
470:         return array_key_exists($name, $this->defaults);
471:     }
472: 
473:     /**
474:      * Sets a default value.
475:      *
476:      * @param string $name    A variable name
477:      * @param mixed  $default The default value
478:      *
479:      * @return $this
480:      */
481:     public function setDefault($name, $default)
482:     {
483:         $this->defaults[$name] = $default;
484:         $this->compiled = null;
485: 
486:         return $this;
487:     }
488: 
489:     /**
490:      * Returns the requirements.
491:      *
492:      * @return array The requirements
493:      */
494:     public function getRequirements()
495:     {
496:         return $this->requirements;
497:     }
498: 
499:     /**
500:      * Sets the requirements.
501:      *
502:      * This method implements a fluent interface.
503:      *
504:      * @param array $requirements The requirements
505:      *
506:      * @return $this
507:      */
508:     public function setRequirements(array $requirements)
509:     {
510:         $this->requirements = array();
511: 
512:         return $this->addRequirements($requirements);
513:     }
514: 
515:     /**
516:      * Adds requirements.
517:      *
518:      * This method implements a fluent interface.
519:      *
520:      * @param array $requirements The requirements
521:      *
522:      * @return $this
523:      */
524:     public function addRequirements(array $requirements)
525:     {
526:         foreach ($requirements as $key => $regex) {
527:             $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
528:         }
529:         $this->compiled = null;
530: 
531:         return $this;
532:     }
533: 
534:     /**
535:      * Returns the requirement for the given key.
536:      *
537:      * @param string $key The key
538:      *
539:      * @return string|null The regex or null when not given
540:      */
541:     public function getRequirement($key)
542:     {
543:         if ('_scheme' === $key) {
544:             @trigger_error('The "_scheme" requirement is deprecated since version 2.2 and will be removed in 3.0. Use getSchemes() instead.', E_USER_DEPRECATED);
545:         } elseif ('_method' === $key) {
546:             @trigger_error('The "_method" requirement is deprecated since version 2.2 and will be removed in 3.0. Use getMethods() instead.', E_USER_DEPRECATED);
547:         }
548: 
549:         return isset($this->requirements[$key]) ? $this->requirements[$key] : null;
550:     }
551: 
552:     /**
553:      * Checks if a requirement is set for the given key.
554:      *
555:      * @param string $key A variable name
556:      *
557:      * @return bool true if a requirement is specified, false otherwise
558:      */
559:     public function hasRequirement($key)
560:     {
561:         return array_key_exists($key, $this->requirements);
562:     }
563: 
564:     /**
565:      * Sets a requirement for the given key.
566:      *
567:      * @param string $key   The key
568:      * @param string $regex The regex
569:      *
570:      * @return $this
571:      */
572:     public function setRequirement($key, $regex)
573:     {
574:         $this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
575:         $this->compiled = null;
576: 
577:         return $this;
578:     }
579: 
580:     /**
581:      * Returns the condition.
582:      *
583:      * @return string The condition
584:      */
585:     public function getCondition()
586:     {
587:         return $this->condition;
588:     }
589: 
590:     /**
591:      * Sets the condition.
592:      *
593:      * This method implements a fluent interface.
594:      *
595:      * @param string $condition The condition
596:      *
597:      * @return $this
598:      */
599:     public function setCondition($condition)
600:     {
601:         $this->condition = (string) $condition;
602:         $this->compiled = null;
603: 
604:         return $this;
605:     }
606: 
607:     /**
608:      * Compiles the route.
609:      *
610:      * @return CompiledRoute A CompiledRoute instance
611:      *
612:      * @throws \LogicException If the Route cannot be compiled because the
613:      *                         path or host pattern is invalid
614:      *
615:      * @see RouteCompiler which is responsible for the compilation process
616:      */
617:     public function compile()
618:     {
619:         if (null !== $this->compiled) {
620:             return $this->compiled;
621:         }
622: 
623:         $class = $this->getOption('compiler_class');
624: 
625:         return $this->compiled = $class::compile($this);
626:     }
627: 
628:     private function sanitizeRequirement($key, $regex)
629:     {
630:         if (!is_string($regex)) {
631:             throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" must be a string.', $key));
632:         }
633: 
634:         if ('' !== $regex && '^' === $regex[0]) {
635:             $regex = (string) substr($regex, 1); // returns false for a single character
636:         }
637: 
638:         if ('$' === substr($regex, -1)) {
639:             $regex = substr($regex, 0, -1);
640:         }
641: 
642:         if ('' === $regex) {
643:             throw new \InvalidArgumentException(sprintf('Routing requirement for "%s" cannot be empty.', $key));
644:         }
645: 
646:         // this is to keep BC and will be removed in a future version
647:         if ('_scheme' === $key) {
648:             @trigger_error('The "_scheme" requirement is deprecated since version 2.2 and will be removed in 3.0. Use the setSchemes() method instead.', E_USER_DEPRECATED);
649: 
650:             $this->setSchemes(explode('|', $regex));
651:         } elseif ('_method' === $key) {
652:             @trigger_error('The "_method" requirement is deprecated since version 2.2 and will be removed in 3.0. Use the setMethods() method instead.', E_USER_DEPRECATED);
653: 
654:             $this->setMethods(explode('|', $regex));
655:         }
656: 
657:         return $regex;
658:     }
659: }
660: 
Ratchet API documentation generated by ApiGen 2.8.0