- Implement AllegroShipmentService for managing shipment creation and status checks. - Create ShipmentController to handle shipment preparation and label downloading. - Introduce ShipmentPackageRepository for database interactions related to shipment packages. - Add methods for retrieving delivery services, creating shipments, checking creation status, and downloading labels. - Implement address validation and token management for Allegro API integration.
125 lines
3.4 KiB
PHP
125 lines
3.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Modules\Settings;
|
|
|
|
use PDO;
|
|
use RuntimeException;
|
|
use Throwable;
|
|
|
|
final class ApaczkaIntegrationRepository
|
|
{
|
|
public function __construct(
|
|
private readonly PDO $pdo,
|
|
private readonly string $secret
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function getSettings(): array
|
|
{
|
|
$row = $this->fetchRow();
|
|
if ($row === null) {
|
|
return $this->defaultSettings();
|
|
}
|
|
|
|
return [
|
|
'has_api_key' => trim((string) ($row['api_key_encrypted'] ?? '')) !== '',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $payload
|
|
*/
|
|
public function saveSettings(array $payload): void
|
|
{
|
|
$this->ensureRow();
|
|
$current = $this->fetchRow();
|
|
if ($current === null) {
|
|
throw new RuntimeException('Brak rekordu konfiguracji Apaczka.');
|
|
}
|
|
|
|
$apiKey = trim((string) ($payload['api_key'] ?? ''));
|
|
$apiKeyEncrypted = trim((string) ($current['api_key_encrypted'] ?? ''));
|
|
if ($apiKey !== '') {
|
|
$apiKeyEncrypted = (string) $this->encrypt($apiKey);
|
|
}
|
|
|
|
$statement = $this->pdo->prepare(
|
|
'UPDATE apaczka_integration_settings
|
|
SET api_key_encrypted = :api_key_encrypted,
|
|
updated_at = NOW()
|
|
WHERE id = 1'
|
|
);
|
|
$statement->execute([
|
|
'api_key_encrypted' => $this->nullableString($apiKeyEncrypted),
|
|
]);
|
|
}
|
|
|
|
private function ensureRow(): void
|
|
{
|
|
$statement = $this->pdo->prepare(
|
|
'INSERT INTO apaczka_integration_settings (id, created_at, updated_at)
|
|
VALUES (1, NOW(), NOW())
|
|
ON DUPLICATE KEY UPDATE updated_at = VALUES(updated_at)'
|
|
);
|
|
$statement->execute();
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>|null
|
|
*/
|
|
private function fetchRow(): ?array
|
|
{
|
|
try {
|
|
$statement = $this->pdo->prepare('SELECT * FROM apaczka_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<string, mixed>
|
|
*/
|
|
private function defaultSettings(): array
|
|
{
|
|
return [
|
|
'has_api_key' => false,
|
|
];
|
|
}
|
|
|
|
private function nullableString(string $value): ?string
|
|
{
|
|
$trimmed = trim($value);
|
|
return $trimmed === '' ? null : $trimmed;
|
|
}
|
|
|
|
private function encrypt(string $plainText): ?string
|
|
{
|
|
$value = trim($plainText);
|
|
if ($value === '') {
|
|
return null;
|
|
}
|
|
if ($this->secret === '') {
|
|
throw new RuntimeException('Brak INTEGRATIONS_SECRET do szyfrowania danych integracji.');
|
|
}
|
|
|
|
$encryptionKey = hash('sha256', 'enc|' . $this->secret, true);
|
|
$hmacKey = hash('sha256', 'auth|' . $this->secret, true);
|
|
$iv = random_bytes(16);
|
|
$cipherRaw = openssl_encrypt($value, 'AES-256-CBC', $encryptionKey, OPENSSL_RAW_DATA, $iv);
|
|
if ($cipherRaw === false) {
|
|
throw new RuntimeException('Nie udalo sie zaszyfrowac danych integracji.');
|
|
}
|
|
|
|
$mac = hash_hmac('sha256', $iv . $cipherRaw, $hmacKey, true);
|
|
return 'v1:' . base64_encode($iv . $mac . $cipherRaw);
|
|
}
|
|
}
|