PluginProbe ʕ •ᴥ•ʔ
TinyPNG – JPEG, PNG & WebP image compression / 3.0.1
TinyPNG – JPEG, PNG & WebP image compression v3.0.1
3.7.0 3.6.14 trunk 1.0.0 1.1.0 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.4.0 1.5.0 1.6.0 1.7.0 1.7.1 1.7.2 2.0.0 2.0.1 2.0.2 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.0.0 3.0.1 3.1.0 3.2.0 3.2.1 3.3 3.4 3.4.1 3.4.2 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.5.2 3.6.0 3.6.1 3.6.10 3.6.11 3.6.12 3.6.13 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9
tiny-compress-images / src / class-tiny-settings.php
tiny-compress-images / src Last commit date
config 7 years ago css 7 years ago data 10 years ago images 9 years ago js 7 years ago vendor 7 years ago views 7 years ago class-tiny-bulk-optimization.php 7 years ago class-tiny-compress-client.php 7 years ago class-tiny-compress-fopen.php 7 years ago class-tiny-compress.php 7 years ago class-tiny-exception.php 7 years ago class-tiny-image-size.php 7 years ago class-tiny-image.php 7 years ago class-tiny-notices.php 7 years ago class-tiny-php.php 7 years ago class-tiny-plugin.php 7 years ago class-tiny-settings.php 7 years ago class-tiny-wp-base.php 7 years ago
class-tiny-settings.php
1017 lines
1 <?php
2 /*
3 * Tiny Compress Images - WordPress plugin.
4 * Copyright (C) 2015-2018 Tinify B.V.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc., 51
18 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20 class Tiny_Settings extends Tiny_WP_Base {
21 const DUMMY_SIZE = '_tiny_dummy';
22
23 private $sizes;
24 private $tinify_sizes;
25 private $compressor;
26 private $notices;
27
28 protected static $incompatible_plugins = array(
29 'CheetahO Image Optimizer' => 'cheetaho-image-optimizer/cheetaho.php',
30 'EWWW Image Optimizer' => 'ewww-image-optimizer/ewww-image-optimizer.php',
31 'Imagify' => 'imagify/imagify.php',
32 'Kraken Image Optimizer' => 'kraken-image-optimizer/kraken.php',
33 'ShortPixel Image Optimizer' => 'shortpixel-image-optimiser/wp-shortpixel.php',
34 'WP Smush' => 'wp-smushit/wp-smush.php',
35 'WP Smush Pro' => 'wp-smush-pro/wp-smush.php',
36 );
37
38 protected static $offload_s3_plugin = 'amazon-s3-and-cloudfront/wordpress-s3.php';
39
40 public function __construct() {
41 parent::__construct();
42 $this->notices = new Tiny_Notices();
43 add_action( 'admin_menu', array( $this, 'add_menu' ) );
44 }
45
46 private function init_compressor() {
47 $this->compressor = Tiny_Compress::create(
48 $this->get_api_key(),
49 $this->get_method( 'after_compress_callback' )
50 );
51 }
52
53 public function get_absolute_url() {
54 return get_admin_url( null, 'options-general.php?page=tinify' );
55 }
56
57 public function xmlrpc_init() {
58 try {
59 $this->init_compressor();
60 } catch ( Tiny_Exception $e ) {
61 }
62 }
63
64 public function add_menu() {
65 add_options_page(
66 __( 'Compress JPEG & PNG images', 'tiny-compress-images' ),
67 esc_html__( 'Compress JPEG & PNG images', 'tiny-compress-images' ),
68 'manage_options',
69 'tinify',
70 array( $this, 'add_options_to_page' )
71 );
72 }
73
74 public function admin_init() {
75 if ( current_user_can( 'manage_options' ) ) {
76 $this->render_notices();
77 }
78
79 try {
80 $this->init_compressor();
81 } catch ( Tiny_Exception $e ) {
82 $this->notices->show(
83 'compressor_exception',
84 esc_html( $e->getMessage(), 'tiny-compress-images' ),
85 'error', false
86 );
87 }
88
89 /* Create link to new settings page from media settings page. */
90 add_settings_section( 'section_end', '',
91 $this->get_method( 'render_settings_link' ),
92 'media'
93 );
94
95 $field = self::get_prefixed_name( 'api_key' );
96 register_setting( 'tinify', $field );
97
98 $field = self::get_prefixed_name( 'api_key_pending' );
99 register_setting( 'tinify', $field );
100
101 $field = self::get_prefixed_name( 'compression_timing' );
102 register_setting( 'tinify', $field );
103
104 $field = self::get_prefixed_name( 'sizes' );
105 register_setting( 'tinify', $field );
106
107 $field = self::get_prefixed_name( 'resize_original' );
108 register_setting( 'tinify', $field );
109
110 $field = self::get_prefixed_name( 'preserve_data' );
111 register_setting( 'tinify', $field );
112
113 add_action(
114 'wp_ajax_tiny_image_sizes_notice',
115 $this->get_method( 'image_sizes_notice' )
116 );
117
118 add_action(
119 'wp_ajax_tiny_account_status',
120 $this->get_method( 'account_status' )
121 );
122
123 add_action(
124 'wp_ajax_tiny_settings_create_api_key',
125 $this->get_method( 'create_api_key' )
126 );
127
128 add_action(
129 'wp_ajax_tiny_settings_update_api_key',
130 $this->get_method( 'update_api_key' )
131 );
132 }
133
134 public function add_options_to_page() {
135 include( dirname( __FILE__ ) . '/views/settings.php' );
136 }
137
138 public function image_sizes_notice() {
139 $this->render_image_sizes_notice(
140 $_GET['image_sizes_selected'],
141 isset( $_GET['resize_original'] ),
142 isset( $_GET['compress_wr2x'] )
143 );
144 exit();
145 }
146
147 public function account_status() {
148 $this->render_account_status();
149 exit();
150 }
151
152 public function get_compressor() {
153 return $this->compressor;
154 }
155
156 public function set_compressor( $compressor ) {
157 $this->compressor = $compressor;
158 }
159
160 public function get_status() {
161 return intval( get_option( self::get_prefixed_name( 'status' ) ) );
162 }
163
164 public function disabled_required_functions() {
165 $required_functions = array( 'curl_exec' );
166 $disabled_required_functions = array();
167 $disabled_functions = explode( ',', ini_get( 'disable_functions' ) );
168
169 foreach ( $required_functions as $required_function ) {
170 if ( in_array( $required_function, $disabled_functions ) ) {
171 array_push( $disabled_required_functions, $required_function );
172 }
173 }
174
175 return $disabled_required_functions;
176 }
177
178 protected function get_api_key() {
179 if ( defined( 'TINY_API_KEY' ) ) {
180 return TINY_API_KEY;
181 } else {
182 return get_option( self::get_prefixed_name( 'api_key' ) );
183 }
184 }
185
186 protected function get_api_key_pending() {
187 if ( defined( 'TINY_API_KEY' ) ) {
188 return false;
189 } else {
190 return get_option( self::get_prefixed_name( 'api_key_pending' ) );
191 }
192 }
193
194 protected function clear_api_key_pending() {
195 delete_option( self::get_prefixed_name( 'api_key_pending' ) );
196 }
197
198 protected static function get_intermediate_size( $size ) {
199 /* Inspired by
200 http://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes */
201 global $_wp_additional_image_sizes;
202
203 $width = get_option( $size . '_size_w' );
204 $height = get_option( $size . '_size_h' );
205
206 /* Note: dimensions might be 0 to indicate no limit. */
207 if ( $width || $height ) {
208 return array( $width, $height );
209 }
210
211 if ( isset( $_wp_additional_image_sizes[ $size ] ) ) {
212 $sizes = $_wp_additional_image_sizes[ $size ];
213 return array(
214 isset( $sizes['width'] ) ? $sizes['width'] : null,
215 isset( $sizes['height'] ) ? $sizes['height'] : null,
216 );
217 }
218 return array( null, null );
219 }
220
221 public function get_sizes() {
222 if ( is_array( $this->sizes ) ) {
223 return $this->sizes;
224 }
225
226 $setting = get_option( self::get_prefixed_name( 'sizes' ) );
227
228 $size = Tiny_Image::ORIGINAL;
229 $this->sizes = array(
230 $size => array(
231 'width' => null,
232 'height' => null,
233 'tinify' => ! is_array( $setting ) ||
234 ( isset( $setting[ $size ] ) && 'on' === $setting[ $size ] ),
235 ),
236 );
237
238 foreach ( get_intermediate_image_sizes() as $size ) {
239 if ( self::DUMMY_SIZE === $size ) {
240 continue;
241 }
242
243 list($width, $height) = self::get_intermediate_size( $size );
244 if ( $width || $height ) {
245 $this->sizes[ $size ] = array(
246 'width' => $width,
247 'height' => $height,
248 'tinify' => ! is_array( $setting ) ||
249 ( isset( $setting[ $size ] ) && 'on' === $setting[ $size ] ),
250 );
251 }
252 }
253
254 return $this->sizes;
255 }
256
257 public function get_active_tinify_sizes() {
258 if ( is_array( $this->tinify_sizes ) ) {
259 return $this->tinify_sizes;
260 }
261
262 $this->tinify_sizes = array();
263 foreach ( $this->get_sizes() as $size => $values ) {
264 if ( $values['tinify'] ) {
265 $this->tinify_sizes[] = $size;
266 }
267 }
268 return $this->tinify_sizes;
269 }
270
271 public function new_plugin_install() {
272 /* We merely have to check whether a newly added setting is already stored. */
273 $compression_timing = get_option( self::get_prefixed_name( 'compression_timing' ) );
274 return ! $compression_timing;
275 }
276
277 public function get_resize_enabled() {
278 /* This only applies if the original is being resized. */
279 $sizes = $this->get_sizes();
280 if ( ! $sizes[ Tiny_Image::ORIGINAL ]['tinify'] ) {
281 return false;
282 }
283
284 $setting = get_option( self::get_prefixed_name( 'resize_original' ) );
285 return isset( $setting['enabled'] ) && 'on' === $setting['enabled'];
286 }
287
288 public function get_compression_timing() {
289 $setting = get_option( self::get_prefixed_name( 'compression_timing' ) );
290 if ( isset( $setting ) && $setting ) {
291 return $setting;
292 } elseif ( $this->new_plugin_install() ) {
293 update_option( self::get_prefixed_name( 'compression_timing' ), 'background' );
294 return 'background';
295 } else {
296 update_option( self::get_prefixed_name( 'compression_timing' ), 'auto' );
297 return 'auto';
298 }
299 }
300
301 public function auto_compress_enabled() {
302 return $this->get_compression_timing() === 'auto' ||
303 $this->get_compression_timing() === 'background';
304 }
305
306 public function background_compress_enabled() {
307 return $this->get_compression_timing() === 'background';
308 }
309
310 public function has_offload_s3_installed() {
311 if (
312 ! function_exists( 'is_plugin_active' ) ||
313 ! is_plugin_active( self::$offload_s3_plugin )
314 ) {
315 return false;
316 }
317 $setting = get_option( 'tantan_wordpress_s3' );
318 if ( ! is_array( $setting ) ) {
319 return false;
320 }
321
322 return true;
323 }
324
325 public function old_offload_s3_version_installed() {
326 if (
327 function_exists( 'is_plugin_active' ) &&
328 is_plugin_active( self::$offload_s3_plugin ) &&
329 function_exists( 'get_plugin_data' )
330 ) {
331 $metadata = get_plugin_data( WP_PLUGIN_DIR . '/' . self::$offload_s3_plugin );
332 $offload_s3_version_parts = explode( '.', $metadata['Version'] );
333 $major_version = intval( $offload_s3_version_parts[0] );
334 $minor_version = intval( $offload_s3_version_parts[1] );
335 if ( 0 === $major_version && $minor_version < 7 ) {
336 return true;
337 }
338 }
339
340 return false;
341 }
342
343 public function remove_local_files_setting_enabled() {
344 /* Check if Offload S3 plugin is installed. */
345 if (
346 ! function_exists( 'is_plugin_active' ) ||
347 ! is_plugin_active( self::$offload_s3_plugin )
348 ) {
349 return false;
350 }
351 $setting = get_option( 'tantan_wordpress_s3' );
352 if ( ! is_array( $setting ) ) {
353 return false;
354 }
355 /* Check if Offload S3 is configured to remove local files. */
356 return ( $this->has_offload_s3_installed() &&
357 array_key_exists( 'remove-local-file', $setting ) &&
358 '1' === $setting['remove-local-file'] );
359 }
360
361 public function get_preserve_enabled( $name ) {
362 $setting = get_option( self::get_prefixed_name( 'preserve_data' ) );
363 return isset( $setting[ $name ] ) && 'on' === $setting[ $name ];
364 }
365
366 public function get_preserve_options( $size_name ) {
367 if ( ! Tiny_Image::is_original( $size_name ) ) {
368 return false;
369 }
370 $options = array();
371 $settings = get_option( self::get_prefixed_name( 'preserve_data' ) );
372 if ( $settings ) {
373 $keys = array_keys( $settings );
374 foreach ( $keys as &$key ) {
375 if ( 'on' === $settings[ $key ] ) {
376 array_push( $options, $key );
377 }
378 }
379 }
380 return $options;
381 }
382
383 public function get_resize_options( $size_name ) {
384 if ( ! Tiny_Image::is_original( $size_name ) ) {
385 return false;
386 }
387 if ( ! $this->get_resize_enabled() ) {
388 return false;
389 }
390 $setting = get_option( self::get_prefixed_name( 'resize_original' ) );
391 $width = intval( $setting['width'] );
392 $height = intval( $setting['height'] );
393 $method = $width > 0 && $height > 0 ? 'fit' : 'scale';
394 $options['method'] = $method;
395 if ( $width > 0 ) {
396 $options['width'] = $width;
397 }
398 if ( $height > 0 ) {
399 $options['height'] = $height;
400 }
401 return sizeof( $options ) >= 2 ? $options : false;
402 }
403
404 public function render_notices() {
405 $this->render_setup_incomplete_notice();
406 $this->render_outdated_platform_notice();
407 $this->render_incompatible_plugins_notice();
408 $this->render_offload_s3_notices();
409 }
410
411 public function render_setup_incomplete_notice() {
412 if ( ! $this->get_api_key() ) {
413 $notice_class = 'error';
414 $notice = esc_html__(
415 'Please register or provide an API key to start compressing images.',
416 'tiny-compress-images'
417 );
418 } elseif ( $this->get_api_key_pending() ) {
419 $notice_class = 'notice-warning';
420 $notice = esc_html__(
421 'Please activate your account to start compressing images.',
422 'tiny-compress-images'
423 );
424 }
425
426 if ( isset( $notice ) && $notice ) {
427 $link = sprintf(
428 '<a href="options-general.php?page=tinify">%s</a>', $notice
429 );
430 $this->notices->show( 'setting', $link, $notice_class, false );
431 }
432 }
433
434 public function render_outdated_platform_notice() {
435 if ( ! Tiny_PHP::client_supported() ) {
436 if ( ! Tiny_PHP::has_fully_supported_php() ) {
437 $details = 'PHP ' . PHP_VERSION;
438 if ( Tiny_PHP::curl_available() ) {
439 $curlinfo = curl_version();
440 $details .= ' ' . sprintf(
441 /* translators: %s: curl version */
442 esc_html__( 'with curl %s', 'tiny-compress-images' ), $curlinfo['version']
443 );
444 } else {
445 $details .= ' ' . esc_html__( 'without curl', 'tiny-compress-images' );
446 }
447 if ( Tiny_PHP::curl_exec_disabled() ) {
448 $details .= ' ' .
449 esc_html__( 'and curl_exec disabled', 'tiny-compress-images' );
450 }
451 $message = sprintf(
452 /* translators: %s: details of outdated platform */
453 esc_html__(
454 'You are using an outdated platform (%s).',
455 'tiny-compress-images'
456 ), $details
457 );
458 } elseif ( ! Tiny_PHP::curl_available() ) {
459 $message = esc_html__(
460 'We noticed that cURL is not available. For the best experience we recommend to make sure cURL is available.', // WPCS: Needed for proper translation.
461 'tiny-compress-images'
462 );
463 } elseif ( Tiny_PHP::curl_exec_disabled() ) {
464 $message = esc_html__(
465 'We noticed that curl_exec is disabled in your PHP configuration. Please update this setting for the best experience.', // WPCS: Needed for proper translation.
466 'tiny-compress-images'
467 );
468 }
469 $this->notices->show( 'deprecated', $message, 'notice-warning', false );
470 } // End if().
471 }
472
473 public function render_incompatible_plugins_notice() {
474 $incompatible_plugins = array_filter( self::$incompatible_plugins, 'is_plugin_active' );
475 if ( count( $incompatible_plugins ) > 0 ) {
476 $this->notices->show_incompatible_plugins( $incompatible_plugins );
477 }
478 }
479
480 public function render_settings_link() {
481 echo '<div class="tinify-settings"><h3>';
482 esc_html_e( 'Compress JPEG & PNG images', 'tiny-compress-images' );
483 echo '</h3>';
484 $url = admin_url( 'options-general.php?page=tinify' );
485 $link = "<a href='" . $url . "'>";
486 $link .= esc_html__( 'settings', 'tiny-compress-images' );
487 $link .= '</a>';
488 printf(
489 wp_kses(
490 /* translators: %s: link saying settings */
491 __( 'The %s have moved.', 'tiny-compress-images' ),
492 array(
493 'a' => array(
494 'href' => array(),
495 ),
496 )
497 ),
498 $link
499 );
500 echo '</div>';
501 }
502
503 public function render_offload_s3_notices() {
504 if ( $this->remove_local_files_setting_enabled() &&
505 'background' === $this->get_compression_timing() ) {
506 $message = esc_html__(
507 'Removing files from the server is incompatible with background compressions. Images will still be automatically compressed, but no longer in the background.', // WPCS: Needed for proper translation.
508 'tiny-compress-images'
509 );
510 $this->notices->show( 'offload-s3', $message, 'notice-error', false );
511 update_option( self::get_prefixed_name( 'compression_timing' ), 'auto' );
512 }
513
514 if ( $this->old_offload_s3_version_installed() &&
515 'background' === $this->get_compression_timing() ) {
516 $message = esc_html__(
517 'Background compressions are not compatible with the version of WP Offload S3 you have installed. Please update to version 0.7.2 at least.', // WPCS: Needed for proper translation.
518 'tiny-compress-images'
519 );
520 $this->notices->show( 'old-offload-s3-version', $message, 'notice-error', false );
521 update_option( self::get_prefixed_name( 'compression_timing' ), 'auto' );
522 }
523 }
524
525 public function render_compression_timing_settings() {
526 $heading = esc_html__(
527 'When should new images be compressed?',
528 'tiny-compress-images'
529 );
530 echo '<h4>' . $heading . '</h4>';
531 echo '<div class="optimization-options">';
532
533 $name = self::get_prefixed_name( 'compression_timing' );
534 $compression_timing = $this->get_compression_timing();
535
536 $id = self::get_prefixed_name( 'background_compress_enabled' );
537 $checked = ( 'background' === $compression_timing ? ' checked="checked"' : '' );
538
539 $label = esc_html__(
540 'Compress new images in the background (Recommended)',
541 'tiny-compress-images'
542 );
543 $description = esc_html__(
544 'This is the fastest method, but can cause issues with some image related plugins.',
545 'tiny-compress-images'
546 );
547
548 $this->render_compression_timing_radiobutton(
549 $name,
550 $label,
551 $description,
552 'background',
553 $checked,
554 $this->remove_local_files_setting_enabled() || $this->old_offload_s3_version_installed()
555 );
556
557 $id = self::get_prefixed_name( 'auto_compress_enabled' );
558 $checked = ( 'auto' === $compression_timing ? ' checked="checked"' : '' );
559
560 $label = esc_html__(
561 'Compress new images during upload',
562 'tiny-compress-images'
563 );
564 $description = esc_html__(
565 'Uploads will take longer, but provides higher compatibility with other plugins.',
566 'tiny-compress-images'
567 );
568
569 $this->render_compression_timing_radiobutton(
570 $name,
571 $label,
572 $description,
573 'auto',
574 $checked,
575 false
576 );
577
578 $id = self::get_prefixed_name( 'auto_compress_disabled' );
579 $checked = ( 'manual' === $compression_timing ? ' checked="checked"' : '' );
580
581 $label = esc_html__(
582 'Do not compress new images automatically',
583 'tiny-compress-images'
584 );
585 $description = esc_html__(
586 'Manually select the images you want to compress in the media library.',
587 'tiny-compress-images'
588 );
589
590 $this->render_compression_timing_radiobutton(
591 $name,
592 $label,
593 $description,
594 'manual',
595 $checked,
596 false
597 );
598
599 echo '</div>';
600 }
601
602 public function render_sizes() {
603 echo '<input type="hidden" name="' .
604 self::get_prefixed_name( 'sizes[' . self::DUMMY_SIZE . ']' ) . '" value="on"/>';
605
606 foreach ( $this->get_sizes() as $size => $option ) {
607 $this->render_size_checkbox( $size, $option );
608 }
609 if ( self::wr2x_active() ) {
610 $this->render_size_checkbox( 'wr2x', $this->get_wr2x_option() );
611 }
612 echo '<br>';
613 echo '<div id="tiny-image-sizes-notice">';
614
615 $this->render_image_sizes_notice(
616 count( self::get_active_tinify_sizes() ),
617 self::get_resize_enabled(),
618 self::compress_wr2x_images()
619 );
620
621 echo '</div>';
622 }
623
624 private function render_size_checkbox( $size, $option ) {
625 $id = self::get_prefixed_name( "sizes_$size" );
626 $name = self::get_prefixed_name( 'sizes[' . $size . ']' );
627 $checked = ( $option['tinify'] ? ' checked="checked"' : '' );
628 if ( Tiny_Image::is_original( $size ) ) {
629 $label = esc_html__( 'Original image', 'tiny-compress-images' ) . ' (' .
630 esc_html__(
631 'overwritten by compressed image',
632 'tiny-compress-images'
633 ) . ')';
634 } elseif ( Tiny_Image::is_retina( $size ) ) {
635 $label = esc_html__( 'WP Retina 2x sizes', 'tiny-compress-images' );
636 } else {
637 $width = $option['width'];
638 if ( ! $width ) {
639 $width = '?';
640 }
641
642 $height = $option['height'];
643 if ( ! $height ) {
644 $height = '?';
645 }
646
647 $label = esc_html( ucfirst( str_replace( '_', ' ', $size ) ) )
648 . ' - ' . $width . 'x' . $height;
649 }
650 echo '<p>';
651 echo '<input type="checkbox" id="' . $id . '" name="' . $name .
652 '" value="on" ' . $checked . '/>';
653 echo '<label for="' . $id . '">' . $label . '</label>';
654 echo '</p>';
655 }
656
657 public function render_image_sizes_notice(
658 $active_sizes_count, $resize_original_enabled, $compress_wr2x ) {
659 echo '<p>';
660 esc_html_e(
661 'Remember each selected size counts as a compression.',
662 'tiny-compress-images'
663 );
664 echo '</p>';
665 echo '<p>';
666 if ( $resize_original_enabled ) {
667 $active_sizes_count++;
668 }
669 if ( $compress_wr2x ) {
670 $active_sizes_count *= 2;
671 }
672
673 if ( $active_sizes_count < 1 ) {
674 esc_html_e(
675 'With these settings no images will be compressed.',
676 'tiny-compress-images'
677 );
678 } else {
679 $free_images_per_month = floor(
680 Tiny_Config::MONTHLY_FREE_COMPRESSIONS / $active_sizes_count
681 );
682
683 $strong = array(
684 'strong' => array(),
685 );
686
687 /* translators: %1$s: number of images */
688 printf( wp_kses( __(
689 'With these settings you can compress <strong>at least %1$s images</strong> for free each month.', // WPCS: Needed for proper translation.
690 'tiny-compress-images'
691 ), $strong ), $free_images_per_month );
692
693 if ( self::wr2x_active() ) {
694 echo '</p>';
695 echo '<p>';
696 esc_html_e(
697 'If selected, retina sizes will be compressed when generated by WP Retina 2x',
698 'tiny-compress-images'
699 );
700 echo '<br>';
701 esc_html_e(
702 'Each retina size will count as an additional compression.',
703 'tiny-compress-images'
704 );
705 }
706 } // End if().
707 echo '</p>';
708 }
709
710 public function render_resize() {
711 $strong = array(
712 'strong' => array(),
713 );
714
715 echo '<p class="tiny-resize-unavailable" style="display: none">';
716 esc_html_e(
717 'Enable compression of the original image size for more options.',
718 'tiny-compress-images'
719 );
720 echo '</p>';
721
722 $id = self::get_prefixed_name( 'resize_original_enabled' );
723 $name = self::get_prefixed_name( 'resize_original[enabled]' );
724 $checked = ( $this->get_resize_enabled() ? ' checked="checked"' : '' );
725
726 $label = esc_html__(
727 'Resize the original image',
728 'tiny-compress-images'
729 );
730
731 echo '<div class="tiny-resize-available">';
732 echo '<input type="checkbox" id="' . $id . '" name="' . $name .
733 '" value="on" ' . $checked . '/>';
734 echo '<label for="' . $id . '">' . $label . '</label><br>';
735
736 echo '<div class="tiny-resize-available tiny-resize-resolution">';
737 echo '<span>';
738 echo wp_kses( __( '<strong>Save space</strong> by setting a maximum width and height for all images uploaded.', 'tiny-compress-images' ), $strong ); // WPCS: Needed for proper translation.
739 echo '<br>';
740 echo wp_kses( __( 'Resizing takes <strong>1 additional compression</strong> for each image that is larger.', 'tiny-compress-images' ), $strong ); // WPCS: Needed for proper translation.
741 echo '</span>';
742 echo '<div class="tiny-resize-inputs">';
743 printf( '%s: ', esc_html__( 'Max Width' ) );
744 $this->render_resize_input( 'width' );
745 printf( '%s: ', esc_html__( 'Max Height' ) );
746 $this->render_resize_input( 'height' );
747 echo '</div></div></div>';
748
749 $this->render_preserve_input(
750 'creation',
751 esc_html__(
752 'Preserve creation date and time in the original image',
753 'tiny-compress-images'
754 )
755 );
756
757 $this->render_preserve_input(
758 'copyright',
759 esc_html__(
760 'Preserve copyright information in the original image',
761 'tiny-compress-images'
762 )
763 );
764
765 $this->render_preserve_input(
766 'location',
767 esc_html__(
768 'Preserve GPS location in the original image',
769 'tiny-compress-images'
770 ) . ' ' .
771 esc_html__( '(JPEG only)', 'tiny-compress-images' )
772 );
773 }
774
775 public function render_compression_timing_radiobutton(
776 $name,
777 $label,
778 $desc,
779 $value,
780 $checked,
781 $disabled
782 ) {
783 if ( $disabled ) {
784 echo '<div class="notice notice-warning inline"><p>';
785 echo '<strong>' . esc_html__( 'Warning', 'tiny-compress-images' ) . '</strong> — ';
786 if ( $this->old_offload_s3_version_installed() ) {
787 $message = esc_html_e(
788 'Background compressions are not compatible with the version of WP Offload S3 you have installed. Please update to version 0.7.2 at least.', // WPCS: Needed for proper translation.
789 'tiny-compress-images'
790 );
791 } elseif ( $this->remove_local_files_setting_enabled() ) {
792 $message = esc_html_e(
793 'For background compression to work you will need to configure WP Offload S3 to keep a copy of the images on the server.', // WPCS: Needed for proper translation.
794 'tiny-compress-images'
795 );
796 }
797 echo '</p></div>';
798 echo '<p class="tiny-radio disabled">';
799 } else {
800 echo '<p class="tiny-radio">';
801 }
802 $id = sprintf( self::get_prefixed_name( 'compression_timing_%s' ), $value );
803 $label = esc_html( $label, 'tiny-compress-images' );
804 $desc = esc_html( $desc, 'tiny-compress-images' );
805 $disabled = ( $disabled ? ' disabled="disabled"' : '' );
806 echo '<input type="radio" id="' . $id . '" name="' . $name .
807 '" value="' . $value . '" ' . $checked . ' ' . $disabled . '/>';
808 echo '<label for="' . $id . '">' . $label . '</label>';
809 echo '<br>';
810 echo '<span class="description">' . $desc . '</span>';
811 echo '<br>';
812 echo '</p>';
813 }
814
815 public function render_preserve_input( $name, $description ) {
816 echo '<p class="tiny-preserve">';
817 $id = sprintf( self::get_prefixed_name( 'preserve_data_%s' ), $name );
818 $field = sprintf( self::get_prefixed_name( 'preserve_data[%s]' ), $name );
819 $checked = ( $this->get_preserve_enabled( $name ) ? ' checked="checked"' : '' );
820 $label = esc_html( $description, 'tiny-compress-images' );
821 echo '<input type="checkbox" id="' . $id . '" name="' . $field .
822 '" value="on" ' . $checked . '/>';
823 echo '<label for="' . $id . '">' . $label . '</label>';
824 echo '<br>';
825 echo '</p>';
826 }
827
828 public function render_resize_input( $name ) {
829 $id = sprintf( self::get_prefixed_name( 'resize_original_%s' ), $name );
830 $field = sprintf( self::get_prefixed_name( 'resize_original[%s]' ), $name );
831 $settings = get_option( self::get_prefixed_name( 'resize_original' ) );
832 $value = isset( $settings[ $name ] ) ? $settings[ $name ] : '2048';
833 echo '<input type="number" id="' . $id . '" name="' . $field .
834 '" value="' . $value . '" size="5" />';
835 }
836
837 public function get_compression_count() {
838 $field = self::get_prefixed_name( 'status' );
839 return get_option( $field );
840 }
841
842 public function limit_reached() {
843 $this->compressor->get_compression_count();
844 return $this->compressor->limit_reached();
845 }
846
847 public function after_compress_callback( $compressor ) {
848 $count = $compressor->get_compression_count();
849 if ( ! is_null( $count ) ) {
850 $field = self::get_prefixed_name( 'status' );
851 update_option( $field, $count );
852 }
853 if ( $compressor->limit_reached() ) {
854 $link = '<a href="https://tinypng.com/dashboard/api" target="_blank">' .
855 esc_html__( 'TinyPNG API account', 'tiny-compress-images' ) . '</a>';
856
857 $this->notices->add('limit-reached',
858 esc_html__(
859 'You have reached your free limit this month.',
860 'tiny-compress-images'
861 ) . ' ' .
862 sprintf(
863 /* translators: %s: link saying TinyPNG API account */
864 esc_html__(
865 'Upgrade your %s if you like to compress more images.',
866 'tiny-compress-images'
867 ),
868 $link
869 )
870 );
871 } else {
872 $this->notices->remove( 'limit-reached' );
873 }
874 }
875
876 public function render_account_status() {
877 $key = $this->get_api_key();
878 if ( empty( $key ) ) {
879 $compressor = $this->get_compressor();
880 if ( $compressor->can_create_key() ) {
881 include( dirname( __FILE__ ) . '/views/account-status-create-advanced.php' );
882 } else {
883 include( dirname( __FILE__ ) . '/views/account-status-create-simple.php' );
884 }
885 } else {
886 $status = $this->compressor->get_status();
887 $status->pending = false;
888 if ( $status->ok ) {
889 if ( $this->get_api_key_pending() ) {
890 $this->clear_api_key_pending();
891 }
892 } else {
893 if ( $this->get_api_key_pending() ) {
894 $status->ok = true;
895 $status->pending = true;
896 $status->message = (
897 'An email has been sent with a link to activate your account'
898 );
899 }
900 }
901 include( dirname( __FILE__ ) . '/views/account-status-connected.php' );
902 }
903 }
904
905 public function render_pending_status() {
906 $key = $this->get_api_key();
907 if ( empty( $key ) ) {
908 $compressor = $this->get_compressor();
909 if ( $compressor->can_create_key() ) {
910 include( dirname( __FILE__ ) . '/views/account-status-create-advanced.php' );
911 } else {
912 include( dirname( __FILE__ ) . '/views/account-status-create-simple.php' );
913 }
914 } else {
915 include( dirname( __FILE__ ) . '/views/account-status-loading.php' );
916 }
917 }
918
919 public function create_api_key() {
920 $compressor = $this->get_compressor();
921 if ( $compressor->can_create_key() ) {
922 if ( ! isset( $_POST['name'] ) || ! $_POST['name'] ) {
923 $status = (object) array(
924 'ok' => false,
925 'message' => __(
926 'Please enter your name', 'tiny-compress-images'
927 ),
928 );
929 echo json_encode( $status );
930 exit();
931 }
932
933 if ( ! isset( $_POST['email'] ) || ! $_POST['email'] ) {
934 $status = (object) array(
935 'ok' => false,
936 'message' => __(
937 'Please enter your email address', 'tiny-compress-images'
938 ),
939 );
940 echo json_encode( $status );
941 exit();
942 }
943
944 try {
945 $site = str_replace( array( 'http://', 'https://' ), '', get_bloginfo( 'url' ) );
946 $identifier = 'WordPress plugin for ' . $site;
947 $link = $this->get_absolute_url();
948 $compressor->create_key( $_POST['email'], array(
949 'name' => $_POST['name'],
950 'identifier' => $identifier,
951 'link' => $link,
952 ) );
953
954 update_option( self::get_prefixed_name( 'api_key_pending' ), true );
955 update_option( self::get_prefixed_name( 'api_key' ), $compressor->get_key() );
956 update_option( self::get_prefixed_name( 'status' ), 0 );
957
958 $status = (object) array(
959 'ok' => true,
960 'message' => null,
961 );
962 } catch ( Tiny_Exception $err ) {
963 list( $message ) = explode( ' (HTTP', $err->getMessage(), 2 );
964 $status = (object) array(
965 'ok' => false,
966 'message' => $message,
967 );
968 }
969 } else {
970 $status = (object) array(
971 'ok' => false,
972 'message' => 'This feature is not available on your platform',
973 );
974 }// End if().
975
976 echo json_encode( $status );
977 exit();
978 }
979
980 public function update_api_key() {
981 $key = $_POST['key'];
982 if ( empty( $key ) ) {
983 /* Always save if key is blank, so the key can be deleted. */
984 $status = (object) array(
985 'ok' => true,
986 'message' => null,
987 );
988 } else {
989 $status = Tiny_Compress::create( $key )->get_status();
990 }
991 if ( $status->ok ) {
992 update_option( self::get_prefixed_name( 'api_key_pending' ), false );
993 update_option( self::get_prefixed_name( 'api_key' ), $key );
994 }
995 echo json_encode( $status );
996 exit();
997 }
998
999 public static function wr2x_active() {
1000 return is_plugin_active( 'wp-retina-2x/wp-retina-2x.php' );
1001 }
1002
1003 public function get_wr2x_option() {
1004 $setting = get_option( self::get_prefixed_name( 'sizes' ) );
1005 return array(
1006 'width' => null,
1007 'height' => null,
1008 'tinify' => ( isset( $setting['wr2x'] ) && 'on' === $setting['wr2x'] ),
1009 );
1010 }
1011
1012 public function compress_wr2x_images() {
1013 $option = $this->get_wr2x_option();
1014 return self::wr2x_active() && $option['tinify'];
1015 }
1016 }
1017