PageRenderTime 47ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/dev/cache/backend/file.c

http://github.com/phalcon/cphalcon
C | 420 lines | 287 code | 76 blank | 57 comment | 40 complexity | cd9143b9e29bb0f1cdd716a7d9dd1469 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*
  2. +------------------------------------------------------------------------+
  3. | Phalcon Framework |
  4. +------------------------------------------------------------------------+
  5. | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
  6. +------------------------------------------------------------------------+
  7. | This source file is subject to the New BSD License that is bundled |
  8. | with this package in the file docs/LICENSE.txt. |
  9. | |
  10. | If you did not receive a copy of the license and are unable to |
  11. | obtain it through the world-wide-web, please send an email |
  12. | to license@phalconphp.com so we can send you a copy immediately. |
  13. +------------------------------------------------------------------------+
  14. | Authors: Andres Gutierrez <andres@phalconphp.com> |
  15. | Eduar Carvajal <eduar@phalconphp.com> |
  16. +------------------------------------------------------------------------+
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include "config.h"
  20. #endif
  21. #include "php.h"
  22. #include "php_phalcon.h"
  23. #include "phalcon.h"
  24. #include "Zend/zend_operators.h"
  25. #include "Zend/zend_exceptions.h"
  26. #include "Zend/zend_interfaces.h"
  27. #include "kernel/main.h"
  28. #include "kernel/memory.h"
  29. #include "kernel/array.h"
  30. #include "kernel/fcall.h"
  31. #include "kernel/object.h"
  32. #include "kernel/concat.h"
  33. /**
  34. * Phalcon_Cache_Backend_File
  35. *
  36. * Allows to cache output fragments using a file backend
  37. *
  38. *
  39. */
  40. /**
  41. * Phalcon_Backend_Adapter_File constructor
  42. *
  43. * @param mixed $frontendObject
  44. * @param array $backendOptions
  45. */
  46. PHP_METHOD(Phalcon_Cache_Backend_File, __construct){
  47. zval *frontend_object = NULL, *backend_options = NULL;
  48. zval *r0 = NULL, *r1 = NULL;
  49. int eval_int;
  50. PHALCON_MM_GROW();
  51. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &frontend_object, &backend_options) == FAILURE) {
  52. PHALCON_MM_RESTORE();
  53. RETURN_NULL();
  54. }
  55. eval_int = phalcon_array_isset_string(backend_options, SL("cacheDir")+1);
  56. if (eval_int) {
  57. PHALCON_ALLOC_ZVAL_MM(r0);
  58. phalcon_array_fetch_string(&r0, backend_options, SL("cacheDir"), PHALCON_NOISY TSRMLS_CC);
  59. PHALCON_ALLOC_ZVAL_MM(r1);
  60. PHALCON_CALL_FUNC_PARAMS_1(r1, "is_writable", r0);
  61. if (!zend_is_true(r1)) {
  62. PHALCON_THROW_EXCEPTION_STR(phalcon_cache_exception_ce, "The cache directory does not exist or is not writable");
  63. return;
  64. }
  65. } else {
  66. PHALCON_THROW_EXCEPTION_STR(phalcon_cache_exception_ce, "You must specify the cache directory with the option cacheDir");
  67. return;
  68. }
  69. PHALCON_CALL_PARENT_PARAMS_2_NORETURN(this_ptr, "Phalcon_Cache_Backend_File", "__construct", frontend_object, backend_options);
  70. PHALCON_MM_RESTORE();
  71. }
  72. /**
  73. * Returns a cached content
  74. *
  75. * @param int|string $keyName
  76. * @param long $lifetime
  77. * @return mixed
  78. */
  79. PHP_METHOD(Phalcon_Cache_Backend_File, get){
  80. zval *key_name = NULL, *lifetime = NULL, *backend = NULL, *front_end = NULL;
  81. zval *prefixed_key = NULL, *cache_file = NULL, *time = NULL, *ttl = NULL, *cached_content = NULL;
  82. zval *t0 = NULL, *t1 = NULL, *t2 = NULL;
  83. zval *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *r4 = NULL, *r5 = NULL, *r6 = NULL;
  84. zval *r7 = NULL, *r8 = NULL;
  85. PHALCON_MM_GROW();
  86. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &key_name, &lifetime) == FAILURE) {
  87. PHALCON_MM_RESTORE();
  88. RETURN_NULL();
  89. }
  90. if (!lifetime) {
  91. PHALCON_INIT_VAR(lifetime);
  92. ZVAL_NULL(lifetime);
  93. }
  94. PHALCON_ALLOC_ZVAL_MM(t0);
  95. phalcon_read_property(&t0, this_ptr, SL("_backendOptions"), PHALCON_NOISY TSRMLS_CC);
  96. PHALCON_CPY_WRT(backend, t0);
  97. PHALCON_ALLOC_ZVAL_MM(t1);
  98. phalcon_read_property(&t1, this_ptr, SL("_frontendObject"), PHALCON_NOISY TSRMLS_CC);
  99. PHALCON_CPY_WRT(front_end, t1);
  100. PHALCON_ALLOC_ZVAL_MM(r0);
  101. PHALCON_ALLOC_ZVAL_MM(t2);
  102. phalcon_read_property(&t2, this_ptr, SL("prefix"), PHALCON_NOISY TSRMLS_CC);
  103. PHALCON_ALLOC_ZVAL_MM(r1);
  104. phalcon_filter_alphanum(r1, key_name);
  105. PHALCON_CONCAT_VV(r0, t2, r1);
  106. PHALCON_CPY_WRT(prefixed_key, r0);
  107. phalcon_update_property_zval(this_ptr, SL("_lastKey"), prefixed_key TSRMLS_CC);
  108. PHALCON_ALLOC_ZVAL_MM(r2);
  109. PHALCON_ALLOC_ZVAL_MM(r3);
  110. phalcon_array_fetch_string(&r3, backend, SL("cacheDir"), PHALCON_NOISY TSRMLS_CC);
  111. PHALCON_CONCAT_VV(r2, r3, prefixed_key);
  112. PHALCON_CPY_WRT(cache_file, r2);
  113. if (phalcon_file_exists(cache_file TSRMLS_CC) == SUCCESS) {
  114. PHALCON_INIT_VAR(time);
  115. PHALCON_CALL_FUNC(time, "time");
  116. if (Z_TYPE_P(lifetime) == IS_NULL) {
  117. PHALCON_ALLOC_ZVAL_MM(r4);
  118. PHALCON_CALL_METHOD(r4, front_end, "getlifetime", PHALCON_NO_CHECK);
  119. PHALCON_CPY_WRT(ttl, r4);
  120. } else {
  121. PHALCON_CPY_WRT(ttl, lifetime);
  122. }
  123. PHALCON_ALLOC_ZVAL_MM(r5);
  124. sub_function(r5, time, ttl TSRMLS_CC);
  125. PHALCON_ALLOC_ZVAL_MM(r6);
  126. PHALCON_CALL_FUNC_PARAMS_1(r6, "filemtime", cache_file);
  127. PHALCON_INIT_VAR(r7);
  128. is_smaller_function(r7, r5, r6 TSRMLS_CC);
  129. if (zend_is_true(r7)) {
  130. PHALCON_INIT_VAR(cached_content);
  131. PHALCON_CALL_FUNC_PARAMS_1(cached_content, "file_get_contents", cache_file);
  132. PHALCON_ALLOC_ZVAL_MM(r8);
  133. PHALCON_CALL_METHOD_PARAMS_1(r8, front_end, "afterretrieve", cached_content, PHALCON_NO_CHECK);
  134. RETURN_DZVAL(r8);
  135. }
  136. }
  137. PHALCON_MM_RESTORE();
  138. RETURN_NULL();
  139. }
  140. /**
  141. * Stores cached content into the file backend
  142. *
  143. * @param int|string $keyName
  144. * @param string $content
  145. * @param long $lifetime
  146. * @param boolean $stopBuffer
  147. */
  148. PHP_METHOD(Phalcon_Cache_Backend_File, save){
  149. zval *key_name = NULL, *content = NULL, *lifetime = NULL, *stop_buffer = NULL;
  150. zval *last_key = NULL, *front_end = NULL, *backend = NULL, *cache_dir = NULL;
  151. zval *cache_file = NULL, *cached_content = NULL, *prepared_content = NULL;
  152. zval *is_buffering = NULL;
  153. zval *t0 = NULL, *t1 = NULL, *t2 = NULL, *t3 = NULL;
  154. zval *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *r4 = NULL, *r5 = NULL, *r6 = NULL;
  155. zval *r7 = NULL;
  156. PHALCON_MM_GROW();
  157. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zzzz", &key_name, &content, &lifetime, &stop_buffer) == FAILURE) {
  158. PHALCON_MM_RESTORE();
  159. RETURN_NULL();
  160. }
  161. if (!key_name) {
  162. PHALCON_INIT_VAR(key_name);
  163. ZVAL_NULL(key_name);
  164. }
  165. if (!content) {
  166. PHALCON_INIT_VAR(content);
  167. ZVAL_NULL(content);
  168. }
  169. if (!lifetime) {
  170. PHALCON_INIT_VAR(lifetime);
  171. ZVAL_NULL(lifetime);
  172. }
  173. if (!stop_buffer) {
  174. PHALCON_INIT_VAR(stop_buffer);
  175. ZVAL_BOOL(stop_buffer, 1);
  176. }
  177. if (Z_TYPE_P(key_name) == IS_NULL) {
  178. PHALCON_ALLOC_ZVAL_MM(t0);
  179. phalcon_read_property(&t0, this_ptr, SL("_lastKey"), PHALCON_NOISY TSRMLS_CC);
  180. PHALCON_CPY_WRT(last_key, t0);
  181. } else {
  182. PHALCON_ALLOC_ZVAL_MM(r0);
  183. PHALCON_ALLOC_ZVAL_MM(t1);
  184. phalcon_read_property(&t1, this_ptr, SL("_prefix"), PHALCON_NOISY TSRMLS_CC);
  185. PHALCON_ALLOC_ZVAL_MM(r1);
  186. phalcon_filter_alphanum(r1, key_name);
  187. PHALCON_CONCAT_VV(r0, t1, r1);
  188. PHALCON_CPY_WRT(last_key, r0);
  189. }
  190. if (!zend_is_true(last_key)) {
  191. PHALCON_THROW_EXCEPTION_STR(phalcon_cache_exception_ce, "The cache must be started first");
  192. return;
  193. }
  194. PHALCON_ALLOC_ZVAL_MM(t2);
  195. phalcon_read_property(&t2, this_ptr, SL("_frontendObject"), PHALCON_NOISY TSRMLS_CC);
  196. PHALCON_CPY_WRT(front_end, t2);
  197. PHALCON_ALLOC_ZVAL_MM(t3);
  198. phalcon_read_property(&t3, this_ptr, SL("_backendOptions"), PHALCON_NOISY TSRMLS_CC);
  199. PHALCON_CPY_WRT(backend, t3);
  200. PHALCON_ALLOC_ZVAL_MM(r2);
  201. phalcon_array_fetch_string(&r2, backend, SL("cacheDir"), PHALCON_NOISY TSRMLS_CC);
  202. PHALCON_CPY_WRT(cache_dir, r2);
  203. PHALCON_ALLOC_ZVAL_MM(r3);
  204. PHALCON_CALL_FUNC_PARAMS_1(r3, "is_writable", cache_dir);
  205. if (!zend_is_true(r3)) {
  206. PHALCON_THROW_EXCEPTION_STR(phalcon_cache_exception_ce, "The cache file is not writable");
  207. return;
  208. }
  209. PHALCON_ALLOC_ZVAL_MM(r4);
  210. PHALCON_CONCAT_VV(r4, cache_dir, last_key);
  211. PHALCON_CPY_WRT(cache_file, r4);
  212. if (!zend_is_true(content)) {
  213. PHALCON_ALLOC_ZVAL_MM(r5);
  214. PHALCON_CALL_METHOD(r5, front_end, "getcontent", PHALCON_NO_CHECK);
  215. PHALCON_CPY_WRT(cached_content, r5);
  216. } else {
  217. PHALCON_CPY_WRT(cached_content, content);
  218. }
  219. PHALCON_ALLOC_ZVAL_MM(r6);
  220. PHALCON_CALL_METHOD_PARAMS_1(r6, front_end, "beforestore", cached_content, PHALCON_NO_CHECK);
  221. PHALCON_CPY_WRT(prepared_content, r6);
  222. PHALCON_CALL_FUNC_PARAMS_2_NORETURN("file_put_contents", cache_file, prepared_content);
  223. PHALCON_ALLOC_ZVAL_MM(r7);
  224. PHALCON_CALL_METHOD(r7, front_end, "isbuffering", PHALCON_NO_CHECK);
  225. PHALCON_CPY_WRT(is_buffering, r7);
  226. if (zend_is_true(stop_buffer)) {
  227. PHALCON_CALL_METHOD_NORETURN(front_end, "stop", PHALCON_NO_CHECK);
  228. }
  229. if (zend_is_true(is_buffering)) {
  230. zend_print_zval(cached_content, 1);
  231. }
  232. phalcon_update_property_bool(this_ptr, SL("_started"), 0 TSRMLS_CC);
  233. PHALCON_MM_RESTORE();
  234. }
  235. /**
  236. * Deletes a value from the cache by its key
  237. *
  238. * @param int|string $keyName
  239. * @return boolean
  240. */
  241. PHP_METHOD(Phalcon_Cache_Backend_File, delete){
  242. zval *key_name = NULL, *backend = NULL, *prefixed_key = NULL, *cache_file = NULL;
  243. zval *t0 = NULL, *t1 = NULL;
  244. zval *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *r4 = NULL;
  245. PHALCON_MM_GROW();
  246. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &key_name) == FAILURE) {
  247. PHALCON_MM_RESTORE();
  248. RETURN_NULL();
  249. }
  250. PHALCON_ALLOC_ZVAL_MM(t0);
  251. phalcon_read_property(&t0, this_ptr, SL("_backendOptions"), PHALCON_NOISY TSRMLS_CC);
  252. PHALCON_CPY_WRT(backend, t0);
  253. PHALCON_ALLOC_ZVAL_MM(r0);
  254. PHALCON_ALLOC_ZVAL_MM(t1);
  255. phalcon_read_property(&t1, this_ptr, SL("_prefix"), PHALCON_NOISY TSRMLS_CC);
  256. PHALCON_ALLOC_ZVAL_MM(r1);
  257. phalcon_filter_alphanum(r1, key_name);
  258. PHALCON_CONCAT_VV(r0, t1, r1);
  259. PHALCON_CPY_WRT(prefixed_key, r0);
  260. PHALCON_ALLOC_ZVAL_MM(r2);
  261. PHALCON_ALLOC_ZVAL_MM(r3);
  262. phalcon_array_fetch_string(&r3, backend, SL("cacheDir"), PHALCON_NOISY TSRMLS_CC);
  263. PHALCON_CONCAT_VV(r2, r3, prefixed_key);
  264. PHALCON_CPY_WRT(cache_file, r2);
  265. if (phalcon_file_exists(cache_file TSRMLS_CC) == SUCCESS) {
  266. PHALCON_ALLOC_ZVAL_MM(r4);
  267. PHALCON_CALL_FUNC_PARAMS_1(r4, "unlink", cache_file);
  268. RETURN_DZVAL(r4);
  269. }
  270. PHALCON_MM_RESTORE();
  271. RETURN_FALSE;
  272. }
  273. /**
  274. * Query the existing cached keys
  275. *
  276. * @param string $prefix
  277. * @return array
  278. */
  279. PHP_METHOD(Phalcon_Cache_Backend_File, queryKeys){
  280. zval *prefix = NULL, *start = NULL, *keys = NULL, *backend = NULL, *prefix_length = NULL;
  281. zval *iterator = NULL, *item = NULL, *key = NULL;
  282. zval *a0 = NULL;
  283. zval *t0 = NULL;
  284. zval *i0 = NULL;
  285. zval *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *r4 = NULL, *r5 = NULL, *r6 = NULL;
  286. zend_class_entry *ce0;
  287. PHALCON_MM_GROW();
  288. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &prefix) == FAILURE) {
  289. PHALCON_MM_RESTORE();
  290. RETURN_NULL();
  291. }
  292. if (!prefix) {
  293. PHALCON_INIT_VAR(prefix);
  294. ZVAL_NULL(prefix);
  295. }
  296. PHALCON_INIT_VAR(start);
  297. ZVAL_LONG(start, 0);
  298. PHALCON_INIT_VAR(a0);
  299. array_init(a0);
  300. PHALCON_CPY_WRT(keys, a0);
  301. PHALCON_ALLOC_ZVAL_MM(t0);
  302. phalcon_read_property(&t0, this_ptr, SL("_backendOptions"), PHALCON_NOISY TSRMLS_CC);
  303. PHALCON_CPY_WRT(backend, t0);
  304. PHALCON_INIT_VAR(prefix_length);
  305. PHALCON_CALL_FUNC_PARAMS_1(prefix_length, "strlen", prefix);
  306. ce0 = zend_fetch_class("DirectoryIterator", strlen("DirectoryIterator"), ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
  307. PHALCON_ALLOC_ZVAL_MM(i0);
  308. object_init_ex(i0, ce0);
  309. PHALCON_ALLOC_ZVAL_MM(r0);
  310. phalcon_array_fetch_string(&r0, backend, SL("cacheDir"), PHALCON_NOISY TSRMLS_CC);
  311. PHALCON_CALL_METHOD_PARAMS_1_NORETURN(i0, "__construct", r0, PHALCON_CHECK);
  312. PHALCON_CPY_WRT(iterator, i0);
  313. PHALCON_CALL_METHOD_NORETURN(iterator, "rewind", PHALCON_NO_CHECK);
  314. ws_469d_0:
  315. PHALCON_INIT_VAR(r1);
  316. PHALCON_CALL_METHOD(r1, iterator, "valid", PHALCON_NO_CHECK);
  317. if (!zend_is_true(r1)) {
  318. goto we_469d_0;
  319. }
  320. PHALCON_INIT_VAR(r2);
  321. PHALCON_CALL_METHOD(r2, iterator, "current", PHALCON_NO_CHECK);
  322. PHALCON_CPY_WRT(item, r2);
  323. PHALCON_INIT_VAR(r3);
  324. PHALCON_CALL_METHOD(r3, item, "isdir", PHALCON_NO_CHECK);
  325. if (!zend_is_true(r3)) {
  326. PHALCON_INIT_VAR(r4);
  327. PHALCON_CALL_METHOD(r4, item, "getfilename", PHALCON_NO_CHECK);
  328. PHALCON_CPY_WRT(key, r4);
  329. if (zend_is_true(prefix)) {
  330. PHALCON_INIT_VAR(r5);
  331. PHALCON_CALL_FUNC_PARAMS_3(r5, "substr", key, start, prefix_length);
  332. PHALCON_INIT_VAR(r6);
  333. is_not_equal_function(r6, r5, prefix TSRMLS_CC);
  334. if (zend_is_true(r6)) {
  335. goto ws_469d_0;
  336. }
  337. }
  338. phalcon_array_append(&keys, key, PHALCON_SEPARATE_PLZ TSRMLS_CC);
  339. }
  340. PHALCON_CALL_METHOD_NORETURN(iterator, "next", PHALCON_NO_CHECK);
  341. goto ws_469d_0;
  342. we_469d_0:
  343. RETURN_CTOR(keys);
  344. }