Skip to content

Commit 69d1806

Browse files
committed
Legibility improved for AbstractRoute
1 parent 8331062 commit 69d1806

1 file changed

Lines changed: 158 additions & 33 deletions

File tree

library/Respect/Rest/Routes/AbstractRoute.php

Lines changed: 158 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,141 +37,266 @@
3737
*/
3838
abstract class AbstractRoute
3939
{
40+
/** @const string Identifier for catch-all parameters in a route path */
4041
const CATCHALL_IDENTIFIER = '/**';
42+
/** @const string Identifier for normal parameters in a route path */
4143
const PARAM_IDENTIFIER = '/*';
44+
/** @const string Quoted version of the normal parameter identifier */
4245
const QUOTED_PARAM_IDENTIFIER = '/\*';
46+
/** @const string A regular expression that cathes from a / to the end */
4347
const REGEX_CATCHALL = '(/.*)?';
48+
/** @const string A regular expression that cathes one parameter */
4449
const REGEX_SINGLE_PARAM = '/([^/]+)';
50+
/** @const string A regular expression that cathes one ending parameter */
4551
const REGEX_ENDING_PARAM = '#/\(\[\^/\]\+\)#';
52+
/** @const string A regular expression that cathes one optional parameter */
4653
const REGEX_OPTIONAL_PARAM = '(?:/([^/]+))?';
54+
/** @const string A regular expression that identifies invalid parameters */
4755
const REGEX_INVALID_OPTIONAL_PARAM = '#\(\?\:/\(\[\^/\]\+\)\)\?/#';
4856

57+
/** @var string The HTTP method for this route (GET, POST, ANY, etc) */
4958
public $method = '';
59+
/** @var string The minimalistic pattern for route paths for this route */
5060
public $pattern = '';
61+
/** @var string The generated regex for the route pattern */
5162
public $regexForMatch = '';
63+
/** @var string The generated regex for creating URIs from parameters */
5264
public $regexForReplace = '';
65+
/** @var array A list of routines appended to this route */
5366
public $routines = array();
67+
/** @var array A list of side routes to be used */
5468
public $sideRoutes = array();
69+
/** @var array A virtualhost applied to this route (deprecated) */
5570
public $virtualHost = null;
5671

57-
/** Returns the RelfectionFunctionAbstract object for the passed method */
72+
/**
73+
* Returns the RelfectionFunctionAbstract object for the passed method
74+
*
75+
* @param string $method The HTTP method (GET, POST, etc)
76+
*/
5877
abstract public function getReflection($method);
5978

60-
/** Runs the target method/params into this route */
79+
/**
80+
* Runs the target method/params into this route
81+
*
82+
* @param string $method The HTTP method (GET, POST, etc)
83+
* @param array $params A list of params to pass to the target
84+
*/
6185
abstract public function runTarget($method, &$params);
6286

87+
/**
88+
* @param string $method The HTTP method (GET, POST, etc)
89+
* @param string $pattern The pattern for this route path
90+
*/
6391
public function __construct($method, $pattern)
6492
{
6593
$this->pattern = $pattern;
6694
$this->method = strtoupper($method);
95+
6796
list($this->regexForMatch, $this->regexForReplace)
6897
= $this->createRegexPatterns($pattern);
6998
}
7099

100+
/**
101+
* A magic routine builder and composite appender
102+
*
103+
* @param string $method The HTTP method (GET, POST, etc)
104+
* @param array $arguments Arguments to pass to this routine constructor
105+
* @see Respect\Rest\Routes\AbstractRoute::appendRoutine
106+
*
107+
* @return AbstractRoute The route itselt
108+
*/
71109
public function __call($method, $arguments)
72110
{
73-
$routineReflection = new ReflectionClass(
111+
$reflection = new ReflectionClass(
74112
'Respect\\Rest\\Routines\\' . ucfirst($method)
75113
);
76114

77-
return $this->appendRoutine($routineReflection->newInstanceArgs($arguments));
115+
return $this->appendRoutine($reflection->newInstanceArgs($arguments));
78116
}
79117

80-
/** Appends a pre-built routine to this route */
118+
/**
119+
* Appends a pre-built routine to this route
120+
*
121+
* @param Routinable $routine A routine to be appended
122+
* @see Respect\Rest\Routes\AbstractRoute::__call
123+
*
124+
* @return AbstractRoute The route itselt
125+
*/
81126
public function appendRoutine(Routinable $routine)
82127
{
83-
$key = $routine instanceof Unique ? get_class($routine) : spl_object_hash($routine);
128+
$key = $routine instanceof Unique
129+
? get_class($routine)
130+
: spl_object_hash($routine);
131+
84132
$this->routines[$key] = $routine;
85133
return $this;
86134
}
87135

88-
/** Creates an URI for this route with the passed parameters */
136+
/**
137+
* Creates an URI for this route with the passed parameters, replacing
138+
* them in the declared pattern. /hello/* with ['tom'] returns /hello/tom
139+
*
140+
* @param mixed $param1 Some parameter
141+
* @param mixed $etc This route accepts as many parameters you can pass
142+
*
143+
* @return string the created URI
144+
*/
89145
public function createUri($param1=null, $etc=null)
90146
{
91147
$params = func_get_args();
92148
array_unshift($params, $this->regexForReplace);
93-
return rtrim($this->virtualHost, '/') . call_user_func_array(
94-
'sprintf', $params
95-
);
149+
150+
return rtrim($this->virtualHost, '/') .
151+
call_user_func_array('sprintf', $params);
96152
}
97153

154+
/**
155+
* Passes a request through all this routes ProxyableWhen routines
156+
*
157+
* @param Request $request The request you want to process
158+
* @param array $params Parameters for the processed request
159+
* @see Respect\Rest\Routines\ProxyableWhen
160+
*
161+
* @return bool always true \,,/
162+
*/
98163
public function matchRoutines(Request $request, $params=array())
99164
{
100-
foreach ($this->routines as $routine)
101-
if ($routine instanceof ProxyableWhen
102-
&& !$request->routineCall('when', $request->method, $routine, $params))
165+
foreach ($this->routines as $routine) {
166+
if (
167+
$routine instanceof ProxyableWhen
168+
&& !$request->routineCall(
169+
'when',
170+
$request->method,
171+
$routine,
172+
$params)
173+
) {
103174
return false;
175+
}
176+
}
104177

105178
return true;
106179
}
107180

108-
/** Checks if this route matches a request */
181+
/**
182+
* Checks if a request passes for this route
183+
*
184+
* @param Request $request The request you want to process
185+
* @param array $params Parameters for the processed request
186+
*
187+
* @return bool as true as xkcd (always true)
188+
*/
109189
public function match(Request $request, &$params=array())
110190
{
111191
$params = array();
112192
$matchUri = $request->uri;
113193

114-
foreach ($this->routines as $routine)
115-
if ($routine instanceof IgnorableFileExtension)
116-
$matchUri = preg_replace('#(\.[\w\d-_.~\+]+)*$#', '',
117-
$request->uri);
194+
foreach ($this->routines as $routine) {
195+
if ($routine instanceof IgnorableFileExtension) {
196+
$matchUri = preg_replace(
197+
'#(\.[\w\d-_.~\+]+)*$#',
198+
'',
199+
$request->uri
200+
);
201+
}
202+
}
118203

119-
if (!preg_match($this->regexForMatch, $matchUri, $params))
204+
if (!preg_match($this->regexForMatch, $matchUri, $params)) {
120205
return false;
206+
}
121207

122208
array_shift($params);
123209

124-
if (false !== stripos($this->pattern, '/**') && false !== stripos(end($params), '/')) {
210+
if (
211+
false !== stripos($this->pattern, '/**')
212+
&& false !== stripos(end($params), '/')
213+
) {
125214
$lastParam = array_pop($params);
126215
$params[] = explode('/', ltrim($lastParam, '/'));
216+
} elseif (
217+
false !== stripos($this->pattern, '/**') && !isset($params[0])
218+
) {
219+
$params[] = array(); // callback expects a parameter give it
127220
}
128-
elseif (false !== stripos($this->pattern, '/**') && !isset($params[0]))
129-
$params[] = array(); // callback expects a parameter give it
130221

131222
return true;
132223
}
133224

134-
/** Creates the regex from the route patterns */
225+
/**
226+
* This creates a regular expression that matches a route pattern and
227+
* extracts it's parameters
228+
*
229+
* @param string $pattern The pattern for the regex creation
230+
*
231+
* @return array A matcher regex and a replacer regex for createUri()
232+
*/
135233
protected function createRegexPatterns($pattern)
136234
{
137235
$pattern = rtrim($pattern, ' /');
138236
$extra = $this->extractCatchAllPattern($pattern);
139237
$matchPattern = str_replace(
140-
static::QUOTED_PARAM_IDENTIFIER, static::REGEX_SINGLE_PARAM, preg_quote($pattern), $paramCount
238+
static::QUOTED_PARAM_IDENTIFIER,
239+
static::REGEX_SINGLE_PARAM,
240+
preg_quote($pattern),
241+
$paramCount
242+
);
243+
$replacePattern = str_replace(
244+
static::PARAM_IDENTIFIER,
245+
'/%s',
246+
$pattern
141247
);
142-
$replacePattern = str_replace(static::PARAM_IDENTIFIER, '/%s', $pattern);
143248
$matchPattern = $this->fixOptionalParams($matchPattern);
144249
$matchRegex = "#^{$matchPattern}{$extra}$#";
145250
return array($matchRegex, $replacePattern);
146251
}
147252

148-
/** Extracts the catch-all param from a pattern */
253+
/**
254+
* Extracts the catch-all parameter from a pattern and modifies the passed
255+
* parameter to remove that. Yes, we're modifying by reference.
256+
*
257+
* @param string $pattern The pattern for the regex creation
258+
*
259+
* @return string The catch-all parameter or empty string
260+
*/
149261
protected function extractCatchAllPattern(&$pattern)
150262
{
151263
$extra = static::REGEX_CATCHALL;
152264

153-
if ((strlen($pattern) - strlen(static::CATCHALL_IDENTIFIER))
154-
=== strripos($pattern, static::CATCHALL_IDENTIFIER))
265+
if (
266+
(strlen($pattern) - strlen(static::CATCHALL_IDENTIFIER))
267+
=== strripos($pattern, static::CATCHALL_IDENTIFIER)
268+
) {
155269
$pattern = substr($pattern, 0, -3);
156-
else
270+
} else {
157271
$extra = '';
272+
}
158273

159274
$pattern = str_replace(
160-
static::CATCHALL_IDENTIFIER, static::PARAM_IDENTIFIER, $pattern
275+
static::CATCHALL_IDENTIFIER,
276+
static::PARAM_IDENTIFIER,
277+
$pattern
161278
);
162279
return $extra;
163280
}
164281

165-
/** Turn sequenced parameters optional */
282+
/**
283+
* Identifies using regular expressions a sequence of parameters in the end
284+
* of a pattern and make the latest ones optional for the matcher regex
285+
*
286+
* @param string $quotedPattern a preg_quoted route pattern
287+
*/
166288
protected function fixOptionalParams($quotedPattern)
167289
{
168-
if (strlen($quotedPattern) - strlen(static::REGEX_SINGLE_PARAM)
169-
=== strripos($quotedPattern, static::REGEX_SINGLE_PARAM))
290+
if (
291+
strlen($quotedPattern) - strlen(static::REGEX_SINGLE_PARAM)
292+
=== strripos($quotedPattern, static::REGEX_SINGLE_PARAM)
293+
) {
170294
$quotedPattern = preg_replace(
171295
static::REGEX_ENDING_PARAM,
172296
static::REGEX_OPTIONAL_PARAM,
173297
$quotedPattern
174298
);
299+
}
175300

176301
$quotedPattern = preg_replace(
177302
static::REGEX_INVALID_OPTIONAL_PARAM,

0 commit comments

Comments
 (0)