Merge pull request #19451 from wintermoor/patch-1
[civicrm-core.git] / CRM / Utils / Check / Message.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17 class CRM_Utils_Check_Message {
18 /**
19 * @var string
20 */
21 private $name;
22
23 /**
24 * @var string
25 */
26 private $message;
27
28 /**
29 * @var string
30 */
31 private $title;
32
33 /**
34 * @var int
35 * @see Psr\Log\LogLevel
36 */
37 private $level;
38
39 /**
40 * @var string
41 * help text (to be presented separately from the message)
42 */
43 private $help;
44
45 /**
46 * @var array
47 * actions which can be performed with this message
48 */
49 private $actions = [];
50
51 /**
52 * @var string
53 * crm-i css class
54 */
55 private $icon;
56
57 /**
58 * @var bool
59 * Has this message been suppressed?
60 */
61 private $isVisible;
62
63 /**
64 * @var bool|string
65 * Date this message is hidden until
66 */
67 private $hiddenUntil;
68
69 /**
70 * Class constructor.
71 *
72 * @param string $name
73 * Symbolic name for the check.
74 * @param string $message
75 * Printable message (short or long).
76 * @param string $title
77 * Printable message (short).
78 * @param string $level
79 * The severity of the message. Use PSR-3 log levels.
80 * @param string $icon
81 *
82 * @see Psr\Log\LogLevel
83 *
84 */
85 public function __construct($name, $message, $title, $level = \Psr\Log\LogLevel::WARNING, $icon = NULL) {
86 $this->name = $name;
87 $this->message = $message;
88 $this->title = $title;
89 $this->icon = $icon;
90 $this->setLevel($level);
91 }
92
93 /**
94 * Get name.
95 *
96 * @return string
97 */
98 public function getName() {
99 return $this->name;
100 }
101
102 /**
103 * Get message.
104 *
105 * @return string
106 */
107 public function getMessage() {
108 return $this->message;
109 }
110
111 /**
112 * @return string
113 */
114 public function getTitle() {
115 return $this->title;
116 }
117
118 /**
119 * Get severity level number.
120 *
121 * @return int
122 * @see Psr\Log\LogLevel
123 */
124 public function getLevel() {
125 return $this->level;
126 }
127
128 /**
129 * Get severity string.
130 *
131 * @return string
132 * @see Psr\Log\LogLevel
133 */
134 public function getSeverity() {
135 return CRM_Utils_Check::severityMap($this->level, TRUE);
136 }
137
138 /**
139 * Set optional additional help text.
140 *
141 * @param string $help
142 */
143 public function addHelp($help) {
144 $this->help = $help;
145 }
146
147 /**
148 * Set optional additional actions text.
149 *
150 * @param string $title
151 * Text displayed on the status message as a link or button.
152 * @param string $confirmation
153 * Optional confirmation message before performing action
154 * @param string $type
155 * Currently supports: api3 or href
156 * @param array $params
157 * Params to be passed to CRM.api3 or CRM.url depending on type
158 */
159 public function addAction($title, $confirmation, $type, $params) {
160 $this->actions[] = [
161 'title' => $title,
162 'confirm' => $confirmation,
163 'type' => $type,
164 'params' => $params,
165 ];
166 }
167
168 /**
169 * Set severity level
170 *
171 * @param string|int $level
172 * @throws \CRM_Core_Exception
173 */
174 public function setLevel($level) {
175 // Convert level to integer
176 if (!CRM_Utils_Rule::positiveInteger($level)) {
177 $level = CRM_Utils_Check::severityMap($level);
178 }
179 else {
180 // Validate numeric input - this will throw an exception if invalid
181 CRM_Utils_Check::severityMap($level, TRUE);
182 }
183 $this->level = $level;
184 // Clear internal caches
185 unset($this->isVisible, $this->hiddenUntil);
186 }
187
188 /**
189 * Convert to array.
190 *
191 * @return array
192 */
193 public function toArray() {
194 $array = [
195 'name' => $this->name,
196 'message' => $this->message,
197 'title' => $this->title,
198 'severity' => $this->getSeverity(),
199 'severity_id' => $this->level,
200 'is_visible' => (int) $this->isVisible(),
201 'icon' => $this->icon,
202 ];
203 if ($this->getHiddenUntil()) {
204 $array['hidden_until'] = $this->getHiddenUntil();
205 }
206 if (!empty($this->help)) {
207 $array['help'] = $this->help;
208 }
209 if (!empty($this->actions)) {
210 $array['actions'] = $this->actions;
211 }
212 return $array;
213 }
214
215 /**
216 * Get message visibility.
217 *
218 * @return bool
219 */
220 public function isVisible() {
221 if (!isset($this->isVisible)) {
222 $this->isVisible = !$this->checkStatusPreference();
223 }
224 return $this->isVisible;
225 }
226
227 /**
228 * Get date hidden until.
229 *
230 * @return string
231 */
232 public function getHiddenUntil() {
233 if (!isset($this->hiddenUntil)) {
234 $this->checkStatusPreference();
235 }
236 return $this->hiddenUntil;
237 }
238
239 /**
240 * Check if message has been hidden by the user.
241 *
242 * Also populates this->hiddenUntil property.
243 *
244 * @return bool
245 * TRUE means hidden, FALSE means visible.
246 * @throws \CiviCRM_API3_Exception
247 */
248 private function checkStatusPreference() {
249 $this->hiddenUntil = FALSE;
250 // Debug & info can't be hidden
251 if ($this->level < 2) {
252 return FALSE;
253 }
254 $where = [
255 ['name', '=', $this->getName()],
256 ['domain_id', '=', CRM_Core_Config::domainID()],
257 ];
258 // Check if there's a StatusPreference matching this name/domain.
259 $pref = civicrm_api4('StatusPreference', 'get', ['checkPermissions' => FALSE, 'where' => $where])->first();
260 if ($pref) {
261 // If so, compare severity to StatusPreference->severity.
262 if ($this->level <= $pref['ignore_severity']) {
263 if (isset($pref['hush_until'])) {
264 // Time-based hush.
265 $this->hiddenUntil = $pref['hush_until'];
266 $today = new DateTime();
267 $snoozeDate = new DateTime($pref['hush_until']);
268 return !($today > $snoozeDate);
269 }
270 else {
271 // Hidden indefinitely.
272 return TRUE;
273 }
274 }
275 }
276 return FALSE;
277 }
278
279 }