| @@ -1,33 +1,56 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | /** |
| 3 | - * Plugin Name: Image Optimizer by Elementor – Compress, Resize and Optimize Images | |
| 4 | - * Description: Automatically compress and enhance your images, boosting your website speed, appearance, and SEO. Get Image Optimizer and optimize your images in seconds. | |
| 3 | + * Plugin Name: Image Optimization - Optimize Images and Convert to WebP or AVIF | |
| 4 | + * Description: Automatically resize, optimize, and convert images to WebP and AVIF. Compress images in bulk or on upload to boost your WordPress site performance. | |
| 5 | 5 | * Plugin URI: https://go.elementor.com/wp-repo-description-tab-io-product-page/ |
| 6 | - * Version: 1.1.0 | |
| 6 | + * Version: 1.7.7 | |
| 7 | 7 | * Author: Elementor.com |
| 8 | - * Author URI: https://go.elementor.com/wp-repo-description-tab-io-author-url/ | |
| 8 | + * Author URI: https://go.elementor.com/author-uri-io/ | |
| 9 | 9 | * Text Domain: image-optimization |
| 10 | 10 | * License: GPL-3 |
| 11 | 11 | * License URI: https://www.gnu.org/licenses/gpl-3.0.en.html |
| 12 | + * | |
| 13 | + * Image Optimization is free software: you can redistribute it and/or modify | |
| 14 | + * it under the terms of the GNU General Public License as published by | |
| 15 | + * the Free Software Foundation, either version 3 of the License, or | |
| 16 | + * any later version. | |
| 17 | + * | |
| 18 | + * Image Optimization is distributed in the hope that it will be useful, | |
| 19 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 20 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 21 | + * GNU General Public License for more details. | |
| 12 | 22 | */ |
| 13 | 23 | |
| 24 | +use ImageOptimization\Modules\Core\Module as CoreModule; | |
| 25 | + | |
| 14 | 26 | if ( ! defined( 'ABSPATH' ) ) { |
| 15 | 27 | exit; // Exit if accessed directly. |
| 16 | 28 | } |
| 17 | 29 | |
| 18 | -define( 'IMAGE_OPTIMIZATION_VERSION', '1.1.0' ); | |
| 19 | -define( 'IMAGE_OPTIMIZATION_PATH', plugin_dir_path( __FILE__ ) ); | |
| 20 | -define( 'IMAGE_OPTIMIZATION_URL', plugins_url( '/', __FILE__ ) ); | |
| 30 | +define( 'IMAGE_OPTIMIZATION_VERSION', '1.7.7' ); | |
| 31 | +define( 'IMAGE_OPTIMIZATION_FILE', __FILE__ ); | |
| 32 | +define( 'IMAGE_OPTIMIZATION_PATH', plugin_dir_path( IMAGE_OPTIMIZATION_FILE ) ); | |
| 33 | +define( 'IMAGE_OPTIMIZATION_URL', plugins_url( '/', IMAGE_OPTIMIZATION_FILE ) ); | |
| 21 | 34 | define( 'IMAGE_OPTIMIZATION_ASSETS_PATH', IMAGE_OPTIMIZATION_PATH . 'assets/' ); |
| 22 | 35 | define( 'IMAGE_OPTIMIZATION_ASSETS_URL', IMAGE_OPTIMIZATION_URL . 'assets/' ); |
| 23 | -define( 'IMAGE_OPTIMIZATION_PLUGIN_FILE', basename( __FILE__ ) ); | |
| 36 | +define( 'IMAGE_OPTIMIZATION_PLUGIN_FILE', plugin_basename( IMAGE_OPTIMIZATION_FILE ) ); | |
| 24 | 37 | |
| 38 | +if ( ! defined( 'IMAGE_OPTIMIZATION_MINIMUM_LOG_LEVEL' ) ) { | |
| 39 | + define( 'IMAGE_OPTIMIZATION_MINIMUM_LOG_LEVEL', 3 ); | |
| 40 | +} | |
| 41 | + | |
| 42 | +register_deactivation_hook( | |
| 43 | + __FILE__, | |
| 44 | + [ CoreModule::class, 'on_deactivation' ] | |
| 45 | +); | |
| 46 | + | |
| 25 | 47 | /** |
| 26 | 48 | * ImageOptimization Class |
| 27 | 49 | */ |
| 28 | 50 | final class ImageOptimization { |
| 29 | - private const REQUIRED_EXTENSIONS = [ | |
| 51 | + private $requirements_errors = []; | |
| 52 | + const REQUIRED_EXTENSIONS = [ | |
| 30 | 53 | 'exif', |
| 31 | 54 | 'fileinfo', |
| 32 | 55 | 'gd', |
| 33 | 56 | ]; |
| @@ -37,10 +60,9 @@ | ||
| 37 | 60 | * |
| 38 | 61 | * @access public |
| 39 | 62 | */ |
| 40 | 63 | public function __construct() { |
| 41 | - // Load translation | |
| 42 | - add_action( 'init', [ $this, 'i18n' ] ); | |
| 64 | + require_once IMAGE_OPTIMIZATION_PATH . 'vendor/autoload.php'; | |
| 43 | 65 | |
| 44 | 66 | // Init Plugin |
| 45 | 67 | add_action( 'plugins_loaded', [ $this, 'init' ], -11 ); |
| 46 | 68 | } |
| @@ -45,34 +67,77 @@ | ||
| 45 | 67 | add_action( 'plugins_loaded', [ $this, 'init' ], -11 ); |
| 46 | 68 | } |
| 47 | 69 | |
| 48 | 70 | /** |
| 49 | - * Load Textdomain | |
| 71 | + * Checks if all requirements met to safely start the plugin and renders admin notices | |
| 72 | + * if something is not right. | |
| 50 | 73 | * |
| 51 | - * Load plugin localization files. | |
| 52 | - * Fired by `init` action hook. | |
| 53 | - * | |
| 54 | 74 | * @access public |
| 75 | + * @return bool | |
| 55 | 76 | */ |
| 56 | - public function i18n() { | |
| 57 | - load_plugin_textdomain( 'image-optimization' ); | |
| 58 | - } | |
| 77 | + public function plugin_can_start(): bool { | |
| 78 | + $can_start = true; | |
| 59 | 79 | |
| 60 | - public function insufficient_php_version() { | |
| 61 | - $message = sprintf( | |
| 62 | - /* translators: 1: `<h3>` opening tag, 2: `</h3>` closing tag, 3: PHP version. 4: Link opening tag, 5: Link closing tag. */ | |
| 63 | - esc_html__( '%1$sImage Optimizer isn’t running because PHP is outdated.%2$s Update to PHP version %3$s and get back to optimizing! %4$sShow me how%5$s', 'image-optimization' ), | |
| 64 | - '<h3>', | |
| 65 | - '</h3>', | |
| 66 | - '7.4', | |
| 67 | - '<a href="https://go.elementor.com/wp-dash-update-php/" target="_blank">', | |
| 68 | - '</a>' | |
| 69 | - ); | |
| 70 | - $html_message = sprintf( '<div class="error">%s</div>', wpautop( $message ) ); | |
| 71 | - echo wp_kses_post( $html_message ); | |
| 80 | + if ( ! version_compare( PHP_VERSION, '7.4', '>=' ) ) { | |
| 81 | + $this->requirements_errors[] = sprintf( | |
| 82 | + '%1$s <a href="https://go.elementor.com/wp-dash-update-php/" target="_blank">%2$s</a>', | |
| 83 | + sprintf( | |
| 84 | + /* translators: %s: PHP version. */ | |
| 85 | + esc_html__( 'Update to PHP version %s and get back to optimizing!', 'image-optimization' ), | |
| 86 | + '7.4', | |
| 87 | + ), | |
| 88 | + esc_html__( 'Show me how', 'image-optimization' ) | |
| 89 | + ); | |
| 90 | + | |
| 91 | + $can_start = false; | |
| 92 | + } | |
| 93 | + | |
| 94 | + if ( count( $this->get_missing_extensions_list() ) ) { | |
| 95 | + $missed_extensions = $this->get_missing_extensions_list(); | |
| 96 | + | |
| 97 | + $this->requirements_errors[] = sprintf( | |
| 98 | + esc_html__( 'The following required PHP extensions are missing: %s', 'image-optimization' ), | |
| 99 | + implode( ', ', $missed_extensions ) | |
| 100 | + ); | |
| 101 | + | |
| 102 | + $can_start = false; | |
| 103 | + } | |
| 104 | + | |
| 105 | + if ( ! $this->is_db_json_supported() ) { | |
| 106 | + $this->requirements_errors[] = sprintf( | |
| 107 | + /* translators: 1: MySQL minimum version. 2: MariaDB minimum version. */ | |
| 108 | + esc_html__( | |
| 109 | + 'The database server version is outdated. Update to MySQL version %1$s or MariaDB version %2$s.', | |
| 110 | + 'image-optimization' | |
| 111 | + ), | |
| 112 | + '5.7', | |
| 113 | + '10.2' | |
| 114 | + ); | |
| 115 | + | |
| 116 | + $can_start = false; | |
| 117 | + } | |
| 118 | + | |
| 119 | + $upload_dir = wp_upload_dir(); | |
| 120 | + | |
| 121 | + if ( ! wp_is_writable( $upload_dir['basedir'] ) ) { | |
| 122 | + $this->requirements_errors[] = esc_html__( | |
| 123 | + 'Your site doesn’t have the necessary read/write permissions for your file system to use this plugin. Please contact your hosting provider to resolve this matter.', | |
| 124 | + 'image-optimization', | |
| 125 | + ); | |
| 126 | + | |
| 127 | + $can_start = false; | |
| 128 | + } | |
| 129 | + | |
| 130 | + return $can_start; | |
| 72 | 131 | } |
| 73 | 132 | |
| 74 | - private function get_missed_extensions_list(): array { | |
| 133 | + /** | |
| 134 | + * Retrieve an array of missing extensions mentioned in self::REQUIRED_EXTENSIONS. | |
| 135 | + * | |
| 136 | + * @access private | |
| 137 | + * @return array Missing extensions. | |
| 138 | + */ | |
| 139 | + private function get_missing_extensions_list(): array { | |
| 75 | 140 | $output = []; |
| 76 | 141 | |
| 77 | 142 | foreach ( self::REQUIRED_EXTENSIONS as $extension ) { |
| 78 | 143 | if ( ! extension_loaded( $extension ) ) { |
| @@ -82,19 +147,59 @@ | ||
| 82 | 147 | |
| 83 | 148 | return $output; |
| 84 | 149 | } |
| 85 | 150 | |
| 86 | - public function add_missed_extensions_notice() { | |
| 87 | - $missed_extensions = $this->get_missed_extensions_list(); | |
| 151 | + /** | |
| 152 | + * The check is strictly based on the action scheduler requirements that needs JSON partial matching to work | |
| 153 | + * with action queries. | |
| 154 | + * | |
| 155 | + * @return bool | |
| 156 | + */ | |
| 157 | + public function is_db_json_supported(): bool { | |
| 158 | + global $wpdb; | |
| 88 | 159 | |
| 160 | + $db_server_info = is_callable( array( $wpdb, 'db_server_info' ) ) ? $wpdb->db_server_info() : $wpdb->db_version(); | |
| 161 | + | |
| 162 | + if ( false !== strpos( $db_server_info, 'MariaDB' ) ) { | |
| 163 | + $supports_json = version_compare( | |
| 164 | + PHP_VERSION_ID >= 80016 ? $wpdb->db_version() : preg_replace( '/[^0-9.].*/', '', str_replace( '5.5.5-', '', $db_server_info ) ), | |
| 165 | + '10.2', | |
| 166 | + '>=' | |
| 167 | + ); | |
| 168 | + } else { | |
| 169 | + $supports_json = version_compare( $wpdb->db_version(), '5.7', '>=' ); | |
| 170 | + } | |
| 171 | + | |
| 172 | + return (bool) $supports_json; | |
| 173 | + } | |
| 174 | + | |
| 175 | + /** | |
| 176 | + * Renders an admin notice if the setup did not meet requirements. | |
| 177 | + * | |
| 178 | + * Fired by `admin_notices` action hook. | |
| 179 | + * | |
| 180 | + * @access public | |
| 181 | + * @return void | |
| 182 | + */ | |
| 183 | + public function add_requirements_error() { | |
| 89 | 184 | $message = sprintf( |
| 90 | - /* translators: 1: `<h3>` opening tag, 2: Missed extension names, 3: `</h3>` closing tag. */ | |
| 91 | - esc_html__( '%1$sImage Optimizer isn’t running because the next required PHP extensions are missed: %2$s.%3$s', 'image-optimization' ), | |
| 92 | - '<h3>', | |
| 93 | - implode( ', ', $missed_extensions ), | |
| 94 | - '</h3>', | |
| 185 | + '<h3>%s</h3>', | |
| 186 | + esc_html__( 'Image Optimization isn’t running because:', 'image-optimization' ) | |
| 95 | 187 | ); |
| 96 | 188 | |
| 189 | + $message .= '<ul>'; | |
| 190 | + | |
| 191 | + foreach ( $this->requirements_errors as $error ) { | |
| 192 | + $message .= sprintf( | |
| 193 | + '%s%s%s', | |
| 194 | + '<li>', | |
| 195 | + $error, | |
| 196 | + '</li>' | |
| 197 | + ); | |
| 198 | + } | |
| 199 | + | |
| 200 | + $message .= '</ul>'; | |
| 201 | + | |
| 97 | 202 | $html_message = sprintf( '<div class="error">%s</div>', wpautop( $message ) ); |
| 98 | 203 | |
| 99 | 204 | echo wp_kses_post( $html_message ); |
| 100 | 205 | } |
| @@ -99,24 +204,20 @@ | ||
| 99 | 204 | echo wp_kses_post( $html_message ); |
| 100 | 205 | } |
| 101 | 206 | |
| 102 | 207 | /** |
| 103 | - * Initialize the plugin | |
| 208 | + * Initialize the plugin. | |
| 104 | 209 | * |
| 105 | - * Validates that PHP version is sufficient. | |
| 106 | - * Checks for basic plugin requirements, if one check fail don't continue, | |
| 107 | - * if all check have passed include the plugin class. | |
| 210 | + * Validates that PHP version is sufficient. Checks for basic plugin requirements, | |
| 211 | + * if one check fail don't continue, if all check have passed include the plugin class. | |
| 108 | 212 | * |
| 109 | 213 | * Fired by `plugins_loaded` action hook. |
| 110 | 214 | * |
| 111 | - * @since 1.2.0 | |
| 112 | 215 | * @access public |
| 113 | 216 | */ |
| 114 | 217 | public function init() { |
| 115 | - if ( ! version_compare( PHP_VERSION, '7.4', '>=' ) ) { | |
| 116 | - add_action( 'admin_notices', [ $this, 'insufficient_php_version' ] ); | |
| 117 | - } else if ( count( $this->get_missed_extensions_list() ) ) { | |
| 118 | - add_action( 'admin_notices', [ $this, 'add_missed_extensions_notice' ] ); | |
| 218 | + if ( ! $this->plugin_can_start() ) { | |
| 219 | + add_action( 'admin_notices', [ $this, 'add_requirements_error' ] ); | |
| 119 | 220 | } else { |
| 120 | 221 | // Once we get here, We have passed all validation checks, so we can safely include our plugin |
| 121 | 222 | require_once 'plugin.php'; |
| 122 | 223 | } |
| @@ -122,6 +223,6 @@ | ||
| 122 | 223 | } |
| 123 | 224 | } |
| 124 | 225 | } |
| 125 | 226 | |
| 126 | -// Instantiate ImageOptimization.. | |
| 227 | +// Instantiate ImageOptimization. | |
| 127 | 228 | new ImageOptimization(); |