feat(117): smsplanet integration settings
This commit is contained in:
@@ -3,7 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Settings;
|
||||
|
||||
use AppCorexceptionsIntegrationConfigException;
|
||||
use App\Core\Exceptions\IntegrationConfigException;
|
||||
|
||||
final class IntegrationSecretCipher
|
||||
{
|
||||
|
||||
@@ -23,7 +23,8 @@ final class IntegrationsHubController
|
||||
private readonly InpostIntegrationRepository $inpost,
|
||||
private readonly ShopproIntegrationsRepository $shoppro,
|
||||
private readonly FakturowniaIntegrationRepository $fakturownia,
|
||||
private readonly HostedSmsIntegrationRepository $hostedSms
|
||||
private readonly HostedSmsIntegrationRepository $hostedSms,
|
||||
private readonly SmsplanetIntegrationRepository $smsplanet
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -37,6 +38,7 @@ final class IntegrationsHubController
|
||||
$this->buildShopproRow(),
|
||||
$this->buildFakturowniaRow(),
|
||||
$this->buildHostedSmsRow(),
|
||||
$this->buildSmsplanetRow(),
|
||||
];
|
||||
|
||||
$html = $this->template->render('settings/integrations', [
|
||||
@@ -242,4 +244,33 @@ final class IntegrationsHubController
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function buildSmsplanetRow(): array
|
||||
{
|
||||
$settings = $this->smsplanet->getSettings();
|
||||
$authMethod = (string) ($settings['auth_method'] ?? 'token');
|
||||
$isConfigured = !empty($settings['sender'])
|
||||
&& (
|
||||
($authMethod === 'token' && !empty($settings['has_api_token']))
|
||||
|| ($authMethod === 'key_password' && !empty($settings['has_api_key']) && !empty($settings['has_api_password']))
|
||||
);
|
||||
|
||||
return [
|
||||
'provider' => $this->translator->get('settings.integrations_hub.providers.smsplanet'),
|
||||
'instance' => 'SMSPLANET',
|
||||
'authorization_status' => $isConfigured
|
||||
? $this->translator->get('settings.integrations_hub.status.configured')
|
||||
: $this->translator->get('settings.integrations_hub.status.not_configured'),
|
||||
'secret_status' => $isConfigured
|
||||
? $this->translator->get('settings.integrations_hub.status.saved')
|
||||
: $this->translator->get('settings.integrations_hub.status.missing'),
|
||||
'is_active' => !empty($settings['is_active']),
|
||||
'last_test_at' => trim((string) ($settings['last_test_at'] ?? '')),
|
||||
'configure_url' => '/settings/integrations/smsplanet',
|
||||
'configure_label' => $this->translator->get('settings.integrations_hub.actions.configure'),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
145
src/Modules/Settings/SmsplanetApiClient.php
Normal file
145
src/Modules/Settings/SmsplanetApiClient.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Settings;
|
||||
|
||||
use App\Core\Http\SslCertificateResolver;
|
||||
|
||||
final class SmsplanetApiClient
|
||||
{
|
||||
private const API_URL = 'https://api2.smsplanet.pl/sms';
|
||||
private const AUTH_TOKEN = 'token';
|
||||
|
||||
public function __construct(private readonly int $timeoutSeconds = 15)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $credentials
|
||||
* @return array{ok: bool, http_code: int, message: string, message_id: string}
|
||||
*/
|
||||
public function sendSms(array $credentials, string $phone, string $message): array
|
||||
{
|
||||
$payload = [
|
||||
'from' => trim((string) ($credentials['sender'] ?? '')),
|
||||
'to' => trim($phone),
|
||||
'msg' => $message,
|
||||
];
|
||||
|
||||
if (!empty($credentials['clear_polish'])) {
|
||||
$payload['clear_polish'] = '1';
|
||||
}
|
||||
if (!empty($credentials['transactional'])) {
|
||||
$payload['transactional'] = '1';
|
||||
}
|
||||
|
||||
$headers = [];
|
||||
if (($credentials['auth_method'] ?? '') === self::AUTH_TOKEN) {
|
||||
$headers[] = 'Authorization: Bearer ' . trim((string) ($credentials['api_token'] ?? ''));
|
||||
} else {
|
||||
$payload['key'] = trim((string) ($credentials['api_key'] ?? ''));
|
||||
$payload['password'] = (string) ($credentials['api_password'] ?? '');
|
||||
}
|
||||
|
||||
[$body, $httpCode, $curlError] = $this->postForm($payload, $headers);
|
||||
if ($curlError !== null) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'http_code' => $httpCode,
|
||||
'message' => 'Blad polaczenia: ' . $curlError,
|
||||
'message_id' => '',
|
||||
];
|
||||
}
|
||||
|
||||
return $this->parseResponse($body, $httpCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $payload
|
||||
* @param array<int, string> $extraHeaders
|
||||
* @return array{0: string, 1: int, 2: ?string}
|
||||
*/
|
||||
private function postForm(array $payload, array $extraHeaders): array
|
||||
{
|
||||
$ch = curl_init(self::API_URL);
|
||||
if ($ch === false) {
|
||||
return ['', 0, 'Nie udalo sie zainicjowac cURL.'];
|
||||
}
|
||||
|
||||
$headers = array_merge([
|
||||
'Accept: application/json',
|
||||
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
|
||||
'User-Agent: orderPRO/1.0',
|
||||
], $extraHeaders);
|
||||
|
||||
$options = [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => http_build_query($payload),
|
||||
CURLOPT_TIMEOUT => $this->timeoutSeconds,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_SSL_VERIFYPEER => true,
|
||||
CURLOPT_SSL_VERIFYHOST => 2,
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
];
|
||||
|
||||
$caPath = SslCertificateResolver::resolve();
|
||||
if ($caPath !== null) {
|
||||
$options[CURLOPT_CAINFO] = $caPath;
|
||||
}
|
||||
|
||||
curl_setopt_array($ch, $options);
|
||||
$rawBody = curl_exec($ch);
|
||||
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curlError = curl_error($ch);
|
||||
unset($ch);
|
||||
|
||||
if ($rawBody === false) {
|
||||
return ['', $httpCode, $curlError !== '' ? $curlError : 'Brak odpowiedzi z API.'];
|
||||
}
|
||||
|
||||
return [(string) $rawBody, $httpCode, null];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{ok: bool, http_code: int, message: string, message_id: string}
|
||||
*/
|
||||
private function parseResponse(string $body, int $httpCode): array
|
||||
{
|
||||
$decoded = json_decode(ltrim($body, "\xEF\xBB\xBF \t\n\r\0\x0B"), true);
|
||||
if (!is_array($decoded)) {
|
||||
return [
|
||||
'ok' => false,
|
||||
'http_code' => $httpCode,
|
||||
'message' => 'Niepoprawna odpowiedz JSON SMSPLANET: ' . substr(trim(strip_tags($body)), 0, 180),
|
||||
'message_id' => '',
|
||||
];
|
||||
}
|
||||
|
||||
$messageId = trim((string) ($decoded['messageId'] ?? ''));
|
||||
if ($httpCode >= 200 && $httpCode < 300 && $messageId !== '') {
|
||||
return [
|
||||
'ok' => true,
|
||||
'http_code' => $httpCode,
|
||||
'message' => 'messageId: ' . $messageId,
|
||||
'message_id' => $messageId,
|
||||
];
|
||||
}
|
||||
|
||||
$errorCode = trim((string) ($decoded['errorCode'] ?? ''));
|
||||
$errorMessage = trim((string) ($decoded['errorMsg'] ?? ''));
|
||||
if ($errorMessage === '') {
|
||||
$errorMessage = 'HTTP ' . $httpCode;
|
||||
}
|
||||
if ($errorCode !== '') {
|
||||
$errorMessage = 'errorCode ' . $errorCode . ': ' . $errorMessage;
|
||||
}
|
||||
|
||||
return [
|
||||
'ok' => false,
|
||||
'http_code' => $httpCode,
|
||||
'message' => $errorMessage,
|
||||
'message_id' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
145
src/Modules/Settings/SmsplanetIntegrationController.php
Normal file
145
src/Modules/Settings/SmsplanetIntegrationController.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Settings;
|
||||
|
||||
use App\Core\Exceptions\IntegrationConfigException;
|
||||
use App\Core\Http\RedirectPathResolver;
|
||||
use App\Core\Http\Request;
|
||||
use App\Core\Http\Response;
|
||||
use App\Core\I18n\Translator;
|
||||
use App\Core\Security\Csrf;
|
||||
use App\Core\Support\Flash;
|
||||
use App\Core\View\Template;
|
||||
use App\Modules\Auth\AuthService;
|
||||
use Throwable;
|
||||
|
||||
final class SmsplanetIntegrationController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Template $template,
|
||||
private readonly Translator $translator,
|
||||
private readonly AuthService $auth,
|
||||
private readonly SmsplanetIntegrationRepository $repository,
|
||||
private readonly SmsplanetApiClient $apiClient,
|
||||
private readonly IntegrationsRepository $integrations
|
||||
) {
|
||||
}
|
||||
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$html = $this->template->render('settings/smsplanet', [
|
||||
'title' => $this->translator->get('settings.smsplanet.title'),
|
||||
'activeMenu' => 'settings',
|
||||
'activeSettings' => 'integrations',
|
||||
'user' => $this->auth->user(),
|
||||
'csrfToken' => Csrf::token(),
|
||||
'settings' => $this->repository->getSettings(),
|
||||
'errorMessage' => (string) Flash::get('settings_error', ''),
|
||||
'successMessage' => (string) Flash::get('settings_success', ''),
|
||||
'testMessage' => (string) Flash::get('smsplanet_test', ''),
|
||||
], 'layouts/app');
|
||||
|
||||
return Response::html($html);
|
||||
}
|
||||
|
||||
public function save(Request $request): Response
|
||||
{
|
||||
$redirectTo = $this->resolveRedirect($request);
|
||||
if (!Csrf::validate((string) $request->input('_token', ''))) {
|
||||
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
|
||||
return Response::redirect($redirectTo);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->repository->saveSettings([
|
||||
'auth_method' => (string) $request->input('auth_method', ''),
|
||||
'api_token' => (string) $request->input('api_token', ''),
|
||||
'api_key' => (string) $request->input('api_key', ''),
|
||||
'api_password' => (string) $request->input('api_password', ''),
|
||||
'sender' => (string) $request->input('sender', ''),
|
||||
'clear_polish' => $request->input('clear_polish', ''),
|
||||
'transactional' => $request->input('transactional', ''),
|
||||
'is_active' => $request->input('is_active', ''),
|
||||
]);
|
||||
Flash::set('settings_success', $this->translator->get('settings.smsplanet.flash.saved'));
|
||||
} catch (Throwable $exception) {
|
||||
Flash::set(
|
||||
'settings_error',
|
||||
$this->translator->get('settings.smsplanet.flash.save_failed') . ' ' . $exception->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
return Response::redirect($redirectTo);
|
||||
}
|
||||
|
||||
public function test(Request $request): Response
|
||||
{
|
||||
$redirectTo = $this->resolveRedirect($request);
|
||||
if (!Csrf::validate((string) $request->input('_token', ''))) {
|
||||
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
|
||||
return Response::redirect($redirectTo);
|
||||
}
|
||||
|
||||
try {
|
||||
$phone = $this->validatePhone((string) $request->input('phone', ''));
|
||||
$message = $this->validateMessage((string) $request->input('message', ''));
|
||||
$credentials = $this->repository->getCredentials();
|
||||
if ($credentials === null) {
|
||||
throw new IntegrationConfigException('Najpierw zapisz kompletna i aktywna konfiguracje SMSPLANET.');
|
||||
}
|
||||
|
||||
$result = $this->apiClient->sendSms($credentials, $phone, $message);
|
||||
$this->integrations->updateTestResult(
|
||||
$credentials['integration_id'],
|
||||
$result['ok'] ? 'ok' : 'fail',
|
||||
(int) $result['http_code'],
|
||||
(string) $result['message']
|
||||
);
|
||||
|
||||
if ($result['ok']) {
|
||||
Flash::set('smsplanet_test', $this->translator->get('settings.smsplanet.flash.test_success', [
|
||||
'message_id' => (string) $result['message_id'],
|
||||
]));
|
||||
} else {
|
||||
Flash::set('settings_error', $this->translator->get('settings.smsplanet.flash.test_failed') . ' ' . $result['message']);
|
||||
}
|
||||
} catch (Throwable $exception) {
|
||||
Flash::set('settings_error', $this->translator->get('settings.smsplanet.flash.test_failed') . ' ' . $exception->getMessage());
|
||||
}
|
||||
|
||||
return Response::redirect($redirectTo);
|
||||
}
|
||||
|
||||
private function resolveRedirect(Request $request): string
|
||||
{
|
||||
return RedirectPathResolver::resolve(
|
||||
(string) $request->input('return_to', '/settings/integrations/smsplanet'),
|
||||
['/settings/integrations'],
|
||||
'/settings/integrations/smsplanet'
|
||||
);
|
||||
}
|
||||
|
||||
private function validatePhone(string $value): string
|
||||
{
|
||||
$phone = preg_replace('/[\s+\-()]/', '', trim($value)) ?? '';
|
||||
if (preg_match('/^\d{8,15}$/', $phone) !== 1) {
|
||||
throw new IntegrationConfigException('Podaj numer telefonu w formacie 600111222 albo 48600111222.');
|
||||
}
|
||||
|
||||
return $phone;
|
||||
}
|
||||
|
||||
private function validateMessage(string $value): string
|
||||
{
|
||||
$message = trim($value);
|
||||
if ($message === '') {
|
||||
throw new IntegrationConfigException('Podaj tresc testowego SMS.');
|
||||
}
|
||||
if (strlen($message) > 918) {
|
||||
throw new IntegrationConfigException('Tresc testowego SMS nie moze przekraczac 918 znakow.');
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
330
src/Modules/Settings/SmsplanetIntegrationRepository.php
Normal file
330
src/Modules/Settings/SmsplanetIntegrationRepository.php
Normal file
@@ -0,0 +1,330 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Modules\Settings;
|
||||
|
||||
use App\Core\Exceptions\IntegrationConfigException;
|
||||
use App\Core\Support\StringHelper;
|
||||
use PDO;
|
||||
use Throwable;
|
||||
|
||||
final class SmsplanetIntegrationRepository
|
||||
{
|
||||
private const INTEGRATION_TYPE = 'smsplanet';
|
||||
private const INTEGRATION_NAME = 'SMSPLANET';
|
||||
private const INTEGRATION_BASE_URL = 'https://api2.smsplanet.pl/sms';
|
||||
private const AUTH_TOKEN = 'token';
|
||||
private const AUTH_KEY_PASSWORD = 'key_password';
|
||||
|
||||
private readonly IntegrationsRepository $integrations;
|
||||
private readonly IntegrationSecretCipher $cipher;
|
||||
|
||||
public function __construct(
|
||||
private readonly PDO $pdo,
|
||||
private readonly string $secret
|
||||
) {
|
||||
$this->integrations = new IntegrationsRepository($this->pdo);
|
||||
$this->cipher = new IntegrationSecretCipher($this->secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getSettings(): array
|
||||
{
|
||||
$this->ensureRow();
|
||||
$integrationId = $this->ensureBaseIntegration();
|
||||
$row = $this->fetchRow() ?? [];
|
||||
$integration = $this->integrations->findById($integrationId);
|
||||
|
||||
return [
|
||||
'integration_id' => $integrationId,
|
||||
'auth_method' => $this->normalizeAuthMethod((string) ($row['auth_method'] ?? '')),
|
||||
'sender' => trim((string) ($row['sender'] ?? '')),
|
||||
'clear_polish' => !empty($row['clear_polish']),
|
||||
'transactional' => !empty($row['transactional']),
|
||||
'has_api_token' => $this->hasEncryptedValue($row['api_token_encrypted'] ?? null),
|
||||
'has_api_key' => $this->hasEncryptedValue($row['api_key_encrypted'] ?? null),
|
||||
'has_api_password' => $this->hasEncryptedValue($row['api_password_encrypted'] ?? null),
|
||||
'is_active' => (int) ($integration['is_active'] ?? 1) === 1,
|
||||
'last_test_status' => trim((string) ($integration['last_test_status'] ?? '')),
|
||||
'last_test_http_code' => isset($integration['last_test_http_code']) ? (int) $integration['last_test_http_code'] : null,
|
||||
'last_test_message' => trim((string) ($integration['last_test_message'] ?? '')),
|
||||
'last_test_at' => trim((string) ($integration['last_test_at'] ?? '')),
|
||||
'updated_at' => trim((string) ($row['updated_at'] ?? '')),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $payload
|
||||
*/
|
||||
public function saveSettings(array $payload): void
|
||||
{
|
||||
$this->ensureRow();
|
||||
$integrationId = $this->ensureBaseIntegration();
|
||||
$row = $this->fetchRequiredRow();
|
||||
|
||||
$authMethod = $this->normalizeAuthMethod((string) ($payload['auth_method'] ?? ''));
|
||||
$sender = $this->validateSender((string) ($payload['sender'] ?? ''));
|
||||
$tokenEncrypted = $this->resolveTokenEncrypted($row, (string) ($payload['api_token'] ?? ''));
|
||||
$keyEncrypted = $this->resolveKeyEncrypted($row, (string) ($payload['api_key'] ?? ''));
|
||||
$passwordEncrypted = $this->resolvePasswordEncrypted($row, (string) ($payload['api_password'] ?? ''));
|
||||
|
||||
$this->validateCredentials($authMethod, $tokenEncrypted, $keyEncrypted, $passwordEncrypted);
|
||||
$this->updateSettingsRow($authMethod, $tokenEncrypted, $keyEncrypted, $passwordEncrypted, $sender, $payload);
|
||||
$this->updateIntegrationActive($integrationId, !empty($payload['is_active']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* integration_id: int,
|
||||
* auth_method: string,
|
||||
* api_token: string,
|
||||
* api_key: string,
|
||||
* api_password: string,
|
||||
* sender: string,
|
||||
* clear_polish: bool,
|
||||
* transactional: bool
|
||||
* }|null
|
||||
*/
|
||||
public function getCredentials(): ?array
|
||||
{
|
||||
$this->ensureRow();
|
||||
$integrationId = $this->ensureBaseIntegration();
|
||||
$row = $this->fetchRow();
|
||||
$integration = $this->integrations->findById($integrationId);
|
||||
if ($row === null || (int) ($integration['is_active'] ?? 0) !== 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$authMethod = $this->normalizeAuthMethod((string) ($row['auth_method'] ?? ''));
|
||||
$sender = trim((string) ($row['sender'] ?? ''));
|
||||
$apiToken = $this->decryptValue((string) ($row['api_token_encrypted'] ?? ''));
|
||||
$apiKey = $this->decryptValue((string) ($row['api_key_encrypted'] ?? ''));
|
||||
$apiPassword = $this->decryptValue((string) ($row['api_password_encrypted'] ?? ''));
|
||||
|
||||
if (!$this->hasCompleteCredentials($authMethod, $sender, $apiToken, $apiKey, $apiPassword)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'integration_id' => $integrationId,
|
||||
'auth_method' => $authMethod,
|
||||
'api_token' => $apiToken,
|
||||
'api_key' => $apiKey,
|
||||
'api_password' => $apiPassword,
|
||||
'sender' => $sender,
|
||||
'clear_polish' => !empty($row['clear_polish']),
|
||||
'transactional' => !empty($row['transactional']),
|
||||
];
|
||||
}
|
||||
|
||||
private function ensureBaseIntegration(): int
|
||||
{
|
||||
return $this->integrations->ensureIntegration(
|
||||
self::INTEGRATION_TYPE,
|
||||
self::INTEGRATION_NAME,
|
||||
self::INTEGRATION_BASE_URL,
|
||||
15,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
private function ensureRow(): void
|
||||
{
|
||||
$integrationId = $this->ensureBaseIntegration();
|
||||
$statement = $this->pdo->prepare(
|
||||
'INSERT INTO smsplanet_integration_settings (id, integration_id, created_at, updated_at)
|
||||
VALUES (1, :integration_id, NOW(), NOW())
|
||||
ON DUPLICATE KEY UPDATE integration_id = VALUES(integration_id), updated_at = VALUES(updated_at)'
|
||||
);
|
||||
$statement->execute(['integration_id' => $integrationId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private function fetchRow(): ?array
|
||||
{
|
||||
try {
|
||||
$statement = $this->pdo->prepare('SELECT * FROM smsplanet_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 fetchRequiredRow(): array
|
||||
{
|
||||
$row = $this->fetchRow();
|
||||
if ($row === null) {
|
||||
throw new IntegrationConfigException('Brak rekordu konfiguracji SMSPLANET.');
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function normalizeAuthMethod(string $value): string
|
||||
{
|
||||
return $value === self::AUTH_KEY_PASSWORD ? self::AUTH_KEY_PASSWORD : self::AUTH_TOKEN;
|
||||
}
|
||||
|
||||
private function validateSender(string $value): string
|
||||
{
|
||||
$sender = trim($value);
|
||||
if ($sender === '' || strlen($sender) > 32) {
|
||||
throw new IntegrationConfigException('Podaj pole nadawcy SMSPLANET (maks. 32 znaki).');
|
||||
}
|
||||
|
||||
return $sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $row
|
||||
*/
|
||||
private function resolveTokenEncrypted(array $row, string $newToken): ?string
|
||||
{
|
||||
$token = trim($newToken);
|
||||
if ($token !== '') {
|
||||
return $this->cipher->encrypt($token);
|
||||
}
|
||||
|
||||
return StringHelper::nullableString((string) ($row['api_token_encrypted'] ?? ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $row
|
||||
*/
|
||||
private function resolveKeyEncrypted(array $row, string $newKey): ?string
|
||||
{
|
||||
$key = trim($newKey);
|
||||
if ($key !== '') {
|
||||
return $this->cipher->encrypt($key);
|
||||
}
|
||||
|
||||
return StringHelper::nullableString((string) ($row['api_key_encrypted'] ?? ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $row
|
||||
*/
|
||||
private function resolvePasswordEncrypted(array $row, string $newPassword): ?string
|
||||
{
|
||||
$password = trim($newPassword);
|
||||
if ($password !== '') {
|
||||
return $this->cipher->encrypt($password);
|
||||
}
|
||||
|
||||
return StringHelper::nullableString((string) ($row['api_password_encrypted'] ?? ''));
|
||||
}
|
||||
|
||||
private function validateCredentials(
|
||||
string $authMethod,
|
||||
?string $tokenEncrypted,
|
||||
?string $keyEncrypted,
|
||||
?string $passwordEncrypted
|
||||
): void {
|
||||
if ($authMethod === self::AUTH_TOKEN && ($tokenEncrypted === null || $tokenEncrypted === '')) {
|
||||
throw new IntegrationConfigException('Podaj token Bearer SMSPLANET.');
|
||||
}
|
||||
|
||||
if ($authMethod !== self::AUTH_KEY_PASSWORD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($keyEncrypted === null || $keyEncrypted === '') {
|
||||
throw new IntegrationConfigException('Podaj klucz API SMSPLANET.');
|
||||
}
|
||||
if ($passwordEncrypted === null || $passwordEncrypted === '') {
|
||||
throw new IntegrationConfigException('Podaj haslo API SMSPLANET.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $payload
|
||||
*/
|
||||
private function updateSettingsRow(
|
||||
string $authMethod,
|
||||
?string $tokenEncrypted,
|
||||
?string $keyEncrypted,
|
||||
?string $passwordEncrypted,
|
||||
string $sender,
|
||||
array $payload
|
||||
): void {
|
||||
$statement = $this->pdo->prepare(
|
||||
'UPDATE smsplanet_integration_settings
|
||||
SET auth_method = :auth_method,
|
||||
api_token_encrypted = :api_token_encrypted,
|
||||
api_key_encrypted = :api_key_encrypted,
|
||||
api_password_encrypted = :api_password_encrypted,
|
||||
sender = :sender,
|
||||
clear_polish = :clear_polish,
|
||||
transactional = :transactional,
|
||||
updated_at = NOW()
|
||||
WHERE id = 1'
|
||||
);
|
||||
$statement->execute([
|
||||
'auth_method' => $authMethod,
|
||||
'api_token_encrypted' => $tokenEncrypted,
|
||||
'api_key_encrypted' => $keyEncrypted,
|
||||
'api_password_encrypted' => $passwordEncrypted,
|
||||
'sender' => $sender,
|
||||
'clear_polish' => !empty($payload['clear_polish']) ? 1 : 0,
|
||||
'transactional' => !empty($payload['transactional']) ? 1 : 0,
|
||||
]);
|
||||
}
|
||||
|
||||
private function updateIntegrationActive(int $integrationId, bool $isActive): void
|
||||
{
|
||||
$statement = $this->pdo->prepare(
|
||||
'UPDATE integrations
|
||||
SET is_active = :is_active,
|
||||
updated_at = NOW()
|
||||
WHERE id = :id AND type = :type'
|
||||
);
|
||||
$statement->execute([
|
||||
'id' => $integrationId,
|
||||
'type' => self::INTEGRATION_TYPE,
|
||||
'is_active' => $isActive ? 1 : 0,
|
||||
]);
|
||||
}
|
||||
|
||||
private function hasEncryptedValue(mixed $value): bool
|
||||
{
|
||||
return trim((string) $value) !== '';
|
||||
}
|
||||
|
||||
private function decryptValue(string $encrypted): string
|
||||
{
|
||||
$value = StringHelper::nullableString($encrypted);
|
||||
if ($value === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return trim((string) $this->cipher->decrypt($value));
|
||||
}
|
||||
|
||||
private function hasCompleteCredentials(
|
||||
string $authMethod,
|
||||
string $sender,
|
||||
string $apiToken,
|
||||
string $apiKey,
|
||||
string $apiPassword
|
||||
): bool {
|
||||
if ($sender === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($authMethod === self::AUTH_TOKEN) {
|
||||
return $apiToken !== '';
|
||||
}
|
||||
|
||||
return $apiKey !== '' && $apiPassword !== '';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user