Commit a555ed2b authored by Thibaut Vallee's avatar Thibaut Vallee
Browse files

Mise en place de la commande etatInstance:purge

parent 83e73d2b
Loading
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ L'interface et le trait `HasEtat` va ajouter une instance d'état `etat`. Elle p
    public function getEtat(): ?EtatInstance;
    public function setEtat(?EtatInstance $etat): void;
```

Remarques :`
___`
- Une entité ne posséde qu'un état actif (celui qui n'est pas archivé).
@@ -75,6 +74,7 @@ Changements
===
- a faire : un viewHelper affichant l'historique des états.
- a faire : api qui retourne les instances d'états
- a faire : améliorer la commande etatInstance:purge afin de prendre de mieux gerer les types/catégories à purger

Scripts et description des tables
===
@@ -133,6 +133,22 @@ Pour `display-categorie`, Cf `EtatCategorieViewHelper`

Si les 2 options sont à false, on affiche l'état sous forme de badge (Cf EtatTypeViewHelper)

Purge des instances d'états historisées
---
La commande console `etatInstance:purge` permet de supprimer les instances d'états `historisées` depuis un certains temps.

- La durée par défaut de conservertion est de 1 an, il s'agit d'un paramétre modifiable dans la configuration sous la forme de DateInterval :
```
    'unicaen-etat' => [
        'conservation-time' => new DateInterval('P2Y'),
    ],
```
3 options possibles :
- `--time=P2Y` *(ou `-t P2Y`)* pour spécifier la durée de conservations des états (on ignore alors celle définie en conf).
- `--categorie=XXX`,  *(ou `-t XXX`)* pour ne purger que les instances d'états historisées de la catégorie dont le code est `XXX`
- `--type=YYY`,  *(ou `-t YYY`)* pour ne purger que les instances d'états historisées du type dont le code est `XXX`


Troubleshooting
===
- Pour nettoyer les instances d'état qui ne sont plus liées à rien, la procédure clear_etat_instance() est un exemple. 
+8 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@

namespace UnicaenEtat;

use UnicaenEtat\Command\EtatInstancePurgeCommand;
use UnicaenEtat\Command\EtatInstancePurgeCommandFactory;
use UnicaenEtat\Controller\EtatInstanceController;
use UnicaenEtat\Controller\EtatInstanceControllerFactory;
use UnicaenEtat\Provider\Privilege\EtatPrivileges;
@@ -90,6 +92,7 @@ return [
    'service_manager' => [
        'factories' => [
            EtatInstanceService::class => EtatInstanceServiceFactory::class,
            EtatInstancePurgeCommand::class => EtatInstancePurgeCommandFactory::class,
        ],
    ],
    'controllers'     => [
@@ -108,5 +111,10 @@ return [
            'etatinstance' => EtatInstanceViewHelper::class,
        ]
    ],
    'laminas-cli' => [
        'commands' => [
            'etatInstance:purge' => EtatInstancePurgeCommand::class,
        ],
    ],

];
 No newline at end of file
+4 −0
Original line number Diff line number Diff line
@@ -25,6 +25,10 @@ return [
            ],
        ],
    ],

    'unicaen-etat' => [
        //'conservation-time' => new DateInterval('P1Y')
    ],
];

?>
 No newline at end of file
+145 −0
Original line number Diff line number Diff line
<?php

namespace UnicaenEtat\Command;

use DateInterval;
use DateTime;
use Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use UnicaenEtat\Entity\Db\EtatInstance;
use UnicaenEtat\Service\EtatInstance\EtatInstanceServiceAwareTrait;

/***
 * @desc Supprime toutes les instances d'état qui sont archivées depuis un certains temps
 * paramétre à définir dans config unicaen-etat > conservation-time sour la forme d'un DateInterval
 * Par défaut : 1 an
 * TODO : permettre dans la conf de spécifier les types et catégories d'états qui doivent être purgée
 * TODO : gérer des dates différents par état/types
 * TODO : rendre des types/catégories non purgeable
 */
class EtatInstancePurgeCommand extends Command
{
    protected static $defaultName = 'etatInstance:purge';

    protected ?DateInterval $conservationTime = null;
    public function setConservationTime(DateInterval $conservationTime): static
    {
        $this->conservationTime = $conservationTime;
        return $this;
    }
    public function getDateSuppression() : DateTime
    {
        $date = new DateTime();
        $conservationTime = ($this->conservationTime) ?? new DateInterval('P1Y');
        $date->sub($conservationTime);
        return $date;
    }
    protected ?string $codeType = null;
    protected ?string $codeCategorie = null;

    public function getCodeType(): ?string
    {
        return $this->codeType;
    }

    public function getCodeCategorie(): ?string
    {
        return $this->codeCategorie;
    }

    public function setCodeType(?string $codeType): static
    {
        $this->codeType = $codeType;
        return $this;
    }
    public function setCodeCategorie(?string $codeCategorie): static
    {
        $this->codeCategorie = $codeCategorie;
        return $this;
    }


    use EtatInstanceServiceAwareTrait;

    protected function configure() : static
    {
        $this->setDescription("Supprime les instances d'états archivés");
        $this->addOption('time', '-t', InputOption::VALUE_OPTIONAL, "Intervale de temps que l'on souhaite conserver -- format : P1Y");
        $this->addOption('categorie', '-c', InputOption::VALUE_OPTIONAL, "code de la catégorie d'état que l'on souhaite purger");
        $this->addOption('type', '-type', InputOption::VALUE_OPTIONAL, "code du type d'état que l'on souhaite purger");
        return $this;
    }

    protected function initialize(InputInterface $input, OutputInterface $output): void
    {
        $io = new SymfonyStyle($input, $output);
        try{
            $time = $input->getOption('time');
            if(isset($time) && $time != ""){
                $this->conservationTime = new DateInterval($time);
            }
            $codeCategorie = $input->getOption('categorie');
            if(isset($codeCategorie) && $codeCategorie != ""){
                $this->codeCategorie = $codeCategorie;
            }
            $codeType = $input->getOption('type');
            if(isset($codeType) && $codeType != ""){
                $this->codeType = $codeType;
            }
        }
        catch (Exception $e){
            $io->error($e->getMessage());
            exit(-1);
        }
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        try {
            $io->title("Suppression des instances d'états archivées");

            $date = $this->getDateSuppression();
            $codeCategorie = $this->getCodeCategorie();
            $codeType = $this->getCodeType();

            $qb =$this->getEtatInstanceService()->createQueryBuilder();
            $qb->andWhere("einstance.histoDestruction < :date");
            $qb->setParameter("date", $date);
            if(isset($codeCategorie) && $codeCategorie != ""){
                $qb->andWhere($qb->expr()->eq('ecategorie.code',':codeCategorie'));
                $qb->setParameter("codeCategorie", $codeCategorie);
            };
            if(isset($codeType) && $codeType != ""){
                $qb->andWhere($qb->expr()->eq('etype.code',':codeType'));
                $qb->setParameter("codeType", $codeType);
            };
            $etatsInstances = $qb->getQuery()->getResult();

            if(!empty($etatsInstances)) {
                $io->progressStart(sizeof($etatsInstances));
                /** @var EtatInstance $log */
                foreach ($etatsInstances as $etatInstance) {
                    $this->getEtatInstanceService()->delete($etatInstance);
                    $io->progressAdvance();
                }
                $io->progressFinish();
            }
            else{
                $io->text("Aucune instance d'états à supprimer");
            }
            $io->success("Suppression terminée");
        }
        catch (Exception $e){
                $io->error($e->getMessage());
                return self::FAILURE;
        }
        return self::SUCCESS;
    }

}
 No newline at end of file
+35 −0
Original line number Diff line number Diff line
<?php

namespace UnicaenEtat\Command;

use DateInterval;
use Exception;
use Psr\Container\ContainerInterface;
use UnicaenEtat\Service\EtatInstance\EtatInstanceService;

class EtatInstancePurgeCommandFactory
{
    /**
     * @param ContainerInterface $container
     *
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \Exception
     */
    public function __invoke(ContainerInterface $container): EtatInstancePurgeCommand
    {
        $command = new EtatInstancePurgeCommand();
        $command->setEtatInstanceService($container->get(EtatInstanceService::class));

        $config = $container->get('Configuration');
        if (isset($config['unicaen-etat']['conservation-time'])) {
            $conservationTime = $config['unicaen-etat']['conservation-time'];
            if(!$conservationTime instanceof DateInterval) {
                throw new Exception("Le paramère de coniguration 'unicaen-etat > conservation-time' doit être un DateInterval");
            }
            $command->setConservationTime($conservationTime);
        }

        return $command;
    }
}
 No newline at end of file