RouteCollection.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Routing;
  11. use Symfony\Component\Config\Resource\ResourceInterface;
  12. /**
  13. * A RouteCollection represents a set of Route instances.
  14. *
  15. * When adding a route at the end of the collection, an existing route
  16. * with the same name is removed first. So there can only be one route
  17. * with a given name.
  18. *
  19. * @author Fabien Potencier <fabien@symfony.com>
  20. * @author Tobias Schultze <http://tobion.de>
  21. *
  22. * @api
  23. */
  24. class RouteCollection implements \IteratorAggregate, \Countable
  25. {
  26. /**
  27. * @var Route[]
  28. */
  29. private $routes = array();
  30. /**
  31. * @var array
  32. */
  33. private $resources = array();
  34. public function __clone()
  35. {
  36. foreach ($this->routes as $name => $route) {
  37. $this->routes[$name] = clone $route;
  38. }
  39. }
  40. /**
  41. * Gets the current RouteCollection as an Iterator that includes all routes.
  42. *
  43. * It implements \IteratorAggregate.
  44. *
  45. * @see all()
  46. *
  47. * @return \ArrayIterator An \ArrayIterator object for iterating over routes
  48. */
  49. public function getIterator()
  50. {
  51. return new \ArrayIterator($this->routes);
  52. }
  53. /**
  54. * Gets the number of Routes in this collection.
  55. *
  56. * @return int The number of routes
  57. */
  58. public function count()
  59. {
  60. return count($this->routes);
  61. }
  62. /**
  63. * Adds a route.
  64. *
  65. * @param string $name The route name
  66. * @param Route $route A Route instance
  67. *
  68. * @api
  69. */
  70. public function add($name, Route $route)
  71. {
  72. unset($this->routes[$name]);
  73. $this->routes[$name] = $route;
  74. }
  75. /**
  76. * Returns all routes in this collection.
  77. *
  78. * @return Route[] An array of routes
  79. */
  80. public function all()
  81. {
  82. return $this->routes;
  83. }
  84. /**
  85. * Gets a route by name.
  86. *
  87. * @param string $name The route name
  88. *
  89. * @return Route|null A Route instance or null when not found
  90. */
  91. public function get($name)
  92. {
  93. return isset($this->routes[$name]) ? $this->routes[$name] : null;
  94. }
  95. /**
  96. * Removes a route or an array of routes by name from the collection
  97. *
  98. * @param string|array $name The route name or an array of route names
  99. */
  100. public function remove($name)
  101. {
  102. foreach ((array) $name as $n) {
  103. unset($this->routes[$n]);
  104. }
  105. }
  106. /**
  107. * Adds a route collection at the end of the current set by appending all
  108. * routes of the added collection.
  109. *
  110. * @param RouteCollection $collection A RouteCollection instance
  111. *
  112. * @api
  113. */
  114. public function addCollection(RouteCollection $collection)
  115. {
  116. // we need to remove all routes with the same names first because just replacing them
  117. // would not place the new route at the end of the merged array
  118. foreach ($collection->all() as $name => $route) {
  119. unset($this->routes[$name]);
  120. $this->routes[$name] = $route;
  121. }
  122. $this->resources = array_merge($this->resources, $collection->getResources());
  123. }
  124. /**
  125. * Adds a prefix to the path of all child routes.
  126. *
  127. * @param string $prefix An optional prefix to add before each pattern of the route collection
  128. * @param array $defaults An array of default values
  129. * @param array $requirements An array of requirements
  130. *
  131. * @api
  132. */
  133. public function addPrefix($prefix, array $defaults = array(), array $requirements = array())
  134. {
  135. $prefix = trim(trim($prefix), '/');
  136. if ('' === $prefix) {
  137. return;
  138. }
  139. foreach ($this->routes as $route) {
  140. $route->setPath('/'.$prefix.$route->getPath());
  141. $route->addDefaults($defaults);
  142. $route->addRequirements($requirements);
  143. }
  144. }
  145. /**
  146. * Sets the host pattern on all routes.
  147. *
  148. * @param string $pattern The pattern
  149. * @param array $defaults An array of default values
  150. * @param array $requirements An array of requirements
  151. */
  152. public function setHost($pattern, array $defaults = array(), array $requirements = array())
  153. {
  154. foreach ($this->routes as $route) {
  155. $route->setHost($pattern);
  156. $route->addDefaults($defaults);
  157. $route->addRequirements($requirements);
  158. }
  159. }
  160. /**
  161. * Adds defaults to all routes.
  162. *
  163. * An existing default value under the same name in a route will be overridden.
  164. *
  165. * @param array $defaults An array of default values
  166. */
  167. public function addDefaults(array $defaults)
  168. {
  169. if ($defaults) {
  170. foreach ($this->routes as $route) {
  171. $route->addDefaults($defaults);
  172. }
  173. }
  174. }
  175. /**
  176. * Adds requirements to all routes.
  177. *
  178. * An existing requirement under the same name in a route will be overridden.
  179. *
  180. * @param array $requirements An array of requirements
  181. */
  182. public function addRequirements(array $requirements)
  183. {
  184. if ($requirements) {
  185. foreach ($this->routes as $route) {
  186. $route->addRequirements($requirements);
  187. }
  188. }
  189. }
  190. /**
  191. * Adds options to all routes.
  192. *
  193. * An existing option value under the same name in a route will be overridden.
  194. *
  195. * @param array $options An array of options
  196. */
  197. public function addOptions(array $options)
  198. {
  199. if ($options) {
  200. foreach ($this->routes as $route) {
  201. $route->addOptions($options);
  202. }
  203. }
  204. }
  205. /**
  206. * Sets the schemes (e.g. 'https') all child routes are restricted to.
  207. *
  208. * @param string|array $schemes The scheme or an array of schemes
  209. */
  210. public function setSchemes($schemes)
  211. {
  212. foreach ($this->routes as $route) {
  213. $route->setSchemes($schemes);
  214. }
  215. }
  216. /**
  217. * Sets the HTTP methods (e.g. 'POST') all child routes are restricted to.
  218. *
  219. * @param string|array $methods The method or an array of methods
  220. */
  221. public function setMethods($methods)
  222. {
  223. foreach ($this->routes as $route) {
  224. $route->setMethods($methods);
  225. }
  226. }
  227. /**
  228. * Returns an array of resources loaded to build this collection.
  229. *
  230. * @return ResourceInterface[] An array of resources
  231. */
  232. public function getResources()
  233. {
  234. return array_unique($this->resources);
  235. }
  236. /**
  237. * Adds a resource for this collection.
  238. *
  239. * @param ResourceInterface $resource A resource instance
  240. */
  241. public function addResource(ResourceInterface $resource)
  242. {
  243. $this->resources[] = $resource;
  244. }
  245. }