Posted By

freelancephp on 02/14/11


Tagged

class view MVC


Versions (?)

Lim_View - PHP View Class


 / Published in: PHP
 

URL: http://www.freelancephp.net/php-view-class/

View class that contains features like: - get vars inside the view with: 1) $var1 2) $this->var1 3) or $this->get( 'var1', 'defaultValue' ) - factory method for direct chaining: Lim_View::factory( 'test.php' )->set( 'var1', 'value1' )->show(); - set filter callbacks that will be executed right after rendering - set global vars and global filters to be available for all views

  1. <?php
  2. /**
  3.  * Lim_View Class
  4.  *
  5.  * View class that contains features like:
  6.  * - Get vars inside the view in different ways:
  7.  * 1) $var1
  8.  * 2) $this->var1
  9.  * 3) $this->getVar('var1', 'defaultValue')
  10.  * - Manage content filters with priority
  11.  * - Manage global vars and global filters, which will be available for all views
  12.  *
  13.  * @package View
  14.  * @version 2.0.0
  15.  * @author Victor Villaverde Laan
  16.  * @link http://www.freelancephp.net/lim_view-php-view-class/
  17.  * @license MIT license
  18.  */
  19. class Lim_View {
  20.  
  21. /**
  22. * Containing global vars (available for all view instances)
  23. * @var array
  24. */
  25. protected static $_globalVars = array();
  26.  
  27. /**
  28. * Containing global filter callbacks
  29. * @var array
  30. */
  31. protected static $_globalFilters = array();
  32.  
  33. /**
  34. * Always able to use the php short open tag (<?= $var ?>), even when
  35. * short_open_tag is disabled in the php configuration
  36. * @var boolean
  37. */
  38. protected static $_shortOpenTag = false;
  39.  
  40. /**
  41. * Containing view paths
  42. * @var array
  43. */
  44. protected static $_paths = array();
  45.  
  46. /**
  47. * View file path
  48. * @var string
  49. */
  50. protected $_file = null;
  51.  
  52. /**
  53. * View vars
  54. * @var array
  55. */
  56. protected $_vars = array();
  57.  
  58. /**
  59. * Containing filter callbacks
  60. * @var array
  61. */
  62. protected $_filters = array();
  63.  
  64.  
  65. /**
  66. * Constructor
  67. * @param string $file Optional, can be set later
  68. */
  69. public function __construct($file = null) {
  70. $this->setFile($file);
  71. }
  72.  
  73. /**
  74. * Set or get php short open tag support (<?= $var ?>)
  75. * @param boolean $shortOpenTag Optional
  76. * @return boolean|void Returns php short tag support or nothing
  77. */
  78. public static function shortOpenTag($shortOpenTag = null) {
  79. if ($shortOpenTag === null)
  80. return self::$_shortOpenTag;
  81.  
  82. self::$_shortOpenTag = $shortOpenTag;
  83. }
  84.  
  85. /**
  86. * Add view path
  87. * @param string|array $path
  88. */
  89. public static function addPath($path) {
  90. if (is_array($path)) {
  91. foreach ($path as $val)
  92. self::$_paths[$val] = $val;
  93. } else {
  94. self::$_paths[$path] = $path;
  95. }
  96. }
  97.  
  98. /**
  99. * Remove view path
  100. * @param string $path
  101. */
  102. public static function removePath($path) {
  103. unset(self::$_paths[$path]);
  104. }
  105.  
  106. /**
  107. * Get array of all paths
  108. * @return array
  109. */
  110. public static function getPaths() {
  111. return self::$_paths;
  112. }
  113.  
  114. /**
  115. * Remove all view paths
  116. */
  117. public static function clearPaths() {
  118. foreach (self::$_paths as $path)
  119. self::removePath($path);
  120. }
  121.  
  122. /**
  123. * Set the view file
  124. * @param string $file
  125. * @return $this
  126. */
  127. public function setFile($file) {
  128. $this->_file = $file;
  129. return $this;
  130. }
  131.  
  132. /**
  133. * Get the view file
  134. * @return string
  135. */
  136. public function getFile() {
  137. return $this->_file;
  138. }
  139.  
  140. /**
  141. * Check if view file exists
  142. * @param string $file Check if given view file exists
  143. * @return boolean
  144. */
  145. public static function exists($file) {
  146. // check if file exists
  147. if (self::_fileExists($file))
  148. return true;
  149.  
  150. // check if file can be found in the paths
  151. foreach (self::$_paths as $path) {
  152. if (self::_fileExists($path . $file))
  153. return true;
  154. }
  155.  
  156. return false;
  157. }
  158.  
  159. /**
  160. * Set (local) var
  161. * @param string|array $key Can also give array of values, f.e. array('var1' => 'value1', 'var2' => 'value2')
  162. * @param mixed $value Optional, default null
  163. * @return $this
  164. */
  165. public function setVar($key, $value = null) {
  166. $keys = (is_array($key)) ? $key : array($key => $value);
  167.  
  168. foreach ($keys as $k => $v)
  169. $this->_vars[$k] = $v;
  170.  
  171. return $this;
  172. }
  173.  
  174. /**
  175. * Set var
  176. * @param string $key
  177. * @param mixed $value
  178. */
  179. public function __set($key, $value) {
  180. $this->setVar($key, $value);
  181. }
  182.  
  183. /**
  184. * Get a var value (if not exists it will look for a global var with the given key)
  185. * @param string $key
  186. * @param mixed $defaultValue Optional, return default when key was not found
  187. * @param boolean $includeGlobalVars Optional, default true
  188. * @return mixed
  189. */
  190. public function getVar($key, $defaultValue = null, $includeGlobalVars = true) {
  191. if (array_key_exists($key, $this->_vars))
  192. return $this->_vars[$key];
  193.  
  194. if ($includeGlobalVars) {
  195. if (array_key_exists($key, self::$_globalVars))
  196. return self::$_globalVars[$key];
  197. }
  198.  
  199. return $defaultValue;
  200. }
  201.  
  202. /**
  203. * Get var value, also checks global vars
  204. * @param string $key
  205. * @return mixed
  206. */
  207. public function __get($key) {
  208. if (!$this->hasVar($key))
  209. $this->_throwException('Key "' . $key . '" was not set.');
  210.  
  211. return $this->getVar($key);
  212. }
  213.  
  214. /**
  215. * Unset given (local) var
  216. * @param string|array $key Can also give array of keys to unset
  217. * @return $this
  218. */
  219. public function unsetVar($key) {
  220. $keys = (is_array($key)) ? $key : array(0 => $key);
  221.  
  222. foreach ($keys as $i => $k) {
  223. if (array_key_exists($k, $this->_vars))
  224. unset($this->_vars[$k]);
  225. }
  226.  
  227. return $this;
  228. }
  229.  
  230. /**
  231. * Unset (local) var
  232. * @param string $key
  233. */
  234. public function __unset($key) {
  235. $this->unsetVar($key);
  236. }
  237.  
  238. /**
  239. * Check if given var exists
  240. * @param string $key
  241. * @param boolean $includeGlobalVars Optional, default true
  242. * @return boolean
  243. */
  244. public function hasVar($key, $includeGlobalVars = true) {
  245. return (array_key_exists($key, $this->_vars) || ($includeGlobalVars && array_key_exists($key, self::$_globalVars)));
  246. }
  247.  
  248. /**
  249. * Get all view vars
  250. * @return array
  251. */
  252. public function getVars($includeGlobalVars = true) {
  253. return ($includeGlobalVars) ? array_merge(self::$_globalVars, $this->_vars) : $this->_vars;
  254. }
  255.  
  256. /**
  257. * Unset all (local) vars
  258. * @param string $key
  259. * @return $this
  260. */
  261. public function clearVars() {
  262. foreach ($this->_vars as $key => $val)
  263. $this->unsetVar($key);
  264.  
  265. return $this;
  266. }
  267.  
  268. /**
  269. * Set a global var (available for all views)
  270. * @param string|array $key Can also give array of values, f.e. array('var1' => 'value1', 'var2' => 'value2')
  271. * @param mixed $value Optional, default null
  272. */
  273. public static function setGlobalVar($key, $value = null) {
  274. $keys = (is_array($key)) ? $key : array($key => $value);
  275.  
  276. foreach ($keys as $k => $v)
  277. self::$_globalVars[$k] = $v;
  278. }
  279.  
  280. /**
  281. * Set a global var (available for all views)
  282. * @param string $key
  283. * @param mixed $defaultValue Optional, return default when key was not found
  284. */
  285. public static function getGlobalVar($key, $defaultValue = null) {
  286. if (array_key_exists($key, self::$_globalVars))
  287. return self::$_globalVars[$key];
  288.  
  289. return $defaultValue;
  290. }
  291.  
  292. /**
  293. * Unset global var
  294. * @param string|array $key Can also give array of keys to unset
  295. */
  296. public static function unsetGlobalVar($key) {
  297. $keys = (is_array($key)) ? $key : array(0 => $key);
  298.  
  299. foreach ($keys as $i => $k) {
  300. if (array_key_exists($k, self::$_globalVars))
  301. unset(self::$_globalVars[$k]);
  302. }
  303. }
  304.  
  305. /**
  306. * Check if global var exists
  307. * @param string $key
  308. * @return boolean
  309. */
  310. public static function hasGlobalVar($key) {
  311. return array_key_exists($key, self::$_globalVars);
  312. }
  313.  
  314. /**
  315. * Get array of all global vars
  316. * @return array
  317. */
  318. public static function getGlobalVars() {
  319. return self::$_globalVars;
  320. }
  321.  
  322. /**
  323. * Unset all global vars
  324. */
  325. public static function clearGlobalVars() {
  326. foreach (self::$_globalVars as $key => $val)
  327. self::unsetGlobalVar($key);
  328. }
  329.  
  330. /**
  331. * Set filter callback. 2 parameters will be passed on to the callback function:
  332. * (1) $content: rendered content
  333. * (2) $view: this view object
  334. * @param mixed $callback
  335. * @param string $key Optional
  336. * @param integer $priority Optional, default 10
  337. * @return $this
  338. */
  339. public function addFilter($callback, $key = null, $priority = 10) {
  340. $cb = array('callback' => $callback, 'priority' => $priority);
  341.  
  342. if ($key === null) {
  343. $this->_filters[] = $cb;
  344. } else {
  345. $this->_filters[$key] = $cb;
  346. }
  347.  
  348. return $this;
  349. }
  350.  
  351. /**
  352. * Remove filter
  353. * @param string $key
  354. * @return $this
  355. */
  356. public function removeFilter($key) {
  357. if (array_key_exists($key, $this->_filters))
  358. unset($this->_filters[$key]);
  359.  
  360. return $this;
  361. }
  362.  
  363. /**
  364. * Check if filter exists
  365. * @param string $key
  366. * @param boolean $includeGlobalFilters Optional, default true
  367. * @return boolean
  368. */
  369. public function hasFilter($key, $includeGlobalFilters = true) {
  370. return (array_key_exists($key, $this->_filters) || ($includeGlobalFilters && array_key_exists($key, self::$_globalFilters)));
  371. }
  372.  
  373. /**
  374. * Get filter
  375. * @param boolean $includeGlobalFilters Optional, default true
  376. * @param boolean $prioritizedOrder
  377. * @return array
  378. */
  379. public function getFilters($includeGlobalFilters = true, $prioritizedOrder = false) {
  380. $filters = ($includeGlobalFilters) ? array_merge(self::$_globalFilters, $this->_filters) : $this->_filters;
  381. return ($prioritizedOrder) ? self::_getPrioritizedFilters($filters) : $filters;
  382. }
  383.  
  384. /**
  385. * Remove all filters
  386. * @return $this
  387. */
  388. public function clearFilters() {
  389. foreach ($this->_filters as $key => $val)
  390. $this->removeFilter($key);
  391.  
  392. // reset indexes
  393. $this->_filters = array();
  394.  
  395. return $this;
  396. }
  397.  
  398. /**
  399. * Set global filter (used for all views). 2 parameters will be passed on to the callback function:
  400. * (1) $content: rendered content
  401. * (2) $view: this view object
  402. * @param mixed $callback
  403. * @param string $key Optional
  404. * @param integer $priority Optional, default 10
  405. */
  406. public static function addGlobalFilter($callback, $key = null, $priority = 10) {
  407. $cb = array('callback' => $callback, 'priority' => $priority);
  408.  
  409. // add global filter as a callback function
  410. if ($key === null) {
  411. self::$_globalFilters[] = $cb;
  412. } else {
  413. self::$_globalFilters[$key] = $cb;
  414. }
  415. }
  416.  
  417. /**
  418. * Remove filter
  419. * @param string $key
  420. */
  421. public static function removeGlobalFilter($key) {
  422. if (array_key_exists($key, self::$_globalFilters))
  423. unset(self::$_globalFilters[$key]);
  424. }
  425.  
  426. /**
  427. * Check if filter exists
  428. * @param string $key
  429. * @return boolean
  430. */
  431. public static function hasGlobalFilter($key) {
  432. return array_key_exists($key, self::$_globalFilters);
  433. }
  434.  
  435. /**
  436. * Get filter
  437. * @param boolean $prioritizedOrder
  438. * @return array
  439. */
  440. public static function getGlobalFilters($prioritizedOrder = false) {
  441. return ($prioritizedOrder) ? self::_getPrioritizedFilters(self::$_globalFilters) : self::$_globalFilters;
  442. }
  443.  
  444. /**
  445. * Remove all global filters
  446. */
  447. public static function clearGlobalFilters() {
  448. foreach (self::$_globalFilters as $key => $val)
  449. self::removeGlobalFilter($key);
  450.  
  451. // reset indexes
  452. self::$_globalFilters = array();
  453. }
  454.  
  455. /**
  456. * Render the view content
  457. * @param boolean $echo Optional, default false
  458. * @param boolean $applyGlobalFilters Optional, default true
  459. * @return string
  460. * @throw Exception
  461. */
  462. public function render($echo = false, $applyGlobalFilters = true) {
  463. // check if view file exists
  464. $file = null;
  465.  
  466. if (self::_fileExists($this->_file)) {
  467. $file = $this->_file;
  468. } else {
  469. foreach (self::$_paths as $path) {
  470. if (self::_fileExists($path . $this->_file))
  471. $file = $path . $this->_file;
  472. }
  473. if ($file === null) {
  474. $this->_throwException('The file "' . $this->_file . '" could not be fetched.');
  475. return $this;
  476. }
  477. }
  478.  
  479. // get global and local vars
  480. $vars = $this->getVars(true);
  481.  
  482. // extract vars to global namespace
  483. extract($vars, EXTR_SKIP);
  484.  
  485. // start output buffer
  486.  
  487. // replace short php tags to normal (in case the server doesn't support it)
  488. if (self::$_shortOpenTag) {
  489. echo eval('?>' . str_replace('<?=', '<?php echo ', file_get_contents($file)));
  490. } else {
  491. include($file);
  492. }
  493.  
  494. // get the view content
  495. $content = ob_get_contents();
  496.  
  497. // clean output buffer
  498. ob_end_clean();
  499.  
  500. // set filters
  501. $filters = $this->getFilters($applyGlobalFilters, true);
  502.  
  503. // call filters
  504. foreach ($filters as $key => $value) {
  505. if (is_callable($value['callback']))
  506. $content = call_user_func($value['callback'], $content, $this);
  507. }
  508.  
  509. // print content
  510. if ($echo)
  511. echo $content;
  512.  
  513. return $content;
  514. }
  515.  
  516. /**
  517. * Show rendered view content
  518. * @param boolean $applyGlobalFilters Optional, default true
  519. * @return $this
  520. */
  521. public function show($applyGlobalFilters = true) {
  522. $this->render(true, $applyGlobalFilters);
  523. return $this;
  524. }
  525.  
  526. /**
  527. * Renders the view
  528. * @return string
  529. */
  530. public function __toString() {
  531. return $this->render(false);
  532. }
  533.  
  534. /**
  535. * Throw exception
  536. * @param string $msg
  537. * @throw Exception
  538. */
  539. protected function _throwException($msg) {
  540. throw new Exception(get_class($this) . ' - ' . $msg);
  541. }
  542.  
  543. /**
  544. * File exists
  545. * @param string $file
  546. * @return boolean
  547. */
  548. protected static function _fileExists($file) {
  549. return (file_exists($file) && is_file($file));
  550. }
  551.  
  552. /**
  553. * Get filters in priority order
  554. * @param array $filters
  555. * @return array
  556. */
  557. protected static function _getPrioritizedFilters($filters) {
  558. uasort($filters, array('Lim_View', '_sortPriority'));
  559. return $filters;
  560. }
  561.  
  562. /**
  563. * Sort by priority (callback)
  564. * @param array $a
  565. * @param array $b
  566. * @return integer
  567. */
  568. protected static function _sortPriority($a, $b) {
  569. if ($a['priority'] == $b['priority'])
  570. return 0;
  571.  
  572. return ($a['priority'] > $b['priority']) ? -1 : 1;
  573. }
  574.  
  575. } // Lim_View Class

Report this snippet  

You need to login to post a comment.