Commit c97ae350 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Possibilité d'inclure les messages du FlashMessenger dans les alertes affichées.

parent 19a42c05
Loading
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
CHANGELOG
=========

3.1.0
-----
- Possibilité d'inclure les messages du FlashMessenger dans les alertes affichées.

3.0.0
-----
- Refonte pour permettre la création manuelle d'alertes (incompatible avec version 2)
+8 −1
Original line number Diff line number Diff line
@@ -2,8 +2,12 @@

namespace UnicaenAlerte;

use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\ORM\Mapping\Driver\XmlDriver;
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
use UnicaenAlerte\Container\Database\DatabaseContainer;
use UnicaenAlerte\Container\Database\DatabaseContainerFactory;
use UnicaenAlerte\Container\FlashMessenger\FlashMessengerContainer;
use UnicaenAlerte\Container\FlashMessenger\FlashMessengerContainerFactory;
use UnicaenAlerte\Entity\Db\Repository\AlerteRepository;
use UnicaenAlerte\Entity\Db\Repository\AlerteRepositoryFactory;
use UnicaenAlerte\Form\AlerteForm;
@@ -65,6 +69,9 @@ return [
        'factories' => [
            AlerteService::class => AlerteServiceFactory::class,
            AlerteRepository::class => AlerteRepositoryFactory::class,
            
            DatabaseContainer::class => DatabaseContainerFactory::class,
            FlashMessengerContainer::class => FlashMessengerContainerFactory::class,
        ],
    ],
    'controllers' => [
+25 −0
Original line number Diff line number Diff line
<?php

namespace UnicaenAlerte\Container\Database;

use Psr\Container\ContainerInterface;
use UnicaenAlerte\Entity\Db\Repository\AlerteRepository;

class DatabaseContainerFactory
{
    /**
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function __invoke(ContainerInterface $container): DatabaseContainer
    {
        $service = new DatabaseContainer();

        /** @var \UnicaenAlerte\Entity\Db\Repository\AlerteRepository $alerteRepository */
        $alerteRepository = $container->get(AlerteRepository::class);
        $service->setAlerteRepository($alerteRepository);

        return $service;
    }

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

namespace UnicaenAlerte\Container\FlashMessenger;

use Laminas\Mvc\Plugin\FlashMessenger\FlashMessenger as FlashMessengerPlugin;
use UnicaenAlerte\Container\ContainerInterface;
use UnicaenAlerte\Entity\Db\Alerte;
use UnicaenApp\Traits\MessageAwareTrait;
use Webmozart\Assert\Assert;

class FlashMessengerContainer implements ContainerInterface
{
    use MessageAwareTrait;

    const SEVERITY_NAMESPACES = [
        FlashMessengerPlugin::NAMESPACE_SUCCESS,
        FlashMessengerPlugin::NAMESPACE_ERROR,
        FlashMessengerPlugin::NAMESPACE_WARNING,
        FlashMessengerPlugin::NAMESPACE_INFO,
    ];

    const NAMESPACED_SEVERITY_SEPARATOR = '/';

    protected FlashMessengerPlugin $flashMessengerPlugin;

    /**
     * @var array ['current_messages => bool, 'namespace' => string]
     */
    protected array $importParams = [];

    /**
     * Alertes à afficher.
     * @var Alerte[]
     */
    protected array $alertes = [];

    protected array $severityOrders = [
        // severity => order
        FlashMessengerPlugin::NAMESPACE_SUCCESS => 1,
        FlashMessengerPlugin::NAMESPACE_ERROR => 2,
        FlashMessengerPlugin::NAMESPACE_WARNING => 3,
        FlashMessengerPlugin::NAMESPACE_INFO => 4,
    ];

    protected array $severityTitles = [
        // severity => title
        FlashMessengerPlugin::NAMESPACE_SUCCESS => "Succès",
        FlashMessengerPlugin::NAMESPACE_ERROR => "Attention",
        FlashMessengerPlugin::NAMESPACE_WARNING => "Avertissement",
        FlashMessengerPlugin::NAMESPACE_INFO => "Information",
    ];

    protected array $severityDurationsDefaults = [
        // severity => duration in ms
        FlashMessengerPlugin::NAMESPACE_SUCCESS => 5000,
        FlashMessengerPlugin::NAMESPACE_ERROR => 0,
        FlashMessengerPlugin::NAMESPACE_WARNING => 0,
        FlashMessengerPlugin::NAMESPACE_INFO => 0,
    ];
    protected array $severityDurations;

    protected array $severityTranslations = [
        // flas messenger severity => alert severity
        FlashMessengerPlugin::NAMESPACE_SUCCESS => Alerte::SEVERITY_SUCCESS,
        FlashMessengerPlugin::NAMESPACE_ERROR => Alerte::SEVERITY_DANGER,
        FlashMessengerPlugin::NAMESPACE_WARNING => Alerte::SEVERITY_WARNING,
        FlashMessengerPlugin::NAMESPACE_INFO => Alerte::SEVERITY_INFO,
    ];

    public function __construct()
    {
        $this->severityDurations = $this->severityDurationsDefaults;
    }

    public function setFlashMessengerPlugin(FlashMessengerPlugin $flashMessengerPlugin): void
    {
        $this->flashMessengerPlugin = $flashMessengerPlugin;
    }

    /**
     * Change la durée d'apparition de l'alerte.
     *
     * NB : Inopérant si le mode d'affichage de l'alerte ne supporte pas cette option.
     *
     * @param string $severity Sévérité concernée, ex : {@see FlashMessengerPlugin::NAMESPACE_SUCCESS}
     * @param int $duration Durée d'apparition de l'alerte (en ms), 0 équivalant à l'infini.
     */
    public function setSeverityDuration(string $severity, int $duration): self
    {
        Assert::inArray($severity, array_keys($this->severityDurations), 'Seules valeurs acceptées pour la sévérité : %2$s');
        $this->severityDurations[$severity] = $duration;
        return $this;
    }

    public function addImport(bool $currentMessages, ?string $namespace): self
    {
        $this->importParams[] = ['current_messages' => $currentMessages, 'namespace' => $namespace];
        return $this;
    }

    public function fetchAlertes(): array
    {
        foreach ($this->importParams as $params) {
            $this->importFromFlashMessages($params['current_messages'], $params['namespace']);
        }

        $this->alertes = [];
        foreach ($this->getSortedMessages() as $severity => $messages) {
            foreach ($messages as $message) {
                $this->alertes[] = $this->createAlerte($message, $severity);
            }
        }

        return $this->alertes;
    }

    protected function createAlerte(string $message, string $severity): Alerte
    {
        return Alerte::create(
            uniqid('ALERTE_'),
            $message,
            $this->severityTitles[$severity],
            $this->severityTranslations[$severity],
            $this->severityDurations[$severity]
        );
    }

    protected function importFromFlashMessages(bool $currentMessages, ?string $namespace): static
    {
        $method = $currentMessages ? 'getCurrentMessagesFromNamespace' : 'getMessagesFromNamespace';

        if ($namespace) {
            // collecte des messages dans les namespaces de la forme "namespace/sévérité"
            $array = $this->extractSeveritiesForComplexNamespace($namespace);
            if ($array) {
                foreach ($array as $sev => $ns) {
                    foreach ($this->flashMessengerPlugin->$method($ns) as $message) {
                        $this->addMessage($message, $sev);
                    }
                    if ($currentMessages) {
                        /* Si on importe alors on nettoie pour éviter un deuxième affichage */
                        $this->flashMessengerPlugin->clearCurrentMessagesFromNamespace($ns);
                    }
                }
            } else {
                // collecte des messages dans le namespace simple (fonctionne aussi si le namespace est une sévérité)
                foreach ((array)$this->flashMessengerPlugin->$method($namespace) as $message) {
                    $this->addMessage($message, $namespace);
                }
                if ($currentMessages) {
                    /* Si on importe alors on nettoie pour éviter un deuxième affichage */
                    $this->flashMessengerPlugin->clearCurrentMessagesFromNamespace($namespace);
                }
            }
        } else {
            foreach ((array)$this->flashMessengerPlugin->$method('error') as $message) {
                $this->addMessage($message, FlashMessengerPlugin::NAMESPACE_ERROR);
            }
            foreach ((array)$this->flashMessengerPlugin->$method('success') as $message) {
                $this->addMessage($message, FlashMessengerPlugin::NAMESPACE_SUCCESS);
            }
            foreach ((array)$this->flashMessengerPlugin->$method('warning') as $message) {
                $this->addMessage($message, FlashMessengerPlugin::NAMESPACE_WARNING);
            }
            foreach ((array)$this->flashMessengerPlugin->$method('info') as $message) {
                $this->addMessage($message, FlashMessengerPlugin::NAMESPACE_INFO);
            }

            if ($currentMessages) {
                $this->flashMessengerPlugin->clearCurrentMessagesFromContainer();
            }
        }

        return $this;
    }

    /**
     * @return array 'severity' => 'namespace'
     */
    protected function extractSeveritiesForComplexNamespace(string $namespace): array
    {
        if (in_array($namespace, self::SEVERITY_NAMESPACES)) {
            return [];
        }

        // Normalisation : $namespace doit être de la forme 'namespace/severity' ou 'namespace/*'.
        // Ex: 'these/danger' ou 'these/*'
        $separatorFound = strrpos($namespace, $sep = self::NAMESPACED_SEVERITY_SEPARATOR) !== false;
        if (!$separatorFound) {
            $namespace = $namespace . '/*';
        }

        $parts = explode($sep, $namespace);
        $severity = array_pop($parts);

        // Si $namespace est de la forme 'namespace/*', cela revient à importer les namespaces
        // 'namespace/danger', 'namespace/success', 'namespace/info' et 'namespace/warning'.
        if ($severity === '*') {
            $namespacePrefix = implode(self::NAMESPACED_SEVERITY_SEPARATOR, $parts) . '/';
            $array = [
                $s = FlashMessengerPlugin::NAMESPACE_ERROR => $namespacePrefix . $s,
                $s = FlashMessengerPlugin::NAMESPACE_SUCCESS => $namespacePrefix . $s,
                $s = FlashMessengerPlugin::NAMESPACE_WARNING => $namespacePrefix . $s,
                $s = FlashMessengerPlugin::NAMESPACE_INFO => $namespacePrefix . $s,
            ];
        } else {
            $array = [
                $severity => $namespace,
            ];
        }

        return $array;
    }

    protected function getSortedMessages(): array
    {
        $messages = $this->getMessages();
        uksort($messages, fn($s1, $s2) => $this->severityOrders[$s1] <=> $this->severityOrders[$s2]);

        return $messages;
    }
}
 No newline at end of file
+26 −0
Original line number Diff line number Diff line
<?php

namespace UnicaenAlerte\Container\FlashMessenger;

use Laminas\Mvc\Controller\PluginManager;
use Laminas\Mvc\Plugin\FlashMessenger\FlashMessenger as FlashMessengerPlugin;
use Psr\Container\ContainerInterface;

class FlashMessengerContainerFactory
{
    /**
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    public function __invoke(ContainerInterface $container): FlashMessengerContainer
    {
        $service = new FlashMessengerContainer();

        /** @var FlashMessengerPlugin $flashMessengerPlugin */
        $flashMessengerPlugin = $container->get(PluginManager::class)->get('flashMessenger');
        $service->setFlashMessengerPlugin($flashMessengerPlugin);

        return $service;
    }

}
 No newline at end of file
Loading