From 2ff6bdccec343d434231382d7f7501794c457ae3 Mon Sep 17 00:00:00 2001 From: James Tancock Date: Wed, 4 Feb 2015 12:18:31 +0000 Subject: [PATCH] Back port of Flash component & helper --- .../Controller/Component/FlashComponent.php | 120 ++++++++++++++++++ lib/Cake/View/Helper/FlashHelper.php | 90 +++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 lib/Cake/Controller/Component/FlashComponent.php create mode 100644 lib/Cake/View/Helper/FlashHelper.php diff --git a/lib/Cake/Controller/Component/FlashComponent.php b/lib/Cake/Controller/Component/FlashComponent.php new file mode 100644 index 000000000..7963af629 --- /dev/null +++ b/lib/Cake/Controller/Component/FlashComponent.php @@ -0,0 +1,120 @@ + 'flash', + 'element' => 'default', + 'params' => array(), + ); + +/** + * Constructor + * + * @param ComponentCollection $collection + * @param array $settings + */ + public function __construct(ComponentCollection $collection, $settings = array()) { + $this->_defaultConfig = Hash::merge($this->_defaultConfig, $settings); + } + +/** + * Used to set a session variable that can be used to output messages in the view. + * + * In your controller: $this->Flash->set('This has been saved'); + * + * ### Options: + * + * - `key` The key to set under the session's Flash key + * - `element` The element used to render the flash message. Default to 'default'. + * - `params` An array of variables to make available when using an element + * + * @param string $message Message to be flashed. If an instance + * of Exception the exception message will be used and code will be set + * in params. + * @param array $options An array of options. + * @return void + */ + + public function set($message, $options = array()) { + $options += $this->_defaultConfig; + + if ($message instanceof Exception) { + $options['params'] += array('code' => $message->getCode()); + $message = $message->getMessage(); + } + + list($plugin, $element) = pluginSplit($options['element']); + + if ($plugin) { + $options['element'] = $plugin . '.Flash/' . $element; + } else { + $options['element'] = 'Flash/' . $element; + } + + CakeSession::write('Flash.' . $options['key'], array( + 'message' => $message, + 'key' => $options['key'], + 'element' => $options['element'], + 'params' => $options['params'] + )); + } + +/** + * Magic method for verbose flash methods based on element names. + * + * For example: $this->Flash->success('My message') would use the + * success.ctp element under `app/View/Element/Flash` for rendering the + * flash message. + * + * @param string $name Element name to use. + * @param array $args Parameters to pass when calling `FlashComponent::set()`. + * @return void + * @throws InternalErrorException If missing the flash message. + */ + public function __call($name, $args) { + $options = array('element' => Inflector::underscore($name)); + + if (count($args) < 1) { + throw new InternalErrorException(__('Flash message missing.')); + } + + if (!empty($args[1])) { + $options += (array)$args[1]; + } + + $this->set($args[0], $options); + } +} diff --git a/lib/Cake/View/Helper/FlashHelper.php b/lib/Cake/View/Helper/FlashHelper.php new file mode 100644 index 000000000..63071e982 --- /dev/null +++ b/lib/Cake/View/Helper/FlashHelper.php @@ -0,0 +1,90 @@ +Flash->render('somekey'); + * Will default to flash if no param is passed + * + * You can pass additional information into the flash message generation. This allows you + * to consolidate all the parameters for a given type of flash message into the view. + * + * ``` + * echo $this->Flash->render('flash', ['params' => ['name' => $user['User']['name']]]); + * ``` + * + * This would pass the current user's name into the flash message, so you could create personalized + * messages without the controller needing access to that data. + * + * Lastly you can choose the element that is used for rendering the flash message. Using + * custom elements allows you to fully customize how flash messages are generated. + * + * ``` + * echo $this->Flash->render('flash', ['element' => 'my_custom_element']); + * ``` + * + * If you want to use an element from a plugin for rendering your flash message + * you can use the dot notation for the plugin's element name: + * + * ``` + * echo $this->Flash->render('flash', [ + * 'element' => 'MyPlugin.my_custom_element', + * ]); + * ``` + * + * @param string $key The [Flash.]key you are rendering in the view. + * @param array $options Additional options to use for the creation of this flash message. + * Supports the 'params', and 'element' keys that are used in the helper. + * @return string|null Rendered flash message or null if flash key does not exist + * in session. + * @throws UnexpectedValueException If value for flash settings key is not an array. + */ + public function render($key = 'flash', $options = array()) { + + if (!CakeSession::check("Message.$key")) { + return; + } + + $flash = CakeSession::read("Message.$key"); + + if (!is_array($flash)) { + throw new UnexpectedValueException(sprintf( + 'Value for flash setting key "%s" must be an array.', + $key + )); + } + + $flash = $options + $flash; + CakeSession::delete("Flash.$key"); + + return $this->_View->element($flash['element'], $flash); + } +}