Loading bin/validation_cines.sh +2 −2 Original line number Diff line number Diff line Loading @@ -8,8 +8,8 @@ # 2/ l'URL du web service, FACULTATIF ("https://facile.cines.fr/xml", par défaut). ########################################################################################## #export http_proxy=proxy.unicaen.fr:3128 #export https_proxy=proxy.unicaen.fr:3128 export http_proxy=proxy.unicaen.fr:3128 export https_proxy=proxy.unicaen.fr:3128 DEFAULT_URL="https://facile.cines.fr/xml" Loading module/Application/config/others/liste-diffusion.config.php +38 −8 Original line number Diff line number Diff line Loading @@ -7,10 +7,12 @@ use Application\Controller\ListeDiffusionController; use Application\Provider\Privilege\ListeDiffusionPrivileges; use Application\Service\ListeDiffusion\ListeDiffusionService; use Application\Service\ListeDiffusion\ListeDiffusionServiceFactory; use Application\Service\ListeDiffusion\Plugin\ListeDiffusionRolePlugin; use Application\Service\ListeDiffusion\Plugin\ListeDiffusionRolePluginFactory; use Application\Service\ListeDiffusion\Plugin\ListeDiffusionStructurePlugin; use Application\Service\ListeDiffusion\Plugin\ListeDiffusionStructurePluginFactory; use Application\Service\ListeDiffusion\Plugin\Structure\ListeDiffusionEcoleDoctoralePlugin; use Application\Service\ListeDiffusion\Plugin\Structure\ListeDiffusionEcoleDoctoralePluginFactory; use Application\Service\ListeDiffusion\Handler\ListeDiffusionHandler; use Application\Service\ListeDiffusion\Handler\ListeDiffusionHandlerFactory; use Application\Service\ListeDiffusion\Plugin\Structure\ListeDiffusionUniteRecherchePlugin; use Application\Service\ListeDiffusion\Plugin\Structure\ListeDiffusionUniteRecherchePluginFactory; use UnicaenAuth\Guard\PrivilegeController; use Zend\Router\Http\Literal; use Zend\Router\Http\Segment; Loading @@ -30,6 +32,7 @@ return [ 'controller' => ListeDiffusionController::class, 'action' => [ 'consulter', 'exporter-tableau', ], 'privileges' => ListeDiffusionPrivileges::LISTE_DIFFUSION_CONSULTER, ], Loading Loading @@ -60,11 +63,11 @@ return [ 'liste' => [ 'type' => Segment::class, 'options' => [ 'route' => '/:liste', 'route' => '/:adresse', // exemple: /consulter/ed591.doctorants.ucn@normandie-univ.fr // exemple: /consulter/ed591.doctorants@normandie-univ.fr 'constraints' => [ 'liste' => '[a-zA-Z0-9-_.@]+', 'adresse' => '[a-zA-Z0-9-_.@]+', ], 'defaults' => [ /** @see ListeDiffusionController::consulterAction() */ Loading Loading @@ -95,6 +98,34 @@ return [ ], ], ], 'export-tableau' => [ 'type' => Literal::class, 'options' => [ 'route' => '/exporter-tableau', 'defaults' => [ /** @see ListeDiffusionController::exporterTableauAction() */ 'action' => 'exporter-tableau', ], ], ] ], ], ], ], 'navigation' => [ 'default' => [ 'home' => [ 'pages' => [ 'admin' => [ 'pages' => [ 'liste-diffusion' => [ 'label' => 'Listes de diffusion', 'route' => 'liste-diffusion', 'icon' => 'glyphicon glyphicon-enveloppe', 'resource' => PrivilegeController::getResourceId(ListeDiffusionController::class, 'index'), ], ], ], ], ], ], Loading @@ -102,8 +133,7 @@ return [ 'service_manager' => [ 'factories' => [ ListeDiffusionService::class => ListeDiffusionServiceFactory::class, ListeDiffusionStructurePlugin::class => ListeDiffusionStructurePluginFactory::class, ListeDiffusionRolePlugin::class => ListeDiffusionRolePluginFactory::class, ListeDiffusionHandler::class => ListeDiffusionHandlerFactory::class, ], ], 'controllers' => [ Loading module/Application/src/Application/Controller/Factory/ListeDiffusionControllerFactory.php +28 −0 Original line number Diff line number Diff line Loading @@ -3,10 +3,14 @@ namespace Application\Controller\Factory; use Application\Controller\ListeDiffusionController; use Application\Service\EcoleDoctorale\EcoleDoctoraleService; use Application\Service\Etablissement\EtablissementService; use Application\Service\File\FileService; use Application\Service\Individu\IndividuService; use Application\Service\ListeDiffusion\ListeDiffusionService; use Application\Service\Notification\NotifierService; use Application\Service\Role\RoleService; use Application\Service\Structure\StructureService; use Interop\Container\ContainerInterface; class ListeDiffusionControllerFactory Loading Loading @@ -39,6 +43,30 @@ class ListeDiffusionControllerFactory $notifierService = $container->get(NotifierService::class); $controller->setNotifierService($notifierService); /** * @var RoleService $roleService */ $roleService = $container->get(RoleService::class); $controller->setRoleService($roleService); /** * @var EtablissementService $etablissementService */ $etablissementService = $container->get(EtablissementService::class); $controller->setEtablissementService($etablissementService); /** * @var StructureService $structureService */ $structureService = $container->get(StructureService::class); $controller->setStructureService($structureService); /** * @var EtablissementService $etablissementService */ $ecoleDoctoraleService = $container->get(EcoleDoctoraleService::class); $controller->setEcoleDoctoraleService($ecoleDoctoraleService); return $controller; } } No newline at end of file module/Application/src/Application/Controller/ListeDiffusionController.php +272 −11 Original line number Diff line number Diff line Loading @@ -2,13 +2,27 @@ namespace Application\Controller; use Application\Entity\Db\EcoleDoctorale; use Application\Entity\Db\Etablissement; use Application\Entity\Db\Individu; use Application\Entity\Db\ListeDiffusion; use Application\Entity\Db\Role; use Application\Entity\Db\TypeStructure; use Application\Service\EcoleDoctorale\EcoleDoctoraleServiceAwareTrait; use Application\Service\Etablissement\EtablissementServiceAwareTrait; use Application\Service\File\FileServiceAwareTrait; use Application\Service\Individu\IndividuServiceAwareTrait; use Application\Service\ListeDiffusion\Address\ListeDiffusionAddressGenerator; use Application\Service\ListeDiffusion\ListeDiffusionServiceAwareTrait; use Application\Service\Notification\NotifierServiceAwareTrait; use Application\Service\Role\RoleServiceAwareTrait; use Application\Service\Structure\StructureServiceAwareTrait; use Doctrine\ORM\ORMException; use InvalidArgumentException; use SplObjectStorage; use UnicaenApp\View\Model\CsvModel; use Webmozart\Assert\Assert; use Zend\Http\Response; use Zend\View\Model\ViewModel; class ListeDiffusionController extends AbstractController Loading @@ -17,6 +31,10 @@ class ListeDiffusionController extends AbstractController use IndividuServiceAwareTrait; use FileServiceAwareTrait; use NotifierServiceAwareTrait; use StructureServiceAwareTrait; use EtablissementServiceAwareTrait; use EcoleDoctoraleServiceAwareTrait; use RoleServiceAwareTrait; /** * Adresse complète de la liste de diffusion, ex : Loading @@ -29,22 +47,245 @@ class ListeDiffusionController extends AbstractController * - 'doctorants' (ou 'dirtheses') est la "cible" ; * - 'insa' est le source_code unique de l'établissement en minuscules. * * @var string * @var ListeDiffusion */ protected $liste; private $liste; /** * @return array|ViewModel * @var SplObjectStorage */ private $dataByEtablissement; /** * @var ListeDiffusion[] Format : 'adresse' => ListeDiffusion */ private $listesDiffusionActives = []; /** * @var string[] Format : 'adresse' => 'adresse' */ private $adressesGenerees = []; /** * @return array|Response|ViewModel */ public function indexAction() { $listes = $this->listeDiffusionService->fetchListesDiffusion(); $etablissement = $this->params()->fromQuery('etablissement'); if ($this->params()->fromPost()) { return $this->modifierListes(); } /** @var EcoleDoctorale[] $ecolesDoctorales */ $etablissements = $this->etablissementService->getRepository()->findAllEtablissementsInscriptions(true); $ecolesDoctorales = $this->structureService->getAllStructuresAffichablesByType(TypeStructure::CODE_ECOLE_DOCTORALE, 'libelle', false, true); $codesRolesAvecTemoinsED = [ Role::CODE_DOCTORANT => true, Role::CODE_DIRECTEUR_THESE => true, Role::CODE_BU => false, Role::CODE_BDD => false, Role::CODE_ADMIN_TECH => false, // NB: pas de structure liée ]; $roles = $this->roleService->getRepository()->findByCodes(array_keys($codesRolesAvecTemoinsED)); $etablissementsAsStructures = array_map(function(Etablissement $e) { return $e->getStructure(); }, $etablissements); $roles = array_filter($roles, function(Role $role) use ($etablissementsAsStructures) { return $role->getStructure() === null || // ex: Admin tech in_array($role->getStructure(), $etablissementsAsStructures); }); $this->prepareDataForView($etablissements, $ecolesDoctorales, $roles, $codesRolesAvecTemoinsED); $this->loadListesDiffusionActives(); $adressesListesActives = array_keys($this->listesDiffusionActives); $adressesListesActivesMaisInexistanteDansGenerees = array_diff($adressesListesActives, $this->adressesGenerees); return new ViewModel([ 'listes' => $listes, 'codeEtablissement' => $etablissement, 'dataByEtablissement' => $this->dataByEtablissement, 'listesDiffusionActives' => $this->listesDiffusionActives, 'adressesListesActivesMaisInexistanteDansGenerees' => $adressesListesActivesMaisInexistanteDansGenerees, 'urlSympa' => $this->listeDiffusionService->getUrlSympa(), ]); } /** * Fetche en bdd les listes de diffusion actives. * NB: pour l'instant le table LISTE_DIFF ne contient que les listes activées. */ private function loadListesDiffusionActives() { $this->listesDiffusionActives = []; $listesDiffusionActives = $this->listeDiffusionService->fetchListesDiffusionActives(); foreach ($listesDiffusionActives as $listeDiffusion) { $this->listesDiffusionActives[$listeDiffusion->getAdresse()] = $listeDiffusion; } } /** * @return Response */ private function modifierListes() { $post = $this->params()->fromPost(); $etablissement = $post['etablissement'] ?? 'Tous'; $adresses = $post['listes'] ?? []; try { $this->enregistrer((array) $adresses, $etablissement); } catch (ORMException $e) { $this->flashMessenger()->addErrorMessage("Erreur rencontrée lors de l'enregistrement des listes : " . $e->getMessage()); error_log($e->getMessage() . PHP_EOL . $e->getTraceAsString()); } return $this->redirect()->toRoute(null, [], ['query' => ['etablissement' => $etablissement]], true); } /** * @param string[] $adresses * @param string $etablissement * @throws ORMException */ private function enregistrer(array $adresses, string $etablissement) { $adressesToDelete = array_filter($adresses, function (string $checked) { return $checked === '0'; }); $adressesToInsert = array_filter($adresses, function (string $checked) { return $checked === '1'; }); $this->listeDiffusionService->deleteListesDiffusions(array_keys($adressesToDelete)); $listes = []; foreach (array_keys($adressesToInsert) as $adresse) { $liste = $this->listeDiffusionService->findListeDiffusionByAdresse($adresse); $data = [ 'adresse' => $adresse, 'enabled' => true, ]; if ($liste === null) { $liste = $this->listeDiffusionService->createListeDiffusion($data); } else { $this->listeDiffusionService->updateListeDiffusion($liste, $data); } $listes[$adresse] = $liste; } $this->listeDiffusionService->saveListesDiffusions($listes); $this->flashMessenger()->addSuccessMessage( sprintf("Enregistrement effectué avec succès pour '%s' : %d adresses actives, %d inactives.", $etablissement, count($adressesToInsert), count($adressesToDelete))); } /** * @param Etablissement[] $etablissements * @param EcoleDoctorale[] $ecolesDoctorales * @param Role[] $roles * @param array $codesRolesAvecTemoinsED */ private function prepareDataForView(array $etablissements, array $ecolesDoctorales, array $roles, array $codesRolesAvecTemoinsED) { $this->adressesGenerees = []; // pour tests : //$etablissements = array_slice($etablissements, -1); // // Par établissement. // $dataByEtablissement = new SplObjectStorage(); foreach ($etablissements as $etablissement) { $rolesForEtablissement = array_filter($roles, function (Role $r) use ($etablissement) { return $r->getStructure() === $etablissement->getStructure(); }); $dataByRole = new SplObjectStorage(); foreach ($rolesForEtablissement as $role) { if ($codesRolesAvecTemoinsED[$role->getCode()] === true) { $dataByED = new SplObjectStorage(); // d'abord, toute ED confondue $edTouteConfondue = $this->ecoleDoctoraleService->createTouteEcoleDoctoraleConfondue(); $ng = $this->listeDiffusionService->createNameGenerator($edTouteConfondue, $role, $role->getStructure()); $dataByED->attach($edTouteConfondue, $this->prepareListeDataForView($ng)); // ensuite, par ED foreach ($ecolesDoctorales as $ed) { $ng = $this->listeDiffusionService->createNameGenerator($ed, $role, $role->getStructure()); $dataByED->attach($ed, $this->prepareListeDataForView($ng)); } $dataByRole->attach($role, $dataByED); } else { // hors ED $ng = $this->listeDiffusionService->createNameGenerator(null, $role, $role->getStructure()); $dataByRole->attach($role, $this->prepareListeDataForView($ng)); } } $dataByEtablissement->attach($etablissement, $dataByRole); } $rolesAvecTemoinsED = array_filter($roles, function (Role $r) use ($codesRolesAvecTemoinsED) { return $codesRolesAvecTemoinsED[$r->getCode()] === true; }); if (count($etablissements) > 1) { // // Tous établissements confondus. // /** @var Role $rolePrec */ $rolePrec = null; $dataByRole = new SplObjectStorage(); foreach ($rolesAvecTemoinsED as $role) { if ($rolePrec && ($isSameRoleAgain = $rolePrec->getCode() === $role->getCode())) { continue; // on ne retient qu'un rôle pour tous les établissements confondus } $dataByED = new SplObjectStorage(); // d'abord, toute ED confondue $edTouteConfondue = $this->ecoleDoctoraleService->createTouteEcoleDoctoraleConfondue(); $ng = $this->listeDiffusionService->createNameGenerator($edTouteConfondue, $role, null); $dataByED->attach($edTouteConfondue, $this->prepareListeDataForView($ng)); // ensuite, par ED foreach ($ecolesDoctorales as $ed) { $ng = $this->listeDiffusionService->createNameGenerator($ed, $role, null); $dataByED->attach($ed, $this->prepareListeDataForView($ng)); } $dataByRole->attach($role, $dataByED); $rolePrec = $role; } $etablissementToutConfondu = $this->etablissementService->createToutEtablissementConfondu(); $dataByEtablissement->attach($etablissementToutConfondu, $dataByRole); } // NB: $this->adressesGenerees a été peuplé. $this->dataByEtablissement = $dataByEtablissement; } /** * @param ListeDiffusionAddressGenerator $namer * @return array */ private function prepareListeDataForView(ListeDiffusionAddressGenerator $namer) { $domain = $this->listeDiffusionService->getEmailDomain(); $namer->setDomain($domain); try { $name = $namer->generateName(); $link = $this->url()->fromRoute('liste-diffusion/liste', ['adresse' => $name]); $enabled = true; } catch (InvalidArgumentException $e) { $name = "Anomalie rencontrée : " . $e->getMessage(); $link = null; $enabled = false; } // collecte avec indexation par adresse $this->adressesGenerees[$name] = $name; return [ 'name' => $name, 'label' => $name, 'link' => $link, 'enabled' => $enabled, ]; } /** * @return ViewModel */ Loading @@ -52,9 +293,6 @@ class ListeDiffusionController extends AbstractController { $this->loadRequestParams(); $listesDeclarees = $this->listeDiffusionService->fetchListesDiffusion(); Assert::inArray($this->liste, $listesDeclarees, "Liste spécifiée non déclarée."); $this->listeDiffusionService->setListe($this->liste); $this->listeDiffusionService->init(); Loading Loading @@ -123,6 +361,25 @@ class ListeDiffusionController extends AbstractController $this->fileService->downloadFileFromContent($content, $filename); } /** * @return CsvModel */ public function exporterTableauAction() { $data = $this->listeDiffusionService->createDataForCsvExport($this->url()); $header = current($data); $data = array_slice($data, 1); $model = new CsvModel(); $model->setDelimiter(';'); $model->setEnclosure('"'); $model->setHeader($header); $model->setData($data); $model->setFilename(sprintf('sygal_listediff_sympa_%s.csv', date_create('now')->format("Ymd-His"))); return $model; } /** * Gestion des ABONNÉS sans adresse mail. */ Loading Loading @@ -153,12 +410,16 @@ class ListeDiffusionController extends AbstractController } /** * @return string * @return ListeDiffusion */ private function getRequestedListe() { $liste = $this->params()->fromRoute('liste'); Assert::notNull($liste, "Aucune liste spécifiée."); $adresse = $this->params()->fromRoute('adresse'); Assert::notNull($adresse, "Aucune adresse spécifiée."); /** @var ListeDiffusion $liste */ $liste = $this->listeDiffusionService->getRepository()->findOneBy(['adresse' => $adresse]); Assert::notNull($liste, "Aucune liste active trouvée avec l'adresse spécifiée."); return $liste; } Loading module/Application/src/Application/Entity/Db/EcoleDoctorale.php +11 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ class EcoleDoctorale implements StructureConcreteInterface, HistoriqueAwareInter use HistoriqueAwareTrait; use SourceAwareTrait; const CODE_TOUTE_ECOLE_DOCTORALE_CONFONDUE = 'TOUTE_ED'; /** * @var integer */ Loading Loading @@ -210,5 +212,13 @@ class EcoleDoctorale implements StructureConcreteInterface, HistoriqueAwareInter return $this; } /** * Teste si cette école doctorale est la pseudo-école doctorale "Toute école doctorale confondue". * * @return bool */ public function estTouteEcoleDoctoraleConfondue() { return $this->getStructure()->getCode() === self::CODE_TOUTE_ECOLE_DOCTORALE_CONFONDUE; } } No newline at end of file Loading
bin/validation_cines.sh +2 −2 Original line number Diff line number Diff line Loading @@ -8,8 +8,8 @@ # 2/ l'URL du web service, FACULTATIF ("https://facile.cines.fr/xml", par défaut). ########################################################################################## #export http_proxy=proxy.unicaen.fr:3128 #export https_proxy=proxy.unicaen.fr:3128 export http_proxy=proxy.unicaen.fr:3128 export https_proxy=proxy.unicaen.fr:3128 DEFAULT_URL="https://facile.cines.fr/xml" Loading
module/Application/config/others/liste-diffusion.config.php +38 −8 Original line number Diff line number Diff line Loading @@ -7,10 +7,12 @@ use Application\Controller\ListeDiffusionController; use Application\Provider\Privilege\ListeDiffusionPrivileges; use Application\Service\ListeDiffusion\ListeDiffusionService; use Application\Service\ListeDiffusion\ListeDiffusionServiceFactory; use Application\Service\ListeDiffusion\Plugin\ListeDiffusionRolePlugin; use Application\Service\ListeDiffusion\Plugin\ListeDiffusionRolePluginFactory; use Application\Service\ListeDiffusion\Plugin\ListeDiffusionStructurePlugin; use Application\Service\ListeDiffusion\Plugin\ListeDiffusionStructurePluginFactory; use Application\Service\ListeDiffusion\Plugin\Structure\ListeDiffusionEcoleDoctoralePlugin; use Application\Service\ListeDiffusion\Plugin\Structure\ListeDiffusionEcoleDoctoralePluginFactory; use Application\Service\ListeDiffusion\Handler\ListeDiffusionHandler; use Application\Service\ListeDiffusion\Handler\ListeDiffusionHandlerFactory; use Application\Service\ListeDiffusion\Plugin\Structure\ListeDiffusionUniteRecherchePlugin; use Application\Service\ListeDiffusion\Plugin\Structure\ListeDiffusionUniteRecherchePluginFactory; use UnicaenAuth\Guard\PrivilegeController; use Zend\Router\Http\Literal; use Zend\Router\Http\Segment; Loading @@ -30,6 +32,7 @@ return [ 'controller' => ListeDiffusionController::class, 'action' => [ 'consulter', 'exporter-tableau', ], 'privileges' => ListeDiffusionPrivileges::LISTE_DIFFUSION_CONSULTER, ], Loading Loading @@ -60,11 +63,11 @@ return [ 'liste' => [ 'type' => Segment::class, 'options' => [ 'route' => '/:liste', 'route' => '/:adresse', // exemple: /consulter/ed591.doctorants.ucn@normandie-univ.fr // exemple: /consulter/ed591.doctorants@normandie-univ.fr 'constraints' => [ 'liste' => '[a-zA-Z0-9-_.@]+', 'adresse' => '[a-zA-Z0-9-_.@]+', ], 'defaults' => [ /** @see ListeDiffusionController::consulterAction() */ Loading Loading @@ -95,6 +98,34 @@ return [ ], ], ], 'export-tableau' => [ 'type' => Literal::class, 'options' => [ 'route' => '/exporter-tableau', 'defaults' => [ /** @see ListeDiffusionController::exporterTableauAction() */ 'action' => 'exporter-tableau', ], ], ] ], ], ], ], 'navigation' => [ 'default' => [ 'home' => [ 'pages' => [ 'admin' => [ 'pages' => [ 'liste-diffusion' => [ 'label' => 'Listes de diffusion', 'route' => 'liste-diffusion', 'icon' => 'glyphicon glyphicon-enveloppe', 'resource' => PrivilegeController::getResourceId(ListeDiffusionController::class, 'index'), ], ], ], ], ], ], Loading @@ -102,8 +133,7 @@ return [ 'service_manager' => [ 'factories' => [ ListeDiffusionService::class => ListeDiffusionServiceFactory::class, ListeDiffusionStructurePlugin::class => ListeDiffusionStructurePluginFactory::class, ListeDiffusionRolePlugin::class => ListeDiffusionRolePluginFactory::class, ListeDiffusionHandler::class => ListeDiffusionHandlerFactory::class, ], ], 'controllers' => [ Loading
module/Application/src/Application/Controller/Factory/ListeDiffusionControllerFactory.php +28 −0 Original line number Diff line number Diff line Loading @@ -3,10 +3,14 @@ namespace Application\Controller\Factory; use Application\Controller\ListeDiffusionController; use Application\Service\EcoleDoctorale\EcoleDoctoraleService; use Application\Service\Etablissement\EtablissementService; use Application\Service\File\FileService; use Application\Service\Individu\IndividuService; use Application\Service\ListeDiffusion\ListeDiffusionService; use Application\Service\Notification\NotifierService; use Application\Service\Role\RoleService; use Application\Service\Structure\StructureService; use Interop\Container\ContainerInterface; class ListeDiffusionControllerFactory Loading Loading @@ -39,6 +43,30 @@ class ListeDiffusionControllerFactory $notifierService = $container->get(NotifierService::class); $controller->setNotifierService($notifierService); /** * @var RoleService $roleService */ $roleService = $container->get(RoleService::class); $controller->setRoleService($roleService); /** * @var EtablissementService $etablissementService */ $etablissementService = $container->get(EtablissementService::class); $controller->setEtablissementService($etablissementService); /** * @var StructureService $structureService */ $structureService = $container->get(StructureService::class); $controller->setStructureService($structureService); /** * @var EtablissementService $etablissementService */ $ecoleDoctoraleService = $container->get(EcoleDoctoraleService::class); $controller->setEcoleDoctoraleService($ecoleDoctoraleService); return $controller; } } No newline at end of file
module/Application/src/Application/Controller/ListeDiffusionController.php +272 −11 Original line number Diff line number Diff line Loading @@ -2,13 +2,27 @@ namespace Application\Controller; use Application\Entity\Db\EcoleDoctorale; use Application\Entity\Db\Etablissement; use Application\Entity\Db\Individu; use Application\Entity\Db\ListeDiffusion; use Application\Entity\Db\Role; use Application\Entity\Db\TypeStructure; use Application\Service\EcoleDoctorale\EcoleDoctoraleServiceAwareTrait; use Application\Service\Etablissement\EtablissementServiceAwareTrait; use Application\Service\File\FileServiceAwareTrait; use Application\Service\Individu\IndividuServiceAwareTrait; use Application\Service\ListeDiffusion\Address\ListeDiffusionAddressGenerator; use Application\Service\ListeDiffusion\ListeDiffusionServiceAwareTrait; use Application\Service\Notification\NotifierServiceAwareTrait; use Application\Service\Role\RoleServiceAwareTrait; use Application\Service\Structure\StructureServiceAwareTrait; use Doctrine\ORM\ORMException; use InvalidArgumentException; use SplObjectStorage; use UnicaenApp\View\Model\CsvModel; use Webmozart\Assert\Assert; use Zend\Http\Response; use Zend\View\Model\ViewModel; class ListeDiffusionController extends AbstractController Loading @@ -17,6 +31,10 @@ class ListeDiffusionController extends AbstractController use IndividuServiceAwareTrait; use FileServiceAwareTrait; use NotifierServiceAwareTrait; use StructureServiceAwareTrait; use EtablissementServiceAwareTrait; use EcoleDoctoraleServiceAwareTrait; use RoleServiceAwareTrait; /** * Adresse complète de la liste de diffusion, ex : Loading @@ -29,22 +47,245 @@ class ListeDiffusionController extends AbstractController * - 'doctorants' (ou 'dirtheses') est la "cible" ; * - 'insa' est le source_code unique de l'établissement en minuscules. * * @var string * @var ListeDiffusion */ protected $liste; private $liste; /** * @return array|ViewModel * @var SplObjectStorage */ private $dataByEtablissement; /** * @var ListeDiffusion[] Format : 'adresse' => ListeDiffusion */ private $listesDiffusionActives = []; /** * @var string[] Format : 'adresse' => 'adresse' */ private $adressesGenerees = []; /** * @return array|Response|ViewModel */ public function indexAction() { $listes = $this->listeDiffusionService->fetchListesDiffusion(); $etablissement = $this->params()->fromQuery('etablissement'); if ($this->params()->fromPost()) { return $this->modifierListes(); } /** @var EcoleDoctorale[] $ecolesDoctorales */ $etablissements = $this->etablissementService->getRepository()->findAllEtablissementsInscriptions(true); $ecolesDoctorales = $this->structureService->getAllStructuresAffichablesByType(TypeStructure::CODE_ECOLE_DOCTORALE, 'libelle', false, true); $codesRolesAvecTemoinsED = [ Role::CODE_DOCTORANT => true, Role::CODE_DIRECTEUR_THESE => true, Role::CODE_BU => false, Role::CODE_BDD => false, Role::CODE_ADMIN_TECH => false, // NB: pas de structure liée ]; $roles = $this->roleService->getRepository()->findByCodes(array_keys($codesRolesAvecTemoinsED)); $etablissementsAsStructures = array_map(function(Etablissement $e) { return $e->getStructure(); }, $etablissements); $roles = array_filter($roles, function(Role $role) use ($etablissementsAsStructures) { return $role->getStructure() === null || // ex: Admin tech in_array($role->getStructure(), $etablissementsAsStructures); }); $this->prepareDataForView($etablissements, $ecolesDoctorales, $roles, $codesRolesAvecTemoinsED); $this->loadListesDiffusionActives(); $adressesListesActives = array_keys($this->listesDiffusionActives); $adressesListesActivesMaisInexistanteDansGenerees = array_diff($adressesListesActives, $this->adressesGenerees); return new ViewModel([ 'listes' => $listes, 'codeEtablissement' => $etablissement, 'dataByEtablissement' => $this->dataByEtablissement, 'listesDiffusionActives' => $this->listesDiffusionActives, 'adressesListesActivesMaisInexistanteDansGenerees' => $adressesListesActivesMaisInexistanteDansGenerees, 'urlSympa' => $this->listeDiffusionService->getUrlSympa(), ]); } /** * Fetche en bdd les listes de diffusion actives. * NB: pour l'instant le table LISTE_DIFF ne contient que les listes activées. */ private function loadListesDiffusionActives() { $this->listesDiffusionActives = []; $listesDiffusionActives = $this->listeDiffusionService->fetchListesDiffusionActives(); foreach ($listesDiffusionActives as $listeDiffusion) { $this->listesDiffusionActives[$listeDiffusion->getAdresse()] = $listeDiffusion; } } /** * @return Response */ private function modifierListes() { $post = $this->params()->fromPost(); $etablissement = $post['etablissement'] ?? 'Tous'; $adresses = $post['listes'] ?? []; try { $this->enregistrer((array) $adresses, $etablissement); } catch (ORMException $e) { $this->flashMessenger()->addErrorMessage("Erreur rencontrée lors de l'enregistrement des listes : " . $e->getMessage()); error_log($e->getMessage() . PHP_EOL . $e->getTraceAsString()); } return $this->redirect()->toRoute(null, [], ['query' => ['etablissement' => $etablissement]], true); } /** * @param string[] $adresses * @param string $etablissement * @throws ORMException */ private function enregistrer(array $adresses, string $etablissement) { $adressesToDelete = array_filter($adresses, function (string $checked) { return $checked === '0'; }); $adressesToInsert = array_filter($adresses, function (string $checked) { return $checked === '1'; }); $this->listeDiffusionService->deleteListesDiffusions(array_keys($adressesToDelete)); $listes = []; foreach (array_keys($adressesToInsert) as $adresse) { $liste = $this->listeDiffusionService->findListeDiffusionByAdresse($adresse); $data = [ 'adresse' => $adresse, 'enabled' => true, ]; if ($liste === null) { $liste = $this->listeDiffusionService->createListeDiffusion($data); } else { $this->listeDiffusionService->updateListeDiffusion($liste, $data); } $listes[$adresse] = $liste; } $this->listeDiffusionService->saveListesDiffusions($listes); $this->flashMessenger()->addSuccessMessage( sprintf("Enregistrement effectué avec succès pour '%s' : %d adresses actives, %d inactives.", $etablissement, count($adressesToInsert), count($adressesToDelete))); } /** * @param Etablissement[] $etablissements * @param EcoleDoctorale[] $ecolesDoctorales * @param Role[] $roles * @param array $codesRolesAvecTemoinsED */ private function prepareDataForView(array $etablissements, array $ecolesDoctorales, array $roles, array $codesRolesAvecTemoinsED) { $this->adressesGenerees = []; // pour tests : //$etablissements = array_slice($etablissements, -1); // // Par établissement. // $dataByEtablissement = new SplObjectStorage(); foreach ($etablissements as $etablissement) { $rolesForEtablissement = array_filter($roles, function (Role $r) use ($etablissement) { return $r->getStructure() === $etablissement->getStructure(); }); $dataByRole = new SplObjectStorage(); foreach ($rolesForEtablissement as $role) { if ($codesRolesAvecTemoinsED[$role->getCode()] === true) { $dataByED = new SplObjectStorage(); // d'abord, toute ED confondue $edTouteConfondue = $this->ecoleDoctoraleService->createTouteEcoleDoctoraleConfondue(); $ng = $this->listeDiffusionService->createNameGenerator($edTouteConfondue, $role, $role->getStructure()); $dataByED->attach($edTouteConfondue, $this->prepareListeDataForView($ng)); // ensuite, par ED foreach ($ecolesDoctorales as $ed) { $ng = $this->listeDiffusionService->createNameGenerator($ed, $role, $role->getStructure()); $dataByED->attach($ed, $this->prepareListeDataForView($ng)); } $dataByRole->attach($role, $dataByED); } else { // hors ED $ng = $this->listeDiffusionService->createNameGenerator(null, $role, $role->getStructure()); $dataByRole->attach($role, $this->prepareListeDataForView($ng)); } } $dataByEtablissement->attach($etablissement, $dataByRole); } $rolesAvecTemoinsED = array_filter($roles, function (Role $r) use ($codesRolesAvecTemoinsED) { return $codesRolesAvecTemoinsED[$r->getCode()] === true; }); if (count($etablissements) > 1) { // // Tous établissements confondus. // /** @var Role $rolePrec */ $rolePrec = null; $dataByRole = new SplObjectStorage(); foreach ($rolesAvecTemoinsED as $role) { if ($rolePrec && ($isSameRoleAgain = $rolePrec->getCode() === $role->getCode())) { continue; // on ne retient qu'un rôle pour tous les établissements confondus } $dataByED = new SplObjectStorage(); // d'abord, toute ED confondue $edTouteConfondue = $this->ecoleDoctoraleService->createTouteEcoleDoctoraleConfondue(); $ng = $this->listeDiffusionService->createNameGenerator($edTouteConfondue, $role, null); $dataByED->attach($edTouteConfondue, $this->prepareListeDataForView($ng)); // ensuite, par ED foreach ($ecolesDoctorales as $ed) { $ng = $this->listeDiffusionService->createNameGenerator($ed, $role, null); $dataByED->attach($ed, $this->prepareListeDataForView($ng)); } $dataByRole->attach($role, $dataByED); $rolePrec = $role; } $etablissementToutConfondu = $this->etablissementService->createToutEtablissementConfondu(); $dataByEtablissement->attach($etablissementToutConfondu, $dataByRole); } // NB: $this->adressesGenerees a été peuplé. $this->dataByEtablissement = $dataByEtablissement; } /** * @param ListeDiffusionAddressGenerator $namer * @return array */ private function prepareListeDataForView(ListeDiffusionAddressGenerator $namer) { $domain = $this->listeDiffusionService->getEmailDomain(); $namer->setDomain($domain); try { $name = $namer->generateName(); $link = $this->url()->fromRoute('liste-diffusion/liste', ['adresse' => $name]); $enabled = true; } catch (InvalidArgumentException $e) { $name = "Anomalie rencontrée : " . $e->getMessage(); $link = null; $enabled = false; } // collecte avec indexation par adresse $this->adressesGenerees[$name] = $name; return [ 'name' => $name, 'label' => $name, 'link' => $link, 'enabled' => $enabled, ]; } /** * @return ViewModel */ Loading @@ -52,9 +293,6 @@ class ListeDiffusionController extends AbstractController { $this->loadRequestParams(); $listesDeclarees = $this->listeDiffusionService->fetchListesDiffusion(); Assert::inArray($this->liste, $listesDeclarees, "Liste spécifiée non déclarée."); $this->listeDiffusionService->setListe($this->liste); $this->listeDiffusionService->init(); Loading Loading @@ -123,6 +361,25 @@ class ListeDiffusionController extends AbstractController $this->fileService->downloadFileFromContent($content, $filename); } /** * @return CsvModel */ public function exporterTableauAction() { $data = $this->listeDiffusionService->createDataForCsvExport($this->url()); $header = current($data); $data = array_slice($data, 1); $model = new CsvModel(); $model->setDelimiter(';'); $model->setEnclosure('"'); $model->setHeader($header); $model->setData($data); $model->setFilename(sprintf('sygal_listediff_sympa_%s.csv', date_create('now')->format("Ymd-His"))); return $model; } /** * Gestion des ABONNÉS sans adresse mail. */ Loading Loading @@ -153,12 +410,16 @@ class ListeDiffusionController extends AbstractController } /** * @return string * @return ListeDiffusion */ private function getRequestedListe() { $liste = $this->params()->fromRoute('liste'); Assert::notNull($liste, "Aucune liste spécifiée."); $adresse = $this->params()->fromRoute('adresse'); Assert::notNull($adresse, "Aucune adresse spécifiée."); /** @var ListeDiffusion $liste */ $liste = $this->listeDiffusionService->getRepository()->findOneBy(['adresse' => $adresse]); Assert::notNull($liste, "Aucune liste active trouvée avec l'adresse spécifiée."); return $liste; } Loading
module/Application/src/Application/Entity/Db/EcoleDoctorale.php +11 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ class EcoleDoctorale implements StructureConcreteInterface, HistoriqueAwareInter use HistoriqueAwareTrait; use SourceAwareTrait; const CODE_TOUTE_ECOLE_DOCTORALE_CONFONDUE = 'TOUTE_ED'; /** * @var integer */ Loading Loading @@ -210,5 +212,13 @@ class EcoleDoctorale implements StructureConcreteInterface, HistoriqueAwareInter return $this; } /** * Teste si cette école doctorale est la pseudo-école doctorale "Toute école doctorale confondue". * * @return bool */ public function estTouteEcoleDoctoraleConfondue() { return $this->getStructure()->getCode() === self::CODE_TOUTE_ECOLE_DOCTORALE_CONFONDUE; } } No newline at end of file