626 lines
24 KiB
PHP
Executable File
626 lines
24 KiB
PHP
Executable File
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace mirzaev\ebala\controllers;
|
||
|
||
// Файлы проекта
|
||
use mirzaev\ebala\controllers\core,
|
||
mirzaev\ebala\controllers\traits\errors,
|
||
mirzaev\ebala\models\account,
|
||
mirzaev\ebala\models\market;
|
||
|
||
// Библиотека для ArangoDB
|
||
use ArangoDBClient\Document as _document;
|
||
|
||
// Встроенные библиотеки
|
||
use exception;
|
||
|
||
/**
|
||
* Контроллер сессии
|
||
*
|
||
* @package mirzaev\ebala\controllers
|
||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||
*/
|
||
final class session extends core
|
||
{
|
||
use errors;
|
||
|
||
/**
|
||
* Записать номер сотрудника во все буферы сессии
|
||
*
|
||
* Проверяет существование аккаунта сотрудника с этим номером
|
||
* и запоминает для использования в процессе аутентификации
|
||
*
|
||
* @param array $parameters Параметры запроса
|
||
*
|
||
* @return void В буфер вывода JSON-документ с запрашиваемыми параметрами
|
||
*/
|
||
public function worker(array $parameters = []): void
|
||
{
|
||
// Инициализация буфера ответа
|
||
$buffer = [];
|
||
|
||
// Инициализация реестра возвращаемых параметров
|
||
$return = explode(',', $parameters['return'], 50);
|
||
|
||
try {
|
||
// Проверка наличия обязательных параметров
|
||
if (empty($parameters['worker'])) throw new exception('Необходимо передать номер');
|
||
|
||
// Очистка всего кроме цифр, а потом поиск 10 первых чисел (без восьмёрки)
|
||
preg_match('/^\d(\d{10})/', preg_replace("/[^\d]/", "", $parameters['worker']), $matches);
|
||
|
||
// Инициализация номера
|
||
$parameters['worker'] = isset($matches[1]) ? 7 . $matches[1] : $parameters['worker'];
|
||
|
||
// Вычисление длины
|
||
$length = mb_strlen($parameters['worker']);
|
||
|
||
// Проверка параметров на соответствование требованиям
|
||
if ($length === 0) throw new exception('Номер не может быть пустым');
|
||
if ($length !== 11) throw new exception('Номер должен иметь 11 цифр');
|
||
if (preg_match_all('/[^\d\(\)\-\s\r\n\t\0]+/u', $parameters['worker'], $matches) > 0) throw new exception('Нельзя использовать символы: ' . implode(', ', ...$matches));
|
||
|
||
if ($remember = isset($parameters['remember']) && $parameters['remember'] === '1') {
|
||
// Запрошено запоминание
|
||
|
||
// Запись в cookie
|
||
setcookie('entry_number', $parameters['worker'], [
|
||
'expires' => strtotime('+1 day'),
|
||
'path' => '/',
|
||
'secure' => true,
|
||
'httponly' => true,
|
||
'samesite' => 'strict'
|
||
]);
|
||
}
|
||
|
||
// Поиск аккаунта
|
||
$account = account::read('d.number == "' . $parameters['worker'] . '"', amount: 1);
|
||
|
||
// Генерация ответа по запрашиваемым параметрам
|
||
foreach ($return as $parameter) match ($parameter) {
|
||
'exist' => $buffer['exist'] = isset($account),
|
||
'account' => (function () use ($parameters, $remember, &$buffer) {
|
||
// Запись в буфер сессии
|
||
if ($remember) $this->session->write(['entry' => ['number' => $parameters['worker']]], $this->errors);
|
||
|
||
// Поиск аккаунта и запись в буфер вывода
|
||
$buffer['account'] = (new account($this->session, 'worker', $this->errors))?->instance() instanceof _document;
|
||
})(),
|
||
'verify' => $buffer['verify'] = true,
|
||
'errors' => null,
|
||
default => throw new exception("Параметр не найден: $parameter")
|
||
};
|
||
} catch (exception $e) {
|
||
// Запись в реестр ошибок
|
||
$this->errors['session'][] = [
|
||
'text' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'stack' => $e->getTrace()
|
||
];
|
||
}
|
||
|
||
// Запись реестра ошибок в буфер ответа
|
||
if (in_array('errors', $return, true)) $buffer['errors'] = self::parse_only_text($this->errors);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Type: application/json');
|
||
header('Content-Encoding: none');
|
||
header('X-Accel-Buffering: no');
|
||
|
||
// Инициализация буфера вывода
|
||
ob_start();
|
||
|
||
// Генерация ответа
|
||
echo json_encode($buffer);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Length: ' . ob_get_length());
|
||
|
||
// Отправка и деинициализация буфера вывода
|
||
ob_end_flush();
|
||
flush();
|
||
|
||
// Запись в буфер сессии
|
||
if (!in_array('account', $return, true) && ($remember ?? false))
|
||
$this->session->write(['entry' => ['number' => $parameters['worker']]]);
|
||
}
|
||
|
||
/**
|
||
* Записать идентификатор администратора во все буферы сессии
|
||
*
|
||
* Проверяет существование аккаунта администратора с этим идентификатором
|
||
* и запоминает для использования в процессе аутентификации
|
||
*
|
||
* @param array $parameters Параметры запроса
|
||
*
|
||
* @return void В буфер вывода JSON-документ с запрашиваемыми параметрами
|
||
*/
|
||
public function administrator(array $parameters = []): void
|
||
{
|
||
// Инициализация буфера ответа
|
||
$buffer = [];
|
||
|
||
// Инициализация реестра возвращаемых параметров
|
||
$return = explode(',', $parameters['return'], 50);
|
||
|
||
try {
|
||
// Проверка наличия обязательных параметров
|
||
if (empty($parameters['administrator'])) throw new exception('Необходимо передать идентификатор');
|
||
|
||
// Очистка всего кроме цифр, а потом поиск 10 первых чисел (без восьмёрки)
|
||
preg_match('/^\d{3,12}/', preg_replace("/[^\d]/", "", $parameters['administrator']), $matches);
|
||
|
||
// Инициализация номера
|
||
$parameters['administrator'] = $matches[0];
|
||
|
||
// Вычисление длины
|
||
$length = mb_strlen($parameters['administrator']);
|
||
|
||
// Проверка параметров на соответствование требованиям
|
||
if ($length === 0) throw new exception('Идентификатор аккаунта не может быть пустым');
|
||
if ($length > 12) throw new exception('Идентификатор аккаунта должен иметь не более 12 цифр');
|
||
if (preg_match_all('/[^\d\(\)\-\s\r\n\t\0]+/u', $parameters['administrator'], $matches) > 0) throw new exception('Нельзя использовать символы: ' . implode(', ', ...$matches));
|
||
|
||
if ($remember = isset($parameters['remember']) && $parameters['remember'] === '1') {
|
||
// Запрошено запоминание
|
||
|
||
// Запись в cookie
|
||
setcookie(
|
||
'entry__key',
|
||
$parameters['administrator'],
|
||
[
|
||
'expires' => strtotime('+1 day'),
|
||
'path' => '/',
|
||
'secure' => true,
|
||
'httponly' => true,
|
||
'samesite' => 'strict'
|
||
]
|
||
);
|
||
}
|
||
|
||
// Поиск аккаунта
|
||
$account = account::read('d._key == "' . $parameters['administrator'] . '"', amount: 1);
|
||
|
||
// Генерация ответа по запрашиваемым параметрам
|
||
foreach ($return as $parameter) match ($parameter) {
|
||
'exist' => $buffer['exist'] = isset($account),
|
||
'account' => (function () use ($parameters, $remember, &$buffer) {
|
||
// Запись в буфер сессии
|
||
if ($remember) $this->session->write(['entry' => ['_key' => $parameters['administrator']]], $this->errors);
|
||
|
||
// Поиск аккаунта и запись в буфер вывода
|
||
$buffer['account'] = (new account($this->session, 'administrator', $this->errors))?->instance() instanceof _document;
|
||
})(),
|
||
'verify' => $buffer['verify'] = true,
|
||
'errors' => null,
|
||
default => throw new exception("Параметр не найден: $parameter")
|
||
};
|
||
} catch (exception $e) {
|
||
// Запись в реестр ошибок
|
||
$this->errors['session'][] = [
|
||
'text' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'stack' => $e->getTrace()
|
||
];
|
||
}
|
||
|
||
// Запись реестра ошибок в буфер ответа
|
||
if (in_array('errors', $return, true)) $buffer['errors'] = self::parse_only_text($this->errors);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Type: application/json');
|
||
header('Content-Encoding: none');
|
||
header('X-Accel-Buffering: no');
|
||
|
||
// Инициализация буфера вывода
|
||
ob_start();
|
||
|
||
// Генерация ответа
|
||
echo json_encode($buffer);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Length: ' . ob_get_length());
|
||
|
||
// Отправка и деинициализация буфера вывода
|
||
ob_end_flush();
|
||
flush();
|
||
|
||
// Запись в буфер сессии
|
||
if (!in_array('account', $return, true) && ($remember ?? false))
|
||
$this->session->write(['entry' => ['_key' => $parameters['administrator']]]);
|
||
}
|
||
|
||
/**
|
||
* Записать идентификатор оператора во все буферы сессии
|
||
*
|
||
* Проверяет существование аккаунта оператора с этим идентификатором
|
||
* и запоминает для использования в процессе аутентификации
|
||
*
|
||
* @param array $parameters Параметры запроса
|
||
*
|
||
* @return void В буфер вывода JSON-документ с запрашиваемыми параметрами
|
||
*/
|
||
public function operator(array $parameters = []): void
|
||
{
|
||
// Инициализация буфера ответа
|
||
$buffer = [];
|
||
|
||
// Инициализация реестра возвращаемых параметров
|
||
$return = explode(',', $parameters['return'], 50);
|
||
|
||
try {
|
||
// Проверка наличия обязательных параметров
|
||
if (empty($parameters['operator'])) throw new exception('Необходимо передать идентификатор');
|
||
|
||
// Очистка всего кроме цифр, а потом поиск 10 первых чисел (без восьмёрки)
|
||
preg_match('/^\d{3,12}/', preg_replace("/[^\d]/", "", $parameters['operator']), $matches);
|
||
|
||
// Инициализация номера
|
||
$parameters['operator'] = $matches[0];
|
||
|
||
// Вычисление длины
|
||
$length = mb_strlen($parameters['operator']);
|
||
|
||
// Проверка параметров на соответствование требованиям
|
||
if ($length === 0) throw new exception('Идентификатор аккаунта не может быть пустым');
|
||
if ($length > 12) throw new exception('Идентификатор аккаунта должен иметь не более 12 цифр');
|
||
if (preg_match_all('/[^\d\(\)\-\s\r\n\t\0]+/u', $parameters['operator'], $matches) > 0) throw new exception('Нельзя использовать символы: ' . implode(', ', ...$matches));
|
||
|
||
if ($remember = isset($parameters['remember']) && $parameters['remember'] === '1') {
|
||
// Запрошено запоминание
|
||
|
||
// Запись в cookie
|
||
setcookie('entry__key', $parameters['operator'], [
|
||
'expires' => strtotime('+1 day'),
|
||
'path' => '/',
|
||
'secure' => true,
|
||
'httponly' => true,
|
||
'samesite' => 'strict'
|
||
]);
|
||
}
|
||
|
||
// Поиск аккаунта
|
||
$account = account::read('d._key == "' . $parameters['operator'] . '"', amount: 1);
|
||
|
||
// Генерация ответа по запрашиваемым параметрам
|
||
foreach ($return as $parameter) match ($parameter) {
|
||
'exist' => $buffer['exist'] = isset($account),
|
||
'account' => (function () use ($parameters, $remember, &$buffer) {
|
||
// Запись в буфер сессии
|
||
if ($remember) $this->session->write(['entry' => ['_key' => $parameters['operator']]], $this->errors);
|
||
|
||
// Поиск аккаунта и запись в буфер вывода
|
||
$buffer['account'] = (new account($this->session, 'operator', $this->errors))?->instance() instanceof _document;
|
||
})(),
|
||
'verify' => $buffer['verify'] = true,
|
||
'errors' => null,
|
||
default => throw new exception("Параметр не найден: $parameter")
|
||
};
|
||
} catch (exception $e) {
|
||
// Запись в реестр ошибок
|
||
$this->errors['session'][] = [
|
||
'text' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'stack' => $e->getTrace()
|
||
];
|
||
}
|
||
|
||
// Запись реестра ошибок в буфер ответа
|
||
if (in_array('errors', $return, true)) $buffer['errors'] = self::parse_only_text($this->errors);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Type: application/json');
|
||
header('Content-Encoding: none');
|
||
header('X-Accel-Buffering: no');
|
||
|
||
// Инициализация буфера вывода
|
||
ob_start();
|
||
|
||
// Генерация ответа
|
||
echo json_encode($buffer);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Length: ' . ob_get_length());
|
||
|
||
// Отправка и деинициализация буфера вывода
|
||
ob_end_flush();
|
||
flush();
|
||
|
||
// Запись в буфер сессии
|
||
if (!in_array('account', $return, true) && ($remember ?? false))
|
||
$this->session->write(['entry' => ['_key' => $parameters['operator']]]);
|
||
}
|
||
|
||
/**
|
||
* Записать идентификатор магазина во все буферы сессии
|
||
*
|
||
* Проверяет существование аккаунта магазина с этим идентификатором
|
||
* и запоминает для использования в процессе аутентификации
|
||
*
|
||
* @param array $parameters Параметры запроса
|
||
*
|
||
* @return void В буфер вывода JSON-документ с запрашиваемыми параметрами
|
||
*/
|
||
public function market(array $parameters = []): void
|
||
{
|
||
// Инициализация буфера ответа
|
||
$buffer = [];
|
||
|
||
// Инициализация реестра возвращаемых параметров
|
||
$return = explode(',', $parameters['return'], 50);
|
||
|
||
try {
|
||
// Проверка наличия обязательных параметров
|
||
if (empty($parameters['market'])) throw new exception('Необходимо передать идентификатор');
|
||
|
||
// Вычисление длины
|
||
$length = mb_strlen($parameters['market']);
|
||
|
||
// Проверка параметров на соответствование требованиям
|
||
if ($length === 0) throw new exception('Идентификатор аккаунта аккаунта не может быть пустым');
|
||
if ($length > 40) throw new exception('Идентификатор аккаунта аккаунта должен иметь не более 40 символов');
|
||
if (preg_match_all('/[^\d\(\)\-\s\r\n\t\0]+/u', $parameters['market'], $matches) > 0) throw new exception('Нельзя использовать символы: ' . implode(', ', ...$matches));
|
||
|
||
if ($remember = isset($parameters['remember']) && $parameters['remember'] === '1') {
|
||
// Запрошено запоминание
|
||
|
||
// Запись в cookie
|
||
setcookie('entry__key', $parameters['market'], [
|
||
'expires' => strtotime('+1 day'),
|
||
'path' => '/',
|
||
'secure' => true,
|
||
'httponly' => true,
|
||
'samesite' => 'strict'
|
||
]);
|
||
}
|
||
|
||
// Поиск аккаунта
|
||
$account = account::read('d._key == "' . $parameters['market'] . '"', amount: 1);
|
||
|
||
// Генерация ответа по запрашиваемым параметрам
|
||
foreach ($return as $parameter) match ($parameter) {
|
||
'exist' => $buffer['exist'] = isset($account),
|
||
'account' => (function () use ($parameters, $remember, &$buffer) {
|
||
// Запись в буфер сессии
|
||
if ($remember) $this->session->write(['entry' => ['_key' => $parameters['market']]], $this->errors);
|
||
|
||
// Поиск аккаунта и запись в буфер вывода
|
||
$buffer['account'] = (new account($this->session, 'market', $this->errors))?->instance() instanceof _document;
|
||
})(),
|
||
'verify' => $buffer['verify'] = true,
|
||
'errors' => null,
|
||
default => throw new exception("Параметр не найден: $parameter")
|
||
};
|
||
} catch (exception $e) {
|
||
// Запись в реестр ошибок
|
||
$this->errors['session'][] = [
|
||
'text' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'stack' => $e->getTrace()
|
||
];
|
||
}
|
||
|
||
// Запись реестра ошибок в буфер ответа
|
||
if (in_array('errors', $return, true)) $buffer['errors'] = self::parse_only_text($this->errors);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Type: application/json');
|
||
header('Content-Encoding: none');
|
||
header('X-Accel-Buffering: no');
|
||
|
||
// Инициализация буфера вывода
|
||
ob_start();
|
||
|
||
// Генерация ответа
|
||
echo json_encode($buffer);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Length: ' . ob_get_length());
|
||
|
||
// Отправка и деинициализация буфера вывода
|
||
ob_end_flush();
|
||
flush();
|
||
|
||
// Запись в буфер сессии
|
||
if (!in_array('account', $return, true) && ($remember ?? false))
|
||
$this->session->write(['entry' => ['_key' => $parameters['market']]]);
|
||
}
|
||
|
||
/**
|
||
* Записать пароль любого типа аккаунта во все буферы сессии
|
||
*
|
||
* Проверяет на соответствие требованиям
|
||
* и запоминает для использования в процессе аутентификации
|
||
*
|
||
* @param array $parameters Параметры запроса
|
||
*
|
||
* @return void В буфер вывода JSON-документ с запрашиваемыми параметрами
|
||
*/
|
||
public function password(array $parameters = []): void
|
||
{
|
||
// Инициализация буфера ответа
|
||
$buffer = [];
|
||
|
||
// Инициализация реестра возвращаемых параметров
|
||
$return = explode(',', $parameters['return'], 50);
|
||
|
||
try {
|
||
// Вычисление длины
|
||
$length = strlen($parameters['password']);
|
||
|
||
// Проверка параметров на соответствование требованиям
|
||
if ($length > 300) throw new exception('Пароль не может быть длиннее 300 символов');
|
||
if (preg_match_all('/[^\w\s\r\n\t\0]+/u', $parameters['password'], $matches) > 0) throw new exception('Нельзя использовать символы: ' . implode(', ', ...$matches));
|
||
|
||
// Инициализация значения по умолчанию для типа аккаунта
|
||
$parameters['type'] ??= 'worker';
|
||
|
||
// Генерация ответа по запрашиваемым параметрам
|
||
foreach ($return as $parameter) match ($parameter) {
|
||
'account' => (function () use ($parameters, &$buffer) {
|
||
// Запись в буфер сессии
|
||
if (isset($parameters['remember']) && $parameters['remember'] === '1')
|
||
$this->session->write(['entry' => ['password' => $parameters['password']]], $this->errors);
|
||
|
||
// Поиск аккаунта и запись в буфер вывода
|
||
$buffer['account'] = (new account($this->session, $parameters['type'], $this->errors))?->instance() instanceof _document;
|
||
})(),
|
||
'verify' => $buffer['verify'] = true,
|
||
'errors' => null,
|
||
default => throw new exception("Параметр не найден: $parameter")
|
||
};
|
||
} catch (exception $e) {
|
||
// Запись в реестр ошибок
|
||
$this->errors['session'][] = [
|
||
'text' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'stack' => $e->getTrace()
|
||
];
|
||
}
|
||
|
||
// Запись реестра ошибок в буфер ответа
|
||
if (in_array('errors', $return, true)) $buffer['errors'] = self::parse_only_text($this->errors);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Type: application/json');
|
||
header('Content-Encoding: none');
|
||
header('X-Accel-Buffering: no');
|
||
|
||
// Инициализация буфера вывода
|
||
ob_start();
|
||
|
||
// Генерация ответа
|
||
echo json_encode($buffer);
|
||
|
||
// Запись заголовков ответа
|
||
header('Content-Length: ' . ob_get_length());
|
||
|
||
// Отправка и деинициализация буфера вывода
|
||
ob_end_flush();
|
||
flush();
|
||
|
||
// Запись в буфер сессии
|
||
if (!in_array('account', $return, true) && isset($parameters['remember']) && $parameters['remember'] === '1')
|
||
$this->session->write(['entry' => ['password' => $parameters['password']]]);
|
||
}
|
||
|
||
/**
|
||
* Записать в буфер сессии
|
||
*
|
||
* @param array $parameters Параметры запроса
|
||
*
|
||
* @return void
|
||
*/
|
||
public function write(array $parameters = []): void
|
||
{
|
||
try {
|
||
if ($this->account->status()) {
|
||
// Авторизован аккаунт
|
||
|
||
// Инициализация директорий для генерации
|
||
$directories = explode('_', $parameters['name'], 100);
|
||
|
||
// Инициализированы директории?
|
||
if (count($directories) === 0) return;
|
||
|
||
// Конвертация: filter -> filters
|
||
if ($directories[1] === 'filter') $directories[1] .= 's';
|
||
|
||
// Инициализация буфера вывода
|
||
$response = [];
|
||
|
||
// Инициализация буфера выполнения
|
||
$buffer = &$response;
|
||
|
||
foreach ($directories as $directory) {
|
||
// Перебор директорий
|
||
|
||
// Инициализация структуры
|
||
$buffer[$directory] = ($next = next($directories) === false) ? $parameters['value'] : [];
|
||
|
||
// Реинициализация цели для инициализации структуры (углубление в массив)
|
||
if ($next) unset($buffer);
|
||
else $buffer = &$buffer[$directory];
|
||
}
|
||
|
||
// Запись в буфер сессии
|
||
$this->session->write($response);
|
||
}
|
||
} catch (exception $e) {
|
||
// Запись в реестр ошибок
|
||
$this->errors['session'][] = [
|
||
'text' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'stack' => $e->getTrace()
|
||
];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Прочитать из буфера сессии
|
||
*
|
||
* @param array $parameters Параметры запроса
|
||
*
|
||
* @return ?string Данные из буфера сессии, если найдены
|
||
*/
|
||
public function read(array $parameters = []): ?string
|
||
{
|
||
try {
|
||
if ($this->account->status()) {
|
||
// Авторизован аккаунт
|
||
|
||
// Инициализация директорий для генерации
|
||
$directories = explode('_', $parameters['name'], 100);
|
||
|
||
// Инициализированы директории?
|
||
if (count($directories) === 0) return null;
|
||
|
||
// Конвертация: filter -> filters
|
||
if ($directories[1] === 'filter') $directories[1] .= 's';
|
||
|
||
// Инициализация буфера хранилища
|
||
$storage = $this->session->buffer[$_SERVER['INTERFACE']];
|
||
|
||
// Инициализация буфера выполнения
|
||
$buffer = &$storage[reset($directories)] ?? null;
|
||
|
||
// Найдена первая директория в базе данных?
|
||
if (isset($buffer) === 0) return null;
|
||
|
||
foreach ($directories as &$directory) {
|
||
// Перебор директорий
|
||
|
||
// Инициализация новой целевой директории
|
||
if (isset($buffer[$directory])) $buffer = &$buffer[$directory];
|
||
else continue;
|
||
|
||
// Реинициализация цели для инициализации структуры (углубление в массив)
|
||
if (next($directories) === false) $buffer = $buffer[$directory];
|
||
}
|
||
|
||
// Возврат (успех)
|
||
return is_array($buffer) ? null : $buffer;
|
||
}
|
||
} catch (exception $e) {
|
||
// Запись в реестр ошибок
|
||
$this->errors['session'][] = [
|
||
'text' => $e->getMessage(),
|
||
'file' => $e->getFile(),
|
||
'line' => $e->getLine(),
|
||
'stack' => $e->getTrace()
|
||
];
|
||
}
|
||
|
||
// Возврат (провал)
|
||
return null;
|
||
}
|
||
}
|