*/ 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; } }