'text/css', 'js' => 'application/javascript', 'png' => 'image/png', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'gif' => 'image/gif', 'webp' => 'image/webp', 'svg' => 'image/svg+xml', 'ico' => 'image/x-icon', 'json' => 'application/json', 'woff' => 'font/woff', 'woff2' => 'font/woff2', 'ttf' => 'font/ttf', 'eot' => 'application/vnd.ms-fontobject', ]; $extension = strtolower(pathinfo($physicalPath, PATHINFO_EXTENSION)); if (isset($mimeTypes[$extension])) { header('Content-Type: ' . $mimeTypes[$extension]); } // Запрещаем кэширование для разработки, в продакшене можно увеличить время header('Cache-Control: public, max-age=3600'); // Отправляем файл readfile($physicalPath); exit; } } // Простой роутер class Router { private $routes = []; public function add($pattern, $handler) { $this->routes[$pattern] = $handler; } public function handle($uri) { // Убираем базовый URL если есть $basePath = parse_url(SITE_URL, PHP_URL_PATH) ?? ''; $uri = str_replace($basePath, '', $uri); $uri = parse_url($uri, PHP_URL_PATH) ?? '/'; foreach ($this->routes as $pattern => $handler) { if ($this->match($pattern, $uri)) { return $this->callHandler($handler, $this->params); } } // 404 http_response_code(404); include 'views/errors/404.php'; exit; } private function match($pattern, $uri) { $pattern = preg_replace('/\{(\w+)\}/', '(?P<$1>[^/]+)', $pattern); $pattern = "#^$pattern$#"; if (preg_match($pattern, $uri, $matches)) { $this->params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY); return true; } return false; } private function callHandler($handler, $params) { if (is_callable($handler)) { return call_user_func_array($handler, array_values($params)); } if (is_string($handler)) { list($controller, $method) = explode('@', $handler); $controllerFile = "controllers/{$controller}.php"; if (file_exists($controllerFile)) { require_once $controllerFile; $controllerInstance = new $controller(); if (method_exists($controllerInstance, $method)) { return call_user_func_array([$controllerInstance, $method], array_values($params)); } } } throw new Exception("Handler not found"); } } // Инициализация роутера $router = new Router(); // Маршруты $router->add('/', 'DashboardController@index'); $router->add('/dashboard', 'DashboardController@index'); $router->add('/index.php', 'DashboardController@index'); $router->add('/login', 'AuthController@login'); $router->add('/logout', 'AuthController@logout'); $router->add('/register', 'AuthController@register'); // Книги $router->add('/books', 'BookController@index'); $router->add('/book/all/{id}', 'BookController@viewAll'); $router->add('/books/create', 'BookController@create'); $router->add('/books/{id}/edit', 'BookController@edit'); $router->add('/books/{id}/delete', 'BookController@delete'); $router->add('/books/delete-all', 'BookController@deleteAll'); $router->add('/books/{id}/normalize', 'BookController@normalizeContent'); $router->add('/books/{id}/regenerate-token', 'BookController@regenerateToken'); // Главы $router->add('/books/{book_id}/chapters', 'ChapterController@index'); $router->add('/books/{book_id}/chapters/create', 'ChapterController@create'); $router->add('/chapters/{id}/edit', 'ChapterController@edit'); $router->add('/chapters/{id}/delete', 'ChapterController@delete'); $router->add('/chapters/preview', 'ChapterController@preview'); $router->add('/books/{id}/chapters/update-order', 'ChapterController@updateOrder'); // Серии $router->add('/series', 'SeriesController@index'); $router->add('/series/create', 'SeriesController@create'); $router->add('/series/{id}/edit', 'SeriesController@edit'); $router->add('/series/{id}/delete', 'SeriesController@delete'); $router->add('/series/{id}/add-book', 'SeriesController@addBook'); $router->add('/series/{id}/remove-book/{book_id}', 'SeriesController@removeBook'); $router->add('/series/{id}/update-order', 'SeriesController@updateBookOrder'); // Профиль $router->add('/profile', 'UserController@profile'); $router->add('/profile/update', 'UserController@updateProfile'); // Экспорт с параметром формата //публичный экспорт $router->add('/export/shared/{share_token}/{format}', 'ExportController@exportShared'); $router->add('/export/shared/{share_token}', 'ExportController@exportShared'); // по умолчанию pdf //авторсикй экспорт $router->add('/export/{book_id}/{format}', 'ExportController@export'); $router->add('/export/{book_id}', 'ExportController@export'); // по умолчанию pdf // Публичные страницы $router->add('/book/{share_token}', 'BookController@viewPublic'); $router->add('/author/{id}', 'UserController@viewPublic'); $router->add('/series/{id}/view', 'SeriesController@viewPublic'); // Администрирование $router->add('/admin/users', 'AdminController@users'); $router->add('/admin/add-user', 'AdminController@addUser'); $router->add('/admin/user/{user_id}/toggle-status', 'AdminController@toggleUserStatus'); $router->add('/admin/user/{user_id}/delete', 'AdminController@deleteUser'); // Обработка запроса $requestUri = $_SERVER['REQUEST_URI']; $router->handle($requestUri); // Редирект с корня на dashboard для авторизованных $router->add('/', function() { if (is_logged_in()) { header("Location: " . SITE_URL . "/dashboard"); } else { header("Location: " . SITE_URL . "/login"); } exit; }); ?>