118 lines
3.6 KiB
PHP
118 lines
3.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* pjdietz\WellRESTed\TemplateRoute
|
|
*
|
|
* @author PJ Dietz <pj@pjdietz.com>
|
|
* @copyright Copyright 2014 by PJ Dietz
|
|
* @license MIT
|
|
*/
|
|
|
|
namespace pjdietz\WellRESTed\Routes;
|
|
|
|
/**
|
|
* Maps a URI template to a Handler
|
|
*/
|
|
class TemplateRoute extends RegexRoute
|
|
{
|
|
/**
|
|
* Regular expression matching URL friendly characters (i.e., letters,
|
|
* digits, hyphen and underscore)
|
|
*/
|
|
const RE_SLUG = '[0-9a-zA-Z\-_]+';
|
|
/** Regular expression matching digitis */
|
|
const RE_NUM = '[0-9]+';
|
|
/** Regular expression matching letters */
|
|
const RE_ALPHA = '[a-zA-Z]+';
|
|
/** Regular expression matching letters and digits */
|
|
const RE_ALPHANUM = '[0-9a-zA-Z]+';
|
|
/** Regular expression matching a URI template variable (e.g., {id}) */
|
|
const URI_TEMPLATE_EXPRESSION_RE = '/{([a-zA-Z]+)}/';
|
|
|
|
/**
|
|
* Create a new route that matches a URI template to a Handler.
|
|
*
|
|
* Optionally provide patterns for the variables in the template.
|
|
*
|
|
* @param string $template URI template the path must match
|
|
* @param string $targetClassName Fully qualified name to an autoloadable handler class
|
|
* @param string $defaultPattern Regular expression for variables
|
|
* @param array|null $variablePatterns Map of variable names and regular expression
|
|
*/
|
|
public function __construct(
|
|
$template,
|
|
$targetClassName,
|
|
$defaultPattern = self::RE_SLUG,
|
|
$variablePatterns = null
|
|
) {
|
|
$pattern = $this->buildPattern($template, $defaultPattern, $variablePatterns);
|
|
parent::__construct($pattern, $targetClassName);
|
|
}
|
|
|
|
/**
|
|
* Translate the URI template into a regular expression.
|
|
*
|
|
* @param string $template URI template the path must match
|
|
* @param string $defaultPattern Regular expression for variables
|
|
* @param array $variablePatterns Map of variable names and regular expression
|
|
* @return string
|
|
*/
|
|
private function buildPattern($template, $defaultPattern, $variablePatterns)
|
|
{
|
|
if (is_null($variablePatterns)) {
|
|
$variablePatterns = array();
|
|
} elseif (is_object($variablePatterns)) {
|
|
$variablePatterns = (array) $variablePatterns;
|
|
}
|
|
|
|
if (!$defaultPattern) {
|
|
$defaultPattern = self::RE_SLUG;
|
|
}
|
|
|
|
$pattern = '';
|
|
|
|
// Explode the template into an array of path segments.
|
|
if ($template[0] === '/') {
|
|
$parts = explode('/', substr($template, 1));
|
|
} else {
|
|
$parts = explode('/', $template);
|
|
}
|
|
|
|
foreach ($parts as $part) {
|
|
|
|
$pattern .= '\/';
|
|
|
|
// Is this part an expression or a literal?
|
|
if (preg_match(self::URI_TEMPLATE_EXPRESSION_RE, $part, $matches)) {
|
|
|
|
// Locate the name for the variable from the template.
|
|
$variableName = $matches[1];
|
|
|
|
// If the caller passed an array with this variable name
|
|
// as a key, use its value for the pattern here.
|
|
// Otherwise, use the class's current default.
|
|
if (isset($variablePatterns[$variableName])) {
|
|
$variablePattern = $variablePatterns[$variableName];
|
|
} else {
|
|
$variablePattern = $defaultPattern;
|
|
}
|
|
|
|
$pattern .= sprintf(
|
|
'(?<%s>%s)',
|
|
$variableName,
|
|
$variablePattern
|
|
);
|
|
|
|
} else {
|
|
// This part is a literal.
|
|
$pattern .= $part;
|
|
}
|
|
|
|
}
|
|
|
|
$pattern = '/^' . $pattern . '$/';
|
|
return $pattern;
|
|
}
|
|
|
|
}
|