/system/classes/kohana/view.php

https://github.com/letuboy/SwiftSharing-Core · PHP · 362 lines · 151 code · 33 blank · 178 comment · 10 complexity · d03e261d7d14e40a0ea65f1d28892c84 MD5 · raw file

  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * Acts as an object wrapper for HTML pages with embedded PHP, called "views".
  4. * Variables can be assigned with the view object and referenced locally within
  5. * the view.
  6. *
  7. * @package Kohana
  8. * @category Base
  9. * @author Kohana Team
  10. * @copyright (c) 2008-2011 Kohana Team
  11. * @license http://kohanaframework.org/license
  12. */
  13. class Kohana_View {
  14. // Array of global variables
  15. protected static $_global_data = array();
  16. /**
  17. * Returns a new View object. If you do not define the "file" parameter,
  18. * you must call [View::set_filename].
  19. *
  20. * $view = View::factory($file);
  21. *
  22. * @param string view filename
  23. * @param array array of values
  24. * @return View
  25. */
  26. public static function factory($file = NULL, array $data = NULL)
  27. {
  28. return new View($file, $data);
  29. }
  30. /**
  31. * Captures the output that is generated when a view is included.
  32. * The view data will be extracted to make local variables. This method
  33. * is static to prevent object scope resolution.
  34. *
  35. * $output = View::capture($file, $data);
  36. *
  37. * @param string filename
  38. * @param array variables
  39. * @return string
  40. */
  41. protected static function capture($kohana_view_filename, array $kohana_view_data)
  42. {
  43. // Import the view variables to local namespace
  44. extract($kohana_view_data, EXTR_SKIP);
  45. if (View::$_global_data)
  46. {
  47. // Import the global view variables to local namespace
  48. extract(View::$_global_data, EXTR_SKIP);
  49. }
  50. // Capture the view output
  51. ob_start();
  52. try
  53. {
  54. // Load the view within the current scope
  55. include $kohana_view_filename;
  56. }
  57. catch (Exception $e)
  58. {
  59. // Delete the output buffer
  60. ob_end_clean();
  61. // Re-throw the exception
  62. throw $e;
  63. }
  64. // Get the captured output and close the buffer
  65. return ob_get_clean();
  66. }
  67. /**
  68. * Sets a global variable, similar to [View::set], except that the
  69. * variable will be accessible to all views.
  70. *
  71. * View::set_global($name, $value);
  72. *
  73. * @param string variable name or an array of variables
  74. * @param mixed value
  75. * @return void
  76. */
  77. public static function set_global($key, $value = NULL)
  78. {
  79. if (is_array($key))
  80. {
  81. foreach ($key as $key2 => $value)
  82. {
  83. View::$_global_data[$key2] = $value;
  84. }
  85. }
  86. else
  87. {
  88. View::$_global_data[$key] = $value;
  89. }
  90. }
  91. /**
  92. * Assigns a global variable by reference, similar to [View::bind], except
  93. * that the variable will be accessible to all views.
  94. *
  95. * View::bind_global($key, $value);
  96. *
  97. * @param string variable name
  98. * @param mixed referenced variable
  99. * @return void
  100. */
  101. public static function bind_global($key, & $value)
  102. {
  103. View::$_global_data[$key] =& $value;
  104. }
  105. // View filename
  106. protected $_file;
  107. // Array of local variables
  108. protected $_data = array();
  109. /**
  110. * Sets the initial view filename and local data. Views should almost
  111. * always only be created using [View::factory].
  112. *
  113. * $view = new View($file);
  114. *
  115. * @param string view filename
  116. * @param array array of values
  117. * @return void
  118. * @uses View::set_filename
  119. */
  120. public function __construct($file = NULL, array $data = NULL)
  121. {
  122. if ($file !== NULL)
  123. {
  124. $this->set_filename($file);
  125. }
  126. if ($data !== NULL)
  127. {
  128. // Add the values to the current data
  129. $this->_data = $data + $this->_data;
  130. }
  131. }
  132. /**
  133. * Magic method, searches for the given variable and returns its value.
  134. * Local variables will be returned before global variables.
  135. *
  136. * $value = $view->foo;
  137. *
  138. * [!!] If the variable has not yet been set, an exception will be thrown.
  139. *
  140. * @param string variable name
  141. * @return mixed
  142. * @throws Kohana_Exception
  143. */
  144. public function & __get($key)
  145. {
  146. if (array_key_exists($key, $this->_data))
  147. {
  148. return $this->_data[$key];
  149. }
  150. elseif (array_key_exists($key, View::$_global_data))
  151. {
  152. return View::$_global_data[$key];
  153. }
  154. else
  155. {
  156. throw new Kohana_Exception('View variable is not set: :var',
  157. array(':var' => $key));
  158. }
  159. }
  160. /**
  161. * Magic method, calls [View::set] with the same parameters.
  162. *
  163. * $view->foo = 'something';
  164. *
  165. * @param string variable name
  166. * @param mixed value
  167. * @return void
  168. */
  169. public function __set($key, $value)
  170. {
  171. $this->set($key, $value);
  172. }
  173. /**
  174. * Magic method, determines if a variable is set.
  175. *
  176. * isset($view->foo);
  177. *
  178. * [!!] `NULL` variables are not considered to be set by [isset](http://php.net/isset).
  179. *
  180. * @param string variable name
  181. * @return boolean
  182. */
  183. public function __isset($key)
  184. {
  185. return (isset($this->_data[$key]) OR isset(View::$_global_data[$key]));
  186. }
  187. /**
  188. * Magic method, unsets a given variable.
  189. *
  190. * unset($view->foo);
  191. *
  192. * @param string variable name
  193. * @return void
  194. */
  195. public function __unset($key)
  196. {
  197. unset($this->_data[$key], View::$_global_data[$key]);
  198. }
  199. /**
  200. * Magic method, returns the output of [View::render].
  201. *
  202. * @return string
  203. * @uses View::render
  204. */
  205. public function __toString()
  206. {
  207. try
  208. {
  209. return $this->render();
  210. }
  211. catch (Exception $e)
  212. {
  213. // Display the exception message
  214. Kohana_Exception::handler($e);
  215. return '';
  216. }
  217. }
  218. /**
  219. * Sets the view filename.
  220. *
  221. * $view->set_filename($file);
  222. *
  223. * @param string view filename
  224. * @return View
  225. * @throws Kohana_View_Exception
  226. */
  227. public function set_filename($file)
  228. {
  229. // Detect if there was a file extension
  230. $_file = explode('.', $file);
  231. // If there are several components
  232. if (count($_file) > 1)
  233. {
  234. // Take the extension
  235. $ext = array_pop($_file);
  236. $file = implode('.', $_file);
  237. }
  238. // Otherwise set the extension to the standard
  239. else
  240. {
  241. $ext = ltrim(EXT, '.');
  242. }
  243. if (($path = Kohana::find_file('views', $file, $ext)) === FALSE)
  244. {
  245. throw new Kohana_View_Exception('The requested view :file could not be found', array(
  246. ':file' => $file.'.'.$ext,
  247. ));
  248. }
  249. // Store the file path locally
  250. $this->_file = $path;
  251. return $this;
  252. }
  253. /**
  254. * Assigns a variable by name. Assigned values will be available as a
  255. * variable within the view file:
  256. *
  257. * // This value can be accessed as $foo within the view
  258. * $view->set('foo', 'my value');
  259. *
  260. * You can also use an array to set several values at once:
  261. *
  262. * // Create the values $food and $beverage in the view
  263. * $view->set(array('food' => 'bread', 'beverage' => 'water'));
  264. *
  265. * @param string variable name or an array of variables
  266. * @param mixed value
  267. * @return $this
  268. */
  269. public function set($key, $value = NULL)
  270. {
  271. if (is_array($key))
  272. {
  273. foreach ($key as $name => $value)
  274. {
  275. $this->_data[$name] = $value;
  276. }
  277. }
  278. else
  279. {
  280. $this->_data[$key] = $value;
  281. }
  282. return $this;
  283. }
  284. /**
  285. * Assigns a value by reference. The benefit of binding is that values can
  286. * be altered without re-setting them. It is also possible to bind variables
  287. * before they have values. Assigned values will be available as a
  288. * variable within the view file:
  289. *
  290. * // This reference can be accessed as $ref within the view
  291. * $view->bind('ref', $bar);
  292. *
  293. * @param string variable name
  294. * @param mixed referenced variable
  295. * @return $this
  296. */
  297. public function bind($key, & $value)
  298. {
  299. $this->_data[$key] =& $value;
  300. return $this;
  301. }
  302. /**
  303. * Renders the view object to a string. Global and local data are merged
  304. * and extracted to create local variables within the view file.
  305. *
  306. * $output = $view->render();
  307. *
  308. * [!!] Global variables with the same key name as local variables will be
  309. * overwritten by the local variable.
  310. *
  311. * @param string view filename
  312. * @return string
  313. * @throws Kohana_View_Exception
  314. * @uses View::capture
  315. */
  316. public function render($file = NULL)
  317. {
  318. if ($file !== NULL)
  319. {
  320. $this->set_filename($file);
  321. }
  322. if (empty($this->_file))
  323. {
  324. throw new Kohana_View_Exception('You must set the file to use within your view before rendering');
  325. }
  326. // Combine local and global data and capture the output
  327. return View::capture($this->_file, $this->_data);
  328. }
  329. } // End View