feat: added new products_carousel bock type
This commit is contained in:
@@ -4,6 +4,8 @@ use Bastion\ApplicationFactory;
|
||||
use Cart\User;
|
||||
use Openguru\OpenCartFramework\Application;
|
||||
use Openguru\OpenCartFramework\Http\Response as HttpResponse;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageTool;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
||||
use Openguru\OpenCartFramework\Logger\LoggerInterface;
|
||||
use Openguru\OpenCartFramework\Logger\OpenCartLogAdapter;
|
||||
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
||||
@@ -127,11 +129,12 @@ class ControllerExtensionModuleTgshop extends Controller
|
||||
->createApplication()
|
||||
->bootAndHandleRequest();
|
||||
} catch (Exception $e) {
|
||||
$this->log->write('[TELECART] Error: ' . $e->getMessage());
|
||||
$logger = new OpenCartLogAdapter($this->log, 'TeleCart');
|
||||
$logger->logException($e);
|
||||
http_response_code(HttpResponse::HTTP_INTERNAL_SERVER_ERROR);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'error' => 'Ошибка сервера. Приносим свои извинения за неудобства.',
|
||||
'error' => 'Server Error.',
|
||||
], JSON_THROW_ON_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -272,6 +275,7 @@ class ControllerExtensionModuleTgshop extends Controller
|
||||
|
||||
$app = ApplicationFactory::create($items);
|
||||
$app->bind(OcRegistryDecorator::class, fn() => new OcRegistryDecorator($this->registry));
|
||||
$app->bind(ImageToolInterface::class, fn() => new ImageTool(DIR_IMAGE, HTTPS_SERVER));
|
||||
|
||||
$app
|
||||
->withLogger(fn() => new OpenCartLogAdapter(
|
||||
|
||||
@@ -2,18 +2,51 @@
|
||||
|
||||
namespace Bastion\Handlers;
|
||||
|
||||
use App\Services\SettingsService;
|
||||
use Openguru\OpenCartFramework\Http\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\OpenCart\Decorators\OcRegistryDecorator;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||
use Openguru\OpenCartFramework\Support\Str;
|
||||
|
||||
class AutocompleteHandler
|
||||
{
|
||||
private OcRegistryDecorator $registry;
|
||||
private Builder $queryBuilder;
|
||||
private SettingsService $settings;
|
||||
|
||||
public function __construct(OcRegistryDecorator $registry)
|
||||
{
|
||||
public function __construct(
|
||||
OcRegistryDecorator $registry,
|
||||
Builder $queryBuilder,
|
||||
SettingsService $settings
|
||||
) {
|
||||
$this->registry = $registry;
|
||||
$this->queryBuilder = $queryBuilder;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function getCategoriesFlat(): JsonResponse
|
||||
{
|
||||
$languageId = $this->settings->config()->getApp()->getLanguageId();
|
||||
$categoriesFlat = $this->getFlatCategories($languageId);
|
||||
|
||||
return new JsonResponse([
|
||||
'data' => $categoriesFlat,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getCategories(): JsonResponse
|
||||
{
|
||||
$languageId = $this->settings->config()->getApp()->getLanguageId();
|
||||
|
||||
$categoriesFlat = $this->getFlatCategories($languageId);
|
||||
|
||||
$categories = $this->buildCategoryTree($categoriesFlat);
|
||||
|
||||
return new JsonResponse([
|
||||
'data' => $categories,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getProductsById(Request $request): JsonResponse
|
||||
@@ -61,4 +94,53 @@ class AutocompleteHandler
|
||||
'data' => $items,
|
||||
]);
|
||||
}
|
||||
|
||||
private function getFlatCategories(int $languageId): array
|
||||
{
|
||||
return $this->queryBuilder->newQuery()
|
||||
->select([
|
||||
'categories.category_id' => 'id',
|
||||
'categories.parent_id' => 'parent_id',
|
||||
'descriptions.name' => 'name',
|
||||
'descriptions.description' => 'description',
|
||||
])
|
||||
->from(db_table('category'), 'categories')
|
||||
->join(
|
||||
db_table('category_description') . ' AS descriptions',
|
||||
function (JoinClause $join) use ($languageId) {
|
||||
$join->on('categories.category_id', '=', 'descriptions.category_id')
|
||||
->where('descriptions.language_id', '=', $languageId);
|
||||
}
|
||||
)
|
||||
->where('categories.status', '=', 1)
|
||||
->orderBy('parent_id')
|
||||
->orderBy('sort_order')
|
||||
->get();
|
||||
}
|
||||
|
||||
private function buildCategoryTree(array $flat, $parentId = 0): array
|
||||
{
|
||||
$branch = [];
|
||||
|
||||
foreach ($flat as $category) {
|
||||
if ((int) $category['parent_id'] === (int) $parentId) {
|
||||
$children = $this->buildCategoryTree($flat, $category['id']);
|
||||
if ($children) {
|
||||
$category['children'] = $children;
|
||||
}
|
||||
|
||||
$branch[] = [
|
||||
'key' => (int) $category['id'],
|
||||
'label' => Str::htmlEntityEncode($category['name']),
|
||||
'data' => [
|
||||
'description' => Str::htmlEntityEncode($category['description']),
|
||||
],
|
||||
'icon' => null,
|
||||
'children' => $category['children'] ?? [],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $branch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Bastion\Handlers;
|
||||
|
||||
use App\Services\SettingsService;
|
||||
use Openguru\OpenCartFramework\Http\JsonResponse;
|
||||
use Openguru\OpenCartFramework\Http\Request;
|
||||
use Openguru\OpenCartFramework\ImageTool\ImageToolInterface;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\Builder;
|
||||
use Openguru\OpenCartFramework\QueryBuilder\JoinClause;
|
||||
|
||||
class DictionariesHandler
|
||||
{
|
||||
private Builder $queryBuilder;
|
||||
private ImageToolInterface $ocImageTool;
|
||||
private SettingsService $settings;
|
||||
|
||||
public function __construct(Builder $queryBuilder, ImageToolInterface $ocImageTool, SettingsService $settings)
|
||||
{
|
||||
$this->queryBuilder = $queryBuilder;
|
||||
$this->ocImageTool = $ocImageTool;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function getCategories(Request $request): JsonResponse
|
||||
{
|
||||
$perPage = $request->get('perPage', 20);
|
||||
$categoryIds = $request->json('category_ids', []);
|
||||
$languageId = $this->settings->config()->getApp()->getLanguageId();
|
||||
|
||||
$data = $this->queryBuilder->newQuery()
|
||||
->select([
|
||||
'categories.category_id' => 'id',
|
||||
'categories.parent_id' => 'parent_id',
|
||||
'categories.image' => 'image',
|
||||
'descriptions.name' => 'name',
|
||||
'descriptions.description' => 'description',
|
||||
])
|
||||
->from(db_table('category'), 'categories')
|
||||
->join(
|
||||
db_table('category_description') . ' AS descriptions',
|
||||
function (JoinClause $join) use ($languageId) {
|
||||
$join->on('categories.category_id', '=', 'descriptions.category_id')
|
||||
->where('descriptions.language_id', '=', $languageId);
|
||||
}
|
||||
)
|
||||
->where('categories.status', '=', 1)
|
||||
->when($categoryIds, function (Builder $query) use ($categoryIds) {
|
||||
$query->whereIn('categories.category_id', $categoryIds);
|
||||
})
|
||||
->orderBy('parent_id')
|
||||
->orderBy('sort_order')
|
||||
->limit($perPage)
|
||||
->get();
|
||||
|
||||
return new JsonResponse(compact('data'));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Bastion\Handlers\AutocompleteHandler;
|
||||
use Bastion\Handlers\DictionariesHandler;
|
||||
use Bastion\Handlers\SettingsHandler;
|
||||
use Bastion\Handlers\StatsHandler;
|
||||
use Bastion\Handlers\TelegramHandler;
|
||||
@@ -15,4 +16,9 @@ return [
|
||||
'getCategoriesById' => [AutocompleteHandler::class, 'getCategoriesById'],
|
||||
'getDashboardStats' => [StatsHandler::class, 'getDashboardStats'],
|
||||
'tgGetMe' => [TelegramHandler::class, 'tgGetMe'],
|
||||
|
||||
'getCategories' => [DictionariesHandler::class, 'getCategories'],
|
||||
|
||||
'getAutocompleteCategories' => [AutocompleteHandler::class, 'getCategories'],
|
||||
'getAutocompleteCategoriesFlat' => [AutocompleteHandler::class, 'getCategoriesFlat'],
|
||||
];
|
||||
|
||||
@@ -61,7 +61,7 @@ class CategoriesHandler
|
||||
return new JsonResponse([
|
||||
'data' => array_map(static function ($category) {
|
||||
return [
|
||||
'id' => (int)$category['id'],
|
||||
'id' => (int) $category['id'],
|
||||
'image' => $category['image'] ?? '',
|
||||
'name' => Utils::htmlEntityEncode($category['name']),
|
||||
'description' => $category['description'],
|
||||
@@ -71,20 +71,26 @@ class CategoriesHandler
|
||||
]);
|
||||
}
|
||||
|
||||
public function buildCategoryTree(array $flat, $parentId = 0): array {
|
||||
public function buildCategoryTree(array $flat, $parentId = 0): array
|
||||
{
|
||||
$branch = [];
|
||||
|
||||
foreach ($flat as $category) {
|
||||
if ((int)$category['parent_id'] === (int)$parentId) {
|
||||
if ((int) $category['parent_id'] === (int) $parentId) {
|
||||
$children = $this->buildCategoryTree($flat, $category['id']);
|
||||
if ($children) {
|
||||
$category['children'] = $children;
|
||||
}
|
||||
|
||||
$image = $this->ocImageTool->resize($category['image'] ?? '', self::THUMB_SIZE, self::THUMB_SIZE, 'no_image.png');
|
||||
$image = $this->ocImageTool->resize(
|
||||
$category['image'] ?? '',
|
||||
self::THUMB_SIZE,
|
||||
self::THUMB_SIZE,
|
||||
'no_image.png'
|
||||
);
|
||||
|
||||
$branch[] = [
|
||||
'id' => (int)$category['id'],
|
||||
'id' => (int) $category['id'],
|
||||
'image' => $image,
|
||||
'name' => Utils::htmlEntityEncode($category['name']),
|
||||
'description' => $category['description'],
|
||||
|
||||
@@ -15,6 +15,7 @@ class BlocksService
|
||||
'slider' => [self::class, 'processSlider'],
|
||||
'categories_top' => [self::class, 'processCategoriesTop'],
|
||||
'products_feed' => [self::class, 'processProductsFeed'],
|
||||
'products_carousel' => [self::class, 'processProductsCarousel'],
|
||||
];
|
||||
|
||||
private LoggerInterface $logger;
|
||||
@@ -22,25 +23,28 @@ class BlocksService
|
||||
private CacheInterface $cache;
|
||||
private SettingsService $settings;
|
||||
private Builder $queryBuilder;
|
||||
private ProductsService $productsService;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
ImageToolInterface $imageTool,
|
||||
CacheInterface $cache,
|
||||
SettingsService $settings,
|
||||
Builder $queryBuilder
|
||||
Builder $queryBuilder,
|
||||
ProductsService $productsService
|
||||
) {
|
||||
$this->logger = $logger;
|
||||
$this->imageTool = $imageTool;
|
||||
$this->cache = $cache;
|
||||
$this->settings = $settings;
|
||||
$this->queryBuilder = $queryBuilder;
|
||||
$this->productsService = $productsService;
|
||||
}
|
||||
|
||||
public function process(array $block): array
|
||||
{
|
||||
$blockType = $block['type'];
|
||||
$cacheKey = "block_$blockType";
|
||||
$cacheKey = "block_{$blockType}_" . md5(serialize($block['data']));
|
||||
$cacheTtlSeconds = 60;
|
||||
|
||||
$data = $this->cache->get($cacheKey);
|
||||
@@ -118,4 +122,36 @@ class BlocksService
|
||||
{
|
||||
return $block;
|
||||
}
|
||||
|
||||
private function processProductsCarousel(array $block): array
|
||||
{
|
||||
$categoryId = $block['data']['category_id'];
|
||||
$languageId = $this->settings->config()->getApp()->getLanguageId();
|
||||
$params = [
|
||||
'page' => 1,
|
||||
'perPage' => 10,
|
||||
'filters' => [
|
||||
"operand" => "AND",
|
||||
"rules" => [
|
||||
"RULE_PRODUCT_CATEGORIES" => [
|
||||
"criteria" => [
|
||||
"product_category_ids" => [
|
||||
"type" => "product_categories",
|
||||
"params" => [
|
||||
"operator" => "contains",
|
||||
"value" => [$categoryId],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$response = $this->productsService->getProductsResponse($params, $languageId);
|
||||
|
||||
$block['data']['products'] = $response;
|
||||
|
||||
return $block;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class ProductsService
|
||||
{
|
||||
$page = $params['page'];
|
||||
$perPage = $params['perPage'];
|
||||
$search = $params['search'];
|
||||
$search = $params['search'] ?? false;
|
||||
$categoryName = '';
|
||||
$imageWidth = 300;
|
||||
$imageHeight = 300;
|
||||
|
||||
Reference in New Issue
Block a user