[!!!][~FEATURE] Extbase (MVC): Improved the way flash messages are handled. Now there...
authorSebastian Kurfürst <sebastian@typo3.org>
Wed, 16 Sep 2009 10:00:10 +0000 (10:00 +0000)
committerSebastian Kurfürst <sebastian@typo3.org>
Wed, 16 Sep 2009 10:00:10 +0000 (10:00 +0000)
typo3/sysext/extbase/Classes/Dispatcher.php
typo3/sysext/extbase/Classes/MVC/Controller/AbstractController.php
typo3/sysext/extbase/Classes/MVC/Controller/ActionController.php
typo3/sysext/extbase/Classes/MVC/Controller/ControllerContext.php
typo3/sysext/extbase/Classes/MVC/Controller/FlashMessages.php [new file with mode: 0644]

index 03be0dd..3a1ebdd 100644 (file)
@@ -113,6 +113,9 @@ class Tx_Extbase_Dispatcher {
                        }
                }
 
+               $flashMessages = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_FlashMessages'); // singleton
+               $flashMessages->persist();
+
                $persistenceManager->persistAll();
                self::$reflectionService->shutdown();
                if (count($response->getAdditionalHeaderData()) > 0) {
@@ -176,6 +179,11 @@ class Tx_Extbase_Dispatcher {
                $propertyMapper->injectReflectionService(self::$reflectionService);
                $controller->injectPropertyMapper($propertyMapper);
                $controller->injectSettings(self::$configurationManager->getSettings($request->getControllerExtensionName()));
+
+               $flashMessages = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_FlashMessages'); // singleton
+               $flashMessages->reset();
+               $controller->injectFlashMessages($flashMessages);
+
                $cacheManager = t3lib_div::makeInstance('t3lib_cache_Manager');
                try {
                        self::$reflectionService->setCache($cacheManager->getCache('cache_extbase_reflection'));
index 5d0b2c3..7c371ae 100755 (executable)
@@ -104,6 +104,14 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
        protected $supportedRequestTypes = array('Tx_Extbase_MVC_Request');
 
        /**
+        * The flash messages. Use $this->flashMessages->add(...) to add a new Flash message.
+        *
+        * @var Tx_Extbase_MVC_Controller_FlashMessages
+        * @api
+        */
+       protected $flashMessages;
+
+       /**
         * Constructs the controller.
         */
        public function __construct() {
@@ -155,6 +163,16 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
        }
 
        /**
+        * Injects the flash messages container
+        *
+        * @param Tx_Extbase_MVC_Controller_FlashMessages $flashMessages
+        * @return void
+        */
+       public function injectFlashMessages(Tx_Extbase_MVC_Controller_FlashMessages $flashMessages) {
+               $this->flashMessages = $flashMessages;
+       }
+
+       /**
         * Checks if the current request type is supported by the controller.
         *
         * If your controller only supports certain request types, either
@@ -212,6 +230,7 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
                        $controllerContext->setArgumentsMappingResults($this->argumentsMappingResults);
                }
                $controllerContext->setUriBuilder($this->uriBuilder);
+               $controllerContext->setFlashMessages($this->flashMessages);
                return $controllerContext;
        }
 
@@ -347,62 +366,5 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas
                $this->propertyMapper->mapAndValidate($allPropertyNames, $this->request->getArguments(), $this->arguments, $optionalPropertyNames, $validator);
                $this->argumentsMappingResults = $this->propertyMapper->getMappingResults();
        }
-       
-       /**
-        * Add a flash message to the queue. It will live until the next call to
-        * popFlashMessages() in the current session.
-        *
-        * @param mixed $message anything serializable, should be "stringy"
-        * @return void
-        * @api
-        */
-       protected function pushFlashMessage($message) {
-               if (!is_string($message)) throw new InvalidArgumentException('The flash message must be string, ' . gettype($message) . ' given.', 1243258395);
-
-               $queuedFlashMessages = $this->getFlashMessagesFromSession();
-               $queuedFlashMessages[] = $message;
-               if (isset($GLOBALS['TSFE'])) {
-                       $GLOBALS['TSFE']->fe_user->setKey(
-                               'ses',
-                               'Extbase_AbstractController_flashMessages',
-                               $queuedFlashMessages
-                       );
-                       $GLOBALS['TSFE']->fe_user->storeSessionData();
-               }
-               // TODO Support BE
-       }
-
-       /**
-        * Returns queued flash messages and clear queue.
-        *
-        * @return array an array with flash messages or NULL if none available
-        * @api
-        */
-       protected function popFlashMessages() {
-               $queuedFlashMessages = $this->getFlashMessagesFromSession();
-               if (isset($GLOBALS['TSFE'])) {
-                       $GLOBALS['TSFE']->fe_user->setKey(
-                               'ses',
-                               'Extbase_AbstractController_flashMessages',
-                               NULL
-                       );
-                       $GLOBALS['TSFE']->fe_user->storeSessionData();
-               }
-               return $queuedFlashMessages;
-       }
-
-       /**
-        * Returns current flash messages from the seesion, making sure to always
-        * return an array.
-        *
-        * @return array
-        */
-       protected function getFlashMessagesFromSession() {
-               if (is_object($GLOBALS['TSFE']->fe_user)) {
-                       $flashMessages = $GLOBALS['TSFE']->fe_user->getKey('ses', 'Extbase_AbstractController_flashMessages');
-               }
-               return is_array($flashMessages) ? $flashMessages : array();
-       }
-       
 }
 ?>
index ca39c93..62e7688 100644 (file)
@@ -272,9 +272,8 @@ class Tx_Extbase_MVC_Controller_ActionController extends Tx_Extbase_MVC_Controll
                if (method_exists($view, 'injectSettings')) {
                        $view->injectSettings($this->settings);
                }
-               $view->initializeView(); // In FLOW3, solved through Object Lifecycle methods, we need to call it explicitely.
-               $view->assign('flashMessages', $this->popFlashMessages());
-               $view->assign('settings', $this->settings);
+               $view->initializeView(); // In FLOW3, solved through Object Lifecycle methods, we need to call it explicitely           
+               $view->assign('settings', $this->settings); // same with settings injection.
                return $view;
        }
 
index 5ce0ace..db1baf1 100644 (file)
@@ -62,6 +62,11 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
        protected $uriBuilder;
 
        /**
+        * @var Tx_Extbase_MVC_Controller_FlashMessages
+        */
+       protected $flashMessages;
+
+       /**
         * Set the request of the controller
         *
         * @param Tx_Extbase_MVC_Request $request
@@ -157,5 +162,24 @@ class Tx_Extbase_MVC_Controller_ControllerContext {
                return $this->uriBuilder;
        }
 
+       /**
+        * Set the flash messages
+        *
+        * @param Tx_Extbase_MVC_Controller_FlashMessages $flashMessages
+        * @return void
+        */
+       public function setFlashMessages(Tx_Extbase_MVC_Controller_FlashMessages $flashMessages) {
+               $this->flashMessages = $flashMessages;
+       }
+
+       /**
+        * Get the flash messages
+        *
+        * @return Tx_Extbase_MVC_Controller_FlashMessages
+        * @api
+        */
+       public function getFlashMessages() {
+               return $this->flashMessages;
+       }
 }
 ?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/MVC/Controller/FlashMessages.php b/typo3/sysext/extbase/Classes/MVC/Controller/FlashMessages.php
new file mode 100644 (file)
index 0000000..7821251
--- /dev/null
@@ -0,0 +1,152 @@
+<?php
+
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2009 Sebastian Kurfürst <sebastian@typo3.org>
+*  All rights reserved
+*
+*  This class is a backport of the corresponding class of FLOW3.
+*  All credits go to the v5 team.
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * This is a container for all Flash Messages. It is of scope session, but as Extbase
+ * has no session scope, we need to save it manually.
+ *
+ * @version $Id$
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
+ * @scope session
+ */
+class Tx_Extbase_MVC_Controller_FlashMessages implements t3lib_Singleton {
+
+       /**
+        * The array of flash messages
+        * @var array<string>
+        */
+       protected $flashMessages = array();
+
+       /**
+        * If FALSE, flash message container still needs to be initialized.
+        * @var boolean
+        */
+       protected $initialized = FALSE;
+
+       /**
+        * The key from which the flash messages should be retrieved.
+        * We have to incorporate the PluginKey and the Extension Key in here, to make
+        * it working when multiple plugins are on the same page.
+        * @var string
+        */
+       protected $flashMessageStorageKey = NULL;
+
+       /**
+        * Add another flash message.
+        *
+        * @param string $message
+        * @return void
+        * @api
+        */
+       public function add($message) {
+               if (!is_string($message)) throw new InvalidArgumentException('The flash message must be string, ' . gettype($message) . ' given.', 1243258395);
+               $this->initialize();
+               $this->flashMessages[] = $message;
+       }
+
+       /**
+        * Get all flash messages currently available.
+        *
+        * @return array<string> An array of flash messages
+        * @api
+        */
+       public function getAll() {
+               $this->initialize();
+               return $this->flashMessages;
+       }
+
+       /**
+        * Reset all flash messages.
+        *
+        * @return void
+        * @api
+        */
+       public function flush() {
+               $this->initialize();
+               $this->flashMessages = array();
+       }
+
+       /**
+        * Get all flash messages currently available and delete them afterwards.
+        *
+        * @return array<string>
+        * @api
+        */
+       public function getAllAndFlush() {
+               $this->initialize();
+               $flashMessages = $this->flashMessages;
+               $this->flashMessages = array();
+               return $flashMessages;
+       }
+
+       /**
+        * Initialize the flash message
+        */
+       protected function initialize() {
+               if ($this->initialized) return;
+
+               $frameworkConfiguration = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
+               $this->flashMessageStorageKey = 'Tx_Extbase_MVC_Controller_FlashMessages_messages_' . $frameworkConfiguration['extensionName'] . $frameworkConfiguration['pluginName'];
+
+               $flashMessages = NULL;
+               if (is_object($GLOBALS['TSFE']->fe_user)) {
+                       $flashMessages = $GLOBALS['TSFE']->fe_user->getKey('ses', $this->flashMessageStorageKey);
+               }
+               if (is_array($flashMessages)) {
+                       $this->flashMessages = $flashMessages;
+               }
+
+               $this->initialized = TRUE;
+       }
+
+       /**
+        * Reset the flash messages. Needs to be called at the beginning of a new rendering,
+        * to account when multiple plugins appear on the same page.
+        */
+       public function reset() {
+               $this->flashMessages = array();
+               $this->initialized = FALSE;
+               $this->flashMessageStorageKey = NULL;
+       }
+
+       /**
+        * Persist the flash messages in the session.
+        */
+       public function persist() {
+               if ($this->initialized && isset($GLOBALS['TSFE'])) {
+                       $GLOBALS['TSFE']->fe_user->setKey(
+                               'ses',
+                               $this->flashMessageStorageKey,
+                               $this->flashMessages
+                       );
+                       $GLOBALS['TSFE']->fe_user->storeSessionData();
+               }
+       }
+}
+
+?>
\ No newline at end of file