FlashComponent.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. namespace Tools\Controller\Component;
  3. use Cake\Core\Configure;
  4. use Cake\Event\Event;
  5. use Cake\Network\Exception\InternalErrorException;
  6. use Cake\Utility\Inflector;
  7. use Shim\Controller\Component\Component;
  8. /**
  9. * A flash component to enhance flash message support with stackable messages, both
  10. * persistent and transient.
  11. *
  12. * @author Mark Scherer
  13. * @copyright 2014 Mark Scherer
  14. * @license MIT
  15. * @deprecated Use dereuromark/cakephp-flash plugin instead.
  16. *
  17. * @method void success(string $message, array $options = []) Set a message using "success" element
  18. * @method void error(string $message, array $options = []) Set a message using "error" element
  19. * @method void warning(string $message, array $options = []) Set a message using "warning" element
  20. * @method void info(string $message, array $options = []) Set a message using "info" element
  21. */
  22. class FlashComponent extends Component {
  23. /**
  24. * @var array
  25. */
  26. protected $_defaultConfig = [
  27. 'headerKey' => 'X-Flash', // Set to empty string to deactivate AJAX response
  28. 'sessionLimit' => 99 // Max message limit for session (Configure doesn't need one)
  29. ];
  30. /**
  31. * Called after the Controller::beforeRender(), after the view class is loaded, and before the
  32. * Controller::render()
  33. *
  34. * @param \Cake\Event\Event $event
  35. * @return \Cake\Network\Response|null|void
  36. */
  37. public function beforeRender(Event $event) {
  38. if (!$this->Controller->request->is('ajax')) {
  39. return;
  40. }
  41. $headerKey = $this->config('headerKey');
  42. if (!$headerKey) {
  43. return;
  44. }
  45. $ajaxMessages = array_merge(
  46. (array)$this->Controller->request->session()->consume('FlashMessage'),
  47. (array)Configure::consume('FlashMessage')
  48. );
  49. // The header can be read with JavaScript and a custom Message can be displayed
  50. $this->Controller->response->header($headerKey, json_encode($ajaxMessages));
  51. }
  52. /**
  53. * Adds a flash message.
  54. * Updates "messages" session content (to enable multiple messages of one type).
  55. *
  56. * @param string $message Message to output.
  57. * @param string|null $options Options
  58. * @return void
  59. */
  60. public function message($message, $options = null) {
  61. if (!is_array($options)) {
  62. $type = $options;
  63. if (!$type) {
  64. $type = 'info';
  65. }
  66. $options = [];
  67. } else {
  68. $options += ['element' => 'info'];
  69. $type = $options['element'];
  70. }
  71. $old = (array)$this->Controller->request->session()->read('FlashMessage');
  72. if (isset($old[$type]) && count($old[$type]) > $this->config('sessionLimit')) {
  73. array_shift($old[$type]);
  74. }
  75. $old[$type][] = $message;
  76. $this->Controller->request->session()->write('FlashMessage', $old);
  77. }
  78. /**
  79. * Wrapper for original core functionality going into this extended component.
  80. * Core Auth component, for example, requires this.
  81. *
  82. * @param string $message
  83. * @param array $config
  84. * @return void
  85. */
  86. public function set($message, array $config = []) {
  87. // For now we only use the element name
  88. $defaults = ['element' => 'info'];
  89. $config += $defaults;
  90. $this->message($message, $config['element']);
  91. }
  92. /**
  93. * Adds a transient flash message.
  94. * These flash messages that are not saved (only available for current view),
  95. * will be merged into the session flash ones prior to output.
  96. *
  97. * @param string $message Message to output.
  98. * @param string|null $type Type ('error', 'warning', 'success', 'info' or custom class).
  99. * @return void
  100. */
  101. public static function transientMessage($message, $type = null) {
  102. if (!$type) {
  103. $type = 'info';
  104. }
  105. $old = (array)Configure::read('FlashMessage');
  106. if (isset($old[$type]) && count($old[$type]) > 99) {
  107. array_shift($old[$type]);
  108. }
  109. $old[$type][] = $message;
  110. Configure::write('FlashMessage', $old);
  111. }
  112. /**
  113. * Magic method for verbose flash methods based on element names.
  114. *
  115. * For example: $this->Flash->success('My message') would use the
  116. * success.ctp element under `App/Template/Element/Flash` for rendering the
  117. * flash message.
  118. *
  119. * @param string $name Element name to use.
  120. * @param array $args Parameters to pass when calling `FlashComponent::message()` or `set()`.
  121. * @return void
  122. * @throws \Cake\Network\Exception\InternalErrorException If missing the flash message.
  123. */
  124. public function __call($name, $args) {
  125. $options = ['element' => Inflector::underscore($name)];
  126. if (count($args) < 1) {
  127. throw new InternalErrorException('Flash message missing.');
  128. }
  129. if (!empty($args[1])) {
  130. $options += (array)$args[1];
  131. }
  132. $this->message($args[0], $options);
  133. }
  134. }