Refactor admin lists and migrate legacy archive/filemanager controllers

This commit is contained in:
2026-02-11 00:03:07 +01:00
parent fe4e98d9bd
commit f9f2ddd3bb
18 changed files with 527 additions and 374 deletions

View File

@@ -9,6 +9,8 @@ namespace Domain\Product;
*/
class ProductRepository
{
private const MAX_PER_PAGE = 100;
/**
* @var \medoo Instancja Medoo ORM
*/
@@ -50,6 +52,118 @@ class ProductRepository
return $product ?: null;
}
/**
* Zwraca liste produktow z archiwum do panelu admin.
*
* @return array{items: array<int, array<string, mixed>>, total: int}
*/
public function listArchivedForAdmin(
array $filters,
string $sortColumn = 'id',
string $sortDir = 'DESC',
int $page = 1,
int $perPage = 10
): array {
$allowedSortColumns = [
'id' => 'psp.id',
'name' => 'name',
'price_brutto' => 'psp.price_brutto',
'price_brutto_promo' => 'psp.price_brutto_promo',
'quantity' => 'psp.quantity',
'combinations' => 'combinations',
];
$sortSql = $allowedSortColumns[$sortColumn] ?? 'psp.id';
$sortDir = strtoupper(trim($sortDir)) === 'ASC' ? 'ASC' : 'DESC';
$page = max(1, $page);
$perPage = min(self::MAX_PER_PAGE, max(1, $perPage));
$offset = ($page - 1) * $perPage;
$where = ['psp.archive = 1', 'psp.parent_id IS NULL'];
$params = [];
$phrase = trim((string)($filters['phrase'] ?? ''));
if (strlen($phrase) > 255) {
$phrase = substr($phrase, 0, 255);
}
if ($phrase !== '') {
$where[] = '(
psp.ean LIKE :phrase
OR psp.sku LIKE :phrase
OR EXISTS (
SELECT 1
FROM pp_shop_products_langs AS pspl2
WHERE pspl2.product_id = psp.id
AND pspl2.name LIKE :phrase
)
)';
$params[':phrase'] = '%' . $phrase . '%';
}
$whereSql = implode(' AND ', $where);
$sqlCount = "
SELECT COUNT(0)
FROM pp_shop_products AS psp
WHERE {$whereSql}
";
$stmtCount = $this->db->query($sqlCount, $params);
$countRows = $stmtCount ? $stmtCount->fetchAll() : [];
$total = isset($countRows[0][0]) ? (int)$countRows[0][0] : 0;
$sql = "
SELECT
psp.id,
psp.price_brutto,
psp.price_brutto_promo,
psp.quantity,
psp.sku,
psp.ean,
(
SELECT pspl.name
FROM pp_shop_products_langs AS pspl
INNER JOIN pp_langs AS pl ON pl.id = pspl.lang_id
WHERE pspl.product_id = psp.id
AND pspl.name <> ''
ORDER BY pl.o ASC
LIMIT 1
) AS name,
(
SELECT pspi.src
FROM pp_shop_products_images AS pspi
WHERE pspi.product_id = psp.id
ORDER BY pspi.o ASC, pspi.id ASC
LIMIT 1
) AS image_src,
(
SELECT pspi.alt
FROM pp_shop_products_images AS pspi
WHERE pspi.product_id = psp.id
ORDER BY pspi.o ASC, pspi.id ASC
LIMIT 1
) AS image_alt,
(
SELECT COUNT(0)
FROM pp_shop_products AS pspc
WHERE pspc.parent_id = psp.id
) AS combinations
FROM pp_shop_products AS psp
WHERE {$whereSql}
ORDER BY {$sortSql} {$sortDir}, psp.id {$sortDir}
LIMIT {$perPage} OFFSET {$offset}
";
$stmt = $this->db->query($sql, $params);
$items = $stmt ? $stmt->fetchAll() : [];
return [
'items' => is_array($items) ? $items : [],
'total' => $total,
];
}
/**
* Pobiera cenę produktu (promocyjną jeśli jest niższa, w przeciwnym razie regularną)
*