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