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

219 lines
5.8 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace mirzaev\arming_bot\models;
// Files of the project
use mirzaev\arming_bot\models\core;
// Framework for ArangoDB
use mirzaev\arangodb\collection,
mirzaev\arangodb\document;
// Library для ArangoDB
use ArangoDBClient\Document as _document;
// Built-in libraries
use exception;
/**
* Model of a product
*
* @package mirzaev\arming_bot\models
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class product extends core
{
/**
* Name of the collection in ArangoDB
*/
final public const string COLLECTION = 'product';
/**
* Чтение товаров
*
* @param string|null $search Поиск
* @param string|null $filter Фильтр
* @param string|null $sort Сортировка
* @param int $page Страница
* @param int $amount Количество товаров на странице
* @param string|null $return
* @param array &$errors Registry of errors
*
* @return array Массив с найденными товарами (может быть пустым)
*/
public static function read(
?string $search = null,
?string $filter = 'd.deleted != true && d.hidden != true',
?string $sort = 'd.promotion DESC, d.position ASC, d.created DESC',
int $page = 1,
int $amount = 100,
?string $return = 'd',
array &$errors = []
): array {
try {
if (collection::init(core::$arangodb->session, self::COLLECTION)) {
// Инициализирована коллекция
// Инициализация строки запроса
$aql = sprintf(
<<<AQL
FOR d IN %s
AQL,
$search ? self::COLLECTION . 's_search' : self::COLLECTION
);
if ($search) {
// Search
$aql .= sprintf(
<<<AQL
SEARCH
LEVENSHTEIN_MATCH(
d.title.ru,
TOKENS("%s", "text_ru")[0],
1,
false
) OR
levenshtein_match(
d.description.ru,
tokens("%s", "text_ru")[0],
1,
false
) OR
levenshtein_match(
d.compatibility.ru,
tokens("%s", "text_ru")[0],
1,
false
)
AQL,
$search,
$search,
$search
);
// Adding sorting
if ($sort) $sort = "BM25(d) DESC, $sort";
else $sort = "BM25(d) DESC";
}
if ($documents = collection::search(
core::$arangodb->session,
sprintf(
$aql . <<<AQL
%s
%s
LIMIT %u, %u
RETURN %s
AQL,
empty($filter) ? '' : "FILTER $filter",
empty($sort) ? '' : "SORT $sort",
--$page <= 0 ? $page = 0 : $page * $amount,
$amount,
empty($return) ? 'd' : $return
)
)) {
// Найдены товары
// Возврат (успех)
return is_array($documents) ? $documents : [$documents];
} else return [];
} else throw new exception('Failed to initialize document collection: ' . self::COLLECTION);
} catch (exception $e) {
// Write to the registry of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
// Выход (провал)
return [];
}
/**
* Запись товара
*
* @param string $title Заголовок
* @param string|null $description Описание
* @param float $cost Цена
* @param float $weight Вес
* @param array $dimensions Габариты (float)
* @param array $images Изображения (первое - обложка) (https, путь в storage, иначе будет поиск в storage)
* @param array $hierarchy Иерархия вложенности (от родителей к потомкам: [ model, model ... ])
* @param array $data Дополнительные данные
* @param array &$errors Registry of errors
*
* @return string|null Идентификатор (_id) документа (товара), если создан
*/
public static function write(
string $title,
?string $description = null,
float $cost = 0,
float $weight = 0,
array $dimensions = ['x' => 0, 'y' => 0, 'z' => 0],
array $images = [],
array $hierarchy = [],
array $data = [],
array &$errors = []
): string|null {
try {
if (collection::init(core::$arangodb->session, self::COLLECTION)) {
// Инициализирована коллекция
// Создание товара
$product = document::write(
core::$arangodb->session,
self::COLLECTION,
[
'title' => $title,
'description' => $description,
'cost' => $cost ?? 0,
'weight' => $weight ?? 0,
'dimensions' => [
'x' => $dimensions['x'] ?? 0,
'y' => $dimensions['y'] ?? 0,
'z' => $dimensions['z'] ?? 0,
],
'images' => $images,
'version' => ROBOT_VERSION
] + $data
);
if ($product) {
// Создан товар
if (collection::init(core::$arangodb->session, 'entry', true)) {
// Инициализирована коллекция
foreach ($hierarchy as $model) {
// Перебор иерархической структуры категорий
// Инициализация вложенной категории (следующей в массиве)
$next = current($hierarchy);
// Поиск ребра описывающего иерархическую связь
document::write(core::$arangodb->session, 'entry');
}
} else throw new exception('Failed to initialize document collection: ' . self::COLLECTION);
}
} else throw new exception('Failed to initialize document collection: entry');
} catch (exception $e) {
// Write to the registry of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
// Выход (провал)
return null;
}
}