+
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(
diff --git a/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/Handlers/AutocompleteHandler.php b/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/Handlers/AutocompleteHandler.php
index 34d7e14..8399146 100755
--- a/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/Handlers/AutocompleteHandler.php
+++ b/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/Handlers/AutocompleteHandler.php
@@ -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;
+ }
}
diff --git a/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/Handlers/DictionariesHandler.php b/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/Handlers/DictionariesHandler.php
new file mode 100644
index 0000000..d715f4f
--- /dev/null
+++ b/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/Handlers/DictionariesHandler.php
@@ -0,0 +1,58 @@
+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'));
+ }
+}
diff --git a/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/routes.php b/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/routes.php
index 0caf308..8a64edc 100755
--- a/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/routes.php
+++ b/module/oc_telegram_shop/upload/oc_telegram_shop/bastion/routes.php
@@ -1,6 +1,7 @@
[AutocompleteHandler::class, 'getCategoriesById'],
'getDashboardStats' => [StatsHandler::class, 'getDashboardStats'],
'tgGetMe' => [TelegramHandler::class, 'tgGetMe'],
+
+ 'getCategories' => [DictionariesHandler::class, 'getCategories'],
+
+ 'getAutocompleteCategories' => [AutocompleteHandler::class, 'getCategories'],
+ 'getAutocompleteCategoriesFlat' => [AutocompleteHandler::class, 'getCategoriesFlat'],
];
diff --git a/module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers/CategoriesHandler.php b/module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers/CategoriesHandler.php
index e8ec3cf..223ae60 100755
--- a/module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers/CategoriesHandler.php
+++ b/module/oc_telegram_shop/upload/oc_telegram_shop/src/Handlers/CategoriesHandler.php
@@ -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'],
diff --git a/module/oc_telegram_shop/upload/oc_telegram_shop/src/Services/BlocksService.php b/module/oc_telegram_shop/upload/oc_telegram_shop/src/Services/BlocksService.php
index 44943eb..2154c19 100755
--- a/module/oc_telegram_shop/upload/oc_telegram_shop/src/Services/BlocksService.php
+++ b/module/oc_telegram_shop/upload/oc_telegram_shop/src/Services/BlocksService.php
@@ -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;
+ }
}
diff --git a/module/oc_telegram_shop/upload/oc_telegram_shop/src/Services/ProductsService.php b/module/oc_telegram_shop/upload/oc_telegram_shop/src/Services/ProductsService.php
index 76a8e18..5ffc019 100755
--- a/module/oc_telegram_shop/upload/oc_telegram_shop/src/Services/ProductsService.php
+++ b/module/oc_telegram_shop/upload/oc_telegram_shop/src/Services/ProductsService.php
@@ -53,7 +53,7 @@ class ProductsService
{
$page = $params['page'];
$perPage = $params['perPage'];
- $search = $params['search'];
+ $search = $params['search'] ?? false;
$categoryName = '';
$imageWidth = 300;
$imageHeight = 300;