integrations = new IntegrationsRepository($this->pdo); $this->cipher = new IntegrationSecretCipher($this->secret); } /** * @return array */ public function getSettings(): array { $row = $this->fetchRow(); if ($row === null) { $row = $this->defaultSettings(); } $encryptedToken = $this->resolveEncryptedToken($row); return [ 'has_api_token' => $encryptedToken !== null && $encryptedToken !== '', 'organization_id' => (string) ($row['organization_id'] ?? ''), 'environment' => (string) ($row['environment'] ?? 'sandbox'), 'default_dispatch_method' => (string) ($row['default_dispatch_method'] ?? 'pop'), 'default_dispatch_point' => (string) ($row['default_dispatch_point'] ?? ''), 'default_insurance' => isset($row['default_insurance']) && $row['default_insurance'] !== null ? (float) $row['default_insurance'] : null, 'default_locker_size' => (string) ($row['default_locker_size'] ?? 'small'), 'default_courier_length' => (int) ($row['default_courier_length'] ?? 20), 'default_courier_width' => (int) ($row['default_courier_width'] ?? 15), 'default_courier_height' => (int) ($row['default_courier_height'] ?? 8), 'label_format' => (string) ($row['label_format'] ?? 'Pdf'), 'weekend_delivery' => (bool) ($row['weekend_delivery'] ?? false), 'auto_insurance_value' => (bool) ($row['auto_insurance_value'] ?? false), 'multi_parcel' => (bool) ($row['multi_parcel'] ?? false), ]; } /** * @param array $payload */ public function saveSettings(array $payload): void { $this->ensureRow(); $current = $this->fetchRow(); if ($current === null) { throw new RuntimeException('Brak rekordu konfiguracji InPost.'); } $integrationId = $this->ensureBaseIntegration(); $currentEncrypted = $this->resolveEncryptedToken($current); $apiToken = trim((string) ($payload['api_token'] ?? '')); $nextEncrypted = $currentEncrypted; if ($apiToken !== '') { $nextEncrypted = $this->cipher->encrypt($apiToken); } $this->integrations->updateApiKeyEncrypted($integrationId, $nextEncrypted); $statement = $this->pdo->prepare( 'UPDATE inpost_integration_settings SET api_token_encrypted = :api_token_encrypted, organization_id = :organization_id, environment = :environment, default_dispatch_method = :default_dispatch_method, default_dispatch_point = :default_dispatch_point, default_insurance = :default_insurance, default_locker_size = :default_locker_size, default_courier_length = :default_courier_length, default_courier_width = :default_courier_width, default_courier_height = :default_courier_height, label_format = :label_format, weekend_delivery = :weekend_delivery, auto_insurance_value = :auto_insurance_value, multi_parcel = :multi_parcel, updated_at = NOW() WHERE id = 1' ); $statement->execute([ 'api_token_encrypted' => StringHelper::nullableString((string) $nextEncrypted), 'organization_id' => StringHelper::nullableString(trim((string) ($payload['organization_id'] ?? ''))), 'environment' => in_array($payload['environment'] ?? '', ['sandbox', 'production'], true) ? $payload['environment'] : 'sandbox', 'default_dispatch_method' => in_array($payload['default_dispatch_method'] ?? '', ['pop', 'parcel_locker', 'courier'], true) ? $payload['default_dispatch_method'] : 'pop', 'default_dispatch_point' => StringHelper::nullableString(trim((string) ($payload['default_dispatch_point'] ?? ''))), 'default_insurance' => ($payload['default_insurance'] ?? '') !== '' ? (float) $payload['default_insurance'] : null, 'default_locker_size' => in_array($payload['default_locker_size'] ?? '', ['small', 'medium', 'large'], true) ? $payload['default_locker_size'] : 'small', 'default_courier_length' => max(1, (int) ($payload['default_courier_length'] ?? 20)), 'default_courier_width' => max(1, (int) ($payload['default_courier_width'] ?? 15)), 'default_courier_height' => max(1, (int) ($payload['default_courier_height'] ?? 8)), 'label_format' => in_array($payload['label_format'] ?? '', ['Pdf', 'Zpl', 'Epl'], true) ? $payload['label_format'] : 'Pdf', 'weekend_delivery' => !empty($payload['weekend_delivery']) ? 1 : 0, 'auto_insurance_value' => !empty($payload['auto_insurance_value']) ? 1 : 0, 'multi_parcel' => !empty($payload['multi_parcel']) ? 1 : 0, ]); } /** * @return string|null Decrypted API token or null */ public function getDecryptedToken(): ?string { $row = $this->fetchRow(); if ($row === null) { return null; } $encrypted = $this->resolveEncryptedToken($row); if ($encrypted === null || $encrypted === '') { return null; } return $this->cipher->decrypt($encrypted); } private function ensureRow(): void { $statement = $this->pdo->prepare( 'INSERT INTO inpost_integration_settings (id, created_at, updated_at) VALUES (1, NOW(), NOW()) ON DUPLICATE KEY UPDATE updated_at = VALUES(updated_at)' ); $statement->execute(); } /** * @return array|null */ private function fetchRow(): ?array { try { $statement = $this->pdo->prepare('SELECT * FROM inpost_integration_settings WHERE id = 1 LIMIT 1'); $statement->execute(); $row = $statement->fetch(PDO::FETCH_ASSOC); } catch (Throwable) { return null; } return is_array($row) ? $row : null; } /** * @return array */ private function defaultSettings(): array { return [ 'has_api_token' => false, 'organization_id' => '', 'environment' => 'sandbox', 'default_dispatch_method' => 'pop', 'default_dispatch_point' => '', 'default_insurance' => null, 'default_locker_size' => 'small', 'default_courier_length' => 20, 'default_courier_width' => 15, 'default_courier_height' => 8, 'label_format' => 'Pdf', 'weekend_delivery' => false, 'auto_insurance_value' => false, 'multi_parcel' => false, ]; } private function resolveEncryptedToken(array $row): ?string { $integrationId = $this->ensureBaseIntegration(); $fromBase = $this->integrations->getApiKeyEncrypted($integrationId); if ($fromBase !== null && $fromBase !== '') { return $fromBase; } $legacy = trim((string) ($row['api_token_encrypted'] ?? '')); return $legacy === '' ? null : $legacy; } private function ensureBaseIntegration(): int { return $this->integrations->ensureIntegration( self::INTEGRATION_TYPE, self::INTEGRATION_NAME, self::INTEGRATION_BASE_URL, 20, true ); } }