SproutCMS

This is the code documentation for the SproutCMS project

source of /sprout/Helpers/View.php

Copyright (C) 2017 Karmabunny Pty Ltd.

This file is a part of SproutCMS.

SproutCMS 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.

For more information, visit <http://getsproutcms.com>.

This class was originally from Kohana 2.3.4
Copyright 2007-2008 Kohana Team
  1. <?php
  2. /**
  3.  * Copyright (C) 2017 Karmabunny Pty Ltd.
  4.  *
  5.  * This file is a part of SproutCMS.
  6.  *
  7.  * SproutCMS is free software: you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation, either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * For more information, visit <http://getsproutcms.com>.
  12.  *
  13.  * This class was originally from Kohana 2.3.4
  14.  * Copyright 2007-2008 Kohana Team
  15.  */
  16. namespace Sprout\Helpers;
  17.  
  18. use Exception;
  19. use Kohana;
  20. use Kohana_Exception;
  21.  
  22.  
  23. /**
  24.  * Loads and displays Kohana view files.
  25.  */
  26. class View
  27. {
  28.  
  29. protected static $EXTENSION = '.php';
  30.  
  31. // The view file name and type
  32. protected $kohana_filename = FALSE;
  33.  
  34. // View variable storage
  35. protected $kohana_local_data = array();
  36. protected static $kohana_global_data = array();
  37.  
  38. /**
  39.   * Attempts to load a view and pre-load view data.
  40.   *
  41.   * @throws Kohana_Exception if the requested view cannot be found
  42.   * @param string $name view name
  43.   * @param array $data pre-load data
  44.   */
  45. public function __construct($name, array $data = [])
  46. {
  47. $this->setFilename($name);
  48.  
  49. // Preload data using array_merge, to allow user extensions
  50. $this->kohana_local_data = array_merge($this->kohana_local_data, $data);
  51. }
  52.  
  53. /**
  54.   * Magic method access to test for view property
  55.   *
  56.   * @param string View property to test for
  57.   * @return boolean
  58.   */
  59. public function __isset($key = NULL)
  60. {
  61. return $this->isPropertySet($key);
  62. }
  63.  
  64. /**
  65.   * Sets the view filename.
  66.   *
  67.   * @chainable
  68.   * @param string view filename
  69.   * @param string view file type
  70.   * @return object
  71.   */
  72. public function setFilename($name)
  73. {
  74. $name = Skin::findTemplate($name, static::$EXTENSION);
  75. $this->kohana_filename = DOCROOT . $name;
  76.  
  77. return $this;
  78. }
  79.  
  80. /**
  81.   * Sets a view variable.
  82.   *
  83.   * @param string|array name of variable or an array of variables
  84.   * @param mixed value when using a named variable
  85.   * @return object
  86.   */
  87. public function set($name, $value = NULL)
  88. {
  89. if (is_array($name))
  90. {
  91. foreach ($name as $key => $value)
  92. {
  93. $this->__set($key, $value);
  94. }
  95. }
  96. else
  97. {
  98. $this->__set($name, $value);
  99. }
  100.  
  101. return $this;
  102. }
  103.  
  104. /**
  105.   * Checks for a property existence in the view locally or globally. Unlike the built in __isset(),
  106.   * this method can take an array of properties to test simultaneously.
  107.   *
  108.   * @param string $key property name to test for
  109.   * @param array $key array of property names to test for
  110.   * @return boolean property test result
  111.   * @return array associative array of keys and boolean test result
  112.   */
  113. public function isPropertySet( $key = FALSE )
  114. {
  115. // Setup result;
  116. $result = FALSE;
  117.  
  118. // If key is an array
  119. if (is_array($key))
  120. {
  121. // Set the result to an array
  122. $result = array();
  123.  
  124. // Foreach key
  125. foreach ($key as $property)
  126. {
  127. // Set the result to an associative array
  128. $result[$property] = (array_key_exists($property, $this->kohana_local_data) OR array_key_exists($property, View::$kohana_global_data)) ? TRUE : FALSE;
  129. }
  130. }
  131. else
  132. {
  133. // Otherwise just check one property
  134. $result = (array_key_exists($key, $this->kohana_local_data) OR array_key_exists($key, View::$kohana_global_data)) ? TRUE : FALSE;
  135. }
  136.  
  137. // Return the result
  138. return $result;
  139. }
  140.  
  141. /**
  142.   * Sets a bound variable by reference.
  143.   *
  144.   * @param string name of variable
  145.   * @param mixed variable to assign by reference
  146.   * @return object
  147.   */
  148. public function bind($name, & $var)
  149. {
  150. $this->kohana_local_data[$name] =& $var;
  151.  
  152. return $this;
  153. }
  154.  
  155. /**
  156.   * Sets a view global variable.
  157.   *
  158.   * @param string|array name of variable or an array of variables
  159.   * @param mixed value when using a named variable
  160.   * @return void
  161.   */
  162. public static function setGlobal($name, $value = NULL)
  163. {
  164. if (is_array($name))
  165. {
  166. foreach ($name as $key => $value)
  167. {
  168. View::$kohana_global_data[$key] = $value;
  169. }
  170. }
  171. else
  172. {
  173. View::$kohana_global_data[$name] = $value;
  174. }
  175. }
  176.  
  177. /**
  178.   * Magically sets a view variable.
  179.   *
  180.   * @param string variable key
  181.   * @param string variable value
  182.   * @return void
  183.   */
  184. public function __set($key, $value)
  185. {
  186. $this->kohana_local_data[$key] = $value;
  187. }
  188.  
  189. /**
  190.   * Magically gets a view variable.
  191.   *
  192.   * @param string variable key
  193.   * @return mixed variable value if the key is found
  194.   * @return void if the key is not found
  195.   */
  196. public function &__get($key)
  197. {
  198. if (isset($this->kohana_local_data[$key]))
  199. return $this->kohana_local_data[$key];
  200.  
  201. if (isset(View::$kohana_global_data[$key]))
  202. return View::$kohana_global_data[$key];
  203.  
  204. if (isset($this->$key))
  205. return $this->$key;
  206.  
  207. $default = null;
  208. return $default;
  209. }
  210.  
  211. /**
  212.   * Magically converts view object to string.
  213.   *
  214.   * @return string
  215.   */
  216. public function __toString()
  217. {
  218. try
  219. {
  220. return $this->render();
  221. }
  222. catch (Exception $e)
  223. {
  224. // Display the exception using its internal __toString method
  225. return (string) $e;
  226. }
  227. }
  228.  
  229. /**
  230.   * Renders a view.
  231.   *
  232.   * @param boolean set to TRUE to echo the output instead of returning it
  233.   * @param callback special renderer to pass the output through
  234.   * @return string if print is FALSE
  235.   * @return void if print is TRUE
  236.   */
  237. public function render($print = FALSE, $renderer = FALSE)
  238. {
  239. if (empty($this->kohana_filename))
  240. throw new Kohana_Exception('core.view_set_filename');
  241.  
  242. // Merge global and local data, local overrides global with the same name
  243. $data = array_merge(View::$kohana_global_data, $this->kohana_local_data);
  244. foreach ($data as &$datum) {
  245. if ($datum instanceof View) $datum = $datum->render();
  246. }
  247.  
  248. $data_into_view = function($_view_filename, $input_data)
  249. {
  250. if ($_view_filename == '') return '';
  251.  
  252.  
  253. // Import the view variables to local scope
  254. extract($input_data, EXTR_SKIP);
  255.  
  256. try {
  257. include $_view_filename;
  258. } catch (Exception $e) {
  259. throw $e;
  260. }
  261.  
  262. return ob_get_clean();
  263. };
  264. $output = $data_into_view($this->kohana_filename, $data);
  265.  
  266. if ($renderer !== FALSE AND is_callable($renderer, TRUE))
  267. {
  268. // Pass the output through the user defined renderer
  269. $output = call_user_func($renderer, $output);
  270. }
  271.  
  272. if ($print === TRUE)
  273. {
  274. // Display the output
  275. echo $output;
  276. return;
  277. }
  278.  
  279. return $output;
  280. }
  281.  
  282.  
  283. /**
  284.   * Shorthand load and render a view.
  285.   *
  286.   * @param string $name
  287.   * @param null|array $data
  288.   * @return string
  289.   * @throws Exception
  290.   */
  291. public static function include(string $name, ?array $data = []): string
  292. {
  293. $view = new View($name, $data);
  294. return $view->render();
  295. }
  296.  
  297.  
  298. /**
  299.   * Create a view as appropriate for the 'sprout.skin_view_types' config.
  300.   *
  301.   * @param string $name
  302.   * @param array $data
  303.   * @return View
  304.   */
  305. public static function create(string $name, $data = [])
  306. {
  307. $type = Kohana::config('sprout.skin_views_type') ?? 'php';
  308.  
  309. switch ($type ?? 'php') {
  310. case 'php':
  311. default:
  312. return new View($name);
  313.  
  314. case 'twig':
  315. return new TwigView($name);
  316. }
  317. }
  318.  
  319. } // End View
  320.