переработка шаблонизатора, работа над аутентификацией

This commit is contained in:
Arsen Mirzaev Tatyano-Muradovich 2023-02-27 00:43:00 +10:00
parent 6360d4cddb
commit 0aae5b6558
9 changed files with 318 additions and 174 deletions

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace mirzaev\site\account\controllers; namespace mirzaev\site\account\controllers;
// Файлы проекта // Файлы проекта
use mirzaev\site\account\views\manager; use mirzaev\site\account\views\templater;
use mirzaev\site\account\models\core as models; use mirzaev\site\account\models\core as models;
use mirzaev\site\account\models\account_model as account; use mirzaev\site\account\models\account_model as account;
use mirzaev\site\account\models\session_model as session; use mirzaev\site\account\models\session_model as session;
@ -28,73 +28,69 @@ use mirzaev\vk\robots\user as robot;
*/ */
class core extends controller class core extends controller
{ {
/** /**
* Переменные окружения * Переменные окружения
*/ */
protected robot $vk; protected robot $vk;
/** /**
* Переменные окружения * Конструктор
*/ *
protected array $variables = []; * @return void
*/
public function __construct()
{
parent::__construct();
/** // Инициализация ядра моделей (соединение с базой данных...)
* Конструктор new models();
*
* @return void
*/
public function __construct()
{
parent::__construct();
// Инициализация ядра моделей (соединение с базой данных...) // Инициализация шаблонизатора представлений
new models(); $this->view = new templater;
// Инициализация журнала ошибок // Инициализация журнала ошибок
$this->variables['errors'] = [ $this->view->errors = [
'session' => [], 'session' => [],
'account' => [], 'account' => [],
'vk' => [] 'vk' => []
]; ];
// Инициализация даты до которой будет активна сессия // Инициализация даты до которой будет активна сессия
$expires = time() + 604800; $expires = time() + 604800;
// Инициализация сессии (без журналирования) // Инициализация сессии (без журналирования)
$this->variables['session'] = new session($_COOKIE["session"] ?? null, $expires) ?? header('Location: https://mirzaev.sexy/error?code=500&text=Не+удалось+инициализировать+сессию'); $this->view->session = new session($_COOKIE["session"] ?? null, $expires) ??
header('Location: https://mirzaev.sexy/error?code=500&text=Не+удалось+инициализировать+сессию');
if ($_COOKIE["session"] ?? null !== $this->variables['session']->hash) { if ($_COOKIE["session"] ?? null !== $this->view->session->hash) {
// Изменился хеш сессии (подразумевается, что сессия устарела) // Изменился хеш сессии (подразумевается, что сессия устарела)
// Запись хеша новой сессии // Запись хеша новой сессии
setcookie('session', $this->variables['session']->hash, [ setcookie('session', $this->view->session->hash, [
'expires' => $expires, 'expires' => $expires,
'domain' => 'mirzaev.sexy', 'domain' => 'mirzaev.sexy',
'path' => '/', 'path' => '/',
'secure' => true, 'secure' => true,
'httponly' => true, 'httponly' => true,
'samesite' => 'strict' 'samesite' => 'strict'
]); ]);
}
// Инициализация аккаунта (без журналирования)
$this->variables['account'] = $this->variables['session']->account();
if ($this->variables['account'] instanceof _document) {
// Инициализирован аккаунт
// Инициализация аккаунта ВКонтакте (без журналирования)
$this->variables['vk'] = account::vk($this->variables['account']);
if ($this->variables['vk'] instanceof _document) {
// Инициализирован аккаунт ВКонтакте
// Инициализация робота для аккаунта ВКонтакте
$this->vk = vk::init()->user(key: $this->variables['vk']->access['key']);
} else unset($this->variables['account'], $this->variables['vk']);
}
// Инициализация препроцессора представления
$this->view = new manager;
} }
// Инициализация аккаунта (без журналирования)
$this->view->account = $this->view->session->account();
if ($this->view->account instanceof _document) {
// Инициализирован аккаунт
// Инициализация аккаунта ВКонтакте (без журналирования)
$this->variables['vk'] = account::vk($this->variables['account']);
if ($this->variables['vk'] instanceof _document) {
// Инициализирован аккаунт ВКонтакте
// Инициализация робота для аккаунта ВКонтакте
$this->vk = vk::init()->user(key: $this->variables['vk']->access['key']);
} else unset($this->variables['account'], $this->variables['vk']);
}
}
} }

View File

@ -22,59 +22,12 @@ final class index_controller extends core
*/ */
public function index(array $parameters = []): ?string public function index(array $parameters = []): ?string
{ {
// Инициализация загружаемых категорий // Инициализация узлов
$this->variables['include'] = [ $this->view->nodes = [
'head' => ['self'], 'account' => $this->view->render(DIRECTORY_SEPARATOR . 'nodes' . DIRECTORY_SEPARATOR . (isset($this->account) ? 'profile.html' : 'authentication.html'))
'body' => ['self']
]; ];
// Инициализация бегущей строки
$this->variables['hotline'] = [
'id' => $this->variables['request']['id'] ?? 'hotline'
];
// Инициализация параметров бегущей строки
$this->variables['hotline']['parameters'] = [
// 'step' => 2
];
// Инициализация аттрибутов бегущей строки
$this->variables['hotline']['attributes'] = [];
// Инициализация элементов бегущей строки
$this->variables['hotline']['elements'] = [
['content' => '1'],
[
'tag' => 'article',
'content' => '2'
],
['content' => '3'],
['content' => '4'],
['content' => '5'],
['content' => '6'],
['content' => '7'],
['content' => '8'],
['content' => '9'],
['content' => '10'],
['content' => '11'],
['content' => '12'],
['content' => '13'],
['content' => '14'],
['content' => '15']
];
// Инициализация бегущей строки
$this->variables['graph'] = [
'id' => $this->variables['request']['id'] ?? 'graph'
];
// Инициализация аттрибутов бегущей строки
$this->variables['graph']['attributes'] = [];
// Инициализация элементов бегущей строки
$this->variables['graph']['elements'] = [];
// Генерация представления // Генерация представления
return $this->view->render(DIRECTORY_SEPARATOR . 'index.html', $this->variables); return $this->view->render(DIRECTORY_SEPARATOR . 'index.html');
} }
} }

View File

@ -222,76 +222,72 @@ final class session_model extends core
/** /**
* Записать * Записать
* *
* Ищет свойство в инстанции сессии, если не находит, то ищет его в инстанции документа сессии из базы данных, * Записывает свойство в инстанцию документа сессии из базы данных
* затем записывает в него переданные данные. Динамическая инициализация свойств происходит в инстанции
* документа сессии из базы данных
* *
* @param string $name Название свойства * @param string $name Название
* @param mixed $value Содержимое для записи * @param mixed $value Содержимое
* *
* @return void * @return void
*/ */
public function __set(string $name, mixed $value = null): void public function __set(string $name, mixed $value = null): void
{ {
if (isset($this->{$name})) $this->{$name} = $value; $this->document->{$name} = $value;
else $this->document->{$name} = $value;
} }
/** /**
* Прочитать * Прочитать
* *
* Ищет свойство в инстанции сессии, если не находит, то ищет его в инстанции документа сессии из базы данных * Читает свойство из инстанции документа сессии из базы данных
* *
* @param string $name Название свойства * @param string $name Название
* *
* @return mixed Данные свойства инстанции сессии или инстанции документа сессии из базы данных * @return mixed Данные свойства инстанции сессии или инстанции документа сессии из базы данных
*/ */
public function __get(string $name): mixed public function __get(string $name): mixed
{ {
return $this->{$name} ?? $this->document->{$name}; return $this->document->{$name};
} }
/** /**
* Проверить инициализированность * Проверить инициализированность
* *
* Ищет свойство в инстанции сессии, если не находит, то ищет его в инстанции документа сессии из базы данных, * Проверяет инициализированность свойства в инстанции документа сессии из базы данных
* затем проверяет его инициализированность через встроенную функцию isset()
* *
* @param string $name Название свойства * @param string $name Название
* *
* @return bool Свойство инициализировано? * @return bool Свойство инициализировано?
*/ */
public function __isset(string $name): bool public function __isset(string $name): bool
{ {
return isset($this->{$name}) || isset($this->document->{$name}); return isset($this->document->{$name});
} }
/** /**
* Удалить * Удалить
* *
* Деинициализирует свойство в инстанции сессии и в инстанции документа сессии из базы данных * Деинициализировать свойство в инстанции документа сессии из базы данных
* *
* @param string $name Название свойства * @param string $name Название
* *
* @return void * @return void
*/ */
public function __unset(string $name): void public function __unset(string $name): void
{ {
unset($this->{$name}, $this->document->{$name}); unset($this->document->{$name});
} }
/** /**
* Выполнить метод * Выполнить метод
* *
* Ищет метод в инстанции сессии, если не находит, то ищет его в инстанции документа сессии из базы данных * Выполнить метод в инстанции документа сессии из базы данных
* *
* @param string $name Название метода * @param string $name Название
* @param array $arguments Аргументы * @param array $arguments Аргументы
* *
* @return void * @return void
*/ */
public function __call(string $name, array $arguments = []): mixed public function __call(string $name, array $arguments = []): mixed
{ {
return method_exists($this, $name) ? $this->{$name}($arguments) : $this->document->{$name}($arguments); return $this->document->{$name}($arguments);
} }
} }

View File

@ -0,0 +1,33 @@
i.arrow.right {
box-sizing: border-box;
position: relative;
display: block;
transform: scale(var(--ggs,1));
width: 22px;
height: 22px
}
i.arrow.right::after,
i.arrow.right::before {
content: "";
display: block;
box-sizing: border-box;
position: absolute;
right: 3px
}
i.arrow.right::after {
width: 8px;
height: 8px;
border-top: 2px solid;
border-right: 2px solid;
transform: rotate(45deg);
bottom: 7px
}
i.arrow.right::before {
width: 16px;
height: 2px;
bottom: 10px;
background: currentColor
}

View File

@ -1,47 +1,32 @@
{% extends "core.html" %} {% extends "core.html" %}
{% use 'nodes/account.html' with css as account_css, body as account_body, js as account_js %}
{% use "core.html" with css as core_css, body as core_body, js as core_js, js_init as core_js_init %} {% use "core.html" with css as core_css, body as core_body, js as core_js, js_init as core_js_init %}
{% use "header.html" with css as header_css, body as header_body, js as header_js, js_init as header_js_init %} {% use "header.html" with css as header_css, body as header_body, js as header_js, js_init as header_js_init %}
{% use "aside.html" with css as aside_css, body as aside_body, js as aside_js, js_init as aside_js_init %} {% use "aside.html" with css as aside_css, body as aside_body, js as aside_js, js_init as aside_js_init %}
{% use 'graph/index.html' with css as graph_css, body as graph_body, js as graph_js, js_init as graph_js_init %}
{% block css %} {% block css %}
{{ block('core_css') }} {{ block('core_css') }}
{{ block('header_css') }} {{ block('header_css') }}
{{ block('aside_css') }} {{ block('aside_css') }}
{{ block('graph_css') }}
{{ block('account_css') }}
{% endblock %} {% endblock %}
{% block body %} {% block body %}
{{ block('core_body') }}
{{ block('aside_body') }}
{{ block('header_body') }}
<main> <main>
<noscript>К сожалению мой сайт ещё пока не готов для работы без javascript</noscript> <noscript>К сожалению мой сайт ещё пока не готов для работы без javascript</noscript>
{% block main %} {% block main %}
{{ block('account_body') }} {{ nodes.account|raw }}
{% endblock %} {% endblock %}
{{ block('graph_body') }}
</main> </main>
{# {% include 'footer.html' %} #}
{# <div class="background"></div> #}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
{{ block('core_js') }} {{ block('core_js') }}
{{ block('header_js') }} {{ block('header_js') }}
{{ block('aside_js') }} {{ block('aside_js') }}
{{ block('graph_js') }}
{{ block('account_js') }}
{% endblock %} {% endblock %}
{% block js_init %} {% block js_init %}
{{ block('core_js_init') }} {{ block('core_js_init') }}
{{ block('header_js_init') }} {{ block('header_js_init') }}
{{ block('aside_js_init') }} {{ block('aside_js_init') }}
{{ block('graph_js_init') }}
{% endblock %} {% endblock %}

View File

@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace mirzaev\site\account\views;
use mirzaev\minimal\controller;
use Twig\Loader\FilesystemLoader;
use Twig\Environment as view;
/**
* Менеджер представлений
*
* @package mirzaev\site\account\controllers
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class manager extends controller
{
public function render(string $file, array $vars = []): ?string
{
// Генерация представления
return (new view(new FilesystemLoader(VIEWS)))->render($file, $vars);
}
}

View File

@ -0,0 +1,30 @@
{% block css %}
<link type="text/css" rel="stylesheet" href="/css/account.css">
<link type="text/css" rel="stylesheet" href="/css/icons/arrow_right.css">
{% endblock %}
{% block body %}
<section id="authentication">
{% if account %}
{{ account.getKey() }}
{% if vk %}
{{ vk.mail }}
{% endif %}
{% else %}
<section class="header unselectable">
<h1>Аутентификация</h1>
</section>
<section class="body">
<label>
<input type="text" name="mail" id="mail" value="{{ account.mail ?? session.buffer.mail ?? cookie.buffer_mail }}" oninplut="remember('mail', this.value, 2000)">
<button class="accept" onclick="account.check(this.parentElement.querySelector('[name=mail]').value) ? account.authentication() : account.registration()"><i class="arrow right"></i></button>
</label>
<input type="password" name="password" id="password">
</section>
{% endif %}
</section>
{% endblock %}
{% block js %}
<script type="text/javascript" src="/js/account.js"></script>
{% endblock %}

View File

@ -0,0 +1,176 @@
<?php
declare(strict_types=1);
namespace mirzaev\site\account\views;
// Файлы проекта
use mirzaev\minimal\controller;
// Шаблонизатор представлений
use Twig\Loader\FilesystemLoader,
Twig\Environment as twig;
// Встроенные библиотеки
use ArrayAccess;
/**
* Шаблонизатор представлений
*
* @package mirzaev\site\account\controllers
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class templater extends controller implements ArrayAccess
{
/**
* Реестр глобальных переменных
*/
public array $variables = [];
/**
* Инстанция окружения twig
*/
public twig $twig;
/**
* Конструктор
*
* @return void
*/
public function __construct()
{
// Инициализация шаблонизатора
$this->twig = new twig(new FilesystemLoader(VIEWS));
// Инициализация глобальных переменных
$this->twig->addGlobal('cookie', $_COOKIE);
}
/**
* Отрисовка HTML-документа
*
* @param string $file Относительный директории представлений путь до файла представления
* @param ?array $variables Реестр переменных
*
* @return ?string HTML-документ
*/
public function render(string $file, ?array $variables = null): ?string
{
// Генерация представления
return $this->twig->render($file, $variables ?? $this->variables);
}
/**
* Записать
*
* Записывает переменную в реестр глобальных переменных
*
* @param string $name Название
* @param mixed $value Содержимое
*
* @return void
*/
public function __set(string $name, mixed $value = null): void
{
$this->variables[$name] = $value;
}
/**
* Прочитать
*
* Читает переменную из реестра глобальных переменных
*
* @param string $name Название
*
* @return mixed Данные переменной из реестра глобальных переменных
*/
public function __get(string $name): mixed
{
return $this->variables[$name];
}
/**
* Проверить инициализированность
*
* Проверяет инициализированность переменной в буфере переменных представления
*
* @param string $name Название
*
* @return bool Переменная инициализирована?
*/
public function __isset(string $name): bool
{
return isset($this->variables[$name]);
}
/**
* Удалить
*
* Деинициализирует переменную в реестре глобальных переменных
*
* @param string $name Название
*
* @return void
*/
public function __unset(string $name): void
{
unset($this->variables[$name]);
}
/**
* Записать
*
* Записывает переменную в реестр глобальных переменных
*
* @param mixed $offset Сдвиг, либо идентификатор
* @param mixed $value Содержимое
*
* @return void
*/
public function offsetSet(mixed $offset, mixed $value): void
{
$this->variables[$offset] = $value;
}
/**
* Прочитать
*
* Читает переменную из реестра глобальных переменных
*
* @param mixed $offset Сдвиг, либо идентификатор
*
* @return mixed Данные переменной из реестра глобальных переменных
*/
public function &offsetGet(mixed $offset): mixed
{
return $this->variables[$offset];
}
/**
* Проверить инициализированность
*
* Проверяет инициализированность переменной в реестре глобальных переменных
*
* @param mixed $offset Сдвиг, либо идентификатор
*
* @return bool Переменная инициализирована?
*/
public function offsetExists(mixed $offset): bool
{
return isset($this->variables[$offset]);
}
/**
* Удалить
*
* Деинициализирует переменную в реестре глобальных переменных
*
* @param mixed $offset Сдвиг, либо идентификатор
*
* @return void
*/
public function offsetUnset(mixed $offset): void
{
unset($this->variables[$offset]);
}
}