Files
surikov/mirzaev/surikovlib/system/models/books_model.php
Arsen Mirzaev Tatyano-Muradovich 30fd8f0ec3 супер попа (обновление)
2022-04-16 17:30:06 +10:00

277 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace mirzaev\surikovlib\models;
use mirzaev\surikovlib\models\accounts_model as accounts;
use pdo;
use exception;
/**
* Модель книг
*
* @package mirzaev\surikovlib\models
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class books_model extends core
{
/**
* Чтение
*
* @param array $expression Выражение поиска
* @param int $limit Ограничение по количеству
* @param int $page Страница (сдвиг)
* @param array &$errors Журнал ошибок
*
* @return array Книги
*/
public static function read(array $expression = [], int $limit = 1, int $page = 1, array &$errors = []): array
{
// Инициализация журнала ошибок
$errors['books'] ?? $errors['books'] = [];
try {
// Инициализация выражения поиска
$where = 'WHERE ';
// Инициализация параметров запроса
$params = [];
foreach ($expression as $parameter => $value) {
// Перебор выражения поиска
// Запись в строку запроса
$where .= "`$parameter` = :$parameter &&";
// Запись параметров запроса
$params[":$parameter"] = $value;
}
// Очистка или реинициализация выражения поиска
$where = empty($expression) ? '' : trim(trim($where, '&&'));
// Инициализация страницы
$page = $limit * --$page;
// Инициализация запроса
$request = static::$db->prepare("SELECT * FROM `books` $where LIMIT $page, $limit");
// Отправка запроса
$request->execute($params);
return (array) $request->fetchAll(pdo::FETCH_ASSOC);
} catch (exception $e) {
// Запись в журнал ошибок
$errors['books'][] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
return [];
}
/**
* Запись в базу данных
*
* @param string $title Название
* @param string|null $description Описание
* @param int|null $account Аккаунт (идентификатор)
* @param array &$errors Журнал ошибок
*
* @return int|null Идентификатор записанной книги
*/
public static function write(string $title, ?string $description = null, ?int $account = null, array &$errors = []): ?int
{
// Инициализация журнала ошибок
$errors['books'] ?? $errors['books'] = [];
try {
// Инициализация аккаунта
$account = accounts::init($account, $errors);
if (empty($account) || !accounts::access('books', $account->id)) {
// Не удалось найти аккаунт или разрешение на управление книгами не выдано
throw new exception('У вас нет разрешения на управление книгами');
}
// Инициализация запроса
$request = static::$db->prepare("INSERT INTO `books` (`account`, `title`, `description`) VALUES (:account, :title, :description)");
// Инициализация параметров
$params = [
':account' => $account->id,
':title' => $title,
':description' => $description
];
// Отправка запроса
$request->execute($params);
if ($id = static::$db->lastInsertId()) {
// Получен идентификатор загруженной книги (подразумевается)
return (int) $id;
}
} catch (exception $e) {
// Запись в журнал ошибок
$errors['books'][] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
return null;
}
/**
* Импорт
*
* @param array $books Книги (файлы)
* @param int|null $account Аккаунт (идентификатор)
* @param array &$errors Журнал ошибок
*
* @return array Записанные книги
*/
public static function import(array $books, ?int $account = null, array &$errors = []): array
{
// Инициализация журнала ошибок
$errors['books'] ?? $errors['books'] = [];
try {
if (empty($books)) {
// Не найдены книги
throw new exception('Не найдены книги для записи');
}
// Инициализация аккаунта
$account = accounts::init($account, $errors);
if (empty($account) || !accounts::access('books', $account->id)) {
// Не найден аккаунт или разрешение на управление книгами не выдано
throw new exception('У вас нет разрешения на управление книгами');
}
// Инициализация буфера инициализированных книг
$initialized = [];
for ($i = -1; count($books['name']) > ++$i;) {
// Перебор загруженных книг
// Генерация хеша файла
$hash = hash_file('md5', $books['tmp_name'][$i]) ?? 0;
if (move_uploaded_file($books['tmp_name'][$i], \STORAGE . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . $hash . '_' . $books['name'][$i])) {
// Загружен и перемещён из временной папки файл с книгой
// Извлечение имени файла
// Запись в буфер инициализированных книг
$initialized[] = [
'name' => preg_replace('/\.pdf/', '', $books['name'])[0],
'file' => $hash . '_' . $books['name'][$i]
];
}
}
// Инициализация буфера записанных книг
$writed = [];
foreach ($initialized as $book) {
// Перебор инициализированных книг
try {
if ($id = static::write($book['name'], 'Без описания', $account->id ?? null, $errors)) {
// Записана в базу данных книга
// Инициализация пути до хранилища
$directory = \STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $id . DIRECTORY_SEPARATOR;
// Инициализация директории
if (!file_exists($directory)) if (!mkdir($directory, 0755, true)) throw new exception('Не удалось записать директорию для книги');
// Инициализация пути до временного файла
$file = \STORAGE . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . $book['file'];
// Извлечение изображений из PDF-документа
exec("pdfimages -j '$file' '$directory'");
// Переименование файлов в необходимый формат
exec("echo 'export j=-1; for i in $directory*.jpg; do let j+=1; mv \$i $directory\$j.jpg; done' | bash");
// Запись в буфер записанных книг
$writed[] = $id;
} else {
// Не записана в базу данных книга
throw new exception('Не удалось записать книгу в базу данных', 500);
}
} catch (exception $e) {
// Запись в журнал ошибок
$errors['books'][] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
}
} catch (exception $e) {
// Запись в журнал ошибок
$errors['books'][] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
return $writed ?? [];
}
/**
* Подсчёт количества страниц
*
* @param int $id Идентификатор
* @param array &$errors Журнал ошибок
*
* @return int|null Количество страниц
*/
public static function amount(int $id, array &$errors = []): ?int
{
// Инициализация журнала ошибок
$errors['books'] ?? $errors['books'] = [];
try {
// Инициализация счётчика
$amount = -1;
while (true) {
// Перебор директорий (!!! Рекурсия !!!)
// Перебор изображений по возрастанию (от 0.jpg до 999.jpg и т.д.)
if (!file_exists(\STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $id . DIRECTORY_SEPARATOR . ++$amount . '.jpg')) return $amount;
}
} catch (exception $e) {
// Запись в журнал ошибок
$errors['books'][] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
return null;
}
}