Smush Image Compression and Optimization - Version 2.0.6.3

Version Description

  • Fixed: Change File permission after replacing image
  • Fixed: Directory path for files
  • Fixed: Workaround for Auto Smush issue on Hostgator
  • Fixed: Smush button doesn't works in media library dialog on post screen, when add media is clicked (https://wordpress.org/support/topic/like-wp-smush-a-lot)
  • New: Show number of images smushed in stats column
  • Added: Support for WP Retina 2x Plugin
  • Added: Filter WP_SMUSH_API_TIMEOUT to change the default time out value from 60s
  • Added: Smush original image option (Pro Only)
Download this release

Release Info

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

Code changes from version 2.0.6 to 2.0.6.3

assets/css/wp-smushit-admin.css CHANGED
@@ -258,6 +258,7 @@ Progressbar ui
258
  overflow: hidden;
259
  position: relative;
260
  }
 
261
  #progress-ui #wp-smush-ss-progress-wrap {
262
  /*background-color: #2ea2cc;*/
263
  }
@@ -376,8 +377,21 @@ button .wp-smush-loader-wrap {
376
  padding: 5px 5px 5px 0;
377
  }
378
 
 
 
 
 
 
 
 
 
 
379
  .wp-smush-pro-features {
 
380
  display: inline-block;
 
 
 
381
  }
382
 
383
  input#wp-smush-save-settings {
@@ -426,6 +440,25 @@ input#wp-smush-save-settings {
426
  content: "";
427
  }
428
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
  /** Grid view button **/
430
  .smush-wrap {
431
  margin-left: 14%;
@@ -474,6 +507,7 @@ input#wp-smush-save-settings {
474
  #post-body-content .wp-smush-send {
475
  margin: 4px 0 0;
476
  }
 
477
  #post-body-content .smush-status {
478
  margin: 4px 0;
479
  }
@@ -535,4 +569,48 @@ input#wp-smush-save-settings {
535
 
536
  .inactive-anim {
537
  transition: opacity .3s;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
538
  }
258
  overflow: hidden;
259
  position: relative;
260
  }
261
+
262
  #progress-ui #wp-smush-ss-progress-wrap {
263
  /*background-color: #2ea2cc;*/
264
  }
377
  padding: 5px 5px 5px 0;
378
  }
379
 
380
+ /*Pro rows*/
381
+ #wp-smush-options-wrap .wp-smush-pro-features .wp-smush-setting-row {
382
+ margin: 5px 20px 5px 25px;
383
+ }
384
+
385
+ #wp-smush-options-wrap .wp-smush-pro-features .pro-note {
386
+ margin: 0 0 0 25px;
387
+ }
388
+
389
  .wp-smush-pro-features {
390
+ border: 1px solid lightgray;
391
  display: inline-block;
392
+ padding: 0 0 10px 0;
393
+ margin: 10px 0 0;
394
+ width: 85%;
395
  }
396
 
397
  input#wp-smush-save-settings {
440
  content: "";
441
  }
442
 
443
+ .wp-smush-pro-features legend {
444
+ margin-left: 15px;
445
+ padding: 0 10px;
446
+ }
447
+
448
+ .pro-note .dashicons-info {
449
+ color: gray;
450
+ margin: 0 5px 0 0;
451
+ }
452
+
453
+ .pro-note .find-out-link {
454
+ margin: -5px 0 0 10px;
455
+ }
456
+
457
+ .wp-smush-setting-row.disabled label, .wp-smush-setting-row.disabled input {
458
+ color: gray;
459
+ cursor: default;
460
+ }
461
+
462
  /** Grid view button **/
463
  .smush-wrap {
464
  margin-left: 14%;
507
  #post-body-content .wp-smush-send {
508
  margin: 4px 0 0;
509
  }
510
+
511
  #post-body-content .smush-status {
512
  margin: 4px 0;
513
  }
569
 
570
  .inactive-anim {
571
  transition: opacity .3s;
572
+ }
573
+
574
+ .smush-stats-wrapper {
575
+ border: 1px solid lightgray;
576
+ }
577
+ table.wp-smush-stats-holder {
578
+ border-collapse: collapse;
579
+ width: 100%;
580
+ }
581
+ table.wp-smush-stats-holder th {
582
+ background-color: #E4E4E4;
583
+ }
584
+ table.wp-smush-stats-holder td, table.wp-smush-stats-holder th {
585
+ border: 1px solid #CECECE;
586
+ }
587
+ table.wp-smush-stats-holder tr:first-child th {
588
+ border-top: 0;
589
+ }
590
+ table.wp-smush-stats-holder tr:last-child td {
591
+ border-bottom: 0;
592
+ }
593
+ table.wp-smush-stats-holder tr td:first-child,
594
+ table.wp-smush-stats-holder tr th:first-child {
595
+ border-left: 0;
596
+ }
597
+ table.wp-smush-stats-holder tr td:last-child,
598
+ table.wp-smush-stats-holder tr th:last-child {
599
+ border-right: 0;
600
+ }
601
+ table.wp-smush-stats-holder tr td:first-child {
602
+ text-align: right;
603
+ }
604
+ .smush-skipped.error {
605
+ color: #C41921;
606
+ }
607
+ .smush-skipped .dashicons-editor-help {
608
+ cursor: pointer;
609
+ }
610
+ /*Media Modal Styling*/
611
+ .compat-field-wp_smush .wp-smush-stats-holder tr {
612
+ display: table-row;
613
+ }
614
+ .compat-field-wp_smush .wp-smush-stats-holder td {
615
+ padding: 8px 10px
616
  }
assets/js/wp-smushit-admin.js CHANGED
@@ -2,40 +2,41 @@
2
  * Processes bulk smushing
3
  *
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;
@@ -171,15 +172,15 @@ jQuery(function ($) {
171
  };
172
 
173
  this.update_progress = function (stats) {
174
- if( !this.is_bulk_super_smush ) {
175
  //handle progress for normal bulk smush
176
  var progress = ( stats.data.smushed / stats.data.total) * 100;
177
- }else{
178
  //Handle progress for Super smush progress bar
179
- if( wp_smushit_data.lossless.length > 0 ) {
180
  $('#wp-smush-ss-progress-wrap .remaining-count').html(wp_smushit_data.lossless.length);
181
- }else if( wp_smushit_data.lossless.length == 0 ){
182
- $('#wp-smush-ss-progress-wrap #wp-smush-compression').html( wp_smush_msgs.all_supersmushed );
183
  }
184
 
185
  }
@@ -194,11 +195,11 @@ jQuery(function ($) {
194
 
195
  this._update_progress = function (count, width) {
196
  "use strict";
197
- if( !this.is_bulk ) {
198
  return;
199
  }
200
 
201
- if( !this.is_bulk_super_smush ) {
202
  // get the progress bar
203
  var $progress_bar = jQuery('#wp-smush-progress-wrap #wp-smush-fetched-progress div');
204
  if ($progress_bar.length < 1) {
@@ -207,9 +208,9 @@ jQuery(function ($) {
207
  $('.done-count').html(count);
208
  // increase progress
209
  $progress_bar.css('width', width + '%');
210
- }else{
211
 
212
- if( this.lossless_count > 0 ) {
213
  var remaining_lossless = this.lossless_count - wp_smushit_data.lossless.length;
214
  var progress_width = ( remaining_lossless / this.lossless_count * 100 );
215
  var $progress_bar = jQuery('#wp-smush-ss-progress-wrap #wp-smush-ss-progress div');
@@ -322,6 +323,20 @@ jQuery(function ($) {
322
  return;
323
  });
324
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  //Handle smush button click
326
  $('body').on('click', '.wp-smush-send', function (e) {
327
 
@@ -329,6 +344,8 @@ jQuery(function ($) {
329
  e.preventDefault();
330
  new WP_Smush.Smush($(this), false);
331
  });
 
 
332
 
333
  });
334
  (function ($) {
2
  * Processes bulk smushing
3
  *
4
  * @author Saurabh Shukla <saurabh@incsub.com>
5
+ * @author Umesh Kumar
6
  *
7
  */
8
  var WP_Smush = WP_Smush || {};
9
  jQuery(function ($) {
10
+ // url for smushing
11
+ WP_Smush.errors = [];
12
+ WP_Smush.timeout = wp_smushit_data.timeout;
13
+ /**
14
+ * Checks for the specified param in URL
15
+ * @param sParam
16
+ * @returns {*}
17
+ */
18
+ WP_Smush.geturlparam = function (arg) {
19
+ var $sPageURL = window.location.search.substring(1);
20
+ var $sURLVariables = $sPageURL.split('&');
21
+
22
+ for (var i = 0; i < $sURLVariables.length; i++) {
23
+ var $sParameterName = $sURLVariables[i].split('=');
24
+ if ($sParameterName[0] == arg) {
25
+ return $sParameterName[1];
26
+ }
27
+ }
28
+ };
29
+
30
+ WP_Smush.ajax = function ($id, $send_url, $getnxt) {
31
+ "use strict";
32
+ return $.ajax({
33
+ type: "GET",
34
+ data: {attachment_id: $id, get_next: $getnxt},
35
+ url: $send_url,
36
+ timeout: WP_Smush.timeout,
37
+ dataType: 'json'
38
+ });
39
+ };
40
 
41
  WP_Smush.Smush = function ($button, bulk) {
42
  var self = this;
172
  };
173
 
174
  this.update_progress = function (stats) {
175
+ if (!this.is_bulk_super_smush) {
176
  //handle progress for normal bulk smush
177
  var progress = ( stats.data.smushed / stats.data.total) * 100;
178
+ } else {
179
  //Handle progress for Super smush progress bar
180
+ if (wp_smushit_data.lossless.length > 0) {
181
  $('#wp-smush-ss-progress-wrap .remaining-count').html(wp_smushit_data.lossless.length);
182
+ } else if (wp_smushit_data.lossless.length == 0) {
183
+ $('#wp-smush-ss-progress-wrap #wp-smush-compression').html(wp_smush_msgs.all_supersmushed);
184
  }
185
 
186
  }
195
 
196
  this._update_progress = function (count, width) {
197
  "use strict";
198
+ if (!this.is_bulk) {
199
  return;
200
  }
201
 
202
+ if (!this.is_bulk_super_smush) {
203
  // get the progress bar
204
  var $progress_bar = jQuery('#wp-smush-progress-wrap #wp-smush-fetched-progress div');
205
  if ($progress_bar.length < 1) {
208
  $('.done-count').html(count);
209
  // increase progress
210
  $progress_bar.css('width', width + '%');
211
+ } else {
212
 
213
+ if (this.lossless_count > 0) {
214
  var remaining_lossless = this.lossless_count - wp_smushit_data.lossless.length;
215
  var progress_width = ( remaining_lossless / this.lossless_count * 100 );
216
  var $progress_bar = jQuery('#wp-smush-ss-progress-wrap #wp-smush-ss-progress div');
323
  return;
324
  });
325
 
326
+ /**
327
+ * Handle the Smush Stats link click
328
+ */
329
+ $('body').on('click', 'a.smush-stats-details', function (e) {
330
+
331
+ // prevent the default action
332
+ e.preventDefault();
333
+ var slide_symbol = $(this).find('.stats-toggle');
334
+ $(this).parents().eq(1).find('.smush-stats-wrapper').slideToggle();
335
+ slide_symbol.text(slide_symbol.text() == '+' ? '-' : '+');
336
+
337
+ return;
338
+ });
339
+
340
  //Handle smush button click
341
  $('body').on('click', '.wp-smush-send', function (e) {
342
 
344
  e.preventDefault();
345
  new WP_Smush.Smush($(this), false);
346
  });
347
+ //Stats Button Click
348
+
349
 
350
  });
351
  (function ($) {
extras/free-dashboard/admin.css ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * CSS styles used by the WDev-Frash module.
3
+ */
4
+
5
+ .wrap .frash-notice.notice {
6
+ padding: 0;
7
+ margin: 5px 0 10px;
8
+ border: 1px solid #E5E5E5;
9
+ background: #FFF;
10
+ overflow: hidden;
11
+ -webkit-border-radius: 6px;
12
+ border-radius: 6px;
13
+ -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
14
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
15
+ position: relative;
16
+ z-index: 1;
17
+ min-height: 80px;
18
+ display: table; /* The magic ingredient! */
19
+ font: 13px "Open Sans", sans-serif;
20
+ }
21
+
22
+ .wrap .frash-notice.notice.loading:before {
23
+ content: attr(data-message);
24
+ position: absolute;
25
+ left: 0;
26
+ right: 0;
27
+ top: 0;
28
+ bottom: 0;
29
+ background-color: rgba(255, 255, 255, 0.7);
30
+ z-index: 5;
31
+ text-align: center;
32
+ line-height: 80px;
33
+ font-size: 22px;
34
+ font-weight: bold;
35
+ }
36
+
37
+ .frash-notice > div {
38
+ display: table-cell; /* The magic ingredient! */
39
+ vertical-align: middle;
40
+ cursor: default;
41
+ }
42
+
43
+ .frash-notice.notice.loading > div {
44
+ -webkit-filter: blur(2px);
45
+ -moz-filter: blur(2px);
46
+ -o-filter: blur(2px);
47
+ -ms-filter: blur(2px);
48
+ filter: blur(2px);
49
+ }
50
+
51
+ .frash-notice-logo {
52
+ background-color: #0B2F3F;
53
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAABNGlDQ1BJQ0MgUHJvZmlsZQAAKJFjYGBSSSwoyGESYGDIzSspCnJ3UoiIjFJgv8/AwcDNIMYgyKCWmFxc4BgQ4MOAE3y7xsAIoi/rgszCrQ4r4EpJLU4G0n+AOC65oKiEgYExBshWLi8pALEbgGyRpGwwewqIXQR0IJC9AsROh7D3gNVA2BfAakKCnIHsJ0C2QxISOx2JDbUXBJiTjUh0NRGgJLWiBEQ75xdUFmWmZ5QoOAJDJ1XBMy9ZT0fByMDQlIEBFNYQ1YgwRIgxiwGxMQMD0xKEWP4iBgaLr0DxCQixpJkMDNtbGRgkbiHEVBYwMPC3MDBsO59cWlQGdZIUEJ9mPMmczDqJI5v7m4C9aKC0ieJHzQlGEtaT3FgDy2PfZhdUsXZunFWzJnN/7eXDLw3+/wcAZQZcDK/8PeoAAAAJcEhZcwAACxMAAAsTAQCanBgAAAQkaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA1LjQuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpDb21wcmVzc2lvbj41PC90aWZmOkNvbXByZXNzaW9uPgogICAgICAgICA8dGlmZjpYUmVzb2x1dGlvbj43MjwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzI8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj44MDwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+ODA8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZGM6c3ViamVjdD4KICAgICAgICAgICAgPHJkZjpCYWcvPgogICAgICAgICA8L2RjOnN1YmplY3Q+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE1LTA4LTExVDIyOjA4OjU5PC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5QaXhlbG1hdG9yIDMuMy4yPC94bXA6Q3JlYXRvclRvb2w+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgrYxXXjAAAONElEQVR4Ae1be3AV1Rn/zu595HETCIEkYEIIbwg+OlF5WYva6iAjApXIoJ2Kdvrw0fpC/yhaxlYtgjg+pjM6Yzv1wdjQ1lYqjsVKxAe+BRUV5A0JJIQk5J3cu3v6+/ZmL/fe7N7cu7kBnNnDhN09e77vfOe333e+73znXCK3OEJgzpw5HkeELpGLgIuAi4CLgIuAi4CLgIuAi4CLgIuAi4CLwHccAXGmyT/x6Y+Hh/JGZeleoRBl9IrXRUpQ6p6m2o5dvzi/4UyS+bQDOPalPRN14a0Q5KnQFTlJ6PoUCJUtSQohw1BJQ0rjqV0qytcKiZ1Sl58oUn6yd0nxrtMJ6GkBsGzd3kKp+K8kj3o1acGLhFDyhQfZIV3Dn05SSmLBevEz7g2QBGoVKKaikgwFud1xUr3vkNT+LYKejfuWFtadajBPKYBjquqLpNCuF1LeqAiaQgBEaqEwcCmPPAymUAE8ANclfS2F+meRJV7YP6/gaMrsHBKcEgDHb5T+YHvdT4TU74QCTeHRSi3oUGRrMqF6iT+ILuXXQqhr1ezC53dfKbqtW6evdtABHPti/QTdH3oEc9sCwRoH0xvMwkDi8+CfeCVE6orDlUVfDGZ/6mAyL/nHsfkkgs+pQp2Fuc6hqaYoodRBIDFNeibhcy0YsmR58x1TA9urq6vNKTVFhombD4oGVjz9tLdp6Ly7IfH9QhEZg611dkPk+ZGnR10oDweo6YEdleU9dm2d1qcdwPKVVb72KbMfQAxyL0tveFan0qWDjr02KZgbxeqA0rwi3SAy97SW9imz7kIIfA+xKXFYcroLwiIIQorQl7cpefdTVVVap620Ajj6X8eugqT3sdFwPHfGFJYF1qBIurdUvXhZOuVKmwmP/fuhCZomXlMVMe50zXn9ASMUD3RRNpLHO2//j4ve7699Mu/TooHFaw9l6qQ+ono8Zyx4DIbUQ/DO6jBMLY+OrWockgxA/bVJC4BqqXcpVhdXy+Cgx639jaff9zIYxCyjzNKVrl/12ziJBgM24TF/2VdE2d5qRYhJyZguB2PsnHlZm2rnWMA4oovHQahYS0ulTvUrl+5eMPKr+PepPA9YA2VWxvWKogI8rGkTFA2DbwvqvIojnyqIn9tDxho2ARX8Z2+7IG6YjsFvC+kE0oQfgOm60MjqI0lNIyQvCoM9+p0JO0/ipRX/JMjCTcY9t7tAy8jYgsSALYDcQRfQGupT6cbJOXR5cRbl+xU60qHRhgMd9MLuFmOgDE58CQEFOCVaOj6H5pdmUUm2hxq7dfpfTSc9u7OFGro0ymRQowjN/vweQT+fPIRe2tNKTaDpw54zOkSNIdU/4/A1Bd9GsUjpdkAnjDRf5jysbydJzT7A7wZ4o3O89Oz3R9DUPF9EuFFZHqoY7qe5o7PoxrfqqaVHIy/AMguDl+lVQFdAFxWZiVWiUVlE08BnbkkW3bSlnva2BCmjF0SmZq0ele2lJ2fl09nDfPT8ty0my9grYlTF6x/m0bRFeLEq9mXyT85NeDECUoUWcoIgRgWi+mYz8gCUx2cOjwEvqglNH+GnR6fnGyYZrUmwUnrogvwY8KLpJg7x0lOzR0ADFWM64Hf8saYX+OnlHxXS7MIMQ/Ojafrcc3wo9MrxT7yf2+ddkhWOARy3eE4Z4oJZRj7PprNODOiq0gBdCJCiS1OPTifwZxY264uhZWzqXPh6fkEGLSzNNpsY19agpOYounOhYYvKsqkDaJumOx80pYHkDIvDGqFrZ/cUjT4npqMUHhwDqMngBZxJTrTiYOW8ovik+YXgAR78rJku+U8t3QCz/d3HjVSLuZAtd25JNrHZMhDsMC4blWnU81gY1sd3nKAfbDhM12+uozu2NtCuE+G02BUwZdZyA3oQ97Da9xbmlXCAkEd4/V5FarNMmlSvCfknYgaRK4w0vI398jAywH1cLhKdveXdo1306BdNdLQjRPkZKpXh3bLN9bQb81gZ5kkPEGc6nvCLAyeXrHtag7Tm8yaADY1Bmxkwz1vePkZb67po8lAvZcFhnITN7C18NaaY2Kq4J1AqnslxlUk/OgNw5UpFCs/ERNrHErDw2ACKCMPeEGOlTPz330PtdOlZmbT8vKF0FzSKNUftdZVM58WfWRrhbTloyfQotPVoJxVmeuix2cPpvg+P05F2jXysgXYImkzsrpzwkLK8eO17mXZNEtU7AvCs4XPzSAanJpNtiR4XmyoXviASo0NtIfohQKzI9yPcaIsJSaLpVONDGKQG8RFoInviJRNy6EmYdgZ/FafFSDSESqi4ZJgTFo4A9BdgwpIy4Pyzh0E0h/2zqbn02fHuyByYaCBMY36I6wBgXadmxIZRCpuIvM87/lACYTWR/9RpoK4hz4yOo7Wkj2QpVHBMOANel72pVTGBjn/HQfQlcDa8wrHSBDu6WD7YP5GUpas+R6GMVb+x/K2eMk56VqvXTupmwTFEOdAYFuy97T4Wh0h+ngNjKMIPHNzY8Yw0hwlDe7N93S2jI3Up3DgDMIUOkm1amKkaXtiqfW2HTkHEhlYaVRLwYg5ULAFs6tawMuFstBXX9NQ5BLBrwL3zmKIHZjhgm4F+1tCFlUpYxwy6qN7Zf1jDR/RJQze125h3hAX2TMC6XfpzD0bqUrhxBCAf9OHh2Iw36e6j6a1MkBnxauYtxI9ZWLJZFaazouW61w93Ghkc65nV5AYXQrJT03psFs1mO+urtVTWbSO13fUI4oRo48ljMAoP3hz0i9+20kiYd8Bnp2exEph+aMuRTmpDgqIYGZxE8yCPAP1pPgrZZ0Riu4h5cgRgTcNrTaR6vuJDPukqhhYZ/3FcS1SAlcpuLNfWIz5cNjHXSBRY9cUkvdZNGlDnFQ575Ye3NdNNk3MTgmfwYyWAMvhYKRwURwDSypU4giJ3GSelHHTKJOxXe3MHBodsOALkCgCUjowKEgtIS93yzjG6ryKPirJU6ul1IgZgUX1m8yQIELj9JCzr2BndUF1PS8YGjExOR3QnUXSRW1YCRf3ym1umN0bqUrhxBiA6EDifF85COzNjThgcaj+Zxa7I99F1SJx6MKmzx10HzXsIaa6LijKNtXIPrxh6CydjzcKA/aZ8iJE7zEb+cB1M/mY83zAph2qxzGtlJ5JIRN54D2nbeCI0eaZyTS7vY8FRzfB+pHV1HxcKZ2RODsiiaaQqPuv89pEuuhaawoXfPT4zn24tzzWcEychzHFX13ZGRsdJ182Y324DSCYwv542hBYircVpsHBSItzlppoO6gCAOQDWskBzsREW1HwZb1q+T6LShnP/lHu6q/cJVXnPOJ/Xf3OkqIg2wSvyupYLJ0I3Hm6nT7GEiy4TANz4KPC2N3bTqwfbjfbczg+gP6zvojdqO6LJjHQ/05rLYk79Pwdt5Gy1XREwX+jnTrWl5nO7Nv3VOwaQKis1HLp9WfIRDnsZjczLYZjq0s1HjfQ6Z2K4sPZ0Y966HZmYvUhXWRWmu/29BkOzTG1jasZk+QeNtC0OfJNHC77Wbe820KHWkJGpMev7XHEUDgC8vn/Z95r7vEuyYkBudNhV99TqqjYfm9XDrVJbnGYag+zw3RjsdgS18abE5liPZMDGgx3YD1GoEGtiLpx1fgV1d77P4IaMLE30eDhv2II2G9CG59JCOBnWbN6tewMbTtzfVmhptjf8saJpI/dGAK13gOye5vWP1UTqU7xJ0ENynErX19yNzZHV0gijYudhZs6my7UI4yLzWDxnBoEz9XnYrRuChq09EhkW3mSimI2maDrmDQVGoK1TrlelYaDjoPsY6Fgr2NQTFeHD2lvXqsbs2HVd9cpLTnqzREQW7xL3YkEQXzWmChvrEhvrivXGOoOXbCcc8GoI6rBJb5hpfF92z0yHuArRTJJ07HmF0oZvdvmByuKtdnyTqQengZX9lWVH8dODNZCfR9CHWd+aPk0iFTzPsVn3ozyR9uYN0/G+SLJ0woPtVUV5ZqDgcf8DBpCZaFJ7EUqwwRCMK87gIjxe0kOhbaqe88d0iJmKgiTsb9w/G6dpoc5NWLEWJdrqTMhksF/yaQRF6UACetH+awpfT0d3adFAFmTPomFfSo/6WykUbJ2ljW06xhjmYcx7CLyk+H26wGPGaR3phaEtf8WEvsoAkAU+U4ohCw40CbE6m5rWplOstJmwKVR51Q5fGw39gyL15UbgErWGNduc0msEPGV1TvmoFTvKhaO0lZ3MaVcTPgUfoOYV2Gl4CAquJ7vUsxNwIPW8VOMgSlM8q3Io/eCxbANaidgN7tj6P2knxIy38s4uq0GybiZOMGRZrVTs6NNRzxEBfu/Zgajy/uFNIx/c/lNhvV4cYGdpN+F4eUqr6mYKEVrDx2oJPyyUSWZu4vkk/QyTNUIVSZ9Kqa44sLjgtaRpHTQcdABZpjEvNw0lrfuXQtNuFx610DgKnG4g4fmFF1oX0tpwKvMZRQms2rMop94BJimRnBIATYlGrztQDnO+A1m4BZif8vHrzfDPXc2cvNkw2StWPsY8x8FxMNiONeCrqh56Ys+1pe8my2Kg7U4pgKawZVU1k7DuWwgvvRggTsMRM5+RlA0f9AknHQxQeSXNBWIyWMYt/mfPykFxqAdpB7ETNZvA62/7Kks+QhOTiFsPejFkGvRebDrgk6HdI0efq4aCl+HHL+cht1iOn0sE8OcBMJlIDuCEJWJf7Nvy1iOcQgh/bTiXuINCwW2az/umqGv44uDN5zTZdDHo1acVwPjRTX7qg/zuvBGBYCDgVRVfrmgNH7eQObkHNV20eNuOB/1Nx9q+uXX68Xha99lFwEXARcBFwEXARcBFwEXARcBFwEXARcBFwEXAReA7gcD/ATWUF/aWa8NWAAAAAElFTkSuQmCC);
54
+ background-repeat: no-repeat;
55
+ background-position: 50% 50%;
56
+ }
57
+
58
+ .frash-notice-logo span {
59
+ display: block;
60
+ width: 80px;
61
+ }
62
+
63
+ .frash-notice-message {
64
+ width: 100%;
65
+ padding: 10px 20px;
66
+ color: #444;
67
+ }
68
+
69
+ .frash-notice-message strong {
70
+ color: #000;
71
+ }
72
+
73
+ .frash-notice-cta {
74
+ border-left: 1px solid #E5E5E5;
75
+ background: #F8F8F8;
76
+ padding: 0 30px;
77
+ position: relative;
78
+ white-space: nowrap;
79
+ }
80
+
81
+ .wp-core-ui .frash-notice-cta button,
82
+ .wp-core-ui .frash-notice-cta .button-primary:active {
83
+ vertical-align: middle;
84
+ }
85
+
86
+ .wp-core-ui .frash-notice-cta input[type="email"] {
87
+ vertical-align: middle;
88
+ line-height: 20px;
89
+ margin: 0;
90
+ min-width: 50px;
91
+ max-width: 320px;
92
+ text-align: center;
93
+ padding-left: 0;
94
+ padding-right: 0;
95
+ }
96
+
97
+ .frash-notice-dismiss {
98
+ background: transparent;
99
+ border: 0;
100
+ cursor: pointer;
101
+ color: #BBB;
102
+ }
103
+
104
+ .frash-notice-dismiss:hover {
105
+ color: #666;
106
+ }
107
+
108
+ @media only all and (max-width: 1200px) {
109
+ .frash-notice-dismiss {
110
+ display: block;
111
+ margin: 0 auto;
112
+ line-height: 18px;
113
+ padding-top: 8px;
114
+ padding-bottom: 2px;
115
+ }
116
+ }
117
+
118
+ @media only all and (max-width: 1000px) {
119
+ .wrap .frash-notice.notice {
120
+ display: block;
121
+ font-size: 13px;
122
+ }
123
+
124
+ .frash-notice > .frash-notice-logo {
125
+ float: left;
126
+ display: inline-block;
127
+ height: 80px;
128
+ margin: 10px;
129
+ border-radius: 4px;
130
+ }
131
+
132
+ .frash-notice > .frash-notice-message {
133
+ width: auto;
134
+ display: block;
135
+ padding: 10px;
136
+ min-height: 80px;
137
+ }
138
+
139
+ .frash-notice > .frash-notice-cta {
140
+ display: block;
141
+ border-top: 1px solid #E5E5E5;
142
+ border-left: 0;
143
+ text-align: center;
144
+ white-space: normal;
145
+ line-height: 30px;
146
+ padding: 10px 20px;
147
+ }
148
+
149
+ .wp-core-ui .frash-notice > .frash-notice-cta > input[type="email"],
150
+ .frash-notice > .frash-notice-cta > button {
151
+ font-size: 14px;
152
+ }
153
+
154
+ .frash-notice > .frash-notice-cta > .frash-notice-dismiss {
155
+ display: inline-block;
156
+ float: none;
157
+ line-height: 26px;
158
+ padding-top: 0;
159
+ padding-bottom: 0;
160
+ font-size: 13px;
161
+ }
162
+ }
163
+
164
+ @media only all and (max-width: 500px) {
165
+ .wp-core-ui .frash-notice > .frash-notice-cta > input[type="email"],
166
+ .frash-notice > .frash-notice-cta > button {
167
+ display: block;
168
+ width: 100% !important;
169
+ max-width: none;
170
+ margin-bottom: 4px;
171
+ font-size: 16px;
172
+ height: 34px;
173
+ }
174
+
175
+ .frash-notice > .frash-notice-cta > .frash-notice-dismiss {
176
+ margin-top: 5px;
177
+ font-size: 14px;
178
+ height: 23px;
179
+ }
180
+ }
extras/free-dashboard/admin.js ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function() {
2
+ var el_notice = jQuery( ".frash-notice" ),
3
+ type = el_notice.find( "input[name=type]" ).val(),
4
+ plugin_id = el_notice.find( "input[name=plugin_id]" ).val(),
5
+ url_wp = el_notice.find( "input[name=url_wp]" ).val(),
6
+ drip_plugin = el_notice.find( "input[name=drip_plugin]" ).val(),
7
+ inp_email = el_notice.find( "input[name=email]" )
8
+ btn_act = el_notice.find( ".frash-notice-act" ),
9
+ btn_dismiss = el_notice.find( ".frash-notice-dismiss" )
10
+ ajax_data = {};
11
+
12
+ ajax_data.plugin_id = plugin_id;
13
+ ajax_data.type = type;
14
+
15
+ function init_email() {
16
+ if ( ! inp_email.length ) { return; }
17
+
18
+ // Adjust the size of the email field to its contents.
19
+ function adjust_email_size() {
20
+ var width, tmp = jQuery( "<span></span>" );
21
+
22
+ tmp.addClass( "input-field" ).text( inp_email.val() );
23
+ tmp.appendTo( "body" );
24
+ width = parseInt( tmp.width() );
25
+ tmp.remove();
26
+
27
+ inp_email.width( width + 34 );
28
+ }
29
+
30
+ function email_keycheck( ev ) {
31
+ if ( 13 === ev.keyCode ) {
32
+ btn_act.click();
33
+ } else {
34
+ adjust_email_size();
35
+ }
36
+ }
37
+
38
+ inp_email.keyup( email_keycheck ).focus().select();
39
+ adjust_email_size();
40
+ }
41
+
42
+ // Display the notice after the page was loaded.
43
+ function initialize() {
44
+ el_notice.fadeIn( 500 );
45
+ init_email();
46
+ }
47
+
48
+ // Hide the notice after a CTA button was clicked
49
+ function remove_notice() {
50
+ el_notice.fadeTo( 100 , 0, function() {
51
+ el_notice.slideUp( 100, function() {
52
+ el_notice.remove();
53
+ });
54
+ });
55
+ }
56
+
57
+ // Open a tab to rate the plugin.
58
+ function act_rate() {
59
+ var url = url_wp.replace( /\/plugins\//, "/support/view/plugin-reviews/" ) + "?rate=5#postform",
60
+ link = jQuery( '<a href="' + url + '" target="_blank">Rate</a>' );
61
+
62
+ link.appendTo( "body" );
63
+ link[0].click();
64
+ link.remove();
65
+ }
66
+
67
+ // Submit the user to our email list.
68
+ function act_email() {
69
+ var email = inp_email.val();
70
+
71
+ // First create a new subscriber.
72
+ _dcq.push([
73
+ "identify",
74
+ { email: email }
75
+ ]);
76
+
77
+ // Then trigger the specified rule.
78
+ _dcq.push([
79
+ "track",
80
+ "Free plugin email course",
81
+ {"Plugin": drip_plugin}
82
+ ]);
83
+ }
84
+
85
+ // Notify WordPress about the users choice and close the message.
86
+ function notify_wordpress( action, message ) {
87
+ el_notice.attr( "data-message", message );
88
+ el_notice.addClass( "loading" );
89
+
90
+ ajax_data.action = action;
91
+ jQuery.post(
92
+ window.ajaxurl,
93
+ ajax_data,
94
+ remove_notice
95
+ );
96
+ }
97
+
98
+ // Handle click on the primary CTA button.
99
+ // Either open the wp.org page or submit the email address.
100
+ btn_act.click(function( ev ) {
101
+ ev.preventDefault();
102
+
103
+ switch ( type ) {
104
+ case 'rate': act_rate(); break;
105
+ case 'email': act_email(); break;
106
+ }
107
+
108
+ notify_wordpress( "frash_act", btn_act.data( "msg" ) );
109
+ });
110
+
111
+ // Dismiss the notice without any action.
112
+ btn_dismiss.click(function( ev ) {
113
+ ev.preventDefault();
114
+
115
+ notify_wordpress( "frash_dismiss", btn_dismiss.data( "msg" ) );
116
+ });
117
+
118
+ window.setTimeout( initialize, 500 );
119
+ });
120
+
121
+ // Drip integration
122
+ var _dcq = _dcq || [];
123
+ var _dcs = _dcs || {};
124
+
125
+ _dcs.account = '6994213';
126
+ var dc = document.createElement( 'script' );
127
+ dc.type = 'text/javascript'; dc.async = true;
128
+ dc.src = '//tag.getdrip.com/6994213.js';
129
+ var s = document.getElementsByTagName('script')[0];
130
+ s.parentNode.insertBefore(dc, s);
131
+ // End of drip integration
extras/free-dashboard/module.php ADDED
@@ -0,0 +1,468 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WPMUDEV Frash - Free Dashboard Notification module.
4
+ * Used by wordpress.org hosted plugins.
5
+ *
6
+ * TODO:
7
+ * - Form submit handler to submit email address to getdrip.com
8
+ * - Show the WPMUDEV logo in left side
9
+ *
10
+ * @version 1.0.0
11
+ * @author Incsub (Philipp Stracker)
12
+ */
13
+ if ( ! class_exists( 'WDev_Frash' ) ) {
14
+ class WDev_Frash {
15
+
16
+ /**
17
+ * The text-domain of the module.
18
+ *
19
+ * @since 1.0.0
20
+ */
21
+ const LANG = 'wdev-frash';
22
+
23
+ /**
24
+ * List of all registered plugins.
25
+ *
26
+ * @since 1.0.0
27
+ * @var array
28
+ */
29
+ protected $plugins = array();
30
+
31
+ /**
32
+ * Module options that are stored in database.
33
+ * Timestamps are stored here.
34
+ *
35
+ * Note that this option is stored in site-meta for multisite installs.
36
+ *
37
+ * @since 1.0.0
38
+ * @var array
39
+ */
40
+ protected $stored = array();
41
+
42
+ /**
43
+ * Initializes and returns the singleton instance.
44
+ *
45
+ * @since 1.0.0
46
+ */
47
+ static public function instance() {
48
+ static $Inst = null;
49
+
50
+ if ( null === $Inst ) {
51
+ $Inst = new WDev_Frash();
52
+ }
53
+
54
+ return $Inst;
55
+ }
56
+
57
+ /**
58
+ * Set up the WDev_Frash module. Private singleton constructor.
59
+ *
60
+ * @since 1.0.0
61
+ */
62
+ private function __construct() {
63
+ $this->read_stored_data();
64
+
65
+ $this->add_action( 'wdev-register-plugin', 5 );
66
+ $this->add_action( 'load-index.php' );
67
+
68
+ $this->add_action( 'wp_ajax_frash_act' );
69
+ $this->add_action( 'wp_ajax_frash_dismiss' );
70
+ }
71
+
72
+ /**
73
+ * Load persistent module-data from the WP Database.
74
+ *
75
+ * @since 1.0.0
76
+ */
77
+ protected function read_stored_data() {
78
+ $data = get_site_option( 'wdev-frash', false, false );
79
+
80
+ if ( ! is_array( $data ) ) {
81
+ $data = array();
82
+ }
83
+
84
+ // A list of all plugins with timestamp of first registration.
85
+ if ( ! isset( $data['plugins'] ) || ! is_array( $data['plugins'] ) ) {
86
+ $data['plugins'] = array();
87
+ }
88
+
89
+ // A list with pending messages and earliest timestamp for display.
90
+ if ( ! isset( $data['queue'] ) || ! is_array( $data['queue'] ) ) {
91
+ $data['queue'] = array();
92
+ }
93
+
94
+ // A list with all messages that were handles already.
95
+ if ( ! isset( $data['done'] ) || ! is_array( $data['done'] ) ) {
96
+ $data['done'] = array();
97
+ }
98
+
99
+ $this->stored = $data;
100
+ }
101
+
102
+ /**
103
+ * Save persistent module-data to the WP database.
104
+ *
105
+ * @since 1.0.0
106
+ */
107
+ protected function store_data() {
108
+ update_site_option( 'wdev-frash', $this->stored );
109
+ }
110
+
111
+ /**
112
+ * Action handler for 'wdev-register-plugin'
113
+ * Register an active plugin.
114
+ *
115
+ * @since 1.0.0
116
+ * @param string $plugin_id WordPress plugin-ID (see: plugin_basename).
117
+ * @param string $title Plugin name for display.
118
+ * @param string $url_wp URL to the plugin on wp.org (domain not needed)
119
+ * @param string $cta_email Title of the Email CTA button.
120
+ * @param string $drip_plugin Optional. Plugin-param for the getdrip rule.
121
+ */
122
+ public function wdev_register_plugin( $plugin_id, $title, $url_wp, $cta_email = '', $drip_plugin = '' ) {
123
+ // Ignore incorrectly registered plugins to avoid errors later.
124
+ if ( empty( $plugin_id ) ) { return; }
125
+ if ( empty( $title ) ) { return; }
126
+ if ( empty( $url_wp ) ) { return; }
127
+
128
+ if ( false === strpos( $url_wp, '://' ) ) {
129
+ $url_wp = 'https://wordpress.org/' . trim( $url_wp, '/' );
130
+ }
131
+
132
+ $this->plugins[$plugin_id] = (object) array(
133
+ 'id' => $plugin_id,
134
+ 'title' => $title,
135
+ 'url_wp' => $url_wp,
136
+ 'cta_email' => $cta_email,
137
+ 'drip_plugin' => $drip_plugin,
138
+ );
139
+
140
+ /*
141
+ * When the plugin is registered the first time we store some infos
142
+ * in the persistent module-data that help us later to find out
143
+ * if/which message should be displayed.
144
+ */
145
+ if ( empty( $this->stored['plugins'][$plugin_id] ) ) {
146
+ // First register the plugin permanently.
147
+ $this->stored['plugins'][$plugin_id] = time();
148
+
149
+ // Second schedule the messages to display.
150
+ $hash = md5( $plugin_id . '-email' );
151
+ $this->stored['queue'][$hash] = array(
152
+ 'plugin' => $plugin_id,
153
+ 'type' => 'email',
154
+ 'show_at' => time(), // Earliest time to display note.
155
+ );
156
+
157
+ $hash = md5( $plugin_id . '-rate' );
158
+ $this->stored['queue'][$hash] = array(
159
+ 'plugin' => $plugin_id,
160
+ 'type' => 'rate',
161
+ 'show_at' => time() + 7 * DAY_IN_SECONDS,
162
+ );
163
+
164
+ // Finally save the details.
165
+ $this->store_data();
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Ajax handler called when the user chooses the CTA button.
171
+ *
172
+ * @since 1.0.0
173
+ */
174
+ public function wp_ajax_frash_act() {
175
+ $plugin = $_POST['plugin_id'];
176
+ $type = $_POST['type'];
177
+
178
+ $this->mark_as_done( $plugin, $type, 'ok' );
179
+
180
+ echo 1;
181
+ exit;
182
+ }
183
+
184
+ /**
185
+ * Ajax handler called when the user chooses the dismiss button.
186
+ *
187
+ * @since 1.0.0
188
+ */
189
+ public function wp_ajax_frash_dismiss() {
190
+ $plugin = $_POST['plugin_id'];
191
+ $type = $_POST['type'];
192
+
193
+ $this->mark_as_done( $plugin, $type, 'ignore' );
194
+
195
+ echo 1;
196
+ exit;
197
+ }
198
+
199
+ /**
200
+ * Action handler for 'load-index.php'
201
+ * Set-up the Dashboard notification.
202
+ *
203
+ * @since 1.0.0
204
+ */
205
+ public function load_index_php() {
206
+ if ( is_super_admin() ) {
207
+ $this->add_action( 'all_admin_notices' );
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Action handler for 'admin_notices'
213
+ * Display the Dashboard notification.
214
+ *
215
+ * @since 1.0.0
216
+ */
217
+ public function all_admin_notices() {
218
+ $info = $this->choose_message();
219
+ if ( ! $info ) { return; }
220
+
221
+ $this->render_message( $info );
222
+ }
223
+
224
+ /**
225
+ * Check to see if there is a pending message to display and returns
226
+ * the message details if there is.
227
+ *
228
+ * Note that this function is only called on the main Dashboard screen
229
+ * and only when logged in as super-admin.
230
+ *
231
+ * @since 1.0.0
232
+ * @return object|false
233
+ * string $type [rate|email] Which message type?
234
+ * string $plugin WordPress plugin ID?
235
+ */
236
+ protected function choose_message() {
237
+ $obj = false;
238
+ $chosen = false;
239
+ $earliest = false;
240
+
241
+ $now = time();
242
+
243
+ // The "current" time can be changed via $_GET to test the module.
244
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! empty( $_GET['time'] ) ) {
245
+ $custom_time = $_GET['time'];
246
+ if ( ' ' == $custom_time[0] ) { $custom_time[0] = '+'; }
247
+ if ( $custom_time ) { $now = strtotime( $custom_time ); }
248
+ if ( ! $now ) { $now = time(); }
249
+ }
250
+
251
+ $tomorrow = $now + DAY_IN_SECONDS;
252
+
253
+ foreach ( $this->stored['queue'] as $hash => $item ) {
254
+ $show_at = intval( $item['show_at'] );
255
+ $is_sticky = ! empty( $item['sticky'] );
256
+
257
+ if ( ! isset( $this->plugins[ $item['plugin'] ] ) ) {
258
+ // Deactivated plugin before the message was displayed.
259
+ continue;
260
+ }
261
+ $plugin = $this->plugins[ $item['plugin'] ];
262
+
263
+ $can_display = true;
264
+ if ( wp_is_mobile() ) {
265
+ // Do not display rating message on mobile devices.
266
+ if ( 'rate' == $item['type'] ) {
267
+ $can_display = false;
268
+ }
269
+ }
270
+ if ( 'email' == $item['type'] ) {
271
+ if ( ! $plugin->drip_plugin || ! $plugin->cta_email ) {
272
+ // Do not display email message with missing email params.
273
+ $can_display = false;
274
+ }
275
+ }
276
+ if ( $now < $show_at ) {
277
+ // Do not display messages that are not due yet.
278
+ $can_display = false;
279
+ }
280
+
281
+ if ( ! $can_display ) { continue; }
282
+
283
+ if ( $is_sticky ) {
284
+ // If sticky item is present then choose it!
285
+ $chosen = $hash;
286
+ break;
287
+ } elseif ( ! $earliest || $earliest < $show_at ) {
288
+ $earliest = $show_at;
289
+ $chosen = $hash;
290
+ // Don't use `break` because a sticky item might follow...
291
+ // Find the item with the earliest schedule.
292
+ }
293
+ }
294
+
295
+ if ( $chosen ) {
296
+ // Make the chosen item sticky.
297
+ $this->stored['queue'][$chosen]['sticky'] = true;
298
+
299
+ // Re-schedule other messages that are due today.
300
+ foreach ( $this->stored['queue'] as $hash => $item ) {
301
+ $show_at = intval( $item['show_at'] );
302
+
303
+ if ( empty( $item['sticky'] ) && $tomorrow > $show_at ) {
304
+ $this->stored['queue'][$hash]['show_at'] = $tomorrow;
305
+ }
306
+ }
307
+
308
+ // Save the changes.
309
+ $this->store_data();
310
+
311
+ $obj = (object) $this->stored['queue'][$chosen];
312
+ }
313
+
314
+ return $obj;
315
+ }
316
+
317
+ /**
318
+ * Moves a message from the queue to the done list.
319
+ *
320
+ * @since 1.0.0
321
+ * @param string $plugin Plugin ID.
322
+ * @param string $type [rate|email] Message type.
323
+ * @param string $state [ok|ignore] Button clicked.
324
+ */
325
+ protected function mark_as_done( $plugin, $type, $state ) {
326
+ $done_item = false;
327
+
328
+ foreach ( $this->stored['queue'] as $hash => $item ) {
329
+ unset( $this->stored['queue'][$hash]['sticky'] );
330
+
331
+ if ( $item['plugin'] == $plugin && $item['type'] == $type ) {
332
+ $done_item = $item;
333
+ unset( $this->stored['queue'][$hash] );
334
+ }
335
+ }
336
+
337
+ if ( $done_item ) {
338
+ $done_item['state'] = $state;
339
+ $done_item['hash'] = $hash;
340
+ $done_item['handled_at'] = time();
341
+ unset( $done_item['sticky'] );
342
+
343
+ $this->stored['done'][] = $done_item;
344
+ $this->store_data();
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Renders the actual Notification message.
350
+ *
351
+ * @since 1.0.0
352
+ */
353
+ protected function render_message( $info ) {
354
+ $plugin = $this->plugins[$info->plugin];
355
+ $css_url = plugin_dir_url( __FILE__ ) . '/admin.css';
356
+ $js_url = plugin_dir_url( __FILE__ ) . '/admin.js';
357
+
358
+ ?>
359
+ <link rel="stylesheet" type="text/css" href="<?php echo esc_url( $css_url ); ?>" />
360
+ <div class="notice frash-notice frash-notice-<?php echo esc_attr( $info->type ); ?>" style="display:none">
361
+ <input type="hidden" name="type" value="<?php echo esc_attr( $info->type ); ?>" />
362
+ <input type="hidden" name="plugin_id" value="<?php echo esc_attr( $info->plugin ); ?>" />
363
+ <input type="hidden" name="url_wp" value="<?php echo esc_attr( $plugin->url_wp ); ?>" />
364
+ <input type="hidden" name="drip_plugin" value="<?php echo esc_attr( $plugin->drip_plugin ); ?>" />
365
+ <?php
366
+ if ( 'email' == $info->type ) {
367
+ $this->render_email_message( $plugin );
368
+ } elseif ( 'rate' == $info->type ) {
369
+ $this->render_rate_message( $plugin );
370
+ }
371
+ ?>
372
+ </div>
373
+ <script src="<?php echo esc_url( $js_url ); ?>"></script>
374
+ <?php
375
+ }
376
+
377
+ /**
378
+ * Output the contents of the email message.
379
+ * No return value. The code is directly output.
380
+ *
381
+ * @since 1.0.0
382
+ */
383
+ protected function render_email_message( $plugin ) {
384
+ $user = wp_get_current_user();
385
+ $user_name = $user->display_name;
386
+ $admin_email = get_site_option( 'admin_email' );
387
+
388
+ $msg = __( "We're happy that you've chosen to install %s! Are you interested in how to make the most of this plugin? How would you like a quick 5 day email crash course with actionable advice on building your membership site? Only the info you want, no subscription!", self::LANG );
389
+ $msg = apply_filters( 'wdev-email-message-' . $plugin->id, $msg );
390
+
391
+ ?>
392
+ <div class="frash-notice-logo"><span></span></div>
393
+ <div class="frash-notice-message">
394
+ <?php
395
+ printf(
396
+ $msg,
397
+ '<strong>' . $plugin->title . '</strong>'
398
+ );
399
+ ?>
400
+ </div>
401
+ <div class="frash-notice-cta">
402
+ <input type="email" name="email" value="<?php echo esc_attr( $admin_email ); ?>" />
403
+ <button class="frash-notice-act button-primary" data-msg="<?php _e( 'Thanks :)', self::LANG ); ?>">
404
+ <?php echo esc_html( $plugin->cta_email ); ?>
405
+ </button>
406
+ <button class="frash-notice-dismiss" data-msg="<?php _e( 'Saving', self::LANG ); ?>">
407
+ <?php _e( 'No thanks', self::LANG ); ?>
408
+ </button>
409
+ </div>
410
+ <?php
411
+ }
412
+
413
+ /**
414
+ * Output the contents of the rate-this-plugin message.
415
+ * No return value. The code is directly output.
416
+ *
417
+ * @since 1.0.0
418
+ */
419
+ protected function render_rate_message( $plugin ) {
420
+ $user = wp_get_current_user();
421
+ $user_name = $user->display_name;
422
+
423
+ $msg = __( "Hey %s, you've been using %s for a while now, and we hope you're happy with it.", self::LANG ) . '<br />'. __( "We've spent countless hours developing this free plugin for you, and we would really appreciate it if you dropped us a quick rating!", self::LANG );
424
+ $msg = apply_filters( 'wdev-rating-message-' . $plugin->id, $msg );
425
+
426
+ ?>
427
+ <div class="frash-notice-logo"><span></span></div>
428
+ <div class="frash-notice-message">
429
+ <?php
430
+ printf(
431
+ $msg,
432
+ '<strong>' . $user_name . '</strong>',
433
+ '<strong>' . $plugin->title . '</strong>'
434
+ );
435
+ ?>
436
+ </div>
437
+ <div class="frash-notice-cta">
438
+ <button class="frash-notice-act button-primary" data-msg="<?php _e( 'Thanks :)', self::LANG ); ?>">
439
+ <?php
440
+ printf(
441
+ __( 'Rate %s', self::LANG ),
442
+ esc_html( $plugin->title )
443
+ ); ?>
444
+ </button>
445
+ <button class="frash-notice-dismiss" data-msg="<?php _e( 'Saving', self::LANG ); ?>">
446
+ <?php _e( 'No thanks', self::LANG ); ?>
447
+ </button>
448
+ </div>
449
+ <?php
450
+ }
451
+
452
+ /**
453
+ * Registers a new action handler. The callback function has the same
454
+ * name as the action hook.
455
+ *
456
+ * @since 1.0.0
457
+ */
458
+ protected function add_action( $hook, $params = 1 ) {
459
+ $method_name = strtolower( $hook );
460
+ $method_name = preg_replace( '/[^a-z0-9]/', '_', $method_name );
461
+ $handler = array( $this, $method_name );
462
+ add_action( $hook, $handler, 5, $params );
463
+ }
464
+ }
465
+
466
+ // Initialize the module.
467
+ WDev_Frash::instance();
468
+ }
languages/wp-smush.pot CHANGED
@@ -4,14 +4,16 @@ msgid ""
4
  msgstr ""
5
  "Project-Id-Version: WP Smush 2.0.5\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/wp-smush\n"
7
- "POT-Creation-Date: 2015-04-16 19:27:10+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:106 lib/class-wp-smush-admin.php:290
16
  msgid "WP Smush"
17
  msgstr ""
@@ -90,15 +92,20 @@ msgid "Thanks for using WP Smush Pro! You now can:"
90
  msgstr ""
91
 
92
  #: lib/class-wp-smush-admin.php:298 lib/class-wp-smush-admin.php:309
93
- msgid "\"Super-Smush\" your images with our intelligent multi-pass lossy compression. Get 2&times; more compression than lossless with almost no noticeable quality loss!"
 
 
 
94
  msgstr ""
95
 
96
  #: lib/class-wp-smush-admin.php:299 lib/class-wp-smush-admin.php:310
97
- msgid "Get the best lossless compression. We try multiple methods to squeeze every last byte out of your images."
 
 
98
  msgstr ""
99
 
100
  #: lib/class-wp-smush-admin.php:300
101
- msgid "Smush images up to 8MB."
102
  msgstr ""
103
 
104
  #: lib/class-wp-smush-admin.php:301
@@ -106,7 +113,9 @@ msgid "Bulk smush ALL your images with one click!"
106
  msgstr ""
107
 
108
  #: lib/class-wp-smush-admin.php:302 lib/class-wp-smush-admin.php:313
109
- msgid "Keep a backup of your original un-smushed images in case you want to restore later."
 
 
110
  msgstr ""
111
 
112
  #: lib/class-wp-smush-admin.php:307
@@ -122,11 +131,17 @@ msgid "Bulk smush ALL your images with one click! No more rate limiting."
122
  msgstr ""
123
 
124
  #: lib/class-wp-smush-admin.php:314
125
- 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>."
 
 
 
126
  msgstr ""
127
 
128
  #: lib/class-wp-smush-admin.php:315
129
- 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."
 
 
 
130
  msgstr ""
131
 
132
  #: lib/class-wp-smush-admin.php:318
@@ -134,7 +149,9 @@ msgid "Upgrade Now &raquo;"
134
  msgstr ""
135
 
136
  #: lib/class-wp-smush-admin.php:321
137
- msgid "Already upgraded to a WPMU DEV membership? Install and Login to our Dashboard plugin to enable Smush Pro features."
 
 
138
  msgstr ""
139
 
140
  #: lib/class-wp-smush-admin.php:330
@@ -154,8 +171,11 @@ msgid "Save Changes"
154
  msgstr ""
155
 
156
  #: lib/class-wp-smush-admin.php:502
157
- msgid "%d image is over 1MB so will be skipped using the free version of the plugin."
158
- msgid_plural "%d images are over 1MB so will be skipped using the free version of the plugin."
 
 
 
159
  msgstr[0] ""
160
  msgstr[1] ""
161
 
@@ -169,7 +189,8 @@ msgstr ""
169
 
170
  #: lib/class-wp-smush-admin.php:525
171
  msgid "%d attachment in your media library has not been smushed."
172
- msgid_plural "%d image attachments in your media library have not been smushed yet."
 
173
  msgstr[0] ""
174
  msgstr[1] ""
175
 
@@ -179,12 +200,17 @@ msgstr ""
179
 
180
  #: lib/class-wp-smush-admin.php:534
181
  msgid ""
182
- "Please be aware, smushing a large number of images can take a while depending on your server and network speed.\n"
183
- "\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."
 
 
 
184
  msgstr ""
185
 
186
  #: lib/class-wp-smush-admin.php:539
187
- 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."
 
 
188
  msgstr ""
189
 
190
  #: lib/class-wp-smush-admin.php:540
@@ -192,11 +218,15 @@ msgid "Remove limits &raquo;"
192
  msgstr ""
193
 
194
  #: lib/class-wp-smush-admin.php:560
195
- msgid "When you <a href=\"%s\">upload some images</a> they will be available to smush here."
 
 
196
  msgstr ""
197
 
198
  #: lib/class-wp-smush-admin.php:566 lib/class-wp-smush-admin.php:802
199
- msgid "You can also smush images individually from your <a href=\"%s\">Media Library</a>."
 
 
200
  msgstr ""
201
 
202
  #: lib/class-wp-smush-admin.php:618
@@ -204,7 +234,9 @@ msgid "Reduced by "
204
  msgstr ""
205
 
206
  #: lib/class-wp-smush-admin.php:628
207
- msgid "<span class=\"done-count\">%d</span> of <span class=\"total-count\">%d</span> total attachments have been smushed"
 
 
208
  msgstr ""
209
 
210
  #: lib/class-wp-smush-admin.php:698
@@ -232,12 +264,17 @@ msgid "Super-Smush Images"
232
  msgstr ""
233
 
234
  #: lib/class-wp-smush-admin.php:1177
235
- msgid "We found attachments that were previously smushed losslessly. If desired you can Super-Smush them now for more savings with almost no noticeable quality loss."
 
 
 
236
  msgstr ""
237
 
238
  #: lib/class-wp-smush-admin.php:1185
239
- msgid "<span class=\"remaining-count\">%d</span> attachment left to Super-Smush"
240
- msgid_plural "<span class=\"remaining-count\">%d</span> attachments left to Super-Smush"
 
 
241
  msgstr[0] ""
242
  msgstr[1] ""
243
 
@@ -312,16 +349,16 @@ msgstr ""
312
  #: wp-smush.php:724
313
  msgid "Smush Now!"
314
  msgstr ""
315
- #. Plugin Name of the plugin/theme
316
- msgid "WP Smush"
317
- msgstr ""
318
 
319
  #. Plugin URI of the plugin/theme
320
  msgid "http://wordpress.org/extend/plugins/wp-smushit/"
321
  msgstr ""
322
 
323
  #. Description of the plugin/theme
324
- msgid "Reduce image file sizes, improve performance and boost your SEO using the free <a href=\"https://premium.wpmudev.org/\">WPMU DEV</a> WordPress Smush API."
 
 
 
325
  msgstr ""
326
 
327
  #. Author of the plugin/theme
@@ -330,4 +367,4 @@ msgstr ""
330
 
331
  #. Author URI of the plugin/theme
332
  msgid "http://premium.wpmudev.org/"
333
- msgstr ""
4
  msgstr ""
5
  "Project-Id-Version: WP Smush 2.0.5\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/wp-smush\n"
7
+ "POT-Creation-Date: 2015-06-13 08:58+0530\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-06-13 08:58+0530\n"
12
+ "X-Generator: Poedit 1.8.1\n"
13
+ "Last-Translator: Umesh <umeshsingla05@gmail.com>\n"
14
+ "Language-Team: \n"
15
 
16
+ #. Plugin Name of the plugin/theme
17
  #: lib/class-wp-smush-admin.php:106 lib/class-wp-smush-admin.php:290
18
  msgid "WP Smush"
19
  msgstr ""
92
  msgstr ""
93
 
94
  #: lib/class-wp-smush-admin.php:298 lib/class-wp-smush-admin.php:309
95
+ msgid ""
96
+ "\"Super-Smush\" your images with our intelligent multi-pass lossy "
97
+ "compression. Get 2&times; more compression than lossless with almost no "
98
+ "noticeable quality loss!"
99
  msgstr ""
100
 
101
  #: lib/class-wp-smush-admin.php:299 lib/class-wp-smush-admin.php:310
102
+ msgid ""
103
+ "Get the best lossless compression. We try multiple methods to squeeze every "
104
+ "last byte out of your images."
105
  msgstr ""
106
 
107
  #: lib/class-wp-smush-admin.php:300
108
+ msgid "Smush images up to 32MB."
109
  msgstr ""
110
 
111
  #: lib/class-wp-smush-admin.php:301
113
  msgstr ""
114
 
115
  #: lib/class-wp-smush-admin.php:302 lib/class-wp-smush-admin.php:313
116
+ msgid ""
117
+ "Keep a backup of your original un-smushed images in case you want to restore "
118
+ "later."
119
  msgstr ""
120
 
121
  #: lib/class-wp-smush-admin.php:307
131
  msgstr ""
132
 
133
  #: lib/class-wp-smush-admin.php:314
134
+ msgid ""
135
+ "Access 24/7/365 support from <a href=\"https://premium.wpmudev.org/support/?"
136
+ "utm_source=wordpress.org&utm_medium=plugin&utm_campaign=WP%20Smush%20Upgrade"
137
+ "\">the best WordPress support team on the planet</a>."
138
  msgstr ""
139
 
140
  #: lib/class-wp-smush-admin.php:315
141
+ msgid ""
142
+ "Download <a href=\"https://premium.wpmudev.org/?utm_source=wordpress."
143
+ "org&utm_medium=plugin&utm_campaign=WP%20Smush%20Upgrade\">350+ other premium "
144
+ "plugins and themes</a> included in your membership."
145
  msgstr ""
146
 
147
  #: lib/class-wp-smush-admin.php:318
149
  msgstr ""
150
 
151
  #: lib/class-wp-smush-admin.php:321
152
+ msgid ""
153
+ "Already upgraded to a WPMU DEV membership? Install and Login to our "
154
+ "Dashboard plugin to enable Smush Pro features."
155
  msgstr ""
156
 
157
  #: lib/class-wp-smush-admin.php:330
171
  msgstr ""
172
 
173
  #: lib/class-wp-smush-admin.php:502
174
+ msgid ""
175
+ "%d image is over 1MB so will be skipped using the free version of the plugin."
176
+ msgid_plural ""
177
+ "%d images are over 1MB so will be skipped using the free version of the "
178
+ "plugin."
179
  msgstr[0] ""
180
  msgstr[1] ""
181
 
189
 
190
  #: lib/class-wp-smush-admin.php:525
191
  msgid "%d attachment in your media library has not been smushed."
192
+ msgid_plural ""
193
+ "%d image attachments in your media library have not been smushed yet."
194
  msgstr[0] ""
195
  msgstr[1] ""
196
 
200
 
201
  #: lib/class-wp-smush-admin.php:534
202
  msgid ""
203
+ "Please be aware, smushing a large number of images can take a while "
204
+ "depending on your server and network speed.\n"
205
+ "\t\t\t\t\t\t<strong>You must keep this page open while the bulk smush is "
206
+ "processing</strong>, but you can leave at any time and come back to continue "
207
+ "where it left off."
208
  msgstr ""
209
 
210
  #: lib/class-wp-smush-admin.php:539
211
+ msgid ""
212
+ "Free accounts are limited to bulk smushing %d attachments per request. You "
213
+ "will need to click to start a new bulk job after each %d attachments."
214
  msgstr ""
215
 
216
  #: lib/class-wp-smush-admin.php:540
218
  msgstr ""
219
 
220
  #: lib/class-wp-smush-admin.php:560
221
+ msgid ""
222
+ "When you <a href=\"%s\">upload some images</a> they will be available to "
223
+ "smush here."
224
  msgstr ""
225
 
226
  #: lib/class-wp-smush-admin.php:566 lib/class-wp-smush-admin.php:802
227
+ msgid ""
228
+ "You can also smush images individually from your <a href=\"%s\">Media "
229
+ "Library</a>."
230
  msgstr ""
231
 
232
  #: lib/class-wp-smush-admin.php:618
234
  msgstr ""
235
 
236
  #: lib/class-wp-smush-admin.php:628
237
+ msgid ""
238
+ "<span class=\"done-count\">%d</span> of <span class=\"total-count\">%d</"
239
+ "span> total attachments have been smushed"
240
  msgstr ""
241
 
242
  #: lib/class-wp-smush-admin.php:698
264
  msgstr ""
265
 
266
  #: lib/class-wp-smush-admin.php:1177
267
+ msgid ""
268
+ "We found attachments that were previously smushed losslessly. If desired you "
269
+ "can Super-Smush them now for more savings with almost no noticeable quality "
270
+ "loss."
271
  msgstr ""
272
 
273
  #: lib/class-wp-smush-admin.php:1185
274
+ msgid ""
275
+ "<span class=\"remaining-count\">%d</span> attachment left to Super-Smush"
276
+ msgid_plural ""
277
+ "<span class=\"remaining-count\">%d</span> attachments left to Super-Smush"
278
  msgstr[0] ""
279
  msgstr[1] ""
280
 
349
  #: wp-smush.php:724
350
  msgid "Smush Now!"
351
  msgstr ""
 
 
 
352
 
353
  #. Plugin URI of the plugin/theme
354
  msgid "http://wordpress.org/extend/plugins/wp-smushit/"
355
  msgstr ""
356
 
357
  #. Description of the plugin/theme
358
+ msgid ""
359
+ "Reduce image file sizes, improve performance and boost your SEO using the "
360
+ "free <a href=\"https://premium.wpmudev.org/\">WPMU DEV</a> WordPress Smush "
361
+ "API."
362
  msgstr ""
363
 
364
  #. Author of the plugin/theme
367
 
368
  #. Author URI of the plugin/theme
369
  msgid "http://premium.wpmudev.org/"
370
+ msgstr ""
languages/wp-smushit.pot ADDED
@@ -0,0 +1,488 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #, fuzzy
2
+ msgid ""
3
+ msgstr ""
4
+ "Project-Id-Version: WP Smush\n"
5
+ "POT-Creation-Date: 2015-10-08 00:56+0530\n"
6
+ "PO-Revision-Date: 2015-10-07 23:49+0530\n"
7
+ "Last-Translator: Umesh <umeshsingla05@gmail.com>\n"
8
+ "Language-Team: Umesh <umeshsingla05@gmail.com>\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Generator: Poedit 1.8.1\n"
13
+ "X-Poedit-Basepath: ..\n"
14
+ "X-Poedit-WPHeader: wp-smush.php\n"
15
+ "X-Poedit-SourceCharset: UTF-8\n"
16
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
17
+ "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
18
+ "_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
19
+ "X-Poedit-SearchPath-0: .\n"
20
+ "X-Poedit-SearchPathExcluded-0: *.js\n"
21
+
22
+ #: extras/free-dashboard/module.php:388
23
+ #, php-format
24
+ msgid ""
25
+ "We're happy that you've chosen to install %s! Are you interested in how to "
26
+ "make the most of this plugin? How would you like a quick 5 day email crash "
27
+ "course with actionable advice on building your membership site? Only the "
28
+ "info you want, no subscription!"
29
+ msgstr ""
30
+
31
+ #: extras/free-dashboard/module.php:403 extras/free-dashboard/module.php:438
32
+ msgid "Thanks :)"
33
+ msgstr ""
34
+
35
+ #: extras/free-dashboard/module.php:406 extras/free-dashboard/module.php:445
36
+ msgid "Saving"
37
+ msgstr ""
38
+
39
+ #: extras/free-dashboard/module.php:407 extras/free-dashboard/module.php:446
40
+ msgid "No thanks"
41
+ msgstr ""
42
+
43
+ #: extras/free-dashboard/module.php:423
44
+ #, php-format
45
+ msgid ""
46
+ "Hey %s, you've been using %s for a while now, and we hope you're happy with "
47
+ "it."
48
+ msgstr ""
49
+
50
+ #: extras/free-dashboard/module.php:423
51
+ msgid ""
52
+ "We've spent countless hours developing this free plugin for you, and we "
53
+ "would really appreciate it if you dropped us a quick rating!"
54
+ msgstr ""
55
+
56
+ #: extras/free-dashboard/module.php:441
57
+ #, php-format
58
+ msgid "Rate %s"
59
+ msgstr ""
60
+
61
+ #. Plugin Name of the plugin/theme
62
+ #: lib/class-wp-smush-admin.php:105 lib/class-wp-smush-admin.php:303
63
+ msgid "WP Smush"
64
+ msgstr ""
65
+
66
+ #: lib/class-wp-smush-admin.php:220 lib/class-wp-smush-admin.php:952
67
+ #: lib/class-wp-smush-admin.php:968
68
+ msgid "Bulk Smush Now"
69
+ msgstr ""
70
+
71
+ #: lib/class-wp-smush-admin.php:222 lib/class-wp-smush-admin.php:972
72
+ #, php-format
73
+ msgid "Bulk Smush %d Attachments"
74
+ msgstr ""
75
+
76
+ #: lib/class-wp-smush-admin.php:226
77
+ msgid "Smushing in Progress"
78
+ msgstr ""
79
+
80
+ #: lib/class-wp-smush-admin.php:227 lib/class-wp-smush-admin.php:962
81
+ msgid "All Done!"
82
+ msgstr ""
83
+
84
+ #: lib/class-wp-smush-admin.php:229
85
+ msgid "Ops!... something went wrong"
86
+ msgstr ""
87
+
88
+ #: lib/class-wp-smush-admin.php:230 lib/class-wp-smush.php:706
89
+ msgid "Super-Smush"
90
+ msgstr ""
91
+
92
+ #: lib/class-wp-smush-admin.php:231
93
+ msgid "Smush it"
94
+ msgstr ""
95
+
96
+ #: lib/class-wp-smush-admin.php:232
97
+ msgid "Smush Now"
98
+ msgstr ""
99
+
100
+ #: lib/class-wp-smush-admin.php:233
101
+ msgid "Sending ..."
102
+ msgstr ""
103
+
104
+ #: lib/class-wp-smush-admin.php:234
105
+ msgid "{{errors}} image(s) were skipped due to an error."
106
+ msgstr ""
107
+
108
+ #: lib/class-wp-smush-admin.php:235
109
+ msgid "All images are Super-Smushed."
110
+ msgstr ""
111
+
112
+ #: lib/class-wp-smush-admin.php:274
113
+ msgid "Smush images on upload"
114
+ msgstr ""
115
+
116
+ #: lib/class-wp-smush-admin.php:275
117
+ msgid "Smush Original Image"
118
+ msgstr ""
119
+
120
+ #: lib/class-wp-smush-admin.php:275
121
+ msgid "Skipped if Large size is available"
122
+ msgstr ""
123
+
124
+ #: lib/class-wp-smush-admin.php:276
125
+ msgid "Super-Smush images"
126
+ msgstr ""
127
+
128
+ #: lib/class-wp-smush-admin.php:276
129
+ msgid "Lossy Image Compression"
130
+ msgstr ""
131
+
132
+ #: lib/class-wp-smush-admin.php:277
133
+ msgid "Backup Original Images"
134
+ msgstr ""
135
+
136
+ #: lib/class-wp-smush-admin.php:277
137
+ msgid "Will nearly double the size of your Uploads Directory"
138
+ msgstr ""
139
+
140
+ #: lib/class-wp-smush-admin.php:301
141
+ msgid "WP Smush Pro"
142
+ msgstr ""
143
+
144
+ #: lib/class-wp-smush-admin.php:311 lib/class-wp-smush-admin.php:1021
145
+ msgid "Settings"
146
+ msgstr ""
147
+
148
+ #: lib/class-wp-smush-admin.php:374
149
+ msgid "PRO FEATURES"
150
+ msgstr ""
151
+
152
+ #: lib/class-wp-smush-admin.php:379
153
+ msgid "These features are available in Pro Version of the plugin."
154
+ msgstr ""
155
+
156
+ #: lib/class-wp-smush-admin.php:402
157
+ msgid "Save Changes"
158
+ msgstr ""
159
+
160
+ #: lib/class-wp-smush-admin.php:474
161
+ #, php-format
162
+ msgid ""
163
+ "%d image is over 1MB so will be skipped using the free version of the plugin."
164
+ msgid_plural ""
165
+ "%d images are over 1MB so will be skipped using the free version of the "
166
+ "plugin."
167
+ msgstr[0] ""
168
+ msgstr[1] ""
169
+
170
+ #: lib/class-wp-smush-admin.php:483
171
+ msgid "Smush in Bulk"
172
+ msgstr ""
173
+
174
+ #: lib/class-wp-smush-admin.php:488
175
+ msgid "Congratulations, all your images are currently Smushed!"
176
+ msgstr ""
177
+
178
+ #: lib/class-wp-smush-admin.php:497
179
+ #, php-format
180
+ msgid "%d attachment in your media library has not been smushed."
181
+ msgid_plural ""
182
+ "%d image attachments in your media library have not been smushed yet."
183
+ msgstr[0] ""
184
+ msgstr[1] ""
185
+
186
+ #: lib/class-wp-smush-admin.php:501
187
+ msgid "Remove size limit &raquo;"
188
+ msgstr ""
189
+
190
+ #: lib/class-wp-smush-admin.php:506
191
+ msgid ""
192
+ "Please be aware, smushing a large number of images can take a while "
193
+ "depending on your server and network speed.\n"
194
+ "\t\t\t\t\t\t<strong>You must keep this page open while the bulk smush is "
195
+ "processing</strong>, but you can leave at any time and come back to continue "
196
+ "where it left off."
197
+ msgstr ""
198
+
199
+ #: lib/class-wp-smush-admin.php:511
200
+ #, php-format
201
+ msgid ""
202
+ "Free accounts are limited to bulk smushing %d attachments per request. You "
203
+ "will need to click to start a new bulk job after each %d attachments."
204
+ msgstr ""
205
+
206
+ #: lib/class-wp-smush-admin.php:512
207
+ msgid "Remove limits &raquo;"
208
+ msgstr ""
209
+
210
+ #: lib/class-wp-smush-admin.php:532
211
+ #, php-format
212
+ msgid ""
213
+ "When you <a href=\"%s\">upload some images</a> they will be available to "
214
+ "smush here."
215
+ msgstr ""
216
+
217
+ #: lib/class-wp-smush-admin.php:538 lib/class-wp-smush-admin.php:774
218
+ #, php-format
219
+ msgid ""
220
+ "You can also smush images individually from your <a href=\"%s\">Media "
221
+ "Library</a>."
222
+ msgstr ""
223
+
224
+ #: lib/class-wp-smush-admin.php:590
225
+ msgid "Reduced by "
226
+ msgstr ""
227
+
228
+ #: lib/class-wp-smush-admin.php:601
229
+ #, php-format
230
+ msgid ""
231
+ "<span class=\"done-count\">%d</span> of <span class=\"total-count\">%d</"
232
+ "span> total attachments have been smushed"
233
+ msgstr ""
234
+
235
+ #: lib/class-wp-smush-admin.php:670
236
+ msgid "You don't have permission to work with uploaded files."
237
+ msgstr ""
238
+
239
+ #: lib/class-wp-smush-admin.php:674
240
+ msgid "No attachment ID was provided."
241
+ msgstr ""
242
+
243
+ #: lib/class-wp-smush-admin.php:745
244
+ #, php-format
245
+ msgid "<p>Please <a href=\"%s\">upload some images</a>.</p>"
246
+ msgstr ""
247
+
248
+ #: lib/class-wp-smush-admin.php:762
249
+ msgid "All your images are already smushed!"
250
+ msgstr ""
251
+
252
+ #: lib/class-wp-smush-admin.php:863
253
+ #, php-format
254
+ msgid "<strong>%d of %d images</strong> were sent for smushing:"
255
+ msgstr ""
256
+
257
+ #: lib/class-wp-smush-admin.php:1148
258
+ msgid "Super-Smush Images"
259
+ msgstr ""
260
+
261
+ #: lib/class-wp-smush-admin.php:1149
262
+ msgid ""
263
+ "We found attachments that were previously smushed losslessly. If desired you "
264
+ "can Super-Smush them now for more savings with almost no noticeable quality "
265
+ "loss."
266
+ msgstr ""
267
+
268
+ #: lib/class-wp-smush-admin.php:1157
269
+ #, php-format
270
+ msgid ""
271
+ "<span class=\"remaining-count\">%d</span> attachment left to Super-Smush"
272
+ msgid_plural ""
273
+ "<span class=\"remaining-count\">%d</span> attachments left to Super-Smush"
274
+ msgstr[0] ""
275
+ msgstr[1] ""
276
+
277
+ #: lib/class-wp-smush-admin.php:1177
278
+ msgid "Thanks for using WP Smush Pro! You now can:"
279
+ msgstr ""
280
+
281
+ #: lib/class-wp-smush-admin.php:1179 lib/class-wp-smush-admin.php:1191
282
+ msgid ""
283
+ "Smush Full size Image, It is skipped by default, if large size is available "
284
+ "for a image"
285
+ msgstr ""
286
+
287
+ #: lib/class-wp-smush-admin.php:1180 lib/class-wp-smush-admin.php:1192
288
+ msgid ""
289
+ "\"Super-Smush\" your images with our intelligent multi-pass lossy "
290
+ "compression. Get 2&times; more compression than lossless with almost no "
291
+ "noticeable quality loss!"
292
+ msgstr ""
293
+
294
+ #: lib/class-wp-smush-admin.php:1181 lib/class-wp-smush-admin.php:1193
295
+ msgid ""
296
+ "Get the best lossless compression. We try multiple methods to squeeze every "
297
+ "last byte out of your images."
298
+ msgstr ""
299
+
300
+ #: lib/class-wp-smush-admin.php:1182
301
+ msgid "Smush images up to 32MB."
302
+ msgstr ""
303
+
304
+ #: lib/class-wp-smush-admin.php:1183
305
+ msgid "Bulk smush ALL your images with one click!"
306
+ msgstr ""
307
+
308
+ #: lib/class-wp-smush-admin.php:1184 lib/class-wp-smush-admin.php:1196
309
+ msgid ""
310
+ "Keep a backup of your original un-smushed images in case you want to restore "
311
+ "later."
312
+ msgstr ""
313
+
314
+ #: lib/class-wp-smush-admin.php:1189
315
+ msgid "Upgrade to WP Smush Pro to:"
316
+ msgstr ""
317
+
318
+ #: lib/class-wp-smush-admin.php:1194
319
+ msgid "Smush images greater than 1MB."
320
+ msgstr ""
321
+
322
+ #: lib/class-wp-smush-admin.php:1195
323
+ msgid "Bulk smush ALL your images with one click! No more rate limiting."
324
+ msgstr ""
325
+
326
+ #: lib/class-wp-smush-admin.php:1197
327
+ msgid ""
328
+ "Access 24/7/365 support from <a href=\"https://premium.wpmudev.org/support/?"
329
+ "utm_source=wordpress.org&utm_medium=plugin&utm_campaign=WP%20Smush%20Upgrade"
330
+ "\">the best WordPress support team on the planet</a>."
331
+ msgstr ""
332
+
333
+ #: lib/class-wp-smush-admin.php:1198
334
+ msgid ""
335
+ "Download <a href=\"https://premium.wpmudev.org/?utm_source=wordpress."
336
+ "org&utm_medium=plugin&utm_campaign=WP%20Smush%20Upgrade\">350+ other premium "
337
+ "plugins and themes</a> included in your membership."
338
+ msgstr ""
339
+
340
+ #: lib/class-wp-smush-admin.php:1201
341
+ msgid "Upgrade Now &raquo;"
342
+ msgstr ""
343
+
344
+ #: lib/class-wp-smush-admin.php:1204
345
+ msgid ""
346
+ "Already upgraded to a WPMU DEV membership? Install and Login to our "
347
+ "Dashboard plugin to enable Smush Pro features."
348
+ msgstr ""
349
+
350
+ #: lib/class-wp-smush-admin.php:1213
351
+ msgid "Activate WPMU DEV Dashboard"
352
+ msgstr ""
353
+
354
+ #: lib/class-wp-smush-admin.php:1216
355
+ msgid "Install WPMU DEV Dashboard"
356
+ msgstr ""
357
+
358
+ #: lib/class-wp-smush.php:92
359
+ msgid "File path is empty"
360
+ msgstr ""
361
+
362
+ #: lib/class-wp-smush.php:97
363
+ #, php-format
364
+ msgid "Could not find %s"
365
+ msgstr ""
366
+
367
+ #: lib/class-wp-smush.php:102
368
+ #, php-format
369
+ msgid "%s is not writable"
370
+ msgstr ""
371
+
372
+ #: lib/class-wp-smush.php:112
373
+ #, php-format
374
+ msgid "Skipped (%s), image not found."
375
+ msgstr ""
376
+
377
+ #: lib/class-wp-smush.php:117
378
+ #, php-format
379
+ msgid "Skipped (%s), size limit exceeded."
380
+ msgstr ""
381
+
382
+ #: lib/class-wp-smush.php:132
383
+ msgid "Unknown API error"
384
+ msgstr ""
385
+
386
+ #: lib/class-wp-smush.php:283
387
+ #, php-format
388
+ msgid "Size '%s' not processed correctly"
389
+ msgstr ""
390
+
391
+ #: lib/class-wp-smush.php:305 lib/class-wp-smush.php:313
392
+ msgid "Size 'full' not processed correctly"
393
+ msgstr ""
394
+
395
+ #: lib/class-wp-smush.php:448
396
+ #, php-format
397
+ msgid "Error posting to API: %s"
398
+ msgstr ""
399
+
400
+ #: lib/class-wp-smush.php:454
401
+ #, php-format
402
+ msgid "Error posting to API: %s %s"
403
+ msgstr ""
404
+
405
+ #: lib/class-wp-smush.php:471
406
+ msgid "Smush data corrupted, try again."
407
+ msgstr ""
408
+
409
+ #: lib/class-wp-smush.php:487
410
+ msgid "Image couldn't be smushed"
411
+ msgstr ""
412
+
413
+ #: lib/class-wp-smush.php:673
414
+ msgid "Error processing request"
415
+ msgstr ""
416
+
417
+ #: lib/class-wp-smush.php:677
418
+ msgid "Already Optimized"
419
+ msgstr ""
420
+
421
+ #: lib/class-wp-smush.php:679
422
+ #, php-format
423
+ msgid "%d images reduced "
424
+ msgstr ""
425
+
426
+ #: lib/class-wp-smush.php:679
427
+ msgid "Reduced "
428
+ msgstr ""
429
+
430
+ #: lib/class-wp-smush.php:680
431
+ #, php-format
432
+ msgid "by %s ( %01.1f%% )"
433
+ msgstr ""
434
+
435
+ #: lib/class-wp-smush.php:683
436
+ msgid "Smush stats"
437
+ msgstr ""
438
+
439
+ #: lib/class-wp-smush.php:712
440
+ msgid "Not processed"
441
+ msgstr ""
442
+
443
+ #: lib/class-wp-smush.php:718
444
+ msgid "Smush Now!"
445
+ msgstr ""
446
+
447
+ #: lib/class-wp-smush.php:985
448
+ msgid "Large size available for the image."
449
+ msgstr ""
450
+
451
+ #: lib/class-wp-smush.php:986
452
+ msgid "Image exceeded the 1Mb size limit."
453
+ msgstr ""
454
+
455
+ #: lib/class-wp-smush.php:988
456
+ msgid " Skipped"
457
+ msgstr ""
458
+
459
+ #: lib/class-wp-smush.php:1005
460
+ msgid "Image size"
461
+ msgstr ""
462
+
463
+ #: lib/class-wp-smush.php:1006
464
+ msgid "Savings"
465
+ msgstr ""
466
+
467
+ #: wp-smush.php:82
468
+ msgid "Get Fast"
469
+ msgstr ""
470
+
471
+ #. Plugin URI of the plugin/theme
472
+ msgid "http://wordpress.org/extend/plugins/wp-smushit/"
473
+ msgstr ""
474
+
475
+ #. Description of the plugin/theme
476
+ msgid ""
477
+ "Reduce image file sizes, improve performance and boost your SEO using the "
478
+ "free <a href=\"https://premium.wpmudev.org/\">WPMU DEV</a> WordPress Smush "
479
+ "API."
480
+ msgstr ""
481
+
482
+ #. Author of the plugin/theme
483
+ msgid "WPMU DEV"
484
+ msgstr ""
485
+
486
+ #. Author URI of the plugin/theme
487
+ msgid "http://premium.wpmudev.org/"
488
+ msgstr ""
lib/class-wp-smush-admin.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /**
3
- * @package WP SmushIt
4
  * @subpackage Admin
5
  * @version 1.0
6
  *
@@ -84,7 +84,6 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
84
  /// Smush Upgrade
85
  add_action( 'admin_notices', array( $this, 'smush_upgrade' ) );
86
 
87
-
88
  $this->init_settings();
89
 
90
  }
@@ -103,7 +102,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
103
  return $form_fields;
104
  }
105
  $form_fields['wp_smush'] = array(
106
- 'label' => __( 'WP Smush', WP_SMUSH_DOMAIN ),
107
  'input' => 'html',
108
  'html' => $this->smush_status( $post->ID ),
109
  'show_in_edit' => true,
@@ -142,6 +141,9 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
142
 
143
  // Enqueue js on Post screen (Edit screen for media )
144
  add_action( 'admin_print_scripts-post.php', array( $this, 'enqueue' ) );
 
 
 
145
  }
146
 
147
  /**
@@ -166,12 +168,12 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
166
  wp_register_script( 'wp-smushit-admin-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin.js', array(
167
  'jquery',
168
  'media-views'
169
- ), WP_SMUSH_VERSON );
170
  } else {
171
  wp_register_script( 'wp-smushit-admin-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin.js', array(
172
  'jquery',
173
  'underscore'
174
- ), WP_SMUSH_VERSON );
175
  }
176
  wp_register_script( 'wp-smushit-admin-media-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin-media.js', array( 'jquery' ), $WpSmush->version );
177
 
@@ -207,7 +209,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
207
 
208
  function localize() {
209
  global $pagenow;
210
- if ( ! isset( $pagenow ) || ! in_array( $pagenow, array( "post.php", "upload.php" ) ) ) {
211
  return;
212
  }
213
 
@@ -215,22 +217,22 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
215
  $handle = 'wp-smushit-admin-js';
216
 
217
  if ( $this->is_pro() || $this->remaining_count <= $this->max_free_bulk ) {
218
- $bulk_now = __( 'Bulk Smush Now', WP_SMUSH_DOMAIN );
219
  } else {
220
- $bulk_now = sprintf( __( 'Bulk Smush %d Attachments', WP_SMUSH_DOMAIN ), $this->max_free_bulk );
221
  }
222
 
223
  $wp_smush_msgs = array(
224
- 'progress' => __( 'Smushing in Progress', WP_SMUSH_DOMAIN ),
225
- 'done' => __( 'All Done!', WP_SMUSH_DOMAIN ),
226
  'bulk_now' => $bulk_now,
227
- 'something_went_wrong' => __( 'Ops!... something went wrong', WP_SMUSH_DOMAIN ),
228
- 'resmush' => __( 'Super-Smush', WP_SMUSH_DOMAIN ),
229
- 'smush_it' => __( 'Smush it', WP_SMUSH_DOMAIN ),
230
- 'smush_now' => __( 'Smush Now', WP_SMUSH_DOMAIN ),
231
- 'sending' => __( 'Sending ...', WP_SMUSH_DOMAIN ),
232
- "error_in_bulk" => __( '{{errors}} image(s) were skipped due to an error.', WP_SMUSH_DOMAIN ),
233
- "all_supersmushed" => __( 'All images are Super-Smushed.', WP_SMUSH_DOMAIN )
234
  );
235
 
236
  wp_localize_script( $handle, 'wp_smush_msgs', $wp_smush_msgs );
@@ -256,7 +258,8 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
256
  $data = array(
257
  'smushed' => $this->get_smushed_image_ids(),
258
  'unsmushed' => $this->ids,
259
- 'lossless' => $this->lossless_ids
 
260
  );
261
 
262
  wp_localize_script( 'wp-smushit-admin-js', 'wp_smushit_data', $data );
@@ -268,9 +271,10 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
268
  */
269
  function init_settings() {
270
  $this->settings = array(
271
- 'auto' => __( 'Auto-Smush images on upload', WP_SMUSH_DOMAIN ),
272
- 'lossy' => __( 'Super-Smush images', WP_SMUSH_DOMAIN ) . ' <small>(' . __( 'lossy optimization', WP_SMUSH_DOMAIN ) . ')</small>',
273
- 'backup' => __( 'Backup original images', WP_SMUSH_DOMAIN ) . ' <small>(' . __( 'this will nearly double the size of your uploads directory', WP_SMUSH_DOMAIN ) . ')</small>'
 
274
  );
275
  }
276
 
@@ -294,63 +298,17 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
294
  <h2>
295
  <?php
296
  if ( $this->is_pro() ) {
297
- _e( 'WP Smush Pro', WP_SMUSH_DOMAIN );
298
  } else {
299
- _e( 'WP Smush', WP_SMUSH_DOMAIN );
300
  } ?>
301
- </h2>
302
-
303
- <?php if ( $this->is_pro() ) { ?>
304
- <div class="wp-smpushit-features updated">
305
- <h3><?php _e( 'Thanks for using WP Smush Pro! You now can:', WP_SMUSH_DOMAIN ) ?></h3>
306
- <ol>
307
- <li><?php _e( '"Super-Smush" your images with our intelligent multi-pass lossy compression. Get 2&times; more compression than lossless with almost no noticeable quality loss!', WP_SMUSH_DOMAIN ); ?></li>
308
- <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>
309
- <li><?php _e( 'Smush images up to 8MB.', WP_SMUSH_DOMAIN ); ?></li>
310
- <li><?php _e( 'Bulk smush ALL your images with one click!', WP_SMUSH_DOMAIN ); ?></li>
311
- <li><?php _e( 'Keep a backup of your original un-smushed images in case you want to restore later.', WP_SMUSH_DOMAIN ); ?></li>
312
- </ol>
313
- </div>
314
- <?php } else { ?>
315
- <div class="wp-smpushit-features error">
316
- <h3><?php _e( 'Upgrade to WP Smush Pro to:', WP_SMUSH_DOMAIN ) ?></h3>
317
- <ol>
318
- <li><?php _e( '"Super-Smush" your images with our intelligent multi-pass lossy compression. Get 2&times; more compression than lossless with almost no noticeable quality loss!', WP_SMUSH_DOMAIN ); ?></li>
319
- <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>
320
- <li><?php _e( 'Smush images greater than 1MB.', WP_SMUSH_DOMAIN ); ?></li>
321
- <li><?php _e( 'Bulk smush ALL your images with one click! No more rate limiting.', WP_SMUSH_DOMAIN ); ?></li>
322
- <li><?php _e( 'Keep a backup of your original un-smushed images in case you want to restore later.', WP_SMUSH_DOMAIN ); ?></li>
323
- <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>
324
- <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>
325
- </ol>
326
- <p>
327
- <a class="button-primary" href="<?php echo $this->upgrade_url; ?>"><?php _e( 'Upgrade Now &raquo;', WP_SMUSH_DOMAIN ); ?></a>
328
- </p>
329
-
330
- <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>
331
-
332
- <p>
333
- <?php
334
- if ( ! class_exists( 'WPMUDEV_Dashboard' ) ) {
335
- if ( file_exists( WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php' ) ) {
336
- $function = is_multisite() ? 'network_admin_url' : 'admin_url';
337
- $url = wp_nonce_url( $function( 'plugins.php?action=activate&plugin=wpmudev-updates%2Fupdate-notifications.php' ), 'activate-plugin_wpmudev-updates/update-notifications.php' );
338
- ?><a class="button-secondary"
339
- href="<?php echo $url; ?>"><?php _e( 'Activate WPMU DEV Dashboard', WP_SMUSH_DOMAIN ); ?></a><?php
340
- } else { //dashboard not installed at all
341
- ?><a class="button-secondary" target="_blank"
342
- href="https://premium.wpmudev.org/project/wpmu-dev-dashboard/"><?php _e( 'Install WPMU DEV Dashboard', WP_SMUSH_DOMAIN ); ?></a><?php
343
- }
344
- }
345
- ?>
346
- </p>
347
- </div>
348
- <?php } ?>
349
-
350
 
351
  <div class="wp-smpushit-container">
352
  <h3>
353
- <?php _e( 'Settings', WP_SMUSH_DOMAIN ) ?>
354
  </h3>
355
  <?php
356
  // display the options
@@ -385,6 +343,11 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
385
  $opt_auto_val = 1;
386
  }
387
 
 
 
 
 
 
388
  //Smush auto key
389
  $opt_lossy = WP_SMUSH_PREFIX . 'lossy';
390
  //Auto value
@@ -396,49 +359,49 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
396
  $opt_backup_val = get_option( $opt_backup, false );
397
 
398
  //disable lossy for non-premium members
399
- $disabled = $class = '';
400
  if ( ! $this->is_pro() ) {
401
  $disabled = ' disabled';
402
  $opt_lossy_val = $opt_backup_val = 0;
403
  $class = ' inactive inactive-anim';
404
- }
405
-
406
- // return html
407
- printf(
408
- "<div class='wp-smush-setting-row'><label><input type='checkbox' name='%1\$s' id='%1\$s' value='1' %2\$s %3\$s>%4\$s</label></div>", esc_attr( $opt_auto ), checked( $opt_auto_val, 1, false ), '', $this->settings['auto']
409
- );
410
- ?>
411
- <div class="pro-only<?php echo $class; ?>"><?php
412
-
413
- //Lossy
414
- printf(
415
- "<div class='wp-smush-setting-row'><label><input type='checkbox' name='%1\$s' id='%1\$s' value='1' %2\$s %3\$s>%4\$s</label></div>", esc_attr( $opt_lossy ), checked( $opt_lossy_val, 1, false ), $disabled, $this->settings['lossy']
416
- );
417
 
418
- //Backup
419
- printf(
420
- "<div class='wp-smush-setting-row'><label><input type='checkbox' name='%1\$s' id='%1\$s' value='1' %2\$s %3\$s>%4\$s</label></div>", esc_attr( $opt_backup ), checked( $opt_backup_val, 1, false ), $disabled, $this->settings['backup']
421
- );
422
  if ( ! $this->is_pro() ) {
423
  ?>
424
  <div class="pro-note">
425
- <div style="padding:14px 0 14px;">Pro feature only.
426
- <a href="<?php echo $this->upgrade_url; ?>" target="_blank">Find out more »</a>
427
  </div>
428
  </div>
429
- <?php
 
430
  }
431
- ?>
432
- </div>
433
- <!-- End of pro-only -->
 
 
 
 
 
 
 
 
434
  </div>
435
  <!-- End of wrap --><?php
436
  // nonce
437
  wp_nonce_field( 'save_wp_smush_options', 'wp_smush_options_nonce' );
438
  ?>
439
- <input type="submit" id="wp-smush-save-settings" class="button button-primary" value="<?php _e( 'Save Changes', WP_SMUSH_DOMAIN ); ?>">
440
  </form>
441
- <?php
442
  }
443
 
444
  /**
@@ -509,7 +472,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
509
  if ( $this->exceeding_items_count ) {
510
  $exceed_mb = sprintf(
511
  _n( "%d image is over 1MB so will be skipped using the free version of the plugin.",
512
- "%d images are over 1MB so will be skipped using the free version of the plugin.", $this->exceeding_items_count, WP_SMUSH_DOMAIN ),
513
  $this->exceeding_items_count
514
  );
515
  }
@@ -517,12 +480,12 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
517
  ?>
518
  <hr>
519
  <div class="bulk-smush">
520
- <h3><?php _e( 'Smush in Bulk', WP_SMUSH_DOMAIN ) ?></h3>
521
  <?php
522
 
523
  if ( $this->remaining_count == 0 ) {
524
  ?>
525
- <p><?php _e( "Congratulations, all your images are currently Smushed!", WP_SMUSH_DOMAIN ); ?></p>
526
  <?php
527
  $this->progress_ui();
528
 
@@ -531,22 +494,22 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
531
  } else {
532
  ?>
533
  <div class="smush-instructions">
534
- <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>
535
  <?php if ( $exceed_mb ) { ?>
536
  <p class="error">
537
  <?php echo $exceed_mb; ?>
538
- <a href="<?php echo $this->upgrade_url; ?>"><?php _e( 'Remove size limit &raquo;', WP_SMUSH_DOMAIN ); ?></a>
539
  </p>
540
 
541
  <?php } ?>
542
 
543
  <p><?php _e( "Please be aware, smushing a large number of images can take a while depending on your server and network speed.
544
- <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>
545
 
546
  <?php if ( ! $this->is_pro() ) { ?>
547
  <p class="error">
548
- <?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 ); ?>
549
- <a href="<?php echo $this->upgrade_url; ?>"><?php _e( 'Remove limits &raquo;', WP_SMUSH_DOMAIN ); ?></a>
550
  </p>
551
  <?php } ?>
552
 
@@ -566,19 +529,19 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
566
  $auto_smush = get_site_option( WP_SMUSH_PREFIX . 'auto' );
567
  if ( ! $auto_smush && $this->remaining_count == 0 ) {
568
  ?>
569
- <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>
570
- <?php
571
  } else { ?>
572
  <p>
573
  <?php
574
  // let the user know that there's an alternative
575
- printf( __( 'You can also smush images individually from your <a href="%s">Media Library</a>.', WP_SMUSH_DOMAIN ), admin_url( 'upload.php' ) );
576
  ?>
577
  </p><?php
578
  }
579
  ?>
580
  </div>
581
- <?php
582
  }
583
 
584
  function print_loader() {
@@ -603,7 +566,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
603
  </div>
604
  </div>
605
  </div>
606
- <?php
607
  }
608
 
609
  /**
@@ -624,7 +587,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
624
  $progress_ui .= '<div id="wp-smush-progress-wrap">
625
  <div id="wp-smush-fetched-progress" class="wp-smush-progressbar"><div style="width:' . $smushed_pc . '%"></div></div>
626
  <p id="wp-smush-compression">'
627
- . __( "Reduced by ", WP_SMUSH_DOMAIN )
628
  . '<span id="human">' . $this->stats['human'] . '</span> ( <span id="percent">' . number_format_i18n( $this->stats['percent'], 2, '.', '' ) . '</span>% )
629
  </p>
630
  </div>';
@@ -635,7 +598,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
635
  <p id="fetched-status">' .
636
  sprintf(
637
  __(
638
- '<span class="done-count">%d</span> of <span class="total-count">%d</span> total attachments have been smushed', WP_SMUSH_DOMAIN
639
  ), $this->smushed_count, $this->total_count
640
  ) .
641
  '</p>
@@ -704,11 +667,11 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
704
  */
705
  function smush_single() {
706
  if ( ! current_user_can( 'upload_files' ) ) {
707
- wp_die( __( "You don't have permission to work with uploaded files.", WP_SMUSH_DOMAIN ) );
708
  }
709
 
710
  if ( ! isset( $_GET['attachment_id'] ) ) {
711
- wp_die( __( 'No attachment ID was provided.', WP_SMUSH_DOMAIN ) );
712
  }
713
 
714
  global $WpSmush;
@@ -779,7 +742,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
779
  if ( $this->total_count < 1 ) {
780
  printf(
781
  __(
782
- '<p>Please <a href="%s">upload some images</a>.</p>', WP_SMUSH_DOMAIN
783
  ), admin_url( 'media-new.php' )
784
  );
785
 
@@ -796,10 +759,10 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
796
  ?>
797
  <p>
798
  <?php
799
- _e( 'All your images are already smushed!', WP_SMUSH_DOMAIN );
800
  ?>
801
  </p>
802
- <?php
803
  } else {
804
  $this->selected_ui( $send_ids, '' );
805
  // we have some smushing to do! :)
@@ -808,10 +771,10 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
808
  <p>
809
  <?php
810
  // let the user know that there's an alternative
811
- printf( __( 'You can also smush images individually from your <a href="%s">Media Library</a>.', WP_SMUSH_DOMAIN ), admin_url( 'upload.php' ) );
812
  ?>
813
  </p>
814
- <?php
815
  }
816
 
817
  // display the progress bar
@@ -822,7 +785,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
822
 
823
  ?>
824
  </div>
825
- <?php
826
  }
827
 
828
  /**
@@ -898,7 +861,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
898
  printf(
899
  __(
900
  '<strong>%d of %d images</strong> were sent for smushing:',
901
- WP_SMUSH_DOMAIN
902
  ),
903
  count( $send_ids ), count( $received_ids )
904
  );
@@ -912,7 +875,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
912
  ?>
913
  </ul>
914
  </div>
915
- <?php
916
  }
917
 
918
  /**
@@ -927,7 +890,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
927
  <button class="button button-primary<?php echo ' ' . $button['class']; ?>" name="smush-all" <?php echo $disabled; ?>>
928
  <span><?php echo $button['text'] ?></span>
929
  </button>
930
- <?php
931
  }
932
 
933
  function global_stats() {
@@ -986,7 +949,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
986
  if ( $super_smush ) {
987
  if ( $this->is_pro() || $this->remaining_count <= $this->max_free_bulk ) { //if premium or under limit
988
 
989
- $button['text'] = __( 'Bulk Smush Now', WP_SMUSH_DOMAIN );
990
  $button['class'] = 'wp-smush-button wp-smush-send';
991
  } else {
992
  return array();
@@ -996,17 +959,17 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
996
 
997
  // if we have nothing left to smush, disable the buttons
998
  if ( $this->smushed_count === $this->total_count ) {
999
- $button['text'] = __( 'All Done!', WP_SMUSH_DOMAIN );
1000
  $button['class'] = 'wp-smush-finished disabled wp-smush-finished';
1001
  $button['disabled'] = 'disabled';
1002
 
1003
  } else if ( $this->is_pro() || $this->remaining_count <= $this->max_free_bulk ) { //if premium or under limit
1004
 
1005
- $button['text'] = __( 'Bulk Smush Now', WP_SMUSH_DOMAIN );
1006
  $button['class'] = 'wp-smush-button wp-smush-send';
1007
 
1008
  } else { //if not premium and over limit
1009
- $button['text'] = sprintf( __( 'Bulk Smush %d Attachments', WP_SMUSH_DOMAIN ), $this->max_free_bulk );
1010
  $button['class'] = 'wp-smush-button wp-smush-send';
1011
 
1012
  }
@@ -1055,7 +1018,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1055
  function settings_link( $links ) {
1056
 
1057
  $settings_page = admin_url( 'upload.php?page=wp-smush-bulk' );
1058
- $settings = '<a href="' . $settings_page . '">' . __( 'Settings', WP_SMUSH_DOMAIN ) . '</a>';
1059
 
1060
  array_unshift( $links, $settings );
1061
 
@@ -1063,7 +1026,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1063
  }
1064
 
1065
  function smush_upgrade() {
1066
- if ( ! current_user_can( 'edit_others_posts' ) ) {
1067
  return;
1068
  }
1069
 
@@ -1079,7 +1042,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1079
  return;
1080
  }
1081
  ?>
1082
- <div class="error">
1083
  <a href="<?php echo admin_url( 'index.php' ); ?>?dismiss_smush_upgrade=1" style="float:right;margin-top: 10px;text-decoration: none;"><span class="dashicons dashicons-dismiss" style="color:gray;"></span>Dismiss</a>
1084
 
1085
  <h3><span class="dashicons dashicons-megaphone" style="color:red"></span> Happy Smushing!</h3>
@@ -1089,14 +1052,14 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1089
  <p>That means that you can continue smushing your images for free, now with added https support, speed,
1090
  and reliability... enjoy!</p>
1091
 
1092
- <p>And now, if you'd like to upgrade to the WP Smush Pro plugin you can smush images up to 8MB in size,
1093
  get 'Super Smushing' of, on average, 2&times; more reduction than lossless, backup all non smushed
1094
  images and bulk smush an
1095
  unlimited number of images at once.
1096
  <a href="https://premium.wpmudev.org/?coupon=SMUSH50OFF#pricing"> Click here to upgrade with a 50%
1097
  discount</a>.</p>
1098
  </div>
1099
- <?php
1100
  }
1101
 
1102
  /**
@@ -1182,8 +1145,8 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1182
  return;
1183
  }
1184
 
1185
- $ss_progress_ui = '<h4>' . __( 'Super-Smush Images', WP_SMUSH_DOMAIN ) . '</h4>';
1186
- $ss_progress_ui .= '<p>' . __( 'We found attachments that were previously smushed losslessly. If desired you can Super-Smush them now for more savings with almost no noticeable quality loss.', WP_SMUSH_DOMAIN ) . '</p>';
1187
  $ss_progress_ui .= '<div id="progress-ui" class="super-smush">';
1188
 
1189
  // display the progress bars
@@ -1191,16 +1154,73 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1191
  <div id="wp-smush-ss-progress" class="wp-smush-progressbar"><div style="width:0%"></div></div>
1192
  <p id="wp-smush-compression">'
1193
  . sprintf(
1194
- _n( '<span class="remaining-count">%d</span> attachment left to Super-Smush',
1195
- '<span class="remaining-count">%d</span> attachments left to Super-Smush',
1196
- count( $this->lossless_ids ),
1197
- WP_SMUSH_DOMAIN ), count( $this->lossless_ids ), count( $this->lossless_ids ) )
1198
  . '</p>
1199
  </div>
1200
  </div><!-- End of progress ui -->';
1201
  echo $ss_progress_ui;
1202
  $this->setup_button( true );
1203
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1204
  }
1205
 
1206
  $wpsmushit_admin = new WpSmushitAdmin();
1
  <?php
2
  /**
3
+ * @package WP Smush
4
  * @subpackage Admin
5
  * @version 1.0
6
  *
84
  /// Smush Upgrade
85
  add_action( 'admin_notices', array( $this, 'smush_upgrade' ) );
86
 
 
87
  $this->init_settings();
88
 
89
  }
102
  return $form_fields;
103
  }
104
  $form_fields['wp_smush'] = array(
105
+ 'label' => __( 'WP Smush', 'wp-smushit' ),
106
  'input' => 'html',
107
  'html' => $this->smush_status( $post->ID ),
108
  'show_in_edit' => true,
141
 
142
  // Enqueue js on Post screen (Edit screen for media )
143
  add_action( 'admin_print_scripts-post.php', array( $this, 'enqueue' ) );
144
+
145
+ // Enqueue js on Post screen (Edit screen for media )
146
+ add_action( 'admin_print_scripts-post-new.php', array( $this, 'enqueue' ) );
147
  }
148
 
149
  /**
168
  wp_register_script( 'wp-smushit-admin-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin.js', array(
169
  'jquery',
170
  'media-views'
171
+ ), WP_SMUSH_VERSION );
172
  } else {
173
  wp_register_script( 'wp-smushit-admin-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin.js', array(
174
  'jquery',
175
  'underscore'
176
+ ), WP_SMUSH_VERSION );
177
  }
178
  wp_register_script( 'wp-smushit-admin-media-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin-media.js', array( 'jquery' ), $WpSmush->version );
179
 
209
 
210
  function localize() {
211
  global $pagenow;
212
+ if ( ! isset( $pagenow ) || ! in_array( $pagenow, array( "post.php", "upload.php", "post-new.php" ) ) ) {
213
  return;
214
  }
215
 
217
  $handle = 'wp-smushit-admin-js';
218
 
219
  if ( $this->is_pro() || $this->remaining_count <= $this->max_free_bulk ) {
220
+ $bulk_now = __( 'Bulk Smush Now', 'wp-smushit' );
221
  } else {
222
+ $bulk_now = sprintf( __( 'Bulk Smush %d Attachments', 'wp-smushit' ), $this->max_free_bulk );
223
  }
224
 
225
  $wp_smush_msgs = array(
226
+ 'progress' => __( 'Smushing in Progress', 'wp-smushit' ),
227
+ 'done' => __( 'All Done!', 'wp-smushit' ),
228
  'bulk_now' => $bulk_now,
229
+ 'something_went_wrong' => __( 'Ops!... something went wrong', 'wp-smushit' ),
230
+ 'resmush' => __( 'Super-Smush', 'wp-smushit' ),
231
+ 'smush_it' => __( 'Smush it', 'wp-smushit' ),
232
+ 'smush_now' => __( 'Smush Now', 'wp-smushit' ),
233
+ 'sending' => __( 'Sending ...', 'wp-smushit' ),
234
+ "error_in_bulk" => __( '{{errors}} image(s) were skipped due to an error.', 'wp-smushit' ),
235
+ "all_supersmushed" => __( 'All images are Super-Smushed.', 'wp-smushit' )
236
  );
237
 
238
  wp_localize_script( $handle, 'wp_smush_msgs', $wp_smush_msgs );
258
  $data = array(
259
  'smushed' => $this->get_smushed_image_ids(),
260
  'unsmushed' => $this->ids,
261
+ 'lossless' => $this->lossless_ids,
262
+ 'timeout' => WP_SMUSH_TIMEOUT * 1000 //Convert it into ms
263
  );
264
 
265
  wp_localize_script( 'wp-smushit-admin-js', 'wp_smushit_data', $data );
271
  */
272
  function init_settings() {
273
  $this->settings = array(
274
+ 'auto' => __( 'Smush images on upload', 'wp-smushit' ),
275
+ 'original' => __( 'Smush Original Image', 'wp-smushit' ) . ' <small>(' . __( 'Skipped if Large size is available', 'wp-smushit' ) . ')</small>',
276
+ 'lossy' => __( 'Super-Smush images', 'wp-smushit' ) . ' <small>(' . __( 'Lossy Image Compression', 'wp-smushit' ) . ')</small>',
277
+ 'backup' => __( 'Backup Original Images', 'wp-smushit' ) . ' <small>(' . __( 'Will nearly double the size of your Uploads Directory', 'wp-smushit' ) . ')</small>'
278
  );
279
  }
280
 
298
  <h2>
299
  <?php
300
  if ( $this->is_pro() ) {
301
+ _e( 'WP Smush Pro', 'wp-smushit' );
302
  } else {
303
+ _e( 'WP Smush', 'wp-smushit' );
304
  } ?>
305
+ </h2><?php
306
+ $this->smush_pro_features();
307
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
 
309
  <div class="wp-smpushit-container">
310
  <h3>
311
+ <?php _e( 'Settings', 'wp-smushit' ) ?>
312
  </h3>
313
  <?php
314
  // display the options
343
  $opt_auto_val = 1;
344
  }
345
 
346
+ //Smush auto key
347
+ $opt_original = WP_SMUSH_PREFIX . 'original';
348
+ //Auto value
349
+ $opt_original_val = get_option( $opt_original, false );
350
+
351
  //Smush auto key
352
  $opt_lossy = WP_SMUSH_PREFIX . 'lossy';
353
  //Auto value
359
  $opt_backup_val = get_option( $opt_backup, false );
360
 
361
  //disable lossy for non-premium members
362
+ $disabled = $class = $feature_class = '';
363
  if ( ! $this->is_pro() ) {
364
  $disabled = ' disabled';
365
  $opt_lossy_val = $opt_backup_val = 0;
366
  $class = ' inactive inactive-anim';
367
+ } ?>
368
+ <div class='wp-smush-setting-row'><?php
369
+ // return html
370
+ printf( "<label><input type='checkbox' name='%1\$s' id='%1\$s' value='1' %2\$s %3\$s>%4\$s</label>", esc_attr( $opt_auto ), checked( $opt_auto_val, 1, false ), '', $this->settings['auto'] );
371
+ ?>
372
+ </div>
373
+ <fieldset class="wp-smush-pro-features">
374
+ <legend><strong><?php esc_html_e( "PRO FEATURES", "wp-smushit" ); ?></strong></legend><?php
 
 
 
 
 
375
 
 
 
 
 
376
  if ( ! $this->is_pro() ) {
377
  ?>
378
  <div class="pro-note">
379
+ <div style="padding:14px 0 14px;"><span class="dashicons dashicons-info"></span><?php esc_html_e( "These features are available in Pro Version of the plugin.", "wp-smushit" ); ?>
380
+ <a href="<?php echo $this->upgrade_url; ?>" target="_blank" class="button find-out-link">Find out more »</a>
381
  </div>
382
  </div>
383
+ <?php
384
+ $feature_class = ' disabled';
385
  }
386
+
387
+ //Smush Original
388
+ printf( "<div class='wp-smush-setting-row%5\$s'><label><input type='checkbox' name='%1\$s' id='%1\$s' value='1' %2\$s %3\$s>%4\$s</label></div>", esc_attr( $opt_original ), checked( $opt_original_val, 1, false ), $disabled, $this->settings['original'], $feature_class );
389
+
390
+ //Lossy
391
+ printf( "<div class='wp-smush-setting-row%5\$s'><label><input type='checkbox' name='%1\$s' id='%1\$s' value='1' %2\$s %3\$s>%4\$s</label></div>", esc_attr( $opt_lossy ), checked( $opt_lossy_val, 1, false ), $disabled, $this->settings['lossy'], $feature_class );
392
+
393
+ //Backup
394
+ printf( "<div class='wp-smush-setting-row%5\$s'><label><input type='checkbox' name='%1\$s' id='%1\$s' value='1' %2\$s %3\$s>%4\$s</label></div>", esc_attr( $opt_backup ), checked( $opt_backup_val, 1, false ), $disabled, $this->settings['backup'], $feature_class ); ?>
395
+ <!-- End of pro-only -->
396
+ </fieldset>
397
  </div>
398
  <!-- End of wrap --><?php
399
  // nonce
400
  wp_nonce_field( 'save_wp_smush_options', 'wp_smush_options_nonce' );
401
  ?>
402
+ <input type="submit" id="wp-smush-save-settings" class="button button-primary" value="<?php _e( 'Save Changes', 'wp-smushit' ); ?>">
403
  </form>
404
+ <?php
405
  }
406
 
407
  /**
472
  if ( $this->exceeding_items_count ) {
473
  $exceed_mb = sprintf(
474
  _n( "%d image is over 1MB so will be skipped using the free version of the plugin.",
475
+ "%d images are over 1MB so will be skipped using the free version of the plugin.", $this->exceeding_items_count, 'wp-smushit' ),
476
  $this->exceeding_items_count
477
  );
478
  }
480
  ?>
481
  <hr>
482
  <div class="bulk-smush">
483
+ <h3><?php _e( 'Smush in Bulk', 'wp-smushit' ) ?></h3>
484
  <?php
485
 
486
  if ( $this->remaining_count == 0 ) {
487
  ?>
488
+ <p><?php _e( "Congratulations, all your images are currently Smushed!", 'wp-smushit' ); ?></p>
489
  <?php
490
  $this->progress_ui();
491
 
494
  } else {
495
  ?>
496
  <div class="smush-instructions">
497
+ <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-smushit' ), $this->remaining_count ); ?></h4>
498
  <?php if ( $exceed_mb ) { ?>
499
  <p class="error">
500
  <?php echo $exceed_mb; ?>
501
+ <a href="<?php echo $this->upgrade_url; ?>"><?php _e( 'Remove size limit &raquo;', 'wp-smushit' ); ?></a>
502
  </p>
503
 
504
  <?php } ?>
505
 
506
  <p><?php _e( "Please be aware, smushing a large number of images can take a while depending on your server and network speed.
507
+ <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-smushit' ); ?></p>
508
 
509
  <?php if ( ! $this->is_pro() ) { ?>
510
  <p class="error">
511
+ <?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-smushit' ), $this->max_free_bulk, $this->max_free_bulk ); ?>
512
+ <a href="<?php echo $this->upgrade_url; ?>"><?php _e( 'Remove limits &raquo;', 'wp-smushit' ); ?></a>
513
  </p>
514
  <?php } ?>
515
 
529
  $auto_smush = get_site_option( WP_SMUSH_PREFIX . 'auto' );
530
  if ( ! $auto_smush && $this->remaining_count == 0 ) {
531
  ?>
532
+ <p><?php printf( __( 'When you <a href="%s">upload some images</a> they will be available to smush here.', 'wp-smushit' ), admin_url( 'media-new.php' ) ); ?></p>
533
+ <?php
534
  } else { ?>
535
  <p>
536
  <?php
537
  // let the user know that there's an alternative
538
+ printf( __( 'You can also smush images individually from your <a href="%s">Media Library</a>.', 'wp-smushit' ), admin_url( 'upload.php' ) );
539
  ?>
540
  </p><?php
541
  }
542
  ?>
543
  </div>
544
+ <?php
545
  }
546
 
547
  function print_loader() {
566
  </div>
567
  </div>
568
  </div>
569
+ <?php
570
  }
571
 
572
  /**
587
  $progress_ui .= '<div id="wp-smush-progress-wrap">
588
  <div id="wp-smush-fetched-progress" class="wp-smush-progressbar"><div style="width:' . $smushed_pc . '%"></div></div>
589
  <p id="wp-smush-compression">'
590
+ . __( "Reduced by ", 'wp-smushit' )
591
  . '<span id="human">' . $this->stats['human'] . '</span> ( <span id="percent">' . number_format_i18n( $this->stats['percent'], 2, '.', '' ) . '</span>% )
592
  </p>
593
  </div>';
598
  <p id="fetched-status">' .
599
  sprintf(
600
  __(
601
+ '<span class="done-count">%d</span> of <span class="total-count">%d</span> total attachments have been smushed', 'wp-smushit'
602
  ), $this->smushed_count, $this->total_count
603
  ) .
604
  '</p>
667
  */
668
  function smush_single() {
669
  if ( ! current_user_can( 'upload_files' ) ) {
670
+ wp_die( __( "You don't have permission to work with uploaded files.", 'wp-smushit' ) );
671
  }
672
 
673
  if ( ! isset( $_GET['attachment_id'] ) ) {
674
+ wp_die( __( 'No attachment ID was provided.', 'wp-smushit' ) );
675
  }
676
 
677
  global $WpSmush;
742
  if ( $this->total_count < 1 ) {
743
  printf(
744
  __(
745
+ '<p>Please <a href="%s">upload some images</a>.</p>', 'wp-smushit'
746
  ), admin_url( 'media-new.php' )
747
  );
748
 
759
  ?>
760
  <p>
761
  <?php
762
+ _e( 'All your images are already smushed!', 'wp-smushit' );
763
  ?>
764
  </p>
765
+ <?php
766
  } else {
767
  $this->selected_ui( $send_ids, '' );
768
  // we have some smushing to do! :)
771
  <p>
772
  <?php
773
  // let the user know that there's an alternative
774
+ printf( __( 'You can also smush images individually from your <a href="%s">Media Library</a>.', 'wp-smushit' ), admin_url( 'upload.php' ) );
775
  ?>
776
  </p>
777
+ <?php
778
  }
779
 
780
  // display the progress bar
785
 
786
  ?>
787
  </div>
788
+ <?php
789
  }
790
 
791
  /**
861
  printf(
862
  __(
863
  '<strong>%d of %d images</strong> were sent for smushing:',
864
+ 'wp-smushit'
865
  ),
866
  count( $send_ids ), count( $received_ids )
867
  );
875
  ?>
876
  </ul>
877
  </div>
878
+ <?php
879
  }
880
 
881
  /**
890
  <button class="button button-primary<?php echo ' ' . $button['class']; ?>" name="smush-all" <?php echo $disabled; ?>>
891
  <span><?php echo $button['text'] ?></span>
892
  </button>
893
+ <?php
894
  }
895
 
896
  function global_stats() {
949
  if ( $super_smush ) {
950
  if ( $this->is_pro() || $this->remaining_count <= $this->max_free_bulk ) { //if premium or under limit
951
 
952
+ $button['text'] = __( 'Bulk Smush Now', 'wp-smushit' );
953
  $button['class'] = 'wp-smush-button wp-smush-send';
954
  } else {
955
  return array();
959
 
960
  // if we have nothing left to smush, disable the buttons
961
  if ( $this->smushed_count === $this->total_count ) {
962
+ $button['text'] = __( 'All Done!', 'wp-smushit' );
963
  $button['class'] = 'wp-smush-finished disabled wp-smush-finished';
964
  $button['disabled'] = 'disabled';
965
 
966
  } else if ( $this->is_pro() || $this->remaining_count <= $this->max_free_bulk ) { //if premium or under limit
967
 
968
+ $button['text'] = __( 'Bulk Smush Now', 'wp-smushit' );
969
  $button['class'] = 'wp-smush-button wp-smush-send';
970
 
971
  } else { //if not premium and over limit
972
+ $button['text'] = sprintf( __( 'Bulk Smush %d Attachments', 'wp-smushit' ), $this->max_free_bulk );
973
  $button['class'] = 'wp-smush-button wp-smush-send';
974
 
975
  }
1018
  function settings_link( $links ) {
1019
 
1020
  $settings_page = admin_url( 'upload.php?page=wp-smush-bulk' );
1021
+ $settings = '<a href="' . $settings_page . '">' . __( 'Settings', 'wp-smushit' ) . '</a>';
1022
 
1023
  array_unshift( $links, $settings );
1024
 
1026
  }
1027
 
1028
  function smush_upgrade() {
1029
+ if ( ! current_user_can( 'edit_others_posts' ) || ! is_super_admin() ) {
1030
  return;
1031
  }
1032
 
1042
  return;
1043
  }
1044
  ?>
1045
+ <div class="updated">
1046
  <a href="<?php echo admin_url( 'index.php' ); ?>?dismiss_smush_upgrade=1" style="float:right;margin-top: 10px;text-decoration: none;"><span class="dashicons dashicons-dismiss" style="color:gray;"></span>Dismiss</a>
1047
 
1048
  <h3><span class="dashicons dashicons-megaphone" style="color:red"></span> Happy Smushing!</h3>
1052
  <p>That means that you can continue smushing your images for free, now with added https support, speed,
1053
  and reliability... enjoy!</p>
1054
 
1055
+ <p>And now, if you'd like to upgrade to the WP Smush Pro plugin you can smush images up to 32MB in size,
1056
  get 'Super Smushing' of, on average, 2&times; more reduction than lossless, backup all non smushed
1057
  images and bulk smush an
1058
  unlimited number of images at once.
1059
  <a href="https://premium.wpmudev.org/?coupon=SMUSH50OFF#pricing"> Click here to upgrade with a 50%
1060
  discount</a>.</p>
1061
  </div>
1062
+ <?php
1063
  }
1064
 
1065
  /**
1145
  return;
1146
  }
1147
 
1148
+ $ss_progress_ui = '<h4>' . __( 'Super-Smush Images', 'wp-smushit' ) . '</h4>';
1149
+ $ss_progress_ui .= '<p>' . __( 'We found attachments that were previously smushed losslessly. If desired you can Super-Smush them now for more savings with almost no noticeable quality loss.', 'wp-smushit' ) . '</p>';
1150
  $ss_progress_ui .= '<div id="progress-ui" class="super-smush">';
1151
 
1152
  // display the progress bars
1154
  <div id="wp-smush-ss-progress" class="wp-smush-progressbar"><div style="width:0%"></div></div>
1155
  <p id="wp-smush-compression">'
1156
  . sprintf(
1157
+ _n( '<span class="remaining-count">%d</span> attachment left to Super-Smush',
1158
+ '<span class="remaining-count">%d</span> attachments left to Super-Smush',
1159
+ count( $this->lossless_ids ),
1160
+ 'wp-smushit' ), count( $this->lossless_ids ), count( $this->lossless_ids ) )
1161
  . '</p>
1162
  </div>
1163
  </div><!-- End of progress ui -->';
1164
  echo $ss_progress_ui;
1165
  $this->setup_button( true );
1166
  }
1167
+
1168
+ /**
1169
+ * Displays the features available in Smush pro
1170
+ */
1171
+ function smush_pro_features() {
1172
+ if ( ! is_super_admin() ) {
1173
+ return;
1174
+ }
1175
+ if ( $this->is_pro() ) { ?>
1176
+ <div class="wp-smpushit-features updated">
1177
+ <h3><?php _e( 'Thanks for using WP Smush Pro! You now can:', 'wp-smushit' ) ?></h3>
1178
+ <ol>
1179
+ <li><?php _e( 'Smush Full size Image, It is skipped by default, if large size is available for a image', 'wp-smushit' ); ?></li>
1180
+ <li><?php _e( '"Super-Smush" your images with our intelligent multi-pass lossy compression. Get 2&times; more compression than lossless with almost no noticeable quality loss!', 'wp-smushit' ); ?></li>
1181
+ <li><?php _e( 'Get the best lossless compression. We try multiple methods to squeeze every last byte out of your images.', 'wp-smushit' ); ?></li>
1182
+ <li><?php _e( 'Smush images up to 32MB.', 'wp-smushit' ); ?></li>
1183
+ <li><?php _e( 'Bulk smush ALL your images with one click!', 'wp-smushit' ); ?></li>
1184
+ <li><?php _e( 'Keep a backup of your original un-smushed images in case you want to restore later.', 'wp-smushit' ); ?></li>
1185
+ </ol>
1186
+ </div>
1187
+ <?php } else { ?>
1188
+ <div class="wp-smpushit-features error">
1189
+ <h3><?php _e( 'Upgrade to WP Smush Pro to:', 'wp-smushit' ) ?></h3>
1190
+ <ol>
1191
+ <li><?php _e( 'Smush Full size Image, It is skipped by default, if large size is available for a image', 'wp-smushit' ); ?></li>
1192
+ <li><?php _e( '"Super-Smush" your images with our intelligent multi-pass lossy compression. Get 2&times; more compression than lossless with almost no noticeable quality loss!', 'wp-smushit' ); ?></li>
1193
+ <li><?php _e( 'Get the best lossless compression. We try multiple methods to squeeze every last byte out of your images.', 'wp-smushit' ); ?></li>
1194
+ <li><?php _e( 'Smush images greater than 1MB.', 'wp-smushit' ); ?></li>
1195
+ <li><?php _e( 'Bulk smush ALL your images with one click! No more rate limiting.', 'wp-smushit' ); ?></li>
1196
+ <li><?php _e( 'Keep a backup of your original un-smushed images in case you want to restore later.', 'wp-smushit' ); ?></li>
1197
+ <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-smushit' ); ?></li>
1198
+ <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-smushit' ); ?></li>
1199
+ </ol>
1200
+ <p>
1201
+ <a class="button-primary" href="<?php echo $this->upgrade_url; ?>"><?php _e( 'Upgrade Now &raquo;', 'wp-smushit' ); ?></a>
1202
+ </p>
1203
+
1204
+ <p><?php _e( 'Already upgraded to a WPMU DEV membership? Install and Login to our Dashboard plugin to enable Smush Pro features.', 'wp-smushit' ); ?></p>
1205
+
1206
+ <p>
1207
+ <?php
1208
+ if ( ! class_exists( 'WPMUDEV_Dashboard' ) ) {
1209
+ if ( file_exists( WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php' ) ) {
1210
+ $function = is_multisite() ? 'network_admin_url' : 'admin_url';
1211
+ $url = wp_nonce_url( $function( 'plugins.php?action=activate&plugin=wpmudev-updates%2Fupdate-notifications.php' ), 'activate-plugin_wpmudev-updates/update-notifications.php' );
1212
+ ?><a class="button-secondary"
1213
+ href="<?php echo $url; ?>"><?php _e( 'Activate WPMU DEV Dashboard', 'wp-smushit' ); ?></a><?php
1214
+ } else { //dashboard not installed at all
1215
+ ?><a class="button-secondary" target="_blank"
1216
+ href="https://premium.wpmudev.org/project/wpmu-dev-dashboard/"><?php _e( 'Install WPMU DEV Dashboard', 'wp-smushit' ); ?></a><?php
1217
+ }
1218
+ }
1219
+ ?>
1220
+ </p>
1221
+ </div>
1222
+ <?php }
1223
+ }
1224
  }
1225
 
1226
  $wpsmushit_admin = new WpSmushitAdmin();
lib/class-wp-smush.php ADDED
@@ -0,0 +1,1062 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once WP_SMUSH_DIR . "lib/class-wp-smush-migrate.php";
3
+ if ( ! class_exists( 'WpSmush' ) ) {
4
+
5
+ class WpSmush {
6
+
7
+ var $version = WP_SMUSH_VERSION;
8
+
9
+ var $is_pro;
10
+
11
+ /**
12
+ * Meta key for api validity
13
+ *
14
+ */
15
+ const VALIDITY_KEY = "wp-smush-valid";
16
+
17
+ /**
18
+ * Api server url to check api key validity
19
+ *
20
+ */
21
+ const API_SERVER = 'https://premium.wpmudev.org/wdp-un.php?action=smushit_check';
22
+
23
+ /**
24
+ * Meta key to save smush result to db
25
+ *
26
+ *
27
+ */
28
+ const SMUSHED_META_KEY = 'wp-smpro-smush-data';
29
+
30
+ /**
31
+ * Meta key to save migrated version
32
+ *
33
+ */
34
+ const MIGRATED_VERSION = "wp-smush-migrated-version";
35
+
36
+ /**
37
+ * Constructor
38
+ */
39
+ function __construct() {
40
+ /**
41
+ * Hooks
42
+ */
43
+ //Check if auto is enabled
44
+ $auto_smush = get_option( WP_SMUSH_PREFIX . 'auto' );
45
+
46
+ //Keep the uto smush on by default
47
+ if ( $auto_smush === false ) {
48
+ $auto_smush = 1;
49
+ }
50
+
51
+ //Auto Smush the new image
52
+ if ( $auto_smush ) {
53
+ add_filter( 'wp_update_attachment_metadata', array(
54
+ $this,
55
+ 'filter_generate_attachment_metadata'
56
+ ), 20, 2 );
57
+ }
58
+
59
+ //Optimise WP Retina 2x images
60
+ add_action( 'wr2x_retina_file_added', array( $this, 'smush_retina_image' ), 20, 3 );
61
+
62
+ //Add Smush Columns
63
+ add_filter( 'manage_media_columns', array( $this, 'columns' ) );
64
+ add_action( 'manage_media_custom_column', array( $this, 'custom_column' ), 10, 2 );
65
+
66
+ //Enqueue Scripts
67
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
68
+
69
+ //Old Smush stats migration
70
+ add_action( "admin_init", array( $this, "migrate" ) );
71
+
72
+ }
73
+
74
+ function admin_init() {
75
+ load_plugin_textdomain( 'wp-smushit', false, dirname( WP_SMUSH_BASENAME ) . '/languages/' );
76
+ wp_enqueue_script( 'common' );
77
+ }
78
+
79
+ /**
80
+ * Process an image with Smush.
81
+ *
82
+ * Returns an array of the $file $results.
83
+ *
84
+ * @param string $file Full absolute path to the image file
85
+ * @param string $file_url Optional full URL to the image file
86
+ *
87
+ * @returns array
88
+ */
89
+ function do_smushit( $file_path = '' ) {
90
+ $errors = new WP_Error();
91
+ if ( empty( $file_path ) ) {
92
+ $errors->add( "empty_path", __( "File path is empty", 'wp-smushit' ) );
93
+ }
94
+
95
+ // check that the file exists
96
+ if ( ! file_exists( $file_path ) || ! is_file( $file_path ) ) {
97
+ $errors->add( "file_not_found", sprintf( __( "Could not find %s", 'wp-smushit' ), $file_path ) );
98
+ }
99
+
100
+ // check that the file is writable
101
+ if ( ! is_writable( dirname( $file_path ) ) ) {
102
+ $errors->add( "not_writable", sprintf( __( "%s is not writable", 'wp-smushit' ), dirname( $file_path ) ) );
103
+ }
104
+
105
+ $file_size = filesize( $file_path );
106
+
107
+ //Check if premium user
108
+ $max_size = $this->is_pro() ? WP_SMUSH_PREMIUM_MAX_BYTES : WP_SMUSH_MAX_BYTES;
109
+
110
+ //Check if file exists
111
+ if ( $file_size == 0 ) {
112
+ $errors->add( "image_not_found", sprintf( __( 'Skipped (%s), image not found.', 'wp-smushit' ), $this->format_bytes( $file_size ) ) );
113
+ }
114
+
115
+ //Check size limit
116
+ if ( $file_size > $max_size ) {
117
+ $errors->add( "size_limit", sprintf( __( 'Skipped (%s), size limit exceeded.', 'wp-smushit' ), $this->format_bytes( $file_size ) ) );
118
+ }
119
+
120
+ if ( count( $errors->get_error_messages() ) ) {
121
+ return $errors;
122
+ }
123
+
124
+ /** Send image for smushing, and fetch the response */
125
+ $response = $this->_post( $file_path, $file_size );
126
+
127
+ if ( ! $response['success'] ) {
128
+ $errors->add( "false_response", $response['message'] );
129
+ }
130
+ //If there is no data
131
+ if ( empty( $response['data'] ) ) {
132
+ $errors->add( "no_data", __( 'Unknown API error', 'wp-smushit' ) );
133
+ }
134
+
135
+ if ( count( $errors->get_error_messages() ) ) {
136
+ return $errors;
137
+ }
138
+
139
+ //If there are no savings, or image returned is bigger in size
140
+ if ( ( ! empty( $response['data']->bytes_saved ) && intval( $response['data']->bytes_saved ) <= 0 )
141
+ || empty( $response['data']->image )
142
+ ) {
143
+ return $response;
144
+ }
145
+ $tempfile = $file_path . ".tmp";
146
+
147
+ //Add the file as tmp
148
+ file_put_contents( $tempfile, $response['data']->image );
149
+
150
+ //handle backups if enabled
151
+ $backup = get_option( WP_SMUSH_PREFIX . 'backup' );
152
+ if ( $backup && $this->is_pro() ) {
153
+ $path = pathinfo( $file_path );
154
+ $backup_name = trailingslashit( $path['dirname'] ) . $path['filename'] . ".bak." . $path['extension'];
155
+ @copy( $file_path, $backup_name );
156
+ }
157
+
158
+ //replace the file
159
+ $success = @rename( $tempfile, $file_path );
160
+
161
+ //if tempfile still exists, unlink it
162
+ if ( file_exists( $tempfile ) ) {
163
+ unlink( $tempfile );
164
+ }
165
+
166
+ //If file renaming failed
167
+ if ( ! $success ) {
168
+ copy( $tempfile, $file_path );
169
+ unlink( $tempfile );
170
+ }
171
+
172
+ //Some servers are having issue with file permission, this should fix it
173
+ chmod($file_path, 0644);
174
+
175
+ return $response;
176
+ }
177
+
178
+ /**
179
+ * Fills $placeholder array with values from $data array
180
+ *
181
+ * @param array $placeholders
182
+ * @param array $data
183
+ *
184
+ * @return array
185
+ */
186
+ private function _array_fill_placeholders( array $placeholders, array $data ) {
187
+ $placeholders['percent'] = $data['compression'];
188
+ $placeholders['bytes'] = $data['bytes_saved'];
189
+ $placeholders['size_before'] = $data['before_size'];
190
+ $placeholders['size_after'] = $data['after_size'];
191
+ $placeholders['time'] = $data['time'];
192
+
193
+ return $placeholders;
194
+ }
195
+
196
+ /**
197
+ * Returns signature for single size of the smush api message to be saved to db;
198
+ *
199
+ * @return array
200
+ */
201
+ private function _get_size_signature() {
202
+ return array(
203
+ 'percent' => - 1,
204
+ 'bytes' => - 1,
205
+ 'size_before' => - 1,
206
+ 'size_after' => - 1,
207
+ 'time' => - 1
208
+ );
209
+ }
210
+
211
+ /**
212
+ * Read the image paths from an attachment's meta data and process each image
213
+ * with wp_smushit().
214
+ *
215
+ * This method also adds a `wp_smushit` meta key for use in the media library.
216
+ * Called after `wp_generate_attachment_metadata` is completed.
217
+ *
218
+ * @param $meta
219
+ * @param null $ID
220
+ *
221
+ * @return mixed
222
+ */
223
+ function resize_from_meta_data( $meta, $ID = null ) {
224
+
225
+ //Flag to check, if original size image should be smushed or not
226
+ $original = get_option( WP_SMUSH_PREFIX . 'original' );
227
+ $smush_full = ( $this->is_pro() && $original == 1 ) ? true : false;
228
+
229
+ $errors = new WP_Error();
230
+ $stats = array(
231
+ "stats" => array_merge( $this->_get_size_signature(), array(
232
+ 'api_version' => - 1,
233
+ 'lossy' => - 1
234
+ )
235
+ ),
236
+ 'sizes' => array()
237
+ );
238
+
239
+ $size_before = $size_after = $compression = $total_time = $bytes_saved = 0;
240
+
241
+ if ( $ID && wp_attachment_is_image( $ID ) === false ) {
242
+ return $meta;
243
+ }
244
+
245
+ //File path and URL for original image
246
+ $attachment_file_path = get_attached_file( $ID );
247
+
248
+ // If images has other registered size, smush them first
249
+ if ( ! empty( $meta['sizes'] ) ) {
250
+
251
+ //if smush original is set to false, otherwise smush
252
+ //Check for large size, we will set a flag to leave the original untouched
253
+ if ( ! $smush_full ) {
254
+ if ( array_key_exists( 'large', $meta['sizes'] ) ) {
255
+ $smush_full = false;
256
+ } else {
257
+ $smush_full = true;
258
+ }
259
+ }
260
+
261
+ foreach ( $meta['sizes'] as $size_key => $size_data ) {
262
+
263
+ // We take the original image. The 'sizes' will all match the same URL and
264
+ // path. So just get the dirname and replace the filename.
265
+ $attachment_file_path_size = trailingslashit( dirname( $attachment_file_path ) ) . $size_data['file'];
266
+
267
+ //Store details for each size key
268
+ $response = $this->do_smushit( $attachment_file_path_size );
269
+
270
+ if ( is_wp_error( $response ) ) {
271
+ return $response;
272
+ }
273
+
274
+ if ( ! empty( $response['data'] ) ) {
275
+ $stats['sizes'][ $size_key ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $response['data'] );
276
+ }
277
+
278
+ //Total Stats, store all data in bytes
279
+ if ( isset( $response['data'] ) ) {
280
+ list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
281
+ = $this->_update_stats_data( $response['data'], $size_before, $size_after, $total_time, $bytes_saved );
282
+ } else {
283
+ $errors->add( "image_size_error" . $size_key, sprintf( __( "Size '%s' not processed correctly", 'wp-smushit' ), $size_key ) );
284
+ }
285
+
286
+ if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
287
+ $stats['stats']['api_version'] = $response['data']->api_version;
288
+ $stats['stats']['lossy'] = $response['data']->lossy;
289
+ }
290
+ }
291
+ }
292
+
293
+ //If original size is supposed to be smushed
294
+ if ( $smush_full ) {
295
+
296
+ $full_image_response = $this->do_smushit( $attachment_file_path );
297
+
298
+ if ( is_wp_error( $full_image_response ) ) {
299
+ return $full_image_response;
300
+ }
301
+
302
+ if ( ! empty( $full_image_response['data'] ) ) {
303
+ $stats['sizes']['full'] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $full_image_response['data'] );
304
+ } else {
305
+ $errors->add( "image_size_error", __( "Size 'full' not processed correctly", 'wp-smushit' ) );
306
+ }
307
+
308
+ //Update stats
309
+ if ( isset( $full_image_response['data'] ) ) {
310
+ list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
311
+ = $this->_update_stats_data( $full_image_response['data'], $size_before, $size_after, $total_time, $bytes_saved );
312
+ } else {
313
+ $errors->add( "image_size_error", __( "Size 'full' not processed correctly", 'wp-smushit' ) );
314
+ }
315
+
316
+ //Api version and lossy, for some images, full image i skipped and for other images only full exists
317
+ //so have to add code again
318
+ if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
319
+ $stats['stats']['api_version'] = $full_image_response['data']->api_version;
320
+ $stats['stats']['lossy'] = $full_image_response['data']->lossy;
321
+ }
322
+
323
+
324
+ }
325
+
326
+ $has_errors = (bool) count( $errors->get_error_messages() );
327
+
328
+ list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
329
+ array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
330
+
331
+ //Set smush status for all the images, store it in wp-smpro-smush-data
332
+ if ( ! $has_errors ) {
333
+
334
+ $existing_stats = get_post_meta( $ID, self::SMUSHED_META_KEY, true );
335
+
336
+ if ( ! empty( $existing_stats ) ) {
337
+ //Update total bytes saved, and compression percent
338
+ $stats['stats']['bytes'] = isset( $existing_stats['stats']['bytes'] ) ? $existing_stats['stats']['bytes'] + $stats['stats']['bytes'] : $stats['stats']['bytes'];
339
+ $stats['stats']['percent'] = isset( $existing_stats['stats']['percent'] ) ? $existing_stats['stats']['percent'] + $stats['stats']['percent'] : $stats['stats']['percent'];
340
+
341
+ //Update stats for each size
342
+ if ( isset( $existing_stats['sizes'] ) && ! empty( $stats['sizes'] ) ) {
343
+
344
+ foreach ( $existing_stats['sizes'] as $size_name => $size_stats ) {
345
+ //if stats for a particular size doesn't exists
346
+ if ( empty( $stats['sizes'][ $size_name ] ) ) {
347
+ $stats['sizes'][ $size_name ] = $existing_stats['sizes'][ $size_name ];
348
+ } else {
349
+ //Update compression percent and bytes saved for each size
350
+ $stats['sizes'][ $size_name ]->bytes = $stats['sizes'][ $size_name ]->bytes + $existing_stats['sizes'][ $size_name ]->bytes;
351
+ $stats['sizes'][ $size_name ]->percent = $stats['sizes'][ $size_name ]->percent + $existing_stats['sizes'][ $size_name ]->percent;
352
+ }
353
+ }
354
+ }
355
+ }
356
+ update_post_meta( $ID, self::SMUSHED_META_KEY, $stats );
357
+ }
358
+
359
+ return $meta;
360
+ }
361
+
362
+ /**
363
+ * Read the image paths from an attachment's meta data and process each image
364
+ * with wp_smushit()
365
+ *
366
+ * Filters wp_generate_attachment_metadata
367
+ *
368
+ * @uses WpSmush::resize_from_meta_data
369
+ *
370
+ * @param $meta
371
+ * @param null $ID
372
+ *
373
+ * @return mixed
374
+ */
375
+ function filter_generate_attachment_metadata( $meta, $ID = null ) {
376
+ //Update API url for Hostgator
377
+
378
+ //Check for use of http url, (Hostgator mostly)
379
+ $use_http = wp_cache_get( WP_SMUSH_PREFIX.'use_http', 'smush' );
380
+ if( !$use_http ) {
381
+ $use_http = get_option( WP_SMUSH_PREFIX.'use_http' );
382
+ wp_cache_add( WP_SMUSH_PREFIX.'use_http', $use_http, 'smush' );
383
+ }
384
+ $use_http ? define( 'WP_SMUSH_API_HTTP', 'http://smushpro.wpmudev.org/1.0/') : '';
385
+
386
+ $this->resize_from_meta_data( $meta, $ID );
387
+
388
+ return $meta;
389
+ }
390
+
391
+
392
+ /**
393
+ * Posts an image to Smush.
394
+ *
395
+ * @param $file_path path of file to send to Smush
396
+ * @param $file_size
397
+ *
398
+ * @return bool|array array containing success status, and stats
399
+ */
400
+ function _post( $file_path, $file_size ) {
401
+
402
+ $data = false;
403
+
404
+ $file = @fopen( $file_path, 'r' );
405
+ $file_data = fread( $file, $file_size );
406
+ $headers = array(
407
+ 'accept' => 'application/json', // The API returns JSON
408
+ 'content-type' => 'application/binary', // Set content type to binary
409
+ );
410
+
411
+ //Check if premium member, add API key
412
+ $api_key = $this->_get_api_key();
413
+ if ( ! empty( $api_key ) ) {
414
+ $headers['apikey'] = $api_key;
415
+ }
416
+
417
+ //Check if lossy compression allowed and add it to headers
418
+ $lossy = get_option( WP_SMUSH_PREFIX . 'lossy' );
419
+
420
+ if ( $lossy && $this->is_pro() ) {
421
+ $headers['lossy'] = 'true';
422
+ } else {
423
+ $headers['lossy'] = 'false';
424
+ }
425
+
426
+ $api_url = defined( 'WP_SMUSH_API_HTTP' ) ? WP_SMUSH_API_HTTP : WP_SMUSH_API;
427
+ $args = array(
428
+ 'headers' => $headers,
429
+ 'body' => $file_data,
430
+ 'timeout' => WP_SMUSH_TIMEOUT,
431
+ 'user-agent' => WP_SMUSH_UA,
432
+ );
433
+ $result = wp_remote_post( $api_url, $args );
434
+
435
+ //Close file connection
436
+ fclose( $file );
437
+ unset( $file_data );//free memory
438
+ if ( is_wp_error( $result ) ) {
439
+
440
+ $er_msg = $result->get_error_message();
441
+
442
+ //Hostgator Issue
443
+ if ( ! empty( $er_msg ) && strpos( $er_msg, 'SSL CA cert' ) !== false ) {
444
+ //Update DB for using http protocol
445
+ update_option( WP_SMUSH_PREFIX . 'use_http', 1 );
446
+ }
447
+ //Handle error
448
+ $data['message'] = sprintf( __( 'Error posting to API: %s', 'wp-smushit' ), $result->get_error_message() );
449
+ $data['success'] = false;
450
+ unset( $result ); //free memory
451
+ return $data;
452
+ } else if ( '200' != wp_remote_retrieve_response_code( $result ) ) {
453
+ //Handle error
454
+ $data['message'] = sprintf( __( 'Error posting to API: %s %s', 'wp-smushit' ), wp_remote_retrieve_response_code( $result ), wp_remote_retrieve_response_message( $result ) );
455
+ $data['success'] = false;
456
+ unset( $result ); //free memory
457
+
458
+ return $data;
459
+ }
460
+
461
+ //If there is a response and image was successfully optimised
462
+ $response = json_decode( $result['body'] );
463
+ if ( $response && $response->success == true ) {
464
+
465
+ //If there is any savings
466
+ if ( $response->data->bytes_saved > 0 ) {
467
+ $image = base64_decode( $response->data->image ); //base64_decode is necessary to send binary img over JSON, no security problems here!
468
+ $image_md5 = md5( $response->data->image );
469
+ if ( $response->data->image_md5 != $image_md5 ) {
470
+ //Handle error
471
+ $data['message'] = __( 'Smush data corrupted, try again.', 'wp-smushit' );
472
+ $data['success'] = false;
473
+ unset( $image );//free memory
474
+ } else {
475
+ $data['success'] = true;
476
+ $data['data'] = $response->data;
477
+ $data['data']->image = $image;
478
+ unset( $image );//free memory
479
+ }
480
+ } else {
481
+ //just return the data
482
+ $data['success'] = true;
483
+ $data['data'] = $response->data;
484
+ }
485
+ } else {
486
+ //Server side error, get message from response
487
+ $data['message'] = ! empty( $response->data ) ? $response->data : __( "Image couldn't be smushed", 'wp-smushit' );
488
+ $data['success'] = false;
489
+ }
490
+
491
+ unset( $result );//free memory
492
+ unset( $response );//free memory
493
+ return $data;
494
+ }
495
+
496
+
497
+ /**
498
+ * Print column header for Smush results in the media library using
499
+ * the `manage_media_columns` hook.
500
+ */
501
+ function columns( $defaults ) {
502
+ $defaults['smushit'] = 'WP Smush';
503
+
504
+ return $defaults;
505
+ }
506
+
507
+ /**
508
+ * Return the filesize in a humanly readable format.
509
+ * Taken from http://www.php.net/manual/en/function.filesize.php#91477
510
+ */
511
+ function format_bytes( $bytes, $precision = 2 ) {
512
+ $units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
513
+ $bytes = max( $bytes, 0 );
514
+ $pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
515
+ $pow = min( $pow, count( $units ) - 1 );
516
+ $bytes /= pow( 1024, $pow );
517
+
518
+ return round( $bytes, $precision ) . ' ' . $units[ $pow ];
519
+ }
520
+
521
+ /**
522
+ * Print column data for Smush results in the media library using
523
+ * the `manage_media_custom_column` hook.
524
+ */
525
+ function custom_column( $column_name, $id ) {
526
+ if ( 'smushit' == $column_name ) {
527
+ $this->set_status( $id );
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Check if user is premium member, check for api key
533
+ *
534
+ * @return mixed|string
535
+ */
536
+ function is_pro() {
537
+
538
+ if ( isset( $this->is_pro ) ) {
539
+ return $this->is_pro;
540
+ }
541
+
542
+ //no api key set, always false
543
+ $api_key = $this->_get_api_key();
544
+ if ( empty( $api_key ) ) {
545
+ return false;
546
+ }
547
+
548
+ $key = "wp-smush-premium-" . substr( $api_key, - 10, 10 ); //add last 10 chars of apikey to transient key in case it changes
549
+ if ( false === ( $valid = get_site_transient( $key ) ) ) {
550
+ // call api
551
+ $url = self::API_SERVER . '&key=' . urlencode( $api_key );
552
+
553
+ $request = wp_remote_get( $url, array(
554
+ "user-agent" => WP_SMUSH_UA,
555
+ "timeout" => 3
556
+ )
557
+ );
558
+
559
+ if ( ! is_wp_error( $request ) && '200' == wp_remote_retrieve_response_code( $request ) ) {
560
+ $result = json_decode( wp_remote_retrieve_body( $request ) );
561
+ if ( $result && $result->success ) {
562
+ $valid = true;
563
+ set_site_transient( $key, 1, 12 * HOUR_IN_SECONDS );
564
+ } else {
565
+ $valid = false;
566
+ set_site_transient( $key, 0, 30 * MINUTE_IN_SECONDS ); //cache failure much shorter
567
+ }
568
+
569
+ } else {
570
+ $valid = false;
571
+ set_site_transient( $key, 0, 5 * MINUTE_IN_SECONDS ); //cache network failure even shorter, we don't want a request every pageload
572
+ }
573
+
574
+ }
575
+
576
+ $this->is_pro = (bool) $valid;
577
+
578
+ return $this->is_pro;
579
+ }
580
+
581
+ /**
582
+ * Returns api key
583
+ *
584
+ * @return mixed
585
+ */
586
+ private function _get_api_key() {
587
+ //Try to fetch it from Cache
588
+ $api_key = wp_cache_get( 'wpmudev_apikey', 'smush' );
589
+
590
+ //If not available, get it from other means, and set it in cache
591
+ if ( ! $api_key ) {
592
+ if ( defined( 'WPMUDEV_APIKEY' ) ) {
593
+ $api_key = WPMUDEV_APIKEY;
594
+ } else {
595
+ $api_key = get_site_option( 'wpmudev_apikey' );
596
+ }
597
+ if ( $api_key ) {
598
+ wp_cache_add( "wpmudev_apikey", $api_key, 'smush', 6000 );
599
+ }
600
+ }
601
+
602
+ return $api_key;
603
+ }
604
+
605
+
606
+ /**
607
+ * Checks if image is already smushed
608
+ *
609
+ * @param int $id
610
+ * @param array $data
611
+ *
612
+ * @return bool|mixed
613
+ */
614
+ function is_smushed( $id, $data = null ) {
615
+
616
+ //For new images
617
+ $wp_is_smushed = get_post_meta( $id, 'wp-is-smushed', true );
618
+
619
+ //Not smushed, backward compatibility, check attachment metadata
620
+ if ( ! $wp_is_smushed && $data !== null ) {
621
+ if ( isset( $data['wp_smushit'] ) && ! empty( $data['wp_smushit'] ) ) {
622
+ $wp_is_smushed = true;
623
+ }
624
+ }
625
+
626
+ return $wp_is_smushed;
627
+ }
628
+
629
+ /**
630
+ * Returns size saved from the api call response
631
+ *
632
+ * @param string $message
633
+ *
634
+ * @return string|bool
635
+ */
636
+ function get_saved_size( $message ) {
637
+ if ( preg_match( '/\((.*)\)/', $message, $matches ) ) {
638
+ return isset( $matches[1] ) ? $matches[1] : false;
639
+ }
640
+
641
+ return false;
642
+ }
643
+
644
+ /**
645
+ * Set send button status
646
+ *
647
+ * @param $id
648
+ * @param bool $echo
649
+ * @param bool $text_only
650
+ *
651
+ * @return string|void
652
+ */
653
+ function set_status( $id, $echo = true, $text_only = false ) {
654
+ $status_txt = $button_txt = '';
655
+ $show_button = false;
656
+
657
+ //Stats are not received properly, otherwise
658
+ // wp_cache_delete( $id, 'post_meta' );
659
+
660
+ $wp_smush_data = get_post_meta( $id, self::SMUSHED_META_KEY, true );
661
+ $attachment_data = wp_get_attachment_metadata( $id );
662
+ //
663
+ // if the image is smushed
664
+ if ( ! empty( $wp_smush_data ) ) {
665
+
666
+ $image_count = count( $wp_smush_data['sizes'] );
667
+ $bytes = isset( $wp_smush_data['stats']['bytes'] ) ? $wp_smush_data['stats']['bytes'] : 0;
668
+ $bytes_readable = ! empty( $bytes ) ? $this->format_bytes( $bytes ) : '';
669
+ $percent = isset( $wp_smush_data['stats']['percent'] ) ? $wp_smush_data['stats']['percent'] : 0;
670
+ $percent = $percent < 0 ? 0 : $percent;
671
+
672
+ if ( isset( $wp_smush_data['stats']['size_before'] ) && $wp_smush_data['stats']['size_before'] == 0 ) {
673
+ $status_txt = __( 'Error processing request', 'wp-smushit' );
674
+ $show_button = true;
675
+ } else {
676
+ if ( $bytes == 0 || $percent == 0 ) {
677
+ $status_txt = __( 'Already Optimized', 'wp-smushit' );
678
+ } elseif ( ! empty( $percent ) && ! empty( $bytes_readable ) ) {
679
+ $status_txt = $image_count > 1 ? sprintf( __( "%d images reduced ", 'wp-smushit' ), $image_count ) : __( "Reduced ", 'wp-smushit' );
680
+ $status_txt .= sprintf( __( "by %s ( %01.1f%% )", 'wp-smushit' ), $bytes_readable, number_format_i18n( $percent, 2, '.', '' ) );
681
+
682
+ //Detailed Stats Link
683
+ $status_txt .= '<br /><a href="#" class="smush-stats-details">' . esc_html__( "Smush stats", 'wp-smushit' ) . ' [<span class="stats-toggle">+</span>]</a>';
684
+
685
+ //Stats
686
+ $status_txt .= $this->get_detailed_stats( $id, $wp_smush_data, $attachment_data );
687
+ }
688
+ }
689
+
690
+ //IF current compression is lossy
691
+ if ( ! empty( $wp_smush_data ) && ! empty( $wp_smush_data['stats'] ) ) {
692
+ $lossy = ! empty( $wp_smush_data['stats']['lossy'] ) ? $wp_smush_data['stats']['lossy'] : '';
693
+ $is_lossy = $lossy == 1 ? true : false;
694
+ }
695
+
696
+ //Check if Lossy enabled
697
+ $opt_lossy = WP_SMUSH_PREFIX . 'lossy';
698
+ $opt_lossy_val = get_option( $opt_lossy, false );
699
+
700
+ //Check image type
701
+ $image_type = get_post_mime_type( $id );
702
+
703
+ //Check if premium user, compression was lossless, and lossy compression is enabled
704
+ if ( $this->is_pro() && ! $is_lossy && $opt_lossy_val && $image_type != 'image/gif' ) {
705
+ // the button text
706
+ $button_txt = __( 'Super-Smush', 'wp-smushit' );
707
+ $show_button = true;
708
+ }
709
+ } else {
710
+
711
+ // the status
712
+ $status_txt = __( 'Not processed', 'wp-smushit' );
713
+
714
+ // we need to show the smush button
715
+ $show_button = true;
716
+
717
+ // the button text
718
+ $button_txt = __( 'Smush Now!', 'wp-smushit' );
719
+ }
720
+ if ( $text_only ) {
721
+ return $status_txt;
722
+ }
723
+
724
+ $text = $this->column_html( $id, $status_txt, $button_txt, $show_button, $wp_smush_data, $echo );
725
+ if ( ! $echo ) {
726
+ return $text;
727
+ }
728
+ }
729
+
730
+ /**
731
+ * Print the column html
732
+ *
733
+ * @param string $id Media id
734
+ * @param string $status_txt Status text
735
+ * @param string $button_txt Button label
736
+ * @param boolean $show_button Whether to shoe the button
737
+ *
738
+ * @return null
739
+ */
740
+ function column_html( $id, $status_txt = "", $button_txt = "", $show_button = true, $smushed = false, $echo = true ) {
741
+ $allowed_images = array( 'image/jpeg', 'image/jpg', 'image/png', 'image/gif' );
742
+
743
+ // don't proceed if attachment is not image, or if image is not a jpg, png or gif
744
+ if ( ! wp_attachment_is_image( $id ) || ! in_array( get_post_mime_type( $id ), $allowed_images ) ) {
745
+ return;
746
+ }
747
+
748
+ $class = $smushed ? '' : ' hidden';
749
+ $html = '
750
+ <p class="smush-status' . $class . '">' . $status_txt . '</p>';
751
+ // if we aren't showing the button
752
+ if ( ! $show_button ) {
753
+ if ( $echo ) {
754
+ echo $html;
755
+
756
+ return;
757
+ } else {
758
+ if ( ! $smushed ) {
759
+ $class = ' currently-smushing';
760
+ } else {
761
+ $class = ' smushed';
762
+ }
763
+
764
+ return '<div class="smush-wrap' . $class . '">' . $html . '</div>';
765
+ }
766
+ }
767
+ if ( ! $echo ) {
768
+ $html .= '
769
+ <button class="button button-primary wp-smush-send" data-id="' . $id . '">
770
+ <span>' . $button_txt . '</span>
771
+ </button>';
772
+ if ( ! $smushed ) {
773
+ $class = ' unsmushed';
774
+ } else {
775
+ $class = ' smushed';
776
+ }
777
+
778
+ return '<div class="smush-wrap' . $class . '">' . $html . '</div>';
779
+ } else {
780
+ $html .= '<button class="button wp-smush-send" data-id="' . $id . '">
781
+ <span>' . $button_txt . '</span>
782
+ </button>';
783
+ echo $html;
784
+ }
785
+ }
786
+
787
+ /**
788
+ * Migrates smushit api message to the latest structure
789
+ *
790
+ *
791
+ * @return void
792
+ */
793
+ function migrate() {
794
+
795
+ if ( ! version_compare( $this->version, "1.7.1", "lte" ) ) {
796
+ return;
797
+ }
798
+
799
+ $migrated_version = get_option( self::MIGRATED_VERSION );
800
+
801
+ if ( $migrated_version === $this->version ) {
802
+ return;
803
+ }
804
+
805
+ global $wpdb;
806
+
807
+ $q = $wpdb->prepare( "SELECT * FROM `" . $wpdb->postmeta . "` WHERE `meta_key`=%s AND `meta_value` LIKE %s ", "_wp_attachment_metadata", "%wp_smushit%" );
808
+ $results = $wpdb->get_results( $q );
809
+
810
+ if ( count( $results ) < 1 ) {
811
+ return;
812
+ }
813
+
814
+ $migrator = new WpSmushMigrate();
815
+ foreach ( $results as $attachment_meta ) {
816
+ $migrated_message = $migrator->migrate_api_message( maybe_unserialize( $attachment_meta->meta_value ) );
817
+ if ( $migrated_message !== array() ) {
818
+ update_post_meta( $attachment_meta->post_id, self::SMUSHED_META_KEY, $migrated_message );
819
+ }
820
+ }
821
+
822
+ update_option( self::MIGRATED_VERSION, $this->version );
823
+
824
+ }
825
+
826
+ /**
827
+ * @param Object $response_data
828
+ * @param $size_before
829
+ * @param $size_after
830
+ * @param $total_time
831
+ * @param $bytes_saved
832
+ *
833
+ * @return array
834
+ */
835
+ private function _update_stats_data( $response_data, $size_before, $size_after, $total_time, $bytes_saved ) {
836
+ $size_before += ! empty( $response_data->before_size ) ? (int) $response_data->before_size : 0;
837
+ $size_after += ( ! empty( $response_data->after_size ) && $response_data->after_size > 0 ) ? (int) $response_data->after_size : (int) $response_data->before_size;
838
+ $total_time += ! empty( $response_data->time ) ? (float) $response_data->time : 0;
839
+ $bytes_saved += ( ! empty( $response_data->bytes_saved ) && $response_data->bytes_saved > 0 ) ? $response_data->bytes_saved : 0;
840
+ $compression = ( $bytes_saved > 0 && $size_before > 0 ) ? ( ( $bytes_saved / $size_before ) * 100 ) : 0;
841
+
842
+ return array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
843
+ }
844
+
845
+ /**
846
+ * Updates the smush stats for a single image size
847
+ * @param $id
848
+ * @param $stats
849
+ * @param $image_size
850
+ */
851
+ function update_smush_stats_single( $id, $smush_stats, $image_size = '' ) {
852
+ //Return, if we don't have image id or stats for it
853
+ if ( empty( $id ) || empty( $smush_stats ) || empty( $image_size ) ) {
854
+ return false;
855
+ }
856
+ $image_size = $image_size . '@2x';
857
+ $data = $smush_stats['data'];
858
+ //Get existing Stats
859
+ $stats = get_post_meta( $id, self::SMUSHED_META_KEY, true );
860
+ //Update existing Stats
861
+ if ( ! empty( $stats ) ) {
862
+ //Update total bytes saved, and compression percent
863
+ //Update Main Stats
864
+ list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
865
+ $this->_update_stats_data( $data, $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['bytes'] );
866
+
867
+
868
+ //Update stats for each size
869
+ if ( isset( $stats['sizes'] ) ) {
870
+
871
+ //if stats for a particular size doesn't exists
872
+ if ( empty( $stats['sizes'][ $image_size ] ) ) {
873
+ //Update size wise details
874
+ $stats['sizes'][ $image_size ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $data );
875
+ } else {
876
+ //Update compression percent and bytes saved for each size
877
+ $stats['sizes'][ $image_size ]->bytes = $stats['sizes'][ $image_size ]->bytes + $data->bytes_saved;
878
+ $stats['sizes'][ $image_size ]->percent = $stats['sizes'][ $image_size ]->percent + $data->compression;
879
+ }
880
+ }
881
+ } else {
882
+ //Create new stats
883
+ $stats = array(
884
+ "stats" => array_merge( $this->_get_size_signature(), array(
885
+ 'api_version' => - 1,
886
+ 'lossy' => - 1
887
+ )
888
+ ),
889
+ 'sizes' => array()
890
+ );
891
+ $stats['stats']['api_version'] = $data->api_version;
892
+ $stats['stats']['lossy'] = $data->lossy;
893
+ //Update Main Stats
894
+ list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
895
+ array( $data->before_size, $data->after_size, $data->time, $data->compression, $data->bytes_saved );
896
+ //Update size wise details
897
+ $stats['sizes'][ $image_size ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $data );
898
+ }
899
+ //Calculate Percent
900
+ update_post_meta( $id, self::SMUSHED_META_KEY, $stats );
901
+
902
+ }
903
+
904
+ function smush_retina_image( $id, $retina_file, $image_size ) {
905
+
906
+ $stats = $this->do_smushit( $retina_file );
907
+ //If we squeezed out something, Update stats
908
+ if ( ! empty( $stats['data'] ) && isset( $stats['data'] ) && $stats['data']->bytes_saved > 0 ) {
909
+ $this->update_smush_stats_single( $id, $stats, $image_size );
910
+ }
911
+ }
912
+
913
+ /**
914
+ * Return a list of images not smushed and reason
915
+ * @param $image_id
916
+ * @param $size_stats
917
+ * @param $attachment_metadata
918
+ *
919
+ * @return array
920
+ */
921
+ function get_skipped_images( $image_id, $size_stats, $attachment_metadata ) {
922
+ $skipped = array();
923
+
924
+ //Get a list of all the sizes, Show skipped images
925
+ $media_size = get_intermediate_image_sizes();
926
+
927
+ //Full size
928
+ $full_image = get_attached_file( $image_id );
929
+
930
+ //If full image was not smushed, reason 1. Large Size logic, 2. Free and greater than 1Mb
931
+ if ( ! array_key_exists( 'full', $size_stats ) ) {
932
+ //For free version, Check the image size
933
+ if ( ! $this->is_pro() ) {
934
+ //For free version, check if full size is greater than 1 Mb, show the skipped status
935
+ $file_size = filesize( $full_image );
936
+ if ( ( $file_size / WP_SMUSH_MAX_BYTES ) > 1 ) {
937
+ $skipped[] = array(
938
+ 'size' => 'full',
939
+ 'reason' => 'size_limit'
940
+ );
941
+ }else{
942
+ $skipped[] = array(
943
+ 'size' => 'full',
944
+ 'reason' => 'large_size'
945
+ );
946
+ }
947
+ } else {
948
+ //Paid version, Check if we have large size
949
+ if ( array_key_exists( 'large', $size_stats ) ) {
950
+ $skipped[] = array(
951
+ 'size' => 'full',
952
+ 'reason' => 'large_size'
953
+ );
954
+ }
955
+
956
+ }
957
+ }
958
+ //For other sizes, check if the image was generated and not available in stats
959
+ if ( is_array( $media_size ) ) {
960
+ foreach ( $media_size as $size ) {
961
+ if ( array_key_exists( $size, $attachment_metadata['sizes'] ) && ! array_key_exists( $size, $size_stats ) ) {
962
+ //Image Path
963
+ $img_path = trailingslashit( dirname( $full_image ) ) . $size['file'];
964
+ $image_size = filesize( $img_path );
965
+ if ( ( $image_size / WP_SMUSH_MAX_BYTES ) > 1 ) {
966
+ $skipped[] = array(
967
+ 'size' => 'full',
968
+ 'reason' => 'size_limit'
969
+ );
970
+ }
971
+ }
972
+ }
973
+ }
974
+ return $skipped;
975
+ }
976
+
977
+ /**
978
+ * Skip messages respective to their ids
979
+ * @param $msg_id
980
+ *
981
+ * @return bool
982
+ */
983
+ function skip_reason( $msg_id ) {
984
+ $skip_msg = array(
985
+ 'large_size' => esc_html__('Large size available for the image.', 'wp-smushit'),
986
+ 'size_limit' => esc_html__('Image exceeded the 1Mb size limit.')
987
+ );
988
+ $skip_rsn = !empty( $skip_msg[$msg_id ] ) ? esc_html__(" Skipped", 'wp-smushit', 'wp-smushit'): '';
989
+ $skip_rsn = ! empty( $skip_rsn ) ? $skip_rsn . '<span class="dashicons dashicons-editor-help" title="' . $skip_msg[ $msg_id ] . '"></span>' : '';
990
+ return $skip_rsn;
991
+ }
992
+
993
+ /**
994
+ * Shows the image size and the compression for each of them
995
+ * @param $image_id
996
+ * @param $wp_smush_data
997
+ *
998
+ * @return string
999
+ */
1000
+ function get_detailed_stats( $image_id, $wp_smush_data, $attachment_metadata ) {
1001
+ $stats = '<div id="smush-stats-' . $image_id . '" class="smush-stats-wrapper hidden">
1002
+ <table class="wp-smush-stats-holder">
1003
+ <thead>
1004
+ <tr>
1005
+ <th><strong>' . esc_html__( 'Image size', 'wp-smushit' ) . '</strong></th>
1006
+ <th><strong>' . esc_html__( 'Savings', 'wp-smushit' ) . '</strong></th>
1007
+ </tr>
1008
+ </thead>
1009
+ <tbody>';
1010
+ $size_stats = $wp_smush_data['sizes'];
1011
+
1012
+ //Reorder Sizes as per the maximum savings
1013
+ uasort( $size_stats, array( $this, "cmp" ) );
1014
+
1015
+ //Get skipped images
1016
+ $skipped = $this->get_skipped_images($image_id, $size_stats, $attachment_metadata );
1017
+
1018
+ if ( ! empty( $skipped ) ) {
1019
+ foreach ( $skipped as $img_data ) {
1020
+ $stats .= '<tr>
1021
+ <td>' . strtoupper( $img_data['size'] ) . '</td>
1022
+ <td class="smush-skipped error">' . $this->skip_reason( $img_data['reason'] ) . '</td>
1023
+ </tr>';
1024
+ }
1025
+
1026
+ }
1027
+ //Show Sizes and their compression
1028
+ foreach ( $size_stats as $size_key => $size_stats ) {
1029
+ if ( $size_stats->bytes > 0 ) {
1030
+ $stats .= '<tr>
1031
+ <td>' . strtoupper( $size_key ) . '</td>
1032
+ <td>' . $this->format_bytes( $size_stats->bytes ) . '</td>
1033
+ </tr>';
1034
+ }
1035
+ }
1036
+ $stats .= '</tbody>
1037
+ </table>
1038
+ </div>';
1039
+
1040
+ return $stats;
1041
+ }
1042
+
1043
+ /**
1044
+ * Compare Values
1045
+ * @param $a
1046
+ * @param $b
1047
+ *
1048
+ * @return int
1049
+ */
1050
+ function cmp($a, $b) {
1051
+ return $a->bytes < $b->bytes;
1052
+ }
1053
+ }
1054
+
1055
+ global $WpSmush;
1056
+ $WpSmush = new WpSmush();
1057
+
1058
+ }
1059
+
1060
+ //Include Admin classes
1061
+ require_once( WP_SMUSH_DIR . 'lib/class-wp-smush-bulk.php' );
1062
+ require_once( WP_SMUSH_DIR . 'lib/class-wp-smush-admin.php' );
readme.txt CHANGED
@@ -1,13 +1,13 @@
1
  === WP Smush ===
2
  Plugin Name: WP Smush
3
- Version: 2.0.6
4
  Author: WPMU DEV
5
  Author URI: http://premium.wpmudev.org/
6
  Contributors: WPMUDEV, alexdunae
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.6
11
  License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12
 
13
  Reduce image file sizes, improve performance and boost your SEO using the free <a href="https://premium.wpmudev.org/">WPMU DEV</a> WordPress Smush API.
@@ -39,7 +39,7 @@ Install WP Smush and find out why it's the most popular image optimization plugi
39
  <ul>
40
  <li>"Super-Smush" your images with our intelligent multi-pass lossy compression. Get over 2x more compression than lossless with almost no noticeable quality loss!</li>
41
  <li>Get even better lossless compression. We try multiple methods to squeeze every last byte out of your images.</li>
42
- <li>Smush images up to 8MB (WP Smush is limited to 1MB)</li>
43
  <li>Bulk smush ALL your images with one click! No more rate limiting.</li>
44
  <li>Keep a backup of your original un-smushed images in case you want to restore later.</li>
45
  <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>
@@ -81,6 +81,26 @@ Yahoo's Smush.it API is gone forever. So WPMU DEV built our own free API that is
81
 
82
  == Changelog ==
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  = 2.0.6 =
85
 
86
  * Fixed: Conflict with various themes while editing post and page
1
  === WP Smush ===
2
  Plugin Name: WP Smush
3
+ Version: 2.0.6.3
4
  Author: WPMU DEV
5
  Author URI: http://premium.wpmudev.org/
6
  Contributors: WPMUDEV, alexdunae
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.3
10
+ Stable tag: 2.0.6.3
11
  License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12
 
13
  Reduce image file sizes, improve performance and boost your SEO using the free <a href="https://premium.wpmudev.org/">WPMU DEV</a> WordPress Smush API.
39
  <ul>
40
  <li>"Super-Smush" your images with our intelligent multi-pass lossy compression. Get over 2x more compression than lossless with almost no noticeable quality loss!</li>
41
  <li>Get even better lossless compression. We try multiple methods to squeeze every last byte out of your images.</li>
42
+ <li>Smush images up to 32MB (WP Smush is limited to 1MB)</li>
43
  <li>Bulk smush ALL your images with one click! No more rate limiting.</li>
44
  <li>Keep a backup of your original un-smushed images in case you want to restore later.</li>
45
  <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>
81
 
82
  == Changelog ==
83
 
84
+ = 2.0.6.3 =
85
+
86
+ * Fixed: Change File permission after replacing image
87
+ * Fixed: Directory path for files
88
+ * Fixed: Workaround for Auto Smush issue on Hostgator
89
+ * Fixed: Smush button doesn't works in media library dialog on post screen, when add media is clicked
90
+ (https://wordpress.org/support/topic/like-wp-smush-a-lot)
91
+ * New: Show number of images smushed in stats column
92
+ * Added: Support for WP Retina 2x Plugin
93
+ * Added: Filter `WP_SMUSH_API_TIMEOUT` to change the default time out value from 60s
94
+ * Added: Smush original image option (Pro Only)
95
+
96
+ = 2.0.6.2 =
97
+
98
+ * Use string for text domain instead of PHP Constant ( WordPress Guideline )
99
+
100
+ = 2.0.6.1 =
101
+
102
+ * Updated: Max image size limit to 32Mb for Pro Version
103
+
104
  = 2.0.6 =
105
 
106
  * Fixed: Conflict with various themes while editing post and page
wp-smush.php CHANGED
@@ -4,9 +4,9 @@ Plugin Name: WP Smush
4
  Plugin URI: http://wordpress.org/extend/plugins/wp-smushit/
5
  Description: Reduce image file sizes, improve performance and boost your SEO using the free <a href="https://premium.wpmudev.org/">WPMU DEV</a> WordPress Smush API.
6
  Author: WPMU DEV
7
- Version: 2.0.6
8
  Author URI: http://premium.wpmudev.org/
9
- Textdomain: wp_smush
10
  */
11
 
12
  /*
@@ -36,836 +36,111 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36
  * Constants
37
  */
38
  $prefix = 'WP_SMUSH_';
39
- $version = '2.0.6';
40
- $smush_constatns = array(
41
- 'VERSON' => $version,
 
 
 
 
 
 
42
  'BASENAME' => plugin_basename( __FILE__ ),
43
  'API' => 'https://smushpro.wpmudev.org/1.0/',
44
- 'DOMAIN' => 'wp_smush',
45
  'UA' => 'WP Smush/' . $version . '; ' . network_home_url(),
46
  'DIR' => plugin_dir_path( __FILE__ ),
47
  'URL' => plugin_dir_url( __FILE__ ),
48
  'MAX_BYTES' => 1000000,
49
- 'PREMIUM_MAX_BYTES' => 8000000,
50
  'PREFIX' => 'wp-smush-',
51
- 'TIMEOUT' => 30
52
-
53
  );
54
 
55
- foreach ( $smush_constatns as $const_name => $constant_val ) {
56
  if ( ! defined( $prefix . $const_name ) ) {
57
  define( $prefix . $const_name, $constant_val );
58
  }
59
  }
60
-
61
- require_once WP_SMUSH_DIR . "lib/class-wp-smush-migrate.php";
62
-
63
- if ( ! class_exists( 'WpSmush' ) ) {
64
-
65
- class WpSmush {
66
-
67
- var $version = WP_SMUSH_VERSON;
68
-
69
- var $is_pro;
70
-
71
- /**
72
- * Meta key for api validity
73
- *
74
- */
75
- const VALIDITY_KEY = "wp-smush-valid";
76
-
77
- /**
78
- * Api server url to check api key validity
79
- *
80
- */
81
- const API_SERVER = 'https://premium.wpmudev.org/wdp-un.php?action=smushit_check';
82
-
83
- /**
84
- * Meta key to save smush result to db
85
- *
86
- *
87
- */
88
- const SMUSHED_META_KEY = 'wp-smpro-smush-data';
89
-
90
- /**
91
- * Meta key to save migrated version
92
- *
93
- */
94
- const MIGRATED_VERSION = "wp-smush-migrated-version";
95
-
96
- /**
97
- * Constructor
98
- */
99
- function __construct() {
100
- /**
101
- * Hooks
102
- */
103
- //Check if auto is enabled
104
- $auto_smush = get_option( WP_SMUSH_PREFIX . 'auto' );
105
-
106
- //Keep the uto smush on by default
107
- if ( $auto_smush === false ) {
108
- $auto_smush = 1;
109
- }
110
-
111
- if ( $auto_smush ) {
112
- add_filter( 'wp_generate_attachment_metadata', array(
113
- $this,
114
- 'filter_generate_attachment_metadata'
115
- ), 10, 2 );
116
- }
117
- add_filter( 'manage_media_columns', array( $this, 'columns' ) );
118
- add_action( 'manage_media_custom_column', array( $this, 'custom_column' ), 10, 2 );
119
- add_action( 'admin_init', array( $this, 'admin_init' ) );
120
- add_action( "admin_init", array( $this, "migrate" ) );
121
-
122
- }
123
-
124
- function admin_init() {
125
- load_plugin_textdomain( WP_SMUSH_DOMAIN, false, dirname( WP_SMUSH_BASENAME ) . '/languages/' );
126
- wp_enqueue_script( 'common' );
127
- }
128
-
129
- /**
130
- * Process an image with Smush.
131
- *
132
- * Returns an array of the $file $results.
133
- *
134
- * @param string $file Full absolute path to the image file
135
- * @param string $file_url Optional full URL to the image file
136
- *
137
- * @returns array
138
- */
139
- function do_smushit( $file_path = '', $file_url = '' ) {
140
- $errors = new WP_Error();
141
- if ( empty( $file_path ) ) {
142
- $errors->add( "empty_path", __( "File path is empty", WP_SMUSH_DOMAIN ) );
143
- }
144
-
145
- if ( empty( $file_url ) ) {
146
- $errors->add( "empty_url", __( "File URL is empty", WP_SMUSH_DOMAIN ) );
147
- }
148
-
149
- // check that the file exists
150
- if ( ! file_exists( $file_path ) || ! is_file( $file_path ) ) {
151
- $errors->add( "file_not_found", sprintf( __( "Could not find %s", WP_SMUSH_DOMAIN ), $file_path ) );
152
- }
153
-
154
- // check that the file is writable
155
- if ( ! is_writable( dirname( $file_path ) ) ) {
156
- $errors->add( "not_writable", sprintf( __( "%s is not writable", WP_SMUSH_DOMAIN ), dirname( $file_path ) ) );
157
- }
158
-
159
- $file_size = file_exists( $file_path ) ? filesize( $file_path ) : 0;
160
-
161
- //Check if premium user
162
- $max_size = $this->is_pro() ? WP_SMUSH_PREMIUM_MAX_BYTES : WP_SMUSH_MAX_BYTES;
163
-
164
- //Check if file exists
165
- if ( $file_size == 0 ) {
166
- $errors->add( "image_not_found", sprintf( __( 'Skipped (%s), image not found.', WP_SMUSH_DOMAIN ), $this->format_bytes( $file_size ) ) );
167
- }
168
-
169
- //Check size limit
170
- if ( $file_size > $max_size ) {
171
- $errors->add( "size_limit", sprintf( __( 'Skipped (%s), size limit exceeded.', WP_SMUSH_DOMAIN ), $this->format_bytes( $file_size ) ) );
172
- }
173
-
174
- if ( count( $errors->get_error_messages() ) ) {
175
- return $errors;
176
- }
177
-
178
- /** Send image for smushing, and fetch the response */
179
- $response = $this->_post( $file_path, $file_size );
180
-
181
- if ( ! $response['success'] ) {
182
- $errors->add( "false_response", $response['message'] );
183
- }
184
- //If there is no data
185
- if ( empty( $response['data'] ) ) {
186
- $errors->add( "no_data", __( 'Unknown API error', WP_SMUSH_DOMAIN ) );
187
- }
188
-
189
- if ( count( $errors->get_error_messages() ) ) {
190
- return $errors;
191
- }
192
-
193
- //If there are no savings, or image returned is bigger in size
194
- if ( ( ! empty( $response['data']->bytes_saved ) && intval( $response['data']->bytes_saved ) <= 0 )
195
- || empty( $response['data']->image )
196
- ) {
197
- return $response;
198
- }
199
- $tempfile = $file_path . ".tmp";
200
-
201
- //Add the file as tmp
202
- file_put_contents( $tempfile, $response['data']->image );
203
-
204
- //handle backups if enabled
205
- $backup = get_option( WP_SMUSH_PREFIX . 'backup' );
206
- if ( $backup && $this->is_pro() ) {
207
- $path = pathinfo( $file_path );
208
- $backup_name = trailingslashit( $path['dirname'] ) . $path['filename'] . ".bak." . $path['extension'];
209
- @copy( $file_path, $backup_name );
210
- }
211
-
212
- //replace the file
213
- $success = @rename( $tempfile, $file_path );
214
-
215
- //if tempfile still exists, unlink it
216
- if ( file_exists( $tempfile ) ) {
217
- unlink( $tempfile );
218
- }
219
-
220
- //If file renaming was successful
221
- if ( ! $success ) {
222
- copy( $tempfile, $file_path );
223
- unlink( $tempfile );
224
- }
225
-
226
- return $response;
227
- }
228
-
229
- /**
230
- * Fills $placeholder array with values from $data array
231
- *
232
- * @param array $placeholders
233
- * @param array $data
234
- *
235
- * @return array
236
- */
237
- private function _array_fill_placeholders( array $placeholders, array $data ) {
238
- $placeholders['percent'] = $data['compression'];
239
- $placeholders['bytes'] = $data['bytes_saved'];
240
- $placeholders['size_before'] = $data['before_size'];
241
- $placeholders['size_after'] = $data['after_size'];
242
- $placeholders['time'] = $data['time'];
243
-
244
- return $placeholders;
245
- }
246
-
247
- /**
248
- * Returns signature for single size of the smush api message to be saved to db;
249
- *
250
- * @return array
251
- */
252
- private function _get_size_signature() {
253
- return array(
254
- 'percent' => - 1,
255
- 'bytes' => - 1,
256
- 'size_before' => - 1,
257
- 'size_after' => - 1,
258
- 'time' => - 1
259
- );
260
- }
261
-
262
- /**
263
- * Read the image paths from an attachment's meta data and process each image
264
- * with wp_smushit().
265
- *
266
- * This method also adds a `wp_smushit` meta key for use in the media library.
267
- * Called after `wp_generate_attachment_metadata` is completed.
268
- *
269
- * @param $meta
270
- * @param null $ID
271
- *
272
- * @return mixed
273
- */
274
- function resize_from_meta_data( $meta, $ID = null ) {
275
-
276
- //Flag to check, if original size image needs to be smushed or not
277
- $smush_full = true;
278
- $errors = new WP_Error();
279
- $stats = array(
280
- "stats" => array_merge( $this->_get_size_signature(), array(
281
- 'api_version' => - 1,
282
- 'lossy' => - 1
283
- )
284
- ),
285
- 'sizes' => array()
286
- );
287
-
288
- $size_before = $size_after = $compression = $total_time = $bytes_saved = 0;
289
-
290
- if ( $ID && wp_attachment_is_image( $ID ) === false ) {
291
- return $meta;
292
- }
293
-
294
- //File path and URL for original image
295
- $attachment_file_path = get_attached_file( $ID );
296
- $attachment_file_url = wp_get_attachment_url( $ID );
297
-
298
- // If images has other registered size, smush them first
299
- if ( ! empty( $meta['sizes'] ) ) {
300
-
301
- foreach ( $meta['sizes'] as $size_key => $size_data ) {
302
-
303
- //if there is a large size, then we will set a flag to leave the original untouched
304
- if ( $size_key == 'large' ) {
305
- $smush_full = false;
306
- }
307
-
308
- // We take the original image. The 'sizes' will all match the same URL and
309
- // path. So just get the dirname and replace the filename.
310
-
311
- $attachment_file_path_size = trailingslashit( dirname( $attachment_file_path ) ) . $size_data['file'];
312
- $attachment_file_url_size = trailingslashit( dirname( $attachment_file_url ) ) . $size_data['file'];
313
-
314
- //Store details for each size key
315
- $response = $this->do_smushit( $attachment_file_path_size, $attachment_file_url_size );
316
-
317
- if ( is_wp_error( $response ) ) {
318
- return $response;
319
- }
320
-
321
- if ( ! empty( $response['data'] ) ) {
322
- $stats['sizes'][ $size_key ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $response['data'] );
323
- }
324
-
325
- //Total Stats, store all data in bytes
326
- if ( isset( $response['data'] ) ) {
327
- list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
328
- = $this->_update_stats_data( $response['data'], $size_before, $size_after, $total_time, $bytes_saved );
329
- } else {
330
- $errors->add( "image_size_error" . $size_key, sprintf( __( "Size '%s' not processed correctly", WP_SMUSH_DOMAIN ), $size_key ) );
331
- }
332
-
333
- if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
334
- $stats['stats']['api_version'] = $response['data']->api_version;
335
- $stats['stats']['lossy'] = $response['data']->lossy;
336
- }
337
- }
338
- }
339
-
340
- //If original size is supposed to be smushed
341
- if ( $smush_full ) {
342
-
343
- $full_image_response = $this->do_smushit( $attachment_file_path, $attachment_file_url );
344
-
345
- if ( is_wp_error( $full_image_response ) ) {
346
- return $full_image_response;
347
- }
348
-
349
- if ( ! empty( $full_image_response['data'] ) ) {
350
- $stats['sizes']['full'] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $full_image_response['data'] );
351
- } else {
352
- $errors->add( "image_size_error", __( "Size 'full' not processed correctly", WP_SMUSH_DOMAIN ) );
353
- }
354
-
355
- //Update stats
356
- if ( isset( $full_image_response['data'] ) ) {
357
- list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
358
- = $this->_update_stats_data( $full_image_response['data'], $size_before, $size_after, $total_time, $bytes_saved );
359
- } else {
360
- $errors->add( "image_size_error", __( "Size 'full' not processed correctly", WP_SMUSH_DOMAIN ) );
361
- }
362
-
363
- //Api version and lossy, for some images, full image i skipped and for other images only full exists
364
- //so have to add code again
365
- if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
366
- $stats['stats']['api_version'] = $full_image_response['data']->api_version;
367
- $stats['stats']['lossy'] = $full_image_response['data']->lossy;
368
- }
369
-
370
-
371
- }
372
-
373
- $has_errors = (bool) count( $errors->get_error_messages() );
374
-
375
- list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
376
- array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
377
-
378
- //Set smush status for all the images, store it in wp-smpro-smush-data
379
- if ( ! $has_errors ) {
380
-
381
- $existing_stats = get_post_meta( $ID, self::SMUSHED_META_KEY, true );
382
-
383
- if ( ! empty( $existing_stats ) ) {
384
- //Update total bytes saved, and compression percent
385
- $stats['stats']['bytes'] = isset( $existing_stats['stats']['bytes'] ) ? $existing_stats['stats']['bytes'] + $stats['stats']['bytes'] : $stats['stats']['bytes'];
386
- $stats['stats']['percent'] = isset( $existing_stats['stats']['percent'] ) ? $existing_stats['stats']['percent'] + $stats['stats']['percent'] : $stats['stats']['percent'];
387
-
388
- //Update stats for each size
389
- if ( ! empty( $existing_stats['sizes'] ) && ! empty( $stats['sizes'] ) ) {
390
-
391
- foreach ( $existing_stats['sizes'] as $size_name => $size_stats ) {
392
- //if stats for a particular size doesn't exists
393
- if ( empty( $stats['sizes'][$size_name] ) ) {
394
- $stats['sizes'][$size_name] = $existing_stats['sizes'][$size_name];
395
- } else {
396
- //Update compression percent and bytes saved for each size
397
- $stats['sizes'][$size_name]->bytes = $stats['sizes'][$size_name]->bytes + $existing_stats['sizes'][$size_name]->bytes;
398
- $stats['sizes'][$size_name]->percent = $stats['sizes'][$size_name]->percent + $existing_stats['sizes'][$size_name]->percent;
399
- }
400
- }
401
- }
402
- }
403
- update_post_meta( $ID, self::SMUSHED_META_KEY, $stats );
404
- }
405
-
406
- return $meta;
407
- }
408
-
409
- /**
410
- * Read the image paths from an attachment's meta data and process each image
411
- * with wp_smushit()
412
- *
413
- * Filters wp_generate_attachment_metadata
414
- *
415
- * @uses WpSmush::resize_from_meta_data
416
- *
417
- * @param $meta
418
- * @param null $ID
419
- *
420
- * @return mixed
421
- */
422
- function filter_generate_attachment_metadata( $meta, $ID = null ) {
423
- $this->resize_from_meta_data( $meta, $ID );
424
-
425
- return $meta;
426
- }
427
-
428
-
429
- /**
430
- * Posts an image to Smush.
431
- *
432
- * @param $file_path path of file to send to Smush
433
- * @param $file_size
434
- *
435
- * @return bool|array array containing success status, and stats
436
- */
437
- function _post( $file_path, $file_size ) {
438
-
439
- $data = false;
440
-
441
- $file = @fopen( $file_path, 'r' );
442
- $file_data = fread( $file, $file_size );
443
- $headers = array(
444
- 'accept' => 'application/json', // The API returns JSON
445
- 'content-type' => 'application/binary', // Set content type to binary
446
- );
447
-
448
- //Check if premium member, add API key
449
- $api_key = $this->_get_api_key();
450
- if ( ! empty( $api_key ) ) {
451
- $headers['apikey'] = $api_key;
452
- }
453
-
454
- //Check if lossy compression allowed and add it to headers
455
- $lossy = get_option( WP_SMUSH_PREFIX . 'lossy' );
456
-
457
- if ( $lossy && $this->is_pro() ) {
458
- $headers['lossy'] = 'true';
459
- } else {
460
- $headers['lossy'] = 'false';
461
- }
462
-
463
- $args = array(
464
- 'headers' => $headers,
465
- 'body' => $file_data,
466
- 'timeout' => WP_SMUSH_TIMEOUT,
467
- 'user-agent' => WP_SMUSH_UA
468
- );
469
- $result = wp_remote_post( WP_SMUSH_API, $args );
470
-
471
- //Close file connection
472
- fclose( $file );
473
- unset( $file_data );//free memory
474
- if ( is_wp_error( $result ) ) {
475
- //Handle error
476
- $data['message'] = sprintf( __( 'Error posting to API: %s', WP_SMUSH_DOMAIN ), $result->get_error_message() );
477
- $data['success'] = false;
478
- unset( $result ); //free memory
479
- return $data;
480
- } else if ( '200' != wp_remote_retrieve_response_code( $result ) ) {
481
- //Handle error
482
- $data['message'] = sprintf( __( 'Error posting to API: %s %s', WP_SMUSH_DOMAIN ), wp_remote_retrieve_response_code( $result ), wp_remote_retrieve_response_message( $result ) );
483
- $data['success'] = false;
484
- unset( $result ); //free memory
485
-
486
- return $data;
487
- }
488
-
489
- //If there is a response and image was successfully optimised
490
- $response = json_decode( $result['body'] );
491
- if ( $response && $response->success == true ) {
492
-
493
- //If there is any savings
494
- if ( $response->data->bytes_saved > 0 ) {
495
- $image = base64_decode( $response->data->image ); //base64_decode is necessary to send binary img over JSON, no security problems here!
496
- $image_md5 = md5( $response->data->image );
497
- if ( $response->data->image_md5 != $image_md5 ) {
498
- //Handle error
499
- $data['message'] = __( 'Smush data corrupted, try again.', WP_SMUSH_DOMAIN );
500
- $data['success'] = false;
501
- unset( $image );//free memory
502
- } else {
503
- $data['success'] = true;
504
- $data['data'] = $response->data;
505
- $data['data']->image = $image;
506
- unset( $image );//free memory
507
- }
508
- } else {
509
- //just return the data
510
- $data['success'] = true;
511
- $data['data'] = $response->data;
512
- }
513
- } else {
514
- //Server side error, get message from response
515
- $data['message'] = ! empty( $response->data ) ? $response->data : __( "Image couldn't be smushed", WP_SMUSH_DOMAIN );
516
- $data['success'] = false;
517
- }
518
-
519
- unset( $result );//free memory
520
- unset( $response );//free memory
521
- return $data;
522
- }
523
-
524
-
525
- /**
526
- * Print column header for Smush results in the media library using
527
- * the `manage_media_columns` hook.
528
- */
529
- function columns( $defaults ) {
530
- $defaults['smushit'] = 'WP Smush';
531
-
532
- return $defaults;
533
- }
534
-
535
- /**
536
- * Return the filesize in a humanly readable format.
537
- * Taken from http://www.php.net/manual/en/function.filesize.php#91477
538
- */
539
- function format_bytes( $bytes, $precision = 2 ) {
540
- $units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
541
- $bytes = max( $bytes, 0 );
542
- $pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
543
- $pow = min( $pow, count( $units ) - 1 );
544
- $bytes /= pow( 1024, $pow );
545
-
546
- return round( $bytes, $precision ) . ' ' . $units[ $pow ];
547
- }
548
-
549
- /**
550
- * Print column data for Smush results in the media library using
551
- * the `manage_media_custom_column` hook.
552
- */
553
- function custom_column( $column_name, $id ) {
554
- if ( 'smushit' == $column_name ) {
555
- $this->set_status( $id );
556
- }
557
- }
558
-
559
- /**
560
- * Check if user is premium member, check for api key
561
- *
562
- * @return mixed|string
563
- */
564
- function is_pro() {
565
-
566
- if ( isset( $this->is_pro ) ) return $this->is_pro;
567
-
568
- //no api key set, always false
569
- $api_key = $this->_get_api_key();
570
- if ( empty( $api_key ) ) {
571
- return false;
572
- }
573
-
574
- $key = "wp-smush-premium-" . substr( $api_key, -10, 10); //add last 10 chars of apikey to transient key in case it changes
575
- if ( false === ( $valid = get_site_transient( $key ) ) ) {
576
- // call api
577
- $url = self::API_SERVER . '&key=' . urlencode( $api_key );
578
-
579
- $request = wp_remote_get( $url, array(
580
- "user-agent" => WP_SMUSH_UA,
581
- "timeout" => 3
582
- )
583
- );
584
-
585
- if ( ! is_wp_error( $request ) && '200' == wp_remote_retrieve_response_code( $request ) ) {
586
- $result = json_decode( wp_remote_retrieve_body( $request ) );
587
- if ( $result && $result->success ) {
588
- $valid = true;
589
- set_site_transient( $key, 1, 12 * HOUR_IN_SECONDS );
590
- } else {
591
- $valid = false;
592
- set_site_transient( $key, 0, 30 * MINUTE_IN_SECONDS ); //cache failure much shorter
593
- }
594
-
595
- } else {
596
- $valid = false;
597
- set_site_transient( $key, 0, 5 * MINUTE_IN_SECONDS ); //cache network failure even shorter, we don't want a request every pageload
598
- }
599
-
600
- }
601
-
602
- $this->is_pro = (bool) $valid;
603
- return $this->is_pro;
604
- }
605
-
606
- /**
607
- * Returns api key
608
- *
609
- * @return mixed
610
- */
611
- private function _get_api_key() {
612
- if ( defined( 'WPMUDEV_APIKEY' ) ) {
613
- $api_key = WPMUDEV_APIKEY;
614
- } else {
615
- $api_key = get_site_option( 'wpmudev_apikey' );
616
- }
617
-
618
- return $api_key;
619
- }
620
-
621
-
622
- /**
623
- * Checks if image is already smushed
624
- *
625
- * @param int $id
626
- * @param array $data
627
- *
628
- * @return bool|mixed
629
- */
630
- function is_smushed( $id, $data = null ) {
631
-
632
- //For new images
633
- $wp_is_smushed = get_post_meta( $id, 'wp-is-smushed', true );
634
-
635
- //Not smushed, backward compatibility, check attachment metadata
636
- if ( ! $wp_is_smushed && $data !== null ) {
637
- if ( isset( $data['wp_smushit'] ) && ! empty( $data['wp_smushit'] ) ) {
638
- $wp_is_smushed = true;
639
- }
640
- }
641
-
642
- return $wp_is_smushed;
643
- }
644
-
645
- /**
646
- * Returns size saved from the api call response
647
- *
648
- * @param string $message
649
- *
650
- * @return string|bool
651
- */
652
- function get_saved_size( $message ) {
653
- if ( preg_match( '/\((.*)\)/', $message, $matches ) ) {
654
- return isset( $matches[1] ) ? $matches[1] : false;
655
- }
656
-
657
- return false;
658
- }
659
-
660
- /**
661
- * Set send button status
662
- *
663
- * @param $id
664
- * @param bool $echo
665
- * @param bool $text_only
666
- *
667
- * @return string|void
668
- */
669
- function set_status( $id, $echo = true, $text_only = false ) {
670
- $status_txt = $button_txt = '';
671
- $show_button = false;
672
-
673
- //Stats are not received properly, otherwise
674
- wp_cache_delete( $id, 'post_meta' );
675
-
676
- $wp_smush_data = get_post_meta( $id, self::SMUSHED_META_KEY, true );
677
- // if the image is smushed
678
- if ( ! empty( $wp_smush_data ) ) {
679
-
680
- $bytes = isset( $wp_smush_data['stats']['bytes'] ) ? $wp_smush_data['stats']['bytes'] : 0;
681
- $bytes_readable = ! empty( $bytes ) ? $this->format_bytes( $bytes ) : '';
682
- $percent = isset( $wp_smush_data['stats']['percent'] ) ? $wp_smush_data['stats']['percent'] : 0;
683
- $percent = $percent < 0 ? 0 : $percent;
684
-
685
- if ( isset( $wp_smush_data['stats']['size_before'] ) && $wp_smush_data['stats']['size_before'] == 0 ) {
686
- $status_txt = __( 'Error processing request', WP_SMUSH_DOMAIN );
687
- $show_button = true;
688
- } else {
689
- if ( $bytes == 0 || $percent == 0 ) {
690
- $status_txt = __( 'Already Optimized', WP_SMUSH_DOMAIN );
691
- } elseif ( ! empty( $percent ) && ! empty( $bytes_readable ) ) {
692
- $status_txt = sprintf( __( "Reduced by %s ( %01.1f%% )", WP_SMUSH_DOMAIN ), $bytes_readable, number_format_i18n( $percent, 2, '.', '' ) );
693
- }
694
- }
695
-
696
- //IF current compression is lossy
697
- if ( ! empty( $wp_smush_data ) && ! empty( $wp_smush_data['stats'] ) ) {
698
- $lossy = !empty( $wp_smush_data['stats']['lossy'] ) ? $wp_smush_data['stats']['lossy'] : '';
699
- $is_lossy = $lossy == 1 ? true : false;
700
- }
701
-
702
- //Check if Lossy enabled
703
- $opt_lossy = WP_SMUSH_PREFIX . 'lossy';
704
- $opt_lossy_val = get_option( $opt_lossy, false );
705
-
706
- //Check image type
707
- $image_type = get_post_mime_type( $id );
708
-
709
- //Check if premium user, compression was lossless, and lossy compression is enabled
710
- if ( $this->is_pro() && ! $is_lossy && $opt_lossy_val && $image_type != 'image/gif' ) {
711
- // the button text
712
- $button_txt = __( 'Super-Smush', WP_SMUSH_DOMAIN );
713
- $show_button = true;
714
- }
715
- } else {
716
-
717
- // the status
718
- $status_txt = __( 'Not processed', WP_SMUSH_DOMAIN );
719
-
720
- // we need to show the smush button
721
- $show_button = true;
722
-
723
- // the button text
724
- $button_txt = __( 'Smush Now!', WP_SMUSH_DOMAIN );
725
- }
726
- if ( $text_only ) {
727
- return $status_txt;
728
- }
729
-
730
- $text = $this->column_html( $id, $status_txt, $button_txt, $show_button, $wp_smush_data, $echo );
731
- if ( ! $echo ) {
732
- return $text;
733
- }
734
- }
735
-
736
- /**
737
- * Print the column html
738
- *
739
- * @param string $id Media id
740
- * @param string $status_txt Status text
741
- * @param string $button_txt Button label
742
- * @param boolean $show_button Whether to shoe the button
743
- *
744
- * @return null
745
- */
746
- function column_html( $id, $status_txt = "", $button_txt = "", $show_button = true, $smushed = false, $echo = true ) {
747
- $allowed_images = array( 'image/jpeg', 'image/jpg', 'image/png', 'image/gif' );
748
-
749
- // don't proceed if attachment is not image, or if image is not a jpg, png or gif
750
- if ( ! wp_attachment_is_image( $id ) || ! in_array( get_post_mime_type( $id ), $allowed_images ) ) {
751
- return;
752
- }
753
-
754
- $class = $smushed ? '' : ' hidden';
755
- $html = '
756
- <p class="smush-status' . $class . '">' . $status_txt . '</p>';
757
- // if we aren't showing the button
758
- if ( ! $show_button ) {
759
- if ( $echo ) {
760
- echo $html;
761
-
762
- return;
763
- } else {
764
- if ( ! $smushed ) {
765
- $class = ' currently-smushing';
766
- } else {
767
- $class = ' smushed';
768
- }
769
-
770
- return '<div class="smush-wrap' . $class . '">' . $html . '</div>';
771
- }
772
- }
773
- if ( ! $echo ) {
774
- $html .= '
775
- <button class="button button-primary wp-smush-send" data-id="' . $id . '">
776
- <span>' . $button_txt . '</span>
777
- </button>';
778
- if ( ! $smushed ) {
779
- $class = ' unsmushed';
780
- } else {
781
- $class = ' smushed';
782
- }
783
-
784
- return '<div class="smush-wrap' . $class . '">' . $html . '</div>';
785
- } else {
786
- $html .= '<button class="button wp-smush-send" data-id="' . $id . '">
787
- <span>' . $button_txt . '</span>
788
- </button>';
789
- echo $html;
790
- }
791
- }
792
-
793
- /**
794
- * Migrates smushit api message to the latest structure
795
- *
796
- *
797
- * @return void
798
- */
799
- function migrate() {
800
-
801
- if ( ! version_compare( $this->version, "1.7.1", "lte" ) ) {
802
- return;
803
- }
804
-
805
- $migrated_version = get_option( self::MIGRATED_VERSION );
806
-
807
- if ( $migrated_version === $this->version ) {
808
- return;
809
- }
810
-
811
- global $wpdb;
812
-
813
- $q = $wpdb->prepare( "SELECT * FROM `" . $wpdb->postmeta . "` WHERE `meta_key`=%s AND `meta_value` LIKE %s ", "_wp_attachment_metadata", "%wp_smushit%" );
814
- $results = $wpdb->get_results( $q );
815
-
816
- if ( count( $results ) < 1 ) {
817
- return;
818
- }
819
-
820
- $migrator = new WpSmushMigrate();
821
- foreach ( $results as $attachment_meta ) {
822
- $migrated_message = $migrator->migrate_api_message( maybe_unserialize( $attachment_meta->meta_value ) );
823
- if ( $migrated_message !== array() ) {
824
- update_post_meta( $attachment_meta->post_id, self::SMUSHED_META_KEY, $migrated_message );
825
- }
826
- }
827
-
828
- update_option( self::MIGRATED_VERSION, $this->version );
829
-
830
- }
831
-
832
- /**
833
- * @param Object $response_data
834
- * @param $size_before
835
- * @param $size_after
836
- * @param $total_time
837
- * @param $bytes_saved
838
- *
839
- * @return array
840
- */
841
- private function _update_stats_data( $response_data, $size_before, $size_after, $total_time, $bytes_saved ) {
842
- $size_before += ! empty( $response_data->before_size ) ? (int) $response_data->before_size : 0;
843
- $size_after += ( ! empty( $response_data->after_size ) && $response_data->after_size > 0 ) ? (int) $response_data->after_size : (int) $response_data->before_size;
844
- $total_time += ! empty( $response_data->time ) ? (float) $response_data->time : 0;
845
- $bytes_saved += ( ! empty( $response_data->bytes_saved ) && $response_data->bytes_saved > 0 ) ? $response_data->bytes_saved : 0;
846
- $compression = ( $bytes_saved > 0 && $size_before > 0 ) ? ( ( $bytes_saved / $size_before ) * 100 ) : 0;
847
-
848
- return array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
849
- }
850
  }
851
 
852
- global $WpSmush;
853
- $WpSmush = new WpSmush();
 
 
 
 
 
854
 
855
- }
856
-
857
- //Include Admin classes
858
- require_once( WP_SMUSH_DIR . '/lib/class-wp-smush-bulk.php' );
859
- require_once( WP_SMUSH_DIR . '/lib/class-wp-smush-admin.php' );
860
- //include_once( WP_SMUSH_DIR . '/extras/dash-notice/wpmudev-dash-notification.php' );
861
 
 
 
862
  //register items for the dashboard plugin
863
- global $wpmudev_notices;
864
- $wpmudev_notices[] = array(
865
- 'id' => 912164,
866
- 'name' => 'WP Smush Pro',
867
- 'screens' => array(
868
- 'media_page_wp-smush-bulk',
869
- 'upload'
870
- )
871
- );
 
4
  Plugin URI: http://wordpress.org/extend/plugins/wp-smushit/
5
  Description: Reduce image file sizes, improve performance and boost your SEO using the free <a href="https://premium.wpmudev.org/">WPMU DEV</a> WordPress Smush API.
6
  Author: WPMU DEV
7
+ Version: 2.0.6.3
8
  Author URI: http://premium.wpmudev.org/
9
+ Textdomain: wp-smushit
10
  */
11
 
12
  /*
36
  * Constants
37
  */
38
  $prefix = 'WP_SMUSH_';
39
+ $version = '2.0.6.3';
40
+
41
+ /**
42
+ * Set the default timeout for API request and AJAX timeout
43
+ */
44
+ $timeout = apply_filters( 'WP_SMUSH_API_TIMEOUT', 60 );
45
+
46
+ $smush_constants = array(
47
+ 'VERSION' => $version,
48
  'BASENAME' => plugin_basename( __FILE__ ),
49
  'API' => 'https://smushpro.wpmudev.org/1.0/',
 
50
  'UA' => 'WP Smush/' . $version . '; ' . network_home_url(),
51
  'DIR' => plugin_dir_path( __FILE__ ),
52
  'URL' => plugin_dir_url( __FILE__ ),
53
  'MAX_BYTES' => 1000000,
54
+ 'PREMIUM_MAX_BYTES' => 32000000,
55
  'PREFIX' => 'wp-smush-',
56
+ 'TIMEOUT' => $timeout
 
57
  );
58
 
59
+ foreach ( $smush_constants as $const_name => $constant_val ) {
60
  if ( ! defined( $prefix . $const_name ) ) {
61
  define( $prefix . $const_name, $constant_val );
62
  }
63
  }
64
+ //Include main class
65
+ require_once WP_SMUSH_DIR . 'lib/class-wp-smush.php';
66
+
67
+ //Only for wordpress.org members
68
+ $plugin = basename( plugin_dir_path( __FILE__ ) );
69
+ if ( $plugin == 'wp-smushit' ) {
70
+ require_once( WP_SMUSH_DIR . 'extras/free-dashboard/module.php' );
71
+
72
+ // Register the current plugin.
73
+ do_action(
74
+ 'wdev-register-plugin',
75
+ /* 1 Plugin ID */
76
+ plugin_basename( __FILE__ ), /* Plugin ID */
77
+ /* 2 Plugin Title */
78
+ 'WP Smush',
79
+ /* 3 https://wordpress.org */
80
+ '/plugins/wp-smushit/',
81
+ /* 4 Email Button CTA */
82
+ __( 'Get Fast', 'wp-smushit' ),
83
+ /* 5 getdrip Plugin param */
84
+ 'Smush'
85
+ );
86
+
87
+ // The rating message contains 2 variables: user-name, plugin-name
88
+ add_filter(
89
+ 'wdev-rating-message-' . plugin_basename( __FILE__ ),
90
+ 'wp_smush_rating_message'
91
+ );
92
+
93
+ /**
94
+ * Filters the rating message, include stats if greater than 1Mb
95
+ *
96
+ * @param $message
97
+ *
98
+ * @return string
99
+ */
100
+ function wp_smush_rating_message( $message ) {
101
+ global $wpsmushit_admin;
102
+ $savings = $wpsmushit_admin->global_stats();
103
+ $image_count = $wpsmushit_admin->total_count();
104
+ $show_stats = false;
105
+
106
+ //If there is any saving, greater than 1Mb, show stats
107
+ if ( ! empty( $savings ) && ! empty( $savings['bytes'] ) && $savings['bytes'] > 1048576 ) {
108
+ $show_stats = true;
109
+ }
110
+
111
+ $message = "Hey %s, you've been using %s for a while now, and we hope you're happy with it.";
112
+
113
+ //Conditionally Show stats in rating message
114
+ if ( $show_stats ) {
115
+ $message .= sprintf( " You've smushed <strong>%s</strong> from %d images already, improving the speed and SEO ranking of this site!", $savings['human'], $image_count );
116
+ }
117
+ $message .= " We've spent countless hours developing this free plugin for you, and we would really appreciate it if you dropped us a quick rating!";
118
+
119
+ return $message;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  }
121
 
122
+ // The email message contains 1 variable: plugin-name
123
+ add_filter(
124
+ 'wdev-email-message-' . plugin_basename( __FILE__ ),
125
+ 'wp_smush_email_message'
126
+ );
127
+ function wp_smush_email_message( $message ) {
128
+ $message = "You're awesome for installing %s! Site speed isn't all image optimization though, so we've collected all the best speed resources we know in a single email - just for users of WP Smush!";
129
 
130
+ return $message;
131
+ }
132
+ } elseif ( $plugin == 'wp-smush-pro' ) {
 
 
 
133
 
134
+ //Only for WPMU DEV Members
135
+ require_once( WP_SMUSH_DIR . 'extras/dash-notice/wpmudev-dash-notification.php' );
136
  //register items for the dashboard plugin
137
+ global $wpmudev_notices;
138
+ $wpmudev_notices[] = array(
139
+ 'id' => 912164,
140
+ 'name' => 'WP Smush Pro',
141
+ 'screens' => array(
142
+ 'media_page_wp-smush-bulk',
143
+ 'upload'
144
+ )
145
+ );
146
+ }