PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.2.0
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.2.0
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Notification / Manager.php
matomo / app / core / Notification Last commit date
Manager.php 1 year ago
Manager.php
190 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 */
9 namespace Piwik\Notification;
10
11 use Piwik\Notification;
12 use Piwik\Session;
13 use Piwik\Session\SessionNamespace;
14 /**
15 * Posts and removes UI notifications (see {@link Piwik\Notification} to learn more).
16 *
17 */
18 class Manager
19 {
20 public const MAX_NOTIFICATIONS_IN_SESSION = 30;
21 /**
22 * @var SessionNamespace
23 */
24 private static $session = null;
25 /**
26 * @var Notification[]
27 */
28 private static $notifications = array();
29 /**
30 * Posts a notification that will be shown in Piwik's status bar. If a notification with the same ID
31 * has been posted and has not been closed/removed, it will be replaced with `$notification`.
32 *
33 * @param string $id A unique identifier for this notification. The ID must be a valid HTML
34 * element ID. It can only contain alphanumeric characters (underscores can
35 * be used).
36 * @param Notification $notification The notification to post.
37 * @return bool true if the notification was added, false if it was ignored because there were too many
38 * pending ones.
39 * @api
40 */
41 public static function notify($id, Notification $notification)
42 {
43 self::checkId($id);
44 self::removeOldestNotificationsIfThereAreTooMany();
45 return self::addNotification($id, $notification);
46 }
47 /**
48 * Removes a posted notification by ID.
49 *
50 * @param string $id The notification ID, see {@link notify()}.
51 */
52 public static function cancel($id)
53 {
54 self::checkId($id);
55 self::removeNotification($id);
56 }
57 /**
58 * Removes all temporary notifications.
59 *
60 * Call this method after the notifications have been
61 * displayed to make sure temporary notifications won't be displayed twice.
62 */
63 public static function cancelAllNonPersistent()
64 {
65 foreach (static::getAllNotifications() as $id => $notification) {
66 if (Notification::TYPE_PERSISTENT != $notification->type) {
67 static::removeNotification($id);
68 }
69 }
70 }
71 /**
72 * Determine all notifications that needs to be displayed. They are sorted by priority. Highest priorities first.
73 * @return \ArrayObject
74 */
75 public static function getAllNotificationsToDisplay()
76 {
77 $notifications = static::getAllNotifications();
78 uasort($notifications, function ($n1, $n2) {
79 /** @var Notification $n1 */
80 /** @var Notification $n2 */
81 if ($n1->getPriority() == $n2->getPriority()) {
82 return 0;
83 }
84 return $n1->getPriority() > $n2->getPriority() ? -1 : 1;
85 });
86 return $notifications;
87 }
88 /**
89 * @param $id
90 * @throws \Exception In case id is empty or if id contains non word characters
91 */
92 private static function checkId($id)
93 {
94 if (empty($id)) {
95 throw new \Exception('Notification ID is empty.');
96 }
97 if (!preg_match('/^\\w*$/', $id)) {
98 throw new \Exception('Invalid Notification ID given. Only word characters (AlNum + underscore) allowed.');
99 }
100 }
101 private static function addNotification($id, Notification $notification)
102 {
103 self::saveNotificationAcrossUiRequestsIfNeeded($id, $notification);
104 if (count(self::$notifications) >= self::MAX_NOTIFICATIONS_IN_SESSION) {
105 return \false;
106 }
107 // we store all kinda notifications here so in case the session is not enabled or disabled later there is still
108 // a chance it gets delivered to the UI during the same request.
109 self::$notifications[$id] = $notification;
110 return \true;
111 }
112 private static function saveNotificationAcrossUiRequestsIfNeeded($id, Notification $notification)
113 {
114 if (self::isSessionEnabled()) {
115 // we need to save even non persistent notifications if possible. Otherwise if there's a redirect
116 // a notification is not shown on the next page view
117 $session = static::getSession();
118 $session->notifications[$id] = $notification;
119 }
120 }
121 private static function removeOldestNotificationsIfThereAreTooMany()
122 {
123 if (!self::isSessionEnabled()) {
124 return;
125 }
126 $maxNotificationsInSession = self::MAX_NOTIFICATIONS_IN_SESSION;
127 $session = static::getSession();
128 while (count($session->notifications) >= $maxNotificationsInSession) {
129 array_shift($session->notifications);
130 }
131 }
132 private static function getAllNotifications()
133 {
134 if (!self::isSessionEnabled()) {
135 return array();
136 }
137 $notifications = self::$notifications;
138 foreach ($notifications as $id => $notification) {
139 // we copy them over to the session if possible and persist it in case the session was not yet
140 // writable / enabled at the time the notification was added.
141 self::saveNotificationAcrossUiRequestsIfNeeded($id, $notification);
142 }
143 if (self::isSessionEnabled()) {
144 $session = static::getSession();
145 foreach ($session->notifications as $id => $notification) {
146 $notifications[$id] = $notification;
147 }
148 }
149 return $notifications;
150 }
151 private static function removeNotification($id)
152 {
153 if (array_key_exists($id, self::$notifications)) {
154 unset(self::$notifications[$id]);
155 }
156 if (self::isSessionEnabled()) {
157 $session = static::getSession();
158 if (array_key_exists($id, $session->notifications)) {
159 unset($session->notifications[$id]);
160 }
161 }
162 }
163 private static function isSessionEnabled()
164 {
165 return Session::isWritable() && Session::isReadable();
166 }
167 /**
168 * @return SessionNamespace
169 */
170 private static function getSession()
171 {
172 if (!isset(static::$session)) {
173 static::$session = new SessionNamespace('notification');
174 }
175 if (empty(static::$session->notifications) && self::isSessionEnabled()) {
176 static::$session->notifications = array();
177 }
178 return static::$session;
179 }
180 public static function cancelAllNotifications()
181 {
182 self::$notifications = [];
183 }
184 // for tests
185 public static function getPendingInMemoryNotifications()
186 {
187 return self::$notifications;
188 }
189 }
190