PluginProbe ʕ •ᴥ•ʔ
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN / 3.23.4
Smush – Image Optimization, Compression, Lazy Load, WebP & CDN v3.23.4
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 / app / class-admin.php
wp-smushit / app Last commit date
assets 3 months ago common 3 months ago modals 3 months ago pages 3 months ago views 3 months ago class-abstract-page.php 3 months ago class-abstract-summary-page.php 3 months ago class-admin.php 3 months ago class-ajax.php 3 months ago class-interface-page.php 3 months ago class-media-library.php 3 months ago class-settings-row.php 3 months ago
class-admin.php
1049 lines
1 <?php
2 /**
3 * Admin class.
4 *
5 * @package Smush\App
6 */
7
8 namespace Smush\App;
9
10 use Smush\Core\Core;
11 use Smush\Core\Error_Handler;
12 use Smush\Core\Helper;
13 use Smush\Core\Next_Gen\Next_Gen_Manager;
14 use Smush\Core\Settings;
15 use Smush\Core\Stats\Global_Stats;
16 use Smush\Core\Membership\Membership;
17 use WP_Smush;
18
19 if ( ! defined( 'WPINC' ) ) {
20 die;
21 }
22
23 /**
24 * Class Admin
25 */
26 class Admin {
27 private static $plugin_discount_percent = 80;
28 private static $cdn_pop_locations = 123;
29 private static $review_prompts_option_key = 'wp-smush-review_prompt_next_show';
30 private static $review_prompts_min_images = 10;
31 private static $review_prompts_optimized_images_threshold = 100;
32 private static $review_prompts_optimization_failed_percent_threshold = 10;
33
34 /**
35 * Plugin pages.
36 *
37 * @var array
38 */
39 public $pages = array();
40
41 /**
42 * AJAX module.
43 *
44 * @var Ajax
45 */
46 public $ajax;
47
48 /**
49 * List of smush settings pages.
50 *
51 * @var array $plugin_pages
52 */
53 public static $plugin_pages = array(
54 'gallery_page_wp-smush-nextgen-bulk',
55 'nextgen-gallery_page_wp-smush-nextgen-bulk', // Different since NextGen 3.3.6.
56 'toplevel_page_smush',
57 'toplevel_page_smush-network',
58 );
59
60 /**
61 * Admin constructor.
62 *
63 * @param Media_Library $media_lib Media uploads library.
64 */
65 public function __construct( $media_lib ) {
66 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
67
68 add_action( 'admin_menu', array( $this, 'add_menu_pages' ) );
69 add_action( 'network_admin_menu', array( $this, 'add_menu_pages' ) );
70
71 add_action( 'admin_init', array( $this, 'smush_i18n' ) );
72 // Add information to privacy policy page (only during creation).
73 add_action( 'admin_init', array( $this, 'add_policy' ) );
74
75 if ( wp_doing_ajax() ) {
76 $this->ajax = new Ajax();
77 }
78
79 // Init media library UI.
80 $media_lib->init_ui();
81
82 add_filter( 'plugin_action_links_' . WP_SMUSH_BASENAME, array( $this, 'dashboard_link' ) );
83 add_filter( 'network_admin_plugin_action_links_' . WP_SMUSH_BASENAME, array( $this, 'dashboard_link' ) );
84 add_filter( 'plugin_row_meta', array( $this, 'add_plugin_meta_links' ), 10, 2 );
85
86 // Prints a membership validation issue notice in Media Library.
87 add_action( 'admin_notices', array( $this, 'media_library_membership_notice' ) );
88
89 // Plugin conflict notice.
90 add_action( 'admin_notices', array( $this, 'show_plugin_conflict_notice' ) );
91 add_action( 'admin_notices', array( $this, 'show_parallel_unavailability_notice' ) );
92 add_action( 'admin_notices', array( $this, 'show_background_unavailability_notice' ) );
93 add_action( 'smush_check_for_conflicts', array( $this, 'check_for_conflicts_cron' ) );
94 add_action( 'activated_plugin', array( $this, 'check_for_conflicts_cron' ) );
95 add_action( 'deactivated_plugin', array( $this, 'check_for_conflicts_cron' ) );
96
97 // Filter built-in wpmudev branding script.
98 add_filter( 'wpmudev_whitelabel_plugin_pages', array( $this, 'builtin_wpmudev_branding' ) );
99 add_action( 'wp_smush_header_notices', array( $this, 'maybe_show_local_webp_convert_original_images_notice' ) );
100
101 // Deactivation survey.
102 add_action( 'admin_footer-plugins.php', array( $this, 'load_deactivation_survey_modal' ) );
103
104 add_action( 'all_admin_notices', array( $this, 'maybe_show_review_prompts' ) );
105 }
106
107 public static function get_cdn_pop_locations() {
108 return self::$cdn_pop_locations;
109 }
110
111 /**
112 * Get review_prompts_option_key.
113 *
114 * @return mixed
115 */
116 public static function get_review_prompts_option_key() {
117 return self::$review_prompts_option_key;
118 }
119
120 /**
121 * Load translation files.
122 */
123 public function smush_i18n() {
124 load_plugin_textdomain(
125 'wp-smushit',
126 false,
127 dirname( WP_SMUSH_BASENAME ) . '/languages'
128 );
129 }
130
131 /**
132 * Register JS and CSS.
133 */
134 private function register_scripts() {
135 global $wp_version;
136 /**
137 * Queue clipboard.js from your plugin if WP's version is below 5.2.0
138 * since it's only included from 5.2.0 on.
139 *
140 * Use 'clipboard' as the handle so it matches WordPress' handle for the script.
141 *
142 * @since 3.8.0
143 */
144 if ( version_compare( $wp_version, '5.2', '<' ) ) {
145 wp_register_script( 'clipboard', WP_SMUSH_URL . 'app/assets/js/smush-clipboard.min.js', array(), WP_SMUSH_VERSION, true );
146 }
147
148 /**
149 * Share UI JS.
150 *
151 * @since 3.8.0 added 'clipboard' dependency.
152 */
153 wp_register_script( 'smush-sui', WP_SMUSH_URL . 'app/assets/js/smush-sui.min.js', array( 'jquery', 'clipboard' ), WP_SHARED_UI_VERSION, true );
154
155 // Main JS.
156 wp_register_script( 'smush-admin', WP_SMUSH_URL . 'app/assets/js/smush-admin.min.js', array( 'jquery', 'smush-sui', 'underscore', 'wp-color-picker' ), WP_SMUSH_VERSION, true );
157
158 // JS that can be used on all pages in the WP backend.
159 wp_register_script( 'smush-admin-common', WP_SMUSH_URL . 'app/assets/js/smush-admin-common.min.js', array( 'jquery' ), WP_SMUSH_VERSION, true );
160
161 // Main CSS.
162 wp_register_style( 'smush-admin', WP_SMUSH_URL . 'app/assets/css/smush-admin.min.css', array(), WP_SMUSH_VERSION );
163
164 // Styles that can be used on all pages in the WP backend.
165 wp_register_style( 'smush-admin-common', WP_SMUSH_URL . 'app/assets/css/smush-global.min.css', array(), WP_SMUSH_VERSION );
166
167 // Dismiss update info.
168 WP_Smush::get_instance()->core()->mod->smush->dismiss_update_info();
169 }
170
171 /**
172 * Enqueue scripts.
173 */
174 public function enqueue_scripts() {
175 wp_enqueue_script( 'smush-global', WP_SMUSH_URL . 'app/assets/js/smush-global.min.js', array(), WP_SMUSH_VERSION, true );
176 wp_localize_script( 'smush-global', 'smush_global', array(
177 'nonce' => wp_create_nonce( 'wp-smush-ajax' ),
178 ) );
179
180 wp_localize_script(
181 'smush-global',
182 'wp_smush_mixpanel',
183 array(
184 'opt_in' => Settings::get_instance()->get( 'usage' ),
185 )
186 );
187
188 $current_page = '';
189 $current_screen = '';
190
191 if ( function_exists( 'get_current_screen' ) ) {
192 $current_screen = get_current_screen();
193 $current_page = ! empty( $current_screen ) ? $current_screen->base : $current_page;
194 }
195
196 if ( 'plugins' === $current_page || 'plugins-network' === $current_page ) {
197 $this->register_scripts();
198 wp_enqueue_script( 'smush-sui' );
199 wp_enqueue_style( 'smush-admin' );
200 return;
201 }
202
203 if ( ! in_array( $current_page, Core::$external_pages, true ) && false === strpos( $current_page, 'page_smush' ) ) {
204 return;
205 }
206
207 // Allows to disable enqueuing smush files on a particular page.
208 if ( ! apply_filters( 'wp_smush_enqueue', true ) ) {
209 return;
210 }
211
212 $this->register_scripts();
213
214 // Load on all Smush page only.
215 if ( isset( $current_screen->id ) && ( in_array( $current_screen->id, self::$plugin_pages, true ) || false !== strpos( $current_screen->id, 'page_smush' ) ) ) {
216 // Smush admin (smush-admin) includes the Shared UI.
217 wp_enqueue_style( 'smush-admin' );
218 wp_enqueue_script( 'smush-wpmudev-sui' );
219 }
220
221 if ( ! in_array( $current_page, array( 'post', 'post-new', 'page', 'edit-page' ), true ) ) {
222 // Skip these pages where the script isn't used.
223 wp_enqueue_script( 'smush-admin' );
224 } else {
225 // Otherwise, load only the common JS code.
226 wp_enqueue_script( 'smush-admin-common' );
227 }
228
229 // We need it on media pages and Smush pages.
230 wp_enqueue_style( 'smush-admin-common' );
231
232 // Localize translatable strings for js.
233 WP_Smush::get_instance()->core()->localize();
234 }
235
236 /**
237 * Adds a Smush pro settings link on plugin page.
238 *
239 * @param array $links Current links.
240 *
241 * @return array|string
242 */
243 public function dashboard_link( $links ) {
244 // Upgrade link.
245 if ( ! WP_Smush::is_pro() ) {
246 $upgrade_url = add_query_arg(
247 array(
248 'utm_source' => 'smush',
249 'utm_medium' => 'plugin',
250 'utm_campaign' => 'wp-smush-pro/wp-smush.php' !== WP_SMUSH_BASENAME ? 'smush_pluginlist_upgrade' : 'smush_pluginlist_renew',
251 ),
252 esc_url( 'https://wpmudev.com/project/wp-smush-pro/' )
253 );
254
255 $using_free_version = 'wp-smush-pro/wp-smush.php' !== WP_SMUSH_BASENAME;
256 if ( $using_free_version ) {
257 $label = __( 'Upgrade to Smush Pro', 'wp-smushit' );
258 $text = __( 'Get Smush Pro', 'wp-smushit' );
259 } else {
260 $label = __( 'Renew Membership', 'wp-smushit' );
261 $text = __( 'Renew Membership', 'wp-smushit' );
262 }
263
264 if ( isset( $text ) ) {
265 $links['smush_upgrade'] = '<a id="smush-pluginlist-upgrade-link" href="' . esc_url( $upgrade_url ) . '" aria-label="' . esc_attr( $label ) . '" target="_blank" style="color: #8D00B1;">' . esc_html( $text ) . '</a>';
266 }
267 }
268
269 // Documentation link.
270 $docs_link = Helper::get_utm_link(
271 array( 'utm_campaign' => 'smush_pluginlist_docs' ),
272 'https://wpmudev.com/docs/wpmu-dev-plugins/smush/'
273 );
274 $links['smush_docs'] = '<a href="' . esc_url( $docs_link ) . '" aria-label="' . esc_attr( __( 'View Smush Documentation', 'wp-smushit' ) ) . '" target="_blank">' . esc_html__( 'Docs', 'wp-smushit' ) . '</a>';
275
276 // Dashboard link.
277 $dashboard_page = is_multisite() && is_network_admin() ? network_admin_url( 'admin.php?page=smush' ) : menu_page_url( 'smush', false );
278 $links['smush_dashboard'] = '<a href="' . esc_url( $dashboard_page ) . '" aria-label="' . esc_attr( __( 'Go to Smush Dashboard', 'wp-smushit' ) ) . '">' . esc_html__( 'Dashboard', 'wp-smushit' ) . '</a>';
279
280 $access = get_site_option( 'wp-smush-networkwide' );
281 if ( ! is_network_admin() && is_plugin_active_for_network( WP_SMUSH_BASENAME ) && ! $access ) {
282 // Remove settings link for subsites if Subsite Controls is not set on network permissions tab.
283 unset( $links['smush_dashboard'] );
284 }
285
286 return array_reverse( $links );
287 }
288
289 /**
290 * Add additional links next to the plugin version.
291 *
292 * @since 3.5.0
293 *
294 * @param array $links Links array.
295 * @param string $file Plugin basename.
296 *
297 * @return array
298 */
299 public function add_plugin_meta_links( $links, $file ) {
300 if ( ! defined( 'WP_SMUSH_BASENAME' ) || WP_SMUSH_BASENAME !== $file ) {
301 return $links;
302 }
303
304 if ( 'wp-smush-pro/wp-smush.php' !== WP_SMUSH_BASENAME ) {
305 $links[] = '<a href="https://wordpress.org/support/plugin/wp-smushit/reviews/?filter=5#new-post" target="_blank" title="' . esc_attr__( 'Rate Smush', 'wp-smushit' ) . '">' . esc_html__( 'Rate Smush', 'wp-smushit' ) . '</a>';
306 $links[] = '<a href="https://wordpress.org/support/plugin/wp-smushit/" target="_blank" title="' . esc_attr__( 'Support', 'wp-smushit' ) . '">' . esc_html__( 'Support', 'wp-smushit' ) . '</a>';
307 } else {
308 if ( isset( $links[2] ) && false !== strpos( $links[2], 'project/wp-smush-pro' ) ) {
309 $links[2] = sprintf(
310 '<a href="https://wpmudev.com/project/wp-smush-pro/" target="_blank">%s</a>',
311 __( 'View details', 'wp-smushit' )
312 );
313 }
314
315 $links[] = '<a href="https://wpmudev.com/get-support/" target="_blank" title="' . esc_attr__( 'Premium Support', 'wp-smushit' ) . '">' . esc_html__( 'Premium Support', 'wp-smushit' ) . '</a>';
316 }
317
318 $roadmap_link = Helper::get_utm_link(
319 array(
320 'utm_campaign' => 'smush_pluginlist_roadmap',
321 ),
322 'https://wpmudev.com/roadmap/'
323 );
324 $links[] = '<a href="' . esc_url( $roadmap_link ) . '" target="_blank" title="' . esc_attr__( 'Roadmap', 'wp-smushit' ) . '">' . esc_html__( 'Roadmap', 'wp-smushit' ) . '</a>';
325
326 $links[] = '<a class="wp-smush-review" href="https://wordpress.org/support/plugin/wp-smushit/reviews/?filter=5#new-post" target="_blank" rel="noopener noreferrer" title="' . esc_attr__( 'Rate our plugin', 'wp-smushit' ) . '">
327 <span>�
328 </span><span>�
329 </span><span>�
330 </span><span>�
331 </span><span>�
332 </span>
333 </a>';
334
335 echo '<style>.wp-smush-review span,.wp-smush-review span:hover{color:#ffb900}.wp-smush-review span:hover~span{color:#888}</style>';
336
337 return $links;
338 }
339
340 /**
341 * Add menu pages.
342 */
343 public function add_menu_pages() {
344 $title = 'wp-smush-pro/wp-smush.php' === WP_SMUSH_BASENAME ? esc_html__( 'Smush Pro', 'wp-smushit' ) : esc_html__( 'Smush', 'wp-smushit' );
345
346 if ( Settings::can_access( false, true ) ) {
347 $this->pages['smush'] = new Pages\Dashboard( 'smush', $title );
348 $this->pages['dashboard'] = new Pages\Dashboard( 'smush', __( 'Dashboard', 'wp-smushit' ), 'smush' );
349
350 if ( Abstract_Page::should_render( 'bulk' ) ) {
351 $this->pages['bulk'] = new Pages\Bulk( 'smush-bulk', __( 'Bulk Smush', 'wp-smushit' ), 'smush' );
352 }
353
354 if ( Abstract_Page::should_render( Settings::get_lazy_preload_module_name() ) ) {
355 $pro_feature_ripple_effect = Abstract_Page::should_show_new_feature_hotspot() ? '<span class="smush-new-feature-dot"></span>' : '';
356 $this->pages['lazy-preload'] = new Pages\Lazy_Preload( 'smush-lazy-preload', __( 'Lazy Load & Preload', 'wp-smushit' ) . $pro_feature_ripple_effect, 'smush' );
357 }
358
359 if ( Abstract_Page::should_render( 'cdn' ) ) {
360 $this->pages['cdn'] = new Pages\CDN( 'smush-cdn', __( 'CDN', 'wp-smushit' ), 'smush' );
361 }
362
363 if ( Abstract_Page::should_render( 'next-gen' ) ) {
364 $this->pages['next-gen'] = new Pages\Next_Gen( 'smush-next-gen', __( 'Next-Gen Formats', 'wp-smushit' ), 'smush' );
365 }
366
367 if ( Abstract_Page::should_render( 'integrations' ) ) {
368 $this->pages['integrations'] = new Pages\Integrations( 'smush-integrations', __( 'Integrations', 'wp-smushit' ), 'smush' );
369 }
370
371 if ( ! is_multisite() || is_network_admin() ) {
372 $this->pages['settings'] = new Pages\Settings( 'smush-settings', __( 'Settings', 'wp-smushit' ), 'smush' );
373 }
374
375 if ( ! WP_Smush::is_pro() ) {
376 new Pages\Upgrade( 'smush_submenu_upsell', __( 'Get Smush Pro', 'wp-smushit' ), 'smush', true );
377 }
378 }
379
380 // Add a bulk smush option for NextGen gallery.
381 if ( defined( 'NGGFOLDER' ) && WP_Smush::get_instance()->core()->nextgen->is_enabled() && WP_Smush::is_pro() && ! is_network_admin() ) {
382 $this->pages['nextgen'] = new Pages\Nextgen( 'wp-smush-nextgen-bulk', $title, NGGFOLDER, true );
383 }
384 }
385
386 /**
387 * Add Smush Policy to "Privacy Policy" page during creation.
388 *
389 * @since 2.3.0
390 */
391 public function add_policy() {
392 if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
393 return;
394 }
395
396 $content = '<h3>' . __( 'Plugin: Smush', 'wp-smushit' ) . '</h3>';
397 $content .=
398 '<p>' . __( 'Note: Smush does not interact with end users on your website. The only input option Smush has is to a newsletter subscription for site admins only. If you would like to notify your users of this in your privacy policy, you can use the information below.', 'wp-smushit' ) . '</p>';
399 $content .=
400 '<p>' . __( 'Smush sends images to the WPMU DEV servers to optimize them for web use. This includes the transfer of EXIF data. The EXIF data will either be stripped or returned as it is. It is not stored on the WPMU DEV servers.', 'wp-smushit' ) . '</p>';
401 $content .=
402 '<p>' . sprintf( /* translators: %1$s - opening <a>, %2$s - closing </a> */
403 __( "Smush uses the Stackpath Content Delivery Network (CDN). Stackpath may store web log information of site visitors, including IPs, UA, referrer, Location and ISP info of site visitors for 7 days. Files and images served by the CDN may be stored and served from countries other than your own. Stackpath's privacy policy can be found %1\$shere%2\$s.", 'wp-smushit' ),
404 '<a href="https://www.stackpath.com/legal/privacy-statement/" target="_blank">',
405 '</a>'
406 ) . '</p>';
407
408 if ( strpos( WP_SMUSH_DIR, 'wp-smushit' ) !== false ) {
409 // Only for wordpress.org members.
410 $content .=
411 '<p>' . __( 'Smush uses a third-party email service (Drip) to send informational emails to the site administrator. The administrator\'s email address is sent to Drip and a cookie is set by the service. Only administrator information is collected by Drip.', 'wp-smushit' ) . '</p>';
412 }
413
414 wp_add_privacy_policy_content(
415 __( 'WP Smush', 'wp-smushit' ),
416 wp_kses_post( wpautop( $content, false ) )
417 );
418 }
419
420 /**
421 * Prints the Membership Validation issue notice
422 */
423 public function media_library_membership_notice() {
424 // No need to print it for free version.
425 if ( ! WP_Smush::is_pro() ) {
426 return;
427 }
428
429 // Show it on Media Library page only.
430 $screen = get_current_screen();
431 if ( ! empty( $screen ) && ( 'upload' === $screen->id || in_array( $screen->id, self::$plugin_pages, true ) || false !== strpos( $screen->id, 'page_smush' ) ) ) {
432 ?>
433 <div id="wp-smush-invalid-member" data-message="<?php esc_attr_e( 'Validating...', 'wp-smushit' ); ?>" class="hidden notice notice-warning is-dismissible">
434 <p>
435 <?php
436 printf(
437 /* translators: $1$s: recheck link, $2$s: closing a tag, %3$s; contact link, %4$s: closing a tag */
438 esc_html__(
439 'It looks like Smush couldn’t verify your WPMU DEV membership so Pro features have been disabled for now. If you think this is an error, run a %1$sre-check%2$s or get in touch with our %3$ssupport team%4$s.',
440 'wp-smushit'
441 ),
442 '<a href="#" id="wp-smush-revalidate-member" data-message="%s">',
443 '</a>',
444 '<a href="https://wpmudev.com/contact" target="_blank">',
445 '</a>'
446 );
447 ?>
448 </p>
449 </div>
450 <?php
451 }
452 }
453
454 /**
455 * Check for plugin conflicts cron.
456 *
457 * @since 3.6.0
458 *
459 * @param string $deactivated Holds the slug of activated/deactivated plugin.
460 */
461 public function check_for_conflicts_cron( $deactivated = '' ) {
462 $conflicting_plugins = array(
463 'autoptimize/autoptimize.php',
464 'ewww-image-optimizer/ewww-image-optimizer.php',
465 'imagify/imagify.php',
466 'resmushit-image-optimizer/resmushit.php',
467 'shortpixel-image-optimiser/wp-shortpixel.php',
468 'tiny-compress-images/tiny-compress-images.php',
469 'wp-rocket/wp-rocket.php',
470 'optimole-wp/optimole-wp.php',
471 // lazy load plugins.
472 'rocket-lazy-load/rocket-lazy-load.php',
473 'a3-lazy-load/a3-lazy-load.php',
474 'jetpack/jetpack.php',
475 'sg-cachepress/sg-cachepress.php',
476 'w3-total-cache/w3-total-cache.php',
477 'wp-fastest-cache/wpFastestCache.php',
478 'wp-optimize/wp-optimize.php',
479 'nitropack/main.php',
480 );
481
482 $plugins = get_plugins();
483
484 $active_plugins = array();
485 foreach ( $conflicting_plugins as $plugin ) {
486 if ( ! array_key_exists( $plugin, $plugins ) ) {
487 continue;
488 }
489
490 if ( ! is_plugin_active( $plugin ) ) {
491 continue;
492 }
493
494 // Deactivation of the plugin in process.
495 if ( doing_action( 'deactivated_plugin' ) && $deactivated === $plugin ) {
496 continue;
497 }
498
499 $active_plugins[] = $plugins[ $plugin ]['Name'];
500 }
501
502 set_transient( 'wp-smush-conflict_check', $active_plugins, 3600 );
503 }
504
505 /**
506 * Display plugin incompatibility notice.
507 *
508 * @since 3.6.0
509 */
510 public function show_plugin_conflict_notice() {
511 // Do not show on lazy load module, there we show an inline notice.
512 $is_lazy_preload_page = false !== strpos( get_current_screen()->id, 'page_smush-lazy-preload' );
513 if ( $is_lazy_preload_page ) {
514 return;
515 }
516
517 $dismissed = $this->is_notice_dismissed( 'plugin-conflict' );
518 if ( $dismissed ) {
519 return;
520 }
521
522 $conflict_check = get_transient( 'wp-smush-conflict_check' );
523
524 // Have never checked before.
525 if ( false === $conflict_check ) {
526 wp_schedule_single_event( time(), 'smush_check_for_conflicts' );
527 return;
528 }
529
530 // No conflicting plugins detected.
531 if ( isset( $conflict_check ) && is_array( $conflict_check ) && empty( $conflict_check ) ) {
532 return;
533 }
534
535 array_walk(
536 $conflict_check,
537 function( &$item ) {
538 $item = '<strong>' . $item . '</strong>';
539 }
540 );
541 ?>
542 <div class="notice notice-info is-dismissible smush-dismissible-notice"
543 id="smush-conflict-notice"
544 data-key="plugin-conflict">
545
546 <p><?php esc_html_e( 'You have multiple WordPress image optimization plugins installed. This may cause unpredictable behavior while optimizing your images, inaccurate reporting, or images to not display. For best results use only one image optimizer plugin at a time. These plugins may cause issues with Smush:', 'wp-smushit' ); ?></p>
547 <p>
548 <?php echo wp_kses_post( join( '<br>', $conflict_check ) ); ?>
549 </p>
550 <p>
551 <a href="<?php echo esc_url( admin_url( 'plugins.php' ) ); ?>" class="button button-primary">
552 <?php esc_html_e( 'Manage Plugins', 'wp-smushit' ); ?>
553 </a>
554 <a href="#"
555 style="margin-left: 15px"
556 id="smush-dismiss-conflict-notice" class="smush-dismiss-notice-button">
557
558 <?php esc_html_e( 'Dismiss', 'wp-smushit' ); ?>
559 </a>
560 </p>
561 </div>
562 <?php
563 }
564
565 /**
566 * Prints the content for pending images for the Bulk Smush section.
567 *
568 * @param int $remaining_count
569 * @param int $reoptimize_count
570 * @param int $optimize_count
571 *
572 * @since 3.7.2
573 */
574 public function print_pending_bulk_smush_content( $remaining_count, $reoptimize_count, $optimize_count ) {
575 $optimize_message = '';
576 if ( 0 < $optimize_count ) {
577 $optimize_message = sprintf(
578 /* translators: 1. opening strong tag, 2: unsmushed images count,3. closing strong tag. */
579 esc_html( _n( '%1$s%2$d attachment%3$s that needs smushing', '%1$s%2$d attachments%3$s that need smushing', $optimize_count, 'wp-smushit' ) ),
580 '<strong>',
581 absint( $optimize_count ),
582 '</strong>'
583 );
584 }
585
586 $reoptimize_message = '';
587 if ( 0 < $reoptimize_count ) {
588 $reoptimize_message = sprintf(
589 /* translators: 1. opening strong tag, 2: re-smush images count,3. closing strong tag. */
590 esc_html( _n( '%1$s%2$d attachment%3$s that needs re-smushing', '%1$s%2$d attachments%3$s that need re-smushing', $reoptimize_count, 'wp-smushit' ) ),
591 '<strong>',
592 esc_html( $reoptimize_count ),
593 '</strong>'
594 );
595 }
596
597 $bulk_limit_free_message = $this->generate_bulk_limit_message_for_free( $remaining_count );
598
599 $image_count_description = sprintf(
600 /* translators: 1. username, 2. unsmushed images message, 3. 'and' text for when having both unsmushed and re-smush images, 4. re-smush images message. */
601 __( '%1$s, you have %2$s%3$s%4$s! %5$s', 'wp-smushit' ),
602 esc_html( Helper::get_user_name() ),
603 $optimize_message,
604 ( $optimize_message && $reoptimize_message ? esc_html__( ' and ', 'wp-smushit' ) : '' ),
605 $reoptimize_message,
606 $bulk_limit_free_message
607 );
608 ?>
609 <span id="wp-smush-bulk-image-count"><?php echo esc_html( $remaining_count ); ?></span>
610 <p id="wp-smush-bulk-image-count-description">
611 <?php echo wp_kses_post( $image_count_description ); ?>
612 </p>
613 <?php
614 }
615
616 public function get_global_stats_with_bulk_smush_content() {
617 $core = WP_Smush::get_instance()->core();
618 $stats = $core->get_global_stats();
619 $global_stats = Global_Stats::get();
620 $remaining_count = $global_stats->get_remaining_count();
621 $optimize_count = $global_stats->get_optimize_list()->get_count();
622 $reoptimize_count = $global_stats->get_redo_count();
623
624 $stats['errors'] = Error_Handler::get_last_errors();
625
626 if ( $remaining_count > 0 ) {
627 ob_start();
628 WP_Smush::get_instance()->admin()->print_pending_bulk_smush_content(
629 $remaining_count,
630 $reoptimize_count,
631 $optimize_count
632 );
633 $content = ob_get_clean();
634 $stats['content'] = $content;
635 }
636
637 return $stats;
638 }
639
640 public function get_global_stats_with_bulk_smush_content_and_notice() {
641 $stats = $this->get_global_stats_with_bulk_smush_content();
642 $remaining_count = Global_Stats::get()->get_remaining_count();
643 if ( $remaining_count < 1 ) {
644 $stats['notice'] = esc_html__( 'Yay! All images are optimized as per your current settings.', 'wp-smushit' );
645 $stats['noticeType'] = 'success';
646 } else {
647 $stats['noticeType'] = 'warning';
648 $stats['notice'] = sprintf(
649 /* translators: %1$d - number of images, %2$s - opening a tag, %3$s - closing a tag */
650 esc_html__( 'Image check complete, you have %1$d images that need smushing. %2$sBulk smush now!%3$s', 'wp-smushit' ),
651 $remaining_count,
652 '<a href="#" class="wp-smush-trigger-bulk">',
653 '</a>'
654 );
655 }
656
657 return $stats;
658 }
659
660 private function generate_bulk_limit_message_for_free( $remaining_count ) {
661 $dont_limit = WP_Smush::get_instance()->core()->mod->bg_optimization->can_use_background();
662 if ( $dont_limit || $remaining_count < Core::get_max_free_bulk() ) {
663 return '';
664 }
665
666 $upgrade_url = add_query_arg(
667 array(
668 'utm_source' => 'smush',
669 'utm_medium' => 'plugin',
670 'utm_campaign' => 'smush_bulk_smush_pre_smush_50_limit',
671 ),
672 'https://wpmudev.com/project/wp-smush-pro/'
673 );
674 return sprintf(
675 /* translators: 1: max free bulk limit, 2: opening a tag, 3: closing a tag. */
676 esc_html__( 'Free users can only Bulk Smush %1$d images at one time. Skip limits, save time. Bulk Smush unlimited images — %2$sGet Smush Pro%3$s', 'wp-smushit' ),
677 Core::get_max_free_bulk(),
678 '<a class="smush-upsell-link" target="_blank" href="' . $upgrade_url . '">',
679 '</a>'
680 );
681 }
682
683 /**
684 * Add more pages to builtin wpmudev branding.
685 *
686 * @since 3.0
687 *
688 * @param array $plugin_pages Nextgen pages is not introduced in built in wpmudev branding.
689 *
690 * @return array
691 */
692 public function builtin_wpmudev_branding( $plugin_pages ) {
693 $plugin_pages['gallery_page_wp-smush-nextgen-bulk'] = array(
694 'wpmudev_whitelabel_sui_plugins_branding',
695 'wpmudev_whitelabel_sui_plugins_footer',
696 'wpmudev_whitelabel_sui_plugins_doc_links',
697 );
698
699 // There's a different page ID since NextGen 3.3.6.
700 $plugin_pages['nextgen-gallery_page_wp-smush-nextgen-bulk'] = array(
701 'wpmudev_whitelabel_sui_plugins_branding',
702 'wpmudev_whitelabel_sui_plugins_footer',
703 'wpmudev_whitelabel_sui_plugins_doc_links',
704 );
705
706 foreach ( $this->pages as $key => $value ) {
707 $plugin_pages[ "smush-pro_page_smush-{$key}" ] = array(
708 'wpmudev_whitelabel_sui_plugins_branding',
709 'wpmudev_whitelabel_sui_plugins_footer',
710 'wpmudev_whitelabel_sui_plugins_doc_links',
711 );
712 }
713
714 return $plugin_pages;
715 }
716
717 public function is_notice_dismissed( $notice ) {
718 $dismissed_notices = get_option( 'wp-smush-dismissed-notices', array() );
719
720 return ! empty( $dismissed_notices[ $notice ] );
721 }
722
723 public function show_parallel_unavailability_notice() {
724 $smush = WP_Smush::get_instance()->core()->mod->smush;
725 $curl_multi_exec_available = $smush->curl_multi_exec_available();
726 $is_current_user_not_admin = ! current_user_can( 'manage_options' );
727 $is_not_bulk_smush_page = false === strpos( get_current_screen()->id, 'page_smush-bulk' );
728 $notice_hidden = $this->is_notice_dismissed( 'curl-multi-unavailable' );
729
730 if (
731 $curl_multi_exec_available ||
732 $is_current_user_not_admin ||
733 $is_not_bulk_smush_page ||
734 $notice_hidden
735 ) {
736 return;
737 }
738
739 $notice_text = sprintf(
740 /* translators: %s: <strong>curl_multi_exec()</strong> */
741 esc_html__( 'Smush was unable to activate parallel processing on your site as your web hosting provider has disabled the %s function on your server. We highly recommend contacting your hosting provider to enable that function to optimize images on your site faster.', 'wp-smushit' ),
742 '<strong>curl_multi_exec()</strong>'
743 );
744
745 ?>
746 <div class="notice notice-warning is-dismissible smush-dismissible-notice"
747 id="smush-parallel-unavailability-notice"
748 data-key="curl-multi-unavailable">
749
750 <strong style="font-size: 15px;line-height: 30px;margin: 8px 0 0 2px;display: inline-block;">
751 <?php esc_html_e( 'Smush images faster with parallel image optimization', 'wp-smushit' ); ?>
752 </strong>
753 <br/>
754 <p style="margin-bottom: 13px;margin-top: 0;">
755 <?php echo wp_kses_post( $notice_text ); ?><br/>
756
757 <a style="margin-top: 5px;display: inline-block;" href="#" class="smush-dismiss-notice-button">
758 <?php esc_html_e( 'Dismiss', 'wp-smushit' ); ?>
759 </a>
760 </p>
761 </div>
762 <?php
763 }
764
765 public function show_background_unavailability_notice() {
766 $bg_optimization = WP_Smush::get_instance()->core()->mod->bg_optimization;
767 $background_supported = $bg_optimization->is_background_supported();
768 $background_disabled = ! $bg_optimization->is_background_enabled();
769 $is_current_user_not_admin = ! current_user_can( 'manage_options' );
770 $is_not_bulk_smush_page = false === strpos( get_current_screen()->id, 'page_smush-bulk' );
771 $notice_hidden = $this->is_notice_dismissed( 'background-smush-unavailable' );
772
773 if (
774 $background_supported ||
775 $background_disabled ||
776 $is_current_user_not_admin ||
777 $is_not_bulk_smush_page ||
778 $notice_hidden
779 ) {
780 return;
781 }
782
783 $notice_text = sprintf(
784 /* translators: 1: Current MYSQL version, 2: Required MYSQL version */
785 esc_html__( 'Smush was unable to activate background processing on your site as your web hosting provider is using an old version of MySQL on your server (version %1$s). We highly recommend contacting your hosting provider to upgrade MySQL to version %2$s or higher to optimize images in the background.', 'wp-smushit' ),
786 $bg_optimization->get_actual_mysql_version(),
787 $bg_optimization->get_required_mysql_version()
788 );
789 ?>
790 <div class="notice notice-warning is-dismissible smush-dismissible-notice"
791 id="smush-background-unavailability-notice"
792 data-key="background-smush-unavailable">
793
794 <strong style="font-size: 15px;line-height: 30px;margin: 8px 0 0 2px;display: inline-block;">
795 <?php esc_html_e( 'Smush images in the background', 'wp-smushit' ); ?>
796 </strong>
797 <br/>
798 <p style="margin-bottom: 13px;margin-top: 0;">
799 <?php echo wp_kses_post( $notice_text ); ?><br/>
800
801 <a style="margin-top: 5px;display: inline-block;" href="#" class="smush-dismiss-notice-button">
802 <?php esc_html_e( 'Dismiss', 'wp-smushit' ); ?>
803 </a>
804 </p>
805 </div>
806 <?php
807 }
808
809 public function maybe_show_local_webp_convert_original_images_notice() {
810 $redirected_from_next_gen = isset( $_GET['smush-action'] ) && 'start-bulk-next-gen-conversion' === $_GET['smush-action'];
811 $settings = Settings::get_instance();
812 $should_show_notice = $redirected_from_next_gen &&
813 current_user_can( 'manage_options' ) &&
814 $settings->has_next_gen_page() &&
815 ! $settings->is_optimize_original_images_active();
816 if ( ! $should_show_notice ) {
817 return;
818 }
819
820 $next_gen_format_ext = Next_Gen_Manager::get_instance()->get_active_format_key();
821 $error_message = sprintf(
822 /* translators: 1: Open a link, 2: Close the link */
823 esc_html__( 'If you wish to also convert your original uploaded images to .%1$s format, please enable the %2$sOptimize original images%3$s setting below.', 'wp-smushit' ),
824 esc_html( $next_gen_format_ext ),
825 '<a href="#original" class="smush-close-and-dismiss-notice">',
826 '</a>'
827 );
828 $error_message = '<p>' . $error_message . '</p>';
829 ?>
830 <div role="alert" id="wp-smush-local-webp-convert-original-notice" class="sui-notice wp-smush-dismissible-header-notice" data-message="<?php echo esc_attr( $error_message ); ?>" aria-live="assertive"></div>
831 <?php
832 }
833
834 public function get_plugin_discount() {
835 return self::$plugin_discount_percent . '%';
836 }
837
838 public function load_deactivation_survey_modal() {
839 $deactivation_survey_template_file = WP_SMUSH_DIR . 'app/modals/deactivation-survey.php';
840 if ( ! file_exists( $deactivation_survey_template_file ) ) {
841 return;
842 }
843
844 ob_start();
845 include $deactivation_survey_template_file;
846 // Everything escaped in all template files.
847 echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
848 }
849
850 /**
851 * Get the notice for reminding later.
852 */
853 public function maybe_show_review_prompts() {
854 $current_screen = get_current_screen();
855 $is_smush_page = strpos( $current_screen->id, 'page_smush' ) !== false || strpos( $current_screen->id, 'smush_page' ) !== false;
856 if ( ! $is_smush_page ) {
857 return false;
858 }
859
860 if ( ! $this->should_show_review_prompts() ) {
861 return;
862 }
863
864 ?>
865 <style>
866 #smush-review-prompts-notice{min-width:320px;padding:6px 20px 6px 12px;display:flex;gap:15px;align-items:center;}#smush-review-prompts-notice #smush-review-prompts-actions{margin-left:2px;margin-top:6px;display:flex;gap:10px;align-items:center;}#smush-review-prompts-notice h3{font-size:15px;margin:0 0 5px 0;}#smush-review-prompts-notice a{text-decoration:none;}#smush-review-prompts-notice a#smush-review-prompts-already-did{border:none;}#smush-review-prompts-notice p{letter-spacing:-0.25px;}#smush-review-prompts-notice .notice-dismiss{display: none;}@media screen and (min-width:1792px) {#smush-review-prompts-notice[data-notice-type="smushed_hundred_images"] .smush-review-prompts-notice-logo img{max-width:95px}}@media screen and (max-width: 600px) {#smush-review-prompts-notice{ display:block; }#smush-review-prompts-notice img{display:none;}#smush-review-prompts-notice .button{font-size:12px;min-height: 32px;padding: 0 10px;}}@media screen and (max-width:860px) { #smush-review-prompts-notice p br{ display:none; } }
867 </style>
868 <?php
869
870 $next_review_prompt = get_option( self::$review_prompts_option_key, array() );
871 if ( ! empty( $next_review_prompt['type'] ) ) {
872 return 'all_optimized' === $next_review_prompt['type'] ? $this->get_all_optimized_images_notice() : $this->get_remind_later_notice();
873 }
874
875 $global_stats = Global_Stats::get();
876
877 $optimized_count = $global_stats->get_total_optimizable_items_count() - $global_stats->get_remaining_count();
878 if ( $optimized_count >= self::$review_prompts_optimized_images_threshold ) {
879 return $this->get_optimized_images_notice( $optimized_count );
880 }
881
882 // Store the prompt state to continue showing the notice when new images are uploaded on small sites.
883 update_option(
884 self::$review_prompts_option_key,
885 array(
886 'time' => time() - 1,
887 'type' => 'all_optimized',
888 )
889 );
890
891 return $this->get_all_optimized_images_notice();
892 }
893
894 /**
895 * Check if the review prompts should be shown.
896 *
897 * @return bool
898 */
899 private function should_show_review_prompts() {
900 $membership = Membership::get_instance();
901 if ( $membership->is_pro() || $membership->is_api_hub_access_required() ) {
902 return false;
903 }
904
905 if ( $this->is_notice_dismissed( 'review-prompts' ) ) {
906 return false;
907 }
908 $global_stats = Global_Stats::get();
909
910 $image_count = $global_stats->get_image_attachment_count();
911 if ( $image_count < self::$review_prompts_min_images ) {
912 return false;
913 }
914
915 $percent_failed = $global_stats->get_optimization_failed_percent();
916 if ( $percent_failed >= self::$review_prompts_optimization_failed_percent_threshold ) {
917 return false;
918 }
919
920 $next_review_prompt = get_option( self::$review_prompts_option_key, array() );
921 $current_time = isset( $_GET['smush-current-time'] ) ? (int) $_GET['smush-current-time'] : time();
922 if ( ! empty( $next_review_prompt['time'] ) ) {
923 return $current_time >= (int) $next_review_prompt['time'];
924 }
925
926 $percent_optimized = $global_stats->get_percent_optimized();
927 $all_image_optimized = $percent_optimized >= 100;
928 if ( $all_image_optimized ) {
929 return true;
930 }
931
932 $optimized_count = $global_stats->get_total_optimizable_items_count() - $global_stats->get_remaining_count();
933
934 return $optimized_count >= self::$review_prompts_optimized_images_threshold;
935 }
936
937 /**
938 * Get the notice for optimized images.
939 *
940 * @param int $optimized_count Number of optimized images.
941 * @return void
942 */
943 private function get_optimized_images_notice( $optimized_count ) {
944 ?>
945 <div id="smush-review-prompts-notice" class="notice notice-info is-dismissible" data-notice-type="smushed_hundred_images">
946 <div class="smush-review-prompts-notice-logo">
947 <img
948 style="margin-top:-2px;margin-bottom:-3px"
949 src="<?php echo esc_url( WP_SMUSH_URL . 'app/assets/images/notices/review-prompts-icon.png' ); ?>"
950 srcset="<?php echo esc_url( WP_SMUSH_URL . 'app/assets/images/notices/review-prompts-icon@2x.png' ); ?> 2x"
951 alt="<?php esc_html_e( 'Smush review prompts icon', 'wp-smushit' ); ?>"
952 >
953 </div>
954 <div class="smush-review-prompts-notice-message">
955 <h3>
956 <?php
957 /* translators: %d: optimized images count */
958 printf( esc_html__( 'You’ve optimized %d images! 🎉', 'wp-smushit' ), (int) $optimized_count );
959 ?>
960 </h3>
961 <p><?php esc_html_e( 'Seeing faster speeds? We’d really appreciate a quick review. It keeps us growing and helps more WordPress users discover Smush.', 'wp-smushit' ); ?></p>
962 <div id="smush-review-prompts-actions">
963 <a target="_blank" href="https://wordpress.org/support/plugin/wp-smushit/reviews/?filter=5#new-post"
964 class="button button-small button-primary"><?php esc_html_e( 'Rate Smush', 'wp-smushit' ); ?></a>
965 <span id="smush-review-prompts-remind-later" class="button button-small" style="background-color: transparent;"><?php esc_html_e( 'Remind me later', 'wp-smushit' ); ?></span>
966 <span id="smush-review-prompts-already-did" class="button button-small" style="box-shadow:unset!important;background-color: transparent;" href="#"><?php esc_html_e( 'I already did', 'wp-smushit' ); ?></span>
967 </div>
968 </div>
969 </div>
970 <?php
971 }
972
973 /**
974 * Get the notice for all optimized images.
975 *
976 * @return void
977 */
978 private function get_all_optimized_images_notice() {
979 ?>
980 <div id="smush-review-prompts-notice"
981 class="notice notice-info is-dismissible"
982 style="padding-top:12px;padding-bottom:12px;"
983 data-notice-type="all_images_optimized">
984 <div class="smush-review-prompts-notice-logo">
985 <img
986 style="margin-top:-2px;margin-bottom:-3px"
987 src="<?php echo esc_url( WP_SMUSH_URL . 'app/assets/images/notices/review-prompts-icon.png' ); ?>"
988 srcset="<?php echo esc_url( WP_SMUSH_URL . 'app/assets/images/notices/review-prompts-icon@2x.png' ); ?> 2x"
989 alt="<?php esc_html_e( 'Smush review prompts icon', 'wp-smushit' ); ?>"
990 >
991 </div>
992 <div class="smush-review-prompts-notice-message">
993 <h3><?php esc_html_e( '100% of your images are now optimized! 🎉', 'wp-smushit' ); ?></h3>
994 <p>
995 <?php
996 printf(
997 /* translators: 1: <br>, 2: Open the link <a>, 3: Close the link </a> */
998 esc_html__( 'Your site’s faster and lighter than ever. Plus, Smush will keep every new image optimized, free for life. %1$sHappy with the results? Share the love with a 5-star review on %2$sWordPress.org%3$s.', 'wp-smushit' ),
999 '<br>',
1000 '<a href="https://wordpress.org/support/plugin/wp-smushit/reviews/?filter=5#new-post" target="_blank">',
1001 '</a>'
1002 );
1003 ?>
1004 </p>
1005 <div id="smush-review-prompts-actions">
1006 <a target="_blank" href="https://wordpress.org/support/plugin/wp-smushit/reviews/?filter=5#new-post"
1007 class="button button-small button-primary"><?php esc_html_e( 'Rate Smush', 'wp-smushit' ); ?></a>
1008 <span id="smush-review-prompts-remind-later" class="button button-small" style="background-color: transparent;"><?php esc_html_e( 'Remind me later', 'wp-smushit' ); ?></span>
1009 <span id="smush-review-prompts-already-did" class="button button-small" style="box-shadow:unset!important;background-color: transparent;"><?php esc_html_e( 'I already did', 'wp-smushit' ); ?></span>
1010 </div>
1011 </div>
1012 </div>
1013 <?php
1014 }
1015
1016 /**
1017 * Get the notice for reminding later.
1018 *
1019 * @return void
1020 */
1021 private function get_remind_later_notice() {
1022 ?>
1023 <div id="smush-review-prompts-notice"
1024 class="notice notice-info is-dismissible"
1025 style="padding-top:8px;padding-bottom:10px;"
1026 data-notice-type="seven_days">
1027 <div class="smush-review-prompts-notice-logo">
1028 <img
1029 style="margin-top:-2px;margin-bottom:-3px"
1030 src="<?php echo esc_url( WP_SMUSH_URL . 'app/assets/images/notices/review-prompts-icon.png' ); ?>"
1031 srcset="<?php echo esc_url( WP_SMUSH_URL . 'app/assets/images/notices/review-prompts-icon@2x.png' ); ?> 2x"
1032 alt="<?php esc_html_e( 'Smush review prompts icon', 'wp-smushit' ); ?>"
1033 >
1034 </div>
1035 <div class="smush-review-prompts-notice-message">
1036 <h3><?php esc_html_e( 'Thanks for choosing Smush! 💙', 'wp-smushit' ); ?></h3>
1037 <p><?php esc_html_e( 'If your site’s feeling faster, we’d be so grateful for a quick 5-star review. It really helps us out!', 'wp-smushit' ); ?></p>
1038 <div id="smush-review-prompts-actions">
1039 <a target="_blank" href="https://wordpress.org/support/plugin/wp-smushit/reviews/?filter=5#new-post"
1040 class="button button-small button-primary"><?php esc_html_e( 'Rate Smush', 'wp-smushit' ); ?></a>
1041 <span id="smush-review-prompts-remind-later" class="button button-small" style="background-color: transparent;"><?php esc_html_e( 'Remind me later', 'wp-smushit' ); ?></span>
1042 <span id="smush-review-prompts-already-did" class="button button-small" style="box-shadow:unset!important;background-color: transparent;"><?php esc_html_e( 'I already did', 'wp-smushit' ); ?></span>
1043 </div>
1044 </div>
1045 </div>
1046 <?php
1047 }
1048 }
1049