Add RouteBuilder class for parsing route configurations
This commit is contained in:
parent
12b971dfe6
commit
3718e03c78
|
|
@ -0,0 +1,163 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace pjdietz\WellRESTed;
|
||||||
|
|
||||||
|
use pjdietz\WellRESTed\Interfaces\DispatcherInterface;
|
||||||
|
use pjdietz\WellRESTed\Routes\RegexRoute;
|
||||||
|
use pjdietz\WellRESTed\Routes\StaticRoute;
|
||||||
|
use pjdietz\WellRESTed\Routes\TemplateRoute;
|
||||||
|
use stdClass;
|
||||||
|
use UnexpectedValueException;
|
||||||
|
|
||||||
|
class RouteBuilder
|
||||||
|
{
|
||||||
|
private $handlerNamespace;
|
||||||
|
private $templateVariablePatterns;
|
||||||
|
private $defaultVariablePattern;
|
||||||
|
|
||||||
|
public function getRoutes($data)
|
||||||
|
{
|
||||||
|
// Locate the list of routes. This should be one of these:
|
||||||
|
// - If $data is an object, $data->routes
|
||||||
|
// - If $data is an array, $data
|
||||||
|
if (is_array($data)) {
|
||||||
|
$dataRoutes = $data;
|
||||||
|
} elseif (is_object($data) && isset($data->routes) && is_array($data->routes)) {
|
||||||
|
$dataRoutes = $data->routes;
|
||||||
|
$this->readConfiguration($data);
|
||||||
|
} else {
|
||||||
|
throw new UnexpectedValueException("Unable to parse. Missing array of routes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a route instance and append it to the list.
|
||||||
|
$routes = array();
|
||||||
|
foreach ($dataRoutes as $item) {
|
||||||
|
$routes[] = $this->buildRoute($item);
|
||||||
|
}
|
||||||
|
return $routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param stdClass|array $item
|
||||||
|
* @return DispatcherInterface
|
||||||
|
* @throws \UnexpectedValueException Parse error
|
||||||
|
*/
|
||||||
|
protected function buildRoute($item)
|
||||||
|
{
|
||||||
|
// Determine the handler for this route.
|
||||||
|
if (isset($item->handler)) {
|
||||||
|
$handler = $item->handler;
|
||||||
|
if ($handler[0] != "\\") {
|
||||||
|
$handler = $this->getHandlerNamespace() . "\\" . $handler;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new UnexpectedValueException("Unable to parse. Route is missing a handler.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static Route
|
||||||
|
if (isset($item->path)) {
|
||||||
|
return new StaticRoute($item->path, $handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Template Route
|
||||||
|
if (isset($item->template)) {
|
||||||
|
$vars = isset($item->vars) ? (array) $item->vars : array();
|
||||||
|
foreach ($vars as $name => $var) {
|
||||||
|
$vars[$name] = $this->getTemplateVariablePattern($var);
|
||||||
|
}
|
||||||
|
if ($this->templateVariablePatterns) {
|
||||||
|
$vars = array_merge($this->templateVariablePatterns, $vars);
|
||||||
|
}
|
||||||
|
return new TemplateRoute($item->template, $handler, $this->getDefaultVariablePattern(), $vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regex Rout
|
||||||
|
if (isset($item->pattern)) {
|
||||||
|
return new RegexRoute($item->pattern, $handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function readConfiguration($data)
|
||||||
|
{
|
||||||
|
if (isset($data->handlerNamespace)) {
|
||||||
|
$this->setHandlerNamespace($data->handlerNamespace);
|
||||||
|
}
|
||||||
|
if (isset($data->variablePattern)) {
|
||||||
|
$this->setDefaultVariablePattern($data->variablePattern);
|
||||||
|
}
|
||||||
|
if (isset($data->vars)) {
|
||||||
|
$this->setTemplateVars((array) $data->vars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTemplateVariablePattern($variable) {
|
||||||
|
switch ($variable) {
|
||||||
|
case "SLUG":
|
||||||
|
return TemplateRoute::RE_SLUG;
|
||||||
|
case "ALPHA":
|
||||||
|
return TemplateRoute::RE_ALPHA;
|
||||||
|
case "ALPHANUM":
|
||||||
|
return TemplateRoute::RE_ALPHANUM;
|
||||||
|
case "DIGIT":
|
||||||
|
case "NUM":
|
||||||
|
return TemplateRoute::RE_NUM;
|
||||||
|
default:
|
||||||
|
return $variable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $handlerNamespace
|
||||||
|
*/
|
||||||
|
public function setHandlerNamespace($handlerNamespace)
|
||||||
|
{
|
||||||
|
$this->handlerNamespace = $handlerNamespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getHandlerNamespace()
|
||||||
|
{
|
||||||
|
return $this->handlerNamespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $vars
|
||||||
|
* @internal param mixed $templateVars
|
||||||
|
*/
|
||||||
|
public function setTemplateVars(array $vars)
|
||||||
|
{
|
||||||
|
foreach ($vars as $name => $var) {
|
||||||
|
$vars[$name] = $this->getTemplateVariablePattern($var);
|
||||||
|
}
|
||||||
|
$this->templateVariablePatterns = $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getTemplateVars()
|
||||||
|
{
|
||||||
|
return $this->templateVariablePatterns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $defaultVariablePattern
|
||||||
|
*/
|
||||||
|
public function setDefaultVariablePattern($defaultVariablePattern)
|
||||||
|
{
|
||||||
|
$this->defaultVariablePattern = $this->getTemplateVariablePattern($defaultVariablePattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getDefaultVariablePattern()
|
||||||
|
{
|
||||||
|
return $this->defaultVariablePattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -20,28 +20,32 @@ class TemplateRoute extends RegexRoute
|
||||||
/** Regular expression matching a URI template variable (e.g., {id}) */
|
/** Regular expression matching a URI template variable (e.g., {id}) */
|
||||||
const URI_TEMPLATE_EXPRESSION_RE = '/{([a-zA-Z]+)}/';
|
const URI_TEMPLATE_EXPRESSION_RE = '/{([a-zA-Z]+)}/';
|
||||||
|
|
||||||
/**
|
|
||||||
* Default regular expression used to match template variable
|
|
||||||
*
|
|
||||||
* @property string
|
|
||||||
*/
|
|
||||||
static public $defaultVariablePattern = self::RE_SLUG;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $template URI template the path must match
|
* @param string $template URI template the path must match
|
||||||
* @param string $targetClassName Fully qualified name to an autoloadable handler class.
|
* @param string $targetClassName Fully qualified name to an autoloadable handler class
|
||||||
* @param array|null $variables Associative array of variables from the template and regular expressions.
|
* @param string $defaultPattern Regular expression for variables
|
||||||
|
* @param array|null $variablePatterns Map of variable names and regular expression
|
||||||
*/
|
*/
|
||||||
public function __construct($template, $targetClassName, $variables = null)
|
public function __construct(
|
||||||
{
|
$template,
|
||||||
$pattern = $this->buildPattern($template, $variables);
|
$targetClassName,
|
||||||
|
$defaultPattern = self::RE_SLUG,
|
||||||
|
$variablePatterns = null
|
||||||
|
) {
|
||||||
|
$pattern = $this->buildPattern($template, $defaultPattern, $variablePatterns);
|
||||||
parent::__construct($pattern, $targetClassName);
|
parent::__construct($pattern, $targetClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildPattern($template, $variables)
|
private function buildPattern($template, $defaultPattern, $variablePatterns)
|
||||||
{
|
{
|
||||||
if (is_null($variables)) {
|
if (is_null($variablePatterns)) {
|
||||||
$variables = array();
|
$variablePatterns = array();
|
||||||
|
} elseif (is_object($variablePatterns)) {
|
||||||
|
$variablePatterns = (array) $variablePatterns;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$defaultPattern) {
|
||||||
|
$defaultPattern = self::RE_SLUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pattern = '';
|
$pattern = '';
|
||||||
|
|
@ -70,10 +74,10 @@ class TemplateRoute extends RegexRoute
|
||||||
// If the caller passed an array with this variable name
|
// If the caller passed an array with this variable name
|
||||||
// as a key, use its value for the pattern here.
|
// as a key, use its value for the pattern here.
|
||||||
// Otherwise, use the class's current default.
|
// Otherwise, use the class's current default.
|
||||||
if (isset($variables[$variableName])) {
|
if (isset($variablePatterns[$variableName])) {
|
||||||
$variablePattern = $variables[$variableName];
|
$variablePattern = $variablePatterns[$variableName];
|
||||||
} else {
|
} else {
|
||||||
$variablePattern = self::$defaultVariablePattern;
|
$variablePattern = $defaultPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pattern .= sprintf(
|
$pattern .= sprintf(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue