Jelajahi Sumber

Minz: Attach a notification to a request (#3208)

* Minz: Attach a notification to a request

Notifications should be attached to a request, not to a global session.
Fix
https://github.com/FreshRSS/FreshRSS/pull/3096#issuecomment-654891906
Prepare https://github.com/FreshRSS/FreshRSS/pull/3096

* Rename array

* Avoid string constants

Implement
https://github.com/FreshRSS/FreshRSS/pull/3208#issuecomment-703243863

* Improved logic

* Simplify storage

https://github.com/FreshRSS/FreshRSS/pull/3208#discussion_r499511213

* Fix notification bug in configuration/system
Alexandre Alapetite 5 tahun lalu
induk
melakukan
7652369359

+ 1 - 4
app/Controllers/authController.php

@@ -166,10 +166,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
 
 				header('HTTP/1.1 403 Forbidden');
 				Minz_Session::_param('POST_to_GET', true);	//Prevent infinite internal redirect
-				Minz_View::_param('notification', [
-					'type' => 'bad',
-					'content' => _t('feedback.auth.login.invalid'),
-				]);
+				Minz_Request::setBadNotification(_t('feedback.auth.login.invalid'));
 				Minz_Request::forward(['c' => 'auth', 'a' => 'login'], false);
 				return;
 			}

+ 1 - 4
app/Controllers/configureController.php

@@ -374,10 +374,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 
 			invalidateHttpCache();
 
-			Minz_Session::_param('notification', array(
-				'type' => 'good',
-				'content' => _t('feedback.conf.updated')
-			));
+			Minz_Request::good(_t('feedback.conf.updated'), [ 'c' => 'configure', 'a' => 'system' ]);
 		}
 	}
 }

+ 1 - 5
app/Controllers/feedController.php

@@ -544,11 +544,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
 			// Most of the time, ajax request is for only one feed. But since
 			// there are several parallel requests, we should return that there
 			// are several updated feeds.
-			$notif = array(
-				'type' => 'good',
-				'content' => _t('feedback.sub.feed.actualizeds')
-			);
-			Minz_Session::_param('notification', $notif);
+			Minz_Request::setGoodNotification(_t('feedback.sub.feed.actualizeds'));
 			// No layout in ajax request.
 			$this->view->_layout(false);
 		} else {

+ 10 - 10
app/Controllers/userController.php

@@ -356,11 +356,11 @@ class FreshRSS_user_Controller extends Minz_ActionController {
 				FreshRSS_Auth::giveAccess();
 			}
 
-			$notif = array(
-				'type' => $ok ? 'good' : 'bad',
-				'content' => _t('feedback.user.created' . (!$ok ? '.error' : ''), $new_user_name)
-			);
-			Minz_Session::_param('notification', $notif);
+			if ($ok) {
+				Minz_Request::setGoodNotification(_t('feedback.user.created', $new_user_name));
+			} else {
+				Minz_Request::setBadNotification(_t('feedback.user.created.error', $new_user_name));
+			}
 		}
 
 		$redirect_url = urldecode(Minz_Request::param('r', false, true));
@@ -546,11 +546,11 @@ class FreshRSS_user_Controller extends Minz_ActionController {
 			}
 			invalidateHttpCache();
 
-			$notif = array(
-				'type' => $ok ? 'good' : 'bad',
-				'content' => _t('feedback.user.deleted' . (!$ok ? '.error' : ''), $username)
-			);
-			Minz_Session::_param('notification', $notif);
+			if ($ok) {
+				Minz_Request::setGoodNotification(_t('feedback.user.deleted', $username));
+			} else {
+				Minz_Request::setBadNotification(_t('feedback.user.deleted.error', $username));
+			}
 		}
 
 		Minz_Request::forward($redirect_url, true);

+ 1 - 2
app/FreshRSS.php

@@ -125,10 +125,9 @@ class FreshRSS extends Minz_FrontController {
 	}
 
 	private static function loadNotifications() {
-		$notif = Minz_Session::param('notification');
+		$notif = Minz_Request::getNotification();
 		if ($notif) {
 			Minz_View::_param('notification', $notif);
-			Minz_Session::_param('notification');
 		}
 	}
 

+ 46 - 10
lib/Minz/Request.php

@@ -261,6 +261,49 @@ class Minz_Request {
 		return (bool)$is_public;
 	}
 
+	private static function requestId() {
+		if (empty($_GET['rid']) || !ctype_xdigit($_GET['rid'])) {
+			$_GET['rid'] = uniqid();
+		}
+		return $_GET['rid'];
+	}
+
+	private static function setNotification($type, $content) {
+		//TODO: Will need to ensure non-concurrency when landing https://github.com/FreshRSS/FreshRSS/pull/3096
+		$requests = Minz_Session::param('requests', []);
+		$requests[self::requestId()] = [
+				'time' => time(),
+				'notification' => [ 'type' => $type, 'content' => $content ],
+			];
+		Minz_Session::_param('requests', $requests);
+	}
+
+	public static function setGoodNotification($content) {
+		self::setNotification('good', $content);
+	}
+
+	public static function setBadNotification($content) {
+		self::setNotification('bad', $content);
+	}
+
+	public static function getNotification() {
+		$notif = null;
+		//TODO: Will need to ensure non-concurrency when landing https://github.com/FreshRSS/FreshRSS/pull/3096
+		$requests = Minz_Session::param('requests');
+		if ($requests) {
+			//Delete abandonned notifications
+			$requests = array_filter($requests, function ($r) { return isset($r['time']) && $r['time'] > time() - 3600; });
+
+			$requestId = self::requestId();
+			if (!empty($requests[$requestId]['notification'])) {
+				$notif = $requests[$requestId]['notification'];
+				unset($requests[$requestId]);
+			}
+			Minz_Session::_param('requests', $requests);
+		}
+		return $notif;
+	}
+
 	/**
 	 * Relance une requête
 	 * @param $url l'url vers laquelle est relancée la requête
@@ -274,6 +317,7 @@ class Minz_Request {
 		}
 
 		$url = Minz_Url::checkUrl($url);
+		$url['params']['rid'] = self::requestId();
 
 		if ($redirect) {
 			header('Location: ' . Minz_Url::display($url, 'php'));
@@ -296,20 +340,12 @@ class Minz_Request {
 	 * @param $url url array to where we should be forwarded
 	 */
 	public static function good($msg, $url = array()) {
-		Minz_Session::_param('notification', array(
-			'type' => 'good',
-			'content' => $msg
-		));
-
+		Minz_Request::setGoodNotification($msg);
 		Minz_Request::forward($url, true);
 	}
 
 	public static function bad($msg, $url = array()) {
-		Minz_Session::_param('notification', array(
-			'type' => 'bad',
-			'content' => $msg
-		));
-
+		Minz_Request::setBadNotification($msg);
 		Minz_Request::forward($url, true);
 	}