[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Cache/Controller/ -> CallbackController.php (source)

   1  <?php
   2  /**
   3   * Joomla! Content Management System
   4   *
   5   * @copyright  (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
   6   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   7   */
   8  
   9  namespace Joomla\CMS\Cache\Controller;
  10  
  11  \defined('JPATH_PLATFORM') or die;
  12  
  13  use Joomla\CMS\Cache\Cache;
  14  use Joomla\CMS\Cache\CacheController;
  15  use Joomla\CMS\Document\HtmlDocument;
  16  use Joomla\CMS\Factory;
  17  
  18  /**
  19   * Joomla! Cache callback type object
  20   *
  21   * @since  1.7.0
  22   */
  23  class CallbackController extends CacheController
  24  {
  25      /**
  26       * Executes a cacheable callback if not found in cache else returns cached output and result
  27       *
  28       * @param   callable  $callback    Callback or string shorthand for a callback
  29       * @param   array     $args        Callback arguments
  30       * @param   mixed     $id          Cache ID
  31       * @param   boolean   $wrkarounds  True to use workarounds
  32       * @param   array     $woptions    Workaround options
  33       *
  34       * @return  mixed  Result of the callback
  35       *
  36       * @since   1.7.0
  37       */
  38  	public function get($callback, $args = array(), $id = false, $wrkarounds = false, $woptions = array())
  39      {
  40          if (!\is_array($args))
  41          {
  42              $referenceArgs = !empty($args) ? array(&$args) : array();
  43          }
  44          else
  45          {
  46              $referenceArgs = &$args;
  47          }
  48  
  49          // Just execute the callback if caching is disabled.
  50          if (empty($this->options['caching']))
  51          {
  52              return \call_user_func_array($callback, $referenceArgs);
  53          }
  54  
  55          if (!$id)
  56          {
  57              // Generate an ID
  58              $id = $this->_makeId($callback, $args);
  59          }
  60  
  61          $data = $this->cache->get($id);
  62  
  63          $locktest = (object) array('locked' => null, 'locklooped' => null);
  64  
  65          if ($data === false)
  66          {
  67              $locktest = $this->cache->lock($id);
  68  
  69              // If locklooped is true try to get the cached data again; it could exist now.
  70              if ($locktest->locked === true && $locktest->locklooped === true)
  71              {
  72                  $data = $this->cache->get($id);
  73              }
  74          }
  75  
  76          if ($data !== false)
  77          {
  78              if ($locktest->locked === true)
  79              {
  80                  $this->cache->unlock($id);
  81              }
  82  
  83              $data = unserialize(trim($data));
  84  
  85              if ($wrkarounds)
  86              {
  87                  echo Cache::getWorkarounds(
  88                      $data['output'],
  89                      array('mergehead' => $woptions['mergehead'] ?? 0)
  90                  );
  91              }
  92              else
  93              {
  94                  echo $data['output'];
  95              }
  96  
  97              return $data['result'];
  98          }
  99  
 100          if ($locktest->locked === false && $locktest->locklooped === true)
 101          {
 102              // We can not store data because another process is in the middle of saving
 103              return \call_user_func_array($callback, $referenceArgs);
 104          }
 105  
 106          $coptions = array('modulemode' => 0);
 107  
 108          if (isset($woptions['modulemode']) && $woptions['modulemode'] == 1)
 109          {
 110              /** @var HtmlDocument $document */
 111              $document = Factory::getDocument();
 112  
 113              if (method_exists($document, 'getHeadData'))
 114              {
 115                  $coptions['headerbefore'] = $document->getHeadData();
 116  
 117                  // Reset document head before rendering module. Module will cache only assets added by itself.
 118                  $document->resetHeadData();
 119                  $document->getWebAssetManager()->reset();
 120  
 121                  $coptions['modulemode'] = 1;
 122              }
 123          }
 124  
 125          $coptions['nopathway'] = $woptions['nopathway'] ?? 1;
 126          $coptions['nohead']    = $woptions['nohead'] ?? 1;
 127          $coptions['nomodules'] = $woptions['nomodules'] ?? 1;
 128  
 129          ob_start();
 130          ob_implicit_flush(false);
 131  
 132          $result = \call_user_func_array($callback, $referenceArgs);
 133          $output = ob_get_clean();
 134  
 135          $data = array('result' => $result);
 136  
 137          if ($wrkarounds)
 138          {
 139              $data['output'] = Cache::setWorkarounds($output, $coptions);
 140          }
 141          else
 142          {
 143              $data['output'] = $output;
 144          }
 145  
 146          // Restore document head data and merge module head data.
 147          if ($coptions['modulemode'] == 1)
 148          {
 149              $moduleHeadData = $document->getHeadData();
 150              $document->resetHeadData();
 151              $document->mergeHeadData($coptions['headerbefore']);
 152              $document->mergeHeadData($moduleHeadData);
 153          }
 154  
 155          // Store the cache data
 156          $this->cache->store(serialize($data), $id);
 157  
 158          if ($locktest->locked === true)
 159          {
 160              $this->cache->unlock($id);
 161          }
 162  
 163          echo $output;
 164  
 165          return $result;
 166      }
 167  
 168      /**
 169       * Store data to cache by ID and group
 170       *
 171       * @param   mixed    $data        The data to store
 172       * @param   string   $id          The cache data ID
 173       * @param   string   $group       The cache data group
 174       * @param   boolean  $wrkarounds  True to use wrkarounds
 175       *
 176       * @return  boolean  True if cache stored
 177       *
 178       * @since   4.0.0
 179       */
 180  	public function store($data, $id, $group = null, $wrkarounds = true)
 181      {
 182          $locktest = $this->cache->lock($id, $group);
 183  
 184          if ($locktest->locked === false && $locktest->locklooped === true)
 185          {
 186              // We can not store data because another process is in the middle of saving
 187              return false;
 188          }
 189  
 190          $result = $this->cache->store(serialize($data), $id, $group);
 191  
 192          if ($locktest->locked === true)
 193          {
 194              $this->cache->unlock($id, $group);
 195          }
 196  
 197          return $result;
 198      }
 199  
 200      /**
 201       * Generate a callback cache ID
 202       *
 203       * @param   mixed  $callback  Callback to cache
 204       * @param   array  $args      Arguments to the callback method to cache
 205       *
 206       * @return  string  MD5 Hash
 207       *
 208       * @since   1.7.0
 209       */
 210  	protected function _makeId($callback, $args)
 211      {
 212          if (\is_array($callback) && \is_object($callback[0]))
 213          {
 214              $vars        = get_object_vars($callback[0]);
 215              $vars[]      = strtolower(\get_class($callback[0]));
 216              $callback[0] = $vars;
 217          }
 218  
 219          // A Closure can't be serialized, so to generate the ID we'll need to get its hash
 220          if ($callback instanceof \closure)
 221          {
 222              $hash = spl_object_hash($callback);
 223  
 224              return md5($hash . serialize(array($args)));
 225          }
 226  
 227          return md5(serialize(array($callback, $args)));
 228      }
 229  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer