1: <?php
2: /**
3: * This file is part of the Autarky package.
4: *
5: * (c) Andreas Lutro <anlutro@gmail.com>
6: *
7: * For the full copyright and license information, please view the LICENSE
8: * file that was distributed with this source code.
9: */
10:
11: namespace Autarky\Routing;
12:
13: /**
14: * Class that represents a single route in the application.
15: */
16: class Route
17: {
18: /**
19: * @var \Autarky\Routing\Router
20: */
21: protected static $router;
22:
23: /**
24: * @var array
25: */
26: protected $methods;
27:
28: /**
29: * @var string
30: */
31: protected $pattern;
32:
33: /**
34: * @var callable
35: */
36: protected $controller;
37:
38: /**
39: * @var array
40: */
41: protected $options;
42:
43: /**
44: * @var null|string
45: */
46: protected $name;
47:
48: /**
49: * @var array|null
50: */
51: protected $params = null;
52:
53: /**
54: * @param array $methods HTTP methods allowed for this route
55: * @param string $pattern
56: * @param callable $controller
57: * @param string $name
58: * @param array $options
59: */
60: public function __construct(array $methods, $pattern, $controller, $name = null, array $options = [])
61: {
62: $this->methods = array_map('strtoupper', $methods);
63: $this->pattern = $pattern;
64: $this->name = $name;
65: $this->controller = $controller;
66: $this->options = $options;
67: }
68:
69: /**
70: * Get the methods the route responds to.
71: *
72: * @return string[]
73: */
74: public function getMethods()
75: {
76: return $this->methods;
77: }
78:
79: /**
80: * Get the URI pattern the route should match against.
81: *
82: * @return string
83: */
84: public function getPattern()
85: {
86: return $this->pattern;
87: }
88:
89: /**
90: * Get the callable controller for the route.
91: *
92: * @return callable
93: */
94: public function getController()
95: {
96: return $this->controller;
97: }
98:
99: /**
100: * Get the route's name.
101: *
102: * @return string|null
103: */
104: public function getName()
105: {
106: return $this->name;
107: }
108:
109: /**
110: * Get the route options.
111: *
112: * @return array
113: */
114: public function getOptions()
115: {
116: return $this->options;
117: }
118:
119: /**
120: * Get a route option.
121: *
122: * @param $option string
123: *
124: * @return mixed Returns null if option not set.
125: */
126: public function getOption($option)
127: {
128: return isset($this->options[$option]) ? $this->options[$option] : null;
129: }
130:
131: /**
132: * Add a before hook.
133: *
134: * @param string $hook
135: */
136: public function addBeforeHook($hook)
137: {
138: if (!isset($this->options['before'])) {
139: $this->options['before'] = [];
140: }
141: $this->options['before'][] = $hook;
142: }
143:
144: /**
145: * Add an after hook.
146: *
147: * @param string $hook
148: */
149: public function addAfterHook($hook)
150: {
151: if (!isset($this->options['after'])) {
152: $this->options['after'] = [];
153: }
154: $this->options['after'][] = $hook;
155: }
156:
157: /**
158: * Add a before or after hook.
159: *
160: * @param string $when "before" or "after"
161: * @param string $hook
162: */
163: public function addHook($when, $hook)
164: {
165: $this->{'add'.ucfirst($when).'Hook'}($hook);
166: }
167:
168: /**
169: * Get the route's before hooks.
170: *
171: * @return string[]
172: */
173: public function getBeforeHooks()
174: {
175: return isset($this->options['before']) ? $this->options['before'] : [];
176: }
177:
178: /**
179: * Get the route's after hooks.
180: *
181: * @return string[]
182: */
183: public function getAfterHooks()
184: {
185: return isset($this->options['after']) ? $this->options['after'] : [];
186: }
187:
188: /**
189: * When a match against the route has been confirmed, extract the parameters
190: * from the URI and pass them as an associative array to this method.
191: *
192: * @param array $params
193: */
194: public function setParams(array $params)
195: {
196: $this->params = $params;
197: }
198:
199: /**
200: * Get the parameters. Can only be called on a route that has been matched
201: * against an URI (i.e. setParams has been called)
202: *
203: * @return array
204: *
205: * @throws \BadMethodCallException If route has not been matched yet
206: */
207: public function getParams()
208: {
209: if ($this->params === null) {
210: throw new \BadMethodCallException("Cannot get params from a route that has not been matched yet");
211: }
212:
213: return $this->params;
214: }
215:
216: /**
217: * Set the router the route objects use.
218: *
219: * Somewhat of a hack to make var_export caching work.
220: *
221: * @param \Autarky\Routing\RouterInterface $router
222: */
223: public static function setRouter(RouterInterface $router)
224: {
225: static::$router = $router;
226: }
227:
228: /**
229: * Re-build a Route object from data that has been var_export-ed.
230: *
231: * @param array $data
232: *
233: * @return static
234: */
235: public static function __set_state($data)
236: {
237: $route = new static($data['methods'], $data['pattern'],
238: $data['controller'], $data['name'], $data['options']);
239: if (static::$router !== null) {
240: static::$router->addCachedRoute($route);
241: }
242: return $route;
243: }
244: }
245: