| 1 |
<?php |
| 2 |
/* |
| 3 |
Plugin Name: ezCache |
| 4 |
Description: 🚀 ezCache 2026 — Lightning-fast WordPress caching with CSS/JS optimization, WebP images, preloading, database cleanup & more. Free & Pro. |
| 5 |
Plugin URI: https://ezcache-wp.com |
| 6 |
Version: 2.5.4 |
| 7 |
Author: uPress |
| 8 |
Author URI: https://www.upress.io |
| 9 |
Text Domain: ezcache |
| 10 |
Domain Path: /languages/ |
| 11 |
License: GPLv2 or later |
| 12 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html |
| 13 |
|
| 14 |
This program is free software; you can redistribute it and/or modify |
| 15 |
it under the terms of the GNU General Public License as published by |
| 16 |
the Free Software Foundation; either version 2 of the License, or |
| 17 |
(at your option) any later version. |
| 18 |
|
| 19 |
This program is distributed in the hope that it will be useful, |
| 20 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 21 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 22 |
GNU General Public License for more details. |
| 23 |
|
| 24 |
You should have received a copy of the GNU General Public License |
| 25 |
along with this program; if not, write to the Free Software |
| 26 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 27 |
*/ |
| 28 |
|
| 29 |
namespace { |
| 30 |
if ( ! defined( 'ABSPATH' ) ) { |
| 31 |
die( 'NO direct access!' ); |
| 32 |
} |
| 33 |
|
| 34 |
// Freemius SDK removed — Pro is unlocked for everyone, no licensing layer. |
| 35 |
define( 'EZCACHE_DIR', __DIR__ ); |
| 36 |
define( 'EZCACHE_FILE', __FILE__ ); |
| 37 |
define( 'EZCACHE_URL', plugin_dir_url( __FILE__ ) ); |
| 38 |
define( 'EZCACHE_BASEBANE', basename( __FILE__ ) ); |
| 39 |
define( 'EZCACHE_VERSION', '2.5.4' ); |
| 40 |
define( 'EZCACHE_SETTINGS_KEY', 'ezcache' ); |
| 41 |
|
| 42 |
register_activation_hook( EZCACHE_FILE, 'upress_ezcache_activation_hook' ); |
| 43 |
register_deactivation_hook( EZCACHE_FILE, 'upress_ezcache_deactivation_hook' ); |
| 44 |
|
| 45 |
function upress_ezcache_activation_hook() { |
| 46 |
$ezcache = Upress\EzCache\Plugin::initialize(); |
| 47 |
$ezcache->activation_hook(); |
| 48 |
} |
| 49 |
|
| 50 |
function upress_ezcache_deactivation_hook() { |
| 51 |
$ezcache = Upress\EzCache\Plugin::initialize(); |
| 52 |
$ezcache->deactivation_hook(); |
| 53 |
} |
| 54 |
} |
| 55 |
|
| 56 |
namespace Upress\EzCache { |
| 57 |
class Plugin { |
| 58 |
private static $instance; |
| 59 |
public $plugin_dir; |
| 60 |
public $plugin_file; |
| 61 |
public $plugin_url; |
| 62 |
public $plugin_basename; |
| 63 |
public $plugin_version; |
| 64 |
public $plugin_settings_key; |
| 65 |
/** @var Cache $ezcache */ |
| 66 |
public $ezcache; |
| 67 |
|
| 68 |
/** |
| 69 |
* @return Plugin |
| 70 |
*/ |
| 71 |
public static function initialize() { |
| 72 |
if ( ! self::$instance ) { |
| 73 |
self::$instance = new self; |
| 74 |
} |
| 75 |
|
| 76 |
return self::$instance; |
| 77 |
} |
| 78 |
|
| 79 |
|
| 80 |
private function __construct() { |
| 81 |
$this->plugin_dir = EZCACHE_DIR; |
| 82 |
$this->plugin_file = EZCACHE_FILE; |
| 83 |
$this->plugin_url = EZCACHE_URL; |
| 84 |
$this->plugin_basename = EZCACHE_BASEBANE; |
| 85 |
$this->plugin_version = EZCACHE_VERSION; |
| 86 |
$this->plugin_settings_key = EZCACHE_SETTINGS_KEY; |
| 87 |
|
| 88 |
$this->load_dependencies(); |
| 89 |
$this->initialize_plugin(); |
| 90 |
} |
| 91 |
|
| 92 |
/** |
| 93 |
* Import required files |
| 94 |
*/ |
| 95 |
protected function load_dependencies() { |
| 96 |
require_once EZCACHE_DIR . '/vendor/autoload.php'; |
| 97 |
} |
| 98 |
|
| 99 |
/** |
| 100 |
* Init all the plugin parts |
| 101 |
*/ |
| 102 |
protected function initialize_plugin() { |
| 103 |
$this->ezcache = Cache::instance(); |
| 104 |
|
| 105 |
add_action( 'init', [ $this, 'load_translation' ] ); |
| 106 |
add_filter( 'cron_schedules', [ $this, 'add_cron_schedules' ] ); |
| 107 |
add_action( 'init', [ $this, 'maybe_repair_installation' ] ); |
| 108 |
|
| 109 |
new RestApi( $this ); |
| 110 |
new Admin( $this ); |
| 111 |
new AdvancedSettingsPage(); |
| 112 |
new Optimizations(); |
| 113 |
Preload::instance(); |
| 114 |
|
| 115 |
// v2.2.0 features |
| 116 |
RedisObjectCache::init(); |
| 117 |
SpeculativeLoading::instance()->register(); |
| 118 |
EarlyHints::instance()->register(); |
| 119 |
CriticalCSS::instance()->register(); |
| 120 |
|
| 121 |
add_action( 'ezcache_clear_expired_cache', [ $this->ezcache, 'clear_expired_cache' ] ); |
| 122 |
add_action( 'ezcache_db_cleanup', function () { |
| 123 |
( new DatabaseOptimizer() )->clean(); |
| 124 |
} ); |
| 125 |
} |
| 126 |
|
| 127 |
function load_translation() { |
| 128 |
$locale = apply_filters( 'plugin_locale', get_locale(), 'ezcache' ); |
| 129 |
load_textdomain( 'ezcache', EZCACHE_DIR . "/languages/ezcache-{$locale}.mo" ); |
| 130 |
} |
| 131 |
|
| 132 |
function get_wp_config_path() { |
| 133 |
if ( file_exists( ABSPATH . 'wp-config.php' ) ) { |
| 134 |
return ABSPATH . 'wp-config.php'; |
| 135 |
} |
| 136 |
|
| 137 |
return dirname( ABSPATH ) . '/wp-config.php'; |
| 138 |
} |
| 139 |
|
| 140 |
function activation_hook() { |
| 141 |
set_transient( 'ezcache_activating', true ); |
| 142 |
|
| 143 |
// copy advanced-cache |
| 144 |
copy( EZCACHE_DIR . '/advanced-cache.php', WP_CONTENT_DIR . '/advanced-cache.php' ); |
| 145 |
|
| 146 |
if ( ! wp_next_scheduled( 'ezcache_clear_expired_cache' ) ) { |
| 147 |
Settings::maybe_update_cronjobs( Settings::get_settings() ); |
| 148 |
} |
| 149 |
Updater::upgrade(); |
| 150 |
|
| 151 |
$this->update_wp_config_const( [ 'WP_CACHE' => true ] ); |
| 152 |
|
| 153 |
$this->ezcache->preload_homepage(); |
| 154 |
|
| 155 |
delete_transient( 'ezcache_activating' ); |
| 156 |
} |
| 157 |
|
| 158 |
function deactivation_hook() { |
| 159 |
set_transient( 'ezcache_deactivating', true ); |
| 160 |
|
| 161 |
// delete advanced-cache |
| 162 |
if ( file_exists( WP_CONTENT_DIR . '/advanced-cache.php' ) ) { |
| 163 |
unlink( WP_CONTENT_DIR . '/advanced-cache.php' ); |
| 164 |
} |
| 165 |
|
| 166 |
if ( wp_next_scheduled( 'ezcache_clear_expired_cache' ) ) { |
| 167 |
wp_clear_scheduled_hook( 'ezcache_clear_expired_cache' ); |
| 168 |
} |
| 169 |
|
| 170 |
delete_site_option( 'ezcache_first_run' ); |
| 171 |
|
| 172 |
$this->update_wp_config_const( [ 'WP_CACHE' => false ] ); |
| 173 |
|
| 174 |
$this->ezcache->clear_cache(); |
| 175 |
|
| 176 |
delete_transient( 'ezcache_deactivating' ); |
| 177 |
} |
| 178 |
|
| 179 |
/** |
| 180 |
* Update the wp-config.php file with the specified values |
| 181 |
* |
| 182 |
* @param array $args Assoc array of key-value, key is the define to update with the value |
| 183 |
*/ |
| 184 |
function update_wp_config_const( $args ) { |
| 185 |
if ( ! is_array( $args ) ) { |
| 186 |
return; |
| 187 |
} |
| 188 |
|
| 189 |
$wp_config_path = $this->get_wp_config_path(); |
| 190 |
|
| 191 |
copy( $wp_config_path, $wp_config_path . '.backup' ); |
| 192 |
|
| 193 |
$contents = file_get_contents( $wp_config_path ); |
| 194 |
$contents = preg_replace( "/\r\n|\r|\n/", "\n", $contents ); // normalize line-breaks |
| 195 |
|
| 196 |
// update wp-config define |
| 197 |
foreach ( $args as $const => $value ) { |
| 198 |
if ( is_string( $value ) ) { |
| 199 |
$value = "'" . str_replace( "'", "\'", $value ) . "'"; |
| 200 |
} elseif ( is_bool( $value ) ) { |
| 201 |
$value = $value ? 'true' : 'false'; // simply casting to string will result in '1' and '' |
| 202 |
} else { |
| 203 |
continue; |
| 204 |
} |
| 205 |
|
| 206 |
if ( preg_match( '/define\s*?\(\s*?[\']' . $const . '[\'"]/', $contents ) ) { |
| 207 |
$contents = preg_replace( '/define\s*?\(\s*?([\'"])' . $const . '\1,\s*(([\'"]).+\3|.+?)\s*\)/', "define( '{$const}', {$value} )", $contents ); |
| 208 |
} else { |
| 209 |
$contents = preg_replace( '/(<\?php)/', "$1\ndefine( '{$const}', {$value} );", $contents ); |
| 210 |
} |
| 211 |
} |
| 212 |
|
| 213 |
if ( "\n" !== PHP_EOL ) { |
| 214 |
// update line-breaks to platform defaults |
| 215 |
$contents = preg_replace( "/\n/", PHP_EOL, $contents ); |
| 216 |
} |
| 217 |
|
| 218 |
file_put_contents( $wp_config_path, trim( $contents ) ); |
| 219 |
|
| 220 |
if ( filesize( $wp_config_path ) <= 0 ) { |
| 221 |
// operation failed, revert the file |
| 222 |
copy( $wp_config_path . '.backup', $wp_config_path ); |
| 223 |
} |
| 224 |
|
| 225 |
unlink( $wp_config_path . '.backup' ); |
| 226 |
} |
| 227 |
|
| 228 |
function add_cron_schedules( $schedules ) { |
| 229 |
if ( ! isset( $schedules['every_10_minutes'] ) ) { |
| 230 |
$schedules['every_10_minutes'] = [ |
| 231 |
'interval' => 600, |
| 232 |
'display' => __( 'Every 10 Minutes', 'ezcache' ), |
| 233 |
]; |
| 234 |
} |
| 235 |
if ( ! isset( $schedules['hourly'] ) ) { |
| 236 |
$schedules['hourly'] = [ |
| 237 |
'interval' => 3600, |
| 238 |
'display' => __( 'Hourly', 'ezcache' ), |
| 239 |
]; |
| 240 |
} |
| 241 |
if ( ! isset( $schedules['every_3_hours'] ) ) { |
| 242 |
$schedules['every_3_hours'] = [ |
| 243 |
'interval' => 10800, |
| 244 |
'display' => __( 'Every 3 Hours', 'ezcache' ), |
| 245 |
]; |
| 246 |
} |
| 247 |
if ( ! isset( $schedules['every_6_hours'] ) ) { |
| 248 |
$schedules['every_6_hours'] = [ |
| 249 |
'interval' => 21600, |
| 250 |
'display' => __( 'Every 6 Hours', 'ezcache' ), |
| 251 |
]; |
| 252 |
} |
| 253 |
if ( ! isset( $schedules['every_12_hours'] ) ) { |
| 254 |
$schedules['every_12_hours'] = [ |
| 255 |
'interval' => 43200, |
| 256 |
'display' => __( 'Every 12 Hours', 'ezcache' ), |
| 257 |
]; |
| 258 |
} |
| 259 |
if ( ! isset( $schedules['daily'] ) ) { |
| 260 |
$schedules['daily'] = [ |
| 261 |
'interval' => 86400, |
| 262 |
'display' => __( 'Daily', 'ezcache' ), |
| 263 |
]; |
| 264 |
} |
| 265 |
if ( ! isset( $schedules['every_3_days'] ) ) { |
| 266 |
$schedules['every_3_days'] = [ |
| 267 |
'interval' => 259200, |
| 268 |
'display' => __( 'Every 3 Days', 'ezcache' ), |
| 269 |
]; |
| 270 |
} |
| 271 |
if ( ! isset( $schedules['every_5_days'] ) ) { |
| 272 |
$schedules['every_5_days'] = [ |
| 273 |
'interval' => 432000, |
| 274 |
'display' => __( 'Every 5 Days', 'ezcache' ), |
| 275 |
]; |
| 276 |
} |
| 277 |
if ( ! isset( $schedules['every_7_days'] ) ) { |
| 278 |
$schedules['every_7_days'] = [ |
| 279 |
'interval' => 604800, |
| 280 |
'display' => __( 'Every 7 Days', 'ezcache' ), |
| 281 |
]; |
| 282 |
} |
| 283 |
|
| 284 |
return $schedules; |
| 285 |
} |
| 286 |
|
| 287 |
/** |
| 288 |
* Repaire the plugin installation when POST variable is set |
| 289 |
*/ |
| 290 |
function maybe_repair_installation() { |
| 291 |
$repaired = get_transient( 'ezcache_repaired' ); |
| 292 |
delete_transient( 'ezcache_repaired' ); |
| 293 |
|
| 294 |
if ( $repaired || get_transient( 'ezcache_deactivating' ) || get_transient( 'ezcache_activating' ) ) { |
| 295 |
return; |
| 296 |
} |
| 297 |
|
| 298 |
if ( ! wp_next_scheduled( 'ezcache_clear_expired_cache' ) ) { |
| 299 |
Settings::maybe_update_cronjobs( Settings::get_settings() ); |
| 300 |
} |
| 301 |
|
| 302 |
$status = $this->ezcache->get_status(); |
| 303 |
if ( $status['cache_enabled'] && $status['adv_cache_exists'] && $status['adv_cache_exists'] && $status['correct_cache_exists'] && $status['webp_table_exists'] ) { |
| 304 |
return; |
| 305 |
} |
| 306 |
|
| 307 |
$this->activation_hook(); |
| 308 |
|
| 309 |
set_transient( 'ezcache_repaired', true ); |
| 310 |
} |
| 311 |
} |
| 312 |
|
| 313 |
add_action( 'plugins_loaded', '\Upress\EzCache\Plugin::initialize' ); |
| 314 |
add_action( 'plugins_loaded', function() { \Upress\EzCache\PremiumFeatures::maybe_start_trial(); }, 20 ); |
| 315 |
} |
| 316 |
|