Version Description
- Ability to disable optimization of main image, allowing faster uploads from Media Library. You can optimize the main image later from within your Media Library.
- Ability to restrict the maximum dimensions of image uploads (resizing), by width and/or height.
- When using resize feature, resized images are enhanced for sharper results using various advanced techniques.
- Ability to force JPEG quality to a discrete "quality" value, for greater savings if you know what you're doing.
- Ability to preserve certain EXIF metadata tags, including Date, Copyright, Orientation, Geotag and Profile.
- Ability to automatically orient images according to their Orientation EXIF metadata.
- Improvements and simplifications to interface elements and Kraken.io Settings page.
Download this release
Release Info
Developer | karim79 |
Plugin | Kraken.io Image Optimizer |
Version | 2.5.0 |
Comparing to | |
See all releases |
Code changes from version 2.0.0 to 2.5.0
- css/admin.css +154 -25
- css/dist/kraken.min.css +1 -1
- js/ajax.js +114 -84
- js/dist/kraken.min.js +2 -3
- kraken.php +625 -172
- lib/Kraken.php +40 -45
- readme.txt +19 -12
css/admin.css
CHANGED
@@ -34,26 +34,46 @@
|
|
34 |
float: left;
|
35 |
clear: left;
|
36 |
}
|
|
|
37 |
.kraken_req, .kraken_req_bulk {
|
38 |
-
border:
|
39 |
-
color: #
|
40 |
padding: 3px 8px 4px;
|
41 |
font-size: 11px;
|
42 |
-
|
43 |
-
background: #ffc942;
|
44 |
-
background-image: -webkit-gradient(linear,left top,left bottom,from(#ffc942),to(#efab00));
|
45 |
-
background-image: -webkit-linear-gradient(top,#ffc942,#efab00);
|
46 |
-
background-image: -moz-linear-gradient(top,#ffc942,#efab00);
|
47 |
-
background-image: -o-linear-gradient(top,#ffc942,#efab00);
|
48 |
-
background-image: linear-gradient(to bottom,#ffc942,#efab00);
|
49 |
-webkit-border-radius: 2px;
|
50 |
-moz-border-radius: 2px;
|
51 |
border-radius: 2px;
|
52 |
cursor: pointer;
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
|
|
|
|
|
|
|
|
|
|
55 |
.kraken_req_bulk {
|
56 |
font-size: 16px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
}
|
58 |
.buttonWrap {
|
59 |
position: relative;
|
@@ -115,27 +135,65 @@ p.apiStatus {
|
|
115 |
font-size: 16px;
|
116 |
margin-bottom: 10px;
|
117 |
font-weight: bold;
|
|
|
|
|
|
|
|
|
|
|
118 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
#kraken-bulk-modal {
|
120 |
position: absolute !important;
|
121 |
-
top: 100px;
|
122 |
width: 785px;
|
|
|
123 |
}
|
124 |
#kraken-bulk-modal label {
|
125 |
margin-bottom: 11px;
|
126 |
}
|
|
|
127 |
#kraken-bulk {
|
128 |
-
width:
|
129 |
-
margin: 0 auto;
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
133 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
.kraken-bulk-header td {
|
135 |
font-weight: bold;
|
136 |
-
font-size:
|
137 |
-
padding:
|
|
|
|
|
|
|
138 |
}
|
|
|
139 |
td.kraken-krakedsize {
|
140 |
text-align: left;
|
141 |
}
|
@@ -156,10 +214,25 @@ span.kraken-bulk-choose-type {
|
|
156 |
font-weight: bold;
|
157 |
cursor: pointer;
|
158 |
}
|
|
|
159 |
.radiosWrap {
|
160 |
-
|
161 |
-
|
|
|
|
|
162 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
.kraken-bulk-small {
|
164 |
font-size: 12px;
|
165 |
display: inline-block;
|
@@ -177,7 +250,7 @@ small.krakenReset {
|
|
177 |
width: 10px;
|
178 |
height: 10px;
|
179 |
background: url('https://kraken-nekkraug.netdna-ssl.com/assets/images/spinner.gif') no-repeat 0 0;
|
180 |
-
background-size: 10px;
|
181 |
}
|
182 |
h1.kraken-admin-section-title {
|
183 |
margin-bottom: 30px;
|
@@ -196,11 +269,11 @@ span.kraken-reset-all.enabled {
|
|
196 |
cursor: pointer;
|
197 |
}
|
198 |
td.krakenAdvancedSettings {
|
199 |
-
padding: 0;
|
200 |
}
|
201 |
td.krakenAdvancedSettingsDescription {
|
202 |
padding: 0;
|
203 |
-
padding
|
204 |
}
|
205 |
td.krakenAdvancedSettings h3 {
|
206 |
margin-bottom: 2px;
|
@@ -230,14 +303,70 @@ td.krakenAdvancedSettings h3 span.kraken-advanced-toggle {
|
|
230 |
user-select: none;
|
231 |
}
|
232 |
.kraken-advanced-settings {
|
233 |
-
display: none
|
234 |
}
|
235 |
#krakenSettings .form-table {
|
236 |
margin-bottom: 30px;
|
237 |
}
|
|
|
238 |
#krakenSettings .form-table th {
|
239 |
-
width:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
.kraken.error.settings-error, .kraken.updated.settings-error {
|
242 |
margin-bottom: 30px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
}
|
34 |
float: left;
|
35 |
clear: left;
|
36 |
}
|
37 |
+
|
38 |
.kraken_req, .kraken_req_bulk {
|
39 |
+
border: none;
|
40 |
+
color: #fff;
|
41 |
padding: 3px 8px 4px;
|
42 |
font-size: 11px;
|
43 |
+
background: #3498DB;
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
-webkit-border-radius: 2px;
|
45 |
-moz-border-radius: 2px;
|
46 |
border-radius: 2px;
|
47 |
cursor: pointer;
|
48 |
+
transition: all 0.15s;
|
49 |
+
}
|
50 |
+
|
51 |
+
.kraken_req:hover,
|
52 |
+
.kraken_req_bulk:hover {
|
53 |
+
background: #2881BD;
|
54 |
}
|
55 |
+
|
56 |
+
.kraken_req {
|
57 |
+
margin-right: 2px;
|
58 |
+
}
|
59 |
+
|
60 |
.kraken_req_bulk {
|
61 |
font-size: 16px;
|
62 |
+
margin: 0 auto;
|
63 |
+
width: 150px;
|
64 |
+
padding: 10px 0;
|
65 |
+
display: block;
|
66 |
+
}
|
67 |
+
|
68 |
+
td.kraken-bulk-filename {
|
69 |
+
width: 360px;
|
70 |
+
max-width: 360px;
|
71 |
+
overflow: hidden;
|
72 |
+
text-overflow: ellipsis;
|
73 |
+
white-space: nowrap;
|
74 |
+
}
|
75 |
+
td.kraken-krakedsize {
|
76 |
+
width: 170px;
|
77 |
}
|
78 |
.buttonWrap {
|
79 |
position: relative;
|
135 |
font-size: 16px;
|
136 |
margin-bottom: 10px;
|
137 |
font-weight: bold;
|
138 |
+
padding: 15px 20px;
|
139 |
+
border-bottom: 1px solid #ddd;
|
140 |
+
margin: 0;
|
141 |
+
background: #fafafa;
|
142 |
+
position: relative;
|
143 |
}
|
144 |
+
|
145 |
+
.krakenBulkHeader span {
|
146 |
+
position: absolute;
|
147 |
+
top: 5px;
|
148 |
+
right: 15px;
|
149 |
+
font-size: 30px;
|
150 |
+
color: #777;
|
151 |
+
}
|
152 |
+
|
153 |
+
.krakenBulkHeader span:hover {
|
154 |
+
color: #222;
|
155 |
+
}
|
156 |
+
|
157 |
#kraken-bulk-modal {
|
158 |
position: absolute !important;
|
159 |
+
top: 100px;
|
160 |
width: 785px;
|
161 |
+
padding: 0 0 20px 0;
|
162 |
}
|
163 |
#kraken-bulk-modal label {
|
164 |
margin-bottom: 11px;
|
165 |
}
|
166 |
+
|
167 |
#kraken-bulk {
|
168 |
+
width: 770px;
|
169 |
+
margin: 0 auto 20px;
|
170 |
+
border-collapse: collapse;
|
171 |
+
}
|
172 |
+
|
173 |
+
#kraken-bulk td {
|
174 |
+
border: 1px solid #ddd;
|
175 |
+
padding: 5px 10px;
|
176 |
}
|
177 |
+
|
178 |
+
#kraken-bulk tr:nth-child(odd) {
|
179 |
+
background-color: #eee;
|
180 |
+
}
|
181 |
+
|
182 |
+
#kraken-bulk-modal .the-following {
|
183 |
+
margin: 0;
|
184 |
+
text-align: center;
|
185 |
+
padding: 15px 0;
|
186 |
+
}
|
187 |
+
|
188 |
.kraken-bulk-header td {
|
189 |
font-weight: bold;
|
190 |
+
font-size: 13px;
|
191 |
+
padding: 7px 10px !important;
|
192 |
+
background: #ddd;
|
193 |
+
color: #212121;
|
194 |
+
border: 1px solid #ccc !important;
|
195 |
}
|
196 |
+
|
197 |
td.kraken-krakedsize {
|
198 |
text-align: left;
|
199 |
}
|
214 |
font-weight: bold;
|
215 |
cursor: pointer;
|
216 |
}
|
217 |
+
|
218 |
.radiosWrap {
|
219 |
+
width: 100%;
|
220 |
+
text-align: center;
|
221 |
+
padding: 15px 0;
|
222 |
+
border-bottom: 1px solid #ddd;
|
223 |
}
|
224 |
+
|
225 |
+
.radiosWrap p {
|
226 |
+
padding: 0;
|
227 |
+
margin: 0 0 5px 0;
|
228 |
+
font-weight: bold;
|
229 |
+
}
|
230 |
+
|
231 |
+
.radiosWrap input[type="radio"] {
|
232 |
+
margin-top: -1px;
|
233 |
+
vertical-align: middle;
|
234 |
+
}
|
235 |
+
|
236 |
.kraken-bulk-small {
|
237 |
font-size: 12px;
|
238 |
display: inline-block;
|
250 |
width: 10px;
|
251 |
height: 10px;
|
252 |
background: url('https://kraken-nekkraug.netdna-ssl.com/assets/images/spinner.gif') no-repeat 0 0;
|
253 |
+
background-size: 10px;
|
254 |
}
|
255 |
h1.kraken-admin-section-title {
|
256 |
margin-bottom: 30px;
|
269 |
cursor: pointer;
|
270 |
}
|
271 |
td.krakenAdvancedSettings {
|
272 |
+
padding: 20px 0 0 0 !important;
|
273 |
}
|
274 |
td.krakenAdvancedSettingsDescription {
|
275 |
padding: 0;
|
276 |
+
padding: 10px 0 !important;
|
277 |
}
|
278 |
td.krakenAdvancedSettings h3 {
|
279 |
margin-bottom: 2px;
|
303 |
user-select: none;
|
304 |
}
|
305 |
.kraken-advanced-settings {
|
306 |
+
/*display: none;*/
|
307 |
}
|
308 |
#krakenSettings .form-table {
|
309 |
margin-bottom: 30px;
|
310 |
}
|
311 |
+
|
312 |
#krakenSettings .form-table th {
|
313 |
+
width: 270px;
|
314 |
+
border-bottom: 1px solid #ddd;
|
315 |
+
padding: 25px 0;
|
316 |
+
}
|
317 |
+
|
318 |
+
#krakenSettings .form-table td {
|
319 |
+
border-bottom: 1px solid #ddd;
|
320 |
+
padding: 25px 0;
|
321 |
+
}
|
322 |
+
|
323 |
+
#krakenSettings .form-table .no-border td,
|
324 |
+
#krakenSettings .form-table .no-border th {
|
325 |
+
border: none;
|
326 |
+
}
|
327 |
+
|
328 |
+
#krakenSettings .form-table .with-tip td,
|
329 |
+
#krakenSettings .form-table .with-tip th {
|
330 |
+
border-bottom: none;
|
331 |
+
padding-bottom: 10px;
|
332 |
+
}
|
333 |
+
|
334 |
+
.tip td {
|
335 |
+
padding: 10px 0 20px 0 !important;
|
336 |
}
|
337 |
+
|
338 |
+
.tip td div {
|
339 |
+
border: 1px solid #BCE8F1;
|
340 |
+
background: #D9EDF7;
|
341 |
+
padding: 5px 10px;
|
342 |
+
line-height: 20px;
|
343 |
+
font-size: 12px;
|
344 |
+
}
|
345 |
+
|
346 |
.kraken.error.settings-error, .kraken.updated.settings-error {
|
347 |
margin-bottom: 30px;
|
348 |
+
}
|
349 |
+
.blog-kraker-info-block-wrap {
|
350 |
+
margin-top: 10px;
|
351 |
+
margin-left: 10px;
|
352 |
+
padding-bottom: 110px;
|
353 |
+
width: 600px;
|
354 |
+
}
|
355 |
+
.blog-kraker-image-summary {
|
356 |
+
width: 50%;
|
357 |
+
float: left;
|
358 |
+
}
|
359 |
+
.blog-kraker-kraken-statistics {
|
360 |
+
width: 50%;
|
361 |
+
float: right;
|
362 |
+
}
|
363 |
+
input[name=blog_kraker_mode] {
|
364 |
+
margin-right: 10px;
|
365 |
+
}
|
366 |
+
label[for=blog_kraker_mode_thumbs] {
|
367 |
+
margin-right: 10px;
|
368 |
+
}
|
369 |
+
.kraken-item-details {
|
370 |
+
cursor: pointer;
|
371 |
+
text-decoration: underline;
|
372 |
}
|
css/dist/kraken.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.tipsy-ne .tipsy-arrow,.tipsy-nw .tipsy-arrow{border-top:none;top:0;border-bottom-style:solid}.
|
1 |
+
.tipsy-ne .tipsy-arrow,.tipsy-nw .tipsy-arrow{border-top:none;top:0;border-bottom-style:solid}.kraken-plus-minus,td.krakenAdvancedSettings h3>.kraken-advanced-settings-label:hover{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-khtml-user-select:none}.kraken-modal{display:none;width:600px;background:#fff;padding:15px 30px;border-radius:8px;-webkit-box-shadow:0 0 10px #000;-moz-box-shadow:0 0 10px #000;-o-box-shadow:0 0 10px #000;-ms-box-shadow:0 0 10px #000;box-shadow:0 0 10px #000}.kraken-modal,.kraken-modal-spinner{-o-border-radius:8px;-ms-border-radius:8px;-webkit-border-radius:8px;-moz-border-radius:8px}.kraken-modal-spinner{display:none;width:64px;height:64px;position:fixed;top:50%;left:50%;margin-right:-32px;margin-top:-32px;background:url(spinner.gif)center center no-repeat #111;border-radius:8px}.tipsy{font-size:10px;position:absolute;padding:5px;z-index:100000}.tipsy-inner{background-color:#000;color:#FFF;max-width:300px;padding:5px 8px 4px;text-align:left;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;box-shadow:0 0 5px #000;-webkit-box-shadow:0 0 5px #000;-moz-box-shadow:0 0 5px #000}.head_cell,.head_file_name,.item_file_name{height:20px;padding-top:5px}.tipsy-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.tipsy-arrow-n{border-bottom-color:#000}.tipsy-arrow-s{border-top-color:#000}.tipsy-arrow-e{border-left-color:#000}.tipsy-n .tipsy-arrow,.tipsy-ne .tipsy-arrow,.tipsy-nw .tipsy-arrow,.tipsy-s .tipsy-arrow,.tipsy-se .tipsy-arrow,.tipsy-sw .tipsy-arrow{border-left-color:transparent}.tipsy-arrow-w{border-right-color:#000}.tipsy-n .tipsy-arrow,.tipsy-ne .tipsy-arrow,.tipsy-nw .tipsy-arrow,.tipsy-s .tipsy-arrow,.tipsy-se .tipsy-arrow,.tipsy-sw .tipsy-arrow{border-right-color:transparent}.tipsy-n .tipsy-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none}.tipsy-nw .tipsy-arrow{left:10px}.tipsy-ne .tipsy-arrow{right:10px}.tipsy-s .tipsy-arrow,.tipsy-se .tipsy-arrow,.tipsy-sw .tipsy-arrow{border-bottom:none;border-top-style:solid}.tipsy-e .tipsy-arrow,.tipsy-w .tipsy-arrow{border-bottom-color:transparent;top:50%;border-top-color:transparent}.tipsy-s .tipsy-arrow{bottom:0;left:50%;margin-left:-5px}.tipsy-sw .tipsy-arrow{bottom:0;left:10px}.tipsy-se .tipsy-arrow{bottom:0;right:10px}.tipsy-e .tipsy-arrow{right:0;margin-top:-5px;border-left-style:solid;border-right:none}.tipsy-w .tipsy-arrow{left:0;margin-top:-5px;border-right-style:solid;border-left:none}.item_cell,.item_file_name{background-color:#F8F8F8;margin-top:5px}.head_cell{float:left;width:10em;background-color:#F0F0F0}.head_file_name{float:left;width:30em;background-color:#F0F0F0;padding-left:2px}.item_cell{float:left;width:10em;height:20px;padding-top:5px}.item_file_name{float:left;width:30em;padding-left:2px}#kraken_loading{float:left;clear:left}.kraken_req,.kraken_req_bulk{border:none;color:#fff;padding:3px 8px 4px;font-size:11px;background:#3498DB;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;cursor:pointer;transition:all .15s}.kraken_req:hover,.kraken_req_bulk:hover{background:#2881BD}.krakenBulkSpinner,.krakenSpinner{background:url(https://kraken-nekkraug.netdna-ssl.com/assets/images/spinner.gif)no-repeat}.kraken_req{margin-right:2px}.kraken_req_bulk{font-size:16px;margin:0 auto;width:150px;padding:10px 0;display:block}td.kraken-bulk-filename{width:360px;max-width:360px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}td.kraken-krakedsize{width:170px}.apiInvalid,.apiValid{position:absolute;width:16px}.buttonWrap{position:relative;margin-bottom:5px}.apiValid{left:0;display:inline-block;height:16px;top:3px}.apiInvalid{left:0;display:inline-block;height:16px;top:2px}p.apiStatus{padding-left:26px;position:relative;width:400px}.krakenSpinner{display:none;position:absolute;width:16px;height:16px;top:5px}.krakenBulkSpinner{display:none;padding:0;margin:0;width:16px;height:16px}.krakenError,.noSavings{margin-left:2px}.kraken-bulk-small,.kraken-plus-minus,.resetSpinner,.visible{display:inline-block}.krakenErrorWrap{margin-top:10px;margin-bottom:4px}.krakenError{font-weight:700;color:#dd3d36}.krakenBulkHeader{font-size:16px;font-weight:700;padding:15px 20px;border-bottom:1px solid #ddd;margin:0;background:#fafafa;position:relative}.krakenBulkHeader span{position:absolute;top:5px;right:15px;font-size:30px;color:#777}.krakenBulkHeader span:hover{color:#222}#kraken-bulk-modal{position:absolute!important;top:100px;width:785px;padding:0 0 20px}#kraken-bulk-modal label{margin-bottom:11px}#kraken-bulk{width:770px;margin:0 auto 20px;border-collapse:collapse}#kraken-bulk td{border:1px solid #ddd;padding:5px 10px}#kraken-bulk tr:nth-child(odd){background-color:#eee}#kraken-bulk-modal .the-following{margin:0;text-align:center;padding:15px 0}.kraken-bulk-header td{font-weight:700;font-size:13px;padding:7px 10px!important;background:#ddd;color:#212121;border:1px solid #ccc!important}td.kraken-krakedsize{text-align:left}tr.kraken-item-row td{padding:2px;height:20px}span.kraken-bulk-choose-type{font-weight:700;margin-right:5px}#kraken-bulk-type-lossy{margin-right:5px}.close-kraken-bulk{font-size:12px;margin-left:10px;font-weight:700;cursor:pointer}.radiosWrap{width:100%;text-align:center;padding:15px 0;border-bottom:1px solid #ddd}.radiosWrap p{padding:0;margin:0 0 5px;font-weight:700}.radiosWrap input[type=radio]{margin-top:-1px;vertical-align:middle}.kraken-bulk-small{font-size:12px;margin:0 0 4px 4px}small.krakenReset{text-decoration:underline;cursor:pointer}.resetSpinner{margin-right:3px;margin-top:4px;vertical-align:baseline;width:10px;height:10px;background:url(https://kraken-nekkraug.netdna-ssl.com/assets/images/spinner.gif)no-repeat;background-size:10px}h1.kraken-admin-section-title{margin-bottom:30px}.kraken_show_reset{margin-right:11px}small.krakenWhatsThis{font-size:9px}span.kraken-reset-all{font-size:11px}span.kraken-reset-all.enabled{text-decoration:underline;cursor:pointer}td.krakenAdvancedSettings{padding:20px 0 0!important}td.krakenAdvancedSettingsDescription{padding:10px 0!important}td.krakenAdvancedSettings h3{margin-bottom:2px}#krakenSettings .form-table,.kraken.error.settings-error,.kraken.updated.settings-error{margin-bottom:30px}td.krakenAdvancedSettings h3>.kraken-advanced-settings-label:hover{cursor:pointer;color:#45bbe6;user-select:none}td.krakenAdvancedSettings h3 span.kraken-advanced-toggle{color:#45bbe6;font-size:10px}.kraken-plus-minus{cursor:pointer;line-height:24px;width:20px;user-select:none}#krakenSettings .form-table th{width:270px;border-bottom:1px solid #ddd;padding:25px 0}#krakenSettings .form-table td{border-bottom:1px solid #ddd;padding:25px 0}#krakenSettings .form-table .no-border td,#krakenSettings .form-table .no-border th{border:none}#krakenSettings .form-table .with-tip td,#krakenSettings .form-table .with-tip th{border-bottom:none;padding-bottom:10px}.tip td{padding:10px 0 20px!important}.tip td div{border:1px solid #BCE8F1;background:#D9EDF7;padding:5px 10px;line-height:20px;font-size:12px}.blog-kraker-info-block-wrap{margin-top:10px;margin-left:10px;padding-bottom:110px;width:600px}.blog-kraker-image-summary{width:50%;float:left}.blog-kraker-kraken-statistics{width:50%;float:right}input[name=blog_kraker_mode],label[for=blog_kraker_mode_thumbs]{margin-right:10px}.kraken-item-details{cursor:pointer;text-decoration:underline}
|
js/ajax.js
CHANGED
@@ -1,40 +1,28 @@
|
|
1 |
jQuery(document).ready(function($) {
|
2 |
|
3 |
-
var
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
}, {
|
16 |
-
code: 415,
|
17 |
-
msg: 'WebP compression is non available for SVG images'
|
18 |
-
}, {
|
19 |
-
code: 422,
|
20 |
-
msg: 'You need to specify either callback_url or wait flag'
|
21 |
-
}, {
|
22 |
-
code: 422,
|
23 |
-
msg: 'This image can not be optimized any further'
|
24 |
-
}, {
|
25 |
-
code: 500,
|
26 |
-
msg: 'Kraken has encountered an unexpected error and cannot fulfill your request'
|
27 |
-
}, {
|
28 |
-
code: 502,
|
29 |
-
msg: 'Couldn\'t get this file'
|
30 |
-
}];
|
31 |
-
|
32 |
|
33 |
$('.krakenWhatsThis').tipsy({
|
34 |
fade: true,
|
35 |
gravity: 'w'
|
36 |
});
|
37 |
|
|
|
|
|
|
|
|
|
|
|
38 |
var data = {
|
39 |
action: 'kraken_request'
|
40 |
},
|
@@ -48,23 +36,24 @@ jQuery(document).ready(function($) {
|
|
48 |
|
49 |
var requestSuccess = function(data, textStatus, jqXHR) {
|
50 |
var $button = $(this),
|
51 |
-
$parent = $(this).
|
52 |
$cell = $(this).closest("td");
|
53 |
|
54 |
-
if (data.
|
55 |
-
|
56 |
$button.text("Image optimized");
|
57 |
|
58 |
var type = data.type,
|
59 |
-
krakedSize = data.kraked_size,
|
60 |
originalSize = data.original_size,
|
61 |
-
savingsPercent = data.savings_percent,
|
62 |
$originalSizeColumn = $(this).parent().prev("td.original_size"),
|
63 |
krakedData = '';
|
64 |
|
65 |
$parent.fadeOut("fast", function() {
|
66 |
-
$cell
|
67 |
-
|
|
|
|
|
|
|
|
|
68 |
$originalSizeColumn.html(originalSize);
|
69 |
$parent.remove();
|
70 |
});
|
@@ -137,40 +126,42 @@ jQuery(document).ready(function($) {
|
|
137 |
return rv;
|
138 |
};
|
139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
var renderBulkImageSummary = function(bulkImageData) {
|
141 |
-
var
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
.html(header)
|
155 |
-
.append(typeRadios)
|
156 |
-
.append('<br /><small class="kraken-bulk-small">The following <strong>' + nImages + '</strong> images will be optimized by Kraken.io using the <strong class="bulkSetting">' + setting + '</strong> setting:</small><br />')
|
157 |
-
.appendTo("body")
|
158 |
-
.kmodal(modalOptions)
|
159 |
-
.bind($.kmodal.BEFORE_CLOSE, function(event, modal) {
|
160 |
|
161 |
-
|
162 |
-
|
163 |
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
|
173 |
-
if (setting ===
|
174 |
$("#kraken-bulk-type-lossy").attr("checked", true);
|
175 |
} else {
|
176 |
$("#kraken-bulk-type-lossless").attr("checked", true);
|
@@ -193,17 +184,16 @@ jQuery(document).ready(function($) {
|
|
193 |
});
|
194 |
|
195 |
var $table = $('<table id="kraken-bulk"></table>'),
|
196 |
-
$headerRow = $('<tr class="kraken-bulk-header"><td>File</td><td style="width:120px">Original Size</td><td style="width:120px">
|
197 |
|
198 |
$table.append($headerRow);
|
199 |
$.each(bulkImageData, function(index, element) {
|
200 |
-
$table.append('<tr class="kraken-item-row" data-krakenbulkid="' + element.id + '"><td class="kraken-filename">' + element.filename + '</td><td class="kraken-originalsize">' + element.originalSize + '</td><td class="kraken-krakedsize"><span class="krakenBulkSpinner hidden"></span></td
|
201 |
});
|
202 |
|
203 |
$modal
|
204 |
.append($table)
|
205 |
-
.append(krakEmAll)
|
206 |
-
.append('<span class="close-kraken-bulk">Close Window</span>');
|
207 |
|
208 |
$(".close-kraken-bulk").click(function() {
|
209 |
$.kmodal.close();
|
@@ -218,6 +208,7 @@ jQuery(document).ready(function($) {
|
|
218 |
}
|
219 |
};
|
220 |
|
|
|
221 |
var bulkAction = function(bulkImageData) {
|
222 |
|
223 |
$bulkTable = $("#kraken-bulk");
|
@@ -242,37 +233,44 @@ jQuery(document).ready(function($) {
|
|
242 |
data: {
|
243 |
'action': 'kraken_request',
|
244 |
'id': id,
|
245 |
-
'type': $("input[name='kraken-bulk-type']:checked").val().toLowerCase()
|
|
|
246 |
},
|
247 |
type: "post",
|
248 |
dataType: "json",
|
249 |
timeout: 360000
|
250 |
})
|
251 |
.done(function(data, textStatus, jqXHR) {
|
252 |
-
if (data.success && typeof data.
|
253 |
var type = data.type,
|
254 |
originalSize = data.original_size,
|
255 |
-
krakedSize = data.
|
256 |
savingsPercent = data.savings_percent,
|
257 |
savingsBytes = data.saved_bytes;
|
258 |
|
259 |
-
$krakedSizeColumn.
|
|
|
|
|
|
|
|
|
|
|
260 |
$savingsPercentColumn.text(savingsPercent);
|
261 |
$savingsBytesColumn.text(savingsBytes);
|
262 |
|
263 |
var $button = $("button[id='krakenid-" + id + "']"),
|
264 |
$parent = $button.parent(),
|
265 |
$cell = $button.closest("td"),
|
266 |
-
$originalSizeColumn = $button.parent().prev("td.original_size")
|
267 |
|
268 |
|
269 |
$parent.fadeOut("fast", function() {
|
270 |
$cell.find(".noSavings, .krakenErrorWrap").remove();
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
|
|
276 |
$originalSizeColumn.html(originalSize);
|
277 |
$parent.remove();
|
278 |
});
|
@@ -284,7 +282,6 @@ jQuery(document).ready(function($) {
|
|
284 |
|
285 |
}
|
286 |
}
|
287 |
-
|
288 |
})
|
289 |
|
290 |
.fail(function() {
|
@@ -338,13 +335,45 @@ jQuery(document).ready(function($) {
|
|
338 |
}
|
339 |
});
|
340 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
$('body').on('click', 'small.krakenReset', function(e) {
|
342 |
e.preventDefault();
|
343 |
var $resetButton = $(this);
|
344 |
var resetData = {
|
345 |
action: 'kraken_reset'
|
346 |
};
|
|
|
347 |
resetData.id = $(this).data("id");
|
|
|
348 |
|
349 |
var $spinner = $('<span class="resetSpinner"></span>');
|
350 |
$resetButton.after($spinner);
|
@@ -358,13 +387,14 @@ jQuery(document).ready(function($) {
|
|
358 |
})
|
359 |
.done(function(data, textStatus, jqXHR) {
|
360 |
if (data.success !== 'undefined') {
|
361 |
-
$
|
362 |
-
.closest('.kraked_size.column-kraked_size')
|
363 |
.hide()
|
364 |
.html(data.html)
|
365 |
.fadeIn()
|
366 |
.prev(".original_size.column-original_size")
|
367 |
.html(data.original_size);
|
|
|
|
|
368 |
}
|
369 |
});
|
370 |
});
|
@@ -417,7 +447,7 @@ jQuery(document).ready(function($) {
|
|
417 |
$rows.show();
|
418 |
$plusMinus
|
419 |
.removeClass('dashicons-arrow-right')
|
420 |
-
.addClass('dashicons-arrow-down');
|
421 |
}
|
422 |
});
|
423 |
|
1 |
jQuery(document).ready(function($) {
|
2 |
|
3 |
+
var tipsySettings = {
|
4 |
+
gravity: 'e',
|
5 |
+
html: true,
|
6 |
+
trigger: 'manual',
|
7 |
+
className: function() {
|
8 |
+
return 'tipsy-' + $(this).data('id');
|
9 |
+
},
|
10 |
+
title: function() {
|
11 |
+
activeId = $(this).data('id');
|
12 |
+
return $(this).attr('original-title');
|
13 |
+
}
|
14 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
$('.krakenWhatsThis').tipsy({
|
17 |
fade: true,
|
18 |
gravity: 'w'
|
19 |
});
|
20 |
|
21 |
+
$('.krakenError').tipsy({
|
22 |
+
fade: true,
|
23 |
+
gravity: 'e'
|
24 |
+
});
|
25 |
+
|
26 |
var data = {
|
27 |
action: 'kraken_request'
|
28 |
},
|
36 |
|
37 |
var requestSuccess = function(data, textStatus, jqXHR) {
|
38 |
var $button = $(this),
|
39 |
+
$parent = $(this).closest('.kraken-wrap, .buttonWrap'),
|
40 |
$cell = $(this).closest("td");
|
41 |
|
42 |
+
if (data.html) {
|
|
|
43 |
$button.text("Image optimized");
|
44 |
|
45 |
var type = data.type,
|
|
|
46 |
originalSize = data.original_size,
|
|
|
47 |
$originalSizeColumn = $(this).parent().prev("td.original_size"),
|
48 |
krakedData = '';
|
49 |
|
50 |
$parent.fadeOut("fast", function() {
|
51 |
+
$cell
|
52 |
+
.find(".noSavings, .krakenErrorWrap")
|
53 |
+
.remove();
|
54 |
+
$cell.html(data.html);
|
55 |
+
$cell.find('.kraken-item-details')
|
56 |
+
.tipsy(tipsySettings);
|
57 |
$originalSizeColumn.html(originalSize);
|
58 |
$parent.remove();
|
59 |
});
|
126 |
return rv;
|
127 |
};
|
128 |
|
129 |
+
var bulkModalOptions = {
|
130 |
+
zIndex: 4,
|
131 |
+
escapeClose: true,
|
132 |
+
clickClose: false,
|
133 |
+
closeText: 'close',
|
134 |
+
showClose: false
|
135 |
+
};
|
136 |
+
|
137 |
var renderBulkImageSummary = function(bulkImageData) {
|
138 |
+
var setting = kraken_settings.api_lossy;
|
139 |
+
var nImages = bulkImageData.length;
|
140 |
+
var header = '<p class="krakenBulkHeader">Kraken Bulk Image Optimization <span class="close-kraken-bulk">×</span></p>';
|
141 |
+
var krakEmAll = '<button class="kraken_req_bulk">Krak \'em all</button>';
|
142 |
+
var typeRadios = '<div class="radiosWrap"><p>Choose optimization mode:</p><label><input type="radio" id="kraken-bulk-type-lossy" value="Lossy" name="kraken-bulk-type"/>Intelligent Lossy</label> <label><input type="radio" id="kraken-bulk-type-lossless" value="Lossless" name="kraken-bulk-type"/>Lossless</label></div>';
|
143 |
+
|
144 |
+
var $modal = $('<div id="kraken-bulk-modal" class="kraken-modal"></div>')
|
145 |
+
.html(header)
|
146 |
+
.append(typeRadios)
|
147 |
+
.append('<p class="the-following">The following <strong>' + nImages + '</strong> images will be optimized by Kraken.io using the <strong class="bulkSetting">' + setting + '</strong> setting:</p>')
|
148 |
+
.appendTo("body")
|
149 |
+
.kmodal(bulkModalOptions)
|
150 |
+
.bind($.kmodal.BEFORE_CLOSE, function(event, modal) {
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
|
152 |
+
})
|
153 |
+
.bind($.kmodal.OPEN, function(event, modal) {
|
154 |
|
155 |
+
})
|
156 |
+
.bind($.kmodal.CLOSE, function(event, modal) {
|
157 |
+
$("#kraken-bulk-modal").remove();
|
158 |
+
})
|
159 |
+
.css({
|
160 |
+
top: "10px",
|
161 |
+
marginTop: "40px"
|
162 |
+
});
|
163 |
|
164 |
+
if (setting === "lossy") {
|
165 |
$("#kraken-bulk-type-lossy").attr("checked", true);
|
166 |
} else {
|
167 |
$("#kraken-bulk-type-lossless").attr("checked", true);
|
184 |
});
|
185 |
|
186 |
var $table = $('<table id="kraken-bulk"></table>'),
|
187 |
+
$headerRow = $('<tr class="kraken-bulk-header"><td>File Name</td><td style="width:120px">Original Size</td><td style="width:120px">Kraken.io Stats</td></tr>');
|
188 |
|
189 |
$table.append($headerRow);
|
190 |
$.each(bulkImageData, function(index, element) {
|
191 |
+
$table.append('<tr class="kraken-item-row" data-krakenbulkid="' + element.id + '"><td class="kraken-bulk-filename">' + element.filename + '</td><td class="kraken-originalsize">' + element.originalSize + '</td><td class="kraken-krakedsize"><span class="krakenBulkSpinner hidden"></span></td></tr>');
|
192 |
});
|
193 |
|
194 |
$modal
|
195 |
.append($table)
|
196 |
+
.append(krakEmAll);
|
|
|
197 |
|
198 |
$(".close-kraken-bulk").click(function() {
|
199 |
$.kmodal.close();
|
208 |
}
|
209 |
};
|
210 |
|
211 |
+
|
212 |
var bulkAction = function(bulkImageData) {
|
213 |
|
214 |
$bulkTable = $("#kraken-bulk");
|
233 |
data: {
|
234 |
'action': 'kraken_request',
|
235 |
'id': id,
|
236 |
+
'type': $("input[name='kraken-bulk-type']:checked").val().toLowerCase(),
|
237 |
+
'origin': 'bulk_optimizer'
|
238 |
},
|
239 |
type: "post",
|
240 |
dataType: "json",
|
241 |
timeout: 360000
|
242 |
})
|
243 |
.done(function(data, textStatus, jqXHR) {
|
244 |
+
if (data.success && typeof data.message === 'undefined') {
|
245 |
var type = data.type,
|
246 |
originalSize = data.original_size,
|
247 |
+
krakedSize = data.html,
|
248 |
savingsPercent = data.savings_percent,
|
249 |
savingsBytes = data.saved_bytes;
|
250 |
|
251 |
+
$krakedSizeColumn.html(data.html);
|
252 |
+
|
253 |
+
$krakedSizeColumn
|
254 |
+
.find('.kraken-item-details')
|
255 |
+
.remove();
|
256 |
+
|
257 |
$savingsPercentColumn.text(savingsPercent);
|
258 |
$savingsBytesColumn.text(savingsBytes);
|
259 |
|
260 |
var $button = $("button[id='krakenid-" + id + "']"),
|
261 |
$parent = $button.parent(),
|
262 |
$cell = $button.closest("td"),
|
263 |
+
$originalSizeColumn = $button.parent().prev("td.original_size");
|
264 |
|
265 |
|
266 |
$parent.fadeOut("fast", function() {
|
267 |
$cell.find(".noSavings, .krakenErrorWrap").remove();
|
268 |
+
$cell
|
269 |
+
.empty()
|
270 |
+
.html(data.html);
|
271 |
+
$cell
|
272 |
+
.find('.kraken-item-details')
|
273 |
+
.tipsy(tipsySettings);
|
274 |
$originalSizeColumn.html(originalSize);
|
275 |
$parent.remove();
|
276 |
});
|
282 |
|
283 |
}
|
284 |
}
|
|
|
285 |
})
|
286 |
|
287 |
.fail(function() {
|
335 |
}
|
336 |
});
|
337 |
|
338 |
+
var activeId = null;
|
339 |
+
$('.kraken-item-details').tipsy(tipsySettings);
|
340 |
+
|
341 |
+
var $activePopup = null;
|
342 |
+
$('body').on('click', '.kraken-item-details', function(e) {
|
343 |
+
//$('.tipsy[class="tipsy-' + activeId + '"]').remove();
|
344 |
+
|
345 |
+
var id = $(this).data('id');
|
346 |
+
$('.tipsy').remove();
|
347 |
+
if (id == activeId) {
|
348 |
+
activeId = null;
|
349 |
+
$(this).text('Show details');
|
350 |
+
return;
|
351 |
+
}
|
352 |
+
$('.kraken-item-details').text('Show details');
|
353 |
+
$(this).tipsy('show');
|
354 |
+
$(this).text('Hide details');
|
355 |
+
});
|
356 |
+
|
357 |
+
$('body').on('click', function(e) {
|
358 |
+
var $t = $(e.target);
|
359 |
+
if (($t.hasClass('tipsy') || $t.closest('.tipsy').length) || $t.hasClass('kraken-item-details')) {
|
360 |
+
return;
|
361 |
+
} else {
|
362 |
+
activeId = null;
|
363 |
+
$('.kraken-item-details').text('Show details');
|
364 |
+
$('.tipsy').remove();
|
365 |
+
}
|
366 |
+
});
|
367 |
+
|
368 |
$('body').on('click', 'small.krakenReset', function(e) {
|
369 |
e.preventDefault();
|
370 |
var $resetButton = $(this);
|
371 |
var resetData = {
|
372 |
action: 'kraken_reset'
|
373 |
};
|
374 |
+
|
375 |
resetData.id = $(this).data("id");
|
376 |
+
$row = $('#post-' + resetData.id).find('.kraked_size');
|
377 |
|
378 |
var $spinner = $('<span class="resetSpinner"></span>');
|
379 |
$resetButton.after($spinner);
|
387 |
})
|
388 |
.done(function(data, textStatus, jqXHR) {
|
389 |
if (data.success !== 'undefined') {
|
390 |
+
$row
|
|
|
391 |
.hide()
|
392 |
.html(data.html)
|
393 |
.fadeIn()
|
394 |
.prev(".original_size.column-original_size")
|
395 |
.html(data.original_size);
|
396 |
+
|
397 |
+
$('.tipsy').remove();
|
398 |
}
|
399 |
});
|
400 |
});
|
447 |
$rows.show();
|
448 |
$plusMinus
|
449 |
.removeClass('dashicons-arrow-right')
|
450 |
+
.addClass('dashicons-arrow-down');
|
451 |
}
|
452 |
});
|
453 |
|
js/dist/kraken.min.js
CHANGED
@@ -1,3 +1,2 @@
|
|
1 |
-
!function(){function only_once(fn){var called=!1;return function(){if(called)throw new Error("Callback was already called.");called=!0,fn.apply(root,arguments)}}var root,previous_async,async={};root=this,null!=root&&(previous_async=root.async),async.noConflict=function(){return root.async=previous_async,async};var _each=function(arr,iterator){if(arr.forEach)return arr.forEach(iterator);for(var i=0;i<arr.length;i+=1)iterator(arr[i],i,arr)},_map=function(arr,iterator){if(arr.map)return arr.map(iterator);var results=[];return _each(arr,function(x,i,a){results.push(iterator(x,i,a))}),results},_reduce=function(arr,iterator,memo){return arr.reduce?arr.reduce(iterator,memo):(_each(arr,function(x,i,a){memo=iterator(memo,x,i,a)}),memo)},_keys=function(obj){if(Object.keys)return Object.keys(obj);var keys=[];for(var k in obj)obj.hasOwnProperty(k)&&keys.push(k);return keys};"undefined"!=typeof process&&process.nextTick?(async.nextTick=process.nextTick,"undefined"!=typeof setImmediate?async.setImmediate=function(fn){setImmediate(fn)}:async.setImmediate=async.nextTick):"function"==typeof setImmediate?(async.nextTick=function(fn){setImmediate(fn)},async.setImmediate=async.nextTick):(async.nextTick=function(fn){setTimeout(fn,0)},async.setImmediate=async.nextTick),async.each=function(arr,iterator,callback){if(callback=callback||function(){},!arr.length)return callback();var completed=0;_each(arr,function(x){iterator(x,only_once(function(err){err?(callback(err),callback=function(){}):(completed+=1,completed>=arr.length&&callback(null))}))})},async.forEach=async.each,async.eachSeries=function(arr,iterator,callback){if(callback=callback||function(){},!arr.length)return callback();var completed=0,iterate=function(){iterator(arr[completed],function(err){err?(callback(err),callback=function(){}):(completed+=1,completed>=arr.length?callback(null):iterate())})};iterate()},async.forEachSeries=async.eachSeries,async.eachLimit=function(arr,limit,iterator,callback){var fn=_eachLimit(limit);fn.apply(null,[arr,iterator,callback])},async.forEachLimit=async.eachLimit;var _eachLimit=function(limit){return function(arr,iterator,callback){if(callback=callback||function(){},!arr.length||0>=limit)return callback();var completed=0,started=0,running=0;!function replenish(){if(completed>=arr.length)return callback();for(;limit>running&&started<arr.length;)started+=1,running+=1,iterator(arr[started-1],function(err){err?(callback(err),callback=function(){}):(completed+=1,running-=1,completed>=arr.length?callback():replenish())})}()}},doParallel=function(fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[async.each].concat(args))}},doParallelLimit=function(limit,fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[_eachLimit(limit)].concat(args))}},doSeries=function(fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[async.eachSeries].concat(args))}},_asyncMap=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(err,v){results[x.index]=v,callback(err)})},function(err){callback(err,results)})};async.map=doParallel(_asyncMap),async.mapSeries=doSeries(_asyncMap),async.mapLimit=function(arr,limit,iterator,callback){return _mapLimit(limit)(arr,iterator,callback)};var _mapLimit=function(limit){return doParallelLimit(limit,_asyncMap)};async.reduce=function(arr,memo,iterator,callback){async.eachSeries(arr,function(x,callback){iterator(memo,x,function(err,v){memo=v,callback(err)})},function(err){callback(err,memo)})},async.inject=async.reduce,async.foldl=async.reduce,async.reduceRight=function(arr,memo,iterator,callback){var reversed=_map(arr,function(x){return x}).reverse();async.reduce(reversed,memo,iterator,callback)},async.foldr=async.reduceRight;var _filter=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(v){v&&results.push(x),callback()})},function(err){callback(_map(results.sort(function(a,b){return a.index-b.index}),function(x){return x.value}))})};async.filter=doParallel(_filter),async.filterSeries=doSeries(_filter),async.select=async.filter,async.selectSeries=async.filterSeries;var _reject=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(v){v||results.push(x),callback()})},function(err){callback(_map(results.sort(function(a,b){return a.index-b.index}),function(x){return x.value}))})};async.reject=doParallel(_reject),async.rejectSeries=doSeries(_reject);var _detect=function(eachfn,arr,iterator,main_callback){eachfn(arr,function(x,callback){iterator(x,function(result){result?(main_callback(x),main_callback=function(){}):callback()})},function(err){main_callback()})};async.detect=doParallel(_detect),async.detectSeries=doSeries(_detect),async.some=function(arr,iterator,main_callback){async.each(arr,function(x,callback){iterator(x,function(v){v&&(main_callback(!0),main_callback=function(){}),callback()})},function(err){main_callback(!1)})},async.any=async.some,async.every=function(arr,iterator,main_callback){async.each(arr,function(x,callback){iterator(x,function(v){v||(main_callback(!1),main_callback=function(){}),callback()})},function(err){main_callback(!0)})},async.all=async.every,async.sortBy=function(arr,iterator,callback){async.map(arr,function(x,callback){iterator(x,function(err,criteria){err?callback(err):callback(null,{value:x,criteria:criteria})})},function(err,results){if(err)return callback(err);var fn=function(left,right){var a=left.criteria,b=right.criteria;return b>a?-1:a>b?1:0};callback(null,_map(results.sort(fn),function(x){return x.value}))})},async.auto=function(tasks,callback){callback=callback||function(){};var keys=_keys(tasks);if(!keys.length)return callback(null);var results={},listeners=[],addListener=function(fn){listeners.unshift(fn)},removeListener=function(fn){for(var i=0;i<listeners.length;i+=1)if(listeners[i]===fn)return void listeners.splice(i,1)},taskComplete=function(){_each(listeners.slice(0),function(fn){fn()})};addListener(function(){_keys(results).length===keys.length&&(callback(null,results),callback=function(){})}),_each(keys,function(k){var task=tasks[k]instanceof Function?[tasks[k]]:tasks[k],taskCallback=function(err){var args=Array.prototype.slice.call(arguments,1);if(args.length<=1&&(args=args[0]),err){var safeResults={};_each(_keys(results),function(rkey){safeResults[rkey]=results[rkey]}),safeResults[k]=args,callback(err,safeResults),callback=function(){}}else results[k]=args,async.setImmediate(taskComplete)},requires=task.slice(0,Math.abs(task.length-1))||[],ready=function(){return _reduce(requires,function(a,x){return a&&results.hasOwnProperty(x)},!0)&&!results.hasOwnProperty(k)};if(ready())task[task.length-1](taskCallback,results);else{var listener=function(){ready()&&(removeListener(listener),task[task.length-1](taskCallback,results))};addListener(listener)}})},async.waterfall=function(tasks,callback){if(callback=callback||function(){},tasks.constructor!==Array){var err=new Error("First argument to waterfall must be an array of functions");return callback(err)}if(!tasks.length)return callback();var wrapIterator=function(iterator){return function(err){if(err)callback.apply(null,arguments),callback=function(){};else{var args=Array.prototype.slice.call(arguments,1),next=iterator.next();args.push(next?wrapIterator(next):callback),async.setImmediate(function(){iterator.apply(null,args)})}}};wrapIterator(async.iterator(tasks))()};var _parallel=function(eachfn,tasks,callback){if(callback=callback||function(){},tasks.constructor===Array)eachfn.map(tasks,function(fn,callback){fn&&fn(function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),callback.call(null,err,args)})},callback);else{var results={};eachfn.each(_keys(tasks),function(k,callback){tasks[k](function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),results[k]=args,callback(err)})},function(err){callback(err,results)})}};async.parallel=function(tasks,callback){_parallel({map:async.map,each:async.each},tasks,callback)},async.parallelLimit=function(tasks,limit,callback){_parallel({map:_mapLimit(limit),each:_eachLimit(limit)},tasks,callback)},async.series=function(tasks,callback){if(callback=callback||function(){},tasks.constructor===Array)async.mapSeries(tasks,function(fn,callback){fn&&fn(function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),callback.call(null,err,args)})},callback);else{var results={};async.eachSeries(_keys(tasks),function(k,callback){tasks[k](function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),results[k]=args,callback(err)})},function(err){callback(err,results)})}},async.iterator=function(tasks){var makeCallback=function(index){var fn=function(){return tasks.length&&tasks[index].apply(null,arguments),fn.next()};return fn.next=function(){return index<tasks.length-1?makeCallback(index+1):null},fn};return makeCallback(0)},async.apply=function(fn){var args=Array.prototype.slice.call(arguments,1);return function(){return fn.apply(null,args.concat(Array.prototype.slice.call(arguments)))}};var _concat=function(eachfn,arr,fn,callback){var r=[];eachfn(arr,function(x,cb){fn(x,function(err,y){r=r.concat(y||[]),cb(err)})},function(err){callback(err,r)})};async.concat=doParallel(_concat),async.concatSeries=doSeries(_concat),async.whilst=function(test,iterator,callback){test()?iterator(function(err){return err?callback(err):void async.whilst(test,iterator,callback)}):callback()},async.doWhilst=function(iterator,test,callback){iterator(function(err){return err?callback(err):void(test()?async.doWhilst(iterator,test,callback):callback())})},async.until=function(test,iterator,callback){test()?callback():iterator(function(err){return err?callback(err):void async.until(test,iterator,callback)})},async.doUntil=function(iterator,test,callback){iterator(function(err){return err?callback(err):void(test()?callback():async.doUntil(iterator,test,callback))})},async.queue=function(worker,concurrency){function _insert(q,data,pos,callback){data.constructor!==Array&&(data=[data]),_each(data,function(task){var item={data:task,callback:"function"==typeof callback?callback:null};pos?q.tasks.unshift(item):q.tasks.push(item),q.saturated&&q.tasks.length===concurrency&&q.saturated(),async.setImmediate(q.process)})}void 0===concurrency&&(concurrency=1);var workers=0,q={tasks:[],concurrency:concurrency,saturated:null,empty:null,drain:null,push:function(data,callback){_insert(q,data,!1,callback)},unshift:function(data,callback){_insert(q,data,!0,callback)},process:function(){if(workers<q.concurrency&&q.tasks.length){var task=q.tasks.shift();q.empty&&0===q.tasks.length&&q.empty(),workers+=1;var next=function(){workers-=1,task.callback&&task.callback.apply(task,arguments),q.drain&&q.tasks.length+workers===0&&q.drain(),q.process()},cb=only_once(next);worker(task.data,cb)}},length:function(){return q.tasks.length},running:function(){return workers}};return q},async.cargo=function(worker,payload){var working=!1,tasks=[],cargo={tasks:tasks,payload:payload,saturated:null,empty:null,drain:null,push:function(data,callback){data.constructor!==Array&&(data=[data]),_each(data,function(task){tasks.push({data:task,callback:"function"==typeof callback?callback:null}),cargo.saturated&&tasks.length===payload&&cargo.saturated()}),async.setImmediate(cargo.process)},process:function process(){if(!working){if(0===tasks.length)return void(cargo.drain&&cargo.drain());var ts="number"==typeof payload?tasks.splice(0,payload):tasks.splice(0),ds=_map(ts,function(task){return task.data});cargo.empty&&cargo.empty(),working=!0,worker(ds,function(){working=!1;var args=arguments;_each(ts,function(data){data.callback&&data.callback.apply(null,args)}),process()})}},length:function(){return tasks.length},running:function(){return working}};return cargo};var _console_fn=function(name){return function(fn){var args=Array.prototype.slice.call(arguments,1);fn.apply(null,args.concat([function(err){var args=Array.prototype.slice.call(arguments,1);"undefined"!=typeof console&&(err?console.error&&console.error(err):console[name]&&_each(args,function(x){console[name](x)}))}]))}};async.log=_console_fn("log"),async.dir=_console_fn("dir"),async.memoize=function(fn,hasher){var memo={},queues={};hasher=hasher||function(x){return x};var memoized=function(){var args=Array.prototype.slice.call(arguments),callback=args.pop(),key=hasher.apply(null,args);key in memo?callback.apply(null,memo[key]):key in queues?queues[key].push(callback):(queues[key]=[callback],fn.apply(null,args.concat([function(){memo[key]=arguments;var q=queues[key];delete queues[key];for(var i=0,l=q.length;l>i;i++)q[i].apply(null,arguments)}])))};return memoized.memo=memo,memoized.unmemoized=fn,memoized},async.unmemoize=function(fn){return function(){return(fn.unmemoized||fn).apply(null,arguments)}},async.times=function(count,iterator,callback){for(var counter=[],i=0;count>i;i++)counter.push(i);return async.map(counter,iterator,callback)},async.timesSeries=function(count,iterator,callback){for(var counter=[],i=0;count>i;i++)counter.push(i);return async.mapSeries(counter,iterator,callback)},async.compose=function(){var fns=Array.prototype.reverse.call(arguments);return function(){var that=this,args=Array.prototype.slice.call(arguments),callback=args.pop();async.reduce(fns,args,function(newargs,fn,cb){fn.apply(that,newargs.concat([function(){var err=arguments[0],nextargs=Array.prototype.slice.call(arguments,1);cb(err,nextargs)}]))},function(err,results){callback.apply(that,[err].concat(results))})}};var _applyEach=function(eachfn,fns){var go=function(){var that=this,args=Array.prototype.slice.call(arguments),callback=args.pop();return eachfn(fns,function(fn,cb){fn.apply(that,args.concat([cb]))},callback)};if(arguments.length>2){var args=Array.prototype.slice.call(arguments,2);return go.apply(this,args)}return go};async.applyEach=doParallel(_applyEach),async.applyEachSeries=doSeries(_applyEach),async.forever=function(fn,callback){function next(err){if(err){if(callback)return callback(err);throw err}fn(next)}next()},"undefined"!=typeof define&&define.amd?define([],function(){return async}):"undefined"!=typeof module&&module.exports?module.exports=async:root.async=async}(),function($){function maybeCall(thing,ctx){return"function"==typeof thing?thing.call(ctx):thing}function isElementInDOM(ele){for(;ele=ele.parentNode;)if(ele==document)return!0;return!1}function Tipsy(element,options){this.$element=$(element),this.options=options,this.enabled=!0,this.fixTitle()}Tipsy.prototype={show:function(){var title=this.getTitle();if(title&&this.enabled){var $tip=this.tip();$tip.find(".tipsy-inner")[this.options.html?"html":"text"](title),$tip[0].className="tipsy",$tip.remove().css({top:0,left:0,visibility:"hidden",display:"block"}).prependTo(document.body);var tp,pos=$.extend({},this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight}),actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight,gravity=maybeCall(this.options.gravity,this.$element[0]);switch(gravity.charAt(0)){case"n":tp={top:pos.top+pos.height+this.options.offset,left:pos.left+pos.width/2-actualWidth/2};break;case"s":tp={top:pos.top-actualHeight-this.options.offset,left:pos.left+pos.width/2-actualWidth/2};break;case"e":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left-actualWidth-this.options.offset};break;case"w":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left+pos.width+this.options.offset}}2==gravity.length&&("w"==gravity.charAt(1)?tp.left=pos.left+pos.width/2-15:tp.left=pos.left+pos.width/2-actualWidth+15),$tip.css(tp).addClass("tipsy-"+gravity),$tip.find(".tipsy-arrow")[0].className="tipsy-arrow tipsy-arrow-"+gravity.charAt(0),this.options.className&&$tip.addClass(maybeCall(this.options.className,this.$element[0])),this.options.fade?$tip.stop().css({opacity:0,display:"block",visibility:"visible"}).animate({opacity:this.options.opacity}):$tip.css({visibility:"visible",opacity:this.options.opacity})}},hide:function(){this.options.fade?this.tip().stop().fadeOut(function(){$(this).remove()}):this.tip().remove()},fixTitle:function(){var $e=this.$element;($e.attr("title")||"string"!=typeof $e.attr("original-title"))&&$e.attr("original-title",$e.attr("title")||"").removeAttr("title")},getTitle:function(){var title,$e=this.$element,o=this.options;this.fixTitle();var title,o=this.options;return"string"==typeof o.title?title=$e.attr("title"==o.title?"original-title":o.title):"function"==typeof o.title&&(title=o.title.call($e[0])),title=(""+title).replace(/(^\s*|\s*$)/,""),title||o.fallback},tip:function(){return this.$tip||(this.$tip=$('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>'),this.$tip.data("tipsy-pointee",this.$element[0])),this.$tip},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled}},$.fn.tipsy=function(options){function get(ele){var tipsy=$.data(ele,"tipsy");return tipsy||(tipsy=new Tipsy(ele,$.fn.tipsy.elementOptions(ele,options)),$.data(ele,"tipsy",tipsy)),tipsy}function enter(){var tipsy=get(this);tipsy.hoverState="in",0==options.delayIn?tipsy.show():(tipsy.fixTitle(),setTimeout(function(){"in"==tipsy.hoverState&&tipsy.show()},options.delayIn))}function leave(){var tipsy=get(this);tipsy.hoverState="out",0==options.delayOut?tipsy.hide():setTimeout(function(){"out"==tipsy.hoverState&&tipsy.hide()},options.delayOut)}if(options===!0)return this.data("tipsy");if("string"==typeof options){var tipsy=this.data("tipsy");return tipsy&&tipsy[options](),this}if(options=$.extend({},$.fn.tipsy.defaults,options),options.live||this.each(function(){get(this)}),"manual"!=options.trigger){var binder=options.live?"live":"bind",eventIn="hover"==options.trigger?"mouseenter":"focus",eventOut="hover"==options.trigger?"mouseleave":"blur";this[binder](eventIn,enter)[binder](eventOut,leave)}return this},$.fn.tipsy.defaults={className:null,delayIn:0,delayOut:0,fade:!1,fallback:"",gravity:"n",html:!1,live:!1,offset:0,opacity:.8,title:"title",trigger:"hover"},$.fn.tipsy.revalidate=function(){$(".tipsy").each(function(){var pointee=$.data(this,"tipsy-pointee");pointee&&isElementInDOM(pointee)||$(this).remove()})},$.fn.tipsy.elementOptions=function(ele,options){return $.metadata?$.extend({},options,$(ele).metadata()):options},$.fn.tipsy.autoNS=function(){return $(this).offset().top>$(document).scrollTop()+$(window).height()/2?"s":"n"},$.fn.tipsy.autoWE=function(){return $(this).offset().left>$(document).scrollLeft()+$(window).width()/2?"e":"w"},$.fn.tipsy.autoBounds=function(margin,prefer){return function(){var dir={ns:prefer[0],ew:prefer.length>1?prefer[1]:!1},boundTop=$(document).scrollTop()+margin,boundLeft=$(document).scrollLeft()+margin,$this=$(this);return $this.offset().top<boundTop&&(dir.ns="n"),$this.offset().left<boundLeft&&(dir.ew="w"),$(window).width()+$(document).scrollLeft()-$this.offset().left<margin&&(dir.ew="e"),$(window).height()+$(document).scrollTop()-$this.offset().top<margin&&(dir.ns="s"),dir.ns+(dir.ew?dir.ew:"")}}}(jQuery),function($){var current=null;$.kmodal=function(el,options){$.kmodal.close();var remove,target;if(this.$body=$("body"),this.options=$.extend({},$.kmodal.defaults,options),this.options.doFade=!isNaN(parseInt(this.options.fadeDuration,10)),el.is("a"))if(target=el.attr("href"),/^#/.test(target)){if(this.$elm=$(target),1!==this.$elm.length)return null;this.open()}else this.$elm=$("<div>"),this.$body.append(this.$elm),remove=function(event,modal){modal.elm.remove()},this.showSpinner(),el.trigger($.kmodal.AJAX_SEND),$.get(target).done(function(html){current&&(el.trigger($.kmodal.AJAX_SUCCESS),current.$elm.empty().append(html).on($.kmodal.CLOSE,remove),current.hideSpinner(),current.open(),el.trigger($.kmodal.AJAX_COMPLETE))}).fail(function(){el.trigger($.kmodal.AJAX_FAIL),current.hideSpinner(),el.trigger($.kmodal.AJAX_COMPLETE)});else this.$elm=el,this.$body.append(this.$elm),this.open()},$.kmodal.prototype={constructor:$.kmodal,open:function(){var m=this;this.options.doFade?(this.block(),setTimeout(function(){m.show()},this.options.fadeDuration*this.options.fadeDelay)):(this.block(),this.show()),this.options.escapeClose&&$(document).on("keydown.modal",function(event){27==event.which&&$.kmodal.close()}),this.options.clickClose&&this.blocker.click($.kmodal.close)},close:function(){this.unblock(),this.hide(),$(document).off("keydown.modal")},block:function(){var initialOpacity=this.options.doFade?0:this.options.opacity;this.$elm.trigger($.kmodal.BEFORE_BLOCK,[this._ctx()]),this.blocker=$('<div class="jquery-modal blocker"></div>').css({top:0,right:0,bottom:0,left:0,width:"100%",height:"100%",position:"fixed",zIndex:this.options.zIndex,background:this.options.overlay,opacity:initialOpacity}),this.$body.append(this.blocker),this.options.doFade&&this.blocker.animate({opacity:this.options.opacity},this.options.fadeDuration),this.$elm.trigger($.kmodal.BLOCK,[this._ctx()])},unblock:function(){this.options.doFade?this.blocker.fadeOut(this.options.fadeDuration,function(){$(this).remove()}):this.blocker.remove()},show:function(){this.$elm.trigger($.kmodal.BEFORE_OPEN,[this._ctx()]),this.options.showClose&&(this.closeButton=$('<a href="#close-modal" rel="modal:close" class="close-modal '+this.options.closeClass+'">'+this.options.closeText+"</a>"),this.$elm.append(this.closeButton)),this.$elm.addClass(this.options.modalClass+" current"),this.center(),this.options.doFade?this.$elm.fadeIn(this.options.fadeDuration):this.$elm.show(),this.$elm.trigger($.kmodal.OPEN,[this._ctx()])},hide:function(){this.$elm.trigger($.kmodal.BEFORE_CLOSE,[this._ctx()]),this.closeButton&&this.closeButton.remove(),this.$elm.removeClass("current"),this.options.doFade?this.$elm.fadeOut(this.options.fadeDuration):this.$elm.hide(),this.$elm.trigger($.kmodal.CLOSE,[this._ctx()])},showSpinner:function(){this.options.showSpinner&&(this.spinner=this.spinner||$('<div class="'+this.options.modalClass+'-spinner"></div>').append(this.options.spinnerHtml),this.$body.append(this.spinner),this.spinner.show())},hideSpinner:function(){this.spinner&&this.spinner.remove()},center:function(){this.$elm.css({position:"fixed",top:"50%",left:"50%",marginTop:-(this.$elm.outerHeight()/2),marginLeft:-(this.$elm.outerWidth()/2),zIndex:this.options.zIndex+1})},_ctx:function(){return{elm:this.$elm,blocker:this.blocker,options:this.options}}},$.kmodal.prototype.resize=$.kmodal.prototype.center,$.kmodal.close=function(event){if(current){event&&event.preventDefault(),current.close();var that=current.$elm;return current=null,that}},$.kmodal.resize=function(){current&¤t.resize()},$.kmodal.isActive=function(){return current?!0:!1},$.kmodal.defaults={overlay:"#000",opacity:.75,zIndex:1,escapeClose:!0,clickClose:!0,closeText:"Close",closeClass:"",modalClass:"kraken-modal",spinnerHtml:null,showSpinner:!0,showClose:!0,fadeDuration:null,fadeDelay:1},$.kmodal.BEFORE_BLOCK="modal:before-block",$.kmodal.BLOCK="modal:block",$.kmodal.BEFORE_OPEN="modal:before-open",$.kmodal.OPEN="modal:open",$.kmodal.BEFORE_CLOSE="modal:before-close",$.kmodal.CLOSE="modal:close",$.kmodal.AJAX_SEND="modal:ajax:send",$.kmodal.AJAX_SUCCESS="modal:ajax:success",$.kmodal.AJAX_FAIL="modal:ajax:fail",$.kmodal.AJAX_COMPLETE="modal:ajax:complete",$.fn.kmodal=function(options){return 1===this.length&&(current=new $.kmodal(this,options)),this},$(document).on("click.modal",'a[rel="modal:close"]',$.kmodal.close),$(document).on("click.modal",'a[rel="modal:open"]',function(event){event.preventDefault(),$(this).kmodal()})}(jQuery),jQuery(document).ready(function($){$(".krakenWhatsThis").tipsy({fade:!0,gravity:"w"});var data={action:"kraken_request"},errorTpl='<div class="krakenErrorWrap"><a class="krakenError">Failed! Hover here</a></div>',$btnApplyBulkAction=$("#doaction"),$btnApplyBulkAction2=$("#doaction2"),$topBulkActionDropdown=$(".tablenav.top .bulkactions select[name='action']"),$bottomBulkActionDropdown=$(".tablenav.bottom .bulkactions select[name='action2']"),requestSuccess=function(data,textStatus,jqXHR){var $button=$(this),$parent=$(this).parent(),$cell=$(this).closest("td");if(data.success&&"undefined"==typeof data.error){$button.text("Image optimized");var originalSize=(data.type,data.kraked_size,data.original_size),$originalSizeColumn=(data.savings_percent,$(this).parent().prev("td.original_size"));$parent.fadeOut("fast",function(){$cell.find(".noSavings, .krakenErrorWrap").remove(),$(this).replaceWith(data.html),$originalSizeColumn.html(originalSize),$parent.remove()})}else if(data.error){var $error=$(errorTpl).attr("title",data.error);$parent.closest("td").find(".krakenErrorWrap").remove(),$parent.after($error),$error.tipsy({fade:!0,gravity:"e"}),$button.text("Retry request").removeAttr("disabled").css({opacity:1})}},requestFail=function(jqXHR,textStatus,errorThrown){$(this).removeAttr("disabled")},requestComplete=function(jqXHR,textStatus,errorThrown){$(this).removeAttr("disabled"),$(this).parent().find(".krakenSpinner").css("display","none")},opts='<option value="kraken-bulk-lossy">Krak \'em all</option>';$topBulkActionDropdown.find("option:last-child").before(opts),$bottomBulkActionDropdown.find("option:last-child").before(opts);var getBulkImageData=function(){var $rows=$("tr[id^='post-']"),$row=null,postId=0,$krakBtn=null,btnData={},originalSize="",rv=[];return $rows.each(function(){$row=$(this),postId=this.id.replace(/^\D+/g,""),$row.find("input[type='checkbox'][value='"+postId+"']:checked").length&&($krakBtn=$row.find(".kraken_req"),$krakBtn.length&&(btnData=$krakBtn.data(),originalSize=$.trim($row.find("td.original_size").text()),btnData.originalSize=originalSize,rv.push(btnData)))}),rv},renderBulkImageSummary=function(bulkImageData){var modalOptions={zIndex:4,escapeClose:!0,clickClose:!1,closeText:"close",showClose:!1},setting=kraken_settings.api_lossy,nImages=bulkImageData.length,header='<p class="krakenBulkHeader">Kraken Bulk Image Optimization</p>',krakEmAll='<button class="kraken_req_bulk">Krak \'em all</button>',typeRadios='<span class="radiosWrap"><span class="kraken-bulk-choose-type">Choose:</span><input type="radio" id="kraken-bulk-type-lossy" value="Lossy" name="kraken-bulk-type"/><label for="kraken-bulk-type-lossy">Lossy</label> <input type="radio" id="kraken-bulk-type-lossless" value="Lossless" name="kraken-bulk-type"/><label for="kraken-bulk-type-lossless">Lossless</label></span>',$modal=$('<div id="kraken-bulk-modal" class="kraken-modal"></div>').html(header).append(typeRadios).append('<br /><small class="kraken-bulk-small">The following <strong>'+nImages+'</strong> images will be optimized by Kraken.io using the <strong class="bulkSetting">'+setting+"</strong> setting:</small><br />").appendTo("body").kmodal(modalOptions).bind($.kmodal.BEFORE_CLOSE,function(event,modal){}).bind($.kmodal.OPEN,function(event,modal){}).bind($.kmodal.CLOSE,function(event,modal){$("#kraken-bulk-modal").remove()}).css({top:"10px",marginTop:"40px"});"lossy"===setting?$("#kraken-bulk-type-lossy").attr("checked",!0):$("#kraken-bulk-type-lossless").attr("checked",!0),$bulkSettingSpan=$(".bulkSetting"),$("input[name='kraken-bulk-type']").change(function(){var text="kraken-bulk-type-lossy"===this.id?"lossy":"lossless";$bulkSettingSpan.text(text)}),$(".jquery-modal.blocker").click(function(e){return!1}),$("#menu-media ul.wp-submenu").css({"z-index":1});var $table=$('<table id="kraken-bulk"></table>'),$headerRow=$('<tr class="kraken-bulk-header"><td>File</td><td style="width:120px">Original Size</td><td style="width:120px">Kraked Size</td><td style="width:120px">Savings</td><td style="width:120px">% Savings</td></tr>');$table.append($headerRow),$.each(bulkImageData,function(index,element){$table.append('<tr class="kraken-item-row" data-krakenbulkid="'+element.id+'"><td class="kraken-filename">'+element.filename+'</td><td class="kraken-originalsize">'+element.originalSize+'</td><td class="kraken-krakedsize"><span class="krakenBulkSpinner hidden"></span></td><td class="kraken-savings"></td><td class="kraken-savingsPercent"></td></tr>')}),$modal.append($table).append(krakEmAll).append('<span class="close-kraken-bulk">Close Window</span>'),$(".close-kraken-bulk").click(function(){$.kmodal.close()}),nImages||$(".kraken_req_bulk").attr("disabled",!0).css({opacity:.5})},bulkAction=function(bulkImageData){$bulkTable=$("#kraken-bulk");var jqxhr=null,q=async.queue(function(task,callback){var id=task.id,$row=(task.filename,$bulkTable.find("tr[data-krakenbulkid='"+id+"']")),$krakedSizeColumn=$row.find(".kraken-krakedsize"),$spinner=$krakedSizeColumn.find(".krakenBulkSpinner").css({display:"inline-block"}),$savingsPercentColumn=$row.find(".kraken-savingsPercent"),$savingsBytesColumn=$row.find(".kraken-savings");jqxhr=$.ajax({url:ajax_object.ajax_url,data:{action:"kraken_request",id:id,type:$("input[name='kraken-bulk-type']:checked").val().toLowerCase()},type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){if(data.success&&"undefined"==typeof data.error){var type=data.type,originalSize=data.original_size,krakedSize=data.kraked_size,savingsPercent=data.savings_percent,savingsBytes=data.saved_bytes;$krakedSizeColumn.text(krakedSize),$savingsPercentColumn.text(savingsPercent),$savingsBytesColumn.text(savingsBytes);var $button=$("button[id='krakenid-"+id+"']"),$parent=$button.parent(),$cell=$button.closest("td"),$originalSizeColumn=$button.parent().prev("td.original_size");$parent.fadeOut("fast",function(){$cell.find(".noSavings, .krakenErrorWrap").remove(),krakedData="<strong>"+krakedSize+"</strong><br /><small>Type: "+type+"</small><br /><small>Savings: "+savingsPercent+"</small>","undefined"!=typeof data.thumbs_data&&(krakedData+="<br /><small>"+data.thumbs_data.length+" thumbs optimized</small>"),$(this).replaceWith(krakedData),$originalSizeColumn.html(originalSize),$parent.remove()})}else data.error&&"This image can not be optimized any further"===data.error&&$krakedSizeColumn.text("No savings found.")}).fail(function(){}).always(function(){$spinner.css({display:"none"}),callback()})},kraken_settings.bulk_async_limit);q.drain=function(){$(".kraken_req_bulk").removeAttr("disabled").css({opacity:1}).text("Done").unbind("click").click(function(){$.kmodal.close()})},q.push(bulkImageData,function(err){})};$btnApplyBulkAction.add($btnApplyBulkAction2).click(function(e){if("kraken-bulk-lossy"===$(this).prev("select").val()){e.preventDefault();var bulkImageData=getBulkImageData();renderBulkImageSummary(bulkImageData),$(".kraken_req_bulk").click(function(e){e.preventDefault(),$(this).attr("disabled",!0).css({opacity:.5}),bulkAction(bulkImageData)})}}),$("body").on("click","small.krakenReset",function(e){e.preventDefault();var $resetButton=$(this),resetData={action:"kraken_reset"};resetData.id=$(this).data("id");var $spinner=$('<span class="resetSpinner"></span>');$resetButton.after($spinner);$.ajax({url:ajax_object.ajax_url,data:resetData,type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){"undefined"!==data.success&&$resetButton.closest(".kraked_size.column-kraked_size").hide().html(data.html).fadeIn().prev(".original_size.column-original_size").html(data.original_size)})}),$("body").on("click",".kraken-reset-all",function(e){e.preventDefault();var reset=confirm("This will immediately remove all Kraken metadata associated with your images. \n\nAre you sure you want to do this?");if(reset){var $resetButton=$(this);$resetButton.text("Resetting images, pleaes wait...").attr("disabled",!0);
|
2 |
-
|
3 |
-
var resetData={action:"kraken_reset_all"},$spinner=$('<span class="resetSpinner"></span>');$resetButton.after($spinner);{$.ajax({url:ajax_object.ajax_url,data:resetData,type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){$spinner.remove(),$resetButton.text("Your images have been reset.").removeAttr("disabled").removeClass("enabled")})}}}),$(".krakenAdvancedSettings h3").on("click",function(){var $rows=$(".kraken-advanced-settings"),$plusMinus=$(".kraken-plus-minus");$rows.is(":visible")?($rows.hide(),$plusMinus.removeClass("dashicons-arrow-down").addClass("dashicons-arrow-right")):($rows.show(),$plusMinus.removeClass("dashicons-arrow-right").addClass("dashicons-arrow-down"))}),$("body").on("click",".kraken_req",function(e){e.preventDefault();var $button=$(this),$parent=$(this).parent();data.id=$(this).data("id"),$button.text("Optimizing image...").attr("disabled",!0).css({opacity:.5}),$parent.find(".krakenSpinner").css("display","inline");$.ajax({url:ajax_object.ajax_url,data:data,type:"post",dataType:"json",timeout:36e4,context:$button}).done(requestSuccess).fail(requestFail).always(requestComplete)})});
|
1 |
+
!function(){function only_once(fn){var called=!1;return function(){if(called)throw new Error("Callback was already called.");called=!0,fn.apply(root,arguments)}}var root,previous_async,async={};root=this,null!=root&&(previous_async=root.async),async.noConflict=function(){return root.async=previous_async,async};var _each=function(arr,iterator){if(arr.forEach)return arr.forEach(iterator);for(var i=0;i<arr.length;i+=1)iterator(arr[i],i,arr)},_map=function(arr,iterator){if(arr.map)return arr.map(iterator);var results=[];return _each(arr,function(x,i,a){results.push(iterator(x,i,a))}),results},_reduce=function(arr,iterator,memo){return arr.reduce?arr.reduce(iterator,memo):(_each(arr,function(x,i,a){memo=iterator(memo,x,i,a)}),memo)},_keys=function(obj){if(Object.keys)return Object.keys(obj);var keys=[];for(var k in obj)obj.hasOwnProperty(k)&&keys.push(k);return keys};"undefined"!=typeof process&&process.nextTick?(async.nextTick=process.nextTick,"undefined"!=typeof setImmediate?async.setImmediate=function(fn){setImmediate(fn)}:async.setImmediate=async.nextTick):"function"==typeof setImmediate?(async.nextTick=function(fn){setImmediate(fn)},async.setImmediate=async.nextTick):(async.nextTick=function(fn){setTimeout(fn,0)},async.setImmediate=async.nextTick),async.each=function(arr,iterator,callback){if(callback=callback||function(){},!arr.length)return callback();var completed=0;_each(arr,function(x){iterator(x,only_once(function(err){err?(callback(err),callback=function(){}):(completed+=1,completed>=arr.length&&callback(null))}))})},async.forEach=async.each,async.eachSeries=function(arr,iterator,callback){if(callback=callback||function(){},!arr.length)return callback();var completed=0,iterate=function(){iterator(arr[completed],function(err){err?(callback(err),callback=function(){}):(completed+=1,completed>=arr.length?callback(null):iterate())})};iterate()},async.forEachSeries=async.eachSeries,async.eachLimit=function(arr,limit,iterator,callback){var fn=_eachLimit(limit);fn.apply(null,[arr,iterator,callback])},async.forEachLimit=async.eachLimit;var _eachLimit=function(limit){return function(arr,iterator,callback){if(callback=callback||function(){},!arr.length||0>=limit)return callback();var completed=0,started=0,running=0;!function replenish(){if(completed>=arr.length)return callback();for(;limit>running&&started<arr.length;)started+=1,running+=1,iterator(arr[started-1],function(err){err?(callback(err),callback=function(){}):(completed+=1,running-=1,completed>=arr.length?callback():replenish())})}()}},doParallel=function(fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[async.each].concat(args))}},doParallelLimit=function(limit,fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[_eachLimit(limit)].concat(args))}},doSeries=function(fn){return function(){var args=Array.prototype.slice.call(arguments);return fn.apply(null,[async.eachSeries].concat(args))}},_asyncMap=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(err,v){results[x.index]=v,callback(err)})},function(err){callback(err,results)})};async.map=doParallel(_asyncMap),async.mapSeries=doSeries(_asyncMap),async.mapLimit=function(arr,limit,iterator,callback){return _mapLimit(limit)(arr,iterator,callback)};var _mapLimit=function(limit){return doParallelLimit(limit,_asyncMap)};async.reduce=function(arr,memo,iterator,callback){async.eachSeries(arr,function(x,callback){iterator(memo,x,function(err,v){memo=v,callback(err)})},function(err){callback(err,memo)})},async.inject=async.reduce,async.foldl=async.reduce,async.reduceRight=function(arr,memo,iterator,callback){var reversed=_map(arr,function(x){return x}).reverse();async.reduce(reversed,memo,iterator,callback)},async.foldr=async.reduceRight;var _filter=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(v){v&&results.push(x),callback()})},function(err){callback(_map(results.sort(function(a,b){return a.index-b.index}),function(x){return x.value}))})};async.filter=doParallel(_filter),async.filterSeries=doSeries(_filter),async.select=async.filter,async.selectSeries=async.filterSeries;var _reject=function(eachfn,arr,iterator,callback){var results=[];arr=_map(arr,function(x,i){return{index:i,value:x}}),eachfn(arr,function(x,callback){iterator(x.value,function(v){v||results.push(x),callback()})},function(err){callback(_map(results.sort(function(a,b){return a.index-b.index}),function(x){return x.value}))})};async.reject=doParallel(_reject),async.rejectSeries=doSeries(_reject);var _detect=function(eachfn,arr,iterator,main_callback){eachfn(arr,function(x,callback){iterator(x,function(result){result?(main_callback(x),main_callback=function(){}):callback()})},function(err){main_callback()})};async.detect=doParallel(_detect),async.detectSeries=doSeries(_detect),async.some=function(arr,iterator,main_callback){async.each(arr,function(x,callback){iterator(x,function(v){v&&(main_callback(!0),main_callback=function(){}),callback()})},function(err){main_callback(!1)})},async.any=async.some,async.every=function(arr,iterator,main_callback){async.each(arr,function(x,callback){iterator(x,function(v){v||(main_callback(!1),main_callback=function(){}),callback()})},function(err){main_callback(!0)})},async.all=async.every,async.sortBy=function(arr,iterator,callback){async.map(arr,function(x,callback){iterator(x,function(err,criteria){err?callback(err):callback(null,{value:x,criteria:criteria})})},function(err,results){if(err)return callback(err);var fn=function(left,right){var a=left.criteria,b=right.criteria;return b>a?-1:a>b?1:0};callback(null,_map(results.sort(fn),function(x){return x.value}))})},async.auto=function(tasks,callback){callback=callback||function(){};var keys=_keys(tasks);if(!keys.length)return callback(null);var results={},listeners=[],addListener=function(fn){listeners.unshift(fn)},removeListener=function(fn){for(var i=0;i<listeners.length;i+=1)if(listeners[i]===fn)return void listeners.splice(i,1)},taskComplete=function(){_each(listeners.slice(0),function(fn){fn()})};addListener(function(){_keys(results).length===keys.length&&(callback(null,results),callback=function(){})}),_each(keys,function(k){var task=tasks[k]instanceof Function?[tasks[k]]:tasks[k],taskCallback=function(err){var args=Array.prototype.slice.call(arguments,1);if(args.length<=1&&(args=args[0]),err){var safeResults={};_each(_keys(results),function(rkey){safeResults[rkey]=results[rkey]}),safeResults[k]=args,callback(err,safeResults),callback=function(){}}else results[k]=args,async.setImmediate(taskComplete)},requires=task.slice(0,Math.abs(task.length-1))||[],ready=function(){return _reduce(requires,function(a,x){return a&&results.hasOwnProperty(x)},!0)&&!results.hasOwnProperty(k)};if(ready())task[task.length-1](taskCallback,results);else{var listener=function(){ready()&&(removeListener(listener),task[task.length-1](taskCallback,results))};addListener(listener)}})},async.waterfall=function(tasks,callback){if(callback=callback||function(){},tasks.constructor!==Array){var err=new Error("First argument to waterfall must be an array of functions");return callback(err)}if(!tasks.length)return callback();var wrapIterator=function(iterator){return function(err){if(err)callback.apply(null,arguments),callback=function(){};else{var args=Array.prototype.slice.call(arguments,1),next=iterator.next();args.push(next?wrapIterator(next):callback),async.setImmediate(function(){iterator.apply(null,args)})}}};wrapIterator(async.iterator(tasks))()};var _parallel=function(eachfn,tasks,callback){if(callback=callback||function(){},tasks.constructor===Array)eachfn.map(tasks,function(fn,callback){fn&&fn(function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),callback.call(null,err,args)})},callback);else{var results={};eachfn.each(_keys(tasks),function(k,callback){tasks[k](function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),results[k]=args,callback(err)})},function(err){callback(err,results)})}};async.parallel=function(tasks,callback){_parallel({map:async.map,each:async.each},tasks,callback)},async.parallelLimit=function(tasks,limit,callback){_parallel({map:_mapLimit(limit),each:_eachLimit(limit)},tasks,callback)},async.series=function(tasks,callback){if(callback=callback||function(){},tasks.constructor===Array)async.mapSeries(tasks,function(fn,callback){fn&&fn(function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),callback.call(null,err,args)})},callback);else{var results={};async.eachSeries(_keys(tasks),function(k,callback){tasks[k](function(err){var args=Array.prototype.slice.call(arguments,1);args.length<=1&&(args=args[0]),results[k]=args,callback(err)})},function(err){callback(err,results)})}},async.iterator=function(tasks){var makeCallback=function(index){var fn=function(){return tasks.length&&tasks[index].apply(null,arguments),fn.next()};return fn.next=function(){return index<tasks.length-1?makeCallback(index+1):null},fn};return makeCallback(0)},async.apply=function(fn){var args=Array.prototype.slice.call(arguments,1);return function(){return fn.apply(null,args.concat(Array.prototype.slice.call(arguments)))}};var _concat=function(eachfn,arr,fn,callback){var r=[];eachfn(arr,function(x,cb){fn(x,function(err,y){r=r.concat(y||[]),cb(err)})},function(err){callback(err,r)})};async.concat=doParallel(_concat),async.concatSeries=doSeries(_concat),async.whilst=function(test,iterator,callback){test()?iterator(function(err){return err?callback(err):void async.whilst(test,iterator,callback)}):callback()},async.doWhilst=function(iterator,test,callback){iterator(function(err){return err?callback(err):void(test()?async.doWhilst(iterator,test,callback):callback())})},async.until=function(test,iterator,callback){test()?callback():iterator(function(err){return err?callback(err):void async.until(test,iterator,callback)})},async.doUntil=function(iterator,test,callback){iterator(function(err){return err?callback(err):void(test()?callback():async.doUntil(iterator,test,callback))})},async.queue=function(worker,concurrency){function _insert(q,data,pos,callback){data.constructor!==Array&&(data=[data]),_each(data,function(task){var item={data:task,callback:"function"==typeof callback?callback:null};pos?q.tasks.unshift(item):q.tasks.push(item),q.saturated&&q.tasks.length===concurrency&&q.saturated(),async.setImmediate(q.process)})}void 0===concurrency&&(concurrency=1);var workers=0,q={tasks:[],concurrency:concurrency,saturated:null,empty:null,drain:null,push:function(data,callback){_insert(q,data,!1,callback)},unshift:function(data,callback){_insert(q,data,!0,callback)},process:function(){if(workers<q.concurrency&&q.tasks.length){var task=q.tasks.shift();q.empty&&0===q.tasks.length&&q.empty(),workers+=1;var next=function(){workers-=1,task.callback&&task.callback.apply(task,arguments),q.drain&&q.tasks.length+workers===0&&q.drain(),q.process()},cb=only_once(next);worker(task.data,cb)}},length:function(){return q.tasks.length},running:function(){return workers}};return q},async.cargo=function(worker,payload){var working=!1,tasks=[],cargo={tasks:tasks,payload:payload,saturated:null,empty:null,drain:null,push:function(data,callback){data.constructor!==Array&&(data=[data]),_each(data,function(task){tasks.push({data:task,callback:"function"==typeof callback?callback:null}),cargo.saturated&&tasks.length===payload&&cargo.saturated()}),async.setImmediate(cargo.process)},process:function process(){if(!working){if(0===tasks.length)return void(cargo.drain&&cargo.drain());var ts="number"==typeof payload?tasks.splice(0,payload):tasks.splice(0),ds=_map(ts,function(task){return task.data});cargo.empty&&cargo.empty(),working=!0,worker(ds,function(){working=!1;var args=arguments;_each(ts,function(data){data.callback&&data.callback.apply(null,args)}),process()})}},length:function(){return tasks.length},running:function(){return working}};return cargo};var _console_fn=function(name){return function(fn){var args=Array.prototype.slice.call(arguments,1);fn.apply(null,args.concat([function(err){var args=Array.prototype.slice.call(arguments,1);"undefined"!=typeof console&&(err?console.error&&console.error(err):console[name]&&_each(args,function(x){console[name](x)}))}]))}};async.log=_console_fn("log"),async.dir=_console_fn("dir"),async.memoize=function(fn,hasher){var memo={},queues={};hasher=hasher||function(x){return x};var memoized=function(){var args=Array.prototype.slice.call(arguments),callback=args.pop(),key=hasher.apply(null,args);key in memo?callback.apply(null,memo[key]):key in queues?queues[key].push(callback):(queues[key]=[callback],fn.apply(null,args.concat([function(){memo[key]=arguments;var q=queues[key];delete queues[key];for(var i=0,l=q.length;l>i;i++)q[i].apply(null,arguments)}])))};return memoized.memo=memo,memoized.unmemoized=fn,memoized},async.unmemoize=function(fn){return function(){return(fn.unmemoized||fn).apply(null,arguments)}},async.times=function(count,iterator,callback){for(var counter=[],i=0;count>i;i++)counter.push(i);return async.map(counter,iterator,callback)},async.timesSeries=function(count,iterator,callback){for(var counter=[],i=0;count>i;i++)counter.push(i);return async.mapSeries(counter,iterator,callback)},async.compose=function(){var fns=Array.prototype.reverse.call(arguments);return function(){var that=this,args=Array.prototype.slice.call(arguments),callback=args.pop();async.reduce(fns,args,function(newargs,fn,cb){fn.apply(that,newargs.concat([function(){var err=arguments[0],nextargs=Array.prototype.slice.call(arguments,1);cb(err,nextargs)}]))},function(err,results){callback.apply(that,[err].concat(results))})}};var _applyEach=function(eachfn,fns){var go=function(){var that=this,args=Array.prototype.slice.call(arguments),callback=args.pop();return eachfn(fns,function(fn,cb){fn.apply(that,args.concat([cb]))},callback)};if(arguments.length>2){var args=Array.prototype.slice.call(arguments,2);return go.apply(this,args)}return go};async.applyEach=doParallel(_applyEach),async.applyEachSeries=doSeries(_applyEach),async.forever=function(fn,callback){function next(err){if(err){if(callback)return callback(err);throw err}fn(next)}next()},"undefined"!=typeof define&&define.amd?define([],function(){return async}):"undefined"!=typeof module&&module.exports?module.exports=async:root.async=async}(),function($){function maybeCall(thing,ctx){return"function"==typeof thing?thing.call(ctx):thing}function isElementInDOM(ele){for(;ele=ele.parentNode;)if(ele==document)return!0;return!1}function Tipsy(element,options){this.$element=$(element),this.options=options,this.enabled=!0,this.fixTitle()}Tipsy.prototype={show:function(){var title=this.getTitle();if(title&&this.enabled){var $tip=this.tip();$tip.find(".tipsy-inner")[this.options.html?"html":"text"](title),$tip[0].className="tipsy",$tip.remove().css({top:0,left:0,visibility:"hidden",display:"block"}).prependTo(document.body);var tp,pos=$.extend({},this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight}),actualWidth=$tip[0].offsetWidth,actualHeight=$tip[0].offsetHeight,gravity=maybeCall(this.options.gravity,this.$element[0]);switch(gravity.charAt(0)){case"n":tp={top:pos.top+pos.height+this.options.offset,left:pos.left+pos.width/2-actualWidth/2};break;case"s":tp={top:pos.top-actualHeight-this.options.offset,left:pos.left+pos.width/2-actualWidth/2};break;case"e":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left-actualWidth-this.options.offset};break;case"w":tp={top:pos.top+pos.height/2-actualHeight/2,left:pos.left+pos.width+this.options.offset}}2==gravity.length&&("w"==gravity.charAt(1)?tp.left=pos.left+pos.width/2-15:tp.left=pos.left+pos.width/2-actualWidth+15),$tip.css(tp).addClass("tipsy-"+gravity),$tip.find(".tipsy-arrow")[0].className="tipsy-arrow tipsy-arrow-"+gravity.charAt(0),this.options.className&&$tip.addClass(maybeCall(this.options.className,this.$element[0])),this.options.fade?$tip.stop().css({opacity:0,display:"block",visibility:"visible"}).animate({opacity:this.options.opacity}):$tip.css({visibility:"visible",opacity:this.options.opacity})}},hide:function(){this.options.fade?this.tip().stop().fadeOut(function(){$(this).remove()}):this.tip().remove()},fixTitle:function(){var $e=this.$element;($e.attr("title")||"string"!=typeof $e.attr("original-title"))&&$e.attr("original-title",$e.attr("title")||"").removeAttr("title")},getTitle:function(){var title,$e=this.$element,o=this.options;this.fixTitle();var title,o=this.options;return"string"==typeof o.title?title=$e.attr("title"==o.title?"original-title":o.title):"function"==typeof o.title&&(title=o.title.call($e[0])),title=(""+title).replace(/(^\s*|\s*$)/,""),title||o.fallback},tip:function(){return this.$tip||(this.$tip=$('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>'),this.$tip.data("tipsy-pointee",this.$element[0])),this.$tip},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled}},$.fn.tipsy=function(options){function get(ele){var tipsy=$.data(ele,"tipsy");return tipsy||(tipsy=new Tipsy(ele,$.fn.tipsy.elementOptions(ele,options)),$.data(ele,"tipsy",tipsy)),tipsy}function enter(){var tipsy=get(this);tipsy.hoverState="in",0==options.delayIn?tipsy.show():(tipsy.fixTitle(),setTimeout(function(){"in"==tipsy.hoverState&&tipsy.show()},options.delayIn))}function leave(){var tipsy=get(this);tipsy.hoverState="out",0==options.delayOut?tipsy.hide():setTimeout(function(){"out"==tipsy.hoverState&&tipsy.hide()},options.delayOut)}if(options===!0)return this.data("tipsy");if("string"==typeof options){var tipsy=this.data("tipsy");return tipsy&&tipsy[options](),this}if(options=$.extend({},$.fn.tipsy.defaults,options),options.live||this.each(function(){get(this)}),"manual"!=options.trigger){var binder=options.live?"live":"bind",eventIn="hover"==options.trigger?"mouseenter":"focus",eventOut="hover"==options.trigger?"mouseleave":"blur";this[binder](eventIn,enter)[binder](eventOut,leave)}return this},$.fn.tipsy.defaults={className:null,delayIn:0,delayOut:0,fade:!1,fallback:"",gravity:"n",html:!1,live:!1,offset:0,opacity:.8,title:"title",trigger:"hover"},$.fn.tipsy.revalidate=function(){$(".tipsy").each(function(){var pointee=$.data(this,"tipsy-pointee");pointee&&isElementInDOM(pointee)||$(this).remove()})},$.fn.tipsy.elementOptions=function(ele,options){return $.metadata?$.extend({},options,$(ele).metadata()):options},$.fn.tipsy.autoNS=function(){return $(this).offset().top>$(document).scrollTop()+$(window).height()/2?"s":"n"},$.fn.tipsy.autoWE=function(){return $(this).offset().left>$(document).scrollLeft()+$(window).width()/2?"e":"w"},$.fn.tipsy.autoBounds=function(margin,prefer){return function(){var dir={ns:prefer[0],ew:prefer.length>1?prefer[1]:!1},boundTop=$(document).scrollTop()+margin,boundLeft=$(document).scrollLeft()+margin,$this=$(this);return $this.offset().top<boundTop&&(dir.ns="n"),$this.offset().left<boundLeft&&(dir.ew="w"),$(window).width()+$(document).scrollLeft()-$this.offset().left<margin&&(dir.ew="e"),$(window).height()+$(document).scrollTop()-$this.offset().top<margin&&(dir.ns="s"),dir.ns+(dir.ew?dir.ew:"")}}}(jQuery),function($){var current=null;$.kmodal=function(el,options){$.kmodal.close();var remove,target;if(this.$body=$("body"),this.options=$.extend({},$.kmodal.defaults,options),this.options.doFade=!isNaN(parseInt(this.options.fadeDuration,10)),el.is("a"))if(target=el.attr("href"),/^#/.test(target)){if(this.$elm=$(target),1!==this.$elm.length)return null;this.open()}else this.$elm=$("<div>"),this.$body.append(this.$elm),remove=function(event,modal){modal.elm.remove()},this.showSpinner(),el.trigger($.kmodal.AJAX_SEND),$.get(target).done(function(html){current&&(el.trigger($.kmodal.AJAX_SUCCESS),current.$elm.empty().append(html).on($.kmodal.CLOSE,remove),current.hideSpinner(),current.open(),el.trigger($.kmodal.AJAX_COMPLETE))}).fail(function(){el.trigger($.kmodal.AJAX_FAIL),current.hideSpinner(),el.trigger($.kmodal.AJAX_COMPLETE)});else this.$elm=el,this.$body.append(this.$elm),this.open()},$.kmodal.prototype={constructor:$.kmodal,open:function(){var m=this;this.options.doFade?(this.block(),setTimeout(function(){m.show()},this.options.fadeDuration*this.options.fadeDelay)):(this.block(),this.show()),this.options.escapeClose&&$(document).on("keydown.modal",function(event){27==event.which&&$.kmodal.close()}),this.options.clickClose&&this.blocker.click($.kmodal.close)},close:function(){this.unblock(),this.hide(),$(document).off("keydown.modal")},block:function(){var initialOpacity=this.options.doFade?0:this.options.opacity;this.$elm.trigger($.kmodal.BEFORE_BLOCK,[this._ctx()]),this.blocker=$('<div class="jquery-modal blocker"></div>').css({top:0,right:0,bottom:0,left:0,width:"100%",height:"100%",position:"fixed",zIndex:this.options.zIndex,background:this.options.overlay,opacity:initialOpacity}),this.$body.append(this.blocker),this.options.doFade&&this.blocker.animate({opacity:this.options.opacity},this.options.fadeDuration),this.$elm.trigger($.kmodal.BLOCK,[this._ctx()])},unblock:function(){this.options.doFade?this.blocker.fadeOut(this.options.fadeDuration,function(){$(this).remove()}):this.blocker.remove()},show:function(){this.$elm.trigger($.kmodal.BEFORE_OPEN,[this._ctx()]),this.options.showClose&&(this.closeButton=$('<a href="#close-modal" rel="modal:close" class="close-modal '+this.options.closeClass+'">'+this.options.closeText+"</a>"),this.$elm.append(this.closeButton)),this.$elm.addClass(this.options.modalClass+" current"),this.center(),this.options.doFade?this.$elm.fadeIn(this.options.fadeDuration):this.$elm.show(),this.$elm.trigger($.kmodal.OPEN,[this._ctx()])},hide:function(){this.$elm.trigger($.kmodal.BEFORE_CLOSE,[this._ctx()]),this.closeButton&&this.closeButton.remove(),this.$elm.removeClass("current"),this.options.doFade?this.$elm.fadeOut(this.options.fadeDuration):this.$elm.hide(),this.$elm.trigger($.kmodal.CLOSE,[this._ctx()])},showSpinner:function(){this.options.showSpinner&&(this.spinner=this.spinner||$('<div class="'+this.options.modalClass+'-spinner"></div>').append(this.options.spinnerHtml),this.$body.append(this.spinner),this.spinner.show())},hideSpinner:function(){this.spinner&&this.spinner.remove()},center:function(){this.$elm.css({position:"fixed",top:"50%",left:"50%",marginTop:-(this.$elm.outerHeight()/2),marginLeft:-(this.$elm.outerWidth()/2),zIndex:this.options.zIndex+1})},_ctx:function(){return{elm:this.$elm,blocker:this.blocker,options:this.options}}},$.kmodal.prototype.resize=$.kmodal.prototype.center,$.kmodal.close=function(event){if(current){event&&event.preventDefault(),current.close();var that=current.$elm;return current=null,that}},$.kmodal.resize=function(){current&¤t.resize()},$.kmodal.isActive=function(){return current?!0:!1},$.kmodal.defaults={overlay:"#000",opacity:.75,zIndex:1,escapeClose:!0,clickClose:!0,closeText:"Close",closeClass:"",modalClass:"kraken-modal",spinnerHtml:null,showSpinner:!0,showClose:!0,fadeDuration:null,fadeDelay:1},$.kmodal.BEFORE_BLOCK="modal:before-block",$.kmodal.BLOCK="modal:block",$.kmodal.BEFORE_OPEN="modal:before-open",$.kmodal.OPEN="modal:open",$.kmodal.BEFORE_CLOSE="modal:before-close",$.kmodal.CLOSE="modal:close",$.kmodal.AJAX_SEND="modal:ajax:send",$.kmodal.AJAX_SUCCESS="modal:ajax:success",$.kmodal.AJAX_FAIL="modal:ajax:fail",$.kmodal.AJAX_COMPLETE="modal:ajax:complete",$.fn.kmodal=function(options){return 1===this.length&&(current=new $.kmodal(this,options)),this},$(document).on("click.modal",'a[rel="modal:close"]',$.kmodal.close),$(document).on("click.modal",'a[rel="modal:open"]',function(event){event.preventDefault(),$(this).kmodal()})}(jQuery),jQuery(document).ready(function($){var tipsySettings={gravity:"e",html:!0,trigger:"manual",className:function(){return"tipsy-"+$(this).data("id")},title:function(){return activeId=$(this).data("id"),$(this).attr("original-title")}};$(".krakenWhatsThis").tipsy({fade:!0,gravity:"w"}),$(".krakenError").tipsy({fade:!0,gravity:"e"});var data={action:"kraken_request"},errorTpl='<div class="krakenErrorWrap"><a class="krakenError">Failed! Hover here</a></div>',$btnApplyBulkAction=$("#doaction"),$btnApplyBulkAction2=$("#doaction2"),$topBulkActionDropdown=$(".tablenav.top .bulkactions select[name='action']"),$bottomBulkActionDropdown=$(".tablenav.bottom .bulkactions select[name='action2']"),requestSuccess=function(data,textStatus,jqXHR){var $button=$(this),$parent=$(this).closest(".kraken-wrap, .buttonWrap"),$cell=$(this).closest("td");if(data.html){$button.text("Image optimized");var originalSize=(data.type,data.original_size),$originalSizeColumn=$(this).parent().prev("td.original_size");$parent.fadeOut("fast",function(){$cell.find(".noSavings, .krakenErrorWrap").remove(),$cell.html(data.html),$cell.find(".kraken-item-details").tipsy(tipsySettings),$originalSizeColumn.html(originalSize),$parent.remove()})}else if(data.error){var $error=$(errorTpl).attr("title",data.error);$parent.closest("td").find(".krakenErrorWrap").remove(),$parent.after($error),$error.tipsy({fade:!0,gravity:"e"}),$button.text("Retry request").removeAttr("disabled").css({opacity:1})}},requestFail=function(jqXHR,textStatus,errorThrown){$(this).removeAttr("disabled")},requestComplete=function(jqXHR,textStatus,errorThrown){$(this).removeAttr("disabled"),$(this).parent().find(".krakenSpinner").css("display","none")},opts='<option value="kraken-bulk-lossy">Krak \'em all</option>';$topBulkActionDropdown.find("option:last-child").before(opts),$bottomBulkActionDropdown.find("option:last-child").before(opts);var getBulkImageData=function(){var $rows=$("tr[id^='post-']"),$row=null,postId=0,$krakBtn=null,btnData={},originalSize="",rv=[];return $rows.each(function(){$row=$(this),postId=this.id.replace(/^\D+/g,""),$row.find("input[type='checkbox'][value='"+postId+"']:checked").length&&($krakBtn=$row.find(".kraken_req"),$krakBtn.length&&(btnData=$krakBtn.data(),originalSize=$.trim($row.find("td.original_size").text()),btnData.originalSize=originalSize,rv.push(btnData)))}),rv},bulkModalOptions={zIndex:4,escapeClose:!0,clickClose:!1,closeText:"close",showClose:!1},renderBulkImageSummary=function(bulkImageData){var setting=kraken_settings.api_lossy,nImages=bulkImageData.length,header='<p class="krakenBulkHeader">Kraken Bulk Image Optimization <span class="close-kraken-bulk">×</span></p>',krakEmAll='<button class="kraken_req_bulk">Krak \'em all</button>',typeRadios='<div class="radiosWrap"><p>Choose optimization mode:</p><label><input type="radio" id="kraken-bulk-type-lossy" value="Lossy" name="kraken-bulk-type"/>Intelligent Lossy</label> <label><input type="radio" id="kraken-bulk-type-lossless" value="Lossless" name="kraken-bulk-type"/>Lossless</label></div>',$modal=$('<div id="kraken-bulk-modal" class="kraken-modal"></div>').html(header).append(typeRadios).append('<p class="the-following">The following <strong>'+nImages+'</strong> images will be optimized by Kraken.io using the <strong class="bulkSetting">'+setting+"</strong> setting:</p>").appendTo("body").kmodal(bulkModalOptions).bind($.kmodal.BEFORE_CLOSE,function(event,modal){}).bind($.kmodal.OPEN,function(event,modal){}).bind($.kmodal.CLOSE,function(event,modal){$("#kraken-bulk-modal").remove()}).css({top:"10px",marginTop:"40px"});"lossy"===setting?$("#kraken-bulk-type-lossy").attr("checked",!0):$("#kraken-bulk-type-lossless").attr("checked",!0),$bulkSettingSpan=$(".bulkSetting"),$("input[name='kraken-bulk-type']").change(function(){var text="kraken-bulk-type-lossy"===this.id?"lossy":"lossless";$bulkSettingSpan.text(text)}),$(".jquery-modal.blocker").click(function(e){return!1}),$("#menu-media ul.wp-submenu").css({"z-index":1});var $table=$('<table id="kraken-bulk"></table>'),$headerRow=$('<tr class="kraken-bulk-header"><td>File Name</td><td style="width:120px">Original Size</td><td style="width:120px">Kraken.io Stats</td></tr>');$table.append($headerRow),$.each(bulkImageData,function(index,element){$table.append('<tr class="kraken-item-row" data-krakenbulkid="'+element.id+'"><td class="kraken-bulk-filename">'+element.filename+'</td><td class="kraken-originalsize">'+element.originalSize+'</td><td class="kraken-krakedsize"><span class="krakenBulkSpinner hidden"></span></td></tr>')}),$modal.append($table).append(krakEmAll),$(".close-kraken-bulk").click(function(){$.kmodal.close()}),nImages||$(".kraken_req_bulk").attr("disabled",!0).css({opacity:.5})},bulkAction=function(bulkImageData){$bulkTable=$("#kraken-bulk");var jqxhr=null,q=async.queue(function(task,callback){var id=task.id,$row=(task.filename,$bulkTable.find("tr[data-krakenbulkid='"+id+"']")),$krakedSizeColumn=$row.find(".kraken-krakedsize"),$spinner=$krakedSizeColumn.find(".krakenBulkSpinner").css({display:"inline-block"}),$savingsPercentColumn=$row.find(".kraken-savingsPercent"),$savingsBytesColumn=$row.find(".kraken-savings");jqxhr=$.ajax({url:ajax_object.ajax_url,data:{action:"kraken_request",id:id,type:$("input[name='kraken-bulk-type']:checked").val().toLowerCase(),origin:"bulk_optimizer"},type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){if(data.success&&"undefined"==typeof data.message){var originalSize=(data.type,data.original_size),savingsPercent=(data.html,data.savings_percent),savingsBytes=data.saved_bytes;$krakedSizeColumn.html(data.html),$krakedSizeColumn.find(".kraken-item-details").remove(),$savingsPercentColumn.text(savingsPercent),$savingsBytesColumn.text(savingsBytes);var $button=$("button[id='krakenid-"+id+"']"),$parent=$button.parent(),$cell=$button.closest("td"),$originalSizeColumn=$button.parent().prev("td.original_size");$parent.fadeOut("fast",function(){$cell.find(".noSavings, .krakenErrorWrap").remove(),$cell.empty().html(data.html),$cell.find(".kraken-item-details").tipsy(tipsySettings),$originalSizeColumn.html(originalSize),$parent.remove()})}else data.error&&"This image can not be optimized any further"===data.error&&$krakedSizeColumn.text("No savings found.")}).fail(function(){}).always(function(){$spinner.css({display:"none"}),callback()})},kraken_settings.bulk_async_limit);q.drain=function(){$(".kraken_req_bulk").removeAttr("disabled").css({opacity:1}).text("Done").unbind("click").click(function(){$.kmodal.close()})},q.push(bulkImageData,function(err){})};$btnApplyBulkAction.add($btnApplyBulkAction2).click(function(e){if("kraken-bulk-lossy"===$(this).prev("select").val()){e.preventDefault();var bulkImageData=getBulkImageData();renderBulkImageSummary(bulkImageData),$(".kraken_req_bulk").click(function(e){e.preventDefault(),$(this).attr("disabled",!0).css({opacity:.5}),bulkAction(bulkImageData)})}});var activeId=null;$(".kraken-item-details").tipsy(tipsySettings);$("body").on("click",".kraken-item-details",function(e){var id=$(this).data("id");return $(".tipsy").remove(),id==activeId?(activeId=null,void $(this).text("Show details")):($(".kraken-item-details").text("Show details"),$(this).tipsy("show"),void $(this).text("Hide details"))}),$("body").on("click",function(e){var $t=$(e.target);$t.hasClass("tipsy")||$t.closest(".tipsy").length||$t.hasClass("kraken-item-details")||(activeId=null,$(".kraken-item-details").text("Show details"),$(".tipsy").remove())}),$("body").on("click","small.krakenReset",function(e){e.preventDefault();var $resetButton=$(this),resetData={action:"kraken_reset"};resetData.id=$(this).data("id"),$row=$("#post-"+resetData.id).find(".kraked_size");var $spinner=$('<span class="resetSpinner"></span>');$resetButton.after($spinner);$.ajax({url:ajax_object.ajax_url,data:resetData,type:"post",dataType:"json",timeout:36e4
|
2 |
+
}).done(function(data,textStatus,jqXHR){"undefined"!==data.success&&($row.hide().html(data.html).fadeIn().prev(".original_size.column-original_size").html(data.original_size),$(".tipsy").remove())})}),$("body").on("click",".kraken-reset-all",function(e){e.preventDefault();var reset=confirm("This will immediately remove all Kraken metadata associated with your images. \n\nAre you sure you want to do this?");if(reset){var $resetButton=$(this);$resetButton.text("Resetting images, pleaes wait...").attr("disabled",!0);var resetData={action:"kraken_reset_all"},$spinner=$('<span class="resetSpinner"></span>');$resetButton.after($spinner);{$.ajax({url:ajax_object.ajax_url,data:resetData,type:"post",dataType:"json",timeout:36e4}).done(function(data,textStatus,jqXHR){$spinner.remove(),$resetButton.text("Your images have been reset.").removeAttr("disabled").removeClass("enabled")})}}}),$(".krakenAdvancedSettings h3").on("click",function(){var $rows=$(".kraken-advanced-settings"),$plusMinus=$(".kraken-plus-minus");$rows.is(":visible")?($rows.hide(),$plusMinus.removeClass("dashicons-arrow-down").addClass("dashicons-arrow-right")):($rows.show(),$plusMinus.removeClass("dashicons-arrow-right").addClass("dashicons-arrow-down"))}),$("body").on("click",".kraken_req",function(e){e.preventDefault();var $button=$(this),$parent=$(this).parent();data.id=$(this).data("id"),$button.text("Optimizing image...").attr("disabled",!0).css({opacity:.5}),$parent.find(".krakenSpinner").css("display","inline");$.ajax({url:ajax_object.ajax_url,data:data,type:"post",dataType:"json",timeout:36e4,context:$button}).done(requestSuccess).fail(requestFail).always(requestComplete)})});
|
|
kraken.php
CHANGED
@@ -21,8 +21,8 @@
|
|
21 |
* Plugin URI: http://wordpress.org/plugins/kraken-image-optimizer/
|
22 |
* Description: This plugin allows you to optimize your WordPress images through the Kraken API, the world's most advanced image optimization solution.
|
23 |
* Author: Karim Salman
|
24 |
-
* Version: 2.
|
25 |
-
* Stable Tag: 2.
|
26 |
* Author URI: https://kraken.io
|
27 |
* License GPL2
|
28 |
*/
|
@@ -41,7 +41,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
41 |
|
42 |
private $optimization_type = 'lossy';
|
43 |
|
44 |
-
public static $kraken_plugin_version = '2.
|
45 |
|
46 |
function __construct() {
|
47 |
$plugin_dir_path = dirname( __FILE__ );
|
@@ -50,22 +50,37 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
50 |
$this->optimization_type = $this->kraken_settings['api_lossy'];
|
51 |
add_action( 'admin_enqueue_scripts', array( &$this, 'my_enqueue' ) );
|
52 |
add_action( 'wp_ajax_kraken_reset', array( &$this, 'kraken_media_library_reset' ) );
|
|
|
53 |
add_action( 'wp_ajax_kraken_request', array( &$this, 'kraken_media_library_ajax_callback' ) );
|
54 |
add_action( 'wp_ajax_kraken_reset_all', array( &$this, 'kraken_media_library_reset_all' ) );
|
55 |
add_action( 'manage_media_custom_column', array( &$this, 'fill_media_columns' ), 10, 2 );
|
56 |
add_filter( 'manage_media_columns', array( &$this, 'add_media_columns') );
|
57 |
add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array( &$this, 'add_settings_link' ) );
|
|
|
58 |
if ( ( !empty( $this->kraken_settings ) && !empty( $this->kraken_settings['auto_optimize'] ) ) || !isset( $this->kraken_settings['auto_optimize'] ) ) {
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
62 |
-
|
63 |
}
|
64 |
|
65 |
function kraken_menu() {
|
66 |
add_options_page( 'Kraken Image Optimizer Settings', 'Kraken.io', 'manage_options', 'wp-krakenio', array( &$this, 'kraken_settings_page' ) );
|
67 |
}
|
68 |
|
|
|
|
|
|
|
69 |
|
70 |
function add_settings_link ( $links ) {
|
71 |
$mylinks = array(
|
@@ -74,9 +89,8 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
74 |
return array_merge( $links, $mylinks );
|
75 |
}
|
76 |
|
|
|
77 |
|
78 |
-
function kraken_settings_page() {
|
79 |
-
|
80 |
if ( !empty( $_POST ) ) {
|
81 |
$options = $_POST['_kraken_options'];
|
82 |
$result = $this->validate_options( $options );
|
@@ -86,12 +100,20 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
86 |
$settings = get_option( '_kraken_options' );
|
87 |
$lossy = isset( $settings['api_lossy'] ) ? $settings['api_lossy'] : 'lossy';
|
88 |
$auto_optimize = isset( $settings['auto_optimize'] ) ? $settings['auto_optimize'] : 1;
|
89 |
-
|
90 |
$api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
|
91 |
$api_secret = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
|
92 |
-
|
93 |
$show_reset = isset( $settings['show_reset'] ) ? $settings['show_reset'] : 0;
|
94 |
$bulk_async_limit = isset( $settings['bulk_async_limit'] ) ? $settings['bulk_async_limit'] : 4;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
$status = $this->get_api_status( $api_key, $api_secret );
|
97 |
|
@@ -138,47 +160,149 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
138 |
</td>
|
139 |
</tr>
|
140 |
<tr>
|
141 |
-
<th scope="row">
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
<td>
|
143 |
<input type="radio" id="kraken_lossy" name="_kraken_options[api_lossy]" value="lossy" <?php checked( 'lossy', $lossy, true ); ?>/>
|
144 |
-
<label for="kraken_lossy">Lossy</label>
|
145 |
<input style="margin-left:10px;" type="radio" id="kraken_lossless" name="_kraken_options[api_lossy]" value="lossless" <?php checked( 'lossless', $lossy, true ) ?>/>
|
146 |
<label for="kraken_lossless">Lossless</label>
|
147 |
</td>
|
148 |
</tr>
|
149 |
-
<tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
<th scope="row">Automatically optimize uploads:</th>
|
151 |
<td>
|
152 |
<input type="checkbox" id="auto_optimize" name="_kraken_options[auto_optimize]" value="1" <?php checked( 1, $auto_optimize, true ); ?>/>
|
153 |
</td>
|
154 |
-
</tr>
|
155 |
-
<tr>
|
156 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
<td>
|
158 |
-
<?php
|
159 |
</td>
|
160 |
</tr>
|
161 |
-
<tr>
|
162 |
-
<td
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
</tr>
|
164 |
<tr class="kraken-advanced-settings">
|
165 |
<td colspan="2" class="krakenAdvancedSettingsDescription"><small>We recommend that you leave these settings at their default values</td>
|
166 |
</tr>
|
167 |
-
|
168 |
-
<th scope="row">
|
169 |
-
|
170 |
-
|
171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
<td>
|
173 |
<input type="checkbox" id="kraken_show_reset" name="_kraken_options[show_reset]" value="1" <?php checked( 1, $show_reset, true ); ?>/>
|
174 |
<span class="kraken-reset-all enabled">Reset All Images</span>
|
175 |
</td>
|
176 |
</tr>
|
177 |
-
<tr class="
|
178 |
-
<
|
179 |
-
|
180 |
-
|
181 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
<td>
|
183 |
<select name="_kraken_options[bulk_async_limit]">
|
184 |
<?php foreach ( range(1, 10) as $number ) { ?>
|
@@ -188,7 +312,15 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
188 |
<?php } ?>
|
189 |
</select>
|
190 |
</td>
|
191 |
-
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
</tbody>
|
193 |
</table>
|
194 |
<input type="submit" name="kraken_save" id="kraken_save" class="button button-primary" value="Save All"/>
|
@@ -201,8 +333,18 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
201 |
$error = array();
|
202 |
$valid['api_lossy'] = $input['api_lossy'];
|
203 |
$valid['auto_optimize'] = isset( $input['auto_optimize'] )? 1 : 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
$valid['show_reset'] = isset( $input['show_reset'] ) ? 1 : 0;
|
205 |
$valid['bulk_async_limit'] = isset( $input['bulk_async_limit'] ) ? $input['bulk_async_limit'] : 4;
|
|
|
|
|
|
|
206 |
|
207 |
if ( $valid['show_reset'] ) {
|
208 |
$valid['show_reset'] = $input['show_reset'];
|
@@ -240,6 +382,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
240 |
}
|
241 |
|
242 |
function my_enqueue( $hook ) {
|
|
|
243 |
if ( $hook == 'options-media.php' || $hook == 'upload.php' || $hook == 'settings_page_wp-krakenio' ) {
|
244 |
wp_enqueue_script( 'jquery' );
|
245 |
if ( KRAKEN_DEV_MODE === true ) {
|
@@ -271,152 +414,227 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
271 |
return false;
|
272 |
}
|
273 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
/**
|
275 |
* Handles optimizing already-uploaded images in the Media Library
|
276 |
*/
|
277 |
function kraken_media_library_ajax_callback() {
|
278 |
-
|
279 |
$image_id = (int) $_POST['id'];
|
280 |
$type = false;
|
|
|
281 |
if ( isset( $_POST['type'] ) ) {
|
282 |
$type = $_POST['type'];
|
|
|
283 |
}
|
284 |
|
285 |
$this->id = $image_id;
|
286 |
|
287 |
if ( wp_attachment_is_image( $image_id ) ) {
|
288 |
|
289 |
-
$image_path = get_attached_file( $image_id );
|
290 |
$settings = $this->kraken_settings;
|
|
|
|
|
|
|
291 |
$api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
|
292 |
$api_secret = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
|
293 |
|
294 |
-
$
|
295 |
|
296 |
-
if ( $
|
297 |
-
$
|
298 |
-
update_post_meta( $image_id, '_kraken_size', $
|
299 |
-
echo json_encode( array( 'error' => $
|
300 |
exit;
|
301 |
}
|
302 |
|
303 |
-
if (
|
304 |
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
|
|
311 |
|
312 |
-
|
|
|
313 |
|
314 |
-
|
|
|
|
|
315 |
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
$kv['success'] = true;
|
324 |
-
$kv['meta'] = wp_get_attachment_metadata( $image_id );
|
325 |
-
$saved_bytes = (int) $kv['saved_bytes'];
|
326 |
|
327 |
-
|
|
|
|
|
|
|
328 |
|
329 |
-
|
330 |
-
$image_data = wp_get_attachment_metadata( $image_id );
|
331 |
-
$this->optimize_thumbnails( $image_data );
|
332 |
|
333 |
-
|
334 |
-
|
|
|
335 |
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
echo json_encode( $kv );
|
343 |
-
} else {
|
344 |
-
echo json_encode( array( 'error' => 'Could not overwrite original file. Please ensure that your files are writable by plugins.' ) );
|
345 |
-
exit;
|
346 |
-
}
|
347 |
|
348 |
-
|
|
|
349 |
|
350 |
-
|
351 |
-
|
|
|
|
|
|
|
|
|
352 |
|
353 |
-
|
354 |
-
|
355 |
-
|
|
|
|
|
|
|
|
|
356 |
|
357 |
-
|
358 |
-
|
359 |
-
|
|
|
|
|
|
|
360 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
|
362 |
-
|
|
|
363 |
|
364 |
-
|
365 |
-
|
|
|
366 |
}
|
367 |
-
|
|
|
|
|
368 |
}
|
369 |
}
|
370 |
-
|
371 |
}
|
372 |
|
|
|
|
|
|
|
373 |
/**
|
374 |
* Handles optimizing images uploaded through any of the media uploaders.
|
375 |
*/
|
376 |
function kraken_media_uploader_callback( $image_id ) {
|
|
|
377 |
$this->id = $image_id;
|
378 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
if ( wp_attachment_is_image( $image_id ) ) {
|
380 |
|
381 |
-
$settings = $this->kraken_settings;
|
382 |
-
$type = $settings['api_lossy'];
|
383 |
$image_path = get_attached_file( $image_id );
|
384 |
-
$
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
$
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
$
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
401 |
} else {
|
402 |
-
|
|
|
|
|
|
|
|
|
|
|
403 |
}
|
|
|
404 |
|
405 |
} else {
|
406 |
-
|
407 |
// error or no optimization
|
408 |
if ( file_exists( $image_path ) ) {
|
409 |
|
410 |
-
$
|
411 |
-
$
|
412 |
-
$
|
413 |
-
|
414 |
-
if ( $kv['error'] == 'This image can not be optimized any further' ) {
|
415 |
-
$kv['kraked_size'] = 'No savings found';
|
416 |
-
$kv['no_savings'] = true;
|
417 |
-
}
|
418 |
-
|
419 |
-
update_post_meta( $image_id, '_kraken_size', $kv );
|
420 |
|
421 |
} else {
|
422 |
// file not found
|
@@ -428,11 +646,11 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
428 |
function kraken_media_library_reset() {
|
429 |
$image_id = (int) $_POST['id'];
|
430 |
$image_meta = get_post_meta( $image_id, '_kraken_size', true );
|
431 |
-
$original_size = $
|
432 |
delete_post_meta( $image_id, '_kraken_size' );
|
433 |
delete_post_meta( $image_id, '_kraked_thumbs' );
|
434 |
echo json_encode( array( 'success' => true, 'original_size' => $original_size, 'html' => $this->optimize_button_html( $image_id ) ) );
|
435 |
-
|
436 |
}
|
437 |
|
438 |
function kraken_media_library_reset_all() {
|
@@ -441,7 +659,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
|
|
441 |
delete_post_meta_by_key( '_kraken_size' );
|
442 |
$result = json_encode( array( 'success' => true ) );
|
443 |
echo $result;
|
444 |
-
|
445 |
}
|
446 |
|
447 |
|
@@ -553,40 +771,189 @@ EOD;
|
|
553 |
<?php
|
554 |
}
|
555 |
|
556 |
-
|
557 |
function add_media_columns( $columns ) {
|
558 |
$columns['original_size'] = 'Original Size';
|
559 |
-
$columns['kraked_size'] = '
|
560 |
return $columns;
|
561 |
}
|
562 |
|
563 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
564 |
$image_meta = get_post_meta( $id, '_kraken_size', true );
|
565 |
$thumbs_meta = get_post_meta( $id, '_kraked_thumbs', true );
|
566 |
-
$kraked_size = $image_meta['kraked_size'];
|
567 |
-
$type = $image_meta['type'];
|
568 |
-
$thumbs_count = count( $thumbs_meta );
|
569 |
-
$savings_percentage = $image_meta['savings_percent'];
|
570 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
571 |
ob_start();
|
572 |
?>
|
573 |
-
|
|
|
|
|
574 |
<br />
|
575 |
-
<
|
|
|
|
|
576 |
<br />
|
577 |
-
|
578 |
-
<?php if (
|
|
|
579 |
<br />
|
580 |
-
<
|
581 |
<?php } ?>
|
|
|
|
|
|
|
|
|
582 |
<?php if ( !empty( $this->kraken_settings['show_reset'] ) ) { ?>
|
583 |
<br />
|
584 |
-
<small
|
585 |
class="krakenReset" data-id="<?php echo $id; ?>"
|
586 |
title="Removes Kraken metadata associated with this image">
|
587 |
Reset
|
588 |
</small>
|
589 |
<span class="krakenSpinner"></span>
|
|
|
590 |
<?php } ?>
|
591 |
<?php
|
592 |
$html = ob_get_clean();
|
@@ -595,12 +962,21 @@ EOD;
|
|
595 |
|
596 |
function fill_media_columns( $column_name, $id ) {
|
597 |
|
598 |
-
$
|
599 |
-
$
|
600 |
|
601 |
-
$
|
602 |
-
$
|
603 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
604 |
|
605 |
if ( strcmp( $column_name, 'original_size' ) === 0 ) {
|
606 |
if ( wp_attachment_is_image( $id ) ) {
|
@@ -608,7 +984,13 @@ EOD;
|
|
608 |
$meta = get_post_meta( $id, '_kraken_size', true );
|
609 |
|
610 |
if ( isset( $meta['original_size'] ) ) {
|
611 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
612 |
} else {
|
613 |
echo $original_size;
|
614 |
}
|
@@ -616,19 +998,23 @@ EOD;
|
|
616 |
echo $original_size;
|
617 |
}
|
618 |
} else if ( strcmp( $column_name, 'kraked_size' ) === 0 ) {
|
619 |
-
|
|
|
|
|
620 |
if ( wp_attachment_is_image( $id ) ) {
|
621 |
|
622 |
-
$meta = get_post_meta($id, '_kraken_size', true);
|
|
|
623 |
|
624 |
// Is it optimized? Show some stats
|
625 |
-
if ( isset( $meta['kraked_size'] ) && empty( $meta['no_savings'] ) ) {
|
626 |
-
|
|
|
|
|
|
|
627 |
|
628 |
// Were there no savings, or was there an error?
|
629 |
} else {
|
630 |
-
$image_url = wp_get_attachment_url( $id );
|
631 |
-
$filename = basename( $image_url );
|
632 |
echo '<div class="buttonWrap"><button data-setting="' . $type . '" type="button" class="kraken_req" data-id="' . $id . '" id="krakenid-' . $id .'" data-filename="' . $filename . '" data-url="' . $image_url . '">Optimize This Image</button><span class="krakenSpinner"></span></div>';
|
633 |
if ( !empty( $meta['no_savings'] ) ) {
|
634 |
echo '<div class="noSavings"><strong>No savings found</strong><br /><small>Type: ' . $meta['type'] . '</small></div>';
|
@@ -640,49 +1026,93 @@ EOD;
|
|
640 |
} else {
|
641 |
echo 'n/a';
|
642 |
}
|
|
|
643 |
}
|
644 |
}
|
645 |
|
646 |
function replace_image( $image_path, $kraked_url ) {
|
647 |
$rv = false;
|
648 |
$ch = curl_init( $kraked_url );
|
649 |
-
curl_setopt( $ch, CURLOPT_RETURNTRANSFER,
|
650 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
|
651 |
-
curl_setopt( $ch,
|
|
|
|
|
|
|
652 |
$result = curl_exec( $ch );
|
653 |
-
|
|
|
|
|
|
|
654 |
return $rv !== false;
|
655 |
}
|
656 |
|
657 |
-
function optimize_image( $image_path, $type ) {
|
658 |
$settings = $this->kraken_settings;
|
659 |
$kraken = new Kraken( $settings['api_key'], $settings['api_secret'] );
|
660 |
|
661 |
if ( !empty( $type ) ) {
|
662 |
$lossy = $type === 'lossy';
|
663 |
} else {
|
664 |
-
$lossy = $settings['api_lossy'] ===
|
665 |
}
|
666 |
|
667 |
$params = array(
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
);
|
673 |
|
674 |
-
|
675 |
-
|
676 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
677 |
}
|
678 |
|
679 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
680 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
681 |
return $data;
|
682 |
}
|
683 |
|
684 |
function optimize_thumbnails( $image_data ) {
|
685 |
-
|
686 |
$image_id = $this->id;
|
687 |
if ( empty( $image_id ) ) {
|
688 |
global $wpdb;
|
@@ -708,39 +1138,62 @@ EOD;
|
|
708 |
}
|
709 |
|
710 |
if ( !empty( $sizes ) ) {
|
711 |
-
|
712 |
$thumb_path = '';
|
713 |
-
|
714 |
$thumbs_optimized_store = array();
|
715 |
$this_thumb = array();
|
716 |
|
717 |
foreach ( $sizes as $key => $size ) {
|
718 |
|
719 |
$thumb_path = $upload_full_path . '/' . $size['file'];
|
720 |
-
|
721 |
if ( file_exists( $thumb_path ) !== false ) {
|
722 |
-
|
723 |
$result = $this->optimize_image( $thumb_path, $this->optimization_type );
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
|
|
|
|
|
|
|
|
730 |
}
|
|
|
|
|
731 |
}
|
732 |
}
|
733 |
}
|
734 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
735 |
if ( !empty( $thumbs_optimized_store ) ) {
|
736 |
update_post_meta( $image_id, '_kraked_thumbs', $thumbs_optimized_store, false );
|
737 |
}
|
738 |
return $image_data;
|
739 |
}
|
740 |
|
741 |
-
|
742 |
-
|
743 |
-
|
|
|
744 |
}
|
745 |
}
|
746 |
}
|
21 |
* Plugin URI: http://wordpress.org/plugins/kraken-image-optimizer/
|
22 |
* Description: This plugin allows you to optimize your WordPress images through the Kraken API, the world's most advanced image optimization solution.
|
23 |
* Author: Karim Salman
|
24 |
+
* Version: 2.5.0
|
25 |
+
* Stable Tag: 2.5.0
|
26 |
* Author URI: https://kraken.io
|
27 |
* License GPL2
|
28 |
*/
|
41 |
|
42 |
private $optimization_type = 'lossy';
|
43 |
|
44 |
+
public static $kraken_plugin_version = '2.5.0';
|
45 |
|
46 |
function __construct() {
|
47 |
$plugin_dir_path = dirname( __FILE__ );
|
50 |
$this->optimization_type = $this->kraken_settings['api_lossy'];
|
51 |
add_action( 'admin_enqueue_scripts', array( &$this, 'my_enqueue' ) );
|
52 |
add_action( 'wp_ajax_kraken_reset', array( &$this, 'kraken_media_library_reset' ) );
|
53 |
+
add_action( 'wp_ajax_kraken_optimize', array( &$this, 'kraken_optimize' ) );
|
54 |
add_action( 'wp_ajax_kraken_request', array( &$this, 'kraken_media_library_ajax_callback' ) );
|
55 |
add_action( 'wp_ajax_kraken_reset_all', array( &$this, 'kraken_media_library_reset_all' ) );
|
56 |
add_action( 'manage_media_custom_column', array( &$this, 'fill_media_columns' ), 10, 2 );
|
57 |
add_filter( 'manage_media_columns', array( &$this, 'add_media_columns') );
|
58 |
add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), array( &$this, 'add_settings_link' ) );
|
59 |
+
|
60 |
if ( ( !empty( $this->kraken_settings ) && !empty( $this->kraken_settings['auto_optimize'] ) ) || !isset( $this->kraken_settings['auto_optimize'] ) ) {
|
61 |
+
add_action( 'add_attachment', array( &$this, 'kraken_media_uploader_callback' ) );
|
62 |
+
add_filter( 'wp_generate_attachment_metadata', array( &$this, 'optimize_thumbnails' ) );
|
63 |
+
}
|
64 |
+
add_action( 'admin_menu', array( &$this, 'kraken_menu' ) );
|
65 |
+
}
|
66 |
+
|
67 |
+
function isApiActive() {
|
68 |
+
$settings = $this->kraken_settings;
|
69 |
+
$api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
|
70 |
+
$api_secret = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
|
71 |
+
if ( empty( $api_key ) || empty( $api_secret) ) {
|
72 |
+
return false;
|
73 |
}
|
74 |
+
return true;
|
75 |
}
|
76 |
|
77 |
function kraken_menu() {
|
78 |
add_options_page( 'Kraken Image Optimizer Settings', 'Kraken.io', 'manage_options', 'wp-krakenio', array( &$this, 'kraken_settings_page' ) );
|
79 |
}
|
80 |
|
81 |
+
function blog_kraker() {
|
82 |
+
add_management_page( 'Blog Kraker', 'Blog Kraker', 'manage_options', 'blog-kraker', array( &$this, 'show_blog_kraker' ) );
|
83 |
+
}
|
84 |
|
85 |
function add_settings_link ( $links ) {
|
86 |
$mylinks = array(
|
89 |
return array_merge( $links, $mylinks );
|
90 |
}
|
91 |
|
92 |
+
function kraken_settings_page() {
|
93 |
|
|
|
|
|
94 |
if ( !empty( $_POST ) ) {
|
95 |
$options = $_POST['_kraken_options'];
|
96 |
$result = $this->validate_options( $options );
|
100 |
$settings = get_option( '_kraken_options' );
|
101 |
$lossy = isset( $settings['api_lossy'] ) ? $settings['api_lossy'] : 'lossy';
|
102 |
$auto_optimize = isset( $settings['auto_optimize'] ) ? $settings['auto_optimize'] : 1;
|
103 |
+
$optimize_main_image = isset( $settings['optimize_main_image'] ) ? $settings['optimize_main_image'] : 1;
|
104 |
$api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
|
105 |
$api_secret = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
|
|
|
106 |
$show_reset = isset( $settings['show_reset'] ) ? $settings['show_reset'] : 0;
|
107 |
$bulk_async_limit = isset( $settings['bulk_async_limit'] ) ? $settings['bulk_async_limit'] : 4;
|
108 |
+
$preserve_meta_date = isset( $settings['preserve_meta_date'] ) ? $settings['preserve_meta_date'] : 0;
|
109 |
+
$preserve_meta_copyright = isset( $settings['preserve_meta_copyright'] ) ? $settings['preserve_meta_copyright'] : 0;
|
110 |
+
$preserve_meta_geotag = isset( $settings['preserve_meta_geotag'] ) ? $settings['preserve_meta_geotag'] : 0;
|
111 |
+
$preserve_meta_orientation = isset( $settings['preserve_meta_orientation'] ) ? $settings['preserve_meta_orientation'] : 0;
|
112 |
+
$preserve_meta_profile = isset( $settings['preserve_meta_profile'] ) ? $settings['preserve_meta_profile'] : 0;
|
113 |
+
$auto_orient = isset( $settings['auto_orient'] ) ? $settings['auto_orient'] : 1;
|
114 |
+
$resize_width = isset( $settings['resize_width'] ) ? $settings['resize_width'] : 0;
|
115 |
+
$resize_height = isset( $settings['resize_height'] ) ? $settings['resize_height'] : 0;
|
116 |
+
$jpeg_quality = isset( $settings['jpeg_quality'] ) ? $settings['jpeg_quality'] : 0;
|
117 |
|
118 |
$status = $this->get_api_status( $api_key, $api_secret );
|
119 |
|
160 |
</td>
|
161 |
</tr>
|
162 |
<tr>
|
163 |
+
<th scope="row">API status:</th>
|
164 |
+
<td>
|
165 |
+
<?php echo $status_html ?>
|
166 |
+
</td>
|
167 |
+
</tr>
|
168 |
+
<tr class="with-tip">
|
169 |
+
<th scope="row">Optimization mode:</th>
|
170 |
<td>
|
171 |
<input type="radio" id="kraken_lossy" name="_kraken_options[api_lossy]" value="lossy" <?php checked( 'lossy', $lossy, true ); ?>/>
|
172 |
+
<label for="kraken_lossy">Intelligent Lossy</label>
|
173 |
<input style="margin-left:10px;" type="radio" id="kraken_lossless" name="_kraken_options[api_lossy]" value="lossless" <?php checked( 'lossless', $lossy, true ) ?>/>
|
174 |
<label for="kraken_lossless">Lossless</label>
|
175 |
</td>
|
176 |
</tr>
|
177 |
+
<tr class="tip">
|
178 |
+
<td colspan="2">
|
179 |
+
<div>
|
180 |
+
The <strong>Intelligent Lossy</strong> mode will yield the greatest savings without perceivable reducing the quality of your images, and so we recommend this setting to users.<br />
|
181 |
+
The <strong>Lossless</strong> mode will result in an unchanged image, however, will yield reduced savings as the image will not be recompressed.
|
182 |
+
</div>
|
183 |
+
</td>
|
184 |
+
</tr>
|
185 |
+
<tr class="with-tip">
|
186 |
<th scope="row">Automatically optimize uploads:</th>
|
187 |
<td>
|
188 |
<input type="checkbox" id="auto_optimize" name="_kraken_options[auto_optimize]" value="1" <?php checked( 1, $auto_optimize, true ); ?>/>
|
189 |
</td>
|
190 |
+
</tr>
|
191 |
+
<tr class="tip">
|
192 |
+
<td colspan="2">
|
193 |
+
<div>
|
194 |
+
Enabled by default. This setting causes images uploaded through the Media Uploader to be optimized on-the-fly.<br />
|
195 |
+
If you do not wish to do this, or wish to optimize images later, disable this setting by unchecking the box.
|
196 |
+
</div>
|
197 |
+
</td>
|
198 |
+
</tr>
|
199 |
+
<tr class="with-tip">
|
200 |
+
<th scope="row">Optimize main image:</th>
|
201 |
<td>
|
202 |
+
<input type="checkbox" id="optimize_main_image" name="_kraken_options[optimize_main_image]" value="1" <?php checked( 1, $optimize_main_image, true ); ?>/>
|
203 |
</td>
|
204 |
</tr>
|
205 |
+
<tr class="tip">
|
206 |
+
<td colspan="2">
|
207 |
+
<div>
|
208 |
+
Enabled by default. This option causes the image uploaded by the user to get optimized, as well as all sizes generated by WordPress.<br />
|
209 |
+
Disabling this option results in faster uploading, since the main image is not sent to our system for optimization.<br />
|
210 |
+
Disable this option if you never use the "main" image upload in your posts, or speed of image uploading is an issue.
|
211 |
+
</div>
|
212 |
+
</td>
|
213 |
+
</tr>
|
214 |
+
<tr class="with-tip">
|
215 |
+
<th scope="row">Resize main image:</th>
|
216 |
+
<td>
|
217 |
+
Max Width (px): <input type="text" id="kraken_maximum_width" name="_kraken_options[resize_width]" value="<?php echo esc_attr( $resize_width ); ?>" style="width:50px;" /> Max Height (px): <input type="text" id="kraken_maximum_height" name="_kraken_options[resize_height]" value="<?php echo esc_attr( $resize_height ); ?>" style="width:50px;" />
|
218 |
+
</td>
|
219 |
+
</tr>
|
220 |
+
<tr class="tip">
|
221 |
+
<td colspan="2">
|
222 |
+
<div>
|
223 |
+
You can restrict the maximum dimensions of image uploads by width and/or height.<br />
|
224 |
+
It is especially useful if you wish to prevent unnecessarily large photos with extremely high resolutions from being uploaded, for example, <br />
|
225 |
+
photos shot with a recent-model iPhone. Note: you can restrict the dimenions by width, height, or both. A value of zero disables.
|
226 |
+
</div>
|
227 |
+
</td>
|
228 |
+
</tr>
|
229 |
+
<tr class="with-tip">
|
230 |
+
<th scope="row">JPEG quality setting:</th>
|
231 |
+
<td>
|
232 |
+
<select name="_kraken_options[jpeg_quality]">
|
233 |
+
<?php $i = 0 ?>
|
234 |
+
<?php foreach ( range(100, 25) as $number ) { ?>
|
235 |
+
<?php if ( $i === 0 ) { ?>
|
236 |
+
<?php echo '<option value="0">Intelligent lossy (recommended)</option>'; ?>
|
237 |
+
<?php } ?>
|
238 |
+
<?php if ($i > 0) { ?>
|
239 |
+
<option value="<?php echo $number ?>" <?php selected( $jpeg_quality, $number, true); ?>>
|
240 |
+
<?php echo $number; ?>
|
241 |
+
<?php } ?>
|
242 |
+
</option>
|
243 |
+
<?php $i++ ?>
|
244 |
+
<?php } ?>
|
245 |
+
</select>
|
246 |
+
</td>
|
247 |
+
</tr>
|
248 |
+
<tr class="tip">
|
249 |
+
<td colspan="2">
|
250 |
+
<div>
|
251 |
+
Advanced users can force the quality of JPEG images to a discrete "q" value between 25 and 100 using this setting <br />
|
252 |
+
For example, forcing the quality to 60 or 70 might yield greater savings, but the resulting quality might be affected, depending on the image. <br />
|
253 |
+
We therefore recommend keeping the <strong>Intelligent Lossy</strong> setting, which will not allow a resulting image of unacceptable quality.<br />
|
254 |
+
This settings will be ignored when using the <strong>lossless</strong> optimization mode.
|
255 |
+
</div>
|
256 |
+
</td>
|
257 |
+
</tr>
|
258 |
+
<tr class="no-border">
|
259 |
+
<td class="krakenAdvancedSettings"><h3><span class="kraken-advanced-settings-label" title="Click to toggle advanced settings">Advanced Settings</span></h3></td>
|
260 |
</tr>
|
261 |
<tr class="kraken-advanced-settings">
|
262 |
<td colspan="2" class="krakenAdvancedSettingsDescription"><small>We recommend that you leave these settings at their default values</td>
|
263 |
</tr>
|
264 |
+
<tr class="kraken-advanced-settings">
|
265 |
+
<th scope="row">Preserve EXIF Metadata:</th>
|
266 |
+
<td>
|
267 |
+
<label for="preserve_meta_date"><input type="checkbox" id="preserve_meta_date" name="_kraken_options[preserve_meta_date]" value="1" <?php checked( 1, $preserve_meta_date, true ); ?>/> Date</label>
|
268 |
+
<label for="preserve_meta_copyright"><input type="checkbox" id="preserve_meta_copyright" name="_kraken_options[preserve_meta_copyright]" value="1" <?php checked( 1, $preserve_meta_copyright, true ); ?>/> Copyright</label>
|
269 |
+
<label for="preserve_meta_geotag"><input type="checkbox" id="preserve_meta_geotag" name="_kraken_options[preserve_meta_geotag]" value="1" <?php checked( 1, $preserve_meta_geotag, true ); ?>/> Geotag</label>
|
270 |
+
<label for="preserve_meta_orientation"><input type="checkbox" id="preserve_meta_orientation" name="_kraken_options[preserve_meta_orientation]" value="1" <?php checked( 1, $preserve_meta_orientation, true ); ?>/> Orientation</label>
|
271 |
+
<label for="preserve_meta_profile"><input type="checkbox" id="preserve_meta_profile" name="_kraken_options[preserve_meta_profile]" value="1" <?php checked( 1, $preserve_meta_profile, true ); ?>/> Profile</label>
|
272 |
+
</td>
|
273 |
+
</tr>
|
274 |
+
<tr class="kraken-advanced-settings with-tip">
|
275 |
+
<th scope="row">Automatically Orient Images:</th>
|
276 |
+
<td>
|
277 |
+
<input type="checkbox" id="auto_orient" name="_kraken_options[auto_orient]" value="1" <?php checked( 1, $auto_orient, true ); ?>/>
|
278 |
+
</td>
|
279 |
+
</tr>
|
280 |
+
<tr class="tip">
|
281 |
+
<td colspan="2">
|
282 |
+
<div>
|
283 |
+
This setting will rotate the JPEG image according to its <strong>Orientation</strong> EXIF metadata such that it will always be correctly displayed in Web Browsers.<br />
|
284 |
+
Enable this setting if many of your image uploads come from smart phones or digital cameras which set the orientation based on how they are held at the time of shooting.
|
285 |
+
</div>
|
286 |
+
</td>
|
287 |
+
</tr>
|
288 |
+
<tr class="kraken-advanced-settings with-tip">
|
289 |
+
<th scope="row">Show metadata reset per image:</th>
|
290 |
<td>
|
291 |
<input type="checkbox" id="kraken_show_reset" name="_kraken_options[show_reset]" value="1" <?php checked( 1, $show_reset, true ); ?>/>
|
292 |
<span class="kraken-reset-all enabled">Reset All Images</span>
|
293 |
</td>
|
294 |
</tr>
|
295 |
+
<tr class="tip">
|
296 |
+
<td colspan="2">
|
297 |
+
<div>
|
298 |
+
Checking this option will add a Reset button in the "Show Details" popup in the Kraken Stats column for each optimized image.<br />
|
299 |
+
Resetting an image will remove the Kraken.io metadata associated with it, effectively making your blog forget that it had been optimized in the first place, allowing further optimization in some cases.<br />
|
300 |
+
If an image has been optimized using the lossless setting, lossless optimization will not yield any greater savings. If in doubt, please contact support@kraken.io
|
301 |
+
</div>
|
302 |
+
</td>
|
303 |
+
</tr>
|
304 |
+
<tr class="kraken-advanced-settings with-tip">
|
305 |
+
<th scope="row">Bulk Concurrency:</th>
|
306 |
<td>
|
307 |
<select name="_kraken_options[bulk_async_limit]">
|
308 |
<?php foreach ( range(1, 10) as $number ) { ?>
|
312 |
<?php } ?>
|
313 |
</select>
|
314 |
</td>
|
315 |
+
</tr>
|
316 |
+
<tr class="tip">
|
317 |
+
<td colspan="2">
|
318 |
+
<div>
|
319 |
+
This settings defines how many images can be processed at the same time using the bulk optimizer. The recommended (and default) value is 4. <br />
|
320 |
+
For blogs on very small hosting plans, or with reduced connectivity, a lower number might be necessary to avoid hitting request limits.
|
321 |
+
</div>
|
322 |
+
</td>
|
323 |
+
</tr>
|
324 |
</tbody>
|
325 |
</table>
|
326 |
<input type="submit" name="kraken_save" id="kraken_save" class="button button-primary" value="Save All"/>
|
333 |
$error = array();
|
334 |
$valid['api_lossy'] = $input['api_lossy'];
|
335 |
$valid['auto_optimize'] = isset( $input['auto_optimize'] )? 1 : 0;
|
336 |
+
$valid['optimize_main_image'] = isset( $input['optimize_main_image'] ) ? 1 : 0;
|
337 |
+
$valid['preserve_meta_date'] = isset( $input['preserve_meta_date'] ) ? $input['preserve_meta_date'] : 0;
|
338 |
+
$valid['preserve_meta_copyright'] = isset( $input['preserve_meta_copyright'] ) ? $input['preserve_meta_copyright'] : 0;
|
339 |
+
$valid['preserve_meta_geotag'] = isset( $input['preserve_meta_geotag'] ) ? $input['preserve_meta_geotag'] : 0;
|
340 |
+
$valid['preserve_meta_orientation'] = isset( $input['preserve_meta_orientation'] ) ? $input['preserve_meta_orientation'] : 0;
|
341 |
+
$valid['preserve_meta_profile'] = isset( $input['preserve_meta_profile'] ) ? $input['preserve_meta_profile'] : 0;
|
342 |
+
$valid['auto_orient'] = isset( $input['auto_orient'] ) ? $input['auto_orient'] : 0;
|
343 |
$valid['show_reset'] = isset( $input['show_reset'] ) ? 1 : 0;
|
344 |
$valid['bulk_async_limit'] = isset( $input['bulk_async_limit'] ) ? $input['bulk_async_limit'] : 4;
|
345 |
+
$valid['resize_width'] = isset( $input['resize_width'] ) ? (int) $input['resize_width'] : 0;
|
346 |
+
$valid['resize_height'] = isset( $input['resize_height'] ) ? (int) $input['resize_height'] : 0;
|
347 |
+
$valid['jpeg_quality'] = isset( $input['jpeg_quality'] ) ? (int) $input['jpeg_quality'] : 0;
|
348 |
|
349 |
if ( $valid['show_reset'] ) {
|
350 |
$valid['show_reset'] = $input['show_reset'];
|
382 |
}
|
383 |
|
384 |
function my_enqueue( $hook ) {
|
385 |
+
|
386 |
if ( $hook == 'options-media.php' || $hook == 'upload.php' || $hook == 'settings_page_wp-krakenio' ) {
|
387 |
wp_enqueue_script( 'jquery' );
|
388 |
if ( KRAKEN_DEV_MODE === true ) {
|
414 |
return false;
|
415 |
}
|
416 |
|
417 |
+
/**
|
418 |
+
* Converts an deserialized API result array into an array
|
419 |
+
* which this plugin will consume
|
420 |
+
*/
|
421 |
+
function get_result_arr( $result, $image_id ) {
|
422 |
+
$rv = array();
|
423 |
+
$rv['original_size'] = $result['original_size'];
|
424 |
+
$rv['kraked_size'] = $result['kraked_size'];
|
425 |
+
$rv['saved_bytes'] = $result['saved_bytes'];
|
426 |
+
$savings_percentage = $result['saved_bytes'] / $result['original_size'] * 100;
|
427 |
+
$rv['savings_percent'] = round( $savings_percentage, 2 ) . '%';
|
428 |
+
$rv['type'] = $result['type'];
|
429 |
+
if ( !empty( $result['kraked_width'] ) && !empty( $result['kraked_height'] ) ) {
|
430 |
+
$rv['kraked_width'] = $result['kraked_width'];
|
431 |
+
$rv['kraked_height'] = $result['kraked_height'];
|
432 |
+
}
|
433 |
+
$rv['success'] = $result['success'];
|
434 |
+
$rv['meta'] = wp_get_attachment_metadata( $image_id );
|
435 |
+
return $rv;
|
436 |
+
}
|
437 |
+
|
438 |
+
|
439 |
/**
|
440 |
* Handles optimizing already-uploaded images in the Media Library
|
441 |
*/
|
442 |
function kraken_media_library_ajax_callback() {
|
443 |
+
|
444 |
$image_id = (int) $_POST['id'];
|
445 |
$type = false;
|
446 |
+
|
447 |
if ( isset( $_POST['type'] ) ) {
|
448 |
$type = $_POST['type'];
|
449 |
+
$this->optimization_type = $type;
|
450 |
}
|
451 |
|
452 |
$this->id = $image_id;
|
453 |
|
454 |
if ( wp_attachment_is_image( $image_id ) ) {
|
455 |
|
|
|
456 |
$settings = $this->kraken_settings;
|
457 |
+
|
458 |
+
$image_path = get_attached_file( $image_id );
|
459 |
+
$optimize_main_image = !empty( $settings['optimize_main_image'] );
|
460 |
$api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
|
461 |
$api_secret = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
|
462 |
|
463 |
+
$data = array();
|
464 |
|
465 |
+
if ( empty( $api_key ) && empty( $api_secret ) ) {
|
466 |
+
$data['error'] = 'There is a problem with your credentials. Please check them in the Kraken.io settings section of Media Settings, and try again.';
|
467 |
+
update_post_meta( $image_id, '_kraken_size', $data );
|
468 |
+
echo json_encode( array( 'error' => $data['error'] ) );
|
469 |
exit;
|
470 |
}
|
471 |
|
472 |
+
if ( $optimize_main_image ) {
|
473 |
|
474 |
+
// check if thumbs already optimized
|
475 |
+
$thumbs_optimized = false;
|
476 |
+
$kraked_thumbs_data = get_post_meta( $image_id, '_kraked_thumbs', true );
|
477 |
+
|
478 |
+
if ( !empty ( $kraked_thumbs_data ) ) {
|
479 |
+
$thumbs_optimized = true;
|
480 |
+
}
|
481 |
|
482 |
+
// get metadata for thumbnails
|
483 |
+
$image_data = wp_get_attachment_metadata( $image_id );
|
484 |
|
485 |
+
if ( !$thumbs_optimized ) {
|
486 |
+
$this->optimize_thumbnails( $image_data );
|
487 |
+
} else {
|
488 |
|
489 |
+
// re-optimize thumbs if mode has changed
|
490 |
+
$kraked_thumbs_mode = $kraked_thumbs_data[0]['type'];
|
491 |
+
if ( strcmp( $kraked_thumbs_mode, $this->optimization_type ) !== 0 ) {
|
492 |
+
wp_generate_attachment_metadata( $image_id, $image_path );
|
493 |
+
$this->optimize_thumbnails( $image_data );
|
494 |
+
}
|
495 |
+
}
|
|
|
|
|
|
|
496 |
|
497 |
+
$resize = false;
|
498 |
+
if ( !empty( $settings['resize_width'] ) || !empty( $settings['resize_height'] ) ) {
|
499 |
+
$resize = true;
|
500 |
+
}
|
501 |
|
502 |
+
$api_result = $this->optimize_image( $image_path, $type, $resize );
|
|
|
|
|
503 |
|
504 |
+
if ( !empty( $api_result ) && !empty( $api_result['success'] ) ) {
|
505 |
+
$data = $this->get_result_arr( $api_result, $image_id );
|
506 |
+
if ( $this->replace_image( $image_path, $api_result['kraked_url'] ) ) {
|
507 |
|
508 |
+
if ( !empty( $data['kraked_width'] ) && !empty( $data['kraked_height'] ) ) {
|
509 |
+
$image_data = wp_get_attachment_metadata( $image_id );
|
510 |
+
$image_data['width'] = $data['kraked_width'];
|
511 |
+
$image_data['height'] = $data['kraked_height'];
|
512 |
+
wp_update_attachment_metadata( $image_id, $image_data );
|
513 |
+
}
|
|
|
|
|
|
|
|
|
|
|
514 |
|
515 |
+
// store kraked info to DB
|
516 |
+
update_post_meta( $image_id, '_kraken_size', $data );
|
517 |
|
518 |
+
// krak thumbnails, store that data too. This can be unset when there are no thumbs
|
519 |
+
$kraked_thumbs_data = get_post_meta( $image_id, '_kraked_thumbs', true );
|
520 |
+
if ( !empty( $kraked_thumbs_data ) ) {
|
521 |
+
$data['thumbs_data'] = $kraked_thumbs_data;
|
522 |
+
$data['success'] = true;
|
523 |
+
}
|
524 |
|
525 |
+
$data['html'] = $this->generate_stats_summary( $image_id );
|
526 |
+
echo json_encode( $data );
|
527 |
+
|
528 |
+
} else {
|
529 |
+
echo json_encode( array( 'error' => 'Could not overwrite original file. Please ensure that your files are writable by plugins.' ) );
|
530 |
+
exit;
|
531 |
+
}
|
532 |
|
533 |
+
} else {
|
534 |
+
// error or no optimization
|
535 |
+
if ( file_exists( $image_path ) ) {
|
536 |
+
update_post_meta( $image_id, '_kraken_size', $data );
|
537 |
+
} else {
|
538 |
+
// file not found
|
539 |
}
|
540 |
+
echo json_encode( array( 'error' => $api_result['message'], '' ) );
|
541 |
+
}
|
542 |
+
} else {
|
543 |
+
// get metadata for thumbnails
|
544 |
+
$image_data = wp_get_attachment_metadata( $image_id );
|
545 |
+
$this->optimize_thumbnails( $image_data );
|
546 |
|
547 |
+
// krak thumbnails, store that data too. This can be unset when there are no thumbs
|
548 |
+
$kraked_thumbs_data = get_post_meta( $image_id, '_kraked_thumbs', true );
|
549 |
|
550 |
+
if ( !empty( $kraked_thumbs_data ) ) {
|
551 |
+
$data['thumbs_data'] = $kraked_thumbs_data;
|
552 |
+
$data['success'] = true;
|
553 |
}
|
554 |
+
$data['html'] = $this->generate_stats_summary( $image_id );
|
555 |
+
|
556 |
+
echo json_encode( $data );
|
557 |
}
|
558 |
}
|
559 |
+
wp_die();
|
560 |
}
|
561 |
|
562 |
+
|
563 |
+
function is_successful( $response ) {}
|
564 |
+
|
565 |
/**
|
566 |
* Handles optimizing images uploaded through any of the media uploaders.
|
567 |
*/
|
568 |
function kraken_media_uploader_callback( $image_id ) {
|
569 |
+
|
570 |
$this->id = $image_id;
|
571 |
|
572 |
+
if ( !$this->kraken_settings['optimize_main_image'] ) {
|
573 |
+
return;
|
574 |
+
}
|
575 |
+
|
576 |
+
$settings = $this->kraken_settings;
|
577 |
+
$type = $settings['api_lossy'];
|
578 |
+
|
579 |
+
if ( !$this->isApiActive() ) {
|
580 |
+
remove_filter( 'wp_generate_attachment_metadata', array( &$this, 'optimize_thumbnails') );
|
581 |
+
remove_action( 'add_attachment', array( &$this, 'kraken_media_uploader_callback' ) );
|
582 |
+
return;
|
583 |
+
}
|
584 |
+
|
585 |
if ( wp_attachment_is_image( $image_id ) ) {
|
586 |
|
|
|
|
|
587 |
$image_path = get_attached_file( $image_id );
|
588 |
+
$image_backup_path = $image_path . '_kraken_' . md5( $image_path );
|
589 |
+
$backup_created = false;
|
590 |
+
|
591 |
+
if ( copy( $image_path, $image_backup_path ) ) {
|
592 |
+
$backup_created = true;
|
593 |
+
}
|
594 |
+
|
595 |
+
$resize = false;
|
596 |
+
if ( !empty( $settings['resize_width'] ) || !empty( $settings['resize_height'] ) ) {
|
597 |
+
$resize = true;
|
598 |
+
}
|
599 |
+
|
600 |
+
// optimize backup image
|
601 |
+
if ( $backup_created ) {
|
602 |
+
$api_result = $this->optimize_image( $image_backup_path, $type, $resize );
|
603 |
+
} else {
|
604 |
+
$api_result = $this->optimize_image( $image_path, $type, $resize );
|
605 |
+
}
|
606 |
+
|
607 |
+
$data = array();
|
608 |
+
|
609 |
+
if ( !empty( $api_result ) && !empty( $api_result['success'] ) ) {
|
610 |
+
$data = $this->get_result_arr( $api_result, $image_id );
|
611 |
+
|
612 |
+
if ( $backup_created ) {
|
613 |
+
$data['optimized_backup_file'] = $image_backup_path;
|
614 |
+
if ( $data['saved_bytes'] > 0 ) {
|
615 |
+
if ( $this->replace_image( $image_backup_path, $api_result['kraked_url'] ) ) {
|
616 |
+
} else {
|
617 |
+
error_log('Kraken.io: Could not replace local image with optimized image.');
|
618 |
+
}
|
619 |
+
}
|
620 |
} else {
|
621 |
+
if ( $data['saved_bytes'] > 0 ) {
|
622 |
+
if ( $this->replace_image( $image_path, $api_result['kraked_url'] ) ) {
|
623 |
+
} else {
|
624 |
+
error_log('Kraken.io: Could not replace local image with optimized image.');
|
625 |
+
}
|
626 |
+
}
|
627 |
}
|
628 |
+
update_post_meta( $image_id, '_kraken_size', $data );
|
629 |
|
630 |
} else {
|
|
|
631 |
// error or no optimization
|
632 |
if ( file_exists( $image_path ) ) {
|
633 |
|
634 |
+
$data['original_size'] = filesize( $image_path );
|
635 |
+
$data['error'] = $api_result['message'];
|
636 |
+
$data['type'] = $api_result['type'];
|
637 |
+
update_post_meta( $image_id, '_kraken_size', $data );
|
|
|
|
|
|
|
|
|
|
|
|
|
638 |
|
639 |
} else {
|
640 |
// file not found
|
646 |
function kraken_media_library_reset() {
|
647 |
$image_id = (int) $_POST['id'];
|
648 |
$image_meta = get_post_meta( $image_id, '_kraken_size', true );
|
649 |
+
$original_size = self::formatBytes( filesize( get_attached_file( $image_id ) ) );
|
650 |
delete_post_meta( $image_id, '_kraken_size' );
|
651 |
delete_post_meta( $image_id, '_kraked_thumbs' );
|
652 |
echo json_encode( array( 'success' => true, 'original_size' => $original_size, 'html' => $this->optimize_button_html( $image_id ) ) );
|
653 |
+
wp_die();
|
654 |
}
|
655 |
|
656 |
function kraken_media_library_reset_all() {
|
659 |
delete_post_meta_by_key( '_kraken_size' );
|
660 |
$result = json_encode( array( 'success' => true ) );
|
661 |
echo $result;
|
662 |
+
wp_die();
|
663 |
}
|
664 |
|
665 |
|
771 |
<?php
|
772 |
}
|
773 |
|
|
|
774 |
function add_media_columns( $columns ) {
|
775 |
$columns['original_size'] = 'Original Size';
|
776 |
+
$columns['kraked_size'] = 'Kraken.io Stats';
|
777 |
return $columns;
|
778 |
}
|
779 |
|
780 |
+
|
781 |
+
static function KBStringToBytes( $str ) {
|
782 |
+
$temp = floatVal( $str );
|
783 |
+
$rv = false;
|
784 |
+
if ( 0 == $temp ) {
|
785 |
+
$rv = '0 bytes';
|
786 |
+
} else {
|
787 |
+
$rv = self::formatBytes( ceil( floatval( $str) * 1024 ) );
|
788 |
+
}
|
789 |
+
return $rv;
|
790 |
+
}
|
791 |
+
|
792 |
+
|
793 |
+
static function calculate_savings( $meta ) {
|
794 |
+
|
795 |
+
if ( isset( $meta['original_size'] ) ) {
|
796 |
+
|
797 |
+
$saved_bytes = isset( $meta['saved_bytes'] ) ? $meta['saved_bytes'] : '';
|
798 |
+
$savings_percentage = $meta['savings_percent'];
|
799 |
+
|
800 |
+
// convert old data format, where applicable
|
801 |
+
if ( stripos( $saved_bytes, 'kb' ) !== false ) {
|
802 |
+
$saved_bytes = self::KBStringToBytes( $saved_bytes );
|
803 |
+
} else {
|
804 |
+
if ( !$saved_bytes ) {
|
805 |
+
$saved_bytes = '0 bytes';
|
806 |
+
} else {
|
807 |
+
$saved_bytes = self::formatBytes( $saved_bytes );
|
808 |
+
}
|
809 |
+
}
|
810 |
+
|
811 |
+
return array(
|
812 |
+
'saved_bytes' => $saved_bytes,
|
813 |
+
'savings_percentage' => $savings_percentage
|
814 |
+
);
|
815 |
+
|
816 |
+
} else if ( !empty( $meta ) ) {
|
817 |
+
$thumbs_count = count( $meta );
|
818 |
+
$total_thumb_byte_savings = 0;
|
819 |
+
$total_thumb_size = 0;
|
820 |
+
$thumbs_savings_percentage = '';
|
821 |
+
$total_thumbs_savings = '';
|
822 |
+
|
823 |
+
foreach ( $meta as $k => $v ) {
|
824 |
+
$total_thumb_size += $v['original_size'];
|
825 |
+
$thumb_byte_savings = $v['original_size'] - $v['kraked_size'];
|
826 |
+
$total_thumb_byte_savings += $thumb_byte_savings;
|
827 |
+
}
|
828 |
+
|
829 |
+
$thumbs_savings_percentage = round( ( $total_thumb_byte_savings / $total_thumb_size * 100 ), 2 ) . '%';
|
830 |
+
if ( $total_thumb_byte_savings ) {
|
831 |
+
$total_thumbs_savings = self::formatBytes( $total_thumb_byte_savings );
|
832 |
+
} else {
|
833 |
+
$total_thumbs_savings = '0 bytes';
|
834 |
+
}
|
835 |
+
return array(
|
836 |
+
'savings_percentage' => $thumbs_savings_percentage,
|
837 |
+
'total_savings' => $total_thumbs_savings
|
838 |
+
);
|
839 |
+
}
|
840 |
+
}
|
841 |
+
|
842 |
+
function generate_stats_summary( $id ) {
|
843 |
$image_meta = get_post_meta( $id, '_kraken_size', true );
|
844 |
$thumbs_meta = get_post_meta( $id, '_kraked_thumbs', true );
|
|
|
|
|
|
|
|
|
845 |
|
846 |
+
$total_original_size = 0;
|
847 |
+
$total_kraked_size = 0;
|
848 |
+
$total_saved_bytes = 0;
|
849 |
+
|
850 |
+
$total_savings_percentage = 0;
|
851 |
+
|
852 |
+
// crap for backward compat
|
853 |
+
if ( isset( $image_meta['original_size'] ) ) {
|
854 |
+
|
855 |
+
$original_size = $image_meta['original_size'];
|
856 |
+
|
857 |
+
if ( stripos( $original_size, 'kb' ) !== false ) {
|
858 |
+
$total_original_size = ceil( floatval( $original_size ) * 1024 );
|
859 |
+
} else {
|
860 |
+
$total_original_size = (int) $original_size;
|
861 |
+
}
|
862 |
+
|
863 |
+
if ( isset( $image_meta['saved_bytes'] ) ) {
|
864 |
+
$saved_bytes = $image_meta['saved_bytes'];
|
865 |
+
if ( is_string( $saved_bytes ) ) {
|
866 |
+
$total_saved_bytes = (int) ceil( floatval( $saved_bytes ) * 1024 );
|
867 |
+
} else {
|
868 |
+
$total_saved_bytes = $saved_bytes;
|
869 |
+
}
|
870 |
+
}
|
871 |
+
|
872 |
+
$total_kraked_size = $total_original_size - $total_saved_bytes;
|
873 |
+
}
|
874 |
+
|
875 |
+
if ( !empty( $thumbs_meta ) ) {
|
876 |
+
$thumb_saved_bytes = 0;
|
877 |
+
$total_thumb_byte_savings = 0;
|
878 |
+
$total_thumb_size = 0;
|
879 |
+
|
880 |
+
foreach ( $thumbs_meta as $k => $v ) {
|
881 |
+
$total_original_size += $v['original_size'];
|
882 |
+
$thumb_saved_bytes = $v['original_size'] - $v['kraked_size'];
|
883 |
+
$total_saved_bytes += $thumb_saved_bytes;
|
884 |
+
}
|
885 |
+
|
886 |
+
}
|
887 |
+
$total_savings_percentage = round( ( $total_saved_bytes / $total_original_size * 100 ), 2 ) . '%';
|
888 |
+
$summary_string = '';
|
889 |
+
if ( !$total_saved_bytes ) {
|
890 |
+
$summary_string = 'No savings';
|
891 |
+
} else {
|
892 |
+
$total_savings = self::formatBytes( $total_saved_bytes );
|
893 |
+
$detailed_results_html = $this->results_html( $id );
|
894 |
+
$summary_string = '<div class="kraken-result-wrap">' . "Saved $total_savings_percentage ($total_savings)";
|
895 |
+
$summary_string .= '<br /><small class="kraken-item-details" data-id="' . $id . '" original-title="' . htmlspecialchars($detailed_results_html) .'">Show details</small></div>';
|
896 |
+
}
|
897 |
+
return $summary_string;
|
898 |
+
}
|
899 |
+
|
900 |
+
function results_html( $id ) {
|
901 |
+
|
902 |
+
$settings = $this->kraken_settings;
|
903 |
+
$optimize_main_image = !empty( $settings['optimize_main_image'] );
|
904 |
+
|
905 |
+
// get meta data for main post and thumbs
|
906 |
+
$image_meta = get_post_meta( $id, '_kraken_size', true );
|
907 |
+
$thumbs_meta = get_post_meta( $id, '_kraked_thumbs', true );
|
908 |
+
$main_image_optimized = !empty( $image_meta ) && isset( $image_meta['type'] );
|
909 |
+
$thumbs_optimized = !empty( $thumbs_meta ) && count( $thumbs_meta ) && isset( $thumbs_meta[0]['type'] );
|
910 |
+
|
911 |
+
$type = '';
|
912 |
+
$kraked_size = '';
|
913 |
+
$savings_percentage = '';
|
914 |
+
|
915 |
+
if ( $main_image_optimized ) {
|
916 |
+
$type = $image_meta['type'];
|
917 |
+
$kraked_size = isset( $image_meta['kraked_size'] ) ? $image_meta['kraked_size'] : '';
|
918 |
+
$savings_percentage = $image_meta['savings_percent'];
|
919 |
+
$main_image_kraked_stats = self::calculate_savings( $image_meta );
|
920 |
+
}
|
921 |
+
|
922 |
+
if ( $thumbs_optimized ) {
|
923 |
+
$type = $thumbs_meta[0]['type'];
|
924 |
+
$thumbs_kraked_stats = self::calculate_savings( $thumbs_meta );
|
925 |
+
$thumbs_count = count( $thumbs_meta );
|
926 |
+
}
|
927 |
+
|
928 |
ob_start();
|
929 |
?>
|
930 |
+
<?php if ( $main_image_optimized ) { ?>
|
931 |
+
<div class="kraken_detailed_results_wrap">
|
932 |
+
<span class=""><strong>Main image savings:</strong></span>
|
933 |
<br />
|
934 |
+
<span style="display:inline-block;margin-bottom:5px"><?php echo $main_image_kraked_stats['saved_bytes']; ?> (<?php echo $main_image_kraked_stats['savings_percentage']; ?> saved)</span>
|
935 |
+
<?php } ?>
|
936 |
+
<?php if ( $main_image_optimized && $thumbs_optimized ) { ?>
|
937 |
<br />
|
938 |
+
<?php } ?>
|
939 |
+
<?php if ( $thumbs_optimized ) { ?>
|
940 |
+
<span><strong>Savings on <?php echo $thumbs_count; ?> thumbnails:</strong></span>
|
941 |
<br />
|
942 |
+
<span style="display:inline-block;margin-bottom:5px"><?php echo $thumbs_kraked_stats['total_savings']; ?> (<?php echo $thumbs_kraked_stats['savings_percentage']; ?> saved)</span>
|
943 |
<?php } ?>
|
944 |
+
<br />
|
945 |
+
<span><strong>Optimization mode:</strong></span>
|
946 |
+
<br />
|
947 |
+
<span><?php echo ucfirst($type); ?></span>
|
948 |
<?php if ( !empty( $this->kraken_settings['show_reset'] ) ) { ?>
|
949 |
<br />
|
950 |
+
<small
|
951 |
class="krakenReset" data-id="<?php echo $id; ?>"
|
952 |
title="Removes Kraken metadata associated with this image">
|
953 |
Reset
|
954 |
</small>
|
955 |
<span class="krakenSpinner"></span>
|
956 |
+
</div>
|
957 |
<?php } ?>
|
958 |
<?php
|
959 |
$html = ob_get_clean();
|
962 |
|
963 |
function fill_media_columns( $column_name, $id ) {
|
964 |
|
965 |
+
$settings = $this->kraken_settings;
|
966 |
+
$optimize_main_image = !empty( $settings['optimize_main_image'] );
|
967 |
|
968 |
+
$file = get_attached_file( $id );
|
969 |
+
$original_size = filesize( $file );
|
970 |
|
971 |
+
// handle the case where file does not exist
|
972 |
+
if ( $original_size === 0 || $original_size === false ) {
|
973 |
+
echo '0 bytes';
|
974 |
+
return;
|
975 |
+
} else {
|
976 |
+
$original_size = self::formatBytes( $original_size );
|
977 |
+
}
|
978 |
+
|
979 |
+
$type = isset( $settings['api_lossy'] ) ? $settings['api_lossy'] : 'lossy';
|
980 |
|
981 |
if ( strcmp( $column_name, 'original_size' ) === 0 ) {
|
982 |
if ( wp_attachment_is_image( $id ) ) {
|
984 |
$meta = get_post_meta( $id, '_kraken_size', true );
|
985 |
|
986 |
if ( isset( $meta['original_size'] ) ) {
|
987 |
+
|
988 |
+
if ( stripos( $meta['original_size'], 'kb' ) !== false ) {
|
989 |
+
echo self::formatBytes( ceil( floatval( $meta['original_size']) * 1024 ) );
|
990 |
+
} else {
|
991 |
+
echo self::formatBytes( $meta['original_size'] );
|
992 |
+
}
|
993 |
+
|
994 |
} else {
|
995 |
echo $original_size;
|
996 |
}
|
998 |
echo $original_size;
|
999 |
}
|
1000 |
} else if ( strcmp( $column_name, 'kraked_size' ) === 0 ) {
|
1001 |
+
echo '<div class="kraken-wrap">';
|
1002 |
+
$image_url = wp_get_attachment_url( $id );
|
1003 |
+
$filename = basename( $image_url );
|
1004 |
if ( wp_attachment_is_image( $id ) ) {
|
1005 |
|
1006 |
+
$meta = get_post_meta( $id, '_kraken_size', true );
|
1007 |
+
$thumbs_meta = get_post_meta( $id, '_kraked_thumbs', true );
|
1008 |
|
1009 |
// Is it optimized? Show some stats
|
1010 |
+
if ( ( isset( $meta['kraked_size'] ) && empty( $meta['no_savings'] ) ) || !empty( $thumbs_meta ) ) {
|
1011 |
+
if ( !isset( $meta['kraked_size'] ) && $optimize_main_image ) {
|
1012 |
+
echo '<div class="buttonWrap"><button data-setting="' . $type . '" type="button" class="kraken_req" data-id="' . $id . '" id="krakenid-' . $id .'" data-filename="' . $filename . '" data-url="' . $image_url . '">Optimize Main Image</button><span class="krakenSpinner"></span></div>';
|
1013 |
+
}
|
1014 |
+
echo $this->generate_stats_summary( $id );
|
1015 |
|
1016 |
// Were there no savings, or was there an error?
|
1017 |
} else {
|
|
|
|
|
1018 |
echo '<div class="buttonWrap"><button data-setting="' . $type . '" type="button" class="kraken_req" data-id="' . $id . '" id="krakenid-' . $id .'" data-filename="' . $filename . '" data-url="' . $image_url . '">Optimize This Image</button><span class="krakenSpinner"></span></div>';
|
1019 |
if ( !empty( $meta['no_savings'] ) ) {
|
1020 |
echo '<div class="noSavings"><strong>No savings found</strong><br /><small>Type: ' . $meta['type'] . '</small></div>';
|
1026 |
} else {
|
1027 |
echo 'n/a';
|
1028 |
}
|
1029 |
+
echo '</div>';
|
1030 |
}
|
1031 |
}
|
1032 |
|
1033 |
function replace_image( $image_path, $kraked_url ) {
|
1034 |
$rv = false;
|
1035 |
$ch = curl_init( $kraked_url );
|
1036 |
+
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
|
1037 |
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
|
1038 |
+
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
|
1039 |
+
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 0 );
|
1040 |
+
curl_setopt( $ch, CURLOPT_TIMEOUT, 120 );
|
1041 |
+
curl_setopt( $ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36' );
|
1042 |
$result = curl_exec( $ch );
|
1043 |
+
|
1044 |
+
if ( $result ) {
|
1045 |
+
$rv = file_put_contents( $image_path, $result );
|
1046 |
+
}
|
1047 |
return $rv !== false;
|
1048 |
}
|
1049 |
|
1050 |
+
function optimize_image( $image_path, $type, $resize = false ) {
|
1051 |
$settings = $this->kraken_settings;
|
1052 |
$kraken = new Kraken( $settings['api_key'], $settings['api_secret'] );
|
1053 |
|
1054 |
if ( !empty( $type ) ) {
|
1055 |
$lossy = $type === 'lossy';
|
1056 |
} else {
|
1057 |
+
$lossy = $settings['api_lossy'] === 'lossy';
|
1058 |
}
|
1059 |
|
1060 |
$params = array(
|
1061 |
+
'file' => $image_path,
|
1062 |
+
'wait' => true,
|
1063 |
+
'lossy' => $lossy,
|
1064 |
+
'origin' => 'wp'
|
1065 |
);
|
1066 |
|
1067 |
+
$preserve_meta_arr = [];
|
1068 |
+
if ( $settings['preserve_meta_date'] ) {
|
1069 |
+
$preserve_meta_arr[] = 'date';
|
1070 |
+
}
|
1071 |
+
if ( $settings['preserve_meta_copyright'] ) {
|
1072 |
+
$preserve_meta_arr[] = 'copyright';
|
1073 |
+
}
|
1074 |
+
if ( $settings['preserve_meta_geotag'] ) {
|
1075 |
+
$preserve_meta_arr[] = 'geotag';
|
1076 |
+
}
|
1077 |
+
if ( $settings['preserve_meta_orientation'] ) {
|
1078 |
+
$preserve_meta_arr[] = 'orientation';
|
1079 |
+
}
|
1080 |
+
if ( $settings['preserve_meta_profile'] ) {
|
1081 |
+
$preserve_meta_arr[] = 'profile';
|
1082 |
}
|
1083 |
|
1084 |
+
if ( count( $preserve_meta_arr ) ) {
|
1085 |
+
$params['preserve_meta'] = $preserve_meta_arr;
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
if ( $settings['auto_orient'] ) {
|
1089 |
+
$params['auto_orient'] = true;
|
1090 |
+
}
|
1091 |
+
|
1092 |
+
if ( $resize ) {
|
1093 |
+
$width = (int) $settings['resize_width'];
|
1094 |
+
$height = (int) $settings['resize_height'];
|
1095 |
+
if ( $width && $height ) {
|
1096 |
+
$params['resize'] = array('strategy' => 'auto', 'width' => $width, 'height' => $height, 'enhance' => true );
|
1097 |
+
} elseif ( $width && !$height ) {
|
1098 |
+
$params['resize'] = array('strategy' => 'landscape', 'width' => $width, 'enhance' => true );
|
1099 |
+
} elseif ( $height && !$width ) {
|
1100 |
+
$params['resize'] = array('strategy' => 'portrait', 'height' => $height, 'enhance' => true );
|
1101 |
+
}
|
1102 |
+
}
|
1103 |
|
1104 |
+
if ( isset( $settings['jpeg_quality'] ) && $settings['jpeg_quality'] > 0 ) {
|
1105 |
+
$params['quality'] = (int) $settings['jpeg_quality'];
|
1106 |
+
}
|
1107 |
+
|
1108 |
+
set_time_limit(400);
|
1109 |
+
$data = $kraken->upload( $params );
|
1110 |
+
$data['type'] = !empty( $type ) ? $type : $settings['api_lossy'];
|
1111 |
return $data;
|
1112 |
}
|
1113 |
|
1114 |
function optimize_thumbnails( $image_data ) {
|
1115 |
+
|
1116 |
$image_id = $this->id;
|
1117 |
if ( empty( $image_id ) ) {
|
1118 |
global $wpdb;
|
1138 |
}
|
1139 |
|
1140 |
if ( !empty( $sizes ) ) {
|
|
|
1141 |
$thumb_path = '';
|
|
|
1142 |
$thumbs_optimized_store = array();
|
1143 |
$this_thumb = array();
|
1144 |
|
1145 |
foreach ( $sizes as $key => $size ) {
|
1146 |
|
1147 |
$thumb_path = $upload_full_path . '/' . $size['file'];
|
1148 |
+
|
1149 |
if ( file_exists( $thumb_path ) !== false ) {
|
|
|
1150 |
$result = $this->optimize_image( $thumb_path, $this->optimization_type );
|
1151 |
+
if ( !empty( $result ) && isset( $result['success'] ) && isset( $result['kraked_url'] ) ) {
|
1152 |
+
$kraked_url = $result['kraked_url'];
|
1153 |
+
if ( (int) $result['saved_bytes'] !== 0 ) {
|
1154 |
+
if ( $this->replace_image( $thumb_path, $kraked_url ) ) {
|
1155 |
+
$this_thumb = array( 'thumb' => $key, 'file' => $size['file'], 'original_size' => $result['original_size'], 'kraked_size' => $result['kraked_size'], 'type' => $this->optimization_type );
|
1156 |
+
$thumbs_optimized_store [] = $this_thumb;
|
1157 |
+
}
|
1158 |
+
} else {
|
1159 |
+
$this_thumb = array( 'thumb' => $key, 'file' => $size['file'], 'original_size' => $result['original_size'], 'kraked_size' => $result['original_size'], 'type' => $this->optimization_type );
|
1160 |
+
$thumbs_optimized_store [] = $this_thumb;
|
1161 |
}
|
1162 |
+
} else {
|
1163 |
+
return $image_data;
|
1164 |
}
|
1165 |
}
|
1166 |
}
|
1167 |
}
|
1168 |
+
|
1169 |
+
$kraken_meta = get_post_meta( $image_id, '_kraken_size', true );
|
1170 |
+
$image_backup_path = isset( $kraken_meta['optimized_backup_file'] ) ? $kraken_meta['optimized_backup_file'] : '';
|
1171 |
+
|
1172 |
+
if ( $image_backup_path ) {
|
1173 |
+
$original_image_path = get_attached_file( $image_id );
|
1174 |
+
if ( copy( $image_backup_path, $original_image_path ) ) {
|
1175 |
+
unlink( $image_backup_path );
|
1176 |
+
unset( $kraken_meta['optimized_backup_file'] );
|
1177 |
+
update_post_meta( $image_id, '_kraken_size', $kraken_meta );
|
1178 |
+
}
|
1179 |
+
}
|
1180 |
+
|
1181 |
+
// when resizing has taken place via API, update the post metadata accordingly
|
1182 |
+
if ( !empty( $kraken_meta['kraked_width'] ) && !empty( $kraken_meta['kraked_height'] ) ) {
|
1183 |
+
$image_data['width'] = $kraken_meta['kraked_width'];
|
1184 |
+
$image_data['height'] = $kraken_meta['kraked_height'];
|
1185 |
+
}
|
1186 |
+
|
1187 |
if ( !empty( $thumbs_optimized_store ) ) {
|
1188 |
update_post_meta( $image_id, '_kraked_thumbs', $thumbs_optimized_store, false );
|
1189 |
}
|
1190 |
return $image_data;
|
1191 |
}
|
1192 |
|
1193 |
+
static function formatBytes( $size, $precision = 2 ) {
|
1194 |
+
$base = log( $size, 1024 );
|
1195 |
+
$suffixes = array( ' bytes', 'KB', 'MB', 'GB', 'TB' );
|
1196 |
+
return round( pow( 1024, $base - floor( $base ) ), $precision ) . $suffixes[floor( $base )];
|
1197 |
}
|
1198 |
}
|
1199 |
}
|
lib/Kraken.php
CHANGED
@@ -1,13 +1,10 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class Kraken
|
4 |
-
{
|
5 |
-
|
6 |
protected $auth = array();
|
7 |
-
public static $kraken_plugin_version = '2.
|
8 |
|
9 |
-
public function __construct($key = '', $secret = '')
|
10 |
-
{
|
11 |
$this->auth = array(
|
12 |
"auth" => array(
|
13 |
"api_key" => $key,
|
@@ -16,95 +13,93 @@ class Kraken
|
|
16 |
);
|
17 |
}
|
18 |
|
19 |
-
public function url($opts = array())
|
20 |
-
{
|
21 |
$data = json_encode(array_merge($this->auth, $opts));
|
22 |
-
$response = self::request($data,
|
23 |
|
24 |
return $response;
|
25 |
}
|
26 |
|
27 |
-
public function upload($opts = array())
|
28 |
-
|
29 |
-
if (!isset($opts['file']))
|
30 |
-
{
|
31 |
return array(
|
32 |
"success" => false,
|
33 |
"error" => "File parameter was not provided"
|
34 |
);
|
35 |
}
|
36 |
|
37 |
-
if (preg_match("/\/\//i", $opts['file']))
|
38 |
-
{
|
39 |
$opts['url'] = $opts['file'];
|
40 |
unset($opts['file']);
|
|
|
41 |
return $this->url($opts);
|
42 |
}
|
43 |
|
44 |
-
if (!file_exists($opts['file']))
|
45 |
-
{
|
46 |
return array(
|
47 |
"success" => false,
|
48 |
-
"error" =>
|
49 |
);
|
50 |
}
|
51 |
|
52 |
-
if (
|
53 |
-
$file =
|
54 |
} else {
|
55 |
-
$file =
|
56 |
}
|
57 |
|
58 |
unset($opts['file']);
|
59 |
|
60 |
$data = array_merge(array(
|
61 |
"file" => $file,
|
62 |
-
"data" => json_encode(array_merge(
|
63 |
-
$this->auth, $opts
|
64 |
-
))
|
65 |
));
|
66 |
-
|
67 |
-
$response = self::request($data, "https://api.kraken.io/v1/upload");
|
68 |
|
69 |
return $response;
|
70 |
}
|
71 |
|
72 |
-
public function status()
|
73 |
-
{
|
74 |
$data = array('auth' => array(
|
75 |
'api_key' => $this->auth['auth']['api_key'],
|
76 |
'api_secret' => $this->auth['auth']['api_secret']
|
77 |
));
|
78 |
-
$response = self::request(json_encode($data),
|
79 |
-
|
80 |
return $response;
|
81 |
}
|
82 |
|
83 |
-
private function request($data, $url)
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
curl_setopt($curl, CURLOPT_POST, 1);
|
89 |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
90 |
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
91 |
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 0);
|
92 |
curl_setopt($curl, CURLOPT_TIMEOUT, 400);
|
93 |
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
|
94 |
-
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
|
95 |
-
curl_setopt($curl, CURLOPT_USERAGENT, 'WordPress/' . get_bloginfo('version') . ' KrakenPlugin/' . self::$kraken_plugin_version);
|
96 |
-
curl_setopt($curl, CURLOPT_FAILONERROR, 1);
|
97 |
|
98 |
$response = json_decode(curl_exec($curl), true);
|
99 |
$error = curl_errno($curl);
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
curl_close($curl);
|
102 |
-
|
103 |
-
if ($error > 0) {
|
104 |
-
throw new RuntimeException(sprintf('cURL returned with the following error code: "%s"', $error));
|
105 |
-
}
|
106 |
-
|
107 |
return $response;
|
108 |
}
|
109 |
-
|
110 |
-
}
|
1 |
<?php
|
2 |
|
3 |
+
class Kraken {
|
|
|
|
|
4 |
protected $auth = array();
|
5 |
+
public static $kraken_plugin_version = '2.5.0';
|
6 |
|
7 |
+
public function __construct($key = '', $secret = '') {
|
|
|
8 |
$this->auth = array(
|
9 |
"auth" => array(
|
10 |
"api_key" => $key,
|
13 |
);
|
14 |
}
|
15 |
|
16 |
+
public function url($opts = array()) {
|
|
|
17 |
$data = json_encode(array_merge($this->auth, $opts));
|
18 |
+
$response = self::request($data, 'https://api.kraken.io/v1/url', 'url');
|
19 |
|
20 |
return $response;
|
21 |
}
|
22 |
|
23 |
+
public function upload($opts = array()) {
|
24 |
+
if (!isset($opts['file'])) {
|
|
|
|
|
25 |
return array(
|
26 |
"success" => false,
|
27 |
"error" => "File parameter was not provided"
|
28 |
);
|
29 |
}
|
30 |
|
31 |
+
if (preg_match("/\/\//i", $opts['file'])) {
|
|
|
32 |
$opts['url'] = $opts['file'];
|
33 |
unset($opts['file']);
|
34 |
+
|
35 |
return $this->url($opts);
|
36 |
}
|
37 |
|
38 |
+
if (!file_exists($opts['file'])) {
|
|
|
39 |
return array(
|
40 |
"success" => false,
|
41 |
+
"error" => 'File `' . $opts['file'] . '` does not exist'
|
42 |
);
|
43 |
}
|
44 |
|
45 |
+
if (class_exists('CURLFile')) {
|
46 |
+
$file = new CURLFile($opts['file']);
|
47 |
} else {
|
48 |
+
$file = '@' . $opts['file'];
|
49 |
}
|
50 |
|
51 |
unset($opts['file']);
|
52 |
|
53 |
$data = array_merge(array(
|
54 |
"file" => $file,
|
55 |
+
"data" => json_encode(array_merge($this->auth, $opts))
|
|
|
|
|
56 |
));
|
57 |
+
$response = self::request($data, 'https://api.kraken.io/v1/upload', 'upload');
|
|
|
58 |
|
59 |
return $response;
|
60 |
}
|
61 |
|
62 |
+
public function status() {
|
|
|
63 |
$data = array('auth' => array(
|
64 |
'api_key' => $this->auth['auth']['api_key'],
|
65 |
'api_secret' => $this->auth['auth']['api_secret']
|
66 |
));
|
67 |
+
$response = self::request(json_encode($data), 'https://api.kraken.io/user_status', 'url');
|
|
|
68 |
return $response;
|
69 |
}
|
70 |
|
71 |
+
private function request($data, $url, $type) {
|
72 |
+
$curl = curl_init($url);
|
73 |
+
|
74 |
+
if ($type === 'url') {
|
75 |
+
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
76 |
+
'Content-Type: application/json'
|
77 |
+
));
|
78 |
+
}
|
79 |
+
|
80 |
+
// Force continue-100 from server
|
81 |
+
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.85 Safari/537.36');
|
82 |
+
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:'));
|
83 |
curl_setopt($curl, CURLOPT_POST, 1);
|
84 |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
85 |
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
86 |
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 0);
|
87 |
curl_setopt($curl, CURLOPT_TIMEOUT, 400);
|
88 |
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
|
89 |
+
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
|
|
|
|
|
90 |
|
91 |
$response = json_decode(curl_exec($curl), true);
|
92 |
$error = curl_errno($curl);
|
93 |
|
94 |
+
if ($response === null) {
|
95 |
+
$error_code = (int) curl_error($curl);
|
96 |
+
$response = array (
|
97 |
+
"success" => false,
|
98 |
+
"error" => 'cURL Error: ' . $error_code,
|
99 |
+
"code" => $error_code
|
100 |
+
);
|
101 |
+
}
|
102 |
curl_close($curl);
|
|
|
|
|
|
|
|
|
|
|
103 |
return $response;
|
104 |
}
|
105 |
+
}
|
|
readme.txt
CHANGED
@@ -1,19 +1,19 @@
|
|
1 |
=== Kraken Image Optimizer ===
|
2 |
Contributors: karim79
|
3 |
-
Tags: Image Optimizer, Image Optimiser, Optimize, Optimise, Images, Media, Performance, SEO, faster loading times, smushit, smush.it, compress, kraken-image-optimizer, tinypng, tinyjpeg, pngquant, jpegmini, ewww, pagespeed, pagespeed insights, sitespeed, optimize gif, optimize jpeg, optimize png, optimize animated gif, svg, improve pagerank, gtmetrix speed test
|
4 |
Requires at least: 3.0.1
|
5 |
-
Tested up to: 4.2
|
6 |
Donate link: https://kraken.io
|
7 |
-
Stable tag: 2.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
10 |
|
11 |
|
12 |
-
This plugin allows you to optimize your WordPress images through the Kraken API, the world's most advanced image optimization
|
13 |
|
14 |
== Description ==
|
15 |
|
16 |
-
This plugin allows you to optimize new and existing Wordpress image uploads through [Kraken Image Optimizer's](https://kraken.io "Kraken Image Optimizer") API. Both lossless and intelligent lossy optimization modes are supported. Supported filetypes are JPEG, PNG and GIF. Maximum filesize limit is
|
17 |
|
18 |
> **Get your FREE account with us**
|
19 |
|
@@ -30,6 +30,10 @@ This plugin allows you to optimize new and existing Wordpress image uploads thro
|
|
30 |
= About the plugin =
|
31 |
* You can use your Kraken API key and secret on as many sites/blogs as you like. We have no per-site license.
|
32 |
* All images uploaded throught the media uploader are optimized on-the-fly. All generated thumbnails are optimized too.
|
|
|
|
|
|
|
|
|
33 |
* All images already present in the media library can be optimized individually, or using the Bulk Action menu "Krak 'em all" feature.
|
34 |
* This plugin does not require any root or command-line access. No compilation and installation of any binaries is necessary.
|
35 |
* All optimization is carried out by sending images to Kraken.io's infrastructure, and pulling the optimized files to your Wordpress installation.
|
@@ -52,12 +56,6 @@ Once you have obtained your credentials, from your Wordpress admin, go to the Kr
|
|
52 |
|
53 |
For advanced users, there is a third party WordPress Command Line Interface (CLI) tool to allow image optimization from the command line, or by using cron. For details, visit: https://github.com/tillkruss/wp-cli-kraken
|
54 |
|
55 |
-
= Features on the way =
|
56 |
-
* Optimize images directly to Amazon S3.
|
57 |
-
* Optimize entire media library in one click.
|
58 |
-
* Optimize your currently active theme.
|
59 |
-
* WordPress Multisite support.
|
60 |
-
|
61 |
Please send bug reports, problems, feature requests and so on to support (at) Kraken dot io, or directly to the author of this plugin.
|
62 |
|
63 |
= Connect with Kraken.io =
|
@@ -65,6 +63,7 @@ Please send bug reports, problems, feature requests and so on to support (at) Kr
|
|
65 |
* [Twitter](https://twitter.com/KrakenIO "@KrakenIO")
|
66 |
* [Google+](https://plus.google.com/107209047753760492207/ "Google+")
|
67 |
* [Facebook](https://www.facebook.com/krakenio "Kraken Image Optimizer")
|
|
|
68 |
|
69 |
== Installation ==
|
70 |
|
@@ -102,9 +101,17 @@ Yes, of course they will. Our plugin simply replaces the image files on your blo
|
|
102 |
|
103 |
You will need to switch the Media Library from the Thumbnail view to the List view. In the "Kraked Size" column, you will then see the "Optimize This Image" button for unoptimized images, or the results of the optimization where the image has already been optimized by our plugin.
|
104 |
|
105 |
-
|
106 |
== Changelog ==
|
107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
= 2.0.0 =
|
109 |
* Please read! Kraken.io settings have now moved to an own section (Settings->Kraken.io), in order to reduce clutter in Media Settings, and to accomodate new features on the way.
|
110 |
* Advanced settings grouped in "Advanced Settings" section of settings page.
|
1 |
=== Kraken Image Optimizer ===
|
2 |
Contributors: karim79
|
3 |
+
Tags: Image Optimizer, Image Optimiser, Optimize, Optimise, Images, Media, Performance, SEO, faster loading times, smushit, smush.it, compress, kraken-image-optimizer, tinypng, tinyjpeg, pngquant, jpegmini, ewww, pagespeed, pagespeed insights, sitespeed, optimize gif, optimize jpeg, optimize png, optimize animated gif, svg, improve pagerank, gtmetrix speed test, EXIF, image resize
|
4 |
Requires at least: 3.0.1
|
5 |
+
Tested up to: 4.4.2
|
6 |
Donate link: https://kraken.io
|
7 |
+
Stable tag: 2.5.0
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
10 |
|
11 |
|
12 |
+
This plugin allows you to optimize your WordPress images through the Kraken API, the world's most advanced image optimization and resizing API.
|
13 |
|
14 |
== Description ==
|
15 |
|
16 |
+
This plugin allows you to optimize and resize new and existing Wordpress image uploads through [Kraken Image Optimizer's](https://kraken.io "Kraken Image Optimizer") API. Both lossless and intelligent lossy optimization modes are supported. Supported filetypes are JPEG, PNG and GIF (including animated). Maximum filesize limit is 32 MB. For more details, including detailed documentation and plans and pricing, please visit [Kraken.io](https://kraken.io "Kraken Image Optimizer"). Even when using Kraken.io's lossy optimization, our system goes the extra mile to ensure that the results are of high quality, every time. You can just install the plugin and stop worrying.
|
17 |
|
18 |
> **Get your FREE account with us**
|
19 |
|
30 |
= About the plugin =
|
31 |
* You can use your Kraken API key and secret on as many sites/blogs as you like. We have no per-site license.
|
32 |
* All images uploaded throught the media uploader are optimized on-the-fly. All generated thumbnails are optimized too.
|
33 |
+
* The main image upload can be optionally resized - this is useful for preventing user uploads with unnecessarily large dimensions. You can specify the maximum width and/or height in Kraken.io->Settings.
|
34 |
+
* When restricting the maximum dimensions of the main image using the resizing feature, the resulting image is **enhanced** using various advanced techniques, to help prevent downsample artifacts and "haloing" and produce a sharper result.
|
35 |
+
* You can optionally preserve one or more of the Date, Copyright, Geotag, Orientation, Profile EXIF metadata tags.
|
36 |
+
* Images can be automatically oriented according to their EXIF Orientation value - no need to manually rotate images.
|
37 |
* All images already present in the media library can be optimized individually, or using the Bulk Action menu "Krak 'em all" feature.
|
38 |
* This plugin does not require any root or command-line access. No compilation and installation of any binaries is necessary.
|
39 |
* All optimization is carried out by sending images to Kraken.io's infrastructure, and pulling the optimized files to your Wordpress installation.
|
56 |
|
57 |
For advanced users, there is a third party WordPress Command Line Interface (CLI) tool to allow image optimization from the command line, or by using cron. For details, visit: https://github.com/tillkruss/wp-cli-kraken
|
58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
Please send bug reports, problems, feature requests and so on to support (at) Kraken dot io, or directly to the author of this plugin.
|
60 |
|
61 |
= Connect with Kraken.io =
|
63 |
* [Twitter](https://twitter.com/KrakenIO "@KrakenIO")
|
64 |
* [Google+](https://plus.google.com/107209047753760492207/ "Google+")
|
65 |
* [Facebook](https://www.facebook.com/krakenio "Kraken Image Optimizer")
|
66 |
+
* [Github](https://github.com/kraken-io "Kraken.io on Github")
|
67 |
|
68 |
== Installation ==
|
69 |
|
101 |
|
102 |
You will need to switch the Media Library from the Thumbnail view to the List view. In the "Kraked Size" column, you will then see the "Optimize This Image" button for unoptimized images, or the results of the optimization where the image has already been optimized by our plugin.
|
103 |
|
|
|
104 |
== Changelog ==
|
105 |
|
106 |
+
= 2.5.0 =
|
107 |
+
* Ability to disable optimization of main image, allowing faster uploads from Media Library. You can optimize the main image later from within your Media Library.
|
108 |
+
* Ability to restrict the maximum dimensions of image uploads (resizing), by width and/or height.
|
109 |
+
* When using resize feature, resized images are enhanced for sharper results using various advanced techniques.
|
110 |
+
* Ability to force JPEG quality to a discrete "quality" value, for greater savings if you know what you're doing.
|
111 |
+
* Ability to preserve certain EXIF metadata tags, including Date, Copyright, Orientation, Geotag and Profile.
|
112 |
+
* Ability to automatically orient images according to their Orientation EXIF metadata.
|
113 |
+
* Improvements and simplifications to interface elements and Kraken.io Settings page.
|
114 |
+
|
115 |
= 2.0.0 =
|
116 |
* Please read! Kraken.io settings have now moved to an own section (Settings->Kraken.io), in order to reduce clutter in Media Settings, and to accomodate new features on the way.
|
117 |
* Advanced settings grouped in "Advanced Settings" section of settings page.
|