Created
May 19, 2010 19:35
-
-
Save zombor/406748 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php defined('SYSPATH') or die('No direct script access.'); | |
/** | |
* Acts as an object wrapper for HTML pages with embedded PHP, called "views". | |
* Variables can be assigned with the view object and referenced locally within | |
* the view. | |
* | |
* @package Kohana | |
* @category Base | |
* @author Kohana Team | |
* @copyright (c) 2008-2009 Kohana Team | |
* @license http://kohanaphp.com/license | |
*/ | |
class Kohana_View { | |
// Array of global variables | |
protected static $_global_data = array(); | |
/** | |
* Returns a new View object. If you do not define the "file" parameter, | |
* you must call [View::set_filename]. | |
* | |
* $view = View::factory($file); | |
* | |
* @param string view filename | |
* @param array array of values | |
* @return View | |
*/ | |
public static function factory($file = NULL, array $data = NULL) | |
{ | |
return new View($file, $data); | |
} | |
/** | |
* Captures the output that is generated when a view is included. | |
* The view data will be extracted to make local variables. This method | |
* is static to prevent object scope resolution. | |
* | |
* $output = View::capture($file, $data); | |
* | |
* @param string filename | |
* @param array variables | |
* @return string | |
*/ | |
protected static function capture($kohana_view_filename, array $kohana_view_data) | |
{ | |
// Import the view variables to local namespace | |
extract($kohana_view_data, EXTR_SKIP); | |
// Capture the view output | |
ob_start(); | |
try | |
{ | |
// Load the view within the current scope | |
include $kohana_view_filename; | |
} | |
catch (Exception $e) | |
{ | |
// Delete the output buffer | |
ob_end_clean(); | |
// Re-throw the exception | |
throw $e; | |
} | |
// Get the captured output and close the buffer | |
return ob_get_clean(); | |
} | |
/** | |
* Sets a global variable, similar to [View::set], except that the | |
* variable will be accessible to all views. | |
* | |
* View::set_global($name, $value); | |
* | |
* @param string variable name or an array of variables | |
* @param mixed value | |
* @return void | |
*/ | |
public static function set_global($key, $value = NULL) | |
{ | |
if (is_array($key)) | |
{ | |
foreach ($key as $key2 => $value) | |
{ | |
View::$_global_data[$key2] = $value; | |
} | |
} | |
else | |
{ | |
View::$_global_data[$key] = $value; | |
} | |
} | |
/** | |
* Assigns a global variable by reference, similar to [View::bind], except | |
* that the variable will be accessible to all views. | |
* | |
* View::bind_global($key, $value); | |
* | |
* @param string variable name | |
* @param mixed referenced variable | |
* @return void | |
*/ | |
public static function bind_global($key, & $value) | |
{ | |
View::$_global_data[$key] =& $value; | |
} | |
// View filename | |
protected $_file; | |
// Array of local variables | |
protected $_data = array(); | |
/** | |
* Sets the initial view filename and local data. Views should almost | |
* always only be created using [View::factory]. | |
* | |
* $view = new View($file); | |
* | |
* @param string view filename | |
* @param array array of values | |
* @return void | |
* @uses View::set_filename | |
*/ | |
public function __construct($file = NULL, array $data = NULL) | |
{ | |
if ($file !== NULL) | |
{ | |
$this->set_filename($file); | |
} | |
else | |
{ | |
$foo = explode('_', get_class($this)); | |
array_shift($foo); | |
$file = strtolower(implode('/', $foo)); | |
$this->set_filename($file); | |
} | |
if ( $data !== NULL) | |
{ | |
// Add the values to the current data | |
$this->_data = $data + $this->_data; | |
} | |
} | |
/** | |
* Magic method, searches for the given variable and returns its value. | |
* Local variables will be returned before global variables. | |
* | |
* $value = $view->foo; | |
* | |
* [!!] If the variable has not yet been set, an exception will be thrown. | |
* | |
* @param string variable name | |
* @return mixed | |
* @throws Kohana_Exception | |
*/ | |
public function & __get($key) | |
{ | |
if (isset($this->_data[$key])) | |
{ | |
return $this->_data[$key]; | |
} | |
elseif (isset(View::$_global_data[$key])) | |
{ | |
return View::$_global_data[$key]; | |
} | |
else | |
{ | |
throw new Kohana_Exception('View variable is not set: :var', | |
array(':var' => $key)); | |
} | |
} | |
/** | |
* Magic method, calls [View::set] with the same parameters. | |
* | |
* $view->foo = 'something'; | |
* | |
* @param string variable name | |
* @param mixed value | |
* @return void | |
*/ | |
public function __set($key, $value) | |
{ | |
$this->set($key, $value); | |
} | |
/** | |
* Magic method, determines if a variable is set. | |
* | |
* isset($view->foo); | |
* | |
* [!!] `NULL` variables are not considered to be set by [isset](http://php.net/isset). | |
* | |
* @param string variable name | |
* @return boolean | |
*/ | |
public function __isset($key) | |
{ | |
return (isset($this->_data[$key]) OR isset(View::$_global_data[$key])); | |
} | |
/** | |
* Magic method, unsets a given variable. | |
* | |
* unset($view->foo); | |
* | |
* @param string variable name | |
* @return void | |
*/ | |
public function __unset($key) | |
{ | |
unset($this->_data[$key], View::$_global_data[$key]); | |
} | |
/** | |
* Magic method, returns the output of [View::render]. | |
* | |
* @return string | |
* @uses View::render | |
*/ | |
public function __toString() | |
{ | |
try | |
{ | |
return $this->render(); | |
} | |
catch (Exception $e) | |
{ | |
// Display the exception message | |
Kohana::exception_handler($e); | |
return ''; | |
} | |
} | |
/** | |
* Sets the view filename. | |
* | |
* $view->set_filename($file); | |
* | |
* @param string view filename | |
* @return View | |
* @throws Kohana_View_Exception | |
*/ | |
public function set_filename($file) | |
{ | |
if (($path = Kohana::find_file('views', $file)) === FALSE) | |
{ | |
throw new Kohana_View_Exception('The requested view :file could not be found', array( | |
':file' => $file, | |
)); | |
} | |
// Store the file path locally | |
$this->_file = $path; | |
return $this; | |
} | |
/** | |
* Assigns a variable by name. Assigned values will be available as a | |
* variable within the view file: | |
* | |
* // This value can be accessed as $foo within the view | |
* $view->set('foo', 'my value'); | |
* | |
* You can also use an array to set several values at once: | |
* | |
* // Create the values $food and $beverage in the view | |
* $view->set(array('food' => 'bread', 'beverage' => 'water')); | |
* | |
* @param string variable name or an array of variables | |
* @param mixed value | |
* @return $this | |
*/ | |
public function set($key, $value = NULL) | |
{ | |
if (is_array($key)) | |
{ | |
foreach ($key as $name => $value) | |
{ | |
$this->_data[$name] = $value; | |
} | |
} | |
else | |
{ | |
$this->_data[$key] = $value; | |
} | |
return $this; | |
} | |
/** | |
* Assigns a value by reference. The benefit of binding is that values can | |
* be altered without re-setting them. It is also possible to bind variables | |
* before they have values. Assigned values will be available as a | |
* variable within the view file: | |
* | |
* // This reference can be accessed as $ref within the view | |
* $view->bind('ref', $bar); | |
* | |
* @param string variable name | |
* @param mixed referenced variable | |
* @return $this | |
*/ | |
public function bind($key, & $value) | |
{ | |
$this->_data[$key] =& $value; | |
return $this; | |
} | |
/** | |
* Renders the view object to a string. Global and local data are merged | |
* and extracted to create local variables within the view file. | |
* | |
* $output = View::render(); | |
* | |
* [!!] Global variables with the same key name as local variables will be | |
* overwritten by the local variable. | |
* | |
* @param string view filename | |
* @return string | |
* @throws Kohana_View_Exception | |
* @uses View::capture | |
*/ | |
public function render($file = NULL) | |
{ | |
if ($file !== NULL) | |
{ | |
$this->set_filename($file); | |
} | |
if (empty($this->_file)) | |
{ | |
throw new Kohana_View_Exception('You must set the file to use within your view before rendering'); | |
} | |
// Get the var_ properties | |
$class = new ReflectionClass($this); | |
foreach ($class->getProperties() as $property) | |
{ | |
if (substr_count($property->name, 'var_')) | |
{ | |
$this->set(str_replace('var_', '', $property->name), $this->{$property->name}); | |
} | |
} | |
// Get the var_ methods | |
foreach ($class->getMethods() as $method) | |
{ | |
if (substr_count($method->name, 'var_')) | |
{ | |
$this->set(str_replace('var_', '', $method->name), $this->{$method->name}()); | |
} | |
} | |
// Combine local and global data and capture the output | |
return View::capture($this->_file, $this->_data + View::$_global_data); | |
} | |
} // End View |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment