huesos/mirzaev/arming_bot/system/models/core.php

258 lines
6.1 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace mirzaev\arming_bot\models;
// Framework for PHP
use mirzaev\minimal\model;
// Framework for ArangoDB
use mirzaev\arangodb\connection as arangodb,
mirzaev\arangodb\collection,
mirzaev\arangodb\enumerations\collection\type;
// Libraries for ArangoDB
use ArangoDBClient\Document as _document;
// Built-in libraries
use exception;
/**
* Core of models
*
* @package mirzaev\arming_bot\models
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
class core extends model
{
/**
* Postfix for name of models files
*/
final public const string POSTFIX = '';
/**
* Path to the file with settings of connecting to the ArangoDB
*/
final public const string ARANGODB = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'settings' . DIRECTORY_SEPARATOR . 'arangodb.php';
/**
* Instance of the session of ArangoDB
*/
protected static arangodb $arangodb;
/**
* Name of the collection in ArangoDB
*/
public const string COLLECTION = 'THIS_COLLECTION_SHOULD_NOT_EXIST';
/**
* Type of the collection in ArangoDB
*/
public const type TYPE = type::document;
/**
* Constructor of an instance
*
* @param bool $initialize Initialize a model?
* @param ?arangodb $arangodb Instance of a session of ArangoDB
*
* @return void
*/
public function __construct(bool $initialize = true, ?arangodb $arangodb = null)
{
// For the extends system
parent::__construct($initialize);
if ($initialize) {
// Initializing is requested
if (isset($arangodb)) {
// Recieved an instance of a session of ArangoDB
// Writing an instance of a session of ArangoDB to the property
$this->__set('arangodb', $arangodb);
} else {
// Not recieved an instance of a session of ArangoDB
// Initializing of an instance of a session of ArangoDB
$this->__get('arangodb');
}
}
}
/**
* Read document from ArangoDB
*
* @param string $filter Expression for filtering (AQL)
* @param string $sort Expression for sorting (AQL)
* @param int $amount Amount of documents for collect
* @param int $page Page
* @param string $return Expression describing the parameters to return (AQL)
* @param array $parameters Binded parameters for placeholders ['placeholder' => parameter]
* @param array &$errors Registry of errors
*
* @return mixed An array of instances of documents from ArangoDB, if they are found
*/
public static function _read(
string $filter = '',
string $sort = 'd.created DESC, d._key DESC',
int $amount = 1,
int $page = 1,
string $return = 'd',
array $parameters = [],
array &$errors = []
): _document|array|null {
try {
if (collection::initialize(static::COLLECTION, static::TYPE)) {
// Initialized the collection
// Read from ArangoDB
$result = collection::execute(
sprintf(
<<<'AQL'
FOR d IN @@collection
%s
%s
LIMIT @offset, @amount
RETURN @return
AQL,
empty($filter) ? '' : "FILTER $filter",
empty($sort) ? '' : "SORT $sort",
),
[
'@collection' => static::COLLECTION,
'offset' => --$page <= 0 ? 0 : $page * $amount,
'amount' => $amount,
'return' => $return
] + $parameters,
errors: $errors
);
// Exit (success)
return is_array($result) ? $result : [$result];
} else throw new exception('Failed to initialize ' . static::TYPE . ' collection: ' . static::COLLECTION);
} catch (exception $e) {
// Writing to registry of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
// Exit (fail)
return null;
}
/**
* Write
*
* @param string $name Name of the property
* @param mixed $value Value of the property
*
* @return void
*/
public function __set(string $name, mixed $value = null): void
{
match ($name) {
'arangodb' => (function () use ($value) {
if ($this->__isset('arangodb')) {
// Is alredy initialized
// Exit (fail)
throw new exception('Forbidden to reinitialize the session of ArangoDB ($this::$arangodb)', 500);
} else {
// Is not already initialized
if ($value instanceof arangodb) {
// Recieved an appropriate value
// Writing the property and exit (success)
self::$arangodb = $value;
} else {
// Recieved an inappropriate value
// Exit (fail)
throw new exception('Session of ArangoDB ($this::$arangodb) is need to be mirzaev\arangodb\connection', 500);
}
}
})(),
default => parent::__set($name, $value)
};
}
/**
* Read
*
* @param string $name Name of the property
*
* @return mixed Content of the property, if they are found
*/
public function __get(string $name): mixed
{
return match ($name) {
'arangodb' => (function () {
try {
if (!$this->__isset('arangodb')) {
// Is not initialized
// Initializing of a default value from settings
$this->__set('arangodb', new arangodb(require static::ARANGODB));
}
// Exit (success)
return self::$arangodb;
} catch (exception) {
// Exit (fail)
return null;
}
})(),
default => parent::__get($name)
};
}
/**
* Delete
*
* @param string $name Name of the property
*
* @return void
*/
public function __unset(string $name): void
{
// Deleting a property and exit (success)
parent::__unset($name);
}
/**
* Check of initialization
*
* @param string $name Name of the property
*
* @return bool The property is initialized?
*/
public function __isset(string $name): bool
{
// Check of initialization of the property and exit (success)
return parent::__isset($name);
}
/**
* Call a static property or method
*
* @param string $name Name of the property or the method
* @param array $arguments Arguments for the method
*/
public static function __callStatic(string $name, array $arguments): mixed
{
return match ($name) {
'arangodb' => (new static)->__get('arangodb'),
default => throw new exception("Not found: $name", 500)
};
}
}