/libraries/src/Cache/CacheController.php

https://github.com/fastslack/joomla-cms · PHP · 220 lines · 97 code · 31 blank · 92 comment · 16 complexity · 0b670b555ce581c2cfe150569ae9cb78 MD5 · raw file

  1. <?php
  2. /**
  3. * Joomla! Content Management System
  4. *
  5. * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
  6. * @license GNU General Public License version 2 or later; see LICENSE.txt
  7. */
  8. namespace Joomla\CMS\Cache;
  9. defined('JPATH_PLATFORM') or die;
  10. /**
  11. * Public cache handler
  12. *
  13. * @since 11.1
  14. * @note As of 4.0 this class will be abstract
  15. */
  16. class CacheController
  17. {
  18. /**
  19. * Cache object
  20. *
  21. * @var Cache
  22. * @since 11.1
  23. */
  24. public $cache;
  25. /**
  26. * Array of options
  27. *
  28. * @var array
  29. * @since 11.1
  30. */
  31. public $options;
  32. /**
  33. * Constructor
  34. *
  35. * @param array $options Array of options
  36. *
  37. * @since 11.1
  38. */
  39. public function __construct($options)
  40. {
  41. $this->cache = new Cache($options);
  42. $this->options = & $this->cache->_options;
  43. // Overwrite default options with given options
  44. foreach ($options as $option => $value)
  45. {
  46. if (isset($options[$option]))
  47. {
  48. $this->options[$option] = $options[$option];
  49. }
  50. }
  51. }
  52. /**
  53. * Magic method to proxy CacheController method calls to Cache
  54. *
  55. * @param string $name Name of the function
  56. * @param array $arguments Array of arguments for the function
  57. *
  58. * @return mixed
  59. *
  60. * @since 11.1
  61. */
  62. public function __call($name, $arguments)
  63. {
  64. return call_user_func_array(array($this->cache, $name), $arguments);
  65. }
  66. /**
  67. * Returns a reference to a cache adapter object, always creating it
  68. *
  69. * @param string $type The cache object type to instantiate; default is output.
  70. * @param array $options Array of options
  71. *
  72. * @return CacheController
  73. *
  74. * @since 11.1
  75. * @throws \RuntimeException
  76. */
  77. public static function getInstance($type = 'output', $options = array())
  78. {
  79. self::addIncludePath(__DIR__ . '/Controller');
  80. $type = strtolower(preg_replace('/[^A-Z0-9_\.-]/i', '', $type));
  81. $class = __NAMESPACE__ . '\\Controller\\' . ucfirst($type) . 'Controller';
  82. if (!class_exists($class))
  83. {
  84. $class = 'JCacheController' . ucfirst($type);
  85. }
  86. if (!class_exists($class))
  87. {
  88. // Search for the class file in the Cache include paths.
  89. \JLoader::import('joomla.filesystem.path');
  90. $path = \JPath::find(self::addIncludePath(), strtolower($type) . '.php');
  91. if ($path !== false)
  92. {
  93. \JLoader::register($class, $path);
  94. }
  95. // The class should now be loaded
  96. if (!class_exists($class))
  97. {
  98. throw new \RuntimeException('Unable to load Cache Controller: ' . $type, 500);
  99. }
  100. }
  101. return new $class($options);
  102. }
  103. /**
  104. * Add a directory where Cache should search for controllers. You may either pass a string or an array of directories.
  105. *
  106. * @param array|string $path A path to search.
  107. *
  108. * @return array An array with directory elements
  109. *
  110. * @since 11.1
  111. */
  112. public static function addIncludePath($path = '')
  113. {
  114. static $paths;
  115. if (!isset($paths))
  116. {
  117. $paths = array();
  118. }
  119. if (!empty($path) && !in_array($path, $paths))
  120. {
  121. \JLoader::import('joomla.filesystem.path');
  122. array_unshift($paths, \JPath::clean($path));
  123. }
  124. return $paths;
  125. }
  126. /**
  127. * Get stored cached data by ID and group
  128. *
  129. * @param string $id The cache data ID
  130. * @param string $group The cache data group
  131. *
  132. * @return mixed Boolean false on no result, cached object otherwise
  133. *
  134. * @since 11.1
  135. * @deprecated 4.0 Implement own method in subclass
  136. */
  137. public function get($id, $group = null)
  138. {
  139. $data = $this->cache->get($id, $group);
  140. if ($data === false)
  141. {
  142. $locktest = $this->cache->lock($id, $group);
  143. // If locklooped is true try to get the cached data again; it could exist now.
  144. if ($locktest->locked === true && $locktest->locklooped === true)
  145. {
  146. $data = $this->cache->get($id, $group);
  147. }
  148. if ($locktest->locked === true)
  149. {
  150. $this->cache->unlock($id, $group);
  151. }
  152. }
  153. // Check again because we might get it from second attempt
  154. if ($data !== false)
  155. {
  156. // Trim to fix unserialize errors
  157. $data = unserialize(trim($data));
  158. }
  159. return $data;
  160. }
  161. /**
  162. * Store data to cache by ID and group
  163. *
  164. * @param mixed $data The data to store
  165. * @param string $id The cache data ID
  166. * @param string $group The cache data group
  167. * @param boolean $wrkarounds True to use wrkarounds
  168. *
  169. * @return boolean True if cache stored
  170. *
  171. * @since 11.1
  172. * @deprecated 4.0 Implement own method in subclass
  173. */
  174. public function store($data, $id, $group = null, $wrkarounds = true)
  175. {
  176. $locktest = $this->cache->lock($id, $group);
  177. if ($locktest->locked === false && $locktest->locklooped === true)
  178. {
  179. // We can not store data because another process is in the middle of saving
  180. return false;
  181. }
  182. $result = $this->cache->store(serialize($data), $id, $group);
  183. if ($locktest->locked === true)
  184. {
  185. $this->cache->unlock($id, $group);
  186. }
  187. return $result;
  188. }
  189. }