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 +222 -17 1.6.11.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,8 +46,11 @@
32 46 'Migrations',
33 47 'Conflicts',
34 48 'User_Feedback',
35 49 'Not_Connected',
50 + 'Not_Connected_Modal',
51 + 'Renewal_Notice',
52 + 'Notificator',
36 53 ];
37 54 }
38 55
39 56 private function render_top_bar() {
@@ -52,8 +69,9 @@
52 69 public function maybe_add_quota_reached_notice() {
53 70
54 71 // @var ImageOptimizer/Modules/ConnectManager/Module
55 72 $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
73 + $upgrade_link = Utils::get_upgrade_link( 'https://go.elementor.com/io-quota-upgrade/' );
56 74
57 75 if ( ! $module->connect_instance->get_connect_status() || $module->connect_instance->images_left() > 0 ) {
58 76 return;
59 77 }
@@ -73,9 +91,9 @@
73 91 'You have no images left to optimize in your current plan.',
74 92 'image-optimization'
75 93 ); ?>
76 94
77 - <a href="https://go.elementor.com/io-quota-upgrade/">
95 + <a href="<?php echo esc_url( $upgrade_link ); ?>">
78 96 <?php esc_html_e(
79 97 'Upgrade plan now',
80 98 'image-optimization'
81 99 ); ?>
@@ -85,8 +103,54 @@
85 103 </div>
86 104 <?php
87 105 }
88 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 +
89 153 public function maybe_add_url_mismatch_notice() {
90 154 // @var ImageOptimizer/Modules/ConnectManager/Module
91 155 $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
92 156
@@ -93,8 +157,10 @@
93 157 if ( $module->connect_instance->is_valid_home_url() ) {
94 158 return;
95 159 }
96 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 +
97 163 ?>
98 164 <div class="notice notice-error notice image-optimizer__notice image-optimizer__notice--error">
99 165 <p>
100 166 <b>
@@ -109,9 +175,9 @@
109 175 'This is most likely due to a change in the domain URL of your site (including HTTP/SSL migration).',
110 176 'image-optimization'
111 177 ); ?>
112 178
113 - <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 ); ?>">
114 180 <?php esc_html_e(
115 181 'Fix mismatched URL',
116 182 'image-optimization'
117 183 ); ?>
@@ -121,11 +187,15 @@
121 187 </div>
122 188 <?php
123 189 }
124 190
125 - 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 +
126 196 if ( ! str_ends_with( $plugin_file_name, '/image-optimization.php' ) ) {
127 - return (array) $links;
197 + return $links;
128 198 }
129 199
130 200 $custom_links = [
131 201 'settings' => sprintf(
@@ -136,17 +206,18 @@
136 206 ];
137 207 // @var ImageOptimizer/Modules/ConnectManager/Module
138 208 $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
139 209
140 - if ( $module->connect_instance->is_connected() ) {
210 + if ( $module->connect_instance->is_connected() && ! self::is_elementor_one() ) {
141 211 $custom_links['upgrade'] = sprintf(
142 - '<a href="%s" style="color: #524CFF; font-weight: 700;" target="_blank" rel="noopener noreferrer">%s</a>',
143 - '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/' ),
144 214 esc_html__( 'Upgrade', 'image-optimization' )
145 215 );
146 - } else {
216 + }
217 + if ( ! $module->connect_instance->is_connected() ) {
147 218 $custom_links['connect'] = sprintf(
148 - '<a href="%s" style="color: #524CFF; font-weight: 700;">%s</a>',
219 + '<a href="%s" style="color: #524cff; font-weight: 700;">%s</a>',
149 220 admin_url( 'admin.php?page=' . \ImageOptimization\Modules\Settings\Module::SETTING_BASE_SLUG ),
150 221 esc_html__( 'Connect', 'image-optimization' )
151 222 );
152 223 }
@@ -194,8 +265,10 @@
194 265 [
195 266 'siteUrl' => wp_parse_url( get_site_url(), PHP_URL_HOST ),
196 267 'thumbnailSizes' => wp_get_registered_image_subsizes(),
197 268 'isDevelopment' => defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG,
269 + 'isRTL' => is_rtl(),
270 + 'version' => IMAGE_OPTIMIZATION_VERSION,
198 271 ]
199 272 );
200 273
201 274 /**
@@ -201,9 +274,8 @@
201 274 /**
202 275 * @var ImageOptimizer\Modules\ConnectManager\Module $module
203 276 */
204 277 $module = Plugin::instance()->modules_manager->get_modules( 'connect-manager' );
205 - $is_connect_on_fly = $module->connect_instance->get_is_connect_on_fly();
206 278 $connect_email = $module->connect_instance->get_connect_data()['user']['email'] ?? null;
207 279 $show_reset = ! $module->connect_instance->is_connected()
208 280 && ( $module->connect_instance->get_client_id() || $module->connect_instance->get_client_secret() );
209 281
@@ -210,10 +282,14 @@
210 282 wp_localize_script(
211 283 'image-optimization-admin',
212 284 'imageOptimizerUserData',
213 285 [
214 - 'isConnectOnFly' => $is_connect_on_fly,
286 + 'isConnectOnFly' => self::is_connect_on_fly(),
215 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,
216 292 'isActivated' => $module->connect_instance->is_activated(),
217 293 'isUrlMismatch' => ! $module->connect_instance->is_valid_home_url(),
218 294 'planData' => $module->connect_instance->is_activated() ? $module->connect_instance->get_connect_status() : null,
219 295 'licenseKey' => $module->connect_instance->is_activated() ? $module->connect_instance->get_activation_state() : null,
@@ -220,8 +296,10 @@
220 296 'imagesLeft' => $module->connect_instance->is_activated() ? $module->connect_instance->images_left() : null,
221 297 'isOwner' => $module->connect_instance->is_connected() ? $module->connect_instance->user_is_subscription_owner() : null,
222 298 'subscriptionEmail' => $connect_email ? $connect_email : null,
223 299 'showResetButton' => $show_reset,
300 + 'maxFileSize' => Validate_Image::get_max_file_size(),
301 + 'helpVideos' => Settings::get( Settings::HELP_VIDEOS ),
224 302
225 303 'wpRestNonce' => wp_create_nonce( 'wp_rest' ),
226 304 'disconnect' => wp_create_nonce( 'wp_rest' ),
227 305 'authInitNonce' => wp_create_nonce( $module->connect_instance->connect_init_nonce() ),
@@ -243,9 +321,131 @@
243 321 private function should_render(): bool {
244 322 return ( Utils::is_media_page() || Utils::is_plugin_page() ) && Utils::user_is_admin();
245 323 }
246 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 +
247 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 + /**
248 448 * Module constructor.
249 449 */
250 450 public function __construct() {
251 451 $this->register_components();
@@ -259,15 +459,16 @@
259 459 if ( ! $this->should_render() ) {
260 460 return;
261 461 }
262 462
263 - 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 +
264 468 add_action( 'admin_notices', [ $this, 'maybe_add_url_mismatch_notice' ] );
265 469
266 470 if ( Utils::is_media_page() ) {
267 - add_action('in_admin_header', function () {
268 - $this->render_top_bar();
269 - });
270 471
271 472 add_action('all_admin_notices', function () {
272 473 $this->render_app();
273 474 });
@@ -281,7 +482,11 @@
281 482
282 483 add_action('admin_enqueue_scripts', function () {
283 484 $this->enqueue_scripts();
284 485 });
486 +
487 + if ( Utils::is_media_page() ) {
488 + add_action( 'admin_enqueue_scripts', [ $this, 'add_bulk_optimization_links' ] );
489 + }
285 490 });
286 491 }
287 492 }