<?php namespace elanpl\L3; class Router{ protected $routes; // The defined routes collection protected $parsedParameters; // Parameters parsed from Request Path protected $depth; // Number of nested nodes in Request Path protected $routeNameIndex; // An array with elements that reference to the routes ordered by a route names public $RouteInfo; // The RouteInfo objcet if the route was matched public function __construct($routing) { $this->routes = array(); $this->routeNameIndex = array(); //Set the routing from configuration object $routing->set($this); } public function add($Method, $Path, $Result, $Name = ''){ $this->routes[] = new RouteInfo($Method, $Path, $Result, $Name); if(isset($Name)&&$Name!='') $this->routeNameIndex[$Name] = &$this->routes[count($this->routes)-1]; return $this; } public function get($Path, $Result, $Name = ''){ return $this->add('GET', $Path, $Result, $Name); } public function post($Path, $Result, $Name = ''){ return $this->add('POST', $Path, $Result, $Name); } public function put($Path, $Result, $Name = ''){ return $this->add('PUT', $Path, $Result, $Name); } public function patch($Path, $Result, $Name = ''){ return $this->add('PATCH', $Path, $Result, $Name); } public function delete($Path, $Result, $Name = ''){ return $this->add('DELETE', $Path, $Result, $Name); } public function any($Path, $Result, $Name = ''){ return $this->add('ANY', $Path, $Result, $Name); } public function AddBeforeAction($event_handler){ $this->routes[count($this->routes)-1]->AddBeforeAction($event_handler); return $this; } public function AddAfterAction($event_handler){ $this->routes[count($this->routes)-1]->AddAfterAction($event_handler); return $this; } public function AddAfterResult($event_handler){ $this->routes[count($this->routes)-1]->AddAfterAction($event_handler); return $this; } public function match($Request){ $auri = explode('/', trim($Request->Path, "/ \t\n\r\0\x0B")); $curi = count($auri); foreach ($this->routes as $routeInfo) { $route = $routeInfo->Path; $method = $routeInfo->Method; if($method=='ANY' || strpos($Request->Method,$method)!==false){ $aroute = explode('/', trim($route, "/ \t\n\r\0\x0B")); //print_r($aroute); if($curi==count($aroute)){ //compare path element count //optimistic assumption :) $matchResult = true; for($i = 0; $i<$curi; $i++){ $pathPartName = trim($aroute[$i],'{}'); if($aroute[$i]==$pathPartName){ if($auri[$i]!=$pathPartName){ //echo "diffrence found"; $matchResult = false; break; } } else{ // {...} found -> catch $uri variable $value = $auri[$i]; $valueKey = explode(':', $pathPartName); //validation if(isset($valueKey[1]) && $valueKey[1]=='int'){ $value = intval($value); } //value store... $this->parsedParameters[$valueKey[0]] = $value; } } if($matchResult){ // match found $this->depth = $curi; $this->RouteInfo = $routeInfo; return $routeInfo->Result; } } } } return false; } public function link($name, $parameters){ $route = $this->routeNameIndex[$name]; $fields = array_keys($parameters); $values = array_values($parameters); array_walk($fields, function (&$item, $key){ $item = "/\{".$item."\}/"; }); return preg_replace($fields, $values, $route->Path); } public function GetParameter($name){ return $this->parsedParameters[$name]; } }