Grewi
* 28.07.2023

Для решения задачи роутинга в системе имеется специальный класс 

system/core/route/route.php

В его задачи входит определение метода запроса (get/post), определение на соответствие маски и передача в метод контроллера.

После загрузки системы первым подключается файл роутера app/route/web.php 

<?php 
use electronic\core\route\route;

$route  = new route();

$route->namespace('app/controllers/index');
$route->get('/')->controller('indexController', 'index');

Функция autoloadWeb

В системе реализована специальная функция автоматической загрузки файлов роутинга из директории app/route/web. Функцию нужно вызывать после создания объекта роутера, передав экземпляр объекта в качестве параметра.

$route  = new route();
autoloadWeb($route);

Рассмотрим методы класса.

group

Позволяет формировать группы роутов, принимает два обязательных параметра: имя и функцию. Пример реализации:

$route->namespace('app\controllers\blog')->group('blog', function($route){
    $route->get('/')->controller('blogController', 'index');
    $route->get('/post')->controller('blogPostController', 'index');
 }

Имя группы является префиксом для роутов, соответственно, при написании шаблона запроса необходимо это учитывать. В данном примере, роуты получат запросы 'blog' и 'blog/post'.

namespace

Метод namespace устанавливает и сохраняет путь. После установки, каждому контроллеру в роутах будет подставляться действующее пространство имён. Метод может вызываться отдельно или в цепочке:

//Отдельно
$route->namespace('app/controllers/index');

//Цепочкой
$route->namespace('app\controllers\blog')->group('blog', function($route){
    $route->get('/')->controller('blogController', 'index');
    $route->get('/category')->controller('blogCategoryController', 'index');    
});

get post put delete all

Методы делают проверку типа запроса и соответствие с шаблоном, на пример, метод post пропустит только post запрос. Метод all пропускает все запросы.

В качестве параметра принимает строку с шаблоном запроса. Шаблон должен начинаться со слеша, если роут ведёт на корень сайта или корень группы, то передаётся строка со слешем. Шаблон запроса может состоять из простой строки или нескольких строк разделённых слешем. Роут сработает в случае полного совпадения всех строк. 

Шаблон может содержать специальные параметры, например для передачи переменных данных. Параметры могут быть обязательными и необязательными. Каждый параметр заключается в фигурные скобки, необязательный параметр закачивается на знак вопроса. Внутри фигурных скобок указывается имя параметра, которое будет доступно в \electronic\core\request::get()->name_param

$route->get('/blog/{blog_id}/{comments?}')->controller('indexController', 'index');

В данном примере запрос обязательно должен содержать первую и вторую часть, а третья может отсутствовать.

Все параметры проходят проверку через регулярное выражение, его шаблон установлен в свойстве param_regex и по умолчанию допускает русские, латинские символы, цифры,тире и знак подчёркивания.

prefix

Префиксы, это дополнительные классы-прослойки вызываемые в цепочке, как правило перед controller, если свойство autoExitController установленно false, то prefix можно устанавливать и после controller.

$route->get('/')->prefix('admin')->controller('indexController', 'index');

Файл префикса должен располагаться в app/prefix, и иметь метод index. Пример файла:

namespace app\prefix;
use app\models\users;
use app\models\user_role;
use electronic\core\config\config;

class admin
{
    public function index()
    {
        $user = users::find(user_id());
        $role = user_role::where('slug', 'admin')->get();
        $authDir = config::globals('authDir') ?? '/';
        if(!$user || $user->user_role_id != $role->id){
            redirect($authDir);
        }
    }
}

filter

Фильтр, это специальные классы, которые необходимо вызвать, например выполнить проверку на соответствие. Фильтры могут располагаться сразу после создания объекта роутера и проверять все запросы, могут разделять часть роутов, а так же вызываться из группы роутов. Фильтр не может быть установлен в цепочку, а вызывается отдельно.

$route->filter('auth');

Файл фильтра находится в app/filter и должен содержать метод index. Пример файла:

namespace app\filter;

use system\core\request\request;
use system\core\config\config;

class auth
{
    public function index()
    {
        $authDir = config::globals('authDir');
        if(isset($_POST['email']) && isset($_POST['password'])  && !user_id()){
            \system\core\user\auth::redirectFailed($authDir)->redirectSuccess('/')->login(null, null, function($auth, $user, $valid){
                if($auth->status){
                    redirect(referal_url());
                } else {
                    $authDir = config::globals('authDir');
                    redirect($authDir ?? referal_url(), $valid->data(), $error);
                }
            });
        }

        if(isset($_REQUEST['output']) && user_id()){
            \system\core\user\auth::out(function(){
                header('Location: /');
            });
        }
    }
}

controller

Метод controller вызывается в цепочке и имеет два параметра: имя класса и имя метода. Для правильной работы системы, до вызова controller необходимо определить nemespace в соответствующем методе. Контроллер должен располагаться в директории controllers. Предполагается, что контроллер должен наследоваться от корневого контроллера для сохранения иерархии, но это не является обязательным. Пример файла:

namespace app\controllers\index;

use app\controllers\controller;
use electronic\core\view\view;
use electronic\core\lang\lang;

class indexController extends controller
{
    public function index()
    {
        $this->title(lang::main('home'));
        $this->data['userType'] = 'admin';
        new view('index/index', $this->data);
    }
}

exit

Метод очевидным образом останавливает цепочку. Используется при значении autoExitController = false, например при необходимости установки методов посде контроллера.

$route->get('/')->controller('indexController', 'index')->prefix('user')->exit();

getUrl

Метод возвращает массив $url

autoExitGroup

Метод устанавливает значения свойства autoExitGroup, в качестве параметра принимает булевое значение.
При значении свойства true, скрипт автоматически останавливается после прохождения группы роутов в методе group

$route->autoExitGroup(true);
$route->group('users', function($route){
   $route->get('/')->controller('userController', 'index');
   $route->get('/edit')->controller('userController', 'edit');
});
 $route->get('/users/info')->controller('userController', 'info');

В данном примере, последний роут никогда не сработает т.к. при обращении к users будет срабатывать группа, а autoExitGroup остановит исполнение программы после её исполнения.

autoExitController

Функция меняет значение свойства autoExitController, в качестве параметра принимает булевое значение. При значении $autoExitController = true после вызова метода controller программа остановится, иначе будет необходимо вызывать метод exit()

Grewi 2024