Smush Image Compression and Optimization - Version 2.0

Version Description

  • Complete rewrite to use WPMU DEV's new fast and reliable API service.
  • New: One-click bulk smushing of all your images.
  • New: "Super-Smush" your images with our intelligent multi-pass lossy compression. Get >60% average compression with almost no noticeable quality loss! (Pro)
  • New: Keep a backup of your original un-smushed images in case you want to restore later. (Pro)
  • UX/UI updated with overall stats, progress bar.
Download this release

Release Info

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

Code changes from version 1.7.1.1 to 2.0

JSON/JSON.php DELETED
@@ -1,806 +0,0 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Converts to and from JSON format.
6
- *
7
- * JSON (JavaScript Object Notation) is a lightweight data-interchange
8
- * format. It is easy for humans to read and write. It is easy for machines
9
- * to parse and generate. It is based on a subset of the JavaScript
10
- * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
11
- * This feature can also be found in Python. JSON is a text format that is
12
- * completely language independent but uses conventions that are familiar
13
- * to programmers of the C-family of languages, including C, C++, C#, Java,
14
- * JavaScript, Perl, TCL, and many others. These properties make JSON an
15
- * ideal data-interchange language.
16
- *
17
- * This package provides a simple encoder and decoder for JSON notation. It
18
- * is intended for use with client-side Javascript applications that make
19
- * use of HTTPRequest to perform server communication functions - data can
20
- * be encoded into JSON notation for use in a client-side javascript, or
21
- * decoded from incoming Javascript requests. JSON format is native to
22
- * Javascript, and can be directly eval()'ed with no further parsing
23
- * overhead
24
- *
25
- * All strings should be in ASCII or UTF-8 format!
26
- *
27
- * LICENSE: Redistribution and use in source and binary forms, with or
28
- * without modification, are permitted provided that the following
29
- * conditions are met: Redistributions of source code must retain the
30
- * above copyright notice, this list of conditions and the following
31
- * disclaimer. Redistributions in binary form must reproduce the above
32
- * copyright notice, this list of conditions and the following disclaimer
33
- * in the documentation and/or other materials provided with the
34
- * distribution.
35
- *
36
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
37
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
38
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
39
- * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
40
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
41
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
42
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
45
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
46
- * DAMAGE.
47
- *
48
- * @category
49
- * @package Services_JSON
50
- * @author Michal Migurski <mike-json@teczno.com>
51
- * @author Matt Knapp <mdknapp[at]gmail[dot]com>
52
- * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
53
- * @copyright 2005 Michal Migurski
54
- * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
55
- * @license http://www.opensource.org/licenses/bsd-license.php
56
- * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
57
- */
58
-
59
- /**
60
- * Marker constant for Services_JSON::decode(), used to flag stack state
61
- */
62
- define('SERVICES_JSON_SLICE', 1);
63
-
64
- /**
65
- * Marker constant for Services_JSON::decode(), used to flag stack state
66
- */
67
- define('SERVICES_JSON_IN_STR', 2);
68
-
69
- /**
70
- * Marker constant for Services_JSON::decode(), used to flag stack state
71
- */
72
- define('SERVICES_JSON_IN_ARR', 3);
73
-
74
- /**
75
- * Marker constant for Services_JSON::decode(), used to flag stack state
76
- */
77
- define('SERVICES_JSON_IN_OBJ', 4);
78
-
79
- /**
80
- * Marker constant for Services_JSON::decode(), used to flag stack state
81
- */
82
- define('SERVICES_JSON_IN_CMT', 5);
83
-
84
- /**
85
- * Behavior switch for Services_JSON::decode()
86
- */
87
- define('SERVICES_JSON_LOOSE_TYPE', 16);
88
-
89
- /**
90
- * Behavior switch for Services_JSON::decode()
91
- */
92
- define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
93
-
94
- /**
95
- * Converts to and from JSON format.
96
- *
97
- * Brief example of use:
98
- *
99
- * <code>
100
- * // create a new instance of Services_JSON
101
- * $json = new Services_JSON();
102
- *
103
- * // convert a complexe value to JSON notation, and send it to the browser
104
- * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
105
- * $output = $json->encode($value);
106
- *
107
- * print($output);
108
- * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
109
- *
110
- * // accept incoming POST data, assumed to be in JSON notation
111
- * $input = file_get_contents('php://input', 1000000);
112
- * $value = $json->decode($input);
113
- * </code>
114
- */
115
- class Services_JSON
116
- {
117
- /**
118
- * constructs a new JSON instance
119
- *
120
- * @param int $use object behavior flags; combine with boolean-OR
121
- *
122
- * possible values:
123
- * - SERVICES_JSON_LOOSE_TYPE: loose typing.
124
- * "{...}" syntax creates associative arrays
125
- * instead of objects in decode().
126
- * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
127
- * Values which can't be encoded (e.g. resources)
128
- * appear as NULL instead of throwing errors.
129
- * By default, a deeply-nested resource will
130
- * bubble up with an error, so all return values
131
- * from encode() should be checked with isError()
132
- */
133
- function Services_JSON($use = 0)
134
- {
135
- $this->use = $use;
136
- }
137
-
138
- /**
139
- * convert a string from one UTF-16 char to one UTF-8 char
140
- *
141
- * Normally should be handled by mb_convert_encoding, but
142
- * provides a slower PHP-only method for installations
143
- * that lack the multibye string extension.
144
- *
145
- * @param string $utf16 UTF-16 character
146
- * @return string UTF-8 character
147
- * @access private
148
- */
149
- function utf162utf8($utf16)
150
- {
151
- // oh please oh please oh please oh please oh please
152
- if(function_exists('mb_convert_encoding')) {
153
- return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
154
- }
155
-
156
- $bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
157
-
158
- switch(true) {
159
- case ((0x7F & $bytes) == $bytes):
160
- // this case should never be reached, because we are in ASCII range
161
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
162
- return chr(0x7F & $bytes);
163
-
164
- case (0x07FF & $bytes) == $bytes:
165
- // return a 2-byte UTF-8 character
166
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
167
- return chr(0xC0 | (($bytes >> 6) & 0x1F))
168
- . chr(0x80 | ($bytes & 0x3F));
169
-
170
- case (0xFFFF & $bytes) == $bytes:
171
- // return a 3-byte UTF-8 character
172
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
173
- return chr(0xE0 | (($bytes >> 12) & 0x0F))
174
- . chr(0x80 | (($bytes >> 6) & 0x3F))
175
- . chr(0x80 | ($bytes & 0x3F));
176
- }
177
-
178
- // ignoring UTF-32 for now, sorry
179
- return '';
180
- }
181
-
182
- /**
183
- * convert a string from one UTF-8 char to one UTF-16 char
184
- *
185
- * Normally should be handled by mb_convert_encoding, but
186
- * provides a slower PHP-only method for installations
187
- * that lack the multibye string extension.
188
- *
189
- * @param string $utf8 UTF-8 character
190
- * @return string UTF-16 character
191
- * @access private
192
- */
193
- function utf82utf16($utf8)
194
- {
195
- // oh please oh please oh please oh please oh please
196
- if(function_exists('mb_convert_encoding')) {
197
- return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
198
- }
199
-
200
- switch(strlen($utf8)) {
201
- case 1:
202
- // this case should never be reached, because we are in ASCII range
203
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
204
- return $utf8;
205
-
206
- case 2:
207
- // return a UTF-16 character from a 2-byte UTF-8 char
208
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
209
- return chr(0x07 & (ord($utf8{0}) >> 2))
210
- . chr((0xC0 & (ord($utf8{0}) << 6))
211
- | (0x3F & ord($utf8{1})));
212
-
213
- case 3:
214
- // return a UTF-16 character from a 3-byte UTF-8 char
215
- // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
216
- return chr((0xF0 & (ord($utf8{0}) << 4))
217
- | (0x0F & (ord($utf8{1}) >> 2)))
218
- . chr((0xC0 & (ord($utf8{1}) << 6))
219
- | (0x7F & ord($utf8{2})));
220
- }
221
-
222
- // ignoring UTF-32 for now, sorry
223
- return '';
224
- }
225
-
226
- /**
227
- * encodes an arbitrary variable into JSON format
228
- *
229
- * @param mixed $var any number, boolean, string, array, or object to be encoded.
230
- * see argument 1 to Services_JSON() above for array-parsing behavior.
231
- * if var is a strng, note that encode() always expects it
232
- * to be in ASCII or UTF-8 format!
233
- *
234
- * @return mixed JSON string representation of input var or an error if a problem occurs
235
- * @access public
236
- */
237
- function encode($var)
238
- {
239
- switch (gettype($var)) {
240
- case 'boolean':
241
- return $var ? 'true' : 'false';
242
-
243
- case 'NULL':
244
- return 'null';
245
-
246
- case 'integer':
247
- return (int) $var;
248
-
249
- case 'double':
250
- case 'float':
251
- return (float) $var;
252
-
253
- case 'string':
254
- // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
255
- $ascii = '';
256
- $strlen_var = strlen($var);
257
-
258
- /*
259
- * Iterate over every character in the string,
260
- * escaping with a slash or encoding to UTF-8 where necessary
261
- */
262
- for ($c = 0; $c < $strlen_var; ++$c) {
263
-
264
- $ord_var_c = ord($var{$c});
265
-
266
- switch (true) {
267
- case $ord_var_c == 0x08:
268
- $ascii .= '\b';
269
- break;
270
- case $ord_var_c == 0x09:
271
- $ascii .= '\t';
272
- break;
273
- case $ord_var_c == 0x0A:
274
- $ascii .= '\n';
275
- break;
276
- case $ord_var_c == 0x0C:
277
- $ascii .= '\f';
278
- break;
279
- case $ord_var_c == 0x0D:
280
- $ascii .= '\r';
281
- break;
282
-
283
- case $ord_var_c == 0x22:
284
- case $ord_var_c == 0x2F:
285
- case $ord_var_c == 0x5C:
286
- // double quote, slash, slosh
287
- $ascii .= '\\'.$var{$c};
288
- break;
289
-
290
- case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
291
- // characters U-00000000 - U-0000007F (same as ASCII)
292
- $ascii .= $var{$c};
293
- break;
294
-
295
- case (($ord_var_c & 0xE0) == 0xC0):
296
- // characters U-00000080 - U-000007FF, mask 110XXXXX
297
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
298
- $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
299
- $c += 1;
300
- $utf16 = $this->utf82utf16($char);
301
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
302
- break;
303
-
304
- case (($ord_var_c & 0xF0) == 0xE0):
305
- // characters U-00000800 - U-0000FFFF, mask 1110XXXX
306
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
307
- $char = pack('C*', $ord_var_c,
308
- ord($var{$c + 1}),
309
- ord($var{$c + 2}));
310
- $c += 2;
311
- $utf16 = $this->utf82utf16($char);
312
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
313
- break;
314
-
315
- case (($ord_var_c & 0xF8) == 0xF0):
316
- // characters U-00010000 - U-001FFFFF, mask 11110XXX
317
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
318
- $char = pack('C*', $ord_var_c,
319
- ord($var{$c + 1}),
320
- ord($var{$c + 2}),
321
- ord($var{$c + 3}));
322
- $c += 3;
323
- $utf16 = $this->utf82utf16($char);
324
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
325
- break;
326
-
327
- case (($ord_var_c & 0xFC) == 0xF8):
328
- // characters U-00200000 - U-03FFFFFF, mask 111110XX
329
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
330
- $char = pack('C*', $ord_var_c,
331
- ord($var{$c + 1}),
332
- ord($var{$c + 2}),
333
- ord($var{$c + 3}),
334
- ord($var{$c + 4}));
335
- $c += 4;
336
- $utf16 = $this->utf82utf16($char);
337
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
338
- break;
339
-
340
- case (($ord_var_c & 0xFE) == 0xFC):
341
- // characters U-04000000 - U-7FFFFFFF, mask 1111110X
342
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
343
- $char = pack('C*', $ord_var_c,
344
- ord($var{$c + 1}),
345
- ord($var{$c + 2}),
346
- ord($var{$c + 3}),
347
- ord($var{$c + 4}),
348
- ord($var{$c + 5}));
349
- $c += 5;
350
- $utf16 = $this->utf82utf16($char);
351
- $ascii .= sprintf('\u%04s', bin2hex($utf16));
352
- break;
353
- }
354
- }
355
-
356
- return '"'.$ascii.'"';
357
-
358
- case 'array':
359
- /*
360
- * As per JSON spec if any array key is not an integer
361
- * we must treat the the whole array as an object. We
362
- * also try to catch a sparsely populated associative
363
- * array with numeric keys here because some JS engines
364
- * will create an array with empty indexes up to
365
- * max_index which can cause memory issues and because
366
- * the keys, which may be relevant, will be remapped
367
- * otherwise.
368
- *
369
- * As per the ECMA and JSON specification an object may
370
- * have any string as a property. Unfortunately due to
371
- * a hole in the ECMA specification if the key is a
372
- * ECMA reserved word or starts with a digit the
373
- * parameter is only accessible using ECMAScript's
374
- * bracket notation.
375
- */
376
-
377
- // treat as a JSON object
378
- if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
379
- $properties = array_map(array($this, 'name_value'),
380
- array_keys($var),
381
- array_values($var));
382
-
383
- foreach($properties as $property) {
384
- if(Services_JSON::isError($property)) {
385
- return $property;
386
- }
387
- }
388
-
389
- return '{' . join(',', $properties) . '}';
390
- }
391
-
392
- // treat it like a regular array
393
- $elements = array_map(array($this, 'encode'), $var);
394
-
395
- foreach($elements as $element) {
396
- if(Services_JSON::isError($element)) {
397
- return $element;
398
- }
399
- }
400
-
401
- return '[' . join(',', $elements) . ']';
402
-
403
- case 'object':
404
- $vars = get_object_vars($var);
405
-
406
- $properties = array_map(array($this, 'name_value'),
407
- array_keys($vars),
408
- array_values($vars));
409
-
410
- foreach($properties as $property) {
411
- if(Services_JSON::isError($property)) {
412
- return $property;
413
- }
414
- }
415
-
416
- return '{' . join(',', $properties) . '}';
417
-
418
- default:
419
- return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
420
- ? 'null'
421
- : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
422
- }
423
- }
424
-
425
- /**
426
- * array-walking function for use in generating JSON-formatted name-value pairs
427
- *
428
- * @param string $name name of key to use
429
- * @param mixed $value reference to an array element to be encoded
430
- *
431
- * @return string JSON-formatted name-value pair, like '"name":value'
432
- * @access private
433
- */
434
- function name_value($name, $value)
435
- {
436
- $encoded_value = $this->encode($value);
437
-
438
- if(Services_JSON::isError($encoded_value)) {
439
- return $encoded_value;
440
- }
441
-
442
- return $this->encode(strval($name)) . ':' . $encoded_value;
443
- }
444
-
445
- /**
446
- * reduce a string by removing leading and trailing comments and whitespace
447
- *
448
- * @param $str string string value to strip of comments and whitespace
449
- *
450
- * @return string string value stripped of comments and whitespace
451
- * @access private
452
- */
453
- function reduce_string($str)
454
- {
455
- $str = preg_replace(array(
456
-
457
- // eliminate single line comments in '// ...' form
458
- '#^\s*//(.+)$#m',
459
-
460
- // eliminate multi-line comments in '/* ... */' form, at start of string
461
- '#^\s*/\*(.+)\*/#Us',
462
-
463
- // eliminate multi-line comments in '/* ... */' form, at end of string
464
- '#/\*(.+)\*/\s*$#Us'
465
-
466
- ), '', $str);
467
-
468
- // eliminate extraneous space
469
- return trim($str);
470
- }
471
-
472
- /**
473
- * decodes a JSON string into appropriate variable
474
- *
475
- * @param string $str JSON-formatted string
476
- *
477
- * @return mixed number, boolean, string, array, or object
478
- * corresponding to given JSON input string.
479
- * See argument 1 to Services_JSON() above for object-output behavior.
480
- * Note that decode() always returns strings
481
- * in ASCII or UTF-8 format!
482
- * @access public
483
- */
484
- function decode($str)
485
- {
486
- $str = $this->reduce_string($str);
487
-
488
- switch (strtolower($str)) {
489
- case 'true':
490
- return true;
491
-
492
- case 'false':
493
- return false;
494
-
495
- case 'null':
496
- return null;
497
-
498
- default:
499
- $m = array();
500
-
501
- if (is_numeric($str)) {
502
- // Lookie-loo, it's a number
503
-
504
- // This would work on its own, but I'm trying to be
505
- // good about returning integers where appropriate:
506
- // return (float)$str;
507
-
508
- // Return float or int, as appropriate
509
- return ((float)$str == (integer)$str)
510
- ? (integer)$str
511
- : (float)$str;
512
-
513
- } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
514
- // STRINGS RETURNED IN UTF-8 FORMAT
515
- $delim = substr($str, 0, 1);
516
- $chrs = substr($str, 1, -1);
517
- $utf8 = '';
518
- $strlen_chrs = strlen($chrs);
519
-
520
- for ($c = 0; $c < $strlen_chrs; ++$c) {
521
-
522
- $substr_chrs_c_2 = substr($chrs, $c, 2);
523
- $ord_chrs_c = ord($chrs{$c});
524
-
525
- switch (true) {
526
- case $substr_chrs_c_2 == '\b':
527
- $utf8 .= chr(0x08);
528
- ++$c;
529
- break;
530
- case $substr_chrs_c_2 == '\t':
531
- $utf8 .= chr(0x09);
532
- ++$c;
533
- break;
534
- case $substr_chrs_c_2 == '\n':
535
- $utf8 .= chr(0x0A);
536
- ++$c;
537
- break;
538
- case $substr_chrs_c_2 == '\f':
539
- $utf8 .= chr(0x0C);
540
- ++$c;
541
- break;
542
- case $substr_chrs_c_2 == '\r':
543
- $utf8 .= chr(0x0D);
544
- ++$c;
545
- break;
546
-
547
- case $substr_chrs_c_2 == '\\"':
548
- case $substr_chrs_c_2 == '\\\'':
549
- case $substr_chrs_c_2 == '\\\\':
550
- case $substr_chrs_c_2 == '\\/':
551
- if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
552
- ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
553
- $utf8 .= $chrs{++$c};
554
- }
555
- break;
556
-
557
- case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
558
- // single, escaped unicode character
559
- $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
560
- . chr(hexdec(substr($chrs, ($c + 4), 2)));
561
- $utf8 .= $this->utf162utf8($utf16);
562
- $c += 5;
563
- break;
564
-
565
- case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
566
- $utf8 .= $chrs{$c};
567
- break;
568
-
569
- case ($ord_chrs_c & 0xE0) == 0xC0:
570
- // characters U-00000080 - U-000007FF, mask 110XXXXX
571
- //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
572
- $utf8 .= substr($chrs, $c, 2);
573
- ++$c;
574
- break;
575
-
576
- case ($ord_chrs_c & 0xF0) == 0xE0:
577
- // characters U-00000800 - U-0000FFFF, mask 1110XXXX
578
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
579
- $utf8 .= substr($chrs, $c, 3);
580
- $c += 2;
581
- break;
582
-
583
- case ($ord_chrs_c & 0xF8) == 0xF0:
584
- // characters U-00010000 - U-001FFFFF, mask 11110XXX
585
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
586
- $utf8 .= substr($chrs, $c, 4);
587
- $c += 3;
588
- break;
589
-
590
- case ($ord_chrs_c & 0xFC) == 0xF8:
591
- // characters U-00200000 - U-03FFFFFF, mask 111110XX
592
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
593
- $utf8 .= substr($chrs, $c, 5);
594
- $c += 4;
595
- break;
596
-
597
- case ($ord_chrs_c & 0xFE) == 0xFC:
598
- // characters U-04000000 - U-7FFFFFFF, mask 1111110X
599
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
600
- $utf8 .= substr($chrs, $c, 6);
601
- $c += 5;
602
- break;
603
-
604
- }
605
-
606
- }
607
-
608
- return $utf8;
609
-
610
- } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
611
- // array, or object notation
612
-
613
- if ($str{0} == '[') {
614
- $stk = array(SERVICES_JSON_IN_ARR);
615
- $arr = array();
616
- } else {
617
- if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
618
- $stk = array(SERVICES_JSON_IN_OBJ);
619
- $obj = array();
620
- } else {
621
- $stk = array(SERVICES_JSON_IN_OBJ);
622
- $obj = new stdClass();
623
- }
624
- }
625
-
626
- array_push($stk, array('what' => SERVICES_JSON_SLICE,
627
- 'where' => 0,
628
- 'delim' => false));
629
-
630
- $chrs = substr($str, 1, -1);
631
- $chrs = $this->reduce_string($chrs);
632
-
633
- if ($chrs == '') {
634
- if (reset($stk) == SERVICES_JSON_IN_ARR) {
635
- return $arr;
636
-
637
- } else {
638
- return $obj;
639
-
640
- }
641
- }
642
-
643
- //print("\nparsing {$chrs}\n");
644
-
645
- $strlen_chrs = strlen($chrs);
646
-
647
- for ($c = 0; $c <= $strlen_chrs; ++$c) {
648
-
649
- $top = end($stk);
650
- $substr_chrs_c_2 = substr($chrs, $c, 2);
651
-
652
- if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
653
- // found a comma that is not inside a string, array, etc.,
654
- // OR we've reached the end of the character list
655
- $slice = substr($chrs, $top['where'], ($c - $top['where']));
656
- array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
657
- //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
658
-
659
- if (reset($stk) == SERVICES_JSON_IN_ARR) {
660
- // we are in an array, so just push an element onto the stack
661
- array_push($arr, $this->decode($slice));
662
-
663
- } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
664
- // we are in an object, so figure
665
- // out the property name and set an
666
- // element in an associative array,
667
- // for now
668
- $parts = array();
669
-
670
- if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
671
- // "name":value pair
672
- $key = $this->decode($parts[1]);
673
- $val = $this->decode($parts[2]);
674
-
675
- if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
676
- $obj[$key] = $val;
677
- } else {
678
- $obj->$key = $val;
679
- }
680
- } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
681
- // name:value pair, where name is unquoted
682
- $key = $parts[1];
683
- $val = $this->decode($parts[2]);
684
-
685
- if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
686
- $obj[$key] = $val;
687
- } else {
688
- $obj->$key = $val;
689
- }
690
- }
691
-
692
- }
693
-
694
- } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
695
- // found a quote, and we are not inside a string
696
- array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
697
- //print("Found start of string at {$c}\n");
698
-
699
- } elseif (($chrs{$c} == $top['delim']) &&
700
- ($top['what'] == SERVICES_JSON_IN_STR) &&
701
- ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
702
- // found a quote, we're in a string, and it's not escaped
703
- // we know that it's not escaped becase there is _not_ an
704
- // odd number of backslashes at the end of the string so far
705
- array_pop($stk);
706
- //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
707
-
708
- } elseif (($chrs{$c} == '[') &&
709
- in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
710
- // found a left-bracket, and we are in an array, object, or slice
711
- array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
712
- //print("Found start of array at {$c}\n");
713
-
714
- } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
715
- // found a right-bracket, and we're in an array
716
- array_pop($stk);
717
- //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
718
-
719
- } elseif (($chrs{$c} == '{') &&
720
- in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
721
- // found a left-brace, and we are in an array, object, or slice
722
- array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
723
- //print("Found start of object at {$c}\n");
724
-
725
- } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
726
- // found a right-brace, and we're in an object
727
- array_pop($stk);
728
- //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
729
-
730
- } elseif (($substr_chrs_c_2 == '/*') &&
731
- in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
732
- // found a comment start, and we are in an array, object, or slice
733
- array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
734
- $c++;
735
- //print("Found start of comment at {$c}\n");
736
-
737
- } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
738
- // found a comment end, and we're in one now
739
- array_pop($stk);
740
- $c++;
741
-
742
- for ($i = $top['where']; $i <= $c; ++$i)
743
- $chrs = substr_replace($chrs, ' ', $i, 1);
744
-
745
- //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
746
-
747
- }
748
-
749
- }
750
-
751
- if (reset($stk) == SERVICES_JSON_IN_ARR) {
752
- return $arr;
753
-
754
- } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
755
- return $obj;
756
-
757
- }
758
-
759
- }
760
- }
761
- }
762
-
763
- /**
764
- * @todo Ultimately, this should just call PEAR::isError()
765
- */
766
- function isError($data, $code = null)
767
- {
768
- if (class_exists('pear')) {
769
- return PEAR::isError($data, $code);
770
- } elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
771
- is_subclass_of($data, 'services_json_error'))) {
772
- return true;
773
- }
774
-
775
- return false;
776
- }
777
- }
778
-
779
- if (class_exists('PEAR_Error')) {
780
-
781
- class Services_JSON_Error extends PEAR_Error
782
- {
783
- function Services_JSON_Error($message = 'unknown error', $code = null,
784
- $mode = null, $options = null, $userinfo = null)
785
- {
786
- parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
787
- }
788
- }
789
-
790
- } else {
791
-
792
- /**
793
- * @todo Ultimately, this class shall be descended from PEAR_Error
794
- */
795
- class Services_JSON_Error
796
- {
797
- function Services_JSON_Error($message = 'unknown error', $code = null,
798
- $mode = null, $options = null, $userinfo = null)
799
- {
800
-
801
- }
802
- }
803
-
804
- }
805
-
806
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
JSON/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- Redistribution and use in source and binary forms, with or without
2
- modification, are permitted provided that the following conditions are
3
- met:
4
-
5
- Redistributions of source code must retain the above copyright notice,
6
- this list of conditions and the following disclaimer.
7
-
8
- Redistributions in binary form must reproduce the above copyright
9
- notice, this list of conditions and the following disclaimer in the
10
- documentation and/or other materials provided with the distribution.
11
-
12
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15
- NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
16
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18
- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/wp-smushit-admin.css CHANGED
@@ -8,7 +8,7 @@ Smush button transformation
8
  float:left;
9
  }
10
 
11
- .button.wp-smushit-finished,.button.wp-smushit-finished:disabled,.button.wp-smushit-finished[disabled]{
12
  color:#fff!important;
13
  background: #00cf21!important;
14
  border-color: #619f6b!important;
@@ -18,7 +18,7 @@ Smush button transformation
18
  /*
19
  Loader
20
  */
21
- #wp-smushit-loader-wrap{
22
  display:none;
23
  }
24
  .floatingCirclesG{
@@ -223,4 +223,198 @@ Progressbar ui
223
 
224
  #progress-ui p#check-status{
225
  display:none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  }
8
  float:left;
9
  }
10
 
11
+ .button.wp-smush-finished.disabled,.button.wp-smush-finished:disabled,.button.wp-smush-finished[disabled]{
12
  color:#fff!important;
13
  background: #00cf21!important;
14
  border-color: #619f6b!important;
18
  /*
19
  Loader
20
  */
21
+ .wp-smushit-loader-wrap{
22
  display:none;
23
  }
24
  .floatingCirclesG{
223
 
224
  #progress-ui p#check-status{
225
  display:none;
226
+ }
227
+ /*
228
+ Progressbar ui
229
+ */
230
+ #progress-ui {
231
+ display: block;
232
+ width: 80%;
233
+ margin-bottom: 20px;
234
+ }
235
+
236
+ #progress-ui #wp-smush-progress-wrap {
237
+ height: 20px;
238
+ border: 1px solid #0074a2;
239
+ border-radius: 10px;
240
+ overflow: hidden;
241
+ position: relative;
242
+ }
243
+
244
+ #progress-ui #wp-smush-progress-wrap .wp-smush-progressbar {
245
+ height: 20px;
246
+ position: absolute;
247
+ width: 100%;
248
+ }
249
+
250
+ #progress-ui #wp-smush-progress-wrap .wp-smush-progressbar div {
251
+ height: 20px;
252
+ border-radius: 10px;
253
+ }
254
+
255
+ #progress-ui #wp-smush-progress-wrap #wp-smush-fetched-progress div {
256
+ background-color: #7ad03a;
257
+ }
258
+
259
+ #progress-ui #wp-smush-progress-wrap #wp-smush-sent-progress div {
260
+ background-color: #2ea2cc;
261
+ }
262
+
263
+ div#wp-smush-progress-status {
264
+ overflow: hidden;
265
+ }
266
+
267
+ #wp-smush-progress-status p {
268
+ float: left;
269
+ width: 50%;
270
+ }
271
+
272
+ div#wp-smush-progress-status p::before {
273
+ content: "c";
274
+ background-color: #7ad03a;
275
+ color: #7ad03a;
276
+ display: inline-block;
277
+ width: 20px;
278
+ margin-right: 10px;
279
+ }
280
+
281
+ div#wp-smush-progress-status p#sent-status::before {
282
+ background-color: #2ea2cc;
283
+ color: #2ea2cc;
284
+ }
285
+
286
+ p#wp-smush-compression {
287
+ text-align: center;
288
+ font-size: 1.1em;
289
+ line-height: 20px;
290
+ position: absolute;
291
+ margin: 0;
292
+ width: 100%;
293
+ }
294
+
295
+ p#wp-smush-compression span {
296
+ font-weight: bold;
297
+ }
298
+
299
+ .media-lib-wp-smush-el{
300
+ position: absolute;
301
+ display: block;
302
+ width: 90%;
303
+ height: 90%;
304
+ left: 5%;
305
+ top: 5%;
306
+ background: transparent;
307
+ }
308
+ .media-lib-wp-smush-el.is_smushed{
309
+ background: rgba(255, 255, 255, 0.5);
310
+ }
311
+ .media-lib-wp-smush-el .spinner{
312
+ display: block;
313
+ }
314
+ .media-lib-wp-smush-button{
315
+ margin-bottom: 5% !important;
316
+ }
317
+ .has-smush-button:hover .media-lib-wp-smush-el{
318
+ display: block;
319
+ }
320
+ .column-smushit .wp-smush-loader{
321
+ margin: 10px;
322
+ float: left;
323
+ }
324
+ #wp-smush-send span.wp-smushing {
325
+ display: inline-block;
326
+ vertical-align: top;
327
+ }
328
+ #wp-smush-send .wp-smush-loader-wrap {
329
+ display: inline-block;
330
+ }
331
+ button .wp-smush-loader-wrap {
332
+ display: inline-block;
333
+ float: left;
334
+ }
335
+ /** Settings Page **/
336
+ ul#wp-smush-options-wrap {
337
+ display: block;
338
+ overflow: auto;
339
+ margin: 0;
340
+ }
341
+
342
+ ul#wp-smush-options-wrap li {
343
+ display: inline-block;
344
+ list-style: none;
345
+ float: left;
346
+ margin: 5px 20px 5px 0;
347
+ padding: 5px 5px 5px 0;
348
+ }
349
+
350
+ input#wp-smush-save-settings {
351
+ margin: 15px 0;
352
+ }
353
+ .media-lib-wp-smush-icon{
354
+ position: absolute;
355
+ left: -10%;
356
+ bottom: -3%;
357
+ display: none;
358
+ }
359
+ .is_smushed .media-lib-wp-smush-icon{
360
+ display: block;
361
+ cursor: auto;
362
+ }
363
+
364
+ .active:hover .media-lib-wp-smush-icon{
365
+ display: block;
366
+ }
367
+ .active:hover .media-lib-wp-smush-icon:hover:before{
368
+ color: #0074a2;
369
+ }
370
+
371
+ .active .media-lib-wp-smush-icon{
372
+ cursor: pointer;
373
+ }
374
+ .media-lib-wp-smush-icon.active{
375
+ display: block;
376
+ color: #0074a2;
377
+ }
378
+ .media-lib-wp-smush-icon:before{
379
+ font-size: 30px;
380
+ }
381
+ .media-lib-wp-smush-icon.spinner{
382
+ left: -7%;
383
+ bottom: -7%;
384
+ }
385
+ .media-lib-wp-smush-icon.spinner:before{
386
+ content: "";
387
+ }
388
+ /** Grid view button **/
389
+ .smush-wrap {
390
+ margin-left: 14%;
391
+ max-width: 60%;
392
+ }
393
+
394
+ .smush-wrap.unsmushed .smush-status {
395
+ display: block;
396
+ }
397
+
398
+ .currently-smushing .smush-status {
399
+ color: #0074a2;
400
+ }
401
+
402
+ .smush-wrap #wp-smush-send {
403
+ display: none;
404
+ }
405
+
406
+ .smush-wrap.unsmushed #wp-smush-send {
407
+ display: block;
408
+ margin-top: 15px;
409
+ }
410
+
411
+ .smush-status.fail {
412
+ color: #dd3d36;
413
+ }
414
+
415
+ .smush-status.success {
416
+ color: #0074a2;
417
+ }
418
+ .smush-status.error{
419
+ color:red;
420
  }
assets/images/ajax-loader.gif ADDED
Binary file
assets/js/wp-smushit-admin-media.js ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var WP_Smush = WP_Smush || {};
2
+ jQuery(function ($) {
3
+ "use strict";
4
+ if (!wp.media) return;
5
+
6
+ var manualUrl = ajaxurl + '?action=wp_smushit_manual';
7
+
8
+ var SmushButton = Backbone.View.extend({
9
+ className: "media-lib-wp-smush-el",
10
+ tagName: "div",
11
+ events: {
12
+ "click .media-lib-wp-smush-icon": "click"
13
+ },
14
+ template : _.template('<span class="dashicons dashicons-media-archive media-lib-wp-smush-icon"></span>'),
15
+ initialize: function () {
16
+ this.render();
17
+ },
18
+ is_smushed: function(){
19
+ var self = this,
20
+ arr = _.filter(wp_smushit_data.smushed, function(id){ return id == self.model.get("id").toString(); });
21
+ return typeof arr == "object" ? arr.length : false;
22
+ },
23
+ render: function () {
24
+ var data = this.model.toJSON();
25
+
26
+
27
+ this.$el.html( this.template() );
28
+ this.$button = this.$(".media-lib-wp-smush-icon");
29
+
30
+ if( this.is_smushed() ){
31
+ this.$el.addClass("is_smushed");
32
+ }else{
33
+ this.$el.addClass("active");
34
+ this.$button.prop("title", wp_smush_msgs.smush_now)
35
+ }
36
+
37
+ this.$button.data("id", data.id);
38
+ },
39
+ click: function (e) {
40
+ var ajax = WP_Smush.ajax(this.model.get("id"), manualUrl, 0),
41
+ self = this;
42
+
43
+ e.preventDefault();
44
+ e.stopPropagation();
45
+
46
+ this.$button.css({display: "block"});
47
+ this.$button.prop("disabled", true);
48
+ this.$button.addClass("active spinner");
49
+ ajax.complete(function (res) {
50
+ self.$button.prop("disabled", false);
51
+ self.$button.removeClass("spinner");
52
+ self.$button.removeClass("active");
53
+ self.$el.removeClass("active");
54
+ self.$el.addClass("is_smushed");
55
+ });
56
+ }
57
+ });
58
+
59
+
60
+ /**
61
+ * Add smush it button to the image thumb
62
+ */
63
+ WP_Smush.Attachments = wp.media.view.Attachments.extend({
64
+ createAttachmentView: function (attachment) {
65
+
66
+ var view = wp.media.view.Attachments.__super__.createAttachmentView.apply(this, arguments);
67
+
68
+ _.defer(function () {
69
+ var smush_button = new SmushButton({model: view.model});
70
+ view.$el.append(smush_button.el);
71
+ view.$el.addClass("has-smush-button");
72
+ });
73
+
74
+ return view;
75
+ }
76
+ });
77
+ //wp.media.view.Attachments = WP_Smush.Attachments;
78
+ });
assets/js/wp-smushit-admin.js CHANGED
@@ -4,173 +4,325 @@
4
  * @author Saurabh Shukla <saurabh@incsub.com>
5
  *
6
  */
7
- jQuery('document').ready(function () {
8
-
9
  // url for smushing
10
- $send_url = ajaxurl + '?action=wp_smushit_bulk';
11
- $remaining = '';
12
- $smush_done = 1;
13
-
14
  /**
15
  * Checks for the specified param in URL
16
  * @param sParam
17
  * @returns {*}
18
  */
19
- function geturlparam ( arg ) {
20
- $sPageURL = window.location.search.substring(1);
21
- $sURLVariables = $sPageURL.split('&');
22
 
23
  for (var i = 0; i < $sURLVariables.length; i++) {
24
- $sParameterName = $sURLVariables[i].split('=');
25
  if ($sParameterName[0] == arg) {
26
  return $sParameterName[1];
27
  }
28
  }
29
- }
30
 
31
- /**
32
- * Show progress of smushing
33
- */
34
- function smushit_progress() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- $total = $smush_done + $remaining;
37
 
38
- // calculate %
39
- if ($remaining != 0) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
- // increase progress count
42
- $smush_done++;
43
 
44
- $progress = ( $smush_done / $total) * 100;
45
- }else{
46
- jQuery('#smush-status').html(wp_smushit_msgs['done']);
47
- }
48
- jQuery('#smushing-total').html($total);
49
 
50
- // increase the progress bar
51
- wp_smushit_change_progress_status($smush_done, $progress);
52
 
53
- }
 
54
 
55
- /**
56
- * Send ajax request for smushing
57
- *
58
- * @param {type} $id
59
- * @param {type} $getnxt
60
- * @returns {unresolved}
61
- */
62
- function smushitRequest($id, $getnxt) {
63
- // make request
64
- return jQuery.ajax({
65
- type: "GET",
66
- data: {attachment_id: $id, get_next: $getnxt},
67
- url: $send_url,
68
- timeout: 60000,
69
- dataType: 'json'
70
- }).done(function (response) {
71
 
72
- // increase progressbar
73
- smushit_progress();
74
- });
75
- }
76
 
77
- /**
78
- * Change the button status on bulk smush completion
79
- *
80
- * @returns {undefined}
81
- */
82
- function wp_smushit_all_done() {
83
- $button = jQuery('.wp-smushit-bulk-wrap #wp-smushit-begin');
84
 
85
- // copy the loader into an object
86
- $loader = $button.find('.floatingCirclesG');
 
 
87
 
88
- // remove the loader
89
- $loader.remove();
90
 
91
- // empty the current text
92
- $button.find('span').html('');
93
 
94
- // add new class for css adjustment
95
- $button.removeClass('wp-smushit-started');
96
- $button.addClass('wp-smushit-finished');
97
 
98
- // add the progress text
99
- $button.find('span').html(wp_smushit_msgs.done);
 
100
 
101
- return;
102
- }
103
 
104
- /**
105
- * Change progress bar and status
106
- *
107
- * @param {type} $count
108
- * @param {type} $width
109
- * @returns {undefined}
110
- */
111
- function wp_smushit_change_progress_status($count, $width) {
112
- // get the progress bar
113
- $progress_bar = jQuery('#wp-smushit-progress-wrap #wp-smushit-smush-progress div');
114
- if ($progress_bar.length < 1) {
115
- return;
116
- }
117
- jQuery('#smushed-count').html($count);
118
- // increase progress
119
- $progress_bar.css('width', $width + '%');
120
 
121
- }
 
 
122
 
123
- /**
124
- * Send for bulk smushing
125
- *
126
- * @returns {undefined}
127
- */
128
- function wp_smushit_bulk_smush() {
129
- // instantiate our deferred object for piping
130
- var startingpoint = jQuery.Deferred();
131
- startingpoint.resolve();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
- //Show progress bar
134
- jQuery('#wp-smushit-progress-wrap #wp-smushit-smush-progress div').css('width', 0);
135
- jQuery('#progress-ui').show();
136
 
137
- // if we have a definite number of ids
138
- if (wp_smushit_ids.length > 0) {
139
 
140
- $remaining = wp_smushit_ids.length;
 
 
 
141
 
142
- // loop and pipe into deferred object
143
- jQuery.each(wp_smushit_ids, function (ix, $id) {
144
- startingpoint = startingpoint.then(function () {
145
- $remaining = $remaining - 1;
146
 
147
- // call the ajax requestor
148
- return smushitRequest($id, 0);
149
- });
150
- });
151
- }
152
 
153
- }
154
- //If ids are set in url, click over bulk smush button
155
- $ids = geturlparam('ids');
156
- if ($ids && $ids != '') {
157
- wp_smushit_bulk_smush();
158
 
159
- return;
160
- }
 
 
 
 
 
 
 
161
 
 
 
 
 
 
162
  /**
163
  * Handle the start button click
164
  */
165
- jQuery('button[name="smush-all"]').on('click', function (e) {
166
  // prevent the default action
167
  e.preventDefault();
168
 
169
- jQuery(this).attr('disabled', 'disabled');
 
 
 
 
170
 
171
- wp_smushit_bulk_smush();
 
172
 
173
- return;
 
174
 
 
 
 
175
  });
176
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  * @author Saurabh Shukla <saurabh@incsub.com>
5
  *
6
  */
7
+ var WP_Smush = WP_Smush || {};
8
+ jQuery(function ($) {
9
  // url for smushing
10
+ WP_Smush.errors = [];
11
+ WP_Smush.timeout = 60000;
 
 
12
  /**
13
  * Checks for the specified param in URL
14
  * @param sParam
15
  * @returns {*}
16
  */
17
+ WP_Smush.geturlparam = function(arg) {
18
+ var $sPageURL = window.location.search.substring(1);
19
+ var $sURLVariables = $sPageURL.split('&');
20
 
21
  for (var i = 0; i < $sURLVariables.length; i++) {
22
+ var $sParameterName = $sURLVariables[i].split('=');
23
  if ($sParameterName[0] == arg) {
24
  return $sParameterName[1];
25
  }
26
  }
27
+ };
28
 
29
+ WP_Smush.ajax = function ($id, $send_url, $getnxt) {
30
+ "use strict";
31
+ return $.ajax({
32
+ type: "GET",
33
+ data: {attachment_id: $id, get_next: $getnxt},
34
+ url: $send_url,
35
+ timeout: WP_Smush.timeout,
36
+ dataType: 'json'
37
+ });
38
+ };
39
+
40
+ WP_Smush.Smush = function( $button, bulk ){
41
+ var self = this;
42
+
43
+ this.init = function( arguments ){
44
+ this.$button = $($button[0]);
45
+ this.is_bulk = typeof bulk ? bulk : false;
46
+ this.url = ajaxurl;
47
+ this.url += this.is_bulk ? '?action=wp_smushit_bulk' : '?action=wp_smushit_manual';
48
+ this.button_text = this.is_bulk ? wp_smush_msgs.bulk_now : wp_smush_msgs.smush_now;
49
+ this.$log = $(".smush-final-log");
50
+ this.$button_span = this.$button.find("span");
51
+ this.$loader = $(".wp-smush-loader-wrap").eq(0).clone();
52
+ this.deferred = jQuery.Deferred();
53
+ this.deferred.errors = [];
54
+ this.ids = wp_smushit_data.unsmushed;
55
+ this.$status = this.$button.parent().find('.smush-status');
56
+ };
57
+
58
+ this.start = function(){
59
+
60
+ this.$button.attr('disabled', 'disabled');
61
+ this.$button.addClass('wp-smush-started');
62
+ if( !this.$button.find(".wp-smush-loader-wrap").length ){
63
+ this.$button.prepend(this.$loader);
64
+ }else{
65
+ this.$loader = this.$button.find(".wp-smush-loader-wrap");
66
+ }
67
 
 
68
 
69
+ this.show_loader();
70
+ this.bulk_start();
71
+ this.single_start();
72
+ };
73
+
74
+ this.bulk_start = function(){
75
+ if( !this.is_bulk ) return;
76
+ $('#progress-ui').show();
77
+ this.$button_span.text(wp_smush_msgs.progress);
78
+ this.show_loader();
79
+
80
+ };
81
+
82
+ this.single_start = function(){
83
+ if( this.is_bulk ) return;
84
+ this.$button_span.text(wp_smush_msgs.sending);
85
+ this.$status.removeClass("error");
86
+ };
87
+
88
+ this.enable_button = function(){
89
+ this.$button.prop("disabled", false);
90
+ };
91
+
92
+
93
+ this.disable_button = function(){
94
+ this.$button.prop("disabled", true);
95
+ };
96
+
97
+ this.show_loader = function(){
98
+ this.$loader.removeClass("hidden");
99
+ this.$loader.show();
100
+ };
101
+
102
+ this.hide_loader = function(){
103
+ this.$loader.hide();
104
+ };
105
+
106
+ this.single_done = function(){
107
+ if( this.is_bulk ) return;
108
+
109
+ this.hide_loader();
110
+ this.request.done(function(response){
111
+ if (typeof response.data != 'undefined') {
112
+ //Append the smush stats or error
113
+ self.$status.html(response.data);
114
+ if (response.success && response.data !== "Not processed") {
115
+ self.$button.remove();
116
+ } else {
117
+ self.$status.addClass("error");
118
+ }
119
+ self.$status.html(response.data);
120
+ }
121
+ self.$button_span.text( self.button_text );
122
+ self.enable_button();
123
+ }).error(function (response) {
124
+ self.$status.html(response.data);
125
+ self.$status.addClass("error");
126
+ self.enable_button();
127
+ self.$button_span.text( self.button_text );
128
+ });
129
 
130
+ };
 
131
 
132
+ this.bulk_done = function(){
133
+ if( !this.is_bulk ) return;
 
 
 
134
 
135
+ this.hide_loader();
 
136
 
137
+ // Add finished class
138
+ this.$button.addClass('wp-smush-finished');
139
 
140
+ // Remove started class
141
+ this.$button.removeClass('wp-smush-started');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
+ //Enable the button
144
+ this.disable_button();
 
 
145
 
146
+ // Update button text
147
+ self.$button_span.text( wp_smush_msgs.done );
148
+ };
 
 
 
 
149
 
150
+ this.is_resolved = function(){
151
+ "use strict";
152
+ return this.deferred.state() === "resolved";
153
+ };
154
 
155
+ this.free_exceeded = function(){
156
+ this.hide_loader();
157
 
158
+ // Add new class for css adjustment
159
+ this.$button.removeClass('wp-smush-started');
160
 
161
+ //Enable button
162
+ this.$button.prop("disabled", false);
 
163
 
164
+ // Update text
165
+ this.$button.find('span').html(wp_smush_msgs.bulk_now);
166
+ };
167
 
168
+ this.update_progress = function(stats){
169
+ var progress = ( stats.data.smushed / stats.data.total) * 100;
170
 
171
+ //Update stats
172
+ $('#wp-smush-compression #human').html(stats.data.human);
173
+ $('#wp-smush-compression #percent').html(stats.data.percent);
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
+ // increase the progress bar
176
+ this._update_progress(stats.data.smushed, progress);
177
+ };
178
 
179
+ this._update_progress = function( count, width ){
180
+ "use strict";
181
+ // get the progress bar
182
+ var $progress_bar = jQuery('#wp-smush-progress-wrap #wp-smush-fetched-progress div');
183
+ if ($progress_bar.length < 1) {
184
+ return;
185
+ }
186
+ $('.done-count').html(count);
187
+ // increase progress
188
+ $progress_bar.css('width', width + '%');
189
+
190
+ };
191
+
192
+ this.continue = function(){
193
+ return this.ids.length > 0 && this.is_bulk;
194
+ };
195
+
196
+ this.increment_errors = function(){
197
+ WP_Smush.errors.push(this.current_id);
198
+ };
199
+
200
+ this.call_ajax = function(){
201
+
202
+ this.current_id = this.is_bulk ? this.ids.shift() : this.$button.data("id"); //remove from array while processing so we can continue where left off
203
+
204
+ this.request = WP_Smush.ajax(this.current_id, this.url , 0)
205
+ .complete(function(){
206
+ if( !self.continue() || !self.is_bulk ){
207
+ self.deferred.resolve();
208
+ }
209
+ })
210
+ .error(function () {
211
+ self.increment_errors();
212
+ }).done(function (res) {
213
+ self.update_progress(res);
214
+
215
+ if (typeof res.success === "undefined" || ( typeof res.success !== "undefined" && res.success === false && res.data.error !== 'bulk_request_image_limit_exceeded' )) {
216
+ self.increment_errors();
217
+ }
218
+
219
+ if (typeof res.data !== "undefined" && res.data.error == 'bulk_request_image_limit_exceeded' && !self.is_resolved() ) {
220
+ self.free_exceeded();
221
+ }else{
222
+ if( self.continue() ){
223
+ self.call_ajax();
224
+ }
225
+ }
226
+ self.single_done();
227
+ });
228
 
229
+ self.deferred.errors = WP_Smush.errors;
230
+ return self.deferred;
231
+ };
232
 
233
+ this.init( arguments );
234
+ this.run = function(){
235
 
236
+ // if we have a definite number of ids
237
+ if ( this.is_bulk && this.ids.length > 0) {
238
+ this.call_ajax();
239
+ }
240
 
241
+ if( !this.is_bulk )
242
+ this.call_ajax();
 
 
243
 
244
+ };
 
 
 
 
245
 
246
+ this.bind_deferred_events = function(){
 
 
 
 
247
 
248
+ this.deferred.done(function(){
249
+ if (WP_Smush.errors.length) {
250
+ var error_message = wp_smush_msgs.error_in_bulk.replace("{{errors}}", WP_Smush.errors.length);
251
+ self.$log.append(error_message);
252
+ }
253
+ self.bulk_done();
254
+ });
255
+
256
+ };
257
 
258
+ this.start();
259
+ this.run();
260
+ this.bind_deferred_events();
261
+ return this.deferred;
262
+ };
263
  /**
264
  * Handle the start button click
265
  */
266
+ $('button[name="smush-all"]').on('click', function (e) {
267
  // prevent the default action
268
  e.preventDefault();
269
 
270
+ $(".smush-remaining-images-notice").remove();
271
+ //Enable Cancel button
272
+ $('#wp-smush-cancel').prop('disabled', false);
273
+
274
+ new WP_Smush.Smush( $(this), true );
275
 
276
+ //buttonProgress(jQuery(this), wp_smush_msgs.progress, wp_smushit_bulk_smush());
277
+ });
278
 
279
+ //Handle smush button click
280
+ $('body').on('click', '.wp-smush-send', function (e) {
281
 
282
+ // prevent the default action
283
+ e.preventDefault();
284
+ new WP_Smush.Smush( $(this), false );
285
  });
286
+
287
+ });
288
+ (function ($) {
289
+ var Smush = function (element, options) {
290
+ var elem = $(element);
291
+
292
+ var defaults = {
293
+ isSingle: false,
294
+ ajaxurl: '',
295
+ msgs: {},
296
+ msgClass: 'wp-smush-msg',
297
+ ids: []
298
+ };
299
+ };
300
+ $.fn.wpsmush = function (options) {
301
+ return this.each(function () {
302
+ var element = $(this);
303
+
304
+ // Return early if this element already has a plugin instance
305
+ if (element.data('wpsmush'))
306
+ return;
307
+
308
+ // pass options to plugin constructor and create a new instance
309
+ var wpsmush = new Smush(this, options);
310
+
311
+ // Store plugin object in this element's data
312
+ element.data('wpsmush', wpsmush);
313
+ });
314
+ };
315
+ if (typeof wp !== 'undefined') {
316
+ _.extend(wp.media.view.AttachmentCompat.prototype, {
317
+ render: function () {
318
+ $view = this;
319
+ //Dirty hack, as there is no way around to get updated status of attachment
320
+ $html = jQuery.get(ajaxurl + '?action=attachment_status', {'id': this.model.get('id')}, function (res) {
321
+ $view.$el.html(res.data);
322
+ $view.views.render();
323
+ return $view;
324
+ });
325
+ }
326
+ });
327
+ }
328
+ })(jQuery);
extras/dash-notice/wpmudev-dash-notification.php ADDED
@@ -0,0 +1,692 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /////////////////////////////////////////////////////////////////////////
3
+ /* -------- WPMU DEV Dashboard Notice - Aaron Edwards (Incsub) ------- */
4
+ if ( !class_exists('WPMUDEV_Dashboard_Notice3') ) {
5
+ class WPMUDEV_Dashboard_Notice3 {
6
+
7
+ var $version = '3.1';
8
+ var $screen_id = false;
9
+ var $product_name = false;
10
+ var $product_update = false;
11
+ var $theme_pack = 128;
12
+ var $server_url = 'http://premium.wpmudev.org/wdp-un.php';
13
+ var $update_count = 0;
14
+
15
+ function __construct() {
16
+ add_action( 'init', array( &$this, 'init' ) );
17
+ }
18
+
19
+ function init() {
20
+ global $wpmudev_un;
21
+
22
+ if ( class_exists( 'WPMUDEV_Dashboard' ) || ( isset($wpmudev_un->version) && version_compare($wpmudev_un->version, '3.4', '<') ) )
23
+ return;
24
+
25
+ // Schedule update cron on main site only
26
+ if ( is_main_site() ) {
27
+ if ( ! wp_next_scheduled( 'wpmudev_scheduled_jobs' ) ) {
28
+ wp_schedule_event( time(), 'twicedaily', 'wpmudev_scheduled_jobs' );
29
+ }
30
+
31
+ add_action( 'wpmudev_scheduled_jobs', array( $this, 'updates_check') );
32
+ }
33
+ add_action( 'delete_site_transient_update_plugins', array( &$this, 'updates_check' ) ); //refresh after upgrade/install
34
+ add_action( 'delete_site_transient_update_themes', array( &$this, 'updates_check' ) ); //refresh after upgrade/install
35
+
36
+ if ( is_admin() && current_user_can( 'install_plugins' ) ) {
37
+
38
+ add_action( 'site_transient_update_plugins', array( &$this, 'filter_plugin_count' ) );
39
+ add_action( 'site_transient_update_themes', array( &$this, 'filter_theme_count' ) );
40
+ add_filter( 'plugins_api', array( &$this, 'filter_plugin_info' ), 101, 3 ); //run later to work with bad autoupdate plugins
41
+ add_filter( 'themes_api', array( &$this, 'filter_plugin_info' ), 101, 3 ); //run later to work with bad autoupdate plugins
42
+ add_action( 'admin_init', array( &$this, 'filter_plugin_rows' ), 15 ); //make sure it runs after WP's
43
+ add_action( 'core_upgrade_preamble', array( &$this, 'disable_checkboxes' ) );
44
+ add_action( 'activated_plugin', array( &$this, 'set_activate_flag' ) );
45
+
46
+ //remove version 1.0
47
+ remove_action( 'admin_notices', 'wdp_un_check', 5 );
48
+ remove_action( 'network_admin_notices', 'wdp_un_check', 5 );
49
+ //remove version 2.0, a bit nasty but only way
50
+ remove_all_actions( 'all_admin_notices', 5 );
51
+
52
+ //if dashboard is installed but not activated
53
+ if ( file_exists(WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php') ) {
54
+ if ( !get_site_option('wdp_un_autoactivated') ) {
55
+ //include plugin API if necessary
56
+ if ( !function_exists('activate_plugin') ) require_once(ABSPATH . 'wp-admin/includes/plugin.php');
57
+ $result = activate_plugin( '/wpmudev-updates/update-notifications.php', network_admin_url('admin.php?page=wpmudev'), is_multisite() );
58
+ if ( !is_wp_error($result) ) { //if autoactivate successful don't show notices
59
+ update_site_option('wdp_un_autoactivated', 1);
60
+ return;
61
+ }
62
+ }
63
+
64
+ add_action( 'admin_print_styles', array( &$this, 'notice_styles' ) );
65
+ add_action( 'all_admin_notices', array( &$this, 'activate_notice' ), 5 );
66
+ } else { //dashboard not installed at all
67
+ if ( get_site_option('wdp_un_autoactivated') ) {
68
+ update_site_option('wdp_un_autoactivated', 0);//reset flag when dashboard is deleted
69
+ }
70
+ add_action( 'admin_print_styles', array( &$this, 'notice_styles' ) );
71
+ add_action( 'all_admin_notices', array( &$this, 'install_notice' ), 5 );
72
+ }
73
+ }
74
+ }
75
+
76
+ function is_allowed_screen() {
77
+ global $wpmudev_notices;
78
+ $screen = get_current_screen();
79
+ $this->screen_id = $screen->id;
80
+
81
+ //Show special message right after plugin activation
82
+ if ( in_array( $this->screen_id, array('plugins', 'plugins-network') ) && ( isset($_GET['activate']) || isset($_GET['activate-multi']) ) ) {
83
+ $activated = get_site_option('wdp_un_activated_flag');
84
+ if ($activated === false) $activated = 1; //on first encounter of new installed notice show
85
+ if ($activated) {
86
+ if ($activated >= 2)
87
+ update_site_option('wdp_un_activated_flag', 0);
88
+ else
89
+ update_site_option('wdp_un_activated_flag', 2);
90
+ return true;
91
+ }
92
+ }
93
+
94
+ //always show on certain core pages if updates are available
95
+ $updates = get_site_option('wdp_un_updates_available');
96
+ if (is_array($updates) && count($updates)) {
97
+ $this->update_count = count($updates);
98
+ if ( in_array( $this->screen_id, array('plugins', 'update-core', /*'plugin-install', 'theme-install',*/ 'plugins-network', 'themes-network', /*'theme-install-network', 'plugin-install-network',*/ 'update-core-network') ) )
99
+ return true;
100
+ }
101
+
102
+ //check our registered plugins for hooks
103
+ if ( isset($wpmudev_notices) && is_array($wpmudev_notices) ) {
104
+ foreach ( $wpmudev_notices as $product ) {
105
+ if ( isset($product['screens']) && is_array($product['screens']) && in_array( $this->screen_id, $product['screens'] ) ) {
106
+ $this->product_name = $product['name'];
107
+ //if this plugin needs updating flag it
108
+ if ( isset($product['id']) && isset($updates[$product['id']]) )
109
+ $this->product_update = true;
110
+ return true;
111
+ }
112
+ }
113
+ }
114
+
115
+ if ( defined('WPMUDEV_SCREEN_ID') ) var_dump($this->screen_id); //for internal debugging
116
+
117
+ return false;
118
+ }
119
+
120
+ function auto_install_url() {
121
+ $function = is_multisite() ? 'network_admin_url' : 'admin_url';
122
+ return wp_nonce_url($function("update.php?action=install-plugin&plugin=install_wpmudev_dash"), "install-plugin_install_wpmudev_dash");
123
+ }
124
+
125
+ function activate_url() {
126
+ $function = is_multisite() ? 'network_admin_url' : 'admin_url';
127
+ return wp_nonce_url($function('plugins.php?action=activate&plugin=wpmudev-updates%2Fupdate-notifications.php'), 'activate-plugin_wpmudev-updates/update-notifications.php');
128
+ }
129
+
130
+ function install_notice() {
131
+ if ( !$this->is_allowed_screen() ) return;
132
+
133
+ echo '<div class="updated" id="wpmu-install-dashboard"><div class="wpmu-install-wrap"><p class="wpmu-message">';
134
+
135
+ if ($this->product_name) {
136
+ if ($this->product_update)
137
+ echo 'Important updates are available for <strong>' . esc_html($this->product_name) . '</strong>. Install the free WPMU DEV Dashboard plugin now for updates and support!';
138
+ else
139
+ echo '<strong>' . esc_html($this->product_name) . '</strong> is almost ready - install the free WPMU DEV Dashboard plugin for updates and support!';
140
+ } else if ($this->update_count) {
141
+ echo "Important updates are available for your WPMU DEV plugins/themes. Install the free WPMU DEV Dashboard plugin now for updates and support!";
142
+ } else {
143
+ echo 'Almost ready - install the free WPMU DEV Dashboard plugin for updates and support!';
144
+ }
145
+ echo '</p><a class="wpmu-button" href="' . $this->auto_install_url() . '">Install WPMU DEV Dashboard</a>';
146
+ echo '</div>';
147
+ echo '<div class="wpmu-more-wrap"><a href="http://premium.wpmudev.org/update-notifications-plugin-information/" class="wpmu-more-info">More Info&raquo;</a></div>';
148
+ echo '</div>';
149
+ }
150
+
151
+ function activate_notice() {
152
+ if ( !$this->is_allowed_screen() ) return;
153
+
154
+ echo '<div class="updated" id="wpmu-install-dashboard"><div class="wpmu-install-wrap"><p class="wpmu-message">';
155
+ if ($this->product_name) {
156
+ if ($this->product_update)
157
+ echo 'Important updates are available for <strong>' . esc_html($this->product_name) . '</strong>. Activate the WPMU DEV Dashboard to update now!';
158
+ else
159
+ echo "Just one more step to enable updates and support for <strong>" . esc_html($this->product_name) . '</strong>!';
160
+ } else if ($this->update_count) {
161
+ echo "Important updates are available for your WPMU DEV plugins/themes. Activate the WPMU DEV Dashboard to update now!";
162
+ } else {
163
+ echo "Just one more step - activate the WPMU DEV Dashboard plugin and you're all done!";
164
+ }
165
+ echo '</p><a class="wpmu-button" href="' . $this->activate_url() . '">Activate WPMU DEV Dashboard</a></div></div>';
166
+ }
167
+
168
+ function notice_styles() {
169
+ if ( !$this->is_allowed_screen() ) return;
170
+ ?>
171
+ <!-- WPMU DEV Dashboard notice -->
172
+ <style type="text/css" media="all">
173
+ #wpmu-install-dashboard{background-color:#031f34;font-family:sans-serif;display:block;border-radius:5px;position:relative;border:none;padding:14px 0.6em;font-size:1.3em;line-height:1.4em}
174
+ #wpmu-install-dashboard .wpmu-button{width:auto;position:absolute;top:0;bottom:0;right:0;padding:10px;margin:auto 14px auto 10px;line-height:1em;max-height:1em;background-color:#06385e;color:#3bb2df;text-decoration:none;border:5px solid rgba(53,131,191,0.4);vertical-align:middle;text-shadow:0 1px 0 rgba(0,0,0,0.6)}
175
+ #wpmu-install-dashboard .wpmu-button:hover{color:#e8da42;border-color:rgba(53,131,191,0.9);-webkit-transition:0.2s}
176
+ #wpmu-install-dashboard .wpmu-message{color:#c0d7eb;margin:0 280px 0 15px;padding:12px 0;text-shadow:0 1px 0 rgba(0,0,0,1);font-size:1em}
177
+ #wpmu-install-dashboard .wpmu-button,#wpmu-install-dashboard .wpmu-button:hover{-webkit-transition:0.2s}
178
+ #wpmu-install-dashboard .wpmu-btn-wrap{min-width:10%;background-color:#fff}
179
+ #wpmu-install-dashboard .wpmu-install-wrap{max-width:1050px;margin:0 auto;position:relative}#wpmu-install-dashboard .wpmu-more-wrap{max-width:1050px;margin:0 auto -9px;padding:5px 0 0;text-align:right}
180
+ #wpmu-install-dashboard .wpmu-more-info{color:#e8da42;font-size:0.9em;margin:0 14px}
181
+ #wpmu-install-dashboard, .wpmu-update-row{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCMDBDRENDMjJEOUUxMUUzQjQ0MThGOUZCNkQzMTIwNCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCMDBDRENDMzJEOUUxMUUzQjQ0MThGOUZCNkQzMTIwNCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkIwMENEQ0MwMkQ5RTExRTNCNDQxOEY5RkI2RDMxMjA0IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkIwMENEQ0MxMkQ5RTExRTNCNDQxOEY5RkI2RDMxMjA0Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+4bBa5AAAFnZJREFUeNrs3el2U0e6BuCyZTybmYSE9JAr6V/nqs+vcyPndHdCgAAGbPA8HFX7U0dxQ5BtWfpq7+dZq5ZJsoilUu16a9pbC+fn5wUArmpRFQAgQAAQIAAIEAAECAAIEAAECAACBAABAoAAAQABAoAAAUCAACBAABAgACBAABAgAAgQAAQIAAIEAAQIAAIEAAECgAABQIAAgAABQIAAIEAAaN5Sthf0t/9+5VMB+LrNYTn/n//69pMZCACTejQsPw7LhhkIAJP22U+H5ZthWRiWMwECwNfU2cazYdnKlGYA5PZ4WL4bluVs0yEAcrpTLpasnpSLJatUBAhATvWU1fcl0ZKVAAHIL+WSlQAByN0n1+BIuWQlQAByqqesfigXS1fNpB0A81NnGqMlqzutTZcAmI8aGN9HgDRHgADMx1aEx2arb0CAAMxWs0tWAgRgfpYjOB6VBk5ZCRCAHJpfshIgALNVZxpPYubRqT5XgADcnuWYdTzq4psTIAC34265ePz6elffoAABmK76Ta91yepp1/tYAQIwPSvlYsnqYR/erAABmI7OL1kJEIDpqktW9TvKv+1bnypAAK6vV0tWAgRgOnq3ZCVAAG5mtGRVT1kN+lwRAgRgcqvlYsnqgaoQIACTuh/hsaYqBAjAJOoy1eiU1UB1CBCASdRnWdXvKbdk9RmLqgDgi9aFhwABuI4FVSBAAK7jXBUIEAAECAACBAABAoAAAQABAoAAAUCAACBAABAgACBAABAgAAgQAAQIAAIEAAQIAAIEAAECgAABAAECgAABQIAAIEAAECAAIEAAECAAzN6SKpi6hQjm8Z/j/20wLKfDcj727+ufzy79hMvtaLwtDcbai3aEAGnw4r4zLMuXfi6NlcFn6njhMxf2SYTKyVg5HpajsZ9HOoRODzqWL5XLbWnp0orB19rR8aV2dDTWnkCAzKGu6oW9MSzrw7ISF/mdCIqb+KO/fxoXfS2Hw/JpWPaiMzjxsTRpEO1m1JbWptSW/ujvHo+V2n4+Dst+tCEDEwTILViOC3xzWLYiNAYzfg2DKKvxGh5HqBxEJ/BxLFDIPcvYGGtLa3H9Lczo948CqrpXLpa4jmNAshM/D3xMCJCbd9hbcZFtxIWe8TVuRPk2AqSW9xEopz7GNOqg40G0qY05DEC+ZDFeWy0Px2a3HyJQzG4RIFdQR/h342JfL22dUFuP8jA6gXfRCRz6WOemzjTuR3tabiToRmFXl7a2I0zMShAgX7lwHseFs9L4e1mMke5WXPg1SN4KkpkHx+MIj0GDr39hbEDyJIJEG0KAXFJHhY+irHTw/dUZ1XcRjLUTeFOcwLnt+n4Ss8CuXFcrY23obRRtiF4HyEJc5HXvYK0H77d2bN/HiPhVzEqcupmeQQxCvunoQGTUhp5FG3pZLvbaoHcBUqflT+NCWOjhe/9ruTgc8KJY256GjRih3+vR+/0xZiI1SJz8EyC98TjCY6XHn/do9lU7gl/KxdIW1/Mk2tNyz973Yrz3URv6oCkIkC67E6PExz2cdXxJDdG/RCdQZyOObF7tmvlee/rXjPbHmIn8Wn7/SBUESCfUPY4/lYtTSfznSLKu29f17Z+KJa1JrEZ7uqsq/qXu/zyLenlebLD3shPpqq0YIQmPP3Y36mlTVfyh0fq/8PhPj2JGu6oqBEhXOsW/ln6cspqG0Qa7sP28zaifdVXxRfeijoSIAGna/WjIyz7eK1kpv53S4j/DQ8c4+SxN0AqQZmcefy6/PTSOq1mO+jMT+W1m9pfS75N7160zgStAmhspCo/phchGz+thVUd44xCxCiBAmrASnZ6R4vQ6zz/3uAOopxN/KJZibjqgqyfWBqpCgGS/2GtDtWE+/VFkHzuAem9Hvc/DXtDN3Y+6dP+VAEnrqYv9VjuAb3v2nuuR1Cc++ql5EnWKAEmnPpbjGx/jraoB8qAn73UzRsxMd0b3rLjPSIAkM3pcuenx7beRWs9d318aRHg4hDF9SxEivn9IgKQZ1XxXnJCZlbUehHWdyTq+fLuzu6eqQYBk8KD0Z1klU513da9po1gKnYX6AEqPghEgc3UnRjKWrmbfVuosZMn74poG6lqAzFs91eHI7nyMvie7S+4Xp/hmqS5lOZUlQOZiLabBzE+t/65sqNeRsKWr2Rt9jQACZOadl1My87XcoVlIHQlv+Ei1IbofIHX55KGPLIWHHRhB3imWUubdhoS3AJlpg7P5pvOdlrr3YS9tfpYEuACZlTradWw3l/p5tPqwxYHZbJo2ZBYiQHRWPbTScKjXU1cerWEWQg8CZKk4ZpnV/dLe03oXzD7ShbkTWQLk1mya5qa10eBIfqt4ZEkmyzEQQYDc2iiXvKP51maH90r3vsq5CzNZB2QEyNStGC2md7e0sz+1XCyHZrTuOhcgt6E2KjcO5u+UW1nG2iy+9jjrTNZKgwCZeqPaKh6a2MLF38oTVs0+coe7zXQBMjV3YmpLfusNzBTrzMNhDDNZpijzxtV64yOSs2E5HJb9+Hka/67+HER4D+I9rkUH1+psazU+rw+JX+NGafteovNhOR6Wg2E5iXIW1/Ag2s9Kae9Y9bg6k30b7xUBcuMLvkU1MHaiMz2Mi/78K7PApbj4R48Wb22dfqGRAGkxoA8utadRcJxfakODaEeb5bcbJVsLk80I+UNdswC5icUGp7P7MXrajtC4ykzlKMrusLwuF08dflTaOtq4GZ/bWdJ2vtFge3ozLO8maE9nUY7j772OEHlc2tqcrsugWwJEgNzUckOj8PMIjRdTavh1xPlzjDqflXb2gdaiA8h48a+Udh6ceBbB8SoGFdf1IQYkNURa+hbAzXj/CJBrW2+kwdf9jF9ixDftddud6Iz/XNo45TSITjpjgGyUNm4ePI72NK0OtIbRrzEr+VMjIboW1/6J7jm/xcSNKPt6dW3gP8UFelubfrUz/keMJFtoS1k7qBZmccfxWd/G6Lu2n78Py14D9VBni47zCpAbyd6A6sjuebnY87htdRnj53Kz5Yw+f26Zg218Jls/49s8hFDD458NtKNB8T0tAuQG6jp69uOWr8ps12nrxf9LyX+8cbnkO/mzmrw9ncdgZHsGv+tTzJrPkrejFlYgSBwgmW9K+xABMmv1NM5OAwGSrbNeK7mPs76OMivvZ/z7rmO9tH0/iwCZo6WSdwO97nu8iCWHWaujxrfJR49LCcM/8w2adWb5ck4z6Mz7IavF03kFyA1mIFkv+DexDDAvdQayn7w9Zbvwsy5fnUV4HM/hd9ffeZuHP6bRjmykC5BOXfCHZf7n0+vMZzt5m8o0A1lK3J7qUuj7Of7+uiT6MWndLAgQAdKFDmjc+5LjHofdMp8ltBY/v0HSABndLHg+59eQeTAiQATItUeN2WQa+ddjmJnXr5dKniXIjHsyo9nHbpLXkXVJtOUHXwoQAfI7dap/kCjMBMjkM5CMbfxdybH/cFzyPgAza/iTPEAyHt/bLblOPx0mb1NZAiRjB7RXcu09ZGvb4/2Ak1gCpPnXVI/ufkr4mrKeoBmUXEtY2RyU+Zy8+qNAO0jajgSIALmybEd4a2ed7fEPme9IX0j0GWZs3+cJ2/dx0nbkZkIBAtD8QBIBAoAAAUCAQI9YmkGAACBAADMQECA6IQABghABBAgAAgQABAgAAgQAAQKAAAFAgACAAPG5AeiIABAgAAgQAAQIAAgQAAQItMqTlBEggPBAgACAADGKBRAgAAgQAAQIAAJEFQAgQAAQIAAIEAAECEm4DwQQIAgQQIAAIEAAQIAAIEAAECAACBBgYgvFKToECAACBAAESC9YAgEECAACBAABAgACBAABAoAAAUCAACBAaIP7QAABggABBAgAAgQABAgAAgQAAQKAAAEm5hsJESDAtQMEBAg6IUCAAIAAAUCAACBAABAgAAgQVQCAAAFAgAAgQJg+NxICAgQBAggQAAQIAAgQAAQIAAIEAAECTMw3EiJAABAgtDmKBRAgAAgQAAQIAAgQAAQIAAIEAAECgAAhP/eBAAIEAQIIEAAECAAIEAAECAACBAABAkzMCToECHDtABEiCBAABAhGsAACpCchAiBAABAgAAgQABAgAAgQAAQIAAIEAAFCbm4kBAQIAAIEAAECAAIEAAECnXCuChAgwHU4RYcAAa4dIJipdaI9CZA2L6zMF1emNjXw+ZmpdbyPPFM5XLUDOk38+mqnvZSkA1pLWD+n877oGxnt18/vToLXsZK8PzgRIDTVaCYIkAwXXe18VgVIswGSpfNeTXytnQoQruMo8WurI8f1BK9jK8kI9rLjhB121hntWpnvMuRi8gA5FiBct+GcJX59G2X+69dbJeeGdcbZY9YAWZ/zLGTev3+SfuBYgNDcyGOCkeM89x/qqPGu2eOV2lNGdfaxOedByCDxdXZUbKJzDYfJA+ROXHzzcr/kXL46TRogtS1l3Qe5N6eZ5CDxIGS8H5grAdKm0wyN5yselvmcxqpLDo+S1slJ0s8t477MyOacBiM1PDYSX1915rEvQLiug+Svr64fP5jD731c8m58niSdgcx9KeQrfdTjGc9C5vE7rzOIFCBc214Dr/HJsCzP8Pdtxe/MHPoZR/onJe8+SHU/yqw8KvNdgp20Lc39MxMg7dpPftFXdSP96Yx+Vw2qZyX3pmfW0K+zj8xLogvRjmYxGKmz129K/kfOfMowaxQg7TrJMIWdwOO4IG9TDY0fSu4163MBciPr8Rnf5gBhKX7HagPX1acML0KAtOu0tLGMVUdy35fb29iuF/2fynz2W66idtCZbwA9aKAtPYhZ5m30W4vRju41UA/HWT6vpULL9mJkm326PYiLs/58Xaa3D7AeHcrdBj6r7EuOh420pSfRjp5PMZBXoh09aOi6TzEYESDtB8hRyf/At1GI/BCd/qtys+W32m7rMeFvGnnv42Gf1VGESAvLNw/jc385LB9uUK+LMeP4ruR88OaXpNj/ECDtO4yOuJVOtI5uRydctuPi/3SFDmAlZhsPSv5TMuNaWG5sKUCqut/147C8j7JTJn8ky9JYO5rXjYo3aUs7WV6MAGnfbpntEcdpqKdp6qmaxxGAn+LnSfn9XdGjR8Ovxswl+7OJ/ijoswfIaJP/XkP1uhizkQfRfvbGZuUnY6P0xWhHyxE869GmWvxyr/2S6PCMAOlGgJw0+lkuxUxia6wTG//Zla9//VhyP3pmZLQ00trhmoWxAcaX2lHpSFvaKYlu+nQKq30HESJdMAqMxShd+frXnUZeZ5rN2VtoR11oS2fZrnUB0r46yvqgGlIvOew18lqPS5L7C/jiTDbVvV8CpBt2Sxvn+Ptop+R/YkCLs6U+qgPFVN/dIkC64ah0ZxmrS84a7JC7sozVxWs83UqDAOmOdyX3txT2Ue2MPzb2mg8bfM19mX2ke9yMAOmOTy58oT4F5zFrOvfxpZrJbmd8YQKkW43sjQs/1Uj+fcOjXXtqebwvSQ83CJBu2SlO0WS66FvdSzgpTvZlGhi+zTowFCDdcpq5sfVI7YC3G38P70obNz92XQ3ytAdkBEg3R777qmHun8Fe4+9hzyxk7upAMPWytADp5uj3jWpQ/1NQZ1FO9s139pH6YIwA6abt4r6QedZ9V/ahds1C5qYuR/+aPcAFSHcb30ujx5mrd5y/7tD7OY/3ox0ZBAqQnqknst6qhpmqI8auHX+tSyjvfLQzdRhtKT0B0v0OzWMpZqMuW3Vx7+k82tGxj3hm9f2ylYGIAOm22ghfqYZbV5d4XpTuHnutJ7Je+5hnou45NXMEXIB039tiI1Qd39zr4ibV23YUA5Fm9pwESPfVDfXnJeGD2DriU1z0XVdnV7+UZI8T75DzqN+m7h8SIP2wH52cO9SnH871ou/L/sBOsZR1W96UBg+9CJD+qI3zpWqY6ojxRenfFzDVNmRJdLo+xECkOQKkX+qGuiOZ07Hd09G4JdHpOoj6bPIAhgDp38X/U3GX+k3VWcfPpb832NUl0X8WD1u8qaOox2afXSdA+uc4Gu2eqriWTzrPf4fo8+Iu9V4P5gRIf6fN/yie2ntVe1Fvlm8uvIkQcTjjak5iEPK+9TciQHSGQmQy++rrs34VIteaeWx34c0IkH6ryzH/V9wgNmk9Wfb7vHo4o897QpM6ikHIdlfekABhPzrH96ris+pa/9/NPCaaifyzuNHwS0bLxp06Bbnkc6VcrOnXxl032J+ojn+r9848Lx4keJX6quv7z4ZlTXX8227M0Do3gxUgjNQL/6cYaX83LHd6XBej71NJ/4U+CdWb4o4iRO71vC5G36fS2QdtChA+1+BriHw/LFs9rIO631HvCt7RHK6ttp+/x2z2m572M4cRHJ3+Th4BwufULxH63+gAnvRkNnIa4em7L6Y3o30Rgfy0R4OROmOtm+T1YMFB19+sAOFrHUAdiX87LPeHZaGj73UnLnizjtup2xoij6Osdnz22qvHBQkQJrko6imtuzEbuduhIKkzrXoz3Pvi9NBtz+5eRT3XEHk4LMsden/70Y7e9W32KkCYRN0bqZujuzETeRhLEq0eA9+Nzmy7eCTJLNV9gedR7w+itDwj2Yv3UoOjl18dLUC4irOxC2YzOoB7jYwma1DsxGvfNeOY+4i9lrcxo62Dko1hGTQym/oY18Fu6fl+mQDhujOS3Sgr0QnUsp4sTE5ilLgb4bFfPHIj24zkdQTJRgxG1qNkCpM6cPoU5UO0Kce7BQhT7ARqWRvrADZieaIuc81qz+Q0RoSji30/fgqN/DPb0YBkEO1nLdpQ/fOdGQfKWbSjvZht7MefzVoFCDNamliK2chaBMlKdASjzmBwg2A5jXISF3oNsYP43Yfx74VGm07HwmQh2tFKBMlKtKnL7egmQTHejo7G2tF+/DczDQHCHJyU35aQRgZx4S/Fn8d/no91GAtj/4+z+OfRqHA8PEYXPt10Hp/vccwExvutUTsataHFsTC53I7Ooq0sxP/zZKyM2tKR6hYg5B9dTrIMsDDWgcCXBifakQCBz448QTtKzuPcARAgAAgQAAQIAAIEAAQIAAIEAAECgAABQIAAgAABQIAAIEAAECAACBAAECAACBAABAgAAgQAAQIAAgQAAQKAAAFAgAAgQABAgAAgQAAQII1ZUAUAAuSqzobl7bAcqwqA31tSBV90NCzPh2VbVQAIkEl9ivDYVRUAAmRS74bl55iBACBAvqrud7walpfxZwAEyFfV2cYv5WLDHAABMpG631GXrD6qCgABMqm631E3yw81BQABMonzcrHf8aLY7wAQIBM6jlmH/Q4AATIx+x0AAuTK3sfM48DHDiBAJjHa76j3d5z6yAEEyCTqfke9v+ONjxpAgEzK86wABMiV2e8AECBXYr8DQIBc2UnMOux3AAiQie2Vi/s77HcACJCJ2e8AECBXUvc7fi0Xz7Oy3wEgQCZivwNAgFyZ/Q4AAXJl7yM8fH8HgACZiP0OAAFyZXW/oz7P6rWPC0CATGq/XCxZ7fioAATI1yzGT/sdAALkSup+R12uqstWJz4iAAEyqZ+G5UMECQBJLZyf66cBuLpFVQCAAAFAgAAgQAAQIAAgQAAQIAAIEAAECAACBAAECAACBAABAoAAAUCAAIAAAUCAACBAABAgAAgQABAgAAgQAAQIAAIEgJ75fwEGABxQF9Ke8fBQAAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:95% 64%}
182
+ #the-list .wpmu-update-row{background-color:#031f34;border:none;color:#c0d7eb;background-size:100px}
183
+ #the-list .wpmu-update-row a{color:#3bb2df}
184
+ #the-list .wpmu-update-row a:hover{color:#e8da42;-webkit-transition:0.2s}
185
+ </style>
186
+ <?php
187
+ }
188
+
189
+ function get_id_plugin($plugin_file) {
190
+ return get_file_data( $plugin_file, array('name' => 'Plugin Name', 'id' => 'WDP ID', 'version' => 'Version') );
191
+ }
192
+
193
+ //simple check for updates
194
+ function updates_check() {
195
+ global $wp_version;
196
+ $local_projects = array();
197
+
198
+ //----------------------------------------------------------------------------------//
199
+ //plugins directory
200
+ //----------------------------------------------------------------------------------//
201
+ $plugins_root = WP_PLUGIN_DIR;
202
+ if( empty($plugins_root) ) {
203
+ $plugins_root = ABSPATH . 'wp-content/plugins';
204
+ }
205
+
206
+ $plugins_dir = @opendir($plugins_root);
207
+ $plugin_files = array();
208
+ if ( $plugins_dir ) {
209
+ while (($file = readdir( $plugins_dir ) ) !== false ) {
210
+ if ( substr($file, 0, 1) == '.' )
211
+ continue;
212
+ if ( is_dir( $plugins_root.'/'.$file ) ) {
213
+ $plugins_subdir = @ opendir( $plugins_root.'/'.$file );
214
+ if ( $plugins_subdir ) {
215
+ while (($subfile = readdir( $plugins_subdir ) ) !== false ) {
216
+ if ( substr($subfile, 0, 1) == '.' )
217
+ continue;
218
+ if ( substr($subfile, -4) == '.php' )
219
+ $plugin_files[] = "$file/$subfile";
220
+ }
221
+ }
222
+ } else {
223
+ if ( substr($file, -4) == '.php' )
224
+ $plugin_files[] = $file;
225
+ }
226
+ }
227
+ }
228
+ @closedir( $plugins_dir );
229
+ @closedir( $plugins_subdir );
230
+
231
+ if ( $plugins_dir && !empty($plugin_files) ) {
232
+ foreach ( $plugin_files as $plugin_file ) {
233
+ if ( is_readable( "$plugins_root/$plugin_file" ) ) {
234
+
235
+ unset($data);
236
+ $data = $this->get_id_plugin( "$plugins_root/$plugin_file" );
237
+
238
+ if ( isset($data['id']) && !empty($data['id']) ) {
239
+ $local_projects[$data['id']]['type'] = 'plugin';
240
+ $local_projects[$data['id']]['version'] = $data['version'];
241
+ $local_projects[$data['id']]['filename'] = $plugin_file;
242
+ }
243
+ }
244
+ }
245
+ }
246
+
247
+ //----------------------------------------------------------------------------------//
248
+ // mu-plugins directory
249
+ //----------------------------------------------------------------------------------//
250
+ $mu_plugins_root = WPMU_PLUGIN_DIR;
251
+ if( empty($mu_plugins_root) ) {
252
+ $mu_plugins_root = ABSPATH . 'wp-content/mu-plugins';
253
+ }
254
+
255
+ if ( is_dir($mu_plugins_root) && $mu_plugins_dir = @opendir($mu_plugins_root) ) {
256
+ while (($file = readdir( $mu_plugins_dir ) ) !== false ) {
257
+ if ( substr($file, -4) == '.php' ) {
258
+ if ( is_readable( "$mu_plugins_root/$file" ) ) {
259
+
260
+ unset($data);
261
+ $data = $this->get_id_plugin( "$mu_plugins_root/$file" );
262
+
263
+ if ( isset($data['id']) && !empty($data['id']) ) {
264
+ $local_projects[$data['id']]['type'] = 'mu-plugin';
265
+ $local_projects[$data['id']]['version'] = $data['version'];
266
+ $local_projects[$data['id']]['filename'] = $file;
267
+ }
268
+ }
269
+ }
270
+ }
271
+ @closedir( $mu_plugins_dir );
272
+ }
273
+
274
+ //----------------------------------------------------------------------------------//
275
+ // wp-content directory
276
+ //----------------------------------------------------------------------------------//
277
+ $content_plugins_root = WP_CONTENT_DIR;
278
+ if( empty($content_plugins_root) ) {
279
+ $content_plugins_root = ABSPATH . 'wp-content';
280
+ }
281
+
282
+ $content_plugins_dir = @opendir($content_plugins_root);
283
+ $content_plugin_files = array();
284
+ if ( $content_plugins_dir ) {
285
+ while (($file = readdir( $content_plugins_dir ) ) !== false ) {
286
+ if ( substr($file, 0, 1) == '.' )
287
+ continue;
288
+ if ( !is_dir( $content_plugins_root.'/'.$file ) ) {
289
+ if ( substr($file, -4) == '.php' )
290
+ $content_plugin_files[] = $file;
291
+ }
292
+ }
293
+ }
294
+ @closedir( $content_plugins_dir );
295
+
296
+ if ( $content_plugins_dir && !empty($content_plugin_files) ) {
297
+ foreach ( $content_plugin_files as $content_plugin_file ) {
298
+ if ( is_readable( "$content_plugins_root/$content_plugin_file" ) ) {
299
+ unset($data);
300
+ $data = $this->get_id_plugin( "$content_plugins_root/$content_plugin_file" );
301
+
302
+ if ( isset($data['id']) && !empty($data['id']) ) {
303
+ $local_projects[$data['id']]['type'] = 'drop-in';
304
+ $local_projects[$data['id']]['version'] = $data['version'];
305
+ $local_projects[$data['id']]['filename'] = $content_plugin_file;
306
+ }
307
+ }
308
+ }
309
+ }
310
+
311
+ //----------------------------------------------------------------------------------//
312
+ //themes directory
313
+ //----------------------------------------------------------------------------------//
314
+ $themes_root = WP_CONTENT_DIR . '/themes';
315
+ if ( empty($themes_root) ) {
316
+ $themes_root = ABSPATH . 'wp-content/themes';
317
+ }
318
+
319
+ $themes_dir = @opendir($themes_root);
320
+ $themes_files = array();
321
+ $local_themes = array();
322
+ if ( $themes_dir ) {
323
+ while (($file = readdir( $themes_dir ) ) !== false ) {
324
+ if ( substr($file, 0, 1) == '.' )
325
+ continue;
326
+ if ( is_dir( $themes_root.'/'.$file ) ) {
327
+ $themes_subdir = @ opendir( $themes_root.'/'.$file );
328
+ if ( $themes_subdir ) {
329
+ while (($subfile = readdir( $themes_subdir ) ) !== false ) {
330
+ if ( substr($subfile, 0, 1) == '.' )
331
+ continue;
332
+ if ( substr($subfile, -4) == '.css' )
333
+ $themes_files[] = "$file/$subfile";
334
+ }
335
+ }
336
+ } else {
337
+ if ( substr($file, -4) == '.css' )
338
+ $themes_files[] = $file;
339
+ }
340
+ }
341
+ }
342
+ @closedir( $themes_dir );
343
+ @closedir( $themes_subdir );
344
+
345
+ if ( $themes_dir && !empty($themes_files) ) {
346
+ foreach ( $themes_files as $themes_file ) {
347
+
348
+ //skip child themes
349
+ if ( strpos( $themes_file, '-child' ) !== false )
350
+ continue;
351
+
352
+ if ( is_readable( "$themes_root/$themes_file" ) ) {
353
+
354
+ unset($data);
355
+ $data = $this->get_id_plugin( "$themes_root/$themes_file" );
356
+
357
+ if ( isset($data['id']) && !empty($data['id']) ) {
358
+ $local_projects[$data['id']]['type'] = 'theme';
359
+ $local_projects[$data['id']]['filename'] = substr( $themes_file, 0, strpos( $themes_file, '/' ) );
360
+
361
+ //keep record of all themes for 133 themepack
362
+ if ($data['id'] == $this->theme_pack) {
363
+ $local_themes[$themes_file]['id'] = $data['id'];
364
+ $local_themes[$themes_file]['filename'] = substr( $themes_file, 0, strpos( $themes_file, '/' ) );
365
+ $local_themes[$themes_file]['version'] = $data['version'];
366
+ //increment 133 theme pack version to lowest in all of them
367
+ if ( isset($local_projects[$data['id']]['version']) && version_compare($data['version'], $local_projects[$data['id']]['version'], '<') ) {
368
+ $local_projects[$data['id']]['version'] = $data['version'];
369
+ } else if ( !isset($local_projects[$data['id']]['version']) ) {
370
+ $local_projects[$data['id']]['version'] = $data['version'];
371
+ }
372
+ } else {
373
+ $local_projects[$data['id']]['version'] = $data['version'];
374
+ }
375
+ }
376
+ }
377
+ }
378
+ }
379
+ update_site_option('wdp_un_local_themes', $local_themes);
380
+
381
+ update_site_option('wdp_un_local_projects', $local_projects);
382
+
383
+ //now check the API
384
+ $projects = '';
385
+ foreach ($local_projects as $pid => $project)
386
+ $projects .= "&p[$pid]=" . $project['version'];
387
+
388
+ //get WP/BP version string to help with support
389
+ $wp = is_multisite() ? "WordPress Multisite $wp_version" : "WordPress $wp_version";
390
+ if ( defined( 'BP_VERSION' ) )
391
+ $wp .= ', BuddyPress ' . BP_VERSION;
392
+
393
+ //add blog count if multisite
394
+ $blog_count = is_multisite() ? get_blog_count() : 1;
395
+
396
+ $url = $this->server_url . '?action=check&un-version=3.3.3&wp=' . urlencode($wp) . '&bcount=' . $blog_count . '&domain=' . urlencode(network_site_url()) . $projects;
397
+
398
+ $options = array(
399
+ 'timeout' => 15,
400
+ 'user-agent' => 'Dashboard Notification/' . $this->version
401
+ );
402
+
403
+ $response = wp_remote_get($url, $options);
404
+ if ( wp_remote_retrieve_response_code($response) == 200 ) {
405
+ $data = $response['body'];
406
+ if ( $data != 'error' ) {
407
+ $data = unserialize($data);
408
+ if ( is_array($data) ) {
409
+
410
+ //we've made it here with no errors, now check for available updates
411
+ $remote_projects = isset($data['projects']) ? $data['projects'] : array();
412
+ $updates = array();
413
+
414
+ //check for updates
415
+ if ( is_array($remote_projects) ) {
416
+ foreach ( $remote_projects as $id => $remote_project ) {
417
+ if ( isset($local_projects[$id]) && is_array($local_projects[$id]) ) {
418
+ //match
419
+ $local_version = $local_projects[$id]['version'];
420
+ $remote_version = $remote_project['version'];
421
+
422
+ if ( version_compare($remote_version, $local_version, '>') ) {
423
+ //add to array
424
+ $updates[$id] = $local_projects[$id];
425
+ $updates[$id]['url'] = $remote_project['url'];
426
+ $updates[$id]['instructions_url'] = $remote_project['instructions_url'];
427
+ $updates[$id]['support_url'] = $remote_project['support_url'];
428
+ $updates[$id]['name'] = $remote_project['name'];
429
+ $updates[$id]['thumbnail'] = $remote_project['thumbnail'];
430
+ $updates[$id]['version'] = $local_version;
431
+ $updates[$id]['new_version'] = $remote_version;
432
+ $updates[$id]['changelog'] = $remote_project['changelog'];
433
+ $updates[$id]['autoupdate'] = $remote_project['autoupdate'];
434
+ }
435
+ }
436
+ }
437
+
438
+ //record results
439
+ update_site_option('wdp_un_updates_available', $updates);
440
+ } else {
441
+ return false;
442
+ }
443
+ }
444
+ }
445
+ }
446
+ }
447
+
448
+ function filter_plugin_info($res, $action, $args) {
449
+ global $wp_version;
450
+ $cur_wp_version = preg_replace('/-.*$/', '', $wp_version);
451
+
452
+ //if in details iframe on update core page short-curcuit it
453
+ if ( ($action == 'plugin_information' || $action == 'theme_information') && strpos($args->slug, 'wpmudev_install') !== false ) {
454
+ $string = explode('-', $args->slug);
455
+ $id = intval($string[1]);
456
+ $updates = get_site_option('wdp_un_updates_available');
457
+ if ( did_action( 'install_plugins_pre_plugin-information' ) && is_array( $updates ) && isset($updates[$id]) ) {
458
+ echo '<iframe width="100%" height="100%" border="0" style="border:none;" src="' . $this->server_url . '?action=details&id=' . $id . '"></iframe>';
459
+ exit;
460
+ }
461
+
462
+ $res = new stdClass;
463
+ $res->name = $updates[$id]['name'];
464
+ $res->slug = sanitize_title($updates[$id]['name']);
465
+ $res->version = $updates[$id]['version'];
466
+ $res->rating = 100;
467
+ $res->homepage = $updates[$id]['url'];
468
+ $res->download_link = '';
469
+ $res->tested = $cur_wp_version;
470
+
471
+ return $res;
472
+ }
473
+
474
+ if ( $action == 'plugin_information' && strpos($args->slug, 'install_wpmudev_dash') !== false ) {
475
+ $res = new stdClass;
476
+ $res->name = 'WPMU DEV Dashboard';
477
+ $res->slug = 'wpmu-dev-dashboard';
478
+ $res->version = '';
479
+ $res->rating = 100;
480
+ $res->homepage = 'http://premium.wpmudev.org/project/wpmu-dev-dashboard/';
481
+ $res->download_link = $this->server_url . "?action=install_wpmudev_dash";
482
+ $res->tested = $cur_wp_version;
483
+
484
+ return $res;
485
+ }
486
+
487
+ return $res;
488
+ }
489
+
490
+ function filter_plugin_rows() {
491
+ if ( !current_user_can( 'update_plugins' ) )
492
+ return;
493
+
494
+ $updates = get_site_option('wdp_un_updates_available');
495
+ if ( is_array($updates) && count($updates) ) {
496
+ foreach ( $updates as $id => $plugin ) {
497
+ if ( $plugin['autoupdate'] != '2' ) {
498
+ if ( $plugin['type'] == 'theme' ) {
499
+ remove_all_actions( 'after_theme_row_' . $plugin['filename'] );
500
+ add_action('after_theme_row_' . $plugin['filename'], array( &$this, 'plugin_row'), 9, 2 );
501
+ } else {
502
+ remove_all_actions( 'after_plugin_row_' . $plugin['filename'] );
503
+ add_action('after_plugin_row_' . $plugin['filename'], array( &$this, 'plugin_row'), 9, 2 );
504
+ }
505
+ }
506
+ }
507
+ }
508
+
509
+ $local_themes = get_site_option('wdp_un_local_themes');
510
+ if ( is_array($local_themes) && count($local_themes) ) {
511
+ foreach ( $local_themes as $id => $plugin ) {
512
+ remove_all_actions( 'after_theme_row_' . $plugin['filename'] );
513
+ //only add the notice if specific version is wrong
514
+ if ( isset($updates[$this->theme_pack]) && version_compare($plugin['version'], $updates[$this->theme_pack]['new_version'], '<') ) {
515
+ add_action('after_theme_row_' . $plugin['filename'], array( &$this, 'themepack_row'), 9, 2 );
516
+ }
517
+ }
518
+ }
519
+ }
520
+
521
+ function filter_plugin_count( $value ) {
522
+
523
+ //remove any conflicting slug local WPMU DEV plugins from WP update notifications
524
+ $local_projects = get_site_option('wdp_un_local_projects');
525
+ if ( is_array($local_projects) && count($local_projects) ) {
526
+ foreach ( $local_projects as $id => $plugin ) {
527
+ if (isset($value->response[$plugin['filename']]))
528
+ unset($value->response[$plugin['filename']]);
529
+ }
530
+ }
531
+
532
+ $updates = get_site_option('wdp_un_updates_available');
533
+ if ( is_array($updates) && count($updates) ) {
534
+ foreach ( $updates as $id => $plugin ) {
535
+ if ( $plugin['type'] != 'theme' && $plugin['autoupdate'] != '2' ) {
536
+
537
+ //build plugin class
538
+ $object = new stdClass;
539
+ $object->url = $plugin['url'];
540
+ $object->slug = "wpmudev_install-$id";
541
+ $object->upgrade_notice = $plugin['changelog'];
542
+ $object->new_version = $plugin['new_version'];
543
+ $object->package = '';
544
+
545
+ //add to class
546
+ $value->response[$plugin['filename']] = $object;
547
+ }
548
+ }
549
+ }
550
+
551
+ return $value;
552
+ }
553
+
554
+ function filter_theme_count( $value ) {
555
+
556
+ $updates = get_site_option('wdp_un_updates_available');
557
+ if ( is_array($updates) && count($updates) ) {
558
+ foreach ( $updates as $id => $theme ) {
559
+ if ( $theme['type'] == 'theme' && $theme['autoupdate'] != '2' ) {
560
+ //build theme listing
561
+ $value->response[$theme['filename']]['url'] = $this->server_url . '?action=details&id=' . $id;
562
+ $value->response[$theme['filename']]['new_version'] = $theme['new_version'];
563
+ $value->response[$theme['filename']]['package'] = '';
564
+ }
565
+ }
566
+ }
567
+
568
+ //filter 133 theme pack themes from the list unless update is available
569
+ $local_themes = get_site_option('wdp_un_local_themes');
570
+ if ( is_array($local_themes) && count($local_themes) ) {
571
+ foreach ( $local_themes as $id => $theme ) {
572
+ //add to count only if new version exists, otherwise remove
573
+ if (isset($updates[$theme['id']]) && isset($updates[$theme['id']]['new_version']) && version_compare($theme['version'], $updates[$theme['id']]['new_version'], '<')) {
574
+ $value->response[$theme['filename']]['new_version'] = $updates[$theme['id']]['new_version'];
575
+ $value->response[$theme['filename']]['package'] = '';
576
+ } else if (isset($value) && isset($value->response) && isset($theme['filename']) && isset($value->response[$theme['filename']])) {
577
+ unset($value->response[$theme['filename']]);
578
+ }
579
+ }
580
+ }
581
+
582
+ return $value;
583
+ }
584
+
585
+ function plugin_row( $file, $plugin_data ) {
586
+
587
+ //get new version and update url
588
+ $updates = get_site_option('wdp_un_updates_available');
589
+ if ( is_array($updates) && count($updates) ) {
590
+ foreach ( $updates as $id => $plugin ) {
591
+ if ($plugin['filename'] == $file) {
592
+ $project_id = $id;
593
+ $version = $plugin['new_version'];
594
+ $plugin_url = $plugin['url'];
595
+ $autoupdate = $plugin['autoupdate'];
596
+ $filename = $plugin['filename'];
597
+ $type = $plugin['type'];
598
+ break;
599
+ }
600
+ }
601
+ } else {
602
+ return false;
603
+ }
604
+
605
+ $plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array());
606
+ $plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags );
607
+
608
+ $info_url = $this->server_url . '?action=details&id=' . $project_id . '&TB_iframe=true&width=640&height=800';
609
+ if ( file_exists(WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php') ) {
610
+ $message = "Activate WPMU DEV Dashboard";
611
+ $action_url = $this->activate_url();
612
+ } else { //dashboard not installed at all
613
+ $message = "Install WPMU DEV Dashboard";
614
+ $action_url = $this->auto_install_url();
615
+ }
616
+
617
+ if ( current_user_can('update_plugins') ) {
618
+ echo '<tr class="plugin-update-tr"><td colspan="3" class="plugin-update colspanchange"><div class="update-message wpmu-update-row">';
619
+ printf( 'There is a new version of %1$s available on WPMU DEV. <a href="%2$s" class="thickbox" title="%3$s">View version %4$s details</a> or <a href="%5$s">%6$s</a> to update.', $plugin_name, esc_url($info_url), esc_attr($plugin_name), $version, esc_url($action_url), $message );
620
+ echo '</div></td></tr>';
621
+ }
622
+ }
623
+
624
+ function themepack_row( $file, $plugin_data ) {
625
+
626
+ //get new version and update url
627
+ $updates = get_site_option('wdp_un_updates_available');
628
+ if ( isset($updates[$this->theme_pack]) ) {
629
+ $plugin = $updates[$this->theme_pack];
630
+ $project_id = $this->theme_pack;
631
+ $version = $plugin['new_version'];
632
+ $plugin_url = $plugin['url'];
633
+ } else {
634
+ return false;
635
+ }
636
+
637
+ $plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array());
638
+ $plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags );
639
+
640
+ $info_url = $this->server_url . '?action=details&id=' . $project_id . '&TB_iframe=true&width=640&height=800';
641
+ if ( file_exists(WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php') ) {
642
+ $message = "Activate WPMU DEV Dashboard";
643
+ $action_url = $this->activate_url();
644
+ } else { //dashboard not installed at all
645
+ $message = "Install WPMU DEV Dashboard";
646
+ $action_url = $this->auto_install_url();
647
+ }
648
+
649
+ if ( current_user_can('update_themes') ) {
650
+ echo '<tr class="plugin-update-tr"><td colspan="3" class="plugin-update colspanchange"><div class="update-message">';
651
+ printf( 'There is a new version of %1$s available on WPMU DEV. <a href="%2$s" class="thickbox" title="%3$s">View version %4$s details</a> or <a href="%5$s">%6$s</a> to update.', $plugin_name, esc_url($info_url), esc_attr($plugin_name), $version, esc_url($action_url), $message );
652
+ echo '</div></td></tr>';
653
+ }
654
+ }
655
+
656
+ function disable_checkboxes() {
657
+
658
+ $updates = get_site_option('wdp_un_updates_available');
659
+ if ( !is_array( $updates ) || ( is_array( $updates ) && !count( $updates ) ) ) {
660
+ return;
661
+ }
662
+
663
+ $jquery = '';
664
+ foreach ( (array) $updates as $id => $plugin) {
665
+ $jquery .= "<script type='text/javascript'>jQuery(\"input:checkbox[value='".esc_attr($plugin['filename'])."']\").remove();</script>\n";
666
+ }
667
+
668
+ //disable checkboxes for 133 theme pack themes
669
+ $local_themes = get_site_option('wdp_un_local_themes');
670
+ if ( is_array($local_themes) && count($local_themes) ) {
671
+ foreach ( $local_themes as $id => $theme ) {
672
+ $jquery .= "<script type='text/javascript'>jQuery(\"input:checkbox[value='".esc_attr($theme['filename'])."']\").remove();</script>\n";
673
+ }
674
+ }
675
+ echo $jquery;
676
+ }
677
+
678
+ function set_activate_flag($plugin) {
679
+ $data = $this->get_id_plugin( WP_PLUGIN_DIR . '/' . $plugin );
680
+ if ( isset($data['id']) && !empty($data['id']) ) {
681
+ update_site_option('wdp_un_activated_flag', 1);
682
+ }
683
+ }
684
+
685
+ }
686
+ $WPMUDEV_Dashboard_Notice3 = new WPMUDEV_Dashboard_Notice3();
687
+ }
688
+
689
+ //disable older version
690
+ if ( !class_exists('WPMUDEV_Dashboard_Notice') ) {
691
+ class WPMUDEV_Dashboard_Notice {}
692
+ }
languages/wp-smush.pot ADDED
@@ -0,0 +1,299 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2015
2
+ # This file is distributed under the same license as the package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: \n"
6
+ "Report-Msgid-Bugs-To: http://premium.wpmudev.org/\n"
7
+ "POT-Creation-Date: 2015-04-13 21:45:18+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+
15
+ #: lib/class-wp-smush-admin.php:166 lib/class-wp-smush-admin.php:876
16
+ msgid "Bulk Smush Now"
17
+ msgstr ""
18
+
19
+ #: lib/class-wp-smush-admin.php:168 lib/class-wp-smush-admin.php:880
20
+ msgid "Bulk Smush %d Attachments"
21
+ msgstr ""
22
+
23
+ #: lib/class-wp-smush-admin.php:172
24
+ msgid "Smushing in Progress"
25
+ msgstr ""
26
+
27
+ #: lib/class-wp-smush-admin.php:173 lib/class-wp-smush-admin.php:870
28
+ msgid "All Done!"
29
+ msgstr ""
30
+
31
+ #: lib/class-wp-smush-admin.php:175
32
+ msgid "Ops!... something went wrong"
33
+ msgstr ""
34
+
35
+ #: lib/class-wp-smush-admin.php:176 wp-smush.php:745
36
+ msgid "Re-smush"
37
+ msgstr ""
38
+
39
+ #: lib/class-wp-smush-admin.php:177
40
+ msgid "Smush it"
41
+ msgstr ""
42
+
43
+ #: lib/class-wp-smush-admin.php:178
44
+ msgid "Smush Now"
45
+ msgstr ""
46
+
47
+ #: lib/class-wp-smush-admin.php:179
48
+ msgid "Sending ..."
49
+ msgstr ""
50
+
51
+ #: lib/class-wp-smush-admin.php:180
52
+ msgid "{{errors}} image(s) were skipped due to an error."
53
+ msgstr ""
54
+
55
+ #: lib/class-wp-smush-admin.php:206
56
+ msgid "Auto-Smush images on upload"
57
+ msgstr ""
58
+
59
+ #: lib/class-wp-smush-admin.php:207
60
+ msgid "Super-Smush images"
61
+ msgstr ""
62
+
63
+ #: lib/class-wp-smush-admin.php:207
64
+ msgid "lossy optimization"
65
+ msgstr ""
66
+
67
+ #: lib/class-wp-smush-admin.php:208
68
+ msgid "Backup original images"
69
+ msgstr ""
70
+
71
+ #: lib/class-wp-smush-admin.php:208
72
+ msgid "this will nearly double the size of your uploads directory"
73
+ msgstr ""
74
+
75
+ #: lib/class-wp-smush-admin.php:222
76
+ msgid "WP Smush Pro"
77
+ msgstr ""
78
+
79
+ #: lib/class-wp-smush-admin.php:224
80
+ msgid "WP Smush"
81
+ msgstr ""
82
+
83
+ #: lib/class-wp-smush-admin.php:230
84
+ msgid "Thanks for using WP Smush Pro! You now can:"
85
+ msgstr ""
86
+
87
+ #: lib/class-wp-smush-admin.php:232 lib/class-wp-smush-admin.php:243
88
+ msgid "\"Super-Smush\" your images with our intelligent multi-pass lossy compression. Get &gt;60% average compression with almost no noticeable quality loss!"
89
+ msgstr ""
90
+
91
+ #: lib/class-wp-smush-admin.php:233 lib/class-wp-smush-admin.php:244
92
+ msgid "Get the best lossless compression. We try multiple methods to squeeze every last byte out of your images."
93
+ msgstr ""
94
+
95
+ #: lib/class-wp-smush-admin.php:234
96
+ msgid "Smush images up to 8MB."
97
+ msgstr ""
98
+
99
+ #: lib/class-wp-smush-admin.php:235
100
+ msgid "Bulk smush ALL your images with one click!"
101
+ msgstr ""
102
+
103
+ #: lib/class-wp-smush-admin.php:236 lib/class-wp-smush-admin.php:247
104
+ msgid "Keep a backup of your original un-smushed images in case you want to restore later."
105
+ msgstr ""
106
+
107
+ #: lib/class-wp-smush-admin.php:241
108
+ msgid "Upgrade to WP Smush Pro to:"
109
+ msgstr ""
110
+
111
+ #: lib/class-wp-smush-admin.php:245
112
+ msgid "Smush images greater than 1MB."
113
+ msgstr ""
114
+
115
+ #: lib/class-wp-smush-admin.php:246
116
+ msgid "Bulk smush ALL your images with one click! No more rate limiting."
117
+ msgstr ""
118
+
119
+ #: lib/class-wp-smush-admin.php:248
120
+ msgid "Access 24/7/365 support from <a href=\"https://premium.wpmudev.org/support/?utm_source=wordpress.org&utm_medium=plugin&utm_campaign=WP%20Smush%20Upgrade\">the best WordPress support team on the planet</a>."
121
+ msgstr ""
122
+
123
+ #: lib/class-wp-smush-admin.php:249
124
+ msgid "Download <a href=\"https://premium.wpmudev.org/?utm_source=wordpress.org&utm_medium=plugin&utm_campaign=WP%20Smush%20Upgrade\">350+ other premium plugins and themes</a> included in your membership."
125
+ msgstr ""
126
+
127
+ #: lib/class-wp-smush-admin.php:251
128
+ msgid "Upgrade Now &raquo;"
129
+ msgstr ""
130
+
131
+ #: lib/class-wp-smush-admin.php:253
132
+ msgid "Already upgraded to a WPMU DEV membership? Install and Login to our Dashboard plugin to enable Smush Pro features."
133
+ msgstr ""
134
+
135
+ #: lib/class-wp-smush-admin.php:261
136
+ msgid "Activate WPMU DEV Dashboard"
137
+ msgstr ""
138
+
139
+ #: lib/class-wp-smush-admin.php:264
140
+ msgid "Install WPMU DEV Dashboard"
141
+ msgstr ""
142
+
143
+ #: lib/class-wp-smush-admin.php:275 lib/class-wp-smush-admin.php:969
144
+ msgid "Settings"
145
+ msgstr ""
146
+
147
+ #: lib/class-wp-smush-admin.php:312
148
+ msgid "Save Changes"
149
+ msgstr ""
150
+
151
+ #: lib/class-wp-smush-admin.php:384
152
+ msgid "%d image is over 1MB so will be skipped using the free version of the plugin."
153
+ msgid_plural "%d images are over 1MB so will be skipped using the free version of the plugin."
154
+ msgstr[0] ""
155
+ msgstr[1] ""
156
+
157
+ #: lib/class-wp-smush-admin.php:393
158
+ msgid "Smush in Bulk"
159
+ msgstr ""
160
+
161
+ #: lib/class-wp-smush-admin.php:398
162
+ msgid "Congratulations, all your images are currently Smushed!"
163
+ msgstr ""
164
+
165
+ #: lib/class-wp-smush-admin.php:404
166
+ msgid "%d attachment in your media library has not been smushed."
167
+ msgid_plural "%d image attachments in your media library have not been smushed yet."
168
+ msgstr[0] ""
169
+ msgstr[1] ""
170
+
171
+ #: lib/class-wp-smush-admin.php:408
172
+ msgid "Remove size limit &raquo;"
173
+ msgstr ""
174
+
175
+ #: lib/class-wp-smush-admin.php:413
176
+ msgid ""
177
+ "Please be aware, smushing a large number of images can take a while depending on your server and network speed.\n"
178
+ "\t\t\t\t\t\t<strong>You must keep this page open while the bulk smush is processing</strong>, but you can leave at any time and come back to continue where it left off."
179
+ msgstr ""
180
+
181
+ #: lib/class-wp-smush-admin.php:418
182
+ msgid "Free accounts are limited to bulk smushing %d attachments per request. You will need to click to start a new bulk job after each %d attachments."
183
+ msgstr ""
184
+
185
+ #: lib/class-wp-smush-admin.php:419
186
+ msgid "Remove limits &raquo;"
187
+ msgstr ""
188
+
189
+ #: lib/class-wp-smush-admin.php:439
190
+ msgid "When you <a href=\"%s\">upload some images</a> they will be available to smush here."
191
+ msgstr ""
192
+
193
+ #: lib/class-wp-smush-admin.php:445 lib/class-wp-smush-admin.php:690
194
+ msgid "You can also smush images individually from your <a href=\"%s\">Media Library</a>."
195
+ msgstr ""
196
+
197
+ #: lib/class-wp-smush-admin.php:496
198
+ msgid "Reduced by "
199
+ msgstr ""
200
+
201
+ #: lib/class-wp-smush-admin.php:506
202
+ msgid "<span class=\"done-count\">%d</span> of <span class=\"total-count\">%d</span> total attachments have been smushed"
203
+ msgstr ""
204
+
205
+ #: lib/class-wp-smush-admin.php:523
206
+ msgid "Smushing <span id=\"smushed-count\">1</span> of <span id=\"smushing-total\">%d</span>"
207
+ msgstr ""
208
+
209
+ #: lib/class-wp-smush-admin.php:589
210
+ msgid "You don't have permission to work with uploaded files."
211
+ msgstr ""
212
+
213
+ #: lib/class-wp-smush-admin.php:593
214
+ msgid "No attachment ID was provided."
215
+ msgstr ""
216
+
217
+ #: lib/class-wp-smush-admin.php:660
218
+ msgid "<p>Please <a href=\"%s\">upload some images</a>.</p>"
219
+ msgstr ""
220
+
221
+ #: lib/class-wp-smush-admin.php:678
222
+ msgid "All your images are already smushed!"
223
+ msgstr ""
224
+
225
+ #: lib/class-wp-smush-admin.php:778
226
+ msgid "<strong>%d of %d images</strong> were sent for smushing:"
227
+ msgstr ""
228
+
229
+ #: wp-smush.php:132
230
+ msgid "File path is empty"
231
+ msgstr ""
232
+
233
+ #: wp-smush.php:136
234
+ msgid "File URL is empty"
235
+ msgstr ""
236
+
237
+ #: wp-smush.php:141
238
+ msgid "Could not find %s"
239
+ msgstr ""
240
+
241
+ #: wp-smush.php:146
242
+ msgid "%s is not writable"
243
+ msgstr ""
244
+
245
+ #: wp-smush.php:156
246
+ msgid "Skipped (%s), image not found."
247
+ msgstr ""
248
+
249
+ #: wp-smush.php:161
250
+ msgid "Skipped (%s), size limit exceeded."
251
+ msgstr ""
252
+
253
+ #: wp-smush.php:176
254
+ msgid "Unknown API error"
255
+ msgstr ""
256
+
257
+ #: wp-smush.php:315 wp-smush.php:432
258
+ msgid "Size '%s' not processed correctly"
259
+ msgstr ""
260
+
261
+ #: wp-smush.php:337 wp-smush.php:345 wp-smush.php:454 wp-smush.php:462
262
+ msgid "Size 'full' not processed correctly"
263
+ msgstr ""
264
+
265
+ #: wp-smush.php:531
266
+ msgid "Error posting to API: %s"
267
+ msgstr ""
268
+
269
+ #: wp-smush.php:537
270
+ msgid "Error posting to API: %s %s"
271
+ msgstr ""
272
+
273
+ #: wp-smush.php:554
274
+ msgid "Smush data corrupted, try again."
275
+ msgstr ""
276
+
277
+ #: wp-smush.php:570
278
+ msgid "Image couldn't be smushed"
279
+ msgstr ""
280
+
281
+ #: wp-smush.php:734
282
+ msgid "Error processing request"
283
+ msgstr ""
284
+
285
+ #: wp-smush.php:738
286
+ msgid "Already Optimized"
287
+ msgstr ""
288
+
289
+ #: wp-smush.php:740
290
+ msgid "Reduced by %s ( %01.1f%% )"
291
+ msgstr ""
292
+
293
+ #: wp-smush.php:749
294
+ msgid "Not processed"
295
+ msgstr ""
296
+
297
+ #: wp-smush.php:755
298
+ msgid "Smush Now!"
299
+ msgstr ""
languages/wp_smushit-default.mo DELETED
Binary file
languages/wp_smushit-default.po DELETED
@@ -1,250 +0,0 @@
1
- # Translation of the WordPress plugin WP Smush.it 1.6.5.2 by WPMU DEV.
2
- # Copyright (C) 2015 WPMU DEV
3
- # This file is distributed under the same license as the WP Smush.it package.
4
- # FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
5
- #
6
- msgid ""
7
- msgstr ""
8
- "Project-Id-Version: WP Smush.it 1.6.5.2\n"
9
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-smushit\n"
10
- "POT-Creation-Date: 2013-09-02 08:12-0500\n"
11
- "PO-Revision-Date: 2013-09-02 09:13-0500\n"
12
- "Last-Translator: Paul Menard <paul@codehooligans.com>\n"
13
- "Language-Team: \n"
14
- "MIME-Version: 1.0\n"
15
- "Content-Type: text/plain; charset=UTF-8\n"
16
- "Content-Transfer-Encoding: 8bit\n"
17
- "X-Poedit-Language: English\n"
18
-
19
- #: wp-smushit.php:110
20
- msgid "Use Smush.it on upload?"
21
- msgstr ""
22
-
23
- #: wp-smushit.php:113
24
- msgid "How many seconds should we wait for a response from Smush.it?"
25
- msgstr ""
26
-
27
- #: wp-smushit.php:116
28
- msgid "Enable debug processing"
29
- msgstr ""
30
-
31
- #: wp-smushit.php:131
32
- msgid "Automatically process on upload"
33
- msgstr ""
34
-
35
- #: wp-smushit.php:132
36
- msgid "Do not process on upload"
37
- msgstr ""
38
-
39
- #: wp-smushit.php:136
40
- #, php-format
41
- msgid "Temporarily disabled until %s"
42
- msgstr ""
43
-
44
- #: wp-smushit.php:150
45
- msgid "If you are having trouble with the plugin enable this option can reveal some information about your system needed for support."
46
- msgstr ""
47
-
48
- #: wp-smushit.php:195
49
- msgid "Bulk WP Smush.it"
50
- msgstr ""
51
-
52
- #: wp-smushit.php:199
53
- msgid "<p>You don't appear to have uploaded any images yet.</p>"
54
- msgstr ""
55
-
56
- #: wp-smushit.php:203
57
- msgid "<p>This tool will run all of the images in your media library through the WP Smush.it web service. Any image already processed will not be reprocessed. Any new images or unsuccessful attempts will be processed.</p>"
58
- msgstr ""
59
-
60
- #: wp-smushit.php:204
61
- msgid "<p>As part of the Yahoo! Smush.it API this plugin wil provide a URL to each of your images to be processed. The Yahoo! service will download the image via the URL. The Yahoo Smush.it service will then return a URL to this plugin of the new version of the image. This image will be downloaded and replace the original image on your server.</p>"
62
- msgstr ""
63
-
64
- #: wp-smushit.php:206
65
- msgid "<p>Limitations of using the Yahoo Smush.it API</p>"
66
- msgstr ""
67
-
68
- #: wp-smushit.php:209
69
- msgid "The image MUST be less than 1 megabyte in size. This is a limit of the Yahoo! service not this plugin."
70
- msgstr ""
71
-
72
- #: wp-smushit.php:210
73
- msgid "The image MUST be accessible via a non-https URL. The Yahoo! Smush.it service will not handle https:// image URLs. This is a limit of the Yahoo! service not this plugin."
74
- msgstr ""
75
-
76
- #: wp-smushit.php:211
77
- msgid "The image MUST publicly accessible server. As the Yahoo! Smush.it service needs to download the image via a URL the image needs to be on a public server and not a local development system. This is a limit of the Yahoo! service not this plugin."
78
- msgstr ""
79
-
80
- #: wp-smushit.php:212
81
- msgid "The image MUST be local to the site. This plugin cannot update images stored on Content Delivery Networks (CDN)"
82
- msgstr ""
83
-
84
- #: wp-smushit.php:215
85
- #, php-format
86
- msgid "<p><strong>This is an experimental feature.</strong> Please post any feedback to the %s.</p>"
87
- msgstr ""
88
-
89
- #: wp-smushit.php:215
90
- msgid "WordPress WP Smush.it forums"
91
- msgstr ""
92
-
93
- #: wp-smushit.php:219
94
- #, php-format
95
- msgid "<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>"
96
- msgstr ""
97
-
98
- #: wp-smushit.php:222
99
- msgid "Run all my images through WP Smush.it right now"
100
- msgstr ""
101
-
102
- #: wp-smushit.php:223
103
- msgid "<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>"
104
- msgstr ""
105
-
106
- #: wp-smushit.php:226
107
- msgid "<p>DEBUG mode is currently enabled. To disable see the Settings > Media page.</p>"
108
- msgstr ""
109
-
110
- #: wp-smushit.php:234
111
- msgid "Cheatin&#8217; uh?"
112
- msgstr ""
113
-
114
- #: wp-smushit.php:241
115
- #, php-format
116
- msgid "<p>Processing <strong>%s</strong>&hellip;<br />"
117
- msgstr ""
118
-
119
- #: wp-smushit.php:251
120
- #: wp-smushit.php:409
121
- msgid "No savings"
122
- msgstr ""
123
-
124
- #: wp-smushit.php:252
125
- #: wp-smushit.php:264
126
- msgid "<strong>already smushed</strong>"
127
- msgstr ""
128
-
129
- #: wp-smushit.php:280
130
- msgid "<hr /></p>Smush.it finished processing.</p>"
131
- msgstr ""
132
-
133
- #: wp-smushit.php:293
134
- msgid "You don't have permission to work with uploaded files."
135
- msgstr ""
136
-
137
- #: wp-smushit.php:297
138
- msgid "No attachment ID was provided."
139
- msgstr ""
140
-
141
- #: wp-smushit.php:323
142
- msgid "File path is empty"
143
- msgstr ""
144
-
145
- #: wp-smushit.php:327
146
- msgid "File URL is empty"
147
- msgstr ""
148
-
149
- #: wp-smushit.php:333
150
- msgid "Did not smush due to previous errors"
151
- msgstr ""
152
-
153
- #: wp-smushit.php:338
154
- #, php-format
155
- msgid "Could not find <span class='code'>%s</span>"
156
- msgstr ""
157
-
158
- #: wp-smushit.php:343
159
- #, php-format
160
- msgid "<span class='code'>%s</span> is not writable"
161
- msgstr ""
162
-
163
- #: wp-smushit.php:348
164
- #, php-format
165
- msgid "<span style=\"color:#FF0000;\">Skipped (%s) Unable to Smush due to Yahoo 1mb size limits. See <a href=\"http://developer.yahoo.com/yslow/smushit/faq.html#faq_restrict\">FAQ</a></span>"
166
- msgstr ""
167
-
168
- #: wp-smushit.php:359
169
- #, php-format
170
- msgid "<span class='code'>%s</span> must be within the website directory (<span class='code'>%s</span>)"
171
- msgstr ""
172
-
173
- #: wp-smushit.php:371
174
- #, php-format
175
- msgid "<span class='code'>%s</span> must be within the website home URL (<span class='code'>%s</span>)"
176
- msgstr ""
177
-
178
- #: wp-smushit.php:382
179
- msgid "Error posting to Smush.it"
180
- msgstr ""
181
-
182
- #: wp-smushit.php:388
183
- #: wp-smushit.php:406
184
- msgid "Bad response from Smush.it"
185
- msgstr ""
186
-
187
- #: wp-smushit.php:412
188
- msgid "Smush.it error: "
189
- msgstr ""
190
-
191
- #: wp-smushit.php:412
192
- msgid "unknown error"
193
- msgstr ""
194
-
195
- #: wp-smushit.php:413
196
- #, php-format
197
- msgid " while processing <span class='code'>%s</span> (<span class='code'>%s</span>)"
198
- msgstr ""
199
-
200
- #: wp-smushit.php:429
201
- #, php-format
202
- msgid "Error downloading file (%s)"
203
- msgstr ""
204
-
205
- #: wp-smushit.php:433
206
- #, php-format
207
- msgid "Unable to locate Smuch.it downloaded file (%s)"
208
- msgstr ""
209
-
210
- #: wp-smushit.php:447
211
- #, php-format
212
- msgid "Reduced by %01.1f%% (%s)"
213
- msgstr ""
214
-
215
- #: wp-smushit.php:545
216
- msgid "WP Smush.it requires WordPress 2.8 or greater"
217
- msgstr ""
218
-
219
- #: wp-smushit.php:585
220
- msgid "Re-smush"
221
- msgstr ""
222
-
223
- #: wp-smushit.php:588
224
- msgid "Not processed"
225
- msgstr ""
226
-
227
- #: wp-smushit.php:591
228
- msgid "Smush.it now!"
229
- msgstr ""
230
-
231
- #. Plugin Name of the plugin/theme
232
- msgid "WP Smush.it"
233
- msgstr ""
234
-
235
- #. Plugin URI of the plugin/theme
236
- msgid "http://wordpress.org/extend/plugins/wp-smushit/"
237
- msgstr ""
238
-
239
- #. Description of the plugin/theme
240
- msgid "Reduce image file sizes and improve performance using the <a href=\"http://smush.it/\">Smush.it</a> API within WordPress."
241
- msgstr ""
242
-
243
- #. Author of the plugin/theme
244
- msgid "WPMU DEV"
245
- msgstr ""
246
-
247
- #. Author URI of the plugin/theme
248
- msgid "http://premium.wpmudev.org/"
249
- msgstr ""
250
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/wp_smushit-default.pot DELETED
@@ -1,324 +0,0 @@
1
- # Translation of the WordPress plugin WP Smush.it 1.7 by WPMU DEV.
2
- # Copyright (C) 2015 WP Smush.it
3
- # This file is distributed under the same license as the WP Smush.it package.
4
- msgid ""
5
- msgstr ""
6
- "Project-Id-Version: WP Smush.it 1.7\n"
7
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-smushit\n"
8
- "POT-Creation-Date: 2015-01-14 08:39:56+00:00\n"
9
- "MIME-Version: 1.0\n"
10
- "Content-Type: text/plain; charset=UTF-8\n"
11
- "Content-Transfer-Encoding: 8bit\n"
12
- "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
13
- "Last-Translator: Umesh Kumar <umeshsingla05@gmail.com>\n"
14
- "Language-Team: WPMU Dev <http://premium.wpmudev.org/>\n"
15
-
16
- #: lib/class-wp-smushit-admin.php:91
17
- msgid "Smushing in Progress"
18
- msgstr ""
19
-
20
- #: lib/class-wp-smushit-admin.php:92
21
- msgid "All done!"
22
- msgstr ""
23
-
24
- #. #-#-#-#-# plugin.pot (WP Smush.it 1.7) #-#-#-#-#
25
- #. Plugin Name of the plugin/theme
26
- #: lib/class-wp-smushit-admin.php:112
27
- msgid "WP Smush.it"
28
- msgstr ""
29
-
30
- #: lib/class-wp-smushit-admin.php:117
31
- msgid "Settings"
32
- msgstr ""
33
-
34
- #: lib/class-wp-smushit-admin.php:145
35
- msgid "Temporarily disabled until %s"
36
- msgstr ""
37
-
38
- #: lib/class-wp-smushit-admin.php:162
39
- msgid "Smush images on upload"
40
- msgstr ""
41
-
42
- #: lib/class-wp-smushit-admin.php:165
43
- msgid "Automatically process on upload"
44
- msgstr ""
45
-
46
- #: lib/class-wp-smushit-admin.php:166
47
- msgid "Do not process on upload"
48
- msgstr ""
49
-
50
- #: lib/class-wp-smushit-admin.php:176
51
- msgid "API Timeout"
52
- msgstr ""
53
-
54
- #: lib/class-wp-smushit-admin.php:182
55
- msgid "Enforce home URL"
56
- msgstr ""
57
-
58
- #: lib/class-wp-smushit-admin.php:185
59
- msgid ""
60
- "By default the plugin will enforce that the image URL is the same domain as "
61
- "the home. If you are using a sub-domain pointed to this same host or an "
62
- "external Content Delivery Network (CDN) you want to unset this option."
63
- msgstr ""
64
-
65
- #: lib/class-wp-smushit-admin.php:189
66
- msgid "Smushit Debug"
67
- msgstr ""
68
-
69
- #: lib/class-wp-smushit-admin.php:192
70
- msgid ""
71
- "If you are having trouble with the plugin enable this option can reveal some "
72
- "information about your system needed for support."
73
- msgstr ""
74
-
75
- #: lib/class-wp-smushit-admin.php:200
76
- msgid "Save Changes"
77
- msgstr ""
78
-
79
- #: lib/class-wp-smushit-admin.php:271
80
- msgid ""
81
- " %d of those images %s <b>over 1Mb</b> and <b>can not be compressed using "
82
- "the free version of the plugin.</b>"
83
- msgstr ""
84
-
85
- #: lib/class-wp-smushit-admin.php:277
86
- msgid "Smush in Bulk"
87
- msgstr ""
88
-
89
- #: lib/class-wp-smushit-admin.php:281
90
- msgid "<p>You don't appear to have uploaded any images yet.</p>"
91
- msgstr ""
92
-
93
- #: lib/class-wp-smushit-admin.php:284
94
- msgid "Upgrade to WP Smush PRO"
95
- msgstr ""
96
-
97
- #: lib/class-wp-smushit-admin.php:285
98
- msgid ""
99
- "<h4>WP Smush.it uses Yahoo! Smush.it API. As such, there are a few "
100
- "restrictions:</h4>"
101
- msgstr ""
102
-
103
- #: lib/class-wp-smushit-admin.php:288
104
- msgid ""
105
- "Each image MUST be less than 1Mb in size. %s and use our servers for images "
106
- "upto 5Mb."
107
- msgstr ""
108
-
109
- #: lib/class-wp-smushit-admin.php:289
110
- msgid ""
111
- "Images MUST be accessible via a non-https URL. The Yahoo! Smush.it service "
112
- "will not handle https:// image URLs. %s to allow https URLs"
113
- msgstr ""
114
-
115
- #: lib/class-wp-smushit-admin.php:290
116
- msgid ""
117
- "Smushing images in bulk can sometimes cause time-outs. %s and use our "
118
- "reliable server to prevent time-outs."
119
- msgstr ""
120
-
121
- #: lib/class-wp-smushit-admin.php:293
122
- msgid ""
123
- "<strong>WP Smush PRO</strong> allows you to smush images up to 5Mb.<br /> "
124
- "Fast, reliable & time-out free. <a href='http://premium.wpmudev.org/projects/"
125
- "wp-smush-pro'>Find Out more &raquo;</a>"
126
- msgstr ""
127
-
128
- #: lib/class-wp-smushit-admin.php:305
129
- msgid "<p>We found %d images in your media library. %s </p>"
130
- msgstr ""
131
-
132
- #: lib/class-wp-smushit-admin.php:307
133
- msgid ""
134
- "<p><b style='color: red;'>Please beware</b>, <b>smushing a large number of "
135
- "images can take a long time.</b></p>"
136
- msgstr ""
137
-
138
- #: lib/class-wp-smushit-admin.php:309
139
- msgid ""
140
- "<p><b>You can not leave this page, until all images have been received back, "
141
- "and you see a success message.</b></p>"
142
- msgstr ""
143
-
144
- #: lib/class-wp-smushit-admin.php:311
145
- msgid ""
146
- "Click below to smush all your images. Alternatively, you can smush your "
147
- "images individually or as a bulk action from your <a href='%s'>Media "
148
- "Library</a>"
149
- msgstr ""
150
-
151
- #: lib/class-wp-smushit-admin.php:318
152
- msgid "Bulk Smush all my images"
153
- msgstr ""
154
-
155
- #: lib/class-wp-smushit-admin.php:319
156
- msgid ""
157
- "<p><em>N.B. If your server <tt>gzip</tt>s content you may not see the "
158
- "progress updates as your files are processed.</em></p>"
159
- msgstr ""
160
-
161
- #: lib/class-wp-smushit-admin.php:322
162
- msgid ""
163
- "<p>DEBUG mode is currently enabled. To disable uncheck the smushit debug "
164
- "option.</p>"
165
- msgstr ""
166
-
167
- #: lib/class-wp-smushit-admin.php:362
168
- msgid ""
169
- "Smushing <span id=\"smushed-count\">1</span> of <span id=\"smushing-total\">"
170
- "%d</span>"
171
- msgstr ""
172
-
173
- #: lib/class-wp-smushit-admin.php:403
174
- msgid "Nonce verification failed"
175
- msgstr ""
176
-
177
- #: lib/error_log.php:9
178
- msgid "Error Log"
179
- msgstr ""
180
-
181
- #: lib/error_log.php:13
182
- msgid "Purge log"
183
- msgstr ""
184
-
185
- #: lib/error_log.php:17 lib/error_log.php:25 lib/error_log.php:55
186
- #: lib/error_log.php:62
187
- msgid "Date"
188
- msgstr ""
189
-
190
- #: lib/error_log.php:18 lib/error_log.php:26
191
- msgid "Function"
192
- msgstr ""
193
-
194
- #: lib/error_log.php:19 lib/error_log.php:27
195
- msgid "Image"
196
- msgstr ""
197
-
198
- #: lib/error_log.php:20 lib/error_log.php:28
199
- msgid "Info"
200
- msgstr ""
201
-
202
- #: lib/error_log.php:56 lib/error_log.php:63
203
- msgid "User"
204
- msgstr ""
205
-
206
- #: lib/error_log.php:57 lib/error_log.php:64
207
- msgid "Message"
208
- msgstr ""
209
-
210
- #: lib/error_log.php:72
211
- msgid "Unknown"
212
- msgstr ""
213
-
214
- #: wp-smushit.php:114
215
- msgid "You don't have permission to work with uploaded files."
216
- msgstr ""
217
-
218
- #: wp-smushit.php:118
219
- msgid "No attachment ID was provided."
220
- msgstr ""
221
-
222
- #: wp-smushit.php:146
223
- msgid "File path is empty"
224
- msgstr ""
225
-
226
- #: wp-smushit.php:150
227
- msgid "File URL is empty"
228
- msgstr ""
229
-
230
- #: wp-smushit.php:156
231
- msgid "Did not Smush.it due to previous errors"
232
- msgstr ""
233
-
234
- #: wp-smushit.php:161
235
- msgid "ERROR: Could not find <span class='code'>%s</span>"
236
- msgstr ""
237
-
238
- #: wp-smushit.php:166
239
- msgid "ERROR: <span class='code'>%s</span> is not writable"
240
- msgstr ""
241
-
242
- #: wp-smushit.php:171
243
- msgid ""
244
- "ERROR: <span style=\"color:#FF0000;\">Skipped (%s) Unable to Smush due to "
245
- "Yahoo 1mb size limits. See <a href=\"http://developer.yahoo.com/yslow/"
246
- "smushit/faq.html#faq_restrict\">FAQ</a></span>"
247
- msgstr ""
248
-
249
- #: wp-smushit.php:204
250
- msgid ""
251
- "ERROR: <span class='code'>%s</span> must be within the website home URL "
252
- "(<span class='code'>%s</span>)"
253
- msgstr ""
254
-
255
- #: wp-smushit.php:217
256
- msgid "ERROR: posting to Smush.it"
257
- msgstr ""
258
-
259
- #: wp-smushit.php:223 wp-smushit.php:252
260
- msgid "Bad response from Smush.it"
261
- msgstr ""
262
-
263
- #: wp-smushit.php:256
264
- msgid "No savings"
265
- msgstr ""
266
-
267
- #: wp-smushit.php:260
268
- msgid "Smush.it error: "
269
- msgstr ""
270
-
271
- #: wp-smushit.php:260
272
- msgid "unknown error"
273
- msgstr ""
274
-
275
- #: wp-smushit.php:261
276
- msgid ""
277
- " while processing <span class='code'>%s</span> (<span class='code'>%s</span>)"
278
- msgstr ""
279
-
280
- #: wp-smushit.php:279
281
- msgid "Error downloading file (%s)"
282
- msgstr ""
283
-
284
- #: wp-smushit.php:283
285
- msgid "Unable to locate Smushed file (%s)"
286
- msgstr ""
287
-
288
- #: wp-smushit.php:297
289
- msgid "Reduced by %01.1f%% (%s)"
290
- msgstr ""
291
-
292
- #: wp-smushit.php:393
293
- msgid "WP Smush.it requires WordPress 2.8 or greater"
294
- msgstr ""
295
-
296
- #: wp-smushit.php:435
297
- msgid "Re-smush"
298
- msgstr ""
299
-
300
- #: wp-smushit.php:438
301
- msgid "Not processed"
302
- msgstr ""
303
-
304
- #: wp-smushit.php:441
305
- msgid "Smush.it now!"
306
- msgstr ""
307
-
308
- #. Plugin URI of the plugin/theme
309
- msgid "http://wordpress.org/extend/plugins/wp-smushit/"
310
- msgstr ""
311
-
312
- #. Description of the plugin/theme
313
- msgid ""
314
- "Reduce image file sizes and improve performance using the <a href=\"http://"
315
- "smush.it/\">Smush.it</a> API within WordPress."
316
- msgstr ""
317
-
318
- #. Author of the plugin/theme
319
- msgid "WPMU DEV"
320
- msgstr ""
321
-
322
- #. Author URI of the plugin/theme
323
- msgid "http://premium.wpmudev.org/"
324
- msgstr ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/wp_smushit-it_IT.po DELETED
@@ -1,208 +0,0 @@
1
- # Copyright (C) 2015 WP Smush.it
2
- # This file is distributed under the same license as the WP Smush.it package.
3
- msgid ""
4
- msgstr ""
5
- "Project-Id-Version: WP Smush.it 1.6.5\n"
6
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/wp-smushit\n"
7
- "POT-Creation-Date: 2013-05-08 07:05:03+00:00\n"
8
- "MIME-Version: 1.0\n"
9
- "Content-Type: text/plain; charset=UTF-8\n"
10
- "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2013-05-08 09:08+0100\n"
12
- "Last-Translator: Daniele Arduini <d.arduini@optimalab.it>\n"
13
- "Language-Team: WPMU DEV\n"
14
-
15
- #: wp-smushit.php:103
16
- msgid "Use Smush.it on upload?"
17
- msgstr "Uso Smush.it negli upload?"
18
-
19
- #: wp-smushit.php:104
20
- msgid "How many seconds should we wait for a response from Smush.it?"
21
- msgstr "Quanti secondi occorre attendere per una risposta da Smush.it?"
22
-
23
- #: wp-smushit.php:116
24
- msgid "Automatically process on upload"
25
- msgstr "Elabora automaticamente sull'upload"
26
-
27
- #: wp-smushit.php:117
28
- msgid "Do not process on upload"
29
- msgstr "Non elaborare sull'upload"
30
-
31
- #: wp-smushit.php:121
32
- msgid "Temporarily disabled until %s"
33
- msgstr "Temporaneamente disabilitato fino a %s"
34
-
35
- #: wp-smushit.php:174
36
- msgid "Bulk WP Smush.it"
37
- msgstr "Smush.it massivo"
38
-
39
- #: wp-smushit.php:178
40
- msgid "<p>You don&#39;t appear to have uploaded any images yet.</p>"
41
- msgstr "<p>Apparentemente al momento non sono state inviate immagini.</p>"
42
-
43
- #: wp-smushit.php:182
44
- msgid ""
45
- "<p>This tool will run all of the images in your media library through the WP "
46
- "Smush.it web service. It won't re-smush images that were successfully "
47
- "smushed before. It will retry images that were not successfully smushed.</p>"
48
- msgstr ""
49
- "<p>Questo strumento processer&agrave; tutte le immagini presenti nella galleria attraverso il servizio web "
50
- "WP Smush.it. Non processer&agrave; nuovamente le immagini gi&agrave; ridotte precedentemente con "
51
- "successo. Cercher&agrave; di riprocessare le immagini che non sono state ridotte con successo.</p>"
52
-
53
- #: wp-smushit.php:184
54
- msgid ""
55
- "<p>It uploads each and every file to Yahoo! and then downloads the resulting "
56
- "file. It can take a long time.</p>"
57
- msgstr ""
58
- "<p>Ogni immagine verr&agrave; inviata a Yahoo! e quindi scaricata l&#39;immagine risultante."
59
- "L&#39;operazione potrebbe impiegare molto tempo.</p>"
60
-
61
- #: wp-smushit.php:186
62
- msgid ""
63
- "<p>We found %d images in your media library. Be forewarned, <strong>it will "
64
- "take <em>at least</em> %d minutes</strong> to process all these images if "
65
- "they have never been smushed before.</p>"
66
- msgstr ""
67
- "<p>Sono state trovate %d immagini nella galleria. Si avverte che <strong>si impiegheranno "
68
- "<em>come minimo</em> %d minuti</strong> per elaborare tutte queste immagini se "
69
- "non sono mai state elaborate in precedenza.</p>"
70
-
71
- #: wp-smushit.php:188
72
- msgid ""
73
- "<p><em>N.B. If your server <tt>gzip</tt>s content you may not see the "
74
- "progress updates as your files are processed.</em></p>"
75
- msgstr ""
76
- "<p><em>NOTA: Se il tuo server comprime i contenuti con <tt>gzip</tt> potresti non vedere "
77
- "l&#39;aggiornamento dello stato durante il processo di elaborazione delle immagini.</em></p>"
78
-
79
- #: wp-smushit.php:190
80
- msgid ""
81
- "<p><strong>This is an experimental feature.</strong> Please post any "
82
- "feedback to the %s.</p>"
83
- msgstr ""
84
- "<p><strong>Questa &egrave; una funzionalit&agrave; sperimentale.</strong> Per favore invia ogni "
85
- "commento al %s.</p>"
86
-
87
- #: wp-smushit.php:190
88
- msgid "WordPress WP Smush.it forums"
89
- msgstr "Forum di WordPress WP Smush.it"
90
-
91
- #: wp-smushit.php:194
92
- msgid "Run all my images through WP Smush.it right now"
93
- msgstr "Avvia l&#39;elaborazione delle immagini tramite WP Smush.it"
94
-
95
- #: wp-smushit.php:201
96
- msgid "Cheatin&#8217; uh?"
97
- msgstr "Fai il furbo eh?"
98
-
99
- #: wp-smushit.php:254
100
- msgid "You don't have permission to work with uploaded files."
101
- msgstr "Non si hanno i permessi per elaborare i file inviati."
102
-
103
- #: wp-smushit.php:258
104
- msgid "No attachment ID was provided."
105
- msgstr "Non &egrave; stato fornito alcun ID allegato."
106
-
107
- #: wp-smushit.php:294
108
- msgid "Did not smush due to previous errors"
109
- msgstr "Smush non effetuato a causa dei precedenti errori"
110
-
111
- #: wp-smushit.php:301
112
- msgid "Could not find <span class='code'>%s</span>"
113
- msgstr "Impossibile trovare <span class='code'>%s</span>"
114
-
115
- #: wp-smushit.php:307
116
- msgid "<span class='code'>%s</span> is not writable"
117
- msgstr "<span class='code'>%s</span> non &egrave; scrivibile"
118
-
119
- #: wp-smushit.php:313
120
- msgid ""
121
- "<a href='http://developer.yahoo.com/yslow/smushit/faq.html#faq_restrict'>Too "
122
- "big</a> for Smush.it (%s)"
123
- msgstr ""
124
- "<a href='http://developer.yahoo.com/yslow/smushit/faq.html#faq_restrict'>Troppo "
125
- "grande</a> per Smush.it (%s)"
126
-
127
- #: wp-smushit.php:322
128
- msgid ""
129
- "<span class='code'>%s</span> must be within the content directory (<span "
130
- "class='code'>%s</span>)"
131
- msgstr ""
132
- "<span class='code'>%s</span> deve essere all'interno della cartella dei contenuti (<span "
133
- "class='code'>%s</span>)"
134
-
135
- #: wp-smushit.php:337
136
- msgid "Error posting to Smush.it"
137
- msgstr "Errore d'invio a Smush.it"
138
-
139
- #: wp-smushit.php:343 wp-smushit.php:356
140
- msgid "Bad response from Smush.it"
141
- msgstr "Risposta errata da Smush.it"
142
-
143
- #: wp-smushit.php:359
144
- msgid "No savings"
145
- msgstr "Nessun risparmio"
146
-
147
- #: wp-smushit.php:362
148
- msgid "Smush.it error: "
149
- msgstr "Errore Smush.it: "
150
-
151
- #: wp-smushit.php:362
152
- msgid "unknown error"
153
- msgstr "errore sconosciuto"
154
-
155
- #: wp-smushit.php:363
156
- msgid ""
157
- " while processing <span class='code'>%s</span> (<span class='code'>%s</span>)"
158
- msgstr ""
159
- " durante l'elaborazione di <span class='code'>%s</span> (<span class='code'>%s</span>)"
160
-
161
- #: wp-smushit.php:379
162
- msgid "Error downloading file (%s)"
163
- msgstr "Errore scaricando il file (%s)"
164
-
165
- #: wp-smushit.php:390
166
- msgid "Reduced by %01.1f%% (%s)"
167
- msgstr "Ridotta del %01.1f%% (%s)"
168
-
169
- #: wp-smushit.php:482
170
- msgid "WP Smush.it requires WordPress 2.8 or greater"
171
- msgstr "WP Smush.it richiede WordPress 2.8 o superiore"
172
-
173
- #: wp-smushit.php:522
174
- msgid "Re-smush"
175
- msgstr "Ri-smush"
176
-
177
- #: wp-smushit.php:525
178
- msgid "Not processed"
179
- msgstr "Non elaborata"
180
-
181
- #: wp-smushit.php:528
182
- msgid "Smush.it now!"
183
- msgstr "Smush.it adesso!"
184
-
185
- #. Plugin Name of the plugin/theme
186
- msgid "WP Smush.it"
187
- msgstr "WP Smush.it"
188
-
189
- #. Plugin URI of the plugin/theme
190
- msgid "http://wordpress.org/extend/plugins/wp-smushit/"
191
- msgstr "http://wordpress.org/extend/plugins/wp-smushit/"
192
-
193
- #. Description of the plugin/theme
194
- msgid ""
195
- "Reduce image file sizes and improve performance using the <a href=\"http://"
196
- "smush.it/\">Smush.it</a> API within WordPress."
197
- msgstr ""
198
- "Riduce la dimensione delle immagini e migliora le prestazioni utilizzando le "
199
- "API Wordpress di <a href=\"http://smush.it/\">Smush.it</a>."
200
-
201
- #. Author of the plugin/theme
202
- msgid "WPMU DEV"
203
- msgstr "WPMU DEV"
204
-
205
- #. Author URI of the plugin/theme
206
- msgid "http://premium.wpmudev.org/"
207
- msgstr "http://premium.wpmudev.org/"
208
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/class-wp-smush-admin.php ADDED
@@ -0,0 +1,978 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP SmushIt
4
+ * @subpackage Admin
5
+ * @version 1.0
6
+ *
7
+ * @author Saurabh Shukla <saurabh@incsub.com>
8
+ * @author Umesh Kumar <umesh@incsub.com>
9
+ *
10
+ * @copyright (c) 2014, Incsub (http://incsub.com)
11
+ */
12
+ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
13
+ /**
14
+ * Show settings in Media settings and add column to media library
15
+ *
16
+ */
17
+
18
+ /**
19
+ * Class WpSmushitAdmin
20
+ *
21
+ * @property int $remaining_count
22
+ * @property int $total_count
23
+ * @property int $smushed_count
24
+ * @property int $exceeding_items_count
25
+ */
26
+ class WpSmushitAdmin extends WpSmush {
27
+
28
+ /**
29
+ *
30
+ * @var array Settings
31
+ */
32
+ public $settings;
33
+
34
+ public $bulk;
35
+
36
+ public $total_count;
37
+
38
+ public $smushed_count;
39
+
40
+ public $stats;
41
+
42
+ public $max_free_bulk = 50; //this is enforced at api level too
43
+
44
+ public $upgrade_url = 'https://premium.wpmudev.org/project/wp-smush-pro/?utm_source=wordpress.org&utm_medium=plugin&utm_campaign=WP%20Smush%20Upgrade';
45
+
46
+ /**
47
+ * Constructor
48
+ */
49
+ public function __construct() {
50
+
51
+ // hook scripts and styles
52
+ add_action( 'admin_init', array( $this, 'register' ) );
53
+
54
+ // hook custom screen
55
+ add_action( 'admin_menu', array( $this, 'screen' ) );
56
+
57
+ //Handle Smush Bulk Ajax
58
+ add_action( 'wp_ajax_wp_smushit_bulk', array( $this, 'process_smush_request' ) );
59
+
60
+
61
+ //Handle Smush Single Ajax
62
+ add_action( 'wp_ajax_wp_smushit_manual', array( $this, 'smush_single' ) );
63
+
64
+ add_action( "admin_enqueue_scripts", array( $this, "admin_enqueue_scripts" ) );
65
+
66
+ add_filter( 'plugin_action_links_' . WP_SMUSH_BASENAME, array(
67
+ $this,
68
+ 'settings_link'
69
+ ) );
70
+ add_filter( 'network_admin_plugin_action_links_' . WP_SMUSH_BASENAME, array(
71
+ $this,
72
+ 'settings_link'
73
+ ) );
74
+ //Attachment status, Grid view
75
+ add_action( 'wp_ajax_attachment_status', array( $this, 'attachment_status' ) );
76
+
77
+ // hook into admin footer to load a hidden html/css spinner
78
+ add_action( 'admin_footer-upload.php', array( $this, 'print_loader' ) );
79
+
80
+ $this->total_count = $this->total_count();
81
+ $this->smushed_count = $this->smushed_count();
82
+ $this->stats = $this->global_stats();
83
+
84
+ $this->init_settings();
85
+
86
+ }
87
+
88
+ function __get($prop){
89
+
90
+ if( method_exists("WpSmushitAdmin", $prop ) ){
91
+ return $this->$prop();
92
+ }
93
+
94
+ $method_name = "get_" . $prop;
95
+ if( method_exists("WpSmushitAdmin", $method_name ) ){
96
+ return $this->$method_name();
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Add Bulk option settings page
102
+ */
103
+ function screen() {
104
+ global $hook_suffix;
105
+ $admin_page_suffix = add_media_page( 'Bulk WP Smush', 'WP Smush', 'edit_others_posts', 'wp-smush-bulk', array(
106
+ $this,
107
+ 'ui'
108
+ ) );
109
+ // enqueue js only on this screen
110
+ add_action( 'admin_print_scripts-' . $admin_page_suffix, array( $this, 'enqueue' ) );
111
+
112
+ // Enqueue js on media screen
113
+ add_action( 'admin_print_scripts-upload.php', array( $this, 'enqueue' ) );
114
+ }
115
+
116
+ /**
117
+ * Register js and css
118
+ */
119
+ function register() {
120
+ global $WpSmush;
121
+ // Register js for smush utton in grid view
122
+ $current_blog_id = get_current_blog_id();
123
+ $meta_key = $current_blog_id == 1 ? 'wp_media_library_mode' : 'wp_' . $current_blog_id . '_media_library_mode';
124
+ $wp_media_library_mode = get_user_meta( get_current_user_id(), $meta_key, true );
125
+
126
+ //Either request variable is not empty and grid mode is set, or if request empty then view is as per user choice, or no view is set
127
+ if ( ( ! empty( $_REQUEST['mode'] ) && $_REQUEST['mode'] == 'grid' ) ||
128
+ ( empty( $_REQUEST['mode'] ) && $wp_media_library_mode != 'list' )
129
+ ) {
130
+ wp_register_script( 'wp-smushit-admin-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin.js', array(
131
+ 'jquery',
132
+ 'media-views'
133
+ ), WP_SMUSH_VERSON );
134
+ } else {
135
+ wp_register_script( 'wp-smushit-admin-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin.js', array(
136
+ 'jquery',
137
+ 'underscore'
138
+ ), WP_SMUSH_VERSON );
139
+ }
140
+
141
+
142
+ /* Register Style. */
143
+ wp_register_style( 'wp-smushit-admin-css', WP_SMUSH_URL . 'assets/css/wp-smushit-admin.css', array(), $WpSmush->version );
144
+
145
+ // localize translatable strings for js
146
+ $this->localize();
147
+
148
+ wp_enqueue_script( 'wp-smushit-admin-media-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin-media.js', array( 'jquery' ), $WpSmush->version );
149
+
150
+ }
151
+
152
+ /**
153
+ * enqueue js and css
154
+ */
155
+ function enqueue() {
156
+ wp_enqueue_script( 'wp-smushit-admin-js' );
157
+ wp_enqueue_style( 'wp-smushit-admin-css' );
158
+ }
159
+
160
+
161
+ function localize() {
162
+ $bulk = new WpSmushitBulk();
163
+ $handle = 'wp-smushit-admin-js';
164
+
165
+ if ( $this->is_premium() || $this->remaining_count <= $this->max_free_bulk ) {
166
+ $bulk_now = __( 'Bulk Smush Now', WP_SMUSH_DOMAIN );
167
+ } else {
168
+ $bulk_now = sprintf( __( 'Bulk Smush %d Attachments', WP_SMUSH_DOMAIN ), $this->max_free_bulk);
169
+ }
170
+
171
+ $wp_smush_msgs = array(
172
+ 'progress' => __( 'Smushing in Progress', WP_SMUSH_DOMAIN ),
173
+ 'done' => __( 'All Done!', WP_SMUSH_DOMAIN ),
174
+ 'bulk_now' => $bulk_now,
175
+ 'something_went_wrong' => __( 'Ops!... something went wrong', WP_SMUSH_DOMAIN ),
176
+ 'resmush' => __( 'Re-smush', WP_SMUSH_DOMAIN ),
177
+ 'smush_it' => __( 'Smush it', WP_SMUSH_DOMAIN ),
178
+ 'smush_now' => __( 'Smush Now', WP_SMUSH_DOMAIN ),
179
+ 'sending' => __( 'Sending ...', WP_SMUSH_DOMAIN ),
180
+ "error_in_bulk" => __( '{{errors}} image(s) were skipped due to an error.', WP_SMUSH_DOMAIN)
181
+ );
182
+
183
+ wp_localize_script( $handle, 'wp_smush_msgs', $wp_smush_msgs );
184
+
185
+ //Localize smushit_ids variable, if there are fix number of ids
186
+ $ids = ! empty( $_REQUEST['ids'] ) ? explode( ',', $_REQUEST['ids'] ) : $bulk->get_attachments();
187
+
188
+ $data = array(
189
+ 'smushed' => $this->get_smushed_image_ids(),
190
+ 'unsmushed' => $ids
191
+ );
192
+
193
+ wp_localize_script( 'wp-smushit-admin-js', 'wp_smushit_data', $data );
194
+
195
+ }
196
+
197
+ function admin_enqueue_scripts() {
198
+ wp_enqueue_script( 'wp-smushit-admin-media-js' );
199
+ }
200
+
201
+ /**
202
+ * Translation ready settings
203
+ */
204
+ function init_settings() {
205
+ $this->settings = array(
206
+ 'auto' => __( 'Auto-Smush images on upload', WP_SMUSH_DOMAIN ),
207
+ 'lossy' => __( 'Super-Smush images', WP_SMUSH_DOMAIN ) . ' <small>(' . __( 'lossy optimization', WP_SMUSH_DOMAIN ) . ')</small>',
208
+ 'backup' => __( 'Backup original images', WP_SMUSH_DOMAIN ) . ' <small>(' . __( 'this will nearly double the size of your uploads directory', WP_SMUSH_DOMAIN ) . ')</small>'
209
+ );
210
+ }
211
+
212
+ /**
213
+ * Display the ui
214
+ */
215
+ function ui() {
216
+ ?>
217
+ <div class="wrap">
218
+
219
+ <h2>
220
+ <?php
221
+ if ( $this->is_premium() ) {
222
+ _e( 'WP Smush Pro', WP_SMUSH_DOMAIN );
223
+ } else {
224
+ _e( 'WP Smush', WP_SMUSH_DOMAIN );
225
+ } ?>
226
+ </h2>
227
+
228
+ <?php if ( $this->is_premium() ) { ?>
229
+ <div class="wp-smpushit-features updated">
230
+ <h3><?php _e( 'Thanks for using WP Smush Pro! You now can:', WP_SMUSH_DOMAIN ) ?></h3>
231
+ <ol>
232
+ <li><?php _e( '"Super-Smush" your images with our intelligent multi-pass lossy compression. Get &gt;60% average compression with almost no noticeable quality loss!', WP_SMUSH_DOMAIN ); ?></li>
233
+ <li><?php _e( 'Get the best lossless compression. We try multiple methods to squeeze every last byte out of your images.', WP_SMUSH_DOMAIN ); ?></li>
234
+ <li><?php _e( 'Smush images up to 8MB.', WP_SMUSH_DOMAIN ); ?></li>
235
+ <li><?php _e( 'Bulk smush ALL your images with one click!', WP_SMUSH_DOMAIN ); ?></li>
236
+ <li><?php _e( 'Keep a backup of your original un-smushed images in case you want to restore later.', WP_SMUSH_DOMAIN ); ?></li>
237
+ </ol>
238
+ </div>
239
+ <?php } else { ?>
240
+ <div class="wp-smpushit-features error">
241
+ <h3><?php _e( 'Upgrade to WP Smush Pro to:', WP_SMUSH_DOMAIN ) ?></h3>
242
+ <ol>
243
+ <li><?php _e( '"Super-Smush" your images with our intelligent multi-pass lossy compression. Get &gt;60% average compression with almost no noticeable quality loss!', WP_SMUSH_DOMAIN ); ?></li>
244
+ <li><?php _e( 'Get the best lossless compression. We try multiple methods to squeeze every last byte out of your images.', WP_SMUSH_DOMAIN ); ?></li>
245
+ <li><?php _e( 'Smush images greater than 1MB.', WP_SMUSH_DOMAIN ); ?></li>
246
+ <li><?php _e( 'Bulk smush ALL your images with one click! No more rate limiting.', WP_SMUSH_DOMAIN ); ?></li>
247
+ <li><?php _e( 'Keep a backup of your original un-smushed images in case you want to restore later.', WP_SMUSH_DOMAIN ); ?></li>
248
+ <li><?php _e( 'Access 24/7/365 support from <a href="https://premium.wpmudev.org/support/?utm_source=wordpress.org&utm_medium=plugin&utm_campaign=WP%20Smush%20Upgrade">the best WordPress support team on the planet</a>.', WP_SMUSH_DOMAIN ); ?></li>
249
+ <li><?php _e( 'Download <a href="https://premium.wpmudev.org/?utm_source=wordpress.org&utm_medium=plugin&utm_campaign=WP%20Smush%20Upgrade">350+ other premium plugins and themes</a> included in your membership.', WP_SMUSH_DOMAIN ); ?></li>
250
+ </ol>
251
+ <p><a class="button-primary" href="<?php echo $this->upgrade_url; ?>"><?php _e( 'Upgrade Now &raquo;', WP_SMUSH_DOMAIN ); ?></a></p>
252
+
253
+ <p><?php _e( 'Already upgraded to a WPMU DEV membership? Install and Login to our Dashboard plugin to enable Smush Pro features.', WP_SMUSH_DOMAIN ); ?></p>
254
+ <p>
255
+ <?php
256
+ if ( ! class_exists( 'WPMUDEV_Dashboard' ) ) {
257
+ if ( file_exists( WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php' ) ) {
258
+ $function = is_multisite() ? 'network_admin_url' : 'admin_url';
259
+ $url = wp_nonce_url( $function( 'plugins.php?action=activate&plugin=wpmudev-updates%2Fupdate-notifications.php' ), 'activate-plugin_wpmudev-updates/update-notifications.php' );
260
+ ?><a class="button-secondary"
261
+ href="<?php echo $url; ?>"><?php _e( 'Activate WPMU DEV Dashboard', WP_SMUSH_DOMAIN ); ?></a><?php
262
+ } else { //dashboard not installed at all
263
+ ?><a class="button-secondary" target="_blank"
264
+ href="https://premium.wpmudev.org/project/wpmu-dev-dashboard/"><?php _e( 'Install WPMU DEV Dashboard', WP_SMUSH_DOMAIN ); ?></a><?php
265
+ }
266
+ }
267
+ ?>
268
+ </p>
269
+ </div>
270
+ <?php } ?>
271
+
272
+
273
+ <div class="wp-smpushit-container">
274
+ <h3>
275
+ <?php _e( 'Settings', WP_SMUSH_DOMAIN ) ?>
276
+ </h3>
277
+ <?php
278
+ // display the options
279
+ $this->options_ui();
280
+
281
+ //Bulk Smushing
282
+ $this->bulk_preview();
283
+ ?>
284
+ </div>
285
+ </div>
286
+ <?php
287
+ $this->print_loader();
288
+ }
289
+
290
+ /**
291
+ * Process and display the options form
292
+ */
293
+ function options_ui() {
294
+
295
+ // Save settings, if needed
296
+ $this->process_options();
297
+
298
+ ?>
299
+ <form action="" method="post">
300
+
301
+ <ul id="wp-smush-options-wrap">
302
+ <?php
303
+ // display each setting
304
+ foreach ( $this->settings as $name => $text ) {
305
+ echo $this->render_checked( $name, $text );
306
+ }
307
+ ?>
308
+ </ul><?php
309
+ // nonce
310
+ wp_nonce_field( 'save_wp_smush_options', 'wp_smush_options_nonce' );
311
+ ?>
312
+ <input type="submit" id="wp-smush-save-settings" class="button button-primary" value="<?php _e( 'Save Changes', WP_SMUSH_DOMAIN ); ?>">
313
+ </form>
314
+ <?php
315
+ }
316
+
317
+ /**
318
+ * Check if form is submitted and process it
319
+ *
320
+ * @return null
321
+ */
322
+ function process_options() {
323
+ // we aren't saving options
324
+ if ( ! isset( $_POST['wp_smush_options_nonce'] ) ) {
325
+ return;
326
+ }
327
+ // the nonce doesn't pan out
328
+ if ( ! wp_verify_nonce( $_POST['wp_smush_options_nonce'], 'save_wp_smush_options' ) ) {
329
+ return;
330
+ }
331
+ // var to temporarily assign the option value
332
+ $setting = null;
333
+
334
+ // process each setting and update options
335
+ foreach ( $this->settings as $name => $text ) {
336
+ // formulate the index of option
337
+ $opt_name = WP_SMUSH_PREFIX . $name;
338
+
339
+ // get the value to be saved
340
+ $setting = isset( $_POST[ $opt_name ] ) ? 1 : 0;
341
+
342
+ // update the new value
343
+ update_option( $opt_name, $setting );
344
+
345
+ // unset the var for next loop
346
+ unset( $setting );
347
+ }
348
+
349
+ }
350
+
351
+ /**
352
+ * Returns number of images of larger than 1Mb size
353
+ *
354
+ * @return int
355
+ */
356
+ function get_exceeding_items_count(){
357
+ $count = 0;
358
+ $bulk = new WpSmushitBulk();
359
+ $attachments = $bulk->get_attachments();
360
+ //Check images bigger than 1Mb, used to display the count of images that can't be smushed
361
+ foreach ( $attachments as $attachment ) {
362
+ if ( file_exists( get_attached_file( $attachment ) ) ) {
363
+ $size = filesize( get_attached_file( $attachment ) );
364
+ }
365
+ if ( empty( $size ) || ! ( ( $size / WP_SMUSH_MAX_BYTES ) > 1 ) ) {
366
+ continue;
367
+ }
368
+ $count ++;
369
+ }
370
+
371
+ return $count;
372
+ }
373
+
374
+ /**
375
+ * Bulk Smushing UI
376
+ */
377
+ function bulk_preview() {
378
+
379
+ $exceed_mb = '';
380
+ if ( ! $this->is_premium() ) {
381
+
382
+ if ( $this->exceeding_items_count ) {
383
+ $exceed_mb = sprintf(
384
+ _n( "%d image is over 1MB so will be skipped using the free version of the plugin.",
385
+ "%d images are over 1MB so will be skipped using the free version of the plugin.", $this->exceeding_items_count, WP_SMUSH_DOMAIN ),
386
+ $this->exceeding_items_count
387
+ );
388
+ }
389
+ }
390
+ ?>
391
+ <hr>
392
+ <div class="bulk-smush">
393
+ <h3><?php _e( 'Smush in Bulk', WP_SMUSH_DOMAIN ) ?></h3>
394
+ <?php
395
+
396
+ if ( $this->remaining_count == 0 ) {
397
+ ?>
398
+ <p><?php _e( "Congratulations, all your images are currently Smushed!", WP_SMUSH_DOMAIN ); ?></p>
399
+ <?php
400
+ $this->progress_ui();
401
+ } else {
402
+ ?>
403
+ <div class="smush-instructions">
404
+ <h4 class="smush-remaining-images-notice"><?php printf( _n( "%d attachment in your media library has not been smushed.", "%d image attachments in your media library have not been smushed yet.", $this->remaining_count, WP_SMUSH_DOMAIN ), $this->remaining_count ); ?></h4>
405
+ <?php if ( $exceed_mb ) { ?>
406
+ <p class="error">
407
+ <?php echo $exceed_mb; ?>
408
+ <a href="<?php echo $this->upgrade_url; ?>"><?php _e( 'Remove size limit &raquo;', WP_SMUSH_DOMAIN ); ?></a>
409
+ </p>
410
+
411
+ <?php } ?>
412
+
413
+ <p><?php _e( "Please be aware, smushing a large number of images can take a while depending on your server and network speed.
414
+ <strong>You must keep this page open while the bulk smush is processing</strong>, but you can leave at any time and come back to continue where it left off.", WP_SMUSH_DOMAIN ); ?></p>
415
+
416
+ <?php if ( ! $this->is_premium() ) { ?>
417
+ <p class="error">
418
+ <?php printf( __( "Free accounts are limited to bulk smushing %d attachments per request. You will need to click to start a new bulk job after each %d attachments.", WP_SMUSH_DOMAIN ), $this->max_free_bulk, $this->max_free_bulk ); ?>
419
+ <a href="<?php echo $this->upgrade_url; ?>"><?php _e( 'Remove limits &raquo;', WP_SMUSH_DOMAIN ); ?></a>
420
+ </p>
421
+ <?php } ?>
422
+
423
+
424
+ </div>
425
+
426
+ <!-- Bulk Smushing -->
427
+ <?php wp_nonce_field( 'wp-smush-bulk', '_wpnonce' ); ?>
428
+ <br/><?php
429
+ $this->progress_ui();
430
+ ?>
431
+ <p class="smush-final-log"></p>
432
+ <?php
433
+ $this->setup_button();
434
+ }
435
+
436
+ $auto_smush = get_site_option( WP_SMUSH_PREFIX . 'auto' );
437
+ if ( ! $auto_smush && $this->remaining_count == 0 ) {
438
+ ?>
439
+ <p><?php printf( __( 'When you <a href="%s">upload some images</a> they will be available to smush here.', WP_SMUSH_DOMAIN ), admin_url( 'media-new.php' ) ); ?></p>
440
+ <?php
441
+ } else { ?>
442
+ <p>
443
+ <?php
444
+ // let the user know that there's an alternative
445
+ printf( __( 'You can also smush images individually from your <a href="%s">Media Library</a>.', WP_SMUSH_DOMAIN ), admin_url( 'upload.php' ) );
446
+ ?>
447
+ </p><?php
448
+ }
449
+ ?>
450
+ </div>
451
+ <?php
452
+ }
453
+
454
+ function print_loader() {
455
+ ?>
456
+ <div class="wp-smush-loader-wrap hidden" >
457
+ <div class="floatingCirclesG">
458
+ <div class="f_circleG" id="frotateG_01">
459
+ </div>
460
+ <div class="f_circleG" id="frotateG_02">
461
+ </div>
462
+ <div class="f_circleG" id="frotateG_03">
463
+ </div>
464
+ <div class="f_circleG" id="frotateG_04">
465
+ </div>
466
+ <div class="f_circleG" id="frotateG_05">
467
+ </div>
468
+ <div class="f_circleG" id="frotateG_06">
469
+ </div>
470
+ <div class="f_circleG" id="frotateG_07">
471
+ </div>
472
+ <div class="f_circleG" id="frotateG_08">
473
+ </div>
474
+ </div>
475
+ </div>
476
+ <?php
477
+ }
478
+
479
+ /**
480
+ * Print out the progress bar
481
+ */
482
+ function progress_ui() {
483
+
484
+ // calculate %ages
485
+ if ( $this->total_count > 0 ) //avoid divide by zero error with no attachments
486
+ $smushed_pc = $this->smushed_count / $this->total_count * 100;
487
+ else
488
+ $smushed_pc = 0;
489
+
490
+ $progress_ui = '<div id="progress-ui">';
491
+
492
+ // display the progress bars
493
+ $progress_ui .= '<div id="wp-smush-progress-wrap">
494
+ <div id="wp-smush-fetched-progress" class="wp-smush-progressbar"><div style="width:' . $smushed_pc . '%"></div></div>
495
+ <p id="wp-smush-compression">'
496
+ . __( "Reduced by ", WP_SMUSH_DOMAIN )
497
+ . '<span id="human">' . $this->stats['human'] . '</span> ( <span id="percent">' . number_format_i18n( $this->stats['percent'], 2, '.', '' ) . '</span>% )
498
+ </p>
499
+ </div>';
500
+
501
+ // status divs to show completed count/ total count
502
+ $progress_ui .= '<div id="wp-smush-progress-status">
503
+
504
+ <p id="fetched-status">' .
505
+ sprintf(
506
+ __(
507
+ '<span class="done-count">%d</span> of <span class="total-count">%d</span> total attachments have been smushed', WP_SMUSH_DOMAIN
508
+ ), $this->smushed_count, $this->total_count
509
+ ) .
510
+ '</p>
511
+ </div>
512
+ </div>';
513
+ // print it out
514
+ echo $progress_ui;
515
+ }
516
+
517
+ function aprogress_ui() {
518
+ $bulk = new WpSmushitBulk;
519
+ $total = count( $bulk->get_attachments() );
520
+ $total = $total ? $total : 1; ?>
521
+
522
+ <div id="progress-ui">
523
+ <div id="smush-status" style="margin: 0 0 5px;"><?php printf( __( 'Smushing <span id="smushed-count">1</span> of <span id="smushing-total">%d</span>', WP_SMUSH_DOMAIN ), $total ); ?></div>
524
+ <div id="wp-smushit-progress-wrap">
525
+ <div id="wp-smushit-smush-progress" class="wp-smushit-progressbar">
526
+ <div></div>
527
+ </div>
528
+ </div>
529
+ </div> <?php
530
+ }
531
+
532
+ /**
533
+ * Processes the Smush request and sends back the next id for smushing
534
+ */
535
+ function process_smush_request() {
536
+
537
+ global $WpSmush;
538
+
539
+ $should_continue = true;
540
+ $is_premium = false;
541
+
542
+ if ( empty( $_REQUEST['attachment_id'] ) ) {
543
+ wp_send_json_error( 'missing id' );
544
+ }
545
+
546
+ //if not premium
547
+ $is_premium = $WpSmush->is_premium();
548
+
549
+ if ( ! $is_premium ) {
550
+ //Free version bulk smush, check the transient counter value
551
+ $should_continue = $this->check_bulk_limit();
552
+ }
553
+
554
+ //If the bulk smush needs to be stopped
555
+ if ( ! $should_continue ) {
556
+ wp_send_json_error(
557
+ array(
558
+ 'error' => 'bulk_request_image_limit_exceeded',
559
+ 'continue' => false
560
+ )
561
+ );
562
+ }
563
+
564
+ $attachment_id = $_REQUEST['attachment_id'];
565
+
566
+ $original_meta = wp_get_attachment_metadata( $attachment_id, true );
567
+
568
+ $smush = $WpSmush->resize_from_meta_data( $original_meta, $attachment_id, false );
569
+
570
+ $stats = $this->global_stats();
571
+
572
+ $stats['smushed'] = $this->smushed_count();
573
+ $stats['total'] = $this->total_count;
574
+
575
+ if( is_wp_error( $smush ) ) {
576
+ wp_send_json_error( $stats );
577
+ } else {
578
+ wp_send_json_success( $stats );
579
+ }
580
+ }
581
+
582
+ /**
583
+ * Smush single images
584
+ *
585
+ * @return mixed
586
+ */
587
+ function smush_single() {
588
+ if ( ! current_user_can( 'upload_files' ) ) {
589
+ wp_die( __( "You don't have permission to work with uploaded files.", WP_SMUSH_DOMAIN ) );
590
+ }
591
+
592
+ if ( ! isset( $_GET['attachment_id'] ) ) {
593
+ wp_die( __( 'No attachment ID was provided.', WP_SMUSH_DOMAIN ) );
594
+ }
595
+
596
+ global $WpSmush;
597
+
598
+ $attachment_id = intval( $_GET['attachment_id'] );
599
+
600
+ $original_meta = wp_get_attachment_metadata( $attachment_id );
601
+
602
+ $smush = $WpSmush->resize_from_meta_data( $original_meta, $attachment_id );
603
+
604
+ $status = $WpSmush->set_status( $attachment_id, false, true );
605
+
606
+ /** Send stats **/
607
+ if ( is_wp_error( $smush ) ) {
608
+ /**
609
+ * @param WP_Error $smush
610
+ */
611
+ wp_send_json_error( $smush->get_error_message() );
612
+ } else {
613
+ wp_send_json_success( $status );
614
+ }
615
+
616
+ }
617
+
618
+ /**
619
+ * Check bulk sent count, whether to allow further smushing or not
620
+ *
621
+ * @return bool
622
+ */
623
+ function check_bulk_limit() {
624
+
625
+ $transient_name = WP_SMUSH_PREFIX . 'bulk_sent_count';
626
+ $bulk_sent_count = get_transient( $transient_name );
627
+
628
+ //If bulk sent count is not set
629
+ if ( false === $bulk_sent_count ) {
630
+
631
+ //start transient at 0
632
+ set_transient( $transient_name, 1, 60 );
633
+ return true;
634
+
635
+ } else if ( $bulk_sent_count < $this->max_free_bulk ) {
636
+
637
+ //If lte $this->max_free_bulk images are sent, increment
638
+ set_transient( $transient_name, $bulk_sent_count + 1, 60 );
639
+ return true;
640
+
641
+ } else { //Bulk sent count is set and greater than $this->max_free_bulk
642
+
643
+ //clear it and return false to stop the process
644
+ set_transient( $transient_name, 0, 60 );
645
+ return false;
646
+
647
+ }
648
+ }
649
+
650
+ /**
651
+ * The UI for bulk smushing
652
+ *
653
+ * @return null
654
+ */
655
+ function all_ui( $send_ids ) {
656
+
657
+ // if there are no images in the media library
658
+ if ( $this->total_count < 1 ) {
659
+ printf(
660
+ __(
661
+ '<p>Please <a href="%s">upload some images</a>.</p>', WP_SMUSH_DOMAIN
662
+ ), admin_url( 'media-new.php' )
663
+ );
664
+
665
+ // no need to print out the rest of the UI
666
+ return;
667
+ }
668
+
669
+ // otherwise, start displaying the UI
670
+ ?>
671
+ <div id="all-bulk" class="wp-smush-bulk-wrap">
672
+ <?php
673
+ // everything has been smushed, display a notice
674
+ if ( $this->smushed_count === $this->total_count ) {
675
+ ?>
676
+ <p>
677
+ <?php
678
+ _e( 'All your images are already smushed!', WP_SMUSH_DOMAIN );
679
+ ?>
680
+ </p>
681
+ <?php
682
+ } else {
683
+ $this->selected_ui( $send_ids, '' );
684
+ // we have some smushing to do! :)
685
+ // first some warnings
686
+ ?>
687
+ <p>
688
+ <?php
689
+ // let the user know that there's an alternative
690
+ printf( __( 'You can also smush images individually from your <a href="%s">Media Library</a>.', WP_SMUSH_DOMAIN ), admin_url( 'upload.php' ) );
691
+ ?>
692
+ </p>
693
+ <?php
694
+ }
695
+
696
+ // display the progress bar
697
+ $this->progress_ui();
698
+
699
+ // display the appropriate button
700
+ $this->setup_button();
701
+
702
+ ?>
703
+ </div>
704
+ <?php
705
+ }
706
+
707
+ /**
708
+ * Total Image count
709
+ * @return int
710
+ */
711
+ function total_count() {
712
+ $query = array(
713
+ 'fields' => 'ids',
714
+ 'post_type' => 'attachment',
715
+ 'post_status' => 'any',
716
+ 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
717
+ 'order' => 'ASC',
718
+ 'posts_per_page' => - 1
719
+ );
720
+ $results = new WP_Query( $query );
721
+ $count = ! empty( $results->post_count ) ? $results->post_count : 0;
722
+
723
+ // send the count
724
+ return $count;
725
+ }
726
+
727
+ /**
728
+ * Optimised images count
729
+ *
730
+ * @param bool $return_ids
731
+ *
732
+ * @return array|int
733
+ */
734
+ function smushed_count( $return_ids = false ) {
735
+ $query = array(
736
+ 'fields' => 'ids',
737
+ 'post_type' => 'attachment',
738
+ 'post_status' => 'any',
739
+ 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
740
+ 'order' => 'ASC',
741
+ 'posts_per_page' => - 1,
742
+ 'meta_key' => 'wp-smpro-smush-data'
743
+ );
744
+
745
+ $results = new WP_Query( $query );
746
+ if ( ! $return_ids ) {
747
+ $count = ! empty( $results->post_count ) ? $results->post_count : 0;
748
+ } else {
749
+ return $results->posts;
750
+ }
751
+
752
+ // send the count
753
+ return $count;
754
+ }
755
+
756
+ /**
757
+ * Returns remaining count
758
+ *
759
+ * @return int
760
+ */
761
+ function remaining_count(){
762
+ return $this->total_count - $this->smushed_count;
763
+ }
764
+
765
+ /**
766
+ * Display Thumbnails, if bulk action is choosen
767
+ */
768
+ function selected_ui( $send_ids, $received_ids ) {
769
+ if ( empty( $received_ids ) ) {
770
+ return;
771
+ }
772
+
773
+ ?>
774
+ <div id="select-bulk" class="wp-smush-bulk-wrap">
775
+ <p>
776
+ <?php
777
+ printf(
778
+ __(
779
+ '<strong>%d of %d images</strong> were sent for smushing:',
780
+ WP_SMUSH_DOMAIN
781
+ ),
782
+ count( $send_ids ), count( $received_ids )
783
+ );
784
+ ?>
785
+ </p>
786
+ <ul id="wp-smush-selected-images">
787
+ <?php
788
+ foreach ( $received_ids as $attachment_id ) {
789
+ $this->attachment_ui( $attachment_id );
790
+ }
791
+ ?>
792
+ </ul>
793
+ </div>
794
+ <?php
795
+ }
796
+
797
+ /**
798
+ * Display the bulk smushing button
799
+ *
800
+ * @todo Add the API status here, next to the button
801
+ */
802
+ function setup_button() {
803
+ $button = $this->button_state();
804
+ $disabled = !empty($button['disabled']) ? ' disabled="disabled"' : '';
805
+ ?>
806
+ <button class="button button-primary<?php echo ' ' . $button['class']; ?>" name="smush-all" <?php echo $disabled; ?>>
807
+ <span><?php echo $button['text'] ?></span>
808
+ </button>
809
+ <?php
810
+ }
811
+
812
+ function global_stats() {
813
+
814
+ global $wpdb, $WpSmush;
815
+
816
+ $sql = "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key=%s";
817
+
818
+ $global_data = $wpdb->get_col( $wpdb->prepare( $sql, "wp-smpro-smush-data" ) );
819
+
820
+ $smush_data = array(
821
+ 'size_before' => 0,
822
+ 'size_after' => 0,
823
+ 'percent' => 0,
824
+ 'human' => 0
825
+ );
826
+
827
+ if ( ! empty( $global_data ) ) {
828
+ foreach ( $global_data as $data ) {
829
+ $data = maybe_unserialize( $data );
830
+ if ( ! empty( $data['stats'] ) ) {
831
+ $smush_data['size_before'] += ! empty( $data['stats']['size_before'] ) ? (int) $data['stats']['size_before'] : 0;
832
+ $smush_data['size_after'] += ! empty( $data['stats']['size_after'] ) ? (int) $data['stats']['size_after'] : 0;
833
+ }
834
+ }
835
+ }
836
+
837
+ $smush_data['bytes'] = $smush_data['size_before'] - $smush_data['size_after'];
838
+
839
+ if ( $smush_data['bytes'] < 0 ) {
840
+ $smush_data['bytes'] = 0;
841
+ }
842
+
843
+ if ( $smush_data['size_before'] > 0 ) {
844
+ $smush_data['percent'] = ( $smush_data['bytes'] / $smush_data['size_before'] ) * 100;
845
+ }
846
+
847
+ //Round off precentage
848
+ $smush_data['percent'] = round( $smush_data['percent'], 2 );
849
+
850
+ $smush_data['human'] = $WpSmush->format_bytes( $smush_data['bytes'] );
851
+
852
+ return $smush_data;
853
+ }
854
+
855
+ /**
856
+ * Returns Bulk smush button id and other details, as per if bulk request is already sent or not
857
+ *
858
+ * @return array
859
+ */
860
+
861
+ private function button_state() {
862
+ $button = array(
863
+ 'cancel' => false,
864
+ );
865
+
866
+
867
+ // if we have nothing left to smush
868
+ // disable the buttons
869
+ if ( $this->smushed_count === $this->total_count ) {
870
+ $button['text'] = __( 'All Done!', WP_SMUSH_DOMAIN );
871
+ $button['class'] = 'wp-smush-finished disabled wp-smush-finished';
872
+ $button['disabled'] = 'disabled';
873
+
874
+ } else if ( $this->is_premium() || $this->remaining_count <= $this->max_free_bulk ) { //if premium or under limit
875
+
876
+ $button['text'] = __( 'Bulk Smush Now', WP_SMUSH_DOMAIN );
877
+ $button['class'] = 'wp-smush-button wp-smush-send';
878
+
879
+ } else { //if not premium and over limit
880
+ $button['text'] = sprintf( __( 'Bulk Smush %d Attachments', WP_SMUSH_DOMAIN ), $this->max_free_bulk );
881
+ $button['class'] = 'wp-smush-button wp-smush-send';
882
+
883
+ }
884
+
885
+ return $button;
886
+ }
887
+
888
+ /**
889
+ * Render a checkbox
890
+ *
891
+ * @param string $key The setting's name
892
+ *
893
+ * @return string checkbox html
894
+ */
895
+ function render_checked( $key, $text ) {
896
+ // the key for options table
897
+ $opt_name = WP_SMUSH_PREFIX . $key;
898
+
899
+ // default value
900
+ $opt_val = get_option( $opt_name, false );
901
+
902
+ //If value is not set for auto smushing set it to 1
903
+ if ( $key == 'auto' && $opt_val === false ) {
904
+ $opt_val = 1;
905
+ }
906
+
907
+ //disable lossy for non-premium members
908
+ $disabled = '';
909
+ if ( ( 'lossy' == $key || 'backup' == $key ) && ! $this->is_premium() ) {
910
+ $disabled = ' disabled';
911
+ $opt_val = 0;
912
+ }
913
+
914
+ // return html
915
+ return sprintf(
916
+ "<li><label><input type='checkbox' name='%1\$s' id='%1\$s' value='1' %2\$s %3\$s>%4\$s</label></li>", esc_attr( $opt_name ), checked( $opt_val, 1, false ), $disabled, $text
917
+ );
918
+ }
919
+
920
+ function get_smushed_image_ids() {
921
+ $args = array(
922
+ 'fields' => 'ids',
923
+ 'post_type' => 'attachment',
924
+ 'post_status' => 'any',
925
+ 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
926
+ 'order' => 'ASC',
927
+ 'posts_per_page' => - 1,
928
+ 'meta_query' => array(
929
+ array(
930
+ 'key' => 'wp-is-smushed',
931
+ 'value' => '1',
932
+ )
933
+ ),
934
+ );
935
+ $query = new WP_Query( $args );
936
+
937
+ return $query->posts;
938
+ }
939
+
940
+ /**
941
+ * Get the smush button text for attachment
942
+ */
943
+ function smush_status( $id ) {
944
+ $response = trim( $this->set_status( $id, false ) );
945
+
946
+ return $response;
947
+ }
948
+
949
+ /**
950
+ * Returns the image smush status, called by grid view ajax
951
+ */
952
+ function attachment_status() {
953
+ $id = $_REQUEST['id'];
954
+ $status_text = $this->smush_status( $id );
955
+ wp_send_json_success( $status_text );
956
+ die();
957
+ }
958
+
959
+ /**
960
+ * Adds a smushit pro settings link on plugin page
961
+ *
962
+ * @param $links
963
+ *
964
+ * @return array
965
+ */
966
+ function settings_link( $links ) {
967
+
968
+ $settings_page = admin_url( 'upload.php?page=wp-smush-bulk' );
969
+ $settings = '<a href="' . $settings_page . '">' . __( 'Settings', WP_SMUSH_DOMAIN ) . '</a>';
970
+
971
+ array_unshift( $links, $settings );
972
+
973
+ return $links;
974
+ }
975
+ }
976
+
977
+ $wpsmushit_admin = new WpSmushitAdmin();
978
+ }
lib/class-wp-smush-bulk.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package WP SmushIt
5
+ * @subpackage Admin
6
+ * @version 1.0
7
+ *
8
+ * @author Saurabh Shukla <saurabh@incsub.com>
9
+ * @author Umesh Kumar <umesh@incsub.com>
10
+ *
11
+ * @copyright (c) 2014, Incsub (http://incsub.com)
12
+ */
13
+ if ( ! class_exists( 'WpSmushitBulk' ) ) {
14
+
15
+ /**
16
+ * Methods for bulk processing
17
+ */
18
+ class WpSmushitBulk {
19
+
20
+ /**
21
+ * Fetch all the unsmushed attachments
22
+ * @return array $attachments
23
+ */
24
+ function get_attachments() {
25
+ if ( ! isset( $_REQUEST['ids'] ) ) {
26
+ $args = array(
27
+ 'fields' => 'ids',
28
+ 'post_type' => 'attachment',
29
+ 'post_status' => 'any',
30
+ 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
31
+ 'order' => 'ASC',
32
+ 'posts_per_page' => - 1,
33
+ 'meta_query' => array(
34
+ 'relation' => 'AND',
35
+ array(
36
+ 'key' => 'wp-smpro-smush-data',
37
+ 'compare' => 'NOT EXISTS'
38
+ ),
39
+ array(
40
+ 'key' => 'wp-smush-data',
41
+ 'compare' => 'NOT EXISTS'
42
+ )
43
+ ),
44
+ );
45
+ $query = new WP_Query( $args );
46
+ $unsmushed_posts = $query->posts;
47
+ } else {
48
+ return explode( ',', $_REQUEST['ids'] );
49
+ }
50
+
51
+ return $unsmushed_posts;
52
+ }
53
+
54
+ }
55
+ }
lib/class-wp-smush-migrate.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package WP Smush
5
+ * @subpackage Migrate
6
+ * @version 1.0
7
+ *
8
+ * @author Umesh Kumar <umesh@incsub.com>
9
+ * @author Sam Najian <sam@incsub.com>
10
+ *
11
+ * @copyright (c) 2015, Incsub (http://incsub.com)
12
+ */
13
+
14
+ class WpSmushMigrate {
15
+
16
+ /**
17
+ * Returns percent saved from the api call response
18
+ *
19
+ * @param string $string
20
+ *
21
+ * @return float
22
+ */
23
+ private function _get_saved_percentage( $string ) {
24
+ if ( preg_match( '/\d+(\.\d+)?%/', $string, $matches ) )
25
+ return isset( $matches[0] ) ? (float) str_replace("%", "", $matches[0]) : -1;
26
+
27
+ return -1;
28
+ }
29
+
30
+ /**
31
+ * Returns bytes saved from the api call response
32
+ *
33
+ * @param string $string
34
+ *
35
+ * @return float
36
+ */
37
+ private function _get_saved_bytes( $string ) {
38
+ if ( preg_match( '/\((.*)\)/', $string, $matches ) ) {
39
+ $size = isset( $matches[1] ) ? $matches[1] : false;
40
+ if($size){
41
+ $size_array = explode("&nbsp;", $size);
42
+
43
+ if( !isset( $size_array[0] ) || !isset( $size_array[1] ) ) return -1;
44
+
45
+ $unit = strtoupper( $size_array[1] );
46
+ $sizes = array("B" => "1", "KB" => 1024, "MB" => 1048576);
47
+ return (float) $size_array[0] * $sizes[$unit];
48
+ }
49
+ }
50
+ return -1;
51
+ }
52
+
53
+
54
+ /**
55
+ * Migrates smushit message structure
56
+ *
57
+ * @param array $message
58
+ *
59
+ * @return array
60
+ */
61
+ public function migrate_api_message( array $message ){
62
+ if( !isset( $message["wp_smushit"] ) ) return array();
63
+
64
+ $new_message = array(
65
+ "stats" => array(
66
+ 'size_before' => -1,
67
+ 'size_after' => -1,
68
+ 'percent' => -1,
69
+ 'time' => -1,
70
+ 'api_version' => -1,
71
+ 'lossy' => -1
72
+ ),
73
+ 'sizes' => array()
74
+ );
75
+
76
+
77
+ if( isset( $message['sizes'] ) ){
78
+ foreach( $message['sizes'] as $key => $size ){
79
+ if( isset( $size['wp_smushit'] ) ){
80
+ $new_size = new stdClass();
81
+
82
+ $new_size->compression = $this->_get_saved_percentage( $size['wp_smushit'] );
83
+ $new_size->bytes_saved = $this->_get_saved_bytes( $size['wp_smushit'] );
84
+ $new_size->before_size = -1;
85
+ $new_size->after_size = -1;
86
+ $new_size->time = -1;
87
+
88
+ if( $new_size->compression !== -1 && $new_size->bytes_saved !== -1){
89
+ $new_size->before_size = ( $new_size->bytes_saved * 100 ) / $new_size->compression;
90
+ $new_size->after_size = ( 100 - $new_size->compression ) * $new_size->before_size / 100;
91
+ }
92
+
93
+ $new_message['sizes'][$key] = $new_size;
94
+ }
95
+ }
96
+ }
97
+
98
+ $new_message["stats"]['percent'] = $this->_get_saved_percentage( $message['wp_smushit'] );
99
+ $new_message["stats"]['bytes'] = $this->_get_saved_bytes( $message['wp_smushit'] );
100
+
101
+ if( $new_message["stats"]['percent'] !== -1 && $new_message["stats"]['bytes'] !== -1){
102
+ $new_message["stats"]['size_before'] = ( $new_message["stats"]['bytes'] * 100 ) / $new_message["stats"]['percent'];
103
+ $new_message["stats"]['size_after'] = ( 100 - $new_message["stats"]['percent'] ) * $new_message["stats"]['size_before'] / 100;
104
+ }
105
+
106
+ return $new_message;
107
+ }
108
+ }
lib/class-wp-smushit-admin.php DELETED
@@ -1,455 +0,0 @@
1
- <?php
2
- /**
3
- * @package WP SmushIt
4
- * @subpackage Admin
5
- * @version 1.0
6
- *
7
- * @author Saurabh Shukla <saurabh@incsub.com>
8
- * @author Umesh Kumar <umesh@incsub.com>
9
- *
10
- * @copyright (c) 2014, Incsub (http://incsub.com)
11
- */
12
- if ( ! class_exists( 'WpSmushitAdmin' ) ) {
13
- /**
14
- * Show settings in Media settings and add column to media library
15
- *
16
- */
17
- class WpSmushitAdmin {
18
-
19
- /**
20
- *
21
- * @var array Settings
22
- */
23
- public $settings;
24
-
25
- public $bulk;
26
-
27
- /**
28
- * Constructor
29
- */
30
- public function __construct() {
31
-
32
- // hook scripts and styles
33
- add_action( 'admin_init', array( $this, 'register' ) );
34
-
35
- // hook custom screen
36
- add_action( 'admin_menu', array( $this, 'screen' ) );
37
-
38
- add_action( 'admin_footer-upload.php', array( $this, 'print_loader' ) );
39
-
40
- //Handle Smush Ajax
41
- add_action( 'wp_ajax_wp_smushit_bulk', array( $this, 'process_smush_request' ) );
42
-
43
-
44
- add_action( 'admin_notices', array( $this, 'depreciated_warning' ) );
45
- }
46
-
47
- /**
48
- * Add Bulk option settings page
49
- */
50
- function screen() {
51
- $admin_page_suffix = add_media_page( 'Bulk WP Smush.it', 'WP Smush.it', 'edit_others_posts', 'wp-smushit-bulk', array(
52
- $this,
53
- 'ui'
54
- ) );
55
- //Register Debug page only if WP_SMPRO_DEBUG is defined and true
56
- if ( defined( 'WP_SMUSHIT_DEBUG' ) && WP_SMUSHIT_DEBUG ) {
57
- add_media_page( 'WP Smush.it Error Log', 'Error Log', 'edit_others_posts', 'wp-smushit-errorlog', array(
58
- $this,
59
- 'create_admin_error_log_page'
60
- ) );
61
- }
62
- // enqueue js only on this screen
63
- add_action( 'admin_print_scripts-' . $admin_page_suffix, array( $this, 'enqueue' ) );
64
- }
65
-
66
- /**
67
- * Register js and css
68
- */
69
- function register() {
70
- global $WpSmushit;
71
- /* Register our script. */
72
- wp_register_script( 'wp-smushit-admin-js', WP_SMUSHIT_URL . 'assets/js/wp-smushit-admin.js', array( 'jquery' ), $WpSmushit->version );
73
-
74
- /* Register Style. */
75
- wp_register_style( 'wp-smushit-admin-css', WP_SMUSHIT_URL . 'assets/css/wp-smushit-admin.css', array(), $WpSmushit->version );
76
-
77
- // localize translatable strings for js
78
- $this->localize();
79
- }
80
-
81
- /**
82
- * enqueue js and css
83
- */
84
- function enqueue() {
85
- wp_enqueue_script( 'wp-smushit-admin-js' );
86
- wp_enqueue_style( 'wp-smushit-admin-css' );
87
- }
88
-
89
- function localize() {
90
- $bulk = new WpSmushitBulk();
91
- $handle = 'wp-smushit-admin-js';
92
-
93
- $wp_smushit_msgs = array(
94
- 'progress' => __( 'Smushing in Progress', WP_SMUSHIT_DOMAIN ),
95
- 'done' => __( 'All done!', WP_SMUSHIT_DOMAIN )
96
- );
97
-
98
- wp_localize_script( $handle, 'wp_smushit_msgs', $wp_smushit_msgs );
99
-
100
- //Localize smushit_ids variable, if there are fix number of ids
101
- $ids = ! empty( $_REQUEST['ids'] ) ? explode( ',', $_REQUEST['ids'] ) : $bulk->get_attachments();
102
- wp_localize_script( 'wp-smushit-admin-js', 'wp_smushit_ids', $ids );
103
-
104
- }
105
-
106
- /**
107
- * Display the ui
108
- */
109
- function ui() {
110
- ?>
111
- <div class="wrap">
112
- <div id="icon-upload" class="icon32"><br/></div>
113
-
114
- <h2>
115
- <?php _e( 'WP Smush.it', WP_SMUSHIT_DOMAIN ) ?>
116
- </h2>
117
-
118
- <h3><span class="dashicons dashicons-megaphone" style="color:red"></span> Urgent Smush.it Notice</h3>
119
- <div class="error">
120
- <p>Yahoo appears to be either discontinuing or not supporting their free Smush.it service - bah!</p>
121
- <p>So, WPMU DEV is looking into how we can provide a free service to you that replaces this... but it's going to take some time.</p>
122
- <p>So, in the interim, we're providing a (very temporary) <strong>90% discount on any new WPMU DEV membership</strong> to WP Smush.It users so you can use our dedicated <a href="https://premium.wpmudev.org/project/wp-smush-pro/">Smush Pro</a> servers - <a href="https://premium.wpmudev.org/?coupon=SMUSHEMERGENCY#pricing">click here to take that up</a> (and please don't share it around).</p>
123
- <p>We will update the plugin as soon as we have it in place. Thanks, WPMU DEV</p>
124
- </div>
125
-
126
- <div class="wp-smpushit-container">
127
- <h3>
128
- <?php _e( 'Settings', WP_SMUSHIT_DOMAIN ) ?>
129
- </h3>
130
- <?php
131
- // display the options
132
- $this->options_ui();
133
-
134
- //Bulk Smushing
135
- $this->bulk_preview();
136
- ?>
137
- </div>
138
- </div>
139
- <?php
140
- }
141
-
142
- /**
143
- * Process and display the options form
144
- */
145
- function options_ui() {
146
-
147
- // Save settings, if needed
148
- $this->process_options();
149
-
150
- ?>
151
- <form action="" method="post"><?php
152
-
153
- //Auto Smushing
154
- $auto = 'wp_smushit_smushit_auto';
155
- $auto_val = intval( get_option( $auto, WP_SMUSHIT_AUTO_OK ) );
156
- $disabled = sprintf( __( 'Temporarily disabled until %s', WP_SMUSHIT_DOMAIN ), date( 'M j, Y \a\t H:i', $auto_val ) );
157
-
158
- //Timeout
159
- $timeout = 'wp_smushit_smushit_timeout';
160
- $timeout_val = intval( get_option( $timeout, WP_SMUSHIT_AUTO_OK ) );
161
-
162
- //Enforce Same URL
163
- $enforce_same_url = 'wp_smushit_smushit_enforce_same_url';
164
- $enforce_same_url_val = get_option( $enforce_same_url, WP_SMUSHIT_ENFORCE_SAME_URL );
165
-
166
- //Debug
167
- $smushit_debug = 'wp_smushit_smushit_debug';
168
- $smushit_debug_val = get_option( $smushit_debug, WP_SMUSHIT_DEBUG );
169
- ?>
170
- <table class="form-table">
171
- <tbody>
172
- <tr>
173
- <th><label><?php echo __( 'Smush images on upload', WP_SMUSHIT_DOMAIN ); ?></label></th>
174
- <td>
175
- <select name='<?php echo $auto; ?>' id='<?php echo $auto; ?>'>
176
- <option value='<?php echo WP_SMUSHIT_AUTO_OK; ?>' <?php selected( WP_SMUSHIT_AUTO_OK, $auto_val ); ?>><?php echo __( 'Automatically process on upload', WP_SMUSHIT_DOMAIN ); ?></option>
177
- <option value='<?php echo WP_SMUSHIT_AUTO_NEVER; ?>' <?php selected( WP_SMUSHIT_AUTO_NEVER, $auto_val ); ?>><?php echo __( 'Do not process on upload', WP_SMUSHIT_DOMAIN ); ?></option> <?php
178
-
179
- if ( $auto_val > 0 ) {
180
- ?>
181
- <option value="<?php echo $auto_val; ?>" selected="selected"><?php echo $disabled; ?></option><?php
182
- } ?>
183
- </select>
184
- </td>
185
- </tr>
186
- <tr>
187
- <th><?php _e( 'API Timeout', WP_SMUSHIT_DOMAIN ); ?></th>
188
- <td>
189
- <input type='text' name='<?php echo esc_attr( $timeout ); ?>' id='<?php echo esc_attr( $timeout ); ?>' value='<?php echo intval( get_option( $timeout, 60 ) ); ?>' size="2">
190
- </td>
191
- </tr>
192
- <tr>
193
- <th><?php _e( 'Enforce home URL', WP_SMUSHIT_DOMAIN ); ?></th>
194
- <td>
195
- <input type="checkbox" name="<?php echo $enforce_same_url ?>" <?php echo checked( $enforce_same_url_val, 'on' ); ?>/> <?php
196
- echo '<strong>' . get_option( 'home' ) . '</strong><br />' . __( 'By default the plugin will enforce that the image URL is the same domain as the home. If you are using a sub-domain pointed to this same host or an external Content Delivery Network (CDN) you want to unset this option.', WP_SMUSHIT_DOMAIN ); ?>
197
- </td>
198
- </tr>
199
- <tr>
200
- <th><?php _e( 'Smushit Debug', WP_SMUSHIT_DOMAIN ); ?></th>
201
- <td>
202
- <input type="checkbox" name="<?php echo $smushit_debug ?>" <?php echo checked( $smushit_debug_val, 'on' ); ?>/>
203
- <?php _e( 'If you are having trouble with the plugin enable this option can reveal some information about your system needed for support.', WP_SMUSHIT_DOMAIN ); ?>
204
- </td>
205
- </tr>
206
- </tbody>
207
- </table><?php
208
- // nonce
209
- wp_nonce_field( 'save_wp_smushit_options', 'wp_smushit_options_nonce' );
210
- ?>
211
- <input type="submit" id="wp-smushit-save-settings" class="button button-primary" value="<?php _e( 'Save Changes', WP_SMUSHIT_DOMAIN ); ?>">
212
- </form>
213
- <?php
214
- }
215
-
216
- /**
217
- * Check if form is submitted and process it
218
- *
219
- * @return null
220
- */
221
- function process_options() {
222
- // we aren't saving options
223
- if ( ! isset( $_POST['wp_smushit_options_nonce'] ) ) {
224
- return;
225
- }
226
- echo "here";
227
- // the nonce doesn't pan out
228
- if ( ! wp_verify_nonce( $_POST['wp_smushit_options_nonce'], 'save_wp_smushit_options' ) ) {
229
- return;
230
- }
231
- echo "there";
232
-
233
- //Array of options
234
- $smushit_settings = array(
235
- 'wp_smushit_smushit_auto',
236
- 'wp_smushit_smushit_timeout',
237
- 'wp_smushit_smushit_enforce_same_url',
238
- 'wp_smushit_smushit_debug'
239
- );
240
- //Save All the options
241
- foreach ( $smushit_settings as $setting ) {
242
- if ( empty( $_POST[ $setting ] ) ) {
243
- update_option( $setting, '' );
244
- continue;
245
- }
246
- update_option( $setting, $_POST[ $setting ] );
247
- }
248
-
249
- }
250
-
251
- /**
252
- * Bulk Smushing UI
253
- */
254
- function bulk_preview() {
255
-
256
- $bulk = new WpSmushitBulk();
257
- if ( function_exists( 'apache_setenv' ) ) {
258
- @apache_setenv( 'no-gzip', 1 );
259
- }
260
- @ini_set( 'output_buffering', 'on' );
261
- @ini_set( 'zlib.output_compression', 0 );
262
- @ini_set( 'implicit_flush', 1 );
263
-
264
- $attachments = null;
265
- $auto_start = false;
266
-
267
- $attachments = $bulk->get_attachments();
268
- $count = 0;
269
- //Check images bigger than 1Mb, used to display the count of images that can't be smushed
270
- foreach ( $attachments as $attachment ) {
271
- if ( file_exists( get_attached_file( $attachment ) ) ) {
272
- $size = filesize( get_attached_file( $attachment ) );
273
- }
274
- if ( empty( $size ) || ! ( ( $size / 1048576 ) > 1 ) ) {
275
- continue;
276
- }
277
- $count ++;
278
- }
279
- $exceed_mb = '';
280
- $text = $count > 1 ? 'are' : 'is';
281
- if ( $count ) {
282
- $exceed_mb = sprintf( __( " %d of those images %s <b>over 1Mb</b> and <b>can not be compressed using the free version of the plugin.</b>", WP_SMUSHIT_DOMAIN ), $count, $text );
283
- }
284
- $media_lib = get_admin_url( '', 'upload.php' );
285
- ?>
286
- <div class="wrap">
287
- <div id="icon-upload" class="icon32"><br/></div>
288
- <h3><?php _e( 'Smush in Bulk', WP_SMUSHIT_DOMAIN ) ?></h3>
289
- <?php
290
-
291
- if ( sizeof( $attachments ) < 1 ) {
292
- _e( "<p>You don't appear to have uploaded any images yet.</p>", WP_SMUSHIT_DOMAIN );
293
- } else {
294
- if ( ! isset( $_POST['smush-all'] ) && ! $auto_start ) { // instructions page
295
- $upgrade_link = "<a href='http://premium.wpmudev.org/project/wp-smush-pro'>" . __( "Upgrade to WP Smush PRO", WP_SMUSHIT_DOMAIN ) . "</a>";
296
- _e( "<h4>WP Smush.it uses Yahoo! Smush.it API. As such, there are a few restrictions:</h4>", WP_SMUSHIT_DOMAIN );
297
- ?>
298
- <ol>
299
- <li><?php printf( __( "Each image MUST be less than 1Mb in size. %s and use our servers for images upto 5Mb.", WP_SMUSHIT_DOMAIN ), $upgrade_link ); ?></li>
300
- <li><?php printf( __( "Images MUST be accessible via a non-https URL. The Yahoo! Smush.it service will not handle https:// image URLs. %s to allow https URLs", WP_SMUSHIT_DOMAIN ), $upgrade_link ); ?></li>
301
- <li><?php printf( __( "Smushing images in bulk can sometimes cause time-outs. %s and use our reliable server to prevent time-outs.", WP_SMUSHIT_DOMAIN ), $upgrade_link ); ?></li>
302
- </ol>
303
- <div class="smushit-pro-update-link" style="background: white; float: left; font-size: 18px; line-height: 1.4; margin: 0 0 10px; padding: 13px;">
304
- <?php _e( "<strong>WP Smush PRO</strong> allows you to smush images up to 5Mb.<br /> Fast, reliable & time-out free. <a href='http://premium.wpmudev.org/projects/wp-smush-pro'>Find Out more &raquo;</a>", WP_SMUSHIT_DOMAIN ); ?>
305
- </div>
306
-
307
- <hr style="clear: left;"/>
308
-
309
- <style type="text/css">
310
- .smush-instructions p {
311
- line-height: 1.2;
312
- margin: 0 0 4px;
313
- }
314
- </style>
315
- <div class="smush-instructions" style="line-height: 1;">
316
- <?php printf( __( "<p>We found %d images in your media library. %s </p>", WP_SMUSHIT_DOMAIN ), sizeof( $attachments ), $exceed_mb ); ?>
317
-
318
- <?php _e( "<p><b style='color: red;'>Please beware</b>, <b>smushing a large number of images can take a long time.</b></p>", WP_SMUSHIT_DOMAIN ); ?>
319
-
320
- <?php _e( "<p><b>You can not leave this page, until all images have been received back, and you see a success message.</b></p>", WP_SMUSHIT_DOMAIN ); ?>
321
- <br/>
322
- <?php printf( __( "Click below to smush all your images. Alternatively, you can smush your images individually or as a bulk action from your <a href='%s'>Media Library</a>", WP_SMUSHIT_DOMAIN ), $media_lib ); ?>
323
- </div>
324
-
325
- <!-- Bulk Smushing-->
326
- <?php wp_nonce_field( 'wp-smushit-bulk', '_wpnonce' ); ?>
327
- <br/>
328
- <?php $this->progress_ui(); ?>
329
- <button type="submit" class="button-primary action" name="smush-all"><?php _e( 'Bulk Smush all my images', WP_SMUSHIT_DOMAIN ) ?></button>
330
- <?php _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 ); ?>
331
- <?php
332
- if ( WP_SMUSHIT_DEBUG ) {
333
- _e( "<p>DEBUG mode is currently enabled. To disable uncheck the smushit debug option.</p>", WP_SMUSHIT_DOMAIN );
334
- }
335
- }
336
- }
337
- ?>
338
- </div>
339
- <?php
340
- }
341
-
342
- function print_loader() {
343
- ?>
344
- <div id="wp-smushit-loader-wrap">
345
- <div class="floatingCirclesG">
346
- <div class="f_circleG" id="frotateG_01">
347
- </div>
348
- <div class="f_circleG" id="frotateG_02">
349
- </div>
350
- <div class="f_circleG" id="frotateG_03">
351
- </div>
352
- <div class="f_circleG" id="frotateG_04">
353
- </div>
354
- <div class="f_circleG" id="frotateG_05">
355
- </div>
356
- <div class="f_circleG" id="frotateG_06">
357
- </div>
358
- <div class="f_circleG" id="frotateG_07">
359
- </div>
360
- <div class="f_circleG" id="frotateG_08">
361
- </div>
362
- </div>
363
- </div>
364
- <?php
365
- }
366
-
367
- function progress_ui() {
368
- $bulk = new WpSmushitBulk;
369
- $total = count( $bulk->get_attachments() );
370
- $total = $total ? $total : 1; ?>
371
-
372
- <div id="progress-ui">
373
- <div id="smush-status" style="margin: 0 0 5px;"><?php printf( __( 'Smushing <span id="smushed-count">1</span> of <span id="smushing-total">%d</span>', WP_SMUSHIT_DOMAIN ), $total ); ?></div>
374
- <div id="wp-smushit-progress-wrap">
375
- <div id="wp-smushit-smush-progress" class="wp-smushit-progressbar">
376
- <div></div>
377
- </div>
378
- </div>
379
- </div> <?php
380
- }
381
-
382
- /**
383
- * Processes the Smush request and sends back the next id for smushing
384
- */
385
- function process_smush_request() {
386
-
387
- global $WpSmushit;
388
-
389
- if ( empty( $_REQUEST['attachment_id'] ) ) {
390
- wp_send_json_error( 'missing id' );
391
- }
392
-
393
- $attachment_id = $_REQUEST['attachment_id'];
394
-
395
- $original_meta = wp_get_attachment_metadata( $attachment_id, true );
396
-
397
- $meta = $WpSmushit->resize_from_meta_data( $original_meta, $attachment_id, false );
398
-
399
- wp_update_attachment_metadata( $attachment_id, $meta );
400
-
401
- wp_send_json_success( 'processed' );
402
- }
403
-
404
- /**
405
- * Creates Admin Error Log info page.
406
- *
407
- * @access private.
408
- */
409
- function create_admin_error_log_page() {
410
- global $log;
411
- if ( ! empty( $_GET['action'] ) && 'purge' == @$_GET['action'] ) {
412
- //Check Nonce
413
- if ( empty( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'purge_log' ) ) {
414
- echo '<div class="error"><p>' . __( 'Nonce verification failed', WP_SMUSHIT_DOMAIN ) . '</p></div>';
415
- } else {
416
- $log->purge_errors();
417
- $log->purge_notices();
418
- }
419
- }
420
- $errors = $log->get_all_errors();
421
- $notices = $log->get_all_notices();
422
- /**
423
- * Error Log Form
424
- */
425
- require_once( WP_SMUSHIT_DIR . '/lib/error_log.php' );
426
- }
427
-
428
- function depreciated_warning() {
429
- if ( ! current_user_can('edit_others_posts') ) return;
430
-
431
- if ( isset( $_GET['page']) && 'wp-smushit-bulk' == $_GET['page'] ) {
432
- return;
433
- }
434
-
435
- if ( isset( $_GET['dismiss_smush_warning'] ) ) {
436
- update_option('dismiss_smush_warning', 1);
437
- }
438
-
439
- if ( get_option('dismiss_smush_warning') ) return;
440
- ?>
441
- <div class="error">
442
- <a href="<?php echo admin_url('index.php'); ?>?dismiss_smush_warning=1" style="float:right;margin-top: 10px;text-decoration: none;"><span class="dashicons dashicons-dismiss" style="color:gray;"></span>Dismiss</a>
443
- <h3><span class="dashicons dashicons-megaphone" style="color:red"></span> Urgent Smush.it Notice</h3>
444
- <p>Yahoo appears to be either discontinuing or not supporting their free Smush.it service - bah!</p>
445
- <p>So, WPMU DEV is looking into how we can provide a free service to you that replaces this... but it's going to take some time.</p>
446
- <p>So, in the interim, we're providing a (very temporary) <strong>90% discount on any new WPMU DEV membership</strong> to WP Smush.It users so you can use our dedicated <a href="https://premium.wpmudev.org/project/wp-smush-pro/">Smush Pro</a> servers - <a href="https://premium.wpmudev.org/?coupon=SMUSHEMERGENCY#pricing">click here to take that up</a> (and please don't share it around).</p>
447
- <p>We will update the plugin as soon as we have it in place. Thanks, WPMU DEV</p>
448
- </div>
449
- <?php
450
- }
451
- }
452
-
453
- //Add js variables for smushing
454
- $wpsmushit_admin = new WpSmushitAdmin();
455
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/class-wp-smushit-bulk.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * @package WP SmushIt
5
- * @subpackage Admin
6
- * @version 1.0
7
- *
8
- * @author Saurabh Shukla <saurabh@incsub.com>
9
- * @author Umesh Kumar <umesh@incsub.com>
10
- *
11
- * @copyright (c) 2014, Incsub (http://incsub.com)
12
- */
13
- if ( ! class_exists( 'WpSmushitBulk' ) ) {
14
-
15
- /**
16
- * Methods for bulk processing
17
- */
18
- class WpSmushitBulk {
19
-
20
- /**
21
- * Fetch all the attachments
22
- * @return array $attachments
23
- */
24
- function get_attachments() {
25
- if ( ! isset( $_REQUEST['ids'] ) ) {
26
- $attachments = get_posts( array(
27
- 'numberposts' => - 1,
28
- 'post_type' => 'attachment',
29
- 'post_mime_type' => 'image',
30
- 'fields' => 'ids'
31
- ) );
32
- } else {
33
- return explode( ',', $_REQUEST['ids'] );
34
- }
35
-
36
- return $attachments;
37
- }
38
-
39
- }
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/error/class-wp-smushit-errorlog.php DELETED
@@ -1,80 +0,0 @@
1
- <?php
2
-
3
- class WpSmushitErrorLog {
4
- var $_limit = 100;
5
-
6
- function get_all_errors() {
7
- $errors = get_option( 'wp-smushit_error_log' );
8
-
9
- return $errors ? $errors : array();
10
- }
11
-
12
- function get_all_notices() {
13
- $notices = get_option( 'wp-smushit_notice_log' );
14
-
15
- return $notices ? $notices : array();
16
- }
17
-
18
- function purge_errors() {
19
- update_option( 'wp-smushit_error_log', array() );
20
- }
21
-
22
- function purge_notices() {
23
- update_option( 'wp-smushit_notice_log', array() );
24
- }
25
-
26
- /**
27
- * Store the error in db
28
- * @param $function, Function name where error occured
29
- * @param $image, Details of attachment
30
- * @param $exception, Details about error
31
- */
32
- function error( $function, $image, $exception ) {
33
- WpSmushitErrorRegistry::store( $exception );
34
- $info = is_object( $exception ) && method_exists( $exception, 'getMessage' )
35
- ? $exception->getMessage()
36
- : $exception;
37
-
38
- //If image variable is an array, display the details per line, otherwise display it directly
39
- $image = is_array( $image ) ? implode( "<br/>", $image ) : $image;
40
- $this->_update_error_queue( array(
41
- 'date' => current_time( 'timestamp' ),
42
- 'area' => $function,
43
- 'image' => $image,
44
- 'info' => $info
45
- ) );
46
- }
47
-
48
- /**
49
- * Store notice in db
50
- * @param $msg
51
- */
52
- function notice( $msg ) {
53
- $this->_update_notice_queue( array(
54
- 'date' => current_time( 'timestamp' ),
55
- 'user_id' => get_current_user_id(),
56
- 'message' => $msg
57
- ) );
58
- }
59
-
60
- function _update_error_queue( $error ) {
61
- $errors = $this->get_all_errors();
62
- if ( count( $errors ) >= $this->_limit ) {
63
- $errors = array_slice( $errors, ( ( $this->_limit * - 1 ) - 1 ), $this->_limit - 1 );
64
- }
65
- $errors[] = $error;
66
- update_option( 'wp-smushit_error_log', $errors );
67
- }
68
-
69
- function _update_notice_queue( $notice ) {
70
- $notices = $this->get_all_notices();
71
- if ( count( $notices ) >= $this->_limit ) {
72
- $notices = array_slice( $notices, - $this->_limit );
73
- } // * -1)), $this->_limit-1);
74
- $notices[] = $notice;
75
- update_option( 'wp-smushit_notice_log', $notices );
76
- }
77
- }
78
-
79
- global $log;
80
- $log = new WpSmushitErrorLog();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/error/class-wp-smushit-errorregistry.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Error registry class for exception transport.
5
- */
6
- class WpSmushitErrorRegistry {
7
- private static $_errors = array();
8
-
9
- private function __construct() {
10
- }
11
-
12
- public static function store( $exception ) {
13
- self::$_errors[] = $exception;
14
- }
15
-
16
- public static function clear() {
17
- self::$_errors = array();
18
- }
19
-
20
- public static function get_errors() {
21
- return self::$_errors;
22
- }
23
-
24
- public static function get_last_error() {
25
- return end( self::$_errors );
26
- }
27
-
28
- public static function get_last_error_message() {
29
- $e = self::get_last_error();
30
-
31
- return ( $e && is_object( $e ) && $e instanceof Exception )
32
- ? $e->getMessage()
33
- : false;
34
- }
35
- }
36
-
37
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/error_log.php DELETED
@@ -1,98 +0,0 @@
1
- <?php
2
- $date_fmt = get_option( 'date_format' );
3
- $date_fmt = $date_fmt ? $date_fmt : 'Y-m-d';
4
- $time_fmt = get_option( 'time_format' );
5
- $time_fmt = $time_fmt ? $time_fmt : 'H:i:s';
6
- $datetime_format = "{$date_fmt} {$time_fmt}";
7
- ?>
8
- <div class="wrap">
9
- <h2><?php _e( 'Error Log', WP_SMUSHIT_DOMAIN ); ?></h2>
10
-
11
- <h3>Errors</h3>
12
- <?php if ( $errors ) { ?>
13
- <a href="<?php echo wp_nonce_url( admin_url( 'admin.php?page=wp-smushit-errorlog&action=purge' ), 'purge_log' ); ?>"><?php _e( 'Purge log', WP_SMUSHIT_DOMAIN ); ?></a>
14
- <table class="widefat">
15
- <thead>
16
- <tr>
17
- <th><?php _e( 'Date', WP_SMUSHIT_DOMAIN ) ?></th>
18
- <th><?php _e( 'Function', WP_SMUSHIT_DOMAIN ) ?></th>
19
- <th><?php _e( 'Image', WP_SMUSHIT_DOMAIN ) ?></th>
20
- <th><?php _e( 'Info', WP_SMUSHIT_DOMAIN ) ?></th>
21
- </tr>
22
- </thead>
23
- <tfoot>
24
- <tr>
25
- <th><?php _e( 'Date', WP_SMUSHIT_DOMAIN ) ?></th>
26
- <th><?php _e( 'Function', WP_SMUSHIT_DOMAIN ) ?></th>
27
- <th><?php _e( 'Image', WP_SMUSHIT_DOMAIN ) ?></th>
28
- <th><?php _e( 'Info', WP_SMUSHIT_DOMAIN ) ?></th>
29
- </tr>
30
- </tfoot>
31
- <tbody>
32
- <?php foreach ( $errors as $error ) { ?>
33
- <?php $user = get_userdata( @$error['user_id'] ); ?>
34
- <tr>
35
- <td><?php echo date( $datetime_format, $error['date'] ); ?></td>
36
- <td><?php echo $error['area']; ?></td>
37
- <td><?php echo $error['image']; ?></td>
38
- <td><?php echo urldecode( $error['info'] ); ?></td>
39
- </tr>
40
- <?php } ?>
41
- </tbody>
42
- </table>
43
- <?php } else { ?>
44
- <p><i>Your error log is empty.</i></p>
45
- <?php } ?>
46
-
47
- <?php if ( current_user_can( 'manage_network_options' ) ) { ?>
48
- <p><a href="#notices" class="wp_smpro_toggle_notices">Show/Hide notices</a></p>
49
- <div id="wp_smpro_notices" style="display:none">
50
- <h3>Notices</h3>
51
- <?php if ( $notices ) { ?>
52
- <table class="widefat">
53
- <thead>
54
- <tr>
55
- <th><?php _e( 'Date', WP_SMUSHIT_DOMAIN ) ?></th>
56
- <th><?php _e( 'User', WP_SMUSHIT_DOMAIN ) ?></th>
57
- <th><?php _e( 'Message', WP_SMUSHIT_DOMAIN ) ?></th>
58
- </tr>
59
- </thead>
60
- <tfoot>
61
- <tr>
62
- <th><?php _e( 'Date', WP_SMUSHIT_DOMAIN ) ?></th>
63
- <th><?php _e( 'User', WP_SMUSHIT_DOMAIN ) ?></th>
64
- <th><?php _e( 'Message', WP_SMUSHIT_DOMAIN ) ?></th>
65
- </tr>
66
- </tfoot>
67
- <tbody>
68
- <?php foreach ( $notices as $notice ) { ?>
69
- <?php $user = get_userdata( @$notice['user_id'] ); ?>
70
- <tr>
71
- <td><?php echo date( $datetime_format, $notice['date'] ); ?></td>
72
- <td><?php echo( ( isset( $user->user_login ) && $user->user_login ) ? $user->user_login : __( 'Unknown', WP_SMUSHIT_DOMAIN ) ); ?></td>
73
- <td><?php echo $notice['message']; ?></td>
74
- </tr>
75
- <?php } ?>
76
- </tbody>
77
- </table>
78
- <?php } else { ?>
79
- <p><i>No notices.</i></p>
80
- <?php } ?>
81
- </div>
82
-
83
- <script type="text/javascript">
84
- (function ($) {
85
- $(function () {
86
-
87
- $(".wp_smpro_toggle_notices").click(function () {
88
- if ($("#wp_smpro_notices").is(":visible")) $("#wp_smpro_notices").hide();
89
- else $("#wp_smpro_notices").show();
90
- return false;
91
- });
92
-
93
- });
94
- })(jQuery);
95
- </script>
96
- <?php } ?>
97
-
98
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -1,90 +1,87 @@
1
- === WP Smush.it ===
2
- Plugin Name: WP Smush.it
3
- Version: 1.7.1.1
4
  Author: WPMU DEV
5
- Author URI: http://premium.wpmudev.org
6
- Contributors: WPMUDEV, alexdunae
7
- Tags: Compress,Images,Compression,Optimise,Optimize,Photo,Photos,Pictures,Smush,Smush.it,Upload,Yahoo,Yahoo Smush.it
8
  Requires at least: 3.5
9
- Tested up to: 4.1
10
- Stable tag: 1.7.1.1
11
  License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12
 
13
- Improve performance and get faster load times by optimizing image files with <a href="http://smush.it/">Smush.it</a> for WordPress – “It's the best plugin of its kind.”
14
-
15
  == Description ==
16
 
17
  <blockquote>
18
- According to <a href="http://www.phpied.com/smush-it-is-dead-long-live-smushing/">unofficial but pretty reliable reports</a> Yahoo has stopped maintaining Smush.it :(
19
-
20
- However, all is not lost! We are working like maniacs here at WPMU DEV to bring you a free, more reliable and better free smushing experience built off of our pro version of the plugin and wrapped up in the next update. We hope to have it available to you very, very soon... in the meantime please stay with us, it'll be worth it, promise. <br />
21
- <em>- James, WPMU DEV, 6th April</em>
22
  </blockquote>
23
 
24
- WP Smush.it strips hidden, bulky information from your images, reducing the file size without losing quality. The faster your site loads, the more Google, Bing, Yahoo and other search engines will like it.
25
 
26
  [youtube https://www.youtube.com/watch?v=_74QFoRb230]
27
 
28
- Heavy image files may be slowing down your site without you even knowing it. WP Smush.it meticulously scans every image you upload – or have already added to your site – and cuts all the unnecessary data for you.
29
 
30
  ★★★★★ <br>
31
  “I had no idea that my page load time was being dragged down by the images. The plugin nearly halved the time it took.” - <a href="http://profiles.wordpress.org/karlcw">karlcw</a>
32
 
33
- Install WP Smush.it and find out why it's the most popular image optimization plugin for WordPress available today with over 1 million downloads.
34
 
35
  <blockquote>
36
- <h4>If you like WP Smush.it, you'll love WP Smush Pro</h4>
37
  <br>
38
- <a href="http://premium.wpmudev.org/project/wp-smush-pro/">WP Smush Pro</a> gives you everything you'll find in WP Smush.it and more:
39
  <ul>
40
- <li>Access better quality, higher performing WPMU DEV dedicated smushing servers</li>
41
- <li>Smush images up to 5MB (WP Smush.it is limited to 1MB)</li>
42
- <li>No more batch smushing dropouts or timeouts (you have your own dedicated servers)</li>
43
- <li>Works with HTTPS images (WP Smush.it won’t work with HTTPS)</li>
44
- <li>24/7/365 support from <a href="http://premium.wpmudev.org/support/">the best WordPress support team on the planet</a></li>
45
- <li><a href="http://premium.wpmudev.org/join/">400+ other premium plugins and themes</a> included in your membership</li>
 
46
  </ul>
47
 
48
- Upgrade to <a href="http://premium.wpmudev.org/project/wp-smush-pro/">WP Smush Pro</a> and optimize more and larger image files faster and with greater reliability to increase your site’s performance.
49
  </blockquote>
50
 
51
- Features available to both WP Smush.it and pro users include:
52
  <ul>
53
- <li>Optimize your images using lossless compression techniques</li>
54
- <li>Process JPEG, GIF and PNG image files</li>
55
- <li>Compress files 1 MB or smaller</li>
56
- <li>Strip unused colours from indexed images</li>
57
- <li>Both versions are fully internationalized</li>
 
 
58
  </ul>
59
- Discover for yourself why WP Smush.it is the most popular free image optimization plugin with more than a million downloads.
60
 
61
 
62
  == Screenshots ==
63
 
64
- 1. See the savings from Smush.it in the Media Library.
 
65
 
66
  == Installation ==
67
 
68
- 1. Upload the `wp-smushit` plugin to your `/wp-content/plugins/` directory.
69
  1. Activate the plugin through the 'Plugins' menu in WordPress.
70
- 1. Automatic smushing of uploaded images can be controlled on the `Settings > Media` screen
71
  1. Done!
72
 
73
  == Upgrade Notice ==
74
 
75
- In this first official release from WPMU DEV, we've done a code cleanup and reformat to get started, as well as
76
- attempting to handle smush.it API errors a bit better. We've also made all the text fully i18n translatable.
77
-
78
- This will give us a good foundation to start adding some new features!
79
 
80
 
81
  == Changelog ==
82
-
83
- = 1.7.1.1 =
84
- * Disable smushing, until smush service resumes
85
-
86
- = 1.7.1 =
87
- * Add depreciated warnings about Smush.it outage
88
 
89
  = 1.7 =
90
  * Use Ajax for Bulk Smush to avoid timeouts and internal server error
@@ -225,17 +222,13 @@ This will give us a good foundation to start adding some new features!
225
 
226
  == About Us ==
227
  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:
228
- <a href="http://premium.wpmudev.org/join/">http://premium.wpmudev.org/join/</a>
229
 
230
  Don't forget to stay up to date on everything WordPress from the Internet's number one resource:
231
- <a href="http://wpmu.org/">http://wpmu.org</a>
232
 
233
  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!
234
 
235
  == Contact and Credits ==
236
 
237
- Originally written by Alex Dunae at Dialect ([dialect.ca](http://dialect.ca/?wp_smush_it), e-mail 'alex' at 'dialect dot ca'), 2008-11.
238
-
239
- 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.
240
-
241
- Smush.it was created by [Nicole Sullivan](http://www.stubbornella.org/content/) and [Stoyan Stefanov](http://phpied.com/).
1
+ === WP Smush ===
2
+ Plugin Name: WP Smush
3
+ Version: 2.0
4
  Author: WPMU DEV
5
+ Author URI: http://premium.wpmudev.org/
6
+ Contributors: WPMUDEV, alexdunae, umeshsingla
7
+ Tags: Attachment,Attachments,Compress,Compress Image File,Compress Image Size,Compress JPG,Compressed JPG, Compression Image,Image,Images,JPG,Optimise,Optimize,Photo,Photos,Pictures,PNG,Reduce Image Size,Smush,Smush.it,Upload,WordPress Compression,WordPress Image Tool,Yahoo, Yahoo Smush.it
8
  Requires at least: 3.5
9
+ Tested up to: 4.2
10
+ Stable tag: 2.0
11
  License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12
 
 
 
13
  == Description ==
14
 
15
  <blockquote>
16
+ Yahoo has stopped maintaining the Smush.it API. So WPMU DEV gathered it's crack team of developers to work like maniacs and create a free, fast, and more reliable API to replace it.
17
+ Then we rewrote this free plugin from the ground up as "WP Smush" with new and exciting features that just work. Update today!
 
 
18
  </blockquote>
19
 
20
+ WP Smush strips hidden, bulky information from your images, reducing the file size without losing quality. The faster your site loads, the more Google, Bing, Yahoo and other search engines will like it.
21
 
22
  [youtube https://www.youtube.com/watch?v=_74QFoRb230]
23
 
24
+ Heavy image files may be slowing down your site without you even knowing it. WP Smush meticulously scans every image you upload – or have already added to your site – and cuts all the unnecessary data for you.
25
 
26
  ★★★★★ <br>
27
  “I had no idea that my page load time was being dragged down by the images. The plugin nearly halved the time it took.” - <a href="http://profiles.wordpress.org/karlcw">karlcw</a>
28
 
29
+ Install WP Smush and find out why it's the most popular image optimization plugin for WordPress available today with over 1 million downloads.
30
 
31
  <blockquote>
32
+ <h4>If you like WP Smush, you'll love WP Smush Pro</h4>
33
  <br>
34
+ <a href="https://premium.wpmudev.org/project/wp-smush-pro/?utm_source=wordpress.org&utm_medium=readme">WP Smush Pro</a> gives you everything you'll find in WP Smush and more:
35
  <ul>
36
+ <li>"Super-Smush" your images with our intelligent multi-pass lossy compression. Get >60% average compression with almost no noticeable quality loss!</li>
37
+ <li>Get even better lossless compression. We try multiple methods to squeeze every last byte out of your images.</li>
38
+ <li>Smush images up to 8MB (WP Smush is limited to 1MB)</li>
39
+ <li>Bulk smush ALL your images with one click! No more rate limiting.</li>
40
+ <li>Keep a backup of your original un-smushed images in case you want to restore later.</li>
41
+ <li>24/7/365 support from <a href="https://premium.wpmudev.org/support/?utm_source=wordpress.org&utm_medium=readme">the best WordPress support team on the planet</a>.</li>
42
+ <li><a href="https://premium.wpmudev.org/?utm_source=wordpress.org&utm_medium=readme">350+ other premium plugins and themes</a> included in your membership.</li>
43
  </ul>
44
 
45
+ Upgrade to <a href="https://premium.wpmudev.org/project/wp-smush-pro/?utm_source=wordpress.org&utm_medium=readme">WP Smush Pro</a> and optimize more and larger image files faster to increase your site’s performance.
46
  </blockquote>
47
 
48
+ Features available to both WP Smush and Pro users include:
49
  <ul>
50
+ <li>Optimize your images using advanced lossless compression techniques.</li>
51
+ <li>Process JPEG, GIF and PNG image files.</li>
52
+ <li>Auto-Smush your attachments on upload.</li>
53
+ <li>Manually smush your attachments individually in the media library, or in bulk 50 attachments at a time.</li>
54
+ <li>Smush all images 1MB or smaller.</li>
55
+ <li>Use of WPMU DEV's fast and reliable Smush API service.</li>
56
+ <li>View advanced compression stats per-attachment and library totals.</li>
57
  </ul>
58
+ Discover for yourself why WP Smush is the most popular free image optimization plugin with more than a million downloads.
59
 
60
 
61
  == Screenshots ==
62
 
63
+ 1. See individual attachment savings from WP Smush in the Media Library.
64
+ 2. See the total savings from WP Smush in the Media Library.
65
 
66
  == Installation ==
67
 
68
+ 1. Upload the `wp-smush` plugin to your `/wp-content/plugins/` directory.
69
  1. Activate the plugin through the 'Plugins' menu in WordPress.
70
+ 1. Configure your desired settings via the `Media -> WP Smush` settings page.
71
  1. Done!
72
 
73
  == Upgrade Notice ==
74
 
75
+ Yahoo's Smush.it API is gone forever. So WPMU DEV built our own free API that is faster, more reliable, and more powerful. Upgrade now!
 
 
 
76
 
77
 
78
  == Changelog ==
79
+ = 2.0 =
80
+ * Complete rewrite to use WPMU DEV's new fast and reliable API service.
81
+ * New: One-click bulk smushing of all your images.
82
+ * New: "Super-Smush" your images with our intelligent multi-pass lossy compression. Get >60% average compression with almost no noticeable quality loss! (Pro)
83
+ * New: Keep a backup of your original un-smushed images in case you want to restore later. (Pro)
84
+ * UX/UI updated with overall stats, progress bar.
85
 
86
  = 1.7 =
87
  * Use Ajax for Bulk Smush to avoid timeouts and internal server error
222
 
223
  == About Us ==
224
  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:
225
+ <a href="https://premium.wpmudev.org/?utm_source=wordpress.org&utm_medium=readme">https://premium.wpmudev.org/</a>
226
 
227
  Don't forget to stay up to date on everything WordPress from the Internet's number one resource:
228
+ <a href="https://premium.wpmudev.org/blog/?utm_source=wordpress.org&utm_medium=readme">WPMU DEV Blog</a>
229
 
230
  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!
231
 
232
  == Contact and Credits ==
233
 
234
+ Originally written by Alex Dunae at Dialect ([dialect.ca](http://dialect.ca/?wp_smush_it), e-mail 'alex' at 'dialect dot ca'), 2008-11.
 
 
 
 
screenshot-1.jpg DELETED
Binary file
uninstall.php CHANGED
@@ -13,17 +13,13 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
13
  global $wpdb;
14
 
15
  $smushit_keys = array(
16
- 'smushit_auto',
17
- 'smushit_timeout',
18
- 'smushit_enforce_same_url',
19
- 'smushit_debug',
20
- 'error_log',
21
- 'notice_log'
22
  );
23
  foreach ( $smushit_keys as $key ) {
24
- $key = 'wp_smushit_' . $key;
25
  if ( is_multisite() ) {
26
- $blogs = $wpdb->get_results( "SELECT blog_id FROM {$wpdb->blogs}", ARRAY_A );
27
  if ( $blogs ) {
28
  foreach ( $blogs as $blog ) {
29
  switch_to_blog( $blog['blog_id'] );
13
  global $wpdb;
14
 
15
  $smushit_keys = array(
16
+ 'auto',
17
+
 
 
 
 
18
  );
19
  foreach ( $smushit_keys as $key ) {
20
+ $key = 'wp-smush-' . $key;
21
  if ( is_multisite() ) {
22
+ $blogs = $wpdb->get_results( "SELECT blog_id FROM {$wpdb->blogs} LIMIT 100", ARRAY_A );
23
  if ( $blogs ) {
24
  foreach ( $blogs as $blog ) {
25
  switch_to_blog( $blog['blog_id'] );
wp-smush.php ADDED
@@ -0,0 +1,899 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: WP Smush
4
+ Plugin URI: http://wordpress.org/extend/plugins/wp-smushit/
5
+ Description: Reduce image file sizes and improve performance using the <a href="https://premium.wpmudev.org/">WPMU DEV</a> Smush API within WordPress.
6
+ Author: WPMU DEV
7
+ Version: 2.0
8
+ Author URI: http://premium.wpmudev.org/
9
+ Textdomain: wp_smush
10
+ */
11
+
12
+ /*
13
+ This plugin was originally developed by Alex Dunae.
14
+ http://dialect.ca/
15
+ */
16
+
17
+ /*
18
+ Copyright 2007-2015 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
+
35
+ /**
36
+ * Constants
37
+ */
38
+ define( 'WP_SMUSH_VERSON', "2.0" );
39
+ /**
40
+ * Plugin base name
41
+ */
42
+ define( 'WP_SMUSH_BASENAME', plugin_basename( __FILE__ ) );
43
+
44
+ define( 'WP_SMUSH_API', 'https://smushpro.wpmudev.org/1.0/' );
45
+ define( 'WP_SMUSH_DOMAIN', 'wp_smush' );
46
+ define( 'WP_SMUSH_UA', 'WP Smush/' . WP_SMUSH_VERSON . '; ' . network_home_url() );
47
+ define( 'WP_SMUSH_DIR', plugin_dir_path( __FILE__ ) );
48
+ define( 'WP_SMUSH_URL', plugin_dir_url( __FILE__ ) );
49
+ define( 'WP_SMUSH_MAX_BYTES', 1000000 );
50
+ define( 'WP_SMUSH_PREMIUM_MAX_BYTES', 8000000 );
51
+ define( 'WP_SMUSH_PREFIX', 'wp-smush-' );
52
+ if ( ! defined( 'WP_SMUSH_TIMEOUT' ) ) {
53
+ define( 'WP_SMUSH_TIMEOUT', 30 );
54
+ }
55
+
56
+ require_once WP_SMUSH_DIR . "/lib/class-wp-smush-migrate.php";
57
+
58
+ if ( ! class_exists( 'WpSmush' ) ) {
59
+
60
+ class WpSmush {
61
+
62
+ var $version = WP_SMUSH_VERSON;
63
+
64
+ /**
65
+ * Meta key for api validity
66
+ *
67
+ */
68
+ const VALIDITY_KEY = "wp-smush-valid";
69
+
70
+ /**
71
+ * Api server url to check api key validity
72
+ *
73
+ */
74
+ const API_SERVER = 'https://premium.wpmudev.org/wdp-un.php?action=smushit_check';
75
+
76
+ /**
77
+ * Meta key to save smush result to db
78
+ *
79
+ *
80
+ */
81
+ const SMUSHED_META_KEY = 'wp-smpro-smush-data';
82
+
83
+ /**
84
+ * Meta key to save migrated version
85
+ *
86
+ */
87
+ const MIGRATED_VERSION = "wp-smush-migrated-version";
88
+
89
+ /**
90
+ * Constructor
91
+ */
92
+ function __construct() {
93
+ /**
94
+ * Hooks
95
+ */
96
+ //Check if auto is enabled
97
+ $auto_smush = get_option( WP_SMUSH_PREFIX . 'auto' );
98
+
99
+ //Keep the uto smush on by default
100
+ if ( $auto_smush === false ) {
101
+ $auto_smush = 1;
102
+ }
103
+
104
+ if ( $auto_smush ) {
105
+ add_filter( 'wp_generate_attachment_metadata', array( $this, 'filter_generate_attachment_metadata' ), 10, 2 );
106
+ }
107
+ add_filter( 'manage_media_columns', array( $this, 'columns' ) );
108
+ add_action( 'manage_media_custom_column', array( $this, 'custom_column' ), 10, 2 );
109
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
110
+ add_action( "admin_init", array( $this, "migrate" ) );
111
+
112
+ }
113
+
114
+ function admin_init() {
115
+ load_plugin_textdomain( WP_SMUSH_DOMAIN, false, dirname( WP_SMUSH_BASENAME ) . '/languages/' );
116
+ wp_enqueue_script( 'common' );
117
+ }
118
+
119
+ /**
120
+ * Process an image with Smush.
121
+ *
122
+ * Returns an array of the $file $results.
123
+ *
124
+ * @param string $file Full absolute path to the image file
125
+ * @param string $file_url Optional full URL to the image file
126
+ *
127
+ * @returns array
128
+ */
129
+ function do_smushit( $attachment_id, $file_path = '', $file_url = '' ) {
130
+ $errors = new WP_Error();
131
+ if ( empty( $file_path ) ) {
132
+ $errors->add( "empty_path", __( "File path is empty", WP_SMUSH_DOMAIN ) );
133
+ }
134
+
135
+ if ( empty( $file_url ) ) {
136
+ $errors->add( "empty_url", __( "File URL is empty", WP_SMUSH_DOMAIN ) );
137
+ }
138
+
139
+ // check that the file exists
140
+ if ( ! file_exists( $file_path ) || ! is_file( $file_path ) ) {
141
+ $errors->add( "file_not_found", sprintf( __( "Could not find %s", WP_SMUSH_DOMAIN ), $file_path ) );
142
+ }
143
+
144
+ // check that the file is writable
145
+ if ( ! is_writable( dirname( $file_path ) ) ) {
146
+ $errors->add( "not_writable", sprintf( __( "%s is not writable", WP_SMUSH_DOMAIN ), dirname( $file_path ) ) );
147
+ }
148
+
149
+ $file_size = filesize( $file_path );
150
+
151
+ //Check if premium user
152
+ $max_size = $this->is_premium() ? WP_SMUSH_PREMIUM_MAX_BYTES : WP_SMUSH_MAX_BYTES;
153
+
154
+ //Check if file exists
155
+ if ( $file_size == 0 ) {
156
+ $errors->add( "image_not_found", sprintf( __( 'Skipped (%s), image not found.', WP_SMUSH_DOMAIN ), $this->format_bytes( $file_size ) ) );
157
+ }
158
+
159
+ //Check size limit
160
+ if ( $file_size > $max_size ) {
161
+ $errors->add( "size_limit", sprintf( __( 'Skipped (%s), size limit exceeded.', WP_SMUSH_DOMAIN ), $this->format_bytes( $file_size ) ) );
162
+ }
163
+
164
+ if ( count( $errors->get_error_messages() ) ) {
165
+ return $errors;
166
+ }
167
+
168
+ /** Send image for smushing, and fetch the response */
169
+ $response = $this->_post( $file_path, $file_size );
170
+
171
+ if ( ! $response['success'] ) {
172
+ $errors->add( "false_response", $response['message'] );
173
+ }
174
+ //If there is no data
175
+ if ( empty( $response['data'] ) ) {
176
+ $errors->add( "no_data", __( 'Unknown API error', WP_SMUSH_DOMAIN ) );
177
+ }
178
+
179
+ if ( count( $errors->get_error_messages() ) ) {
180
+ return $errors;
181
+ }
182
+
183
+ //If there are no savings, or image returned is bigger in size
184
+ if ( ( ! empty( $response['data']->bytes_saved ) && intval( $response['data']->bytes_saved ) <= 0 )
185
+ || empty( $response['data']->image )
186
+ ) {
187
+ return $response;
188
+ }
189
+ $tempfile = $file_path . ".tmp";
190
+
191
+ //Add the file as tmp
192
+ file_put_contents( $tempfile, $response['data']->image );
193
+
194
+ //handle backups if enabled
195
+ $backup = get_option( WP_SMUSH_PREFIX . 'backup' );
196
+ if ( $backup && $this->is_premium() ) {
197
+ $path = pathinfo( $file_path );
198
+ $backup_name = trailingslashit( $path['dirname'] ) . $path['filename'] . ".bak." . $path['extension'];
199
+ @copy( $file_path, $backup_name );
200
+ }
201
+
202
+ //replace the file
203
+ $success = @rename( $tempfile, $file_path );
204
+
205
+ //if tempfile still exists, unlink it
206
+ if ( file_exists( $tempfile ) ) {
207
+ unlink( $tempfile );
208
+ }
209
+
210
+ //If file renaming was successful
211
+ if ( ! $success ) {
212
+ copy( $tempfile, $file_path );
213
+ unlink( $tempfile );
214
+ }
215
+
216
+ return $response;
217
+ }
218
+
219
+ /**
220
+ * Fills $placeholder array with values from $data array without creating new keys
221
+ *
222
+ * @param array $placeholders
223
+ * @param array $data
224
+ *
225
+ * @return array
226
+ */
227
+ private function _array_fill_placeholders( array $placeholders, array $data ) {
228
+ return array_merge( $placeholders, array_intersect_key( $data, $placeholders ) );
229
+ }
230
+
231
+ /**
232
+ * Returns signature for single size of the smush api message to be saved to db;
233
+ *
234
+ * @return array
235
+ */
236
+ private function _get_size_signature() {
237
+ return array(
238
+ 'percent' => - 1,
239
+ 'bytes' => - 1,
240
+ 'size_before' => - 1,
241
+ 'size_after' => - 1,
242
+ 'time' => - 1
243
+ );
244
+ }
245
+
246
+ /**
247
+ * Read the image paths from an attachment's meta data and process each image
248
+ * with wp_smushit().
249
+ *
250
+ * This method also adds a `wp_smushit` meta key for use in the media library.
251
+ * Called after `wp_generate_attachment_metadata` is completed.
252
+ *
253
+ * @param $meta
254
+ * @param null $ID
255
+ * @param bool $force_resmush
256
+ *
257
+ * @return mixed
258
+ */
259
+ function resize_from_meta_data( $meta, $ID = null, $force_resmush = true ) {
260
+
261
+ //Flag to check, if original size image needs to be smushed or not
262
+ $smush_full = true;
263
+ $errors = new WP_Error();
264
+ $stats = array(
265
+ "stats" => array_merge( $this->_get_size_signature(), array(
266
+ 'api_version' => - 1,
267
+ 'lossy' => - 1
268
+ )
269
+ ),
270
+ 'sizes' => array()
271
+ );
272
+
273
+ $size_before = $size_after = $compression = $total_time = $bytes_saved = 0;
274
+
275
+ if ( $ID && wp_attachment_is_image( $ID ) === false ) {
276
+ return $meta;
277
+ }
278
+
279
+ //File path and URL for original image
280
+ $attachment_file_path = get_attached_file( $ID );
281
+ $attachment_file_url = wp_get_attachment_url( $ID );
282
+
283
+ // If images has other registered size, smush them first
284
+ if ( ! empty( $meta['sizes'] ) ) {
285
+
286
+ foreach ( $meta['sizes'] as $size_key => $size_data ) {
287
+
288
+ //if there is a large size, then we will set a flag to leave the original untouched
289
+ if ( $size_key == 'large' ) {
290
+ $smush_full = false;
291
+ }
292
+
293
+ // We take the original image. The 'sizes' will all match the same URL and
294
+ // path. So just get the dirname and replace the filename.
295
+
296
+ $attachment_file_path_size = trailingslashit( dirname( $attachment_file_path ) ) . $size_data['file'];
297
+ $attachment_file_url_size = trailingslashit( dirname( $attachment_file_url ) ) . $size_data['file'];
298
+
299
+ //Store details for each size key
300
+ $response = $this->do_smushit( $ID, $attachment_file_path_size, $attachment_file_url_size );
301
+
302
+ if ( is_wp_error( $response ) ) {
303
+ return $response;
304
+ }
305
+
306
+ if ( ! empty( $response['data'] ) ) {
307
+ $stats['sizes'][ $size_key ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $response['data'] );
308
+ }
309
+
310
+ //Total Stats, store all data in bytes
311
+ if ( isset( $response['data'] ) ) {
312
+ list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
313
+ = $this->_update_stats_data( $response['data'], $size_before, $size_after, $total_time, $bytes_saved );
314
+ } else {
315
+ $errors->add( "image_size_error" . $size_key, sprintf( __( "Size '%s' not processed correctly", WP_SMUSH_DOMAIN ), $size_key ) );
316
+ }
317
+
318
+ if ( empty( $stats['stats']['api_version'] ) ) {
319
+ $stats['stats']['api_version'] = $response['data']->api_version;
320
+ $stats['stats']['lossy'] = $response['data']->lossy;
321
+ }
322
+ }
323
+ }
324
+
325
+ //If original size is supposed to be smushed
326
+ if ( $smush_full ) {
327
+
328
+ $full_image_response = $this->do_smushit( $ID, $attachment_file_path, $attachment_file_url );
329
+
330
+ if ( is_wp_error( $full_image_response ) ) {
331
+ return $full_image_response;
332
+ }
333
+
334
+ if ( ! empty( $full_image_response['data'] ) ) {
335
+ $stats['sizes']['full'] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $full_image_response['data'] );
336
+ } else {
337
+ $errors->add( "image_size_error", __( "Size 'full' not processed correctly", WP_SMUSH_DOMAIN ) );
338
+ }
339
+
340
+ //Update stats
341
+ if ( isset( $full_image_response['data'] ) ) {
342
+ list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
343
+ = $this->_update_stats_data( $full_image_response['data'], $size_before, $size_after, $total_time, $bytes_saved );
344
+ } else {
345
+ $errors->add( "image_size_error", __( "Size 'full' not processed correctly", WP_SMUSH_DOMAIN ) );
346
+ }
347
+
348
+ }
349
+
350
+ $has_errors = (bool) count( $errors->get_error_messages() );
351
+
352
+ //Store stats
353
+
354
+ list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
355
+ array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
356
+
357
+
358
+ //Set smush status for all the images, store it in wp-smpro-smush-data
359
+ if ( ! $has_errors ) {
360
+ update_post_meta( $ID, self::SMUSHED_META_KEY, $stats );
361
+ }
362
+
363
+ //return stats
364
+ return $has_errors ? $errors : $stats['stats'];
365
+ }
366
+
367
+ /**
368
+ * Read the image paths from an attachment's meta data and process each image
369
+ * with wp_smushit()
370
+ *
371
+ * Filters wp_generate_attachment_metadata
372
+ * @param $meta
373
+ * @param null $ID
374
+ *
375
+ * @return mixed
376
+ */
377
+ function filter_generate_attachment_metadata( $meta, $ID = null ){
378
+ //Flag to check, if original size image needs to be smushed or not
379
+ $smush_full = true;
380
+ $errors = new WP_Error();
381
+ $stats = array(
382
+ "stats" => array_merge( $this->_get_size_signature(), array(
383
+ 'api_version' => - 1,
384
+ 'lossy' => - 1
385
+ )
386
+ ),
387
+ 'sizes' => array()
388
+ );
389
+
390
+ $size_before = $size_after = $compression = $total_time = $bytes_saved = 0;
391
+
392
+ if ( $ID && wp_attachment_is_image( $ID ) === false ) {
393
+ return $meta;
394
+ }
395
+
396
+ //File path and URL for original image
397
+ $attachment_file_path = get_attached_file( $ID );
398
+ $attachment_file_url = wp_get_attachment_url( $ID );
399
+
400
+ // If images has other registered size, smush them first
401
+ if ( ! empty( $meta['sizes'] ) ) {
402
+
403
+ foreach ( $meta['sizes'] as $size_key => $size_data ) {
404
+
405
+ //if there is a large size, then we will set a flag to leave the original untouched
406
+ if ( $size_key == 'large' ) {
407
+ $smush_full = false;
408
+ }
409
+
410
+ // We take the original image. The 'sizes' will all match the same URL and
411
+ // path. So just get the dirname and replace the filename.
412
+
413
+ $attachment_file_path_size = trailingslashit( dirname( $attachment_file_path ) ) . $size_data['file'];
414
+ $attachment_file_url_size = trailingslashit( dirname( $attachment_file_url ) ) . $size_data['file'];
415
+
416
+ //Store details for each size key
417
+ $response = $this->do_smushit( $ID, $attachment_file_path_size, $attachment_file_url_size );
418
+
419
+ if ( is_wp_error( $response ) ) {
420
+ return $meta;
421
+ }
422
+
423
+ if ( ! empty( $response['data'] ) ) {
424
+ $stats['sizes'][ $size_key ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $response['data'] );
425
+ }
426
+
427
+ //Total Stats, store all data in bytes
428
+ if ( isset( $response['data'] ) ) {
429
+ list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
430
+ = $this->_update_stats_data( $response['data'], $size_before, $size_after, $total_time, $bytes_saved );
431
+ } else {
432
+ $errors->add( "image_size_error" . $size_key, sprintf( __( "Size '%s' not processed correctly", WP_SMUSH_DOMAIN ), $size_key ) );
433
+ }
434
+
435
+ if ( empty( $stats['stats']['api_version'] ) ) {
436
+ $stats['stats']['api_version'] = $response['data']->api_version;
437
+ $stats['stats']['lossy'] = $response['data']->lossy;
438
+ }
439
+ }
440
+ }
441
+
442
+ //If original size is supposed to be smushed
443
+ if ( $smush_full ) {
444
+
445
+ $full_image_response = $this->do_smushit( $ID, $attachment_file_path, $attachment_file_url );
446
+
447
+ if ( is_wp_error( $full_image_response ) ) {
448
+ return $meta;
449
+ }
450
+
451
+ if ( ! empty( $full_image_response['data'] ) ) {
452
+ $stats['sizes']['full'] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $full_image_response['data'] );
453
+ } else {
454
+ $errors->add( "image_size_error", __( "Size 'full' not processed correctly", WP_SMUSH_DOMAIN ) );
455
+ }
456
+
457
+ //Update stats
458
+ if ( isset( $full_image_response['data'] ) ) {
459
+ list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
460
+ = $this->_update_stats_data( $full_image_response['data'], $size_before, $size_after, $total_time, $bytes_saved );
461
+ } else {
462
+ $errors->add( "image_size_error", __( "Size 'full' not processed correctly", WP_SMUSH_DOMAIN ) );
463
+ }
464
+
465
+ }
466
+
467
+ $has_errors = (bool) count( $errors->get_error_messages() );
468
+
469
+ //Store stats
470
+
471
+ list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
472
+ array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
473
+
474
+
475
+ //Set smush status for all the images, store it in wp-smpro-smush-data
476
+ if ( ! $has_errors ) {
477
+ update_post_meta( $ID, self::SMUSHED_META_KEY, $stats );
478
+ }
479
+
480
+ //return stats
481
+ return $has_errors ? $meta : $stats['stats'];
482
+ }
483
+
484
+ /**
485
+ * Post an image to Smush.
486
+ *
487
+ * @param string $file_url URL of the file to send to Smush
488
+ *
489
+ * @return array Returns array containing success status, and stats
490
+ */
491
+ function _post( $file_path, $file_size ) {
492
+ global $log;
493
+
494
+ $data = false;
495
+
496
+ $file = @fopen( $file_path, 'r' );
497
+ $file_data = fread( $file, $file_size );
498
+ $headers = array(
499
+ 'accept' => 'application/json', // The API returns JSON
500
+ 'content-type' => 'application/binary', // Set content type to binary
501
+ );
502
+
503
+ //Check if premium member, add API key
504
+ $api_key = $this->_get_api_key();
505
+ if ( ! empty( $api_key ) ) {
506
+ $headers['apikey'] = $api_key;
507
+ }
508
+
509
+ //Check if lossy compression allowed and add it to headers
510
+ $lossy = get_option( WP_SMUSH_PREFIX . 'lossy' );
511
+
512
+ if ( $lossy && $this->is_premium() ) {
513
+ $headers['lossy'] = 'true';
514
+ } else {
515
+ $headers['lossy'] = 'false';
516
+ }
517
+
518
+ $args = array(
519
+ 'headers' => $headers,
520
+ 'body' => $file_data,
521
+ 'timeout' => WP_SMUSH_TIMEOUT,
522
+ 'user-agent' => WP_SMUSH_UA
523
+ );
524
+ $result = wp_remote_post( WP_SMUSH_API, $args );
525
+
526
+ //Close file connection
527
+ fclose( $file );
528
+ unset( $file_data );//free memory
529
+ if ( is_wp_error( $result ) ) {
530
+ //Handle error
531
+ $data['message'] = sprintf( __( 'Error posting to API: %s', WP_SMUSH_DOMAIN ), $result->get_error_message() );
532
+ $data['success'] = false;
533
+ unset( $result ); //free memory
534
+ return $data;
535
+ } else if ( '200' != wp_remote_retrieve_response_code( $result ) ) {
536
+ //Handle error
537
+ $data['message'] = sprintf( __( 'Error posting to API: %s %s', WP_SMUSHIT_DOMAIN ), wp_remote_retrieve_response_code( $result ), wp_remote_retrieve_response_message( $result ) );
538
+ $data['success'] = false;
539
+ unset( $result ); //free memory
540
+
541
+ return $data;
542
+ }
543
+
544
+ //If there is a response and image was successfully optimised
545
+ $response = json_decode( $result['body'] );
546
+ if ( $response && $response->success == true ) {
547
+
548
+ //If there is any savings
549
+ if ( $response->data->bytes_saved > 0 ) {
550
+ $image = base64_decode( $response->data->image ); //base64_decode is necessary to send binary img over JSON, no security problems here!
551
+ $image_md5 = md5( $response->data->image );
552
+ if ( $response->data->image_md5 != $image_md5 ) {
553
+ //Handle error
554
+ $data['message'] = __( 'Smush data corrupted, try again.', WP_SMUSH_DOMAIN );
555
+ $data['success'] = false;
556
+ unset( $image );//free memory
557
+ } else {
558
+ $data['success'] = true;
559
+ $data['data'] = $response->data;
560
+ $data['data']->image = $image;
561
+ unset( $image );//free memory
562
+ }
563
+ } else {
564
+ //just return the data
565
+ $data['success'] = true;
566
+ $data['data'] = $response->data;
567
+ }
568
+ } else {
569
+ //Server side error, get message from response
570
+ $data['message'] = ! empty( $response->data ) ? $response->data : __( "Image couldn't be smushed", WP_SMUSH_DOMAIN );
571
+ $data['success'] = false;
572
+ }
573
+
574
+ unset( $result );//free memory
575
+ unset( $response );//free memory
576
+ return $data;
577
+ }
578
+
579
+
580
+ /**
581
+ * Print column header for Smush results in the media library using
582
+ * the `manage_media_columns` hook.
583
+ */
584
+ function columns( $defaults ) {
585
+ $defaults['smushit'] = 'WP Smush';
586
+
587
+ return $defaults;
588
+ }
589
+
590
+ /**
591
+ * Return the filesize in a humanly readable format.
592
+ * Taken from http://www.php.net/manual/en/function.filesize.php#91477
593
+ */
594
+ function format_bytes( $bytes, $precision = 2 ) {
595
+ $units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
596
+ $bytes = max( $bytes, 0 );
597
+ $pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
598
+ $pow = min( $pow, count( $units ) - 1 );
599
+ $bytes /= pow( 1024, $pow );
600
+
601
+ return round( $bytes, $precision ) . ' ' . $units[ $pow ];
602
+ }
603
+
604
+ /**
605
+ * Print column data for Smush results in the media library using
606
+ * the `manage_media_custom_column` hook.
607
+ */
608
+ function custom_column( $column_name, $id ) {
609
+ if ( 'smushit' == $column_name ) {
610
+ $this->set_status( $id );
611
+ }
612
+ }
613
+
614
+ /**
615
+ * Check if user is premium member, check for api key
616
+ *
617
+ * @return mixed|string
618
+ */
619
+ function is_premium() {
620
+
621
+ //no api key set, always false
622
+ $api_key = $this->_get_api_key();
623
+ if ( empty( $api_key ) ) {
624
+ return false;
625
+ }
626
+
627
+ $key = "wp-smush-valid-$api_key"; //add apikey to transient key in case it changes
628
+
629
+ if ( false === ( $valid = get_site_transient( $key ) ) ) {
630
+ // call api
631
+ $url = self::API_SERVER . '&key=' . urlencode( $api_key );
632
+
633
+ $request = wp_remote_get( $url, array(
634
+ "timeout" => 3
635
+ )
636
+ );
637
+
638
+ if ( ! is_wp_error( $request ) && '200' == wp_remote_retrieve_response_code( $request ) ) {
639
+ $result = json_decode( wp_remote_retrieve_body( $request ) );
640
+ if ( $result && $result->success ) {
641
+ $valid = true;
642
+ set_site_transient( $key, 1, 12 * HOUR_IN_SECONDS );
643
+ } else {
644
+ $valid = false;
645
+ set_site_transient( $key, 0, 30 * MINUTE_IN_SECONDS ); //cache failure much shorter
646
+ }
647
+
648
+ } else {
649
+ $valid = false;
650
+ set_site_transient( $key, 0, 5 * MINUTE_IN_SECONDS ); //cache network failure even shorter, we don't want a request every pageload
651
+ }
652
+
653
+ }
654
+
655
+ return (bool) $valid;
656
+ }
657
+
658
+ /**
659
+ * Returns api key
660
+ *
661
+ * @return mixed
662
+ */
663
+ private function _get_api_key() {
664
+ if ( defined( 'WPMUDEV_APIKEY' ) ) {
665
+ $api_key = WPMUDEV_APIKEY;
666
+ } else {
667
+ $api_key = get_site_option( 'wpmudev_apikey' );
668
+ }
669
+
670
+ return $api_key;
671
+ }
672
+
673
+
674
+ /**
675
+ * Checks if image is already smushed
676
+ *
677
+ * @param int $id
678
+ * @param array $data
679
+ *
680
+ * @return bool|mixed
681
+ */
682
+ function is_smushed( $id, $data = null ) {
683
+
684
+ //For new images
685
+ $wp_is_smushed = get_post_meta( $id, 'wp-is-smushed', true );
686
+
687
+ //Not smushed, backward compatibility, check attachment metadata
688
+ if ( ! $wp_is_smushed && $data !== null ) {
689
+ if ( isset( $data['wp_smushit'] ) && ! empty( $data['wp_smushit'] ) ) {
690
+ $wp_is_smushed = true;
691
+ }
692
+ }
693
+
694
+ return $wp_is_smushed;
695
+ }
696
+
697
+ /**
698
+ * Returns size saved from the api call response
699
+ *
700
+ * @param string $message
701
+ *
702
+ * @return string|bool
703
+ */
704
+ function get_saved_size( $message ) {
705
+ if ( preg_match( '/\((.*)\)/', $message, $matches ) ) {
706
+ return isset( $matches[1] ) ? $matches[1] : false;
707
+ }
708
+
709
+ return false;
710
+ }
711
+
712
+ /**
713
+ * Set send button status
714
+ *
715
+ * @param $id
716
+ * @param bool $echo
717
+ * @param bool $text_only
718
+ *
719
+ * @return string|void
720
+ */
721
+ function set_status( $id, $echo = true, $text_only = false ) {
722
+ $status_txt = $button_txt = '';
723
+ $show_button = false;
724
+ $wp_smush_data = get_post_meta( $id, self::SMUSHED_META_KEY, true );
725
+ // if the image is smushed
726
+ if ( ! empty( $wp_smush_data ) ) {
727
+
728
+ $bytes = isset( $wp_smush_data['stats']['bytes'] ) ? $wp_smush_data['stats']['bytes'] : 0;
729
+ $bytes_readable = ! empty( $bytes ) ? $this->format_bytes( $bytes ) : '';
730
+ $percent = isset( $wp_smush_data['stats']['percent'] ) ? $wp_smush_data['stats']['percent'] : 0;
731
+ $percent = $percent < 0 ? 0 : $percent;
732
+
733
+ if ( isset( $wp_smush_data['stats']['size_before'] ) && $wp_smush_data['stats']['size_before'] == 0 ) {
734
+ $status_txt = __( 'Error processing request', WP_SMUSH_DOMAIN );
735
+ $show_button = true;
736
+ } else {
737
+ if ( $bytes == 0 || $percent == 0 ) {
738
+ $status_txt = __( 'Already Optimized', WP_SMUSH_DOMAIN );
739
+ } elseif ( ! empty( $percent ) && ! empty( $bytes_readable ) ) {
740
+ $status_txt = sprintf( __( "Reduced by %s ( %01.1f%% )", WP_SMUSH_DOMAIN ), $bytes_readable, number_format_i18n( $percent, 2, '.', '' ) );
741
+ }
742
+ }
743
+
744
+ // the button text
745
+ $button_txt = __( 'Re-smush', WP_SMUSH_DOMAIN );
746
+ } else {
747
+
748
+ // the status
749
+ $status_txt = __( 'Not processed', WP_SMUSH_DOMAIN );
750
+
751
+ // we need to show the smush button
752
+ $show_button = true;
753
+
754
+ // the button text
755
+ $button_txt = __( 'Smush Now!', WP_SMUSH_DOMAIN );
756
+ }
757
+ if ( $text_only ) {
758
+ return $status_txt;
759
+ }
760
+
761
+ $text = $this->column_html( $id, $status_txt, $button_txt, $show_button, $wp_smush_data, $echo );
762
+ if ( ! $echo ) {
763
+ return $text;
764
+ }
765
+ }
766
+
767
+ /**
768
+ * Print the column html
769
+ *
770
+ * @param string $id Media id
771
+ * @param string $status_txt Status text
772
+ * @param string $button_txt Button label
773
+ * @param boolean $show_button Whether to shoe the button
774
+ *
775
+ * @return null
776
+ */
777
+ function column_html( $id, $status_txt = "", $button_txt = "", $show_button = true, $smushed = false, $echo = true ) {
778
+ $allowed_images = array( 'image/jpeg', 'image/jpg', 'image/png', 'image/gif' );
779
+ // don't proceed if attachment is not image, or if image is not a jpg, png or gif
780
+ if ( ! wp_attachment_is_image( $id ) || ! in_array( get_post_mime_type( $id ), $allowed_images ) ) {
781
+ return;
782
+ }
783
+ $html = '
784
+ <p class="smush-status">' . $status_txt . '</p>';
785
+ // if we aren't showing the button
786
+ if ( ! $show_button ) {
787
+ if ( $echo ) {
788
+ echo $html;
789
+
790
+ return;
791
+ } else {
792
+ if ( ! $smushed ) {
793
+ $class = ' currently-smushing';
794
+ } else {
795
+ $class = ' smushed';
796
+ }
797
+
798
+ return '<div class="smush-wrap' . $class . '">' . $html . '</div>';
799
+ }
800
+ }
801
+ if ( ! $echo ) {
802
+ $html .= '
803
+ <button class="button button-primary wp-smush-send" data-id="' . $id . '">
804
+ <span>' . $button_txt . '</span>
805
+ </button>';
806
+ if ( ! $smushed ) {
807
+ $class = ' unsmushed';
808
+ } else {
809
+ $class = ' smushed';
810
+ }
811
+
812
+ return '<div class="smush-wrap' . $class . '">' . $html . '</div>';
813
+ } else {
814
+ $html .= '<button class="button wp-smush-send" data-id="' . $id . '">
815
+ <span>' . $button_txt . '</span>
816
+ </button>';
817
+ echo $html;
818
+ }
819
+ }
820
+
821
+ /**
822
+ * Migrates smushit api message to the latest structure
823
+ *
824
+ *
825
+ * @return void
826
+ */
827
+ function migrate() {
828
+
829
+ if ( ! version_compare( $this->version, "1.7.1", "lte" ) ) {
830
+ return;
831
+ }
832
+
833
+ $migrated_version = get_option( self::MIGRATED_VERSION );
834
+
835
+ if ( $migrated_version === $this->version ) {
836
+ return;
837
+ }
838
+
839
+ global $wpdb;
840
+
841
+ $q = $wpdb->prepare( "SELECT * FROM `" . $wpdb->postmeta . "` WHERE `meta_key`=%s AND `meta_value` LIKE %s ", "_wp_attachment_metadata", "%wp_smushit%" );
842
+ $results = $wpdb->get_results( $q );
843
+
844
+ if ( count( $results ) < 1 ) {
845
+ return;
846
+ }
847
+
848
+ $migrator = new WpSmushMigrate();
849
+ foreach ( $results as $attachment_meta ) {
850
+ $migrated_message = $migrator->migrate_api_message( maybe_unserialize( $attachment_meta->meta_value ) );
851
+ if ( $migrated_message !== array() ) {
852
+ update_post_meta( $attachment_meta->post_id, self::SMUSHED_META_KEY, $migrated_message );
853
+ }
854
+ }
855
+
856
+ update_option( self::MIGRATED_VERSION, $this->version );
857
+
858
+ }
859
+
860
+ /**
861
+ * @param Object $response_data
862
+ * @param $size_before
863
+ * @param $size_after
864
+ * @param $total_time
865
+ * @param $bytes_saved
866
+ *
867
+ * @return array
868
+ */
869
+ private function _update_stats_data( $response_data, $size_before, $size_after, $total_time, $bytes_saved ) {
870
+ $size_before += ! empty( $response_data->before_size ) ? (int) $response_data->before_size : 0;
871
+ $size_after += ( ! empty( $response_data->after_size ) && $response_data->after_size > 0 ) ? (int) $response_data->after_size : (int) $response_data->before_size;
872
+ $total_time += ! empty( $response_data->time ) ? (float) $response_data->time : 0;
873
+ $bytes_saved += ( ! empty( $response_data->bytes_saved ) && $response_data->bytes_saved > 0 ) ? $response_data->bytes_saved : 0;
874
+ $compression = ( $bytes_saved > 0 && $size_before > 0 ) ? ( ( $bytes_saved / $size_before ) * 100 ) : 0;
875
+
876
+ return array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
877
+ }
878
+ }
879
+
880
+ global $WpSmush;
881
+ $WpSmush = new WpSmush();
882
+
883
+ }
884
+
885
+ //Include Admin classes
886
+ require_once( WP_SMUSH_DIR . '/lib/class-wp-smush-bulk.php' );
887
+ require_once( WP_SMUSH_DIR . '/lib/class-wp-smush-admin.php' );
888
+ //include_once( WP_SMUSH_DIR . '/extras/dash-notice/wpmudev-dash-notification.php' );
889
+
890
+ //register items for the dashboard plugin
891
+ global $wpmudev_notices;
892
+ $wpmudev_notices[] = array(
893
+ 'id' => 912164,
894
+ 'name' => 'WP Smush Pro',
895
+ 'screens' => array(
896
+ 'media_page_wp-smush-bulk',
897
+ 'upload'
898
+ )
899
+ );
wp-smushit.php CHANGED
@@ -1,515 +1,3 @@
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.7.1.1
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 ( ! function_exists( 'download_url' ) ) {
35
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
36
- }
37
-
38
- if ( ! class_exists( 'WpSmushit' ) ) {
39
-
40
- class WpSmushit {
41
-
42
- var $version = "1.7.1";
43
-
44
- /**
45
- * Constructor
46
- */
47
- function __construct() {
48
-
49
- /**
50
- * Constants
51
- */
52
- define( 'SMUSHIT_REQ_URL', 'http://www.smushit.com/ysmush.it/ws.php?img=%s' );
53
- define( 'SMUSHIT_BASE_URL', 'http://www.smushit.com/' );
54
-
55
- define( 'WP_SMUSHIT_DOMAIN', 'wp_smushit' );
56
- define( 'WP_SMUSHIT_UA', "WP Smush.it/{$this->version} (+http://wordpress.org/extend/plugins/wp-smushit/)" );
57
- define( 'WP_SMUSHIT_DIR', plugin_dir_path( __FILE__ ) );
58
- define( 'WP_SMUSHIT_URL', plugin_dir_url( __FILE__ ) );
59
- define( 'WP_SMUSHIT_MAX_BYTES', 1048576 );
60
-
61
- // The number of images (including generated sizes) that can return errors before abandoning all hope.
62
- // N.B. this doesn't work with the bulk uploader, since it creates a new HTTP request
63
- // for each image. It does work with the bulk smusher, though.
64
- define( 'WP_SMUSHIT_ERRORS_BEFORE_QUITTING', 3 * count( get_intermediate_image_sizes() ) );
65
-
66
- define( 'WP_SMUSHIT_AUTO', intval( get_option( 'wp_smushit_smushit_auto', 0 ) ) );
67
- define( 'WP_SMUSHIT_TIMEOUT', intval( get_option( 'wp_smushit_smushit_timeout', 60 ) ) );
68
- define( 'WP_SMUSHIT_ENFORCE_SAME_URL', get_option( 'wp_smushit_smushit_enforce_same_url', 'on' ) );
69
-
70
- define( 'WP_SMUSHIT_DEBUG', get_option( 'wp_smushit_smushit_debug', '' ) );
71
-
72
- /*
73
- Each service has a setting specifying whether it should be used automatically on upload.
74
- Values are:
75
- -1 Don't use (until manually enabled via Media > Settings)
76
- 0 Use automatically
77
- n Any other number is a Unix timestamp indicating when the service can be used again
78
- */
79
-
80
- define( 'WP_SMUSHIT_AUTO_OK', 0 );
81
- define( 'WP_SMUSHIT_AUTO_NEVER', - 1 );
82
-
83
- /**
84
- * Hooks
85
- */
86
- if ( WP_SMUSHIT_AUTO == WP_SMUSHIT_AUTO_OK ) {
87
- // add_filter( 'wp_generate_attachment_metadata', array( &$this, 'resize_from_meta_data' ), 10, 2 );
88
- }
89
- add_filter( 'manage_media_columns', array( &$this, 'columns' ) );
90
- add_action( 'manage_media_custom_column', array( &$this, 'custom_column' ), 10, 2 );
91
- add_action( 'admin_init', array( &$this, 'admin_init' ) );
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
- }
96
-
97
- function WpSmushit() {
98
- $this->__construct();
99
- }
100
-
101
- function settings_cb() {
102
- }
103
-
104
- function admin_init() {
105
- load_plugin_textdomain( WP_SMUSHIT_DOMAIN, false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
106
- wp_enqueue_script( 'common' );
107
- }
108
-
109
- /**
110
- * Manually process an image from the Media Library
111
- */
112
- function smushit_manual() {
113
- if ( ! current_user_can( 'upload_files' ) ) {
114
- wp_die( __( "You don't have permission to work with uploaded files.", WP_SMUSHIT_DOMAIN ) );
115
- }
116
-
117
- if ( ! isset( $_GET['attachment_ID'] ) ) {
118
- wp_die( __( 'No attachment ID was provided.', WP_SMUSHIT_DOMAIN ) );
119
- }
120
-
121
- $attachment_ID = intval( $_GET['attachment_ID'] );
122
-
123
- $original_meta = wp_get_attachment_metadata( $attachment_ID );
124
-
125
- $new_meta = $this->resize_from_meta_data( $original_meta, $attachment_ID );
126
- wp_update_attachment_metadata( $attachment_ID, $new_meta );
127
-
128
- wp_redirect( preg_replace( '|[^a-z0-9-~+_.?#=&;,/:]|i', '', wp_get_referer() ) );
129
- exit();
130
- }
131
-
132
- /**
133
- * Process an image with Smush.it.
134
- *
135
- * Returns an array of the $file $results.
136
- *
137
- * @param string $file Full absolute path to the image file
138
- * @param string $file_url Optional full URL to the image file
139
- *
140
- * @returns array
141
- */
142
- function do_smushit( $attachment_id, $file_path = '', $file_url = '' ) {
143
- global $log;
144
- //API calls disabled until new Smush comes back
145
- return __( "Smush service currently unavailable", WP_SMUSHIT_DOMAIN);
146
-
147
- if ( empty( $file_path ) ) {
148
- return __( "File path is empty", WP_SMUSHIT_DOMAIN );
149
- }
150
-
151
- if ( empty( $file_url ) ) {
152
- return __( "File URL is empty", WP_SMUSHIT_DOMAIN );
153
- }
154
-
155
- static $error_count = 0;
156
-
157
- if ( $error_count >= WP_SMUSHIT_ERRORS_BEFORE_QUITTING ) {
158
- return __( "Did not Smush.it due to previous errors", WP_SMUSHIT_DOMAIN );
159
- }
160
-
161
- // check that the file exists
162
- if ( ! file_exists( $file_path ) || ! is_file( $file_path ) ) {
163
- return sprintf( __( "ERROR: Could not find <span class='code'>%s</span>", WP_SMUSHIT_DOMAIN ), $file_path );
164
- }
165
-
166
- // check that the file is writable
167
- if ( ! is_writable( dirname( $file_path ) ) ) {
168
- return sprintf( __( "ERROR: <span class='code'>%s</span> is not writable", WP_SMUSHIT_DOMAIN ), dirname( $file_path ) );
169
- }
170
-
171
- $file_size = filesize( $file_path );
172
- if ( $file_size > WP_SMUSHIT_MAX_BYTES ) {
173
- return sprintf( __( 'ERROR: <span style="color:#FF0000;">Skipped (%s) Unable to Smush due to Yahoo 1mb size limits. See <a href="http://developer.yahoo.com/yslow/smushit/faq.html#faq_restrict">FAQ</a></span>', WP_SMUSHIT_DOMAIN ), $this->format_bytes( $file_size ) );
174
- }
175
-
176
- // local file check disabled 2013-09-05 - I don't see a point in checking this. We only use the URL of the file to Yahoo! and there is no gaurentee
177
- // the file path is the SAME as the image from the URL. We can only really make sure the image URL starts with the home URL. This should prevent CDN URLs
178
- // from being processed.
179
- // check that the file is within the WP_CONTENT_DIR
180
- // But first convert the slashes to be uniform. Really with WP would already do this!
181
- /*
182
- $file_path_tmp = str_replace('\\', '/', $file_path);
183
- $WP_CONTENT_DIR_tmp = str_replace('\\', '/', WP_CONTENT_DIR);
184
-
185
- if (WP_SMUSHIT_DEBUG) {
186
- echo "DEBUG: file_path [". $file_path_tmp ."] WP_CONTENT_DIR [". $WP_CONTENT_DIR_tmp ."]<br />";
187
- }
188
- if (stripos( $file_path_tmp, $WP_CONTENT_DIR_tmp) !== 0) {
189
- return sprintf( __( "ERROR: <span class='code'>%s</span> must be within the website content directory (<span class='code'>%s</span>)", WP_SMUSHIT_DOMAIN ),
190
- htmlentities( $file_path_tmp ), $WP_CONTENT_DIR_tmp);
191
- }
192
- }
193
- */
194
- // The Yahoo! Smush.it service does not working with https images.
195
- $file_url = str_replace( 'https://', 'http://', $file_url );
196
-
197
- // File URL check disabled 2013-10-11 - The assumption here is the URL may not be the local site URL. The image may be served via a sub-domain pointed
198
- // to this same host or may be an external CDN. In either case the image would be the same. So we let the Yahoo! Smush.it service use the image URL with
199
- // the assumption the remote image and the local file are the same. Also with the assumption that the CDN service will somehow be updated when the image
200
- // is changed.
201
- if ( ( defined( 'WP_SMUSHIT_ENFORCE_SAME_URL' ) ) && ( WP_SMUSHIT_ENFORCE_SAME_URL == 'on' ) ) {
202
- $home_url = str_replace( 'https://', 'http://', get_option( 'home' ) );
203
- $error_message = "<b>Home URL: </b>" . $home_url . " <br />";
204
-
205
- if ( stripos( $file_url, $home_url ) !== 0 ) {
206
- return sprintf( __( "ERROR: <span class='code'>%s</span> must be within the website home URL (<span class='code'>%s</span>)", WP_SMUSHIT_DOMAIN ),
207
- htmlentities( $file_url ), $home_url );
208
- }
209
- }
210
-
211
- //echo "calling _post(". $file_url .")<br />";
212
- $data = $this->_post( $attachment_id, $file_url );
213
-
214
- //echo "returned from _post data<pre>"; print_r($data); echo "</pre>";
215
-
216
- if ( false === $data ) {
217
- $error_count ++;
218
-
219
- return __( 'ERROR: posting to Smush.it', WP_SMUSHIT_DOMAIN );
220
- }
221
-
222
- // make sure the response looks like JSON -- added 2008-12-19 when
223
- // Smush.it was returning PHP warnings before the JSON output
224
- if ( strpos( trim( $data ), '{' ) != 0 ) {
225
- return __( 'Bad response from Smush.it', WP_SMUSHIT_DOMAIN );
226
- }
227
- $string_data = http_build_query( json_decode( $data, true ), '', '<br />' );
228
- $string_data = urldecode( $string_data );
229
-
230
- //Log data for debugging purpose
231
- $error_message .= "<b>Return from API:</b> <br />$string_data";
232
- if ( WP_SMUSHIT_DEBUG ) {
233
- $log->error(
234
- "do_smushit",
235
- array(
236
- "Attachment id" => "<b>Attachment id: </b>" . $attachment_id,
237
- "File URL" => "<b>File URL: </b>" . $file_url,
238
- "File Path" => "<b>File Path: </b>" . $file_path
239
- ),
240
- $error_message );
241
- }
242
- // read the JSON response
243
- if ( function_exists( 'json_decode' ) ) {
244
- $data = json_decode( $data );
245
- } else {
246
- require_once( 'JSON/JSON.php' );
247
- $json = new Services_JSON();
248
- $data = $json->decode( $data );
249
- }
250
-
251
- //echo "returned from _post data<pre>"; print_r($data); echo "</pre>";
252
-
253
- if ( ! isset( $data->dest_size ) ) {
254
- return __( 'Bad response from Smush.it', WP_SMUSHIT_DOMAIN );
255
- }
256
-
257
- if ( - 1 === intval( $data->dest_size ) ) {
258
- return __( 'No savings', WP_SMUSHIT_DOMAIN );
259
- }
260
-
261
- if ( ! isset( $data->dest ) ) {
262
- $err = ( $data->error ? __( 'Smush.it error: ', WP_SMUSHIT_DOMAIN ) . $data->error : __( 'unknown error', WP_SMUSHIT_DOMAIN ) );
263
- $err .= sprintf( __( " while processing <span class='code'>%s</span> (<span class='code'>%s</span>)", WP_SMUSHIT_DOMAIN ), $file_url, $file_path );
264
-
265
- return $err;
266
- }
267
-
268
- $processed_url = $data->dest;
269
-
270
- // The smush.it web service does not append the domain;
271
- // smushit.com web service does
272
- if ( 0 !== stripos( $processed_url, 'http://' ) ) {
273
- $processed_url = SMUSHIT_BASE_URL . $processed_url;
274
- }
275
-
276
- $temp_file = download_url( $processed_url );
277
-
278
- if ( is_wp_error( $temp_file ) ) {
279
- @unlink( $temp_file );
280
-
281
- return sprintf( __( "Error downloading file (%s)", WP_SMUSHIT_DOMAIN ), $temp_file->get_error_message() );
282
- }
283
-
284
- if ( ! file_exists( $temp_file ) ) {
285
- return sprintf( __( "Unable to locate Smushed file (%s)", WP_SMUSHIT_DOMAIN ), $temp_file );
286
- }
287
-
288
- @unlink( $file_path );
289
- $success = @rename( $temp_file, $file_path );
290
- if ( ! $success ) {
291
- copy( $temp_file, $file_path );
292
- unlink( $temp_file );
293
- }
294
-
295
- $savings = intval( $data->src_size ) - intval( $data->dest_size );
296
- $savings_str = $this->format_bytes( $savings, 1 );
297
- $savings_str = str_replace( ' ', '&nbsp;', $savings_str );
298
-
299
- $results_msg = sprintf( __( "Reduced by %01.1f%% (%s)", WP_SMUSHIT_DOMAIN ),
300
- $data->percent,
301
- $savings_str );
302
-
303
- return $results_msg;
304
- }
305
-
306
- function should_resmush( $previous_status ) {
307
- if ( ! $previous_status || empty( $previous_status ) ) {
308
- return true;
309
- }
310
-
311
- if ( stripos( $previous_status, 'no savings' ) !== false || stripos( $previous_status, 'reduced' ) !== false ) {
312
- return false;
313
- }
314
-
315
- // otherwise an error
316
- return true;
317
- }
318
-
319
-
320
- /**
321
- * Read the image paths from an attachment's meta data and process each image
322
- * with wp_smushit().
323
- *
324
- * This method also adds a `wp_smushit` meta key for use in the media library.
325
- *
326
- * Called after `wp_generate_attachment_metadata` is completed.
327
- */
328
- function resize_from_meta_data( $meta, $ID = null, $force_resmush = true ) {
329
- global $log;
330
- if ( $ID && wp_attachment_is_image( $ID ) === false ) {
331
- return $meta;
332
- }
333
-
334
- $attachment_file_path = get_attached_file( $ID );
335
- $attachment_file_url = wp_get_attachment_url( $ID );
336
-
337
- if ( $force_resmush || $this->should_resmush( @$meta['wp_smushit'] ) ) {
338
- $meta['wp_smushit'] = $this->do_smushit( $ID, $attachment_file_path, $attachment_file_url );
339
- }
340
-
341
- // no resized versions, so we can exit
342
- if ( ! isset( $meta['sizes'] ) ) {
343
- return $meta;
344
- }
345
- foreach ( $meta['sizes'] as $size_key => $size_data ) {
346
- if ( ! $force_resmush && $this->should_resmush( @$meta['sizes'][ $size_key ]['wp_smushit'] ) === false ) {
347
- continue;
348
- }
349
-
350
- // We take the original image. The 'sizes' will all match the same URL and
351
- // path. So just get the dirname and rpelace the filename.
352
- $attachment_file_path_size = trailingslashit( dirname( $attachment_file_path ) ) . $size_data['file'];
353
-
354
- $attachment_file_url_size = trailingslashit( dirname( $attachment_file_url ) ) . $size_data['file'];
355
-
356
- $meta['sizes'][ $size_key ]['wp_smushit'] = $this->do_smushit( $ID, $attachment_file_path_size, $attachment_file_url_size );
357
-
358
- //echo "size_key[". $size_key ."] wp_smushit<pre>"; print_r($meta['sizes'][$size_key]['wp_smushit']); echo "</pre>";
359
- }
360
-
361
- //echo "meta<pre>"; print_r($meta); echo "</pre>";
362
- return $meta;
363
- }
364
-
365
- /**
366
- * Post an image to Smush.it.
367
- *
368
- * @param string $file_url URL of the file to send to Smush.it
369
- *
370
- * @return string|boolean Returns the JSON response on success or else false
371
- */
372
- function _post( $id, $file_url ) {
373
- global $log;
374
- $req = sprintf( SMUSHIT_REQ_URL, urlencode( $file_url ) );
375
-
376
- $data = false;
377
- if ( WP_SMUSHIT_DEBUG ) {
378
- $debug = "<b>Calling API: </b>[" . $req . "]<br />";
379
- $log->error( '_post', array(
380
- ' attachment_id' => "<b>Attachment id: </b>" . $id,
381
- 'file_url' => "<b>File URL: </b>" . $file_url
382
- ), $debug );
383
- }
384
- if ( function_exists( 'wp_remote_get' ) ) {
385
- $response = wp_remote_get( $req, array(
386
- 'user-agent' => WP_SMUSHIT_UA,
387
- 'timeout' => WP_SMUSHIT_TIMEOUT
388
- ) );
389
- if ( ! $response || is_wp_error( $response ) ) {
390
- $data = false;
391
- } else {
392
- $data = wp_remote_retrieve_body( $response );
393
- }
394
- } else {
395
- wp_die( __( 'WP Smush.it requires WordPress 2.8 or greater', WP_SMUSHIT_DOMAIN ) );
396
- }
397
-
398
- return $data;
399
- }
400
-
401
-
402
- /**
403
- * Print column header for Smush.it results in the media library using
404
- * the `manage_media_columns` hook.
405
- */
406
- function columns( $defaults ) {
407
- $defaults['smushit'] = 'Smush.it';
408
-
409
- return $defaults;
410
- }
411
-
412
- /**
413
- * Return the filesize in a humanly readable format.
414
- * Taken from http://www.php.net/manual/en/function.filesize.php#91477
415
- */
416
- function format_bytes( $bytes, $precision = 2 ) {
417
- $units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
418
- $bytes = max( $bytes, 0 );
419
- $pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
420
- $pow = min( $pow, count( $units ) - 1 );
421
- $bytes /= pow( 1024, $pow );
422
-
423
- return round( $bytes, $precision ) . ' ' . $units[ $pow ];
424
- }
425
-
426
- /**
427
- * Print column data for Smush.it results in the media library using
428
- * the `manage_media_custom_column` hook.
429
- */
430
- function custom_column( $column_name, $id ) {
431
- if ( 'smushit' == $column_name ) {
432
- $data = wp_get_attachment_metadata( $id );
433
- if ( isset( $data['wp_smushit'] ) && ! empty( $data['wp_smushit'] ) ) {
434
- print $data['wp_smushit'];
435
- printf( "<br><a href=\"admin.php?action=wp_smushit_manual&amp;attachment_ID=%d\">%s</a>",
436
- $id,
437
- __( 'Re-smush', WP_SMUSHIT_DOMAIN ) );
438
- } else {
439
- if ( wp_attachment_is_image( $id ) ) {
440
- print __( 'Not processed', WP_SMUSHIT_DOMAIN );
441
- printf( "<br><a href=\"admin.php?action=wp_smushit_manual&amp;attachment_ID=%d\">%s</a>",
442
- $id,
443
- __( 'Smush.it now!', WP_SMUSHIT_DOMAIN ) );
444
- }
445
- }
446
- }
447
- }
448
-
449
-
450
- // Borrowed from http://www.viper007bond.com/wordpress-plugins/regenerate-thumbnails/
451
- function add_bulk_actions_via_javascript() {
452
- ?>
453
- <script type="text/javascript">
454
- jQuery(document).ready(function ($) {
455
- $('select[name^="action"] option:last-child').before('<option value="bulk_smushit">Bulk Smush.it</option>');
456
- });
457
- </script>
458
- <?php
459
- }
460
-
461
-
462
- // Handles the bulk actions POST
463
- // Borrowed from http://www.viper007bond.com/wordpress-plugins/regenerate-thumbnails/
464
- function bulk_action_handler() {
465
- check_admin_referer( 'bulk-media' );
466
-
467
- if ( empty( $_REQUEST['media'] ) || ! is_array( $_REQUEST['media'] ) ) {
468
- return;
469
- }
470
-
471
- $ids = implode( ',', array_map( 'intval', $_REQUEST['media'] ) );
472
-
473
- // Can't use wp_nonce_url() as it escapes HTML entities
474
- $url = admin_url( 'upload.php' );
475
- $url = add_query_arg(
476
- array(
477
- 'page' => 'wp-smushit-bulk',
478
- 'goback' => 1,
479
- 'ids' => $ids,
480
- '_wpnonce' => wp_create_nonce( 'wp-smushit-bulk' )
481
- ),
482
- $url
483
- );
484
- wp_redirect( $url );
485
- exit();
486
- }
487
-
488
- // default is 6hrs
489
- function temporarily_disable( $seconds = 21600 ) {
490
- update_option( 'wp_smushit_smushit_auto', time() + $seconds );
491
- }
492
-
493
- }
494
-
495
- $WpSmushit = new WpSmushit();
496
- global $WpSmushit;
497
-
498
- }
499
- //Include Admin class
500
- require_once( WP_SMUSHIT_DIR . '/lib/class-wp-smushit-bulk.php' );
501
- require_once( WP_SMUSHIT_DIR . '/lib/class-wp-smushit-admin.php' );
502
- /**
503
- * Error Log
504
- */
505
- require_once( WP_SMUSHIT_DIR . '/lib/error/class-wp-smushit-errorlog.php' );
506
- require_once( WP_SMUSHIT_DIR . '/lib/error/class-wp-smushit-errorregistry.php' );
507
-
508
- if ( ! function_exists( 'wp_basename' ) ) {
509
- /**
510
- * Introduced in WP 3.1... this is copied verbatim from wp-includes/formatting.php.
511
- */
512
- function wp_basename( $path, $suffix = '' ) {
513
- return urldecode( basename( str_replace( '%2F', '/', urlencode( $path ) ), $suffix ) );
514
- }
515
- }
1
  <?php
2
+ /* simply for backwards compatibility with old installs that have this filename activated */
3
+ require_once( 'wp-smush.php' );