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: * The router broker.
19: *
20: * @author David Grudl
21: * @property-read string $module
22: */
23: class RouteList extends Nette\ArrayList implements Nette\Application\IRouter
24: {
25: /** @var array */
26: private $cachedRoutes;
27:
28: /** @var string */
29: private $module;
30:
31:
32: public function __construct($module = NULL)
33: {
34: $this->module = $module ? $module . ':' : '';
35: }
36:
37:
38: /**
39: * Maps HTTP request to a Request object.
40: * @return Nette\Application\Request|NULL
41: */
42: public function match(Nette\Http\IRequest $httpRequest)
43: {
44: foreach ($this as $route) {
45: $appRequest = $route->match($httpRequest);
46: if ($appRequest !== NULL) {
47: $appRequest->setPresenterName($this->module . $appRequest->getPresenterName());
48: return $appRequest;
49: }
50: }
51: return NULL;
52: }
53:
54:
55: /**
56: * Constructs absolute URL from Request object.
57: * @return string|NULL
58: */
59: public function constructUrl(Nette\Application\Request $appRequest, Nette\Http\Url $refUrl)
60: {
61: if ($this->cachedRoutes === NULL) {
62: $routes = array();
63: $routes['*'] = array();
64:
65: foreach ($this as $route) {
66: $presenter = $route instanceof Route ? $route->getTargetPresenter() : NULL;
67:
68: if ($presenter === FALSE) {
69: continue;
70: }
71:
72: if (is_string($presenter)) {
73: $presenter = strtolower($presenter);
74: if (!isset($routes[$presenter])) {
75: $routes[$presenter] = $routes['*'];
76: }
77: $routes[$presenter][] = $route;
78:
79: } else {
80: foreach ($routes as $id => $foo) {
81: $routes[$id][] = $route;
82: }
83: }
84: }
85:
86: $this->cachedRoutes = $routes;
87: }
88:
89: if ($this->module) {
90: if (strncasecmp($tmp = $appRequest->getPresenterName(), $this->module, strlen($this->module)) === 0) {
91: $appRequest = clone $appRequest;
92: $appRequest->setPresenterName(substr($tmp, strlen($this->module)));
93: } else {
94: return NULL;
95: }
96: }
97:
98: $presenter = strtolower($appRequest->getPresenterName());
99: if (!isset($this->cachedRoutes[$presenter])) {
100: $presenter = '*';
101: }
102:
103: foreach ($this->cachedRoutes[$presenter] as $route) {
104: $url = $route->constructUrl($appRequest, $refUrl);
105: if ($url !== NULL) {
106: return $url;
107: }
108: }
109:
110: return NULL;
111: }
112:
113:
114: /**
115: * Adds the router.
116: * @param mixed
117: * @param Nette\Application\IRouter
118: * @return void
119: */
120: public function offsetSet($index, $route)
121: {
122: if (!$route instanceof Nette\Application\IRouter) {
123: throw new Nette\InvalidArgumentException("Argument must be IRouter descendant.");
124: }
125: parent::offsetSet($index, $route);
126: }
127:
128:
129: /**
130: * @return string
131: */
132: public function getModule()
133: {
134: return $this->module;
135: }
136:
137: }
138: