diff --git a/Core/Router.php b/Core/Router.php new file mode 100644 index 0000000..7cc3b09 --- /dev/null +++ b/Core/Router.php @@ -0,0 +1,95 @@ +routes; + } + + public function getParams() + { + return $this->params; + } + + public function add($route, $params = []) + { + $route = preg_replace('/\//', '\/', $route); + $route = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[a-z-]+)', $route); + $route = preg_replace('/\{([a-z]+):([^\}]+)\}/', '(?P<\1>\2)', $route); + $route = '/^'.$route.'$/'; + + if ($this->routes[$route] = $params) { + return true; + } + return false; + } + + public function match($url) + { + $url = htmlspecialchars($url); + + foreach ($this->routes as $route => $params) { + if (preg_match($route, $url, $matches)) { + foreach ($matches as $key => $match) { + if (is_string($key)) { + $params[$key] = $match; + } + } + if ($putParams = $this->params = $params) { + return true; + } + } + } + + return false; + } + + public function dispatch($url) + { + $url = $this->removeQueryStringVariable($url); + if ($this->match($url)) { + $controller = $this->params['controller']; + $controller = $this->convertToStudlyCaps($controller); + $controller = $this->getNamespace($controller); + + if (class_exists($controller)) { + $object = new $controller(); + + $action = $this->params['action']; + $action = $this->convertToCamelCaps($action); + + if (is_callable([$object, $action])) { + $object->$action(); + } + } + } + return false; + } + + private function removeQueryStringVariable($url) + { + $parts = explode('&', $url); + return $url = $parts[0]; + } + + private function convertToStudlyCaps($string) + { + return str_replace(' ', '', ucwords(str_replace('-', ' ', $string))); + } + + private function getNamespace($controller) + { + return $namespace = 'App\Controllers\\' . $controller; + } + + private function convertToCamelCaps($string) + { + return lcfirst($this->convertToStudlyCaps($string)); + } +} diff --git a/_tests/unit/RouterTest.php b/_tests/unit/RouterTest.php new file mode 100644 index 0000000..1cb561a --- /dev/null +++ b/_tests/unit/RouterTest.php @@ -0,0 +1,69 @@ + 'Data', 'action' => 'index'], + '', + ['controller' => 'Data', 'action' => 'index'] + ], + [ + '{controller}/{action}', + [], + 'home/index', + ['controller' => 'home', 'action' => 'index'] + ], + [ + '{controller}/{id:\d+}/{action}', + [], + 'home/150/index', + ['controller' => 'home', 'action' => 'index', 'id' => '150'] + ] + ]; + } + + /** + * + * @test + * @dataProvider routeProvider + */ + public function matchingRouteSuccess($route, $params, $url, $expected_param) + { + $router = new Router(); + + $router->add($route, $params); + + $this->assertTrue($router->match($url)); + + $this->assertEquals($expected_param, $router->getParams()); + } + + /** + * + * @test + * @dataProvider routeProvider + */ + public function dispatchingRouteSuccess($route, $params, $url) + { + // $url = 'home/index'; + + $router = new Router(); + + // $router->add('{controller}/{action}'); + $router->add($route, $params); + + $this->assertTrue($router->match($url)); + + $this->assertFalse($router->dispatch($url)); + } +} diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..028dc42 --- /dev/null +++ b/public/index.php @@ -0,0 +1,9 @@ +add('', ['controller' => 'Data', 'action' => 'index']); +$router->add('{controller}/{action}'); +$router->add('{controller}/{id:\d+}/{action}'); + +$url = $_SERVER['QUERY_STRING']; +$router->dispatch($url);