Kraken.io Image Optimizer - Version 1.0.3.3

Version Description

  • Bug and cleanup release prior to next feature release (Amazon S3 support, in the near future).
  • Fixed bug related to SSL certificates on some blogs.
  • Fixed bug causing preventing WPEngine users from copying live site to and from staging.
  • JavaScripts and styles now only included where they need to be.
  • Increased HTTP timeouts for users with extremely large numbers of thumbnails.
  • Fixed issue preventing optimization of images on WordPress installations using relative image URIs. One plugin which used to cause this problem is Root Relative URLs by Marcus E. Pope.
Download this release

Release Info

Developer karim79
Plugin Icon 128x128 Kraken.io Image Optimizer
Version 1.0.3.3
Comparing to
See all releases

Code changes from version 1.0.3.2 to 1.0.3.3

Files changed (4) hide show
  1. js/ajax.js +378 -384
  2. kraken.php +98 -78
  3. lib/Kraken.php +5 -1
  4. readme.txt +43 -23
js/ajax.js CHANGED
@@ -1,388 +1,382 @@
1
- jQuery(document).ready(function ($) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
- var errors = [
5
- {
6
- code: 401,
7
- msg: 'Unnknown API Key. Please check your API key and try again'
8
- },
9
- {
10
- code: 403,
11
- msg: 'Your account has been temporarily suspended'
12
- },
13
- {
14
- code: 413,
15
- msg: 'File size too large. The maximum file size for your plan is 1048576 bytes'
16
- },
17
- {
18
- code: 415,
19
- msg: 'File type not supported'
20
- },
21
- {
22
- code: 415,
23
- msg: 'WebP compression is non available for SVG images'
24
- },
25
- {
26
- code: 422,
27
- msg: 'You need to specify either callback_url or wait flag'
28
- },
29
- {
30
- code: 422,
31
- msg: 'This image can not be optimized any further'
32
- },
33
- {
34
- code: 500,
35
- msg: 'Kraken has encountered an unexpected error and cannot fulfill your request'
36
- },
37
- {
38
- code: 502,
39
- msg: 'Couldn\'t get this file'
 
 
 
40
  }
41
- ];
42
-
43
-
44
- $('a.krakenError').tipsy({
45
- fade: true,
46
- gravity: 'e'
47
- });
48
-
49
- var data = {
50
- action: 'kraken_request'
51
- },
52
-
53
- errorTpl = '<div class="krakenErrorWrap"><a class="krakenError">Failed! Hover here</a></div>'
54
- , $btnApplyBulkAction = $("#doaction")
55
- , $btnApplyBulkAction2 = $("#doaction2")
56
- , $topBulkActionDropdown = $(".tablenav.top .bulkactions select[name='action']")
57
- , $bottomBulkActionDropdown = $(".tablenav.bottom .bulkactions select[name='action2']");
58
-
59
-
60
- var requestSuccess = function (data, textStatus, jqXHR) {
61
- var $button = $(this)
62
- , $parent = $(this).parent()
63
- , $cell = $(this).closest("td");
64
-
65
- if (data.success && typeof data.error === 'undefined') {
66
-
67
- $button.text("Image optimized");
68
-
69
- var type = data.type
70
- , krakedSize = data.kraked_size
71
- , originalSize = data.original_size
72
- , savingsPercent = data.savings_percent
73
- , $originalSizeColumn = $(this).parent().prev("td.original_size")
74
- , krakedData = '';
75
-
76
- $parent.fadeOut("fast", function () {
77
- $cell.find(".noSavings, .krakenErrorWrap").remove();
78
- krakedData = '<strong>' + krakedSize + '</strong><br /><small>Type:&nbsp;' + type + '</small><br /><small>Savings: ' + savingsPercent + '</small>';
79
- if (typeof data.thumbs_data !== 'undefined') {
80
- krakedData += '<br /><small>' + data.thumbs_data.length + ' thumbs optimized</small>';
81
- }
82
- $(this).replaceWith(krakedData);
83
- $originalSizeColumn.html(originalSize);
84
- $parent.remove();
85
- });
86
-
87
- } else if (data.error) {
88
-
89
- var $error = $(errorTpl).attr("title", data.error);
90
-
91
- $parent
92
- .closest("td")
93
- .find(".krakenErrorWrap")
94
- .remove();
95
-
96
-
97
- $parent.after($error);
98
- $error.tipsy({
99
- fade: true,
100
- gravity: 'e'
101
- });
102
-
103
- $button
104
- .text("Retry request")
105
- .removeAttr("disabled")
106
- .css({
107
- opacity: 1
108
- });
109
- }
110
- };
111
-
112
- var requestFail = function (jqXHR, textStatus, errorThrown) {
113
- $(this).removeAttr("disabled");
114
- };
115
-
116
- var requestComplete = function (jqXHR, textStatus, errorThrown) {
117
- $(this).removeAttr("disabled");
118
- $(this)
119
- .parent()
120
- .find(".krakenSpinner")
121
- .css("display", "none");
122
- };
123
-
124
- var opts = '<option value="kraken-bulk-lossy">' + "Krak 'em all" + '</option>';
125
-
126
- $topBulkActionDropdown.find("option:last-child").before(opts);
127
- $bottomBulkActionDropdown.find("option:last-child").before(opts);
128
-
129
-
130
- var getBulkImageData = function () {
131
- var $rows = $("tr[id^='post-']")
132
- , $row = null
133
- , postId = 0
134
- , imageDateItem = {}
135
- , $krakBtn = null
136
- , btnData = {}
137
- , originalSize = ''
138
- , rv = [];
139
- $rows.each(function () {
140
- $row = $(this);
141
- postId = this.id.replace(/^\D+/g, '');
142
- if ($row.find("input[type='checkbox'][value='" + postId + "']:checked").length) {
143
- $krakBtn = $row.find(".kraken_req");
144
- if ($krakBtn.length) {
145
- btnData = $krakBtn.data();
146
- originalSize = $.trim($row.find('td.original_size').text());
147
- btnData.originalSize = originalSize;
148
- rv.push(btnData);
149
- }
150
- }
151
- });
152
- return rv;
153
- };
154
-
155
- var renderBulkImageSummary = function (bulkImageData) {
156
- var modalOptions = {
157
- zIndex: 4,
158
- escapeClose: true,
159
- clickClose: false,
160
- closeText: 'close',
161
- showClose: false
162
- }
163
- , setting = $("button.kraken_req").eq(0).data("setting")
164
- , nImages = bulkImageData.length
165
- , header = '<p class="krakenBulkHeader">Kraken Bulk Image Optimization</p>'
166
- , krakEmAll = '<button class="kraken_req_bulk">Krak \'em all</button>'
167
- , typeRadios = '<span class="radiosWrap"><span class="kraken-bulk-choose-type">Choose:</span>'
168
- + '<input type="radio" id="kraken-bulk-type-lossy" value="Lossy" name="kraken-bulk-type"/>'
169
- + '<label for="kraken-bulk-type-lossy">Lossy</label>&nbsp;'
170
- + '<input type="radio" id="kraken-bulk-type-lossless" value="Lossless" name="kraken-bulk-type"/>'
171
- + '<label for="kraken-bulk-type-lossless">Lossless</label></span>'
172
- , $modal = $('<div id="kraken-bulk-modal" class="modal"></div>')
173
- .html(header)
174
- .append(typeRadios)
175
- .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 />')
176
- .appendTo("body")
177
- .modal(modalOptions)
178
- .bind($.modal.BEFORE_CLOSE, function (event, modal) {
179
-
180
- })
181
- .bind($.modal.OPEN, function (event, modal) {
182
-
183
- })
184
- .bind($.modal.CLOSE, function (event, modal) {
185
- $("#kraken-bulk-modal").remove();
186
- })
187
- .css({
188
- top: "10px",
189
- marginTop: "40px"
190
- });
191
-
192
- if (setting === 'lossy') {
193
- $("#kraken-bulk-type-lossy").attr("checked", true);
194
- } else {
195
- $("#kraken-bulk-type-lossless").attr("checked", true);
196
- }
197
-
198
- $bulkSettingSpan = $(".bulkSetting");
199
- $("input[name='kraken-bulk-type']").change(function () {
200
- var text = this.id === "kraken-bulk-type-lossy" ? "lossy" : "lossless";
201
- $bulkSettingSpan.text(text);
202
- });
203
-
204
- // to prevent close on clicking overlay div
205
- $(".jquery-modal.blocker").click(function (e) {
206
- return false;
207
- });
208
-
209
- // otherwise media submenu shows through modal overlay
210
- $("#menu-media ul.wp-submenu").css({
211
- "z-index" : 1
212
- });
213
-
214
- var $table= $('<table id="kraken-bulk"></table>')
215
- , $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>');
216
-
217
- $table.append($headerRow);
218
- $.each(bulkImageData, function(index, element) {
219
- $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>');
220
- });
221
-
222
- $modal
223
- .append($table)
224
- .append(krakEmAll)
225
- .append('<span class="close-kraken-bulk">Close Window</span>');
226
-
227
- $(".close-kraken-bulk").click(function () {
228
- $.modal.close();
229
- });
230
-
231
- if (!nImages) {
232
- $(".kraken_req_bulk")
233
- .attr("disabled", true)
234
- .css({
235
- opacity: 0.5
236
- });
237
- }
238
- };
239
-
240
- var bulkAction = function (bulkImageData) {
241
-
242
- $bulkTable = $("#kraken-bulk");
243
- var jqxhr = null;
244
-
245
- var q = async.queue(function (task, callback) {
246
- var id = task.id
247
- , filename = task.filename;
248
-
249
- var $row = $bulkTable.find("tr[data-krakenbulkid='" + id + "']")
250
- , $krakedSizeColumn = $row.find(".kraken-krakedsize")
251
- , $spinner = $krakedSizeColumn
252
- .find(".krakenBulkSpinner")
253
- .css({ display: "inline-block" })
254
- , $savingsPercentColumn = $row.find(".kraken-savingsPercent")
255
- , $savingsBytesColumn = $row.find(".kraken-savings");
256
-
257
- jqxhr = $.ajax({
258
- url: ajax_object.ajax_url,
259
- data: { 'action' : 'kraken_request', 'id' : id, 'type' : $("input[name='kraken-bulk-type']:checked").val().toLowerCase() },
260
- type: "post",
261
- dataType: "json",
262
- timeout: 120000
263
- })
264
- .done(function (data, textStatus, jqXHR) {
265
- if (data.success && typeof data.error === 'undefined') {
266
- var type = data.type
267
- , originalSize = data.original_size
268
- , krakedSize = data.kraked_size
269
- , savingsPercent = data.savings_percent
270
- , savingsBytes = data.saved_bytes;
271
-
272
- $krakedSizeColumn.text(krakedSize);
273
- $savingsPercentColumn.text(savingsPercent);
274
- $savingsBytesColumn.text(savingsBytes);
275
-
276
- var $button = $("button[id='krakenid-" + id + "']")
277
- , $parent = $button.parent()
278
- , $cell = $button.closest("td")
279
- , $originalSizeColumn = $button.parent().prev("td.original_size")
280
-
281
-
282
- $parent.fadeOut("fast", function () {
283
- $cell.find(".noSavings, .krakenErrorWrap").remove();
284
- krakedData = '<strong>' + krakedSize + '</strong><br /><small>Type:&nbsp;' + type + '</small><br /><small>Savings: ' + savingsPercent + '</small>';
285
- if (typeof data.thumbs_data !== 'undefined') {
286
- krakedData += '<br /><small>' + data.thumbs_data.length + ' thumbs optimized</small>';
287
- }
288
- $(this).replaceWith(krakedData);
289
- $originalSizeColumn.html(originalSize);
290
- $parent.remove();
291
- });
292
-
293
- } else if (data.error) {
294
- if (data.error === 'This image can not be optimized any further') {
295
- $krakedSizeColumn.text('No savings found.');
296
- } else {
297
-
298
- }
299
- }
300
-
301
- })
302
-
303
- .fail(function () {
304
-
305
- })
306
-
307
- .always(function () {
308
- $spinner.css({ display: "none" });
309
- callback();
310
- });
311
- }, 5);
312
-
313
- q.drain = function() {
314
- $(".kraken_req_bulk")
315
- .removeAttr("disabled")
316
- .css({
317
- opacity: 1
318
- })
319
- .text("Done")
320
- .unbind("click")
321
- .click(function () {
322
- $.modal.close();
323
- });
324
- }
325
-
326
- // add some items to the queue (batch-wise)
327
- q.push(bulkImageData, function (err) {
328
-
329
- });
330
- };
331
-
332
-
333
- $btnApplyBulkAction.add($btnApplyBulkAction2)
334
- .click(function (e) {
335
- if ($(this).prev("select").val() === 'kraken-bulk-lossy') {
336
- e.preventDefault();
337
- var bulkImageData = getBulkImageData();
338
- renderBulkImageSummary(bulkImageData);
339
-
340
- $('.kraken_req_bulk').click(function (e) {
341
- e.preventDefault();
342
- $(this)
343
- .attr("disabled", true)
344
- .css({
345
- opacity: 0.5
346
- });
347
- bulkAction(bulkImageData);
348
- });
349
- }
350
- });
351
-
352
- $(".kraken_req").click(function (e) {
353
- e.preventDefault();
354
- var $button = $(this)
355
- , $parent = $(this).parent();
356
-
357
- data.id = $(this).data("id");
358
-
359
- $button
360
- .text("Optimizing image...")
361
- .attr("disabled", true)
362
- .css({
363
- opacity: 0.5
364
- });
365
-
366
-
367
- $parent
368
- .find(".krakenSpinner")
369
- .css("display", "inline");
370
-
371
-
372
- var jqxhr = $.ajax({
373
- url: ajax_object.ajax_url,
374
- data: data,
375
- type: "post",
376
- dataType: "json",
377
- timeout: 180000,
378
- context: $button
379
- })
380
-
381
- .done(requestSuccess)
382
-
383
- .fail(requestFail)
384
-
385
- .always(requestComplete);
386
-
387
- });
388
  });
1
+ jQuery(document).ready(function($) {
2
+
3
+
4
+ var errors = [{
5
+ code: 401,
6
+ msg: 'Unnknown API Key. Please check your API key and try again'
7
+ }, {
8
+ code: 403,
9
+ msg: 'Your account has been temporarily suspended'
10
+ }, {
11
+ code: 413,
12
+ msg: 'File size too large. The maximum file size for your plan is 1048576 bytes'
13
+ }, {
14
+ code: 415,
15
+ msg: 'File type not supported'
16
+ }, {
17
+ code: 415,
18
+ msg: 'WebP compression is non available for SVG images'
19
+ }, {
20
+ code: 422,
21
+ msg: 'You need to specify either callback_url or wait flag'
22
+ }, {
23
+ code: 422,
24
+ msg: 'This image can not be optimized any further'
25
+ }, {
26
+ code: 500,
27
+ msg: 'Kraken has encountered an unexpected error and cannot fulfill your request'
28
+ }, {
29
+ code: 502,
30
+ msg: 'Couldn\'t get this file'
31
+ }];
32
+
33
+
34
+ $('a.krakenError').tipsy({
35
+ fade: true,
36
+ gravity: 'e'
37
+ });
38
+
39
+ var data = {
40
+ action: 'kraken_request'
41
+ },
42
 
43
+ errorTpl = '<div class="krakenErrorWrap"><a class="krakenError">Failed! Hover here</a></div>',
44
+ $btnApplyBulkAction = $("#doaction"),
45
+ $btnApplyBulkAction2 = $("#doaction2"),
46
+ $topBulkActionDropdown = $(".tablenav.top .bulkactions select[name='action']"),
47
+ $bottomBulkActionDropdown = $(".tablenav.bottom .bulkactions select[name='action2']");
48
+
49
+
50
+ var requestSuccess = function(data, textStatus, jqXHR) {
51
+ var $button = $(this),
52
+ $parent = $(this).parent(),
53
+ $cell = $(this).closest("td");
54
+
55
+ if (data.success && typeof data.error === 'undefined') {
56
+
57
+ $button.text("Image optimized");
58
+
59
+ var type = data.type,
60
+ krakedSize = data.kraked_size,
61
+ originalSize = data.original_size,
62
+ savingsPercent = data.savings_percent,
63
+ $originalSizeColumn = $(this).parent().prev("td.original_size"),
64
+ krakedData = '';
65
+
66
+ $parent.fadeOut("fast", function() {
67
+ $cell.find(".noSavings, .krakenErrorWrap").remove();
68
+ krakedData = '<strong>' + krakedSize + '</strong><br /><small>Type:&nbsp;' + type + '</small><br /><small>Savings: ' + savingsPercent + '</small>';
69
+ if (typeof data.thumbs_data !== 'undefined') {
70
+ krakedData += '<br /><small>' + data.thumbs_data.length + ' thumbs optimized</small>';
71
+ }
72
+ $(this).replaceWith(krakedData);
73
+ $originalSizeColumn.html(originalSize);
74
+ $parent.remove();
75
+ });
76
+
77
+ } else if (data.error) {
78
+
79
+ var $error = $(errorTpl).attr("title", data.error);
80
+
81
+ $parent
82
+ .closest("td")
83
+ .find(".krakenErrorWrap")
84
+ .remove();
85
+
86
+
87
+ $parent.after($error);
88
+ $error.tipsy({
89
+ fade: true,
90
+ gravity: 'e'
91
+ });
92
+
93
+ $button
94
+ .text("Retry request")
95
+ .removeAttr("disabled")
96
+ .css({
97
+ opacity: 1
98
+ });
99
+ }
100
+ };
101
+
102
+ var requestFail = function(jqXHR, textStatus, errorThrown) {
103
+ $(this).removeAttr("disabled");
104
+ };
105
+
106
+ var requestComplete = function(jqXHR, textStatus, errorThrown) {
107
+ $(this).removeAttr("disabled");
108
+ $(this)
109
+ .parent()
110
+ .find(".krakenSpinner")
111
+ .css("display", "none");
112
+ };
113
+
114
+ var opts = '<option value="kraken-bulk-lossy">' + "Krak 'em all" + '</option>';
115
+
116
+ $topBulkActionDropdown.find("option:last-child").before(opts);
117
+ $bottomBulkActionDropdown.find("option:last-child").before(opts);
118
+
119
+
120
+ var getBulkImageData = function() {
121
+ var $rows = $("tr[id^='post-']"),
122
+ $row = null,
123
+ postId = 0,
124
+ imageDateItem = {},
125
+ $krakBtn = null,
126
+ btnData = {},
127
+ originalSize = '',
128
+ rv = [];
129
+ $rows.each(function() {
130
+ $row = $(this);
131
+ postId = this.id.replace(/^\D+/g, '');
132
+ if ($row.find("input[type='checkbox'][value='" + postId + "']:checked").length) {
133
+ $krakBtn = $row.find(".kraken_req");
134
+ if ($krakBtn.length) {
135
+ btnData = $krakBtn.data();
136
+ originalSize = $.trim($row.find('td.original_size').text());
137
+ btnData.originalSize = originalSize;
138
+ rv.push(btnData);
139
+ }
140
+ }
141
+ });
142
+ return rv;
143
+ };
144
+
145
+ var renderBulkImageSummary = function(bulkImageData) {
146
+ var modalOptions = {
147
+ zIndex: 4,
148
+ escapeClose: true,
149
+ clickClose: false,
150
+ closeText: 'close',
151
+ showClose: false
152
+ },
153
+ setting = $("button.kraken_req").eq(0).data("setting"),
154
+ nImages = bulkImageData.length,
155
+ header = '<p class="krakenBulkHeader">Kraken Bulk Image Optimization</p>',
156
+ krakEmAll = '<button class="kraken_req_bulk">Krak \'em all</button>',
157
+ 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>&nbsp;' + '<input type="radio" id="kraken-bulk-type-lossless" value="Lossless" name="kraken-bulk-type"/>' + '<label for="kraken-bulk-type-lossless">Lossless</label></span>',
158
+ $modal = $('<div id="kraken-bulk-modal" class="modal"></div>')
159
+ .html(header)
160
+ .append(typeRadios)
161
+ .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 />')
162
+ .appendTo("body")
163
+ .modal(modalOptions)
164
+ .bind($.modal.BEFORE_CLOSE, function(event, modal) {
165
+
166
+ })
167
+ .bind($.modal.OPEN, function(event, modal) {
168
+
169
+ })
170
+ .bind($.modal.CLOSE, function(event, modal) {
171
+ $("#kraken-bulk-modal").remove();
172
+ })
173
+ .css({
174
+ top: "10px",
175
+ marginTop: "40px"
176
+ });
177
+
178
+ if (setting === 'lossy') {
179
+ $("#kraken-bulk-type-lossy").attr("checked", true);
180
+ } else {
181
+ $("#kraken-bulk-type-lossless").attr("checked", true);
182
+ }
183
 
184
+ $bulkSettingSpan = $(".bulkSetting");
185
+ $("input[name='kraken-bulk-type']").change(function() {
186
+ var text = this.id === "kraken-bulk-type-lossy" ? "lossy" : "lossless";
187
+ $bulkSettingSpan.text(text);
188
+ });
189
+
190
+ // to prevent close on clicking overlay div
191
+ $(".jquery-modal.blocker").click(function(e) {
192
+ return false;
193
+ });
194
+
195
+ // otherwise media submenu shows through modal overlay
196
+ $("#menu-media ul.wp-submenu").css({
197
+ "z-index": 1
198
+ });
199
+
200
+ var $table = $('<table id="kraken-bulk"></table>'),
201
+ $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>');
202
+
203
+ $table.append($headerRow);
204
+ $.each(bulkImageData, function(index, element) {
205
+ $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>');
206
+ });
207
+
208
+ $modal
209
+ .append($table)
210
+ .append(krakEmAll)
211
+ .append('<span class="close-kraken-bulk">Close Window</span>');
212
+
213
+ $(".close-kraken-bulk").click(function() {
214
+ $.modal.close();
215
+ });
216
+
217
+ if (!nImages) {
218
+ $(".kraken_req_bulk")
219
+ .attr("disabled", true)
220
+ .css({
221
+ opacity: 0.5
222
+ });
223
  }
224
+ };
225
+
226
+ var bulkAction = function(bulkImageData) {
227
+
228
+ $bulkTable = $("#kraken-bulk");
229
+ var jqxhr = null;
230
+
231
+ var q = async.queue(function(task, callback) {
232
+ var id = task.id,
233
+ filename = task.filename;
234
+
235
+ var $row = $bulkTable.find("tr[data-krakenbulkid='" + id + "']"),
236
+ $krakedSizeColumn = $row.find(".kraken-krakedsize"),
237
+ $spinner = $krakedSizeColumn
238
+ .find(".krakenBulkSpinner")
239
+ .css({
240
+ display: "inline-block"
241
+ }),
242
+ $savingsPercentColumn = $row.find(".kraken-savingsPercent"),
243
+ $savingsBytesColumn = $row.find(".kraken-savings");
244
+
245
+ jqxhr = $.ajax({
246
+ url: ajax_object.ajax_url,
247
+ data: {
248
+ 'action': 'kraken_request',
249
+ 'id': id,
250
+ 'type': $("input[name='kraken-bulk-type']:checked").val().toLowerCase()
251
+ },
252
+ type: "post",
253
+ dataType: "json",
254
+ timeout: 360000
255
+ })
256
+ .done(function(data, textStatus, jqXHR) {
257
+ if (data.success && typeof data.error === 'undefined') {
258
+ var type = data.type,
259
+ originalSize = data.original_size,
260
+ krakedSize = data.kraked_size,
261
+ savingsPercent = data.savings_percent,
262
+ savingsBytes = data.saved_bytes;
263
+
264
+ $krakedSizeColumn.text(krakedSize);
265
+ $savingsPercentColumn.text(savingsPercent);
266
+ $savingsBytesColumn.text(savingsBytes);
267
+
268
+ var $button = $("button[id='krakenid-" + id + "']"),
269
+ $parent = $button.parent(),
270
+ $cell = $button.closest("td"),
271
+ $originalSizeColumn = $button.parent().prev("td.original_size")
272
+
273
+
274
+ $parent.fadeOut("fast", function() {
275
+ $cell.find(".noSavings, .krakenErrorWrap").remove();
276
+ krakedData = '<strong>' + krakedSize + '</strong><br /><small>Type:&nbsp;' + type + '</small><br /><small>Savings: ' + savingsPercent + '</small>';
277
+ if (typeof data.thumbs_data !== 'undefined') {
278
+ krakedData += '<br /><small>' + data.thumbs_data.length + ' thumbs optimized</small>';
279
+ }
280
+ $(this).replaceWith(krakedData);
281
+ $originalSizeColumn.html(originalSize);
282
+ $parent.remove();
283
+ });
284
+
285
+ } else if (data.error) {
286
+ if (data.error === 'This image can not be optimized any further') {
287
+ $krakedSizeColumn.text('No savings found.');
288
+ } else {
289
+
290
+ }
291
+ }
292
+
293
+ })
294
+
295
+ .fail(function() {
296
+
297
+ })
298
+
299
+ .always(function() {
300
+ $spinner.css({
301
+ display: "none"
302
+ });
303
+ callback();
304
+ });
305
+ }, 5);
306
+
307
+ q.drain = function() {
308
+ $(".kraken_req_bulk")
309
+ .removeAttr("disabled")
310
+ .css({
311
+ opacity: 1
312
+ })
313
+ .text("Done")
314
+ .unbind("click")
315
+ .click(function() {
316
+ $.modal.close();
317
+ });
318
+ }
319
+
320
+ // add some items to the queue (batch-wise)
321
+ q.push(bulkImageData, function(err) {
322
+
323
+ });
324
+ };
325
+
326
+
327
+ $btnApplyBulkAction.add($btnApplyBulkAction2)
328
+ .click(function(e) {
329
+ if ($(this).prev("select").val() === 'kraken-bulk-lossy') {
330
+ e.preventDefault();
331
+ var bulkImageData = getBulkImageData();
332
+ renderBulkImageSummary(bulkImageData);
333
+
334
+ $('.kraken_req_bulk').click(function(e) {
335
+ e.preventDefault();
336
+ $(this)
337
+ .attr("disabled", true)
338
+ .css({
339
+ opacity: 0.5
340
+ });
341
+ bulkAction(bulkImageData);
342
+ });
343
+ }
344
+ });
345
+
346
+ $(".kraken_req").click(function(e) {
347
+ e.preventDefault();
348
+ var $button = $(this),
349
+ $parent = $(this).parent();
350
+
351
+ data.id = $(this).data("id");
352
+
353
+ $button
354
+ .text("Optimizing image...")
355
+ .attr("disabled", true)
356
+ .css({
357
+ opacity: 0.5
358
+ });
359
+
360
+
361
+ $parent
362
+ .find(".krakenSpinner")
363
+ .css("display", "inline");
364
+
365
+
366
+ var jqxhr = $.ajax({
367
+ url: ajax_object.ajax_url,
368
+ data: data,
369
+ type: "post",
370
+ dataType: "json",
371
+ timeout: 360000,
372
+ context: $button
373
+ })
374
+
375
+ .done(requestSuccess)
376
+
377
+ .fail(requestFail)
378
+
379
+ .always(requestComplete);
380
+
381
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
  });
kraken.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
- /*
3
  Copyright 2014 Karim Salman (email : ksalman@kraken.io)
4
 
5
  This program is free software; you can redistribute it and/or modify
6
- it under the terms of the GNU General Public License, version 2, as
7
  published by the Free Software Foundation.
8
 
9
  This program is distributed in the hope that it will be useful,
@@ -21,8 +21,8 @@
21
  * Plugin URI: http://wordpress.org/plugins/kraken-image-optimizer/
22
  * Description: Optimize Wordpress image uploads through Kraken.io's Image Optimization API
23
  * Author: Karim Salman
24
- * Version: 1.0.3.2
25
- * Stable Tag: 1.0.3.2
26
  * Author URI: https://kraken.io
27
  * License GPL2
28
  */
@@ -31,7 +31,7 @@
31
  if ( !class_exists( 'Wp_Kraken' ) ) {
32
 
33
  class Wp_Kraken {
34
-
35
  private $id;
36
 
37
  private $kraken_settings = array();
@@ -54,19 +54,19 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
54
  add_action( 'add_attachment', array( &$this, 'kraken_media_uploader_callback' ) );
55
  }
56
 
57
- /*
58
  * Adds kraken fields and settings to Settings->Media settings page
59
  */
60
  function admin_init() {
61
-
62
  add_settings_section( 'kraken_image_optimizer', 'Kraken Image Optimizer', array( &$this, 'show_kraken_image_optimizer' ), 'media' );
63
-
64
  register_setting(
65
  'media',
66
  '_kraken_options',
67
  array( &$this, 'validate_options' )
68
  );
69
-
70
  add_settings_field(
71
  'kraken_api_key',
72
  'API Key:',
@@ -74,15 +74,15 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
74
  'media',
75
  'kraken_image_optimizer'
76
  );
77
-
78
  add_settings_field(
79
- 'kraken_api_secret',
80
- 'API Secret:',
81
- array( &$this, 'show_api_secret' ),
82
- 'media',
83
- 'kraken_image_optimizer'
84
  );
85
-
86
  add_settings_field(
87
  'kraken_lossy',
88
  'Optimization Type:',
@@ -95,29 +95,30 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
95
  'credentials_valid',
96
  'API status:',
97
  array( &$this, 'show_credentials_validity' ),
98
- 'media',
99
- 'kraken_image_optimizer'
100
  );
101
-
102
  }
103
 
104
  function my_enqueue( $hook ) {
105
- wp_enqueue_script( 'jquery' );
106
- wp_enqueue_script( 'tipsy-js', plugins_url( '/js/jquery.tipsy.js', __FILE__ ), array( 'jquery' ) );
107
- wp_enqueue_script( 'async-js', plugins_url( '/js/async.js', __FILE__ ) );
108
- wp_enqueue_script( 'ajax-script', plugins_url( '/js/ajax.js', __FILE__ ), array( 'jquery' ) );
109
- wp_enqueue_style( 'kraken_admin_style', plugins_url( 'css/admin.css', __FILE__ ) );
110
- wp_enqueue_style( 'tipsy-style', plugins_url( 'css/tipsy.css', __FILE__ ) );
111
- wp_enqueue_style( 'modal-style', plugins_url( 'css/jquery.modal.css', __FILE__ ) );
112
- wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
113
- wp_enqueue_script( 'modal-js', plugins_url( '/js/jquery.modal.min.js', __FILE__ ), array( 'jquery' ) );
114
-
 
115
  }
116
 
117
  function get_api_status( $api_key, $api_secret ) {
118
 
119
  /* Possible API Status Errors:
120
- *
121
  * 'Incoming request body does not contain a valid JSON object'
122
  * 'Incoming request body does not contain a valid auth.api_key or auth.api_secret'
123
  * 'Kraken has encountered an unexpected error and cannot fulfill your request'
@@ -137,18 +138,24 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
137
  * Handles optimizing already-uploaded images in the Media Library
138
  */
139
  function kraken_media_library_ajax_callback() {
140
-
141
  $image_id = (int) $_POST['id'];
142
  $type = false;
143
  if ( isset( $_POST['type'] ) ) {
144
  $type = $_POST['type'];
145
  }
146
-
147
  $this->id = $image_id;
148
 
149
- if ( wp_attachment_is_image( $image_id ) ) {
150
 
151
  $imageUrl = wp_get_attachment_url( $image_id );
 
 
 
 
 
 
152
  $image_path = get_attached_file( $image_id );
153
  $settings = $this->kraken_settings;
154
  $api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
@@ -162,15 +169,21 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
162
  echo json_encode( array( 'error' => $kv['error'] ) );
163
  exit;
164
  }
165
-
166
  if ( isset( $status['active'] ) && $status['active'] === true ) {
167
 
168
  } else {
169
  echo json_encode( array( 'error' => 'Your API is inactive. Please visit your account settings' ) );
170
  die();
171
  }
172
-
173
  $result = $this->optimize_image( $imageUrl, $type );
 
 
 
 
 
 
174
  $kv = array();
175
 
176
  if ( $result['success'] == true && !isset( $result['error'] ) ) {
@@ -186,7 +199,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
186
  $kv['meta'] = wp_get_attachment_metadata( $image_id );
187
 
188
  if ( $this->replace_image( $image_path, $kraked_url ) ) {
189
-
190
  // get metadata for thumbnails
191
  $image_data = wp_get_attachment_metadata( $image_id );
192
  $this->optimize_thumbnails( $image_data );
@@ -227,20 +240,25 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
227
  echo json_encode($result);
228
  }
229
  }
230
- die();
231
  }
232
 
233
- /**
234
  * Handles optimizing images uploaded through any of the media uploaders.
235
  */
236
  function kraken_media_uploader_callback( $image_id ) {
237
  $this->id = $image_id;
238
 
239
- if ( wp_attachment_is_image( $image_id ) ) {
240
 
241
  $settings = $this->kraken_settings;
242
  $type = $settings['api_lossy'];
243
  $imageUrl = wp_get_attachment_url( $image_id );
 
 
 
 
 
244
  $image_path = get_attached_file( $image_id );
245
  $result = $this->optimize_image( $imageUrl, $type );
246
 
@@ -257,7 +275,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
257
  $kv['meta'] = wp_get_attachment_metadata( $image_id );
258
 
259
  if ( $this->replace_image( $image_path, $kraked_url ) ) {
260
- update_post_meta( $image_id, '_kraken_size', $kv );
261
  } else {
262
  // writing image failed
263
  }
@@ -282,13 +300,12 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
282
  }
283
  }
284
  }
285
- }
286
 
287
 
288
  function show_credentials_validity() {
289
 
290
  $settings = $this->kraken_settings;
291
-
292
  $api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
293
  $api_secret = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
294
 
@@ -302,17 +319,16 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
302
  $url .= 'no.png';
303
  echo '<p class="apiStatus">There is a problem with your credentials <span class="apiInvalid" style="background:url(' . "'$url') no-repeat 0 0" . '"></span></p>';
304
  }
305
-
306
  }
307
 
308
  function show_kraken_image_optimizer() {
309
  echo '<a href="http://kraken.io" title="Visit Kraken.io Homepage">Kraken.io</a> API settings';
310
  }
311
-
312
  function validate_options( $input ) {
313
  $valid = array();
314
  $error = '';
315
- $valid['api_lossy'] = $input['api_lossy'];
316
 
317
  $status = $this->get_api_status( $input['api_key'], $input['api_secret'] );
318
 
@@ -328,7 +344,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
328
  } else {
329
  $error = 'There is a problem with your credentials. Please check them from your Kraken.io account.';
330
  }
331
-
332
  } else {
333
  $error = 'Please enter a valid Kraken.io API key and secret';
334
  }
@@ -339,9 +355,8 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
339
  'api_key_error',
340
  $error,
341
  'error'
342
- );
343
- }
344
-
345
  return $valid;
346
  }
347
 
@@ -353,7 +368,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
353
  type='text' value='<?php echo esc_attr( $value ); ?>' size="50"/>
354
  <?php
355
  }
356
-
357
  function show_api_secret() {
358
  $settings = $this->kraken_settings;
359
  $value = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
@@ -362,20 +377,20 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
362
  type='text' value='<?php echo esc_attr( $value ); ?>' size="50"/>
363
  <?php
364
  }
365
-
366
  function show_lossy() {
367
  $options = get_option( '_kraken_options' );
368
  $value = isset( $options['api_lossy'] ) ? $options['api_lossy'] : 'lossy';
369
 
370
- $html = '<input type="radio" id="kraken_lossy" name="_kraken_options[api_lossy]" value="lossy"' . checked( 'lossy', $value, false ) . '/>';
371
- $html .= '<label for="kraken_lossy">Lossy</label>';
372
-
373
- $html .= '<input style="margin-left:10px;" type="radio" id="kraken_lossless" name="_kraken_options[api_lossy]" value="lossless"' . checked( 'lossless', $value, false ) . '/>';
374
- $html .= '<label for="kraken_lossless">Lossless</label>';
375
-
376
- echo $html;
377
  }
378
-
379
  function add_media_columns( $columns ) {
380
  $columns['original_size'] = 'Original Size';
381
  $columns['kraked_size'] = 'Kraked Size';
@@ -386,13 +401,13 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
386
 
387
  $original_size = filesize( get_attached_file( $id ) );
388
  $original_size = self::pretty_kb( $original_size );
389
-
390
  $options = get_option( '_kraken_options' );
391
  $type = isset( $options['api_lossy'] ) ? $options['api_lossy'] : 'lossy';
392
 
393
 
394
  if ( strcmp( $column_name, 'original_size' ) === 0 ) {
395
- if ( wp_attachment_is_image( $id ) ) {
396
 
397
  $meta = get_post_meta( $id, '_kraken_size', true );
398
 
@@ -406,7 +421,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
406
  }
407
  } else if ( strcmp( $column_name, 'kraked_size' ) === 0 ) {
408
 
409
- if ( wp_attachment_is_image( $id ) ) {
410
 
411
  $meta = get_post_meta($id, '_kraken_size', true);
412
 
@@ -416,7 +431,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
416
  $type = $meta['type'];
417
  $savings_percentage = $meta['savings_percent'];
418
  echo '<strong>' . $kraked_size .'</strong><br /><small>Type:&nbsp;' . $type . '</small><br /><small>Savings:&nbsp;' . $savings_percentage . '</small>';
419
-
420
  $thumbs_data = get_post_meta( $id, '_kraked_thumbs', true );
421
  $thumbs_count = count( $thumbs_data );
422
 
@@ -441,18 +456,19 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
441
  }
442
  }
443
  }
444
-
445
  function replace_image( $image_path, $kraked_url ) {
446
  $rv = false;
447
  $ch = curl_init( $kraked_url );
448
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
 
 
449
  $result = curl_exec( $ch );
450
  $rv = file_put_contents( $image_path, $result );
451
  return $rv !== false;
452
  }
453
 
454
  function optimize_image( $url, $type ) {
455
-
456
  $settings = $this->kraken_settings;
457
  $kraken = new Kraken( $settings['api_key'], $settings['api_secret'] );
458
 
@@ -469,7 +485,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
469
 
470
  $data = $kraken->url( $params );
471
  $data['type'] = !empty( $type ) ? $type : $settings['api_lossy'];
472
-
473
  return $data;
474
  }
475
 
@@ -481,14 +497,14 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
481
  $post = $wpdb->get_row( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_value = %s LIMIT 1", $image_data['file'] ) );
482
  $image_id = $post->post_id;
483
  }
484
-
485
  $path_parts = pathinfo( $image_data['file'] );
486
 
487
  // e.g. 04/02, for use in getting correct path or URL
488
  $upload_subdir = $path_parts['dirname'];
489
 
490
- $upload_dir = wp_upload_dir();
491
-
492
  // all the way up to /uploads
493
  $upload_base_path = $upload_dir['basedir'];
494
  $upload_full_path = $upload_base_path . '/' . $upload_subdir;
@@ -496,7 +512,11 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
496
  // all the way up to /uploads
497
  $upload_base_url = $upload_dir['baseurl'];
498
  $upload_url = $upload_base_url . '/' . $upload_subdir;
499
-
 
 
 
 
500
  $sizes = array();
501
 
502
  if ( isset( $image_data['sizes'] ) ) {
@@ -504,7 +524,7 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
504
  }
505
 
506
  if ( !empty( $sizes ) ) {
507
-
508
  $thumb_url = '';
509
  $thumb_path = '';
510
 
@@ -512,26 +532,26 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
512
  $this_thumb = array();
513
 
514
  foreach ( $sizes as $key => $size ) {
515
-
516
  $thumb_path = $upload_full_path . '/' . $size['file'];
517
  $thumb_url = $upload_url . '/' . $size['file'];
518
-
519
  if ( file_exists( $thumb_path ) !== false ) {
520
 
521
  $result = $this->optimize_image( $thumb_url, $this->optimization_type );
522
-
523
  if ( !empty($result) && isset($result['success']) && isset( $result['kraked_url'] ) ) {
524
  $kraked_url = $result["kraked_url"];
525
  if ( $this->replace_image( $thumb_path, $kraked_url ) ) {
526
  $this_thumb = array( 'thumb' => $key, 'file' => $size['file'], 'original_size' => $result['original_size'], 'kraked_size' => $result['kraked_size'], 'type' => $this->optimization_type );
527
- $thumbs_optimized_store [] = $this_thumb;
528
  }
529
  }
530
- }
531
  }
532
  }
533
  if ( !empty( $thumbs_optimized_store ) ) {
534
- update_post_meta( $image_id, '_kraked_thumbs', $thumbs_optimized_store, false );
535
  }
536
  return $image_data;
537
  }
@@ -542,4 +562,4 @@ if ( !class_exists( 'Wp_Kraken' ) ) {
542
  }
543
  }
544
 
545
- new Wp_Kraken();
1
  <?php
2
+ /*
3
  Copyright 2014 Karim Salman (email : ksalman@kraken.io)
4
 
5
  This program is free software; you can redistribute it and/or modify
6
+ it under the terms of the GNU General Public License, version 2, as
7
  published by the Free Software Foundation.
8
 
9
  This program is distributed in the hope that it will be useful,
21
  * Plugin URI: http://wordpress.org/plugins/kraken-image-optimizer/
22
  * Description: Optimize Wordpress image uploads through Kraken.io's Image Optimization API
23
  * Author: Karim Salman
24
+ * Version: 1.0.3.3
25
+ * Stable Tag: 1.0.3.3
26
  * Author URI: https://kraken.io
27
  * License GPL2
28
  */
31
  if ( !class_exists( 'Wp_Kraken' ) ) {
32
 
33
  class Wp_Kraken {
34
+
35
  private $id;
36
 
37
  private $kraken_settings = array();
54
  add_action( 'add_attachment', array( &$this, 'kraken_media_uploader_callback' ) );
55
  }
56
 
57
+ /*
58
  * Adds kraken fields and settings to Settings->Media settings page
59
  */
60
  function admin_init() {
61
+
62
  add_settings_section( 'kraken_image_optimizer', 'Kraken Image Optimizer', array( &$this, 'show_kraken_image_optimizer' ), 'media' );
63
+
64
  register_setting(
65
  'media',
66
  '_kraken_options',
67
  array( &$this, 'validate_options' )
68
  );
69
+
70
  add_settings_field(
71
  'kraken_api_key',
72
  'API Key:',
74
  'media',
75
  'kraken_image_optimizer'
76
  );
77
+
78
  add_settings_field(
79
+ 'kraken_api_secret',
80
+ 'API Secret:',
81
+ array( &$this, 'show_api_secret' ),
82
+ 'media',
83
+ 'kraken_image_optimizer'
84
  );
85
+
86
  add_settings_field(
87
  'kraken_lossy',
88
  'Optimization Type:',
95
  'credentials_valid',
96
  'API status:',
97
  array( &$this, 'show_credentials_validity' ),
98
+ 'media',
99
+ 'kraken_image_optimizer'
100
  );
101
+
102
  }
103
 
104
  function my_enqueue( $hook ) {
105
+ if ( $hook == 'options-media.php' || $hook == 'upload.php') {
106
+ wp_enqueue_script( 'jquery' );
107
+ wp_enqueue_script( 'tipsy-js', plugins_url( '/js/jquery.tipsy.js', __FILE__ ), array( 'jquery' ) );
108
+ wp_enqueue_script( 'async-js', plugins_url( '/js/async.js', __FILE__ ) );
109
+ wp_enqueue_script( 'ajax-script', plugins_url( '/js/ajax.js', __FILE__ ), array( 'jquery' ) );
110
+ wp_enqueue_style( 'kraken_admin_style', plugins_url( 'css/admin.css', __FILE__ ) );
111
+ wp_enqueue_style( 'tipsy-style', plugins_url( 'css/tipsy.css', __FILE__ ) );
112
+ wp_enqueue_style( 'modal-style', plugins_url( 'css/jquery.modal.css', __FILE__ ) );
113
+ wp_localize_script( 'ajax-script', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
114
+ wp_enqueue_script( 'modal-js', plugins_url( '/js/jquery.modal.min.js', __FILE__ ), array( 'jquery' ) );
115
+ }
116
  }
117
 
118
  function get_api_status( $api_key, $api_secret ) {
119
 
120
  /* Possible API Status Errors:
121
+ *
122
  * 'Incoming request body does not contain a valid JSON object'
123
  * 'Incoming request body does not contain a valid auth.api_key or auth.api_secret'
124
  * 'Kraken has encountered an unexpected error and cannot fulfill your request'
138
  * Handles optimizing already-uploaded images in the Media Library
139
  */
140
  function kraken_media_library_ajax_callback() {
141
+
142
  $image_id = (int) $_POST['id'];
143
  $type = false;
144
  if ( isset( $_POST['type'] ) ) {
145
  $type = $_POST['type'];
146
  }
147
+
148
  $this->id = $image_id;
149
 
150
+ if ( wp_attachment_is_image( $image_id ) ) {
151
 
152
  $imageUrl = wp_get_attachment_url( $image_id );
153
+
154
+ // fix for blogs with nasty plugins which convert URLs to relative paths
155
+ if ( filter_var( $imageUrl, FILTER_VALIDATE_URL ) === false ) {
156
+ $imageUrl = get_site_url() . $imageUrl;
157
+ }
158
+
159
  $image_path = get_attached_file( $image_id );
160
  $settings = $this->kraken_settings;
161
  $api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
169
  echo json_encode( array( 'error' => $kv['error'] ) );
170
  exit;
171
  }
172
+
173
  if ( isset( $status['active'] ) && $status['active'] === true ) {
174
 
175
  } else {
176
  echo json_encode( array( 'error' => 'Your API is inactive. Please visit your account settings' ) );
177
  die();
178
  }
179
+
180
  $result = $this->optimize_image( $imageUrl, $type );
181
+
182
+ if ( $result['success'] == true && !isset( $result['error'] ) ) {
183
+ $image_data = wp_get_attachment_metadata( $image_id );
184
+ $this->optimize_thumbnails( $image_data );
185
+ }
186
+
187
  $kv = array();
188
 
189
  if ( $result['success'] == true && !isset( $result['error'] ) ) {
199
  $kv['meta'] = wp_get_attachment_metadata( $image_id );
200
 
201
  if ( $this->replace_image( $image_path, $kraked_url ) ) {
202
+
203
  // get metadata for thumbnails
204
  $image_data = wp_get_attachment_metadata( $image_id );
205
  $this->optimize_thumbnails( $image_data );
240
  echo json_encode($result);
241
  }
242
  }
243
+ die();
244
  }
245
 
246
+ /**
247
  * Handles optimizing images uploaded through any of the media uploaders.
248
  */
249
  function kraken_media_uploader_callback( $image_id ) {
250
  $this->id = $image_id;
251
 
252
+ if ( wp_attachment_is_image( $image_id ) ) {
253
 
254
  $settings = $this->kraken_settings;
255
  $type = $settings['api_lossy'];
256
  $imageUrl = wp_get_attachment_url( $image_id );
257
+
258
+ if ( filter_var( $imageUrl, FILTER_VALIDATE_URL ) === false ) {
259
+ $imageUrl = get_site_url() . $imageUrl;
260
+ }
261
+
262
  $image_path = get_attached_file( $image_id );
263
  $result = $this->optimize_image( $imageUrl, $type );
264
 
275
  $kv['meta'] = wp_get_attachment_metadata( $image_id );
276
 
277
  if ( $this->replace_image( $image_path, $kraked_url ) ) {
278
+ update_post_meta( $image_id, '_kraken_size', $kv );
279
  } else {
280
  // writing image failed
281
  }
300
  }
301
  }
302
  }
303
+ }
304
 
305
 
306
  function show_credentials_validity() {
307
 
308
  $settings = $this->kraken_settings;
 
309
  $api_key = isset( $settings['api_key'] ) ? $settings['api_key'] : '';
310
  $api_secret = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
311
 
319
  $url .= 'no.png';
320
  echo '<p class="apiStatus">There is a problem with your credentials <span class="apiInvalid" style="background:url(' . "'$url') no-repeat 0 0" . '"></span></p>';
321
  }
 
322
  }
323
 
324
  function show_kraken_image_optimizer() {
325
  echo '<a href="http://kraken.io" title="Visit Kraken.io Homepage">Kraken.io</a> API settings';
326
  }
327
+
328
  function validate_options( $input ) {
329
  $valid = array();
330
  $error = '';
331
+ $valid['api_lossy'] = $input['api_lossy'];
332
 
333
  $status = $this->get_api_status( $input['api_key'], $input['api_secret'] );
334
 
344
  } else {
345
  $error = 'There is a problem with your credentials. Please check them from your Kraken.io account.';
346
  }
347
+
348
  } else {
349
  $error = 'Please enter a valid Kraken.io API key and secret';
350
  }
355
  'api_key_error',
356
  $error,
357
  'error'
358
+ );
359
+ }
 
360
  return $valid;
361
  }
362
 
368
  type='text' value='<?php echo esc_attr( $value ); ?>' size="50"/>
369
  <?php
370
  }
371
+
372
  function show_api_secret() {
373
  $settings = $this->kraken_settings;
374
  $value = isset( $settings['api_secret'] ) ? $settings['api_secret'] : '';
377
  type='text' value='<?php echo esc_attr( $value ); ?>' size="50"/>
378
  <?php
379
  }
380
+
381
  function show_lossy() {
382
  $options = get_option( '_kraken_options' );
383
  $value = isset( $options['api_lossy'] ) ? $options['api_lossy'] : 'lossy';
384
 
385
+ $html = '<input type="radio" id="kraken_lossy" name="_kraken_options[api_lossy]" value="lossy"' . checked( 'lossy', $value, false ) . '/>';
386
+ $html .= '<label for="kraken_lossy">Lossy</label>';
387
+
388
+ $html .= '<input style="margin-left:10px;" type="radio" id="kraken_lossless" name="_kraken_options[api_lossy]" value="lossless"' . checked( 'lossless', $value, false ) . '/>';
389
+ $html .= '<label for="kraken_lossless">Lossless</label>';
390
+
391
+ echo $html;
392
  }
393
+
394
  function add_media_columns( $columns ) {
395
  $columns['original_size'] = 'Original Size';
396
  $columns['kraked_size'] = 'Kraked Size';
401
 
402
  $original_size = filesize( get_attached_file( $id ) );
403
  $original_size = self::pretty_kb( $original_size );
404
+
405
  $options = get_option( '_kraken_options' );
406
  $type = isset( $options['api_lossy'] ) ? $options['api_lossy'] : 'lossy';
407
 
408
 
409
  if ( strcmp( $column_name, 'original_size' ) === 0 ) {
410
+ if ( wp_attachment_is_image( $id ) ) {
411
 
412
  $meta = get_post_meta( $id, '_kraken_size', true );
413
 
421
  }
422
  } else if ( strcmp( $column_name, 'kraked_size' ) === 0 ) {
423
 
424
+ if ( wp_attachment_is_image( $id ) ) {
425
 
426
  $meta = get_post_meta($id, '_kraken_size', true);
427
 
431
  $type = $meta['type'];
432
  $savings_percentage = $meta['savings_percent'];
433
  echo '<strong>' . $kraked_size .'</strong><br /><small>Type:&nbsp;' . $type . '</small><br /><small>Savings:&nbsp;' . $savings_percentage . '</small>';
434
+
435
  $thumbs_data = get_post_meta( $id, '_kraked_thumbs', true );
436
  $thumbs_count = count( $thumbs_data );
437
 
456
  }
457
  }
458
  }
459
+
460
  function replace_image( $image_path, $kraked_url ) {
461
  $rv = false;
462
  $ch = curl_init( $kraked_url );
463
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
464
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
465
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
466
  $result = curl_exec( $ch );
467
  $rv = file_put_contents( $image_path, $result );
468
  return $rv !== false;
469
  }
470
 
471
  function optimize_image( $url, $type ) {
 
472
  $settings = $this->kraken_settings;
473
  $kraken = new Kraken( $settings['api_key'], $settings['api_secret'] );
474
 
485
 
486
  $data = $kraken->url( $params );
487
  $data['type'] = !empty( $type ) ? $type : $settings['api_lossy'];
488
+
489
  return $data;
490
  }
491
 
497
  $post = $wpdb->get_row( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_value = %s LIMIT 1", $image_data['file'] ) );
498
  $image_id = $post->post_id;
499
  }
500
+
501
  $path_parts = pathinfo( $image_data['file'] );
502
 
503
  // e.g. 04/02, for use in getting correct path or URL
504
  $upload_subdir = $path_parts['dirname'];
505
 
506
+ $upload_dir = wp_upload_dir();
507
+
508
  // all the way up to /uploads
509
  $upload_base_path = $upload_dir['basedir'];
510
  $upload_full_path = $upload_base_path . '/' . $upload_subdir;
512
  // all the way up to /uploads
513
  $upload_base_url = $upload_dir['baseurl'];
514
  $upload_url = $upload_base_url . '/' . $upload_subdir;
515
+
516
+ if ( filter_var( $upload_url, FILTER_VALIDATE_URL ) === false ) {
517
+ $upload_url = get_site_url() . $upload_url;
518
+ }
519
+
520
  $sizes = array();
521
 
522
  if ( isset( $image_data['sizes'] ) ) {
524
  }
525
 
526
  if ( !empty( $sizes ) ) {
527
+
528
  $thumb_url = '';
529
  $thumb_path = '';
530
 
532
  $this_thumb = array();
533
 
534
  foreach ( $sizes as $key => $size ) {
535
+
536
  $thumb_path = $upload_full_path . '/' . $size['file'];
537
  $thumb_url = $upload_url . '/' . $size['file'];
538
+
539
  if ( file_exists( $thumb_path ) !== false ) {
540
 
541
  $result = $this->optimize_image( $thumb_url, $this->optimization_type );
542
+
543
  if ( !empty($result) && isset($result['success']) && isset( $result['kraked_url'] ) ) {
544
  $kraked_url = $result["kraked_url"];
545
  if ( $this->replace_image( $thumb_path, $kraked_url ) ) {
546
  $this_thumb = array( 'thumb' => $key, 'file' => $size['file'], 'original_size' => $result['original_size'], 'kraked_size' => $result['kraked_size'], 'type' => $this->optimization_type );
547
+ $thumbs_optimized_store [] = $this_thumb;
548
  }
549
  }
550
+ }
551
  }
552
  }
553
  if ( !empty( $thumbs_optimized_store ) ) {
554
+ update_post_meta( $image_id, '_kraked_thumbs', $thumbs_optimized_store, false );
555
  }
556
  return $image_data;
557
  }
562
  }
563
  }
564
 
565
+ new Wp_Kraken();
lib/Kraken.php CHANGED
@@ -78,11 +78,15 @@ class Kraken
78
  private function request($data, $url)
79
  {
80
  $curl = curl_init();
81
-
82
  curl_setopt($curl, CURLOPT_URL, $url);
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_FAILONERROR, 1);
87
 
88
  $response = json_decode(curl_exec($curl), true);
78
  private function request($data, $url)
79
  {
80
  $curl = curl_init();
81
+
82
  curl_setopt($curl, CURLOPT_URL, $url);
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
  curl_setopt($curl, CURLOPT_FAILONERROR, 1);
91
 
92
  $response = json_decode(curl_exec($curl), true);
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: karim79
3
  Tags: Image Optimizer, Optimize, Images, Media, Performance, SEO, smushit, compress, kraken-image-optimizer
4
  Requires at least: 3.0.1
5
- Tested up to: 3.8.1
6
  Donate link: https://kraken.io
7
- Stable tag: 1.0.3.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10
 
@@ -14,7 +14,7 @@ This plugin allows you to optimize all your Wordpress images through the Kraken
14
 
15
  == Description ==
16
 
17
- 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 lossy optimization modes are supported. Supported filetypes are JPEG, PNG and GIF. Maximum filesize limit is 8MB. For more details, including detailed documentation and plans and pricing, please visit [Kraken.io](https://kraken.io "Kraken Image Optimizer"). **Note: You will need to obtain a paid Kraken API key and secret to use this plugin**.
18
 
19
 
20
 
@@ -23,6 +23,7 @@ This plugin allows you to optimize new and existing Wordpress image uploads thro
23
  * This plugin does not require any root or command-line access. No compilation and installation of any binaries is necessary.
24
  * All optimization is carried out by sending images to Kraken.io's infrastructure, and pulling the optimized files to your Wordpress installation.
25
  * To use this plugin, you must obtain a full API key and secret from [https://kraken.io/plans](https://kraken.io/plans "Kraken Image Optimizer"). The Developer API key/secret will **not** work with this plugin.
 
26
 
27
 
28
  Once you have obtained your credentials, from your Wordpress admin, go to the Settings->Media page. The Kraken Wordpress plugin adds a Kraken.io Settings section to the bottom of the page, from where you can enter your API credentials, and select your optimization preferences. Once you have done this, click **Save**. If everything is in order, it will simply say "settings saved" and give you a reassuring green tick in the **Kraken.io settings** section. You can now start optimizing images from within Media Library. Any image you upload from now on, through any of the media upload screens will be optimized on-the-fly by Kraken.
@@ -31,7 +32,7 @@ Once you have obtained your credentials, from your Wordpress admin, go to the Se
31
  * Optimize images directly to Amazon S3.
32
  * Optimize entire media library in one click.
33
  * Optimize your currently active theme.
34
- * Kraken NextGen Gallery extension.
35
 
36
  Please send bug reports, problems, feature requests and so on to support (at) Kraken dot io, or directly to the author of this plugin.
37
 
@@ -55,6 +56,7 @@ To install the Kraken Wordpress Plugin:
55
 
56
  1. This screenshot shows the new section which this plugin to Settings->Media. You must enter your credentials, and select your optimization mode from there, then hit **save**.
57
  2. This screenshot shows the two columns added by Kraken Image Optimizer: **original image** and **Kraked size**, as well as the new **Optimize This Image** button which is present for images which already exist in your media library. Stats and optimization type are shown for optimized images.
 
58
 
59
  == Frequently Asked Questions ==
60
 
@@ -65,18 +67,34 @@ To test the performance and results of Kraken Image Optimizer, you can try the f
65
 
66
  = Where can I purchase an API key and secret? =
67
 
68
- From our plans page, right [here](https://kraken.io/plans "Kraken.io plans and pricing"). In addition to being able to use our Wordpress Plugin, you can also use the API in your own applications, and take advantage of our [Web Interface PRO ](https://kraken.io/pro "Kraken Web Interface PRO") feature.
69
 
70
 
71
  == Changelog ==
72
 
73
- = 1.0 =
74
- * First version. Supports lossy and lossless optimization of JPG, PNG and GIF (including aniGIF) image formats
75
- * Hooks to Media Uploader to optimize all uploaded images, including generated thumbnails.
76
- * Allows optimization of existing images in Wordpress Media Library.
 
 
 
77
 
78
- = 1.0.1 =
79
- * Minor cleanup release.
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  = 1.0.2 =
82
  * Thumbnails are now optimized when triggering an image optimization from within the media library.
@@ -86,20 +104,22 @@ From our plans page, right [here](https://kraken.io/plans "Kraken.io plans and p
86
  * Information about thumbnail optimization is persisted for future fun-stats page/widget.
87
  * Minor CSS tweaks.
88
 
89
- = 1.0.2.1 =
90
- * Fixed bug which led to kraked file not being retrieved in rare cases.
91
- * Increase ajax timeout for media library inline kraking to be kinder to slower WordPress blogs.
 
 
 
 
 
 
 
 
 
 
 
92
 
93
- = 1.0.3 =
94
- * Bulk Actions menu in Media Library is now extended with "Krak 'em all", our Bulk Optimization feature.
95
- * Fixed a bug which caused old images' thumbnails to not be optimized.
96
- * Fixed a failure condition which occured only on WPEngine-hosted systems.
97
 
98
- = 1.0.3.1 =
99
- * When using the Regenerate Thumbnails plugin with kraked images, meta data is now correctly updated per image.
100
- * Optimization mode (lossy/lossless) is now stored with kraken thumbnail metadata (for future Stats page).
101
 
102
- = 1.0.3.2 =
103
- * Fixed bug related to storing optimized thumbnails metadata.
104
 
105
 
2
  Contributors: karim79
3
  Tags: Image Optimizer, Optimize, Images, Media, Performance, SEO, smushit, compress, kraken-image-optimizer
4
  Requires at least: 3.0.1
5
+ Tested up to: 3.9.2
6
  Donate link: https://kraken.io
7
+ Stable tag: 1.0.3.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10
 
14
 
15
  == Description ==
16
 
17
+ 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 lossy optimization modes are supported. Supported filetypes are JPEG, PNG and GIF. Maximum filesize limit is 10MB. For more details, including detailed documentation and plans and pricing, please visit [Kraken.io](https://kraken.io "Kraken Image Optimizer"). **Note: You will need to obtain a paid Kraken API key and secret to use this plugin**.
18
 
19
 
20
 
23
  * This plugin does not require any root or command-line access. No compilation and installation of any binaries is necessary.
24
  * All optimization is carried out by sending images to Kraken.io's infrastructure, and pulling the optimized files to your Wordpress installation.
25
  * To use this plugin, you must obtain a full API key and secret from [https://kraken.io/plans](https://kraken.io/plans "Kraken Image Optimizer"). The Developer API key/secret will **not** work with this plugin.
26
+ * You can use your Kraken API key and secret on as many sites/blogs as you like. We have no per-site license.
27
 
28
 
29
  Once you have obtained your credentials, from your Wordpress admin, go to the Settings->Media page. The Kraken Wordpress plugin adds a Kraken.io Settings section to the bottom of the page, from where you can enter your API credentials, and select your optimization preferences. Once you have done this, click **Save**. If everything is in order, it will simply say "settings saved" and give you a reassuring green tick in the **Kraken.io settings** section. You can now start optimizing images from within Media Library. Any image you upload from now on, through any of the media upload screens will be optimized on-the-fly by Kraken.
32
  * Optimize images directly to Amazon S3.
33
  * Optimize entire media library in one click.
34
  * Optimize your currently active theme.
35
+ * WordPress Multisite support.
36
 
37
  Please send bug reports, problems, feature requests and so on to support (at) Kraken dot io, or directly to the author of this plugin.
38
 
56
 
57
  1. This screenshot shows the new section which this plugin to Settings->Media. You must enter your credentials, and select your optimization mode from there, then hit **save**.
58
  2. This screenshot shows the two columns added by Kraken Image Optimizer: **original image** and **Kraked size**, as well as the new **Optimize This Image** button which is present for images which already exist in your media library. Stats and optimization type are shown for optimized images.
59
+ 3. This screenshot shows the bulk optimizer aka the "Krak 'em all" feature which appears as an overlay.
60
 
61
  == Frequently Asked Questions ==
62
 
67
 
68
  = Where can I purchase an API key and secret? =
69
 
70
+ From our plans page, right [here](https://kraken.io/plans "Kraken.io plans and pricing"). In addition to being able to use our Wordpress Plugin, you can also use the API in your own applications, and take advantage of our [Web Interface PRO ](https://kraken.io/pro "Kraken Web Interface PRO") feature (and much more!) for as little as USD $5 per month.
71
 
72
 
73
  == Changelog ==
74
 
75
+ = 1.0.3.3 =
76
+ * Bug and cleanup release prior to next feature release (Amazon S3 support, in the near future).
77
+ * Fixed bug related to SSL certificates on some blogs.
78
+ * Fixed bug causing preventing WPEngine users from copying live site to and from staging.
79
+ * JavaScripts and styles now only included where they need to be.
80
+ * Increased HTTP timeouts for users with extremely large numbers of thumbnails.
81
+ * Fixed issue preventing optimization of images on WordPress installations using relative image URIs. One plugin which used to cause this problem is Root Relative URLs by Marcus E. Pope.
82
 
83
+ = 1.0.3.2 =
84
+ * Fixed bug related to storing optimized thumbnails metadata.
85
+
86
+ = 1.0.3.1 =
87
+ * When using the Regenerate Thumbnails plugin with kraked images, meta data is now correctly updated per image.
88
+ * Optimization mode (lossy/lossless) is now stored with kraken thumbnail metadata (for future Stats page).
89
+
90
+ = 1.0.3 =
91
+ * Bulk Actions menu in Media Library is now extended with "Krak 'em all", our Bulk Optimization feature.
92
+ * Fixed a bug which caused old images' thumbnails to not be optimized.
93
+ * Fixed a failure condition which occured only on WPEngine-hosted systems.
94
+
95
+ = 1.0.2.1 =
96
+ * Fixed bug which led to kraked file not being retrieved in rare cases.
97
+ * Increase ajax timeout for media library inline kraking to be kinder to slower WordPress blogs.
98
 
99
  = 1.0.2 =
100
  * Thumbnails are now optimized when triggering an image optimization from within the media library.
104
  * Information about thumbnail optimization is persisted for future fun-stats page/widget.
105
  * Minor CSS tweaks.
106
 
107
+ = 1.0.1 =
108
+ * Minor cleanup release.
109
+
110
+ = 1.0 =
111
+ * First version. Supports lossy and lossless optimization of JPG, PNG and GIF (including aniGIF) image formats
112
+ * Hooks to Media Uploader to optimize all uploaded images, including generated thumbnails.
113
+ * Allows optimization of existing images in Wordpress Media Library.
114
+
115
+ == Notes and Incompatible plugins ==
116
+ If you use the WP Super Cache plugin, you must **disable the plugin** prior to performing any image optimization, as it is known to cause strange and buggy behaviour with the Kraken Image Optimizer plugin.
117
+
118
+ == Any Questions? ==
119
+ We love to hear from you! Just shoot an email to support (at) kraken dot io and let's talk.
120
+
121
 
 
 
 
 
122
 
 
 
 
123
 
 
 
124
 
125