PluginProbe ʕ •ᴥ•ʔ
TinyPNG – JPEG, PNG & WebP image compression / 2.0.2
TinyPNG – JPEG, PNG & WebP image compression v2.0.2
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
455 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.0.2';
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_thickbox();
117 }
118
119 public function admin_menu() {
120 add_media_page(
121 __( 'Bulk Optimization', 'tiny-compress-images' ),
122 esc_html__( 'Bulk Optimization', 'tiny-compress-images' ),
123 'upload_files',
124 'tiny-bulk-optimization',
125 $this->get_method( 'render_bulk_optimization_page' )
126 );
127 }
128
129 public function add_plugin_links( $current_links ) {
130 $additional = array(
131 'settings' => sprintf(
132 '<a href="options-media.php#%s">%s</a>',
133 self::NAME,
134 esc_html__( 'Settings', 'tiny-compress-images' )
135 ),
136 'bulk' => sprintf(
137 '<a href="upload.php?page=tiny-bulk-optimization">%s</a>',
138 esc_html__( 'Bulk Optimization', 'tiny-compress-images' )
139 ),
140 );
141 return array_merge( $additional, $current_links );
142 }
143
144 public function enqueue_scripts( $hook ) {
145 wp_enqueue_style( self::NAME .'_admin',
146 plugins_url( '/css/admin.css', __FILE__ ),
147 array(), self::version()
148 );
149
150 wp_register_script( self::NAME .'_admin',
151 plugins_url( '/js/admin.js', __FILE__ ),
152 array(), self::version(), true
153 );
154
155 // WordPress < 3.3 does not handle multidimensional arrays
156 wp_localize_script( self::NAME .'_admin', 'tinyCompress', array(
157 'nonce' => wp_create_nonce( 'tiny-compress' ),
158 'wpVersion' => self::wp_version(),
159 'pluginVersion' => self::version(),
160 'L10nAllDone' => __( 'All images are processed', 'tiny-compress-images' ),
161 'L10nNoActionTaken' => __( 'No action taken', 'tiny-compress-images' ),
162 'L10nBulkAction' => __( 'Compress Images', 'tiny-compress-images' ),
163 'L10nCancelled' => __( 'Cancelled', 'tiny-compress-images' ),
164 'L10nCompressing' => __( 'Compressing', 'tiny-compress-images' ),
165 'L10nCompressed' => __( 'compressed', 'tiny-compress-images' ),
166 'L10nFile' => __( 'File', 'tiny-compress-images' ),
167 'L10nSizesOptimized' => __( 'Sizes optimized', 'tiny-compress-images' ),
168 'L10nInitialSize' => __( 'Initial size', 'tiny-compress-images' ),
169 'L10nCurrentSize' => __( 'Current size', 'tiny-compress-images' ),
170 'L10nSavings' => __( 'Savings', 'tiny-compress-images' ),
171 'L10nStatus' => __( 'Status', 'tiny-compress-images' ),
172 'L10nShowMoreDetails' => __( 'Show more details', 'tiny-compress-images' ),
173 'L10nError' => __( 'Error', 'tiny-compress-images' ),
174 'L10nLatestError' => __( 'Latest error', 'tiny-compress-images' ),
175 'L10nInternalError' => __( 'Internal error', 'tiny-compress-images' ),
176 'L10nOutOf' => __( 'out of', 'tiny-compress-images' ),
177 'L10nWaiting' => __( 'Waiting', 'tiny-compress-images' ),
178 ));
179
180 wp_enqueue_script( self::NAME .'_admin' );
181
182 if ( 'media_page_tiny-bulk-optimization' == $hook ) {
183 wp_enqueue_style(
184 self::NAME . '_tiny_bulk_optimization',
185 plugins_url( '/css/bulk-optimization.css', __FILE__ ),
186 array(), self::version()
187 );
188
189 wp_register_script(
190 self::NAME . '_tiny_bulk_optimization',
191 plugins_url( '/js/bulk-optimization.js', __FILE__ ),
192 array(), self::version(), true
193 );
194
195 wp_enqueue_script( self::NAME .'_tiny_bulk_optimization' );
196 }
197
198 }
199
200 public function compress_on_upload( $metadata, $attachment_id ) {
201 if ( ! empty( $metadata ) ) {
202 $tiny_image = new Tiny_Image( $this->settings, $attachment_id, $metadata );
203 $result = $tiny_image->compress( $this->settings );
204 return $tiny_image->get_wp_metadata();
205 } else {
206 return $metadata;
207 }
208 }
209
210 public function compress_image_from_library() {
211 if ( ! $this->check_ajax_referer() ) {
212 exit();
213 }
214 if ( ! current_user_can( 'upload_files' ) ) {
215 $message = esc_html__(
216 "You don't have permission to upload files.",
217 'tiny-compress-images'
218 );
219 echo $message;
220 exit();
221 }
222 if ( empty( $_POST['id'] ) ) {
223 $message = esc_html__(
224 'Not a valid media file.',
225 'tiny-compress-images'
226 );
227 echo $message;
228 exit();
229 }
230 $id = intval( $_POST['id'] );
231 $metadata = wp_get_attachment_metadata( $id );
232 if ( ! is_array( $metadata ) ) {
233 $message = esc_html__(
234 'Could not find metadata of media file.',
235 'tiny-compress-images'
236 );
237 echo $message;
238 exit;
239 }
240
241 $tiny_image = new Tiny_Image( $this->settings, $id, $metadata );
242 $result = $tiny_image->compress( $this->settings );
243
244 // The wp_update_attachment_metadata call is thrown because the
245 // dimensions of the original image can change. This will then
246 // trigger other plugins and can result in unexpected behaviour and
247 // further changes to the image. This may require another approach.
248 wp_update_attachment_metadata( $id, $tiny_image->get_wp_metadata() );
249
250 echo $this->render_compress_details( $tiny_image );
251
252 exit();
253 }
254
255 public function compress_image_for_bulk() {
256 if ( ! $this->check_ajax_referer() ) {
257 exit();
258 }
259 if ( ! current_user_can( 'upload_files' ) ) {
260 $message = esc_html__(
261 "You don't have permission to upload files.",
262 'tiny-compress-images'
263 );
264 echo json_encode( array( 'error' => $message ) );
265 exit();
266 }
267 if ( empty( $_POST['id'] ) ) {
268 $message = esc_html__(
269 'Not a valid media file.',
270 'tiny-compress-images'
271 );
272 echo json_encode( array( 'error' => $message ) );
273 exit();
274 }
275 $id = intval( $_POST['id'] );
276 $metadata = wp_get_attachment_metadata( $id );
277 if ( ! is_array( $metadata ) ) {
278 $message = esc_html__(
279 'Could not find metadata of media file.',
280 'tiny-compress-images'
281 );
282 echo json_encode( array( 'error' => $message ) );
283 exit;
284 }
285
286 $tiny_image_before = new Tiny_Image( $this->settings, $id, $metadata );
287 $image_statistics_before = $tiny_image_before->get_statistics();
288 $size_before = $image_statistics_before['optimized_total_size'];
289
290 $tiny_image = new Tiny_Image( $this->settings, $id, $metadata );
291 $result = $tiny_image->compress( $this->settings );
292 $image_statistics = $tiny_image->get_statistics();
293 wp_update_attachment_metadata( $id, $tiny_image->get_wp_metadata() );
294
295 $current_library_size = intval( $_POST['current_size'] );
296 $size_after = $image_statistics['optimized_total_size'];
297 $new_library_size = $current_library_size + $size_after - $size_before;
298
299 $result['message'] = $tiny_image->get_latest_error();
300 $result['image_sizes_optimized'] = $image_statistics['image_sizes_optimized'];
301
302 $result['initial_total_size'] = size_format(
303 $image_statistics['initial_total_size'], 1
304 );
305
306 $result['optimized_total_size'] = size_format(
307 $image_statistics['optimized_total_size'], 1
308 );
309
310 $result['savings'] = $tiny_image->get_savings( $image_statistics );
311 $result['status'] = $this->settings->get_status();
312 $result['thumbnail'] = wp_get_attachment_image(
313 $id, array( '30', '30' ), true, array(
314 'class' => 'pinkynail',
315 'alt' => '',
316 )
317 );
318 $result['size_change'] = $size_after - $size_before;
319 $result['human_readable_library_size'] = size_format( $new_library_size, 2 );
320
321 echo json_encode( $result );
322
323 exit();
324 }
325
326 public function ajax_optimization_statistics() {
327 if ( ! $this->check_ajax_referer() ) {
328 exit();
329 }
330 $stats = Tiny_Image::get_optimization_statistics( $this->settings );
331 echo json_encode( $stats );
332 exit();
333 }
334
335 public function media_library_bulk_action() {
336
337 if ( empty( $_REQUEST['action'] ) || (
338 'tiny_bulk_action' != $_REQUEST['action'] &&
339 'tiny_bulk_action' != $_REQUEST['action2'] ) ) {
340 return;
341 }
342
343 if ( empty( $_REQUEST['media'] ) || ( ! $_REQUEST['media'] ) ) {
344 return;
345 }
346
347 check_admin_referer( 'bulk-media' );
348 $ids = implode( '-', array_map( 'intval', $_REQUEST['media'] ) );
349 wp_redirect(add_query_arg(
350 '_wpnonce',
351 wp_create_nonce( 'tiny-bulk-optimization' ),
352 admin_url( "upload.php?page=tiny-bulk-optimization&ids=$ids" )
353 ));
354 exit();
355 }
356
357 public function add_media_columns( $columns ) {
358 $columns[ self::MEDIA_COLUMN ] = esc_html__( 'Compression', 'tiny-compress-images' );
359 return $columns;
360 }
361
362 public function render_media_column( $column, $id ) {
363 if ( self::MEDIA_COLUMN === $column ) {
364 $tiny_image = new Tiny_Image( $this->settings, $id );
365 if ( $tiny_image->file_type_allowed() ) {
366 echo '<div class="tiny-ajax-container">';
367 $this->render_compress_details( $tiny_image );
368 echo '</div>';
369 }
370 }
371 }
372
373 public function show_media_info() {
374 global $post;
375 $tiny_image = new Tiny_Image( $this->settings, $post->ID );
376 if ( $tiny_image->file_type_allowed() ) {
377 echo '<div class="misc-pub-section tiny-compress-images">';
378 echo '<h4>';
379 esc_html_e( 'JPEG and PNG optimization', 'tiny-compress-images' );
380 echo '</h4>';
381 echo '<div class="tiny-ajax-container">';
382 $this->render_compress_details( $tiny_image );
383 echo '</div>';
384 echo '</div>';
385 }
386 }
387
388 private function render_compress_details( $tiny_image ) {
389 $in_progress = $tiny_image->filter_image_sizes( 'in_progress' );
390 if ( count( $in_progress ) > 0 ) {
391 include( dirname( __FILE__ ) . '/views/compress-details-processing.php' );
392 } else {
393 include( dirname( __FILE__ ) . '/views/compress-details.php' );
394 }
395 }
396
397 public function render_bulk_optimization_page() {
398 $stats = Tiny_Image::get_optimization_statistics( $this->settings );
399 $estimated_costs = Tiny_Compress::estimate_cost(
400 $stats['available-unoptimised-sizes'],
401 $this->settings->get_compression_count()
402 );
403 $admin_colors = self::retrieve_admin_colors();
404
405 $active_tinify_sizes = $this->settings->get_active_tinify_sizes();
406
407 $auto_start_bulk = isset( $_REQUEST['ids'] );
408
409 include( dirname( __FILE__ ) . '/views/bulk-optimization.php' );
410 }
411
412 private static function retrieve_admin_colors() {
413 global $_wp_admin_css_colors;
414 $admin_colour_scheme = get_user_option( 'admin_color', get_current_user_id() );
415 $admin_colors = array( '#0074aa', '#1685b5', '#78ca44', '#0086ba' ); // default
416 if ( isset( $_wp_admin_css_colors[ $admin_colour_scheme ] ) ) {
417 if ( isset( $_wp_admin_css_colors[ $admin_colour_scheme ]->colors ) ) {
418 $admin_colors = $_wp_admin_css_colors[ $admin_colour_scheme ]->colors;
419 }
420 }
421 if ( '#e5e5e5' == $admin_colors[0] && '#999' == $admin_colors[1] ) {
422 $admin_colors[0] = '#bbb';
423 }
424 if ( '#5589aa' == $admin_colors[0] && '#cfdfe9' == $admin_colors[1] ) {
425 $admin_colors[1] = '#85aec5';
426 }
427 if ( '#7c7976' == $admin_colors[0] && '#c6c6c6' == $admin_colors[1] ) {
428 $admin_colors[1] = '#adaba9';
429 $admin_colors[2] = '#adaba9';
430 }
431 if ( self::wp_version() > 3.7 ) {
432 if ( 'fresh' == $admin_colour_scheme ) {
433 $admin_colors = array( '#0074aa', '#1685b5', '#78ca44', '#0086ba' ); // better
434 }
435 }
436 return $admin_colors;
437 }
438
439 private function get_ids_to_compress() {
440 if ( empty( $_REQUEST['ids'] ) ) {
441 return array();
442 }
443
444 $ids = implode( ',', array_map( 'intval', explode( '-', $_REQUEST['ids'] ) ) );
445 $condition = "AND ID IN($ids)";
446
447 global $wpdb;
448 return $wpdb->get_results(
449 "SELECT ID, post_title FROM $wpdb->posts
450 WHERE post_type = 'attachment' $condition
451 AND (post_mime_type = 'image/jpeg' OR post_mime_type = 'image/png')
452 ORDER BY ID DESC", ARRAY_A);
453 }
454 }
455