PageRenderTime 25ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/ezc/MvcTools/src/routes/regexp.php

https://bitbucket.org/crevillo/enetcall
PHP | 253 lines | 125 code | 25 blank | 103 comment | 24 complexity | a03eccc39ffb5655e23c5b7d8f235cc1 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * File containing the ezcMvcRegexpRoute class
  4. *
  5. * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
  6. * @license http://ez.no/licenses/new_bsd New BSD License
  7. * @version //autogentag//
  8. * @filesource
  9. * @package MvcTools
  10. */
  11. /**
  12. * Router class that uses regular expressions for matching routes.
  13. *
  14. * The routes are matched against the uri property of the request object.
  15. *
  16. * @package MvcTools
  17. * @version //autogentag//
  18. * @mainclass
  19. */
  20. class ezcMvcRegexpRoute implements ezcMvcRoute, ezcMvcReversibleRoute
  21. {
  22. /**
  23. * This property contains the regular expression.
  24. *
  25. * @var string
  26. */
  27. protected $pattern;
  28. /**
  29. * This is the name of the controller class that will be instantiated with the
  30. * request variables obtained from the route, as well as the default values
  31. * belonging to a route.
  32. *
  33. * @var string
  34. */
  35. protected $controllerClassName;
  36. /**
  37. * Contains the action that the controller should execute.
  38. *
  39. * @var string
  40. */
  41. protected $action;
  42. /**
  43. * The default values for the variables that are send to the controller. The route
  44. * matchers can override those default values
  45. *
  46. * @var array(string)
  47. */
  48. protected $defaultValues;
  49. /**
  50. * Constructs a new ezcMvcRegexpRoute with $pattern.
  51. *
  52. * When the route is matched (with the match() method), the route instantiates
  53. * an object of the class $controllerClassName.
  54. *
  55. * @param string $pattern
  56. * @param string $controllerClassName
  57. * @param string $action
  58. * @param array(string) $defaultValues
  59. */
  60. public function __construct( $pattern, $controllerClassName, $action = null, array $defaultValues = array() )
  61. {
  62. $this->pattern = $pattern;
  63. $this->controllerClassName = $controllerClassName;
  64. $this->action = $action;
  65. $this->defaultValues = $defaultValues;
  66. }
  67. /**
  68. * Returns the request information that the matches() method will match the
  69. * pattern against.
  70. *
  71. * @param ezcMvcRequest $request
  72. * @return string
  73. */
  74. protected function getUriString( ezcMvcRequest $request )
  75. {
  76. return $request->uri;
  77. }
  78. /**
  79. * Evaluates the URI against this route.
  80. *
  81. * The method first runs the match. If the regular expression matches, it
  82. * cleans up the variables to only include named parameters. it then
  83. * creates an object containing routing information and returns it. If the
  84. * route's pattern did not match it returns null.
  85. *
  86. * @param ezcMvcRequest $request
  87. * @return null|ezcMvcRoutingInformation
  88. */
  89. public function matches( ezcMvcRequest $request )
  90. {
  91. if ( $this->pregMatch( $request, $matches ) )
  92. {
  93. foreach ( $matches as $key => $match )
  94. {
  95. if ( is_numeric( $key ) )
  96. {
  97. unset( $matches[$key] );
  98. }
  99. }
  100. $request->variables = array_merge( $this->defaultValues, $request->variables, $matches );
  101. return new ezcMvcRoutingInformation( $this->pattern, $this->controllerClassName, $this->action );
  102. }
  103. return null;
  104. }
  105. /**
  106. * This method performs the actual regular expresion match against the
  107. * $request's URI.
  108. *
  109. * @param ezcMvcRequest $request
  110. * @param array(string) $matches
  111. * @return bool
  112. */
  113. protected function pregMatch( $request, &$matches )
  114. {
  115. return preg_match( $this->pattern, $this->getUriString( $request ), $matches );
  116. }
  117. /**
  118. * Parses the pattern and adds the prefix.
  119. *
  120. * It's up to the developer to provide a meaningfull prefix. In this case,
  121. * it needs to be a regular expression just like the pattern.
  122. *
  123. * @param mixed $prefix
  124. * @throws ezcMvcRegexpRouteException if the prefix can not be prepended to
  125. * the pattern.
  126. */
  127. public function prefix( $prefix )
  128. {
  129. $pattern = $this->pattern;
  130. // Find pattern delimiter
  131. $patternDelim = $pattern[0];
  132. // Obtain pattern modifiers
  133. $patternModifier = substr( strrchr( $pattern, $patternDelim ), 1 );
  134. // Find prefix delimiter
  135. $prefixDelim = $prefix[0];
  136. // Obtain prefix modifiers
  137. $prefixModifier = substr( strrchr( $prefix, $prefixDelim ), 1 );
  138. // If modifiers are not the same, throw exception
  139. if ( $patternModifier !== $prefixModifier )
  140. {
  141. throw new ezcMvcRegexpRouteException( "The pattern modifiers of the prefix '{$prefix}' and pattern '{$pattern}' do not match." );
  142. }
  143. // Reassemble the new pattern
  144. $newPattern = $patternDelim;
  145. $newPattern .= substr( $prefix, 1, -1 - strlen( $prefixModifier ) );
  146. $newPattern .= substr( $pattern, 1 + ( $pattern[1] == '^' ) );
  147. $this->pattern = $newPattern;
  148. }
  149. /**
  150. * Generates an URL back out of a route, including possible arguments
  151. *
  152. * @param array $arguments
  153. */
  154. public function generateUrl( array $arguments = null )
  155. {
  156. $url = $this->pattern;
  157. // strip delimiters
  158. $url = substr( $url, 1 );
  159. $url = substr( $url, 0, -1 );
  160. // strip ^
  161. if ( substr( $url, 0, 1 ) == '^' )
  162. {
  163. $url = substr( $url, 1 );
  164. }
  165. // strip $
  166. if ( substr( $url, -1 ) == '$' )
  167. {
  168. $url = substr( $url, 0, -1 );
  169. }
  170. // merge default values
  171. if ( is_null( $arguments ) )
  172. {
  173. $arguments = array( );
  174. }
  175. $arguments = array_merge( $this->defaultValues, $arguments );
  176. $openPart = $openPartName = false;
  177. $partName = $partOffset = $partLength = false;
  178. $openParenthesis = 0;
  179. for( $i = 0; isset( $url[$i] ); $i ++)
  180. {
  181. if ( $url[$i] == '(' )
  182. {
  183. $openParenthesis++;
  184. }
  185. elseif ( $url[$i] == ')' )
  186. {
  187. $openParenthesis--;
  188. }
  189. if ( substr( $url, $i, 4 ) == '(?P<' )
  190. {
  191. $openPart = $openPartName = true;
  192. $partOffset = $i;
  193. $partLength = 4;
  194. $i += 4;
  195. }
  196. if ( $openPart )
  197. {
  198. $partLength++;
  199. if ( $url[$i] == ')' && $openParenthesis == 0 )
  200. {
  201. $url = str_replace(
  202. substr( $url, $partOffset, $partLength ),
  203. $arguments[$partName],
  204. $url
  205. );
  206. $i = $partOffset + strlen( $arguments[$partName] );
  207. $partName = '';
  208. $openPart = false;
  209. $partOffset = false;
  210. $partLength = 0;
  211. }
  212. }
  213. if ( $openPartName )
  214. {
  215. if ( $url[$i] == '>' )
  216. {
  217. $openPartName = false;
  218. }
  219. else
  220. {
  221. $partName.= $url[$i];
  222. }
  223. }
  224. }
  225. return $url;
  226. }
  227. }
  228. ?>