PluginProbe ʕ •ᴥ•ʔ
TinyPNG – JPEG, PNG & WebP image compression / 3.6.0
TinyPNG – JPEG, PNG & WebP image compression v3.6.0
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
compatibility 1 year ago config 4 years ago css 1 year ago data 4 years ago images 4 years ago js 1 year ago vendor 1 year ago views 1 year ago class-tiny-bulk-optimization.php 1 year ago class-tiny-compress-client.php 1 year ago class-tiny-compress-fopen.php 1 year ago class-tiny-compress.php 1 year ago class-tiny-exception.php 4 years ago class-tiny-helpers.php 1 year ago class-tiny-image-size.php 1 year ago class-tiny-image.php 1 year ago class-tiny-notices.php 1 year ago class-tiny-php.php 4 years ago class-tiny-picture.php 1 year ago class-tiny-plugin.php 1 year ago class-tiny-settings.php 1 year ago class-tiny-wp-base.php 1 year ago
class-tiny-settings.php
1060 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
22
23 const DUMMY_SIZE = '_tiny_dummy';
24
25 private $sizes;
26 private $tinify_sizes;
27 private $compressor;
28 private $notices;
29
30 public function __construct() {
31 parent::__construct();
32 $this->notices = new Tiny_Notices();
33 }
34
35 private function init_compressor() {
36 $this->compressor = Tiny_Compress::create(
37 $this->get_api_key(),
38 $this->get_method( 'after_compress_callback' )
39 );
40 }
41
42 public function get_absolute_url() {
43 return get_admin_url( null, 'options-general.php?page=tinify' );
44 }
45
46 public function xmlrpc_init() {
47 try {
48 $this->init_compressor();
49 } catch ( Tiny_Exception $e ) {
50 }
51 }
52
53 public function ajax_init() {
54 try {
55 $this->init_compressor();
56 } catch ( Tiny_Exception $e ) {
57 }
58
59 add_action(
60 'wp_ajax_tiny_image_sizes_notice',
61 $this->get_method( 'image_sizes_notice' )
62 );
63
64 add_action(
65 'wp_ajax_tiny_account_status',
66 $this->get_method( 'account_status' )
67 );
68
69 add_action(
70 'wp_ajax_tiny_settings_create_api_key',
71 $this->get_method( 'create_api_key' )
72 );
73
74 add_action(
75 'wp_ajax_tiny_settings_update_api_key',
76 $this->get_method( 'update_api_key' )
77 );
78 }
79
80 public function rest_init() {
81 try {
82 $this->init_compressor();
83 } catch ( Tiny_Exception $e ) {
84 }
85 }
86
87 public function admin_init() {
88 try {
89 $this->init_compressor();
90 } catch ( Tiny_Exception $e ) {
91 $this->notices->show(
92 'compressor_exception',
93 esc_html( $e->getMessage(), 'tiny-compress-images' ),
94 'error',
95 false
96 );
97 }
98
99 if ( current_user_can( 'manage_options' ) ) {
100 $this->setup_incomplete_checks();
101 }
102
103 $field = self::get_prefixed_name( 'api_key' );
104 register_setting( 'tinify', $field );
105
106 $field = self::get_prefixed_name( 'api_key_pending' );
107 register_setting( 'tinify', $field );
108
109 $field = self::get_prefixed_name( 'compression_timing' );
110 register_setting( 'tinify', $field );
111
112 $field = self::get_prefixed_name( 'sizes' );
113 register_setting( 'tinify', $field );
114
115 $field = self::get_prefixed_name( 'resize_original' );
116 register_setting( 'tinify', $field );
117
118 $field = self::get_prefixed_name( 'preserve_data' );
119 register_setting( 'tinify', $field );
120
121 $field = self::get_prefixed_name( 'convert_format' );
122 register_setting( 'tinify', $field );
123 }
124
125 public function admin_menu() {
126 /* Create link to new settings page from media settings page. */
127 add_settings_section(
128 'section_end',
129 '',
130 $this->get_method( 'render_settings_moved' ),
131 'media'
132 );
133
134 add_options_page(
135 __( 'TinyPNG - JPEG, PNG & WebP image compression', 'tiny-compress-images' ),
136 esc_html__( 'TinyPNG', 'tiny-compress-images' ),
137 'manage_options',
138 'tinify',
139 array( $this, 'add_options_to_page' )
140 );
141 }
142
143 public function add_options_to_page() {
144 include( dirname( __FILE__ ) . '/views/settings.php' );
145 }
146
147 public function image_sizes_notice() {
148 if ( current_user_can( 'manage_options' ) ) {
149 $this->render_size_checkboxes_description(
150 $_GET['image_sizes_selected'],
151 isset( $_GET['resize_original'] ),
152 isset( $_GET['compress_wr2x'] )
153 );
154 }
155 exit();
156 }
157
158 public function account_status() {
159 if ( current_user_can( 'manage_options' ) ) {
160 $this->render_account_status();
161 }
162 exit();
163 }
164
165 public function get_compressor() {
166 return $this->compressor;
167 }
168
169 public function set_compressor( $compressor ) {
170 $this->compressor = $compressor;
171 }
172
173 public function get_status() {
174 return intval( get_option( self::get_prefixed_name( 'status' ) ) );
175 }
176
177 public function disabled_required_functions() {
178 $required_functions = array( 'curl_exec' );
179 $disabled_required_functions = array();
180 $disabled_functions = explode( ',', ini_get( 'disable_functions' ) );
181
182 foreach ( $required_functions as $required_function ) {
183 if ( in_array( $required_function, $disabled_functions ) ) {
184 array_push( $disabled_required_functions, $required_function );
185 }
186 }
187
188 return $disabled_required_functions;
189 }
190
191 protected function get_api_key() {
192 if ( defined( 'TINY_API_KEY' ) ) {
193 return TINY_API_KEY;
194 } else {
195 return get_option( self::get_prefixed_name( 'api_key' ) );
196 }
197 }
198
199 protected function get_api_key_pending() {
200 if ( defined( 'TINY_API_KEY' ) ) {
201 return false;
202 } else {
203 return get_option( self::get_prefixed_name( 'api_key_pending' ) );
204 }
205 }
206
207 protected function clear_api_key_pending() {
208 delete_option( self::get_prefixed_name( 'api_key_pending' ) );
209 }
210
211 protected static function get_intermediate_size( $size ) {
212 /* Inspired by
213 http://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes */
214 global $_wp_additional_image_sizes;
215
216 $width = get_option( $size . '_size_w' );
217 $height = get_option( $size . '_size_h' );
218
219 /* Note: dimensions might be 0 to indicate no limit. */
220 if ( $width || $height ) {
221 return array( $width, $height );
222 }
223
224 if ( isset( $_wp_additional_image_sizes[ $size ] ) ) {
225 $sizes = $_wp_additional_image_sizes[ $size ];
226 return array(
227 isset( $sizes['width'] ) ? $sizes['width'] : null,
228 isset( $sizes['height'] ) ? $sizes['height'] : null,
229 );
230 }
231 return array( null, null );
232 }
233
234 public function get_sizes() {
235 if ( is_array( $this->sizes ) ) {
236 return $this->sizes;
237 }
238
239 $setting = get_option( self::get_prefixed_name( 'sizes' ) );
240
241 $size = Tiny_Image::ORIGINAL;
242 $this->sizes = array(
243 $size => array(
244 'width' => null,
245 'height' => null,
246 'tinify' => ! is_array( $setting ) ||
247 (isset( $setting[ $size ] ) && 'on' === $setting[ $size ]),
248 ),
249 );
250
251 foreach ( get_intermediate_image_sizes() as $size ) {
252 if ( self::DUMMY_SIZE === $size ) {
253 continue;
254 }
255
256 list($width, $height) = self::get_intermediate_size( $size );
257 if ( $width || $height ) {
258 $this->sizes[ $size ] = array(
259 'width' => $width,
260 'height' => $height,
261 'tinify' => ! is_array( $setting ) ||
262 (isset( $setting[ $size ] ) && 'on' === $setting[ $size ]),
263 );
264 }
265 }
266
267 return $this->sizes;
268 }
269
270 public function get_active_tinify_sizes() {
271 if ( is_array( $this->tinify_sizes ) ) {
272 return $this->tinify_sizes;
273 }
274
275 $this->tinify_sizes = array();
276 foreach ( $this->get_sizes() as $size => $values ) {
277 if ( $values['tinify'] ) {
278 $this->tinify_sizes[] = $size;
279 }
280 }
281 return $this->tinify_sizes;
282 }
283
284 public function new_plugin_install() {
285 /* We merely have to check whether a newly added setting is already stored. */
286 $compression_timing = get_option( self::get_prefixed_name( 'compression_timing' ) );
287 return ! $compression_timing;
288 }
289
290 public function get_resize_enabled() {
291 /* This only applies if the original is being resized. */
292 $sizes = $this->get_sizes();
293 if ( ! $sizes[ Tiny_Image::ORIGINAL ]['tinify'] ) {
294 return false;
295 }
296
297 $setting = get_option( self::get_prefixed_name( 'resize_original' ) );
298 return isset( $setting['enabled'] ) && 'on' === $setting['enabled'];
299 }
300
301 public function get_compression_timing() {
302 $setting = get_option( self::get_prefixed_name( 'compression_timing' ) );
303 if ( isset( $setting ) && $setting ) {
304 return $setting;
305 } elseif ( $this->new_plugin_install() ) {
306 update_option( self::get_prefixed_name( 'compression_timing' ), 'background' );
307 return 'background';
308 } else {
309 update_option( self::get_prefixed_name( 'compression_timing' ), 'auto' );
310 return 'auto';
311 }
312 }
313
314 public function auto_compress_enabled() {
315 return $this->get_compression_timing() === 'auto' ||
316 $this->get_compression_timing() === 'background';
317 }
318
319 public function background_compress_enabled() {
320 return $this->get_compression_timing() === 'background';
321 }
322
323 public function get_preserve_enabled( $name ) {
324 $setting = get_option( self::get_prefixed_name( 'preserve_data' ) );
325 return isset( $setting[ $name ] ) && 'on' === $setting[ $name ];
326 }
327
328 public function get_preserve_options( $size_name ) {
329 if ( ! Tiny_Image::is_original( $size_name ) ) {
330 return false;
331 }
332 $options = array();
333 $settings = get_option( self::get_prefixed_name( 'preserve_data' ) );
334 if ( $settings ) {
335 $keys = array_keys( $settings );
336 foreach ( $keys as &$key ) {
337 if ( 'on' === $settings[ $key ] ) {
338 array_push( $options, $key );
339 }
340 }
341 }
342 return $options;
343 }
344
345 public function get_resize_options( $size_name ) {
346 if ( ! Tiny_Image::is_original( $size_name ) ) {
347 return false;
348 }
349 if ( ! $this->get_resize_enabled() ) {
350 return false;
351 }
352 $setting = get_option( self::get_prefixed_name( 'resize_original' ) );
353 $width = intval( $setting['width'] );
354 $height = intval( $setting['height'] );
355 $method = $width > 0 && $height > 0 ? 'fit' : 'scale';
356 $options['method'] = $method;
357 if ( $width > 0 ) {
358 $options['width'] = $width;
359 }
360 if ( $height > 0 ) {
361 $options['height'] = $height;
362 }
363 return sizeof( $options ) >= 2 ? $options : false;
364 }
365
366 /**
367 * Retrieves the configured settings for conversion.
368 *
369 * @return array{ convert: bool, convert_to: string } The conversion options.
370 */
371 public function get_conversion_options() {
372 return array(
373 'convert' => $this->get_conversion_enabled(),
374 'convert_to' => $this->get_convertto_mimetype(),
375 );
376 }
377
378 /**
379 * Checks wether converting to optimized file format is enabled
380 *
381 * @return bool true if conversion is enabled, false otherwise
382 */
383 public function get_conversion_enabled() {
384 $conversion_enabled = self::get_convert_format_option( 'convert', 'off' );
385
386 return 'on' === $conversion_enabled;
387 }
388
389 /**
390 * Retrieve the mimetypes to convert to
391 *
392 * @return array{string} mimetypes to convert to
393 */
394 private function get_convertto_mimetype() {
395 $convert_to = self::get_convert_format_option( 'convert_to', 'smallest' );
396 if ( 'webp' == $convert_to ) {
397 return array( 'image/webp' );
398 }
399 if ( 'avif' == $convert_to ) {
400 return array( 'image/avif' );
401 }
402 return array( 'image/avif', 'image/webp' );
403 }
404
405 private function setup_incomplete_checks() {
406 if ( ! $this->get_api_key() ) {
407 $this->notices->api_key_missing_notice();
408 } elseif ( $this->get_api_key_pending() ) {
409 $this->notices->get_api_key_pending_notice();
410 }
411 }
412
413 public function render_settings_moved() {
414 echo '<div class="tinify-settings"><h3>';
415 esc_html_e( 'TinyPNG - JPEG, PNG & WebP image compression', 'tiny-compress-images' );
416 echo '</h3>';
417 $url = admin_url( 'options-general.php?page=tinify' );
418 $link = "<a href='" . $url . "'>";
419 $link .= esc_html__( 'settings', 'tiny-compress-images' );
420 $link .= '</a>';
421 printf(
422 wp_kses(
423 /* translators: %s: link saying settings */
424 __( 'The %s have moved.', 'tiny-compress-images' ),
425 array(
426 'a' => array(
427 'href' => array(),
428 ),
429 )
430 ),
431 $link
432 );
433 echo '</div>';
434 }
435
436 public function render_compression_timing_settings() {
437 $heading = esc_html__(
438 'When should new images be compressed?',
439 'tiny-compress-images'
440 );
441 echo '<h4>' . $heading . '</h4>';
442 echo '<div class="optimization-options">';
443
444 $name = self::get_prefixed_name( 'compression_timing' );
445 $compression_timing = $this->get_compression_timing();
446
447 $id = self::get_prefixed_name( 'background_compress_enabled' );
448 $checked = ('background' === $compression_timing ? ' checked="checked"' : '');
449
450 $label = esc_html__(
451 'Compress new images in the background (Recommended)',
452 'tiny-compress-images'
453 );
454 $description = esc_html__(
455 'This is the fastest method, but can cause issues with some image related plugins.',
456 'tiny-compress-images'
457 );
458
459 $this->render_compression_timing_radiobutton(
460 $name,
461 $label,
462 $description,
463 'background',
464 $checked,
465 false
466 );
467
468 $id = self::get_prefixed_name( 'auto_compress_enabled' );
469 $checked = ('auto' === $compression_timing ? ' checked="checked"' : '');
470
471 $label = esc_html__(
472 'Compress new images during upload',
473 'tiny-compress-images'
474 );
475 $description = esc_html__(
476 'Uploads will take longer, but provides higher compatibility with other plugins.',
477 'tiny-compress-images'
478 );
479
480 $this->render_compression_timing_radiobutton(
481 $name,
482 $label,
483 $description,
484 'auto',
485 $checked,
486 false
487 );
488
489 $id = self::get_prefixed_name( 'auto_compress_disabled' );
490 $checked = ('manual' === $compression_timing ? ' checked="checked"' : '');
491
492 $label = esc_html__(
493 'Do not compress new images automatically',
494 'tiny-compress-images'
495 );
496 $description = esc_html__(
497 'Manually select the images you want to compress in the media library.',
498 'tiny-compress-images'
499 );
500
501 $this->render_compression_timing_radiobutton(
502 $name,
503 $label,
504 $description,
505 'manual',
506 $checked,
507 false
508 );
509
510 echo '</div>';
511 }
512
513 public function render_sizes() {
514 echo '<input type="hidden" name="' .
515 self::get_prefixed_name( 'sizes[' . self::DUMMY_SIZE . ']' ) . '" value="on"/>';
516
517 foreach ( $this->get_sizes() as $size => $option ) {
518 $this->render_size_checkboxes( $size, $option );
519 }
520 if ( self::wr2x_active() ) {
521 $this->render_size_checkboxes( 'wr2x', $this->get_wr2x_option() );
522 }
523 echo '<br>';
524 echo '<div id="tiny-image-sizes-notice">';
525
526 $this->render_size_checkboxes_description(
527 count( self::get_active_tinify_sizes() ),
528 self::get_resize_enabled(),
529 self::compress_wr2x_images(),
530 self::get_conversion_enabled()
531 );
532
533 echo '</div>';
534 }
535
536 private function render_size_checkboxes( $size, $option ) {
537 $id = self::get_prefixed_name( "sizes_$size" );
538 $name = self::get_prefixed_name( 'sizes[' . $size . ']' );
539 $checked = ($option['tinify'] ? ' checked="checked"' : '');
540 if ( Tiny_Image::is_original( $size ) ) {
541 $label = esc_html__( 'Original image', 'tiny-compress-images' ) . ' (' .
542 esc_html__(
543 'overwritten by compressed image',
544 'tiny-compress-images'
545 ) . ')';
546 } elseif ( Tiny_Image::is_retina( $size ) ) {
547 $label = esc_html__( 'WP Retina 2x sizes', 'tiny-compress-images' );
548 } else {
549 $width = $option['width'];
550 if ( ! $width ) {
551 $width = '?';
552 }
553
554 $height = $option['height'];
555 if ( ! $height ) {
556 $height = '?';
557 }
558
559 $label = esc_html( ucfirst( str_replace( '_', ' ', $size ) ) )
560 . ' - ' . $width . 'x' . $height;
561 }
562 echo '<p>';
563 echo '<input type="checkbox" id="' . $id . '" name="' . $name .
564 '" value="on" ' . $checked . '/>';
565 echo '<label for="' . $id . '">' . $label . '</label>';
566 echo '</p>';
567 }
568
569 public function render_size_checkboxes_description(
570 $active_sizes_count,
571 $resize_original_enabled,
572 $compress_wr2x,
573 $conversion_enabled
574 ) {
575 echo '<p>';
576 esc_html_e(
577 'Remember each selected size counts as a compression.',
578 'tiny-compress-images'
579 );
580 echo '</p>';
581 echo '<p>';
582 if ( $resize_original_enabled ) {
583 $active_sizes_count++;
584 }
585 if ( $compress_wr2x ) {
586 $active_sizes_count *= 2;
587 }
588
589 if ( $conversion_enabled ) {
590 $active_sizes_count *= 2;
591 }
592
593 if ( $active_sizes_count < 1 ) {
594 esc_html_e(
595 'With these settings no images will be compressed.',
596 'tiny-compress-images'
597 );
598 } else {
599 $free_images_per_month = floor(
600 Tiny_Config::MONTHLY_FREE_COMPRESSIONS / $active_sizes_count
601 );
602
603 $strong = array(
604 'strong' => array(),
605 );
606
607 /* translators: %1$s: number of images */
608 printf(wp_kses(__(
609 'With these settings you can compress <strong>at least %1$s images</strong> for free each month.', // WPCS: Needed for proper translation.
610 'tiny-compress-images'
611 ), $strong), $free_images_per_month);
612
613 if ( self::wr2x_active() ) {
614 echo '</p>';
615 echo '<p>';
616 esc_html_e(
617 'If selected, retina sizes will be compressed when generated by WP Retina 2x',
618 'tiny-compress-images'
619 );
620 echo '<br>';
621 esc_html_e(
622 'Each retina size will count as an additional compression.',
623 'tiny-compress-images'
624 );
625 }
626 } // End if().
627 echo '</p>';
628 }
629
630 public function render_resize() {
631 $strong = array(
632 'strong' => array(),
633 );
634
635 echo '<div class="tiny-resize-unavailable" style="display: none">';
636 esc_html_e(
637 'Enable compression of the original image size for more options.',
638 'tiny-compress-images'
639 );
640 echo '</div>';
641
642 $id = self::get_prefixed_name( 'resize_original_enabled' );
643 $name = self::get_prefixed_name( 'resize_original[enabled]' );
644 $checked = ($this->get_resize_enabled() ? ' checked="checked"' : '');
645
646 $label = esc_html__(
647 'Resize the original image',
648 'tiny-compress-images'
649 );
650
651 echo '<div class="tiny-resize-available">';
652 echo '<input type="checkbox" id="' . $id . '" name="' . $name .
653 '" value="on" ' . $checked . '/>';
654 echo '<label for="' . $id . '">' . $label . '</label><br>';
655
656 echo '<div class="tiny-resize-available tiny-resize-resolution">';
657 echo '<span>';
658 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.
659 echo '<br>';
660 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.
661 echo '</span>';
662 echo '<div class="tiny-resize-inputs">';
663 printf( '%s: ', esc_html__( 'Max Width' ) );
664 $this->render_resize_input( 'width' );
665 printf( '%s: ', esc_html__( 'Max Height' ) );
666 $this->render_resize_input( 'height' );
667 echo '</div></div></div>';
668
669 $this->render_preserve_input(
670 'creation',
671 esc_html__(
672 'Preserve creation date and time in the original image',
673 'tiny-compress-images'
674 )
675 );
676
677 $this->render_preserve_input(
678 'copyright',
679 esc_html__(
680 'Preserve copyright information in the original image',
681 'tiny-compress-images'
682 )
683 );
684
685 $this->render_preserve_input(
686 'location',
687 esc_html__(
688 'Preserve GPS location in the original image',
689 'tiny-compress-images'
690 ) . ' ' .
691 esc_html__( '(JPEG only)', 'tiny-compress-images' )
692 );
693 }
694
695 public function render_compression_timing_radiobutton(
696 $name,
697 $label,
698 $desc,
699 $value,
700 $checked
701 ) {
702 $as3cf_local_files_present = Tiny_AS3CF::is_active()
703 && Tiny_AS3CF::remove_local_files_setting_enabled();
704 if ( 'background' == $value && $as3cf_local_files_present && $checked ) {
705 echo '<div class="notice notice-warning inline"><p>';
706 echo '<strong>' . esc_html__( 'Warning', 'tiny-compress-images' ) . '</strong> — ';
707 $message = esc_html_e(
708 'For 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.
709 'tiny-compress-images'
710 );
711 echo $message;
712 echo '</p></div>';
713 echo '<p class="tiny-radio disabled">';
714 } else {
715 echo '<p class="tiny-radio">';
716 }
717
718 $id = sprintf( self::get_prefixed_name( 'compression_timing_%s' ), $value );
719 $label = esc_html( $label, 'tiny-compress-images' );
720 $desc = esc_html( $desc, 'tiny-compress-images' );
721 echo '<input type="radio" id="' . $id . '" name="' . $name .
722 '" value="' . $value . '" ' . $checked . '/>';
723 echo '<label for="' . $id . '">' . $label . '</label>';
724 echo '<br>';
725 echo '<span>' . $desc . '</span>';
726 echo '</p>';
727 }
728
729 public function render_preserve_input( $name, $description ) {
730 echo '<p class="tiny-preserve">';
731 $id = sprintf( self::get_prefixed_name( 'preserve_data_%s' ), $name );
732 $field = sprintf( self::get_prefixed_name( 'preserve_data[%s]' ), $name );
733 $checked = ($this->get_preserve_enabled( $name ) ? ' checked="checked"' : '');
734 $label = esc_html( $description, 'tiny-compress-images' );
735 echo '<input type="checkbox" id="' . $id . '" name="' . $field .
736 '" value="on" ' . $checked . '/>';
737 echo '<label for="' . $id . '">' . $label . '</label>';
738 echo '<br>';
739 echo '</p>';
740 }
741
742 public function render_resize_input( $name ) {
743 $id = sprintf( self::get_prefixed_name( 'resize_original_%s' ), $name );
744 $field = sprintf( self::get_prefixed_name( 'resize_original[%s]' ), $name );
745 $settings = get_option( self::get_prefixed_name( 'resize_original' ) );
746 $value = isset( $settings[ $name ] ) ? $settings[ $name ] : '2048';
747 echo '<input type="number" id="' . $id . '" name="' . $field .
748 '" value="' . $value . '" size="5" />';
749 }
750
751 public function get_compression_count() {
752 $field = self::get_prefixed_name( 'status' );
753 return get_option( $field );
754 }
755
756 public function limit_reached() {
757 $this->compressor->get_compression_count();
758 return $this->compressor->limit_reached();
759 }
760
761 public function get_remaining_credits() {
762 $field = self::get_prefixed_name( 'remaining_credits' );
763 return get_option( $field );
764 }
765
766 public function get_paying_state() {
767 $field = self::get_prefixed_name( 'paying_state' );
768 return get_option( $field );
769 }
770
771 public function is_on_free_plan() {
772 return self::get_paying_state() === 'free';
773 }
774
775 public function get_email_address() {
776 $field = self::get_prefixed_name( 'email_address' );
777 return get_option( $field );
778 }
779
780 public function after_compress_callback( $compressor ) {
781 $count = $compressor->get_compression_count();
782 if ( ! is_null( $count ) ) {
783 $field = self::get_prefixed_name( 'status' );
784 update_option( $field, $count );
785 }
786 $remaining_credits = $compressor->get_remaining_credits();
787 if ( ! is_null( $remaining_credits ) ) {
788 $field = self::get_prefixed_name( 'remaining_credits' );
789 update_option( $field, $remaining_credits );
790 }
791 $paying_state = $compressor->get_paying_state();
792 if ( ! is_null( $paying_state ) ) {
793 $field = self::get_prefixed_name( 'paying_state' );
794 update_option( $field, $paying_state );
795 }
796 $email_address = $compressor->get_email_address();
797 if ( ! is_null( $email_address ) ) {
798 $field = self::get_prefixed_name( 'email_address' );
799 update_option( $field, $email_address );
800 }
801 if ( $compressor->limit_reached() ) {
802 $this->notices->add_limit_reached_notice( $email_address );
803 } else {
804 $this->notices->remove( 'limit-reached' );
805 }
806 }
807
808 public function render_account_status() {
809 $key = $this->get_api_key();
810 if ( empty( $key ) ) {
811 $compressor = $this->get_compressor();
812 if ( $compressor->can_create_key() ) {
813 include( dirname( __FILE__ ) . '/views/account-status-create-advanced.php' );
814 } else {
815 include( dirname( __FILE__ ) . '/views/account-status-create-simple.php' );
816 }
817 } else {
818 $status = $this->compressor->get_status();
819 $status->pending = false;
820 if ( $status->ok ) {
821 if ( $this->get_api_key_pending() ) {
822 $this->clear_api_key_pending();
823 }
824 } else {
825 if ( $this->get_api_key_pending() ) {
826 $status->ok = true;
827 $status->pending = true;
828 $status->message = (
829 'An email has been sent to activate your account'
830 );
831 }
832 }
833 include( dirname( __FILE__ ) . '/views/account-status-connected.php' );
834 }
835 }
836
837 public function render_pending_status() {
838 $key = $this->get_api_key();
839 if ( empty( $key ) ) {
840 $compressor = $this->get_compressor();
841 if ( $compressor->can_create_key() ) {
842 include( dirname( __FILE__ ) . '/views/account-status-create-advanced.php' );
843 } else {
844 include( dirname( __FILE__ ) . '/views/account-status-create-simple.php' );
845 }
846 } else {
847 include( dirname( __FILE__ ) . '/views/account-status-loading.php' );
848 }
849 }
850
851 public function create_api_key() {
852 if ( ! $this->check_ajax_referer() ) {
853 exit;
854 }
855 $compressor = $this->get_compressor();
856 if ( ! current_user_can( 'manage_options' ) ) {
857 $status = (object) array(
858 'ok' => false,
859 'message' => 'This feature requires certain user capabilities',
860 );
861 } elseif ( $compressor->can_create_key() ) {
862 if ( ! isset( $_POST['name'] ) || ! $_POST['name'] ) {
863 $status = (object) array(
864 'ok' => false,
865 'message' => __(
866 'Please enter your name',
867 'tiny-compress-images'
868 ),
869 );
870 echo json_encode( $status );
871 exit();
872 }
873
874 if ( ! isset( $_POST['email'] ) || ! $_POST['email'] ) {
875 $status = (object) array(
876 'ok' => false,
877 'message' => __(
878 'Please enter your email address',
879 'tiny-compress-images'
880 ),
881 );
882 echo json_encode( $status );
883 exit();
884 }
885
886 try {
887 $site = str_replace( array( 'http://', 'https://' ), '', get_bloginfo( 'url' ) );
888 $identifier = 'WordPress plugin for ' . $site;
889 $link = $this->get_absolute_url();
890 $compressor->create_key($_POST['email'], array(
891 'name' => $_POST['name'],
892 'identifier' => $identifier,
893 'link' => $link,
894 ));
895
896 update_option( self::get_prefixed_name( 'api_key_pending' ), true );
897 update_option( self::get_prefixed_name( 'api_key' ), $compressor->get_key() );
898 update_option( self::get_prefixed_name( 'status' ), 0 );
899
900 $status = (object) array(
901 'ok' => true,
902 'message' => null,
903 );
904 } catch ( Tiny_Exception $err ) {
905 list($message) = explode( ' (HTTP', $err->getMessage(), 2 );
906 $status = (object) array(
907 'ok' => false,
908 'message' => $message,
909 );
910 }
911 } else {
912 $status = (object) array(
913 'ok' => false,
914 'message' => 'This feature is not available on your platform',
915 );
916 } // End if().
917
918 echo json_encode( $status );
919 exit();
920 }
921
922 public function update_api_key() {
923 $key = $_POST['key'];
924 if ( ! $this->check_ajax_referer() ) {
925 exit;
926 }
927 if ( ! current_user_can( 'manage_options' ) ) {
928 $status = (object) array(
929 'ok' => false,
930 'message' => 'This feature requires certain user capabilities',
931 );
932 } elseif ( empty( $key ) ) {
933 /* Always save if key is blank, so the key can be deleted. */
934 $status = (object) array(
935 'ok' => true,
936 'message' => null,
937 );
938 } else {
939 $status = Tiny_Compress::create( $key )->get_status();
940 }
941 if ( $status->ok ) {
942 update_option( self::get_prefixed_name( 'api_key_pending' ), false );
943 update_option( self::get_prefixed_name( 'api_key' ), $key );
944 }
945 echo json_encode( $status );
946 exit();
947 }
948
949 public static function wr2x_active() {
950 return function_exists( 'wr2x_get_retina' );
951 }
952
953 public function get_wr2x_option() {
954 $setting = get_option( self::get_prefixed_name( 'sizes' ) );
955 return array(
956 'width' => null,
957 'height' => null,
958 'tinify' => (isset( $setting['wr2x'] ) && 'on' === $setting['wr2x']),
959 );
960 }
961
962 public function compress_wr2x_images() {
963 $option = $this->get_wr2x_option();
964 return self::wr2x_active() && $option['tinify'];
965 }
966
967
968 public function render_format_conversion() {
969 echo '<div class="conversion-options">';
970
971 $convertopts_convert = self::get_prefixed_name( 'convert_format[convert]' );
972 $convertopts_convert_id = self::get_prefixed_name( 'conversion_convert' );
973 $convertopts_convert_checked = $this->get_conversion_enabled() ?
974 ' checked="checked"' : '';
975
976 echo '<p class="tiny-check">';
977 echo '<input type="checkbox" id="' . $convertopts_convert_id . '" ';
978 echo 'name="' . $convertopts_convert . '" ';
979 echo 'value="on"' . $convertopts_convert_checked . '/>';
980 echo '<label for="' . $convertopts_convert_id . '">' .
981 esc_html__( 'Generate optimized image formats', 'tiny-compress-images' ) .
982 '</label>';
983 echo '</p>';
984
985 $convertopts_convert_to_name = self::get_prefixed_name( 'convert_format[convert_to]' );
986 $convertopts_convert_subfields_classname = self::get_prefixed_name( 'convert_fields' );
987 $convertopts_convert_to_id = self::get_prefixed_name( 'convert_convert_to' );
988 $convertopts_convert_value = self::get_convert_format_option( 'convert_to', 'smallest' );
989 $convertopts_convert_disabled =
990 self::get_conversion_enabled() ? '' : ' disabled="disabled"';
991 echo sprintf(
992 '<fieldset class="%s" id="%s" %s>',
993 $convertopts_convert_subfields_classname,
994 $convertopts_convert_to_id,
995 $convertopts_convert_disabled
996 );
997 echo '<h4>' . __( 'Conversion output', 'tiny-compress-images' ) . '</h4>';
998 self::render_convert_to_radiobutton(
999 $convertopts_convert_to_name,
1000 sprintf( self::get_prefixed_name( 'convert_convert_to_%s' ), 'smallest' ),
1001 'smallest',
1002 $convertopts_convert_value,
1003 __( 'Convert to smallest file type (Recommended)', 'tiny-compress-images' ),
1004 __(
1005 'We will calculate what is the best format for your image.',
1006 'tiny-compress-images'
1007 )
1008 );
1009 self::render_convert_to_radiobutton(
1010 $convertopts_convert_to_name,
1011 sprintf( self::get_prefixed_name( 'convert_convert_to_%s' ), 'webp' ),
1012 'webp',
1013 $convertopts_convert_value,
1014 __( 'Convert to WebP', 'tiny-compress-images' ),
1015 __(
1016 'WebP balances a small file size with good visual quality,
1017 supporting transparency and animation.',
1018 'tiny-compress-images'
1019 )
1020 );
1021 self::render_convert_to_radiobutton(
1022 $convertopts_convert_to_name,
1023 sprintf( self::get_prefixed_name( 'convert_convert_to_%s' ), 'avif' ),
1024 'avif',
1025 $convertopts_convert_value,
1026 __( 'Convert to AVIF', 'tiny-compress-images' ),
1027 __( 'AVIF delivers even better compression and image quality than WebP.
1028 Browser support is not as good as WebP.', 'tiny-compress-images' )
1029 );
1030 echo '</fieldset>';
1031 echo '</div>';
1032 }
1033
1034 private static function render_convert_to_radiobutton(
1035 $name,
1036 $id,
1037 $value,
1038 $current,
1039 $label,
1040 $descr
1041 ) {
1042 $checked = ($current === $value ? ' checked="checked"' : '');
1043 echo '<p class="tiny-radio">';
1044 echo '<input type="radio" id="' . $id . '" name="' . $name .
1045 '" value="' . $value . '" ' . $checked . '/>';
1046 echo '<label for="' . $id . '">' . $label;
1047 echo '<span>' . $descr . '</span>';
1048 echo '</label>';
1049 echo '</p>';
1050 }
1051
1052 private static function get_convert_format_option( $option, $default_value ) {
1053 $setting = get_option( self::get_prefixed_name( 'convert_format' ) );
1054 if ( isset( $setting[ $option ] ) && $setting[ $option ] ) {
1055 return $setting[ $option ];
1056 }
1057 return $default_value;
1058 }
1059 }
1060