Helper.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 0.2.9
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\View;
  16. use Cake\Core\InstanceConfigTrait;
  17. use Cake\Event\EventListenerInterface;
  18. /**
  19. * Abstract base class for all other Helpers in CakePHP.
  20. * Provides common methods and features.
  21. *
  22. * ### Callback methods
  23. *
  24. * Helpers support a number of callback methods. These callbacks allow you to hook into
  25. * the various view lifecycle events and either modify existing view content or perform
  26. * other application specific logic. The events are not implemented by this base class, as
  27. * implementing a callback method subscribes a helper to the related event. The callback methods
  28. * are as follows:
  29. *
  30. * - `beforeRender(Event $event, $viewFile)` - beforeRender is called before the view file is rendered.
  31. * - `afterRender(Event $event, $viewFile)` - afterRender is called after the view file is rendered
  32. * but before the layout has been rendered.
  33. * - beforeLayout(Event $event, $layoutFile)` - beforeLayout is called before the layout is rendered.
  34. * - `afterLayout(Event $event, $layoutFile)` - afterLayout is called after the layout has rendered.
  35. * - `beforeRenderFile(Event $event, $viewFile)` - Called before any view fragment is rendered.
  36. * - `afterRenderFile(Event $event, $viewFile, $content)` - Called after any view fragment is rendered.
  37. * If a listener returns a non-null value, the output of the rendered file will be set to that.
  38. *
  39. */
  40. class Helper implements EventListenerInterface
  41. {
  42. use InstanceConfigTrait;
  43. /**
  44. * List of helpers used by this helper
  45. *
  46. * @var array
  47. */
  48. public $helpers = [];
  49. /**
  50. * Default config for this helper.
  51. *
  52. * @var array
  53. */
  54. protected $_defaultConfig = [];
  55. /**
  56. * A helper lookup table used to lazy load helper objects.
  57. *
  58. * @var array
  59. */
  60. protected $_helperMap = [];
  61. /**
  62. * The current theme name if any.
  63. *
  64. * @var string
  65. */
  66. public $theme = null;
  67. /**
  68. * Request object
  69. *
  70. * @var \Cake\Network\Request
  71. */
  72. public $request = null;
  73. /**
  74. * Plugin path
  75. *
  76. * @var string
  77. */
  78. public $plugin = null;
  79. /**
  80. * Holds the fields ['field_name' => ['type' => 'string', 'length' => 100]],
  81. * primaryKey and validates ['field_name']
  82. *
  83. * @var array
  84. */
  85. public $fieldset = [];
  86. /**
  87. * Holds tag templates.
  88. *
  89. * @var array
  90. */
  91. public $tags = [];
  92. /**
  93. * The View instance this helper is attached to
  94. *
  95. * @var \Cake\View\View
  96. */
  97. protected $_View;
  98. /**
  99. * Default Constructor
  100. *
  101. * @param \Cake\View\View $View The View this helper is being attached to.
  102. * @param array $config Configuration settings for the helper.
  103. */
  104. public function __construct(View $View, array $config = [])
  105. {
  106. $this->_View = $View;
  107. $this->request = $View->request;
  108. $this->config($config);
  109. if (!empty($this->helpers)) {
  110. $this->_helperMap = $View->helpers()->normalizeArray($this->helpers);
  111. }
  112. }
  113. /**
  114. * Provide non fatal errors on missing method calls.
  115. *
  116. * @param string $method Method to invoke
  117. * @param array $params Array of params for the method.
  118. * @return void
  119. */
  120. public function __call($method, $params)
  121. {
  122. trigger_error(sprintf('Method %1$s::%2$s does not exist', get_class($this), $method), E_USER_WARNING);
  123. }
  124. /**
  125. * Lazy loads helpers.
  126. *
  127. * @param string $name Name of the property being accessed.
  128. * @return \Cake\View\Helper|null Helper instance if helper with provided name exists
  129. */
  130. public function __get($name)
  131. {
  132. if (isset($this->_helperMap[$name]) && !isset($this->{$name})) {
  133. $config = ['enabled' => false] + (array)$this->_helperMap[$name]['config'];
  134. $this->{$name} = $this->_View->loadHelper($this->_helperMap[$name]['class'], $config);
  135. return $this->{$name};
  136. }
  137. }
  138. /**
  139. * Returns a string to be used as onclick handler for confirm dialogs.
  140. *
  141. * @param string $message Message to be displayed
  142. * @param string $okCode Code to be executed after user chose 'OK'
  143. * @param string $cancelCode Code to be executed after user chose 'Cancel'
  144. * @param array $options Array of options
  145. * @return string onclick JS code
  146. */
  147. protected function _confirm($message, $okCode, $cancelCode = '', $options = [])
  148. {
  149. $message = str_replace('\n', "\n", json_encode($message));
  150. $confirm = "if (confirm({$message})) { {$okCode} } {$cancelCode}";
  151. // We cannot change the key here in 3.x, but the behavior is inverted in this case
  152. $escape = isset($options['escape']) && $options['escape'] === false;
  153. if ($escape) {
  154. $confirm = h($confirm);
  155. }
  156. return $confirm;
  157. }
  158. /**
  159. * Adds the given class to the element options
  160. *
  161. * @param array $options Array options/attributes to add a class to
  162. * @param string $class The class name being added.
  163. * @param string $key the key to use for class.
  164. * @return array Array of options with $key set.
  165. */
  166. public function addClass(array $options = [], $class = null, $key = 'class')
  167. {
  168. if (isset($options[$key]) && trim($options[$key])) {
  169. $options[$key] .= ' ' . $class;
  170. } else {
  171. $options[$key] = $class;
  172. }
  173. return $options;
  174. }
  175. /**
  176. * Get the View callbacks this helper is interested in.
  177. *
  178. * By defining one of the callback methods a helper is assumed
  179. * to be interested in the related event.
  180. *
  181. * Override this method if you need to add non-conventional event listeners.
  182. * Or if you want helpers to listen to non-standard events.
  183. *
  184. * @return array
  185. */
  186. public function implementedEvents()
  187. {
  188. $eventMap = [
  189. 'View.beforeRenderFile' => 'beforeRenderFile',
  190. 'View.afterRenderFile' => 'afterRenderFile',
  191. 'View.beforeRender' => 'beforeRender',
  192. 'View.afterRender' => 'afterRender',
  193. 'View.beforeLayout' => 'beforeLayout',
  194. 'View.afterLayout' => 'afterLayout'
  195. ];
  196. $events = [];
  197. foreach ($eventMap as $event => $method) {
  198. if (method_exists($this, $method)) {
  199. $events[$event] = $method;
  200. }
  201. }
  202. return $events;
  203. }
  204. /**
  205. * Returns an array that can be used to describe the internal state of this
  206. * object.
  207. *
  208. * @return array
  209. */
  210. public function __debugInfo()
  211. {
  212. return [
  213. 'helpers' => $this->helpers,
  214. 'theme' => $this->theme,
  215. 'plugin' => $this->plugin,
  216. 'fieldset' => $this->fieldset,
  217. 'tags' => $this->tags,
  218. 'implementedEvents' => $this->implementedEvents(),
  219. '_config' => $this->config(),
  220. ];
  221. }
  222. }