1: <?php
2: /*
3: You may not change or alter any portion of this comment or credits
4: of supporting developers from this source code or any supporting source code
5: which is considered copyrighted (c) material of the original comment or credit authors.
6:
7: This program is distributed in the hope that it will be useful,
8: but WITHOUT ANY WARRANTY; without even the implied warranty of
9: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10: */
11:
12: namespace Xoops\Core\Cache;
13:
14: use Stash\Pool;
15: use Stash\Invalidation;
16: use Stash\Interfaces\PoolInterface;
17:
18: /**
19: * Provides a standardized cache access
20: *
21: * @category Xoops\Core\Cache
22: * @package Cache
23: * @author Richard Griffith <richard@geekwright.com>
24: * @copyright 2015 The XOOPS Project https://github.com/XOOPS
25: * @license GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
26: * @link http://xoops.org
27: */
28: class Access
29: {
30: /**
31: * Cache pools
32: *
33: * @var PoolInterface
34: */
35: protected $pool = null;
36:
37: /**
38: * __construct
39: *
40: * @param type PoolInterface $pool cache pool to use for this cache instance
41: */
42: public function __construct(PoolInterface $pool)
43: {
44: $this->pool = $pool;
45: }
46:
47: /**
48: * Write data for key into cache.
49: *
50: * @param string|string[] $key Identifier for the cache item
51: * @param mixed $value Data to be cached - anything except a resource
52: * @param int|DateTime|null $ttl time to live, integer for ttl in seconds,
53: * DateTime object to expire at a specific time,
54: * or null for
55: *
56: * @return boolean True if the data was successfully cached, false on failure
57: */
58: public function write($key, $value, $ttl = null)
59: {
60: $item = $this->pool->getItem($key);
61: return $item->set($value, $ttl);
62: }
63:
64: /**
65: * Read a key from the cache.
66: *
67: * @param string|string[] $key Identifier for the cache item
68: *
69: * @return mixed The cached data
70: */
71: public function read($key)
72: {
73: $item = $this->pool->getItem($key);
74: $value = $item->get(Invalidation::NONE);
75: return ($item->isMiss()) ? false : $value;
76: }
77:
78: /**
79: * Delete a key from the cache.
80: *
81: * @param string|string[] $key Identifier for the cache item
82: *
83: * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
84: */
85: public function delete($key)
86: {
87: $item = $this->pool->getItem($key);
88: return $item->clear();
89: }
90:
91: /**
92: * cache block wrapper using Invalidation::PRECOMPUTE
93: *
94: * If the cache read for $key is a miss, call the $regenFunction to update it.
95: * With the PRECOMPUTE strategy, it will trigger a miss on a read on one caller
96: * before the cache expires, so it will be done in advance.
97: *
98: * @param string|string[] $cacheKey Identifier for the cache item
99: * @param callable $regenFunction function to generate cached content
100: * @param int|DateTime|null $ttl time to live, number ofseconds as integer,
101: * DateTime to expire at a specific time,
102: * or null for default
103: * @param mixed ...$args variable argument list for $regenFunction
104: *
105: * @return mixed
106: */
107: public function cacheRead($cacheKey, $regenFunction, $ttl = null, $args = null)
108: {
109: if (is_null($args)) {
110: $varArgs = array();
111: } else {
112: $varArgs = func_get_args();
113: array_shift($varArgs); // pull off $key
114: array_shift($varArgs); // pull off $regenFunction
115: array_shift($varArgs); // pull off $ttl
116: }
117:
118: $item = $this->pool->getItem($cacheKey);
119:
120: // Get the data from cache using the Stash\Invalidation::PRECOMPUTE technique
121: // for dealing with stampedes
122: $cachedContent = $item->get(Invalidation::PRECOMPUTE);
123:
124: // Check to see if the cache missed, which could mean that it either didn't exist or was stale.
125: if ($item->isMiss()) {
126: // Mark this instance as the one regenerating the cache.
127: $item->lock();
128:
129: // Run the relatively expensive code.
130: $cachedContent = call_user_func_array($regenFunction, $varArgs);
131:
132: // save result
133: $item->set($cachedContent, $ttl);
134: }
135:
136: return $cachedContent;
137: }
138:
139: /**
140: * Garbage collection - remove all expired and deleted data
141: *
142: * @return void
143: */
144: public function garbageCollect()
145: {
146: return $this->pool->purge();
147: }
148:
149: /**
150: * clear all keys and data from the cache.
151: *
152: * @return boolean True if the cache was successfully cleared, false otherwise
153: */
154: public function clear()
155: {
156: return $this->pool->flush();
157: }
158:
159: /**
160: * direct access to pool
161: *
162: * WARNING: this is intended for diagnostics and similar advanced uses.
163: * Depending on direct access to the pool may break future compatibility.
164: *
165: * @return PoolInterface the current pool
166: */
167: public function pool()
168: {
169: return $this->pool;
170: }
171: }
172: