Standard.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. /**
  3. *
  4. * Cube Framework $Id$ cOvGSa9QPt4189rmC7aLgem5hXPRB+LLhHrBiSlt62c=
  5. *
  6. * @link http://codecu.be/framework
  7. * @copyright Copyright (c) 2014 CodeCube SRL
  8. * @license http://codecu.be/framework/license Commercial License
  9. *
  10. * @version 1.2
  11. */
  12. /**
  13. * router class for when mod rewrite or equivalent is not available
  14. */
  15. namespace Cube\Controller\Router;
  16. use Cube\Controller\Front,
  17. Cube\Controller\Request\AbstractRequest;
  18. class Standard extends AbstractRouter
  19. {
  20. const DEFAULT_PATH = 'index.php';
  21. const DEFAULT_MATCH = '#:([a-zA-Z0-9\._-]+)#';
  22. const DEFAULT_REGEX = '[a-zA-Z0-9\._-]+';
  23. /**
  24. *
  25. * the route class that corresponds to this router
  26. *
  27. * @var string
  28. */
  29. protected $_routeClass = '\Cube\Controller\Router\Route\Standard';
  30. /**
  31. *
  32. * routes a request and returns the routed request object
  33. * can match multiple routes, and will return the one that was matched last
  34. *
  35. * from the route's defaults array
  36. *
  37. * @param \Cube\Controller\Request\AbstractRequest $request
  38. *
  39. * @return \Cube\Controller\Request\AbstractRequest returns the routed request
  40. */
  41. public function route(AbstractRequest $request)
  42. {
  43. $request->setModule($request->getParam('module'))
  44. ->setController($request->getParam('controller'))
  45. ->setAction($request->getParam('action'));
  46. $request->clearParam('module')
  47. ->clearParam('controller')
  48. ->clearParam('action');
  49. return $request;
  50. }
  51. /**
  52. *
  53. * return a url string after processing the params and matching them to one of the existing routes
  54. * if a string is given, return it unmodified
  55. * if no route is specified
  56. *
  57. * @param mixed $params
  58. * @param string $name the name of a specific route to use
  59. * @param bool $addBaseUrl flag to add the base url param to the assembled route
  60. * @param bool $addGetParams whether to attach params resulted from a previous get operation to the url
  61. * @param array $skipParams an array of params to be omitted when constructing the url
  62. *
  63. * @return string
  64. */
  65. public function assemble($params, $name = null, $addBaseUrl = true, $addGetParams = false, array $skipParams = null)
  66. {
  67. $url = null;
  68. // check if we have a named route or if params is a string
  69. if ($name !== null) {
  70. $route = $this->getRoute($name);
  71. $url = $route->assemble($params, true);
  72. }
  73. else if (is_string($params)) {
  74. $uri = $params;
  75. /** @var \Cube\Controller\Router\Route\Standard $route */
  76. foreach ($this->_routes as $route) {
  77. $routePattern = preg_replace(self::DEFAULT_MATCH, '(' . self::DEFAULT_REGEX . ')', $route->getRoute());
  78. if (preg_match('#^' . $routePattern . '$#', $params, $values)) {
  79. preg_match_all(self::DEFAULT_MATCH, $route->getRoute(), $uri, PREG_PATTERN_ORDER);
  80. array_shift($values);
  81. foreach ((array)$uri[1] as $key) {
  82. $route->setParam($key, array_shift($values));
  83. }
  84. $url = $route->assemble(
  85. $route->getAllParams());
  86. }
  87. }
  88. }
  89. if (!isset($url)) {
  90. if (is_string($params)) {
  91. $parts = (array)explode(self::URI_DELIMITER, $params);
  92. $params = array();
  93. $params['module'] = array_shift($parts);
  94. $params['controller'] = array_shift($parts);
  95. $params['action'] = array_shift($parts);
  96. while ($key = array_shift($parts)) {
  97. $value = array_shift($parts);
  98. $params[$key] = $value;
  99. }
  100. }
  101. $params = $this->_getDefaultParams((array)$params, $addGetParams, $skipParams);
  102. $url = $this->_defaultRouteAssemble($params);
  103. }
  104. if (!preg_match('#^[a-z]+://#', $url)) {
  105. $url = (($addBaseUrl) ? Front::getInstance()->getRequest()->getBaseUrl() : '')
  106. . self::URI_DELIMITER
  107. . ltrim($url, self::URI_DELIMITER);
  108. }
  109. return $url;
  110. }
  111. /**
  112. *
  113. * assemble a request when no routes match
  114. * for array params, they wont be added in the url, but after the ? character
  115. *
  116. * if no module, controller and action is specified in the params, return the current uri + params after ? character
  117. *
  118. * @param array $params
  119. *
  120. * @return string the routed uri
  121. */
  122. protected function _defaultRouteAssemble(array $params = null)
  123. {
  124. $uri = self::DEFAULT_PATH;
  125. $get = array();
  126. foreach ((array)$params as $key => $value) {
  127. if (preg_match('#^[a-zA-Z0-9_-]+$#', $key)) {
  128. if (!is_array($value)) {
  129. if (in_array($key, array('module', 'controller', 'action'))) {
  130. $value = $this->normalize($value, true);
  131. }
  132. $get[] = $key . '=' . $value;
  133. }
  134. else {
  135. foreach ((array)$value as $val) {
  136. if (!empty($val)) {
  137. $get[] = $key . '[]=' . $val;
  138. }
  139. }
  140. }
  141. }
  142. }
  143. if (count($get) > 0) {
  144. $uri .= '?' . implode('&', $get);
  145. }
  146. return $uri;
  147. }
  148. /**
  149. *
  150. * normalize url parts for modules/controllers/actions in order for them to be parsable by the router
  151. *
  152. * - will first convert the input to lowercase
  153. * - will remove any non alpha-numeric and '-' characters from the value
  154. * - will convert '-' to camel cased and will capitalize the first letter of the string
  155. *
  156. * if reverse is set to true, we convert a router router parsable string into a url string
  157. *
  158. * @param string $input
  159. * @param bool $reverse
  160. *
  161. * @return string
  162. */
  163. public function normalize($input, $reverse = false)
  164. {
  165. if ($reverse) {
  166. return strtolower(
  167. preg_replace("/([a-z])([A-Z])/", '$1-$2', $input));
  168. }
  169. else {
  170. $input = str_replace('-', ' ', strtolower(
  171. preg_replace("/[^a-zA-Z0-9\_\-]/", '', $input)));
  172. return str_replace(' ', '', ucwords($input));
  173. }
  174. }
  175. }