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