ShortPixel Image Optimizer - Version 4.8.5

Version Description

  • drop usage of the PHP session / wp_option for the priority queue - use a flat file instead.
Download this release

Release Info

Developer ShortPixel
Plugin Icon 128x128 ShortPixel Image Optimizer
Version 4.8.5
Comparing to
See all releases

Code changes from version 4.8.4 to 4.8.5

class/shortpixel_queue.php CHANGED
@@ -17,32 +17,6 @@ class ShortPixelQueue {
17
  public function __construct($controller, $settings) {
18
  $this->ctrl = $controller;
19
  $this->settings = $settings;
20
- //init the option if needed
21
- if( !isset($_SESSION["wp-short-pixel-priorityQueue"]) //session is not defined
22
- || !(is_admin() && function_exists("is_user_logged_in") && is_user_logged_in())) { //or we're not in the admin - re-init each time
23
- //take the priority list from the options (we persist there the priority IDs from the previous session)
24
- $prioQueueOpt = $this->settings->getOpt( 'priorityQueue', array());//here we save the IDs for the files that need to be processed after an image upload for example
25
- $_SESSION["wp-short-pixel-priorityQueue"] = array();
26
- foreach($prioQueueOpt as $ID) {
27
- if(ShortPixelMetaFacade::isCustomQueuedId($ID)) {
28
- $meta = $this->ctrl->getSpMetaDao()->getMeta(ShortPixelMetaFacade::stripQueuedIdType($ID));
29
- $todo = isset($meta) && ($meta->getStatus() == 0 || $meta->getStatus() == 1);
30
- } else {
31
- $meta = wp_get_attachment_metadata($ID);
32
- $todo = !isset($meta['ShortPixelImprovement']);
33
- }
34
- WPShortPixel::log("INIT: Item $ID from options has metadata: " .json_encode($meta));
35
- if($todo) {
36
- $this->push($ID);
37
- }
38
- }
39
- $this->settings->priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"];
40
-
41
- if(is_admin() && function_exists("is_user_logged_in") && is_user_logged_in()) {
42
- WPShortPixel::log("INIT: Session queue not found, updated from Options with "
43
- .json_encode($_SESSION["wp-short-pixel-priorityQueue"]));
44
- }
45
- }
46
  }
47
 
48
  //handling older
@@ -50,8 +24,56 @@ class ShortPixelQueue {
50
  $this->__construct($controller);
51
  }
52
 
53
- public function get() {
54
- return $_SESSION["wp-short-pixel-priorityQueue"];//get_option("wp-short-pixel-priorityQueue");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  }
56
 
57
  public function skip($id) {
@@ -69,7 +91,7 @@ class ShortPixelQueue {
69
 
70
  public function allSkipped() {
71
  if( !is_array($this->settings->prioritySkip) ) return false;
72
- count(array_diff($_SESSION["wp-short-pixel-priorityQueue"], $this->settings->prioritySkip));
73
  }
74
 
75
  public function skippedCount() {
@@ -81,7 +103,8 @@ class ShortPixelQueue {
81
  }
82
 
83
  public function isPrio($id) {
84
- return is_array($_SESSION["wp-short-pixel-priorityQueue"]) && in_array($id, $_SESSION["wp-short-pixel-priorityQueue"]);
 
85
  }
86
 
87
  public function getSkipped() {
@@ -89,48 +112,45 @@ class ShortPixelQueue {
89
  }
90
 
91
  public function reverse() {
92
- $this->settings->priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"] = array_reverse($_SESSION["wp-short-pixel-priorityQueue"]);
 
93
 
94
  }
95
 
96
  public function push($ID)//add an ID to priority queue
97
  {
98
- $priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"]; //get_option("wp-short-pixel-priorityQueue");
99
- WPShortPixel::log("PUSH: Push ID $ID into queue ".json_encode($priorityQueue));
100
- array_push($priorityQueue, $ID);
101
- $prioQ = array_unique($priorityQueue);
102
- $_SESSION["wp-short-pixel-priorityQueue"] = $prioQ;
103
- //push also to the options queue, in case the session gets killed retrieve from there
104
- $this->settings->priorityQueue = $prioQ;
105
-
106
- WPShortPixel::log("PUSH: Updated: ".json_encode($_SESSION["wp-short-pixel-priorityQueue"]));//get_option("wp-short-pixel-priorityQueue")));
107
  }
108
 
109
  public function enqueue($ID)//add an ID to priority queue as LAST
110
  {
111
- $priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"]; //get_option("wp-short-pixel-priorityQueue");
112
- WPShortPixel::log("PUSH: Push ID $ID into queue ".json_encode($priorityQueue));
113
- array_unshift($priorityQueue, $ID);
114
- $prioQ = array_unique($priorityQueue);
115
- $_SESSION["wp-short-pixel-priorityQueue"] = $prioQ;
116
- //push also to the options queue, in case the session gets killed retrieve from there
117
- $this->settings->priorityQueue = $prioQ;
118
-
119
- WPShortPixel::log("ENQUEUE: Updated: ".json_encode($_SESSION["wp-short-pixel-priorityQueue"]));//get_option("wp-short-pixel-priorityQueue")));
120
  }
121
 
122
  public function getFirst($count = 1)//return the first values added to priority queue
123
  {
124
- $priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"];//self::getOpt("wp-short-pixel-priorityQueue", array());
125
  $count = min(count($priorityQueue), $count);
126
  return(array_slice($priorityQueue, count($priorityQueue) - $count, $count));
127
  }
128
 
129
  public function getFromPrioAndCheck() {
 
 
130
  $ids = array();
131
  $removeIds = array();
132
-
133
- $idsPrio = $this->get();
134
  for($i = count($idsPrio) - 1, $cnt = 0; $i>=0 && $cnt < 3; $i--) {
135
  if(!isset($idsPrio[$i])) continue; //saw this situation but then couldn't reproduce it to see the cause, so at least treat the effects.
136
  $id = $idsPrio[$i];
@@ -150,20 +170,25 @@ class ShortPixelQueue {
150
 
151
  public function remove($ID)//remove an ID from priority queue
152
  {
153
- $priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"];//get_option("wp-short-pixel-priorityQueue");
154
- WPShortPixel::log("REM: Remove ID $ID from queue ".json_encode($priorityQueue));
155
- $newPriorityQueue = array();
156
- $found = false;
157
- foreach($priorityQueue as $item) {
 
158
  if($item != $ID) {
159
- $newPriorityQueue[] = $item;
160
  } else {
161
  $found = true;
162
  }
163
  }
164
- //$this->settings->setOpt("wp-short-pixel-priorityQueue", $newPriorityQueue);
165
- $_SESSION["wp-short-pixel-priorityQueue"] = $newPriorityQueue;
166
- WPShortPixel::log("REM: " . ($found ? "Updated: " : "Not found") . json_encode($_SESSION["wp-short-pixel-priorityQueue"]));//get_option("wp-short-pixel-priorityQueue")));
 
 
 
 
167
  return $found;
168
  }
169
 
@@ -375,11 +400,9 @@ class ShortPixelQueue {
375
  }
376
 
377
  public static function resetPrio() {
378
- delete_option( "wp-short-pixel-priorityQueue");
379
- if(isset($_SESSION["wp-short-pixel-priorityQueue"])){
380
- unset($_SESSION["wp-short-pixel-priorityQueue"]);
381
- }
382
- }
383
 
384
  public function logBulkProgress() {
385
  $t = time();
17
  public function __construct($controller, $settings) {
18
  $this->ctrl = $controller;
19
  $this->settings = $settings;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  }
21
 
22
  //handling older
24
  $this->__construct($controller);
25
  }
26
 
27
+ public static function get() {
28
+ $fp = self::openQ(LOCK_SH);
29
+ $itemsRaw = fgets($fp);
30
+ $items = strlen($itemsRaw) ? self::parseQ($itemsRaw) : array();
31
+ self::closeQ($fp);
32
+ return $items;
33
+ }
34
+
35
+ public static function set($items) {
36
+ $fp = self::openQ();
37
+ fseek($fp, 0);
38
+ ftruncate($fp, 0); // truncate file
39
+ fwrite($fp, implode(',', $items));
40
+ fflush($fp); // flush output before releasing the lock
41
+ self::closeQ($fp);
42
+ }
43
+
44
+ public function apply($callable, $extra = false) {
45
+ $fp = self::openQ();
46
+ $itemsRaw = fgets($fp);
47
+ $items = strlen($itemsRaw) ? self::parseQ($itemsRaw) : array();
48
+ if($extra) {
49
+ $items = call_user_func($callable, $items, $extra);
50
+ } else {
51
+ $items = call_user_func($callable, $items);
52
+ }
53
+ fseek($fp, 0);
54
+ ftruncate($fp, 0); // truncate file
55
+ fwrite($fp, implode(',', $items));
56
+ fflush($fp); // flush output before releasing the lock
57
+ self::closeQ($fp);
58
+ return $items;
59
+ }
60
+
61
+ protected static function openQ($lock = LOCK_EX) {
62
+ $queueName = SHORTPIXEL_UPLOADS_BASE . "/.shortpixel-q-" . get_current_blog_id();
63
+ $fp = @fopen($queueName, "r+");
64
+ if(!$fp) {
65
+ $fp = @fopen($queueName, "w");
66
+ }
67
+ while (!flock($fp, $lock)) {} // acquire the lock, the stubborn way...
68
+ return $fp;
69
+ }
70
+ protected static function closeQ($fp) {
71
+ flock($fp, LOCK_UN); // release the lock
72
+ fclose($fp);
73
+ }
74
+
75
+ protected static function parseQ($items) {
76
+ return explode(',', preg_replace("/[^0-9,C-]/", "", $items));
77
  }
78
 
79
  public function skip($id) {
91
 
92
  public function allSkipped() {
93
  if( !is_array($this->settings->prioritySkip) ) return false;
94
+ count(array_diff($this->get(), $this->settings->prioritySkip));
95
  }
96
 
97
  public function skippedCount() {
103
  }
104
 
105
  public function isPrio($id) {
106
+ $prioItems = $this->get();
107
+ return is_array($prioItems) && in_array($id, $prioItems);
108
  }
109
 
110
  public function getSkipped() {
112
  }
113
 
114
  public function reverse() {
115
+ $this->apply('array_reverse');
116
+ //$this->settings->priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"] = array_reverse($_SESSION["wp-short-pixel-priorityQueue"]);
117
 
118
  }
119
 
120
  public function push($ID)//add an ID to priority queue
121
  {
122
+ $this->apply(function($priorityQueue, $ID) {
123
+ WPShortPixel::log("PUSH: Push ID $ID into queue " . json_encode($priorityQueue));
124
+ array_push($priorityQueue, $ID);
125
+ $prioQ = array_unique($priorityQueue);
126
+ WPShortPixel::log("PUSH: Updated: " . json_encode($prioQ));//get_option("wp-short-pixel-priorityQueue")));
127
+ return $prioQ;
128
+ }, $ID);
 
 
129
  }
130
 
131
  public function enqueue($ID)//add an ID to priority queue as LAST
132
  {
133
+ $this->apply(function($priorityQueue, $ID) {
134
+ WPShortPixel::log("ENQUEUE: Enqueue ID $ID into queue " . json_encode($priorityQueue));
135
+ array_unshift($priorityQueue, $ID);
136
+ $prioQ = array_unique($priorityQueue);
137
+ WPShortPixel::log("ENQUEUE: Updated: " . json_encode($prioQ));//get_option("wp-short-pixel-priorityQueue")));
138
+ return $prioQ;
139
+ }, $ID);
 
 
140
  }
141
 
142
  public function getFirst($count = 1)//return the first values added to priority queue
143
  {
144
+ $priorityQueue = $this->get();
145
  $count = min(count($priorityQueue), $count);
146
  return(array_slice($priorityQueue, count($priorityQueue) - $count, $count));
147
  }
148
 
149
  public function getFromPrioAndCheck() {
150
+ $idsPrio = $this->get();
151
+
152
  $ids = array();
153
  $removeIds = array();
 
 
154
  for($i = count($idsPrio) - 1, $cnt = 0; $i>=0 && $cnt < 3; $i--) {
155
  if(!isset($idsPrio[$i])) continue; //saw this situation but then couldn't reproduce it to see the cause, so at least treat the effects.
156
  $id = $idsPrio[$i];
170
 
171
  public function remove($ID)//remove an ID from priority queue
172
  {
173
+ $fp = $this->openQ();
174
+ $items = fgets($fp);
175
+ $items = self::parseQ($items);
176
+ $items = is_array($items) ? $items : array();
177
+ $newItems = array();
178
+ foreach($items as $item) { // this instead of array_values(array_diff(.. because we need to know if we actually removed it
179
  if($item != $ID) {
180
+ $newItems[] = $item;
181
  } else {
182
  $found = true;
183
  }
184
  }
185
+ if($found) {
186
+ fseek($fp, 0);
187
+ ftruncate($fp, 0);
188
+ fwrite($fp, implode(',', $newItems));
189
+ fflush($fp); // flush output before releasing the lock
190
+ }
191
+ $this->closeQ($fp);
192
  return $found;
193
  }
194
 
400
  }
401
 
402
  public static function resetPrio() {
403
+ //delete_option( "wp-short-pixel-priorityQueue");
404
+ self::set(array());
405
+ }
 
 
406
 
407
  public function logBulkProgress() {
408
  $t = time();
class/wp-short-pixel.php CHANGED
@@ -19,10 +19,6 @@ class WPShortPixel {
19
  public static $PROCESSABLE_EXTENSIONS = array('jpg', 'jpeg', 'gif', 'png', 'pdf');
20
 
21
  public function __construct() {
22
- if (!session_id()) {
23
- @session_start();
24
- }
25
-
26
  if (SHORTPIXEL_DEBUG === true) {
27
  $this->jsSuffix = '.js'; //use unminified versions for easier debugging
28
  }
19
  public static $PROCESSABLE_EXTENSIONS = array('jpg', 'jpeg', 'gif', 'png', 'pdf');
20
 
21
  public function __construct() {
 
 
 
 
22
  if (SHORTPIXEL_DEBUG === true) {
23
  $this->jsSuffix = '.js'; //use unminified versions for easier debugging
24
  }
class/wp-shortpixel-settings.php CHANGED
@@ -86,7 +86,7 @@ class WPShortPixelSettings {
86
  'failedImages' => array('key' => 'wp-short-pixel-failed-imgs', 'default' => 0),
87
  'bulkProcessingStatus' => array('key' => 'bulkProcessingStatus', 'default' => null),
88
 
89
- 'priorityQueue' => array('key' => 'wp-short-pixel-priorityQueue', 'default' => array()),
90
  'prioritySkip' => array('key' => 'wp-short-pixel-prioritySkip', 'default' => array()),
91
 
92
  //'' => array('key' => 'wp-short-pixel-', 'default' => null),
@@ -118,9 +118,6 @@ class WPShortPixelSettings {
118
  foreach(self::$_optionsMap as $key => $val) {
119
  delete_option($val['key']);
120
  }
121
- if(isset($_SESSION["wp-short-pixel-priorityQueue"])) {
122
- unset($_SESSION["wp-short-pixel-priorityQueue"]);
123
- }
124
  delete_option("wp-short-pixel-bulk-previous-percent");
125
  }
126
 
@@ -136,7 +133,11 @@ class WPShortPixelSettings {
136
  unset($dismissed['compat']);
137
  update_option('wp-short-pixel-dismissed-notices', $dismissed, 'no');
138
  }
139
-
 
 
 
 
140
  }
141
 
142
  public static function onDeactivate() {
86
  'failedImages' => array('key' => 'wp-short-pixel-failed-imgs', 'default' => 0),
87
  'bulkProcessingStatus' => array('key' => 'bulkProcessingStatus', 'default' => null),
88
 
89
+ //'priorityQueue' => array('key' => 'wp-short-pixel-priorityQueue', 'default' => array()),
90
  'prioritySkip' => array('key' => 'wp-short-pixel-prioritySkip', 'default' => array()),
91
 
92
  //'' => array('key' => 'wp-short-pixel-', 'default' => null),
118
  foreach(self::$_optionsMap as $key => $val) {
119
  delete_option($val['key']);
120
  }
 
 
 
121
  delete_option("wp-short-pixel-bulk-previous-percent");
122
  }
123
 
133
  unset($dismissed['compat']);
134
  update_option('wp-short-pixel-dismissed-notices', $dismissed, 'no');
135
  }
136
+ $formerPrio = get_option('wp-short-pixel-priorityQueue');
137
+ if(is_array($formerPrio) && !count(ShortPixelQueue::get())) {
138
+ ShortPixelQueue::set($formerPrio);
139
+ delete_option('wp-short-pixel-priorityQueue');
140
+ }
141
  }
142
 
143
  public static function onDeactivate() {
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: compress, image, compression, optimize, image optimizer, image optimiser,
4
  Requires at least: 3.2.0
5
  Tested up to: 4.9
6
  Requires PHP: 5.2
7
- Stable tag: 4.8.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -228,6 +228,9 @@ The ShortPixel team is here to help. <a href="https://shortpixel.com/contact">Co
228
 
229
  == Changelog ==
230
 
 
 
 
231
  = 4.8.4 =
232
  * fix compatibility problem with WP 4.9 when editing source files with the new built-in editor
233
  * fix restore converted PNGs in some situations
4
  Requires at least: 3.2.0
5
  Tested up to: 4.9
6
  Requires PHP: 5.2
7
+ Stable tag: 4.8.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
228
 
229
  == Changelog ==
230
 
231
+ = 4.8.5 =
232
+ * drop usage of the PHP session / wp_option for the priority queue - use a flat file instead.
233
+
234
  = 4.8.4 =
235
  * fix compatibility problem with WP 4.9 when editing source files with the new built-in editor
236
  * fix restore converted PNGs in some situations
wp-shortpixel.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
  * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
- * Version: 4.8.4
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * Text Domain: shortpixel-image-optimiser
@@ -18,7 +18,7 @@ define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
18
 
19
  define('SHORTPIXEL_AFFILIATE_CODE', '');
20
 
21
- define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.8.4");
22
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
23
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
24
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
@@ -62,13 +62,13 @@ function shortpixelInit() {
62
 
63
  }
64
  }
65
- //is admin, is logged in - :) seems funny but it's not, ajax scripts are admin even if no admin is logged in.
66
- $prio = get_option('wp-short-pixel-priorityQueue');
67
  $isAjaxButNotSP = defined( 'DOING_AJAX' ) && DOING_AJAX && !(isset($_REQUEST['action']) && (strpos($_REQUEST['action'], 'shortpixel_') === 0));
68
  if (!isset($pluginInstance)
69
  && ( ($prio && is_array($prio) && count($prio) && get_option('wp-short-pixel-front-bootstrap'))
70
  || is_admin() && !$isAjaxButNotSP
71
- && (function_exists("is_user_logged_in") && is_user_logged_in())
72
  && ( current_user_can( 'manage_options' )
73
  || current_user_can( 'upload_files' )
74
  || current_user_can( 'edit_posts' )
3
  * Plugin Name: ShortPixel Image Optimizer
4
  * Plugin URI: https://shortpixel.com/
5
  * Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel" target="_blank">Settings &gt; ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
6
+ * Version: 4.8.5
7
  * Author: ShortPixel
8
  * Author URI: https://shortpixel.com
9
  * Text Domain: shortpixel-image-optimiser
18
 
19
  define('SHORTPIXEL_AFFILIATE_CODE', '');
20
 
21
+ define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.8.5");
22
  define('SHORTPIXEL_MAX_TIMEOUT', 10);
23
  define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
24
  define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
62
 
63
  }
64
  }
65
+ require_once('class/shortpixel_queue.php');
66
+ $prio = ShortPixelQueue::get();
67
  $isAjaxButNotSP = defined( 'DOING_AJAX' ) && DOING_AJAX && !(isset($_REQUEST['action']) && (strpos($_REQUEST['action'], 'shortpixel_') === 0));
68
  if (!isset($pluginInstance)
69
  && ( ($prio && is_array($prio) && count($prio) && get_option('wp-short-pixel-front-bootstrap'))
70
  || is_admin() && !$isAjaxButNotSP
71
+ && (function_exists("is_user_logged_in") && is_user_logged_in()) //is admin, is logged in - :) seems funny but it's not, ajax scripts are admin even if no admin is logged in.
72
  && ( current_user_can( 'manage_options' )
73
  || current_user_can( 'upload_files' )
74
  || current_user_can( 'edit_posts' )