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