1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (http://nette.org)
5: *
6: * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
7: *
8: * For the full copyright and license information, please view
9: * the file license.txt that was distributed with this source code.
10: */
11:
12: namespace Nette\Application\Routers;
13:
14: use Nette;
15:
16:
17:
18: /**
19: * The router broker.
20: *
21: * @author David Grudl
22: * @property-read string $module
23: */
24: class RouteList extends Nette\ArrayList implements Nette\Application\IRouter
25: {
26: /** @var array */
27: private $cachedRoutes;
28:
29: /** @var string */
30: private $module;
31:
32:
33:
34: public function __construct($module = NULL)
35: {
36: $this->module = $module ? $module . ':' : '';
37: }
38:
39:
40:
41: /**
42: * Maps HTTP request to a Request object.
43: * @return Nette\Application\Request|NULL
44: */
45: public function match(Nette\Http\IRequest $httpRequest)
46: {
47: foreach ($this as $route) {
48: $appRequest = $route->match($httpRequest);
49: if ($appRequest !== NULL) {
50: $appRequest->setPresenterName($this->module . $appRequest->getPresenterName());
51: return $appRequest;
52: }
53: }
54: return NULL;
55: }
56:
57:
58:
59: /**
60: * Constructs absolute URL from Request object.
61: * @return string|NULL
62: */
63: public function constructUrl(Nette\Application\Request $appRequest, Nette\Http\Url $refUrl)
64: {
65: if ($this->cachedRoutes === NULL) {
66: $routes = array();
67: $routes['*'] = array();
68:
69: foreach ($this as $route) {
70: $presenter = $route instanceof Route ? $route->getTargetPresenter() : NULL;
71:
72: if ($presenter === FALSE) {
73: continue;
74: }
75:
76: if (is_string($presenter)) {
77: $presenter = strtolower($presenter);
78: if (!isset($routes[$presenter])) {
79: $routes[$presenter] = $routes['*'];
80: }
81: $routes[$presenter][] = $route;
82:
83: } else {
84: foreach ($routes as $id => $foo) {
85: $routes[$id][] = $route;
86: }
87: }
88: }
89:
90: $this->cachedRoutes = $routes;
91: }
92:
93: if ($this->module) {
94: if (strncasecmp($tmp = $appRequest->getPresenterName(), $this->module, strlen($this->module)) === 0) {
95: $appRequest = clone $appRequest;
96: $appRequest->setPresenterName(substr($tmp, strlen($this->module)));
97: } else {
98: return NULL;
99: }
100: }
101:
102: $presenter = strtolower($appRequest->getPresenterName());
103: if (!isset($this->cachedRoutes[$presenter])) {
104: $presenter = '*';
105: }
106:
107: foreach ($this->cachedRoutes[$presenter] as $route) {
108: $url = $route->constructUrl($appRequest, $refUrl);
109: if ($url !== NULL) {
110: return $url;
111: }
112: }
113:
114: return NULL;
115: }
116:
117:
118:
119: /**
120: * Adds the router.
121: * @param mixed
122: * @param Nette\Application\IRouter
123: * @return void
124: */
125: public function offsetSet($index, $route)
126: {
127: if (!$route instanceof Nette\Application\IRouter) {
128: throw new Nette\InvalidArgumentException("Argument must be IRouter descendant.");
129: }
130: parent::offsetSet($index, $route);
131: }
132:
133:
134:
135: /**
136: * @return string
137: */
138: public function getModule()
139: {
140: return $this->module;
141: }
142:
143: }
144: