PluginProbe ʕ •ᴥ•ʔ
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN / 3.14.1
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN v3.14.1
4.1.0 4.0.3 4.0.2 2.8.1 2.9.1 3.0.0 3.0.1 3.0.2 3.1.1 3.10.1 3.10.2 3.10.3 3.11.1 3.12.3 3.12.4 3.12.5 3.12.6 3.13.0 3.13.1 3.13.2 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.2 3.16.4 3.16.5 3.16.6 3.17.0 3.17.1 3.18.0 3.18.1 3.2.0.1 3.2.1 3.2.2.1 3.2.4 3.20.0 3.21.1 3.22.1 3.22.3 3.23.0 3.23.1 3.23.2 3.23.3 3.23.4 3.24.0 3.24.0-beta.2 3.3.0 3.3.1 3.3.2 3.4.1 3.4.2 3.6.1 3.6.3 3.7.0 3.7.1 3.7.2 3.7.3 3.8.2 3.8.3 3.8.4 3.8.5 3.8.7 3.8.8 3.9.0 3.9.1 3.9.11 3.9.2 3.9.4 3.9.5 3.9.8 3.9.9 trunk 1.0.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.2 1.2.1 1.2.10 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.5.1 1.6.5.2 1.6.5.3 1.6.5.4 1.7 1.7.1 1.7.1.1 2.0 2.0.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.6.2 2.0.6.3 2.0.6.5 2.0.7 2.0.7.1 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2 2.2.1 2.2.2 2.3 2.3.1 2.4 2.4.2 2.4.3 2.4.4 2.4.5 2.5.2 2.5.3 2.6.1 2.6.2 2.6.3 2.7 2.7.1 2.7.4 2.7.4.1 2.7.5 2.7.6 2.7.8 2.7.8.1 2.7.9.1 2.8.0 2.8.0.1
wp-smushit / wp-smush.php
wp-smushit Last commit date
_src 2 years ago app 2 years ago core 2 years ago languages 2 years ago vendor 2 years ago readme.txt 2 years ago uninstall.php 2 years ago wp-smush.php 2 years ago
wp-smush.php
576 lines
1 <?php
2 /**
3 * WP Smush plugin
4 *
5 * Reduce image file sizes, improve performance and boost your SEO using the free
6 * <a href="https://wpmudev.com/">WPMU DEV</a> WordPress Smush API.
7 *
8 * @link http://wpmudev.com/project/wp-smush-pro/
9 * @since 1.0.0
10 * @package WP_Smush
11 *
12 * @wordpress-plugin
13 * Plugin Name: Smush
14 * Plugin URI: http://wordpress.org/plugins/wp-smushit/
15 * Description: Reduce image file sizes, improve performance and boost your SEO using the free <a href="https://wpmudev.com/">WPMU DEV</a> WordPress Smush API.
16 * Version: 3.14.1
17 * Author: WPMU DEV
18 * Author URI: https://profiles.wordpress.org/wpmudev/
19 * License: GPLv2
20 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
21 * Text Domain: wp-smushit
22 * Domain Path: /languages/
23 * Network: true
24 */
25
26 /*
27 This plugin was originally developed by Alex Dunae (http://dialect.ca/).
28
29 Copyright 2007-2022 Incsub (http://incsub.com)
30
31 This program is free software; you can redistribute it and/or modify
32 it under the terms of the GNU General Public License (Version 2 - GPLv2) as published by
33 the Free Software Foundation.
34
35 This program is distributed in the hope that it will be useful,
36 but WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 GNU General Public License for more details.
39
40 You should have received a copy of the GNU General Public License
41 along with this program; if not, write to the Free Software
42 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
43 */
44
45 // If this file is called directly, abort.
46 if ( ! defined( 'WPINC' ) ) {
47 die;
48 }
49
50 if ( ! defined( 'WP_SMUSH_VERSION' ) ) {
51 define( 'WP_SMUSH_VERSION', '3.14.1' );
52 }
53 // Used to define body class.
54 if ( ! defined( 'WP_SHARED_UI_VERSION' ) ) {
55 define( 'WP_SHARED_UI_VERSION', 'sui-2-12-10' );
56 }
57 if ( ! defined( 'WP_SMUSH_BASENAME' ) ) {
58 define( 'WP_SMUSH_BASENAME', plugin_basename( __FILE__ ) );
59 }
60 if ( ! defined( 'WP_SMUSH_API' ) ) {
61 define( 'WP_SMUSH_API', 'https://smushpro.wpmudev.com/1.0/' );
62 }
63 if ( ! defined( 'WP_SMUSH_UA' ) ) {
64 define( 'WP_SMUSH_UA', 'WP Smush/' . WP_SMUSH_VERSION . '; ' . network_home_url() );
65 }
66 if ( ! defined( 'WP_SMUSH_DIR' ) ) {
67 define( 'WP_SMUSH_DIR', plugin_dir_path( __FILE__ ) );
68 }
69 if ( ! defined( 'WP_SMUSH_URL' ) ) {
70 define( 'WP_SMUSH_URL', plugin_dir_url( __FILE__ ) );
71 }
72 if ( ! defined( 'WP_SMUSH_MAX_BYTES' ) ) {
73 define( 'WP_SMUSH_MAX_BYTES', 5242880 );
74 }
75 if ( ! defined( 'WP_SMUSH_PREMIUM_MAX_BYTES' ) ) {
76 define( 'WP_SMUSH_PREMIUM_MAX_BYTES', 33554432 );
77 }
78 if ( ! defined( 'WP_SMUSH_TIMEOUT' ) ) {
79 define( 'WP_SMUSH_TIMEOUT', 150 );
80 }
81 if ( ! defined( 'WP_SMUSH_RETRY_ATTEMPTS' ) ) {
82 define( 'WP_SMUSH_RETRY_ATTEMPTS', 3 );
83 }
84 if ( ! defined( 'WP_SMUSH_RETRY_WAIT' ) ) {
85 define( 'WP_SMUSH_RETRY_WAIT', 1 );
86 }
87 if ( ! defined( 'WP_SMUSH_PARALLEL' ) ) {
88 define( 'WP_SMUSH_PARALLEL', true );
89 }
90 if ( ! defined( 'WP_SMUSH_BACKGROUND' ) ) {
91 define( 'WP_SMUSH_BACKGROUND', true );
92 }
93
94 /**
95 * To support Smushing on staging sites like SiteGround staging where staging site urls are different
96 * but redirects to main site url. Remove the protocols and www, and get the domain name.*
97 * If Set to false, WP Smush switch backs to the Old Sync Optimisation.
98 */
99 $site_url = str_replace( array( 'http://', 'https://', 'www.' ), '', site_url() );
100 // Compat with WPMU DEV staging.
101 $wpmu_host = isset( $_SERVER['WPMUDEV_HOSTING_ENV'] ) && 'staging' === sanitize_text_field( wp_unslash( $_SERVER['WPMUDEV_HOSTING_ENV'] ) );
102 if ( ! defined( 'WP_SMUSH_ASYNC' ) ) {
103 if ( ( ! empty( $_SERVER['SERVER_NAME'] ) && 0 !== strpos( $site_url, sanitize_text_field( wp_unslash( $_SERVER['SERVER_NAME'] ) ) ) ) || $wpmu_host ) {
104 define( 'WP_SMUSH_ASYNC', false );
105 } else {
106 define( 'WP_SMUSH_ASYNC', true );
107 }
108 }
109
110 /**
111 * If we are activating a version, while having another present and activated.
112 * Leave in the Pro version, if it is available.
113 *
114 * @since 2.9.1
115 */
116 if ( WP_SMUSH_BASENAME !== plugin_basename( __FILE__ ) ) {
117 $pro_installed = false;
118 if ( file_exists( WP_PLUGIN_DIR . '/wp-smush-pro/wp-smush.php' ) ) {
119 $pro_installed = true;
120 }
121
122 if ( ! function_exists( 'is_plugin_active' ) ) {
123 include_once ABSPATH . 'wp-admin/includes/plugin.php';
124 }
125
126 if ( is_plugin_active( 'wp-smush-pro/wp-smush.php' ) ) {
127 deactivate_plugins( plugin_basename( __FILE__ ) );
128 update_site_option( 'smush_deactivated', 1 );
129 return; // Return to avoid errors with free-dashboard module.
130 } elseif ( $pro_installed && is_plugin_active( WP_SMUSH_BASENAME ) ) {
131 deactivate_plugins( WP_SMUSH_BASENAME );
132 // If WordPress is already in the process of activating - return.
133 if ( defined( 'WP_SANDBOX_SCRAPING' ) && WP_SANDBOX_SCRAPING ) {
134 return;
135 }
136 activate_plugin( plugin_basename( __FILE__ ) );
137 }
138 }
139
140 /* @noinspection PhpIncludeInspection */
141 require_once WP_SMUSH_DIR . 'core/class-installer.php';
142 register_activation_hook( __FILE__, array( 'Smush\\Core\\Installer', 'smush_activated' ) );
143 register_deactivation_hook( __FILE__, array( 'Smush\\Core\\Installer', 'smush_deactivated' ) );
144
145 register_activation_hook( __FILE__, function () {
146 set_transient( 'wp-smush-plugin-activated', true, 30 );
147 } );
148
149 // Init the plugin and load the plugin instance for the first time.
150 add_action( 'plugins_loaded', array( 'WP_Smush', 'get_instance' ) );
151
152 if ( ! class_exists( 'WP_Smush' ) ) {
153 /**
154 * Class WP_Smush
155 */
156 final class WP_Smush {
157
158 /**
159 * Plugin instance.
160 *
161 * @since 2.9.0
162 * @var null|WP_Smush
163 */
164 private static $instance = null;
165
166 /**
167 * Plugin core.
168 *
169 * @since 2.9.0
170 * @var Smush\Core\Core
171 */
172 private $core;
173
174 /**
175 * Plugin admin.
176 *
177 * @since 2.9.0
178 * @var Smush\App\Admin
179 */
180 private $admin;
181
182 /**
183 * Plugin API.
184 *
185 * @since 3.0
186 * @var Smush\Core\Api\Smush_API
187 */
188 private $api = '';
189
190 /**
191 * Media library UI.
192 *
193 * @since 3.4.0
194 * @var Smush\App\Media_Library
195 */
196 private $library;
197
198 /**
199 * Stores the value of validate_install function.
200 *
201 * @var bool $is_pro
202 */
203 private static $is_pro;
204
205 /**
206 * Return the plugin instance.
207 *
208 * @return WP_Smush
209 */
210 public static function get_instance() {
211 if ( ! self::$instance ) {
212 self::$instance = new self();
213 }
214
215 return self::$instance;
216 }
217
218 /**
219 * WP_Smush constructor.
220 */
221 private function __construct() {
222 spl_autoload_register( array( $this, 'autoload' ) );
223
224 /**
225 * Include vendor dependencies
226 */
227 require_once __DIR__ . '/vendor/autoload.php';
228
229 add_action( 'admin_init', array( '\\Smush\\Core\\Installer', 'upgrade_settings' ) );
230 add_action( 'current_screen', array( '\\Smush\\Core\\Installer', 'maybe_create_table' ) );
231 // We use priority 9 to avoid conflict with old free-dashboard module <= 2.0.4.
232 add_action( 'admin_init', array( $this, 'register_free_modules' ), 9 );
233
234 // The dash-notification actions are hooked into "init" with a priority of 10.
235 add_action( 'init', array( $this, 'register_pro_modules' ), 5 );
236
237 add_action( 'init', array( $this, 'do_plugin_activated_action' ) );
238
239 $this->init();
240 }
241
242 public function do_plugin_activated_action() {
243 $transient_key = 'wp-smush-plugin-activated';
244
245 ( new \Smush\Core\Modules\Background\Mutex( $transient_key ) )->execute( function () use ( $transient_key ) {
246 if ( get_transient( $transient_key ) ) {
247 do_action( 'wp_smush_plugin_activated' );
248 delete_transient( $transient_key );
249 }
250 } );
251 }
252
253 /**
254 * Autoload method.
255 *
256 * @since 3.1.0
257 * @param string $class Class name to autoload.
258 */
259 public function autoload( $class ) {
260 // Project-specific namespace prefix.
261 $prefix = 'Smush\\';
262
263 // Does the class use the namespace prefix?
264 $len = strlen( $prefix );
265 if ( 0 !== strncmp( $prefix, $class, $len ) ) {
266 // Maybe require some external classes.
267 $external_libs = array( 'WDEV_Logger' );
268 if ( in_array( $class, $external_libs, true ) ) {
269 $lib = str_replace( '_', '-', strtolower( $class ) );
270 $file = WP_SMUSH_DIR . "core/external/{$lib}/{$lib}.php";
271 if ( file_exists( $file ) ) {
272 require_once $file;
273 }
274 }
275 // No, move to the next registered autoloader.
276 return;
277 }
278
279 // Get the relative class name.
280 $relative_class = substr( $class, $len );
281
282 $path = explode( '\\', strtolower( str_replace( '_', '-', $relative_class ) ) );
283 $file = array_pop( $path );
284 $file = WP_SMUSH_DIR . implode( '/', $path ) . '/class-' . $file . '.php';
285
286 // If the file exists, require it.
287 if ( file_exists( $file ) ) {
288 /* @noinspection PhpIncludeInspection */
289 require $file;
290 }
291 }
292
293 /**
294 * Init core module.
295 *
296 * @since 2.9.0
297 */
298 private function init() {
299 try {
300 $this->api = new Smush\Core\Api\Smush_API( Smush\Core\Helper::get_wpmudev_apikey() );
301 } catch ( Exception $e ) {
302 $this->api = '';
303 }
304
305 // Handle failed items, load it before validate the install.
306 new Smush\Core\Error_Handler();
307
308 $this->validate_install();
309
310 $this->core = new Smush\Core\Core();
311 $this->library = new Smush\App\Media_Library( $this->core() );
312 if ( is_admin() ) {
313 $this->admin = new Smush\App\Admin( $this->library() );
314 }
315
316 if ( defined( 'WP_CLI' ) && WP_CLI ) {
317 WP_CLI::add_command( 'smush', '\\Smush\\Core\\CLI' );
318 }
319 }
320
321 /**
322 * Getter method for core.
323 *
324 * @since 2.9.0
325 *
326 * @return Smush\Core\Core
327 */
328 public function core() {
329 return $this->core;
330 }
331
332 /**
333 * Getter method for core.
334 *
335 * @since 2.9.0
336 *
337 * @return Smush\App\Admin
338 */
339 public function admin() {
340 return $this->admin;
341 }
342
343 /**
344 * Getter method for core.
345 *
346 * @since 3.0
347 *
348 * @return Smush\Core\Api\Smush_API
349 */
350 public function api() {
351 return $this->api;
352 }
353
354 /**
355 * Getter method for library.
356 *
357 * @since 3.4.0
358 *
359 * @return Smush\App\Media_Library
360 */
361 public function library() {
362 return $this->library;
363 }
364
365 /**
366 * Return PRO status.
367 *
368 * @since 2.9.0
369 *
370 * @return bool
371 */
372 public static function is_pro() {
373 return self::$is_pro;
374 }
375
376 public static function is_expired() {
377 return ! self::is_pro() && Smush\Core\Helper::get_wpmudev_apikey();
378 }
379
380 public static function is_new_user() {
381 return ! self::is_pro() && ! self::is_expired();
382 }
383
384 /**
385 * Verify the site is connected to TFH.
386 *
387 * @since 3.12.0
388 *
389 * @return boolean
390 */
391 public static function is_site_connected_to_tfh() {
392 return isset( $_SERVER['WPMUDEV_HOSTED'] )
393 && class_exists( '\WPMUDEV_Dashboard' ) && is_object( \WPMUDEV_Dashboard::$api )
394 && method_exists( \WPMUDEV_Dashboard::$api, 'get_membership_status' )
395 && 'free' === \WPMUDEV_Dashboard::$api->get_membership_status();
396 }
397
398 public static function is_member() {
399 return self::is_pro() || self::is_site_connected_to_tfh();
400 }
401
402 /**
403 * Register submodules.
404 * Only for wordpress.org members.
405 */
406 public function register_free_modules() {
407 if ( false === strpos( WP_SMUSH_DIR, 'wp-smushit' ) || class_exists( 'WPMUDEV_Dashboard' ) || file_exists( WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php' ) ) {
408 return;
409 }
410
411 /* @noinspection PhpIncludeInspection */
412 require_once WP_SMUSH_DIR . 'core/external/free-dashboard/module.php';
413 /* @noinspection PhpIncludeInspection */
414 require_once WP_SMUSH_DIR . 'core/external/plugin-notice/notice.php';
415
416 // Add the Mailchimp group value.
417 add_action(
418 'frash_subscribe_form_fields',
419 function ( $mc_list_id ) {
420 if ( '4b14b58816' === $mc_list_id ) {
421 echo '<input type="hidden" id="mce-group[53]-53-1" name="group[53][2]" value="2" />';
422 }
423 }
424 );
425
426 // Register the current plugin.
427 do_action(
428 'wpmudev_register_notices',
429 'smush',
430 array(
431 'basename' => WP_SMUSH_BASENAME, // Required: Plugin basename (for backward compat).
432 'title' => 'Smush', // Required: Plugin title.
433 'wp_slug' => 'wp-smushit', // Required: wp.org slug of the plugin.
434 'cta_email' => __( 'Get Fast!', 'wp-smushit' ), // Email button CTA.
435 'installed_on' => time(), // Optional: Plugin activated time.
436 'screens' => array( // Required: Plugin screen ids.
437 'toplevel_page_smush',
438 ),
439 )
440 );
441 add_filter( 'wpmudev_notices_is_disabled', array( $this, 'enable_free_tips_opt_in' ), 10, 3 );
442
443 // The email message contains 1 variable: plugin-name.
444 add_filter(
445 'wdev_email_message_' . WP_SMUSH_BASENAME,
446 function () {
447 return "You're awesome for installing %s! Make sure you get the most out of it, boost your Google PageSpeed score with these tips and tricks - just for users of Smush!";
448 }
449 );
450
451 // Recommended plugin notice.
452 do_action(
453 'wpmudev-recommended-plugins-register-notice',
454 WP_SMUSH_BASENAME,
455 __( 'Smush', 'wp-smushit' ),
456 \Smush\App\Admin::$plugin_pages,
457 array( 'before', '.sui-wrap .sui-floating-notices, .sui-wrap .sui-upgrade-page' )
458 );
459 }
460
461 public function enable_free_tips_opt_in( $is_disabled, $type, $plugin ) {
462 // Enable email opt-in.
463 if ( 'smush' === $plugin && 'email' === $type ) {
464 $is_disabled = false;
465 }
466
467 return $is_disabled;
468 }
469
470 /**
471 * Register sub-modules.
472 * Only for WPMU DEV Members.
473 */
474 public function register_pro_modules() {
475 if ( ! file_exists( WP_SMUSH_DIR . 'core/external/dash-notice/wpmudev-dash-notification.php' ) ) {
476 return;
477 }
478
479 // Register items for the dashboard plugin.
480 global $wpmudev_notices;
481 $wpmudev_notices[] = array(
482 'id' => 912164,
483 'name' => 'WP Smush Pro',
484 'screens' => array(
485 'upload',
486 ),
487 );
488
489 /* @noinspection PhpIncludeInspection */
490 require_once WP_SMUSH_DIR . 'core/external/dash-notice/wpmudev-dash-notification.php';
491 }
492
493 /**
494 * Check if user is premium member, check for API key.
495 *
496 * @param bool $manual Is it a manual check? Default: false.
497 */
498 public function validate_install( $manual = false ) {
499 if ( isset( self::$is_pro ) && ! $manual ) {
500 return;
501 }
502
503 // No API key set, always false.
504 $api_key = Smush\Core\Helper::get_wpmudev_apikey();
505
506 if ( empty( $api_key ) ) {
507 return;
508 }
509
510 // Flag to check if we need to revalidate the key.
511 $revalidate = false;
512
513 $api_auth = get_site_option( 'wp_smush_api_auth' );
514
515 // Check if we need to revalidate.
516 if ( empty( $api_auth[ $api_key ] ) ) {
517 $api_auth = array();
518 $revalidate = true;
519 } else {
520 $last_checked = $api_auth[ $api_key ]['timestamp'];
521 $valid = $api_auth[ $api_key ]['validity'];
522
523 // Difference in hours.
524 $diff = ( time() - $last_checked ) / HOUR_IN_SECONDS;
525
526 if ( 24 < $diff ) {
527 $revalidate = true;
528 }
529 }
530
531 // If we are supposed to validate API, update the results in options table.
532 if ( $revalidate || $manual ) {
533 if ( empty( $api_auth[ $api_key ] ) ) {
534 // For api key resets.
535 $api_auth[ $api_key ] = array();
536
537 // Storing it as valid, unless we really get to know from API call.
538 $valid = 'valid';
539 $api_auth[ $api_key ]['validity'] = 'valid';
540 }
541
542 // This is the first check.
543 if ( ! isset( $api_auth[ $api_key ]['timestamp'] ) ) {
544 $api_auth[ $api_key ]['timestamp'] = time();
545 }
546
547 $request = $this->api()->check( $manual );
548
549 if ( ! is_wp_error( $request ) && 200 === wp_remote_retrieve_response_code( $request ) ) {
550 // Update the timestamp only on successful attempts.
551 $api_auth[ $api_key ]['timestamp'] = time();
552 update_site_option( 'wp_smush_api_auth', $api_auth );
553
554 $result = json_decode( wp_remote_retrieve_body( $request ) );
555 if ( ! empty( $result->success ) && $result->success ) {
556 $valid = 'valid';
557 update_site_option( 'wp-smush-cdn_status', $result->data );
558 } else {
559 $valid = 'invalid';
560 }
561 } elseif ( ! isset( $valid ) || 'valid' !== $valid ) {
562 // Invalidate only in case when it was not valid before.
563 $valid = 'invalid';
564 }
565
566 $api_auth[ $api_key ]['validity'] = $valid;
567
568 // Update API validity.
569 update_site_option( 'wp_smush_api_auth', $api_auth );
570 }
571
572 self::$is_pro = isset( $valid ) && 'valid' === $valid;
573 }
574 }
575 }
576