PageRenderTime 38ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/kohana/haml.php

http://github.com/fredwu/kohana-phamlp
PHP | 233 lines | 120 code | 27 blank | 86 comment | 9 complexity | ce9bb714c92fb93c7475ad34061d5e6c MD5 | raw file
  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * Kohana Haml bridge for PHamlP
  4. *
  5. * @package PHamlP
  6. * @subpackage Haml
  7. * @author Fred Wu <fred@wuit.com>
  8. * @copyright Wuit.com <http://wuit.com/>
  9. * @license http://www.opensource.org/licenses/mit-license.php
  10. */
  11. class Kohana_Haml extends View {
  12. /**
  13. * @var array Kohana::config('phamlp')
  14. */
  15. protected static $config;
  16. protected $data;
  17. protected $options;
  18. /**
  19. * Prepares Haml view
  20. *
  21. * @see View::__construct()
  22. * @param string view filename
  23. * @param array array of values
  24. * @param array options
  25. * @return View
  26. */
  27. public function __construct($file = NULL, array $data = NULL, array $options = array())
  28. {
  29. self::$config = self::$config ?: Kohana::$config->load('phamlp');
  30. $this->data = $data;
  31. $this->options = $options;
  32. $this->compile_haml($file);
  33. return parent::__construct($file, $this->data);
  34. }
  35. /**
  36. * Returns a new View object
  37. *
  38. * @see View::factory()
  39. * @param string view filename
  40. * @param array array of values
  41. * @param array options
  42. * @return View
  43. */
  44. public static function factory($file = NULL, array $data = NULL, array $options = array())
  45. {
  46. return new Haml($file, $data, $options);
  47. }
  48. /**
  49. * Sets a global variable, similar to [View::set], except that the
  50. * variable will be accessible to all views.
  51. *
  52. * @see View::set_global()
  53. * @param string variable name or an array of variables
  54. * @param mixed value
  55. * @return void
  56. */
  57. public static function set_global($key, $value = NULL)
  58. {
  59. View::set_global($key, $value);
  60. }
  61. /**
  62. * Assigns a global variable by reference, similar to [View::bind], except
  63. * that the variable will be accessible to all views.
  64. *
  65. * @see View::set_global()
  66. * @param string variable name
  67. * @param mixed referenced variable
  68. * @return void
  69. */
  70. public static function bind_global($key, & $value)
  71. {
  72. View::bind_global($key, $value);
  73. }
  74. private static function haml_ext()
  75. {
  76. return self::$config['haml']['extension'];
  77. }
  78. /**
  79. * Compiles the HAML template from the given HTML/PHP template
  80. *
  81. * @param string view filename
  82. * @param array array of values
  83. * @param array options
  84. * @return string path of the compiled HAML file
  85. */
  86. private function compile_haml($file)
  87. {
  88. $cache_dir = self::$config['haml']['cache_dir'].'/';
  89. $cache_root = APPPATH.'cache/'.self::$config['haml']['cache_dir'].'/';
  90. $cache_dir_real = $cache_root.dirname($file);
  91. $cached_file = $cache_root.$file.EXT;
  92. self::create_dir_unless_exists($cache_root);
  93. self::make_dir_writable($cache_root);
  94. // in development mode, let's reload the template on each request
  95. if (Kohana::$environment === Kohana::DEVELOPMENT)
  96. {
  97. self::remove_haml_file($cached_file);
  98. }
  99. if ( ! is_file($cached_file))
  100. {
  101. self::create_dir_unless_exists($cache_root . dirname($file));
  102. $options = array_merge(self::$config['haml']['options'], $this->options);
  103. $haml = new HamlParser($options);
  104. $haml->parse(
  105. Kohana::find_file('views', $file, self::haml_ext()),
  106. $cache_dir_real
  107. );
  108. }
  109. return $file;
  110. }
  111. /**
  112. * Kohana 3.1 uses very "silly" extension checking
  113. * We're overloading set_filename to seek our view in cache
  114. *
  115. * @param string $dir path of the directory
  116. * @return void
  117. */
  118. public function set_filename($file, $validate_file_change = true)
  119. {
  120. // Detect if there was a file extension
  121. $_file = explode('.', $file);
  122. // If there are several components
  123. if (count($_file) > 1)
  124. {
  125. // Take the extension
  126. $ext = array_pop($_file);
  127. $file = implode('.', $_file);
  128. }
  129. // Otherwise set the extension to the standard
  130. else
  131. {
  132. $ext = ltrim(EXT, '.');
  133. }
  134. $base_name = self::$config['haml']['cache_dir'].'/'.$file;
  135. $path = self::find_file('cache', $base_name, $ext);
  136. // izhevsky: added 2 fixes:
  137. // path exists, but cached file has to be recompiled, because source .haml was changed
  138. // path not exists, because previous view didn't exist, but now we set up right name
  139. $real_file = self::find_file('views', $file, self::haml_ext());
  140. if ($path === FALSE)
  141. {
  142. if (file_exists($real_file))
  143. {
  144. // file exists, recompile
  145. self::compile_haml($file);
  146. $this->set_filename($file, false);
  147. return;
  148. }
  149. throw new Kohana_View_Exception(
  150. 'The requested view :file could not be found',
  151. array(':file' => $file.($ext ? '.haml' : ''))
  152. );
  153. }
  154. elseif (Kohana::$environment === Kohana::DEVELOPMENT &&
  155. $validate_file_change &&
  156. filemtime($real_file) >= filemtime($path)
  157. )
  158. {
  159. self::compile_haml($file);
  160. $this->set_filename($file, false);
  161. return;
  162. }
  163. // Store the file path locally
  164. $this->_file = $path;
  165. return $this;
  166. }
  167. /**
  168. * Checks and makes the directory writable
  169. *
  170. * @param string $dir path of the directory
  171. * @return void
  172. */
  173. protected static function make_dir_writable($dir)
  174. {
  175. if ( ! is_writable($dir))
  176. {
  177. chmod($dir, 0777);
  178. }
  179. }
  180. /**
  181. * Creates the directory unless it already exists
  182. *
  183. * @param string $dir path of the directory
  184. * @return void
  185. */
  186. protected static function create_dir_unless_exists($dir)
  187. {
  188. if ( ! is_dir($dir))
  189. {
  190. mkdir($dir, 0777, TRUE);
  191. }
  192. }
  193. protected static function remove_haml_file($file)
  194. {
  195. @unlink($file);
  196. }
  197. // platform-independent wrapper around Kohana::find_file
  198. protected static function find_file($dir, $file, $ext)
  199. {
  200. if(substr(Kohana::VERSION, 0, 3) == '3.0')
  201. {
  202. return Kohana::find_file($dir, $file);
  203. }
  204. return Kohana::find_file($dir, $file, $ext);
  205. }
  206. }