Just to check if I have something worth using & sharing
All routing goes to the corresponding controllers which reside in Modules.
Modules
– Front
---- MainController
---- AnotherFrontController
– Admin
---- AdminController
---- UserController
So if you call /admin/user/list
if will auto-magically go to the edit function within the UserController
routes.php:
<?php
/**
* All the routes to their corresponding controllers
*
* The first param is the start of the url
* Example:
* every url starting with /admin will be handled by the configured controller
*
*/
use MyApp\Common\Helpers\RouteResolver;
$app->any('[/{args:.*}]', function ($request, $response, $args) use($app)
{
$obRouteResolver = new RouteResolver($this, $request, $response, $args);
return $obRouteResolver->call($this, $request, $response, $args);
});
RouteResolver.php:
<?php
namespace MyApp\Common\Helpers;
/**
* Class routeResolver
* creates dynamic routing functionality
* routes url to the correct controller->action($args)
*/
class RouteResolver
{
/**
* Call a given class / method
*
* @param string $container
* @param string $request
* @param string $response
* @param array $args
*
* @return \Psr\Http\Message\ResponseInterface
* @throws \Exception
*/
public function call($container, $request, $response, $args)
{
$args = explode('/', $args['args']);
$reflection = $this->getControllerClass($args);
$method = $this->getMethod($reflection, $args);
if (!$method)
{
throw new \Exception('Method ' . $method->getName() . ' not found in ' . $reflection->getName());
}
$params['args'] = $args;
$oClass = $reflection->newInstanceArgs([$container, $request, $response]);
$ret = $method->invokeArgs($oClass, $params);
if ($ret instanceof ResponseInterface) {
$response = $ret;
} elseif (is_string($ret) || is_numeric($ret)) {
$response->write($ret);
}
return $response;
}
/**
* Get the correct controller class
*
* @param $nameSpace
* @param $route
* @param $defaultRoute
* @param $args
*
* @return \ReflectionClass
*/
private function getControllerClass(&$args)
{
$reflection = false;
// test if argument 1 is a controller
if (@$args[1])
{
$reflection = $this->getReflection($args, 1);
}
// test if argument 0 is a controller
if (@$args[0] && !$reflection) {
$reflection = $this->getReflection($args, 0);
}
// get default controller
if (!$reflection) {
$reflection = $this->getReflection($args);
}
return $reflection;
}
/**
* Try to load the reflection class of the controller
*
* @param $args
* @param int $argNr
*
* @return bool|\ReflectionClass
*/
private function getReflection(&$args, $argNr = -1)
{
if ($argNr == 1) {
$domain = ucfirst($args[0]);
$controller = ucfirst($args[1]);
} elseif ($argNr == 0) {
$domain = ucfirst($args[0]);
$controller = ucfirst($args[0]);
}
else {
$domain = 'Frontend';
$controller = 'Frontend';
}
$nameSpace = 'MyApp\Modules\\';
$route = $domain . '\Controllers\\' . $controller . 'Controller';
$fullControllerName = $nameSpace . $route;
//var_dump($fullControllerName);
try {
$reflection = new \ReflectionClass($fullControllerName);
for ($i = 0; $i <= $argNr; $i++){
unset($args[$i]);
}
$args = array_values($args);
} catch (\ReflectionException $e) {
$reflection = false;
}
return $reflection;
}
/**
* Try to load the method of the reflection class of the controller
*
* @param $reflection
* @param $args
*
* @return bool|\ReflectionMethod
*/
private function getMethod($reflection, &$args)
{
$func = false;
if ($args) {
$func = $args[0];
unset($args[0]);
$args = array_values($args);
}
if (!$func) {
$func = 'index'; // default action in a controller
}
try {
$method = $reflection->getMethod($func);
} catch (\ReflectionException $e) {
$method = false;
}
return $method;
}
}