PluginProbe ʕ •ᴥ•ʔ
TinyPNG – JPEG, PNG & WebP image compression / 2.2.6
TinyPNG – JPEG, PNG & WebP image compression v2.2.6
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 9 years ago css 8 years ago data 9 years ago images 9 years ago js 8 years ago vendor 9 years ago views 8 years ago class-tiny-compress-client.php 9 years ago class-tiny-compress-fopen.php 9 years ago class-tiny-compress.php 9 years ago class-tiny-exception.php 9 years ago class-tiny-image-size.php 9 years ago class-tiny-image.php 8 years ago class-tiny-notices.php 9 years ago class-tiny-php.php 9 years ago class-tiny-plugin.php 8 years ago class-tiny-settings.php 8 years ago class-tiny-wp-base.php 9 years ago
class-tiny-settings.php
720 lines
1 <?php
2 /*
3 * Tiny Compress Images - WordPress plugin.
4 * Copyright (C) 2015-2017 Voormedia 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 public function __construct() {
29 parent::__construct();
30 $this->notices = new Tiny_Notices();
31 }
32
33 private function init_compressor() {
34 $this->compressor = Tiny_Compress::create(
35 $this->get_api_key(),
36 $this->get_method( 'after_compress_callback' )
37 );
38 }
39
40 public function get_absolute_url() {
41 return get_admin_url( null, 'options-media.php#' . self::NAME );
42 }
43
44 public function xmlrpc_init() {
45 try {
46 $this->init_compressor();
47 } catch ( Tiny_Exception $e ) {
48 }
49 }
50
51 public function admin_init() {
52 if ( current_user_can( 'manage_options' ) ) {
53 if ( ! $this->get_api_key() ) {
54 $notice_class = 'error';
55 $notice = esc_html__(
56 'Please register or provide an API key to start compressing images',
57 'tiny-compress-images'
58 );
59 } elseif ( $this->get_api_key_pending() ) {
60 $notice_class = 'notice-warning';
61 $notice = esc_html__(
62 'Please activate your account to start compressing images',
63 'tiny-compress-images'
64 );
65 }
66
67 if ( isset( $notice ) && $notice ) {
68 $link = sprintf(
69 '<a href="options-media.php#%s">%s</a>', self::NAME, $notice
70 );
71 $this->notices->show( 'setting', $link, $notice_class, false );
72 }
73
74 if ( ! Tiny_PHP::client_supported() ) {
75 $details = 'PHP ' . PHP_VERSION;
76 if ( extension_loaded( 'curl' ) ) {
77 $curlinfo = curl_version();
78 $details .= ' with curl ' . $curlinfo['version'];
79 } else {
80 $details .= ' without curl';
81 }
82 $message = sprintf(
83 esc_html__(
84 'You are using an outdated platform (%s) – some features are disabled',
85 'tiny-compress-images'
86 ), $details
87 );
88 $this->notices->show( 'deprecated', $message, 'notice-warning', false );
89 }
90 }// End if().
91
92 try {
93 $this->init_compressor();
94 } catch ( Tiny_Exception $e ) {
95 $this->notices->show(
96 'compressor_exception',
97 esc_html( $e->getMessage(), 'tiny-compress-images' ),
98 'error', false
99 );
100 }
101
102 $section = self::get_prefixed_name( 'settings' );
103 add_settings_section( $section,
104 esc_html__( 'JPEG and PNG optimization', 'tiny-compress-images' ),
105 $this->get_method( 'render_section' ),
106 'media'
107 );
108
109 $field = self::get_prefixed_name( 'api_key' );
110 register_setting( 'media', $field );
111 add_settings_field( $field,
112 esc_html__( 'TinyPNG account', 'tiny-compress-images' ),
113 $this->get_method( 'render_pending_status' ),
114 'media',
115 $section
116 );
117
118 $field = self::get_prefixed_name( 'api_key_pending' );
119 register_setting( 'media', $field );
120
121 $field = self::get_prefixed_name( 'sizes' );
122 register_setting( 'media', $field );
123 add_settings_field( $field,
124 esc_html__( 'File compression', 'tiny-compress-images' ),
125 $this->get_method( 'render_sizes' ),
126 'media',
127 $section
128 );
129
130 $field = self::get_prefixed_name( 'resize_original' );
131 register_setting( 'media', $field );
132 add_settings_field( $field,
133 esc_html__( 'Original image', 'tiny-compress-images' ),
134 $this->get_method( 'render_resize' ),
135 'media',
136 $section
137 );
138
139 $field = self::get_prefixed_name( 'preserve_data' );
140 register_setting( 'media', $field );
141
142 add_settings_section( 'section_end', '',
143 $this->get_method( 'render_section_end' ),
144 'media'
145 );
146
147 add_action(
148 'wp_ajax_tiny_image_sizes_notice',
149 $this->get_method( 'image_sizes_notice' )
150 );
151
152 add_action(
153 'wp_ajax_tiny_account_status',
154 $this->get_method( 'account_status' )
155 );
156
157 add_action(
158 'wp_ajax_tiny_settings_create_api_key',
159 $this->get_method( 'create_api_key' )
160 );
161
162 add_action(
163 'wp_ajax_tiny_settings_update_api_key',
164 $this->get_method( 'update_api_key' )
165 );
166 }
167
168 public function image_sizes_notice() {
169 $this->render_image_sizes_notice(
170 $_GET['image_sizes_selected'],
171 isset( $_GET['resize_original'] ),
172 isset( $_GET['compress_wr2x'] )
173 );
174 exit();
175 }
176
177 public function account_status() {
178 $this->render_account_status();
179 exit();
180 }
181
182 public function get_compressor() {
183 return $this->compressor;
184 }
185
186 public function set_compressor( $compressor ) {
187 $this->compressor = $compressor;
188 }
189
190 public function get_status() {
191 return intval( get_option( self::get_prefixed_name( 'status' ) ) );
192 }
193
194 protected function get_api_key() {
195 if ( defined( 'TINY_API_KEY' ) ) {
196 return TINY_API_KEY;
197 } else {
198 return get_option( self::get_prefixed_name( 'api_key' ) );
199 }
200 }
201
202 protected function get_api_key_pending() {
203 if ( defined( 'TINY_API_KEY' ) ) {
204 return false;
205 } else {
206 return get_option( self::get_prefixed_name( 'api_key_pending' ) );
207 }
208 }
209
210 protected function clear_api_key_pending() {
211 delete_option( self::get_prefixed_name( 'api_key_pending' ) );
212 }
213
214 protected static function get_intermediate_size( $size ) {
215 /* Inspired by
216 http://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes */
217 global $_wp_additional_image_sizes;
218
219 $width = get_option( $size . '_size_w' );
220 $height = get_option( $size . '_size_h' );
221
222 /* Note: dimensions might be 0 to indicate no limit. */
223 if ( $width || $height ) {
224 return array( $width, $height );
225 }
226
227 if ( isset( $_wp_additional_image_sizes[ $size ] ) ) {
228 $sizes = $_wp_additional_image_sizes[ $size ];
229 return array(
230 isset( $sizes['width'] ) ? $sizes['width'] : null,
231 isset( $sizes['height'] ) ? $sizes['height'] : null,
232 );
233 }
234 return array( null, null );
235 }
236
237 public function get_sizes() {
238 if ( is_array( $this->sizes ) ) {
239 return $this->sizes;
240 }
241
242 $setting = get_option( self::get_prefixed_name( 'sizes' ) );
243
244 $size = Tiny_Image::ORIGINAL;
245 $this->sizes = array(
246 $size => array(
247 'width' => null,
248 'height' => null,
249 'tinify' => ! is_array( $setting ) ||
250 ( isset( $setting[ $size ] ) && 'on' === $setting[ $size ] ),
251 ),
252 );
253
254 foreach ( get_intermediate_image_sizes() as $size ) {
255 if ( self::DUMMY_SIZE === $size ) {
256 continue;
257 }
258
259 list($width, $height) = self::get_intermediate_size( $size );
260 if ( $width || $height ) {
261 $this->sizes[ $size ] = array(
262 'width' => $width,
263 'height' => $height,
264 'tinify' => ! is_array( $setting ) ||
265 ( isset( $setting[ $size ] ) && 'on' === $setting[ $size ] ),
266 );
267 }
268 }
269
270 return $this->sizes;
271 }
272
273 public function get_active_tinify_sizes() {
274 if ( is_array( $this->tinify_sizes ) ) {
275 return $this->tinify_sizes;
276 }
277
278 $this->tinify_sizes = array();
279 foreach ( $this->get_sizes() as $size => $values ) {
280 if ( $values['tinify'] ) {
281 $this->tinify_sizes[] = $size;
282 }
283 }
284 return $this->tinify_sizes;
285 }
286
287 public function get_resize_enabled() {
288 /* This only applies if the original is being resized. */
289 $sizes = $this->get_sizes();
290 if ( ! $sizes[ Tiny_Image::ORIGINAL ]['tinify'] ) {
291 return false;
292 }
293
294 $setting = get_option( self::get_prefixed_name( 'resize_original' ) );
295 return isset( $setting['enabled'] ) && 'on' === $setting['enabled'];
296 }
297
298 public function get_preserve_enabled( $name ) {
299 $setting = get_option( self::get_prefixed_name( 'preserve_data' ) );
300 return isset( $setting[ $name ] ) && 'on' === $setting[ $name ];
301 }
302
303 public function get_preserve_options( $size_name ) {
304 if ( ! Tiny_Image::is_original( $size_name ) ) {
305 return false;
306 }
307 $options = array();
308 $settings = get_option( self::get_prefixed_name( 'preserve_data' ) );
309 if ( $settings ) {
310 $keys = array_keys( $settings );
311 foreach ( $keys as &$key ) {
312 if ( 'on' === $settings[ $key ] ) {
313 array_push( $options, $key );
314 }
315 }
316 }
317 return $options;
318 }
319
320 public function get_resize_options( $size_name ) {
321 if ( ! Tiny_Image::is_original( $size_name ) ) {
322 return false;
323 }
324 if ( ! $this->get_resize_enabled() ) {
325 return false;
326 }
327 $setting = get_option( self::get_prefixed_name( 'resize_original' ) );
328 $width = intval( $setting['width'] );
329 $height = intval( $setting['height'] );
330 $method = $width > 0 && $height > 0 ? 'fit' : 'scale';
331 $options['method'] = $method;
332 if ( $width > 0 ) {
333 $options['width'] = $width;
334 }
335 if ( $height > 0 ) {
336 $options['height'] = $height;
337 }
338 return sizeof( $options ) >= 2 ? $options : false;
339 }
340
341 public function render_section_end() {
342 echo '</div>';
343 }
344
345 public function render_section() {
346 echo '<div class="' . self::NAME . '">';
347 echo '<span id="' . self::NAME . '"></span>';
348 }
349
350 public function render_sizes() {
351 echo '<p>';
352 esc_html_e(
353 'Choose sizes to compress. Remember each selected size counts as a compression.',
354 'tiny-compress-images'
355 );
356 echo '</p>';
357 echo '<input type="hidden" name="' .
358 self::get_prefixed_name( 'sizes[' . self::DUMMY_SIZE . ']' ) . '" value="on"/>';
359
360 foreach ( $this->get_sizes() as $size => $option ) {
361 $this->render_size_checkbox( $size, $option );
362 }
363 if ( self::wr2x_active() ) {
364 $this->render_size_checkbox( 'wr2x', $this->get_wr2x_option() );
365 }
366 echo '<br>';
367 echo '<div id="tiny-image-sizes-notice">';
368
369 $this->render_image_sizes_notice(
370 count( self::get_active_tinify_sizes() ),
371 self::get_resize_enabled(),
372 self::compress_wr2x_images()
373 );
374
375 echo '</div>';
376 }
377
378 private function render_size_checkbox( $size, $option ) {
379 $id = self::get_prefixed_name( "sizes_$size" );
380 $name = self::get_prefixed_name( 'sizes[' . $size . ']' );
381 $checked = ( $option['tinify'] ? ' checked="checked"' : '' );
382 if ( Tiny_Image::is_original( $size ) ) {
383 $label = esc_html__( 'Original image', 'tiny-compress-images' ) . ' (' .
384 esc_html__( 'overwritten by compressed image', 'tiny-compress-images' ) . ')';
385 } elseif ( Tiny_Image::is_retina( $size ) ) {
386 $label = esc_html__( 'WP Retina 2x sizes', 'tiny-compress-images' );
387 } else {
388 $width = $option['width'];
389 if ( ! $width ) {
390 $width = '?';
391 }
392
393 $height = $option['height'];
394 if ( ! $height ) {
395 $height = '?';
396 }
397
398 $label = esc_html( ucfirst( str_replace( '_', ' ', $size ) ) )
399 . ' - ' . $width . 'x' . $height;
400 }
401 echo '<p>';
402 echo '<input type="checkbox" id="' . $id . '" name="' . $name .
403 '" value="on" ' . $checked . '/>';
404 echo '<label for="' . $id . '">' . $label . '</label>';
405 echo '</p>';
406 }
407
408 public function render_image_sizes_notice(
409 $active_sizes_count, $resize_original_enabled, $compress_wr2x ) {
410 echo '<p>';
411 if ( $resize_original_enabled ) {
412 $active_sizes_count++;
413 }
414 if ( $compress_wr2x ) {
415 $active_sizes_count *= 2;
416 }
417
418 if ( $active_sizes_count < 1 ) {
419 esc_html_e(
420 'With these settings no images will be compressed.',
421 'tiny-compress-images'
422 );
423 } else {
424 $free_images_per_month = floor(
425 Tiny_Config::MONTHLY_FREE_COMPRESSIONS / $active_sizes_count
426 );
427
428 $strong = array(
429 'strong' => array(),
430 );
431
432 printf( wp_kses( __(
433 'With these settings you can compress <strong>at least %1$s images</strong> %2$s',
434 'tiny-compress-images'
435 ), $strong ), $free_images_per_month, 'for free each month.' );
436
437 if ( self::wr2x_active() ) {
438 echo '</p>';
439 echo '<p>';
440 esc_html_e(
441 'If selected, retina sizes will be compressed when generated by WP Retina 2x',
442 'tiny-compress-images'
443 );
444 echo '<br>';
445 esc_html_e(
446 'Each retina size will count as an additional compression.',
447 'tiny-compress-images'
448 );
449 }
450 }
451 echo '</p>';
452 }
453
454 public function render_resize() {
455 echo '<p class="tiny-resize-unavailable" style="display: none">';
456 esc_html_e(
457 'Enable compression of the original image size for more options.',
458 'tiny-compress-images'
459 );
460 echo '</p>';
461
462 $id = self::get_prefixed_name( 'resize_original_enabled' );
463 $name = self::get_prefixed_name( 'resize_original[enabled]' );
464 $checked = ( $this->get_resize_enabled() ? ' checked="checked"' : '' );
465
466 $label = esc_html__(
467 'Resize and compress the original image',
468 'tiny-compress-images'
469 );
470
471 echo '<p class="tiny-resize-available">';
472 echo '<input type="checkbox" id="' . $id . '" name="' . $name .
473 '" value="on" ' . $checked . '/>';
474 echo '<label for="' . $id . '">' . $label . '</label>';
475 echo '<br>';
476 echo '</p>';
477
478 echo '<p class="tiny-resize-available tiny-resize-resolution">';
479 printf( '%s ', esc_html__( 'Max Width' ) );
480 $this->render_resize_input( 'width' );
481 printf( '%s ', esc_html__( 'Max Height' ) );
482 $this->render_resize_input( 'height' );
483 echo '</p>';
484
485 echo '<p class="tiny-resize-available tiny-resize-resolution">';
486
487 esc_html_e(
488 'Resizing takes 1 additional compression for each image that is larger.',
489 'tiny-compress-images'
490 );
491
492 echo '</p><br>';
493
494 $this->render_preserve_input(
495 'creation',
496 esc_html__(
497 'Preserve creation date and time in the original image',
498 'tiny-compress-images'
499 ) . ' ' .
500 esc_html__( '(JPEG only)', 'tiny-compress-images' )
501 );
502
503 $this->render_preserve_input(
504 'copyright',
505 esc_html__(
506 'Preserve copyright information in the original image',
507 'tiny-compress-images'
508 )
509 );
510
511 $this->render_preserve_input(
512 'location',
513 esc_html__(
514 'Preserve GPS location in the original image',
515 'tiny-compress-images'
516 ) . ' ' .
517 esc_html__( '(JPEG only)', 'tiny-compress-images' )
518 );
519 }
520
521 public function render_preserve_input( $name, $description ) {
522 echo '<p class="tiny-preserve">';
523 $id = sprintf( self::get_prefixed_name( 'preserve_data_%s' ), $name );
524 $field = sprintf( self::get_prefixed_name( 'preserve_data[%s]' ), $name );
525 $checked = ( $this->get_preserve_enabled( $name ) ? ' checked="checked"' : '' );
526 $label = esc_html( $description, 'tiny-compress-images' );
527 echo '<input type="checkbox" id="' . $id . '" name="' . $field .
528 '" value="on" ' . $checked . '/>';
529 echo '<label for="' . $id . '">' . $label . '</label>';
530 echo '<br>';
531 echo '</p>';
532 }
533
534 public function render_resize_input( $name ) {
535 $id = sprintf( self::get_prefixed_name( 'resize_original_%s' ), $name );
536 $field = sprintf( self::get_prefixed_name( 'resize_original[%s]' ), $name );
537 $settings = get_option( self::get_prefixed_name( 'resize_original' ) );
538 $value = isset( $settings[ $name ] ) ? $settings[ $name ] : '2048';
539 echo '<input type="number" id="' . $id . '" name="' . $field .
540 '" value="' . $value . '" size="5" />';
541 }
542
543 public function get_compression_count() {
544 $field = self::get_prefixed_name( 'status' );
545 return get_option( $field );
546 }
547
548 public function after_compress_callback( $compressor ) {
549 $count = $compressor->get_compression_count();
550 if ( ! is_null( $count ) ) {
551 $field = self::get_prefixed_name( 'status' );
552 update_option( $field, $count );
553 }
554 if ( $compressor->limit_reached() ) {
555 $link = '<a href="https://tinypng.com/dashboard/developers" target="_blank">' .
556 esc_html__( 'TinyPNG API account', 'tiny-compress-images' ) . '</a>';
557
558 $this->notices->add('limit-reached',
559 sprintf(
560 esc_html__(
561 'You have reached your limit of %s compressions this month.',
562 'tiny-compress-images'
563 ),
564 $count
565 ) .
566 sprintf(
567 esc_html__(
568 'Upgrade your %s if you like to compress more images.',
569 'tiny-compress-images'
570 ),
571 $link
572 )
573 );
574 } else {
575 $this->notices->remove( 'limit-reached' );
576 }
577 }
578
579 public function render_account_status() {
580 $key = $this->get_api_key();
581 if ( empty( $key ) ) {
582 $compressor = $this->get_compressor();
583 if ( $compressor->can_create_key() ) {
584 include( dirname( __FILE__ ) . '/views/account-status-create-advanced.php' );
585 } else {
586 include( dirname( __FILE__ ) . '/views/account-status-create-simple.php' );
587 }
588 } else {
589 $status = $this->compressor->get_status();
590 $status->pending = false;
591 if ( $status->ok ) {
592 if ( $this->get_api_key_pending() ) {
593 $this->clear_api_key_pending();
594 }
595 } else {
596 if ( $this->get_api_key_pending() ) {
597 $status->ok = true;
598 $status->pending = true;
599 $status->message = (
600 'An email has been sent with a link to activate your account'
601 );
602 }
603 }
604 include( dirname( __FILE__ ) . '/views/account-status-connected.php' );
605 }
606 }
607
608 public function render_pending_status() {
609 $key = $this->get_api_key();
610 if ( empty( $key ) ) {
611 $compressor = $this->get_compressor();
612 if ( $compressor->can_create_key() ) {
613 include( dirname( __FILE__ ) . '/views/account-status-create-advanced.php' );
614 } else {
615 include( dirname( __FILE__ ) . '/views/account-status-create-simple.php' );
616 }
617 } else {
618 include( dirname( __FILE__ ) . '/views/account-status-loading.php' );
619 }
620 }
621
622 public function create_api_key() {
623 $compressor = $this->get_compressor();
624 if ( $compressor->can_create_key() ) {
625 if ( ! isset( $_POST['name'] ) || ! $_POST['name'] ) {
626 $status = (object) array(
627 'ok' => false,
628 'message' => __(
629 'Please enter your name', 'tiny-compress-images'
630 ),
631 );
632 echo json_encode( $status );
633 exit();
634 }
635
636 if ( ! isset( $_POST['email'] ) || ! $_POST['email'] ) {
637 $status = (object) array(
638 'ok' => false,
639 'message' => __(
640 'Please enter your email address', 'tiny-compress-images'
641 ),
642 );
643 echo json_encode( $status );
644 exit();
645 }
646
647 try {
648 $site = str_replace( array( 'http://', 'https://' ), '', get_bloginfo( 'url' ) );
649 $identifier = 'WordPress plugin for ' . $site;
650 $link = $this->get_absolute_url();
651 $compressor->create_key( $_POST['email'], array(
652 'name' => $_POST['name'],
653 'identifier' => $identifier,
654 'link' => $link,
655 ) );
656
657 update_option( self::get_prefixed_name( 'api_key_pending' ), true );
658 update_option( self::get_prefixed_name( 'api_key' ), $compressor->get_key() );
659 update_option( self::get_prefixed_name( 'status' ), 0 );
660
661 $status = (object) array(
662 'ok' => true,
663 'message' => null,
664 );
665 } catch ( Tiny_Exception $err ) {
666 list( $message ) = explode( ' (HTTP', $err->getMessage(), 2 );
667 $status = (object) array(
668 'ok' => false,
669 'message' => $message,
670 );
671 }
672 } else {
673 $status = (object) array(
674 'ok' => false,
675 'message' => 'This feature is not available on your platform',
676 );
677 }// End if().
678
679 echo json_encode( $status );
680 exit();
681 }
682
683 public function update_api_key() {
684 $key = $_POST['key'];
685 if ( empty( $key ) ) {
686 /* Always save if key is blank, so the key can be deleted. */
687 $status = (object) array(
688 'ok' => true,
689 'message' => null,
690 );
691 } else {
692 $status = Tiny_Compress::create( $key )->get_status();
693 }
694 if ( $status->ok ) {
695 update_option( self::get_prefixed_name( 'api_key_pending' ), false );
696 update_option( self::get_prefixed_name( 'api_key' ), $key );
697 }
698 echo json_encode( $status );
699 exit();
700 }
701
702 public static function wr2x_active() {
703 return is_plugin_active( 'wp-retina-2x/wp-retina-2x.php' );
704 }
705
706 public function get_wr2x_option() {
707 $setting = get_option( self::get_prefixed_name( 'sizes' ) );
708 return array(
709 'width' => null,
710 'height' => null,
711 'tinify' => ( isset( $setting['wr2x'] ) && 'on' === $setting['wr2x'] ),
712 );
713 }
714
715 public function compress_wr2x_images() {
716 $option = $this->get_wr2x_option();
717 return self::wr2x_active() && $option['tinify'];
718 }
719 }
720