Smush Image Compression and Optimization - Version 1.6.5

Version Description

  • Codes reformatted and cleaned up into a php class
  • More texts are translatable now
Download this release

Release Info

Developer WPMUDEV
Plugin Icon 128x128 Smush Image Compression and Optimization
Version 1.6.5
Comparing to
See all releases

Code changes from version 1.6.4 to 1.6.5

Files changed (5) hide show
  1. bulk.php +0 -77
  2. languages/wp_smushit.po +146 -0
  3. readme.txt +36 -24
  4. settings.php +0 -52
  5. wp-smushit.php +506 -350
bulk.php DELETED
@@ -1,77 +0,0 @@
1
- <div class="wrap">
2
- <div id="icon-upload" class="icon32"><br /></div><h2>Bulk WP Smush.it </h2>
3
-
4
- <?php
5
-
6
- if ( sizeof($attachments) < 1 ):
7
- echo '<p>You don’t appear to have uploaded any images yet.</p>';
8
- else:
9
- if ( empty($_POST) && !$auto_start ): // instructions page
10
- ?>
11
- <p>This tool will run all of the images in your media library through the WP Smush.it web service. It won't re-smush images that were successfully smushed before. It will retry images that were not successfully smushed.</p>
12
-
13
- <p>It uploads each and every file to Yahoo! and then downloads the resulting file. It can take a long time.</p>
14
-
15
- <p>We found <?php echo sizeof($attachments); ?> images in your media library. Be forewarned, <strong>it will take <em>at least</em> <?php echo (sizeof($attachments) * 3 / 60); ?> minutes</strong> to process all these images if they have never been smushed before.</p>
16
-
17
- <p><em>N.B. If your server <tt>gzip</tt>s content you may not see the progress updates as your files are processed.</em></p>
18
-
19
- <p><strong>This is an experimental feature.</strong> Please post any feedback to the <a href="http://wordpress.org/tags/wp-smushit">WordPress WP Smush.it forums</a>.</p>
20
-
21
- <form method="post" action="">
22
- <?php wp_nonce_field( 'wp-smushit-bulk', '_wpnonce'); ?>
23
- <button type="submit" class="button-secondary action">Run all my images through WP Smush.it right now</button>
24
- </form>
25
-
26
- <?php
27
- else: // run the script
28
-
29
- if (!wp_verify_nonce( $_REQUEST['_wpnonce'], 'wp-smushit-bulk' ) || !current_user_can( 'edit_others_posts' ) ) {
30
- wp_die( __( 'Cheatin&#8217; uh?' ) );
31
- }
32
-
33
-
34
- ob_implicit_flush(true);
35
- ob_end_flush();
36
- foreach( $attachments as $attachment ) {
37
- printf( "<p>Processing <strong>%s</strong>&hellip;<br>", esc_html($attachment->post_name) );
38
- $original_meta = wp_get_attachment_metadata( $attachment->ID, true );
39
-
40
- $meta = wp_smushit_resize_from_meta_data( $original_meta, $attachment->ID, false );
41
-
42
- printf( "– %dx%d: ", intval($meta['width']), intval($meta['height']) );
43
-
44
- if ( $original_meta['wp_smushit'] == $meta['wp_smushit'] && stripos( $meta['wp_smushit'], 'Smush.it error' ) === false ) {
45
- echo 'already smushed' . $meta['wp_smushit'];
46
- } else {
47
- echo $meta['wp_smushit'];
48
- }
49
- echo '<br>';
50
-
51
-
52
-
53
- if ( isset( $meta['sizes'] ) && is_array( $meta['sizes'] ) ) {
54
- foreach( $meta['sizes'] as $size_name => $size ) {
55
- printf( "– %dx%d: ", intval($size['width']), intval($size['height']) );
56
- if ( $original_meta['sizes'][$size_name]['wp_smushit'] == $size['wp_smushit'] && stripos( $meta['sizes'][$size_name]['wp_smushit'], 'Smush.it error' ) === false ) {
57
- echo 'already smushed';
58
- } else {
59
- echo $size['wp_smushit'];
60
- }
61
- echo '<br>';
62
-
63
- }
64
- }
65
- echo "</p>";
66
-
67
- wp_update_attachment_metadata( $attachment->ID, $meta );
68
-
69
- // rate limiting is good manners, let's be nice to Yahoo!
70
- sleep(0.5);
71
- @ob_flush();
72
- flush();
73
- }
74
- endif;
75
- endif;
76
- ?>
77
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/wp_smushit.po ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: WP Smushit\n"
4
+ "POT-Creation-Date: 2013-04-14 20:54+0700\n"
5
+ "PO-Revision-Date: 2013-04-14 20:55+0700\n"
6
+ "Last-Translator: incsub.com <hakan@incsub.com>\n"
7
+ "Language-Team: WPMU DEV\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "X-Generator: Poedit 1.5.3\n"
12
+ "X-Poedit-KeywordsList: _;__\n"
13
+ "X-Poedit-Basepath: .\n"
14
+ "X-Poedit-SearchPath-0: C:\\Users\\Hakan\\Desktop\\wp-smushit\n"
15
+
16
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:103
17
+ msgid "Use Smush.it on upload?"
18
+ msgstr ""
19
+
20
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:104
21
+ msgid "How many seconds should we wait for a response from Smush.it?"
22
+ msgstr ""
23
+
24
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:116
25
+ msgid "Automatically process on upload"
26
+ msgstr ""
27
+
28
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:117
29
+ msgid "Do not process on upload"
30
+ msgstr ""
31
+
32
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:121
33
+ #, php-format
34
+ msgid "Temporarily disabled until %s"
35
+ msgstr ""
36
+
37
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:186
38
+ #, php-format
39
+ msgid ""
40
+ "<p>We found %d images in your media library. Be forewarned, <strong>it will "
41
+ "take <em>at least</em> %d minutes</strong> to process all these images if "
42
+ "they have never been smushed before.</p>"
43
+ msgstr ""
44
+
45
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:190
46
+ #, php-format
47
+ msgid ""
48
+ "<p><strong>This is an experimental feature.</strong> Please post any "
49
+ "feedback to the %s.</p>"
50
+ msgstr ""
51
+
52
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:190
53
+ msgid "WordPress WP Smush.it forums"
54
+ msgstr ""
55
+
56
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:201
57
+ msgid "Cheatin&#8217; uh?"
58
+ msgstr ""
59
+
60
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:254
61
+ msgid "You don't have permission to work with uploaded files."
62
+ msgstr ""
63
+
64
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:258
65
+ msgid "No attachment ID was provided."
66
+ msgstr ""
67
+
68
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:294
69
+ msgid "Did not smush due to previous errors"
70
+ msgstr ""
71
+
72
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:301
73
+ #, php-format
74
+ msgid "Could not find <span class='code'>%s</span>"
75
+ msgstr ""
76
+
77
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:307
78
+ #, php-format
79
+ msgid "<span class='code'>%s</span> is not writable"
80
+ msgstr ""
81
+
82
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:313
83
+ #, php-format
84
+ msgid ""
85
+ "<a href='http://developer.yahoo.com/yslow/smushit/faq.html#faq_restrict'>Too "
86
+ "big</a> for Smush.it (%s)"
87
+ msgstr ""
88
+
89
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:322
90
+ #, php-format
91
+ msgid ""
92
+ "<span class='code'>%s</span> must be within the content directory (<span "
93
+ "class='code'>%s</span>)"
94
+ msgstr ""
95
+
96
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:337
97
+ msgid "Error posting to Smush.it"
98
+ msgstr ""
99
+
100
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:343
101
+ msgid "Bad response from Smush.it"
102
+ msgstr ""
103
+
104
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:356
105
+ msgid "No savings"
106
+ msgstr ""
107
+
108
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:359
109
+ msgid "Smush.it error: "
110
+ msgstr ""
111
+
112
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:359
113
+ msgid "unknown error"
114
+ msgstr ""
115
+
116
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:360
117
+ #, php-format
118
+ msgid ""
119
+ " while processing <span class='code'>%s</span> (<span class='code'>%s</span>)"
120
+ msgstr ""
121
+
122
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:376
123
+ #, php-format
124
+ msgid "Error downloading file (%s)"
125
+ msgstr ""
126
+
127
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:387
128
+ #, php-format
129
+ msgid "Reduced by %01.1f%% (%s)"
130
+ msgstr ""
131
+
132
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:479
133
+ msgid "WP Smush.it requires WordPress 2.8 or greater"
134
+ msgstr ""
135
+
136
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:519
137
+ msgid "Re-smush"
138
+ msgstr ""
139
+
140
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:522
141
+ msgid "Not processed"
142
+ msgstr ""
143
+
144
+ #: C:\Users\Hakan\Desktop\wp-smushit/wp-smushit.php:525
145
+ msgid "Smush.it now!"
146
+ msgstr ""
readme.txt CHANGED
@@ -1,20 +1,19 @@
1
  === WP Smush.it ===
2
  Plugin Name: WP Smush.it
3
- Version: 1.6.4
4
- Author: Dialect
5
- Author URI: http://dialect.ca/?wp_smush_it
6
- Contributors: alexdunae, WPMUDEV
7
  Tags: images, image, attachments, attachment
8
  Requires at least: 2.9
9
- Tested up to: 3.5.1
10
- Stable tag: 1.6.4
 
11
 
12
  Reduce image file sizes and improve performance using the <a href="http://smush.it/">Smush.it</a> API within WordPress.
13
 
14
  == Description ==
15
 
16
- = Dear Smushers: WP Smush.it has found a new maintainer. Stay tuned for a fresh release. =
17
-
18
  Yahoo's excellent <a href="http://developer.yahoo.com/performance/">Exceptional Performance series</a> recommends <a href="http://developer.yahoo.com/performance/rules.html#opt_images">optimizing images</a> in several lossless ways:
19
 
20
  * stripping meta data from JPEGs
@@ -23,6 +22,9 @@ Yahoo's excellent <a href="http://developer.yahoo.com/performance/">Exceptional
23
  * stripping the un-used colours from indexed images
24
 
25
  <a href="http://smush.it/">Smush.it</a> offers an API that performs these optimizations (except for stripping JPEG meta data) automatically, and this plugin seamlessly integrates Smush.it with WordPress.
 
 
 
26
 
27
  = How does it work? =
28
  Every image you add to a page or post will be automatically run through Smush.it behind the scenes. You don&rsquo;t have to do anything different.
@@ -38,11 +40,16 @@ Sometimes the Smush.it service goes down or is under heavy load. If the plugin h
38
 
39
  You can also define how long you want to wait for the Smush.it server to respond.
40
 
41
- = NextGEN Gallery =
42
- NextGEN user? Also download the <a href="http://wordpress.org/extend/plugins/wp-smushit-nextgen-gallery-integration/">WP Smush.it NextGEN Integration</a> plugin.
43
-
44
  = Privacy =
45
  Be sure you&rsquo;re comfortable with Smush.it&rsquo;s privacy policy (found on their <a href="http://info.yahoo.com/legal/us/yahoo/smush_it/smush_it-4378.html">FAQ</a>).
 
 
 
 
 
 
 
 
46
 
47
  == Screenshots ==
48
 
@@ -57,22 +64,20 @@ Be sure you&rsquo;re comfortable with Smush.it&rsquo;s privacy policy (found on
57
 
58
  == Upgrade Notice ==
59
 
60
- Dear Smushers: WP Smush.it has found a new maintainer. Stay tuned for a fresh release.
61
-
62
- In this release, my last official one, we've got:
63
-
64
- * check image size before uploading (1 MB limit)
65
- * attempt to smush more than one image before bailing (kind thanks to <a href="http://wordpress.org/support/profile/xrampage16">xrampage16</a>)
66
- * allow setting timeout value under `Media > Settings` (default is 60 seconds)
67
-
68
- Cheers from Vancouver Island, and thanks for all the smushing.
69
 
70
- - Alex
71
 
72
  == Changelog ==
73
 
 
 
 
 
74
  = 1.6.4 =
75
- * Fix debug code left in 1.6.3
76
 
77
  = 1.6.3 =
78
  * check image size before uploading (1 MB limit)
@@ -181,12 +186,19 @@ Cheers from Vancouver Island, and thanks for all the smushing.
181
  = 1.0 =
182
  * first edition
183
 
 
 
 
 
 
 
 
 
184
 
185
  == Contact and Credits ==
186
 
187
- Written by Alex Dunae at Dialect ([dialect.ca](http://dialect.ca/?wp_smush_it), e-mail 'alex' at 'dialect dot ca'), 2008-11.
188
 
189
  WP Smush.it includes a copy of the [PEAR JSON library](http://pear.php.net/pepr/pepr-proposal-show.php?id=198) written by Michal Migurski.
190
 
191
  Smush.it was created by [Nicole Sullivan](http://www.stubbornella.org/content/) and [Stoyan Stefanov](http://phpied.com/).
192
-
1
  === WP Smush.it ===
2
  Plugin Name: WP Smush.it
3
+ Version: 1.6.5
4
+ Author: WPMU DEV
5
+ Author URI: http://premium.wpmudev.org
6
+ Contributors: WPMUDEV, alexdunae
7
  Tags: images, image, attachments, attachment
8
  Requires at least: 2.9
9
+ Tested up to: 3.6
10
+ Stable tag: 1.6.5
11
+ License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12
 
13
  Reduce image file sizes and improve performance using the <a href="http://smush.it/">Smush.it</a> API within WordPress.
14
 
15
  == Description ==
16
 
 
 
17
  Yahoo's excellent <a href="http://developer.yahoo.com/performance/">Exceptional Performance series</a> recommends <a href="http://developer.yahoo.com/performance/rules.html#opt_images">optimizing images</a> in several lossless ways:
18
 
19
  * stripping meta data from JPEGs
22
  * stripping the un-used colours from indexed images
23
 
24
  <a href="http://smush.it/">Smush.it</a> offers an API that performs these optimizations (except for stripping JPEG meta data) automatically, and this plugin seamlessly integrates Smush.it with WordPress.
25
+
26
+ = Dear Smushers: WPMU DEV has taken over maintenance and support for WP Smush.it =
27
+ With the backing of <a href="http://premium.wpmudev.org/">WPMU DEV's professional WordPress team</a> you can expect faster support, bug-fixes, and new features!
28
 
29
  = How does it work? =
30
  Every image you add to a page or post will be automatically run through Smush.it behind the scenes. You don&rsquo;t have to do anything different.
40
 
41
  You can also define how long you want to wait for the Smush.it server to respond.
42
 
 
 
 
43
  = Privacy =
44
  Be sure you&rsquo;re comfortable with Smush.it&rsquo;s privacy policy (found on their <a href="http://info.yahoo.com/legal/us/yahoo/smush_it/smush_it-4378.html">FAQ</a>).
45
+
46
+ = About Us =
47
+ WPMU DEV is a premium supplier of quality WordPress plugins and themes. For premium support with any WordPress related issues you can join us here:
48
+ <a href="http://premium.wpmudev.org/join/">http://premium.wpmudev.org/join/</a>
49
+
50
+ Don't forget to stay up to date on everything WordPress from the Internet's number one resource:
51
+ <a href="http://wpmu.org/">http://wpmu.org</a>
52
+
53
 
54
  == Screenshots ==
55
 
64
 
65
  == Upgrade Notice ==
66
 
67
+ In this first official release from WPMU DEV, we've done a code cleanup and reformat to get started, as well as
68
+ attempting to handle smush.it API errors a bit better. We've also made all the text fully i18n translatable.
69
+
70
+ This will give us a good foundation to start adding some new features!
 
 
 
 
 
71
 
 
72
 
73
  == Changelog ==
74
 
75
+ = 1.6.5 =
76
+ * Codes reformatted and cleaned up into a php class
77
+ * More texts are translatable now
78
+
79
  = 1.6.4 =
80
+ * Fixed a bug that prevents execution
81
 
82
  = 1.6.3 =
83
  * check image size before uploading (1 MB limit)
186
  = 1.0 =
187
  * first edition
188
 
189
+ == About Us ==
190
+ WPMU DEV is a premium supplier of quality WordPress plugins and themes. For premium support with any WordPress related issues you can join us here:
191
+ <a href="http://premium.wpmudev.org/join/">http://premium.wpmudev.org/join/</a>
192
+
193
+ Don't forget to stay up to date on everything WordPress from the Internet's number one resource:
194
+ <a href="http://wpmu.org/">http://wpmu.org</a>
195
+
196
+ Hey, one more thing... we hope you <a href="http://profiles.wordpress.org/WPMUDEV/">enjoy our free offerings</a> as much as we've loved making them for you!
197
 
198
  == Contact and Credits ==
199
 
200
+ Originally written by Alex Dunae at Dialect ([dialect.ca](http://dialect.ca/?wp_smush_it), e-mail 'alex' at 'dialect dot ca'), 2008-11.
201
 
202
  WP Smush.it includes a copy of the [PEAR JSON library](http://pear.php.net/pepr/pepr-proposal-show.php?id=198) written by Michal Migurski.
203
 
204
  Smush.it was created by [Nicole Sullivan](http://www.stubbornella.org/content/) and [Stoyan Stefanov](http://phpied.com/).
 
settings.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
-
3
- /*
4
-
5
- Each service has a setting specifying whether it should be used automatically on upload.
6
-
7
- Values are:
8
- -1 Don't use (until manually enabled via Media > Settings)
9
- 0 Use automatically
10
- n Any other number is a Unix timestamp indicating when the service can be used again
11
-
12
- */
13
-
14
- define('WP_SMUSHIT_AUTO_OK', 0);
15
- define('WP_SMUSHIT_AUTO_NEVER', -1);
16
-
17
-
18
- function wp_smushit_register_settings() {
19
- add_settings_section( 'wp_smushit_settings', 'WP Smush.it', 'wp_smushit_settings_cb', 'media' );
20
- add_settings_field( 'wp_smushit_smushit_auto', 'Use Smush.it on upload?', 'wp_smushit_render_auto_opts', 'media', 'wp_smushit_settings' );
21
- add_settings_field( 'wp_smushit_smushit_timeout', 'How many seconds should we wait for a response from Smush.it?', 'wp_smushit_render_timeout_opts', 'media', 'wp_smushit_settings' );
22
- register_setting( 'media', 'wp_smushit_smushit_auto');
23
- register_setting( 'media', 'wp_smushit_smushit_timeout');
24
- }
25
- add_action('admin_init', 'wp_smushit_register_settings');
26
-
27
- function wp_smushit_settings_cb() {
28
- }
29
-
30
- function wp_smushit_render_auto_opts() {
31
- $key = 'wp_smushit_smushit_auto';
32
- $val = intval( get_option( $key, WP_SMUSHIT_AUTO_OK ) );
33
- printf( "<select name='%1\$s' id='%1\$s'>", esc_attr( $key ) );
34
- echo '<option value=' . WP_SMUSHIT_AUTO_OK . ' ' . selected( WP_SMUSHIT_AUTO_OK, $val ) . '>Automatically process on upload</option>';
35
- echo '<option value=' . WP_SMUSHIT_AUTO_NEVER . ' ' . selected( WP_SMUSHIT_AUTO_NEVER, $val ) . '>Do not process on upload</option>';
36
-
37
- if ( $val > 0 ) {
38
- printf( '<option value="%d" selected="selected">Temporarily disabled until %s</option>', $val, date( 'M j, Y \a\t H:i', $val ) );
39
- }
40
- echo '</select>';
41
- }
42
-
43
- function wp_smushit_render_timeout_opts( $key ) {
44
- $key = 'wp_smushit_smushit_timeout';
45
- $val = intval( get_option( $key, WP_SMUSHIT_AUTO_OK ) );
46
- printf( "<input type='text' name='%1\$s' id='%1\$s' value='%2\%d'>", esc_attr( $key ), intval( get_option( $key, 60 ) ) );
47
- }
48
-
49
- // default is 6hrs
50
- function wp_smushit_temporarily_disable( $seconds = 21600) {
51
- update_option( 'wp_smushit_smushit_auto', time() + $seconds );
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
wp-smushit.php CHANGED
@@ -1,418 +1,574 @@
1
  <?php
2
  /*
3
  Plugin Name: WP Smush.it
4
- Plugin URI: http://dialect.ca/code/wp-smushit/
5
  Description: Reduce image file sizes and improve performance using the <a href="http://smush.it/">Smush.it</a> API within WordPress.
6
- Author: Dialect
7
- Version: 1.6.4
8
- Author URI: http://dialect.ca/
 
9
  */
10
 
11
- if ( !function_exists('json_encode') ) {
12
- require_once('JSON/JSON.php');
13
- }
 
14
 
15
- if ( !function_exists('download_url') ) {
16
- require_once(ABSPATH . 'wp-admin/includes/file.php');
17
- }
18
 
19
- /**
20
- * Constants
21
- */
22
- define('SMUSHIT_REQ_URL', 'http://www.smushit.com/ysmush.it/ws.php?img=%s');
23
- define('SMUSHIT_BASE_URL', 'http://www.smushit.com/');
24
 
25
- define('WP_SMUSHIT_DOMAIN', 'wp_smushit');
26
- define('WP_SMUSHIT_UA', 'WP Smush.it/1.6.3 (+http://wordpress.org/extend/plugins/wp-smushit/)');
27
- define('WP_SMUSHIT_PLUGIN_DIR', dirname(plugin_basename(__FILE__)));
28
- define('WP_SMUSHIT_MAX_BYTES', 1048576);
29
 
30
- // The number of images (including generated sizes) that can return errors before abandoning all hope.
31
- // N.B. this doesn't work with the bulk uploader, since it creates a new HTTP request
32
- // for each image. It does work with the bulk smusher, though.
33
- define('WP_SMUSHIT_ERRORS_BEFORE_QUITTING', 3 * count(get_intermediate_image_sizes()));
34
 
35
- define('WP_SMUSHIT_AUTO', intval(get_option('wp_smushit_smushit_auto', 0)));
36
- define('WP_SMUSHIT_TIMEOUT', intval(get_option('wp_smushit_smushit_timeout', 60)));
37
- require( dirname(__FILE__) . '/settings.php' );
38
 
39
- /**
40
- * Hooks
41
- */
42
 
43
- if (WP_SMUSHIT_AUTO == WP_SMUSHIT_AUTO_OK) {
44
- add_filter('wp_generate_attachment_metadata', 'wp_smushit_resize_from_meta_data', 10, 2);
45
- }
46
- add_filter('manage_media_columns', 'wp_smushit_columns');
47
- add_action('manage_media_custom_column', 'wp_smushit_custom_column', 10, 2);
48
- add_action('admin_init', 'wp_smushit_admin_init');
49
- add_action('admin_action_wp_smushit_manual', 'wp_smushit_manual');
50
-
51
- /**
52
- * Plugin admin functions
53
- */
54
- function wp_smushit_admin_init() {
55
- load_plugin_textdomain(WP_SMUSHIT_DOMAIN);
56
- wp_enqueue_script('common');
57
- }
58
 
59
- function wp_smushit_admin_menu() {
60
- add_media_page( 'Bulk Smush.it', 'Bulk Smush.it', 'edit_others_posts', 'wp-smushit-bulk', 'wp_smushit_bulk_preview');
61
- }
62
- add_action( 'admin_menu', 'wp_smushit_admin_menu' );
63
-
64
-
65
- function wp_smushit_bulk_preview() {
66
- if ( function_exists( 'apache_setenv' ) ) {
67
- @apache_setenv('no-gzip', 1);
68
- }
69
- @ini_set('output_buffering','on');
70
- @ini_set('zlib.output_compression', 0);
71
- @ini_set('implicit_flush', 1);
72
-
73
- $attachments = null;
74
- $auto_start = false;
75
-
76
- if ( isset($_REQUEST['ids'])) {
77
- $attachments = get_posts( array(
78
- 'numberposts' => -1,
79
- 'include' => explode(',', $_REQUEST['ids']),
80
- 'post_type' => 'attachment',
81
- 'post_mime_type' => 'image'
82
- ));
83
- $auto_start = true;
84
- } else {
85
- $attachments = get_posts( array(
86
- 'numberposts' => -1,
87
- 'post_type' => 'attachment',
88
- 'post_mime_type' => 'image'
89
- ));
90
- }
91
-
92
-
93
- require( dirname(__FILE__) . '/bulk.php' );
94
- }
95
-
96
- /**
97
- * Manually process an image from the Media Library
98
- */
99
- function wp_smushit_manual() {
100
- if ( FALSE === current_user_can('upload_files') ) {
101
- wp_die(__('You don\'t have permission to work with uploaded files.', WP_SMUSHIT_DOMAIN));
102
  }
103
-
104
- if ( FALSE === isset($_GET['attachment_ID'])) {
105
- wp_die(__('No attachment ID was provided.', WP_SMUSHIT_DOMAIN));
106
- }
107
-
108
- $attachment_ID = intval($_GET['attachment_ID']);
109
-
110
- $original_meta = wp_get_attachment_metadata( $attachment_ID );
111
-
112
- $new_meta = wp_smushit_resize_from_meta_data( $original_meta, $attachment_ID );
113
- wp_update_attachment_metadata( $attachment_ID, $new_meta );
114
-
115
- $sendback = wp_get_referer();
116
- $sendback = preg_replace('|[^a-z0-9-~+_.?#=&;,/:]|i', '', $sendback);
117
- wp_redirect($sendback);
118
- exit(0);
119
- }
120
-
121
- /**
122
- * Process an image with Smush.it.
123
- *
124
- * Returns an array of the $file $results.
125
- *
126
- * @param string $file Full absolute path to the image file
127
- * @param string $file_url Optional full URL to the image file
128
- * @returns array
129
- */
130
- function wp_smushit($file, $file_url = null) {
131
- // don't run on localhost, IPv4 and IPv6 checks
132
- // if( in_array($_SERVER['SERVER_ADDR'], array('127.0.0.1', '::1')) )
133
- // return array($file, __('Not processed (local file)', WP_SMUSHIT_DOMAIN));
134
-
135
- // canonicalize path - disabled 2011-02-1 troubleshooting 'Could not find...' errors.
136
- // From the PHP docs: "The running script must have executable permissions on
137
- // all directories in the hierarchy, otherwise realpath() will return FALSE."
138
- // $file_path = realpath($file);
139
-
140
- static $error_count = 0;
141
-
142
- if ( $error_count >= WP_SMUSHIT_ERRORS_BEFORE_QUITTING ) {
143
- $msg = __("Did not smush due to previous errors", WP_SMUSHIT_DOMAIN);
144
- return array($file, $msg);
145
- }
146
-
147
- $file_path = $file;
148
- // check that the file exists
149
- if ( FALSE === file_exists($file_path) || FALSE === is_file($file_path) ) {
150
- $msg = sprintf(__("Could not find <span class='code'>%s</span>", WP_SMUSHIT_DOMAIN), $file_path);
151
- return array($file, $msg);
 
152
  }
153
-
154
- // check that the file is writable
155
- if ( FALSE === is_writable($file_path) ) {
156
- $msg = sprintf(__("<span class='code'>%s</span> is not writable", WP_SMUSHIT_DOMAIN), $file_path);
157
- return array($file, $msg);
 
 
 
 
 
158
  }
159
 
160
- $file_size = filesize($file_path);
161
- if ( $file_size > WP_SMUSHIT_MAX_BYTES ) {
162
- $msg = sprintf(__("<a href='http://developer.yahoo.com/yslow/smushit/faq.html#faq_restrict'>Too big</a> for Smush.it (%s)", WP_SMUSHIT_DOMAIN), wp_smushit_format_bytes($file_size));
163
- return array($file, $msg);
164
- }
165
-
166
- // check that the file is within the WP_CONTENT_DIR
167
- $upload_dir = wp_upload_dir();
168
- $wp_upload_dir = $upload_dir['basedir'];
169
- $wp_upload_url = $upload_dir['baseurl'];
170
- if ( 0 !== stripos(realpath($file_path), realpath(ABSPATH)) ) {
171
- $msg = sprintf(__("<span class='code'>%s</span> must be within the content directory (<span class='code'>%s</span>)", WP_SMUSHIT_DOMAIN), htmlentities($file_path), $wp_upload_dir);
172
-
173
- return array($file, $msg);
174
  }
175
 
176
- if ( !$file_url ) {
177
- // determine the public URL
178
- $file_url = str_replace( $wp_upload_dir, $wp_upload_url, $file );
 
 
 
 
 
 
 
 
 
179
  }
180
 
181
- $data = wp_smushit_post($file_url);
182
-
183
- if ( FALSE === $data ) {
184
- $error_count++;
185
- return array($file, __('Error posting to Smush.it', WP_SMUSHIT_DOMAIN));
186
- }
187
-
188
- // make sure the response looks like JSON -- added 2008-12-19 when
189
- // Smush.it was returning PHP warnings before the JSON output
190
- if ( strpos( trim($data), '{' ) != 0 ) {
191
- return array($file, __('Bad response from Smush.it', WP_SMUSHIT_DOMAIN));
192
  }
193
 
194
- // read the JSON response
195
- if ( function_exists('json_decode') ) {
196
- $data = json_decode( $data );
197
- } else {
198
- $json = new Services_JSON();
199
- $data = $json->decode($data);
 
 
200
  }
201
 
202
- if ( -1 === intval($data->dest_size) )
203
- return array($file, __('No savings', WP_SMUSHIT_DOMAIN));
204
-
205
- if ( !isset($data->dest) ) {
206
- $err = ($data->error ? 'Smush.it error: ' . $data->error : 'unknown error');
207
- $err .= " while processing <span class='code'>$file_url</span> (<span class='code'>$file_path</span>)";
208
- return array($file, __($err, WP_SMUSHIT_DOMAIN) );
209
  }
210
 
211
- $processed_url = $data->dest;
212
-
213
- // The smush.it web service does not append the domain;
214
- // smushit.com web service does
215
- if ( 0 !== stripos($processed_url, 'http://') ) {
216
- $processed_url = SMUSHIT_BASE_URL . $processed_url;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  }
218
 
219
- $temp_file = download_url($processed_url);
 
 
 
 
 
 
220
 
221
- if ( is_wp_error($temp_file) ) {
222
- @unlink($tmp);
223
- $results_msg = sprintf(__("Error downloading file (%s)", WP_SMUSHIT_DOMAIN),
224
- $temp_file->get_error_message());
225
- return array($file, $results_msg );
226
- }
227
 
228
- @rename( $temp_file, $file_path );
229
 
230
- $savings = intval($data->src_size) - intval($data->dest_size);
231
- $savings_str = wp_smushit_format_bytes($savings, 1);
232
- $savings_str = str_replace(' ', '&nbsp;', $savings_str);
233
 
234
- $results_msg = sprintf(__("Reduced by %01.1f%% (%s)", WP_SMUSHIT_DOMAIN),
235
- $data->percent,
236
- $savings_str);
237
 
238
- return array($file, $results_msg);
239
- }
240
-
241
- function wp_smushit_should_resmush($previous_status) {
242
- if ( !$previous_status || empty($previous_status) ) {
243
- return TRUE;
244
- }
245
-
246
- if ( stripos($previous_status, 'no savings') !== FALSE || stripos($previous_status, 'reduced') !== FALSE ) {
247
- return FALSE;
248
- }
249
-
250
- // otherwise an error
251
- return TRUE;
252
- }
253
-
254
-
255
- /**
256
- * Read the image paths from an attachment's meta data and process each image
257
- * with wp_smushit().
258
- *
259
- * This method also adds a `wp_smushit` meta key for use in the media library.
260
- *
261
- * Called after `wp_generate_attachment_metadata` is completed.
262
- */
263
- function wp_smushit_resize_from_meta_data($meta, $ID = null, $force_resmush = true) {
264
- if ( $ID && wp_attachment_is_image( $ID ) === false ) {
265
- return $meta;
266
- }
267
-
268
- $file_path = $meta['file'];
269
- $store_absolute_path = true;
270
- $upload_dir = wp_upload_dir();
271
- $upload_path = trailingslashit( $upload_dir['basedir'] );
272
-
273
- // WordPress >= 2.6.2: determine the absolute $file_path (http://core.trac.wordpress.org/changeset/8796)
274
- if ( FALSE === strpos($file_path, $upload_path) ) {
275
- $store_absolute_path = false;
276
- $file_path = $upload_path . $file_path;
277
  }
278
 
279
- if ( $force_resmush || wp_smushit_should_resmush( @$meta['wp_smushit'] ) ) {
280
- list($file, $msg) = wp_smushit($file_path);
281
- $meta['wp_smushit'] = $msg;
282
- }
283
-
284
- // strip absolute path for Wordpress >= 2.6.2
285
- if ( FALSE === $store_absolute_path ) {
286
- $meta['file'] = str_replace($upload_path, '', $meta['file']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  }
288
 
289
- // no resized versions, so we can exit
290
- if ( !isset($meta['sizes']) )
291
- return $meta;
292
-
293
- // meta sizes don't contain a path, so we calculate one
294
- $base_dir = trailingslashit( dirname($file_path) );
295
 
296
- foreach($meta['sizes'] as $size => $data) {
297
- if ( !$force_resmush && wp_smushit_should_resmush( @$meta['sizes'][$size]['wp_smushit'] ) === FALSE ) {
298
- continue;
299
  }
300
 
301
- list($smushed_file, $results) = wp_smushit( $base_dir . wp_basename( $data['file'] ) );
302
- $meta['sizes'][$size]['wp_smushit'] = $results;
303
  }
304
- return $meta;
305
- }
306
 
307
 
308
- /**
309
- * Post an image to Smush.it.
310
- *
311
- * @param string $file_url URL of the file to send to Smush.it
312
- * @return string|boolean Returns the JSON response on success or else FALSE
313
- */
314
- function wp_smushit_post($file_url) {
315
- $req = sprintf( SMUSHIT_REQ_URL, urlencode( $file_url ) );
316
-
317
- $data = false;
318
-
319
- if ( function_exists('wp_remote_get') ) {
320
- $response = wp_remote_get($req, array('user-agent' => WP_SMUSHIT_UA, 'timeout' => WP_SMUSHIT_TIMEOUT));
321
- if ( !$response || is_wp_error($response)) {
322
- $data = FALSE;
323
- } else {
324
- $data = wp_remote_retrieve_body($response);
325
- }
326
- } else {
327
- wp_die( __('WP Smush.it requires WordPress 2.8 or greater', WP_SMUSHIT_DOMAIN) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
  }
329
 
330
- //$data = FALSE;
331
-
332
- return $data;
333
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
 
336
- /**
337
- * Print column header for Smush.it results in the media library using
338
- * the `manage_media_columns` hook.
339
- */
340
- function wp_smushit_columns($defaults) {
341
- $defaults['smushit'] = 'Smush.it';
342
- return $defaults;
343
- }
344
 
345
- /**
346
- * Return the filesize in a humanly readable format.
347
- * Taken from http://www.php.net/manual/en/function.filesize.php#91477
348
- */
349
- function wp_smushit_format_bytes($bytes, $precision = 2) {
350
- $units = array('B', 'KB', 'MB', 'GB', 'TB');
351
- $bytes = max($bytes, 0);
352
- $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
353
- $pow = min($pow, count($units) - 1);
354
- $bytes /= pow(1024, $pow);
355
- return round($bytes, $precision) . ' ' . $units[$pow];
356
- }
357
 
358
- /**
359
- * Print column data for Smush.it results in the media library using
360
- * the `manage_media_custom_column` hook.
361
- */
362
- function wp_smushit_custom_column($column_name, $id) {
363
- if( $column_name == 'smushit' ) {
364
- $data = wp_get_attachment_metadata($id);
365
- if ( isset($data['wp_smushit']) && !empty($data['wp_smushit']) ) {
366
- print $data['wp_smushit'];
367
- printf("<br><a href=\"admin.php?action=wp_smushit_manual&amp;attachment_ID=%d\">%s</a>",
368
- $id,
369
- __('Re-smush', WP_SMUSHIT_DOMAIN));
370
- } else {
371
- if ( wp_attachment_is_image( $id ) ) {
372
- print __('Not processed', WP_SMUSHIT_DOMAIN);
373
- printf("<br><a href=\"admin.php?action=wp_smushit_manual&amp;attachment_ID=%d\">%s</a>",
374
- $id,
375
- __('Smush.it now!', WP_SMUSHIT_DOMAIN));
376
- }
377
- }
378
- }
379
- }
380
 
381
- add_action( 'admin_head-upload.php', 'wp_smushit_add_bulk_actions_via_javascript' );
382
 
383
- // Borrowed from http://www.viper007bond.com/wordpress-plugins/regenerate-thumbnails/
384
- function wp_smushit_add_bulk_actions_via_javascript() { ?>
385
  <script type="text/javascript">
386
  jQuery(document).ready(function($){
387
  $('select[name^="action"] option:last-child').before('<option value="bulk_smushit">Bulk Smush.it</option>');
388
  });
389
  </script>
390
- <?php }
391
 
392
 
393
- add_action( 'admin_action_bulk_smushit', 'wp_smushit_bulk_action_handler' );
 
 
 
394
 
395
- // Handles the bulk actions POST
396
- // Borrowed from http://www.viper007bond.com/wordpress-plugins/regenerate-thumbnails/
397
- function wp_smushit_bulk_action_handler() {
398
- check_admin_referer( 'bulk-media' );
399
 
400
- if ( empty( $_REQUEST['media'] ) || ! is_array( $_REQUEST['media'] ) )
401
- return;
402
 
403
- $ids = implode( ',', array_map( 'intval', $_REQUEST['media'] ) );
 
 
 
 
 
404
 
 
 
405
 
406
- // Can't use wp_nonce_url() as it escapes HTML entities
407
- wp_redirect( add_query_arg( '_wpnonce', wp_create_nonce( 'wp-smushit-bulk' ), admin_url( 'upload.php?page=wp-smushit-bulk&goback=1&ids=' . $ids ) ) );
408
- exit();
409
  }
410
 
411
- if ( function_exists( 'wp_basename' ) === false ) {
412
- /**
413
- * Introduced in WP 3.1... this is copied verbatim from wp-includes/formatting.php.
414
- */
415
- function wp_basename( $path, $suffix = '' ) {
416
- return urldecode( basename( str_replace( '%2F', '/', urlencode( $path ) ), $suffix ) );
417
- }
418
  }
1
  <?php
2
  /*
3
  Plugin Name: WP Smush.it
4
+ Plugin URI: http://wordpress.org/extend/plugins/wp-smushit/
5
  Description: Reduce image file sizes and improve performance using the <a href="http://smush.it/">Smush.it</a> API within WordPress.
6
+ Author: WPMU DEV
7
+ Version: 1.6.5
8
+ Author URI: http://premium.wpmudev.org/
9
+ Textdomain: wp_smushit
10
  */
11
 
12
+ /*
13
+ This plugin was originally developed by Alex Dunae.
14
+ http://dialect.ca/
15
+ */
16
 
17
+ /*
18
+ Copyright 2007-2013 Incsub (http://incsub.com)
 
19
 
20
+ This program is free software; you can redistribute it and/or modify
21
+ it under the terms of the GNU General Public License (Version 2 - GPLv2) as published by
22
+ the Free Software Foundation.
 
 
23
 
24
+ This program is distributed in the hope that it will be useful,
25
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ GNU General Public License for more details.
28
 
29
+ You should have received a copy of the GNU General Public License
30
+ along with this program; if not, write to the Free Software
31
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32
+ */
33
 
34
+ if ( !class_exists( 'WpSmushit' ) ) {
 
 
35
 
36
+ class WpSmushit {
 
 
37
 
38
+ var $version = "1.6.5";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ /**
41
+ * Constructor
42
+ */
43
+ function WpSmushit( ) {
44
+ $this->__construct( );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
46
+ function __construct( ) {
47
+
48
+ if ( !function_exists( 'download_url' ) ) {
49
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
50
+ }
51
+
52
+ /**
53
+ * Constants
54
+ */
55
+ define( 'SMUSHIT_REQ_URL', 'http://www.smushit.com/ysmush.it/ws.php?img=%s' );
56
+ define( 'SMUSHIT_BASE_URL', 'http://www.smushit.com/' );
57
+
58
+ define( 'WP_SMUSHIT_DOMAIN', 'wp_smushit' );
59
+ define( 'WP_SMUSHIT_UA', "WP Smush.it/{$this->version} (+http://wordpress.org/extend/plugins/wp-smushit/)" );
60
+ define( 'WP_SMUSHIT_PLUGIN_DIR', dirname( plugin_basename(__FILE__) ) );
61
+ define( 'WP_SMUSHIT_MAX_BYTES', 1048576 );
62
+
63
+ // The number of images (including generated sizes) that can return errors before abandoning all hope.
64
+ // N.B. this doesn't work with the bulk uploader, since it creates a new HTTP request
65
+ // for each image. It does work with the bulk smusher, though.
66
+ define( 'WP_SMUSHIT_ERRORS_BEFORE_QUITTING', 3 * count( get_intermediate_image_sizes( ) ) );
67
+
68
+ define( 'WP_SMUSHIT_AUTO', intval( get_option( 'wp_smushit_smushit_auto', 0) ) );
69
+ define( 'WP_SMUSHIT_TIMEOUT', intval( get_option( 'wp_smushit_smushit_timeout', 60) ) );
70
+
71
+ /*
72
+ Each service has a setting specifying whether it should be used automatically on upload.
73
+ Values are:
74
+ -1 Don't use (until manually enabled via Media > Settings)
75
+ 0 Use automatically
76
+ n Any other number is a Unix timestamp indicating when the service can be used again
77
+ */
78
+
79
+ define('WP_SMUSHIT_AUTO_OK', 0);
80
+ define('WP_SMUSHIT_AUTO_NEVER', -1);
81
+
82
+ /**
83
+ * Hooks
84
+ */
85
+ if ( WP_SMUSHIT_AUTO == WP_SMUSHIT_AUTO_OK ) {
86
+ add_filter( 'wp_generate_attachment_metadata', array( &$this, 'resize_from_meta_data' ), 10, 2 );
87
+ }
88
+ add_filter( 'manage_media_columns', array( &$this, 'columns' ) );
89
+ add_action( 'manage_media_custom_column', array( &$this, 'custom_column' ), 10, 2 );
90
+ add_action( 'admin_init', array( &$this, 'admin_init' ) );
91
+ add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
92
+ add_action( 'admin_action_wp_smushit_manual', array( &$this, 'smushit_manual' ) );
93
+ add_action( 'admin_head-upload.php', array( &$this, 'add_bulk_actions_via_javascript' ) );
94
+ add_action( 'admin_action_bulk_smushit', array( &$this, 'bulk_action_handler' ) );
95
+ add_action( 'admin_init', array( &$this, 'register_settings' ) );
96
  }
97
+
98
+ /**
99
+ * Plugin setting functions
100
+ */
101
+ function register_settings( ) {
102
+ add_settings_section( 'wp_smushit_settings', 'WP Smush.it', array( &$this, 'settings_cb' ), 'media' );
103
+ add_settings_field( 'wp_smushit_smushit_auto', __( 'Use Smush.it on upload?', WP_SMUSHIT_DOMAIN ), array( &$this, 'render_auto_opts' ), 'media', 'wp_smushit_settings' );
104
+ add_settings_field( 'wp_smushit_smushit_timeout', __( 'How many seconds should we wait for a response from Smush.it?', WP_SMUSHIT_DOMAIN ), array( &$this, 'render_timeout_opts' ), 'media', 'wp_smushit_settings' );
105
+ register_setting( 'media', array( &$this, 'smushit_auto' ) );
106
+ register_setting( 'media', array( &$this, 'smushit_timeout' ) );
107
  }
108
 
109
+ function settings_cb( ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  }
111
 
112
+ function render_auto_opts( ) {
113
+ $key = 'wp_smushit_smushit_auto';
114
+ $val = intval( get_option( $key, WP_SMUSHIT_AUTO_OK ) );
115
+ printf( "<select name='%1\$s' id='%1\$s'>", esc_attr( $key ) );
116
+ echo '<option value=' . WP_SMUSHIT_AUTO_OK . ' ' . selected( WP_SMUSHIT_AUTO_OK, $val ) . '>'. __( 'Automatically process on upload', WP_SMUSHIT_DOMAIN ) . '</option>';
117
+ echo '<option value=' . WP_SMUSHIT_AUTO_NEVER . ' ' . selected( WP_SMUSHIT_AUTO_NEVER, $val ) . '>'. __( 'Do not process on upload', WP_SMUSHIT_DOMAIN ) . '</option>';
118
+
119
+ if ( $val > 0 ) {
120
+ printf( '<option value="%d" selected="selected">', $val ) .
121
+ printf( __( 'Temporarily disabled until %s', WP_SMUSHIT_DOMAIN ), date( 'M j, Y \a\t H:i', $val ) ).'</option>';
122
+ }
123
+ echo '</select>';
124
  }
125
 
126
+ function render_timeout_opts( $key ) {
127
+ $key = 'wp_smushit_smushit_timeout';
128
+ $val = intval( get_option( $key, WP_SMUSHIT_AUTO_OK ) );
129
+ printf( "<input type='text' name='%1\$s' id='%1\$s' value='%2\%d'>", esc_attr( $key ), intval( get_option( $key, 60 ) ) );
 
 
 
 
 
 
 
130
  }
131
 
132
+ // default is 6hrs
133
+ function temporarily_disable( $seconds = 21600 ) {
134
+ update_option( 'wp_smushit_smushit_auto', time() + $seconds );
135
+ }
136
+
137
+ function admin_init( ) {
138
+ load_plugin_textdomain( WP_SMUSHIT_DOMAIN );
139
+ wp_enqueue_script( 'common' );
140
  }
141
 
142
+ function admin_menu( ) {
143
+ add_media_page( 'Bulk Smush.it', 'Bulk Smush.it', 'edit_others_posts', 'wp-smushit-bulk', array( &$this, 'bulk_preview' ) );
 
 
 
 
 
144
  }
145
 
146
+ function bulk_preview( ) {
147
+ if ( function_exists( 'apache_setenv' ) ) {
148
+ @apache_setenv('no-gzip', 1);
149
+ }
150
+ @ini_set('output_buffering','on');
151
+ @ini_set('zlib.output_compression', 0);
152
+ @ini_set('implicit_flush', 1);
153
+
154
+ $attachments = null;
155
+ $auto_start = false;
156
+
157
+ if ( isset($_REQUEST['ids'] ) ) {
158
+ $attachments = get_posts( array(
159
+ 'numberposts' => -1,
160
+ 'include' => explode(',', $_REQUEST['ids']),
161
+ 'post_type' => 'attachment',
162
+ 'post_mime_type' => 'image'
163
+ ));
164
+ $auto_start = true;
165
+ } else {
166
+ $attachments = get_posts( array(
167
+ 'numberposts' => -1,
168
+ 'post_type' => 'attachment',
169
+ 'post_mime_type' => 'image'
170
+ ));
171
+ }
172
+ ?>
173
+ <div class="wrap">
174
+ <div id="icon-upload" class="icon32"><br /></div><h2><?php _e( 'Bulk WP Smush.it', WP_SMUSHIT_DOMAIN ) ?></h2>
175
+ <?php
176
+
177
+ if ( sizeof($attachments) < 1 ):
178
+ _e( '<p>You don�t appear to have uploaded any images yet.</p>', WP_SMUSHIT_DOMAIN );
179
+ else:
180
+ if ( empty($_POST) && !$auto_start ): // instructions page
181
+
182
+ _e( "<p>This tool will run all of the images in your media library through the WP Smush.it web service. It won't re-smush images that were successfully smushed before. It will retry images that were not successfully smushed.</p>", WP_SMUSHIT_DOMAIN );
183
+
184
+ _e( "<p>It uploads each and every file to Yahoo! and then downloads the resulting file. It can take a long time.</p>", WP_SMUSHIT_DOMAIN );
185
+
186
+ printf( __( "<p>We found %d images in your media library. Be forewarned, <strong>it will take <em>at least</em> %d minutes</strong> to process all these images if they have never been smushed before.</p>", WP_SMUSHIT_DOMAIN ), sizeof($attachments), sizeof($attachments) * 3 / 60 );
187
+
188
+ _e( "<p><em>N.B. If your server <tt>gzip</tt>s content you may not see the progress updates as your files are processed.</em></p>", WP_SMUSHIT_DOMAIN );
189
+
190
+ printf( __( "<p><strong>This is an experimental feature.</strong> Please post any feedback to the %s.</p>", WP_SMUSHIT_DOMAIN ), '<a href="http://wordpress.org/tags/wp-smushit">'. __( 'WordPress WP Smush.it forums', WP_SMUSHIT_DOMAIN ). '</a>' );
191
+ ?>
192
+ <form method="post" action="">
193
+ <?php wp_nonce_field( 'wp-smushit-bulk', '_wpnonce'); ?>
194
+ <button type="submit" class="button-secondary action"><?php _e( 'Run all my images through WP Smush.it right now', WP_SMUSHIT_DOMAIN ) ?></button>
195
+ </form>
196
+
197
+ <?php
198
+ else: // run the script
199
+
200
+ if ( !wp_verify_nonce( $_REQUEST['_wpnonce'], 'wp-smushit-bulk' ) || !current_user_can( 'edit_others_posts' ) ) {
201
+ wp_die( __( 'Cheatin&#8217; uh?' ) );
202
+ }
203
+
204
+
205
+ @ob_implicit_flush( true );
206
+ @ob_end_flush();
207
+ foreach( $attachments as $attachment ) {
208
+ printf( "<p>Processing <strong>%s</strong>&hellip;<br>", esc_html( $attachment->post_name ) );
209
+ $original_meta = wp_get_attachment_metadata( $attachment->ID, true );
210
+
211
+ $meta = $this->resize_from_meta_data( $original_meta, $attachment->ID, false );
212
+
213
+ printf( "� %dx%d: ", intval($meta['width']), intval($meta['height']) );
214
+
215
+ if ( $original_meta['wp_smushit'] == $meta['wp_smushit'] && stripos( $meta['wp_smushit'], 'Smush.it error' ) === false ) {
216
+ echo 'already smushed' . $meta['wp_smushit'];
217
+ } else {
218
+ echo $meta['wp_smushit'];
219
+ }
220
+ echo '<br>';
221
+
222
+ if ( isset( $meta['sizes'] ) && is_array( $meta['sizes'] ) ) {
223
+ foreach( $meta['sizes'] as $size_name => $size ) {
224
+ printf( "� %dx%d: ", intval($size['width']), intval($size['height']) );
225
+ if ( $original_meta['sizes'][$size_name]['wp_smushit'] == $size['wp_smushit'] && stripos( $meta['sizes'][$size_name]['wp_smushit'], 'Smush.it error' ) === false ) {
226
+ echo 'already smushed';
227
+ } else {
228
+ echo $size['wp_smushit'];
229
+ }
230
+ echo '<br>';
231
+ }
232
+ }
233
+ echo "</p>";
234
+
235
+ wp_update_attachment_metadata( $attachment->ID, $meta );
236
+
237
+ // rate limiting is good manners, let's be nice to Yahoo!
238
+ sleep(0.5);
239
+ @ob_flush();
240
+ flush();
241
+ }
242
+ endif;
243
+ endif;
244
+ ?>
245
+ </div>
246
+ <?php
247
  }
248
 
249
+ /**
250
+ * Manually process an image from the Media Library
251
+ */
252
+ function smushit_manual( ) {
253
+ if ( !current_user_can('upload_files') ) {
254
+ wp_die( __( 'You don\'t have permission to work with uploaded files.', WP_SMUSHIT_DOMAIN ) );
255
+ }
256
 
257
+ if ( !isset( $_GET['attachment_ID'] ) ) {
258
+ wp_die( __( 'No attachment ID was provided.', WP_SMUSHIT_DOMAIN ) );
259
+ }
 
 
 
260
 
261
+ $attachment_ID = intval( $_GET['attachment_ID'] );
262
 
263
+ $original_meta = wp_get_attachment_metadata( $attachment_ID );
 
 
264
 
265
+ $new_meta = $this->resize_from_meta_data( $original_meta, $attachment_ID );
266
+ wp_update_attachment_metadata( $attachment_ID, $new_meta );
 
267
 
268
+ wp_redirect( preg_replace( '|[^a-z0-9-~+_.?#=&;,/:]|i', '', wp_get_referer( ) ) );
269
+ exit();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  }
271
 
272
+ /**
273
+ * Process an image with Smush.it.
274
+ *
275
+ * Returns an array of the $file $results.
276
+ *
277
+ * @param string $file Full absolute path to the image file
278
+ * @param string $file_url Optional full URL to the image file
279
+ * @returns array
280
+ */
281
+ function do_smushit( $file, $file_url = null ) {
282
+ // don't run on localhost, IPv4 and IPv6 checks
283
+ // if( in_array($_SERVER['SERVER_ADDR'], array('127.0.0.1', '::1')) )
284
+ // return array($file, __('Not processed (local file)', WP_SMUSHIT_DOMAIN));
285
+
286
+ // canonicalize path - disabled 2011-02-1 troubleshooting 'Could not find...' errors.
287
+ // From the PHP docs: "The running script must have executable permissions on
288
+ // all directories in the hierarchy, otherwise realpath() will return false."
289
+ // $file_path = realpath($file);
290
+
291
+ static $error_count = 0;
292
+
293
+ if ( $error_count >= WP_SMUSHIT_ERRORS_BEFORE_QUITTING ) {
294
+ $msg = __( "Did not smush due to previous errors", WP_SMUSHIT_DOMAIN );
295
+ return array( $file, $msg );
296
+ }
297
+
298
+ $file_path = $file;
299
+ // check that the file exists
300
+ if ( !file_exists( $file_path ) || !is_file( $file_path ) ) {
301
+ $msg = sprintf( __( "Could not find <span class='code'>%s</span>", WP_SMUSHIT_DOMAIN ), $file_path );
302
+ return array( $file, $msg );
303
+ }
304
+
305
+ // check that the file is writable
306
+ if ( !is_writable( $file_path ) ) {
307
+ $msg = sprintf( __("<span class='code'>%s</span> is not writable", WP_SMUSHIT_DOMAIN ), $file_path );
308
+ return array( $file, $msg );
309
+ }
310
+
311
+ $file_size = filesize( $file_path );
312
+ if ( $file_size > WP_SMUSHIT_MAX_BYTES ) {
313
+ $msg = sprintf(__("<a href='http://developer.yahoo.com/yslow/smushit/faq.html#faq_restrict'>Too big</a> for Smush.it (%s)", WP_SMUSHIT_DOMAIN), $this->format_bytes($file_size));
314
+ return array( $file, $msg );
315
+ }
316
+
317
+ // check that the file is within the WP_CONTENT_DIR
318
+ $upload_dir = wp_upload_dir();
319
+ $wp_upload_dir = $upload_dir['basedir'];
320
+ $wp_upload_url = $upload_dir['baseurl'];
321
+ if ( 0 !== stripos(realpath($file_path), realpath(ABSPATH)) ) {
322
+ $msg = sprintf( __( "<span class='code'>%s</span> must be within the content directory (<span class='code'>%s</span>)",
323
+ WP_SMUSHIT_DOMAIN ), htmlentities( $file_path ), $wp_upload_dir);
324
+
325
+ return array($file, $msg);
326
+ }
327
+
328
+ if ( !$file_url ) {
329
+ // determine the public URL
330
+ $file_url = str_replace( $wp_upload_dir, $wp_upload_url, $file );
331
+ }
332
+
333
+ $data = $this->_post( $file_url );
334
+
335
+ if ( false === $data ) {
336
+ $error_count++;
337
+ return array( $file, __( 'Error posting to Smush.it', WP_SMUSHIT_DOMAIN ) );
338
+ }
339
+
340
+ // make sure the response looks like JSON -- added 2008-12-19 when
341
+ // Smush.it was returning PHP warnings before the JSON output
342
+ if ( strpos( trim($data), '{' ) != 0 ) {
343
+ return array( $file, __('Bad response from Smush.it', WP_SMUSHIT_DOMAIN ) );
344
+ }
345
+
346
+ // read the JSON response
347
+ if ( function_exists('json_decode') ) {
348
+ $data = json_decode( $data );
349
+ } else {
350
+ require_once( 'JSON/JSON.php' );
351
+ $json = new Services_JSON( );
352
+ $data = $json->decode( $data );
353
+ }
354
+
355
+ if ( !isset( $data->dest_size ) )
356
+ return array( $file, __('Bad response from Smush.it', WP_SMUSHIT_DOMAIN ) );
357
+
358
+ if ( -1 === intval( $data->dest_size ) )
359
+ return array( $file, __('No savings', WP_SMUSHIT_DOMAIN ) );
360
+
361
+ if ( !isset( $data->dest ) ) {
362
+ $err = ( $data->error ? __( 'Smush.it error: ', WP_SMUSHIT_DOMAIN ) . $data->error : __( 'unknown error', WP_SMUSHIT_DOMAIN ) );
363
+ $err .= sprintf( __( " while processing <span class='code'>%s</span> (<span class='code'>%s</span>)", WP_SMUSHIT_DOMAIN ), $file_url, $file_path);
364
+ return array( $file, $err );
365
+ }
366
+
367
+ $processed_url = $data->dest;
368
+
369
+ // The smush.it web service does not append the domain;
370
+ // smushit.com web service does
371
+ if ( 0 !== stripos($processed_url, 'http://') ) {
372
+ $processed_url = SMUSHIT_BASE_URL . $processed_url;
373
+ }
374
+
375
+ $temp_file = download_url( $processed_url );
376
+
377
+ if ( is_wp_error( $temp_file ) ) {
378
+ @unlink($tmp);
379
+ $results_msg = sprintf( __("Error downloading file (%s)", WP_SMUSHIT_DOMAIN ),
380
+ $temp_file->get_error_message());
381
+ return array($file, $results_msg );
382
+ }
383
+
384
+ @rename( $temp_file, $file_path );
385
+
386
+ $savings = intval( $data->src_size ) - intval( $data->dest_size );
387
+ $savings_str = $this->format_bytes( $savings, 1 );
388
+ $savings_str = str_replace( ' ', '&nbsp;', $savings_str );
389
+
390
+ $results_msg = sprintf( __("Reduced by %01.1f%% (%s)", WP_SMUSHIT_DOMAIN ),
391
+ $data->percent,
392
+ $savings_str );
393
+
394
+ return array( $file, $results_msg );
395
  }
396
 
397
+ function should_resmush($previous_status) {
398
+ if ( !$previous_status || empty($previous_status ) ) {
399
+ return true;
400
+ }
 
 
401
 
402
+ if ( stripos( $previous_status, 'no savings' ) !== false || stripos( $previous_status, 'reduced' ) !== false ) {
403
+ return false;
 
404
  }
405
 
406
+ // otherwise an error
407
+ return true;
408
  }
 
 
409
 
410
 
411
+ /**
412
+ * Read the image paths from an attachment's meta data and process each image
413
+ * with wp_smushit().
414
+ *
415
+ * This method also adds a `wp_smushit` meta key for use in the media library.
416
+ *
417
+ * Called after `wp_generate_attachment_metadata` is completed.
418
+ */
419
+ function resize_from_meta_data( $meta, $ID = null, $force_resmush = true ) {
420
+ if ( $ID && wp_attachment_is_image( $ID ) === false ) {
421
+ return $meta;
422
+ }
423
+
424
+ $file_path = $meta['file'];
425
+ $store_absolute_path = true;
426
+ $upload_dir = wp_upload_dir();
427
+ $upload_path = trailingslashit( $upload_dir['basedir'] );
428
+
429
+ // WordPress >= 2.6.2: determine the absolute $file_path (http://core.trac.wordpress.org/changeset/8796)
430
+ if ( false === strpos($file_path, $upload_path) ) {
431
+ $store_absolute_path = false;
432
+ $file_path = $upload_path . $file_path;
433
+ }
434
+
435
+ if ( $force_resmush || $this->should_resmush( @$meta['wp_smushit'] ) ) {
436
+ list($file, $msg) = $this->do_smushit($file_path);
437
+ $meta['wp_smushit'] = $msg;
438
+ }
439
+
440
+ // strip absolute path for Wordpress >= 2.6.2
441
+ if ( false === $store_absolute_path ) {
442
+ $meta['file'] = str_replace($upload_path, '', $meta['file']);
443
+ }
444
+
445
+ // no resized versions, so we can exit
446
+ if ( !isset( $meta['sizes'] ) )
447
+ return $meta;
448
+
449
+ // meta sizes don't contain a path, so we calculate one
450
+ $base_dir = trailingslashit( dirname($file_path) );
451
+
452
+ foreach($meta['sizes'] as $size => $data) {
453
+ if ( !$force_resmush && $this->should_resmush( @$meta['sizes'][$size]['wp_smushit'] ) === false ) {
454
+ continue;
455
+ }
456
+
457
+ list($smushed_file, $results) = $this->do_smushit( $base_dir . wp_basename( $data['file'] ) );
458
+ $meta['sizes'][$size]['wp_smushit'] = $results;
459
+ }
460
+ return $meta;
461
  }
462
 
463
+ /**
464
+ * Post an image to Smush.it.
465
+ *
466
+ * @param string $file_url URL of the file to send to Smush.it
467
+ * @return string|boolean Returns the JSON response on success or else false
468
+ */
469
+ function _post( $file_url ) {
470
+ $req = sprintf( SMUSHIT_REQ_URL, urlencode( $file_url ) );
471
+
472
+ $data = false;
473
+
474
+ if ( function_exists( 'wp_remote_get' ) ) {
475
+ $response = wp_remote_get( $req, array('user-agent' => WP_SMUSHIT_UA, 'timeout' => WP_SMUSHIT_TIMEOUT ) );
476
+ if ( !$response || is_wp_error( $response ) ) {
477
+ $data = false;
478
+ } else {
479
+ $data = wp_remote_retrieve_body( $response );
480
+ }
481
+ } else {
482
+ wp_die( __('WP Smush.it requires WordPress 2.8 or greater', WP_SMUSHIT_DOMAIN) );
483
+ }
484
+
485
+ return $data;
486
+ }
487
 
488
 
489
+ /**
490
+ * Print column header for Smush.it results in the media library using
491
+ * the `manage_media_columns` hook.
492
+ */
493
+ function columns( $defaults ) {
494
+ $defaults['smushit'] = 'Smush.it';
495
+ return $defaults;
496
+ }
497
 
498
+ /**
499
+ * Return the filesize in a humanly readable format.
500
+ * Taken from http://www.php.net/manual/en/function.filesize.php#91477
501
+ */
502
+ function format_bytes( $bytes, $precision = 2 ) {
503
+ $units = array('B', 'KB', 'MB', 'GB', 'TB');
504
+ $bytes = max($bytes, 0);
505
+ $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
506
+ $pow = min($pow, count($units) - 1);
507
+ $bytes /= pow(1024, $pow);
508
+ return round($bytes, $precision) . ' ' . $units[$pow];
509
+ }
510
 
511
+ /**
512
+ * Print column data for Smush.it results in the media library using
513
+ * the `manage_media_custom_column` hook.
514
+ */
515
+ function custom_column( $column_name, $id ) {
516
+ if( 'smushit' == $column_name ) {
517
+ $data = wp_get_attachment_metadata($id);
518
+ if ( isset( $data['wp_smushit'] ) && !empty( $data['wp_smushit'] ) ) {
519
+ print $data['wp_smushit'];
520
+ printf( "<br><a href=\"admin.php?action=wp_smushit_manual&amp;attachment_ID=%d\">%s</a>",
521
+ $id,
522
+ __( 'Re-smush', WP_SMUSHIT_DOMAIN ) );
523
+ } else {
524
+ if ( wp_attachment_is_image( $id ) ) {
525
+ print __( 'Not processed', WP_SMUSHIT_DOMAIN );
526
+ printf( "<br><a href=\"admin.php?action=wp_smushit_manual&amp;attachment_ID=%d\">%s</a>",
527
+ $id,
528
+ __('Smush.it now!', WP_SMUSHIT_DOMAIN));
529
+ }
530
+ }
531
+ }
532
+ }
533
 
 
534
 
535
+ // Borrowed from http://www.viper007bond.com/wordpress-plugins/regenerate-thumbnails/
536
+ function add_bulk_actions_via_javascript() { ?>
537
  <script type="text/javascript">
538
  jQuery(document).ready(function($){
539
  $('select[name^="action"] option:last-child').before('<option value="bulk_smushit">Bulk Smush.it</option>');
540
  });
541
  </script>
542
+ <?php }
543
 
544
 
545
+ // Handles the bulk actions POST
546
+ // Borrowed from http://www.viper007bond.com/wordpress-plugins/regenerate-thumbnails/
547
+ function bulk_action_handler() {
548
+ check_admin_referer( 'bulk-media' );
549
 
550
+ if ( empty( $_REQUEST['media'] ) || ! is_array( $_REQUEST['media'] ) )
551
+ return;
 
 
552
 
553
+ $ids = implode( ',', array_map( 'intval', $_REQUEST['media'] ) );
 
554
 
555
+ // Can't use wp_nonce_url() as it escapes HTML entities
556
+ wp_redirect( add_query_arg( '_wpnonce', wp_create_nonce( 'wp-smushit-bulk' ), admin_url( 'upload.php?page=wp-smushit-bulk&goback=1&ids=' . $ids ) ) );
557
+ exit();
558
+ }
559
+
560
+ }
561
 
562
+ $WpSmushit = new WpSmushit();
563
+ global $WpSmushit;
564
 
 
 
 
565
  }
566
 
567
+ if ( !function_exists( 'wp_basename' ) ) {
568
+ /**
569
+ * Introduced in WP 3.1... this is copied verbatim from wp-includes/formatting.php.
570
+ */
571
+ function wp_basename( $path, $suffix = '' ) {
572
+ return urldecode( basename( str_replace( '%2F', '/', urlencode( $path ) ), $suffix ) );
573
+ }
574
  }