feat(06-sonarqube-quality): extract string literals to constants (S1192 fix)

- Add IntegrationSources {ALLEGRO, SHOPPRO, APACZKA, INPOST} and RedirectPaths constants in src/Core/Constants/
- Replace integration source literals in AllegroOrderImportService, AllegroStatusSyncService, ShopproOrdersSyncService, ShopproPaymentStatusSyncService
- Replace redirect path literals in AllegroIntegrationController (24+ occurrences) and ShopproIntegrationsController (3 occurrences)
- Auto-fix: broken use statements from plan 06-01 in AllegroOrderImportService and AllegroIntegrationController (missing backslashes)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 11:28:23 +01:00
parent 3c27c4e54a
commit d7d3f996cc
8 changed files with 82 additions and 46 deletions

View File

@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace App\Core\Constants;
final class IntegrationSources
{
public const ALLEGRO = 'allegro';
public const SHOPPRO = 'shoppro';
public const APACZKA = 'apaczka';
public const INPOST = 'inpost';
}

View File

@@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace App\Core\Constants;
final class RedirectPaths
{
public const ALLEGRO_INTEGRATION = '/settings/integrations/allegro';
public const ALLEGRO_SETTINGS_TAB = '/settings/integrations/allegro?tab=settings';
public const ALLEGRO_STATUSES_TAB = '/settings/integrations/allegro?tab=statuses';
public const ALLEGRO_DELIVERY_TAB = '/settings/integrations/allegro?tab=delivery';
public const ALLEGRO_OAUTH_CALLBACK_PATH = '/settings/integrations/allegro/oauth/callback';
public const SHOPPRO_INTEGRATION = '/settings/integrations/shoppro';
}

View File

@@ -13,8 +13,10 @@ use App\Modules\Auth\AuthService;
use App\Modules\Cron\CronRepository;
use DateInterval;
use DateTimeImmutable;
use App\Core\Constants\IntegrationSources;
use App\Core\Constants\RedirectPaths;
use App\Core\Exceptions\IntegrationConfigException;
use RuntimeException;
use AppCoreExceptionsIntegrationConfigException;
use Throwable;
final class AllegroIntegrationController
@@ -99,8 +101,8 @@ final class AllegroIntegrationController
'errorMessage' => (string) Flash::get('settings_error', ''),
'successMessage' => (string) Flash::get('settings_success', ''),
'warningMessage' => (string) Flash::get('settings_warning', ''),
'deliveryMappings' => $this->deliveryMappings !== null ? $this->deliveryMappings->listMappings('allegro', 0) : [],
'orderDeliveryMethods' => $this->deliveryMappings !== null ? $this->deliveryMappings->getDistinctOrderDeliveryMethods('allegro', 0) : [],
'deliveryMappings' => $this->deliveryMappings !== null ? $this->deliveryMappings->listMappings(IntegrationSources::ALLEGRO, 0) : [],
'orderDeliveryMethods' => $this->deliveryMappings !== null ? $this->deliveryMappings->getDistinctOrderDeliveryMethods(IntegrationSources::ALLEGRO, 0) : [],
'allegroDeliveryServices' => $deliveryServicesData[0],
'apaczkaDeliveryServices' => $deliveryServicesData[1],
'allegroDeliveryServicesError' => $deliveryServicesData[2],
@@ -115,7 +117,7 @@ final class AllegroIntegrationController
public function save(Request $request): Response
{
$redirectTo = $this->resolveRedirectPath((string) $request->input('return_to', '/settings/integrations/allegro'));
$redirectTo = $this->resolveRedirectPath((string) $request->input('return_to', RedirectPaths::ALLEGRO_INTEGRATION));
if (!Csrf::validate((string) $request->input('_token', ''))) {
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
return Response::redirect($redirectTo);
@@ -178,7 +180,7 @@ final class AllegroIntegrationController
$intervalMinutes = max(1, min(1440, $intervalMinutesRaw));
if ($intervalMinutesRaw !== $intervalMinutes) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.orders_import_interval_invalid'));
return Response::redirect('/settings/integrations/allegro?tab=settings');
return Response::redirect(RedirectPaths::ALLEGRO_SETTINGS_TAB);
}
$statusSyncDirection = trim((string) $request->input(
@@ -187,7 +189,7 @@ final class AllegroIntegrationController
));
if (!in_array($statusSyncDirection, $this->allowedStatusSyncDirections(), true)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.status_sync_direction_invalid'));
return Response::redirect('/settings/integrations/allegro?tab=settings');
return Response::redirect(RedirectPaths::ALLEGRO_SETTINGS_TAB);
}
$statusSyncIntervalRaw = (int) $request->input(
@@ -197,7 +199,7 @@ final class AllegroIntegrationController
$statusSyncInterval = max(1, min(1440, $statusSyncIntervalRaw));
if ($statusSyncIntervalRaw !== $statusSyncInterval) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.status_sync_interval_invalid'));
return Response::redirect('/settings/integrations/allegro?tab=settings');
return Response::redirect(RedirectPaths::ALLEGRO_SETTINGS_TAB);
}
$existing = $this->findImportSchedule();
@@ -243,7 +245,7 @@ final class AllegroIntegrationController
);
}
return Response::redirect('/settings/integrations/allegro?tab=settings');
return Response::redirect(RedirectPaths::ALLEGRO_SETTINGS_TAB);
}
public function saveStatusMapping(Request $request): Response
@@ -259,17 +261,17 @@ final class AllegroIntegrationController
if ($allegroStatusCode === '') {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.allegro_status_required'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
if ($orderproStatusCode === '') {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.orderpro_status_required'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
if (!$this->orderStatusCodeExists($orderproStatusCode)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.orderpro_status_not_found'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
try {
@@ -279,7 +281,7 @@ final class AllegroIntegrationController
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.save_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
public function saveStatusMappingsBulk(Request $request): Response
@@ -294,7 +296,7 @@ final class AllegroIntegrationController
$selectedOrderproCodes = $request->input('orderpro_status_code', []);
if (!is_array($codes) || !is_array($names) || !is_array($selectedOrderproCodes)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.save_failed'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
try {
@@ -310,7 +312,7 @@ final class AllegroIntegrationController
if ($orderproStatusCode !== null && !$this->orderStatusCodeExists($orderproStatusCode)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.orderpro_status_not_found'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
$this->statusMappings->upsertMapping(
@@ -325,7 +327,7 @@ final class AllegroIntegrationController
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.save_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
public function deleteStatusMapping(Request $request): Response
@@ -338,7 +340,7 @@ final class AllegroIntegrationController
$mappingId = max(0, (int) $request->input('mapping_id', 0));
if ($mappingId <= 0) {
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.mapping_not_found'));
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
try {
@@ -348,7 +350,7 @@ final class AllegroIntegrationController
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.delete_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
public function syncStatusesFromAllegro(Request $request): Response
@@ -371,7 +373,7 @@ final class AllegroIntegrationController
Flash::set('settings_error', $this->translator->get('settings.allegro.statuses.flash.sync_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro?tab=statuses');
return Response::redirect(RedirectPaths::ALLEGRO_STATUSES_TAB);
}
public function startOAuth(Request $request): Response
@@ -397,7 +399,7 @@ final class AllegroIntegrationController
return Response::redirect($url);
} catch (Throwable $exception) {
Flash::set('settings_error', $exception->getMessage());
return Response::redirect('/settings/integrations/allegro');
return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
}
}
@@ -411,7 +413,7 @@ final class AllegroIntegrationController
$message .= ' ' . $description;
}
Flash::set('settings_error', $message);
return Response::redirect('/settings/integrations/allegro');
return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
}
$state = trim((string) $request->input('state', ''));
@@ -419,13 +421,13 @@ final class AllegroIntegrationController
unset($_SESSION[self::OAUTH_STATE_SESSION_KEY]);
if ($state === '' || $expectedState === '' || !hash_equals($expectedState, $state)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.flash.oauth_state_invalid'));
return Response::redirect('/settings/integrations/allegro');
return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
}
$authorizationCode = trim((string) $request->input('code', ''));
if ($authorizationCode === '') {
Flash::set('settings_error', $this->translator->get('settings.allegro.flash.oauth_code_missing'));
return Response::redirect('/settings/integrations/allegro');
return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
}
try {
@@ -458,7 +460,7 @@ final class AllegroIntegrationController
Flash::set('settings_error', $this->translator->get('settings.allegro.flash.oauth_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro');
return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
}
public function importSingleOrder(Request $request): Response
@@ -471,7 +473,7 @@ final class AllegroIntegrationController
$checkoutFormId = trim((string) $request->input('checkout_form_id', ''));
if ($checkoutFormId === '') {
Flash::set('settings_error', $this->translator->get('settings.allegro.flash.checkout_form_id_required'));
return Response::redirect('/settings/integrations/allegro');
return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
}
try {
@@ -504,7 +506,7 @@ final class AllegroIntegrationController
);
}
return Response::redirect('/settings/integrations/allegro');
return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
}
public function saveDeliveryMappings(Request $request): Response
@@ -516,7 +518,7 @@ final class AllegroIntegrationController
if ($this->deliveryMappings === null) {
Flash::set('settings_error', 'Delivery mappings not configured.');
return Response::redirect('/settings/integrations/allegro?tab=delivery');
return Response::redirect(RedirectPaths::ALLEGRO_DELIVERY_TAB);
}
$orderMethods = (array) $request->input('order_delivery_method', []);
@@ -549,13 +551,13 @@ final class AllegroIntegrationController
}
try {
$this->deliveryMappings->saveMappings('allegro', 0, $mappings);
$this->deliveryMappings->saveMappings(IntegrationSources::ALLEGRO, 0, $mappings);
Flash::set('settings_success', $this->translator->get('settings.allegro.delivery.flash.saved'));
} catch (Throwable $exception) {
Flash::set('settings_error', $this->translator->get('settings.allegro.delivery.flash.save_failed') . ' ' . $exception->getMessage());
}
return Response::redirect('/settings/integrations/allegro?tab=delivery');
return Response::redirect(RedirectPaths::ALLEGRO_DELIVERY_TAB);
}
/**
@@ -669,7 +671,7 @@ final class AllegroIntegrationController
$base = 'http://localhost:8000';
}
return rtrim($base, '/') . '/settings/integrations/allegro/oauth/callback';
return rtrim($base, '/') . RedirectPaths::ALLEGRO_OAUTH_CALLBACK_PATH;
}
private function validateCsrf(string $token): ?Response
@@ -679,17 +681,17 @@ final class AllegroIntegrationController
}
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
return Response::redirect('/settings/integrations/allegro');
return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
}
private function resolveRedirectPath(string $candidate): string
{
$value = trim($candidate);
if ($value === '') {
return '/settings/integrations/allegro';
return RedirectPaths::ALLEGRO_INTEGRATION;
}
if (!str_starts_with($value, '/settings/integrations')) {
return '/settings/integrations/allegro';
return RedirectPaths::ALLEGRO_INTEGRATION;
}
return $value;

View File

@@ -6,8 +6,8 @@ namespace App\Modules\Settings;
use App\Core\Support\StringHelper;
use App\Modules\Orders\OrderImportRepository;
use App\Modules\Orders\OrdersRepository;
use RuntimeException;
use AppCoreExceptionsAllegroApiException;
use App\Core\Constants\IntegrationSources;
use App\Core\Exceptions\AllegroApiException;
use Throwable;
final class AllegroOrderImportService
@@ -68,7 +68,7 @@ final class AllegroOrderImportService
'import',
$summary,
[
'source' => 'allegro',
'source' => IntegrationSources::ALLEGRO,
'source_order_id' => trim($checkoutFormId),
'created' => $wasCreated,
],
@@ -155,7 +155,7 @@ final class AllegroOrderImportService
$order = [
'integration_id' => $this->integrationRepository->getActiveIntegrationId(),
'source' => 'allegro',
'source' => IntegrationSources::ALLEGRO,
'source_order_id' => $checkoutFormId,
'external_order_id' => $checkoutFormId,
'external_platform_id' => trim((string) ($payload['marketplace']['id'] ?? 'allegro-pl')),

View File

@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace App\Modules\Settings;
use App\Core\Constants\IntegrationSources;
use App\Modules\Cron\CronRepository;
use PDO;
use Throwable;
@@ -94,7 +95,7 @@ final class AllegroStatusSyncService
ORDER BY source_updated_at DESC
LIMIT ' . self::MAX_ORDERS_PER_RUN
);
$params = array_merge(['allegro'], self::FINAL_STATUSES);
$params = array_merge([IntegrationSources::ALLEGRO], self::FINAL_STATUSES);
$statement->execute($params);
return $statement->fetchAll(PDO::FETCH_ASSOC) ?: [];

View File

@@ -13,6 +13,8 @@ use App\Modules\Auth\AuthService;
use App\Modules\Cron\CronRepository;
use DateInterval;
use DateTimeImmutable;
use App\Core\Constants\IntegrationSources;
use App\Core\Constants\RedirectPaths;
use RuntimeException;
use Throwable;
@@ -72,10 +74,10 @@ final class ShopproIntegrationsController
? $this->loadDeliveryServices()
: [[], [], ''];
$deliveryMappings = $selectedIntegration !== null
? $this->deliveryMappings->listMappings('shoppro', (int) ($selectedIntegration['id'] ?? 0))
? $this->deliveryMappings->listMappings(IntegrationSources::SHOPPRO, (int) ($selectedIntegration['id'] ?? 0))
: [];
$orderDeliveryMethods = $selectedIntegration !== null
? $this->deliveryMappings->getDistinctOrderDeliveryMethods('shoppro', (int) ($selectedIntegration['id'] ?? 0))
? $this->deliveryMappings->getDistinctOrderDeliveryMethods(IntegrationSources::SHOPPRO, (int) ($selectedIntegration['id'] ?? 0))
: [];
$html = $this->template->render('settings/shoppro', [
@@ -113,7 +115,7 @@ final class ShopproIntegrationsController
{
$integrationId = max(0, (int) $request->input('integration_id', 0));
$tab = $this->resolveTab((string) $request->input('tab', 'integration'));
$redirectBase = '/settings/integrations/shoppro';
$redirectBase = RedirectPaths::SHOPPRO_INTEGRATION;
$redirectTo = $this->buildRedirectUrl($integrationId, $tab);
if (!Csrf::validate((string) $request->input('_token', ''))) {
@@ -203,7 +205,7 @@ final class ShopproIntegrationsController
{
$integrationId = max(0, (int) $request->input('integration_id', 0));
$tab = $this->resolveTab((string) $request->input('tab', 'integration'));
$redirectBase = '/settings/integrations/shoppro';
$redirectBase = RedirectPaths::SHOPPRO_INTEGRATION;
$redirectTo = $this->buildRedirectUrl($integrationId, $tab);
if (!Csrf::validate((string) $request->input('_token', ''))) {
@@ -382,7 +384,7 @@ final class ShopproIntegrationsController
}
try {
$this->deliveryMappings->saveMappings('shoppro', $integrationId, $mappings);
$this->deliveryMappings->saveMappings(IntegrationSources::SHOPPRO, $integrationId, $mappings);
Flash::set('settings_success', $this->translator->get('settings.integrations.delivery.flash.saved'));
} catch (Throwable $exception) {
Flash::set(
@@ -585,7 +587,7 @@ final class ShopproIntegrationsController
private function buildRedirectUrl(int $integrationId, string $tab): string
{
$url = '/settings/integrations/shoppro';
$url = RedirectPaths::SHOPPRO_INTEGRATION;
$query = [];
if ($integrationId > 0) {
$query['id'] = (string) $integrationId;

View File

@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace App\Modules\Settings;
use App\Core\Constants\IntegrationSources;
use App\Core\Support\StringHelper;
use App\Modules\Orders\OrderImportRepository;
use App\Modules\Orders\OrdersRepository;
@@ -420,10 +421,10 @@ final class ShopproOrdersSyncService
$order = [
'integration_id' => $integrationId,
'source' => 'shoppro',
'source' => IntegrationSources::SHOPPRO,
'source_order_id' => $sourceOrderId,
'external_order_id' => $sourceOrderId,
'external_platform_id' => 'shoppro',
'external_platform_id' => IntegrationSources::SHOPPRO,
'external_platform_account_id' => null,
'external_status_id' => $effectiveStatus,
'external_payment_type_id' => StringHelper::nullableString((string) $this->readPath($payload, ['payment_method', 'payment.method', 'payments.method'])),

View File

@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace App\Modules\Settings;
use App\Core\Constants\IntegrationSources;
use App\Core\Support\StringHelper;
use App\Modules\Orders\OrdersRepository;
use PDO;
@@ -147,7 +148,7 @@ final class ShopproPaymentStatusSyncService
'(payment_status IS NULL OR payment_status <> :paid_status)',
];
$params = [
'source' => 'shoppro',
'source' => IntegrationSources::SHOPPRO,
'integration_id' => $integrationId,
'paid_status' => self::PAID_STATUS,
];