Skip to content

Commit eb35faf

Browse files
committed
feat: add cache expiry and timestamp-based validation to Knowledge Base caching system
1 parent 64174bf commit eb35faf

File tree

1 file changed

+122
-4
lines changed

1 file changed

+122
-4
lines changed

includes/util/class-cache.php

Lines changed: 122 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Cache functions used by Better Search
3+
* Cache functions used by Knowledge Base
44
*
55
* @since 2.3.0
66
*
@@ -32,7 +32,7 @@ public function __construct() {
3232
}
3333

3434
/**
35-
* Function to clear the Better Search Cache with Ajax.
35+
* Function to clear the Knowledge Base Cache with Ajax.
3636
*
3737
* @since 2.3.0
3838
*/
@@ -43,7 +43,7 @@ public function ajax_clearcache() {
4343
}
4444
check_ajax_referer( 'wzkb-admin', 'security' );
4545

46-
$count = $this->delete();
46+
$count = self::delete();
4747

4848
wp_send_json_success(
4949
array(
@@ -56,7 +56,7 @@ public function ajax_clearcache() {
5656
}
5757

5858
/**
59-
* Delete the Better Search cache.
59+
* Delete the Knowledge Base cache.
6060
*
6161
* @since 2.3.0
6262
*
@@ -133,4 +133,122 @@ public static function get_key( $attr ) {
133133

134134
return $meta_key;
135135
}
136+
137+
/**
138+
* Get the timestamp meta key for a cache entry.
139+
*
140+
* @since 3.0.0
141+
*
142+
* @param string $cache_key The cache key.
143+
* @return string Timestamp meta key
144+
*/
145+
public static function get_timestamp_key( $cache_key ) {
146+
return $cache_key . '_timestamp';
147+
}
148+
149+
/**
150+
* Check if a cache entry has expired.
151+
*
152+
* @since 3.0.0
153+
*
154+
* @param int $term_id Term ID.
155+
* @param string $cache_key Cache key.
156+
* @return bool True if expired or no expiry set, false if still valid.
157+
*/
158+
public static function is_expired( $term_id, $cache_key ) {
159+
$cache_expiry = (int) \wzkb_get_option( 'cache_expiry', DAY_IN_SECONDS );
160+
161+
// If expiry is 0, cache never expires.
162+
if ( 0 === $cache_expiry ) {
163+
return false;
164+
}
165+
166+
$timestamp_key = self::get_timestamp_key( $cache_key );
167+
$cached_time = get_term_meta( $term_id, $timestamp_key, true );
168+
169+
// If no timestamp exists, consider it expired.
170+
if ( false === $cached_time || '' === $cached_time ) {
171+
return true;
172+
}
173+
174+
$cached_time = (int) $cached_time;
175+
176+
$expiry_time = $cached_time + $cache_expiry;
177+
178+
return time() > $expiry_time;
179+
}
180+
181+
/**
182+
* Store cache data with timestamp.
183+
*
184+
* @since 3.0.0
185+
*
186+
* @param int $term_id Term ID.
187+
* @param string $cache_key Cache key.
188+
* @param mixed $data Data to cache.
189+
* @return bool True on success, false on failure.
190+
*/
191+
public static function set( $term_id, $cache_key, $data ) {
192+
$timestamp_key = self::get_timestamp_key( $cache_key );
193+
194+
// Delete existing cache entries first to ensure clean update.
195+
delete_term_meta( $term_id, $cache_key );
196+
delete_term_meta( $term_id, $timestamp_key );
197+
198+
// Store timestamp first to ensure atomicity.
199+
$timestamp_stored = add_term_meta( $term_id, $timestamp_key, time(), true );
200+
201+
// Only store data if timestamp was successfully stored.
202+
if ( ! $timestamp_stored ) {
203+
return false;
204+
}
205+
206+
$data_stored = add_term_meta( $term_id, $cache_key, $data, true );
207+
208+
// If data storage fails, clean up the orphaned timestamp.
209+
if ( ! $data_stored ) {
210+
delete_term_meta( $term_id, $timestamp_key );
211+
return false;
212+
}
213+
214+
return true;
215+
}
216+
217+
/**
218+
* Get cache data if not expired.
219+
*
220+
* @since 3.0.0
221+
*
222+
* @param int $term_id Term ID.
223+
* @param string $cache_key Cache key.
224+
* @return mixed|false Cached data if valid, false if expired or not found.
225+
*/
226+
public static function get( $term_id, $cache_key ) {
227+
// Check if cache has expired.
228+
if ( self::is_expired( $term_id, $cache_key ) ) {
229+
// Clean up expired cache.
230+
self::delete_expired_entry( $term_id, $cache_key );
231+
return false;
232+
}
233+
234+
return get_term_meta( $term_id, $cache_key, true );
235+
}
236+
237+
/**
238+
* Delete an expired cache entry and its timestamp.
239+
*
240+
* @since 3.0.0
241+
*
242+
* @param int $term_id Term ID.
243+
* @param string $cache_key Cache key.
244+
* @return bool True on success, false on failure.
245+
*/
246+
public static function delete_expired_entry( $term_id, $cache_key ) {
247+
$timestamp_key = self::get_timestamp_key( $cache_key );
248+
249+
$data_deleted = delete_term_meta( $term_id, $cache_key );
250+
$timestamp_deleted = delete_term_meta( $term_id, $timestamp_key );
251+
252+
return $data_deleted || $timestamp_deleted;
253+
}
136254
}

0 commit comments

Comments
 (0)