-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathlive-cache.php
More file actions
293 lines (255 loc) · 8.98 KB
/
live-cache.php
File metadata and controls
293 lines (255 loc) · 8.98 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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
<?php
/*
* Handles ajax requests with cached values as early as possible. Uses a queryvar instead of
* standard wp ajax method to allow page caching, refresh the cache every 10 seconds, and to
* process requests as early as possible.
*
* Installation suggestion: Instead of activating this plugin normally, call it from the top
* of the theme's functions.php for even faster response and less load on the server.
* Use: require_once( path/to/plugin/live-cache/live-cache.php' );
* However this will still work when activated normally.
*
* See live-cache-widget.php for a usage sample. Also note how refresh rate is set inside
* sanitize_options() and picked up at the bottom of live-cache.js for a second method.
*/
class Live_Cache {
/**
* Set to false with the 'live_cache_show_options' filter if you want to handle things differently
*
* @var bool
*/
var $show_options;
/**
* Set to false with the 'live_cache_show_options' filter if you want to handle things differently
*
* @var bool
*/
var $show_widget;
/**
* If you lower this value (using the 'live_cache_min_refresh_rate' filter, check minRefresh in live-cache.js
*
* @var int
*/
var $minimum_refresh_rate; // if you lower this here, check minRefresh in live-cache.js
/**
* Data container
*
* @var bool|array
*/
var $data = false;
/**
* Flag whether or not we need to save the cache, since flushing can be expensive.
*
* @var bool
*/
private $needs_save = false;
/**
* Check for live_cache_check on init. If set return cached value
*
* @uses apply_filters()
* @uses add_action()
* @uses add_filter()
*/
public function __construct() {
// Setup default options
$this->show_options = apply_filters( 'live_cache_show_options', true );
$this->show_widget = apply_filters( 'live_cache_show_widget', true );
$this->minimum_refresh_rate = (int) apply_filters( 'live_cache_min_refresh_rate', 60 );
/* By running this check as soon as the class is initialized instead of on action,
* we can skip most of the theme being loaded. ouput and die.
*/
if ( isset( $_SERVER['REQUEST_URI'] ) && strpos( $_SERVER['REQUEST_URI'], 'live_cache_check' ) ) {
header( 'Content-Type: application/json' );
nocache_headers(); //essential for getting date that is used for incrementing the timestamp
echo json_encode( (array) $this->get_cache() );
die();
}
// ok, this was not a live-cache check. so let's set up the rest of the class and let the rest of the theme load.
add_action( 'init', array( $this, 'init' ) );
add_action( 'admin_init', array( $this, 'admin_init' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) );
/* This one is a bit unusual. We are making it possible to plug-in to this plugin by
* reversing the hook and allowing the other plugin to trigger an action that we process.
*/
add_action( 'live_cache_set_value', array( $this, 'live_cache_set_value' ), 10, 2 );
add_filter( 'live_cache_get_value', array( $this, 'live_cache_get_value' ), 10, 2 );
add_action( 'shutdown', array( $this, 'live_cache_persist' ) );
// Demo code and a small widget to make this plug-in do something fresh out of the box
if ( $this->show_widget ) {
require_once( __DIR__ . '/live-cache-widget.php' );
}
}
/**
* Add scripts and localized variables to the admin.
*
* @uses wp_enqueue_script()
* @uses wp_localize_script()
*/
public function wp_enqueue_scripts() {
// embed the javascript file that makes the AJAX request
wp_enqueue_script( 'live-cache', plugin_dir_url( __FILE__ ) . 'live-cache.js', array( 'jquery' ) );
/* pass in the url where we will be checking for updates along with a list of keys to monitor and where
* to put their values. filter live_cache_auto_updates to set a key and selector. see live-cache-widget.php
* for sample usage. wp_localize_script handles output sanitization for us. don't double escape. do verify
* you are passing valid input.
*
* Note: no point in passing a timestamp here. It will get cached and be as out of date as the rest. that is
* fine. we are getting timestamp from http response headers.
*/
wp_localize_script( 'live-cache', 'Live_Cache', array( 'ajaxurl' => get_bloginfo( 'url' ), 'auto_updates' => apply_filters( 'live_cache_auto_updates', array() ) ) );
}
/**
* Initialize rewrite rules.
*
* @uses add_rewrite_rule()
*/
public function init() {
add_rewrite_rule( '^live_cache_check/([\d]+)/?', 'index.php?live_cache_check=$matches[0]', 'top' );
}
/**
* Initialize the admin interface.
*
* @uses register_setting()
* @uses add_settings_section()
* @uses add_settings_field()
*/
public function admin_init() {
if ( $this->show_options ) {
// add refresh rate option to the reading settings page
register_setting( 'reading', 'live_cache_refresh_rate', array( $this, 'sanitize_options' ) ); //live_cache_check includes all of the values we are passing back thru ajax including the refresh rate controled here.
add_settings_section( 'live-cache', '', '__return_false', 'reading' );
add_settings_field( 'refresh_rate', 'Live Cache Refresh Rate', array( $this, 'settings_field_refresh_rate' ), 'reading', 'live-cache' );
}
}
/**
* Store a value in the cache.
*
* @uses sanitize_key()
* @uses sanitize_text_field()
*
* @param string $key Name of the cache key to set.
* @param mixed $value Value to cache.
*/
public function live_cache_set_value( $key, $value ) {
$live_cache = $this->get_cache();
$key = sanitize_key( $key );
// Set value. Create option if necessary.
if ( is_array( $live_cache ) ) {
$live_cache[$key] = sanitize_text_field( $value );
} else {
$live_cache = array( $key => sanitize_text_field( $value ) );
}
$this->data = $live_cache;
$this->needs_save = true;
}
/**
* Retrieve a value from the cache if it exists
*
* @param string $key Cached value to retrieve
* @param null $value Default value to return if a value is not set in the cache.
*
* @return mixed|null
*/
public function live_cache_get_value( $key, $value = null ) {
$live_cache = $this->get_cache();
$key = sanitize_key( $key );
// Get value if available.
if ( isset( $live_cache[ $key ] ) ) {
$value = $live_cache[ $key ];
}
return $value;
}
/**
* Get the Live Cache data either from the advanced cache or the database.
*
* @return bool|array False on failure.
*/
protected function get_cache() {
if ( false === $this->data ) {
$this->data = $this->get_cached_data();
if ( false === $this->data ) {
$this->data = get_option( 'live_cache' );
if ( false === $this->data ) {
$this->data = array();
} else {
$this->set_cached_data();
}
}
}
return $this->data;
}
/**
* Finally save the data in the cache on shutdown (so we only save once).
*/
public function live_cache_persist() {
// If we don't need to save, then skip
if ( ! $this->needs_save ) {
return;
}
// Flush saved data.
delete_option( 'live_cache' );
// Store the data
$this->set_cached_data();
add_option( 'live_cache', $this->data, '', 'no' );
}
/**
* Render the refresh rate settings field.
*/
public function settings_field_refresh_rate() {
$live_cache_refresh_rate = (int) get_option( 'live_cache_refresh_rate' );
if ( $live_cache_refresh_rate < $this->minimum_refresh_rate )
$live_cache_refresh_rate = $this->minimum_refresh_rate;
?>
<input type="text" name="live_cache_refresh_rate" id="live_cache_refresh_rate" class="regular-text" value="<?php echo $live_cache_refresh_rate; ?>" />
<p class="description">Number of seconds between ajax calls. You can set this as low as 60 seconds for live events. Make sure to increase it back, though.</p>
<?php
}
/**
* Sanitize the minimum refresh rate option.
*
* @param int $input
*
* @return int
*/
public function sanitize_options( $input ) {
$new_input = (int) $input;
if ( $new_input < $this->minimum_refresh_rate ) {
$new_input = $this->minimum_refresh_rate;
}
// do live_cache_set_value action - same method that could be used by other plugins that extend this plugin.
do_action( 'live_cache_set_value', 'refresh_rate', $new_input );
return $new_input;
}
/**
* Allow code to turn off the object caching layer of live cache
*
* @return bool
*/
protected function use_object_cache() {
return (bool) apply_filters( 'live_cache_use_object_cache_backend', true );
}
/**
* Get the data from object cache.
*
* If object caching is turned off, this function will simply return false
*
* @return bool|mixed
*/
protected function get_cached_data() {
if ( $this->use_object_cache() ) {
return wp_cache_get( 'live_cache' );
}
return false;
}
/**
* Set the cache data in the object cache (if we're using it)
*
* Also sets the expiration of the cached data to the minimum refresh rate
*/
protected function set_cached_data() {
if ( $this->use_object_cache() ) {
wp_cache_set( 'live_cache', $this->data, '', $this->minimum_refresh_rate );
}
}
}
$live_cache = new Live_Cache();