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