diff --git a/composer.lock b/composer.lock
index 4d7856d..7e1eada 100644
--- a/composer.lock
+++ b/composer.lock
@@ -12,7 +12,7 @@
"source": {
"type": "git",
"url": "https://git.hood.su/mirzaev/minimal",
- "reference": "b6f90b700116f20fe48725166ddfb8f6d27ae52d"
+ "reference": "7777d7af1733d661a36551a0fdcf27a972e4ef81"
},
"require": {
"php": "~8.0"
@@ -48,25 +48,28 @@
"docs": "https://git.hood.su/mirzaev/minimal/manual",
"issues": "https://git.hood.su/mirzaev/minimal/issues"
},
- "time": "2021-11-12T13:20:13+00:00"
+ "time": "2022-03-03T21:15:52+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.23.0",
+ "version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
+ "reference": "30885182c981ab175d4d034db0f6f469898070ab"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
- "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
+ "reference": "30885182c981ab175d4d034db0f6f469898070ab",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
+ "provide": {
+ "ext-ctype": "*"
+ },
"suggest": {
"ext-ctype": "For best performance"
},
@@ -81,12 +84,12 @@
}
},
"autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- },
"files": [
"bootstrap.php"
- ]
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -111,7 +114,7 @@
"portable"
],
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
},
"funding": [
{
@@ -127,25 +130,28 @@
"type": "tidelift"
}
],
- "time": "2021-02-19T12:13:01+00:00"
+ "time": "2021-10-20T20:35:02+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.23.1",
+ "version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6"
+ "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6",
- "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
+ "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
+ "provide": {
+ "ext-mbstring": "*"
+ },
"suggest": {
"ext-mbstring": "For best performance"
},
@@ -160,12 +166,12 @@
}
},
"autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- },
"files": [
"bootstrap.php"
- ]
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -191,7 +197,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
},
"funding": [
{
@@ -207,20 +213,20 @@
"type": "tidelift"
}
],
- "time": "2021-05-27T12:26:48+00:00"
+ "time": "2021-11-30T18:21:41+00:00"
},
{
"name": "twig/twig",
- "version": "v3.3.3",
+ "version": "v3.3.8",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "a27fa056df8a6384316288ca8b0fa3a35fdeb569"
+ "reference": "972d8604a92b7054828b539f2febb0211dd5945c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/a27fa056df8a6384316288ca8b0fa3a35fdeb569",
- "reference": "a27fa056df8a6384316288ca8b0fa3a35fdeb569",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/972d8604a92b7054828b539f2febb0211dd5945c",
+ "reference": "972d8604a92b7054828b539f2febb0211dd5945c",
"shasum": ""
},
"require": {
@@ -271,7 +277,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.3.3"
+ "source": "https://github.com/twigphp/Twig/tree/v3.3.8"
},
"funding": [
{
@@ -283,7 +289,7 @@
"type": "tidelift"
}
],
- "time": "2021-09-17T08:44:23+00:00"
+ "time": "2022-02-04T06:59:48+00:00"
}
],
"packages-dev": [],
@@ -298,5 +304,5 @@
"php": "^8.0.0"
},
"platform-dev": [],
- "plugin-api-version": "2.0.0"
+ "plugin-api-version": "2.2.0"
}
diff --git a/mirzaev/surikovlib/system/controllers/books_controller.php b/mirzaev/surikovlib/system/controllers/books_controller.php
index 60433b5..5a193fd 100644
--- a/mirzaev/surikovlib/system/controllers/books_controller.php
+++ b/mirzaev/surikovlib/system/controllers/books_controller.php
@@ -66,10 +66,14 @@ final class books_controller extends core
// Инициализация журнала ошибок
$vars['errors'] = [];
- if (count($books = books::import($files['books'] ?? [], errors: $vars['errors'])) > 0) {
- // Загружены книги
- } else {
- // Не загружены книги
+ if (accounts::init(errors: $vars['errors'])->access('books')) {
+ // Найден и авторизован аккаунт
+
+ if (count($books = books::import($files['books'] ?? [], errors: $vars['errors'])) > 0) {
+ // Загружены книги
+ } else {
+ // Не загружены книги
+ }
}
// Перенаправление
@@ -122,5 +126,66 @@ final class books_controller extends core
*/
public function delete(array $vars = []): ?string
{
+ // Инициализация журнала ошибок
+ $vars['errors'] = [];
+
+ if (accounts::init(errors: $vars['errors'])->access('books')) {
+ // Найден и авторизован аккаунт
+
+ if (isset($vars['id'])) {
+ // Найдены обязательные входные параметры
+
+ if (books::delete((int) $vars['id'], $vars['errors'])) {
+ // Удалена книга из базы данных
+
+ // Инициализация пути до книги
+ $book = \STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $vars['id'];
+
+ if (file_exists($book)) {
+ // Найдена книга
+
+ // Удаление книги
+ exec('rm -rf ' . escapeshellarg($book));
+
+ // Запись статуса выполнения в буфер вывода
+ $status = true;
+ }
+ }
+ }
+ }
+
+ return json_encode([
+ 'status' => $status ?? false,
+ 'errors' => $vars['errors']
+ ]);
+ }
+
+ /**
+ * Поворот
+ *
+ * @param array $vars
+ *
+ * @return string|null JSON
+ */
+ public function rotate(array $vars = []): ?string
+ {
+ // Инициализация журнала ошибок
+ $vars['errors'] = [];
+
+ if (accounts::init(errors: $vars['errors'])->access('books')) {
+ // Найден и авторизован аккаунт
+
+ if (isset($vars['id'], $vars['page'])) {
+ // Найдены обязательные входные параметры
+
+ // Поворот страницы
+ $status = books::rotate((int) $vars['id'], (int) $vars['page'], $vars['errors']);
+ }
+ }
+
+ return json_encode([
+ 'status' => $status ?? false,
+ 'errors' => $vars['errors']
+ ]);
}
}
diff --git a/mirzaev/surikovlib/system/controllers/contacts_controller.php b/mirzaev/surikovlib/system/controllers/contacts_controller.php
new file mode 100644
index 0000000..130825c
--- /dev/null
+++ b/mirzaev/surikovlib/system/controllers/contacts_controller.php
@@ -0,0 +1,28 @@
+
+ */
+final class contacts_controller extends core
+{
+ public function index(array $vars = []): ?string
+ {
+ // Инициализация журнала ошибок
+ $vars['errors'] = [];
+
+ // Генерация представления
+ return $this->view->render(DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'contacts' . DIRECTORY_SEPARATOR . 'index.html', $vars);
+ }
+}
diff --git a/mirzaev/surikovlib/system/controllers/kemenov_controller.php b/mirzaev/surikovlib/system/controllers/kemenov_controller.php
new file mode 100644
index 0000000..fddb25a
--- /dev/null
+++ b/mirzaev/surikovlib/system/controllers/kemenov_controller.php
@@ -0,0 +1,28 @@
+
+ */
+final class kemenov_controller extends core
+{
+ public function index(array $vars = []): ?string
+ {
+ // Инициализация журнала ошибок
+ $vars['errors'] = [];
+
+ // Генерация представления
+ return $this->view->render(DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'kemenov' . DIRECTORY_SEPARATOR . 'index.html', $vars);
+ }
+}
diff --git a/mirzaev/surikovlib/system/controllers/surikov_controller.php b/mirzaev/surikovlib/system/controllers/surikov_controller.php
new file mode 100644
index 0000000..86d7b3e
--- /dev/null
+++ b/mirzaev/surikovlib/system/controllers/surikov_controller.php
@@ -0,0 +1,28 @@
+
+ */
+final class surikov_controller extends core
+{
+ public function index(array $vars = []): ?string
+ {
+ // Инициализация журнала ошибок
+ $vars['errors'] = [];
+
+ // Генерация представления
+ return $this->view->render(DIRECTORY_SEPARATOR . 'pages' . DIRECTORY_SEPARATOR . 'surikov' . DIRECTORY_SEPARATOR . 'index.html', $vars);
+ }
+}
diff --git a/mirzaev/surikovlib/system/models/accounts_model.php b/mirzaev/surikovlib/system/models/accounts_model.php
index decc7a5..5498526 100644
--- a/mirzaev/surikovlib/system/models/accounts_model.php
+++ b/mirzaev/surikovlib/system/models/accounts_model.php
@@ -33,7 +33,7 @@ final class accounts_model extends core
/**
* Хеш
*/
- public string $hash;
+ public ?string $hash;
/**
* Время активности хеша
@@ -361,21 +361,17 @@ final class accounts_model extends core
* Проверить разрешение
*
* @param string $permission Разрешение
- * @param int|null $id Идентификатор аккаунта
* @param array &$errors Журнал ошибок
*
* @return bool|null Статус разрешения, если оно записано
*/
- public static function access(string $permission, int|null $id = null, array &$errors = []): ?bool
+ public function access(string $permission, array &$errors = []): ?bool
{
// Инициализация журнала ошибок
$errors['account'] ?? $errors['account'] = [];
try {
- // Инициализация аккаунта
- $account = isset($id) ? self::read(['id' => $id], $errors) : self::account($errors);
-
- return isset($account->permissions[$permission]) ? (bool) $account->permissions[$permission] : null;
+ return isset($this->permissions[$permission]) ? (bool) $this->permissions[$permission] : null;
} catch (exception $e) {
// Запись в журнал ошибок
$errors['account'][]= [
diff --git a/mirzaev/surikovlib/system/models/books_model.php b/mirzaev/surikovlib/system/models/books_model.php
index 41184cf..524aa80 100644
--- a/mirzaev/surikovlib/system/models/books_model.php
+++ b/mirzaev/surikovlib/system/models/books_model.php
@@ -17,12 +17,62 @@ use exception;
*/
final class books_model extends core
{
+ /**
+ * Запись в базу данных
+ *
+ * @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);
+
+ // Инициализация запроса
+ $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 $expression Выражение поиска
* @param int $limit Ограничение по количеству
- * @param int $page Страница (сдвиг)
+ * @param int $page Страница (для списка книг)
* @param array &$errors Журнал ошибок
*
* @return array Книги
@@ -76,48 +126,26 @@ final class books_model extends core
}
/**
- * Запись в базу данных
+ * Удаление из базы данных
*
- * @param string $title Название
- * @param string|null $description Описание
- * @param int|null $account Аккаунт (идентификатор)
+ * @param int $id Идентификатор
* @param array &$errors Журнал ошибок
*
- * @return int|null Идентификатор записанной книги
+ * @return bool Статус выполнения
*/
- public static function write(string $title, ?string $description = null, ?int $account = null, array &$errors = []): ?int
+ public static function delete(int $id, array &$errors = []): bool
{
// Инициализация журнала ошибок
$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 = static::$db->prepare("DELETE FROM `books` WHERE `id` = :id LIMIT 1");
// Отправка запроса
- $request->execute($params);
+ $request->execute([':id' => $id]);
- if ($id = static::$db->lastInsertId()) {
- // Получен идентификатор загруженной книги (подразумевается)
-
- return (int) $id;
- }
+ return true;
} catch (exception $e) {
// Запись в журнал ошибок
$errors['books'][] = [
@@ -128,7 +156,7 @@ final class books_model extends core
];
}
- return null;
+ return false;
}
/**
@@ -155,12 +183,6 @@ final class books_model extends core
// Инициализация аккаунта
$account = accounts::init($account, $errors);
- if (empty($account) || !accounts::access('books', $account->id)) {
- // Не найден аккаунт или разрешение на управление книгами не выдано
-
- throw new exception('У вас нет разрешения на управление книгами');
- }
-
// Инициализация буфера инициализированных книг
$initialized = [];
@@ -238,6 +260,66 @@ final class books_model extends core
return $writed ?? [];
}
+ /**
+ * Чтение
+ *
+ * @param int $id Идентификатор
+ * @param int $page Страница (сдвиг)
+ * @param array &$errors Журнал ошибок
+ *
+ * @return bool Статус выполнения
+ */
+ public static function rotate(int $id, int $page = 1, array &$errors = []): bool
+ {
+ // Инициализация журнала ошибок
+ $errors['books'] ?? $errors['books'] = [];
+
+ try {
+ // Инициализация запроса
+ $request = static::$db->prepare("SELECT EXISTS (SELECT * FROM `books` WHERE `id` = :id LIMIT 1)");
+
+ // Отправка запроса
+ $request->execute([':id' => $id]);
+
+ if ($request->fetch(pdo::FETCH_NUM)[0] === 1) {
+ // Найдена книга
+
+ // Инициализация пути книги
+ $book = \STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $id;
+
+ // Инициализация пути до файла
+ $file = $book . DIRECTORY_SEPARATOR . "$page.jpg";
+
+ // Инициализация пути до нового местоположения файла
+ $old = $book . DIRECTORY_SEPARATOR . 'old' . DIRECTORY_SEPARATOR . "$page.jpg";
+
+ // Инициализация директории
+ if (!file_exists($book)) throw new exception('Не удалось найти директорию книги');
+
+ // Инициализация директории оригинальных изображений
+ if (!file_exists($book . DIRECTORY_SEPARATOR . 'old')) if (!mkdir($book . DIRECTORY_SEPARATOR . 'old', 0755, true)) throw new exception('Не удалось записать директорию для оригинальных страниц книги');
+
+ // Перемещение страницы в директорию оригинальных страниц
+ exec("mv $file $old");
+
+ // Переворачивание файла и возвращение на нужное местоположение
+ exec("jpegtran -rotate 90 $old > $file");
+
+ return true;
+ }
+ } catch (exception $e) {
+ // Запись в журнал ошибок
+ $errors['books'][] = [
+ 'text' => $e->getMessage(),
+ 'file' => $e->getFile(),
+ 'line' => $e->getLine(),
+ 'stack' => $e->getTrace()
+ ];
+ }
+
+ return false;
+ }
+
/**
* Подсчёт количества страниц
*
diff --git a/mirzaev/surikovlib/system/public/css/auth.css b/mirzaev/surikovlib/system/public/css/auth.css
index 4dd01c8..d7c2eda 100644
--- a/mirzaev/surikovlib/system/public/css/auth.css
+++ b/mirzaev/surikovlib/system/public/css/auth.css
@@ -68,6 +68,7 @@
#authentication>div#account>p>b {
margin-right: 8px;
+ font-weight: 900;
}
#authentication>div#account>p>span {
diff --git a/mirzaev/surikovlib/system/public/css/books.css b/mirzaev/surikovlib/system/public/css/books.css
index 9bd635b..91b72d7 100644
--- a/mirzaev/surikovlib/system/public/css/books.css
+++ b/mirzaev/surikovlib/system/public/css/books.css
@@ -26,6 +26,50 @@ main>section#books>article.book {
margin-right: 20px;
display: flex;
flex-direction: column;
+ border-radius: 3px;
+ overflow: hidden;
+ background: #b38b8b;
+ transition: .1s ease-in-out;
+ font-weight: 900;
+}
+
+main>section#books>article.book:hover {
+ scale: 1.05;
+ z-index: 1000;
+}
+
+main>section#books>article.book>button {
+ position: absolute;
+ display: flex;
+ top: 10px;
+ right: 10px;
+ width: 25px;
+ height: 25px;
+ flex-direction: column;
+ justify-content: center;
+ font-size: 110%;
+ opacity: 0;
+ pointer-events: none;
+ border-radius: 3px;
+ border: none;
+ color: #ff5757;
+ background-color: rgba(0, 0, 0, .5);
+}
+
+main>section#books>article.book:hover>button {
+ opacity: 1;
+ pointer-events: all;
+ transition: .2s ease-in-out;
+}
+
+main>section#books>article.book>button:hover {
+ color: #ff6b6b;
+ background-color: rgba(0, 0, 0, .4);
+}
+
+main>section#books>article.book>button:active {
+ color: #e04d4d;
+ background-color: rgba(0, 0, 0, .6);
}
main>section#books>article.book:nth-child(3n) {
@@ -42,7 +86,8 @@ main>section#books>article.book>img {
height: 100%;
object-fit: cover;
object-position: right;
- overflow: hidden;
+ text-align: center;
+ /* overflow: hidden; */
/* clip-path: polygon(5px calc(100% - 5px), calc(100% - 5px) calc(100% - 5px), calc(100% - 5px) 5px, 5px 5px); */
}
@@ -58,8 +103,16 @@ main>section#books>article.book>h4 {
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
+ color: #e8e8e8;
+ background-color: rgba(0, 0, 0, .5);
+}
+
+main>section#books>article.book>h4:hover {
color: #fff;
- background: rgba(0, 0, 0, 50%);
+}
+
+main>section#books>article.book>h4:active {
+ color: #e7e4e4;
}
main>section#books>article.book>p {
@@ -96,11 +149,35 @@ main>section#book>nav>ul>li:only-of-type {
margin-right: auto;
}
-main>section#book>nav>ul>li.previous {
- margin-left: auto;
+
+main>section#book>nav>ul>li {
margin-right: 15px;
}
+main>section#book>nav>ul>li:first-of-type,
+main>section#book>nav>ul>li.previous {
+ margin-left: auto;
+}
+
+main>section#book>nav>ul>li:last-of-type,
main>section#book>nav>ul>li.next {
margin-right: auto;
}
+
+main>section#book>nav>ul>li.icon {
+ display: flex;
+}
+
+main>section#book>nav>ul>li.icon>i {
+ height: 1rem;
+ margin: auto;
+ color: #9b3d10;
+}
+
+main>section#book>nav>ul>li.icon>i:hover {
+ color: #bd4f1c;
+}
+
+main>section#book>nav>ul>li.icon>i:active {
+ color: #813410;
+}
diff --git a/mirzaev/surikovlib/system/public/css/main.css b/mirzaev/surikovlib/system/public/css/main.css
index 42b0542..13c96f1 100644
--- a/mirzaev/surikovlib/system/public/css/main.css
+++ b/mirzaev/surikovlib/system/public/css/main.css
@@ -1,6 +1,15 @@
+@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:wght@200;400;500;600;700&display=swap');
+
* {
- font-family: "open sans";
+ font-family: 'IBM Plex Serif', serif;
text-decoration: none;
+ transition: .2s ease-out;
+}
+
+button,
+*[type="button"] {
+ cursor: pointer;
+ font-weight: 900;
}
::selection,
@@ -12,7 +21,8 @@ body {
margin: 0;
display: grid;
grid-template-rows: auto auto 150px;
- grid-template-columns: minmax(100px, auto) 300px minmax(500px, auto) minmax(100px, auto);;
+ /* grid-template-columns: minmax(100px, auto) 300px minmax(500px, auto) minmax(100px, auto); */
+ grid-template-columns: minmax(100px, auto) 300px minmax(500px, 1000px) minmax(100px, auto);
background-color: #e5ddd1;
}
@@ -112,6 +122,7 @@ header>.menu>nav>.link {
margin-right: 50px;
text-decoration: none;
color: #e5ddd1;
+ font-weight: 900;
}
header>.menu>nav>.link:last-child {
diff --git a/mirzaev/surikovlib/system/public/css/pages.css b/mirzaev/surikovlib/system/public/css/pages.css
new file mode 100644
index 0000000..a4692ee
--- /dev/null
+++ b/mirzaev/surikovlib/system/public/css/pages.css
@@ -0,0 +1,7 @@
+main>section#page>article *:first-child {
+ margin-top: 0;
+}
+
+main>section#page>article *:last-child {
+ margin-bottom: 0;
+}
diff --git a/mirzaev/surikovlib/system/public/index.php b/mirzaev/surikovlib/system/public/index.php
index 0e2bcbd..6757108 100644
--- a/mirzaev/surikovlib/system/public/index.php
+++ b/mirzaev/surikovlib/system/public/index.php
@@ -8,12 +8,16 @@ use mirzaev\minimal\core;
use mirzaev\minimal\router;
define('VIEWS', realpath('..' . DIRECTORY_SEPARATOR . 'views'));
-define('STORAGE', '..' . DIRECTORY_SEPARATOR . 'storage');
+define('STORAGE', realpath('..' . DIRECTORY_SEPARATOR . 'storage'));
define('TYPE', 'mysql');
define('BASE', 'surikovlib');
define('HOST', '127.0.0.1');
define('LOGIN', 'root');
-define('PASSWORD', '');
+define('PASSWORD', 'sUrikov_topchik_228!');
+
+ini_set('error_reporting', E_ALL);
+ini_set('display_errors', 1);
+ini_set('display_startup_errors', 1);
// Автозагрузка
require __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
@@ -29,9 +33,14 @@ $router->write('/account/deauthentication', 'accounts', 'deauthentication', 'POS
$router->write('/account/deauthentication', 'accounts', 'deauthentication', 'GET');
$router->write('/books', 'books', 'index', 'GET');
$router->write('/books/$id', 'books', 'index', 'GET');
-$router->write('/books/$id/cover', 'books', 'cover', 'GET');
-$router->write('/books/$id/0', 'books', 'cover', 'GET');
-$router->write('/books/write', 'books', 'write', 'POST');
+$router->write('/books/$id/$page', 'books', 'index', 'GET');
+$router->write('/books/$id/$page/rotate', 'books', 'rotate', 'POST');
+$router->write('/books/$id/delete', 'books', 'delete', 'POST');
+$router->write('/storage/books/$id/$file', 'books', 'read', 'GET');
+$router->write('/storage/books/write', 'books', 'write', 'POST');
+$router->write('/kemenov', 'kemenov', 'index', 'GET');
+$router->write('/surikov', 'surikov', 'index', 'GET');
+$router->write('/contacts', 'contacts', 'index', 'GET');
// Инициализация ядра
$core = new core(namespace: __NAMESPACE__, router: $router);
diff --git a/mirzaev/surikovlib/system/public/js/delete.js b/mirzaev/surikovlib/system/public/js/delete.js
new file mode 100644
index 0000000..cc92d89
--- /dev/null
+++ b/mirzaev/surikovlib/system/public/js/delete.js
@@ -0,0 +1,25 @@
+'use strict';
+
+function remove(id, element = null) {
+ if (typeof id === 'number') {
+ // Получены входные параметры
+
+ // Запрос
+ fetch(`https://surikovlib.ru/books/${id}/delete`, {
+ method: 'POST'
+ }).then(
+ (value) => {
+ return value.json();
+ }
+ ).then(
+ (response) => {
+ if (response.status === true) {
+ // Удалена книга
+
+ // Удаление элемента
+ if (typeof element === 'object') element.remove();
+ }
+ }
+ );
+ }
+}
diff --git a/mirzaev/surikovlib/system/public/js/rotate.js b/mirzaev/surikovlib/system/public/js/rotate.js
new file mode 100644
index 0000000..6cfd7b1
--- /dev/null
+++ b/mirzaev/surikovlib/system/public/js/rotate.js
@@ -0,0 +1,24 @@
+'use strict';
+
+function rotate(id, page, reload = false) {
+ if (typeof id === 'number' && typeof page === 'number') {
+ // Получены входные параметры
+
+ // Запрос
+ fetch(`https://surikovlib.ru/books/${id}/${page}/rotate`, {
+ method: 'POST'
+ }).then(
+ (value) => {
+ return value.json();
+ }
+ ).then(
+ (response) => {
+ if (response.status === true) {
+ // Перевёрнута страница
+
+ if (reload === true) location.reload();
+ }
+ }
+ );
+ }
+}
diff --git a/mirzaev/surikovlib/system/views/books/book.html b/mirzaev/surikovlib/system/views/books/book.html
index 3f5ab0a..e8e50b1 100644
--- a/mirzaev/surikovlib/system/views/books/book.html
+++ b/mirzaev/surikovlib/system/views/books/book.html
@@ -5,13 +5,23 @@
{{ book.title|e }}
-
+
diff --git a/mirzaev/surikovlib/system/views/books/index.html b/mirzaev/surikovlib/system/views/books/index.html
index 7c40247..c6afb3e 100644
--- a/mirzaev/surikovlib/system/views/books/index.html
+++ b/mirzaev/surikovlib/system/views/books/index.html
@@ -15,9 +15,15 @@
{% endif %}
{% for book in books %}
+ {% if account.permissions.books is defined and account.permissions.books == 1 %}
+
+ {% endif %}
{% endfor %}
+ {% if account.permissions.books is defined and account.permissions.books == 1 %}
+
+ {% endif %}
{% endblock %}
diff --git a/mirzaev/surikovlib/system/views/header.html b/mirzaev/surikovlib/system/views/header.html
index 6820c5d..c26ccae 100644
--- a/mirzaev/surikovlib/system/views/header.html
+++ b/mirzaev/surikovlib/system/views/header.html
@@ -1,8 +1,8 @@