Messenger.php 8.59 KB
Newer Older
1
2
3
<?php
namespace UnicaenApp\View\Helper;

4
5
use UnicaenApp\Traits\MessageAwareInterface;
use UnicaenApp\Traits\MessageAwareTrait;
6
use UnicaenApp\Exception\LogicException;
7
8
9
10
use UnicaenApp\View\Helper\Messenger;
use Zend\View\Helper\AbstractHelper;

/**
11
12
13
 * Aide de vue permettant de stocker une liste de messages d'information de différentes sévérités
 * et de générer le code HTML pour les afficher (affublés d'un icône correspondant à leur sévérité).
 *
14
 * Possibilité d'importer les messages du FlashMessenger pour les mettre en forme de la même manière.
15
16
17
 *
 * @author Bertrand GAUTHIER <bertrand.gauthier@unicaen.fr>
 */
18
class Messenger extends AbstractHelper implements MessageAwareInterface
19
{
20
    use MessageAwareTrait;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

    protected $uiClasses     = [ // severity => [ alert class, icon class ]
                                 self::INFO    => ['info', 'info-sign'],
                                 self::SUCCESS => ['success', 'ok-sign'],
                                 self::WARNING => ['warning', 'warning-sign'],
                                 self::ERROR   => ['danger', 'exclamation-sign'],
    ];

    protected $severityOrder = [ // severity => order
                                 self::SUCCESS => 1,
                                 self::ERROR   => 2,
                                 self::WARNING => 3,
                                 self::INFO    => 4,
    ];

36
37
    /**
     * Activation ou non de l'affichage de l'icône
38
     *
39
40
41
     * @var bool
     */
    protected $withIcon = true;
42

43
44
45
46
    /**
     * @var string
     */
    protected $containerInnerTemplate = '%s';
47

48
49


50
    /**
51
     * Helper entry point.
52
     *
53
     * @return self
54
     */
55
    public function __invoke()
56
57
58
    {
        return $this;
    }
59
60
61



62
63
    /**
     * Retourne le code HTML généré par cette aide de vue.
64
     *
65
66
67
68
     * @return string
     */
    public function __toString()
    {
69
70
        try {
            return $this->render();
71
72
73
        } catch (\Exception $exc) {
            var_dump($exc->getMessage(), \UnicaenApp\Util::formatTraceString($exc->getTraceAsString()));
            die;
74
        }
75
    }
76

77
78


79
    /**
80
     * Génère le code HTML.
81
     *
82
83
     * @return string
     */
84
    protected function render()
85
86
87
88
89
90
    {
        if (!$this->hasMessages()) {
            return '';
        }

        $out = '';
91

92
93
94
        foreach ($this->getSortedMessages() as $severity => $array) {
            foreach ($array as $priority => $message) {
                $out .= sprintf(
95
96
                    $this->getTemplate(is_string($severity) ? $severity : (is_string($priority) ? $priority : 'info')),
                    implode('<br />', (array)$message)
97
98
                );
            }
99
100
101
102
103
        }

        return $out;
    }

104
105


106
107
    /**
     * Génère le code HTML d'un seul message. Pour usage ponctuel.
108
109
     *
     * @param string $message  Message à afficher
110
     * @param string $severity Ex: MessageAwareInterface::INFO
111
     *
112
113
114
115
     * @return string
     */
    public function renderMessage($message, $severity = null)
    {
116
        if (!$message) {
117
118
119
120
121
122
            return '';
        }

        return sprintf($this->getTemplate($severity ?: 'info'), $message);
    }

123
124


125
126
127
    /**
     * @return array
     */
128
    protected function getSortedMessages()
129
    {
130
        $messages = (array)$this->getMessages();
131
        $order    = $this->severityOrder;
132
133

        uksort($messages, function ($s1, $s2) use ($order) {
134
135
136
137
138
139
            if ($order[$s1] < $order[$s2]) {
                return -1;
            }
            if ($order[$s1] > $order[$s2]) {
                return 1;
            }
140

141
142
            return 0;
        });
143

144
145
        return $messages;
    }
146
147
148



149
    /**
150
151
     * Importe les messages n-1 du FlashMessenger.
     *
152
153
154
155
156
157
     * @return self
     */
    protected function importFlashMessages()
    {
        /* @var $fm \Zend\View\Helper\FlashMessenger */
        $fm = $this->getView()->getHelperPluginManager()->get('flashMessenger');
158

159
160
161
162
163
164
        foreach ($fm->getErrorMessages() as $message) {
            $this->addMessage($message, self::ERROR);
        }
        foreach ($fm->getSuccessMessages() as $message) {
            $this->addMessage($message, self::SUCCESS);
        }
165
166
167
        foreach ($fm->getInfoMessages() as $message) {
            $this->addMessage($message, self::INFO);
        }
168
169
170
        foreach ($fm->getWarningMessages() as $message) {
            $this->addMessage($message, self::WARNING);
        }
171

172
173
        return $this;
    }
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198



    /**
     * Importe les messages courants du FlashMessenger.
     *
     * @return self
     */
    protected function importCurrentFlashMessages()
    {
        /* @var $fm \Zend\View\Helper\FlashMessenger */
        $fm = $this->getView()->getHelperPluginManager()->get('flashMessenger');
        foreach ($fm->getCurrentErrorMessages() as $message) {
            $this->addMessage($message, self::ERROR);
        }
        foreach ($fm->getCurrentSuccessMessages() as $message) {
            $this->addMessage($message, self::SUCCESS);
        }
        foreach ($fm->getCurrentInfoMessages() as $message) {
            $this->addMessage($message, self::INFO);
        }
        foreach ($fm->getCurrentWarningMessages() as $message) {
            $this->addMessage($message, self::WARNING);
        }

199
200
        /* Si on importe alors on nettoie pour éviter un deuxième affichage */
        $fm->clearCurrentMessagesFromContainer();
201
202
203
204
205
        return $this;
    }



206
207
    /**
     * Spécifie l'unique message courant au format Exception.
208
     *
209
     * @param \Exception $exception Exception
210
211
     * @param string     $severity  Ex: Messenger::INFO
     *
212
213
214
215
216
217
218
219
     * @return Messenger
     */
    public function setException(\Exception $exception, $severity = self::ERROR)
    {
        $message = sprintf("<p><strong>%s</strong></p>", $exception->getMessage());
        if (($previous = $exception->getPrevious())) {
            $message .= sprintf("<p>Cause :<br />%s</p>", $previous->getMessage());
        }
220
221

        return $this->setMessages([$severity => $message]);
222
    }
223

224
225


226
227
    /**
     * Importe les messages courants du FlashMessenger (remplaçant les messages existants).
228
     *
229
230
231
232
     * @return Messenger
     */
    public function setMessagesFromFlashMessenger()
    {
233
        $this->messages = [];
234
        $this->importFlashMessages();
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

        return $this;
    }



    /**
     * Importe les messages courants du FlashMessenger (remplaçant les messages existants).
     *
     * @return Messenger
     */
    public function setCurrentMessagesFromFlashMessenger()
    {
        $this->messages = [];
        $this->importCurrentFlashMessages();

251
252
        return $this;
    }
253
254
255



256
    /**
257
     * Ajoute les messages courants du FlashMessenger.
258
     *
259
260
     * @return Messenger
     */
261
    public function addMessagesFromFlashMessenger()
262
    {
263
        $this->importFlashMessages();
264

265
266
        return $this;
    }
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283



    /**
     * Ajoute les messages courants du FlashMessenger.
     *
     * @return Messenger
     */
    public function addCurrentMessagesFromFlashMessenger()
    {
        $this->importCurrentFlashMessages();

        return $this;
    }



284
285
    /**
     * Active ou non l'affichage de l'icône.
286
     *
287
     * @param bool $withIcon <tt>true</tt> pour activer l'affichage de l'icône.
288
     *
289
290
291
292
     * @return Messenger
     */
    public function withIcon($withIcon = true)
    {
293
294
        $this->withIcon = (bool)$withIcon;

295
296
        return $this;
    }
297

298
299


300
    /**
301
     * Retourne le motif utilisé pour générer le conteneur de chaque message à afficher.
302
     *
303
     * @param string $severity    Ex: Messenger::INFO
304
     * @param string $containerId Dom id éventuel à utiliser pour la div englobante
305
306
     *
     * @return string
307
     */
308
    public function getTemplate($severity, $containerId = null)
309
310
    {
        if (!isset($this->uiClasses[$severity])) {
311
            throw new LogicException("Sévérité inconnue: " . $severity);
312
        }
313

314
        $innerTemplate = $this->containerInnerTemplate ?: '%s';
315
316
        $iconMarkup    = $this->withIcon ? "<span class=\"glyphicon glyphicon-{$this->uiClasses[$severity][1]}\"></span> " : null;
        $containerId   = $containerId ? sprintf('id="%s"', $containerId) : '';
317
318

        $template = <<<EOT
319
<div class="messenger alert alert-{$this->uiClasses[$severity][0]}" {$containerId}>
320
321
    <button type="button" class="close" title="Fermer cette alerte" data-dismiss="alert">&times;</button>
    $iconMarkup 
322
    $innerTemplate
323
</div>
324
EOT;
325

326
327
        return $template . PHP_EOL;
    }
328
329
330



331
    /**
332
333
334
     *
     * @param string $containerInnerTemplate
     *
335
336
337
338
339
     * @return self
     */
    public function setContainerInnerTemplate($containerInnerTemplate = '%s')
    {
        $this->containerInnerTemplate = $containerInnerTemplate;
340

341
342
        return $this;
    }
343
}