'(?:[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 (? [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; } }