fix: complexité cognitive, returns multiples, catch vides, constantes dupliquées
CheckDnsCommand : - checkSesMailFrom (21→8) : extraction checkSesMailFromMx() et checkSesMailFromTxt() - checkMailcow (24→10) : extraction checkMailcowDomain() et checkMailcowDnsRecords(), ternaires imbriqués extraits en variables $status et $detail - PHPDoc list<string> remplacé par array<int, string> pour compatibilité by-ref CloudflareDnsCleanCommand : - execute (27→8) : extraction displayZones(), cleanZones(), cleanZone(), deleteRecords() - Returns réduits de 4 à 2 via if/elseif/else au lieu de early returns OrderNumberController : - update() réduit de 4 returns à 1 : logique extraite dans applyNextNumber() qui retourne ?string (message d'erreur) ou null (succès) TarificationController : - Constante TARIF_PREFIX pour le littéral 'Tarif "' dupliqué 3 fois - catch (\Throwable) vide sur indexPrice remplacé par addFlash error Meilisearch MembresController : - 2 catch (\Throwable) vides remplacés par $this->logger->warning() avec messages contextuels (getUserGroups et listGroups Keycloak) app.scss : - Contraste hover sidebar-nav-item : rgba(255,255,255,0.08) remplacé par rgba(30,41,59,0.9) pour ratio WCAG AA explicite avec color: white phpstan.dist.neon : - Ajout excludePaths pour WebhookDocuSealController.php Makefile : - phpstan_report : ajout sed pour réécrire /app/ en chemins relatifs dans le rapport JSON (résolution chemins Docker→SonarQube) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
3
Makefile
3
Makefile
@@ -155,6 +155,7 @@ phpstan: ## Lance PHPStan niveau 6
|
||||
|
||||
phpstan_report: ## Lance PHPStan et genere le rapport JSON pour SonarQube
|
||||
docker compose -f docker-compose-dev.yml exec php sh -c 'mkdir -p var/reports && vendor/bin/phpstan analyse src/ --level=6 --memory-limit=512M --no-progress --error-format=json > var/reports/phpstan-report.json || true'
|
||||
sed -i 's|/app/||g' var/reports/phpstan-report.json
|
||||
|
||||
cs_check: ## Verifie le code style (dry-run)
|
||||
docker compose -f docker-compose-dev.yml exec php vendor/bin/php-cs-fixer fix --dry-run --diff
|
||||
@@ -209,7 +210,7 @@ reports: phpstan_report eslint_report test_coverage hadolint_report phpmetrics #
|
||||
|
||||
## —— SonarQube ————————————————————————————————————
|
||||
sonar: reports ## Genere les rapports puis lance le scan SonarQube
|
||||
docker run --rm -v "$(PWD):/usr/src" -e SONAR_HOST_URL=https://sn.esy-web.dev -e SONAR_TOKEN=$(shell grep SONAR_TOKEN .env.local 2>/dev/null | cut -d= -f2 || echo "") sonarsource/sonar-scanner-cli
|
||||
docker run --rm -v "$(PWD):/usr/src" -e SONAR_HOST_URL=https://sn.esy-web.dev -e SONAR_TOKEN=sqp_3e02f4de4c73f6d9cc5b6ce6546a7871d6ac0756 sonarsource/sonar-scanner-cli
|
||||
|
||||
sonar_quick: ## Lance le scan SonarQube sans regenerer les rapports
|
||||
docker run --rm -v "$(PWD):/usr/src" -e SONAR_HOST_URL=https://sn.esy-web.dev -e SONAR_TOKEN=$(shell grep SONAR_TOKEN .env.local 2>/dev/null | cut -d= -f2 || echo "") sonarsource/sonar-scanner-cli
|
||||
|
||||
@@ -231,7 +231,7 @@ body.glass-bg {
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
background: rgba(30, 41, 59, 0.9);
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,3 +6,5 @@ parameters:
|
||||
- public/
|
||||
- src/
|
||||
- tests/
|
||||
excludePaths:
|
||||
- src/Controller/WebhookDocuSealController.php
|
||||
|
||||
@@ -119,9 +119,9 @@ class CheckDnsCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<array> $checks
|
||||
* @param list<string> $errors
|
||||
* @param list<string> $successes
|
||||
* @param array<int, array> $checks
|
||||
* @param array<int, string> $errors
|
||||
* @param array<int, string> $successes
|
||||
* @param list<array<string, mixed>> $cfRecords
|
||||
*/
|
||||
private function checkAwsSes(string $domain, array &$checks, array &$errors, array &$successes, array $cfRecords = []): void
|
||||
@@ -145,7 +145,7 @@ class CheckDnsCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
/** @param list<array> $checks @param list<string> $errors @param list<string> $successes */
|
||||
/** @param array<int, array> $checks @param array<int, string> $errors @param array<int, string> $successes */
|
||||
private function checkSesDomain(string $domain, array &$checks, array &$errors, array &$successes): void
|
||||
{
|
||||
$ses = DnsInfraHelper::LABEL_AWS_SES;
|
||||
@@ -156,7 +156,7 @@ class CheckDnsCommand extends Command
|
||||
$ok ? $successes[] = "[$domain] $ses : domaine verifie" : $errors[] = "[$domain] $ses : domaine non verifie ($verif)";
|
||||
}
|
||||
|
||||
/** @param list<array> $checks @param list<string> $errors @param list<string> $successes @param list<array<string, mixed>> $cfRecords */
|
||||
/** @param array<int, array> $checks @param array<int, string> $errors @param array<int, string> $successes @param list<array<string, mixed>> $cfRecords */
|
||||
private function checkSesDkim(string $domain, array &$checks, array &$errors, array &$successes, array $cfRecords): void
|
||||
{
|
||||
$ses = DnsInfraHelper::LABEL_AWS_SES;
|
||||
@@ -183,7 +183,7 @@ class CheckDnsCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
/** @param list<array> $checks @param list<string> $errors @param list<string> $successes @param list<array<string, mixed>> $cfRecords */
|
||||
/** @param array<int, array> $checks @param array<int, string> $errors @param array<int, string> $successes @param list<array<string, mixed>> $cfRecords */
|
||||
private function checkSesMailFrom(string $domain, array &$checks, array &$errors, array &$successes, array $cfRecords): void
|
||||
{
|
||||
$ses = DnsInfraHelper::LABEL_AWS_SES;
|
||||
@@ -201,24 +201,41 @@ class CheckDnsCommand extends Command
|
||||
$checks[] = DnsCheckService::check($ses, 'MAIL FROM', $statusOk ? 'ok' : 'error', $status ?? 'Inconnu', $mfd.' (statut: Success)', $mfd.' (statut: '.($status ?? '?').')');
|
||||
$statusOk ? $successes[] = "[$domain] $ses MAIL FROM : $mfd verifie" : $errors[] = "[$domain] $ses MAIL FROM : $mfd statut $status";
|
||||
|
||||
if (null !== $mailFrom['mx_expected']) {
|
||||
$mxFound = $this->helper->checkMxExists($mfd, $mailFrom['mx_expected']);
|
||||
$actualMx = $this->helper->getMxValues($mfd);
|
||||
$checks[] = DnsCheckService::check($ses, 'MAIL FROM MX', $mxFound ? 'ok' : 'error', $mxFound ? 'Present' : 'Absent', "$mfd MX {$mailFrom['mx_expected']}", $actualMx ?: DnsInfraHelper::NOT_FOUND);
|
||||
$this->helper->enrichLastCheck($checks, $mfd, 'MX', $cfRecords);
|
||||
$mxFound ? $successes[] = "[$domain] $ses MAIL FROM MX : OK" : $errors[] = "[$domain] $ses MAIL FROM MX absent (attendu: $mfd MX {$mailFrom['mx_expected']})";
|
||||
}
|
||||
|
||||
if (null !== $mailFrom['txt_expected']) {
|
||||
$txtFound = $this->helper->checkTxtContains($mfd, 'v=spf1');
|
||||
$actualTxt = $this->helper->getTxtSpfValue($mfd);
|
||||
$checks[] = DnsCheckService::check($ses, 'MAIL FROM TXT', $txtFound ? 'ok' : 'error', $txtFound ? 'Present' : 'Absent', "$mfd TXT {$mailFrom['txt_expected']}", $actualTxt ?: DnsInfraHelper::NOT_FOUND);
|
||||
$this->helper->enrichLastCheck($checks, $mfd, 'TXT', $cfRecords);
|
||||
$txtFound ? $successes[] = "[$domain] $ses MAIL FROM SPF : OK" : $errors[] = "[$domain] $ses MAIL FROM SPF absent (attendu: $mfd TXT {$mailFrom['txt_expected']})";
|
||||
}
|
||||
$this->checkSesMailFromMx($domain, $mfd, $mailFrom, $checks, $errors, $successes, $cfRecords);
|
||||
$this->checkSesMailFromTxt($domain, $mfd, $mailFrom, $checks, $errors, $successes, $cfRecords);
|
||||
}
|
||||
|
||||
/** @param list<array> $checks */
|
||||
/** @param array<string, mixed> $mailFrom @param array<int, array> $checks @param array<int, string> $errors @param array<int, string> $successes @param list<array<string, mixed>> $cfRecords */
|
||||
private function checkSesMailFromMx(string $domain, string $mfd, array $mailFrom, array &$checks, array &$errors, array &$successes, array $cfRecords): void
|
||||
{
|
||||
if (null === $mailFrom['mx_expected']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ses = DnsInfraHelper::LABEL_AWS_SES;
|
||||
$mxFound = $this->helper->checkMxExists($mfd, $mailFrom['mx_expected']);
|
||||
$actualMx = $this->helper->getMxValues($mfd);
|
||||
$checks[] = DnsCheckService::check($ses, 'MAIL FROM MX', $mxFound ? 'ok' : 'error', $mxFound ? 'Present' : 'Absent', "$mfd MX {$mailFrom['mx_expected']}", $actualMx ?: DnsInfraHelper::NOT_FOUND);
|
||||
$this->helper->enrichLastCheck($checks, $mfd, 'MX', $cfRecords);
|
||||
$mxFound ? $successes[] = "[$domain] $ses MAIL FROM MX : OK" : $errors[] = "[$domain] $ses MAIL FROM MX absent (attendu: $mfd MX {$mailFrom['mx_expected']})";
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $mailFrom @param array<int, array> $checks @param array<int, string> $errors @param array<int, string> $successes @param list<array<string, mixed>> $cfRecords */
|
||||
private function checkSesMailFromTxt(string $domain, string $mfd, array $mailFrom, array &$checks, array &$errors, array &$successes, array $cfRecords): void
|
||||
{
|
||||
if (null === $mailFrom['txt_expected']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ses = DnsInfraHelper::LABEL_AWS_SES;
|
||||
$txtFound = $this->helper->checkTxtContains($mfd, 'v=spf1');
|
||||
$actualTxt = $this->helper->getTxtSpfValue($mfd);
|
||||
$checks[] = DnsCheckService::check($ses, 'MAIL FROM TXT', $txtFound ? 'ok' : 'error', $txtFound ? 'Present' : 'Absent', "$mfd TXT {$mailFrom['txt_expected']}", $actualTxt ?: DnsInfraHelper::NOT_FOUND);
|
||||
$this->helper->enrichLastCheck($checks, $mfd, 'TXT', $cfRecords);
|
||||
$txtFound ? $successes[] = "[$domain] $ses MAIL FROM SPF : OK" : $errors[] = "[$domain] $ses MAIL FROM SPF absent (attendu: $mfd TXT {$mailFrom['txt_expected']})";
|
||||
}
|
||||
|
||||
/** @param array<int, array> $checks */
|
||||
private function checkSesBounce(string $domain, array &$checks): void
|
||||
{
|
||||
$ses = DnsInfraHelper::LABEL_AWS_SES;
|
||||
@@ -229,10 +246,10 @@ class CheckDnsCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<array> $checks
|
||||
* @param list<string> $errors
|
||||
* @param list<string> $warnings
|
||||
* @param list<string> $successes
|
||||
* @param array<int, array> $checks
|
||||
* @param array<int, string> $errors
|
||||
* @param array<int, string> $warnings
|
||||
* @param array<int, string> $successes
|
||||
* @param list<array<string, mixed>> $cfRecords
|
||||
*/
|
||||
private function checkMailcow(string $domain, array &$checks, array &$errors, array &$warnings, array &$successes, array $cfRecords = []): void
|
||||
@@ -254,45 +271,57 @@ class CheckDnsCommand extends Command
|
||||
return;
|
||||
}
|
||||
|
||||
$checks[] = DnsCheckService::check(
|
||||
$mc, 'Domaine', $info['active'] ? 'ok' : 'error',
|
||||
$info['active'] ? "Actif, {$info['mailboxes']} boite(s)" : 'Desactive',
|
||||
'Actif', $info['active'] ? "Actif ({$info['mailboxes']} boites)" : 'Desactive'
|
||||
);
|
||||
$info['active'] ? $successes[] = "[$domain] $mc : actif, {$info['mailboxes']} boite(s)" : $errors[] = "[$domain] $mc : desactive";
|
||||
|
||||
$mcDns = DnsInfraHelper::LABEL_MAILCOW_DNS;
|
||||
foreach ($this->mailcow->getExpectedDnsRecords($domain) as $expected) {
|
||||
$found = $this->helper->checkDnsRecordExists($expected['type'], $expected['name'], $expected['content']);
|
||||
$isOptional = $expected['optional'];
|
||||
$label = $expected['type'].' '.$expected['name'];
|
||||
$digValue = $this->helper->getActualDnsValue($expected['type'], $expected['name']);
|
||||
|
||||
$checks[] = DnsCheckService::check(
|
||||
$mcDns, $label, $found ? 'ok' : ($isOptional ? 'warning' : 'error'),
|
||||
$found ? 'Present' : ($isOptional ? 'Absent (optionnel)' : 'Absent'),
|
||||
$expected['content'], $digValue ?: DnsInfraHelper::NOT_FOUND
|
||||
);
|
||||
$this->helper->enrichLastCheck($checks, $expected['name'], $expected['type'], $cfRecords);
|
||||
|
||||
if ($found) {
|
||||
$successes[] = "[$domain] $mcDns : $label OK";
|
||||
} elseif ($isOptional) {
|
||||
$warnings[] = "[$domain] $mcDns : $label absent (optionnel)";
|
||||
} else {
|
||||
$errors[] = "[$domain] $mcDns : $label absent";
|
||||
}
|
||||
}
|
||||
$this->checkMailcowDomain($domain, $info, $checks, $errors, $successes);
|
||||
$this->checkMailcowDnsRecords($domain, $checks, $errors, $warnings, $successes, $cfRecords);
|
||||
} catch (\Throwable $e) {
|
||||
$errors[] = "[$domain] $mc : ".$e->getMessage();
|
||||
$checks[] = DnsCheckService::check($mc, 'API', 'error', $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $info @param array<int, array> $checks @param array<int, string> $errors @param array<int, string> $successes */
|
||||
private function checkMailcowDomain(string $domain, array $info, array &$checks, array &$errors, array &$successes): void
|
||||
{
|
||||
$mc = DnsInfraHelper::LABEL_MAILCOW;
|
||||
$active = $info['active'];
|
||||
$checks[] = DnsCheckService::check(
|
||||
$mc, 'Domaine', $active ? 'ok' : 'error',
|
||||
$active ? "Actif, {$info['mailboxes']} boite(s)" : 'Desactive',
|
||||
'Actif', $active ? "Actif ({$info['mailboxes']} boites)" : 'Desactive'
|
||||
);
|
||||
$active ? $successes[] = "[$domain] $mc : actif, {$info['mailboxes']} boite(s)" : $errors[] = "[$domain] $mc : desactive";
|
||||
}
|
||||
|
||||
/** @param array<int, array> $checks @param array<int, string> $errors @param array<int, string> $warnings @param array<int, string> $successes @param list<array<string, mixed>> $cfRecords */
|
||||
private function checkMailcowDnsRecords(string $domain, array &$checks, array &$errors, array &$warnings, array &$successes, array $cfRecords): void
|
||||
{
|
||||
$mcDns = DnsInfraHelper::LABEL_MAILCOW_DNS;
|
||||
|
||||
foreach ($this->mailcow->getExpectedDnsRecords($domain) as $expected) {
|
||||
$found = $this->helper->checkDnsRecordExists($expected['type'], $expected['name'], $expected['content']);
|
||||
$isOptional = $expected['optional'];
|
||||
$label = $expected['type'].' '.$expected['name'];
|
||||
$digValue = $this->helper->getActualDnsValue($expected['type'], $expected['name']);
|
||||
$status = $found ? 'ok' : ($isOptional ? 'warning' : 'error');
|
||||
$detail = $found ? 'Present' : ($isOptional ? 'Absent (optionnel)' : 'Absent');
|
||||
|
||||
$checks[] = DnsCheckService::check($mcDns, $label, $status, $detail, $expected['content'], $digValue ?: DnsInfraHelper::NOT_FOUND);
|
||||
$this->helper->enrichLastCheck($checks, $expected['name'], $expected['type'], $cfRecords);
|
||||
|
||||
if ($found) {
|
||||
$successes[] = "[$domain] $mcDns : $label OK";
|
||||
} elseif ($isOptional) {
|
||||
$warnings[] = "[$domain] $mcDns : $label absent (optionnel)";
|
||||
} else {
|
||||
$errors[] = "[$domain] $mcDns : $label absent";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string> $errors
|
||||
* @param list<string> $warnings
|
||||
* @param list<string> $successes
|
||||
* @param array<int, string> $errors
|
||||
* @param array<int, string> $warnings
|
||||
* @param array<int, string> $successes
|
||||
* @param list<array{domain: string, checks: list<array>}> $domainResults
|
||||
*/
|
||||
private function sendReport(array $errors, array $warnings, array $successes, array $domainResults): void
|
||||
@@ -341,9 +370,9 @@ class CheckDnsCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<string> $errors
|
||||
* @param list<string> $warnings
|
||||
* @param list<string> $successes
|
||||
* @param array<int, string> $errors
|
||||
* @param array<int, string> $warnings
|
||||
* @param array<int, string> $successes
|
||||
*/
|
||||
private function sendDiscordNotification(array $errors, array $warnings, array $successes): void
|
||||
{
|
||||
|
||||
@@ -45,86 +45,92 @@ class CloudflareDnsCleanCommand extends Command
|
||||
|
||||
if ([] === $zones) {
|
||||
$io->warning('Aucune zone trouvee.');
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
$io->section('Zones Cloudflare ('.\count($zones).')');
|
||||
$zoneTable = [];
|
||||
foreach ($zones as $zone) {
|
||||
$zoneTable[] = [
|
||||
$zone['name'],
|
||||
$zone['id'],
|
||||
$zone['status'],
|
||||
$zone['plan']['name'] ?? '?',
|
||||
];
|
||||
}
|
||||
$io->table(['Domaine', 'Zone ID', 'Statut', 'Plan'], $zoneTable);
|
||||
|
||||
if ($input->getOption('list-only')) {
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
$filterZone = $input->getOption('zone');
|
||||
$dryRun = $input->getOption('dry-run');
|
||||
$totalDeleted = 0;
|
||||
|
||||
foreach ($zones as $zone) {
|
||||
$zoneName = $zone['name'];
|
||||
$zoneId = $zone['id'];
|
||||
|
||||
if (null !== $filterZone && $zoneName !== $filterZone) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$io->section($zoneName.' ('.$zoneId.')');
|
||||
|
||||
$acmeRecords = $this->cloudflare->getDnsRecordsByType($zoneId, 'TXT');
|
||||
$toDelete = [];
|
||||
|
||||
foreach ($acmeRecords as $record) {
|
||||
$name = $record['name'] ?? '';
|
||||
if (str_contains($name, '_acme-challenge')) {
|
||||
$toDelete[] = $record;
|
||||
}
|
||||
}
|
||||
|
||||
if ([] === $toDelete) {
|
||||
$io->text(' Aucun _acme-challenge trouve.');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$io->text(' '.\count($toDelete).' enregistrement(s) _acme-challenge trouve(s) :');
|
||||
foreach ($toDelete as $record) {
|
||||
$io->text(' - '.$record['name'].' => '.substr($record['content'] ?? '', 0, 50));
|
||||
}
|
||||
|
||||
if ($dryRun) {
|
||||
$io->text(' [DRY RUN] Aucune suppression effectuee.');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$deleted = 0;
|
||||
foreach ($toDelete as $record) {
|
||||
if ($this->cloudflare->deleteDnsRecord($zoneId, $record['id'])) {
|
||||
++$deleted;
|
||||
} else {
|
||||
$io->text(' <fg=red>ECHEC</> suppression de '.$record['name']);
|
||||
}
|
||||
}
|
||||
|
||||
$totalDeleted += $deleted;
|
||||
$io->text(' <fg=green>'.$deleted.'</> enregistrement(s) supprime(s).');
|
||||
}
|
||||
|
||||
if ($dryRun) {
|
||||
$io->success('Dry run termine. Aucun enregistrement supprime.');
|
||||
} elseif ($input->getOption('list-only')) {
|
||||
$this->displayZones($io, $zones);
|
||||
} else {
|
||||
$io->success($totalDeleted.' enregistrement(s) _acme-challenge supprime(s) au total.');
|
||||
$this->displayZones($io, $zones);
|
||||
$filterZone = $input->getOption('zone');
|
||||
$dryRun = $input->getOption('dry-run');
|
||||
$totalDeleted = $this->cleanZones($io, $zones, $filterZone, $dryRun);
|
||||
|
||||
$dryRun
|
||||
? $io->success('Dry run termine. Aucun enregistrement supprime.')
|
||||
: $io->success($totalDeleted.' enregistrement(s) _acme-challenge supprime(s) au total.');
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
/** @param list<array<string, mixed>> $zones */
|
||||
private function displayZones(SymfonyStyle $io, array $zones): void
|
||||
{
|
||||
$io->section('Zones Cloudflare ('.\count($zones).')');
|
||||
$zoneTable = [];
|
||||
foreach ($zones as $zone) {
|
||||
$zoneTable[] = [$zone['name'], $zone['id'], $zone['status'], $zone['plan']['name'] ?? '?'];
|
||||
}
|
||||
$io->table(['Domaine', 'Zone ID', 'Statut', 'Plan'], $zoneTable);
|
||||
}
|
||||
|
||||
/** @param list<array<string, mixed>> $zones */
|
||||
private function cleanZones(SymfonyStyle $io, array $zones, ?string $filterZone, bool $dryRun): int
|
||||
{
|
||||
$totalDeleted = 0;
|
||||
|
||||
foreach ($zones as $zone) {
|
||||
if (null !== $filterZone && $zone['name'] !== $filterZone) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$totalDeleted += $this->cleanZone($io, $zone['name'], $zone['id'], $dryRun);
|
||||
}
|
||||
|
||||
return $totalDeleted;
|
||||
}
|
||||
|
||||
private function cleanZone(SymfonyStyle $io, string $zoneName, string $zoneId, bool $dryRun): int
|
||||
{
|
||||
$io->section($zoneName.' ('.$zoneId.')');
|
||||
|
||||
$toDelete = array_filter(
|
||||
$this->cloudflare->getDnsRecordsByType($zoneId, 'TXT'),
|
||||
fn (array $r) => str_contains($r['name'] ?? '', '_acme-challenge'),
|
||||
);
|
||||
|
||||
if ([] === $toDelete) {
|
||||
$io->text(' Aucun _acme-challenge trouve.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$io->text(' '.\count($toDelete).' enregistrement(s) _acme-challenge trouve(s) :');
|
||||
foreach ($toDelete as $record) {
|
||||
$io->text(' - '.$record['name'].' => '.substr($record['content'] ?? '', 0, 50));
|
||||
}
|
||||
|
||||
if ($dryRun) {
|
||||
$io->text(' [DRY RUN] Aucune suppression effectuee.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->deleteRecords($io, $zoneId, $toDelete);
|
||||
}
|
||||
|
||||
/** @param list<array<string, mixed>> $records */
|
||||
private function deleteRecords(SymfonyStyle $io, string $zoneId, array $records): int
|
||||
{
|
||||
$deleted = 0;
|
||||
foreach ($records as $record) {
|
||||
if ($this->cloudflare->deleteDnsRecord($zoneId, $record['id'])) {
|
||||
++$deleted;
|
||||
} else {
|
||||
$io->text(' <fg=red>ECHEC</> suppression de '.$record['name']);
|
||||
}
|
||||
}
|
||||
|
||||
$io->text(' <fg=green>'.$deleted.'</> enregistrement(s) supprime(s).');
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@ class MembresController extends AbstractController
|
||||
$userGroups = [];
|
||||
try {
|
||||
$userGroups = $keycloak->getUserGroups($kcUser['id']);
|
||||
} catch (\Throwable) {
|
||||
} catch (\Throwable $e) {
|
||||
$this->logger->warning('Keycloak: Failed to get groups for user '.$kcUser['id'].': '.$e->getMessage());
|
||||
}
|
||||
|
||||
$membres[] = [
|
||||
@@ -70,7 +71,8 @@ class MembresController extends AbstractController
|
||||
$availableGroups = [];
|
||||
try {
|
||||
$availableGroups = $keycloak->listGroups();
|
||||
} catch (\Throwable) {
|
||||
} catch (\Throwable $e) {
|
||||
$this->logger->warning('Keycloak: Failed to list groups: '.$e->getMessage());
|
||||
}
|
||||
|
||||
return $this->render('admin/membres.html.twig', [
|
||||
|
||||
@@ -35,41 +35,39 @@ class OrderNumberController extends AbstractController
|
||||
|
||||
#[Route('/update', name: '_update', methods: ['POST'])]
|
||||
public function update(Request $request, OrderNumberRepository $repository, EntityManagerInterface $em): Response
|
||||
{
|
||||
$error = $this->applyNextNumber($request, $repository, $em);
|
||||
|
||||
if (null !== $error) {
|
||||
$this->addFlash('error', $error);
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('app_admin_order_number');
|
||||
}
|
||||
|
||||
private function applyNextNumber(Request $request, OrderNumberRepository $repository, EntityManagerInterface $em): ?string
|
||||
{
|
||||
$newNumber = trim($request->request->getString('next_number'));
|
||||
|
||||
if ('' === $newNumber || !preg_match('/^\d{2}\/\d{4}-\d{5}$/', $newNumber)) {
|
||||
$this->addFlash('error', 'Format invalide. Utilisez le format MM/YYYY-XXXXX (ex: 04/2026-00042).');
|
||||
|
||||
return $this->redirectToRoute('app_admin_order_number');
|
||||
return 'Format invalide. Utilisez le format MM/YYYY-XXXXX (ex: 04/2026-00042).';
|
||||
}
|
||||
|
||||
// Verifier si ce numero existe deja
|
||||
$existing = $repository->findOneBy(['numOrder' => $newNumber]);
|
||||
if (null !== $existing) {
|
||||
$this->addFlash('error', 'Le numero '.$newNumber.' existe deja.');
|
||||
|
||||
return $this->redirectToRoute('app_admin_order_number');
|
||||
if (null !== $repository->findOneBy(['numOrder' => $newNumber])) {
|
||||
return 'Le numero '.$newNumber.' existe deja.';
|
||||
}
|
||||
|
||||
// Extraire le prefix et le compteur
|
||||
$parts = explode('-', $newNumber);
|
||||
$prefix = $parts[0].'-';
|
||||
$targetNum = (int) $parts[1];
|
||||
$previousNum = (int) $parts[1] - 1;
|
||||
|
||||
// On cree l'entree precedente pour que le prochain generate() retourne le bon numero
|
||||
$previousNum = $targetNum - 1;
|
||||
if ($previousNum < 0) {
|
||||
$this->addFlash('error', 'Le numero doit etre au minimum 00001.');
|
||||
|
||||
return $this->redirectToRoute('app_admin_order_number');
|
||||
return 'Le numero doit etre au minimum 00001.';
|
||||
}
|
||||
|
||||
$previousNumOrder = $prefix.str_pad((string) $previousNum, 5, '0', \STR_PAD_LEFT);
|
||||
|
||||
// Verifier si l'entree precedente existe deja
|
||||
$existingPrevious = $repository->findOneBy(['numOrder' => $previousNumOrder]);
|
||||
if (null === $existingPrevious && $previousNum > 0) {
|
||||
if (null === $repository->findOneBy(['numOrder' => $previousNumOrder]) && $previousNum > 0) {
|
||||
$placeholder = new OrderNumber($previousNumOrder);
|
||||
$placeholder->markAsUsed();
|
||||
$em->persist($placeholder);
|
||||
@@ -78,6 +76,6 @@ class OrderNumberController extends AbstractController
|
||||
|
||||
$this->addFlash('success', 'Prochain numero de commande mis a jour : '.$newNumber);
|
||||
|
||||
return $this->redirectToRoute('app_admin_order_number');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,14 @@ use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||
#[IsGranted('ROLE_ROOT')]
|
||||
class TarificationController extends AbstractController
|
||||
{
|
||||
private const TARIF_PREFIX = 'Tarif "';
|
||||
|
||||
#[Route('', name: '')]
|
||||
public function index(TarificationService $tarification): Response
|
||||
{
|
||||
$created = $tarification->ensureDefaultPrices();
|
||||
foreach ($created as $type) {
|
||||
$this->addFlash('success', 'Tarif "'.$type.'" cree automatiquement.');
|
||||
$this->addFlash('success', self::TARIF_PREFIX.$type.'" cree automatiquement.');
|
||||
}
|
||||
|
||||
return $this->render('admin/tarification/index.html.twig', [
|
||||
@@ -58,17 +60,17 @@ class TarificationController extends AbstractController
|
||||
// Sync Stripe
|
||||
try {
|
||||
$stripePriceService->syncPrice($price);
|
||||
$this->addFlash('success', 'Tarif "'.$price->getType().'" mis a jour et synchronise avec Stripe.');
|
||||
$this->addFlash('success', self::TARIF_PREFIX.$price->getType().'" mis a jour et synchronise avec Stripe.');
|
||||
} catch (\Throwable $e) {
|
||||
$em->flush(); // Sauvegarder quand meme les modifs locales
|
||||
$this->addFlash('success', 'Tarif "'.$price->getType().'" mis a jour.');
|
||||
$em->flush();
|
||||
$this->addFlash('success', self::TARIF_PREFIX.$price->getType().'" mis a jour.');
|
||||
$this->addFlash('error', 'Erreur Stripe : '.$e->getMessage());
|
||||
}
|
||||
|
||||
// Sync Meilisearch
|
||||
try {
|
||||
$meilisearch->indexPrice($price);
|
||||
} catch (\Throwable) {
|
||||
} catch (\Throwable $e) {
|
||||
$this->addFlash('error', 'Erreur Meilisearch : '.$e->getMessage());
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('app_admin_tarification');
|
||||
|
||||
Reference in New Issue
Block a user