<?php

/**

*

*/

class Router

{

public $config ;

public $URI ;

public $requestURI ;

public $routingPatterns ;

public $routes ;

public function __construct ( Config $config , $requestURI = '' )

{

$this -> config = $config ;

$this -> routes = array ( ) ;

$this -> routingPatterns = array ( ) ;

$this -> requestURI = $requestURI ;

$URI = $this -> getURI ( ) ;

$this -> URI = explode ( '/' , $URI ) ;

}

public function setRouteByPattern ( $routePattern )

{

//Use :controller to set where the controller is, :method to set the method and :args (the rest will be turned into arguments)

//If no controller is specified, the default controller will be used

//if no method is specified, the default method will be used

//Example: :controller/:method/:args

array_push ( $this -> routingPatterns , $routePattern ) ;

}

public function setRoute ( $routeMatch , $action )

{

//These routes get preference over the routing patterns

//Use '/*/' to allow any value inside the //

//Use /? to allow anything after the /

//Example: setRoute('myController/someMethod/?', 'someClass/?')

$this -> routes [ $routeMatch ] = $action ;

}

public function splitRoute ( $routeString )

{

return explode ( '/' , $routeString ) ;

}

public function getRequestURI ( )

{

if ( $this -> requestURI == '' )

{

return filter_input ( INPUT_SERVER , "REQUEST_URI" , FILTER_SANITIZE_URL ) ;

}

else

{

return $this -> requestURI ;

}

}

public function getURI ( )

{

$URI = trim ( $this -> getRequestURI ( ) , '/' ) ;

//remove the path which the Application is stored under

$URI = preg_replace ( '~' . $this -> config -> router ( 'path' ) . '~' , '' , $URI , 1 ) ;

$URI = trim ( $URI , '/' ) ;

return $URI ;

}

public function matchRoute ( $routeString )

{

$routeParts = $this -> splitRoute ( $routeString ) ;

$numRouteElements = count ( $routeParts ) ;

$atElement = 0 ;

$match = true ;

while ( $match && $atElement < $numRouteElements )

{

if ( ! $this -> compareRoute ( $routeParts [ $atElement ] , $atElement ) )

{

$match = false ;

}

$atElement ++;

}

return $match ;

}

public function compareRoute ( $routePart , $element )

{

switch ( $routePart )

{

case '*' :

if ( isset ( $this -> URI [ $element ] ) && $this -> URI [ $element ] != '' )

{

return true ;

}

else

{

return false ;

}

break ;

case '?' :

return true ;

break ;

default :

if ( isset ( $this -> URI [ $element ] ) && strcmp ( $this -> URI [ $element ] , $routePart ) == 0 )

{

return true ;

}

else

{

return false ;

}

break ;

}

}

public function translateIntoDispatch ( $action )

{

$countAction = count ( $action ) ;

if ( isset ( $action [ 0 ] ) && $action [ 0 ] != '' )

{

$controller = $action [ 0 ] ;

}

else

{

$controller = $this -> config -> router ( 'defaultController' ) ;

}

if ( isset ( $action [ 1 ] ) && $action [ 1 ] != '' )

{

$method = $action [ 1 ] ;

}

else

{

$method = $this -> config -> router ( 'defaultMethod' ) ;

}

unset ( $action [ 0 ] ) ;

unset ( $action [ 1 ] ) ;

$callToDispatch = array ( 'controller' => $controller ,

'method' => $method ,

'args' => $action ) ;

return $callToDispatch ;

}

public function route ( )

{

//add the default routing pattern to the end of the Routing list, so if no other patterns match, this will be loaded

$this -> setRouteByPattern ( $this -> config -> router ( 'defaultRoutingPattern' ) ) ;

foreach ( $this -> routes as $route => $action )

{

if ( $this -> matchRoute ( $route ) )

{

$routeParts = $this -> splitRoute ( $route ) ;

$endLocation = array_search ( '?' , $routeParts ) ;

$endInAction = array_search ( '?' , explode ( '/' , $action ) ) ;

if ( $endLocation !== false && $endInAction !== false )

{

$elementsInURI = count ( $this -> URI ) ;

$actionArray = explode ( '/' , $action ) ;

array_pop ( $actionArray ) ; //remove the ? from the array

while ( $endLocation < $elementsInURI )

{

//create one big action array

array_push ( $actionArray , $this -> URI [ $endLocation ] ) ;

$endLocation ++;

}

return $this -> translateIntoDispatch ( $actionArray ) ;

}

else

{

return $this -> translateIntoDispatch ( explode ( '/' , $action ) ) ;

}

}

}

//if we get to here, none of the set routes have matched our URI, move onto the patterns

foreach ( $this -> routingPatterns as $routingPattern )

{

$action = array ( ) ; //this will contain our action, which will be returned

$patternParts = explode ( '/' , $routingPattern ) ;

$controllerLocation = array_search ( ':controller' , $patternParts ) ;

if ( $controllerLocation !== false && isset ( $this -> URI [ $controllerLocation ] ) && $this -> URI [ $controllerLocation ] != '' )

{

$action [ 0 ] == $this -> URI [ $controllerLocation ] ;

}

$methodLocation = array_search ( ':method' , $patternParts ) ;

if ( $methodLocation !== false && isset ( $this -> URI [ $methodLocation ] ) && $this -> URI [ $methodLocation ] != '' )

{

$action [ 1 ] == $this -> URI [ $controllerLocation ] ;

}

$argsLocation = array_search ( ':args' , $patternParts ) ;

$element = $argsLocation ;

while ( $element <= count ( $this -> URI ) )

{

array_push ( $action , $this -> URI [ $element ] ) ;

$element ++;

}

return $this -> translateIntoDispatch ( $action ) ;

}

return $this -> translateIntoDispatch ( $this -> URI ) ;

}

public function generateURI ( $controller )

{

}

}