превью относительно готово

This commit is contained in:
Alisa
2026-06-05 19:24:57 +03:00
parent c08519263c
commit 98987b5355
5 changed files with 227 additions and 47 deletions
+67 -2
View File
@@ -47,6 +47,9 @@ final class ProductRepository extends BaseRepository
{
$limit = max(1, min($limit, 96));
$categoryIds = (new CategoryRepository())->descendantIds($categoryId);
$categoryParents = $this->categoryParentMap();
$requestedRootId = $this->rootCategoryId($categoryId, $categoryParents);
$isRootCategory = ($categoryParents[$categoryId] ?? null) === null;
$placeholders = implode(',', array_fill(0, count($categoryIds), '?'));
$sql = $this->previewSelectSql(
'AND (
@@ -67,13 +70,37 @@ final class ProductRepository extends BaseRepository
)
)
ORDER BY p.sort_order, p.name',
$limit
5000
);
$statement = $this->pdo()->prepare($sql);
$statement->execute(array_merge($categoryIds, $categoryIds));
return $this->preparePreviewProducts($statement->fetchAll());
$categoryLookup = array_flip($categoryIds);
$products = $this->preparePreviewProducts($statement->fetchAll());
$filtered = [];
foreach ($products as $product) {
$leafCategoryIds = $product['category_display_ids'] ?? [];
$leafRootIds = $product['category_display_root_ids'] ?? [];
if ($leafCategoryIds === []) {
if (isset($categoryLookup[(int) ($product['category_id'] ?? 0)])) {
$filtered[] = $product;
}
} elseif (
array_intersect($leafCategoryIds, $categoryIds) !== []
&& (!$isRootCategory || array_values(array_unique($leafRootIds)) === [$requestedRootId])
) {
$filtered[] = $product;
}
if (count($filtered) >= $limit) {
break;
}
}
return $filtered;
}
/**
@@ -236,6 +263,7 @@ final class ProductRepository extends BaseRepository
p.seo_title,
p.seo_description,
p.seo_keywords,
p.category_id,
c.name AS category_name,
c.slug AS category_slug,
p.main_image_path,
@@ -351,6 +379,7 @@ final class ProductRepository extends BaseRepository
}
$categoryParents = $this->categoryParentMap();
$categoryRoots = $this->categoryRootMap($categoryParents);
foreach ($products as &$product) {
$linkedCategories = $categoriesByProduct[(int) $product['id']] ?? [];
@@ -373,6 +402,11 @@ final class ProductRepository extends BaseRepository
});
$names = array_values(array_unique(array_map(static fn (array $category): string => $category['name'], $leafCategories)));
$product['category_display_ids'] = array_values(array_map(static fn (array $category): int => (int) $category['id'], $leafCategories));
$product['category_display_root_ids'] = array_values(array_unique(array_map(
static fn (array $category): int => (int) ($categoryRoots[(int) $category['id']] ?? $category['id']),
$leafCategories
)));
$product['category_display_name'] = $names === []
? ($product['category_name'] ?? 'Каталог')
: implode(' / ', $names);
@@ -398,6 +432,37 @@ final class ProductRepository extends BaseRepository
return $parents;
}
/**
* @param array<int, int|null> $categoryParents
* @return array<int, int>
*/
private function categoryRootMap(array $categoryParents): array
{
$roots = [];
foreach (array_keys($categoryParents) as $categoryId) {
$roots[$categoryId] = $this->rootCategoryId((int) $categoryId, $categoryParents);
}
return $roots;
}
/**
* @param array<int, int|null> $categoryParents
*/
private function rootCategoryId(int $categoryId, array $categoryParents): int
{
$currentId = $categoryId;
$parentId = $categoryParents[$currentId] ?? null;
while ($parentId !== null) {
$currentId = $parentId;
$parentId = $categoryParents[$currentId] ?? null;
}
return $currentId;
}
/**
* @param array<int, int> $linkedCategoryIds
* @param array<int, int|null> $categoryParents