436 lines
12 KiB
PHP
Executable File
436 lines
12 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace mirzaev\arming_bot\controllers;
|
|
|
|
// Files of the project
|
|
use mirzaev\arming_bot\controllers\core,
|
|
mirzaev\arming_bot\models\enumerations\language,
|
|
mirzaev\arming_bot\models\entry,
|
|
mirzaev\arming_bot\models\category,
|
|
mirzaev\arming_bot\models\product,
|
|
mirzaev\arming_bot\models\menu;
|
|
|
|
// Library for ArangoDB
|
|
use ArangoDBClient\Document as _document;
|
|
|
|
/**
|
|
* Controller of catalog
|
|
*
|
|
* @package mirzaev\arming_bot\controllers
|
|
*
|
|
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
|
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
|
*/
|
|
final class catalog extends core
|
|
{
|
|
/**
|
|
* Registry of errors
|
|
*/
|
|
protected array $errors = [
|
|
'session' => [],
|
|
'account' => [],
|
|
'menu' => [],
|
|
'catalog' => []
|
|
];
|
|
|
|
/**
|
|
* Catalog
|
|
*
|
|
* @param array $parameters Parameters of the request (POST + GET)
|
|
*/
|
|
public function index(array $parameters = []): ?string
|
|
{
|
|
// validating
|
|
if (isset($parameters['product']) && preg_match('/[\d]+/', $parameters['product'], $matches)) $product = (int) $matches[0];
|
|
|
|
if (isset($product)) {
|
|
// Received and validated identifier of the product
|
|
|
|
// Search for the product data and write to the buffer of global variables of view templater
|
|
$this->view->product = product::read(
|
|
filter: "d.identifier == @identifier && d.deleted != true && d.hidden != true",
|
|
sort: 'd.created DESC',
|
|
amount: 1,
|
|
return: '{identifier: d.identifier, name: d.name.@language, description: d.description.@language, cost: d.cost.@currency, weight: d.weight, dimensions: d.dimensions, brand: d.brand.@language, compatibility: d.compatibility.@language, cost: d.cost.@currency, images: d.images[*].storage}',
|
|
language: $this->language,
|
|
currency: $this->currency,
|
|
parameters: ['identifier' => $product],
|
|
errors: $this->errors['catalog']
|
|
)?->getAll();
|
|
}
|
|
|
|
// Intializing buffer of query parameters
|
|
$_parameters = [];
|
|
|
|
// Initializing buffer of filters query (AQL)
|
|
$_filters = 'd.deleted != true && d.hidden != true';
|
|
|
|
// Validating
|
|
if (isset($parameters['brand']) && preg_match('/[\w\s]+/u', urldecode($parameters['brand']), $matches)) $brand = $matches[0];
|
|
|
|
if (isset($brand)) {
|
|
// Received and validated filter by brand
|
|
|
|
// Writing to the account buffer
|
|
$this->account?->write(
|
|
[
|
|
'catalog' => [
|
|
'filters' => [
|
|
'brand' => $brand
|
|
]
|
|
]
|
|
]
|
|
);
|
|
|
|
// Writing to the session buffer
|
|
$this->session?->write(
|
|
[
|
|
'catalog' => [
|
|
'filters' => [
|
|
'brand' => $brand
|
|
]
|
|
]
|
|
]
|
|
);
|
|
|
|
// Writing to the buffer of filters query (AQL)
|
|
$_filters .= ' && d.brand.@language == @brand';
|
|
|
|
// Writing to the buffer of query parameters
|
|
$_parameters['brand'] = $brand;
|
|
} else {
|
|
// Not received or not validated filter by brand
|
|
|
|
// Writing to the account buffer
|
|
$this->account?->write(
|
|
[
|
|
'catalog' => [
|
|
'filters' => [
|
|
'brand' => null
|
|
]
|
|
]
|
|
]
|
|
);
|
|
|
|
// Writing to the session buffer
|
|
$this->session?->write(
|
|
[
|
|
'catalog' => [
|
|
'filters' => [
|
|
'brand' => null
|
|
]
|
|
]
|
|
]
|
|
);
|
|
}
|
|
|
|
// Initialize buffer of filters query (AQL)
|
|
$_sort = 'd.position ASC, d.name ASC, d.created DESC';
|
|
|
|
// Validating
|
|
if (isset($parameters['sort']) && preg_match('/[\w\s]+/u', $parameters['sort'], $matches)) $sort = $matches[0];
|
|
|
|
if (isset($sort)) {
|
|
// Received and validated sort
|
|
|
|
// Writing to the account buffer
|
|
$this->account?->write(
|
|
[
|
|
'catalog' => [
|
|
'sort' => $sort
|
|
]
|
|
]
|
|
);
|
|
|
|
// Writing to the session buffer
|
|
$this->session?->write(
|
|
[
|
|
'catalog' => [
|
|
'sort' => $sort
|
|
]
|
|
]
|
|
);
|
|
|
|
// Write to the buffer of sort query (AQL)
|
|
$_sort = "d.@sort DESC, $_sort";
|
|
|
|
// Write to the buffer of query parameters
|
|
$_parameters['sort'] = $sort;
|
|
} else {
|
|
// Not received or not validated filter by brand
|
|
|
|
// Writing to the account buffer
|
|
$this->account?->write(
|
|
[
|
|
'catalog' => [
|
|
'sort' => null
|
|
]
|
|
]
|
|
);
|
|
|
|
// Writing to the session buffer
|
|
$this->session?->write(
|
|
[
|
|
'catalog' => [
|
|
'sort' => null
|
|
]
|
|
]
|
|
);
|
|
}
|
|
|
|
// Validating @todo add throwing errors
|
|
if (isset($parameters['text']) && preg_match('/[\w\s]+/u', urldecode($parameters['text']), $matches) && mb_strlen($matches[0]) > 2) $text = $matches[0];
|
|
|
|
if (isset($text)) {
|
|
// Received and validated text
|
|
|
|
// Writing to the account buffer (useless becouse rewrite itself to null with every request)
|
|
$this->account?->write(
|
|
[
|
|
'catalog' => [
|
|
'search' => [
|
|
'text' => $text
|
|
]
|
|
]
|
|
]
|
|
);
|
|
|
|
// Writing to the session buffer (useless becouse rewrite itself to null with every request)
|
|
$this->session?->write(
|
|
[
|
|
'catalog' => [
|
|
'search' => [
|
|
'text' => $text
|
|
]
|
|
]
|
|
]
|
|
);
|
|
} else {
|
|
// Not received or not validated filter by brand
|
|
|
|
// Writing to the account buffer
|
|
$this->account?->write(
|
|
[
|
|
'catalog' => [
|
|
'search' => [
|
|
'text' => null
|
|
]
|
|
]
|
|
]
|
|
);
|
|
|
|
// Writing to the session buffer
|
|
$this->session?->write(
|
|
[
|
|
'catalog' => [
|
|
'search' => [
|
|
'text' => null
|
|
]
|
|
]
|
|
]
|
|
);
|
|
}
|
|
|
|
// Validating
|
|
if (isset($parameters['category']) && preg_match('/[\d]+/', $parameters['category'], $matches)) $category = (int) $matches[0];
|
|
|
|
if (isset($category)) {
|
|
// Received and validated identifier of the category
|
|
|
|
// Initialize of category
|
|
$category = category::_read('d.identifier == @identifier', parameters: ['identifier' => $category], errors: $this->errors['catalog']);
|
|
|
|
if ($category instanceof category) {
|
|
// Found the category
|
|
|
|
// Write to the response buffer
|
|
$response['category'] = ['name' => $category->name ?? null];
|
|
|
|
// Search for categories that are descendants of $category
|
|
$entries = entry::search(
|
|
document: $category,
|
|
amount: 50,
|
|
categories_merge: 'name: v.name.@language',
|
|
/* products_merge: 'DISTINCT MERGE(d, {name: d.name.@language, description: d.description.@language, compatibility: d.compatibility.@language, brand: d.brand.@language, cost: d.cost.@currency})', */
|
|
parameters: ['language' => $this->language->name],
|
|
errors: $this->errors['catalog']
|
|
);
|
|
|
|
// Initialize buffers of entries (in singular, by parameter from ArangoDB)
|
|
$category = $product = [];
|
|
|
|
foreach ($entries as $entry) {
|
|
// Iterate over entries (descendands)
|
|
|
|
// Write entry to the buffer of entries (sort by $category and $product)
|
|
${$entry->_type}[] = $entry;
|
|
}
|
|
|
|
// Write to the buffer of global variables of view templater
|
|
$this->view->categories = $category;
|
|
|
|
// Write to the buffer of global variables of view templater
|
|
$this->view->products = $product;
|
|
|
|
if (isset($this->view->products) && count($this->view->products) > 0) {
|
|
// Amount of rendered products is more than 0
|
|
|
|
// Write to the buffer of filters query (AQL)
|
|
$_filters .= ' && POSITION(["' . implode('", "', array_map(fn(_document $document): string => $document->getId(), $this->view->products)) . '"], d._id)';
|
|
}
|
|
|
|
// Deleting buffers
|
|
unset($category, $product);
|
|
}
|
|
} else if (!isset($parameters['category'])) {
|
|
// Not received identifier of the category
|
|
|
|
// search for root ascendants categories
|
|
$this->view->categories = entry::ascendants(
|
|
descendant: new category,
|
|
return: 'DISTINCT MERGE(ascendant, { name: ascendant.name.@language})',
|
|
parameters: ['language' => $this->language->name],
|
|
errors: $this->errors['catalog']
|
|
) ?? null;
|
|
}
|
|
|
|
if (isset($brand) || isset($text) || (isset($this->view->products) && count($this->view->products) > 0)) {
|
|
// Received and validated at least one of filters or amount of rendered products is more than 0
|
|
|
|
// Search for filters and write to the buffer of global variables of view templater
|
|
$this->view->filters = [
|
|
'brands' => product::collect(
|
|
return: 'd.brand.@language',
|
|
products: array_map(fn(_document $document): string => $document->getId(), $this->view->products ?? []),
|
|
language: $this->language,
|
|
errors: $this->errors['catalog']
|
|
)
|
|
];
|
|
}
|
|
|
|
// Search among products in the $category
|
|
if (isset($text) || isset($this->view->products) && count($this->view->products) > 0) {
|
|
// Amount of rendered products is more than 0
|
|
|
|
// Search for products and write to the buffer of global variables of view templater
|
|
$this->view->products = product::read(
|
|
search: $text ?? null,
|
|
filter: $_filters,
|
|
sort: $_sort,
|
|
amount: 50, // @todo pagination
|
|
return: 'DISTINCT MERGE(d, {name: d.name.@language, description: d.description.@language, compatibility: d.compatibility.@language, brand: d.brand.@language, cost: d.cost.@currency})',
|
|
language: $this->language,
|
|
currency: $this->currency,
|
|
parameters: $_parameters,
|
|
errors: $this->errors['catalog']
|
|
);
|
|
}
|
|
|
|
if (isset($menu)) {
|
|
//
|
|
|
|
} else {
|
|
// Not received ... menu
|
|
|
|
// Search for filters and write to the buffer of global variables of view templater
|
|
$this->view->menu = menu::_read(
|
|
return: 'MERGE(d, { name: d.name.@language })',
|
|
sort: 'd.style.order ASC, d.created DESC, d._key DESC',
|
|
amount: 4,
|
|
parameters: ['language' => $this->language->name],
|
|
errors: $this->errors['menu']
|
|
);
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
|
// GET request
|
|
|
|
if (!empty($this->view->product)) {
|
|
// Initialized the product data
|
|
|
|
// Writing javascript code that has been executed after core and damper has been loaded
|
|
$this->view->javascript = [
|
|
sprintf(
|
|
<<<javascript
|
|
if (typeof _window === 'undefined') {
|
|
_window = setTimeout(() => core.catalog.product.system('%s'), 500);
|
|
}
|
|
javascript,
|
|
$this->view->product['identifier']
|
|
)
|
|
] + ($this->view->javascript ?? []);
|
|
}
|
|
|
|
// Exit (success)
|
|
return $this->view->render('catalog/page.html', [
|
|
'h2' => $this->language === language::ru ? 'Каталог' : 'Catalog' // @see https://git.mirzaev.sexy/mirzaev/huesos/issues/1
|
|
]);
|
|
} else if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
// POST request
|
|
|
|
// Initializing the buffer of response
|
|
$response = [
|
|
'title' => $this->language === language::ru ? 'Каталог' : 'Catalog' // @see https://git.mirzaev.sexy/mirzaev/huesos/issues/1
|
|
];
|
|
|
|
if (isset($this->view->categories)) {
|
|
// Initialized categories
|
|
|
|
// Render HTML-code of categories and write to the response buffer
|
|
$response['categories'] = $this->view->render('catalog/elements/categories.html');
|
|
}
|
|
|
|
if (isset($this->view->product)) {
|
|
// Initialized product
|
|
|
|
// Writing data of the product to the response buffer @todo GENERATE THIS ON THE SERVER
|
|
$response['product'] = $this->view->product;
|
|
}
|
|
|
|
if (isset($this->view->products)) {
|
|
// Initialized products
|
|
|
|
// Render HTML-code of products and write to the response buffer
|
|
$response['products'] = $this->view->render('catalog/elements/products.html');
|
|
}
|
|
|
|
if (isset($this->view->filters)) {
|
|
// Initialized filters
|
|
|
|
// Render HTML-code of filters and write to the response buffer
|
|
$response['filters'] = $this->view->render('catalog/elements/filters.html');
|
|
}
|
|
|
|
// Initializing a response headers
|
|
header('Content-Type: application/json');
|
|
header('Content-Encoding: none');
|
|
header('X-Accel-Buffering: no');
|
|
|
|
// Initializing of the output buffer
|
|
ob_start();
|
|
|
|
// Generating the reponse
|
|
echo json_encode(
|
|
$response + [
|
|
'errors' => $this->errors
|
|
]
|
|
);
|
|
|
|
// Initializing a response headers
|
|
header('Content-Length: ' . ob_get_length());
|
|
|
|
// Sending and deinitializing of the output buffer
|
|
ob_end_flush();
|
|
flush();
|
|
|
|
// Exit (success)
|
|
return null;
|
|
}
|
|
|
|
// Exit (fail)
|
|
return null;
|
|
}
|
|
}
|