Modify link to handle servers with odd configurations

This commit is contained in:
Mike Koch 2017-11-07 21:48:38 -05:00
parent 443d4ac1f3
commit 30dcb113ae
No known key found for this signature in database
GPG Key ID: 9BA5D7F8391455ED

View File

@ -8,114 +8,124 @@ require_once 'RequestMethod.php';
class Link class Link
{ {
/** /**
* @var array A collection of the routes originally passed into all function. Used by static function route * @var array A collection of the routes originally passed into all function. Used by static function route
*/ */
private static $routes = array(); private static $routes = array();
/** /**
* @var array A collection of functions that are executed before a route completion ( valid for all routes ), aka universal before functions * @var array A collection of functions that are executed before a route completion ( valid for all routes ), aka universal before functions
*/ */
private static $beforeFuncs = array(); private static $beforeFuncs = array();
/** /**
* @var array A collection of function that are executed after a route completion ( valid for all routes ), aka universal after functions * @var array A collection of function that are executed after a route completion ( valid for all routes ), aka universal after functions
*/ */
private static $afterFuncs = array(); private static $afterFuncs = array();
/** /**
* Static function of the class Link that deploys the route according to the passed handler and path * Static function of the class Link that deploys the route according to the passed handler and path
* *
* @param array $routes An array of combination of the path and its handler, that are final deployed for a particular url * @param array $routes An array of combination of the path and its handler, that are final deployed for a particular url
*/ */
public static function all( $routes ) public static function all( $routes )
{ {
/* Call all functions that are to be executed before routing */ /* Call all functions that are to be executed before routing */
foreach( self::$beforeFuncs as $beforeFunc ) { foreach( self::$beforeFuncs as $beforeFunc ) {
if( $beforeFunc[1] ) { if( $beforeFunc[1] ) {
call_user_func_array( $beforeFunc[0] , $beforeFunc[1] ); call_user_func_array( $beforeFunc[0] , $beforeFunc[1] );
} else { } else {
call_user_func( $beforeFunc[0] ); call_user_func( $beforeFunc[0] );
} }
} }
self::$routes = $routes; self::$routes = $routes;
$method = self::getRequestMethod(); $method = self::getRequestMethod();
$acceptedMethods = RequestMethod::all(); $acceptedMethods = RequestMethod::all();
$path = '/'; $path = '/';
$handler = null; $handler = null;
$matched = array(); $matched = array();
$middleware = null; $middleware = null;
if ( !empty ( $_SERVER['PATH_INFO'] ) ) { if ( !empty ( $_SERVER['PATH_INFO'] ) ) {
$path = $_SERVER['PATH_INFO']; $path = $_SERVER['PATH_INFO'];
} else if ( !empty ( $_SERVER['REQUEST_URI'] ) ) { } else if ( !empty ( $_SERVER['REQUEST_URI'] ) ) {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $parts = explode('/', $_SERVER['REQUEST_URI']);
} $startingIndex = -1;
for ($i = count($parts) - 1; $i > -1 && $startingIndex === -1; $i--) {
if ($parts[$i] === 'index.php' || $parts[$i] === 'api') {
$startingIndex = $i + 1;
}
}
$path = '';
for ($i = $startingIndex; $i < count($parts); $i++) {
$path .= "/{$parts[$i]}";
}
}
if ( isset($routes[$path] ) ) { if ( isset($routes[$path] ) ) {
if( is_array( $routes[$path] ) ) { if( is_array( $routes[$path] ) ) {
$handler = $routes[$path][0]; $handler = $routes[$path][0];
$middleware = $routes[$path][2]; $middleware = $routes[$path][2];
$acceptedMethods = $routes[$path][3]; $acceptedMethods = $routes[$path][3];
} else { } else {
$handler = $routes[$path]; $handler = $routes[$path];
} }
} else if ( $routes ) { } else if ( $routes ) {
$regex = array( $regex = array(
'/{i}/', '/{i}/',
'/{s}/', '/{s}/',
'/{a}/' '/{a}/'
); );
$replacements = array( $replacements = array(
'([\d]+)' , '([\d]+)' ,
'([a-zA-Z]+)', '([a-zA-Z]+)',
'([\w-]+)' '([\w-]+)'
); );
foreach ( $routes as $routePath => $routeDesc ){ foreach ( $routes as $routePath => $routeDesc ){
$routePath = preg_replace( $regex, $replacements, $routePath ); $routePath = preg_replace( $regex, $replacements, $routePath );
if( preg_match( '#^/?' . $routePath . '/?$#', $path, $matches ) ){ if( preg_match( '#^/?' . $routePath . '/?$#', $path, $matches ) ){
if( is_array( $routeDesc ) ) { if( is_array( $routeDesc ) ) {
$handler = $routeDesc[0]; $handler = $routeDesc[0];
if( isset( $routeDesc[2] )) { if( isset( $routeDesc[2] )) {
$middleware = $routeDesc[2]; $middleware = $routeDesc[2];
$acceptedMethods = $routeDesc[3]; $acceptedMethods = $routeDesc[3];
} }
} }
else else
$handler = $routeDesc; $handler = $routeDesc;
$matched = $matches; $matched = $matches;
break; break;
} }
} }
} }
unset( $matched[0] ); unset( $matched[0] );
if( isset($middleware) ){ if( isset($middleware) ){
$newMatched = self::callFunction( $middleware, $matched, $method, $acceptedMethods ); $newMatched = self::callFunction( $middleware, $matched, $method, $acceptedMethods );
/* If new wildcard param are there pass them to main handler */ /* If new wildcard param are there pass them to main handler */
if( $newMatched ) { if( $newMatched ) {
self::callFunction( $handler, $newMatched, $method, $acceptedMethods ); self::callFunction( $handler, $newMatched, $method, $acceptedMethods );
} else { } else {
self::callFunction( $handler, $matched, $method, $acceptedMethods ); self::callFunction( $handler, $matched, $method, $acceptedMethods );
} }
} else { } else {
self::callFunction( $handler, $matched, $method, $acceptedMethods ); self::callFunction( $handler, $matched, $method, $acceptedMethods );
} }
/* Call all the function that are to be executed after routing */ /* Call all the function that are to be executed after routing */
foreach( self::$afterFuncs as $afterFunc ) foreach( self::$afterFuncs as $afterFunc )
if( $afterFunc[1] ) { if( $afterFunc[1] ) {
call_user_func_array( $afterFunc[0] , $afterFunc[1] ); call_user_func_array( $afterFunc[0] , $afterFunc[1] );
} else { } else {
call_user_func( $afterFunc[0] ); call_user_func( $afterFunc[0] );
} }
} }
private static function getRequestMethod() { private static function getRequestMethod() {
$headers = getallheaders(); $headers = getallheaders();
$uppercaseHeaders = array(); $uppercaseHeaders = array();
@ -130,42 +140,42 @@ class Link
return $_SERVER['REQUEST_METHOD']; return $_SERVER['REQUEST_METHOD'];
} }
/** /**
* Static function that helps you generate links effortlessly and pass parameters to them, thus enabling to generate dynamic links * Static function that helps you generate links effortlessly and pass parameters to them, thus enabling to generate dynamic links
* *
* @param string $name name of the route for which the link has to be generated * @param string $name name of the route for which the link has to be generated
* @param array $params An array of parameters that are replaced in the route if it contains wildcards * @param array $params An array of parameters that are replaced in the route if it contains wildcards
* For e.g. if route is /name/{i}/{a} and parameters passed are 1, aps then link generated will be /name/1/aps * For e.g. if route is /name/{i}/{a} and parameters passed are 1, aps then link generated will be /name/1/aps
*/ */
public static function route( $name, $params = array() ) public static function route( $name, $params = array() )
{ {
$href = null; $href = null;
foreach ( self::$routes as $routePath => $routeDesc ) { foreach ( self::$routes as $routePath => $routeDesc ) {
if( is_array( $routeDesc ) ){ if( is_array( $routeDesc ) ){
if( $name == $routeDesc[1] ){ if( $name == $routeDesc[1] ){
$href = $routePath; $href = $routePath;
for( $i = 0; $i < count($params); $i++){ for( $i = 0; $i < count($params); $i++){
$href = preg_replace('#{(.*?)}#', $params[$i], $href, 1); $href = preg_replace('#{(.*?)}#', $params[$i], $href, 1);
} }
} }
} }
} }
return $href; return $href;
} }
/** /**
* Static function to handle cases when route is not found, call handler of 404 if defined else * Static function to handle cases when route is not found, call handler of 404 if defined else
* sends a 404 header * sends a 404 header
*/ */
public static function handle404() public static function handle404()
{ {
/* Call '404' route if it exists */ /* Call '404' route if it exists */
if( isset ( self::$routes['404'] ) ) { if( isset ( self::$routes['404'] ) ) {
call_user_func( self::$routes['404'] ); call_user_func( self::$routes['404'] );
} else { } else {
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
} }
} }
/** /**
* Static function to handle both middlewares' call and main handler's call. * Static function to handle both middlewares' call and main handler's call.
@ -178,64 +188,64 @@ class Link
* the wildcards that were originally passed, this newParams will * the wildcards that were originally passed, this newParams will
* be next passed to main handler * be next passed to main handler
*/ */
public static function callFunction( $handler , $matched, $method, $acceptedMethods ) public static function callFunction( $handler , $matched, $method, $acceptedMethods )
{ {
if (!in_array($method, $acceptedMethods)) { if (!in_array($method, $acceptedMethods)) {
print_r('Request method ' . $method . ' not allowed'); print_r('Request method ' . $method . ' not allowed');
header($_SERVER['SERVER_PROTOCOL'] . ' 405 Method Not Allowed', true, 405); header($_SERVER['SERVER_PROTOCOL'] . ' 405 Method Not Allowed', true, 405);
die(); die();
} }
if ( $handler ) { if ( $handler ) {
if ( is_callable( $handler ) ) { if ( is_callable( $handler ) ) {
$newParams = call_user_func_array( $handler, $matched ) ; $newParams = call_user_func_array( $handler, $matched ) ;
} else { } else {
/* Check if class exists in the case user is using RESTful pattern */ /* Check if class exists in the case user is using RESTful pattern */
if( class_exists( $handler ) ) { if( class_exists( $handler ) ) {
$instanceOfHandler = new $handler(); // Won't work in case of middleware since we aren't using RESTful in that $instanceOfHandler = new $handler(); // Won't work in case of middleware since we aren't using RESTful in that
} else { } else {
print_r('Class or function ' . $handler . ' not found'); print_r('Class or function ' . $handler . ' not found');
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500); header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
die(); die();
} }
} }
} else { } else {
self::handle404(); self::handle404();
} }
if( isset( $instanceOfHandler ) ) { if( isset( $instanceOfHandler ) ) {
if( method_exists( $instanceOfHandler, $method ) ) { if( method_exists( $instanceOfHandler, $method ) ) {
$newParams = call_user_func_array( array( $instanceOfHandler, $method ), $matched ); $newParams = call_user_func_array( array( $instanceOfHandler, $method ), $matched );
} }
} }
if( isset( $newParams ) && $newParams ) { if( isset( $newParams ) && $newParams ) {
return $newParams; return $newParams;
} }
} }
/** /**
* Static function to add functions that are to be excuted before each routing, must be called before Link::all * Static function to add functions that are to be excuted before each routing, must be called before Link::all
* *
* @param string $funcName Name of the funtion to be called upon before * @param string $funcName Name of the funtion to be called upon before
* @param array $params Array of parameters that are to be passed to before function, can be null but if not * @param array $params Array of parameters that are to be passed to before function, can be null but if not
* it must be an array * it must be an array
*/ */
public static function before( $funcName, $params = null ) public static function before( $funcName, $params = null )
{ {
array_push( self::$beforeFuncs, array($funcName, $params)); array_push( self::$beforeFuncs, array($funcName, $params));
} }
/** /**
* Static function to add functions that are to be excuted after each routing, must be called before Link::all * Static function to add functions that are to be excuted after each routing, must be called before Link::all
* *
* @param string $funcName Name of the funtion to be called upon after * @param string $funcName Name of the funtion to be called upon after
* @param array $params Array of parameters that are to be passed to after function, can be null but if not * @param array $params Array of parameters that are to be passed to after function, can be null but if not
* it must be an array * it must be an array
*/ */
public static function after( $funcName, $params = null ) public static function after( $funcName, $params = null )
{ {
array_push( self::$afterFuncs, array($funcName, $params)); array_push( self::$afterFuncs, array($funcName, $params));
} }
} }