<?php
namespace Lia\Obj;
/**
* A simple object to hold route information for a matched route.
*
* Nothing documented here is enforced by this class. It's all passed TO it.
* If a different Routing component is used, it might not follow the currently documented usage in this class.
*/
class Route {
/**
* Paramaters extracted from the url, based upon the route.
* Ex: `/blog/{slug}/` requested by `/blog/happy-cats/` would yield `['slug'=>'happy-cats']`
*/
protected $paramaters = [];
/**
* The requeted URL without any GET params
*/
protected $url;
/**
* The request method, like GET, POST, etc
*/
protected $method;
/**
* The regex that captured the url
*/
protected $urlRegex;
/**
* The declared route, unparsed, like `/blog/{slug}/`
*/
protected $paramaterizedPattern;
/**
* A simplified pattern for the route-selection algorithm
* For declared route `/blog/{slug}/`, $placeholderPattern would be `blog/?/`
*/
protected $placeholderPattern;
/**
* Array of methods that are valid for this route. Such as GET, PUT, POST, DELETE, etc
*/
protected $allowedMethods = [];
/**
* The thing being routed to. A callable or an absolute file path
*/
protected $target;
/**
* The package that create the route which was matched.
*/
protected $package;
/**
* Make a route
* Sorry, I'm not documenting this further.
* Usage is in Router component, in the route() method.
* @param $details an array of route info.
*/
public function __construct($details){
foreach ($details as $name => $d){
if (property_exists($this,$name)){
$this->$name = $d;
}
}
foreach ($details['optionalParamaters']??[] as $op){
$index = array_search($op, $details['paramaters']);
// print_r($details['paramaters']);
// print_r($details['optionalParamaters']);
if (!isset($this->paramaters[$op]))$this->paramaters[$op] = null;
}
}
/**
* The piece of the url to return
* Ex url: `/part1/part2/part3.php`
* `part(0)` returns `part1`.
*/
public function part($index){
//@TODO should part() check parts between forward slashes (/) or parts between all valid delimiters? Should this be decided by route?
return explode('/',$this->url)[1+$index] ?? null;
}
/**
* Get a named url paramater.
* Ex: for `/blog/{slug}/`, `param('slug')` returns the slug
*/
public function param($key){
return $this->paramaters[$key] ?? null;
}
/**
* Get a named url paramater by index (zero-based)
*/
public function var($index){
return array_values($this->paramaters)[$index] ?? null;
}
/**
* @return a package object
*/
public function package(){
return $this->package;
}
/**
* return the requested url
*/
public function url(){
return $this->url;
}
/**
* return the requested method (GET/POST/etc)
*/
public function method(){
return $this->method;
}
/**
* Get the callable or file this route points to
*/
public function target(){
return $this->target;
}
/**
* get the type (is callable vs. is file)
*/
public function type(){
$t = $this->target;
if ($this->isFile())return 'file';
else if ($this->isCallable())return 'callable';
else return null;
}
/** check if target is callable */
public function isCallable(){
$t = $this->target;
return is_callable($t);
}
/** check if target is a file */
public function isFile(){
$t = $this->target;
return is_string($t) && is_file($t);
}
/** get the file extension if target is a file
* @return file path or false
*/
public function fileExt(){
if (!$this->isFile())return false;
$ext = pathinfo($this->target, PATHINFO_EXTENSION);
return $ext;
}
/**
* Get the target pattern for this route with {param} declarations
*/
public function paramaterizedPattern(){
return $this->paramaterizedPattern;
}
/**
* Get the target pattern for this route with placeholders (?)
*/
public function placeholderPattern(){
return $this->placeholderPattern;
}
/** array of methods allowed for this route */
public function allowedMethods(){
return $this->allowedMethods;
}
/** number of url paramaters */
public function paramaterCount(){
return count($this->paramaters);
}
/** names of url paramaters */
public function paramaterNames(){
return array_keys($this->paramaters);
}
/** array of paramaters */
public function paramaters(){
return $this->paramaters;
}
/** true if there are no paramaters in the route pattern */
public function isStatic(){
return ($this->paramaterCount()===0);
}
/** true if there are paramaters in the route pattern */
public function isDynamic(){
return !$this->isStatic();
}
}