feat(06-sonarqube-quality): reduce return statements to ≤3 (S1142 fix)

Extract validation helpers in AllegroIntegrationController:
- validateSaveInput(): ?string (save: 6→3 returns)
- validateImportSettingsInput(): ?string (saveImportSettings: 5→3 returns)
- validateOAuthCallbackParams(): ?string (oauthCallback: 4→3 returns)

Extract validation helpers in ShopproIntegrationsController:
- validateSaveAccess(): ?Response (save: 9→3 returns)
- validateSaveInput(): ?string (save field validation)
- validateCsrfAndIntegrationAccess(): ?Response (saveStatusMappings/syncStatuses: 4→3 returns)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 11:57:18 +01:00
parent d7d3f996cc
commit 028c46c685
2 changed files with 143 additions and 82 deletions

View File

@@ -124,27 +124,14 @@ final class AllegroIntegrationController
} }
$environment = trim((string) $request->input('environment', 'sandbox')); $environment = trim((string) $request->input('environment', 'sandbox'));
if (!in_array($environment, ['sandbox', 'production'], true)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.environment_invalid'));
return Response::redirect($redirectTo);
}
$clientId = trim((string) $request->input('client_id', '')); $clientId = trim((string) $request->input('client_id', ''));
if ($clientId !== '' && mb_strlen($clientId) > 128) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.client_id_too_long'));
return Response::redirect($redirectTo);
}
$redirectUriInput = trim((string) $request->input('redirect_uri', '')); $redirectUriInput = trim((string) $request->input('redirect_uri', ''));
$redirectUri = $redirectUriInput !== '' ? $redirectUriInput : $this->defaultRedirectUri(); $redirectUri = $redirectUriInput !== '' ? $redirectUriInput : $this->defaultRedirectUri();
if (!$this->isValidHttpUrl($redirectUri)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.redirect_uri_invalid'));
return Response::redirect($redirectTo);
}
$ordersFetchStartDate = trim((string) $request->input('orders_fetch_start_date', '')); $ordersFetchStartDate = trim((string) $request->input('orders_fetch_start_date', ''));
if ($ordersFetchStartDate !== '' && !$this->isValidDate($ordersFetchStartDate)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.orders_fetch_start_date_invalid')); $validationError = $this->validateSaveInput($environment, $clientId, $redirectUri, $ordersFetchStartDate);
if ($validationError !== null) {
Flash::set('settings_error', $validationError);
return Response::redirect($redirectTo); return Response::redirect($redirectTo);
} }
@@ -178,27 +165,27 @@ final class AllegroIntegrationController
$intervalMinutesRaw = (int) $request->input('orders_import_interval_minutes', 5); $intervalMinutesRaw = (int) $request->input('orders_import_interval_minutes', 5);
$intervalMinutes = max(1, min(1440, $intervalMinutesRaw)); $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(RedirectPaths::ALLEGRO_SETTINGS_TAB);
}
$statusSyncDirection = trim((string) $request->input( $statusSyncDirection = trim((string) $request->input(
'status_sync_direction', 'status_sync_direction',
self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO
)); ));
if (!in_array($statusSyncDirection, $this->allowedStatusSyncDirections(), true)) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.status_sync_direction_invalid'));
return Response::redirect(RedirectPaths::ALLEGRO_SETTINGS_TAB);
}
$statusSyncIntervalRaw = (int) $request->input( $statusSyncIntervalRaw = (int) $request->input(
'status_sync_interval_minutes', 'status_sync_interval_minutes',
self::STATUS_SYNC_DEFAULT_INTERVAL_MINUTES self::STATUS_SYNC_DEFAULT_INTERVAL_MINUTES
); );
$statusSyncInterval = max(1, min(1440, $statusSyncIntervalRaw)); $statusSyncInterval = max(1, min(1440, $statusSyncIntervalRaw));
if ($statusSyncIntervalRaw !== $statusSyncInterval) {
Flash::set('settings_error', $this->translator->get('settings.allegro.validation.status_sync_interval_invalid')); $validationError = $this->validateImportSettingsInput(
$intervalMinutesRaw,
$intervalMinutes,
$statusSyncDirection,
$statusSyncIntervalRaw,
$statusSyncInterval
);
if ($validationError !== null) {
Flash::set('settings_error', $validationError);
return Response::redirect(RedirectPaths::ALLEGRO_SETTINGS_TAB); return Response::redirect(RedirectPaths::ALLEGRO_SETTINGS_TAB);
} }
@@ -419,14 +406,11 @@ final class AllegroIntegrationController
$state = trim((string) $request->input('state', '')); $state = trim((string) $request->input('state', ''));
$expectedState = trim((string) ($_SESSION[self::OAUTH_STATE_SESSION_KEY] ?? '')); $expectedState = trim((string) ($_SESSION[self::OAUTH_STATE_SESSION_KEY] ?? ''));
unset($_SESSION[self::OAUTH_STATE_SESSION_KEY]); 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(RedirectPaths::ALLEGRO_INTEGRATION);
}
$authorizationCode = trim((string) $request->input('code', '')); $authorizationCode = trim((string) $request->input('code', ''));
if ($authorizationCode === '') {
Flash::set('settings_error', $this->translator->get('settings.allegro.flash.oauth_code_missing')); $validationError = $this->validateOAuthCallbackParams($state, $expectedState, $authorizationCode);
if ($validationError !== null) {
Flash::set('settings_error', $validationError);
return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION); return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
} }
@@ -896,6 +880,60 @@ final class AllegroIntegrationController
]; ];
} }
private function validateSaveInput(
string $environment,
string $clientId,
string $redirectUri,
string $ordersFetchStartDate
): ?string {
if (!in_array($environment, ['sandbox', 'production'], true)) {
return $this->translator->get('settings.allegro.validation.environment_invalid');
}
if ($clientId !== '' && mb_strlen($clientId) > 128) {
return $this->translator->get('settings.allegro.validation.client_id_too_long');
}
if (!$this->isValidHttpUrl($redirectUri)) {
return $this->translator->get('settings.allegro.validation.redirect_uri_invalid');
}
if ($ordersFetchStartDate !== '' && !$this->isValidDate($ordersFetchStartDate)) {
return $this->translator->get('settings.allegro.validation.orders_fetch_start_date_invalid');
}
return null;
}
private function validateImportSettingsInput(
int $intervalMinutesRaw,
int $intervalMinutes,
string $statusSyncDirection,
int $statusSyncIntervalRaw,
int $statusSyncInterval
): ?string {
if ($intervalMinutesRaw !== $intervalMinutes) {
return $this->translator->get('settings.allegro.validation.orders_import_interval_invalid');
}
if (!in_array($statusSyncDirection, $this->allowedStatusSyncDirections(), true)) {
return $this->translator->get('settings.allegro.validation.status_sync_direction_invalid');
}
if ($statusSyncIntervalRaw !== $statusSyncInterval) {
return $this->translator->get('settings.allegro.validation.status_sync_interval_invalid');
}
return null;
}
private function validateOAuthCallbackParams(
string $state,
string $expectedState,
string $authorizationCode
): ?string {
if ($state === '' || $expectedState === '' || !hash_equals($expectedState, $state)) {
return $this->translator->get('settings.allegro.flash.oauth_state_invalid');
}
if ($authorizationCode === '') {
return $this->translator->get('settings.allegro.flash.oauth_code_missing');
}
return null;
}
private function ensureDefaultSchedulesExist(): void private function ensureDefaultSchedulesExist(): void
{ {
try { try {

View File

@@ -118,44 +118,21 @@ final class ShopproIntegrationsController
$redirectBase = RedirectPaths::SHOPPRO_INTEGRATION; $redirectBase = RedirectPaths::SHOPPRO_INTEGRATION;
$redirectTo = $this->buildRedirectUrl($integrationId, $tab); $redirectTo = $this->buildRedirectUrl($integrationId, $tab);
if (!Csrf::validate((string) $request->input('_token', ''))) {
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
return Response::redirect($redirectTo);
}
$existing = $integrationId > 0 ? $this->repository->findIntegration($integrationId) : null; $existing = $integrationId > 0 ? $this->repository->findIntegration($integrationId) : null;
if ($integrationId > 0 && $existing === null) { $accessError = $this->validateSaveAccess((string) $request->input('_token', ''), $integrationId, $existing, $tab);
Flash::set('settings_error', $this->translator->get('settings.integrations.flash.not_found')); if ($accessError !== null) {
return Response::redirect($this->buildRedirectUrl(0, $tab)); return $accessError;
} }
$name = trim((string) $request->input('name', '')); $name = trim((string) $request->input('name', ''));
if (mb_strlen($name) < 2) {
Flash::set('settings_error', $this->translator->get('settings.integrations.validation.name_min'));
return Response::redirect($redirectTo);
}
$baseUrl = rtrim(trim((string) $request->input('base_url', '')), '/'); $baseUrl = rtrim(trim((string) $request->input('base_url', '')), '/');
if (!$this->isValidHttpUrl($baseUrl)) {
Flash::set('settings_error', $this->translator->get('settings.integrations.validation.base_url_invalid'));
return Response::redirect($redirectTo);
}
$apiKey = trim((string) $request->input('api_key', '')); $apiKey = trim((string) $request->input('api_key', ''));
$hasExistingApiKey = (bool) ($existing['has_api_key'] ?? false); $hasExistingApiKey = (bool) ($existing['has_api_key'] ?? false);
if ($tab === 'integration' && $apiKey === '' && !$hasExistingApiKey) {
Flash::set('settings_error', $this->translator->get('settings.integrations.validation.api_key_required'));
return Response::redirect($redirectTo);
}
$ordersFetchStartDate = trim((string) $request->input('orders_fetch_start_date', '')); $ordersFetchStartDate = trim((string) $request->input('orders_fetch_start_date', ''));
if ($ordersFetchStartDate !== '' && !$this->isValidYmdDate($ordersFetchStartDate)) {
Flash::set('settings_error', $this->translator->get('settings.integrations.validation.orders_fetch_start_date_invalid'));
return Response::redirect($redirectTo);
}
if ($this->isDuplicateName($integrationId, $name)) { $validationError = $this->validateSaveInput($name, $baseUrl, $apiKey, $hasExistingApiKey, $tab, $ordersFetchStartDate, $integrationId);
Flash::set('settings_error', $this->translator->get('settings.integrations.validation.name_taken')); if ($validationError !== null) {
Flash::set('settings_error', $validationError);
return Response::redirect($redirectTo); return Response::redirect($redirectTo);
} }
@@ -193,12 +170,12 @@ final class ShopproIntegrationsController
? 'settings.integrations.flash.updated' ? 'settings.integrations.flash.updated'
: 'settings.integrations.flash.created'; : 'settings.integrations.flash.created';
Flash::set('settings_success', $this->translator->get($flashKey)); Flash::set('settings_success', $this->translator->get($flashKey));
$redirectTo = $this->buildRedirectUrl($savedId, $tab);
return Response::redirect($this->buildRedirectUrl($savedId, $tab));
} catch (Throwable) { } catch (Throwable) {
Flash::set('settings_error', $this->translator->get('settings.integrations.flash.failed')); Flash::set('settings_error', $this->translator->get('settings.integrations.flash.failed'));
return Response::redirect($redirectTo);
} }
return Response::redirect($redirectTo);
} }
public function test(Request $request): Response public function test(Request $request): Response
@@ -242,14 +219,9 @@ final class ShopproIntegrationsController
$integrationId = max(0, (int) $request->input('integration_id', 0)); $integrationId = max(0, (int) $request->input('integration_id', 0));
$redirectTo = $this->buildRedirectUrl($integrationId, 'statuses'); $redirectTo = $this->buildRedirectUrl($integrationId, 'statuses');
if (!Csrf::validate((string) $request->input('_token', ''))) { $accessError = $this->validateCsrfAndIntegrationAccess((string) $request->input('_token', ''), $integrationId, 'statuses');
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired')); if ($accessError !== null) {
return Response::redirect($redirectTo); return $accessError;
}
if ($integrationId <= 0 || $this->repository->findIntegration($integrationId) === null) {
Flash::set('settings_error', $this->translator->get('settings.integrations.flash.not_found'));
return Response::redirect($this->buildRedirectUrl(0, 'statuses'));
} }
$shopCodes = $request->input('shoppro_status_code', []); $shopCodes = $request->input('shoppro_status_code', []);
@@ -305,14 +277,9 @@ final class ShopproIntegrationsController
$integrationId = max(0, (int) $request->input('integration_id', 0)); $integrationId = max(0, (int) $request->input('integration_id', 0));
$redirectTo = $this->buildRedirectUrl($integrationId, 'statuses'); $redirectTo = $this->buildRedirectUrl($integrationId, 'statuses');
if (!Csrf::validate((string) $request->input('_token', ''))) { $accessError = $this->validateCsrfAndIntegrationAccess((string) $request->input('_token', ''), $integrationId, 'statuses');
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired')); if ($accessError !== null) {
return Response::redirect($redirectTo); return $accessError;
}
if ($integrationId <= 0 || $this->repository->findIntegration($integrationId) === null) {
Flash::set('settings_error', $this->translator->get('settings.integrations.flash.not_found'));
return Response::redirect($this->buildRedirectUrl(0, 'statuses'));
} }
$result = $this->repository->fetchOrderStatuses($integrationId); $result = $this->repository->fetchOrderStatuses($integrationId);
@@ -431,6 +398,62 @@ final class ShopproIntegrationsController
]; ];
} }
/**
* @param array<string, mixed>|null $existing
*/
private function validateSaveAccess(string $token, int $integrationId, ?array $existing, string $tab): ?Response
{
if (!Csrf::validate($token)) {
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
return Response::redirect($this->buildRedirectUrl($integrationId, $tab));
}
if ($integrationId > 0 && $existing === null) {
Flash::set('settings_error', $this->translator->get('settings.integrations.flash.not_found'));
return Response::redirect($this->buildRedirectUrl(0, $tab));
}
return null;
}
private function validateSaveInput(
string $name,
string $baseUrl,
string $apiKey,
bool $hasExistingApiKey,
string $tab,
string $ordersFetchStartDate,
int $integrationId
): ?string {
if (mb_strlen($name) < 2) {
return $this->translator->get('settings.integrations.validation.name_min');
}
if (!$this->isValidHttpUrl($baseUrl)) {
return $this->translator->get('settings.integrations.validation.base_url_invalid');
}
if ($tab === 'integration' && $apiKey === '' && !$hasExistingApiKey) {
return $this->translator->get('settings.integrations.validation.api_key_required');
}
if ($ordersFetchStartDate !== '' && !$this->isValidYmdDate($ordersFetchStartDate)) {
return $this->translator->get('settings.integrations.validation.orders_fetch_start_date_invalid');
}
if ($this->isDuplicateName($integrationId, $name)) {
return $this->translator->get('settings.integrations.validation.name_taken');
}
return null;
}
private function validateCsrfAndIntegrationAccess(string $token, int $integrationId, string $tab): ?Response
{
if (!Csrf::validate($token)) {
Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
return Response::redirect($this->buildRedirectUrl($integrationId, $tab));
}
if ($integrationId <= 0 || $this->repository->findIntegration($integrationId) === null) {
Flash::set('settings_error', $this->translator->get('settings.integrations.flash.not_found'));
return Response::redirect($this->buildRedirectUrl(0, $tab));
}
return null;
}
private function isDuplicateName(int $currentId, string $name): bool private function isDuplicateName(int $currentId, string $name): bool
{ {
$needle = mb_strtolower(trim($name)); $needle = mb_strtolower(trim($name));