瀏覽代碼

Все методы контроллеров теперь статичные

Добавлена поддержка именованых параметров в маршрутах

Немного подредактирован home.css
Вадим Королёв 1 年之前
父節點
當前提交
c5185c95ab

+ 7 - 7
src/controllers/ApiController.php

@@ -4,14 +4,14 @@
 class ApiController extends Controller {
 
 	// Добавление предмета
-	public function createSubject() {
+	public static function createSubject() {
 		$id = SubjectModel::create($_POST['name'], $_POST['code'], $_POST['teacher_id']);
 		$subject = SubjectModel::getById($id);
 		echo json_encode($subject);
 	}
 
 	// Обновление предмета
-	public function updateSubject() {
+	public static function updateSubject() {
 		$subject = SubjectModel::getById($_POST['id']);
 		$subject['name'] = $_POST['name'];
 		$subject['code'] = $_POST['code'];
@@ -21,12 +21,12 @@ class ApiController extends Controller {
 	}
 
 	// Удаление предмета
-	public function deleteSubject() {
+	public static function deleteSubject() {
 		SubjectModel::deleteById($_GET['id']);
 	}
 
 	// Обновление отчёта
-	public function updateReport() {
+	public static function updateReport() {
 		$report = ReportModel::getById($_POST['id']);
 
 		$fields = ['work_number', 'work_type', 'notice', 'markup'];
@@ -40,12 +40,12 @@ class ApiController extends Controller {
 	}
 
 	// Удаление отчёта
-	public function deleteReport() {
+	public static function deleteReport() {
 		ReportModel::deleteById($_GET['id']);
 	}
 
 	// Получение всех преподавателей
-	public function getTeachers() {
+	public static function getTeachers() {
 		$teachers = TeacherModel::all();
 		$output = [];
 		while ($teacher = $teachers->fetchArray(SQLITE3_ASSOC)) {
@@ -56,7 +56,7 @@ class ApiController extends Controller {
 	}
 
 	// Получение всех типов работ
-	public function getWorkTypes() {
+	public static function getWorkTypes() {
 		$worktypes = WorkTypeModel::all();
 		$output = [];
 		while ($worktype = $worktypes->fetchArray(SQLITE3_ASSOC)) {

+ 1 - 7
src/controllers/Controller.php

@@ -1,11 +1,5 @@
 <?php
-// Контроллер
+// Контроллер, родительский класс
 
 class Controller {
-	public string $request_uri;
-	
-	// Родительский класс контроллеров
-	public function __construct($request_uri = null) {
-		$this->request_uri = $request_uri;
-	}
 }

+ 2 - 2
src/controllers/GradesController.php

@@ -4,7 +4,7 @@
 class GradesController extends Controller {
 
 	// Оценки
-	public function index() {
+	public static function index() {
 		$view = new GradesView([
 			"page_title"=>"Оценки",
 			"crumbs" => ["Главная" => "/", "Оценки" => "/grades"]
@@ -13,7 +13,7 @@ class GradesController extends Controller {
 	}
 
 	// Сбор оценок
-	public function collect() {
+	public static function collect() {
 		
 		// Создаём разделяемый обработчик
 		$sh = curl_share_init();

+ 1 - 1
src/controllers/HomeController.php

@@ -4,7 +4,7 @@
 class HomeController extends Controller {
 
 	// Главная домашняя страница
-	public function index() {
+	public static function index() {
 		// Определяем текст приветствия
 		$now_hour = localtime(time(), true)['tm_hour'];
 		if ($now_hour < 6 || $now_hour > 20) {

+ 1 - 1
src/controllers/NotFoundController.php

@@ -3,7 +3,7 @@
 
 class NotFoundController {
 	// Главная страница
-	public function index() {
+	public static function index() {
 		$view = new NotFoundView();
 		$view->view();
 	}

+ 10 - 14
src/controllers/RegenController.php

@@ -4,7 +4,7 @@
 class RegenController extends Controller {
 
 	// Загрузка изображений
-	public function uploadImage() {
+	public static function uploadImage() {
 
 		if (is_uploaded_file($_FILES['file']['tmp_name'])) {
 			$mime_type = mime_content_type($_FILES['file']['tmp_name']);
@@ -30,9 +30,7 @@ class RegenController extends Controller {
 	}
 
 	// Список отчётов по дисциплине
-	public function listReports() {
-		$parts = explode("/", $this->request_uri);
-		$subject_id = end($parts);
+	public static function listReports($subject_id) {
 		
 		$reports = ReportModel::where("subject_id", $subject_id);
 		$subject = SubjectModel::getById($subject_id);
@@ -47,7 +45,7 @@ class RegenController extends Controller {
 	}
 
 	// Архив отчётов
-	public function archive() {
+	public static function archive() {
 		$subjects = SubjectModel::all();
 
 		$view = new RegenArchiveView([
@@ -59,15 +57,13 @@ class RegenController extends Controller {
 	}
 
 	// Редактирование отчёта
-	public function edit() {
-		$parts = explode("/", $this->request_uri);
-		$report_id = end($parts);
+	public function edit($report_id) {
 		$report = ReportModel::getById($report_id);
 		$subject = SubjectModel::getById($report['subject_id']);
 
 		$view = new RegenEditView([
 			"page_title" => "Regen: редактирование отчёта",
-			"crumbs" => ["Главная"=>"/", "Regen: редактирование отчёта" => "/"],
+			"crumbs" => ["Главная"=>"/", "Regen: архив" => "/regen/archive/", $subject['name'] => "/regen/archive/".$subject['id'], "Редактирование"=>"/"],
 			"markup" => $report['markup'],
 			"filename" => $subject['name']." #".$report['work_number']." - Королёв",
 			"report_id" => $report_id
@@ -76,7 +72,7 @@ class RegenController extends Controller {
 	}
 
 	// Валидация создания отчёта
-	private function validateCreation() {
+	private static function validateCreation() {
 		if (empty($_POST["number"])) {
 			// Запрос на создание
 			return 'Не указан номер работы';
@@ -85,12 +81,12 @@ class RegenController extends Controller {
 	}
 
 	// Создание отчёта
-	public function newReport() {
+	public static function newReport() {
 		$subjects = SubjectModel::all();
 		$worktypes = WorkTypeModel::all();
 
 		if (!empty($_POST)) {
-			$response = $this->validateCreation();
+			$response = self::validateCreation();
 			if ($response === true) {
 				// Валидация успешна
 
@@ -127,7 +123,7 @@ class RegenController extends Controller {
 	}
 
 	// Получение HTML
-	public function getHtml() {
+	public static function getHtml() {
 		$report = ReportModel::getById($_POST['report_id']);
 		$subject = SubjectModel::getById($report["subject_id"]);
 		$work_type = WorkTypeModel::getById($report["work_type"]);
@@ -287,7 +283,7 @@ class RegenController extends Controller {
 
 			$output .= $page_wrapped->render();
 
-			if ($this->isCountablePage($current_page_marker) != "!-") {
+			if (self::isCountablePage($current_page_marker) != "!-") {
 				$current_page_number++;
 			}
 		}

+ 5 - 0
src/css/home.css

@@ -1,4 +1,9 @@
 body {
   background-image: url('/img/wallpapers/train.jpg');
   background-color: #396690;
+  background-size: cover;
+}
+
+html {
+    height: 100%;
 }

+ 18 - 18
src/index.php

@@ -11,29 +11,29 @@ spl_autoload_register("Pockit::autoload");
 $router = new Router();
 
 // Главная
-$router->register('', ['HomeController', 'index']);
+$router->register('', 'HomeController::index');
 
 // Оценки
-$router->register('/grades', ['GradesController', 'index']);
-$router->register('/grades/get', ['GradesController', 'collect']);
+$router->register('/grades', 'GradesController::index');
+$router->register('/grades/get', 'GradesController::collect');
 
 // Regen
-$router->register('/regen/new', ['RegenController', 'newReport']);
-$router->register('/regen/upload-image', ['RegenController', 'uploadImage']);
-$router->register('/regen/edit/\d+', ['RegenController', 'edit']);
-$router->register("/regen/gethtml", ['RegenController', 'getHtml']);
-$router->register("/regen/archive", ['RegenController', 'archive']);
-$router->register("/regen/archive/\d+", ['RegenController', 'listReports']);
+$router->register('/regen/new', 'RegenController::newReport');
+$router->register('/regen/upload-image', 'RegenController::uploadImage');
+$router->register('/regen/edit/{report_id}', 'RegenController::edit');
+$router->register("/regen/gethtml", 'RegenController::getHtml');
+$router->register("/regen/archive", 'RegenController::archive');
+$router->register("/regen/archive/{subject_id}", 'RegenController::listReports');
 
 // API
-$router->register('/subjects/create', ['ApiController', 'createSubject']);
-$router->register('/subjects/update', ['ApiController', 'updateSubject']);
-$router->register('/subjects/delete', ['ApiController', 'deleteSubject']);
-$router->register('/reports/update', ['ApiController', 'updateReport']);
-$router->register('/reports/delete', ['ApiController', 'deleteReport']);
-$router->register('/teachers/read', ['ApiController', 'getTeachers']);
-$router->register('/work_types/read', ['ApiController', 'getWorkTypes']);
-
-$router->register404(['NotFoundController', 'index']);
+$router->register('/subjects/create', 'ApiController::createSubject');
+$router->register('/subjects/update', 'ApiController::updateSubject');
+$router->register('/subjects/delete', 'ApiController::deleteSubject');
+$router->register('/reports/update', 'ApiController::updateReport');
+$router->register('/reports/delete', 'ApiController::deleteReport');
+$router->register('/teachers/read', 'ApiController::getTeachers');
+$router->register('/work_types/read', 'ApiController::getWorkTypes');
+
+$router->register404('NotFoundController::index');
 
 return $router->handle($_SERVER['REQUEST_URI']);

+ 32 - 24
src/pockit.php

@@ -31,49 +31,57 @@ class Router {
 	public function handle(string $request_uri) {
 		if (preg_match('/^\/(?:css|fonts|img|jquery|js)\//', $request_uri)) {
 			// Подача как есть
-			header("Cache-Control: public, max-age=3600");
 			return false;
 		}
 
 		// Ищем подходящий маршрут
+		// TODO: кэшировать regex-выражения если приложение не в режиме разработки
 		foreach ($this->routes as $route => $callback) {
-			$pattern = '/^'.str_replace('/', '\/', $route).'\/?((?:\?|\&)\w+=\w*)*$/';
-			if (preg_match($pattern, $request_uri)) {
-				$this->invoke($callback, $request_uri);
+			// Преобразование маршрута в regex выражение
+			$pattern = preg_replace(
+				['/\//', '/{(\w+)}/'],
+				['\\\/', '(?<$1>\\w+)'],
+				$route
+			);
+			$pattern = '/^'.$pattern.'\/?((?:\?|\&)\w+=\w*)*$/';
+			if (preg_match($pattern, $request_uri, $named_groups)) {
+				// Поиск именованных групп в $named_groups
+				$named_groups = array_filter($named_groups, function($key) {
+					return !is_numeric($key);
+				}, ARRAY_FILTER_USE_KEY);
+				$this->invoke($callback, $named_groups);
 			}
 		}
 
 		// Маршрут не найден, вызываем 404!
 		header("HTTP/1.1 404 Not Found");
-		$this->invoke($this->not_found_handler, $request_uri);
+		$this->invoke($this->not_found_handler, []);
 	}
 
 	// Вызывает функцию, которую определил маршрут
-	private function invoke(callable $callback, string $request_uri) {
-		list($handler, $handle_method) = $callback;
-		$h = new $handler($request_uri);
-		$h->$handle_method();
+	private function invoke(callable $callback, array $parameters) {
+		call_user_func_array($callback, $parameters);
 		exit();
 	}
 }
 
 // Класс работы с БД
 class Database {
-    private static $db;
-    private $connection;
-    
-    private function __construct() {
-        $this->connection = new SQLite3(rootdir.'/db.sqlite3');
-    }
+	private static $db;
+	private $connection;
+	
+	private function __construct() {
+		$this->connection = new SQLite3(rootdir.'/db.sqlite3');
+	}
 
-    function __destruct() {
-        $this->connection->close();
-    }
+	function __destruct() {
+		$this->connection->close();
+	}
 
-    public static function getConnection() {
-        if (self::$db == null) {
-            self::$db = new Database();
-        }
-        return self::$db->connection;
-    }
+	public static function getConnection() {
+		if (self::$db == null) {
+			self::$db = new Database();
+		}
+		return self::$db->connection;
+	}
 }

+ 1 - 0
start.cmd

@@ -0,0 +1 @@
+start ..\tools\php-8.3.0-nts-Win32-vs16-x64\php.exe -S 127.0.0.1:9000 -t ./src ./src/index.php