db = $db; } /** * @return array{items: array>, total: int} */ public function listForAdmin( array $filters, string $sortColumn = 'name', string $sortDir = 'ASC', int $page = 1, int $perPage = 15 ): array { $allowedSortColumns = [ 'id' => 'ps.id', 'name' => 'ps.name', 'status' => 'ps.status', ]; $sortSql = $allowedSortColumns[$sortColumn] ?? 'ps.name'; $sortDir = strtoupper(trim($sortDir)) === 'DESC' ? 'DESC' : 'ASC'; $page = max(1, $page); $perPage = min(self::MAX_PER_PAGE, max(1, $perPage)); $offset = ($page - 1) * $perPage; $where = ['1 = 1']; $params = []; $name = trim((string)($filters['name'] ?? '')); if ($name !== '') { if (strlen($name) > 255) { $name = substr($name, 0, 255); } $where[] = 'ps.name LIKE :name'; $params[':name'] = '%' . $name . '%'; } $status = trim((string)($filters['status'] ?? '')); if ($status === '0' || $status === '1') { $where[] = 'ps.status = :status'; $params[':status'] = (int)$status; } $whereSql = implode(' AND ', $where); $sqlCount = " SELECT COUNT(0) FROM pp_shop_product_sets AS ps WHERE {$whereSql} "; $stmtCount = $this->db->query($sqlCount, $params); $countRows = $stmtCount ? $stmtCount->fetchAll() : []; $total = isset($countRows[0][0]) ? (int)$countRows[0][0] : 0; $sql = " SELECT ps.id, ps.name, ps.status FROM pp_shop_product_sets AS ps WHERE {$whereSql} ORDER BY {$sortSql} {$sortDir}, ps.id DESC LIMIT {$perPage} OFFSET {$offset} "; $stmt = $this->db->query($sql, $params); $items = $stmt ? $stmt->fetchAll() : []; if (!is_array($items)) { $items = []; } foreach ($items as &$item) { $item['id'] = (int)($item['id'] ?? 0); $item['status'] = $this->toSwitchValue($item['status'] ?? 0); } unset($item); return [ 'items' => $items, 'total' => $total, ]; } public function find(int $id): array { if ($id <= 0) { return $this->defaultSet(); } $set = $this->db->get('pp_shop_product_sets', '*', ['id' => $id]); if (!is_array($set)) { return $this->defaultSet(); } $set['id'] = (int)($set['id'] ?? 0); $set['status'] = $this->toSwitchValue($set['status'] ?? 0); $products = $this->db->select('pp_shop_product_sets_products', 'product_id', ['set_id' => $id]); $set['products'] = is_array($products) ? array_map('intval', $products) : []; return $set; } public function save(int $id, string $name, int $status, array $productIds): ?int { $row = [ 'name' => trim($name), 'status' => $status === 1 ? 1 : 0, ]; if ($id <= 0) { $this->db->insert('pp_shop_product_sets', $row); $id = (int)$this->db->id(); if ($id <= 0) { return null; } } else { $this->db->update('pp_shop_product_sets', $row, ['id' => $id]); } $this->syncProducts($id, $productIds); $this->clearTempAndCache(); return $id; } public function delete(int $id): bool { if ($id <= 0) { return false; } $this->db->delete('pp_shop_product_sets_products', ['set_id' => $id]); $result = (bool)$this->db->delete('pp_shop_product_sets', ['id' => $id]); if ($result) { $this->clearTempAndCache(); } return $result; } /** * @return array */ public function allSets(): array { $rows = $this->db->select('pp_shop_product_sets', ['id', 'name'], ['ORDER' => ['name' => 'ASC']]); if (!is_array($rows)) { return []; } $sets = []; foreach ($rows as $row) { $sets[] = [ 'id' => (int)($row['id'] ?? 0), 'name' => (string)($row['name'] ?? ''), ]; } return $sets; } /** * @return array */ public function allProductsMap(): array { $rows = $this->db->select('pp_shop_products', 'id', ['parent_id' => null]); if (!is_array($rows)) { return []; } $products = []; foreach ($rows as $productId) { $name = $this->db->get('pp_shop_products_langs', 'name', [ 'AND' => ['product_id' => $productId, 'lang_id' => 'pl'], ]); if ($name) { $products[(int)$productId] = (string)$name; } } return $products; } private function syncProducts(int $setId, array $productIds): void { $this->db->delete('pp_shop_product_sets_products', ['set_id' => $setId]); $seen = []; foreach ($productIds as $productId) { $pid = (int)$productId; if ($pid > 0 && !isset($seen[$pid])) { $this->db->insert('pp_shop_product_sets_products', [ 'set_id' => $setId, 'product_id' => $pid, ]); $seen[$pid] = true; } } } private function defaultSet(): array { return [ 'id' => 0, 'name' => '', 'status' => 1, 'products' => [], ]; } private function toSwitchValue($value): int { if (is_bool($value)) { return $value ? 1 : 0; } if (is_numeric($value)) { return ((int)$value) === 1 ? 1 : 0; } if (is_string($value)) { $normalized = strtolower(trim($value)); return in_array($normalized, ['1', 'on', 'true', 'yes'], true) ? 1 : 0; } return 0; } private function clearTempAndCache(): void { \Shared\Helpers\Helpers::delete_dir('../temp/'); \Shared\Helpers\Helpers::delete_dir('../thumbs/'); } }