| 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 |
| 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.') . '</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.') . '</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.') . '</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.') . '</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.') . '<br/><code>' . WP_CONTENT_DIR . 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.'); |
| 74 |
echo ' '; |
| 75 |
echo esc_html__('Disk external object cache running'); |
| 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.'); |
| 89 |
echo ' '; |
| 90 |
echo esc_html__('Memcached Server running'); |
| 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')) { |
| 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 - ' . date('d/m/Y G:i:s', current_time('timestamp', 0)) . PHP_EOL; |
| 192 |
$template .= "define('OC4EVERYONE_PREDEFINED_SERVER', '$found_server');" . PHP_EOL; |
| 193 |
|
| 194 |
$template .= "if (! defined('WP_CACHE_KEY_SALT')) {" . PHP_EOL; |
| 195 |
global $wpdb; |
| 196 |
$template .= "define('WP_CACHE_KEY_SALT', '" . 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 - ' . date('d/m/Y G:i:s', current_time('timestamp', 0)) . PHP_EOL; |
| 235 |
$template .= "define('OC4EVERYONE_PREDEFINED_SERVER', '');" . 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 |
// Extra check. |
| 258 |
if(!defined('OC4EVERYONE_PREDEFINED_SERVER') || !array_key_exists(OC4EVERYONE_PREDEFINED_SERVER, $wp_object_cache->getStats())){ |
| 259 |
return $links_array; |
| 260 |
} |
| 261 |
|
| 262 |
$hits = $wp_object_cache->getStats()[OC4EVERYONE_PREDEFINED_SERVER]['get_hits']; |
| 263 |
// Extra check. |
| 264 |
if($hits == 0) { |
| 265 |
return $links_array; |
| 266 |
} |
| 267 |
$misses = $wp_object_cache->getStats()[OC4EVERYONE_PREDEFINED_SERVER]['get_misses']; |
| 268 |
$total = $hits + $misses; |
| 269 |
$found = @round((100 / $total) * $hits, 2); |
| 270 |
|
| 271 |
if (defined('WP_DEBUG') && WP_DEBUG) { |
| 272 |
error_log('Object Cache 4 everyone::Memcached Server running'); |
| 273 |
} |
| 274 |
$nonce = wp_create_nonce('flush_memcached_nonce'); |
| 275 |
|
| 276 |
$links_array[] = '<a href="' . esc_url(admin_url('admin-post.php?action=oc4flush_memcached&nonce=' . $nonce)) . '"><strong>' . esc_html__('Flush cache') . '</strong></a>' . |
| 277 |
'<br/><br/>' . |
| 278 |
esc_html__('Memcached Server running:') . ' <strong><code style="background-color: inherit;">' . OC4EVERYONE_PREDEFINED_SERVER . '</code></strong>' . '<br/>' . |
| 279 |
esc_html__('Cache Hit Ratio') . ' <strong><code style="background-color: inherit;">' . $found . '%</code></strong>' . '<br/>' . |
| 280 |
esc_html__('Uptime:') . ' <strong><code style="background-color: inherit;">' . secondsToHumanReadable($wp_object_cache->getStats()[OC4EVERYONE_PREDEFINED_SERVER]['uptime']) . '</strong></code>' . '<br/>' . |
| 281 |
esc_html__('Current Unique Items / Total Items:') . ' <strong><code style="background-color: inherit;">' . $wp_object_cache->getStats()[OC4EVERYONE_PREDEFINED_SERVER]['curr_items'] . ' / ' . $wp_object_cache->getStats()[OC4EVERYONE_PREDEFINED_SERVER]['total_items'] . '</strong></code>' . '<br/>'; |
| 282 |
} |
| 283 |
|
| 284 |
return $links_array; |
| 285 |
} |
| 286 |
add_filter('plugin_row_meta', 'oc4everyone_add_server_info', PHP_INT_MAX, 4); |
| 287 |
|
| 288 |
|
| 289 |
add_action('admin_post_oc4flush_memcached', 'oc4flush_memcached'); |
| 290 |
function oc4flush_memcached() { |
| 291 |
if (!class_exists('Memcached')) { |
| 292 |
wp_die(esc_html__('Failed to flush Memcached server')); |
| 293 |
} |
| 294 |
// Verify the nonce. |
| 295 |
if (isset($_GET['nonce']) && wp_verify_nonce(sanitize_key($_GET['nonce']), 'flush_memcached_nonce')) { |
| 296 |
// Flush cache. |
| 297 |
global $wp_object_cache; |
| 298 |
error_log(print_r($wp_object_cache->getStats()[OC4EVERYONE_PREDEFINED_SERVER], true)); |
| 299 |
$wp_object_cache->flush(); |
| 300 |
|
| 301 |
$memcached = new Memcached(); |
| 302 |
list($node, $port) = explode(':', OC4EVERYONE_PREDEFINED_SERVER); |
| 303 |
$memcached->addServer($node, $port, PHP_INT_MAX); |
| 304 |
|
| 305 |
if ($memcached->flush(0)) { |
| 306 |
if (defined('WP_DEBUG') && WP_DEBUG) { |
| 307 |
error_log('Object Cache 4 everyone::Memcached server flushed.'); |
| 308 |
} |
| 309 |
wp_redirect(admin_url('plugins.php')); |
| 310 |
exit; |
| 311 |
} else { |
| 312 |
wp_die(esc_html__('Failed to flush Memcached server')); |
| 313 |
} |
| 314 |
} else { |
| 315 |
wp_die(esc_html__('Nonce verification failed. Access denied.')); |
| 316 |
} |
| 317 |
} |
| 318 |
|
| 319 |
|
| 320 |
function secondsToHumanReadable($seconds) |
| 321 |
{ |
| 322 |
$units = array( |
| 323 |
"D" => 86400, |
| 324 |
"H" => 3600, |
| 325 |
"M" => 60, |
| 326 |
"S" => 1 |
| 327 |
); |
| 328 |
|
| 329 |
$output = ""; |
| 330 |
|
| 331 |
foreach ($units as $unit => $value) { |
| 332 |
if ($seconds >= $value) { |
| 333 |
$numUnits = floor($seconds / $value); |
| 334 |
$output .= $numUnits . " " . $unit . " "; |
| 335 |
$seconds %= $value; |
| 336 |
} |
| 337 |
} |
| 338 |
|
| 339 |
return trim($output); |
| 340 |
} |
| 341 |
|