PageRenderTime 24ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/h2o/loaders.php

http://github.com/speedmax/h2o-php
PHP | 290 lines | 211 code | 61 blank | 18 comment | 35 complexity | 502e1dc300688fe4365aef8f045d9385 MD5 | raw file
  1. <?php
  2. /**
  3. *
  4. * @author taylor.luk
  5. * @todo FileLoader need more test coverage
  6. */
  7. class H2o_Loader {
  8. public $parser;
  9. public $runtime;
  10. public $cached = false;
  11. protected $cache = false;
  12. public $searchpath = false;
  13. function read($filename) {}
  14. function cache_read($file, $object, $ttl = 3600) {}
  15. }
  16. class H2o_File_Loader extends H2o_Loader {
  17. function __construct($searchpath, $options = array()) {
  18. // if (is_file($searchpath)) {
  19. // $searthpath = dirname($searchpath).DS;
  20. // }
  21. // if (!is_dir($searchpath))
  22. // throw new TemplateNotFound($filename);
  23. //
  24. if (!is_array($searchpath))
  25. throw new Exception("searchpath must be an array");
  26. $this->searchpath = (array) $searchpath;
  27. $this->setOptions($options);
  28. }
  29. function setOptions($options = array()) {
  30. if (isset($options['cache']) && $options['cache']) {
  31. $this->cache = h2o_cache($options);
  32. }
  33. }
  34. function read($filename) {
  35. if (!is_file($filename))
  36. $filename = $this->get_template_path($this->searchpath,$filename);
  37. if (is_file($filename)) {
  38. $source = file_get_contents($filename);
  39. return $this->runtime->parse($source);
  40. } else {
  41. throw new TemplateNotFound($filename);
  42. }
  43. }
  44. function get_template_path($search_path, $filename){
  45. for ($i=0 ; $i < count($search_path) ; $i++)
  46. {
  47. if(file_exists($search_path[$i] . $filename)) {
  48. $filename = $search_path[$i] . $filename;
  49. return $filename;
  50. break;
  51. } else {
  52. continue;
  53. }
  54. }
  55. throw new Exception('TemplateNotFound - Looked for template: ' . $filename);
  56. }
  57. function read_cache($filename) {
  58. if (!$this->cache){
  59. $filename = $this->get_template_path($this->searchpath,$filename);
  60. return $this->read($filename);
  61. }
  62. if (!is_file($filename)){
  63. $filename = $this->get_template_path($this->searchpath,$filename);
  64. }
  65. $filename = realpath($filename);
  66. $cache = md5($filename);
  67. $object = $this->cache->read($cache);
  68. $this->cached = $object && !$this->expired($object);
  69. if (!$this->cached) {
  70. $nodelist = $this->read($filename);
  71. $object = (object) array(
  72. 'filename' => $filename,
  73. 'content' => serialize($nodelist),
  74. 'created' => time(),
  75. 'templates' => $nodelist->parser->storage['templates'],
  76. 'included' => $nodelist->parser->storage['included'] + array_values(h2o::$extensions)
  77. );
  78. $this->cache->write($cache, $object);
  79. } else {
  80. foreach($object->included as $ext => $file) {
  81. include_once (h2o::$extensions[$ext] = $file);
  82. }
  83. }
  84. return unserialize($object->content);
  85. }
  86. function flush_cache() {
  87. $this->cache->flush();
  88. }
  89. function expired($object) {
  90. if (!$object) return false;
  91. $files = array_merge(array($object->filename), $object->templates);
  92. foreach ($files as $file) {
  93. if (!is_file($file))
  94. $file = $this->get_template_path($this->searchpath, $file);
  95. if ($object->created < filemtime($file))
  96. return true;
  97. }
  98. return false;
  99. }
  100. }
  101. function file_loader($file) {
  102. return new H2o_File_Loader($file);
  103. }
  104. class H2o_Hash_Loader {
  105. function __construct($scope, $options = array()) {
  106. $this->scope = $scope;
  107. }
  108. function setOptions() {}
  109. function read($file) {
  110. if (!isset($this->scope[$file]))
  111. throw new TemplateNotFound;
  112. return $this->runtime->parse($this->scope[$file], $file);
  113. }
  114. function read_cache($file) {
  115. return $this->read($file);
  116. }
  117. }
  118. function hash_loader($hash = array()) {
  119. return new H2o_Hash_Loader($hash);
  120. }
  121. /**
  122. * Cache subsystem
  123. *
  124. */
  125. function h2o_cache($options = array()) {
  126. $type = $options['cache'];
  127. $className = "H2o_".ucwords($type)."_Cache";
  128. if (class_exists($className, false)) {
  129. return new $className($options);
  130. }
  131. return false;
  132. }
  133. class H2o_File_Cache {
  134. var $ttl = 3600;
  135. var $prefix = 'h2o_';
  136. function __construct($options = array()) {
  137. if (isset($options['cache_dir']) && is_writable($options['cache_dir'])) {
  138. $path = $options['cache_dir'];
  139. } else {
  140. $path = dirname($tmp = tempnam(uniqid(rand(), true), ''));
  141. if (file_exists($tmp)) unlink($tmp);
  142. }
  143. if (isset($options['cache_ttl'])) {
  144. $this->ttl = $options['cache_ttl'];
  145. }
  146. if(isset($options['cache_prefix'])) {
  147. $this->prefix = $options['cache_prefix'];
  148. }
  149. $this->path = realpath($path). DS;
  150. }
  151. function read($filename) {
  152. if (!file_exists($this->path . $this->prefix. $filename))
  153. return false;
  154. $content = file_get_contents($this->path . $this->prefix. $filename);
  155. $expires = (int)substr($content, 0, 10);
  156. if (time() >= $expires)
  157. return false;
  158. return unserialize(trim(substr($content, 10)));
  159. }
  160. function write($filename, &$object) {
  161. $expires = time() + $this->ttl;
  162. $content = $expires . serialize($object);
  163. return file_put_contents($this->path . $this->prefix. $filename, $content);
  164. }
  165. function flush() {
  166. foreach (glob($this->path. $this->prefix. '*') as $file) {
  167. @unlink($file);
  168. }
  169. }
  170. }
  171. class H2o_Apc_Cache {
  172. var $ttl = 3600;
  173. var $prefix = 'h2o_';
  174. function __construct($options = array()) {
  175. if (!function_exists('apc_add'))
  176. throw new Exception('APC extension needs to be loaded to use APC cache');
  177. if (isset($options['cache_ttl'])) {
  178. $this->ttl = $options['cache_ttl'];
  179. }
  180. if(isset($options['cache_prefix'])) {
  181. $this->prefix = $options['cache_prefix'];
  182. }
  183. }
  184. function read($filename) {
  185. return apc_fetch($this->prefix.$filename);
  186. }
  187. function write($filename, $object) {
  188. return apc_store($this->prefix.$filename, $object, $this->ttl);
  189. }
  190. function flush() {
  191. return apc_clear_cache('user');
  192. }
  193. }
  194. class H2o_Memcache_Cache {
  195. var $ttl = 3600;
  196. var $prefix = 'h2o_';
  197. /**
  198. * @var host default is file socket
  199. */
  200. var $host = 'unix:///tmp/memcached.sock';
  201. var $port = 0;
  202. var $object;
  203. function __construct( $scope, $options = array() ) {
  204. if ( !function_exists( 'memcache_set' ) )
  205. throw new Exception( 'Memcache extension needs to be loaded to use memcache' );
  206. if ( isset( $options['cache_ttl'] ) ) {
  207. $this->ttl = $options['cache_ttl'];
  208. }
  209. if( isset( $options['cache_prefix'] ) ) {
  210. $this->prefix = $options['cache_prefix'];
  211. }
  212. if( isset( $options['host'] ) ) {
  213. $this->host = $options['host'];
  214. }
  215. if( isset( $options['port'] ) ) {
  216. $this->port = $options['port'];
  217. }
  218. $this->object = memcache_connect( $this->host, $this->port );
  219. }
  220. function read( $filename ){
  221. return memcache_get( $this->object, $this->prefix.$filename );
  222. }
  223. function write( $filename, $content ) {
  224. return memcache_set( $this->object,$this->prefix.$filename,$content , MEMCACHE_COMPRESSED,$this->ttl );
  225. }
  226. function flush(){
  227. return memcache_flush( $this->object );
  228. }
  229. }