diff --git a/README.md b/README.md index dfdab3a..79062df 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ use Pecee\SimpleRouter\SimpleRouter; SimpleRouter::group(['prefix' => 'v1', 'middleware' => '\MyWebsite\Middleware\SomeMiddlewareClass'], function() { - SimpleRouter::group(['prefix' => 'services'], function() { + SimpleRouter::group(['prefix' => '/services', 'exceptionHandler' => '\MyProject\Handler\CustomExceptionHandler'], function() { SimpleRouter::get('/answers/{id}', 'ControllerAnswers@show')->where(['id' => '[0-9]+'); @@ -131,47 +131,57 @@ The framework has it's own ```Router``` class which inherits from the ```SimpleR namespace MyProject; use Pecee\Handler\ExceptionHandler; +use Pecee\SimpleRouter\RouterBase; use Pecee\SimpleRouter\SimpleRouter; class Router extends SimpleRouter { - protected static $exceptionHandlers = array(); + protected static $defaultExceptionHandler; - public static function start() { - - Debug::getInstance()->add('Router initialised.'); + public static function start($defaultNamespace = null) { // Load routes.php - $file = $_ENV['basePath'] . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'routes.php'; + $file = $_ENV['base_path'] . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'routes.php'; if(file_exists($file)) { require_once $file; } - // Init locale settings - Locale::getInstance(); - - // Set default namespace for routes - $defaultNamespace = '\\'.Registry::getInstance()->get('AppName') . '\\Controller'; - - // Add custom csrf verifier (must extend BaseCsrfVerifier) - parent::csrfVerifier('MyProject\Middleware\CustomCsrfVerifier'); + // Set default namespace + $defaultNamespace = '\\'.$_ENV['app_name'] . '\\Controller'; // Handle exceptions try { parent::start($defaultNamespace); } catch(\Exception $e) { - /* @var $handler ExceptionHandler */ - foreach(self::$exceptionHandlers as $handler) { - $class = new $handler(); - $class->handleError($e); + + $route = RouterBase::getInstance()->getLoadedRoute(); + + $exceptionHandler = null; + + // Load and use exception-handler defined on group + + if($route && $route->getGroup()) { + $exceptionHandler = $route->getGroup()->getExceptionHandler(); + + if($exceptionHandler !== null) { + $class = new $exceptionHandler(); + $class->handleError(RouterBase::getInstance()->getRequest(), $route, $e); + } + } + + // Otherwise use the fallback default exceptions handler + + if(self::$defaultExceptionHandler !== null) { + $class = new self::$defaultExceptionHandler(); + $class->handleError(RouterBase::getInstance()->getRequest(), $route, $e); } throw $e; } } - public static function addExceptionHandler($handler) { - self::$exceptionHandlers[] = $handler; + public static function setDefaultExceptionHandler($handler) { + self::$defaultExceptionHandler = $handler; } } diff --git a/src/Pecee/SimpleRouter/RouterBase.php b/src/Pecee/SimpleRouter/RouterBase.php index 9f83013..6da4e36 100644 --- a/src/Pecee/SimpleRouter/RouterBase.php +++ b/src/Pecee/SimpleRouter/RouterBase.php @@ -39,12 +39,16 @@ class RouterBase { } } - protected function processRoutes(array $routes, array $settings = array(), array $prefixes = array(), $backstack = false) { + protected function processRoutes(array $routes, array $settings = array(), array $prefixes = array(), $backstack = false, $group = null) { // Loop through each route-request + $activeGroup = null; + /* @var $route RouterEntry */ foreach($routes as $route) { + $route->setGroup($group); + if($this->defaultNamespace && !$route->getNamespace()) { $namespace = null; if ($route->getNamespace()) { @@ -75,6 +79,7 @@ class RouterBase { $this->currentRoute = $route; if($route instanceof RouterGroup && is_callable($route->getCallback())) { $route->renderRoute($this->request); + $activeGroup = $route; } $this->currentRoute = null; @@ -83,7 +88,7 @@ class RouterBase { $this->backstack = array(); // Route any routes added to the backstack - $this->processRoutes($backstack, $mergedSettings, $newPrefixes, true); + $this->processRoutes($backstack, $mergedSettings, $newPrefixes, true, $activeGroup); } } } diff --git a/src/Pecee/SimpleRouter/RouterEntry.php b/src/Pecee/SimpleRouter/RouterEntry.php index e38ac29..7adc53e 100644 --- a/src/Pecee/SimpleRouter/RouterEntry.php +++ b/src/Pecee/SimpleRouter/RouterEntry.php @@ -317,6 +317,15 @@ abstract class RouterEntry { return $this->settings['requestMethods']; } + public function getGroup() { + return $this->group; + } + + public function setGroup($group) { + $this->group = $group; + return $this; + } + abstract function matchRoute(Request $request); } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/RouterGroup.php b/src/Pecee/SimpleRouter/RouterGroup.php index 66600fb..61e4d41 100644 --- a/src/Pecee/SimpleRouter/RouterGroup.php +++ b/src/Pecee/SimpleRouter/RouterGroup.php @@ -33,4 +33,13 @@ class RouterGroup extends RouterEntry { return null; } + public function setExceptionHandler($class) { + $this->exceptionHandler = $class; + return $this; + } + + public function getExceptionHandler() { + return $this->exceptionHandler; + } + } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/RouterRoute.php b/src/Pecee/SimpleRouter/RouterRoute.php index 4b7cf98..65e75c9 100644 --- a/src/Pecee/SimpleRouter/RouterRoute.php +++ b/src/Pecee/SimpleRouter/RouterRoute.php @@ -6,7 +6,7 @@ use Pecee\Http\Request; class RouterRoute extends RouterEntry { - const PARAMETERS_REGEX_MATCH = '{([A-Za-z\-\_]*?\?{0,1})}'; + const PARAMETERS_REGEX_MATCH = '{([A-Za-z\-\_]*?)\?{0,1}}'; protected $url; @@ -60,12 +60,12 @@ class RouterRoute extends RouterEntry { $isParameter = true; } elseif($isParameter && $character === '}') { - $required = false; + $required = true; // Check for optional parameter if($lastCharacter === '?') { $parameter = substr($parameter, 0, strlen($parameter)-1); $regex .= '(?:(?:\/{0,1}(?P<'.$parameter.'>[a-z0-9]*?)){0,1}\\/)'; - $required = true; + $required = false; } else { // Use custom parameter regex if it exists $parameterRegex = '[a-z0-9]*?'; @@ -130,12 +130,13 @@ class RouterRoute extends RouterEntry { public function setUrl($url) { $parameters = array(); + $matches = array(); - preg_match_all('/'.self::PARAMETERS_REGEX_MATCH.'/is', $url, $parameters); + if(preg_match_all('/'.self::PARAMETERS_REGEX_MATCH.'/is', $url, $matches)) { + $parameters = $matches[1]; + } - $parameters = $parameters[1]; - - if($parameters !== null) { + if(count($parameters)) { foreach($parameters as $param) { $this->parameters[$param] = ''; }