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' => 'spm.id', 'name' => 'spm.name', 'status' => 'spm.status', 'apilo_payment_type_id' => 'spm.apilo_payment_type_id', ]; $sortSql = $allowedSortColumns[$sortColumn] ?? 'spm.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[] = 'spm.name LIKE :name'; $params[':name'] = '%' . $name . '%'; } $status = trim((string)($filters['status'] ?? '')); if ($status === '0' || $status === '1') { $where[] = 'spm.status = :status'; $params[':status'] = (int)$status; } $whereSql = implode(' AND ', $where); $sqlCount = " SELECT COUNT(0) FROM pp_shop_payment_methods AS spm WHERE {$whereSql} "; $stmtCount = $this->db->query($sqlCount, $params); $countRows = $stmtCount ? $stmtCount->fetchAll() : []; $total = isset($countRows[0][0]) ? (int)$countRows[0][0] : 0; $sql = " SELECT spm.id, spm.name, spm.description, spm.status, spm.apilo_payment_type_id FROM pp_shop_payment_methods AS spm WHERE {$whereSql} ORDER BY {$sortSql} {$sortDir}, spm.id ASC LIMIT {$perPage} OFFSET {$offset} "; $stmt = $this->db->query($sql, $params); $items = $stmt ? $stmt->fetchAll() : []; if (!is_array($items)) { $items = []; } foreach ($items as &$item) { $item = $this->normalizePaymentMethod($item); } unset($item); return [ 'items' => $items, 'total' => $total, ]; } public function find(int $paymentMethodId): ?array { if ($paymentMethodId <= 0) { return null; } $paymentMethod = $this->db->get('pp_shop_payment_methods', '*', ['id' => $paymentMethodId]); if (!is_array($paymentMethod)) { return null; } return $this->normalizePaymentMethod($paymentMethod); } public function save(int $paymentMethodId, array $data): ?int { if ($paymentMethodId <= 0) { return null; } $row = [ 'description' => trim((string)($data['description'] ?? '')), 'status' => $this->toSwitchValue($data['status'] ?? 0), 'apilo_payment_type_id' => $this->normalizeApiloPaymentTypeId($data['apilo_payment_type_id'] ?? null), 'min_order_amount' => $this->normalizeDecimalOrNull($data['min_order_amount'] ?? null), 'max_order_amount' => $this->normalizeDecimalOrNull($data['max_order_amount'] ?? null), 'is_cod' => (int)(!empty($data['is_cod']) ? 1 : 0), ]; $this->db->update('pp_shop_payment_methods', $row, ['id' => $paymentMethodId]); $cacheHandler = new \Shared\Cache\CacheHandler(); $cacheHandler->deletePattern('payment_method*'); $cacheHandler->deletePattern('payment_methods*'); return $paymentMethodId; } /** * @return array> */ public function allActive(): array { $rows = $this->db->select('pp_shop_payment_methods', '*', [ 'status' => 1, 'ORDER' => ['id' => 'ASC'], ]); if (!is_array($rows)) { return []; } $result = []; foreach ($rows as $row) { if (is_array($row)) { $result[] = $this->normalizePaymentMethod($row); } } return $result; } /** * @return array> */ public function allForAdmin(): array { $rows = $this->db->select('pp_shop_payment_methods', '*', [ 'ORDER' => ['name' => 'ASC'], ]); if (!is_array($rows)) { return []; } $result = []; foreach ($rows as $row) { if (is_array($row)) { $result[] = $this->normalizePaymentMethod($row); } } return $result; } public function findActiveById(int $paymentMethodId): ?array { if ($paymentMethodId <= 0) { return null; } $paymentMethod = $this->db->get('pp_shop_payment_methods', '*', [ 'AND' => [ 'id' => $paymentMethodId, 'status' => 1, ], ]); if (!is_array($paymentMethod)) { return null; } return $this->normalizePaymentMethod($paymentMethod); } public function isActive(int $paymentMethodId): int { if ($paymentMethodId <= 0) { return 0; } $status = $this->db->get('pp_shop_payment_methods', 'status', ['id' => $paymentMethodId]); return $this->toSwitchValue($status); } /** * @return int|string|null */ public function getApiloPaymentTypeId(int $paymentMethodId) { if ($paymentMethodId <= 0) { return null; } $value = $this->db->get('pp_shop_payment_methods', 'apilo_payment_type_id', ['id' => $paymentMethodId]); return $this->normalizeApiloPaymentTypeId($value); } /** * @return array> */ public function forTransport(int $transportMethodId): array { if ($transportMethodId <= 0) { return []; } $sql = " SELECT spm.id, spm.name, spm.description, spm.status, spm.apilo_payment_type_id, spm.min_order_amount, spm.max_order_amount, spm.is_cod FROM pp_shop_payment_methods AS spm INNER JOIN pp_shop_transport_payment_methods AS stpm ON stpm.id_payment_method = spm.id WHERE spm.status = 1 AND stpm.id_transport = :transport_id "; $stmt = $this->db->query($sql, [':transport_id' => $transportMethodId]); $rows = $stmt ? $stmt->fetchAll() : []; if (!is_array($rows)) { return []; } $result = []; foreach ($rows as $row) { if (is_array($row)) { $result[] = $this->normalizePaymentMethod($row); } } return $result; } /** * Metody platnosci dla danego transportu — z Redis cache (frontend). * * @return array> */ public function paymentMethodsByTransport(int $transportMethodId): array { $cacheHandler = new \Shared\Cache\CacheHandler(); $cacheKey = 'payment_methods_by_transport' . $transportMethodId; $cached = $cacheHandler->get($cacheKey); if ($cached) { return unserialize($cached); } $result = $this->forTransport($transportMethodId); $cacheHandler->set($cacheKey, $result); return $result; } /** * Pojedyncza aktywna metoda platnosci — z Redis cache (frontend). */ public function paymentMethodCached(int $paymentMethodId): ?array { $cacheHandler = new \Shared\Cache\CacheHandler(); $cacheKey = 'payment_method' . $paymentMethodId; $cached = $cacheHandler->get($cacheKey); if ($cached) { return unserialize($cached); } $result = $this->findActiveById($paymentMethodId); $cacheHandler->set($cacheKey, $result); return $result; } /** * Wszystkie aktywne metody platnosci — z Redis cache (frontend). * * @return array> */ public function paymentMethodsCached(): array { $cacheHandler = new \Shared\Cache\CacheHandler(); $cacheKey = 'payment_methods'; $cached = $cacheHandler->get($cacheKey); if ($cached) { return unserialize($cached); } $result = $this->allActive(); $cacheHandler->set($cacheKey, $result); return $result; } private function normalizePaymentMethod(array $row): array { $row['id'] = (int)($row['id'] ?? 0); $row['name'] = trim((string)($row['name'] ?? '')); $row['description'] = (string)($row['description'] ?? ''); $row['status'] = $this->toSwitchValue($row['status'] ?? 0); $row['apilo_payment_type_id'] = $this->normalizeApiloPaymentTypeId($row['apilo_payment_type_id'] ?? null); $row['min_order_amount'] = $this->normalizeDecimalOrNull($row['min_order_amount'] ?? null); $row['max_order_amount'] = $this->normalizeDecimalOrNull($row['max_order_amount'] ?? null); $row['is_cod'] = (int)($row['is_cod'] ?? 0); return $row; } /** * @return int|string|null */ private function normalizeApiloPaymentTypeId($value) { if ($value === null || $value === false) { return null; } $text = trim((string)$value); if ($text === '') { return null; } if (preg_match('/^-?\d+$/', $text) === 1) { return (int)$text; } return $text; } /** * @return float|null */ private function normalizeDecimalOrNull($value) { if ($value === null || $value === false) { return null; } $text = trim((string)$value); if ($text === '') { return null; } return (float)$text; } 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; } }