PluginProbe
Object Cache 4 everyone / trunk
Object Cache 4 everyone vtrunk
2.3.3 trunk 2.3 2.3.1 2.3.2
object-cache-4-everyone / object-cache-4-everyone.php

object-cache-4-everyone.php in Object Cache 4 everyone trunk, at object-cache-4-everyone.php

353 lines 15.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Plugin Name: Object Cache 4 everyone
5 * Description: Memcached or disk backend support for the WP Object Cache. Memcached server running and PHP Memcached class needed for better performance. No configuration needed, runs automatically
6 * Plugin URI: https://wordpress.org/plugins/object-cache-4-everyone
7 * Author: fpuenteonline
8 * Version: 2.3.3
9 * Author URI: https://twitter.com/fpuenteonline
10 * License: GPLv2 or later
11 * License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12 *
13 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License version 2, as published by the Free Software Foundation. You may NOT assume
15 * that you can use any other version of the GPL.
16 *
17 */
18
19 if (!defined('ABSPATH')) {
20 exit; // Exit if accessed directly.
21 }
22
23 //Delete object-cache.php
24 include_once 'oc4-deactivation.php';
25 register_deactivation_hook(__FILE__, 'oc4everyone_deactivation');
26
27 // First install.
28 if (!function_exists('oc4everyone_plugins_loaded_activation')) {
29 function oc4everyone_admin_notices_no_class_exists()
30 {
31 if (defined('OC4EVERYONE_DISABLE_DISK_CACHE') && OC4EVERYONE_DISABLE_DISK_CACHE) {
32 echo '<div class="notice notice-warning is-dismissible"><p><strong>Object Cache 4 everyone</strong> ' . esc_html__('needs PHP Memcached class installed for better performance.', 'object-cache-4-everyone') . '</p></div>';
33 if (defined('WP_DEBUG') && WP_DEBUG) {
34 error_log('Object Cache 4 everyone::needs PHP Memcached class installed for better performance.');
35 }
36 } else {
37 echo '<div class="notice notice-warning is-dismissible"><p><strong>Object Cache 4 everyone</strong> ' . esc_html__('needs PHP Memcached class installed for better performance. Running disk support instead.', 'object-cache-4-everyone') . '</p></div>';
38 if (defined('WP_DEBUG') && WP_DEBUG) {
39 error_log('Object Cache 4 everyone::needs PHP Memcached class installed for better performance. Running disk support instead.');
40 }
41 }
42 }
43 function oc4everyone_admin_notices_no_server_running()
44 {
45 if (defined('OC4EVERYONE_DISABLE_DISK_CACHE') && OC4EVERYONE_DISABLE_DISK_CACHE) {
46 echo '<div class="notice notice-warning is-dismissible"><p><strong>Object Cache 4 everyone</strong> ' . esc_html__('needs PHP Memcached class installed for better performance.', 'object-cache-4-everyone') . '</p></div>';
47 if (defined('WP_DEBUG') && WP_DEBUG) {
48 error_log('Object Cache 4 everyone::needs PHP Memcached class installed for better performance.');
49 }
50 } else {
51 echo '<div class="notice notice-warning is-dismissible"><p><strong>Object Cache 4 everyone</strong> ' . esc_html__('needs PHP Memcached class installed for better performance. Running disk support instead.', 'object-cache-4-everyone') . '</p></div>';
52 if (defined('WP_DEBUG') && WP_DEBUG) {
53 error_log('Object Cache 4 everyone::needs PHP Memcached class installed for better performance. Running disk support instead.');
54 }
55 }
56 }
57 function oc4everyone_admin_notices_object()
58 {
59 if (defined('WP_DEBUG') && WP_DEBUG) {
60 error_log('Object Cache 4 everyone::has detected another WP Object Cache instance running. Plugin is deactivated now.');
61 }
62 echo '<div class="notice notice-error is-dismissible"><p><strong>Object Cache 4 everyone</strong> ' . esc_html__('has detected another WP Object Cache instance running. Plugin is deactivated now.', 'object-cache-4-everyone') . '<br/><code>' . esc_html(WP_CONTENT_DIR) . esc_html(DIRECTORY_SEPARATOR) . 'object-cache.php' . '</code></p></div>';
63 if (isset($_GET['activate'])) {
64 unset($_GET['activate']);
65 }
66 }
67 function oc4everyone_admin_notices_ok_disk()
68 {
69 if (defined('WP_DEBUG') && WP_DEBUG) {
70 error_log('Object Cache 4 everyone::running Disk. Thanks for using.');
71 }
72 echo '<div class="notice notice-success is-dismissible"><p>';
73 echo '<strong>Object Cache 4 everyone</strong> ' . esc_html__('running. Thanks for using.', 'object-cache-4-everyone');
74 echo ' ';
75 echo esc_html__('Disk external object cache running', 'object-cache-4-everyone');
76 echo '</p></div>';
77
78 if (isset($_GET['activate'])) {
79 unset($_GET['activate']);
80 }
81 }
82 function oc4everyone_admin_notices_ok_memcached()
83 {
84 if (defined('WP_DEBUG') && WP_DEBUG) {
85 error_log('Object Cache 4 everyone::running Memcached. Thanks for using.');
86 }
87 echo '<div class="notice notice-success is-dismissible"><p>';
88 echo '<strong>Object Cache 4 everyone</strong> ' . esc_html__('running. Thanks for using.', 'object-cache-4-everyone');
89 echo ' ';
90 echo esc_html__('Memcached Server running', 'object-cache-4-everyone');
91 echo '</p></div>';
92
93 if (isset($_GET['activate'])) {
94 unset($_GET['activate']);
95 }
96 }
97 function oc4everyone_admin_init_deactivate_itself()
98 {
99 if (defined('WP_DEBUG') && WP_DEBUG) {
100 error_log('Object Cache 4 everyone::oc4everyone_admin_init_deactivate_itself');
101 }
102 if (isset($_GET['activate'])) {
103 unset($_GET['activate']);
104 }
105 deactivate_plugins(plugin_basename(__FILE__), true);
106 }
107
108 function oc4everyone_plugins_loaded_activation()
109 {
110 if (defined('OC4EVERYONE_PREDEFINED_SERVER')) {
111 return; // Nothing needed, everything works.
112 }
113
114 if (!current_user_can('activate_plugins') || !is_admin()) {
115 return; // Only for admin users and dashboard access.
116 }
117
118 // Check object-cache.php exists.
119 if (file_exists(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'object-cache.php')) {
120 add_action('admin_notices', 'oc4everyone_admin_notices_object', PHP_INT_MAX);
121 add_action('admin_init', 'oc4everyone_admin_init_deactivate_itself', PHP_INT_MAX);
122 return;
123 }
124
125 //Check Memcached class
126 if (class_exists('Memcached')) {
127 //Detecting first Memcached server running
128 $memcached_servers = array(
129 '127.0.0.1:11211',
130 '127.0.0.1:11212',
131 '127.0.0.1:11213',
132 '127.0.0.1:20000',
133 '127.0.0.1:20001'
134 );
135
136 if (defined('OC4EVERYONE_MEMCACHED_SERVER') && is_string(OC4EVERYONE_MEMCACHED_SERVER) && preg_match('/^[A-Za-z0-9.\-]+:[0-9]{1,5}$/', OC4EVERYONE_MEMCACHED_SERVER)) {
137 $memcached_servers = array(OC4EVERYONE_MEMCACHED_SERVER);
138 } else {
139 // Try SG Memcached server first.
140 // Get the account name.
141 if (function_exists('get_current_user') && get_current_user() !== '') {
142 $account_name = get_current_user();
143
144 // Generate the port file path.
145 $port_file_path = "/home/{$account_name}/.SGCache/cache_status";
146 if (file_exists($port_file_path) && is_readable($port_file_path)) {
147 $string = file_get_contents($port_file_path);
148
149 preg_match('#memcache\|\|([0-9]+)#', $string, $matches);
150
151 // Return empty string if there is no match.
152 if (!empty($matches[1])) {
153 // Override current list.
154 $memcached_servers = array(
155 '127.0.0.1:' . $matches[1]
156 );
157 }
158 }
159 }
160 }
161
162 $found_server = '';
163 foreach ($memcached_servers as $server) {
164 $temp_Memcached = new Memcached();
165 list($node, $port) = explode(':', $server);
166 $temp_Memcached->addServer($node, $port);
167
168 // Checks server.
169 $temp_Memcached->getVersion();
170 if ($temp_Memcached->getResultCode() === 0) {
171 $found_server = $server;
172 break;
173 }
174 }
175 if ($found_server !== '') {
176
177 // Memcached + Memcached Server running.
178
179 // Copy object-cache.php + define('OC4EVERYONE_PREDEFINED_SERVER', $server); line.
180 $template = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'object-cache-memcached-template.php');
181
182 $template = "<?php
183 /**
184 * Plugin Name: Object Cache 4 everyone - Memcached
185 * Plugin URI: https://wordpress.org/plugins/object-cache-4-everyone
186 * Author: fpuenteonline
187 * Author URI: https://twitter.com/fpuenteonline
188 *
189 */
190 ?>" . $template;
191 $template .= '//Detected memcached server - ' . gmdate('d/m/Y G:i:s', time()) . PHP_EOL;
192 $template .= 'define(\'OC4EVERYONE_PREDEFINED_SERVER\', ' . var_export($found_server, true) . ');' . PHP_EOL;
193
194 $template .= "if (! defined('WP_CACHE_KEY_SALT')) {" . PHP_EOL;
195 global $wpdb;
196 $template .= "define('WP_CACHE_KEY_SALT', '" . md5(DB_NAME . DB_USER . $wpdb->prefix) . "');" . PHP_EOL;
197 $template .= "}" . PHP_EOL;
198
199 file_put_contents(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'object-cache.php', $template);
200
201 add_action('admin_notices', 'oc4everyone_admin_notices_ok_memcached', PHP_INT_MAX);
202
203 // Flush cache on plugin activation.
204 wp_cache_flush();
205
206 return;
207 } else {
208 // Memcached - Memcached Server not running.
209 add_action('admin_notices', 'oc4everyone_admin_notices_no_server_running', PHP_INT_MAX);
210 }
211 // class_exists('Memcached').
212 } else {
213 add_action('admin_notices', 'oc4everyone_admin_notices_no_class_exists', PHP_INT_MAX);
214 }
215
216 if (defined('OC4EVERYONE_DISABLE_DISK_CACHE') && OC4EVERYONE_DISABLE_DISK_CACHE) {
217 add_action('admin_init', 'oc4everyone_admin_init_deactivate_itself', PHP_INT_MAX);
218 return;
219 }
220
221 // Copy object-cache.php + define('OC4EVERYONE_PREDEFINED_SERVER', ''); line.
222 $template = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'object-cache-disk-template.php');
223
224 $template = "<?php
225 /**
226 * Plugin Name: Object Cache 4 everyone - Disk
227 * Plugin URI: https://wordpress.org/plugins/object-cache-4-everyone
228 * Author: fpuenteonline
229 * Author URI: https://twitter.com/fpuenteonline
230 *
231 */
232 ?>" . $template;
233
234 $template .= '//No detected memcached server - ' . gmdate('d/m/Y G:i:s', time()) . PHP_EOL;
235 $template .= 'define(\'OC4EVERYONE_PREDEFINED_SERVER\', ' . var_export('', true) . ');' . PHP_EOL;
236
237 $template .= "if (! defined('WP_CACHE_KEY_SALT')) {" . PHP_EOL;
238 $template .= "define('WP_CACHE_KEY_SALT', '" . filemtime(__FILE__) . "');" . PHP_EOL;
239 $template .= "}" . PHP_EOL;
240
241 file_put_contents(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'object-cache.php', $template);
242
243 add_action('admin_notices', 'oc4everyone_admin_notices_ok_disk', PHP_INT_MAX);
244
245 // Flush cache on plugin activation.
246 wp_cache_flush();
247 }
248 }
249 add_action('plugins_loaded', 'oc4everyone_plugins_loaded_activation');
250
251
252 function oc4everyone_add_server_info($links_array, $plugin_file_name, $plugin_data, $status)
253 {
254 global $wp_object_cache;
255
256 if (strpos($plugin_file_name, basename(__FILE__)) && class_exists('Memcached') && method_exists($wp_object_cache, 'getStats') && file_exists(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'object-cache.php')) {
257 // Read the stats once; every value below comes from the Memcached server, so it is treated as untrusted and escaped on output.
258 $all_stats = $wp_object_cache->getStats();
259
260 // Extra check.
261 if (!defined('OC4EVERYONE_PREDEFINED_SERVER') || !array_key_exists(OC4EVERYONE_PREDEFINED_SERVER, $all_stats)) {
262 return $links_array;
263 }
264
265 $stats = $all_stats[OC4EVERYONE_PREDEFINED_SERVER];
266
267 $hits = isset($stats['get_hits']) ? (int) $stats['get_hits'] : 0;
268 // Extra check.
269 if ($hits === 0) {
270 return $links_array;
271 }
272 $misses = isset($stats['get_misses']) ? (int) $stats['get_misses'] : 0;
273 $total = $hits + $misses;
274 $found = $total > 0 ? round((100 / $total) * $hits, 2) : 0;
275
276 if (defined('WP_DEBUG') && WP_DEBUG) {
277 error_log('Object Cache 4 everyone::Memcached Server running'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
278 }
279 $nonce = wp_create_nonce('flush_memcached_nonce');
280
281 $uptime = isset($stats['uptime']) ? (int) $stats['uptime'] : 0;
282 $curr_items = isset($stats['curr_items']) ? $stats['curr_items'] : 0;
283 $total_items = isset($stats['total_items']) ? $stats['total_items'] : 0;
284
285 $links_array[] = '<a href="' . esc_url(admin_url('admin-post.php?action=oc4flush_memcached&nonce=' . $nonce)) . '"><strong>' . esc_html__('Flush cache', 'object-cache-4-everyone') . '</strong></a>' .
286 '<br/><br/>' .
287 esc_html__('Memcached Server running:', 'object-cache-4-everyone') . ' <strong><code style="background-color: inherit;">' . esc_html(OC4EVERYONE_PREDEFINED_SERVER) . '</code></strong>' . '<br/>' .
288 esc_html__('Cache Hit Ratio', 'object-cache-4-everyone') . ' <strong><code style="background-color: inherit;">' . esc_html($found) . '%</code></strong>' . '<br/>' .
289 esc_html__('Uptime:', 'object-cache-4-everyone') . ' <strong><code style="background-color: inherit;">' . esc_html(secondsToHumanReadable($uptime)) . '</code></strong>' . '<br/>' .
290 esc_html__('Current Unique Items / Total Items:', 'object-cache-4-everyone') . ' <strong><code style="background-color: inherit;">' . absint($curr_items) . ' / ' . absint($total_items) . '</code></strong>' . '<br/>';
291 }
292
293 return $links_array;
294 }
295 add_filter('plugin_row_meta', 'oc4everyone_add_server_info', PHP_INT_MAX, 4);
296
297
298 add_action('admin_post_oc4flush_memcached', 'oc4flush_memcached');
299 function oc4flush_memcached() {
300 // Authorization: only administrators may flush the cache. The nonce alone is not an authorization check.
301 if (!current_user_can('manage_options')) {
302 wp_die(esc_html__('Access denied.', 'object-cache-4-everyone'), '', array('response' => 403));
303 }
304 if (!class_exists('Memcached')) {
305 wp_die(esc_html__('Failed to flush Memcached server', 'object-cache-4-everyone'));
306 }
307 // Verify the nonce.
308 if (isset($_GET['nonce']) && wp_verify_nonce(sanitize_key($_GET['nonce']), 'flush_memcached_nonce')) {
309 // Flush cache.
310 global $wp_object_cache;
311 $wp_object_cache->flush();
312
313 $memcached = new Memcached();
314 list($node, $port) = explode(':', OC4EVERYONE_PREDEFINED_SERVER);
315 $memcached->addServer($node, $port, PHP_INT_MAX);
316
317 if ($memcached->flush(0)) {
318 if (defined('WP_DEBUG') && WP_DEBUG) {
319 error_log('Object Cache 4 everyone::Memcached server flushed.'); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
320 }
321 wp_redirect(admin_url('plugins.php'));
322 exit;
323 } else {
324 wp_die(esc_html__('Failed to flush Memcached server', 'object-cache-4-everyone'));
325 }
326 } else {
327 wp_die(esc_html__('Nonce verification failed. Access denied.', 'object-cache-4-everyone'));
328 }
329 }
330
331
332 function secondsToHumanReadable($seconds)
333 {
334 $units = array(
335 "D" => 86400,
336 "H" => 3600,
337 "M" => 60,
338 "S" => 1
339 );
340
341 $output = "";
342
343 foreach ($units as $unit => $value) {
344 if ($seconds >= $value) {
345 $numUnits = floor($seconds / $value);
346 $output .= $numUnits . " " . $unit . " ";
347 $seconds %= $value;
348 }
349 }
350
351 return trim($output);
352 }
353