-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathobject-cache-helper.php
More file actions
192 lines (147 loc) · 6.69 KB
/
object-cache-helper.php
File metadata and controls
192 lines (147 loc) · 6.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<?php
/**
* Plugin Name: WP Object Cache Helper
* Plugin URI: https://github.com/dmhendricks/object-cache-helper
* Description: A wrapper class for WP Object Cache
* Version: 1.0.0
* Author: Daniel M. Hendricks
* Author URI: https://www.danhendricks.com
* License: GPL-2.0
* License URI: https://opensource.org/licenses/GPL-2.0
*/
namespace MU_Plugins;
class WP_Cache_Object {
protected $config;
public function __construct( $args = [] ) {
// Set configuration defaults
$this->config = self::set_default_atts( [
'expire' => HOUR_IN_SECONDS,
'group' => get_option('stylesheet') . '_cache_group',
'single' => false, // Store as single key rather than group array
'network_global' => false, // Set to true to store cache value for entire network, rather than per sub-site
'force' => false
], $args );
// Validate arguments
$this->config['expire'] = intval( $this->config['expire'] );
$this->config['single'] = filter_var( $this->config['single'], FILTER_VALIDATE_BOOLEAN );
$this->config['network_global'] = filter_var( $this->config['network_global'], FILTER_VALIDATE_BOOLEAN );
$this->config['force'] = filter_var( $this->config['force'], FILTER_VALIDATE_BOOLEAN );
}
/*
* Retrieves value from cache, if enabled/present, else returns value
* generated by callback().
*
* @param string $key Key value of cache to retrieve
* @param function $callback Result to return/set if does not exist in cache
* @param array $args An array of arguments
* @return string Cached value of key
* @since 1.0.0
*/
public function get_object( $key, $callback ) {
$result = null;
$result_group = null;
$cache_hit = false;
// Add site ID suffic to cache group if multisite
if( is_multisite() ) $this->config['group'] .= '_' . get_current_site()->id;
// Set key variable, appending blog ID if network_global is false
$object_cache_key = $key . ( is_multisite() && !$this->config['network_global'] && get_current_blog_id() ? '_' . get_current_blog_id() : '' );
// Try to get key value from cache
if( !$this->config['force'] ) {
if( $this->config['single'] ) {
// Store value in individual key
$result = unserialize( wp_cache_get( $object_cache_key, $this->config['group'], false, $cache_hit ) );
} else {
// Store value in array of values with group as key
$result_group = wp_cache_get( $this->config['group'], $this->config['group'], false, $cache_hit );
$result_group = $cache_hit ? (array) unserialize( $result_group ) : [];
if( $cache_hit && isset( $result_group[$object_cache_key] ) ) {
$result = $result_group[$object_cache_key];
} else {
$cache_hit = false;
}
}
}
// If cache miss, set & return the value from $callback()
if( !$cache_hit ) {
$result = $callback();
// Store cache key value pair
if( $this->config['single'] ) {
// If single, store cache value.
wp_cache_set( $object_cache_key, serialize( $result ), $this->config['group'], $this->config['expire'] );
} else {
// Store cache value in group array to allow "flushing" of individual group
$result_group[$object_cache_key] = $result;
wp_cache_set( $this->config['group'], serialize( $result_group ), $this->config['group'], $this->config['expire'] );
}
}
if( is_string( $result ) && is_numeric( $result ) ) $result = intval( $result ) ? (int) $result : (float) $result;
return $result;
}
/**
* Flushes the key group from cache. This is an alternative method of flushing
* a single group rather than the entire object cache via wp_cache_flush().
* This function only works if values were stored via get_cache_object().
*
* @param string $group The name of the key group to flush (delete)
* @return bool True on success, false on error
* @since 1.0.0
*/
public function flush_group( $cache_group = null ) {
$cache_group = $cache_group ?: $this->config['group'];
try {
wp_cache_delete( $cache_group, $cache_group );
} catch ( Exception $e ) {
return false;
}
return true;
}
/**
* Deletes a single object key from a cache group. This function only works
* if values were stored via get_cache_object().
*
* @param string $object_cache_key The cache key to delete
* @param string $group The name of the key group to remove the key from
* @return bool True if key exists and is deleted, false if key not set
* @since 1.0.0
*/
public function delete_group_key( $object_cache_key, $cache_group = null ) {
$cache_group = $cache_group ?: $this->config['group'];
$result_group = unserialize( wp_cache_get( $cache_group, $cache_group, false, $cache_hit ) );
if( isset( $result_group[$object_cache_key] ) ) {
unset( $result_group[$object_cache_key] );
wp_cache_set( $cache_group, serialize( $result_group ), $cache_group, $this->config['expire'] );
return true;
}
return false;
}
/**
* Combines arrays and fill in defaults as needed.
* Same usage as shortcode_atts() except for non-shortcodes. Example usage:
*
* $person = [ 'name' => 'John', 'age' => 29 ];
* $human = set_default_atts( [
* 'name' => 'World',
* 'human' => true,
* 'location' => 'USA',
* 'age' => null
* ], $daniel );
* print_r( $human ); // Result: [ 'name' => 'John', 'human' => true, 'location' => 'USA', 'age' => 29 ];
*
* @param array $pairs Entire list of supported attributes and their defaults.
* @param array $atts User defined attributes in shortcode tag.
* @return array Combined and filtered attribute list.
* @since 1.0.0
*/
public static function set_default_atts( $pairs, $atts ) {
$atts = (array) $atts;
$result = array();
foreach ($pairs as $name => $default) {
if ( array_key_exists($name, $atts) ) {
$result[$name] = $atts[$name];
} else {
$result[$name] = $default;
}
}
return $result;
}
}