/libraries/joomla/cache/controller/callback.php

https://github.com/bolis97/joomla-cms · PHP · 171 lines · 79 code · 25 blank · 67 comment · 22 complexity · 74dc55d074481a2e85bc82485d2ca0b0 MD5 · raw file

  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Cache
  5. *
  6. * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. jimport('joomla.cache.controller');
  11. /**
  12. * Joomla! Cache callback type object
  13. *
  14. * @package Joomla.Platform
  15. * @subpackage Cache
  16. * @since 11.1
  17. */
  18. class JCacheControllerCallback extends JCacheController
  19. {
  20. /**
  21. * Executes a cacheable callback if not found in cache else returns cached output and result
  22. *
  23. * Since arguments to this function are read with func_get_args you can pass any number of
  24. * arguments to this method
  25. * as long as the first argument passed is the callback definition.
  26. *
  27. * The callback definition can be in several forms:
  28. * - Standard PHP Callback array see <http://php.net/callback> [recommended]
  29. * - Function name as a string eg. 'foo' for function foo()
  30. * - Static method name as a string eg. 'MyClass::myMethod' for method myMethod() of class MyClass
  31. *
  32. * @return mixed Result of the callback
  33. *
  34. * @since 11.1
  35. */
  36. public function call()
  37. {
  38. // Get callback and arguments
  39. $args = func_get_args();
  40. $callback = array_shift($args);
  41. return $this->get($callback, $args);
  42. }
  43. /**
  44. * Executes a cacheable callback if not found in cache else returns cached output and result
  45. *
  46. * @param mixed Callback or string shorthand for a callback
  47. * @param array Callback arguments
  48. * @param string Cache id
  49. * @param boolean True to perform workarounds on data
  50. * @param array Workaround options
  51. *
  52. * @return mixed Result of the callback
  53. *
  54. * @since 11.1
  55. */
  56. public function get($callback, $args=array(), $id=false, $wrkarounds=false, $woptions=array())
  57. {
  58. // Normalize callback
  59. if (is_array($callback)) {
  60. // We have a standard php callback array -- do nothing
  61. } elseif (strstr($callback, '::')) {
  62. // This is shorthand for a static method callback classname::methodname
  63. list($class, $method) = explode('::', $callback);
  64. $callback = array(trim($class), trim($method));
  65. } elseif (strstr($callback, '->')) {
  66. /*
  67. * This is a really not so smart way of doing this... we provide this for backward compatability but this
  68. * WILL! disappear in a future version. If you are using this syntax change your code to use the standard
  69. * PHP callback array syntax: <http://php.net/callback>
  70. *
  71. * We have to use some silly global notation to pull it off and this is very unreliable
  72. */
  73. list($object_123456789, $method) = explode('->', $callback);
  74. global $$object_123456789;
  75. $callback = array($$object_123456789, $method);
  76. } else {
  77. // We have just a standard function -- do nothing
  78. }
  79. if (!$id) {
  80. // Generate an ID
  81. $id = $this->_makeId($callback, $args);
  82. }
  83. $data = false;
  84. $data = $this->cache->get($id);
  85. $locktest = new stdClass;
  86. $locktest->locked = null;
  87. $locktest->locklooped = null;
  88. if ($data === false) {
  89. $locktest = $this->cache->lock($id);
  90. if ($locktest->locked == true && $locktest->locklooped == true) {
  91. $data = $this->cache->get($id);
  92. }
  93. }
  94. $coptions= array();
  95. if ($data !== false) {
  96. $cached = unserialize(trim($data));
  97. $coptions['mergehead'] = isset($woptions['mergehead']) ? $woptions['mergehead'] : 0;
  98. $output = ($wrkarounds == false) ? $cached['output'] : JCache::getWorkarounds($cached['output'], $coptions);
  99. $result = $cached['result'];
  100. if ($locktest->locked == true) $this->cache->unlock($id);
  101. } else {
  102. if (!is_array($args)) {
  103. $Args = !empty($args) ? array( &$args) : array();
  104. } else {
  105. $Args = &$args;
  106. }
  107. if ($locktest->locked == false) $locktest = $this->cache->lock($id);
  108. ob_start();
  109. ob_implicit_flush(false);
  110. $result = call_user_func_array($callback, $Args);
  111. $output = ob_get_contents();
  112. ob_end_clean();
  113. $cached = array();
  114. $coptions['nopathway'] = isset($woptions['nopathway']) ? $woptions['nopathway'] : 1;
  115. $coptions['nohead'] = isset($woptions['nohead']) ? $woptions['nohead'] : 1;
  116. $coptions['nomodules'] = isset($woptions['nomodules']) ? $woptions['nomodules'] : 1;
  117. $coptions['modulemode'] = isset($woptions['modulemode']) ? $woptions['modulemode'] : 0;
  118. $cached['output'] = ($wrkarounds == false) ? $output : JCache::setWorkarounds($output, $coptions);
  119. $cached['result'] = $result;
  120. // Store the cache data
  121. $this->cache->store(serialize($cached), $id);
  122. if ($locktest->locked == true) $this->cache->unlock($id);
  123. }
  124. echo $output;
  125. return $result;
  126. }
  127. /**
  128. * Generate a callback cache id
  129. *
  130. * @param callback $callback Callback to cache
  131. * @param array $args Arguments to the callback method to cache
  132. *
  133. * @return string MD5 Hash : function cache id
  134. *
  135. * @since 11.1
  136. */
  137. protected function _makeId($callback, $args)
  138. {
  139. if (is_array($callback) && is_object($callback[0])) {
  140. $vars = get_object_vars($callback[0]);
  141. $vars[] = strtolower(get_class($callback[0]));
  142. $callback[0] = $vars;
  143. }
  144. return md5(serialize(array($callback, $args)));
  145. }
  146. }