PluginProbe ʕ •ᴥ•ʔ
TinyPNG – JPEG, PNG & WebP image compression / 2.2.1
TinyPNG – JPEG, PNG & WebP image compression v2.2.1
3.7.0 3.6.14 trunk 1.0.0 1.1.0 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.4.0 1.5.0 1.6.0 1.7.0 1.7.1 1.7.2 2.0.0 2.0.1 2.0.2 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.0.0 3.0.1 3.1.0 3.2.0 3.2.1 3.3 3.4 3.4.1 3.4.2 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.5.2 3.6.0 3.6.1 3.6.10 3.6.11 3.6.12 3.6.13 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9
tiny-compress-images / src / class-tiny-plugin.php
tiny-compress-images / src Last commit date
config 10 years ago css 9 years ago data 10 years ago images 9 years ago js 9 years ago vendor 9 years ago views 9 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 9 years ago class-tiny-notices.php 9 years ago class-tiny-php.php 9 years ago class-tiny-plugin.php 9 years ago class-tiny-settings.php 9 years ago class-tiny-wp-base.php 9 years ago
class-tiny-plugin.php
526 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_Plugin extends Tiny_WP_Base {
21 const VERSION = '2.2.1';
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
43 $this->settings = new Tiny_Settings();
44 }
45
46 public function set_compressor( $compressor ) {
47 $this->settings->set_compressor( $compressor );
48 }
49
50 public function init() {
51 add_filter( 'jpeg_quality',
52 $this->get_static_method( 'jpeg_quality' )
53 );
54
55 add_filter( 'wp_editor_set_quality',
56 $this->get_static_method( 'jpeg_quality' )
57 );
58
59 add_filter( 'wp_generate_attachment_metadata',
60 $this->get_method( 'compress_on_upload' ),
61 10, 2
62 );
63
64 load_plugin_textdomain( self::NAME, false,
65 dirname( plugin_basename( __FILE__ ) ) . '/languages'
66 );
67 }
68
69 public function admin_init() {
70 add_action('wp_dashboard_setup',
71 $this->get_method( 'add_dashboard_widget' )
72 );
73
74 add_action( 'admin_enqueue_scripts',
75 $this->get_method( 'enqueue_scripts' )
76 );
77
78 add_action( 'admin_action_tiny_bulk_action',
79 $this->get_method( 'media_library_bulk_action' )
80 );
81
82 add_action( 'admin_action_-1',
83 $this->get_method( 'media_library_bulk_action' )
84 );
85
86 add_filter( 'manage_media_columns',
87 $this->get_method( 'add_media_columns' )
88 );
89
90 add_action( 'manage_media_custom_column',
91 $this->get_method( 'render_media_column' ),
92 10, 2
93 );
94
95 add_action( 'attachment_submitbox_misc_actions',
96 $this->get_method( 'show_media_info' )
97 );
98
99 add_action( 'wp_ajax_tiny_compress_image_from_library',
100 $this->get_method( 'compress_image_from_library' )
101 );
102
103 add_action( 'wp_ajax_tiny_compress_image_for_bulk',
104 $this->get_method( 'compress_image_for_bulk' )
105 );
106
107 add_action( 'wp_ajax_tiny_get_optimization_statistics',
108 $this->get_method( 'ajax_optimization_statistics' )
109 );
110
111 $plugin = plugin_basename(
112 dirname( dirname( __FILE__ ) ) . '/tiny-compress-images.php'
113 );
114
115 add_filter( "plugin_action_links_$plugin",
116 $this->get_method( 'add_plugin_links' )
117 );
118
119 add_action( 'wr2x_retina_file_added',
120 $this->get_method( 'compress_retina_image' ),
121 10, 3
122 );
123
124 add_action( 'wr2x_retina_file_removed',
125 $this->get_method( 'remove_retina_image' ),
126 10, 2
127 );
128
129 add_thickbox();
130 }
131
132 public function admin_menu() {
133 add_media_page(
134 __( 'Bulk Optimization', 'tiny-compress-images' ),
135 esc_html__( 'Bulk Optimization', 'tiny-compress-images' ),
136 'upload_files',
137 'tiny-bulk-optimization',
138 $this->get_method( 'render_bulk_optimization_page' )
139 );
140 }
141
142 public function add_plugin_links( $current_links ) {
143 $additional = array(
144 'settings' => sprintf(
145 '<a href="options-media.php#%s">%s</a>',
146 self::NAME,
147 esc_html__( 'Settings', 'tiny-compress-images' )
148 ),
149 'bulk' => sprintf(
150 '<a href="upload.php?page=tiny-bulk-optimization">%s</a>',
151 esc_html__( 'Bulk Optimization', 'tiny-compress-images' )
152 ),
153 );
154 return array_merge( $additional, $current_links );
155 }
156
157 public function compress_retina_image( $attachment_id, $path, $size_name ) {
158 if ( $this->settings->compress_wr2x_images() ) {
159 $tiny_image = new Tiny_Image( $this->settings, $attachment_id );
160 $tiny_image->compress_retina( $size_name . '_wr2x', $path );
161 }
162 }
163
164 public function remove_retina_image( $attachment_id, $path ) {
165 $tiny_image = new Tiny_Image( $this->settings, $attachment_id );
166 $tiny_image->remove_retina_metadata();
167 }
168
169 public function enqueue_scripts( $hook ) {
170 wp_enqueue_style( self::NAME . '_admin',
171 plugins_url( '/css/admin.css', __FILE__ ),
172 array(), self::version()
173 );
174
175 wp_enqueue_style( self::NAME . '_chart',
176 plugins_url( '/css/chart.css', __FILE__ ),
177 array(), self::version()
178 );
179
180 wp_register_script( self::NAME . '_admin',
181 plugins_url( '/js/admin.js', __FILE__ ),
182 array(), self::version(), true
183 );
184
185 // WordPress < 3.3 does not handle multidimensional arrays
186 wp_localize_script( self::NAME . '_admin', 'tinyCompress', array(
187 'nonce' => wp_create_nonce( 'tiny-compress' ),
188 'wpVersion' => self::wp_version(),
189 'pluginVersion' => self::version(),
190 'L10nAllDone' => __( 'All images are processed', 'tiny-compress-images' ),
191 'L10nNoActionTaken' => __( 'No action taken', 'tiny-compress-images' ),
192 'L10nBulkAction' => __( 'Compress Images', 'tiny-compress-images' ),
193 'L10nCancelled' => __( 'Cancelled', 'tiny-compress-images' ),
194 'L10nCompressing' => __( 'Compressing', 'tiny-compress-images' ),
195 'L10nCompressed' => __( 'compressed', 'tiny-compress-images' ),
196 'L10nFile' => __( 'File', 'tiny-compress-images' ),
197 'L10nSizesOptimized' => __( 'Sizes optimized', 'tiny-compress-images' ),
198 'L10nInitialSize' => __( 'Initial size', 'tiny-compress-images' ),
199 'L10nCurrentSize' => __( 'Current size', 'tiny-compress-images' ),
200 'L10nSavings' => __( 'Savings', 'tiny-compress-images' ),
201 'L10nStatus' => __( 'Status', 'tiny-compress-images' ),
202 'L10nShowMoreDetails' => __( 'Show more details', 'tiny-compress-images' ),
203 'L10nError' => __( 'Error', 'tiny-compress-images' ),
204 'L10nLatestError' => __( 'Latest error', 'tiny-compress-images' ),
205 'L10nInternalError' => __( 'Internal error', 'tiny-compress-images' ),
206 'L10nOutOf' => __( 'out of', 'tiny-compress-images' ),
207 'L10nWaiting' => __( 'Waiting', 'tiny-compress-images' ),
208 ));
209
210 wp_enqueue_script( self::NAME . '_admin' );
211
212 if ( 'media_page_tiny-bulk-optimization' == $hook ) {
213 wp_enqueue_style(
214 self::NAME . '_tiny_bulk_optimization',
215 plugins_url( '/css/bulk-optimization.css', __FILE__ ),
216 array(), self::version()
217 );
218
219 wp_enqueue_style( self::NAME . '_chart',
220 plugins_url( '/css/chart.css', __FILE__ ),
221 array(), self::version()
222 );
223
224 wp_register_script(
225 self::NAME . '_tiny_bulk_optimization',
226 plugins_url( '/js/bulk-optimization.js', __FILE__ ),
227 array(), self::version(), true
228 );
229
230 wp_enqueue_script( self::NAME . '_tiny_bulk_optimization' );
231 }
232
233 }
234
235 public function compress_on_upload( $metadata, $attachment_id ) {
236 if ( ! empty( $metadata ) ) {
237 $tiny_image = new Tiny_Image( $this->settings, $attachment_id, $metadata );
238 $result = $tiny_image->compress( $this->settings );
239 return $tiny_image->get_wp_metadata();
240 } else {
241 return $metadata;
242 }
243 }
244
245 public function compress_image_from_library() {
246 if ( ! $this->check_ajax_referer() ) {
247 exit();
248 }
249 if ( ! current_user_can( 'upload_files' ) ) {
250 $message = esc_html__(
251 "You don't have permission to upload files.",
252 'tiny-compress-images'
253 );
254 echo $message;
255 exit();
256 }
257 if ( empty( $_POST['id'] ) ) {
258 $message = esc_html__(
259 'Not a valid media file.',
260 'tiny-compress-images'
261 );
262 echo $message;
263 exit();
264 }
265 $id = intval( $_POST['id'] );
266 $metadata = wp_get_attachment_metadata( $id );
267 if ( ! is_array( $metadata ) ) {
268 $message = esc_html__(
269 'Could not find metadata of media file.',
270 'tiny-compress-images'
271 );
272 echo $message;
273 exit;
274 }
275
276 $tiny_image = new Tiny_Image( $this->settings, $id, $metadata );
277 $result = $tiny_image->compress( $this->settings );
278
279 // The wp_update_attachment_metadata call is thrown because the
280 // dimensions of the original image can change. This will then
281 // trigger other plugins and can result in unexpected behaviour and
282 // further changes to the image. This may require another approach.
283 wp_update_attachment_metadata( $id, $tiny_image->get_wp_metadata() );
284
285 echo $this->render_compress_details( $tiny_image );
286
287 exit();
288 }
289
290 public function compress_image_for_bulk() {
291 if ( ! $this->check_ajax_referer() ) {
292 exit();
293 }
294 if ( ! current_user_can( 'upload_files' ) ) {
295 $message = esc_html__(
296 "You don't have permission to upload files.",
297 'tiny-compress-images'
298 );
299 echo json_encode( array( 'error' => $message ) );
300 exit();
301 }
302 if ( empty( $_POST['id'] ) ) {
303 $message = esc_html__(
304 'Not a valid media file.',
305 'tiny-compress-images'
306 );
307 echo json_encode( array( 'error' => $message ) );
308 exit();
309 }
310 $id = intval( $_POST['id'] );
311 $metadata = wp_get_attachment_metadata( $id );
312 if ( ! is_array( $metadata ) ) {
313 $message = esc_html__(
314 'Could not find metadata of media file.',
315 'tiny-compress-images'
316 );
317 echo json_encode( array( 'error' => $message ) );
318 exit;
319 }
320
321 $tiny_image_before = new Tiny_Image( $this->settings, $id, $metadata );
322 $image_statistics_before = $tiny_image_before->get_statistics();
323 $size_before = $image_statistics_before['optimized_total_size'];
324
325 $tiny_image = new Tiny_Image( $this->settings, $id, $metadata );
326 $result = $tiny_image->compress( $this->settings );
327 $image_statistics = $tiny_image->get_statistics();
328 wp_update_attachment_metadata( $id, $tiny_image->get_wp_metadata() );
329
330 $current_library_size = intval( $_POST['current_size'] );
331 $size_after = $image_statistics['optimized_total_size'];
332 $new_library_size = $current_library_size + $size_after - $size_before;
333
334 $result['message'] = $tiny_image->get_latest_error();
335 $result['image_sizes_optimized'] = $image_statistics['image_sizes_optimized'];
336
337 $result['initial_total_size'] = size_format(
338 $image_statistics['initial_total_size'], 1
339 );
340
341 $result['optimized_total_size'] = size_format(
342 $image_statistics['optimized_total_size'], 1
343 );
344
345 $result['savings'] = $tiny_image->get_savings( $image_statistics );
346 $result['status'] = $this->settings->get_status();
347 $result['thumbnail'] = wp_get_attachment_image(
348 $id, array( '30', '30' ), true, array(
349 'class' => 'pinkynail',
350 'alt' => '',
351 )
352 );
353 $result['size_change'] = $size_after - $size_before;
354 $result['human_readable_library_size'] = size_format( $new_library_size, 2 );
355
356 echo json_encode( $result );
357
358 exit();
359 }
360
361 public function ajax_optimization_statistics() {
362 if ( ! $this->check_ajax_referer() ) {
363 exit();
364 }
365 $stats = Tiny_Image::get_optimization_statistics( $this->settings );
366 echo json_encode( $stats );
367 exit();
368 }
369
370 public function media_library_bulk_action() {
371
372 if ( empty( $_REQUEST['action'] ) || (
373 'tiny_bulk_action' != $_REQUEST['action'] &&
374 'tiny_bulk_action' != $_REQUEST['action2'] ) ) {
375 return;
376 }
377
378 if ( empty( $_REQUEST['media'] ) || ( ! $_REQUEST['media'] ) ) {
379 return;
380 }
381
382 check_admin_referer( 'bulk-media' );
383 $ids = implode( '-', array_map( 'intval', $_REQUEST['media'] ) );
384 wp_redirect(add_query_arg(
385 '_wpnonce',
386 wp_create_nonce( 'tiny-bulk-optimization' ),
387 admin_url( "upload.php?page=tiny-bulk-optimization&ids=$ids" )
388 ));
389 exit();
390 }
391
392 public function add_media_columns( $columns ) {
393 $columns[ self::MEDIA_COLUMN ] = esc_html__( 'Compression', 'tiny-compress-images' );
394 return $columns;
395 }
396
397 public function render_media_column( $column, $id ) {
398 if ( self::MEDIA_COLUMN === $column ) {
399 $tiny_image = new Tiny_Image( $this->settings, $id );
400 if ( $tiny_image->file_type_allowed() ) {
401 echo '<div class="tiny-ajax-container">';
402 $this->render_compress_details( $tiny_image );
403 echo '</div>';
404 }
405 }
406 }
407
408 public function show_media_info() {
409 global $post;
410 $tiny_image = new Tiny_Image( $this->settings, $post->ID );
411 if ( $tiny_image->file_type_allowed() ) {
412 echo '<div class="misc-pub-section tiny-compress-images">';
413 echo '<h4>';
414 esc_html_e( 'JPEG and PNG optimization', 'tiny-compress-images' );
415 echo '</h4>';
416 echo '<div class="tiny-ajax-container">';
417 $this->render_compress_details( $tiny_image );
418 echo '</div>';
419 echo '</div>';
420 }
421 }
422
423 private function render_compress_details( $tiny_image ) {
424 $in_progress = $tiny_image->filter_image_sizes( 'in_progress' );
425 if ( count( $in_progress ) > 0 ) {
426 include( dirname( __FILE__ ) . '/views/compress-details-processing.php' );
427 } else {
428 include( dirname( __FILE__ ) . '/views/compress-details.php' );
429 }
430 }
431
432 public function render_bulk_optimization_page() {
433 $stats = Tiny_Image::get_optimization_statistics( $this->settings );
434 $estimated_costs = Tiny_Compress::estimate_cost(
435 $stats['available-unoptimised-sizes'],
436 $this->settings->get_compression_count()
437 );
438 $admin_colors = self::retrieve_admin_colors();
439
440 $active_tinify_sizes = $this->settings->get_active_tinify_sizes();
441
442 $auto_start_bulk = isset( $_REQUEST['ids'] );
443
444 include( dirname( __FILE__ ) . '/views/bulk-optimization.php' );
445 }
446
447 public function add_dashboard_widget() {
448 wp_enqueue_style( self::NAME . '_chart',
449 plugins_url( '/css/chart.css', __FILE__ ),
450 array(), self::version()
451 );
452
453 wp_enqueue_style( self::NAME . '_dashboard_widget',
454 plugins_url( '/css/dashboard-widget.css', __FILE__ ),
455 array(), self::version()
456 );
457
458 wp_register_script( self::NAME . '_dashboard_widget',
459 plugins_url( '/js/dashboard-widget.js', __FILE__ ),
460 array(), self::version(), true
461 );
462
463 wp_enqueue_script( self::NAME . '_dashboard_widget' );
464
465 wp_add_dashboard_widget(
466 $this->get_prefixed_name( 'dashboard_widget' ),
467 esc_html__( 'Compress JPEG & PNG images', 'tiny-compress-images' ),
468 $this->get_method( 'add_widget_view' )
469 );
470 }
471
472 function add_widget_view() {
473 $admin_colors = self::retrieve_admin_colors();
474 include( dirname( __FILE__ ) . '/views/dashboard-widget.php' );
475 }
476
477 private static function retrieve_admin_colors() {
478 global $_wp_admin_css_colors;
479 $admin_colour_scheme = get_user_option( 'admin_color', get_current_user_id() );
480 $admin_colors = array( '#0074aa', '#1685b5', '#78ca44', '#0086ba' ); // default
481 if ( isset( $_wp_admin_css_colors[ $admin_colour_scheme ] ) ) {
482 if ( isset( $_wp_admin_css_colors[ $admin_colour_scheme ]->colors ) ) {
483 $admin_colors = $_wp_admin_css_colors[ $admin_colour_scheme ]->colors;
484 }
485 }
486 if ( '#e5e5e5' == $admin_colors[0] && '#999' == $admin_colors[1] ) {
487 $admin_colors[0] = '#bbb';
488 }
489 if ( '#5589aa' == $admin_colors[0] && '#cfdfe9' == $admin_colors[1] ) {
490 $admin_colors[1] = '#85aec5';
491 }
492 if ( '#7c7976' == $admin_colors[0] && '#c6c6c6' == $admin_colors[1] ) {
493 $admin_colors[1] = '#adaba9';
494 $admin_colors[2] = '#adaba9';
495 }
496 if ( self::wp_version() > 3.7 ) {
497 if ( 'fresh' == $admin_colour_scheme ) {
498 $admin_colors = array( '#0074aa', '#1685b5', '#78ca44', '#0086ba' ); // better
499 }
500 }
501 return $admin_colors;
502 }
503
504 function friendly_user_name() {
505 $user = wp_get_current_user();
506 $name = ucfirst( empty( $user->first_name ) ? $user->display_name : $user->first_name );
507 return $name;
508 }
509
510 private function get_ids_to_compress() {
511 if ( empty( $_REQUEST['ids'] ) ) {
512 return array();
513 }
514
515 $ids = implode( ',', array_map( 'intval', explode( '-', $_REQUEST['ids'] ) ) );
516 $condition = "AND ID IN($ids)";
517
518 global $wpdb;
519 return $wpdb->get_results(
520 "SELECT ID, post_title FROM $wpdb->posts
521 WHERE post_type = 'attachment' $condition
522 AND (post_mime_type = 'image/jpeg' OR post_mime_type = 'image/png')
523 ORDER BY ID DESC", ARRAY_A);
524 }
525 }
526