/src/View/ViewBuilder.php

https://gitlab.com/0072016/0072016-fbphp · PHP · 427 lines · 176 code · 54 blank · 197 comment · 19 complexity · 3a5f5aaedb00cd87a206fe545a693765 MD5 · raw file

  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 3.1.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\View;
  16. use Cake\Core\App;
  17. use Cake\Event\EventManager;
  18. use Cake\Network\Request;
  19. use Cake\Network\Response;
  20. use Cake\View\Exception\MissingViewException;
  21. use JsonSerializable;
  22. use Serializable;
  23. /**
  24. * Provides an API for iteratively building a view up.
  25. *
  26. * Once you have configured the view and established all the context
  27. * you can create a view instance with `build()`.
  28. */
  29. class ViewBuilder implements JsonSerializable, Serializable
  30. {
  31. /**
  32. * The subdirectory to the template.
  33. *
  34. * @var string
  35. */
  36. protected $_templatePath;
  37. /**
  38. * The template file to render.
  39. *
  40. * @var string
  41. */
  42. protected $_template;
  43. /**
  44. * The plugin name to use.
  45. *
  46. * @var string
  47. */
  48. protected $_plugin;
  49. /**
  50. * The theme name to use.
  51. *
  52. * @var string
  53. */
  54. protected $_theme;
  55. /**
  56. * The layout name to render.
  57. *
  58. * @var string
  59. */
  60. protected $_layout;
  61. /**
  62. * Whether or not autoLayout should be enabled.
  63. *
  64. * @var bool
  65. */
  66. protected $_autoLayout;
  67. /**
  68. * The layout path to build the view with.
  69. *
  70. * @var string
  71. */
  72. protected $_layoutPath;
  73. /**
  74. * The view variables to use
  75. *
  76. * @var string
  77. */
  78. protected $_name;
  79. /**
  80. * The view class name to use.
  81. * Can either use plugin notation, a short name
  82. * or a fully namespaced classname.
  83. *
  84. * @var string
  85. */
  86. protected $_className;
  87. /**
  88. * Additional options used when constructing the view.
  89. *
  90. * This options array lets you provide custom constructor
  91. * arguments to application/plugin view classes.
  92. *
  93. * @var array
  94. */
  95. protected $_options = [];
  96. /**
  97. * The helpers to use
  98. *
  99. * @var array
  100. */
  101. protected $_helpers = [];
  102. /**
  103. * Get/set path for template files.
  104. *
  105. * @param string|null $path Path for view files. If null returns current path.
  106. * @return string|$this
  107. */
  108. public function templatePath($path = null)
  109. {
  110. if ($path === null) {
  111. return $this->_templatePath;
  112. }
  113. $this->_templatePath = $path;
  114. return $this;
  115. }
  116. /**
  117. * Get/set path for layout files.
  118. *
  119. * @param string|null $path Path for layout files. If null returns current path.
  120. * @return string|$this
  121. */
  122. public function layoutPath($path = null)
  123. {
  124. if ($path === null) {
  125. return $this->_layoutPath;
  126. }
  127. $this->_layoutPath = $path;
  128. return $this;
  129. }
  130. /**
  131. * Turns on or off CakePHP's conventional mode of applying layout files.
  132. * On by default. Setting to off means that layouts will not be
  133. * automatically applied to rendered views.
  134. *
  135. * @param bool|null $autoLayout Boolean to turn on/off. If null returns current value.
  136. * @return bool|$this
  137. */
  138. public function autoLayout($autoLayout = null)
  139. {
  140. if ($autoLayout === null) {
  141. return $this->_autoLayout;
  142. }
  143. $this->_autoLayout = (bool)$autoLayout;
  144. return $this;
  145. }
  146. /**
  147. * The plugin name to use
  148. *
  149. * @param string|null|false $name Plugin name. If null returns current plugin.
  150. * Use false to remove the current plugin name.
  151. * @return string|$this
  152. */
  153. public function plugin($name = null)
  154. {
  155. if ($name === null) {
  156. return $this->_plugin;
  157. }
  158. $this->_plugin = $name;
  159. return $this;
  160. }
  161. /**
  162. * The helpers to use
  163. *
  164. * @param array|null $helpers Helpers to use.
  165. * @param bool $merge Whether or not to merge existing data with the new data.
  166. * @return array|$this
  167. */
  168. public function helpers(array $helpers = null, $merge = true)
  169. {
  170. if ($helpers === null) {
  171. return $this->_helpers;
  172. }
  173. if ($merge) {
  174. $helpers = array_merge($this->_helpers, $helpers);
  175. }
  176. $this->_helpers = $helpers;
  177. return $this;
  178. }
  179. /**
  180. * The view theme to use.
  181. *
  182. * @param string|null|false $theme Theme name. If null returns current theme.
  183. * Use false to remove the current theme.
  184. * @return string|$this
  185. */
  186. public function theme($theme = null)
  187. {
  188. if ($theme === null) {
  189. return $this->_theme;
  190. }
  191. $this->_theme = $theme;
  192. return $this;
  193. }
  194. /**
  195. * Get/set the name of the view file to render. The name specified is the
  196. * filename in /src/Template/<SubFolder> without the .ctp extension.
  197. *
  198. * @param string|null $name View file name to set. If null returns current name.
  199. * @return string|$this
  200. */
  201. public function template($name = null)
  202. {
  203. if ($name === null) {
  204. return $this->_template;
  205. }
  206. $this->_template = $name;
  207. return $this;
  208. }
  209. /**
  210. * Get/set the name of the layout file to render the view inside of.
  211. * The name specified is the filename of the layout in /src/Template/Layout
  212. * without the .ctp extension.
  213. *
  214. * @param string|null $name Layout file name to set. If null returns current name.
  215. * @return string|$this
  216. */
  217. public function layout($name = null)
  218. {
  219. if ($name === null) {
  220. return $this->_layout;
  221. }
  222. $this->_layout = $name;
  223. return $this;
  224. }
  225. /**
  226. * Set additional options for the view.
  227. *
  228. * This lets you provide custom constructor arguments to application/plugin view classes.
  229. *
  230. * @param array|null $options Either an array of options or null to get current options.
  231. * @param bool $merge Whether or not to merge existing data with the new data.
  232. * @return array|$this
  233. */
  234. public function options(array $options = null, $merge = true)
  235. {
  236. if ($options === null) {
  237. return $this->_options;
  238. }
  239. if ($merge) {
  240. $options = array_merge($this->_options, $options);
  241. }
  242. $this->_options = $options;
  243. return $this;
  244. }
  245. /**
  246. * Get/set the view name
  247. *
  248. * @param string|null $name The name of the view
  249. * @return array|$this
  250. */
  251. public function name($name = null)
  252. {
  253. if ($name === null) {
  254. return $this->_name;
  255. }
  256. $this->_name = $name;
  257. return $this;
  258. }
  259. /**
  260. * Get/set the view classname.
  261. *
  262. * Accepts either a short name (Ajax) a plugin name (MyPlugin.Ajax)
  263. * or a fully namespaced name (App\View\AppView).
  264. *
  265. * @param string|null $name The class name for the view. Can
  266. * be a plugin.class name reference, a short alias, or a fully
  267. * namespaced name.
  268. * @return array|$this
  269. */
  270. public function className($name = null)
  271. {
  272. if ($name === null) {
  273. return $this->_className;
  274. }
  275. $this->_className = $name;
  276. return $this;
  277. }
  278. /**
  279. * Using the data in the builder, create a view instance.
  280. *
  281. * If className() is null, App\View\AppView will be used.
  282. * If that class does not exist, then Cake\View\View will be used.
  283. *
  284. * @param array $vars The view variables/context to use.
  285. * @param \Cake\Network\Request|null $request The request to use.
  286. * @param \Cake\Network\Response|null $response The response to use.
  287. * @param \Cake\Event\EventManager|null $events The event manager to use.
  288. * @return \Cake\View\View
  289. * @throws \Cake\View\Exception\MissingViewException
  290. */
  291. public function build($vars = [], Request $request = null, Response $response = null, EventManager $events = null)
  292. {
  293. $className = $this->_className;
  294. if ($className === null) {
  295. $className = App::className('App', 'View', 'View') ?: 'Cake\View\View';
  296. }
  297. if ($className === 'View') {
  298. $className = App::className($className, 'View');
  299. } else {
  300. $className = App::className($className, 'View', 'View');
  301. }
  302. if (!$className) {
  303. throw new MissingViewException(['class' => $this->_className]);
  304. }
  305. $data = [
  306. 'name' => $this->_name,
  307. 'templatePath' => $this->_templatePath,
  308. 'template' => $this->_template,
  309. 'plugin' => $this->_plugin,
  310. 'theme' => $this->_theme,
  311. 'layout' => $this->_layout,
  312. 'autoLayout' => $this->_autoLayout,
  313. 'layoutPath' => $this->_layoutPath,
  314. 'helpers' => $this->_helpers,
  315. 'viewVars' => $vars,
  316. ];
  317. $data += $this->_options;
  318. return new $className($request, $response, $events, $data);
  319. }
  320. /**
  321. * Serializes the view builder object to a value that can be natively
  322. * serialized and re-used to clone this builder instance.
  323. *
  324. * @return array Serializable array of configuration properties.
  325. */
  326. public function jsonSerialize()
  327. {
  328. $properties = [
  329. '_templatePath', '_template', '_plugin', '_theme', '_layout', '_autoLayout',
  330. '_layoutPath', '_name', '_className', '_options', '_helpers'
  331. ];
  332. $array = [];
  333. foreach ($properties as $property) {
  334. $array[$property] = $this->{$property};
  335. }
  336. return array_filter($array, function ($i) {
  337. return !is_array($i) && strlen($i) || !empty($i);
  338. });
  339. }
  340. /**
  341. * Configures a view builder instance from serialized config.
  342. *
  343. * @param array $config View builder configuration array.
  344. * @return $this Configured view builder instance.
  345. */
  346. public function createFromArray($config)
  347. {
  348. foreach ($config as $property => $value) {
  349. $this->{$property} = $value;
  350. }
  351. return $this;
  352. }
  353. /**
  354. * Serializes the view builder object.
  355. *
  356. * @return string
  357. */
  358. public function serialize()
  359. {
  360. $array = $this->jsonSerialize();
  361. return serialize($array);
  362. }
  363. /**
  364. * Unserializes the view builder object.
  365. *
  366. * @param string $data Serialized string.
  367. * @return $this Configured view builder instance.
  368. */
  369. public function unserialize($data)
  370. {
  371. return $this->createFromArray(unserialize($data));
  372. }
  373. }