PluginProbe
Image Optimizer – Compress Images and Convert to WebP or AVIF / 1.7.7
Image Optimizer – Compress Images and Convert to WebP or AVIF v1.7.7
1.7.7 1.7.6 1.7.5 1.7.4 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 All 33 releases
← All changes | modules/core/module.php +221 -17 1.6.31.7.7 View file →
@@ -1,21 +1,32 @@
1 1 <?php
2 2 namespace ImageOptimization\Modules\Core;
3 3
4 4 use ImageOptimization\Modules\Optimization\{
5 + Classes\Validate_Image,
5 6 Rest\Cancel_Bulk_Optimization,
6 7 Rest\Optimize_Bulk,
7 8 };
9 +use ImageOptimization\Modules\Settings\Classes\Settings;
8 10 use ImageOptimization\Modules\Backups\Rest\{
9 11 Restore_All,
10 12 Remove_Backups,
11 13 };
12 14 use ImageOptimization\Classes\{
15 + Async_Operation\Async_Operation,
16 + Async_Operation\Async_Operation_Queue,
17 + Async_Operation\Queries\Operation_Query,
18 + Image\Image_Meta,
19 + Image\Image_Optimization_Error_Type,
20 + Image\Image_Status,
13 21 Migration\Migration_Manager,
14 22 Module_Base,
15 - Utils
23 + Utils,
16 24 };
17 25
26 +use ImageOptimization\Modules\Connect\Module as Connect_Module;
27 +use ImageOptimization\Modules\Connect\Classes\Config;
28 +
18 29 use ImageOptimization\Plugin;
19 30
20 31 if ( ! defined( 'ABSPATH' ) ) {
21 32 exit; // Exit if accessed directly.
@@ -21,13 +32,16 @@
21 32 exit; // Exit if accessed directly.
22 33 }
23 34
24 35 class Module extends Module_Base {
36 +
37 + const ONE_MISMATCH_URL = '/wp-admin/admin.php?page=elementor-home#/home/url-mismatch';
38 +
25 39 public function get_name(): string {
26 40 return 'core';
27 41 }
28 42
29 - public static function component_list() : array {
43 + public static function component_list(): array {
30 44 return [
31 45 'Pointers',
32 46 'Migrations',
33 47 'Conflicts',
@@ -32,9 +46,11 @@
32 46 'Migrations',
33 47 'Conflicts',
34 48 'User_Feedback',
35 49 'Not_Connected',
50 + 'Not_Connected_Modal',
36 51 'Renewal_Notice',
52 + 'Notificator',
37 53 ];
38 54 }
39 55
40 56 private function render_top_bar() {
@@ -53,8 +69,9 @@
53 69 public function maybe_add_quota_reached_notice() {
54 70
55 71 // @var ImageOptimizer/Modules/ConnectManager/Module
56 72 $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
73 + $upgrade_link = Utils::get_upgrade_link( 'https://go.elementor.com/io-quota-upgrade/' );
57 74
58 75 if ( ! $module->connect_instance->get_connect_status() || $module->connect_instance->images_left() > 0 ) {
59 76 return;
60 77 }
@@ -74,9 +91,9 @@
74 91 'You have no images left to optimize in your current plan.',
75 92 'image-optimization'
76 93 ); ?>
77 94
78 - <a href="https://go.elementor.com/io-quota-upgrade/">
95 + <a href="<?php echo esc_url( $upgrade_link ); ?>">
79 96 <?php esc_html_e(
80 97 'Upgrade plan now',
81 98 'image-optimization'
82 99 ); ?>
@@ -86,8 +103,54 @@
86 103 </div>
87 104 <?php
88 105 }
89 106
107 + public function maybe_add_80_quota_reached_notice() {
108 + // @var ImageOptimizer/Modules/ConnectManager/Module
109 + $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
110 +
111 + $connect_status = $module->connect_instance->get_connect_status();
112 +
113 + if ( ! isset( $connect_status->quota ) || ! isset( $connect_status->used_quota ) ) {
114 + return;
115 + }
116 +
117 + $usage = $connect_status->used_quota / $connect_status->quota * 100;
118 +
119 + if ( $usage < 80 || 100 === $usage ) {
120 + return;
121 + }
122 +
123 + $upgrade_link = Utils::get_upgrade_link( 'https://go.elementor.com/io-quota-upgrade/' );
124 +
125 + ?>
126 + <div class="notice notice-warning notice image-optimizer__notice image-optimizer__notice--warning">
127 + <p>
128 + <b>
129 + <?php esc_html_e(
130 + 'You’ve used 80% of your plan quota.',
131 + 'image-optimization'
132 + ); ?>
133 + </b>
134 +
135 + <span>
136 + <?php esc_html_e(
137 + 'Upgrade now to avoid interruptions.',
138 + 'image-optimization'
139 + ); ?>
140 +
141 + <a href="<?php echo esc_url( $upgrade_link ); ?>">
142 + <?php esc_html_e(
143 + 'Upgrade plan now',
144 + 'image-optimization'
145 + ); ?>
146 + </a>
147 + </span>
148 + </p>
149 + </div>
150 + <?php
151 + }
152 +
90 153 public function maybe_add_url_mismatch_notice() {
91 154 // @var ImageOptimizer/Modules/ConnectManager/Module
92 155 $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
93 156
@@ -94,8 +157,10 @@
94 157 if ( $module->connect_instance->is_valid_home_url() ) {
95 158 return;
96 159 }
97 160
161 + $onclick = self::is_elementor_one() ? 'window.location.href = "' . self::ONE_MISMATCH_URL . '";' : 'document.dispatchEvent( new Event( "image-optimizer/auth/url-mismatch-modal/open" ) );';
162 +
98 163 ?>
99 164 <div class="notice notice-error notice image-optimizer__notice image-optimizer__notice--error">
100 165 <p>
101 166 <b>
@@ -110,9 +175,9 @@
110 175 'This is most likely due to a change in the domain URL of your site (including HTTP/SSL migration).',
111 176 'image-optimization'
112 177 ); ?>
113 178
114 - <button type="button" onclick="document.dispatchEvent( new Event( 'image-optimizer/auth/url-mismatch-modal/open' ) );">
179 + <button type="button" onclick="<?php echo esc_js( $onclick ); ?>">
115 180 <?php esc_html_e(
116 181 'Fix mismatched URL',
117 182 'image-optimization'
118 183 ); ?>
@@ -122,11 +187,15 @@
122 187 </div>
123 188 <?php
124 189 }
125 190
126 - public function add_plugin_links( $links, $plugin_file_name ): array {
191 + public function add_plugin_links( $links, $plugin_file_name ) {
192 + if ( ! is_array( $links ) ) {
193 + return $links;
194 + }
195 +
127 196 if ( ! str_ends_with( $plugin_file_name, '/image-optimization.php' ) ) {
128 - return (array) $links;
197 + return $links;
129 198 }
130 199
131 200 $custom_links = [
132 201 'settings' => sprintf(
@@ -137,17 +206,18 @@
137 206 ];
138 207 // @var ImageOptimizer/Modules/ConnectManager/Module
139 208 $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
140 209
141 - if ( $module->connect_instance->is_connected() ) {
210 + if ( $module->connect_instance->is_connected() && ! self::is_elementor_one() ) {
142 211 $custom_links['upgrade'] = sprintf(
143 - '<a href="%s" style="color: #524CFF; font-weight: 700;" target="_blank" rel="noopener noreferrer">%s</a>',
144 - 'https://go.elementor.com/io-plugins-upgrade/',
212 + '<a href="%s" style="color: #524cff; font-weight: 700;" target="_blank" rel="noopener noreferrer">%s</a>',
213 + Utils::get_upgrade_link( 'https://go.elementor.com/io-plugins-upgrade/' ),
145 214 esc_html__( 'Upgrade', 'image-optimization' )
146 215 );
147 - } else {
216 + }
217 + if ( ! $module->connect_instance->is_connected() ) {
148 218 $custom_links['connect'] = sprintf(
149 - '<a href="%s" style="color: #524CFF; font-weight: 700;">%s</a>',
219 + '<a href="%s" style="color: #524cff; font-weight: 700;">%s</a>',
150 220 admin_url( 'admin.php?page=' . \ImageOptimization\Modules\Settings\Module::SETTING_BASE_SLUG ),
151 221 esc_html__( 'Connect', 'image-optimization' )
152 222 );
153 223 }
@@ -195,8 +265,10 @@
195 265 [
196 266 'siteUrl' => wp_parse_url( get_site_url(), PHP_URL_HOST ),
197 267 'thumbnailSizes' => wp_get_registered_image_subsizes(),
198 268 'isDevelopment' => defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG,
269 + 'isRTL' => is_rtl(),
270 + 'version' => IMAGE_OPTIMIZATION_VERSION,
199 271 ]
200 272 );
201 273
202 274 /**
@@ -202,9 +274,8 @@
202 274 /**
203 275 * @var ImageOptimizer\Modules\ConnectManager\Module $module
204 276 */
205 277 $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
206 - $is_connect_on_fly = $module->connect_instance->get_is_connect_on_fly();
207 278 $connect_email = $module->connect_instance->get_connect_data()['user']['email'] ?? null;
208 279 $show_reset = ! $module->connect_instance->is_connected()
209 280 && ( $module->connect_instance->get_client_id() || $module->connect_instance->get_client_secret() );
210 281
@@ -211,10 +282,14 @@
211 282 wp_localize_script(
212 283 'image-optimization-admin',
213 284 'imageOptimizerUserData',
214 285 [
215 - 'isConnectOnFly' => $is_connect_on_fly,
286 + 'isConnectOnFly' => self::is_connect_on_fly(),
216 287 'isConnected' => $module->connect_instance->is_connected(),
288 + 'isElementorOne' => self::is_elementor_one(),
289 + 'hasElementorOneSubscription' => self::has_elementor_one_subscription(),
290 + 'isMigrationPopupDismissed' => (bool) Settings::get( Settings::MIGRATION_POPUP_DISMISSED ),
291 + 'currentPage' => get_current_screen()->base,
217 292 'isActivated' => $module->connect_instance->is_activated(),
218 293 'isUrlMismatch' => ! $module->connect_instance->is_valid_home_url(),
219 294 'planData' => $module->connect_instance->is_activated() ? $module->connect_instance->get_connect_status() : null,
220 295 'licenseKey' => $module->connect_instance->is_activated() ? $module->connect_instance->get_activation_state() : null,
@@ -221,8 +296,10 @@
221 296 'imagesLeft' => $module->connect_instance->is_activated() ? $module->connect_instance->images_left() : null,
222 297 'isOwner' => $module->connect_instance->is_connected() ? $module->connect_instance->user_is_subscription_owner() : null,
223 298 'subscriptionEmail' => $connect_email ? $connect_email : null,
224 299 'showResetButton' => $show_reset,
300 + 'maxFileSize' => Validate_Image::get_max_file_size(),
301 + 'helpVideos' => Settings::get( Settings::HELP_VIDEOS ),
225 302
226 303 'wpRestNonce' => wp_create_nonce( 'wp_rest' ),
227 304 'disconnect' => wp_create_nonce( 'wp_rest' ),
228 305 'authInitNonce' => wp_create_nonce( $module->connect_instance->connect_init_nonce() ),
@@ -244,9 +321,131 @@
244 321 private function should_render(): bool {
245 322 return ( Utils::is_media_page() || Utils::is_plugin_page() ) && Utils::user_is_admin();
246 323 }
247 324
325 + private static function is_connect_on_fly(): bool {
326 + /**
327 + * @var ImageOptimizer\Modules\ConnectManager\Module $module
328 + */
329 + $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
330 + return $module->connect_instance->get_is_connect_on_fly();
331 + }
332 +
333 + public static function is_elementor_one(): bool {
334 +
335 + if ( ! self::is_connect_on_fly() ) {
336 + return false;
337 + }
338 +
339 + $connect = Connect_Module::get_connect();
340 +
341 + if ( ! $connect ) {
342 + return false;
343 + }
344 +
345 + return Connect_Module::get_connect()->get_config( 'app_type' ) !== Config::APP_TYPE;
346 + }
347 +
248 348 /**
349 + * Check if user generally has an active Elementor One subscription.
350 + * @return bool
351 + */
352 + public static function has_elementor_one_subscription(): bool {
353 + $one_facade = \ElementorOne\Admin\Helpers\Utils::get_one_connect();
354 + return $one_facade && $one_facade->utils()->is_connected();
355 + }
356 +
357 + public static function on_deactivation(): void {
358 + $optimization_query = ( new Operation_Query() )
359 + ->set_queue( Async_Operation_Queue::OPTIMIZE )
360 + ->set_status( [ Async_Operation::OPERATION_STATUS_PENDING, Async_Operation::OPERATION_STATUS_RUNNING ] )
361 + ->set_limit( -1 );
362 +
363 + $restoring_query = ( new Operation_Query() )
364 + ->set_queue( Async_Operation_Queue::RESTORE )
365 + ->set_status( [ Async_Operation::OPERATION_STATUS_PENDING, Async_Operation::OPERATION_STATUS_RUNNING ] )
366 + ->set_limit( -1 );
367 +
368 + $optimization_operations = Async_Operation::get( $optimization_query );
369 + $restoring_operations = Async_Operation::get( $restoring_query );
370 +
371 + foreach ( $optimization_operations as $operation ) {
372 + $image_id = $operation->get_args()['attachment_id'];
373 +
374 + if ( ! $image_id ) {
375 + continue;
376 + }
377 +
378 + Async_Operation::remove( [ $operation->get_id() ] );
379 +
380 + $image_meta = new Image_Meta( $image_id );
381 +
382 + if ( empty( $image_meta->get_optimized_sizes() ) ) {
383 + $image_meta->delete();
384 + } else {
385 + $image_meta
386 + ->set_status( Image_Status::OPTIMIZATION_FAILED )
387 + ->set_error_type( Image_Optimization_Error_Type::PLUGIN_DEACTIVATION )
388 + ->save();
389 + }
390 + }
391 +
392 + foreach ( $restoring_operations as $operation ) {
393 + $image_id = $operation->get_args()['attachment_id'];
394 +
395 + if ( ! $image_id ) {
396 + continue;
397 + }
398 +
399 + Async_Operation::remove( [ $operation->get_id() ] );
400 +
401 + $image_meta = new Image_Meta( $image_id );
402 +
403 + $image_meta
404 + ->set_status( Image_Status::RESTORING_FAILED )
405 + ->set_error_type( Image_Optimization_Error_Type::PLUGIN_DEACTIVATION )
406 + ->save();
407 + }
408 + }
409 +
410 + /**
411 + * Renders the Bulk Optimization link on the media pages.
412 + *
413 + * @return void
414 + */
415 + public function add_bulk_optimization_links(): void {
416 + $page_url = add_query_arg(
417 + [
418 + 'page' => 'image-optimization-settings',
419 + 'tab' => 'image-optimization-bulk-optimization',
420 + ],
421 + admin_url( 'admin.php' )
422 + );
423 +
424 + ?>
425 + <script>
426 + document.addEventListener( 'DOMContentLoaded', function () {
427 + // Grid media is rendered by JS, so the timeout is required
428 + setTimeout( () => {
429 + const targetButton = document.querySelector( '.filter-items .actions input[type=submit]' ) ||
430 + document.querySelector( '.media-toolbar-secondary .select-mode-toggle-button' );
431 +
432 + if ( targetButton ) {
433 + const link = document.createElement('a');
434 +
435 + link.href = '<?php echo esc_js( $page_url ); ?>';
436 + link.innerText = '<?php echo esc_js( __( 'Bulk Optimization', 'image-optimization' ) ); ?>';
437 + link.className = 'button button-compact is-primary image-optimizer__button image-optimizer__button--pink';
438 +
439 + targetButton.insertAdjacentElement( 'afterend', link );
440 + }
441 + }, 100 )
442 + } );
443 + </script>
444 + <?php
445 + }
446 +
447 + /**
249 448 * Module constructor.
250 449 */
251 450 public function __construct() {
252 451 $this->register_components();
@@ -260,15 +459,16 @@
260 459 if ( ! $this->should_render() ) {
261 460 return;
262 461 }
263 462
264 - add_action( 'admin_notices', [ $this, 'maybe_add_quota_reached_notice' ] );
463 + if ( ! self::is_elementor_one() ) {
464 + add_action( 'admin_notices', [ $this, 'maybe_add_quota_reached_notice' ] );
465 + add_action( 'admin_notices', [ $this, 'maybe_add_80_quota_reached_notice' ] );
466 + }
467 +
265 468 add_action( 'admin_notices', [ $this, 'maybe_add_url_mismatch_notice' ] );
266 469
267 470 if ( Utils::is_media_page() ) {
268 - add_action('in_admin_header', function () {
269 - $this->render_top_bar();
270 - });
271 471
272 472 add_action('all_admin_notices', function () {
273 473 $this->render_app();
274 474 });
@@ -282,7 +482,11 @@
282 482
283 483 add_action('admin_enqueue_scripts', function () {
284 484 $this->enqueue_scripts();
285 485 });
486 +
487 + if ( Utils::is_media_page() ) {
488 + add_action( 'admin_enqueue_scripts', [ $this, 'add_bulk_optimization_links' ] );
489 + }
286 490 });
287 491 }
288 492 }