|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Bluz Framework Component |
|
4
|
|
|
* |
|
5
|
|
|
* @copyright Bluz PHP Team |
|
6
|
|
|
* @link https://github.com/bluzphp/framework |
|
7
|
|
|
*/ |
|
8
|
|
|
|
|
9
|
|
|
/** |
|
10
|
|
|
* @namespace |
|
11
|
|
|
*/ |
|
12
|
|
|
namespace Bluz\Messages; |
|
13
|
|
|
|
|
14
|
|
|
use Bluz\Common\Options; |
|
15
|
|
|
use Bluz\Proxy\Session; |
|
16
|
|
|
use Bluz\Proxy\Translator; |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* Realization of Flash Messages |
|
20
|
|
|
* |
|
21
|
|
|
* @package Bluz\Messages |
|
22
|
|
|
* @author Anton Shevchuk |
|
23
|
|
|
* @link https://github.com/bluzphp/framework/wiki/Messages |
|
24
|
|
|
*/ |
|
25
|
|
|
class Messages |
|
26
|
|
|
{ |
|
27
|
|
|
use Options; |
|
28
|
|
|
|
|
29
|
|
|
const TYPE_ERROR = 'error'; |
|
30
|
|
|
const TYPE_SUCCESS = 'success'; |
|
31
|
|
|
const TYPE_NOTICE = 'notice'; |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* @var array list of messages types |
|
35
|
|
|
*/ |
|
36
|
|
|
protected $types = [ |
|
37
|
|
|
self::TYPE_ERROR, |
|
38
|
|
|
self::TYPE_SUCCESS, |
|
39
|
|
|
self::TYPE_NOTICE |
|
40
|
|
|
]; |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* Initialize Messages container |
|
44
|
|
|
* |
|
45
|
|
|
* @return Messages |
|
46
|
|
|
*/ |
|
47
|
4 |
|
protected function init() |
|
48
|
|
|
{ |
|
49
|
4 |
|
if (!$this->getMessagesStore()) { |
|
50
|
1 |
|
$this->reset(); |
|
51
|
|
|
} |
|
52
|
4 |
|
return $this; |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* Add notice |
|
57
|
|
|
* |
|
58
|
|
|
* @param string $message |
|
59
|
|
|
* @param string[] $text |
|
60
|
|
|
* @return void |
|
61
|
|
|
* @since 1.0.0 added $text |
|
62
|
|
|
*/ |
|
63
|
4 |
|
public function addNotice($message, ...$text) |
|
64
|
|
|
{ |
|
65
|
4 |
|
$this->add(self::TYPE_NOTICE, $message, ...$text); |
|
66
|
4 |
|
} |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* Add success |
|
70
|
|
|
* |
|
71
|
|
|
* @param string $message |
|
72
|
|
|
* @param string[] $text |
|
73
|
|
|
* @return void |
|
74
|
|
|
* @since 1.0.0 added $text |
|
75
|
|
|
*/ |
|
76
|
4 |
|
public function addSuccess($message, ...$text) |
|
77
|
|
|
{ |
|
78
|
4 |
|
$this->add(self::TYPE_SUCCESS, $message, ...$text); |
|
79
|
4 |
|
} |
|
80
|
|
|
|
|
81
|
|
|
/** |
|
82
|
|
|
* Add error |
|
83
|
|
|
* |
|
84
|
|
|
* @param string $message |
|
85
|
|
|
* @param string[] $text |
|
86
|
|
|
* @return void |
|
87
|
|
|
* @since 1.0.0 added $text |
|
88
|
|
|
*/ |
|
89
|
4 |
|
public function addError($message, ...$text) |
|
90
|
|
|
{ |
|
91
|
4 |
|
$this->add(self::TYPE_ERROR, $message, ...$text); |
|
92
|
4 |
|
} |
|
93
|
|
|
|
|
94
|
|
|
/** |
|
95
|
|
|
* Add message to container |
|
96
|
|
|
* |
|
97
|
|
|
* @param string $type One of error, notice or success |
|
98
|
|
|
* @param string $message |
|
99
|
|
|
* @param string[] $text |
|
100
|
|
|
* @return void |
|
101
|
|
|
*/ |
|
102
|
4 |
|
protected function add($type, $message, ...$text) |
|
103
|
|
|
{ |
|
104
|
4 |
|
$this->init(); |
|
105
|
4 |
|
$this->getMessagesStore()[$type][] = Translator::translate($message, ...$text); |
|
106
|
4 |
|
} |
|
107
|
|
|
|
|
108
|
|
|
/** |
|
109
|
|
|
* Pop a message |
|
110
|
|
|
* |
|
111
|
|
|
* @param string $type |
|
112
|
|
|
* @return \stdClass|null |
|
113
|
|
|
*/ |
|
114
|
4 |
|
public function pop($type = null) |
|
115
|
|
|
{ |
|
116
|
4 |
|
if (!$this->getMessagesStore()) { |
|
117
|
|
|
return null; |
|
118
|
|
|
} |
|
119
|
|
|
|
|
120
|
4 |
|
if ($type !== null) { |
|
121
|
4 |
|
$text = array_shift($this->getMessagesStore()[$type]); |
|
122
|
4 |
|
if ($text) { |
|
123
|
3 |
|
$message = new \stdClass(); |
|
124
|
3 |
|
$message->text = $text; |
|
125
|
3 |
|
$message->type = $type; |
|
126
|
4 |
|
return $message; |
|
127
|
|
|
} |
|
128
|
|
|
} else { |
|
129
|
1 |
|
foreach ($this->types as $type) { |
|
130
|
1 |
|
if ($message = $this->pop($type)) { |
|
131
|
1 |
|
return $message; |
|
132
|
|
|
} |
|
133
|
|
|
} |
|
134
|
|
|
} |
|
135
|
2 |
|
return null; |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
/** |
|
139
|
|
|
* Pop all messages |
|
140
|
|
|
* |
|
141
|
|
|
* @return \ArrayObject |
|
142
|
|
|
*/ |
|
143
|
630 |
|
public function popAll() |
|
144
|
|
|
{ |
|
145
|
630 |
|
if (!$this->getMessagesStore()) { |
|
146
|
108 |
|
return $this->createEmptyMessagesStore(); |
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
522 |
|
$messages = $this->getMessagesStore()->getArrayCopy(); |
|
150
|
522 |
|
$this->reset(); |
|
151
|
522 |
|
return $messages; |
|
|
|
|
|
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
/** |
|
155
|
|
|
* Get size of messages container |
|
156
|
|
|
* |
|
157
|
|
|
* @return integer |
|
158
|
|
|
*/ |
|
159
|
2 |
|
public function count() |
|
160
|
|
|
{ |
|
161
|
2 |
|
$size = 0; |
|
162
|
2 |
|
if (!$store = $this->getMessagesStore()) { |
|
163
|
|
|
return $size; |
|
164
|
|
|
} |
|
165
|
2 |
|
foreach ($store as $messages) { |
|
166
|
2 |
|
$size += sizeof($messages); |
|
167
|
|
|
} |
|
168
|
2 |
|
return $size; |
|
169
|
|
|
} |
|
170
|
|
|
|
|
171
|
|
|
/** |
|
172
|
|
|
* Reset messages |
|
173
|
|
|
* |
|
174
|
|
|
* @return void |
|
175
|
|
|
*/ |
|
176
|
522 |
|
public function reset() |
|
177
|
|
|
{ |
|
178
|
522 |
|
Session::set('messages:store', $this->createEmptyMessagesStore()); |
|
179
|
522 |
|
} |
|
180
|
|
|
|
|
181
|
|
|
/** |
|
182
|
|
|
* Returns current messages store |
|
183
|
|
|
* |
|
184
|
|
|
* @return \ArrayObject|null Returns null if store not exists yet |
|
185
|
|
|
*/ |
|
186
|
630 |
|
protected function getMessagesStore() |
|
187
|
|
|
{ |
|
188
|
630 |
|
return Session::get('messages:store'); |
|
189
|
|
|
} |
|
190
|
|
|
|
|
191
|
|
|
/** |
|
192
|
|
|
* Creates a new empty store for messages |
|
193
|
|
|
* |
|
194
|
|
|
* @return \ArrayObject |
|
195
|
|
|
*/ |
|
196
|
630 |
|
protected function createEmptyMessagesStore() |
|
197
|
|
|
{ |
|
198
|
630 |
|
return new \ArrayObject( |
|
199
|
|
|
[ |
|
200
|
630 |
|
self::TYPE_ERROR => [], |
|
201
|
|
|
self::TYPE_SUCCESS => [], |
|
202
|
|
|
self::TYPE_NOTICE => [] |
|
203
|
|
|
] |
|
204
|
|
|
); |
|
205
|
|
|
} |
|
206
|
|
|
} |
|
207
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_functionexpects aPostobject, and outputs the author of the post. The base classPostreturns a simple string and outputting a simple string will work just fine. However, the child classBlogPostwhich is a sub-type ofPostinstead decided to return anobject, and is therefore violating the SOLID principles. If aBlogPostwere passed tomy_function, PHP would not complain, but ultimately fail when executing thestrtouppercall in its body.