попа
This commit is contained in:
parent
30fd8f0ec3
commit
6d6712e9d2
|
@ -12,7 +12,7 @@
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.hood.su/mirzaev/minimal",
|
"url": "https://git.hood.su/mirzaev/minimal",
|
||||||
"reference": "b6f90b700116f20fe48725166ddfb8f6d27ae52d"
|
"reference": "7777d7af1733d661a36551a0fdcf27a972e4ef81"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "~8.0"
|
"php": "~8.0"
|
||||||
|
@ -48,25 +48,28 @@
|
||||||
"docs": "https://git.hood.su/mirzaev/minimal/manual",
|
"docs": "https://git.hood.su/mirzaev/minimal/manual",
|
||||||
"issues": "https://git.hood.su/mirzaev/minimal/issues"
|
"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",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.23.0",
|
"version": "v1.25.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
|
"reference": "30885182c981ab175d4d034db0f6f469898070ab"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
|
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
|
||||||
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
|
"reference": "30885182c981ab175d4d034db0f6f469898070ab",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.1"
|
"php": ">=7.1"
|
||||||
},
|
},
|
||||||
|
"provide": {
|
||||||
|
"ext-ctype": "*"
|
||||||
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-ctype": "For best performance"
|
"ext-ctype": "For best performance"
|
||||||
},
|
},
|
||||||
|
@ -81,12 +84,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
|
||||||
"Symfony\\Polyfill\\Ctype\\": ""
|
|
||||||
},
|
|
||||||
"files": [
|
"files": [
|
||||||
"bootstrap.php"
|
"bootstrap.php"
|
||||||
]
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Ctype\\": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
"license": [
|
"license": [
|
||||||
|
@ -111,7 +114,7 @@
|
||||||
"portable"
|
"portable"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
|
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -127,25 +130,28 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-02-19T12:13:01+00:00"
|
"time": "2021-10-20T20:35:02+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
"version": "v1.23.1",
|
"version": "v1.25.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
"reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6"
|
"reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6",
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
|
||||||
"reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6",
|
"reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.1"
|
"php": ">=7.1"
|
||||||
},
|
},
|
||||||
|
"provide": {
|
||||||
|
"ext-mbstring": "*"
|
||||||
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-mbstring": "For best performance"
|
"ext-mbstring": "For best performance"
|
||||||
},
|
},
|
||||||
|
@ -160,12 +166,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
|
||||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
|
||||||
},
|
|
||||||
"files": [
|
"files": [
|
||||||
"bootstrap.php"
|
"bootstrap.php"
|
||||||
]
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
"license": [
|
"license": [
|
||||||
|
@ -191,7 +197,7 @@
|
||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1"
|
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -207,20 +213,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-05-27T12:26:48+00:00"
|
"time": "2021-11-30T18:21:41+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "twig/twig",
|
"name": "twig/twig",
|
||||||
"version": "v3.3.3",
|
"version": "v3.3.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/twigphp/Twig.git",
|
"url": "https://github.com/twigphp/Twig.git",
|
||||||
"reference": "a27fa056df8a6384316288ca8b0fa3a35fdeb569"
|
"reference": "972d8604a92b7054828b539f2febb0211dd5945c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a27fa056df8a6384316288ca8b0fa3a35fdeb569",
|
"url": "https://api.github.com/repos/twigphp/Twig/zipball/972d8604a92b7054828b539f2febb0211dd5945c",
|
||||||
"reference": "a27fa056df8a6384316288ca8b0fa3a35fdeb569",
|
"reference": "972d8604a92b7054828b539f2febb0211dd5945c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -271,7 +277,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/twigphp/Twig/issues",
|
"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": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -283,7 +289,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-09-17T08:44:23+00:00"
|
"time": "2022-02-04T06:59:48+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [],
|
"packages-dev": [],
|
||||||
|
@ -298,5 +304,5 @@
|
||||||
"php": "^8.0.0"
|
"php": "^8.0.0"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.0.0"
|
"plugin-api-version": "2.2.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,10 +66,14 @@ final class books_controller extends core
|
||||||
// Инициализация журнала ошибок
|
// Инициализация журнала ошибок
|
||||||
$vars['errors'] = [];
|
$vars['errors'] = [];
|
||||||
|
|
||||||
if (count($books = books::import($files['books'] ?? [], errors: $vars['errors'])) > 0) {
|
if (accounts::init(errors: $vars['errors'])->access('books')) {
|
||||||
// Загружены книги
|
// Найден и авторизован аккаунт
|
||||||
} else {
|
|
||||||
// Не загружены книги
|
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
|
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']
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace mirzaev\surikovlib\controllers;
|
||||||
|
|
||||||
|
use mirzaev\surikovlib\controllers\core;
|
||||||
|
use mirzaev\surikovlib\models\accounts_model as accounts;
|
||||||
|
|
||||||
|
use Twig\Environment as view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Контроллер страницы "контакты"
|
||||||
|
*
|
||||||
|
* @package mirzaev\surikovlib\controllers
|
||||||
|
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace mirzaev\surikovlib\controllers;
|
||||||
|
|
||||||
|
use mirzaev\surikovlib\controllers\core;
|
||||||
|
use mirzaev\surikovlib\models\accounts_model as accounts;
|
||||||
|
|
||||||
|
use Twig\Environment as view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Контроллер страницы "кеменов"
|
||||||
|
*
|
||||||
|
* @package mirzaev\surikovlib\controllers
|
||||||
|
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace mirzaev\surikovlib\controllers;
|
||||||
|
|
||||||
|
use mirzaev\surikovlib\controllers\core;
|
||||||
|
use mirzaev\surikovlib\models\accounts_model as accounts;
|
||||||
|
|
||||||
|
use Twig\Environment as view;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Контроллер страницы "суриков"
|
||||||
|
*
|
||||||
|
* @package mirzaev\surikovlib\controllers
|
||||||
|
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 string $permission Разрешение
|
||||||
* @param int|null $id Идентификатор аккаунта
|
|
||||||
* @param array &$errors Журнал ошибок
|
* @param array &$errors Журнал ошибок
|
||||||
*
|
*
|
||||||
* @return bool|null Статус разрешения, если оно записано
|
* @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'] = [];
|
$errors['account'] ?? $errors['account'] = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Инициализация аккаунта
|
return isset($this->permissions[$permission]) ? (bool) $this->permissions[$permission] : null;
|
||||||
$account = isset($id) ? self::read(['id' => $id], $errors) : self::account($errors);
|
|
||||||
|
|
||||||
return isset($account->permissions[$permission]) ? (bool) $account->permissions[$permission] : null;
|
|
||||||
} catch (exception $e) {
|
} catch (exception $e) {
|
||||||
// Запись в журнал ошибок
|
// Запись в журнал ошибок
|
||||||
$errors['account'][]= [
|
$errors['account'][]= [
|
||||||
|
|
|
@ -17,12 +17,62 @@ use exception;
|
||||||
*/
|
*/
|
||||||
final class books_model extends core
|
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 array $expression Выражение поиска
|
||||||
* @param int $limit Ограничение по количеству
|
* @param int $limit Ограничение по количеству
|
||||||
* @param int $page Страница (сдвиг)
|
* @param int $page Страница (для списка книг)
|
||||||
* @param array &$errors Журнал ошибок
|
* @param array &$errors Журнал ошибок
|
||||||
*
|
*
|
||||||
* @return array Книги
|
* @return array Книги
|
||||||
|
@ -76,48 +126,26 @@ final class books_model extends core
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Запись в базу данных
|
* Удаление из базы данных
|
||||||
*
|
*
|
||||||
* @param string $title Название
|
* @param int $id Идентификатор
|
||||||
* @param string|null $description Описание
|
|
||||||
* @param int|null $account Аккаунт (идентификатор)
|
|
||||||
* @param array &$errors Журнал ошибок
|
* @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'] = [];
|
$errors['books'] ?? $errors['books'] = [];
|
||||||
|
|
||||||
try {
|
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)");
|
$request = static::$db->prepare("DELETE FROM `books` WHERE `id` = :id LIMIT 1");
|
||||||
|
|
||||||
// Инициализация параметров
|
|
||||||
$params = [
|
|
||||||
':account' => $account->id,
|
|
||||||
':title' => $title,
|
|
||||||
':description' => $description
|
|
||||||
];
|
|
||||||
|
|
||||||
// Отправка запроса
|
// Отправка запроса
|
||||||
$request->execute($params);
|
$request->execute([':id' => $id]);
|
||||||
|
|
||||||
if ($id = static::$db->lastInsertId()) {
|
return true;
|
||||||
// Получен идентификатор загруженной книги (подразумевается)
|
|
||||||
|
|
||||||
return (int) $id;
|
|
||||||
}
|
|
||||||
} catch (exception $e) {
|
} catch (exception $e) {
|
||||||
// Запись в журнал ошибок
|
// Запись в журнал ошибок
|
||||||
$errors['books'][] = [
|
$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);
|
$account = accounts::init($account, $errors);
|
||||||
|
|
||||||
if (empty($account) || !accounts::access('books', $account->id)) {
|
|
||||||
// Не найден аккаунт или разрешение на управление книгами не выдано
|
|
||||||
|
|
||||||
throw new exception('У вас нет разрешения на управление книгами');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Инициализация буфера инициализированных книг
|
// Инициализация буфера инициализированных книг
|
||||||
$initialized = [];
|
$initialized = [];
|
||||||
|
|
||||||
|
@ -238,6 +260,66 @@ final class books_model extends core
|
||||||
return $writed ?? [];
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Подсчёт количества страниц
|
* Подсчёт количества страниц
|
||||||
*
|
*
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
|
|
||||||
#authentication>div#account>p>b {
|
#authentication>div#account>p>b {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
|
font-weight: 900;
|
||||||
}
|
}
|
||||||
|
|
||||||
#authentication>div#account>p>span {
|
#authentication>div#account>p>span {
|
||||||
|
|
|
@ -26,6 +26,50 @@ main>section#books>article.book {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
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) {
|
main>section#books>article.book:nth-child(3n) {
|
||||||
|
@ -42,7 +86,8 @@ main>section#books>article.book>img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
object-position: right;
|
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); */
|
/* 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;
|
-moz-hyphens: auto;
|
||||||
-ms-hyphens: auto;
|
-ms-hyphens: auto;
|
||||||
hyphens: auto;
|
hyphens: auto;
|
||||||
|
color: #e8e8e8;
|
||||||
|
background-color: rgba(0, 0, 0, .5);
|
||||||
|
}
|
||||||
|
|
||||||
|
main>section#books>article.book>h4:hover {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background: rgba(0, 0, 0, 50%);
|
}
|
||||||
|
|
||||||
|
main>section#books>article.book>h4:active {
|
||||||
|
color: #e7e4e4;
|
||||||
}
|
}
|
||||||
|
|
||||||
main>section#books>article.book>p {
|
main>section#books>article.book>p {
|
||||||
|
@ -96,11 +149,35 @@ main>section#book>nav>ul>li:only-of-type {
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
main>section#book>nav>ul>li.previous {
|
|
||||||
margin-left: auto;
|
main>section#book>nav>ul>li {
|
||||||
margin-right: 15px;
|
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 {
|
main>section#book>nav>ul>li.next {
|
||||||
margin-right: auto;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
text-decoration: none;
|
||||||
|
transition: .2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
*[type="button"] {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 900;
|
||||||
}
|
}
|
||||||
|
|
||||||
::selection,
|
::selection,
|
||||||
|
@ -12,7 +21,8 @@ body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: auto auto 150px;
|
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;
|
background-color: #e5ddd1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +122,7 @@ header>.menu>nav>.link {
|
||||||
margin-right: 50px;
|
margin-right: 50px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #e5ddd1;
|
color: #e5ddd1;
|
||||||
|
font-weight: 900;
|
||||||
}
|
}
|
||||||
|
|
||||||
header>.menu>nav>.link:last-child {
|
header>.menu>nav>.link:last-child {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
main>section#page>article *:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main>section#page>article *:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
|
@ -8,12 +8,16 @@ use mirzaev\minimal\core;
|
||||||
use mirzaev\minimal\router;
|
use mirzaev\minimal\router;
|
||||||
|
|
||||||
define('VIEWS', realpath('..' . DIRECTORY_SEPARATOR . 'views'));
|
define('VIEWS', realpath('..' . DIRECTORY_SEPARATOR . 'views'));
|
||||||
define('STORAGE', '..' . DIRECTORY_SEPARATOR . 'storage');
|
define('STORAGE', realpath('..' . DIRECTORY_SEPARATOR . 'storage'));
|
||||||
define('TYPE', 'mysql');
|
define('TYPE', 'mysql');
|
||||||
define('BASE', 'surikovlib');
|
define('BASE', 'surikovlib');
|
||||||
define('HOST', '127.0.0.1');
|
define('HOST', '127.0.0.1');
|
||||||
define('LOGIN', 'root');
|
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';
|
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('/account/deauthentication', 'accounts', 'deauthentication', 'GET');
|
||||||
$router->write('/books', 'books', 'index', 'GET');
|
$router->write('/books', 'books', 'index', 'GET');
|
||||||
$router->write('/books/$id', 'books', 'index', 'GET');
|
$router->write('/books/$id', 'books', 'index', 'GET');
|
||||||
$router->write('/books/$id/cover', 'books', 'cover', 'GET');
|
$router->write('/books/$id/$page', 'books', 'index', 'GET');
|
||||||
$router->write('/books/$id/0', 'books', 'cover', 'GET');
|
$router->write('/books/$id/$page/rotate', 'books', 'rotate', 'POST');
|
||||||
$router->write('/books/write', 'books', 'write', '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);
|
$core = new core(namespace: __NAMESPACE__, router: $router);
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,13 +5,23 @@
|
||||||
|
|
||||||
<section id="book">
|
<section id="book">
|
||||||
<h2>{{ book.title|e }}</h2>
|
<h2>{{ book.title|e }}</h2>
|
||||||
<img class="unselectable" src="/storage/books/{{ book.id|e }}/{{ page|e }}" alt='Страница отсутствует'>
|
<img id="page" class="unselectable" src="/storage/books/{{ book.id|e }}/{{ page|e }}" alt='Страница отсутствует'>
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
{% if page != 0 %}
|
{% if page != 0 %}
|
||||||
<li class="previous unselectable" type="button"><a href="/books/{{ book.id|e }}/{{ page|e - 1 }}" title="Страница №{{ page|e - 1 }}">Назад</a></li>
|
<li class="previous unselectable" type="button"><a href="/books/{{ book.id|e }}/{{ page|e - 1 }}"
|
||||||
|
title="Страница №{{ page|e - 1 }}">Назад</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li class="next unselectable" type="button"><a href="/books/{{ book.id|e }}/{{ page|e + 1 }}" title="Страница №{{ page|e + 1 }}">Вперёд</a></li>
|
{% if account.permissions.books is defined and account.permissions.books == 1 %}
|
||||||
|
<li class="middle icon unselectable"><i class="fa-solid fa-rotate-right unselectable" type="button"
|
||||||
|
onclick="rotate({{ book.id|e }}, {{ page|e }}, true)" title="Повернуть страницу"></i></li>
|
||||||
|
<script type="text/javascript" src="/js/rotate.js"></script>
|
||||||
|
{% else %}
|
||||||
|
<li class="middle icon unselectable"><i class="fa-solid fa-rotate-right unselectable" type="button"
|
||||||
|
onclick="const image = document.getElementById('page'); image.style.rotate = ((isNaN(buffer = parseInt(image.style.rotate)) ? 0 : buffer) + 90) + 'deg'; (((isNaN(buffer) ? 0 : buffer) / 90) % 2) === 0 ? image.style.margin = '15% 0px 20% 0px' : image.style.margin = null" title="Повернуть страницу"></i></li>
|
||||||
|
{% endif %}
|
||||||
|
<li class="next unselectable" type="button"><a href="/books/{{ book.id|e }}/{{ page|e + 1 }}"
|
||||||
|
title="Страница №{{ page|e + 1 }}">Вперёд</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -15,9 +15,15 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for book in books %}
|
{% for book in books %}
|
||||||
<article class="book">
|
<article class="book">
|
||||||
|
{% if account.permissions.books is defined and account.permissions.books == 1 %}
|
||||||
|
<button onclick="return remove({{ book.id|e }}, this.parentElement);" title="Удалить"><i class="fa-solid fa-xmark"></i></button>
|
||||||
|
{% endif %}
|
||||||
<img src="/storage/books/{{ book.id|e }}/0" class="unselectable" alt='Обложка книги "{{ book.title|e }}"'>
|
<img src="/storage/books/{{ book.id|e }}/0" class="unselectable" alt='Обложка книги "{{ book.title|e }}"'>
|
||||||
<h4><a href="/books/{{ book.id|e }}">{{ book.title|e }}</a></h3>
|
<h4><a href="/books/{{ book.id|e }}">{{ book.title|e }}</a></h3>
|
||||||
</article>
|
</article>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% if account.permissions.books is defined and account.permissions.books == 1 %}
|
||||||
|
<script type="text/javascript" src="/js/delete.js"></script>
|
||||||
|
{% endif %}
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<header class="unselectable">
|
<header class="unselectable">
|
||||||
<section class="menu">
|
<section class="menu">
|
||||||
<nav>
|
<nav>
|
||||||
<a class="link" href="/surikov" title="Архивный фонд">Кеменов</a>
|
<a class="link" href="/kemenov" title="Архивный фонд">Кеменов</a>
|
||||||
<a class="link" href="/kemenev" title="Список книг">Суриков</a>
|
<a class="link" href="/surikov" title="Список книг">Суриков</a>
|
||||||
<a id="logo" href="/" title="Главная страница">
|
<a id="logo" href="/" title="Главная страница">
|
||||||
<img src="/img/surikovlib_logo_1_white.svg">
|
<img src="/img/surikovlib_logo_1_white.svg">
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
<script type="text/javascript" src="/js/auth.js"></script>
|
<script type="text/javascript" src="/js/auth.js"></script>
|
||||||
<script type="text/javascript" src="/js/tasks.js"></script>
|
<script src="https://kit.fontawesome.com/d67f03b1ae.js" crossorigin="anonymous"></script>
|
||||||
<script src="https://kit.fontawesome.com/d7e922c226.js" crossorigin="anonymous"></script>
|
|
||||||
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
|
||||||
<script type="text/javascript" src="/js/bootstrap/bootstrap.min.js"></script>
|
|
||||||
<script type="text/javascript" src="/js/bootstrap/forms_validator.js"></script>
|
|
||||||
|
|
||||||
{% block js %}
|
{% block js %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
{% extends "core.html" %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<link href="/css/pages.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<section id="page">
|
||||||
|
<article>
|
||||||
|
<h2>Суриков</h2>
|
||||||
|
<p>Библиотека научно-вспомогательного фонда <b>Музея-усадьбы В.И. Сурикова</b> начала формироваться с 1948 года, когда
|
||||||
|
первые сотрудники самостоятельно стали собирать её, приобретая за свои средства необходимую для работы
|
||||||
|
литературу, прежде всего по осмыслению жизни и творчества <b>В.И. Сурикова</b>, а также специальную
|
||||||
|
профессиональную литературу по экспонированию и иной деятельности в музее. В это время было начато системное
|
||||||
|
взаимодействие с <b>Центральной библиотечной системой им. Горького</b>, поэтому многие издания, поступавшие из
|
||||||
|
библиотеки в музей, имеют её опознавательный знак.
|
||||||
|
Позже, уже с приходом Л. П. Греченко, директора музея-усадьбы с 1970 по 2008 гг., было принято решение
|
||||||
|
ежемесячно закупать книги из бибколлектора (ныне «Центр книги – Красноярский бибколлектор»). </p>
|
||||||
|
<p>Но в 1990-е годы в период экономического спада и дефицита закупка прекратилась, с этого времени библиотека
|
||||||
|
продолжила формироваться за счёт <b>личного вклада</b> сотрудников музея. Особое значение библиотеке уделяла <b>Нина
|
||||||
|
Ярославовна Скалиш</b>, главный хранитель музея на протяжении 45 лет.
|
||||||
|
Основой библиотеки является научная литература, монографии о жизни и творчестве В. И. Сурикова, изданные с
|
||||||
|
1914 по 2018 гг. (кроме того, статьи, каталоги и художественная литература). Библиотека музея включает
|
||||||
|
архивный фонд В. С. Кеменова: рукописи, документы и фотографии, собранные известным суриковедом. Его
|
||||||
|
исследования, не вошедшие в первый том «Историческая живопись В.И. Сурикова», являются фундаментальными и
|
||||||
|
охватывают период с 1890 по 1916 годы жизни В. И. Сурикова. </p>
|
||||||
|
<p>Стоит отметить тот факт, что музейная библиотека является кладезью <b>настоящих библиографических редкостей</b>, к
|
||||||
|
которым можно отнести дореволюционные издания о великом русском художнике, книги с дарственной надписью его
|
||||||
|
потомков; а также книги и периодику из личного собрания В. М. Крутовского с его подписью; и многочисленные
|
||||||
|
дореволюционные нотные издания, оставшиеся в доме художника от семьи музыкантов, квартирантов Красиковых.
|
||||||
|
Таким образом, <b>общее количество всех изданий по В.И. Сурикову, собранных в библиотеке музея, составляет
|
||||||
|
более 100</b>. Сейчас музейная библиография публикуется впервые, ведь следуя миссии музея – мы делаем открытым
|
||||||
|
доступ к тем книжным ценностям, которые помогут будущим исследователям в изучении творческого наследия В. И.
|
||||||
|
Сурикова.</p>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{% extends "core.html" %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<link href="/css/pages.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<section id="page">
|
||||||
|
<article>
|
||||||
|
<h2>Кеменов</h2>
|
||||||
|
<p>Научная деятельность <b>Владимира Семеновича Кеменова</b> (1908 – 1988), многолетнего вице-президента
|
||||||
|
Академии художеств СССР, составила целую эпоху в советском искусствоведении. Вклад ученого в его развитие
|
||||||
|
высоко оценен специалистами. Интересы В. С. Кеменова простирались «От Леонардо да Винчи до Рокуэлла Кента»
|
||||||
|
(так назывался его последний сборник статей) и охватывали западноевропейское (XV-XVII вв.), русское и
|
||||||
|
советское (XVIII-XX вв.), современное зарубежное искусство, теорию эстетики.</p>
|
||||||
|
<p>Однако центральное место в его творчестве занимал В. И. Суриков, о котором учёный писал с 1930-х гг. до конца
|
||||||
|
жизни. Неудивительно, что в 1989 г. вдова учёного Л. Г. Крамаренко передала большую часть архива В. С.
|
||||||
|
Кеменова <b>Музею-усадьбе В. И. Сурикова в Красноярске</b>. Сотрудники музея перевезли документы из Москвы,
|
||||||
|
разместили в административном здании (флигель усадьбы) и бережно сохранили в отдельном шкафу. В 2011 – 2012
|
||||||
|
гг. кандидат исторических наук И. А. Черкасов провёл разбор и описание архива, сформировал <b>личный
|
||||||
|
фонд</b> В. С. Кеменова (Ф. 1. Оп. 1-2. 81 ед. хр.), многие документы которого <b>до сих пор не введены
|
||||||
|
в научный оборот</b>.</p>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,35 @@
|
||||||
|
{% extends "core.html" %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<link href="/css/pages.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<section id="page">
|
||||||
|
<article>
|
||||||
|
<h2>Суриков</h2>
|
||||||
|
<p>Библиотека научно-вспомогательного фонда <b>Музея-усадьбы В.И. Сурикова</b> начала формироваться с 1948 года, когда
|
||||||
|
первые сотрудники самостоятельно стали собирать её, приобретая за свои средства необходимую для работы
|
||||||
|
литературу, прежде всего по осмыслению жизни и творчества <b>В.И. Сурикова</b>, а также специальную
|
||||||
|
профессиональную литературу по экспонированию и иной деятельности в музее. В это время было начато системное
|
||||||
|
взаимодействие с <b>Центральной библиотечной системой им. Горького</b>, поэтому многие издания, поступавшие из
|
||||||
|
библиотеки в музей, имеют её опознавательный знак.
|
||||||
|
Позже, уже с приходом Л. П. Греченко, директора музея-усадьбы с 1970 по 2008 гг., было принято решение
|
||||||
|
ежемесячно закупать книги из бибколлектора (ныне «Центр книги – Красноярский бибколлектор»). </p>
|
||||||
|
<p>Но в 1990-е годы в период экономического спада и дефицита закупка прекратилась, с этого времени библиотека
|
||||||
|
продолжила формироваться за счёт <b>личного вклада</b> сотрудников музея. Особое значение библиотеке уделяла <b>Нина
|
||||||
|
Ярославовна Скалиш</b>, главный хранитель музея на протяжении 45 лет.
|
||||||
|
Основой библиотеки является научная литература, монографии о жизни и творчестве В. И. Сурикова, изданные с
|
||||||
|
1914 по 2018 гг. (кроме того, статьи, каталоги и художественная литература). Библиотека музея включает
|
||||||
|
архивный фонд В. С. Кеменова: рукописи, документы и фотографии, собранные известным суриковедом. Его
|
||||||
|
исследования, не вошедшие в первый том «Историческая живопись В.И. Сурикова», являются фундаментальными и
|
||||||
|
охватывают период с 1890 по 1916 годы жизни В. И. Сурикова. </p>
|
||||||
|
<p>Стоит отметить тот факт, что музейная библиотека является кладезью <b>настоящих библиографических редкостей</b>, к
|
||||||
|
которым можно отнести дореволюционные издания о великом русском художнике, книги с дарственной надписью его
|
||||||
|
потомков; а также книги и периодику из личного собрания В. М. Крутовского с его подписью; и многочисленные
|
||||||
|
дореволюционные нотные издания, оставшиеся в доме художника от семьи музыкантов, квартирантов Красиковых.
|
||||||
|
Таким образом, <b>общее количество всех изданий по В.И. Сурикову, собранных в библиотеке музея, составляет
|
||||||
|
более 100</b>. Сейчас музейная библиография публикуется впервые, ведь следуя миссии музея – мы делаем открытым
|
||||||
|
доступ к тем книжным ценностям, которые помогут будущим исследователям в изучении творческого наследия В. И.
|
||||||
|
Сурикова.</p>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue