A modest collection of PHP libraries used at SparkFun.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

135 lines
3.9 KiB

<?php
namespace SparkLib\Application;
class RouteMap {
/**
* Sub-patterns for matching given components of a route. The patterns
* will be placed inside named capture groups corresponding to the keys
* here, and separated by slashes. See makePattern().
*/
public $patterns = [
// Controller names may contain underscores, but must begin and end with
// a character in [a-z]. Single-character controller names are allowed.
// (Alternation happens inside of a non-capturing group, because captured
// groups are treated as components of the route.)
'controller' => '(?:[a-z][a-z_]*[a-z]|[a-z])',
// Same pattern as controller. Note that because actions are methods,
// we need to require them to start with a-z lest we accidentally expose
// __construct() and friends.
'action' => '(?:[a-z][a-z_]*[a-z]|[a-z])',
'shortlink' => '[enptwr][0-9]+',
'id' => '[0-9]+',
'bson' => '[0-9a-z]{24}',
'default' => '',
];
/**
* Define routing for requests by method. Currently:
*
* GET /orders/123/foo -> $controller->foo() - call action foo() for order 123
* GET /orders/make -> $controller->make() - get a new blank order
* GET /orders/123 -> $controller->view() - look at one order
* GET /orders -> $controller->index() - look at the index/list of orders
*
* HEAD Identical to GET
*
* POST /orders/123 -> $controller->view() - change order 123
* POST /orders -> $controller->create() - create a new blank order (using a form returned by make())
*
* DELETE /orders/123 -> delete order 123
*
* It is not safe to touch this unless you know _EXACTLY_ what you are doing.
*/
public $defaultRoutes = [
'GET' => [
'id/action' => null,
'bson/action' => null,
'action' => null,
'id' => 'view',
'default' => 'index',
],
// These should be identical to GET
'HEAD' => [
'id/action' => null,
'bson/action' => null,
'action' => null,
'id' => 'view',
'default' => 'index',
],
'POST' => [
'id/action' => null,
'bson/action' => null,
'action' => null,
'id' => 'update',
'default' => 'create',
],
'DELETE' => [
'id' => 'delete',
'bson' => 'delete',
],
];
// Override this to set up custom routes.
public $routes = [];
/**
* Generate a regexp corresponding to a route string.
* (Plus optionally a type extension.)
*
* @return string regular expression
*/
public function makePattern ($route)
{
$pattern_parts = [];
$route = 'controller/' . $route;
foreach (explode('/', $route) as $route_part) {
$part_pattern = $this->patterns[$route_part];
if ($part_pattern)
$pattern_parts[] = '(?<' . $route_part . '>' . $this->patterns[$route_part] . ')';
}
$pts = implode('/', $pattern_parts);
return '{^/ # open slash
' . $pts . ' # main components of route
/? # optional trailing slash
(?: # optional group for extension
[.] # dot - not captured
(?<type>
[a-z]+ # actual extension (xml, json, etc.)
)
)?
$}x';
}
/**
* Get a route array that takes any custom routes into account,
* ordered correctly. Custom routes will take priority over all default
* routes.
*/
public function buildRoutes ($method)
{
$default = isset($this->defaultRoutes[$method]) ? $this->defaultRoutes[$method] : array();
$custom = isset($this->routes[$method]) ? $this->routes[$method] : array();
$merged = $custom;
foreach ($default as $route => $action) {
if (! isset($merged[$route]))
$merged[$route] = $action;
}
return $merged;
}
}