Plugin Directory

source: tiny-compress-images/trunk/src/class-tiny-plugin.php

Last change on this file was 3454600, checked in by TinyPNG, 7 weeks ago

Update to version 3.6.9 from GitHub

File size: 25.2 KB
Line 
1<?php
2/*
3* Tiny Compress Images - WordPress plugin.
4* Copyright (C) 2015-2023 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*/
20class Tiny_Plugin extends Tiny_WP_Base {
21        const VERSION         = '3.6.8';
22        const MEDIA_COLUMN    = self::NAME;
23        const DATETIME_FORMAT = 'Y-m-d G:i:s';
24
25        private static $version;
26
27        private $settings;
28        private $twig;
29
30        public static function jpeg_quality() {
31                return 85;
32        }
33
34        public static function version() {
35                /* Avoid using get_plugin_data() because it is not loaded early enough
36                        in xmlrpc.php. */
37                return self::VERSION;
38        }
39
40        public function __construct() {
41                parent::__construct();
42                $this->settings = new Tiny_Settings();
43        }
44
45        public function set_compressor( $compressor ) {
46                $this->settings->set_compressor( $compressor );
47        }
48
49        public function init() {
50                add_filter(
51                        'jpeg_quality',
52                        $this->get_static_method( 'jpeg_quality' )
53                );
54
55                add_filter(
56                        'wp_editor_set_quality',
57                        $this->get_static_method( 'jpeg_quality' )
58                );
59
60                add_filter(
61                        'wp_generate_attachment_metadata',
62                        $this->get_method( 'process_attachment' ),
63                        10,
64                        2
65                );
66
67                add_action( 'delete_attachment', $this->get_method( 'clean_attachment' ), 10, 2 );
68
69                load_plugin_textdomain(
70                        self::NAME,
71                        false,
72                        dirname( plugin_basename( __FILE__ ) ) . '/languages'
73                );
74
75                new Tiny_Picture( $this->settings, ABSPATH, array( get_site_url() ) );
76                $this->tiny_compatibility();
77        }
78
79        public function cli_init() {
80                Tiny_CLI::register_command( $this->settings );
81        }
82
83        public function ajax_init() {
84                add_filter(
85                        'wp_ajax_tiny_async_optimize_upload_new_media',
86                        $this->get_method( 'compress_on_upload' )
87                );
88
89                add_action(
90                        'wp_ajax_tiny_compress_image_from_library',
91                        $this->get_method( 'compress_image_from_library' )
92                );
93
94                add_action(
95                        'wp_ajax_tiny_compress_image_for_bulk',
96                        $this->get_method( 'compress_image_for_bulk' )
97                );
98
99                add_action(
100                        'wp_ajax_tiny_get_optimization_statistics',
101                        $this->get_method( 'ajax_optimization_statistics' )
102                );
103
104                add_action(
105                        'wp_ajax_tiny_get_compression_status',
106                        $this->get_method( 'ajax_compression_status' )
107                );
108
109                add_action(
110                        'wp_ajax_tiny_mark_image_as_compressed',
111                        $this->get_method( 'mark_image_as_compressed' )
112                );
113
114                /* When touching any functionality linked to image compressions when
115                        uploading images make sure it also works with XML-RPC. See README. */
116                add_filter(
117                        'wp_ajax_nopriv_tiny_rpc',
118                        $this->get_method( 'process_rpc_request' )
119                );
120
121                if ( $this->settings->compress_wr2x_images() ) {
122                        add_action(
123                                'wr2x_upload_retina',
124                                $this->get_method( 'compress_original_retina_image' ),
125                                10,
126                                2
127                        );
128
129                        add_action(
130                                'wr2x_retina_file_added',
131                                $this->get_method( 'compress_retina_image' ),
132                                10,
133                                3
134                        );
135
136                        add_action(
137                                'wr2x_retina_file_removed',
138                                $this->get_method( 'remove_retina_image' ),
139                                10,
140                                2
141                        );
142                }
143        }
144
145        public function admin_init() {
146                add_action(
147                        'wp_dashboard_setup',
148                        $this->get_method( 'add_dashboard_widget' )
149                );
150
151                add_action(
152                        'admin_enqueue_scripts',
153                        $this->get_method( 'enqueue_scripts' )
154                );
155
156                add_action(
157                        'admin_action_tiny_bulk_action',
158                        $this->get_method( 'media_library_bulk_action' )
159                );
160
161                add_action(
162                        'admin_action_-1',
163                        $this->get_method( 'media_library_bulk_action' )
164                );
165
166                add_action(
167                        'admin_action_tiny_bulk_mark_compressed',
168                        $this->get_method( 'media_library_bulk_action' )
169                );
170
171                add_filter(
172                        'manage_media_columns',
173                        $this->get_method( 'add_media_columns' )
174                );
175
176                add_action(
177                        'manage_media_custom_column',
178                        $this->get_method( 'render_media_column' ),
179                        10,
180                        2
181                );
182
183                add_action(
184                        'attachment_submitbox_misc_actions',
185                        $this->get_method( 'show_media_info' )
186                );
187
188                $plugin = plugin_basename(
189                        dirname( __DIR__ ) . '/tiny-compress-images.php'
190                );
191
192                add_filter(
193                        "plugin_action_links_$plugin",
194                        $this->get_method( 'add_plugin_links' )
195                );
196
197                $this->tiny_compatibility();
198
199                add_thickbox();
200                Tiny_Logger::init();
201        }
202
203        public function admin_menu() {
204                add_media_page(
205                        __( 'Bulk Optimization', 'tiny-compress-images' ),
206                        esc_html__( 'Bulk TinyPNG', 'tiny-compress-images' ),
207                        'upload_files',
208                        'tiny-bulk-optimization',
209                        $this->get_method( 'render_bulk_optimization_page' )
210                );
211        }
212
213        public function add_plugin_links( $current_links ) {
214                $additional = array(
215                        'settings' => sprintf(
216                                '<a href="options-general.php?page=tinify">%s</a>',
217                                esc_html__( 'Settings', 'tiny-compress-images' )
218                        ),
219                        'bulk'     => sprintf(
220                                '<a href="upload.php?page=tiny-bulk-optimization">%s</a>',
221                                esc_html__( 'Bulk TinyPNG', 'tiny-compress-images' )
222                        ),
223                );
224                return array_merge( $additional, $current_links );
225        }
226
227        public function tiny_compatibility() {
228                if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
229                        new Tiny_WPML();
230                }
231
232                if ( Tiny_AS3CF::is_active() ) {
233                        new Tiny_AS3CF( $this->settings );
234                }
235
236                new Tiny_WooCommerce();
237        }
238
239        public function compress_original_retina_image( $attachment_id, $path ) {
240                $tiny_image = new Tiny_Image( $this->settings, $attachment_id );
241                $tiny_image->compress_retina( 'original_wr2x', $path );
242        }
243
244        public function compress_retina_image( $attachment_id, $path, $size_name ) {
245                $tiny_image = new Tiny_Image( $this->settings, $attachment_id );
246                $tiny_image->compress_retina( $size_name . '_wr2x', $path );
247        }
248
249        public function remove_retina_image( $attachment_id, $path ) {
250                $tiny_image = new Tiny_Image( $this->settings, $attachment_id );
251                $tiny_image->remove_retina_metadata();
252        }
253
254        public function enqueue_scripts( $hook ) {
255                wp_enqueue_style(
256                        self::NAME . '_admin',
257                        plugins_url( '/css/admin.css', __FILE__ ),
258                        array(),
259                        self::version()
260                );
261
262                wp_enqueue_style(
263                        self::NAME . '_chart',
264                        plugins_url( '/css/optimization-chart.css', __FILE__ ),
265                        array(),
266                        self::version()
267                );
268
269                wp_register_script(
270                        self::NAME . '_admin',
271                        plugins_url( '/js/admin.js', __FILE__ ),
272                        array(),
273                        self::version(),
274                        true
275                );
276
277                // WordPress < 3.3 does not handle multidimensional arrays
278                wp_localize_script(
279                        self::NAME . '_admin',
280                        'tinyCompress',
281                        array(
282                                'nonce'                  => wp_create_nonce( 'tiny-compress' ),
283                                'wpVersion'              => self::wp_version(),
284                                'pluginVersion'          => self::version(),
285                                'L10nAllDone'            => __(
286                                        'All images are processed',
287                                        'tiny-compress-images'
288                                ),
289                                'L10nNoActionTaken'      => __(
290                                        'No action taken',
291                                        'tiny-compress-images'
292                                ),
293                                'L10nDuplicate'          => __(
294                                        'Image was already processed',
295                                        'tiny-compress-images'
296                                ),
297                                'L10nBulkAction'         => __( 'Compress Images', 'tiny-compress-images' ),
298                                'L10nBulkMarkCompressed' => __(
299                                        'Mark as Compressed',
300                                        'tiny-compress-images'
301                                ),
302                                'L10nCancelled'          => __( 'Cancelled', 'tiny-compress-images' ),
303                                'L10nCompressing'        => __( 'Compressing', 'tiny-compress-images' ),
304                                'L10nCompressed'         => __( 'compressed', 'tiny-compress-images' ),
305                                'L10nConverted'          => __( 'converted', 'tiny-compress-images' ),
306                                'L10nFile'               => __( 'File', 'tiny-compress-images' ),
307                                'L10nSizesOptimized'     => __(
308                                        'Sizes optimized',
309                                        'tiny-compress-images'
310                                ),
311                                'L10nInitialSize'        => __( 'Initial size', 'tiny-compress-images' ),
312                                'L10nCurrentSize'        => __( 'Current size', 'tiny-compress-images' ),
313                                'L10nSavings'            => __( 'Savings', 'tiny-compress-images' ),
314                                'L10nStatus'             => __( 'Status', 'tiny-compress-images' ),
315                                'L10nShowMoreDetails'    => __(
316                                        'Show more details',
317                                        'tiny-compress-images'
318                                ),
319                                'L10nError'              => __( 'Error', 'tiny-compress-images' ),
320                                'L10nLatestError'        => __( 'Latest error', 'tiny-compress-images' ),
321                                'L10nInternalError'      => __( 'Internal error', 'tiny-compress-images' ),
322                                'L10nOutOf'              => __( 'out of', 'tiny-compress-images' ),
323                                'L10nWaiting'            => __( 'Waiting', 'tiny-compress-images' ),
324                        )
325                );
326
327                wp_enqueue_script( self::NAME . '_admin' );
328
329                if ( 'media_page_tiny-bulk-optimization' == $hook ) {
330                        wp_enqueue_style(
331                                self::NAME . '_tiny_bulk_optimization',
332                                plugins_url( '/css/bulk-optimization.css', __FILE__ ),
333                                array(),
334                                self::version()
335                        );
336
337                        wp_enqueue_style(
338                                self::NAME . '_chart',
339                                plugins_url( '/css/optimization-chart.css', __FILE__ ),
340                                array(),
341                                self::version()
342                        );
343
344                        wp_register_script(
345                                self::NAME . '_tiny_bulk_optimization',
346                                plugins_url( '/js/bulk-optimization.js', __FILE__ ),
347                                array(),
348                                self::version(),
349                                true
350                        );
351
352                        wp_enqueue_script( self::NAME . '_tiny_bulk_optimization' );
353                }
354        }
355
356        public function process_attachment( $metadata, $attachment_id ) {
357                if ( $this->settings->auto_compress_enabled() ) {
358                        if (
359                                $this->settings->background_compress_enabled()
360                        ) {
361                                $this->async_compress_on_upload( $metadata, $attachment_id );
362                        } else {
363                                return $this->blocking_compress_on_upload( $metadata, $attachment_id );
364                        }
365                }
366
367                return $metadata;
368        }
369
370        public function blocking_compress_on_upload( $metadata, $attachment_id ) {
371                if ( ! empty( $metadata ) ) {
372                        $tiny_image = new Tiny_Image( $this->settings, $attachment_id, $metadata );
373
374                        Tiny_Logger::debug(
375                                'blocking compress on upload',
376                                array(
377                                        'image_id' => $attachment_id,
378                                )
379                        );
380
381                        $result = $tiny_image->compress();
382                        return $tiny_image->get_wp_metadata();
383                } else {
384                        return $metadata;
385                }
386        }
387
388        public function async_compress_on_upload( $metadata, $attachment_id ) {
389                $context     = 'wp';
390                $action      = 'tiny_async_optimize_upload_new_media';
391                $_ajax_nonce = wp_create_nonce( 'new_media-' . $attachment_id );
392                $body        = compact( 'action', '_ajax_nonce', 'metadata', 'attachment_id', 'context' );
393
394                $args = array(
395                        'timeout'   => 0.01,
396                        'blocking'  => false,
397                        'body'      => $body,
398                        'cookies'   => isset( $_COOKIE ) && is_array( $_COOKIE ) ? $_COOKIE : array(),
399                        'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
400                );
401
402                if ( defined( 'XMLRPC_REQUEST' ) && get_current_user_id() ) {
403                        /* We generate a hash to be used for the transient we use to store the current user. */
404                        $rpc_hash = md5( maybe_serialize( $body ) );
405
406                        $args['body']['tiny_rpc_action'] = $args['body']['action'];
407                        /* We set a different action to make sure that all RPC requests are first validated. */
408                        $args['body']['action']         = 'tiny_rpc';
409                        $args['body']['tiny_rpc_hash']  = $rpc_hash;
410                        $args['body']['tiny_rpc_nonce'] = wp_create_nonce( 'tiny_rpc_' . $rpc_hash );
411
412                        /*
413                                We can't use cookies here, so we save the user id in a transient
414                                so that we can retrieve it again when processing the RPC request.
415                                We should be able to use a relatively short timeout, as the request
416                                should be processed directly afterwards.
417                        */
418                        set_transient( 'tiny_rpc_' . $rpc_hash, get_current_user_id(), 10 );
419                }
420
421                Tiny_Logger::debug(
422                        'remote post',
423                        array(
424                                'image_id' => $attachment_id,
425                        )
426                );
427
428                if ( getenv( 'WORDPRESS_HOST' ) !== false ) {
429                        wp_remote_post( getenv( 'WORDPRESS_HOST' ) . '/wp-admin/admin-ajax.php', $args );
430                } else {
431                        wp_remote_post( admin_url( 'admin-ajax.php' ), $args );
432                }
433        }
434
435        public function process_rpc_request() {
436                if (
437                        empty( $_POST['tiny_rpc_action'] ) ||
438                        empty( $_POST['tiny_rpc_hash'] ) ||
439                        32 !== strlen( $_POST['tiny_rpc_hash'] )
440                ) {
441                        exit();
442                }
443
444                $rpc_hash = sanitize_key( $_POST['tiny_rpc_hash'] );
445                $user_id  = absint( get_transient( 'tiny_rpc_' . $rpc_hash ) );
446                $user     = $user_id ? get_userdata( $user_id ) : false;
447
448                /* We no longer need the transient. */
449                delete_transient( 'tiny_rpc_' . $rpc_hash );
450
451                if ( ! $user || ! $user->exists() ) {
452                        exit();
453                }
454                wp_set_current_user( $user_id );
455
456                if ( ! check_ajax_referer( 'tiny_rpc_' . $rpc_hash, 'tiny_rpc_nonce', false ) ) {
457                        exit();
458                }
459
460                /* Now that everything is checked, perform the actual action. */
461                $action = $_POST['tiny_rpc_action'];
462                unset(
463                        $_POST['action'],
464                        $_POST['tiny_rpc_action'],
465                        $_POST['tiny_rpc_id'],
466                        $_POST['tiny_rpc_nonce']
467                );
468                do_action( 'wp_ajax_' . $action );
469        }
470
471        public function compress_on_upload() {
472                if ( ! wp_verify_nonce( $_POST['_ajax_nonce'], 'new_media-' . $_POST['attachment_id'] ) ) {
473                        exit;
474                }
475                if ( current_user_can( 'upload_files' ) ) {
476                        $attachment_id = intval( $_POST['attachment_id'] );
477                        $metadata      = $_POST['metadata'];
478                        if ( is_array( $metadata ) ) {
479                                $tiny_image = new Tiny_Image( $this->settings, $attachment_id, $metadata );
480
481                                Tiny_Logger::debug(
482                                        'compress on upload',
483                                        array(
484                                                'image_id' => $attachment_id,
485                                        )
486                                );
487
488                                $result = $tiny_image->compress();
489                                // The wp_update_attachment_metadata call is thrown because the
490                                // dimensions of the original image can change. This will then
491                                // trigger other plugins and can result in unexpected behaviour and
492                                // further changes to the image. This may require another approach.
493                                // Note that as of WP 5.3 it is advised to not hook into this filter
494                                // anymore, so other plugins are less likely to be triggered.
495                                wp_update_attachment_metadata( $attachment_id, $tiny_image->get_wp_metadata() );
496                        }
497                }
498                exit();
499        }
500
501        /**
502         * Validates AJAX request for attachment operations.
503         *
504         * @since 3.0.0
505         *
506         * @return array Either error array ['error' => 'message']
507         *               or success array ['data' => [$id, $metadata]]
508         */
509        private function validate_ajax_attachment_request() {
510                if ( ! $this->check_ajax_referer() ) {
511                        exit();
512                }
513                if ( ! current_user_can( 'upload_files' ) ) {
514                        return array(
515                                'error' => esc_html__(
516                                        "You don't have permission to upload files.",
517                                        'tiny-compress-images'
518                                ),
519                        );
520                }
521                if ( empty( $_POST['id'] ) ) {
522                        return array(
523                                'error' => esc_html__(
524                                        'Not a valid media file.',
525                                        'tiny-compress-images'
526                                ),
527                        );
528                }
529                $id       = intval( $_POST['id'] );
530                $metadata = wp_get_attachment_metadata( $id );
531                if ( ! is_array( $metadata ) ) {
532                        return array(
533                                'error' => esc_html__(
534                                        'Could not find metadata of media file.',
535                                        'tiny-compress-images'
536                                ),
537                        );
538                }
539
540                return array(
541                        'data' => array( $id, $metadata ),
542                );
543        }
544
545        public function compress_image_from_library() {
546                $response = $this->validate_ajax_attachment_request();
547                if ( isset( $response['error'] ) ) {
548                        echo $response['error'];
549                        exit();
550                }
551                list($id, $metadata) = $response['data'];
552
553                Tiny_Logger::debug(
554                        'compress from library',
555                        array(
556                                'image_id' => $id,
557                        )
558                );
559
560                $tiny_image = new Tiny_Image( $this->settings, $id, $metadata );
561                $result     = $tiny_image->compress();
562
563                // The wp_update_attachment_metadata call is thrown because the
564                // dimensions of the original image can change. This will then
565                // trigger other plugins and can result in unexpected behaviour and
566                // further changes to the image. This may require another approach.
567                // Note that as of WP 5.3 it is advised to not hook into this filter
568                // anymore, so other plugins are less likely to be triggered.
569                wp_update_attachment_metadata( $id, $tiny_image->get_wp_metadata() );
570
571                echo $this->render_compress_details( $tiny_image );
572
573                exit();
574        }
575
576        public function compress_image_for_bulk() {
577                $response = $this->validate_ajax_attachment_request();
578                if ( isset( $response['error'] ) ) {
579                        echo json_encode( $response );
580                        exit();
581                }
582
583                list($id, $metadata)     = $response['data'];
584                $tiny_image_before       = new Tiny_Image( $this->settings, $id, $metadata );
585                $image_statistics_before = $tiny_image_before->get_statistics(
586                        $this->settings->get_sizes(),
587                        $this->settings->get_active_tinify_sizes()
588                );
589                $size_before             = $image_statistics_before['compressed_total_size'];
590
591                $tiny_image = new Tiny_Image( $this->settings, $id, $metadata );
592
593                Tiny_Logger::debug(
594                        'compress from bulk',
595                        array(
596                                'image_id' => $id,
597                        )
598                );
599
600                $result           = $tiny_image->compress();
601                $image_statistics = $tiny_image->get_statistics(
602                        $this->settings->get_sizes(),
603                        $this->settings->get_active_tinify_sizes()
604                );
605                wp_update_attachment_metadata( $id, $tiny_image->get_wp_metadata() );
606
607                $current_library_size = intval( $_POST['current_size'] );
608                $size_after           = $image_statistics['compressed_total_size'];
609                $new_library_size     = $current_library_size + $size_after - $size_before;
610
611                $result['message']                = $tiny_image->get_latest_error();
612                $result['image_sizes_compressed'] = $image_statistics['image_sizes_compressed'];
613                $result['image_sizes_converted']  = $image_statistics['image_sizes_converted'];
614                $result['image_sizes_optimized']  = $image_statistics['image_sizes_compressed'];
615
616                $result['initial_total_size'] = size_format(
617                        $image_statistics['initial_total_size'],
618                        1
619                );
620
621                $result['optimized_total_size'] = size_format(
622                        $image_statistics['compressed_total_size'],
623                        1
624                );
625
626                $result['savings']                     = $tiny_image->get_savings( $image_statistics );
627                $result['status']                      = $this->settings->get_status();
628                $result['thumbnail']                   = wp_get_attachment_image(
629                        $id,
630                        array( '30', '30' ),
631                        true,
632                        array(
633                                'class' => 'pinkynail',
634                                'alt'   => '',
635                        )
636                );
637                $result['size_change']                 = $size_after - $size_before;
638                $result['human_readable_library_size'] = size_format( $new_library_size, 2 );
639
640                echo json_encode( $result );
641
642                exit();
643        }
644
645        public function ajax_optimization_statistics() {
646                if ( $this->check_ajax_referer() && current_user_can( 'upload_files' ) ) {
647                        $stats = Tiny_Bulk_Optimization::get_optimization_statistics( $this->settings );
648                        echo json_encode( $stats );
649                }
650                exit();
651        }
652
653        public function ajax_compression_status() {
654                $response = $this->validate_ajax_attachment_request();
655
656                if ( isset( $response['error'] ) ) {
657                        echo $response['error'];
658                        exit();
659                }
660                list($id, $metadata) = $response['data'];
661
662                $tiny_image = new Tiny_Image( $this->settings, $id, $metadata );
663
664                echo $this->render_compress_details( $tiny_image );
665
666                exit();
667        }
668
669        public function media_library_bulk_action() {
670                $valid_actions = array( 'tiny_bulk_action', 'tiny_bulk_mark_compressed' );
671                $action        = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
672                $action2       = isset( $_REQUEST['action2'] ) ? $_REQUEST['action2'] : '';
673
674                if (
675                        ! in_array( $action, $valid_actions, true ) &&
676                        ! in_array( $action2, $valid_actions, true )
677                ) {
678                        return;
679                }
680                if ( empty( $_REQUEST['media'] ) || ( ! $_REQUEST['media'] ) ) {
681                        $_REQUEST['action'] = '';
682                        return;
683                }
684                check_admin_referer( 'bulk-media' );
685                $ids      = implode( '-', array_map( 'intval', $_REQUEST['media'] ) );
686                $location = 'upload.php?mode=list&ids=' . $ids;
687
688                $location = add_query_arg( 'action', $_REQUEST['action'], $location );
689
690                if ( ! empty( $_REQUEST['paged'] ) ) {
691                        $location = add_query_arg( 'paged', absint( $_REQUEST['paged'] ), $location );
692                }
693                if ( ! empty( $_REQUEST['s'] ) ) {
694                        $location = add_query_arg( 's', $_REQUEST['s'], $location );
695                }
696                if ( ! empty( $_REQUEST['m'] ) ) {
697                        $location = add_query_arg( 'm', $_REQUEST['m'], $location );
698                }
699
700                wp_redirect( admin_url( $location ) );
701                exit();
702        }
703
704        public function add_media_columns( $columns ) {
705                $columns[ self::MEDIA_COLUMN ] = esc_html__( 'Compression', 'tiny-compress-images' );
706                return $columns;
707        }
708
709        public function render_media_column( $column, $id ) {
710                if ( self::MEDIA_COLUMN === $column ) {
711                        $tiny_image = new Tiny_Image( $this->settings, $id );
712                        if ( $tiny_image->file_type_allowed() ) {
713                                echo '<div class="tiny-ajax-container">';
714                                $this->render_compress_details( $tiny_image );
715                                echo '</div>';
716                        }
717                }
718        }
719
720        public function show_media_info() {
721                global $post;
722                $tiny_image = new Tiny_Image( $this->settings, $post->ID );
723                if ( $tiny_image->file_type_allowed() ) {
724                        echo '<div class="misc-pub-section tiny-compress-images">';
725                        echo '<h4>';
726                        esc_html_e( 'JPEG, PNG, & WebP optimization', 'tiny-compress-images' );
727                        echo '</h4>';
728                        echo '<div class="tiny-ajax-container">';
729                        $this->render_compress_details( $tiny_image );
730                        echo '</div>';
731                        echo '</div>';
732                }
733        }
734
735        private function render_compress_details( $tiny_image ) {
736                $in_progress = $tiny_image->filter_image_sizes( 'in_progress' );
737                if ( count( $in_progress ) > 0 ) {
738                        include __DIR__ . '/views/compress-details-processing.php';
739                } else {
740                        include __DIR__ . '/views/compress-details.php';
741                }
742        }
743
744        public function get_estimated_bulk_cost( $estimated_credit_use ) {
745                return Tiny_Compress::estimate_cost(
746                        $estimated_credit_use,
747                        $this->settings->get_compression_count()
748                );
749        }
750
751        public function render_bulk_optimization_page() {
752                $stats = Tiny_Bulk_Optimization::get_optimization_statistics( $this->settings );
753
754                $estimated_costs = $this->get_estimated_bulk_cost( $stats['estimated_credit_use'] );
755                $admin_colors    = self::retrieve_admin_colors();
756
757                /* This makes sure that up to date information is retrieved from the API. */
758                $this->settings->get_compressor()->get_status();
759
760                $active_tinify_sizes = $this->settings->get_active_tinify_sizes();
761                $remaining_credits   = $this->settings->get_remaining_credits();
762                $is_on_free_plan     = $this->settings->is_on_free_plan();
763                $email_address       = $this->settings->get_email_address();
764
765                include __DIR__ . '/views/bulk-optimization.php';
766        }
767
768        public function add_dashboard_widget() {
769                wp_enqueue_style(
770                        self::NAME . '_chart',
771                        plugins_url( '/css/optimization-chart.css', __FILE__ ),
772                        array(),
773                        self::version()
774                );
775
776                wp_enqueue_style(
777                        self::NAME . '_dashboard_widget',
778                        plugins_url( '/css/dashboard-widget.css', __FILE__ ),
779                        array(),
780                        self::version()
781                );
782
783                wp_register_script(
784                        self::NAME . '_dashboard_widget',
785                        plugins_url( '/js/dashboard-widget.js', __FILE__ ),
786                        array(),
787                        self::version(),
788                        true
789                );
790
791                /* This might be deduplicated with the admin script localization, but
792                        the order of including scripts is sometimes different. So in that
793                        case we need to make sure that the order of inclusion is correc.t */
794                wp_localize_script(
795                        self::NAME . '_dashboard_widget',
796                        'tinyCompressDashboard',
797                        array(
798                                'nonce' => wp_create_nonce( 'tiny-compress' ),
799                        )
800                );
801
802                wp_enqueue_script( self::NAME . '_dashboard_widget' );
803
804                wp_add_dashboard_widget(
805                        $this->get_prefixed_name( 'dashboard_widget' ),
806                        esc_html__( 'TinyPNG - JPEG, PNG & WebP image compression', 'tiny-compress-images' ),
807                        $this->get_method( 'add_widget_view' )
808                );
809        }
810
811        public function add_widget_view() {
812                $admin_colors = self::retrieve_admin_colors();
813                include __DIR__ . '/views/dashboard-widget.php';
814        }
815
816        private static function retrieve_admin_colors() {
817                global $_wp_admin_css_colors;
818                $admin_colour_scheme = get_user_option( 'admin_color', get_current_user_id() );
819                $admin_colors        = array( '#0074aa', '#1685b5', '#78ca44', '#0086ba' ); // default
820                if ( isset( $_wp_admin_css_colors[ $admin_colour_scheme ] ) ) {
821                        if ( isset( $_wp_admin_css_colors[ $admin_colour_scheme ]->colors ) ) {
822                                $admin_colors = $_wp_admin_css_colors[ $admin_colour_scheme ]->colors;
823                        }
824                }
825                if ( '#e5e5e5' == $admin_colors[0] && '#999' == $admin_colors[1] ) {
826                        $admin_colors[0] = '#bbb';
827                }
828                if ( '#5589aa' == $admin_colors[0] && '#cfdfe9' == $admin_colors[1] ) {
829                        $admin_colors[1] = '#85aec5';
830                }
831                if ( '#7c7976' == $admin_colors[0] && '#c6c6c6' == $admin_colors[1] ) {
832                        $admin_colors[1] = '#adaba9';
833                        $admin_colors[2] = '#adaba9';
834                }
835                if ( self::wp_version() > 3.7 ) {
836                        if ( 'fresh' == $admin_colour_scheme ) {
837                                $admin_colors = array( '#0074aa', '#1685b5', '#78ca44', '#0086ba' ); // better
838                        }
839                }
840                return $admin_colors;
841        }
842
843        public function friendly_user_name() {
844                $user = wp_get_current_user();
845                $name = ucfirst( empty( $user->first_name ) ? $user->display_name : $user->first_name );
846                return $name;
847        }
848
849        /**
850         * Will clean up converted files (if any) when the original is deleted
851         *
852         * Hooked to the `delete_attachment` action.
853         * @see https://developer.wordpress.org/reference/hooks/deleted_post/
854         *
855         * @param [int] $post_id
856         *
857         * @return void
858         */
859        public function clean_attachment( $post_id ) {
860                $tiny_image = new Tiny_Image( $this->settings, $post_id );
861                $tiny_image->delete_converted_image();
862        }
863
864        public static function request_review() {
865                $review_url    =
866                        'https://wordpress.org/support/plugin/tiny-compress-images/reviews/#new-post';
867                $review_block  = esc_html__( 'Enjoying TinyPNG?', 'tiny-compress-images' );
868                $review_block .= ' ';
869                $review_block .= sprintf(
870                        '<a href="%s" target="_blank">%s</a>',
871                        esc_url( $review_url ),
872                        esc_html__( 'Write a review', 'tiny-compress-images' )
873                );
874                return $review_block;
875        }
876
877        public function mark_image_as_compressed() {
878                $response = $this->validate_ajax_attachment_request();
879                if ( isset( $response['error'] ) ) {
880                        echo $response['error'];
881                        exit();
882                }
883
884                list($id, $metadata) = $response['data'];
885                $tiny_image          = new Tiny_Image( $this->settings, $id, $metadata );
886                $tiny_image->mark_as_compressed();
887
888                echo $this->render_compress_details( $tiny_image );
889
890                exit();
891        }
892}
Note: See TracBrowser for help on using the repository browser.