generated from mirzaev/pot
starting farting
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "damper.mjs"]
|
||||
path = damper.mjs
|
||||
url = https://git.svoboda.works/mirzaev/damper.mjs
|
||||
@@ -27,7 +27,10 @@
|
||||
"mirzaev/baza": "^3.3",
|
||||
"twig/twig": "^3.2",
|
||||
"twig/extra-bundle": "^3.7",
|
||||
"twig/intl-extra": "^3.10"
|
||||
"twig/intl-extra": "^3.10",
|
||||
"mirzaev/languages": "^1.0",
|
||||
"mirzaev/currencies": "^1.0",
|
||||
"svoboda/time": "^1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
1
damper.mjs
Submodule
1
damper.mjs
Submodule
Submodule damper.mjs added at 81d208b964
13
install.sh
13
install.sh
@@ -1,10 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -d author/project ]; then
|
||||
mv author/project author/site
|
||||
fi
|
||||
|
||||
if [ -d author ]; then
|
||||
mv author zharko
|
||||
fi
|
||||
#!/bin/fish
|
||||
|
||||
if not test -L zharko/site/system/public/js/modules/damper.mjs
|
||||
ln -s ../../../../../../damper.mjs/damper.mjs zharko/site/system/public/js/modules/damper.mjs;
|
||||
end
|
||||
|
||||
120
zharko/site/system/controllers/account.php
Executable file
120
zharko/site/system/controllers/account.php
Executable file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace zharko\site\controllers;
|
||||
|
||||
// Files of the project
|
||||
use zharko\site\controllers\core;
|
||||
|
||||
// Framework for PHP
|
||||
use mirzaev\minimal\http\enumerations\content,
|
||||
mirzaev\minimal\http\enumerations\method,
|
||||
mirzaev\minimal\http\enumerations\status;
|
||||
|
||||
// Library for languages support
|
||||
use mirzaev\languages\language;
|
||||
|
||||
/**
|
||||
* Account
|
||||
*
|
||||
* @package zharko\site\controllers
|
||||
*
|
||||
* @param array $errors Registry of errors
|
||||
*
|
||||
* @method null index() Main page
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
final class account extends core
|
||||
{
|
||||
/**
|
||||
* Errors
|
||||
*
|
||||
* @var array $errors Registry of errors
|
||||
*/
|
||||
protected array $errors = [
|
||||
'system' => [],
|
||||
'account' => []
|
||||
];
|
||||
|
||||
/**
|
||||
* Registration page
|
||||
*
|
||||
* @param string|null $mail Mail
|
||||
* @param string|null $password Password
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function registration(
|
||||
?string $mail = null,
|
||||
?string $password = null
|
||||
): null {
|
||||
if ($this->request->method === method::put) {
|
||||
// PUT (creating the account)
|
||||
|
||||
if (str_contains($this->request->headers['accept'] ?? '', content::json->value)) {
|
||||
// Request for JSON response
|
||||
|
||||
// Filtering the mail value
|
||||
preg_match('/([^@\r\n]+)@([^@\r\n\.]+)\.([^@\r\n\.]+)/u', 'vova@mail.ru', $matches);
|
||||
$mail = $matches[1] . '@' . $matches[2] . '.' . $matches[3];
|
||||
unset($matches);
|
||||
|
||||
// Filtering the password value
|
||||
preg_match_all('/[^a-fA-F0-9]+/Uu', $password, $password_restricted);
|
||||
|
||||
if (empty($mail)) {
|
||||
// Mail is empty
|
||||
|
||||
} else if (empty($password)) {
|
||||
// Password is empty
|
||||
|
||||
} else if (!empty($password_restricted)) {
|
||||
// Pasword has restricted symbols
|
||||
|
||||
} else {
|
||||
// All parameters validated
|
||||
|
||||
// Creating the account
|
||||
$this->model->write(mail: $mail, password: $password, errors: $this->errors['account']);
|
||||
|
||||
// Exit (success)
|
||||
return null;
|
||||
}
|
||||
|
||||
// Exit (fail)
|
||||
return null;
|
||||
}
|
||||
} else if ($this->request->method === method::get) {
|
||||
// GET (sending the HTML-document for registration)
|
||||
|
||||
if (str_contains($this->request->headers['accept'] ?? '', content::html->value)) {
|
||||
// Request for HTML response
|
||||
|
||||
// Render page
|
||||
$page = $this->view->render('pages/account/registration.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;
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ namespace zharko\site\controllers;
|
||||
// Files of the project
|
||||
use zharko\site\views\templater,
|
||||
zharko\site\models\core as models,
|
||||
zharko\site\models\account,
|
||||
zharko\site\models\enumerations\language;
|
||||
zharko\site\models\session,
|
||||
zharko\site\models\account;
|
||||
|
||||
// Framework for PHP
|
||||
use mirzaev\minimal\core as minimal,
|
||||
@@ -16,6 +16,9 @@ use mirzaev\minimal\core as minimal,
|
||||
mirzaev\minimal\http\response,
|
||||
mirzaev\minimal\http\enumerations\status;
|
||||
|
||||
// Library for languages support
|
||||
use mirzaev\languages\language;
|
||||
|
||||
/**
|
||||
* Controllers core
|
||||
*
|
||||
@@ -30,10 +33,16 @@ use mirzaev\minimal\core as minimal,
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
* @author zharko <mail@domain.zone>
|
||||
*/
|
||||
class core extends controller
|
||||
{
|
||||
/**
|
||||
* Session
|
||||
*
|
||||
* @var session $session Session
|
||||
*/
|
||||
protected session $session;
|
||||
|
||||
/**
|
||||
* Account
|
||||
*
|
||||
|
||||
@@ -22,7 +22,6 @@ use mirzaev\minimal\http\enumerations\content,
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
* @author zharko <mail@domain.zone>
|
||||
*/
|
||||
final class index extends core
|
||||
{
|
||||
|
||||
@@ -5,7 +5,20 @@ declare(strict_types=1);
|
||||
namespace zharko\site\models;
|
||||
|
||||
// Files of the project
|
||||
use zharko\site\models\core
|
||||
use zharko\site\models\core;
|
||||
|
||||
// Library for languages
|
||||
use mirzaev\languages\language;
|
||||
|
||||
// Baza database
|
||||
use mirzaev\baza\database,
|
||||
mirzaev\baza\column,
|
||||
mirzaev\baza\record,
|
||||
mirzaev\baza\enumerations\encoding,
|
||||
mirzaev\baza\enumerations\type;
|
||||
|
||||
// Svoboda time
|
||||
use svoboda\time\statement as svoboda;
|
||||
|
||||
// Built-in libraries
|
||||
use Exception as exception,
|
||||
@@ -28,7 +41,7 @@ class account extends core
|
||||
*
|
||||
* @var string database Path to the database file
|
||||
*/
|
||||
protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'account.baza';
|
||||
protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'accounts.baza';
|
||||
|
||||
/**
|
||||
* Database
|
||||
@@ -66,6 +79,52 @@ class account extends core
|
||||
->connect($this->file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write
|
||||
*
|
||||
* Create the account record in the database
|
||||
*
|
||||
* @return int|false The record identifier, if created
|
||||
*/
|
||||
public function write(
|
||||
string $domain = '',
|
||||
string $name = '',
|
||||
string $mail = '',
|
||||
string $password = '',
|
||||
language $language = language::en,
|
||||
&$errors = []
|
||||
): int|false {
|
||||
// Initializing the identifier
|
||||
$identifier = $this->database->count() + 1;
|
||||
|
||||
// Calculating the current timestamp
|
||||
$timestamp = svoboda::timestamp();
|
||||
|
||||
// Initializing the record
|
||||
$record = $this->database->record(
|
||||
$identifier,
|
||||
$domain,
|
||||
$name,
|
||||
$mail,
|
||||
$password,
|
||||
'',
|
||||
'',
|
||||
$language->value,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
$timestamp,
|
||||
$timestamp
|
||||
);
|
||||
|
||||
// Creating the record in the database
|
||||
$created = $this->database->write($record);
|
||||
|
||||
// Exit (success)
|
||||
return $created ? $identifier : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorization
|
||||
*
|
||||
@@ -88,16 +147,16 @@ class account extends core
|
||||
// Found the account record
|
||||
|
||||
if (
|
||||
$account->name_first !== $telegram->getFirstName() ||
|
||||
$account->name_second !== $telegram->getLastName() ||
|
||||
$account->domain !== $telegram->getUsername()
|
||||
$account->name_first !== $telegram->getFirstName() ||
|
||||
$account->name_second !== $telegram->getLastName() ||
|
||||
$account->domain !== $telegram->getUsername()
|
||||
) {
|
||||
// The telegram account was updated
|
||||
|
||||
|
||||
// Updating the account in the database
|
||||
$updated = $this->database->read(
|
||||
filter: fn(record $record) => $record->identifier_telegram === $telegram->getId(),
|
||||
update: function (record &$record) use ($telegram){
|
||||
update: function (record &$record) use ($telegram) {
|
||||
// Writing new values into the record
|
||||
$record->name_first = $telegram->getFirstName();
|
||||
$record->name_second = $telegram->getLastName();
|
||||
@@ -151,4 +210,3 @@ class account extends core
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace zharko\site\models\enumerations;
|
||||
|
||||
/**
|
||||
* Language
|
||||
*
|
||||
* Types of languages by ISO 639-1 standart
|
||||
*
|
||||
* @package zharko\site\models\enumerations
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
* @author zharko <mail@domain.zone>
|
||||
*/
|
||||
enum language
|
||||
{
|
||||
case en;
|
||||
case ru;
|
||||
|
||||
/**
|
||||
* Label
|
||||
*
|
||||
* Initialize label of the language
|
||||
*
|
||||
* @param language|null language Language into which to translate
|
||||
*
|
||||
* @return string Translated label of the language
|
||||
*/
|
||||
public function label(?language $language = language::en): string
|
||||
{
|
||||
// Exit (success)
|
||||
return match ($this) {
|
||||
language::en => match ($language) {
|
||||
language::en => 'English',
|
||||
language::ru => 'Английский'
|
||||
},
|
||||
language::ru => match ($language) {
|
||||
language::en => 'Russian',
|
||||
language::ru => 'Русский'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag
|
||||
*
|
||||
* Initialize the flag emoji of the language
|
||||
*
|
||||
* @return string The flag emoji of the language
|
||||
*/
|
||||
public function flag(): string
|
||||
{
|
||||
// Exit (success)
|
||||
return match ($this) {
|
||||
language::en => '🇺🇸',
|
||||
language::ru => '🇷🇺'
|
||||
};
|
||||
}
|
||||
}
|
||||
19
zharko/site/system/models/enumerations/session.php
Normal file
19
zharko/site/system/models/enumerations/session.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace zharko\site\models\enumerations;
|
||||
|
||||
/**
|
||||
* Types of session verification
|
||||
*
|
||||
* @package zharko\site\models\enumerations
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
enum session
|
||||
{
|
||||
case blake2b;
|
||||
case blake2b_or_address;
|
||||
}
|
||||
43
zharko/site/system/models/middlewares/account.php
Executable file
43
zharko/site/system/models/middlewares/account.php
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace zharko\site\models\middlewares;
|
||||
|
||||
// Files of the project
|
||||
use zharko\site\models\core,
|
||||
zharko\site\models\account as model;
|
||||
|
||||
// Framework for PHP
|
||||
use mirzaev\minimal\route,
|
||||
mirzaev\minimal\controller,
|
||||
mirzaev\minimal\middleware;
|
||||
|
||||
// Built-in libraries
|
||||
use Exception as exception,
|
||||
RuntimeException as exception_runtime;
|
||||
|
||||
/**
|
||||
* Account middleware
|
||||
*
|
||||
* @package zharko\site\models\middlewares
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class account extends middleware
|
||||
{
|
||||
/**
|
||||
* Authentication
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function authentication(callable $next, controller $controller): void
|
||||
{
|
||||
// Authorizing the account
|
||||
$controller->account = account::authorization() ?? null;
|
||||
|
||||
// Exit (success)
|
||||
$next();
|
||||
}
|
||||
}
|
||||
55
zharko/site/system/models/middlewares/session.php
Executable file
55
zharko/site/system/models/middlewares/session.php
Executable file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace zharko\site\models\middlewares;
|
||||
|
||||
// Files of the project
|
||||
use zharko\site\models\core,
|
||||
zharko\site\models\session as model;
|
||||
|
||||
// Framework for PHP
|
||||
use mirzaev\minimal\route,
|
||||
mirzaev\minimal\controller,
|
||||
mirzaev\minimal\middleware;
|
||||
|
||||
// Baza database
|
||||
use mirzaev\baza\database,
|
||||
mirzaev\baza\column,
|
||||
mirzaev\baza\record,
|
||||
mirzaev\baza\enumerations\encoding,
|
||||
mirzaev\baza\enumerations\type;
|
||||
|
||||
// Built-in libraries
|
||||
use Exception as exception,
|
||||
RuntimeException as exception_runtime;
|
||||
|
||||
/**
|
||||
* Session middleware
|
||||
*
|
||||
* @package zharko\site\models\middlewares
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class session extends middleware
|
||||
{
|
||||
/**
|
||||
* Middleware
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function middleware(callable $next, controller $controller): void
|
||||
{
|
||||
// Initializing the session
|
||||
$session = model::read();
|
||||
|
||||
if ($session instanceof session) {
|
||||
// Found the session
|
||||
|
||||
}
|
||||
|
||||
// Exit (success)
|
||||
$next();
|
||||
}
|
||||
}
|
||||
169
zharko/site/system/models/session.php
Executable file
169
zharko/site/system/models/session.php
Executable file
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace zharko\site\models;
|
||||
|
||||
// Files of the project
|
||||
use zharko\site\models\core,
|
||||
zharko\site\models\enumerations\session as verification;
|
||||
|
||||
// Library for languages
|
||||
use mirzaev\languages\language;
|
||||
|
||||
// Baza database
|
||||
use mirzaev\baza\database,
|
||||
mirzaev\baza\column,
|
||||
mirzaev\baza\record,
|
||||
mirzaev\baza\enumerations\encoding,
|
||||
mirzaev\baza\enumerations\type;
|
||||
|
||||
// Svoboda time
|
||||
use svoboda\time\statement as svoboda;
|
||||
|
||||
// Built-in libraries
|
||||
use Exception as exception,
|
||||
RuntimeException as exception_runtime;
|
||||
|
||||
/**
|
||||
* Session model
|
||||
*
|
||||
* @package zharko\site\models
|
||||
*
|
||||
* @method void __construct() Constructor
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class session extends core
|
||||
{
|
||||
/**
|
||||
* File
|
||||
*
|
||||
* @var string database Path to the database file
|
||||
*/
|
||||
protected string $file = DATABASES . DIRECTORY_SEPARATOR . 'sessions.baza';
|
||||
|
||||
/**
|
||||
* Database
|
||||
*
|
||||
* @var database $database The database
|
||||
*/
|
||||
public protected(set) database $database;
|
||||
|
||||
/**
|
||||
* Type
|
||||
*
|
||||
* @var varification Type of the session verification
|
||||
*/
|
||||
final public const verification VERIFICATION = verification::blake2b;
|
||||
|
||||
/**
|
||||
* Timer
|
||||
*
|
||||
* @var int The number of seconds after which the session is deactivated
|
||||
*/
|
||||
final public const int TIMER = 604800;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Initializing the database
|
||||
$this->database = new database()
|
||||
->encoding(encoding::utf8)
|
||||
->columns(
|
||||
new column('identifier', type::integer_unsigned),
|
||||
new column('expires', type::integer_unsigned),
|
||||
new column('address', type::string, ['length' => 128]),
|
||||
new column('x-forwarded-for', type::string, ['length' => 128]),
|
||||
new column('referer', type::string, ['length' => 128]),
|
||||
new column('useragent', type::string, ['length' => 256]),
|
||||
new column('updated', type::integer_unsigned),
|
||||
new column('created', type::integer_unsigned)
|
||||
)
|
||||
->connect($this->file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write
|
||||
*
|
||||
* Create the session record in the database
|
||||
*
|
||||
* @return int|false The record identifier, if created
|
||||
*/
|
||||
public function write(
|
||||
string $address = '',
|
||||
string $x_forwarded_for = '',
|
||||
string $referer = '',
|
||||
string $useragent = '',
|
||||
&$errors = []
|
||||
): int|false {
|
||||
// Initializing the identifier
|
||||
$identifier = $this->database->count() + 1;
|
||||
|
||||
// Calculating the current timestamp
|
||||
$timestamp = svoboda::timestamp();
|
||||
|
||||
// Initializing the record
|
||||
$record = $this->database->record(
|
||||
$identifier,
|
||||
$timestamp + static::TIMER,
|
||||
$address,
|
||||
$x_forwarded_for,
|
||||
$referer,
|
||||
$useragent,
|
||||
$timestamp,
|
||||
$timestamp
|
||||
);
|
||||
|
||||
// Creating the record in the database
|
||||
$created = $this->database->write($record);
|
||||
|
||||
// Exit (success)
|
||||
return $created ? $identifier : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read
|
||||
*
|
||||
* Read the session record from the database
|
||||
*
|
||||
* @return int|false The record identifier, if created
|
||||
*/
|
||||
public function read(
|
||||
string $address = '',
|
||||
string $x_forwarded_for = '',
|
||||
string $referer = '',
|
||||
string $useragent = '',
|
||||
&$errors = []
|
||||
): int|false {
|
||||
// Initializing the identifier
|
||||
$identifier = $this->database->count() + 1;
|
||||
|
||||
// Calculating the current timestamp
|
||||
$timestamp = svoboda::timestamp();
|
||||
|
||||
// Initializing the record
|
||||
$record = $this->database->record(
|
||||
$identifier,
|
||||
$timestamp + static::TIMER,
|
||||
$address,
|
||||
$x_forwarded_for,
|
||||
$referer,
|
||||
$useragent,
|
||||
$timestamp,
|
||||
$timestamp
|
||||
);
|
||||
|
||||
// Creating the record in the database
|
||||
$created = $this->database->write($record);
|
||||
|
||||
// Exit (success)
|
||||
return $created ? $identifier : false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace zharko\site;
|
||||
|
||||
// Files of the project
|
||||
use zharko\site\models\middlewares\session;
|
||||
|
||||
// Framework for PHP
|
||||
use mirzaev\minimal\core,
|
||||
mirzaev\minimal\route,
|
||||
@@ -48,15 +51,12 @@ $core = new core(namespace: __NAMESPACE__);
|
||||
// Initializing routes
|
||||
$core->router
|
||||
->write('/', new route('index', 'index'), 'GET')
|
||||
->write('/account/registration', new route('account', 'registration'), ['GET', 'PUT'])
|
||||
;
|
||||
|
||||
// Writing the global middleware
|
||||
$core->router->middleware(new middleware(function(callable $next, controller $controller) {
|
||||
// Authorizing the account
|
||||
$controller->account = account::authorization() ?? null;
|
||||
|
||||
$next();
|
||||
}));
|
||||
$core->router->middleware(new session);
|
||||
/* $core->router->middleware(new account); */
|
||||
|
||||
// Processing the request
|
||||
$core->start();
|
||||
|
||||
404
zharko/site/system/public/js/core.js
Normal file
404
zharko/site/system/public/js/core.js
Normal file
@@ -0,0 +1,404 @@
|
||||
/**
|
||||
* @name Core
|
||||
*
|
||||
* @description
|
||||
* Core of the project
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class core {
|
||||
// Domain
|
||||
static domain = window.location.hostname;
|
||||
|
||||
// Language
|
||||
static language = "en";
|
||||
|
||||
// Theme
|
||||
static theme = window.getComputedStyle(document.getElementById('theme'));
|
||||
|
||||
// Window
|
||||
static window;
|
||||
|
||||
// The "loading" element
|
||||
static loading = document.getElementById("loading");
|
||||
|
||||
// The <header> element
|
||||
static header = document.body.getElementsByTagName("header")[0];
|
||||
|
||||
// The <aside> element
|
||||
static aside = document.body.getElementsByTagName("aside")[0];
|
||||
|
||||
// The <menu> element
|
||||
static menu = document.getElementById("menu");
|
||||
|
||||
// The <main> element
|
||||
static main = document.body.getElementsByTagName("main")[0];
|
||||
|
||||
// The <footer> element
|
||||
static footer = document.body.getElementsByTagName("footer")[0];
|
||||
|
||||
/**
|
||||
* Request
|
||||
*
|
||||
* @param {string} uri
|
||||
* @param {string} body
|
||||
* @param {string} method POST, GET...
|
||||
* @param {object} headers
|
||||
* @param {string} type Format of response (json, text...)
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
static async request(
|
||||
uri = "/",
|
||||
body,
|
||||
method = "GET",
|
||||
headers = {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"Accept": "application/json",
|
||||
},
|
||||
type = "json",
|
||||
) {
|
||||
return await fetch(encodeURI(uri), { method, headers, body })
|
||||
.then((response) => type === null || response[type]());
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Modules
|
||||
*
|
||||
* @method connect(modules) Connect modules
|
||||
*
|
||||
* @return {Array} List of initialized modules
|
||||
*/
|
||||
static modules() {
|
||||
return Object.keys(this).filter((module) =>
|
||||
this[module]?.type === "module"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Buffer
|
||||
*/
|
||||
static buffer = class buffer {
|
||||
/**
|
||||
* @name Write to buffers
|
||||
*
|
||||
* @description
|
||||
* Write to buffers (interface)
|
||||
*
|
||||
* @param {string} name Name of the parameter
|
||||
* @param {string} value Value of the parameter (it can be JSON)
|
||||
*
|
||||
* @return {bool} Execution completed with an error?
|
||||
*/
|
||||
static write(name, value) {
|
||||
core.modules.connect("damper").then(
|
||||
() => {
|
||||
// Imported the damper module
|
||||
|
||||
// Execute under damper
|
||||
this.write.damper(name, value);
|
||||
},
|
||||
() => {
|
||||
// Not imported the damper module
|
||||
|
||||
// Execute
|
||||
this.write.system(name, value);
|
||||
},
|
||||
);
|
||||
|
||||
// Exit (success)
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Сгенерировать окно выбора действия
|
||||
*
|
||||
* @param {string} title Верхний колонтинул
|
||||
* @param {string} text Основное содержимое окна
|
||||
* @param {string} left Содержимое левой кнопки
|
||||
* @param {object} left_css Перечисление CSS-классов левой кнопки (массив)
|
||||
* @param {function} left_click Действие после нажатия на левую кнопку
|
||||
* @param {string} right Содержимое правой кнопки
|
||||
* @param {object} right_css Перечисление CSS-классов правой кнопки (массив)
|
||||
* @param {function} right_click Действие после нажатия на правую кнопку
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
/* static choose = core.damper(
|
||||
(
|
||||
title = "Выбор действия",
|
||||
text = "",
|
||||
left = "Да",
|
||||
left_css = ["grass"],
|
||||
left_click = () => {},
|
||||
right = "Нет",
|
||||
right_css = ["clay"],
|
||||
right_click = () => {},
|
||||
) => {
|
||||
// Инициализация оболочки всплывающего окна
|
||||
this.popup_body.wrap = document.createElement("div");
|
||||
this.popup_body.wrap.setAttribute("id", "popup");
|
||||
|
||||
// Инициализация всплывающего окна
|
||||
const popup = document.createElement("section");
|
||||
popup.classList.add("list", "small");
|
||||
|
||||
// Инициализация заголовка всплывающего окна
|
||||
const title_h3 = document.createElement("h3");
|
||||
title_h3.classList.add("unselectable");
|
||||
title_h3.innerText = title;
|
||||
|
||||
// Инициализация оболочки с основной информацией
|
||||
const main = document.createElement("section");
|
||||
main.classList.add("main");
|
||||
|
||||
// Инициализация колонки
|
||||
const column = document.createElement("div");
|
||||
column.classList.add("column");
|
||||
|
||||
// Инициализация текста
|
||||
const text_p = document.createElement("p");
|
||||
text_p.innerText = text;
|
||||
|
||||
// Инициализация строки
|
||||
const row = document.createElement("div");
|
||||
row.classList.add("row", "buttons");
|
||||
|
||||
// Инициализация левой кнопки
|
||||
const left_button = document.createElement("button");
|
||||
left_button.classList.add(...left_css);
|
||||
left_button.innerText = left;
|
||||
left_button.addEventListener("click", left_click);
|
||||
|
||||
// Инициализация правой кнопки
|
||||
const right_button = document.createElement("button");
|
||||
right_button.classList.add(...right_css);
|
||||
right_button.innerText = right;
|
||||
right_button.addEventListener("click", right_click);
|
||||
|
||||
// Инициализация окна с ошибками
|
||||
this.popup_body.errors = document.createElement("section");
|
||||
this.popup_body.errors.classList.add(
|
||||
"errors",
|
||||
"window",
|
||||
"list",
|
||||
"calculated",
|
||||
"hidden",
|
||||
);
|
||||
this.popup_body.errors.setAttribute("data-errors", true);
|
||||
|
||||
// Инициализация элемента-тела (оболочки) окна с ошибками
|
||||
const errors = document.createElement("section");
|
||||
errors.classList.add("body");
|
||||
|
||||
// Инициализация элемента-списка ошибок
|
||||
const dl = document.createElement("dl");
|
||||
|
||||
// Инициализация активного всплывающего окна
|
||||
const old = document.getElementById("popup");
|
||||
|
||||
if (old instanceof HTMLElement) {
|
||||
// Найдено активное окно
|
||||
|
||||
// Деинициализация быстрых действий по кнопкам
|
||||
document.removeEventListener("keydown", this.buttons);
|
||||
|
||||
// Сброс блокировки
|
||||
this.freeze = false;
|
||||
|
||||
// Удаление активного окна
|
||||
old.remove();
|
||||
}
|
||||
|
||||
// Запись в документ
|
||||
popup.appendChild(title_h3);
|
||||
|
||||
column.appendChild(text_p);
|
||||
|
||||
row.appendChild(left_button);
|
||||
row.appendChild(right_button);
|
||||
column.appendChild(row);
|
||||
|
||||
main.appendChild(column);
|
||||
popup.appendChild(main);
|
||||
|
||||
this.popup_body.wrap.appendChild(popup);
|
||||
document.body.appendChild(this.popup_body.wrap);
|
||||
|
||||
errors.appendChild(dl);
|
||||
this.popup_body.errors.appendChild(errors);
|
||||
this.popup_body.wrap.appendChild(this.popup_body.errors);
|
||||
|
||||
// Инициализация ширины окна с ошибками
|
||||
this.popup_body.errors.style.setProperty(
|
||||
"--calculated-width",
|
||||
popup.offsetWidth + "px",
|
||||
);
|
||||
|
||||
// Инициализация переменных для окна с ошибками (12 - это значение gap из div#popup)
|
||||
function top(errors) {
|
||||
errors.style.setProperty("transition", "0s");
|
||||
errors.style.setProperty(
|
||||
"--top",
|
||||
popup.offsetTop + popup.offsetHeight + 12 + "px",
|
||||
);
|
||||
setTimeout(() => errors.style.removeProperty("transition"), 100);
|
||||
}
|
||||
top(this.popup_body.errors);
|
||||
const resize = new ResizeObserver(() => top(this.popup_body.errors));
|
||||
resize.observe(this.popup_body.wrap);
|
||||
|
||||
// Инициализация функции закрытия всплывающего окна
|
||||
const click = () => {
|
||||
// Блокировка
|
||||
if (this.freeze) return;
|
||||
|
||||
// Удаление всплывающего окна
|
||||
this.popup_body.wrap.remove();
|
||||
|
||||
// Удаление статуса активной строки
|
||||
row.removeAttribute("data-selected");
|
||||
|
||||
// Деинициализация быстрых действий по кнопкам
|
||||
document.removeEventListener("keydown", this.buttons);
|
||||
|
||||
// Сброс блокировки
|
||||
this.freeze = false;
|
||||
};
|
||||
|
||||
// Инициализация функции добавления функции закрытия всплывающего окна
|
||||
const enable = () =>
|
||||
this.popup_body.wrap.addEventListener("click", click);
|
||||
|
||||
// Инициализация функции удаления функции закрытия всплывающего окна
|
||||
const disable = () =>
|
||||
this.popup_body.wrap.removeEventListener("click", click);
|
||||
|
||||
// Первичная активация функции удаления всплывающего окна
|
||||
enable();
|
||||
|
||||
// Добавление функции удаления всплывающего окна по событиям
|
||||
popup.addEventListener("mouseenter", disable);
|
||||
popup.addEventListener("mouseleave", enable);
|
||||
|
||||
// Добавление функции удаления всплывающего окна по кнопкам
|
||||
left_button.addEventListener("click", click);
|
||||
right_button.addEventListener("click", click);
|
||||
|
||||
// Фокусировка
|
||||
right_button.focus();
|
||||
},
|
||||
300,
|
||||
); */
|
||||
}
|
||||
|
||||
Object.assign(
|
||||
core.modules,
|
||||
{
|
||||
/**
|
||||
* @name Connect modules
|
||||
*
|
||||
* @param {Array|string} modules Names of modules or name of the module
|
||||
*
|
||||
* @return {Prommise}
|
||||
*/
|
||||
async connect(modules) {
|
||||
// Normalisation required argiments
|
||||
if (typeof modules === "string") modules = [modules];
|
||||
|
||||
if (modules instanceof Array) {
|
||||
// Received and validated required arguments
|
||||
|
||||
// Initializing the registry of loaded modules
|
||||
const loaded = [];
|
||||
|
||||
for (const module of modules) {
|
||||
// Iterating over modules
|
||||
|
||||
// Downloading, importing and writing the module into a core property and into registry of loaded modules
|
||||
core[module] =
|
||||
loaded[module] =
|
||||
await (await import(`./modules/${module}.mjs`)).default;
|
||||
}
|
||||
|
||||
// Exit (success)
|
||||
return loaded;
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
core.modules.connect("damper").then(() => {
|
||||
// Imported the damper module
|
||||
|
||||
Object.assign(
|
||||
core.buffer.write,
|
||||
{
|
||||
/**
|
||||
* @name Write to buffers
|
||||
*
|
||||
* @description
|
||||
* Write to buffers (damper)
|
||||
*
|
||||
* @param {string} name Name of the parameter
|
||||
* @param {string} value Value of the parameter (it can be JSON)
|
||||
* @param {bool} force Ignore the damper? (false)
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
damper: core.damper(
|
||||
(...variables) => core.buffer.write.system(...variables),
|
||||
300,
|
||||
2,
|
||||
),
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Write to buffers
|
||||
*
|
||||
* @description
|
||||
* Write to buffers (system)
|
||||
*
|
||||
* @param {string} name Name of the parameter
|
||||
* @param {string} value Value of the parameter (it can be JSON)
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
Object.assign(
|
||||
core.buffer.write,
|
||||
{
|
||||
system(
|
||||
name,
|
||||
value,
|
||||
resolve = () => {},
|
||||
reject = () => {},
|
||||
) {
|
||||
try {
|
||||
core.modules.connect("session").then(() => {
|
||||
// Imported the session module
|
||||
|
||||
// Write to the session buffer
|
||||
core.session.buffer?.write(name, value);
|
||||
});
|
||||
|
||||
core.modules.connect("account").then(() => {
|
||||
// Imported the account module
|
||||
|
||||
// Write to the account buffer
|
||||
core.account.buffer?.write(name, value);
|
||||
});
|
||||
|
||||
// Exit (success)
|
||||
resolve();
|
||||
} catch (e) {
|
||||
// Exit (fail)
|
||||
reject(e);
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
1
zharko/site/system/public/js/libraries/md5.js
Normal file
1
zharko/site/system/public/js/libraries/md5.js
Normal file
@@ -0,0 +1 @@
|
||||
var MD5 = function(d){var r = M(V(Y(X(d),8*d.length)));return r.toLowerCase()};function M(d){for(var _,m="0123456789ABCDEF",f="",r=0;r<d.length;r++)_=d.charCodeAt(r),f+=m.charAt(_>>>4&15)+m.charAt(15&_);return f}function X(d){for(var _=Array(d.length>>2),m=0;m<_.length;m++)_[m]=0;for(m=0;m<8*d.length;m+=8)_[m>>5]|=(255&d.charCodeAt(m/8))<<m%32;return _}function V(d){for(var _="",m=0;m<32*d.length;m+=8)_+=String.fromCharCode(d[m>>5]>>>m%32&255);return _}function Y(d,_){d[_>>5]|=128<<_%32,d[14+(_+64>>>9<<4)]=_;for(var m=1732584193,f=-271733879,r=-1732584194,i=271733878,n=0;n<d.length;n+=16){var h=m,t=f,g=r,e=i;f=md5_ii(f=md5_ii(f=md5_ii(f=md5_ii(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_ff(f=md5_ff(f=md5_ff(f=md5_ff(f,r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+0],7,-680876936),f,r,d[n+1],12,-389564586),m,f,d[n+2],17,606105819),i,m,d[n+3],22,-1044525330),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+4],7,-176418897),f,r,d[n+5],12,1200080426),m,f,d[n+6],17,-1473231341),i,m,d[n+7],22,-45705983),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+8],7,1770035416),f,r,d[n+9],12,-1958414417),m,f,d[n+10],17,-42063),i,m,d[n+11],22,-1990404162),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+12],7,1804603682),f,r,d[n+13],12,-40341101),m,f,d[n+14],17,-1502002290),i,m,d[n+15],22,1236535329),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+1],5,-165796510),f,r,d[n+6],9,-1069501632),m,f,d[n+11],14,643717713),i,m,d[n+0],20,-373897302),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+5],5,-701558691),f,r,d[n+10],9,38016083),m,f,d[n+15],14,-660478335),i,m,d[n+4],20,-405537848),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+9],5,568446438),f,r,d[n+14],9,-1019803690),m,f,d[n+3],14,-187363961),i,m,d[n+8],20,1163531501),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+13],5,-1444681467),f,r,d[n+2],9,-51403784),m,f,d[n+7],14,1735328473),i,m,d[n+12],20,-1926607734),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+5],4,-378558),f,r,d[n+8],11,-2022574463),m,f,d[n+11],16,1839030562),i,m,d[n+14],23,-35309556),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+1],4,-1530992060),f,r,d[n+4],11,1272893353),m,f,d[n+7],16,-155497632),i,m,d[n+10],23,-1094730640),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+13],4,681279174),f,r,d[n+0],11,-358537222),m,f,d[n+3],16,-722521979),i,m,d[n+6],23,76029189),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+9],4,-640364487),f,r,d[n+12],11,-421815835),m,f,d[n+15],16,530742520),i,m,d[n+2],23,-995338651),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+0],6,-198630844),f,r,d[n+7],10,1126891415),m,f,d[n+14],15,-1416354905),i,m,d[n+5],21,-57434055),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+12],6,1700485571),f,r,d[n+3],10,-1894986606),m,f,d[n+10],15,-1051523),i,m,d[n+1],21,-2054922799),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+8],6,1873313359),f,r,d[n+15],10,-30611744),m,f,d[n+6],15,-1560198380),i,m,d[n+13],21,1309151649),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+4],6,-145523070),f,r,d[n+11],10,-1120210379),m,f,d[n+2],15,718787259),i,m,d[n+9],21,-343485551),m=safe_add(m,h),f=safe_add(f,t),r=safe_add(r,g),i=safe_add(i,e)}return Array(m,f,r,i)}function md5_cmn(d,_,m,f,r,i){return safe_add(bit_rol(safe_add(safe_add(_,d),safe_add(f,i)),r),m)}function md5_ff(d,_,m,f,r,i,n){return md5_cmn(_&m|~_&f,d,_,r,i,n)}function md5_gg(d,_,m,f,r,i,n){return md5_cmn(_&f|m&~f,d,_,r,i,n)}function md5_hh(d,_,m,f,r,i,n){return md5_cmn(_^m^f,d,_,r,i,n)}function md5_ii(d,_,m,f,r,i,n){return md5_cmn(m^(_|~f),d,_,r,i,n)}function safe_add(d,_){var m=(65535&d)+(65535&_);return(d>>16)+(_>>16)+(m>>16)<<16|65535&m}function bit_rol(d,_){return d<<_|d>>>32-_}
|
||||
1
zharko/site/system/public/js/modules/damper.mjs
Symbolic link
1
zharko/site/system/public/js/modules/damper.mjs
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../../../damper.mjs/damper.mjs
|
||||
280
zharko/site/system/public/js/modules/loader.mjs
Normal file
280
zharko/site/system/public/js/modules/loader.mjs
Normal file
@@ -0,0 +1,280 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @name Loader
|
||||
*
|
||||
* @description
|
||||
* Implements actions with loading and rendering content
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
export default class loader {
|
||||
/**
|
||||
* @name Type of the program
|
||||
*/
|
||||
static type = "module";
|
||||
|
||||
/**
|
||||
* @name Actial URI
|
||||
*/
|
||||
static uri;
|
||||
|
||||
/**
|
||||
* @name Load
|
||||
*
|
||||
* @param {string} uri
|
||||
* @param {string} body
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
static async load(uri = "/", body, back = false) {
|
||||
if (typeof uri === "string") {
|
||||
// Received and validated uri
|
||||
|
||||
return await core
|
||||
.request(
|
||||
uri,
|
||||
body,
|
||||
"GET",
|
||||
{
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Accept: "application/json",
|
||||
},
|
||||
"json",
|
||||
)
|
||||
.then((json) => {
|
||||
if (json) {
|
||||
// Received a JSON-response
|
||||
|
||||
if (
|
||||
json.errors !== null &&
|
||||
typeof json.errors === "object" &&
|
||||
json.errors.length > 0
|
||||
) {
|
||||
// Fail (received errors)
|
||||
|
||||
// Exit (fail)
|
||||
reject(json);
|
||||
} else {
|
||||
// Success (not received errors)
|
||||
|
||||
if (back) {
|
||||
// Requested to go back
|
||||
|
||||
// Writing actual URI
|
||||
this.uri = history.state?.previous;
|
||||
|
||||
// Deletimg from the browser history
|
||||
history.back();
|
||||
} else {
|
||||
// Requested to go forward
|
||||
|
||||
// Writing to the browser history
|
||||
history.pushState(
|
||||
{ previous: this.uri },
|
||||
json.title ?? uri,
|
||||
uri,
|
||||
);
|
||||
|
||||
// Writing actual URI
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* The <title>
|
||||
*
|
||||
* The title of the page
|
||||
*/
|
||||
if (
|
||||
typeof json.title === "string" &&
|
||||
json.title.length > 0
|
||||
) {
|
||||
// Received text for the <title> of the page
|
||||
|
||||
// Search for the <title> element (document.title)
|
||||
const title = document.getElementsByTagName("title")[0];
|
||||
|
||||
if (title instanceof HTMLElement) {
|
||||
// Found the <title> element
|
||||
|
||||
// Writing into the <title> element
|
||||
title.innerText = json.title;
|
||||
} else {
|
||||
// Not found the <title> element
|
||||
|
||||
// Initialize the <title> element
|
||||
const title = document.createElement("title");
|
||||
|
||||
// Inititalize the <head> element (document.head)
|
||||
const head = document.getElementsByTagName("head")[0];
|
||||
|
||||
if (head instanceof HTMLElement) {
|
||||
// Found the <head> element
|
||||
|
||||
// Writing the <title> element into the <head> element
|
||||
head.appendChild(title);
|
||||
}
|
||||
|
||||
// Writing title into the <title> element
|
||||
title.innerText = json.title;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The <header> element
|
||||
*/
|
||||
if (
|
||||
typeof json.header === "string" &&
|
||||
json.header.length > 0
|
||||
) {
|
||||
// Received and validated the header HTML-code
|
||||
|
||||
if (core.header instanceof HTMLElement) {
|
||||
// Found the <header> element
|
||||
|
||||
// Writing into the <header> element
|
||||
core.header.outerHTML = json.header;
|
||||
|
||||
// Reinitializing the parameter with the <header> element
|
||||
core.header = document.getElementsByTagName("header")[0];
|
||||
} else {
|
||||
// Not found the <header> element
|
||||
|
||||
// Initialize the <header> element
|
||||
core.header = document.createElement("header");
|
||||
|
||||
// Inititalize the <body> element (document.body)
|
||||
const body = document.getElementsByTagName("body")[0];
|
||||
|
||||
if (body instanceof HTMLElement) {
|
||||
// Found the <body> element
|
||||
|
||||
if (core.main instanceof HTMLElement) {
|
||||
// Found the <main> element
|
||||
|
||||
// Writing the <header> element before the <main> element
|
||||
body.insertBefore(core.header, core.main);
|
||||
} else if (core.footer instanceof HTMLElement) {
|
||||
// Fount the <footer> element
|
||||
|
||||
// Writing the <header> element before the <footer> element
|
||||
body.insertBefore(core.header, core.footer);
|
||||
} else {
|
||||
// Not found the <main> element and the <footer> element
|
||||
|
||||
// Search for the last <section> element inside the <body> element
|
||||
const section = document.body.querySelector(
|
||||
"body > section:last-of-type",
|
||||
);
|
||||
|
||||
if (section instanceof HTMLElement) {
|
||||
// Found the last <section> element inside the <body> element
|
||||
|
||||
// Writing the <header> element after the last <section> element inside the <body> element
|
||||
body.insertBefore(
|
||||
core.header,
|
||||
section.nextElementSibling,
|
||||
);
|
||||
} else {
|
||||
// Not found section elements <section> inside the <body> element
|
||||
|
||||
// Writing the <header> element into the <body> element
|
||||
body.appendChild(core.header);
|
||||
}
|
||||
}
|
||||
|
||||
// Writing into the <header> element
|
||||
core.header.outerHTML = json.header;
|
||||
|
||||
// Reinitializing the parameter with the <header> element
|
||||
core.header = document.getElementsByTagName("header")[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The <main> element
|
||||
*
|
||||
* The main content of the page
|
||||
*/
|
||||
if (typeof json.main === "string" && json.main.length > 0) {
|
||||
// Received and validated the <main> HTML-code
|
||||
|
||||
if (core.main instanceof HTMLElement) {
|
||||
// Found the <main> element
|
||||
|
||||
// Writing into the <main> element
|
||||
core.main.outerHTML = json.main;
|
||||
|
||||
// Reinitializing the parameter with the <main> element
|
||||
core.main = document.getElementsByTagName("main")[0];
|
||||
} else {
|
||||
// Not found the <main> element
|
||||
|
||||
// Initialize the <main> element
|
||||
core.main = document.createElement("main");
|
||||
|
||||
// Inititalize the <body> element (document.body)
|
||||
const body = document.getElementsByTagName("body")[0];
|
||||
|
||||
if (body instanceof HTMLElement) {
|
||||
// Found the <body> element
|
||||
|
||||
if (core.header instanceof HTMLElement) {
|
||||
// Found the <header> element
|
||||
|
||||
// Writing the <main> element after the <header> element
|
||||
body.insertBefore(
|
||||
core.main,
|
||||
core.header.nextElementSibling,
|
||||
);
|
||||
} else if (core.footer instanceof HTMLElement) {
|
||||
// Fount the <footer> element
|
||||
|
||||
// Writing the <main> element before the <footer> element
|
||||
body.insertBefore(core.main, core.footer);
|
||||
} else {
|
||||
// Not found the <header> element and the <footer> element
|
||||
|
||||
// Search for the last <section> element inside the <body> element
|
||||
const section = document.body.querySelector(
|
||||
"body > section:last-of-type",
|
||||
);
|
||||
|
||||
if (section instanceof HTMLElement) {
|
||||
// Found the last <section> element inside the <body> element
|
||||
|
||||
// Writing the <main> element after the last <section> element inside the <body> element
|
||||
body.insertBefore(
|
||||
core.main,
|
||||
section.nextElementSibling,
|
||||
);
|
||||
} else {
|
||||
// Not found section elements <section> inside the <body> element
|
||||
|
||||
// Writing the <main> element into the <body> element
|
||||
body.appendChild(core.main);
|
||||
}
|
||||
}
|
||||
|
||||
// Writing into the <main> element
|
||||
core.main.outerHTML = json.main;
|
||||
|
||||
// Reinitializing the parameter with the <main> element
|
||||
core.main = document.getElementsByTagName("main")[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exit (success)
|
||||
return json;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Connecting to the core
|
||||
if (!core.loader) core.loader = loader;
|
||||
144
zharko/site/system/public/js/pages/account/registration.js
Normal file
144
zharko/site/system/public/js/pages/account/registration.js
Normal file
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* @name Registration
|
||||
*
|
||||
* @description
|
||||
* Account registration
|
||||
*
|
||||
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class registration {
|
||||
/**
|
||||
* @name Request (interface)
|
||||
*
|
||||
* @description
|
||||
* Send the account data for registration
|
||||
*
|
||||
* @param {string} mail Mail
|
||||
* @param {string} password Password
|
||||
* @param {bool} force Ignore the damper? (false)
|
||||
*
|
||||
* @return {bool} Did the processing complete without errors?
|
||||
*/
|
||||
static request(mail, password, force = false) {
|
||||
core.modules.connect("damper").then(
|
||||
() => {
|
||||
// Imported the damper module
|
||||
|
||||
// Processing under damper
|
||||
this.request.damper(mail, password, force);
|
||||
},
|
||||
() => {
|
||||
// Not imported the damper module
|
||||
|
||||
// Processing
|
||||
this.request.system(mail, password);
|
||||
},
|
||||
);
|
||||
|
||||
// Exit (success)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
core.modules.connect("damper").then(() => {
|
||||
// Imported the damper module
|
||||
|
||||
Object.assign(
|
||||
registration.request,
|
||||
{
|
||||
/**
|
||||
* @name Registration (damper)
|
||||
*
|
||||
* @description
|
||||
* Send the account data for registration
|
||||
*
|
||||
* @memberof registration.request
|
||||
*
|
||||
* @param {string} mail Mail
|
||||
* @param {string} password Password
|
||||
* @param {bool} [force=false] Ignore the damper?
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
damper: core.damper(
|
||||
(...variables) => registration.request.system(...variables),
|
||||
300,
|
||||
3,
|
||||
),
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Object.assign(
|
||||
registration.request,
|
||||
{
|
||||
/**
|
||||
* @name Request (system)
|
||||
*
|
||||
* @description
|
||||
* Send the account data for registration
|
||||
*
|
||||
* @param {string} mail Mail
|
||||
* @param {string} password Password
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
async system(
|
||||
mail,
|
||||
password,
|
||||
resolve = () => {},
|
||||
reject = () => {},
|
||||
) {
|
||||
try {
|
||||
// Declaring the query row
|
||||
let query = "";
|
||||
|
||||
// Generating the query row
|
||||
if (typeof mail === "string") {
|
||||
query += "&mail=" + mail;
|
||||
}
|
||||
if (typeof password === "string") {
|
||||
query += "&password=" + MD5(unescape(encodeURIComponent(password)));
|
||||
}
|
||||
|
||||
// Sending request to the server
|
||||
return await core.request(
|
||||
"/account/registration",
|
||||
query,
|
||||
"PUT",
|
||||
).then(
|
||||
(json) => {
|
||||
if (json) {
|
||||
// Received a JSON-response
|
||||
|
||||
if (
|
||||
json.errors !== null &&
|
||||
typeof json.errors === "object" &&
|
||||
json.errors.length > 0
|
||||
) {
|
||||
// Fail (received errors)
|
||||
|
||||
// Exit (fail)
|
||||
reject(json);
|
||||
} else {
|
||||
// Success (not received errors)
|
||||
|
||||
alert('Вы зарегистрировались');
|
||||
|
||||
window.location.href = '/';
|
||||
|
||||
// Exit (success)
|
||||
resolve(json);
|
||||
}
|
||||
}
|
||||
},
|
||||
() => reject(),
|
||||
);
|
||||
} catch (e) {
|
||||
// Exit (fail)
|
||||
reject(e);
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
@@ -4,8 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace zharko\site\views;
|
||||
|
||||
// Files of the project
|
||||
use zharko\site\models\enumerations\language;
|
||||
// Library for languages support
|
||||
use mirzaev\languages\language;
|
||||
|
||||
// Framework for PHP
|
||||
use mirzaev\minimal\controller;
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
{% block js %}
|
||||
{% for element in js %}
|
||||
<script {% if element.src %}src="{{ element.src }}"{% endif %} {% if element.type %}type="{{ element.type }}"{% endif %}>{{ element.innerText }}</script>
|
||||
{% endfor %}
|
||||
<script src="/js/modules/damper.mjs" type="module"></script>
|
||||
<script src="/js/core.js"></script>
|
||||
<script src="/js/modules/loader.mjs" type="module"></script>
|
||||
|
||||
{% for element in js %}
|
||||
<script
|
||||
{% if element.src %}src="{{ element.src }}"{% endif %}
|
||||
{% if element.type %}type="{{ element.type }}"{% endif %}>
|
||||
{{ element.innerText }}
|
||||
</script>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{% extends "/themes/default/index.html" %}
|
||||
|
||||
{% block css %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block main %}
|
||||
<section id="registration">
|
||||
<div>
|
||||
<label for="registration_mail">{{ language == 'ru' ? 'Почта' : 'Mail' }}</label>
|
||||
<input id="registration_mail" type="mail" required/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="registration_password">{{ language == 'ru' ? 'Пароль' : 'Password' }}</label>
|
||||
<input id="registration_password" type="password" required/>
|
||||
</div>
|
||||
<button id="registration_send" onclick="registration.request(...[...document.querySelectorAll('main #registration :is(input:not([type=\'radio\']), input[type=\'radio\']:checked, textarea)')]?.map(element => element.value))">{{ language == 'ru' ? 'Зарегистрироваться' : 'Register' }}</button>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<script src="/js/pages/account/registration.js"></script>
|
||||
<script src="/js/libraries/md5.js"></script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user