first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
<?php
namespace KupShop\LuigisBoxBundle\Recommenders;
use KupShop\CatalogBundle\ProductList\ProductCollection;
use KupShop\CatalogBundle\ProductList\ProductList;
use KupShop\LuigisBoxBundle\Api\RecommendersRequest;
use KupShop\RecommendersBundle\Recommenders\AbstractRecommender;
use KupShop\RecommendersBundle\Recommenders\IRecommender;
use KupShop\RecommendersBundle\Recommenders\RecommendersLocator;
use Query\Operator;
use Query\Product;
use Symfony\Component\HttpFoundation\RequestStack;
class LuigisBoxRecommender extends AbstractRecommender implements IRecommender
{
protected static string $type = 'luigisbox';
protected static string $name = 'Luigi\'s Box Recommender';
protected ?string $user_id;
public function __construct(
?RecommendersLocator $recommendersLocator,
protected RecommendersRequest $recommendersRequest,
protected ProductList $productList,
protected RequestStack $requestStack,
) {
$this->productList->applyDefaultFilterParams();
$this->user_id = $this->requestStack->getMainRequest()?->cookies->get('_lb');
parent::__construct($recommendersLocator);
}
public function execute(array $data, array $config): ProductCollection
{
$params = array_merge($config, $data, ['type' => $this::$type]);
$luigisParams = [];
$default = [
'user_id' => $this->user_id ?? '',
'size' => (int) $params['count'],
'hit_fields' => ['id', 'item_group_id', 'original_url', 'title'],
'mark_fallback_results' => true,
];
if (!empty($data['products'])) {
$default['item_ids'] = array_values(array_map('strval', $data['products']));
}
if (!empty($data['category'])) {
$category = (array) $data['category'];
if ($params['recommender_type'] == 'category') {
$default['item_ids'] = array_map('strval', $category);
} else {
$category = sqlQueryBuilder()->select('name')->from('sections')
->andWhere(Operator::inIntArray($category, 'id'))
->execute()->fetchFirstColumn();
if ($category) {
$default['recommendation_context']['category'] = ['values' => $category, 'operator' => 'or'];
}
}
}
$luigisParams[] = array_merge($default, ['recommendation_type' => $params['recommender_type']]);
if (!empty($params['fallback'])) {
$fallback = reset($params['fallback']);
if (($fallback['type'] == 'luigisbox') && (!empty($fallback['recommender_type']))) {
$luigisParams[] = array_merge($default, ['recommendation_type' => $fallback['recommender_type']]);
}
}
$searchResponse = $this->recommendersRequest->search($luigisParams);
$ids = [];
foreach ($searchResponse as $response) {
$hits = $response['hits'] ?? [];
foreach ($hits as $result) {
$id = (int) ($result['attributes']['item_group_id'][0] ?? $result['attributes']['id'][0] ?? $result['attributes']['original_url'] ?? $result['url'] ?? false);
if ($id) {
$ids[$id] = $id;
if (count($ids) >= $params['count']) {
break 2;
}
}
}
}
if (empty($ids)) {
return new ProductCollection();
}
return $this->preparePreloadProductList($ids, $data)->getProducts();
}
protected function preparePreloadProductList(array $ids, array $data): ProductList
{
$productList = clone $this->productList;
$productList->andSpec(Product::productsIds($ids));
$productList->fetchImages($data['image'] ?? 'product_catalog');
return $productList;
}
public function getLogData()
{
return [
'request' => $this->recommendersRequest->request ?? null,
'response' => $this->recommendersRequest->response ?? null,
];
}
}