Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/Notification/Manager.php59
-rw-r--r--core/Plugin/Manager.php11
-rw-r--r--libs/README.md1
-rw-r--r--libs/Zend/Session.php13
4 files changed, 69 insertions, 15 deletions
diff --git a/core/Notification/Manager.php b/core/Notification/Manager.php
index e7eafec49e..bdf1f130dd 100644
--- a/core/Notification/Manager.php
+++ b/core/Notification/Manager.php
@@ -24,6 +24,11 @@ class Manager
private static $session = null;
/**
+ * @var Notification[]
+ */
+ private static $notifications = array();
+
+ /**
* Posts a notification that will be shown in Piwik's status bar. If a notification with the same ID
* has been posted and has not been closed/removed, it will be replaced with `$notification`.
*
@@ -105,12 +110,21 @@ class Manager
private static function addNotification($id, Notification $notification)
{
- if (!self::isEnabled()) {
- return;
- }
+ self::saveNotificationAcrossUiRequestsIfNeeded($id, $notification);
- $session = static::getSession();
- $session->notifications[$id] = $notification;
+ // we store all kinda notifications here so in case the session is not enabled or disabled later there is still
+ // a chance it gets delivered to the UI during the same request.
+ self::$notifications[$id] = $notification;
+ }
+
+ private static function saveNotificationAcrossUiRequestsIfNeeded($id, Notification $notification)
+ {
+ $isPersistent = $notification->type === Notification::TYPE_PERSISTENT;
+
+ if ($isPersistent && self::isSessionEnabled()) {
+ $session = static::getSession();
+ $session->notifications[$id] = $notification;
+ }
}
private static function removeOldestNotificationsIfThereAreTooMany()
@@ -126,28 +140,43 @@ class Manager
private static function getAllNotifications()
{
- if (!self::isEnabled()) {
+ if (!self::isSessionEnabled()) {
return array();
}
- $session = static::getSession();
+ $notifications = self::$notifications;
+
+ foreach ($notifications as $id => $notification) {
+ // we copy them over to the session if possible and persist it in case the session was not yet
+ // writable / enabled at the time the notification was added.
+ self::saveNotificationAcrossUiRequestsIfNeeded($id, $notification);
+ }
- return $session->notifications;
+ if (self::isSessionEnabled()) {
+ $session = static::getSession();
+ foreach ($session->notifications as $id => $notification) {
+ $notifications[$id] = $notification;
+ }
+ }
+
+ return $notifications;
}
private static function removeNotification($id)
{
- if (!self::isEnabled()) {
- return;
+ if (array_key_exists($id, self::$notifications)) {
+ unset(self::$notifications[$id]);
}
- $session = static::getSession();
- if (array_key_exists($id, $session->notifications)) {
- unset($session->notifications[$id]);
+ if (self::isSessionEnabled()) {
+ $session = static::getSession();
+ if (array_key_exists($id, $session->notifications)) {
+ unset($session->notifications[$id]);
+ }
}
}
- private static function isEnabled()
+ private static function isSessionEnabled()
{
return Session::isWritable() && Session::isReadable();
}
@@ -161,7 +190,7 @@ class Manager
static::$session = new SessionNamespace('notification');
}
- if (empty(static::$session->notifications) && self::isEnabled()) {
+ if (empty(static::$session->notifications) && self::isSessionEnabled()) {
static::$session->notifications = array();
}
diff --git a/core/Plugin/Manager.php b/core/Plugin/Manager.php
index 63a3e0aaaf..2b552f48e0 100644
--- a/core/Plugin/Manager.php
+++ b/core/Plugin/Manager.php
@@ -18,9 +18,11 @@ use Piwik\Container\StaticContainer;
use Piwik\EventDispatcher;
use Piwik\Filesystem;
use Piwik\Log;
+use Piwik\Notification;
use Piwik\Piwik;
use Piwik\Plugin;
use Piwik\PluginDeactivatedException;
+use Piwik\Session;
use Piwik\Theme;
use Piwik\Tracker;
use Piwik\Translation\Translator;
@@ -828,6 +830,15 @@ class Manager
if ($newPlugin->hasMissingDependencies()) {
$this->deactivatePlugin($pluginName);
+
+ // add this state we do not know yet whether current user has super user access. We do not even know
+ // if someone is actually logged in.
+ $message = sprintf('We disabled the plugin %s as it has missing dependencies.', $pluginName);
+ $message .= ' Please contact your Piwik administrator.';
+
+ $notification = new Notification($message);
+ $notification->context = Notification::CONTEXT_ERROR;
+ Notification\Manager::notify('PluginManager_PluginDeactivated', $notification);
continue;
}
diff --git a/libs/README.md b/libs/README.md
index f5a061a1dc..083684c962 100644
--- a/libs/README.md
+++ b/libs/README.md
@@ -30,3 +30,4 @@ third-party libraries:
- ZF-10871 - undefined variables when socket support disabled
- fix #6980 ("Array to string conversion") in `Zend/Session/Exception.php`
- fix Zend/Validate using deprecated iconv_set_encoding()
+ - Make sure sessions work when storing notifications
diff --git a/libs/Zend/Session.php b/libs/Zend/Session.php
index b5177c18fd..8b55a17b6d 100644
--- a/libs/Zend/Session.php
+++ b/libs/Zend/Session.php
@@ -491,6 +491,10 @@ class Zend_Session extends Zend_Session_Abstract
self::regenerateId();
}
+ if (isset($_SESSION['data']) && is_string($_SESSION['data'])) {
+ $_SESSION = unserialize(base64_decode($_SESSION['data']));
+ }
+
// run validators if they exist
if (isset($_SESSION['__ZF']['VALID'])) {
self::_processValidators();
@@ -688,8 +692,17 @@ class Zend_Session extends Zend_Session_Abstract
parent::$_writable = false;
}
+ if (isset($_SESSION)) {
+ $sessionBkp = $_SESSION;
+ $_SESSION = array('data' => base64_encode(serialize($_SESSION)));
+ }
+
session_write_close();
self::$_writeClosed = true;
+
+ if (isset($sessionBkp)) {
+ $_SESSION = $sessionBkp;
+ }
}