Files
shopPRO/autoload/Domain/Scontainers/ScontainersRepository.php
Jacek Pyziak 42e4396064 Refactor Scontainers management
- Removed legacy Scontainers controller and view files, transitioning to a new controller structure.
- Introduced ScontainersController to handle CRUD operations with improved dependency injection.
- Created ScontainersRepository for database interactions, encapsulating logic for container management.
- Updated container edit and list views to utilize new templating system.
- Added unit tests for ScontainersRepository and ScontainersController to ensure functionality.
- Enhanced form handling for container editing, including validation and error management.
2026-02-12 23:54:56 +01:00

312 lines
8.8 KiB
PHP

<?php
namespace Domain\Scontainers;
class ScontainersRepository
{
private const MAX_PER_PAGE = 100;
private $db;
public function __construct($db)
{
$this->db = $db;
}
/**
* @return array{items: array<int, array<string, mixed>>, total: int}
*/
public function listForAdmin(
array $filters,
string $sortColumn = 'id',
string $sortDir = 'DESC',
int $page = 1,
int $perPage = 15
): array {
$allowedSortColumns = [
'id' => 'q1.id',
'title' => 'q1.title',
'status' => 'q1.status',
];
$sortSql = $allowedSortColumns[$sortColumn] ?? 'q1.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 = ['1 = 1'];
$params = [];
$title = trim((string)($filters['title'] ?? ''));
if ($title !== '') {
if (strlen($title) > 255) {
$title = substr($title, 0, 255);
}
$where[] = 'q1.title LIKE :title';
$params[':title'] = '%' . $title . '%';
}
$status = trim((string)($filters['status'] ?? ''));
if ($status === '0' || $status === '1') {
$where[] = 'q1.status = :status';
$params[':status'] = (int)$status;
}
$whereSql = implode(' AND ', $where);
$baseSelect = $this->baseListSelect();
$sqlCount = "
SELECT COUNT(0)
FROM ({$baseSelect}) AS q1
WHERE {$whereSql}
";
$stmtCount = $this->db->query($sqlCount, $params);
$countRows = $stmtCount ? $stmtCount->fetchAll() : [];
$total = isset($countRows[0][0]) ? (int)$countRows[0][0] : 0;
$sql = "
SELECT q1.*
FROM ({$baseSelect}) AS q1
WHERE {$whereSql}
ORDER BY {$sortSql} {$sortDir}, q1.id DESC
LIMIT {$perPage} OFFSET {$offset}
";
$stmt = $this->db->query($sql, $params);
$items = $stmt ? $stmt->fetchAll() : [];
return [
'items' => is_array($items) ? $items : [],
'total' => $total,
];
}
public function find(int $containerId): array
{
if ($containerId <= 0) {
return $this->defaultContainer();
}
$container = $this->db->get('pp_scontainers', '*', ['id' => $containerId]);
if (!is_array($container)) {
return $this->defaultContainer();
}
$container['languages'] = $this->translationsMap($containerId);
return $container;
}
public function detailsForLanguage(int $containerId, string $langId): ?array
{
if ($containerId <= 0 || trim($langId) === '') {
return null;
}
$container = $this->db->get('pp_scontainers', '*', ['id' => $containerId]);
if (!is_array($container)) {
return null;
}
$translation = $this->db->get('pp_scontainers_langs', '*', [
'AND' => [
'container_id' => $containerId,
'lang_id' => $langId,
],
]);
$container['languages'] = is_array($translation) ? $translation : [
'lang_id' => $langId,
'title' => '',
'text' => '',
];
return $container;
}
public function save(array $data): ?int
{
$containerId = (int)($data['id'] ?? 0);
$status = $this->toSwitchValue($data['status'] ?? 0);
$showTitle = $this->toSwitchValue($data['show_title'] ?? 0);
$translations = $this->extractTranslations($data);
if ($containerId <= 0) {
$this->db->insert('pp_scontainers', [
'status' => $status,
'show_title' => $showTitle,
]);
$containerId = (int)$this->db->id();
if ($containerId <= 0) {
return null;
}
} else {
$this->db->update('pp_scontainers', [
'status' => $status,
'show_title' => $showTitle,
], [
'id' => $containerId,
]);
}
foreach ($translations as $langId => $row) {
$translationId = $this->db->get('pp_scontainers_langs', 'id', [
'AND' => [
'container_id' => $containerId,
'lang_id' => $langId,
],
]);
if ($translationId) {
$this->db->update('pp_scontainers_langs', [
'title' => (string)($row['title'] ?? ''),
'text' => (string)($row['text'] ?? ''),
], [
'id' => (int)$translationId,
]);
} else {
$this->db->insert('pp_scontainers_langs', [
'container_id' => $containerId,
'lang_id' => $langId,
'title' => (string)($row['title'] ?? ''),
'text' => (string)($row['text'] ?? ''),
]);
}
}
\S::delete_dir('../temp/');
$this->clearFrontCache($containerId);
return $containerId;
}
public function delete(int $containerId): bool
{
if ($containerId <= 0) {
return false;
}
$result = (bool)$this->db->delete('pp_scontainers', ['id' => $containerId]);
if ($result) {
$this->clearFrontCache($containerId);
}
return $result;
}
private function baseListSelect(): string
{
return "
SELECT
ps.id,
ps.status,
(
SELECT psl.title
FROM pp_scontainers_langs AS psl
JOIN pp_langs AS pl ON psl.lang_id = pl.id
WHERE psl.container_id = ps.id
AND psl.title <> ''
ORDER BY pl.o ASC
LIMIT 1
) AS title
FROM pp_scontainers AS ps
";
}
private function clearFrontCache(int $containerId): void
{
if ($containerId <= 0 || !class_exists('\CacheHandler')) {
return;
}
$cacheHandler = new \CacheHandler();
$cacheKey = '\front\factory\Scontainers::scontainer_details:' . $containerId;
$cacheHandler->delete($cacheKey);
}
/**
* @return array<string, array<string, mixed>>
*/
private function translationsMap(int $containerId): array
{
$rows = $this->db->select('pp_scontainers_langs', '*', ['container_id' => $containerId]);
if (!is_array($rows)) {
return [];
}
$result = [];
foreach ($rows as $row) {
$langId = (string)($row['lang_id'] ?? '');
if ($langId !== '') {
$result[$langId] = $row;
}
}
return $result;
}
/**
* @return array<string, array<string, string>>
*/
private function extractTranslations(array $data): array
{
$translations = [];
if (isset($data['translations']) && is_array($data['translations'])) {
foreach ($data['translations'] as $langId => $row) {
if (!is_array($row)) {
continue;
}
$safeLangId = trim((string)$langId);
if ($safeLangId === '') {
continue;
}
$translations[$safeLangId] = [
'title' => (string)($row['title'] ?? ''),
'text' => (string)($row['text'] ?? ''),
];
}
}
$legacyTitles = isset($data['title']) && is_array($data['title']) ? $data['title'] : [];
$legacyTexts = isset($data['text']) && is_array($data['text']) ? $data['text'] : [];
foreach ($legacyTitles as $langId => $title) {
$safeLangId = trim((string)$langId);
if ($safeLangId === '') {
continue;
}
if (!isset($translations[$safeLangId])) {
$translations[$safeLangId] = [
'title' => '',
'text' => '',
];
}
$translations[$safeLangId]['title'] = (string)$title;
$translations[$safeLangId]['text'] = (string)($legacyTexts[$safeLangId] ?? '');
}
return $translations;
}
private function toSwitchValue($value): int
{
return ($value === 'on' || $value === 1 || $value === '1' || $value === true) ? 1 : 0;
}
private function defaultContainer(): array
{
return [
'id' => 0,
'status' => 1,
'show_title' => 0,
'languages' => [],
];
}
}