[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Part of the Joomla Framework Router Package 4 * 5 * @copyright Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. 6 * @license GNU General Public License version 2 or later; see LICENSE 7 */ 8 9 namespace Joomla\Router; 10 11 use SuperClosure\SerializableClosure; 12 13 /** 14 * An object representing a route definition. 15 * 16 * @since 2.0.0 17 */ 18 class Route implements \Serializable 19 { 20 /** 21 * The controller which handles this route 22 * 23 * @var mixed 24 * @since 2.0.0 25 */ 26 private $controller; 27 28 /** 29 * The default variables defined by the route 30 * 31 * @var array 32 * @since 2.0.0 33 */ 34 private $defaults = []; 35 36 /** 37 * The HTTP methods this route supports 38 * 39 * @var string[] 40 * @since 2.0.0 41 */ 42 private $methods; 43 44 /** 45 * The route pattern to use for matching 46 * 47 * @var string 48 * @since 2.0.0 49 */ 50 private $pattern; 51 52 /** 53 * The path regex this route processes 54 * 55 * @var string 56 * @since 2.0.0 57 */ 58 private $regex; 59 60 /** 61 * The variables defined by the route 62 * 63 * @var array 64 * @since 2.0.0 65 */ 66 private $routeVariables = []; 67 68 /** 69 * An array of regex rules keyed using the route variables 70 * 71 * @var array 72 * @since 2.0.0 73 */ 74 private $rules = []; 75 76 /** 77 * Constructor. 78 * 79 * @param array $methods The HTTP methods this route supports 80 * @param string $pattern The route pattern to use for matching 81 * @param mixed $controller The controller which handles this route 82 * @param array $rules An array of regex rules keyed using the route variables 83 * @param array $defaults The default variables defined by the route 84 * 85 * @since 2.0.0 86 */ 87 public function __construct(array $methods, string $pattern, $controller, array $rules = [], array $defaults = []) 88 { 89 $this->setMethods($methods); 90 $this->setPattern($pattern); 91 $this->setController($controller); 92 $this->setRules($rules); 93 $this->setDefaults($defaults); 94 } 95 96 /** 97 * Parse the route's pattern to extract the named variables and build a proper regular expression for use when parsing the routes. 98 * 99 * @return void 100 * 101 * @since 2.0.0 102 */ 103 protected function buildRegexAndVarList(): void 104 { 105 // Sanitize and explode the pattern. 106 $pattern = explode('/', trim(parse_url($this->getPattern(), PHP_URL_PATH), ' /')); 107 108 // Prepare the route variables 109 $vars = []; 110 111 // Initialize regular expression 112 $regex = []; 113 114 // Loop on each segment 115 foreach ($pattern as $segment) 116 { 117 if ($segment == '*') 118 { 119 // Match a splat with no variable. 120 $regex[] = '.*'; 121 } 122 elseif (isset($segment[0]) && $segment[0] == '*') 123 { 124 // Match a splat and capture the data to a named variable. 125 $vars[] = substr($segment, 1); 126 $regex[] = '(.*)'; 127 } 128 elseif (isset($segment[0]) && $segment[0] == '\\' && $segment[1] == '*') 129 { 130 // Match an escaped splat segment. 131 $regex[] = '\*' . preg_quote(substr($segment, 2)); 132 } 133 elseif ($segment == ':') 134 { 135 // Match an unnamed variable without capture. 136 $regex[] = '([^/]*)'; 137 } 138 elseif (isset($segment[0]) && $segment[0] == ':') 139 { 140 // Match a named variable and capture the data. 141 $varName = substr($segment, 1); 142 $vars[] = $varName; 143 144 // Use the regex in the rules array if it has been defined. 145 $regex[] = array_key_exists($varName, $this->getRules()) ? '(' . $this->getRules()[$varName] . ')' : '([^/]*)'; 146 } 147 elseif (isset($segment[0]) && $segment[0] == '\\' && $segment[1] == ':') 148 { 149 // Match a segment with an escaped variable character prefix. 150 $regex[] = preg_quote(substr($segment, 1)); 151 } 152 else 153 { 154 // Match the standard segment. 155 $regex[] = preg_quote($segment); 156 } 157 } 158 159 $this->setRegex(\chr(1) . '^' . implode('/', $regex) . '$' . \chr(1)); 160 $this->setRouteVariables($vars); 161 } 162 163 /** 164 * Retrieve the controller which handles this route 165 * 166 * @return mixed 167 * 168 * @since 2.0.0 169 */ 170 public function getController() 171 { 172 return $this->controller; 173 } 174 175 /** 176 * Retrieve the default variables defined by the route 177 * 178 * @return array 179 * 180 * @since 2.0.0 181 */ 182 public function getDefaults(): array 183 { 184 return $this->defaults; 185 } 186 187 /** 188 * Retrieve the HTTP methods this route supports 189 * 190 * @return string[] 191 * 192 * @since 2.0.0 193 */ 194 public function getMethods(): array 195 { 196 return $this->methods; 197 } 198 199 /** 200 * Retrieve the route pattern to use for matching 201 * 202 * @return string 203 * 204 * @since 2.0.0 205 */ 206 public function getPattern(): string 207 { 208 return $this->pattern; 209 } 210 211 /** 212 * Retrieve the path regex this route processes 213 * 214 * @return string 215 * 216 * @since 2.0.0 217 */ 218 public function getRegex(): string 219 { 220 if (!$this->regex) 221 { 222 $this->buildRegexAndVarList(); 223 } 224 225 return $this->regex; 226 } 227 228 /** 229 * Retrieve the variables defined by the route 230 * 231 * @return array 232 * 233 * @since 2.0.0 234 */ 235 public function getRouteVariables(): array 236 { 237 if (!$this->regex) 238 { 239 $this->buildRegexAndVarList(); 240 } 241 242 return $this->routeVariables; 243 } 244 245 /** 246 * Retrieve the regex rules keyed using the route variables 247 * 248 * @return array 249 * 250 * @since 2.0.0 251 */ 252 public function getRules(): array 253 { 254 return $this->rules; 255 } 256 257 /** 258 * Set the controller which handles this route 259 * 260 * @param mixed $controller The controller which handles this route 261 * 262 * @return $this 263 * 264 * @since 2.0.0 265 */ 266 public function setController($controller): self 267 { 268 $this->controller = $controller; 269 270 return $this; 271 } 272 273 /** 274 * Set the default variables defined by the route 275 * 276 * @param array $defaults The default variables defined by the route 277 * 278 * @return $this 279 * 280 * @since 2.0.0 281 */ 282 public function setDefaults(array $defaults): self 283 { 284 $this->defaults = $defaults; 285 286 return $this; 287 } 288 289 /** 290 * Set the HTTP methods this route supports 291 * 292 * @param array $methods The HTTP methods this route supports 293 * 294 * @return $this 295 * 296 * @since 2.0.0 297 */ 298 public function setMethods(array $methods): self 299 { 300 $this->methods = $this->methods = array_map('strtoupper', $methods); 301 302 return $this; 303 } 304 305 /** 306 * Set the route pattern to use for matching 307 * 308 * @param string $pattern The route pattern to use for matching 309 * 310 * @return $this 311 * 312 * @since 2.0.0 313 */ 314 public function setPattern(string $pattern): self 315 { 316 $this->pattern = $pattern; 317 318 $this->setRegex(''); 319 $this->setRouteVariables([]); 320 321 return $this; 322 } 323 324 /** 325 * Set the path regex this route processes 326 * 327 * @param string $regex The path regex this route processes 328 * 329 * @return $this 330 * 331 * @since 2.0.0 332 */ 333 public function setRegex(string $regex): self 334 { 335 $this->regex = $regex; 336 337 return $this; 338 } 339 340 /** 341 * Set the variables defined by the route 342 * 343 * @param array $routeVariables The variables defined by the route 344 * 345 * @return $this 346 * 347 * @since 2.0.0 348 */ 349 public function setRouteVariables(array $routeVariables): self 350 { 351 $this->routeVariables = $routeVariables; 352 353 return $this; 354 } 355 356 /** 357 * Set the regex rules keyed using the route variables 358 * 359 * @param array $rules The rules defined by the route 360 * 361 * @return $this 362 * 363 * @since 2.0.0 364 */ 365 public function setRules(array $rules): self 366 { 367 $this->rules = $rules; 368 369 return $this; 370 } 371 372 /** 373 * Serialize the route. 374 * 375 * @return string The serialized route. 376 * 377 * @since 2.0.0 378 */ 379 public function serialize() 380 { 381 return serialize($this->__serialize()); 382 } 383 384 /** 385 * Serialize the route. 386 * 387 * @return array The data to be serialized 388 * 389 * @since 2.0.0 390 */ 391 public function __serialize() 392 { 393 $controller = $this->getController(); 394 395 if ($controller instanceof \Closure) 396 { 397 if (!class_exists(SerializableClosure::class)) 398 { 399 throw new \RuntimeException( 400 \sprintf( 401 'Cannot serialize the route for pattern "%s" because the controller is a Closure. ' 402 . 'Install the "jeremeamia/superclosure" package to serialize Closures.', 403 $this->getPattern() 404 ) 405 ); 406 } 407 408 $controller = new SerializableClosure($controller); 409 } 410 411 return [ 412 'controller' => $controller, 413 'defaults' => $this->getDefaults(), 414 'methods' => $this->getMethods(), 415 'pattern' => $this->getPattern(), 416 'regex' => $this->getRegex(), 417 'routeVariables' => $this->getRouteVariables(), 418 'rules' => $this->getRules(), 419 ]; 420 } 421 422 /** 423 * Unserialize the route. 424 * 425 * @param string $serialized The serialized route. 426 * 427 * @return void 428 * 429 * @since 1.0 430 */ 431 public function unserialize($serialized) 432 { 433 $this->__unserialize(unserialize($serialized)); 434 } 435 436 /** 437 * Unserialize the route. 438 * 439 * @param array $data The serialized route. 440 * 441 * @return void 442 * 443 * @since 2.0.0 444 */ 445 public function __unserialize(array $data) 446 { 447 $this->controller = $data['controller']; 448 $this->defaults = $data['defaults']; 449 $this->methods = $data['methods']; 450 $this->pattern = $data['pattern']; 451 $this->regex = $data['regex']; 452 $this->routeVariables = $data['routeVariables']; 453 $this->rules = $data['rules']; 454 } 455 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |