From f313e74c9e6d1d0a88b8c3172e2032f545616486 Mon Sep 17 00:00:00 2001 From: matthieu Date: Wed, 20 May 2026 07:46:11 +0200 Subject: [PATCH] =?UTF-8?q?fix(mail)=20:=20le=20test=20de=20connexion=20fo?= =?UTF-8?q?nctionne=20m=C3=AAme=20si=20la=20config=20est=20d=C3=A9sactiv?= =?UTF-8?q?=C3=A9e=20+=20remonte=20l'erreur=20IMAP=20r=C3=A9elle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le guard enabled dans getClient() bloquait le test de connexion alors que le workflow naturel est configurer → tester → activer. getClient(requireEnabled) permet au nouveau testConnection() de se connecter sans exiger enabled=true. Le controller (ROLE_ADMIN) renvoie désormais le détail de l'erreur pour faciliter le diagnostic. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Mail/MailTestConnectionController.php | 18 +++++++------ src/Mail/ImapMailProvider.php | 26 ++++++++++++++++--- src/Mail/MailProviderInterface.php | 9 +++++++ 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/Controller/Mail/MailTestConnectionController.php b/src/Controller/Mail/MailTestConnectionController.php index eedee6a..6d25518 100644 --- a/src/Controller/Mail/MailTestConnectionController.php +++ b/src/Controller/Mail/MailTestConnectionController.php @@ -23,21 +23,23 @@ class MailTestConnectionController extends AbstractController public function __invoke(): JsonResponse { try { - $folders = $this->mailProvider->listFolders(); + $foldersCount = $this->mailProvider->testConnection(); return $this->json([ 'ok' => true, - 'foldersCount' => count($folders), + 'foldersCount' => $foldersCount, ]); - } catch (MailProviderException) { + } catch (MailProviderException $e) { return $this->json([ - 'ok' => false, - 'error' => 'Connexion IMAP impossible. Vérifiez la configuration.', + 'ok' => false, + 'error' => 'Connexion IMAP impossible. Vérifiez la configuration.', + 'detail' => $e->getMessage(), ]); - } catch (Throwable) { + } catch (Throwable $e) { return $this->json([ - 'ok' => false, - 'error' => 'Erreur inattendue lors du test de connexion.', + 'ok' => false, + 'error' => 'Erreur inattendue lors du test de connexion.', + 'detail' => $e->getMessage(), ]); } } diff --git a/src/Mail/ImapMailProvider.php b/src/Mail/ImapMailProvider.php index 1354d1f..eac2021 100644 --- a/src/Mail/ImapMailProvider.php +++ b/src/Mail/ImapMailProvider.php @@ -26,6 +26,22 @@ final class ImapMailProvider implements MailProviderInterface private readonly LoggerInterface $logger, ) {} + public function testConnection(): int + { + $client = $this->getClient(requireEnabled: false); + + try { + $folders = $client->getFolders(false); + $client->disconnect(); + + return count($folders); + } catch (Throwable $e) { + $this->logger->error('ImapMailProvider::testConnection failed: '.$e->getMessage()); + + throw MailProviderException::connectionFailed($e->getMessage()); + } + } + public function listFolders(): array { $client = $this->getClient(); @@ -269,12 +285,16 @@ final class ImapMailProvider implements MailProviderInterface } } - private function getClient(): Client + private function getClient(bool $requireEnabled = true): Client { $config = $this->configRepository->findSingleton(); - if (null === $config || !$config->isEnabled()) { - throw MailProviderException::connectionFailed('Mail configuration is missing or disabled'); + if (null === $config) { + throw MailProviderException::connectionFailed('Mail configuration is missing'); + } + + if ($requireEnabled && !$config->isEnabled()) { + throw MailProviderException::connectionFailed('Mail configuration is disabled'); } if (null === $config->getEncryptedPassword()) { diff --git a/src/Mail/MailProviderInterface.php b/src/Mail/MailProviderInterface.php index 1de7da3..9392f85 100644 --- a/src/Mail/MailProviderInterface.php +++ b/src/Mail/MailProviderInterface.php @@ -11,6 +11,15 @@ use App\Mail\Exception\MailProviderException; interface MailProviderInterface { + /** + * Opens a connection using the stored configuration and returns the number + * of folders found. Used by the admin "test connection" endpoint, so it + * MUST work even when the configuration is not yet enabled. + * + * @throws MailProviderException + */ + public function testConnection(): int; + /** * Returns the full folder tree of the configured mailbox. *