1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (https://nette.org)
5: * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6: */
7:
8: namespace Nette\Application\Routers;
9:
10: use Nette;
11:
12:
13: /**
14: * The router broker.
15: */
16: class RouteList extends Nette\Utils\ArrayList implements Nette\Application\IRouter
17: {
18: /** @var array */
19: private $cachedRoutes;
20:
21: /** @var string */
22: private $module;
23:
24:
25: public function __construct($module = NULL)
26: {
27: $this->module = $module ? $module . ':' : '';
28: }
29:
30:
31: /**
32: * Maps HTTP request to a Request object.
33: * @return Nette\Application\Request|NULL
34: */
35: public function match(Nette\Http\IRequest $httpRequest)
36: {
37: foreach ($this as $route) {
38: $appRequest = $route->match($httpRequest);
39: if ($appRequest !== NULL) {
40: $name = $appRequest->getPresenterName();
41: if (strncmp($name, 'Nette:', 6)) {
42: $appRequest->setPresenterName($this->module . $name);
43: }
44: return $appRequest;
45: }
46: }
47: return NULL;
48: }
49:
50:
51: /**
52: * Constructs absolute URL from Request object.
53: * @return string|NULL
54: */
55: public function constructUrl(Nette\Application\Request $appRequest, Nette\Http\Url $refUrl)
56: {
57: if ($this->cachedRoutes === NULL) {
58: $this->warmupCache();
59: }
60:
61: if ($this->module) {
62: if (strncmp($tmp = $appRequest->getPresenterName(), $this->module, strlen($this->module)) === 0) {
63: $appRequest = clone $appRequest;
64: $appRequest->setPresenterName(substr($tmp, strlen($this->module)));
65: } else {
66: return NULL;
67: }
68: }
69:
70: $presenter = $appRequest->getPresenterName();
71: if (!isset($this->cachedRoutes[$presenter])) {
72: $presenter = '*';
73: }
74:
75: foreach ($this->cachedRoutes[$presenter] as $route) {
76: $url = $route->constructUrl($appRequest, $refUrl);
77: if ($url !== NULL) {
78: return $url;
79: }
80: }
81:
82: return NULL;
83: }
84:
85:
86: /** @internal */
87: public function warmupCache()
88: {
89: $routes = array();
90: $routes['*'] = array();
91:
92: foreach ($this as $route) {
93: $presenters = $route instanceof Route && is_array($tmp = $route->getTargetPresenters())
94: ? $tmp
95: : array_keys($routes);
96:
97: foreach ($presenters as $presenter) {
98: if (!isset($routes[$presenter])) {
99: $routes[$presenter] = $routes['*'];
100: }
101: $routes[$presenter][] = $route;
102: }
103: }
104:
105: $this->cachedRoutes = $routes;
106: }
107:
108:
109: /**
110: * Adds the router.
111: * @param mixed
112: * @param Nette\Application\IRouter
113: * @return void
114: */
115: public function offsetSet($index, $route)
116: {
117: if (!$route instanceof Nette\Application\IRouter) {
118: throw new Nette\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: