Loading .env.dist +3 −0 Changes for .env.dist: 3 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -70,6 +70,9 @@ PEGASE_LANGUES= # Dates des semestres, début et fin en mois-jour PEGASE_SEMESTRE_1=09-01:01-31 PEGASE_SEMESTRE_2=01-15:06-30 # Limite mémoire PHP de l'import, qui croît avec le nombre de cours et de périodes : à augmenter si la mémoire # affichée dans le bilan de l'import s'en approche (-1 pour aucune limite) PEGASE_MEMOIRE=512M # Informations de connexion à l'API via Basic Auth, à communiquer à Smile API_USER= Loading README.md +3 −0 Changes for README.md: 3 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -132,6 +132,9 @@ PEGASE_LANGUES= # Dates des semestres, début et fin en mois-jour PEGASE_SEMESTRE_1=09-01:01-31 PEGASE_SEMESTRE_2=01-15:06-30 # Limite mémoire PHP de l'import, qui croît avec le nombre de cours et de périodes : à augmenter si la mémoire # affichée dans le bilan de l'import s'en approche (-1 pour aucune limite) PEGASE_MEMOIRE=512M # Informations de connexion à l'API via Basic Auth, à communiquer à Smile API_USER= Loading api/config/services.yaml +1 −0 Changes for api/config/services.yaml: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ parameters: env(PEGASE_LANGUES): '' env(PEGASE_SEMESTRE_1): '09-01:01-31' env(PEGASE_SEMESTRE_2): '01-15:06-30' env(PEGASE_MEMOIRE): '512M' services: # default configuration for services in *this* file Loading api/src/Command/ImportPegaseCommand.php +19 −0 Changes for api/src/Command/ImportPegaseCommand.php: 19 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ use App\Entity\CourseInstance; use App\Entity\Ounit; use App\Entity\PegaseImportLog; use App\Entity\Programme; use App\Pegase\PegaseException; use App\Pegase\PegaseImporter; use App\Pegase\ResultatImport; use Doctrine\Common\Collections\ArrayCollection; Loading Loading @@ -44,6 +45,8 @@ final class ImportPegaseCommand extends Command * @param bool $pegaseActive valeur de PEGASE_ENABLED * @param int $lot entités enregistrées entre deux vidages du gestionnaire, pour * borner la mémoire * @param string $memoire PEGASE_MEMOIRE, limite mémoire PHP de l'import (512M, -1 sans * limite) * @param LoggerInterface $logger progression de l'enregistrement */ public function __construct( Loading @@ -54,6 +57,8 @@ final class ImportPegaseCommand extends Command #[Autowire(env: 'bool:PEGASE_ENABLED')] private readonly bool $pegaseActive, private readonly int $lot = 500, #[Autowire(env: 'PEGASE_MEMOIRE')] private readonly string $memoire = '512M', private readonly LoggerInterface $logger = new NullLogger(), ) { parent::__construct(); Loading @@ -73,6 +78,7 @@ final class ImportPegaseCommand extends Command $io->title('Import des données depuis Pegase'); $io->writeln($journal->date->format('Y-m-d H:i:s')); try { $this->appliquerLimiteMemoire(); $resultat = $this->importer->importer($journal->date); $journal->nbOunits = \count($resultat->ounits); $journal->nbProgrammes = \count($resultat->programmes); Loading Loading @@ -106,6 +112,19 @@ final class ImportPegaseCommand extends Command return Command::SUCCESS; } /** * @throws PegaseException si PEGASE_MEMOIRE n'est pas une limite valide ou est inférieure à la mémoire utilisée */ private function appliquerLimiteMemoire(): void { // Avertissement de ini_set remplacé par l'exception if (preg_match('/^(-1|\d+[KMG]?)$/i', $this->memoire) && false !== @ini_set('memory_limit', $this->memoire)) { return; } $message = \sprintf('PEGASE_MEMOIRE : « %s » n\'est pas une limite mémoire utilisable (512M)', $this->memoire); throw new PegaseException($message); } private function enregistrer(ResultatImport $resultat, PegaseImportLog $journal): void { $this->manager->wrapInTransaction(function (EntityManagerInterface $manager) use ($resultat, $journal): void { Loading api/tests/Command/ImportPegaseCommandTest.php +32 −2 Changes for api/tests/Command/ImportPegaseCommandTest.php: 32 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -160,8 +160,30 @@ class ImportPegaseCommandTest extends KernelTestCase $this->assertSame(['FAILURE'], $this->statuts()); } private function executer(string $annees = self::ANNEES, bool $pegaseActive = true, int $lot = 500): CommandTester /** * Vérifie le refus d'une limite mémoire invalide ou trop basse, sans appel à Pegase, avec une ligne de journal. */ public function testLimiteMemoireInutilisable(): void { $limite = ini_get('memory_limit'); foreach (['beaucoup', '1M'] as $memoire) { $tester = $this->executer(memoire: $memoire); $this->assertSame(Command::FAILURE, $tester->getStatusCode()); $this->assertStringContainsString('PEGASE_MEMOIRE : « '.$memoire.' »', $tester->getDisplay()); } $this->assertSame($limite, ini_get('memory_limit')); $this->assertSame([], $this->serveur->requetes); $this->assertSame(['FAILURE', 'FAILURE'], $this->statuts()); } private function executer( string $annees = self::ANNEES, bool $pegaseActive = true, int $lot = 500, string $memoire = '512M', ): CommandTester { $client = $this->serveur->client(); $importer = new PegaseImporter( $client, Loading @@ -169,7 +191,15 @@ class ImportPegaseCommandTest extends KernelTestCase new Configuration($annees, 'ECA:en,UEA:en,ECN:gmq', '09-01:01-31', '01-15:06-30'), ); $container = static::getContainer(); $commande = new ImportPegaseCommand($importer, $container->get(EntityManagerInterface::class), $container->get('doctrine'), new MockClock('2026-10-08 12:00:00'), $pegaseActive, $lot); $commande = new ImportPegaseCommand( $importer, $container->get(EntityManagerInterface::class), $container->get('doctrine'), new MockClock('2026-10-08 12:00:00'), $pegaseActive, $lot, $memoire, ); $tester = new CommandTester($commande); $tester->execute([]); Loading Loading
.env.dist +3 −0 Changes for .env.dist: 3 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -70,6 +70,9 @@ PEGASE_LANGUES= # Dates des semestres, début et fin en mois-jour PEGASE_SEMESTRE_1=09-01:01-31 PEGASE_SEMESTRE_2=01-15:06-30 # Limite mémoire PHP de l'import, qui croît avec le nombre de cours et de périodes : à augmenter si la mémoire # affichée dans le bilan de l'import s'en approche (-1 pour aucune limite) PEGASE_MEMOIRE=512M # Informations de connexion à l'API via Basic Auth, à communiquer à Smile API_USER= Loading
README.md +3 −0 Changes for README.md: 3 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -132,6 +132,9 @@ PEGASE_LANGUES= # Dates des semestres, début et fin en mois-jour PEGASE_SEMESTRE_1=09-01:01-31 PEGASE_SEMESTRE_2=01-15:06-30 # Limite mémoire PHP de l'import, qui croît avec le nombre de cours et de périodes : à augmenter si la mémoire # affichée dans le bilan de l'import s'en approche (-1 pour aucune limite) PEGASE_MEMOIRE=512M # Informations de connexion à l'API via Basic Auth, à communiquer à Smile API_USER= Loading
api/config/services.yaml +1 −0 Changes for api/config/services.yaml: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ parameters: env(PEGASE_LANGUES): '' env(PEGASE_SEMESTRE_1): '09-01:01-31' env(PEGASE_SEMESTRE_2): '01-15:06-30' env(PEGASE_MEMOIRE): '512M' services: # default configuration for services in *this* file Loading
api/src/Command/ImportPegaseCommand.php +19 −0 Changes for api/src/Command/ImportPegaseCommand.php: 19 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ use App\Entity\CourseInstance; use App\Entity\Ounit; use App\Entity\PegaseImportLog; use App\Entity\Programme; use App\Pegase\PegaseException; use App\Pegase\PegaseImporter; use App\Pegase\ResultatImport; use Doctrine\Common\Collections\ArrayCollection; Loading Loading @@ -44,6 +45,8 @@ final class ImportPegaseCommand extends Command * @param bool $pegaseActive valeur de PEGASE_ENABLED * @param int $lot entités enregistrées entre deux vidages du gestionnaire, pour * borner la mémoire * @param string $memoire PEGASE_MEMOIRE, limite mémoire PHP de l'import (512M, -1 sans * limite) * @param LoggerInterface $logger progression de l'enregistrement */ public function __construct( Loading @@ -54,6 +57,8 @@ final class ImportPegaseCommand extends Command #[Autowire(env: 'bool:PEGASE_ENABLED')] private readonly bool $pegaseActive, private readonly int $lot = 500, #[Autowire(env: 'PEGASE_MEMOIRE')] private readonly string $memoire = '512M', private readonly LoggerInterface $logger = new NullLogger(), ) { parent::__construct(); Loading @@ -73,6 +78,7 @@ final class ImportPegaseCommand extends Command $io->title('Import des données depuis Pegase'); $io->writeln($journal->date->format('Y-m-d H:i:s')); try { $this->appliquerLimiteMemoire(); $resultat = $this->importer->importer($journal->date); $journal->nbOunits = \count($resultat->ounits); $journal->nbProgrammes = \count($resultat->programmes); Loading Loading @@ -106,6 +112,19 @@ final class ImportPegaseCommand extends Command return Command::SUCCESS; } /** * @throws PegaseException si PEGASE_MEMOIRE n'est pas une limite valide ou est inférieure à la mémoire utilisée */ private function appliquerLimiteMemoire(): void { // Avertissement de ini_set remplacé par l'exception if (preg_match('/^(-1|\d+[KMG]?)$/i', $this->memoire) && false !== @ini_set('memory_limit', $this->memoire)) { return; } $message = \sprintf('PEGASE_MEMOIRE : « %s » n\'est pas une limite mémoire utilisable (512M)', $this->memoire); throw new PegaseException($message); } private function enregistrer(ResultatImport $resultat, PegaseImportLog $journal): void { $this->manager->wrapInTransaction(function (EntityManagerInterface $manager) use ($resultat, $journal): void { Loading
api/tests/Command/ImportPegaseCommandTest.php +32 −2 Changes for api/tests/Command/ImportPegaseCommandTest.php: 32 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -160,8 +160,30 @@ class ImportPegaseCommandTest extends KernelTestCase $this->assertSame(['FAILURE'], $this->statuts()); } private function executer(string $annees = self::ANNEES, bool $pegaseActive = true, int $lot = 500): CommandTester /** * Vérifie le refus d'une limite mémoire invalide ou trop basse, sans appel à Pegase, avec une ligne de journal. */ public function testLimiteMemoireInutilisable(): void { $limite = ini_get('memory_limit'); foreach (['beaucoup', '1M'] as $memoire) { $tester = $this->executer(memoire: $memoire); $this->assertSame(Command::FAILURE, $tester->getStatusCode()); $this->assertStringContainsString('PEGASE_MEMOIRE : « '.$memoire.' »', $tester->getDisplay()); } $this->assertSame($limite, ini_get('memory_limit')); $this->assertSame([], $this->serveur->requetes); $this->assertSame(['FAILURE', 'FAILURE'], $this->statuts()); } private function executer( string $annees = self::ANNEES, bool $pegaseActive = true, int $lot = 500, string $memoire = '512M', ): CommandTester { $client = $this->serveur->client(); $importer = new PegaseImporter( $client, Loading @@ -169,7 +191,15 @@ class ImportPegaseCommandTest extends KernelTestCase new Configuration($annees, 'ECA:en,UEA:en,ECN:gmq', '09-01:01-31', '01-15:06-30'), ); $container = static::getContainer(); $commande = new ImportPegaseCommand($importer, $container->get(EntityManagerInterface::class), $container->get('doctrine'), new MockClock('2026-10-08 12:00:00'), $pegaseActive, $lot); $commande = new ImportPegaseCommand( $importer, $container->get(EntityManagerInterface::class), $container->get('doctrine'), new MockClock('2026-10-08 12:00:00'), $pegaseActive, $lot, $memoire, ); $tester = new CommandTester($commande); $tester->execute([]); Loading