fix: remove dead CategoryRepository param, fix N+1 queries in categories/list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -105,8 +105,7 @@ class ApiRouter
|
|||||||
return new Controllers\DictionariesApiController($statusRepo, $transportRepo, $paymentRepo, $attrRepo, $producerRepo);
|
return new Controllers\DictionariesApiController($statusRepo, $transportRepo, $paymentRepo, $attrRepo, $producerRepo);
|
||||||
},
|
},
|
||||||
'categories' => function () use ($db) {
|
'categories' => function () use ($db) {
|
||||||
$categoryRepo = new \Domain\Category\CategoryRepository($db);
|
return new Controllers\CategoriesApiController();
|
||||||
return new Controllers\CategoriesApiController($categoryRepo);
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,9 @@
|
|||||||
namespace api\Controllers;
|
namespace api\Controllers;
|
||||||
|
|
||||||
use api\ApiRouter;
|
use api\ApiRouter;
|
||||||
use Domain\Category\CategoryRepository;
|
|
||||||
|
|
||||||
class CategoriesApiController
|
class CategoriesApiController
|
||||||
{
|
{
|
||||||
private $categoryRepo;
|
|
||||||
|
|
||||||
public function __construct(CategoryRepository $categoryRepo)
|
|
||||||
{
|
|
||||||
$this->categoryRepo = $categoryRepo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function list(): void
|
public function list(): void
|
||||||
{
|
{
|
||||||
if (!ApiRouter::requireMethod('GET')) {
|
if (!ApiRouter::requireMethod('GET')) {
|
||||||
@@ -25,14 +17,14 @@ class CategoriesApiController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pobierz domyślny język sklepu
|
// Default shop language
|
||||||
$defaultLang = $db->get('pp_langs', 'id', ['start' => 1]);
|
$defaultLang = $db->get('pp_langs', 'id', ['start' => 1]);
|
||||||
if (!$defaultLang) {
|
if (!$defaultLang) {
|
||||||
$defaultLang = 'pl';
|
$defaultLang = 'pl';
|
||||||
}
|
}
|
||||||
$defaultLang = (string)$defaultLang;
|
$defaultLang = (string)$defaultLang;
|
||||||
|
|
||||||
// Pobierz wszystkie aktywne kategorie (płaska lista)
|
// All active categories, ordered by display order
|
||||||
$rows = $db->select(
|
$rows = $db->select(
|
||||||
'pp_shop_categories',
|
'pp_shop_categories',
|
||||||
['id', 'parent_id'],
|
['id', 'parent_id'],
|
||||||
@@ -42,11 +34,54 @@ class CategoriesApiController
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!is_array($rows)) {
|
if (!is_array($rows) || empty($rows)) {
|
||||||
ApiRouter::sendSuccess(['categories' => []]);
|
ApiRouter::sendSuccess(['categories' => []]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$categoryIds = array_values(array_filter(
|
||||||
|
array_map(fn($row) => (int)($row['id'] ?? 0), $rows),
|
||||||
|
fn($id) => $id > 0
|
||||||
|
));
|
||||||
|
|
||||||
|
// Bulk fetch titles for default language
|
||||||
|
$titlesByCategory = [];
|
||||||
|
$titleRows = $db->select('pp_shop_categories_langs', ['category_id', 'title'], [
|
||||||
|
'AND' => [
|
||||||
|
'category_id' => $categoryIds,
|
||||||
|
'lang_id' => $defaultLang,
|
||||||
|
'title[!]' => '',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
if (is_array($titleRows)) {
|
||||||
|
foreach ($titleRows as $tr) {
|
||||||
|
$tid = (int)($tr['category_id'] ?? 0);
|
||||||
|
if ($tid > 0 && !isset($titlesByCategory[$tid])) {
|
||||||
|
$titlesByCategory[$tid] = (string)($tr['title'] ?? '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bulk fetch fallback titles for categories without a title in default language
|
||||||
|
$missingIds = array_values(array_filter($categoryIds, fn($id) => !isset($titlesByCategory[$id])));
|
||||||
|
if (!empty($missingIds)) {
|
||||||
|
$fallbackRows = $db->select('pp_shop_categories_langs', ['category_id', 'title'], [
|
||||||
|
'AND' => [
|
||||||
|
'category_id' => $missingIds,
|
||||||
|
'title[!]' => '',
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
if (is_array($fallbackRows)) {
|
||||||
|
foreach ($fallbackRows as $fr) {
|
||||||
|
$fid = (int)($fr['category_id'] ?? 0);
|
||||||
|
if ($fid > 0 && !isset($titlesByCategory[$fid])) {
|
||||||
|
$titlesByCategory[$fid] = (string)($fr['title'] ?? '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build flat category list
|
||||||
$categories = [];
|
$categories = [];
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$categoryId = (int)($row['id'] ?? 0);
|
$categoryId = (int)($row['id'] ?? 0);
|
||||||
@@ -54,28 +89,13 @@ class CategoriesApiController
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$title = $db->get('pp_shop_categories_langs', 'title', [
|
|
||||||
'AND' => [
|
|
||||||
'category_id' => $categoryId,
|
|
||||||
'lang_id' => $defaultLang,
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Fallback: jeśli brak tłumaczenia w domyślnym języku, weź pierwsze dostępne
|
|
||||||
if (!$title) {
|
|
||||||
$title = $db->get('pp_shop_categories_langs', 'title', [
|
|
||||||
'category_id' => $categoryId,
|
|
||||||
'title[!]' => '',
|
|
||||||
'LIMIT' => 1,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$parentId = $row['parent_id'] !== null ? (int)$row['parent_id'] : null;
|
$parentId = $row['parent_id'] !== null ? (int)$row['parent_id'] : null;
|
||||||
|
$title = $titlesByCategory[$categoryId] ?? ('Kategoria #' . $categoryId);
|
||||||
|
|
||||||
$categories[] = [
|
$categories[] = [
|
||||||
'id' => $categoryId,
|
'id' => $categoryId,
|
||||||
'parent_id' => $parentId,
|
'parent_id' => $parentId,
|
||||||
'title' => (string)($title ?? 'Kategoria #' . $categoryId),
|
'title' => $title,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user