Skip to content

Commit

Permalink
Merge pull request #9676 from piwik/notification_deactivate_plugin
Browse files Browse the repository at this point in the history
Show an error message in case we deactivate a plugin because of missing dependencies
  • Loading branch information
tsteur committed Feb 13, 2016
2 parents e61124c + be4ff3c commit cbd47fe
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 15 deletions.
59 changes: 44 additions & 15 deletions core/Notification/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,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`.
Expand Down Expand Up @@ -105,12 +110,21 @@ private static function checkId($id)

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()
Expand All @@ -126,28 +140,43 @@ private static function removeOldestNotificationsIfThereAreTooMany()

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();
}
Expand All @@ -161,7 +190,7 @@ private static function getSession()
static::$session = new SessionNamespace('notification');
}

if (empty(static::$session->notifications) && self::isEnabled()) {
if (empty(static::$session->notifications) && self::isSessionEnabled()) {
static::$session->notifications = array();
}

Expand Down
11 changes: 11 additions & 0 deletions core/Plugin/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
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;
Expand Down Expand Up @@ -828,6 +830,15 @@ private function reloadActivatedPlugins()

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;
}

Expand Down
1 change: 1 addition & 0 deletions libs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
13 changes: 13 additions & 0 deletions libs/Zend/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,10 @@ public static function start($options = false)
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();
Expand Down Expand Up @@ -688,8 +692,17 @@ public static function writeClose($readonly = true)
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;
}
}


Expand Down

0 comments on commit cbd47fe

Please sign in to comment.