ksenia ebanula
This commit is contained in:
24
composer.lock
generated
24
composer.lock
generated
@@ -8,11 +8,11 @@
|
|||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "mirzaev/languages",
|
"name": "mirzaev/languages",
|
||||||
"version": "1.0.2",
|
"version": "1.0.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.svoboda.works/mirzaev/languages",
|
"url": "https://git.svoboda.works/mirzaev/languages",
|
||||||
"reference": "eceff49204c718243f24e3da42294c5ea5b29e01"
|
"reference": "c6e28f25ea1bf42f4f8a201c2919c02fef59a284"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.4"
|
"php": "^8.4"
|
||||||
@@ -38,22 +38,20 @@
|
|||||||
"description": "Library for easy languages support",
|
"description": "Library for easy languages support",
|
||||||
"homepage": "https://git.svoboda.works/mirzaev/languages",
|
"homepage": "https://git.svoboda.works/mirzaev/languages",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"enumeration",
|
|
||||||
"languages"
|
"languages"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://git.svoboda.works/mirzaev/languages/issues",
|
"issues": "https://git.svoboda.works/mirzaev/languages/issues"
|
||||||
"wiki": "https://git.svoboda.works/mirzaev/languages/wiki"
|
|
||||||
},
|
},
|
||||||
"time": "2025-08-21T14:50:06+00:00"
|
"time": "2025-10-21T18:34:30+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "mirzaev/minimal",
|
"name": "mirzaev/minimal",
|
||||||
"version": "3.6.2",
|
"version": "3.7.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.svoboda.works/mirzaev/minimal",
|
"url": "https://git.svoboda.works/mirzaev/minimal",
|
||||||
"reference": "d9e4e0af6cffc169831eec798d00e53187839b8e"
|
"reference": "e604d19eb1a39049bf51e9318cbda952f89e949a"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "~8.4"
|
"php": "~8.4"
|
||||||
@@ -76,18 +74,18 @@
|
|||||||
"role": "Programmer"
|
"role": "Programmer"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "My vision of a good framework",
|
"description": "The best code-to-utility framework",
|
||||||
"homepage": "https://git.mirzaev.sexy/mirzaev/minimal",
|
"homepage": "https://git.svoboda.works/mirzaev/minimal",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"framework",
|
"framework",
|
||||||
"lightweight",
|
"lightweight",
|
||||||
"mvc"
|
"mvc"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"docs": "https://git.mirzaev.sexy/mirzaev/minimal/wiki",
|
"docs": "https://git.svoboda.works/mirzaev/minimal/wiki",
|
||||||
"issues": "https://git.mirzaev.sexy/mirzaev/minimal/issues"
|
"issues": "https://git.svoboda.works/mirzaev/minimal/issues"
|
||||||
},
|
},
|
||||||
"time": "2025-07-16T01:09:25+00:00"
|
"time": "2025-10-25T11:39:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ final class accounts extends core
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not registered
|
// Not registered
|
||||||
var_dump($this->errors); die;
|
var_dump($this->errors);
|
||||||
|
die;
|
||||||
// Sending response
|
// Sending response
|
||||||
$this->response
|
$this->response
|
||||||
->status(status::unauthorized)
|
->status(status::unauthorized)
|
||||||
|
|||||||
@@ -47,16 +47,20 @@ final class books extends core
|
|||||||
*
|
*
|
||||||
* @param int|string|null $identifier Identifier of the book
|
* @param int|string|null $identifier Identifier of the book
|
||||||
* @param int|string $page Page if the book
|
* @param int|string $page Page if the book
|
||||||
*
|
* @param int|string $next Next page if the book
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public function index(
|
public function index(
|
||||||
int|string|null $identifier = null,
|
int|string|null $identifier = null,
|
||||||
int|string $page = 1
|
int|string $page = 1,
|
||||||
|
int|string $next = 0,
|
||||||
|
int|string $last = 0
|
||||||
): null {
|
): null {
|
||||||
// Normalizing the page argument
|
// Normalizing the page argument
|
||||||
$page = (int) $page;
|
$page = (int) $page;
|
||||||
if ($page < 1) $page = 1;
|
if ($page < 1) {
|
||||||
|
$page = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($identifier)) {
|
if (isset($identifier)) {
|
||||||
// Received the book identifier (the book)
|
// Received the book identifier (the book)
|
||||||
@@ -64,11 +68,30 @@ final class books extends core
|
|||||||
// Initializing the book
|
// Initializing the book
|
||||||
$this->view->book = book::read(expressions: ['identifier' => (int) $identifier])[0] ?? null;
|
$this->view->book = book::read(expressions: ['identifier' => (int) $identifier])[0] ?? null;
|
||||||
|
|
||||||
if (empty($page)) {
|
if (!empty($page)) {
|
||||||
// Received the book page
|
// Received the book page
|
||||||
|
|
||||||
// Initializing the book page
|
// Initializing the book page
|
||||||
$this->view->page = $page;
|
$this->view->page = $page;
|
||||||
|
|
||||||
|
//Вынести в модель
|
||||||
|
$next = $page + 1;
|
||||||
|
$directory = \STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $identifier . DIRECTORY_SEPARATOR . $next . '.jpg';
|
||||||
|
|
||||||
|
if (!file_exists($directory)) {
|
||||||
|
$next = $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
$last = $page - 1;
|
||||||
|
|
||||||
|
$directory = \STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $identifier . DIRECTORY_SEPARATOR . $last . '.jpg';
|
||||||
|
|
||||||
|
if (!file_exists($directory)) {
|
||||||
|
$last = $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->view->next = $next;
|
||||||
|
$this->view->last = $last;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str_contains($this->request->headers['accept'] ?? '', content::any->value)) {
|
if (str_contains($this->request->headers['accept'] ?? '', content::any->value)) {
|
||||||
@@ -136,10 +159,12 @@ final class books extends core
|
|||||||
*/
|
*/
|
||||||
public function write(): null
|
public function write(): null
|
||||||
{
|
{
|
||||||
if (account::initialize(errors: $this->errors['account'])->access('books')) {
|
if ($this->account->access('books')) {
|
||||||
// Initialized account and authorized to books
|
// Initialized account and authorized to books
|
||||||
|
|
||||||
if (count($books = book::import(files: $this->request->files['books'] ?? [], errors: $this->errors['books'])) > 0) {
|
if (count($books = book::import(files: $this->request->files['books'] ?? [], errors: $this->errors['books'])) > 0) {
|
||||||
|
$status = true;
|
||||||
|
|
||||||
// Imported books
|
// Imported books
|
||||||
} else {
|
} else {
|
||||||
// Not imported books
|
// Not imported books
|
||||||
@@ -172,26 +197,25 @@ final class books extends core
|
|||||||
|
|
||||||
// Normalizing the page argument
|
// Normalizing the page argument
|
||||||
$page = (int) $page;
|
$page = (int) $page;
|
||||||
if ($page < 1) $page = 1;
|
if ($page < 1) {
|
||||||
|
$page = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Initializing the book file path
|
// Initializing the publication file path
|
||||||
$file = \STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $identifier . DIRECTORY_SEPARATOR . $page . '.jpg';
|
$file = \STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $identifier . DIRECTORY_SEPARATOR . $page . '.jpg';
|
||||||
|
|
||||||
|
// Reading the file
|
||||||
|
$stream = fopen($file, 'rb');
|
||||||
|
|
||||||
if (file_exists($file)) {
|
if (file_exists($file)) {
|
||||||
// Found the book page file
|
// Found the publication page file
|
||||||
|
|
||||||
// Initializing headers
|
// Initializing headers
|
||||||
header('Content-Description: File Transfer');
|
header('Content-Type: image/jpg');
|
||||||
header('Content-Type: image/jpeg');
|
|
||||||
header('Content-Disposition: attachment; filename=' . basename($file));
|
|
||||||
header('Content-Transfer-Encoding: binary');
|
|
||||||
header('Content-Length: ' . filesize($file));
|
header('Content-Length: ' . filesize($file));
|
||||||
|
|
||||||
// Cleaning the output buffer
|
// Cleaning the output buffer
|
||||||
ob_end_clean();
|
fpassthru($stream);
|
||||||
|
|
||||||
// Exit (success)
|
|
||||||
return file_get_contents($file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit (fail)
|
// Exit (fail)
|
||||||
@@ -207,7 +231,7 @@ final class books extends core
|
|||||||
*
|
*
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
public function delete(int|string|null $identifier = null): null
|
public function delete(int|string|null $identifier = null, int $active = 0): null
|
||||||
{
|
{
|
||||||
if (account::initialize(errors: $this->errors['account'])->access('books')) {
|
if (account::initialize(errors: $this->errors['account'])->access('books')) {
|
||||||
// Initialized account and authorized to books
|
// Initialized account and authorized to books
|
||||||
@@ -218,22 +242,14 @@ final class books extends core
|
|||||||
// Normalizing the identifier argument
|
// Normalizing the identifier argument
|
||||||
$identifier = (int) $identifier;
|
$identifier = (int) $identifier;
|
||||||
|
|
||||||
if (book::delete(identifier: $identifier, errors: $this->errors['books'])) {
|
if (book::delete(identifier: $identifier, active: $active, errors: $this->errors['books'])) {
|
||||||
// Deleted the book from the database
|
// Deleted the book from the database
|
||||||
|
|
||||||
// Initializing the book directory path
|
// Initializing the book directory path
|
||||||
$directory = \STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $identifier;
|
$directory = \STORAGE . DIRECTORY_SEPARATOR . 'books' . DIRECTORY_SEPARATOR . $identifier;
|
||||||
|
|
||||||
if (file_exists($directory)) {
|
|
||||||
// Found the book directory
|
|
||||||
|
|
||||||
// Deletimg the book from the storage
|
|
||||||
exec('rm -rf ' . escapeshellarg($directory));
|
|
||||||
|
|
||||||
// Writing the processing status
|
|
||||||
$status = true;
|
$status = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (str_contains($this->request->headers['accept'] ?? '', content::json->value)) {
|
if (str_contains($this->request->headers['accept'] ?? '', content::json->value)) {
|
||||||
// Request for JSON response
|
// Request for JSON response
|
||||||
|
|||||||
@@ -41,6 +41,13 @@ class core extends controller
|
|||||||
*/
|
*/
|
||||||
protected language $language = language::ru;
|
protected language $language = language::ru;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Account
|
||||||
|
*
|
||||||
|
* @var account $account Account
|
||||||
|
*/
|
||||||
|
// protected account $account;
|
||||||
|
protected ?account $account = null;
|
||||||
/**
|
/**
|
||||||
* Response
|
* Response
|
||||||
*
|
*
|
||||||
@@ -74,15 +81,21 @@ class core extends controller
|
|||||||
public function __construct(minimal $core)
|
public function __construct(minimal $core)
|
||||||
{
|
{
|
||||||
// Blocking requests from CloudFlare (better to write this blocking into nginx config file)
|
// Blocking requests from CloudFlare (better to write this blocking into nginx config file)
|
||||||
if (isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] === 'nginx-ssl early hints') return status::bruh->label;
|
if (isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] === 'nginx-ssl early hints')
|
||||||
|
return status::bruh->label;
|
||||||
|
|
||||||
// Initializing the models core
|
// Initializing the models core
|
||||||
new models();
|
new models();
|
||||||
|
|
||||||
|
$this->account = account::initialize(errors: $this->errors['account']);
|
||||||
|
|
||||||
|
|
||||||
// Initializing the view template engine instance
|
// Initializing the view template engine instance
|
||||||
$this->view = new templater(account::initialize(errors: $this->errors['account']));
|
$this->view = new templater($this->account);
|
||||||
|
|
||||||
// For the extends system
|
// For the extends system
|
||||||
parent::__construct(core: $core);
|
parent::__construct(core: $core);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ namespace kodorvan\surikov\controllers;
|
|||||||
|
|
||||||
// Files of the project
|
// Files of the project
|
||||||
use kodorvan\surikov\controllers\core,
|
use kodorvan\surikov\controllers\core,
|
||||||
kodorvan\surikov\models\account;
|
kodorvan\surikov\models\account,
|
||||||
|
kodorvan\surikov\models\publication;
|
||||||
|
|
||||||
// Framework for PHP
|
// Framework for PHP
|
||||||
use mirzaev\minimal\http\enumerations\content,
|
use mirzaev\minimal\http\enumerations\content,
|
||||||
@@ -33,16 +34,20 @@ final class index extends core
|
|||||||
*/
|
*/
|
||||||
protected array $errors = [
|
protected array $errors = [
|
||||||
'system' => [],
|
'system' => [],
|
||||||
'account' => []
|
'account' => [],
|
||||||
];
|
|
||||||
|
|
||||||
|
];
|
||||||
|
var_dump($this->request->headers['accept']);
|
||||||
|
die;
|
||||||
/**
|
/**
|
||||||
* Main page
|
* Main page
|
||||||
*
|
*
|
||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function index(): null
|
public function index(): null
|
||||||
{
|
{
|
||||||
|
|
||||||
if (str_contains($this->request->headers['accept'] ?? '', content::any->value)) {
|
if (str_contains($this->request->headers['accept'] ?? '', content::any->value)) {
|
||||||
// Request for any response
|
// Request for any response
|
||||||
|
|
||||||
@@ -70,3 +75,32 @@ final class index extends core
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// public function index(): null
|
||||||
|
// {
|
||||||
|
|
||||||
|
// if (str_contains($this->request->headers['accept'] ?? '', content::any->value)) {
|
||||||
|
// // Request for any response
|
||||||
|
|
||||||
|
// // Render page
|
||||||
|
// $page = $this->view->render('main/index.html');
|
||||||
|
|
||||||
|
// // Sending response
|
||||||
|
// $this->response
|
||||||
|
// ->start()
|
||||||
|
// ->clean()
|
||||||
|
// ->sse()
|
||||||
|
// ->write($page)
|
||||||
|
// ->validate($this->request)
|
||||||
|
// ?->body()
|
||||||
|
// ->end();
|
||||||
|
|
||||||
|
// // Deinitializing rendered page
|
||||||
|
// unset($page);
|
||||||
|
|
||||||
|
// // Exit (success)
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Exit (fail)
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
446
kodorvan/surikov/system/controllers/publications.php
Normal file
446
kodorvan/surikov/system/controllers/publications.php
Normal file
@@ -0,0 +1,446 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace kodorvan\surikov\controllers;
|
||||||
|
|
||||||
|
// The project
|
||||||
|
use kodorvan\surikov\controllers\core,
|
||||||
|
kodorvan\surikov\models\account,
|
||||||
|
kodorvan\surikov\models\publication;
|
||||||
|
|
||||||
|
// Framework for PHP
|
||||||
|
use mirzaev\minimal\http\enumerations\content,
|
||||||
|
mirzaev\minimal\http\enumerations\status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publications controller
|
||||||
|
*
|
||||||
|
* @package kodorvan\surikov\controllers
|
||||||
|
*
|
||||||
|
* @param array $errors Registry of errors
|
||||||
|
*
|
||||||
|
* @method null index() Publications page
|
||||||
|
* @method null write() Write
|
||||||
|
* @method null read(int|string|null $identifier, int|string|null $page) Read
|
||||||
|
* @method null delete(int|string|null $identifier) Delete
|
||||||
|
* @method null rotate(int|string|null $identifier, int|string|null $page) Rotate
|
||||||
|
*
|
||||||
|
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||||
|
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||||
|
*/
|
||||||
|
final class publications extends core
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Errors
|
||||||
|
*
|
||||||
|
* @var array $errors Registry of errors
|
||||||
|
*/
|
||||||
|
protected array $errors = [
|
||||||
|
'system' => [],
|
||||||
|
'account' => [],
|
||||||
|
'publications' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data verification
|
||||||
|
*
|
||||||
|
* @param string|null $title Title if the publication
|
||||||
|
* @param string|null $content Content if the publication
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
private function data(string|null $title, string|null $content): bool
|
||||||
|
{
|
||||||
|
//Removing spaces
|
||||||
|
$title = trim($title ?? '');
|
||||||
|
$content = trim($content ?? '');
|
||||||
|
|
||||||
|
//Checking for the existence of data
|
||||||
|
if (empty($title)) {
|
||||||
|
|
||||||
|
//Error recording
|
||||||
|
$this->errors['publications'][] = 'Заголовок не может быть пустым';
|
||||||
|
|
||||||
|
// Exit (failed)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Removing the shielding "/"
|
||||||
|
$title = stripslashes($title);
|
||||||
|
$content = stripslashes($content);
|
||||||
|
|
||||||
|
//Checking the length
|
||||||
|
if (mb_strlen($title) > 255) {
|
||||||
|
|
||||||
|
//Error recording
|
||||||
|
$this->errors['publications'][] = 'Заголовок слишком длинный';
|
||||||
|
|
||||||
|
// Exit (failed)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Checking the length
|
||||||
|
if (mb_strlen($content) > 1000) {
|
||||||
|
|
||||||
|
//Error recording
|
||||||
|
$this->errors['publications'][] = 'Содержание слишком большое!';
|
||||||
|
|
||||||
|
// Exit (failed)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processing of uploaded files
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function files($identifier): array|null
|
||||||
|
{
|
||||||
|
//Presence of uploaded files
|
||||||
|
if (!empty($_FILES['publications']['tmp_name'])) {
|
||||||
|
|
||||||
|
//Array for storing data
|
||||||
|
$files = [];
|
||||||
|
|
||||||
|
// Path to the directory to save
|
||||||
|
$dir = \STORAGE . DIRECTORY_SEPARATOR . 'publications' . DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
|
//Maximum file size (5MB)
|
||||||
|
$size = 5 * 1024 * 1024;
|
||||||
|
|
||||||
|
// Acceptable MIME types
|
||||||
|
$types = ['image/jpeg', 'image/png', 'image/gif'];
|
||||||
|
|
||||||
|
//Checking if the directory exists and creating it if it doesn't
|
||||||
|
if (!is_dir($dir) && !mkdir($dir, 0755, true)) {
|
||||||
|
$this->errors['publications'][] = 'Не удалось создать путь для изображения';
|
||||||
|
|
||||||
|
// Exit (failed)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Verifying write permissions to a directory
|
||||||
|
if (!is_writable($dir)) {
|
||||||
|
$this->errors['publications'][] = 'Директория недоступна для записи';
|
||||||
|
|
||||||
|
// Exit (failed)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processing of each file
|
||||||
|
foreach ($_FILES['publications']['tmp_name'] as $key => $tmp) {
|
||||||
|
|
||||||
|
/// Checking the upload to a temporary server
|
||||||
|
if (empty($tmp) || $_FILES['publications']['error'][$key] !== UPLOAD_ERR_OK) {
|
||||||
|
$this->errors['publications'][] = 'Ошибка загрузки файла ';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checking the file size
|
||||||
|
if ($_FILES['publications']['size'][$key] > $size) {
|
||||||
|
$this->errors['publications'][] = 'Размер изображения не должен превышать 5MB';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//// Defining the MIME type of a file
|
||||||
|
$type = mime_content_type($tmp);
|
||||||
|
|
||||||
|
// Checking the file type validity
|
||||||
|
if (!in_array($type, $types)) {
|
||||||
|
$this->errors['publications'][] = 'Недопустимый тип файла';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Full path to save
|
||||||
|
$path = trim($dir . $identifier . '.png');
|
||||||
|
|
||||||
|
//// Moving a file from a temporary directory
|
||||||
|
if (!move_uploaded_file($tmp, $path)) {
|
||||||
|
$this->errors['publications'][] = 'Ошибка при загрузке файла на сервер: ' . $_FILES['publications']['name'][$key];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// checking the existence of the file after moving
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
$this->erroFrs['publications'][] = 'Файл не был сохранен: ' . $identifier;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collecting information about a file
|
||||||
|
$files[] = [
|
||||||
|
'path' => $path,
|
||||||
|
'name' => $identifier,
|
||||||
|
'size' => $_FILES['publications']['size'][$key],
|
||||||
|
'type' => $type
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Exit (Succes)
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Exit (Failed)
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read
|
||||||
|
*
|
||||||
|
* Read the publication image
|
||||||
|
*
|
||||||
|
* @param int|string|null $identifier Identifier of the publication
|
||||||
|
*
|
||||||
|
* @return string|null The publication image
|
||||||
|
*/
|
||||||
|
public function read(int|string|null $identifier = null): ?string
|
||||||
|
{
|
||||||
|
// Normalizing the identifier argument
|
||||||
|
$identifier = (int) $identifier;
|
||||||
|
|
||||||
|
// Initializing the publication file path
|
||||||
|
$file = \STORAGE . DIRECTORY_SEPARATOR . 'publications' . DIRECTORY_SEPARATOR . $identifier . '.png';
|
||||||
|
|
||||||
|
// Reading the file
|
||||||
|
$stream = fopen($file, 'rb');
|
||||||
|
|
||||||
|
if (file_exists($file)) {
|
||||||
|
// Found the publication page file
|
||||||
|
|
||||||
|
// Initializing headers
|
||||||
|
header('Content-Type: image/png');
|
||||||
|
header('Content-Length: ' . filesize($file));
|
||||||
|
|
||||||
|
// Cleaning the output buffer
|
||||||
|
fpassthru($stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (fail)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publications page
|
||||||
|
*
|
||||||
|
* @param int|string $page Page if the publication
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
public function index(
|
||||||
|
int|string $page = 1,
|
||||||
|
): null {
|
||||||
|
// Reading publications
|
||||||
|
$this->view->publications = publication::read(expressions: ['active' => true], limit: 30, page: $page, sort: '`created` DESC');
|
||||||
|
|
||||||
|
if (str_contains($this->request->headers['accept'] ?? '', content::any->value)) {
|
||||||
|
// Request for any response
|
||||||
|
|
||||||
|
// Render page
|
||||||
|
$page = $this->view->render('main/index.html');
|
||||||
|
|
||||||
|
// Sending response
|
||||||
|
$this->response
|
||||||
|
->start()
|
||||||
|
->clean()
|
||||||
|
->sse()
|
||||||
|
->write($page)
|
||||||
|
->validate($this->request)
|
||||||
|
?->body()
|
||||||
|
->end();
|
||||||
|
|
||||||
|
// Deinitializing rendered page
|
||||||
|
unset($page);
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write
|
||||||
|
*
|
||||||
|
* Import publications into the storage and the database
|
||||||
|
* @param string|null $title Title if the publication
|
||||||
|
* @param string|null $content Content if the publication
|
||||||
|
* @param int|bool $active Relevance if the publication
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
public function write(string|null $title = null, string|null $content = null, int|bool $active = 1): null
|
||||||
|
{
|
||||||
|
// Initialized account and authorized to publications
|
||||||
|
if ($this->account->access('publications')) {
|
||||||
|
|
||||||
|
//Data verification
|
||||||
|
if ($this->data($title, $content)) {
|
||||||
|
|
||||||
|
$identifier = 0;
|
||||||
|
|
||||||
|
//Processing uploaded files
|
||||||
|
$identifier = publication::write($title, $content, $active, $this->account->identifier, $this->errors['publications']);
|
||||||
|
|
||||||
|
if ($identifier) {
|
||||||
|
|
||||||
|
// Recording a publication
|
||||||
|
$status = true;
|
||||||
|
|
||||||
|
//Image verification
|
||||||
|
$this->files($identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$status = false;
|
||||||
|
// Data verification failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reading publications
|
||||||
|
$this->view->publication = publication::read(expressions: ['account' => (int) $this->account->identifier], sort: '`created` DESC')[0] ?? null;
|
||||||
|
|
||||||
|
// Redirecting
|
||||||
|
$publications = $this->view->render('publication.html');
|
||||||
|
|
||||||
|
// Sending response
|
||||||
|
$this->response
|
||||||
|
->start()
|
||||||
|
->clean()
|
||||||
|
->sse()
|
||||||
|
->write($publications)
|
||||||
|
->validate($this->request)
|
||||||
|
?->body()
|
||||||
|
->end();
|
||||||
|
|
||||||
|
// Deinitializing rendered page
|
||||||
|
unset($publications);
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update
|
||||||
|
*
|
||||||
|
* Update a post in the database and images
|
||||||
|
*
|
||||||
|
* @param string|null $title Post title
|
||||||
|
* @param string|null $content Post content
|
||||||
|
* @param int|string|null $identifier Post identifier
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
public function update(string|null $title = null, string|null $content = null, int|string|null $identifier = null): null
|
||||||
|
{
|
||||||
|
// Initialized account and authorized to publications
|
||||||
|
if ($this->account->access('publications')) {
|
||||||
|
|
||||||
|
//Converting an identifier to Int
|
||||||
|
$identifier = (int) $identifier;
|
||||||
|
|
||||||
|
//Data verification
|
||||||
|
if ($this->data($title, $content) && $identifier > 0) {
|
||||||
|
|
||||||
|
//Image verification
|
||||||
|
$files = $this->files($identifier);
|
||||||
|
|
||||||
|
if (publication::update($identifier, $title, $content, $files, $this->errors['publications'])) {
|
||||||
|
$status = true;
|
||||||
|
//Updating the publication
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$status = false;
|
||||||
|
//Not updating the publication
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$status = false;
|
||||||
|
//Data verification failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reading publications
|
||||||
|
$this->view->publication = publication::read(expressions: ['account' => (int) $this->account->identifier], sort: '`created` DESC')[0] ?? null;
|
||||||
|
|
||||||
|
// Redirecting
|
||||||
|
$publications = $this->view->render('publication.html');
|
||||||
|
|
||||||
|
// Sending response
|
||||||
|
$this->response
|
||||||
|
->start()
|
||||||
|
->clean()
|
||||||
|
->sse()
|
||||||
|
->write($publications)
|
||||||
|
->validate($this->request)
|
||||||
|
?->body()
|
||||||
|
->end();
|
||||||
|
|
||||||
|
// Deinitializing rendered page
|
||||||
|
unset($publications);
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete
|
||||||
|
*
|
||||||
|
* Delete the publication from the storage and the database
|
||||||
|
*
|
||||||
|
* @param int|string|null $identifier Identifier of the publication
|
||||||
|
* @param int|bool $active Relevance if the publication
|
||||||
|
*
|
||||||
|
* @return null
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function delete(int|string|null $identifier = null, int|bool $active = 0): null
|
||||||
|
{
|
||||||
|
// Initialized account and authorized to publications
|
||||||
|
if ($this->account->access('publications')) {
|
||||||
|
|
||||||
|
//Converting an identifier to Int
|
||||||
|
$identifier = (int) $identifier;
|
||||||
|
|
||||||
|
//Verification identifier
|
||||||
|
if ($identifier > 0) {
|
||||||
|
|
||||||
|
if (publication::delete($identifier, $active, $this->errors['publications'])) {
|
||||||
|
$status = true;
|
||||||
|
//Deleting publication
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$status = false;
|
||||||
|
//Not Deleting publication
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$status = false;
|
||||||
|
//Data verification failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reading publications
|
||||||
|
$this->view->publication = publication::read(expressions: ['account' => (int) $this->account->identifier], sort: '`created` DESC')[0] ?? null;
|
||||||
|
|
||||||
|
// Redirecting
|
||||||
|
$publications = $this->view->render('publication.html');
|
||||||
|
|
||||||
|
// Sending response
|
||||||
|
$this->response
|
||||||
|
->start()
|
||||||
|
->clean()
|
||||||
|
->sse()
|
||||||
|
->write($publications)
|
||||||
|
->validate($this->request)
|
||||||
|
?->body()
|
||||||
|
->end();
|
||||||
|
|
||||||
|
// Deinitializing rendered page
|
||||||
|
unset($publications);
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -97,7 +97,8 @@ final class account extends core
|
|||||||
// Iterating over parameters
|
// Iterating over parameters
|
||||||
|
|
||||||
// Writing the property
|
// Writing the property
|
||||||
if (property_exists($this, $key)) $this->$key = $value;
|
if (property_exists($this, $key))
|
||||||
|
$this->$key = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +133,7 @@ final class account extends core
|
|||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
$account = static::authenticate(mail: $mail, password: $password, remember: true, errors: $errors);
|
$account = static::authenticate(mail: $mail, password: $password, remember: true, errors: $errors);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit (success)
|
// Exit (success)
|
||||||
@@ -338,10 +340,12 @@ final class account extends core
|
|||||||
throw new exception('Вы аутентифицированы с другого устройства (не совпадают хеши аутентификации)');
|
throw new exception('Вы аутентифицированы с другого устройства (не совпадают хеши аутентификации)');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($account = static::read([
|
if (
|
||||||
|
empty($account = static::read([
|
||||||
'identifier' => $_COOKIE['identifier'],
|
'identifier' => $_COOKIE['identifier'],
|
||||||
'hash' => $_COOKIE['hash']
|
'hash' => $_COOKIE['hash']
|
||||||
]))) {
|
]))
|
||||||
|
) {
|
||||||
// Not found the account or a connection with it
|
// Not found the account or a connection with it
|
||||||
|
|
||||||
// Exit (fail)
|
// Exit (fail)
|
||||||
@@ -477,16 +481,21 @@ final class account extends core
|
|||||||
$parameters = [];
|
$parameters = [];
|
||||||
|
|
||||||
// Filtering the parameter
|
// Filtering the parameter
|
||||||
if (filter_var($mail, FILTER_VALIDATE_EMAIL) === false) throw new exception('Не удалось распознать почту');
|
if (filter_var($mail, FILTER_VALIDATE_EMAIL) === false)
|
||||||
if (iconv_strlen($mail) < 3) throw new exception('Длина почты должна быть не менее 3 символов');
|
throw new exception('Не удалось распознать почту');
|
||||||
if (iconv_strlen($mail) > 60) throw new exception('Длина почты должна быть не более 80 символов');
|
if (iconv_strlen($mail) < 3)
|
||||||
|
throw new exception('Длина почты должна быть не менее 3 символов');
|
||||||
|
if (iconv_strlen($mail) > 60)
|
||||||
|
throw new exception('Длина почты должна быть не более 80 символов');
|
||||||
|
|
||||||
// Writing the parameter
|
// Writing the parameter
|
||||||
$parameters[':mail'] = $mail;
|
$parameters[':mail'] = $mail;
|
||||||
|
|
||||||
// Filtering the parameter
|
// Filtering the parameter
|
||||||
if (iconv_strlen($password) < 3) throw new exception('Длина пароля должна быть не менее 3 символов');
|
if (iconv_strlen($password) < 3)
|
||||||
if (iconv_strlen($password) > 60) throw new exception('Длина пароля должна быть не более 120 символов');
|
throw new exception('Длина пароля должна быть не менее 3 символов');
|
||||||
|
if (iconv_strlen($password) > 60)
|
||||||
|
throw new exception('Длина пароля должна быть не более 120 символов');
|
||||||
|
|
||||||
// Writing the parameter
|
// Writing the parameter
|
||||||
$parameters[':password'] = password_hash($password, PASSWORD_BCRYPT);
|
$parameters[':password'] = password_hash($password, PASSWORD_BCRYPT);
|
||||||
|
|||||||
@@ -149,14 +149,16 @@ final class book extends core
|
|||||||
*
|
*
|
||||||
* @return bool Is the book was deleted?
|
* @return bool Is the book was deleted?
|
||||||
*/
|
*/
|
||||||
public static function delete(int $identifier, array &$errors = []): bool
|
public static function delete(int $identifier, int $active, array &$errors = []): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// Initializing the request
|
// Initializing the request
|
||||||
$request = static::$database->prepare("DELETE FROM `books` WHERE `identifier` = :identifier LIMIT 1");
|
$request = static::$database->prepare("UPDATE `books` SET `active` = :active WHERE `identifier` = :identifier LIMIT 1");
|
||||||
|
|
||||||
// Sending the request
|
// Sending the request
|
||||||
$request->execute([':identifier' => $identifier]);
|
$request->execute([
|
||||||
|
':identifier' => $identifier,
|
||||||
|
':active' => $active,
|
||||||
|
]);
|
||||||
|
|
||||||
// Exit (success)
|
// Exit (success)
|
||||||
return true;
|
return true;
|
||||||
@@ -190,6 +192,7 @@ final class book extends core
|
|||||||
public static function import(array $files, ?int $account = null, array &$errors = []): array|false
|
public static function import(array $files, ?int $account = null, array &$errors = []): array|false
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (empty($files)) {
|
if (empty($files)) {
|
||||||
// Not received books
|
// Not received books
|
||||||
|
|
||||||
@@ -251,7 +254,7 @@ final class book extends core
|
|||||||
exec("pdfimages -j '$file' '$directory'");
|
exec("pdfimages -j '$file' '$directory'");
|
||||||
|
|
||||||
// Renaming files
|
// Renaming files
|
||||||
exec("echo 'export j=-1; for i in $directory*.jpg; do let j+=1; mv \$i $directory\$j.jpg; done' | bash");
|
exec("echo 'export j=0; for i in $directory*.jpg; do let j+=1; mv \$i $directory\$j.jpg; done' | bash");
|
||||||
|
|
||||||
// Writing into the buffer of writed books
|
// Writing into the buffer of writed books
|
||||||
$writed[] = $identifier;
|
$writed[] = $identifier;
|
||||||
@@ -363,11 +366,11 @@ final class book extends core
|
|||||||
'stack' => $e->getTrace()
|
'stack' => $e->getTrace()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit (fail)
|
// Exit (fail)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Amount
|
* Amount
|
||||||
*
|
*
|
||||||
|
|||||||
252
kodorvan/surikov/system/models/publication.php
Normal file
252
kodorvan/surikov/system/models/publication.php
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace kodorvan\surikov\models;
|
||||||
|
|
||||||
|
// Built-in libraries
|
||||||
|
use pdo,
|
||||||
|
exception;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publication model
|
||||||
|
*
|
||||||
|
* @package kodorvan\surikov\models
|
||||||
|
*
|
||||||
|
* @param
|
||||||
|
*
|
||||||
|
* @method static int|null write(string $title, ?string $content, int $active, int $account, array &$errors) Write
|
||||||
|
*
|
||||||
|
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||||
|
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||||
|
*/
|
||||||
|
final class publication extends core
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Write
|
||||||
|
*
|
||||||
|
* Write into the database
|
||||||
|
*
|
||||||
|
* @param string $title Title
|
||||||
|
* @param string|null $content Сontent
|
||||||
|
* @param int $active Active of the publication
|
||||||
|
* @param int $account Identifier of the publication
|
||||||
|
* @param array &$errors Registry of errors
|
||||||
|
*
|
||||||
|
* @return int|bool The book publication
|
||||||
|
*/
|
||||||
|
public static function write(string $title, ?string $content, int $active, int $account, array &$errors = []): int|bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
//Current date
|
||||||
|
$time = date("Y-m-d H:i:s");
|
||||||
|
|
||||||
|
// Initializing the request
|
||||||
|
$request = static::$database->prepare("INSERT INTO `publications` (`account`, `title`, `content`, `updated`, `created`,`active`) VALUES (:account, :title, :content, :updated, :created, :active) ;");
|
||||||
|
|
||||||
|
// Initializing the request parameters
|
||||||
|
$parameters = [
|
||||||
|
':account' => $account,
|
||||||
|
':title' => $title,
|
||||||
|
':content' => $content,
|
||||||
|
':updated' => $time,
|
||||||
|
':created' => $time,
|
||||||
|
':active' => $active
|
||||||
|
];
|
||||||
|
|
||||||
|
// Sending the request
|
||||||
|
$request->execute($parameters);
|
||||||
|
|
||||||
|
// Initializing the request
|
||||||
|
$request = static::$database->prepare("SELECT `identifier` FROM `publications` WHERE `account` = :account AND `created` = :created ORDER BY `identifier` DESC LIMIT 1");
|
||||||
|
|
||||||
|
// Initializing the request parameters
|
||||||
|
$request->execute([
|
||||||
|
':account' => $account,
|
||||||
|
':created' => $time
|
||||||
|
]);
|
||||||
|
|
||||||
|
//Getting the identifier
|
||||||
|
$result = $request->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
//Exit (true)
|
||||||
|
return (int) $result['identifier'];
|
||||||
|
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Exception
|
||||||
|
|
||||||
|
// Writing into the errors registry
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (fail)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read
|
||||||
|
*
|
||||||
|
* Read publication from the database
|
||||||
|
*
|
||||||
|
* @param array $expressions Request expressions
|
||||||
|
* @param string $sort Sort
|
||||||
|
* @param int $limit Amount
|
||||||
|
* @param int $page Page (offset by $limit)
|
||||||
|
* @param array &$errors Registry of errors
|
||||||
|
*
|
||||||
|
* @return array|false Books
|
||||||
|
*/
|
||||||
|
public static function read(array $expressions = [], string $sort = '', int $limit = 1, int $page = 1, array &$errors = []): array|false
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Initializing the request row
|
||||||
|
$row = 'WHERE ';
|
||||||
|
|
||||||
|
// Initializing the request parameters
|
||||||
|
$parameters = [];
|
||||||
|
|
||||||
|
foreach ($expressions as $name => $value) {
|
||||||
|
// Iterating over the request expressions
|
||||||
|
|
||||||
|
// Generating the request row
|
||||||
|
$row .= "`$name` = :$name &&";
|
||||||
|
|
||||||
|
// Generating the request parameters
|
||||||
|
$parameters[":$name"] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleaning the request row
|
||||||
|
$row = empty($expressions) ? '' : trim(trim($row, '&&'));
|
||||||
|
|
||||||
|
//Forming a query sort
|
||||||
|
$order = empty($sort) ? '' : "ORDER BY $sort";
|
||||||
|
|
||||||
|
// Initializing the page
|
||||||
|
$page = $limit * --$page;
|
||||||
|
|
||||||
|
// Initializing the request
|
||||||
|
$request = static::$database->prepare("SELECT * FROM `publications` $row $order LIMIT $page, $limit");
|
||||||
|
|
||||||
|
// Sending the request
|
||||||
|
$request->execute($parameters);
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return (array) $request->fetchAll(pdo::FETCH_ASSOC);
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Exception
|
||||||
|
|
||||||
|
// Writing into the errors registry
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (fail)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update
|
||||||
|
*
|
||||||
|
* Update the database from the database
|
||||||
|
*
|
||||||
|
* @param int $identifier Identifier
|
||||||
|
* @param string $title Title
|
||||||
|
* @param string $content Content
|
||||||
|
*
|
||||||
|
* @param array &$errors Registry of errors
|
||||||
|
*
|
||||||
|
* @return bool Is the publications was deleted?
|
||||||
|
*/
|
||||||
|
public static function update(int $identifier, string $title, ?string $content, ?array $files, array &$errors = []): ?bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Initializing the request
|
||||||
|
$request = static::$database->prepare("UPDATE `publications` SET `title` = :title, `content` = :content WHERE `identifier` = :identifier ");
|
||||||
|
|
||||||
|
// Initializing the request parameters
|
||||||
|
$parameters = [
|
||||||
|
':title' => $title,
|
||||||
|
':content' => $content,
|
||||||
|
':identifier' => $identifier,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Sending the request
|
||||||
|
$request->execute($parameters);
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Exception
|
||||||
|
|
||||||
|
// Writing into the errors registry
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (fail)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete
|
||||||
|
*
|
||||||
|
* Delete the publication from the database
|
||||||
|
*
|
||||||
|
* @param int $identifier Identifier
|
||||||
|
* @param int $active Active
|
||||||
|
* @param int $limit Amount
|
||||||
|
*
|
||||||
|
* @param array &$errors Registry of errors
|
||||||
|
*
|
||||||
|
* @return bool Is the publication was deleted?
|
||||||
|
*/
|
||||||
|
public static function delete(int $identifier, int $active, array &$errors = []): bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Initializing the request
|
||||||
|
$request = static::$database->prepare("UPDATE `publications` SET `active` = :active WHERE `identifier` = :identifier LIMIT 1");
|
||||||
|
|
||||||
|
// Initializing the request parameters
|
||||||
|
$parameters = [
|
||||||
|
':identifier' => $identifier,
|
||||||
|
':active' => $active,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Sending the request
|
||||||
|
$request->execute($parameters);
|
||||||
|
|
||||||
|
// Exit (success)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} catch (exception $e) {
|
||||||
|
// Exception
|
||||||
|
|
||||||
|
// Writing into the errors registry
|
||||||
|
$errors[] = [
|
||||||
|
'text' => $e->getMessage(),
|
||||||
|
'file' => $e->getFile(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'stack' => $e->getTrace()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit (fail)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,17 +20,17 @@ main>section#books>form.upload>p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main > section#books > article.book {
|
main > section#books > article.book {
|
||||||
width: calc(100% / 3 - 20px);
|
|
||||||
height: 220px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
|
width: calc(100% / 3 - 20px);
|
||||||
|
height: 220px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-radius: 3px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #b38b8b;
|
border-radius: 3px;
|
||||||
transition: .1s ease-in-out;
|
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
|
background-color: #b38b8b;
|
||||||
|
transition: 0.1s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
main > section#books > article.book:hover {
|
main > section#books > article.book:hover {
|
||||||
@@ -53,23 +53,23 @@ main>section#books>article.book>button {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: none;
|
border: none;
|
||||||
color: #ff5757;
|
color: #ff5757;
|
||||||
background-color: rgba(0, 0, 0, .5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
main > section#books > article.book:hover > button {
|
main > section#books > article.book:hover > button {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
transition: .2s ease-in-out;
|
transition: 0.2s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
main > section#books > article.book > button:hover {
|
main > section#books > article.book > button:hover {
|
||||||
color: #ff6b6b;
|
color: #ff6b6b;
|
||||||
background-color: rgba(0, 0, 0, .4);
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
main > section#books > article.book > button:active {
|
main > section#books > article.book > button:active {
|
||||||
color: #e04d4d;
|
color: #e04d4d;
|
||||||
background-color: rgba(0, 0, 0, .6);
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
main > section#books > article.book:nth-child(3n) {
|
main > section#books > article.book:nth-child(3n) {
|
||||||
@@ -84,8 +84,9 @@ main>section#books>:is(form.upload, article.book):nth-last-child(3) {
|
|||||||
|
|
||||||
main > section#books > article.book > img {
|
main > section#books > article.book > img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: auto;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
object-position: right;
|
/* object-position: right; */
|
||||||
text-align: center;
|
text-align: center;
|
||||||
/* overflow: hidden; */
|
/* 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); */
|
||||||
@@ -104,7 +105,7 @@ main>section#books>article.book>h4 {
|
|||||||
-ms-hyphens: auto;
|
-ms-hyphens: auto;
|
||||||
hyphens: auto;
|
hyphens: auto;
|
||||||
color: #e8e8e8;
|
color: #e8e8e8;
|
||||||
background-color: rgba(0, 0, 0, .5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
main > section#books > article.book > h4:hover {
|
main > section#books > article.book > h4:hover {
|
||||||
@@ -121,7 +122,7 @@ main>section#books>article.book>p {
|
|||||||
|
|
||||||
main > section#book > img,
|
main > section#book > img,
|
||||||
main > section#book > img::before {
|
main > section#book > img::before {
|
||||||
margin-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,9 +135,15 @@ main>section#book>img::before{
|
|||||||
}
|
}
|
||||||
|
|
||||||
main > section#book > nav > ul {
|
main > section#book > nav > ul {
|
||||||
margin: 0;
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
gap: 15px;
|
||||||
|
width: 200px;
|
||||||
|
|
||||||
|
justify-items: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
display: flex;
|
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,9 +156,11 @@ main>section#book>nav>ul>li:only-of-type {
|
|||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
main > section#book > nav > ul > li {
|
main > section#book > nav > ul > li {
|
||||||
margin-right: 15px;
|
/* margin-right: 15px; */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
main > section#book > nav > ul > li:first-of-type,
|
main > section#book > nav > ul > li:first-of-type,
|
||||||
@@ -174,10 +183,20 @@ main>section#book>nav>ul>li.icon>i {
|
|||||||
color: #9b3d10;
|
color: #9b3d10;
|
||||||
}
|
}
|
||||||
|
|
||||||
main>section#book>nav>ul>li.icon>i:hover {
|
main > section#book > nav > ul > li.icon > i:hover,
|
||||||
|
main > section#book > nav > ul > li > a > i:hover {
|
||||||
color: #bd4f1c;
|
color: #bd4f1c;
|
||||||
}
|
}
|
||||||
|
|
||||||
main > section#book > nav > ul > li.icon > i:active {
|
main > section#book > nav > ul > li.icon > i:active {
|
||||||
color: #813410;
|
color: #813410;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main > section#book > nav > ul > li.middle {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
main > section#book > nav > ul > li.previous {
|
||||||
|
grid-column: 1;
|
||||||
|
}
|
||||||
|
main > section#book > nav > ul > li.next {
|
||||||
|
N FgHJ.,./
|
||||||
44
kodorvan/surikov/system/public/css/icons/arrow.css
Normal file
44
kodorvan/surikov/system/public/css/icons/arrow.css
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
i.icon.arrow:not(.circle, .square) {
|
||||||
|
position: relative;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transform: rotate(var(--rotate));
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icon.arrow.short:not(.circle, .square) {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icon.arrow:not(.circle, .square)::after,
|
||||||
|
i.icon.arrow:not(.circle, .square)::before {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: absolute;
|
||||||
|
right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icon.arrow:not(.circle, .square)::after {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-top: 2px solid;
|
||||||
|
border-right: 2px solid;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
bottom: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icon.arrow.small:not(.circle, .square)::after {
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.icon.arrow:not(.circle, .square, .short)::before {
|
||||||
|
width: 16px;
|
||||||
|
height: 2px;
|
||||||
|
bottom: 10px;
|
||||||
|
background-color: currentColor;
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:wght@200;400;500;600;700&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:wght@200;400;500;600;700&display=swap');
|
||||||
|
--rotate: 180deg;
|
||||||
* {
|
* {
|
||||||
font-family: 'IBM Plex Serif', serif;
|
font-family: 'IBM Plex Serif', serif;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: .2s ease-out;
|
transition: .2s ease-out;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
@@ -22,7 +24,7 @@ body {
|
|||||||
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);
|
grid-template-columns: minmax(100px, auto) 300px minmax(270px, 600px) minmax(100px, auto);
|
||||||
background-color: #e5ddd1;
|
background-color: #e5ddd1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
147
kodorvan/surikov/system/public/css/publications.css
Normal file
147
kodorvan/surikov/system/public/css/publications.css
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
.content-main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-new {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: left;
|
||||||
|
padding: 1rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
background-color: #d9b5b5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-new > input {
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-new > textarea {
|
||||||
|
min-height: 2rem;
|
||||||
|
max-height: 5rem;
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
|
resize: vertical;
|
||||||
|
padding: 1rem 0.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
outline: none;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 300;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-new > textarea:focus {
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-file-upload {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-file-upload > .file-input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-file-upload > .custom-file-button {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-btn > button {
|
||||||
|
padding: 0.4rem 0.6rem;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.8em;
|
||||||
|
font-weight: 300;
|
||||||
|
border: unset;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #fdfdfd;
|
||||||
|
background-color: #ad4717;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-btn > button:hover {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #c5531f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-news {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-news > .block-new {
|
||||||
|
display: flex;
|
||||||
|
gap: 1.5rem;
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-news > .block-new > .new-inside {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-news > .block-new > .new-inside > img {
|
||||||
|
width: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
max-height: 35rem;
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-news > .block-new > .new-inside > .new-title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-news > .block-new > .new-inside > .new-title > .right-block {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.content-news > .block-new > .new-inside > .new-title > h1 {
|
||||||
|
font-family: "Pochaevsk", system-ui;
|
||||||
|
font-size: 3em;
|
||||||
|
margin: unset;
|
||||||
|
line-height: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-btns {
|
||||||
|
display: inline-flex;
|
||||||
|
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-btns > button {
|
||||||
|
background: unset;
|
||||||
|
border: unset;
|
||||||
|
margin: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-btns > #edit:hover {
|
||||||
|
color: #61b128;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-btns > #trash:hover {
|
||||||
|
color: #ad4717;
|
||||||
|
}
|
||||||
288
kodorvan/surikov/system/public/css/test/test-main.css
Normal file
288
kodorvan/surikov/system/public/css/test/test-main.css
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
@import url("https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Geologica:wght@100..900&family=Lora:ital,wght@0,400..700;1,400..700&family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Pochaevsk&display=swap");
|
||||||
|
@import url("https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Geologica:wght@100..900&family=Lora:ital,wght@0,400..700;1,400..700&family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap");
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: "Geologica", sans-serif;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
*[type="button"] {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection,
|
||||||
|
::-moz-selection {
|
||||||
|
background-color: #544f7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) 270px minmax(270px, 600px) minmax(
|
||||||
|
100px,
|
||||||
|
auto
|
||||||
|
);
|
||||||
|
background-color: #e5ddd1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
padding: 0px 20vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
margin-right: 20px;
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside > section {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside > section > h3 {
|
||||||
|
margin-top: -0.2rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(main, aside) {
|
||||||
|
margin-top: 30px;
|
||||||
|
display: inline-block;
|
||||||
|
grid-row: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(main, aside) > section {
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #d9b5b5;
|
||||||
|
}
|
||||||
|
|
||||||
|
:is(main, aside) > section {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
grid-column: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
main > section > h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* main>section>h2:has(+ .divider) { */
|
||||||
|
main > section > h2 + .divider {
|
||||||
|
margin-top: -1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
z-index: 1000;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
grid-row: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .menu {
|
||||||
|
z-index: 1000;
|
||||||
|
width: 100%;
|
||||||
|
height: 250px;
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .menu > nav {
|
||||||
|
top: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
height: 40px;
|
||||||
|
padding: 15px 0;
|
||||||
|
position: sticky;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .menu > nav > #logo {
|
||||||
|
height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .menu > nav > #logo > img {
|
||||||
|
height: inherit;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .menu > nav > #logo ~ .link {
|
||||||
|
margin-right: unset;
|
||||||
|
margin-left: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .menu > nav > .link {
|
||||||
|
margin: auto 0;
|
||||||
|
margin-right: 50px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #e5ddd1;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .menu > nav > .link:last-child {
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .window {
|
||||||
|
z-index: 500;
|
||||||
|
height: 650px;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
padding: 30px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #1a1449;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .window > .background {
|
||||||
|
margin-top: auto;
|
||||||
|
width: 100%;
|
||||||
|
height: min-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > .window > .img_1 {
|
||||||
|
left: -70px;
|
||||||
|
bottom: -20px;
|
||||||
|
height: 120%;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
header,
|
||||||
|
footer {
|
||||||
|
grid-column-start: 1;
|
||||||
|
grid-column-end: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > nav,
|
||||||
|
footer {
|
||||||
|
background-color: #1a1449;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
z-index: 800;
|
||||||
|
margin-top: 30px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
grid-row: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banners {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banners > img {
|
||||||
|
width: 100%;
|
||||||
|
position: sticky;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button,
|
||||||
|
:is(li, a, label)[type="button"],
|
||||||
|
input[type="submit"] {
|
||||||
|
padding: 10px 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
border: unset;
|
||||||
|
border-radius: 3px;
|
||||||
|
color: #fdfdfd;
|
||||||
|
background-color: #ad4717;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover,
|
||||||
|
:is(li, a, label)[type="button"]:hover,
|
||||||
|
input[type="submit"]:hover {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #c5531f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:active:is(:active, :focus),
|
||||||
|
:is(li, a, label)[type="button"]:is(:active, :focus),
|
||||||
|
input[type="radio"]:checked + label[type="button"],
|
||||||
|
input[type="submit"]:is(:active, :focus) {
|
||||||
|
color: #ddd;
|
||||||
|
background-color: #993f15;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:is([type="checkbox"], [type="radio"]) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
select,
|
||||||
|
input:is([type="text"], [type="password"]),
|
||||||
|
input:is([type="text"], [type="password"]).measured + .unit {
|
||||||
|
padding: 8px 12px;
|
||||||
|
outline: unset;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding-top: unset;
|
||||||
|
padding-bottom: unset;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
select.measured,
|
||||||
|
input:is([type="text"], [type="password"]).measured {
|
||||||
|
margin-right: unset;
|
||||||
|
padding-right: 3px;
|
||||||
|
text-align: right;
|
||||||
|
border-radius: 3px 0 0 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select.measured + .unit,
|
||||||
|
input:is([type="text"], [type="password"]).measured + .unit {
|
||||||
|
margin-right: 3px;
|
||||||
|
padding-left: unset;
|
||||||
|
display: inline;
|
||||||
|
border-radius: 0 3px 3px 0;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unit {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unselectable,
|
||||||
|
.unselectable * {
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unselectable::selection,
|
||||||
|
.unselectable *::-moz-selection {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider + h3 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
section > div.divider {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border-bottom: 3px solid #aaa9a9;
|
||||||
|
}
|
||||||
BIN
kodorvan/surikov/system/public/img/asd.jpg
Normal file
BIN
kodorvan/surikov/system/public/img/asd.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
kodorvan/surikov/system/public/img/icons/close.png
Normal file
BIN
kodorvan/surikov/system/public/img/icons/close.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
4
kodorvan/surikov/system/public/img/icons/edit.svg
Normal file
4
kodorvan/surikov/system/public/img/icons/edit.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="45" height="45" viewBox="0 0 45 45" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M20.625 7.5H7.5C6.50544 7.5 5.55161 7.89509 4.84835 8.59835C4.14509 9.30161 3.75 10.2554 3.75 11.25V37.5C3.75 38.4946 4.14509 39.4484 4.84835 40.1516C5.55161 40.8549 6.50544 41.25 7.5 41.25H33.75C34.7446 41.25 35.6984 40.8549 36.4016 40.1516C37.1049 39.4484 37.5 38.4946 37.5 37.5V24.375" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M34.6875 4.6875C35.4334 3.94158 36.4451 3.52252 37.5 3.52252C38.5549 3.52252 39.5666 3.94158 40.3125 4.6875C41.0584 5.43342 41.4775 6.44511 41.4775 7.5C41.4775 8.55489 41.0584 9.56658 40.3125 10.3125L22.5 28.125L15 30L16.875 22.5L34.6875 4.6875Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 819 B |
BIN
kodorvan/surikov/system/public/img/icons/plus.png
Normal file
BIN
kodorvan/surikov/system/public/img/icons/plus.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 159 B |
6
kodorvan/surikov/system/public/img/icons/trash.svg
Normal file
6
kodorvan/surikov/system/public/img/icons/trash.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<svg width="45" height="45" viewBox="0 0 45 45" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5.625 11.25H9.375H39.375" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M35.625 11.25V37.5C35.625 38.4946 35.2299 39.4484 34.5266 40.1516C33.8234 40.8549 32.8696 41.25 31.875 41.25H13.125C12.1304 41.25 11.1766 40.8549 10.4733 40.1516C9.77009 39.4484 9.375 38.4946 9.375 37.5V11.25M15 11.25V7.5C15 6.50544 15.3951 5.55161 16.0984 4.84835C16.8016 4.14509 17.7554 3.75 18.75 3.75H26.25C27.2446 3.75 28.1984 4.14509 28.9016 4.84835C29.6049 5.55161 30 6.50544 30 7.5V11.25" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M18.75 20.625V31.875" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M26.25 20.625V31.875" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 931 B |
@@ -8,6 +8,8 @@ namespace kodorvan\surikov;
|
|||||||
use mirzaev\minimal\core,
|
use mirzaev\minimal\core,
|
||||||
mirzaev\minimal\route;
|
mirzaev\minimal\route;
|
||||||
|
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
// Initializing path to the public directory
|
// Initializing path to the public directory
|
||||||
define('INDEX', __DIR__);
|
define('INDEX', __DIR__);
|
||||||
|
|
||||||
@@ -26,33 +28,41 @@ define('SETTINGS', INDEX . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 's
|
|||||||
// Initializing the database connection parameters
|
// Initializing the database connection parameters
|
||||||
define('DATABASE', require(SETTINGS . DIRECTORY_SEPARATOR . 'database.php'));
|
define('DATABASE', require(SETTINGS . DIRECTORY_SEPARATOR . 'database.php'));
|
||||||
|
|
||||||
ini_set('error_reporting', E_ALL);
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
ini_set('display_startup_errors', 1);
|
|
||||||
|
|
||||||
// Initializing dependencies
|
// Initializing dependencies
|
||||||
require ROOT . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
|
require ROOT . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
|
||||||
|
|
||||||
// Initializing the core
|
// Initializing the core
|
||||||
$core = new core(namespace: __NAMESPACE__);
|
$core = new core(
|
||||||
|
namespace: __NAMESPACE__
|
||||||
|
);
|
||||||
|
|
||||||
// Initializing routes
|
// Initializing routes
|
||||||
$core->router
|
$core->router
|
||||||
->write('/', new route('index', 'index'), 'GET')
|
// ->write('/', new route('index', 'index'), 'GET')
|
||||||
|
|
||||||
|
->write('/', new route('publications', 'index'), 'GET')
|
||||||
|
|
||||||
|
->write('/publications/delete/$identifier', new route('publications', 'delete'), 'POST')
|
||||||
|
->write('/publications/write', new route('publications', 'write'), 'POST')
|
||||||
|
->write('/publications/update/$identifier', new route('publications', 'update'), 'POST')
|
||||||
|
->write('/storage/publications/$identifier', new route('publications', 'read'), 'GET')
|
||||||
|
|
||||||
->write('/account/registration', new route('accounts', 'registration'), 'POST')
|
->write('/account/registration', new route('accounts', 'registration'), 'POST')
|
||||||
->write('/account/authentication', new route('accounts', 'authentication'), 'POST')
|
->write('/account/authentication', new route('accounts', 'authentication'), 'POST')
|
||||||
->write('/account/deauthentication', new route('accounts', 'deauthentication'), 'POST')
|
->write('/account/deauthentication', new route('accounts', 'deauthentication'), 'POST')
|
||||||
->write('/account/deauthentication', new route('accounts', 'deauthentication'), 'GET')
|
->write('/account/deauthentication', new route('accounts', 'deauthentication'), 'GET')
|
||||||
|
|
||||||
->write('/books', new route('books', 'index'), 'GET')
|
->write('/books', new route('books', 'index'), 'GET')
|
||||||
->write('/books/$id', new route('books', 'index'), 'GET')
|
->write('/books/$identifier', new route('books', 'index'), 'GET')
|
||||||
->write('/books/$id/$page', new route('books', 'index'), 'GET')
|
->write('/books/$identifier/$page', new route('books', 'index'), 'GET')
|
||||||
->write('/books/$id/$page/rotate', new route('books', 'rotate'), 'POST')
|
->write('/books/$identifier/$page/rotate', new route('books', 'rotate'), 'POST')
|
||||||
->write('/books/$id/delete', new route('books', 'delete'), 'POST')
|
->write('/books/$identifier/delete', new route('books', 'delete'), 'POST')
|
||||||
->write('/storage/books/$id/$file', new route('books', 'read'), 'GET')
|
->write('/storage/books/$identifier/$page', new route('books', 'read'), 'GET')
|
||||||
->write('/storage/books/write', new route('books', 'write'), 'POST')
|
->write('/storage/books/write', new route('books', 'write'), 'POST')
|
||||||
|
|
||||||
->write('/kemenov', new route('kemenov', 'index'), 'GET')
|
->write('/kemenov', new route('kemenov', 'index'), 'GET')
|
||||||
->write('/surikov', new route('surikov', 'index'), 'GET')
|
->write('/surikov', new route('surikov', 'index'), 'GET')
|
||||||
->write('/contacts', new route('contacts', 'index'), 'GET');
|
->write('/contacts', new route('contacts', 'index'), 'GET');
|
||||||
|
;
|
||||||
// Handling the request
|
// Handling the request
|
||||||
$core->start();
|
$core->start();
|
||||||
|
|||||||
@@ -1,37 +1,64 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switches the lock state (open/closed) and updates the corresponding input field
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} target - the HTML element that was clicked (the lock icon)
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
function remember_switch(target) {
|
function remember_switch(target) {
|
||||||
if (target.classList.contains('fa-unlock')) {
|
|
||||||
// Найден "открытый замок"
|
|
||||||
|
|
||||||
// Перезапись на "закрытый замок"
|
if (target.classList.contains('fa-unlock')) {
|
||||||
|
// An "open lock" has been found
|
||||||
|
|
||||||
|
// Rewriting to "closed lock"
|
||||||
target.classList.remove('fa-unlock');
|
target.classList.remove('fa-unlock');
|
||||||
target.classList.add('fa-lock');
|
target.classList.add('fa-lock');
|
||||||
|
|
||||||
// Изменение отправляемого значения
|
// Changing the value being sent
|
||||||
document.querySelector('input[name=' + target.getAttribute('for') + ']').checked = true;
|
document.querySelector('input[name=' + target.getAttribute('for') + ']').checked = true;
|
||||||
} else {
|
} else {
|
||||||
// Не найден "открытый замок", подразумевается, что найден "закрытый замок"
|
// No "open lock" found, which means a "closed lock" was found
|
||||||
|
|
||||||
// Перезапись на "открытый замок"
|
// Rewriting to "open lock"
|
||||||
target.classList.remove('fa-lock');
|
target.classList.remove('fa-lock');
|
||||||
target.classList.add('fa-unlock');
|
target.classList.add('fa-unlock');
|
||||||
|
|
||||||
// Изменение отправляемого значения
|
// Changing the value being sent
|
||||||
document.querySelector('input[name=' + target.getAttribute('for') + ']').checked = false;
|
document.querySelector('input[name=' + target.getAttribute('for') + ']').checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the authentication form by setting the URL for submission
|
||||||
|
*
|
||||||
|
* @param {HTMLFormElement} form - The HTML form to be processed
|
||||||
|
*
|
||||||
|
* @returns {boolean} Always returns true (successful processing)
|
||||||
|
*/
|
||||||
function authentication(form) {
|
function authentication(form) {
|
||||||
// Инициализация адреса отправки формы
|
|
||||||
|
// Initializing the form submission address
|
||||||
form.action = '/account/authentication';
|
form.action = '/account/authentication';
|
||||||
|
|
||||||
|
//Exit (succes)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the registration form by setting the submission URL
|
||||||
|
*
|
||||||
|
* @param {HTMLFormElement} form - The HTML form to be processed
|
||||||
|
*
|
||||||
|
* @returns {boolean} Always returns true (successful processing)
|
||||||
|
*/
|
||||||
function registration(form) {
|
function registration(form) {
|
||||||
// Инициализация адреса отправки формы
|
|
||||||
|
// Initializing the form submission address
|
||||||
form.action = '/account/registration';
|
form.action = '/account/registration';
|
||||||
|
|
||||||
|
//Exit (succes)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
30
kodorvan/surikov/system/public/js/book/delete.js
Normal file
30
kodorvan/surikov/system/public/js/book/delete.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a book by ID and the corresponding element from the DOM
|
||||||
|
*
|
||||||
|
* @param {number} id - The ID of the book to delete
|
||||||
|
*/
|
||||||
|
function trash(id, element) {
|
||||||
|
// Sending a POST request to the server
|
||||||
|
fetch(`books/${id}/delete`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
},
|
||||||
|
body: 'identifier=' + id
|
||||||
|
})
|
||||||
|
|
||||||
|
// Checking the success of the request
|
||||||
|
.then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
|
||||||
|
// Removing an element from the DOM
|
||||||
|
element.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Ошибка:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
27
kodorvan/surikov/system/public/js/book/rotate.js
Normal file
27
kodorvan/surikov/system/public/js/book/rotate.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates the page of a book and reloads the page if necessary
|
||||||
|
*
|
||||||
|
* @param {number} identifier - Book ID
|
||||||
|
* @param {number} page - Page number to rotate
|
||||||
|
* @param {boolean} [reload=false] - Whether to reload the page after rotation
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function rotate(id, page, reload = false) {
|
||||||
|
if (typeof id === 'number' && typeof page === 'number') {
|
||||||
|
// Получены входные параметры
|
||||||
|
|
||||||
|
// Запрос
|
||||||
|
fetch(`/books/${id}/${page}/rotate`, {
|
||||||
|
method: 'POST'
|
||||||
|
}).then((response) => response.text()
|
||||||
|
).then(
|
||||||
|
(response) => {
|
||||||
|
location.reload();
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
kodorvan/surikov/system/public/js/book/turning.js
Normal file
4
kodorvan/surikov/system/public/js/book/turning.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
function turning() {
|
||||||
|
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.width = '100%') : image.style.margin = null
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
'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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
78
kodorvan/surikov/system/public/js/publication/create.js
Normal file
78
kodorvan/surikov/system/public/js/publication/create.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
//Hash of the last post
|
||||||
|
let lastPublications = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the post form data to the server and adds a new post to the page
|
||||||
|
*/
|
||||||
|
function create() {
|
||||||
|
//FormData object for sending form data
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
//Form elements
|
||||||
|
const fileInput = document.querySelector('#file-input');
|
||||||
|
const titleInput = document.getElementById('title');
|
||||||
|
const contentInput = document.getElementById('content');
|
||||||
|
|
||||||
|
// Get values and trim spaces
|
||||||
|
const title = titleInput.value.trim();
|
||||||
|
const content = contentInput.value.trim();
|
||||||
|
|
||||||
|
// Checking for empty fields
|
||||||
|
if (!title) {
|
||||||
|
alert('Заголовок не может быть пустыми!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let hash = title + content;
|
||||||
|
|
||||||
|
// Checking the hash of the previous publication
|
||||||
|
if (hash === lastPublications) {
|
||||||
|
|
||||||
|
//Form data reset
|
||||||
|
titleInput.value = '';
|
||||||
|
contentInput.value = '';
|
||||||
|
fileInput.value = '';
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Getting data from FormData
|
||||||
|
formData.append('title', titleInput.value);
|
||||||
|
formData.append('content', contentInput.value);
|
||||||
|
|
||||||
|
//Adding files
|
||||||
|
if (fileInput.files.length != 0) {
|
||||||
|
for (let i = 0; i < fileInput.files.length; i++) {
|
||||||
|
formData.append('publications[]', fileInput.files[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('/publications/write', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((text) => {
|
||||||
|
|
||||||
|
//Saving the hash (success)
|
||||||
|
lastPublications = hash;
|
||||||
|
hash = '';
|
||||||
|
|
||||||
|
//Clearing form fields (success)
|
||||||
|
titleInput.value = '';
|
||||||
|
contentInput.value = '';
|
||||||
|
fileInput.value = '';
|
||||||
|
|
||||||
|
//Creating an html publication
|
||||||
|
const publication = document.createElement('div');
|
||||||
|
const publications = document.getElementById('publications');
|
||||||
|
publications.insertBefore(publication, publications.firstElementChild);
|
||||||
|
publication.outerHTML = text;
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
28
kodorvan/surikov/system/public/js/publication/trash.js
Normal file
28
kodorvan/surikov/system/public/js/publication/trash.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the content of a publication by ID
|
||||||
|
*
|
||||||
|
* @param {int} publicationId - Publication ID to update
|
||||||
|
*/
|
||||||
|
function trash(id, element) {
|
||||||
|
|
||||||
|
// Sending a POST request to the server
|
||||||
|
fetch('/publications/delete/' + id, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
},
|
||||||
|
body: 'identifier=' + id
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
// Removing an element from the DOM
|
||||||
|
element.remove();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Ошибка:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
100
kodorvan/surikov/system/public/js/publication/update.js
Normal file
100
kodorvan/surikov/system/public/js/publication/update.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the content of a publication by ID
|
||||||
|
*
|
||||||
|
* @param {int} publicationId - Publication ID to update
|
||||||
|
*/
|
||||||
|
function update(publicationId) {
|
||||||
|
|
||||||
|
// Getting the DOM elements of the post's title and content, image
|
||||||
|
const publicationTitle = document.getElementById('publication-title-' + publicationId)
|
||||||
|
const publicationContent = document.getElementById('publication-content-' + publicationId)
|
||||||
|
const publicationImage = document.getElementById('img-' + publicationId)
|
||||||
|
|
||||||
|
// Requesting a new title from the user
|
||||||
|
let title = prompt('Введите название для публикации', publicationTitle.textContent.trim())
|
||||||
|
|
||||||
|
//Checking that the title is not empty
|
||||||
|
if (!title.trim()) {
|
||||||
|
alert('Заголовок не может быть пустыми!');
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Requesting a new content from the user
|
||||||
|
let content = prompt('Введите содержание для публикации', publicationContent.textContent.trim())
|
||||||
|
let image = confirm('Изменить изображение?');
|
||||||
|
|
||||||
|
if (image) {
|
||||||
|
//Creating an input to select a file
|
||||||
|
const input = document.createElement('input');
|
||||||
|
|
||||||
|
//Configuring input
|
||||||
|
input.type = 'file'
|
||||||
|
input.id = 'image'
|
||||||
|
input.accept = '.jpg,.jpeg,.png,.gif'
|
||||||
|
input.name = 'publications[]'
|
||||||
|
input.style.display = 'none'
|
||||||
|
document.body.appendChild(input);
|
||||||
|
|
||||||
|
input.addEventListener('change', function () {
|
||||||
|
//If the image is uploaded
|
||||||
|
send(publicationId, title, content, input.files, publicationTitle, publicationContent, publicationImage)
|
||||||
|
document.body.removeChild(input);
|
||||||
|
|
||||||
|
})
|
||||||
|
//Click simulation
|
||||||
|
input.click();
|
||||||
|
} else {
|
||||||
|
//If the image is not uploaded
|
||||||
|
send(publicationId, title, content, null, publicationTitle, publicationContent, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the updated publication data to the server
|
||||||
|
*
|
||||||
|
* @param {int} publicationId - Publication ID
|
||||||
|
* @param {string} title - Title
|
||||||
|
* @param {string} content - Content
|
||||||
|
* @param {FileList|null} files - List of files to upload
|
||||||
|
* @param {HTMLElement} publicationTitle - DOM element of the title
|
||||||
|
* @param {HTMLElement} publicationContent - DOM element of the content
|
||||||
|
* @param {HTMLElement|null} publicationImage - DOM-element of the image
|
||||||
|
*/
|
||||||
|
function send(publicationId, title, content, files, publicationTitle, publicationContent, publicationImage) {
|
||||||
|
|
||||||
|
//The FormData object for sending form data
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
//Adding the publication data to FormData
|
||||||
|
formData.append('identifier', publicationId);
|
||||||
|
formData.append('title', title);
|
||||||
|
formData.append('content', content);
|
||||||
|
|
||||||
|
// If there are files to upload, add them to FormData
|
||||||
|
if (files != null) {
|
||||||
|
for (let file of files) {
|
||||||
|
formData.append('publications[]', file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('/publications/update/' + publicationId,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((text) => {
|
||||||
|
|
||||||
|
// Updating publication data in DOM
|
||||||
|
publicationTitle.textContent = title;
|
||||||
|
publicationContent.textContent = content;
|
||||||
|
publicationImage.src = "storage/publication/" + publicationId;
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
'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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2
kodorvan/surikov/system/settings/.gitignore
vendored
2
kodorvan/surikov/system/settings/.gitignore
vendored
@@ -1 +1 @@
|
|||||||
*.sample.php
|
*.php
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
return [
|
return [
|
||||||
'type' => 'mysql',
|
'type' => 'mysql',
|
||||||
'host' => '127.0.0.1',
|
'host' => '127.0.0.1',
|
||||||
'name' => 'casino_2',
|
'name' => 'youtube_parser',
|
||||||
'login' => 'brawl_stars',
|
'login' => 'roma',
|
||||||
'password' => 'knopka_bablo_228'
|
'password' => 'America_pizda128'
|
||||||
];
|
];
|
||||||
|
|||||||
4
kodorvan/surikov/system/storage/.gitignore
vendored
4
kodorvan/surikov/system/storage/.gitignore
vendored
@@ -1,4 +1,8 @@
|
|||||||
/books/*
|
/books/*
|
||||||
/temp/*
|
/temp/*
|
||||||
|
/images/*
|
||||||
|
/publications/*
|
||||||
!/books/.gitkeep
|
!/books/.gitkeep
|
||||||
!/temp/.gitkeep
|
!/temp/.gitkeep
|
||||||
|
!/images/.gitkeep
|
||||||
|
!/publications/.gitkeep
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ final class templater extends controller implements array_access
|
|||||||
$this->twig = new twig(new FilesystemLoader(VIEWS));
|
$this->twig = new twig(new FilesystemLoader(VIEWS));
|
||||||
|
|
||||||
// Initializing global variables
|
// Initializing global variables
|
||||||
$this->twig->addGlobal('theme', 'default');
|
$this->twig->addGlobal('theme', 'test');
|
||||||
$this->twig->addGlobal('server', $_SERVER);
|
$this->twig->addGlobal('server', $_SERVER);
|
||||||
$this->twig->addGlobal('cookies', $_COOKIE);
|
$this->twig->addGlobal('cookies', $_COOKIE);
|
||||||
if ($account instanceof account) $this->twig->addGlobal('account', $account);
|
if ($account instanceof account) $this->twig->addGlobal('account', $account);
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
<head>
|
<head>
|
||||||
{% include '/themes/default/head.html' %}
|
{% include '/themes/default/head.html' %}
|
||||||
|
|
||||||
<link href="/css/main.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<title>
|
<title>
|
||||||
{% block title %}
|
{% block title %}
|
||||||
Библиотека Сурикова
|
Библиотека Сурикова
|
||||||
@@ -19,9 +17,10 @@
|
|||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
{% include '/themes/default/sidebar.html' %}
|
{% include '/themes/default/sidebar.html' %}
|
||||||
</aside><!----><main>
|
</aside><!---->
|
||||||
|
<main>
|
||||||
{% block main %}
|
{% block main %}
|
||||||
{% include '/themes/default/calculators/index.html' %}
|
<!-- {% include '/themes/default/calculators/index.html' %} -->
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,8 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
|
||||||
|
<link href="/css/main.css" riel="stylesheet">
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Geologica:wght@100..900&display=swap" rel="stylesheet">
|
||||||
|
|||||||
@@ -6,28 +6,33 @@
|
|||||||
<section id="page">
|
<section id="page">
|
||||||
<article>
|
<article>
|
||||||
<h2>Суриков</h2>
|
<h2>Суриков</h2>
|
||||||
<p>Библиотека научно-вспомогательного фонда <b>Музея-усадьбы В.И. Сурикова</b> начала формироваться с 1948 года, когда
|
<p>Библиотека научно-вспомогательного фонда <b>Музея-усадьбы В.И. Сурикова</b> начала формироваться с 1948 года,
|
||||||
|
когда
|
||||||
первые сотрудники самостоятельно стали собирать её, приобретая за свои средства необходимую для работы
|
первые сотрудники самостоятельно стали собирать её, приобретая за свои средства необходимую для работы
|
||||||
литературу, прежде всего по осмыслению жизни и творчества <b>В.И. Сурикова</b>, а также специальную
|
литературу, прежде всего по осмыслению жизни и творчества <b>В.И. Сурикова</b>, а также специальную
|
||||||
профессиональную литературу по экспонированию и иной деятельности в музее. В это время было начато системное
|
профессиональную литературу по экспонированию и иной деятельности в музее. В это время было начато системное
|
||||||
взаимодействие с <b>Центральной библиотечной системой им. Горького</b>, поэтому многие издания, поступавшие из
|
взаимодействие с <b>Центральной библиотечной системой им. Горького</b>, поэтому многие издания, поступавшие
|
||||||
|
из
|
||||||
библиотеки в музей, имеют её опознавательный знак.
|
библиотеки в музей, имеют её опознавательный знак.
|
||||||
Позже, уже с приходом Л. П. Греченко, директора музея-усадьбы с 1970 по 2008 гг., было принято решение
|
Позже, уже с приходом Л. П. Греченко, директора музея-усадьбы с 1970 по 2008 гг., было принято решение
|
||||||
ежемесячно закупать книги из бибколлектора (ныне «Центр книги – Красноярский бибколлектор»). </p>
|
ежемесячно закупать книги из бибколлектора (ныне «Центр книги – Красноярский бибколлектор»). </p>
|
||||||
<p>Но в 1990-е годы в период экономического спада и дефицита закупка прекратилась, с этого времени библиотека
|
<p>Но в 1990-е годы в период экономического спада и дефицита закупка прекратилась, с этого времени библиотека
|
||||||
продолжила формироваться за счёт <b>личного вклада</b> сотрудников музея. Особое значение библиотеке уделяла <b>Нина
|
продолжила формироваться за счёт <b>личного вклада</b> сотрудников музея. Особое значение библиотеке уделяла
|
||||||
|
<b>Нина
|
||||||
Ярославовна Скалиш</b>, главный хранитель музея на протяжении 45 лет.
|
Ярославовна Скалиш</b>, главный хранитель музея на протяжении 45 лет.
|
||||||
Основой библиотеки является научная литература, монографии о жизни и творчестве В. И. Сурикова, изданные с
|
Основой библиотеки является научная литература, монографии о жизни и творчестве В. И. Сурикова, изданные с
|
||||||
1914 по 2018 гг. (кроме того, статьи, каталоги и художественная литература). Библиотека музея включает
|
1914 по 2018 гг. (кроме того, статьи, каталоги и художественная литература). Библиотека музея включает
|
||||||
архивный фонд В. С. Кеменова: рукописи, документы и фотографии, собранные известным суриковедом. Его
|
архивный фонд В. С. Кеменова: рукописи, документы и фотографии, собранные известным суриковедом. Его
|
||||||
исследования, не вошедшие в первый том «Историческая живопись В.И. Сурикова», являются фундаментальными и
|
исследования, не вошедшие в первый том «Историческая живопись В.И. Сурикова», являются фундаментальными и
|
||||||
охватывают период с 1890 по 1916 годы жизни В. И. Сурикова. </p>
|
охватывают период с 1890 по 1916 годы жизни В. И. Сурикова. </p>
|
||||||
<p>Стоит отметить тот факт, что музейная библиотека является кладезью <b>настоящих библиографических редкостей</b>, к
|
<p>Стоит отметить тот факт, что музейная библиотека является кладезью <b>настоящих библиографических
|
||||||
|
редкостей</b>, к
|
||||||
которым можно отнести дореволюционные издания о великом русском художнике, книги с дарственной надписью его
|
которым можно отнести дореволюционные издания о великом русском художнике, книги с дарственной надписью его
|
||||||
потомков; а также книги и периодику из личного собрания В. М. Крутовского с его подписью; и многочисленные
|
потомков; а также книги и периодику из личного собрания В. М. Крутовского с его подписью; и многочисленные
|
||||||
дореволюционные нотные издания, оставшиеся в доме художника от семьи музыкантов, квартирантов Красиковых.
|
дореволюционные нотные издания, оставшиеся в доме художника от семьи музыкантов, квартирантов Красиковых.
|
||||||
Таким образом, <b>общее количество всех изданий по В.И. Сурикову, собранных в библиотеке музея, составляет
|
Таким образом, <b>общее количество всех изданий по В.И. Сурикову, собранных в библиотеке музея, составляет
|
||||||
более 100</b>. Сейчас музейная библиография публикуется впервые, ведь следуя миссии музея – мы делаем открытым
|
более 100</b>. Сейчас музейная библиография публикуется впервые, ведь следуя миссии музея – мы делаем
|
||||||
|
открытым
|
||||||
доступ к тем книжным ценностям, которые помогут будущим исследователям в изучении творческого наследия В. И.
|
доступ к тем книжным ценностям, которые помогут будущим исследователям в изучении творческого наследия В. И.
|
||||||
Сурикова.</p>
|
Сурикова.</p>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -6,28 +6,33 @@
|
|||||||
<section id="page">
|
<section id="page">
|
||||||
<article>
|
<article>
|
||||||
<h2>Суриков</h2>
|
<h2>Суриков</h2>
|
||||||
<p>Библиотека научно-вспомогательного фонда <b>Музея-усадьбы В.И. Сурикова</b> начала формироваться с 1948 года, когда
|
<p>Библиотека научно-вспомогательного фонда <b>Музея-усадьбы В.И. Сурикова</b> начала формироваться с 1948 года,
|
||||||
|
когда
|
||||||
первые сотрудники самостоятельно стали собирать её, приобретая за свои средства необходимую для работы
|
первые сотрудники самостоятельно стали собирать её, приобретая за свои средства необходимую для работы
|
||||||
литературу, прежде всего по осмыслению жизни и творчества <b>В.И. Сурикова</b>, а также специальную
|
литературу, прежде всего по осмыслению жизни и творчества <b>В.И. Сурикова</b>, а также специальную
|
||||||
профессиональную литературу по экспонированию и иной деятельности в музее. В это время было начато системное
|
профессиональную литературу по экспонированию и иной деятельности в музее. В это время было начато системное
|
||||||
взаимодействие с <b>Центральной библиотечной системой им. Горького</b>, поэтому многие издания, поступавшие из
|
взаимодействие с <b>Центральной библиотечной системой им. Горького</b>, поэтому многие издания, поступавшие
|
||||||
|
из
|
||||||
библиотеки в музей, имеют её опознавательный знак.
|
библиотеки в музей, имеют её опознавательный знак.
|
||||||
Позже, уже с приходом Л. П. Греченко, директора музея-усадьбы с 1970 по 2008 гг., было принято решение
|
Позже, уже с приходом Л. П. Греченко, директора музея-усадьбы с 1970 по 2008 гг., было принято решение
|
||||||
ежемесячно закупать книги из бибколлектора (ныне «Центр книги – Красноярский бибколлектор»). </p>
|
ежемесячно закупать книги из бибколлектора (ныне «Центр книги – Красноярский бибколлектор»). </p>
|
||||||
<p>Но в 1990-е годы в период экономического спада и дефицита закупка прекратилась, с этого времени библиотека
|
<p>Но в 1990-е годы в период экономического спада и дефицита закупка прекратилась, с этого времени библиотека
|
||||||
продолжила формироваться за счёт <b>личного вклада</b> сотрудников музея. Особое значение библиотеке уделяла <b>Нина
|
продолжила формироваться за счёт <b>личного вклада</b> сотрудников музея. Особое значение библиотеке уделяла
|
||||||
|
<b>Нина
|
||||||
Ярославовна Скалиш</b>, главный хранитель музея на протяжении 45 лет.
|
Ярославовна Скалиш</b>, главный хранитель музея на протяжении 45 лет.
|
||||||
Основой библиотеки является научная литература, монографии о жизни и творчестве В. И. Сурикова, изданные с
|
Основой библиотеки является научная литература, монографии о жизни и творчестве В. И. Сурикова, изданные с
|
||||||
1914 по 2018 гг. (кроме того, статьи, каталоги и художественная литература). Библиотека музея включает
|
1914 по 2018 гг. (кроме того, статьи, каталоги и художественная литература). Библиотека музея включает
|
||||||
архивный фонд В. С. Кеменова: рукописи, документы и фотографии, собранные известным суриковедом. Его
|
архивный фонд В. С. Кеменова: рукописи, документы и фотографии, собранные известным суриковедом. Его
|
||||||
исследования, не вошедшие в первый том «Историческая живопись В.И. Сурикова», являются фундаментальными и
|
исследования, не вошедшие в первый том «Историческая живопись В.И. Сурикова», являются фундаментальными и
|
||||||
охватывают период с 1890 по 1916 годы жизни В. И. Сурикова. </p>
|
охватывают период с 1890 по 1916 годы жизни В. И. Сурикова. </p>
|
||||||
<p>Стоит отметить тот факт, что музейная библиотека является кладезью <b>настоящих библиографических редкостей</b>, к
|
<p>Стоит отметить тот факт, что музейная библиотека является кладезью <b>настоящих библиографических
|
||||||
|
редкостей</b>, к
|
||||||
которым можно отнести дореволюционные издания о великом русском художнике, книги с дарственной надписью его
|
которым можно отнести дореволюционные издания о великом русском художнике, книги с дарственной надписью его
|
||||||
потомков; а также книги и периодику из личного собрания В. М. Крутовского с его подписью; и многочисленные
|
потомков; а также книги и периодику из личного собрания В. М. Крутовского с его подписью; и многочисленные
|
||||||
дореволюционные нотные издания, оставшиеся в доме художника от семьи музыкантов, квартирантов Красиковых.
|
дореволюционные нотные издания, оставшиеся в доме художника от семьи музыкантов, квартирантов Красиковых.
|
||||||
Таким образом, <b>общее количество всех изданий по В.И. Сурикову, собранных в библиотеке музея, составляет
|
Таким образом, <b>общее количество всех изданий по В.И. Сурикову, собранных в библиотеке музея, составляет
|
||||||
более 100</b>. Сейчас музейная библиография публикуется впервые, ведь следуя миссии музея – мы делаем открытым
|
более 100</b>. Сейчас музейная библиография публикуется впервые, ведь следуя миссии музея – мы делаем
|
||||||
|
открытым
|
||||||
доступ к тем книжным ценностям, которые помогут будущим исследователям в изучении творческого наследия В. И.
|
доступ к тем книжным ценностям, которые помогут будущим исследователям в изучении творческого наследия В. И.
|
||||||
Сурикова.</p>
|
Сурикова.</p>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<section id="authentication">
|
||||||
|
<link href="/css/auth.css" rel="stylesheet">
|
||||||
|
|
||||||
|
{% if account is not empty %}
|
||||||
|
<h3 class="unselectable">Аккаунт</h3>
|
||||||
|
<div id="account">
|
||||||
|
<p><b class="unselectable"> Почта:</b><span title="{{ account.mail }}"> {{ account.mail
|
||||||
|
}}</span></p>
|
||||||
|
<a class="exit unselectable" type="button" href='/account/deauthentication'>Выход</a>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<h3 class="unselectable">Аутентификация</h3>
|
||||||
|
<form method="POST" accept-charset="UTF-8">
|
||||||
|
<input type="text" name="mail" placeholder="Почта">
|
||||||
|
<input type="password" name="password" placeholder="Пароль">
|
||||||
|
|
||||||
|
<div class="submit">
|
||||||
|
<label class="button unselectable fas fa-unlock" for="remember"
|
||||||
|
onclick="return remember_switch(this);"></label>
|
||||||
|
<input type="checkbox" name="remember" value="1">
|
||||||
|
<input type="submit" value="Войти" onclick="return authentication(this.parentElement.parentElement);">
|
||||||
|
</div>
|
||||||
|
<input type="submit" class="registration" value="Зарегистрироваться"
|
||||||
|
onclick="return registration(this.parentElement);">
|
||||||
|
|
||||||
|
{% if errors is not empty %}
|
||||||
|
{% if errors.account is not empty %}
|
||||||
|
<ul class="errors">
|
||||||
|
{% for error in errors.account %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/js/auth.js" defer></script>
|
||||||
|
</section>
|
||||||
47
kodorvan/surikov/system/views/themes/test/books/book.html
Normal file
47
kodorvan/surikov/system/views/themes/test/books/book.html
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
{% extends "/themes/test/core.html" %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<link href="/css/books.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<section id="book">
|
||||||
|
|
||||||
|
<h2>{{ book.title|e }}</h2>
|
||||||
|
|
||||||
|
<img id="page" class="unselectable" src="/storage/books/{{ book.identifier|e }}/{{ page|e }}"
|
||||||
|
alt='Страница отсутствует'>
|
||||||
|
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
{% if page != last %}
|
||||||
|
<!-- <li class="previous unselectable" type="button"><a href="/books/{{ book.identifier|e }}/{{ last|e }}"
|
||||||
|
title="Страница №{{ last|e }}">Назад</a></li> -->
|
||||||
|
|
||||||
|
<li class="previous unselectable">
|
||||||
|
<a href="/books/{{ book.identifier|e }}/{{ last|e }}" title="Страница №{{ last|e }}"><i
|
||||||
|
class="icon arrow" style="--rotate: 180deg; color:#9b3d10"></i></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% 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.identifier|e }}, {{ page|e }}, true)" title="Повернуть страницу"></i></li>
|
||||||
|
<script type="text/javascript" src="/js/book/rotate.js"></script>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
<li class="middle icon unselectable"><i class="fa-solid fa-rotate-right unselectable" type="button"
|
||||||
|
onclick="turning()" title="Повернуть страницу"></i></li>
|
||||||
|
<script type="text/javascript" src="/js/book/turning.js"></script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{%if page != next %}
|
||||||
|
<li class="next unselectable"><a href="/books/{{ book.identifier|e }}/{{ next|e }}"
|
||||||
|
title="Страница №{{ next|e }}"><i class="icon arrow" style="--rotate: 0deg;color:#9b3d10"></i></a>
|
||||||
|
</li>
|
||||||
|
{%endif%}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{% extends "/themes/test/core.html" %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<link href="/css/books.css" rel="stylesheet">
|
||||||
|
<link href="/css/upload.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<section id="books">
|
||||||
|
|
||||||
|
{% if account is not empty %}
|
||||||
|
{% if account.permissions.books is defined and account.permissions.books == 1 %}
|
||||||
|
<form class="upload unselectable" action="/storage/books/write" enctype="multipart/form-data" method="POST">
|
||||||
|
|
||||||
|
<input type="file" name="books[]" accept=".pdf" oninput="this.parentElement.submit();" multiple="true">
|
||||||
|
<p>+</p>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for book in books %}
|
||||||
|
<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="image-book unselectable" alt='Обложка книги "{{ book.title|e }}"'>
|
||||||
|
<h4><a href="/books/{{ book.id|e }}">{{ book.title|e }}</a></h3>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if account.permissions.books is defined and account.permissions.books == 1 %}
|
||||||
|
<script type="text/javascript" src="/js/book/delete.js"></script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
42
kodorvan/surikov/system/views/themes/test/books/index.html
Normal file
42
kodorvan/surikov/system/views/themes/test/books/index.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{% extends "/themes/test/core.html" %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
<link href="/css/books.css" rel="stylesheet">
|
||||||
|
<link href="/css/upload.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<section id="books">
|
||||||
|
|
||||||
|
{% if account is not empty %}
|
||||||
|
{% if account.permissions.books is defined and account.permissions.books == 1 %}
|
||||||
|
<form class="upload unselectable" action="/storage/books/write" enctype="multipart/form-data" method="POST">
|
||||||
|
|
||||||
|
<input type="file" name="books[]" accept=".pdf" oninput="this.parentElement.submit();" multiple="true">
|
||||||
|
<p>+</p>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for book in books %}
|
||||||
|
{% if book.active == 1 %}
|
||||||
|
<article class="book" id="book-{{ book.identifier|e }}">
|
||||||
|
|
||||||
|
{% if account.permissions.books is defined and account.permissions.books == 1 %}
|
||||||
|
<button onclick="trash({{ book.identifier|e }}, this.closest('.book'))" title="Удалить"><i
|
||||||
|
class="fa-solid fa-xmark"></i></button>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
<img src="/storage/books/{{ book.identifier|e }}/0" class="unselectable"
|
||||||
|
alt='Обложка книги "{{ book.title|e }}"'>
|
||||||
|
<h4><a href="/books/{{ book.identifier|e }}">{{ book.title|e }}</a></h3>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
{%endif%}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if account.permissions.books is defined and account.permissions.books == 1 %}
|
||||||
|
<script type="text/javascript" src="/js/book/delete.js"></script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
40
kodorvan/surikov/system/views/themes/test/core.html
Normal file
40
kodorvan/surikov/system/views/themes/test/core.html
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<html lang="ru">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
{% include '/themes/test/head.html' %}
|
||||||
|
|
||||||
|
<link href="/css/test/test-main.css" rel="stylesheet">
|
||||||
|
<link href="/css/publications.css" rel="stylesheet">
|
||||||
|
<link href="/css/icons/arrow.css" rel="stylesheet">
|
||||||
|
<title>
|
||||||
|
{% block title %}
|
||||||
|
Библиотека Сурикова
|
||||||
|
{% endblock %}
|
||||||
|
</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
{% include '/themes/test/header.html' %}
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
{% include '/themes/test/sidebar.html' %}
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
|
||||||
|
{% include '/themes/test/footer.html' %}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
{% include '/themes/test/js.html' %}
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
3
kodorvan/surikov/system/views/themes/test/footer.html
Normal file
3
kodorvan/surikov/system/views/themes/test/footer.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<footer>
|
||||||
|
|
||||||
|
</footer>
|
||||||
8
kodorvan/surikov/system/views/themes/test/head.html
Normal file
8
kodorvan/surikov/system/views/themes/test/head.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Geologica:wght@100..900&display=swap" rel="stylesheet">
|
||||||
18
kodorvan/surikov/system/views/themes/test/header.html
Normal file
18
kodorvan/surikov/system/views/themes/test/header.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<header class="unselectable">
|
||||||
|
<section class="menu">
|
||||||
|
<nav>
|
||||||
|
<a class="link" href="/kemenov" title="Архивный фонд">Кеменов</a>
|
||||||
|
<a class="link" href="/surikov" title="Список книг">Суриков</a>
|
||||||
|
<a id="logo" href="/" title="Главная страница">
|
||||||
|
<img src="/img/surikovlib_logo_1_white.svg">
|
||||||
|
</a>
|
||||||
|
<a class="link" href="/books" title="Читать книги">Библиотека</a>
|
||||||
|
<a class="link" href="/contacts" title="Контакты администрации">Контакты</a>
|
||||||
|
</nav>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="window">
|
||||||
|
<img class="img_1" src="/img/ФЖ-28.png" alt="">
|
||||||
|
<img class="background" src="/img/background_1.png" alt="">
|
||||||
|
</section>
|
||||||
|
</header>
|
||||||
8
kodorvan/surikov/system/views/themes/test/js.html
Normal file
8
kodorvan/surikov/system/views/themes/test/js.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/js/auth.js"></script>
|
||||||
|
<script src="https://kit.fontawesome.com/d67f03b1ae.js" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{% extends "/themes/test/core.html" %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% include '/themes/test/publications.html' %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
{% extends "/themes/test/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 "/themes/test/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,40 @@
|
|||||||
|
{% extends "/themes/test/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 %}
|
||||||
47
kodorvan/surikov/system/views/themes/test/publication.html
Normal file
47
kodorvan/surikov/system/views/themes/test/publication.html
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<div class="block-new" id="publication-{{publication.identifier|e }}">
|
||||||
|
|
||||||
|
<div class="new-inside">
|
||||||
|
<div class=" new-title" id="{{publication.identifier|e }}">
|
||||||
|
|
||||||
|
<h1 id="publication-title-{{publication.identifier|e }}">
|
||||||
|
{{publication.title|e }} </h1>
|
||||||
|
<div class="right-block">
|
||||||
|
{% if account.permissions.publications is defined and account.permissions.publications == 1 %}
|
||||||
|
<div class="new-btns">
|
||||||
|
|
||||||
|
<button id="edit" onclick="update({{publication.identifier|e}})">
|
||||||
|
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||||
|
d="M21.2635 2.29289C20.873 1.90237 20.2398 1.90237 19.8493 2.29289L18.9769 3.16525C17.8618 2.63254 16.4857 2.82801 15.5621 3.75165L4.95549 14.3582L10.6123 20.0151L21.2189 9.4085C22.1426 8.48486 22.338 7.1088 21.8053 5.99367L22.6777 5.12132C23.0682 4.7308 23.0682 4.09763 22.6777 3.70711L21.2635 2.29289ZM16.9955 10.8035L10.6123 17.1867L7.78392 14.3582L14.1671 7.9751L16.9955 10.8035ZM18.8138 8.98525L19.8047 7.99429C20.1953 7.60376 20.1953 6.9706 19.8047 6.58007L18.3905 5.16586C18 4.77534 17.3668 4.77534 16.9763 5.16586L15.9853 6.15683L18.8138 8.98525Z"
|
||||||
|
fill="currentColor" />
|
||||||
|
<path d="M2 22.9502L4.12171 15.1717L9.77817 20.8289L2 22.9502Z" fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button id="trash" onclick="trash({{publication.identifier|e}}, this.closest('.block-new'))">
|
||||||
|
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||||
|
d="M17 5V4C17 2.89543 16.1046 2 15 2H9C7.89543 2 7 2.89543 7 4V5H4C3.44772 5 3 5.44772 3 6C3 6.55228 3.44772 7 4 7H5V18C5 19.6569 6.34315 21 8 21H16C17.6569 21 19 19.6569 19 18V7H20C20.5523 7 21 6.55228 21 6C21 5.44772 20.5523 5 20 5H17ZM15 4H9V5H15V4ZM17 7H7V18C7 18.5523 7.44772 19 8 19H16C16.5523 19 17 18.5523 17 18V7Z"
|
||||||
|
fill="currentColor" />
|
||||||
|
<path d="M9 9H11V17H9V9Z" fill="currentColor" />
|
||||||
|
<path d="M13 9H15V17H13V9Z" fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{%endif%}
|
||||||
|
|
||||||
|
<span>{{publication.created|date("d.m.Y") }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p id="publication-content-{{publication.identifier|e }}">{{publication.content }}</p>
|
||||||
|
|
||||||
|
<img src="/storage/publications/{{publication.identifier|e }}" alt="Не удалось загрузить изображение" id="img-{{publication.identifier|e }}">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
62
kodorvan/surikov/system/views/themes/test/publications.html
Normal file
62
kodorvan/surikov/system/views/themes/test/publications.html
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<div class="content-main">
|
||||||
|
|
||||||
|
{% if account is not empty %}
|
||||||
|
{% if account.permissions.publications is defined and account.permissions.publications == 1 %}
|
||||||
|
<div class="add-new unselectable">
|
||||||
|
|
||||||
|
<input type="text" placeholder="Заголовок" name="title" id="title">
|
||||||
|
<textarea type="text" placeholder="Напишите что-нибудь.." name="content" id="content"></textarea>
|
||||||
|
|
||||||
|
<div class="new-btn">
|
||||||
|
|
||||||
|
<div class="custom-file-upload">
|
||||||
|
|
||||||
|
<input type="file" id="file-input" class="file-input" name="publications[]"
|
||||||
|
accept=".png,.gif,.jpeg,.jpg">
|
||||||
|
<label for="file-input" class="custom-file-button">
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||||
|
d="M7 7C5.34315 7 4 8.34315 4 10C4 11.6569 5.34315 13 7 13C8.65685 13 10 11.6569 10 10C10 8.34315 8.65685 7 7 7ZM6 10C6 9.44772 6.44772 9 7 9C7.55228 9 8 9.44772 8 10C8 10.5523 7.55228 11 7 11C6.44772 11 6 10.5523 6 10Z"
|
||||||
|
fill="currentColor" />
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||||
|
d="M3 3C1.34315 3 0 4.34315 0 6V18C0 19.6569 1.34315 21 3 21H21C22.6569 21 24 19.6569 24 18V6C24 4.34315 22.6569 3 21 3H3ZM21 5H3C2.44772 5 2 5.44772 2 6V18C2 18.5523 2.44772 19 3 19H7.31374L14.1924 12.1214C15.364 10.9498 17.2635 10.9498 18.435 12.1214L22 15.6863V6C22 5.44772 21.5523 5 21 5ZM21 19H10.1422L15.6066 13.5356C15.9971 13.145 16.6303 13.145 17.0208 13.5356L21.907 18.4217C21.7479 18.7633 21.4016 19 21 19Z"
|
||||||
|
fill="currentColor" />
|
||||||
|
</svg>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button onclick="create()" name="account">Сохранить</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{%endif%}
|
||||||
|
{%endif%}
|
||||||
|
|
||||||
|
<div class="content-news" id="publications">
|
||||||
|
|
||||||
|
{% for publication in publications %}
|
||||||
|
|
||||||
|
{% include '/themes/test/publication.html' %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if errors is not empty %}
|
||||||
|
{% if errors.account is not empty %}
|
||||||
|
<ul class="errors">
|
||||||
|
|
||||||
|
{% for error in errors.account %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if account.permissions.publications is defined and account.permissions.publications == 1 %}
|
||||||
|
<script type="text/javascript" src="/js/publication/trash.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/publication/update.js"></script>
|
||||||
|
<script type="text/javascript" src="/js/publication/create.js"></script>
|
||||||
|
{%endif%}
|
||||||
|
|
||||||
|
</div>
|
||||||
5
kodorvan/surikov/system/views/themes/test/sidebar.html
Normal file
5
kodorvan/surikov/system/views/themes/test/sidebar.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<link href="/css/banners.css" rel="stylesheet">
|
||||||
|
|
||||||
|
{% include '/themes/default/authentication.html' %}
|
||||||
|
{% include '/themes/default/vk.html' %}
|
||||||
|
|
||||||
11
kodorvan/surikov/system/views/themes/test/vk.html
Normal file
11
kodorvan/surikov/system/views/themes/test/vk.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<section id="vk">
|
||||||
|
<script src="https://vk.com/js/api/openapi.js?169" type="text/javascript"></script>
|
||||||
|
<script type="text/javascript" src="https://vk.com/js/api/openapi.js?169"></script>
|
||||||
|
|
||||||
|
<div id="group"></div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
VK.Widgets.Group("group", { mode: 4, wide: 0, width: parseInt(getComputedStyle(document.getElementById('vk')).getPropertyValue('width')), height: "600", color1: 'E5DDD1', color3: '86781C' }, 29605269);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</section>
|
||||||
Reference in New Issue
Block a user