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

  1. <?php
  2. namespace SparkLib\Application;
  3. class RouteMap {
  4. /**
  5. * Sub-patterns for matching given components of a route. The patterns
  6. * will be placed inside named capture groups corresponding to the keys
  7. * here, and separated by slashes. See makePattern().
  8. */
  9. public $patterns = [
  10. // Controller names may contain underscores, but must begin and end with
  11. // a character in [a-z]. Single-character controller names are allowed.
  12. // (Alternation happens inside of a non-capturing group, because captured
  13. // groups are treated as components of the route.)
  14. 'controller' => '(?:[a-z][a-z_]*[a-z]|[a-z])',
  15. // Same pattern as controller. Note that because actions are methods,
  16. // we need to require them to start with a-z lest we accidentally expose
  17. // __construct() and friends.
  18. 'action' => '(?:[a-z][a-z_]*[a-z]|[a-z])',
  19. 'shortlink' => '[enptwr][0-9]+',
  20. 'id' => '[0-9]+',
  21. 'bson' => '[0-9a-z]{24}',
  22. 'default' => '',
  23. ];
  24. /**
  25. * Define routing for requests by method. Currently:
  26. *
  27. * GET /orders/123/foo -> $controller->foo() - call action foo() for order 123
  28. * GET /orders/make -> $controller->make() - get a new blank order
  29. * GET /orders/123 -> $controller->view() - look at one order
  30. * GET /orders -> $controller->index() - look at the index/list of orders
  31. *
  32. * HEAD Identical to GET
  33. *
  34. * POST /orders/123 -> $controller->view() - change order 123
  35. * POST /orders -> $controller->create() - create a new blank order (using a form returned by make())
  36. *
  37. * DELETE /orders/123 -> delete order 123
  38. *
  39. * It is not safe to touch this unless you know _EXACTLY_ what you are doing.
  40. */
  41. public $defaultRoutes = [
  42. 'GET' => [
  43. 'id/action' => null,
  44. 'bson/action' => null,
  45. 'action' => null,
  46. 'id' => 'view',
  47. 'default' => 'index',
  48. ],
  49. // These should be identical to GET
  50. 'HEAD' => [
  51. 'id/action' => null,
  52. 'bson/action' => null,
  53. 'action' => null,
  54. 'id' => 'view',
  55. 'default' => 'index',
  56. ],
  57. 'POST' => [
  58. 'id/action' => null,
  59. 'bson/action' => null,
  60. 'action' => null,
  61. 'id' => 'update',
  62. 'default' => 'create',
  63. ],
  64. 'DELETE' => [
  65. 'id' => 'delete',
  66. 'bson' => 'delete',
  67. ],
  68. ];
  69. // Override this to set up custom routes.
  70. public $routes = [];
  71. /**
  72. * Generate a regexp corresponding to a route string.
  73. * (Plus optionally a type extension.)
  74. *
  75. * @return string regular expression
  76. */
  77. public function makePattern ($route)
  78. {
  79. $pattern_parts = [];
  80. $route = 'controller/' . $route;
  81. foreach (explode('/', $route) as $route_part) {
  82. $part_pattern = $this->patterns[$route_part];
  83. if ($part_pattern)
  84. $pattern_parts[] = '(?<' . $route_part . '>' . $this->patterns[$route_part] . ')';
  85. }
  86. $pts = implode('/', $pattern_parts);
  87. return '{^/ # open slash
  88. ' . $pts . ' # main components of route
  89. /? # optional trailing slash
  90. (?: # optional group for extension
  91. [.] # dot - not captured
  92. (?<type>
  93. [a-z]+ # actual extension (xml, json, etc.)
  94. )
  95. )?
  96. $}x';
  97. }
  98. /**
  99. * Get a route array that takes any custom routes into account,
  100. * ordered correctly. Custom routes will take priority over all default
  101. * routes.
  102. */
  103. public function buildRoutes ($method)
  104. {
  105. $default = isset($this->defaultRoutes[$method]) ? $this->defaultRoutes[$method] : array();
  106. $custom = isset($this->routes[$method]) ? $this->routes[$method] : array();
  107. $merged = $custom;
  108. foreach ($default as $route => $action) {
  109. if (! isset($merged[$route]))
  110. $merged[$route] = $action;
  111. }
  112. return $merged;
  113. }
  114. }