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