dispatch(); } } /** * Add CRUD routes * Example usage: Router::resource('/example', 'CrudController'); * * @param string $route The URL location * @param string $controller Controller to handle this route * * @return void */ public static function resource(string $route, string $controller): void { /* * HTTP Verb Part (URL) Action (Method) * * GET /route indexAction * GET /route/create createAction * POST /route storeAction * GET /route/{id} showAction * GET /route/{id}/edit editAction * PUT/PATCH /route/{id} updateAction * DELETE /route/{id} destroyAction */ self::addRoute(['GET'], [$route, $controller, 'index']); self::addRoute(['GET'], [$route . '/create', $controller, 'create']); self::addRoute(['POST'], [$route, $controller, 'store']); self::addRoute(['GET'], [$route . '/[i:id]', $controller, 'show']); self::addRoute(['GET'], [$route . '/[i:id]/edit', $controller, 'edit']); self::addRoute(['PUT', 'PATCH'], [$route . '/[i:id]', $controller, 'update']); self::addRoute(['DELETE'], [$route . '/[i:id]', $controller, 'destroy']); } //-------------------------------------// protected static function setDefaultLayout(): void { self::$router->respond(function ($request, $response, $service) { $service->layout('../app/views/layouts/default.php'); }); } protected static function loadConfigRoutes(): void { if (file_exists('../route.php')) { self::$routes = require_once '../route.php'; } } /** * Add all pages in the Db to self::$routes * * @return void */ protected static function loadDbRoutes(): void { // Load all sections from Db $sections = SectionModel::selectAll('*', 'WHERE `active` = 1 ORDER BY `order` ASC'); // Return if no sections if (!_exists($sections)) { return; } // Load all pages from Db $pages = PageModel::selectAll('DISTINCT page.*', ' LEFT JOIN page_has_content ON page_has_content.page_id = page.id LEFT JOIN content ON content.id = page_has_content.content_id WHERE page.active = 1 AND content.active = 1 ORDER BY page.order ASC; '); // Return if no pages if (!_exists($pages)) { return; } // Select id column $section = array_column($sections, 'section', 'id'); // Loop through all pages foreach ($pages as $pageKey => $page) { // Skip if section isn't created / active if (!_exists($section, $page['section_id'])) { continue; } // url = /section/page $url = '/' . $section[$page['section_id']] . '/' . $page['page']; // Add route self::$routes[] = [$url, 'PageController', 'route', [$page['id']]]; } // Cache sections and pages Db::setSections($sections); Db::setPages($pages); } protected static function addRoute(array $method = [], array $data = []): void { if (!_exists($method) || !_exists($data) || count($data) < 2) { return; } $route = $data[0] ?? null; $controller = $data[1] ?? null; $action = $data[2] ?? null; $parameters = $data[3] ?? []; if (!$route || !$controller || !is_array($parameters)) { return; } // Create Klein route self::$router->respond($method, $route, function($request, $response, $service) use($controller, $action, $parameters) { // Create new Controller object $controller = '\App\Controllers\\' . $controller; $controller = new $controller(self::$router); // Complete action variable if (!$action) { $action = 'indexAction'; } else { $action .= 'Action'; } // If method does not exist in object if (!method_exists($controller, $action)) { return $controller->throw404(); } // If no valid permissions if ($controller->getAdminSection() && !$controller->getLoggedIn()) { return $controller->throw404(); } // Get URL parameters $namedParameters = array_filter($request->paramsNamed()->all(), 'is_string', ARRAY_FILTER_USE_KEY); $namedParameters = array_values($namedParameters); // Append URL parameters to the hard-coded parameters array_push($parameters, ...$namedParameters); // Call Controller action return $controller->{$action}(...$parameters); }); } public static function createNavigation(): void { // Pull from cache $sections = Db::getSections(); $pages = Db::getPages(); // [ // [ // 'section url', // 'title', // ['page url', 'title'], // ['page url', 'titleOfPage2'], // ], // [], // [], // ] $navigation = []; // Generate sections foreach ($sections as $section) { // Skip hidden sections if ($section['hide_navigation'] == '1') { continue; } // Add URL, title to ID $navigation[$section['id']] = [ $section['section'], $section['title'] ]; } // Generate pages foreach ($pages as $page) { // Skip hidden sections if (!_exists($navigation, $page['section_id'])) { continue; } // Skip hidden pages if ($page['hide_navigation'] == '1') { continue; } // Add [URL, title] to ID $navigation[$page['section_id']][] = [ $page['page'], $page['title'] ]; } self::$router->service()->navigation = $navigation; } //-------------------------------------// protected static function setHttpError(): void { self::$router->onHttpError(function($code) { $service = self::$router->service(); switch ($code) { case 404: // @Todo: find out why this was needed and remove if possible $service->escape = function (?string $string) { return htmlentities($string, ENT_QUOTES | ENT_HTML5, 'UTF-8'); }; self::$router->response()->sendHeaders(true, true); $service->pageTitle = 'Error 404 (Not Found)'; $service->render('../app/views/errors/404.php'); break; } }); } //-------------------------------------// public static function getRoutes(): array { return self::$routes; } } Router::_init();