Loading config/module.config.php +3 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ return [ 'aliases' => [ 'alertes' => AlerteViewHelper::class, ], 'shared' => [ AlerteViewHelper::class => false, ] ], 'view_manager' => [ 'template_path_stack' => [ Loading src/UnicaenAlerte/View/Helper/AlerteViewHelper.php +87 −38 Original line number Diff line number Diff line Loading @@ -3,7 +3,6 @@ namespace UnicaenAlerte\View\Helper; use Doctrine\ORM\Query\Expr\Join; use InvalidArgumentException; use Laminas\View\Helper\AbstractHelper; use UnicaenAlerte\Entity\Db\Alerte; use UnicaenAlerte\Entity\Db\Repository\AlerteRepositoryAwareTrait; Loading @@ -15,10 +14,26 @@ class AlerteViewHelper extends AbstractHelper { use AlerteRepositoryAwareTrait; private array $alerteCodes = []; /** * Sélection précise des alertes par leur code, * en précisant pour chacune si elle doit avoir un planning qui inclue la date du jour pour être retenue. * * @var bool[] $code => $withMatchingPlanning */ private array $withCodesAndMatchingPlanning = []; /** * Spécifie *globalement* si les alertes doivent avoir un planning qui inclue la date du jour pour être retenues. * * @var bool */ private bool $withMatchingPlanning = false; /** @var null|Alerte[] */ /** * Alertes répondant aux critères de sélection. * * @var null|Alerte[] */ private ?array $alertes = null; /** Loading @@ -42,38 +57,70 @@ class AlerteViewHelper extends AbstractHelper } /** * Sélection d'une alerte précise par son code. * Sélection précise des alertes par leur code. * * @param string[] $codes */ public function withCodes(array $codes): self { return $this->withCodesAndMatchingPlanning($codes, false); } /** * Sélection précise des alertes par leur code, * en précisant si les alertes doivent avoir un planning qui inclue la date du jour. * * @param string[] $codes * @param bool $matchingPlanning L'alerte doit-elle avoir un planning qui inclue la date du jour pour être retenue ? * @return \UnicaenAlerte\View\Helper\AlerteViewHelper */ public function withCodesAndMatchingPlanning(array $codes, bool $matchingPlanning = true): self { foreach ($codes as $code) { $this->withCodeAndMatchingPlanning($code, $matchingPlanning); } return $this; } /** * Sélection précise d'une alerte par son code. * * @param string $code * @return self */ public function withCode(string $code): self { return $this->withCodes([$code]); return $this->withCodeAndMatchingPlanning($code, false); } /** * Sélection précises des alertes par leur code. * Sélection précise d'une alerte par son code, * en précisant si l'alerte doit avoir un planning qui inclue la date du jour. * * @param string[] $codes * @param string $code * @param bool $matchingPlanning L'alerte doit-elle avoir un planning qui inclue la date du jour pour être retenue ? * @return self */ public function withCodes(array $codes): self public function withCodeAndMatchingPlanning(string $code, bool $matchingPlanning = true): self { $this->alerteCodes = $codes; $this->withCodesAndMatchingPlanning[$code] = $matchingPlanning; $this->alertes = null; $this->withMatchingPlanning = false; return $this; } /** * Permet de ne sélectionner que les alertes ayant un planning qui inclue la date du jour. * * @param bool $withMatchingPlanning * @param bool $matchingPlanning L'alerte doit-elle avoir un planning qui inclue la date du jour pour être retenue ? * @return self */ public function withMatchingPlanning(bool $withMatchingPlanning = true): self public function withMatchingPlanning(bool $matchingPlanning = true): self { $this->withMatchingPlanning = $withMatchingPlanning; $this->withMatchingPlanning = $matchingPlanning; $this->alertes = null; return $this; Loading Loading @@ -146,41 +193,43 @@ class AlerteViewHelper extends AbstractHelper private function fetchAlertes(): array { $qb = $this->alerteRepository->createQueryBuilder('a'); $qb = $this->alerteRepository->createQueryBuilder('a') ->addSelect('p') // seuls les plannings (éventuels) incluant la date du jour nous intéressent ->leftJoin('a.plannings', 'p', Join::WITH, 'current_timestamp() between p.startDate and p.endDate'); if (!empty($this->alerteCodes)) { $qb->andWhere($qb->expr()->in('a.code', $this->alerteCodes)); $ors = []; foreach ($this->withCodesAndMatchingPlanning as $code => $matchingPlanning) { // le code de l'alerte doit matcher $param = uniqid(':code_'); $expr = "a.code = $param"; $qb->setParameter($param, $code); if ($matchingPlanning) { // et en plus, un planning doit exister $expr = $qb->expr()->andX($expr, 'p.id is not null'); } $ors[] = $expr; } if ($ors) { $qb->andWhere($qb->expr()->orX(...$ors)); } // filtre global portant sur toutes les alertes. if ($this->withMatchingPlanning) { $qb ->addSelect('p') ->join('a.plannings', 'p', Join::WITH, 'current_timestamp() between p.startDate and p.endDate'); $qb->andWhere('p.id is not null'); } /** @var Alerte[] $alertes */ $alertes = $qb->getQuery()->getResult(); if (!$this->withMatchingPlanning) { // si on ne trouve pas tous les codes d'alertes spécifiés, on couine ! if (!empty($this->alerteCodes) && count($this->alerteCodes) !== count($alertes)) { $codesDiff = array_diff($this->alerteCodes, array_map(fn(Alerte $a) => $a->getCode(), $alertes)); throw new InvalidArgumentException( "Aucune alerte trouvée pour les codes spécifiés suivants : " . implode(', ', $codesDiff) ); } } if ($this->withMatchingPlanning) { // la sévérité éventuellement spécifiée dans le planning écrase la sévérité par défaut : // la sévérité spécifiée dans l'eventuel planning écrase la sévérité par défaut : foreach ($alertes as $alerte) { /** @var \UnicaenAlerte\Entity\Db\AlertePlanning $planning */ $planning = $alerte->getPlannings()->first(); // un seul planning en cours théoriquement if ($severity = $planning->getSeverity()) { $planning = $alerte->getPlannings()->first(); // un seul planning en cours pris en compte if ($planning && $severity = $planning->getSeverity()) { $alerte->setSeverity($severity); break; } } } return $alertes; } Loading Loading
config/module.config.php +3 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,9 @@ return [ 'aliases' => [ 'alertes' => AlerteViewHelper::class, ], 'shared' => [ AlerteViewHelper::class => false, ] ], 'view_manager' => [ 'template_path_stack' => [ Loading
src/UnicaenAlerte/View/Helper/AlerteViewHelper.php +87 −38 Original line number Diff line number Diff line Loading @@ -3,7 +3,6 @@ namespace UnicaenAlerte\View\Helper; use Doctrine\ORM\Query\Expr\Join; use InvalidArgumentException; use Laminas\View\Helper\AbstractHelper; use UnicaenAlerte\Entity\Db\Alerte; use UnicaenAlerte\Entity\Db\Repository\AlerteRepositoryAwareTrait; Loading @@ -15,10 +14,26 @@ class AlerteViewHelper extends AbstractHelper { use AlerteRepositoryAwareTrait; private array $alerteCodes = []; /** * Sélection précise des alertes par leur code, * en précisant pour chacune si elle doit avoir un planning qui inclue la date du jour pour être retenue. * * @var bool[] $code => $withMatchingPlanning */ private array $withCodesAndMatchingPlanning = []; /** * Spécifie *globalement* si les alertes doivent avoir un planning qui inclue la date du jour pour être retenues. * * @var bool */ private bool $withMatchingPlanning = false; /** @var null|Alerte[] */ /** * Alertes répondant aux critères de sélection. * * @var null|Alerte[] */ private ?array $alertes = null; /** Loading @@ -42,38 +57,70 @@ class AlerteViewHelper extends AbstractHelper } /** * Sélection d'une alerte précise par son code. * Sélection précise des alertes par leur code. * * @param string[] $codes */ public function withCodes(array $codes): self { return $this->withCodesAndMatchingPlanning($codes, false); } /** * Sélection précise des alertes par leur code, * en précisant si les alertes doivent avoir un planning qui inclue la date du jour. * * @param string[] $codes * @param bool $matchingPlanning L'alerte doit-elle avoir un planning qui inclue la date du jour pour être retenue ? * @return \UnicaenAlerte\View\Helper\AlerteViewHelper */ public function withCodesAndMatchingPlanning(array $codes, bool $matchingPlanning = true): self { foreach ($codes as $code) { $this->withCodeAndMatchingPlanning($code, $matchingPlanning); } return $this; } /** * Sélection précise d'une alerte par son code. * * @param string $code * @return self */ public function withCode(string $code): self { return $this->withCodes([$code]); return $this->withCodeAndMatchingPlanning($code, false); } /** * Sélection précises des alertes par leur code. * Sélection précise d'une alerte par son code, * en précisant si l'alerte doit avoir un planning qui inclue la date du jour. * * @param string[] $codes * @param string $code * @param bool $matchingPlanning L'alerte doit-elle avoir un planning qui inclue la date du jour pour être retenue ? * @return self */ public function withCodes(array $codes): self public function withCodeAndMatchingPlanning(string $code, bool $matchingPlanning = true): self { $this->alerteCodes = $codes; $this->withCodesAndMatchingPlanning[$code] = $matchingPlanning; $this->alertes = null; $this->withMatchingPlanning = false; return $this; } /** * Permet de ne sélectionner que les alertes ayant un planning qui inclue la date du jour. * * @param bool $withMatchingPlanning * @param bool $matchingPlanning L'alerte doit-elle avoir un planning qui inclue la date du jour pour être retenue ? * @return self */ public function withMatchingPlanning(bool $withMatchingPlanning = true): self public function withMatchingPlanning(bool $matchingPlanning = true): self { $this->withMatchingPlanning = $withMatchingPlanning; $this->withMatchingPlanning = $matchingPlanning; $this->alertes = null; return $this; Loading Loading @@ -146,41 +193,43 @@ class AlerteViewHelper extends AbstractHelper private function fetchAlertes(): array { $qb = $this->alerteRepository->createQueryBuilder('a'); $qb = $this->alerteRepository->createQueryBuilder('a') ->addSelect('p') // seuls les plannings (éventuels) incluant la date du jour nous intéressent ->leftJoin('a.plannings', 'p', Join::WITH, 'current_timestamp() between p.startDate and p.endDate'); if (!empty($this->alerteCodes)) { $qb->andWhere($qb->expr()->in('a.code', $this->alerteCodes)); $ors = []; foreach ($this->withCodesAndMatchingPlanning as $code => $matchingPlanning) { // le code de l'alerte doit matcher $param = uniqid(':code_'); $expr = "a.code = $param"; $qb->setParameter($param, $code); if ($matchingPlanning) { // et en plus, un planning doit exister $expr = $qb->expr()->andX($expr, 'p.id is not null'); } $ors[] = $expr; } if ($ors) { $qb->andWhere($qb->expr()->orX(...$ors)); } // filtre global portant sur toutes les alertes. if ($this->withMatchingPlanning) { $qb ->addSelect('p') ->join('a.plannings', 'p', Join::WITH, 'current_timestamp() between p.startDate and p.endDate'); $qb->andWhere('p.id is not null'); } /** @var Alerte[] $alertes */ $alertes = $qb->getQuery()->getResult(); if (!$this->withMatchingPlanning) { // si on ne trouve pas tous les codes d'alertes spécifiés, on couine ! if (!empty($this->alerteCodes) && count($this->alerteCodes) !== count($alertes)) { $codesDiff = array_diff($this->alerteCodes, array_map(fn(Alerte $a) => $a->getCode(), $alertes)); throw new InvalidArgumentException( "Aucune alerte trouvée pour les codes spécifiés suivants : " . implode(', ', $codesDiff) ); } } if ($this->withMatchingPlanning) { // la sévérité éventuellement spécifiée dans le planning écrase la sévérité par défaut : // la sévérité spécifiée dans l'eventuel planning écrase la sévérité par défaut : foreach ($alertes as $alerte) { /** @var \UnicaenAlerte\Entity\Db\AlertePlanning $planning */ $planning = $alerte->getPlannings()->first(); // un seul planning en cours théoriquement if ($severity = $planning->getSeverity()) { $planning = $alerte->getPlannings()->first(); // un seul planning en cours pris en compte if ($planning && $severity = $planning->getSeverity()) { $alerte->setSeverity($severity); break; } } } return $alertes; } Loading