3 declare(strict_types
=1);
10 use function _ngettext
;
11 use function array_unshift
;
13 use function htmlspecialchars
;
14 use function is_array
;
15 use function is_float
;
26 * simple usage examples:
28 * // display simple error message 'Error'
29 * echo Message::error()->getDisplay();
31 * // get simple success message 'Success'
32 * $message = Message::success();
34 * // get special notice
35 * $message = Message::notice(__('This is a localized notice'));
38 * more advanced usage example:
40 * // create another message, a hint, with a localized string which expects
41 * $hint = Message::notice('Read the %smanual%s');
42 * // replace placeholders with the following params
43 * $hint->addParam('[doc@cfg_Example]');
44 * $hint->addParam('[/doc]');
45 * // add this hint as a tooltip
46 * $hint = showHint($hint);
48 * // add the retrieved tooltip reference to the original message
49 * $message->addMessage($hint);
52 class Message
implements Stringable
54 public const SUCCESS
= 1; // 0001
55 public const NOTICE
= 2; // 0010
56 public const ERROR
= 8; // 1000
58 public const SANITIZE_NONE
= 0; // 0000 0000
59 public const SANITIZE_STRING
= 16; // 0001 0000
60 public const SANITIZE_PARAMS
= 32; // 0010 0000
61 public const SANITIZE_BOOTH
= 48; // 0011 0000
68 public static $level = [
69 self
::SUCCESS
=> 'success',
70 self
::NOTICE
=> 'notice',
71 self
::ERROR
=> 'error',
79 protected $number = self
::NOTICE
;
82 * The locale string identifier
86 protected $string = '';
89 * The formatted message
93 protected $message = '';
96 * Whether the message was already displayed
100 protected $isDisplayed = false;
103 * Whether to use BB code when displaying.
107 protected $useBBCode = true;
114 protected $hash = null;
121 protected $params = [];
124 * holds additional messages
128 protected $addedMessages = [];
131 * @param string $string The message to be displayed
132 * @param int $number A numeric representation of the type of message
133 * @param array $params An array of parameters to use in the message
134 * @param int $sanitize A flag to indicate what to sanitize, see
135 * constant definitions above
137 public function __construct(
139 int $number = self
::NOTICE
,
141 int $sanitize = self
::SANITIZE_NONE
143 $this->setString($string, $sanitize & self
::SANITIZE_STRING
);
144 $this->setNumber($number);
145 $this->setParams($params, $sanitize & self
::SANITIZE_PARAMS
);
149 * magic method: return string representation for this object
151 public function __toString(): string
153 return $this->getMessage();
157 * get Message of type success
159 * shorthand for getting a simple success message
161 * @param string $string A localized string
162 * e.g. __('Your SQL query has been
163 * executed successfully')
169 public static function success(string $string = ''): self
171 if (empty($string)) {
172 $string = __('Your SQL query has been executed successfully.');
175 return new Message($string, self
::SUCCESS
);
179 * get Message of type error
181 * shorthand for getting a simple error message
183 * @param string $string A localized string e.g. __('Error')
189 public static function error(string $string = ''): self
191 if (empty($string)) {
192 $string = __('Error');
195 return new Message($string, self
::ERROR
);
199 * get Message of type notice
201 * shorthand for getting a simple notice message
203 * @param string $string A localized string
204 * e.g. __('The additional features for working with
205 * linked tables have been deactivated. To find out
206 * why click %shere%s.')
212 public static function notice(string $string): self
214 return new Message($string, self
::NOTICE
);
218 * get Message with customized content
220 * shorthand for getting a customized message
222 * @param string $message A localized string
223 * @param int $type A numeric representation of the type of message
229 public static function raw(string $message, int $type = self
::NOTICE
): self
231 $r = new Message('', $type);
232 $r->setMessage($message);
233 $r->setBBCode(false);
239 * get Message for number of affected rows
241 * shorthand for getting a customized message
243 * @param int $rows Number of rows
249 public static function getMessageForAffectedRows(int $rows): self
251 $message = self
::success(
252 _ngettext('%1$d row affected.', '%1$d rows affected.', $rows)
254 $message->addParam($rows);
260 * get Message for number of deleted rows
262 * shorthand for getting a customized message
264 * @param int $rows Number of rows
270 public static function getMessageForDeletedRows(int $rows): self
272 $message = self
::success(
273 _ngettext('%1$d row deleted.', '%1$d rows deleted.', $rows)
275 $message->addParam($rows);
281 * get Message for number of inserted rows
283 * shorthand for getting a customized message
285 * @param int $rows Number of rows
291 public static function getMessageForInsertedRows(int $rows): self
293 $message = self
::success(
294 _ngettext('%1$d row inserted.', '%1$d rows inserted.', $rows)
296 $message->addParam($rows);
302 * get Message of type error with custom content
304 * shorthand for getting a customized error message
306 * @param string $message A localized string
312 public static function rawError(string $message): self
314 return self
::raw($message, self
::ERROR
);
318 * get Message of type notice with custom content
320 * shorthand for getting a customized notice message
322 * @param string $message A localized string
328 public static function rawNotice(string $message): self
330 return self
::raw($message, self
::NOTICE
);
334 * get Message of type success with custom content
336 * shorthand for getting a customized success message
338 * @param string $message A localized string
344 public static function rawSuccess(string $message): self
346 return self
::raw($message, self
::SUCCESS
);
350 * returns whether this message is a success message or not
351 * and optionally makes this message a success message
353 * @param bool $set Whether to make this message of SUCCESS type
355 public function isSuccess(bool $set = false): bool
358 $this->setNumber(self
::SUCCESS
);
361 return $this->getNumber() === self
::SUCCESS
;
365 * returns whether this message is a notice message or not
366 * and optionally makes this message a notice message
368 * @param bool $set Whether to make this message of NOTICE type
370 public function isNotice(bool $set = false): bool
373 $this->setNumber(self
::NOTICE
);
376 return $this->getNumber() === self
::NOTICE
;
380 * returns whether this message is an error message or not
381 * and optionally makes this message an error message
383 * @param bool $set Whether to make this message of ERROR type
385 public function isError(bool $set = false): bool
388 $this->setNumber(self
::ERROR
);
391 return $this->getNumber() === self
::ERROR
;
395 * Set whether we should use BB Code when rendering.
397 * @param bool $useBBCode Use BB Code?
399 public function setBBCode(bool $useBBCode): void
401 $this->useBBCode
= $useBBCode;
405 * set raw message (overrides string)
407 * @param string $message A localized string
408 * @param bool $sanitize Whether to sanitize $message or not
410 public function setMessage(string $message, bool $sanitize = false): void
413 $message = self
::sanitize($message);
416 $this->message
= $message;
420 * set string (does not take effect if raw message is set)
422 * @param string $string string to set
423 * @param bool|int $sanitize whether to sanitize $string or not
425 public function setString(string $string, $sanitize = true): void
428 $string = self
::sanitize($string);
431 $this->string = $string;
435 * set message type number
437 * @param int $number message type number to set
439 public function setNumber(int $number): void
441 $this->number
= $number;
445 * add string or Message parameter
449 * $message->addParam('[em]some string[/em]');
452 * @param mixed $param parameter to add
454 public function addParam($param): void
456 if ($param instanceof self ||
is_float($param) ||
is_int($param)) {
457 $this->params
[] = $param;
459 $this->params
[] = htmlspecialchars((string) $param, ENT_COMPAT
);
464 * add parameter as raw HTML, usually in conjunction with strings
468 * $message->addParamHtml('<img src="img">');
471 * @param string $param parameter to add
473 public function addParamHtml(string $param): void
475 $this->params
[] = self
::notice($param);
479 * add a bunch of messages at once
481 * @param Message[] $messages to be added
482 * @param string $separator to use between this and previous string/message
484 public function addMessages(array $messages, string $separator = ' '): void
486 foreach ($messages as $message) {
487 $this->addMessage($message, $separator);
492 * add a bunch of messages at once
494 * @param string[] $messages to be added
495 * @param string $separator to use between this and previous string/message
497 public function addMessagesString(array $messages, string $separator = ' '): void
499 foreach ($messages as $message) {
500 $this->addText($message, $separator);
505 * Real implementation of adding message
507 * @param Message $message to be added
508 * @param string $separator to use between this and previous string/message
510 private function addMessageToList(self
$message, string $separator): void
512 if (! empty($separator)) {
513 $this->addedMessages
[] = $separator;
516 $this->addedMessages
[] = $message;
520 * add another raw message to be concatenated on displaying
522 * @param self $message to be added
523 * @param string $separator to use between this and previous string/message
525 public function addMessage(self
$message, string $separator = ' '): void
527 $this->addMessageToList($message, $separator);
531 * add another raw message to be concatenated on displaying
533 * @param string $message to be added
534 * @param string $separator to use between this and previous string/message
536 public function addText(string $message, string $separator = ' '): void
538 $this->addMessageToList(self
::notice(htmlspecialchars($message)), $separator);
542 * add another html message to be concatenated on displaying
544 * @param string $message to be added
545 * @param string $separator to use between this and previous string/message
547 public function addHtml(string $message, string $separator = ' '): void
549 $this->addMessageToList(self
::rawNotice($message), $separator);
553 * set all params at once, usually used in conjunction with string
555 * @param array $params parameters to set
556 * @param bool|int $sanitize whether to sanitize params
558 public function setParams(array $params, $sanitize = false): void
561 $params = self
::sanitize($params);
564 $this->params
= $params;
568 * return all parameters
572 public function getParams(): array
574 return $this->params
;
578 * return all added messages
582 public function getAddedMessages(): array
584 return $this->addedMessages
;
590 * @param mixed $message the message(s)
592 * @return mixed the sanitized message(s)
596 public static function sanitize($message)
598 if (is_array($message)) {
599 foreach ($message as $key => $val) {
600 $message[$key] = self
::sanitize($val);
606 return htmlspecialchars((string) $message);
610 * decode $message, taking into account our special codes
613 * @param string $message the message
615 * @return string the decoded message
619 public static function decodeBB(string $message): string
621 return Sanitize
::sanitizeMessage($message, false, true);
625 * wrapper for sprintf()
627 * @param mixed[] ...$params Params
629 * @return string formatted
631 public static function format(...$params): string
633 if (isset($params[1]) && is_array($params[1])) {
634 array_unshift($params[1], $params[0]);
635 $params = $params[1];
638 return sprintf(...$params);
642 * returns unique Message::$hash, if not exists it will be created
644 * @return string Message::$hash
646 public function getHash(): string
648 if ($this->hash
=== null) {
660 * returns compiled message
662 * @return string complete message
664 public function getMessage(): string
666 $message = $this->message
;
668 if (strlen($message) === 0) {
669 $string = $this->getString();
670 if (strlen($string) === 0) {
677 if ($this->isDisplayed()) {
678 $message = $this->getMessageWithIcon($message);
681 if (count($this->getParams()) > 0) {
682 $message = self
::format($message, $this->getParams());
685 if ($this->useBBCode
) {
686 $message = self
::decodeBB($message);
689 foreach ($this->getAddedMessages() as $add_message) {
690 $message .= $add_message;
697 * Returns only message string without image & other HTML.
699 public function getOnlyMessage(): string
701 return $this->message
;
705 * returns Message::$string
707 * @return string Message::$string
709 public function getString(): string
711 return $this->string;
715 * returns Message::$number
717 * @return int Message::$number
719 public function getNumber(): int
721 return $this->number
;
725 * returns level of message
727 * @return string level of message
729 public function getLevel(): string
731 return self
::$level[$this->getNumber()];
735 * returns HTML code for displaying this message
737 * @return string whole message box
739 public function getDisplay(): string
741 $this->isDisplayed(true);
743 $context = 'primary';
744 $level = $this->getLevel();
745 if ($level === 'error') {
747 } elseif ($level === 'success') {
748 $context = 'success';
751 $template = new Template();
753 return $template->render('message', [
754 'context' => $context,
755 'message' => $this->getMessage(),
760 * sets and returns whether the message was displayed or not
762 * @param bool $isDisplayed whether to set displayed flag
764 public function isDisplayed(bool $isDisplayed = false): bool
767 $this->isDisplayed
= true;
770 return $this->isDisplayed
;
774 * Returns the message with corresponding image icon
776 * @param string $message the message(s)
778 * @return string message with icon
780 public function getMessageWithIcon(string $message): string
782 if ($this->getLevel() === 'error') {
784 } elseif ($this->getLevel() === 'success') {
785 $image = 's_success';
790 $message = self
::notice(Html\Generator
::getImage($image)) . ' ' . $message;