Completed
Push — master ( fbee6d...8a36ee )
by Adam
02:56
created

Message::__sleep()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 6
rs 9.4286
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
/**
3
 * Message.php
4
 *
5
 * @copyright      More in license.md
6
 * @license        http://www.ipublikuj.eu
7
 * @author         Adam Kadlec http://www.ipublikuj.eu
8
 * @package        iPublikuj:FlashMessages!
9
 * @subpackage     Entities
10
 * @since          1.0.0
11
 *
12
 * @date           06.02.15
13
 */
14
15
namespace IPub\FlashMessages\Entities;
16
17
use Nette;
18
use Nette\Localization;
19
20
use IPub;
21
use IPub\FlashMessages\Adapters;
22
use IPub\FlashMessages\Exceptions;
23
24
/**
25
 * Flash message entity
26
 *
27
 * @package        iPublikuj:FlashMessages!
28
 * @subpackage     Entities
29
 *
30
 * @author         Adam Kadlec <[email protected]>
31
 */
32
class Message extends Nette\Object implements IMessage
33
{
34
	const LEVEL_INFO = 'info';
35
	const LEVEL_SUCCESS = 'success';
36
	const LEVEL_WARNING = 'warning';
37
	const LEVEL_ERROR = 'error';
38
39
	/**
40
	 * @var string
41
	 */
42
	protected $message;
43
44
	/**
45
	 * @var string
46
	 */
47
	protected $level;
48
49
	/**
50
	 * @var string
51
	 */
52
	protected $title;
53
54
	/**
55
	 * @var bool
56
	 */
57
	protected $overlay = FALSE;
58
59
	/**
60
	 * @var bool
61
	 */
62
	protected $displayed = FALSE;
63
64
	/**
65
	 * @var Localization\ITranslator
66
	 */
67
	protected $translator;
68
69
	/**
70
	 * @var Adapters\IPhraseAdapter
71
	 */
72
	protected $phraseAdapter;
73
74
	/**
75
	 * @var Adapters\IPhraseAdapter
76
	 */
77
	protected $titlePhraseAdapter;
78
79
	/**
80
	 * @param Localization\ITranslator $translator
81
	 * @param Adapters\IPhraseAdapter $phraseAdapter
82
	 * @param Adapters\IPhraseAdapter $titlePhraseAdapter
83
	 */
84
	public function __construct(
85
		Localization\ITranslator $translator = NULL,
86
		Adapters\IPhraseAdapter $phraseAdapter,
87
		Adapters\IPhraseAdapter $titlePhraseAdapter = NULL
88
	) {
89
		$this->translator = $translator;
90
		$this->phraseAdapter = $phraseAdapter;
91
		$this->titlePhraseAdapter = $titlePhraseAdapter;
92
	}
93
94
	/**
95
	 * {@inheritdoc}
96
	 */
97
	public function setMessage($message)
98
	{
99
		if ($this->isUnserialized()) {
100
			$this->message = $message;
101
102
		} else {
103
			$this->phraseAdapter->setMessage($message);
104
			$this->message = NULL;
105
		}
106
107
		return $this;
108
	}
109
110
	/**
111
	 * {@inheritdoc}
112
	 */
113
	public function getMessage()
114
	{
115
		if ($this->message === NULL && $this->translator) {
116
			$this->message = $this->phraseAdapter->translate($this->translator);
117
		}
118
119
		return $this->message;
120
	}
121
122
	/**
123
	 * {@inheritdoc}
124
	 */
125
	public function setLevel($level)
126
	{
127
		$this->level = $level;
128
129
		return $this;
130
	}
131
132
	/**
133
	 * {@inheritdoc}
134
	 */
135
	public function getLevel()
136
	{
137
		return $this->level;
138
	}
139
140
	/**
141
	 * {@inheritdoc}
142
	 */
143
	public function info()
144
	{
145
		$this->setLevel(self::LEVEL_INFO);
146
147
		return $this;
148
	}
149
150
	/**
151
	 * {@inheritdoc}
152
	 */
153
	public function success()
154
	{
155
		$this->setLevel(self::LEVEL_SUCCESS);
156
157
		return $this;
158
	}
159
160
	/**
161
	 * {@inheritdoc}
162
	 */
163
	public function warning()
164
	{
165
		$this->setLevel(self::LEVEL_WARNING);
166
167
		return $this;
168
	}
169
170
	/**
171
	 * {@inheritdoc}
172
	 */
173
	public function error()
174
	{
175
		$this->setLevel(self::LEVEL_ERROR);
176
177
		return $this;
178
	}
179
180
	/**
181
	 * {@inheritdoc}
182
	 */
183
	public function setTitle($title = NULL)
184
	{
185
		if ($this->isUnserialized()) {
186
			$this->title = $title;
187
188
		} else {
189
			if ($this->titlePhraseAdapter instanceof Adapters\IPhraseAdapter) {
190
				$this->titlePhraseAdapter->setMessage($title);
191
			}
192
			$this->title = NULL;
193
		}
194
195
		return $this;
196
	}
197
198
	/**
199
	 * {@inheritdoc}
200
	 */
201
	public function getTitle()
202
	{
203
		if ($this->title === NULL && $this->translator && $this->titlePhraseAdapter instanceof Adapters\IPhraseAdapter) {
204
			$this->title = $this->titlePhraseAdapter->translate($this->translator);
205
		}
206
207
		return $this->title;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->title; (string) is incompatible with the return type declared by the interface IPub\FlashMessages\Entities\IMessage::getTitle of type IPub\FlashMessages\Adapters\IPhraseAdapter|null.

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:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
208
	}
209
210
	/**
211
	 * {@inheritdoc}
212
	 */
213
	public function setOverlay($overlay)
214
	{
215
		$this->overlay = (bool) $overlay;
216
217
		return $this;
218
	}
219
220
	/**
221
	 * {@inheritdoc}
222
	 */
223
	public function getOverlay()
224
	{
225
		return $this->overlay;
226
	}
227
228
	/**
229
	 * {@inheritdoc}
230
	 */
231
	public function setParameters(array $parameter)
232
	{
233
		$this->validateState(__FUNCTION__);
234
		$this->phraseAdapter->setParameters($parameter);
235
		$this->message = NULL;
236
237
		return $this;
238
	}
239
240
	/**
241
	 * {@inheritdoc}
242
	 */
243
	public function setCount($count)
244
	{
245
		$this->validateState(__FUNCTION__);
246
		$this->phraseAdapter->setCount($count);
247
		$this->message = NULL;
248
249
		return $this;
250
	}
251
252
	/**
253
	 * {@inheritdoc}
254
	 */
255
	public function setDisplayed($displayed = TRUE)
256
	{
257
		$this->displayed = (bool) $displayed;
258
259
		return $this;
260
	}
261
262
	/**
263
	 * {@inheritdoc}
264
	 */
265
	public function isDisplayed()
266
	{
267
		return $this->displayed === TRUE ? TRUE : FALSE;
268
	}
269
270
	/**
271
	 * @param string $method
272
	 *
273
	 * @throws Exceptions\InvalidStateException
274
	 */
275
	private function validateState($method)
276
	{
277
		if ($this->isUnserialized()) {
278
			throw new Exceptions\InvalidStateException("You cannot call method $method on unserialized Entities\\Message object");
279
		}
280
	}
281
282
	/**
283
	 * @return bool
284
	 */
285
	private function isUnserialized()
286
	{
287
		return $this->translator === NULL;
288
	}
289
290
	/**
291
	 * @return string
292
	 */
293
	public function __toString()
294
	{
295
		return $this->level . ' ' . ($this->title ? $this->title . ' ' : '') . $this->getMessage();
296
	}
297
298
	/**
299
	 * @return array
300
	 */
301
	public function __sleep()
302
	{
303
		$this->message = $this->getMessage();
304
305
		return ['message', 'level', 'title', 'overlay', 'displayed'];
306
	}
307
}
308