|
9 | 9 |
|
10 | 10 | defined( 'ABSPATH' ) || exit; |
11 | 11 |
|
| 12 | +require_once __DIR__ . '/WpAiClientTransientCache.php'; |
| 13 | + |
12 | 14 | /** |
13 | 15 | * Installs a WordPress-backed PSR-16 cache for wp-ai-client. |
14 | 16 | */ |
@@ -46,233 +48,3 @@ public static function install(): void { |
46 | 48 | } |
47 | 49 | } |
48 | 50 | } |
49 | | - |
50 | | -/** |
51 | | - * Shared implementation for transient-backed wp-ai-client caches. |
52 | | - */ |
53 | | -abstract class WpAiClientTransientCacheBase { |
54 | | - |
55 | | - /** |
56 | | - * Cache version option used to logically clear Data Machine's namespace. |
57 | | - */ |
58 | | - private const VERSION_OPTION = 'datamachine_wp_ai_client_cache_version'; |
59 | | - |
60 | | - /** |
61 | | - * Prefix for transient keys. |
62 | | - */ |
63 | | - private const TRANSIENT_PREFIX = 'datamachine_wp_ai_client_'; |
64 | | - |
65 | | - /** |
66 | | - * Fetches a value from the cache. |
67 | | - * |
68 | | - * @param string $key Cache key. |
69 | | - * @param mixed $default Default value. |
70 | | - * @return mixed |
71 | | - */ |
72 | | - public function get( $key, $default_value = null ) { |
73 | | - $this->validateKey( $key ); |
74 | | - |
75 | | - $cached = get_transient( $this->transientKey( $key ) ); |
76 | | - if ( ! is_array( $cached ) || ! array_key_exists( 'value', $cached ) ) { |
77 | | - return $default_value; |
78 | | - } |
79 | | - |
80 | | - return $cached['value']; |
81 | | - } |
82 | | - |
83 | | - /** |
84 | | - * Stores a value in the cache. |
85 | | - * |
86 | | - * @param string $key Cache key. |
87 | | - * @param mixed $value Cache value. |
88 | | - * @param null|int|\DateInterval $ttl TTL. |
89 | | - * @return bool |
90 | | - */ |
91 | | - public function set( $key, $value, $ttl = null ) { |
92 | | - $this->validateKey( $key ); |
93 | | - |
94 | | - $expiration = $this->ttlToSeconds( $ttl ); |
95 | | - if ( $expiration < 0 ) { |
96 | | - return $this->delete( $key ); |
97 | | - } |
98 | | - |
99 | | - return set_transient( $this->transientKey( $key ), array( 'value' => $value ), $expiration ); |
100 | | - } |
101 | | - |
102 | | - /** |
103 | | - * Deletes a value from the cache. |
104 | | - * |
105 | | - * @param string $key Cache key. |
106 | | - * @return bool |
107 | | - */ |
108 | | - public function delete( $key ) { |
109 | | - $this->validateKey( $key ); |
110 | | - |
111 | | - return delete_transient( $this->transientKey( $key ) ); |
112 | | - } |
113 | | - |
114 | | - /** |
115 | | - * Clears this adapter's logical namespace. |
116 | | - * |
117 | | - * @return bool |
118 | | - */ |
119 | | - public function clear() { |
120 | | - $version = (int) get_option( self::VERSION_OPTION, 1 ); |
121 | | - |
122 | | - return update_option( self::VERSION_OPTION, max( 1, $version ) + 1, false ); |
123 | | - } |
124 | | - |
125 | | - /** |
126 | | - * Fetches multiple values from the cache. |
127 | | - * |
128 | | - * @param iterable $keys Cache keys. |
129 | | - * @param mixed $default Default value. |
130 | | - * @return iterable |
131 | | - */ |
132 | | - public function getMultiple( $keys, $default_value = null ) { |
133 | | - $values = array(); |
134 | | - foreach ( $this->iterableKeys( $keys ) as $key ) { |
135 | | - $values[ $key ] = $this->get( $key, $default_value ); |
136 | | - } |
137 | | - |
138 | | - return $values; |
139 | | - } |
140 | | - |
141 | | - /** |
142 | | - * Stores multiple values in the cache. |
143 | | - * |
144 | | - * @param iterable $values Key/value map. |
145 | | - * @param null|int|\DateInterval $ttl TTL. |
146 | | - * @return bool |
147 | | - */ |
148 | | - public function setMultiple( $values, $ttl = null ) { |
149 | | - $ok = true; |
150 | | - foreach ( $this->iterableValues( $values ) as $key => $value ) { |
151 | | - $ok = $this->set( $key, $value, $ttl ) && $ok; |
152 | | - } |
153 | | - |
154 | | - return $ok; |
155 | | - } |
156 | | - |
157 | | - /** |
158 | | - * Deletes multiple values from the cache. |
159 | | - * |
160 | | - * @param iterable $keys Cache keys. |
161 | | - * @return bool |
162 | | - */ |
163 | | - public function deleteMultiple( $keys ) { |
164 | | - $ok = true; |
165 | | - foreach ( $this->iterableKeys( $keys ) as $key ) { |
166 | | - $ok = $this->delete( $key ) && $ok; |
167 | | - } |
168 | | - |
169 | | - return $ok; |
170 | | - } |
171 | | - |
172 | | - /** |
173 | | - * Determines whether a key exists in the cache. |
174 | | - * |
175 | | - * @param string $key Cache key. |
176 | | - * @return bool |
177 | | - */ |
178 | | - public function has( $key ) { |
179 | | - $missing = new \stdClass(); |
180 | | - |
181 | | - return $missing !== $this->get( $key, $missing ); |
182 | | - } |
183 | | - |
184 | | - /** |
185 | | - * Builds a WordPress-safe transient key from the wp-ai-client key. |
186 | | - * |
187 | | - * @param string $key Original cache key. |
188 | | - * @return string |
189 | | - */ |
190 | | - private function transientKey( string $key ): string { |
191 | | - $version = (int) get_option( self::VERSION_OPTION, 1 ); |
192 | | - |
193 | | - return self::TRANSIENT_PREFIX . max( 1, $version ) . '_' . md5( $key ); |
194 | | - } |
195 | | - |
196 | | - /** |
197 | | - * Converts a PSR-16 TTL to WordPress transient seconds. |
198 | | - * |
199 | | - * @param null|int|\DateInterval $ttl TTL. |
200 | | - * @return int |
201 | | - */ |
202 | | - private function ttlToSeconds( $ttl ): int { |
203 | | - if ( null === $ttl ) { |
204 | | - return 0; |
205 | | - } |
206 | | - |
207 | | - if ( $ttl instanceof \DateInterval ) { |
208 | | - $now = new \DateTimeImmutable(); |
209 | | - $future = $now->add( $ttl ); |
210 | | - |
211 | | - return $future->getTimestamp() - $now->getTimestamp(); |
212 | | - } |
213 | | - |
214 | | - if ( is_numeric( $ttl ) ) { |
215 | | - return (int) $ttl; |
216 | | - } |
217 | | - |
218 | | - throw new \InvalidArgumentException( 'Cache TTL must be null, an integer, or a DateInterval.' ); |
219 | | - } |
220 | | - |
221 | | - /** |
222 | | - * Validate a PSR-16 key. |
223 | | - * |
224 | | - * @param mixed $key Cache key. |
225 | | - * @return void |
226 | | - */ |
227 | | - private function validateKey( $key ): void { |
228 | | - if ( ! is_string( $key ) || '' === $key ) { |
229 | | - throw new \InvalidArgumentException( 'Cache key must be a non-empty string.' ); |
230 | | - } |
231 | | - } |
232 | | - |
233 | | - /** |
234 | | - * Normalize iterable keys. |
235 | | - * |
236 | | - * @param mixed $keys Keys. |
237 | | - * @return iterable |
238 | | - */ |
239 | | - private function iterableKeys( $keys ): iterable { |
240 | | - if ( ! is_iterable( $keys ) ) { |
241 | | - throw new \InvalidArgumentException( 'Cache keys must be iterable.' ); |
242 | | - } |
243 | | - |
244 | | - foreach ( $keys as $key ) { |
245 | | - $this->validateKey( $key ); |
246 | | - yield $key; |
247 | | - } |
248 | | - } |
249 | | - |
250 | | - /** |
251 | | - * Normalize iterable key/value pairs. |
252 | | - * |
253 | | - * @param mixed $values Values. |
254 | | - * @return iterable |
255 | | - */ |
256 | | - private function iterableValues( $values ): iterable { |
257 | | - if ( ! is_iterable( $values ) ) { |
258 | | - throw new \InvalidArgumentException( 'Cache values must be iterable.' ); |
259 | | - } |
260 | | - |
261 | | - foreach ( $values as $key => $value ) { |
262 | | - $this->validateKey( $key ); |
263 | | - yield $key => $value; |
264 | | - } |
265 | | - } |
266 | | -} |
267 | | - |
268 | | -if ( interface_exists( '\WordPress\AiClientDependencies\Psr\SimpleCache\CacheInterface' ) ) { |
269 | | - /** |
270 | | - * Transient-backed cache for WordPress' scoped wp-ai-client dependency namespace. |
271 | | - */ |
272 | | - class WpAiClientTransientCache extends WpAiClientTransientCacheBase implements \WordPress\AiClientDependencies\Psr\SimpleCache\CacheInterface {} |
273 | | -} elseif ( interface_exists( '\Psr\SimpleCache\CacheInterface' ) ) { |
274 | | - /** |
275 | | - * Transient-backed cache for unscoped php-ai-client installs. |
276 | | - */ |
277 | | - class WpAiClientTransientCache extends WpAiClientTransientCacheBase implements \Psr\SimpleCache\CacheInterface {} |
278 | | -} |
0 commit comments