PluginProbe ʕ •ᴥ•ʔ
TinyPNG – JPEG, PNG & WebP image compression / 1.3.2
TinyPNG – JPEG, PNG & WebP image compression v1.3.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 11 years ago languages 10 years ago scripts 11 years ago styles 11 years ago cacert.pem 11 years ago class-tiny-compress-curl.php 10 years ago class-tiny-compress-fopen.php 10 years ago class-tiny-compress.php 10 years ago class-tiny-exception.php 11 years ago class-tiny-metadata.php 10 years ago class-tiny-notices.php 11 years ago class-tiny-php.php 11 years ago class-tiny-plugin.php 10 years ago class-tiny-settings.php 10 years ago class-tiny-wp-base.php 11 years ago
class-tiny-plugin.php
277 lines
1 <?php
2 /*
3 * Tiny Compress Images - WordPress plugin.
4 * Copyright (C) 2015 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 MEDIA_COLUMN = self::NAME;
23 const MEDIA_COLUMN_HEADER = 'Compression';
24
25 private $settings;
26
27 public static function jpeg_quality() {
28 return 95;
29 }
30
31 public function __construct() {
32 parent::__construct();
33
34 $this->settings = new Tiny_Settings();
35 if (is_admin()) {
36 add_action('admin_menu', $this->get_method('admin_menu'));
37 }
38 }
39
40 public function set_compressor($compressor) {
41 $this->settings->set_compressor($compressor);
42 }
43
44 public function init() {
45 add_filter('jpeg_quality', $this->get_static_method('jpeg_quality'));
46 add_filter('wp_editor_set_quality', $this->get_static_method('jpeg_quality'));
47 add_filter('wp_generate_attachment_metadata', $this->get_method('compress_attachment'), 10, 2);
48 load_plugin_textdomain(self::NAME, false, dirname(plugin_basename(__FILE__)) . '/languages');
49 }
50
51 public function admin_init() {
52 add_filter('manage_media_columns', $this->get_method('add_media_columns'));
53 add_action('manage_media_custom_column', $this->get_method('render_media_column'), 10, 2);
54 add_action('wp_ajax_tiny_compress_image', $this->get_method('compress_image'));
55 add_action('admin_action_tiny_bulk_compress', $this->get_method('bulk_compress'));
56 add_action('admin_enqueue_scripts', $this->get_method('enqueue_scripts'));
57 }
58
59 public function admin_menu() {
60 add_management_page(
61 self::translate('Compress JPEG & PNG Images'), self::translate('Compress All Images'),
62 'upload_files', 'tiny-bulk-compress', $this->get_method('bulk_compress_page')
63 );
64
65 }
66
67 public function enqueue_scripts($hook) {
68 wp_enqueue_style(self::NAME .'_admin', plugins_url('/styles/admin.css', __FILE__),
69 array(), self::plugin_version());
70
71 $handle = self::NAME .'_admin';
72 wp_register_script($handle, plugins_url('/scripts/admin.js', __FILE__),
73 array(), self::plugin_version(), true);
74
75 // Wordpress < 3.3 does not handle multi dimensional arrays
76 wp_localize_script($handle, 'tinyCompress', array(
77 'nonce' => wp_create_nonce('tiny-compress'),
78 'wpVersion' => self::wp_version(),
79 'pluginVersion' => self::plugin_version(),
80 'L10nAllDone' => self::translate('All images are processed'),
81 'L10nBulkAction' => self::translate('Compress Images'),
82 'L10nCompressing' => self::translate('Compressing'),
83 'L10nCompressions' => self::translate('compressions'),
84 'L10nError' => self::translate('Error'),
85 'L10nInternalError' => self::translate('Internal error'),
86 'L10nOutOf' => self::translate('out of'),
87 'L10nWaiting' => self::translate('Waiting'),
88 ));
89 wp_enqueue_script($handle);
90 }
91
92 private function compress($metadata, $attachment_id) {
93 $mime_type = get_post_mime_type($attachment_id);
94 $tiny_metadata = new Tiny_Metadata($attachment_id, $metadata);
95
96 if ($this->settings->get_compressor() === null || strpos($mime_type, 'image/') !== 0) {
97 return $metadata;
98 }
99
100 $success = 0;
101 $failed = 0;
102
103 $compressor = $this->settings->get_compressor();
104 $active_tinify_sizes = $this->settings->get_active_tinify_sizes();
105 $uncompressed_sizes = $tiny_metadata->get_uncompressed_sizes($active_tinify_sizes);
106
107 foreach ($uncompressed_sizes as $uncompressed_size) {
108 try {
109 $tiny_metadata->add_request($uncompressed_size);
110 $tiny_metadata->update();
111 $response = $compressor->compress_file($tiny_metadata->get_filename($uncompressed_size));
112 $responses[$uncompressed_size] = $response;
113
114 $tiny_metadata->add_response($response, $uncompressed_size);
115 $success++;
116 } catch (Tiny_Exception $e) {
117 $tiny_metadata->add_exception($e, $uncompressed_size);
118 $failed++;
119 }
120 }
121 $tiny_metadata->update();
122
123 return array($tiny_metadata, array('success' => $success, 'failed' => $failed));
124 }
125
126 public function compress_attachment($metadata, $attachment_id) {
127 $this->compress($metadata, $attachment_id);
128 return $metadata;
129 }
130
131 public function compress_image() {
132 if (!$this->check_ajax_referer()) {
133 exit();
134 }
135 $json = !empty($_POST['json']) && $_POST['json'];
136 if (!current_user_can('upload_files')) {
137 $message = self::translate("You don't have permission to work with uploaded files") . '.';
138 echo $json ? json_encode(array('error' => $message)) : $message;
139 exit();
140 }
141 if (empty($_POST['id'])) {
142 $message = self::translate("Not a valid media file") . '.';
143 echo $json ? json_encode(array('error' => $message)) : $message;
144 exit();
145 }
146 $id = intval($_POST['id']);
147 $metadata = wp_get_attachment_metadata($id);
148 if (!is_array($metadata)) {
149 $message = self::translate("Could not find metadata of media file") . '.';
150 echo $json ? json_encode(array('error' => $message)) : $message;
151 exit;
152 }
153
154 list($tiny_metadata, $result) = $this->compress($metadata, $id);
155 if ($json) {
156 $result['message'] = $tiny_metadata->get_latest_error();
157 $result['status'] = $this->settings->get_status();
158 $result['thumbnail'] = $tiny_metadata->get_url('thumbnail');
159 echo json_encode($result);
160 } else {
161 echo $this->render_compress_details($tiny_metadata);
162 }
163
164 exit();
165 }
166
167 public function bulk_compress() {
168 check_admin_referer('bulk-media');
169
170 if (empty($_REQUEST['media']) || !is_array( $_REQUEST['media'])) {
171 return;
172 }
173
174 $ids = implode('-', array_map('intval', $_REQUEST['media']));
175 wp_redirect(add_query_arg(
176 '_wpnonce',
177 wp_create_nonce('tiny-bulk-compress'),
178 admin_url("tools.php?page=tiny-bulk-compress&ids=$ids")
179 ));
180 exit();
181 }
182
183 public function add_media_columns($columns) {
184 $columns[self::MEDIA_COLUMN] = self::translate(self::MEDIA_COLUMN_HEADER);
185 return $columns;
186 }
187
188 public function render_media_column($column, $id) {
189 if ($column === self::MEDIA_COLUMN) {
190 $this->render_compress_details(new Tiny_Metadata($id));
191 }
192 }
193
194 private function render_compress_details($tiny_metadata) {
195 $missing = $tiny_metadata->get_uncompressed_sizes($this->settings->get_active_tinify_sizes());
196 $success = count($tiny_metadata->get_success_sizes());
197 $total = count($missing) + $success;
198 $progress = count($tiny_metadata->get_in_progress_sizes());
199
200 $duplicates = count($this->settings->get_active_tinify_sizes()) - $total;
201 $success += $duplicates;
202 $total += $duplicates;
203
204 if (count($missing) > 0) {
205 printf(self::translate_escape('Compressed %d out of %d sizes'), $success, $total);
206 echo '<br/>';
207 if (($error = $tiny_metadata->get_latest_error())) {
208 echo '<span class="error">' . self::translate_escape('Latest error') . ': '. self::translate_escape($error) .'</span><br/>';
209 }
210 echo '<button type="button" class="tiny-compress" data-id="' . $tiny_metadata->get_id() . '">' .
211 self::translate_escape('Compress') . '</button>';
212 echo '<div class="spinner hidden"></div>';
213 } elseif ($progress > 0) {
214 printf(self::translate_escape('Compressing %d sizes...'), count($this->settings->get_active_tinify_sizes()));
215 } else {
216 printf(self::translate_escape('Compressed %d out of %d sizes'), $success, $total);
217 $savings = $tiny_metadata->get_savings();
218 if ($savings['count'] > 0) {
219 echo '<br/>';
220 echo self::translate_escape('Total size') . ': ' . size_format($savings['input']) . '<br/>';
221 echo self::translate_escape('Compressed size') . ': ' . size_format($savings['output']);
222 }
223 }
224 }
225
226 public function bulk_compress_page() {
227 global $wpdb;
228
229 echo '<div class="wrap" id="tiny-bulk-compress">';
230 echo '<h2>' . self::translate('Compress JPEG & PNG Images') . '</h2>';
231 if (empty($_POST['tiny-bulk-compress']) && empty($_REQUEST['ids'])) {
232 $result = $wpdb->get_results("SELECT COUNT(*) AS `count` FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' ORDER BY ID DESC", ARRAY_A);
233 $count = $result[0]['count'];
234
235 echo '<p>' . self::translate_escape("Use this tool to compress all images in your media library") . '. ';
236 echo self::translate_escape("Only images that have not been compressed will be compressed") . '.</p>';
237 echo '<p>' . sprintf(self::translate_escape("We have found %d images in your media library"), $count) . '. ';
238 echo self::translate_escape("To begin, just press the button below") . '.</p>';
239
240 echo '<form method="POST" action="?page=tiny-bulk-compress">';
241 echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce('tiny-bulk-compress') . '">';
242 echo '<input type="hidden" name="tiny-bulk-compress" value="1">';
243 echo '<p><button class="button button-primary button-large" type="submit">' .
244 self::translate_escape('Compress All Images') . '</p>';
245 echo '</form>';
246 } else {
247 check_admin_referer('tiny-bulk-compress');
248
249 if (!empty($_REQUEST['ids'])) {
250 $ids = implode(',', array_map('intval', explode('-', $_REQUEST['ids'])));
251 $cond = "AND ID IN($ids)";
252 } else {
253 $cond = "";
254 }
255
256 // Get all ids and names of the images and not the whole objects which will only fill memory
257 $items = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' $cond ORDER BY ID DESC", ARRAY_A);
258
259 echo '<p>';
260 echo self::translate_escape("Please be patient while the images are being compressed") . '. ';
261 echo self::translate_escape("This can take a while if you have many images") . '. ';
262 echo self::translate_escape("Do not navigate away from this page because it will stop the process") . '. ';
263 echo self::translate_escape("You will be notified via this page when the processing is done") . '.';
264 echo "</p>";
265
266 echo '<div id="tiny-status"><p>'. self::translate_escape('Compressions this month') . sprintf(' <span>%d</span></p></div>', $this->settings->get_status());
267 echo '<div id="tiny-progress"><p>'. self::translate_escape('Processing') . ' <span>0</span> ' . self::translate_escape('out of') . sprintf(' %d </p></div>', count($items));
268 echo '<div id="media-items">';
269 echo '</div>';
270
271 echo '<script type="text/javascript">jQuery(function() { tinyBulkCompress('. json_encode($items) . ')})</script>';
272 }
273
274 echo '</div>';
275 }
276 }
277