1<?php defined('SYSPATH') OR die('No direct access allowed.'); 2/** 3 * Loads and displays Kohana view files. Can also handle output of some binary 4 * files, such as image, Javascript, and CSS files. 5 * 6 * $Id: View.php 4072 2009-03-13 17:20:38Z jheathco $ 7 * 8 * @package Core 9 * @author Kohana Team 10 * @copyright (c) 2007-2008 Kohana Team 11 * @license http://kohanaphp.com/license.html 12 */ 13class View_Core { 14 15 // The view file name and type 16 protected $kohana_filename = FALSE; 17 protected $kohana_filetype = FALSE; 18 19 // View variable storage 20 protected $kohana_local_data = array(); 21 protected static $kohana_global_data = array(); 22 23 /** 24 * Creates a new View using the given parameters. 25 * 26 * @param string view name 27 * @param array pre-load data 28 * @param string type of file: html, css, js, etc. 29 * @return object 30 */ 31 public static function factory($name = NULL, $data = NULL, $type = NULL) 32 { 33 return new View($name, $data, $type); 34 } 35 36 /** 37 * Attempts to load a view and pre-load view data. 38 * 39 * @throws Kohana_Exception if the requested view cannot be found 40 * @param string view name 41 * @param array pre-load data 42 * @param string type of file: html, css, js, etc. 43 * @return void 44 */ 45 public function __construct($name = NULL, $data = NULL, $type = NULL) 46 { 47 if (is_string($name) AND $name !== '') 48 { 49 // Set the filename 50 $this->set_filename($name, $type); 51 } 52 53 if (is_array($data) AND ! empty($data)) 54 { 55 // Preload data using array_merge, to allow user extensions 56 $this->kohana_local_data = array_merge($this->kohana_local_data, $data); 57 } 58 } 59 60 /** 61 * Magic method access to test for view property 62 * 63 * @param string View property to test for 64 * @return boolean 65 */ 66 public function __isset($key = NULL) 67 { 68 return $this->is_set($key); 69 } 70 71 /** 72 * Sets the view filename. 73 * 74 * @chainable 75 * @param string view filename 76 * @param string view file type 77 * @return object 78 */ 79 public function set_filename($name, $type = NULL) 80 { 81 if ($type == NULL) 82 { 83 // Load the filename and set the content type 84 $this->kohana_filename = Kohana::find_file('views', $name, TRUE); 85 $this->kohana_filetype = EXT; 86 } 87 else 88 { 89 // Check if the filetype is allowed by the configuration 90 if ( ! in_array($type, Kohana::config('view.allowed_filetypes'))) 91 throw new Kohana_Exception('core.invalid_filetype', $type); 92 93 // Load the filename and set the content type 94 $this->kohana_filename = Kohana::find_file('views', $name, TRUE, $type); 95 $this->kohana_filetype = Kohana::config('mimes.'.$type); 96 97 if ($this->kohana_filetype == NULL) 98 { 99 // Use the specified type 100 $this->kohana_filetype = $type; 101 } 102 } 103 104 return $this; 105 } 106 107 /** 108 * Sets a view variable. 109 * 110 * @param string|array name of variable or an array of variables 111 * @param mixed value when using a named variable 112 * @return object 113 */ 114 public function set($name, $value = NULL) 115 { 116 if (is_array($name)) 117 { 118 foreach ($name as $key => $value) 119 { 120 $this->__set($key, $value); 121 } 122 } 123 else 124 { 125 $this->__set($name, $value); 126 } 127 128 return $this; 129 } 130 131 /** 132 * Checks for a property existence in the view locally or globally. Unlike the built in __isset(), 133 * this method can take an array of properties to test simultaneously. 134 * 135 * @param string $key property name to test for 136 * @param array $key array of property names to test for 137 * @return boolean property test result 138 * @return array associative array of keys and boolean test result 139 */ 140 public function is_set( $key = FALSE ) 141 { 142 // Setup result; 143 $result = FALSE; 144 145 // If key is an array 146 if (is_array($key)) 147 { 148 // Set the result to an array 149 $result = array(); 150 151 // Foreach key 152 foreach ($key as $property) 153 { 154 // Set the result to an associative array 155 $result[$property] = (array_key_exists($property, $this->kohana_local_data) OR array_key_exists($property, View::$kohana_global_data)) ? TRUE : FALSE; 156 } 157 } 158 else 159 { 160 // Otherwise just check one property 161 $result = (array_key_exists($key, $this->kohana_local_data) OR array_key_exists($key, View::$kohana_global_data)) ? TRUE : FALSE; 162 } 163 164 // Return the result 165 return $result; 166 } 167 168 /** 169 * Sets a bound variable by reference. 170 * 171 * @param string name of variable 172 * @param mixed variable to assign by reference 173 * @return object 174 */ 175 public function bind($name, & $var) 176 { 177 $this->kohana_local_data[$name] =& $var; 178 179 return $this; 180 } 181 182 /** 183 * Sets a view global variable. 184 * 185 * @param string|array name of variable or an array of variables 186 * @param mixed value when using a named variable 187 * @return void 188 */ 189 public static function set_global($name, $value = NULL) 190 { 191 if (is_array($name)) 192 { 193 foreach ($name as $key => $value) 194 { 195 View::$kohana_global_data[$key] = $value; 196 } 197 } 198 else 199 { 200 View::$kohana_global_data[$name] = $value; 201 } 202 } 203 204 /** 205 * Magically sets a view variable. 206 * 207 * @param string variable key 208 * @param string variable value 209 * @return void 210 */ 211 public function __set($key, $value) 212 { 213 $this->kohana_local_data[$key] = $value; 214 } 215 216 /** 217 * Magically gets a view variable. 218 * 219 * @param string variable key 220 * @return mixed variable value if the key is found 221 * @return void if the key is not found 222 */ 223 public function &__get($key) 224 { 225 if (isset($this->kohana_local_data[$key])) 226 return $this->kohana_local_data[$key]; 227 228 if (isset(View::$kohana_global_data[$key])) 229 return View::$kohana_global_data[$key]; 230 231 if (isset($this->$key)) 232 return $this->$key; 233 } 234 235 /** 236 * Magically converts view object to string. 237 * 238 * @return string 239 */ 240 public function __toString() 241 { 242 try 243 { 244 return $this->render(); 245 } 246 catch (Exception $e) 247 { 248 // Display the exception using its internal __toString method 249 return (string) $e; 250 } 251 } 252 253 /** 254 * Renders a view. 255 * 256 * @param boolean set to TRUE to echo the output instead of returning it 257 * @param callback special renderer to pass the output through 258 * @return string if print is FALSE 259 * @return void if print is TRUE 260 */ 261 public function render($print = FALSE, $renderer = FALSE) 262 { 263 if (empty($this->kohana_filename)) 264 throw new Kohana_Exception('core.view_set_filename'); 265 266 if (is_string($this->kohana_filetype)) 267 { 268 // Merge global and local data, local overrides global with the same name 269 $data = array_merge(View::$kohana_global_data, $this->kohana_local_data); 270 271 // Load the view in the controller for access to $this 272 $output = Kohana::$instance->_kohana_load_view($this->kohana_filename, $data); 273 274 if ($renderer !== FALSE AND is_callable($renderer, TRUE)) 275 { 276 // Pass the output through the user defined renderer 277 $output = call_user_func($renderer, $output); 278 } 279 280 if ($print === TRUE) 281 { 282 // Display the output 283 echo $output; 284 return; 285 } 286 } 287 else 288 { 289 // Set the content type and size 290 header('Content-Type: '.$this->kohana_filetype[0]); 291 292 if ($print === TRUE) 293 { 294 if ($file = fopen($this->kohana_filename, 'rb')) 295 { 296 // Display the output 297 fpassthru($file); 298 fclose($file); 299 } 300 return; 301 } 302 303 // Fetch the file contents 304 $output = file_get_contents($this->kohana_filename); 305 } 306 307 return $output; 308 } 309} // End View