1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Application;
13:
14: use Nette;
15:
16:
17:
18: 19: 20: 21: 22:
23: class MultiRouter extends Nette\ArrayList implements IRouter
24: {
25:
26: private $cachedRoutes;
27:
28:
29: private $module;
30:
31:
32:
33: public function __construct($module = NULL)
34: {
35: $this->module = $module ? $module . ':' : '';
36: }
37:
38:
39:
40: 41: 42: 43: 44:
45: public function match(Nette\Web\IHttpRequest $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: 61: 62: 63: 64:
65: public function constructUrl(PresenterRequest $appRequest, Nette\Web\Uri $refUri)
66: {
67: if ($this->cachedRoutes === NULL) {
68: $routes = array();
69: $routes['*'] = array();
70:
71: foreach ($this as $route) {
72: $presenter = $route instanceof Route ? $route->getTargetPresenter() : NULL;
73:
74: if ($presenter === FALSE) continue;
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])) $presenter = '*';
104:
105: foreach ($this->cachedRoutes[$presenter] as $route) {
106: $uri = $route->constructUrl($appRequest, $refUri);
107: if ($uri !== NULL) {
108: return $uri;
109: }
110: }
111:
112: return NULL;
113: }
114:
115:
116:
117: 118: 119: 120: 121: 122:
123: public function offsetSet($index, $route)
124: {
125: if (!$route instanceof IRouter) {
126: throw new \InvalidArgumentException("Argument must be IRouter descendant.");
127: }
128: parent::offsetSet($index, $route);
129: }
130:
131: }
132: