RouteMaker   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 4
Bugs 0 Features 2
Metric Value
wmc 11
c 4
b 0
f 2
lcom 1
cbo 0
dl 0
loc 171
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
B actions() 0 26 3
A resource() 0 7 1
A normalize_options() 0 13 1
A get_resource_actions() 0 14 1
A filter_actions() 0 14 3
A resolve_patterns() 0 12 2
1
<?php
2
3
/*
4
 * This file is part of the ICanBoogie package.
5
 *
6
 * (c) Olivier Laviale <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ICanBoogie\Routing;
13
14
use ICanBoogie\HTTP\Request;
15
16
/**
17
 * Makes route definitions.
18
 */
19
class RouteMaker
20
{
21
	const ACTION_INDEX = 'index';
22
	const ACTION_NEW = 'new';
23
	const ACTION_CREATE = 'create';
24
	const ACTION_SHOW = 'show';
25
	const ACTION_EDIT = 'edit';
26
	const ACTION_UPDATE = 'update';
27
	const ACTION_DELETE = 'delete';
28
29
	const OPTION_ID_NAME = 'id_name';
30
	const OPTION_ID_REGEX = 'id_regex';
31
	const OPTION_ONLY = 'only';
32
	const OPTION_EXCEPT = 'except';
33
	const OPTION_AS = 'as';
34
	const OPTION_ACTIONS = 'actions';
35
36
	const SEPARATOR = ':';
37
	const CONTROLLER_ACTION_SEPARATOR = '#';
38
39
	/**
40
	 * @param string $name
41
	 * @param string $controller
42
	 * @param array $actions Action templates.
43
	 * @param array $options The following options are available:
44
	 *
45
	 * - `only`: Only the routes specified are made.
46
	 * - `except`: The routes specified are excluded.
47
	 * - `id_name`: Name of the identifier property. Defaults to `id`.
48
	 * - `id_regex`: Regex of the identifier value. Defaults to `\d+`.
49
	 * - `as`: Specifies the `as` option of the routes created.
50
	 *
51
	 * @return array
52
	 */
53
	static public function actions($name, $controller, $actions, array $options = [])
54
	{
55
		$options = self::normalize_options($options);
56
		$actions = static::filter_actions($actions, $options);
57
		$actions = static::resolve_patterns($name, $actions, $options);
58
59
		$options_as = $options[self::OPTION_AS];
60
		$routes = [];
61
62
		foreach ($actions as $action => list($pattern, $via))
63
		{
64
			$as = empty($options_as[$action]) ? $name . self::SEPARATOR . $action : $options_as[$action];
65
66
			$routes[$as] = [
67
68
				RouteDefinition::PATTERN => $pattern,
69
				RouteDefinition::CONTROLLER => $controller,
70
				RouteDefinition::ACTION => $action,
71
				RouteDefinition::VIA => $via,
72
				RouteDefinition::ID => $as
73
74
			];
75
		}
76
77
		return $routes;
78
	}
79
80
	/**
81
	 * Makes route definitions for a resource.
82
	 *
83
	 * @param string $name
84
	 * @param string $controller
85
	 * @param array $options The following options are available:
86
	 *
87
	 * - `only`: Only the routes specified are made.
88
	 * - `except`: The routes specified are excluded.
89
	 * - `id_name`: Name of the identifier property. Defaults to `id`.
90
	 * - `id_regex`: Regex of the identifier value. Defaults to `\d+`.
91
	 * - `as`: Specifies the `as` option of the routes created.
92
	 * - `actions`: Additional actions templates.
93
	 *
94
	 * @return array
95
	 */
96
	static public function resource($name, $controller, array $options = [])
97
	{
98
		$options = static::normalize_options($options);
99
		$actions = array_merge(static::get_resource_actions(), $options[self::OPTION_ACTIONS]);
100
101
		return static::actions($name, $controller, $actions, $options);
102
	}
103
104
	/**
105
	 * Normalizes options.
106
	 *
107
	 * @param array $options
108
	 *
109
	 * @return array
110
	 */
111
	static protected function normalize_options(array $options)
112
	{
113
		return $options + [
114
115
			self::OPTION_ID_NAME => 'id',
116
			self::OPTION_ID_REGEX => '\d+',
117
			self::OPTION_ONLY => [ ],
118
			self::OPTION_EXCEPT => [ ],
119
			self::OPTION_AS => [ ],
120
			self::OPTION_ACTIONS => [ ]
121
122
		];
123
	}
124
125
	/**
126
	 * Returns default resource actions.
127
	 *
128
	 * @return array
129
	 */
130
	static protected function get_resource_actions()
131
	{
132
		return [
133
134
			self::ACTION_INDEX  => [ '/{name}',           Request::METHOD_GET ],
135
			self::ACTION_NEW    => [ '/{name}/new',       Request::METHOD_GET ],
136
			self::ACTION_CREATE => [ '/{name}',           Request::METHOD_POST ],
137
			self::ACTION_SHOW   => [ '/{name}/{id}',      Request::METHOD_GET ],
138
			self::ACTION_EDIT   => [ '/{name}/{id}/edit', Request::METHOD_GET ],
139
			self::ACTION_UPDATE => [ '/{name}/{id}',      [ Request::METHOD_PUT, Request::METHOD_PATCH ] ],
140
			self::ACTION_DELETE => [ '/{name}/{id}',      Request::METHOD_DELETE ]
141
142
		];
143
	}
144
145
	/**
146
	 * Filters actions according to only/except options.
147
	 *
148
	 * @param array $actions
149
	 * @param array $options
150
	 *
151
	 * @return array
152
	 */
153
	static protected function filter_actions(array $actions, array $options = [])
154
	{
155
		if ($options[self::OPTION_ONLY])
156
		{
157
			$actions = array_intersect_key($actions, array_flip((array) $options[self::OPTION_ONLY]));
158
		}
159
160
		if ($options[self::OPTION_EXCEPT])
161
		{
162
			$actions = array_diff_key($actions, array_flip((array) $options[self::OPTION_EXCEPT]));
163
		}
164
165
		return $actions;
166
	}
167
168
	/**
169
	 * Replaces pattern placeholders.
170
	 *
171
	 * @param string $name
172
	 * @param array $actions
173
	 * @param array $options
174
	 *
175
	 * @return array
176
	 */
177
	static protected function resolve_patterns($name, array $actions, $options)
178
	{
179
		$id = "<{$options[self::OPTION_ID_NAME]}:{$options[self::OPTION_ID_REGEX]}>";
180
		$replace = [ '{name}' => $name, '{id}' => $id ];
181
182
		foreach ($actions as $action => &$template)
183
		{
184
			$template[0] = strtr($template[0], $replace);
185
		}
186
187
		return $actions;
188
	}
189
}
190