Nginx Helper - Version 2.0.0

Version Description

  • Fix typo causing failure to purge on trashed comment. #159 - by jinschoi
  • Refactor Plugin structure and remove unused code. Initial code by chandrapatel, #153 - by jinschoi,
  • Run phpcs and fix warning. #158
  • Make compatible with EasyEngine v4.
Download this release

Release Info

Developer rahulsprajapati
Plugin Icon 128x128 Nginx Helper
Version 2.0.0
Comparing to
See all releases

Code changes from version 1.9.12 to 2.0.0

admin/class-fastcgi-purger.php ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The admin-specific functionality of the plugin.
4
+ *
5
+ * @link https://rtcamp.com/nginx-helper/
6
+ * @since 2.0.0
7
+ *
8
+ * @package nginx-helper
9
+ * @subpackage nginx-helper/admin
10
+ */
11
+
12
+ /**
13
+ * Description of FastCGI_Purger
14
+ *
15
+ * @package nginx-helper
16
+ * @subpackage nginx-helper/admin
17
+ * @author rtCamp
18
+ */
19
+ class FastCGI_Purger extends Purger {
20
+
21
+ /**
22
+ * Function to purge url.
23
+ *
24
+ * @param string $url URL.
25
+ * @param bool $feed Weather it is feed or not.
26
+ */
27
+ public function purge_url( $url, $feed = true ) {
28
+
29
+ global $nginx_helper_admin;
30
+
31
+ $this->log( '- Purging URL | ' . $url );
32
+
33
+ $parse = wp_parse_url( $url );
34
+
35
+ if ( ! isset( $parse['path'] ) ) {
36
+ $parse['path'] = '';
37
+ }
38
+
39
+ switch ( $nginx_helper_admin->options['purge_method'] ) {
40
+
41
+ case 'unlink_files':
42
+ $_url_purge_base = $parse['scheme'] . '://' . $parse['host'] . $parse['path'];
43
+ $_url_purge = $_url_purge_base;
44
+
45
+ if ( isset( $parse['query'] ) && $parse['query'] !== '' ) {
46
+ $_url_purge .= '?' . $parse['query'];
47
+ }
48
+
49
+ $this->delete_cache_file_for( $_url_purge );
50
+
51
+ if ( $feed ) {
52
+
53
+ $feed_url = rtrim( $_url_purge_base, '/' ) . '/feed/';
54
+ $this->delete_cache_file_for( $feed_url );
55
+ $this->delete_cache_file_for( $feed_url . 'atom/' );
56
+ $this->delete_cache_file_for( $feed_url . 'rdf/' );
57
+
58
+ }
59
+ break;
60
+
61
+ case 'get_request':
62
+ // Go to default case.
63
+ default:
64
+ $_url_purge_base = $parse['scheme'] . '://' . $parse['host'] . '/purge' . $parse['path'];
65
+ $_url_purge = $_url_purge_base;
66
+
67
+ if ( isset( $parse['query'] ) && '' !== $parse['query'] ) {
68
+ $_url_purge .= '?' . $parse['query'];
69
+ }
70
+
71
+ $this->do_remote_get( $_url_purge );
72
+
73
+ if ( $feed ) {
74
+
75
+ $feed_url = rtrim( $_url_purge_base, '/' ) . '/feed/';
76
+ $this->do_remote_get( $feed_url );
77
+ $this->do_remote_get( $feed_url . 'atom/' );
78
+ $this->do_remote_get( $feed_url . 'rdf/' );
79
+
80
+ }
81
+ break;
82
+
83
+ }
84
+
85
+ }
86
+
87
+ /**
88
+ * Function to custom purge urls.
89
+ */
90
+ public function custom_purge_urls() {
91
+
92
+ global $nginx_helper_admin;
93
+
94
+ $parse = wp_parse_url( site_url() );
95
+
96
+ $purge_urls = isset( $nginx_helper_admin->options['purge_url'] ) && ! empty( $nginx_helper_admin->options['purge_url'] ) ?
97
+ explode( "\r\n", $nginx_helper_admin->options['purge_url'] ) : array();
98
+
99
+ /**
100
+ * Allow plugins/themes to modify/extend urls.
101
+ *
102
+ * @param array $purge_urls URLs which needs to be purged.
103
+ * @param bool $wildcard If wildcard in url is allowed or not. default false.
104
+ */
105
+ $purge_urls = apply_filters( 'rt_nginx_helper_purge_urls', $purge_urls, false );
106
+
107
+ switch ( $nginx_helper_admin->options['purge_method'] ) {
108
+
109
+ case 'unlink_files':
110
+ $_url_purge_base = $parse['scheme'] . '://' . $parse['host'];
111
+
112
+ if ( is_array( $purge_urls ) && ! empty( $purge_urls ) ) {
113
+
114
+ foreach ( $purge_urls as $purge_url ) {
115
+
116
+ $purge_url = trim( $purge_url );
117
+
118
+ if ( strpos( $purge_url, '*' ) === false ) {
119
+
120
+ $purge_url = $_url_purge_base . $purge_url;
121
+ $this->log( '- Purging URL | ' . $purge_url );
122
+ $this->delete_cache_file_for( $purge_url );
123
+
124
+ }
125
+
126
+ }
127
+
128
+ }
129
+ break;
130
+
131
+ case 'get_request':
132
+ // Go to default case.
133
+ default:
134
+ $_url_purge_base = $parse['scheme'] . '://' . $parse['host'] . '/purge';
135
+
136
+ if ( is_array( $purge_urls ) && ! empty( $purge_urls ) ) {
137
+
138
+ foreach ( $purge_urls as $purge_url ) {
139
+
140
+ $purge_url = trim( $purge_url );
141
+
142
+ if ( strpos( $purge_url, '*' ) === false ) {
143
+
144
+ $purge_url = $_url_purge_base . $purge_url;
145
+ $this->log( '- Purging URL | ' . $purge_url );
146
+ $this->do_remote_get( $purge_url );
147
+
148
+ }
149
+
150
+ }
151
+
152
+ }
153
+ break;
154
+
155
+ }
156
+
157
+ }
158
+
159
+ /**
160
+ * Purge everything.
161
+ */
162
+ public function purge_all() {
163
+
164
+ $this->unlink_recursive( RT_WP_NGINX_HELPER_CACHE_PATH, false );
165
+ $this->log( '* * * * *' );
166
+ $this->log( '* Purged Everything!' );
167
+ $this->log( '* * * * *' );
168
+
169
+ }
170
+
171
+ }
admin/class-nginx-helper-admin.php ADDED
@@ -0,0 +1,694 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The admin-specific functionality of the plugin.
4
+ *
5
+ * @link https://rtcamp.com/nginx-helper/
6
+ * @since 2.0.0
7
+ *
8
+ * @package nginx-helper
9
+ * @subpackage nginx-helper/admin
10
+ */
11
+
12
+ /**
13
+ * The admin-specific functionality of the plugin.
14
+ *
15
+ * Defines the plugin name, version, and two examples hooks for how to
16
+ * enqueue the admin-specific stylesheet and JavaScript.
17
+ *
18
+ * @package nginx-helper
19
+ * @subpackage nginx-helper/admin
20
+ * @author rtCamp
21
+ */
22
+ class Nginx_Helper_Admin {
23
+
24
+ /**
25
+ * The ID of this plugin.
26
+ *
27
+ * @since 2.0.0
28
+ * @access private
29
+ * @var string $plugin_name The ID of this plugin.
30
+ */
31
+ private $plugin_name;
32
+
33
+ /**
34
+ * The version of this plugin.
35
+ *
36
+ * @since 2.0.0
37
+ * @access private
38
+ * @var string $version The current version of this plugin.
39
+ */
40
+ private $version;
41
+
42
+ /**
43
+ * Various settings tabs.
44
+ *
45
+ * @since 2.0.0
46
+ * @access private
47
+ * @var string $settings_tabs Various settings tabs.
48
+ */
49
+ private $settings_tabs;
50
+
51
+ /**
52
+ * Purge options.
53
+ *
54
+ * @since 2.0.0
55
+ * @access public
56
+ * @var string $options Purge options.
57
+ */
58
+ public $options;
59
+
60
+ /**
61
+ * WP-CLI Command.
62
+ *
63
+ * @since 2.0.0
64
+ * @access public
65
+ * @var string $options WP-CLI Command.
66
+ */
67
+ const WP_CLI_COMMAND = 'nginx-helper';
68
+
69
+ /**
70
+ * Initialize the class and set its properties.
71
+ *
72
+ * @since 2.0.0
73
+ * @param string $plugin_name The name of this plugin.
74
+ * @param string $version The version of this plugin.
75
+ */
76
+ public function __construct( $plugin_name, $version ) {
77
+
78
+ $this->plugin_name = $plugin_name;
79
+ $this->version = $version;
80
+
81
+ /**
82
+ * Define settings tabs
83
+ */
84
+ $this->settings_tabs = apply_filters(
85
+ 'rt_nginx_helper_settings_tabs', array(
86
+ 'general' => array(
87
+ 'menu_title' => __( 'General', 'nginx-helper' ),
88
+ 'menu_slug' => 'general',
89
+ ),
90
+ 'support' => array(
91
+ 'menu_title' => __( 'Support', 'nginx-helper' ),
92
+ 'menu_slug' => 'support',
93
+ ),
94
+ )
95
+ );
96
+
97
+ $this->options = $this->nginx_helper_settings();
98
+
99
+ }
100
+
101
+ /**
102
+ * Register the stylesheets for the admin area.
103
+ *
104
+ * @since 2.0.0
105
+ *
106
+ * @param string $hook The current admin page.
107
+ */
108
+ public function enqueue_styles( $hook ) {
109
+
110
+ /**
111
+ * This function is provided for demonstration purposes only.
112
+ *
113
+ * An instance of this class should be passed to the run() function
114
+ * defined in Nginx_Helper_Loader as all of the hooks are defined
115
+ * in that particular class.
116
+ *
117
+ * The Nginx_Helper_Loader will then create the relationship
118
+ * between the defined hooks and the functions defined in this
119
+ * class.
120
+ */
121
+
122
+ if ( 'settings_page_nginx' !== $hook ) {
123
+ return;
124
+ }
125
+
126
+ wp_enqueue_style( $this->plugin_name . '-icons', plugin_dir_url( __FILE__ ) . 'icons/css/nginx-fontello.css', array(), $this->version, 'all' );
127
+ wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/nginx-helper-admin.css', array(), $this->version, 'all' );
128
+
129
+ }
130
+
131
+ /**
132
+ * Register the JavaScript for the admin area.
133
+ *
134
+ * @since 2.0.0
135
+ *
136
+ * @param string $hook The current admin page.
137
+ */
138
+ public function enqueue_scripts( $hook ) {
139
+
140
+ /**
141
+ * This function is provided for demonstration purposes only.
142
+ *
143
+ * An instance of this class should be passed to the run() function
144
+ * defined in Nginx_Helper_Loader as all of the hooks are defined
145
+ * in that particular class.
146
+ *
147
+ * The Nginx_Helper_Loader will then create the relationship
148
+ * between the defined hooks and the functions defined in this
149
+ * class.
150
+ */
151
+
152
+ if ( 'settings_page_nginx' !== $hook ) {
153
+ return;
154
+ }
155
+
156
+ wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/nginx-helper-admin.js', array( 'jquery' ), $this->version, false );
157
+
158
+ }
159
+
160
+ /**
161
+ * Add admin menu.
162
+ *
163
+ * @since 2.0.0
164
+ */
165
+ public function nginx_helper_admin_menu() {
166
+
167
+ if ( is_multisite() ) {
168
+
169
+ add_submenu_page(
170
+ 'settings.php',
171
+ __( 'Nginx Helper', 'nginx-helper' ),
172
+ __( 'Nginx Helper', 'nginx-helper' ),
173
+ 'manage_options',
174
+ 'nginx',
175
+ array( &$this, 'nginx_helper_setting_page' )
176
+ );
177
+
178
+ } else {
179
+
180
+ add_submenu_page(
181
+ 'options-general.php',
182
+ __( 'Nginx Helper', 'nginx-helper' ),
183
+ __( 'Nginx Helper', 'nginx-helper' ),
184
+ 'manage_options',
185
+ 'nginx',
186
+ array( &$this, 'nginx_helper_setting_page' )
187
+ );
188
+
189
+ }
190
+
191
+ }
192
+
193
+ /**
194
+ * Function to add toolbar purge link.
195
+ *
196
+ * @param object $wp_admin_bar Admin bar object.
197
+ */
198
+ public function nginx_helper_toolbar_purge_link( $wp_admin_bar ) {
199
+
200
+ if ( ! current_user_can( 'manage_options' ) ) {
201
+ return;
202
+ }
203
+
204
+ $purge_url = add_query_arg(
205
+ array(
206
+ 'nginx_helper_action' => 'purge',
207
+ 'nginx_helper_urls' => 'all',
208
+ )
209
+ );
210
+
211
+ $nonced_url = wp_nonce_url( $purge_url, 'nginx_helper-purge_all' );
212
+
213
+ $wp_admin_bar->add_menu(
214
+ array(
215
+ 'id' => 'nginx-helper-purge-all',
216
+ 'title' => __( 'Purge Cache', 'nginx-helper' ),
217
+ 'href' => $nonced_url,
218
+ 'meta' => array( 'title' => __( 'Purge Cache', 'nginx-helper' ) ),
219
+ )
220
+ );
221
+
222
+ }
223
+
224
+ /**
225
+ * Display settings.
226
+ *
227
+ * @global $string $pagenow Contain current admin page.
228
+ *
229
+ * @since 2.0.0
230
+ */
231
+ public function nginx_helper_setting_page() {
232
+ include plugin_dir_path(__FILE__ ) . 'partials/nginx-helper-admin-display.php';
233
+ }
234
+
235
+ /**
236
+ * Default settings.
237
+ *
238
+ * @since 2.0.0
239
+ * @return array
240
+ */
241
+ public function nginx_helper_default_settings() {
242
+
243
+ return array(
244
+ 'enable_purge' => 0,
245
+ 'cache_method' => 'enable_fastcgi',
246
+ 'purge_method' => 'get_request',
247
+ 'enable_map' => 0,
248
+ 'enable_log' => 0,
249
+ 'log_level' => 'INFO',
250
+ 'log_filesize' => '5',
251
+ 'enable_stamp' => 0,
252
+ 'purge_homepage_on_edit' => 1,
253
+ 'purge_homepage_on_del' => 1,
254
+ 'purge_archive_on_edit' => 1,
255
+ 'purge_archive_on_del' => 1,
256
+ 'purge_archive_on_new_comment' => 0,
257
+ 'purge_archive_on_deleted_comment' => 0,
258
+ 'purge_page_on_mod' => 1,
259
+ 'purge_page_on_new_comment' => 1,
260
+ 'purge_page_on_deleted_comment' => 1,
261
+ 'redis_hostname' => '127.0.0.1',
262
+ 'redis_port' => '6379',
263
+ 'redis_prefix' => 'nginx-cache:',
264
+ 'purge_url' => '',
265
+ );
266
+
267
+ }
268
+
269
+ /**
270
+ * Get settings.
271
+ *
272
+ * @since 2.0.0
273
+ */
274
+ public function nginx_helper_settings() {
275
+
276
+ $options = get_site_option( 'rt_wp_nginx_helper_options', array( 'redis_hostname' => '127.0.0.1', 'redis_port' => '6379', 'redis_prefix' => 'nginx-cache:' ) );
277
+
278
+ $data = wp_parse_args(
279
+ $options,
280
+ $this->nginx_helper_default_settings()
281
+ );
282
+
283
+ $is_redis_enabled = (
284
+ defined( 'RT_WP_NGINX_HELPER_REDIS_HOSTNAME' ) &&
285
+ defined( 'RT_WP_NGINX_HELPER_REDIS_PORT' ) &&
286
+ defined( 'RT_WP_NGINX_HELPER_REDIS_PREFIX' )
287
+ );
288
+
289
+ if ( ! $is_redis_enabled ) {
290
+ return $data;
291
+ }
292
+
293
+ $data['redis_enabled_by_constant'] = $is_redis_enabled;
294
+ $data['enable_purge'] = $is_redis_enabled;
295
+ $data['cache_method'] = 'enable_redis';
296
+ $data['redis_hostname'] = RT_WP_NGINX_HELPER_REDIS_HOSTNAME;
297
+ $data['redis_port'] = RT_WP_NGINX_HELPER_REDIS_PORT;
298
+ $data['redis_prefix'] = RT_WP_NGINX_HELPER_REDIS_PREFIX;
299
+
300
+ return $data;
301
+
302
+ }
303
+
304
+ /**
305
+ * Nginx helper setting link function.
306
+ *
307
+ * @param array $links links.
308
+ *
309
+ * @return mixed
310
+ */
311
+ public function nginx_helper_settings_link( $links ) {
312
+
313
+ if ( is_network_admin() ) {
314
+ $setting_page = 'settings.php';
315
+ } else {
316
+ $setting_page = 'options-general.php';
317
+ }
318
+
319
+ $settings_link = '<a href="' . admin_url( $setting_page . '?page=nginx' ) . '">' . __( 'Settings', 'nginx-helper' ) . '</a>';
320
+ array_unshift( $links, $settings_link );
321
+
322
+ return $links;
323
+
324
+ }
325
+
326
+ /**
327
+ * Retrieve the asset path.
328
+ *
329
+ * @since 2.0.0
330
+ * @return string asset path of the plugin.
331
+ */
332
+ public function functional_asset_path() {
333
+
334
+ $log_path = WP_CONTENT_DIR . '/uploads/nginx-helper/';
335
+
336
+ return apply_filters( 'nginx_asset_path', $log_path );
337
+
338
+ }
339
+
340
+ /**
341
+ * Retrieve the asset url.
342
+ *
343
+ * @since 2.0.0
344
+ * @return string asset url of the plugin.
345
+ */
346
+ public function functional_asset_url() {
347
+
348
+ $log_url = WP_CONTENT_URL . '/uploads/nginx-helper/';
349
+
350
+ return apply_filters( 'nginx_asset_url', $log_url );
351
+
352
+ }
353
+
354
+ /**
355
+ * Get latest news.
356
+ *
357
+ * @since 2.0.0
358
+ */
359
+ public function nginx_helper_get_feeds() {
360
+
361
+ // Get RSS Feed(s).
362
+ require_once ABSPATH . WPINC . '/feed.php';
363
+
364
+ $maxitems = 0;
365
+ $rss_items = array();
366
+
367
+ // Get a SimplePie feed object from the specified feed source.
368
+ $rss = fetch_feed( 'https://rtcamp.com/blog/feed/' );
369
+
370
+ if ( ! is_wp_error( $rss ) ) { // Checks that the object is created correctly.
371
+
372
+ // Figure out how many total items there are, but limit it to 5.
373
+ $maxitems = $rss->get_item_quantity( 5 );
374
+ // Build an array of all the items, starting with element 0 (first element).
375
+ $rss_items = $rss->get_items( 0, $maxitems );
376
+
377
+ }
378
+ ?>
379
+ <ul role="list">
380
+ <?php
381
+ if ( 0 === $maxitems ) {
382
+ echo '<li role="listitem">' . esc_html_e( 'No items', 'nginx-helper' ) . '.</li>';
383
+ } else {
384
+
385
+ // Loop through each feed item and display each item as a hyperlink.
386
+ foreach ( $rss_items as $item ) {
387
+ ?>
388
+ <li role="listitem">
389
+ <?php
390
+ echo wp_kses(
391
+ sprintf(
392
+ '<a href="%1$s" title="%2$s">%3$s</a>',
393
+ esc_url( $item->get_permalink() ), esc_attr__( 'Posted ', 'nginx-helper' ) . esc_attr( $item->get_date( 'j F Y | g:i a' ) ), esc_html( $item->get_title() )
394
+ ),
395
+ array( 'strong' => array(), 'a' => array( 'href' => array(), 'title' => array() ) )
396
+ );
397
+ ?>
398
+ </li>
399
+ <?php
400
+ }
401
+
402
+ }
403
+ ?>
404
+ </ul>
405
+ <?php
406
+ die();
407
+
408
+ }
409
+
410
+ /**
411
+ * Add time stamps in html.
412
+ */
413
+ public function add_timestamps() {
414
+
415
+ if ( is_admin() || (int) $this->options['enable_purge'] !== 1 || (int) $this->options['enable_stamp'] !== 1 ) {
416
+ return;
417
+ }
418
+
419
+ foreach ( headers_list() as $header ) {
420
+ list( $key, $value ) = explode( ':', $header, 2 );
421
+ if ( 'Content-Type' === $key && strpos( trim( $value ), 'text/html' ) !== 0 ) {
422
+ return;
423
+ }
424
+ if ( 'Content-Type' === $key ) {
425
+ break;
426
+ }
427
+ }
428
+
429
+ /**
430
+ * Don't add timestamp if run from ajax, cron or wpcli.
431
+ */
432
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
433
+ return;
434
+ }
435
+
436
+ if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
437
+ return;
438
+ }
439
+
440
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
441
+ return;
442
+ }
443
+
444
+ $timestamps = "\n<!--" .
445
+ 'Cached using Nginx-Helper on ' . current_time( 'mysql' ) . '. ' .
446
+ 'It took ' . get_num_queries() . ' queries executed in ' . timer_stop() . ' seconds.' .
447
+ "-->\n" .
448
+ '<!--Visit http://wordpress.org/extend/plugins/nginx-helper/faq/ for more details-->';
449
+
450
+ echo wp_kses( $timestamps, array() );
451
+
452
+ }
453
+
454
+ /**
455
+ * Get map
456
+ *
457
+ * @global object $wpdb
458
+ *
459
+ * @return string
460
+ */
461
+ public function get_map() {
462
+
463
+ if ( ! $this->options['enable_map'] ) {
464
+ return;
465
+ }
466
+
467
+ if ( is_multisite() ) {
468
+
469
+ global $wpdb;
470
+
471
+ $rt_all_blogs = $wpdb->get_results(
472
+ $wpdb->prepare(
473
+ 'SELECT blog_id, domain, path FROM ' . $wpdb->blogs . " WHERE site_id = %d AND archived = '0' AND mature = '0' AND spam = '0' AND deleted = '0'",
474
+ $wpdb->siteid
475
+ )
476
+ );
477
+
478
+ $wpdb->dmtable = $wpdb->base_prefix . 'domain_mapping';
479
+
480
+ $rt_domain_map_sites = '';
481
+
482
+ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->dmtable}'" ) === $wpdb->dmtable ) { // phpcs:ignore
483
+ $rt_domain_map_sites = $wpdb->get_results( "SELECT blog_id, domain FROM {$wpdb->dmtable} ORDER BY id DESC" );
484
+ }
485
+
486
+ $rt_nginx_map = '';
487
+ $rt_nginx_map_array = array();
488
+
489
+ if ( $rt_all_blogs ) {
490
+
491
+ foreach ( $rt_all_blogs as $blog ) {
492
+
493
+ if ( 'yes' === SUBDOMAIN_INSTALL ) {
494
+ $rt_nginx_map_array[ $blog->domain ] = $blog->blog_id;
495
+ } else {
496
+
497
+ if ( 1 !== $blog->blog_id ) {
498
+ $rt_nginx_map_array[ $blog->path ] = $blog->blog_id;
499
+ }
500
+
501
+ }
502
+
503
+ }
504
+
505
+ }
506
+
507
+ if ( $rt_domain_map_sites ) {
508
+
509
+ foreach ( $rt_domain_map_sites as $site ) {
510
+ $rt_nginx_map_array[ $site->domain ] = $site->blog_id;
511
+ }
512
+
513
+ }
514
+
515
+ foreach ( $rt_nginx_map_array as $domain => $domain_id ) {
516
+ $rt_nginx_map .= "\t" . $domain . "\t" . $domain_id . ";\n";
517
+ }
518
+
519
+ return $rt_nginx_map;
520
+
521
+ }
522
+
523
+ }
524
+
525
+ /**
526
+ * Update map
527
+ */
528
+ public function update_map() {
529
+
530
+ if ( is_multisite() ) {
531
+
532
+ $rt_nginx_map = $this->get_map();
533
+
534
+ if ( $fp = fopen( $this->functional_asset_path() . 'map.conf', 'w+' ) ) {
535
+ fwrite( $fp, $rt_nginx_map );
536
+ fclose( $fp );
537
+ }
538
+
539
+ }
540
+
541
+ }
542
+
543
+ /**
544
+ * Purge url when post status is changed.
545
+ *
546
+ * @global string $blog_id Blog id.
547
+ * @global object $nginx_purger Nginx purger variable.
548
+ *
549
+ * @param string $new_status New status.
550
+ * @param string $old_status Old status.
551
+ * @param object $post Post object.
552
+ */
553
+ public function set_future_post_option_on_future_status( $new_status, $old_status, $post ) {
554
+
555
+ global $blog_id, $nginx_purger;
556
+
557
+ if ( ! $this->options['enable_purge'] ) {
558
+ return;
559
+ }
560
+
561
+ $purge_status = array( 'publish', 'future' );
562
+
563
+ if ( in_array( $old_status, $purge_status, true ) || in_array( $new_status, $purge_status, true ) ) {
564
+
565
+ $nginx_purger->log( 'Purge post on transition post STATUS from ' . $old_status . ' to ' . $new_status );
566
+ $nginx_purger->purge_post( $post->ID );
567
+
568
+ }
569
+
570
+ if (
571
+ 'future' === $new_status && $post && 'future' === $post->post_status &&
572
+ (
573
+ ( 'post' === $post->post_type || 'page' === $post->post_type ) ||
574
+ (
575
+ isset( $this->options['custom_post_types_recognized'] ) &&
576
+ in_array( $post->post_type, $this->options['custom_post_types_recognized'], true )
577
+ )
578
+ )
579
+ ) {
580
+
581
+ $nginx_purger->log( 'Set/update future_posts option ( post id = ' . $post->ID . ' and blog id = ' . $blog_id . ' )' );
582
+ $this->options['future_posts'][ $blog_id ][ $post->ID ] = strtotime( $post->post_date_gmt ) + 60;
583
+ update_site_option( 'rt_wp_nginx_helper_options', $this->options );
584
+
585
+ }
586
+
587
+ }
588
+
589
+ /**
590
+ * Unset future post option on delete
591
+ *
592
+ * @global string $blog_id Blog id.
593
+ * @global object $nginx_purger Nginx helper object.
594
+ *
595
+ * @param int $post_id Post id.
596
+ */
597
+ public function unset_future_post_option_on_delete( $post_id ) {
598
+
599
+ global $blog_id, $nginx_purger;
600
+
601
+ if (
602
+ ! $this->options['enable_purge'] ||
603
+ empty( $this->options['future_posts'] ) ||
604
+ empty( $this->options['future_posts'][ $blog_id ] ) ||
605
+ empty( isset( $this->options['future_posts'][ $blog_id ][ $post_id ] ) ) ||
606
+ wp_is_post_revision( $post_id )
607
+ ) {
608
+ return;
609
+ }
610
+
611
+ $nginx_purger->log( 'Unset future_posts option ( post id = ' . $post_id . ' and blog id = ' . $blog_id . ' )' );
612
+
613
+ unset( $this->options['future_posts'][ $blog_id ][ $post_id ] );
614
+
615
+ if ( ! count( $this->options['future_posts'][ $blog_id ] ) ) {
616
+ unset( $this->options['future_posts'][ $blog_id ] );
617
+ }
618
+
619
+ update_site_option( 'rt_wp_nginx_helper_options', $this->options );
620
+ }
621
+
622
+ /**
623
+ * Update map when new blog added in multisite.
624
+ *
625
+ * @global object $nginx_purger Nginx purger class object.
626
+ *
627
+ * @param string $blog_id blog id.
628
+ */
629
+ public function update_new_blog_options( $blog_id ) {
630
+
631
+ global $nginx_purger;
632
+
633
+ $nginx_purger->log( "New site added ( id $blog_id )" );
634
+ $this->update_map();
635
+ $nginx_purger->log( "New site added to nginx map ( id $blog_id )" );
636
+ $helper_options = $this->nginx_helper_default_settings();
637
+ update_blog_option( $blog_id, 'rt_wp_nginx_helper_options', $helper_options );
638
+ $nginx_purger->log( "Default options updated for the new blog ( id $blog_id )" );
639
+
640
+ }
641
+
642
+ /**
643
+ * Purge all urls.
644
+ *
645
+ * @global object $nginx_purger
646
+ */
647
+ public function purge_all() {
648
+
649
+ global $nginx_purger;
650
+
651
+ $method = filter_input( INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING );
652
+
653
+ if ( 'POST' === $method ) {
654
+ $action = filter_input( INPUT_POST, 'nginx_helper_action', FILTER_SANITIZE_STRING );
655
+ } else {
656
+ $action = filter_input( INPUT_GET, 'nginx_helper_action', FILTER_SANITIZE_STRING );
657
+ }
658
+
659
+ if ( empty( $action ) ) {
660
+ return;
661
+ }
662
+
663
+ if ( ! current_user_can( 'manage_options' ) ) {
664
+ wp_die( 'Sorry, you do not have the necessary privileges to edit these options.' );
665
+ }
666
+
667
+ if ( 'done' === $action ) {
668
+
669
+ add_action( 'admin_notices', array( &$this, 'display_notices' ) );
670
+ add_action( 'network_admin_notices', array( &$this, 'display_notices' ) );
671
+ return;
672
+
673
+ }
674
+
675
+ check_admin_referer( 'nginx_helper-purge_all' );
676
+ switch ( $action ) {
677
+ case 'purge':
678
+ $nginx_purger->purge_all();
679
+ break;
680
+ }
681
+
682
+ wp_redirect( esc_url_raw( add_query_arg( array( 'nginx_helper_action' => 'done' ) ) ) );
683
+ exit();
684
+
685
+ }
686
+
687
+ /**
688
+ * Dispay plugin notices.
689
+ */
690
+ public function display_notices() {
691
+ echo '<div class="updated"><p>' . esc_html__( 'Purge initiated', 'nginx-helper' ) . '</p></div>';
692
+ }
693
+
694
+ }
admin/class-phpredis-purger.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The admin-specific functionality of the plugin.
4
+ *
5
+ * @link https://rtcamp.com/nginx-helper/
6
+ * @since 2.0.0
7
+ *
8
+ * @package nginx-helper
9
+ * @subpackage nginx-helper/admin
10
+ */
11
+
12
+ /**
13
+ * Description of PhpRedis_Purger
14
+ *
15
+ * @package nginx-helper
16
+ * @subpackage nginx-helper/admin
17
+ * @author rtCamp
18
+ */
19
+ class PhpRedis_Purger extends Purger {
20
+
21
+ /**
22
+ * PHP Redis api object.
23
+ *
24
+ * @since 2.0.0
25
+ * @access public
26
+ * @var string $redis_object PHP Redis api object.
27
+ */
28
+ public $redis_object;
29
+
30
+ /**
31
+ * Initialize the class and set its properties.
32
+ *
33
+ * @since 2.0.0
34
+ */
35
+ public function __construct() {
36
+
37
+ global $nginx_helper_admin;
38
+
39
+ try {
40
+
41
+ $this->redis_object = new Redis();
42
+ $this->redis_object->connect(
43
+ $nginx_helper_admin->options['redis_hostname'],
44
+ $nginx_helper_admin->options['redis_port'],
45
+ 5
46
+ );
47
+
48
+ } catch ( Exception $e ) {
49
+ $this->log( $e->getMessage(), 'ERROR' );
50
+ }
51
+
52
+ }
53
+
54
+ /**
55
+ * Purge all cache.
56
+ */
57
+ public function purge_all() {
58
+
59
+ global $nginx_helper_admin;
60
+
61
+ $prefix = trim( $nginx_helper_admin->options['redis_prefix'] );
62
+
63
+ $this->log( '* * * * *' );
64
+
65
+ // If Purge Cache link click from network admin then purge all.
66
+ if ( is_network_admin() ) {
67
+
68
+ $total_keys_purged = $this->delete_keys_by_wildcard( $prefix . '*' );
69
+ $this->log( '* Purged Everything! * ' );
70
+
71
+ } else { // Else purge only site specific cache.
72
+
73
+ $parse = wp_parse_url( get_home_url() );
74
+ $parse['path'] = empty( $parse['path'] ) ? '/' : $parse['path'];
75
+ $total_keys_purged = $this->delete_keys_by_wildcard( $prefix . $parse['scheme'] . 'GET' . $parse['host'] . $parse['path'] . '*' );
76
+ $this->log( '* ' . get_home_url() . ' Purged! * ' );
77
+
78
+ }
79
+
80
+ if ( $total_keys_purged ) {
81
+ $this->log( "Total {$total_keys_purged} urls purged." );
82
+ } else {
83
+ $this->log( 'No Cache found.' );
84
+ }
85
+
86
+ $this->log( '* * * * *' );
87
+
88
+ }
89
+
90
+ /**
91
+ * Purge url.
92
+ *
93
+ * @param string $url URL to purge.
94
+ * @param bool $feed Feed or not.
95
+ */
96
+ public function purge_url( $url, $feed = true ) {
97
+
98
+ global $nginx_helper_admin;
99
+
100
+ $parse = wp_parse_url( $url );
101
+
102
+ if ( ! isset( $parse['path'] ) ) {
103
+ $parse['path'] = '';
104
+ }
105
+
106
+ $prefix = $nginx_helper_admin->options['redis_prefix'];
107
+ $_url_purge_base = $prefix . $parse['scheme'] . 'GET' . $parse['host'] . $parse['path'];
108
+ $is_purged = $this->delete_single_key( $_url_purge_base );
109
+
110
+ if ( $is_purged ) {
111
+ $this->log( '- Purged URL | ' . $url );
112
+ } else {
113
+ $this->log( '- Cache Not Found | ' . $url, 'ERROR' );
114
+ }
115
+
116
+ $this->log( '* * * * *' );
117
+
118
+ }
119
+
120
+ /**
121
+ * Custom purge urls.
122
+ */
123
+ public function custom_purge_urls() {
124
+
125
+ global $nginx_helper_admin;
126
+
127
+ $parse = wp_parse_url( site_url() );
128
+ $prefix = $nginx_helper_admin->options['redis_prefix'];
129
+ $_url_purge_base = $prefix . $parse['scheme'] . 'GET' . $parse['host'];
130
+
131
+ $purge_urls = isset( $nginx_helper_admin->options['purge_url'] ) && ! empty( $nginx_helper_admin->options['purge_url'] ) ?
132
+ explode( "\r\n", $nginx_helper_admin->options['purge_url'] ) : array();
133
+
134
+ /**
135
+ * Allow plugins/themes to modify/extend urls.
136
+ *
137
+ * @param array $purge_urls URLs which needs to be purged.
138
+ * @param bool $wildcard If wildcard in url is allowed or not. default true.
139
+ */
140
+ $purge_urls = apply_filters( 'rt_nginx_helper_purge_urls', $purge_urls, true );
141
+
142
+ if ( is_array( $purge_urls ) && ! empty( $purge_urls ) ) {
143
+
144
+ foreach ( $purge_urls as $purge_url ) {
145
+
146
+ $purge_url = trim( $purge_url );
147
+
148
+ if ( strpos( $purge_url, '*' ) === false ) {
149
+
150
+ $purge_url = $_url_purge_base . $purge_url;
151
+ $status = $this->delete_single_key( $purge_url );
152
+
153
+ if ( $status ) {
154
+ $this->log( '- Purge URL | ' . $purge_url );
155
+ } else {
156
+ $this->log( '- Cache Not Found | ' . $purge_url, 'ERROR' );
157
+ }
158
+
159
+ } else {
160
+
161
+ $purge_url = $_url_purge_base . $purge_url;
162
+ $status = $this->delete_keys_by_wildcard( $purge_url );
163
+
164
+ if ( $status ) {
165
+ $this->log( '- Purge Wild Card URL | ' . $purge_url . ' | ' . $status . ' url purged' );
166
+ } else {
167
+ $this->log( '- Cache Not Found | ' . $purge_url, 'ERROR' );
168
+ }
169
+
170
+ }
171
+
172
+ }
173
+
174
+ }
175
+
176
+ }
177
+
178
+ /**
179
+ * Single Key Delete Example
180
+ * e.g. $key can be nginx-cache:httpGETexample.com/
181
+ *
182
+ * @param string $key Key.
183
+ *
184
+ * @return int
185
+ */
186
+ public function delete_single_key( $key ) {
187
+
188
+ try {
189
+ return $this->redis_object->del( $key );
190
+ } catch ( Exception $e ) {
191
+ $this->log( $e->getMessage(), 'ERROR' );
192
+ }
193
+
194
+ }
195
+
196
+ /**
197
+ * Delete Keys by wildcard.
198
+ * e.g. $key can be nginx-cache:httpGETexample.com*
199
+ *
200
+ * Lua Script block to delete multiple keys using wildcard
201
+ * Script will return count i.e. number of keys deleted
202
+ * if return value is 0, that means no matches were found
203
+ *
204
+ * Call redis eval and return value from lua script
205
+ *
206
+ * @param string $pattern pattern.
207
+ *
208
+ * @return mixed
209
+ */
210
+ public function delete_keys_by_wildcard( $pattern ) {
211
+
212
+ // Lua Script.
213
+ $lua = <<<LUA
214
+ local k = 0
215
+ for i, name in ipairs(redis.call('KEYS', KEYS[1]))
216
+ do
217
+ redis.call('DEL', name)
218
+ k = k+1
219
+ end
220
+ return k
221
+ LUA;
222
+
223
+ try {
224
+ return $this->redis_object->eval( $lua, array( $pattern ), 1 );
225
+ } catch ( Exception $e ) {
226
+ $this->log( $e->getMessage(), 'ERROR' );
227
+ }
228
+
229
+ }
230
+
231
+ }
admin/class-predis-purger.php ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The admin-specific functionality of the plugin.
4
+ *
5
+ * @package nginx-helper
6
+ */
7
+
8
+ /**
9
+ * Description of Predis_Purger
10
+ *
11
+ * @package nginx-helper
12
+ * @subpackage nginx-helper/admin
13
+ * @author rtCamp
14
+ */
15
+ class Predis_Purger extends Purger {
16
+
17
+ /**
18
+ * Predis api object.
19
+ *
20
+ * @since 2.0.0
21
+ * @access public
22
+ * @var string $redis_object Predis api object.
23
+ */
24
+ public $redis_object;
25
+
26
+ /**
27
+ * Initialize the class and set its properties.
28
+ *
29
+ * @since 2.0.0
30
+ */
31
+ public function __construct() {
32
+
33
+ global $nginx_helper_admin;
34
+
35
+ if ( ! class_exists( 'Predis\Autoloader' ) ) {
36
+ require_once NGINX_HELPER_BASEPATH . 'admin/predis.php';
37
+ }
38
+
39
+ Predis\Autoloader::register();
40
+
41
+ // redis server parameter.
42
+ $this->redis_object = new Predis\Client(
43
+ array(
44
+ 'host' => $nginx_helper_admin->options['redis_hostname'],
45
+ 'port' => $nginx_helper_admin->options['redis_port'],
46
+ )
47
+ );
48
+
49
+ try {
50
+ $this->redis_object->connect();
51
+ } catch ( Exception $e ) {
52
+ $this->log( $e->getMessage(), 'ERROR' );
53
+ }
54
+
55
+ }
56
+
57
+ /**
58
+ * Purge all.
59
+ */
60
+ public function purge_all() {
61
+
62
+ global $nginx_helper_admin;
63
+
64
+ $prefix = trim( $nginx_helper_admin->options['redis_prefix'] );
65
+
66
+ $this->log( '* * * * *' );
67
+
68
+ // If Purge Cache link click from network admin then purge all.
69
+ if ( is_network_admin() ) {
70
+
71
+ $this->delete_keys_by_wildcard( $prefix . '*' );
72
+ $this->log( '* Purged Everything! * ' );
73
+
74
+ } else { // Else purge only site specific cache.
75
+
76
+ $parse = wp_parse_url( get_home_url() );
77
+ $parse['path'] = empty( $parse['path'] ) ? '/' : $parse['path'];
78
+ $this->delete_keys_by_wildcard( $prefix . $parse['scheme'] . 'GET' . $parse['host'] . $parse['path'] . '*' );
79
+ $this->log( '* ' . get_home_url() . ' Purged! * ' );
80
+
81
+ }
82
+
83
+ $this->log( '* * * * *' );
84
+
85
+ }
86
+
87
+ /**
88
+ * Purge url.
89
+ *
90
+ * @param string $url URL.
91
+ * @param bool $feed Feed or not.
92
+ */
93
+ public function purge_url( $url, $feed = true ) {
94
+
95
+ global $nginx_helper_admin;
96
+
97
+ $this->log( '- Purging URL | ' . $url );
98
+
99
+ $parse = wp_parse_url( $url );
100
+
101
+ if ( ! isset( $parse['path'] ) ) {
102
+ $parse['path'] = '';
103
+ }
104
+
105
+ $prefix = $nginx_helper_admin->options['redis_prefix'];
106
+ $_url_purge_base = $prefix . $parse['scheme'] . 'GET' . $parse['host'] . $parse['path'];
107
+ $this->delete_single_key( $_url_purge_base );
108
+
109
+ }
110
+
111
+ /**
112
+ * Custom purge urls.
113
+ */
114
+ public function custom_purge_urls() {
115
+
116
+ global $nginx_helper_admin;
117
+
118
+ $parse = wp_parse_url( site_url() );
119
+ $prefix = $nginx_helper_admin->options['redis_prefix'];
120
+ $_url_purge_base = $prefix . $parse['scheme'] . 'GET' . $parse['host'];
121
+
122
+ $purge_urls = isset( $nginx_helper_admin->options['purge_url'] ) && ! empty( $nginx_helper_admin->options['purge_url'] ) ?
123
+ explode( "\r\n", $nginx_helper_admin->options['purge_url'] ) : array();
124
+
125
+ /**
126
+ * Allow plugins/themes to modify/extend urls.
127
+ *
128
+ * @param array $purge_urls URLs which needs to be purged.
129
+ * @param bool $wildcard If wildcard in url is allowed or not. default true.
130
+ */
131
+ $purge_urls = apply_filters( 'rt_nginx_helper_purge_urls', $purge_urls, true );
132
+
133
+ if ( is_array( $purge_urls ) && ! empty( $purge_urls ) ) {
134
+
135
+ foreach ( $purge_urls as $purge_url ) {
136
+
137
+ $purge_url = trim( $purge_url );
138
+
139
+ if ( strpos( $purge_url, '*' ) === false ) {
140
+
141
+ $purge_url = $_url_purge_base . $purge_url;
142
+ $status = $this->delete_single_key( $purge_url );
143
+ if ( $status ) {
144
+ $this->log( '- Purge URL | ' . $purge_url );
145
+ } else {
146
+ $this->log( '- Not Found | ' . $purge_url, 'ERROR' );
147
+ }
148
+
149
+ } else {
150
+
151
+ $purge_url = $_url_purge_base . $purge_url;
152
+ $status = $this->delete_keys_by_wildcard( $purge_url );
153
+
154
+ if ( $status ) {
155
+ $this->log( '- Purge Wild Card URL | ' . $purge_url . ' | ' . $status . ' url purged' );
156
+ } else {
157
+ $this->log( '- Not Found | ' . $purge_url, 'ERROR' );
158
+ }
159
+
160
+ }
161
+
162
+ }
163
+
164
+ }
165
+
166
+ }
167
+
168
+ /**
169
+ * Single Key Delete Example
170
+ * e.g. $key can be nginx-cache:httpGETexample.com/
171
+ *
172
+ * @param string $key Key to delete cache.
173
+ *
174
+ * @return mixed
175
+ */
176
+ public function delete_single_key( $key ) {
177
+
178
+ try {
179
+ return $this->redis_object->executeRaw( array( 'DEL', $key ) );
180
+ } catch ( Exception $e ) {
181
+ $this->log( $e->getMessage(), 'ERROR' );
182
+ }
183
+
184
+ }
185
+
186
+ /**
187
+ * Delete Keys by wildcard.
188
+ * e.g. $key can be nginx-cache:httpGETexample.com*
189
+ *
190
+ * Lua Script block to delete multiple keys using wildcard
191
+ * Script will return count i.e. number of keys deleted
192
+ * if return value is 0, that means no matches were found
193
+ *
194
+ * Call redis eval and return value from lua script
195
+ *
196
+ * @param string $pattern Pattern.
197
+ *
198
+ * @return mixed
199
+ */
200
+ public function delete_keys_by_wildcard( $pattern ) {
201
+
202
+ // Lua Script.
203
+ $lua = <<<LUA
204
+ local k = 0
205
+ for i, name in ipairs(redis.call('KEYS', KEYS[1]))
206
+ do
207
+ redis.call('DEL', name)
208
+ k = k+1
209
+ end
210
+ return k
211
+ LUA;
212
+
213
+ try {
214
+ return $this->redis_object->eval( $lua, 1, $pattern );
215
+ } catch ( Exception $e ) {
216
+ $this->log( $e->getMessage(), 'ERROR' );
217
+ }
218
+
219
+ }
220
+
221
+ }
admin/class-purger.php ADDED
@@ -0,0 +1,1164 @@