Message::getIterator()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 0
1
<?php
2
namespace Tuum\Form\Data;
3
4
use Traversable;
5
6
/**
7
 * Class Message
8
 *
9
 * @package Tuum\View\Values
10
 */
11
class Message implements \IteratorAggregate
12
{
13
    const MESSAGE = 'message';
14
    const ALERT   = 'alert';
15
    const ERROR   = 'error';
16
17
    /**
18
     * @var array
19
     */
20
    protected $messages = [];
21
22
    public $formats = [
23
        self::MESSAGE => '<div class="alert alert-success">%s</div>',
24
        self::ALERT   => '<div class="alert alert-info">%s</div>',
25
        self::ERROR   => '<div class="alert alert-danger">%s</div>',
26
    ];
27
28
    /**
29
     * @param array $data
30
     */
31
    private function __construct($data = [])
32
    {
33
        $this->messages = $data;
34
    }
35
36
    /**
37
     * @param array $data
38
     * @return Message
39
     */
40
    public static function forge($data)
41
    {
42
        return new self($data);
43
    }
44
45
    /**
46
     * @param string $message
47
     * @param string $type
48
     */
49
    public function add($message, $type = self::MESSAGE)
50
    {
51
        $this->messages[] = ['message' => $message, 'type' => $type];
52
    }
53
54
    /**
55
     * @param array $msg
56
     * @return string
57
     */
58
    private function show($msg)
59
    {
60
        $type   = isset($msg['type']) ? $msg['type'] : self::MESSAGE;
61
        $format = isset($this->formats[$type]) ? $this->formats[$type] : $this->formats[self::MESSAGE];
62
        return sprintf($format, $msg['message']);
63
    }
64
65
    /**
66
     * show the most severe message only once.
67
     *
68
     * @return string
69
     */
70
    public function onlyOne()
71
    {
72
        $serious   = $this->findMostSerious();
73
        if (!empty($serious)) {
74
            return $this->show($serious);
75
        }
76
        return '';
77
    }
78
79
    /**
80
     * @return string[]
81
     */
82
    public function findMostSerious()
83
    {
84
        $msgScores = [
85
            self::ERROR   => 3,
86
            self::ALERT   => 2,
87
            self::MESSAGE => 1,
88
        ];
89
        $serious   = array_reduce(
90
            $this->messages,
91
            function ($carry, $msg) use ($msgScores) {
92
                $myScore      = $msgScores[$msg['type']];
93
                $msg['score'] = $myScore;
94
                return $myScore > $carry['score'] ? $msg : $carry;
95
            },
96
            ['message' => false, 'type' => self::MESSAGE, 'score' => 0]);
97
        if ($serious && $serious['message']) {
98
            return $serious;
99
        }
100
        return [];
101
    }
102
103
    /**
104
     * @return string
105
     */
106
    public function __toString()
107
    {
108
        $html = '';
109
        foreach ($this->messages as $msg) {
110
            $html .= $this->show($msg);
111
        }
112
        return $html;
113
    }
114
115
    /**
116
     * Retrieve an external iterator
117
     *
118
     * @return Traversable|string[]
119
     */
120
    public function getIterator()
121
    {
122
        foreach($this->messages as $message) {
123
            yield $message['type'] => $message['message'];
124
        }
125
    }
126
}