PageRenderTime 32ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/timber-library/lib/Loader.php

https://bitbucket.org/francesca_anni/blog-concept-sesta
PHP | 342 lines | 229 code | 50 blank | 63 comment | 47 complexity | 9ec05be72c747ad43ba70c067f192ddd MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. namespace Timber;
  3. use Timber\Cache\Cleaner;
  4. class Loader {
  5. const CACHEGROUP = 'timberloader';
  6. const TRANS_KEY_LEN = 50;
  7. const CACHE_NONE = 'none';
  8. const CACHE_OBJECT = 'cache';
  9. const CACHE_TRANSIENT = 'transient';
  10. const CACHE_SITE_TRANSIENT = 'site-transient';
  11. const CACHE_USE_DEFAULT = 'default';
  12. public static $cache_modes = array(
  13. self::CACHE_NONE,
  14. self::CACHE_OBJECT,
  15. self::CACHE_TRANSIENT,
  16. self::CACHE_SITE_TRANSIENT
  17. );
  18. protected $cache_mode = self::CACHE_TRANSIENT;
  19. protected $locations;
  20. /**
  21. * @param bool|string $caller the calling directory or false
  22. */
  23. public function __construct( $caller = false ) {
  24. $this->locations = LocationManager::get_locations($caller);
  25. $this->cache_mode = apply_filters('timber_cache_mode', $this->cache_mode);
  26. $this->cache_mode = apply_filters('timber/cache/mode', $this->cache_mode);
  27. }
  28. /**
  29. * @param string $file
  30. * @param array $data
  31. * @param array|boolean $expires (array for options, false for none, integer for # of seconds)
  32. * @param string $cache_mode
  33. * @return bool|string
  34. */
  35. public function render( $file, $data = null, $expires = false, $cache_mode = self::CACHE_USE_DEFAULT ) {
  36. // Different $expires if user is anonymous or logged in
  37. if ( is_array($expires) ) {
  38. /** @var array $expires */
  39. if ( is_user_logged_in() && isset($expires[1]) ) {
  40. $expires = $expires[1];
  41. } else {
  42. $expires = $expires[0];
  43. }
  44. }
  45. $key = null;
  46. $output = false;
  47. if ( false !== $expires ) {
  48. ksort($data);
  49. $key = md5($file.json_encode($data));
  50. $output = $this->get_cache($key, self::CACHEGROUP, $cache_mode);
  51. }
  52. if ( false === $output || null === $output ) {
  53. $twig = $this->get_twig();
  54. if ( strlen($file) ) {
  55. $loader = $this->get_loader();
  56. $result = $loader->getCacheKey($file);
  57. do_action('timber_loader_render_file', $result);
  58. }
  59. $data = apply_filters('timber_loader_render_data', $data);
  60. $data = apply_filters('timber/loader/render_data', $data, $file);
  61. $output = $twig->render($file, $data);
  62. }
  63. if ( false !== $output && false !== $expires && null !== $key ) {
  64. $this->delete_cache();
  65. $this->set_cache($key, $output, self::CACHEGROUP, $expires, $cache_mode);
  66. }
  67. $output = apply_filters('timber_output', $output);
  68. return apply_filters('timber/output', $output, $data, $file);
  69. }
  70. protected function delete_cache() {
  71. Cleaner::delete_transients();
  72. }
  73. /**
  74. * Get first existing template.
  75. *
  76. * @param array|string $templates Name(s) of the Twig template(s) to choose from.
  77. * @return string|bool Name of chosen template, otherwise false.
  78. */
  79. public function choose_template( $templates ) {
  80. // Change $templates into array, if needed
  81. if ( !is_array($templates) ) {
  82. $templates = (array) $templates;
  83. }
  84. // Get Twig loader
  85. $loader = $this->get_loader();
  86. // Run through template array
  87. foreach ( $templates as $template ) {
  88. // Use the Twig loader to test for existance
  89. if ( $loader->exists($template) ) {
  90. // Return name of existing template
  91. return $template;
  92. }
  93. }
  94. // No existing template was found
  95. return false;
  96. }
  97. /**
  98. * @param string $name
  99. * @return bool
  100. * @deprecated 1.3.5 No longer used internally
  101. * @todo remove in 2.x
  102. * @codeCoverageIgnore
  103. */
  104. protected function template_exists( $name ) {
  105. return $this->get_loader()->exists($name);
  106. }
  107. /**
  108. * @return \Twig_Loader_Filesystem
  109. */
  110. public function get_loader() {
  111. $open_basedir = ini_get('open_basedir');
  112. $paths = array_merge($this->locations, array($open_basedir ? ABSPATH : '/'));
  113. $paths = apply_filters('timber/loader/paths', $paths);
  114. $rootPath = '/';
  115. if ( $open_basedir ) {
  116. $rootPath = null;
  117. }
  118. $fs = new \Twig_Loader_Filesystem($paths, $rootPath);
  119. $fs = apply_filters('timber/loader/loader', $fs);
  120. return $fs;
  121. }
  122. /**
  123. * @return \Twig_Environment
  124. */
  125. public function get_twig() {
  126. $loader = $this->get_loader();
  127. $params = array('debug' => WP_DEBUG, 'autoescape' => false);
  128. if ( isset(Timber::$autoescape) ) {
  129. $params['autoescape'] = Timber::$autoescape === true ? 'html' : Timber::$autoescape;
  130. }
  131. if ( Timber::$cache === true ) {
  132. Timber::$twig_cache = true;
  133. }
  134. if ( Timber::$twig_cache ) {
  135. $twig_cache_loc = apply_filters('timber/cache/location', TIMBER_LOC.'/cache/twig');
  136. if ( !file_exists($twig_cache_loc) ) {
  137. mkdir($twig_cache_loc, 0777, true);
  138. }
  139. $params['cache'] = $twig_cache_loc;
  140. }
  141. $twig = new \Twig_Environment($loader, $params);
  142. if ( WP_DEBUG ) {
  143. $twig->addExtension(new \Twig_Extension_Debug());
  144. }
  145. $twig->addExtension($this->_get_cache_extension());
  146. $twig = apply_filters('twig_apply_filters', $twig);
  147. $twig = apply_filters('timber/twig/filters', $twig);
  148. $twig = apply_filters('timber/twig/functions', $twig);
  149. $twig = apply_filters('timber/twig/escapers', $twig);
  150. $twig = apply_filters('timber/loader/twig', $twig);
  151. return $twig;
  152. }
  153. public function clear_cache_timber( $cache_mode = self::CACHE_USE_DEFAULT ) {
  154. //_transient_timberloader
  155. $object_cache = false;
  156. if ( isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache']) ) {
  157. $object_cache = true;
  158. }
  159. $cache_mode = $this->_get_cache_mode($cache_mode);
  160. if ( self::CACHE_TRANSIENT === $cache_mode || self::CACHE_SITE_TRANSIENT === $cache_mode ) {
  161. return self::clear_cache_timber_database();
  162. } else if ( self::CACHE_OBJECT === $cache_mode && $object_cache ) {
  163. return self::clear_cache_timber_object();
  164. }
  165. return false;
  166. }
  167. protected static function clear_cache_timber_database() {
  168. global $wpdb;
  169. $query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE '%s'", '_transient_timberloader_%');
  170. return $wpdb->query($query);
  171. }
  172. protected static function clear_cache_timber_object() {
  173. global $wp_object_cache;
  174. if ( isset($wp_object_cache->cache[self::CACHEGROUP]) ) {
  175. $items = $wp_object_cache->cache[self::CACHEGROUP];
  176. foreach ( $items as $key => $value ) {
  177. if ( is_multisite() ) {
  178. $key = preg_replace('/^(.*?):/', '', $key);
  179. }
  180. wp_cache_delete($key, self::CACHEGROUP);
  181. }
  182. return true;
  183. }
  184. }
  185. public function clear_cache_twig() {
  186. $twig = $this->get_twig();
  187. if ( method_exists($twig, 'clearCacheFiles') ) {
  188. $twig->clearCacheFiles();
  189. }
  190. $cache = $twig->getCache();
  191. if ( $cache ) {
  192. self::rrmdir($twig->getCache());
  193. return true;
  194. }
  195. return false;
  196. }
  197. /**
  198. * @param string|false $dirPath
  199. */
  200. public static function rrmdir( $dirPath ) {
  201. if ( !is_dir($dirPath) ) {
  202. throw new \InvalidArgumentException("$dirPath must be a directory");
  203. }
  204. if ( substr($dirPath, strlen($dirPath) - 1, 1) != '/' ) {
  205. $dirPath .= '/';
  206. }
  207. $files = glob($dirPath.'*', GLOB_MARK);
  208. foreach ( $files as $file ) {
  209. if ( is_dir($file) ) {
  210. self::rrmdir($file);
  211. } else {
  212. unlink($file);
  213. }
  214. }
  215. rmdir($dirPath);
  216. }
  217. /**
  218. * @return \Asm89\Twig\CacheExtension\Extension
  219. */
  220. private function _get_cache_extension() {
  221. $key_generator = new \Timber\Cache\KeyGenerator();
  222. $cache_provider = new \Timber\Cache\WPObjectCacheAdapter($this);
  223. $cache_lifetime = apply_filters('timber/cache/extension/lifetime', 0);
  224. $cache_strategy = new \Asm89\Twig\CacheExtension\CacheStrategy\GenerationalCacheStrategy($cache_provider, $key_generator, $cache_lifetime);
  225. $cache_extension = new \Asm89\Twig\CacheExtension\Extension($cache_strategy);
  226. return $cache_extension;
  227. }
  228. /**
  229. * @param string $key
  230. * @param string $group
  231. * @param string $cache_mode
  232. * @return bool
  233. */
  234. public function get_cache( $key, $group = self::CACHEGROUP, $cache_mode = self::CACHE_USE_DEFAULT ) {
  235. $object_cache = false;
  236. if ( isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache']) ) {
  237. $object_cache = true;
  238. }
  239. $cache_mode = $this->_get_cache_mode($cache_mode);
  240. $value = false;
  241. $trans_key = substr($group.'_'.$key, 0, self::TRANS_KEY_LEN);
  242. if ( self::CACHE_TRANSIENT === $cache_mode ) {
  243. $value = get_transient($trans_key);
  244. } elseif ( self::CACHE_SITE_TRANSIENT === $cache_mode ) {
  245. $value = get_site_transient($trans_key);
  246. } elseif ( self::CACHE_OBJECT === $cache_mode && $object_cache ) {
  247. $value = wp_cache_get($key, $group);
  248. }
  249. return $value;
  250. }
  251. /**
  252. * @param string $key
  253. * @param string|boolean $value
  254. * @param string $group
  255. * @param integer $expires
  256. * @param string $cache_mode
  257. * @return string|boolean
  258. */
  259. public function set_cache( $key, $value, $group = self::CACHEGROUP, $expires = 0, $cache_mode = self::CACHE_USE_DEFAULT ) {
  260. $object_cache = false;
  261. if ( isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache']) ) {
  262. $object_cache = true;
  263. }
  264. if ( (int) $expires < 1 ) {
  265. $expires = 0;
  266. }
  267. $cache_mode = self::_get_cache_mode($cache_mode);
  268. $trans_key = substr($group.'_'.$key, 0, self::TRANS_KEY_LEN);
  269. if ( self::CACHE_TRANSIENT === $cache_mode ) {
  270. set_transient($trans_key, $value, $expires);
  271. } elseif ( self::CACHE_SITE_TRANSIENT === $cache_mode ) {
  272. set_site_transient($trans_key, $value, $expires);
  273. } elseif ( self::CACHE_OBJECT === $cache_mode && $object_cache ) {
  274. wp_cache_set($key, $value, $group, $expires);
  275. }
  276. return $value;
  277. }
  278. /**
  279. * @param string $cache_mode
  280. * @return string
  281. */
  282. private function _get_cache_mode( $cache_mode ) {
  283. if ( empty($cache_mode) || self::CACHE_USE_DEFAULT === $cache_mode ) {
  284. $cache_mode = $this->cache_mode;
  285. }
  286. // Fallback if self::$cache_mode did not get a valid value
  287. if ( !in_array($cache_mode, self::$cache_modes) ) {
  288. $cache_mode = self::CACHE_OBJECT;
  289. }
  290. return $cache_mode;
  291. }
  292. }