Smush Image Compression and Optimization - Version 2.7.4

Version Description

  • Update: Minor UI changes
  • Fixed:
    • Images not being resized when image is uploaded via Mobile App
    • Notices and Warnings
    • S3 offload Integration - Original Image not being deleted in some cases
Download this release

Release Info

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

Code changes from version 2.2.1 to 2.7.4

Files changed (88) hide show
  1. assets/css/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  2. assets/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  3. assets/css/jQueryFileTree.min.css +1 -0
  4. assets/css/notice.css +181 -0
  5. assets/css/wp-smushit-admin.css +1394 -201
  6. assets/images/ajax-loader.gif +0 -0
  7. assets/images/application.png +0 -0
  8. assets/images/bulk-smush.png +0 -0
  9. assets/images/code.png +0 -0
  10. assets/images/css.png +0 -0
  11. assets/images/db.png +0 -0
  12. assets/images/dev-team.png +0 -0
  13. assets/images/directory-lock.png +0 -0
  14. assets/images/directory.png +0 -0
  15. assets/images/doc.png +0 -0
  16. assets/images/file-lock.png +0 -0
  17. assets/images/file.png +0 -0
  18. assets/images/film.png +0 -0
  19. assets/images/flash.png +0 -0
  20. assets/images/folder-closed.svg +12 -0
  21. assets/images/folder-open-selected.svg +12 -0
  22. assets/images/folder-open.svg +12 -0
  23. assets/images/folder_open.png +0 -0
  24. assets/images/html.png +0 -0
  25. assets/images/hummingbird.png +0 -0
  26. assets/images/image.svg +12 -0
  27. assets/images/install-welcome.png +0 -0
  28. assets/images/java.png +0 -0
  29. assets/images/linux.png +0 -0
  30. assets/images/music.png +0 -0
  31. assets/images/pdf.png +0 -0
  32. assets/images/php.png +0 -0
  33. assets/images/picture.png +0 -0
  34. assets/images/ppt.png +0 -0
  35. assets/images/psd.png +0 -0
  36. assets/images/ruby.png +0 -0
  37. assets/images/script.png +0 -0
  38. assets/images/share-bg-small.png +0 -0
  39. assets/images/smush-no-media.png +0 -0
  40. assets/images/smush-upload-images.png +0 -0
  41. assets/images/spinner.gif +0 -0
  42. assets/images/txt.png +0 -0
  43. assets/images/welcome-notice.png +0 -0
  44. assets/images/whatsapp-button-14px.png +0 -0
  45. assets/images/whatsapp-button-16px.png +0 -0
  46. assets/images/xls.png +0 -0
  47. assets/images/zip.png +0 -0
  48. assets/js/bulk-smush.js +8 -0
  49. assets/js/jQueryFileTree.js +215 -0
  50. assets/js/notice.js +55 -0
  51. assets/js/wp-smushit-admin-media.js +0 -84
  52. assets/js/wp-smushit-admin.js +1690 -260
  53. assets/shared-ui/font/WPMU DEV Dashboard.json +0 -0
  54. assets/shared-ui/img/spin-grey.gif +0 -0
  55. assets/shared-ui/img/spin.gif +0 -0
  56. assets/shared-ui/notice.css +0 -1
  57. assets/shared-ui/notice.js +30 -14
  58. assets/shared-ui/plugin-ui.php +52 -5
  59. assets/shared-ui/wdev-ui.css +108 -18
  60. assets/shared-ui/wdev-ui.js +130 -23
  61. extras/dash-notice/wpmudev-dash-notification.php +995 -381
  62. extras/free-dashboard/admin.css +5 -20
  63. extras/free-dashboard/module.php +10 -21
  64. languages/wp-smushit.pot +782 -240
  65. lib/class-wp-smush-admin.php +1262 -715
  66. lib/class-wp-smush-async.php +124 -0
  67. lib/class-wp-smush-backup.php +391 -0
  68. lib/class-wp-smush-bulk.php +23 -9
  69. lib/class-wp-smush-db.php +874 -0
  70. lib/class-wp-smush-dir.php +1349 -0
  71. lib/class-wp-smush-helper.php +86 -0
  72. lib/class-wp-smush-nextgen.php +298 -50
  73. lib/class-wp-smush-png_jpg.php +706 -0
  74. lib/class-wp-smush-resize.php +391 -0
  75. lib/class-wp-smush-s3.php +377 -0
  76. lib/class-wp-smush-settings.php +155 -0
  77. lib/class-wp-smush-share.php +51 -0
  78. lib/class-wp-smush-stats.php +592 -0
  79. lib/class-wp-smush-ui.php +557 -237
  80. lib/class-wp-smush.php +716 -220
  81. lib/nextgen-integration/class-wp-smush-nextgen-admin.php +167 -70
  82. lib/nextgen-integration/class-wp-smush-nextgen-bulk.php +46 -24
  83. lib/nextgen-integration/class-wp-smush-nextgen-stats.php +52 -16
  84. lib/wp-async-task-smush.php +285 -0
  85. lib/wp-async-task.php +275 -0
  86. readme.txt +285 -27
  87. uninstall.php +99 -26
  88. wp-smush.php +132 -25
assets/css/images/ui-bg_flat_75_ffffff_40x100.png CHANGED
Binary file
assets/css/images/ui-bg_glass_65_ffffff_1x400.png CHANGED
Binary file
assets/css/jQueryFileTree.min.css ADDED
@@ -0,0 +1 @@
 
1
+ UL.jqueryFileTree{font-family:Verdana,sans-serif;font-size:11px;line-height:18px;padding:0;margin:0;display:none}UL.jqueryFileTree LI{list-style:none;padding:0 0 0 20px;margin:0;white-space:nowrap}UL.jqueryFileTree LI.directory{background:url(../images/directory.png) left top no-repeat} UL.jqueryFileTree LI.directory-locked{background:url(../images/directory-lock.png) left top no-repeat} UL.jqueryFileTree LI.expanded{background:url(../images/folder_open.png) left top no-repeat} UL.jqueryFileTree LI.file{background:url(../images/file.png) left top no-repeat} UL.jqueryFileTree LI.file-locked{background:url(../images/file-lock.png) left top no-repeat!important} UL.jqueryFileTree LI.wait{background:url(../images/spinner.gif) left top no-repeat} UL.jqueryFileTree LI.selected>a{font-weight:700} UL.jqueryFileTree LI.ext_3gp{background:url(../images/film.png) left top no-repeat} UL.jqueryFileTree LI.ext_afp,UL.jqueryFileTree LI.ext_afpa,UL.jqueryFileTree LI.ext_asp,UL.jqueryFileTree LI.ext_aspx{background:url(../images/code.png) left top no-repeat} UL.jqueryFileTree LI.ext_avi{background:url(../images/film.png) left top no-repeat} UL.jqueryFileTree LI.ext_bat{background:url(../images/application.png) left top no-repeat} UL.jqueryFileTree LI.ext_bmp{background:url(../images/picture.png) left top no-repeat} UL.jqueryFileTree LI.ext_c,UL.jqueryFileTree LI.ext_cfm,UL.jqueryFileTree LI.ext_cgi{background:url(../images/code.png) left top no-repeat} UL.jqueryFileTree LI.ext_com{background:url(../images/application.png) left top no-repeat} UL.jqueryFileTree LI.ext_cpp{background:url(../images/code.png) left top no-repeat} UL.jqueryFileTree LI.ext_css{background:url(../images/css.png) left top no-repeat} UL.jqueryFileTree LI.ext_doc{background:url(../images/doc.png) left top no-repeat} UL.jqueryFileTree LI.ext_exe{background:url(../images/application.png) left top no-repeat} UL.jqueryFileTree LI.ext_gif{background:url(../images/picture.png) left top no-repeat} UL.jqueryFileTree LI.ext_fla{background:url(../images/flash.png) left top no-repeat} UL.jqueryFileTree LI.ext_h{background:url(../images/code.png) left top no-repeat} UL.jqueryFileTree LI.ext_htm,UL.jqueryFileTree LI.ext_html{background:url(../images/html.png) left top no-repeat} UL.jqueryFileTree LI.ext_jar{background:url(../images/java.png) left top no-repeat} UL.jqueryFileTree LI.ext_jpeg,UL.jqueryFileTree LI.ext_jpg{background:url(../images/picture.png) left top no-repeat} UL.jqueryFileTree LI.ext_js{background:url(../images/script.png) left top no-repeat} UL.jqueryFileTree LI.ext_lasso{background:url(../images/code.png) left top no-repeat} UL.jqueryFileTree LI.ext_log{background:url(../images/txt.png) left top no-repeat} UL.jqueryFileTree LI.ext_m4p{background:url(../images/music.png) left top no-repeat} UL.jqueryFileTree LI.ext_mov{background:url(../images/film.png) left top no-repeat} UL.jqueryFileTree LI.ext_mp3{background:url(../images/music.png) left top no-repeat} UL.jqueryFileTree LI.ext_mp4,UL.jqueryFileTree LI.ext_mpeg,UL.jqueryFileTree LI.ext_mpg{background:url(../images/film.png) left top no-repeat} UL.jqueryFileTree LI.ext_ogg{background:url(../images/music.png) left top no-repeat} UL.jqueryFileTree LI.ext_ogv{background:url(../images/film.png) left top no-repeat} UL.jqueryFileTree LI.ext_pcx{background:url(../images/picture.png) left top no-repeat} UL.jqueryFileTree LI.ext_pdf{background:url(../images/pdf.png) left top no-repeat} UL.jqueryFileTree LI.ext_php{background:url(../images/php.png) left top no-repeat} UL.jqueryFileTree LI.ext_png{background:url(../images/picture.png) left top no-repeat} UL.jqueryFileTree LI.ext_ppt{background:url(../images/ppt.png) left top no-repeat} UL.jqueryFileTree LI.ext_psd{background:url(../images/psd.png) left top no-repeat} UL.jqueryFileTree LI.ext_pl,UL.jqueryFileTree LI.ext_py{background:url(../images/script.png) left top no-repeat} UL.jqueryFileTree LI.ext_rb,UL.jqueryFileTree LI.ext_rbx,UL.jqueryFileTree LI.ext_rhtml{background:url(../images/ruby.png) left top no-repeat} UL.jqueryFileTree LI.ext_rpm{background:url(../images/linux.png) left top no-repeat} UL.jqueryFileTree LI.ext_ruby{background:url(../images/ruby.png) left top no-repeat} UL.jqueryFileTree LI.ext_sql{background:url(../images/db.png) left top no-repeat} UL.jqueryFileTree LI.ext_swf{background:url(../images/flash.png) left top no-repeat} UL.jqueryFileTree LI.ext_tif,UL.jqueryFileTree LI.ext_tiff{background:url(../images/picture.png) left top no-repeat} UL.jqueryFileTree LI.ext_txt{background:url(../images/txt.png) left top no-repeat} UL.jqueryFileTree LI.ext_vb{background:url(../images/code.png) left top no-repeat} UL.jqueryFileTree LI.ext_wav{background:url(../images/music.png) left top no-repeat} UL.jqueryFileTree LI.ext_webm,UL.jqueryFileTree LI.ext_wmv{background:url(../images/film.png) left top no-repeat} UL.jqueryFileTree LI.ext_xls{background:url(../images/xls.png) left top no-repeat} UL.jqueryFileTree LI.ext_xml{background:url(../images/code.png) left top no-repeat} UL.jqueryFileTree LI.ext_zip{background:url(../images/zip.png) left top no-repeat} UL.jqueryFileTree A{color:#333;text-decoration:none;display:inline-block;padding:0 2px;cursor:pointer} UL.jqueryFileTree A:hover{background:#BDF}
assets/css/notice.css ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * CSS styles used Admin notice
3
+ */
4
+
5
+ .wrap .smush-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 .smush-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
+ .smush-notice > div {
38
+ display: table-cell; /* The magic ingredient! */
39
+ vertical-align: middle;
40
+ cursor: default;
41
+ line-height: 1.5;
42
+ }
43
+
44
+ .smush-notice.notice.loading > div {
45
+ -webkit-filter: blur(2px);
46
+ -moz-filter: blur(2px);
47
+ -o-filter: blur(2px);
48
+ -ms-filter: blur(2px);
49
+ filter: blur(2px);
50
+ }
51
+
52
+ .smush-notice-logo {
53
+ background-color: #0B2F3F;
54
+ 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);
55
+ background-repeat: no-repeat;
56
+ background-position: 50% 50%;
57
+ }
58
+
59
+ .smush-notice-logo span {
60
+ display: block;
61
+ width: 80px;
62
+ }
63
+
64
+ .smush-notice-message {
65
+ width: 100%;
66
+ padding: 10px 20px;
67
+ color: #444;
68
+ }
69
+
70
+ .smush-notice-message strong {
71
+ color: #000;
72
+ }
73
+
74
+ .smush-notice-cta {
75
+ border-left: 1px solid #E5E5E5;
76
+ background: #F8F8F8;
77
+ padding: 0 30px;
78
+ position: relative;
79
+ white-space: nowrap;
80
+ }
81
+
82
+ .wp-core-ui .smush-notice-cta button,
83
+ .wp-core-ui .smush-notice-cta .button-primary:active {
84
+ vertical-align: middle;
85
+ }
86
+
87
+ .wp-core-ui .smush-notice-cta input[type="email"] {
88
+ vertical-align: middle;
89
+ line-height: 20px;
90
+ margin: 0;
91
+ min-width: 50px;
92
+ max-width: 320px;
93
+ text-align: center;
94
+ padding-left: 0;
95
+ padding-right: 0;
96
+ }
97
+
98
+ .smush-notice-dismiss {
99
+ background: transparent;
100
+ border: 0;
101
+ cursor: pointer;
102
+ color: #BBB;
103
+ }
104
+
105
+ .smush-notice-dismiss:hover {
106
+ color: #666;
107
+ }
108
+
109
+ @media only all and (max-width: 1200px) {
110
+ .smush-notice-dismiss {
111
+ display: block;
112
+ margin: 0 auto;
113
+ line-height: 18px;
114
+ padding-top: 8px;
115
+ padding-bottom: 2px;
116
+ }
117
+ }
118
+
119
+ @media only all and (max-width: 1000px) {
120
+ .wrap .smush-notice.notice {
121
+ display: block;
122
+ font-size: 13px;
123
+ }
124
+
125
+ .smush-notice > .smush-notice-logo {
126
+ float: left;
127
+ display: inline-block;
128
+ height: 80px;
129
+ margin: 10px;
130
+ border-radius: 4px;
131
+ }
132
+
133
+ .smush-notice > .smush-notice-message {
134
+ width: auto;
135
+ display: block;
136
+ padding: 10px;
137
+ min-height: 80px;
138
+ }
139
+
140
+ .smush-notice > .smush-notice-cta {
141
+ display: block;
142
+ border-top: 1px solid #E5E5E5;
143
+ border-left: 0;
144
+ text-align: center;
145
+ white-space: normal;
146
+ line-height: 30px;
147
+ padding: 10px 20px;
148
+ }
149
+
150
+ .wp-core-ui .smush-notice > .smush-notice-cta > input[type="email"],
151
+ .smush-notice > .smush-notice-cta > button {
152
+ font-size: 14px;
153
+ }
154
+
155
+ .smush-notice > .smush-notice-cta > .smush-notice-dismiss {
156
+ display: inline-block;
157
+ float: none;
158
+ line-height: 26px;
159
+ padding-top: 0;
160
+ padding-bottom: 0;
161
+ font-size: 13px;
162
+ }
163
+ }
164
+
165
+ @media only all and (max-width: 500px) {
166
+ .wp-core-ui .smush-notice > .smush-notice-cta > input[type="email"],
167
+ .smush-notice > .smush-notice-cta > button {
168
+ display: block;
169
+ width: 100% !important;
170
+ max-width: none;
171
+ margin-bottom: 4px;
172
+ font-size: 16px;
173
+ height: 34px;
174
+ }
175
+
176
+ .smush-notice > .smush-notice-cta > .smush-notice-dismiss {
177
+ margin-top: 5px;
178
+ font-size: 14px;
179
+ height: 23px;
180
+ }
181
+ }
assets/css/wp-smushit-admin.css CHANGED
@@ -68,29 +68,31 @@ Smush button transformation
68
  margin-top: 18px;
69
  }
70
 
71
- .wpmud .dev-box.wp-smush-install-thanks-box {
72
- margin-bottom: 20px;
73
- padding-bottom: 0;
74
- }
75
- #wp-smush-install-thanks .row {
76
- background-image: url(../images/install-welcome.png);
77
- background-repeat: no-repeat;
78
- background-position: 30px bottom;
79
- min-height: 206px;
80
- }
81
-
82
  /** Settings Page **/
83
 
84
  .wp-smush-setting-row {
85
  margin: 15px 20px 15px 0;
86
  }
87
 
 
 
 
 
 
 
 
 
88
  .wpmud .wp-smushit-container-wrap {
89
  display: inline-block;
90
  margin-top: 30px;
91
  }
92
 
93
- .wp-smush-pro.smush-settings-wrapper {
 
 
 
 
 
94
  width: 100%;
95
  }
96
 
@@ -101,18 +103,26 @@ Smush button transformation
101
  }
102
 
103
  .wpmud .wp-smush-submit-wrap {
 
 
104
  padding-top: 0;
105
  }
106
 
107
  .wp-smush-submit-wrap .spinner {
108
- float: none;
109
  margin: 1.5em 1em 0;
110
  }
111
 
112
  input#wp-smush-save-settings {
 
 
113
  margin: 10px 0 5px;
114
  }
115
 
 
 
 
 
116
  .wp-smush-welcome #wp-smush-save-settings {
117
  float: right;
118
  }
@@ -249,7 +259,6 @@ input#wp-smush-save-settings {
249
  .compat-field-wp_smush .smush-wrap {
250
  margin: 0 0 5px 0;
251
  max-width: 100%;
252
- overflow: hidden;
253
  }
254
 
255
  .inactive {
@@ -276,12 +285,27 @@ input#wp-smush-save-settings {
276
  padding-top: 0;
277
  }
278
 
279
- .smush-stats-wrapper .row:last-child {
280
- padding-bottom: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  }
282
 
283
  .wpmud .wp-smushit-container-right .smush-stats-wrapper .wp-smush-container-header {
284
- margin-bottom: 20px;
285
  }
286
 
287
  .smush-stats-wrapper td, .smush-stats-wrapper th {
@@ -293,6 +317,54 @@ input#wp-smush-save-settings {
293
  margin: 7px 8px 0;
294
  }
295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  table.wp-smush-stats-holder {
297
  border: 1px solid lightgray;
298
  border-collapse: collapse;
@@ -486,8 +558,9 @@ table.wp-smush-stats-holder tr td:first-child {
486
  .wp-smush-auto-message {
487
  float: right;
488
  font-size: 15px;
 
489
  line-height: 1.7;
490
- margin: 1.4em auto;
491
  }
492
 
493
  .wp-smush-auto-disabled {
@@ -500,8 +573,61 @@ table.wp-smush-stats-holder tr td:first-child {
500
 
501
  .wp-smush-page-header {
502
  overflow: hidden;
503
- padding: 10px 0 0;
504
  margin: 0 0 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
  }
506
 
507
  .wpmud .wp-smush-welcome.wp-smush-container {
@@ -510,12 +636,24 @@ table.wp-smush-stats-holder tr td:first-child {
510
  background-position: 30px bottom;
511
  padding-bottom: 0;
512
  }
 
513
  .wpmud .wp-smush-welcome.wp-smush-container .box-content {
514
  min-height: 149px;
515
  }
516
 
517
- .wpmud .dev-box .box-title h3 {
 
 
 
 
 
 
 
 
 
 
518
  display: inline-block;
 
519
  }
520
 
521
  .smush-container-subheading {
@@ -526,28 +664,49 @@ table.wp-smush-stats-holder tr td:first-child {
526
  }
527
 
528
  .wp-smush-premium .smush-container-subheading {
529
- border: solid 1px #ff6d6d;
530
- border-radius: 4px;
531
- float: none;
532
  font-size: 12px;
533
  line-height: 1.4;
534
  margin: 1.3em 10px;
535
- padding: 5px 8px;
536
  vertical-align: top;
537
  }
538
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539
  .wpmud .wp-smush-premium .smush-container-subheading a {
540
- color: #ff6d6d;
 
 
 
 
 
 
 
541
  }
542
 
543
  .smush-stats-wrapper .smush-container-subheading {
544
- margin: 1em 0;
545
  max-width: 90%;
546
  }
547
 
548
- .wpmud .row .col-two-third.wp-smushit-container-left {
 
 
 
 
 
549
  padding-left: 0;
550
- width: 62%;
551
  }
552
 
553
  .wp-smush-premium .box-content {
@@ -584,6 +743,7 @@ table.wp-smush-stats-holder tr td:first-child {
584
 
585
  .wpmud .wp-smush-welcome-content h4 {
586
  font-size: 30px;
 
587
  text-align: left;
588
  }
589
 
@@ -615,7 +775,7 @@ table.wp-smush-stats-holder tr td:first-child {
615
  .wp-smush-upload-images {
616
  display: block;
617
  overflow: hidden;
618
- padding: 10px 0;
619
  }
620
 
621
  /** Ongoing Bulk Smush **/
@@ -625,21 +785,25 @@ table.wp-smush-stats-holder tr td:first-child {
625
 
626
  .wp-smush-bulk-active .spinner {
627
  float: left;
628
- margin-top: 0;
629
  }
630
 
631
  /** All Smushed **/
632
  .wp-smush-notice {
633
- background-color: #1abc9c;
634
  border-radius: 5px;
635
- color: white;
636
  font-family: 'Roboto', sans-serif;
637
  font-size: 15px;
638
- margin-bottom: 20px;
639
- padding: 20px 40px;
 
 
640
  }
641
 
642
- .wp-smush-resmush-message, .wp-smush-settings-updated {
 
 
643
  border: none;
644
  margin-bottom: 25px;
645
  padding: 18px 50px;
@@ -648,36 +812,84 @@ table.wp-smush-stats-holder tr td:first-child {
648
 
649
  .wpmud a.wp-smush-trigger-bulk, .wpmud a.wp-smush-trigger-bulk:hover,
650
  .wpmud a.wp-smush-trigger-bulk:focus, .wpmud a.wp-smush-trigger-bulk:active {
651
- color: white;
652
  text-decoration: underline;
653
  }
654
 
655
- .wp-smush-resmush-message .dev-icon, .wp-smush-settings-updated .dev-icon {
656
- font-size: 16px;
 
 
657
  }
658
 
659
- .wp-smush-resmush-message .dev-icon-cross, .wp-smush-settings-updated .dev-icon-cross {
660
- cursor: pointer;
661
- float: right;
 
 
662
  }
663
 
664
- .wp-smush-notice .dev-icon-tick:before {
665
- line-height: 1.1;
666
- vertical-align: bottom;
 
 
 
 
667
  }
668
 
669
  .wp-smush-all-done .dev-icon-tick {
670
  display: inline-block;
671
- font-size: 16px;
672
  margin-right: 10px;
673
- vertical-align: bottom;
 
674
  }
675
 
676
  /** Image Remaining **/
677
- .wp-smush-remaining {
678
- background-color: #fee696;
679
- color: #514a30;
680
- line-height: 1.7;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
681
  }
682
 
683
  .wp-smush-resmush-wrap .wp-smush-remaining {
@@ -686,16 +898,13 @@ table.wp-smush-stats-holder tr td:first-child {
686
 
687
  .wp-smush-remaining .dev-icon img {
688
  position: relative;
689
- top: 6px;
690
  width: 14px;
691
  }
692
 
693
- .wpmud .dev-box.bulk-smush-wrapper:not(.wp-smush-pro-install) {
694
- padding-bottom: 0;
695
- }
696
-
697
- .wpmud .bulk-smush-wrapper .dev-icon {
698
  margin-right: 10px;
 
699
  vertical-align: top;
700
  }
701
 
@@ -705,17 +914,28 @@ table.wp-smush-stats-holder tr td:first-child {
705
 
706
  .bulk-smush-wrapper .wp-smush-notice-text {
707
  display: inline-block;
708
- max-width: 90%;
709
  }
710
 
711
- .bulk-smush-wrapper .wp-smush-all {
712
- margin: 20px 0;
713
  }
714
 
715
- .bulk-smush-wrapper .wp-smush-remaining .wp-smush-skip-resmush {
716
- display: block;
717
- margin-left: 27px;
718
- margin-top: 10px;
 
 
 
 
 
 
 
 
 
 
 
719
  }
720
 
721
  .wp-smush-pro-trial {
@@ -800,6 +1020,7 @@ table.wp-smush-stats-holder tr td:first-child {
800
  }
801
 
802
  .smush-final-log {
 
803
  padding: 10px;
804
  }
805
 
@@ -813,6 +1034,7 @@ table.wp-smush-stats-holder tr td:first-child {
813
  .wpmud .wp-smush-enable-lossy {
814
  color: #adadad;
815
  font-size: 13px;
 
816
  }
817
 
818
  /** Settings Styling **/
@@ -824,16 +1046,28 @@ table.wp-smush-stats-holder tr td:first-child {
824
  }
825
 
826
  small.smush-setting-description {
827
- margin-top: 10px;
828
  display: block;
 
 
 
 
 
 
 
829
  }
830
 
831
  /** Stats Container **/
832
- .wpmud .smush-stats-wrapper {
833
- color: #777771;
834
- font-size: 15px;
835
  font-family: 'Roboto Condensed', sans-serif;
836
  font-weight: 700;
 
 
 
 
 
837
  }
838
 
839
  .wp-smush-lossy-disabled {
@@ -844,42 +1078,94 @@ small.smush-setting-description {
844
  padding: 10px;
845
  }
846
 
847
- .wp-smush-lossy-enable {
848
- background: #00ACCA;
 
849
  border-radius: 3px;
850
- color: #FFF;
851
- cursor: pointer;
852
- font: 500 11px/20px 'Roboto';
853
- padding: 10px;
854
  }
855
 
856
- .wp-smush-lossy-enable:hover, .wp-smush-lossy-enable:active, .wp-smush-lossy-enable:focus {
 
 
 
 
 
 
857
  background-color: #0093B1;
858
  color: #FFF;
859
  box-shadow: none;
 
 
860
  }
861
 
862
  .wpmud .wp-smush-stats, .wp-smush-stats-wrap {
863
  color: #555555;
864
  font-family: 'Roboto Condensed', sans-serif;
865
- font-size: 25px;
 
866
  line-height: 1;
867
  padding: 5px 0;
868
  }
869
 
 
 
 
 
 
 
 
 
 
870
  .wpmud .row .col-third.wp-smushit-container-right {
871
  padding-right: 0;
872
  width: 38%;
873
  }
874
 
875
  .wpmud .wp-smush-stats-label {
876
- padding-top: 7px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
877
  }
878
 
879
  /** For Smush Pro Promo and Humming Bird promo **/
880
- .wpmud .wp-smushit-container-right .wp-smush-pro-adv {
 
 
 
 
 
 
881
  overflow: hidden;
882
- padding: 30px 0 0;
883
  }
884
 
885
  .wpmud .dev-box.wp-smush-pro-adv .wp-smush-container-header {
@@ -896,16 +1182,19 @@ small.smush-setting-description {
896
  display: block;
897
  }
898
 
899
- .wp-smush-pro-cta, .wp-smush-hb-cta {
900
  overflow: hidden;
901
  display: block;
902
  padding: 20px;
903
  }
904
 
905
  .wp-smush-hb-cta {
 
 
 
906
  padding-bottom: 0;
907
  padding-top: 30px;
908
- width: 100%;
909
  }
910
 
911
  .wp-smush-hummingbird-image {
@@ -918,7 +1207,6 @@ small.smush-setting-description {
918
  color: #555555;
919
  line-height: 1.7;
920
  margin: auto;
921
- max-width: 320px;
922
  text-align: center;
923
  }
924
 
@@ -926,9 +1214,17 @@ small.smush-setting-description {
926
  margin-top: 30px;
927
  }
928
 
 
 
 
 
 
 
 
 
929
  .wpmud .wp-smush-hb-cta .button.button-cta {
930
- background-color: #ffe900;
931
- box-shadow: inset 0 -3px 0 0 #f0db00;
932
  color: #4e4b10;
933
  width: 100%;
934
  }
@@ -937,7 +1233,8 @@ small.smush-setting-description {
937
  .wpmud .box-content .wp-smush-hb-cta .button.button-cta.button-yellow:active,
938
  .wpmud .box-content .wp-smush-hb-cta .button.button-cta.button-yellow:focus {
939
  box-shadow: none;
940
- color: #4e4b10;
 
941
  }
942
 
943
  /** Re Smush **/
@@ -958,129 +1255,54 @@ small.smush-setting-description {
958
  font-weight: bold;
959
  }
960
 
961
- @media screen and (max-width: 1024px) and ( min-width: 800px ) {
962
- .wpmud .wrap .dev-box:not(.wp-smush-pro-adv) {
963
- padding: 20px;
964
- }
965
-
966
- .wpmud .dev-box.wp-smush-pro-adv .box-title, .wpmud .wp-smush-pro-adv .box-content {
967
- padding: 0 20px;
968
- }
969
-
970
- /** Stats Section **/
971
- .wpmud .smush-stats-wrapper {
972
- font-size: 12px;
973
- }
974
 
975
- .smush-stats-wrapper h3 {
976
- padding: 6px 0;
977
- }
978
 
979
- .smush-stats-wrapper .smush-container-subheading {
980
- margin-top: 20px;
981
- }
982
 
983
- .wpmud .wp-smush-stats, .wp-smush-stats-wrap {
984
- font-size: 20px;
985
- }
 
986
 
987
- /** Sub Heading **/
988
- .wpmud .smush-container-subheading {
989
- font-size: 12px;
990
- }
 
 
 
 
 
 
 
 
 
991
  }
992
 
993
- /** Media Queries for resolution between 782px - 1024px **/
994
- @media screen and (max-width: 1024px) {
995
- /** Configure screen **/
996
- .wpmud .row .wp-smush-lady.col-third {
997
- display: none;
998
- }
999
-
1000
- /** Media Library Stats **/
1001
- .wp-list-table .smushit .wp-smush-stats-holder tr th {
1002
- display: inline-block;
1003
- width: 50%;
1004
- box-sizing: border-box;
1005
- }
1006
-
1007
- .wp-list-table .smushit .wp-smush-stats-holder tr td:first-child {
1008
- border-right: none;
1009
- box-sizing: border-box;
1010
- display: inline-block !important;
1011
- width: 50% !important;
1012
- }
1013
-
1014
- .wp-list-table .smushit .wp-smush-stats-holder tr td:last-child {
1015
- box-sizing: border-box;
1016
- display: inline-block !important;
1017
- float: none;
1018
- width: 50% !important;
1019
- }
1020
-
1021
- .wpmud .wp-smush-promo-content, .wpmud .wp-smush-promo-content-smaller {
1022
- max-width: none;
1023
- }
1024
- }
1025
-
1026
- /** Media Queries for resolution below 782px **/
1027
- @media only screen and (max-width: 800px) {
1028
- .wpmud .wp-smushit-container-wrap .col-two-third.wp-smushit-container-left, .wpmud .wp-smushit-container-wrap .col-third.wp-smushit-container-right {
1029
- padding: 0;
1030
- width: 100%;
1031
- }
1032
- .wpmud .wp-smush-welcome-content {
1033
- margin: 0 30px 0px 160px;
1034
- }
1035
- .dev-box.bulk-smush-wrapper.wp-smush-container {
1036
- padding: 20px 10px;
1037
- }
1038
- .wpmud .wp-smush-super-smush-content {
1039
- font-size: 11px;
1040
- margin-left: 160px;
1041
- padding: 15px 20px;
1042
- }
1043
- }
1044
-
1045
- /** For Media Gallery and Other WordPress pages **/
1046
- /** No Caps for the tooltips **/
1047
- .wp-admin.wpmud [tooltip]:after {
1048
- text-transform: none !important;
1049
- }
1050
- .smushit [tooltip] {
1051
- position: relative;
1052
- overflow: visible;
1053
- }
1054
-
1055
- .smushit [tooltip]:before {
1056
- content: '';
1057
- position: absolute;
1058
- border: 5px solid transparent;
1059
- border-top-color: #0B2F3F;
1060
- bottom: 100%;
1061
- left: 50%;
1062
- margin-left: -5px;
1063
- margin-bottom: -5px;
1064
- opacity: 0;
1065
- z-index: -1;
1066
- transition: margin .2s, opacity .2s, z-index .2s linear .2s;
1067
- pointer-events: none;
1068
- }
1069
-
1070
- .smushit [tooltip]:after {
1071
  content: attr(tooltip);
1072
  position: absolute;
1073
  background: #0B2F3F;
1074
  color: #FFF;
1075
  bottom: 100%;
1076
  left: 50%;
1077
- width: 200px;
1078
  margin-left: -100px;
1079
  margin-bottom: 5px;
1080
  text-align: center;
1081
  padding: 5px;
1082
  border-radius: 4px;
1083
- font: 600 13px/20px 'Roboto Condensed';
1084
  opacity: 0;
1085
  z-index: -1;
1086
  transition: margin .2s, opacity .2s, z-index .2s linear .2s;
@@ -1088,29 +1310,44 @@ small.smush-setting-description {
1088
  pointer-events: none;
1089
  }
1090
 
1091
- .smushit [tooltip].tooltip-s:after {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1092
  width: 150px;
1093
  margin-left: -75px;
1094
  }
1095
 
1096
- .smushit [tooltip].tooltip-l:after {
1097
  width: 280px;
1098
  margin-left: -140px;
1099
  }
1100
 
1101
- .smushit [tooltip].tooltip-right:after {
1102
  margin-left: -180px;
1103
  }
1104
 
1105
- .smushit [tooltip].tooltip-s.tooltip-right:after {
1106
  margin-left: -130px;
1107
  }
1108
 
1109
- .smushit [tooltip].tooltip-l.tooltip-right:after {
1110
  margin-left: -260px;
1111
  }
1112
 
1113
- .smushit [tooltip].tooltip-bottom:before {
1114
  border-color: transparent;
1115
  border-bottom-color: #0B2F3F;
1116
  top: 100%;
@@ -1119,21 +1356,21 @@ small.smush-setting-description {
1119
  margin-bottom: 0;
1120
  }
1121
 
1122
- .smushit [tooltip].tooltip-bottom:after {
1123
  bottom: auto;
1124
  top: 100%;
1125
  margin-top: 5px;
1126
  margin-bottom: 0;
1127
  }
1128
 
1129
- .smushit [tooltip]:hover:before {
1130
- opacity: 1;
1131
  z-index: 1;
1132
  margin-bottom: 0;
 
1133
  transition: margin .2s, opacity .2s;
1134
  }
1135
 
1136
- .smushit [tooltip]:hover:after {
1137
  opacity: 1;
1138
  z-index: 1;
1139
  margin-bottom: 10px;
@@ -1141,7 +1378,9 @@ small.smush-setting-description {
1141
  }
1142
 
1143
  .smushit .disabled[tooltip]:before,
1144
- .smushit .disabled[tooltip]:after {
 
 
1145
  display: none;
1146
  }
1147
 
@@ -1166,6 +1405,7 @@ small.smush-setting-description {
1166
  position: relative;
1167
  width: 58%;
1168
  }
 
1169
  /** Arrow **/
1170
  .wp-smush-super-smush-content:after {
1171
  right: 100%;
@@ -1181,9 +1421,962 @@ small.smush-setting-description {
1181
  border-width: 10px;
1182
  margin-top: -10px;
1183
  }
 
1184
  .wpmud .wp-smush-super-smush-content a,
1185
  .wpmud .wp-smush-super-smush-content a:hover,
1186
  .wpmud .wp-smush-super-smush-content a:visited {
1187
  color: black;
1188
  text-decoration: underline;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1189
  }
68
  margin-top: 18px;
69
  }
70
 
 
 
 
 
 
 
 
 
 
 
 
71
  /** Settings Page **/
72
 
73
  .wp-smush-setting-row {
74
  margin: 15px 20px 15px 0;
75
  }
76
 
77
+ .wpmud .toggle .toggle-checkbox:focus + .toggle-label:before {
78
+ background: #c1c1c1;
79
+ }
80
+
81
+ .wpmud .wp-smush-setting-row .toggle-checkbox:checked:focus + .toggle-label {
82
+ box-shadow: 0 1px 1px rgba(26, 188, 156, 0.75);
83
+ }
84
+
85
  .wpmud .wp-smushit-container-wrap {
86
  display: inline-block;
87
  margin-top: 30px;
88
  }
89
 
90
+ .wpmud .bulk-smush-wrapper.wp-smush-container:not(.wp-smush-pro-install) {
91
+ padding-bottom: 0;
92
+ }
93
+
94
+ .wpmud .wp-smush-pro.smush-settings-wrapper {
95
+ padding-bottom: 24px;
96
  width: 100%;
97
  }
98
 
103
  }
104
 
105
  .wpmud .wp-smush-submit-wrap {
106
+ margin-top: 17px;
107
+ overflow: hidden;
108
  padding-top: 0;
109
  }
110
 
111
  .wp-smush-submit-wrap .spinner {
112
+ float: right;
113
  margin: 1.5em 1em 0;
114
  }
115
 
116
  input#wp-smush-save-settings {
117
+ background: #17A8E3;
118
+ float: right;
119
  margin: 10px 0 5px;
120
  }
121
 
122
+ input#wp-smush-save-settings:hover {
123
+ background: #0A9BD6;
124
+ }
125
+
126
  .wp-smush-welcome #wp-smush-save-settings {
127
  float: right;
128
  }
259
  .compat-field-wp_smush .smush-wrap {
260
  margin: 0 0 5px 0;
261
  max-width: 100%;
 
262
  }
263
 
264
  .inactive {
285
  padding-top: 0;
286
  }
287
 
288
+ div#smush-avg-pro-savings {
289
+ background: rgba(242, 242, 242, 0.5);;
290
+ border-top: 1px solid #ddd;
291
+ margin-top: 12px;
292
+ padding: 14px 28px 12px 30px;
293
+ }
294
+
295
+ div#smush-avg-pro-savings:before, div#smush-avg-pro-savings:after {
296
+ margin: 0 -10px;
297
+ }
298
+
299
+ div.row.smush-avg-pro-savings {
300
+ padding-bottom: 8px;
301
+ padding-top: 19px;
302
+ }
303
+ div.row.smush-avg-pro-savings span.wp-smush-stats-label strong, div.row.smush-avg-pro-savings span.wp-smush-stats {
304
+ opacity: 0.5;
305
  }
306
 
307
  .wpmud .wp-smushit-container-right .smush-stats-wrapper .wp-smush-container-header {
308
+ padding: 0 30px;
309
  }
310
 
311
  .smush-stats-wrapper td, .smush-stats-wrapper th {
317
  margin: 7px 8px 0;
318
  }
319
 
320
+ .smush-stats-wrapper .box-content {
321
+ margin-top: 20px;
322
+ padding-left: 30px;
323
+ padding-right: 30px;
324
+ }
325
+
326
+ .wp-smush-count-total {
327
+ display: inline-block;
328
+ line-height: 1;
329
+ margin-left: 15px;
330
+ overflow: hidden;
331
+ text-align: left;
332
+ }
333
+
334
+ .wp-smush-smush-stats-wrapper {
335
+ color: #555555;
336
+ font-size: 25px;
337
+ }
338
+
339
+ .total-stats-label {
340
+ color: #b9b9b9;
341
+ font-size: 12px;
342
+ }
343
+
344
+ .wpmud .smush-total-savings.smush-total-reduction-percent {
345
+ margin-bottom: 18px;
346
+ text-align: center;
347
+ }
348
+
349
+ .smush-total-savings.smush-total-reduction-percent .wp-smush-stats-wrap {
350
+ display: inline-block;
351
+ max-width: 200px;
352
+ text-align: left;
353
+ vertical-align: middle;
354
+ }
355
+
356
+ .wp-smush-current-progress {
357
+ cursor: pointer;
358
+ margin: 0 auto;
359
+ width: 200px;
360
+ }
361
+
362
+ .wp-smushed-progress {
363
+ display: inline-block;
364
+ text-align: center;
365
+ vertical-align: bottom;
366
+ }
367
+
368
  table.wp-smush-stats-holder {
369
  border: 1px solid lightgray;
370
  border-collapse: collapse;
558
  .wp-smush-auto-message {
559
  float: right;
560
  font-size: 15px;
561
+ letter-spacing: -0.015em;
562
  line-height: 1.7;
563
+ margin: 1.2em auto;
564
  }
565
 
566
  .wp-smush-auto-disabled {
573
 
574
  .wp-smush-page-header {
575
  overflow: hidden;
 
576
  margin: 0 0 20px;
577
+ width: 100%;
578
+ }
579
+
580
+ #wp-smush-invalid-member {
581
+ border-radius: 5px;
582
+ font-family: 'Roboto', sans-serif;
583
+ font-size: 15px;
584
+ -webkit-font-smoothing: antialiased;
585
+ font-weight: 500;
586
+ margin-bottom: 20px;
587
+ overflow: hidden;
588
+ padding: 15px 30px;
589
+ position: relative;
590
+ }
591
+
592
+ #wp-smush-invalid-member.loading-notice:before {
593
+ content: attr(data-message);
594
+ position: absolute;
595
+ left: 0;
596
+ right: 0;
597
+ top: 0;
598
+ bottom: 0;
599
+ background-color: rgba(255, 255, 255, 0.7);
600
+ z-index: 5;
601
+ text-align: center;
602
+ line-height: 80px;
603
+ font-size: 18px;
604
+ }
605
+
606
+ #wp-smush-invalid-member.loaded-notice:before {
607
+ content: attr(data-message);
608
+ position: absolute;
609
+ left: 0;
610
+ right: 0;
611
+ top: 0;
612
+ bottom: 0;
613
+ background-color: rgba(255, 255, 255, 0.7);
614
+ z-index: 5;
615
+ text-align: center;
616
+ line-height: 80px;
617
+ font-size: 18px;
618
+ }
619
+
620
+ #wp-smush-invalid-member.loading-notice > div, #wp-smush-invalid-member.loaded-notice > div {
621
+ -webkit-filter: blur(2px);
622
+ -moz-filter: blur(2px);
623
+ -o-filter: blur(2px);
624
+ -ms-filter: blur(2px);
625
+ filter: blur(2px);
626
+ }
627
+
628
+ #wp-smush-invalid-member a {
629
+ color: #514a30;
630
+ text-decoration: underline;
631
  }
632
 
633
  .wpmud .wp-smush-welcome.wp-smush-container {
636
  background-position: 30px bottom;
637
  padding-bottom: 0;
638
  }
639
+
640
  .wpmud .wp-smush-welcome.wp-smush-container .box-content {
641
  min-height: 149px;
642
  }
643
 
644
+ .wpmud .box-container {
645
+ letter-spacing: -0.015em;
646
+ }
647
+
648
+ .wpmud .smush-page-wrap .dev-box .box-title {
649
+ height: 67px;
650
+ margin: -25px 0px 28px;
651
+ }
652
+
653
+ .wpmud .dev-box .wp-smush-container-header.box-title h3 {
654
+ color: #333333;
655
  display: inline-block;
656
+ font-size: 15px;
657
  }
658
 
659
  .smush-container-subheading {
664
  }
665
 
666
  .wp-smush-premium .smush-container-subheading {
 
 
 
667
  font-size: 12px;
668
  line-height: 1.4;
669
  margin: 1.3em 10px;
 
670
  vertical-align: top;
671
  }
672
 
673
+ .wpmud .wp-smush-premium .smush-container-subheading:hover > a {
674
+ background-color: #1ABC9C;
675
+ color: #fff;
676
+ }
677
+
678
+
679
+ .wpmud .row .col-half.wp-smush-pro-for-free {
680
+ padding-left: 0;
681
+ }
682
+
683
+ .wpmud .row .col-half.wp-smush-pro-for-free .dev-box {
684
+ padding: 30px 0;
685
+ }
686
+
687
  .wpmud .wp-smush-premium .smush-container-subheading a {
688
+ border: solid 2px #1ABC9C;
689
+ border-radius: 13px;
690
+ color: #1ABC9C;
691
+ padding: 4px 10px;
692
+ }
693
+
694
+ .wpmud .wp-smush-premium .smush-container-subheading a:hover {
695
+ color: #fff;
696
  }
697
 
698
  .smush-stats-wrapper .smush-container-subheading {
699
+ margin: 1.2em 0 0.9em;
700
  max-width: 90%;
701
  }
702
 
703
+ .wpmud .smush-stats-wrapper .smush-container-subheading button.wp-smush-scan:not(.wph-button):not(#collapse-button) {
704
+ font-size: 12px;
705
+ padding: 5px 16px 5px;
706
+ }
707
+
708
+ .wpmud .row .col-half.wp-smushit-container-left {
709
  padding-left: 0;
 
710
  }
711
 
712
  .wp-smush-premium .box-content {
743
 
744
  .wpmud .wp-smush-welcome-content h4 {
745
  font-size: 30px;
746
+ line-height: 1.4;
747
  text-align: left;
748
  }
749
 
775
  .wp-smush-upload-images {
776
  display: block;
777
  overflow: hidden;
778
+ padding: 10px 0 40px;
779
  }
780
 
781
  /** Ongoing Bulk Smush **/
785
 
786
  .wp-smush-bulk-active .spinner {
787
  float: left;
788
+ margin-top: 5px;
789
  }
790
 
791
  /** All Smushed **/
792
  .wp-smush-notice {
793
+ background-color: #D1F1EA;
794
  border-radius: 5px;
795
+ color: #333333;
796
  font-family: 'Roboto', sans-serif;
797
  font-size: 15px;
798
+ line-height: 30px;
799
+ margin-bottom: 30px;
800
+ padding: 15px 30px;
801
+ letter-spacing: -0.015em;
802
  }
803
 
804
+ .wp-smush-resmush-message,
805
+ .wp-smush-settings-updated,
806
+ .wp-smush-re-check-message {
807
  border: none;
808
  margin-bottom: 25px;
809
  padding: 18px 50px;
812
 
813
  .wpmud a.wp-smush-trigger-bulk, .wpmud a.wp-smush-trigger-bulk:hover,
814
  .wpmud a.wp-smush-trigger-bulk:focus, .wpmud a.wp-smush-trigger-bulk:active {
815
+ color: #333333;
816
  text-decoration: underline;
817
  }
818
 
819
+ .wp-smush-resmush-message .dev-icon,
820
+ .wp-smush-settings-updated .dev-icon,
821
+ .wp-smush-re-check-message .dev-icon {
822
+ font-size: 22px;
823
  }
824
 
825
+ .wp-smush-resmush-message .dev-icon-tick,
826
+ .wp-smush-settings-updated .dev-icon-tick {
827
+ font-size: 22px;
828
+ margin-right: 5px;
829
+ vertical-align: middle;
830
  }
831
 
832
+ .wp-smush-resmush-message .dev-icon-cross,
833
+ .wp-smush-settings-updated .dev-icon-cross,
834
+ .wp-smush-re-check-message .dev-icon-cross {
835
+ cursor: pointer;
836
+ float: right;
837
+ font-size: 16px;
838
+ margin-top: 8px;
839
  }
840
 
841
  .wp-smush-all-done .dev-icon-tick {
842
  display: inline-block;
843
+ font-size: 22px;
844
  margin-right: 10px;
845
+ margin-top: -3px;
846
+ vertical-align: middle;
847
  }
848
 
849
  /** Image Remaining **/
850
+ div.wp-smush-remaining,
851
+ #wp-smush-invalid-member,
852
+ div.wp-smush-dir-remaining,
853
+ div.wp-smush-dir-limit,
854
+ div.smush-s3-setup-error {
855
+ background-color: #FFF5D5;
856
+ border: none;
857
+ color: #333333;
858
+ line-height: 30px;
859
+ font-size: 15px;
860
+ letter-spacing: -0.015em;
861
+ }
862
+
863
+ div.smush-s3-setup-error a {
864
+ color: #333;
865
+ cursor: pointer;
866
+ text-decoration: underline;
867
+ }
868
+
869
+ div.wp-smush-dir-limit {
870
+ background-color: #dff6fa;
871
+ }
872
+
873
+ div.wp-smush-notice .dev-icon-tick:before,
874
+ div.wp-smush-all-done .dev-icon-tick:before,
875
+ div.wp-smush-dir-all-done .dev-icon-tick:before {
876
+ content: "\67";
877
+ color: #1ABC9C;
878
+ }
879
+
880
+ .wpmud div.wp-smush-notice.wp-smush-dir-limit a,
881
+ .wpmud div.wp-smush-notice.wp-smush-remaining a {
882
+ color: #333;
883
+ text-decoration: underline;
884
+ }
885
+
886
+ div.wp-smush-dir-remaining .wdv-icon-exclamation-sign:before,
887
+ div.smush-s3-setup-error .wdv-icon-exclamation-sign:before {
888
+ color: #FECF2F;
889
+ }
890
+
891
+ div.wp-smush-dir-limit .wdv-icon-info-sign:before {
892
+ color: #333;
893
  }
894
 
895
  .wp-smush-resmush-wrap .wp-smush-remaining {
898
 
899
  .wp-smush-remaining .dev-icon img {
900
  position: relative;
901
+ top: 8px;
902
  width: 14px;
903
  }
904
 
905
+ .wpmud .bulk-smush-wrapper .wp-smush-remaining .dev-icon {
 
 
 
 
906
  margin-right: 10px;
907
+ line-height: 30px;
908
  vertical-align: top;
909
  }
910
 
914
 
915
  .bulk-smush-wrapper .wp-smush-notice-text {
916
  display: inline-block;
917
+ max-width: 88%;
918
  }
919
 
920
+ .wpmud .bulk-smush-wrapper .wp-smush-all {
921
+ margin: 22px 0 0 !important;
922
  }
923
 
924
+ .wpmud .bulk-smush-wrapper .wp-smush-remaining button.wp-smush-skip-resmush:not(.wph-button):not(#collapse-button) {
925
+ background-color: transparent;
926
+ border: solid 2px #888888;
927
+ color: #888888;
928
+ display: block !important;
929
+ font-size: 12px;
930
+ font-weight: 600;
931
+ margin-left: 27px !important;
932
+ margin-top: 10px !important;
933
+ padding: 5px 16px;
934
+ }
935
+ .wpmud .bulk-smush-wrapper .wp-smush-remaining button.wp-smush-skip-resmush:not(.wph-button):not(#collapse-button):not([tooltip]):hover {
936
+ background-color: transparent !important;
937
+ border: solid 2px #7d7d7d;
938
+ color: #7d7d7d;
939
  }
940
 
941
  .wp-smush-pro-trial {
1020
  }
1021
 
1022
  .smush-final-log {
1023
+ margin-left: 0;
1024
  padding: 10px;
1025
  }
1026
 
1034
  .wpmud .wp-smush-enable-lossy {
1035
  color: #adadad;
1036
  font-size: 13px;
1037
+ margin-top: 20px;
1038
  }
1039
 
1040
  /** Settings Styling **/
1046
  }
1047
 
1048
  small.smush-setting-description {
1049
+ color: #888888;
1050
  display: block;
1051
+ font-size: 13px;
1052
+ line-height: 22px;
1053
+ margin-top: 10px;
1054
+ }
1055
+
1056
+ small.smush-setting-description strong {
1057
+ color: #5f5d5d
1058
  }
1059
 
1060
  /** Stats Container **/
1061
+ .wpmud .dev-box.smush-stats-wrapper {
1062
+ color: #333333;
1063
+ font-size: 13px;
1064
  font-family: 'Roboto Condensed', sans-serif;
1065
  font-weight: 700;
1066
+ padding: 30px 0 24px 0;
1067
+ }
1068
+
1069
+ .wpmud .smush-stats-wrapper strong {
1070
+ font-weight: 700;
1071
  }
1072
 
1073
  .wp-smush-lossy-disabled {
1078
  padding: 10px;
1079
  }
1080
 
1081
+ .wpmud .wp-smush-stats .button-small.wp-smush-lossy-enable,
1082
+ .wpmud .wp-smush-dir-link,
1083
+ .wpmud .wp-smush-stats .button-small.wp-smush-resize-enable {
1084
  border-radius: 3px;
1085
+ font: 500 12px/20px 'Roboto' !important;
1086
+ padding: 4px 15px !important;
1087
+ vertical-align: top;
 
1088
  }
1089
 
1090
+ .wpmud .wp-smush-lossy-enable:hover,
1091
+ .wpmud .wp-smush-lossy-enable:active,
1092
+ .wpmud .wp-smush-lossy-enable:focus,
1093
+ .wpmud .wp-smush-dir-link,
1094
+ .wpmud .wp-smush-resize-enable:hover,
1095
+ .wpmud .wp-smush-resize-enable:active,
1096
+ .wpmud .wp-smush-resize-enable:focus {
1097
  background-color: #0093B1;
1098
  color: #FFF;
1099
  box-shadow: none;
1100
+ transform: none;
1101
+ -webkit-transform: none;
1102
  }
1103
 
1104
  .wpmud .wp-smush-stats, .wp-smush-stats-wrap {
1105
  color: #555555;
1106
  font-family: 'Roboto Condensed', sans-serif;
1107
+ font-size: 20px;
1108
+ font-weight: 400;
1109
  line-height: 1;
1110
  padding: 5px 0;
1111
  }
1112
 
1113
+ .wp-smush-stats-wrap .wp-smush-progress-text {
1114
+ color: #b9b9b9;
1115
+ font-size: 12px;
1116
+ }
1117
+
1118
+ .wpmud .wp-smush-lossy-disabled-wrap {
1119
+ padding: 0;
1120
+ }
1121
+
1122
  .wpmud .row .col-third.wp-smushit-container-right {
1123
  padding-right: 0;
1124
  width: 38%;
1125
  }
1126
 
1127
  .wpmud .wp-smush-stats-label {
1128
+ padding-top: 9px;
1129
+ }
1130
+
1131
+ .wp-smush-stats-label .wdv-icon.wdv-icon-question-sign {
1132
+ margin-left: 3px;
1133
+ }
1134
+
1135
+ .wpmud .wp-smush-stats-try-pro {
1136
+ font-size: 12px;
1137
+ font-weight: 500;
1138
+ margin-left: 15px;
1139
+ vertical-align: top;
1140
+ }
1141
+
1142
+ .wpmud .wp-smush-stats-try-pro a, .wpmud .wp-smush-stats-try-pro a:focus {
1143
+ border: solid 2px #1ABC9C;
1144
+ border-radius: 13px;
1145
+ color: #1ABC9C;
1146
+ padding: 4px 10px;
1147
+ }
1148
+
1149
+ .wpmud .wp-smush-stats-try-pro:hover > a, .wpmud .wp-smush-stats-try-pro a:hover {
1150
+ background-color: #1ABC9C;
1151
+ color: #fff;
1152
+ cursor: pointer;
1153
+ }
1154
+
1155
+ .wp-smush-total-thumbnails .dashicons-editor-help {
1156
+ cursor: pointer;
1157
+ margin-top: -2px;
1158
  }
1159
 
1160
  /** For Smush Pro Promo and Humming Bird promo **/
1161
+ .wpmud .wp-smush-pro-adv {
1162
+ background-image: url(../images/dev-team.png);
1163
+ background-repeat: no-repeat;
1164
+ background-position: center bottom;
1165
+ background-size: 90%;
1166
+ height: 500px;
1167
+ margin-top: 8px;
1168
  overflow: hidden;
 
1169
  }
1170
 
1171
  .wpmud .dev-box.wp-smush-pro-adv .wp-smush-container-header {
1182
  display: block;
1183
  }
1184
 
1185
+ .wp-smush-pro-cta {
1186
  overflow: hidden;
1187
  display: block;
1188
  padding: 20px;
1189
  }
1190
 
1191
  .wp-smush-hb-cta {
1192
+ display: block;
1193
+ margin: 0 auto;
1194
+ overflow: hidden;
1195
  padding-bottom: 0;
1196
  padding-top: 30px;
1197
+ width: 242px;
1198
  }
1199
 
1200
  .wp-smush-hummingbird-image {
1207
  color: #555555;
1208
  line-height: 1.7;
1209
  margin: auto;
 
1210
  text-align: center;
1211
  }
1212
 
1214
  margin-top: 30px;
1215
  }
1216
 
1217
+ .wpmud .wp-smush-pro-cta .button.button-cta {
1218
+ box-shadow: none !important;
1219
+ }
1220
+
1221
+ .wpmud .wp-smush-pro-cta .button.button-cta:hover {
1222
+ background: #0A9BD6 !important;
1223
+ }
1224
+
1225
  .wpmud .wp-smush-hb-cta .button.button-cta {
1226
+ background-color: #FFEA00;
1227
+ box-shadow: none;
1228
  color: #4e4b10;
1229
  width: 100%;
1230
  }
1233
  .wpmud .box-content .wp-smush-hb-cta .button.button-cta.button-yellow:active,
1234
  .wpmud .box-content .wp-smush-hb-cta .button.button-cta.button-yellow:focus {
1235
  box-shadow: none;
1236
+ background: #f7e303 !important;
1237
+ color: #4e4b10 !important;
1238
  }
1239
 
1240
  /** Re Smush **/
1255
  font-weight: bold;
1256
  }
1257
 
1258
+ /** For Media Gallery and Other WordPress pages **/
1259
+ /** No Caps for the tooltips **/
1260
+ .wp-admin.wpmud [tooltip]:after {
1261
+ text-transform: none !important;
1262
+ }
 
 
 
 
 
 
 
 
1263
 
1264
+ .compat-item .compat-field-wp_smush {
1265
+ display: table-row;
1266
+ }
1267
 
1268
+ .manage-column.column-smushit {
1269
+ width: 260px;
1270
+ }
1271
 
1272
+ .smushit [tooltip], .compat-field-wp_smush [tooltip] {
1273
+ position: relative;
1274
+ overflow: visible;
1275
+ }
1276
 
1277
+ .smushit [tooltip]:before, .compat-field-wp_smush [tooltip]:before {
1278
+ content: '';
1279
+ position: absolute;
1280
+ border: 5px solid transparent;
1281
+ border-top-color: #0B2F3F;
1282
+ bottom: 100%;
1283
+ left: 50%;
1284
+ margin-left: -5px;
1285
+ margin-bottom: -5px;
1286
+ opacity: 0;
1287
+ z-index: -1;
1288
+ transition: margin .2s, opacity .2s, z-index .2s linear .2s;
1289
+ pointer-events: none;
1290
  }
1291
 
1292
+ .smushit [tooltip]:after, .compat-field-wp_smush [tooltip]:after {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1293
  content: attr(tooltip);
1294
  position: absolute;
1295
  background: #0B2F3F;
1296
  color: #FFF;
1297
  bottom: 100%;
1298
  left: 50%;
1299
+ width: 180px;
1300
  margin-left: -100px;
1301
  margin-bottom: 5px;
1302
  text-align: center;
1303
  padding: 5px;
1304
  border-radius: 4px;
1305
+ font: 400 13px/20px 'Roboto Condensed';
1306
  opacity: 0;
1307
  z-index: -1;
1308
  transition: margin .2s, opacity .2s, z-index .2s linear .2s;
1310
  pointer-events: none;
1311
  }
1312
 
1313
+ .smushit .smush-skipped [tooltip]:before, .compat-field-wp_smush .smush-skipped [tooltip]:before {
1314
+ border-top-color: transparent;
1315
+ border-left-color: #0B2F3F;
1316
+ bottom: 0;
1317
+ left: 0;
1318
+ }
1319
+
1320
+ .smushit .smush-skipped [tooltip]:after, .compat-field-wp_smush .smush-skipped [tooltip]:after {
1321
+ margin-left: 0;
1322
+ left: -195px;
1323
+ top: -35px;
1324
+ bottom: inherit;
1325
+ margin-bottom: 5px;
1326
+ }
1327
+
1328
+ .smushit [tooltip].tooltip-s:after, .compat-field-wp_smush [tooltip].tooltip-s:after {
1329
  width: 150px;
1330
  margin-left: -75px;
1331
  }
1332
 
1333
+ .smushit [tooltip].tooltip-l:after, .compat-field-wp_smush [tooltip].tooltip-l:after {
1334
  width: 280px;
1335
  margin-left: -140px;
1336
  }
1337
 
1338
+ .smushit [tooltip].tooltip-right:after, .compat-field-wp_smush [tooltip].tooltip-right:after {
1339
  margin-left: -180px;
1340
  }
1341
 
1342
+ .smushit [tooltip].tooltip-s.tooltip-right:after, .compat-field-wp_smush [tooltip].tooltip-s.tooltip-right:after {
1343
  margin-left: -130px;
1344
  }
1345
 
1346
+ .smushit [tooltip].tooltip-l.tooltip-right:after, .compat-field-wp_smush [tooltip].tooltip-l.tooltip-right:after {
1347
  margin-left: -260px;
1348
  }
1349
 
1350
+ .smushit [tooltip].tooltip-bottom:before, .compat-field-wp_smush [tooltip].tooltip-bottom:before {
1351
  border-color: transparent;
1352
  border-bottom-color: #0B2F3F;
1353
  top: 100%;
1356
  margin-bottom: 0;
1357
  }
1358
 
1359
+ .smushit [tooltip].tooltip-bottom:after, .compat-field-wp_smush [tooltip].tooltip-bottom:after {
1360
  bottom: auto;
1361
  top: 100%;
1362
  margin-top: 5px;
1363
  margin-bottom: 0;
1364
  }
1365
 
1366
+ .smushit [tooltip]:hover:before, .compat-field-wp_smush [tooltip]:hover:before {
 
1367
  z-index: 1;
1368
  margin-bottom: 0;
1369
+ opacity: 1;
1370
  transition: margin .2s, opacity .2s;
1371
  }
1372
 
1373
+ .smushit [tooltip]:hover:after, .compat-field-wp_smush [tooltip]:hover:after {
1374
  opacity: 1;
1375
  z-index: 1;
1376
  margin-bottom: 10px;
1378
  }
1379
 
1380
  .smushit .disabled[tooltip]:before,
1381
+ .smushit .disabled[tooltip]:after,
1382
+ .compat-field-wp_smush .disabled[tooltip]:before,
1383
+ .compat-field-wp_smush .disabled[tooltip]:after {
1384
  display: none;
1385
  }
1386
 
1405
  position: relative;
1406
  width: 58%;
1407
  }
1408
+
1409
  /** Arrow **/
1410
  .wp-smush-super-smush-content:after {
1411
  right: 100%;
1421
  border-width: 10px;
1422
  margin-top: -10px;
1423
  }
1424
+
1425
  .wpmud .wp-smush-super-smush-content a,
1426
  .wpmud .wp-smush-super-smush-content a:hover,
1427
  .wpmud .wp-smush-super-smush-content a:visited {
1428
  color: black;
1429
  text-decoration: underline;
1430
+ }
1431
+
1432
+ .wpmud .wp-smush-setting-row .toggle .toggle-checkbox {
1433
+ display: inline-block;
1434
+ opacity: 0;
1435
+ }
1436
+
1437
+ .wp-smush-resize-settings-wrap, .wp-smush-png_to_jpg-wrap, .wp-smush-image-size-list {
1438
+ background: rgba(0, 0, 0, 0.05);
1439
+ border-radius: 5px;
1440
+ color: #555;
1441
+ font-family: "Roboto", sans-serif;
1442
+ margin: 1.5em 0;
1443
+ overflow: auto;
1444
+ padding: 30px;
1445
+ vertical-align: middle;
1446
+ }
1447
+
1448
+ .wpmud .wp-smush-image-size-list label {
1449
+ clear: left;
1450
+ float: left;
1451
+ font-size: 13px;
1452
+ }
1453
+
1454
+ .wpmud .wp-smush-resize-settings-wrap label {
1455
+ display: inline-block;
1456
+ margin-bottom: 0;
1457
+ overflow: hidden;
1458
+ }
1459
+
1460
+ .wpmud .wp-smush-png_to_jpg-wrap label {
1461
+ font-weight: 400;
1462
+ }
1463
+
1464
+ .wpmud .wp-smush-resize-settings-wrap label:first-child {
1465
+ padding-left: 0;
1466
+ }
1467
+
1468
+ .wpmud .wp-smush-resize-settings-wrap .wp-smush-resize-input, .wpmud .wp-smush-png_to_jpg-wrap .wp-smush-png_to_jpg_background {
1469
+ display: inline-block;
1470
+ margin-left: 10px;
1471
+ width: 120px;
1472
+ }
1473
+
1474
+ .wpmud .wp-smush-png_to_jpg-wrap .wp-smush-png_to_jpg_background {
1475
+ margin-left: 0;
1476
+ width: 100px;
1477
+ }
1478
+
1479
+ .wpmud .wp-smush-resize-input.error, .wpmud #png_to_jpg_background.error {
1480
+ border-color: #fd8b8b;
1481
+ }
1482
+
1483
+ .wpmud .smush-s3-setup-error {
1484
+ margin-top: 15px;
1485
+ }
1486
+
1487
+ .wpmud .smush-s3-setup-error p {
1488
+ color: #333;
1489
+ display: inline-block;
1490
+ font-size: 15px;
1491
+ margin-top: 0;
1492
+ }
1493
+
1494
+ .wp-smush-settings-info {
1495
+ background: #e0f6fa;
1496
+ border-radius: 5px;
1497
+ font-size: 13px;
1498
+ line-height: 1.5;
1499
+ margin-top: 20px;
1500
+ padding: 20px 30px;
1501
+ }
1502
+
1503
+ .smush-final-log.notice.notice-warning {
1504
+ max-height: 200px;
1505
+ overflow: auto;
1506
+ }
1507
+
1508
+ /** Hide W3TC notice on smush pages, it breaks them all **/
1509
+ .wpmud #edge-mode {
1510
+ display: none;
1511
+ }
1512
+
1513
+ .smush-page-wrap {
1514
+ margin: 10px 20px 0 2px;
1515
+ }
1516
+
1517
+ /** Circle Style **/
1518
+ .wp-smush-stats-graph {
1519
+ display: inline-block;
1520
+ }
1521
+
1522
+ .wp-smush-progress-circle {
1523
+ border-radius: 100%;
1524
+ display: block;
1525
+ height: 50px;
1526
+ position: relative;
1527
+ width: 50px;
1528
+ }
1529
+
1530
+ .wp-smush-progress-circle .wp-smush-svg-circle {
1531
+ stroke: #E5E5E5;
1532
+ stroke-dashoffset: 80;
1533
+ stroke-width: 5px;
1534
+ -ms-transition: stroke-dashoffset 1s linear;
1535
+ -moz-transition: stroke-dashoffset 1s linear;
1536
+ -webkit-transition: stroke-dashoffset 1s linear;
1537
+ transition: stroke-dashoffset 1s linear;
1538
+ }
1539
+
1540
+ .wp-smush-progress-circle .wp-smush-svg-circle-progress {
1541
+ transform: rotate(-80deg) translateX(-45px) translateY(4px);
1542
+ -moz-transform: rotate(-80deg) translateX(-45px) translateY(4px);
1543
+ -webkit-transform: rotate(-80deg) translateX(-45px) translateY(4px);
1544
+ }
1545
+
1546
+ .wp-smush-optimisation-progress {
1547
+ color: #28B576;
1548
+ cursor: pointer;
1549
+ position: relative;
1550
+ }
1551
+
1552
+ .wp-smush-optimisation-progress .wp-smush-progress-circle .wp-smush-svg-circle-progress {
1553
+ stroke: #28B576;
1554
+ }
1555
+
1556
+ .wpmud #wp-smush-share-widget {
1557
+ background-image: url(../images/share-bg-small.png);
1558
+ background-repeat: no-repeat;
1559
+ background-position: 30px 24px;
1560
+ min-height: 144px;
1561
+ padding: 21px;
1562
+ }
1563
+
1564
+ #wp-smush-share-widget .box-content {
1565
+ color: #767676;
1566
+ font-size: 15px;
1567
+ font-weight: 400;
1568
+ letter-spacing: -0.015em;
1569
+ line-height: 1.5;
1570
+ margin-left: 158px;
1571
+ }
1572
+
1573
+ #wp-smush-twitter-share {
1574
+ background: #1da1f2;
1575
+ }
1576
+
1577
+ #wp-smush-twitter-share:hover:not(:focus):not(:active):not(.wph-button):not(#collapse-button):not([tooltip]) {
1578
+ background-color: #0A9BD6;
1579
+ }
1580
+
1581
+ #wp-smush-facebook-share {
1582
+ background: #3b5998;
1583
+ }
1584
+
1585
+ #wp-smush-facebook-share:hover:not(:focus):not(:active):not(.wph-button):not(#collapse-button):not([tooltip]) {
1586
+ background-color: #2b4886;
1587
+ }
1588
+
1589
+ #wp-smush-whatsapp-share {
1590
+ background-color: #00ba00;
1591
+ background-image: url(../images/whatsapp-button-16px.png);
1592
+ background-repeat: no-repeat;
1593
+ background-position: 20px 12px;
1594
+ display: none;
1595
+ padding-left: 47px;
1596
+ }
1597
+
1598
+ .wp-smush-share-buttons-wrapper {
1599
+ margin-top: 20px;
1600
+ overflow: hidden;
1601
+ }
1602
+
1603
+ .wpmud .button.wp-smush-share-button {
1604
+ font-weight: 400;
1605
+ }
1606
+
1607
+ .wp-smush-share-button .dev-icon {
1608
+ margin-right: 12px;
1609
+ }
1610
+
1611
+ .wpmud .wp-smush-share-message {
1612
+ font-weight: 500;
1613
+ }
1614
+
1615
+ /** Override WP Footer Styling, Hide it on WPMU pages only, if we really need to **/
1616
+ .wp-admin #wpfooter {
1617
+ display: block;
1618
+ }
1619
+
1620
+ .wpmud #wpfooter {
1621
+ display: none;
1622
+ }
1623
+
1624
+ /** Directory Browser **/
1625
+ div.wp-smush-dir-desc {
1626
+ font-size: 15px;
1627
+ font-weight: 500;
1628
+ line-height: 30px;
1629
+ padding: 10px 0 25px;
1630
+ }
1631
+
1632
+ .wp-smush-dir-browser {
1633
+ overflow: hidden;
1634
+ }
1635
+
1636
+ .wpmud .wp-smush-dir-browser input.wp-smush-dir-path {
1637
+ width: 450px;
1638
+ }
1639
+
1640
+ .wpmud .wp-smush-dir-browser input.wp-smush-dir-path,
1641
+ .wpmud .wp-smush-dir-browser button,
1642
+ .wpmud .wp-smush-dir-browser label {
1643
+ display: inline-block;
1644
+ }
1645
+
1646
+ .wp-smush-loading-wrap {
1647
+ float: left;
1648
+ margin: 0 auto;
1649
+ overflow: hidden;
1650
+ width: 150px;
1651
+ }
1652
+
1653
+ .wpmud .dev-overlay.wp-smush-list-dialog .title h3 {
1654
+ padding: 20px 0;
1655
+ }
1656
+
1657
+ .wp-smush-list-dialog .box-scroll {
1658
+ margin-top: 80px;
1659
+ }
1660
+
1661
+ .wpmud .dev-overlay.wp-smush-list-dialog .box {
1662
+ margin-left: -300px;
1663
+ padding: 35px 35px 30px;
1664
+ width: 600px;
1665
+ }
1666
+
1667
+ .wp-smush-select-dir {
1668
+ float: right;
1669
+ margin-top: 20px;
1670
+ width: 154px;
1671
+ }
1672
+
1673
+ .wp-smush-list-dialog .spinner {
1674
+ float: left;
1675
+ }
1676
+
1677
+ .wpmud .dev-overlay.wp-smush-list-dialog .box .title {
1678
+ margin-bottom: 20px;
1679
+ }
1680
+
1681
+ .dev-overlay.wp-smush-list-dialog .wp-smush-instruct {
1682
+ color: #888888;
1683
+ font-size: 14px;
1684
+ font-weight: 500;
1685
+ padding-bottom: 20px;
1686
+ padding-top: 8px;
1687
+ }
1688
+
1689
+ .wpmud UL.jqueryFileTree a, .wpmud UL.jqueryFileTree a:hover {
1690
+ background: #f8f8f8;
1691
+ color: #888888;
1692
+ font-family: "Roboto", sans-serif;
1693
+ font-size: 14px;
1694
+ font-weight: 500;
1695
+ }
1696
+
1697
+ .jqueryFileTree .wp-smush-list {
1698
+ margin-top: 2px;
1699
+ vertical-align: top;
1700
+ }
1701
+
1702
+ .jqueryFileTree li {
1703
+ display: inline-block;
1704
+ }
1705
+
1706
+ .wpmud UL.jqueryFileTree LI {
1707
+ padding: 0 0 5px 20px;
1708
+ }
1709
+
1710
+ .wpmud UL.jqueryFileTree LI.ext_tif,
1711
+ .wpmud UL.jqueryFileTree LI.ext_tiff,
1712
+ .wpmud UL.jqueryFileTree LI.ext_png,
1713
+ .wpmud UL.jqueryFileTree LI.ext_pcx,
1714
+ .wpmud UL.jqueryFileTree LI.ext_jpeg,
1715
+ .wpmud UL.jqueryFileTree LI.ext_jpg,
1716
+ .wpmud UL.jqueryFileTree LI.ext_gif,
1717
+ .wpmud UL.jqueryFileTree LI.ext_bmp {
1718
+ background: url(../images/image.svg) left top no-repeat
1719
+ }
1720
+
1721
+ .wpmud UL.jqueryFileTree LI.directory {
1722
+ background: url(../images/folder-closed.svg) left top no-repeat;
1723
+ }
1724
+
1725
+ .wpmud UL.jqueryFileTree LI.expanded {
1726
+ background: url(../images/folder-open.svg) left top no-repeat;
1727
+ }
1728
+
1729
+ .wpmud UL.jqueryFileTree LI.expanded.selected {
1730
+ background: url(../images/folder-open-selected.svg) left top no-repeat;
1731
+ }
1732
+
1733
+ .wpmud UL.jqueryFileTree LI.expanded.selected > a {
1734
+ color: #17a8e3;
1735
+ }
1736
+
1737
+ .wpmud UL.jqueryFileTree LI.expanded.selected #Folder-22px-Solid-3-Open {
1738
+ fill: #17a8e3;
1739
+ }
1740
+
1741
+ .wpmud UL.jqueryFileTree LI.selected > a {
1742
+ font-weight: 500;
1743
+ }
1744
+
1745
+ li.directory.selected.expanded ul.jqueryFileTree {
1746
+ margin-top: 10px;
1747
+ }
1748
+
1749
+ /** Image List **/
1750
+ .wpmud .wp-smush-div-heading {
1751
+ display: inline-block;
1752
+ overflow: hidden;
1753
+ }
1754
+
1755
+ /** Smush Button Wrapper **/
1756
+ .wp-smush-all-button-wrap {
1757
+ display: inline-block;
1758
+ float: right;
1759
+ overflow: hidden;
1760
+ }
1761
+
1762
+ .wp-smush-all-button-wrap.top {
1763
+ display: inline-block;
1764
+ margin-bottom: 20px;
1765
+ }
1766
+
1767
+ div.wp-smush-all-button-wrap.bottom {
1768
+ margin-top: 14px;
1769
+ }
1770
+
1771
+ .wp-smush-all-button-wrap .spinner {
1772
+ margin-top: 12px;
1773
+ }
1774
+
1775
+ .wp-smush-start {
1776
+ float: right;
1777
+ vertical-align: top;
1778
+ }
1779
+
1780
+ .wpmud button.wp-smush-pause {
1781
+ cursor: pointer;
1782
+ float: right;
1783
+ }
1784
+
1785
+ .wpmud button.wp-smush-start:disabled:not(.finished),
1786
+ .wpmud button.wp-smush-pause.disabled {
1787
+ display: none !important;
1788
+ }
1789
+
1790
+ .wpmud button.wp-smush-start.finished {
1791
+ background: #1abc9c !important;
1792
+ opacity: 1;
1793
+ }
1794
+
1795
+ .wp-smush-image-list {
1796
+ line-height: 1.5;
1797
+ }
1798
+
1799
+ .wp-smush-image-ul {
1800
+ margin: 5px 0;
1801
+ }
1802
+
1803
+ .wp-smush-image-list-inner {
1804
+ display: none;
1805
+ max-height: 0;
1806
+ opacity: 0;
1807
+ overflow-y: scroll;
1808
+ padding: 15px 20px 0;
1809
+ transition: 0.6s ease-in-out;
1810
+ }
1811
+
1812
+ .wp-smush-image-list-inner.show {
1813
+ display: block;
1814
+ opacity: 1;
1815
+ max-height: 500px;
1816
+ }
1817
+
1818
+ span.wp-smush-li-path {
1819
+ cursor: pointer;
1820
+ font-weight: 500;
1821
+ position: relative;
1822
+ }
1823
+
1824
+ li.wp-smush-image-ul span.wp-smush-li-path {
1825
+ background: url("../images/folder-closed.svg") no-repeat;
1826
+ background-position-y: 3px;
1827
+ line-height: 1.5;
1828
+ padding: 4px 30px 3px;
1829
+
1830
+ }
1831
+
1832
+ li.wp-smush-image-ul.in-progress span.wp-smush-li-path {
1833
+ background: none;
1834
+ padding: 0;
1835
+ }
1836
+
1837
+ li.wp-smush-image-ul.complete span.wp-smush-li-path,
1838
+ li.wp-smush-image-ul.partial span.wp-smush-li-path {
1839
+ background: none;
1840
+ }
1841
+
1842
+ /** Show loader **/
1843
+ li.wp-smush-image-ul.in-progress span.spinner,
1844
+ li.wp-smush-image-ul li.wp-smush-image-ele.in-progress span.spinner {
1845
+ float: left;
1846
+ margin-top: 0px;
1847
+ margin-left: 0;
1848
+ display: inline-block;
1849
+ margin-right: 11px;
1850
+ }
1851
+
1852
+ li.wp-smush-image-ul.complete span.wp-smush-li-path:before,
1853
+ li.wp-smush-image-ul.partial span.wp-smush-li-path:before {
1854
+ box-shadow: none;
1855
+ color: #1ABC9C;
1856
+ content: '\67';
1857
+ font-family: 'WPMU-DEV-App-Icons';
1858
+ font-size: 20px;
1859
+ font-style: normal;
1860
+ font-variant: normal;
1861
+ font-weight: normal;
1862
+ height: 22px;
1863
+ left: 0;
1864
+ line-height: 22px;
1865
+ margin-top: -8px;
1866
+ opacity: 1;
1867
+ position: absolute;
1868
+ speak: none;
1869
+ transition-duration: 0.2s;
1870
+ transition-property: color, opacity;
1871
+ text-transform: none;
1872
+ top: 50%;
1873
+ vertical-align: middle;
1874
+ width: 22px;
1875
+ -webkit-font-smoothing: antialiased;
1876
+ -moz-osx-font-smoothing: grayscale;
1877
+ }
1878
+
1879
+ li.wp-smush-image-ul.partial span.wp-smush-li-path:before {
1880
+ color: #ffd000;
1881
+ content: '\f06a';
1882
+ font-family: 'FontAwesomeWdv';
1883
+ font-size: 22px;
1884
+ margin-left: 1px;
1885
+ }
1886
+
1887
+ .wp-smush-image-count {
1888
+ background: #f2f2f2;
1889
+ border-radius: 20px;
1890
+ margin-left: 10px;
1891
+ padding: 5px 10px;
1892
+ vertical-align: middle;
1893
+ }
1894
+
1895
+ div.wp-smush-dir-stats-wrap, div.wp-smush-scan-result {
1896
+ background: white;
1897
+ }
1898
+
1899
+ div.wp-smush-scan-result div.wp-smush-notice {
1900
+ margin-top: 14px;
1901
+ padding: 15px 30px;
1902
+
1903
+ }
1904
+
1905
+ div.wp-smush-scan-result div.wp-smush-notice .wdv-icon,
1906
+ div.wp-smush-scan-result div.wp-smush-notice .dev-icon,
1907
+ div.smush-s3-setup-error i.dev-icon {
1908
+ display: inline-block;
1909
+ font-size: 22px;
1910
+ margin-right: 5px;
1911
+ margin-top: -3px;
1912
+ vertical-align: middle;
1913
+ }
1914
+
1915
+ div.wp-smush-scan-result hr.primary-separator {
1916
+ margin: 10px 0 28px;
1917
+ }
1918
+
1919
+ div.wp-smush-scan-result hr {
1920
+ margin: 20px 0;
1921
+ }
1922
+
1923
+ div.wp-smush-scan-result div.content {
1924
+ overflow: hidden;
1925
+ width: 100%;
1926
+ }
1927
+
1928
+ .wpmud a.wp-smush-exclude-dir {
1929
+ color: #878787;
1930
+ cursor: pointer;
1931
+ display: inline-block;
1932
+ float: right;
1933
+ font-size: 15px;
1934
+ font-weight: 700;
1935
+ margin-right: 16px;
1936
+ padding: 0 10px;
1937
+ }
1938
+
1939
+ .wpmud a.wp-smush-exclude-dir:hover {
1940
+ color: #878787;
1941
+ }
1942
+
1943
+ div.dir-smush-button-wrap {
1944
+ margin-top: 14px;
1945
+ overflow: hidden;
1946
+ }
1947
+
1948
+ div.dir-smush-button-wrap.top {
1949
+ height: 40px;
1950
+ margin-top: 0;
1951
+ margin-bottom: 30px;
1952
+ }
1953
+
1954
+ div.dir-smush-button-wrap button, div.dir-smush-button-wrap span {
1955
+ float: left;
1956
+ }
1957
+
1958
+ div.dir-smush-button-wrap span {
1959
+ margin-top: 10px;
1960
+ }
1961
+
1962
+ .wpmud button.wp-smush-browse {
1963
+ background-color: #AEAEAE !important;
1964
+ }
1965
+
1966
+ .wpmud button.wp-smush-browse:hover {
1967
+ background-color: #9E9E9E !important;
1968
+ }
1969
+
1970
+ .wp-smush-loading-text {
1971
+ font-size: 20px;
1972
+ line-height: 1.3;
1973
+ visibility: visible;
1974
+ }
1975
+
1976
+ .wp-smush-select-button-wrap {
1977
+ padding: 20px;
1978
+ background: #f9f9f9;
1979
+ border-radius: 5px;
1980
+ margin-top: 25px;
1981
+ overflow: hidden;
1982
+ }
1983
+
1984
+ .wp-smush-select-button-wrap .wp-smush-section-desc {
1985
+ color: #888;
1986
+ display: inline-block;
1987
+ float: left;
1988
+ line-height: 22px;
1989
+ max-width: 59%;
1990
+ }
1991
+
1992
+ .wp-smush-select-button-wrap .spinner {
1993
+ margin-top: 12px;
1994
+ }
1995
+
1996
+ .wp-smush-image-ele {
1997
+ margin: 15px 0;
1998
+ }
1999
+
2000
+ li.wp-smush-image-ele span.wp-smush-image-path {
2001
+ padding: 4px 0 3px;
2002
+ }
2003
+
2004
+ .wp-smush-image-ele:last-child {
2005
+ margin: 15px 0 0;
2006
+ }
2007
+
2008
+ .wp-smush-image-ele .spinner {
2009
+ float: left;
2010
+ margin-left: 0;
2011
+ margin-top: 1px;
2012
+ }
2013
+
2014
+ .wp-smush-image-ul .wp-smush-image-ele .spinner {
2015
+ margin-left: 18px;
2016
+ position: relative;
2017
+ }
2018
+
2019
+ .wp-smush-image-ele-status {
2020
+ color: #C6C6C6;
2021
+ display: inline-block;
2022
+ height: 22px;
2023
+ line-height: 1;
2024
+ margin-right: 10px;
2025
+ overflow: hidden;
2026
+ position: relative;
2027
+ width: 22px;
2028
+ vertical-align: middle;
2029
+ }
2030
+
2031
+ .wp-smush-image-ele-status:after {
2032
+ box-shadow: none;
2033
+ content: url("../images/image.svg");
2034
+ font-family: 'WPMU-DEV-App-Icons';
2035
+ font-size: 20px;
2036
+ font-style: normal;
2037
+ font-variant: normal;
2038
+ font-weight: normal;
2039
+ height: 22px;
2040
+ line-height: 22px;
2041
+ margin-top: -12px;
2042
+ opacity: 1;
2043
+ position: absolute;
2044
+ speak: none;
2045
+ transition-duration: 0.2s;
2046
+ transition-property: color, opacity;
2047
+ text-transform: none;
2048
+ top: 50%;
2049
+ vertical-align: middle;
2050
+ width: 22px;
2051
+ -webkit-font-smoothing: antialiased;
2052
+ -moz-osx-font-smoothing: grayscale;
2053
+ }
2054
+
2055
+ li.wp-smush-image-ele.in-progress .wp-smush-image-ele-status {
2056
+ display: none;
2057
+ }
2058
+
2059
+ /** Optimised Image **/
2060
+ li.wp-smush-image-ele.optimised .wp-smush-image-ele-status:after {
2061
+ content: '\67';
2062
+ color: #1ABC9C;
2063
+ }
2064
+
2065
+ li.wp-smush-image-ele.error .wp-smush-image-ele-status:after {
2066
+ color: #ffd000;
2067
+ content: '\f06a';
2068
+ font-family: 'FontAwesomeWdv';
2069
+ }
2070
+
2071
+ div.wp-smush-dir-notice {
2072
+ padding: 15px 20px;
2073
+ background: #fff5d5;
2074
+ border-radius: 5px;
2075
+ margin-top: 20px;
2076
+ font-size: 14px;
2077
+ font-weight: 500;
2078
+ }
2079
+
2080
+ div.wp-smush-dir-notice .wdv-icon-exclamation-sign {
2081
+ margin-right: 10px;
2082
+ vertical-align: middle;
2083
+ }
2084
+
2085
+ div.wp-smush-dir-notice .wdv-icon-exclamation-sign:before {
2086
+ color: #ffd000;
2087
+ content: '\f06a';
2088
+ font-family: 'FontAwesomeWdv';
2089
+ font-size: 22px;
2090
+ margin-left: 1px;
2091
+ margin-top: 4px;
2092
+ vertical-align: middle;
2093
+ }
2094
+
2095
+ div.wp-smush-dir-progress-wrap {
2096
+ display: inline-block;
2097
+ float: right;
2098
+ font-weight: 600;
2099
+ padding-top: 4px;
2100
+ width: 145px;
2101
+ }
2102
+
2103
+ div.wp-smush-dir-progress-wrap.hidden {
2104
+ display: none;
2105
+ }
2106
+
2107
+ span.smush-percent {
2108
+ display: inline-block;
2109
+ text-align: right;
2110
+ width: 34px;
2111
+ }
2112
+
2113
+ div.wp-smush-dir-progress-wrap-inner {
2114
+ background: #e6e6e6;
2115
+ -moz-border-radius: 10px;
2116
+ -webkit-border-radius: 10px;
2117
+ border-radius: 10px;
2118
+ display: inline-block;
2119
+ height: 10px;
2120
+ margin-left: 10px;
2121
+ position: relative;
2122
+ width: 100px;
2123
+ }
2124
+
2125
+ .wp-smush-dir-progress {
2126
+ background: #ffd000;
2127
+ -webkit-border-radius: 20px;
2128
+ -moz-border-radius: 20px;
2129
+ border-radius: 20px;
2130
+ display: block;
2131
+ height: 100%;
2132
+ position: relative;
2133
+ overflow: hidden;
2134
+ transition: 0.4s linear;
2135
+ transition-property: width, background-color;
2136
+ }
2137
+
2138
+ .wp-smush-dir-progress.complete {
2139
+ background: #1abc9c;
2140
+ }
2141
+
2142
+ .wp-smush-dir-progress.complete ~ a.wp-smush-exclude-dir {
2143
+ display: none;
2144
+ }
2145
+
2146
+ div.wp-smush-info.notice {
2147
+ font-size: 15px;
2148
+ letter-spacing: -0.015em;
2149
+ margin: 0 0 30px;
2150
+ padding: 15px;
2151
+ }
2152
+
2153
+ .wpmud div.smush-page-wrap button:not(.wph-button):not(#collapse-button),
2154
+ .wpmud div.smush-page-wrap .button {
2155
+ background-color: #17A8E3;
2156
+ }
2157
+
2158
+ .wpmud div.smush-page-wrap button:hover:not(:focus):not(:active):not(.wph-button):not(#collapse-button):not([tooltip]),
2159
+ .wpmud .div.smush-page-wrap button:hover:not(:focus):not(:active):not(.wph-button):not(#collapse-button):not([tooltip]),
2160
+ .wpmud .smush-page-wrap .wp-smush-submit-wrap .button.button-grey:hover:not(:focus):not(:active):not(.wph-button):not(#collapse-button):not([tooltip]) {
2161
+ background: #0A9BD6;
2162
+ }
2163
+
2164
+ .wpmud .smush-page-wrap .button.button-grey {
2165
+ background: #AEAEAE;
2166
+ }
2167
+
2168
+ /** Media Queries **/
2169
+ @media screen and (max-width: 1110px) {
2170
+ .wpmud .row .col-half.wp-smushit-container-left,
2171
+ .wpmud .row .col-half.wp-smushit-container-right {
2172
+ padding-left: 0;
2173
+ padding-right: 0;
2174
+ width: 100%;
2175
+ }
2176
+ }
2177
+
2178
+ @media screen and (max-width: 1100px) {
2179
+ li.wp-smush-image-ul span.wp-smush-li-path {
2180
+ max-width: 75%;
2181
+ display: inline-block;
2182
+ padding-right: 0;
2183
+ }
2184
+
2185
+ span.wp-smush-image-count {
2186
+ display: inline-block;
2187
+ margin-left: 0;
2188
+ overflow: hidden;
2189
+ text-align: center;
2190
+ }
2191
+
2192
+ li.wp-smush-image-ul.complete span.wp-smush-li-path:before,
2193
+ li.wp-smush-image-ul.partial span.wp-smush-li-path:before {
2194
+ margin-top: 0;
2195
+ top: 4px;
2196
+ }
2197
+
2198
+ li.wp-smush-image-ul.partial span.wp-smush-li-path:before {
2199
+ margin-top: 2px;
2200
+ }
2201
+ }
2202
+
2203
+ @media screen and (max-width: 1024px) and ( min-width: 800px ) {
2204
+ .wpmud .wrap .dev-box:not(.wp-smush-pro-adv) {
2205
+ padding: 20px;
2206
+ }
2207
+
2208
+ .wpmud .dev-box.wp-smush-pro-adv .box-title, .wpmud .wp-smush-pro-adv .box-content {
2209
+ padding: 0 20px;
2210
+ }
2211
+
2212
+ /** Stats Section **/
2213
+ .wpmud .smush-stats-wrapper {
2214
+ font-size: 12px;
2215
+ }
2216
+
2217
+ .smush-stats-wrapper h3 {
2218
+ padding: 6px 0;
2219
+ }
2220
+
2221
+ .smush-stats-wrapper .smush-container-subheading {
2222
+ margin-top: 20px;
2223
+ }
2224
+
2225
+ .wpmud .wp-smush-stats, .wp-smush-stats-wrap {
2226
+ font-size: 20px;
2227
+ }
2228
+
2229
+ /** Sub Heading **/
2230
+ .wpmud .smush-container-subheading {
2231
+ font-size: 12px;
2232
+ }
2233
+ }
2234
+
2235
+ /** Media Queries for resolution between 782px - 1024px **/
2236
+ @media screen and (max-width: 1024px) {
2237
+ /** Configure screen **/
2238
+ .wpmud .row .wp-smush-lady.col-third {
2239
+ display: none;
2240
+ }
2241
+
2242
+ /** Media Library Stats **/
2243
+ .wp-list-table .smushit .wp-smush-stats-holder tr th {
2244
+ display: inline-block;
2245
+ width: 50%;
2246
+ box-sizing: border-box;
2247
+ }
2248
+
2249
+ .wp-list-table .smushit .wp-smush-stats-holder tr td:first-child {
2250
+ border-right: none;
2251
+ box-sizing: border-box;
2252
+ display: inline-block !important;
2253
+ width: 50% !important;
2254
+ }
2255
+
2256
+ .wp-list-table .smushit .wp-smush-stats-holder tr td:last-child {
2257
+ box-sizing: border-box;
2258
+ display: inline-block !important;
2259
+ float: none;
2260
+ overflow: visible;
2261
+ width: 50% !important;
2262
+ }
2263
+
2264
+ .wpmud .wp-smush-promo-content, .wpmud .wp-smush-promo-content-smaller {
2265
+ max-width: none;
2266
+ }
2267
+ }
2268
+
2269
+ @media only screen and (min-width: 1100px) and ( max-width: 1200px ) {
2270
+ .wp-smush-super-smush-promo .wp-smush-super-smush-content {
2271
+ margin-left: 170px;
2272
+ padding: 10px 20px;
2273
+ }
2274
+ }
2275
+
2276
+ @media only screen and (max-width: 960px) {
2277
+ .wpmud .dev-overlay.wp-smush-list-dialog {
2278
+ left: 35px;
2279
+ }
2280
+ }
2281
+
2282
+ /** Media Queries for resolution below 782px **/
2283
+ @media only screen and (max-width: 800px) {
2284
+ .wpmud .wp-smushit-container-wrap .col-half.wp-smushit-container-left, .wpmud .wp-smushit-container-wrap .col-half.wp-smushit-container-right {
2285
+ padding: 0;
2286
+ width: 100%;
2287
+ }
2288
+
2289
+ .wpmud .wp-smush-welcome-content {
2290
+ margin: 0 30px 0px 160px;
2291
+ }
2292
+
2293
+ .dev-box.bulk-smush-wrapper.wp-smush-container {
2294
+ padding: 20px 10px;
2295
+ }
2296
+
2297
+ .wpmud .wp-smush-super-smush-content {
2298
+ margin-left: 160px;
2299
+ }
2300
+ }
2301
+
2302
+ @media only screen and (max-width: 782px) {
2303
+ .wpmud .dev-overlay.wp-smush-list-dialog {
2304
+ left: 0;
2305
+ }
2306
+ }
2307
+
2308
+ @media screen and (max-width: 750px) {
2309
+ .wpmud .dev-box#wp-smush-share-widget {
2310
+ background-position: 30px 45px;
2311
+ }
2312
+ }
2313
+
2314
+ /** For directory smush image listing **/
2315
+ @media screen and (max-width: 672px) {
2316
+ li.wp-smush-image-ul span.wp-smush-li-path {
2317
+ max-width: 65%;
2318
+ }
2319
+ }
2320
+
2321
+ @media screen and (max-width: 650px) {
2322
+ .wpmud .dev-box#wp-smush-share-widget {
2323
+ background-image: none;
2324
+ }
2325
+
2326
+ .wpmud #wp-smush-share-widget .box-content {
2327
+ margin-left: 0;
2328
+ padding: 20px;
2329
+ }
2330
+
2331
+ .wpmud .button.wp-smush-share-button,
2332
+ .wpmud a + .button.wp-smush-share-button {
2333
+ margin-bottom: 10px;
2334
+ margin-left: 0;
2335
+ text-align: center;
2336
+ width: 100%;
2337
+ }
2338
+
2339
+ .wpmud .button.wp-smush-share-button .dev-icon {
2340
+ float: left;
2341
+ }
2342
+
2343
+ .wpmud #wp-smush-whatsapp-share {
2344
+ display: inline-block;
2345
+ }
2346
+ }
2347
+
2348
+ @media screen and (max-width: 600px) {
2349
+ .wpmud .wp-smush-welcome.wp-smush-container {
2350
+ background-position: 43% bottom;
2351
+ padding-bottom: 148px;
2352
+ }
2353
+
2354
+ .wpmud .wp-smush-welcome-content {
2355
+ margin: 0 30px 0px 0;
2356
+ max-width: 100%;
2357
+ }
2358
+
2359
+ .wpmud .dev-overlay.wp-smush-list-dialog {
2360
+ top: 0;
2361
+ }
2362
+
2363
+ .wpmud .dev-overlay.wp-smush-list-dialog .box {
2364
+ margin-left: -40%;
2365
+ width: 80%;
2366
+ }
2367
+
2368
+ .wp-smush-select-button-wrap .wp-smush-section-desc {
2369
+ width: 100%;
2370
+ max-width: none;
2371
+ }
2372
+
2373
+ div.wp-smush-select-button-wrap-child {
2374
+ overflow: hidden;
2375
+ float: left;
2376
+ margin-top: 14px;
2377
+ }
2378
+
2379
+ div.wp-smush-select-button-wrap-child span.spinner {
2380
+ float: right;
2381
+ }
2382
  }
assets/images/ajax-loader.gif CHANGED
Binary file
assets/images/application.png ADDED
Binary file
assets/images/bulk-smush.png DELETED
Binary file
assets/images/code.png ADDED
Binary file
assets/images/css.png ADDED
Binary file
assets/images/db.png ADDED
Binary file
assets/images/dev-team.png CHANGED
Binary file
assets/images/directory-lock.png ADDED
Binary file
assets/images/directory.png ADDED
Binary file
assets/images/doc.png ADDED
Binary file
assets/images/file-lock.png ADDED
Binary file
assets/images/file.png ADDED
Binary file
assets/images/film.png ADDED
Binary file
assets/images/flash.png ADDED
Binary file
assets/images/folder-closed.svg ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="18px" height="15px" viewBox="0 0 18 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
4
+ <title>folder-closed</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Folder-22px-Solid-3-Closed" fill="#888888">
9
+ <path d="M0,1 C0,0.44771525 0.45303631,0 0.99703014,0 L7.00296986,0 C7.5536144,0 8,0.44386482 8,1 L8,2 L0,2 L0,1 Z M0,3 L18,3 L18,15 L0,15 L0,3 Z" id="folder-closed"></path>
10
+ </g>
11
+ </g>
12
+ </svg>
assets/images/folder-open-selected.svg ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="18px" height="15px" viewBox="0 0 18 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
4
+ <title>folder-open</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Folder-22px-Solid-3-Open" fill="#17a8e3">
9
+ <path d="M2.00010759,5 L17.9871925,5 L16.1942557,14.0229504 C16.0870306,14.56256 15.5496251,15 14.9982973,15 L0.791347791,15 C0.238063241,15 -0.104466299,14.5709592 0.0287507007,14.0317368 L0.246548481,13.1501568 L2.00010759,5 Z M0.000107590658,0.99396592 C0.000107590658,0.4450137 0.453143901,0 0.997137731,0 L7.00307745,0 C7.55372199,0 8.00010759,0.44386482 8.00010759,1 L8.00010759,2 L16.5001076,2 L16.5001076,4 L1.50010759,4 L0.000107590658,10.5 L0.000107590658,2.44374814 L0.000107590658,0.99396592 Z" id="folder-open"></path>
10
+ </g>
11
+ </g>
12
+ </svg>
assets/images/folder-open.svg ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="18px" height="15px" viewBox="0 0 18 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
4
+ <title>folder-open</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Folder-22px-Solid-3-Open" fill="#888888">
9
+ <path d="M2.00010759,5 L17.9871925,5 L16.1942557,14.0229504 C16.0870306,14.56256 15.5496251,15 14.9982973,15 L0.791347791,15 C0.238063241,15 -0.104466299,14.5709592 0.0287507007,14.0317368 L0.246548481,13.1501568 L2.00010759,5 Z M0.000107590658,0.99396592 C0.000107590658,0.4450137 0.453143901,0 0.997137731,0 L7.00307745,0 C7.55372199,0 8.00010759,0.44386482 8.00010759,1 L8.00010759,2 L16.5001076,2 L16.5001076,4 L1.50010759,4 L0.000107590658,10.5 L0.000107590658,2.44374814 L0.000107590658,0.99396592 Z" id="folder-open"></path>
10
+ </g>
11
+ </g>
12
+ </svg>
assets/images/folder_open.png ADDED
Binary file
assets/images/html.png ADDED
Binary file
assets/images/hummingbird.png CHANGED
Binary file
assets/images/image.svg ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="18px" height="14px" viewBox="0 0 18 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
4
+ <title>image</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Image-22px-Solid" fill="#888888">
9
+ <path d="M9.25,12 L15.5176792,12 C15.7911357,12 16,11.7782068 16,11.504611 L16,9 L11,4 L6.97222222,9.23611111 L4.5,8 L2,10.5 L2,11.4921684 C2,11.7786698 2.22673949,12 2.50643682,12 L9.25,12 Z M0,2.00585866 C0,0.898053512 0.892622799,0 1.99508929,0 L16.0049107,0 C17.1067681,0 18,0.897060126 18,2.00585866 L18,11.9941413 C18,13.1019465 17.1073772,14 16.0049107,14 L1.99508929,14 C0.893231902,14 0,13.1029399 0,11.9941413 L0,2.00585866 Z M4.5,7 C5.88071187,7 7,5.88071187 7,4.5 C7,3.11928813 5.88071187,2 4.5,2 C3.11928813,2 2,3.11928813 2,4.5 C2,5.88071187 3.11928813,7 4.5,7 Z" id="image"></path>
10
+ </g>
11
+ </g>
12
+ </svg>
assets/images/install-welcome.png DELETED
Binary file
assets/images/java.png ADDED
Binary file
assets/images/linux.png ADDED
Binary file
assets/images/music.png ADDED
Binary file
assets/images/pdf.png ADDED
Binary file
assets/images/php.png ADDED
Binary file
assets/images/picture.png ADDED
Binary file
assets/images/ppt.png ADDED
Binary file
assets/images/psd.png ADDED
Binary file
assets/images/ruby.png ADDED
Binary file
assets/images/script.png ADDED
Binary file
assets/images/share-bg-small.png ADDED
Binary file
assets/images/smush-no-media.png ADDED
Binary file
assets/images/smush-upload-images.png DELETED
Binary file
assets/images/spinner.gif ADDED
Binary file
assets/images/txt.png ADDED
Binary file
assets/images/welcome-notice.png CHANGED
Binary file
assets/images/whatsapp-button-14px.png ADDED
Binary file
assets/images/whatsapp-button-16px.png ADDED
Binary file
assets/images/xls.png ADDED
Binary file
assets/images/zip.png ADDED
Binary file
assets/js/bulk-smush.js ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ /**
2
+ * All the function related to Bulk Smushing page
3
+ *
4
+ * @author Umesh Kumar <umeshsingla05@gmail.com>
5
+ *
6
+ * @since 2.7.1
7
+ *
8
+ */
assets/js/jQueryFileTree.js ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ /*
3
+ * jQueryFileTree Plugin
4
+ *
5
+ * @author - Cory S.N. LaViska - A Beautiful Site (http://abeautifulsite.net/) - 24 March 2008
6
+ * @author - Dave Rogers - (https://github.com/daverogers/)
7
+ *
8
+ * Usage: $('.fileTreeDemo').fileTree({ options }, callback )
9
+ *
10
+ * TERMS OF USE
11
+ *
12
+ * This plugin is dual-licensed under the GNU General Public License and the MIT License and
13
+ * is copyright 2008 A Beautiful Site, LLC.
14
+ */
15
+ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
16
+
17
+ (function($, window) {
18
+ var FileTree;
19
+ FileTree = (function() {
20
+ function FileTree(el, args, callback) {
21
+ this.onEvent = bind(this.onEvent, this);
22
+ var $el, _this, defaults;
23
+ $el = $(el);
24
+ _this = this;
25
+ defaults = {
26
+ root: '/',
27
+ script: '/files/filetree',
28
+ folderEvent: 'click',
29
+ expandSpeed: 500,
30
+ collapseSpeed: 500,
31
+ expandEasing: 'swing',
32
+ collapseEasing: 'swing',
33
+ multiFolder: true,
34
+ loadMessage: 'Loading...',
35
+ errorMessage: 'Unable to get file tree information',
36
+ multiSelect: false,
37
+ onlyFolders: false,
38
+ onlyFiles: false,
39
+ preventLinkAction: false
40
+ };
41
+ this.jqft = {
42
+ container: $el
43
+ };
44
+ this.options = $.extend(defaults, args);
45
+ this.callback = callback;
46
+ this.data = {};
47
+ $el.html('<ul class="jqueryFileTree start"><li class="wait">' + this.options.loadMessage + '<li></ul>');
48
+ _this.showTree($el, escape(this.options.root), function() {
49
+ return _this._trigger('filetreeinitiated', {});
50
+ });
51
+ $el.delegate("li a", this.options.folderEvent, _this.onEvent);
52
+ }
53
+
54
+ FileTree.prototype.onEvent = function(event) {
55
+ var $ev, _this, callback, jqft, options, ref;
56
+ $ev = $(event.target);
57
+ options = this.options;
58
+ jqft = this.jqft;
59
+ _this = this;
60
+ callback = this.callback;
61
+ _this.data = {};
62
+ _this.data.li = $ev.closest('li');
63
+ _this.data.type = (ref = _this.data.li.hasClass('directory')) != null ? ref : {
64
+ 'directory': 'file'
65
+ };
66
+ _this.data.value = $ev.text();
67
+ _this.data.rel = $ev.prop('rel');
68
+ _this.data.container = jqft.container;
69
+ if (options.preventLinkAction) {
70
+ event.preventDefault();
71
+ }
72
+ if ($ev.parent().hasClass('directory')) {
73
+ //Add a selected class to directory, Thanks to shortpixel for the modification in here
74
+ _this.jqft.container.find('LI.directory').removeClass('selected');
75
+ $ev.parent().addClass('selected');
76
+
77
+ if ($ev.parent().hasClass('collapsed')) {
78
+ if (!options.multiFolder) {
79
+ $ev.parent().parent().find('UL').slideUp({
80
+ duration: options.collapseSpeed,
81
+ easing: options.collapseEasing
82
+ });
83
+ $ev.parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed');
84
+ }
85
+ $ev.parent().removeClass('collapsed').addClass('expanded');
86
+ $ev.parent().find('UL').remove();
87
+ return _this.showTree($ev.parent(), $ev.attr('rel'), function() {
88
+ _this._trigger('filetreeexpanded', _this.data);
89
+ return callback != null;
90
+ });
91
+ } else {
92
+ return $ev.parent().find('UL').slideUp({
93
+ duration: options.collapseSpeed,
94
+ easing: options.collapseEasing,
95
+ start: function() {
96
+ return _this._trigger('filetreecollapse', _this.data);
97
+ },
98
+ complete: function() {
99
+ $ev.parent().removeClass('expanded').addClass('collapsed');
100
+ _this._trigger('filetreecollapsed', _this.data);
101
+ return callback != null;
102
+ }
103
+ });
104
+ }
105
+ } else {
106
+ if (!options.multiSelect) {
107
+ jqft.container.find('li').removeClass('selected');
108
+ $ev.parent().addClass('selected');
109
+ } else {
110
+ if ($ev.parent().find('input').is(':checked')) {
111
+ $ev.parent().find('input').prop('checked', false);
112
+ $ev.parent().removeClass('selected');
113
+ } else {
114
+ $ev.parent().find('input').prop('checked', true);
115
+ $ev.parent().addClass('selected');
116
+ }
117
+ }
118
+ _this._trigger('filetreeclicked', _this.data);
119
+ return typeof callback === "function" ? callback($ev.attr('rel')) : void 0;
120
+ }
121
+ };
122
+
123
+ FileTree.prototype.showTree = function(el, dir, finishCallback) {
124
+ var $el, _this, data, handleFail, handleResult, options, result;
125
+ $el = $(el);
126
+ options = this.options;
127
+ _this = this;
128
+ $el.addClass('wait');
129
+ $(".jqueryFileTree.start").remove();
130
+ data = {
131
+ dir: dir,
132
+ onlyFolders: options.onlyFolders,
133
+ onlyFiles: options.onlyFiles,
134
+ multiSelect: options.multiSelect
135
+ };
136
+ handleResult = function(result) {
137
+ var li;
138
+ $el.find('.start').html('');
139
+ $el.removeClass('wait').append(result);
140
+ if (options.root === dir) {
141
+ $el.find('UL:hidden').show(typeof callback !== "undefined" && callback !== null);
142
+ } else {
143
+ if (jQuery.easing[options.expandEasing] === void 0) {
144
+ console.log('Easing library not loaded. Include jQueryUI or 3rd party lib.');
145
+ options.expandEasing = 'swing';
146
+ }
147
+ $el.find('UL:hidden').slideDown({
148
+ duration: options.expandSpeed,
149
+ easing: options.expandEasing,
150
+ start: function() {
151
+ return _this._trigger('filetreeexpand', _this.data);
152
+ },
153
+ complete: finishCallback
154
+ });
155
+ }
156
+ li = $('[rel="' + decodeURIComponent(dir) + '"]').parent();
157
+ if (options.multiSelect && li.children('input').is(':checked')) {
158
+ li.find('ul li input').each(function() {
159
+ $(this).prop('checked', true);
160
+ return $(this).parent().addClass('selected');
161
+ });
162
+ }
163
+ return false;
164
+ };
165
+ handleFail = function() {
166
+ $el.find('.start').html('');
167
+ $el.removeClass('wait').append("<p>" + options.errorMessage + "</p>");
168
+ return false;
169
+ };
170
+ if (typeof options.script === 'function') {
171
+ result = options.script(data);
172
+ if (typeof result === 'string' || result instanceof jQuery) {
173
+ return handleResult(result);
174
+ } else {
175
+ return handleFail();
176
+ }
177
+ } else {
178
+ return $.ajax({
179
+ url: options.script,
180
+ type: 'POST',
181
+ dataType: 'HTML',
182
+ data: data
183
+ }).done(function(result) {
184
+ return handleResult(result);
185
+ }).fail(function() {
186
+ return handleFail();
187
+ });
188
+ }
189
+ };
190
+
191
+ FileTree.prototype._trigger = function(eventType, data) {
192
+ var $el;
193
+ $el = this.jqft.container;
194
+ return $el.triggerHandler(eventType, data);
195
+ };
196
+
197
+ return FileTree;
198
+
199
+ })();
200
+ return $.fn.extend({
201
+ fileTree: function(args, callback) {
202
+ return this.each(function() {
203
+ var $this, data;
204
+ $this = $(this);
205
+ data = $this.data('fileTree');
206
+ if (!data) {
207
+ $this.data('fileTree', (data = new FileTree(this, args, callback)));
208
+ }
209
+ if (typeof args === 'string') {
210
+ return data[option].apply(data);
211
+ }
212
+ });
213
+ }
214
+ });
215
+ })(window.jQuery, window);
assets/js/notice.js ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Created by umeshkumar on 12/05/16.
3
+ */
4
+ jQuery(function () {
5
+ var el_notice = jQuery(".smush-notice"),
6
+ btn_act = el_notice.find(".smush-notice-act"),
7
+ btn_dismiss = el_notice.find(".smush-notice-dismiss");
8
+ el_notice.fadeIn(500);
9
+
10
+ // Hide the notice after a CTA button was clicked
11
+ function remove_notice() {
12
+ el_notice.fadeTo(100, 0, function () {
13
+ el_notice.slideUp(100, function () {
14
+ el_notice.remove();
15
+ });
16
+ });
17
+ }
18
+
19
+ btn_act.click(function (ev) {
20
+ remove_notice();
21
+ notify_wordpress(btn_act.data("msg"));
22
+ });
23
+ btn_dismiss.click(function (ev) {
24
+ remove_notice();
25
+ notify_wordpress(btn_act.data("msg"));
26
+ });
27
+
28
+ // Notify WordPress about the users choice and close the message.
29
+ function notify_wordpress(message) {
30
+ el_notice.attr("data-message", message);
31
+ el_notice.addClass("loading");
32
+
33
+ //Send a ajax request to save the dismissed notice option
34
+ var param = {
35
+ action: 'dismiss_upgrade_notice'
36
+ };
37
+ jQuery.post(ajaxurl, param);
38
+ }
39
+
40
+ //Store the preference in db
41
+ jQuery('.wp-smush-update-info').on('click', '.notice-dismiss', function (e) {
42
+ e.preventDefault();
43
+ var $el = jQuery(this);
44
+ $el.fadeTo( 100, 0, function() {
45
+ $el.slideUp( 100, function() {
46
+ $el.remove();
47
+ });
48
+ });
49
+ var param = {
50
+ action: 'dismiss_update_info'
51
+ };
52
+ jQuery.post(ajaxurl, param);
53
+ });
54
+
55
+ });
assets/js/wp-smushit-admin-media.js DELETED
@@ -1,84 +0,0 @@
1
- /**
2
- * Adds a smush button in grid view, Show the stats
3
- * @type {WP_Smush|*|{}}
4
- */
5
- var WP_Smush = WP_Smush || {};
6
- jQuery(function ($) {
7
- "use strict";
8
- if (!wp.media) return;
9
-
10
- var manualUrl = ajaxurl + '?action=wp_smushit_manual';
11
-
12
- var SmushButton = Backbone.View.extend({
13
- className: "media-lib-wp-smush-el",
14
- tagName: "div",
15
- events: {
16
- "click .media-lib-wp-smush-icon": "click"
17
- },
18
- template: _.template('<span class="dashicons dashicons-media-archive media-lib-wp-smush-icon"></span>'),
19
- initialize: function () {
20
- this.render();
21
- },
22
- is_smushed: function () {
23
- var self = this,
24
- arr = _.filter(wp_smushit_data.smushed, function (id) {
25
- return id == self.model.get("id").toString();
26
- });
27
- return typeof arr == "object" ? arr.length : false;
28
- },
29
- render: function () {
30
- var data = this.model.toJSON();
31
-
32
-
33
- this.$el.html(this.template());
34
- this.$button = this.$(".media-lib-wp-smush-icon");
35
-
36
- if (this.is_smushed()) {
37
- this.$el.addClass("is_smushed");
38
- } else {
39
- this.$el.addClass("active");
40
- this.$button.prop("title", wp_smush_msgs.smush_now)
41
- }
42
-
43
- this.$button.data("id", data.id);
44
- },
45
- click: function (e) {
46
- var ajax = WP_Smush.ajax(this.model.get("id"), manualUrl, 0),
47
- self = this;
48
-
49
- e.preventDefault();
50
- e.stopPropagation();
51
-
52
- this.$button.css({display: "block"});
53
- this.$button.prop("disabled", true);
54
- this.$button.addClass("active spinner");
55
- ajax.complete(function (res) {
56
- self.$button.prop("disabled", false);
57
- self.$button.removeClass("spinner");
58
- self.$button.removeClass("active");
59
- self.$el.removeClass("active");
60
- self.$el.addClass("is_smushed");
61
- });
62
- }
63
- });
64
-
65
-
66
- /**
67
- * Add smush it button to the image thumb
68
- */
69
- WP_Smush.Attachments = wp.media.view.Attachments.extend({
70
- createAttachmentView: function (attachment) {
71
-
72
- var view = wp.media.view.Attachments.__super__.createAttachmentView.apply(this, arguments);
73
-
74
- _.defer(function () {
75
- var smush_button = new SmushButton({model: view.model});
76
- view.$el.append(smush_button.el);
77
- view.$el.addClass("has-smush-button");
78
- });
79
-
80
- return view;
81
- }
82
- });
83
- //wp.media.view.Attachments = WP_Smush.Attachments;
84
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/wp-smushit-admin.js CHANGED
@@ -1,10 +1,11 @@
1
  /**
2
  * Processes bulk smushing
3
  *
4
- * @author Saurabh Shukla <saurabh@incsub.com>
5
  * @author Umesh Kumar <umeshsingla05@gmail.com>
6
  *
7
  */
 
 
8
  var WP_Smush = WP_Smush || {};
9
 
10
  /**
@@ -14,19 +15,72 @@ var WP_Smush = WP_Smush || {};
14
  * @param txt Message to be displayed
15
  * @param state show/hide
16
  */
17
- var progress_bar = function( cur_ele, txt, state ) {
18
 
19
  //Update Progress bar text and show it
20
  var progress_button = cur_ele.parents().eq(1).find('.wp-smush-progress');
21
 
22
- if( 'show' == state ) {
23
  progress_button.find('span').html(txt);
24
  progress_button.removeClass('hidden');
25
- }else{
26
- progress_button.find('span').html( wp_smush_msgs.all_done );
27
  progress_button.hide();
28
  }
29
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  jQuery(function ($) {
31
  var smushAddParams = function (url, data) {
32
  if (!$.isEmptyObject(data)) {
@@ -69,17 +123,24 @@ jQuery(function ($) {
69
  this.deferred = jQuery.Deferred();
70
  this.deferred.errors = [];
71
 
72
- //If button has resmush class, and we do have ids that needs to resmushed, put them in the list
73
- this.ids = wp_smushit_data.resmush.length > 0 && !skip_resmush ? wp_smushit_data.resmush.concat( wp_smushit_data.unsmushed ) : wp_smushit_data.unsmushed ;
 
 
 
 
 
 
 
74
 
75
  this.is_bulk_resmush = wp_smushit_data.resmush.length > 0 && !skip_resmush ? true : false;
76
 
77
  this.$status = this.$button.parent().find('.smush-status');
78
 
79
  //Added for NextGen support
80
- this.smush_type = typeof smush_type ? smush_type : false;
81
- this.single_ajax_suffix = this.smush_type ? 'smush_manual_nextgen' : 'wp_smushit_manual';
82
- this.bulk_ajax_suffix = this.smush_type ? 'wp_smushit_nextgen_bulk' : 'wp_smushit_bulk';
83
  this.url = this.is_bulk ? smushAddParams(this.url, {action: this.bulk_ajax_suffix}) : smushAddParams(this.url, {action: this.single_ajax_suffix});
84
  };
85
 
@@ -121,16 +182,6 @@ jQuery(function ($) {
121
  //Show the Progress Bar
122
  $('.bulk-smush-wrapper .wp-smush-bulk-progress-bar-wrapper').show();
123
 
124
- //Set Progress Bar width
125
- if( 'undefined' !== typeof this.ids && 'undefined' !== typeof wp_smushit_data.count_total && wp_smushit_data.count_total > 0 ) {
126
- var progress = ( ( wp_smushit_data.count_total - this.ids.length ) / wp_smushit_data.count_total ) * 100;
127
- var progress_bar = jQuery('.bulk-smush-wrapper .wp-smush-progress-inner');
128
- if ( progress_bar.length < 1) {
129
- return;
130
- }
131
- // increase progress
132
- progress_bar.css('width', progress + '%');
133
- }
134
  //Remove any Global Notices if there
135
  $('.wp-smush-notice.wp-smush-resmush-message').remove();
136
  };
@@ -145,7 +196,7 @@ jQuery(function ($) {
145
  this.$button.prop("disabled", false);
146
  //For Bulk process, Enable other buttons
147
  $('button.wp-smush-all').removeAttr('disabled');
148
- $('button.wp-smush-scan').removeAttr('disabled');
149
  };
150
 
151
  this.show_loader = function () {
@@ -164,21 +215,29 @@ jQuery(function ($) {
164
  if (typeof response.data != 'undefined') {
165
  //Append the smush stats or error
166
  self.$status.html(response.data);
 
 
 
 
167
  if (response.success && response.data !== "Not processed") {
168
  self.$status.removeClass('hidden');
169
  self.$button.parent().removeClass('unsmushed').addClass('smushed');
170
  self.$button.remove();
171
  } else {
172
  self.$status.addClass("error");
 
 
 
 
 
173
  }
174
- self.$status.html( response.data.status );
175
  //Check if stats div exists
176
  var parent = self.$status.parent();
177
  var stats_div = parent.find('.smush-stats-wrapper');
178
- if( 'undefined' != stats_div && stats_div.length ) {
179
- stats_div.replaceWith( response.data.stats );
180
- }else{
181
- parent.append( response.data.stats );
182
  }
183
  }
184
  self.enable_button();
@@ -198,8 +257,9 @@ jQuery(function ($) {
198
  this.enable_button();
199
 
200
  //Show Notice
201
- if ( self.ids.length == 0 ) {
202
  $('.bulk-smush-wrapper .wp-smush-all-done').show();
 
203
  } else {
204
  if ($('.bulk-smush-wrapper .wp-smush-resmush-notice').length > 0) {
205
  $('.bulk-smush-wrapper .wp-smush-resmush-notice').show();
@@ -225,7 +285,7 @@ jQuery(function ($) {
225
  //Hide the Progress bar and show the Bulk smush wrapper
226
  $('.wp-smush-bulk-progress-bar-wrapper').hide();
227
 
228
- if ( self.ids.length > 0 ) {
229
  //Show Bulk wrapper
230
  $('.wp-smush-bulk-wrapper ').show();
231
  } else {
@@ -234,15 +294,15 @@ jQuery(function ($) {
234
  };
235
 
236
  this.update_remaining_count = function () {
237
- if( this.is_bulk_resmush ) {
238
  //ReSmush Notice
239
- if( $('.wp-smush-resmush-notice .wp-smush-remaining-count').length && 'undefined' != typeof self.ids ) {
240
- $('.wp-smush-resmush-notice .wp-smush-remaining-count').html( self.ids.length );
241
  }
242
- }else{
243
  //Smush Notice
244
- if( $('.bulk-smush-wrapper .wp-smush-remaining-count').length && 'undefined' != typeof self.ids ) {
245
- $('.bulk-smush-wrapper .wp-smush-remaining-count').html( self.ids.length );
246
  }
247
  }
248
  }
@@ -255,12 +315,14 @@ jQuery(function ($) {
255
 
256
  var progress = '';
257
 
 
 
 
 
 
258
  if (!this.is_bulk_resmush) {
259
- if (_res && ( 'undefined' == typeof _res.data || 'undefined' == typeof _res.data.stats )) {
260
- return;
261
- }
262
  //handle progress for normal bulk smush
263
- progress = ( _res.data.stats.smushed / _res.data.stats.total) * 100;
264
  } else {
265
  //If the Request was successful, Update the progress bar
266
  if (_res.success) {
@@ -268,7 +330,7 @@ jQuery(function ($) {
268
  if (wp_smushit_data.resmush.length > 0) {
269
  //Update the Count
270
  $('.wp-smush-images-remaining').html(wp_smushit_data.resmush.length);
271
- } else if (wp_smushit_data.resmush.length == 0) {
272
  //If all images are resmushed, show the All Smushed message
273
 
274
  //Show All Smushed
@@ -287,7 +349,7 @@ jQuery(function ($) {
287
  }
288
 
289
  //Show Bulk Wrapper and Smush Notice
290
- if( self.ids.length == 0 ) {
291
  //Hide the bulk wrapper
292
  $('.wp-smush-bulk-wrapper').hide();
293
  //Show All done notice
@@ -299,26 +361,17 @@ jQuery(function ($) {
299
 
300
  //if we have received the progress data, update the stats else skip
301
  if ('undefined' != typeof _res.data.stats) {
302
- //Temporary Workaround, @todo: Need to fix this jugaad
303
- var smushed_count = self.is_bulk_resmush ? ( _res.data.stats.total - self.ids.length ) + 1 : _res.data.stats.smushed;
304
- smushed_count = smushed_count > _res.data.stats.total ? _res.data.stats.total : smushed_count;
305
- //Update stats
306
- $('.smush-total-reduction-percent .wp-smush-stats').html(_res.data.stats.percent);
307
- $('.smush-total-reduction-bytes .wp-smush-stats').html(_res.data.stats.human);
308
-
309
- $('.smush-attachments .wp-smush-stats .smushed-count, .wp-smush-images-smushed').html(smushed_count);
310
- if ($('.super-smush-attachments .smushed-count').length && 'undefined' != typeof _res.data.stats.super_smushed) {
311
- $('.super-smush-attachments .smushed-count').html(_res.data.stats.super_smushed);
312
- }
313
 
314
  // increase the progress bar
315
- this._update_progress(_res.data.stats.smushed, progress);
316
  }
 
 
317
  };
318
 
319
  this._update_progress = function (count, width) {
320
  "use strict";
321
- if ( !this.is_bulk && !this.is_bulk_resmush ) {
322
  return;
323
  }
324
  //Update the Progress Bar Width
@@ -347,7 +400,7 @@ jQuery(function ($) {
347
  return continue_smush && this.ids.length > 0 && this.is_bulk;
348
  };
349
 
350
- this.increment_errors = function ( id ) {
351
  WP_Smush.errors.push(id);
352
  };
353
 
@@ -355,6 +408,10 @@ jQuery(function ($) {
355
  this.call_ajax = function () {
356
  var nonce_value = '';
357
  this.current_id = this.is_bulk ? this.ids.shift() : this.$button.data("id"); //remove from array while processing so we can continue where left off
 
 
 
 
358
  var nonce_field = this.$button.parent().find('#_wp_smush_nonce');
359
  if (nonce_field) {
360
  nonce_value = nonce_field.val();
@@ -362,11 +419,11 @@ jQuery(function ($) {
362
 
363
  this.request = WP_Smush.ajax(this.is_bulk_resmush, this.current_id, this.url, 0, nonce_value)
364
  .error(function () {
365
- self.increment_errors( self.current_id );
366
- }).done(function (res ) {
367
  //Increase the error count if any
368
  if (typeof res.success === "undefined" || ( typeof res.success !== "undefined" && res.success === false && res.data.error !== 'bulk_request_image_limit_exceeded' )) {
369
- self.increment_errors( self.current_id );
370
  }
371
  //If no response or success is false, do not process further
372
  if (typeof res == 'undefined' || !res || !res.success) {
@@ -377,7 +434,10 @@ jQuery(function ($) {
377
  }
378
  }
379
 
380
- if (typeof res.data !== "undefined" && res.data.error == 'bulk_request_image_limit_exceeded' && !self.is_resolved() ) {
 
 
 
381
  //Add a data attribute to the smush button, to stop sending ajax
382
  self.$button.attr('continue_smush', false);
383
 
@@ -390,7 +450,7 @@ jQuery(function ($) {
390
  self.update_remaining_count();
391
  } else {
392
 
393
- if (self.is_bulk && res.success ) {
394
  self.update_progress(res);
395
  }
396
  }
@@ -399,7 +459,7 @@ jQuery(function ($) {
399
  if (!self.continue() || !self.is_bulk) {
400
  //Calls deferred.done()
401
  self.deferred.resolve();
402
- }else{
403
  self.call_ajax();
404
  }
405
  });
@@ -452,7 +512,7 @@ jQuery(function ($) {
452
  this.cancel_ajax = function () {
453
  $('.wp-smush-cancel-bulk').on('click', function () {
454
  //Add a data attribute to the smush button, to stop sending ajax
455
- self.$button.attr('continue_smush', false );
456
 
457
  self.request.abort();
458
  self.enable_button();
@@ -463,6 +523,25 @@ jQuery(function ($) {
463
  $('.wp-smush-bulk-progress-bar-wrapper').hide();
464
  });
465
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
 
467
  this.start();
468
  this.run();
@@ -485,7 +564,7 @@ jQuery(function ($) {
485
  $('.wp-smush-notice.wp-smush-settings-updated').remove();
486
 
487
  //Disable Resmush and scan button
488
- $('.wp-resmush.wp-smush-action, .wp-smush-scan, .wp-smush-button').attr('disabled', 'disabled');
489
 
490
  //Check for ids, if there is none (Unsmushed or lossless), don't call smush function
491
  if (typeof wp_smushit_data == 'undefined' ||
@@ -500,7 +579,7 @@ jQuery(function ($) {
500
 
501
  new WP_Smush.Smush($(this), true);
502
 
503
-
504
  });
505
 
506
  /** Disable the action links **/
@@ -530,10 +609,10 @@ jQuery(function ($) {
530
  * @param smush_action
531
  * @returns {boolean}
532
  */
533
- var process_smush_action = function( e, current_button, smush_action ) {
534
 
535
  //If disabled
536
- if( 'disabled' == current_button.attr('disabled') ) {
537
  return false;
538
  }
539
 
@@ -553,23 +632,23 @@ jQuery(function ($) {
553
  };
554
 
555
  //Reduce the opacity of stats and disable the click
556
- disable_links( current_button );
557
 
558
- progress_bar( current_button, wp_smush_msgs.smushing, 'show' );
559
 
560
  //Restore the image
561
  $.post(ajaxurl, params, function (r) {
562
 
563
- progress_bar( current_button, wp_smush_msgs.smushing, 'hide' );
564
 
565
  //reset all functionality
566
- enable_links( current_button );
567
 
568
- if (r.success && 'undefined' != typeof( r.data.button ) ) {
569
  //Show the smush button, and remove stats and restore option
570
  current_button.parents().eq(1).html(r.data.button);
571
  } else {
572
- if(r.data.message ) {
573
  //show error
574
  current_button.parent().append(r.data.message);
575
  }
@@ -578,96 +657,131 @@ jQuery(function ($) {
578
  };
579
 
580
  /**
581
- * Handle the Smush Stats link click
 
 
 
 
 
 
582
  */
583
- $('body').on('click', 'a.smush-stats-details', function (e) {
 
 
 
 
 
 
 
 
 
584
 
585
- //If disabled
586
- if( 'disabled' == $(this).attr('disabled') ) {
587
- return false;
 
 
 
588
  }
589
 
590
- // prevent the default action
591
- e.preventDefault();
592
- //Replace the `+` with a `-`
593
- var slide_symbol = $(this).find('.stats-toggle');
594
- $(this).parents().eq(1).find('.smush-stats-wrapper').slideToggle();
595
- slide_symbol.text(slide_symbol.text() == '+' ? '-' : '+');
596
 
597
-
598
- });
 
 
 
 
 
 
 
 
 
 
 
599
 
600
- /** Handle smush button click **/
601
- $('body').on('click', '.wp-smush-send:not(.wp-smush-resmush)', function (e) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
 
603
- // prevent the default action
604
- e.preventDefault();
605
- new WP_Smush.Smush($(this), false);
606
- });
607
 
608
- /** Handle NextGen Gallery smush button click **/
609
- $('body').on('click', '.wp-smush-nextgen-send', function (e) {
610
 
611
- // prevent the default action
612
- e.preventDefault();
613
- new WP_Smush.Smush($(this), false, 'nextgen');
614
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615
 
616
- /** Handle NextGen Gallery Bulk smush button click **/
617
- $('body').on('click', '.wp-smush-nextgen-bulk', function (e) {
618
 
619
- // prevent the default action
620
- e.preventDefault();
 
 
 
621
 
622
- //Check for ids, if there is none (Unsmushed or lossless), don't call smush function
623
- if (typeof wp_smushit_data == 'undefined' ||
624
- ( wp_smushit_data.unsmushed.length == 0 && wp_smushit_data.resmush.length == 0 )
625
- ) {
 
 
626
 
 
627
  return false;
628
-
629
  }
630
 
631
- jQuery('.wp-smush-button, .wp-smush-scan').attr('disabled', 'disabled');
632
- $(".wp-smush-notice.wp-smush-remaining").hide();
633
- new WP_Smush.Smush($(this), true, 'nextgen');
634
-
635
- });
636
-
637
- /** Restore: Media Library **/
638
- $('body').on('click', '.wp-smush-action.wp-smush-restore', function (e) {
639
- var current_button = $(this);
640
- var smush_action = 'smush_restore_image';
641
- process_smush_action( e, current_button, smush_action );
642
- });
643
-
644
- /** Resmush: Media Library **/
645
- $('body').on('click', '.wp-smush-action.wp-smush-resmush', function (e) {
646
- var current_button = $(this);
647
- var smush_action = 'smush_resmush_image';
648
- process_smush_action( e, current_button, smush_action );
649
- });
650
-
651
- /** Restore: NextGen Gallery **/
652
- $('body').on('click', '.wp-smush-action.wp-smush-nextgen-restore', function (e) {
653
- var current_button = $(this);
654
- var smush_action = 'smush_restore_nextgen_image';
655
- process_smush_action( e, current_button, smush_action );
656
- });
657
 
658
- /** Resmush: NextGen Gallery **/
659
- $('body').on('click', '.wp-smush-action.wp-smush-nextgen-resmush', function (e) {
660
- var current_button = $(this);
661
- var smush_action = 'smush_resmush_nextgen_image';
662
- process_smush_action( e, current_button, smush_action );
663
- });
664
 
665
- //Scan For resmushing images
666
- $('body').on('click', '.wp-smush-scan', function(e) {
667
 
668
- e.preventDefault();
 
 
669
 
670
- var button = jQuery(this);
671
  var spinner = button.parent().find('.spinner');
672
 
673
  //Check if type is set in data attributes
@@ -688,7 +802,7 @@ jQuery(function ($) {
688
 
689
  //Disable Bulk smush button and itself
690
  button.attr('disabled', 'disabled');
691
- $('.wp-smush-button' ).attr('disabled', 'disabled');
692
 
693
  //Hide Settings changed Notice
694
  $('.wp-smush-settings-changed').hide();
@@ -701,22 +815,34 @@ jQuery(function ($) {
701
  action: 'scan_for_resmush',
702
  type: scan_type,
703
  get_ui: true,
 
704
  wp_smush_options_nonce: jQuery('#wp_smush_options_nonce').val()
705
  };
706
 
707
  //Send ajax request and get ids if any
708
  $.get(ajaxurl, params, function (r) {
709
  //Check if we have the ids, initialize the local variable
710
- if( 'undefined' != typeof r.data ) {
711
  //Update Resmush id list
712
- if( 'undefined' != typeof r.data.resmush_ids ) {
713
  wp_smushit_data.resmush = r.data.resmush_ids;
714
 
715
- //Get the Smushed image count
716
- var smushed_count = wp_smushit_data.count_smushed - r.data.resmush_ids.length;
 
 
 
 
 
 
 
 
 
 
 
717
 
718
  //Update it in stats bar
719
- $('.smush-attachments .wp-smush-stats .smushed-count, .wp-smush-images-smushed').html(smushed_count);
720
 
721
  //Hide the Existing wrapper
722
  var notices = $('.bulk-smush-wrapper .wp-smush-notice');
@@ -728,18 +854,37 @@ jQuery(function ($) {
728
 
729
  //Show Bulk wrapper
730
  $('.wp-smush-bulk-wrapper').show();
 
 
 
 
 
731
  }
732
  //If content is received, Prepend it
733
  if ('undefined' != typeof r.data.content) {
734
  $('.bulk-smush-wrapper .box-container').prepend(r.data.content);
735
  }
736
  //If we have any notice to show
737
- if ('undefined' != typeof r.data.notice ) {
738
  $('.wp-smush-page-header').after(r.data.notice);
739
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
740
  }
741
 
742
- }).always( function() {
743
 
744
  //Hide the progress bar
745
  jQuery('.bulk-smush-wrapper .wp-smush-bulk-progress-bar-wrapper').hide();
@@ -750,148 +895,1433 @@ jQuery(function ($) {
750
  //Hide Spinner
751
  spinner.removeClass('is-active');
752
  $('.wp-smush-button').removeAttr('disabled');
753
- });
754
-
755
- });
756
 
757
- //Dismiss Welcome notice
758
- $('#wp-smush-welcome-box .smush-dismiss-welcome').on('click', function(e) {
759
- e.preventDefault();
760
- var $el = $(this).parents().eq(1);
761
- $el.fadeTo( 100, 0, function() {
762
- $el.slideUp( 100, function() {
763
- $el.remove();
764
- });
765
  });
766
- //Send a ajax request to save the dismissed notice option
767
- var param = {
768
- action: 'dismiss_welcome_notice'
769
- };
770
- $.post(ajaxurl, param );
771
- });
772
 
773
- //Remove Notice
774
- $('body').on('click', '.wp-smush-notice .dev-icon-cross', function(e) {
775
- e.preventDefault();
776
- var $el = $(this).parent();
777
- $el.fadeTo( 100, 0, function() {
778
- $el.slideUp( 100, function() {
779
- $el.remove();
780
- });
 
 
 
 
 
 
 
 
 
 
 
781
  });
782
- });
783
-
784
- //On Click Update Settings. Check for change in settings
785
- $('#wp-smush-save-settings').on('click', function(e) {
786
- e.preventDefault();
787
-
788
- var self = $(this);
789
- //Update text
790
- self.attr('disabled', 'disabled').addClass('button-grey').val( wp_smush_msgs.checking );
791
- self.parent().find('.spinner').addClass('is-active');
792
 
793
- //Check if type is set in data attributes
794
- var scan_type = self.data('type');
795
- scan_type = 'undefined' == typeof scan_type ? 'media' : scan_type;
796
 
797
- //Ajax param
798
- var param = {
799
- action: 'scan_for_resmush',
800
- scan_type: scan_type
801
- };
802
 
803
- param = jQuery.param( param ) + '&' + jQuery('form#wp-smush-settings-form').serialize();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
 
805
- //Send ajax, Update Settings, And Check For resmush
806
- jQuery.post(ajaxurl, param).done(function () {
807
- jQuery('form#wp-smush-settings-form').submit();
 
 
 
 
 
 
 
 
808
  return true;
809
- });
810
- });
 
811
 
812
- //On Resmush click
813
- $('body').on('click', '.wp-smush-skip-resmush', function (e) {
814
- e.preventDefault();
815
- var self = jQuery(this);
816
- var container = self.parents().eq(1);
 
 
 
 
817
 
818
- //Remove Parent div
819
- var $el = self.parent();
820
- $el.fadeTo( 100, 0, function() {
821
- $el.slideUp( 100, function() {
822
- $el.remove();
823
- });
824
- });
 
 
 
 
 
 
 
 
 
 
 
825
 
826
- //Remove Settings Notice
827
- $('.wp-smush-notice.wp-smush-settings-updated').remove();
 
 
 
 
 
 
 
828
 
829
- //Set button attribute to skip re-smush ids
830
- container.find('.wp-smush-all').attr('data-smush', 'skip_resmush');
 
 
 
 
 
 
 
 
 
 
831
 
832
- //Update Stats
833
- if( wp_smushit_data.count_smushed == wp_smushit_data.count_total ) {
834
 
835
- //Show all done notice
836
- $('.wp-smush-notice.wp-smush-all-done').show();
837
 
838
- //Hide Smush button
839
- $('.wp-smush-bulk-wrapper ').hide()
 
 
 
 
 
 
840
 
 
 
 
 
 
841
  }
842
- //Remove Re-Smush Notice
843
- $('.wp-smush-resmush-notice').remove();
844
 
845
- var type = $('.wp-smush-scan').data('type');
846
- type = 'undefined' == typeof type ? 'media' : type;
847
 
848
- var smushed_count = 'undefined' != typeof wp_smushit_data.count_smushed ? wp_smushit_data.count_smushed : 0
849
- $('.smush-attachments .wp-smush-stats .smushed-count, .wp-smush-images-smushed').html(smushed_count);
 
 
 
 
 
 
 
850
 
851
- //Show the default bulk smush notice
852
- $('.wp-smush-bulk-wrapper .wp-smush-notice').removeClass('hidden');
 
 
853
 
854
- var params = {
855
- action: 'delete_resmush_list',
856
- type: type
 
857
  }
858
- //Delete resmush list
859
- $.post(ajaxurl, params);
860
 
861
- });
 
 
862
 
863
- //Enable Super Smush
864
- $('.wp-smush-lossy-enable').on('click', function (e) {
865
- e.preventDefault();
866
 
867
- //Enable Super Smush
868
- $('#wp-smush-lossy').prop('checked', true);
869
- //Induce Setting button save click
870
- $('#wp-smush-save-settings').click();
871
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
872
 
873
- //Trigger Bulk
874
- $('body').on('click', '.wp-smush-trigger-bulk', function (e) {
875
- e.preventDefault();
876
- //Induce Setting button save click
877
- $('button.wp-smush-all').click();
878
 
879
- });
 
 
880
 
881
- //Dismiss Install/Upgrade notice
882
- $('#wp-smush-install-thanks .smush-dismiss-welcome').on('click', function(e) {
883
- e.preventDefault();
884
- var $el = $(this).parents().eq(2);
885
- $el.fadeTo( 100, 0, function() {
886
- $el.slideUp( 100, function() {
887
- $el.remove();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
888
  });
889
- });
890
- //Send a ajax request to save the dismissed notice option
891
- var param = {
892
- action: 'dismiss_upgrade_notice'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
893
  };
894
- $.post(ajaxurl, param );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
895
  });
896
 
897
  });
1
  /**
2
  * Processes bulk smushing
3
  *
 
4
  * @author Umesh Kumar <umeshsingla05@gmail.com>
5
  *
6
  */
7
+ /**@todo: Use Element tag for all the class selectors **/
8
+
9
  var WP_Smush = WP_Smush || {};
10
 
11
  /**
15
  * @param txt Message to be displayed
16
  * @param state show/hide
17
  */
18
+ var progress_bar = function (cur_ele, txt, state) {
19
 
20
  //Update Progress bar text and show it
21
  var progress_button = cur_ele.parents().eq(1).find('.wp-smush-progress');
22
 
23
+ if ('show' == state) {
24
  progress_button.find('span').html(txt);
25
  progress_button.removeClass('hidden');
26
+ } else {
27
+ progress_button.find('span').html(wp_smush_msgs.all_done);
28
  progress_button.hide();
29
  }
30
  };
31
+
32
+ var dash_offset = function (percent) {
33
+ //Get the dasharray value
34
+ var dasharray = jQuery('.wp-smush-svg-circle-progress').attr('stroke-dasharray');
35
+ return dasharray - ( dasharray * percent );
36
+ }
37
+
38
+ var update_dashoffset = function () {
39
+ var total = wp_smushit_data.count_total;
40
+ if (total > 0) {
41
+ var dashoffset = dash_offset(wp_smushit_data.count_smushed / total);
42
+ var circle_progress = jQuery('.wp-smush-svg-circle-progress');
43
+ if (typeof dashoffset != 'undefined' && circle_progress.length) {
44
+ circle_progress.css({'stroke-dashoffset': dashoffset});
45
+ }
46
+ }
47
+ };
48
+
49
+ var membership_validity = function (data) {
50
+ var member_validity_notice = jQuery('#wp-smush-invalid-member');
51
+
52
+ //Check for Membership warning
53
+ if ('undefined' != typeof ( data.show_warning ) && member_validity_notice.length > 0) {
54
+ if (data.show_warning) {
55
+ member_validity_notice.show();
56
+ } else {
57
+ member_validity_notice.hide();
58
+ }
59
+ }
60
+ };
61
+ /**
62
+ * Resize Background width
63
+ */
64
+ var resize_width = function () {
65
+ var width = jQuery('.wp-smush-pro-for-free').width();
66
+ if ('undefined' != typeof ( width ) && 500 < width) {
67
+ jQuery('.wpmud .wp-smush-pro-adv').css({'background-size': '500px'});
68
+ } else {
69
+ jQuery('.wpmud .wp-smush-pro-adv').css({'background-size': '90%'});
70
+ }
71
+ };
72
+
73
+ var remove_element = function (el, timeout) {
74
+ if (typeof timeout == 'undefined') {
75
+ timeout = 100;
76
+ }
77
+ el.fadeTo(timeout, 0, function () {
78
+ el.slideUp(timeout, function () {
79
+ el.remove();
80
+ });
81
+ });
82
+ };
83
+
84
  jQuery(function ($) {
85
  var smushAddParams = function (url, data) {
86
  if (!$.isEmptyObject(data)) {
123
  this.deferred = jQuery.Deferred();
124
  this.deferred.errors = [];
125
 
126
+ var ids = wp_smushit_data.resmush.length > 0 && !skip_resmush ? ( wp_smushit_data.unsmushed.length > 0 ? wp_smushit_data.resmush.concat(wp_smushit_data.unsmushed) : wp_smushit_data.resmush ) : wp_smushit_data.unsmushed;
127
+ if ('object' == typeof ids) {
128
+ //If button has resmush class, and we do have ids that needs to resmushed, put them in the list
129
+ this.ids = ids.filter(function (itm, i, a) {
130
+ return i == a.indexOf(itm);
131
+ });
132
+ } else {
133
+ this.ids = ids;
134
+ }
135
 
136
  this.is_bulk_resmush = wp_smushit_data.resmush.length > 0 && !skip_resmush ? true : false;
137
 
138
  this.$status = this.$button.parent().find('.smush-status');
139
 
140
  //Added for NextGen support
141
+ this.smush_type = 'undefined' != typeof smush_type ? smush_type : 'media';
142
+ this.single_ajax_suffix = 'nextgen' == this.smush_type ? 'smush_manual_nextgen' : 'wp_smushit_manual';
143
+ this.bulk_ajax_suffix = 'nextgen' == this.smush_type ? 'wp_smushit_nextgen_bulk' : 'wp_smushit_bulk';
144
  this.url = this.is_bulk ? smushAddParams(this.url, {action: this.bulk_ajax_suffix}) : smushAddParams(this.url, {action: this.single_ajax_suffix});
145
  };
146
 
182
  //Show the Progress Bar
183
  $('.bulk-smush-wrapper .wp-smush-bulk-progress-bar-wrapper').show();
184
 
 
 
 
 
 
 
 
 
 
 
185
  //Remove any Global Notices if there
186
  $('.wp-smush-notice.wp-smush-resmush-message').remove();
187
  };
196
  this.$button.prop("disabled", false);
197
  //For Bulk process, Enable other buttons
198
  $('button.wp-smush-all').removeAttr('disabled');
199
+ $('button.wp-smush-scan, button.wp-smush-lossy-enable, button.wp-smush-resize-enable, input#wp-smush-save-settings').removeAttr('disabled');
200
  };
201
 
202
  this.show_loader = function () {
215
  if (typeof response.data != 'undefined') {
216
  //Append the smush stats or error
217
  self.$status.html(response.data);
218
+
219
+ //Check whether to show membership validity notice or not
220
+ membership_validity(response.data);
221
+
222
  if (response.success && response.data !== "Not processed") {
223
  self.$status.removeClass('hidden');
224
  self.$button.parent().removeClass('unsmushed').addClass('smushed');
225
  self.$button.remove();
226
  } else {
227
  self.$status.addClass("error");
228
+ self.$status.html(response.data.error_msg);
229
+ self.$status.show();
230
+ }
231
+ if (response.data.status) {
232
+ self.$status.html(response.data.status);
233
  }
 
234
  //Check if stats div exists
235
  var parent = self.$status.parent();
236
  var stats_div = parent.find('.smush-stats-wrapper');
237
+ if ('undefined' != stats_div && stats_div.length) {
238
+ stats_div.replaceWith(response.data.stats);
239
+ } else {
240
+ parent.append(response.data.stats);
241
  }
242
  }
243
  self.enable_button();
257
  this.enable_button();
258
 
259
  //Show Notice
260
+ if (self.ids.length == 0) {
261
  $('.bulk-smush-wrapper .wp-smush-all-done').show();
262
+ $('.wp-smush-bulk-wrapper').hide();
263
  } else {
264
  if ($('.bulk-smush-wrapper .wp-smush-resmush-notice').length > 0) {
265
  $('.bulk-smush-wrapper .wp-smush-resmush-notice').show();
285
  //Hide the Progress bar and show the Bulk smush wrapper
286
  $('.wp-smush-bulk-progress-bar-wrapper').hide();
287
 
288
+ if (self.ids.length > 0) {
289
  //Show Bulk wrapper
290
  $('.wp-smush-bulk-wrapper ').show();
291
  } else {
294
  };
295
 
296
  this.update_remaining_count = function () {
297
+ if (this.is_bulk_resmush) {
298
  //ReSmush Notice
299
+ if ($('.wp-smush-resmush-notice .wp-smush-remaining-count').length && 'undefined' != typeof self.ids) {
300
+ $('.wp-smush-resmush-notice .wp-smush-remaining-count').html(self.ids.length);
301
  }
302
+ } else {
303
  //Smush Notice
304
+ if ($('.bulk-smush-wrapper .wp-smush-remaining-count').length && 'undefined' != typeof self.ids) {
305
+ $('.bulk-smush-wrapper .wp-smush-remaining-count').html(self.ids.length);
306
  }
307
  }
308
  }
315
 
316
  var progress = '';
317
 
318
+ //Update localized stats
319
+ if (_res && ( 'undefined' != typeof _res.data || 'undefined' != typeof _res.data.stats )) {
320
+ update_localized_stats( _res.data.stats, this.smush_type );
321
+ }
322
+
323
  if (!this.is_bulk_resmush) {
 
 
 
324
  //handle progress for normal bulk smush
325
+ progress = ( wp_smushit_data.count_smushed / wp_smushit_data.count_total ) * 100;
326
  } else {
327
  //If the Request was successful, Update the progress bar
328
  if (_res.success) {
330
  if (wp_smushit_data.resmush.length > 0) {
331
  //Update the Count
332
  $('.wp-smush-images-remaining').html(wp_smushit_data.resmush.length);
333
+ } else if (wp_smushit_data.resmush.length == 0 && this.ids.length == 0) {
334
  //If all images are resmushed, show the All Smushed message
335
 
336
  //Show All Smushed
349
  }
350
 
351
  //Show Bulk Wrapper and Smush Notice
352
+ if (self.ids.length == 0) {
353
  //Hide the bulk wrapper
354
  $('.wp-smush-bulk-wrapper').hide();
355
  //Show All done notice
361
 
362
  //if we have received the progress data, update the stats else skip
363
  if ('undefined' != typeof _res.data.stats) {
 
 
 
 
 
 
 
 
 
 
 
364
 
365
  // increase the progress bar
366
+ this._update_progress(wp_smushit_data.count_smushed, progress);
367
  }
368
+ // Update stats and counts.
369
+ update_stats();
370
  };
371
 
372
  this._update_progress = function (count, width) {
373
  "use strict";
374
+ if (!this.is_bulk && !this.is_bulk_resmush) {
375
  return;
376
  }
377
  //Update the Progress Bar Width
400
  return continue_smush && this.ids.length > 0 && this.is_bulk;
401
  };
402
 
403
+ this.increment_errors = function (id) {
404
  WP_Smush.errors.push(id);
405
  };
406
 
408
  this.call_ajax = function () {
409
  var nonce_value = '';
410
  this.current_id = this.is_bulk ? this.ids.shift() : this.$button.data("id"); //remove from array while processing so we can continue where left off
411
+
412
+ //Remove the id from respective variable as well
413
+ this.update_smush_ids(this.current_id);
414
+
415
  var nonce_field = this.$button.parent().find('#_wp_smush_nonce');
416
  if (nonce_field) {
417
  nonce_value = nonce_field.val();
419
 
420
  this.request = WP_Smush.ajax(this.is_bulk_resmush, this.current_id, this.url, 0, nonce_value)
421
  .error(function () {
422
+ self.increment_errors(self.current_id);
423
+ }).done(function (res) {
424
  //Increase the error count if any
425
  if (typeof res.success === "undefined" || ( typeof res.success !== "undefined" && res.success === false && res.data.error !== 'bulk_request_image_limit_exceeded' )) {
426
+ self.increment_errors(self.current_id);
427
  }
428
  //If no response or success is false, do not process further
429
  if (typeof res == 'undefined' || !res || !res.success) {
434
  }
435
  }
436
 
437
+ //Check whether to show the warning notice or not
438
+ membership_validity(res.data);
439
+
440
+ if (typeof res.data !== "undefined" && res.data.error == 'bulk_request_image_limit_exceeded' && !self.is_resolved()) {
441
  //Add a data attribute to the smush button, to stop sending ajax
442
  self.$button.attr('continue_smush', false);
443
 
450
  self.update_remaining_count();
451
  } else {
452
 
453
+ if (self.is_bulk && res.success) {
454
  self.update_progress(res);
455
  }
456
  }
459
  if (!self.continue() || !self.is_bulk) {
460
  //Calls deferred.done()
461
  self.deferred.resolve();
462
+ } else {
463
  self.call_ajax();
464
  }
465
  });
512
  this.cancel_ajax = function () {
513
  $('.wp-smush-cancel-bulk').on('click', function () {
514
  //Add a data attribute to the smush button, to stop sending ajax
515
+ self.$button.attr('continue_smush', false);
516
 
517
  self.request.abort();
518
  self.enable_button();
523
  $('.wp-smush-bulk-progress-bar-wrapper').hide();
524
  });
525
  };
526
+ /**
527
+ * Remove the current id from unsmushed/resmush variable
528
+ * @param current_id
529
+ */
530
+ this.update_smush_ids = function (current_id) {
531
+ if ('undefined' !== typeof wp_smushit_data.unsmushed && wp_smushit_data.unsmushed.length > 0) {
532
+ var u_index = wp_smushit_data.unsmushed.indexOf(current_id);
533
+ if (u_index > -1) {
534
+ wp_smushit_data.unsmushed.splice(u_index, 1);
535
+ }
536
+ }
537
+ //remove from the resmush list
538
+ if ('undefined' !== typeof wp_smushit_data.resmush && wp_smushit_data.resmush.length > 0) {
539
+ var index = wp_smushit_data.resmush.indexOf(current_id);
540
+ if (index > -1) {
541
+ wp_smushit_data.resmush.splice(index, 1);
542
+ }
543
+ }
544
+ }
545
 
546
  this.start();
547
  this.run();
564
  $('.wp-smush-notice.wp-smush-settings-updated').remove();
565
 
566
  //Disable Resmush and scan button
567
+ $('.wp-resmush.wp-smush-action, .wp-smush-scan, .wp-smush-button, button.wp-smush-lossy-enable, button.wp-smush-resize-enable, input#wp-smush-save-settings').attr('disabled', 'disabled');
568
 
569
  //Check for ids, if there is none (Unsmushed or lossless), don't call smush function
570
  if (typeof wp_smushit_data == 'undefined' ||
579
 
580
  new WP_Smush.Smush($(this), true);
581
 
582
+
583
  });
584
 
585
  /** Disable the action links **/
609
  * @param smush_action
610
  * @returns {boolean}
611
  */
612
+ var process_smush_action = function (e, current_button, smush_action, action) {
613
 
614
  //If disabled
615
+ if ('disabled' == current_button.attr('disabled')) {
616
  return false;
617
  }
618
 
632
  };
633
 
634
  //Reduce the opacity of stats and disable the click
635
+ disable_links(current_button);
636
 
637
+ progress_bar(current_button, wp_smush_msgs[action], 'show');
638
 
639
  //Restore the image
640
  $.post(ajaxurl, params, function (r) {
641
 
642
+ progress_bar(current_button, wp_smush_msgs[action], 'hide');
643
 
644
  //reset all functionality
645
+ enable_links(current_button);
646
 
647
+ if (r.success && 'undefined' != typeof( r.data.button )) {
648
  //Show the smush button, and remove stats and restore option
649
  current_button.parents().eq(1).html(r.data.button);
650
  } else {
651
+ if (r.data.message) {
652
  //show error
653
  current_button.parent().append(r.data.message);
654
  }
657
  };
658
 
659
  /**
660
+ * Validates the Resize Width and Height against the Largest Thumbnail Width and Height
661
+ *
662
+ * @param wrapper_div jQuery object for the whole setting row wrapper div
663
+ * @param width_only Whether to validate only width
664
+ * @param height_only Validate only Height
665
+ * @returns {boolean} All Good or not
666
+ *
667
  */
668
+ var validate_resize_settings = function (wrapper_div, width_only, height_only) {
669
+ var resize_checkbox = wrapper_div.find('#wp-smush-resize');
670
+ if (!height_only) {
671
+ var width_input = wrapper_div.find('#wp-smush-resize_width');
672
+ var width_error_note = wrapper_div.find('.wp-smush-size-info.wp-smush-update-width');
673
+ }
674
+ if (!width_only) {
675
+ var height_input = wrapper_div.find('#wp-smush-resize_height');
676
+ var height_error_note = wrapper_div.find('.wp-smush-size-info.wp-smush-update-height');
677
+ }
678
 
679
+ var width_error = false;
680
+ var height_error = false
681
+
682
+ //If resize settings is not enabled, return true
683
+ if (!resize_checkbox.is(':checked')) {
684
+ return true;
685
  }
686
 
687
+ //Check if we have localised width and height
688
+ if ('undefined' == typeof (wp_smushit_data.resize_sizes) || 'undefined' == typeof (wp_smushit_data.resize_sizes.width)) {
689
+ //Rely on server validation
690
+ return true;
691
+ }
 
692
 
693
+ //Check for width
694
+ if (!height_only && 'undefined' != typeof width_input && parseInt(wp_smushit_data.resize_sizes.width) > parseInt(width_input.val())) {
695
+ width_input.addClass('error');
696
+ width_error_note.show('slow');
697
+ width_error = true;
698
+ } else {
699
+ //Remove error class
700
+ width_input.removeClass('error');
701
+ width_error_note.hide();
702
+ if (height_input.hasClass('error')) {
703
+ height_error_note.show('slow');
704
+ }
705
+ }
706
 
707
+ //Check for height
708
+ if (!width_only && 'undefined' != typeof height_input && parseInt(wp_smushit_data.resize_sizes.height) > parseInt(height_input.val())) {
709
+ height_input.addClass('error');
710
+ //If we are not showing the width error already
711
+ if (!width_error) {
712
+ height_error_note.show('slow');
713
+ }
714
+ height_error = true;
715
+ } else {
716
+ //Remove error class
717
+ height_input.removeClass('error');
718
+ height_error_note.hide();
719
+ if (width_input.hasClass('error')) {
720
+ width_error_note.show('slow');
721
+ }
722
+ }
723
 
724
+ if (width_error || height_error) {
725
+ return false;
726
+ }
727
+ return true;
728
 
729
+ };
 
730
 
731
+ /**
732
+ * Convert bytes to human readable form
733
+ * @param a, Bytes
734
+ * @param b, Number of digits
735
+ * @returns {*} Formatted Bytes
736
+ */
737
+ var formatBytes = function (a, b) {
738
+ var thresh = 1024;
739
+ if(Math.abs(a) < thresh) {
740
+ return a + ' B';
741
+ }
742
+ var units = ['KB','MB','GB','TB','PB'];
743
+ var u = -1;
744
+ do {
745
+ a /= thresh;
746
+ ++u;
747
+ } while(Math.abs(a) >= thresh && u < units.length - 1);
748
+ return a.toFixed(b)+' '+units[u];
749
+ }
750
 
 
 
751
 
752
+ //Stackoverflow: http://stackoverflow.com/questions/1726630/formatting-a-number-with-exactly-two-decimals-in-javascript
753
+ var precise_round = function (num, decimals) {
754
+ var sign = num >= 0 ? 1 : -1;
755
+ return (Math.round((num * Math.pow(10, decimals)) + (sign * 0.001)) / Math.pow(10, decimals));
756
+ };
757
 
758
+ /**
759
+ * Update the progress bar width if we have images that needs to be resmushed
760
+ * @param unsmushed_count
761
+ * @returns {boolean}
762
+ */
763
+ var update_progress_bar_resmush = function (unsmushed_count) {
764
 
765
+ if ('undefined' == typeof unsmushed_count) {
766
  return false;
 
767
  }
768
 
769
+ var smushed_count = wp_smushit_data.count_total - unsmushed_count;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
770
 
771
+ //Update the Progress Bar Width
772
+ // get the progress bar
773
+ var $progress_bar = jQuery('.bulk-smush-wrapper .wp-smush-progress-inner');
774
+ if ($progress_bar.length < 1) {
775
+ return;
776
+ }
777
 
778
+ var width = ( smushed_count / wp_smushit_data.count_total ) * 100;
 
779
 
780
+ // increase progress
781
+ $progress_bar.css('width', width + '%');
782
+ };
783
 
784
+ var run_re_check = function (button, process_settings) {
785
  var spinner = button.parent().find('.spinner');
786
 
787
  //Check if type is set in data attributes
802
 
803
  //Disable Bulk smush button and itself
804
  button.attr('disabled', 'disabled');
805
+ $('.wp-smush-button').attr('disabled', 'disabled');
806
 
807
  //Hide Settings changed Notice
808
  $('.wp-smush-settings-changed').hide();
815
  action: 'scan_for_resmush',
816
  type: scan_type,
817
  get_ui: true,
818
+ process_settings: process_settings,
819
  wp_smush_options_nonce: jQuery('#wp_smush_options_nonce').val()
820
  };
821
 
822
  //Send ajax request and get ids if any
823
  $.get(ajaxurl, params, function (r) {
824
  //Check if we have the ids, initialize the local variable
825
+ if ('undefined' != typeof r.data) {
826
  //Update Resmush id list
827
+ if ('undefined' != typeof r.data.resmush_ids) {
828
  wp_smushit_data.resmush = r.data.resmush_ids;
829
 
830
+ //Update wp_smushit_data ( Smushed count, Smushed Percent, Image count, Super smush count, resize savings, conversion savings )
831
+ if ('undefinied' != typeof wp_smushit_data) {
832
+ wp_smushit_data.count_smushed = 'undefined' != typeof r.data.count_smushed ? r.data.count_smushed : wp_smushit_data.count_smushed;
833
+ wp_smushit_data.count_supersmushed = 'undefined' != typeof r.data.count_supersmushed ? r.data.count_supersmushed : wp_smushit_data.count_supersmushed;
834
+ wp_smushit_data.count_images = 'undefined' != typeof r.data.count_image ? r.data.count_image : wp_smushit_data.count_images;
835
+ wp_smushit_data.size_before = 'undefined' != typeof r.data.size_before ? r.data.size_before : wp_smushit_data.size_before;
836
+ wp_smushit_data.size_after = 'undefined' != typeof r.data.size_after ? r.data.size_after : wp_smushit_data.size_after;
837
+ wp_smushit_data.savings_resize = 'undefined' != typeof r.data.savings_resize ? r.data.savings_resize : wp_smushit_data.savings_resize;
838
+ wp_smushit_data.savings_conversion = 'undefined' != typeof r.data.savings_conversion ? r.data.savings_conversion : wp_smushit_data.savings_conversion;
839
+ }
840
+
841
+ var smush_percent = ( wp_smushit_data.count_smushed / wp_smushit_data.count_total ) * 100;
842
+ smush_percent = precise_round( smush_percent, 1 );
843
 
844
  //Update it in stats bar
845
+ $('.wp-smush-images-percent').html(smush_percent);
846
 
847
  //Hide the Existing wrapper
848
  var notices = $('.bulk-smush-wrapper .wp-smush-notice');
854
 
855
  //Show Bulk wrapper
856
  $('.wp-smush-bulk-wrapper').show();
857
+
858
+ if ('undefined' !== typeof r.data.count) {
859
+ //Update progress bar
860
+ update_progress_bar_resmush(r.data.count);
861
+ }
862
  }
863
  //If content is received, Prepend it
864
  if ('undefined' != typeof r.data.content) {
865
  $('.bulk-smush-wrapper .box-container').prepend(r.data.content);
866
  }
867
  //If we have any notice to show
868
+ if ('undefined' != typeof r.data.notice) {
869
  $('.wp-smush-page-header').after(r.data.notice);
870
  }
871
+ //Hide errors
872
+ $('.smush-final-log').hide();
873
+
874
+ //Hide Super Smush notice if it's enabled in media settings
875
+ if ('undefined' != typeof r.data.super_smush && r.data.super_smush) {
876
+ var enable_lossy = jQuery('.wp-smush-enable-lossy');
877
+ if (enable_lossy.length > 0) {
878
+ enable_lossy.remove();
879
+ }
880
+ if ('undefined' !== r.data.super_smush_stats) {
881
+ $('.super-smush-attachments .wp-smush-stats').html(r.data.super_smush_stats);
882
+ }
883
+ }
884
+ update_stats();
885
  }
886
 
887
+ }).always(function () {
888
 
889
  //Hide the progress bar
890
  jQuery('.bulk-smush-wrapper .wp-smush-bulk-progress-bar-wrapper').hide();
895
  //Hide Spinner
896
  spinner.removeClass('is-active');
897
  $('.wp-smush-button').removeAttr('disabled');
 
 
 
898
 
899
+ //If wp-smush-re-check-message is there, remove it
900
+ if ($('.wp-smush-re-check-message').length) {
901
+ remove_element($('.wp-smush-re-check-message'));
902
+ }
 
 
 
 
903
  });
904
+ }
 
 
 
 
 
905
 
906
+ /**
907
+ * Get directory list using Ajax
908
+ *
909
+ * @param param
910
+ * @returns {string}
911
+ *
912
+ */
913
+ var getDirectoryList = function (param) {
914
+ param.action = 'smush_get_directory_list';
915
+ param.list_nonce = jQuery('input[name="list_nonce"]').val();
916
+ var res = '';
917
+ $.ajax({
918
+ type: "GET",
919
+ url: ajaxurl,
920
+ data: param,
921
+ success: function (response) {
922
+ res = response;
923
+ },
924
+ async: false
925
  });
926
+ return res;
927
+ }
928
+ /**
929
+ * Hide the popup and reset the opacity for the button
930
+ *
931
+ */
932
+ var close_dialog = function () {
933
+ //Hide the dialog
934
+ $('.wp-smush-list-dialog').hide();
935
+ $('.wp-smush-select-dir, button.wp-smush-browse, button.wp-smush-resume').removeAttr('disabled');
936
 
937
+ //Remove the spinner
938
+ $('div.dir-smush-button-wrap span.spinner').removeClass('is-active');
 
939
 
940
+ //Reset the opacity for content and scan button
941
+ $('.wp-smush-select-dir, .wp-smush-list-dialog .box .content').css({'opacity': '1'});
942
+ $('.wp-smush-select-button-wrap .spinner').removeClass('is-active');
943
+ }
 
944
 
945
+ /**
946
+ * Initialize accordion
947
+ *
948
+ */
949
+ var set_accordion = function () {
950
+ //Accordion On WP Smush All Page
951
+ var acc = document.getElementsByClassName("wp-smush-li-path");
952
+ var i;
953
+
954
+ for (i = 0; i < acc.length; i++) {
955
+ acc[i].onclick = function () {
956
+ var parent = $(this).parent();
957
+ if (parent.hasClass('active')) {
958
+ parent.removeClass('active');
959
+ parent.find('.wp-smush-image-list-inner').removeClass("show");
960
+ } else {
961
+ parent.addClass("active");
962
+ $('.wp-smush-image-ul.active .wp-smush-image-list-inner').addClass("show");
963
+ }
964
+ }
965
+ }
966
+ }
967
 
968
+ /**
969
+ * Check if all the elements in the directory are smushed or not
970
+ *
971
+ * @param parent directory selector
972
+ *
973
+ * @returns {boolean}
974
+ *
975
+ */
976
+ var is_last_element = function(parent) {
977
+ var elements = parent.find('li.wp-smush-image-ele:not(.optimised,.error)');
978
+ if( elements.length <= 0 ) {
979
  return true;
980
+ }
981
+ return false;
982
+ };
983
 
984
+ /**
985
+ * Update directory optimisation progress if the element has a parent
986
+ *
987
+ * @param ele
988
+ *
989
+ */
990
+ var update_dir_progress = function (ele) {
991
+ //Get the parent element
992
+ var parent = ele.parents('li.wp-smush-image-ul');
993
 
994
+ if (!parent.length) {
995
+ return;
996
+ }
997
+ var child = parent.find('ul.wp-smush-image-list-inner li');
998
+
999
+ //Check if first image, Add a loader against directory path
1000
+ var progress_wrap = parent.find('div.wp-smush-dir-progress-wrap');
1001
+
1002
+ //Update the percentage, Check the total number of images inside dir, smushed images count
1003
+ var total = child.length;
1004
+ var smushed = child.filter('.optimised').length;
1005
+ var smush_progress = progress_wrap.find('.wp-smush-dir-progress');
1006
+ if (smushed > 0 && total > 0) {
1007
+ var percent = ( smushed / total ) * 100;
1008
+ percent = precise_round(percent, 1);
1009
+ progress_wrap.find('.smush-percent').html(percent + '%');
1010
+ smush_progress.css({'width': percent + '%'});
1011
+ }
1012
 
1013
+ //Add the class in-progress, to show the respective icon for parent
1014
+ if (0 != $('input[name="wp-smush-continue-ajax"]').val() && !parent.hasClass('in-progress') && smushed != total) {
1015
+ parent.addClass('in-progress').removeClass('partial');
1016
+ //Append a spinner
1017
+ var spinner = $('div.wp-smush-scan-result span.spinner:first').clone();
1018
+ if (spinner) {
1019
+ parent.find('span.wp-smush-li-path').prepend(spinner);
1020
+ }
1021
+ }
1022
 
1023
+ var parent_class = '';
1024
+ //Check if last image, and if all the images are not smushed under the specified directory path, add a generic warning message
1025
+ if (is_last_element(parent)) {
1026
+ if (smushed < total) {
1027
+ var unsmushed = total - smushed;
1028
+ var message = '<div class="wp-smush-dir-notice"><i class="dev-icon wdv-icon wdv-icon-fw wdv-icon-exclamation-sign"></i>' + unsmushed + ' ' + ( 1 == unsmushed ? wp_smush_msgs.unfinished_smush_single : wp_smush_msgs.unfinished_smush ) + '</div>';
1029
+
1030
+ //If the notice is already displayed, remove it
1031
+ var notice = parent.find('div.wp-smush-dir-notice');
1032
+ if( notice.length ) {
1033
+ notice.remove();
1034
+ }
1035
 
1036
+ //Append message to 2nd parent i.e li
1037
+ parent.find('ul.wp-smush-image-list-inner').after(message);
1038
 
1039
+ //Check If all the images are smushed, remove the class in-progress and add the class complete, else add class partial
1040
+ parent_class = 'partial';
1041
 
1042
+ //Remove the Spinner
1043
+ parent.find('span.wp-smush-li-path span.spinner').remove();
1044
+ } else {
1045
+ parent_class = 'complete';
1046
+ smush_progress.removeClass('partial').addClass('complete');
1047
+ }
1048
+ //Remove Spinner
1049
+ parent.find('span.wp-smush-li-path span.spinner').remove();
1050
 
1051
+ //Remove In progress class for the element and add partial/complete class
1052
+ parent.removeClass('in-progress active').addClass(parent_class);
1053
+
1054
+ //Remove active class from parent
1055
+ parent.removeClass('active').find('.wp-smush-image-list-inner').removeClass("show");
1056
  }
 
 
1057
 
1058
+ }
 
1059
 
1060
+ /**
1061
+ * Add choose directory button at the top
1062
+ *
1063
+ */
1064
+ var add_dir_browser_button = function () {
1065
+ //Get the content div length, if less than 1500, Skip
1066
+ if( $('div.wp-smush-scan-result div.content').height() < 1500 || $('div.dir-smush-button-wrap.top').length >= 1 ) {
1067
+ return;
1068
+ }
1069
 
1070
+ var choose_button = $('div.dir-smush-button-wrap').clone();
1071
+ choose_button.addClass('top');
1072
+ $('div.wp-smush-scan-result div.content').prepend(choose_button);
1073
+ };
1074
 
1075
+ var add_smush_button = function() {
1076
+ //Get the content div length, if less than 1500, Skip
1077
+ if( $('div.wp-smush-scan-result div.content').height() < 1500 || $('div.wp-smush-all-button-wrap.top').length >= 1 ) {
1078
+ return;
1079
  }
 
 
1080
 
1081
+ var smush_button = $('div.wp-smush-all-button-wrap.bottom').clone();
1082
+ smush_button.addClass('top').removeClass('bottom');
1083
+ $('div.wp-smush-scan-result div.content').prepend(smush_button);
1084
 
1085
+ };
 
 
1086
 
1087
+ /**
1088
+ * Add smush notice after directory smushing is finished
1089
+ *
1090
+ * @param notice_type
1091
+ * all_done - If all the images were smushed else warning
1092
+ * smush_limit - If Free users exceeded limit
1093
+ *
1094
+ */
1095
+ var add_smush_dir_notice = function ( notice_type ) {
1096
+ //Get the content div length, if less than 1500, Skip
1097
+ if( $('div.wp-smush-scan-result div.content').height() < 1500 || $('div.wp-smush-scan-result div.wp-smush-notice.top').length >= 1 ) {
1098
+ return;
1099
+ }
1100
+ var notice = '';
1101
+ //Clone and append the notice
1102
+ if( 'all_done' == notice_type ) {
1103
+ notice = $('div.wp-smush-notice.wp-smush-dir-all-done').clone();
1104
+ }else if( 'smush_limit' == notice_type ){
1105
+ notice = $('div.wp-smush-notice.wp-smush-dir-limit').clone();
1106
+ }else{
1107
+ notice = $('div.wp-smush-notice.wp-smush-dir-remaining').clone();
1108
+ }
1109
 
1110
+ //Add class top
1111
+ notice.addClass('top');
 
 
 
1112
 
1113
+ //Append the notice
1114
+ $('div.wp-smush-scan-result div.dir-smush-button-wrap').after( notice );
1115
+ };
1116
 
1117
+ var update_smush_progress = function() {
1118
+ var in_progress_path = $('ul.wp-smush-image-list li.in-progress');
1119
+ in_progress_path.removeClass('in-progress active');
1120
+ if( in_progress_path.length > 0 ) {
1121
+ in_progress_path.each( function( index, ele ) {
1122
+ if ($(ele).hasClass('wp-smush-image-ul')) {
1123
+ //Remove Spinner
1124
+ $(ele).find('span.spinner').remove();
1125
+
1126
+ //Check if images are pending
1127
+ var in_progress_ele = $(ele).find('li.wp-smush-image-ele');
1128
+
1129
+ //If there are elements
1130
+ if (in_progress_ele.length > 0) {
1131
+ var optimised = in_progress_ele.filter('.optimised').length;
1132
+ var error = in_progress_ele.filter('.error').length;
1133
+ //if all the elements are optimised
1134
+ if (optimised == in_progress_ele.length) {
1135
+ $( ele ).addClass('complete');
1136
+ } else if (0 < optimised || 0 < error) {
1137
+ //If there are images that needs to be smushed, add the class partial
1138
+ $( ele ).addClass('partial');
1139
+ }
1140
+ }
1141
+
1142
+ }else{
1143
+ //Remove spinner for the element
1144
+ $(ele).find('span.spinner').remove();
1145
+ }
1146
  });
1147
+ }
1148
+ };
1149
+
1150
+ /**
1151
+ * Set pro savings stats if not premium user.
1152
+ *
1153
+ * For non-premium users, show expected avarage savings based
1154
+ * on the free version savings.
1155
+ */
1156
+ var set_pro_savings = function() {
1157
+
1158
+ // Default values.
1159
+ var savings = wp_smushit_data.savings_percent > 0 ? wp_smushit_data.savings_percent : 0;
1160
+ var savings_bytes = wp_smushit_data.savings_bytes > 0 ? wp_smushit_data.savings_bytes : 0;
1161
+ var orig_diff = 2.22058824;
1162
+ if ( savings > 49 ) {
1163
+ var orig_diff = 1.22054412;
1164
+ }
1165
+ //Calculate Pro savings
1166
+ if( savings > 0 ) {
1167
+ savings = orig_diff * savings;
1168
+ savings_bytes = orig_diff * savings_bytes;
1169
+ }
1170
+
1171
+ wp_smushit_data.pro_savings = {
1172
+ 'percent': precise_round(savings, 1),
1173
+ 'savings_bytes': formatBytes(savings_bytes, 1)
1174
+
1175
+ }
1176
+ };
1177
+
1178
+ /**
1179
+ * Adds the stats for the current image to existing stats
1180
+ *
1181
+ * @param image_stats
1182
+ *
1183
+ */
1184
+ var update_localized_stats = function (image_stats, type ) {
1185
+ //Increase the smush count
1186
+ if ('undefined' == typeof wp_smushit_data) {
1187
+ return;
1188
+ }
1189
+
1190
+ //No need to increase attachment count, resize, conversion savings for directory smush
1191
+ if ('media' == type) {
1192
+ wp_smushit_data.count_smushed = parseInt(wp_smushit_data.count_smushed) + 1;
1193
+
1194
+ //Increase smushed image count
1195
+ wp_smushit_data.count_images = parseInt(wp_smushit_data.count_images) + parseInt(image_stats.count);
1196
+
1197
+ //Increase super smush count, if applicable
1198
+ if (image_stats.is_lossy) {
1199
+ wp_smushit_data.count_supersmushed = parseInt(wp_smushit_data.count_supersmushed) + 1;
1200
+ }
1201
+
1202
+ //Add to Resize Savings
1203
+ wp_smushit_data.savings_resize = 'undefined' != typeof image_stats.savings_resize.bytes ? parseInt(wp_smushit_data.savings_resize) + parseInt(image_stats.savings_resize.bytes) : parseInt(wp_smushit_data.savings_resize);
1204
+
1205
+ //Add to Conversion Savings
1206
+ wp_smushit_data.savings_conversion = 'undefined' != typeof image_stats.savings_conversion && 'undefined' != typeof image_stats.savings_conversion.bytes ? parseInt(wp_smushit_data.savings_conversion) + parseInt(image_stats.savings_conversion.bytes ) : parseInt(wp_smushit_data.savings_conversion);
1207
+ } else if( 'directory_smush' == type ) {
1208
+ //Increase smushed image count
1209
+ wp_smushit_data.count_images = parseInt(wp_smushit_data.count_images) + 1;
1210
+ }else if( 'nextgen' == type ) {
1211
+ wp_smushit_data.count_smushed = parseInt(wp_smushit_data.count_smushed) + 1;
1212
+ wp_smushit_data.count_supersmushed = parseInt(wp_smushit_data.count_supersmushed) + 1;
1213
+
1214
+ //Increase smushed image count
1215
+ wp_smushit_data.count_images = parseInt(wp_smushit_data.count_images) + parseInt(image_stats.count);
1216
+ }
1217
+
1218
+ //If we have savings
1219
+ if (image_stats.size_before > image_stats.size_after) {
1220
+ //Update savings
1221
+ wp_smushit_data.size_before = 'undefined' != typeof image_stats.size_before ? parseInt(wp_smushit_data.size_before) + parseInt(image_stats.size_before) : parseInt(wp_smushit_data.size_before);
1222
+ wp_smushit_data.size_after = 'undefined' != typeof image_stats.size_after ? parseInt(wp_smushit_data.size_after) + parseInt(image_stats.size_after) : parseInt(wp_smushit_data.size_after);
1223
+ }
1224
+ //Add stats for resizing
1225
+ if( 'undefined' != typeof image_stats.savings_resize ) {
1226
+ //Update savings
1227
+ wp_smushit_data.size_before = 'undefined' != typeof image_stats.savings_resize.size_before ? parseInt(wp_smushit_data.size_before) + parseInt(image_stats.savings_resize.size_before) : parseInt(wp_smushit_data.size_before);
1228
+ wp_smushit_data.size_after = 'undefined' != typeof image_stats.savings_resize.size_after ? parseInt(wp_smushit_data.size_after) + parseInt(image_stats.savings_resize.size_after) : parseInt(wp_smushit_data.size_after);
1229
+ }
1230
+ //Add stats for Conversion
1231
+ if( 'undefined' != typeof image_stats.savings_conversion ) {
1232
+ //Update savings
1233
+ wp_smushit_data.size_before = 'undefined' != typeof image_stats.savings_conversion.size_before ? parseInt(wp_smushit_data.size_before) + parseInt(image_stats.savings_conversion.size_before) : parseInt(wp_smushit_data.size_before);
1234
+ wp_smushit_data.size_after = 'undefined' != typeof image_stats.savings_conversion.size_after ? parseInt(wp_smushit_data.size_after) + parseInt(image_stats.savings_conversion.size_after) : parseInt(wp_smushit_data.size_after);
1235
+ }
1236
+ }
1237
+
1238
+ /**
1239
+ * Update all stats sections based on the response.
1240
+ *
1241
+ * @param _res Ajax response data.
1242
+ */
1243
+ var update_stats = function () {
1244
+
1245
+ // Update Progress on Circle.
1246
+ update_dashoffset();
1247
+
1248
+ //Calculate updated savings in bytes
1249
+ wp_smushit_data.savings_bytes = parseInt(wp_smushit_data.size_before) - parseInt(wp_smushit_data.size_after);
1250
+
1251
+ $('.wp-smush-savings .wp-smush-stats-human').html(formatBytes(wp_smushit_data.savings_bytes, 1));
1252
+
1253
+ //Update the savings percent
1254
+ wp_smushit_data.savings_percent = precise_round(( parseInt(wp_smushit_data.savings_bytes) / parseInt(wp_smushit_data.size_before) ) * 100, 1);
1255
+ $('.wp-smush-savings .wp-smush-stats-percent').html(wp_smushit_data.savings_percent);
1256
+
1257
+ //Update Savings in share message
1258
+ $('span.smush-share-savings').html( formatBytes(wp_smushit_data.savings_bytes, 1) );
1259
+
1260
+ //Update Smush percent
1261
+ wp_smushit_data.smush_percent = precise_round(( parseInt(wp_smushit_data.count_smushed) / parseInt(wp_smushit_data.count_total) ) * 100, 1);
1262
+ $('span.wp-smush-images-percent').html(wp_smushit_data.smush_percent);
1263
+
1264
+ //Update Image count
1265
+ $('span.wp-smush-total-optimised').html(wp_smushit_data.count_images);
1266
+
1267
+ //Update image count in share message
1268
+ $('span.smush-share-image-count').html( wp_smushit_data.count_images );
1269
+
1270
+ //Update image count in share message
1271
+
1272
+ //Update supersmushed image count
1273
+ if ($('.super-smush-attachments .smushed-count').length && 'undefined' != typeof wp_smushit_data.count_supersmushed) {
1274
+ $('.super-smush-attachments .smushed-count').html(wp_smushit_data.count_supersmushed);
1275
+ }
1276
+
1277
+ //Update Conversion Savings
1278
+ var smush_conversion_savings = $('.smush-conversion-savings');
1279
+ if (smush_conversion_savings.length > 0 && 'undefined' != typeof ( wp_smushit_data.savings_conversion ) && wp_smushit_data.savings_conversion != '') {
1280
+ var conversion_savings = smush_conversion_savings.find('.wp-smush-stats');
1281
+ if (conversion_savings.length > 0) {
1282
+ conversion_savings.html(formatBytes(wp_smushit_data.savings_conversion, 1));
1283
+ }
1284
+ }
1285
+
1286
+ //Update Resize Savings
1287
+ var smush_resize_savings = $('.smush-resize-savings');
1288
+ if (smush_resize_savings.length > 0 && 'undefined' != typeof ( wp_smushit_data.savings_resize ) && wp_smushit_data.savings_resize != '') {
1289
+ // Get the resize savings in number.
1290
+ var savings_value = parseInt(wp_smushit_data.savings_resize );
1291
+ var resize_savings = smush_resize_savings.find('.wp-smush-stats');
1292
+ // Replace only if value is grater than 0.
1293
+ if (savings_value > 0 && resize_savings.length > 0) {
1294
+ resize_savings.html(formatBytes(wp_smushit_data.savings_resize, 1));
1295
+ }
1296
+ }
1297
+
1298
+ //Update pro Savings
1299
+ set_pro_savings();
1300
+
1301
+ // Updating pro savings stats.
1302
+ if ('undefined' != typeof (wp_smushit_data.pro_savings)) {
1303
+ // Make pro savings div visible if hidden.
1304
+ $('#smush-avg-pro-savings').show();
1305
+ // Pro stats section.
1306
+ var smush_pro_savings = $('.smush-avg-pro-savings');
1307
+ if (smush_pro_savings.length > 0) {
1308
+ var pro_savings_percent = smush_pro_savings.find('.wp-smush-stats-percent');
1309
+ var pro_savings_bytes = smush_pro_savings.find('.wp-smush-stats-human');
1310
+ if (pro_savings_percent.length > 0 && 'undefined' != typeof (wp_smushit_data.pro_savings.percent) && wp_smushit_data.pro_savings.percent != '') {
1311
+ pro_savings_percent.html(wp_smushit_data.pro_savings.percent);
1312
+ }
1313
+ if (pro_savings_bytes.length > 0 && 'undefined' != typeof (wp_smushit_data.pro_savings.savings_bytes) && wp_smushit_data.pro_savings.savings_bytes != '') {
1314
+ pro_savings_bytes.html(wp_smushit_data.pro_savings.savings_bytes);
1315
+ }
1316
+ }
1317
+ }
1318
+ };
1319
+
1320
+ /**
1321
+ * Update the progress and show notice when smush completes
1322
+ */
1323
+ var directory_smush_finished = function( notice_type ) {
1324
+ //If there are no images left
1325
+ $('div.wp-smush-all-button-wrap span.spinner').remove();
1326
+ $('button.wp-smush-pause').hide().attr('disabled', 'disabled');
1327
+
1328
+ //Hide Bulk Smush button if smush was stopped for error or finished
1329
+ if ('' == notice_type) {
1330
+ $('button.wp-smush-start').parent().hide();
1331
+ } else {
1332
+ $('button.wp-smush-start').show().removeAttr('disabled');
1333
+ }
1334
+
1335
+ //Enable Choose directory button
1336
+ $('button.wp-smush-browse').show().removeAttr('disabled', 'disabled');
1337
+
1338
+ //Clone Choose Directory Button and add at the top
1339
+ add_dir_browser_button();
1340
+
1341
+ //Clone and add Smush button
1342
+ add_smush_button();
1343
+
1344
+ if( '' == notice_type ) {
1345
+ //Get the Total and Optimised image count
1346
+ var image_ele = $('li.wp-smush-image-ele')
1347
+ var total = image_ele.length;
1348
+ var remaning = image_ele.filter(':not(.optimised)').length;
1349
+ var smushed = total - remaning;
1350
+ if (remaning > 0) {
1351
+
1352
+ //Append the count
1353
+ $('span.wp-smush-dir-remaining').html(remaning);
1354
+ $('span.wp-smush-dir-total').html(total);
1355
+ $('span.wp-smush-dir-smushed').html(smushed);
1356
+
1357
+ //Show remaining image notice
1358
+ $('.wp-smush-notice.wp-smush-dir-remaining').show();
1359
+
1360
+ //Show notice on top if required
1361
+ add_smush_dir_notice();
1362
+ } else {
1363
+ // Hide images list.
1364
+ $('ul.wp-smush-image-list').hide();
1365
+ $('div.dir-smush-button-wrap.top').hide();
1366
+
1367
+ //Show All done notice
1368
+ $('.wp-smush-notice.wp-smush-dir-all-done').show();
1369
+
1370
+ //Show notice on top if required
1371
+ add_smush_dir_notice('all_done');
1372
+ }
1373
+ }else{
1374
+ //Show Bulk Limit Notice
1375
+ $('.wp-smush-notice.wp-smush-dir-limit').show();
1376
+ //Show notice on top if required
1377
+ add_smush_dir_notice('smush_limit');
1378
+ }
1379
+
1380
+ //Update Directory progress and remove any loaders still in there
1381
+ update_smush_progress();
1382
+
1383
+ }
1384
+
1385
+ /**
1386
+ * Start Optimising all the images listed in last directory scan
1387
+ *
1388
+ */
1389
+ var smush_all = function () {
1390
+
1391
+ var spinner = $('div.smush-page-wrap span.spinner:first').clone();
1392
+ spinner.addClass('is-active');
1393
+ var unprocessed_child = jQuery('ul.wp-smush-image-list li.wp-smush-image-ele:not(".optimised, .processed")');
1394
+ //Update the Optimising status for the image
1395
+ var first_child = unprocessed_child.first();
1396
+
1397
+ var parent = first_child.parents('li.wp-smush-image-ul');
1398
+
1399
+ //Check if the selected element is under expandable li
1400
+ if (parent.length == 1) {
1401
+ parent.addClass('active in-progress').removeClass('partial');
1402
+ parent.find('.wp-smush-image-list-inner').addClass('show');
1403
+ if (!parent.find('span.wp-smush-li-path span.spinner').length) {
1404
+ parent.find('span.wp-smush-li-path').prepend(spinner.clone());
1405
+ }
1406
+ }
1407
+
1408
+ //Append and show spinner
1409
+ first_child.addClass('in-progress processed');
1410
+ if (!first_child.find('spam.spinner').length) {
1411
+ first_child.prepend(spinner.clone());
1412
+ }
1413
+
1414
+ //If all the elements are optimised, No need to send ajax request
1415
+ if( first_child.length == 0 ) {
1416
+ directory_smush_finished('');
1417
+ return;
1418
+ }
1419
+
1420
+ /** Ajax Request to optimise directory images */
1421
+ var param = {
1422
+ action: 'optimise',
1423
+ image_id: first_child.attr('id'),
1424
+ get_stats: unprocessed_child.length > 1 ? 0: 1,
1425
+ nonce: $('#wp-smush-all').val()
1426
  };
1427
+
1428
+ //Send Ajax request
1429
+ $.get(ajaxurl, param, function (res) {
1430
+
1431
+ //Check, if limit is exceeded for free version
1432
+ if (typeof res.data !== "undefined" && res.data.error == 'dir_smush_limit_exceeded') {
1433
+ //Show error, Bulk Smush limit exceeded
1434
+ directory_smush_finished( 'wp-smush-dir-limit' );
1435
+ return;
1436
+ }
1437
+
1438
+ //append stats, remove loader, add loader to next image, loop
1439
+ var data = 'undefined' != typeof ( res.data ) ? res.data : '';
1440
+
1441
+ //If image element is there
1442
+ if ('undefined' != typeof(data.image)) {
1443
+ //Mark Optimised
1444
+ var ele = jQuery(document.getElementById(data.image.id));
1445
+
1446
+ //Remove the spinner
1447
+ ele.find('span.spinner').remove();
1448
+ ele.removeClass('in-progress');
1449
+
1450
+ if (res.success) {
1451
+
1452
+ ele.addClass('optimised');
1453
+
1454
+ //Show the Optimisation status
1455
+ ele.find('span.wp-smush-image-ele-status').show();
1456
+
1457
+ //Update Directory progress
1458
+ update_dir_progress(ele);
1459
+
1460
+ // Update dir savings stats.
1461
+ if ('undefined' != typeof (res.data.total.percent) && 'undefined' != typeof (res.data.total.human) && 'undefined' != typeof (res.data.total.bytes)) {
1462
+ // Directory stats section.
1463
+ var smush_dir_savings = $('.smush-dir-savings');
1464
+ if (smush_dir_savings.length > 0 && res.data.total.bytes > 0) {
1465
+ // Make separator visible if hidden.
1466
+ smush_dir_savings.find('.wp-smush-stats-sep').show();
1467
+ var dir_savings_percent = smush_dir_savings.find('.wp-smush-stats-percent');
1468
+ var dir_savings_human = smush_dir_savings.find('.wp-smush-stats-human');
1469
+ if (dir_savings_percent.length > 0) {
1470
+ dir_savings_percent.html(res.data.total.percent + '%');
1471
+ }
1472
+ if (dir_savings_human.length > 0) {
1473
+ dir_savings_human.html(res.data.total.human);
1474
+ }
1475
+ }
1476
+ }
1477
+ } else {
1478
+ //If there was an error optimising the image
1479
+ ele.addClass('error');
1480
+ //Update Directory progress
1481
+ update_dir_progress(ele);
1482
+ }
1483
+
1484
+
1485
+ //@todo: Fixed stats UI
1486
+ if ('undefined' != typeof res.data.total) {
1487
+ //Update localized stats, Need to modify function to not increase count, and just update image count, and savings
1488
+ update_localized_stats( res.data.image, 'directory_smush' );
1489
+ // Update stats.
1490
+ update_stats();
1491
+ }
1492
+ }
1493
+
1494
+ //If user haven't paused the Smushing
1495
+ if ( 1 == $('input[name="wp-smush-continue-ajax"]').val() ) {
1496
+ //Loop
1497
+ smush_all(false);
1498
+ } else {
1499
+ //Reset the Ajax flag
1500
+ $('input.wp-smush-continue-ajax').val(1);
1501
+ }
1502
+
1503
+ });
1504
+ }
1505
+
1506
+ //Scroll the element to top of the page
1507
+ var goToByScroll = function (selector) {
1508
+ // Scroll
1509
+ $('html,body').animate({
1510
+ scrollTop: selector.offset().top
1511
+ },
1512
+ 'slow');
1513
+ };
1514
+
1515
+ var disable_buttons = function (self) {
1516
+ self.attr('disabled', 'disabled');
1517
+ $('.wp-smush-browse').attr('disabled', 'disabled');
1518
+ };
1519
+
1520
+ var update_cummulative_stats = function (stats) {
1521
+ //Update Directory Smush Stats
1522
+ if ('undefined' != typeof ( stats.dir_smush )) {
1523
+ var stats_human = $('div.smush-dir-savings span.wp-smush-stats span.wp-smush-stats-human');
1524
+ var stats_percent = $('div.smush-dir-savings span.wp-smush-stats span.wp-smush-stats-percent');
1525
+
1526
+ // Do not replace if 0 savings.
1527
+ if (stats.dir_smush.bytes > 0) {
1528
+ // Show size and percentage separator.
1529
+ $('div.smush-dir-savings span.wp-smush-stats span.wp-smush-stats-sep').show();
1530
+ //Update Savings in bytes
1531
+ if (stats_human.length > 0) {
1532
+ stats_human.html(stats.dir_smush.human);
1533
+ } else {
1534
+ var span = '<span class="wp-smush-stats-human">' + stats.dir_smush.bytes + '</span>';
1535
+ }
1536
+
1537
+ //Update Optimisation percentage
1538
+ if (stats_percent.length > 0) {
1539
+ stats_percent.html(stats.dir_smush.percent + '%');
1540
+ } else {
1541
+ var span = '<span class="wp-smush-stats-percent">' + stats.dir_smush.percent + '%' + '</span>';
1542
+ }
1543
+ }
1544
+ }
1545
+
1546
+ //Update Combined stats
1547
+ if ('undefined' != typeof ( stats.combined_stats ) && stats.combined_stats.length > 0) {
1548
+ var c_stats = stats.combined_stats;
1549
+
1550
+ var smush_percent = ( c_stats.smushed / c_stats.total_count ) * 100;
1551
+ smush_percent = precise_round( smush_percent, 1 );
1552
+
1553
+ //Update Circle Progress
1554
+ if (c_stats.dash_offset) {
1555
+ $('circle.wp-smush-svg-circle-progress').css({'stroke-dashoffset': c_stats.dash_offset});
1556
+ }
1557
+ //Smushed Percent
1558
+ if (smush_percent) {
1559
+ $('div.wp-smush-count-total span.wp-smush-images-percent').html(smush_percent);
1560
+ }
1561
+ //Update Total Attachment Count
1562
+ if (c_stats.total_count) {
1563
+ $('div.wp-smush-count-total div.wp-smush-smush-stats-wrapper span:last-child').html(c_stats.total_count);
1564
+ }
1565
+ //Update Savings and Percent
1566
+ if (c_stats.savings) {
1567
+ $('div.wp-smush-savings span.wp-smush-stats-human').html(c_stats.savings);
1568
+ }
1569
+ if (c_stats.percent) {
1570
+ $('div.wp-smush-savings span.wp-smush-stats-percent').html(c_stats.percent);
1571
+ }
1572
+ }
1573
+ };
1574
+
1575
+ /**
1576
+ * Handle the Smush Stats link click
1577
+ */
1578
+ $('body').on('click', 'a.smush-stats-details', function (e) {
1579
+
1580
+ //If disabled
1581
+ if ('disabled' == $(this).attr('disabled')) {
1582
+ return false;
1583
+ }
1584
+
1585
+ // prevent the default action
1586
+ e.preventDefault();
1587
+ //Replace the `+` with a `-`
1588
+ var slide_symbol = $(this).find('.stats-toggle');
1589
+ $(this).parents().eq(1).find('.smush-stats-wrapper').slideToggle();
1590
+ slide_symbol.text(slide_symbol.text() == '+' ? '-' : '+');
1591
+
1592
+
1593
+ });
1594
+
1595
+ /** Handle smush button click **/
1596
+ $('body').on('click', '.wp-smush-send:not(.wp-smush-resmush)', function (e) {
1597
+
1598
+ // prevent the default action
1599
+ e.preventDefault();
1600
+ new WP_Smush.Smush($(this), false);
1601
+ });
1602
+
1603
+ /** Handle NextGen Gallery smush button click **/
1604
+ $('body').on('click', '.wp-smush-nextgen-send', function (e) {
1605
+
1606
+ // prevent the default action
1607
+ e.preventDefault();
1608
+ new WP_Smush.Smush($(this), false, 'nextgen');
1609
+ });
1610
+
1611
+ /** Handle NextGen Gallery Bulk smush button click **/
1612
+ $('body').on('click', '.wp-smush-nextgen-bulk', function (e) {
1613
+
1614
+ // prevent the default action
1615
+ e.preventDefault();
1616
+
1617
+ //Check for ids, if there is none (Unsmushed or lossless), don't call smush function
1618
+ if (typeof wp_smushit_data == 'undefined' ||
1619
+ ( wp_smushit_data.unsmushed.length == 0 && wp_smushit_data.resmush.length == 0 )
1620
+ ) {
1621
+
1622
+ return false;
1623
+
1624
+ }
1625
+
1626
+ jQuery('.wp-smush-button, .wp-smush-scan').attr('disabled', 'disabled');
1627
+ $(".wp-smush-notice.wp-smush-remaining").hide();
1628
+ new WP_Smush.Smush($(this), true, 'nextgen');
1629
+
1630
+ });
1631
+
1632
+ /** Restore: Media Library **/
1633
+ $('body').on('click', '.wp-smush-action.wp-smush-restore', function (e) {
1634
+ var current_button = $(this);
1635
+ var smush_action = 'smush_restore_image';
1636
+ process_smush_action(e, current_button, smush_action, 'restore');
1637
+ });
1638
+
1639
+ /** Resmush: Media Library **/
1640
+ $('body').on('click', '.wp-smush-action.wp-smush-resmush', function (e) {
1641
+ var current_button = $(this);
1642
+ var smush_action = 'smush_resmush_image';
1643
+ process_smush_action(e, current_button, smush_action, 'smushing');
1644
+ });
1645
+
1646
+ /** Restore: NextGen Gallery **/
1647
+ $('body').on('click', '.wp-smush-action.wp-smush-nextgen-restore', function (e) {
1648
+ var current_button = $(this);
1649
+ var smush_action = 'smush_restore_nextgen_image';
1650
+ process_smush_action(e, current_button, smush_action, 'restore');
1651
+ });
1652
+
1653
+ /** Resmush: NextGen Gallery **/
1654
+ $('body').on('click', '.wp-smush-action.wp-smush-nextgen-resmush', function (e) {
1655
+ var current_button = $(this);
1656
+ var smush_action = 'smush_resmush_nextgen_image';
1657
+ process_smush_action(e, current_button, smush_action, 'smushing');
1658
+ });
1659
+
1660
+ //Scan For resmushing images
1661
+ $('body').on('click', '.wp-smush-scan', function (e) {
1662
+
1663
+ e.preventDefault();
1664
+
1665
+ //Run the Re-check
1666
+ run_re_check($(this), false);
1667
+
1668
+ });
1669
+
1670
+ //Dismiss Welcome notice
1671
+ $('#wp-smush-welcome-box .smush-dismiss-welcome').on('click', function (e) {
1672
+ e.preventDefault();
1673
+ var $el = $(this).parents().eq(1);
1674
+ remove_element($el);
1675
+
1676
+ //Send a ajax request to save the dismissed notice option
1677
+ var param = {
1678
+ action: 'dismiss_welcome_notice'
1679
+ };
1680
+ $.post(ajaxurl, param);
1681
+ });
1682
+
1683
+ //Remove Notice
1684
+ $('body').on('click', '.wp-smush-notice .dev-icon-cross', function (e) {
1685
+ e.preventDefault();
1686
+ var $el = $(this).parent();
1687
+ remove_element($el);
1688
+ });
1689
+
1690
+ //On Click Update Settings. Check for change in settings
1691
+ $('input#wp-smush-save-settings').on('click', function (e) {
1692
+ e.preventDefault();
1693
+
1694
+ var setting_type = '';
1695
+ var setting_input = $('input[name="setting-type"]');
1696
+ //Check if setting type is set in the form
1697
+ if (setting_input.length > 0) {
1698
+ setting_type = setting_input.val();
1699
+ }
1700
+
1701
+ //Show the spinner
1702
+ var self = $(this);
1703
+ self.parent().find('span.spinner').addClass('is-active');
1704
+
1705
+ //Save settings if in network admin
1706
+ if ('' != setting_type && 'network' == setting_type) {
1707
+ //Ajax param
1708
+ var param = {
1709
+ action: 'save_settings',
1710
+ nonce: $('#wp_smush_options_nonce').val()
1711
+ };
1712
+
1713
+ param = jQuery.param(param) + '&' + jQuery('form#wp-smush-settings-form').serialize();
1714
+
1715
+ //Send ajax, Update Settings, And Check For resmush
1716
+ jQuery.post(ajaxurl, param).done(function () {
1717
+ jQuery('form#wp-smush-settings-form').submit();
1718
+ return true;
1719
+ });
1720
+ } else {
1721
+
1722
+ //Check for all the settings, and scan for resmush
1723
+ var wrapper_div = self.parents().eq(1);
1724
+
1725
+ //Get all the main settings
1726
+ var keep_exif = document.getElementById("wp-smush-keep_exif");
1727
+ var super_smush = document.getElementById("wp-smush-lossy");
1728
+ var smush_original = document.getElementById("wp-smush-original");
1729
+ var resize_images = document.getElementById("wp-smush-resize");
1730
+ var smush_pngjpg = document.getElementById("wp-smush-png_to_jpg");
1731
+
1732
+ var update_button_txt = true;
1733
+
1734
+ $('.wp-smush-hex-notice').hide();
1735
+
1736
+ //If Preserve Exif is Checked, and all other settings are off, just save the settings
1737
+ if (keep_exif.checked && !super_smush.checked && !smush_original.checked && !resize_images.checked && !smush_pngjpg.checked) {
1738
+ update_button_txt = false;
1739
+ }
1740
+
1741
+ //Update text
1742
+ self.attr('disabled', 'disabled').addClass('button-grey');
1743
+
1744
+ if (update_button_txt) {
1745
+ self.val(wp_smush_msgs.checking)
1746
+ }
1747
+
1748
+ //Check if type is set in data attributes
1749
+ var scan_type = self.data('type');
1750
+ scan_type = 'undefined' == typeof scan_type ? 'media' : scan_type;
1751
+
1752
+ //Ajax param
1753
+ var param = {
1754
+ action: 'scan_for_resmush',
1755
+ wp_smush_options_nonce: jQuery('#wp_smush_options_nonce').val(),
1756
+ scan_type: scan_type
1757
+ };
1758
+
1759
+ param = jQuery.param(param) + '&' + jQuery('form#wp-smush-settings-form').serialize();
1760
+
1761
+ //Send ajax, Update Settings, And Check For resmush
1762
+ jQuery.post(ajaxurl, param).done(function () {
1763
+ jQuery('form#wp-smush-settings-form').submit();
1764
+ return true;
1765
+ });
1766
+ }
1767
+ });
1768
+
1769
+ //On Resmush click
1770
+ $('body').on('click', '.wp-smush-skip-resmush', function (e) {
1771
+ e.preventDefault();
1772
+ var self = jQuery(this);
1773
+ var container = self.parents().eq(1);
1774
+
1775
+ //Remove Parent div
1776
+ var $el = self.parent();
1777
+ remove_element($el);
1778
+
1779
+ //Remove Settings Notice
1780
+ $('.wp-smush-notice.wp-smush-settings-updated').remove();
1781
+
1782
+ //Set button attribute to skip re-smush ids
1783
+ container.find('.wp-smush-all').attr('data-smush', 'skip_resmush');
1784
+
1785
+ //Update Smushed count
1786
+ wp_smushit_data.count_smushed = parseInt( wp_smushit_data.count_smushed ) + wp_smushit_data.resmush.length;
1787
+ wp_smushit_data.count_supersmushed = parseInt( wp_smushit_data.count_supersmushed ) + wp_smushit_data.resmush.length;
1788
+
1789
+ //Update Stats
1790
+ if (wp_smushit_data.count_smushed == wp_smushit_data.count_total) {
1791
+
1792
+ //Show all done notice
1793
+ $('.wp-smush-notice.wp-smush-all-done').show();
1794
+
1795
+ //Hide Smush button
1796
+ $('.wp-smush-bulk-wrapper ').hide()
1797
+
1798
+ }
1799
+ //Remove Re-Smush Notice
1800
+ $('.wp-smush-resmush-notice').remove();
1801
+
1802
+ var type = $('.wp-smush-scan').data('type');
1803
+ type = 'undefined' == typeof type ? 'media' : type;
1804
+
1805
+ var smushed_count = 'undefined' != typeof wp_smushit_data.count_smushed ? wp_smushit_data.count_smushed : 0
1806
+
1807
+ var smush_percent = ( smushed_count / wp_smushit_data.count_total ) * 100;
1808
+ smush_percent = precise_round( smush_percent, 1 );
1809
+
1810
+ $('.wp-smush-images-percent').html(smush_percent);
1811
+
1812
+ //Update the Progress Bar Width
1813
+ // get the progress bar
1814
+ var $progress_bar = jQuery('.bulk-smush-wrapper .wp-smush-progress-inner');
1815
+ if ($progress_bar.length < 1) {
1816
+ return;
1817
+ }
1818
+
1819
+ // increase progress
1820
+ $progress_bar.css('width', smush_percent + '%');
1821
+
1822
+ //Show the default bulk smush notice
1823
+ $('.wp-smush-bulk-wrapper .wp-smush-notice').show();
1824
+
1825
+ var params = {
1826
+ action: 'delete_resmush_list',
1827
+ type: type
1828
+ }
1829
+ //Delete resmush list, @todo: update stats from the ajax response
1830
+ $.post(ajaxurl, params, function (res) {
1831
+ //Remove the whole li element on success
1832
+ if (res.success && 'undefined' != typeof res.data.stats ) {
1833
+ var stats = res.data.stats;
1834
+ //Update wp_smushit_data ( Smushed count, Smushed Percent, Image count, Super smush count, resize savings, conversion savings )
1835
+ if ('undefinied' != typeof wp_smushit_data) {
1836
+ wp_smushit_data.count_images = 'undefined' != typeof stats.count_images ? parseInt(wp_smushit_data.count_images) + stats.count_images : wp_smushit_data.count_images;
1837
+ wp_smushit_data.size_before = 'undefined' != typeof stats.size_before ? parseInt(wp_smushit_data.size_before) + stats.size_before : wp_smushit_data.size_before;
1838
+ wp_smushit_data.size_after = 'undefined' != typeof stats.size_after ? parseInt(wp_smushit_data.size_after) + stats.size_after : wp_smushit_data.size_after;
1839
+ wp_smushit_data.savings_resize = 'undefined' != typeof stats.savings_resize ? parseInt(wp_smushit_data.savings_resize) + stats.savings_resize : wp_smushit_data.savings_resize;
1840
+ wp_smushit_data.savings_conversion = 'undefined' != typeof stats.savings_conversion ? parseInt(wp_smushit_data.savings_conversion) + stats.savings_conversion : wp_smushit_data.savings_conversion;
1841
+ }
1842
+ update_stats();
1843
+ }
1844
+ });
1845
+
1846
+ });
1847
+
1848
+ //Enable Super Smush
1849
+ $('button.wp-smush-lossy-enable').on('click', function (e) {
1850
+ e.preventDefault();
1851
+
1852
+ //Enable Super Smush
1853
+ $('#wp-smush-lossy').prop('checked', true);
1854
+ //Induce Setting button save click
1855
+ $('#wp-smush-save-settings').click();
1856
+ });
1857
+
1858
+ //Enable Resize
1859
+ $('.wp-smush-resize-enable').on('click', function (e) {
1860
+ e.preventDefault();
1861
+
1862
+ //Enable Super Smush
1863
+ $('#wp-smush-resize').prop('checked', true);
1864
+ //Induce Setting button save click
1865
+ $('#wp-smush-save-settings').click();
1866
+ });
1867
+
1868
+ //Trigger Bulk
1869
+ $('body').on('click', '.wp-smush-trigger-bulk', function (e) {
1870
+ e.preventDefault();
1871
+ //Induce Setting button save click
1872
+ $('button.wp-smush-all').click();
1873
+
1874
+ });
1875
+
1876
+ //Allow the checkboxes to be Keyboard Accessible
1877
+ $('.wp-smush-setting-row .toggle-checkbox').focus(function () {
1878
+ //If Space is pressed
1879
+ $(this).keypress(function (e) {
1880
+ if (e.keyCode == 32) {
1881
+ e.preventDefault();
1882
+ $(this).find('.toggle-checkbox').click();
1883
+ }
1884
+ });
1885
+ });
1886
+
1887
+ //Re-Validate Resize Width And Height
1888
+ $('.wp-smush-resize-input').blur(function () {
1889
+
1890
+ var self = $(this);
1891
+
1892
+ var wrapper_div = self.parents().eq(2);
1893
+
1894
+ //Initiate the check
1895
+ validate_resize_settings(wrapper_div, false, false); // run the validation
1896
+
1897
+ });
1898
+
1899
+ //Handle Resize Checkbox toggle, to show/hide width, height settings
1900
+ $('#wp-smush-resize').click(function () {
1901
+ var self = $(this);
1902
+ var settings_wrap = $('.wp-smush-resize-settings-wrap');
1903
+
1904
+ if (self.is(':checked')) {
1905
+ settings_wrap.show();
1906
+ } else {
1907
+ settings_wrap.hide();
1908
+ }
1909
+ });
1910
+
1911
+ //Handle PNG to JPG Checkbox toggle, to show/hide Transparent image conversion settings
1912
+ $('#wp-smush-png_to_jpg').click(function () {
1913
+ var self = $(this);
1914
+ var settings_wrap = $('.wp-smush-png_to_jpg-wrap');
1915
+
1916
+ if (self.is(':checked')) {
1917
+ settings_wrap.show();
1918
+ } else {
1919
+ settings_wrap.hide();
1920
+ }
1921
+ });
1922
+
1923
+ //Handle, Change event in Enable Networkwide settings
1924
+ $('#wp-smush-networkwide').on('click', function (e) {
1925
+ if ($(this).is(':checked')) {
1926
+ $('.network-settings-wrapper').show();
1927
+ } else {
1928
+ $('.network-settings-wrapper').hide();
1929
+ }
1930
+ });
1931
+
1932
+ //Handle Twitter Share
1933
+ $('#wp-smush-twitter-share').on('click', function (e) {
1934
+ e.preventDefault();
1935
+ var width = 550,
1936
+ height = 420,
1937
+ left = ($(window).width() - width) / 2,
1938
+ top = ($(window).height() - height) / 2,
1939
+ url = this.href,
1940
+ opts = 'status=1' +
1941
+ ',width=' + width +
1942
+ ',height=' + height +
1943
+ ',top=' + top +
1944
+ ',left=' + left;
1945
+
1946
+ window.open(url, 'twitter', opts);
1947
+
1948
+ return false;
1949
+ });
1950
+
1951
+ //Handle Facebook Share
1952
+ $('#wp-smush-facebook-share').on('click', function (e) {
1953
+ e.preventDefault();
1954
+ var width = 550,
1955
+ height = 420,
1956
+ left = ($(window).width() - width) / 2,
1957
+ top = ($(window).height() - height) / 2,
1958
+ url = this.href,
1959
+ opts = 'status=1' +
1960
+ ',width=' + width +
1961
+ ',height=' + height +
1962
+ ',top=' + top +
1963
+ ',left=' + left;
1964
+
1965
+ window.open(url, 'facebook', opts);
1966
+
1967
+ return false;
1968
+ });
1969
+
1970
+ //Adjust background image size if required
1971
+ if ($('.wp-smush-pro-for-free').length) {
1972
+ //On Page load
1973
+ resize_width();
1974
+ //Adjust background image
1975
+ $(window).resize(function () {
1976
+ resize_width();
1977
+ });
1978
+ }
1979
+ //Handle Re-check button functionality
1980
+ $("#wp-smush-revalidate-member").on('click', function (e) {
1981
+ e.preventDefault();
1982
+ //Ajax Params
1983
+ var params = {
1984
+ action: 'smush_show_warning',
1985
+ };
1986
+ var link = $(this);
1987
+ var parent = link.parents().eq(1);
1988
+ parent.addClass('loading-notice');
1989
+ $.get(ajaxurl, params, function (r) {
1990
+ //remove the warning
1991
+ parent.removeClass('loading-notice').addClass("loaded-notice");
1992
+ if (0 == r) {
1993
+ parent.attr('data-message', wp_smush_msgs.membership_valid);
1994
+ remove_element(parent, 1000);
1995
+ } else {
1996
+ parent.attr('data-message', wp_smush_msgs.membership_invalid);
1997
+ setTimeout(function remove_loader() {
1998
+ parent.removeClass('loaded-notice');
1999
+ }, 1000)
2000
+ }
2001
+ });
2002
+ });
2003
+
2004
+ //Initiate Re-check if the variable is set
2005
+ if ('undefined' != typeof (wp_smush_run_re_check) && 1 == wp_smush_run_re_check && $('.wp-smush-scan').length > 0) {
2006
+ //Run the Re-check
2007
+ run_re_check($('.wp-smush-scan'), false);
2008
+ }
2009
+
2010
+ //WP Smush all : Scan Images
2011
+ $('div.row').on('click', 'button.wp-smush-browse', function (e) {
2012
+
2013
+ e.preventDefault();
2014
+
2015
+ //Hide all the notices
2016
+ $('div.wp-smush-scan-result div.wp-smush-notice').hide();
2017
+
2018
+ //If disabled, do not process
2019
+ if ($(this).attr('disabled')) {
2020
+ return;
2021
+ } else {
2022
+ //Disable Buttons
2023
+ $(this).attr('disabled', 'disabled');
2024
+ $('button.wp-smush-resume').attr('disabled', 'disabled');
2025
+ $('div.dir-smush-button-wrap span.spinner').addClass('is-active');
2026
+
2027
+ }
2028
+
2029
+ //Remove Notice
2030
+ $('div.wp-smush-info').remove();
2031
+
2032
+ //Shows the directories available
2033
+ $('.wp-smush-list-dialog').show();
2034
+
2035
+ //Display the loader
2036
+ $('button.dir-smush-button-wrap span.spinner').addClass('is-active');
2037
+
2038
+ $(".wp-smush-list-dialog .content").fileTree({
2039
+ script: getDirectoryList,
2040
+ //folderEvent: 'dblclick',
2041
+ multiFolder: false
2042
+ //onlyFolders: true
2043
+ });
2044
+
2045
+ });
2046
+
2047
+ //WP Smush all: Close button functionality
2048
+ $('.wp-smush-list-dialog').on('click', '.close', function (e) {
2049
+ e.preventDefault();
2050
+ close_dialog();
2051
+ });
2052
+
2053
+ //Image Directories: On Select button click
2054
+ $('.wp-smush-select-dir').on('click', function (e) {
2055
+ e.preventDefault();
2056
+
2057
+ //If disabled, do not process
2058
+ if ($(this).attr('disabled')) {
2059
+ return;
2060
+ }
2061
+
2062
+ var button = $(this);
2063
+
2064
+ button.css({'opacity': '0.5'});
2065
+ $('div.wp-smush-list-dialog div.box div.content').css({'opacity': '0.8'});
2066
+ $('div.wp-smush-list-dialog div.box div.content a').unbind('click');
2067
+
2068
+ //Remove resume button
2069
+ $('button.wp-smush-resume').remove();
2070
+
2071
+ //Disable Button
2072
+ button.attr('disabled', 'disabled');
2073
+
2074
+ //Display the spinner
2075
+ button.parent().find('.spinner').addClass('is-active');
2076
+
2077
+ //Get the Selected directory path
2078
+ var path = $('.jqueryFileTree .selected a').attr('rel');
2079
+ path = 'undefined' == typeof (path) ? '' : path;
2080
+
2081
+ //Absolute path
2082
+ var abs_path = $('input[name="wp-smush-base-path"]').val();
2083
+
2084
+ //Fill in the input field
2085
+ $('.wp-smush-dir-path').val(abs_path + path);
2086
+
2087
+ //Send a ajax request to get a list of all the image files
2088
+ var param = {
2089
+ action: 'image_list',
2090
+ smush_path: $('.wp-smush-dir-path').val(),
2091
+ image_list_nonce: $('input[name="image_list_nonce"]').val()
2092
+ };
2093
+
2094
+ //Get the List of images
2095
+ $.get(ajaxurl, param, function (res) {
2096
+ if( !res.success && 'undefined' !== typeof ( res.data.message ) ) {
2097
+ $('div.wp-smush-scan-result div.content').html(res.data.message );
2098
+ }else {
2099
+ $('div.wp-smush-scan-result div.content').html(res.data );
2100
+ wp_smush_dir_image_ids = res.data.ids;
2101
+ }
2102
+ set_accordion();
2103
+ close_dialog();
2104
+
2105
+ //Show Scan result
2106
+ $('.wp-smush-scan-result').removeClass('hidden');
2107
+ }).done(function (res) {
2108
+
2109
+ //If there was no image list, return
2110
+ if( !res.success ) {
2111
+ //Hide the smush button
2112
+ $('div.wp-smush-all-button-wrap.bottom').hide();
2113
+ return;
2114
+ }
2115
+
2116
+ //Show the smush button
2117
+ $('div.wp-smush-all-button-wrap.bottom').show();
2118
+
2119
+ //Remove disabled attribute for the button
2120
+ $('button.wp-smush-start').removeAttr('disabled');
2121
+
2122
+ //Append a Directory browser button at the top
2123
+ add_dir_browser_button();
2124
+
2125
+ //Clone and add Smush button
2126
+ add_smush_button();
2127
+
2128
+ });
2129
+ });
2130
+
2131
+ /**
2132
+ * Handle the Smush Now button click
2133
+ */
2134
+ $('div.wp-smush-scan-result').on('click', 'button.wp-smush-start', function (e) {
2135
+ e.preventDefault();
2136
+
2137
+ //Check if we have images to be optimised
2138
+ if (!$('.wp-smush-image-list li').length) {
2139
+ return;
2140
+ }
2141
+
2142
+ //Disable this button
2143
+ var button = $('.wp-smush-start');
2144
+ var parent = button.parent();
2145
+
2146
+ //Hide all the notices
2147
+ $('div.wp-smush-scan-result div.wp-smush-notice').hide();
2148
+
2149
+ //Set the button status to 0, to cancel next ajax request
2150
+ $('input[name="wp-smush-continue-ajax"]').val(1);
2151
+
2152
+ //Hide Directory browser button
2153
+ $('button.wp-smush-browse').hide();
2154
+
2155
+ //Hide Exclude directory button link
2156
+ $('a.wp-smush-exclude-dir').hide();
2157
+
2158
+ /** All the Styling changes **/
2159
+ button.attr('disabled', 'disabled');
2160
+ parent.find('span.spinner').addClass('is-active');
2161
+ parent.find('button.wp-smush-pause').show().removeClass('disabled').removeAttr('disabled');
2162
+
2163
+ //Disable Select Directory button
2164
+ $('button.wp-smush-browse').attr('disabled', 'disabled');
2165
+
2166
+ //Initialize the optimisation
2167
+ smush_all(true);
2168
+
2169
+ });
2170
+
2171
+ //Handle the Pause button click
2172
+ $('div.wp-smush-scan-result').on('click', 'button.wp-smush-pause', function (e) {
2173
+ e.preventDefault();
2174
+
2175
+ var pause_button = $('button.wp-smush-pause');
2176
+ //Return if the link is disabled
2177
+ if (pause_button.hasClass('disabled')) {
2178
+ return false;
2179
+ }
2180
+
2181
+ //Set the button status to 0, to cancel next ajax request
2182
+ $('input[name="wp-smush-continue-ajax"]').val(0);
2183
+
2184
+ //Enable the smush button, disable Pause button
2185
+ pause_button.attr('disabled', 'disabled');
2186
+
2187
+ //Enable the smush button, hide the spinner
2188
+ $('button.wp-smush-start, button.wp-smush-browse').show().removeAttr('disabled');
2189
+ $('div.wp-smush-all-button-wrap span.spinner').removeClass('is-active');
2190
+
2191
+ //Show directory exclude option
2192
+ $('a.wp-smush-exclude-dir').show();
2193
+
2194
+ //Remove the loaders
2195
+ update_smush_progress();
2196
+
2197
+
2198
+ });
2199
+
2200
+ //Exclude Directory from list - Handle Click
2201
+ $('div.wp-smush-scan-result').on('click', 'a.wp-smush-exclude-dir', function (e) {
2202
+ e.preventDefault();
2203
+
2204
+ var self = $(this);
2205
+ var parent = self.parent();
2206
+
2207
+ //Hide the link
2208
+ self.hide();
2209
+
2210
+ //Append the loader
2211
+ parent.find('span.wp-smush-li-path').after($('div.wp-smush-scan-result span.spinner:first').clone());
2212
+
2213
+ //Store the spinner in a element
2214
+ var loader = parent.find('span.spinner:first');
2215
+
2216
+ loader.removeClass('is-active');
2217
+
2218
+ var path = self.data('path');
2219
+ var param = {
2220
+ action: 'smush_exclude_path',
2221
+ path: path,
2222
+ nonce: $('input[name="exclude-path-nonce"]').val()
2223
+ };
2224
+
2225
+ //Send Ajax request to remove image for the given path from db
2226
+ $.post(ajaxurl, param, function (res) {
2227
+ loader.remove();
2228
+ //Remove the whole li element on success
2229
+ if (res.success) {
2230
+ //Check if immediate sibling is ul, add a hr tag to it
2231
+ if (parent.is("li.wp-smush-image-ul:first")) {
2232
+ //Add a hr tag for the next element
2233
+ parent.siblings('li.wp-smush-image-ul:first').prepend('<hr />');
2234
+ }
2235
+ parent.remove();
2236
+ }
2237
+ });
2238
+ });
2239
+
2240
+ //Handle Click for Resume Last scan button
2241
+ $('button.wp-smush-resume').on('click', function () {
2242
+
2243
+ var self = $(this);
2244
+
2245
+ //Disable buttons
2246
+ disable_buttons(self);
2247
+
2248
+ //Show Spinner
2249
+ $('div.dir-smush-button-wrap span.spinner').addClass('is-active');
2250
+
2251
+ var params = {
2252
+ action: 'resume_scan',
2253
+ };
2254
+
2255
+ //Send Ajax request to load a list of images
2256
+ $.get(ajaxurl, params, function (r) {
2257
+
2258
+ //Hide the buttons
2259
+ $('button.wp-smush-resume').remove();
2260
+ //Remove the loader for choose directory button
2261
+ $('div.dir-smush-button-wrap span.spinner').remove();
2262
+ // Allow to select a new directory
2263
+ $('button.wp-smush-browse').removeAttr('disabled');
2264
+ //Append the results
2265
+ if (!r.success) {
2266
+ //Append the error message before the buttons
2267
+ $('div.wp-smush-dir-desc').after(r.data.message);
2268
+ } else {
2269
+ //Append the image markup after the buttons
2270
+ $('div.wp-smush-scan-result div.content').html(r.data);
2271
+ $('div.wp-smush-scan-result').removeClass('hidden');
2272
+
2273
+ set_accordion();
2274
+ }
2275
+ }).done(function () {
2276
+ //Add Choose dir browser button
2277
+ add_dir_browser_button();
2278
+
2279
+ //Clone and add Smush button
2280
+ add_smush_button();
2281
+ });
2282
+
2283
+ });
2284
+
2285
+ if ($('div.smush-dir-savings').length > 0) {
2286
+ //Update Directory Smush, as soon as the page loads
2287
+ var stats_param = {
2288
+ action: 'get_dir_smush_stats'
2289
+ }
2290
+ $.get(ajaxurl, stats_param, function (r) {
2291
+
2292
+ //Hide the spinner
2293
+ $('div.smush-dir-savings span.spinner').hide();
2294
+
2295
+ //If there are no errors, and we have a message to display
2296
+ if (!r.success && 'undefined' != typeof ( r.data.message )) {
2297
+ $('div.wp-smush-scan-result div.content').prepend(r.data.message);
2298
+ return;
2299
+ }
2300
+
2301
+ //If there is no value in r
2302
+ if ('undefined' == typeof ( r.data) || 'undefined' == typeof ( r.data.dir_smush )) {
2303
+ //Append the text
2304
+ $('div.smush-dir-savings span.wp-smush-stats').append(wp_smush_msgs.ajax_error);
2305
+ $('div.smush-dir-savings span.wp-smush-stats span').hide();
2306
+ return;
2307
+ } else {
2308
+ //Update the stats
2309
+ update_cummulative_stats(r.data);
2310
+ }
2311
+
2312
+ });
2313
+ }
2314
+ //Close Directory smush modal, if pressed esc
2315
+ $(document).keyup(function (e) {
2316
+ if (e.keyCode === 27) {
2317
+ var modal = $('div.dev-overlay.wp-smush-list-dialog');
2318
+ //If the Directory dialog is not visible
2319
+ if (!modal.is(':visible')) {
2320
+ return;
2321
+ }
2322
+ modal.find('div.close').click();
2323
+
2324
+ }
2325
  });
2326
 
2327
  });
assets/shared-ui/font/WPMU DEV Dashboard.json CHANGED
File without changes
assets/shared-ui/img/spin-grey.gif CHANGED
Binary file
assets/shared-ui/img/spin.gif CHANGED
Binary file
assets/shared-ui/notice.css CHANGED
@@ -115,7 +115,6 @@
115
  z-index: 1;
116
  }
117
  .frash-notice .frash-notice-logo:after {
118
- animation: spin 30s linear infinite;
119
  background-color: rgba(0, 0, 0, 0);
120
  z-index: 2;
121
  }
115
  z-index: 1;
116
  }
117
  .frash-notice .frash-notice-logo:after {
 
118
  background-color: rgba(0, 0, 0, 0);
119
  z-index: 2;
120
  }
assets/shared-ui/notice.js CHANGED
@@ -3,20 +3,30 @@ jQuery(function() {
3
 
4
  // Display the notice after the page was loaded.
5
  function initialize() {
6
- if (! jQuery(".frash-notice:visible").length) {
7
- el_notice = jQuery(".frash-notice");
8
- msg_id = el_notice.find("input[name=msg_id]").val();
9
- btn_dismiss = el_notice.find(".frash-notice-dismiss");
10
-
11
- // Dismiss the notice without any action.
12
- btn_dismiss.click(function(ev) {
13
- ev.preventDefault();
14
- notify_wordpress("wdev_notice_dismiss", btn_dismiss.data("msg"));
15
- });
16
-
17
- // Display the notification.
18
- el_notice.fadeIn(500);
19
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
21
 
22
  // Hide the notice after a CTA button was clicked
@@ -48,5 +58,11 @@ jQuery(function() {
48
  }
49
  }
50
 
51
- window.setTimeout(initialize, 550);
 
 
 
 
 
 
52
  });
3
 
4
  // Display the notice after the page was loaded.
5
  function initialize() {
6
+ if (jQuery(".frash-notice:visible").length) {
7
+ // Free plugin already displayed a notification...
8
+ return;
 
 
 
 
 
 
 
 
 
 
9
  }
10
+ if ( jQuery(".frash-notice.active").length) {
11
+ // Some other premium plugin already displayed a notification...
12
+ return;
13
+ }
14
+
15
+ el_notice = jQuery(".frash-notice");
16
+ msg_id = el_notice.find("input[name=msg_id]").val();
17
+ btn_dismiss = el_notice.find(".frash-notice-dismiss");
18
+
19
+ // Mark this notification "active" before it's visible to avoid duplicates.
20
+ el_notice.addClass("active");
21
+
22
+ // Dismiss the notice without any action.
23
+ btn_dismiss.click(function(ev) {
24
+ ev.preventDefault();
25
+ notify_wordpress("wdev_notice_dismiss", btn_dismiss.data("msg"));
26
+ });
27
+
28
+ // Display the notification.
29
+ el_notice.fadeIn(500);
30
  }
31
 
32
  // Hide the notice after a CTA button was clicked
58
  }
59
  }
60
 
61
+ // Premium version uses a HIGHER delay than the notice in free plugins.
62
+ // So if any free plugin display a notice it will be displayed instead of
63
+ // the premium notice.
64
+ //
65
+ // 1050 ... free notice uses 500 delay + 500 fade in + 20 to let browser render the changes.
66
+ // So after 1020ms the free notice is considered "visible".
67
+ window.setTimeout(initialize, 1050);
68
  });
assets/shared-ui/plugin-ui.php CHANGED
@@ -71,10 +71,16 @@ if ( ! class_exists( 'WDEV_Plugin_Ui' ) ) {
71
  if ( ! did_action( 'admin_enqueue_scripts' ) ) {
72
  add_action(
73
  'admin_enqueue_scripts',
74
- array( __CLASS__, 'enqueue' )
 
 
 
 
 
75
  );
76
  } else {
77
  self::enqueue();
 
78
  }
79
  }
80
 
@@ -85,26 +91,67 @@ if ( ! class_exists( 'WDEV_Plugin_Ui' ) ) {
85
  * @internal Do not call this method manually. It's called by `load()`!
86
  */
87
  static public function enqueue() {
 
 
 
 
 
 
 
 
 
 
88
  wp_enqueue_style(
89
  'wdev-plugin-google_fonts',
90
  'https://fonts.googleapis.com/css?family=Roboto+Condensed:400,700|Roboto:400,500,300,300italic',
91
  false,
92
- self::VERSION
 
 
 
 
 
 
 
93
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
  wp_enqueue_style(
96
  'wdev-plugin-ui',
97
  self::$module_url . 'wdev-ui.css',
98
  array( 'wdev-plugin-google_fonts' ),
99
- self::VERSION
100
  );
101
 
102
  wp_enqueue_script(
103
  'wdev-plugin-ui',
104
  self::$module_url . 'wdev-ui.js',
105
  array( 'jquery' ),
106
- self::VERSION
107
  );
 
 
 
 
 
 
108
  }
109
 
110
  /**
@@ -248,7 +295,7 @@ if ( ! class_exists( 'WDEV_Plugin_Ui' ) ) {
248
  </div>
249
  <?php if ( $show_actions ) : ?>
250
  <div class="frash-notice-cta">
251
- <?php echo wp_kses( $msg['cta'], $allowed ); ?>
252
  <?php if ( $msg['can_dismiss'] ) : ?>
253
  <button class="frash-notice-dismiss" data-msg="<?php echo esc_attr( $msg_dismiss ); ?>">
254
  <?php esc_html_e( 'Dismiss', 'wpmudev' ); ?>
71
  if ( ! did_action( 'admin_enqueue_scripts' ) ) {
72
  add_action(
73
  'admin_enqueue_scripts',
74
+ array( __CLASS__, 'enqueue_early' )
75
+ );
76
+ add_action(
77
+ 'admin_enqueue_scripts',
78
+ array( __CLASS__, 'enqueue_late' ),
79
+ 999
80
  );
81
  } else {
82
  self::enqueue();
83
+ self::enqueue_late();
84
  }
85
  }
86
 
91
  * @internal Do not call this method manually. It's called by `load()`!
92
  */
93
  static public function enqueue() {
94
+ /*
95
+ * Beta-testers will not have cached scripts!
96
+ * Just in case we have to update the plugin prior to launch.
97
+ */
98
+ if ( defined( 'WPMUDEV_BETATEST' ) && WPMUDEV_BETATEST ) {
99
+ $script_version = time();
100
+ } else {
101
+ $script_version = self::VERSION;
102
+ }
103
+
104
  wp_enqueue_style(
105
  'wdev-plugin-google_fonts',
106
  'https://fonts.googleapis.com/css?family=Roboto+Condensed:400,700|Roboto:400,500,300,300italic',
107
  false,
108
+ $script_version
109
+ );
110
+
111
+ wp_enqueue_style(
112
+ 'wdev-plugin-notice',
113
+ self::$module_url . 'notice.css',
114
+ array( 'wdev-plugin-google_fonts' ),
115
+ $script_version
116
  );
117
+ }
118
+
119
+ /**
120
+ * Enqueues the CSS and JS files after all other files.
121
+ *
122
+ * @since 1.0.0
123
+ * @internal Do not call this method manually. It's called by `load()`!
124
+ */
125
+ static public function enqueue_late() {
126
+ /*
127
+ * Beta-testers will not have cached scripts!
128
+ * Just in case we have to update the plugin prior to launch.
129
+ */
130
+ if ( defined( 'WPMUDEV_BETATEST' ) && WPMUDEV_BETATEST ) {
131
+ $script_version = time();
132
+ } else {
133
+ $script_version = self::VERSION;
134
+ }
135
 
136
  wp_enqueue_style(
137
  'wdev-plugin-ui',
138
  self::$module_url . 'wdev-ui.css',
139
  array( 'wdev-plugin-google_fonts' ),
140
+ $script_version
141
  );
142
 
143
  wp_enqueue_script(
144
  'wdev-plugin-ui',
145
  self::$module_url . 'wdev-ui.js',
146
  array( 'jquery' ),
147
+ $script_version
148
  );
149
+
150
+ /**
151
+ * Allow other plugins to enqueue css/js after shared-ui to
152
+ * overwrite certain definitions.
153
+ */
154
+ do_action( 'wpmudev_plugin_ui_enqueued' );
155
  }
156
 
157
  /**
295
  </div>
296
  <?php if ( $show_actions ) : ?>
297
  <div class="frash-notice-cta">
298
+ <?php echo $msg['cta']; ?>
299
  <?php if ( $msg['can_dismiss'] ) : ?>
300
  <button class="frash-notice-dismiss" data-msg="<?php echo esc_attr( $msg_dismiss ); ?>">
301
  <?php esc_html_e( 'Dismiss', 'wpmudev' ); ?>
assets/shared-ui/wdev-ui.css CHANGED
@@ -115,18 +115,18 @@
115
  font-family: 'Roboto', sans-serif;
116
  font-weight: 400;
117
  font-size: 15px;
118
- line-height: 21px;
119
  color: #777771;
120
  }
121
  .wpmud p small {
122
  font-size: 12.5px;
123
- line-height: 17px;
124
  display: inline-block;
125
  color: #555550;
126
  }
127
  .wpmud p big {
128
  font-size: 18px;
129
- line-height: 24px;
130
  display: inline-block;
131
  font-weight: 400;
132
  color: #888882;
@@ -164,6 +164,10 @@
164
  #wpfooter {
165
  display: none;
166
  }
 
 
 
 
167
  .wpmud a {
168
  text-decoration: none;
169
  color: #19B4CF;
@@ -859,9 +863,15 @@
859
  .wpmud [tooltip].tooltip-right:after {
860
  margin-left: -180px;
861
  }
 
 
 
862
  .wpmud [tooltip].tooltip-s.tooltip-right:after {
863
  margin-left: -130px;
864
  }
 
 
 
865
  .wpmud [tooltip].tooltip-l.tooltip-right:after {
866
  margin-left: -260px;
867
  }
@@ -1042,14 +1052,14 @@
1042
  /* ****************************************************************************
1043
  * 12. ELEMENT: BUTTONS
1044
  */
1045
- .wpmud button:focus,
1046
  .wpmud .button:focus {
1047
  outline-color: transparent;
1048
  outline-style: none;
1049
  border: 0;
1050
  box-shadow: none;
1051
  }
1052
- .wpmud button,
1053
  .wpmud .button {
1054
  font: 500 15px/20px 'Roboto';
1055
  background: #00ACCA;
@@ -1060,24 +1070,24 @@
1060
  display: inline-block;
1061
  margin: 0;
1062
  border: 0;
1063
- border-radius: 5px;
1064
- -moz-border-radius: 5px;
1065
  cursor: pointer;
1066
  box-shadow: none;
1067
  -moz-transition: color 0.3s, opacity 0.3s;
1068
  transition: color 0.3s, opacity 0.3s;
1069
  text-shadow: none;
1070
  }
1071
- .wpmud button + button,
1072
- .wpmud .button + button,
1073
- .wpmud button + .button,
1074
  .wpmud .button + .button,
1075
- .wpmud a + button,
1076
  .wpmud a + .button {
1077
  margin-left: 10px;
1078
  }
1079
- .wpmud button:hover:not(:focus):not(:active),
1080
- .wpmud .button:hover:not(:focus):not(:active) {
1081
  background-color: #0093B1;
1082
  color: #FFF;
1083
  box-shadow: none;
@@ -1098,6 +1108,13 @@
1098
  background: linear-gradient(to bottom, #0082a1 0%,#008fae 100%);
1099
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0082a1', endColorstr='#008fae',GradientType=0 );
1100
  }
 
 
 
 
 
 
 
1101
  /* Variation: Green button */
1102
  .wpmud .button-green {
1103
  background: #1ABC9C;
@@ -1296,9 +1313,9 @@
1296
  padding: 7px 10px;
1297
  font-weight: 500;
1298
  font-family: 'Roboto', sans-serif;
1299
- font-size: 16px;
1300
  margin: 0 0 4px;
1301
- color: #777771;
1302
  }
1303
  .wpmud label.inline-label {
1304
  display: inline-block;
@@ -1662,7 +1679,7 @@
1662
  margin-left: -1px;
1663
  margin-right: -1px;
1664
  margin-top: -2px;
1665
- opacity: 0;
1666
  border-radius: 0 0 4px 4px;
1667
  font: 500 15px/25px 'Roboto';
1668
  transition-property: opacity, border-color;
@@ -1680,6 +1697,21 @@
1680
  opacity: 0.8;
1681
  transition-property: opacity;
1682
  transition-duration: 0.3s;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1683
  }
1684
  .wpmud .select-list-container .list-results li:last-child {
1685
  border-radius: 0 0 3px 3px;
@@ -1688,6 +1720,9 @@
1688
  background: #b5e6f8;
1689
  color: #3d464d;
1690
  }
 
 
 
1691
  .wpmud .select-list-container .list-results .current {
1692
  background: #FFF;
1693
  color: #19b4cf;
@@ -1723,8 +1758,9 @@
1723
  left: 0;
1724
  right: 0;
1725
  width: auto;
1726
- opacity: 1;
1727
- transition-duration: 0;
 
1728
  }
1729
  .wpmud .select-container.active:hover {
1730
  border-color: #DDD;
@@ -1825,6 +1861,7 @@
1825
  /* ****************************************************************************
1826
  * 19. ELEMENT: USER NOTIFICATIONS
1827
  */
 
1828
  .wpmud .update-notice,
1829
  .wpmud .wpmud-loading-info {
1830
  position: fixed;
@@ -1898,6 +1935,59 @@
1898
  .wpmud.folded .wpmud-loading-info {
1899
  left: 36px;
1900
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1901
 
1902
  /* ****************************************************************************
1903
  * 20. ELEMENT: SEARCH BOX
115
  font-family: 'Roboto', sans-serif;
116
  font-weight: 400;
117
  font-size: 15px;
118
+ line-height: 29px;
119
  color: #777771;
120
  }
121
  .wpmud p small {
122
  font-size: 12.5px;
123
+ line-height: 22px;
124
  display: inline-block;
125
  color: #555550;
126
  }
127
  .wpmud p big {
128
  font-size: 18px;
129
+ line-height: 28px;
130
  display: inline-block;
131
  font-weight: 400;
132
  color: #888882;
164
  #wpfooter {
165
  display: none;
166
  }
167
+ .wpmud b,
168
+ .wpmud strong {
169
+ font-weight: 500;
170
+ }
171
  .wpmud a {
172
  text-decoration: none;
173
  color: #19B4CF;
863
  .wpmud [tooltip].tooltip-right:after {
864
  margin-left: -180px;
865
  }
866
+ .wpmud [tooltip].tooltip-left:after {
867
+ margin-left: -20px;
868
+ }
869
  .wpmud [tooltip].tooltip-s.tooltip-right:after {
870
  margin-left: -130px;
871
  }
872
+ .wpmud [tooltip].tooltip-s.tooltip-left:after {
873
+ margin-left: -30px;
874
+ }
875
  .wpmud [tooltip].tooltip-l.tooltip-right:after {
876
  margin-left: -260px;
877
  }
1052
  /* ****************************************************************************
1053
  * 12. ELEMENT: BUTTONS
1054
  */
1055
+ .wpmud button:not(.wph-button):not(#collapse-button):focus,
1056
  .wpmud .button:focus {
1057
  outline-color: transparent;
1058
  outline-style: none;
1059
  border: 0;
1060
  box-shadow: none;
1061
  }
1062
+ .wpmud button:not(.wph-button):not(#collapse-button),
1063
  .wpmud .button {
1064
  font: 500 15px/20px 'Roboto';
1065
  background: #00ACCA;
1070
  display: inline-block;
1071
  margin: 0;
1072
  border: 0;
1073
+ border-radius: 3px;
1074
+ -moz-border-radius: 3px;
1075
  cursor: pointer;
1076
  box-shadow: none;
1077
  -moz-transition: color 0.3s, opacity 0.3s;
1078
  transition: color 0.3s, opacity 0.3s;
1079
  text-shadow: none;
1080
  }
1081
+ .wpmud button:not(.wph-button):not(#collapse-button) + button:not(.wph-button):not(#collapse-button),
1082
+ .wpmud .button + button:not(.wph-button):not(#collapse-button),
1083
+ .wpmud button:not(.wph-button):not(#collapse-button) + .button,
1084
  .wpmud .button + .button,
1085
+ .wpmud a + button:not(.wph-button):not(#collapse-button),
1086
  .wpmud a + .button {
1087
  margin-left: 10px;
1088
  }
1089
+ .wpmud button:hover:not(:focus):not(:active):not(.wph-button):not(#collapse-button):not([tooltip]),
1090
+ .wpmud .button:hover:not(:focus):not(:active):not(.wph-button):not(#collapse-button):not([tooltip]) {
1091
  background-color: #0093B1;
1092
  color: #FFF;
1093
  box-shadow: none;
1108
  background: linear-gradient(to bottom, #0082a1 0%,#008fae 100%);
1109
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0082a1', endColorstr='#008fae',GradientType=0 );
1110
  }
1111
+ .wpmud a.disabled,
1112
+ .wpmud button.disabled,
1113
+ .wpmud .close.disabled,
1114
+ .wpmud .button.disabled {
1115
+ /* Do not handle click events while disabled */
1116
+ pointer-events: none;
1117
+ }
1118
  /* Variation: Green button */
1119
  .wpmud .button-green {
1120
  background: #1ABC9C;
1313
  padding: 7px 10px;
1314
  font-weight: 500;
1315
  font-family: 'Roboto', sans-serif;
1316
+ font-size: 15px;
1317
  margin: 0 0 4px;
1318
+ color: #555;
1319
  }
1320
  .wpmud label.inline-label {
1321
  display: inline-block;
1679
  margin-left: -1px;
1680
  margin-right: -1px;
1681
  margin-top: -2px;
1682
+ display: none;
1683
  border-radius: 0 0 4px 4px;
1684
  font: 500 15px/25px 'Roboto';
1685
  transition-property: opacity, border-color;
1697
  opacity: 0.8;
1698
  transition-property: opacity;
1699
  transition-duration: 0.3s;
1700
+ border-radius: 0 !important;
1701
+ cursor: pointer;
1702
+ }
1703
+ .wpmud .select-list-container .list-results .optgroup{
1704
+ cursor: default;
1705
+ }
1706
+ .wpmud .select-list-container .list-results .optgroup li{
1707
+ padding-left: 30px;
1708
+ cursor: pointer;
1709
+ }
1710
+ .wpmud .select-list-container .list-results .optgroup li.optgroup-label{
1711
+ padding-left: 10px;
1712
+ color: #ababab;
1713
+ cursor: default;
1714
+ pointer-events: none;
1715
  }
1716
  .wpmud .select-list-container .list-results li:last-child {
1717
  border-radius: 0 0 3px 3px;
1720
  background: #b5e6f8;
1721
  color: #3d464d;
1722
  }
1723
+ .wpmud .select-list-container .list-results .optgroup li.optgroup-label:hover{
1724
+ background: none;
1725
+ }
1726
  .wpmud .select-list-container .list-results .current {
1727
  background: #FFF;
1728
  color: #19b4cf;
1758
  left: 0;
1759
  right: 0;
1760
  width: auto;
1761
+ /*opacity: 1;*/
1762
+ display: block;
1763
+ transition-duration: 0ms;
1764
  }
1765
  .wpmud .select-container.active:hover {
1766
  border-color: #DDD;
1861
  /* ****************************************************************************
1862
  * 19. ELEMENT: USER NOTIFICATIONS
1863
  */
1864
+ /* Notice floating on top of the screen */
1865
  .wpmud .update-notice,
1866
  .wpmud .wpmud-loading-info {
1867
  position: fixed;
1935
  .wpmud.folded .wpmud-loading-info {
1936
  left: 36px;
1937
  }
1938
+ /* Inline notifications */
1939
+ .wpmud .inline-notice {
1940
+ position: relative;
1941
+ display: block;
1942
+ padding: 20px 30px;
1943
+ line-height: 20px;
1944
+ font-size: 15px;
1945
+ font-family: "Roboto", Arial, sans-serif;
1946
+ border-radius: 5px;
1947
+ margin: 30px 0;
1948
+ background: #EBFCFF;
1949
+ color: #14485F;
1950
+ border: 1px solid #B5D3E0;
1951
+ }
1952
+ .wpmud .inline-notice.ok {
1953
+ background: #1ABC9C;
1954
+ color: #ffffff;
1955
+ border: 0;
1956
+ }
1957
+ .wpmud .inline-notice.err {
1958
+ background: #FF6D6D;
1959
+ color: #ffffff;
1960
+ border: 0;
1961
+ }
1962
+ .wpmud .inline-notice button,
1963
+ .wpmud .inline-notice button:hover:not(:focus):not(:active),
1964
+ .wpmud .inline-notice .button,
1965
+ .wpmud .inline-notice .button:hover:not(:focus):not(:active) {
1966
+ background: transparent;
1967
+ border: 1px solid #14485F;
1968
+ color: #14485F;
1969
+ padding: 3px 14px;
1970
+ }
1971
+ .wpmud .inline-notice.ok button,
1972
+ .wpmud .inline-notice.ok .button,
1973
+ .wpmud .inline-notice.ok button:hover:not(:focus):not(:active),
1974
+ .wpmud .inline-notice.ok .button:hover:not(:focus):not(:active),
1975
+ .wpmud .inline-notice.err button,
1976
+ .wpmud .inline-notice.err .button,
1977
+ .wpmud .inline-notice.err button:hover:not(:focus):not(:active),
1978
+ .wpmud .inline-notice.err .button:hover:not(:focus):not(:active) {
1979
+ border-color: #fff;
1980
+ color: #fff;
1981
+ }
1982
+ .wpmud .inline-notice button:hover:not(:focus):not(:active),
1983
+ .wpmud .inline-notice button:focus,
1984
+ .wpmud .inline-notice button:active,
1985
+ .wpmud .inline-notice .button:hover:not(:focus):not(:active),
1986
+ .wpmud .inline-notice .button:focus,
1987
+ .wpmud .inline-notice .button:active {
1988
+ background: rgba(255,255,255,0.1);
1989
+ }
1990
+
1991
 
1992
  /* ****************************************************************************
1993
  * 20. ELEMENT: SEARCH BOX
assets/shared-ui/wdev-ui.js CHANGED
@@ -30,6 +30,9 @@ jQuery(function() {
30
  // Handle close buttons inside boxes.
31
  jQuery(".wpmud").on("click", ".can-close .close", closeElement);
32
 
 
 
 
33
  // Initialize all tab-areas.
34
  jQuery(".wpmud .tabs").each(function(){
35
  WDP.wpmuTabs(this);
@@ -96,6 +99,29 @@ jQuery(function() {
96
  return false;
97
  }
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  // Select all text inside the element.
100
  function selectOnClick(ev) {
101
  WDP.selectText(this);
@@ -146,7 +172,7 @@ jQuery(function() {
146
 
147
  // Parses the hash-tag in the current address bar.
148
  function checkLocalRoutes() {
149
- var route = window.location.hash.substr(1);
150
  parts = route.split("=");
151
 
152
  WDP.localRoutes = {
@@ -393,7 +419,7 @@ WDP.prepareOverlay = function() {
393
  WDP.overlay.box = jQuery('<div class="box"></div>');
394
  WDP.overlay.box_title = jQuery('<div class="title"><h3></h3></div>');
395
  WDP.overlay.box_content = jQuery('<div class="content"></div>');
396
- WDP.overlay.close = jQuery('<div class="close">&times;</div>');
397
 
398
  WDP.overlay.back.appendTo(WDP.overlay.wrapper);
399
  WDP.overlay.scroll.appendTo(WDP.overlay.wrapper);
@@ -606,7 +632,7 @@ WDP.wpmuSelect = function(el) {
606
  wrap, handle, list, value, items;
607
 
608
  if (! jq.is("select")) { return; }
609
- if (jq.closest(".select-container").length) { return; }
610
 
611
  // Add the DOM elements to style the select list.
612
  function setupElement() {
@@ -622,24 +648,64 @@ WDP.wpmuSelect = function(el) {
622
  wrap.addClass(jq.attr("class"));
623
  }
624
 
 
 
 
 
 
 
 
 
 
 
 
 
 
625
  // Add all the options to the new DOM elements.
626
  function populateList() {
627
  items.empty();
628
- jq.find("option").each(function onPopulateLoop() {
629
- var opt = jQuery(this),
630
- item;
631
- item = jQuery("<li></li>").appendTo(items);
632
- item.text(opt.text());
633
- item.data("value", opt.val());
634
-
635
- if (opt.val() == jq.val()) {
636
- selectItem(item);
637
- }
638
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
639
  }
640
 
641
  // Toggle the dropdown state between open/closed.
642
  function stateToggle() {
 
 
643
  if (! wrap.hasClass("active")) {
644
  stateOpen();
645
  } else {
@@ -664,16 +730,18 @@ WDP.wpmuSelect = function(el) {
664
  }
665
 
666
  // Visually mark the specified option as "selected".
667
- function selectItem(opt) {
 
668
  value.text(opt.text());
669
-
670
  jQuery(".current", items).removeClass("current");
671
  opt.addClass("current");
672
  stateClose();
673
 
674
  // Also update the select list value.
675
  jq.val(opt.data("value"));
676
- jq.trigger("change");
 
 
677
  }
678
 
679
  // Element constructor.
@@ -682,9 +750,10 @@ WDP.wpmuSelect = function(el) {
682
 
683
  setupElement();
684
  populateList();
685
- items.on("click", function onItemClick(ev) {
 
686
  var opt = jQuery(ev.target);
687
- selectItem(opt);
688
  });
689
 
690
  handle.on("click", stateToggle);
@@ -708,6 +777,7 @@ WDP.wpmuSelect = function(el) {
708
  if (sel_id) {
709
  jQuery("label[for=" + sel_id + "]").on("click", stateOpen);
710
  }
 
711
  }
712
 
713
  init();
@@ -1042,16 +1112,16 @@ WDP.showMessage = function(action) {
1042
  '<span class="the-msg-icon check-animation"></span>' +
1043
  '<p><span class="default-text">' + WDP.lang.default_msg_ok + '</span>' +
1044
  '<span class="extra-text" style="display:none"></span></p>' +
1045
- '<span class="close">&times;</span>' +
1046
  '</div>'
1047
- );
1048
 
1049
  jQuery("body").append(
1050
  '<div class="update-notice err" id="wdp-error" style="display:none">' +
1051
  '<i class="the-msg-icon wdv-icon wdv-icon-warning-sign"></i>' +
1052
  '<p><span class="default-text">' + WDP.lang.default_msg_err + '</span>' +
1053
  '<span class="extra-text" style="display:none"></span></p>' +
1054
- '<span class="close">&times;</span>' +
1055
  '</div>'
1056
  );
1057
 
@@ -1111,7 +1181,7 @@ WDP.showMessage = function(action) {
1111
  }
1112
 
1113
  return WDP;
1114
- };
1115
 
1116
  /**
1117
  * Displays the "Changes saved" message in the top of the window.
@@ -1200,4 +1270,41 @@ WDP.updateHash = function(newHash) {
1200
  fx.remove();
1201
  node.attr('id', newHash);
1202
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1203
  };
30
  // Handle close buttons inside boxes.
31
  jQuery(".wpmud").on("click", ".can-close .close", closeElement);
32
 
33
+ // Add a reload-page handler.
34
+ jQuery(".wpmud").on("click", ".reload-page", reloadPage);
35
+
36
  // Initialize all tab-areas.
37
  jQuery(".wpmud .tabs").each(function(){
38
  WDP.wpmuTabs(this);
99
  return false;
100
  }
101
 
102
+ // When a .reload-page item is clicked, we reload it!
103
+ function reloadPage(ev) {
104
+ if (ev && ev.preventDefault) { ev.preventDefault(); }
105
+
106
+ var btn = jQuery(ev.target),
107
+ scope = jQuery("#wpbody, .dev-overlay"),
108
+ elems = scope.find("button, .button, a[href], [tooltip]");
109
+
110
+ // Disable other elements on the page and start loading animation.
111
+ if (btn.closest(".box").length) {
112
+ btn.closest(".box").loading(true);
113
+ } else if (btn.find(".spin-on-click")) {
114
+ spinOnClick.call(btn, ev);
115
+ } else {
116
+ btn.loading(true);
117
+ }
118
+ elems.prop("disabled", true).addClass("disabled");
119
+
120
+ // Reload the page!
121
+ window.location.reload();
122
+ return false;
123
+ }
124
+
125
  // Select all text inside the element.
126
  function selectOnClick(ev) {
127
  WDP.selectText(this);
172
 
173
  // Parses the hash-tag in the current address bar.
174
  function checkLocalRoutes() {
175
+ var route = window.location.hash.substr(1),
176
  parts = route.split("=");
177
 
178
  WDP.localRoutes = {
419
  WDP.overlay.box = jQuery('<div class="box"></div>');
420
  WDP.overlay.box_title = jQuery('<div class="title"><h3></h3></div>');
421
  WDP.overlay.box_content = jQuery('<div class="content"></div>');
422
+ WDP.overlay.close = jQuery('<div class="close" aria-label="Close">&times;</div>');
423
 
424
  WDP.overlay.back.appendTo(WDP.overlay.wrapper);
425
  WDP.overlay.scroll.appendTo(WDP.overlay.wrapper);
632
  wrap, handle, list, value, items;
633
 
634
  if (! jq.is("select")) { return; }
635
+ if (jq.closest(".select-container").length || jq.data("select2") || jq.is(".none-wpmu") ) { return; }
636
 
637
  // Add the DOM elements to style the select list.
638
  function setupElement() {
648
  wrap.addClass(jq.attr("class"));
649
  }
650
 
651
+ // When changing selection using JS, you need to trigger a 'wpmu:change' event
652
+ // eg: jQuery('select').val('4').trigger('wpmu:change')
653
+ function handleSelectionChange() {
654
+ jq.on('wpmu:change',function(){
655
+ //We need to re-populateList to handle dynamic select options added via JS/ajax
656
+ populateList();
657
+ items.find("li").not('.optgroup-label').on("click", function onItemClick(ev) {
658
+ var opt = jQuery(ev.target);
659
+ selectItem(opt, false);
660
+ });
661
+ });
662
+ }
663
+
664
  // Add all the options to the new DOM elements.
665
  function populateList() {
666
  items.empty();
667
+ if( jq.find("optgroup").length ){
668
+ jq.find("optgroup").each(function(){
669
+ var optgroup = jQuery(this),
670
+ optgroup_item;
671
+ optgroup_item = jQuery("<ul></ul>").appendTo(items);
672
+ $label = jQuery('<li class="optgroup-label"></li>').text( optgroup.prop('label') );
673
+
674
+ optgroup_item.html( $label );
675
+ optgroup_item.addClass('optgroup');
676
+
677
+ optgroup.find('option').each(function onPopulateLoop() {
678
+ var opt = jQuery(this),
679
+ item;
680
+ item = jQuery("<li></li>").appendTo(optgroup_item);
681
+ item.text(opt.text());
682
+ item.data("value", opt.val());
683
+
684
+ if (opt.val() == jq.val()) {
685
+ selectItem(item);
686
+ }
687
+ });
688
+ });
689
+ }else{
690
+ jq.find("option").each(function onPopulateLoop() {
691
+ var opt = jQuery(this),
692
+ item;
693
+ item = jQuery("<li></li>").appendTo(items);
694
+ item.text(opt.text());
695
+ item.data("value", opt.val());
696
+
697
+ if (opt.val() == jq.val()) {
698
+ selectItem(item, true);
699
+ }
700
+ });
701
+ }
702
+
703
  }
704
 
705
  // Toggle the dropdown state between open/closed.
706
  function stateToggle() {
707
+ if( wrap.find("select").is(":disabled") ) return;
708
+
709
  if (! wrap.hasClass("active")) {
710
  stateOpen();
711
  } else {
730
  }
731
 
732
  // Visually mark the specified option as "selected".
733
+ function selectItem(opt, is_init) {
734
+ is_init = typeof is_init === "undefined" ? false : is_init;
735
  value.text(opt.text());
 
736
  jQuery(".current", items).removeClass("current");
737
  opt.addClass("current");
738
  stateClose();
739
 
740
  // Also update the select list value.
741
  jq.val(opt.data("value"));
742
+
743
+ if( !is_init )
744
+ jq.trigger("change");
745
  }
746
 
747
  // Element constructor.
750
 
751
  setupElement();
752
  populateList();
753
+ handleSelectionChange();
754
+ items.find("li").not('.optgroup-label').on("click", function onItemClick(ev) {
755
  var opt = jQuery(ev.target);
756
+ selectItem(opt, false);
757
  });
758
 
759
  handle.on("click", stateToggle);
777
  if (sel_id) {
778
  jQuery("label[for=" + sel_id + "]").on("click", stateOpen);
779
  }
780
+ jq.addClass("wdev-styled");
781
  }
782
 
783
  init();
1112
  '<span class="the-msg-icon check-animation"></span>' +
1113
  '<p><span class="default-text">' + WDP.lang.default_msg_ok + '</span>' +
1114
  '<span class="extra-text" style="display:none"></span></p>' +
1115
+ '<span class="close" aria-label="Close">&times;</span>' +
1116
  '</div>'
1117
+ )
1118
 
1119
  jQuery("body").append(
1120
  '<div class="update-notice err" id="wdp-error" style="display:none">' +
1121
  '<i class="the-msg-icon wdv-icon wdv-icon-warning-sign"></i>' +
1122
  '<p><span class="default-text">' + WDP.lang.default_msg_err + '</span>' +
1123
  '<span class="extra-text" style="display:none"></span></p>' +
1124
+ '<span class="close" aria-label="Close">&times;</span>' +
1125
  '</div>'
1126
  );
1127
 
1181
  }
1182
 
1183
  return WDP;
1184
+ }
1185
 
1186
  /**
1187
  * Displays the "Changes saved" message in the top of the window.
1270
  fx.remove();
1271
  node.attr('id', newHash);
1272
  }
1273
+ }
1274
+
1275
+ /**
1276
+ * Create or replace a cookie via javascript.
1277
+ *
1278
+ * @since 4.1.0
1279
+ */
1280
+ WDP.setCookie = function(name, value, days) {
1281
+ var expires;
1282
+ if (days) {
1283
+ var date = new Date();
1284
+ date.setTime(date.getTime() + (days * 86400 * 1000));
1285
+ expires = "; expires=" + date.toGMTString();
1286
+ } else {
1287
+ expires = "";
1288
+ }
1289
+ document.cookie = name + "=" + value + expires + "; path=/";
1290
+ };
1291
+
1292
+ /**
1293
+ * Return the value of a cookie.
1294
+ *
1295
+ * @since 4.1.0
1296
+ */
1297
+ WDP.getCookie = function(cookieName) {
1298
+ if (document.cookie.length > 0) {
1299
+ offset = document.cookie.indexOf(cookieName + "=");
1300
+ if (-1 != offset) {
1301
+ offset = offset + cookieName.length + 1;
1302
+ end = document.cookie.indexOf(";", offset);
1303
+ if (end == -1) {
1304
+ end = document.cookie.length;
1305
+ }
1306
+ return unescape(document.cookie.substring(offset, end));
1307
+ }
1308
+ }
1309
+ return "";
1310
  };
extras/dash-notice/wpmudev-dash-notification.php CHANGED
@@ -1,442 +1,635 @@
1
  <?php
2
  /////////////////////////////////////////////////////////////////////////
3
  /* -------- WPMU DEV Dashboard Notice - Aaron Edwards (Incsub) ------- */
4
- if ( !class_exists('WPMUDEV_Dashboard_Notice3') ) {
5
- class WPMUDEV_Dashboard_Notice3 {
6
-
7
- var $version = '3.1';
 
8
  var $screen_id = false;
9
  var $product_name = false;
10
  var $product_update = false;
11
  var $theme_pack = 128;
12
- var $server_url = 'http://premium.wpmudev.org/wdp-un.php';
13
  var $update_count = 0;
14
-
15
  function __construct() {
16
  add_action( 'init', array( &$this, 'init' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
-
19
  function init() {
20
  global $wpmudev_un;
21
-
22
- if ( class_exists( 'WPMUDEV_Dashboard' ) || ( isset($wpmudev_un->version) && version_compare($wpmudev_un->version, '3.4', '<') ) )
23
  return;
24
-
 
25
  // Schedule update cron on main site only
26
  if ( is_main_site() ) {
27
  if ( ! wp_next_scheduled( 'wpmudev_scheduled_jobs' ) ) {
28
  wp_schedule_event( time(), 'twicedaily', 'wpmudev_scheduled_jobs' );
29
  }
30
 
31
- add_action( 'wpmudev_scheduled_jobs', array( $this, 'updates_check') );
32
  }
33
- add_action( 'delete_site_transient_update_plugins', array( &$this, 'updates_check' ) ); //refresh after upgrade/install
34
- add_action( 'delete_site_transient_update_themes', array( &$this, 'updates_check' ) ); //refresh after upgrade/install
35
-
 
 
 
 
 
 
36
  if ( is_admin() && current_user_can( 'install_plugins' ) ) {
37
-
38
  add_action( 'site_transient_update_plugins', array( &$this, 'filter_plugin_count' ) );
39
  add_action( 'site_transient_update_themes', array( &$this, 'filter_theme_count' ) );
40
- add_filter( 'plugins_api', array( &$this, 'filter_plugin_info' ), 101, 3 ); //run later to work with bad autoupdate plugins
41
- add_filter( 'themes_api', array( &$this, 'filter_plugin_info' ), 101, 3 ); //run later to work with bad autoupdate plugins
42
- add_action( 'admin_init', array( &$this, 'filter_plugin_rows' ), 15 ); //make sure it runs after WP's
 
 
 
 
 
 
 
43
  add_action( 'core_upgrade_preamble', array( &$this, 'disable_checkboxes' ) );
44
  add_action( 'activated_plugin', array( &$this, 'set_activate_flag' ) );
45
-
46
- //remove version 1.0
47
- remove_action( 'admin_notices', 'wdp_un_check', 5 );
48
- remove_action( 'network_admin_notices', 'wdp_un_check', 5 );
49
- //remove version 2.0, a bit nasty but only way
50
- remove_all_actions( 'all_admin_notices', 5 );
51
-
52
  //if dashboard is installed but not activated
53
- if ( file_exists(WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php') ) {
54
- if ( !get_site_option('wdp_un_autoactivated') ) {
55
  //include plugin API if necessary
56
- if ( !function_exists('activate_plugin') ) require_once(ABSPATH . 'wp-admin/includes/plugin.php');
57
- $result = activate_plugin( '/wpmudev-updates/update-notifications.php', network_admin_url('admin.php?page=wpmudev'), is_multisite() );
58
- if ( !is_wp_error($result) ) { //if autoactivate successful don't show notices
59
- update_site_option('wdp_un_autoactivated', 1);
 
 
 
60
  return;
61
  }
62
  }
63
-
64
  add_action( 'admin_print_styles', array( &$this, 'notice_styles' ) );
 
65
  add_action( 'all_admin_notices', array( &$this, 'activate_notice' ), 5 );
66
  } else { //dashboard not installed at all
67
- if ( get_site_option('wdp_un_autoactivated') ) {
68
- update_site_option('wdp_un_autoactivated', 0);//reset flag when dashboard is deleted
69
  }
70
  add_action( 'admin_print_styles', array( &$this, 'notice_styles' ) );
 
71
  add_action( 'all_admin_notices', array( &$this, 'install_notice' ), 5 );
72
  }
73
  }
74
  }
75
-
76
  function is_allowed_screen() {
77
  global $wpmudev_notices;
78
- $screen = get_current_screen();
79
- $this->screen_id = $screen->id;
80
-
81
  //Show special message right after plugin activation
82
- if ( in_array( $this->screen_id, array('plugins', 'plugins-network') ) && ( isset($_GET['activate']) || isset($_GET['activate-multi']) ) ) {
83
- $activated = get_site_option('wdp_un_activated_flag');
84
- if ($activated === false) $activated = 1; //on first encounter of new installed notice show
85
- if ($activated) {
86
- if ($activated >= 2)
87
- update_site_option('wdp_un_activated_flag', 0);
88
- else
89
- update_site_option('wdp_un_activated_flag', 2);
 
 
 
 
 
 
 
 
90
  return true;
91
  }
92
  }
93
-
 
 
 
 
 
 
94
  //always show on certain core pages if updates are available
95
- $updates = get_site_option('wdp_un_updates_available');
96
- if (is_array($updates) && count($updates)) {
97
- $this->update_count = count($updates);
98
- if ( in_array( $this->screen_id, array('plugins', 'update-core', /*'plugin-install', 'theme-install',*/ 'plugins-network', 'themes-network', /*'theme-install-network', 'plugin-install-network',*/ 'update-core-network') ) )
 
 
 
99
  return true;
 
100
  }
101
-
102
  //check our registered plugins for hooks
103
- if ( isset($wpmudev_notices) && is_array($wpmudev_notices) ) {
104
  foreach ( $wpmudev_notices as $product ) {
105
- if ( isset($product['screens']) && is_array($product['screens']) && in_array( $this->screen_id, $product['screens'] ) ) {
106
  $this->product_name = $product['name'];
107
  //if this plugin needs updating flag it
108
- if ( isset($product['id']) && isset($updates[$product['id']]) )
109
  $this->product_update = true;
 
 
110
  return true;
111
  }
112
  }
113
  }
114
-
115
- if ( defined('WPMUDEV_SCREEN_ID') ) var_dump($this->screen_id); //for internal debugging
116
-
117
  return false;
118
  }
119
-
120
  function auto_install_url() {
121
  $function = is_multisite() ? 'network_admin_url' : 'admin_url';
122
- return wp_nonce_url($function("update.php?action=install-plugin&plugin=install_wpmudev_dash"), "install-plugin_install_wpmudev_dash");
 
123
  }
124
-
125
  function activate_url() {
126
  $function = is_multisite() ? 'network_admin_url' : 'admin_url';
127
- return wp_nonce_url($function('plugins.php?action=activate&plugin=wpmudev-updates%2Fupdate-notifications.php'), 'activate-plugin_wpmudev-updates/update-notifications.php');
 
128
  }
129
-
130
  function install_notice() {
131
- if ( !$this->is_allowed_screen() ) return;
132
 
133
- echo '<div class="updated" id="wpmu-install-dashboard"><div class="wpmu-install-wrap"><p class="wpmu-message">';
134
-
135
- if ($this->product_name) {
136
- if ($this->product_update)
137
- echo 'Important updates are available for <strong>' . esc_html($this->product_name) . '</strong>. Install the free WPMU DEV Dashboard plugin now for updates and support!';
138
- else
139
- echo '<strong>' . esc_html($this->product_name) . '</strong> is almost ready - install the free WPMU DEV Dashboard plugin for updates and support!';
140
- } else if ($this->update_count) {
141
- echo "Important updates are available for your WPMU DEV plugins/themes. Install the free WPMU DEV Dashboard plugin now for updates and support!";
142
- } else {
143
- echo 'Almost ready - install the free WPMU DEV Dashboard plugin for updates and support!';
144
- }
145
- echo '</p><a class="wpmu-button" href="' . $this->auto_install_url() . '">Install WPMU DEV Dashboard</a>';
146
- echo '</div>';
147
- echo '<div class="wpmu-more-wrap"><a href="http://premium.wpmudev.org/update-notifications-plugin-information/" class="wpmu-more-info">More Info&raquo;</a></div>';
148
- echo '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
-
151
  function activate_notice() {
152
- if ( !$this->is_allowed_screen() ) return;
153
-
154
- echo '<div class="updated" id="wpmu-install-dashboard"><div class="wpmu-install-wrap"><p class="wpmu-message">';
155
- if ($this->product_name) {
156
- if ($this->product_update)
157
- echo 'Important updates are available for <strong>' . esc_html($this->product_name) . '</strong>. Activate the WPMU DEV Dashboard to update now!';
158
- else
159
- echo "Just one more step to enable updates and support for <strong>" . esc_html($this->product_name) . '</strong>!';
160
- } else if ($this->update_count) {
161
- echo "Important updates are available for your WPMU DEV plugins/themes. Activate the WPMU DEV Dashboard to update now!";
162
- } else {
163
- echo "Just one more step - activate the WPMU DEV Dashboard plugin and you're all done!";
164
- }
165
- echo '</p><a class="wpmu-button" href="' . $this->activate_url() . '">Activate WPMU DEV Dashboard</a></div></div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  }
167
-
168
  function notice_styles() {
169
  if ( !$this->is_allowed_screen() ) return;
170
  ?>
171
- <!-- WPMU DEV Dashboard notice -->
172
- <style type="text/css" media="all">
173
- #wpmu-install-dashboard{background-color:#031f34;font-family:sans-serif;display:block;border-radius:5px;position:relative;border:none;padding:14px 0.6em;font-size:1.3em;line-height:1.4em}
174
- #wpmu-install-dashboard .wpmu-button{width:auto;position:absolute;top:0;bottom:0;right:0;padding:10px;margin:auto 14px auto 10px;line-height:1em;max-height:1em;background-color:#06385e;color:#3bb2df;text-decoration:none;border:5px solid rgba(53,131,191,0.4);vertical-align:middle;text-shadow:0 1px 0 rgba(0,0,0,0.6)}
175
- #wpmu-install-dashboard .wpmu-button:hover{color:#e8da42;border-color:rgba(53,131,191,0.9);-webkit-transition:0.2s}
176
- #wpmu-install-dashboard .wpmu-message{color:#c0d7eb;margin:0 280px 0 15px;padding:12px 0;text-shadow:0 1px 0 rgba(0,0,0,1);font-size:1em}
177
- #wpmu-install-dashboard .wpmu-button,#wpmu-install-dashboard .wpmu-button:hover{-webkit-transition:0.2s}
178
- #wpmu-install-dashboard .wpmu-btn-wrap{min-width:10%;background-color:#fff}
179
- #wpmu-install-dashboard .wpmu-install-wrap{max-width:1050px;margin:0 auto;position:relative}#wpmu-install-dashboard .wpmu-more-wrap{max-width:1050px;margin:0 auto -9px;padding:5px 0 0;text-align:right}
180
- #wpmu-install-dashboard .wpmu-more-info{color:#e8da42;font-size:0.9em;margin:0 14px}
181
- #wpmu-install-dashboard, .wpmu-update-row{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpCMDBDRENDMjJEOUUxMUUzQjQ0MThGOUZCNkQzMTIwNCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpCMDBDRENDMzJEOUUxMUUzQjQ0MThGOUZCNkQzMTIwNCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkIwMENEQ0MwMkQ5RTExRTNCNDQxOEY5RkI2RDMxMjA0IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkIwMENEQ0MxMkQ5RTExRTNCNDQxOEY5RkI2RDMxMjA0Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+4bBa5AAAFnZJREFUeNrs3el2U0e6BuCyZTybmYSE9JAr6V/nqs+vcyPndHdCgAAGbPA8HFX7U0dxQ5BtWfpq7+dZq5ZJsoilUu16a9pbC+fn5wUArmpRFQAgQAAQIAAIEAAECAAIEAAECAACBAABAoAAAQABAoAAAUCAACBAABAgACBAABAgAAgQAAQIAAIEAAQIAAIEAAECgAABQIAAgAABQIAAIEAAaN5Sthf0t/9+5VMB+LrNYTn/n//69pMZCACTejQsPw7LhhkIAJP22U+H5ZthWRiWMwECwNfU2cazYdnKlGYA5PZ4WL4bluVs0yEAcrpTLpasnpSLJatUBAhATvWU1fcl0ZKVAAHIL+WSlQAByN0n1+BIuWQlQAByqqesfigXS1fNpB0A81NnGqMlqzutTZcAmI8aGN9HgDRHgADMx1aEx2arb0CAAMxWs0tWAgRgfpYjOB6VBk5ZCRCAHJpfshIgALNVZxpPYubRqT5XgADcnuWYdTzq4psTIAC34265ePz6elffoAABmK76Ta91yepp1/tYAQIwPSvlYsnqYR/erAABmI7OL1kJEIDpqktW9TvKv+1bnypAAK6vV0tWAgRgOnq3ZCVAAG5mtGRVT1kN+lwRAgRgcqvlYsnqgaoQIACTuh/hsaYqBAjAJOoy1eiU1UB1CBCASdRnWdXvKbdk9RmLqgDgi9aFhwABuI4FVSBAAK7jXBUIEAAECAACBAABAoAAAQABAoAAAUCAACBAABAgACBAABAgAAgQAAQIAAIEAAQIAAIEAAECgAABAAECgAABQIAAIEAAECAAIEAAECAAzN6SKpi6hQjm8Z/j/20wLKfDcj727+ufzy79hMvtaLwtDcbai3aEAGnw4r4zLMuXfi6NlcFn6njhMxf2SYTKyVg5HpajsZ9HOoRODzqWL5XLbWnp0orB19rR8aV2dDTWnkCAzKGu6oW9MSzrw7ISF/mdCIqb+KO/fxoXfS2Hw/JpWPaiMzjxsTRpEO1m1JbWptSW/ujvHo+V2n4+Dst+tCEDEwTILViOC3xzWLYiNAYzfg2DKKvxGh5HqBxEJ/BxLFDIPcvYGGtLa3H9Lczo948CqrpXLpa4jmNAshM/D3xMCJCbd9hbcZFtxIWe8TVuRPk2AqSW9xEopz7GNOqg40G0qY05DEC+ZDFeWy0Px2a3HyJQzG4RIFdQR/h342JfL22dUFuP8jA6gXfRCRz6WOemzjTuR3tabiToRmFXl7a2I0zMShAgX7lwHseFs9L4e1mMke5WXPg1SN4KkpkHx+MIj0GDr39hbEDyJIJEG0KAXFJHhY+irHTw/dUZ1XcRjLUTeFOcwLnt+n4Ss8CuXFcrY23obRRtiF4HyEJc5HXvYK0H77d2bN/HiPhVzEqcupmeQQxCvunoQGTUhp5FG3pZLvbaoHcBUqflT+NCWOjhe/9ruTgc8KJY256GjRih3+vR+/0xZiI1SJz8EyC98TjCY6XHn/do9lU7gl/KxdIW1/Mk2tNyz973Yrz3URv6oCkIkC67E6PExz2cdXxJDdG/RCdQZyOObF7tmvlee/rXjPbHmIn8Wn7/SBUESCfUPY4/lYtTSfznSLKu29f17Z+KJa1JrEZ7uqsq/qXu/zyLenlebLD3shPpqq0YIQmPP3Y36mlTVfyh0fq/8PhPj2JGu6oqBEhXOsW/ln6cspqG0Qa7sP28zaifdVXxRfeijoSIAGna/WjIyz7eK1kpv53S4j/DQ8c4+SxN0AqQZmcefy6/PTSOq1mO+jMT+W1m9pfS75N7160zgStAmhspCo/phchGz+thVUd44xCxCiBAmrASnZ6R4vQ6zz/3uAOopxN/KJZibjqgqyfWBqpCgGS/2GtDtWE+/VFkHzuAem9Hvc/DXtDN3Y+6dP+VAEnrqYv9VjuAb3v2nuuR1Cc++ql5EnWKAEmnPpbjGx/jraoB8qAn73UzRsxMd0b3rLjPSIAkM3pcuenx7beRWs9d318aRHg4hDF9SxEivn9IgKQZ1XxXnJCZlbUehHWdyTq+fLuzu6eqQYBk8KD0Z1klU513da9po1gKnYX6AEqPghEgc3UnRjKWrmbfVuosZMn74poG6lqAzFs91eHI7nyMvie7S+4Xp/hmqS5lOZUlQOZiLabBzE+t/65sqNeRsKWr2Rt9jQACZOadl1My87XcoVlIHQlv+Ei1IbofIHX55KGPLIWHHRhB3imWUubdhoS3AJlpg7P5pvOdlrr3YS9tfpYEuACZlTradWw3l/p5tPqwxYHZbJo2ZBYiQHRWPbTScKjXU1cerWEWQg8CZKk4ZpnV/dLe03oXzD7ShbkTWQLk1mya5qa10eBIfqt4ZEkmyzEQQYDc2iiXvKP51maH90r3vsq5CzNZB2QEyNStGC2md7e0sz+1XCyHZrTuOhcgt6E2KjcO5u+UW1nG2iy+9jjrTNZKgwCZeqPaKh6a2MLF38oTVs0+coe7zXQBMjV3YmpLfusNzBTrzMNhDDNZpijzxtV64yOSs2E5HJb9+Hka/67+HER4D+I9rkUH1+psazU+rw+JX+NGafteovNhOR6Wg2E5iXIW1/Ag2s9Kae9Y9bg6k30b7xUBcuMLvkU1MHaiMz2Mi/78K7PApbj4R48Wb22dfqGRAGkxoA8utadRcJxfakODaEeb5bcbJVsLk80I+UNdswC5icUGp7P7MXrajtC4ykzlKMrusLwuF08dflTaOtq4GZ/bWdJ2vtFge3ozLO8maE9nUY7j772OEHlc2tqcrsugWwJEgNzUckOj8PMIjRdTavh1xPlzjDqflXb2gdaiA8h48a+Udh6ceBbB8SoGFdf1IQYkNURa+hbAzXj/CJBrW2+kwdf9jF9ixDftddud6Iz/XNo45TSITjpjgGyUNm4ePI72NK0OtIbRrzEr+VMjIboW1/6J7jm/xcSNKPt6dW3gP8UFelubfrUz/keMJFtoS1k7qBZmccfxWd/G6Lu2n78Py14D9VBni47zCpAbyd6A6sjuebnY87htdRnj53Kz5Yw+f26Zg218Jls/49s8hFDD458NtKNB8T0tAuQG6jp69uOWr8ps12nrxf9LyX+8cbnkO/mzmrw9ncdgZHsGv+tTzJrPkrejFlYgSBwgmW9K+xABMmv1NM5OAwGSrbNeK7mPs76OMivvZ/z7rmO9tH0/iwCZo6WSdwO97nu8iCWHWaujxrfJR49LCcM/8w2adWb5ck4z6Mz7IavF03kFyA1mIFkv+DexDDAvdQayn7w9Zbvwsy5fnUV4HM/hd9ffeZuHP6bRjmykC5BOXfCHZf7n0+vMZzt5m8o0A1lK3J7qUuj7Of7+uiT6MWndLAgQAdKFDmjc+5LjHofdMp8ltBY/v0HSABndLHg+59eQeTAiQATItUeN2WQa+ddjmJnXr5dKniXIjHsyo9nHbpLXkXVJtOUHXwoQAfI7dap/kCjMBMjkM5CMbfxdybH/cFzyPgAza/iTPEAyHt/bLblOPx0mb1NZAiRjB7RXcu09ZGvb4/2Ak1gCpPnXVI/ufkr4mrKeoBmUXEtY2RyU+Zy8+qNAO0jajgSIALmybEd4a2ed7fEPme9IX0j0GWZs3+cJ2/dx0nbkZkIBAtD8QBIBAoAAAUCAQI9YmkGAACBAADMQECA6IQABghABBAgAAgQABAgAAgQAAQKAAAFAgACAAPG5AeiIABAgAAgQAAQIAAgQAAQItMqTlBEggPBAgACAADGKBRAgAAgQAAQIAAJEFQAgQAAQIAAIEAAECEm4DwQQIAgQQIAAIEAAQIAAIEAAECAACBBgYgvFKToECAACBAAESC9YAgEECAACBAABAgACBAABAoAAAUCAACBAaIP7QAABggABBAgAAgQABAgAAgQAAQKAAAEm5hsJESDAtQMEBAg6IUCAAIAAAUCAACBAABAgAAgQVQCAAAFAgAAgQJg+NxICAgQBAggQAAQIAAgQAAQIAAIEAAECTMw3EiJAABAgtDmKBRAgAAgQAAQIAAgQAAQIAAIEAAECgAAhP/eBAAIEAQIIEAAECAAIEAAECAACBAABAkzMCToECHDtABEiCBAABAhGsAACpCchAiBAABAgAAgQABAgAAgQAAQIAAIEAAFCbm4kBAQIAAIEAAECAAIEAAECnXCuChAgwHU4RYcAAa4dIJipdaI9CZA2L6zMF1emNjXw+ZmpdbyPPFM5XLUDOk38+mqnvZSkA1pLWD+n877oGxnt18/vToLXsZK8PzgRIDTVaCYIkAwXXe18VgVIswGSpfNeTXytnQoQruMo8WurI8f1BK9jK8kI9rLjhB121hntWpnvMuRi8gA5FiBct+GcJX59G2X+69dbJeeGdcbZY9YAWZ/zLGTev3+SfuBYgNDcyGOCkeM89x/qqPGu2eOV2lNGdfaxOedByCDxdXZUbKJzDYfJA+ROXHzzcr/kXL46TRogtS1l3Qe5N6eZ5CDxIGS8H5grAdKm0wyN5yselvmcxqpLDo+S1slJ0s8t477MyOacBiM1PDYSX1915rEvQLiug+Svr64fP5jD731c8m58niSdgcx9KeQrfdTjGc9C5vE7rzOIFCBc214Dr/HJsCzP8Pdtxe/MHPoZR/onJe8+SHU/yqw8KvNdgp20Lc39MxMg7dpPftFXdSP96Yx+Vw2qZyX3pmfW0K+zj8xLogvRjmYxGKmz129K/kfOfMowaxQg7TrJMIWdwOO4IG9TDY0fSu4163MBciPr8Rnf5gBhKX7HagPX1acML0KAtOu0tLGMVUdy35fb29iuF/2fynz2W66idtCZbwA9aKAtPYhZ5m30W4vRju41UA/HWT6vpULL9mJkm326PYiLs/58Xaa3D7AeHcrdBj6r7EuOh420pSfRjp5PMZBXoh09aOi6TzEYESDtB8hRyf/At1GI/BCd/qtys+W32m7rMeFvGnnv42Gf1VGESAvLNw/jc385LB9uUK+LMeP4ruR88OaXpNj/ECDtO4yOuJVOtI5uRydctuPi/3SFDmAlZhsPSv5TMuNaWG5sKUCqut/147C8j7JTJn8ky9JYO5rXjYo3aUs7WV6MAGnfbpntEcdpqKdp6qmaxxGAn+LnSfn9XdGjR8Ovxswl+7OJ/ijoswfIaJP/XkP1uhizkQfRfvbGZuUnY6P0xWhHyxE869GmWvxyr/2S6PCMAOlGgJw0+lkuxUxia6wTG//Zla9//VhyP3pmZLQ00trhmoWxAcaX2lHpSFvaKYlu+nQKq30HESJdMAqMxShd+frXnUZeZ5rN2VtoR11oS2fZrnUB0r46yvqgGlIvOew18lqPS5L7C/jiTDbVvV8CpBt2Sxvn+Ptop+R/YkCLs6U+qgPFVN/dIkC64ah0ZxmrS84a7JC7sozVxWs83UqDAOmOdyX3txT2Ue2MPzb2mg8bfM19mX2ke9yMAOmOTy58oT4F5zFrOvfxpZrJbmd8YQKkW43sjQs/1Uj+fcOjXXtqebwvSQ83CJBu2SlO0WS66FvdSzgpTvZlGhi+zTowFCDdcpq5sfVI7YC3G38P70obNz92XQ3ytAdkBEg3R777qmHun8Fe4+9hzyxk7upAMPWytADp5uj3jWpQ/1NQZ1FO9s139pH6YIwA6abt4r6QedZ9V/ahds1C5qYuR/+aPcAFSHcb30ujx5mrd5y/7tD7OY/3ox0ZBAqQnqknst6qhpmqI8auHX+tSyjvfLQzdRhtKT0B0v0OzWMpZqMuW3Vx7+k82tGxj3hm9f2ylYGIAOm22ghfqYZbV5d4XpTuHnutJ7Je+5hnou45NXMEXIB039tiI1Qd39zr4ibV23YUA5Fm9pwESPfVDfXnJeGD2DriU1z0XVdnV7+UZI8T75DzqN+m7h8SIP2wH52cO9SnH871ou/L/sBOsZR1W96UBg+9CJD+qI3zpWqY6ojxRenfFzDVNmRJdLo+xECkOQKkX+qGuiOZ07Hd09G4JdHpOoj6bPIAhgDp38X/U3GX+k3VWcfPpb832NUl0X8WD1u8qaOox2afXSdA+uc4Gu2eqriWTzrPf4fo8+Iu9V4P5gRIf6fN/yie2ntVe1Fvlm8uvIkQcTjjak5iEPK+9TciQHSGQmQy++rrs34VIteaeWx34c0IkH6ryzH/V9wgNmk9Wfb7vHo4o897QpM6ikHIdlfekABhPzrH96ris+pa/9/NPCaaifyzuNHwS0bLxp06Bbnkc6VcrOnXxl032J+ojn+r9848Lx4keJX6quv7z4ZlTXX8227M0Do3gxUgjNQL/6cYaX83LHd6XBej71NJ/4U+CdWb4o4iRO71vC5G36fS2QdtChA+1+BriHw/LFs9rIO631HvCt7RHK6ttp+/x2z2m572M4cRHJ3+Th4BwufULxH63+gAnvRkNnIa4em7L6Y3o30Rgfy0R4OROmOtm+T1YMFB19+sAOFrHUAdiX87LPeHZaGj73UnLnizjtup2xoij6Osdnz22qvHBQkQJrko6imtuzEbuduhIKkzrXoz3Pvi9NBtz+5eRT3XEHk4LMsden/70Y7e9W32KkCYRN0bqZujuzETeRhLEq0eA9+Nzmy7eCTJLNV9gedR7w+itDwj2Yv3UoOjl18dLUC4irOxC2YzOoB7jYwma1DsxGvfNeOY+4i9lrcxo62Dko1hGTQym/oY18Fu6fl+mQDhujOS3Sgr0QnUsp4sTE5ilLgb4bFfPHIj24zkdQTJRgxG1qNkCpM6cPoU5UO0Kce7BQhT7ARqWRvrADZieaIuc81qz+Q0RoSji30/fgqN/DPb0YBkEO1nLdpQ/fOdGQfKWbSjvZht7MefzVoFCDNamliK2chaBMlKdASjzmBwg2A5jXISF3oNsYP43Yfx74VGm07HwmQh2tFKBMlKtKnL7egmQTHejo7G2tF+/DczDQHCHJyU35aQRgZx4S/Fn8d/no91GAtj/4+z+OfRqHA8PEYXPt10Hp/vccwExvutUTsataHFsTC53I7Ooq0sxP/zZKyM2tKR6hYg5B9dTrIMsDDWgcCXBifakQCBz448QTtKzuPcARAgAAgQAAQIAAIEAAQIAAIEAAECgAABQIAAgAABQIAAIEAAECAACBAAECAACBAABAgAAgQAAQIAAgQAAQKAAAFAgAAgQABAgAAgQAAQII1ZUAUAAuSqzobl7bAcqwqA31tSBV90NCzPh2VbVQAIkEl9ivDYVRUAAmRS74bl55iBACBAvqrud7walpfxZwAEyFfV2cYv5WLDHAABMpG631GXrD6qCgABMqm631E3yw81BQABMonzcrHf8aLY7wAQIBM6jlmH/Q4AATIx+x0AAuTK3sfM48DHDiBAJjHa76j3d5z6yAEEyCTqfke9v+ONjxpAgEzK86wABMiV2e8AECBXYr8DQIBc2UnMOux3AAiQie2Vi/s77HcACJCJ2e8AECBXUvc7fi0Xz7Oy3wEgQCZivwNAgFyZ/Q4AAXJl7yM8fH8HgACZiP0OAAFyZXW/oz7P6rWPC0CATGq/XCxZ7fioAATI1yzGT/sdAALkSup+R12uqstWJz4iAAEyqZ+G5UMECQBJLZyf66cBuLpFVQCAAAFAgAAgQAAQIAAgQAAQIAAIEAAECAACBAAECAACBAABAoAAAUCAAIAAAUCAACBAABAgAAgQABAgAAgQAAQIAAIEgJ75fwEGABxQF9Ke8fBQAAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:95% 64%}
182
- #the-list .wpmu-update-row{background-color:#031f34;border:none;color:#c0d7eb;background-size:100px}
183
- #the-list .wpmu-update-row a{color:#3bb2df}
184
- #the-list .wpmu-update-row a:hover{color:#e8da42;-webkit-transition:0.2s}
185
- </style>
186
  <?php
187
  }
188
-
189
- function get_id_plugin($plugin_file) {
190
- return get_file_data( $plugin_file, array('name' => 'Plugin Name', 'id' => 'WDP ID', 'version' => 'Version') );
 
 
 
 
191
  }
192
-
193
  //simple check for updates
194
  function updates_check() {
195
  global $wp_version;
196
  $local_projects = array();
197
-
198
  //----------------------------------------------------------------------------------//
199
  //plugins directory
200
  //----------------------------------------------------------------------------------//
201
  $plugins_root = WP_PLUGIN_DIR;
202
- if( empty($plugins_root) ) {
203
  $plugins_root = ABSPATH . 'wp-content/plugins';
204
  }
205
-
206
- $plugins_dir = @opendir($plugins_root);
207
  $plugin_files = array();
208
  if ( $plugins_dir ) {
209
- while (($file = readdir( $plugins_dir ) ) !== false ) {
210
- if ( substr($file, 0, 1) == '.' )
211
  continue;
212
- if ( is_dir( $plugins_root.'/'.$file ) ) {
213
- $plugins_subdir = @ opendir( $plugins_root.'/'.$file );
 
214
  if ( $plugins_subdir ) {
215
- while (($subfile = readdir( $plugins_subdir ) ) !== false ) {
216
- if ( substr($subfile, 0, 1) == '.' )
217
  continue;
218
- if ( substr($subfile, -4) == '.php' )
 
219
  $plugin_files[] = "$file/$subfile";
 
220
  }
221
  }
222
  } else {
223
- if ( substr($file, -4) == '.php' )
224
  $plugin_files[] = $file;
 
225
  }
226
  }
227
  }
228
  @closedir( $plugins_dir );
229
  @closedir( $plugins_subdir );
230
-
231
- if ( $plugins_dir && !empty($plugin_files) ) {
232
  foreach ( $plugin_files as $plugin_file ) {
233
  if ( is_readable( "$plugins_root/$plugin_file" ) ) {
234
-
235
- unset($data);
236
  $data = $this->get_id_plugin( "$plugins_root/$plugin_file" );
237
-
238
- if ( isset($data['id']) && !empty($data['id']) ) {
239
- $local_projects[$data['id']]['type'] = 'plugin';
240
- $local_projects[$data['id']]['version'] = $data['version'];
241
- $local_projects[$data['id']]['filename'] = $plugin_file;
242
  }
243
  }
244
  }
245
  }
246
-
247
  //----------------------------------------------------------------------------------//
248
  // mu-plugins directory
249
  //----------------------------------------------------------------------------------//
250
  $mu_plugins_root = WPMU_PLUGIN_DIR;
251
- if( empty($mu_plugins_root) ) {
252
  $mu_plugins_root = ABSPATH . 'wp-content/mu-plugins';
253
  }
254
-
255
- if ( is_dir($mu_plugins_root) && $mu_plugins_dir = @opendir($mu_plugins_root) ) {
256
- while (($file = readdir( $mu_plugins_dir ) ) !== false ) {
257
- if ( substr($file, -4) == '.php' ) {
258
  if ( is_readable( "$mu_plugins_root/$file" ) ) {
259
-
260
- unset($data);
261
  $data = $this->get_id_plugin( "$mu_plugins_root/$file" );
262
-
263
- if ( isset($data['id']) && !empty($data['id']) ) {
264
- $local_projects[$data['id']]['type'] = 'mu-plugin';
265
- $local_projects[$data['id']]['version'] = $data['version'];
266
- $local_projects[$data['id']]['filename'] = $file;
267
  }
268
  }
269
  }
270
  }
271
- @closedir( $mu_plugins_dir );
272
  }
273
-
274
  //----------------------------------------------------------------------------------//
275
  // wp-content directory
276
  //----------------------------------------------------------------------------------//
277
  $content_plugins_root = WP_CONTENT_DIR;
278
- if( empty($content_plugins_root) ) {
279
  $content_plugins_root = ABSPATH . 'wp-content';
280
  }
281
-
282
- $content_plugins_dir = @opendir($content_plugins_root);
283
  $content_plugin_files = array();
284
  if ( $content_plugins_dir ) {
285
- while (($file = readdir( $content_plugins_dir ) ) !== false ) {
286
- if ( substr($file, 0, 1) == '.' )
287
  continue;
288
- if ( !is_dir( $content_plugins_root.'/'.$file ) ) {
289
- if ( substr($file, -4) == '.php' )
 
290
  $content_plugin_files[] = $file;
 
291
  }
292
  }
293
  }
294
  @closedir( $content_plugins_dir );
295
-
296
- if ( $content_plugins_dir && !empty($content_plugin_files) ) {
297
  foreach ( $content_plugin_files as $content_plugin_file ) {
298
  if ( is_readable( "$content_plugins_root/$content_plugin_file" ) ) {
299
- unset($data);
300
  $data = $this->get_id_plugin( "$content_plugins_root/$content_plugin_file" );
301
-
302
- if ( isset($data['id']) && !empty($data['id']) ) {
303
- $local_projects[$data['id']]['type'] = 'drop-in';
304
- $local_projects[$data['id']]['version'] = $data['version'];
305
- $local_projects[$data['id']]['filename'] = $content_plugin_file;
306
  }
307
  }
308
  }
309
  }
310
-
311
  //----------------------------------------------------------------------------------//
312
  //themes directory
313
  //----------------------------------------------------------------------------------//
314
  $themes_root = WP_CONTENT_DIR . '/themes';
315
- if ( empty($themes_root) ) {
316
  $themes_root = ABSPATH . 'wp-content/themes';
317
  }
318
-
319
- $themes_dir = @opendir($themes_root);
320
  $themes_files = array();
321
  $local_themes = array();
322
  if ( $themes_dir ) {
323
- while (($file = readdir( $themes_dir ) ) !== false ) {
324
- if ( substr($file, 0, 1) == '.' )
325
  continue;
326
- if ( is_dir( $themes_root.'/'.$file ) ) {
327
- $themes_subdir = @ opendir( $themes_root.'/'.$file );
 
328
  if ( $themes_subdir ) {
329
- while (($subfile = readdir( $themes_subdir ) ) !== false ) {
330
- if ( substr($subfile, 0, 1) == '.' )
331
  continue;
332
- if ( substr($subfile, -4) == '.css' )
 
333
  $themes_files[] = "$file/$subfile";
 
334
  }
335
  }
336
  } else {
337
- if ( substr($file, -4) == '.css' )
338
  $themes_files[] = $file;
 
339
  }
340
  }
341
  }
342
  @closedir( $themes_dir );
343
  @closedir( $themes_subdir );
344
-
345
- if ( $themes_dir && !empty($themes_files) ) {
346
  foreach ( $themes_files as $themes_file ) {
347
-
348
  //skip child themes
349
- if ( strpos( $themes_file, '-child' ) !== false )
350
  continue;
351
-
 
352
  if ( is_readable( "$themes_root/$themes_file" ) ) {
353
-
354
- unset($data);
355
  $data = $this->get_id_plugin( "$themes_root/$themes_file" );
356
-
357
- if ( isset($data['id']) && !empty($data['id']) ) {
358
- $local_projects[$data['id']]['type'] = 'theme';
359
- $local_projects[$data['id']]['filename'] = substr( $themes_file, 0, strpos( $themes_file, '/' ) );
360
-
361
  //keep record of all themes for 133 themepack
362
- if ($data['id'] == $this->theme_pack) {
363
- $local_themes[$themes_file]['id'] = $data['id'];
364
- $local_themes[$themes_file]['filename'] = substr( $themes_file, 0, strpos( $themes_file, '/' ) );
365
- $local_themes[$themes_file]['version'] = $data['version'];
366
  //increment 133 theme pack version to lowest in all of them
367
- if ( isset($local_projects[$data['id']]['version']) && version_compare($data['version'], $local_projects[$data['id']]['version'], '<') ) {
368
- $local_projects[$data['id']]['version'] = $data['version'];
369
- } else if ( !isset($local_projects[$data['id']]['version']) ) {
370
- $local_projects[$data['id']]['version'] = $data['version'];
371
  }
372
  } else {
373
- $local_projects[$data['id']]['version'] = $data['version'];
374
  }
375
  }
376
  }
377
  }
378
  }
379
- update_site_option('wdp_un_local_themes', $local_themes);
380
-
381
- update_site_option('wdp_un_local_projects', $local_projects);
382
-
383
  //now check the API
384
- $projects = '';
385
- foreach ($local_projects as $pid => $project)
386
- $projects .= "&p[$pid]=" . $project['version'];
387
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  //get WP/BP version string to help with support
389
- $wp = is_multisite() ? "WordPress Multisite $wp_version" : "WordPress $wp_version";
390
- if ( defined( 'BP_VERSION' ) )
391
- $wp .= ', BuddyPress ' . BP_VERSION;
392
-
 
393
  //add blog count if multisite
394
  $blog_count = is_multisite() ? get_blog_count() : 1;
395
-
396
- $url = $this->server_url . '?action=check&un-version=3.3.3&wp=' . urlencode($wp) . '&bcount=' . $blog_count . '&domain=' . urlencode(network_site_url()) . $projects;
397
-
398
  $options = array(
399
- 'timeout' => 15,
 
400
  'user-agent' => 'Dashboard Notification/' . $this->version
401
  );
402
-
403
- $response = wp_remote_get($url, $options);
404
- if ( wp_remote_retrieve_response_code($response) == 200 ) {
 
 
 
 
 
 
 
 
 
405
  $data = $response['body'];
406
  if ( $data != 'error' ) {
407
- $data = unserialize($data);
408
- if ( is_array($data) ) {
409
-
410
  //we've made it here with no errors, now check for available updates
411
- $remote_projects = isset($data['projects']) ? $data['projects'] : array();
412
- $updates = array();
413
-
414
  //check for updates
415
- if ( is_array($remote_projects) ) {
416
  foreach ( $remote_projects as $id => $remote_project ) {
417
- if ( isset($local_projects[$id]) && is_array($local_projects[$id]) ) {
418
  //match
419
- $local_version = $local_projects[$id]['version'];
420
  $remote_version = $remote_project['version'];
421
-
422
- if ( version_compare($remote_version, $local_version, '>') ) {
423
  //add to array
424
- $updates[$id] = $local_projects[$id];
425
- $updates[$id]['url'] = $remote_project['url'];
426
- $updates[$id]['instructions_url'] = $remote_project['instructions_url'];
427
- $updates[$id]['support_url'] = $remote_project['support_url'];
428
- $updates[$id]['name'] = $remote_project['name'];
429
- $updates[$id]['thumbnail'] = $remote_project['thumbnail'];
430
- $updates[$id]['version'] = $local_version;
431
- $updates[$id]['new_version'] = $remote_version;
432
- $updates[$id]['changelog'] = $remote_project['changelog'];
433
- $updates[$id]['autoupdate'] = $remote_project['autoupdate'];
434
  }
435
  }
436
  }
437
-
438
  //record results
439
- update_site_option('wdp_un_updates_available', $updates);
440
  } else {
441
  return false;
442
  }
@@ -444,249 +637,670 @@ if ( !class_exists('WPMUDEV_Dashboard_Notice3') ) {
444
  }
445
  }
446
  }
447
-
448
- function filter_plugin_info($res, $action, $args) {
449
  global $wp_version;
450
- $cur_wp_version = preg_replace('/-.*$/', '', $wp_version);
451
-
452
- //if in details iframe on update core page short-curcuit it
453
- if ( ($action == 'plugin_information' || $action == 'theme_information') && strpos($args->slug, 'wpmudev_install') !== false ) {
454
- $string = explode('-', $args->slug);
455
- $id = intval($string[1]);
456
- $updates = get_site_option('wdp_un_updates_available');
457
- if ( did_action( 'install_plugins_pre_plugin-information' ) && is_array( $updates ) && isset($updates[$id]) ) {
458
- echo '<iframe width="100%" height="100%" border="0" style="border:none;" src="' . $this->server_url . '?action=details&id=' . $id . '"></iframe>';
459
- exit;
460
  }
461
-
462
- $res = new stdClass;
463
- $res->name = $updates[$id]['name'];
464
- $res->slug = sanitize_title($updates[$id]['name']);
465
- $res->version = $updates[$id]['version'];
466
- $res->rating = 100;
467
- $res->homepage = $updates[$id]['url'];
468
  $res->download_link = '';
469
- $res->tested = $cur_wp_version;
470
-
471
  return $res;
472
  }
473
-
474
- if ( $action == 'plugin_information' && strpos($args->slug, 'install_wpmudev_dash') !== false ) {
475
- $res = new stdClass;
476
- $res->name = 'WPMU DEV Dashboard';
477
- $res->slug = 'wpmu-dev-dashboard';
478
- $res->version = '';
479
- $res->rating = 100;
480
- $res->homepage = 'http://premium.wpmudev.org/project/wpmu-dev-dashboard/';
481
- $res->download_link = $this->server_url . "?action=install_wpmudev_dash";
482
- $res->tested = $cur_wp_version;
483
-
484
  return $res;
485
  }
486
-
487
  return $res;
488
  }
489
-
490
  function filter_plugin_rows() {
491
- if ( !current_user_can( 'update_plugins' ) )
492
  return;
493
-
494
- $updates = get_site_option('wdp_un_updates_available');
495
- if ( is_array($updates) && count($updates) ) {
 
 
 
 
496
  foreach ( $updates as $id => $plugin ) {
497
  if ( $plugin['autoupdate'] != '2' ) {
498
  if ( $plugin['type'] == 'theme' ) {
499
  remove_all_actions( 'after_theme_row_' . $plugin['filename'] );
500
- add_action('after_theme_row_' . $plugin['filename'], array( &$this, 'plugin_row'), 9, 2 );
501
  } else {
502
  remove_all_actions( 'after_plugin_row_' . $plugin['filename'] );
503
- add_action('after_plugin_row_' . $plugin['filename'], array( &$this, 'plugin_row'), 9, 2 );
 
 
 
504
  }
505
  }
506
  }
507
  }
508
-
509
- $local_themes = get_site_option('wdp_un_local_themes');
510
- if ( is_array($local_themes) && count($local_themes) ) {
511
  foreach ( $local_themes as $id => $plugin ) {
512
  remove_all_actions( 'after_theme_row_' . $plugin['filename'] );
513
  //only add the notice if specific version is wrong
514
- if ( isset($updates[$this->theme_pack]) && version_compare($plugin['version'], $updates[$this->theme_pack]['new_version'], '<') ) {
515
- add_action('after_theme_row_' . $plugin['filename'], array( &$this, 'themepack_row'), 9, 2 );
516
  }
517
  }
518
  }
519
  }
520
-
521
  function filter_plugin_count( $value ) {
522
-
 
 
523
  //remove any conflicting slug local WPMU DEV plugins from WP update notifications
524
- $local_projects = get_site_option('wdp_un_local_projects');
525
- if ( is_array($local_projects) && count($local_projects) ) {
526
  foreach ( $local_projects as $id => $plugin ) {
527
- if (isset($value->response[$plugin['filename']]))
528
- unset($value->response[$plugin['filename']]);
 
529
  }
530
  }
531
-
532
- $updates = get_site_option('wdp_un_updates_available');
533
- if ( is_array($updates) && count($updates) ) {
534
  foreach ( $updates as $id => $plugin ) {
535
  if ( $plugin['type'] != 'theme' && $plugin['autoupdate'] != '2' ) {
536
-
537
  //build plugin class
538
- $object = new stdClass;
539
- $object->url = $plugin['url'];
540
- $object->slug = "wpmudev_install-$id";
541
- $object->upgrade_notice = $plugin['changelog'];
542
  $object->new_version = $plugin['new_version'];
543
- $object->package = '';
544
-
 
545
  //add to class
546
- $value->response[$plugin['filename']] = $object;
547
  }
548
  }
549
  }
550
-
551
  return $value;
552
  }
553
-
554
  function filter_theme_count( $value ) {
555
-
556
- $updates = get_site_option('wdp_un_updates_available');
557
- if ( is_array($updates) && count($updates) ) {
558
  foreach ( $updates as $id => $theme ) {
559
  if ( $theme['type'] == 'theme' && $theme['autoupdate'] != '2' ) {
 
 
 
560
  //build theme listing
561
- $value->response[$theme['filename']]['url'] = $this->server_url . '?action=details&id=' . $id;
562
- $value->response[$theme['filename']]['new_version'] = $theme['new_version'];
563
- $value->response[$theme['filename']]['package'] = '';
 
564
  }
565
  }
566
  }
567
-
568
  //filter 133 theme pack themes from the list unless update is available
569
- $local_themes = get_site_option('wdp_un_local_themes');
570
- if ( is_array($local_themes) && count($local_themes) ) {
571
  foreach ( $local_themes as $id => $theme ) {
 
 
572
  //add to count only if new version exists, otherwise remove
573
- if (isset($updates[$theme['id']]) && isset($updates[$theme['id']]['new_version']) && version_compare($theme['version'], $updates[$theme['id']]['new_version'], '<')) {
574
- $value->response[$theme['filename']]['new_version'] = $updates[$theme['id']]['new_version'];
575
- $value->response[$theme['filename']]['package'] = '';
576
- } else if (isset($value) && isset($value->response) && isset($theme['filename']) && isset($value->response[$theme['filename']])) {
577
- unset($value->response[$theme['filename']]);
578
  }
579
  }
580
  }
581
-
582
  return $value;
583
  }
584
-
585
  function plugin_row( $file, $plugin_data ) {
586
-
587
  //get new version and update url
588
- $updates = get_site_option('wdp_un_updates_available');
589
- if ( is_array($updates) && count($updates) ) {
590
  foreach ( $updates as $id => $plugin ) {
591
- if ($plugin['filename'] == $file) {
592
  $project_id = $id;
593
- $version = $plugin['new_version'];
594
  $plugin_url = $plugin['url'];
595
  $autoupdate = $plugin['autoupdate'];
596
- $filename = $plugin['filename'];
597
- $type = $plugin['type'];
598
  break;
599
  }
600
  }
601
  } else {
602
  return false;
603
  }
604
-
605
- $plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array());
606
- $plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags );
607
-
608
- $info_url = $this->server_url . '?action=details&id=' . $project_id . '&TB_iframe=true&width=640&height=800';
609
- if ( file_exists(WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php') ) {
610
- $message = "Activate WPMU DEV Dashboard";
 
 
 
 
 
 
 
611
  $action_url = $this->activate_url();
612
  } else { //dashboard not installed at all
613
- $message = "Install WPMU DEV Dashboard";
614
  $action_url = $this->auto_install_url();
615
  }
616
-
617
- if ( current_user_can('update_plugins') ) {
618
- echo '<tr class="plugin-update-tr"><td colspan="3" class="plugin-update colspanchange"><div class="update-message wpmu-update-row">';
619
- printf( 'There is a new version of %1$s available on WPMU DEV. <a href="%2$s" class="thickbox" title="%3$s">View version %4$s details</a> or <a href="%5$s">%6$s</a> to update.', $plugin_name, esc_url($info_url), esc_attr($plugin_name), $version, esc_url($action_url), $message );
620
- echo '</div></td></tr>';
621
  }
622
  }
623
-
624
  function themepack_row( $file, $plugin_data ) {
625
-
626
  //get new version and update url
627
- $updates = get_site_option('wdp_un_updates_available');
628
- if ( isset($updates[$this->theme_pack]) ) {
629
- $plugin = $updates[$this->theme_pack];
630
  $project_id = $this->theme_pack;
631
- $version = $plugin['new_version'];
632
  $plugin_url = $plugin['url'];
633
  } else {
634
  return false;
635
  }
636
-
637
- $plugins_allowedtags = array('a' => array('href' => array(),'title' => array()),'abbr' => array('title' => array()),'acronym' => array('title' => array()),'code' => array(),'em' => array(),'strong' => array());
638
- $plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags );
639
-
640
- $info_url = $this->server_url . '?action=details&id=' . $project_id . '&TB_iframe=true&width=640&height=800';
641
- if ( file_exists(WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php') ) {
642
- $message = "Activate WPMU DEV Dashboard";
 
 
 
 
 
 
 
643
  $action_url = $this->activate_url();
644
  } else { //dashboard not installed at all
645
- $message = "Install WPMU DEV Dashboard";
646
  $action_url = $this->auto_install_url();
647
  }
648
-
649
- if ( current_user_can('update_themes') ) {
650
- echo '<tr class="plugin-update-tr"><td colspan="3" class="plugin-update colspanchange"><div class="update-message">';
651
- printf( 'There is a new version of %1$s available on WPMU DEV. <a href="%2$s" class="thickbox" title="%3$s">View version %4$s details</a> or <a href="%5$s">%6$s</a> to update.', $plugin_name, esc_url($info_url), esc_attr($plugin_name), $version, esc_url($action_url), $message );
652
- echo '</div></td></tr>';
653
  }
654
  }
655
-
656
  function disable_checkboxes() {
657
-
658
- $updates = get_site_option('wdp_un_updates_available');
659
- if ( !is_array( $updates ) || ( is_array( $updates ) && !count( $updates ) ) ) {
660
  return;
661
  }
662
-
663
- $jquery = '';
664
- foreach ( (array) $updates as $id => $plugin) {
665
- $jquery .= "<script type='text/javascript'>jQuery(\"input:checkbox[value='".esc_attr($plugin['filename'])."']\").remove();</script>\n";
 
 
 
 
 
 
 
 
 
 
 
 
666
  }
667
-
668
  //disable checkboxes for 133 theme pack themes
669
- $local_themes = get_site_option('wdp_un_local_themes');
670
- if ( is_array($local_themes) && count($local_themes) ) {
671
  foreach ( $local_themes as $id => $theme ) {
672
- $jquery .= "<script type='text/javascript'>jQuery(\"input:checkbox[value='".esc_attr($theme['filename'])."']\").remove();</script>\n";
 
673
  }
674
  }
 
 
 
675
  echo $jquery;
676
  }
677
-
678
- function set_activate_flag($plugin) {
679
  $data = $this->get_id_plugin( WP_PLUGIN_DIR . '/' . $plugin );
680
- if ( isset($data['id']) && !empty($data['id']) ) {
681
- update_site_option('wdp_un_activated_flag', 1);
682
  }
683
  }
684
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
685
  }
686
- $WPMUDEV_Dashboard_Notice3 = new WPMUDEV_Dashboard_Notice3();
 
687
  }
688
 
689
- //disable older version
690
- if ( !class_exists('WPMUDEV_Dashboard_Notice') ) {
691
- class WPMUDEV_Dashboard_Notice {}
 
 
 
 
 
 
692
  }
1
  <?php
2
  /////////////////////////////////////////////////////////////////////////
3
  /* -------- WPMU DEV Dashboard Notice - Aaron Edwards (Incsub) ------- */
4
+ /* This provides notices of available updates for our premium products */
5
+ if ( ! class_exists( 'WPMUDEV_Dashboard_Notice4' ) ) {
6
+ class WPMUDEV_Dashboard_Notice4 {
7
+
8
+ var $version = '4.2';
9
  var $screen_id = false;
10
  var $product_name = false;
11
  var $product_update = false;
12
  var $theme_pack = 128;
13
+ var $server_url = 'https://premium.wpmudev.org/api/dashboard/v1/';
14
  var $update_count = 0;
15
+
16
  function __construct() {
17
  add_action( 'init', array( &$this, 'init' ) );
18
+ add_action( 'plugins_loaded', array( &$this, 'remove_older' ), 5 );
19
+ }
20
+
21
+ function remove_older() {
22
+ global $WPMUDEV_Dashboard_Notice3;
23
+
24
+ //remove 3.0 notices
25
+ if ( is_object( $WPMUDEV_Dashboard_Notice3 ) ) {
26
+ remove_action( 'init', array( $WPMUDEV_Dashboard_Notice3, 'init' ) );
27
+ remove_action( 'plugins_loaded', array( $WPMUDEV_Dashboard_Notice3, 'init' ) );
28
+ } else if ( method_exists( 'WPMUDEV_Dashboard_Notice3', 'init' ) ) { //if class is not in global (some projects included inside a method), we have to use a hacky way to remove the filter
29
+ $this->deregister_hook( 'init', 'WPMUDEV_Dashboard_Notice3', 'init', 10 );
30
+ $this->deregister_hook( 'plugins_loaded', 'WPMUDEV_Dashboard_Notice3', 'init', 10 );
31
+ }
32
+
33
+ //remove version 2.0
34
+ if ( method_exists( 'WPMUDEV_Dashboard_Notice', 'init' ) ) {
35
+ $this->deregister_hook( 'init', 'WPMUDEV_Dashboard_Notice', 'init', 10 );
36
+ $this->deregister_hook( 'plugins_loaded', 'WPMUDEV_Dashboard_Notice', 'init', 10 );
37
+ }
38
+
39
+ //remove version 1.0
40
+ remove_action( 'admin_notices', 'wdp_un_check', 5 );
41
+ remove_action( 'network_admin_notices', 'wdp_un_check', 5 );
42
+ }
43
+
44
+ /* Adapted from: https://github.com/herewithme/wp-filters-extras/ - Copyright 2012 Amaury Balmer - amaury@beapi.fr */
45
+ function deregister_hook( $hook_name, $class_name, $method_name, $priority ) {
46
+ global $wp_filter;
47
+
48
+ // Take only filters on right hook name and priority
49
+ if ( ! isset( $wp_filter[ $hook_name ][ $priority ] ) || ! is_array( $wp_filter[ $hook_name ][ $priority ] ) ) {
50
+ return false;
51
+ }
52
+
53
+ // Loop on filters registered
54
+ foreach ( (array) $wp_filter[ $hook_name ][ $priority ] as $unique_id => $filter_array ) {
55
+ // Test if filter is an array ! (always for class/method)
56
+ if ( isset( $filter_array['function'] ) && is_array( $filter_array['function'] ) ) {
57
+ // Test if object is a class, class and method is equal to param !
58
+ if ( is_object( $filter_array['function'][0] ) && get_class( $filter_array['function'][0] ) && get_class( $filter_array['function'][0] ) == $class_name && $filter_array['function'][1] == $method_name ) {
59
+ if ( class_exists( 'WP_Hook' ) ) { //introduced in WP 4.7 https://make.wordpress.org/core/2016/09/08/wp_hook-next-generation-actions-and-filters/
60
+ unset( $wp_filter[ $hook_name ]->callbacks[ $priority ][ $unique_id ] );
61
+ } else {
62
+ unset( $wp_filter[ $hook_name ][ $priority ][ $unique_id ] );
63
+ }
64
+ return true;
65
+ }
66
+ }
67
+ }
68
+
69
+ return false;
70
  }
71
+
72
  function init() {
73
  global $wpmudev_un;
74
+
75
+ if ( class_exists( 'WPMUDEV_Dashboard' ) || ( isset( $wpmudev_un->version ) && version_compare( $wpmudev_un->version, '3.4', '<' ) ) ) {
76
  return;
77
+ }
78
+
79
  // Schedule update cron on main site only
80
  if ( is_main_site() ) {
81
  if ( ! wp_next_scheduled( 'wpmudev_scheduled_jobs' ) ) {
82
  wp_schedule_event( time(), 'twicedaily', 'wpmudev_scheduled_jobs' );
83
  }
84
 
85
+ add_action( 'wpmudev_scheduled_jobs', array( $this, 'updates_check' ) );
86
  }
87
+ add_action( 'delete_site_transient_update_plugins', array(
88
+ &$this,
89
+ 'updates_check'
90
+ ) ); //refresh after upgrade/install
91
+ add_action( 'delete_site_transient_update_themes', array(
92
+ &$this,
93
+ 'updates_check'
94
+ ) ); //refresh after upgrade/install
95
+
96
  if ( is_admin() && current_user_can( 'install_plugins' ) ) {
97
+
98
  add_action( 'site_transient_update_plugins', array( &$this, 'filter_plugin_count' ) );
99
  add_action( 'site_transient_update_themes', array( &$this, 'filter_theme_count' ) );
100
+ add_filter( 'plugins_api', array(
101
+ &$this,
102
+ 'filter_plugin_info'
103
+ ), 101, 3 ); //run later to work with bad autoupdate plugins
104
+ add_filter( 'themes_api', array(
105
+ &$this,
106
+ 'filter_plugin_info'
107
+ ), 101, 3 ); //run later to work with bad autoupdate plugins
108
+ add_action( 'load-plugins.php', array( &$this, 'filter_plugin_rows' ), 21 ); //make sure it runs after WP's
109
+ add_action( 'load-themes.php', array( &$this, 'filter_plugin_rows' ), 21 ); //make sure it runs after WP's
110
  add_action( 'core_upgrade_preamble', array( &$this, 'disable_checkboxes' ) );
111
  add_action( 'activated_plugin', array( &$this, 'set_activate_flag' ) );
112
+ add_action( 'wp_ajax_wdpun-changelog', array( &$this, 'popup_changelog_ajax' ) );
113
+ add_action( 'wp_ajax_wdpun-dismiss', array( &$this, 'dismiss_ajax' ) );
114
+
 
 
 
 
115
  //if dashboard is installed but not activated
116
+ if ( file_exists( WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php' ) ) {
117
+ if ( ! get_site_option( 'wdp_un_autoactivated' ) ) {
118
  //include plugin API if necessary
119
+ if ( ! function_exists( 'activate_plugin' ) ) {
120
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
121
+ }
122
+ $result = activate_plugin( '/wpmudev-updates/update-notifications.php', network_admin_url( 'admin.php?page=wpmudev' ), is_multisite() );
123
+ if ( ! is_wp_error( $result ) ) { //if autoactivate successful don't show notices
124
+ update_site_option( 'wdp_un_autoactivated', 1 );
125
+
126
  return;
127
  }
128
  }
129
+
130
  add_action( 'admin_print_styles', array( &$this, 'notice_styles' ) );
131
+ add_action( 'admin_print_footer_scripts', array( &$this, 'notice_scripts' ) );
132
  add_action( 'all_admin_notices', array( &$this, 'activate_notice' ), 5 );
133
  } else { //dashboard not installed at all
134
+ if ( get_site_option( 'wdp_un_autoactivated' ) ) {
135
+ update_site_option( 'wdp_un_autoactivated', 0 );//reset flag when dashboard is deleted
136
  }
137
  add_action( 'admin_print_styles', array( &$this, 'notice_styles' ) );
138
+ add_action( 'admin_print_footer_scripts', array( &$this, 'notice_scripts' ) );
139
  add_action( 'all_admin_notices', array( &$this, 'install_notice' ), 5 );
140
  }
141
  }
142
  }
143
+
144
  function is_allowed_screen() {
145
  global $wpmudev_notices;
146
+ $screen = get_current_screen();
147
+ if ($screen && is_object($screen)) $this->screen_id = $screen->id;
148
+
149
  //Show special message right after plugin activation
150
+ if ( in_array( $this->screen_id, array(
151
+ 'plugins',
152
+ 'plugins-network'
153
+ ) ) && ( isset( $_GET['activate'] ) || isset( $_GET['activate-multi'] ) )
154
+ ) {
155
+ $activated = get_site_option( 'wdp_un_activated_flag' );
156
+ if ( $activated === false ) {
157
+ $activated = 1;
158
+ } //on first encounter of new installed notice show
159
+ if ( $activated ) {
160
+ if ( $activated >= 2 ) {
161
+ update_site_option( 'wdp_un_activated_flag', 0 );
162
+ } else {
163
+ update_site_option( 'wdp_un_activated_flag', 2 );
164
+ }
165
+
166
  return true;
167
  }
168
  }
169
+
170
+ //check dismiss flag
171
+ $dismissed = get_site_option( 'wdp_un_dismissed' );
172
+ if ( $dismissed && $dismissed > strtotime( '-1 week' ) ) {
173
+ return false;
174
+ }
175
+
176
  //always show on certain core pages if updates are available
177
+ $updates = get_site_option( 'wdp_un_updates_available' );
178
+ if ( is_array( $updates ) && count( $updates ) ) {
179
+ $this->update_count = count( $updates );
180
+ if ( in_array( $this->screen_id, array(
181
+ 'update-core',
182
+ 'update-core-network'
183
+ ) ) ) {
184
  return true;
185
+ }
186
  }
187
+
188
  //check our registered plugins for hooks
189
+ if ( isset( $wpmudev_notices ) && is_array( $wpmudev_notices ) ) {
190
  foreach ( $wpmudev_notices as $product ) {
191
+ if ( isset( $product['screens'] ) && is_array( $product['screens'] ) && in_array( $this->screen_id, $product['screens'] ) ) {
192
  $this->product_name = $product['name'];
193
  //if this plugin needs updating flag it
194
+ if ( isset( $product['id'] ) && isset( $updates[ $product['id'] ] ) ) {
195
  $this->product_update = true;
196
+ }
197
+
198
  return true;
199
  }
200
  }
201
  }
202
+
 
 
203
  return false;
204
  }
205
+
206
  function auto_install_url() {
207
  $function = is_multisite() ? 'network_admin_url' : 'admin_url';
208
+
209
+ return wp_nonce_url( $function( "update.php?action=install-plugin&plugin=install_wpmudev_dash" ), "install-plugin_install_wpmudev_dash" );
210
  }
211
+
212
  function activate_url() {
213
  $function = is_multisite() ? 'network_admin_url' : 'admin_url';
214
+
215
+ return wp_nonce_url( $function( 'plugins.php?action=activate&plugin=wpmudev-updates%2Fupdate-notifications.php' ), 'activate-plugin_wpmudev-updates/update-notifications.php' );
216
  }
217
+
218
  function install_notice() {
219
+ if ( ! $this->is_allowed_screen() ) return; ?>
220
 
221
+ <div class="notice wdpun-notice" style="display: none;">
222
+
223
+ <input type="hidden" name="msg_id" value="<?php _e( 'install', 'wpmudev' ); ?>" />
224
+
225
+ <div class="wdpun-notice-logo"></div>
226
+ <div class="wdpun-notice-message">
227
+ <?php
228
+ if ( $this->product_name ) {
229
+ if ( $this->product_update ) {
230
+ printf( __( 'Important updates are available for <strong>%s</strong>. Install the free WPMU DEV Dashboard plugin now for updates and support!', 'wpmudev' ), esc_html( $this->product_name ) );
231
+ } else {
232
+ printf( __( '<strong>%s</strong> is almost ready - install the free WPMU DEV Dashboard plugin for updates and support!', 'wpmudev' ), esc_html( $this->product_name ) );
233
+ }
234
+
235
+ } else if ( $this->update_count ) {
236
+ _e( 'Important updates are available for your WPMU DEV plugins/themes. Install the free WPMU DEV Dashboard plugin now for updates and support!', 'wpmudev' );
237
+ } else {
238
+ _e( 'Almost ready - install the free WPMU DEV Dashboard plugin for updates and support!', 'wpmudev' );
239
+ }
240
+ ?>
241
+ </div><!-- end wdpun-notice-message -->
242
+ <div class="wdpun-notice-cta">
243
+ <a href="<?php echo $this->auto_install_url(); ?>"
244
+ class="wdpun-button wdpun-button-small"><?php _e( 'Install Plugin', 'wpmudev' ); ?></a>
245
+
246
+ <button class="wdpun-button wdpun-button-notice-dismiss"
247
+ data-msg="<?php _e( 'Saving...', 'wpmudev' ); ?>">
248
+ <?php _e( 'Dismiss', 'wpmudev' ); ?>
249
+ </button>
250
+ </div><!-- end wdpun-notice-cta -->
251
+
252
+ </div><!-- end notice wdpun-notice -->
253
+
254
+ <?php
255
+
256
+ return;
257
  }
258
+
259
  function activate_notice() {
260
+ if ( ! $this->is_allowed_screen() ) return; ?>
261
+
262
+ <div class="notice wdpun-notice" style="display: none;">
263
+
264
+ <input type="hidden" name="msg_id" value="<?php _e( 'activate', 'wpmudev' ); ?>" />
265
+
266
+ <div class="wdpun-notice-logo"><span></span></div>
267
+ <div class="wdpun-notice-message">
268
+ <?php
269
+ if ( $this->product_name ) {
270
+ if ( $this->product_update ) {
271
+ printf( __( 'Important updates are available for <strong>%s</strong>. Activate the WPMU DEV Dashboard to update now!', 'wpmudev' ), esc_html( $this->product_name ) );
272
+ } else {
273
+ printf( __( 'Just one more step to enable updates and support for <strong>%s</strong>!', 'wpmudev' ), esc_html( $this->product_name ) );
274
+ }
275
+
276
+ } else if ( $this->update_count ) {
277
+ _e( 'Important updates are available for your WPMU DEV plugins/themes. Activate the WPMU DEV Dashboard to update now!', 'wpmudev' );
278
+ } else {
279
+ _e( "Just one more step - activate the WPMU DEV Dashboard plugin and you're all done!", 'wpmudev' );
280
+ }
281
+ ?>
282
+ </div><!-- end wdpun-notice-message -->
283
+ <div class="wdpun-notice-cta">
284
+ <a href="<?php echo $this->activate_url(); ?>"
285
+ class="wdpun-button wdpun-button-small"><?php _e( 'Activate WPMU DEV Dashboard', 'wpmudev' ); ?></a>
286
+
287
+ <button class="wdpun-button wdpun-button-notice-dismiss"
288
+ data-msg="<?php _e( 'Saving...', 'wpmudev' ); ?>">
289
+ <?php _e( 'Dismiss', 'wpmudev' ); ?>
290
+ </button>
291
+ </div><!-- end wdpun-notice-cta -->
292
+
293
+ </div><!-- end notice wdpun-notice -->
294
+
295
+ <?php
296
+
297
+ return;
298
  }
299
+
300
  function notice_styles() {
301
  if ( !$this->is_allowed_screen() ) return;
302
  ?>
303
+ <style type="text/css" media="all">
304
+ .cf:after{content:"";display:table;clear:both}@media only screen and (min-width: 1200px){.hide-to-large{display:none}}@media only screen and (min-width: 1140px){.hide-to-desktop{display:none}}.wrap>.wdpun-notice.notice,.wrap #header>.wdpun-notice.notice{width:100%}.wrap #header>.wdpun-notice.notice{box-shadow:none}.wdpun-notice *,.wdpun-notice *:after,.wdpun-notice *:before{box-sizing:border-box}.wdpun-notice.notice{background:#fff;border:1px solid #E5E5E5;border-radius:6px;box-shadow:0 1px 1px 0 rgba(0,0,0,0.05);clear:both;display:block;font:400 13px/20px "Open Sans",Arial,sans-serif;overflow:hidden;margin:10px 20px 20px 0;min-height:80px;padding:0;position:relative;text-align:center;z-index:1}.wdpun-notice.notice.loading:before{background-color:rgba(255,255,255,0.7);bottom:0;content:attr(data-message);font-size:22px;font-weight:600;left:0;line-height:80px;position:absolute;right:0;text-align:center;top:0;z-index:5}.wdpun-notice.notice.loading>div{-webkit-filter:blur(2px);filter:blur(2px)}.wdpun-notice-logo{background-color:transparent;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjU2cHgiIGhlaWdodD0iNTZweCIgdmlld0JveD0iMCAwIDU2IDU2IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCAzLjguMyAoMjk4MDIpIC0gaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoIC0tPgogICAgPHRpdGxlPndwbXVkZXYtc3ZnPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9ImlQYWQtUHJvLUxhbmRzY2FwZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIzLjAwMDAwMCwgLTIyLjAwMDAwMCkiPgogICAgICAgICAgICA8ZyBpZD0id3BtdWRldi1zdmciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIzLjAwMDAwMCwgMjIuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMjgsNTYgQzEyLjUzNTg3MSw1NiAwLDQzLjQ2NDEyOSAwLDI4IEMwLDEyLjUzNjc3NDIgMTIuNTM1ODcxLDAgMjgsMCBDNDMuNDY0MTI5LDAgNTYsMTIuNTM2Nzc0MiA1NiwyOCBDNTYsNDMuNDY0MTI5IDQzLjQ2NDEyOSw1NiAyOCw1NiBMMjgsNTYgWiIgaWQ9IkZpbGwtMSIgZmlsbD0iI0ZGRDAwNSI+PC9wYXRoPgogICAgICAgICAgICAgICAgPHBhdGggZD0iTTUxLjQ4Mzg3MSwyOCBDNTEuNDgzODcxLDQwLjk2OTQxOTQgNDAuOTY5NDE5NCw1MS40ODM4NzEgMjgsNTEuNDgzODcxIEMxNS4wMzA1ODA2LDUxLjQ4Mzg3MSA0LjUxNjEyOTAzLDQwLjk2OTQxOTQgNC41MTYxMjkwMywyOCBDNC41MTYxMjkwMywxNS4wMzA1ODA2IDE1LjAzMDU4MDYsNC41MTYxMjkwMyAyOCw0LjUxNjEyOTAzIEM0MC45Njk0MTk0LDQuNTE2MTI5MDMgNTEuNDgzODcxLDE1LjAzMDU4MDYgNTEuNDgzODcxLDI4IiBpZD0iRmlsbC0zIiBmaWxsPSIjMzMzMzMzIj48L3BhdGg+CiAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNDIuNzc4ODUxNiwzMi42NzY2MzIzIEw0Mi43Nzg4NTE2LDEyLjUzMTA4MzkgTDM5LjUzMDg1MTYsMTUuMDU4MzA5NyBMMzkuNTMwODUxNiwzMi42NzY2MzIzIEwzOS41MjcyMzg3LDMyLjY3NjYzMjMgQzM5LjUyNzIzODcsMzMuNzA4MTE2MSAzOC43ODI5ODA2LDM0LjU0NDUwMzIgMzcuODY2MjA2NSwzNC41NDQ1MDMyIEMzNi45NDY3MjI2LDM0LjU0NDUwMzIgMzYuMjAyNDY0NSwzMy43MDgxMTYxIDM2LjIwMjQ2NDUsMzIuNjc2NjMyMyBMMzYuMjA3ODgzOSwyMy4zMjM3MjkgQzM2LjIwNzg4MzksMjAuMjc0NDM4NyAzNC4wMDU4MTk0LDE3LjgwMTQwNjUgMzEuMjkwNzIyNiwxNy44MDE0MDY1IEMyOC41NzM4MTk0LDE3LjgwMTQwNjUgMjYuMzcyNjU4MSwyMC4yNzQ0Mzg3IDI2LjM3MjY1ODEsMjMuMzIzNzI5IEwyNi4zNzI2NTgxLDMyLjY3NjYzMjMgQzI2LjM3MjY1ODEsMzMuNzA4MTE2MSAyNS42Mjg0LDM0LjU0NDUwMzIgMjQuNzA4OTE2MSwzNC41NDQ1MDMyIEMyMy43OTIxNDE5LDM0LjU0NDUwMzIgMjMuMDQ1MTc0MiwzMy43MDgxMTYxIDIzLjA0NTE3NDIsMzIuNjc2NjMyMyBMMjMuMDUyNCwyMy4zMjM3MjkgQzIzLjA1MjQsMjAuMjc0NDM4NyAyMC44NTEyMzg3LDE3LjgwMTQwNjUgMTguMTM2MTQxOSwxNy44MDE0MDY1IEMxNS40MjEwNDUyLDE3LjgwMTQwNjUgMTMuMjE4OTgwNiwyMC4yNzQ0Mzg3IDEzLjIxODk4MDYsMjMuMzIzNzI5IEwxMy4yMjA3ODcxLDIzLjMyMzcyOSBMMTMuMjIwNzg3MSw0My40NjkyNzc0IEwxNi40Njg3ODcxLDQwLjk0MTE0ODQgTDE2LjQ3MjQsMjMuMzIzNzI5IEMxNi40NzI0LDIyLjI5MjI0NTIgMTcuMjE2NjU4MSwyMS40NTU4NTgxIDE4LjEzNjE0MTksMjEuNDU1ODU4MSBDMTkuMDU0NzIyNiwyMS40NTU4NTgxIDE5Ljc5OTg4MzksMjIuMjkyMjQ1MiAxOS43OTk4ODM5LDIzLjMyMzcyOSBMMTkuNzkyNjU4MSwzMi42NzY2MzIzIEMxOS43OTI2NTgxLDM1LjcyNTkyMjYgMjEuOTkzODE5NCwzOC4xOTg5NTQ4IDI0LjcwODkxNjEsMzguMTk4OTU0OCBDMjcuNDI0MDEyOSwzOC4xOTg5NTQ4IDI5LjYyNTE3NDIsMzUuNzI1OTIyNiAyOS42MjUxNzQyLDMyLjY3NjYzMjMgTDI5LjYyNDI3MSwzMi42NzY2MzIzIEwyOS42MjY5ODA2LDIzLjMyMzcyOSBDMjkuNjI2OTgwNiwyMi4yOTIyNDUyIDMwLjM3MjE0MTksMjEuNDU1ODU4MSAzMS4yOTA3MjI2LDIxLjQ1NTg1ODEgQzMyLjIwODQsMjEuNDU1ODU4MSAzMi45NTI2NTgxLDIyLjI5MjI0NTIgMzIuOTUyNjU4MSwyMy4zMjM3MjkgTDMyLjk0NzIzODcsMzIuNjc2NjMyMyBDMzIuOTQ3MjM4NywzNS43MjU5MjI2IDM1LjE0OTMwMzIsMzguMTk4OTU0OCAzNy44NjYyMDY1LDM4LjE5ODk1NDggQzQwLjU4MDQsMzguMTk4OTU0OCA0Mi43ODA2NTgxLDM1LjcyNTkyMjYgNDIuNzgwNjU4MSwzMi42NzY2MzIzIEw0Mi43Nzg4NTE2LDMyLjY3NjYzMjMgTDQyLjc3ODg1MTYsMzIuNjc2NjMyMyBaIiBpZD0iRmlsbC01IiBmaWxsPSIjRjlFQzFDIj48L3BhdGg+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==);background-repeat:no-repeat;background-position:50% 50%;display:block;height:56px;margin:10px auto 0;width:56px}.wdpun-notice .wdpun-notice-message{color:#23282D;display:block;font-family:"Open Sans",Arial,sans-serif;font-size:13px;line-height:20px;padding:10px}.wdpun-notice .wdpun-notice-message strong{font-weight:600}.wdpun-notice .wdpun-button{background:#00ACCA;border:1px solid #0087B9;border-radius:2px;color:#fff;cursor:pointer;display:block;font-weight:500;font-size:16px;height:auto;line-height:18px;margin:0;padding:10px 20px;text-decoration:none;-webkit-transition:color 0.3s, opacity 0.3s, background 0.3s;transition:color 0.3s, opacity 0.3s, background 0.3s;white-space:nowrap}.wdpun-notice .wdpun-button:hover:not(:focus):not(:active){background-color:#0093B1;color:#fff}.wdpun-notice .wdpun-button:focus,.wdpun-notice .wdpun-button:active{background:#0082a1;background:-webkit-linear-gradient(top, #0082a1 0%, #008fae 100%);background:linear-gradient(to bottom, #0082a1 0%, #008fae 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#0082a1', endColorstr='#008fae',GradientType=0 );border-color:transparent;color:#fff;outline-color:transparent;outline-style:none}.wdpun-notice .wdpun-button-small{padding:5px 15px}.wdpun-notice .wdpun-button-notice-dismiss{background:transparent;border:none;border-radius:0;color:#C5C5C5;padding:0;text-transform:none;-webkit-transition:color 0.3s;transition:color 0.3s}.wdpun-notice .wdpun-button-notice-dismiss:hover:not(:focus):not(:active),.wdpun-notice .wdpun-button-notice-dismiss:active,.wdpun-notice .wdpun-button-notice-dismiss:focus{background:transparent;color:#666}.wdpun-notice .wdpun-notice-cta{border-top:1px solid #E5E5E5;background:#F8F8F8;clear:both;display:block;padding:15px 20px;position:relative;text-align:center;white-space:nowrap}.wdpun-notice .wdpun-notice-cta .wdpun-button{vertical-align:middle}.wdpun-notice .wdpun-notice-cta .wdpun-button-notice-dismiss{margin:10px auto 0}.wdpun-notice .wdpun-notice-cta input[type="email"]{line-height:20px;margin:0;max-width:320px;min-width:50px;padding-right:0;padding-left:0;text-align:center;vertical-align:middle}@media only screen and (min-width: 601px){.wdpun-notice.notice{text-align:left}.wdpun-notice-logo{float:left;margin:10px}.wdpun-notice .wdpun-notice-message{margin-top:5px;margin-left:76px;padding:10px 20px 10px 10px}.wdpun-notice .wdpun-button{display:inline-block;font-size:14px}}@media only screen and (min-width: 783px){.wdpun-notice .wdpun-notice-cta .wdpun-button-notice-dismiss{margin-top:0}.wdpun-notice button+button,.wdpun-notice .wdpun-button+button,.wdpun-notice button+.wdpun-button,.wdpun-notice .wdpun-button+.wdpun-button,.wdpun-notice a+button,.wdpun-notice a+.wdpun-button{margin-left:10px}}@media only screen and (min-width: 961px){.wdpun-notice.notice{display:table}.wdpun-notice-logo{border-radius:0;height:auto;margin:0;min-height:80px;min-width:80px;width:5%}.wdpun-notice .wdpun-notice-logo,.wdpun-notice .wdpun-notice-message,.wdpun-notice .wdpun-notice-cta{cursor:default;display:table-cell;float:none;vertical-align:middle}.wdpun-notice .wdpun-notice-message{margin-top:0;max-width:100%;min-height:80px;width:75%}.wdpun-notice .wdpun-notice-cta{border-left:1px solid #E5E5E5;border-top:none;padding:0 30px;width:20%}}@media only screen and (min-width: 1140px){.wdpun-notice .wdpun-button{font-size:13px}}
305
+ </style>
306
+ <?php
307
+ }
308
+
309
+ function notice_scripts() {
310
+ if ( !$this->is_allowed_screen() ) return;
311
+ ?>
312
+ <script type="text/javascript">
313
+ !function($){function n(){function n(){a.fadeIn(500)}function i(){a.fadeTo(100,0,function(){a.slideUp(100,function(){a.remove()})})}function t(n,t){"0"!==e?(a.attr("data-message",t),a.addClass("saving"),s.action=n,jQuery.post(window.ajaxurl,s,i)):i()}var a=jQuery(".wdpun-notice"),e=a.find("input[name=msg_id]").val(),o=a.find(".wdpun-button-notice-dismiss"),s={};s.msg_id=e,o.click(function(n){n.preventDefault(),t("wdpun-dismiss",o.data("msg"))}),window.setTimeout(n,500)}$(n)}(jQuery);
314
+ </script>
 
 
 
315
  <?php
316
  }
317
+
318
+ function get_id_plugin( $plugin_file ) {
319
+ return get_file_data( $plugin_file, array(
320
+ 'name' => 'Plugin Name',
321
+ 'id' => 'WDP ID',
322
+ 'version' => 'Version'
323
+ ) );
324
  }
325
+
326
  //simple check for updates
327
  function updates_check() {
328
  global $wp_version;
329
  $local_projects = array();
330
+
331
  //----------------------------------------------------------------------------------//
332
  //plugins directory
333
  //----------------------------------------------------------------------------------//
334
  $plugins_root = WP_PLUGIN_DIR;
335
+ if ( empty( $plugins_root ) ) {
336
  $plugins_root = ABSPATH . 'wp-content/plugins';
337
  }
338
+
339
+ $plugins_dir = @opendir( $plugins_root );
340
  $plugin_files = array();
341
  if ( $plugins_dir ) {
342
+ while ( ( $file = readdir( $plugins_dir ) ) !== false ) {
343
+ if ( substr( $file, 0, 1 ) == '.' ) {
344
  continue;
345
+ }
346
+ if ( is_dir( $plugins_root . '/' . $file ) ) {
347
+ $plugins_subdir = @ opendir( $plugins_root . '/' . $file );
348
  if ( $plugins_subdir ) {
349
+ while ( ( $subfile = readdir( $plugins_subdir ) ) !== false ) {
350
+ if ( substr( $subfile, 0, 1 ) == '.' ) {
351
  continue;
352
+ }
353
+ if ( substr( $subfile, - 4 ) == '.php' ) {
354
  $plugin_files[] = "$file/$subfile";
355
+ }
356
  }
357
  }
358
  } else {
359
+ if ( substr( $file, - 4 ) == '.php' ) {
360
  $plugin_files[] = $file;
361
+ }
362
  }
363
  }
364
  }
365
  @closedir( $plugins_dir );
366
  @closedir( $plugins_subdir );
367
+
368
+ if ( $plugins_dir && ! empty( $plugin_files ) ) {
369
  foreach ( $plugin_files as $plugin_file ) {
370
  if ( is_readable( "$plugins_root/$plugin_file" ) ) {
371
+
372
+ unset( $data );
373
  $data = $this->get_id_plugin( "$plugins_root/$plugin_file" );
374
+
375
+ if ( isset( $data['id'] ) && ! empty( $data['id'] ) ) {
376
+ $local_projects[ $data['id'] ]['type'] = 'plugin';
377
+ $local_projects[ $data['id'] ]['version'] = $data['version'];
378
+ $local_projects[ $data['id'] ]['filename'] = $plugin_file;
379
  }
380
  }
381
  }
382
  }
383
+
384
  //----------------------------------------------------------------------------------//
385
  // mu-plugins directory
386
  //----------------------------------------------------------------------------------//
387
  $mu_plugins_root = WPMU_PLUGIN_DIR;
388
+ if ( empty( $mu_plugins_root ) ) {
389
  $mu_plugins_root = ABSPATH . 'wp-content/mu-plugins';
390
  }
391
+
392
+ if ( is_dir( $mu_plugins_root ) && $mu_plugins_dir = @opendir( $mu_plugins_root ) ) {
393
+ while ( ( $file = readdir( $mu_plugins_dir ) ) !== false ) {
394
+ if ( substr( $file, - 4 ) == '.php' ) {
395
  if ( is_readable( "$mu_plugins_root/$file" ) ) {
396
+
397
+ unset( $data );
398
  $data = $this->get_id_plugin( "$mu_plugins_root/$file" );
399
+
400
+ if ( isset( $data['id'] ) && ! empty( $data['id'] ) ) {
401
+ $local_projects[ $data['id'] ]['type'] = 'mu-plugin';
402
+ $local_projects[ $data['id'] ]['version'] = $data['version'];
403
+ $local_projects[ $data['id'] ]['filename'] = $file;
404
  }
405
  }
406
  }
407
  }
408
+ @closedir( $mu_plugins_dir );
409
  }
410
+
411
  //----------------------------------------------------------------------------------//
412
  // wp-content directory
413
  //----------------------------------------------------------------------------------//
414
  $content_plugins_root = WP_CONTENT_DIR;
415
+ if ( empty( $content_plugins_root ) ) {
416
  $content_plugins_root = ABSPATH . 'wp-content';
417
  }
418
+
419
+ $content_plugins_dir = @opendir( $content_plugins_root );
420
  $content_plugin_files = array();
421
  if ( $content_plugins_dir ) {
422
+ while ( ( $file = readdir( $content_plugins_dir ) ) !== false ) {
423
+ if ( substr( $file, 0, 1 ) == '.' ) {
424
  continue;
425
+ }
426
+ if ( ! is_dir( $content_plugins_root . '/' . $file ) ) {
427
+ if ( substr( $file, - 4 ) == '.php' ) {
428
  $content_plugin_files[] = $file;
429
+ }
430
  }
431
  }
432
  }
433
  @closedir( $content_plugins_dir );
434
+
435
+ if ( $content_plugins_dir && ! empty( $content_plugin_files ) ) {
436
  foreach ( $content_plugin_files as $content_plugin_file ) {
437
  if ( is_readable( "$content_plugins_root/$content_plugin_file" ) ) {
438
+ unset( $data );
439
  $data = $this->get_id_plugin( "$content_plugins_root/$content_plugin_file" );
440
+
441
+ if ( isset( $data['id'] ) && ! empty( $data['id'] ) ) {
442
+ $local_projects[ $data['id'] ]['type'] = 'drop-in';
443
+ $local_projects[ $data['id'] ]['version'] = $data['version'];
444
+ $local_projects[ $data['id'] ]['filename'] = $content_plugin_file;
445
  }
446
  }
447
  }
448
  }
449
+
450
  //----------------------------------------------------------------------------------//
451
  //themes directory
452
  //----------------------------------------------------------------------------------//
453
  $themes_root = WP_CONTENT_DIR . '/themes';
454
+ if ( empty( $themes_root ) ) {
455
  $themes_root = ABSPATH . 'wp-content/themes';
456
  }
457
+
458
+ $themes_dir = @opendir( $themes_root );
459
  $themes_files = array();
460
  $local_themes = array();
461
  if ( $themes_dir ) {
462
+ while ( ( $file = readdir( $themes_dir ) ) !== false ) {
463
+ if ( substr( $file, 0, 1 ) == '.' ) {
464
  continue;
465
+ }
466
+ if ( is_dir( $themes_root . '/' . $file ) ) {
467
+ $themes_subdir = @ opendir( $themes_root . '/' . $file );
468
  if ( $themes_subdir ) {
469
+ while ( ( $subfile = readdir( $themes_subdir ) ) !== false ) {
470
+ if ( substr( $subfile, 0, 1 ) == '.' ) {
471
  continue;
472
+ }
473
+ if ( substr( $subfile, - 4 ) == '.css' ) {
474
  $themes_files[] = "$file/$subfile";
475
+ }
476
  }
477
  }
478
  } else {
479
+ if ( substr( $file, - 4 ) == '.css' ) {
480
  $themes_files[] = $file;
481
+ }
482
  }
483
  }
484
  }
485
  @closedir( $themes_dir );
486
  @closedir( $themes_subdir );
487
+
488
+ if ( $themes_dir && ! empty( $themes_files ) ) {
489
  foreach ( $themes_files as $themes_file ) {
490
+
491
  //skip child themes
492
+ if ( strpos( $themes_file, '-child' ) !== false ) {
493
  continue;
494
+ }
495
+
496
  if ( is_readable( "$themes_root/$themes_file" ) ) {
497
+
498
+ unset( $data );
499
  $data = $this->get_id_plugin( "$themes_root/$themes_file" );
500
+
501
+ if ( isset( $data['id'] ) && ! empty( $data['id'] ) ) {
502
+ $local_projects[ $data['id'] ]['type'] = 'theme';
503
+ $local_projects[ $data['id'] ]['filename'] = substr( $themes_file, 0, strpos( $themes_file, '/' ) );
504
+
505
  //keep record of all themes for 133 themepack
506
+ if ( $data['id'] == $this->theme_pack ) {
507
+ $local_themes[ $themes_file ]['id'] = $data['id'];
508
+ $local_themes[ $themes_file ]['filename'] = substr( $themes_file, 0, strpos( $themes_file, '/' ) );
509
+ $local_themes[ $themes_file ]['version'] = $data['version'];
510
  //increment 133 theme pack version to lowest in all of them
511
+ if ( isset( $local_projects[ $data['id'] ]['version'] ) && version_compare( $data['version'], $local_projects[ $data['id'] ]['version'], '<' ) ) {
512
+ $local_projects[ $data['id'] ]['version'] = $data['version'];
513
+ } else if ( ! isset( $local_projects[ $data['id'] ]['version'] ) ) {
514
+ $local_projects[ $data['id'] ]['version'] = $data['version'];
515
  }
516
  } else {
517
+ $local_projects[ $data['id'] ]['version'] = $data['version'];
518
  }
519
  }
520
  }
521
  }
522
  }
523
+ update_site_option( 'wdp_un_local_themes', $local_themes );
524
+
525
+ update_site_option( 'wdp_un_local_projects', $local_projects );
526
+
527
  //now check the API
528
+
529
+ $projects = array();
530
+ $theme = wp_get_theme();
531
+ $ms_allowed = $theme->get_allowed();
532
+ foreach ( $local_projects as $pid => $item ) {
533
+ if ( ! empty( $blog_projects[ $pid ] ) ) { //not yet implemented
534
+ // This project is activated on a blog!
535
+ $active = true;
536
+ } else {
537
+ if ( is_multisite() ) {
538
+ if ( 'theme' == $item['type'] ) {
539
+ // If the theme is available on main site it's "active".
540
+ $slug = $item['filename'];
541
+ $active = ! empty( $ms_allowed[ $slug ] );
542
+ } else {
543
+ $active = is_plugin_active_for_network( $item['filename'] );
544
+ }
545
+ } else {
546
+ if ( 'theme' == $item['type'] ) {
547
+ $slug = $item['filename'];
548
+ $active = ( $theme->stylesheet == $slug || $theme->template == $slug );
549
+ } else {
550
+ $active = is_plugin_active( $item['filename'] );
551
+ }
552
+ }
553
+ }
554
+ $extra = '';
555
+
556
+ /**
557
+ * Collect extra data from individual plugins.
558
+ *
559
+ * @since 4.0.0
560
+ * @api wpmudev_api_project_extra_data-$pid
561
+ *
562
+ * @param string $extra Default extra data is an empty string.
563
+ */
564
+ $extra = apply_filters( "wpmudev_api_project_extra_data-$pid", $extra );
565
+ $extra = apply_filters( 'wpmudev_api_project_extra_data', $extra, $pid );
566
+
567
+ $projects[ $pid ] = array(
568
+ 'version' => $item['version'],
569
+ 'active' => $active ? true : false,
570
+ 'extra' => $extra,
571
+ );
572
+ }
573
+
574
  //get WP/BP version string to help with support
575
+ $wp_ver = is_multisite() ? "WordPress Multisite $wp_version" : "WordPress $wp_version";
576
+ if ( defined( 'BP_VERSION' ) ) {
577
+ $wp_ver .= ', BuddyPress ' . BP_VERSION;
578
+ }
579
+
580
  //add blog count if multisite
581
  $blog_count = is_multisite() ? get_blog_count() : 1;
582
+
583
+ $url = $this->server_url . 'updates';
584
+
585
  $options = array(
586
+ 'timeout' => 15,
587
+ 'sslverify' => false, // Many hosts have no updated CA bundle.
588
  'user-agent' => 'Dashboard Notification/' . $this->version
589
  );
590
+
591
+ $options['body'] = array(
592
+ 'blog_count' => $blog_count,
593
+ 'wp_version' => $wp_ver,
594
+ 'projects' => json_encode( $projects ),
595
+ 'domain' => network_site_url(),
596
+ 'admin_url' => network_admin_url(),
597
+ 'home_url' => network_home_url(),
598
+ );
599
+
600
+ $response = wp_remote_post( $url, $options );
601
+ if ( wp_remote_retrieve_response_code( $response ) == 200 ) {
602
  $data = $response['body'];
603
  if ( $data != 'error' ) {
604
+ $data = json_decode( $data, true );
605
+ if ( is_array( $data ) ) {
606
+
607
  //we've made it here with no errors, now check for available updates
608
+ $remote_projects = isset( $data['projects'] ) ? $data['projects'] : array();
609
+ $updates = array();
610
+
611
  //check for updates
612
+ if ( is_array( $remote_projects ) ) {
613
  foreach ( $remote_projects as $id => $remote_project ) {
614
+ if ( isset( $local_projects[ $id ] ) && is_array( $local_projects[ $id ] ) ) {
615
  //match
616
+ $local_version = $local_projects[ $id ]['version'];
617
  $remote_version = $remote_project['version'];
618
+
619
+ if ( version_compare( $remote_version, $local_version, '>' ) ) {
620
  //add to array
621
+ $updates[ $id ] = $local_projects[ $id ];
622
+ $updates[ $id ]['url'] = $remote_project['url'];
623
+ $updates[ $id ]['name'] = $remote_project['name'];
624
+ $updates[ $id ]['version'] = $local_version;
625
+ $updates[ $id ]['new_version'] = $remote_version;
626
+ $updates[ $id ]['autoupdate'] = $remote_project['autoupdate'];
 
 
 
 
627
  }
628
  }
629
  }
630
+
631
  //record results
632
+ update_site_option( 'wdp_un_updates_available', $updates );
633
  } else {
634
  return false;
635
  }
637
  }
638
  }
639
  }
640
+
641
+ function filter_plugin_info( $res, $action, $args ) {
642
  global $wp_version;
643
+ $cur_wp_version = preg_replace( '/-.*$/', '', $wp_version );
644
+
645
+ if ( ( $action == 'plugin_information' || $action == 'theme_information' ) && strpos( $args->slug, 'wpmudev_install' ) !== false ) {
646
+ $string = explode( '-', $args->slug );
647
+ $id = intval( $string[1] );
648
+ $updates = get_site_option( 'wdp_un_updates_available' );
649
+ //if in details iframe on update core page short-curcuit it
650
+ if ( did_action( 'install_plugins_pre_plugin-information' ) && is_array( $updates ) && isset( $updates[ $id ] ) ) {
651
+ $this->popup_changelog( $id );
 
652
  }
653
+
654
+ $res = new stdClass;
655
+ $res->name = $updates[ $id ]['name'];
656
+ $res->slug = sanitize_title( $updates[ $id ]['name'] );
657
+ $res->version = $updates[ $id ]['version'];
658
+ $res->rating = 100;
659
+ $res->homepage = $updates[ $id ]['url'];
660
  $res->download_link = '';
661
+ $res->tested = $cur_wp_version;
662
+
663
  return $res;
664
  }
665
+
666
+ if ( $action == 'plugin_information' && strpos( $args->slug, 'install_wpmudev_dash' ) !== false ) {
667
+ $res = new stdClass;
668
+ $res->name = 'WPMU DEV Dashboard';
669
+ $res->slug = 'wpmu-dev-dashboard';
670
+ $res->version = '';
671
+ $res->rating = 100;
672
+ $res->homepage = 'https://premium.wpmudev.org/project/wpmu-dev-dashboard/';
673
+ $res->download_link = $this->server_url . "download-dashboard";
674
+ $res->tested = $cur_wp_version;
675
+
676
  return $res;
677
  }
678
+
679
  return $res;
680
  }
681
+
682
  function filter_plugin_rows() {
683
+ if ( ! current_user_can( 'update_plugins' ) ) {
684
  return;
685
+ }
686
+
687
+ //don't show on per site plugins list, just like core
688
+ if ( is_multisite() && ! is_network_admin() ) { return; }
689
+
690
+ $updates = get_site_option( 'wdp_un_updates_available' );
691
+ if ( is_array( $updates ) && count( $updates ) ) {
692
  foreach ( $updates as $id => $plugin ) {
693
  if ( $plugin['autoupdate'] != '2' ) {
694
  if ( $plugin['type'] == 'theme' ) {
695
  remove_all_actions( 'after_theme_row_' . $plugin['filename'] );
696
+ add_action( 'after_theme_row_' . $plugin['filename'], array( &$this, 'plugin_row' ), 99, 2 );
697
  } else {
698
  remove_all_actions( 'after_plugin_row_' . $plugin['filename'] );
699
+ add_action( 'after_plugin_row_' . $plugin['filename'], array(
700
+ &$this,
701
+ 'plugin_row'
702
+ ), 99, 2 );
703
  }
704
  }
705
  }
706
  }
707
+
708
+ $local_themes = get_site_option( 'wdp_un_local_themes' );
709
+ if ( is_array( $local_themes ) && count( $local_themes ) ) {
710
  foreach ( $local_themes as $id => $plugin ) {
711
  remove_all_actions( 'after_theme_row_' . $plugin['filename'] );
712
  //only add the notice if specific version is wrong
713
+ if ( isset( $updates[ $this->theme_pack ] ) && version_compare( $plugin['version'], $updates[ $this->theme_pack ]['new_version'], '<' ) ) {
714
+ add_action( 'after_theme_row_' . $plugin['filename'], array( &$this, 'themepack_row' ), 9, 2 );
715
  }
716
  }
717
  }
718
  }
719
+
720
  function filter_plugin_count( $value ) {
721
+ global $wp_version;
722
+ $cur_wp_version = preg_replace( '/-.*$/', '', $wp_version );
723
+
724
  //remove any conflicting slug local WPMU DEV plugins from WP update notifications
725
+ $local_projects = get_site_option( 'wdp_un_local_projects' );
726
+ if ( is_array( $local_projects ) && count( $local_projects ) ) {
727
  foreach ( $local_projects as $id => $plugin ) {
728
+ if ( isset( $value->response[ $plugin['filename'] ] ) ) {
729
+ unset( $value->response[ $plugin['filename'] ] );
730
+ }
731
  }
732
  }
733
+
734
+ $updates = get_site_option( 'wdp_un_updates_available' );
735
+ if ( is_array( $updates ) && count( $updates ) ) {
736
  foreach ( $updates as $id => $plugin ) {
737
  if ( $plugin['type'] != 'theme' && $plugin['autoupdate'] != '2' ) {
738
+
739
  //build plugin class
740
+ $object = new stdClass;
741
+ $object->url = $plugin['url'];
742
+ $object->slug = "wpmudev_install-$id";
 
743
  $object->new_version = $plugin['new_version'];
744
+ $object->package = '';
745
+ $object->tested = $cur_wp_version;
746
+
747
  //add to class
748
+ $value->response[ $plugin['filename'] ] = $object;
749
  }
750
  }
751
  }
752
+
753
  return $value;
754
  }
755
+
756
  function filter_theme_count( $value ) {
757
+
758
+ $updates = get_site_option( 'wdp_un_updates_available' );
759
+ if ( is_array( $updates ) && count( $updates ) ) {
760
  foreach ( $updates as $id => $theme ) {
761
  if ( $theme['type'] == 'theme' && $theme['autoupdate'] != '2' ) {
762
+
763
+ $theme_slug = $theme['filename'];
764
+
765
  //build theme listing
766
+ $value->response[ $theme_slug ]['theme'] = $theme['filename'];
767
+ $value->response[ $theme_slug ]['url'] = admin_url( 'admin-ajax.php?action=wdpun-changelog&pid=' . $id );
768
+ $value->response[ $theme_slug ]['new_version'] = $theme['new_version'];
769
+ $value->response[ $theme_slug ]['package'] = '';
770
  }
771
  }
772
  }
773
+
774
  //filter 133 theme pack themes from the list unless update is available
775
+ $local_themes = get_site_option( 'wdp_un_local_themes' );
776
+ if ( is_array( $local_themes ) && count( $local_themes ) ) {
777
  foreach ( $local_themes as $id => $theme ) {
778
+ $theme_slug = $theme['filename'];
779
+
780
  //add to count only if new version exists, otherwise remove
781
+ if ( isset( $updates[ $theme['id'] ] ) && isset( $updates[ $theme['id'] ]['new_version'] ) && version_compare( $theme['version'], $updates[ $theme['id'] ]['new_version'], '<' ) ) {
782
+ $value->response[ $theme_slug ]['new_version'] = $updates[ $theme['id'] ]['new_version'];
783
+ $value->response[ $theme_slug ]['package'] = '';
784
+ } else if ( isset( $value ) && isset( $value->response ) && isset( $theme_slug ) && isset( $value->response[ $theme_slug ] ) ) {
785
+ unset( $value->response[ $theme_slug ] );
786
  }
787
  }
788
  }
789
+
790
  return $value;
791
  }
792
+
793
  function plugin_row( $file, $plugin_data ) {
 
794
  //get new version and update url
795
+ $updates = get_site_option( 'wdp_un_updates_available' );
796
+ if ( is_array( $updates ) && count( $updates ) ) {
797
  foreach ( $updates as $id => $plugin ) {
798
+ if ( $plugin['filename'] == $file ) {
799
  $project_id = $id;
800
+ $version = $plugin['new_version'];
801
  $plugin_url = $plugin['url'];
802
  $autoupdate = $plugin['autoupdate'];
803
+ $filename = $plugin['filename'];
804
+ $type = $plugin['type'];
805
  break;
806
  }
807
  }
808
  } else {
809
  return false;
810
  }
811
+
812
+ $plugins_allowedtags = array(
813
+ 'a' => array( 'href' => array(), 'title' => array() ),
814
+ 'abbr' => array( 'title' => array() ),
815
+ 'acronym' => array( 'title' => array() ),
816
+ 'code' => array(),
817
+ 'em' => array(),
818
+ 'strong' => array()
819
+ );
820
+ $plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags );
821
+
822
+ $info_url = admin_url( 'admin-ajax.php?action=wdpun-changelog&pid=' . $project_id . '&TB_iframe=true&width=640&height=800' );
823
+ if ( file_exists( WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php' ) ) {
824
+ $message = "Activate WPMU DEV Dashboard";
825
  $action_url = $this->activate_url();
826
  } else { //dashboard not installed at all
827
+ $message = "Install WPMU DEV Dashboard";
828
  $action_url = $this->auto_install_url();
829
  }
830
+
831
+ if ( current_user_can( 'update_plugins' ) ) {
832
+ echo '<tr class="plugin-update-tr"><td colspan="3" class="plugin-update colspanchange"><div class="update-message notice inline notice-warning notice-alt"><p>';
833
+ printf( 'There is a new version of %1$s available on WPMU DEV. <a href="%2$s" class="thickbox" title="%3$s">View version %4$s details</a> or <a href="%5$s">%6$s</a> to update.', $plugin_name, esc_url( $info_url ), esc_attr( $plugin_name ), $version, esc_url( $action_url ), $message );
834
+ echo '</p></div></td></tr>';
835
  }
836
  }
837
+
838
  function themepack_row( $file, $plugin_data ) {
839
+
840
  //get new version and update url
841
+ $updates = get_site_option( 'wdp_un_updates_available' );
842
+ if ( isset( $updates[ $this->theme_pack ] ) ) {
843
+ $plugin = $updates[ $this->theme_pack ];
844
  $project_id = $this->theme_pack;
845
+ $version = $plugin['new_version'];
846
  $plugin_url = $plugin['url'];
847
  } else {
848
  return false;
849
  }
850
+
851
+ $plugins_allowedtags = array(
852
+ 'a' => array( 'href' => array(), 'title' => array() ),
853
+ 'abbr' => array( 'title' => array() ),
854
+ 'acronym' => array( 'title' => array() ),
855
+ 'code' => array(),
856
+ 'em' => array(),
857
+ 'strong' => array()
858
+ );
859
+ $plugin_name = wp_kses( $plugin_data['Name'], $plugins_allowedtags );
860
+
861
+ $info_url = admin_url( 'admin_ajax.php?action=wdpun-changelog&pid=' . $project_id . '&TB_iframe=true&width=640&height=800' );
862
+ if ( file_exists( WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php' ) ) {
863
+ $message = "Activate WPMU DEV Dashboard";
864
  $action_url = $this->activate_url();
865
  } else { //dashboard not installed at all
866
+ $message = "Install WPMU DEV Dashboard";
867
  $action_url = $this->auto_install_url();
868
  }
869
+
870
+ if ( current_user_can( 'update_themes' ) ) {
871
+ echo '<tr class="plugin-update-tr"><td colspan="3" class="plugin-update colspanchange"><div class="update-message notice inline notice-warning notice-alt"><p>';
872
+ printf( 'There is a new version of %1$s available on WPMU DEV. <a href="%2$s" class="thickbox" title="%3$s">View version %4$s details</a> or <a href="%5$s">%6$s</a> to update.', $plugin_name, esc_url( $info_url ), esc_attr( $plugin_name ), $version, esc_url( $action_url ), $message );
873
+ echo '</p></div></td></tr>';
874
  }
875
  }
876
+
877
  function disable_checkboxes() {
878
+
879
+ $updates = get_site_option( 'wdp_un_updates_available' );
880
+ if ( ! is_array( $updates ) || ( is_array( $updates ) && ! count( $updates ) ) ) {
881
  return;
882
  }
883
+
884
+ $jquery = "<script type='text/javascript'>";
885
+
886
+ if ( file_exists( WP_PLUGIN_DIR . '/wpmudev-updates/update-notifications.php' ) ) {
887
+ $message = "Activate WPMU DEV Dashboard";
888
+ $action_url = $this->activate_url();
889
+ } else { //dashboard not installed at all
890
+ $message = "Install WPMU DEV Dashboard";
891
+ $action_url = $this->auto_install_url();
892
+ }
893
+ $jquery .= "var wdp_note = '<br><span class=\"notice inline notice-warning notice-alt\">" . sprintf( '<a href="%s">%s</a> to update.', esc_url( $action_url ), $message ) . "</span>';\n";
894
+
895
+ foreach ( (array) $updates as $id => $project ) {
896
+ $slug = $project['filename'];
897
+ $jquery .= "jQuery(\"input:checkbox[value='" . esc_attr( $slug ) . "']\").closest('tr').find('td p').last().append(wdp_note);\n";
898
+ $jquery .= "jQuery(\"input:checkbox[value='" . esc_attr( $slug ) . "']\").remove();\n";
899
  }
900
+
901
  //disable checkboxes for 133 theme pack themes
902
+ $local_themes = get_site_option( 'wdp_un_local_themes' );
903
+ if ( is_array( $local_themes ) && count( $local_themes ) ) {
904
  foreach ( $local_themes as $id => $theme ) {
905
+ $jquery .= "jQuery(\"input:checkbox[value='" . esc_attr( $theme['filename'] ) . "']\").closest('tr').find('td p').last().append(wdp_note);\n";
906
+ $jquery .= "jQuery(\"input:checkbox[value='" . esc_attr( $theme['filename'] ) . "']\").remove();\n";
907
  }
908
  }
909
+
910
+ $jquery .= "</script>\n";
911
+
912
  echo $jquery;
913
  }
914
+
915
+ function set_activate_flag( $plugin ) {
916
  $data = $this->get_id_plugin( WP_PLUGIN_DIR . '/' . $plugin );
917
+ if ( isset( $data['id'] ) && ! empty( $data['id'] ) ) {
918
+ update_site_option( 'wdp_un_activated_flag', 1 );
919
  }
920
  }
921
+
922
+ function popup_changelog( $project_id ) {
923
+ /**
924
+ * Dashboard popup template: Project changelog
925
+ *
926
+ * Displays the changelog of a specific project.
927
+ *
928
+ * Following variables are passed into the template:
929
+ * $pid (project ID)
930
+ *
931
+ * @since 4.0.5
932
+ * @package WPMUDEV_Dashboard
933
+ */
934
+
935
+ $url = $this->server_url . 'changelog/' . $project_id;
936
+
937
+ $options = array(
938
+ 'timeout' => 15,
939
+ 'sslverify' => false, // Many hosts have no updated CA bundle.
940
+ 'user-agent' => 'Dashboard Notification/' . $this->version
941
+ );
942
+
943
+ $response = wp_remote_get( $url, $options );
944
+ if ( wp_remote_retrieve_response_code( $response ) == 200 ) {
945
+ $changelog = json_decode( wp_remote_retrieve_body( $response ), true );
946
+ }
947
+
948
+ $updates = get_site_option( 'wdp_un_updates_available' );
949
+ $item = $updates[ $project_id ];
950
+
951
+ if ( ! $changelog || ! is_array( $changelog ) || ! $item ) {
952
+ wp_die( __( 'We did not find any data for this plugin or theme...', 'wpmudev' ) );
953
+ }
954
+ $dlg_id = 'dlg-' . md5( time() . '-' . $project_id );
955
+
956
+
957
+ ?>
958
+ <div id="content" class="<?php echo esc_attr( $dlg_id ); ?>">
959
+ <script src="<?php echo includes_url( '/wp-includes/js/jquery/jquery.js' ); ?>"></script>
960
+ <link rel="stylesheet"
961
+ href="https://fonts.googleapis.com/css?family=Roboto+Condensed%3A400%2C700%7CRoboto%3A400%2C500%2C300%2C300italic%2C100"
962
+ type="text/css" media="all"/>
963
+ <style>
964
+ * {
965
+ box-sizing: border-box;
966
+ -moz-box-sizing: border-box;
967
+ }
968
+
969
+ html, body {
970
+ margin: 0;
971
+ padding: 0;
972
+ height: 100%;
973
+ font-family: 'Roboto', 'Helvetica Neue', Helvetica, sans-serif;
974
+ font-size: 15px;
975
+ }
976
+
977
+ h1, h2, h3, h4 {
978
+ font-family: 'Roboto Condensed', 'Roboto', 'Helvetica Neue', Helvetica, sans-serif;
979
+ font-weight: 700;
980
+ color: #777771;
981
+ }
982
+
983
+ h1 {
984
+ font-size: 3em;
985
+ }
986
+
987
+ p {
988
+ font-size: 1.2em;
989
+ font-weight: 300;
990
+ color: #777771;
991
+ }
992
+
993
+ a {
994
+ color: #19b4cf;
995
+ text-decoration: none;
996
+ }
997
+
998
+ a:hover,
999
+ a:focus,
1000
+ a:active {
1001
+ color: #387ac1;
1002
+ }
1003
+
1004
+ #content {
1005
+ min-height: 100%;
1006
+ text-align: center;
1007
+ background: #FFF;
1008
+ position: absolute;
1009
+ left: 0;
1010
+ top: 0;
1011
+ right: 0;
1012
+ bottom: 0;
1013
+ overflow: auto;
1014
+ }
1015
+
1016
+ #content .excerpt {
1017
+ width: 100%;
1018
+ background-color: #14485F;
1019
+ padding: 10px;
1020
+ color: #FFF;
1021
+ }
1022
+
1023
+ #content .excerpt h1 {
1024
+ margin: 30px;
1025
+ color: #FFF;
1026
+ font-weight: 100;
1027
+ }
1028
+
1029
+ #content .versions h4 {
1030
+ font-size: 15px;
1031
+ text-transform: uppercase;
1032
+ text-align: left;
1033
+ padding: 0 0 15px;
1034
+ font-weight: bold;
1035
+ line-height: 20px;
1036
+ }
1037
+
1038
+ #content .excerpt a {
1039
+ float: left;
1040
+ margin-right: 40px;
1041
+ text-decoration: none;
1042
+ color: #6ECEDE;
1043
+ }
1044
+
1045
+ #content .excerpt a:hover,
1046
+ #content .excerpt a:focus,
1047
+ #content .excerpt a:active {
1048
+ color: #C7F7FF;
1049
+ }
1050
+
1051
+ #content .footer {
1052
+ background-color: #0B2F3F;
1053
+ padding: 20px 0;
1054
+ margin: 0;
1055
+ position: relative;
1056
+ }
1057
+
1058
+ #content .footer p {
1059
+ color: #FFF;
1060
+ margin: 10px 0;
1061
+ padding: 0;
1062
+ font-size: 15px;
1063
+ }
1064
+
1065
+ #content .information {
1066
+ padding: 0;
1067
+ text-align: left;
1068
+ }
1069
+
1070
+ #content .versions > li {
1071
+ border-bottom: 1px solid #E5E5E5;
1072
+ padding: 40px;
1073
+ margin: 0;
1074
+ }
1075
+
1076
+ #content .versions > li.new {
1077
+ background: #fffff6;
1078
+ }
1079
+
1080
+ #content .information .current-version,
1081
+ #content .information .new-version {
1082
+ border-radius: 5px;
1083
+ color: #FFF;
1084
+ cursor: default;
1085
+ display: inline-block;
1086
+ position: relative;
1087
+ top: -2px;
1088
+ margin: 0 0 0 10px;
1089
+ padding: 1px 5px;
1090
+ font-size: 10px;
1091
+ line-height: 20px;
1092
+ height: 20px;
1093
+ box-sizing: border-box;
1094
+ }
1095
+
1096
+ #content .information .new-version {
1097
+ background: #FDCE43;
1098
+ text-shadow: 0 1px 1px #DDAE30;
1099
+ }
1100
+
1101
+ #content .current-version {
1102
+ background: #00ACCA;
1103
+ text-shadow: 0 1px 1px #008CAA;
1104
+ }
1105
+
1106
+ #content .versions {
1107
+ margin: 0;
1108
+ padding: 0;
1109
+ }
1110
+
1111
+ #content .versions .changes {
1112
+ list-style: disc;
1113
+ padding: 0 0 0 20px;
1114
+ margin: 0;
1115
+ }
1116
+
1117
+ #content .versions .changes li {
1118
+ padding: 3px 0 3px 20px;
1119
+ margin: 0;
1120
+ color: #777771;
1121
+ cursor: default;
1122
+ }
1123
+
1124
+ #content .version-meta {
1125
+ float: right;
1126
+ text-align: right;
1127
+ }
1128
+ </style>
1129
+
1130
+ <div class="excerpt">
1131
+ <h1><?php printf( esc_attr__( '%s changelog', 'wpmudev' ), esc_html( $item['name'] ) ); ?></h1>
1132
+ </div>
1133
+
1134
+ <div class="information">
1135
+
1136
+ <ul class="versions">
1137
+ <?php
1138
+ foreach ( $changelog as $log ) {
1139
+ $row_class = '';
1140
+ $badge = '';
1141
+
1142
+ if ( ! is_array( $log ) ) {
1143
+ continue;
1144
+ }
1145
+ if ( empty( $log ) ) {
1146
+ continue;
1147
+ }
1148
+
1149
+ // -1 .. local is higher (dev) | 0 .. equal | 1 .. new version available
1150
+ $version_check = version_compare( $log['version'], $item['version'] );
1151
+
1152
+ if ( $item['version'] && 1 === $version_check ) {
1153
+ $row_class = 'new';
1154
+ }
1155
+
1156
+ if ( $item['version'] ) {
1157
+ if ( 0 === $version_check ) {
1158
+ $badge = sprintf(
1159
+ '<div class="current-version">%s %s</div>',
1160
+ '<i class="wdv-icon wdv-icon-ok"></i>',
1161
+ __( 'Current', 'wpmudev' )
1162
+ );
1163
+ } elseif ( 1 === $version_check ) {
1164
+ $badge = sprintf(
1165
+ '<div class="new-version">%s %s</div>',
1166
+ '<i class="wdv-icon wdv-icon-star"></i>',
1167
+ __( 'New', 'wpmudev' )
1168
+ );
1169
+ }
1170
+ }
1171
+
1172
+ $version = $log['version'];
1173
+
1174
+ if ( empty( $log['time'] ) ) {
1175
+ $rel_date = '';
1176
+ } else {
1177
+ $rel_date = date_i18n( get_option( 'date_format' ), $log['time'] );
1178
+ }
1179
+
1180
+ printf(
1181
+ '<li class="%1$s"><h4>%2$s %3$s <small class="version-meta">%4$s</small></h4>',
1182
+ esc_attr( $row_class ),
1183
+ sprintf(
1184
+ esc_html__( 'Version %s', 'wpmudev' ), esc_html( $version )
1185
+ ),
1186
+ wp_kses_post( $badge ),
1187
+ esc_html( $rel_date )
1188
+ );
1189
+
1190
+ $notes = explode( "\n", $log['log'] );
1191
+ $detail_level = 0;
1192
+ $detail_class = 'intro';
1193
+
1194
+ echo '<ul class="changes">';
1195
+ foreach ( $notes as $note ) {
1196
+ if ( 0 === strpos( $note, '<p>' ) ) {
1197
+ if ( 1 == $detail_level ) {
1198
+ printf(
1199
+ '<li class="toggle-details">
1200
+ <a href="#" class="for-intro">%s</a><a href="#" class="for-detail">%s</a>
1201
+ </li>',
1202
+ esc_html__( 'Show all changes', 'wpmudev' ),
1203
+ esc_html__( 'Hide details', 'wpmudev' )
1204
+ );
1205
+ $detail_class = 'detail';
1206
+ }
1207
+ $detail_level += 1;
1208
+ }
1209
+
1210
+ $note = stripslashes( $note );
1211
+ $note = preg_replace( '/(<br ?\/?>|<p>|<\/p>)/', '', $note );
1212
+ $note = trim( preg_replace( '/^\s*(\*|\-)\s*/', '', $note ) );
1213
+ $note = str_replace( array( '<', '>' ), array( '&lt;', '&gt;' ), $note );
1214
+ $note = preg_replace( '/`(.*?)`/', '<code>\1</code>', $note );
1215
+ if ( empty( $note ) ) {
1216
+ continue;
1217
+ }
1218
+
1219
+ printf(
1220
+ '<li class="version-%s">%s</li>',
1221
+ esc_attr( $detail_class ),
1222
+ wp_kses_post( $note )
1223
+ );
1224
+ }
1225
+ echo '</ul></li>';
1226
+ }
1227
+ ?>
1228
+ </ul>
1229
+ </div>
1230
+
1231
+ <div class="footer">
1232
+ <p>Copyright 2009 - <?php echo esc_html( date( 'Y' ) ); ?> WPMU DEV</p>
1233
+ </div>
1234
+
1235
+ <style>
1236
+ .<?php echo esc_attr( $dlg_id ); ?> .versions ul.changes .for-detail,
1237
+ .<?php echo esc_attr( $dlg_id ); ?> .versions ul.changes .version-detail {
1238
+ display: none;
1239
+ }
1240
+
1241
+ .<?php echo esc_attr( $dlg_id ); ?> .versions ul.changes .for-intro {
1242
+ display: inline-block;
1243
+ }
1244
+
1245
+ .<?php echo esc_attr( $dlg_id ); ?> .versions ul.changes.show-details .for-intro {
1246
+ display: none;
1247
+ }
1248
+
1249
+ .<?php echo esc_attr( $dlg_id ); ?> .versions ul.changes.show-details .for-detail {
1250
+ display: inline-block;
1251
+ }
1252
+
1253
+ .<?php echo esc_attr( $dlg_id ); ?> .versions ul.changes.show-details .version-detail {
1254
+ display: list-item;
1255
+ }
1256
+
1257
+ .<?php echo esc_attr( $dlg_id ); ?> .versions ul.changes .toggle-details {
1258
+ padding: 8px 0 4px;
1259
+ text-align: right;
1260
+ font-size: 12px;
1261
+ list-style: none;
1262
+ }
1263
+ </style>
1264
+ <script>
1265
+ jQuery(function () {
1266
+ jQuery('.<?php echo esc_attr( $dlg_id ); ?>').on('click', '.toggle-details a', function (ev) {
1267
+ var li = jQuery(this),
1268
+ ver = li.closest('.changes');
1269
+
1270
+ ev.preventDefault();
1271
+ ev.stopPropagation();
1272
+ ver.toggleClass('show-details');
1273
+ return false;
1274
+ });
1275
+ });
1276
+ </script>
1277
+ </div>
1278
+ <?php
1279
+ exit; //this is for output, we are done after this.
1280
+ }
1281
+
1282
+ function popup_changelog_ajax() {
1283
+ $project_id = $_GET['pid'];
1284
+ $this->popup_changelog( $project_id );
1285
+ }
1286
+
1287
+ function dismiss_ajax() {
1288
+ update_site_option( 'wdp_un_dismissed', time() );
1289
+ wp_send_json_success();
1290
+ }
1291
+
1292
  }
1293
+
1294
+ $GLOBALS['WPMUDEV_Dashboard_Notice4'] = new WPMUDEV_Dashboard_Notice4();
1295
  }
1296
 
1297
+ //disable older versions
1298
+ if ( ! class_exists( 'WPMUDEV_Dashboard_Notice' ) ) {
1299
+ class WPMUDEV_Dashboard_Notice {
1300
+ }
1301
+ }
1302
+
1303
+ if ( ! class_exists( 'WPMUDEV_Dashboard_Notice3' ) ) {
1304
+ class WPMUDEV_Dashboard_Notice3 {
1305
+ }
1306
  }
extras/free-dashboard/admin.css CHANGED
@@ -1,5 +1,8 @@
1
- /**
2
- * CSS styles used by the WDev-Frash module.
 
 
 
3
  */
4
 
5
  .wrap .frash-notice.notice {
@@ -18,7 +21,6 @@
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;
@@ -33,13 +35,11 @@
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);
@@ -47,29 +47,24 @@
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;
@@ -77,12 +72,10 @@
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;
@@ -93,14 +86,12 @@
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
  }
@@ -120,7 +111,6 @@
120
  display: block;
121
  font-size: 13px;
122
  }
123
-
124
  .frash-notice > .frash-notice-logo {
125
  float: left;
126
  display: inline-block;
@@ -128,14 +118,12 @@
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;
@@ -145,12 +133,10 @@
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;
@@ -171,7 +157,6 @@
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;
1
+ /* ****************************************************************************
2
+ * NOTIFICATION STYLES
3
+ *
4
+ * The styles are identical with the WPMUDEV dashboard CSS (section 22)
5
+ * Any changes made here should also be made to the dashboard CSS!
6
  */
7
 
8
  .wrap .frash-notice.notice {
21
  display: table; /* The magic ingredient! */
22
  font: 13px "Open Sans", sans-serif;
23
  }
 
24
  .wrap .frash-notice.notice.loading:before {
25
  content: attr(data-message);
26
  position: absolute;
35
  font-size: 22px;
36
  font-weight: bold;
37
  }
 
38
  .frash-notice > div {
39
  display: table-cell; /* The magic ingredient! */
40
  vertical-align: middle;
41
  cursor: default;
42
  }
 
43
  .frash-notice.notice.loading > div {
44
  -webkit-filter: blur(2px);
45
  -moz-filter: blur(2px);
47
  -ms-filter: blur(2px);
48
  filter: blur(2px);
49
  }
 
50
  .frash-notice-logo {
51
  background-color: #0B2F3F;
52
  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);
53
  background-repeat: no-repeat;
54
  background-position: 50% 50%;
55
  }
 
56
  .frash-notice-logo span {
57
  display: block;
58
  width: 80px;
59
  }
 
60
  .frash-notice-message {
61
  width: 100%;
62
  padding: 10px 20px;
63
  color: #444;
64
  }
 
65
  .frash-notice-message strong {
66
  color: #000;
67
  }
 
68
  .frash-notice-cta {
69
  border-left: 1px solid #E5E5E5;
70
  background: #F8F8F8;
72
  position: relative;
73
  white-space: nowrap;
74
  }
 
75
  .wp-core-ui .frash-notice-cta button,
76
  .wp-core-ui .frash-notice-cta .button-primary:active {
77
  vertical-align: middle;
78
  }
 
79
  .wp-core-ui .frash-notice-cta input[type="email"] {
80
  vertical-align: middle;
81
  line-height: 20px;
86
  padding-left: 0;
87
  padding-right: 0;
88
  }
 
89
  .frash-notice-dismiss {
90
  background: transparent;
91
  border: 0;
92
  cursor: pointer;
93
  color: #BBB;
94
  }
 
95
  .frash-notice-dismiss:hover {
96
  color: #666;
97
  }
111
  display: block;
112
  font-size: 13px;
113
  }
 
114
  .frash-notice > .frash-notice-logo {
115
  float: left;
116
  display: inline-block;
118
  margin: 10px;
119
  border-radius: 4px;
120
  }
 
121
  .frash-notice > .frash-notice-message {
122
  width: auto;
123
  display: block;
124
  padding: 10px;
125
  min-height: 80px;
126
  }
 
127
  .frash-notice > .frash-notice-cta {
128
  display: block;
129
  border-top: 1px solid #E5E5E5;
133
  line-height: 30px;
134
  padding: 10px 20px;
135
  }
 
136
  .wp-core-ui .frash-notice > .frash-notice-cta > input[type="email"],
137
  .frash-notice > .frash-notice-cta > button {
138
  font-size: 14px;
139
  }
 
140
  .frash-notice > .frash-notice-cta > .frash-notice-dismiss {
141
  display: inline-block;
142
  float: none;
157
  font-size: 16px;
158
  height: 34px;
159
  }
 
160
  .frash-notice > .frash-notice-cta > .frash-notice-dismiss {
161
  margin-top: 5px;
162
  font-size: 14px;
extras/free-dashboard/module.php CHANGED
@@ -3,23 +3,12 @@
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
  *
@@ -385,7 +374,7 @@ if ( ! class_exists( 'WDev_Frash' ) ) {
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
  ?>
@@ -400,11 +389,11 @@ if ( ! class_exists( 'WDev_Frash' ) ) {
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
@@ -420,7 +409,7 @@ if ( ! class_exists( 'WDev_Frash' ) ) {
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
  ?>
@@ -435,15 +424,15 @@ if ( ! class_exists( 'WDev_Frash' ) ) {
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
3
  * WPMUDEV Frash - Free Dashboard Notification module.
4
  * Used by wordpress.org hosted plugins.
5
  *
6
+ * @version 1.1.0
 
 
 
 
7
  * @author Incsub (Philipp Stracker)
8
  */
9
  if ( ! class_exists( 'WDev_Frash' ) ) {
10
  class WDev_Frash {
11
 
 
 
 
 
 
 
 
12
  /**
13
  * List of all registered plugins.
14
  *
374
  $user_name = $user->display_name;
375
  $admin_email = get_site_option( 'admin_email' );
376
 
377
+ $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!", 'wdev_frash' );
378
  $msg = apply_filters( 'wdev-email-message-' . $plugin->id, $msg );
379
 
380
  ?>
389
  </div>
390
  <div class="frash-notice-cta">
391
  <input type="email" name="email" value="<?php echo esc_attr( $admin_email ); ?>" />
392
+ <button class="frash-notice-act button-primary" data-msg="<?php _e( 'Thanks :)', 'wdev_frash' ); ?>">
393
  <?php echo esc_html( $plugin->cta_email ); ?>
394
  </button>
395
+ <button class="frash-notice-dismiss" data-msg="<?php _e( 'Saving', 'wdev_frash' ); ?>">
396
+ <?php _e( 'No thanks', 'wdev_frash' ); ?>
397
  </button>
398
  </div>
399
  <?php
409
  $user = wp_get_current_user();
410
  $user_name = $user->display_name;
411
 
412
+ $msg = __( "Hey %s, you've been using %s for a while now, and we hope you're happy with it.", 'wdev_frash' ) . '<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!", 'wdev_frash' );
413
  $msg = apply_filters( 'wdev-rating-message-' . $plugin->id, $msg );
414
 
415
  ?>
424
  ?>
425
  </div>
426
  <div class="frash-notice-cta">
427
+ <button class="frash-notice-act button-primary" data-msg="<?php _e( 'Thanks :)', 'wdev_frash' ); ?>">
428
  <?php
429
  printf(
430
+ __( 'Rate %s', 'wdev_frash' ),
431
  esc_html( $plugin->title )
432
  ); ?>
433
  </button>
434
+ <button class="frash-notice-dismiss" data-msg="<?php _e( 'Saving', 'wdev_frash' ); ?>">
435
+ <?php _e( 'No thanks', 'wdev_frash' ); ?>
436
  </button>
437
  </div>
438
  <?php
languages/wp-smushit.pot CHANGED
@@ -1,16 +1,21 @@
1
- # Copyright (C) 2016 WP Smush
2
- # This file is distributed under the same license as the WP Smush package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: WP Smush 2.2\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/wp-smushit\n"
7
- "POT-Creation-Date: 2016-04-12 10:56:34+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: 2016-MO-DA HO:MI+ZONE\n"
12
- "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
- "Language-Team: LANGUAGE <LL@li.org>\n"
 
 
 
 
 
 
14
 
15
  #: assets/shared-ui/plugin-ui.php:49
16
  msgid "Nothing found"
@@ -24,579 +29,1116 @@ msgstr ""
24
  msgid "Oops, we could not do this..."
25
  msgstr ""
26
 
27
- #: assets/shared-ui/plugin-ui.php:225 extras/free-dashboard/module.php:406
28
- #: extras/free-dashboard/module.php:445
29
  msgid "Saving"
30
  msgstr ""
31
 
32
- #: assets/shared-ui/plugin-ui.php:254
 
 
 
33
  msgid "Dismiss"
34
  msgstr ""
35
 
36
- #: extras/free-dashboard/module.php:388
37
- msgid "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!"
38
  msgstr ""
39
 
40
- #: extras/free-dashboard/module.php:403 extras/free-dashboard/module.php:438
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  msgid "Thanks :)"
42
  msgstr ""
43
 
44
- #: extras/free-dashboard/module.php:407 extras/free-dashboard/module.php:446
45
  msgid "No thanks"
46
  msgstr ""
47
 
48
- #: extras/free-dashboard/module.php:423
49
- msgid "Hey %s, you've been using %s for a while now, and we hope you're happy with it."
 
 
 
50
  msgstr ""
51
 
52
- #: extras/free-dashboard/module.php:423
53
- msgid "We've spent countless hours developing this free plugin for you, and we would really appreciate it if you dropped us a quick rating!"
 
 
54
  msgstr ""
55
 
56
- #: extras/free-dashboard/module.php:441
 
57
  msgid "Rate %s"
58
  msgstr ""
59
 
60
- #: lib/class-wp-smush-admin.php:153
 
 
 
 
 
 
 
 
61
  msgid "Automatically smush my images on upload"
62
  msgstr ""
63
 
64
- #: lib/class-wp-smush-admin.php:154
65
- msgid "When you upload images to the media library, we’ll automatically optimize them."
 
 
66
  msgstr ""
67
 
68
- #: lib/class-wp-smush-admin.php:157
69
  msgid "Preserve image EXIF data"
70
  msgstr ""
71
 
72
- #: lib/class-wp-smush-admin.php:158
73
- msgid "EXIF data stores camera settings, focal length, date, time and location information in image files. EXIF data makes image files larger but if you are a photographer you may want to preserve this information."
 
 
 
74
  msgstr ""
75
 
76
- #: lib/class-wp-smush-admin.php:161
 
 
 
 
 
 
 
 
 
 
 
77
  msgid "Super-smush my images"
78
  msgstr ""
79
 
80
- #: lib/class-wp-smush-admin.php:162
81
- msgid "Compress images up to 10x more than regular smush with almost no visible drop in quality."
 
 
82
  msgstr ""
83
 
84
- #: lib/class-wp-smush-admin.php:165
85
  msgid "Include my original full-size images"
86
  msgstr ""
87
 
88
- #: lib/class-wp-smush-admin.php:166
89
- msgid "WordPress crops and resizes every image you upload for embedding on your site. By default, Smush only compresses these cropped and resized images, not your original full-size images. To save space on your server, activate this setting to smush your original images, too. Note: This doesn’t usually improve page speed."
 
 
 
 
 
90
  msgstr ""
91
 
92
- #: lib/class-wp-smush-admin.php:169
93
  msgid "Make a copy of my original images"
94
  msgstr ""
95
 
96
- #: lib/class-wp-smush-admin.php:170
97
- msgid "Save your original full-size images so you can restore them at any point. Note: Activating this setting will significantly increase the size of your uploads folder by nearly twice as much."
 
 
 
98
  msgstr ""
99
 
100
- #: lib/class-wp-smush-admin.php:177
101
- msgid "Enable NextGen Gallery integration"
102
  msgstr ""
103
 
104
- #: lib/class-wp-smush-admin.php:178
105
- msgid "Allow smushing images directly through NextGen Gallery settings."
 
 
 
 
 
 
106
  msgstr ""
107
 
108
- #: lib/class-wp-smush-admin.php:197 lib/class-wp-smush-ui.php:607
109
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:70
110
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:89
111
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:91
 
112
  msgid "WP Smush"
113
  msgstr ""
114
 
115
- #: lib/class-wp-smush-admin.php:320 lib/class-wp-smush.php:939
116
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:159
117
- #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:277
118
  msgid "Super-Smush"
119
  msgstr ""
120
 
121
- #: lib/class-wp-smush-admin.php:321
122
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:160
123
  msgid "Smush Now"
124
  msgstr ""
125
 
126
- #: lib/class-wp-smush-admin.php:322
127
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:161
128
  msgid "{{errors}} image(s) were skipped due to an error."
129
  msgstr ""
130
 
131
- #: lib/class-wp-smush-admin.php:323
132
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:162
133
- msgid "All images are fully optimised."
134
  msgstr ""
135
 
136
- #: lib/class-wp-smush-admin.php:324
137
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:163
138
  msgid "Restoring image.."
139
  msgstr ""
140
 
141
- #: lib/class-wp-smush-admin.php:325
142
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:164
143
  msgid "Smushing image.."
144
  msgstr ""
145
 
146
- #: lib/class-wp-smush-admin.php:326
147
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:165
148
  msgid "Checking images.."
149
  msgstr ""
150
 
151
- #: lib/class-wp-smush-admin.php:504
152
- msgid "Smush request timed out, You can try setting a higher value for `WP_SMUSH_API_TIMEOUT`."
 
 
 
 
 
 
153
  msgstr ""
154
 
155
- #: lib/class-wp-smush-admin.php:526 lib/class-wp-smush-nextgen.php:379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  msgid "You don't have permission to work with uploaded files."
157
  msgstr ""
158
 
159
- #: lib/class-wp-smush-admin.php:530 lib/class-wp-smush-nextgen.php:383
160
  msgid "No attachment ID was provided."
161
  msgstr ""
162
 
163
- #: lib/class-wp-smush-admin.php:719
 
 
 
 
 
164
  msgid "<strong>%d of %d images</strong> were sent for smushing:"
165
  msgstr ""
166
 
167
- #: lib/class-wp-smush-admin.php:860 lib/class-wp-smush-admin.php:873
168
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:334
169
  msgid "Bulk Smush Now"
170
  msgstr ""
171
 
172
- #: lib/class-wp-smush-admin.php:867
173
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:338
174
- msgid "All Done!"
175
  msgstr ""
176
 
177
- #: lib/class-wp-smush-admin.php:906
 
 
 
 
 
178
  msgid "Settings"
179
  msgstr ""
180
 
181
- #: lib/class-wp-smush-admin.php:951
182
- msgid "THANKS FOR UPDATING SMUSH!"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  msgstr ""
184
 
185
- #: lib/class-wp-smush-admin.php:951
186
- msgid "HAPPY SMUSHING!"
 
 
 
 
 
 
 
 
187
  msgstr ""
188
 
189
- #: lib/class-wp-smush-admin.php:1104 lib/class-wp-smush-nextgen.php:466
190
  msgid "Error in processing restore action, Fields empty."
191
  msgstr ""
192
 
193
- #: lib/class-wp-smush-admin.php:1111 lib/class-wp-smush-nextgen.php:473
194
  msgid "Image not restored, Nonce verification failed."
195
  msgstr ""
196
 
197
- #: lib/class-wp-smush-admin.php:1185 lib/class-wp-smush-nextgen.php:548
198
  msgid "Unable to restore image"
199
  msgstr ""
200
 
201
- #: lib/class-wp-smush-admin.php:1202
202
- msgid "Image not smushed, fields empty."
203
  msgstr ""
204
 
205
- #: lib/class-wp-smush-admin.php:1209 lib/class-wp-smush-nextgen.php:566
206
- msgid "Image couldn't be smushed as the nonce verification failed, try reloading the page."
207
  msgstr ""
208
 
209
- #: lib/class-wp-smush-admin.php:1226
210
- msgid "Unable to smush image"
211
  msgstr ""
212
 
213
- #: lib/class-wp-smush-admin.php:1245
214
- msgid "Yay! All images are optimised as per your current settings."
215
  msgstr ""
216
 
217
- #: lib/class-wp-smush-admin.php:1371 lib/class-wp-smush-ui.php:584
218
- msgid "You have images that need smushing. %sBulk smush now!%s"
 
 
 
 
 
 
 
219
  msgstr ""
220
 
221
- #: lib/class-wp-smush-nextgen.php:334
222
- msgid "We couldn't find the metadata for the image, possibly the image has been deleted."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  msgstr ""
224
 
225
- #: lib/class-wp-smush-nextgen.php:559
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  msgid "We couldn't process the image, fields empty."
227
  msgstr ""
228
 
229
- #: lib/class-wp-smush-nextgen.php:583
 
230
  msgid "Unable to smush image, %s"
231
  msgstr ""
232
 
233
- #: lib/class-wp-smush-ui.php:53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  msgid "Dismiss Welcome notice"
235
  msgstr ""
236
 
237
- #: lib/class-wp-smush-ui.php:69
238
  msgid "WELCOME"
239
  msgstr ""
240
 
241
- #: lib/class-wp-smush-ui.php:77
242
  msgid "OH YEAH, IT'S COMPRESSION TIME!"
243
  msgstr ""
244
 
245
- #: lib/class-wp-smush-ui.php:78
246
- msgid "You've just installed %3$s, the most popular image compression plugin for WordPress! %1$sChoose your desired settings%2$s and get smushing!"
 
 
 
247
  msgstr ""
248
 
249
- #: lib/class-wp-smush-ui.php:92
 
250
  msgid "Smush individual images via your %sMedia Library%s"
251
  msgstr ""
252
 
253
- #: lib/class-wp-smush-ui.php:92
254
  msgid "Media Library"
255
  msgstr ""
256
 
257
- #: lib/class-wp-smush-ui.php:97
258
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:481
259
- msgid "BULK SMUSH"
260
- msgstr ""
261
-
262
- #: lib/class-wp-smush-ui.php:111
263
  msgid "SETTINGS"
264
  msgstr ""
265
 
266
- #: lib/class-wp-smush-ui.php:126
267
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:501
268
- msgid "Lets you check if any images can be further optimised. Useful after changing settings."
 
 
269
  msgstr ""
270
 
271
- #: lib/class-wp-smush-ui.php:126
272
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:501
273
  msgid "RE-CHECK IMAGES"
274
  msgstr ""
275
 
276
- #: lib/class-wp-smush-ui.php:127
277
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:502
278
  msgid "STATS"
279
  msgstr ""
280
 
281
- #: lib/class-wp-smush-ui.php:131
282
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:507
283
- msgid "TOTAL % REDUCTIONS"
284
  msgstr ""
285
 
286
- #: lib/class-wp-smush-ui.php:139
287
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:519
288
- msgid "TOTAL SIZE REDUCTIONS"
289
  msgstr ""
290
 
291
- #: lib/class-wp-smush-ui.php:146
292
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:528
293
- msgid "ATTACHMENTS SMUSHED"
294
  msgstr ""
295
 
296
- #: lib/class-wp-smush-ui.php:159
297
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:543
298
  msgid "ATTACHMENTS SUPER-SMUSHED"
299
  msgstr ""
300
 
301
- #: lib/class-wp-smush-ui.php:164
302
- msgid "%sENABLE%s"
 
303
  msgstr ""
304
 
305
- #: lib/class-wp-smush-ui.php:189
306
- msgid "UPDATE SETTINGS"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  msgstr ""
308
 
309
- #: lib/class-wp-smush-ui.php:203
310
- msgid "%sPRO ONLY%s"
311
  msgstr ""
312
 
313
- #: lib/class-wp-smush-ui.php:205
 
 
 
 
314
  msgid "ADVANCED SETTINGS"
315
  msgstr ""
316
 
317
- #: lib/class-wp-smush-ui.php:376
318
- msgid "TRY WP SMUSH PRO - DEV TEAM"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  msgstr ""
320
 
321
- #: lib/class-wp-smush-ui.php:392
322
  msgid "BOOST YOUR PERFORMANCE - HUMMINGBIRD"
323
  msgstr ""
324
 
325
- #: lib/class-wp-smush-ui.php:419
326
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:422
327
  msgid "No attachments found - Upload some images"
328
  msgstr ""
329
 
330
- #: lib/class-wp-smush-ui.php:421
331
- msgid "We haven’t found any images in your %smedia library%s yet so there’s no smushing to be done! Once you upload images, reload this page and start playing!"
 
 
 
 
332
  msgstr ""
333
 
334
- #: lib/class-wp-smush-ui.php:424
335
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:427
336
  msgid "UPLOAD IMAGES"
337
  msgstr ""
338
 
339
- #: lib/class-wp-smush-ui.php:429
340
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:432
341
- msgid "No attachments need smushing. Awesome!"
342
  msgstr ""
343
 
344
- #: lib/class-wp-smush-ui.php:434
345
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:437
346
  msgid "BULK SMUSH NOW"
347
  msgstr ""
348
 
349
- #: lib/class-wp-smush-ui.php:445
350
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:445
351
- msgid "%s, you have %s%s%d%s image%s that need smushing!"
352
- msgid_plural "%s, you have %s%s%d%s images%s that need smushing!"
 
353
  msgstr[0] ""
354
  msgstr[1] ""
355
 
356
- #: lib/class-wp-smush-ui.php:454
357
- msgid "Enable Super-smush in the Settings area to get even more savings with almost no noticeable quality loss."
 
358
  msgstr ""
359
 
360
- #: lib/class-wp-smush-ui.php:477
361
- msgid "%sBulk smush is currently running.%s You need to keep this page open."
362
  msgstr ""
363
 
364
- #: lib/class-wp-smush-ui.php:487
365
- msgid "%s%d%s of %d attachments have been smushed."
 
 
366
  msgstr ""
367
 
368
- #: lib/class-wp-smush-ui.php:493 lib/class-wp-smush-ui.php:523
369
- msgid "CANCEL"
 
 
 
370
  msgstr ""
371
 
372
- #: lib/class-wp-smush-ui.php:509
373
- msgid "%sBulk re-smush is currently running.%s You need to keep this page open."
 
374
  msgstr ""
375
 
376
- #: lib/class-wp-smush-ui.php:514
377
- msgid "%s%d%s image left to Re-Smush"
378
- msgid_plural "%s%d%s images left to Re-Smush"
 
379
  msgstr[0] ""
380
  msgstr[1] ""
381
 
382
- #: lib/class-wp-smush-ui.php:562
383
- msgid "%s, you have %s%s%d%s image%s that need re-compressing!"
384
- msgid_plural "%s, you have %s%s%d%s images%s that need re-compressing!"
385
- msgstr[0] ""
386
- msgstr[1] ""
387
-
388
- #: lib/class-wp-smush-ui.php:563
389
  msgid "Skip"
390
  msgstr ""
391
 
392
- #: lib/class-wp-smush-ui.php:577
393
  msgid "Your settings have been updated!"
394
  msgstr ""
395
 
396
- #: lib/class-wp-smush-ui.php:607
397
- msgid "WP Smush Pro"
 
 
 
398
  msgstr ""
399
 
400
- #: lib/class-wp-smush-ui.php:609
401
- msgid "Automatic smushing is %senabled%s. Newly uploaded images will be automagically compressed."
 
 
 
402
  msgstr ""
403
 
404
- #: lib/class-wp-smush-ui.php:609
405
- msgid "Automatic smushing is %sdisabled%s. Newly uploaded images will need to be manually smushed."
406
  msgstr ""
407
 
408
- #: lib/class-wp-smush-ui.php:636
409
- msgid "Thanks for installing Smush. We hope you like it!"
 
 
410
  msgstr ""
411
 
412
- #: lib/class-wp-smush-ui.php:637
413
- msgid "And hey, if you do, you can now try out Smush Pro for double the smushy goodness (benchmarked), entirely for free!"
414
  msgstr ""
415
 
416
- #: lib/class-wp-smush-ui.php:638
417
- msgid "FIND OUT MORE"
 
 
418
  msgstr ""
419
 
420
- #: lib/class-wp-smush-ui.php:640
421
- msgid "Did you know that you can now %stry out Smush Pro%s for FREE?"
 
 
422
  msgstr ""
423
 
424
- #: lib/class-wp-smush-ui.php:641
425
- msgid "Yep, Super Smush your images for double the savings, save originals and batch Smush thousands of images all at once.... no charge!!!"
 
 
 
 
426
  msgstr ""
427
 
428
- #: lib/class-wp-smush-ui.php:642
429
- msgid "TRY SMUSH PRO FOR FREE"
430
  msgstr ""
431
 
432
- #: lib/class-wp-smush-ui.php:665
433
- msgid "Did you know WP Smush Pro delivers up to 10x better compression, allows you to smush your originals and removes any bulk smushing limits? – %sTry it absolutely FREE%s"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  msgstr ""
435
 
436
- #: lib/class-wp-smush.php:142
437
  msgid "File path is empty"
438
  msgstr ""
439
 
440
- #: lib/class-wp-smush.php:147
 
441
  msgid "Could not find %s"
442
  msgstr ""
443
 
444
- #: lib/class-wp-smush.php:152
 
445
  msgid "%s is not writable"
446
  msgstr ""
447
 
448
- #: lib/class-wp-smush.php:162
 
449
  msgid "Skipped (%s), image not found. Attachment: %s"
450
  msgstr ""
451
 
452
- #: lib/class-wp-smush.php:167
 
453
  msgid "Skipped (%s), size limit exceeded. Attachment: %s"
454
  msgstr ""
455
 
456
- #: lib/class-wp-smush.php:186
457
  msgid "Unknown API error"
458
  msgstr ""
459
 
460
- #: lib/class-wp-smush.php:613
 
461
  msgid "Error posting to API: %s"
462
  msgstr ""
463
 
464
- #: lib/class-wp-smush.php:619
 
465
  msgid "Error posting to API: %s %s"
466
  msgstr ""
467
 
468
- #: lib/class-wp-smush.php:636
469
  msgid "Smush data corrupted, try again."
470
  msgstr ""
471
 
472
- #: lib/class-wp-smush.php:652
473
  msgid "Image couldn't be smushed"
474
  msgstr ""
475
 
476
- #: lib/class-wp-smush.php:866 lib/class-wp-smush.php:870
477
- #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:195
478
- #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:198
479
- msgid "Already Optimized"
480
- msgstr ""
481
-
482
- #: lib/class-wp-smush.php:879
483
  msgid "%d images reduced "
484
  msgstr ""
485
 
486
- #: lib/class-wp-smush.php:879
487
  msgid "Reduced "
488
  msgstr ""
489
 
490
- #: lib/class-wp-smush.php:880
491
- msgid "by %s ( %01.1f%% )"
 
 
 
 
 
 
492
  msgstr ""
493
 
494
- #: lib/class-wp-smush.php:914
495
  msgid "Detailed stats for all the image sizes"
496
  msgstr ""
497
 
498
- #: lib/class-wp-smush.php:914
499
- #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:238
500
  msgid "Smush stats"
501
  msgstr ""
502
 
503
- #: lib/class-wp-smush.php:946
504
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:247
505
  msgid "Not processed"
506
  msgstr ""
507
 
508
- #: lib/class-wp-smush.php:952
509
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:253
510
- msgid "Smush Now!"
511
- msgstr ""
512
-
513
- #: lib/class-wp-smush.php:1286
514
- msgid "When you upload an image to WordPress it automatically creates %s thumbnail sizes that are commonly used in your pages. WordPress also stores the original full-size image, but because these are not usually embedded on your site we don’t Smush them. Pro users can override this."
515
  msgstr ""
516
 
517
- #: lib/class-wp-smush.php:1289
518
- msgid "Image couldn't be smushed as it exceeded the 1Mb size limit, Pro users can smush images with size upto 32Mb."
 
 
519
  msgstr ""
520
 
521
- #: lib/class-wp-smush.php:1291
522
  msgid " Skipped"
523
  msgstr ""
524
 
525
- #: lib/class-wp-smush.php:1311
526
- #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:396
527
  msgid "Image size"
528
  msgstr ""
529
 
530
- #: lib/class-wp-smush.php:1312
531
- #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:397
532
  msgid "Savings"
533
  msgstr ""
534
 
535
- #: lib/class-wp-smush.php:1494
536
  msgid "Restore original image."
537
  msgstr ""
538
 
539
- #: lib/class-wp-smush.php:1494
540
  msgid "Restore image"
541
  msgstr ""
542
 
543
- #: lib/class-wp-smush.php:1539
544
  msgid "Smush image including original file."
545
  msgstr ""
546
 
547
- #: lib/class-wp-smush.php:1539
548
  msgid "Resmush image"
549
  msgstr ""
550
 
551
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:70
552
  msgid "Bulk WP Smush"
553
  msgstr ""
554
 
555
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:424
556
- msgid "We haven’t found any images in your %sgallery%s yet, so there’s no smushing to be done! Once you upload images, reload this page and start playing!"
 
 
 
557
  msgstr ""
558
 
559
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:461
560
- msgid "Enable Super-smush in the %sSettings%s area to get even more savings with almost no noticeable quality loss."
 
 
 
561
  msgstr ""
562
 
563
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:476
 
564
  msgid "Smush individual images via your %sManage Galleries%s section"
565
  msgstr ""
566
 
567
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:476
568
  msgid "Manage Galleries"
569
  msgstr ""
570
 
571
- #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:551
 
 
 
 
 
572
  msgid "%sDISABLED%s"
573
  msgstr ""
574
 
575
- #: lib/nextgen-integration/class-wp-smush-nextgen-bulk.php:43
576
- msgid "Smush request timed out, You can try setting a higher value ( > 60 ) for `WP_SMUSH_API_TIMEOUT`."
 
 
577
  msgstr ""
578
 
579
- #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:207
 
580
  msgid "Reduced by %s ( %01.1f%% )"
581
  msgstr ""
582
 
583
- #: wp-smush.php:131
584
  msgid "Get Fast"
585
  msgstr ""
586
 
587
- #: wp-smush.php:185
588
  msgid "WP Smush Free was deactivated. You have WP Smush Pro active!"
589
  msgstr ""
590
- #. Plugin Name of the plugin/theme
591
- msgid "WP Smush"
592
- msgstr ""
593
 
594
  #. Plugin URI of the plugin/theme
595
  msgid "http://wordpress.org/extend/plugins/wp-smushit/"
596
  msgstr ""
597
 
598
  #. Description of the plugin/theme
599
- 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."
 
 
 
600
  msgstr ""
601
 
602
  #. Author of the plugin/theme
1
+ #, fuzzy
 
2
  msgid ""
3
  msgstr ""
4
+ "Project-Id-Version: WP Smush 2.7.4\n"
5
  "Report-Msgid-Bugs-To: http://wordpress.org/support/plugin/wp-smushit\n"
6
+ "POT-Creation-Date: 2017-07-18 04:14:20+00:00\n"
7
  "MIME-Version: 1.0\n"
8
  "Content-Type: text/plain; charset=UTF-8\n"
9
  "Content-Transfer-Encoding: 8bit\n"
10
+ "X-Generator: Poedit 1.8.1\n"
11
+ "X-Poedit-Basepath: ..\n"
12
+ "X-Poedit-WPHeader: wp-smush.php\n"
13
+ "X-Poedit-SourceCharset: UTF-8\n"
14
+ "X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
15
+ "esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
16
+ "_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+ "X-Poedit-SearchPathExcluded-0: *.js\n"
19
 
20
  #: assets/shared-ui/plugin-ui.php:49
21
  msgid "Nothing found"
29
  msgid "Oops, we could not do this..."
30
  msgstr ""
31
 
32
+ #: assets/shared-ui/plugin-ui.php:272 extras/free-dashboard/module.php:395
33
+ #: extras/free-dashboard/module.php:434 lib/class-wp-smush-ui.php:890
34
  msgid "Saving"
35
  msgstr ""
36
 
37
+ #: assets/shared-ui/plugin-ui.php:301
38
+ #: extras/dash-notice/wpmudev-dash-notification.php:248
39
+ #: extras/dash-notice/wpmudev-dash-notification.php:289
40
+ #: lib/class-wp-smush-ui.php:890
41
  msgid "Dismiss"
42
  msgstr ""
43
 
44
+ #: extras/dash-notice/wpmudev-dash-notification.php:223
45
+ msgid "install"
46
  msgstr ""
47
 
48
+ #: extras/dash-notice/wpmudev-dash-notification.php:230
49
+ #, php-format
50
+ msgid ""
51
+ "Important updates are available for <strong>%s</strong>. Install the free "
52
+ "WPMU DEV Dashboard plugin now for updates and support!"
53
+ msgstr ""
54
+
55
+ #: extras/dash-notice/wpmudev-dash-notification.php:232
56
+ #, php-format
57
+ msgid ""
58
+ "<strong>%s</strong> is almost ready - install the free WPMU DEV Dashboard "
59
+ "plugin for updates and support!"
60
+ msgstr ""
61
+
62
+ #: extras/dash-notice/wpmudev-dash-notification.php:236
63
+ msgid ""
64
+ "Important updates are available for your WPMU DEV plugins/themes. Install "
65
+ "the free WPMU DEV Dashboard plugin now for updates and support!"
66
+ msgstr ""
67
+
68
+ #: extras/dash-notice/wpmudev-dash-notification.php:238
69
+ msgid ""
70
+ "Almost ready - install the free WPMU DEV Dashboard plugin for updates and "
71
+ "support!"
72
+ msgstr ""
73
+
74
+ #: extras/dash-notice/wpmudev-dash-notification.php:244
75
+ msgid "Install Plugin"
76
+ msgstr ""
77
+
78
+ #: extras/dash-notice/wpmudev-dash-notification.php:247
79
+ #: extras/dash-notice/wpmudev-dash-notification.php:288
80
+ msgid "Saving..."
81
+ msgstr ""
82
+
83
+ #: extras/dash-notice/wpmudev-dash-notification.php:264
84
+ msgid "activate"
85
+ msgstr ""
86
+
87
+ #: extras/dash-notice/wpmudev-dash-notification.php:271
88
+ #, php-format
89
+ msgid ""
90
+ "Important updates are available for <strong>%s</strong>. Activate the WPMU "
91
+ "DEV Dashboard to update now!"
92
+ msgstr ""
93
+
94
+ #: extras/dash-notice/wpmudev-dash-notification.php:273
95
+ #, php-format
96
+ msgid ""
97
+ "Just one more step to enable updates and support for <strong>%s</strong>!"
98
+ msgstr ""
99
+
100
+ #: extras/dash-notice/wpmudev-dash-notification.php:277
101
+ msgid ""
102
+ "Important updates are available for your WPMU DEV plugins/themes. Activate "
103
+ "the WPMU DEV Dashboard to update now!"
104
+ msgstr ""
105
+
106
+ #: extras/dash-notice/wpmudev-dash-notification.php:279
107
+ msgid ""
108
+ "Just one more step - activate the WPMU DEV Dashboard plugin and you're all "
109
+ "done!"
110
+ msgstr ""
111
+
112
+ #: extras/dash-notice/wpmudev-dash-notification.php:285
113
+ msgid "Activate WPMU DEV Dashboard"
114
+ msgstr ""
115
+
116
+ #: extras/dash-notice/wpmudev-dash-notification.php:952
117
+ msgid "We did not find any data for this plugin or theme..."
118
+ msgstr ""
119
+
120
+ #: extras/dash-notice/wpmudev-dash-notification.php:1131
121
+ #, php-format
122
+ msgid "%s changelog"
123
+ msgstr ""
124
+
125
+ #: extras/dash-notice/wpmudev-dash-notification.php:1161
126
+ msgid "Current"
127
+ msgstr ""
128
+
129
+ #: extras/dash-notice/wpmudev-dash-notification.php:1167
130
+ msgid "New"
131
+ msgstr ""
132
+
133
+ #: extras/dash-notice/wpmudev-dash-notification.php:1184
134
+ #, php-format
135
+ msgid "Version %s"
136
+ msgstr ""
137
+
138
+ #: extras/dash-notice/wpmudev-dash-notification.php:1202
139
+ msgid "Show all changes"
140
+ msgstr ""
141
+
142
+ #: extras/dash-notice/wpmudev-dash-notification.php:1203
143
+ msgid "Hide details"
144
+ msgstr ""
145
+
146
+ #: extras/free-dashboard/module.php:377
147
+ #, php-format
148
+ msgid ""
149
+ "We're happy that you've chosen to install %s! Are you interested in how to "
150
+ "make the most of this plugin? How would you like a quick 5 day email crash "
151
+ "course with actionable advice on building your membership site? Only the "
152
+ "info you want, no subscription!"
153
+ msgstr ""
154
+
155
+ #: extras/free-dashboard/module.php:392 extras/free-dashboard/module.php:427
156
  msgid "Thanks :)"
157
  msgstr ""
158
 
159
+ #: extras/free-dashboard/module.php:396 extras/free-dashboard/module.php:435
160
  msgid "No thanks"
161
  msgstr ""
162
 
163
+ #: extras/free-dashboard/module.php:412
164
+ #, php-format
165
+ msgid ""
166
+ "Hey %s, you've been using %s for a while now, and we hope you're happy with "
167
+ "it."
168
  msgstr ""
169
 
170
+ #: extras/free-dashboard/module.php:412
171
+ msgid ""
172
+ "We've spent countless hours developing this free plugin for you, and we "
173
+ "would really appreciate it if you dropped us a quick rating!"
174
  msgstr ""
175
 
176
+ #: extras/free-dashboard/module.php:430
177
+ #, php-format
178
  msgid "Rate %s"
179
  msgstr ""
180
 
181
+ #: lib/class-wp-smush-admin.php:209
182
+ msgid "Enable Network wide settings"
183
+ msgstr ""
184
+
185
+ #: lib/class-wp-smush-admin.php:210
186
+ msgid "If disabled sub sites can override the individual Smush settings."
187
+ msgstr ""
188
+
189
+ #: lib/class-wp-smush-admin.php:213
190
  msgid "Automatically smush my images on upload"
191
  msgstr ""
192
 
193
+ #: lib/class-wp-smush-admin.php:214
194
+ msgid ""
195
+ "When you upload images to the media library, we’ll automatically optimize "
196
+ "them."
197
  msgstr ""
198
 
199
+ #: lib/class-wp-smush-admin.php:217
200
  msgid "Preserve image EXIF data"
201
  msgstr ""
202
 
203
+ #: lib/class-wp-smush-admin.php:218
204
+ msgid ""
205
+ "EXIF data stores camera settings, focal length, date, time and location "
206
+ "information in image files. EXIF data makes image files larger but if you "
207
+ "are a photographer you may want to preserve this information."
208
  msgstr ""
209
 
210
+ #: lib/class-wp-smush-admin.php:221
211
+ msgid "Resize original images"
212
+ msgstr ""
213
+
214
+ #: lib/class-wp-smush-admin.php:222
215
+ msgid ""
216
+ "Save a ton of space by not storing over-sized images on your server. Set "
217
+ "image maximum width and height and large images will be automatically scaled "
218
+ "before being added to the media library."
219
+ msgstr ""
220
+
221
+ #: lib/class-wp-smush-admin.php:225
222
  msgid "Super-smush my images"
223
  msgstr ""
224
 
225
+ #: lib/class-wp-smush-admin.php:226
226
+ msgid ""
227
+ "Compress images up to 2x more than regular smush with almost no visible drop "
228
+ "in quality."
229
  msgstr ""
230
 
231
+ #: lib/class-wp-smush-admin.php:229
232
  msgid "Include my original full-size images"
233
  msgstr ""
234
 
235
+ #: lib/class-wp-smush-admin.php:230
236
+ msgid ""
237
+ "WordPress crops and resizes every image you upload for embedding on your "
238
+ "site. By default, Smush only compresses these cropped and resized images, "
239
+ "not your original full-size images. To save space on your server, activate "
240
+ "this setting to smush your original images, too. Note: This doesn’t usually "
241
+ "improve page speed."
242
  msgstr ""
243
 
244
+ #: lib/class-wp-smush-admin.php:233
245
  msgid "Make a copy of my original images"
246
  msgstr ""
247
 
248
+ #: lib/class-wp-smush-admin.php:234
249
+ msgid ""
250
+ "Save your original full-size images so you can restore them at any point. "
251
+ "Note: Activating this setting will significantly increase the size of your "
252
+ "uploads folder by nearly twice as much."
253
  msgstr ""
254
 
255
+ #: lib/class-wp-smush-admin.php:237
256
+ msgid "Convert PNG to JPEG (lossy)"
257
  msgstr ""
258
 
259
+ #: lib/class-wp-smush-admin.php:238
260
+ #, php-format
261
+ msgid ""
262
+ "When you compress a PNG file, Smush will check if converting the file to "
263
+ "JPEG will further reduce its size. %s Note: PNGs with transparency will be "
264
+ "ignored and Smush will only convert the file format if it results in a "
265
+ "smaller file size. This will change the file’s name and extension, and any "
266
+ "hard-coded URLs will need to be updated.%s"
267
  msgstr ""
268
 
269
+ #. Plugin Name of the plugin/theme
270
+ #: lib/class-wp-smush-admin.php:266 lib/class-wp-smush-ui.php:823
271
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:71
272
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:90
273
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:92
274
  msgid "WP Smush"
275
  msgstr ""
276
 
277
+ #: lib/class-wp-smush-admin.php:394 lib/class-wp-smush.php:1058
278
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:159
279
+ #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:275
280
  msgid "Super-Smush"
281
  msgstr ""
282
 
283
+ #: lib/class-wp-smush-admin.php:395
284
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:160
285
  msgid "Smush Now"
286
  msgstr ""
287
 
288
+ #: lib/class-wp-smush-admin.php:396
289
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:161
290
  msgid "{{errors}} image(s) were skipped due to an error."
291
  msgstr ""
292
 
293
+ #: lib/class-wp-smush-admin.php:397
294
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:162
295
+ msgid "All images are fully optimized."
296
  msgstr ""
297
 
298
+ #: lib/class-wp-smush-admin.php:398
299
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:163
300
  msgid "Restoring image.."
301
  msgstr ""
302
 
303
+ #: lib/class-wp-smush-admin.php:399
304
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:164
305
  msgid "Smushing image.."
306
  msgstr ""
307
 
308
+ #: lib/class-wp-smush-admin.php:400
309
  #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:165
310
  msgid "Checking images.."
311
  msgstr ""
312
 
313
+ #: lib/class-wp-smush-admin.php:401
314
+ msgid ""
315
+ "We successfully verified your membership, all the Pro features should work "
316
+ "completely. "
317
+ msgstr ""
318
+
319
+ #: lib/class-wp-smush-admin.php:402
320
+ msgid "Your membership couldn't be verified."
321
  msgstr ""
322
 
323
+ #: lib/class-wp-smush-admin.php:403
324
+ msgid "Missing file path."
325
+ msgstr ""
326
+
327
+ #: lib/class-wp-smush-admin.php:405
328
+ msgid "image could not be smushed."
329
+ msgstr ""
330
+
331
+ #: lib/class-wp-smush-admin.php:406
332
+ msgid "images could not be smushed."
333
+ msgstr ""
334
+
335
+ #: lib/class-wp-smush-admin.php:407 lib/class-wp-smush.php:974
336
+ #: lib/class-wp-smush.php:978
337
+ #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:193
338
+ #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:196
339
+ msgid "Already Optimized"
340
+ msgstr ""
341
+
342
+ #: lib/class-wp-smush-admin.php:408
343
+ msgid "Ajax Error"
344
+ msgstr ""
345
+
346
+ #: lib/class-wp-smush-admin.php:409 lib/class-wp-smush-admin.php:410
347
+ #: lib/class-wp-smush-admin.php:1270
348
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:354
349
+ msgid "All Done!"
350
+ msgstr ""
351
+
352
+ #: lib/class-wp-smush-admin.php:691
353
+ msgid ""
354
+ "Smush request timed out, You can try setting a higher value for "
355
+ "`WP_SMUSH_API_TIMEOUT`."
356
+ msgstr ""
357
+
358
+ #: lib/class-wp-smush-admin.php:745 lib/class-wp-smush-nextgen.php:432
359
  msgid "You don't have permission to work with uploaded files."
360
  msgstr ""
361
 
362
+ #: lib/class-wp-smush-admin.php:749 lib/class-wp-smush-nextgen.php:436
363
  msgid "No attachment ID was provided."
364
  msgstr ""
365
 
366
+ #: lib/class-wp-smush-admin.php:761
367
+ msgid "Attachment Skipped - Check `wp_smush_image` filter."
368
+ msgstr ""
369
+
370
+ #: lib/class-wp-smush-admin.php:948
371
+ #, php-format
372
  msgid "<strong>%d of %d images</strong> were sent for smushing:"
373
  msgstr ""
374
 
375
+ #: lib/class-wp-smush-admin.php:1263 lib/class-wp-smush-admin.php:1276
376
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:350
377
  msgid "Bulk Smush Now"
378
  msgstr ""
379
 
380
+ #: lib/class-wp-smush-admin.php:1298 lib/class-wp-smush.php:1064
381
+ msgid "Smushing in progress.."
 
382
  msgstr ""
383
 
384
+ #: lib/class-wp-smush-admin.php:1304 lib/class-wp-smush.php:1083
385
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:269
386
+ msgid "Smush Now!"
387
+ msgstr ""
388
+
389
+ #: lib/class-wp-smush-admin.php:1325
390
  msgid "Settings"
391
  msgstr ""
392
 
393
+ #: lib/class-wp-smush-admin.php:1476
394
+ msgid "Image not smushed, fields empty."
395
+ msgstr ""
396
+
397
+ #: lib/class-wp-smush-admin.php:1483 lib/class-wp-smush-nextgen.php:619
398
+ msgid ""
399
+ "Image couldn't be smushed as the nonce verification failed, try reloading "
400
+ "the page."
401
+ msgstr ""
402
+
403
+ #: lib/class-wp-smush-admin.php:1500
404
+ msgid "Unable to smush image"
405
+ msgstr ""
406
+
407
+ #: lib/class-wp-smush-admin.php:1525
408
+ msgid ""
409
+ "We haven’t found any images in your media library yet so there’s no smushing "
410
+ "to be done!"
411
+ msgstr ""
412
+
413
+ #: lib/class-wp-smush-admin.php:1541
414
+ msgid "Yay! All images are optimized as per your current settings."
415
+ msgstr ""
416
+
417
+ #: lib/class-wp-smush-admin.php:1745 lib/class-wp-smush-ui.php:798
418
+ #, php-format
419
+ msgid "You have images that need smushing. %sBulk smush now!%s"
420
+ msgstr ""
421
+
422
+ #: lib/class-wp-smush-admin.php:2122
423
+ msgid "Review your setting now."
424
+ msgstr ""
425
+
426
+ #: lib/class-wp-smush-admin.php:2123 lib/class-wp-smush-dir.php:249
427
+ #: lib/class-wp-smush-dir.php:275 lib/class-wp-smush-ui.php:686
428
+ #: lib/class-wp-smush-ui.php:823
429
+ msgid "WP Smush Pro"
430
+ msgstr ""
431
+
432
+ #: lib/class-wp-smush-admin.php:2124
433
+ msgid ""
434
+ "Welcome to the newest version of WP Smush! In this update we've added the "
435
+ "ability to bulk smush images in directories outside your uploads folder."
436
  msgstr ""
437
 
438
+ #: lib/class-wp-smush-admin.php:2127
439
+ #, php-format
440
+ msgid ""
441
+ " And as a multisite user, you can manage %sSmush settings%s globally across "
442
+ "all sites!"
443
+ msgstr ""
444
+
445
+ #: lib/class-wp-smush-admin.php:2130
446
+ #, php-format
447
+ msgid " %sFind out more here >>%s"
448
  msgstr ""
449
 
450
+ #: lib/class-wp-smush-backup.php:148 lib/class-wp-smush-nextgen.php:519
451
  msgid "Error in processing restore action, Fields empty."
452
  msgstr ""
453
 
454
+ #: lib/class-wp-smush-backup.php:155 lib/class-wp-smush-nextgen.php:526
455
  msgid "Image not restored, Nonce verification failed."
456
  msgstr ""
457
 
458
+ #: lib/class-wp-smush-backup.php:282 lib/class-wp-smush-nextgen.php:601
459
  msgid "Unable to restore image"
460
  msgstr ""
461
 
462
+ #: lib/class-wp-smush-dir.php:88
463
+ msgid "DIRECTORY SMUSH SAVINGS"
464
  msgstr ""
465
 
466
+ #: lib/class-wp-smush-dir.php:90
467
+ msgid "Updating Stats"
468
  msgstr ""
469
 
470
+ #: lib/class-wp-smush-dir.php:104
471
+ msgid "SMUSH DIRECTORY"
472
  msgstr ""
473
 
474
+ #: lib/class-wp-smush-dir.php:219
475
+ msgid "RESUME LAST SCAN"
476
  msgstr ""
477
 
478
+ #: lib/class-wp-smush-dir.php:251
479
+ msgid "DIRECTORY SMUSH"
480
+ msgstr ""
481
+
482
+ #: lib/class-wp-smush-dir.php:256
483
+ msgid ""
484
+ "In addition to smushing your media uploads, you may want to also smush "
485
+ "images living outside your uploads directory. Simply add any directories you "
486
+ "wish to smush and bulk smush away!"
487
  msgstr ""
488
 
489
+ #: lib/class-wp-smush-dir.php:269
490
+ msgid ""
491
+ "All images for the selected directory are smushed and up to date. Awesome!"
492
+ msgstr ""
493
+
494
+ #: lib/class-wp-smush-dir.php:272
495
+ #, php-format
496
+ msgid ""
497
+ "%s/%s image(s) were successfully smushed, however %s image(s) could not be "
498
+ "smushed due to an error."
499
+ msgstr ""
500
+
501
+ #: lib/class-wp-smush-dir.php:275
502
+ #, php-format
503
+ msgid ""
504
+ " %sUpgrade to pro%s to bulk smush all your directory images with one click. "
505
+ "Free users can smush 50 images with each click."
506
+ msgstr ""
507
+
508
+ #: lib/class-wp-smush-dir.php:279 lib/class-wp-smush-ui.php:90
509
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:496
510
+ msgid "BULK SMUSH"
511
+ msgstr ""
512
+
513
+ #: lib/class-wp-smush-dir.php:281
514
+ msgid "Click to stop the directory smushing process."
515
  msgstr ""
516
 
517
+ #: lib/class-wp-smush-dir.php:282 lib/class-wp-smush-ui.php:734
518
+ msgid "CANCEL"
519
+ msgstr ""
520
+
521
+ #: lib/class-wp-smush-dir.php:290
522
+ msgid "CHOOSE DIRECTORY"
523
+ msgstr ""
524
+
525
+ #: lib/class-wp-smush-dir.php:299
526
+ msgid "Directory list"
527
+ msgstr ""
528
+
529
+ #: lib/class-wp-smush-dir.php:302
530
+ msgid "Choose the folder you wish to smush."
531
+ msgstr ""
532
+
533
+ #: lib/class-wp-smush-dir.php:306
534
+ msgid ""
535
+ "Smush will also include any images in sub folders of your selected folder."
536
+ msgstr ""
537
+
538
+ #: lib/class-wp-smush-dir.php:309
539
+ msgid "ADD DIRECTORY"
540
+ msgstr ""
541
+
542
+ #: lib/class-wp-smush-dir.php:472
543
+ msgid "Exclude directory from Smush List"
544
+ msgstr ""
545
+
546
+ #: lib/class-wp-smush-dir.php:606
547
+ msgid "We could not find any images in the selected directory."
548
+ msgstr ""
549
+
550
+ #: lib/class-wp-smush-dir.php:916
551
+ #, php-format
552
+ msgid "%d images"
553
+ msgstr ""
554
+
555
+ #: lib/class-wp-smush-dir.php:945
556
+ msgid "Waiting.."
557
+ msgstr ""
558
+
559
+ #: lib/class-wp-smush-dir.php:1067
560
+ msgid "Incorrect image id"
561
+ msgstr ""
562
+
563
+ #: lib/class-wp-smush-dir.php:1101
564
+ msgid "Could not find image id in last scanned images"
565
+ msgstr ""
566
+
567
+ #: lib/class-wp-smush-dir.php:1114
568
+ msgid "Image couldn't be optimized"
569
+ msgstr ""
570
+
571
+ #: lib/class-wp-smush-dir.php:1158 lib/class-wp-smush-dir.php:1291
572
+ #, php-format
573
+ msgid "You've smushed %d images in total."
574
+ msgstr ""
575
+
576
+ #: lib/class-wp-smush-dir.php:1235
577
+ msgid ""
578
+ "We were unable to retrieve the image list from last scan, please continue "
579
+ "with a latest scan"
580
+ msgstr ""
581
+
582
+ #: lib/class-wp-smush-nextgen.php:66
583
+ msgid "Enable NextGen Gallery integration"
584
+ msgstr ""
585
+
586
+ #: lib/class-wp-smush-nextgen.php:67
587
+ msgid "Allow smushing images directly through NextGen Gallery settings."
588
+ msgstr ""
589
+
590
+ #: lib/class-wp-smush-nextgen.php:373
591
+ msgid ""
592
+ "We couldn't find the metadata for the image, possibly the image has been "
593
+ "deleted."
594
+ msgstr ""
595
+
596
+ #: lib/class-wp-smush-nextgen.php:612
597
  msgid "We couldn't process the image, fields empty."
598
  msgstr ""
599
 
600
+ #: lib/class-wp-smush-nextgen.php:636
601
+ #, php-format
602
  msgid "Unable to smush image, %s"
603
  msgstr ""
604
 
605
+ #: lib/class-wp-smush-s3.php:56
606
+ msgid "Amazon S3 support"
607
+ msgstr ""
608
+
609
+ #: lib/class-wp-smush-s3.php:57
610
+ #, php-format
611
+ msgid ""
612
+ "Optimize your images stored on Amazon S3. This feature uses the %sWP Offload "
613
+ "S3%s plugin and is needed if the option %sRemove Files From Server%s is "
614
+ "enabled. Images will be smushed as per your current settings."
615
+ msgstr ""
616
+
617
+ #: lib/class-wp-smush-s3.php:101
618
+ #, php-format
619
+ msgid ""
620
+ "We are having trouble interacting with WP S3 Offload, make sure the plugin "
621
+ "is activated. Or you can %sreport a bug%s."
622
+ msgstr ""
623
+
624
+ #: lib/class-wp-smush-s3.php:108
625
+ #, php-format
626
+ msgid ""
627
+ "It seems you haven't finished setting up WP S3 Offload yet, %sConfigure%s it "
628
+ "now to enable Amazon S3 support."
629
+ msgstr ""
630
+
631
+ #: lib/class-wp-smush-share.php:24
632
+ #, php-format
633
+ msgid ""
634
+ "%s, you've smushed %s%d%s images and saved %s%s%s in total. Help your "
635
+ "friends save bandwidth easily, and help me in my quest to Smush the internet!"
636
+ msgstr ""
637
+
638
+ #: lib/class-wp-smush-share.php:25
639
+ #, php-format
640
+ msgid ""
641
+ "I saved %s%s%s on my site with WP Smush ( %s ) - wanna make your website "
642
+ "light and faster?"
643
+ msgstr ""
644
+
645
+ #: lib/class-wp-smush-share.php:33
646
+ msgid "TWEET"
647
+ msgstr ""
648
+
649
+ #: lib/class-wp-smush-share.php:37
650
+ msgid "SHARE"
651
+ msgstr ""
652
+
653
+ #: lib/class-wp-smush-share.php:41
654
+ msgid "WhatsApp"
655
+ msgstr ""
656
+
657
+ #: lib/class-wp-smush-ui.php:46
658
  msgid "Dismiss Welcome notice"
659
  msgstr ""
660
 
661
+ #: lib/class-wp-smush-ui.php:62
662
  msgid "WELCOME"
663
  msgstr ""
664
 
665
+ #: lib/class-wp-smush-ui.php:70
666
  msgid "OH YEAH, IT'S COMPRESSION TIME!"
667
  msgstr ""
668
 
669
+ #: lib/class-wp-smush-ui.php:71
670
+ #, php-format
671
+ msgid ""
672
+ "You've just installed %3$s, the most popular image compression plugin for "
673
+ "WordPress! %1$sChoose your desired settings%2$s and get smushing!"
674
  msgstr ""
675
 
676
+ #: lib/class-wp-smush-ui.php:85
677
+ #, php-format
678
  msgid "Smush individual images via your %sMedia Library%s"
679
  msgstr ""
680
 
681
+ #: lib/class-wp-smush-ui.php:85
682
  msgid "Media Library"
683
  msgstr ""
684
 
685
+ #: lib/class-wp-smush-ui.php:104
 
 
 
 
 
686
  msgid "SETTINGS"
687
  msgstr ""
688
 
689
+ #: lib/class-wp-smush-ui.php:117
690
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:513
691
+ msgid ""
692
+ "Lets you check if any images can be further optimized. Useful after changing "
693
+ "settings."
694
  msgstr ""
695
 
696
+ #: lib/class-wp-smush-ui.php:117
697
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:513
698
  msgid "RE-CHECK IMAGES"
699
  msgstr ""
700
 
701
+ #: lib/class-wp-smush-ui.php:118
702
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:514
703
  msgid "STATS"
704
  msgstr ""
705
 
706
+ #: lib/class-wp-smush-ui.php:121
707
+ #, php-format
708
+ msgid "You've smushed %d images in total"
709
  msgstr ""
710
 
711
+ #: lib/class-wp-smush-ui.php:146
712
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:542
713
+ msgid "IMAGES SMUSHED"
714
  msgstr ""
715
 
716
+ #: lib/class-wp-smush-ui.php:152
717
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:548
718
+ msgid "TOTAL SAVINGS"
719
  msgstr ""
720
 
721
+ #: lib/class-wp-smush-ui.php:168
 
722
  msgid "ATTACHMENTS SUPER-SMUSHED"
723
  msgstr ""
724
 
725
+ #: lib/class-wp-smush-ui.php:176 lib/class-wp-smush-ui.php:179
726
+ #, php-format
727
+ msgid "%sENABLE SUPER-SMUSH%s"
728
  msgstr ""
729
 
730
+ #: lib/class-wp-smush-ui.php:187
731
+ msgid "RESIZE SAVINGS"
732
+ msgstr ""
733
+
734
+ #: lib/class-wp-smush-ui.php:195 lib/class-wp-smush-ui.php:198
735
+ #, php-format
736
+ msgid "%sENABLE IMAGE RESIZING%s"
737
+ msgstr ""
738
+
739
+ #: lib/class-wp-smush-ui.php:201
740
+ #, php-format
741
+ msgid "%sNO RESIZE SAVINGS AVAILABLE%s"
742
+ msgstr ""
743
+
744
+ #: lib/class-wp-smush-ui.php:210
745
+ msgid "PNG TO JPEG SAVINGS"
746
+ msgstr ""
747
+
748
+ #: lib/class-wp-smush-ui.php:241 lib/class-wp-smush-ui.php:285
749
+ #, php-format
750
+ msgid "%sPRO FEATURE%s"
751
+ msgstr ""
752
+
753
+ #: lib/class-wp-smush-ui.php:241 lib/class-wp-smush-ui.php:285
754
+ msgid "Join WPMU DEV to try Smush Pro for free."
755
  msgstr ""
756
 
757
+ #: lib/class-wp-smush-ui.php:245
758
+ msgid "BASED ON AVERAGE SAVINGS IF YOU UPGRADE TO PRO"
759
  msgstr ""
760
 
761
+ #: lib/class-wp-smush-ui.php:245
762
+ msgid "PRO SAVINGS ESTIMATE"
763
+ msgstr ""
764
+
765
+ #: lib/class-wp-smush-ui.php:287
766
  msgid "ADVANCED SETTINGS"
767
  msgstr ""
768
 
769
+ #: lib/class-wp-smush-ui.php:437
770
+ msgid "The following image sizes will be optimized by WP Smush:"
771
+ msgstr ""
772
+
773
+ #: lib/class-wp-smush-ui.php:487
774
+ msgid "Max width"
775
+ msgstr ""
776
+
777
+ #: lib/class-wp-smush-ui.php:490
778
+ msgid "Max height"
779
+ msgstr ""
780
+
781
+ #: lib/class-wp-smush-ui.php:493
782
+ #, php-format
783
+ msgid "Currently, your largest image size is set at %s%dpx wide x %dpx high%s."
784
+ msgstr ""
785
+
786
+ #: lib/class-wp-smush-ui.php:494
787
+ msgid ""
788
+ "Just to let you know, the width you've entered is less than your largest "
789
+ "image and may result in pixelation."
790
+ msgstr ""
791
+
792
+ #: lib/class-wp-smush-ui.php:495
793
+ msgid ""
794
+ "Just to let you know, the height you’ve entered is less than your largest "
795
+ "image and may result in pixelation."
796
  msgstr ""
797
 
798
+ #: lib/class-wp-smush-ui.php:623
799
  msgid "BOOST YOUR PERFORMANCE - HUMMINGBIRD"
800
  msgstr ""
801
 
802
+ #: lib/class-wp-smush-ui.php:650
803
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:437
804
  msgid "No attachments found - Upload some images"
805
  msgstr ""
806
 
807
+ #: lib/class-wp-smush-ui.php:652
808
+ #, php-format
809
+ msgid ""
810
+ "We haven’t found any images in your %smedia library%s yet so there’s no "
811
+ "smushing to be done! Once you upload images, reload this page and start "
812
+ "playing!"
813
  msgstr ""
814
 
815
+ #: lib/class-wp-smush-ui.php:655
816
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:442
817
  msgid "UPLOAD IMAGES"
818
  msgstr ""
819
 
820
+ #: lib/class-wp-smush-ui.php:660
821
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:447
822
+ msgid "All images are smushed and up to date. Awesome!"
823
  msgstr ""
824
 
825
+ #: lib/class-wp-smush-ui.php:665
826
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:452
827
  msgid "BULK SMUSH NOW"
828
  msgstr ""
829
 
830
+ #: lib/class-wp-smush-ui.php:684
831
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:460
832
+ #, php-format
833
+ msgid "%s, you have %s%s%d%s attachment%s that needs smushing!"
834
+ msgid_plural "%s, you have %s%s%d%s attachments%s that need smushing!"
835
  msgstr[0] ""
836
  msgstr[1] ""
837
 
838
+ #: lib/class-wp-smush-ui.php:686
839
+ #, php-format
840
+ msgid " %sUpgrade to Pro%s to bulk smush all your images with one click."
841
  msgstr ""
842
 
843
+ #: lib/class-wp-smush-ui.php:687
844
+ msgid " Free users can smush 50 images with each click."
845
  msgstr ""
846
 
847
+ #: lib/class-wp-smush-ui.php:696
848
+ msgid ""
849
+ "Enable Super-smush in the Settings area to get even more savings with almost "
850
+ "no noticeable quality loss."
851
  msgstr ""
852
 
853
+ #: lib/class-wp-smush-ui.php:719
854
+ #, php-format
855
+ msgid ""
856
+ "%sBulk smush is currently running.%s You need to keep this page open for the "
857
+ "process to complete."
858
  msgstr ""
859
 
860
+ #: lib/class-wp-smush-ui.php:729
861
+ #, php-format
862
+ msgid "%s%d%s of your media attachments have been smushed."
863
  msgstr ""
864
 
865
+ #: lib/class-wp-smush-ui.php:770
866
+ #, php-format
867
+ msgid "%s, you have %s%s%d%s attachment%s that needs re-compressing!"
868
+ msgid_plural "%s, you have %s%s%d%s attachments%s that need re-compressing!"
869
  msgstr[0] ""
870
  msgstr[1] ""
871
 
872
+ #: lib/class-wp-smush-ui.php:771
 
 
 
 
 
 
873
  msgid "Skip"
874
  msgstr ""
875
 
876
+ #: lib/class-wp-smush-ui.php:791
877
  msgid "Your settings have been updated!"
878
  msgstr ""
879
 
880
+ #: lib/class-wp-smush-ui.php:825
881
+ #, php-format
882
+ msgid ""
883
+ "Automatic smushing is %senabled%s. Newly uploaded images will be "
884
+ "automagically compressed."
885
  msgstr ""
886
 
887
+ #: lib/class-wp-smush-ui.php:825
888
+ #, php-format
889
+ msgid ""
890
+ "Automatic smushing is %sdisabled%s. Newly uploaded images will need to be "
891
+ "manually smushed."
892
  msgstr ""
893
 
894
+ #: lib/class-wp-smush-ui.php:863
895
+ msgid "Thanks for installing Smush. We hope you like it!"
896
  msgstr ""
897
 
898
+ #: lib/class-wp-smush-ui.php:864
899
+ msgid ""
900
+ "And hey, if you do, you can now try out Smush Pro for double the smushy "
901
+ "goodness (benchmarked), entirely for free!"
902
  msgstr ""
903
 
904
+ #: lib/class-wp-smush-ui.php:865 lib/class-wp-smush-ui.php:869
905
+ msgid "Try Smush Pro for Free"
906
  msgstr ""
907
 
908
+ #: lib/class-wp-smush-ui.php:867
909
+ msgid ""
910
+ "Thanks for updating Smush. Did you know that you can now try the Smush Pro "
911
+ "for FREE?!"
912
  msgstr ""
913
 
914
+ #: lib/class-wp-smush-ui.php:868
915
+ msgid ""
916
+ "Yep, Super Smush your images for double the savings, save originals and "
917
+ "batch Smush thousands of images all at once.... no charge!"
918
  msgstr ""
919
 
920
+ #: lib/class-wp-smush-ui.php:917
921
+ #, php-format
922
+ msgid ""
923
+ "Did you know WP Smush Pro delivers up to 2x better compression, allows you "
924
+ "to smush your originals and removes any bulk smushing limits? – %sTry it "
925
+ "absolutely FREE%s"
926
  msgstr ""
927
 
928
+ #: lib/class-wp-smush-ui.php:917
929
+ msgid "Try WP Smush Pro for FREE"
930
  msgstr ""
931
 
932
+ #: lib/class-wp-smush-ui.php:940
933
+ msgid "Validating.."
934
+ msgstr ""
935
+
936
+ #: lib/class-wp-smush-ui.php:942
937
+ #, php-format
938
+ msgid ""
939
+ "It looks like Smush couldn’t verify your WPMU DEV membership so Pro features "
940
+ "like Super-Smush may not work correctly. If you think this is an error, run "
941
+ "a %sre-check%s or get in touch with our %ssupport team%s."
942
+ msgstr ""
943
+
944
+ #: lib/class-wp-smush-ui.php:964
945
+ msgid "UPDATE SETTINGS"
946
+ msgstr ""
947
+
948
+ #: lib/class-wp-smush-ui.php:994
949
+ msgid ""
950
+ "Smush settings were updated, performing a quick scan to check if any of the "
951
+ "images need to be Smushed again."
952
  msgstr ""
953
 
954
+ #: lib/class-wp-smush.php:198
955
  msgid "File path is empty"
956
  msgstr ""
957
 
958
+ #: lib/class-wp-smush.php:201
959
+ #, php-format
960
  msgid "Could not find %s"
961
  msgstr ""
962
 
963
+ #: lib/class-wp-smush.php:204
964
+ #, php-format
965
  msgid "%s is not writable"
966
  msgstr ""
967
 
968
+ #: lib/class-wp-smush.php:214
969
+ #, php-format
970
  msgid "Skipped (%s), image not found. Attachment: %s"
971
  msgstr ""
972
 
973
+ #: lib/class-wp-smush.php:217
974
+ #, php-format
975
  msgid "Skipped (%s), size limit exceeded. Attachment: %s"
976
  msgstr ""
977
 
978
+ #: lib/class-wp-smush.php:235
979
  msgid "Unknown API error"
980
  msgstr ""
981
 
982
+ #: lib/class-wp-smush.php:708
983
+ #, php-format
984
  msgid "Error posting to API: %s"
985
  msgstr ""
986
 
987
+ #: lib/class-wp-smush.php:714
988
+ #, php-format
989
  msgid "Error posting to API: %s %s"
990
  msgstr ""
991
 
992
+ #: lib/class-wp-smush.php:731
993
  msgid "Smush data corrupted, try again."
994
  msgstr ""
995
 
996
+ #: lib/class-wp-smush.php:751
997
  msgid "Image couldn't be smushed"
998
  msgstr ""
999
 
1000
+ #: lib/class-wp-smush.php:987
1001
+ #, php-format
 
 
 
 
 
1002
  msgid "%d images reduced "
1003
  msgstr ""
1004
 
1005
+ #: lib/class-wp-smush.php:987
1006
  msgid "Reduced "
1007
  msgstr ""
1008
 
1009
+ #: lib/class-wp-smush.php:991
1010
+ #, php-format
1011
+ msgid "by %s %s"
1012
+ msgstr ""
1013
+
1014
+ #: lib/class-wp-smush.php:997
1015
+ #, php-format
1016
+ msgid "<br /> Image Size: %s"
1017
  msgstr ""
1018
 
1019
+ #: lib/class-wp-smush.php:1033
1020
  msgid "Detailed stats for all the image sizes"
1021
  msgstr ""
1022
 
1023
+ #: lib/class-wp-smush.php:1033
1024
+ #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:236
1025
  msgid "Smush stats"
1026
  msgstr ""
1027
 
1028
+ #: lib/class-wp-smush.php:1077
1029
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:263
1030
  msgid "Not processed"
1031
  msgstr ""
1032
 
1033
+ #: lib/class-wp-smush.php:1391
1034
+ #, php-format
1035
+ msgid ""
1036
+ "When you upload an image to WordPress it automatically creates %s thumbnail "
1037
+ "sizes that are commonly used in your pages. WordPress also stores the "
1038
+ "original full-size image, but because these are not usually embedded on your "
1039
+ "site we don’t Smush them. Pro users can override this."
1040
  msgstr ""
1041
 
1042
+ #: lib/class-wp-smush.php:1394
1043
+ msgid ""
1044
+ "Image couldn't be smushed as it exceeded the 1Mb size limit, Pro users can "
1045
+ "smush images with size upto 32Mb."
1046
  msgstr ""
1047
 
1048
+ #: lib/class-wp-smush.php:1396
1049
  msgid " Skipped"
1050
  msgstr ""
1051
 
1052
+ #: lib/class-wp-smush.php:1418
1053
+ #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:432
1054
  msgid "Image size"
1055
  msgstr ""
1056
 
1057
+ #: lib/class-wp-smush.php:1419
1058
+ #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:433
1059
  msgid "Savings"
1060
  msgstr ""
1061
 
1062
+ #: lib/class-wp-smush.php:1666
1063
  msgid "Restore original image."
1064
  msgstr ""
1065
 
1066
+ #: lib/class-wp-smush.php:1666
1067
  msgid "Restore image"
1068
  msgstr ""
1069
 
1070
+ #: lib/class-wp-smush.php:1714
1071
  msgid "Smush image including original file."
1072
  msgstr ""
1073
 
1074
+ #: lib/class-wp-smush.php:1714
1075
  msgid "Resmush image"
1076
  msgstr ""
1077
 
1078
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:71
1079
  msgid "Bulk WP Smush"
1080
  msgstr ""
1081
 
1082
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:439
1083
+ #, php-format
1084
+ msgid ""
1085
+ "We haven’t found any images in your %sgallery%s yet, so there’s no smushing "
1086
+ "to be done! Once you upload images, reload this page and start playing!"
1087
  msgstr ""
1088
 
1089
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:476
1090
+ #, php-format
1091
+ msgid ""
1092
+ "Enable Super-smush in the %sSettings%s area to get even more savings with "
1093
+ "almost no noticeable quality loss."
1094
  msgstr ""
1095
 
1096
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:491
1097
+ #, php-format
1098
  msgid "Smush individual images via your %sManage Galleries%s section"
1099
  msgstr ""
1100
 
1101
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:491
1102
  msgid "Manage Galleries"
1103
  msgstr ""
1104
 
1105
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:564
1106
+ msgid "IMAGES SUPER-SMUSHED"
1107
+ msgstr ""
1108
+
1109
+ #: lib/nextgen-integration/class-wp-smush-nextgen-admin.php:572
1110
+ #, php-format
1111
  msgid "%sDISABLED%s"
1112
  msgstr ""
1113
 
1114
+ #: lib/nextgen-integration/class-wp-smush-nextgen-bulk.php:31
1115
+ msgid ""
1116
+ "Smush request timed out, You can try setting a higher value ( > 60 ) for "
1117
+ "`WP_SMUSH_API_TIMEOUT`."
1118
  msgstr ""
1119
 
1120
+ #: lib/nextgen-integration/class-wp-smush-nextgen-stats.php:205
1121
+ #, php-format
1122
  msgid "Reduced by %s ( %01.1f%% )"
1123
  msgstr ""
1124
 
1125
+ #: wp-smush.php:169
1126
  msgid "Get Fast"
1127
  msgstr ""
1128
 
1129
+ #: wp-smush.php:211
1130
  msgid "WP Smush Free was deactivated. You have WP Smush Pro active!"
1131
  msgstr ""
 
 
 
1132
 
1133
  #. Plugin URI of the plugin/theme
1134
  msgid "http://wordpress.org/extend/plugins/wp-smushit/"
1135
  msgstr ""
1136
 
1137
  #. Description of the plugin/theme
1138
+ msgid ""
1139
+ "Reduce image file sizes, improve performance and boost your SEO using the "
1140
+ "free <a href=\"https://premium.wpmudev.org/\">WPMU DEV</a> WordPress Smush "
1141
+ "API."
1142
  msgstr ""
1143
 
1144
  #. Author of the plugin/theme
lib/class-wp-smush-admin.php CHANGED
@@ -4,11 +4,11 @@
4
  * @subpackage Admin
5
  * @version 1.0
6
  *
7
- * @author Saurabh Shukla <saurabh@incsub.com>
8
  * @author Umesh Kumar <umesh@incsub.com>
9
  *
10
  * @copyright (c) 2016, Incsub (http://incsub.com)
11
  */
 
12
  //Include Bulk UI
13
  require_once WP_SMUSH_DIR . 'lib/class-wp-smush-ui.php';
14
 
@@ -29,7 +29,6 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
29
  * @property int $remaining_count
30
  * @property int $total_count
31
  * @property int $smushed_count
32
- * @property int $exceeding_items_count
33
  */
34
  class WpSmushitAdmin extends WpSmush {
35
 
@@ -50,11 +49,44 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
50
  */
51
  public $smushed_count;
52
 
 
 
 
 
 
53
  /**
54
  * @var Smushed attachments out of total attachments
55
  */
 
 
 
 
 
56
  public $super_smushed;
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  /**
59
  * @array Stores the stats for all the images
60
  */
@@ -69,53 +101,64 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
69
 
70
  public $upgrade_url = 'https://premium.wpmudev.org/project/wp-smush-pro/';
71
 
72
- //Stores unsmushed ids
73
- private $ids = '';
74
-
75
- //Stores all lossless smushed ids
76
- public $resmush_ids = array();
77
-
78
- /**
79
- * @var int Number of attachments exceeding free limit
80
- */
81
- public $exceeding_items_count = 0;
82
 
83
  /**
84
- * @var If the plugin is a pro version or not
 
85
  */
86
- private $is_pro_user;
87
-
88
- private $attachments = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
  /**
91
  * Constructor
92
  */
93
  public function __construct() {
94
 
95
- // Save Settings, Process Option, Need to process it early, so the pages are loaded accordingly, nextgen gallery integration is loaded at same action
96
- // add_action( 'plugins_loaded', array( $this, 'process_options' ), 16 );
97
-
98
  // hook scripts and styles
99
  add_action( 'admin_init', array( $this, 'register' ) );
100
 
101
  // hook custom screen
102
  add_action( 'admin_menu', array( $this, 'screen' ) );
103
 
 
 
 
104
  //Handle Smush Bulk Ajax
105
  add_action( 'wp_ajax_wp_smushit_bulk', array( $this, 'process_smush_request' ) );
106
 
107
  //Handle Smush Single Ajax
108
  add_action( 'wp_ajax_wp_smushit_manual', array( $this, 'smush_manual' ) );
109
 
110
- //Handle Restore operation
111
- add_action( 'wp_ajax_smush_restore_image', array( $this, 'restore_image' ) );
112
-
113
  //Handle Restore operation
114
  add_action( 'wp_ajax_smush_resmush_image', array( $this, 'resmush_image' ) );
115
 
116
- //Handle Restore operation
117
  add_action( 'wp_ajax_scan_for_resmush', array( $this, 'scan_images' ) );
118
 
 
 
 
119
  add_filter( 'plugin_action_links_' . WP_SMUSH_BASENAME, array(
120
  $this,
121
  'settings_link'
@@ -127,15 +170,22 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
127
  //Attachment status, Grid view
128
  add_filter( 'attachment_fields_to_edit', array( $this, 'filter_attachment_fields_to_edit' ), 10, 2 );
129
 
130
- /// Smush Upgrade
131
  add_action( 'admin_notices', array( $this, 'smush_upgrade' ) );
132
 
 
 
 
 
133
  //Handle the smush pro dismiss features notice ajax
134
  add_action( 'wp_ajax_dismiss_upgrade_notice', array( $this, 'dismiss_upgrade_notice' ) );
135
 
136
  //Handle the smush pro dismiss features notice ajax
137
  add_action( 'wp_ajax_dismiss_welcome_notice', array( $this, 'dismiss_welcome_notice' ) );
138
 
 
 
 
139
  //Update the Super Smush count, after the smushing
140
  add_action( 'wp_smush_image_optimised', array( $this, 'update_lists' ), '', 2 );
141
 
@@ -144,40 +194,59 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
144
 
145
  add_action( 'admin_init', array( $this, 'init_settings' ) );
146
 
 
 
 
 
 
147
  $this->bulk_ui = new WpSmushBulkUi();
 
148
  }
149
 
150
  function init_settings() {
151
  $this->settings = array(
152
- 'auto' => array(
 
 
 
 
153
  'label' => esc_html__( 'Automatically smush my images on upload', 'wp-smushit' ),
154
  'desc' => esc_html__( 'When you upload images to the media library, we’ll automatically optimize them.', 'wp-smushit' )
155
  ),
156
- 'keep_exif' => array(
157
  'label' => esc_html__( 'Preserve image EXIF data', 'wp-smushit' ),
158
  'desc' => esc_html__( 'EXIF data stores camera settings, focal length, date, time and location information in image files. EXIF data makes image files larger but if you are a photographer you may want to preserve this information.', 'wp-smushit' )
159
  ),
160
- 'lossy' => array(
 
 
 
 
161
  'label' => esc_html__( 'Super-smush my images', 'wp-smushit' ),
162
- 'desc' => esc_html__( 'Compress images up to 10x more than regular smush with almost no visible drop in quality.', 'wp-smushit' )
163
  ),
164
- 'original' => array(
165
  'label' => esc_html__( 'Include my original full-size images', 'wp-smushit' ),
166
  'desc' => esc_html__( 'WordPress crops and resizes every image you upload for embedding on your site. By default, Smush only compresses these cropped and resized images, not your original full-size images. To save space on your server, activate this setting to smush your original images, too. Note: This doesn’t usually improve page speed.', 'wp-smushit' )
167
  ),
168
- 'backup' => array(
169
  'label' => esc_html__( 'Make a copy of my original images', 'wp-smushit' ),
170
  'desc' => esc_html__( 'Save your original full-size images so you can restore them at any point. Note: Activating this setting will significantly increase the size of your uploads folder by nearly twice as much.', 'wp-smushit' )
 
 
 
 
171
  )
172
  );
173
 
174
- //Show NextGen settings only if Nextgen is installed
175
- if ( class_exists( 'C_NextGEN_Bootstrap' ) ) {
176
- $this->settings['nextgen'] = array(
177
- 'label' => esc_html__( 'Enable NextGen Gallery integration', 'wp-smushit' ),
178
- 'desc' => esc_html__( 'Allow smushing images directly through NextGen Gallery settings.', 'wp-smushit' )
179
- );
180
- }
 
181
  }
182
 
183
  /**
@@ -210,16 +279,24 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
210
  function screen() {
211
  global $admin_page_suffix;
212
 
 
213
  $admin_page_suffix = add_media_page( 'Bulk WP Smush', 'WP Smush', 'edit_others_posts', 'wp-smush-bulk', array(
214
  $this->bulk_ui,
215
  'ui'
216
  ) );
217
 
 
 
 
 
 
 
 
 
 
218
  //For Nextgen gallery Pages, check later in enqueue function
219
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
220
 
221
- //Reset Transient
222
- $this->check_bulk_limit( true );
223
  }
224
 
225
  /**
@@ -227,38 +304,29 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
227
  */
228
  function register() {
229
 
230
- global $WpSmush;
231
-
232
- // Register js for smush utton in grid view
233
- $current_blog_id = get_current_blog_id();
234
- $meta_key = $current_blog_id == 1 ? 'wp_media_library_mode' : 'wp_' . $current_blog_id . '_media_library_mode';
235
- $wp_media_library_mode = get_user_meta( get_current_user_id(), $meta_key, true );
236
-
237
- //Either request variable is not empty and grid mode is set, or if request empty then view is as per user choice, or no view is set
238
- if ( ( ! empty( $_REQUEST['mode'] ) && $_REQUEST['mode'] == 'grid' ) ||
239
- ( empty( $_REQUEST['mode'] ) && $wp_media_library_mode != 'list' )
240
- ) {
241
- wp_register_script( 'wp-smushit-admin-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin.js', array(
242
- 'jquery',
243
- 'media-views'
244
- ), WP_SMUSH_VERSION );
245
- } else {
246
- wp_register_script( 'wp-smushit-admin-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin.js', array(
247
- 'jquery',
248
- 'underscore'
249
- ), WP_SMUSH_VERSION );
250
- }
251
- wp_register_script( 'wp-smushit-admin-media-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin-media.js', array( 'jquery' ), $WpSmush->version );
252
-
253
-
254
- /* Register Style. */
255
- wp_register_style( 'wp-smushit-admin-css', WP_SMUSH_URL . 'assets/css/wp-smushit-admin.css', array(), $WpSmush->version );
256
- //Get resmush list
257
- //If we have a resmush list already, localize those ids
258
- if ( $resmush_ids = get_option( "wp-smush-resmush-list" ) ) {
259
- //get the attachments, and get lossless count
260
- $this->resmush_ids = $resmush_ids;
261
- }
262
  }
263
 
264
  /**
@@ -266,8 +334,6 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
266
  */
267
  function enqueue() {
268
 
269
- global $pagenow;
270
-
271
  $current_screen = get_current_screen();
272
  $current_page = $current_screen->base;
273
 
@@ -276,10 +342,13 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
276
  */
277
  $enqueue_smush = apply_filters( 'wp_smush_enqueue', true );
278
 
279
- //If we upgrade/install message is dismissed
280
- if( get_option( 'wp-smush-hide_upgrade_notice' ) ) {
 
 
 
281
  //Do not enqueue, unless it is one of the required screen
282
- if ( ! $enqueue_smush || ( $current_page != 'nggallery-manage-images' && $current_page != 'gallery_page_wp-smush-nextgen-bulk' && $pagenow != 'post.php' && $pagenow != 'post-new.php' && $pagenow != 'upload.php' ) ) {
283
 
284
  return;
285
  }
@@ -301,6 +370,13 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
301
  );
302
  }
303
 
 
 
 
 
 
 
 
304
  // localize translatable strings for js
305
  $this->localize();
306
  }
@@ -309,41 +385,106 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
309
  * Localize Translations
310
  */
311
  function localize() {
 
 
312
 
313
- $bulk = new WpSmushitBulk();
314
  $handle = 'wp-smushit-admin-js';
315
 
316
- //Setup all the stats
317
- $this->setup_global_stats();
318
-
319
  $wp_smush_msgs = array(
320
- 'resmush' => esc_html__( 'Super-Smush', 'wp-smushit' ),
321
- 'smush_now' => esc_html__( 'Smush Now', 'wp-smushit' ),
322
- 'error_in_bulk' => esc_html__( '{{errors}} image(s) were skipped due to an error.', 'wp-smushit' ),
323
- 'all_resmushed' => esc_html__( 'All images are fully optimised.', 'wp-smushit' ),
324
- 'restore' => esc_html__( "Restoring image..", "wp-smushit" ),
325
- 'smushing' => esc_html__( "Smushing image..", "wp-smushit" ),
326
- 'checking' => esc_html__( "Checking images..", "wp-smushit" )
 
 
 
 
 
 
 
 
 
 
327
  );
328
 
329
  wp_localize_script( $handle, 'wp_smush_msgs', $wp_smush_msgs );
330
 
331
- $this->attachments = $bulk->get_attachments();
 
 
 
 
 
 
 
332
 
333
- //Localize smushit_ids variable, if there are fix number of ids
334
- $this->ids = ! empty( $_REQUEST['ids'] ) ? array_map( 'intval', explode( ',', $_REQUEST['ids'] ) ) : $this->attachments;
335
 
336
- //Array of all smushed, unsmushed and lossless ids
337
- $data = array(
338
- 'count_smushed' => $this->smushed_count,
339
- 'count_total' => $this->total_count,
340
- 'unsmushed' => $this->ids,
341
- 'resmush' => $this->resmush_ids,
342
- 'timeout' => WP_SMUSH_TIMEOUT * 1000, //Convert it into ms
343
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
 
345
  wp_localize_script( 'wp-smushit-admin-js', 'wp_smushit_data', $data );
346
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
  }
348
 
349
  /**
@@ -353,104 +494,87 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
353
  *
354
  */
355
  function setup_global_stats( $force_update = false ) {
356
- $this->total_count = $this->total_count();
357
- $this->smushed_count = $this->smushed_count();
358
- $this->remaining_count = $this->remaining_count();
359
- $this->stats = $this->global_stats( $force_update );
360
- }
361
 
362
- /**
363
- * Check if form is submitted and process it
364
- *
365
- * @return null
366
- */
367
- function process_options() {
368
 
369
- if ( ! is_admin() ) {
370
- return false;
371
- }
372
 
373
- // we aren't saving options
374
- if ( ! isset( $_POST['wp_smush_options_nonce'] ) ) {
375
- return false;
376
- }
377
 
378
- // the nonce doesn't pan out
379
- if ( ! wp_verify_nonce( $_POST['wp_smush_options_nonce'], 'save_wp_smush_options' ) ) {
380
- return false;
381
  }
382
 
383
- //Store that we need not redirect again on plugin activation
384
- update_option( 'wp-smush-hide_smush_welcome', true );
385
-
386
- // var to temporarily assign the option value
387
- $setting = null;
388
 
389
- //Store Option Name and their values in an array
390
- $settings = array();
391
-
392
-
393
- // process each setting and update options
394
- foreach ( $this->settings as $name => $text ) {
395
 
396
- // formulate the index of option
397
- $opt_name = WP_SMUSH_PREFIX . $name;
398
 
399
- // get the value to be saved
400
- $setting = isset( $_POST[ $opt_name ] ) ? 1 : 0;
 
 
401
 
402
- $settings[ $opt_name ] = $setting;
 
 
 
 
 
 
403
 
404
- // update the new value
405
- update_option( $opt_name, $setting );
406
 
407
- // unset the var for next loop
408
- unset( $setting );
 
409
  }
410
 
411
- //Store the option in table
412
- update_option( 'wp-smush-settings_updated', 1 );
 
 
 
413
 
414
- //Delete Show Resmush option
415
- if ( isset( $_POST['wp-smush-keep_exif'] ) && ! isset( $_POST['wp-smush-original'] ) && ! isset( $_POST['wp-smush-lossy'] ) ) {
416
- //@todo: Update Resmush ids
 
 
 
417
  }
418
-
419
- }
420
-
421
- /**
422
- * Returns number of images of larger than 1Mb size
423
- *
424
- * @param bool $force_update Whether to Force update the Global Stats or not
425
- *
426
- * @return int
427
- */
428
- function get_exceeding_items_count( $force_update = false ) {
429
- $count = wp_cache_get( 'exceeding_items', 'wp_smush' );
430
- if ( ! $count || $force_update ) {
431
- $count = 0;
432
- //Check images bigger than 1Mb, used to display the count of images that can't be smushed
433
- foreach ( $this->attachments as $attachment ) {
434
- if ( file_exists( get_attached_file( $attachment ) ) ) {
435
- $size = filesize( get_attached_file( $attachment ) );
436
- }
437
- if ( empty( $size ) || ! ( ( $size / WP_SMUSH_MAX_BYTES ) > 1 ) ) {
438
- continue;
439
- }
440
- $count ++;
441
- }
442
- wp_cache_set( 'exceeding_items', $count, 'wp_smush', 3000 );
443
  }
444
 
445
- return $count;
 
 
 
 
 
 
446
  }
447
 
448
  /**
449
  * Processes the Smush request and sends back the next id for smushing
 
 
 
450
  */
451
  function process_smush_request() {
452
 
453
- global $WpSmush;
454
 
455
  // turn off errors for ajax result
456
  @error_reporting( 0 );
@@ -461,7 +585,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
461
  wp_send_json_error( 'missing id' );
462
  }
463
 
464
- if ( ! $this->is_pro() ) {
465
  //Free version bulk smush, check the transient counter value
466
  $should_continue = $this->check_bulk_limit();
467
  }
@@ -476,41 +600,135 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
476
  );
477
  }
478
 
479
- $attachment_id = (int) ( $_REQUEST['attachment_id'] );
 
480
 
481
- $original_meta = wp_get_attachment_metadata( $attachment_id, true );
482
 
483
- $smush = $WpSmush->resize_from_meta_data( $original_meta, $attachment_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
 
485
- //Get the updated Global Stats
486
- $this->setup_global_stats( true );
487
 
488
- $stats = $this->stats;
 
489
 
490
- $stats['smushed'] = $this->smushed_count;
 
 
491
 
492
- if ( $WpSmush->lossy_enabled ) {
493
- $stats['super_smushed'] = $this->super_smushed_count();
494
  }
495
 
496
- $stats['resmush_count'] = count( $this->resmush_ids );
 
 
 
 
 
 
 
 
 
 
 
497
 
498
- $stats['total'] = $this->total_count();
 
 
499
 
500
- if ( is_wp_error( $smush ) ) {
501
  $error = $smush->get_error_message();
502
  //Check for timeout error and suggest to filter timeout
503
  if ( strpos( $error, 'timed out' ) ) {
504
  $error = esc_html__( "Smush request timed out, You can try setting a higher value for `WP_SMUSH_API_TIMEOUT`.", "wp-smushit" );
505
  }
506
- wp_send_json_error( array( 'stats' => $stats, 'error_msg' => $error ) );
507
  } else {
508
  //Check if a resmush request, update the resmush list
509
  if ( ! empty( $_REQUEST['is_bulk_resmush'] ) && 'false' != $_REQUEST['is_bulk_resmush'] && $_REQUEST['is_bulk_resmush'] ) {
510
  $this->update_resmush_list( $attachment_id );
511
  }
512
- wp_send_json_success( array( 'stats' => $stats ) );
513
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  }
515
 
516
  /**
@@ -519,6 +737,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
519
  * @uses smush_single()
520
  */
521
  function smush_manual() {
 
522
  // turn off errors for ajax result
523
  @error_reporting( 0 );
524
 
@@ -530,8 +749,24 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
530
  wp_die( __( 'No attachment ID was provided.', 'wp-smushit' ) );
531
  }
532
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
  //Pass on the attachment id to smush single function
534
- $this->smush_single( $_GET['attachment_id'] );
535
  }
536
 
537
  /**
@@ -544,18 +779,59 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
544
  */
545
  function smush_single( $attachment_id, $return = false ) {
546
 
547
- global $WpSmush;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
 
549
  $attachment_id = absint( (int) ( $attachment_id ) );
550
 
551
- $original_meta = wp_get_attachment_metadata( $attachment_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
552
 
553
  //Smush the image
554
  $smush = $WpSmush->resize_from_meta_data( $original_meta, $attachment_id );
555
 
 
 
 
556
  //Get the button status
557
  $status = $WpSmush->set_status( $attachment_id, false, true );
558
 
 
 
 
559
  //Send Json response if we are not suppose to return the results
560
 
561
  /** Send stats **/
@@ -563,7 +839,9 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
563
  if ( $return ) {
564
  return array( 'error' => $smush->get_error_message() );
565
  } else {
566
- wp_send_json_error( array( 'error_msg' => $smush->get_error_message() ) );
 
 
567
  }
568
  } else {
569
  if ( $return ) {
@@ -577,117 +855,60 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
577
  /**
578
  * Check bulk sent count, whether to allow further smushing or not
579
  *
 
 
 
 
580
  * @return bool
581
  */
582
- function check_bulk_limit( $reset = false ) {
583
-
584
- $transient_name = WP_SMUSH_PREFIX . 'bulk_sent_count';
585
-
586
- //Do not go through this, if we need to reset
587
- if( !$reset ) {
588
- $bulk_sent_count = get_transient( $transient_name );
589
-
590
- //If bulk sent count is not set
591
- if ( false === $bulk_sent_count ) {
592
-
593
- //start transient at 0
594
- set_transient( $transient_name, 1, 200 );
595
-
596
- return true;
597
-
598
- } else if ( $bulk_sent_count < $this->max_free_bulk ) {
599
 
600
- //If lte $this->max_free_bulk images are sent, increment
601
- set_transient( $transient_name, $bulk_sent_count + 1, 200 );
602
 
603
- return true;
604
 
605
- } else { //Bulk sent count is set and greater than $this->max_free_bulk
606
-
607
- $reset = true;
608
-
609
- }
 
 
 
 
610
  }
611
 
612
- //Reset the transient
613
- if( $reset ) {
614
- //clear it and return false to stop the process
615
  set_transient( $transient_name, 0, 60 );
616
-
617
- return false;
618
  }
 
 
619
  }
620
 
621
  /**
622
- * Total Image count
623
- * @return int
 
 
624
  */
625
- function total_count() {
626
-
627
- //Don't query again, if the variable is already set
628
- if ( ! empty( $this->total_count ) && $this->total_count > 0 ) {
629
- return $this->total_count;
630
- }
631
 
632
- $query = array(
633
- 'fields' => 'ids',
634
- 'post_type' => 'attachment',
635
- 'post_status' => 'any',
636
- 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
637
- 'order' => 'ASC',
638
- 'posts_per_page' => - 1,
639
- 'no_found_rows' => true
640
- );
641
- //Remove the Filters added by WP Media Folder
642
- $this->remove_wmf_filters();
643
 
644
- $results = new WP_Query( $query );
645
- $count = ! empty( $results->post_count ) ? $results->post_count : 0;
646
 
647
- // send the count
648
- return $count;
649
- }
650
 
651
- /**
652
- * Optimised images count
653
- *
654
- * @param bool $return_ids
655
- *
656
- * @return array|int
657
- */
658
- function smushed_count( $return_ids = false ) {
659
-
660
- //Don't query again, if the variable is already set
661
- if ( ! empty( $this->smushed_count ) && $this->smushed_count > 0 ) {
662
- return $this->smushed_count;
663
- }
664
-
665
- $query = array(
666
- 'fields' => 'ids',
667
- 'post_type' => 'attachment',
668
- 'post_status' => 'any',
669
- 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
670
- 'order' => 'ASC',
671
- 'posts_per_page' => - 1,
672
- 'meta_key' => 'wp-smpro-smush-data',
673
- 'no_found_rows' => true
674
- );
675
 
676
- //Remove the Filters added by WP Media Folder
677
- $this->remove_wmf_filters();
678
 
679
- $results = new WP_Query( $query );
 
680
 
681
- if ( ! is_wp_error( $results ) && $results->post_count > 0 ) {
682
- if ( ! $return_ids ) {
683
- //return Post Count
684
- return $results->post_count;
685
- } else {
686
- //Return post ids
687
- return $results->posts;
688
- }
689
- } else {
690
- return false;
691
  }
692
  }
693
 
@@ -697,7 +918,14 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
697
  * @return int
698
  */
699
  function remaining_count() {
700
- return $this->total_count - $this->smushed_count;
 
 
 
 
 
 
 
701
  }
702
 
703
  /**
@@ -766,45 +994,73 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
766
  * @param bool $force_update , Whether to forcefully update the Cache
767
  *
768
  * @return array|bool|mixed
 
 
 
769
  */
770
  function global_stats( $force_update = false ) {
771
 
772
- if ( ! $force_update && $stats = wp_cache_get( 'global_stats', 'wp_smush' ) ) {
773
- if ( ! empty( $stats ) ) {
 
 
 
 
774
  return $stats;
775
  }
776
  }
777
 
778
- global $wpdb, $WpSmush;
779
 
780
  $smush_data = array(
781
  'size_before' => 0,
782
  'size_after' => 0,
783
  'percent' => 0,
784
- 'human' => 0
 
785
  );
786
 
787
  /**
788
  * Allows to set a limit of mysql query
789
  * Default value is 2000
790
  */
791
- $limit = apply_filters( 'wp_smush_media_query_limit', 2000 );
792
- $limit = intval( $limit );
793
  $offset = 0;
794
  $query_next = true;
795
 
796
- while ( $query_next ) {
 
797
 
798
- $global_data = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key=%s LIMIT $offset, $limit", "wp-smpro-smush-data" ) );
799
 
 
800
  if ( ! empty( $global_data ) ) {
801
- $smush_data['count'] = 0;
802
  foreach ( $global_data as $data ) {
803
- $data = maybe_unserialize( $data );
804
- if ( ! empty( $data['stats'] ) ) {
805
- $smush_data['count'] += 1;
806
- $smush_data['size_before'] += ! empty( $data['stats']['size_before'] ) ? (int) $data['stats']['size_before'] : 0;
807
- $smush_data['size_after'] += ! empty( $data['stats']['size_after'] ) ? (int) $data['stats']['size_after'] : 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
808
  }
809
  }
810
  }
@@ -815,7 +1071,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
815
  $offset += $limit;
816
 
817
  //Compare the Offset value to total images
818
- if ( ! empty( $this->total_count ) && $this->total_count < $offset ) {
819
  $query_next = false;
820
  } elseif ( ! $global_data ) {
821
  //If we didn' got any results
@@ -824,41 +1080,188 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
824
 
825
  }
826
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
827
  if ( ! isset( $smush_data['bytes'] ) || $smush_data['bytes'] < 0 ) {
828
  $smush_data['bytes'] = 0;
829
  }
830
 
 
 
 
 
 
 
 
 
 
 
831
  if ( $smush_data['size_before'] > 0 ) {
832
  $smush_data['percent'] = ( $smush_data['bytes'] / $smush_data['size_before'] ) * 100;
833
  }
834
 
835
  //Round off precentage
836
- $smush_data['percent'] = round( $smush_data['percent'], 2 );
 
 
 
 
 
 
 
 
837
 
838
- $smush_data['human'] = $WpSmush->format_bytes( $smush_data['bytes'] );
 
839
 
840
  //Update Cache
841
- wp_cache_set( 'smush_global_stats', $smush_data, '', DAY_IN_SECONDS );
842
 
843
  return $smush_data;
844
  }
845
 
846
  /**
847
- * Returns Bulk smush button id and other details, as per if bulk request is already sent or not
848
  *
849
- * @param $resmush
850
  *
851
- * @return array
852
  */
 
853
 
854
- private function button_state( $resmush ) {
855
- $button = array(
856
- 'cancel' => false,
857
- );
858
- if ( $this->is_pro() && $resmush ) {
859
 
860
- $button['text'] = __( 'Bulk Smush Now', 'wp-smushit' );
861
- $button['class'] = 'wp-smush-button wp-smush-resmush wp-smush-all';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
862
 
863
  } else {
864
 
@@ -887,6 +1290,22 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
887
  * @return string
888
  */
889
  function smush_status( $id ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
890
  $response = trim( $this->set_status( $id, false ) );
891
 
892
  return $response;
@@ -900,11 +1319,16 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
900
  *
901
  * @return array
902
  */
903
- function settings_link( $links ) {
904
 
905
- $settings_page = admin_url( 'upload.php?page=wp-smush-bulk' );
906
  $settings = '<a href="' . $settings_page . '">' . __( 'Settings', 'wp-smushit' ) . '</a>';
907
 
 
 
 
 
 
908
  //Added a fix for weird warning in multisite, "array_unshift() expects parameter 1 to be array, null given"
909
  if ( ! empty( $links ) ) {
910
  array_unshift( $links, $settings );
@@ -921,7 +1345,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
921
  function smush_upgrade() {
922
 
923
  //Return, If a pro user, or not super admin, or don't have the admin privilleges
924
- if ( $this->is_pro() || ! current_user_can( 'edit_others_posts' ) || ! is_super_admin() ) {
925
  return;
926
  }
927
 
@@ -931,12 +1355,11 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
931
  }
932
 
933
  //Return if notice is already dismissed
934
- if ( get_option( 'wp-smush-hide_upgrade_notice' ) ) {
935
  return;
936
- } ?>
937
- <div class="wpmud wp-smush-updated"><?php
938
 
939
- $install_type = get_option( 'wp-smush-install-type', false );
940
 
941
  if ( ! $install_type ) {
942
  if ( $this->smushed_count > 0 ) {
@@ -944,17 +1367,11 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
944
  } else {
945
  $install_type = 'new';
946
  }
947
- update_option( 'wp-smush-install-type', $install_type );
948
  }
949
 
950
- //Whether New/Existing Installation
951
- $box_heading = 'existing' == $install_type ? esc_html__( "THANKS FOR UPDATING SMUSH!", "wp-smushit" ) : esc_html__( "HAPPY SMUSHING!", "wp-smushit" );
952
-
953
  //Container Header
954
- echo $this->bulk_ui->container_header( 'wp-smush-install-thanks-box', 'wp-smush-install-thanks', $box_heading, '', true );
955
  echo $this->bulk_ui->installation_notice();
956
- ?>
957
- </div><?php
958
  }
959
 
960
  /**
@@ -970,8 +1387,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
970
 
971
  $allowed_images = "( 'image/jpeg', 'image/jpg', 'image/png' )";
972
 
973
- $limit = apply_filters( 'wp_smush_media_query_limit', 2000 );
974
- $limit = intval( $limit );
975
  $offset = 0;
976
  $query_next = true;
977
 
@@ -991,7 +1407,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
991
 
992
  //Update the offset
993
  $offset += $limit;
994
- if ( $this->total_count() && $this->total_count() < $offset ) {
995
  $query_next = false;
996
  } else if ( ! $results || empty( $results ) ) {
997
  $query_next = false;
@@ -1001,194 +1417,52 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1001
  return $results;
1002
  }
1003
 
1004
- /**
1005
- * Returns the ids and meta which are losslessly compressed
1006
- *
1007
- * @return array
1008
- */
1009
- function get_lossy_attachments( $attachments = '', $return_count = true ) {
1010
-
1011
- $lossy_attachments = array();
1012
- $count = 0;
1013
-
1014
- if ( empty( $attachments ) ) {
1015
- //Fetch all the smushed attachment ids
1016
- $attachments = $this->get_smushed_attachments();
1017
- }
1018
-
1019
- //If we dont' have any attachments
1020
- if ( empty( $attachments ) || 0 == count( $attachments ) ) {
1021
- return 0;
1022
- }
1023
-
1024
- //Check if image is lossless or lossy
1025
- foreach ( $attachments as $attachment ) {
1026
-
1027
- //Check meta for lossy value
1028
- $smush_data = ! empty( $attachment->smush_data ) ? maybe_unserialize( $attachment->smush_data ) : '';
1029
-
1030
- //For Nextgen Gallery images
1031
- if ( empty( $smush_data ) && is_array( $attachment ) && ! empty( $attachment['wp_smush'] ) ) {
1032
- $smush_data = ! empty( $attachment['wp_smush'] ) ? $attachment['wp_smush'] : '';
1033
- }
1034
-
1035
- //Return if not smushed
1036
- if ( empty( $smush_data ) ) {
1037
- continue;
1038
- }
1039
-
1040
- //if stats not set or lossy is not set for attachment, return
1041
- if ( empty( $smush_data['stats'] ) || ! isset( $smush_data['stats']['lossy'] ) ) {
1042
- continue;
1043
- }
1044
-
1045
- //Add to array if lossy is not 1
1046
- if ( 1 == $smush_data['stats']['lossy'] ) {
1047
- $count ++;
1048
- if ( ! empty( $attachment->attachment_id ) ) {
1049
- $lossy_attachments[] = $attachment->attachment_id;
1050
- } elseif ( is_array( $attachment ) && ! empty( $attachment['pid'] ) ) {
1051
- $lossy_attachments[] = $attachment['pid'];
1052
- }
1053
- }
1054
- }
1055
- unset( $attachments );
1056
-
1057
- if ( $return_count ) {
1058
- return $count;
1059
- }
1060
-
1061
- return $lossy_attachments;
1062
- }
1063
-
1064
- /**
1065
- * Remove any pre_get_posts_filters added by WP Media Folder plugin
1066
- */
1067
- function remove_wmf_filters() {
1068
- //remove any filters added b WP media Folder plugin to get the all attachments
1069
- if ( class_exists( 'Wp_Media_Folder' ) ) {
1070
- global $wp_media_folder;
1071
- if ( is_object( $wp_media_folder ) ) {
1072
- remove_filter( 'pre_get_posts', array( $wp_media_folder, 'wpmf_pre_get_posts1' ) );
1073
- remove_filter( 'pre_get_posts', array( $wp_media_folder, 'wpmf_pre_get_posts' ), 0, 1 );
1074
- }
1075
- }
1076
- }
1077
-
1078
  /**
1079
  * Store a key/value to hide the smush features on bulk page
1080
  */
1081
  function dismiss_welcome_notice() {
1082
- update_option( 'wp-smush-hide_smush_welcome', 1 );
1083
  wp_send_json_success();
1084
  }
1085
 
1086
  /**
1087
  * Store a key/value to hide the smush features on bulk page
1088
  */
1089
- function dismiss_upgrade_notice() {
1090
- update_option( 'wp-smush-hide_upgrade_notice', 1 );
1091
- wp_send_json_success();
 
 
 
1092
  }
1093
 
1094
  /**
1095
- * Restore the image and its sizes from backup
 
 
 
1096
  */
1097
- function restore_image( $attachment = '', $resp = true ) {
1098
-
1099
- if( empty( $attachment ) ) {
1100
- //Check Empty fields
1101
- if ( empty( $_POST['attachment_id'] ) || empty( $_POST['_nonce'] ) ) {
1102
- wp_send_json_error( array(
1103
- 'error' => 'empty_fields',
1104
- 'message' => esc_html__( "Error in processing restore action, Fields empty.", "wp-smushit" )
1105
- ) );
1106
- }
1107
- //Check Nonce
1108
- if ( ! wp_verify_nonce( $_POST['_nonce'], "wp-smush-restore-" . $_POST['attachment_id'] ) ) {
1109
- wp_send_json_error( array(
1110
- 'error' => 'empty_fields',
1111
- 'message' => esc_html__( "Image not restored, Nonce verification failed.", "wp-smushit" )
1112
- ) );
1113
- }
1114
- }
1115
-
1116
- //Store the restore success/failure for all the sizes
1117
- $restored = array();
1118
-
1119
- //Process Now
1120
- $image_id = empty( $attachment ) ? absint( (int) $_POST['attachment_id'] ) : $attachment;
1121
-
1122
- //Restore Full size -> get other image sizes -> restore other images
1123
-
1124
- //Get the Original Path
1125
- $file_path = get_attached_file( $image_id );
1126
-
1127
- //Get the backup path
1128
- $backup_name = $this->get_image_backup_path( $file_path );
1129
 
1130
- //If file exists, corresponding to our backup path
1131
- if ( file_exists( $backup_name ) ) {
1132
- //Restore
1133
- $restored[] = @copy( $backup_name, $file_path );
1134
-
1135
- //Delete the backup
1136
- @unlink( $backup_name );
1137
- } elseif ( file_exists( $file_path . '_backup' ) ) {
1138
- //Restore from other backups
1139
- $restored[] = @copy( $file_path . '_backup', $file_path );
1140
  }
1141
 
1142
- //Get other sizes and restore
1143
- //Get attachment data
1144
- $attachment_data = wp_get_attachment_metadata( $image_id );
1145
-
1146
- //Get the sizes
1147
- $sizes = ! empty( $attachment_data['sizes'] ) ? $attachment_data['sizes'] : '';
1148
-
1149
- //Loop on images to restore them
1150
- foreach ( $sizes as $size ) {
1151
- //Get the file path
1152
- if ( empty( $size['file'] ) ) {
1153
- continue;
1154
- }
1155
-
1156
- //Image Path and Backup path
1157
- $image_size_path = path_join( dirname( $file_path ), $size['file'] );
1158
- $image_bckup_path = $this->get_image_backup_path( $image_size_path );
1159
-
1160
- //Restore
1161
- if ( file_exists( $image_bckup_path ) ) {
1162
- $restored[] = @copy( $image_bckup_path, $image_size_path );
1163
- //Delete the backup
1164
- @unlink( $image_bckup_path );
1165
- } elseif ( file_exists( $image_size_path . '_backup' ) ) {
1166
- $restored[] = @copy( $image_size_path . '_backup', $image_size_path );
1167
- }
1168
  }
1169
- //If any of the image is restored, we count it as success
1170
- if ( in_array( true, $restored ) ) {
1171
-
1172
- //Remove the Meta, And send json success
1173
- delete_post_meta( $image_id, $this->smushed_meta_key );
1174
 
1175
- //Get the Button html without wrapper
1176
- $button_html = $this->set_status( $image_id, false, false, false );
1177
-
1178
- if( $resp ) {
1179
- wp_send_json_success( array( 'button' => $button_html ) );
1180
- }else{
1181
- return true;
1182
- }
1183
- }
1184
- if( $resp ) {
1185
- wp_send_json_error( array( 'message' => '<div class="wp-smush-error">' . __( "Unable to restore image", "wp-smushit" ) . '</div>' ) );
1186
  }
1187
- return false;
1188
  }
1189
 
1190
  /**
1191
- * Restore the image and its sizes from backup
1192
  *
1193
  * @uses smush_single()
1194
  *
@@ -1234,16 +1508,38 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1234
  */
1235
  function scan_images() {
1236
 
1237
- global $WpSmush, $wpsmushnextgenadmin;
1238
 
1239
  check_ajax_referer( 'save_wp_smush_options', 'wp_smush_options_nonce' );
1240
 
1241
  $resmush_list = array();
1242
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1243
  //Default Notice, to be displayed at the top of page
1244
  //Show a message, at the top
1245
- $message = esc_html__( 'Yay! All images are optimised as per your current settings.', 'wp-smushit' );
1246
- $resp = '<div class="wp-smush-notice wp-smush-resmush-message"><i class="dev-icon dev-icon-tick"></i> ' . $message . '
1247
  <i class="dev-icon dev-icon-cross"></i>
1248
  </div>';
1249
 
@@ -1253,9 +1549,6 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1253
  //If a user manually runs smush check
1254
  $return_ui = isset( $_REQUEST['get_ui'] ) && 'true' == $_REQUEST['get_ui'] ? true : false;
1255
 
1256
- //Save Settings
1257
- $this->process_options();
1258
-
1259
  //Update the variables
1260
  $WpSmush->initialise();
1261
 
@@ -1264,10 +1557,24 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1264
  //Allow to smush Upfront images as well
1265
  $upfront_active = class_exists( 'Upfront' );
1266
 
 
 
 
 
 
 
 
 
 
 
1267
  $key = 'nextgen' == $type ? 'wp-smush-nextgen-resmush-list' : 'wp-smush-resmush-list';
1268
 
1269
- if ( ! $WpSmush->lossy_enabled && ! $WpSmush->smush_original && $WpSmush->keep_exif && ! $upfront_active ) {
 
 
1270
  delete_option( $key );
 
 
1271
  wp_send_json_success( array( 'notice' => $resp ) );
1272
  }
1273
 
@@ -1278,7 +1585,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1278
  if ( 'nextgen' != $type ) {
1279
 
1280
  //Get list of Smushed images
1281
- $attachments = $this->smushed_count( true );
1282
  } else {
1283
  global $wpsmushnextgenstats;
1284
 
@@ -1287,19 +1594,37 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1287
 
1288
  }
1289
 
 
1290
  //Check if any of the smushed image needs to be resmushed
1291
  if ( ! empty( $attachments ) && is_array( $attachments ) ) {
 
 
 
 
 
 
 
 
 
 
1292
  foreach ( $attachments as $attachment_k => $attachment ) {
1293
 
 
 
 
 
 
 
1294
  //For NextGen we get the metadata in the attachment data itself
1295
- if ( ! empty( $attachment['wp_smush'] ) ) {
1296
  $smush_data = $attachment['wp_smush'];
1297
  } else {
1298
  //Check the current settings, and smush data for the image
1299
  $smush_data = get_post_meta( $attachment, $this->smushed_meta_key, true );
1300
  }
1301
 
1302
- if ( ! empty( $smush_data['stats'] ) ) {
 
1303
 
1304
  //If we need to optmise losslessly, add to resmush list
1305
  $smush_lossy = $WpSmush->lossy_enabled && ! $smush_data['stats']['lossy'];
@@ -1311,15 +1636,57 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1311
  $smush_original = $WpSmush->smush_original && empty( $smush_data['sizes']['full'] );
1312
 
1313
  if ( $smush_lossy || $strip_exif || $smush_original ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1314
  $resmush_list[] = 'nextgen' == $type ? $attachment_k : $attachment;
1315
  continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1316
  }
1317
  }
1318
  }
1319
 
1320
  //Check for Upfront images that needs to be smushed
1321
  if ( $upfront_active && 'nextgen' != $type ) {
1322
- $upfront_attachments = $this->get_upfront_images( $resmush_list );
1323
  if ( ! empty( $upfront_attachments ) && is_array( $upfront_attachments ) ) {
1324
  foreach ( $upfront_attachments as $u_attachment_id ) {
1325
  if ( ! in_array( $u_attachment_id, $resmush_list ) ) {
@@ -1342,49 +1709,88 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1342
  }//End Of Upfront loop
1343
 
1344
  //Store the resmush list in Options table
1345
- update_option( $key, $resmush_list );
 
1346
 
1347
- //Return the Remsmush list and UI to be appended to Bulk Smush UI
1348
- if ( $return_ui ) {
1349
- if ( 'nextgen' != $type ) {
1350
- //Set the variables
1351
- $this->resmush_ids = $resmush_list;
1352
- } else {
1353
- //To avoid the php warning
1354
- $wpsmushnextgenadmin->resmush_ids = $resmush_list;
1355
- }
1356
 
1357
- //Initialize stats
1358
- if ( empty( $this->remaining_count ) ) {
1359
- $this->setup_global_stats();
1360
- }
 
1361
 
1362
- if ( ( $count = count( $resmush_list ) ) > 0 || $this->remaining_count > 0 ) {
 
 
 
 
 
 
 
1363
  $show = true;
1364
 
1365
- if ( empty( $wpsmushnextgenadmin->remaining_count ) && 'nextgen' == $type ) {
1366
- $wpsmushnextgenadmin->setup_stats();
1367
- }
1368
  $count += 'nextgen' == $type ? $wpsmushnextgenadmin->remaining_count : $this->remaining_count;
1369
 
1370
  $ajax_response = $this->bulk_ui->bulk_resmush_content( $count, $show );
1371
- $message = sprintf( esc_html__("You have images that need smushing. %sBulk smush now!%s", "wp-smushit"), '<a href="#" class="wp-smush-trigger-bulk">', '</a>' );
1372
- $resp = '<div class="wp-smush-notice wp-smush-resmush-message wp-smush-resmush-pending"><i class="dev-icon dev-icon-tick"></i> ' . $message . '
 
 
 
 
 
1373
  <i class="dev-icon dev-icon-cross"></i>
1374
  </div>';
1375
- } else {
1376
- //Delete the resmush list
1377
- delete_option( $key );
1378
- }
 
 
 
 
 
 
 
 
 
 
 
1379
  }
1380
  }
1381
 
1382
  //If there is a Ajax response return it, else return null
1383
- $return = ! empty( $ajax_response ) ? array(
1384
- "resmush_ids" => $resmush_list,
1385
- "content" => $ajax_response
1386
- ) : '';
1387
- $return['notice'] = $resp;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1388
 
1389
  wp_send_json_success( $return );
1390
 
@@ -1414,41 +1820,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1414
  //Delete resmush list
1415
  delete_option( $mkey );
1416
  } else {
1417
- update_option( $mkey, $resmush_list );
1418
- }
1419
- }
1420
-
1421
- /**
1422
- * Get the attachment ids with Upfront images
1423
- *
1424
- * @param array $skip_ids
1425
- *
1426
- * @return array|bool
1427
- */
1428
- function get_upfront_images( $skip_ids = array() ) {
1429
-
1430
- $query = array(
1431
- 'fields' => 'ids',
1432
- 'post_type' => 'attachment',
1433
- 'post_status' => 'any',
1434
- 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
1435
- 'order' => 'ASC',
1436
- 'posts_per_page' => - 1,
1437
- 'meta_key' => 'upfront_used_image_sizes',
1438
- 'no_found_rows' => true
1439
- );
1440
-
1441
- //Skip all the ids which are already in resmush list
1442
- if ( ! empty( $skip_ids ) && is_array( $skip_ids ) ) {
1443
- $query['post__not_in'] = $skip_ids;
1444
- }
1445
-
1446
- $results = new WP_Query( $query );
1447
-
1448
- if ( ! is_wp_error( $results ) && $results->post_count > 0 ) {
1449
- return $results->posts;
1450
- } else {
1451
- return false;
1452
  }
1453
  }
1454
 
@@ -1479,79 +1851,6 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1479
  }
1480
  }
1481
 
1482
- /**
1483
- * Returns/Updates the number of images Super Smushed
1484
- *
1485
- * @param string $type media/nextgen, Type of images to get/set the super smushed count for
1486
- *
1487
- * @param array $attachments Optional, By default Media attachments will be fetched
1488
- *
1489
- * @return array|mixed|void
1490
- *
1491
- */
1492
- function super_smushed_count( $type = 'media', $attachments = '' ) {
1493
-
1494
- if ( 'media' == $type ) {
1495
- $count = $this->media_super_smush_count();
1496
- } else {
1497
- $key = 'wp-smush-super_smushed_nextgen';
1498
-
1499
- //Flag to check if we need to re-evaluate the count
1500
- $revaluate = false;
1501
-
1502
- $super_smushed = get_option( $key, false );
1503
-
1504
- //Check if need to revalidate
1505
- if ( ! $super_smushed || empty( $super_smushed ) || empty( $super_smushed['ids'] ) ) {
1506
-
1507
- $super_smushed = array(
1508
- 'ids' => array()
1509
- );
1510
-
1511
- $revaluate = true;
1512
- } else {
1513
- $last_checked = $super_smushed['timestamp'];
1514
-
1515
- $diff = $last_checked - current_time( 'timestamp' );
1516
-
1517
- //Difference in hour
1518
- $diff_h = $diff / 3600;
1519
-
1520
- //if last checked was more than 1 hours.
1521
- if ( $diff_h > 1 ) {
1522
- $revaluate = true;
1523
- }
1524
- }
1525
- //Do not Revaluate stats if nextgen attachments are not provided
1526
- if ( 'nextgen' == $type && empty( $attachments ) && $revaluate ) {
1527
- $revaluate = false;
1528
- }
1529
-
1530
- //Need to scan all the image
1531
- if ( $revaluate ) {
1532
- //Get all the Smushed attachments ids
1533
- $super_smushed_images = $this->get_lossy_attachments( $attachments, false );
1534
-
1535
- if ( ! empty( $super_smushed_images ) && is_array( $super_smushed_images ) ) {
1536
- //Iterate over all the attachments to check if it's already there in list, else add it
1537
- foreach ( $super_smushed_images as $id ) {
1538
- if ( ! in_array( $id, $super_smushed['ids'] ) ) {
1539
- $super_smushed['ids'][] = $id;
1540
- }
1541
- }
1542
- }
1543
-
1544
- $super_smushed['timestamp'] = current_time( 'timestamp' );
1545
-
1546
- update_option( $key, $super_smushed );
1547
- }
1548
-
1549
- $count = ! empty( $super_smushed['ids'] ) ? count( $super_smushed['ids'] ) : 0;
1550
- }
1551
-
1552
- return $count;
1553
- }
1554
-
1555
  /**
1556
  * Add/Remove image id from Super Smushed images count
1557
  *
@@ -1592,7 +1891,7 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1592
  //Add the timestamp
1593
  $super_smushed['timestamp'] = current_time( 'timestamp' );
1594
 
1595
- update_option( $key, $super_smushed );
1596
 
1597
  //Update to database
1598
  return true;
@@ -1634,121 +1933,369 @@ if ( ! class_exists( 'WpSmushitAdmin' ) ) {
1634
 
1635
  /**
1636
  * Delete the resmush list for Nextgen or the Media Library
 
 
 
1637
  */
1638
  function delete_resmush_list() {
1639
 
1640
- $key = ! empty( $_POST['type'] ) && 'nextgen' == $_POST['type'] ? 'wp-smush-nextgen-resmush-list' : 'wp-smush-resmush-list';
 
 
 
 
 
 
 
 
 
 
1641
  //Delete the resmush list
1642
  delete_option( $key );
1643
- wp_send_json_success();
1644
  }
1645
 
1646
  /**
1647
- * Updates the Meta for existing smushed images and retrieves the count of Super Smushed images
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1648
  *
1649
- * @return int Count of Super Smushed images
1650
  *
1651
  */
1652
- function media_super_smush_count() {
1653
- //Check if we have updated the stats for existing images, One time
1654
- if ( ! get_option( 'wp-smush-lossy-updated' ) ) {
1655
-
1656
- //Get all the smushed attachments
1657
- $attachments = $this->get_lossy_attachments( '', false );
1658
- foreach ( $attachments as $attachment ) {
1659
- update_post_meta( $attachment, 'wp-smush-lossy', 1 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1660
  }
1661
  }
1662
- //Get all the attachments with wp-smush-lossy
1663
- $limit = apply_filters( 'wp_smush_query_limit', 2000 );
1664
- $limit = intval( $limit );
1665
- $get_posts = true;
1666
- $super_smushed = array();
1667
- $args = array(
1668
- 'fields' => 'ids',
1669
- 'post_type' => 'attachment',
1670
- 'post_status' => 'any',
1671
- 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
1672
- 'orderby' => 'ID',
1673
- 'order' => 'DESC',
1674
- 'posts_per_page' => $limit,
1675
- 'offset' => 0,
1676
- 'meta_query' => array(
1677
- array(
1678
- 'key' => 'wp-smush-lossy',
1679
- 'value' => 1
1680
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1681
  ),
1682
- 'update_post_term_cache' => false,
1683
- 'no_found_rows' => true,
1684
  );
1685
- //Loop Over to get all the attachments
1686
- while ( $get_posts ) {
1687
 
1688
- //Remove the Filters added by WP Media Folder
1689
- $this->remove_wmf_filters();
 
1690
 
1691
- $query = new WP_Query( $args );
 
1692
 
1693
- if ( ! empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
1694
- //Merge the results
1695
- $super_smushed = array_merge( $super_smushed, $query->posts );
 
 
 
 
 
 
1696
 
1697
- //Update the offset
1698
- $args['offset'] += $limit;
1699
- } else {
1700
- //If we didn't get any posts from query, set $get_posts to false
1701
- $get_posts = false;
1702
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1703
 
1704
- //If total Count is set, and it is alread lesser than offset, don't query
1705
- if ( ! empty( $this->total_count ) && $this->total_count < $args['offset'] ) {
1706
- $get_posts = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1707
  }
1708
  }
1709
- update_option( 'wp-smush-lossy-updated', true );
 
 
 
 
 
 
 
 
 
 
 
1710
 
1711
- return count( $super_smushed );
1712
  }
1713
 
1714
  /**
1715
- * Allows to bulk restore the images, if there is any backup for them
 
1716
  */
1717
- function bulk_restore() {
1718
- $smushed_attachments = $this->get_smushed_attachments();
1719
- foreach ( $smushed_attachments as $attachment ) {
1720
- $this->restore_image( $attachment->attachment_id, false );
 
 
 
 
 
 
 
 
1721
  }
 
 
1722
  }
1723
 
1724
  /**
1725
- * Loads the Shared UI to on all admin pages
1726
- * @param $current_page
1727
  */
1728
- function load_shared_ui( $current_page ) {
1729
- //If class method exists, load shared UI
1730
- if ( class_exists( 'WDEV_Plugin_Ui' ) ) {
1731
 
1732
- if ( method_exists( 'WDEV_Plugin_Ui', 'load' ) ) {
 
 
 
1733
 
1734
- //Load Shared UI
1735
- WDEV_Plugin_Ui::load( WP_SMUSH_URL . '/assets/shared-ui/', false );
1736
 
1737
- if ( ( 'media_page_wp-smush-bulk' != $current_page && 'gallery_page_wp-smush-nextgen-bulk' != $current_page ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
1738
 
1739
- //Don't add thhe WPMUD class to body to other admin pages
1740
- remove_filter(
1741
- 'admin_body_class',
1742
- array( 'WDEV_Plugin_Ui', 'admin_body_class' )
1743
- );
1744
 
1745
- }
1746
- }
 
 
 
 
 
 
 
 
 
1747
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1748
  }
1749
 
1750
  }
1751
 
1752
  global $wpsmushit_admin;
1753
  $wpsmushit_admin = new WpSmushitAdmin();
1754
- }
4
  * @subpackage Admin
5
  * @version 1.0
6
  *
 
7
  * @author Umesh Kumar <umesh@incsub.com>
8
  *
9
  * @copyright (c) 2016, Incsub (http://incsub.com)
10
  */
11
+
12
  //Include Bulk UI
13
  require_once WP_SMUSH_DIR . 'lib/class-wp-smush-ui.php';
14
 
29
  * @property int $remaining_count
30
  * @property int $total_count
31
  * @property int $smushed_count
 
32
  */
33
  class WpSmushitAdmin extends WpSmush {
34
 
49
  */
50
  public $smushed_count;
51
 
52
+ /**
53
+ * @var Smushed attachments from selected directories.
54
+ */
55
+ public $dir_stats;
56
+
57
  /**
58
  * @var Smushed attachments out of total attachments
59
  */
60
+ public $remaining_count;
61
+
62
+ /**
63
+ * @var Super Smushed attachments count
64
+ */
65
  public $super_smushed;
66
 
67
+ /**
68
+ * @var array Unsmushed image ids
69
+ */
70
+ public $attachments = array();
71
+
72
+ /**
73
+ * @var array Unsmushed image ids
74
+ */
75
+ public $unsmushed_attachments = array();
76
+
77
+ /**
78
+ * @var array Attachment ids which are smushed
79
+ *
80
+ */
81
+ public $smushed_attachments = array();
82
+
83
+ /**
84
+ * @var array Image ids that needs to be resmushed
85
+ */
86
+ public $resmush_ids = array();
87
+
88
+ public $mime_types = array( 'image/jpg', 'image/jpeg', 'image/gif', 'image/png' );
89
+
90
  /**
91
  * @array Stores the stats for all the images
92
  */
101
 
102
  public $upgrade_url = 'https://premium.wpmudev.org/project/wp-smush-pro/';
103
 
104
+ public $image_sizes = array();
 
 
 
 
 
 
 
 
 
105
 
106
  /**
107
+ * @var string Stores the headers returned by the latest API call
108
+ *
109
  */
110
+ public $api_headers = array();
111
+
112
+ public $page_smush_all = '';
113
+
114
+ //List of pages where smush needs to be loaded
115
+ public $pages = array(
116
+ 'nggallery-manage-images',
117
+ 'gallery_page_wp-smush-nextgen-bulk',
118
+ 'post',
119
+ 'post-new',
120
+ 'upload',
121
+ 'settings_page_wp-smush-network',
122
+ 'media_page_wp-smush-bulk',
123
+ 'media_page_wp-smush-all'
124
+ );
125
+
126
+ public $plugin_pages = array(
127
+ 'gallery_page_wp-smush-nextgen-bulk',
128
+ 'settings_page_wp-smush-network',
129
+ 'media_page_wp-smush-bulk',
130
+ 'media_page_wp-smush-all'
131
+ );
132
 
133
  /**
134
  * Constructor
135
  */
136
  public function __construct() {
137
 
 
 
 
138
  // hook scripts and styles
139
  add_action( 'admin_init', array( $this, 'register' ) );
140
 
141
  // hook custom screen
142
  add_action( 'admin_menu', array( $this, 'screen' ) );
143
 
144
+ //Network Settings Page
145
+ add_action( 'network_admin_menu', array( $this, 'screen' ) );
146
+
147
  //Handle Smush Bulk Ajax
148
  add_action( 'wp_ajax_wp_smushit_bulk', array( $this, 'process_smush_request' ) );
149
 
150
  //Handle Smush Single Ajax
151
  add_action( 'wp_ajax_wp_smushit_manual', array( $this, 'smush_manual' ) );
152
 
 
 
 
153
  //Handle Restore operation
154
  add_action( 'wp_ajax_smush_resmush_image', array( $this, 'resmush_image' ) );
155
 
156
+ //Scan images as per the latest settings
157
  add_action( 'wp_ajax_scan_for_resmush', array( $this, 'scan_images' ) );
158
 
159
+ //Save Settings
160
+ add_action( 'wp_ajax_save_settings', array( $this, 'save_settings' ) );
161
+
162
  add_filter( 'plugin_action_links_' . WP_SMUSH_BASENAME, array(
163
  $this,
164
  'settings_link'
170
  //Attachment status, Grid view
171
  add_filter( 'attachment_fields_to_edit', array( $this, 'filter_attachment_fields_to_edit' ), 10, 2 );
172
 
173
+ // Smush Upgrade
174
  add_action( 'admin_notices', array( $this, 'smush_upgrade' ) );
175
 
176
+ // New Features Notice
177
+ // add_action( 'admin_notices', array( $this, 'smush_updated' ) );
178
+ // add_action( 'network_admin_notices', array( $this, 'smush_updated' ) );
179
+
180
  //Handle the smush pro dismiss features notice ajax
181
  add_action( 'wp_ajax_dismiss_upgrade_notice', array( $this, 'dismiss_upgrade_notice' ) );
182
 
183
  //Handle the smush pro dismiss features notice ajax
184
  add_action( 'wp_ajax_dismiss_welcome_notice', array( $this, 'dismiss_welcome_notice' ) );
185
 
186
+ //Handle the smush pro dismiss features notice ajax
187
+ add_action( 'wp_ajax_dismiss_update_info', array( $this, 'dismiss_update_info' ) );
188
+
189
  //Update the Super Smush count, after the smushing
190
  add_action( 'wp_smush_image_optimised', array( $this, 'update_lists' ), '', 2 );
191
 
194
 
195
  add_action( 'admin_init', array( $this, 'init_settings' ) );
196
 
197
+ /**
198
+ * Prints a membership validation issue notice in Media Library
199
+ */
200
+ add_action( 'admin_notices', array( $this, 'media_library_membership_notice' ) );
201
+
202
  $this->bulk_ui = new WpSmushBulkUi();
203
+
204
  }
205
 
206
  function init_settings() {
207
  $this->settings = array(
208
+ 'networkwide' => array(
209
+ 'label' => esc_html__( 'Enable Network wide settings', 'wp-smushit' ),
210
+ 'desc' => esc_html__( 'If disabled sub sites can override the individual Smush settings.', 'wp-smushit' )
211
+ ),
212
+ 'auto' => array(
213
  'label' => esc_html__( 'Automatically smush my images on upload', 'wp-smushit' ),
214
  'desc' => esc_html__( 'When you upload images to the media library, we’ll automatically optimize them.', 'wp-smushit' )
215
  ),
216
+ 'keep_exif' => array(
217
  'label' => esc_html__( 'Preserve image EXIF data', 'wp-smushit' ),
218
  'desc' => esc_html__( 'EXIF data stores camera settings, focal length, date, time and location information in image files. EXIF data makes image files larger but if you are a photographer you may want to preserve this information.', 'wp-smushit' )
219
  ),
220
+ 'resize' => array(
221
+ 'label' => esc_html__( 'Resize original images', 'wp-smushit' ),
222
+ 'desc' => esc_html__( 'Save a ton of space by not storing over-sized images on your server. Set image maximum width and height and large images will be automatically scaled before being added to the media library.', 'wp-smushit' )
223
+ ),
224
+ 'lossy' => array(
225
  'label' => esc_html__( 'Super-smush my images', 'wp-smushit' ),
226
+ 'desc' => esc_html__( 'Compress images up to 2x more than regular smush with almost no visible drop in quality.', 'wp-smushit' )
227
  ),
228
+ 'original' => array(
229
  'label' => esc_html__( 'Include my original full-size images', 'wp-smushit' ),
230
  'desc' => esc_html__( 'WordPress crops and resizes every image you upload for embedding on your site. By default, Smush only compresses these cropped and resized images, not your original full-size images. To save space on your server, activate this setting to smush your original images, too. Note: This doesn’t usually improve page speed.', 'wp-smushit' )
231
  ),
232
+ 'backup' => array(
233
  'label' => esc_html__( 'Make a copy of my original images', 'wp-smushit' ),
234
  'desc' => esc_html__( 'Save your original full-size images so you can restore them at any point. Note: Activating this setting will significantly increase the size of your uploads folder by nearly twice as much.', 'wp-smushit' )
235
+ ),
236
+ 'png_to_jpg' => array(
237
+ 'label' => esc_html__( 'Convert PNG to JPEG (lossy)', 'wp-smushit' ),
238
+ 'desc' => sprintf( esc_html__( "When you compress a PNG file, Smush will check if converting the file to JPEG will further reduce its size. %s Note: PNGs with transparency will be ignored and Smush will only convert the file format if it results in a smaller file size. This will change the file’s name and extension, and any hard-coded URLs will need to be updated.%s", 'wp-smushit' ), "<br /><strong>", "</strong>" )
239
  )
240
  );
241
 
242
+ /**
243
+ * Allow to add other settings via filtering the variable
244
+ *
245
+ */
246
+ $this->settings = apply_filters('wp_smush_settings', $this->settings );
247
+
248
+ //Initialize Image dimensions
249
+ $this->image_sizes = $this->image_dimensions();
250
  }
251
 
252
  /**
279
  function screen() {
280
  global $admin_page_suffix;
281
 
282
+ //Bulk Smush Page for each site
283
  $admin_page_suffix = add_media_page( 'Bulk WP Smush', 'WP Smush', 'edit_others_posts', 'wp-smush-bulk', array(
284
  $this->bulk_ui,
285
  'ui'
286
  ) );
287
 
288
+ //Network Settings Page
289
+ $page = 'settings.php';
290
+ $cap = 'manage_network_options';
291
+
292
+ add_submenu_page( $page, 'WP Smush', 'WP Smush', $cap, 'wp-smush', array(
293
+ $this->bulk_ui,
294
+ 'ui'
295
+ ) );
296
+
297
  //For Nextgen gallery Pages, check later in enqueue function
298
  add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
299
 
 
 
300
  }
301
 
302
  /**
304
  */
305
  function register() {
306
 
307
+ //Main JS
308
+ wp_register_script( 'wp-smushit-admin-js', WP_SMUSH_URL . 'assets/js/wp-smushit-admin.js', array(
309
+ 'jquery'
310
+ ), WP_SMUSH_VERSION );
311
+
312
+ //Notice JS
313
+ wp_register_script( 'wp-smushit-notice-js', WP_SMUSH_URL . 'assets/js/notice.js', array(
314
+ 'jquery'
315
+ ), WP_SMUSH_VERSION );
316
+
317
+ /* Register Style */
318
+ wp_register_style( 'wp-smushit-admin-css', WP_SMUSH_URL . 'assets/css/wp-smushit-admin.css', array(), WP_SMUSH_VERSION );
319
+ //Notice CSS
320
+ wp_register_style( 'wp-smushit-notice-css', WP_SMUSH_URL . 'assets/css/notice.css', array(), WP_SMUSH_VERSION );
321
+
322
+ //jQuery tree
323
+ wp_register_script( 'jqft-js', WP_SMUSH_URL . 'assets/js/jQueryFileTree.js', array(
324
+ 'jquery'
325
+ ), WP_SMUSH_VERSION, true );
326
+ wp_register_style( 'jqft-css', WP_SMUSH_URL . 'assets/css/jQueryFileTree.min.css', array(), WP_SMUSH_VERSION );
327
+
328
+ //Dismiss Update Info
329
+ $this->dismiss_update_info();
 
 
 
 
 
 
 
 
 
330
  }
331
 
332
  /**
334
  */
335
  function enqueue() {
336
 
 
 
337
  $current_screen = get_current_screen();
338
  $current_page = $current_screen->base;
339
 
342
  */
343
  $enqueue_smush = apply_filters( 'wp_smush_enqueue', true );
344
 
345
+ //Load js and css on all admin pages, in order t display install/upgrade notice
346
+ // And If upgrade/install message is dismissed or for pro users, Do not enqueue script
347
+ if ( get_option( 'wp-smush-hide_upgrade_notice' ) || get_site_option( 'wp-smush-hide_upgrade_notice' ) || $this->validate_install() ) {
348
+ /** @var $pages List of screens where script needs to be loaded */
349
+
350
  //Do not enqueue, unless it is one of the required screen
351
+ if ( ! $enqueue_smush || ! in_array( $current_page, $this->pages ) ) {
352
 
353
  return;
354
  }
370
  );
371
  }
372
 
373
+ //Load on Smush all page only
374
+ if ( 'media_page_wp-smush-bulk' == $current_page ) {
375
+ //Load Jquery tree on specified page
376
+ wp_enqueue_script( 'jqft-js' );
377
+ wp_enqueue_style( 'jqft-css' );
378
+ }
379
+
380
  // localize translatable strings for js
381
  $this->localize();
382
  }
385
  * Localize Translations
386
  */
387
  function localize() {
388
+ global $current_screen, $wpsmush_settings, $wpsmush_db;
389
+ $current_page = ! empty( $current_screen ) ? $current_screen->base : '';
390
 
 
391
  $handle = 'wp-smushit-admin-js';
392
 
 
 
 
393
  $wp_smush_msgs = array(
394
+ 'resmush' => esc_html__( 'Super-Smush', 'wp-smushit' ),
395
+ 'smush_now' => esc_html__( 'Smush Now', 'wp-smushit' ),
396
+ 'error_in_bulk' => esc_html__( '{{errors}} image(s) were skipped due to an error.', 'wp-smushit' ),
397
+ 'all_resmushed' => esc_html__( 'All images are fully optimized.', 'wp-smushit' ),
398
+ 'restore' => esc_html__( "Restoring image..", "wp-smushit" ),
399
+ 'smushing' => esc_html__( "Smushing image..", "wp-smushit" ),
400
+ 'checking' => esc_html__( "Checking images..", "wp-smushit" ),
401
+ 'membership_valid' => esc_html__( "We successfully verified your membership, all the Pro features should work completely. ", "wp-smushit" ),
402
+ 'membership_invalid' => esc_html__( "Your membership couldn't be verified.", "wp-smushit" ),
403
+ 'missing_path' => esc_html__( "Missing file path.", "wp-smushit" ),
404
+ //Used by Directory Smush
405
+ 'unfinished_smush_single' => esc_html__( "image could not be smushed.", "wp-smushit" ),
406
+ 'unfinished_smush' => esc_html__( "images could not be smushed.", "wp-smushit" ),
407
+ 'already_optimised' => esc_html__( "Already Optimized", "wp-smushit" ),
408
+ 'ajax_error' => esc_html__( "Ajax Error", "wp-smushit" ),
409
+ 'all_done' => esc_html__( "All Done!", "wp-smushit" ),
410
+ 'all_done' => esc_html__( "All Done!", "wp-smushit" ),
411
  );
412
 
413
  wp_localize_script( $handle, 'wp_smush_msgs', $wp_smush_msgs );
414
 
415
+ //Load the stats on selected screens only
416
+ if ( $current_page == 'media_page_wp-smush-bulk' ) {
417
+
418
+ //Get resmush list, If we have a resmush list already, localize those ids
419
+ if ( $resmush_ids = get_option( "wp-smush-resmush-list" ) ) {
420
+ //get the attachments, and get lossless count
421
+ $this->resmush_ids = $resmush_ids;
422
+ }
423
 
424
+ //Setup all the stats
425
+ $this->setup_global_stats( true );
426
 
427
+ //Localize smushit_ids variable, if there are fix number of ids
428
+ $this->unsmushed_attachments = ! empty( $_REQUEST['ids'] ) ? array_map( 'intval', explode( ',', $_REQUEST['ids'] ) ) : array();
429
+
430
+ if ( empty( $this->unsmushed_attachments ) ) {
431
+ //Get attachments if all the images are not smushed
432
+ $this->unsmushed_attachments = $this->remaining_count > 0 ? $wpsmush_db->get_unsmushed_attachments() : array();
433
+ $this->unsmushed_attachments = ! empty( $this->unsmushed_attachments ) && is_array( $this->unsmushed_attachments ) ? array_values( $this->unsmushed_attachments ) : $this->unsmushed_attachments;
434
+ }
435
+
436
+ //Array of all smushed, unsmushed and lossless ids
437
+ $data = array(
438
+ 'count_supersmushed' => $this->super_smushed,
439
+ 'count_smushed' => $this->smushed_count,
440
+ 'count_total' => $this->total_count,
441
+ 'count_images' => $this->stats['total_images'],
442
+ 'unsmushed' => $this->unsmushed_attachments,
443
+ 'resmush' => $this->resmush_ids,
444
+ 'size_before' => $this->stats['size_before'],
445
+ 'size_after' => $this->stats['size_after'],
446
+ 'savings_bytes' => $this->stats['bytes'],
447
+ 'savings_resize' => $this->stats['resize_savings'],
448
+ 'savings_conversion' => $this->stats['conversion_savings'],
449
+ 'savings_dir_smush' => $this->dir_stats
450
+ );
451
+ } else {
452
+ $data = array(
453
+ 'count_supersmushed' => '',
454
+ 'count_smushed' => '',
455
+ 'count_total' => '',
456
+ 'count_images' => '',
457
+ 'unsmushed' => '',
458
+ 'resmush' => '',
459
+ 'savings_bytes' => '',
460
+ 'savings_resize' => '',
461
+ 'savings_conversion' => '',
462
+ 'savings_supersmush' => '',
463
+ 'pro_savings' => ''
464
+ );
465
+
466
+ }
467
+
468
+ $data['resize_sizes'] = $this->get_max_image_dimensions();
469
+
470
+ $data['timeout'] = WP_SMUSH_TIMEOUT * 1000; //Convert it into ms
471
 
472
  wp_localize_script( 'wp-smushit-admin-js', 'wp_smushit_data', $data );
473
 
474
+ //Check if settings were changed for a multisite, and localize whether to run re-check on page load
475
+ if ( is_multisite() && get_site_option( WP_SMUSH_PREFIX . 'networkwide' ) && ! is_network_admin() ) {
476
+ //Check the last settings stored in db
477
+ $settings = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'last_settings', '' );
478
+
479
+ //Get current settings
480
+ $c_settings = $this->get_serialised_settings();
481
+
482
+ //If not same, Set a variable to run re-check on page load
483
+ if( $settings != $c_settings ) {
484
+ wp_localize_script( 'wp-smushit-admin-js', 'wp_smush_run_re_check', array( 1 ) );
485
+ }
486
+ }
487
+
488
  }
489
 
490
  /**
494
  *
495
  */
496
  function setup_global_stats( $force_update = false ) {
497
+ global $wpsmush_db, $wpsmush_dir;
 
 
 
 
498
 
499
+ // Set directory smush status.
500
+ $this->dir_stats = $wpsmush_dir->total_stats();
 
 
 
 
501
 
502
+ //Setup Attachments and total count
503
+ $wpsmush_db->total_count( true );
 
504
 
505
+ $this->stats = $this->global_stats( $force_update );
 
 
 
506
 
507
+ if ( empty( $this->smushed_attachments ) ) {
508
+ //Get smushed attachments
509
+ $this->smushed_attachments = $wpsmush_db->smushed_count( true );
510
  }
511
 
512
+ //Get supersmushed iamges count
513
+ if ( empty( $this->super_smushed ) ) {
 
 
 
514
 
515
+ $this->super_smushed = $wpsmush_db->super_smushed_count();
516
+ }
 
 
 
 
517
 
518
+ // Set pro savings.
519
+ $this->set_pro_savings();
520
 
521
+ // Set smushed count
522
+ $this->smushed_count = ! empty( $this->smushed_attachments ) ? count( $this->smushed_attachments ) : 0;
523
+ $this->remaining_count = $this->remaining_count();
524
+ }
525
 
526
+ /**
527
+ * Set pro savings stats if not premium user.
528
+ *
529
+ * For non-premium users, show expected avarage savings based
530
+ * on the free version savings.
531
+ */
532
+ function set_pro_savings() {
533
 
534
+ global $WpSmush;
 
535
 
536
+ // No need this already premium.
537
+ if ( $WpSmush->validate_install() ) {
538
+ return;
539
  }
540
 
541
+ //Initialize
542
+ $this->stats['pro_savings'] = array(
543
+ 'percent' => 0,
544
+ 'savings' => 0,
545
+ );
546
 
547
+ // Default values.
548
+ $savings = $this->stats['percent'] > 0 ? $this->stats['percent'] : 0;
549
+ $savings_bytes = $this->stats['human'] > 0 ? $this->stats['bytes'] : "0";
550
+ $orig_diff = 2.22058824;
551
+ if ( ! empty( $savings ) && $savings > 49 ) {
552
+ $orig_diff = 1.22054412;
553
  }
554
+ //Calculate Pro savings
555
+ if( !empty( $savings ) ) {
556
+ $savings = $orig_diff * $savings;
557
+ $savings_bytes = $orig_diff * $savings_bytes;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
  }
559
 
560
+ // Set pro savings in global stats.
561
+ if ( $savings > 0 ) {
562
+ $this->stats['pro_savings'] = array(
563
+ 'percent' => number_format_i18n( $savings, 1 ),
564
+ 'savings' => size_format( $savings_bytes, 1 ),
565
+ );
566
+ }
567
  }
568
 
569
  /**
570
  * Processes the Smush request and sends back the next id for smushing
571
+ *
572
+ * Bulk Smushing Handler
573
+ *
574
  */
575
  function process_smush_request() {
576
 
577
+ global $WpSmush, $wpsmush_helper;
578
 
579
  // turn off errors for ajax result
580
  @error_reporting( 0 );
585
  wp_send_json_error( 'missing id' );
586
  }
587
 
588
+ if ( ! $this->validate_install() ) {
589
  //Free version bulk smush, check the transient counter value
590
  $should_continue = $this->check_bulk_limit();
591
  }
600
  );
601
  }
602
 
603
+ $error = '';
604
+ $send_error = false;
605
 
606
+ $attachment_id = (int) ( $_REQUEST['attachment_id'] );
607
 
608
+ /**
609
+ * Filter: wp_smush_image
610
+ *
611
+ * Whether to smush the given attachment id or not
612
+ *
613
+ * @param $skip bool, whether to Smush image or not
614
+ *
615
+ * @param $Attachment Id, Attachment id of the image being processed
616
+ *
617
+ */
618
+ if ( ! apply_filters( 'wp_smush_image', true, $attachment_id ) ) {
619
+ $send_error = true;
620
+ $error = $this->filter_error( esc_html__( "Attachment $attachment_id was skipped.", "wp-smushit" ), $attachment_id );
621
+ }
622
+
623
+ //Get the file path for backup
624
+ $attachment_file_path = $wpsmush_helper->get_attached_file( $attachment_id );
625
+
626
+ //Download if not exists
627
+ do_action('smush_file_exists', $attachment_file_path, $attachment_id );
628
+
629
+ //Take Backup
630
+ global $wpsmush_backup;
631
+ $wpsmush_backup->create_backup( $attachment_file_path, '', $attachment_id );
632
+
633
+ if ( ! $send_error ) {
634
+ //Proceed only if Smushing Transient is not set for the given attachment id
635
+ if ( ! get_transient( 'smush-in-progress-' . $attachment_id ) ) {
636
+
637
+ //Set a transient to avoid multiple request
638
+ set_transient( 'smush-in-progress-' . $attachment_id, true, WP_SMUSH_TIMEOUT );
639
+
640
+ $original_meta = wp_get_attachment_metadata( $attachment_id, true );
641
+
642
+ //Resize the dimensions of the image
643
+ /**
644
+ * Filter whether the existing image should be resized or not
645
+ *
646
+ * @since 2.3
647
+ *
648
+ * @param bool $should_resize , Set to True by default
649
+ *
650
+ * @param $attachment_id Image Attachment ID
651
+ *
652
+ */
653
+ if ( $should_resize = apply_filters( 'wp_smush_resize_media_image', true, $attachment_id ) ) {
654
+ $updated_meta = $this->resize_image( $attachment_id, $original_meta );
655
+ $original_meta = ! empty( $updated_meta ) ? $updated_meta : $original_meta;
656
+ }
657
 
658
+ global $wpsmush_pngjpg;
 
659
 
660
+ //Convert PNGs to JPG
661
+ $original_meta = $wpsmush_pngjpg->png_to_jpg( $attachment_id, $original_meta );
662
 
663
+ $smush = $WpSmush->resize_from_meta_data( $original_meta, $attachment_id );
664
+ wp_update_attachment_metadata( $attachment_id, $original_meta );
665
+ }
666
 
667
+ //Delete Transient
668
+ delete_transient( 'smush-in-progress-' . $attachment_id );
669
  }
670
 
671
+ $smush_data = get_post_meta( $attachment_id, $this->smushed_meta_key, true );
672
+ $resize_savings = get_post_meta( $attachment_id, WP_SMUSH_PREFIX . 'resize_savings', true );
673
+ $conversion_savings = $wpsmush_helper->get_pngjpg_savings( $attachment_id );
674
+
675
+ $stats = array(
676
+ 'count' => ! empty( $smush_data['sizes'] ) ? count( $smush_data['sizes'] ) : 0,
677
+ 'size_before' => ! empty( $smush_data['stats'] ) ? $smush_data['stats']['size_before'] : 0,
678
+ 'size_after' => ! empty( $smush_data['stats'] ) ? $smush_data['stats']['size_after'] : 0,
679
+ 'savings_resize' => $resize_savings > 0 ? $resize_savings : 0,
680
+ 'savings_conversion' => $conversion_savings['bytes'] > 0 ? $conversion_savings : 0,
681
+ 'is_lossy' => ! empty( $smush_data ['stats'] ) ? $smush_data['stats']['lossy'] : false
682
+ );
683
 
684
+ if ( isset( $smush ) && is_wp_error( $smush ) ) {
685
+
686
+ $send_error = true;
687
 
 
688
  $error = $smush->get_error_message();
689
  //Check for timeout error and suggest to filter timeout
690
  if ( strpos( $error, 'timed out' ) ) {
691
  $error = esc_html__( "Smush request timed out, You can try setting a higher value for `WP_SMUSH_API_TIMEOUT`.", "wp-smushit" );
692
  }
 
693
  } else {
694
  //Check if a resmush request, update the resmush list
695
  if ( ! empty( $_REQUEST['is_bulk_resmush'] ) && 'false' != $_REQUEST['is_bulk_resmush'] && $_REQUEST['is_bulk_resmush'] ) {
696
  $this->update_resmush_list( $attachment_id );
697
  }
 
698
  }
699
+
700
+ if ( ! $send_error ) {
701
+ /**
702
+ * Runs after a image is succesfully smushed
703
+ */
704
+ do_action( 'image_smushed', $attachment_id, $stats );
705
+ }
706
+
707
+ /**
708
+ * Used internally to modify the error message
709
+ *
710
+ */
711
+ $error = $this->filter_error( $error, $attachment_id );
712
+
713
+ //Wrap the error message in div
714
+ $error = !empty( $error ) ? sprintf( '<p class="wp-smush-error-message">%s</p>', $error ) : $error;
715
+
716
+ if ( ! $send_error ) {
717
+ //Update the bulk Limit count
718
+ $this->update_smush_count();
719
+ }
720
+
721
+ //Send ajax response
722
+ $send_error ? wp_send_json_error( array(
723
+ 'stats' => $stats,
724
+ 'error_msg' => $error,
725
+ 'show_warning' => intval( $this->show_warning() )
726
+
727
+ ) ) : wp_send_json_success( array(
728
+ 'stats' => $stats,
729
+ 'show_warning' => intval( $this->show_warning() )
730
+ ) );
731
+
732
  }
733
 
734
  /**
737
  * @uses smush_single()
738
  */
739
  function smush_manual() {
740
+
741
  // turn off errors for ajax result
742
  @error_reporting( 0 );
743
 
749
  wp_die( __( 'No attachment ID was provided.', 'wp-smushit' ) );
750
  }
751
 
752
+ $attachemnt_id = intval( $_GET['attachment_id'] );
753
+
754
+ /**
755
+ * Filter: wp_smush_image
756
+ *
757
+ * Whether to smush the given attachment id or not
758
+ *
759
+ */
760
+ if ( ! apply_filters( 'wp_smush_image', true, $attachemnt_id ) ) {
761
+ $error = $this->filter_error( esc_html__( "Attachment Skipped - Check `wp_smush_image` filter.", "wp-smushit" ), $attachemnt_id );
762
+ wp_send_json_error( array(
763
+ 'error_msg' => sprintf( '<p class="wp-smush-error-message">%s</p>', $error ),
764
+ 'show_warning' => intval( $this->show_warning() )
765
+ ) );
766
+ }
767
+
768
  //Pass on the attachment id to smush single function
769
+ $this->smush_single( $attachemnt_id );
770
  }
771
 
772
  /**
779
  */
780
  function smush_single( $attachment_id, $return = false ) {
781
 
782
+ //If the smushing transient is already set, return the status
783
+ if ( get_transient( 'smush-in-progress-' . $attachment_id ) || get_transient( "wp-smush-restore-$attachment_id" ) ) {
784
+ //Get the button status
785
+ $status = $this->set_status( $attachment_id, false, true );
786
+ if ( $return ) {
787
+ return $status;
788
+ } else {
789
+ wp_send_json_success( $status );
790
+ }
791
+ }
792
+
793
+ //Set a transient to avoid multiple request
794
+ set_transient( 'smush-in-progress-' . $attachment_id, true, WP_SMUSH_TIMEOUT );
795
+
796
+ global $WpSmush, $wpsmush_pngjpg, $wpsmush_helper;
797
 
798
  $attachment_id = absint( (int) ( $attachment_id ) );
799
 
800
+ //Get the file path for backup
801
+ $attachment_file_path = $wpsmush_helper->get_attached_file( $attachment_id );
802
+
803
+ //Download file if not exists
804
+ do_action('smush_file_exists', $attachment_file_path, $attachment_id );
805
+
806
+ //Take Backup
807
+ global $wpsmush_backup;
808
+ $wpsmush_backup->create_backup( $attachment_file_path, '', $attachment_id );
809
+
810
+ //Get the image metadata from $_POST
811
+ $original_meta = ! empty( $_POST['metadata'] ) ? $_POST['metadata'] : '';
812
+
813
+ $original_meta = empty( $original_meta ) ? wp_get_attachment_metadata( $attachment_id ) : $original_meta;
814
+
815
+ //Send image for resizing, if enabled resize first before any other operation
816
+ $updated_meta = $this->resize_image( $attachment_id, $original_meta );
817
+
818
+ //Convert PNGs to JPG
819
+ $updated_meta = $wpsmush_pngjpg->png_to_jpg( $attachment_id, $updated_meta );
820
+
821
+ $original_meta = ! empty( $updated_meta ) ? $updated_meta : $original_meta;
822
 
823
  //Smush the image
824
  $smush = $WpSmush->resize_from_meta_data( $original_meta, $attachment_id );
825
 
826
+ //Update the details, after smushing, so that latest image is used in hook
827
+ wp_update_attachment_metadata( $attachment_id, $original_meta );
828
+
829
  //Get the button status
830
  $status = $WpSmush->set_status( $attachment_id, false, true );
831
 
832
+ //Delete the transient after attachment meta is updated
833
+ delete_transient( 'smush-in-progress-' . $attachment_id );
834
+
835
  //Send Json response if we are not suppose to return the results
836
 
837
  /** Send stats **/
839
  if ( $return ) {
840
  return array( 'error' => $smush->get_error_message() );
841
  } else {
842
+ wp_send_json_error( array( 'error_msg' => '<p class="wp-smush-error-message">' . $smush->get_error_message() . '</p>',
843
+ 'show_warning' => intval( $this->show_warning() )
844
+ ) );
845
  }
846
  } else {
847
  if ( $return ) {
855
  /**
856
  * Check bulk sent count, whether to allow further smushing or not
857
  *
858
+ * @param bool $reset To hard reset the transient
859
+ *
860
+ * @param string $key Transient Key - bulk_sent_count/dir_sent_count
861
+ *
862
  * @return bool
863
  */
864
+ function check_bulk_limit( $reset = false, $key = 'bulk_sent_count' ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
865
 
866
+ $transient_name = WP_SMUSH_PREFIX . $key;
 
867
 
868
+ $bulk_sent_count = get_transient( $transient_name );
869
 
870
+ //Check if bulk smush limit is less than limit
871
+ if ( ! $bulk_sent_count || $bulk_sent_count < $this->max_free_bulk ) {
872
+ $continue = true;
873
+ } elseif ( $bulk_sent_count == $this->max_free_bulk ) {
874
+ //If user has reached the limit, reset the transient
875
+ $continue = false;
876
+ $reset = true;
877
+ } else {
878
+ $continue = false;
879
  }
880
 
881
+ //If we need to reset the transient
882
+ if ( $reset ) {
 
883
  set_transient( $transient_name, 0, 60 );
 
 
884
  }
885
+
886
+ return $continue;
887
  }
888
 
889
  /**
890
+ * Update the image smushed count in transient
891
+ *
892
+ * @param string $key
893
+ *
894
  */
895
+ function update_smush_count( $key = 'bulk_sent_count' ) {
 
 
 
 
 
896
 
897
+ $transient_name = WP_SMUSH_PREFIX . $key;
 
 
 
 
 
 
 
 
 
 
898
 
899
+ $bulk_sent_count = get_transient( $transient_name );
 
900
 
901
+ //If bulk sent count is not set
902
+ if ( false === $bulk_sent_count ) {
 
903
 
904
+ //start transient at 0
905
+ set_transient( $transient_name, 1, 200 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
906
 
907
+ } else if ( $bulk_sent_count < $this->max_free_bulk ) {
 
908
 
909
+ //If lte $this->max_free_bulk images are sent, increment
910
+ set_transient( $transient_name, $bulk_sent_count + 1, 200 );
911
 
 
 
 
 
 
 
 
 
 
 
912
  }
913
  }
914
 
918
  * @return int
919
  */
920
  function remaining_count() {
921
+
922
+ //Check if the resmush count is equal to remaining count
923
+ $resmush_count = count( $this->resmush_ids );
924
+ if ( $resmush_count > 0 && $resmush_count == $this->smushed_count ) {
925
+ return $resmush_count;
926
+ }
927
+
928
+ return ( $this->total_count - $this->smushed_count );
929
  }
930
 
931
  /**
994
  * @param bool $force_update , Whether to forcefully update the Cache
995
  *
996
  * @return array|bool|mixed
997
+ *
998
+ * @todo: remove id from global stats stored in db
999
+ *
1000
  */
1001
  function global_stats( $force_update = false ) {
1002
 
1003
+ if ( ! $force_update && $stats = get_option( 'smush_global_stats' ) ) {
1004
+ if ( ! empty( $stats ) && ! empty( $stats['size_before'] ) ) {
1005
+ if ( isset( $stats['id'] ) ) {
1006
+ unset( $stats['id'] );
1007
+ }
1008
+
1009
  return $stats;
1010
  }
1011
  }
1012
 
1013
+ global $wpdb, $wpsmush_db;
1014
 
1015
  $smush_data = array(
1016
  'size_before' => 0,
1017
  'size_after' => 0,
1018
  'percent' => 0,
1019
+ 'human' => 0,
1020
+ 'bytes' => 0
1021
  );
1022
 
1023
  /**
1024
  * Allows to set a limit of mysql query
1025
  * Default value is 2000
1026
  */
1027
+ $limit = $this->query_limit();
 
1028
  $offset = 0;
1029
  $query_next = true;
1030
 
1031
+ $supersmushed_count = 0;
1032
+ $smush_data['total_images'] = 0;
1033
 
1034
+ while ( $query_next ) {
1035
 
1036
+ $global_data = $wpdb->get_results( $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key=%s LIMIT $offset, $limit", "wp-smpro-smush-data" ) );
1037
  if ( ! empty( $global_data ) ) {
 
1038
  foreach ( $global_data as $data ) {
1039
+
1040
+ //Skip attachment, if in re-smush list
1041
+ if ( ! empty( $this->resmush_ids ) && in_array( $data->post_id, $this->resmush_ids ) ) {
1042
+ continue;
1043
+ }
1044
+
1045
+ $smush_data['id'][] = $data->post_id;
1046
+ if ( ! empty( $data->meta_value ) ) {
1047
+ $meta = maybe_unserialize( $data->meta_value );
1048
+ if ( ! empty( $meta['stats'] ) ) {
1049
+
1050
+ //Check for lossy Compression
1051
+ if ( 1 == $meta['stats']['lossy'] ) {
1052
+ $supersmushed_count += 1;
1053
+ }
1054
+
1055
+ //If the image was optimised
1056
+ if ( !empty( $meta['stats'] ) && $meta['stats']['size_before'] > $meta['stats']['size_after'] ) {
1057
+ //Total Image Smushed
1058
+ $smush_data['total_images'] += ! empty( $meta['sizes'] ) ? count( $meta['sizes'] ) : 0;
1059
+
1060
+ $smush_data['size_before'] += ! empty( $meta['stats']['size_before'] ) ? (int) $meta['stats']['size_before'] : 0;
1061
+ $smush_data['size_after'] += ! empty( $meta['stats']['size_after'] ) ? (int) $meta['stats']['size_after'] : 0;
1062
+ }
1063
+ }
1064
  }
1065
  }
1066
  }
1071
  $offset += $limit;
1072
 
1073
  //Compare the Offset value to total images
1074
+ if ( ! empty( $this->total_count ) && $this->total_count <= $offset ) {
1075
  $query_next = false;
1076
  } elseif ( ! $global_data ) {
1077
  //If we didn' got any results
1080
 
1081
  }
1082
 
1083
+ // Add directory smush image bytes.
1084
+ if ( ! empty( $this->dir_stats['bytes'] ) && $this->dir_stats['bytes'] > 0 ) {
1085
+ $smush_data['bytes'] += $this->dir_stats['bytes'];
1086
+ }
1087
+ // Add directory smush image total size.
1088
+ if ( ! empty( $this->dir_stats['orig_size'] ) && $this->dir_stats['orig_size'] > 0 ) {
1089
+ $smush_data['size_before'] += $this->dir_stats['orig_size'];
1090
+ }
1091
+ // Add directory smush saved size.
1092
+ if ( ! empty( $this->dir_stats['image_size'] ) && $this->dir_stats['image_size'] > 0 ) {
1093
+ $smush_data['size_after'] += $this->dir_stats['image_size'];
1094
+ }
1095
+ // Add directory smushed images.
1096
+ if ( ! empty( $this->dir_stats['optimised'] ) && $this->dir_stats['optimised'] > 0 ) {
1097
+ $smush_data['total_images'] += $this->dir_stats['optimised'];
1098
+ }
1099
+
1100
+ //Resize Savings
1101
+ $resize_savings = $wpsmush_db->resize_savings( false );
1102
+ $smush_data['resize_savings'] = ! empty( $resize_savings['bytes'] ) ? $resize_savings['bytes'] : 0;
1103
+
1104
+ //Conversion Savings
1105
+ $conversion_savings = $wpsmush_db->conversion_savings( false );
1106
+ $smush_data['conversion_savings'] = ! empty( $conversion_savings['bytes'] ) ? $conversion_savings['bytes'] : 0;
1107
+
1108
  if ( ! isset( $smush_data['bytes'] ) || $smush_data['bytes'] < 0 ) {
1109
  $smush_data['bytes'] = 0;
1110
  }
1111
 
1112
+ //Add the resize savings to bytes
1113
+ $smush_data['bytes'] += $smush_data['resize_savings'];
1114
+ $smush_data['size_before'] += $resize_savings['size_before'];
1115
+ $smush_data['size_after'] += $resize_savings['size_after'];
1116
+
1117
+ //Add Conversion Savings
1118
+ $smush_data['bytes'] += $smush_data['conversion_savings'];
1119
+ $smush_data['size_before'] += $conversion_savings['size_before'];
1120
+ $smush_data['size_after'] += $conversion_savings['size_after'];
1121
+
1122
  if ( $smush_data['size_before'] > 0 ) {
1123
  $smush_data['percent'] = ( $smush_data['bytes'] / $smush_data['size_before'] ) * 100;
1124
  }
1125
 
1126
  //Round off precentage
1127
+ $smush_data['percent'] = round( $smush_data['percent'], 1 );
1128
+
1129
+ $smush_data['human'] = size_format( $smush_data['bytes'], 1 );
1130
+
1131
+ //Setup Smushed attachment ids
1132
+ $this->smushed_attachments = ! empty( $smush_data['id'] ) ? $smush_data['id'] : '';
1133
+
1134
+ //Super Smushed attachment count
1135
+ $this->super_smushed = $supersmushed_count;
1136
 
1137
+ //Remove ids from stats
1138
+ unset( $smush_data['id'] );
1139
 
1140
  //Update Cache
1141
+ update_option( 'smush_global_stats', $smush_data, false );
1142
 
1143
  return $smush_data;
1144
  }
1145
 
1146
  /**
1147
+ * Get all the attachment meta, sum up the stats and return
1148
  *
1149
+ * @param bool $force_update , Whether to forcefully update the Cache
1150
  *
1151
+ * @return array|bool|mixed Stats
1152
  */
1153
+ function global_stats_from_ids( $force_update = false ) {
1154
 
1155
+ if ( ! $force_update && $stats = get_option( 'smush_global_stats' ) ) {
1156
+ if ( ! empty( $stats ) ) {
1157
+ return $stats;
1158
+ }
1159
+ }
1160
 
1161
+ global $wpsmush_db, $wpsmush_helper;
1162
+ if ( empty( $this->smushed_attachments ) ) {
1163
+ $this->smushed_attachments = $wpsmush_db->smushed_count( true );
1164
+ }
1165
+
1166
+ $smush_data = array(
1167
+ 'size_before' => 0,
1168
+ 'size_after' => 0,
1169
+ 'percent' => 0,
1170
+ 'human' => 0
1171
+ );
1172
+ $smush_data['count'] = 0;
1173
+ $smush_data['total_images'] = 0;
1174
+
1175
+ if ( ! empty( $this->smushed_attachments ) && is_array( $this->smushed_attachments ) ) {
1176
+ //Iterate over all the attachments
1177
+ foreach ( $this->smushed_attachments as $attachment ) {
1178
+ //Get all the Savings for each image
1179
+ $smush_stats = get_post_meta( $attachment, 'wp-smpro-smush-data', true );
1180
+ $resize_savings = get_post_meta( $attachment, WP_SMUSH_PREFIX . 'resize_savings', true );
1181
+ $conversion_savings = $wpsmush_helper->get_pngjpg_savings( $attachment );
1182
+
1183
+ $smush_data['count'] += 1;
1184
+ $smush_data['total_images'] += ! empty( $smush_stats['sizes'] ) ? count( $smush_stats['sizes'] ) : 0;
1185
+
1186
+ //Sum up all the stats
1187
+ if ( ! empty( $smush_stats['sizes'] ) ) {
1188
+ foreach ( $smush_stats['sizes'] as $size_k => $size_savings ) {
1189
+ //size_before from optimisation stats
1190
+ $size_before = $size_savings->size_before;
1191
+ $size_after = $size_savings->size_after;
1192
+ if ( 'full' == $size_k ) {
1193
+ //Check for savings from resizing for the original image
1194
+ if ( ! empty( $resize_savings['size_before'] ) && $resize_savings['size_before'] > $size_before ) {
1195
+ $size_before = $resize_savings['size_before'];
1196
+ }
1197
+ //Check for savings from resizing for the original image
1198
+ if ( ! empty( $resize_savings['size_after'] ) && $resize_savings['size_after'] < $size_after ) {
1199
+ $size_after = $resize_savings['size_after'];
1200
+ }
1201
+ }
1202
+
1203
+ //Add conversion savings, if available
1204
+ if ( ! empty( $conversion_savings['bytes'] ) ) {
1205
+ $smush_data['size_before'] += $conversion_savings['size_before'];
1206
+ $smush_data['size_after'] += $conversion_savings['size_after'];
1207
+ }
1208
+ }
1209
+
1210
+ //Resize Savings: If full image wasn't optimised, but resized, combine the stats
1211
+ if ( empty( $smush_stats['sizes']['full'] ) && ! empty( $resize_savings ) && $resize_savings['bytes'] > 0 ) {
1212
+ $smush_data['size_before'] += $resize_savings['size_before'];
1213
+ $smush_data['size_after'] += $resize_savings['size_after'];
1214
+ }
1215
+
1216
+ //Conversion Savings: If full image wasn't optimised, but Conversion saved few bytes
1217
+ if ( empty( $smush_stats['sizes']['full'] ) && ! empty( $conversion_savings['full'] ) && $conversion_savings['full']['bytes'] > 0 ) {
1218
+ $smush_data['size_before'] += $conversion_savings['full']['size_before'];
1219
+ $smush_data['size_after'] += $conversion_savings['full']['size_after'];
1220
+ }
1221
+ }
1222
+ }
1223
+ $smush_data['bytes'] = $smush_data['size_before'] - $smush_data['size_after'];
1224
+
1225
+ //Resize Savings
1226
+ $resize_savings = $wpsmush_db->resize_savings( false );
1227
+ $smush_data['resize_savings'] = ! empty( $resize_savings['bytes'] ) ? $resize_savings['bytes'] : 0;
1228
+
1229
+ //Conversion Savings
1230
+ $conversion_savings = $wpsmush_db->conversion_savings( false );
1231
+ $smush_data['conversion_savings'] = ! empty( $conversion_savings['bytes'] ) ? $conversion_savings['bytes'] : 0;
1232
+
1233
+ if ( $smush_data['size_before'] > 0 ) {
1234
+ $smush_data['percent'] = ( $smush_data['bytes'] / $smush_data['size_before'] ) * 100;
1235
+ }
1236
+
1237
+ //Round off precentage
1238
+ $smush_data['percent'] = round( $smush_data['percent'], 1 );
1239
+
1240
+ $smush_data['human'] = size_format( $smush_data['bytes'], 1 );
1241
+
1242
+ }
1243
+ //Update Cache
1244
+ update_option( 'smush_global_stats', $smush_data, false );
1245
+
1246
+ return $smush_data;
1247
+ }
1248
+
1249
+ /**
1250
+ * Returns Bulk smush button id and other details, as per if bulk request is already sent or not
1251
+ *
1252
+ * @param $resmush
1253
+ *
1254
+ * @return array
1255
+ */
1256
+
1257
+ private function button_state( $resmush ) {
1258
+ $button = array(
1259
+ 'cancel' => false,
1260
+ );
1261
+ if ( $this->validate_install() && $resmush ) {
1262
+
1263
+ $button['text'] = __( 'Bulk Smush Now', 'wp-smushit' );
1264
+ $button['class'] = 'wp-smush-button wp-smush-resmush wp-smush-all';
1265
 
1266
  } else {
1267
 
1290
  * @return string
1291
  */
1292
  function smush_status( $id ) {
1293
+ global $WpSmush;
1294
+
1295
+ //Show Temporary Status, For Async Optimisation, No Good workaround
1296
+ if ( ! get_transient( "wp-smush-restore-$id" ) && ! empty( $_POST['action'] ) && 'upload-attachment' == $_POST['action'] && $WpSmush->is_auto_smush_enabled() ) {
1297
+ // the status
1298
+ $status_txt = __( 'Smushing in progress..', 'wp-smushit' );
1299
+
1300
+ // we need to show the smush button
1301
+ $show_button = false;
1302
+
1303
+ // the button text
1304
+ $button_txt = __( 'Smush Now!', 'wp-smushit' );
1305
+
1306
+ return $this->column_html( $id, $status_txt, $button_txt, $show_button, true, false, true );
1307
+ }
1308
+ //Else Return the normal status
1309
  $response = trim( $this->set_status( $id, false ) );
1310
 
1311
  return $response;
1319
  *
1320
  * @return array
1321
  */
1322
+ function settings_link( $links, $url_only = false ) {
1323
 
1324
+ $settings_page = is_multisite() ? network_admin_url( 'settings.php?page=wp-smush' ) : admin_url( 'upload.php?page=wp-smush-bulk' );
1325
  $settings = '<a href="' . $settings_page . '">' . __( 'Settings', 'wp-smushit' ) . '</a>';
1326
 
1327
+ //Return Only settings page link
1328
+ if ( $url_only ) {
1329
+ return $settings_page;
1330
+ }
1331
+
1332
  //Added a fix for weird warning in multisite, "array_unshift() expects parameter 1 to be array, null given"
1333
  if ( ! empty( $links ) ) {
1334
  array_unshift( $links, $settings );
1345
  function smush_upgrade() {
1346
 
1347
  //Return, If a pro user, or not super admin, or don't have the admin privilleges
1348
+ if ( $this->validate_install() || ! current_user_can( 'edit_others_posts' ) || ! is_super_admin() ) {
1349
  return;
1350
  }
1351
 
1355
  }
1356
 
1357
  //Return if notice is already dismissed
1358
+ if ( get_option( 'wp-smush-hide_upgrade_notice' ) || get_site_option( 'wp-smush-hide_upgrade_notice' ) ) {
1359
  return;
1360
+ }
 
1361
 
1362
+ $install_type = get_site_option( 'wp-smush-install-type', false );
1363
 
1364
  if ( ! $install_type ) {
1365
  if ( $this->smushed_count > 0 ) {
1367
  } else {
1368
  $install_type = 'new';
1369
  }
1370
+ update_site_option( 'wp-smush-install-type', $install_type );
1371
  }
1372
 
 
 
 
1373
  //Container Header
 
1374
  echo $this->bulk_ui->installation_notice();
 
 
1375
  }
1376
 
1377
  /**
1387
 
1388
  $allowed_images = "( 'image/jpeg', 'image/jpg', 'image/png' )";
1389
 
1390
+ $limit = $this->query_limit();
 
1391
  $offset = 0;
1392
  $query_next = true;
1393
 
1407
 
1408
  //Update the offset
1409
  $offset += $limit;
1410
+ if ( !empty( $this->total_count ) && $this->total_count <= $offset ) {
1411
  $query_next = false;
1412
  } else if ( ! $results || empty( $results ) ) {
1413
  $query_next = false;
1417
  return $results;
1418
  }
1419
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1420
  /**
1421
  * Store a key/value to hide the smush features on bulk page
1422
  */
1423
  function dismiss_welcome_notice() {
1424
+ update_site_option( 'wp-smush-hide_smush_welcome', 1 );
1425
  wp_send_json_success();
1426
  }
1427
 
1428
  /**
1429
  * Store a key/value to hide the smush features on bulk page
1430
  */
1431
+ function dismiss_upgrade_notice( $ajax = true ) {
1432
+ update_site_option( 'wp-smush-hide_upgrade_notice', 1 );
1433
+ //No Need to send json response for other requests
1434
+ if ( $ajax ) {
1435
+ wp_send_json_success();
1436
+ }
1437
  }
1438
 
1439
  /**
1440
+ * Remove the Update info
1441
+ *
1442
+ * @param bool $remove_notice
1443
+ *
1444
  */
1445
+ function dismiss_update_info( $remove_notice = false ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1446
 
1447
+ //From URL arg
1448
+ if ( isset( $_GET['dismiss_smush_update_info'] ) && 1 == $_GET['dismiss_smush_update_info'] ) {
1449
+ $remove_notice = true;
 
 
 
 
 
 
 
1450
  }
1451
 
1452
+ //From Ajax
1453
+ if ( ! empty( $_REQUEST['action'] ) && 'dismiss_update_info' == $_REQUEST['action'] ) {
1454
+ $remove_notice = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1455
  }
 
 
 
 
 
1456
 
1457
+ //Update Db
1458
+ if ( $remove_notice ) {
1459
+ update_site_option( 'wp-smush-hide_update_info', 1 );
 
 
 
 
 
 
 
 
1460
  }
1461
+
1462
  }
1463
 
1464
  /**
1465
+ * Resmush the image
1466
  *
1467
  * @uses smush_single()
1468
  *
1508
  */
1509
  function scan_images() {
1510
 
1511
+ global $WpSmush, $wpsmushnextgenadmin, $wpsmush_db, $wpsmush_settings, $wpsmush_helper, $wpsmush_resize, $wpsmushit_admin;
1512
 
1513
  check_ajax_referer( 'save_wp_smush_options', 'wp_smush_options_nonce' );
1514
 
1515
  $resmush_list = array();
1516
 
1517
+ //Save settings only if networkwide settings are disabled
1518
+ if ( ( ! is_multisite() || ! $wpsmush_settings->is_network_enabled() ) && ( ! isset( $_REQUEST['process_settings'] ) || 'false' != $_REQUEST['process_settings'] ) ) {
1519
+ //Save Settings
1520
+ $wpsmush_settings->process_options();
1521
+ }
1522
+
1523
+ //If there aren't any images in the library, return the notice
1524
+ if ( 0 == $wpsmush_db->get_media_attachments( true ) ) {
1525
+ $notice = esc_html__( "We haven’t found any images in your media library yet so there’s no smushing to be done!", "wp-smushit" );
1526
+ $resp = '<div class="wp-smush-notice wp-smush-resmush-message" tabindex="0"><i class="dev-icon dev-icon-tick"></i> ' . $notice . '
1527
+ <i class="dev-icon dev-icon-cross"></i>
1528
+ </div>';
1529
+
1530
+ //Save serialized settings
1531
+ $this->save_serialized_settings();
1532
+
1533
+ wp_send_json_success( array(
1534
+ 'notice' => $resp,
1535
+ 'super_smush' => $WpSmush->lossy_enabled
1536
+ ) );
1537
+ }
1538
+
1539
  //Default Notice, to be displayed at the top of page
1540
  //Show a message, at the top
1541
+ $message = esc_html__( 'Yay! All images are optimized as per your current settings.', 'wp-smushit' );
1542
+ $resp = '<div class="wp-smush-notice wp-smush-resmush-message" tabindex="0"><i class="dev-icon dev-icon-tick"></i> ' . $message . '
1543
  <i class="dev-icon dev-icon-cross"></i>
1544
  </div>';
1545
 
1549
  //If a user manually runs smush check
1550
  $return_ui = isset( $_REQUEST['get_ui'] ) && 'true' == $_REQUEST['get_ui'] ? true : false;
1551
 
 
 
 
1552
  //Update the variables
1553
  $WpSmush->initialise();
1554
 
1557
  //Allow to smush Upfront images as well
1558
  $upfront_active = class_exists( 'Upfront' );
1559
 
1560
+ //Initialize Media Library Stats
1561
+ if ( 'nextgen' != $type && empty( $this->remaining_count ) ) {
1562
+ $this->setup_global_stats();
1563
+ }
1564
+
1565
+ //Intialize NextGen Stats
1566
+ if ( 'nextgen' == $type && is_object( $wpsmushnextgenadmin ) && empty( $wpsmushnextgenadmin->remaining_count ) ) {
1567
+ $wpsmushnextgenadmin->setup_stats();
1568
+ }
1569
+
1570
  $key = 'nextgen' == $type ? 'wp-smush-nextgen-resmush-list' : 'wp-smush-resmush-list';
1571
 
1572
+ $remaining_count = 'nextgen' == $type ? $wpsmushnextgenadmin->remaining_count : $this->remaining_count;
1573
+
1574
+ if ( 0 == $remaining_count && ! $WpSmush->lossy_enabled && ! $WpSmush->smush_original && $WpSmush->keep_exif && ! $upfront_active ) {
1575
  delete_option( $key );
1576
+ //Save serialized settings
1577
+ $this->save_serialized_settings();
1578
  wp_send_json_success( array( 'notice' => $resp ) );
1579
  }
1580
 
1585
  if ( 'nextgen' != $type ) {
1586
 
1587
  //Get list of Smushed images
1588
+ $attachments = ! empty( $this->smushed_attachments ) ? $this->smushed_attachments : $wpsmush_db->smushed_count( true );
1589
  } else {
1590
  global $wpsmushnextgenstats;
1591
 
1594
 
1595
  }
1596
 
1597
+ $image_count = $super_smushed_count = $smushed_count = 0;
1598
  //Check if any of the smushed image needs to be resmushed
1599
  if ( ! empty( $attachments ) && is_array( $attachments ) ) {
1600
+ $stats = array(
1601
+ 'size_before' => 0,
1602
+ 'size_after' => 0,
1603
+ 'savings_resize' => 0,
1604
+ 'savings_conversion' => 0
1605
+ );
1606
+
1607
+ // Initialize resize class.
1608
+ $wpsmush_resize->initialize();
1609
+
1610
  foreach ( $attachments as $attachment_k => $attachment ) {
1611
 
1612
+ //Skip if already in resmuhs list
1613
+ if ( ! empty( $wpsmushit_admin->resmush_ids ) && in_array( $attachment, $wpsmushit_admin->resmush_ids ) ) {
1614
+ continue;
1615
+ }
1616
+ $should_resmush = false;
1617
+
1618
  //For NextGen we get the metadata in the attachment data itself
1619
+ if ( is_array( $attachment ) && ! empty( $attachment['wp_smush'] ) ) {
1620
  $smush_data = $attachment['wp_smush'];
1621
  } else {
1622
  //Check the current settings, and smush data for the image
1623
  $smush_data = get_post_meta( $attachment, $this->smushed_meta_key, true );
1624
  }
1625
 
1626
+ //If the image is already smushed
1627
+ if ( is_array( $smush_data ) && ! empty( $smush_data['stats'] ) ) {
1628
 
1629
  //If we need to optmise losslessly, add to resmush list
1630
  $smush_lossy = $WpSmush->lossy_enabled && ! $smush_data['stats']['lossy'];
1636
  $smush_original = $WpSmush->smush_original && empty( $smush_data['sizes']['full'] );
1637
 
1638
  if ( $smush_lossy || $strip_exif || $smush_original ) {
1639
+ $should_resmush = true;
1640
+ }
1641
+
1642
+ //If Image needs to be resized
1643
+ if ( ! $should_resmush ) {
1644
+ $should_resmush = $wpsmush_resize->should_resize( $attachment );
1645
+ }
1646
+
1647
+ //If image can be converted
1648
+ if ( ! $should_resmush ) {
1649
+ global $wpsmush_pngjpg;
1650
+ $should_resmush = $wpsmush_pngjpg->can_be_converted( $attachment );
1651
+ }
1652
+
1653
+ //If the image needs to be resmushed add it to the list
1654
+ if ( $should_resmush ) {
1655
  $resmush_list[] = 'nextgen' == $type ? $attachment_k : $attachment;
1656
  continue;
1657
+ } else {
1658
+ if ( 'nextgen' != $type ) {
1659
+ $resize_savings = get_post_meta( $attachment, WP_SMUSH_PREFIX . 'resize_savings', true );
1660
+ $conversion_savings = $wpsmush_helper->get_pngjpg_savings( $attachment );
1661
+
1662
+ //Increase the smushed count
1663
+ $smushed_count += 1;
1664
+
1665
+ //Get the image count
1666
+ $image_count += ( ! empty( $smush_data['sizes'] ) && is_array( $smush_data['sizes'] ) ) ? sizeof( $smush_data['sizes'] ) : 0;
1667
+
1668
+ //If the image is in resmush list, and it was super smushed earlier
1669
+ $super_smushed_count += ( $smush_data['stats']['lossy'] ) ? 1 : 0;
1670
+
1671
+ //Add to the stats
1672
+ $stats['size_before'] += ! empty( $smush_data['stats'] ) ? $smush_data['stats']['size_before'] : 0;
1673
+ $stats['size_before'] += ! empty( $resize_savings['size_before'] ) ? $resize_savings['size_before'] : 0;
1674
+ $stats['size_before'] += ! empty( $conversion_savings['size_before'] ) ? $conversion_savings['size_before'] : 0;
1675
+
1676
+ $stats['size_after'] += ! empty( $smush_data['stats'] ) ? $smush_data['stats']['size_after'] : 0;
1677
+ $stats['size_after'] += ! empty( $resize_savings['size_after'] ) ? $resize_savings['size_after'] : 0;
1678
+ $stats['size_after'] += ! empty( $conversion_savings['size_after'] ) ? $conversion_savings['size_after'] : 0;
1679
+
1680
+ $stats['savings_resize'] += ! empty( $resize_savings ) ? $resize_savings['bytes'] : 0;
1681
+ $stats['savings_conversion'] += ! empty( $conversion_savings ) ? $conversion_savings['bytes'] : 0;
1682
+ }
1683
  }
1684
  }
1685
  }
1686
 
1687
  //Check for Upfront images that needs to be smushed
1688
  if ( $upfront_active && 'nextgen' != $type ) {
1689
+ $upfront_attachments = $wpsmush_db->get_upfront_images( $resmush_list );
1690
  if ( ! empty( $upfront_attachments ) && is_array( $upfront_attachments ) ) {
1691
  foreach ( $upfront_attachments as $u_attachment_id ) {
1692
  if ( ! in_array( $u_attachment_id, $resmush_list ) ) {
1709
  }//End Of Upfront loop
1710
 
1711
  //Store the resmush list in Options table
1712
+ update_option( $key, $resmush_list, false );
1713
+ }
1714
 
1715
+ //Delete resmush list if empty
1716
+ if ( empty( $resmush_list ) ) {
1717
+ //Delete the resmush list
1718
+ delete_option( $key );
1719
+ }
 
 
 
 
1720
 
1721
+ //Return the Remsmush list and UI to be appended to Bulk Smush UI
1722
+ if ( $return_ui ) {
1723
+ if ( 'nextgen' != $type ) {
1724
+ //Set the variables
1725
+ $this->resmush_ids = $resmush_list;
1726
 
1727
+ } else {
1728
+ //To avoid the php warning
1729
+ $wpsmushnextgenadmin->resmush_ids = $resmush_list;
1730
+ }
1731
+
1732
+ if ( ( $count = count( $resmush_list ) ) > 0 || $this->remaining_count > 0 ) {
1733
+
1734
+ if ( $count ) {
1735
  $show = true;
1736
 
 
 
 
1737
  $count += 'nextgen' == $type ? $wpsmushnextgenadmin->remaining_count : $this->remaining_count;
1738
 
1739
  $ajax_response = $this->bulk_ui->bulk_resmush_content( $count, $show );
1740
+ }
1741
+ }
1742
+ }
1743
+
1744
+ if ( ! empty( $resmush_list ) || $remaining_count > 0 ) {
1745
+ $message = sprintf( esc_html__( "You have images that need smushing. %sBulk smush now!%s", "wp-smushit" ), '<a href="#" class="wp-smush-trigger-bulk">', '</a>' );
1746
+ $resp = '<div class="wp-smush-notice wp-smush-resmush-message wp-smush-resmush-pending" tabindex="0"><i class="dev-icon dev-icon-tick"></i> ' . $message . '
1747
  <i class="dev-icon dev-icon-cross"></i>
1748
  </div>';
1749
+ }
1750
+
1751
+ //Append the directory smush stats
1752
+ $dir_smush_stats = get_option('dir_smush_stats');
1753
+ if ( ! empty( $dir_smush_stats ) && is_array( $dir_smush_stats ) ) {
1754
+
1755
+ if ( ! empty( $dir_smush_stats['dir_smush'] ) && ! empty( $dir_smush_stats['optimised'] ) ) {
1756
+ $dir_smush_stats = $dir_smush_stats['dir_smush'];
1757
+ $image_count += $dir_smush_stats['optimised'];
1758
+ }
1759
+
1760
+ //Add directory smush stats if not empty
1761
+ if ( ! empty( $dir_smush_stats['image_size'] ) && ! empty( $dir_smush_stats['orig_size'] ) ) {
1762
+ $stats['size_before'] += $dir_smush_stats['orig_size'];
1763
+ $stats['size_after'] += $dir_smush_stats['image_size'];
1764
  }
1765
  }
1766
 
1767
  //If there is a Ajax response return it, else return null
1768
+ $return = ! empty( $ajax_response ) ? array(
1769
+ "resmush_ids" => $resmush_list,
1770
+ "content" => $ajax_response,
1771
+ 'count_image' => $image_count,
1772
+ 'count_supersmushed' => $super_smushed_count,
1773
+ 'count_smushed' => $smushed_count,
1774
+ 'size_before' => $stats['size_before'],
1775
+ 'size_after' => $stats['size_after'],
1776
+ 'savings_resize' => $stats['savings_resize'],
1777
+ 'savings_conversion' => $stats['savings_conversion']
1778
+ ) : array();
1779
+
1780
+ //Include the count
1781
+ if ( ! empty( $count ) && $count ) {
1782
+ $return['count'] = $count;
1783
+ }
1784
+
1785
+ $return['notice'] = $resp;
1786
+ $return['super_smush'] = $WpSmush->lossy_enabled;
1787
+ if ( $WpSmush->lossy_enabled && 'nextgen' == $type ) {
1788
+ $ss_count = $wpsmush_db->super_smushed_count( 'nextgen', $wpsmushnextgenstats->get_ngg_images( 'smushed' ) );
1789
+ $return['super_smush_stats'] = sprintf( '<strong><span class="smushed-count">%d</span>/%d</strong>', $ss_count, $wpsmushnextgenadmin->total_count );
1790
+ }
1791
+
1792
+ //Save serialized settings
1793
+ $this->save_serialized_settings();
1794
 
1795
  wp_send_json_success( $return );
1796
 
1820
  //Delete resmush list
1821
  delete_option( $mkey );
1822
  } else {
1823
+ update_option( $mkey, $resmush_list, false );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1824
  }
1825
  }
1826
 
1851
  }
1852
  }
1853
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1854
  /**
1855
  * Add/Remove image id from Super Smushed images count
1856
  *
1891
  //Add the timestamp
1892
  $super_smushed['timestamp'] = current_time( 'timestamp' );
1893
 
1894
+ update_option( $key, $super_smushed, false );
1895
 
1896
  //Update to database
1897
  return true;
1933
 
1934
  /**
1935
  * Delete the resmush list for Nextgen or the Media Library
1936
+ *
1937
+ * Return Stats in ajax response
1938
+ *
1939
  */
1940
  function delete_resmush_list() {
1941
 
1942
+ global $wpsmush_db;
1943
+ $stats = array();
1944
+
1945
+ $key = ! empty( $_POST['type'] ) && 'nextgen' == $_POST['type'] ? 'wp-smush-nextgen-resmush-list' : 'wp-smush-resmush-list';
1946
+ if ( 'nextgen' != $_POST['type'] ) {
1947
+ $resmush_list = get_option( $key );
1948
+ if ( ! empty( $resmush_list ) && is_array( $resmush_list ) ) {
1949
+ $stats = $wpsmush_db->get_savings_for_attachments( $resmush_list );
1950
+ }
1951
+ }
1952
+
1953
  //Delete the resmush list
1954
  delete_option( $key );
1955
+ wp_send_json_success( array( 'stats' => $stats ) );
1956
  }
1957
 
1958
  /**
1959
+ * Allows to bulk restore the images, if there is any backup for them
1960
+ */
1961
+ function bulk_restore() {
1962
+ global $wpsmush_db, $wpsmush_backup;
1963
+ $smushed_attachments = ! empty( $this->smushed_attachments ) ? $this->smushed_attachments : $wpsmush_db->smushed_count( true );
1964
+ foreach ( $smushed_attachments as $attachment ) {
1965
+ $wpsmush_backup->restore_image( $attachment->attachment_id, false );
1966
+ }
1967
+ }
1968
+
1969
+ /**
1970
+ * Loads the Shared UI to on all admin pages
1971
+ *
1972
+ * @param $current_page
1973
+ */
1974
+ function load_shared_ui( $current_page ) {
1975
+ //If class method exists, load shared UI
1976
+ if ( class_exists( 'WDEV_Plugin_Ui' ) ) {
1977
+
1978
+ if ( method_exists( 'WDEV_Plugin_Ui', 'load' ) && in_array( $current_page, $this->plugin_pages ) ) {
1979
+
1980
+ //Load Shared UI
1981
+ WDEV_Plugin_Ui::load( WP_SMUSH_URL . 'assets/shared-ui/', false );
1982
+ }
1983
+ }
1984
+ }
1985
+
1986
+ /** Get the Maximum Width and Height settings for WrodPress
1987
  *
1988
+ * @return array, Array of Max. Width and Height for image
1989
  *
1990
  */
1991
+ function get_max_image_dimensions() {
1992
+ global $_wp_additional_image_sizes;
1993
+
1994
+ $width = $height = 0;
1995
+ $limit = 9999; //Post-thumbnail
1996
+
1997
+ $image_sizes = get_intermediate_image_sizes();
1998
+
1999
+ // Create the full array with sizes and crop info
2000
+ foreach ( $image_sizes as $size ) {
2001
+ if ( in_array( $size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) ) {
2002
+ $size_width = get_option( "{$size}_size_w" );
2003
+ $size_height = get_option( "{$size}_size_h" );
2004
+ } elseif ( isset( $_wp_additional_image_sizes[ $size ] ) ) {
2005
+ $size_width = $_wp_additional_image_sizes[ $size ]['width'];
2006
+ $size_height = $_wp_additional_image_sizes[ $size ]['height'];
2007
+ }
2008
+
2009
+ //Skip if no width and height
2010
+ if ( ! isset( $size_width, $size_height ) ) {
2011
+ continue;
2012
+ }
2013
+
2014
+ //If within te limit, check for a max value
2015
+ if ( $size_width <= $limit ) {
2016
+ $width = max( $width, $size_width );
2017
+ }
2018
+
2019
+ if ( $size_height <= $limit ) {
2020
+ $height = max( $height, $size_height );
2021
  }
2022
  }
2023
+
2024
+ return array(
2025
+ 'width' => $width,
2026
+ 'height' => $height
2027
+ );
2028
+ }
2029
+
2030
+ /**
2031
+ * Perform the resize operation for the image
2032
+ *
2033
+ * @param $attachment_id
2034
+ *
2035
+ * @param $meta
2036
+ *
2037
+ * @return mixed
2038
+ */
2039
+ function resize_image( $attachment_id, $meta ) {
2040
+ if ( empty( $attachment_id ) || empty( $meta ) ) {
2041
+ return $meta;
2042
+ }
2043
+ global $wpsmush_resize;
2044
+
2045
+ return $wpsmush_resize->auto_resize( $attachment_id, $meta );
2046
+ }
2047
+
2048
+ /**
2049
+ * Limit for all the queries
2050
+ *
2051
+ * @return int|mixed|void
2052
+ *
2053
+ */
2054
+ function query_limit() {
2055
+ $limit = apply_filters( 'wp_smush_query_limit', 2000 );
2056
+ $limit = !empty( $this->total_count ) && $limit > $this->total_count ? $this->total_count : $limit;
2057
+ $limit = intval( $limit );
2058
+
2059
+ return $limit;
2060
+ }
2061
+
2062
+ /**
2063
+ * Filter the number of results fetched at once for NextGen queries
2064
+ *
2065
+ * @return int|mixed|void
2066
+ *
2067
+ */
2068
+ function nextgen_query_limit() {
2069
+ $limit = apply_filters( 'wp_smush_nextgen_query_limit', 1000 );
2070
+ $limit = intval( $limit );
2071
+
2072
+ return $limit;
2073
+ }
2074
+
2075
+ /**
2076
+ * Show Update info in admin Notice
2077
+ *
2078
+ */
2079
+ function smush_updated() {
2080
+ //@todo: Update Smush Update Notice for next release
2081
+ //Make sure to not display this message for next release
2082
+ $plugin_data = get_plugin_data( WP_SMUSH_DIR . 'wp-smush.php', false, false );
2083
+ $version = ! empty( $plugin_data['Version'] ) ? $plugin_data['Version'] : '';
2084
+
2085
+ //If Versions Do not match
2086
+ if ( empty( $version ) || $version != WP_SMUSH_VERSION ) {
2087
+ return true;
2088
+ }
2089
+
2090
+ //Do not display it for other users
2091
+ if ( ! is_super_admin() || ! current_user_can( 'manage_options' ) ) {
2092
+ return true;
2093
+ }
2094
+
2095
+ //If dismissed, Delete the option on Plugin Activation, For alter releases
2096
+ if ( 1 == get_site_option( 'wp-smush-hide_update_info' ) ) {
2097
+ return true;
2098
+ }
2099
+
2100
+ //Get Plugin dir, Return if it's WP Smush Pro installation
2101
+ $dir_path = get_plugin_dir();
2102
+ if ( ! empty( $dir_path ) && strpos( $dir_path, 'wp-smush-pro' ) !== false ) {
2103
+ return true;
2104
+ }
2105
+
2106
+ //Do not display the notice on Bulk Smush Screen
2107
+ global $current_screen;
2108
+ if ( ! empty( $current_screen->base ) && ( 'media_page_wp-smush-bulk' == $current_screen->base || 'gallery_page_wp-smush-nextgen-bulk' == $current_screen->base || 'settings_page_wp-smush-network' == $current_screen->base ) ) {
2109
+ return true;
2110
+ }
2111
+
2112
+ $upgrade_url = add_query_arg(
2113
+ array(
2114
+ 'utm_source' => 'Smush-Free',
2115
+ 'utm_medium' => 'Banner',
2116
+ 'utm_campaign' => 'now-with-async'
2117
  ),
2118
+ $this->upgrade_url
 
2119
  );
2120
+ $settings_link = is_multisite() ? network_admin_url( 'settings.php?page=wp-smush' ) : admin_url( 'upload.php?page=wp-smush-bulk' );
 
2121
 
2122
+ $settings_link = '<a href="' . $settings_link . '" title="' . esc_html__( "Review your setting now.", "wp-smushit" ) . '">';
2123
+ $upgrade_link = '<a href="' . esc_url( $upgrade_url ) . '" title="' . esc_html__( "WP Smush Pro", "wp-smushit" ) . '">';
2124
+ $message_s = sprintf( esc_html__( "Welcome to the newest version of WP Smush! In this update we've added the ability to bulk smush images in directories outside your uploads folder.", 'wp-smushit' ), WP_SMUSH_VERSION, '<strong>', '</strong>' );
2125
 
2126
+ //Message for network admin
2127
+ $message_s .= is_multisite() ? sprintf( esc_html__( " And as a multisite user, you can manage %sSmush settings%s globally across all sites!", 'wp-smushit' ), $settings_link, '</a>' ) : '';
2128
 
2129
+ //Upgrade link for free users
2130
+ $message_s .= ! $this->validate_install() ? sprintf( esc_html__( " %sFind out more here >>%s", "wp-smushit" ), $upgrade_link, '</a>' ) : '';
2131
+ ?>
2132
+ <div class="notice notice-info is-dismissible wp-smush-update-info">
2133
+ <p><?php echo $message_s; ?></p>
2134
+ </div><?php
2135
+ //Notice JS
2136
+ wp_enqueue_script('wp-smushit-notice-js', '', array(), '', true );
2137
+ }
2138
 
2139
+ /**
2140
+ * Check whether to skip a specific image size or not
2141
+ *
2142
+ * @param string $size Registered image size
2143
+ *
2144
+ * @return bool true/false Whether to skip the image size or not
2145
+ *
2146
+ */
2147
+ function skip_image_size ( $size = '' ) {
2148
+ global $wpsmush_settings;
2149
+
2150
+ //No image size specified, Don't skip
2151
+ if( empty( $size ) ) {
2152
+ return false;
2153
+ }
2154
+
2155
+ $image_sizes = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX.'image_sizes' );
2156
+
2157
+ //If Images sizes aren't set, don't skip any of the image size
2158
+ if( false === $image_sizes ) {
2159
+ return false;
2160
+ }
2161
+
2162
+ //Check if the size is in the smush list
2163
+ if( is_array( $image_sizes ) && !in_array( $size, $image_sizes ) ) {
2164
+ return true;
2165
+ }
2166
+
2167
+ }
2168
 
2169
+ /**
2170
+ * Get registered image sizes with dimension
2171
+ *
2172
+ */
2173
+ function image_dimensions() {
2174
+ global $_wp_additional_image_sizes;
2175
+ $additional_sizes = get_intermediate_image_sizes();
2176
+ $sizes = array();
2177
+
2178
+ // Create the full array with sizes and crop info
2179
+ foreach( $additional_sizes as $_size ) {
2180
+ if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
2181
+ $sizes[ $_size ]['width'] = get_option( $_size . '_size_w' );
2182
+ $sizes[ $_size ]['height'] = get_option( $_size . '_size_h' );
2183
+ $sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
2184
+ } elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
2185
+ $sizes[ $_size ] = array(
2186
+ 'width' => $_wp_additional_image_sizes[ $_size ]['width'],
2187
+ 'height' => $_wp_additional_image_sizes[ $_size ]['height'],
2188
+ 'crop' => $_wp_additional_image_sizes[ $_size ]['crop']
2189
+ );
2190
  }
2191
  }
2192
+ //Medium Large
2193
+ if ( !isset( $sizes['medium_large'] ) || empty( $sizes['medium_large'] ) ) {
2194
+ $width = intval( get_option( 'medium_large_size_w' ) );
2195
+ $height = intval( get_option( 'medium_large_size_h' ) );
2196
+
2197
+ $sizes['medium_large'] = array(
2198
+ 'width' => $width,
2199
+ 'height' => $height
2200
+ );
2201
+ }
2202
+
2203
+ return $sizes;
2204
 
 
2205
  }
2206
 
2207
  /**
2208
+ * Prints the Membership Validation issue notice
2209
+ *
2210
  */
2211
+ function media_library_membership_notice() {
2212
+
2213
+ //No need to print it for free version
2214
+ if( !$this->validate_install() ) {
2215
+ return;
2216
+ }
2217
+ //Show it on Media Library page only
2218
+ $screen = get_current_screen();
2219
+ $screen_id = !empty( $screen ) ? $screen->id : '';
2220
+ //Do not show notice anywhere else
2221
+ if( empty( $screen ) || 'upload' != $screen_id ) {
2222
+ return;
2223
  }
2224
+
2225
+ echo $this->bulk_ui->get_user_validation_message( $notice = true );
2226
  }
2227
 
2228
  /**
2229
+ * Save settings, Used for networkwide option
 
2230
  */
2231
+ function save_settings() {
2232
+ //Validate Ajax request
2233
+ check_ajax_referer( 'save_wp_smush_options', 'nonce' );
2234
 
2235
+ global $wpsmush_settings;
2236
+ //Save Settings
2237
+ $wpsmush_settings->process_options();
2238
+ wp_send_json_success();
2239
 
2240
+ }
 
2241
 
2242
+ /**
2243
+ * Returns a serialised string of current settings
2244
+ *
2245
+ * @return Serialised string of settings
2246
+ *
2247
+ */
2248
+ function get_serialised_settings() {
2249
+ global $wpsmush_settings;
2250
+ $settings = array();
2251
+ foreach ( $this->settings as $key => $val ) {
2252
+ $settings[ $key ] = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . $key );
2253
+ }
2254
+ $settings = maybe_serialize( $settings );
2255
 
2256
+ return $settings;
2257
+ }
 
 
 
2258
 
2259
+ /**
2260
+ * Stores the latest settings in serialised form in DB For the current settings
2261
+ *
2262
+ * No need to store the serialised settings, if network wide settings is disabled
2263
+ * because the site would run the scan when settings are saved
2264
+ *
2265
+ */
2266
+ function save_serialized_settings() {
2267
+ //Return -> Single Site | If network settings page | Networkwide Settings Disabled
2268
+ if ( ! is_multisite() || is_network_admin() || ! get_site_option( WP_SMUSH_PREFIX . 'networkwide' ) ) {
2269
+ return;
2270
  }
2271
+ global $wpsmush_settings;
2272
+ $c_settings = $this->get_serialised_settings();
2273
+ $wpsmush_settings->update_setting( WP_SMUSH_PREFIX . 'last_settings', $c_settings );
2274
+ }
2275
+
2276
+ /**
2277
+ * Allows to filter the error message sent to the user
2278
+ *
2279
+ * @param string $error
2280
+ * @param string $attachment_id
2281
+ *
2282
+ * @return mixed|null|string|void
2283
+ */
2284
+ function filter_error( $error = '', $attachment_id = '' ) {
2285
+ if ( empty( $error ) ) {
2286
+ return null;
2287
+ }
2288
+ /**
2289
+ * Used internally to modify the error message
2290
+ *
2291
+ */
2292
+ $error = apply_filters( 'wp_smush_error', $error, $attachment_id );
2293
+
2294
+ return $error;
2295
  }
2296
 
2297
  }
2298
 
2299
  global $wpsmushit_admin;
2300
  $wpsmushit_admin = new WpSmushitAdmin();
2301
+ }
lib/class-wp-smush-async.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Smush
4
+ * @subpackage Admin
5
+ * @since 2.5
6
+ *
7
+ * @author Umesh Kumar <umesh@incsub.com>
8
+ *
9
+ * @copyright (c) 2016, Incsub (http://incsub.com)
10
+ */
11
+ require_once 'wp-async-task-smush.php';
12
+
13
+ if ( ! class_exists( 'WpSmushAsync' ) ) {
14
+
15
+ class WpSmushAsync extends WP_Async_Task_Smush {
16
+
17
+ protected $argument_count = 2;
18
+ protected $priority = 12;
19
+ /**
20
+ * Whenever a attachment metadata is generated
21
+ * Had to be hooked on generate and not update, else it goes in infinite loop
22
+ *
23
+ * @var string
24
+ */
25
+ protected $action = 'wp_generate_attachment_metadata';
26
+
27
+ /**
28
+ * Prepare data for the asynchronous request
29
+ *
30
+ * @throws Exception If for any reason the request should not happen
31
+ *
32
+ * @param array $data An array of data sent to the hook
33
+ *
34
+ * @return array
35
+ */
36
+ protected function prepare_data( $data ) {
37
+ //We don't have the data, bail out
38
+ if ( empty( $data ) ) {
39
+ return $data;
40
+ }
41
+
42
+ //Return a associative array
43
+ $image_meta = array();
44
+ $image_meta['metadata'] = ! empty( $data[0] ) ? $data[0] : '';
45
+ $image_meta['id'] = ! empty( $data[1] ) ? $data[1] : '';
46
+
47
+ return $image_meta;
48
+ }
49
+
50
+ /**
51
+ * Run the async task action
52
+ * @todo: See if auto smush is enabled or not
53
+ * @todo: Check if async is enabled or not
54
+ */
55
+ protected function run_action() {
56
+
57
+ $metadata = ! empty( $_POST['metadata'] ) ? $_POST['metadata'] : '';
58
+ $id = ! empty( $_POST['id'] ) ? $_POST['id'] : '';
59
+
60
+ //Get metadata from $_POST
61
+ if ( ! empty( $metadata ) && wp_attachment_is_image( $id ) ) {
62
+ // Allow the Asynchronous task to run
63
+ do_action( "wp_async_$this->action", $id );
64
+ }
65
+ }
66
+
67
+ }
68
+
69
+ class WpSmushEditorAsync extends WP_Async_Task_Smush {
70
+
71
+ protected $argument_count = 2;
72
+ protected $priority = 12;
73
+ /**
74
+ * Whenever a attachment metadata is generated
75
+ * Had to be hooked on generate and not update, else it goes in infinite loop
76
+ *
77
+ * @var string
78
+ */
79
+ protected $action = 'wp_save_image_editor_file';
80
+
81
+ /**
82
+ * Prepare data for the asynchronous request
83
+ *
84
+ * @throws Exception If for any reason the request should not happen
85
+ *
86
+ * @param array $data An array of data sent to the hook
87
+ *
88
+ * @return array
89
+ */
90
+ protected function prepare_data( $data ) {
91
+ //Store the post data in $data variable
92
+ if ( ! empty( $data ) ) {
93
+ $data = array_merge( $data, $_POST );
94
+ }
95
+
96
+ //Store the image path
97
+ $data['filepath'] = !empty( $data[1] ) ? $data[1] : '';
98
+ $data['wp-action'] = !empty( $data['action'] ) ? $data['action'] : '';
99
+ unset( $data['action'], $data[1] );
100
+
101
+ return $data;
102
+ }
103
+
104
+ /**
105
+ * Run the async task action
106
+ * @todo: Add a check for image
107
+ * @todo: See if auto smush is enabled or not
108
+ * @todo: Check if async is enabled or not
109
+ */
110
+ protected function run_action() {
111
+
112
+ if ( isset( $_POST['wp-action'], $_POST['do'], $_POST['postid'] )
113
+ && 'image-editor' === $_POST['wp-action']
114
+ && check_ajax_referer( 'image_editor-' . $_POST['postid'] )
115
+ && 'open' != $_POST['do']
116
+ ) {
117
+ $postid = ! empty( $_POST['postid'] ) ? $_POST['postid'] : '';
118
+ // Allow the Asynchronous task to run
119
+ do_action( "wp_async_$this->action", $postid, $_POST );
120
+ }
121
+ }
122
+
123
+ }
124
+ }
lib/class-wp-smush-backup.php ADDED
@@ -0,0 +1,391 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! class_exists( 'WpSmushBackup' ) ) {
4
+
5
+ class WpSmushBackup {
6
+
7
+ /**
8
+ * Whether to backp images or not
9
+ * @var bool
10
+ */
11
+ var $backup_enabled = false;
12
+
13
+ /**
14
+ * Key for storing file path for image backup
15
+ *
16
+ * @var string
17
+ */
18
+ var $backup_key = 'smush-full';
19
+
20
+ /**
21
+ * Constructor
22
+ */
23
+ function __construct() {
24
+ //Initialize Variables and perform other operations
25
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
26
+
27
+ //Handle Restore operation
28
+ add_action( 'wp_ajax_smush_restore_image', array( $this, 'restore_image' ) );
29
+ }
30
+
31
+ function admin_init() {
32
+
33
+ $this->initialize();
34
+
35
+ }
36
+
37
+ function initialize() {
38
+
39
+ global $wpsmush_settings;
40
+
41
+ //Whether backup is enabled or not
42
+ $this->backup_enabled = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'backup' );
43
+ }
44
+
45
+ /**
46
+ * Creates a backup of file for the given attachment path
47
+ *
48
+ * Checks if there is a existing backup, else create one
49
+ *
50
+ * @param string $file_path
51
+ * @param string $backup_path
52
+ * @param string $attachment_id
53
+ *
54
+ * @return string
55
+ */
56
+ function create_backup( $file_path = '', $backup_path = '', $attachment_id = '' ) {
57
+ global $WpSmush, $wpsmush_pngjpg;
58
+
59
+ $copied = false;
60
+
61
+ if ( empty( $file_path ) ) {
62
+ return '';
63
+ }
64
+
65
+ //Return file path if backup is disabled
66
+ if ( ! $this->backup_enabled || ! $WpSmush->validate_install() ) {
67
+ return $file_path;
68
+ }
69
+
70
+ //Get a backup path if empty
71
+ if ( empty( $backup_path ) ) {
72
+ $backup_path = $WpSmush->get_image_backup_path( $file_path );
73
+ }
74
+
75
+ //If we don't have any backup path yet, bail!
76
+ if ( empty( $backup_path ) ) {
77
+ return $file_path;
78
+ }
79
+
80
+ $attachment_id = ! empty( $WpSmush->attachment_id ) ? $WpSmush->attachment_id : $attachment_id;
81
+ if ( ! empty( $attachment_id ) && $wpsmush_pngjpg->is_converted( $attachment_id ) ) {
82
+ //No need to create a backup, we already have one if enabled
83
+ return $file_path;
84
+ }
85
+
86
+ //Check for backup from other plugins, like nextgen, if it doesn't exists, create our own
87
+ if ( ! file_exists( $backup_path ) ) {
88
+ $copied = @copy( $file_path, $backup_path );
89
+ }
90
+ //Store the backup path in image backup sizes
91
+ if ( $copied ) {
92
+ $this->add_to_image_backup_sizes( $attachment_id, $backup_path );
93
+ }
94
+
95
+ }
96
+
97
+ /**
98
+ * Store new backup path for the image
99
+ *
100
+ * @param string $attachment_id
101
+ * @param string $backup_path
102
+ * @param string $backup_key
103
+ *
104
+ * @return bool|int|void
105
+ */
106
+ function add_to_image_backup_sizes( $attachment_id = '', $backup_path = '', $backup_key = '' ) {
107
+ if ( empty( $attachment_id ) || empty( $backup_path ) ) {
108
+ return;
109
+ }
110
+ //Get the Existing backup sizes
111
+ $backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
112
+ if ( empty( $backup_sizes ) ) {
113
+ $backup_sizes = array();
114
+ }
115
+
116
+ //Return if backup file doesn't exists
117
+ if( !file_exists( $backup_path ) ) {
118
+ return;
119
+ }
120
+ list( $width, $height ) = getimagesize( $backup_path );
121
+ //Store our backup Path
122
+ $backup_key = empty( $backup_key ) ? $this->backup_key : $backup_key;
123
+ $backup_sizes[ $backup_key ] = array(
124
+ 'file' => wp_basename( $backup_path ),
125
+ 'width' => $width,
126
+ 'height' => $height
127
+ );
128
+
129
+ return update_post_meta( $attachment_id, '_wp_attachment_backup_sizes', $backup_sizes );
130
+ }
131
+
132
+ /**
133
+ * Restore the image and its sizes from backup
134
+ *
135
+ * @param string $attachment
136
+ * @param bool $resp
137
+ *
138
+ * @return bool
139
+ */
140
+ function restore_image( $attachment = '', $resp = true ) {
141
+ global $WpSmush, $wpsmush_helper;
142
+ //If no attachment id is provided, check $_POST variable for attachment_id
143
+ if ( empty( $attachment ) ) {
144
+ //Check Empty fields
145
+ if ( empty( $_POST['attachment_id'] ) || empty( $_POST['_nonce'] ) ) {
146
+ wp_send_json_error( array(
147
+ 'error' => 'empty_fields',
148
+ 'message' => esc_html__( "Error in processing restore action, Fields empty.", "wp-smushit" )
149
+ ) );
150
+ }
151
+ //Check Nonce
152
+ if ( ! wp_verify_nonce( $_POST['_nonce'], "wp-smush-restore-" . $_POST['attachment_id'] ) ) {
153
+ wp_send_json_error( array(
154
+ 'error' => 'empty_fields',
155
+ 'message' => esc_html__( "Image not restored, Nonce verification failed.", "wp-smushit" )
156
+ ) );
157
+ }
158
+ }
159
+
160
+ //Store the restore success/failure for Full size image
161
+ $restored = $restore_png = false;
162
+
163
+ //Process Now
164
+ $attachment_id = empty( $attachment ) ? absint( (int) $_POST['attachment_id'] ) : $attachment;
165
+
166
+ //Set a transient to avoid the smush-restore-smush loop
167
+ set_transient( "wp-smush-restore-$attachment_id", true, 60 );
168
+
169
+ //Restore Full size -> get other image sizes -> restore other images
170
+
171
+ //Get the Original Path
172
+ $file_path = $wpsmush_helper->get_attached_file( $attachment_id );
173
+
174
+ //Get the backup path
175
+ $backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
176
+
177
+ //If there are
178
+ if ( ! empty( $backup_sizes ) ) {
179
+
180
+ // 1. Check if the image was converted from PNG->JPG, Get the corresponding backup path
181
+ if ( ! empty( $backup_sizes['smush_png_path'] ) ) {
182
+ $backup_path = $backup_sizes['smush_png_path'];
183
+ //If we don't have the backup path in backup sizes, Check for legacy original file path
184
+ if ( empty( $backup_path ) ) {
185
+ //Check if it's a jpg converted from png, and restore the jpg to png
186
+ $original_file = get_post_meta( $attachment_id, WP_SMUSH_PREFIX . 'original_file', true );
187
+ $backup_path = $WpSmush->original_file( $original_file );
188
+ }
189
+
190
+ //If we have a backup path for PNG file, use restore_png()
191
+ if ( ! empty( $backup_path ) ) {
192
+ $restore_png = true;
193
+ }
194
+ }
195
+
196
+ // 2. If we don't have a backup path from PNG->JPG, check for normal smush backup path
197
+ if ( empty( $backup_path ) ) {
198
+
199
+ if ( ! empty( $backup_sizes[ $this->backup_key ] ) ) {
200
+ $backup_path = $backup_sizes[ $this->backup_key ];
201
+ } else {
202
+ //If we don't have a backup path, check for legacy backup naming convention
203
+ $backup_path = $WpSmush->get_image_backup_path( $file_path );
204
+ }
205
+ }
206
+ $backup_path = is_array( $backup_path ) && !empty( $backup_path['file'] ) ? $backup_path['file'] : $backup_path;
207
+ }
208
+
209
+ $backup_full_path = str_replace( wp_basename( $file_path ), wp_basename( $backup_path ), $file_path );
210
+
211
+ //Finally, if we have the backup path, perform the restore operation
212
+ if ( ! empty( $backup_full_path ) ) {
213
+
214
+ /**
215
+ * Allows S3 to hook, check and download the file
216
+ */
217
+ do_action('smush_file_exists', $backup_full_path, $attachment_id, array() );
218
+
219
+ if ( $restore_png ) {
220
+ //restore PNG full size and all other image sizes
221
+ $restored = $this->restore_png( $attachment_id, $backup_full_path, $file_path );
222
+
223
+ //JPG file is already deleted, Update backup sizes
224
+ if ( $restored ) {
225
+ $this->remove_from_backup_sizes( $attachment_id, 'smush_png_path', $backup_sizes );
226
+ }
227
+ } else {
228
+ //If file exists, corresponding to our backup path
229
+ //Restore
230
+ $restored = @copy( $backup_full_path, $file_path );
231
+
232
+ //Remove the backup, if we were able to restore the image
233
+ if ( $restored ) {
234
+
235
+ //Update backup sizes
236
+ $this->remove_from_backup_sizes( $attachment_id, '', $backup_sizes );
237
+
238
+ //Delete the backup
239
+ $this->remove_backup( $attachment_id, $backup_full_path );
240
+ }
241
+ }
242
+ } elseif ( file_exists( $file_path . '_backup' ) ) {
243
+ // Try to restore from other backups, if any
244
+ $restored = @copy( $file_path . '_backup', $file_path );
245
+ }
246
+
247
+ //Generate all other image size, and update attachment metadata
248
+ $metadata = wp_generate_attachment_metadata( $attachment_id, $file_path );
249
+
250
+ //Update metadata to db if it was successfully generated
251
+ if ( ! empty( $metadata ) && ! is_wp_error( $metadata ) ) {
252
+ wp_update_attachment_metadata( $attachment_id, $metadata );
253
+ }
254
+
255
+ //If any of the image is restored, we count it as success
256
+ if ( $restored ) {
257
+
258
+ //Remove the Meta, And send json success
259
+ delete_post_meta( $attachment_id, $WpSmush->smushed_meta_key );
260
+
261
+ //Remove PNG to JPG conversion savings
262
+ delete_post_meta( $attachment_id, WP_SMUSH_PREFIX . 'pngjpg_savings' );
263
+
264
+ //Remove Original File
265
+ delete_post_meta( $attachment_id, WP_SMUSH_PREFIX . 'original_file' );
266
+
267
+ //Get the Button html without wrapper
268
+ $button_html = $WpSmush->set_status( $attachment_id, false, false, false );
269
+
270
+ //Remove the transient
271
+ delete_transient( "wp-smush-restore-$attachment_id" );
272
+
273
+ if ( $resp ) {
274
+ wp_send_json_success( array( 'button' => $button_html ) );
275
+ } else {
276
+ return true;
277
+ }
278
+ }
279
+ //Remove the transient
280
+ delete_transient( "wp-smush-restore-$attachment_id" );
281
+ if ( $resp ) {
282
+ wp_send_json_error( array( 'message' => '<div class="wp-smush-error">' . __( "Unable to restore image", "wp-smushit" ) . '</div>' ) );
283
+ }
284
+
285
+ return false;
286
+ }
287
+
288
+
289
+ /**
290
+ *
291
+ * @param string $image_id
292
+ * @param string $original_file
293
+ * @param string $file_path
294
+ *
295
+ * @return bool
296
+ */
297
+ function restore_png( $image_id = '', $original_file = '', $file_path = '' ) {
298
+
299
+ global $WpSmush, $wpsmush_pngjpg;
300
+
301
+ //If we don't have attachment id, there is nothing we can do
302
+ if ( empty ( $image_id ) ) {
303
+ return false;
304
+ }
305
+
306
+ $meta = '';
307
+
308
+ //Else get the Attachment details
309
+ /**
310
+ * For Full Size
311
+ * 1. Get the original file path
312
+ * 2. Update the attachment metadata and all other meta details
313
+ * 3. Delete the JPEG
314
+ * 4. And we're done
315
+ * 5. Add a action after updating the URLs, that'd allow the users to perform a additional search, replace action
316
+ **/
317
+ if ( empty( $original_file ) ) {
318
+ $original_file = get_post_meta( $image_id, WP_SMUSH_PREFIX . 'original_file', true );
319
+ }
320
+ $original_file_path = $WpSmush->original_file( $original_file );
321
+ if ( file_exists( $original_file_path ) ) {
322
+ //Update the path details in meta and attached file, replace the image
323
+ $meta = $wpsmush_pngjpg->update_image_path( $image_id, $file_path, $original_file_path, $meta, 'full', 'restore' );
324
+
325
+ //Unlink JPG
326
+ if ( ! empty( $meta['file'] ) && $original_file == $meta['file'] ) {
327
+ @unlink( $file_path );
328
+ }
329
+
330
+ $meta = wp_generate_attachment_metadata( $image_id, $original_file_path );
331
+
332
+ /**
333
+ * Perform a action after the image URL is updated in post content
334
+ */
335
+ do_action( 'wp_smush_image_url_updated', $image_id, $file_path, $original_file );
336
+ }
337
+ //Update Meta
338
+ if ( ! empty( $meta ) ) {
339
+ //Remove Smushing, while attachment data is updated for the image
340
+ remove_filter( 'wp_update_attachment_metadata', array( $WpSmush, 'smush_image' ), 15 );
341
+ wp_update_attachment_metadata( $image_id, $meta );
342
+
343
+ return true;
344
+ }
345
+
346
+ return false;
347
+
348
+ }
349
+
350
+ /**
351
+ * Remove the backup path for a give attachment id and path
352
+ *
353
+ * @param string $attachment_id
354
+ *
355
+ * @param string $path
356
+ *
357
+ *
358
+ */
359
+ function remove_backup( $attachment_id = '', $path = '' ) {
360
+ @unlink( $path );
361
+ }
362
+
363
+ /**
364
+ * Remove a specific backup key from Backup Size array
365
+ *
366
+ * @param string $attachment_id
367
+ * @param string $backup_key
368
+ * @param array $backup_sizes
369
+ */
370
+ function remove_from_backup_sizes( $attachment_id = '', $backup_key = '', $backup_sizes = array() ) {
371
+ //Get backup sizes
372
+ $backup_sizes = empty( $backup_sizes ) ? get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true ) : $backup_sizes;
373
+ $backup_key = empty( $backup_key ) ? $this->backup_key : $backup_key;
374
+
375
+ //If we don't have any backup sizes list or if the particular key is not set, return
376
+ if ( empty( $backup_sizes ) || ! isset( $backup_sizes[ $backup_key ] ) ) {
377
+ return;
378
+ }
379
+
380
+ unset( $backup_sizes[ $backup_key ] );
381
+
382
+ //Store it in attachment meta
383
+ update_post_meta( $attachment_id, '_wp_attachment_backup_sizes', $backup_sizes );
384
+
385
+ }
386
+ }
387
+
388
+ global $wpsmush_backup;
389
+ $wpsmush_backup = new WpSmushBackup();
390
+
391
+ }
lib/class-wp-smush-bulk.php CHANGED
@@ -22,18 +22,22 @@ if ( ! class_exists( 'WpSmushitBulk' ) ) {
22
  * @return array $attachments
23
  */
24
  function get_attachments() {
25
- global $wpsmushit_admin;
26
 
27
  if ( ! isset( $_REQUEST['ids'] ) ) {
28
- $limit = apply_filters( 'wp_smush_nextgen_query_limit', 2000 );
29
- $limit = intval( $limit );
 
 
 
 
 
30
  $get_posts = true;
31
  $unsmushed_posts = array();
32
  $args = array(
33
- 'fields' => 'ids',
34
  'post_type' => 'attachment',
35
  'post_status' => 'any',
36
- 'post_mime_type' => array( 'image/jpeg', 'image/gif', 'image/png' ),
37
  'orderby' => 'ID',
38
  'order' => 'DESC',
39
  'posts_per_page' => $limit,
@@ -44,6 +48,7 @@ if ( ! class_exists( 'WpSmushitBulk' ) ) {
44
  'compare' => 'NOT EXISTS'
45
  )
46
  ),
 
47
  'update_post_term_cache' => false,
48
  'no_found_rows' => true,
49
  );
@@ -51,21 +56,30 @@ if ( ! class_exists( 'WpSmushitBulk' ) ) {
51
  while ( $get_posts ) {
52
 
53
  //Remove the Filters added by WP Media Folder
54
- $wpsmushit_admin->remove_wmf_filters();
55
 
56
  $query = new WP_Query( $args );
57
 
58
- if( !empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
 
 
 
 
59
  //Merge the results
60
- $unsmushed_posts = array_merge( $unsmushed_posts, $query->posts );
61
 
62
  //Update the offset
63
  $args['offset'] += $limit;
64
- }else{
65
  //If we didn't get any posts from query, set $get_posts to false
66
  $get_posts = false;
67
  }
68
 
 
 
 
 
 
69
  //If total Count is set, and it is alread lesser than offset, don't query
70
  if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $args['offset'] ) {
71
  $get_posts = false;
22
  * @return array $attachments
23
  */
24
  function get_attachments() {
25
+ global $wpsmushit_admin, $wpsmush_stats;
26
 
27
  if ( ! isset( $_REQUEST['ids'] ) ) {
28
+ $limit = $wpsmushit_admin->query_limit();
29
+ $limit = ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $limit ? $wpsmushit_admin->total_count : $limit;
30
+
31
+ //Do not fetch more than this, any time
32
+ //Localizing all rows at once increases the page load and sloes down everything
33
+ $r_limit = apply_filters( 'wp_smush_max_rows', 5000 );
34
+
35
  $get_posts = true;
36
  $unsmushed_posts = array();
37
  $args = array(
38
+ 'fields' => array( 'ids', 'post_mime_type' ),
39
  'post_type' => 'attachment',
40
  'post_status' => 'any',
 
41
  'orderby' => 'ID',
42
  'order' => 'DESC',
43
  'posts_per_page' => $limit,
48
  'compare' => 'NOT EXISTS'
49
  )
50
  ),
51
+ 'update_post_meta_cache' => false,
52
  'update_post_term_cache' => false,
53
  'no_found_rows' => true,
54
  );
56
  while ( $get_posts ) {
57
 
58
  //Remove the Filters added by WP Media Folder
59
+ $wpsmush_stats->remove_filters();
60
 
61
  $query = new WP_Query( $args );
62
 
63
+ if ( ! empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
64
+
65
+ //Get a filtered list of post ids
66
+ $posts = $wpsmushit_admin->filter_by_mime( $query->posts );
67
+
68
  //Merge the results
69
+ $unsmushed_posts = array_merge( $unsmushed_posts, $posts );
70
 
71
  //Update the offset
72
  $args['offset'] += $limit;
73
+ } else {
74
  //If we didn't get any posts from query, set $get_posts to false
75
  $get_posts = false;
76
  }
77
 
78
+ //If we already got enough posts
79
+ if ( count( $unsmushed_posts ) >= $r_limit ) {
80
+ $get_posts = false;
81
+ }
82
+
83
  //If total Count is set, and it is alread lesser than offset, don't query
84
  if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $args['offset'] ) {
85
  $get_posts = false;
lib/class-wp-smush-db.php ADDED
@@ -0,0 +1,874 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Smush
4
+ * @subpackage Admin
5
+ * @version 2.3
6
+ *
7
+ * @author Umesh Kumar <umesh@incsub.com>
8
+ *
9
+ * @copyright (c) 2016, Incsub (http://incsub.com)
10
+ */
11
+ if ( ! class_exists( 'WpSmushDB' ) ) {
12
+
13
+ /**
14
+ * Class WpSmushStats
15
+ */
16
+ class WpSmushDB {
17
+ function __construct() {
18
+ //Recalculate resize savings
19
+ add_action( 'wp_smush_image_resized', array( $this, 'resize_savings' ) );
20
+
21
+ //Update Conversion savings
22
+ add_action( 'wp_smush_png_jpg_converted', array( $this, 'conversion_savings' ) );
23
+
24
+ }
25
+
26
+ /**
27
+ * Filter the Posts object as per mime type
28
+ *
29
+ * @param $posts Object of Posts
30
+ *
31
+ * @return mixed array of post ids
32
+ *
33
+ */
34
+ function filter_by_mime( $posts ) {
35
+ global $wpsmushit_admin;
36
+ if ( empty( $posts ) ) {
37
+ return $posts;
38
+ }
39
+ foreach ( $posts as $post_k => $post ) {
40
+ if ( ! isset( $post->post_mime_type ) || ! in_array( $post->post_mime_type, $wpsmushit_admin->mime_types ) ) {
41
+ unset( $posts[ $post_k ] );
42
+ } else {
43
+ $posts[ $post_k ] = $post->ID;
44
+ }
45
+ }
46
+
47
+ return $posts;
48
+ }
49
+
50
+ /**
51
+ * Fetch all the unsmushed attachments
52
+ *
53
+ * @return array $attachments
54
+ */
55
+ function get_unsmushed_attachments() {
56
+ global $wpsmushit_admin, $wpsmush_db;
57
+
58
+ if ( ! isset( $_REQUEST['ids'] ) ) {
59
+
60
+ /** Do not fetch more than this, any time
61
+ Localizing all rows at once increases the page load and slows down everything */
62
+ $r_limit = apply_filters( 'wp_smush_max_rows', 5000 );
63
+
64
+ //Check if we can get the unsmushed attachments from the other two variables
65
+ if ( ! empty( $wpsmushit_admin->attachments ) && ! empty( $wpsmushit_admin->smushed_attachments ) ) {
66
+ $unsmushed_posts = array_diff( $wpsmushit_admin->attachments, $wpsmushit_admin->smushed_attachments );
67
+ $unsmushed_posts = ! empty( $unsmushed_posts ) && is_array( $unsmushed_posts ) ? array_slice( $unsmushed_posts, 0, $r_limit ) : array();
68
+ } else {
69
+ $limit = $wpsmushit_admin->query_limit();
70
+
71
+ $get_posts = true;
72
+ $unsmushed_posts = array();
73
+ $args = array(
74
+ 'fields' => array( 'ids', 'post_mime_type' ),
75
+ 'post_type' => 'attachment',
76
+ 'post_status' => 'any',
77
+ 'orderby' => 'ID',
78
+ 'order' => 'DESC',
79
+ 'posts_per_page' => $limit,
80
+ 'offset' => 0,
81
+ 'meta_query' => array(
82
+ array(
83
+ 'key' => 'wp-smpro-smush-data',
84
+ 'compare' => 'NOT EXISTS'
85
+ )
86
+ ),
87
+ 'update_post_term_cache' => false,
88
+ 'no_found_rows' => true,
89
+ );
90
+ //Loop Over to get all the attachments
91
+ while ( $get_posts ) {
92
+
93
+ //Remove the Filters added by WP Media Folder
94
+ $wpsmush_db->remove_filters();
95
+
96
+ $query = new WP_Query( $args );
97
+
98
+ if ( ! empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
99
+
100
+ //Get a filtered list of post ids
101
+ $posts = $wpsmush_db->filter_by_mime( $query->posts );
102
+
103
+ //Merge the results
104
+ $unsmushed_posts = array_merge( $unsmushed_posts, $posts );
105
+
106
+ //Update the offset
107
+ $args['offset'] += $limit;
108
+ } else {
109
+ //If we didn't get any posts from query, set $get_posts to false
110
+ $get_posts = false;
111
+ }
112
+
113
+ //If we already got enough posts
114
+ if ( count( $unsmushed_posts ) >= $r_limit ) {
115
+ $get_posts = false;
116
+ } else if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count <= $args['offset'] ) {
117
+ //If total Count is set, and it is alread lesser than offset, don't query
118
+ $get_posts = false;
119
+ }
120
+ }
121
+ }
122
+ } else {
123
+ return array_map( 'intval', explode( ',', $_REQUEST['ids'] ) );
124
+ }
125
+
126
+ //Remove resmush list from unsmushed images
127
+ if( !empty( $wpsmushit_admin->resmush_ids ) && is_array( $wpsmushit_admin->resmush_ids ) ) {
128
+ $unsmushed_posts = array_diff( $unsmushed_posts, $wpsmushit_admin->resmush_ids );
129
+ }
130
+ return $unsmushed_posts;
131
+ }
132
+
133
+ /**
134
+ * Total Image count
135
+ *
136
+ * @param bool $force_update
137
+ *
138
+ * @return bool|int|mixed
139
+ */
140
+ function total_count( $force_update = false ) {
141
+ global $wpsmushit_admin;
142
+
143
+ //Retrieve from Cache
144
+ if ( ! $force_update && $count = wp_cache_get( 'total_count', 'wp-smush' ) ) {
145
+ if( $count ) {
146
+ return $count;
147
+ }
148
+ }
149
+
150
+ //Set Attachment ids, and total count
151
+ $posts = $this->get_media_attachments( '', $force_update );
152
+ $wpsmushit_admin->attachments = $posts;
153
+
154
+ //Get total count from attachments
155
+ $total_count = ! empty( $posts ) && is_array( $posts ) ? sizeof( $posts ) : 0;
156
+
157
+ // Set total count.
158
+ $wpsmushit_admin->total_count = $total_count;
159
+
160
+ wp_cache_add( 'total_count', $total_count, 'wp-smush' );
161
+
162
+ // send the count
163
+ return $total_count;
164
+ }
165
+
166
+ /**
167
+ * Get the media attachment Id/Count
168
+ *
169
+ * @param bool $return_count
170
+ * @param bool $force_update
171
+ *
172
+ * @return array|bool|int|mixed
173
+ */
174
+ function get_media_attachments( $return_count = false, $force_update = false ) {
175
+ global $wpsmushit_admin, $wpdb;
176
+
177
+ //Return results from cache
178
+ if ( ! $force_update ) {
179
+ $posts = wp_cache_get( 'media_attachments', 'wp-smush' );
180
+ $count = ! empty( $posts ) ? sizeof( $posts ) : 0;
181
+
182
+ //Return results only if we've got any
183
+ if( $count ) {
184
+ return $return_count ? $count : $posts;
185
+ }
186
+
187
+ }
188
+
189
+ $posts = array();
190
+
191
+ //Else Get it Fresh!!
192
+ $offset = 0;
193
+ $limit = $wpsmushit_admin->query_limit();
194
+
195
+ $mime = implode( "', '", $wpsmushit_admin->mime_types );
196
+ $query = "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_status != 'trash' AND post_mime_type IN ('$mime') LIMIT %d, %d";
197
+ //Remove the Filters added by WP Media Folder
198
+ $this->remove_filters();
199
+
200
+ $get_posts = true;
201
+
202
+ while ( $get_posts ) {
203
+ $results = $wpdb->get_col( $wpdb->prepare( $query, $offset, $limit ) );
204
+ if ( ! empty( $results ) && is_array( $results ) && sizeof( $results ) > 0 ) {
205
+
206
+ //Get a filtered list of post ids
207
+ $posts = array_merge( $posts, $results );
208
+
209
+ //Update the offset
210
+ $offset += $limit;
211
+ } else {
212
+ //If we didn't get any posts from query, set $get_posts to false
213
+ $get_posts = false;
214
+ }
215
+ }
216
+
217
+ //Add the attachments to cache
218
+ wp_cache_add( 'media_attachments', $posts, 'wp-smushit' );
219
+
220
+ if ( $return_count ) {
221
+ return sizeof( $posts );
222
+ }
223
+
224
+ return $posts;
225
+ }
226
+
227
+ /**
228
+ * Optimised images count
229
+ *
230
+ * @param bool $return_ids
231
+ *
232
+ * @return array|int
233
+ */
234
+ function smushed_count( $return_ids = false ) {
235
+ global $wpsmushit_admin, $wpdb;
236
+
237
+ //Don't query again, if the variable is already set
238
+ if ( ! $return_ids && ! empty( $wpsmushit_admin->smushed_count ) && $wpsmushit_admin->smushed_count > 0 ) {
239
+ return $wpsmushit_admin->smushed_count;
240
+ }
241
+
242
+ /**
243
+ * Allows to set a limit of mysql query
244
+ * Default value is 2000
245
+ */
246
+ $limit = $wpsmushit_admin->query_limit();
247
+ $offset = 0;
248
+ $query_next = true;
249
+
250
+ $posts = array();
251
+
252
+ //Remove the Filters added by WP Media Folder
253
+ $this->remove_filters();
254
+ while ( $query_next && $results = $wpdb->get_col( $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key=%s LIMIT $offset, $limit", "wp-smpro-smush-data" ) ) ) {
255
+ if ( ! is_wp_error( $results ) && sizeof( $results ) > 0 ) {
256
+
257
+ $posts = array_merge( $posts, $results );
258
+ }
259
+ //Update the offset
260
+ $offset += $limit;
261
+
262
+ //Compare the Offset value to total images
263
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count <= $offset ) {
264
+ $query_next = false;
265
+ }
266
+ }
267
+
268
+ return $return_ids ? $posts : count( $posts );
269
+ }
270
+
271
+ /**
272
+ * Returns/Updates the number of images Super Smushed
273
+ *
274
+ * @param string $type media/nextgen, Type of images to get/set the super smushed count for
275
+ *
276
+ * @param array $attachments Optional, By default Media attachments will be fetched
277
+ *
278
+ * @return array|mixed|void
279
+ *
280
+ * @todo: Refactor Method, Separate Media Library and Nextgen, moreover nextgen functioanlity is broken
281
+ *
282
+ */
283
+ function super_smushed_count( $type = 'media', $attachments = array() ) {
284
+
285
+ if ( 'media' == $type ) {
286
+ $count = $this->get_super_smushed_attachments();
287
+ } else {
288
+ $key = 'wp-smush-super_smushed_nextgen';
289
+
290
+ //Flag to check if we need to re-evaluate the count
291
+ $revaluate = false;
292
+
293
+ $super_smushed = get_option( $key, false );
294
+
295
+ //Check if need to revalidate
296
+ if ( ! $super_smushed || empty( $super_smushed ) || empty( $super_smushed['ids'] ) ) {
297
+
298
+ $super_smushed = array(
299
+ 'ids' => array()
300
+ );
301
+
302
+ $revaluate = true;
303
+ } else {
304
+ $last_checked = $super_smushed['timestamp'];
305
+
306
+ $diff = $last_checked - current_time( 'timestamp' );
307
+
308
+ //Difference in hour
309
+ $diff_h = $diff / 3600;
310
+
311
+ //if last checked was more than 1 hours.
312
+ if ( $diff_h > 1 ) {
313
+ $revaluate = true;
314
+ }
315
+ }
316
+ //Do not Revaluate stats if nextgen attachments are not provided
317
+ if ( 'nextgen' == $type && empty( $attachments ) && $revaluate ) {
318
+ $revaluate = false;
319
+ }
320
+
321
+ //Need to scan all the image
322
+ if ( $revaluate ) {
323
+ //Get all the Smushed attachments ids
324
+ //Note: Wrong Method called, it'll fetch media images and not NextGen images
325
+ //Should be $attachments, in place of $super_smushed_images
326
+ $super_smushed_images = $this->get_super_smushed_attachments( true );
327
+
328
+ if ( ! empty( $super_smushed_images ) && is_array( $super_smushed_images ) ) {
329
+ //Iterate over all the attachments to check if it's already there in list, else add it
330
+ foreach ( $super_smushed_images as $id ) {
331
+ if ( ! in_array( $id, $super_smushed['ids'] ) ) {
332
+ $super_smushed['ids'][] = $id;
333
+ }
334
+ }
335
+ }
336
+
337
+ $super_smushed['timestamp'] = current_time( 'timestamp' );
338
+
339
+ update_option( $key, $super_smushed, false );
340
+ }
341
+
342
+ $count = ! empty( $super_smushed['ids'] ) ? count( $super_smushed['ids'] ) : 0;
343
+ }
344
+
345
+ return $count;
346
+ }
347
+
348
+ /**
349
+ * Updates the Meta for existing smushed images and retrieves the count of Super Smushed images
350
+ *
351
+ * @param bool $return_ids Whether to return ids or just the count
352
+ *
353
+ * @return array|int Super Smushed images Id / Count of Super Smushed images
354
+ */
355
+ function get_super_smushed_attachments( $return_ids = false ) {
356
+
357
+ global $wpsmushit_admin;
358
+
359
+ //Get all the attachments with wp-smush-lossy
360
+ $limit = $wpsmushit_admin->query_limit();
361
+ $get_posts = true;
362
+ $super_smushed = array();
363
+ $args = array(
364
+ 'fields' => array( 'ids', 'post_mime_type' ),
365
+ 'post_type' => 'attachment',
366
+ 'post_status' => 'any',
367
+ 'orderby' => 'ID',
368
+ 'order' => 'DESC',
369
+ 'posts_per_page' => $limit,
370
+ 'offset' => 0,
371
+ 'meta_query' => array(
372
+ array(
373
+ 'key' => 'wp-smush-lossy',
374
+ 'value' => 1
375
+ )
376
+ ),
377
+ 'update_post_term_cache' => false,
378
+ 'no_found_rows' => true,
379
+ );
380
+ //Loop Over to get all the attachments
381
+ while ( $get_posts ) {
382
+
383
+ //Remove the Filters added by WP Media Folder
384
+ $this->remove_filters();
385
+
386
+ $query = new WP_Query( $args );
387
+
388
+ if ( ! empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
389
+ $posts = $this->filter_by_mime( $query->posts );
390
+ //Merge the results
391
+ $super_smushed = array_merge( $super_smushed, $posts );
392
+
393
+ //Update the offset
394
+ $args['offset'] += $limit;
395
+ } else {
396
+ //If we didn't get any posts from query, set $get_posts to false
397
+ $get_posts = false;
398
+ }
399
+ //If total Count is set, and it is alread lesser than offset, don't query
400
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count <= $args['offset'] ) {
401
+ $get_posts = false;
402
+ }
403
+ }
404
+ //Remove resmush ids from the list
405
+ if ( ! empty( $wpsmushit_admin->resmush_ids ) && is_array( $wpsmushit_admin->resmush_ids ) ) {
406
+ $super_smushed = array_diff( $super_smushed, $wpsmushit_admin->resmush_ids );
407
+ }
408
+
409
+ return $return_ids ? $super_smushed : count( $super_smushed );
410
+ }
411
+
412
+ /**
413
+ * Remove any pre_get_posts_filters added by WP Media Folder plugin
414
+ */
415
+ function remove_filters() {
416
+ //remove any filters added b WP media Folder plugin to get the all attachments
417
+ if ( class_exists( 'Wp_Media_Folder' ) ) {
418
+ global $wp_media_folder;
419
+ if ( is_object( $wp_media_folder ) ) {
420
+ remove_filter( 'pre_get_posts', array( $wp_media_folder, 'wpmf_pre_get_posts1' ) );
421
+ remove_filter( 'pre_get_posts', array( $wp_media_folder, 'wpmf_pre_get_posts' ), 0, 1 );
422
+ }
423
+ }
424
+ global $wpml_query_filter;
425
+ //If WPML is not installed, return
426
+ if ( ! is_object( $wpml_query_filter ) ) {
427
+ return;
428
+ }
429
+
430
+ //Remove language filter and let all the images be smushed at once
431
+ if ( has_filter( 'posts_join', array( $wpml_query_filter, 'posts_join_filter' ) ) ) {
432
+ remove_filter( 'posts_join', array( $wpml_query_filter, 'posts_join_filter' ), 10, 2 );
433
+ remove_filter( 'posts_where', array( $wpml_query_filter, 'posts_where_filter' ), 10, 2 );
434
+ }
435
+ }
436
+
437
+ /**
438
+ * Get the savings from image resizing, And force update if set to true
439
+ *
440
+ * @param bool $force_update , Whether to Re-Calculate all the stats or not
441
+ *
442
+ * @param bool $format Format the Bytes in readable format
443
+ *
444
+ * @return array|bool|mixed|string Array of {
445
+ * 'bytes',
446
+ * 'before_size',
447
+ * 'after_size'
448
+ * }
449
+ *
450
+ */
451
+ function resize_savings( $force_update = true, $format = false ) {
452
+ $savings = '';
453
+
454
+ if ( ! $force_update ) {
455
+ $savings = wp_cache_get( WP_SMUSH_PREFIX . 'resize_savings', 'wp-smush' );
456
+ }
457
+
458
+ global $wpsmushit_admin;
459
+
460
+ //If nothing in cache, Calculate it
461
+ if ( empty( $savings ) || $force_update ) {
462
+ $savings = array(
463
+ 'bytes' => 0,
464
+ 'size_before' => 0,
465
+ 'size_after' => 0,
466
+ );
467
+
468
+ $limit = $wpsmushit_admin->query_limit();
469
+ $offset = 0;
470
+ $query_next = true;
471
+ global $wpdb;
472
+
473
+ while ( $query_next ) {
474
+
475
+ $resize_data = $wpdb->get_results( $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key=%s LIMIT $offset, $limit", WP_SMUSH_PREFIX . 'resize_savings' ) );
476
+
477
+ if ( ! empty( $resize_data ) ) {
478
+ foreach ( $resize_data as $data ) {
479
+ //Skip resmush ids
480
+ if ( ! empty( $wpsmushit_admin->resmush_ids ) && in_array( $data->post_id, $wpsmushit_admin->resmush_ids ) ) {
481
+ continue;
482
+ }
483
+ if ( ! empty( $data ) ) {
484
+ $meta = maybe_unserialize( $data->meta_value );
485
+ if ( ! empty( $meta ) && ! empty( $meta['bytes'] ) ) {
486
+ $savings['bytes'] += $meta['bytes'];
487
+ $savings['size_before'] += $meta['size_before'];
488
+ $savings['size_after'] += $meta['size_after'];
489
+ }
490
+ }
491
+ }
492
+ }
493
+ //Update the offset
494
+ $offset += $limit;
495
+
496
+ //Compare the Offset value to total images
497
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $offset ) {
498
+ $query_next = false;
499
+ } elseif ( ! $resize_data ) {
500
+ //If we didn' got any results
501
+ $query_next = false;
502
+ }
503
+ }
504
+
505
+ if ( $format ) {
506
+ $savings['bytes'] = size_format( $savings['bytes'], 1 );
507
+ }
508
+
509
+ wp_cache_set( WP_SMUSH_PREFIX . 'resize_savings', $savings, 'wp-smush' );
510
+ }
511
+
512
+ return $savings;
513
+ }
514
+
515
+ /**
516
+ * Return/Update PNG -> JPG Conversion savings
517
+ *
518
+ * @param bool $force_update Whether to force update the conversion savings or not
519
+ * @param bool $format Optionally return formatted savings
520
+ *
521
+ * @return array Savings
522
+ */
523
+ function conversion_savings( $force_update = true, $format = false ) {
524
+ $savings = '';
525
+
526
+ if ( ! $force_update ) {
527
+ $savings = wp_cache_get( WP_SMUSH_PREFIX . 'pngjpg_savings', 'wp-smush' );
528
+ }
529
+ //If nothing in cache, Calculate it
530
+ if ( empty( $savings ) || $force_update ) {
531
+ global $wpsmushit_admin;
532
+ $savings = array(
533
+ 'bytes' => 0,
534
+ 'size_before' => 0,
535
+ 'size_after' => 0,
536
+ );
537
+
538
+ $limit = $wpsmushit_admin->query_limit();
539
+ $offset = 0;
540
+ $query_next = true;
541
+ global $wpdb;
542
+
543
+ while ( $query_next ) {
544
+
545
+ $conversion_savings = $wpdb->get_results( $wpdb->prepare( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key=%s LIMIT $offset, $limit", WP_SMUSH_PREFIX . 'pngjpg_savings' ) );
546
+
547
+ if ( ! empty( $conversion_savings ) ) {
548
+ foreach ( $conversion_savings as $data ) {
549
+
550
+ //Skip resmush ids
551
+ if ( ! empty( $wpsmushit_admin->resmush_ids ) && in_array( $data->post_id, $wpsmushit_admin->resmush_ids ) ) {
552
+ continue;
553
+ }
554
+
555
+ if ( ! empty( $data ) ) {
556
+ $meta = maybe_unserialize( $data->meta_value );
557
+
558
+ if ( is_array( $meta ) ) {
559
+ foreach ( $meta as $size ) {
560
+ if ( ! empty( $size ) && is_array( $size ) ) {
561
+ $savings['bytes'] += $size['bytes'];
562
+ $savings['size_before'] += $size['size_before'];
563
+ $savings['size_after'] += $size['size_after'];
564
+ }
565
+ }
566
+ }
567
+ }
568
+ }
569
+ }
570
+ //Update the offset
571
+ $offset += $limit;
572
+
573
+ //Compare the Offset value to total images
574
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $offset ) {
575
+ $query_next = false;
576
+ } elseif ( ! $conversion_savings ) {
577
+ //If we didn' got any results
578
+ $query_next = false;
579
+ }
580
+ }
581
+
582
+ if ( $format ) {
583
+ $savings['bytes'] = size_format( $savings['bytes'], 1 );
584
+ }
585
+
586
+ wp_cache_set( WP_SMUSH_PREFIX . 'pngjpg_savings', $savings, 'wp-smush' );
587
+ }
588
+
589
+ return $savings;
590
+ }
591
+
592
+ /**
593
+ * Get all the resized images
594
+ *
595
+ * @return array Array of post ids of all the resized images
596
+ *
597
+ */
598
+ function resize_images() {
599
+ global $wpsmushit_admin;
600
+ $limit = $wpsmushit_admin->query_limit();
601
+ $get_posts = true;
602
+ $resized_images = array();
603
+ $args = array(
604
+ 'fields' => array( 'ids', 'post_mime_type' ),
605
+ 'post_type' => 'attachment',
606
+ 'post_status' => 'inherit',
607
+ 'orderby' => 'ID',
608
+ 'order' => 'DESC',
609
+ 'posts_per_page' => $limit,
610
+ 'offset' => 0,
611
+ 'meta_key' => WP_SMUSH_PREFIX . 'resize_savings',
612
+ 'update_post_term_cache' => false,
613
+ 'no_found_rows' => true,
614
+ );
615
+ //Loop Over to get all the attachments
616
+ while ( $get_posts ) {
617
+
618
+ //Remove the Filters added by WP Media Folder
619
+ $this->remove_filters();
620
+
621
+ $query = new WP_Query( $args );
622
+
623
+ if ( ! empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
624
+
625
+ $posts = $this->filter_by_mime( $query->posts );
626
+
627
+ //Merge the results
628
+ $resized_images = array_merge( $resized_images, $posts );
629
+
630
+ //Update the offset
631
+ $args['offset'] += $limit;
632
+ } else {
633
+ //If we didn't get any posts from query, set $get_posts to false
634
+ $get_posts = false;
635
+ }
636
+
637
+ //If total Count is set, and it is alread lesser than offset, don't query
638
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $args['offset'] ) {
639
+ $get_posts = false;
640
+ }
641
+ }
642
+
643
+ return $resized_images;
644
+ }
645
+
646
+ /**
647
+ * Get all the PNGJPG Converted images
648
+ *
649
+ * @return array Array of post ids of all the converted images
650
+ *
651
+ */
652
+ function converted_images() {
653
+ global $wpsmushit_admin;
654
+ $limit = $wpsmushit_admin->query_limit();
655
+ $get_posts = true;
656
+ $converted_images = array();
657
+ $args = array(
658
+ 'fields' => array( 'ids', 'post_mime_type' ),
659
+ 'post_type' => 'attachment',
660
+ 'post_status' => 'inherit',
661
+ 'orderby' => 'ID',
662
+ 'order' => 'DESC',
663
+ 'posts_per_page' => $limit,
664
+ 'offset' => 0,
665
+ 'meta_key' => WP_SMUSH_PREFIX . 'pngjpg_savings',
666
+ 'update_post_term_cache' => false,
667
+ 'no_found_rows' => true,
668
+ );
669
+ //Loop Over to get all the attachments
670
+ while ( $get_posts ) {
671
+
672
+ //Remove the Filters added by WP Media Folder
673
+ $this->remove_filters();
674
+
675
+ $query = new WP_Query( $args );
676
+
677
+ if ( ! empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
678
+
679
+ //Filter Posts by mime types
680
+ $posts = $this->filter_by_mime( $query->posts );
681
+
682
+ //Merge the results
683
+ $converted_images = array_merge( $converted_images, $posts );
684
+
685
+ //Update the offset
686
+ $args['offset'] += $limit;
687
+ } else {
688
+ //If we didn't get any posts from query, set $get_posts to false
689
+ $get_posts = false;
690
+ }
691
+
692
+ //If total Count is set, and it is alread lesser than offset, don't query
693
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $args['offset'] ) {
694
+ $get_posts = false;
695
+ }
696
+ }
697
+
698
+ return $converted_images;
699
+ }
700
+
701
+ /**
702
+ * Returns the ids and meta which are losslessly compressed
703
+ *
704
+ * Called only if the meta key isn't updated for old images, else it is not used
705
+ *
706
+ * @return array
707
+ */
708
+ function get_lossy_attachments( $attachments = '', $return_count = true ) {
709
+
710
+ $lossy_attachments = array();
711
+ $count = 0;
712
+
713
+ if ( empty( $attachments ) ) {
714
+ //Fetch all the smushed attachment ids
715
+ $attachments = $this->smushed_count( true );
716
+ }
717
+
718
+ //If we dont' have any attachments
719
+ if ( empty( $attachments ) || 0 == count( $attachments ) ) {
720
+ return 0;
721
+ }
722
+
723
+ //Check if image is lossless or lossy
724
+ foreach ( $attachments as $attachment ) {
725
+
726
+ //Check meta for lossy value
727
+ $smush_data = ! empty( $attachment->smush_data ) ? maybe_unserialize( $attachment->smush_data ) : '';
728
+
729
+ //For Nextgen Gallery images
730
+ if ( empty( $smush_data ) && is_array( $attachment ) && ! empty( $attachment['wp_smush'] ) ) {
731
+ $smush_data = ! empty( $attachment['wp_smush'] ) ? $attachment['wp_smush'] : '';
732
+ }
733
+
734
+ //Return if not smushed
735
+ if ( empty( $smush_data ) ) {
736
+ continue;
737
+ }
738
+
739
+ //if stats not set or lossy is not set for attachment, return
740
+ if ( empty( $smush_data['stats'] ) || ! isset( $smush_data['stats']['lossy'] ) ) {
741
+ continue;
742
+ }
743
+
744
+ //Add to array if lossy is not 1
745
+ if ( 1 == $smush_data['stats']['lossy'] ) {
746
+ $count ++;
747
+ if ( ! empty( $attachment->attachment_id ) ) {
748
+ $lossy_attachments[] = $attachment->attachment_id;
749
+ } elseif ( is_array( $attachment ) && ! empty( $attachment['pid'] ) ) {
750
+ $lossy_attachments[] = $attachment['pid'];
751
+ }
752
+ }
753
+ }
754
+ unset( $attachments );
755
+
756
+ if ( $return_count ) {
757
+ return $count;
758
+ }
759
+
760
+ return $lossy_attachments;
761
+ }
762
+
763
+ /**
764
+ * Get the attachment ids with Upfront images
765
+ *
766
+ * @param array $skip_ids
767
+ *
768
+ * @return array|bool
769
+ */
770
+ function get_upfront_images( $skip_ids = array() ) {
771
+
772
+ $query = array(
773
+ 'fields' => array( 'ids', 'post_mime_type' ),
774
+ 'post_type' => 'attachment',
775
+ 'post_status' => 'any',
776
+ 'order' => 'ASC',
777
+ 'posts_per_page' => - 1,
778
+ 'meta_key' => 'upfront_used_image_sizes',
779
+ 'no_found_rows' => true
780
+ );
781
+
782
+ //Skip all the ids which are already in resmush list
783
+ if ( ! empty( $skip_ids ) && is_array( $skip_ids ) ) {
784
+ $query['post__not_in'] = $skip_ids;
785
+ }
786
+
787
+ $results = new WP_Query( $query );
788
+
789
+ if ( ! is_wp_error( $results ) && $results->post_count > 0 ) {
790
+ $posts = $this->filter_by_mime( $results->posts );
791
+
792
+ return $posts;
793
+ } else {
794
+ return false;
795
+ }
796
+ }
797
+
798
+ /**
799
+ * Get the savings for the given set of attachments
800
+ *
801
+ * @param array $attachments Array of attachment ids
802
+ *
803
+ * @return array Stats
804
+ * array(
805
+ * 'size_before' => 0,
806
+ * 'size_after' => 0,
807
+ * 'savings_resize' => 0,
808
+ * 'savings_conversion' => 0
809
+ * )
810
+ *
811
+ *
812
+ */
813
+ function get_savings_for_attachments( $attachments = array() ) {
814
+ //@todo: Add image_count, lossy count, count_smushed
815
+ $stats = array(
816
+ 'size_before' => 0,
817
+ 'size_after' => 0,
818
+ 'savings_resize' => 0,
819
+ 'savings_conversion' => 0,
820
+ 'count_images' => 0,
821
+ 'count_supersmushed' => 0,
822
+ 'count_smushed' => 0
823
+ );
824
+
825
+ //If we don't have any attachments, return empty array
826
+ if( empty( $attachments ) || !is_array( $attachments ) ) {
827
+ return $stats;
828
+ }
829
+
830
+ global $WpSmush, $wpsmush_helper;
831
+
832
+ //Loop over all the attachments to get the cummulative savings
833
+ foreach ( $attachments as $attachment ) {
834
+ $smush_stats = get_post_meta( $attachment, $WpSmush->smushed_meta_key, true );
835
+ $resize_savings = get_post_meta( $attachment, WP_SMUSH_PREFIX . 'resize_savings', true );
836
+ $conversion_savings = $wpsmush_helper->get_pngjpg_savings( $attachment );
837
+
838
+ if ( ! empty( $smush_stats['stats'] ) ) {
839
+ //Combine all the stats, and keep the resize and send conversion settings separately
840
+ $stats['size_before'] += ! empty( $smush_stats['stats']['size_before'] ) ? $smush_stats['stats']['size_before'] : 0;
841
+ $stats['size_after'] += ! empty( $smush_stats['stats']['size_after'] ) ? $smush_stats['stats']['size_after'] : 0;
842
+ }
843
+
844
+ $stats['count_images'] += ! empty( $smush_stats['sizes'] ) && is_array( $smush_stats['sizes'] ) ? sizeof( $smush_stats['sizes'] ) : 0;
845
+ $stats['count_supersmushed'] + ! empty( $smush_stats['stats'] ) && $smush_stats['stats']['lossy'] ? 1 : 0;
846
+
847
+ //Add resize saving stats
848
+ if ( ! empty( $resize_savings ) ) {
849
+ //Add resize and conversion savings
850
+ $stats['savings_resize'] += ! empty( $resize_savings['bytes'] ) ? $resize_savings['bytes'] : 0;
851
+ $stats['size_before'] += ! empty( $resize_savings['size_before'] ) ? ! empty( $resize_savings['size_before'] ) : 0;
852
+ $stats['size_after'] += ! empty( $resize_savings['size_after'] ) ? ! empty( $resize_savings['size_after'] ) : 0;
853
+ }
854
+
855
+ //Add conversion saving stats
856
+ if ( ! empty( $conversion_savings ) ) {
857
+ //Add resize and conversion savings
858
+ $stats['savings_conversion'] += ! empty( $conversion_savings['bytes'] ) ? $conversion_savings['bytes'] : 0;
859
+ $stats['size_before'] += ! empty( $conversion_savings['size_before'] ) ? $conversion_savings['size_before'] : 0;
860
+ $stats['size_after'] += ! empty( $conversion_savings['size_after'] ) ? $conversion_savings['size_after'] : 0;
861
+ }
862
+ $stats['count_smushed'] += 1;
863
+ }
864
+
865
+ return $stats;
866
+ }
867
+ }
868
+
869
+ /**
870
+ * Initialise class
871
+ */
872
+ global $wpsmush_db;
873
+ $wpsmush_db = new WpSmushDB();
874
+ }
lib/class-wp-smush-dir.php ADDED
@@ -0,0 +1,1349 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Smush
4
+ * @subpackage Admin
5
+ * @since 2.6
6
+ *
7
+ * @author Umesh Kumar <umesh@incsub.com>
8
+ *
9
+ * @copyright (c) 2016, Incsub (http://incsub.com)
10
+ */
11
+
12
+ if ( ! class_exists( 'WpSmushDir' ) ) {
13
+
14
+ class WpSmushDir {
15
+
16
+ /**
17
+ * @var Contains a list of optimised images
18
+ */
19
+ public $optimised_images;
20
+
21
+ /**
22
+ * @var Total Stats for the image optimisation
23
+ *
24
+ */
25
+ public $stats;
26
+
27
+ function __construct() {
28
+
29
+ if ( ! $this->should_continue() ) {
30
+ return;
31
+ }
32
+
33
+ //Hook early for free version, in order to display it before the advanced settings
34
+ add_action( 'wp_smush_before_advanced_settings', array( $this, 'ui' ) );
35
+
36
+ //Hook UI at the end of Settings UI
37
+ add_action( 'smush_settings_ui_bottom', array( $this, 'ui' ) );
38
+
39
+ //Output Stats after Resize savings
40
+ add_action( 'stats_ui_after_resize_savings', array( $this, 'stats_ui' ) );
41
+
42
+ //Handle Ajax request 'smush_get_directory_list'
43
+ add_action( 'wp_ajax_smush_get_directory_list', array( $this, 'directory_list' ) );
44
+
45
+ //Scan the given directory path for the list of images
46
+ add_action( 'wp_ajax_image_list', array( $this, 'image_list' ) );
47
+
48
+ //Handle Ajax Request to optimise images
49
+ add_action( 'wp_ajax_optimise', array( $this, 'optimise' ) );
50
+
51
+ //Handle Exclude path request
52
+ add_action( 'wp_ajax_smush_exclude_path', array( $this, 'smush_exclude_path' ) );
53
+
54
+ //Handle Ajax request: resume scan
55
+ add_action( 'wp_ajax_resume_scan', array( $this, 'resume_scan' ) );
56
+
57
+ //Handle Ajax request for directory smush stats
58
+ add_action( 'wp_ajax_get_dir_smush_stats', array( $this, 'get_dir_smush_stats' ) );
59
+
60
+ }
61
+
62
+ /**
63
+ * Do not display Directory smush for Subsites
64
+ *
65
+ * @return bool True/False, whether to display the Directory smush or not
66
+ *
67
+ */
68
+ function should_continue() {
69
+
70
+ //Do not show directory smush, if not main site in a network
71
+ if ( is_multisite() && ! is_main_site() ) {
72
+ return false;
73
+ }
74
+
75
+ return true;
76
+ }
77
+
78
+ function stats_ui() { ?>
79
+ <hr/><?php
80
+ $dir_smush_stats = get_option( 'dir_smush_stats' );
81
+ $human = $percent = 0;
82
+ if ( ! empty( $dir_smush_stats ) && ! empty( $dir_smush_stats['dir_smush'] ) ) {
83
+ $human = ! empty( $dir_smush_stats['dir_smush']['percent'] ) && ! $dir_smush_stats['dir_smush']['percent'] > 0 ? $dir_smush_stats['dir_smush']['bytes'] : 0;
84
+ $percent = ! empty( $dir_smush_stats['dir_smush']['percent'] ) && $dir_smush_stats['dir_smush']['percent'] > 0 ? number_format_i18n( $dir_smush_stats['dir_smush']['percent'], 1, '.', '' ) : 0;
85
+ } ?>
86
+ <!-- Savings from Directory Smush -->
87
+ <div class="row smush-dir-savings">
88
+ <span class="float-l wp-smush-stats-label"><strong><?php esc_html_e( "DIRECTORY SMUSH SAVINGS", "wp-smushit" ); ?></strong></span>
89
+ <span class="float-r wp-smush-stats">
90
+ <span class="spinner" style="visibility: visible" title="<?php esc_html_e( "Updating Stats", "wp-smushit" ); ?>"></span>
91
+ <?php
92
+ if ( $human > 0 ) { ?>
93
+ <span class="wp-smush-stats-human"> <?php echo $human; ?></span><?php
94
+ //Output percentage only if > 1
95
+ if ( $percent > 1 ) { ?>
96
+ <span class="wp-smush-stats-sep">/</span>
97
+ <span class="wp-smush-stats-percent"><?php echo ! empty( $percent ) ? $percent : ''; ?>
98
+ %</span><?php
99
+ }
100
+ } else { ?>
101
+ <span class="wp-smush-stats-human">
102
+ <a href="#wp-smush-dir-browser">
103
+ <button class="button button-small wp-smush-dir-link"
104
+ type="button"><?php esc_html_e( "SMUSH DIRECTORY", "wp-smushit" ); ?></button>
105
+ </a>
106
+ </span>
107
+ <span class="wp-smush-stats-sep hidden">/</span>
108
+ <span class="wp-smush-stats-percent"></span>
109
+ <?php } ?>
110
+ </span>
111
+ </div><?php
112
+ }
113
+
114
+ /**
115
+ * Create the Smush image table to store the paths of scanned images, and stats
116
+ */
117
+ function create_table() {
118
+ global $wpdb;
119
+
120
+ $charset_collate = $wpdb->get_charset_collate();
121
+
122
+ //Use a lower index size
123
+ $path_index_size = 191;
124
+
125
+ /**
126
+ * Table: wp_smush_dir_images
127
+ * Columns:
128
+ * id -> Auto Increment ID
129
+ * path -> Absolute path to the image file
130
+ * resize -> Whether the image was resized or not
131
+ * lossy -> Whether the image was super-smushed/lossy or not
132
+ * image_size -> Current image size post optimisation
133
+ * orig_size -> Original image size before optimisation
134
+ * file_time -> Unix time for the file creation, to match it against the current creation time,
135
+ * in order to confirm if it is optimised or not
136
+ * last_scan -> Timestamp, Get images form last scan by latest timestamp
137
+ * are from latest scan only and not the whole list from db
138
+ * meta -> For any future use
139
+ *
140
+ */
141
+ $sql = "CREATE TABLE {$wpdb->prefix}smush_dir_images (
142
+ id mediumint(9) NOT NULL AUTO_INCREMENT,
143
+ path text NOT NULL,
144
+ resize varchar(55),
145
+ lossy varchar(55),
146
+ error varchar(55) DEFAULT NULL,
147
+ image_size int(10) unsigned,
148
+ orig_size int(10) unsigned,
149
+ file_time int(10) unsigned,
150
+ last_scan timestamp DEFAULT '0000-00-00 00:00:00',
151
+ meta text,
152
+ UNIQUE KEY id (id),
153
+ UNIQUE KEY path (path($path_index_size)),
154
+ KEY image_size (image_size)
155
+ ) $charset_collate;";
156
+
157
+ // include the upgrade library to initialize a table
158
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
159
+ dbDelta( $sql );
160
+ }
161
+
162
+ /**
163
+ * Get the image ids and path for last scanned images
164
+ *
165
+ * @return array Array of last scanned images containing image id and path
166
+ */
167
+ function get_scanned_images() {
168
+ global $wpdb;
169
+
170
+ $query = "SELECT id, path, orig_size FROM {$wpdb->prefix}smush_dir_images WHERE last_scan = (SELECT MAX(last_scan) FROM {$wpdb->prefix}smush_dir_images ) GROUP BY id ORDER BY id";
171
+
172
+ $results = $wpdb->get_results( $query, ARRAY_A );
173
+
174
+ //Return image ids
175
+ if ( is_wp_error( $results ) ) {
176
+ error_log( sprintf( "WP Smush Query Error in %s at %s: %s", __FILE__, __LINE__, $results->get_error_message() ) );
177
+ $results = array();
178
+ }
179
+
180
+ return $results;
181
+ }
182
+
183
+ /**
184
+ * Check if there is any unsmushed image from last scan
185
+ *
186
+ * @return bool True/False
187
+ *
188
+ */
189
+ function get_unsmushed_image() {
190
+ global $wpdb, $WpSmush;
191
+
192
+ // If super-smush enabled, add lossy check.
193
+ $lossy_condition = $WpSmush->lossy_enabled ? '(image_size IS NULL OR lossy <> 1)' : 'image_size IS NULL';
194
+
195
+ $query = $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}smush_dir_images WHERE $lossy_condition && last_scan = (SELECT MAX(last_scan) FROM {$wpdb->prefix}smush_dir_images t2 ) GROUP BY id ORDER BY id LIMIT %d", 1 );
196
+ $results = $wpdb->get_col( $query );
197
+
198
+ //If The query went through
199
+ if ( empty( $results ) ) {
200
+ return false;
201
+ } elseif ( is_wp_error( $results ) ) {
202
+ error_log( sprintf( "WP Smush Query Error in %s at %s: %s", __FILE__, __LINE__, $results->get_error_message() ) );
203
+
204
+ return false;
205
+ }
206
+
207
+ return true;
208
+ }
209
+
210
+
211
+ /**
212
+ * Prints a resume button if required
213
+ */
214
+ function show_resume_button() {
215
+ if ( ! $this->get_unsmushed_image() ) {
216
+ return null;
217
+ }
218
+ //Print the button ?>
219
+ <button class="wp-smush-resume wp-smush-button button"><?php esc_html_e( "RESUME LAST SCAN", "wp-smushit" ); ?></button><?php
220
+ }
221
+
222
+ /**
223
+ * Output the required UI for WP Smush All page
224
+ */
225
+ function ui() {
226
+ global $WpSmush, $wpsmushit_admin;
227
+
228
+ //Print Directory Smush UI, if not a network site
229
+ if ( is_network_admin() ) {
230
+ return;
231
+ }
232
+
233
+ //Remove the early hook
234
+ if ( $WpSmush->validate_install() ) {
235
+ remove_action( 'wp_smush_before_advanced_settings', array( $this, 'ui' ) );
236
+ } else {
237
+ remove_action( 'smush_settings_ui_bottom', array( $this, 'ui' ) );
238
+ }
239
+
240
+ //Reset the bulk limit
241
+ if ( ! $WpSmush->validate_install() ) {
242
+ //Reset Transient
243
+ $wpsmushit_admin->check_bulk_limit( true, 'dir_sent_count' );
244
+ }
245
+
246
+ wp_nonce_field( 'smush_get_dir_list', 'list_nonce' );
247
+ wp_nonce_field( 'smush_get_image_list', 'image_list_nonce' );
248
+
249
+ $upgrade_link = '<a href="' . esc_url( $wpsmushit_admin->upgrade_url ) . '" title="' . esc_html__( "WP Smush Pro", "wp-smushit" ) . '">';
250
+ /** Directory Browser and Image List **/
251
+ $wpsmushit_admin->bulk_ui->container_header( 'wp-smush-dir-browser', 'wp-smush-dir-browser', esc_html__( "DIRECTORY SMUSH", "wp-smushit" ) ); ?>
252
+ <div class="box-content">
253
+ <div class="row">
254
+ <div class="wp-smush-dir-desc roboto-regular">
255
+ <!-- Description -->
256
+ <?php esc_html_e( "In addition to smushing your media uploads, you may want to also smush images living outside your uploads directory. Simply add any directories you wish to smush and bulk smush away!", "wp-smushit" ); ?>
257
+ </div>
258
+ <!-- Directory Path -->
259
+ <input type="hidden" class="wp-smush-dir-path" value=""/>
260
+ <div class="wp-smush-scan-result hidden">
261
+ <hr class="primary-separator"/>
262
+ <div class="content">
263
+ <!-- Show a list of images, inside a fixed height div, with a scroll. As soon as the image is
264
+ optimised show a tick mark, with savings below the image. Scroll the li each time for the
265
+ current optimised image -->
266
+ </div>
267
+ <!-- Notices -->
268
+ <div class="wp-smush-notice wp-smush-dir-all-done hidden" tabindex="0">
269
+ <i class="dev-icon dev-icon-tick"></i><?php esc_html_e( "All images for the selected directory are smushed and up to date. Awesome!", "wp-smushit" ); ?>
270
+ </div>
271
+ <div class="wp-smush-notice wp-smush-dir-remaining hidden" tabindex="0">
272
+ <i class="dev-icon wdv-icon wdv-icon-fw wdv-icon-exclamation-sign"></i><?php printf( esc_html__( "%s/%s image(s) were successfully smushed, however %s image(s) could not be smushed due to an error.", "wp-smushit" ), '<span class="wp-smush-dir-smushed"></span>', '<span class="wp-smush-dir-total"></span>', '<span class="wp-smush-dir-remaining"></span>' ); ?>
273
+ </div>
274
+ <div class="wp-smush-notice wp-smush-dir-limit hidden" tabindex="0">
275
+ <i class="dev-icon wdv-icon wdv-icon-fw wdv-icon-info-sign"></i><?php printf( esc_html__( " %sUpgrade to pro%s to bulk smush all your directory images with one click. Free users can smush 50 images with each click.", "wp-smushit" ), '<a href="' . esc_url( $wpsmushit_admin->upgrade_url ) . '" target="_blank" title="' . esc_html__( "WP Smush Pro", "wp-smushit" ) . '">', '</a>' ); ?>
276
+ </div>
277
+ <div class="wp-smush-all-button-wrap bottom">
278
+ <!-- @todo: Check status of the images in last scan and do not show smush now button, if already finished -->
279
+ <button class="wp-smush-start"><?php esc_html_e( "BULK SMUSH", "wp-smushit" ); ?></button>
280
+ <button type="button"
281
+ title="<?php esc_html_e( "Click to stop the directory smushing process.", "wp-smushit" ); ?>"
282
+ class="button button-grey wp-smush-pause disabled"><?php esc_html_e( "CANCEL", "wp-smushit" ); ?></button>
283
+ <span class="spinner"></span>
284
+ </div><?php
285
+ //Nonce Field
286
+ wp_nonce_field( 'wp_smush_all', 'wp-smush-all' ); ?>
287
+ <input type="hidden" name="wp-smush-continue-ajax" value=1>
288
+ </div>
289
+ <div class="dir-smush-button-wrap">
290
+ <button class="wp-smush-browse wp-smush-button button"><?php esc_html_e( "CHOOSE DIRECTORY", "wp-smushit" ); ?></button><?php
291
+ //Optionally show a resume button, if there were images left from last scan
292
+ $this->show_resume_button(); ?>
293
+ <span class="spinner"></span>
294
+ </div>
295
+ <div class="dev-overlay wp-smush-list-dialog roboto-regular">
296
+ <div class="back"></div>
297
+ <div class="box-scroll">
298
+ <div class="box">
299
+ <div class="title"><h3><?php esc_html_e( "Directory list", "wp-smushit" ); ?></h3>
300
+ <div class="close" aria-label="Close">×</div>
301
+ </div>
302
+ <div class="wp-smush-instruct"><?php esc_html_e( "Choose the folder you wish to smush.", "wp-smushit" ); ?></div>
303
+ <div class="content">
304
+ </div>
305
+ <div class="wp-smush-select-button-wrap">
306
+ <div class="wp-smush-section-desc"><?php esc_html_e( "Smush will also include any images in sub folders of your selected folder.", "wp-smushit" ); ?></div>
307
+ <div class="wp-smush-select-button-wrap-child">
308
+ <span class="spinner"></span>
309
+ <button class="wp-smush-select-dir"><?php esc_html_e( "ADD DIRECTORY", "wp-smushit" ); ?></button>
310
+ </div>
311
+ </div>
312
+ </div>
313
+ </div>
314
+ </div>
315
+ <input type="hidden" name="wp-smush-base-path" value="<?php echo $this->get_root_path(); ?>">
316
+ </div>
317
+ </div><?php
318
+ echo "</section>";
319
+
320
+ }
321
+
322
+ /**
323
+ * Check if the image file is media library file
324
+ *
325
+ * @param $file_path
326
+ *
327
+ * @return bool
328
+ *
329
+ */
330
+ function is_media_library_file( $file_path ) {
331
+ $upload_dir = wp_upload_dir();
332
+ $upload_path = $upload_dir["path"];
333
+
334
+ //Get the base path of file
335
+ $base_dir = dirname( $file_path );
336
+ if ( $base_dir == $upload_path ) {
337
+ return true;
338
+ }
339
+
340
+ return false;
341
+ }
342
+
343
+ /**
344
+ * Return a directory/File list
345
+ */
346
+ function directory_list() {
347
+ //Check For Permission
348
+ if ( ! current_user_can( 'manage_options' ) || ! is_user_logged_in() ) {
349
+ wp_send_json_error( "Unauthorized" );
350
+ }
351
+ //Verify nonce
352
+ check_ajax_referer( 'smush_get_dir_list', 'list_nonce' );
353
+
354
+ //Get the Root path for a main site or subsite
355
+ $root = $this->get_root_path();
356
+
357
+ $postDir = rawurldecode( $root . ( isset( $_GET['dir'] ) ? $_GET['dir'] : null ) );
358
+
359
+ $supported_image = array(
360
+ 'gif',
361
+ 'jpg',
362
+ 'jpeg',
363
+ 'png'
364
+ );
365
+
366
+ $list = '';
367
+
368
+ // set checkbox if multiSelect set to true
369
+ $onlyFolders = ( '/' == $_GET['dir'] || isset( $_GET['onlyFolders'] ) && $_GET['onlyFolders'] == 'true' ) ? true : false;
370
+ $onlyFiles = ( isset( $_GET['onlyFiles'] ) && $_GET['onlyFiles'] == 'true' ) ? true : false;
371
+
372
+ if ( file_exists( $postDir ) ) {
373
+
374
+ $files = scandir( $postDir );
375
+ $returnDir = substr( $postDir, strlen( $root ) );
376
+
377
+ natcasesort( $files );
378
+
379
+ if ( count( $files ) > 2 ) {
380
+ $list = "<ul class='jqueryFileTree'>";
381
+ foreach ( $files as $file ) {
382
+
383
+ $htmlRel = htmlentities( $returnDir . $file );
384
+ $htmlName = htmlentities( $file );
385
+ $ext = preg_replace( '/^.*\./', '', $file );
386
+
387
+ if ( file_exists( $postDir . $file ) && $file != '.' && $file != '..' ) {
388
+ if ( is_dir( $postDir . $file ) && ( ! $onlyFiles || $onlyFolders ) && ! $this->skip_dir( $postDir . $file ) ) {
389
+ //Skip Uploads folder - Media Files
390
+ $list .= "<li class='directory collapsed'><a rel='" . $htmlRel . "/'>" . $htmlName . "</a></li><br />";
391
+ } else if ( ( ! $onlyFolders || $onlyFiles ) && in_array( $ext, $supported_image ) && ! $this->is_media_library_file( $postDir . $file ) ) {
392
+ $list .= "<li class='file ext_{$ext}'><a rel='" . $htmlRel . "'>" . $htmlName . "</a></li><br />";
393
+ }
394
+ }
395
+ }
396
+
397
+ $list .= "</ul>";
398
+ }
399
+ }
400
+ echo $list;
401
+ die();
402
+
403
+ }
404
+
405
+ public function get_root_path() {
406
+ if ( is_main_site() ) {
407
+
408
+ return rtrim( get_home_path(), '/' );
409
+ } else {
410
+ $up = wp_upload_dir();
411
+
412
+ return $up['basedir'];
413
+ }
414
+ }
415
+
416
+ /**
417
+ * @param SplFileInfo $file
418
+ * @param mixed $key
419
+ * @param RecursiveCallbackFilterIterator $iterator
420
+ *
421
+ * @return bool True if you need to recurse or if the item is acceptable
422
+ */
423
+ function exclude( $file, $key, $iterator ) {
424
+ // Will exclude everything under these directories
425
+ $exclude_dir = array( '.git', 'test' );
426
+
427
+ //Exclude from the list, if one of the media upload folders
428
+ if ( $this->skip_dir( $file->getPath() ) ) {
429
+ return true;
430
+ }
431
+
432
+ //Exclude Directories like git, and test
433
+ if ( $iterator->hasChildren() && ! in_array( $file->getFilename(), $exclude_dir ) ) {
434
+ return true;
435
+ }
436
+
437
+ //Do not exclude, if image
438
+ if ( $file->isFile() && $this->is_image_from_extension( $file->getPath() ) ) {
439
+ return true;
440
+ }
441
+
442
+ return $file->isFile();
443
+ }
444
+
445
+ /**
446
+ * Display a progress bar for the images in particular directory
447
+ *
448
+ * @param $count
449
+ * @param $optimised
450
+ * @param $dir_path
451
+ *
452
+ * @return bool|string
453
+ */
454
+ function progress_ui( $count, $optimised, $dir_path ) {
455
+
456
+ if ( ! $count ) {
457
+ return false;
458
+ }
459
+
460
+ $width = ( $optimised > 0 ) ? ( $optimised / $count ) * 100 : 0;
461
+
462
+ $class = 0 < $width && 100 == $width ? 'complete' : 'partial';
463
+ $o_class = 0 == $width ? 'hidden' : '';
464
+
465
+ $content = "<div class='wp-smush-dir-progress-wrap {$o_class}'>";
466
+ $content .= '<span class="smush-percent">' . number_format_i18n( $width, 0 ) . '% </span>';
467
+ $content .= "<div class='wp-smush-dir-progress-wrap-inner'>
468
+ <span class='wp-smush-dir-progress {$class}' style='width: {$width}px'></span>
469
+ </div>
470
+ </div>";
471
+
472
+ $content .= 0 == $width ? "<a href='#' class='wp-smush-exclude-dir' data-path='" . $dir_path . "' title='" . esc_html__( "Exclude directory from Smush List", "wp-smushit" ) . "'>&times;</a>" : '';
473
+
474
+ return $content;
475
+ }
476
+
477
+ /**
478
+ * Get the image list in a specified directory path
479
+ *
480
+ * @param string $path
481
+ *
482
+ * @return string
483
+ */
484
+ function get_image_list( $path = '' ) {
485
+ global $wpdb;
486
+
487
+ $base_dir = empty( $path ) ? $_GET['path'] : $path;
488
+ //Directory Path
489
+ $base_dir = realpath( $base_dir );
490
+
491
+ //Store the path in option
492
+ update_option( 'wp-smush-dir_path', $base_dir, false );
493
+
494
+ //Directory Iterator, Exclude . and ..
495
+ $dirIterator = new RecursiveDirectoryIterator(
496
+ $base_dir
497
+ //PHP 5.2 compatibility
498
+ //RecursiveDirectoryIterator::SKIP_DOTS
499
+ );
500
+
501
+ $filtered_dir = new WPSmushRecursiveFilterIterator( $dirIterator );
502
+
503
+ //File Iterator
504
+ $iterator = new RecursiveIteratorIterator( $filtered_dir,
505
+ RecursiveIteratorIterator::CHILD_FIRST
506
+ );
507
+
508
+ //Iterate over the file List
509
+ $files_arr = array();
510
+ $images = array();
511
+ $count = 0;
512
+ $timestamp = gmdate( 'Y-m-d H:i:s' );
513
+ $values = array();
514
+ foreach ( $iterator as $path ) {
515
+
516
+ //Used in place of Skip Dots, For php 5.2 compatability
517
+ if ( basename( $path ) == '..' || basename( $path ) == '.' ) {
518
+ continue;
519
+ }
520
+ if ( $path->isFile() ) {
521
+ $file_path = $path->getPathname();
522
+ $file_name = $path->getFilename();
523
+
524
+ if ( $this->is_image( $file_path ) && ! $this->is_media_library_file( $file_path ) && strpos( $path, '.bak' ) === false ) {
525
+
526
+ /** To generate Markup **/
527
+ $dir_name = dirname( $file_path );
528
+
529
+ //Initialize if dirname doesn't exists in array already
530
+ if ( ! isset( $files_arr[ $dir_name ] ) ) {
531
+ $files_arr[ $dir_name ] = array();
532
+ }
533
+ $files_arr[ $dir_name ][ $file_name ] = $file_path;
534
+ /** End */
535
+
536
+ //Get the file modification time
537
+ $file_time = @filectime( $file_path );
538
+
539
+ /** To be stored in DB, Part of code inspired from Ewwww Optimiser */
540
+ $image_size = $path->getSize();
541
+ $images [] = $file_path;
542
+ $images [] = $image_size;
543
+ $images [] = $file_time;
544
+ $images [] = $timestamp;
545
+ $values[] = '(%s, %d, %d, %s)';
546
+ $count ++;
547
+ }
548
+ }
549
+
550
+ //Store the Images in db at an interval of 5k
551
+ if ( $count >= 5000 ) {
552
+ $count = 0;
553
+ $query = $this->build_query( $values, $images );
554
+ $images = $values = array();
555
+ $wpdb->query( $query );
556
+ }
557
+ }
558
+
559
+ //Update rest of the images
560
+ if ( ! empty( $images ) && $count > 0 ) {
561
+ $query = $this->build_query( $values, $images );
562
+ $wpdb->query( $query );
563
+ }
564
+
565
+ //remove scanne dimages from cache
566
+ wp_cache_delete( 'wp_smush_scanned_images' );
567
+
568
+ //Get the image ids
569
+ $images = $this->get_scanned_images();
570
+
571
+ //Store scanned images in cache
572
+ wp_cache_add( 'wp_smush_scanned_images', $images );
573
+
574
+ return array( 'files_arr' => $files_arr, 'base_dir' => $base_dir, 'image_items' => $images );
575
+ }
576
+
577
+ /**
578
+ * Build and prepare query from the given values and image array
579
+ *
580
+ * @param $values
581
+ * @param $images
582
+ *
583
+ * @return bool|string|void
584
+ */
585
+ function build_query( $values, $images ) {
586
+
587
+ if ( empty( $images ) || empty( $values ) ) {
588
+ return false;
589
+ }
590
+
591
+ global $wpdb;
592
+ $values = implode( ',', $values );
593
+
594
+ //Replace with image path and respective parameters
595
+ $query = "INSERT INTO {$wpdb->prefix}smush_dir_images (path,orig_size,file_time,last_scan) VALUES $values ON DUPLICATE KEY UPDATE image_size = IF( file_time < VALUES(file_time), NULL, image_size ), file_time = IF( file_time < VALUES(file_time), VALUES(file_time), file_time ), last_scan = VALUES( last_scan )";
596
+ $query = $wpdb->prepare( $query, $images );
597
+
598
+ return $query;
599
+
600
+ }
601
+
602
+ /**
603
+ * Sends a Ajax response if no images are found in selected directory
604
+ */
605
+ function send_error() {
606
+ $message = sprintf( "<div class='wp-smush-info notice notice-info roboto-regular'>%s</div>", esc_html__( "We could not find any images in the selected directory.", "wp-smushit" ) );
607
+ wp_send_json_error( array( 'message' => $message ) );
608
+ }
609
+
610
+ /**
611
+ * Handles Ajax request to obtain the Image list within a selected directory path
612
+ *
613
+ */
614
+ function image_list() {
615
+
616
+ //Check For Permission
617
+ if ( ! current_user_can( 'manage_options' ) ) {
618
+ wp_send_json_error( "Unauthorized" );
619
+ }
620
+
621
+ //Verify nonce
622
+ check_ajax_referer( 'smush_get_image_list', 'image_list_nonce' );
623
+
624
+ //Check if directory path is set or not
625
+ if ( empty( $_GET['smush_path'] ) ) {
626
+ wp_send_json_error( "Empth Directory Path" );
627
+ }
628
+
629
+ //Get the File list
630
+ $files = $this->get_image_list( $_GET['smush_path'] );
631
+
632
+ //If files array is empty, send a message
633
+ if ( empty( $files['files_arr'] ) ) {
634
+ $this->send_error();
635
+ }
636
+
637
+ //Get the markup from the list
638
+ $markup = $this->generate_markup( $files );
639
+
640
+ //Send response
641
+ wp_send_json_success( $markup );
642
+
643
+ }
644
+
645
+ /**
646
+ * Check whether the given path is a image or not
647
+ *
648
+ * Do not include backup files
649
+ *
650
+ * @param $path
651
+ *
652
+ * @return bool
653
+ *
654
+ */
655
+ function is_image( $path ) {
656
+
657
+ //Check if the path is valid
658
+ if ( ! file_exists( $path ) || ! $this->is_image_from_extension( $path ) ) {
659
+ return false;
660
+ }
661
+
662
+ $a = @getimagesize( $path );
663
+
664
+ //If a is not set
665
+ if ( ! $a || empty( $a ) ) {
666
+ return false;
667
+ }
668
+
669
+ $image_type = $a[2];
670
+
671
+ if ( in_array( $image_type, array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG ) ) ) {
672
+ return true;
673
+ }
674
+
675
+ return false;
676
+ }
677
+
678
+ /**
679
+ * Obtain the path to the admin directory.
680
+ *
681
+ * @return string
682
+ *
683
+ * Thanks @andrezrv (Github)
684
+ *
685
+ */
686
+ function get_admin_path() {
687
+ // Replace the site base URL with the absolute path to its installation directory.
688
+ $admin_path = rtrim( str_replace( get_bloginfo( 'url' ) . '/', ABSPATH, get_admin_url() ), '/' );
689
+
690
+ // Make it filterable, so other plugins can hook into it.
691
+ $admin_path = apply_filters( 'wp_smush_get_admin_path', $admin_path );
692
+
693
+ return $admin_path;
694
+ }
695
+
696
+ /**
697
+ * Check if the given file path is a supported image format
698
+ *
699
+ * @param $path File Path
700
+ *
701
+ * @return bool Whether a image or not
702
+ */
703
+ function is_image_from_extension( $path ) {
704
+ $supported_image = array(
705
+ 'gif',
706
+ 'jpg',
707
+ 'jpeg',
708
+ 'png'
709
+ );
710
+ $ext = strtolower( pathinfo( $path, PATHINFO_EXTENSION ) ); // Using strtolower to overcome case sensitive
711
+ if ( in_array( $ext, $supported_image ) ) {
712
+ return true;
713
+ }
714
+
715
+ return false;
716
+ }
717
+
718
+ /**
719
+ * Excludes the Media Upload Directory ( Checks for Year and Month )
720
+ *
721
+ * @param $path
722
+ *
723
+ * @return bool
724
+ *
725
+ * Borrowed from Shortpixel - (y)
726
+ *
727
+ * @todo: Add a option to filter images if User have turned off the Year and Month Organize option
728
+ *
729
+ */
730
+ public function skip_dir( $path ) {
731
+
732
+ //Admin Directory path
733
+ $admin_dir = $this->get_admin_path();
734
+
735
+ //Includes directory path
736
+ $includes_dir = ABSPATH . WPINC;
737
+
738
+ //Upload Directory
739
+ $upload_dir = wp_upload_dir();
740
+ $base_dir = $upload_dir["basedir"];
741
+
742
+ $skip = false;
743
+
744
+ //Skip sites folder for Multisite
745
+ if ( false !== strpos( $path, $base_dir . '/sites' ) ) {
746
+ $skip = true;
747
+ } else if ( false !== strpos( $path, $base_dir ) ) {
748
+ //If matches the current upload path
749
+ //contains one of the year subfolders of the media library
750
+ $pathArr = explode( '/', str_replace( $base_dir . '/', "", $path ) );
751
+ if ( count( $pathArr ) >= 1
752
+ && is_numeric( $pathArr[0] ) && $pathArr[0] > 1900 && $pathArr[0] < 2100 //contains the year subfolder
753
+ && ( count( $pathArr ) == 1 //if there is another subfolder then it's the month subfolder
754
+ || ( is_numeric( $pathArr[1] ) && $pathArr[1] > 0 && $pathArr[1] < 13 ) )
755
+ ) {
756
+ $skip = true;
757
+ }
758
+ } elseif ( ( false !== strpos( $path, $admin_dir ) ) || false !== strpos( $path, $includes_dir ) ) {
759
+ $skip = true;
760
+ }
761
+
762
+ /**
763
+ * Can be used to skip/include folders matching a specific directory path
764
+ *
765
+ */
766
+ apply_filters( 'wp_smush_skip_folder', $skip, $path );
767
+
768
+ return $skip;
769
+ }
770
+
771
+ /**
772
+ * Creates a tree out of Given path array
773
+ *
774
+ * @param $path_list Array of path and images
775
+ * @param $base_dir Selected Base Path for the image search
776
+ *
777
+ * @return array Array of images, Child Directories and images inside
778
+ *
779
+ */
780
+ function build_tree( $path_list, $base_dir ) {
781
+ $path_tree = array();
782
+ foreach ( $path_list as $path => $images ) {
783
+ $path = str_replace( $base_dir, '', $path );
784
+ $list = explode( '/', trim( $path, '/' ), 3 );
785
+ $last_dir = &$path_tree;
786
+ $length = sizeof( $list );
787
+ foreach ( $list as $dir ) {
788
+ $length --;
789
+ $last_dir =& $last_dir[ $dir ];
790
+ }
791
+ }
792
+
793
+ return $path_tree;
794
+ }
795
+
796
+ /**
797
+ * Returns the count of optimised image
798
+ *
799
+ * @param array $images
800
+ *
801
+ * @return int
802
+ */
803
+ function optimised_count( $images = array() ) {
804
+ //If we have optimised images
805
+ if ( ! empty( $images ) && is_array( $images ) ) {
806
+ $optimised = 0;
807
+ if ( ! is_array( $this->optimised_images ) ) {
808
+ return 0;
809
+ }
810
+ foreach ( $images as $item ) {
811
+ //Check if the image is already in optimised list
812
+ if ( array_key_exists( $item, $this->optimised_images ) ) {
813
+ $optimised ++;
814
+ }
815
+ }
816
+ }
817
+
818
+ return $optimised;
819
+ }
820
+
821
+ /**
822
+ *
823
+ * Search for image id from path
824
+ *
825
+ * @param $path Image path to be searched
826
+ * @param $images Array of images
827
+ *
828
+ * @return image id
829
+ */
830
+ function get_image_id( $path, $images ) {
831
+ foreach ( $images as $key => $val ) {
832
+ if ( $val['path'] === $path ) {
833
+ return $val['id'];
834
+ }
835
+ }
836
+
837
+ return null;
838
+ }
839
+
840
+ /**
841
+ *
842
+ * Search for image id from path
843
+ *
844
+ * @param $path Image path to be searched
845
+ * @param $images Array of images
846
+ *
847
+ * @return image id
848
+ */
849
+ function get_image_path( $id, $images ) {
850
+ foreach ( $images as $key => $val ) {
851
+ if ( $val['id'] === $id ) {
852
+ return $val['path'];
853
+ }
854
+ }
855
+
856
+ return null;
857
+ }
858
+
859
+ /**
860
+ * Search for image from given image id or path
861
+ *
862
+ * @param string $id Image id to search for
863
+ * @param string $path Image path to search for
864
+ * @param $images Image array to search within
865
+ *
866
+ * @return Image array or Empty array
867
+ */
868
+ function get_image( $id = '', $path = '', $images ) {
869
+ foreach ( $images as $key => $val ) {
870
+ if ( ! empty( $id ) && $val['id'] == $id ) {
871
+ return $images[ $key ];
872
+ } elseif ( ! empty( $path ) && $val['path'] == $path ) {
873
+ return $images[ $key ];
874
+ }
875
+ }
876
+
877
+ return array();
878
+ }
879
+
880
+ /*
881
+ * Generate the markup for all the images
882
+ */
883
+ function generate_markup( $images ) {
884
+
885
+ if ( empty( $images ) || empty( $images['files_arr'] ) || empty( $images['image_items'] ) ) {
886
+ return null;
887
+ }
888
+
889
+ $this->total_stats();
890
+
891
+ $div = wp_nonce_field( 'wp-smush-exclude-path', 'exclude-path-nonce', '', false );
892
+ $div .= '<ul class="wp-smush-image-list roboto-regular">';
893
+ //Flag - Whether to print top hr tag or not
894
+ $hr = true;
895
+ //Flag - Not to print hr tag, if first element is ul in the scanned image list
896
+ $index = 1;
897
+ $files_arr = $images['files_arr'];
898
+
899
+ foreach ( $files_arr as $image_path => $image ) {
900
+ $count = sizeof( $image );
901
+ $wrapper_class = '';
902
+ if ( is_array( $image ) && $count > 1 ) {
903
+
904
+ //Get the number of optimised images for the given image array
905
+ $optimised_count = $this->optimised_count( $image );
906
+
907
+ if ( $optimised_count > 0 ) {
908
+ $wrapper_class = $count == $optimised_count ? 'complete' : 'partial';
909
+ }
910
+
911
+ $div .= "<li class='wp-smush-image-ul {$wrapper_class}'>";
912
+ if ( $hr && $index > 1 ) {
913
+ $div .= "<hr/>";
914
+ }
915
+
916
+ $div .= "<span class='wp-smush-li-path'>{$image_path} <span class='wp-smush-image-count'>" . sprintf( esc_html__( "%d images", "wp-smushit" ), $count ) . "</span></span>";
917
+ $div .= $this->progress_ui( $count, $optimised_count, $image_path );
918
+ $div .= "<ul class='wp-smush-image-list-inner'>";
919
+ foreach ( $image as $item ) {
920
+ //Check if the image is already in optimised list
921
+ $class = is_array( $this->optimised_images ) && array_key_exists( $item, $this->optimised_images ) ? ' optimised' : '';
922
+
923
+ $image_id = $this->get_image_id( $item, $images['image_items'] );
924
+ $div .= "<li class='wp-smush-image-ele{$class}' id='{$image_id}'><span class='wp-smush-image-ele-status'></span><span class='wp-smush-image-path'>{$item}</span>";
925
+ //Close LI
926
+ $div .= "</li>";
927
+ }
928
+ $div .= "</ul>
929
+ <hr />
930
+ </li>";
931
+ $hr = false;
932
+ } else {
933
+ $hr = true;
934
+ $image_p = array_pop( $image );
935
+ //Check if the image is already in optimised list
936
+ $class = is_array( $this->optimised_images ) && array_key_exists( $image_p, $this->optimised_images ) ? ' optimised' : '';
937
+ $image_id = $this->get_image_id( $image_p, $images['image_items'] );
938
+ $div .= "<li class='wp-smush-image-ele{$class}' id='{$image_id}'><span class='wp-smush-image-ele-status'></span><span class='wp-smush-image-path'>{$image_p}</span>";
939
+ //Close LI
940
+ $div .= "</li>";
941
+ }
942
+ $index ++;
943
+ }
944
+ $div .= '</ul>';
945
+ $div .= "<span class='waiting-message hidden' title='" . esc_html__( "Waiting..", "wp-smushit" ) . "'></span>";
946
+
947
+ return $div;
948
+
949
+ }
950
+
951
+ /**
952
+ * Fetch all the optimised image, Calculate stats
953
+ *
954
+ * @return array Total Stats
955
+ *
956
+ */
957
+ function total_stats() {
958
+ global $wpdb, $WpSmush;
959
+
960
+ $offset = 0;
961
+ $optimised = 0;
962
+ $limit = 1000;
963
+ $images = array();
964
+
965
+ $total = $wpdb->get_col( "SELECT count(id) FROM {$wpdb->prefix}smush_dir_images" );
966
+
967
+ $total = ! empty( $total ) && is_array( $total ) ? $total[0] : 0;
968
+
969
+ // If super-smush enabled, add meta condition.
970
+ $lossy_condition = $WpSmush->lossy_enabled ? 'AND lossy = 1' : '';
971
+
972
+ $continue = true;
973
+ while ( $continue && $results = $wpdb->get_results( "SELECT path, image_size, orig_size FROM {$wpdb->prefix}smush_dir_images WHERE image_size IS NOT NULL $lossy_condition ORDER BY `id` LIMIT $offset, $limit", ARRAY_A ) ) {
974
+ if ( ! empty( $results ) ) {
975
+ $images = array_merge( $images, $results );
976
+ }
977
+ $offset += $limit;
978
+ //If offset is above total number, do not query
979
+ if( $offset > $total ) {
980
+ $continue = false;
981
+ }
982
+ }
983
+
984
+ //Iterate over stats, Return Count and savings
985
+ if ( ! empty( $images ) ) {
986
+ $this->stats = array_shift( $images );
987
+ $path = $this->stats['path'];
988
+ $this->optimised_images[ $path ] = $this->stats;
989
+
990
+ foreach ( $images as $im ) {
991
+ foreach ( $im as $key => $val ) {
992
+ if ( 'path' == $key ) {
993
+ $this->optimised_images[ $val ] = $im;
994
+ continue;
995
+ }
996
+ $this->stats[ $key ] += $val;
997
+ }
998
+ $optimised ++;
999
+ }
1000
+ }
1001
+
1002
+ //Get the savings in bytes and percent
1003
+ if ( ! empty( $this->stats ) && ! empty( $this->stats['orig_size'] ) ) {
1004
+ $this->stats['bytes'] = ( $this->stats['orig_size'] > $this->stats['image_size'] ) ? $this->stats['orig_size'] - $this->stats['image_size'] : 0;
1005
+ $this->stats['percent'] = number_format_i18n( ( ( $this->stats['bytes'] / $this->stats['orig_size'] ) * 100 ), 1 );
1006
+ //Convert to human readable form
1007
+ $this->stats['human'] = size_format( $this->stats['bytes'], 1 );
1008
+ }
1009
+
1010
+ $this->stats['total'] = $total;
1011
+ $this->stats['optimised'] = $optimised;
1012
+
1013
+ return $this->stats;
1014
+
1015
+ }
1016
+
1017
+ /**
1018
+ * Returns the number of images scanned and optimised
1019
+ *
1020
+ * @return array
1021
+ *
1022
+ */
1023
+ function last_scan_stats() {
1024
+ global $wpdb;
1025
+ $query = "SELECT id, image_size, orig_size FROM {$wpdb->prefix}smush_dir_images WHERE last_scan = (SELECT MAX(last_scan) FROM {$wpdb->prefix}smush_dir_images ) GROUP BY id";
1026
+ $results = $wpdb->get_results( $query, ARRAY_A );
1027
+ $total = count( $results );
1028
+ $smushed = 0;
1029
+ $stats = array(
1030
+ 'image_size' => 0,
1031
+ 'orig_size' => 0
1032
+ );
1033
+
1034
+ //Get the Smushed count, and stats sum
1035
+ foreach ( $results as $image ) {
1036
+ if ( ! is_null( $image['image_size'] ) ) {
1037
+ $smushed ++;
1038
+ }
1039
+ //Summation of stats
1040
+ foreach ( $image as $k => $v ) {
1041
+ if ( 'id' == $k ) {
1042
+ continue;
1043
+ }
1044
+ $stats[ $k ] += $v;
1045
+ }
1046
+ }
1047
+
1048
+ //Stats
1049
+ $stats['total'] = $total;
1050
+ $stats['smushed'] = $smushed;
1051
+
1052
+ return $stats;
1053
+ }
1054
+
1055
+ /**
1056
+ * Handles the ajax request for image optimisation in a folder
1057
+ */
1058
+ function optimise() {
1059
+ global $wpdb, $WpSmush, $wpsmushit_admin;
1060
+
1061
+ //Verify the ajax nonce
1062
+ check_ajax_referer( 'wp_smush_all', 'nonce' );
1063
+
1064
+ $error_msg = '';
1065
+ if ( empty( $_GET['image_id'] ) ) {
1066
+ //If there are no stats
1067
+ $error_msg = esc_html__( "Incorrect image id", "wp-smushit" );
1068
+ wp_send_json_error( $error_msg );
1069
+ }
1070
+
1071
+ // Get the last scan stats.
1072
+ $last_scan = $this->last_scan_stats();
1073
+ $stats = array();
1074
+
1075
+ //Check smush limit for free users
1076
+ if ( ! $WpSmush->validate_install() ) {
1077
+
1078
+ //Free version bulk smush, check the transient counter value
1079
+ $should_continue = $wpsmushit_admin->check_bulk_limit( false, 'dir_sent_count' );
1080
+
1081
+ //Send a error for the limit
1082
+ if ( ! $should_continue ) {
1083
+ wp_send_json_error(
1084
+ array(
1085
+ 'error' => 'dir_smush_limit_exceeded',
1086
+ 'continue' => false
1087
+ )
1088
+ );
1089
+ }
1090
+ }
1091
+
1092
+ $id = intval( $_GET['image_id'] );
1093
+ if ( ! $scanned_images = wp_cache_get( 'wp_smush_scanned_images' ) ) {
1094
+ $scanned_images = $this->get_scanned_images();
1095
+ }
1096
+
1097
+ $image = $this->get_image( $id, '', $scanned_images );
1098
+
1099
+ if ( empty( $image ) ) {
1100
+ //If there are no stats
1101
+ $error_msg = esc_html__( "Could not find image id in last scanned images", "wp-smushit" );
1102
+ wp_send_json_error( $error_msg );
1103
+ }
1104
+
1105
+ $path = $image['path'];
1106
+
1107
+ //We have the image path, optimise
1108
+ $smush_results = $WpSmush->do_smushit( $path );
1109
+
1110
+ if ( is_wp_error( $smush_results ) ) {
1111
+ $error_msg = $smush_results->get_error_message();
1112
+ } else if ( empty( $smush_results['data'] ) ) {
1113
+ //If there are no stats
1114
+ $error_msg = esc_html__( "Image couldn't be optimized", "wp-smushit" );
1115
+ }
1116
+
1117
+ if ( ! empty( $error_msg ) ) {
1118
+
1119
+ //Store the error in DB
1120
+ //All good, Update the stats
1121
+ $query = "UPDATE {$wpdb->prefix}smush_dir_images SET error=%s WHERE id=%d LIMIT 1";
1122
+ $query = $wpdb->prepare( $query, $error_msg, $id );
1123
+ $wpdb->query( $query );
1124
+
1125
+ $error_msg = "<div class='wp-smush-error'>" . $error_msg . "</div>";
1126
+
1127
+ wp_send_json_error(
1128
+ array(
1129
+ 'error' => $error_msg,
1130
+ 'image' => array( 'id' => $id )
1131
+ )
1132
+ );
1133
+ }
1134
+ //Get file time
1135
+ $file_time = @filectime( $path );
1136
+
1137
+ // If super-smush enabled, update supersmushed meta value also.
1138
+ $lossy = $WpSmush->lossy_enabled ? 1 : 0;
1139
+
1140
+ // All good, Update the stats.
1141
+ $query = "UPDATE {$wpdb->prefix}smush_dir_images SET image_size=%d, file_time=%d, lossy=%s WHERE id=%d LIMIT 1";
1142
+ $query = $wpdb->prepare( $query, $smush_results['data']->after_size, $file_time, $lossy, $id );
1143
+ $wpdb->query( $query );
1144
+
1145
+ // Get the global stats if current dir smush completed.
1146
+ if ( isset( $_GET['get_stats'] ) && 1 == $_GET['get_stats'] ) {
1147
+ // This will setup directory smush stats too.
1148
+ $wpsmushit_admin->setup_global_stats();
1149
+ $stats = $wpsmushit_admin->stats;
1150
+ $stats['total'] = $wpsmushit_admin->total_count;
1151
+ $resmush_count = empty( $wpsmushit_admin->resmush_ids ) ? count( $wpsmushit_admin->resmush_ids = get_option( "wp-smush-resmush-list" ) ) : count( $wpsmushit_admin->resmush_ids );
1152
+ // $stats['smushed'] = ! empty( $wpsmushit_admin->resmush_ids ) ? $wpsmushit_admin->smushed_count - $resmush_count : $wpsmushit_admin->smushed_count;
1153
+ $stats['smushed'] = $wpsmushit_admin->smushed_count;
1154
+ if ( $lossy == 1 ) {
1155
+ $stats['super_smushed'] = $wpsmushit_admin->super_smushed;
1156
+ }
1157
+ // Set tootltip text to update.
1158
+ $stats['tooltip_text'] = ! empty( $stats['total_images'] ) ? sprintf( __( "You've smushed %d images in total.", "wp-smushit" ), $stats['total_images'] ) : '';
1159
+ // Get the total dir smush stats.
1160
+ $total = $wpsmushit_admin->dir_stats;
1161
+ } else {
1162
+ $total = $this->total_stats();
1163
+ }
1164
+
1165
+ //Show the image wise stats
1166
+ $image = array(
1167
+ 'id' => $id,
1168
+ 'size_before' => $image['orig_size'],
1169
+ 'size_after' => $smush_results['data']->after_size
1170
+ );
1171
+
1172
+ $bytes = $image['size_before'] - $image['size_after'];
1173
+ $image['savings'] = size_format( $bytes, 1 );
1174
+ $image['percent'] = $image['size_before'] > 0 ? number_format_i18n( ( ( $bytes / $image['size_before'] ) * 100 ), 1 ) . '%' : 0;
1175
+
1176
+ $data = array(
1177
+ 'image' => $image,
1178
+ 'total' => $total,
1179
+ 'latest_scan' => $last_scan,
1180
+ );
1181
+
1182
+ // If current dir smush completed, include global stats.
1183
+ if ( ! empty( $stats ) ) {
1184
+ $data['stats'] = $stats;
1185
+ }
1186
+
1187
+ //Update Bulk Limit Transient
1188
+ $wpsmushit_admin->update_smush_count( 'dir_sent_count' );
1189
+
1190
+ wp_send_json_success( $data );
1191
+ }
1192
+
1193
+ /**
1194
+ * Remove image/image from db based on path details
1195
+ */
1196
+ function smush_exclude_path() {
1197
+
1198
+ //Validate Ajax nonce
1199
+ check_ajax_referer( 'wp-smush-exclude-path', 'nonce' );
1200
+
1201
+ //If we don't have path, send json error
1202
+ if ( empty( $_POST['path'] ) ) {
1203
+ wp_send_json_error( 'missing_path' );
1204
+ }
1205
+
1206
+ global $wpdb;
1207
+
1208
+ $path = realpath( $_POST['path'] );
1209
+ $table = "{$wpdb->prefix}smush_dir_images";
1210
+ if ( is_file( $path ) ) {
1211
+ $sql = sprintf( "DELETE FROM $table WHERE path='%s'", $path );
1212
+ } else {
1213
+ $sql = sprintf( "DELETE FROM $table WHERE path LIKE '%s'", '%' . $path . '%' );
1214
+ }
1215
+
1216
+ //Execute the query
1217
+ $result = $wpdb->query( $sql );
1218
+
1219
+ if ( $result ) {
1220
+ wp_send_json_success();
1221
+ } else {
1222
+ wp_send_json_error();
1223
+ }
1224
+ }
1225
+
1226
+ /**
1227
+ * Send the markup for image list scanned from a directory path
1228
+ *
1229
+ */
1230
+ function resume_scan() {
1231
+ $dir_path = get_option( 'wp-smush-dir_path' );
1232
+
1233
+ //If we don't get an error path, return an error message
1234
+ if ( empty( $dir_path ) ) {
1235
+ $message = "<div class='error'>" . esc_html__( "We were unable to retrieve the image list from last scan, please continue with a latest scan", "wp-smushit" ) . "</div>";
1236
+ wp_send_json_error( array( 'message' => $message ) );
1237
+ }
1238
+
1239
+ //Else, Get the image list and then markup
1240
+ $file_list = $this->get_image_list( $dir_path );
1241
+
1242
+ //If there are no image files in selected directory
1243
+ if ( empty( $file_list['files_arr'] ) ) {
1244
+ $this->send_error();
1245
+ }
1246
+
1247
+ $markup = $this->generate_markup( $file_list );
1248
+
1249
+ //Send response
1250
+ wp_send_json_success( $markup );
1251
+ }
1252
+
1253
+ /**
1254
+ * Combine the stats from Directory Smush and Media Library Smush
1255
+ *
1256
+ * @param $stats Directory Smush stats
1257
+ *
1258
+ * @return array Combined array of Stats
1259
+ */
1260
+ function combined_stats( $stats ) {
1261
+
1262
+ if ( empty( $stats ) || empty( $stats['percent'] ) || empty( $stats['bytes'] ) ) {
1263
+ return array();
1264
+ }
1265
+
1266
+ global $wpsmushit_admin;
1267
+
1268
+ $result = array();
1269
+ $dasharray = 125.663706144;
1270
+
1271
+ //Initialize Global Stats
1272
+ $wpsmushit_admin->setup_global_stats();
1273
+
1274
+ //Get the total/Smushed attachment count
1275
+ $total_attachments = $wpsmushit_admin->total_count + $stats['total'];
1276
+ $total_images = $wpsmushit_admin->stats['total_images'] + $stats['total'];
1277
+
1278
+ $smushed = $wpsmushit_admin->smushed_count + $stats['optimised'];
1279
+ $savings = ! empty( $wpsmushit_admin->stats ) ? $wpsmushit_admin->stats['bytes'] + $stats['bytes'] : $stats['bytes'];
1280
+ $size_before = ! empty( $wpsmushit_admin->stats ) ? $wpsmushit_admin->stats['size_before'] + $stats['orig_size'] : $stats['orig_size'];
1281
+ $percent = $size_before > 0 ? ( $savings / $size_before ) * 100 : 0;
1282
+
1283
+ //Store the stats in array
1284
+ $result = array(
1285
+ 'total_count' => $total_attachments,
1286
+ 'smushed_count' => $smushed,
1287
+ 'savings' => size_format( $savings ),
1288
+ 'percent' => round( $percent, 1 ),
1289
+ 'image_count' => $total_images,
1290
+ 'dash_offset' => $total_attachments > 0 ? $dasharray - ( $dasharray * ( $smushed / $total_attachments ) ) : $dasharray,
1291
+ 'tooltip_text' => ! empty( $total_images ) ? sprintf( __( "You've smushed %d images in total.", "wp-smushit" ), $total_images ) : ''
1292
+ );
1293
+
1294
+ return $result;
1295
+ }
1296
+
1297
+ /**
1298
+ * Returns Directory Smush stats and Cumulative stats
1299
+ *
1300
+ */
1301
+ function get_dir_smush_stats() {
1302
+
1303
+ $result = array();
1304
+
1305
+ //Store the Total/Smushed count
1306
+ $stats = $this->total_stats();
1307
+
1308
+ $result['dir_smush'] = $stats;
1309
+
1310
+ //Cumulative Stats
1311
+ $result['combined_stats'] = $this->combined_stats( $stats );
1312
+
1313
+ //Store the stats in options table
1314
+ update_option( 'dir_smush_stats', $result, false );
1315
+
1316
+ //Send ajax response
1317
+ wp_send_json_success( $result );
1318
+ }
1319
+
1320
+ }
1321
+
1322
+ //Class Object
1323
+ global $wpsmush_dir;
1324
+ $wpsmush_dir = new WpSmushDir();
1325
+ }
1326
+
1327
+ /**
1328
+ * Filters the list of directories, Exclude the Media Subfolders
1329
+ *
1330
+ */
1331
+ if ( class_exists( 'RecursiveFilterIterator' ) && ! class_exists( 'WPSmushRecursiveFilterIterator' ) ) {
1332
+ class WPSmushRecursiveFilterIterator extends RecursiveFilterIterator {
1333
+
1334
+ public function accept() {
1335
+ global $wpsmush_dir;
1336
+ $path = $this->current()->getPathname();
1337
+ if ( $this->isDir() ) {
1338
+ if ( ! $wpsmush_dir->skip_dir( $path ) ) {
1339
+ return true;
1340
+ }
1341
+ } else {
1342
+ return true;
1343
+ }
1344
+
1345
+ return false;
1346
+ }
1347
+
1348
+ }
1349
+ }
lib/class-wp-smush-helper.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Smush
4
+ * @subpackage Admin
5
+ * @version 1.0
6
+ *
7
+ * @author Umesh Kumar <umesh@incsub.com>
8
+ *
9
+ * @copyright (c) 2017, Incsub (http://incsub.com)
10
+ */
11
+
12
+
13
+ if ( ! class_exists( 'WpSmushHelper' ) ) {
14
+
15
+ class WpSmushHelper {
16
+
17
+ function __construct() {
18
+ $this->init();
19
+ }
20
+
21
+ function init() {
22
+
23
+ }
24
+
25
+ /**
26
+ * Return unfiltered file path
27
+ *
28
+ * @param $attachment_id
29
+ *
30
+ * @return bool
31
+ */
32
+ function get_attached_file( $attachment_id ) {
33
+ if ( empty( $attachment_id ) ) {
34
+ return false;
35
+ }
36
+
37
+ $file_path = get_attached_file( $attachment_id );
38
+ if ( ! empty( $file_path ) && strpos( $file_path, 's3' ) !== false ) {
39
+ $file_path = get_attached_file( $attachment_id, true );
40
+ }
41
+
42
+ return $file_path;
43
+ }
44
+
45
+ /**
46
+ * Iterate over PNG->JPG Savings to return cummulative savings for an image
47
+ *
48
+ * @param string $attachment_id
49
+ *
50
+ * @return array|bool
51
+ */
52
+ function get_pngjpg_savings( $attachment_id = '' ) {
53
+ //Initialize empty array
54
+ $savings = array(
55
+ 'bytes' => 0,
56
+ 'size_before' => 0,
57
+ 'size_after' => 0
58
+ );
59
+
60
+ //Return empty array if attaachment id not provided
61
+ if( empty( $attachment_id ) ) {
62
+ return $savings;
63
+ }
64
+
65
+ $pngjpg_savings = get_post_meta( $attachment_id, WP_SMUSH_PREFIX . 'pngjpg_savings', true );
66
+ if( empty( $pngjpg_savings ) || !is_array( $pngjpg_savings )) {
67
+ return $savings;
68
+ }
69
+
70
+ foreach ( $pngjpg_savings as $size => $s_savings ) {
71
+ if( empty( $s_savings ) ) {
72
+ continue;
73
+ }
74
+ $savings['size_before'] += $s_savings['size_before'];
75
+ $savings['size_after'] += $s_savings['size_after'];
76
+ }
77
+ $savings['bytes'] = $savings['size_before'] - $savings['size_after'];
78
+
79
+ return $savings;
80
+ }
81
+ }
82
+
83
+ global $wpsmush_helper;
84
+ $wpsmush_helper = new WpSmushHelper();
85
+
86
+ }
lib/class-wp-smush-nextgen.php CHANGED
@@ -22,7 +22,21 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
22
  var $is_nextgen_active = false;
23
 
24
  function __construct() {
 
 
 
 
25
  global $WpSmush;
 
 
 
 
 
 
 
 
 
 
26
 
27
  //Auto Smush image, if enabled, runs after Nextgen is finished uploading the image
28
  //Allows to override whether to auto smush nextgen image or not
@@ -38,7 +52,37 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
38
 
39
  //Resmush Image: Handles the single/Manual resmush image request for NextGen Gallery
40
  add_action( 'wp_ajax_smush_resmush_nextgen_image', array( $this, 'resmush_image' ) );
 
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
 
44
  /**
@@ -107,7 +151,7 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
107
  * @return bool|string
108
  */
109
  function get_file_type( $file_path ) {
110
- if ( empty( $file_path ) || !file_exists( $file_path ) ) {
111
  return false;
112
  }
113
  if ( function_exists( 'exif_imagetype' ) ) {
@@ -127,9 +171,6 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
127
  * Read the image paths from an attachment's meta data and process each image
128
  * with wp_smushit().
129
  *
130
- * This method also adds a `wp_smushit` meta key for use in the media library.
131
- * Called after `wp_generate_attachment_metadata` is completed.
132
- *
133
  * @param $meta
134
  * @param null $ID
135
  *
@@ -153,7 +194,7 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
153
  // Registry Object for NextGen Gallery
154
  $registry = C_Component_Registry::get_instance();
155
 
156
- //Gallery Storage Object
157
  $storage = $registry->get_utility( 'I_Gallery_Storage' );
158
 
159
  //File path and URL for original image
@@ -172,10 +213,16 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
172
  foreach ( $sizes as $size ) {
173
 
174
  //Skip Full size, if smush original is not checked
175
- if( 'full' == $size && !$WpSmush->smush_original ) {
176
  continue;
177
  }
178
 
 
 
 
 
 
 
179
  // We take the original image. Get the absolute path using the storage object
180
  $attachment_file_path_size = $storage->get_image_abspath( $image, $size );
181
 
@@ -218,50 +265,33 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
218
  }
219
 
220
  //If there are no stats
221
- if( empty( $response['data'] ) ) {
222
  continue;
223
  }
224
 
225
  //If the image size grew after smushing, skip it
226
- if( $response['data']->after_size > $response['data']->before_size ) {
227
  continue;
228
  }
229
 
230
  $stats['sizes'][ $size ] = (object) $WpSmush->_array_fill_placeholders( $WpSmush->_get_size_signature(), (array) $response['data'] );
231
 
232
- //Total Stats, store all data in bytes
233
- list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
234
- = $WpSmush->_update_stats_data( $response['data'], $size_before, $size_after, $total_time, $bytes_saved );
235
-
236
  if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
237
  $stats['stats']['api_version'] = $response['data']->api_version;
238
  $stats['stats']['lossy'] = $response['data']->lossy;
239
- $stats['stats']['keep_exif'] = !empty( $response['data']->keep_exif ) ? $response['data']->keep_exif : 0;
240
  }
241
  }
242
  }
243
 
244
  $has_errors = (bool) count( $errors->get_error_messages() );
245
 
246
- list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
247
- array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
248
-
249
  //Set smush status for all the images, store it in wp-smpro-smush-data
250
  if ( ! $has_errors ) {
251
 
252
  $existing_stats = ( ! empty( $image->meta_data ) && ! empty( $image->meta_data['wp_smush'] ) ) ? $image->meta_data['wp_smush'] : '';
253
 
254
  if ( ! empty( $existing_stats ) ) {
255
- $e_size_before = !empty( $existing_stats['stats']['size_before'] ) ? $existing_stats['stats']['size_before'] : '';
256
-
257
- //Store Original size before
258
- $stats['stats']['size_before'] = ( !empty($e_size_before ) && $e_size_before > $stats['stats']['size_before'] ) ? $e_size_before : $stats['stats']['size_before'];
259
-
260
- //Update total bytes saved, and compression percent
261
- $stats['stats']['bytes'] = isset( $existing_stats['stats']['bytes'] ) ? $existing_stats['stats']['bytes'] + $stats['stats']['bytes'] : $stats['stats']['bytes'];
262
-
263
- $stats['stats']['percent'] = $WpSmush->calculate_percentage( (object) $stats['stats'], (object) $existing_stats['stats'] );
264
-
265
  //Update stats for each size
266
  if ( ! empty( $existing_stats['sizes'] ) && ! empty( $stats['sizes'] ) ) {
267
 
@@ -274,30 +304,34 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
274
  }
275
  $stats['sizes'][ $size_name ] = $existing_stats['sizes'][ $size_name ];
276
  } else {
277
- $existing_stats_size = (object)$existing_stats['sizes'][ $size_name ];
278
 
279
  //store the original image size
280
  $stats['sizes'][ $size_name ]->size_before = ( ! empty( $existing_stats_size->size_before ) && $existing_stats_size->size_before > $stats['sizes'][ $size_name ]->size_before ) ? $existing_stats_size->size_before : $stats['sizes'][ $size_name ]->size_before;
281
 
282
  //Update compression percent and bytes saved for each size
283
- $stats['sizes'][ $size_name ]->bytes = $stats['sizes'][ $size_name ]->bytes + $existing_stats_size->bytes;
284
  //Calculate percentage
285
  $stats['sizes'][ $size_name ]->percent = $WpSmush->calculate_percentage( $stats['sizes'][ $size_name ], $existing_stats_size );
286
  }
287
  }
288
  }
289
  }
 
 
 
 
290
  //If there was any compression and there was no error in smushing
291
- if( isset( $stats['stats']['bytes'] ) && $stats['stats']['bytes'] >= 0 && !$has_errors ) {
292
  /**
293
  * Runs if the image smushing was successful
294
  *
295
- * @param int $ID Image Id
296
  *
297
  * @param array $stats Smush Stats for the image
298
  *
299
  */
300
- do_action('wp_smush_image_optimised_nextgen', $image->pid, $stats );
301
  }
302
  $image->meta_data['wp_smush'] = $stats;
303
  nggdb::update_image_meta( $image->pid, $image->meta_data );
@@ -314,12 +348,17 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
314
  *
315
  * @usedby: `manual_nextgen`, `auto_smush`, `smush_bulk`
316
  *
317
- * @param string $pid , NextGen Gallery Image id
318
- * @param string $image , Nextgen gallery image object
319
- * @param bool|true $echo , Whether to echo the stats or not, false for auto smush
 
 
 
320
  */
321
- function smush_image( $pid = '', $image = '', $echo = true ) {
322
- global $wpsmushnextgenstats;
 
 
323
 
324
  //Get image, if we have image id
325
  if ( ! empty( $pid ) ) {
@@ -331,11 +370,21 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
331
  $metadata = ! empty( $image ) ? $image->meta_data : '';
332
 
333
  if ( empty( $metadata ) ) {
334
- wp_send_json_error( array( 'error_msg' => esc_html__( "We couldn't find the metadata for the image, possibly the image has been deleted.", "wp-smushit" ) ) );
335
  }
336
 
 
 
 
 
 
 
 
 
 
 
337
  //smush the main image and its sizes
338
- $smush = $this->resize_from_meta_data( $image );
339
 
340
  if ( ! is_wp_error( $smush ) ) {
341
  $status = $wpsmushnextgenstats->show_stats( $pid, $smush, false, true );
@@ -353,10 +402,14 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
353
  wp_send_json_success( $status );
354
  }
355
  } else {
356
- if ( is_wp_error( $smush ) ) {
 
 
 
 
 
 
357
  return $smush;
358
- } else {
359
- return $status;
360
  }
361
  }
362
  }
@@ -508,8 +561,8 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
508
  $restored[] = @copy( $attachment_file_path . '_backup', $attachment_file_path );
509
  }
510
  //Restoring the other sizes
511
- $attachment_data = !empty( $image->meta_data['wp_smush'] ) ? $image->meta_data['wp_smush'] : '';
512
- if( !empty( $attachment_data['sizes'] ) ) {
513
  foreach ( $attachment_data['sizes'] as $size => $size_data ) {
514
  if ( 'full' == $size ) {
515
  continue;
@@ -543,7 +596,7 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
543
  //Get the Button html without wrapper
544
  $button_html = $wpsmushnextgenadmin->wp_smush_column_options( '', $image_id, false );
545
 
546
- wp_send_json_success( array('button' => $button_html ) );
547
  }
548
  wp_send_json_error( array( 'message' => '<div class="wp-smush-error">' . __( "Unable to restore image", "wp-smushit" ) . '</div>' ) );
549
  }
@@ -572,7 +625,7 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
572
  $smushed = $this->smush_image( $image_id, '', false );
573
 
574
  //If any of the image is restored, we count it as success
575
- if ( ! empty( $smushed ) && !is_wp_error( $smushed ) ) {
576
 
577
  //Send button content
578
  wp_send_json_success( array( 'button' => $smushed['status'] . $smushed['stats'] ) );
@@ -585,13 +638,208 @@ if ( ! class_exists( 'WpSmushNextGen' ) ) {
585
  }
586
  }
587
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
588
  }//End of Class
 
589
  }//End Of if class not exists
590
 
591
  //Extend NextGen Mixin class to smush dynamic images
592
  if ( class_exists( 'WpSmushNextGen' ) ) {
593
- global $WpSmush;
594
- $wpsmushnextgen = new WpSmushNextGen();
 
 
595
 
596
  //Extend Nextgen Mixin class and override the generate_image_size, to optimize dynamic thumbnails, generated by nextgen, check for auto smush
597
  if ( ! class_exists( 'WpSmushNextGenDynamicThumbs' ) && class_exists( 'Mixin' ) && $WpSmush->is_auto_smush_enabled() ) {
@@ -652,7 +900,7 @@ if ( class_exists( 'WpSmushNextGen' ) ) {
652
  $stats['size_before'] = $response['data']->before_size;
653
  $stats['time'] = $response['data']->time;
654
  }
655
- $stats['sizes'][ $size ] = (object) $WpSmush->_array_fill_placeholders( $WpSmush->_get_size_signature(), (array) $response['data'] );
656
 
657
  if ( isset( $image->metadata ) ) {
658
  $image->meta_data['wp_smush'] = $stats;
@@ -670,8 +918,8 @@ if ( class_exists( 'WpSmushNextGen' ) ) {
670
  }
671
  }
672
  }
673
- if ( class_exists('WpSmushNextGenDynamicThumbs') ) {
674
- if(! get_option('ngg_options') ) {
675
  return;
676
  }
677
  $storage = C_Gallery_Storage::get_instance();
22
  var $is_nextgen_active = false;
23
 
24
  function __construct() {
25
+ $this->init();
26
+ }
27
+
28
+ function init() {
29
  global $WpSmush;
30
+ //Filters the setting variable to add S3 setting title and description
31
+ add_filter( 'wp_smush_settings', array( $this, 'register' ), 5 );
32
+
33
+ //Filters the setting variable to add S3 setting in premium features
34
+ add_filter( 'wp_smush_pro_settings', array( $this, 'add_setting' ), 5 );
35
+
36
+ //return if not a pro user
37
+ if( !$WpSmush->validate_install() ) {
38
+ return;
39
+ }
40
 
41
  //Auto Smush image, if enabled, runs after Nextgen is finished uploading the image
42
  //Allows to override whether to auto smush nextgen image or not
52
 
53
  //Resmush Image: Handles the single/Manual resmush image request for NextGen Gallery
54
  add_action( 'wp_ajax_smush_resmush_nextgen_image', array( $this, 'resmush_image' ) );
55
+ }
56
 
57
+ /**
58
+ * Filters the setting variable to add S3 setting title and description
59
+ *
60
+ * @param $settings
61
+ *
62
+ * @return mixed
63
+ */
64
+ function register( $settings ) {
65
+ $settings['nextgen'] = array(
66
+ 'label' => esc_html__( 'Enable NextGen Gallery integration', 'wp-smushit' ),
67
+ 'desc' => esc_html__( 'Allow smushing images directly through NextGen Gallery settings.', 'wp-smushit' )
68
+ );
69
+
70
+ return $settings;
71
+ }
72
+
73
+ /**
74
+ * Append S3 in pro feature list
75
+ *
76
+ * @param $pro_settings
77
+ *
78
+ * @return array
79
+ */
80
+ function add_setting( $pro_settings ) {
81
+ if ( ! isset( $pro_settings['nextgen'] ) ) {
82
+ $pro_settings[] = 'nextgen';
83
+ }
84
+
85
+ return $pro_settings;
86
  }
87
 
88
  /**
151
  * @return bool|string
152
  */
153
  function get_file_type( $file_path ) {
154
+ if ( empty( $file_path ) || ! file_exists( $file_path ) ) {
155
  return false;
156
  }
157
  if ( function_exists( 'exif_imagetype' ) ) {
171
  * Read the image paths from an attachment's meta data and process each image
172
  * with wp_smushit().
173
  *
 
 
 
174
  * @param $meta
175
  * @param null $ID
176
  *
194
  // Registry Object for NextGen Gallery
195
  $registry = C_Component_Registry::get_instance();
196
 
197
+ //Storage Object for NextGen Gallery
198
  $storage = $registry->get_utility( 'I_Gallery_Storage' );
199
 
200
  //File path and URL for original image
213
  foreach ( $sizes as $size ) {
214
 
215
  //Skip Full size, if smush original is not checked
216
+ if ( 'full' == $size && ! $WpSmush->smush_original ) {
217
  continue;
218
  }
219
 
220
+ //Check if registered size is supposed to be converted or not
221
+ global $wpsmushit_admin;
222
+ if ( 'full' != $size && $wpsmushit_admin->skip_image_size( $size ) ) {
223
+ return false;
224
+ }
225
+
226
  // We take the original image. Get the absolute path using the storage object
227
  $attachment_file_path_size = $storage->get_image_abspath( $image, $size );
228
 
265
  }
266
 
267
  //If there are no stats
268
+ if ( empty( $response['data'] ) ) {
269
  continue;
270
  }
271
 
272
  //If the image size grew after smushing, skip it
273
+ if ( $response['data']->after_size > $response['data']->before_size ) {
274
  continue;
275
  }
276
 
277
  $stats['sizes'][ $size ] = (object) $WpSmush->_array_fill_placeholders( $WpSmush->_get_size_signature(), (array) $response['data'] );
278
 
 
 
 
 
279
  if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
280
  $stats['stats']['api_version'] = $response['data']->api_version;
281
  $stats['stats']['lossy'] = $response['data']->lossy;
282
+ $stats['stats']['keep_exif'] = ! empty( $response['data']->keep_exif ) ? $response['data']->keep_exif : 0;
283
  }
284
  }
285
  }
286
 
287
  $has_errors = (bool) count( $errors->get_error_messages() );
288
 
 
 
 
289
  //Set smush status for all the images, store it in wp-smpro-smush-data
290
  if ( ! $has_errors ) {
291
 
292
  $existing_stats = ( ! empty( $image->meta_data ) && ! empty( $image->meta_data['wp_smush'] ) ) ? $image->meta_data['wp_smush'] : '';
293
 
294
  if ( ! empty( $existing_stats ) ) {
 
 
 
 
 
 
 
 
 
 
295
  //Update stats for each size
296
  if ( ! empty( $existing_stats['sizes'] ) && ! empty( $stats['sizes'] ) ) {
297
 
304
  }
305
  $stats['sizes'][ $size_name ] = $existing_stats['sizes'][ $size_name ];
306
  } else {
307
+ $existing_stats_size = (object) $existing_stats['sizes'][ $size_name ];
308
 
309
  //store the original image size
310
  $stats['sizes'][ $size_name ]->size_before = ( ! empty( $existing_stats_size->size_before ) && $existing_stats_size->size_before > $stats['sizes'][ $size_name ]->size_before ) ? $existing_stats_size->size_before : $stats['sizes'][ $size_name ]->size_before;
311
 
312
  //Update compression percent and bytes saved for each size
313
+ $stats['sizes'][ $size_name ]->bytes = $stats['sizes'][ $size_name ]->bytes + $existing_stats_size->bytes;
314
  //Calculate percentage
315
  $stats['sizes'][ $size_name ]->percent = $WpSmush->calculate_percentage( $stats['sizes'][ $size_name ], $existing_stats_size );
316
  }
317
  }
318
  }
319
  }
320
+ //Total Stats
321
+ $stats = $WpSmush->total_compression( $stats );
322
+ $stats['total_images'] = ! empty( $stats['sizes'] ) ? count( $stats['sizes'] ) : 0;
323
+
324
  //If there was any compression and there was no error in smushing
325
+ if ( isset( $stats['stats']['bytes'] ) && $stats['stats']['bytes'] >= 0 && ! $has_errors ) {
326
  /**
327
  * Runs if the image smushing was successful
328
  *
329
+ * @param int $ID Image Id
330
  *
331
  * @param array $stats Smush Stats for the image
332
  *
333
  */
334
+ do_action( 'wp_smush_image_optimised_nextgen', $image->pid, $stats );
335
  }
336
  $image->meta_data['wp_smush'] = $stats;
337
  nggdb::update_image_meta( $image->pid, $image->meta_data );
348
  *
349
  * @usedby: `manual_nextgen`, `auto_smush`, `smush_bulk`
350
  *
351
+ * @param string $pid NextGen Gallery Image id
352
+ * @param string $image Nextgen gallery image object
353
+ * @param bool $echo Whether to echo the stats or not, false for auto smush
354
+ * @param bool $is_bulk Whether it's called by bulk smush or not
355
+ *
356
+ * @return mixed Stats / Status / Error
357
  */
358
+ function smush_image( $pid = '', $image = '', $echo = true, $is_bulk = false ) {
359
+ global $wpsmushnextgenstats, $WpSmush;
360
+
361
+ $WpSmush->initialise();
362
 
363
  //Get image, if we have image id
364
  if ( ! empty( $pid ) ) {
370
  $metadata = ! empty( $image ) ? $image->meta_data : '';
371
 
372
  if ( empty( $metadata ) ) {
373
+ wp_send_json_error( array( 'error_msg' => '<p class="wp-smush-error-message">' . esc_html__( "We couldn't find the metadata for the image, possibly the image has been deleted.", "wp-smushit" ) . '</p>' ) );
374
  }
375
 
376
+ $registry = C_Component_Registry::get_instance();
377
+ $storage = $registry->get_utility( 'I_Gallery_Storage' );
378
+
379
+ //Perform Resizing
380
+ $metadata = $this->resize_image( $pid, $image, $metadata, $storage );
381
+
382
+ //Store Meta
383
+ $image->meta_data = $metadata;
384
+ nggdb::update_image_meta( $image->pid, $image->meta_data );
385
+
386
  //smush the main image and its sizes
387
+ $smush = $this->resize_from_meta_data( $image, $registry, $storage );
388
 
389
  if ( ! is_wp_error( $smush ) ) {
390
  $status = $wpsmushnextgenstats->show_stats( $pid, $smush, false, true );
402
  wp_send_json_success( $status );
403
  }
404
  } else {
405
+ if( ! $is_bulk ) {
406
+ if ( is_wp_error( $smush ) ) {
407
+ return $smush;
408
+ } else {
409
+ return $status;
410
+ }
411
+ }else{
412
  return $smush;
 
 
413
  }
414
  }
415
  }
561
  $restored[] = @copy( $attachment_file_path . '_backup', $attachment_file_path );
562
  }
563
  //Restoring the other sizes
564
+ $attachment_data = ! empty( $image->meta_data['wp_smush'] ) ? $image->meta_data['wp_smush'] : '';
565
+ if ( ! empty( $attachment_data['sizes'] ) ) {
566
  foreach ( $attachment_data['sizes'] as $size => $size_data ) {
567
  if ( 'full' == $size ) {
568
  continue;
596
  //Get the Button html without wrapper
597
  $button_html = $wpsmushnextgenadmin->wp_smush_column_options( '', $image_id, false );
598
 
599
+ wp_send_json_success( array( 'button' => $button_html ) );
600
  }
601
  wp_send_json_error( array( 'message' => '<div class="wp-smush-error">' . __( "Unable to restore image", "wp-smushit" ) . '</div>' ) );
602
  }
625
  $smushed = $this->smush_image( $image_id, '', false );
626
 
627
  //If any of the image is restored, we count it as success
628
+ if ( ! empty( $smushed ) && ! is_wp_error( $smushed ) ) {
629
 
630
  //Send button content
631
  wp_send_json_success( array( 'button' => $smushed['status'] . $smushed['stats'] ) );
638
  }
639
  }
640
 
641
+ /**
642
+ * Get file extension from file path
643
+ *
644
+ * @param string $file_path Absolute image path to get the mime for
645
+ *
646
+ * @return string Null/ Mime Type
647
+ *
648
+ */
649
+ function get_file_ext( $file_path = '' ) {
650
+ if ( empty( $file_path ) ) {
651
+ return '';
652
+ }
653
+
654
+ if ( class_exists( 'finfo' ) ) {
655
+ $finfo = new finfo( FILEINFO_MIME_TYPE );
656
+ } else {
657
+ $finfo = false;
658
+ }
659
+
660
+ if ( $finfo ) {
661
+ $ext = file_exists( $file_path ) ? $finfo->file( $file_path ) : '';
662
+ } elseif ( function_exists( 'mime_content_type' ) ) {
663
+ $ext = mime_content_type( $file_path );
664
+ } else {
665
+ $ext = '';
666
+ }
667
+
668
+ return $ext;
669
+ }
670
+
671
+ /**
672
+ * Optionally resize a NextGen image
673
+ *
674
+ * @param $attachment_id Gallery Image id
675
+ * @param $image Image object for NextGen gallery
676
+ * @param $meta Image meta from nextgen gallery
677
+ * @param $storage Storage object for nextgen gallery
678
+ *
679
+ * @return mixed
680
+ */
681
+ function resize_image( $attachment_id, $image, $meta, $storage ) {
682
+ global $wpsmush_resize, $wpsmushit_admin;
683
+ if ( empty( $attachment_id ) || empty( $meta ) || ! is_object( $storage ) ) {
684
+ return $meta;
685
+ }
686
+
687
+ //Initialize resize class
688
+ $wpsmush_resize->initialize();
689
+
690
+ //If resizing not enabled, or if both max width and height is set to 0, return
691
+ if ( ! $wpsmush_resize->resize_enabled || ( $wpsmush_resize->max_w == 0 && $wpsmush_resize->max_h == 0 ) ) {
692
+ return $meta;
693
+ }
694
+
695
+ $file_path = $storage->get_image_abspath( $image );
696
+ if ( ! file_exists( $file_path ) ) {
697
+ return $meta;
698
+ }
699
+
700
+ $ext = $this->get_file_ext( $file_path );
701
+
702
+ $mime_supported = in_array( $ext, $wpsmushit_admin->mime_types );
703
+
704
+ //If type of upload doesn't matches the criteria return
705
+ if ( ! empty( $mime ) && ! $mime_supported = apply_filters( 'wp_smush_resmush_mime_supported', $mime_supported, $mime ) ) {
706
+ return $meta;
707
+ }
708
+
709
+ //If already resized
710
+ if ( ! empty( $meta['wp_smush_resize_savings'] ) ) {
711
+ return $meta;
712
+ }
713
+
714
+ $sizes = $storage->get_image_sizes();
715
+
716
+ $should_resize = true;
717
+
718
+ /**
719
+ * Filter whether the NextGen image should be resized or not
720
+ *
721
+ * @since 2.3
722
+ *
723
+ * @param bool $should_resize
724
+ *
725
+ * @param object NextGen Gallery image object
726
+ *
727
+ * @param array NextGen Gallery image object
728
+ *
729
+ * @param string $context The type of upload action. Values include 'upload' or 'sideload'.
730
+ *
731
+ */
732
+ if ( ! $should_resize = apply_filters( 'wp_smush_resize_nextgen_image', $should_resize, $image, $meta ) ) {
733
+ return $meta;
734
+ }
735
+
736
+ $original_file_size = filesize( $file_path );
737
+
738
+ $resized = $wpsmush_resize->perform_resize( $file_path, $original_file_size, $attachment_id, '', false );
739
+
740
+ //If resize wasn't successful
741
+ if ( ! $resized || $resized['filesize'] == $original_file_size ) {
742
+ //Unlink Image, if other size path is not similar
743
+ $this->maybe_unlink( $file_path, $sizes, $image, $storage );
744
+
745
+ return $meta;
746
+ } else {
747
+
748
+ //Else Replace the Original file with resized file
749
+ $replaced = @copy( $resized['file_path'], $file_path );
750
+ $this->maybe_unlink( $resized['file_path'], $sizes, $image, $storage );
751
+ }
752
+
753
+ if ( $replaced ) {
754
+ //Updated File size
755
+ $u_file_size = filesize( $file_path );
756
+
757
+ $savings['bytes'] = $original_file_size > $u_file_size ? $original_file_size - $u_file_size : 0;
758
+ $savings['size_before'] = $original_file_size;
759
+ $savings['size_after'] = $u_file_size;
760
+
761
+ //Store savings in meta data
762
+ if ( ! empty( $savings ) ) {
763
+ $meta['wp_smush_resize_savings'] = $savings;
764
+ }
765
+
766
+ //Update dimensions of the image in meta
767
+ $meta['width'] = ! empty( $resized['width'] ) ? $resized['width'] : $meta['width'];
768
+ $meta['full']['width'] = ! empty( $resized['width'] ) ? $resized['width'] : $meta['width'];
769
+
770
+ $meta['height'] = ! empty( $resized['height'] ) ? $resized['height'] : $meta['height'];
771
+ $meta['full']['height'] = ! empty( $resized['height'] ) ? $resized['height'] : $meta['height'];
772
+
773
+ /**
774
+ * Called after the image has been successfully resized
775
+ * Can be used to update the stored stats
776
+ */
777
+ do_action( 'wp_smush_image_nextgen_resized', $attachment_id, array( 'stats' => $savings ) );
778
+
779
+ /**
780
+ * Called after the image has been successfully resized
781
+ * Can be used to update the stored stats
782
+ */
783
+ do_action( 'wp_smush_image_resized', $attachment_id, $savings );
784
+ }
785
+
786
+ return $meta;
787
+
788
+ }
789
+
790
+ /**
791
+ * Unlinks a file if none of the thumbnails have same file path
792
+ *
793
+ * @param $path Full path of the file to be unlinked
794
+ * @param $sizes All the available image sizes for the image
795
+ * @param $image Image object to fetch the full path of all the sizes
796
+ * @param $storage Gallery storage object
797
+ *
798
+ * @return bool Whether the file was unlinked or not
799
+ *
800
+ */
801
+ function maybe_unlink( $path, $sizes, $image, $storage ) {
802
+ if ( empty( $path ) || ! is_object( $storage ) || ! is_object( $image ) ) {
803
+ return false;
804
+ }
805
+
806
+ //Unlink directly if meta value is not specified
807
+ if ( empty( $sizes ) ) {
808
+ @unlink( $path );
809
+ }
810
+
811
+ $unlink = true;
812
+
813
+ //Check if the file name is similar to one of the image sizes
814
+ $path_parts = pathinfo( $path );
815
+
816
+ $filename = ! empty( $path_parts['basename'] ) ? $path_parts['basename'] : $path_parts['filename'];
817
+ foreach ( $sizes as $image_size ) {
818
+ $file_path_size = $storage->get_image_abspath( $image, $image_size );
819
+ if ( false === strpos( $file_path_size, $filename ) ) {
820
+ continue;
821
+ }
822
+ $unlink = false;
823
+ }
824
+
825
+ //Unlink the file
826
+ if ( $unlink ) {
827
+ @unlink( $path );
828
+ }
829
+
830
+ return $unlink;
831
+ }
832
+
833
  }//End of Class
834
+
835
  }//End Of if class not exists
836
 
837
  //Extend NextGen Mixin class to smush dynamic images
838
  if ( class_exists( 'WpSmushNextGen' ) ) {
839
+ global $WpSmush, $wpsmushnextgen;
840
+ if ( ! is_object( $wpsmushnextgen ) ) {
841
+ $wpsmushnextgen = new WpSmushNextGen();
842
+ }
843
 
844
  //Extend Nextgen Mixin class and override the generate_image_size, to optimize dynamic thumbnails, generated by nextgen, check for auto smush
845
  if ( ! class_exists( 'WpSmushNextGenDynamicThumbs' ) && class_exists( 'Mixin' ) && $WpSmush->is_auto_smush_enabled() ) {
900
  $stats['size_before'] = $response['data']->before_size;
901
  $stats['time'] = $response['data']->time;
902
  }
903
+ $stats['sizes'][ $size ] = (object) $WpSmush->_array_fill_placeholders( $WpSmush->_get_size_signature(), (array) $response['data'] );
904
 
905
  if ( isset( $image->metadata ) ) {
906
  $image->meta_data['wp_smush'] = $stats;
918
  }
919
  }
920
  }
921
+ if ( class_exists( 'WpSmushNextGenDynamicThumbs' ) ) {
922
+ if ( ! get_option( 'ngg_options' ) ) {
923
  return;
924
  }
925
  $storage = C_Gallery_Storage::get_instance();
lib/class-wp-smush-png_jpg.php ADDED
@@ -0,0 +1,706 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Smush
4
+ *
5
+ * @version 2.4
6
+ *
7
+ * @author Umesh Kumar <umesh@incsub.com>
8
+ *
9
+ * @copyright (c) 2016, Incsub (http://incsub.com)
10
+ */
11
+ if ( ! class_exists( 'WpSmushPngtoJpg' ) ) {
12
+
13
+ class WpSmushPngtoJpg {
14
+
15
+ var $is_transparent = false;
16
+
17
+ /**
18
+ * Check if Imagick is available or not
19
+ *
20
+ * @return bool True/False Whether Imagick is available or not
21
+ *
22
+ */
23
+ function supports_imagick() {
24
+ if ( ! class_exists( 'Imagick' ) ) {
25
+ return false;
26
+ }
27
+
28
+ return true;
29
+ }
30
+
31
+ /**
32
+ * Check if GD is loaded
33
+ *
34
+ * @return bool True/False Whether GD is available or not
35
+ *
36
+ */
37
+ function supports_GD() {
38
+ if ( ! function_exists( 'gd_info' ) ) {
39
+ return false;
40
+ }
41
+
42
+ return true;
43
+ }
44
+
45
+ /**
46
+ * Checks if the Given PNG file is transparent or not
47
+ *
48
+ * @param string $id Attachment id
49
+ * @param string $file
50
+ *
51
+ * @return bool|int
52
+ */
53
+ function is_transparent( $id = '', $file = '' ) {
54
+
55
+ global $wpsmush_helper;
56
+
57
+ //No attachment id/ file path, return
58
+ if ( empty( $id ) && empty( $file ) ) {
59
+ return false;
60
+ }
61
+
62
+ if ( empty( $file ) ) {
63
+ $file = $wpsmush_helper->get_attached_file( $id );
64
+ }
65
+
66
+ //Check if File exists
67
+ if ( empty( $file ) || ! file_exists( $file ) ) {
68
+ return false;
69
+ }
70
+
71
+ $transparent = '';
72
+
73
+ //Try to get transparency using Imagick
74
+ if ( $this->supports_imagick() ) {
75
+ try {
76
+ $im = new Imagick( $file );
77
+
78
+ return $im->getImageAlphaChannel();
79
+ } catch ( Exception $e ) {
80
+ error_log( "Imagick: Error in checking PNG transparency " . $e->getMessage() );
81
+ }
82
+ } else {
83
+ //Simple check
84
+ //Src: http://camendesign.com/code/uth1_is-png-32bit
85
+ if ( ord( file_get_contents( $file, false, null, 25, 1 ) ) & 4 ) {
86
+ return true;
87
+ }
88
+ //Src: http://www.jonefox.com/blog/2011/04/15/how-to-detect-transparency-in-png-images/
89
+ $contents = file_get_contents( $file );
90
+ if ( stripos( $contents, 'PLTE' ) !== false && stripos( $contents, 'tRNS' ) !== false ) {
91
+ return true;
92
+ }
93
+
94
+ //If both the conditions failed, that means not transparent
95
+ return false;
96
+
97
+ }
98
+
99
+ //If Imagick is installed, and the code exited due to some error
100
+ //Src: StackOverflow
101
+ if ( empty( $transparent ) && $this->supports_GD() ) {
102
+ //Check for transparency using GD
103
+ $i = imagecreatefrompng( $file );
104
+ $palette = ( imagecolortransparent( $i ) < 0 );
105
+ if ( $palette ) {
106
+ return true;
107
+ }
108
+ }
109
+
110
+ return false;
111
+
112
+ }
113
+
114
+ /**
115
+ * Check whether to convert the PNG to JPG or not
116
+ *
117
+ * @param $id Attachment ID
118
+ * @param $file File path for the attachment
119
+ *
120
+ * @return bool Whether to convert the PNG or not
121
+ *
122
+ */
123
+ function should_convert( $id, $file ) {
124
+
125
+ global $wpsmush_settings;
126
+
127
+ $should_convert = false;
128
+
129
+ //Get the Transparency conversion settings
130
+ $convert_png = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'png_to_jpg', false );
131
+
132
+ if ( ! $convert_png ) {
133
+ return $should_convert;
134
+ }
135
+
136
+ //Whether to convert transparent images or not
137
+ $transparent_settings = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'transparent_png', false );
138
+
139
+ $convert_transparent = $transparent_settings['convert'];
140
+
141
+ /** Transparency Check */
142
+ $this->is_transparent = $this->is_transparent( $id, $file );
143
+
144
+ //If we are suppose to convert transaprent images, skip is transparent check
145
+ if ( $convert_transparent || !$this->is_transparent ) {
146
+ $should_convert = true;
147
+ }
148
+
149
+ return $should_convert;
150
+ }
151
+
152
+ /**
153
+ * Check if given attachment id can be converted to JPEG or not
154
+ *
155
+ * @param string $id Atachment id
156
+ *
157
+ * @param string $id
158
+ * @param string $size
159
+ * @param string $mime
160
+ * @param string $file
161
+ *
162
+ * @return bool True/False Can be converted or not
163
+ */
164
+ function can_be_converted( $id = '', $size = 'full', $mime = '', $file = '' ) {
165
+
166
+ if ( empty( $id ) ) {
167
+ return false;
168
+ }
169
+
170
+ //False if not a PNG
171
+ $mime = empty( $mime ) ? get_post_mime_type( $id ) : $mime;
172
+ if ( 'image/png' != $mime ) {
173
+ return false;
174
+ }
175
+
176
+ /** Return if Imagick and GD is not available **/
177
+ if ( ! $this->supports_imagick() && ! $this->supports_GD() ) {
178
+ return false;
179
+ }
180
+
181
+ //If already tried the conversion
182
+ if ( get_post_meta( $id, WP_SMUSH_PREFIX . 'pngjpg_savings', true ) ) {
183
+ return false;
184
+ }
185
+
186
+ //Check if registered size is supposed to be converted or not
187
+ global $wpsmushit_admin, $wpsmush_helper;
188
+ if ( 'full' != $size && $wpsmushit_admin->skip_image_size( $size ) ) {
189
+ return false;
190
+ }
191
+
192
+ if ( empty( $file ) ) {
193
+ $file = $wpsmush_helper->get_attached_file( $id );
194
+ }
195
+
196
+ /** Whether to convert to jpg or not **/
197
+ $should_convert = $this->should_convert( $id, $file );
198
+
199
+ /**
200
+ * Filter whether to convert the PNG to JPG or not
201
+ *
202
+ * @since 2.4
203
+ *
204
+ * @param bool $should_convert Current choice for image conversion
205
+ *
206
+ * @param int $id Attachment id
207
+ *
208
+ * @param string $file File path for the image
209
+ *
210
+ * @param string $size Image size being converted
211
+ *
212
+ */
213
+ $should_convert = apply_filters( 'wp_smush_convert_to_jpg', $should_convert, $id, $file, $size );
214
+
215
+ return $should_convert;
216
+
217
+ }
218
+
219
+ /**
220
+ * Update the image URL, MIME Type, Attached File, file path in Meta, URL in post content
221
+ *
222
+ * @param $id Attachment ID
223
+ * @param $o_file Original File Path that has to be replaced
224
+ * @param $n_file New File Path which replaces the old file
225
+ * @param $meta Attachment Meta
226
+ * @param $size_k Image Size
227
+ * @param $o_type Operation Type "conversion", "restore"
228
+ *
229
+ * @return mixed Attachment Meta with updated file path
230
+ *
231
+ */
232
+ function update_image_path( $id, $o_file, $n_file, $meta, $size_k, $o_type = 'conversion' ) {
233
+
234
+ global $wpsmush_settings;
235
+
236
+ //Upload Directory
237
+ $upload_dir = wp_upload_dir();
238
+
239
+ //Upload Path
240
+ $upload_path = trailingslashit( $upload_dir['basedir'] );
241
+
242
+ $dir_name = pathinfo( $o_file, PATHINFO_DIRNAME );
243
+
244
+ //Full Path to new file
245
+ $n_file_path = path_join( $dir_name, $n_file );
246
+
247
+ //Current URL for image
248
+ $o_url = wp_get_attachment_url( $id );
249
+
250
+ //Update URL for image size
251
+ if ( 'full' != $size_k ) {
252
+ $base_url = dirname( $o_url );
253
+ $o_url = $base_url . '/' . basename( $o_file );
254
+ }
255
+
256
+ //Update File path, Attached File, GUID
257
+ $meta = empty( $meta ) ? wp_get_attachment_metadata( $id ) : $meta;
258
+
259
+ //Get the File mime
260
+ if ( class_exists( 'finfo' ) ) {
261
+ $finfo = new finfo( FILEINFO_MIME_TYPE );
262
+ } else {
263
+ $finfo = false;
264
+ }
265
+
266
+ if ( $finfo ) {
267
+ $mime = file_exists( $n_file_path ) ? $finfo->file( $n_file_path ) : '';
268
+ } elseif ( function_exists( 'mime_content_type' ) ) {
269
+ $mime = mime_content_type( $n_file_path );
270
+ } else {
271
+ $mime = false;
272
+ }
273
+
274
+ //Update File Path, Attached file, Mime Type for Image
275
+ if ( 'full' == $size_k ) {
276
+ if ( ! empty( $meta ) ) {
277
+ $new_file = str_replace( $upload_path, '', $n_file_path );
278
+ $meta['file'] = $new_file;
279
+ }
280
+ //Update Attached File
281
+ update_attached_file( $id, $meta['file'] );
282
+
283
+ //Update Mime type
284
+ wp_update_post( array(
285
+ 'ID' => $id,
286
+ 'post_mime_type' => $mime
287
+ )
288
+ );
289
+ } else {
290
+ $meta['sizes'][ $size_k ]['file'] = basename( $n_file );
291
+ $meta['sizes'][ $size_k ]['mime-type'] = $mime;
292
+ }
293
+
294
+ if ( 'full' == $size_k ) {
295
+ //Get the updated image URL
296
+ $n_url = wp_get_attachment_url( $id );
297
+ } else {
298
+ $n_url = dirname( $o_url ) . '/' . basename( $n_file );
299
+ }
300
+
301
+ //Update In Post Content
302
+ global $wpdb;
303
+ $query = $wpdb->prepare( "UPDATE $wpdb->posts SET post_content = REPLACE(post_content, '%s', '%s');", $o_url, $n_url );
304
+ $wpdb->query( $query );
305
+
306
+ //Delete the Original files if backup not enabled
307
+ if ( 'conversion' == $o_type && ! $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'backup' ) ) {
308
+ @unlink( $o_file );
309
+ }
310
+
311
+ return $meta;
312
+ }
313
+
314
+ function update_stats( $id = '', $savings = '' ) {
315
+ if ( empty( $id ) || empty( $savings ) ) {
316
+ return false;
317
+ }
318
+
319
+ }
320
+
321
+ /**
322
+ * Replace the file if there are savings, and return savings
323
+ *
324
+ * @param string $file Original File Path
325
+ * @param array $result Array structure
326
+ * @param string $n_file Updated File path
327
+ *
328
+ * @return array
329
+ */
330
+ function replace_file( $file = '', $result = array(), $n_file = '' ) {
331
+
332
+ if ( empty( $file ) || empty( $n_file ) ) {
333
+ return $result;
334
+ }
335
+
336
+ //Get the file size of original image
337
+ $o_file_size = filesize( $file );
338
+
339
+ $n_file = path_join( dirname( $file ), $n_file );
340
+
341
+ $n_file_size = filesize( $n_file );
342
+
343
+ //If there aren't any savings return
344
+ if ( $n_file_size >= $o_file_size ) {
345
+ //Delete the JPG image and return
346
+ @unlink( $n_file );
347
+
348
+ return $result;
349
+ }
350
+
351
+ //Get the savings
352
+ $savings = $o_file_size - $n_file_size;
353
+
354
+ //Store Stats
355
+ $savings = array(
356
+ 'bytes' => $savings,
357
+ 'size_before' => $o_file_size,
358
+ 'size_after' => $n_file_size
359
+ );
360
+
361
+ $result['savings'] = $savings;
362
+
363
+ return $result;
364
+ }
365
+
366
+ /**
367
+ * Perform the conversion process, using WordPress Image Editor API
368
+ *
369
+ * @param $id Attachment Id
370
+ * @param $file Attachment File path
371
+ * @param $meta Attachment meta
372
+ * @param $size Image size, default empty for full image
373
+ *
374
+ * @return array $result array(
375
+ * 'meta' => array Update Attachment metadata
376
+ * 'savings' => Reduction of Image size in bytes
377
+ * )
378
+ *
379
+ */
380
+ function convert_to_jpg( $id = '', $file = '', $meta = '', $size = 'full' ) {
381
+
382
+ $result = array(
383
+ 'meta' => $meta,
384
+ 'savings' => ''
385
+ );
386
+
387
+ //Flag: Whether the image was converted or not
388
+ if ( 'full' == $size ) {
389
+ $result['converted'] = false;
390
+ }
391
+
392
+ //If any of the values is not set
393
+ if ( empty( $id ) || empty( $file ) || empty( $meta ) ) {
394
+ return $result;
395
+ }
396
+
397
+ $editor = wp_get_image_editor( $file );
398
+
399
+ if ( is_wp_error( $editor ) ) {
400
+ //Use custom method maybe
401
+ return $result;
402
+ }
403
+
404
+ $n_file = pathinfo( $file );
405
+
406
+ if ( ! empty( $n_file['filename'] ) && $n_file['dirname'] ) {
407
+ //Get a unique File name
408
+ $n_file['filename'] = wp_unique_filename( $n_file['dirname'], $n_file['filename'] . '.jpg' );
409
+ $n_file = path_join( $n_file['dirname'], $n_file['filename'] );
410
+ } else {
411
+ return $result;
412
+ }
413
+
414
+ //Save PNG as JPG
415
+ $new_image_info = $editor->save( $n_file, 'image/jpeg' );
416
+
417
+ //If image editor was unable to save the image, return
418
+ if ( is_wp_error( $new_image_info ) ) {
419
+ return $result;
420
+ }
421
+
422
+ $n_file = ! empty( $new_image_info ) ? $new_image_info['file'] : '';
423
+
424
+ //Replace file, and get savings
425
+ $result = $this->replace_file( $file, $result, $n_file );
426
+
427
+ if ( ! empty( $result['savings'] ) ) {
428
+ if ( 'full' == $size ) {
429
+ $result['converted'] = true;
430
+ }
431
+ //Update the File Details. and get updated meta
432
+ $result['meta'] = $this->update_image_path( $id, $file, $n_file, $meta, $size );
433
+
434
+ /**
435
+ * Perform a action after the image URL is updated in post content
436
+ */
437
+ do_action( 'wp_smush_image_url_changed', $id, $file, $n_file, $size );
438
+ }
439
+
440
+ return $result;
441
+ }
442
+
443
+ /**
444
+ * Convert a PNG to JPG, Lossless Conversion, if we have any savings
445
+ *
446
+ * @param string $id
447
+ * @param string $meta
448
+ *
449
+ * @uses WpSmushBackup::add_to_image_backup_sizes()
450
+ *
451
+ * @return mixed|string
452
+ *
453
+ * @todo: Save cummulative savings
454
+ */
455
+ function png_to_jpg( $id = '', $meta = '' ) {
456
+ global $wpsmush_backup, $WpSmush;
457
+
458
+ // If we don't have meta or ID, or if not a premium user.
459
+ if ( empty( $id ) || empty( $meta ) || ! $WpSmush->validate_install() ) {
460
+ return $meta;
461
+ }
462
+
463
+ global $wpsmush_helper;
464
+
465
+ $file = $wpsmush_helper->get_attached_file( $id );
466
+
467
+ /** Whether to convert to jpg or not **/
468
+ $should_convert = $this->can_be_converted( $id );
469
+
470
+ if ( ! $should_convert ) {
471
+ return $meta;
472
+ }
473
+
474
+ $result['meta'] = $meta;
475
+
476
+ if ( ! $this->is_transparent ) {
477
+ //Perform the conversion, and update path
478
+ $result = $this->convert_to_jpg( $id, $file, $result['meta'] );
479
+ } else {
480
+ $result = $this->convert_tpng_to_jpg( $id, $file, $result['meta'] );
481
+ }
482
+
483
+ $savings['full'] = ! empty( $result['savings'] ) ? $result['savings'] : '';
484
+
485
+ //If original image was converted and other sizes are there for the image, Convert all other image sizes
486
+ if ( $result['converted'] ) {
487
+ if ( ! empty( $meta['sizes'] ) ) {
488
+ foreach ( $meta['sizes'] as $size_k => $data ) {
489
+
490
+ $s_file = path_join( dirname( $file ), $data['file'] );
491
+
492
+ /** Whether to convert to jpg or not **/
493
+ $should_convert = $this->can_be_converted( $id, $size_k, 'image/png', $s_file );
494
+
495
+ //Perform the conversion
496
+ if ( ! $should_convert ) {
497
+ continue;
498
+ }
499
+
500
+ //Perform the conversion, and update path
501
+ if ( ! $this->is_transparent ) {
502
+ //Perform the conversion, and update path
503
+ $result = $this->convert_to_jpg( $id, $s_file, $result['meta'], $size_k );
504
+ } else {
505
+ $result = $this->convert_tpng_to_jpg( $id, $s_file, $result['meta'], $size_k );
506
+ }
507
+ if( !empty( $result['savings'] ) ) {
508
+ $savings[ $size_k ] = $result['savings'];
509
+ }
510
+ }
511
+ }
512
+
513
+ //Save the original File URL
514
+ $o_file = ! empty( $file ) ? $file : get_post_meta( $id, '_wp_attached_file', true );
515
+ $wpsmush_backup->add_to_image_backup_sizes( $id, $o_file, 'smush_png_path' );
516
+
517
+ /**
518
+ * Do action, if the PNG to JPG conversion was successful
519
+ */
520
+ do_action( 'wp_smush_png_jpg_converted', $id, $meta, $savings );
521
+ }
522
+
523
+ //Update the Final Stats
524
+ update_post_meta( $id, WP_SMUSH_PREFIX . 'pngjpg_savings', $savings );
525
+
526
+ return $result['meta'];
527
+
528
+ }
529
+
530
+ /**
531
+ * Convert a transparent PNG to JPG, with specified background color
532
+ *
533
+ * @param string $id Attachment ID
534
+ * @param string $file File Path Original Image
535
+ * @param string $meta Attachment Meta
536
+ * @param string $size Image size. set to 'full' by default
537
+ *
538
+ * @return array Savings and Updated Meta
539
+ */
540
+ function convert_tpng_to_jpg( $id = '', $file = '', $meta = '', $size = 'full' ) {
541
+
542
+ global $wpsmush_settings;
543
+
544
+ $result = array(
545
+ 'meta' => $meta,
546
+ 'savings' => ''
547
+ );
548
+
549
+ //Flag: Whether the image was converted or not
550
+ if ( 'full' == $size ) {
551
+ $result['converted'] = false;
552
+ }
553
+
554
+ //If any of the values is not set
555
+ if ( empty( $id ) || empty( $file ) || empty( $meta ) ) {
556
+ return $result;
557
+ }
558
+
559
+ //Get the File name without ext
560
+ $n_file = pathinfo( $file );
561
+
562
+ if ( empty( $n_file['dirname'] ) || empty( $n_file['filename'] ) ) {
563
+ return $result;
564
+ }
565
+
566
+ $n_file['filename'] = wp_unique_filename( $n_file['dirname'], $n_file['filename'] . '.jpg' );
567
+
568
+ //Updated File name
569
+ $n_file = path_join( $n_file['dirname'], $n_file['filename'] );
570
+
571
+ $transparent_png = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'transparent_png' );
572
+
573
+ /**
574
+ * Filter Background Color for Transparent PNGs
575
+ */
576
+ $bg = apply_filters( 'wp_smush_bg', $transparent_png['background'], $id, $size );
577
+
578
+ $quality = $this->get_quality( $file );
579
+
580
+ if ( $this->supports_imagick() ) {
581
+ try {
582
+ $imagick = new Imagick( $file );
583
+ $imagick->setImageBackgroundColor( new ImagickPixel( '#' . $bg ) );
584
+ $imagick->setImageAlphaChannel( 11 );
585
+ $imagick->setImageFormat( 'JPG' );
586
+ $imagick->setCompressionQuality( $quality );
587
+ $imagick->writeImage( $n_file );
588
+ } catch ( Exception $e ) {
589
+ error_log( "WP Smush PNG to JPG Conversion error in " . __FILE__ . " at " . __LINE__ . " " . $e->getMessage() );
590
+
591
+ return $result;
592
+ }
593
+ } else {
594
+ //Use GD for conversion
595
+ //Get data from PNG
596
+ $input = imagecreatefrompng( $file );
597
+
598
+ //Width and Height of image
599
+ list( $width, $height ) = getimagesize( $file );
600
+
601
+ //Create New image
602
+ $output = imagecreatetruecolor( $width, $height );
603
+
604
+ // set background color for GD
605
+ $r = hexdec( '0x' . strtoupper( substr( $bg, 0, 2 ) ) );
606
+ $g = hexdec( '0x' . strtoupper( substr( $bg, 2, 2 ) ) );
607
+ $b = hexdec( '0x' . strtoupper( substr( $bg, 4, 2 ) ) );
608
+
609
+ //Set the Background color
610
+ $rgb = imagecolorallocate( $output, $r, $g, $b );
611
+
612
+ //Fill Background
613
+ imagefilledrectangle( $output, 0, 0, $width, $height, $rgb );
614
+
615
+ //Create New image
616
+ imagecopy( $output, $input, 0, 0, 0, 0, $width, $height );
617
+
618
+ //Create JPG
619
+ imagejpeg( $output, $n_file, $quality );
620
+ }
621
+
622
+ //Replace file, and get savings
623
+ $result = $this->replace_file( $file, $result, $n_file );
624
+
625
+ if ( ! empty( $result['savings'] ) ) {
626
+ if ( 'full' == $size ) {
627
+ $result['converted'] = true;
628
+ }
629
+ //Update the File Details. and get updated meta
630
+ $result['meta'] = $this->update_image_path( $id, $file, $n_file, $meta, $size );
631
+
632
+ /**
633
+ * Perform a action after the image URL is updated in post content
634
+ */
635
+ do_action( 'wp_smush_image_url_changed', $id, $file, $n_file, $size );
636
+ }
637
+
638
+ return $result;
639
+ }
640
+
641
+ /**
642
+ * Get JPG quality from WordPress Image Editor
643
+ *
644
+ * @param $file
645
+ *
646
+ * @return int Quality for JPEG images
647
+ *
648
+ */
649
+ function get_quality( $file ) {
650
+ if ( empty( $file ) ) {
651
+ return 82;
652
+ }
653
+ $editor = wp_get_image_editor( $file );
654
+
655
+ if ( ! is_wp_error( $editor ) ) {
656
+
657
+ $quality = $editor->get_quality();
658
+ }
659
+
660
+ //Choose the default quaity if we didn't get it
661
+ if ( ! $quality || $quality < 1 || $quality > 100 ) {
662
+ //The default quality
663
+ $quality = 82;
664
+ }
665
+
666
+ return $quality;
667
+
668
+ }
669
+
670
+ /**
671
+ * Check whether the given attachment was converted from PNG to JPG
672
+ *
673
+ * @param string $id
674
+ *
675
+ * @return bool True/False Whether the image was converted from PNG or not
676
+ *
677
+ */
678
+ function is_converted( $id = '' ) {
679
+ if ( empty( $id ) ) {
680
+ return false;
681
+ }
682
+ //Get the original file path and check if it exists
683
+ $original_file = get_post_meta( $id, WP_SMUSH_PREFIX . 'original_file', true );
684
+
685
+ //If original file path is not stored, then it wasn't converted or was restored to original
686
+ if ( empty( $original_file ) ) {
687
+ return false;
688
+ }
689
+ //Upload Directory
690
+ $upload_dir = wp_upload_dir();
691
+
692
+ //Upload Path
693
+ $upload_path = trailingslashit( $upload_dir['basedir'] );
694
+
695
+ //If file exists return true
696
+ if ( file_exists( path_join( $upload_path, $original_file ) ) ) {
697
+ return true;
698
+ }
699
+
700
+ return false;
701
+ }
702
+ }
703
+
704
+ global $wpsmush_pngjpg;
705
+ $wpsmush_pngjpg = new WpSmushPngtoJpg();
706
+ }
lib/class-wp-smush-resize.php ADDED
@@ -0,0 +1,391 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Smush
4
+ * @subpackage Admin
5
+ * @version 2.3
6
+ *
7
+ * @author Umesh Kumar <umesh@incsub.com>
8
+ *
9
+ * @copyright (c) 2016, Incsub (http://incsub.com)
10
+ */
11
+ if ( ! class_exists( 'WpSmushResize' ) ) {
12
+
13
+ /**
14
+ * Class WpSmushResize
15
+ */
16
+ class WpSmushResize {
17
+
18
+ /**
19
+ * @var int Specified width for resizing images
20
+ *
21
+ */
22
+ public $max_w = 0;
23
+
24
+ /**
25
+ * @var int Specified Height for resizing images
26
+ *
27
+ */
28
+ public $max_h = 0;
29
+
30
+ /**
31
+ * @var bool If resizing is enabled or not
32
+ */
33
+ public $resize_enabled = false;
34
+
35
+ function __construct() {
36
+ /**
37
+ * Initialize class variables, after all stuff has been loaded
38
+ */
39
+ add_action( 'admin_init', array( $this, 'initialize' ) );
40
+
41
+ }
42
+
43
+ /**
44
+ * Get the settings for resizing
45
+ *
46
+ * @param bool $skip_check Added for Mobile APP uploads
47
+ */
48
+ function initialize( $skip_check = false ) {
49
+
50
+ //Do not initialize unless in the WP Backend Or On one of the smush pages
51
+ if ( ! is_user_logged_in() || ( ! is_admin() && ! $skip_check ) ) {
52
+ return;
53
+ }
54
+
55
+ global $wpsmush_settings, $wpsmushit_admin;
56
+ $current_screen = get_current_screen();
57
+
58
+ if ( ! empty( $current_screen ) && ! $skip_check ) {
59
+ //Do not Proceed if not on one of the required screens
60
+ $current_page = $current_screen->base;
61
+ if ( ! in_array( $current_page, $wpsmushit_admin->pages ) ) {
62
+ return;
63
+ }
64
+ }
65
+
66
+ //If resizing is enabled
67
+ $this->resize_enabled = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'resize' );
68
+
69
+ $resize_sizes = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'resize_sizes', array() );
70
+
71
+ //Resize width and Height
72
+ $this->max_w = ! empty( $resize_sizes['width'] ) ? $resize_sizes['width'] : 0;
73
+ $this->max_h = ! empty( $resize_sizes['height'] ) ? $resize_sizes['height'] : 0;
74
+ }
75
+
76
+ /**
77
+ * Check whether Image should be resized or not
78
+ * @param string $id Attachment ID
79
+ * @param string $meta Attachment Metadata
80
+ *
81
+ * @return bool Should resize or not
82
+ *
83
+ */
84
+ public function should_resize( $id = '', $meta = '' ) {
85
+
86
+ global $wpsmush_helper;
87
+
88
+ //If resizing not enabled, or if both max width and height is set to 0, return
89
+ if ( ! $this->resize_enabled || ( $this->max_w == 0 && $this->max_h == 0 ) ) {
90
+ return false;
91
+ }
92
+
93
+ $file_path = $wpsmush_helper->get_attached_file( $id );
94
+
95
+ if ( ! empty( $file_path ) ) {
96
+
97
+ // Skip: if "noresize" is included in the filename, Thanks to Imsanity
98
+ if ( strpos( $file_path, 'noresize' ) !== false ) {
99
+ return false;
100
+ }
101
+
102
+ //If file doesn't exists, return
103
+ if ( ! file_exists( $file_path ) ) {
104
+ return false;
105
+ }
106
+
107
+ }
108
+
109
+ //Check for a supported mime type
110
+ global $wpsmushit_admin, $wpsmush_settings;
111
+
112
+ //Get image mime type
113
+ $mime = get_post_mime_type( $id );
114
+
115
+ $mime_supported = in_array( $mime, $wpsmushit_admin->mime_types );
116
+
117
+ //If type of upload doesn't matches the criteria return
118
+ if ( ! empty( $mime ) && ! $mime_supported = apply_filters( 'wp_smush_resmush_mime_supported', $mime_supported, $mime ) ) {
119
+ return false;
120
+ }
121
+
122
+ //Check if already resized
123
+ $resize_meta = get_post_meta( $id, WP_SMUSH_PREFIX . 'resize_savings', true );
124
+ if ( ! empty( $resize_meta ) ) {
125
+ return false;
126
+ }
127
+
128
+ //Get attachment metadata
129
+ $meta = empty( $meta ) ? wp_get_attachment_metadata( $id ) : $meta;
130
+
131
+ if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) {
132
+ $oldW = $meta['width'];
133
+ $oldH = $meta['height'];
134
+
135
+ $resize_dim = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'resize_sizes' );
136
+
137
+ $maxW = ! empty( $resize_dim['width'] ) ? $resize_dim['width'] : 0;
138
+ $maxH = ! empty( $resize_dim['height'] ) ? $resize_dim['height'] : 0;
139
+
140
+ if ( ( $oldW > $maxW && $maxW > 0 ) || ( $oldH > $maxH && $maxH > 0 ) ) {
141
+ return true;
142
+ }
143
+ }
144
+
145
+ return false;
146
+ }
147
+
148
+ /**
149
+ * Handles the Auto resizing of new uploaded images
150
+ *
151
+ * @param $id Attachment ID
152
+ * @param $meta Attachment Metadata
153
+ *
154
+ * @return mixed Updated/Original Metadata if image was resized or not
155
+ */
156
+ function auto_resize( $id, $meta ) {
157
+
158
+ if ( empty( $id ) || ! wp_attachment_is_image( $id ) ) {
159
+ return $meta;
160
+ }
161
+
162
+ //Do not perform resize while restoring images/ Editing images
163
+ if ( ! empty( $_REQUEST['do'] ) && ( 'restore' == $_REQUEST['do'] || 'scale' == $_REQUEST['do'] ) ) {
164
+ return $meta;
165
+ }
166
+
167
+ global $wpsmush_helper;
168
+
169
+ $savings = array(
170
+ 'bytes' => 0,
171
+ 'size_before' => 0,
172
+ 'size_after' => 0
173
+ );
174
+
175
+ //Check if the image should be resized or not
176
+ $should_resize = $this->should_resize( $id, $meta );
177
+
178
+ /**
179
+ * Filter whether the uploaded image should be resized or not
180
+ *
181
+ * @since 2.3
182
+ *
183
+ * @param bool $should_resize
184
+ *
185
+ * @param array $upload {
186
+ * Array of upload data.
187
+ *
188
+ * @type string $file Filename of the newly-uploaded file.
189
+ * @type string $url URL of the uploaded file.
190
+ * @type string $type File type.
191
+ * }
192
+ *
193
+ * @param string $context The type of upload action. Values include 'upload' or 'sideload'.
194
+ *
195
+ */
196
+ if ( ! $should_resize = apply_filters( 'wp_smush_resize_uploaded_image', $should_resize, $id, $meta ) ) {
197
+ return $meta;
198
+ }
199
+
200
+ //Good to go
201
+ $file_path = $wpsmush_helper->get_attached_file( $id );
202
+
203
+ $original_file_size = filesize( $file_path );
204
+
205
+ $resize = $this->perform_resize( $file_path, $original_file_size, $id, $meta );
206
+
207
+ //If resize wasn't successful
208
+ if ( ! $resize || $resize['filesize'] >= $original_file_size ) {
209
+ update_post_meta( $id, WP_SMUSH_PREFIX . 'resize_savings', $savings );
210
+ return $meta;
211
+ }
212
+
213
+ //Else Replace the Original file with resized file
214
+ $replaced = $this->replcae_original_image( $file_path, $resize, $id, $meta );
215
+
216
+ if ( $replaced ) {
217
+ //Clear Stat Cache, Else the size obtained is same as the original file size
218
+ clearstatcache();
219
+
220
+ //Updated File size
221
+ $u_file_size = filesize( $file_path );
222
+
223
+ $savings['bytes'] = $original_file_size > $u_file_size ? $original_file_size - $u_file_size : 0;
224
+ $savings['size_before'] = $original_file_size;
225
+ $savings['size_after'] = $u_file_size;
226
+
227
+ //Store savings in meta data
228
+ if ( ! empty( $savings ) ) {
229
+ update_post_meta( $id, WP_SMUSH_PREFIX . 'resize_savings', $savings );
230
+ }
231
+
232
+ $meta['width'] = ! empty( $resize['width'] ) ? $resize['width'] : $meta['width'];
233
+ $meta['height'] = ! empty( $resize['height'] ) ? $resize['height'] : $meta['height'];
234
+
235
+ /**
236
+ * Called after the image has been successfully resized
237
+ * Can be used to update the stored stats
238
+ */
239
+ do_action( 'wp_smush_image_resized', $id, $savings );
240
+
241
+ }
242
+
243
+ return $meta;
244
+
245
+ }
246
+
247
+ /**
248
+ * Generates the new image for specified width and height,
249
+ * Checks if the size of generated image is greater,
250
+ *
251
+ * @param $file_path Original File path
252
+ * @param $original_file_size File size before optimisation
253
+ * @param $id Attachment ID
254
+ * @param string $meta Attachment Metadata
255
+ * @param bool $unlink Whether to unlink the original image or not
256
+ *
257
+ * @return array|bool|false If the image generation was successful
258
+ */
259
+ function perform_resize( $file_path, $original_file_size, $id, $meta = '', $unlink = true ) {
260
+
261
+ /**
262
+ * Filter the resize image dimensions
263
+ *
264
+ * @since 2.3
265
+ *
266
+ * @param array $sizes {
267
+ * Array of sizes containing max width and height for all the uploaded images.
268
+ *
269
+ * @type int $width Maximum Width For resizing
270
+ * @type int $height Maximum Height for resizing
271
+ * }
272
+ *
273
+ * @param string $file_path Original Image file path
274
+ *
275
+ * @param array $upload {
276
+ * Array of upload data.
277
+ *
278
+ * @type string $file Filename of the newly-uploaded file.
279
+ * @type string $url URL of the uploaded file.
280
+ * @type string $type File type.
281
+ * }
282
+ *
283
+ */
284
+ $sizes = apply_filters( 'wp_smush_resize_sizes', array(
285
+ 'width' => $this->max_w,
286
+ 'height' => $this->max_h
287
+ ), $file_path, $id );
288
+
289
+ $data = image_make_intermediate_size( $file_path, $sizes['width'], $sizes['height'] );
290
+
291
+ //If the image wasn't resized
292
+ if ( empty( $data['file'] ) || is_wp_error( $data ) ) {
293
+ return false;
294
+ }
295
+
296
+ //Check if file size is lesser than original image
297
+ $resize_path = path_join( dirname( $file_path ), $data['file'] );
298
+ if ( ! file_exists( $resize_path ) ) {
299
+ return false;
300
+ }
301
+
302
+ $data['file_path'] = $resize_path;
303
+
304
+ $file_size = filesize( $resize_path );
305
+ $data['filesize'] = $file_size;
306
+ if ( $file_size > $original_file_size ) {
307
+ //Don't Unlink for nextgen images
308
+ if ( $unlink ) {
309
+ $this->maybe_unlink( $resize_path, $meta );
310
+ }
311
+ }
312
+
313
+ return $data;
314
+ }
315
+
316
+ /**
317
+ * Replace the original file with resized file
318
+ *
319
+ * @param $file_path
320
+ * @param $resized
321
+ * @param string $attachment_id
322
+ * @param string $meta
323
+ *
324
+ * @return bool
325
+ */
326
+ function replcae_original_image( $file_path, $resized, $attachment_id = '', $meta = '' ) {
327
+
328
+ $replaced = @copy( $resized['file_path'], $file_path );
329
+ $this->maybe_unlink( $resized['file_path'], $meta );
330
+
331
+ return $replaced;
332
+ }
333
+
334
+ /**
335
+ * @param $filename
336
+ *
337
+ * @return mixed
338
+ */
339
+ function file_name( $filename ) {
340
+ if ( empty( $filename ) ) {
341
+ return $filename;
342
+ }
343
+
344
+ return $filename . 'tmp';
345
+ }
346
+
347
+ /**
348
+ * Do not unlink the resized file if the name is similar to one of the image sizes
349
+ *
350
+ * @param $path Image File Path
351
+ * @param $meta Image Meta
352
+ *
353
+ * @return bool
354
+ */
355
+ function maybe_unlink( $path, $meta ) {
356
+ if ( empty( $path ) ) {
357
+ return true;
358
+ }
359
+
360
+ //Unlink directly if meta value is not specified
361
+ if ( empty( $meta['sizes'] ) ) {
362
+ @unlink( $path );
363
+ }
364
+
365
+ $unlink = true;
366
+ //Check if the file name is similar to one of the image sizes
367
+ $path_parts = pathinfo( $path );
368
+ $filename = ! empty( $path_parts['basename'] ) ? $path_parts['basename'] : $path_parts['filename'];
369
+ if ( ! empty( $meta['sizes'] ) ) {
370
+ foreach ( $meta['sizes'] as $image_size ) {
371
+ if ( false === strpos( $image_size['file'], $filename ) ) {
372
+ continue;
373
+ }
374
+ $unlink = false;
375
+ }
376
+ }
377
+ if ( $unlink ) {
378
+ @unlink( $path );
379
+ }
380
+
381
+ return true;
382
+
383
+ }
384
+ }
385
+
386
+ /**
387
+ * Initialise class
388
+ */
389
+ global $wpsmush_resize;
390
+ $wpsmush_resize = new WpSmushResize();
391
+ }
lib/class-wp-smush-s3.php ADDED
@@ -0,0 +1,377 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Smush
4
+ * @subpackage S3
5
+ * @version 2.7
6
+ *
7
+ * @author Umesh Kumar <umesh@incsub.com>
8
+ *
9
+ * @copyright (c) 2017, Incsub (http://incsub.com)
10
+ */
11
+ if ( ! class_exists( 'WpSmushS3' ) ) {
12
+
13
+ class WpSmushS3 {
14
+
15
+ private $setup_error = '';
16
+
17
+ function __construct() {
18
+ $this->init();
19
+ }
20
+
21
+ function init() {
22
+
23
+ global $WpSmush;
24
+
25
+ //Filters the setting variable to add S3 setting title and description
26
+ add_filter( 'wp_smush_settings', array( $this, 'register' ), 6 );
27
+
28
+ //Filters the setting variable to add S3 setting in premium features
29
+ add_filter( 'wp_smush_pro_settings', array( $this, 'add_setting' ), 6 );
30
+
31
+ //return if not a pro user
32
+ if ( ! $WpSmush->validate_install() ) {
33
+ return;
34
+ }
35
+ $this->check_client();
36
+
37
+ //Check if the file exists for the given path and download
38
+ add_action( 'smush_file_exists', array( $this, 'maybe_download_file' ), 10, 3 );
39
+
40
+ //Check if the backup file exists
41
+ add_filter( 'smush_backup_exists', array( $this, 'backup_exists_on_s3' ), 10, 3 );
42
+
43
+
44
+ }
45
+
46
+ /**
47
+ * Filters the setting variable to add S3 setting title and description
48
+ *
49
+ * @param $settings
50
+ *
51
+ * @return mixed
52
+ */
53
+ function register( $settings ) {
54
+ $plugin_url = esc_url( "https://wordpress.org/plugins/amazon-s3-and-cloudfront/" );
55
+ $settings['s3'] = array(
56
+ 'label' => esc_html__( 'Amazon S3 support', 'wp-smushit' ),
57
+ 'desc' => sprintf( esc_html__( 'Optimize your images stored on Amazon S3. This feature uses the %sWP Offload S3%s plugin and is needed if the option %sRemove Files From Server%s is enabled. Images will be smushed as per your current settings.', 'wp-smushit' ), "<a href='" . $plugin_url . "' target = '_blank'>", "</a>", "<b>", "</b>" )
58
+ );
59
+
60
+ return $settings;
61
+ }
62
+
63
+ /**
64
+ * Append S3 in pro feature list
65
+ *
66
+ * @param $pro_settings
67
+ *
68
+ * @return array
69
+ */
70
+ function add_setting( $pro_settings ) {
71
+
72
+ if ( ! isset( $pro_settings['s3'] ) ) {
73
+ $pro_settings[] = 's3';
74
+ }
75
+
76
+ return $pro_settings;
77
+ }
78
+
79
+ /**
80
+ * Check if WP S3 Offload is configured properly or not
81
+ *
82
+ * If not, hook at the end of setting row to show a error message
83
+ */
84
+ function check_client() {
85
+
86
+ global $as3cf, $WpSmush, $wpsmush_settings;
87
+ $show_error = false;
88
+ //If S3 integration is not enabled, return
89
+ $setting_m_key = WP_SMUSH_PREFIX . 's3';
90
+ $setting_val = $WpSmush->validate_install() ? $wpsmush_settings->get_setting( $setting_m_key, false ) : 0;
91
+
92
+ if ( ! $setting_val ) {
93
+ return;
94
+ }
95
+
96
+ //Check if plugin is setup or not
97
+ //In case for some reason, we couldn't find the function
98
+ if ( ! is_object( $as3cf ) || ! method_exists( $as3cf, 'is_plugin_setup' ) ) {
99
+ $show_error = true;
100
+ $support_url = esc_url( "https://premium.wpmudev.org/contact" );
101
+ $this->setup_error = sprintf( esc_html__( "We are having trouble interacting with WP S3 Offload, make sure the plugin is activated. Or you can %sreport a bug%s.", "wp-smushit" ), '<a href="' . $support_url . '" target="_blank">', '</a>' );
102
+ }
103
+
104
+ //Plugin is not setup, or some information is missing
105
+ if ( ! $as3cf->is_plugin_setup() ) {
106
+ $show_error = true;
107
+ $configure_url = $as3cf->get_plugin_page_url();
108
+ $this->setup_error = sprintf( esc_html__( "It seems you haven't finished setting up WP S3 Offload yet, %sConfigure%s it now to enable Amazon S3 support.", "wp-smushit" ), "<a href='" . $configure_url . "' target='_blank'>", "</a>" );
109
+ }
110
+ //Return Early if we don't need to do anything
111
+ if ( ! $show_error ) {
112
+ return;
113
+ }
114
+ //Hook at the end of setting row to output a error div
115
+ add_action( 'smush_setting_row_end', array( $this, 's3_setup_error' ) );
116
+
117
+ }
118
+
119
+ /**
120
+ * Prints the error message if any
121
+ *
122
+ * @return null
123
+ */
124
+ function s3_setup_error( $setting_key ) {
125
+ if ( empty( $this->setup_error ) || 's3' != $setting_key ) {
126
+ return null;
127
+ }
128
+ echo "<div class='wp-smush-notice smush-s3-setup-error'><i class='dev-icon wdv-icon wdv-icon-fw wdv-icon-exclamation-sign'></i><p>$this->setup_error</p></div>";
129
+ }
130
+
131
+ /**
132
+ * Checks if the given attachment is on S3 or not, Returns S3 URL or WP Error
133
+ *
134
+ * @param $attachment_id
135
+ *
136
+ * @return bool|false|string
137
+ *
138
+ */
139
+ function is_image_on_s3( $attachment_id = '' ) {
140
+ global $as3cf;
141
+ if ( empty( $attachment_id ) ) {
142
+ return false;
143
+ }
144
+
145
+ //If we only have the attachment id
146
+ $full_url = $as3cf->is_attachment_served_by_s3( $attachment_id );
147
+ //If the filepath contains S3, get the s3 URL for the file
148
+ if ( ! empty( $full_url ) ) {
149
+ $full_url = $as3cf->get_attachment_url( $attachment_id );
150
+ } else {
151
+ $full_url = false;
152
+ }
153
+
154
+ return $full_url;
155
+
156
+ }
157
+
158
+ /**
159
+ * Download a specified file to local server with respect to provided attachment id
160
+ * and/or Attachment path
161
+ *
162
+ * @param $attachment_id
163
+ *
164
+ * @param array $size_details
165
+ *
166
+ * @param string $uf_file_path
167
+ *
168
+ * @return string|bool Returns file path or false
169
+ *
170
+ */
171
+ function download_file( $attachment_id, $size_details = array(), $uf_file_path = '' ) {
172
+ global $WpSmush, $wpsmush_settings;
173
+ if ( empty( $attachment_id ) || ! $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 's3', false ) || ! $WpSmush->validate_install() ) {
174
+ return false;
175
+ }
176
+
177
+ global $as3cf;
178
+ $renamed = $s3_object = $s3_url = $file = false;
179
+
180
+ //If file path wasn't specified in argument
181
+ $uf_file_path = empty( $uf_file_path ) ? get_attached_file( $attachment_id, true ) : $uf_file_path;
182
+
183
+ //If we have plugin method available, us that otherwise check it ourselves
184
+ if ( method_exists( $as3cf, 'is_attachment_served_by_s3' ) ) {
185
+ $s3_object = $as3cf->is_attachment_served_by_s3( $attachment_id );
186
+ $size_prefix = dirname( $s3_object['key'] );
187
+ $size_file_prefix = ( '.' === $size_prefix ) ? '' : $size_prefix . '/';
188
+ if ( ! empty( $size_details ) && is_array( $size_details ) ) {
189
+ $s3_object['key'] = path_join( $size_file_prefix, $size_details['file'] );
190
+ } elseif ( ! empty( $uf_file_path ) ) {
191
+ //Get the File path using basename for given attachment path
192
+ $s3_object['key'] = path_join( $size_file_prefix, wp_basename( $uf_file_path ) );
193
+ }
194
+
195
+ //Try to download the attachment
196
+ if ( $s3_object && is_object( $as3cf->plugin_compat ) && method_exists( $as3cf->plugin_compat, 'copy_s3_file_to_server' ) ) {
197
+ //Download file
198
+ $file = $as3cf->plugin_compat->copy_s3_file_to_server( $s3_object, $uf_file_path );
199
+ }
200
+
201
+ if ( $file ) {
202
+ return $file;
203
+ }
204
+ }
205
+
206
+ //If we don't have the file, Try it the basic way
207
+ if ( ! $file ) {
208
+ $s3_url = $this->is_image_on_s3( $attachment_id );
209
+
210
+ //If we couldn't get the image URL, return false
211
+ if ( is_wp_error( $s3_url ) || empty( $s3_url ) || ! $s3_url ) {
212
+ return false;
213
+ }
214
+
215
+ if ( ! empty( $size_details ) ) {
216
+ //If size details are available, Update the URL to get the image for the specified size
217
+ $s3_url = str_replace( wp_basename( $s3_url ), $size_details['file'], $s3_url );
218
+ } elseif ( ! empty( $uf_file_path ) ) {
219
+ //Get the File path using basename for given attachment path
220
+ $s3_url = str_replace( wp_basename( $s3_url ), wp_basename( $uf_file_path ), $s3_url );
221
+ }
222
+
223
+ //Download the file
224
+ $temp_file = download_url( $s3_url );
225
+ if ( ! is_wp_error( $temp_file ) ) {
226
+ $renamed = @copy( $temp_file, $uf_file_path );
227
+ unlink( $temp_file );
228
+ }
229
+
230
+ //If we were able to successfully rename the file, return file path
231
+ if ( $renamed ) {
232
+
233
+ return $uf_file_path;
234
+ }
235
+ }
236
+
237
+ return false;
238
+ }
239
+
240
+ /**
241
+ * Check if file exists for the given path
242
+ *
243
+ * @param string $attachment_id
244
+ * @param string $file_path
245
+ *
246
+ * @return bool
247
+ */
248
+ function does_image_exists( $attachment_id = '', $file_path = '' ) {
249
+ global $as3cf;
250
+ if ( empty( $attachment_id ) || empty( $file_path ) ) {
251
+ return false;
252
+ }
253
+ //Return if method doesn't exists
254
+ if ( ! method_exists( $as3cf, 'is_attachment_served_by_s3' ) ) {
255
+ error_log( "Couldn't find method is_attachment_served_by_s3." );
256
+
257
+ return false;
258
+ }
259
+ //Get s3 object for the file
260
+ $s3_object = $as3cf->is_attachment_served_by_s3( $attachment_id );
261
+
262
+ $size_prefix = dirname( $s3_object['key'] );
263
+ $size_file_prefix = ( '.' === $size_prefix ) ? '' : $size_prefix . '/';
264
+
265
+ //Get the File path using basename for given attachment path
266
+ $s3_object['key'] = path_join( $size_file_prefix, wp_basename( $file_path ) );
267
+
268
+ //Get bucket details
269
+ $bucket = $as3cf->get_setting( 'bucket' );
270
+ $region = $as3cf->get_setting( 'region' );
271
+
272
+ if ( is_wp_error( $region ) ) {
273
+ return false;
274
+ }
275
+
276
+ $s3client = $as3cf->get_s3client( $region );
277
+
278
+ $file_exists = $s3client->doesObjectExist( $bucket, $s3_object['key'] );
279
+ return $file_exists;
280
+ }
281
+
282
+ /**
283
+ * Check if the file is served by S3 and download the file for given path
284
+ *
285
+ * @param string $file_path Full file path
286
+ * @param string $attachment_id
287
+ * @param array $size_details Array of width and height for the image
288
+ *
289
+ * @return bool|string False/ File Path
290
+ */
291
+ function maybe_download_file( $file_path = '', $attachment_id = '', $size_details = array() ) {
292
+ if ( empty( $file_path ) || empty( $attachment_id ) ) {
293
+ return false;
294
+ }
295
+ //Download if file not exists and served by S3
296
+ if ( ! file_exists( $file_path ) && $this->is_image_on_s3( $attachment_id ) ) {
297
+ return $this->download_file( $attachment_id, $size_details, $file_path );
298
+ }
299
+
300
+ return false;
301
+ }
302
+
303
+ /**
304
+ * Checks if we've backup on S3 for the given attachment id and backup path
305
+ *
306
+ * @param string $attachment_id
307
+ * @param string $backup_path
308
+ *
309
+ * @return bool
310
+ */
311
+ function backup_exists_on_s3( $exists, $attachment_id = '', $backup_path = '' ) {
312
+ //If the file is on S3, Check if backup image object exists
313
+ if ( $this->is_image_on_s3( $attachment_id ) ) {
314
+ return $this->does_image_exists( $attachment_id, $backup_path );
315
+ }
316
+
317
+ return $exists;
318
+ }
319
+ }
320
+
321
+ global $wpsmush_s3;
322
+ $wpsmush_s3 = new WpSmushS3();
323
+
324
+ }
325
+
326
+ if ( class_exists( 'AS3CF_Plugin_Compatibility' ) && ! class_exists( 'wp_smush_s3_compat' ) ) {
327
+ class wp_smush_s3_compat extends AS3CF_Plugin_Compatibility {
328
+
329
+ function __construct() {
330
+ $this->init();
331
+ }
332
+
333
+ function init() {
334
+ //Plugin Compatibility with Amazon S3
335
+ add_filter( 'as3cf_get_attached_file', array( $this, 'smush_download_file' ), 11, 4 );
336
+ }
337
+
338
+ /**
339
+ * Download the attached file from S3 to local server
340
+ *
341
+ * @param $url
342
+ * @param $file
343
+ * @param $attachment_id
344
+ * @param $s3_object
345
+ */
346
+ function smush_download_file( $url, $file, $attachment_id, $s3_object ) {
347
+
348
+ global $as3cf, $wpsmush_settings, $WpSmush;
349
+
350
+ //Return if integration is disabled, or not a pro user
351
+ if ( ! $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 's3', false ) || ! $WpSmush->validate_install() ) {
352
+ return $url;
353
+ }
354
+
355
+ //If we already have the local file at specified path
356
+ if ( file_exists( $file ) ) {
357
+ return $url;
358
+ }
359
+
360
+ //Download image for Manual and Bulk Smush
361
+ $action = ! empty( $_GET['action'] ) ? $_GET['action'] : '';
362
+ if ( empty( $action ) || ! in_array( $action, array( 'wp_smushit_manual', 'wp_smushit_bulk' ) ) ) {
363
+ return $url;
364
+ }
365
+
366
+ //If the plugin compat object is not available, or the method has been updated
367
+ if ( ! is_object( $as3cf->plugin_compat ) || ! method_exists( $as3cf->plugin_compat, 'copy_image_to_server_on_action' ) ) {
368
+ return $url;
369
+ }
370
+
371
+ $as3cf->plugin_compat->copy_image_to_server_on_action( $action, true, $url, $file, $s3_object );
372
+ }
373
+ }
374
+
375
+ global $wpsmush_s3_compat;
376
+ $wpsmush_s3_compat = new wp_smush_s3_compat();
377
+ }
lib/class-wp-smush-settings.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! class_exists( 'WpSmushSettings' ) ) {
4
+ class WpSmushSettings {
5
+
6
+ function __construct() {
7
+ }
8
+
9
+ /**
10
+ * Check if form is submitted and process it
11
+ *
12
+ * @return null
13
+ */
14
+ function process_options() {
15
+
16
+ if ( ! is_user_logged_in() ) {
17
+ return false;
18
+ }
19
+
20
+ global $wpsmushit_admin, $wpsmush_settings;
21
+
22
+ //Store that we need not redirect again on plugin activation
23
+ update_site_option( 'wp-smush-hide_smush_welcome', true );
24
+
25
+ // var to temporarily assign the option value
26
+ $setting = null;
27
+
28
+ //Store Option Name and their values in an array
29
+ $settings = array();
30
+
31
+ //Save whether to use the settings networkwide or not ( Only if in network admin )
32
+ if ( ! empty( $_POST['action'] ) && 'save_settings' == $_POST['action'] ) {
33
+ if ( ! isset( $_POST['wp-smush-networkwide'] ) ) {
34
+ //Save the option to disable nwtwork wide settings and return
35
+ update_site_option( WP_SMUSH_PREFIX . 'networkwide', 0 );
36
+ } else {
37
+ //Save the option to disable nwtwork wide settings and return
38
+ update_site_option( WP_SMUSH_PREFIX . 'networkwide', 1 );
39
+ }
40
+ }
41
+
42
+ // process each setting and update options
43
+ foreach ( $wpsmushit_admin->settings as $name => $text ) {
44
+
45
+ // formulate the index of option
46
+ $opt_name = WP_SMUSH_PREFIX . $name;
47
+
48
+ // get the value to be saved
49
+ $setting = isset( $_POST[ $opt_name ] ) ? 1 : 0;
50
+
51
+ $settings[ $opt_name ] = $setting;
52
+
53
+ // update the new value
54
+ $wpsmush_settings->update_setting( $opt_name, $setting );
55
+
56
+ // unset the var for next loop
57
+ unset( $setting );
58
+ }
59
+
60
+ //Save the selected image sizes
61
+ $image_sizes = ! empty( $_POST['wp-smush-image_sizes'] ) ? $_POST['wp-smush-image_sizes'] : array();
62
+ $image_sizes = array_filter( array_map( "sanitize_text_field", $image_sizes ) );
63
+ $wpsmush_settings->update_setting( WP_SMUSH_PREFIX . 'image_sizes', $image_sizes );
64
+
65
+ //Update Resize width and height settings if set
66
+ $resize_sizes['width'] = isset( $_POST['wp-smush-resize_width'] ) ? intval( $_POST['wp-smush-resize_width'] ) : 0;
67
+ $resize_sizes['height'] = isset( $_POST['wp-smush-resize_height'] ) ? intval( $_POST['wp-smush-resize_height'] ) : 0;
68
+
69
+ // update the resize sizes
70
+ $wpsmush_settings->update_setting( WP_SMUSH_PREFIX . 'resize_sizes', $resize_sizes );
71
+
72
+ //Store the option in table
73
+ $wpsmush_settings->update_setting( 'wp-smush-settings_updated', 1 );
74
+
75
+ //Delete Show Resmush option
76
+ if ( isset( $_POST['wp-smush-keep_exif'] ) && ! isset( $_POST['wp-smush-original'] ) && ! isset( $_POST['wp-smush-lossy'] ) ) {
77
+ //@todo: Update Resmush ids
78
+ }
79
+
80
+ }
81
+
82
+ /**
83
+ * Checks whether the settings are applicable for the whole network/site or Sitewise ( Multisite )
84
+ * @todo: Check in subdirectory installation as well
85
+ */
86
+ function is_network_enabled() {
87
+ //If Single site return true
88
+ if ( ! is_multisite() ) {
89
+ return true;
90
+ }
91
+
92
+ //Check if the settings are network wide or site wise
93
+ $networkwide = get_site_option( WP_SMUSH_PREFIX . 'networkwide', true );
94
+ if ( $networkwide ) {
95
+ return true;
96
+ }
97
+
98
+ return false;
99
+ }
100
+
101
+ /**
102
+ * Returns the value of given setting key, based on if network settings are enabled or not
103
+ *
104
+ * @param string $name Setting to fetch
105
+ * @param string $default Default Value
106
+ *
107
+ * @return bool|mixed|void
108
+ *
109
+ */
110
+ function get_setting( $name = '', $default = '' ) {
111
+
112
+ if( empty( $name ) ) {
113
+ return false;
114
+ }
115
+
116
+ return $this->is_network_enabled() ? get_site_option( $name, $default ) : get_option( $name, $default );
117
+ }
118
+
119
+ /**
120
+ * Update value for given setting key
121
+ *
122
+ * @param string $name Key
123
+ * @param string $value Value
124
+ *
125
+ * @return bool If the setting was updated or not
126
+ */
127
+ function update_setting( $name = '', $value = '' ) {
128
+
129
+ if( empty( $name ) ) {
130
+ return false;
131
+ }
132
+
133
+ return $this->is_network_enabled() ? update_site_option( $name, $value ) : update_option( $name, $value );
134
+ }
135
+
136
+ /**
137
+ * Delete the given key name
138
+ *
139
+ * @param string $name Key
140
+ *
141
+ * @return bool If the setting was updated or not
142
+ */
143
+ function delete_setting( $name = '' ) {
144
+
145
+ if( empty( $name ) ) {
146
+ return false;
147
+ }
148
+
149
+ return $this->is_network_enabled() ? delete_site_option( $name ) : delete_option( $name );
150
+ }
151
+
152
+ }
153
+ global $wpsmush_settings;
154
+ $wpsmush_settings = new WpSmushSettings();
155
+ }
lib/class-wp-smush-share.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Smush
4
+ *
5
+ * @version 2.4
6
+ *
7
+ * @author Umesh Kumar <umesh@incsub.com>
8
+ *
9
+ * @copyright (c) 2016, Incsub (http://incsub.com)
10
+ */
11
+ if ( ! class_exists( 'WpSmushShare' ) ) {
12
+
13
+ class WpSmushShare {
14
+ function __construct() {}
15
+
16
+ function share_widget() {
17
+ global $wpsmushit_admin;
18
+ $savings = $wpsmushit_admin->stats;
19
+
20
+ //If there is any saving, greater than 1Mb, show stats
21
+ if ( empty( $savings ) || empty( $savings['bytes'] ) || $savings['bytes'] <= 1048576 || $savings['total_images'] <= 1 || ! is_super_admin() ) {
22
+ return false;
23
+ }
24
+ $message = sprintf( esc_html__( "%s, you've smushed %s%d%s images and saved %s%s%s in total. Help your friends save bandwidth easily, and help me in my quest to Smush the internet!", "wp-smushit" ), $wpsmushit_admin->get_user_name(), '<span class="smush-share-image-count">', $savings['total_images'], '</span>', '<span class="smush-share-savings">', $savings['human'], '</span>' );
25
+ $share_msg = sprintf( esc_html__( 'I saved %s%s%s on my site with WP Smush ( %s ) - wanna make your website light and faster?', "wp-smushit" ) , '<span class="smush-share-savings">', $savings['human'], '</span>', urlencode( "https://wordpress.org/plugins/wp-smushit/" ) ); ?>
26
+ <section class="dev-box" id="wp-smush-share-widget">
27
+ <div class="box-content roboto-medium">
28
+ <p class="wp-smush-share-message"><?php echo $message; ?></p>
29
+ <div class="wp-smush-share-buttons-wrapper">
30
+ <!-- Twitter Button -->
31
+ <a href="https://twitter.com/intent/tweet?text=<?php echo esc_attr( $share_msg ); ?>"
32
+ class="button wp-smush-share-button" id="wp-smush-twitter-share">
33
+ <i class="dev-icon dev-icon-twitter"></i><?php esc_html_e( "TWEET", "wp-smushit" ); ?></a>
34
+ <!-- Facebook Button -->
35
+ <a href="http://www.facebook.com/sharer.php?s=100&p[title]=WP Smush&p[url]=http://wordpress.org/plugins/wp-smushit/"
36
+ class="button wp-smush-share-button" id="wp-smush-facebook-share">
37
+ <i class="dev-icon dev-icon-facebook"></i><?php esc_html_e( "SHARE", "wp-smushit" ); ?></a>
38
+ <a href="whatsapp://send?text='<?php echo esc_attr( $share_msg ); ?>'"
39
+ class="button wp-smush-share-button"
40
+ id="wp-smush-whatsapp-share">
41
+ <?php esc_html_e( "WhatsApp", "wp-smushit" ); ?></a>
42
+ </div>
43
+ </div>
44
+ </section><?php
45
+ }
46
+
47
+ }
48
+
49
+ global $wpsmush_share;
50
+ $wpsmush_share = new WpSmushShare();
51
+ }
lib/class-wp-smush-stats.php ADDED
@@ -0,0 +1,592 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Smush
4
+ * @subpackage Admin
5
+ * @version 2.3
6
+ *
7
+ * @author Umesh Kumar <umesh@incsub.com>
8
+ *
9
+ * @copyright (c) 2016, Incsub (http://incsub.com)
10
+ */
11
+ if ( ! class_exists( 'WpSmushStats' ) ) {
12
+
13
+ /**
14
+ * Class WpSmushStats
15
+ */
16
+ class WpSmushStats {
17
+ function __construct() {
18
+ //Update resize savings
19
+ add_action( 'wp_smush_image_resized', array( $this, 'resize_savings' ) );
20
+ //Update Conversion savings
21
+ add_action( 'wp_smush_png_jpg_converted', array( $this, 'conversion_savings' ) );
22
+ }
23
+
24
+ /**
25
+ * Total Image count
26
+ * @return int
27
+ */
28
+ function total_count() {
29
+ global $wpsmushit_admin;
30
+
31
+ //Remove the Filters added by WP Media Folder
32
+ $this->remove_filters();
33
+
34
+ $count = 0;
35
+
36
+ $counts = wp_count_attachments( $wpsmushit_admin->mime_types );
37
+ foreach ( $wpsmushit_admin->mime_types as $mime ) {
38
+ if ( isset( $counts->$mime ) ) {
39
+ $count += $counts->$mime;
40
+ }
41
+ }
42
+
43
+ // send the count
44
+ return $count;
45
+ }
46
+
47
+ /**
48
+ * Optimised images count
49
+ *
50
+ * @param bool $return_ids
51
+ *
52
+ * @return array|int
53
+ */
54
+ function smushed_count( $return_ids = false ) {
55
+ global $wpsmushit_admin;
56
+
57
+ //Don't query again, if the variable is already set
58
+ if ( ! $return_ids && ! empty( $wpsmushit_admin->smushed_count ) && $wpsmushit_admin->smushed_count > 0 ) {
59
+ return $wpsmushit_admin->smushed_count;
60
+ }
61
+
62
+ $query = array(
63
+ 'fields' => array( 'ids', 'post_mime_type' ) ,
64
+ 'post_type' => 'attachment',
65
+ 'post_status' => 'inherit',
66
+ 'order' => 'ASC',
67
+ 'posts_per_page' => - 1,
68
+ 'meta_key' => 'wp-smpro-smush-data',
69
+ 'no_found_rows' => true
70
+ );
71
+
72
+ //Remove the Filters added by WP Media Folder
73
+ $this->remove_filters();
74
+
75
+ $results = new WP_Query( $query );
76
+
77
+ if ( ! is_wp_error( $results ) && $results->post_count > 0 ) {
78
+
79
+ $posts = $wpsmushit_admin->filter_by_mime( $results->posts );
80
+
81
+ if ( ! $return_ids ) {
82
+ //return Post Count
83
+ return count( $posts );
84
+ } else {
85
+ //Return post ids
86
+ return $posts;
87
+ }
88
+ } else {
89
+ return false;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Returns/Updates the number of images Super Smushed
95
+ *
96
+ * @param string $type media/nextgen, Type of images to get/set the super smushed count for
97
+ *
98
+ * @param array $attachments Optional, By default Media attachments will be fetched
99
+ *
100
+ * @return array|mixed|void
101
+ *
102
+ */
103
+ function super_smushed_count( $type = 'media', $attachments = '' ) {
104
+
105
+ if ( 'media' == $type ) {
106
+ $count = $this->media_super_smush_count();
107
+ } else {
108
+ $key = 'wp-smush-super_smushed_nextgen';
109
+
110
+ //Flag to check if we need to re-evaluate the count
111
+ $revaluate = false;
112
+
113
+ $super_smushed = get_option( $key, false );
114
+
115
+ //Check if need to revalidate
116
+ if ( ! $super_smushed || empty( $super_smushed ) || empty( $super_smushed['ids'] ) ) {
117
+
118
+ $super_smushed = array(
119
+ 'ids' => array()
120
+ );
121
+
122
+ $revaluate = true;
123
+ } else {
124
+ $last_checked = $super_smushed['timestamp'];
125
+
126
+ $diff = $last_checked - current_time( 'timestamp' );
127
+
128
+ //Difference in hour
129
+ $diff_h = $diff / 3600;
130
+
131
+ //if last checked was more than 1 hours.
132
+ if ( $diff_h > 1 ) {
133
+ $revaluate = true;
134
+ }
135
+ }
136
+ //Do not Revaluate stats if nextgen attachments are not provided
137
+ if ( 'nextgen' == $type && empty( $attachments ) && $revaluate ) {
138
+ $revaluate = false;
139
+ }
140
+
141
+ //Need to scan all the image
142
+ if ( $revaluate ) {
143
+ //Get all the Smushed attachments ids
144
+ $super_smushed_images = $this->get_lossy_attachments( $attachments, false );
145
+
146
+ if ( ! empty( $super_smushed_images ) && is_array( $super_smushed_images ) ) {
147
+ //Iterate over all the attachments to check if it's already there in list, else add it
148
+ foreach ( $super_smushed_images as $id ) {
149
+ if ( ! in_array( $id, $super_smushed['ids'] ) ) {
150
+ $super_smushed['ids'][] = $id;
151
+ }
152
+ }
153
+ }
154
+
155
+ $super_smushed['timestamp'] = current_time( 'timestamp' );
156
+
157
+ update_option( $key, $super_smushed );
158
+ }
159
+
160
+ $count = ! empty( $super_smushed['ids'] ) ? count( $super_smushed['ids'] ) : 0;
161
+ }
162
+
163
+ return $count;
164
+ }
165
+
166
+ /**
167
+ * Updates the Meta for existing smushed images and retrieves the count of Super Smushed images
168
+ *
169
+ * @return int Count of Super Smushed images
170
+ *
171
+ */
172
+ function media_super_smush_count( $return_ids = false ) {
173
+
174
+ global $wpsmushit_admin;
175
+
176
+ //Check if we have updated the stats for existing images, One time
177
+ if ( ! $lossy_updated = get_option( WP_SMUSH_PREFIX . 'lossy-updated' ) ) {
178
+
179
+ //Get all the smushed attachments
180
+ $attachments = $this->get_lossy_attachments( '', false );
181
+ if ( ! empty( $attachments ) ) {
182
+ foreach ( $attachments as $attachment ) {
183
+ update_post_meta( $attachment, WP_SMUSH_PREFIX . 'lossy', 1 );
184
+ }
185
+ }
186
+ }
187
+
188
+ //Get all the attachments with wp-smush-lossy
189
+ $limit = $wpsmushit_admin->query_limit();
190
+ $get_posts = true;
191
+ $super_smushed = array();
192
+ $args = array(
193
+ 'fields' => array( 'ids', 'post_mime_type' ),
194
+ 'post_type' => 'attachment',
195
+ 'post_status' => 'any',
196
+ 'orderby' => 'ID',
197
+ 'order' => 'DESC',
198
+ 'posts_per_page' => $limit,
199
+ 'offset' => 0,
200
+ 'meta_query' => array(
201
+ array(
202
+ 'key' => 'wp-smush-lossy',
203
+ 'value' => 1
204
+ )
205
+ ),
206
+ 'update_post_term_cache' => false,
207
+ 'no_found_rows' => true,
208
+ );
209
+ //Loop Over to get all the attachments
210
+ while ( $get_posts ) {
211
+
212
+ //Remove the Filters added by WP Media Folder
213
+ $this->remove_filters();
214
+
215
+ $query = new WP_Query( $args );
216
+
217
+ if ( ! empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
218
+ $posts = $wpsmushit_admin->filter_by_mime( $query->posts );
219
+ //Merge the results
220
+ $super_smushed = array_merge( $super_smushed, $posts );
221
+
222
+ //Update the offset
223
+ $args['offset'] += $limit;
224
+ } else {
225
+ //If we didn't get any posts from query, set $get_posts to false
226
+ $get_posts = false;
227
+ }
228
+
229
+ //If total Count is set, and it is alread lesser than offset, don't query
230
+ if ( ! empty( $this->total_count ) && $this->total_count < $args['offset'] ) {
231
+ $get_posts = false;
232
+ }
233
+ }
234
+ if ( ! $lossy_updated ) {
235
+ update_option( 'wp-smush-lossy-updated', true );
236
+ }
237
+
238
+ return $return_ids ? $super_smushed : count( $super_smushed );
239
+ }
240
+
241
+ /**
242
+ * Remove any pre_get_posts_filters added by WP Media Folder plugin
243
+ */
244
+ function remove_filters() {
245
+ //remove any filters added b WP media Folder plugin to get the all attachments
246
+ if ( class_exists( 'Wp_Media_Folder' ) ) {
247
+ global $wp_media_folder;
248
+ if ( is_object( $wp_media_folder ) ) {
249
+ remove_filter( 'pre_get_posts', array( $wp_media_folder, 'wpmf_pre_get_posts1' ) );
250
+ remove_filter( 'pre_get_posts', array( $wp_media_folder, 'wpmf_pre_get_posts' ), 0, 1 );
251
+ }
252
+ }
253
+ global $wpml_query_filter;
254
+ //If WPML is not installed, return
255
+ if ( ! is_object( $wpml_query_filter ) ) {
256
+ return;
257
+ }
258
+
259
+ //Remove language filter and let all the images be smushed at once
260
+ if ( has_filter( 'posts_join', array( $wpml_query_filter, 'posts_join_filter' ) ) ) {
261
+ remove_filter( 'posts_join', array( $wpml_query_filter, 'posts_join_filter' ), 10, 2 );
262
+ remove_filter( 'posts_where', array( $wpml_query_filter, 'posts_where_filter' ), 10, 2 );
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Get the savings from image resizing, And force update if set to true
268
+ *
269
+ * @param bool $force_update , Whether to Re-Calculate all the stats or not
270
+ *
271
+ * @param bool $format Format the Bytes in readable format
272
+ *
273
+ * @return array|bool|mixed|string Array of {
274
+ * 'bytes',
275
+ * 'before_size',
276
+ * 'after_size'
277
+ * }
278
+ *
279
+ */
280
+ function resize_savings( $force_update = true, $format = false ) {
281
+ $savings = '';
282
+
283
+ if ( ! $force_update ) {
284
+ $savings = wp_cache_get( WP_SMUSH_PREFIX . 'resize_savings', 'wp-smush' );
285
+ }
286
+
287
+ global $wpsmushit_admin;
288
+
289
+ //If nothing in cache, Calculate it
290
+ if ( empty( $savings ) || $force_update ) {
291
+ $savings = array(
292
+ 'bytes' => 0,
293
+ 'size_before' => 0,
294
+ 'size_after' => 0,
295
+ );
296
+
297
+ $limit = $wpsmushit_admin->query_limit();
298
+ $offset = 0;
299
+ $query_next = true;
300
+ global $wpdb;
301
+
302
+ while ( $query_next ) {
303
+
304
+ $resize_data = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key=%s LIMIT $offset, $limit", WP_SMUSH_PREFIX . 'resize_savings' ) );
305
+
306
+ if ( ! empty( $resize_data ) ) {
307
+ foreach ( $resize_data as $data ) {
308
+
309
+ if ( ! empty( $data ) ) {
310
+ $meta = maybe_unserialize( $data );
311
+ if ( ! empty( $meta ) && ! empty( $meta['bytes'] ) ) {
312
+ $savings['bytes'] += $meta['bytes'];
313
+ $savings['size_before'] += $meta['size_before'];
314
+ $savings['size_after'] += $meta['size_after'];
315
+ }
316
+ }
317
+ }
318
+ }
319
+ //Update the offset
320
+ $offset += $limit;
321
+
322
+ //Compare the Offset value to total images
323
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $offset ) {
324
+ $query_next = false;
325
+ } elseif ( ! $resize_data ) {
326
+ //If we didn' got any results
327
+ $query_next = false;
328
+ }
329
+ }
330
+
331
+ if ( $format ) {
332
+ $savings['bytes'] = size_format( $savings['bytes'], 1 );
333
+ }
334
+
335
+ wp_cache_set( WP_SMUSH_PREFIX . 'resize_savings', $savings, 'wp-smush' );
336
+ }
337
+
338
+ return $savings;
339
+ }
340
+
341
+ /**
342
+ * Return/Update PNG -> JPG Conversion savings
343
+ *
344
+ * @param bool $force_update Whether to force update the conversion savings or not
345
+ * @param bool $format Optionally return formatted savings
346
+ *
347
+ * @return array Savings
348
+ */
349
+ function conversion_savings( $force_update = true, $format = false ) {
350
+ $savings = '';
351
+
352
+ if ( ! $force_update ) {
353
+ $savings = wp_cache_get( WP_SMUSH_PREFIX . 'pngjpg_savings', 'wp-smush' );
354
+ }
355
+ //If nothing in cache, Calculate it
356
+ if ( empty( $savings ) || $force_update ) {
357
+ global $wpsmushit_admin;
358
+ $savings = array(
359
+ 'bytes' => 0,
360
+ 'size_before' => 0,
361
+ 'size_after' => 0,
362
+ );
363
+
364
+ $limit = $wpsmushit_admin->query_limit();
365
+ $offset = 0;
366
+ $query_next = true;
367
+ global $wpdb;
368
+
369
+ while ( $query_next ) {
370
+
371
+ $conversion_savings = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM $wpdb->postmeta WHERE meta_key=%s LIMIT $offset, $limit", WP_SMUSH_PREFIX . 'pngjpg_savings' ) );
372
+
373
+ if ( ! empty( $conversion_savings ) ) {
374
+ foreach ( $conversion_savings as $data ) {
375
+
376
+ if ( ! empty( $data ) ) {
377
+ $meta = maybe_unserialize( $data );
378
+
379
+ if( is_array( $meta ) ) {
380
+ foreach ( $meta as $size ) {
381
+ if ( ! empty( $size ) && is_array( $size ) ) {
382
+ $savings['bytes'] += $size['bytes'];
383
+ $savings['size_before'] += $size['size_before'];
384
+ $savings['size_after'] += $size['size_after'];
385
+ }
386
+ }
387
+ }
388
+ }
389
+ }
390
+ }
391
+ //Update the offset
392
+ $offset += $limit;
393
+
394
+ //Compare the Offset value to total images
395
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $offset ) {
396
+ $query_next = false;
397
+ } elseif ( ! $conversion_savings ) {
398
+ //If we didn' got any results
399
+ $query_next = false;
400
+ }
401
+ }
402
+
403
+ if ( $format ) {
404
+ $savings['bytes'] = size_format( $savings['bytes'], 1 );
405
+ }
406
+
407
+ wp_cache_set( WP_SMUSH_PREFIX . 'pngjpg_savings', $savings, 'wp-smush' );
408
+ }
409
+
410
+ return $savings;
411
+ }
412
+
413
+ /**
414
+ * Get all the resized images
415
+ *
416
+ * @return array Array of post ids of all the resized images
417
+ *
418
+ */
419
+ function resize_images() {
420
+ global $wpsmushit_admin;
421
+ $limit = $wpsmushit_admin->query_limit();
422
+ $limit = ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $limit ? $wpsmushit_admin->total_count : $limit;
423
+ $get_posts = true;
424
+ $resized_images = array();
425
+ $args = array(
426
+ 'fields' => array( 'ids', 'post_mime_type' ),
427
+ 'post_type' => 'attachment',
428
+ 'post_status' => 'inherit',
429
+ 'orderby' => 'ID',
430
+ 'order' => 'DESC',
431
+ 'posts_per_page' => $limit,
432
+ 'offset' => 0,
433
+ 'meta_key' => WP_SMUSH_PREFIX . 'resize_savings',
434
+ 'update_post_term_cache' => false,
435
+ 'no_found_rows' => true,
436
+ );
437
+ //Loop Over to get all the attachments
438
+ while ( $get_posts ) {
439
+
440
+ //Remove the Filters added by WP Media Folder
441
+ $this->remove_filters();
442
+
443
+ $query = new WP_Query( $args );
444
+
445
+ if ( ! empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
446
+
447
+ $posts = $wpsmushit_admin->filter_by_mime( $query->posts );
448
+
449
+ //Merge the results
450
+ $resized_images = array_merge( $resized_images, $posts );
451
+
452
+ //Update the offset
453
+ $args['offset'] += $limit;
454
+ } else {
455
+ //If we didn't get any posts from query, set $get_posts to false
456
+ $get_posts = false;
457
+ }
458
+
459
+ //If total Count is set, and it is alread lesser than offset, don't query
460
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $args['offset'] ) {
461
+ $get_posts = false;
462
+ }
463
+ }
464
+
465
+ return $resized_images;
466
+ }
467
+
468
+ /**
469
+ * Get all the PNGJPG Converted images
470
+ *
471
+ * @return array Array of post ids of all the converted images
472
+ *
473
+ */
474
+ function converted_images() {
475
+ global $wpsmushit_admin;
476
+ $limit = $wpsmushit_admin->query_limit();
477
+ $limit = ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $limit ? $wpsmushit_admin->total_count : $limit;
478
+ $get_posts = true;
479
+ $converted_images = array();
480
+ $args = array(
481
+ 'fields' => array( 'ids', 'post_mime_type' ),
482
+ 'post_type' => 'attachment',
483
+ 'post_status' => 'inherit',
484
+ 'orderby' => 'ID',
485
+ 'order' => 'DESC',
486
+ 'posts_per_page' => $limit,
487
+ 'offset' => 0,
488
+ 'meta_key' => WP_SMUSH_PREFIX . 'pngjpg_savings',
489
+ 'update_post_term_cache' => false,
490
+ 'no_found_rows' => true,
491
+ );
492
+ //Loop Over to get all the attachments
493
+ while ( $get_posts ) {
494
+
495
+ //Remove the Filters added by WP Media Folder
496
+ $this->remove_filters();
497
+
498
+ $query = new WP_Query( $args );
499
+
500
+ if ( ! empty( $query->post_count ) && sizeof( $query->posts ) > 0 ) {
501
+
502
+ //Filter Posts by mime types
503
+ $posts = $wpsmushit_admin->filter_by_mime( $query->posts );
504
+
505
+ //Merge the results
506
+ $converted_images = array_merge( $converted_images, $posts );
507
+
508
+ //Update the offset
509
+ $args['offset'] += $limit;
510
+ } else {
511
+ //If we didn't get any posts from query, set $get_posts to false
512
+ $get_posts = false;
513
+ }
514
+
515
+ //If total Count is set, and it is alread lesser than offset, don't query
516
+ if ( ! empty( $wpsmushit_admin->total_count ) && $wpsmushit_admin->total_count < $args['offset'] ) {
517
+ $get_posts = false;
518
+ }
519
+ }
520
+
521
+ return $converted_images;
522
+ }
523
+
524
+ /**
525
+ * Returns the ids and meta which are losslessly compressed
526
+ *
527
+ * Called only if the meta key isn't updated for old images, else it is not used
528
+ *
529
+ * @return array
530
+ */
531
+ function get_lossy_attachments( $attachments = '', $return_count = true ) {
532
+
533
+ $lossy_attachments = array();
534
+ $count = 0;
535
+
536
+ if ( empty( $attachments ) ) {
537
+ //Fetch all the smushed attachment ids
538
+ $attachments = $this->smushed_count( true );
539
+ }
540
+
541
+ //If we dont' have any attachments
542
+ if ( empty( $attachments ) || 0 == count( $attachments ) ) {
543
+ return 0;
544
+ }
545
+
546
+ //Check if image is lossless or lossy
547
+ foreach ( $attachments as $attachment ) {
548
+
549
+ //Check meta for lossy value
550
+ $smush_data = ! empty( $attachment->smush_data ) ? maybe_unserialize( $attachment->smush_data ) : '';
551
+
552
+ //For Nextgen Gallery images
553
+ if ( empty( $smush_data ) && is_array( $attachment ) && ! empty( $attachment['wp_smush'] ) ) {
554
+ $smush_data = ! empty( $attachment['wp_smush'] ) ? $attachment['wp_smush'] : '';
555
+ }
556
+
557
+ //Return if not smushed
558
+ if ( empty( $smush_data ) ) {
559
+ continue;
560
+ }
561
+
562
+ //if stats not set or lossy is not set for attachment, return
563
+ if ( empty( $smush_data['stats'] ) || ! isset( $smush_data['stats']['lossy'] ) ) {
564
+ continue;
565
+ }
566
+
567
+ //Add to array if lossy is not 1
568
+ if ( 1 == $smush_data['stats']['lossy'] ) {
569
+ $count ++;
570
+ if ( ! empty( $attachment->attachment_id ) ) {
571
+ $lossy_attachments[] = $attachment->attachment_id;
572
+ } elseif ( is_array( $attachment ) && ! empty( $attachment['pid'] ) ) {
573
+ $lossy_attachments[] = $attachment['pid'];
574
+ }
575
+ }
576
+ }
577
+ unset( $attachments );
578
+
579
+ if ( $return_count ) {
580
+ return $count;
581
+ }
582
+
583
+ return $lossy_attachments;
584
+ }
585
+ }
586
+
587
+ /**
588
+ * Initialise class
589
+ */
590
+ global $wpsmush_stats;
591
+ $wpsmush_stats = new WpSmushStats();
592
+ }
lib/class-wp-smush-ui.php CHANGED
@@ -19,13 +19,6 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
19
  */
20
  class WpSmushBulkUi {
21
 
22
- function __construct() {
23
- //Add a container for Smush Pro promo
24
- add_action( 'wp_smush_after_stats_box', array( $this, 'wp_smush_promo' ) );
25
- //Add a Container for Hummingbird Promo
26
- add_action( 'wp_smush_after_stats_box', array( $this, 'wp_smush_hummingbird_promo' ) );
27
- }
28
-
29
  /**
30
  * Prints the Header Section for a container as per the Shared UI
31
  *
@@ -41,8 +34,8 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
41
  return '';
42
  }
43
  echo '<section class="dev-box ' . $classes . ' wp-smush-container" id="' . $id . '">'; ?>
44
- <div class="wp-smush-container-header box-title">
45
- <h3><?php echo $heading ?></h3><?php
46
  //Sub Heading
47
  if ( ! empty( $sub_heading ) ) { ?>
48
  <div class="smush-container-subheading roboto-medium"><?php echo $sub_heading ?></div><?php
@@ -68,7 +61,7 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
68
  //Header Of the Box
69
  $this->container_header( 'wp-smush-welcome', 'wp-smush-welcome-box', esc_html__( "WELCOME", "wp-smushit" ), '', true );
70
  //Settings Page heading
71
- $plugin_name = $WpSmush->is_pro() ? "WP Smush Pro" : "WP Smush";
72
  ?>
73
  <!-- Content -->
74
  <div class="box-content">
@@ -91,7 +84,7 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
91
  //Subheading content
92
  $smush_individual_msg = sprintf( esc_html__( "Smush individual images via your %sMedia Library%s", "wp-smushit" ), '<a href="' . esc_url( admin_url( 'upload.php' ) ) . '" title="' . esc_html__( 'Media Library', 'wp-smushit' ) . '">', '</a>' );
93
 
94
- $class = $WpSmush->is_pro() ? 'bulk-smush-wrapper wp-smush-pro-install' : 'bulk-smush-wrapper';
95
 
96
  //Contianer Header
97
  $this->container_header( $class, 'wp-smush-bulk-wrap-box', esc_html__( "BULK SMUSH", "wp-smushit" ), $smush_individual_msg ); ?>
@@ -107,71 +100,159 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
107
  */
108
  function settings_ui() {
109
  global $WpSmush;
110
- $class = $WpSmush->is_pro() ? 'smush-settings-wrapper wp-smush-pro' : 'smush-settings-wrapper';
111
  $this->container_header( $class, 'wp-smush-settings-box', esc_html__( "SETTINGS", "wp-smushit" ), '' );
112
  // display the options
113
  $this->options_ui();
114
  }
115
 
116
  /**
117
- * Outputs the Smush stats for the site
118
- */
 
 
119
  function smush_stats_container() {
120
- global $WpSmush, $wpsmushit_admin;
121
-
122
- //If we have resmush list, smushed_count = totalcount - resmush count, else smushed_count
123
- $smushed_count = ( $resmush_count = count( $wpsmushit_admin->resmush_ids ) ) > 0 ? $wpsmushit_admin->total_count - ( $resmush_count + $wpsmushit_admin->remaining_count ) : $wpsmushit_admin->smushed_count;
124
- $smushed_count = $smushed_count > 0 ? $smushed_count : 0;
125
 
126
- $button = '<span class="spinner"></span><button tooltip="' . esc_html__( "Lets you check if any images can be further optimised. Useful after changing settings.", "wp-smushit" ) . '" class="wp-smush-title button button-grey button-small wp-smush-scan">' . esc_html__( "RE-CHECK IMAGES", "wp-smushit" ) . '</button>';
127
- $this->container_header( 'smush-stats-wrapper', 'wp-smush-stats-box', esc_html__( "STATS", "wp-smushit" ), $button ); ?>
 
 
 
128
  <div class="box-content">
129
- <div class="row smush-total-reduction-percent">
130
- <span
131
- class="float-l wp-smush-stats-label"><strong><?php esc_html_e( "TOTAL % REDUCTIONS", "wp-smushit" ); ?></strong></span>
132
- <span class="float-r wp-smush-stats-wrap"><strong><span
133
- class="wp-smush-stats"><?php echo $wpsmushit_admin->stats['percent'] > 0 ? number_format_i18n( $wpsmushit_admin->stats['percent'], 2, '.', '' ) : 0; ?></span>
134
- %</strong></span>
135
- </div>
136
- <hr>
137
- <div class="row smush-total-reduction-bytes">
138
- <span
139
- class="float-l wp-smush-stats-label"><strong><?php esc_html_e( "TOTAL SIZE REDUCTIONS", "wp-smushit" ); ?></strong></span>
140
- <span
141
- class="float-r wp-smush-stats"><strong><?php echo $wpsmushit_admin->stats['human'] > 0 ? $wpsmushit_admin->stats['human'] : "0MB"; ?></strong></span>
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  </div>
143
- <hr>
144
- <div class="row smush-attachments">
145
- <span
146
- class="float-l wp-smush-stats-label"><strong><?php esc_html_e( "ATTACHMENTS SMUSHED", "wp-smushit" ); ?></strong></span>
147
- <span class="float-r wp-smush-stats"><strong><span
148
- class="smushed-count"><?php echo intval( $smushed_count ) . '</span>/' . $wpsmushit_admin->total_count; ?>
149
- </strong></span>
 
 
 
150
  </div><?php
151
  /**
152
  * Allows to hide the Super Smush stats as it might be heavy for some users
153
  */
154
- if ( $WpSmush->is_pro() && apply_filters( 'wp_smush_show_lossy_stats', true ) ) {
155
- $wpsmushit_admin->super_smushed = $wpsmushit_admin->super_smushed_count(); ?>
156
- <hr>
157
  <div class="row super-smush-attachments">
158
- <span
159
- class="float-l wp-smush-stats-label"><strong><?php esc_html_e( "ATTACHMENTS SUPER-SMUSHED", "wp-smushit" ); ?></strong></span>
160
- <span class="float-r wp-smush-stats"><?php
161
- if ( $WpSmush->lossy_enabled ) {
162
- echo '<strong><span class="smushed-count">' . intval( $wpsmushit_admin->super_smushed ) . '</span>/' . $wpsmushit_admin->total_count . '</strong>';
163
- } else {
164
- printf( esc_html__( "%sENABLE%s", "wp-smushit" ), '<span class="wp-smush-lossy-enable">', '</span>' );
165
- } ?>
166
- </span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  </div><?php
168
  }
 
 
 
 
169
  /**
170
  * Allows you to output any content within the stats box at the end
171
  */
172
  do_action( 'wp_smush_after_stats' );
173
- ?>
174
- </div><?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  echo "</section>";
176
  }
177
 
@@ -179,28 +260,29 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
179
  * Outputs the advanced settings for Pro users, Disabled for basic users by default
180
  */
181
  function advanced_settings( $configure_screen = false ) {
182
- global $WpSmush, $wpsmushit_admin;
183
 
184
  //Content for the End of box container
185
- $div_end =
186
- wp_nonce_field( 'save_wp_smush_options', 'wp_smush_options_nonce', '', false ) .
187
- '<div class="wp-smush-submit-wrap">
188
- <input type="submit" id="wp-smush-save-settings" class="button button-grey"
189
- value="' . esc_html__( 'UPDATE SETTINGS', 'wp-smushit' ) . '">
190
- <span class="spinner"></span>
191
- </div>
192
- </form>';
193
- //For Configuration screen we need to show the advanced settings in single box
194
- if ( ! $configure_screen ) {
195
- $div_end .= '</div><!-- Box Content -->
196
- </section><!-- Main Section -->';
197
- }
198
 
199
  //For Basic User, Show advanced settings in a separate box
200
- if ( ! $WpSmush->is_pro() ) {
201
  echo $div_end;
202
-
203
- $pro_only = sprintf( esc_html__( '%sPRO ONLY%s', 'wp-smushit' ), '<a href="' . esc_url( $wpsmushit_admin->upgrade_url ) . '" target="_blank">', '</a>' );
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
  $this->container_header( 'wp-smush-premium', 'wp-smush-pro-settings-box', esc_html__( "ADVANCED SETTINGS", "wp-smushit" ), $pro_only, false ); ?>
206
  <div class="box-content"><?php
@@ -208,13 +290,15 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
208
 
209
  //Available advanced settings
210
  $pro_settings = array(
211
- 'original',
212
  'lossy',
 
213
  'backup',
214
- 'nextgen'
215
  );
216
 
217
- if ( $WpSmush->is_pro() ) {
 
 
218
  echo "<hr />";
219
  }
220
 
@@ -222,9 +306,9 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
222
  foreach ( $pro_settings as $setting_key ) {
223
  if ( isset( $wpsmushit_admin->settings[ $setting_key ] ) ) {
224
  $setting_m_key = WP_SMUSH_PREFIX . $setting_key;
225
- $setting_val = $WpSmush->is_pro() ? get_option( $setting_m_key, false ) : 0; ?>
226
  <div class='wp-smush-setting-row wp-smush-advanced'>
227
- <label class="inline-label" for="<?php echo $setting_m_key; ?>">
228
  <span
229
  class="wp-smush-setting-label"><?php echo $wpsmushit_admin->settings[ $setting_key ]['label']; ?></span>
230
  <br/>
@@ -236,33 +320,53 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
236
  <input type="checkbox" class="toggle-checkbox"
237
  id="<?php echo $setting_m_key; ?>" <?php checked( $setting_val, 1, true ); ?>
238
  value="1"
239
- name="<?php echo $setting_m_key; ?>">
240
  <label class="toggle-label" for="<?php echo $setting_m_key; ?>"></label>
241
  </span>
 
 
 
 
 
242
  </div>
243
  <hr><?php
244
  }
245
  }
246
  //Output Form end and Submit button for pro version
247
- if ( $WpSmush->is_pro() ) {
248
  echo $div_end;
249
  } else {
250
  echo "</div><!-- Box Content -->
251
  </section><!-- Main Section -->";
252
  }
 
 
 
 
253
  }
254
 
255
  /**
256
  * Process and display the options form
257
  */
258
  function options_ui( $configure_screen = false ) {
259
- global $wpsmushit_admin;
260
  echo '<div class="box-container">
261
  <form id="wp-smush-settings-form" method="post">';
 
 
 
 
 
 
 
 
 
 
 
262
  //Smush auto key
263
  $opt_auto = WP_SMUSH_PREFIX . 'auto';
264
  //Auto value
265
- $opt_auto_val = get_option( $opt_auto, false );
266
 
267
  //If value is not set for auto smushing set it to 1
268
  if ( $opt_auto_val === false ) {
@@ -272,87 +376,208 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
272
 
273
  //Keep Exif
274
  $opt_keep_exif = WP_SMUSH_PREFIX . 'keep_exif';
275
- //Keep Exif
276
- $opt_keep_exif_val = get_option( $opt_keep_exif, false ); ?>
277
- <div class='wp-smush-setting-row wp-smush-basic'>
278
- <label class="inline-label" for="<?php echo $opt_auto; ?>">
279
- <span
280
- class="wp-smush-setting-label"><?php echo $wpsmushit_admin->settings['auto']['label']; ?></span><br/>
281
- <small
282
- class="smush-setting-description"><?php echo $wpsmushit_admin->settings['auto']['desc']; ?></small>
283
- </label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  <span class="toggle float-r">
285
  <input type="checkbox" class="toggle-checkbox"
286
- id="<?php echo $opt_auto; ?>"
287
- name="<?php echo $opt_auto; ?>" <?php checked( $opt_auto_val, 1, true ); ?> value="1">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  <label class="toggle-label" for="<?php echo $opt_auto; ?>"></label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  </span>
290
- </div>
291
- <hr/>
292
- <div class='wp-smush-setting-row wp-smush-basic'>
293
- <label class="inline-label" for="<?php echo $opt_keep_exif; ?>"><span
294
- class="wp-smush-setting-label"><?php echo $wpsmushit_admin->settings['keep_exif']['label']; ?></span>
295
- <br/>
296
- <small class="smush-setting-description">
297
- <?php echo $wpsmushit_admin->settings['keep_exif']['desc']; ?>
298
- </small>
299
- </label>
300
- <span class="toggle float-r">
301
- <input type="checkbox" class="toggle-checkbox"
302
- id="<?php echo $opt_keep_exif; ?>" <?php checked( $opt_keep_exif_val, 1, true ); ?>
303
- value="1" name="<?php echo $opt_keep_exif; ?>">
304
- <label class="toggle-label" for="<?php echo $opt_keep_exif; ?>"></label>
305
- </span>
306
- </div> <!-- End of Basic Settings --><?php
 
 
 
 
 
 
 
 
 
 
 
307
 
308
- do_action( 'wp_smush_after_basic_settings' );
309
- $this->advanced_settings( $configure_screen );
 
 
 
 
 
 
310
  }
311
 
312
  /**
313
  * Display the Whole page ui, Call all the other functions under this
314
  */
315
  function ui() {
 
316
  global $WpSmush, $wpsmushit_admin;
317
- $this->smush_page_header();
318
 
319
- //Show Configure screen for only a new installation and for only network admins
320
- if ( 1 != get_option( 'wp-smush-hide_smush_welcome' ) && 1 != get_option( 'hide_smush_features' ) && 0 >= $wpsmushit_admin->smushed_count && is_super_admin() ) {
321
- echo '<div class="block float-l smush-welcome-wrapper">';
322
- $this->welcome_screen();
323
- echo '</div>';
324
- } ?>
325
 
326
- <!-- Bulk Smush Progress Bar -->
327
- <div class="wp-smushit-container-left col-two-third float-l"><?php
328
- //Bulk Smush Container
329
- $this->bulk_smush_container();
 
 
 
 
 
 
 
 
 
 
 
 
 
330
 
331
- if ( ! $WpSmush->is_pro() ) {
332
- //Settings
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  $this->settings_ui();
334
  }
335
- ?>
336
- </div>
337
 
338
- <!-- Stats -->
339
- <div class="wp-smushit-container-right col-third float-l"><?php
340
- //Stats
341
- $this->smush_stats_container();
342
- if ( ! $WpSmush->is_pro() ) {
343
- /**
344
- * Allows to Hook in Additional Containers after Stats Box for free version
345
- * Pro Version has a full width settings box, so we don't want to do it there
346
- */
347
- do_action( 'wp_smush_after_stats_box' );
348
  } ?>
349
- </div><!-- End Of Smushit Container right --><?php
350
- if ( $WpSmush->is_pro() ) { ?>
351
- <div class="row"><?php
352
- //Settings
353
- $this->settings_ui(); ?>
354
- </div><?php
355
- }
356
  $this->smush_page_footer();
357
  }
358
 
@@ -361,19 +586,25 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
361
  */
362
  function wp_smush_promo() {
363
  global $wpsmushit_admin;
364
- $this->container_header( 'wp-smush-pro-adv', 'wp-smush-pro-promo', "FANCY A FREE SUPER SMUSH?" ); ?>
 
 
 
 
 
 
 
 
 
365
  <div class="box-content">
366
- <p class="wp-smush-promo-content roboto-medium">You can now get Smush Pro... for FREE!</p>
367
- <p class="wp-smush-promo-content wp-smush-promo-content-2 roboto-medium">No obligation, no contracts, no
368
- catches. You'll get Smush Pro plus 100+ WPMU DEV plugins, Defender, Hummingbird & 24/7 WP support
369
- for absolutely nothing for 14 days.</p>
370
  <span class="wp-smush-pro-cta tc">
371
- <a href="<?php echo esc_url( $wpsmushit_admin->upgrade_url ); ?>"
372
- class="button button-cta button-green" target="_blank">FIND OUT MORE</a>
373
  </span>
374
- </div>
375
- <img src="<?php echo WP_SMUSH_URL . 'assets/images/dev-team.png'; ?>"
376
- alt="<?php esc_html_e( "TRY WP SMUSH PRO - DEV TEAM", "wp-smushit" ); ?>"><?php
377
  echo "</section>";
378
  }
379
 
@@ -385,12 +616,12 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
385
  if ( class_exists( 'WP_Hummingbird' ) ) {
386
  return;
387
  }
388
- $this->container_header( 'wp-smush-hb-adv', 'wp-smush-hb-promo', "OH YEAH, SMUSHING ON STERIODS!" ); ?>
389
  <div class="box-content">
390
  <span class="wp-smush-hummingbird-image tc">
391
  <img src="<?php echo WP_SMUSH_URL . 'assets/images/hummingbird.png'; ?>"
392
  alt="<?php esc_html_e( "BOOST YOUR PERFORMANCE - HUMMINGBIRD", "wp-smushit" ); ?>">
393
- </span>
394
  <p class="wp-smush-promo-content tc roboto-medium">Hummingbird goes beyond Smush compression with
395
  minification, caching, performance monitoring and more - every millisecond counts!</p>
396
  <span class="wp-smush-hb-cta tc roboto-medium">
@@ -415,7 +646,7 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
415
  //If there are no images in Media Library
416
  if ( 0 >= $wpsmushit_admin->total_count ) { ?>
417
  <span class="wp-smush-no-image tc">
418
- <img src="<?php echo WP_SMUSH_URL . 'assets/images/smush-upload-images.png'; ?>"
419
  alt="<?php esc_html_e( "No attachments found - Upload some images", "wp-smushit" ); ?>">
420
  </span>
421
  <p class="wp-smush-no-images-content tc roboto-regular"><?php printf( esc_html__( "We haven’t found any images in your %smedia library%s yet so there’s no smushing to be done! Once you upload images, reload this page and start playing!", "wp-smushit" ), '<a href="' . esc_url( admin_url( 'upload.php' ) ) . '">', '</a>' ); ?></p>
@@ -425,8 +656,8 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
425
  </span><?php
426
  } else { ?>
427
  <!-- Hide All done div if there are images pending -->
428
- <div class="wp-smush-notice wp-smush-all-done<?php echo $all_done ? '' : ' hidden' ?>">
429
- <i class="dev-icon dev-icon-tick"></i><?php esc_html_e( "No attachments need smushing. Awesome!", "wp-smushit" ); ?>
430
  </div>
431
  <div class="wp-smush-bulk-wrapper <?php echo $all_done ? ' hidden' : ''; ?>"><?php
432
  //If all the images in media library are smushed
@@ -436,21 +667,32 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
436
  //Show the notice only if there are remaining images and if we aren't showing a notice for resmush
437
  if ( $wpsmushit_admin->remaining_count > 0 ) {
438
  $class = count( $wpsmushit_admin->resmush_ids ) > 0 ? ' hidden' : '';
 
 
 
 
 
 
 
 
439
  ?>
440
- <div class="wp-smush-notice wp-smush-remaining<?php echo $class; ?>">
441
- <i class="dev-icon">
442
- <img src="<?php echo WP_SMUSH_URL . 'assets/images/icon-gzip.svg'; ?>" width="14px">
443
- </i>
444
- <span class="wp-smush-notice-text">
445
- <?php printf( _n( "%s, you have %s%s%d%s image%s that need smushing!", "%s, you have %s%s%d%s images%s that need smushing!", $wpsmushit_admin->remaining_count, "wp-smushit" ), $wpsmushit_admin->get_user_name(), '<strong>', '<span class="wp-smush-remaining-count">', $wpsmushit_admin->remaining_count, '</span>', '</strong>' ); ?>
 
 
 
 
446
  </span>
447
  </div><?php
448
  } ?>
449
  <hr>
450
- <div class="smush-final-log notice notice-warning inline hidden"></div>
451
  <button type="button" class="wp-smush-all wp-smush-button"><?php echo $button_content; ?></button><?php
452
  //Enable Super Smush
453
- if ( $WpSmush->is_pro() && ! $WpSmush->lossy_enabled ) { ?>
454
  <p class="wp-smush-enable-lossy"><?php esc_html_e( "Enable Super-smush in the Settings area to get even more savings with almost no noticeable quality loss.", "wp-smushit" ); ?></p><?php
455
  } ?>
456
  </div><?php
@@ -464,17 +706,17 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
464
  */
465
  function progress_bar( $count ) {
466
 
 
 
467
  // calculate %ages, avoid divide by zero error with no attachments
468
  if ( $count->total_count > 0 && $count->smushed_count > 0 ) {
469
  $smushed_pc = $count->smushed_count / $count->total_count * 100;
470
  } else {
471
  $smushed_pc = 0;
472
- }
473
- //If we have resmush list, smushed_count = totalcount - resmush count, else smushed_count
474
- $smushed_count = ( $resmush_count = count( $count->resmush_ids ) ) > 0 ? ( $count->total_count - $resmush_count ) : $count->smushed_count; ?>
475
  <div class="wp-smush-bulk-progress-bar-wrapper hidden">
476
  <p class="wp-smush-bulk-active roboto-medium"><span
477
- class="spinner is-active"></span><?php printf( esc_html__( "%sBulk smush is currently running.%s You need to keep this page open.", "wp-smushit" ), '<strong>', '</strong>' ); ?>
478
  </p>
479
  <div class="wp-smush-progress-wrap">
480
  <div class="wp-smush-progress-bar-wrap">
@@ -484,48 +726,14 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
484
  </div>
485
  </div>
486
  <div class="wp-smush-count tc">
487
- <?php printf( esc_html__( "%s%d%s of %d attachments have been smushed." ), '<span class="wp-smush-images-smushed">', $smushed_count, '</span>', $count->total_count ); ?>
488
  </div>
489
  </div>
490
- <div class="smush-final-log notice notice-warning inline hidden"></div>
491
  <hr class="wp-smush-sep">
492
  <button type="button"
493
  class="button button-grey wp-smush-cancel-bulk"><?php esc_html_e( "CANCEL", "wp-smushit" ); ?></button>
494
- </div><?php
495
- }
496
-
497
- /**
498
- * Progress Bar for Resmush UI
499
- */
500
- function resmush_progress_bar( $resmush_count = '', $return = false ) {
501
- global $wpsmushit_admin;
502
- if ( empty( $resmush_count ) ) {
503
- //Get Resmush List
504
- $resmush_list = get_option( 'wp-smush-resmush-list' );
505
- $resmush_count = ! empty( $resmush_list ) ? count( $resmush_list ) : 0;
506
- }
507
-
508
- $content = '<div class="wp-smush-bulk-progress-bar-wrapper hidden">
509
- <p class="wp-smush-bulk-active roboto-medium">' . sprintf( esc_html__( "%sBulk re-smush is currently running.%s You need to keep this page open.", "wp-smushit" ), '<strong>', '</strong>' ) . '</p>
510
- <div class="wp-smush-progress-wrap">
511
- <div class="wp-smush-progress-bar-wrap">
512
- <div class="wp-smush-progress-bar">
513
- <div class="wp-smush-progress-inner" style="width: 100%;">
514
- <div class="wp-smush-progress-count">' . sprintf( _n( "%s%d%s image left to Re-Smush", "%s%d%s images left to Re-Smush", $resmush_count, "wp-smushit" ), '<span class="wp-smush-images-remaining">', $wpsmushit_admin->format_number( $resmush_count ), '</span>' ) . '
515
- </div>
516
- </div>
517
- </div>
518
- </div>
519
  </div>
520
- <div class="smush-final-log notice notice-warning inline hidden"></div>
521
- <hr class="wp-smush-sep">
522
- <button type="button"
523
- class="button button-grey wp-smush-cancel-bulk">' . esc_html__( "CANCEL", "wp-smushit" ) . '</button>
524
- </div>';
525
- if ( $return ) {
526
- return $content;
527
- }
528
- echo $content;
529
  }
530
 
531
  /**
@@ -552,14 +760,14 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
552
  $wpsmushit_admin->setup_global_stats();
553
  }
554
 
555
- $count += $wpsmushit_admin->remaining_count;
556
  }
557
  }
558
  //Show only if we have any images to ber resmushed
559
  if ( $show ) {
560
- return '<div class="wp-smush-notice wp-smush-resmush-notice wp-smush-remaining">
561
  <i class="dev-icon"><img src="' . WP_SMUSH_URL . 'assets/images/icon-gzip.svg" width="14px"></i>
562
- <span class="wp-smush-notice-text">' . sprintf( _n( "%s, you have %s%s%d%s image%s that need re-compressing!", "%s, you have %s%s%d%s images%s that need re-compressing!", $count, "wp-smushit" ), $wpsmushit_admin->get_user_name(), '<strong>', '<span class="wp-smush-remaining-count">', $count, '</span>', '</strong>' ) . '</span>
563
  <button class="button button-grey button-small wp-smush-skip-resmush">' . esc_html__( "Skip", "wp-smushit" ) . '</button>
564
  </div>';
565
  }
@@ -569,9 +777,15 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
569
  * Displays a admin notice for settings update
570
  */
571
  function settings_updated() {
572
- global $wpsmushit_admin;
 
 
 
 
 
 
573
  //Show Setttings Saved message
574
- if ( 1 == get_option( 'wp-smush-settings_updated', false ) ) {
575
 
576
  //Default message
577
  $message = esc_html__( "Your settings have been updated!", "wp-smushit" );
@@ -588,7 +802,7 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
588
  </div>';
589
 
590
  //Remove the option
591
- delete_option( 'wp-smush-settings_updated' );
592
  }
593
  }
594
 
@@ -600,18 +814,31 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
600
  //Include Shared UI
601
  require_once WP_SMUSH_DIR . 'assets/shared-ui/plugin-ui.php';
602
 
603
- //Initialize global Stats
604
- $wpsmushit_admin->setup_global_stats();
 
 
605
 
606
  //Page Heading for Free and Pro Version
607
- $page_heading = $WpSmush->is_pro() ? esc_html__( 'WP Smush Pro', 'wp-smushit' ) : esc_html__( 'WP Smush', 'wp-smushit' );
608
 
609
  $auto_smush_message = $WpSmush->is_auto_smush_enabled() ? sprintf( esc_html__( "Automatic smushing is %senabled%s. Newly uploaded images will be automagically compressed." ), '<span class="wp-smush-auto-enabled">', '</span>' ) : sprintf( esc_html__( "Automatic smushing is %sdisabled%s. Newly uploaded images will need to be manually smushed." ), '<span class="wp-smush-auto-disabled">', '</span>' );
610
- echo '<div class="wrap">
611
- <div class="wp-smush-page-header">
612
- <h1 class="wp-smush-page-heading">' . $page_heading . '</h1>
613
- <div class="wp-smush-auto-message roboto-regular">' . $auto_smush_message . '</div>
614
- </div>';
 
 
 
 
 
 
 
 
 
 
 
615
  //Check if settings were updated and shoe a notice
616
  $this->settings_updated();
617
 
@@ -625,31 +852,48 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
625
  global $wpsmushit_admin;
626
 
627
  //Whether New/Existing Installation
628
- $install_type = get_option('wp-smush-install-type', false );
629
 
630
  if( !$install_type ) {
631
  $install_type = $wpsmushit_admin->smushed_count > 0 ? 'existing' : 'new';
632
- update_option( 'wp-smush-install-type', $install_type );
633
  }
634
 
635
  if ( 'new' == $install_type ) {
636
  $notice_heading = esc_html__( "Thanks for installing Smush. We hope you like it!", "wp-smushit" );
637
  $notice_content = esc_html__( "And hey, if you do, you can now try out Smush Pro for double the smushy goodness (benchmarked), entirely for free!", "wp-smushit" );
638
- $button_content = esc_html__( "FIND OUT MORE", "wp-smushit" );
639
  } else {
640
- $notice_heading = sprintf( esc_html__( "Did you know that you can now %stry out Smush Pro%s for FREE?", "wp-smushit" ), '<a href="' . esc_url( $wpsmushit_admin->upgrade_url ) . '" target="_blank">', '</a>' );
641
- $notice_content = esc_html__( "Yep, Super Smush your images for double the savings, save originals and batch Smush thousands of images all at once.... no charge!!!", "wp-smushit" );
642
- $button_content = esc_html__( "TRY SMUSH PRO FOR FREE", "wp-smushit" );
643
- } ?>
644
- <div class="box-content">
645
- <div class="row">
646
- <div class="wp-smush-install-welcome<?php echo 'new' == $install_type ? ' wp-smush-fresh' : ' wp-smush-existing'; ?>">
647
- <p class="wp-smush-install-heading roboto-medium"><?php echo $notice_heading; ?></p>
648
- <p class="wp-smush-install-content roboto-regular"><?php echo $notice_content; ?></p>
649
- <a href="<?php echo esc_url( $wpsmushit_admin->upgrade_url ); ?>" class="button button-green button-cta" target="_blank"><?php echo $button_content; ?></a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
650
  </div>
651
- </div>
652
  </div><?php
 
 
 
 
653
  }
654
 
655
  /**
@@ -657,12 +901,20 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
657
  */
658
  function super_smush_promo() {
659
  global $WpSmush, $wpsmushit_admin;
660
- if ( $WpSmush->is_pro() ) {
661
  return;
662
- } ?>
 
 
 
 
 
 
 
 
663
  <div class="wp-smush-super-smush-promo">
664
  <div class="wp-smush-super-smush-content"><?php
665
- printf( esc_html__("Did you know WP Smush Pro delivers up to 10x better compression, allows you to smush your originals and removes any bulk smushing limits? – %sTry it absolutely FREE%s", "wp-smushit"), '<a href="' . esc_url( $wpsmushit_admin->upgrade_url ). '" target="_blank">', '</a>' ); ?>
666
  </div>
667
  </div>
668
  <?php
@@ -675,5 +927,73 @@ if ( ! class_exists( 'WpSmushBulkUi' ) ) {
675
  echo '</div><!-- End of Container wrap -->
676
  </div> <!-- End of div wrap -->';
677
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
678
  }
679
  }
19
  */
20
  class WpSmushBulkUi {
21
 
 
 
 
 
 
 
 
22
  /**
23
  * Prints the Header Section for a container as per the Shared UI
24
  *
34
  return '';
35
  }
36
  echo '<section class="dev-box ' . $classes . ' wp-smush-container" id="' . $id . '">'; ?>
37
+ <div class="wp-smush-container-header box-title" xmlns="http://www.w3.org/1999/html">
38
+ <h3 tabindex="0"><?php echo $heading ?></h3><?php
39
  //Sub Heading
40
  if ( ! empty( $sub_heading ) ) { ?>
41
  <div class="smush-container-subheading roboto-medium"><?php echo $sub_heading ?></div><?php
61
  //Header Of the Box
62
  $this->container_header( 'wp-smush-welcome', 'wp-smush-welcome-box', esc_html__( "WELCOME", "wp-smushit" ), '', true );
63
  //Settings Page heading
64
+ $plugin_name = $WpSmush->validate_install() ? "WP Smush Pro" : "WP Smush";
65
  ?>
66
  <!-- Content -->
67
  <div class="box-content">
84
  //Subheading content
85
  $smush_individual_msg = sprintf( esc_html__( "Smush individual images via your %sMedia Library%s", "wp-smushit" ), '<a href="' . esc_url( admin_url( 'upload.php' ) ) . '" title="' . esc_html__( 'Media Library', 'wp-smushit' ) . '">', '</a>' );
86
 
87
+ $class = $WpSmush->validate_install() ? 'bulk-smush-wrapper wp-smush-pro-install' : 'bulk-smush-wrapper';
88
 
89
  //Contianer Header
90
  $this->container_header( $class, 'wp-smush-bulk-wrap-box', esc_html__( "BULK SMUSH", "wp-smushit" ), $smush_individual_msg ); ?>
100
  */
101
  function settings_ui() {
102
  global $WpSmush;
103
+ $class = $WpSmush->validate_install() ? 'smush-settings-wrapper wp-smush-pro' : 'smush-settings-wrapper';
104
  $this->container_header( $class, 'wp-smush-settings-box', esc_html__( "SETTINGS", "wp-smushit" ), '' );
105
  // display the options
106
  $this->options_ui();
107
  }
108
 
109
  /**
110
+ * Outputs the Smush stats for the site
111
+ * @todo: Divide the function into parts, way too big
112
+ *
113
+ */
114
  function smush_stats_container() {
115
+ global $WpSmush, $wpsmushit_admin, $wpsmush_db, $wpsmush_settings;
 
 
 
 
116
 
117
+ $button = '<span class="spinner"></span><button tooltip="' . esc_html__( "Lets you check if any images can be further optimized. Useful after changing settings.", "wp-smushit" ) . '" class="wp-smush-title button button-grey button-small wp-smush-scan">' . esc_html__( "RE-CHECK IMAGES", "wp-smushit" ) . '</button>';
118
+ $this->container_header( 'smush-stats-wrapper', 'wp-smush-stats-box', esc_html__( "STATS", "wp-smushit" ), $button );
119
+ $dasharray = 125.663706144;
120
+ $dash_offset = $wpsmushit_admin->total_count > 0 ? $dasharray - ( $dasharray * ( $wpsmushit_admin->smushed_count / $wpsmushit_admin->total_count) ) : $dasharray;
121
+ $tooltip = $wpsmushit_admin->stats['total_images'] > 0 ? 'tooltip="' . sprintf( esc_html__("You've smushed %d images in total", "wp-smushit"), $wpsmushit_admin->stats['total_images'] ) . '"' : ''; ?>
122
  <div class="box-content">
123
+ <div class="row smush-total-savings smush-total-reduction-percent">
124
+
125
+ <div class="wp-smush-current-progress" >
126
+ <div class="wp-smushed-progress">
127
+ <div class="wp-smush-score inside">
128
+ <div class="tooltip-box">
129
+ <div class="wp-smush-optimisation-progress">
130
+ <div class="wp-smush-progress-circle">
131
+ <svg class="wp-smush-svg" xmlns="http://www.w3.org/2000/svg" width="50" height="50">
132
+ <circle class="wp-smush-svg-circle" r="20" cx="25" cy="25" fill="transparent" stroke-dasharray="0" stroke-dashoffset="0"></circle>
133
+ <!-- Stroke Dasharray is 2 PI r -->
134
+ <circle class="wp-smush-svg-circle wp-smush-svg-circle-progress" r="20" cx="25" cy="25" fill="transparent" stroke-dasharray="<?php echo $dasharray; ?>" style="stroke-dashoffset: <?php echo $dash_offset; ?>px;"></circle>
135
+ </svg>
136
+ </div>
137
+ </div>
138
+ </div><!-- end tooltip-box -->
139
+ </div>
140
+ </div>
141
+
142
+ <div class="wp-smush-count-total">
143
+ <div class="wp-smush-smush-stats-wrapper">
144
+ <span class="wp-smush-total-optimised"><?php echo $wpsmushit_admin->stats['total_images']; ?></span>
145
+ </div>
146
+ <span class="total-stats-label"><strong><?php esc_html_e( "IMAGES SMUSHED", "wp-smushit" ); ?></strong></span>
147
+ </div>
148
+ </div>
149
  </div>
150
+ <hr />
151
+ <div class="row wp-smush-savings">
152
+ <span class="float-l wp-smush-stats-label"><strong><?php esc_html_e("TOTAL SAVINGS", "wp-smushit");?></strong></span>
153
+ <span class="float-r wp-smush-stats">
154
+ <span class="wp-smush-stats-human">
155
+ <?php echo $wpsmushit_admin->stats['human'] > 0 ? $wpsmushit_admin->stats['human'] : "0MB"; ?>
156
+ </span>
157
+ <span class="wp-smush-stats-sep">/</span>
158
+ <span class="wp-smush-stats-percent"><?php echo $wpsmushit_admin->stats['percent'] > 0 ? number_format_i18n( $wpsmushit_admin->stats['percent'], 1, '.', '' ) : 0; ?></span>%
159
+ </span>
160
  </div><?php
161
  /**
162
  * Allows to hide the Super Smush stats as it might be heavy for some users
163
  */
164
+ if ( $WpSmush->validate_install() && apply_filters( 'wp_smush_show_lossy_stats', true ) ) {
165
+ $wpsmushit_admin->super_smushed = $wpsmush_db->super_smushed_count();?>
166
+ <hr />
167
  <div class="row super-smush-attachments">
168
+ <span class="float-l wp-smush-stats-label"><strong><?php esc_html_e( "ATTACHMENTS SUPER-SMUSHED", "wp-smushit" ); ?></strong></span>
169
+ <span class="float-r wp-smush-stats<?php echo $WpSmush->lossy_enabled ? '' : ' wp-smush-lossy-disabled-wrap' ?>"><?php
170
+ if ( $WpSmush->lossy_enabled ) {
171
+ echo '<span class="smushed-count">' . intval( $wpsmushit_admin->super_smushed ) . '</span>/' . $wpsmushit_admin->total_count;
172
+ } else {
173
+ //Output a button/link to enable respective setting
174
+ if( !is_multisite() || !get_site_option( WP_SMUSH_PREFIX . 'networkwide', 1 ) ) {
175
+ //@todo:Print a link to settings page for network sites
176
+ printf( esc_html__( "%sENABLE SUPER-SMUSH%s", "wp-smushit" ), '<button class="wp-smush-lossy-enable button button-small">', '</button>' );
177
+ }else {
178
+ $settings_link = $wpsmushit_admin->settings_link( array(), true );
179
+ printf( esc_html__( "%sENABLE SUPER-SMUSH%s", "wp-smushit" ), '<a href="' . $settings_link .'" class="wp-smush-lossy-enable button button-small">', '</a>' );
180
+ }
181
+ } ?>
182
+ </span>
183
+ </div><?php
184
+ } ?>
185
+ <hr />
186
+ <div class="row smush-resize-savings">
187
+ <span class="float-l wp-smush-stats-label"><strong><?php esc_html_e( "RESIZE SAVINGS", "wp-smushit" ); ?></strong></span>
188
+ <span class="float-r wp-smush-stats"><?php
189
+ if( !empty( $wpsmushit_admin->stats['resize_savings'] ) && $wpsmushit_admin->stats['resize_savings'] > 0 ) {
190
+ echo size_format( $wpsmushit_admin->stats['resize_savings'], 1 );
191
+ }else{
192
+ if( !$wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'resize' ) ) {
193
+ //Output a button/link to enable respective setting
194
+ if( !is_multisite() || !get_site_option( WP_SMUSH_PREFIX . 'networkwide', 1 ) ) {
195
+ printf( esc_html__( "%sENABLE IMAGE RESIZING%s", "wp-smushit" ), '<button class="wp-smush-resize-enable button button-small">', '</button>' );
196
+ }else {
197
+ $settings_link = $wpsmushit_admin->settings_link( array(), true );
198
+ printf( esc_html__( "%sENABLE IMAGE RESIZING%s", "wp-smushit" ), '<a href="' . $settings_link .'" class="wp-smush-lossy-enable button button-small">', '</a>' );
199
+ }
200
+ }else{
201
+ printf( esc_html__( "%sNO RESIZE SAVINGS AVAILABLE%s", "wp-smushit" ), '<span class="total-stats-label"><strong>', '</strong></span>' );
202
+ }
203
+ } ?>
204
+ </span>
205
+ </div>
206
+ <?php
207
+ if( $WpSmush->validate_install() && !empty( $wpsmushit_admin->stats['conversion_savings'] ) && $wpsmushit_admin->stats['conversion_savings'] > 0 ) { ?>
208
+ <hr />
209
+ <div class="row smush-conversion-savings">
210
+ <span class="float-l wp-smush-stats-label"><strong><?php esc_html_e( "PNG TO JPEG SAVINGS", "wp-smushit" ); ?></strong></span>
211
+ <span class="float-r wp-smush-stats"><?php echo $wpsmushit_admin->stats['conversion_savings'] > 0 ? size_format( $wpsmushit_admin->stats['conversion_savings'], 1 ) : "0MB"; ?></span>
212
  </div><?php
213
  }
214
+ /**
215
+ * Allows to output Directory Smush stats
216
+ */
217
+ do_action('stats_ui_after_resize_savings');
218
  /**
219
  * Allows you to output any content within the stats box at the end
220
  */
221
  do_action( 'wp_smush_after_stats' );
222
+ echo "</div>";
223
+ //Pro Savings Expected: For free Version
224
+ if ( ! $WpSmush->validate_install() ) {
225
+ //Initialize pro savings if not set already
226
+ if( empty( $wpsmushit_admin->stats) || empty( $wpsmushit_admin->stats['pro_savings'] ) ) {
227
+ $wpsmushit_admin->set_pro_savings();
228
+ }
229
+ $pro_savings = $wpsmushit_admin->stats['pro_savings'];
230
+ $show_pro_savings = $pro_savings['savings'] > 0 ? true : false;
231
+
232
+ //If we have any savings
233
+ $upgrade_url = add_query_arg(
234
+ array(
235
+ 'utm_source' => 'Smush-Free',
236
+ 'utm_medium' => 'Banner',
237
+ 'utm_campaign'=> 'pro-only-stats'
238
+ ),
239
+ $wpsmushit_admin->upgrade_url
240
+ );
241
+ $pro_only = sprintf( esc_html__( '%sPRO FEATURE%s', 'wp-smushit' ), '<a href="' . esc_url( $upgrade_url ) . '" target="_blank" tooltip="'. esc_html__( "Join WPMU DEV to try Smush Pro for free.", "wp-smushit" ) .'">', '</a>' ); ?>
242
+ <!-- Make a hidden div if not stats found -->
243
+ <div class="row" id="smush-avg-pro-savings" <?php echo $show_pro_savings ? '' : 'style="display: none;"'; ?>>
244
+ <div class="row smush-avg-pro-savings">
245
+ <span class="float-l wp-smush-stats-label"><span tooltip="<?php esc_html_e("BASED ON AVERAGE SAVINGS IF YOU UPGRADE TO PRO", "wp-smushit"); ?>"><strong><?php esc_html_e( "PRO SAVINGS ESTIMATE", "wp-smushit" ); ?></strong></span><span class="wp-smush-stats-try-pro roboto-regular"><?php echo $pro_only; ?></span></span>
246
+ <span class="float-r wp-smush-stats">
247
+ <span class="wp-smush-stats-human">
248
+ <?php echo $show_pro_savings ? $pro_savings['savings']: '0.0 B'; ?>
249
+ </span>
250
+ <span class="wp-smush-stats-sep">/</span>
251
+ <span class="wp-smush-stats-percent"><?php echo $show_pro_savings ? $pro_savings['percent'] : 0; ?></span>%
252
+ </span>
253
+ </div>
254
+ </div><?php
255
+ }
256
  echo "</section>";
257
  }
258
 
260
  * Outputs the advanced settings for Pro users, Disabled for basic users by default
261
  */
262
  function advanced_settings( $configure_screen = false ) {
263
+ global $WpSmush, $wpsmushit_admin, $wpsmush_settings;
264
 
265
  //Content for the End of box container
266
+ $div_end = $this->save_button( $configure_screen );
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
  //For Basic User, Show advanced settings in a separate box
269
+ if ( ! $WpSmush->validate_install() ) {
270
  echo $div_end;
271
+ do_action('wp_smush_before_advanced_settings');
272
+ //Network settings wrapper
273
+ if( is_multisite() && is_network_admin() ) {
274
+ $class = get_site_option( WP_SMUSH_PREFIX . 'networkwide', 1 ) ? '' : ' hidden'; ?>
275
+ <div class="network-settings-wrapper<?php echo $class; ?>"><?php
276
+ }
277
+ $upgrade_url = add_query_arg(
278
+ array(
279
+ 'utm_source' => 'Smush-Free',
280
+ 'utm_medium' => 'Banner',
281
+ 'utm_campaign'=> 'pro-only-advanced-settings'
282
+ ),
283
+ $wpsmushit_admin->upgrade_url
284
+ );
285
+ $pro_only = sprintf( esc_html__( '%sPRO FEATURE%s', 'wp-smushit' ), '<a href="' . esc_url( $upgrade_url ) . '" target="_blank" tooltip="'. esc_html__( "Join WPMU DEV to try Smush Pro for free.", "wp-smushit" ) .'">', '</a>' );
286
 
287
  $this->container_header( 'wp-smush-premium', 'wp-smush-pro-settings-box', esc_html__( "ADVANCED SETTINGS", "wp-smushit" ), $pro_only, false ); ?>
288
  <div class="box-content"><?php
290
 
291
  //Available advanced settings
292
  $pro_settings = array(
 
293
  'lossy',
294
+ 'original',
295
  'backup',
296
+ 'png_to_jpg'
297
  );
298
 
299
+ $pro_settings = apply_filters( 'wp_smush_pro_settings', $pro_settings );
300
+
301
+ if ( $WpSmush->validate_install() ) {
302
  echo "<hr />";
303
  }
304
 
306
  foreach ( $pro_settings as $setting_key ) {
307
  if ( isset( $wpsmushit_admin->settings[ $setting_key ] ) ) {
308
  $setting_m_key = WP_SMUSH_PREFIX . $setting_key;
309
+ $setting_val = $WpSmush->validate_install() ? $wpsmush_settings->get_setting( $setting_m_key, false ) : 0; ?>
310
  <div class='wp-smush-setting-row wp-smush-advanced'>
311
+ <label class="inline-label" for="<?php echo $setting_m_key; ?>" tabindex="0">
312
  <span
313
  class="wp-smush-setting-label"><?php echo $wpsmushit_admin->settings[ $setting_key ]['label']; ?></span>
314
  <br/>
320
  <input type="checkbox" class="toggle-checkbox"
321
  id="<?php echo $setting_m_key; ?>" <?php checked( $setting_val, 1, true ); ?>
322
  value="1"
323
+ name="<?php echo $setting_m_key; ?>" tabindex= "0">
324
  <label class="toggle-label" for="<?php echo $setting_m_key; ?>"></label>
325
  </span>
326
+ <?php
327
+ /**
328
+ * Perform a action after setting row content
329
+ */
330
+ do_action('smush_setting_row_end', $setting_key );?>
331
  </div>
332
  <hr><?php
333
  }
334
  }
335
  //Output Form end and Submit button for pro version
336
+ if ( $WpSmush->validate_install() ) {
337
  echo $div_end;
338
  } else {
339
  echo "</div><!-- Box Content -->
340
  </section><!-- Main Section -->";
341
  }
342
+ //Close wrapper div
343
+ if( is_multisite() && is_network_admin() && !$WpSmush->validate_install() ) {
344
+ echo "</div>";
345
+ }
346
  }
347
 
348
  /**
349
  * Process and display the options form
350
  */
351
  function options_ui( $configure_screen = false ) {
352
+ global $wpsmushit_admin, $wpsmush_settings;
353
  echo '<div class="box-container">
354
  <form id="wp-smush-settings-form" method="post">';
355
+
356
+ //Get max. dimesnions
357
+ $max_sizes = $wpsmushit_admin->get_max_image_dimensions();
358
+
359
+ //Placeholder width and Height
360
+ $p_width = $p_height = 2048;
361
+
362
+ //Use settings networkwide,@uses get_site_option() and not get_option
363
+ $opt_networkwide = WP_SMUSH_PREFIX . 'networkwide';
364
+ $opt_networkwide_val = get_site_option( $opt_networkwide, true );
365
+
366
  //Smush auto key
367
  $opt_auto = WP_SMUSH_PREFIX . 'auto';
368
  //Auto value
369
+ $opt_auto_val = $wpsmush_settings->get_setting( $opt_auto, false );
370
 
371
  //If value is not set for auto smushing set it to 1
372
  if ( $opt_auto_val === false ) {
376
 
377
  //Keep Exif
378
  $opt_keep_exif = WP_SMUSH_PREFIX . 'keep_exif';
379
+ $opt_keep_exif_val = $wpsmush_settings->get_setting( $opt_keep_exif, false );
380
+
381
+ //Resize images
382
+ $opt_resize = WP_SMUSH_PREFIX . 'resize';
383
+ $opt_resize_val = $wpsmush_settings->get_setting( $opt_resize, false );
384
+
385
+ //Dimensions
386
+ $resize_sizes = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'resize_sizes', array( 'width' => '', 'height' => '' ) );
387
+
388
+ //Additional Image sizes
389
+ $image_sizes = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'image_sizes', false );
390
+ $sizes = $wpsmushit_admin->image_dimensions();
391
+
392
+ //Option to enable/disable networkwide settings
393
+ if( is_multisite() && is_network_admin() ) {
394
+ $class = get_site_option( WP_SMUSH_PREFIX . 'networkwide', 1 ) ? '' : ' hidden'; ?>
395
+ <!-- A tab index of 0 keeps the element in tab flow with other elements with an unspecified tab index which are still tabbable.) -->
396
+ <div class='wp-smush-setting-row wp-smush-basic'>
397
+ <label class="inline-label" for="<?php echo $opt_networkwide; ?>" tabindex="0">
398
+ <span class="wp-smush-setting-label">
399
+ <?php echo $wpsmushit_admin->settings['networkwide']['label']; ?>
400
+ </span><br/>
401
+ <small class="smush-setting-description">
402
+ <?php echo $wpsmushit_admin->settings['networkwide']['desc']; ?>
403
+ </small>
404
+ </label>
405
  <span class="toggle float-r">
406
  <input type="checkbox" class="toggle-checkbox"
407
+ id="<?php echo $opt_networkwide; ?>"
408
+ name="<?php echo $opt_networkwide; ?>" <?php checked( $opt_networkwide_val, 1, true ); ?> value="1" tabindex="0">
409
+ <label class="toggle-label" for="<?php echo $opt_networkwide; ?>"></label>
410
+ </span>
411
+ </div>
412
+ <input type="hidden" name="setting-type" value="network">
413
+ <hr />
414
+ <div class="network-settings-wrapper<?php echo $class; ?>"><?php
415
+ }
416
+
417
+ //Do not print settings in network page if networkwide settings are disabled
418
+ if( ! is_multisite() || ( ! get_site_option( WP_SMUSH_PREFIX . 'networkwide', 1 ) && !is_network_admin() ) || is_network_admin() ) { ?>
419
+ <div class='wp-smush-setting-row wp-smush-basic'>
420
+ <label class="inline-label" for="<?php echo $opt_auto; ?>" tabindex="0">
421
+ <span class="wp-smush-setting-label">
422
+ <?php echo $wpsmushit_admin->settings['auto']['label']; ?>
423
+ </span><br/>
424
+ <small class="smush-setting-description">
425
+ <?php echo $wpsmushit_admin->settings['auto']['desc']; ?>
426
+ </small>
427
+ </label>
428
+ <span class="toggle float-r">
429
+ <input type="checkbox" class="toggle-checkbox"
430
+ id="<?php echo $opt_auto; ?>"
431
+ name="<?php echo $opt_auto; ?>" <?php checked( $opt_auto_val, 1, true ); ?> value="1" tabindex="0">
432
  <label class="toggle-label" for="<?php echo $opt_auto; ?>"></label>
433
+ </span><?php
434
+ if( !empty( $sizes ) ) { ?>
435
+ <!-- List of image sizes recognised by WP Smush -->
436
+ <div class="wp-smush-image-size-list">
437
+ <p><?php esc_html_e("The following image sizes will be optimized by WP Smush:", "wp-smushit"); ?></p><?php
438
+ foreach ( $sizes as $size_k => $size ) {
439
+ //If image sizes array isn't set, mark all checked ( Default Values )
440
+ if ( false === $image_sizes ) {
441
+ $checked = true;
442
+ }else{
443
+ $checked = is_array( $image_sizes ) ? in_array( $size_k, $image_sizes ) : false;
444
+ } ?>
445
+ <label>
446
+ <input type="checkbox" id="wp-smush-size-<?php echo $size_k; ?>" <?php checked( $checked, true ); ?> name="wp-smush-image_sizes[]" value="<?php echo $size_k; ?>"><?php
447
+ if( isset( $size['width'], $size['height'] ) ) {
448
+ echo $size_k . " (" . $size['width'] . "x" . $size['height'] . ") ";
449
+ } ?>
450
+ </label><?php
451
+ } ?>
452
+ </div><?php
453
+ } ?>
454
+ </div>
455
+ <hr/>
456
+ <div class='wp-smush-setting-row wp-smush-basic'>
457
+ <label class="inline-label" for="<?php echo $opt_keep_exif; ?>" tabindex="0">
458
+ <span class="wp-smush-setting-label"><?php echo $wpsmushit_admin->settings['keep_exif']['label']; ?></span>
459
+ <br/>
460
+ <small class="smush-setting-description">
461
+ <?php echo $wpsmushit_admin->settings['keep_exif']['desc']; ?>
462
+ </small>
463
+ </label>
464
+ <span class="toggle float-r">
465
+ <input type="checkbox" class="toggle-checkbox"
466
+ id="<?php echo $opt_keep_exif; ?>" <?php checked( $opt_keep_exif_val, 1, true ); ?>
467
+ value="1" name="<?php echo $opt_keep_exif; ?>" tabindex="0">
468
+ <label class="toggle-label" for="<?php echo $opt_keep_exif; ?>"></label>
469
  </span>
470
+ </div>
471
+ <hr/>
472
+ <div class='wp-smush-setting-row wp-smush-basic'>
473
+ <label class="inline-label" for="<?php echo $opt_resize; ?>" tabindex="0">
474
+ <span class="wp-smush-setting-label"><?php echo $wpsmushit_admin->settings['resize']['label']; ?></span>
475
+ <br/>
476
+ <small class="smush-setting-description">
477
+ <?php echo $wpsmushit_admin->settings['resize']['desc']; ?>
478
+ </small>
479
+ </label>
480
+ <span class="toggle float-r">
481
+ <input type="checkbox" class="toggle-checkbox"
482
+ id="<?php echo $opt_resize; ?>" <?php echo $resize_checked = checked( $opt_resize_val, 1, false ); ?>
483
+ value="1" name="<?php echo $opt_resize; ?>" tabindex="0">
484
+ <label class="toggle-label" for="<?php echo $opt_resize; ?>"></label>
485
+ </span>
486
+ <div class="wp-smush-resize-settings-wrap<?php echo $resize_checked ? '' : ' hidden'?>">
487
+ <label for="<?php echo $opt_resize . '_width'; ?>"><?php esc_html_e("Max width", "wp-smushit"); ?>
488
+ <input type="text" id="<?php echo $opt_resize . '_width'; ?>" class="wp-smush-resize-input" value="<?php echo isset( $resize_sizes['width'] ) && '' != $resize_sizes['width'] ? $resize_sizes['width'] : $p_width; ?>" placeholder="<?php echo $p_width; ?>" name="<?php echo $opt_resize . '_width'; ?>" tabindex="0" width=100 /> px
489
+ </label>
490
+ <label for"<?php echo $opt_resize . '_height'; ?>"><?php esc_html_e("Max height", "wp-smushit"); ?>
491
+ <input type="text" id="<?php echo $opt_resize . '_height'; ?>" class="wp-smush-resize-input" value="<?php echo isset( $resize_sizes['height'] ) && '' != $resize_sizes['height'] ? $resize_sizes['height'] : $p_height; ?>" placeholder="<?php echo $p_height; ?>" name="<?php echo $opt_resize . '_height'; ?>" tabindex="0" width=100 /> px
492
+ </label>
493
+ <div class="wp-smush-resize-note"><?php printf( esc_html__("Currently, your largest image size is set at %s%dpx wide x %dpx high%s.", "wp-smushit"), '<strong>', $max_sizes['width'], $max_sizes['height'], '</strong>' ); ?></div>
494
+ <div class="wp-smush-settings-info wp-smush-size-info wp-smush-update-width hidden"><?php esc_html_e( "Just to let you know, the width you've entered is less than your largest image and may result in pixelation.", "wp-smushit" ); ?></div>
495
+ <div class="wp-smush-settings-info wp-smush-size-info wp-smush-update-height hidden"><?php esc_html_e( "Just to let you know, the height you’ve entered is less than your largest image and may result in pixelation.", "wp-smushit" ); ?></div>
496
+ </div>
497
+ </div><!-- End of Basic Settings --><?php
498
 
499
+ do_action( 'wp_smush_after_basic_settings' );
500
+ $this->advanced_settings( $configure_screen );
501
+ } else{
502
+ echo "<hr />";
503
+ echo $this->save_button( $configure_screen );
504
+ echo "</div><!-- Box Content -->
505
+ </section><!-- Main Section -->";
506
+ }
507
  }
508
 
509
  /**
510
  * Display the Whole page ui, Call all the other functions under this
511
  */
512
  function ui() {
513
+
514
  global $WpSmush, $wpsmushit_admin;
 
515
 
516
+ if( !$WpSmush->validate_install() ) {
517
+ //Reset Transient
518
+ $wpsmushit_admin->check_bulk_limit( true );
519
+ }
 
 
520
 
521
+ $this->smush_page_header();
522
+ $is_network = is_network_admin();
523
+
524
+ if( !$is_network ) {
525
+ //Show Configure screen for only a new installation and for only network admins
526
+ if ( ( 1 != get_site_option( 'wp-smush-hide_smush_welcome' ) && 1 != get_option( 'wp-smush-hide_smush_welcome' ) ) && 1 != get_option( 'hide_smush_features' ) && 0 >= $wpsmushit_admin->smushed_count && is_super_admin() ) {
527
+ echo '<div class="block float-l smush-welcome-wrapper">';
528
+ $this->welcome_screen();
529
+ echo '</div>';
530
+ } ?>
531
+
532
+ <!-- Bulk Smush Progress Bar -->
533
+ <div class="wp-smushit-container-left col-half float-l"><?php
534
+ //Bulk Smush Container
535
+ $this->bulk_smush_container();
536
+ ?>
537
+ </div>
538
 
539
+ <!-- Stats -->
540
+ <div class="wp-smushit-container-right col-half float-l"><?php
541
+ //Stats
542
+ $this->smush_stats_container();
543
+ if ( ! $WpSmush->validate_install() ) {
544
+ /**
545
+ * Allows to Hook in Additional Containers after Stats Box for free version
546
+ * Pro Version has a full width settings box, so we don't want to do it there
547
+ */
548
+ do_action( 'wp_smush_after_stats_box' );
549
+ } ?>
550
+ </div><!-- End Of Smushit Container right -->
551
+
552
+ <!-- Stats Share Widget -->
553
+ <div class="row"><?php
554
+ global $wpsmush_share;
555
+ $wpsmush_share->share_widget(); ?>
556
+ </div>
557
+ <?php
558
+ //End of "!is_network()' check
559
+ }?>
560
+
561
+ <!-- Settings -->
562
+ <div class="row"><?php
563
+ wp_nonce_field( 'save_wp_smush_options', 'wp_smush_options_nonce', '', true );
564
+ //Check if a network site and networkwide settings is enabled
565
+ if( ! is_multisite() || ( is_multisite() && ! get_site_option( WP_SMUSH_PREFIX . 'networkwide', true ) ) || ( is_multisite() && is_network_admin() ) ) {
566
  $this->settings_ui();
567
  }
 
 
568
 
569
+ do_action('smush_settings_ui_bottom');
570
+
571
+ //Validate Membership
572
+ if( !$wpsmushit_admin->validate_install() ) {?>
573
+ <div class="wp-smush-pro-for-free wp-smushit-container-left col-half float-l"><?php
574
+ $this->wp_smush_promo();?>
575
+ </div>
576
+ <div class="wp-smushit-container-left col-half float-l"><?php
577
+ $this->wp_smush_hummingbird_promo(); ?>
578
+ </div><?php
579
  } ?>
580
+ </div><?php
 
 
 
 
 
 
581
  $this->smush_page_footer();
582
  }
583
 
586
  */
587
  function wp_smush_promo() {
588
  global $wpsmushit_admin;
589
+ $this->container_header( 'wp-smush-pro-adv', 'wp-smush-pro-promo', "READY TO LEVEL UP YOUR WEB DEVELOPMENT?" );
590
+ $upgrade_url = add_query_arg(
591
+ array(
592
+ 'utm_source' => 'Smush-Free',
593
+ 'utm_medium' => 'Banner',
594
+ 'utm_campaign' => 'settings-sidebar'
595
+ ),
596
+ $wpsmushit_admin->upgrade_url
597
+ );
598
+ ?>
599
  <div class="box-content">
600
+ <p class="wp-smush-promo-content wp-smush-promo-content-2 roboto-medium">Create amazing websites, automate your workflow, and run your business like a well-oiled machine.
601
+ Get access to the tools that will win you more clients and help you spend less time working.
602
+ Start a free WPMU DEV trial today.</p>
 
603
  <span class="wp-smush-pro-cta tc">
604
+ <a href="<?php echo esc_url( $upgrade_url ); ?>"
605
+ class="button button-cta button-green" target="_blank">GET STARTED</a>
606
  </span>
607
+ </div><?php
 
 
608
  echo "</section>";
609
  }
610
 
616
  if ( class_exists( 'WP_Hummingbird' ) ) {
617
  return;
618
  }
619
+ $this->container_header( 'wp-smush-hb-adv', 'wp-smush-hb-promo', "OH YEAH, SMUSHING ON STEROIDS!" ); ?>
620
  <div class="box-content">
621
  <span class="wp-smush-hummingbird-image tc">
622
  <img src="<?php echo WP_SMUSH_URL . 'assets/images/hummingbird.png'; ?>"
623
  alt="<?php esc_html_e( "BOOST YOUR PERFORMANCE - HUMMINGBIRD", "wp-smushit" ); ?>">
624
+ </span>
625
  <p class="wp-smush-promo-content tc roboto-medium">Hummingbird goes beyond Smush compression with
626
  minification, caching, performance monitoring and more - every millisecond counts!</p>
627
  <span class="wp-smush-hb-cta tc roboto-medium">
646
  //If there are no images in Media Library
647
  if ( 0 >= $wpsmushit_admin->total_count ) { ?>
648
  <span class="wp-smush-no-image tc">
649
+ <img src="<?php echo WP_SMUSH_URL . 'assets/images/smush-no-media.png'; ?>"
650
  alt="<?php esc_html_e( "No attachments found - Upload some images", "wp-smushit" ); ?>">
651
  </span>
652
  <p class="wp-smush-no-images-content tc roboto-regular"><?php printf( esc_html__( "We haven’t found any images in your %smedia library%s yet so there’s no smushing to be done! Once you upload images, reload this page and start playing!", "wp-smushit" ), '<a href="' . esc_url( admin_url( 'upload.php' ) ) . '">', '</a>' ); ?></p>
656
  </span><?php
657
  } else { ?>
658
  <!-- Hide All done div if there are images pending -->
659
+ <div class="wp-smush-notice wp-smush-all-done<?php echo $all_done ? '' : ' hidden' ?>" tabindex="0">
660
+ <i class="dev-icon dev-icon-tick"></i><?php esc_html_e( "All images are smushed and up to date. Awesome!", "wp-smushit" ); ?>
661
  </div>
662
  <div class="wp-smush-bulk-wrapper <?php echo $all_done ? ' hidden' : ''; ?>"><?php
663
  //If all the images in media library are smushed
667
  //Show the notice only if there are remaining images and if we aren't showing a notice for resmush
668
  if ( $wpsmushit_admin->remaining_count > 0 ) {
669
  $class = count( $wpsmushit_admin->resmush_ids ) > 0 ? ' hidden' : '';
670
+ $upgrade_url = add_query_arg(
671
+ array(
672
+ 'utm_source' => 'Smush-Free',
673
+ 'utm_medium' => 'Banner',
674
+ 'utm_campaign' => 'yellow-bulk-smush-upsell'
675
+ ),
676
+ $wpsmushit_admin->upgrade_url
677
+ );
678
  ?>
679
+ <div class="wp-smush-notice wp-smush-remaining<?php echo $class; ?>" tabindex="0">
680
+ <i class="dev-icon">
681
+ <img src="<?php echo WP_SMUSH_URL . 'assets/images/icon-gzip.svg'; ?>" width="14px">
682
+ </i>
683
+ <span class="wp-smush-notice-text"><?php
684
+ printf( _n( "%s, you have %s%s%d%s attachment%s that needs smushing!", "%s, you have %s%s%d%s attachments%s that need smushing!", $wpsmushit_admin->remaining_count, "wp-smushit" ), $wpsmushit_admin->get_user_name(), '<strong>', '<span class="wp-smush-remaining-count">', $wpsmushit_admin->remaining_count, '</span>', '</strong>' );
685
+ if( !$WpSmush->validate_install() && $wpsmushit_admin->remaining_count > 50 ) {
686
+ printf( esc_html__(" %sUpgrade to Pro%s to bulk smush all your images with one click.", "wp-smushit") , '<a href="' . esc_url( $upgrade_url ). '" target="_blank" title="' . esc_html__("WP Smush Pro", "wp-smushit") . '">', '</a>' );
687
+ esc_html_e(" Free users can smush 50 images with each click.", "wp-smushit");
688
+ }?>
689
  </span>
690
  </div><?php
691
  } ?>
692
  <hr>
 
693
  <button type="button" class="wp-smush-all wp-smush-button"><?php echo $button_content; ?></button><?php
694
  //Enable Super Smush
695
+ if ( $WpSmush->validate_install() && ! $WpSmush->lossy_enabled ) { ?>
696
  <p class="wp-smush-enable-lossy"><?php esc_html_e( "Enable Super-smush in the Settings area to get even more savings with almost no noticeable quality loss.", "wp-smushit" ); ?></p><?php
697
  } ?>
698
  </div><?php
706
  */
707
  function progress_bar( $count ) {
708
 
709
+ //If we have resmush list, smushed_count = totalcount - resmush count, else smushed_count
710
+ // $smushed_count = ( $resmush_count = count( $count->resmush_ids ) ) > 0 ? ( $count->total_count - ( $count->remaining_count + $resmush_count ) ) : $count->smushed_count;
711
  // calculate %ages, avoid divide by zero error with no attachments
712
  if ( $count->total_count > 0 && $count->smushed_count > 0 ) {
713
  $smushed_pc = $count->smushed_count / $count->total_count * 100;
714
  } else {
715
  $smushed_pc = 0;
716
+ } ?>
 
 
717
  <div class="wp-smush-bulk-progress-bar-wrapper hidden">
718
  <p class="wp-smush-bulk-active roboto-medium"><span
719
+ class="spinner is-active"></span><?php printf( esc_html__( "%sBulk smush is currently running.%s You need to keep this page open for the process to complete.", "wp-smushit" ), '<strong>', '</strong>' ); ?>
720
  </p>
721
  <div class="wp-smush-progress-wrap">
722
  <div class="wp-smush-progress-bar-wrap">
726
  </div>
727
  </div>
728
  <div class="wp-smush-count tc">
729
+ <?php printf( esc_html__( "%s%d%s of your media attachments have been smushed." ), '<span class="wp-smush-images-percent">', $smushed_pc, '</span>%' ); ?>
730
  </div>
731
  </div>
 
732
  <hr class="wp-smush-sep">
733
  <button type="button"
734
  class="button button-grey wp-smush-cancel-bulk"><?php esc_html_e( "CANCEL", "wp-smushit" ); ?></button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
735
  </div>
736
+ <div class="smush-final-log notice notice-warning inline hidden"></div><?php
 
 
 
 
 
 
 
 
737
  }
738
 
739
  /**
760
  $wpsmushit_admin->setup_global_stats();
761
  }
762
 
763
+ $count = $wpsmushit_admin->remaining_count;
764
  }
765
  }
766
  //Show only if we have any images to ber resmushed
767
  if ( $show ) {
768
+ return '<div class="wp-smush-notice wp-smush-resmush-notice wp-smush-remaining" tabindex="0">
769
  <i class="dev-icon"><img src="' . WP_SMUSH_URL . 'assets/images/icon-gzip.svg" width="14px"></i>
770
+ <span class="wp-smush-notice-text">' . sprintf( _n( "%s, you have %s%s%d%s attachment%s that needs re-compressing!", "%s, you have %s%s%d%s attachments%s that need re-compressing!", $count, "wp-smushit" ), $wpsmushit_admin->get_user_name(), '<strong>', '<span class="wp-smush-remaining-count">', $count, '</span>', '</strong>' ) . '</span>
771
  <button class="button button-grey button-small wp-smush-skip-resmush">' . esc_html__( "Skip", "wp-smushit" ) . '</button>
772
  </div>';
773
  }
777
  * Displays a admin notice for settings update
778
  */
779
  function settings_updated() {
780
+ global $wpsmushit_admin, $wpsmush_settings;
781
+
782
+ //Check if Networkwide settings are enabled, Do not show settings updated message
783
+ if( is_multisite() && get_site_option( WP_SMUSH_PREFIX . 'networkwide', 1 ) && !is_network_admin() ) {
784
+ return;
785
+ }
786
+
787
  //Show Setttings Saved message
788
+ if ( 1 == $wpsmush_settings->get_setting( 'wp-smush-settings_updated', false ) ) {
789
 
790
  //Default message
791
  $message = esc_html__( "Your settings have been updated!", "wp-smushit" );
802
  </div>';
803
 
804
  //Remove the option
805
+ $wpsmush_settings->delete_setting( 'wp-smush-settings_updated' );
806
  }
807
  }
808
 
814
  //Include Shared UI
815
  require_once WP_SMUSH_DIR . 'assets/shared-ui/plugin-ui.php';
816
 
817
+ if( $wpsmushit_admin->remaining_count == 0 || $wpsmushit_admin->smushed_count == 0 ) {
818
+ //Initialize global Stats
819
+ $wpsmushit_admin->setup_global_stats();
820
+ }
821
 
822
  //Page Heading for Free and Pro Version
823
+ $page_heading = $WpSmush->validate_install() ? esc_html__( 'WP Smush Pro', 'wp-smushit' ) : esc_html__( 'WP Smush', 'wp-smushit' );
824
 
825
  $auto_smush_message = $WpSmush->is_auto_smush_enabled() ? sprintf( esc_html__( "Automatic smushing is %senabled%s. Newly uploaded images will be automagically compressed." ), '<span class="wp-smush-auto-enabled">', '</span>' ) : sprintf( esc_html__( "Automatic smushing is %sdisabled%s. Newly uploaded images will need to be manually smushed." ), '<span class="wp-smush-auto-disabled">', '</span>' );
826
+
827
+ //User API check, and display a message if not valid
828
+ $user_validation = $this->get_user_validation_message();
829
+
830
+ //Re-Check images notice
831
+ $recheck_notice = $this->get_recheck_message();
832
+
833
+ echo '<div class="smush-page-wrap">
834
+ <section id="header">
835
+ <div class="wp-smush-page-header">
836
+ <h1 class="wp-smush-page-heading">' . $page_heading . '</h1>
837
+ <div class="wp-smush-auto-message roboto-regular">' . $auto_smush_message . '</div>
838
+ </div>' .
839
+ $user_validation .
840
+ $recheck_notice .
841
+ '</section>';
842
  //Check if settings were updated and shoe a notice
843
  $this->settings_updated();
844
 
852
  global $wpsmushit_admin;
853
 
854
  //Whether New/Existing Installation
855
+ $install_type = get_site_option('wp-smush-install-type', false );
856
 
857
  if( !$install_type ) {
858
  $install_type = $wpsmushit_admin->smushed_count > 0 ? 'existing' : 'new';
859
+ update_site_option( 'wp-smush-install-type', $install_type );
860
  }
861
 
862
  if ( 'new' == $install_type ) {
863
  $notice_heading = esc_html__( "Thanks for installing Smush. We hope you like it!", "wp-smushit" );
864
  $notice_content = esc_html__( "And hey, if you do, you can now try out Smush Pro for double the smushy goodness (benchmarked), entirely for free!", "wp-smushit" );
865
+ $button_content = esc_html__( "Try Smush Pro for Free", "wp-smushit" );
866
  } else {
867
+ $notice_heading = esc_html__( "Thanks for updating Smush. Did you know that you can now try the Smush Pro for FREE?!", "wp-smushit" );
868
+ $notice_content = '<br />' . esc_html__( "Yep, Super Smush your images for double the savings, save originals and batch Smush thousands of images all at once.... no charge!", "wp-smushit" );
869
+ $button_content = esc_html__( "Try Smush Pro for Free", "wp-smushit" );
870
+ }
871
+ $upgrade_url = add_query_arg(
872
+ array(
873
+ 'utm_source' => 'Smush-Free',
874
+ 'utm_medium' => 'Banner',
875
+ 'utm_campaign' => 'try-pro-free'
876
+ ),
877
+ $wpsmushit_admin->upgrade_url
878
+ );?>
879
+ <div class="notice smush-notice" style="display: none;">
880
+ <div class="smush-notice-logo"><span></span></div>
881
+ <div
882
+ class="smush-notice-message<?php echo 'new' == $install_type ? ' wp-smush-fresh' : ' wp-smush-existing'; ?>">
883
+ <strong><?php echo $notice_heading; ?></strong>
884
+ <?php echo $notice_content; ?>
885
+ </div>
886
+ <div class="smush-notice-cta">
887
+ <a href="<?php echo esc_url( $upgrade_url ); ?>" class="smush-notice-act button-primary" target="_blank">
888
+ <?php echo $button_content; ?>
889
+ </a>
890
+ <button class="smush-notice-dismiss smush-dismiss-welcome" data-msg="<?php esc_html_e( 'Saving', 'wp-smushit'); ?>"><?php esc_html_e( 'Dismiss', "wp-smushit" ); ?></button>
891
  </div>
 
892
  </div><?php
893
+ //Notice CSS
894
+ wp_enqueue_style('wp-smushit-notice-css');
895
+ //Notice JS
896
+ wp_enqueue_script('wp-smushit-notice-js', '', array(), '', true );
897
  }
898
 
899
  /**
901
  */
902
  function super_smush_promo() {
903
  global $WpSmush, $wpsmushit_admin;
904
+ if ( $WpSmush->validate_install() ) {
905
  return;
906
+ }
907
+ $upgrade_url = add_query_arg(
908
+ array(
909
+ 'utm_source' => 'Smush-Free',
910
+ 'utm_medium' => 'Banner',
911
+ 'utm_campaign' => 'smush-lady-upgrade'
912
+ ),
913
+ $wpsmushit_admin->upgrade_url
914
+ ); ?>
915
  <div class="wp-smush-super-smush-promo">
916
  <div class="wp-smush-super-smush-content"><?php
917
+ printf( esc_html__("Did you know WP Smush Pro delivers up to 2x better compression, allows you to smush your originals and removes any bulk smushing limits? – %sTry it absolutely FREE%s", "wp-smushit"), '<a href="' . esc_url( $upgrade_url ). '" target="_blank" title="' . esc_html__("Try WP Smush Pro for FREE", "wp-smushit") . '">', '</a>' ); ?>
918
  </div>
919
  </div>
920
  <?php
927
  echo '</div><!-- End of Container wrap -->
928
  </div> <!-- End of div wrap -->';
929
  }
930
+
931
+ /**
932
+ * Returns a Warning message if API key is not validated
933
+ *
934
+ * @return string Warning Message to be displayed on Bulk Smush Page
935
+ *
936
+ */
937
+ function get_user_validation_message( $notice = false ) {
938
+ $notice_class = $notice ? ' notice' : '';
939
+ $wpmu_contact = sprintf( '<a href="%s" target="_blank">', esc_url("https://premium.wpmudev.org/contact") );
940
+ $attr_message = esc_html__("Validating..", "wp-smushit");
941
+ $recheck_link = '<a href="#" id="wp-smush-revalidate-member" data-message="%s">';
942
+ $message = sprintf( esc_html__( "It looks like Smush couldn’t verify your WPMU DEV membership so Pro features like Super-Smush may not work correctly. If you think this is an error, run a %sre-check%s or get in touch with our %ssupport team%s.", "wp-smushit"), $recheck_link, '</a>', $wpmu_contact, '</a>' ) ;
943
+ $content = sprintf( '<div id="wp-smush-invalid-member" data-message="%s" class="hidden' . $notice_class . '"><div class="message">%s</div></div>', $attr_message, $message );
944
+ return $content;
945
+ }
946
+
947
+ /**
948
+ *
949
+ * @param $configure_screen
950
+ *
951
+ * @return string
952
+ *
953
+ */
954
+ function save_button( $configure_screen = false ) {
955
+ $div_end = '';
956
+ //Close wrapper div
957
+ if( is_multisite() && is_network_admin() ) {
958
+ $div_end .= "</div>";
959
+ }
960
+
961
+ $div_end .=
962
+ '<div class="wp-smush-submit-wrap">
963
+ <input type="submit" id="wp-smush-save-settings" class="button button-grey"
964
+ value="' . esc_html__( 'UPDATE SETTINGS', 'wp-smushit' ) . '">
965
+ <span class="spinner"></span>
966
+ </div>
967
+ </form>';
968
+
969
+ //For Configuration screen we need to show the advanced settings in single box
970
+ if ( ! $configure_screen ) {
971
+ $div_end .= '</div><!-- Box Content -->
972
+ </section><!-- Main Section -->';
973
+ }
974
+ return $div_end;
975
+ }
976
+
977
+ function get_recheck_message() {
978
+ //Return if not multisite, or on network settings page, Netowrkwide settings is disabled
979
+ if( ! is_multisite() || is_network_admin() || ! get_site_option( WP_SMUSH_PREFIX . 'networkwide' ) ) {
980
+ return;
981
+ }
982
+ global $wpsmush_settings, $wpsmushit_admin;
983
+
984
+ //Check the last settings stored in db
985
+ $settings = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'last_settings', '' );
986
+
987
+ //Get current settings
988
+ $c_settings = $wpsmushit_admin->get_serialised_settings();
989
+
990
+ //If not same, Display notice
991
+ if( $settings == $c_settings ) {
992
+ return;
993
+ }
994
+ $message = '<div class="wp-smush-notice wp-smush-re-check-message">' . esc_html__( "Smush settings were updated, performing a quick scan to check if any of the images need to be Smushed again.", "wp-smushit") . '<i class="dev-icon dev-icon-cross"></i></div>';
995
+
996
+ return $message;
997
+ }
998
  }
999
  }
lib/class-wp-smush.php CHANGED
@@ -1,5 +1,33 @@
1
  <?php
 
 
 
 
 
 
 
 
2
  require_once WP_SMUSH_DIR . "lib/class-wp-smush-migrate.php";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  if ( ! class_exists( 'WpSmush' ) ) {
4
 
5
  class WpSmush {
@@ -15,7 +43,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
15
  * Api server url to check api key validity
16
  *
17
  */
18
- var $api_server = 'https://premium.wpmudev.org/wdp-un.php?action=smushit_check';
19
 
20
  /**
21
  * Meta key to save smush result to db
@@ -48,6 +76,16 @@ if ( ! class_exists( 'WpSmush' ) ) {
48
  */
49
  var $keep_exif = false;
50
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  * Constructor
53
  */
@@ -61,8 +99,8 @@ if ( ! class_exists( 'WpSmush' ) ) {
61
  */
62
  add_filter( 'wp_update_attachment_metadata', array(
63
  $this,
64
- 'filter_generate_attachment_metadata'
65
- ), 12, 2 );
66
 
67
  //Delete Backup files
68
  add_action( 'delete_attachment', array(
@@ -80,91 +118,103 @@ if ( ! class_exists( 'WpSmush' ) ) {
80
  //Manage column sorting
81
  add_action( 'pre_get_posts', array( $this, 'smushit_orderby' ) );
82
 
83
- //Enqueue Scripts
84
  add_action( 'admin_init', array( $this, 'admin_init' ) );
85
 
86
- //Old Smush stats migration
87
- add_action( "admin_init", array( $this, "migrate" ) );
88
-
89
- //Load Translation files
90
- add_action( 'plugins_loaded', array( $this, 'i18n' ), 12 );
91
 
92
- //Load NextGen Gallery, if hooked too late or early, auto smush doesn't works, also Load after settings have been saved on init action
93
- add_action( 'plugins_loaded', array( $this, 'load_nextgen' ), 90 );
94
 
95
  //Send Smush Stats for pro members
96
- add_filter( 'wpmudev_api_project_extra_data-912164', array( $this, 'send_smush_stats') );
97
 
98
- }
 
 
 
 
 
 
 
99
 
100
- function i18n() {
101
- load_plugin_textdomain( 'wp-smushit', false, WP_SMUSH_DIR . '/languages/' );
102
  }
103
 
104
  /**
105
  * Initialise the setting variables
106
  */
107
  function initialise() {
 
 
 
108
  //Check if Lossy enabled
109
  $opt_lossy = WP_SMUSH_PREFIX . 'lossy';
110
- $this->lossy_enabled = $this->is_pro() && get_option( $opt_lossy, false );
111
 
112
  //Check if Smush Original enabled
113
  $opt_original = WP_SMUSH_PREFIX . 'original';
114
- $this->smush_original = $this->is_pro() && get_option( $opt_original, false );
115
 
116
  //Check Whether to keep exif or not
117
  $opt_keep_exif = WP_SMUSH_PREFIX . 'keep_exif';
118
- $this->keep_exif = get_option( $opt_keep_exif, false );
119
  }
120
 
121
  function admin_init() {
122
- wp_enqueue_script( 'common' );
 
 
 
 
 
 
 
 
123
  //Initialize variables
124
  $this->initialise();
 
 
 
 
 
 
125
  }
126
 
127
  /**
128
  * Process an image with Smush.
129
  *
130
- * Returns an array of the $file $results.
131
  *
132
- * @param string $file Full absolute path to the image file
133
- * @param string $file_url Optional full URL to the image file
134
  *
135
- * @returns array
136
  */
137
  function do_smushit( $file_path = '' ) {
138
- global $wpsmushit_admin;
139
  $errors = new WP_Error();
140
  $dir_name = dirname( $file_path );
 
 
141
  if ( empty( $file_path ) ) {
142
  $errors->add( "empty_path", __( "File path is empty", 'wp-smushit' ) );
143
- }
144
-
145
- // check that the file exists
146
- if ( ! file_exists( $file_path ) || ! is_file( $file_path ) ) {
147
  $errors->add( "file_not_found", sprintf( __( "Could not find %s", 'wp-smushit' ), $file_path ) );
148
- }
149
-
150
- // check that the file is writable
151
- if ( ! is_writable( $dir_name ) ) {
152
  $errors->add( "not_writable", sprintf( __( "%s is not writable", 'wp-smushit' ), $dir_name ) );
153
  }
154
 
155
  $file_size = file_exists( $file_path ) ? filesize( $file_path ) : '';
156
 
157
  //Check if premium user
158
- $max_size = $this->is_pro() ? WP_SMUSH_PREMIUM_MAX_BYTES : WP_SMUSH_MAX_BYTES;
159
 
160
  //Check if file exists
161
  if ( $file_size == 0 ) {
162
- $errors->add( "image_not_found", '<p>' . sprintf( __( 'Skipped (%s), image not found. Attachment: %s', 'wp-smushit' ), $this->format_bytes( $file_size ), basename( $file_path ) ) . '</p>' );
163
- }
164
-
165
- //Check size limit
166
- if ( $file_size > $max_size ) {
167
- $errors->add( "size_limit", '<p>' . sprintf( __( 'Skipped (%s), size limit exceeded. Attachment: %s', 'wp-smushit' ), $this->format_bytes( $file_size ), basename( $file_path ) ) . '</p>' );
168
  }
169
 
170
  if ( count( $errors->get_error_messages() ) ) {
@@ -173,16 +223,15 @@ if ( ! class_exists( 'WpSmush' ) ) {
173
 
174
  // save original file permissions
175
  clearstatcache();
176
- $perms = fileperms($file_path) & 0777;
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-smushit' ) );
187
  }
188
 
@@ -201,16 +250,6 @@ if ( ! class_exists( 'WpSmush' ) ) {
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
- //Check for backup from other plugins, like nextgen, if it doesn't exists, create our own
208
- if ( ! file_exists( $file_path . '_backup' ) ) {
209
- $backup_name = $wpsmushit_admin->get_image_backup_path( $file_path );
210
- @copy( $file_path, $backup_name );
211
- }
212
- }
213
-
214
  //replace the file
215
  $success = @rename( $tempfile, $file_path );
216
 
@@ -226,12 +265,12 @@ if ( ! class_exists( 'WpSmush' ) ) {
226
  }
227
 
228
  //Some servers are having issue with file permission, this should fix it
229
- if( empty( $perms ) || !$perms ) {
230
  //Source: WordPress Core
231
  $stat = stat( dirname( $file_path ) );
232
  $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
233
  }
234
- @ chmod( $file_path, $perms );
235
 
236
  return $response;
237
  }
@@ -261,21 +300,22 @@ if ( ! class_exists( 'WpSmush' ) ) {
261
  */
262
  function _get_size_signature() {
263
  return array(
264
- 'percent' => - 1,
265
- 'bytes' => - 1,
266
- 'size_before' => - 1,
267
- 'size_after' => - 1,
268
- 'time' => - 1
269
  );
270
  }
271
 
272
  /**
 
 
 
 
273
  * Read the image paths from an attachment's meta data and process each image
274
  * with wp_smushit().
275
  *
276
- * This method also adds a `wp_smushit` meta key for use in the media library.
277
- * Called after `wp_generate_attachment_metadata` is completed.
278
- *
279
  * @param $meta
280
  * @param null $ID
281
  *
@@ -283,9 +323,11 @@ if ( ! class_exists( 'WpSmush' ) ) {
283
  */
284
  function resize_from_meta_data( $meta, $ID = null ) {
285
 
 
 
286
  //Flag to check, if original size image should be smushed or not
287
- $original = get_option( WP_SMUSH_PREFIX . 'original' );
288
- $smush_full = ( $this->is_pro() && $original == 1 ) ? true : false;
289
 
290
  $errors = new WP_Error();
291
  $stats = array(
@@ -304,8 +346,12 @@ if ( ! class_exists( 'WpSmush' ) ) {
304
  return $meta;
305
  }
306
 
 
 
 
 
307
  //File path and URL for original image
308
- $attachment_file_path = get_attached_file( $ID );
309
 
310
  // If images has other registered size, smush them first
311
  if ( ! empty( $meta['sizes'] ) ) {
@@ -325,14 +371,25 @@ if ( ! class_exists( 'WpSmush' ) ) {
325
  } else {
326
  $finfo = false;
327
  }
 
328
  foreach ( $meta['sizes'] as $size_key => $size_data ) {
329
 
 
 
 
 
 
330
  // We take the original image. The 'sizes' will all match the same URL and
331
  // path. So just get the dirname and replace the filename.
332
  $attachment_file_path_size = path_join( dirname( $attachment_file_path ), $size_data['file'] );
333
 
 
 
 
 
 
334
  if ( $finfo ) {
335
- $ext = file_exists( $attachment_file_path_size ) ? $finfo->file( $attachment_file_path_size ) : '';
336
  } elseif ( function_exists( 'mime_content_type' ) ) {
337
  $ext = mime_content_type( $attachment_file_path_size );
338
  } else {
@@ -371,26 +428,23 @@ if ( ! class_exists( 'WpSmush' ) ) {
371
  }
372
 
373
  //If there are no stats
374
- if( empty( $response['data'] ) ) {
375
  continue;
376
  }
377
 
378
  //If the image size grew after smushing, skip it
379
- if( $response['data']->after_size > $response['data']->before_size ) {
380
  continue;
381
  }
382
 
383
  //All Clear, Store the stat
 
384
  $stats['sizes'][ $size_key ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $response['data'] );
385
 
386
- //Total Stats, store all data in bytes
387
- list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
388
- = $this->_update_stats_data( $response['data'], $size_before, $size_after, $total_time, $bytes_saved );
389
-
390
  if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
391
  $stats['stats']['api_version'] = $response['data']->api_version;
392
  $stats['stats']['lossy'] = $response['data']->lossy;
393
- $stats['stats']['keep_exif'] = !empty( $response['data']->keep_exif ) ? $response['data']->keep_exif : 0;
394
  }
395
  }
396
  //Upfront Integration
@@ -420,12 +474,12 @@ if ( ! class_exists( 'WpSmush' ) ) {
420
  }
421
 
422
  //If there are no stats
423
- if( empty( $full_image_response['data'] ) ) {
424
  $store_stats = false;
425
  }
426
 
427
  //If the image size grew after smushing, skip it
428
- if( $full_image_response['data']->after_size > $full_image_response['data']->before_size ) {
429
  $store_stats = false;
430
  }
431
 
@@ -433,45 +487,24 @@ if ( ! class_exists( 'WpSmush' ) ) {
433
  $stats['sizes']['full'] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $full_image_response['data'] );
434
  }
435
 
436
- //Update stats
437
- if ( $store_stats ) {
438
- list( $size_before, $size_after, $total_time, $compression, $bytes_saved )
439
- = $this->_update_stats_data( $full_image_response['data'], $size_before, $size_after, $total_time, $bytes_saved );
440
- }
441
-
442
  //Api version and lossy, for some images, full image i skipped and for other images only full exists
443
  //so have to add code again
444
  if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
445
  $stats['stats']['api_version'] = $full_image_response['data']->api_version;
446
  $stats['stats']['lossy'] = $full_image_response['data']->lossy;
447
- $stats['stats']['keep_exif'] = !empty( $full_image_response['data']->keep_exif ) ? $full_image_response['data']->keep_exif : 0;
448
  }
449
 
450
  }
451
 
452
  $has_errors = (bool) count( $errors->get_error_messages() );
453
 
454
- list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
455
- array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
456
-
457
  //Set smush status for all the images, store it in wp-smpro-smush-data
458
  if ( ! $has_errors ) {
459
 
460
  $existing_stats = get_post_meta( $ID, $this->smushed_meta_key, true );
461
 
462
  if ( ! empty( $existing_stats ) ) {
463
- $e_size_before = isset( $existing_stats['stats']['size_before'] ) ? $existing_stats['stats']['size_before'] : '';
464
- $e_size_after = isset( $existing_stats['stats']['size_after'] ) ? $existing_stats['stats']['size_after'] : '';
465
- //Store Original size before
466
- $stats['stats']['size_before'] = ! empty( $e_size_before ) && $e_size_before > $stats['stats']['size_before'] ? $e_size_before : $stats['stats']['size_before'];
467
-
468
- if ( $size_after == 0 || empty( $stats['stats']['size_after'] ) || $stats['stats']['size_after'] == $stats['stats']['size_before'] ) {
469
- $stats['stats']['size_after'] = $e_size_after < $stats['stats']['size_before'] ? $e_size_after : $stats['stats']['size_before'];
470
- }
471
-
472
- //Update total bytes saved, and compression percent
473
- $stats['stats']['bytes'] = isset( $existing_stats['stats']['bytes'] ) ? $existing_stats['stats']['bytes'] + $stats['stats']['bytes'] : $stats['stats']['bytes'];
474
- $stats['stats']['percent'] = $this->calculate_percentage( (object) $stats['stats'], (object) $existing_stats['stats'] );
475
 
476
  //Update stats for each size
477
  if ( isset( $existing_stats['sizes'] ) && ! empty( $stats['sizes'] ) ) {
@@ -482,10 +515,10 @@ if ( ! class_exists( 'WpSmush' ) ) {
482
  $stats['sizes'][ $size_name ] = $existing_stats['sizes'][ $size_name ];
483
  } else {
484
 
485
- $existing_stats_size = (object)$existing_stats['sizes'][ $size_name ];
486
 
487
  //store the original image size
488
- $stats['sizes'][ $size_name ]->size_before = ( !empty( $existing_stats_size->size_before ) && $existing_stats_size->size_before > $stats['sizes'][ $size_name ]->size_before ) ? $existing_stats_size->size_before : $stats['sizes'][ $size_name ]->size_before;
489
 
490
  //Update compression percent and bytes saved for each size
491
  $stats['sizes'][ $size_name ]->bytes = $stats['sizes'][ $size_name ]->bytes + $existing_stats_size->bytes;
@@ -494,21 +527,32 @@ if ( ! class_exists( 'WpSmush' ) ) {
494
  }
495
  }
496
  }
 
 
 
 
497
  //If there was any compression and there was no error in smushing
498
- if( isset( $stats['stats']['bytes'] ) && $stats['stats']['bytes'] >= 0 && !$has_errors ) {
499
  /**
500
  * Runs if the image smushing was successful
501
  *
502
- * @param int $ID Image Id
503
  *
504
  * @param array $stats Smush Stats for the image
505
- *
506
  */
507
- do_action('wp_smush_image_optimised', $ID, $stats );
508
  }
509
  update_post_meta( $ID, $this->smushed_meta_key, $stats );
510
  }
511
 
 
 
 
 
 
 
 
512
  return $meta;
513
  }
514
 
@@ -516,8 +560,6 @@ if ( ! class_exists( 'WpSmush' ) ) {
516
  * Read the image paths from an attachment's meta data and process each image
517
  * with wp_smushit()
518
  *
519
- * Filters wp_generate_attachment_metadata
520
- *
521
  * @uses resize_from_meta_data
522
  *
523
  * @param $meta
@@ -525,21 +567,70 @@ if ( ! class_exists( 'WpSmush' ) ) {
525
  *
526
  * @return mixed
527
  */
528
- function filter_generate_attachment_metadata( $meta, $ID = null ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
529
  //Check if auto is enabled
530
  $auto_smush = $this->is_auto_smush_enabled();
531
 
 
 
 
532
  //Auto Smush the new image
533
  if ( $auto_smush ) {
534
- //Update API url for Hostgator
535
 
 
 
 
 
536
  //Check for use of http url, (Hostgator mostly)
537
  $use_http = wp_cache_get( WP_SMUSH_PREFIX . 'use_http', 'smush' );
538
  if ( ! $use_http ) {
539
- $use_http = get_option( WP_SMUSH_PREFIX . 'use_http' );
540
  wp_cache_add( WP_SMUSH_PREFIX . 'use_http', $use_http, 'smush' );
541
  }
542
- if( $use_http ) {
543
  //HTTP Url
544
  define( 'WP_SMUSH_API_HTTP', 'http://smushpro.wpmudev.org/1.0/' );
545
  }
@@ -551,6 +642,9 @@ if ( ! class_exists( 'WpSmush' ) ) {
551
  delete_post_meta( $ID, $this->smushed_meta_key );
552
  }
553
 
 
 
 
554
  return $meta;
555
  }
556
 
@@ -564,11 +658,12 @@ if ( ! class_exists( 'WpSmush' ) ) {
564
  * @return bool|array array containing success status, and stats
565
  */
566
  function _post( $file_path, $file_size ) {
 
567
 
568
  $data = false;
569
 
570
- $file = @fopen( $file_path, 'r' );
571
- $file_data = fread( $file, $file_size );
572
  $headers = array(
573
  'accept' => 'application/json', // The API returns JSON
574
  'content-type' => 'application/binary', // Set content type to binary
@@ -580,7 +675,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
580
  $headers['apikey'] = $api_key;
581
  }
582
 
583
- if ( $this->lossy_enabled && $this->is_pro() ) {
584
  $headers['lossy'] = 'true';
585
  } else {
586
  $headers['lossy'] = 'false';
@@ -595,10 +690,10 @@ if ( ! class_exists( 'WpSmush' ) ) {
595
  'timeout' => WP_SMUSH_TIMEOUT,
596
  'user-agent' => WP_SMUSH_UA,
597
  );
 
 
598
  $result = wp_remote_post( $api_url, $args );
599
 
600
- //Close file connection
601
- fclose( $file );
602
  unset( $file_data );//free memory
603
  if ( is_wp_error( $result ) ) {
604
 
@@ -607,7 +702,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
607
  //Hostgator Issue
608
  if ( ! empty( $er_msg ) && strpos( $er_msg, 'SSL CA cert' ) !== false ) {
609
  //Update DB for using http protocol
610
- update_option( WP_SMUSH_PREFIX . 'use_http', 1 );
611
  }
612
  //Handle error
613
  $data['message'] = sprintf( __( 'Error posting to API: %s', 'wp-smushit' ), $result->get_error_message() );
@@ -647,6 +742,10 @@ if ( ! class_exists( 'WpSmush' ) ) {
647
  $data['success'] = true;
648
  $data['data'] = $response->data;
649
  }
 
 
 
 
650
  } else {
651
  //Server side error, get message from response
652
  $data['message'] = ! empty( $response->data ) ? $response->data : __( "Image couldn't be smushed", 'wp-smushit' );
@@ -658,7 +757,6 @@ if ( ! class_exists( 'WpSmush' ) ) {
658
  return $data;
659
  }
660
 
661
-
662
  /**
663
  * Print column header for Smush results in the media library using
664
  * the `manage_media_columns` hook.
@@ -673,14 +771,14 @@ if ( ! class_exists( 'WpSmush' ) ) {
673
  * Return the filesize in a humanly readable format.
674
  * Taken from http://www.php.net/manual/en/function.filesize.php#91477
675
  */
676
- function format_bytes( $bytes, $precision = 2 ) {
677
- $units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
678
  $bytes = max( $bytes, 0 );
679
  $pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
680
  $pow = min( $pow, count( $units ) - 1 );
681
  $bytes /= pow( 1024, $pow );
682
 
683
- return round( $bytes, $precision ) . ' ' . $units[ $pow ];
684
  }
685
 
686
  /**
@@ -698,7 +796,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
698
  *
699
  * @return mixed|string
700
  */
701
- function is_pro() {
702
 
703
  if ( isset( $this->is_pro ) ) {
704
  return $this->is_pro;
@@ -723,7 +821,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
723
  $last_checked = $api_auth[ $api_key ]['timestamp'];
724
  $valid = $api_auth[ $api_key ]['validity'];
725
 
726
- $diff = $last_checked - current_time( 'timestamp' );
727
 
728
  //Difference in hours
729
  $diff_h = $diff / 3600;
@@ -768,7 +866,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
768
  update_site_option( 'wp_smush_api_auth', $api_auth );
769
 
770
  // call api
771
- $url = $this->api_server . '&key=' . urlencode( $api_key );
772
 
773
  $request = wp_remote_get( $url, array(
774
  "user-agent" => WP_SMUSH_UA,
@@ -778,7 +876,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
778
 
779
  if ( ! is_wp_error( $request ) && '200' == wp_remote_retrieve_response_code( $request ) ) {
780
  $result = json_decode( wp_remote_retrieve_body( $request ) );
781
- if ( $result && $result->success ) {
782
  $valid = 'valid';
783
  } else {
784
  $valid = 'invalid';
@@ -847,19 +945,29 @@ if ( ! class_exists( 'WpSmush' ) ) {
847
  * @return string|void
848
  */
849
  function set_status( $id, $echo = true, $text_only = false, $wrapper = true ) {
 
850
  $status_txt = $button_txt = $stats = '';
851
  $show_button = $show_resmush = false;
852
 
853
- $wp_smush_data = get_post_meta( $id, $this->smushed_meta_key, true );
 
 
 
 
 
 
 
 
 
854
  $attachment_data = wp_get_attachment_metadata( $id );
855
 
856
  // if the image is smushed
857
  if ( ! empty( $wp_smush_data ) ) {
858
 
859
  $image_count = count( $wp_smush_data['sizes'] );
860
- $bytes = isset( $wp_smush_data['stats']['bytes'] ) ? $wp_smush_data['stats']['bytes'] : 0;
861
- $bytes_readable = ! empty( $bytes ) ? $this->format_bytes( $bytes ) : '';
862
- $percent = isset( $wp_smush_data['stats']['percent'] ) ? $wp_smush_data['stats']['percent'] : 0;
863
  $percent = $percent < 0 ? 0 : $percent;
864
 
865
  if ( isset( $wp_smush_data['stats']['size_before'] ) && $wp_smush_data['stats']['size_before'] == 0 && ! empty( $wp_smush_data['sizes'] ) ) {
@@ -867,19 +975,30 @@ if ( ! class_exists( 'WpSmush' ) ) {
867
  $show_button = false;
868
  } else {
869
  if ( $bytes == 0 || $percent == 0 ) {
870
- $status_txt = __( 'Already Optimized', 'wp-smushit' );
871
 
872
  //Show resmush link, if the settings were changed
873
- $show_resmush = $this->show_resmush( $show_resmush, $wp_smush_data );
874
  if ( $show_resmush ) {
875
  $status_txt .= '<br />' . $this->get_resmsuh_link( $id );
876
  }
877
 
878
  } elseif ( ! empty( $percent ) && ! empty( $bytes_readable ) ) {
879
  $status_txt = $image_count > 1 ? sprintf( __( "%d images reduced ", 'wp-smushit' ), $image_count ) : __( "Reduced ", 'wp-smushit' );
880
- $status_txt .= sprintf( __( "by %s ( %01.1f%% )", 'wp-smushit' ), $bytes_readable, number_format_i18n( $percent, 2, '.', '' ) );
881
 
882
- $show_resmush = $this->show_resmush( $show_resmush, $wp_smush_data );
 
 
 
 
 
 
 
 
 
 
 
 
883
 
884
  if ( $show_resmush ) {
885
  $status_txt .= '<br />' . $this->get_resmsuh_link( $id );
@@ -934,12 +1053,24 @@ if ( ! class_exists( 'WpSmush' ) ) {
934
 
935
  //Check if premium user, compression was lossless, and lossy compression is enabled
936
  //If we are displaying the resmush option already, no need to show the Super Smush button
937
- if ( ! $show_resmush && $this->is_pro() && ! $is_lossy && $this->lossy_enabled && $image_type != 'image/gif' ) {
938
  // the button text
939
  $button_txt = __( 'Super-Smush', 'wp-smushit' );
940
  $show_button = true;
941
  }
942
 
 
 
 
 
 
 
 
 
 
 
 
 
943
  } else {
944
 
945
  // the status
@@ -954,8 +1085,9 @@ if ( ! class_exists( 'WpSmush' ) ) {
954
  if ( $text_only ) {
955
  //For ajax response
956
  return array(
957
- 'status' => $status_txt,
958
- 'stats' => $stats
 
959
  );
960
  }
961
 
@@ -1046,7 +1178,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
1046
  return;
1047
  }
1048
 
1049
- $migrated_version = get_option( $this->migrated_version_key );
1050
 
1051
  if ( $migrated_version === $this->version ) {
1052
  return;
@@ -1069,40 +1201,10 @@ if ( ! class_exists( 'WpSmush' ) ) {
1069
  }
1070
  }
1071
 
1072
- update_option( $this->migrated_version_key, $this->version );
1073
 
1074
  }
1075
 
1076
- /**
1077
- * Update the Given array by adding to existing values and returns a array of variables
1078
- *
1079
- * @param Object $response_data , Object containing the latest stats (before_size, after_size, time, bytes_saved)
1080
- * @param $size_before
1081
- * @param $size_after
1082
- * @param $total_time
1083
- * @param $bytes_saved
1084
- *
1085
- * @return array('size_before', 'size_after', 'total_time', 'compression', 'bytes_saved' )
1086
- */
1087
- function _update_stats_data( $response_data, $size_before, $size_after, $total_time, $bytes_saved ) {
1088
-
1089
- //If image is already optimised, do not add in stats
1090
- if( $response_data->before_size == $response_data->after_size ) {
1091
-
1092
- $compression = ( $bytes_saved > 0 && $size_before > 0 ) ? ( ( $bytes_saved / $size_before ) * 100 ) : 0;
1093
-
1094
- return array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
1095
- }
1096
-
1097
- $size_before += ! empty( $response_data->before_size ) ? (int) $response_data->before_size : 0;
1098
- $size_after += ( ! empty( $response_data->after_size ) && $response_data->after_size > 0 ) ? (int) $response_data->after_size : (int) $response_data->before_size;
1099
- $total_time += ! empty( $response_data->time ) ? (float) $response_data->time : 0;
1100
- $bytes_saved += ( ! empty( $response_data->bytes_saved ) && $response_data->bytes_saved > 0 ) ? $response_data->bytes_saved : 0;
1101
- $compression = ( $bytes_saved > 0 && $size_before > 0 ) ? ( ( $bytes_saved / $size_before ) * 100 ) : 0;
1102
-
1103
- return array( $size_before, $size_after, $total_time, $compression, $bytes_saved );
1104
- }
1105
-
1106
  /**
1107
  * Updates the smush stats for a single image size
1108
  *
@@ -1120,11 +1222,6 @@ if ( ! class_exists( 'WpSmush' ) ) {
1120
  $stats = get_post_meta( $id, $this->smushed_meta_key, true );
1121
  //Update existing Stats
1122
  if ( ! empty( $stats ) ) {
1123
- //Update total bytes saved, and compression percent
1124
- //Update Main Stats
1125
- list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
1126
- $this->_update_stats_data( $data, $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['bytes'] );
1127
-
1128
 
1129
  //Update stats for each size
1130
  if ( isset( $stats['sizes'] ) ) {
@@ -1150,16 +1247,15 @@ if ( ! class_exists( 'WpSmush' ) ) {
1150
  'sizes' => array()
1151
  );
1152
  $stats['stats']['api_version'] = $data->api_version;
1153
- $stats['stats']['lossy'] = $data->lossy;
1154
- $stats['stats']['keep_exif'] = ! empty( $data->keep_exif ) ? $data->keep_exif : 0;
1155
 
1156
- //Update Main Stats
1157
- list( $stats['stats']['size_before'], $stats['stats']['size_after'], $stats['stats']['time'], $stats['stats']['percent'], $stats['stats']['bytes'] ) =
1158
- array( $data->before_size, $data->after_size, $data->time, $data->compression, $data->bytes_saved );
1159
  //Update size wise details
1160
  $stats['sizes'][ $image_size ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $data );
1161
  }
1162
- //Calculate Percent
 
 
1163
  update_post_meta( $id, $this->smushed_meta_key, $stats );
1164
 
1165
  }
@@ -1173,6 +1269,10 @@ if ( ! class_exists( 'WpSmush' ) ) {
1173
  */
1174
  function smush_retina_image( $id, $retina_file, $image_size ) {
1175
 
 
 
 
 
1176
  /**
1177
  * Allows to Enable/Disable WP Retina 2x Integration
1178
  */
@@ -1187,6 +1287,11 @@ if ( ! class_exists( 'WpSmush' ) ) {
1187
  return;
1188
  }
1189
 
 
 
 
 
 
1190
  /**
1191
  * Allows to skip a image from smushing
1192
  *
@@ -1229,7 +1334,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
1229
  //If full image was not smushed, reason 1. Large Size logic, 2. Free and greater than 1Mb
1230
  if ( ! array_key_exists( 'full', $size_stats ) ) {
1231
  //For free version, Check the image size
1232
- if ( ! $this->is_pro() ) {
1233
  //For free version, check if full size is greater than 1 Mb, show the skipped status
1234
  $file_size = file_exists( $full_image ) ? filesize( $full_image ) : '';
1235
  if ( ! empty( $file_size ) && ( $file_size / WP_SMUSH_MAX_BYTES ) > 1 ) {
@@ -1304,6 +1409,8 @@ if ( ! class_exists( 'WpSmush' ) ) {
1304
  */
1305
  function get_detailed_stats( $image_id, $wp_smush_data, $attachment_metadata ) {
1306
 
 
 
1307
  $stats = '<div id="smush-stats-' . $image_id . '" class="smush-stats-wrapper hidden">
1308
  <table class="wp-smush-stats-holder">
1309
  <thead>
@@ -1335,10 +1442,18 @@ if ( ! class_exists( 'WpSmush' ) ) {
1335
  }
1336
  //Show Sizes and their compression
1337
  foreach ( $size_stats as $size_key => $size_value ) {
 
 
 
 
 
 
1338
  if ( $size_value->bytes > 0 ) {
 
 
1339
  $stats .= '<tr>
1340
- <td>' . strtoupper( $size_key ) . '</td>
1341
- <td>' . $this->format_bytes( $size_value->bytes ) . ' ( ' . $size_value->percent . '% )</td>
1342
  </tr>';
1343
  }
1344
  }
@@ -1361,35 +1476,66 @@ if ( ! class_exists( 'WpSmush' ) ) {
1361
  return $a->bytes < $b->bytes;
1362
  }
1363
 
 
 
 
 
 
 
 
 
 
 
 
1364
  /**
1365
  * Check if NextGen is active or not
1366
  * Include and instantiate classes
1367
  */
1368
  function load_nextgen() {
1369
- if ( ! class_exists( 'C_NextGEN_Bootstrap' ) || ! $this->is_pro() ) {
 
1370
  return;
1371
  }
 
 
1372
  //Check if integration is Enabled or not
1373
  //Smush NextGen key
1374
  $opt_nextgen = WP_SMUSH_PREFIX . 'nextgen';
1375
- $opt_nextgen_val = get_option( $opt_nextgen, 1 );
1376
- if ( ! $opt_nextgen_val ) {
1377
- return;
1378
- }
1379
 
1380
  require_once( WP_SMUSH_DIR . '/lib/class-wp-smush-nextgen.php' );
 
 
 
 
1381
  require_once( WP_SMUSH_DIR . '/lib/nextgen-integration/class-wp-smush-nextgen-admin.php' );
1382
  require_once( WP_SMUSH_DIR . '/lib/nextgen-integration/class-wp-smush-nextgen-stats.php' );
1383
  require_once( WP_SMUSH_DIR . '/lib/nextgen-integration/class-wp-smush-nextgen-bulk.php' );
1384
 
1385
  global $wpsmushnextgen, $wpsmushnextgenadmin, $wpsmushnextgenstats;
1386
  //Initialize Nextgen support
1387
- $wpsmushnextgen = new WpSmushNextGen();
1388
- $wpsmushnextgenadmin = new WpSmushNextGenAdmin();
 
1389
  $wpsmushnextgenstats = new WpSmushNextGenStats();
 
1390
  new WPSmushNextGenBulk();
1391
  }
1392
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1393
  /**
1394
  * Add the Smushit Column to sortable list
1395
  *
@@ -1453,20 +1599,46 @@ if ( ! class_exists( 'WpSmush' ) ) {
1453
 
1454
  //Get the image path for all sizes
1455
  $file = get_attached_file( $image_id );
 
 
 
 
1456
 
1457
- //Check backup for Full size
1458
- $backup = $wpsmushit_admin->get_image_backup_path( $file );
 
 
1459
 
1460
- //Check for backup of full image
1461
- if ( file_exists( $backup ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1462
  return true;
1463
  }
1464
 
1465
- //Check for backup of image sizes
1466
- foreach ( $attachment_data['sizes'] as $image_size ) {
1467
- $size_path = path_join( dirname( $file ), $image_size['file'] );
1468
- $size_backup_path = $wpsmushit_admin->get_image_backup_path( $size_path );
1469
- if ( file_exists( $size_backup_path ) ) {
 
 
 
 
1470
  return true;
1471
  }
1472
  }
@@ -1491,7 +1663,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
1491
 
1492
  $ajax_nonce = wp_create_nonce( "wp-smush-restore-" . $image_id );
1493
 
1494
- return sprintf( '<a href="#" tooltip="%s" data-id="%d" data-nonce="%s" class="%s">%s</a>', esc_html__( "Restore original image.", "wp-smushit" ), $image_id, $ajax_nonce, $class, esc_html__( "Restore image", "wp-smush" ) );
1495
  }
1496
 
1497
  /**
@@ -1509,7 +1681,10 @@ if ( ! class_exists( 'WpSmush' ) ) {
1509
  * @return int|mixed|void
1510
  */
1511
  function is_auto_smush_enabled() {
1512
- $auto_smush = get_option( WP_SMUSH_PREFIX . 'auto' );
 
 
 
1513
 
1514
  //Keep the auto smush on by default
1515
  if ( $auto_smush === false ) {
@@ -1536,7 +1711,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
1536
 
1537
  $ajax_nonce = wp_create_nonce( "wp-smush-resmush-" . $image_id );
1538
 
1539
- return sprintf( '<a href="#" tooltip="%s" data-id="%d" data-nonce="%s" class="%s">%s</a>', esc_html__( "Smush image including original file.", "wp-smushit" ), $image_id, $ajax_nonce, $class, esc_html__( "Resmush image", "wp-smush" ) );
1540
  }
1541
 
1542
  /**
@@ -1552,7 +1727,13 @@ if ( ! class_exists( 'WpSmush' ) ) {
1552
  if ( empty( $attachment_path ) ) {
1553
  return false;
1554
  }
1555
- $path = pathinfo( $attachment_path );
 
 
 
 
 
 
1556
  $backup_name = trailingslashit( $path['dirname'] ) . $path['filename'] . ".bak." . $path['extension'];
1557
 
1558
  return $backup_name;
@@ -1560,12 +1741,20 @@ if ( ! class_exists( 'WpSmush' ) ) {
1560
 
1561
  /**
1562
  * Deletes all the backup files when an attachment is deleted
1563
- * Update Resmush List
1564
  * Update Super Smush image count
1565
  *
1566
  * @param $image_id
 
1567
  */
1568
  function delete_images( $image_id ) {
 
 
 
 
 
 
 
1569
 
1570
  //If no image id provided
1571
  if ( empty( $image_id ) ) {
@@ -1579,7 +1768,6 @@ if ( ! class_exists( 'WpSmush' ) ) {
1579
  }
1580
 
1581
  /** Delete Backups **/
1582
-
1583
  //Check if we have any smush data for image
1584
  $this->delete_backup_files( $image_id );
1585
  }
@@ -1611,6 +1799,11 @@ if ( ! class_exists( 'WpSmush' ) ) {
1611
  if ( empty( $attachment_id ) || ! class_exists( 'Upfront' ) ) {
1612
  return $stats;
1613
  }
 
 
 
 
 
1614
  //Get post meta to check for Upfront images
1615
  $upfront_images = get_post_meta( $attachment_id, 'upfront_used_image_sizes', true );
1616
 
@@ -1633,7 +1826,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
1633
 
1634
  //If the smushing was successful
1635
  if ( ! is_wp_error( $res ) && ! empty( $res['data'] ) ) {
1636
- if( $res['data']->bytes_saved > 0 ) {
1637
  //Update attachment stats
1638
  $stats['sizes'][ $element_id ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $res['data'] );
1639
  }
@@ -1652,27 +1845,39 @@ if ( ! class_exists( 'WpSmush' ) ) {
1652
 
1653
  /**
1654
  * Checks the current settings and returns the value whether to enable or not the resmush option
1655
- * @param $show_resmush
 
1656
  * @param $wp_smush_data
1657
  *
1658
  * @return bool
1659
  */
1660
- function show_resmush( $show_resmush, $wp_smush_data ) {
1661
  //Resmush: Show resmush link, Check if user have enabled smushing the original and full image was skipped
1662
  //Or: If keep exif is unchecked and the smushed image have exif
 
1663
  if ( $this->smush_original ) {
1664
  //IF full image was not smushed
1665
  if ( ! empty( $wp_smush_data ) && empty( $wp_smush_data['sizes']['full'] ) ) {
1666
- $show_resmush = true;
1667
  }
1668
  }
1669
- if ( !$this->keep_exif ) {
1670
- //If Keep Exif was set to tru initially, and since it is set to false now
 
 
1671
  if ( isset( $wp_smush_data['stats']['keep_exif'] ) && $wp_smush_data['stats']['keep_exif'] == 1 ) {
1672
- $show_resmush = true;
1673
  }
1674
  }
1675
- return $show_resmush;
 
 
 
 
 
 
 
 
1676
  }
1677
 
1678
  /**
@@ -1688,7 +1893,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
1688
  return 0;
1689
  }
1690
  $size_before = ! empty( $stats->size_before ) ? $stats->size_before : $existing_stats->size_before;
1691
- $size_after = ! empty( $stats->size_after ) ? $stats->size_after : $existing_stats->size_after;
1692
  $savings = $size_before - $size_after;
1693
  if ( $savings > 0 ) {
1694
  $percentage = ( $savings / $size_before ) * 100;
@@ -1700,6 +1905,27 @@ if ( ! class_exists( 'WpSmush' ) ) {
1700
  return 0;
1701
  }
1702
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1703
  /**
1704
  * Redirects the user to Plugin settings page on Plugin activation
1705
  *
@@ -1709,39 +1935,44 @@ if ( ! class_exists( 'WpSmush' ) ) {
1709
  */
1710
  function wp_smush_redirect( $plugin ) {
1711
 
1712
- global $wpsmushit_admin;
1713
 
1714
  //Run for only our plugin
1715
- if( $plugin != WP_SMUSH_BASENAME ) {
1716
  return false;
1717
  }
1718
 
 
 
 
 
1719
  //Skip if bulk activation, Or if we have to skip redirection
1720
- if ( isset( $_GET['activate-multi'] ) || get_site_option('wp-smush-skip-redirect') ) {
1721
  return false;
1722
  }
1723
 
1724
  //If images are already smushed
1725
- if( $wpsmushit_admin->smushed_count() > 0 ) {
1726
  return false;
1727
  }
1728
 
1729
  $url = admin_url( 'upload.php' );
1730
  $url = add_query_arg(
1731
  array(
1732
- 'page' => 'wp-smush-bulk'
1733
  ),
1734
  $url
1735
  );
1736
 
1737
  //Store that we need not redirect again
1738
- add_site_option('wp-smush-skip-redirect', true );
1739
 
1740
  exit( wp_redirect( $url ) );
1741
  }
1742
 
1743
  /**
1744
  * Clear up all the backup files for the image, if any
 
1745
  * @param $image_id
1746
  */
1747
  function delete_backup_files( $image_id ) {
@@ -1778,6 +2009,269 @@ if ( ! class_exists( 'WpSmush' ) ) {
1778
  }
1779
  }
1780
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1781
  }
1782
 
1783
  global $WpSmush;
@@ -1786,5 +2280,7 @@ if ( ! class_exists( 'WpSmush' ) ) {
1786
  }
1787
 
1788
  //Include Admin classes
1789
- require_once( WP_SMUSH_DIR . 'lib/class-wp-smush-bulk.php' );
1790
- require_once( WP_SMUSH_DIR . 'lib/class-wp-smush-admin.php' );
 
 
1
  <?php
2
+
3
+ //Helper Class
4
+ require_once WP_SMUSH_DIR . "lib/class-wp-smush-helper.php";
5
+
6
+ //Settings Class
7
+ require_once WP_SMUSH_DIR . "lib/class-wp-smush-settings.php";
8
+
9
+ //Migration Class
10
  require_once WP_SMUSH_DIR . "lib/class-wp-smush-migrate.php";
11
+
12
+ //Stats
13
+ require_once WP_SMUSH_DIR . "lib/class-wp-smush-db.php";
14
+
15
+ //Include Resize class
16
+ require_once WP_SMUSH_DIR . 'lib/class-wp-smush-resize.php';
17
+
18
+ //Include PNG to JPG Converter
19
+ require_once WP_SMUSH_DIR . 'lib/class-wp-smush-png_jpg.php';
20
+
21
+ //Include Social Sharing
22
+ require_once WP_SMUSH_DIR . 'lib/class-wp-smush-share.php';
23
+
24
+ //Include Image backup class
25
+ require_once WP_SMUSH_DIR . 'lib/class-wp-smush-backup.php';
26
+
27
+ //Include Smush Async class
28
+ require_once WP_SMUSH_DIR . 'lib/class-wp-smush-async.php';
29
+
30
+
31
  if ( ! class_exists( 'WpSmush' ) ) {
32
 
33
  class WpSmush {
43
  * Api server url to check api key validity
44
  *
45
  */
46
+ var $api_server = 'https://premium.wpmudev.org/api/smush/v1/check/';
47
 
48
  /**
49
  * Meta key to save smush result to db
76
  */
77
  var $keep_exif = false;
78
 
79
+ /** @var Attachment id for the Image being smushed currently */
80
+ var $attachment_id;
81
+ /**
82
+ * Attachment type, being smushed currently
83
+ *
84
+ * @var string Possible values, "wp", "nextgen"
85
+ *
86
+ */
87
+ var $media_type = 'wp';
88
+
89
  /**
90
  * Constructor
91
  */
99
  */
100
  add_filter( 'wp_update_attachment_metadata', array(
101
  $this,
102
+ 'smush_image'
103
+ ), 15, 2 );
104
 
105
  //Delete Backup files
106
  add_action( 'delete_attachment', array(
118
  //Manage column sorting
119
  add_action( 'pre_get_posts', array( $this, 'smushit_orderby' ) );
120
 
121
+ //Enqueue Scripts, And Initialize variables
122
  add_action( 'admin_init', array( $this, 'admin_init' ) );
123
 
124
+ //Load NextGen Gallery, S3, if hooked too late or early, auto smush doesn't works, also Load after settings have been saved on init action
125
+ add_action( 'plugins_loaded', array( $this, 'load_modules' ), 90 );
 
 
 
126
 
127
+ //Send Smush Stats for pro members
128
+ add_filter( 'wpmudev_api_project_extra_data-912164', array( $this, 'send_smush_stats' ) );
129
 
130
  //Send Smush Stats for pro members
131
+ add_action( 'wp_ajax_smush_show_warning', array( $this, 'show_warning_ajax' ) );
132
 
133
+ //Instanitate the Async class
134
+ add_action( 'plugins_loaded', array( $this, 'wp_smush_async' ) );
135
+
136
+ //Handle the Async optimisation
137
+ add_action( 'wp_async_wp_generate_attachment_metadata', array( $this, 'wp_smush_handle_async' ) );
138
+
139
+ //Handle the Async optimisation
140
+ add_action( 'wp_async_wp_save_image_editor_file', array( $this, 'wp_smush_handle_editor_async' ), '', 2 );
141
 
 
 
142
  }
143
 
144
  /**
145
  * Initialise the setting variables
146
  */
147
  function initialise() {
148
+
149
+ global $wpsmush_settings;
150
+
151
  //Check if Lossy enabled
152
  $opt_lossy = WP_SMUSH_PREFIX . 'lossy';
153
+ $this->lossy_enabled = $this->validate_install() && $wpsmush_settings->get_setting( $opt_lossy, false );
154
 
155
  //Check if Smush Original enabled
156
  $opt_original = WP_SMUSH_PREFIX . 'original';
157
+ $this->smush_original = $this->validate_install() && $wpsmush_settings->get_setting( $opt_original, false );
158
 
159
  //Check Whether to keep exif or not
160
  $opt_keep_exif = WP_SMUSH_PREFIX . 'keep_exif';
161
+ $this->keep_exif = $wpsmush_settings->get_setting( $opt_keep_exif, false );
162
  }
163
 
164
  function admin_init() {
165
+
166
+ global $wpsmush_dir;
167
+
168
+ //Handle Notice dismiss
169
+ $this->dismiss_smush_upgrade();
170
+
171
+ //Perform Migration if required
172
+ $this->migrate();
173
+
174
  //Initialize variables
175
  $this->initialise();
176
+
177
+ //Create a clas object, if doesn't exists
178
+ if ( empty( $wpsmush_dir ) && class_exists( 'WpSmushDir' ) ) {
179
+ $wpsmush_dir = new WpSmushDir();
180
+ }
181
+ $wpsmush_dir->create_table();
182
  }
183
 
184
  /**
185
  * Process an image with Smush.
186
  *
187
+ * @param string $file_path Absolute path to the image
188
  *
189
+ * @return array|bool
 
190
  *
 
191
  */
192
  function do_smushit( $file_path = '' ) {
 
193
  $errors = new WP_Error();
194
  $dir_name = dirname( $file_path );
195
+
196
+ //Check if file exists and the directory is writable
197
  if ( empty( $file_path ) ) {
198
  $errors->add( "empty_path", __( "File path is empty", 'wp-smushit' ) );
199
+ } elseif ( ! file_exists( $file_path ) || ! is_file( $file_path ) ) {
200
+ // check that the file exists
 
 
201
  $errors->add( "file_not_found", sprintf( __( "Could not find %s", 'wp-smushit' ), $file_path ) );
202
+ } elseif ( ! is_writable( $dir_name ) ) {
203
+ // check that the file is writable
 
 
204
  $errors->add( "not_writable", sprintf( __( "%s is not writable", 'wp-smushit' ), $dir_name ) );
205
  }
206
 
207
  $file_size = file_exists( $file_path ) ? filesize( $file_path ) : '';
208
 
209
  //Check if premium user
210
+ $max_size = $this->validate_install() ? WP_SMUSH_PREMIUM_MAX_BYTES : WP_SMUSH_MAX_BYTES;
211
 
212
  //Check if file exists
213
  if ( $file_size == 0 ) {
214
+ $errors->add( "image_not_found", '<p>' . sprintf( __( 'Skipped (%s), image not found. Attachment: %s', 'wp-smushit' ), size_format( $file_size, 1 ), basename( $file_path ) ) . '</p>' );
215
+ } elseif ( $file_size > $max_size ) {
216
+ //Check size limit
217
+ $errors->add( "size_limit", '<p>' . sprintf( __( 'Skipped (%s), size limit exceeded. Attachment: %s', 'wp-smushit' ), size_format( $file_size, 1 ), basename( $file_path ) ) . '</p>' );
 
 
218
  }
219
 
220
  if ( count( $errors->get_error_messages() ) ) {
223
 
224
  // save original file permissions
225
  clearstatcache();
226
+ $perms = fileperms( $file_path ) & 0777;
227
 
228
  /** Send image for smushing, and fetch the response */
229
  $response = $this->_post( $file_path, $file_size );
230
 
231
  if ( ! $response['success'] ) {
232
  $errors->add( "false_response", $response['message'] );
233
+ } else if ( empty( $response['data'] ) ) {
234
+ //If there is no data
 
235
  $errors->add( "no_data", __( 'Unknown API error', 'wp-smushit' ) );
236
  }
237
 
250
  //Add the file as tmp
251
  file_put_contents( $tempfile, $response['data']->image );
252
 
 
 
 
 
 
 
 
 
 
 
253
  //replace the file
254
  $success = @rename( $tempfile, $file_path );
255
 
265
  }
266
 
267
  //Some servers are having issue with file permission, this should fix it
268
+ if ( empty( $perms ) || ! $perms ) {
269
  //Source: WordPress Core
270
  $stat = stat( dirname( $file_path ) );
271
  $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
272
  }
273
+ @chmod( $file_path, $perms );
274
 
275
  return $response;
276
  }
300
  */
301
  function _get_size_signature() {
302
  return array(
303
+ 'percent' => 0,
304
+ 'bytes' => 0,
305
+ 'size_before' => 0,
306
+ 'size_after' => 0,
307
+ 'time' => 0
308
  );
309
  }
310
 
311
  /**
312
+ * Optimises the image sizes
313
+ *
314
+ * Note: Function name is bit confusing, it is for optimisation, and calls the resizing function as well
315
+ *
316
  * Read the image paths from an attachment's meta data and process each image
317
  * with wp_smushit().
318
  *
 
 
 
319
  * @param $meta
320
  * @param null $ID
321
  *
323
  */
324
  function resize_from_meta_data( $meta, $ID = null ) {
325
 
326
+ global $wpsmush_settings, $wpsmush_helper, $wpsmushit_admin;
327
+
328
  //Flag to check, if original size image should be smushed or not
329
+ $original = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'original', false );
330
+ $smush_full = ( $this->validate_install() && $original == 1 ) ? true : false;
331
 
332
  $errors = new WP_Error();
333
  $stats = array(
346
  return $meta;
347
  }
348
 
349
+ //Set attachment id and Media type
350
+ $this->attachment_id = $ID;
351
+ $this->media_type = "wp";
352
+
353
  //File path and URL for original image
354
+ $attachment_file_path = $wpsmush_helper->get_attached_file( $ID );
355
 
356
  // If images has other registered size, smush them first
357
  if ( ! empty( $meta['sizes'] ) ) {
371
  } else {
372
  $finfo = false;
373
  }
374
+
375
  foreach ( $meta['sizes'] as $size_key => $size_data ) {
376
 
377
+ //Check if registered size is supposed to be Smushed or not
378
+ if ( 'full' != $size_key && $wpsmushit_admin->skip_image_size( $size_key ) ) {
379
+ continue;
380
+ }
381
+
382
  // We take the original image. The 'sizes' will all match the same URL and
383
  // path. So just get the dirname and replace the filename.
384
  $attachment_file_path_size = path_join( dirname( $attachment_file_path ), $size_data['file'] );
385
 
386
+ /**
387
+ * Allows S3 to hook over here and check if the given file path exists else download the file
388
+ */
389
+ do_action('smush_file_exists', $attachment_file_path_size, $ID, $size_data );
390
+
391
  if ( $finfo ) {
392
+ $ext = is_file( $attachment_file_path_size ) ? $finfo->file( $attachment_file_path_size ) : '';
393
  } elseif ( function_exists( 'mime_content_type' ) ) {
394
  $ext = mime_content_type( $attachment_file_path_size );
395
  } else {
428
  }
429
 
430
  //If there are no stats
431
+ if ( empty( $response['data'] ) ) {
432
  continue;
433
  }
434
 
435
  //If the image size grew after smushing, skip it
436
+ if ( $response['data']->after_size > $response['data']->before_size ) {
437
  continue;
438
  }
439
 
440
  //All Clear, Store the stat
441
+ //@todo: Move the existing stats code over here, we don't need to do the stats part twice
442
  $stats['sizes'][ $size_key ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $response['data'] );
443
 
 
 
 
 
444
  if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
445
  $stats['stats']['api_version'] = $response['data']->api_version;
446
  $stats['stats']['lossy'] = $response['data']->lossy;
447
+ $stats['stats']['keep_exif'] = ! empty( $response['data']->keep_exif ) ? $response['data']->keep_exif : 0;
448
  }
449
  }
450
  //Upfront Integration
474
  }
475
 
476
  //If there are no stats
477
+ if ( empty( $full_image_response['data'] ) ) {
478
  $store_stats = false;
479
  }
480
 
481
  //If the image size grew after smushing, skip it
482
+ if ( $full_image_response['data']->after_size > $full_image_response['data']->before_size ) {
483
  $store_stats = false;
484
  }
485
 
487
  $stats['sizes']['full'] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $full_image_response['data'] );
488
  }
489
 
 
 
 
 
 
 
490
  //Api version and lossy, for some images, full image i skipped and for other images only full exists
491
  //so have to add code again
492
  if ( empty( $stats['stats']['api_version'] ) || $stats['stats']['api_version'] == - 1 ) {
493
  $stats['stats']['api_version'] = $full_image_response['data']->api_version;
494
  $stats['stats']['lossy'] = $full_image_response['data']->lossy;
495
+ $stats['stats']['keep_exif'] = ! empty( $full_image_response['data']->keep_exif ) ? $full_image_response['data']->keep_exif : 0;
496
  }
497
 
498
  }
499
 
500
  $has_errors = (bool) count( $errors->get_error_messages() );
501
 
 
 
 
502
  //Set smush status for all the images, store it in wp-smpro-smush-data
503
  if ( ! $has_errors ) {
504
 
505
  $existing_stats = get_post_meta( $ID, $this->smushed_meta_key, true );
506
 
507
  if ( ! empty( $existing_stats ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
508
 
509
  //Update stats for each size
510
  if ( isset( $existing_stats['sizes'] ) && ! empty( $stats['sizes'] ) ) {
515
  $stats['sizes'][ $size_name ] = $existing_stats['sizes'][ $size_name ];
516
  } else {
517
 
518
+ $existing_stats_size = (object) $existing_stats['sizes'][ $size_name ];
519
 
520
  //store the original image size
521
+ $stats['sizes'][ $size_name ]->size_before = ( ! empty( $existing_stats_size->size_before ) && $existing_stats_size->size_before > $stats['sizes'][ $size_name ]->size_before ) ? $existing_stats_size->size_before : $stats['sizes'][ $size_name ]->size_before;
522
 
523
  //Update compression percent and bytes saved for each size
524
  $stats['sizes'][ $size_name ]->bytes = $stats['sizes'][ $size_name ]->bytes + $existing_stats_size->bytes;
527
  }
528
  }
529
  }
530
+
531
+ //Sum Up all the stats
532
+ $stats = $this->total_compression( $stats );
533
+
534
  //If there was any compression and there was no error in smushing
535
+ if ( isset( $stats['stats']['bytes'] ) && $stats['stats']['bytes'] >= 0 && ! $has_errors ) {
536
  /**
537
  * Runs if the image smushing was successful
538
  *
539
+ * @param int $ID Image Id
540
  *
541
  * @param array $stats Smush Stats for the image
542
+ *
543
  */
544
+ do_action( 'wp_smush_image_optimised', $ID, $stats );
545
  }
546
  update_post_meta( $ID, $this->smushed_meta_key, $stats );
547
  }
548
 
549
+ unset( $stats );
550
+
551
+ //Unset Response
552
+ if ( ! empty( $response ) ) {
553
+ unset( $response );
554
+ }
555
+
556
  return $meta;
557
  }
558
 
560
  * Read the image paths from an attachment's meta data and process each image
561
  * with wp_smushit()
562
  *
 
 
563
  * @uses resize_from_meta_data
564
  *
565
  * @param $meta
567
  *
568
  * @return mixed
569
  */
570
+ function smush_image( $meta, $ID = null ) {
571
+
572
+ // Our async task runs when action is upload-attachment and post_id found. So do not run on these conditions.
573
+ if ( ( ( ! empty( $_POST['action'] ) && 'upload-attachment' == $_POST['action'] ) || isset( $_POST['post_id'] ) )
574
+ // And, check if Async is enabled.
575
+ && defined( 'WP_SMUSH_ASYNC' ) && WP_SMUSH_ASYNC
576
+ ) {
577
+ return $meta;
578
+ }
579
+
580
+ //Return directly if not a image
581
+ if ( ! wp_attachment_is_image( $ID ) ) {
582
+ return $meta;
583
+ }
584
+
585
+ //Check if we're restoring the image Or already smushing the image
586
+ if ( get_transient( "wp-smush-restore-$ID" ) || get_transient( "smush-in-progress-$ID" ) || get_transient( "wp-smush-restore-$ID" ) ) {
587
+ return $meta;
588
+ }
589
+
590
+ /**
591
+ * Filter: wp_smush_image
592
+ *
593
+ * Whether to smush the given attachment id or not
594
+ *
595
+ * @param $skip bool, whether to Smush image or not
596
+ *
597
+ * @param $Attachment Id, Attachment id of the image being processed
598
+ *
599
+ */
600
+ if ( ! apply_filters( 'wp_smush_image', true, $ID ) ) {
601
+ return false;
602
+ }
603
+
604
+ //Set a transient to avoid multiple request
605
+ set_transient( 'smush-in-progress-' . $ID, true, WP_SMUSH_TIMEOUT );
606
+
607
+ global $wpsmush_resize, $wpsmush_pngjpg, $wpsmush_settings;
608
+
609
+ // While uploading from Mobile App or other sources, admin_init action may not fire.
610
+ // So we need to manually initialize those.
611
+ $this->initialise();
612
+ $wpsmush_resize->initialize( true );
613
+
614
  //Check if auto is enabled
615
  $auto_smush = $this->is_auto_smush_enabled();
616
 
617
+ //Optionally Resize Images
618
+ $meta = $wpsmush_resize->auto_resize( $ID, $meta );
619
+
620
  //Auto Smush the new image
621
  if ( $auto_smush ) {
 
622
 
623
+ //Optionally Convert PNGs to JPG
624
+ $meta = $wpsmush_pngjpg->png_to_jpg( $ID, $meta );
625
+
626
+ /** Fix for Hostgator */
627
  //Check for use of http url, (Hostgator mostly)
628
  $use_http = wp_cache_get( WP_SMUSH_PREFIX . 'use_http', 'smush' );
629
  if ( ! $use_http ) {
630
+ $use_http = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'use_http', false );
631
  wp_cache_add( WP_SMUSH_PREFIX . 'use_http', $use_http, 'smush' );
632
  }
633
+ if ( $use_http ) {
634
  //HTTP Url
635
  define( 'WP_SMUSH_API_HTTP', 'http://smushpro.wpmudev.org/1.0/' );
636
  }
642
  delete_post_meta( $ID, $this->smushed_meta_key );
643
  }
644
 
645
+ //Delete Transient
646
+ delete_transient( 'smush-in-progress-' . $ID );
647
+
648
  return $meta;
649
  }
650
 
658
  * @return bool|array array containing success status, and stats
659
  */
660
  function _post( $file_path, $file_size ) {
661
+ global $wpsmushit_admin, $wpsmush_settings;
662
 
663
  $data = false;
664
 
665
+ $file_data = file_get_contents( $file_path );
666
+
667
  $headers = array(
668
  'accept' => 'application/json', // The API returns JSON
669
  'content-type' => 'application/binary', // Set content type to binary
675
  $headers['apikey'] = $api_key;
676
  }
677
 
678
+ if ( $this->lossy_enabled && $this->validate_install() ) {
679
  $headers['lossy'] = 'true';
680
  } else {
681
  $headers['lossy'] = 'false';
690
  'timeout' => WP_SMUSH_TIMEOUT,
691
  'user-agent' => WP_SMUSH_UA,
692
  );
693
+ //Temporary Increase the limit
694
+ @ini_set('memory_limit','256M');
695
  $result = wp_remote_post( $api_url, $args );
696
 
 
 
697
  unset( $file_data );//free memory
698
  if ( is_wp_error( $result ) ) {
699
 
702
  //Hostgator Issue
703
  if ( ! empty( $er_msg ) && strpos( $er_msg, 'SSL CA cert' ) !== false ) {
704
  //Update DB for using http protocol
705
+ $wpsmush_settings->update_setting( WP_SMUSH_PREFIX . 'use_http', 1 );
706
  }
707
  //Handle error
708
  $data['message'] = sprintf( __( 'Error posting to API: %s', 'wp-smushit' ), $result->get_error_message() );
742
  $data['success'] = true;
743
  $data['data'] = $response->data;
744
  }
745
+ //If is_premium is set in response, send it over to check for member validity
746
+ if ( ! empty( $response->data ) && isset( $response->data->is_premium ) ) {
747
+ $wpsmushit_admin->api_headers['is_premium'] = $response->data->is_premium;
748
+ }
749
  } else {
750
  //Server side error, get message from response
751
  $data['message'] = ! empty( $response->data ) ? $response->data : __( "Image couldn't be smushed", 'wp-smushit' );
757
  return $data;
758
  }
759
 
 
760
  /**
761
  * Print column header for Smush results in the media library using
762
  * the `manage_media_columns` hook.
771
  * Return the filesize in a humanly readable format.
772
  * Taken from http://www.php.net/manual/en/function.filesize.php#91477
773
  */
774
+ function format_bytes( $bytes, $precision = 1 ) {
775
+ $units = array( 'B', 'KiB', 'MiB', 'GiB', 'TiB' );
776
  $bytes = max( $bytes, 0 );
777
  $pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
778
  $pow = min( $pow, count( $units ) - 1 );
779
  $bytes /= pow( 1024, $pow );
780
 
781
+ return round( $bytes, $precision ) . $units[ $pow ];
782
  }
783
 
784
  /**
796
  *
797
  * @return mixed|string
798
  */
799
+ function validate_install() {
800
 
801
  if ( isset( $this->is_pro ) ) {
802
  return $this->is_pro;
821
  $last_checked = $api_auth[ $api_key ]['timestamp'];
822
  $valid = $api_auth[ $api_key ]['validity'];
823
 
824
+ $diff = current_time( 'timestamp' ) - $last_checked;
825
 
826
  //Difference in hours
827
  $diff_h = $diff / 3600;
866
  update_site_option( 'wp_smush_api_auth', $api_auth );
867
 
868
  // call api
869
+ $url = $this->api_server . $api_key;
870
 
871
  $request = wp_remote_get( $url, array(
872
  "user-agent" => WP_SMUSH_UA,
876
 
877
  if ( ! is_wp_error( $request ) && '200' == wp_remote_retrieve_response_code( $request ) ) {
878
  $result = json_decode( wp_remote_retrieve_body( $request ) );
879
+ if ( ! empty( $result->success ) && $result->success ) {
880
  $valid = 'valid';
881
  } else {
882
  $valid = 'invalid';
945
  * @return string|void
946
  */
947
  function set_status( $id, $echo = true, $text_only = false, $wrapper = true ) {
948
+ global $wpsmush_s3_compat;
949
  $status_txt = $button_txt = $stats = '';
950
  $show_button = $show_resmush = false;
951
 
952
+ $wp_smush_data = get_post_meta( $id, $this->smushed_meta_key, true );
953
+ $wp_resize_savings = get_post_meta( $id, WP_SMUSH_PREFIX . 'resize_savings', true );
954
+ $conversion_savings = get_post_meta( $id, WP_SMUSH_PREFIX . 'pngjpg_savings', true );
955
+
956
+ $combined_stats = $this->combined_stats( $wp_smush_data, $wp_resize_savings );
957
+
958
+ $combined_stats = $this->combine_conversion_stats( $combined_stats, $conversion_savings );
959
+
960
+ //Remove Smush s3 hook, as it downloads the file again
961
+ remove_filter('as3cf_get_attached_file', array( $wpsmush_s3_compat, 'smush_download_file'), 11, 4 );
962
  $attachment_data = wp_get_attachment_metadata( $id );
963
 
964
  // if the image is smushed
965
  if ( ! empty( $wp_smush_data ) ) {
966
 
967
  $image_count = count( $wp_smush_data['sizes'] );
968
+ $bytes = isset( $combined_stats['stats']['bytes'] ) ? $combined_stats['stats']['bytes'] : 0;
969
+ $bytes_readable = ! empty( $bytes ) ? size_format( $bytes, 1 ) : '';
970
+ $percent = isset( $combined_stats['stats']['percent'] ) ? $combined_stats['stats']['percent'] : 0;
971
  $percent = $percent < 0 ? 0 : $percent;
972
 
973
  if ( isset( $wp_smush_data['stats']['size_before'] ) && $wp_smush_data['stats']['size_before'] == 0 && ! empty( $wp_smush_data['sizes'] ) ) {
975
  $show_button = false;
976
  } else {
977
  if ( $bytes == 0 || $percent == 0 ) {
978
+ $status_txt = __( 'Already Optimized', 'wp-smushit' );
979
 
980
  //Show resmush link, if the settings were changed
981
+ $show_resmush = $this->show_resmush( $id, $wp_smush_data );
982
  if ( $show_resmush ) {
983
  $status_txt .= '<br />' . $this->get_resmsuh_link( $id );
984
  }
985
 
986
  } elseif ( ! empty( $percent ) && ! empty( $bytes_readable ) ) {
987
  $status_txt = $image_count > 1 ? sprintf( __( "%d images reduced ", 'wp-smushit' ), $image_count ) : __( "Reduced ", 'wp-smushit' );
 
988
 
989
+ $stats_percent = number_format_i18n( $percent, 2, '.', '' );
990
+ $stats_percent = $stats_percent > 0 ? sprintf( "( %01.1f%% )", $stats_percent ) : '';
991
+ $status_txt .= sprintf( __( "by %s %s", 'wp-smushit' ), $bytes_readable, $stats_percent );
992
+
993
+ $file_path = get_attached_file( $id );
994
+ $size = file_exists( $file_path ) ? filesize( $file_path ) : 0;
995
+ if ( $size > 0 ) {
996
+ $size = size_format( $size, 1 );
997
+ $image_size = sprintf( __( "<br /> Image Size: %s", "wp-smushit" ), $size );
998
+ $status_txt .= $image_size;
999
+ }
1000
+
1001
+ $show_resmush = $this->show_resmush( $id, $wp_smush_data );
1002
 
1003
  if ( $show_resmush ) {
1004
  $status_txt .= '<br />' . $this->get_resmsuh_link( $id );
1053
 
1054
  //Check if premium user, compression was lossless, and lossy compression is enabled
1055
  //If we are displaying the resmush option already, no need to show the Super Smush button
1056
+ if ( ! $show_resmush && $this->validate_install() && ! $is_lossy && $this->lossy_enabled && $image_type != 'image/gif' ) {
1057
  // the button text
1058
  $button_txt = __( 'Super-Smush', 'wp-smushit' );
1059
  $show_button = true;
1060
  }
1061
 
1062
+ } elseif ( get_transient( 'smush-in-progress-' . $id ) ) {
1063
+ // the status
1064
+ $status_txt = __( 'Smushing in progress..', 'wp-smushit' );
1065
+
1066
+ //Set WP Smush data to true in order to show the text
1067
+ $wp_smush_data = true;
1068
+
1069
+ // we need to show the smush button
1070
+ $show_button = false;
1071
+
1072
+ // the button text
1073
+ $button_txt = '';
1074
  } else {
1075
 
1076
  // the status
1085
  if ( $text_only ) {
1086
  //For ajax response
1087
  return array(
1088
+ 'status' => $status_txt,
1089
+ 'stats' => $stats,
1090
+ 'show_warning' => intval( $this->show_warning() )
1091
  );
1092
  }
1093
 
1178
  return;
1179
  }
1180
 
1181
+ $migrated_version = get_site_option( $this->migrated_version_key );
1182
 
1183
  if ( $migrated_version === $this->version ) {
1184
  return;
1201
  }
1202
  }
1203
 
1204
+ update_site_option( $this->migrated_version_key, $this->version );
1205
 
1206
  }
1207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1208
  /**
1209
  * Updates the smush stats for a single image size
1210
  *
1222
  $stats = get_post_meta( $id, $this->smushed_meta_key, true );
1223
  //Update existing Stats
1224
  if ( ! empty( $stats ) ) {
 
 
 
 
 
1225
 
1226
  //Update stats for each size
1227
  if ( isset( $stats['sizes'] ) ) {
1247
  'sizes' => array()
1248
  );
1249
  $stats['stats']['api_version'] = $data->api_version;
1250
+ $stats['stats']['lossy'] = $data->lossy;
1251
+ $stats['stats']['keep_exif'] = ! empty( $data->keep_exif ) ? $data->keep_exif : 0;
1252
 
 
 
 
1253
  //Update size wise details
1254
  $stats['sizes'][ $image_size ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $data );
1255
  }
1256
+ //Calculate the total compression
1257
+ $stats = $this->total_compression( $stats );
1258
+
1259
  update_post_meta( $id, $this->smushed_meta_key, $stats );
1260
 
1261
  }
1269
  */
1270
  function smush_retina_image( $id, $retina_file, $image_size ) {
1271
 
1272
+ //Initialize attachment id and media type
1273
+ $this->attachment_id = $id;
1274
+ $this->media_type = "wp";
1275
+
1276
  /**
1277
  * Allows to Enable/Disable WP Retina 2x Integration
1278
  */
1287
  return;
1288
  }
1289
 
1290
+ //Do not smush if auto smush is turned off
1291
+ if ( ! $this->is_auto_smush_enabled() ) {
1292
+ return;
1293
+ }
1294
+
1295
  /**
1296
  * Allows to skip a image from smushing
1297
  *
1334
  //If full image was not smushed, reason 1. Large Size logic, 2. Free and greater than 1Mb
1335
  if ( ! array_key_exists( 'full', $size_stats ) ) {
1336
  //For free version, Check the image size
1337
+ if ( ! $this->validate_install() ) {
1338
  //For free version, check if full size is greater than 1 Mb, show the skipped status
1339
  $file_size = file_exists( $full_image ) ? filesize( $full_image ) : '';
1340
  if ( ! empty( $file_size ) && ( $file_size / WP_SMUSH_MAX_BYTES ) > 1 ) {
1409
  */
1410
  function get_detailed_stats( $image_id, $wp_smush_data, $attachment_metadata ) {
1411
 
1412
+ global $wpsmushit_admin;
1413
+
1414
  $stats = '<div id="smush-stats-' . $image_id . '" class="smush-stats-wrapper hidden">
1415
  <table class="wp-smush-stats-holder">
1416
  <thead>
1442
  }
1443
  //Show Sizes and their compression
1444
  foreach ( $size_stats as $size_key => $size_value ) {
1445
+ $dimensions = '';
1446
+ //Get the dimensions for the image size if available
1447
+ if ( ! empty( $wpsmushit_admin->image_sizes ) && ! empty( $wpsmushit_admin->image_sizes[ $size_key ] ) ) {
1448
+ $dimensions = $wpsmushit_admin->image_sizes[ $size_key ]['width'] . 'x' . $wpsmushit_admin->image_sizes[ $size_key ]['height'];
1449
+ }
1450
+ $dimensions = ! empty( $dimensions ) ? sprintf( " <br /> (%s)", $dimensions ) : '';
1451
  if ( $size_value->bytes > 0 ) {
1452
+ $percent = round( $size_value->percent, 1 );
1453
+ $percent = $percent > 0 ? ' ( ' . $percent . '% )' : '';
1454
  $stats .= '<tr>
1455
+ <td>' . strtoupper( $size_key ) . $dimensions . '</td>
1456
+ <td>' . size_format( $size_value->bytes, 1 ) . $percent . '</td>
1457
  </tr>';
1458
  }
1459
  }
1476
  return $a->bytes < $b->bytes;
1477
  }
1478
 
1479
+ /**
1480
+ * Load Plugin Modules
1481
+ *
1482
+ */
1483
+ function load_modules() {
1484
+ $this->load_nextgen();
1485
+ //Load S3
1486
+ if( has_action('aws_init') ) {
1487
+ add_action( 'aws_init', array( $this, 'load_s3' ), 120 );
1488
+ }
1489
+ }
1490
  /**
1491
  * Check if NextGen is active or not
1492
  * Include and instantiate classes
1493
  */
1494
  function load_nextgen() {
1495
+
1496
+ if ( ! class_exists( 'C_NextGEN_Bootstrap' ) ) {
1497
  return;
1498
  }
1499
+ global $wpsmush_settings;
1500
+
1501
  //Check if integration is Enabled or not
1502
  //Smush NextGen key
1503
  $opt_nextgen = WP_SMUSH_PREFIX . 'nextgen';
1504
+ $opt_nextgen_val = $wpsmush_settings->get_setting( $opt_nextgen, false );
 
 
 
1505
 
1506
  require_once( WP_SMUSH_DIR . '/lib/class-wp-smush-nextgen.php' );
1507
+ // Do not continue if integration not enabled or not a pro user.
1508
+ if ( ! $opt_nextgen_val || ! $this->validate_install() ) {
1509
+ return;
1510
+ }
1511
  require_once( WP_SMUSH_DIR . '/lib/nextgen-integration/class-wp-smush-nextgen-admin.php' );
1512
  require_once( WP_SMUSH_DIR . '/lib/nextgen-integration/class-wp-smush-nextgen-stats.php' );
1513
  require_once( WP_SMUSH_DIR . '/lib/nextgen-integration/class-wp-smush-nextgen-bulk.php' );
1514
 
1515
  global $wpsmushnextgen, $wpsmushnextgenadmin, $wpsmushnextgenstats;
1516
  //Initialize Nextgen support
1517
+ if( !is_object( $wpsmushnextgen ) ) {
1518
+ $wpsmushnextgen = new WpSmushNextGen();
1519
+ }
1520
  $wpsmushnextgenstats = new WpSmushNextGenStats();
1521
+ $wpsmushnextgenadmin = new WpSmushNextGenAdmin();
1522
  new WPSmushNextGenBulk();
1523
  }
1524
 
1525
+ /**
1526
+ * Load S3 module if the respective plugin is active
1527
+ */
1528
+ function load_s3() {
1529
+
1530
+ //If we don't have free or pro verison for WP S3 Offload, return
1531
+ if ( ! class_exists( 'Amazon_S3_And_CloudFront' ) && ! class_exists( 'Amazon_S3_And_CloudFront_Pro' ) ) {
1532
+ return;
1533
+ }
1534
+
1535
+ //Include Smush Async class
1536
+ require_once WP_SMUSH_DIR . 'lib/class-wp-smush-s3.php';
1537
+ }
1538
+
1539
  /**
1540
  * Add the Smushit Column to sortable list
1541
  *
1599
 
1600
  //Get the image path for all sizes
1601
  $file = get_attached_file( $image_id );
1602
+ $uf_file = get_attached_file( $image_id, true );
1603
+
1604
+ //Get stored backup path, if any
1605
+ $backup_sizes = get_post_meta( $image_id, '_wp_attachment_backup_sizes', true );
1606
 
1607
+ //Check if we've a backup path
1608
+ if( !empty( $backup_sizes ) && ( !empty( $backup_sizes['smush-full']) || !empty( $backup_sizes['smush_png_path']) ) ) {
1609
+ //Check for PNG backup
1610
+ $backup = !empty( $backup_sizes['smush_png_path'] ) ? $backup_sizes['smush_png_path'] : '';
1611
 
1612
+ //Check for original full size image backup
1613
+ $backup = empty( $backup ) && !empty( $backup_sizes['smush-full'] ) ? $backup_sizes['smush-full'] : $backup;
1614
+
1615
+ $backup = !empty( $backup['file'] ) ? $backup['file'] : '';
1616
+ }
1617
+
1618
+ //If we still don't have a backup path, use traditional method to get it
1619
+ if( empty( $backup ) ) {
1620
+ //Check backup for Full size
1621
+ $backup = $wpsmushit_admin->get_image_backup_path( $file );
1622
+ }else{
1623
+ //Get the full path for file backup
1624
+ $backup = str_replace( wp_basename( $file ), wp_basename( $backup ), $file );
1625
+ }
1626
+
1627
+ $file_exists = apply_filters( 'smush_backup_exists', file_exists( $backup ), $image_id, $backup );
1628
+
1629
+ if( $file_exists ) {
1630
  return true;
1631
  }
1632
 
1633
+ //Additional Backup Check for JPEGs converted from PNG
1634
+ $pngjpg_savings = get_post_meta( $image_id, WP_SMUSH_PREFIX . 'pngjpg_savings', true );
1635
+ if ( ! empty( $pngjpg_savings ) ) {
1636
+
1637
+ //Get the original File path and check if it exists
1638
+ $backup = get_post_meta( $image_id, WP_SMUSH_PREFIX . 'original_file', true );
1639
+ $backup = $this->original_file( $backup );
1640
+
1641
+ if ( ! empty( $backup ) && is_file( $backup ) ) {
1642
  return true;
1643
  }
1644
  }
1663
 
1664
  $ajax_nonce = wp_create_nonce( "wp-smush-restore-" . $image_id );
1665
 
1666
+ return sprintf( '<a href="#" tooltip="%s" data-id="%d" data-nonce="%s" class="%s">%s</a>', esc_html__( "Restore original image.", "wp-smushit" ), $image_id, $ajax_nonce, $class, esc_html__( "Restore image", "wp-smushit" ) );
1667
  }
1668
 
1669
  /**
1681
  * @return int|mixed|void
1682
  */
1683
  function is_auto_smush_enabled() {
1684
+
1685
+ global $wpsmush_settings;
1686
+
1687
+ $auto_smush = $wpsmush_settings->get_setting( WP_SMUSH_PREFIX . 'auto', false );
1688
 
1689
  //Keep the auto smush on by default
1690
  if ( $auto_smush === false ) {
1711
 
1712
  $ajax_nonce = wp_create_nonce( "wp-smush-resmush-" . $image_id );
1713
 
1714
+ return sprintf( '<a href="#" tooltip="%s" data-id="%d" data-nonce="%s" class="%s">%s</a>', esc_html__( "Smush image including original file.", "wp-smushit" ), $image_id, $ajax_nonce, $class, esc_html__( "Resmush image", "wp-smushit" ) );
1715
  }
1716
 
1717
  /**
1727
  if ( empty( $attachment_path ) ) {
1728
  return false;
1729
  }
1730
+ $path = pathinfo( $attachment_path );
1731
+
1732
+ //If we don't have complete filename return false
1733
+ if ( empty( $path['extension'] ) ) {
1734
+ return false;
1735
+ }
1736
+
1737
  $backup_name = trailingslashit( $path['dirname'] ) . $path['filename'] . ".bak." . $path['extension'];
1738
 
1739
  return $backup_name;
1741
 
1742
  /**
1743
  * Deletes all the backup files when an attachment is deleted
1744
+ * Update resmush List
1745
  * Update Super Smush image count
1746
  *
1747
  * @param $image_id
1748
+ *
1749
  */
1750
  function delete_images( $image_id ) {
1751
+ global $wpsmush_db;
1752
+
1753
+ //Update the savings cache
1754
+ $wpsmush_db->resize_savings( true );
1755
+
1756
+ //Update the savings cache
1757
+ $wpsmush_db->conversion_savings( true );
1758
 
1759
  //If no image id provided
1760
  if ( empty( $image_id ) ) {
1768
  }
1769
 
1770
  /** Delete Backups **/
 
1771
  //Check if we have any smush data for image
1772
  $this->delete_backup_files( $image_id );
1773
  }
1799
  if ( empty( $attachment_id ) || ! class_exists( 'Upfront' ) ) {
1800
  return $stats;
1801
  }
1802
+
1803
+ //Set attachment id and Media type
1804
+ $this->attachment_id = $attachment_id;
1805
+ $this->media_type = "upfront";
1806
+
1807
  //Get post meta to check for Upfront images
1808
  $upfront_images = get_post_meta( $attachment_id, 'upfront_used_image_sizes', true );
1809
 
1826
 
1827
  //If the smushing was successful
1828
  if ( ! is_wp_error( $res ) && ! empty( $res['data'] ) ) {
1829
+ if ( $res['data']->bytes_saved > 0 ) {
1830
  //Update attachment stats
1831
  $stats['sizes'][ $element_id ] = (object) $this->_array_fill_placeholders( $this->_get_size_signature(), (array) $res['data'] );
1832
  }
1845
 
1846
  /**
1847
  * Checks the current settings and returns the value whether to enable or not the resmush option
1848
+ *
1849
+ * @param $id
1850
  * @param $wp_smush_data
1851
  *
1852
  * @return bool
1853
  */
1854
+ function show_resmush( $id = '', $wp_smush_data ) {
1855
  //Resmush: Show resmush link, Check if user have enabled smushing the original and full image was skipped
1856
  //Or: If keep exif is unchecked and the smushed image have exif
1857
+ //PNG To JPEG
1858
  if ( $this->smush_original ) {
1859
  //IF full image was not smushed
1860
  if ( ! empty( $wp_smush_data ) && empty( $wp_smush_data['sizes']['full'] ) ) {
1861
+ return true;
1862
  }
1863
  }
1864
+
1865
+ //EXIF Check
1866
+ if ( ! $this->keep_exif ) {
1867
+ //If Keep Exif was set to true initially, and since it is set to false now
1868
  if ( isset( $wp_smush_data['stats']['keep_exif'] ) && $wp_smush_data['stats']['keep_exif'] == 1 ) {
1869
+ return true;
1870
  }
1871
  }
1872
+
1873
+ //PNG to JPEG
1874
+ global $wpsmush_pngjpg;
1875
+ if ( $wpsmush_pngjpg->can_be_converted( $id ) ) {
1876
+ return true;
1877
+ }
1878
+
1879
+ return false;
1880
+
1881
  }
1882
 
1883
  /**
1893
  return 0;
1894
  }
1895
  $size_before = ! empty( $stats->size_before ) ? $stats->size_before : $existing_stats->size_before;
1896
+ $size_after = ! empty( $stats->size_after ) ? $stats->size_after : $existing_stats->size_after;
1897
  $savings = $size_before - $size_after;
1898
  if ( $savings > 0 ) {
1899
  $percentage = ( $savings / $size_before ) * 100;
1905
  return 0;
1906
  }
1907
 
1908
+ /**
1909
+ * Calculate saving percentage for a given size stats
1910
+ *
1911
+ * @param $stats
1912
+ *
1913
+ * @return float|int
1914
+ */
1915
+ function calculate_percentage_from_stats( $stats ) {
1916
+ if ( empty( $stats ) || ! isset( $stats->size_before, $stats->size_after ) ) {
1917
+ return 0;
1918
+ }
1919
+
1920
+ $savings = $stats->size_before - $stats->size_after;
1921
+ if ( $savings > 0 ) {
1922
+ $percentage = ( $savings / $stats->size_before ) * 100;
1923
+ $percentage = $percentage > 0 ? round( $percentage, 2 ) : $percentage;
1924
+
1925
+ return $percentage;
1926
+ }
1927
+ }
1928
+
1929
  /**
1930
  * Redirects the user to Plugin settings page on Plugin activation
1931
  *
1935
  */
1936
  function wp_smush_redirect( $plugin ) {
1937
 
1938
+ global $wpsmush_db;
1939
 
1940
  //Run for only our plugin
1941
+ if ( $plugin != WP_SMUSH_BASENAME ) {
1942
  return false;
1943
  }
1944
 
1945
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1946
+ return true;
1947
+ }
1948
+
1949
  //Skip if bulk activation, Or if we have to skip redirection
1950
+ if ( isset( $_GET['activate-multi'] ) || get_site_option( 'wp-smush-skip-redirect' ) ) {
1951
  return false;
1952
  }
1953
 
1954
  //If images are already smushed
1955
+ if ( $wpsmush_db->smushed_count( false ) > 0 ) {
1956
  return false;
1957
  }
1958
 
1959
  $url = admin_url( 'upload.php' );
1960
  $url = add_query_arg(
1961
  array(
1962
+ 'page' => 'wp-smush-bulk'
1963
  ),
1964
  $url
1965
  );
1966
 
1967
  //Store that we need not redirect again
1968
+ add_site_option( 'wp-smush-skip-redirect', true );
1969
 
1970
  exit( wp_redirect( $url ) );
1971
  }
1972
 
1973
  /**
1974
  * Clear up all the backup files for the image, if any
1975
+ *
1976
  * @param $image_id
1977
  */
1978
  function delete_backup_files( $image_id ) {
2009
  }
2010
  }
2011
  }
2012
+
2013
+ /**
2014
+ * Manually Dismiss Smush Upgrade notice
2015
+ */
2016
+ function dismiss_smush_upgrade() {
2017
+ if ( isset( $_GET['remove_smush_upgrade_notice'] ) && 1 == $_GET['remove_smush_upgrade_notice'] ) {
2018
+ global $wpsmushit_admin;
2019
+ $wpsmushit_admin->dismiss_upgrade_notice( false );
2020
+ }
2021
+ }
2022
+
2023
+ /**
2024
+ * Iterate over all the size stats and calculate the total stats
2025
+ *
2026
+ * @param $stats
2027
+ *
2028
+ * @return mixed
2029
+ */
2030
+ function total_compression( $stats ) {
2031
+ $stats['stats']['size_before'] = $stats['stats']['size_after'] = $stats['stats']['time'] = 0;
2032
+ foreach ( $stats['sizes'] as $size_stats ) {
2033
+ $stats['stats']['size_before'] += ! empty( $size_stats->size_before ) ? $size_stats->size_before : 0;
2034
+ $stats['stats']['size_after'] += ! empty( $size_stats->size_after ) ? $size_stats->size_after : 0;
2035
+ $stats['stats']['time'] += ! empty( $size_stats->time ) ? $size_stats->time : 0;
2036
+ }
2037
+ $stats['stats']['bytes'] = ! empty( $stats['stats']['size_before'] ) && $stats['stats']['size_before'] > $stats['stats']['size_after'] ? $stats['stats']['size_before'] - $stats['stats']['size_after'] : 0;
2038
+ if ( ! empty( $stats['stats']['bytes'] ) && ! empty( $stats['stats']['size_before'] ) ) {
2039
+ $stats['stats']['percent'] = ( $stats['stats']['bytes'] / $stats['stats']['size_before'] ) * 100;
2040
+ }
2041
+
2042
+ return $stats;
2043
+ }
2044
+
2045
+ /**
2046
+ * Smush and Resizing Stats Combined together
2047
+ *
2048
+ * @param $smush_stats
2049
+ * @param $resize_savings
2050
+ *
2051
+ * @return array Array of all the stats
2052
+ */
2053
+ function combined_stats( $smush_stats, $resize_savings ) {
2054
+ if ( empty( $smush_stats ) || empty( $resize_savings ) ) {
2055
+ return $smush_stats;
2056
+ }
2057
+
2058
+ //Full Image
2059
+ if ( ! empty( $smush_stats['sizes']['full'] ) ) {
2060
+ $smush_stats['sizes']['full']->bytes = ! empty( $resize_savings['bytes'] ) ? $smush_stats['sizes']['full']->bytes + $resize_savings['bytes'] : $smush_stats['sizes']['full']->bytes;
2061
+ $smush_stats['sizes']['full']->size_before = ! empty( $resize_savings['size_before'] ) && ( $resize_savings['size_before'] > $smush_stats['sizes']['full']->size_before ) ? $resize_savings['size_before'] : $smush_stats['sizes']['full']->size_before;
2062
+ $smush_stats['sizes']['full']->percent = ! empty( $smush_stats['sizes']['full']->bytes ) && $smush_stats['sizes']['full']->size_before > 0 ? ( $smush_stats['sizes']['full']->bytes / $smush_stats['sizes']['full']->size_before ) * 100 : $smush_stats['sizes']['full']->percent;
2063
+
2064
+ $smush_stats['sizes']['full']->percent = round( $smush_stats['sizes']['full']->percent, 1 );
2065
+ }
2066
+
2067
+ $smush_stats = $this->total_compression( $smush_stats );
2068
+
2069
+ return $smush_stats;
2070
+ }
2071
+
2072
+ /**
2073
+ * Combine Savings from PNG to JPG conversion with smush stats
2074
+ *
2075
+ * @param $stats Savings from Smushing the image
2076
+ * @param $conversion_savings Savings from converting the PNG to JPG
2077
+ *
2078
+ * @return Object Total Savings
2079
+ */
2080
+ function combine_conversion_stats( $stats, $conversion_savings ) {
2081
+ if ( empty( $stats ) || empty( $conversion_savings ) ) {
2082
+ return $stats;
2083
+ }
2084
+ foreach ( $conversion_savings as $size_k => $savings ) {
2085
+ if ( ! empty( $stats['sizes'][ $size_k ] ) && ! empty( $savings ) ) {
2086
+ $stats['sizes'][ $size_k ]->bytes = $stats['sizes'][ $size_k ]->bytes + $savings['bytes'];
2087
+ $stats['sizes'][ $size_k ]->size_before = $stats['sizes'][ $size_k ]->size_before > $savings['size_before'] ? $stats['sizes'][ $size_k ]->size_before : $savings['size_before'];
2088
+ $stats['sizes'][ $size_k ]->percent = ! empty( $stats['sizes'][ $size_k ]->bytes ) && $stats['sizes'][ $size_k ]->size_before > 0 ? ( $stats['sizes'][ $size_k ]->bytes / $stats['sizes'][ $size_k ]->size_before ) * 100 : $stats['sizes'][ $size_k ]->percent;
2089
+ $stats['sizes'][ $size_k ]->percent = round( $stats['sizes'][ $size_k ]->percent, 1 );
2090
+ }
2091
+ }
2092
+
2093
+ $stats = $this->total_compression( $stats );
2094
+
2095
+ return $stats;
2096
+ }
2097
+
2098
+ /**
2099
+ * Original File path
2100
+ *
2101
+ * @param string $original_file
2102
+ *
2103
+ * @return string File Path
2104
+ *
2105
+ */
2106
+ function original_file( $original_file = '' ) {
2107
+ $uploads = wp_get_upload_dir();
2108
+ $upload_path = $uploads['basedir'];
2109
+
2110
+ return path_join( $upload_path, $original_file );
2111
+ }
2112
+
2113
+ /**
2114
+ * Check whether to show warning or not for Pro users, if they don't have a valid install
2115
+ *
2116
+ * @return bool
2117
+ *
2118
+ */
2119
+ function show_warning() {
2120
+ //If it's a free setup, Go back right away!
2121
+ if ( ! $this->validate_install() ) {
2122
+ return false;
2123
+ }
2124
+
2125
+ global $wpsmushit_admin;
2126
+ // Return. If we don't have any headers
2127
+ if ( ! isset( $wpsmushit_admin->api_headers ) ) {
2128
+ return false;
2129
+ }
2130
+
2131
+ //Show warning, if function says it's premium and api says not premium
2132
+ if ( isset( $wpsmushit_admin->api_headers['is_premium'] ) && ! intval( $wpsmushit_admin->api_headers['is_premium'] ) ) {
2133
+ return true;
2134
+ }
2135
+
2136
+ return false;
2137
+
2138
+ }
2139
+
2140
+ /**
2141
+ * Send JSON response whether to show or not the warning
2142
+ */
2143
+ function show_warning_ajax() {
2144
+ $show = $this->show_warning();
2145
+ wp_send_json( intval( $show ) );
2146
+ }
2147
+
2148
+ /**
2149
+ * Initialize the Smush Async class
2150
+ */
2151
+ function wp_smush_async() {
2152
+
2153
+ //Don't load the Async task, if user not logged in or not in backend
2154
+ if ( ! is_user_logged_in() || ! is_admin() ) {
2155
+ return;
2156
+ }
2157
+
2158
+ //Check if Async is disabled
2159
+ if ( defined( 'WP_SMUSH_ASYNC' ) && ! WP_SMUSH_ASYNC ) {
2160
+ return;
2161
+ }
2162
+
2163
+ //Instantiate Class
2164
+ new WpSmushAsync();
2165
+ new WpSmushEditorAsync();
2166
+ }
2167
+
2168
+ /**
2169
+ * Send a smush request for the attachment
2170
+ *
2171
+ * @param $id Attachment ID
2172
+ */
2173
+ function wp_smush_handle_async( $id ) {
2174
+
2175
+ //If we don't have image id, or the smush is already in progress for the image, return
2176
+ if ( empty( $id ) || get_transient( 'smush-in-progress-' . $id ) || get_transient( "wp-smush-restore-$id" ) ) {
2177
+ return;
2178
+ }
2179
+
2180
+ //If auto Smush is disabled
2181
+ if ( ! $this->is_auto_smush_enabled() ) {
2182
+ return;
2183
+ }
2184
+
2185
+ /**
2186
+ * Filter: wp_smush_image
2187
+ *
2188
+ * Whether to smush the given attachment id or not
2189
+ *
2190
+ * @param $skip bool, whether to Smush image or not
2191
+ *
2192
+ * @param $Attachment Id, Attachment id of the image being processed
2193
+ *
2194
+ */
2195
+ if ( ! apply_filters( 'wp_smush_image', true, $id ) ) {
2196
+ return;
2197
+ }
2198
+
2199
+ global $wpsmushit_admin;
2200
+ $wpsmushit_admin->smush_single( $id, true );
2201
+
2202
+ }
2203
+
2204
+ /**
2205
+ * Send a smush request for the attachment
2206
+ *
2207
+ * @param $id Attachment ID
2208
+ */
2209
+ function wp_smush_handle_editor_async( $id, $post_data ) {
2210
+
2211
+ //If we don't have image id, or the smush is already in progress for the image, return
2212
+ if ( empty( $id ) || get_transient( "smush-in-progress-$id" ) || get_transient( "wp-smush-restore-$id" ) ) {
2213
+ return;
2214
+ }
2215
+
2216
+ //If auto Smush is disabled
2217
+ if ( ! $this->is_auto_smush_enabled() ) {
2218
+ return;
2219
+ }
2220
+
2221
+ /**
2222
+ * Filter: wp_smush_image
2223
+ *
2224
+ * Whether to smush the given attachment id or not
2225
+ *
2226
+ * @param $skip bool, whether to Smush image or not
2227
+ *
2228
+ * @param $Attachment Id, Attachment id of the image being processed
2229
+ *
2230
+ */
2231
+ if ( ! apply_filters( 'wp_smush_image', true, $id ) ) {
2232
+ return;
2233
+ }
2234
+
2235
+ //If filepath is not set or file doesn't exists
2236
+ if ( ! isset( $post_data['filepath'] ) || ! file_exists( $post_data['filepath'] ) ) {
2237
+ return;
2238
+ }
2239
+
2240
+ //Send image for smushing
2241
+ $res = $this->do_smushit( $post_data['filepath'] );
2242
+
2243
+ //Exit if smushing wasn't successful
2244
+ if ( is_wp_error( $res) || empty( $res['success'] ) || ! $res['success'] ) {
2245
+ return;
2246
+ }
2247
+
2248
+ //Update stats if it's the full size image
2249
+ //Return if it's not the full image size
2250
+ if ( $post_data['filepath'] != get_attached_file( $post_data['postid'] ) ) {
2251
+ return;
2252
+ }
2253
+
2254
+ //Get the existing Stats
2255
+ $smush_stats = get_post_meta( $post_data['postid'], $this->smushed_meta_key, true );
2256
+ $stats_full = ! empty( $smush_stats['sizes'] ) && ! empty( $smush_stats['sizes']['full'] ) ? $smush_stats['sizes']['full'] : '';
2257
+
2258
+ if ( empty( $stats_full ) ) {
2259
+ return;
2260
+ }
2261
+
2262
+ //store the original image size
2263
+ $stats_full->size_before = ( ! empty( $stats_full->size_before ) && $stats_full->size_before > $res['data']->before_size ) ? $stats_full->size_before : $res['data']->before_size;
2264
+ $stats_full->size_after = $res['data']->after_size;
2265
+
2266
+ //Update compression percent and bytes saved for each size
2267
+ $stats_full->bytes = $stats_full->size_before - $stats_full->size_after;
2268
+
2269
+ $stats_full->percent = $this->calculate_percentage_from_stats( $stats_full );
2270
+ $smush_stats['sizes']['full'] = $stats_full;
2271
+
2272
+ //Update Stats
2273
+ update_post_meta( $post_data['postid'], $this->smushed_meta_key, $smush_stats );
2274
+ }
2275
  }
2276
 
2277
  global $WpSmush;
2280
  }
2281
 
2282
  //Include Admin classes
2283
+ require_once( WP_SMUSH_DIR . 'lib/class-wp-smush-admin.php' );
2284
+
2285
+ //Include Directory Smush
2286
+ require_once WP_SMUSH_DIR . 'lib/class-wp-smush-dir.php';
lib/nextgen-integration/class-wp-smush-nextgen-admin.php CHANGED
@@ -17,6 +17,7 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
17
 
18
  var $total_count = 0;
19
  var $smushed_count = 0;
 
20
  var $remaining_count = 0;
21
  var $super_smushed = 0;
22
  var $bulk_page_handle;
@@ -101,11 +102,10 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
101
  * @param $id
102
  */
103
  function wp_smush_column_options( $column_name, $id, $echo = false ) {
104
- global $wpsmushnextgenstats;
105
 
106
  //NExtGen Doesn't returns Column name, weird? yeah, right, it is proper because hook is called for the particular column
107
  if ( $column_name == 'wp_smush_image' || $column_name == '' ) {
108
- $supported_image = array( 'image/jpeg', 'image/gif', 'image/png', 'image/jpg' );
109
 
110
  // Registry Object for NextGen Gallery
111
  $registry = C_Component_Registry::get_instance();
@@ -129,10 +129,12 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
129
  $image_type = $this->get_file_type( $file_path );
130
 
131
  //If image type not supported
132
- if ( ! $image_type || ! in_array( $image_type, $supported_image ) ) {
133
  return;
134
  }
135
 
 
 
136
  //Check Image metadata, if smushed, print the stats or super smush button
137
  if ( ! empty( $image->meta_data['wp_smush'] ) ) {
138
  //Echo the smush stats
@@ -151,15 +153,13 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
151
  function localize() {
152
  global $wpsmushnextgenstats;
153
 
154
- $this->setup_stats();
155
-
156
  $handle = 'wp-smushit-admin-js';
157
 
158
  $wp_smush_msgs = array(
159
  'resmush' => esc_html__( 'Super-Smush', 'wp-smushit' ),
160
  'smush_now' => esc_html__( 'Smush Now', 'wp-smushit' ),
161
  "error_in_bulk" => esc_html__( '{{errors}} image(s) were skipped due to an error.', 'wp-smushit' ),
162
- "all_resmushed" => esc_html__( 'All images are fully optimised.', 'wp-smushit' ),
163
  'restore' => esc_html__( "Restoring image..", "wp-smushit" ),
164
  'smushing' => esc_html__( "Smushing image..", "wp-smushit" ),
165
  'checking' => esc_html__( "Checking images..", "wp-smushit" )
@@ -167,6 +167,12 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
167
 
168
  wp_localize_script( $handle, 'wp_smush_msgs', $wp_smush_msgs );
169
 
 
 
 
 
 
 
170
  //Get the unsmushed ids, used for localized stats as well as normal localization
171
  $unsmushed = $wpsmushnextgenstats->get_ngg_images( 'unsmushed' );
172
  $unsmushed = ( ! empty( $unsmushed ) && is_array( $unsmushed ) ) ? array_keys( $unsmushed ) : '';
@@ -186,15 +192,25 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
186
  $this->resmush_ids = $resmush_ids;
187
  }
188
 
 
 
 
189
  //Array of all smushed, unsmushed and lossless ids
190
  $data = array(
191
- 'count_smushed' => $this->smushed_count,
192
- 'count_total' => $this->total_count,
193
- 'smushed' => $smushed,
194
- 'unsmushed' => $unsmushed,
195
- 'resmush' => $this->resmush_ids
 
 
196
  );
197
 
 
 
 
 
 
198
  wp_localize_script( 'wp-smushit-admin-js', 'wp_smushit_data', $data );
199
 
200
  }
@@ -376,18 +392,17 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
376
  //Page Header
377
  $this->bulk_ui->smush_page_header(); ?>
378
  <!-- Bulk Smush Progress Bar -->
379
- <div class="wp-smushit-container-left col-two-third float-l"><?php
380
- //Bulk Smush Container
381
- $this->bulk_smush_container();
382
- ?>
383
- </div>
384
 
385
- <!-- Stats -->
386
- <div class="wp-smushit-container-right col-third float-l"><?php
387
- //Stats
388
- $this->smush_stats_container(); ?>
389
- </div><!-- End Of Smushit Container right --><?php
390
- $this->get_nextgen_attachments(); ?>
391
  </div><?php
392
  $this->bulk_ui->smush_page_footer();
393
  }
@@ -418,7 +433,7 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
418
  //If there are no images in Media Library
419
  if ( 0 >= $this->total_count ) { ?>
420
  <span class="wp-smush-no-image tc">
421
- <img src="<?php echo WP_SMUSH_URL . 'assets/images/smush-upload-images.png'; ?>"
422
  alt="<?php esc_html_e( "No attachments found - Upload some images", "wp-smushit" ); ?>">
423
  </span>
424
  <p class="wp-smush-no-images-content tc roboto-regular"><?php printf( esc_html__( "We haven’t found any images in your %sgallery%s yet, so there’s no smushing to be done! Once you upload images, reload this page and start playing!", "wp-smushit" ), '<a href="' . esc_url( admin_url( 'admin.php?page=ngg_addgallery' ) ) . '">', '</a>' ); ?></p>
@@ -429,7 +444,7 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
429
  } else { ?>
430
  <!-- Hide All done div if there are images pending -->
431
  <div class="wp-smush-notice wp-smush-all-done<?php echo $all_done ? '' : ' hidden' ?>">
432
- <i class="dev-icon dev-icon-tick"></i><?php esc_html_e( "No attachments need smushing. Awesome!", "wp-smushit" ); ?>
433
  </div>
434
  <div class="wp-smush-bulk-wrapper <?php echo $all_done ? ' hidden' : ''; ?>"><?php
435
  //If all the images in media library are smushed
@@ -441,11 +456,11 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
441
  <i class="dev-icon">
442
  <img src="<?php echo WP_SMUSH_URL . 'assets/images/icon-gzip.svg'; ?>" width="14px">
443
  </i>
444
- <span
445
- class="wp-smush-notice-text"><?php printf( _n( "%s, you have %s%s%d%s image%s that need smushing!", "%s, you have %s%s%d%s images%s that need smushing!", $this->remaining_count, "wp-smushit" ), $wpsmushit_admin->get_user_name(), '<strong>', '<span class="wp-smush-remaining-count">', $this->remaining_count, '</span>', '</strong>' ); ?></span>
 
446
  </div>
447
  <hr class="wp-smush-sep">
448
- <div class="smush-final-log notice notice-warning inline hidden"></div>
449
  <button type="button"
450
  class="wp-smush-button wp-smush-nextgen-bulk"><?php echo $button_content; ?></button><?php
451
 
@@ -475,7 +490,7 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
475
  //Subheading Content
476
  $smush_individual_msg = sprintf( esc_html__( "Smush individual images via your %sManage Galleries%s section", "wp-smushit" ), '<a href="' . esc_url( admin_url() . 'admin.php?page=nggallery-manage-gallery' ) . '" title="' . esc_html__( 'Manage Galleries', 'wp-smushit' ) . '">', '</a>' );
477
 
478
- $class = $WpSmush->is_pro() ? 'bulk-smush-wrapper wp-smush-pro-install' : 'bulk-smush-wrapper';
479
 
480
  //Container Header
481
  $this->bulk_ui->container_header( $class, 'wp-smush-bulk-wrap-box', esc_html__( "BULK SMUSH", "wp-smushit" ), $smush_individual_msg ); ?>
@@ -490,63 +505,69 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
490
  * Outputs the Smush stats for the site
491
  */
492
  function smush_stats_container() {
493
- global $WpSmush, $wpsmushnextgenstats, $wpsmushit_admin;
494
 
495
  //If we have resmush list, smushed_count = totalcount - resmush count, else smushed_count
496
  $smushed_count = ( $resmush_count = count( $this->resmush_ids ) ) > 0 ? ( $this->total_count - ( $resmush_count + $this->remaining_count ) ) : $this->smushed_count;
497
 
498
- //NextGen Stats
499
- $this->stats = $wpsmushnextgenstats->get_smush_stats();
500
-
501
- $button = '<span class="spinner"></span><button tooltip="' . esc_html__( "Lets you check if any images can be further optimised. Useful after changing settings.", "wp-smushit" ) . '" data-type="nextgen" class="wp-smush-title button button-grey button-small wp-smush-scan">' . esc_html__( "RE-CHECK IMAGES", "wp-smushit" ) . '</button>';
502
- $this->bulk_ui->container_header( 'smush-stats-wrapper', 'wp-smush-stats-box', esc_html__( "STATS", "wp-smushit" ), $button ); ?>
503
 
504
  <div class="box-content">
505
- <div class="row smush-total-reduction-percent">
506
- <span class="float-l wp-smush-stats-label">
507
- <strong><?php esc_html_e( "TOTAL % REDUCTIONS", "wp-smushit" ); ?></strong>
508
- </span>
509
- <span class="float-r wp-smush-stats-wrap">
510
- <strong>
511
- <span
512
- class="wp-smush-stats"><?php echo $this->stats['percent'] > 0 ? number_format_i18n( $this->stats['percent'], 2, '.', '' ) : 0; ?></span>%
513
- </strong>
514
- </span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
515
  </div>
516
- <hr>
517
- <div class="row smush-total-reduction-bytes">
518
- <span class="float-l wp-smush-stats-label">
519
- <strong><?php esc_html_e( "TOTAL SIZE REDUCTIONS", "wp-smushit" ); ?></strong>
520
- </span>
521
- <span class="float-r wp-smush-stats">
522
- <strong><?php echo $this->stats['human'] > 0 ? $this->stats['human'] : "0MB"; ?></strong>
 
523
  </span>
 
524
  </div>
525
- <hr>
526
- <div class="row smush-attachments">
527
- <span class="float-l wp-smush-stats-label">
528
- <strong><?php esc_html_e( "ATTACHMENTS SMUSHED", "wp-smushit" ); ?></strong>
529
- </span>
530
- <span class="float-r wp-smush-stats">
531
- <strong>
532
- <span
533
- class="smushed-count"><?php echo $smushed_count . '</span>/' . $this->total_count; ?>
534
- </strong>
535
- </span>
536
- </div><?php
537
  //Nonce Field for Ajax requests
538
  echo wp_nonce_field( 'save_wp_smush_options', 'wp_smush_options_nonce', '', false );
539
  if ( apply_filters( 'wp_smush_show_nextgen_lossy_stats', true ) ) { ?>
540
  <hr>
541
  <div class="row super-smush-attachments">
542
  <span class="float-l wp-smush-stats-label">
543
- <strong><?php esc_html_e( "ATTACHMENTS SUPER-SMUSHED", "wp-smushit" ); ?></strong>
544
  </span>
545
  <span class="float-r wp-smush-stats">
546
  <?php
547
  if ( $WpSmush->lossy_enabled ) {
548
- $count = $wpsmushit_admin->super_smushed_count( 'nextgen', $wpsmushnextgenstats->get_ngg_images( 'smushed' ) );
549
- echo '<strong><span class="smushed-count">' . $count . '</span>/' . $this->total_count . '</strong>';
550
  } else {
551
  printf( esc_html__( "%sDISABLED%s", "wp-smushit" ), '<span class="wp-smush-lossy-disabled">', '</span>' );
552
  } ?>
@@ -576,9 +597,11 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
576
  * Fetch the stats for the given attachment id, and subtract them from Global stats
577
  *
578
  * @param $attachment_id
 
 
579
  */
580
  function update_nextgen_stats( $attachment_id ) {
581
- global $WpSmush, $wpsmushit_admin;
582
 
583
  if ( empty( $attachment_id ) ) {
584
  return false;
@@ -608,11 +631,11 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
608
  $nextgen_stats['size_after'] = $nextgen_stats['size_after'] - $smush_stats['stats']['size_after'];
609
  $nextgen_stats['bytes'] = $nextgen_stats['size_before'] - $nextgen_stats['size_after'];
610
  $nextgen_stats['percent'] = ( $nextgen_stats['bytes'] / $nextgen_stats['size_before'] ) * 100;
611
- $nextgen_stats['human'] = $WpSmush->format_bytes( $nextgen_stats['bytes'] );
612
  }
613
 
614
  //Update Stats
615
- update_option( 'wp_smush_stats_nextgen', $nextgen_stats );
616
 
617
  //Remove from Super Smush list
618
  $wpsmushit_admin->update_super_smush_count( $attachment_id, 'remove', 'wp-smush-super_smushed_nextgen' );
@@ -638,12 +661,86 @@ if ( ! class_exists( 'WpSmushNextGenAdmin' ) ) {
638
  */
639
  function setup_stats() {
640
  global $wpsmushnextgenstats;
 
 
 
641
  //Set the counts
642
  $this->total_count = $wpsmushnextgenstats->total_count();
643
- $this->smushed_count = $wpsmushnextgenstats->get_ngg_images( 'smushed', true );
 
644
  $this->remaining_count = $wpsmushnextgenstats->get_ngg_images( 'unsmushed', true );
645
  }
646
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
647
  }//End of Class
648
 
649
  }//End Of if class not exists
17
 
18
  var $total_count = 0;
19
  var $smushed_count = 0;
20
+ var $image_count = 0;
21
  var $remaining_count = 0;
22
  var $super_smushed = 0;
23
  var $bulk_page_handle;
102
  * @param $id
103
  */
104
  function wp_smush_column_options( $column_name, $id, $echo = false ) {
105
+ global $wpsmushnextgenstats, $wpsmushit_admin;
106
 
107
  //NExtGen Doesn't returns Column name, weird? yeah, right, it is proper because hook is called for the particular column
108
  if ( $column_name == 'wp_smush_image' || $column_name == '' ) {
 
109
 
110
  // Registry Object for NextGen Gallery
111
  $registry = C_Component_Registry::get_instance();
129
  $image_type = $this->get_file_type( $file_path );
130
 
131
  //If image type not supported
132
+ if ( ! $image_type || ! in_array( $image_type, $wpsmushit_admin->mime_types ) ) {
133
  return;
134
  }
135
 
136
+ $image->meta_data = $this->get_combined_stats( $image->meta_data );
137
+
138
  //Check Image metadata, if smushed, print the stats or super smush button
139
  if ( ! empty( $image->meta_data['wp_smush'] ) ) {
140
  //Echo the smush stats
153
  function localize() {
154
  global $wpsmushnextgenstats;
155
 
 
 
156
  $handle = 'wp-smushit-admin-js';
157
 
158
  $wp_smush_msgs = array(
159
  'resmush' => esc_html__( 'Super-Smush', 'wp-smushit' ),
160
  'smush_now' => esc_html__( 'Smush Now', 'wp-smushit' ),
161
  "error_in_bulk" => esc_html__( '{{errors}} image(s) were skipped due to an error.', 'wp-smushit' ),
162
+ "all_resmushed" => esc_html__( 'All images are fully optimized.', 'wp-smushit' ),
163
  'restore' => esc_html__( "Restoring image..", "wp-smushit" ),
164
  'smushing' => esc_html__( "Smushing image..", "wp-smushit" ),
165
  'checking' => esc_html__( "Checking images..", "wp-smushit" )
167
 
168
  wp_localize_script( $handle, 'wp_smush_msgs', $wp_smush_msgs );
169
 
170
+ //Initialize Stats
171
+ $this->setup_stats();
172
+
173
+ //Get the Latest Stats
174
+ $this->stats = $wpsmushnextgenstats->get_smush_stats();
175
+
176
  //Get the unsmushed ids, used for localized stats as well as normal localization
177
  $unsmushed = $wpsmushnextgenstats->get_ngg_images( 'unsmushed' );
178
  $unsmushed = ( ! empty( $unsmushed ) && is_array( $unsmushed ) ) ? array_keys( $unsmushed ) : '';
192
  $this->resmush_ids = $resmush_ids;
193
  }
194
 
195
+ $super_smushed = get_option('wp-smush-super_smushed_nextgen', array() );
196
+ $super_smushed = !empty( $super_smushed['ids'] ) ? $super_smushed['ids'] : array();
197
+
198
  //Array of all smushed, unsmushed and lossless ids
199
  $data = array(
200
+ 'count_smushed' => $this->smushed_count,
201
+ 'count_supersmushed' => count( $super_smushed ),
202
+ 'count_total' => $this->total_count,
203
+ 'count_images' => $this->image_count,
204
+ 'smushed' => $smushed,
205
+ 'unsmushed' => $unsmushed,
206
+ 'resmush' => $this->resmush_ids,
207
  );
208
 
209
+ //Add the stats to arrray
210
+ if ( ! empty( $this->stats ) && is_array( $this->stats ) ) {
211
+ $data = array_merge( $data, $this->stats );
212
+ }
213
+
214
  wp_localize_script( 'wp-smushit-admin-js', 'wp_smushit_data', $data );
215
 
216
  }
392
  //Page Header
393
  $this->bulk_ui->smush_page_header(); ?>
394
  <!-- Bulk Smush Progress Bar -->
395
+ <div class="wp-smushit-container-left col-half float-l"><?php
396
+ //Bulk Smush Container
397
+ $this->bulk_smush_container();
398
+ ?>
399
+ </div>
400
 
401
+ <!-- Stats -->
402
+ <div class="wp-smushit-container-right col-half float-l"><?php
403
+ //Stats
404
+ $this->smush_stats_container(); ?>
405
+ </div><!-- End Of Smushit Container right -->
 
406
  </div><?php
407
  $this->bulk_ui->smush_page_footer();
408
  }
433
  //If there are no images in Media Library
434
  if ( 0 >= $this->total_count ) { ?>
435
  <span class="wp-smush-no-image tc">
436
+ <img src="<?php echo WP_SMUSH_URL . 'assets/images/smush-no-media.png'; ?>"
437
  alt="<?php esc_html_e( "No attachments found - Upload some images", "wp-smushit" ); ?>">
438
  </span>
439
  <p class="wp-smush-no-images-content tc roboto-regular"><?php printf( esc_html__( "We haven’t found any images in your %sgallery%s yet, so there’s no smushing to be done! Once you upload images, reload this page and start playing!", "wp-smushit" ), '<a href="' . esc_url( admin_url( 'admin.php?page=ngg_addgallery' ) ) . '">', '</a>' ); ?></p>
444
  } else { ?>
445
  <!-- Hide All done div if there are images pending -->
446
  <div class="wp-smush-notice wp-smush-all-done<?php echo $all_done ? '' : ' hidden' ?>">
447
+ <i class="dev-icon dev-icon-tick"></i><?php esc_html_e( "All images are smushed and up to date. Awesome!", "wp-smushit" ); ?>
448
  </div>
449
  <div class="wp-smush-bulk-wrapper <?php echo $all_done ? ' hidden' : ''; ?>"><?php
450
  //If all the images in media library are smushed
456
  <i class="dev-icon">
457
  <img src="<?php echo WP_SMUSH_URL . 'assets/images/icon-gzip.svg'; ?>" width="14px">
458
  </i>
459
+ <span class="wp-smush-notice-text">
460
+ <?php printf( _n( "%s, you have %s%s%d%s attachment%s that needs smushing!", "%s, you have %s%s%d%s attachments%s that need smushing!", $this->remaining_count, "wp-smushit" ), $wpsmushit_admin->get_user_name(), '<strong>', '<span class="wp-smush-remaining-count">', $this->remaining_count, '</span>', '</strong>' ); ?>
461
+ </span>
462
  </div>
463
  <hr class="wp-smush-sep">
 
464
  <button type="button"
465
  class="wp-smush-button wp-smush-nextgen-bulk"><?php echo $button_content; ?></button><?php
466
 
490
  //Subheading Content
491
  $smush_individual_msg = sprintf( esc_html__( "Smush individual images via your %sManage Galleries%s section", "wp-smushit" ), '<a href="' . esc_url( admin_url() . 'admin.php?page=nggallery-manage-gallery' ) . '" title="' . esc_html__( 'Manage Galleries', 'wp-smushit' ) . '">', '</a>' );
492
 
493
+ $class = $WpSmush->validate_install() ? 'bulk-smush-wrapper wp-smush-pro-install' : 'bulk-smush-wrapper';
494
 
495
  //Container Header
496
  $this->bulk_ui->container_header( $class, 'wp-smush-bulk-wrap-box', esc_html__( "BULK SMUSH", "wp-smushit" ), $smush_individual_msg ); ?>
505
  * Outputs the Smush stats for the site
506
  */
507
  function smush_stats_container() {
508
+ global $WpSmush, $wpsmushnextgenstats, $wpsmushit_admin, $wpsmush_db;
509
 
510
  //If we have resmush list, smushed_count = totalcount - resmush count, else smushed_count
511
  $smushed_count = ( $resmush_count = count( $this->resmush_ids ) ) > 0 ? ( $this->total_count - ( $resmush_count + $this->remaining_count ) ) : $this->smushed_count;
512
 
513
+ $button = '<span class="spinner"></span><button tooltip="' . esc_html__( "Lets you check if any images can be further optimized. Useful after changing settings.", "wp-smushit" ) . '" data-type="nextgen" class="wp-smush-title button button-grey button-small wp-smush-scan">' . esc_html__( "RE-CHECK IMAGES", "wp-smushit" ) . '</button>';
514
+ $this->bulk_ui->container_header( 'smush-stats-wrapper', 'wp-smush-stats-box', esc_html__( "STATS", "wp-smushit" ), $button );
515
+ $dasharray = 125.663706144;
516
+ $dash_offset = $this->total_count > 0 ? $dasharray - ( $dasharray * ( $smushed_count / $this->total_count ) ) : $dasharray; ?>
 
517
 
518
  <div class="box-content">
519
+ <div class="row smush-total-savings smush-total-reduction-percent">
520
+
521
+ <div class="wp-smush-current-progress">
522
+ <div class="wp-smushed-progress">
523
+ <div class="wp-smush-score inside">
524
+ <div class="tooltip-box">
525
+ <div class="wp-smush-optimisation-progress">
526
+ <div class="wp-smush-progress-circle">
527
+ <svg class="wp-smush-svg" xmlns="http://www.w3.org/2000/svg" width="50" height="50">
528
+ <circle class="wp-smush-svg-circle" r="20" cx="25" cy="25" fill="transparent" stroke-dasharray="0" stroke-dashoffset="0"></circle>
529
+ <!-- Stroke Dasharray is 2 PI r -->
530
+ <circle class="wp-smush-svg-circle wp-smush-svg-circle-progress" r="20" cx="25" cy="25" fill="transparent" stroke-dasharray="<?php echo $dasharray; ?>" style="stroke-dashoffset: <?php echo $dash_offset; ?>px;"></circle>
531
+ </svg>
532
+ </div>
533
+ </div>
534
+ </div><!-- end tooltip-box -->
535
+ </div>
536
+ </div>
537
+
538
+ <div class="wp-smush-count-total">
539
+ <div class="wp-smush-smush-stats-wrapper">
540
+ <span class="wp-smush-total-optimised"><?php echo $this->image_count; ?></span>
541
+ </div>
542
+ <span class="total-stats-label"><strong><?php esc_html_e( "IMAGES SMUSHED", "wp-smushit" ); ?></strong></span>
543
+ </div>
544
+ </div>
545
  </div>
546
+ <hr />
547
+ <div class="row wp-smush-savings">
548
+ <span class="float-l wp-smush-stats-label"><strong><?php esc_html_e("TOTAL SAVINGS", "wp-smushit");?></strong></span>
549
+ <span class="float-r wp-smush-stats">
550
+ <span class="wp-smush-stats-percent"><?php echo $this->stats['percent'] > 0 ? number_format_i18n( $this->stats['percent'], 1, '.', '' ) : 0; ?></span>%
551
+ <span class="wp-smush-stats-sep">/</span>
552
+ <span class="wp-smush-stats-human">
553
+ <?php echo $this->stats['human'] > 0 ? $this->stats['human'] : "0MB"; ?>
554
  </span>
555
+ </span>
556
  </div>
557
+ <?php
 
 
 
 
 
 
 
 
 
 
 
558
  //Nonce Field for Ajax requests
559
  echo wp_nonce_field( 'save_wp_smush_options', 'wp_smush_options_nonce', '', false );
560
  if ( apply_filters( 'wp_smush_show_nextgen_lossy_stats', true ) ) { ?>
561
  <hr>
562
  <div class="row super-smush-attachments">
563
  <span class="float-l wp-smush-stats-label">
564
+ <strong><?php esc_html_e( "IMAGES SUPER-SMUSHED", "wp-smushit" ); ?></strong>
565
  </span>
566
  <span class="float-r wp-smush-stats">
567
  <?php
568
  if ( $WpSmush->lossy_enabled ) {
569
+ $count = $wpsmush_db->super_smushed_count( 'nextgen', $wpsmushnextgenstats->get_ngg_images( 'smushed' ) );
570
+ echo '<span class="smushed-count">' . $count . '</span>/' . $this->total_count;
571
  } else {
572
  printf( esc_html__( "%sDISABLED%s", "wp-smushit" ), '<span class="wp-smush-lossy-disabled">', '</span>' );
573
  } ?>
597
  * Fetch the stats for the given attachment id, and subtract them from Global stats
598
  *
599
  * @param $attachment_id
600
+ *
601
+ * @return bool
602
  */
603
  function update_nextgen_stats( $attachment_id ) {
604
+ global $wpsmushit_admin;
605
 
606
  if ( empty( $attachment_id ) ) {
607
  return false;
631
  $nextgen_stats['size_after'] = $nextgen_stats['size_after'] - $smush_stats['stats']['size_after'];
632
  $nextgen_stats['bytes'] = $nextgen_stats['size_before'] - $nextgen_stats['size_after'];
633
  $nextgen_stats['percent'] = ( $nextgen_stats['bytes'] / $nextgen_stats['size_before'] ) * 100;
634
+ $nextgen_stats['human'] = size_format( $nextgen_stats['bytes'], 1 );
635
  }
636
 
637
  //Update Stats
638
+ update_option( 'wp_smush_stats_nextgen', $nextgen_stats, false );
639
 
640
  //Remove from Super Smush list
641
  $wpsmushit_admin->update_super_smush_count( $attachment_id, 'remove', 'wp-smush-super_smushed_nextgen' );
661
  */
662
  function setup_stats() {
663
  global $wpsmushnextgenstats;
664
+
665
+ $smushed_images = $wpsmushnextgenstats->get_ngg_images( 'smushed' );
666
+
667
  //Set the counts
668
  $this->total_count = $wpsmushnextgenstats->total_count();
669
+ $this->image_count = $this->get_image_count( $smushed_images );
670
+ $this->smushed_count = count( $smushed_images );
671
  $this->remaining_count = $wpsmushnextgenstats->get_ngg_images( 'unsmushed', true );
672
  }
673
 
674
+ /**
675
+ * Get the image count for nextgen images
676
+ *
677
+ * @param array $smushed_images
678
+ *
679
+ * @return int
680
+ */
681
+ function get_image_count( $smushed_images = array() ) {
682
+ if ( empty( $smushed_images ) || ! is_array( $smushed_images ) ) {
683
+ return 0;
684
+ }
685
+ $image_count = 0;
686
+ foreach ( $smushed_images as $image ) {
687
+ //If there are no smush stats, skip
688
+ if ( empty( $image['wp_smush'] ) ) {
689
+ continue;
690
+ }
691
+ //Get the image count
692
+ if ( ! empty( $image['wp_smush']['sizes'] ) ) {
693
+ $image_count += count( $image['wp_smush']['sizes'] );
694
+ }
695
+ }
696
+
697
+ return $image_count;
698
+ }
699
+
700
+ /**
701
+ * Combine the resizing stats and smush stats
702
+ *
703
+ * @param $metadata
704
+ *
705
+ * @return bool|string
706
+ */
707
+ function get_combined_stats( $metadata ) {
708
+ if ( empty( $metadata ) ) {
709
+ return $metadata;
710
+ }
711
+
712
+ $smush_stats = ! empty( $metadata['wp_smush'] ) ? $metadata['wp_smush'] : '';
713
+ $resize_savings = ! empty( $metadata['wp_smush_resize_savings'] ) ? $metadata['wp_smush_resize_savings'] : '';
714
+
715
+ if ( empty( $resize_savings ) ) {
716
+ return $metadata;
717
+ }
718
+
719
+ $smush_stats['stats']['bytes'] = ! empty( $resize_savings['bytes'] ) ? $smush_stats['stats']['bytes'] + $resize_savings['bytes'] : $smush_stats['stats']['bytes'];
720
+ $smush_stats['stats']['size_before'] = ! empty( $resize_savings['size_before'] ) ? $smush_stats['stats']['size_before'] + $resize_savings['size_before'] : $smush_stats['stats']['size_before'];
721
+ $smush_stats['stats']['size_after'] = ! empty( $resize_savings['size_after'] ) ? $smush_stats['stats']['size_after'] + $resize_savings['size_after'] : $smush_stats['stats']['size_after'];
722
+ $smush_stats['stats']['percent'] = ! empty( $resize_savings['size_before'] ) ? ( $smush_stats['stats']['bytes'] / $smush_stats['stats']['size_before'] ) * 100 : $smush_stats['stats']['percent'];
723
+
724
+ //Round off
725
+ $smush_stats['stats']['percent'] = round( $smush_stats['stats']['percent'], 2 );
726
+
727
+ if( !empty( $smush_stats['sizes']['full'] ) ) {
728
+ //Full Image
729
+ $smush_stats['sizes']['full']['bytes'] = ! empty( $resize_savings['bytes'] ) ? $smush_stats['sizes']['full']['bytes'] + $resize_savings['bytes'] : $smush_stats['sizes']['full']['bytes'];
730
+ $smush_stats['sizes']['full']['size_before'] = ! empty( $resize_savings['size_before'] ) ? $smush_stats['sizes']['full']['size_before'] + $resize_savings['size_before'] : $smush_stats['sizes']['full']['size_before'];
731
+ $smush_stats['sizes']['full']['size_after'] = ! empty( $resize_savings['size_after'] ) ? $smush_stats['sizes']['full']['size_after'] + $resize_savings['size_after'] : $smush_stats['sizes']['full']['size_after'];
732
+ $smush_stats['sizes']['full']['percent'] = ! empty( $smush_stats['sizes']['full']['bytes'] ) && $smush_stats['sizes']['full']['size_before'] > 0 ? ( $smush_stats['sizes']['full']['bytes'] / $smush_stats['sizes']['full']['size_before'] ) * 100 : $smush_stats['sizes']['full']['percent'];
733
+
734
+ $smush_stats['sizes']['full']['percent'] = round( $smush_stats['sizes']['full']['percent'], 2 );
735
+ }else{
736
+ $smush_stats['sizes']['full'] = $resize_savings;
737
+ }
738
+
739
+ $metadata['wp_smush'] = $smush_stats;
740
+ return $metadata;
741
+
742
+ }
743
+
744
  }//End of Class
745
 
746
  }//End Of if class not exists
lib/nextgen-integration/class-wp-smush-nextgen-bulk.php CHANGED
@@ -8,7 +8,7 @@ if ( ! class_exists( 'WPSmushNextGenBulk' ) ) {
8
 
9
  function smush_bulk() {
10
 
11
- global $wpsmushnextgenstats, $wpsmushit_admin, $wpsmushnextgenadmin, $WpSmush;
12
 
13
  $stats = array();
14
 
@@ -16,40 +16,62 @@ if ( ! class_exists( 'WPSmushNextGenBulk' ) ) {
16
  wp_send_json_error( 'missing id' );
17
  }
18
 
19
- $atchmnt_id = absint( (int) $_GET['attachment_id'] );
20
-
21
- $smush = $this->smush_image( $atchmnt_id, '', false );
22
-
23
- $stats = $wpsmushnextgenstats->get_smush_stats();
24
 
25
- $stats['smushed'] = $wpsmushnextgenstats->get_ngg_images('smushed', true );
26
-
27
- if ( $WpSmush->lossy_enabled ) {
28
- //Most of the time the stats would be update and the function won't need to go thorugh all the
29
- //images to get the count, but in case it has to, we provide the SMushed attachment list
30
- $stats['super_smushed'] = $wpsmushit_admin->super_smushed_count('nextgen', $wpsmushnextgenstats->get_ngg_images('smushed' ) );
31
- }
32
- if( empty( $wpsmushnextgenadmin->resmush_ids ) ) {
33
- $wpsmushnextgenadmin->resmush_ids = get_option( 'wp-smush-nextgen-resmush-list' );
34
- }
35
- $stats['resmush_count'] = count( $wpsmushnextgenadmin->resmush_ids );
36
 
37
- $stats['total'] = $wpsmushnextgenstats->total_count();
38
 
39
  if ( is_wp_error( $smush ) ) {
40
- $error = $smush->get_error_message();
 
 
41
  //Check for timeout error and suggest to filter timeout
42
- if( strpos( $error, 'timed out') ) {
43
- $msg = esc_html__( "Smush request timed out, You can try setting a higher value ( > 60 ) for `WP_SMUSH_API_TIMEOUT`.", "wp-smushit" );
44
  }
45
- wp_send_json_error( array( 'stats' => $stats, 'error_msg' => $msg ) );
46
  } else {
47
  //Check if a resmush request, update the resmush list
48
- if( !empty( $_REQUEST['is_bulk_resmush']) && $_REQUEST['is_bulk_resmush'] ) {
49
  $wpsmushit_admin->update_resmush_list( $atchmnt_id, 'wp-smush-nextgen-resmush-list' );
50
  }
51
- wp_send_json_success( array( 'stats' => $stats ) );
52
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
 
55
  }
8
 
9
  function smush_bulk() {
10
 
11
+ global $wpsmushnextgenstats, $wpsmush_db, $wpsmushit_admin, $wpsmushnextgenadmin, $WpSmush;
12
 
13
  $stats = array();
14
 
16
  wp_send_json_error( 'missing id' );
17
  }
18
 
19
+ $send_error = false;
 
 
 
 
20
 
21
+ $atchmnt_id = absint( (int) $_GET['attachment_id'] );
 
 
 
 
 
 
 
 
 
 
22
 
23
+ $smush = $this->smush_image( $atchmnt_id, '', false, true );
24
 
25
  if ( is_wp_error( $smush ) ) {
26
+ $send_error = true;
27
+ $msg = '';
28
+ $error = $smush->get_error_message();
29
  //Check for timeout error and suggest to filter timeout
30
+ if ( strpos( $error, 'timed out' ) ) {
31
+ $msg = '<p class="wp-smush-error-message">' . esc_html__( "Smush request timed out, You can try setting a higher value ( > 60 ) for `WP_SMUSH_API_TIMEOUT`.", "wp-smushit" ) . '</p>';
32
  }
 
33
  } else {
34
  //Check if a resmush request, update the resmush list
35
+ if ( ! empty( $_REQUEST['is_bulk_resmush'] ) && $_REQUEST['is_bulk_resmush'] ) {
36
  $wpsmushit_admin->update_resmush_list( $atchmnt_id, 'wp-smush-nextgen-resmush-list' );
37
  }
 
38
  }
39
+
40
+ $stats['is_lossy'] = !empty( $smush['stats'] ) ? $smush['stats']['lossy'] : 0;
41
+
42
+ //Size before and after smush
43
+ $stats['size_before'] = !empty( $smush['stats'] ) ? $smush['stats']['size_before'] : 0;
44
+ $stats['size_after'] = !empty( $smush['stats'] ) ? $smush['stats']['size_after'] : 0;
45
+
46
+ //Get the resmush ids list
47
+ if ( empty( $wpsmushnextgenadmin->resmush_ids ) ) {
48
+ $wpsmushnextgenadmin->resmush_ids = get_option( 'wp-smush-nextgen-resmush-list' );
49
+ }
50
+
51
+ $wpsmushnextgenadmin->resmush_ids = empty( $wpsmushnextgenadmin->resmush_ids ) ? get_option( 'wp-smush-nextgen-resmush-list' ) : array();
52
+ $resmush_count = ! empty( $wpsmushnextgenadmin->resmush_ids ) ? count( $wpsmushnextgenadmin->resmush_ids ) : 0;
53
+ $smushed_images = $wpsmushnextgenstats->get_ngg_images( 'smushed' );
54
+
55
+ //remove resmush ids from smushed images list
56
+ if ( $resmush_count > 0 && is_array( $wpsmushnextgenadmin->resmush_ids ) ) {
57
+ foreach ( $smushed_images as $image_k => $image ) {
58
+ if ( in_array( $image_k, $wpsmushnextgenadmin->resmush_ids ) ) {
59
+ unset( $smushed_images[ $image_k ] );
60
+ }
61
+ }
62
+ }
63
+
64
+ //Get the image count and smushed images count
65
+ $image_count = ! empty( $smush ) && ! empty( $smush['sizes'] ) ? count( $smush['sizes'] ) : 0;
66
+ $smushed_count = is_array( $smushed_images ) ? count( $smushed_images ) : 0;
67
+
68
+ $stats['smushed'] = ! empty( $wpsmushnextgenadmin->resmush_ids ) ? $smushed_count - $resmush_count : $smushed_count;
69
+ $stats['count'] = $image_count;
70
+
71
+ $send_error ? wp_send_json_error( array(
72
+ 'stats' => $stats,
73
+ 'error_msg' => $msg
74
+ ) ) : wp_send_json_success( array( 'stats' => $stats ) );
75
  }
76
 
77
  }
lib/nextgen-integration/class-wp-smush-nextgen-stats.php CHANGED
@@ -24,7 +24,7 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
24
  function __construct() {
25
 
26
  global $WpSmush;
27
- $this->is_pro_user = $WpSmush->is_pro();
28
 
29
  //Update Total Image count
30
  add_action( 'ngg_added_new_image', array( $this, 'image_count' ), 10 );
@@ -32,6 +32,9 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
32
  //Update images list in cache
33
  add_action( 'wp_smush_nextgen_image_stats', array( $this, 'update_cache' ) );
34
 
 
 
 
35
  //Get the stats for single image, update the global stats
36
  add_action( 'wp_smush_nextgen_image_stats', array( $this, 'update_stats' ), '', 2 );
37
  }
@@ -91,13 +94,8 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
91
  */
92
  function get_ngg_images( $type = 'smushed', $count = false, $force_update = false ) {
93
 
94
- global $wpdb;
95
- /**
96
- * Allows to set a limit of mysql query
97
- * Default value is 2000
98
- */
99
- $limit = apply_filters( 'wp_smush_nextgen_query_limit', 2000 );
100
- $limit = intval( $limit );
101
  $offset = 0;
102
 
103
  //Check type of images being queried
@@ -179,7 +177,7 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
179
  * @return bool|null|string|void
180
  */
181
  function show_stats( $pid, $wp_smush_data = false, $image_type = '', $text_only = false, $echo = true ) {
182
- global $WpSmush, $wpsmushnextgenadmin;
183
  if ( empty( $wp_smush_data ) ) {
184
  return false;
185
  }
@@ -187,7 +185,7 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
187
  $show_button = $show_resmush = $show_restore = false;
188
 
189
  $bytes = isset( $wp_smush_data['stats']['bytes'] ) ? $wp_smush_data['stats']['bytes'] : 0;
190
- $bytes_readable = ! empty( $bytes ) ? $WpSmush->format_bytes( $bytes ) : '';
191
  $percent = isset( $wp_smush_data['stats']['percent'] ) ? $wp_smush_data['stats']['percent'] : 0;
192
  $percent = $percent < 0 ? 0 : $percent;
193
 
@@ -269,7 +267,7 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
269
 
270
  //Check if Lossy enabled
271
  $opt_lossy = WP_SMUSH_PREFIX . 'lossy';
272
- $opt_lossy_val = get_option( $opt_lossy, false );
273
 
274
  //Check if premium user, compression was lossless, and lossy compression is enabled
275
  if ( !$show_resmush && $this->is_pro_user && ! $is_lossy && $opt_lossy_val && ! empty( $image_type ) && $image_type != 'image/gif' ) {
@@ -299,6 +297,44 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
299
  *
300
  */
301
  function update_stats( $image_id, $stats ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  global $WpSmush;
303
 
304
  $stats = ! empty( $stats['stats'] ) ? $stats['stats'] : '';
@@ -311,7 +347,7 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
311
  $smush_stats['bytes'] = ! empty( $smush_stats['bytes'] ) ? ( $smush_stats['bytes'] + $stats['bytes'] ) : $stats['bytes'];
312
 
313
  //Human Readable
314
- $smush_stats['human'] = ! empty( $smush_stats['bytes'] ) ? $WpSmush->format_bytes( $smush_stats['bytes'] ) : '';
315
 
316
  //Size of images before the compression
317
  $smush_stats['size_before'] = ! empty( $smush_stats['size_before'] ) ? ( $smush_stats['size_before'] + $stats['size_before'] ) : $stats['size_before'];
@@ -322,7 +358,7 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
322
  //Compression Percentage
323
  $smush_stats['percent'] = ! empty( $smush_stats['size_before'] ) && !empty( $smush_stats['size_after'] ) && $smush_stats['size_before'] > 0 ? ( $smush_stats['bytes'] / $smush_stats['size_before'] ) * 100 : $stats['percent'];
324
  }
325
- update_option( 'wp_smush_stats_nextgen', $smush_stats );
326
 
327
  //Cahce the results, we don't need a timed cache expiration.
328
  wp_cache_set( 'wp_smush_stats_nextgen', $smush_stats, 'nextgen' );
@@ -363,9 +399,9 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
363
  }
364
 
365
  //Round off precentage
366
- $smushed_stats['percent'] = ! empty( $smushed_stats['percent'] ) ? round( $smushed_stats['percent'], 2 ) : 0;
367
 
368
- $smushed_stats['human'] = $WpSmush->format_bytes( $smushed_stats['bytes'] );
369
 
370
  return $smushed_stats;
371
  }
@@ -424,7 +460,7 @@ if ( ! class_exists( 'WpSmushNextGenStats' ) ) {
424
  if ( $size_value->bytes > 0 ) {
425
  $stats .= '<tr>
426
  <td>' . strtoupper( $size_key ) . '</td>
427
- <td>' . $WpSmush->format_bytes( $size_value->bytes ) . ' ( ' . $size_value->percent . '% )</td>
428
  </tr>';
429
  }
430
  }
24
  function __construct() {
25
 
26
  global $WpSmush;
27
+ $this->is_pro_user = $WpSmush->validate_install();
28
 
29
  //Update Total Image count
30
  add_action( 'ngg_added_new_image', array( $this, 'image_count' ), 10 );
32
  //Update images list in cache
33
  add_action( 'wp_smush_nextgen_image_stats', array( $this, 'update_cache' ) );
34
 
35
+ //Add the resizing stats to Global stats
36
+ add_action( 'wp_smush_image_nextgen_resized', array( $this, 'update_stats' ), '', 2 );
37
+
38
  //Get the stats for single image, update the global stats
39
  add_action( 'wp_smush_nextgen_image_stats', array( $this, 'update_stats' ), '', 2 );
40
  }
94
  */
95
  function get_ngg_images( $type = 'smushed', $count = false, $force_update = false ) {
96
 
97
+ global $wpdb, $wpsmushit_admin;
98
+ $limit = $wpsmushit_admin->nextgen_query_limit();
 
 
 
 
 
99
  $offset = 0;
100
 
101
  //Check type of images being queried
177
  * @return bool|null|string|void
178
  */
179
  function show_stats( $pid, $wp_smush_data = false, $image_type = '', $text_only = false, $echo = true ) {
180
+ global $WpSmush, $wpsmushnextgenadmin, $wpsmush_settings;
181
  if ( empty( $wp_smush_data ) ) {
182
  return false;
183
  }
185
  $show_button = $show_resmush = $show_restore = false;
186
 
187
  $bytes = isset( $wp_smush_data['stats']['bytes'] ) ? $wp_smush_data['stats']['bytes'] : 0;
188
+ $bytes_readable = ! empty( $bytes ) ? size_format( $bytes, 1 ) : '';
189
  $percent = isset( $wp_smush_data['stats']['percent'] ) ? $wp_smush_data['stats']['percent'] : 0;
190
  $percent = $percent < 0 ? 0 : $percent;
191
 
267
 
268
  //Check if Lossy enabled
269
  $opt_lossy = WP_SMUSH_PREFIX . 'lossy';
270
+ $opt_lossy_val = $wpsmush_settings->get_setting( $opt_lossy, false );
271
 
272
  //Check if premium user, compression was lossless, and lossy compression is enabled
273
  if ( !$show_resmush && $this->is_pro_user && ! $is_lossy && $opt_lossy_val && ! empty( $image_type ) && $image_type != 'image/gif' ) {
297
  *
298
  */
299
  function update_stats( $image_id, $stats ) {
300
+
301
+ global $WpSmush;
302
+
303
+ $stats = ! empty( $stats['stats'] ) ? $stats['stats'] : '';
304
+
305
+ $smush_stats = get_option( 'wp_smush_stats_nextgen', array() );
306
+
307
+ if ( ! empty( $stats ) ) {
308
+
309
+ //Compression Bytes
310
+ $smush_stats['bytes'] = ! empty( $smush_stats['bytes'] ) ? ( $smush_stats['bytes'] + $stats['bytes'] ) : $stats['bytes'];
311
+
312
+ //Human Readable
313
+ $smush_stats['human'] = ! empty( $smush_stats['bytes'] ) ? size_format( $smush_stats['bytes'], 1 ) : '';
314
+
315
+ //Size of images before the compression
316
+ $smush_stats['size_before'] = ! empty( $smush_stats['size_before'] ) ? ( $smush_stats['size_before'] + $stats['size_before'] ) : $stats['size_before'];
317
+
318
+ //Size of image after compression
319
+ $smush_stats['size_after'] = ! empty( $smush_stats['size_after'] ) ? ( $smush_stats['size_after'] + $stats['size_after'] ) : $stats['size_after'];
320
+
321
+ //Compression Percentage
322
+ $smush_stats['percent'] = ! empty( $smush_stats['size_before'] ) && !empty( $smush_stats['size_after'] ) && $smush_stats['size_before'] > 0 ? ( $smush_stats['bytes'] / $smush_stats['size_before'] ) * 100 : $stats['percent'];
323
+ }
324
+
325
+ update_option( 'wp_smush_stats_nextgen', $smush_stats, false );
326
+
327
+ //Cahce the results, we don't need a timed cache expiration.
328
+ wp_cache_set( 'wp_smush_stats_nextgen', $smush_stats, 'nextgen' );
329
+ }
330
+
331
+ /**
332
+ * Updated the global smush stats for NextGen gallery
333
+ *
334
+ * @param $stats Compression stats fo respective image
335
+ *
336
+ */
337
+ function update_resize_stats( $image_id, $stats ) {
338
  global $WpSmush;
339
 
340
  $stats = ! empty( $stats['stats'] ) ? $stats['stats'] : '';
347
  $smush_stats['bytes'] = ! empty( $smush_stats['bytes'] ) ? ( $smush_stats['bytes'] + $stats['bytes'] ) : $stats['bytes'];
348
 
349
  //Human Readable
350
+ $smush_stats['human'] = ! empty( $smush_stats['bytes'] ) ? size_format( $smush_stats['bytes'], 1 ) : '';
351
 
352
  //Size of images before the compression
353
  $smush_stats['size_before'] = ! empty( $smush_stats['size_before'] ) ? ( $smush_stats['size_before'] + $stats['size_before'] ) : $stats['size_before'];
358
  //Compression Percentage
359
  $smush_stats['percent'] = ! empty( $smush_stats['size_before'] ) && !empty( $smush_stats['size_after'] ) && $smush_stats['size_before'] > 0 ? ( $smush_stats['bytes'] / $smush_stats['size_before'] ) * 100 : $stats['percent'];
360
  }
361
+ update_option( 'wp_smush_stats_nextgen', $smush_stats, false );
362
 
363
  //Cahce the results, we don't need a timed cache expiration.
364
  wp_cache_set( 'wp_smush_stats_nextgen', $smush_stats, 'nextgen' );
399
  }
400
 
401
  //Round off precentage
402
+ $smushed_stats['percent'] = ! empty( $smushed_stats['percent'] ) ? round( $smushed_stats['percent'], 1 ) : 0;
403
 
404
+ $smushed_stats['human'] = size_format( $smushed_stats['bytes'], 1 );
405
 
406
  return $smushed_stats;
407
  }
460
  if ( $size_value->bytes > 0 ) {
461
  $stats .= '<tr>
462
  <td>' . strtoupper( $size_key ) . '</td>
463
+ <td>' . size_format( $size_value->bytes, 1 ) . ' ( ' . $size_value->percent . '% )</td>
464
  </tr>';
465
  }
466
  }
lib/wp-async-task-smush.php ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WP Asynchronous Tasks
4
+ * Version: 1.0
5
+ * Description: Creates an abstract class to execute asynchronous tasks
6
+ * Author: 10up, Eric Mann, Luke Gedeon, John P. Bloch
7
+ * License: MIT
8
+ * Note: Modified to return metadata at the end of the launch function
9
+ */
10
+
11
+ if ( ! class_exists( 'WP_Async_Task_Smush' ) ) {
12
+ abstract class WP_Async_Task_Smush {
13
+
14
+ /**
15
+ * Constant identifier for a task that should be available to logged-in users
16
+ *
17
+ * See constructor documentation for more details.
18
+ */
19
+ const LOGGED_IN = 1;
20
+
21
+ /**
22
+ * Constant identifier for a task that should be available to logged-out users
23
+ *
24
+ * See constructor documentation for more details.
25
+ */
26
+ const LOGGED_OUT = 2;
27
+
28
+ /**
29
+ * Constant identifier for a task that should be available to all users regardless of auth status
30
+ *
31
+ * See constructor documentation for more details.
32
+ */
33
+ const BOTH = 3;
34
+
35
+ /**
36
+ * This is the argument count for the main action set in the constructor. It
37
+ * is set to an arbitrarily high value of twenty, but can be overridden if
38
+ * necessary
39
+ *
40
+ * @var int
41
+ */
42
+ protected $argument_count = 20;
43
+
44
+ /**
45
+ * Priority to fire intermediate action.
46
+ *
47
+ * @var int
48
+ */
49
+ protected $priority = 10;
50
+
51
+ /**
52
+ * @var string
53
+ */
54
+ protected $action;
55
+
56
+ /**
57
+ * @var array
58
+ */
59
+ protected $_body_data;
60
+
61
+ /**
62
+ * Constructor to wire up the necessary actions
63
+ *
64
+ * Which hooks the asynchronous postback happens on can be set by the
65
+ * $auth_level parameter. There are essentially three options: logged in users
66
+ * only, logged out users only, or both. Set this when you instantiate an
67
+ * object by using one of the three class constants to do so:
68
+ * - LOGGED_IN
69
+ * - LOGGED_OUT
70
+ * - BOTH
71
+ * $auth_level defaults to BOTH
72
+ *
73
+ * @throws Exception If the class' $action value hasn't been set
74
+ *
75
+ * @param int $auth_level The authentication level to use (see above)
76
+ */
77
+ public function __construct( $auth_level = self::BOTH ) {
78
+ if ( empty( $this->action ) ) {
79
+ throw new Exception( 'Action not defined for class ' . __CLASS__ );
80
+ }
81
+ //Handle the actual action
82
+ add_action( $this->action, array( $this, 'launch' ), (int) $this->priority, (int) $this->argument_count );
83
+
84
+ add_action( "admin_post_wp_async_$this->action", array( $this, 'handle_postback' ) );
85
+ }
86
+
87
+ /**
88
+ * Add the shutdown action for launching the real postback if we don't
89
+ * get an exception thrown by prepare_data().
90
+ *
91
+ * @uses func_get_args() To grab any arguments passed by the action
92
+ */
93
+ public function launch() {
94
+ $data = func_get_args();
95
+ try {
96
+ $data = $this->prepare_data( $data );
97
+ } catch ( Exception $e ) {
98
+ error_log( sprintf( "Async Smush: Error in prepare_data function in %s at line %s: %s", __FILE__, __LINE__, $e->getMessage() ) );
99
+ return;
100
+ }
101
+
102
+ $data['action'] = "wp_async_$this->action";
103
+ $data['_nonce'] = $this->create_async_nonce();
104
+
105
+ $this->_body_data = $data;
106
+
107
+ $shutdown_action = has_action( 'shutdown', array( $this, 'process_request' ) );
108
+
109
+ //Do not use this, as in case of importing, only the last image gets processed
110
+ //It's very important that all the Media uploads, are handled via shutdown action, else, sometimes the image meta updated
111
+ // by smush is earlier, and then original meta update causes discrepancy
112
+ if ( ( ( !empty( $_POST['action'] ) && 'upload-attachment' == $_POST['action'] ) || ( ! empty( $_POST ) && isset( $_POST['post_id'] ) ) ) && ! $shutdown_action ) {
113
+ add_action( 'shutdown', array( $this, 'process_request' ) );
114
+ } else {
115
+ //Send a ajax request to process image and return image metadata, added for compatibility with plugins like
116
+ // WP All Import, and RSS aggregator, which upload multiple images at once
117
+ $this->process_request();
118
+ }
119
+
120
+ //If we have image metadata return it
121
+ if ( ! empty( $data['metadata'] ) ) {
122
+ return $data['metadata'];
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Launch the request on the WordPress shutdown hook
128
+ *
129
+ * On VIP we got into data races due to the postback sometimes completing
130
+ * faster than the data could propogate to the database server cluster.
131
+ * This made WordPress get empty data sets from the database without
132
+ * failing. On their advice, we're moving the actual firing of the async
133
+ * postback to the shutdown hook. Supposedly that will ensure that the
134
+ * data at least has time to get into the object cache.
135
+ *
136
+ * @uses $_COOKIE To send a cookie header for async postback
137
+ * @uses apply_filters()
138
+ * @uses admin_url()
139
+ * @uses wp_remote_post()
140
+ */
141
+ public function process_request() {
142
+ if ( ! empty( $this->_body_data ) ) {
143
+ $cookies = array();
144
+ foreach ( $_COOKIE as $name => $value ) {
145
+ $cookies[] = "$name=" . urlencode( is_array( $value ) ? serialize( $value ) : $value );
146
+ }
147
+
148
+ //@todo: We've set sslverify to false
149
+ $request_args = array(
150
+ 'timeout' => apply_filters( 'smush_async_time_out', 0 ),
151
+ 'blocking' => false,
152
+ 'sslverify' => false,
153
+ 'body' => $this->_body_data,
154
+ 'headers' => array(
155
+ 'cookie' => implode( '; ', $cookies ),
156
+ ),
157
+ );
158
+
159
+ $url = admin_url( 'admin-post.php' );
160
+
161
+ wp_remote_post( $url, $request_args );
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Verify the postback is valid, then fire any scheduled events.
167
+ *
168
+ * @uses $_POST['_nonce']
169
+ * @uses is_user_logged_in()
170
+ * @uses add_filter()
171
+ * @uses wp_die()
172
+ */
173
+ public function handle_postback() {
174
+ if ( isset( $_POST['_nonce'] ) && $this->verify_async_nonce( $_POST['_nonce'] ) ) {
175
+ $this->run_action();
176
+ }
177
+
178
+ add_filter( 'wp_die_handler', array( $this, 'handle_die' ) );
179
+ wp_die();
180
+ }
181
+
182
+ /**
183
+ * Handle Die
184
+ */
185
+ function handle_die() {
186
+ die();
187
+ }
188
+
189
+ /**
190
+ * Create a random, one time use token.
191
+ *
192
+ * Based entirely on wp_create_nonce() but does not tie the nonce to the
193
+ * current logged-in user.
194
+ *
195
+ * @uses wp_nonce_tick()
196
+ * @uses wp_hash()
197
+ *
198
+ * @return string The one-time use token
199
+ */
200
+ protected function create_async_nonce() {
201
+ $action = $this->get_nonce_action();
202
+ $i = wp_nonce_tick();
203
+
204
+ return substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 );
205
+ }
206
+
207
+ /**
208
+ * Verify that the correct nonce was used within the time limit.
209
+ *
210
+ * @uses wp_nonce_tick()
211
+ * @uses wp_hash()
212
+ *
213
+ * @param string $nonce Nonce to be verified
214
+ *
215
+ * @return bool Whether the nonce check passed or failed
216
+ */
217
+ protected function verify_async_nonce( $nonce ) {
218
+ $action = $this->get_nonce_action();
219
+ $i = wp_nonce_tick();
220
+
221
+ // Nonce generated 0-12 hours ago
222
+ if ( substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
223
+ return 1;
224
+ }
225
+
226
+ // Nonce generated 12-24 hours ago
227
+ if ( substr( wp_hash( ( $i - 1 ) . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
228
+ return 2;
229
+ }
230
+
231
+ // Invalid nonce
232
+ return false;
233
+ }
234
+
235
+ /**
236
+ * Get a nonce action based on the $action property of the class
237
+ *
238
+ * @return string The nonce action for the current instance
239
+ */
240
+ protected function get_nonce_action() {
241
+ $action = $this->action;
242
+ if ( substr( $action, 0, 7 ) === 'nopriv_' ) {
243
+ $action = substr( $action, 7 );
244
+ }
245
+ $action = "wp_async_$action";
246
+
247
+ return $action;
248
+ }
249
+
250
+ /**
251
+ * Prepare any data to be passed to the asynchronous postback
252
+ *
253
+ * The array this function receives will be a numerically keyed array from
254
+ * func_get_args(). It is expected that you will return an associative array
255
+ * so that the $_POST values used in the asynchronous call will make sense.
256
+ *
257
+ * The array you send back may or may not have anything to do with the data
258
+ * passed into this method. It all depends on the implementation details and
259
+ * what data is needed in the asynchronous postback.
260
+ *
261
+ * Do not set values for 'action' or '_nonce', as those will get overwritten
262
+ * later in launch().
263
+ *
264
+ * @throws Exception If the postback should not occur for any reason
265
+ *
266
+ * @param array $data The raw data received by the launch method
267
+ *
268
+ * @return array The prepared data
269
+ */
270
+ abstract protected function prepare_data( $data );
271
+
272
+ /**
273
+ * Run the do_action function for the asynchronous postback.
274
+ *
275
+ * This method needs to fetch and sanitize any and all data from the $_POST
276
+ * superglobal and provide them to the do_action call.
277
+ *
278
+ * The action should be constructed as "wp_async_task_$this->action"
279
+ */
280
+ abstract protected function run_action();
281
+
282
+ }
283
+
284
+ }
285
+
lib/wp-async-task.php ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WP Asynchronous Tasks
4
+ * Version: 1.0
5
+ * Description: Creates an abstract class to execute asynchronous tasks
6
+ * Author: 10up, Eric Mann, Luke Gedeon, John P. Bloch
7
+ * License: MIT
8
+ * Note: Modified to return metadata at the end of the launch function
9
+ */
10
+
11
+ if ( ! class_exists( 'WP_Async_Task' ) ) {
12
+ abstract class WP_Async_Task {
13
+
14
+ /**
15
+ * Constant identifier for a task that should be available to logged-in users
16
+ *
17
+ * See constructor documentation for more details.
18
+ */
19
+ const LOGGED_IN = 1;
20
+
21
+ /**
22
+ * Constant identifier for a task that should be available to logged-out users
23
+ *
24
+ * See constructor documentation for more details.
25
+ */
26
+ const LOGGED_OUT = 2;
27
+
28
+ /**
29
+ * Constant identifier for a task that should be available to all users regardless of auth status
30
+ *
31
+ * See constructor documentation for more details.
32
+ */
33
+ const BOTH = 3;
34
+
35
+ /**
36
+ * This is the argument count for the main action set in the constructor. It
37
+ * is set to an arbitrarily high value of twenty, but can be overridden if
38
+ * necessary
39
+ *
40
+ * @var int
41
+ */
42
+ protected $argument_count = 20;
43
+
44
+ /**
45
+ * Priority to fire intermediate action.
46
+ *
47
+ * @var int
48
+ */
49
+ protected $priority = 10;
50
+
51
+ /**
52
+ * @var string
53
+ */
54
+ protected $action;
55
+
56
+ /**
57
+ * @var array
58
+ */
59
+ protected $_body_data;
60
+
61
+ /**
62
+ * Constructor to wire up the necessary actions
63
+ *
64
+ * Which hooks the asynchronous postback happens on can be set by the
65
+ * $auth_level parameter. There are essentially three options: logged in users
66
+ * only, logged out users only, or both. Set this when you instantiate an
67
+ * object by using one of the three class constants to do so:
68
+ * - LOGGED_IN
69
+ * - LOGGED_OUT
70
+ * - BOTH
71
+ * $auth_level defaults to BOTH
72
+ *
73
+ * @throws Exception If the class' $action value hasn't been set
74
+ *
75
+ * @param int $auth_level The authentication level to use (see above)
76
+ */
77
+ public function __construct( $auth_level = self::BOTH ) {
78
+ if ( empty( $this->action ) ) {
79
+ throw new Exception( 'Action not defined for class ' . __CLASS__ );
80
+ }
81
+ //Handle the actual action
82
+ add_action( $this->action, array( $this, 'launch' ), (int) $this->priority, (int) $this->argument_count );
83
+
84
+ add_action( "admin_post_wp_async_$this->action", array( $this, 'handle_postback' ) );
85
+ }
86
+
87
+ /**
88
+ * Add the shutdown action for launching the real postback if we don't
89
+ * get an exception thrown by prepare_data().
90
+ *
91
+ * @uses func_get_args() To grab any arguments passed by the action
92
+ */
93
+ public function launch() {
94
+ $data = func_get_args();
95
+ try {
96
+ $data = $this->prepare_data( $data );
97
+ } catch ( Exception $e ) {
98
+ return;
99
+ }
100
+
101
+ $data['action'] = "wp_async_$this->action";
102
+ $data['_nonce'] = $this->create_async_nonce();
103
+
104
+ $this->_body_data = $data;
105
+
106
+ if ( ! has_action( 'shutdown', array( $this, 'launch_on_shutdown' ) ) ) {
107
+ add_action( 'shutdown', array( $this, 'launch_on_shutdown' ) );
108
+ }
109
+
110
+ //If we have image metadata return it
111
+ if ( ! empty( $data['metadata'] ) ) {
112
+ return $data['metadata'];
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Launch the request on the WordPress shutdown hook
118
+ *
119
+ * On VIP we got into data races due to the postback sometimes completing
120
+ * faster than the data could propogate to the database server cluster.
121
+ * This made WordPress get empty data sets from the database without
122
+ * failing. On their advice, we're moving the actual firing of the async
123
+ * postback to the shutdown hook. Supposedly that will ensure that the
124
+ * data at least has time to get into the object cache.
125
+ *
126
+ * @uses $_COOKIE To send a cookie header for async postback
127
+ * @uses apply_filters()
128
+ * @uses admin_url()
129
+ * @uses wp_remote_post()
130
+ */
131
+ public function launch_on_shutdown() {
132
+ if ( ! empty( $this->_body_data ) ) {
133
+ $cookies = array();
134
+ foreach ( $_COOKIE as $name => $value ) {
135
+ $cookies[] = "$name=" . urlencode( is_array( $value ) ? serialize( $value ) : $value );
136
+ }
137
+
138
+ //@todo: We've set sslverify to false
139
+ $request_args = array(
140
+ 'timeout' => 10,
141
+ 'blocking' => false,
142
+ 'sslverify' => false,
143
+ 'body' => $this->_body_data,
144
+ 'headers' => array(
145
+ 'cookie' => implode( '; ', $cookies ),
146
+ ),
147
+ );
148
+
149
+ $url = admin_url( 'admin-post.php' );
150
+
151
+ wp_remote_post( $url, $request_args );
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Verify the postback is valid, then fire any scheduled events.
157
+ *
158
+ * @uses $_POST['_nonce']
159
+ * @uses is_user_logged_in()
160
+ * @uses add_filter()
161
+ * @uses wp_die()
162
+ */
163
+ public function handle_postback() {
164
+ if ( isset( $_POST['_nonce'] ) && $this->verify_async_nonce( $_POST['_nonce'] ) ) {
165
+ $this->run_action();
166
+ }
167
+
168
+ add_filter( 'wp_die_handler', array( $this, 'handle_die' ) );
169
+ wp_die();
170
+ }
171
+
172
+ /**
173
+ * Handle Die
174
+ */
175
+ function handle_die() {
176
+ die();
177
+ }
178
+
179
+ /**
180
+ * Create a random, one time use token.
181
+ *
182
+ * Based entirely on wp_create_nonce() but does not tie the nonce to the
183
+ * current logged-in user.
184
+ *
185
+ * @uses wp_nonce_tick()
186
+ * @uses wp_hash()
187
+ *
188
+ * @return string The one-time use token
189
+ */
190
+ protected function create_async_nonce() {
191
+ $action = $this->get_nonce_action();
192
+ $i = wp_nonce_tick();
193
+
194
+ return substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 );
195
+ }
196
+
197
+ /**
198
+ * Verify that the correct nonce was used within the time limit.
199
+ *
200
+ * @uses wp_nonce_tick()
201
+ * @uses wp_hash()
202
+ *
203
+ * @param string $nonce Nonce to be verified
204
+ *
205
+ * @return bool Whether the nonce check passed or failed
206
+ */
207
+ protected function verify_async_nonce( $nonce ) {
208
+ $action = $this->get_nonce_action();
209
+ $i = wp_nonce_tick();
210
+
211
+ // Nonce generated 0-12 hours ago
212
+ if ( substr( wp_hash( $i . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
213
+ return 1;
214
+ }
215
+
216
+ // Nonce generated 12-24 hours ago
217
+ if ( substr( wp_hash( ( $i - 1 ) . $action . get_class( $this ), 'nonce' ), - 12, 10 ) == $nonce ) {
218
+ return 2;
219
+ }
220
+
221
+ // Invalid nonce
222
+ return false;
223
+ }
224
+
225
+ /**
226
+ * Get a nonce action based on the $action property of the class
227
+ *
228
+ * @return string The nonce action for the current instance
229
+ */
230
+ protected function get_nonce_action() {
231
+ $action = $this->action;
232
+ if ( substr( $action, 0, 7 ) === 'nopriv_' ) {
233
+ $action = substr( $action, 7 );
234
+ }
235
+ $action = "wp_async_$action";
236
+
237
+ return $action;
238
+ }
239
+
240
+ /**
241
+ * Prepare any data to be passed to the asynchronous postback
242
+ *
243
+ * The array this function receives will be a numerically keyed array from
244
+ * func_get_args(). It is expected that you will return an associative array
245
+ * so that the $_POST values used in the asynchronous call will make sense.
246
+ *
247
+ * The array you send back may or may not have anything to do with the data
248
+ * passed into this method. It all depends on the implementation details and
249
+ * what data is needed in the asynchronous postback.
250
+ *
251
+ * Do not set values for 'action' or '_nonce', as those will get overwritten
252
+ * later in launch().
253
+ *
254
+ * @throws Exception If the postback should not occur for any reason
255
+ *
256
+ * @param array $data The raw data received by the launch method
257
+ *
258
+ * @return array The prepared data
259
+ */
260
+ abstract protected function prepare_data( $data );
261
+
262
+ /**
263
+ * Run the do_action function for the asynchronous postback.
264
+ *
265
+ * This method needs to fetch and sanitize any and all data from the $_POST
266
+ * superglobal and provide them to the do_action call.
267
+ *
268
+ * The action should be constructed as "wp_async_task_$this->action"
269
+ */
270
+ abstract protected function run_action();
271
+
272
+ }
273
+
274
+ }
275
+
readme.txt CHANGED
@@ -1,38 +1,63 @@
1
- === WP Smush ===
2
- Plugin Name: WP Smush
3
- Version: 2.2.1
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.8
10
- Stable tag: 2.2.1
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.
14
 
15
  == Description ==
16
 
17
- <strong>Optimize all of your images</strong> with the <strong>incredibly powerful</strong> and <strong>100% free image smusher</strong>, brought to you by the superteam at WPMU DEV!
 
 
 
 
 
18
 
19
  Our servers do all the heavy lifting. Strip hidden bulky information from your images and reduce file size without losing quality.
20
 
21
  Large image files may be slowing down your site without you even knowing it. WP Smush uses WPMU DEV’s super servers to quickly smush every single one of your images and cuts all the unnecessary data without slowing down your site.
22
 
23
- [youtube https://www.youtube.com/watch?v=Bb905kWPohU&feature=youtu.be]
24
 
25
- Heavy image files may be slowing down your site without you even knowing it. WP Smush meticulously scans every image you upload – or have already added to your site – and cuts all the unnecessary data for you.
26
 
27
  <a href="https://garage.godaddy.com/wordpress-plugin-partner-program/directory/?cvosrc=advocacy.evangelism.WP3" rel="nofollow"><img src="https://garage.godaddy.com/wp-content/uploads/badges/godaddy-plugin-partner-program-badge.svg" title="GoDaddy Plugin Program Partner" alt="GoDaddy Plugin Program Partner"/></a>
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  ★★★★★ <br>
30
  “I had no idea that my page load time was being dragged down by the images. The plugin nearly halved the time it took.” - <a href="http://profiles.wordpress.org/karlcw">karlcw</a>
31
 
32
  ★★★★★ <br>
33
  “I optimize my photos in Photoshop, but Smush makes it so easy – it does it automatically. I can just sit back and enjoy the speed.” - <a href="https://profiles.wordpress.org/helen432">helen432</a>
34
 
35
- WP Smush is super easy to use no confusing compression software settings! Smush images in your library one at a time or bulk smush up to 50 images at a time. Plus, Smush can help keep your site running fast. Use automatic smush and compress every new image upload without thinking about.
 
 
36
 
37
  The faster your site loads, the more Google, Bing, Yahoo and other search engines will like it. Your site will load faster and rank higher.
38
 
@@ -41,37 +66,72 @@ The faster your site loads, the more Google, Bing, Yahoo and other search engine
41
  <br>
42
  <ul>
43
  <li>Optimize your images using advanced lossless compression techniques.</li>
 
44
  <li>Process JPEG, GIF and PNG image files.</li>
45
- <li>Auto-smush your attachments on upload.</li>
 
46
  <li>Manually smush your attachments individually in the media library, or in bulk 50 attachments at a time.</li>
47
  <li>Smush all standard web-sized images 1MB or smaller. </li>
48
- <li>Smush images with no slowdown using WPMU DEV's fast, reliable Smush API.</li>
49
- <li>View advanced compression stats per-attachment and library totals.</li>
 
50
  </ul>
51
 
52
  Install WP Smush now and find out why it's the most popular image optimization plugin for WordPress available today with over 2.7 million downloads.
53
  </blockquote>
54
 
55
- <h4>If you like WP Smush, you'll love <a href="https://premium.wpmudev.org/project/wp-smush-pro/?utm_source=wordpress.org&utm_medium=readme">WP Smush Pro</a></h4>
56
 
57
- WP Smush Pro gives you everything you'll find in WP Smush and more:
58
- <ul>
59
- <li>Super smush your images with our intelligent multi-pass lossy compression. Get from 2x - 10x more compression than lossless with almost no noticeable quality loss!</li>
60
- <li>Get even better lossless compression. We try multiple methods to squeeze every last byte out of your images.</li>
61
- <li>Smush images up to 32MB. Now you can smush any image, even one’s that aren’t web optimized.</li>
62
- <li>Bulk smush ALL your images with one click - no more rate limiting!</li>
63
- <li>Keep a backup of original un-smushed images in case you want to restore later.</li>
64
- <li>24/7/365 support from the best WordPress support team on the planet.</li>
65
- <li>Includes Hummingbird pagespeed booster, Uptime monitoring and security hardening.</li>
66
- <li>100+ other premium plugins, services and themes included in your membership.</li>
67
- </ul>
68
- Upgrade to WP Smush Pro and optimize more and larger image files faster to increase your site’s performance.
 
 
 
 
 
 
 
 
 
 
69
 
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  == Screenshots ==
72
 
73
  1. Watch as your image library is processed – up to 50 images at a time.
74
- 2. Set automatic smush and optomize every image as it is uploaded.
75
  3. Smush will find and optimize images for you.
76
 
77
  == Installation ==
@@ -88,6 +148,204 @@ Yahoo's Smush.it API is gone forever. So WPMU DEV built our own free API that is
88
 
89
  == Changelog ==
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  = 2.2.1 =
92
  * New: Option to resmush image if settings are changed after optimising images
93
  * New: Added an option to preserve EXIF
1
+ === Smush Image Compression and Optimization ===
2
+ Plugin Name: Smush Image Compression and Optimization
3
+ Version: 2.7.4
4
  Author: WPMU DEV
5
  Author URI: http://premium.wpmudev.org/
6
  Contributors: WPMUDEV, alexdunae
7
+ Tags: image, resize, optimize, compress, performance, lossless, lossy, photo, pictures, optimize JPG, compress PNG, Smush WordPress Compression, Smush.it
8
  Requires at least: 3.5
9
  Tested up to: 4.8
10
+ Stable tag: 2.7.4
11
  License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
12
 
13
+ Compress and optimize image files, improve performance and boost your SEO rank using Smush WordPress image compression and optimization.
14
 
15
  == Description ==
16
 
17
+ <strong>Resize, optimize and compress all of your images with the incredibly powerful and 100% free WordPress image smusher, brought to you by the superteam at WPMU DEV!</strong>
18
+
19
+ = Award Winning Image Optimization =
20
+ Smush has been benchmarked and tested number one for speed and quality and is the <a href="https://torquemag.io/2017/04/wp-smush-defeats-wordfence-wins-plugin-madness-2017/">award-winning</a>, proven crowd favorite image optimization plugin for WordPress.
21
+
22
+ Now with image resizing! Set a max width and height and large images will scale down as they are being compressed.
23
 
24
  Our servers do all the heavy lifting. Strip hidden bulky information from your images and reduce file size without losing quality.
25
 
26
  Large image files may be slowing down your site without you even knowing it. WP Smush uses WPMU DEV’s super servers to quickly smush every single one of your images and cuts all the unnecessary data without slowing down your site.
27
 
28
+ [youtube https://www.youtube.com/watch?v=BDtgVJZEajg&feature=youtu.be]
29
 
30
+ WP Smush meticulously scans every image you upload – or have already added to your site – cuts all the unnecessary data and scales it for you before adding it to your media library.
31
 
32
  <a href="https://garage.godaddy.com/wordpress-plugin-partner-program/directory/?cvosrc=advocacy.evangelism.WP3" rel="nofollow"><img src="https://garage.godaddy.com/wp-content/uploads/badges/godaddy-plugin-partner-program-badge.svg" title="GoDaddy Plugin Program Partner" alt="GoDaddy Plugin Program Partner"/></a>
33
 
34
+ = Compress any Image in any Directory =
35
+
36
+ In addition to smushing your media uploads, you may want to compress the images stored in other folders. Smush now lets you compress any image in any directory so that you can optimize all the images on your site – including <a href="https://wordpress.org/plugins/nextgen-gallery/">NextGEN</a> images, images stored on Amazon S3 using <a href="https://wordpress.org/plugins/amazon-s3-and-cloudfront/">WP Offload S3</a> and images in EVERY WordPress plugin and theme package!
37
+
38
+ = Compatible with Your Favorite Media Library Plugins =
39
+
40
+ No matter what plugins you use to better manage your WordPress media library, Smush has you covered. Check out just a few of the plugins Smush is working with to help make your site faster and more efficient:
41
+
42
+ * <a href="https://wordpress.org/plugins/wp-all-import/">WP All Import</a>
43
+ * <a href="https://wordpress.org/plugins/amazon-s3-and-cloudfront/">WP Offload S3</a>
44
+ * <a href="https://www.joomunited.com/wordpress-products/wp-media-folder">WP Media Folder</a>
45
+ * <a href="https://wordpress.org/plugins/wp-retina-2x/">WP Retina 2x</a>
46
+ * <a href="https://wordpress.org/plugins/nextgen-gallery/">NextGen Gallery</a>
47
+ * <a href="https://wpml.org/">WPML</a>
48
+ * <a href="https://wpml.org/2011/05/new-plugin-wpml-media-translation/">WPML Media Translation Add-on</a>
49
+ * <a href="https://wordpress.org/plugins/styles/">Styles</a>
50
+ * And many, many, more!
51
+
52
  ★★★★★ <br>
53
  “I had no idea that my page load time was being dragged down by the images. The plugin nearly halved the time it took.” - <a href="http://profiles.wordpress.org/karlcw">karlcw</a>
54
 
55
  ★★★★★ <br>
56
  “I optimize my photos in Photoshop, but Smush makes it so easy – it does it automatically. I can just sit back and enjoy the speed.” - <a href="https://profiles.wordpress.org/helen432">helen432</a>
57
 
58
+ <strong>What about Multisite?</strong> WP Smush can be used to optimize all the images across your entire network! Use global settings or configure each site individually.
59
+
60
+ WP Smush is super easy to use – no confusing compression software settings! Smush images in your library one at a time or bulk smush up to 50 images at a time. Plus, configure auto-smush to asyncronously scale and compress some or all of your images as they are being uploaded – it's incredibly fast.
61
 
62
  The faster your site loads, the more Google, Bing, Yahoo and other search engines will like it. Your site will load faster and rank higher.
63
 
66
  <br>
67
  <ul>
68
  <li>Optimize your images using advanced lossless compression techniques.</li>
69
+ <li>Set maximum width and height and large images will automatically scale before being added to your media library</li>
70
  <li>Process JPEG, GIF and PNG image files.</li>
71
+ <li>Optimize any image in any directory.</li>
72
+ <li>Asynchronously auto-smush your attachments for super fast compression on upload.</li>
73
  <li>Manually smush your attachments individually in the media library, or in bulk 50 attachments at a time.</li>
74
  <li>Smush all standard web-sized images 1MB or smaller. </li>
75
+ <li>Smush images with no slowdown using WPMU DEV's fast, reliable Smush API.</li>
76
+ <li>Global and individual settings for Multisite </li>
77
+ <li>View advanced compression stats per-attachment and library totals.</li>
78
  </ul>
79
 
80
  Install WP Smush now and find out why it's the most popular image optimization plugin for WordPress available today with over 2.7 million downloads.
81
  </blockquote>
82
 
83
+ Smush can take care of all your image compression needs, for free!
84
 
85
+ However, if you'd like to Super Smush lossy compression, the ability to optimize image up to 32MB, and bulk smush optimization for all your images in just one-click, you can always take the next step with <a href="https://premium.wpmudev.org/project/wp-smush-pro/?utm_source=wordpress.org&utm_medium=readme">WP Smush Pro</a>.
86
+
87
+
88
+ == Frequently Asked Questions ==
89
+
90
+ = I just finished running Smush and Google Pagespeed still says my images need compressing and resizing. How do I fix it? =
91
+
92
+ This means your images were not properly scaled for where they are being displayed. Scaling images before uploading them can be time consuming but can save space and speedup load time. First, determine what size your image needs to be. You can use the built-in developer tools in Chrome or Firefox to find what height and width your image should be. Once you know how large the image should be, scale your images to the right size.
93
+
94
+
95
+ <strong>Tip:</strong> you may not be need to scale each image individually. If the images are in your Media Library, you may be able to fix them with a plugin.
96
+
97
+ = Does Smush delete or replace my original full-size images? =
98
+
99
+ Nope. WordPress crops and resizes every image you upload for embedding on your site. By default, Smush only compresses these cropped and resized images, not your original full-size images. To compress your original full-sized images use <a href="https://premium.wpmudev.org/project/wp-smush-pro/?utm_source=wordpress.org&utm_medium=readme">WP Smush Pro</a>.
100
+
101
+ = What type of file should I use for my images (GIF, PNG, JPG)? =
102
+
103
+ GIF files are large and can’t be optimized much. They should only be used if the image is animated.
104
+
105
+
106
+ PNG is best for computer generated graphics (vectors, logos, fonts, etc.), images with few colors or images with transparency.
107
 
108
 
109
+ JPG should be used for photography or images with a lot of color variation.
110
+
111
+ = I’m a photographer can I keep all my EXIF data? =
112
+
113
+ Yes! EXIF data stores camera settings, focal length, date, time and location information in image files. EXIF data makes image files larger but if you are a photographer you may want to preserve this information. We have included the option to preserve EXIF image data in WP Smush.
114
+
115
+ = I just ran bulk smush and some of my images didn't get compressed? =
116
+
117
+ First, check to see if you're receiving any server errors. If your images seem to be processing correctly check the file size of the images being skipped. Images over 1mb will be skipped. To compress images up to 32mb get <a href="https://premium.wpmudev.org/project/wp-smush-pro/?utm_source=wordpress.org&utm_medium=readme">WP Smush Pro</a>.
118
+
119
+ = I activated Smush and I don’t see any difference in image quality. How am I supposed to know if Smush is working? =
120
+
121
+ Great question! It is important to understand Smush is an optimization tool that uses lossless image compression to save disk storage space and speed up your site. Smush squeezes data from your image files that will save space, resize huge images, and improve speed without changing quality.
122
+
123
+ You can track file size changes in your media library, individual image savings, directory savings, and Smush total savings with Smush stats. If you want to see some additional magic, run before-and-after page-speed tests with WP Checkup or Google PageSpeed Insights. Every little bit of resource savings is important when it comes to page-speed!
124
+
125
+ = Can't I just use Photoshop or another image editing application to optimize my images? =
126
+
127
+ Optimizing all the image sizes generated by WordPress, images being imported from plugins and themes, and images from other web sites is a painful and time consuming process.
128
+
129
+ Smush automatically handles optimizing all your images no matter where they come from and can be used as a standalone tool or alongside Photoshop.
130
+
131
  == Screenshots ==
132
 
133
  1. Watch as your image library is processed – up to 50 images at a time.
134
+ 2. Set automatic smush to resize and optomize every image as it is uploaded.
135
  3. Smush will find and optimize images for you.
136
 
137
  == Installation ==
148
 
149
  == Changelog ==
150
 
151
+ = 2.7.4 =
152
+
153
+ * Update: Minor UI changes
154
+ * Fixed:
155
+ * Images not being resized when image is uploaded via Mobile App
156
+ * Notices and Warnings
157
+ * S3 offload Integration - Original Image not being deleted in some cases
158
+
159
+ = 2.7.3.1 =
160
+
161
+ * Fixed: Pro user unable to login to WPMU DEV Dashboard plugin when Smush is active, Error: "Your key is invalid."
162
+ * Updated: S3 Integration, return URL for any error, 'as3cf_get_attached_file'
163
+
164
+ = 2.7.3 =
165
+
166
+ * Fixed:
167
+ * Manual Smush not working
168
+ * Bulk Smush broken for few sites
169
+
170
+ = 2.7.2 =
171
+
172
+ * Updated:
173
+ * Use JS for stats calculation while using Bulk Smush, to reduce the Ajax time
174
+ * Fixed:
175
+ * Some Images would keep appearing in the re-smush list, if "Resize original images" is enabled
176
+ * Enable buttons in settings redirects to network smush settings page in a subsite if networkwide settings are enabled
177
+
178
+ = 2.7.1 =
179
+
180
+ * Fixed: Progress bar not updating
181
+
182
+ = 2.7 =
183
+
184
+ * Updated:
185
+ * Faster image uploads: Set async request timeout to 0, if you're having trouble with Auto Smush, set timeout using filter `smush_async_time_out`
186
+
187
+ * Fixed:
188
+
189
+ * Issue with WP Smush Pro membership check
190
+ * Stats: Rating message shows incorrect image count
191
+ * Stats: Include directory smush stats in media stats
192
+ * Directory Smush: UI improvement
193
+ * Directory Smush: Allow re-smushing directory images, if the lossy feature is turned on
194
+ * Directory Smush: Fixed empty query warning if there are more than 5k images
195
+ * Site Ground Staging - Disable Async smush for staging sites, admin URL for async request is incorrect because of the Apache module
196
+ * Image appearing in Re-Smush list even after smushing, if resize settings are kept on.
197
+ * Performance: Updated query for smushed images count
198
+ * Added:
199
+ * WP S3 Offload - Plugin Compatibility for Remove files from server feature ( Pro Version )
200
+ * WP RSS Aggregator compatibility for Auto Smush
201
+ * WordPress mobile app Auto smush compatibility
202
+
203
+ = 2.6.3 =
204
+
205
+ * Fixed:
206
+
207
+ * Compatibility issue with WP Defender
208
+ * Image dimensions not updated after resizing in Grid view
209
+
210
+ * Added:
211
+
212
+ * Added a check to preserve smush stats on plugin deletion, You can add `define('WP_SMUSH_PRESERVE_STATS', true );` in wp-config.php
213
+
214
+ = 2.6.2 =
215
+
216
+ * Added:
217
+ * WP All Import Compatibility
218
+
219
+ * Fixed:
220
+ * Image not being updated to S3 after resmush ( *Only if remove files from server is kept off in S3 plugin settings )
221
+ * Added check for directory smush savings
222
+ * Call `wp_update_attachment_metadata` after smushing, to allow the optimised image to be used
223
+ * Dir Smush: Images with special symbols doesn't gets optimised
224
+ * Dir Smush: Skip .bak files
225
+ * Retina Images @2x: Do not smush if auto smush is disabled
226
+ * Backup ( Pro ): Take backup of original untouched image, improved backup and restore.
227
+
228
+ * Updated:
229
+ * Smush Limit ( 50 Images ), do not include images with error in count
230
+
231
+ = 2.6.1 =
232
+
233
+ * Fixed:
234
+ * PHP 5.2 compatibility
235
+ * DB error: Use a smaller value for Path Index size ( Prefix Indexes )
236
+ * Updated translation function name
237
+ * UI/UX fixes for directory smush
238
+ * Improved optimisation process for directory smush
239
+ * Updated uninstall.php
240
+ * Skip sites directory from Directory Smush in a Multisite
241
+
242
+ = 2.6 =
243
+
244
+ * Fixed:
245
+ * PHP 7 warning ( https://goo.gl/GKEMim ), @props: @alexis-mag
246
+ * Async Smush conflict with other plugins
247
+
248
+ * Changes:
249
+ * Moved notice JS/CSS in footer
250
+ * Bulk Smush page optimisation
251
+ * Increased timeout for Async request - Fixes Async smush not working for some hosting services
252
+
253
+ * Added:
254
+ * Directory Smush
255
+
256
+ = 2.5.3 =
257
+
258
+ * Fixed:
259
+ * Show a Smush progress message in Grid view for Auto Smush
260
+ ( A lot of people reported it as Auto Smush not working, which works in background though )
261
+ * Translation domain was incorrect for few strings
262
+ * Translation: Load translation domain in main plugin file
263
+ * Include image size `medium_large` in smush list
264
+ * Error: Cannot use string offset as an array
265
+ * Error in PNG to JPG conversion ( Pro Feature ), added check for mime_content_type function
266
+ * Pro Status not recognised
267
+
268
+ = 2.5.2 =
269
+
270
+ * Added:
271
+ * Filter: `wp_smush_image`, Boolean, Whether to Smush image or not
272
+ * Async Optimisation for Auto Smush on upload ( Set WP_SMUSH_ASYNC to false to turn off async optimisation )
273
+ * Networkwide settings option in a Multisite
274
+
275
+ * Fixed:
276
+ * Double slash in file path causing 403 on some of the sites
277
+ * Localisation error reported by @talgat ( Thank You :) )
278
+
279
+ = 2.4.5 =
280
+
281
+ * Fixed:
282
+ * Error "No file content sent" with WP 4.6
283
+
284
+ = 2.4.4 =
285
+
286
+ * Fixed:
287
+ * PNG to JPEG conversion not working for Multisite
288
+ * Stats Calculation, Use custom query to retrieve data
289
+ * Fixed warning and notices
290
+ * Added check for invalid membership ( Pro Users )
291
+ * thumbnails not being converted for PNG to JPEG conversion
292
+ * Removed option to convert Transparent PNGs to JPEGs ( Pro Users )
293
+
294
+ = 2.4.3 =
295
+
296
+ * Fixed: Image resizing not working on image upload
297
+
298
+ = 2.4.2 =
299
+
300
+ * Fixed: PHP 5.2 compatibility
301
+
302
+ = 2.4.1 =
303
+
304
+ * Fixed: Conflict with Customizer
305
+
306
+ = 2.4 =
307
+
308
+ * Compatibility:
309
+ * WPML Media Add-on compatibility, you can smush all the images for all the languages at once from Bulk Smush page
310
+
311
+ * Features:
312
+ * Added PNG to JPG - Lossy Conversion for higher savings ( Pro Feature )
313
+
314
+ *Fixed:
315
+ * EXIF: Device details were left out for some images, even when opted for stripping it
316
+
317
+ * Updated:
318
+ * Minor Tweaks on WP Smush Page ( Bulk Smush )
319
+ * Stats calculation is more accurate
320
+ * Show current image size and image size dimensions in media library after image has been smushed
321
+ * JPEG optimisation - higher savings for JPEGs lossy optimisation ( Pro Feature )
322
+
323
+ = 2.3.1 =
324
+
325
+ * Fixed:
326
+ * Stats not updated on resizing images
327
+ * CSS conflict in Media Library
328
+
329
+ = 2.3 =
330
+
331
+ * Fixed:
332
+ * Tooltip on image edit page
333
+ * Warning and Notices
334
+ * Updated:
335
+ * Improved stats calculation
336
+ * Bulk Smush page optimised for Image heavy sites
337
+ * Cleanup on uninstall
338
+ * Added:
339
+ * Image Resizing option for Media, NextGen(Pro Only) images
340
+ * Total image count on stats page
341
+
342
+ = 2.2.2 =
343
+
344
+ - Fixed: JS error causing issue with Editor on some installs, plugin conflict with CoursePress plugin, ACF ( Clear All Caches after plugin upgrade, Cloudflare as well )
345
+ - Fixed: ReSmush count for bulk smushing
346
+ - Fixed: Smush settings accessibility for Screen reader/Keyboard
347
+ - Fixed: WP Admin loading slow ( Load smush stats on required admin pages only )
348
+
349
  = 2.2.1 =
350
  * New: Option to resmush image if settings are changed after optimising images
351
  * New: Added an option to preserve EXIF
uninstall.php CHANGED
@@ -10,6 +10,12 @@
10
  if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
11
  exit();
12
  }
 
 
 
 
 
 
13
  global $wpdb;
14
 
15
  $smushit_keys = array(
@@ -17,9 +23,16 @@ $smushit_keys = array(
17
  'original',
18
  'lossy',
19
  'backup',
 
 
 
20
  'nextgen',
21
  'keep_exif',
22
  'resmush-list',
 
 
 
 
23
  'nextgen-resmush-list',
24
  'super_smushed',
25
  'super_smushed_nextgen',
@@ -27,53 +40,113 @@ $smushit_keys = array(
27
  'skip-redirect',
28
  'hide_smush_welcome',
29
  'hide_upgrade_notice',
 
30
  'install-type',
31
- 'lossy-updated'
 
 
 
 
 
32
  );
33
- foreach ( $smushit_keys as $key ) {
34
- $key = 'wp-smush-' . $key;
35
- if ( is_multisite() ) {
36
- $offset = 0;
37
- $limit = 100;
38
- while( $blogs = $wpdb->get_results( "SELECT blog_id FROM {$wpdb->blogs} LIMIT $offset, $limit", ARRAY_A ) ) {
39
- if ( $blogs ) {
40
- foreach ( $blogs as $blog ) {
41
- switch_to_blog( $blog['blog_id'] );
42
- delete_option( $key );
43
- delete_site_option( $key );
44
- }
45
- restore_current_blog();
46
- }
47
- $offset += $limit;
48
- }
49
- } else {
 
 
 
 
 
 
50
  delete_option( $key );
 
 
 
 
 
51
  }
 
 
 
 
 
 
 
 
 
52
  }
 
 
 
 
 
 
 
 
53
  //Delete Post meta
54
  $meta_type = 'post';
55
- $user_id = 0;
56
  $meta_key = 'wp-smpro-smush-data';
57
  $meta_value = '';
58
  $delete_all = true;
59
 
60
  if ( is_multisite() ) {
61
  $offset = 0;
62
- $limit = 100;
63
- while( $blogs = $wpdb->get_results( "SELECT blog_id FROM {$wpdb->blogs} LIMIT $offset, $limit", ARRAY_A ) ) {
64
  if ( $blogs ) {
65
  foreach ( $blogs as $blog ) {
66
  switch_to_blog( $blog['blog_id'] );
67
- delete_metadata( $meta_type, $user_id, $meta_key, $meta_value, $delete_all );
68
- delete_metadata( $meta_type, $user_id, 'wp-smush-lossy', '', $delete_all );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
  restore_current_blog();
71
  }
72
  $offset += $limit;
73
  }
74
  } else {
75
- delete_metadata( $meta_type, $user_id, $meta_key, $meta_value, $delete_all );
76
- delete_metadata( $meta_type, $user_id, 'wp-smush-lossy', '', $delete_all );
 
 
 
77
  }
 
 
 
 
78
  //@todo: Add procedure to delete backup files
79
- ?>
10
  if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
11
  exit();
12
  }
13
+
14
+ //Check if someone want to keep the stats and settings
15
+ if( defined('WP_SMUSH_PRESERVE_STATS') && WP_SMUSH_PRESERVE_STATS ) {
16
+ return;
17
+ }
18
+
19
  global $wpdb;
20
 
21
  $smushit_keys = array(
23
  'original',
24
  'lossy',
25
  'backup',
26
+ 'resize',
27
+ 'png_to_jpg',
28
+ 'resize-sizes',
29
  'nextgen',
30
  'keep_exif',
31
  'resmush-list',
32
+ 'resize_sizes',
33
+ 'transparent_png',
34
+ 'image_sizes',
35
+ 'skip-redirect',
36
  'nextgen-resmush-list',
37
  'super_smushed',
38
  'super_smushed_nextgen',
40
  'skip-redirect',
41
  'hide_smush_welcome',
42
  'hide_upgrade_notice',
43
+ 'hide_update_info',
44
  'install-type',
45
+ 'lossy-updated',
46
+ 'version',
47
+ 'networkwide',
48
+ 'dir_path',
49
+ 'scan',
50
+ 'last_settings'
51
  );
52
+
53
+ //Cache Keys
54
+ $cache_keys = array(
55
+ 'smush_global_stats',
56
+ );
57
+
58
+ $cache_smush_group = array(
59
+ 'exceeding_items',
60
+ 'wp-smush-resize_savings',
61
+ 'pngjpg_savings'
62
+ );
63
+ $cache_nextgen_group = array(
64
+ 'wp_smush_images',
65
+ 'wp_smush_images_smushed',
66
+ 'wp_smush_images_unsmushed',
67
+ 'wp_smush_stats_nextgen',
68
+
69
+ );
70
+
71
+ if ( ! is_multisite() ) {
72
+ //Delete Options
73
+ foreach ( $smushit_keys as $key ) {
74
+ $key = 'wp-smush-' . $key;
75
  delete_option( $key );
76
+ delete_site_option( $key );
77
+ }
78
+ //Delete Cache data
79
+ foreach ( $cache_keys as $key ) {
80
+ wp_cache_delete( $key );
81
  }
82
+
83
+ foreach ( $cache_smush_group as $s_key ) {
84
+ wp_cache_delete( $s_key, 'smush' );
85
+ }
86
+
87
+ foreach ( $cache_nextgen_group as $n_key ) {
88
+ wp_cache_delete( $n_key, 'nextgen' );
89
+ }
90
+
91
  }
92
+
93
+ //Delete Directory Smush stats
94
+ delete_option( 'dir_smush_stats' );
95
+ delete_option( 'wp_smush_scan' );
96
+ delete_option( 'wp_smush_api_auth' );
97
+ delete_option( 'wp_smush_dir_path' );
98
+ delete_site_option( 'wp_smush_api_auth' );
99
+
100
  //Delete Post meta
101
  $meta_type = 'post';
 
102
  $meta_key = 'wp-smpro-smush-data';
103
  $meta_value = '';
104
  $delete_all = true;
105
 
106
  if ( is_multisite() ) {
107
  $offset = 0;
108
+ $limit = 100;
109
+ while ( $blogs = $wpdb->get_results( "SELECT blog_id FROM {$wpdb->blogs} LIMIT $offset, $limit", ARRAY_A ) ) {
110
  if ( $blogs ) {
111
  foreach ( $blogs as $blog ) {
112
  switch_to_blog( $blog['blog_id'] );
113
+ delete_metadata( $meta_type, null, $meta_key, $meta_value, $delete_all );
114
+ delete_metadata( $meta_type, null, 'wp-smush-lossy', '', $delete_all );
115
+ delete_metadata( $meta_type, null, 'wp-smush-resize_savings', '', $delete_all );
116
+ delete_metadata( $meta_type, null, 'wp-smush-original_file', '', $delete_all );
117
+ delete_metadata( $meta_type, null, 'wp-smush-pngjpg_savings', '', $delete_all );
118
+ foreach ( $smushit_keys as $key ) {
119
+ $key = 'wp-smush-' . $key;
120
+ delete_option( $key );
121
+ delete_site_option( $key );
122
+ }
123
+ //Delete Cache data
124
+ foreach ( $cache_keys as $key ) {
125
+ wp_cache_delete( $key );
126
+ }
127
+
128
+ foreach ( $cache_smush_group as $s_key ) {
129
+ wp_cache_delete( $s_key, 'smush' );
130
+ }
131
+
132
+ foreach ( $cache_nextgen_group as $n_key ) {
133
+ wp_cache_delete( $n_key, 'nextgen' );
134
+ }
135
  }
136
  restore_current_blog();
137
  }
138
  $offset += $limit;
139
  }
140
  } else {
141
+ delete_metadata( $meta_type, null, $meta_key, $meta_value, $delete_all );
142
+ delete_metadata( $meta_type, null, 'wp-smush-lossy', '', $delete_all );
143
+ delete_metadata( $meta_type, null, 'wp-smush-resize_savings', '', $delete_all );
144
+ delete_metadata( $meta_type, null, 'wp-smush-original_file', '', $delete_all );
145
+ delete_metadata( $meta_type, null, 'wp-smush-pngjpg_savings', '', $delete_all );
146
  }
147
+ //Delete Directory smush table
148
+ global $wpdb;
149
+ $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}smush_dir_images" );
150
+
151
  //@todo: Add procedure to delete backup files
152
+ //@todo: Update NextGen Metadata to remove Smush stats on plugin deletion
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.2.1
8
  Author URI: http://premium.wpmudev.org/
9
- Textdomain: wp-smushit
10
  */
11
 
12
  /*
@@ -35,13 +35,35 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35
  * Constants
36
  */
37
  $prefix = 'WP_SMUSH_';
38
- $version = '2.2.1';
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  /**
41
  * Set the default timeout for API request and AJAX timeout
42
  */
43
  $timeout = apply_filters( 'WP_SMUSH_API_TIMEOUT', 90 );
44
 
 
 
 
 
 
 
 
 
 
45
  $smush_constants = array(
46
  'VERSION' => $version,
47
  'BASENAME' => plugin_basename( __FILE__ ),
@@ -52,7 +74,9 @@ $smush_constants = array(
52
  'MAX_BYTES' => 1000000,
53
  'PREMIUM_MAX_BYTES' => 32000000,
54
  'PREFIX' => 'wp-smush-',
55
- 'TIMEOUT' => $timeout
 
 
56
  );
57
 
58
  foreach ( $smush_constants as $const_name => $constant_val ) {
@@ -73,9 +97,11 @@ require_once WP_SMUSH_DIR . 'lib/class-wp-smush.php';
73
  */
74
  if ( ! function_exists( 'wp_smush_rating_message' ) ) {
75
  function wp_smush_rating_message( $message ) {
76
- global $wpsmushit_admin;
77
- $savings = $wpsmushit_admin->global_stats();
78
- $image_count = $wpsmushit_admin->total_count();
 
 
79
  $show_stats = false;
80
 
81
  //If there is any saving, greater than 1Mb, show stats
@@ -87,7 +113,7 @@ if ( ! function_exists( 'wp_smush_rating_message' ) ) {
87
 
88
  //Conditionally Show stats in rating message
89
  if ( $show_stats ) {
90
- $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 );
91
  }
92
  $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!";
93
 
@@ -109,10 +135,23 @@ if ( ! function_exists( 'wp_smush_email_message' ) ) {
109
  return $message;
110
  }
111
  }
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
  if ( is_admin() ) {
114
 
115
- $dir_path = plugin_dir_path( __FILE__ );
 
116
  //Only for wordpress.org members
117
  if ( strpos( $dir_path, 'wp-smushit' ) !== false ) {
118
  require_once( WP_SMUSH_DIR . 'extras/free-dashboard/module.php' );
@@ -154,23 +193,12 @@ if ( is_admin() ) {
154
  'id' => 912164,
155
  'name' => 'WP Smush Pro',
156
  'screens' => array(
157
- 'upload'
 
158
  )
159
  );
160
  }
161
  }
162
- //Deactivate the .org version, if pro version is active
163
- add_action( 'admin_init', 'deactivate_smush_org' );
164
-
165
- if ( ! function_exists( 'deactivate_smush_org' ) ) {
166
- function deactivate_smush_org() {
167
- if ( is_plugin_active( 'wp-smush-pro/wp-smush.php' ) && is_plugin_active( 'wp-smushit/wp-smush.php' ) ) {
168
- deactivate_plugins( 'wp-smushit/wp-smush.php' );
169
- //Store in database, in order to show a notice on page load
170
- update_option( 'smush_deactivated', 1 );
171
- }
172
- }
173
- }
174
 
175
  //Show the required notice
176
  add_action( 'network_admin_notices', 'smush_deactivated' );
@@ -178,11 +206,90 @@ add_action( 'admin_notices', 'smush_deactivated' );
178
  //Display a admin Notice about plugin deactivation
179
  if ( ! function_exists( 'smush_deactivated' ) ) {
180
  function smush_deactivated() {
181
- if ( get_option( 'smush_deactivated' ) && is_admin() ) { ?>
182
  <div class="updated">
183
  <p><?php esc_html_e( 'WP Smush Free was deactivated. You have WP Smush Pro active!', 'wp-smushit' ); ?></p>
184
  </div> <?php
185
- delete_option( 'smush_deactivated' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  }
 
 
187
  }
188
- }
 
 
 
 
 
 
 
 
 
 
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.7.4
8
  Author URI: http://premium.wpmudev.org/
9
+ Text Domain: wp-smushit
10
  */
11
 
12
  /*
35
  * Constants
36
  */
37
  $prefix = 'WP_SMUSH_';
38
+ $version = '2.7.4';
39
+
40
+ //Deactivate the .org version, if pro version is active
41
+ add_action( 'admin_init', 'deactivate_smush_org' );
42
+
43
+ if ( ! function_exists( 'deactivate_smush_org' ) ) {
44
+ function deactivate_smush_org() {
45
+ if ( is_plugin_active( 'wp-smush-pro/wp-smush.php' ) && is_plugin_active( 'wp-smushit/wp-smush.php' ) ) {
46
+ deactivate_plugins( 'wp-smushit/wp-smush.php' );
47
+ //Store in database, in order to show a notice on page load
48
+ update_site_option( 'smush_deactivated', 1 );
49
+ }
50
+ }
51
+ }
52
 
53
  /**
54
  * Set the default timeout for API request and AJAX timeout
55
  */
56
  $timeout = apply_filters( 'WP_SMUSH_API_TIMEOUT', 90 );
57
 
58
+ // To support smushing on staging sites like SiteGround staging where
59
+ // staging site urls are different but redirects to main site url.
60
+ // Remove the protocols and www, and get the domain name.
61
+ $site_url = str_replace( array( 'http://', 'https://', 'www.' ), '', site_url() );
62
+ // If current site's url is different from site_url, disable Async.
63
+ if ( ! empty( $_SERVER['SERVER_NAME'] ) && ( 0 !== strpos( $_SERVER['SERVER_NAME'], $site_url ) ) && ! defined( $prefix . 'ASYNC' ) ) {
64
+ define( $prefix . 'ASYNC', false );
65
+ }
66
+
67
  $smush_constants = array(
68
  'VERSION' => $version,
69
  'BASENAME' => plugin_basename( __FILE__ ),
74
  'MAX_BYTES' => 1000000,
75
  'PREMIUM_MAX_BYTES' => 32000000,
76
  'PREFIX' => 'wp-smush-',
77
+ 'TIMEOUT' => $timeout,
78
+ //If Set to false, WP Smush switch backs to the Old Sync Optimisation
79
+ 'ASYNC' => true
80
  );
81
 
82
  foreach ( $smush_constants as $const_name => $constant_val ) {
97
  */
98
  if ( ! function_exists( 'wp_smush_rating_message' ) ) {
99
  function wp_smush_rating_message( $message ) {
100
+ global $wpsmushit_admin, $wpsmush_db;
101
+ if ( empty( $wpsmushit_admin->stats ) ) {
102
+ $wpsmushit_admin->setup_global_stats();
103
+ }
104
+ $savings = $wpsmushit_admin->stats;
105
  $show_stats = false;
106
 
107
  //If there is any saving, greater than 1Mb, show stats
113
 
114
  //Conditionally Show stats in rating message
115
  if ( $show_stats ) {
116
+ $message .= sprintf( " You've smushed <strong>%s</strong> from %d images already, improving the speed and SEO ranking of this site!", $savings['human'], $savings['total_images'] );
117
  }
118
  $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!";
119
 
135
  return $message;
136
  }
137
  }
138
+ if ( ! function_exists( 'get_plugin_dir' ) ) {
139
+ /**
140
+ * Returns the dir path for the plugin
141
+ *
142
+ * @return string
143
+ */
144
+ function get_plugin_dir() {
145
+ $dir_path = plugin_dir_path( __FILE__ );
146
+
147
+ return $dir_path;
148
+ }
149
+ }
150
 
151
  if ( is_admin() ) {
152
 
153
+ $dir_path = get_plugin_dir();
154
+
155
  //Only for wordpress.org members
156
  if ( strpos( $dir_path, 'wp-smushit' ) !== false ) {
157
  require_once( WP_SMUSH_DIR . 'extras/free-dashboard/module.php' );
193
  'id' => 912164,
194
  'name' => 'WP Smush Pro',
195
  'screens' => array(
196
+ 'upload',
197
+ 'media_page_wp-smush-bulk'
198
  )
199
  );
200
  }
201
  }
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  //Show the required notice
204
  add_action( 'network_admin_notices', 'smush_deactivated' );
206
  //Display a admin Notice about plugin deactivation
207
  if ( ! function_exists( 'smush_deactivated' ) ) {
208
  function smush_deactivated() {
209
+ if ( get_site_option( 'smush_deactivated' ) && is_super_admin() ) { ?>
210
  <div class="updated">
211
  <p><?php esc_html_e( 'WP Smush Free was deactivated. You have WP Smush Pro active!', 'wp-smushit' ); ?></p>
212
  </div> <?php
213
+ delete_site_option( 'smush_deactivated' );
214
+ }
215
+ }
216
+ }
217
+
218
+ if ( ! function_exists( 'smush_activated' ) ) {
219
+ //Check if a existing install or new
220
+ function smush_activated() {
221
+
222
+ $version = get_site_option( WP_SMUSH_PREFIX . 'version' );
223
+
224
+ //If the version is not saved or if the version is not same as the current version,
225
+ if ( ! $version || WP_SMUSH_VERSION != $version ) {
226
+ global $wpdb;
227
+ //Check if there are any existing smush stats
228
+ $query = "SELECT meta_id FROM {$wpdb->postmeta} WHERE meta_key=%s LIMIT 1";
229
+ $results = $wpdb->get_var( $wpdb->prepare( $query, 'wp-smpro-smush-data' ) );
230
+
231
+ if ( $results ) {
232
+ update_site_option( 'wp-smush-install-type', 'existing' );
233
+ } else {
234
+ //Check for existing settings
235
+ if ( false !== get_site_option( WP_SMUSH_PREFIX . 'auto' ) || false !== get_option( WP_SMUSH_PREFIX . 'auto' ) ) {
236
+ update_site_option( 'wp-smush-install-type', 'existing' );
237
+ }
238
+ }
239
+
240
+ //Store the plugin version in db
241
+ update_site_option( WP_SMUSH_PREFIX . 'version', WP_SMUSH_VERSION );
242
+ }
243
+
244
+ }
245
+ }
246
+
247
+
248
+ if ( ! function_exists( 'smush_sanitize_hex_color' ) ) {
249
+ /**
250
+ * Sanitizes a hex color.
251
+ *
252
+ * @param $color
253
+ *
254
+ * @return string Returns either '', a 3 or 6 digit hex color (with #), or nothing
255
+ */
256
+ function smush_sanitize_hex_color( $color ) {
257
+ if ( '' === $color ) {
258
+ return '';
259
+ }
260
+
261
+ // 3 or 6 hex digits, or the empty string.
262
+ if ( preg_match( '|^#([A-Fa-f0-9]{3}){1,2}$|', $color ) ) {
263
+ return $color;
264
+ }
265
+ }
266
+ }
267
+
268
+ if ( ! function_exists( 'smush_sanitize_hex_color_no_hash' ) ) {
269
+ /**
270
+ * Sanitizes a hex color without hash
271
+ *
272
+ * @param $color
273
+ *
274
+ * @return string Returns either '', a 3 or 6 digit hex color (with #), or nothing
275
+ */
276
+ function smush_sanitize_hex_color_no_hash( $color ) {
277
+ $color = ltrim( $color, '#' );
278
+
279
+ if ( '' === $color ) {
280
+ return '';
281
  }
282
+
283
+ return smush_sanitize_hex_color( '#' . $color ) ? $color : null;
284
  }
285
+ }
286
+ //Load Translation files
287
+ add_action( 'plugins_loaded', 'smush_i18n' );
288
+ if( !function_exists('smush_i18n')) {
289
+ function smush_i18n() {
290
+ $path = path_join( dirname( plugin_basename( __FILE__ ) ), 'languages/' );
291
+ load_plugin_textdomain( 'wp-smushit', false, $path );
292
+ }
293
+ }
294
+
295
+ register_activation_hook( __FILE__, 'smush_activated' );