Version Description
Release date: 10th April 2019 * Bulk restore for the Other Media * make the filename extension be updated when manually optimizing a PNG from Media Library, if the convert to JPG is active, without refreshing the page * Integration with Regenerate Thumbnails Advanced new 2.0 beta version * Add the rules for WebP in the WP-CONTENT .htaccess * ShortPixel Other Media - display the time of optimization in the grid and offer option to sort by it * Keep sort order when optimizing / refreshing page on Other Media * offer the visual comparer for Other Media too * resolve the Settings inconsistency in Other Media (settings displayed were from when adding the folder not from when actually optimizing) * Make pressing Escape or clicking outside of any popup close it. * Fixed: Restoring an Other Media item and then Optimizing it again optimizes it Lossless * fix generating the WebP
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 4.13.0 |
Comparing to | |
See all releases |
Code changes from version 4.12.8 to 4.13.0
- class/controller/bulk-restore-all.php +80 -0
- class/controller/controller.php +83 -0
- class/db/shortpixel-custom-meta-dao.php +120 -56
- class/db/shortpixel-meta-facade.php +5 -4
- class/db/wp-shortpixel-db.php +21 -13
- class/db/wp-shortpixel-media-library-adapter.php +1 -4
- class/front/img-to-picture-webp.php +172 -10
- class/model/shortpixel-entity.php +1 -0
- class/model/shortpixel-meta.php +18 -10
- class/shortpixel-tools.php +42 -5
- class/view/shortpixel-list-table.php +128 -58
- class/view/shortpixel_view.php +173 -160
- class/view/view-restore-all.php +47 -0
- class/wp-short-pixel.php +507 -329
- class/wp-shortpixel-settings.php +1 -1
- readme.txt +16 -1
- res/css/short-pixel-bar.css +4 -0
- res/css/short-pixel-bar.min.css +1 -1
- res/css/short-pixel-modal.css +46 -0
- res/css/short-pixel-modal.min.css +1 -0
- res/css/short-pixel.css +25 -69
- res/css/short-pixel.min.css +1 -1
- res/css/shortpixel-admin.css +35 -0
- res/css/shortpixel-admin.min.css +1 -0
- res/css/sp-file-tree.css +15 -3
- res/css/sp-file-tree.min.css +1 -2
- res/img/{robo-cool@2x.png@ → robo-cool@2x.png} +0 -0
- res/img/robo-cool@x2.png +0 -0
- res/js/shortpixel.js +180 -101
- res/js/shortpixel.min.js +1 -1
- res/scss/shortpixel-admin.scss +3 -0
- res/scss/view/_bulk-restore-all.scss +54 -0
- res/scss/view/_settings-advanced.scss +26 -0
- shortpixel_api.php +884 -874
- wp-shortpixel-req.php +7 -6
- wp-shortpixel.php +245 -238
@@ -0,0 +1,80 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
|
4 |
+
|
5 |
+
class BulkRestoreAll extends ShortPixelController
|
6 |
+
{
|
7 |
+
protected static $slug = 'bulk-restore-all';
|
8 |
+
protected $template = 'view-restore-all';
|
9 |
+
|
10 |
+
protected $selected_folders = array();
|
11 |
+
|
12 |
+
public function __construct()
|
13 |
+
{
|
14 |
+
parent::__construct();
|
15 |
+
|
16 |
+
}
|
17 |
+
|
18 |
+
public function randomCheck()
|
19 |
+
{
|
20 |
+
|
21 |
+
$output = '';
|
22 |
+
for ($i=1; $i<= 10; $i++)
|
23 |
+
{
|
24 |
+
$output .= "<span><input type='radio' name='random_check[]' value='$i' onchange='ShortPixel.checkRandomAnswer(event)' /> $i </span>";
|
25 |
+
}
|
26 |
+
|
27 |
+
return $output;
|
28 |
+
}
|
29 |
+
|
30 |
+
public function randomAnswer()
|
31 |
+
{
|
32 |
+
$correct = rand(1,10);
|
33 |
+
$output = "<input type='hidden' name='random_answer' value='$correct' data-target='#bulkRestore' /> <span class='answer'>$correct</span> ";
|
34 |
+
|
35 |
+
return $output;
|
36 |
+
}
|
37 |
+
|
38 |
+
public function getCustomFolders()
|
39 |
+
{
|
40 |
+
//wpshortPixel::refreshCustomFolders();
|
41 |
+
$spMetaDao = $this->shortPixel->getSpMetaDao();
|
42 |
+
$customFolders = $spMetaDao->getFolders();
|
43 |
+
|
44 |
+
return $customFolders;
|
45 |
+
|
46 |
+
}
|
47 |
+
|
48 |
+
protected function processPostData($post)
|
49 |
+
{
|
50 |
+
if (isset($post['selected_folders']))
|
51 |
+
{
|
52 |
+
$folders = array_filter($post['selected_folders'], 'intval');
|
53 |
+
// var_dump($post['selected_folders']);
|
54 |
+
if (count($folders) > 0)
|
55 |
+
{
|
56 |
+
$this->selected_folders = $folders;
|
57 |
+
}
|
58 |
+
unset($post['selected_folders']);
|
59 |
+
}
|
60 |
+
|
61 |
+
parent::processPostData($post);
|
62 |
+
|
63 |
+
}
|
64 |
+
|
65 |
+
public function setupBulk()
|
66 |
+
{
|
67 |
+
// handle the custom folders if there are any.
|
68 |
+
if (count($this->selected_folders) > 0)
|
69 |
+
{
|
70 |
+
$spMetaDao = $this->shortPixel->getSpMetaDao();
|
71 |
+
|
72 |
+
foreach($this->selected_folders as $folder_id)
|
73 |
+
{
|
74 |
+
$spMetaDao->setBulkRestore($folder_id);
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
}
|
@@ -0,0 +1,83 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ShortPixel;
|
4 |
+
|
5 |
+
class ShortPixelController
|
6 |
+
{
|
7 |
+
protected static $controllers = array();
|
8 |
+
|
9 |
+
protected $data = array(); // data array for usage with databases data and such
|
10 |
+
protected $postData = array(); // data coming from form posts.
|
11 |
+
protected $layout; // object to use in the view.
|
12 |
+
|
13 |
+
protected $template = null; // template name to include when loading.
|
14 |
+
|
15 |
+
public static function init()
|
16 |
+
{
|
17 |
+
foreach (get_declared_classes() as $class) {
|
18 |
+
if (is_subclass_of($class, \ShortPixelTools::namespaceit('shortPixelController') ))
|
19 |
+
self::$controllers[] = $class;
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
public static function findControllerbySlug($name)
|
24 |
+
{
|
25 |
+
foreach(self::$controllers as $className)
|
26 |
+
{
|
27 |
+
if ($className::$slug == $name)
|
28 |
+
{
|
29 |
+
return $className; // found!
|
30 |
+
}
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
public function __construct()
|
35 |
+
{
|
36 |
+
$this->layout = new \stdClass;
|
37 |
+
if (isset($_POST) && count($_POST) > 0)
|
38 |
+
{
|
39 |
+
$this->processPostData($_POST);
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
/** Meant as a temporary glue method between all the shortpixel methods and the newer structures
|
44 |
+
*
|
45 |
+
* @param Object $pixel WPShortPixel instance.
|
46 |
+
*/
|
47 |
+
|
48 |
+
public function setShortPixel($pixel)
|
49 |
+
{
|
50 |
+
$this->shortPixel = $pixel;
|
51 |
+
}
|
52 |
+
|
53 |
+
public function loadView()
|
54 |
+
{
|
55 |
+
if (is_null($this->template))
|
56 |
+
{
|
57 |
+
// error
|
58 |
+
return false;
|
59 |
+
}
|
60 |
+
|
61 |
+
$layout = $this->layout;
|
62 |
+
$controller = $this;
|
63 |
+
|
64 |
+
$template_path = \ShortPixelTools::getPluginPath() . 'class/view/' . $this->template . '.php';
|
65 |
+
if (file_exists($template_path))
|
66 |
+
include($template_path);
|
67 |
+
|
68 |
+
}
|
69 |
+
|
70 |
+
protected function processPostData($post)
|
71 |
+
{
|
72 |
+
// most likely to easy .
|
73 |
+
foreach($post as $name => $data )
|
74 |
+
{
|
75 |
+
$this->postData[sanitize_text_field($name)] = sanitize_text_field($data);
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
|
81 |
+
|
82 |
+
|
83 |
+
}
|
@@ -3,7 +3,7 @@
|
|
3 |
Â
class ShortPixelCustomMetaDao {
|
4 |
Â
const META_VERSION = 1;
|
5 |
Â
private $db, $excludePatterns;
|
6 |
-
|
7 |
Â
private static $fields = array(
|
8 |
Â
ShortPixelMeta::TABLE_SUFFIX => array(
|
9 |
Â
"folder_id" => "d",
|
@@ -20,6 +20,8 @@ class ShortPixelCustomMetaDao {
|
|
20 |
Â
"status" => "d",
|
21 |
Â
"retries" => "d",
|
22 |
Â
"message" => "s",
|
Â
|
|
Â
|
|
23 |
Â
"ext_meta_id" => "d" //this is nggPid for now
|
24 |
Â
),
|
25 |
Â
ShortPixelFolder::TABLE_SUFFIX => array(
|
@@ -30,12 +32,12 @@ class ShortPixelCustomMetaDao {
|
|
30 |
Â
"ts_created" => "s",
|
31 |
Â
)
|
32 |
Â
);
|
33 |
-
|
34 |
Â
public function __construct($db, $excludePatterns = false) {
|
35 |
Â
$this->db = $db;
|
36 |
Â
$this->excludePatterns = $excludePatterns;
|
37 |
Â
}
|
38 |
-
|
39 |
Â
public static function getCreateFolderTableSQL($tablePrefix, $charsetCollate) {
|
40 |
Â
return "CREATE TABLE {$tablePrefix}shortpixel_folders (
|
41 |
Â
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
@@ -50,7 +52,7 @@ class ShortPixelCustomMetaDao {
|
|
50 |
Â
) $charsetCollate;";
|
51 |
Â
// UNIQUE INDEX spf_path_md5 (path_md5)
|
52 |
Â
}
|
53 |
-
|
54 |
Â
public static function getCreateMetaTableSQL($tablePrefix, $charsetCollate) {
|
55 |
Â
return "CREATE TABLE {$tablePrefix}shortpixel_meta (
|
56 |
Â
id mediumint(10) NOT NULL AUTO_INCREMENT,
|
@@ -77,7 +79,7 @@ class ShortPixelCustomMetaDao {
|
|
77 |
Â
//UNIQUE INDEX sp_path_md5 (path_md5),
|
78 |
Â
//FOREIGN KEY fk_shortpixel_meta_folder(folder_id) REFERENCES {$tablePrefix}shortpixel_folders(id)
|
79 |
Â
}
|
80 |
-
|
81 |
Â
private function addIfMissing($type, $table, $key, $field, $fkTable = null, $fkField = null) {
|
82 |
Â
$hasIndexSql = "select count(*) hasIndex from information_schema.statistics where table_name = '%s' and index_name = '%s' and table_schema = database()";
|
83 |
Â
$createIndexSql = "ALTER TABLE %s ADD UNIQUE INDEX %s (%s)";
|
@@ -93,7 +95,7 @@ class ShortPixelCustomMetaDao {
|
|
93 |
Â
}
|
94 |
Â
return false;
|
95 |
Â
}
|
96 |
-
|
97 |
Â
public function tablesExist() {
|
98 |
Â
$hasTablesSql = "SELECT COUNT(1) tableCount FROM information_schema.tables WHERE table_schema='".$this->db->getDbName()."' "
|
99 |
Â
. "AND (table_name='".$this->db->getPrefix()."shortpixel_meta' OR table_name='".$this->db->getPrefix()."shortpixel_folders')";
|
@@ -103,26 +105,26 @@ class ShortPixelCustomMetaDao {
|
|
103 |
Â
}
|
104 |
Â
return false;
|
105 |
Â
}
|
106 |
-
|
107 |
Â
public function dropTables() {
|
108 |
Â
if($this->tablesExist()) {
|
109 |
Â
$this->db->query("DROP TABLE ".$this->db->getPrefix()."shortpixel_meta");
|
110 |
Â
$this->db->query("DROP TABLE ".$this->db->getPrefix()."shortpixel_folders");
|
111 |
Â
}
|
112 |
Â
}
|
113 |
-
|
114 |
Â
public function createUpdateShortPixelTables() {
|
115 |
Â
$res = $this->db->createUpdateSchema(array(
|
116 |
Â
self::getCreateFolderTableSQL($this->db->getPrefix(), $this->db->getCharsetCollate()),
|
117 |
-
self::getCreateMetaTableSQL($this->db->getPrefix(), $this->db->getCharsetCollate())
|
118 |
Â
));
|
119 |
Â
// Set up indexes, not handled well by WP DBDelta
|
120 |
Â
$this->addIfMissing("UNIQUE INDEX", $this->db->getPrefix()."shortpixel_folders", "spf_path_md5", "path_md5");
|
121 |
Â
$this->addIfMissing("UNIQUE INDEX", $this->db->getPrefix()."shortpixel_meta", "sp_path_md5", "path_md5");
|
122 |
-
$this->addIfMissing("FOREIGN KEY", $this->db->getPrefix()."shortpixel_meta", "fk_shortpixel_meta_folder", "folder_id",
|
123 |
Â
$this->db->getPrefix()."shortpixel_folders", "id");
|
124 |
Â
}
|
125 |
-
|
126 |
Â
public function getFolders($deleted = false) {
|
127 |
Â
$sql = "SELECT * FROM {$this->db->getPrefix()}shortpixel_folders" . ($deleted ? "" : " WHERE status <> -1");
|
128 |
Â
$rows = $this->db->query($sql);
|
@@ -132,7 +134,7 @@ class ShortPixelCustomMetaDao {
|
|
132 |
Â
}
|
133 |
Â
return $folders;
|
134 |
Â
}
|
135 |
-
|
136 |
Â
public function getFolder($path, $deleted = false) {
|
137 |
Â
$sql = "SELECT * FROM {$this->db->getPrefix()}shortpixel_folders" . ($deleted ? "" : " WHERE path = %s AND status <> -1");
|
138 |
Â
$rows = $this->db->query($sql, array($path));
|
@@ -142,21 +144,21 @@ class ShortPixelCustomMetaDao {
|
|
142 |
Â
}
|
143 |
Â
return false;
|
144 |
Â
}
|
145 |
-
|
146 |
Â
public function hasFoldersTable() {
|
147 |
Â
global $wpdb;
|
148 |
Â
$foldersTable = $wpdb->get_results("SELECT COUNT(1) hasFoldersTable FROM information_schema.tables WHERE table_schema='{$wpdb->dbname}' AND table_name='{$wpdb->prefix}shortpixel_folders'");
|
149 |
Â
if(isset($foldersTable[0]->hasFoldersTable) && $foldersTable[0]->hasFoldersTable > 0) {
|
150 |
Â
return true;
|
151 |
Â
}
|
152 |
-
return false;
|
153 |
Â
}
|
154 |
-
|
155 |
Â
public function addFolder($folder, $fileCount = 0) {
|
156 |
Â
//$sql = "INSERT INTO {$this->db->getPrefix()}shortpixel_folders (path, file_count, ts_created) values (%s, %d, now())";
|
157 |
Â
//$this->db->query($sql, array($folder, $fileCount));
|
158 |
-
return $this->db->insert($this->db->getPrefix().'shortpixel_folders',
|
159 |
-
array("path" => $folder, "path_md5" => md5($folder), "file_count" => $fileCount, "ts_updated" => date("Y-m-d H:i:s")),
|
160 |
Â
array("path" => "%s", "path_md5" => "%s", "file_count" => "%d", "ts_updated" => "%s"));
|
161 |
Â
}
|
162 |
Â
|
@@ -224,16 +226,16 @@ class ShortPixelCustomMetaDao {
|
|
224 |
Â
return __('The folder could not be saved to the database. Please check that the plugin can create its database tables.', 'shortpixel-image-optimiser') . $folderMsg;
|
225 |
Â
}
|
226 |
Â
}
|
227 |
-
|
228 |
Â
if(!$folderMsg) {
|
229 |
Â
$fileList = $folder->getFileList();
|
230 |
Â
$this->batchInsertImages($fileList, $folder->getId());
|
231 |
Â
}
|
232 |
Â
return $folderMsg;
|
233 |
-
|
234 |
Â
}
|
235 |
Â
/**
|
236 |
-
*
|
237 |
Â
* @param type $path
|
238 |
Â
* @return false if saved OK, error message otherwise.
|
239 |
Â
*/
|
@@ -269,8 +271,8 @@ class ShortPixelCustomMetaDao {
|
|
269 |
Â
}
|
270 |
Â
} else {
|
271 |
Â
return __('Folder does not exist.','shortpixel-image-optimiser');
|
272 |
-
}
|
273 |
-
}
|
274 |
Â
|
275 |
Â
protected function metaToParams($meta) {
|
276 |
Â
$params = $types = array();
|
@@ -292,14 +294,14 @@ class ShortPixelCustomMetaDao {
|
|
292 |
Â
$id = $this->db->insert($this->db->getPrefix().'shortpixel_meta', $p->params, $p->types);
|
293 |
Â
return $id;
|
294 |
Â
}
|
295 |
-
|
296 |
Â
public function batchInsertImages($pathsFile, $folderId) {
|
297 |
Â
$pathsFileHandle = fopen($pathsFile, 'r');
|
298 |
-
|
299 |
Â
//facem un delete pe cele care nu au shortpixel_folder, pentru curatenie - am mai intalnit situatii in care stergerea s-a agatat (stop monitoring)
|
300 |
Â
$sqlCleanup = "DELETE FROM {$this->db->getPrefix()}shortpixel_meta WHERE folder_id NOT IN (SELECT id FROM {$this->db->getPrefix()}shortpixel_folders)";
|
301 |
Â
$this->db->query($sqlCleanup);
|
302 |
-
|
303 |
Â
$values = ''; $inserted = 0;
|
304 |
Â
$sql = "INSERT IGNORE INTO {$this->db->getPrefix()}shortpixel_meta(folder_id, path, name, path_md5, status) VALUES ";
|
305 |
Â
for ($i = 0; ($path = fgets($pathsFileHandle)) !== false; $i++) {
|
@@ -319,37 +321,45 @@ class ShortPixelCustomMetaDao {
|
|
319 |
Â
unlink($pathsFile);
|
320 |
Â
return $inserted;
|
321 |
Â
}
|
322 |
-
|
323 |
Â
public function resetFailed() {
|
324 |
Â
$sql = "UPDATE {$this->db->getPrefix()}shortpixel_meta SET status = 0, retries = 0 WHERE status < 0";
|
325 |
Â
$this->db->query($sql);
|
326 |
Â
}
|
327 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
328 |
Â
public function getPaginatedMetas($hasNextGen, $filters, $count, $page, $orderby = false, $order = false) {
|
Â
|
|
329 |
Â
$sql = "SELECT sm.id, sm.name, sm.path folder, "
|
330 |
Â
. ($hasNextGen ? "CASE WHEN ng.gid IS NOT NULL THEN 'NextGen' ELSE 'Custom' END media_type, " : "'Custom' media_type, ")
|
331 |
-
. "sm.status, sm.compression_type, sm.keep_exif, sm.cmyk2rgb, sm.resize, sm.resize_width, sm.resize_height, sm.message "
|
332 |
Â
. "FROM {$this->db->getPrefix()}shortpixel_meta sm "
|
333 |
Â
. "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
|
334 |
Â
. ($hasNextGen ? "LEFT JOIN {$this->db->getPrefix()}ngg_gallery ng on sf.path = ng.path " : " ")
|
335 |
-
. "WHERE sf.status <> -1 AND sm.status <> 3
|
336 |
Â
foreach($filters as $field => $value) {
|
337 |
Â
$sql .= " AND sm.$field " . $value->operator . " ". $value->value . " ";
|
338 |
-
}
|
339 |
Â
$sql .= ($orderby ? " ORDER BY $orderby $order " : "")
|
340 |
Â
. " LIMIT $count OFFSET " . ($page - 1) * $count;
|
341 |
-
|
342 |
-
//die($sql);
|
343 |
Â
return $this->db->query($sql);
|
344 |
Â
}
|
345 |
-
|
346 |
Â
public function getPendingMetas($count) {
|
347 |
Â
return $this->db->query("SELECT sm.id from {$this->db->getPrefix()}shortpixel_meta sm "
|
348 |
Â
. "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
|
349 |
Â
. "WHERE sf.status <> -1 AND sm.status <> 3 AND ( sm.status = 0 OR sm.status = 1 OR (sm.status < 0 AND sm.retries < 3)) "
|
350 |
Â
. "ORDER BY sm.id DESC LIMIT $count");
|
351 |
Â
}
|
352 |
-
|
353 |
Â
public function getFolderOptimizationStatus($folderId) {
|
354 |
Â
$res = $this->db->query("SELECT SUM(CASE WHEN sm.status = 2 THEN 1 ELSE 0 END) Optimized, SUM(CASE WHEN sm.status = 1 THEN 1 ELSE 0 END) Pending, "
|
355 |
Â
. "SUM(CASE WHEN sm.status = 0 THEN 1 ELSE 0 END) Waiting, SUM(CASE WHEN sm.status < 0 THEN 1 ELSE 0 END) Failed, count(*) Total "
|
@@ -358,26 +368,50 @@ class ShortPixelCustomMetaDao {
|
|
358 |
Â
. "WHERE sf.id = $folderId");
|
359 |
Â
return $res[0];
|
360 |
Â
}
|
361 |
-
|
362 |
Â
public function getPendingMetaCount() {
|
363 |
Â
$res = $this->db->query("SELECT COUNT(sm.id) recCount from {$this->db->getPrefix()}shortpixel_meta sm "
|
364 |
Â
. "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
|
365 |
Â
. "WHERE sf.status <> -1 AND sm.status <> 3 AND ( sm.status = 0 OR sm.status = 1 OR (sm.status < 0 AND sm.retries < 3))");
|
366 |
Â
return isset($res[0]->recCount) ? $res[0]->recCount : null;
|
367 |
Â
}
|
368 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
369 |
Â
public function getCustomMetaCount($filters = array()) {
|
Â
|
|
370 |
Â
$sql = "SELECT COUNT(sm.id) recCount FROM {$this->db->getPrefix()}shortpixel_meta sm "
|
371 |
Â
. "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
|
372 |
-
. "WHERE sf.status <> -1 AND sm.status <> 3
|
373 |
Â
foreach($filters as $field => $value) {
|
374 |
Â
$sql .= " AND sm.$field " . $value->operator . " ". $value->value . " ";
|
375 |
Â
}
|
376 |
-
|
377 |
Â
$res = $this->db->query($sql);
|
378 |
Â
return isset($res[0]->recCount) ? $res[0]->recCount : 0;
|
379 |
Â
}
|
380 |
-
|
381 |
Â
public function getMeta($id, $deleted = false) {
|
382 |
Â
$sql = "SELECT * FROM {$this->db->getPrefix()}shortpixel_meta WHERE id = %d " . ($deleted ? "" : " AND status <> -1");
|
383 |
Â
$rows = $this->db->query($sql, array($id));
|
@@ -386,44 +420,74 @@ class ShortPixelCustomMetaDao {
|
|
386 |
Â
if($meta->getPath()) {
|
387 |
Â
$meta->setWebPath(ShortPixelMetaFacade::filenameToRootRelative($meta->getPath()));
|
388 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
389 |
Â
//die(var_dump($meta)."ZA META");
|
390 |
Â
return $meta;
|
391 |
Â
}
|
392 |
-
return null;
|
393 |
Â
}
|
394 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
395 |
Â
public function getMetaForPath($path, $deleted = false) {
|
396 |
Â
$sql = "SELECT * FROM {$this->db->getPrefix()}shortpixel_meta WHERE path = %s " . ($deleted ? "" : " AND status <> -1");
|
397 |
Â
$rows = $this->db->query($sql, array($path));
|
398 |
Â
foreach($rows as $row) {
|
399 |
Â
return new ShortPixelMeta($row);
|
400 |
Â
}
|
401 |
-
return null;
|
402 |
Â
}
|
403 |
-
|
404 |
Â
public function update($meta) {
|
405 |
Â
$metaClass = get_class($meta);
|
406 |
Â
$tableSuffix = "";
|
407 |
-
|
408 |
-
$
|
Â
|
|
Â
|
|
409 |
Â
foreach(self::$fields[$tableSuffix] as $field => $type) {
|
410 |
Â
$getter = "get" . ShortPixelTools::snakeToCamel($field);
|
411 |
Â
$val = $meta->$getter();
|
412 |
Â
if($meta->$getter() !== null) {
|
413 |
-
$sql .= " {$field} = %{$type},";
|
Â
|
|
414 |
Â
}
|
415 |
Â
}
|
416 |
-
|
417 |
Â
if(substr($sql, -1) != ',') {
|
418 |
Â
return; //no fields added;
|
419 |
-
}
|
420 |
-
|
421 |
Â
$sql = rtrim($sql, ",");
|
422 |
Â
$sql .= " WHERE id = %d";
|
423 |
Â
$params[] = $meta->getId();
|
424 |
Â
$this->db->query($sql, $params);
|
425 |
Â
}
|
426 |
-
|
427 |
Â
public function delete($meta) {
|
428 |
Â
$metaClass = get_class($meta);
|
429 |
Â
$tableSuffix = "";
|
@@ -431,7 +495,7 @@ class ShortPixelCustomMetaDao {
|
|
431 |
Â
$sql = "DELETE FROM {$this->db->getPrefix()}shortpixel_" . $tableSuffix . " WHERE id = %d";
|
432 |
Â
$this->db->query($sql, array($meta->getId()));
|
433 |
Â
}
|
434 |
-
|
435 |
Â
public function countAllProcessableFiles() {
|
436 |
Â
$sql = "SELECT count(*) totalFiles, sum(CASE WHEN status = 2 THEN 1 ELSE 0 END) totalProcessedFiles,"
|
437 |
Â
." sum(CASE WHEN status = 2 AND compression_type = 1 THEN 1 ELSE 0 END) totalProcLossyFiles,"
|
@@ -439,7 +503,7 @@ class ShortPixelCustomMetaDao {
|
|
439 |
Â
." sum(CASE WHEN status = 2 AND compression_type = 0 THEN 1 ELSE 0 END) totalProcLosslessFiles"
|
440 |
Â
." FROM {$this->db->getPrefix()}shortpixel_meta WHERE status <> -1";
|
441 |
Â
$rows = $this->db->query($sql);
|
442 |
-
|
443 |
Â
$filesWithErrors = array();
|
444 |
Â
$sql = "SELECT id, name, path, message FROM {$this->db->getPrefix()}shortpixel_meta WHERE status < -1 AND retries >= 3 LIMIT 30";
|
445 |
Â
$failRows = $this->db->query($sql);
|
@@ -451,17 +515,17 @@ class ShortPixelCustomMetaDao {
|
|
451 |
Â
$moreFilesWithErrors++;
|
452 |
Â
}
|
453 |
Â
}
|
454 |
-
|
455 |
Â
if(!isset($rows[0])) {
|
456 |
Â
$rows[0] = (object)array('totalFiles' => 0, 'totalProcessedFiles' => 0, 'totalProcLossyFiles' => 0, 'totalProcGlossyFiles' => 0, 'totalProcLosslessFiles' => 0);
|
457 |
Â
}
|
458 |
-
|
459 |
-
return array("totalFiles" => $rows[0]->totalFiles, "mainFiles" => $rows[0]->totalFiles,
|
460 |
Â
"totalProcessedFiles" => $rows[0]->totalProcessedFiles, "mainProcessedFiles" => $rows[0]->totalProcessedFiles,
|
461 |
Â
"totalProcLossyFiles" => $rows[0]->totalProcLossyFiles, "mainProcLossyFiles" => $rows[0]->totalProcLossyFiles,
|
462 |
Â
"totalProcGlossyFiles" => $rows[0]->totalProcGlossyFiles, "mainProcGlossyFiles" => $rows[0]->totalProcGlossyFiles,
|
463 |
Â
"totalProcLosslessFiles" => $rows[0]->totalProcLosslessFiles, "mainProcLosslessFiles" => $rows[0]->totalProcLosslessFiles,
|
464 |
-
"totalCustomFiles" => $rows[0]->totalFiles, "mainCustomFiles" => $rows[0]->totalFiles,
|
465 |
Â
"totalProcessedCustomFiles" => $rows[0]->totalProcessedFiles, "mainProcessedCustomFiles" => $rows[0]->totalProcessedFiles,
|
466 |
Â
"totalProcLossyCustomFiles" => $rows[0]->totalProcLossyFiles, "mainProcLossyCustomFiles" => $rows[0]->totalProcLossyFiles,
|
467 |
Â
"totalProcGlossyCustomFiles" => $rows[0]->totalProcGlossyFiles, "mainProcGlossyCustomFiles" => $rows[0]->totalProcGlossyFiles,
|
@@ -469,6 +533,6 @@ class ShortPixelCustomMetaDao {
|
|
469 |
Â
"filesWithErrors" => $filesWithErrors,
|
470 |
Â
"moreFilesWithErrors" => $moreFilesWithErrors
|
471 |
Â
);
|
472 |
-
|
473 |
Â
}
|
474 |
Â
}
|
3 |
Â
class ShortPixelCustomMetaDao {
|
4 |
Â
const META_VERSION = 1;
|
5 |
Â
private $db, $excludePatterns;
|
6 |
+
|
7 |
Â
private static $fields = array(
|
8 |
Â
ShortPixelMeta::TABLE_SUFFIX => array(
|
9 |
Â
"folder_id" => "d",
|
20 |
Â
"status" => "d",
|
21 |
Â
"retries" => "d",
|
22 |
Â
"message" => "s",
|
23 |
+
"ts_added" => 's',
|
24 |
+
"ts_optimized" => 's',
|
25 |
Â
"ext_meta_id" => "d" //this is nggPid for now
|
26 |
Â
),
|
27 |
Â
ShortPixelFolder::TABLE_SUFFIX => array(
|
32 |
Â
"ts_created" => "s",
|
33 |
Â
)
|
34 |
Â
);
|
35 |
+
|
36 |
Â
public function __construct($db, $excludePatterns = false) {
|
37 |
Â
$this->db = $db;
|
38 |
Â
$this->excludePatterns = $excludePatterns;
|
39 |
Â
}
|
40 |
+
|
41 |
Â
public static function getCreateFolderTableSQL($tablePrefix, $charsetCollate) {
|
42 |
Â
return "CREATE TABLE {$tablePrefix}shortpixel_folders (
|
43 |
Â
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
52 |
Â
) $charsetCollate;";
|
53 |
Â
// UNIQUE INDEX spf_path_md5 (path_md5)
|
54 |
Â
}
|
55 |
+
|
56 |
Â
public static function getCreateMetaTableSQL($tablePrefix, $charsetCollate) {
|
57 |
Â
return "CREATE TABLE {$tablePrefix}shortpixel_meta (
|
58 |
Â
id mediumint(10) NOT NULL AUTO_INCREMENT,
|
79 |
Â
//UNIQUE INDEX sp_path_md5 (path_md5),
|
80 |
Â
//FOREIGN KEY fk_shortpixel_meta_folder(folder_id) REFERENCES {$tablePrefix}shortpixel_folders(id)
|
81 |
Â
}
|
82 |
+
|
83 |
Â
private function addIfMissing($type, $table, $key, $field, $fkTable = null, $fkField = null) {
|
84 |
Â
$hasIndexSql = "select count(*) hasIndex from information_schema.statistics where table_name = '%s' and index_name = '%s' and table_schema = database()";
|
85 |
Â
$createIndexSql = "ALTER TABLE %s ADD UNIQUE INDEX %s (%s)";
|
95 |
Â
}
|
96 |
Â
return false;
|
97 |
Â
}
|
98 |
+
|
99 |
Â
public function tablesExist() {
|
100 |
Â
$hasTablesSql = "SELECT COUNT(1) tableCount FROM information_schema.tables WHERE table_schema='".$this->db->getDbName()."' "
|
101 |
Â
. "AND (table_name='".$this->db->getPrefix()."shortpixel_meta' OR table_name='".$this->db->getPrefix()."shortpixel_folders')";
|
105 |
Â
}
|
106 |
Â
return false;
|
107 |
Â
}
|
108 |
+
|
109 |
Â
public function dropTables() {
|
110 |
Â
if($this->tablesExist()) {
|
111 |
Â
$this->db->query("DROP TABLE ".$this->db->getPrefix()."shortpixel_meta");
|
112 |
Â
$this->db->query("DROP TABLE ".$this->db->getPrefix()."shortpixel_folders");
|
113 |
Â
}
|
114 |
Â
}
|
115 |
+
|
116 |
Â
public function createUpdateShortPixelTables() {
|
117 |
Â
$res = $this->db->createUpdateSchema(array(
|
118 |
Â
self::getCreateFolderTableSQL($this->db->getPrefix(), $this->db->getCharsetCollate()),
|
119 |
+
self::getCreateMetaTableSQL($this->db->getPrefix(), $this->db->getCharsetCollate())
|
120 |
Â
));
|
121 |
Â
// Set up indexes, not handled well by WP DBDelta
|
122 |
Â
$this->addIfMissing("UNIQUE INDEX", $this->db->getPrefix()."shortpixel_folders", "spf_path_md5", "path_md5");
|
123 |
Â
$this->addIfMissing("UNIQUE INDEX", $this->db->getPrefix()."shortpixel_meta", "sp_path_md5", "path_md5");
|
124 |
+
$this->addIfMissing("FOREIGN KEY", $this->db->getPrefix()."shortpixel_meta", "fk_shortpixel_meta_folder", "folder_id",
|
125 |
Â
$this->db->getPrefix()."shortpixel_folders", "id");
|
126 |
Â
}
|
127 |
+
|
128 |
Â
public function getFolders($deleted = false) {
|
129 |
Â
$sql = "SELECT * FROM {$this->db->getPrefix()}shortpixel_folders" . ($deleted ? "" : " WHERE status <> -1");
|
130 |
Â
$rows = $this->db->query($sql);
|
134 |
Â
}
|
135 |
Â
return $folders;
|
136 |
Â
}
|
137 |
+
|
138 |
Â
public function getFolder($path, $deleted = false) {
|
139 |
Â
$sql = "SELECT * FROM {$this->db->getPrefix()}shortpixel_folders" . ($deleted ? "" : " WHERE path = %s AND status <> -1");
|
140 |
Â
$rows = $this->db->query($sql, array($path));
|
144 |
Â
}
|
145 |
Â
return false;
|
146 |
Â
}
|
147 |
+
|
148 |
Â
public function hasFoldersTable() {
|
149 |
Â
global $wpdb;
|
150 |
Â
$foldersTable = $wpdb->get_results("SELECT COUNT(1) hasFoldersTable FROM information_schema.tables WHERE table_schema='{$wpdb->dbname}' AND table_name='{$wpdb->prefix}shortpixel_folders'");
|
151 |
Â
if(isset($foldersTable[0]->hasFoldersTable) && $foldersTable[0]->hasFoldersTable > 0) {
|
152 |
Â
return true;
|
153 |
Â
}
|
154 |
+
return false;
|
155 |
Â
}
|
156 |
+
|
157 |
Â
public function addFolder($folder, $fileCount = 0) {
|
158 |
Â
//$sql = "INSERT INTO {$this->db->getPrefix()}shortpixel_folders (path, file_count, ts_created) values (%s, %d, now())";
|
159 |
Â
//$this->db->query($sql, array($folder, $fileCount));
|
160 |
+
return $this->db->insert($this->db->getPrefix().'shortpixel_folders',
|
161 |
+
array("path" => $folder, "path_md5" => md5($folder), "file_count" => $fileCount, "ts_updated" => date("Y-m-d H:i:s")),
|
162 |
Â
array("path" => "%s", "path_md5" => "%s", "file_count" => "%d", "ts_updated" => "%s"));
|
163 |
Â
}
|
164 |
Â
|
226 |
Â
return __('The folder could not be saved to the database. Please check that the plugin can create its database tables.', 'shortpixel-image-optimiser') . $folderMsg;
|
227 |
Â
}
|
228 |
Â
}
|
229 |
+
|
230 |
Â
if(!$folderMsg) {
|
231 |
Â
$fileList = $folder->getFileList();
|
232 |
Â
$this->batchInsertImages($fileList, $folder->getId());
|
233 |
Â
}
|
234 |
Â
return $folderMsg;
|
235 |
+
|
236 |
Â
}
|
237 |
Â
/**
|
238 |
+
*
|
239 |
Â
* @param type $path
|
240 |
Â
* @return false if saved OK, error message otherwise.
|
241 |
Â
*/
|
271 |
Â
}
|
272 |
Â
} else {
|
273 |
Â
return __('Folder does not exist.','shortpixel-image-optimiser');
|
274 |
+
}
|
275 |
+
}
|
276 |
Â
|
277 |
Â
protected function metaToParams($meta) {
|
278 |
Â
$params = $types = array();
|
294 |
Â
$id = $this->db->insert($this->db->getPrefix().'shortpixel_meta', $p->params, $p->types);
|
295 |
Â
return $id;
|
296 |
Â
}
|
297 |
+
|
298 |
Â
public function batchInsertImages($pathsFile, $folderId) {
|
299 |
Â
$pathsFileHandle = fopen($pathsFile, 'r');
|
300 |
+
|
301 |
Â
//facem un delete pe cele care nu au shortpixel_folder, pentru curatenie - am mai intalnit situatii in care stergerea s-a agatat (stop monitoring)
|
302 |
Â
$sqlCleanup = "DELETE FROM {$this->db->getPrefix()}shortpixel_meta WHERE folder_id NOT IN (SELECT id FROM {$this->db->getPrefix()}shortpixel_folders)";
|
303 |
Â
$this->db->query($sqlCleanup);
|
304 |
+
|
305 |
Â
$values = ''; $inserted = 0;
|
306 |
Â
$sql = "INSERT IGNORE INTO {$this->db->getPrefix()}shortpixel_meta(folder_id, path, name, path_md5, status) VALUES ";
|
307 |
Â
for ($i = 0; ($path = fgets($pathsFileHandle)) !== false; $i++) {
|
321 |
Â
unlink($pathsFile);
|
322 |
Â
return $inserted;
|
323 |
Â
}
|
324 |
+
|
325 |
Â
public function resetFailed() {
|
326 |
Â
$sql = "UPDATE {$this->db->getPrefix()}shortpixel_meta SET status = 0, retries = 0 WHERE status < 0";
|
327 |
Â
$this->db->query($sql);
|
328 |
Â
}
|
329 |
+
|
330 |
+
/** Reset Restored items
|
331 |
+
* On Bulk Optimize, Reset the restored status so it will process these images again.
|
332 |
+
*
|
333 |
+
**/
|
334 |
+
public function resetRestored() {
|
335 |
+
$sql = "UPDATE {$this->db->getPrefix()}shortpixel_meta SET status = 0, retries = 0 WHERE status = 3";
|
336 |
+
$this->db->query($sql);
|
337 |
+
}
|
338 |
+
|
339 |
Â
public function getPaginatedMetas($hasNextGen, $filters, $count, $page, $orderby = false, $order = false) {
|
340 |
+
// [BS] Remove exclusion for sm.status <> 3. Status 3 is 'restored, perform no action'
|
341 |
Â
$sql = "SELECT sm.id, sm.name, sm.path folder, "
|
342 |
Â
. ($hasNextGen ? "CASE WHEN ng.gid IS NOT NULL THEN 'NextGen' ELSE 'Custom' END media_type, " : "'Custom' media_type, ")
|
343 |
+
. "sm.status, sm.compression_type, sm.keep_exif, sm.cmyk2rgb, sm.resize, sm.resize_width, sm.resize_height, sm.message, sm.ts_added, sm.ts_optimized "
|
344 |
Â
. "FROM {$this->db->getPrefix()}shortpixel_meta sm "
|
345 |
Â
. "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
|
346 |
Â
. ($hasNextGen ? "LEFT JOIN {$this->db->getPrefix()}ngg_gallery ng on sf.path = ng.path " : " ")
|
347 |
+
. "WHERE sf.status <> -1"; // AND sm.status <> 3
|
348 |
Â
foreach($filters as $field => $value) {
|
349 |
Â
$sql .= " AND sm.$field " . $value->operator . " ". $value->value . " ";
|
350 |
+
}
|
351 |
Â
$sql .= ($orderby ? " ORDER BY $orderby $order " : "")
|
352 |
Â
. " LIMIT $count OFFSET " . ($page - 1) * $count;
|
Â
|
|
Â
|
|
353 |
Â
return $this->db->query($sql);
|
354 |
Â
}
|
355 |
+
|
356 |
Â
public function getPendingMetas($count) {
|
357 |
Â
return $this->db->query("SELECT sm.id from {$this->db->getPrefix()}shortpixel_meta sm "
|
358 |
Â
. "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
|
359 |
Â
. "WHERE sf.status <> -1 AND sm.status <> 3 AND ( sm.status = 0 OR sm.status = 1 OR (sm.status < 0 AND sm.retries < 3)) "
|
360 |
Â
. "ORDER BY sm.id DESC LIMIT $count");
|
361 |
Â
}
|
362 |
+
|
363 |
Â
public function getFolderOptimizationStatus($folderId) {
|
364 |
Â
$res = $this->db->query("SELECT SUM(CASE WHEN sm.status = 2 THEN 1 ELSE 0 END) Optimized, SUM(CASE WHEN sm.status = 1 THEN 1 ELSE 0 END) Pending, "
|
365 |
Â
. "SUM(CASE WHEN sm.status = 0 THEN 1 ELSE 0 END) Waiting, SUM(CASE WHEN sm.status < 0 THEN 1 ELSE 0 END) Failed, count(*) Total "
|
368 |
Â
. "WHERE sf.id = $folderId");
|
369 |
Â
return $res[0];
|
370 |
Â
}
|
371 |
+
|
372 |
Â
public function getPendingMetaCount() {
|
373 |
Â
$res = $this->db->query("SELECT COUNT(sm.id) recCount from {$this->db->getPrefix()}shortpixel_meta sm "
|
374 |
Â
. "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
|
375 |
Â
. "WHERE sf.status <> -1 AND sm.status <> 3 AND ( sm.status = 0 OR sm.status = 1 OR (sm.status < 0 AND sm.retries < 3))");
|
376 |
Â
return isset($res[0]->recCount) ? $res[0]->recCount : null;
|
377 |
Â
}
|
378 |
+
|
379 |
+
/** Get all Custom Meta when status is other than 'restored' **/
|
380 |
+
public function getPendingBulkRestore($count)
|
381 |
+
{
|
382 |
+
return $this->db->query("SELECT sm.id from {$this->db->getPrefix()}shortpixel_meta sm "
|
383 |
+
. "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
|
384 |
+
. "WHERE sf.status <> -1 AND sm.status = " . ShortPixelMeta::FILE_STATUS_TORESTORE
|
385 |
+
. " ORDER BY sm.id DESC LIMIT $count");
|
386 |
+
}
|
387 |
+
|
388 |
+
/** Sets files from folders that are selected for bulk restore to the status 'To Restore';
|
389 |
+
*
|
390 |
+
*/
|
391 |
+
public function setBulkRestore($folder_id)
|
392 |
+
{
|
393 |
+
if (! is_numeric($folder_id) || $folder_id <= 0)
|
394 |
+
return false;
|
395 |
+
|
396 |
+
$table = $this->db->getPrefix() . 'shortpixel_meta';
|
397 |
+
//$sql = "UPDATE status on "; ShortPixelMeta::FILE_STATUS_TORESTORE
|
398 |
+
$this->db->update($table, array('status' => ShortPixelMeta::FILE_STATUS_TORESTORE), array('folder_id' => $folder_id), '%d', '%d' );
|
399 |
+
}
|
400 |
+
|
401 |
+
|
402 |
Â
public function getCustomMetaCount($filters = array()) {
|
403 |
+
// [BS] Remove exclusion for sm.status <> 3. Status 3 is 'restored, perform no action'
|
404 |
Â
$sql = "SELECT COUNT(sm.id) recCount FROM {$this->db->getPrefix()}shortpixel_meta sm "
|
405 |
Â
. "INNER JOIN {$this->db->getPrefix()}shortpixel_folders sf on sm.folder_id = sf.id "
|
406 |
+
. "WHERE sf.status <> -1"; // AND sm.status <> 3
|
407 |
Â
foreach($filters as $field => $value) {
|
408 |
Â
$sql .= " AND sm.$field " . $value->operator . " ". $value->value . " ";
|
409 |
Â
}
|
410 |
+
|
411 |
Â
$res = $this->db->query($sql);
|
412 |
Â
return isset($res[0]->recCount) ? $res[0]->recCount : 0;
|
413 |
Â
}
|
414 |
+
|
415 |
Â
public function getMeta($id, $deleted = false) {
|
416 |
Â
$sql = "SELECT * FROM {$this->db->getPrefix()}shortpixel_meta WHERE id = %d " . ($deleted ? "" : " AND status <> -1");
|
417 |
Â
$rows = $this->db->query($sql, array($id));
|
420 |
Â
if($meta->getPath()) {
|
421 |
Â
$meta->setWebPath(ShortPixelMetaFacade::filenameToRootRelative($meta->getPath()));
|
422 |
Â
}
|
423 |
+
if ($meta->getStatus() == $meta::FILE_STATUS_UNPROCESSED)
|
424 |
+
{
|
425 |
+
$meta = $this->updateMetaWithSettings($meta);
|
426 |
+
}
|
427 |
Â
//die(var_dump($meta)."ZA META");
|
428 |
Â
return $meta;
|
429 |
Â
}
|
430 |
+
return null;
|
431 |
Â
}
|
432 |
Â
|
433 |
+
/** If File is not yet processed, don't use empty default meta, but use the global settings
|
434 |
+
*
|
435 |
+
* @param $meta ShortPixelMeta object
|
436 |
+
* @return ShortPixelMetaObject - Replaced meta object data
|
437 |
+
* @author Bas Schuiling
|
438 |
+
*/
|
439 |
+
protected function updateMetaWithSettings($meta)
|
440 |
+
{
|
441 |
+
$objSettings = new WPShortPixelSettings();
|
442 |
+
|
443 |
+
$meta->setKeepExif( $objSettings->keepExif );
|
444 |
+
$meta->setCmyk2rgb($objSettings->CMYKtoRGBconversion);
|
445 |
+
$meta->setResize($objSettings->resizeImages);
|
446 |
+
$meta->setResizeWidth($objSettings->resizeWidth);
|
447 |
+
$meta->setResizeHeight($objSettings->resizeHeight);
|
448 |
+
$meta->setCompressionType($objSettings->compressionType);
|
449 |
+
$meta->setBackup($objSettings->backupImages);
|
450 |
+
// update the record. If the image is pending the meta will be requested again.
|
451 |
+
$this->update($meta);
|
452 |
+
return $meta;
|
453 |
+
}
|
454 |
+
|
455 |
+
|
456 |
Â
public function getMetaForPath($path, $deleted = false) {
|
457 |
Â
$sql = "SELECT * FROM {$this->db->getPrefix()}shortpixel_meta WHERE path = %s " . ($deleted ? "" : " AND status <> -1");
|
458 |
Â
$rows = $this->db->query($sql, array($path));
|
459 |
Â
foreach($rows as $row) {
|
460 |
Â
return new ShortPixelMeta($row);
|
461 |
Â
}
|
462 |
+
return null;
|
463 |
Â
}
|
464 |
+
|
465 |
Â
public function update($meta) {
|
466 |
Â
$metaClass = get_class($meta);
|
467 |
Â
$tableSuffix = "";
|
468 |
+
$tableSuffix = $metaClass::TABLE_SUFFIX;
|
469 |
+
$prefix = $this->db->getPrefix();
|
470 |
+
// eval( '$tableSuffix = ' . $metaClass . '::TABLE_SUFFIX;'); // horror!
|
471 |
+
$sql = "UPDATE " . $prefix . "shortpixel_" . $tableSuffix . " SET ";
|
472 |
Â
foreach(self::$fields[$tableSuffix] as $field => $type) {
|
473 |
Â
$getter = "get" . ShortPixelTools::snakeToCamel($field);
|
474 |
Â
$val = $meta->$getter();
|
475 |
Â
if($meta->$getter() !== null) {
|
476 |
+
$sql .= " {$field} = %{$type},";
|
477 |
+
$params[] = $val;
|
478 |
Â
}
|
479 |
Â
}
|
480 |
+
|
481 |
Â
if(substr($sql, -1) != ',') {
|
482 |
Â
return; //no fields added;
|
483 |
+
}
|
484 |
+
|
485 |
Â
$sql = rtrim($sql, ",");
|
486 |
Â
$sql .= " WHERE id = %d";
|
487 |
Â
$params[] = $meta->getId();
|
488 |
Â
$this->db->query($sql, $params);
|
489 |
Â
}
|
490 |
+
|
491 |
Â
public function delete($meta) {
|
492 |
Â
$metaClass = get_class($meta);
|
493 |
Â
$tableSuffix = "";
|
495 |
Â
$sql = "DELETE FROM {$this->db->getPrefix()}shortpixel_" . $tableSuffix . " WHERE id = %d";
|
496 |
Â
$this->db->query($sql, array($meta->getId()));
|
497 |
Â
}
|
498 |
+
|
499 |
Â
public function countAllProcessableFiles() {
|
500 |
Â
$sql = "SELECT count(*) totalFiles, sum(CASE WHEN status = 2 THEN 1 ELSE 0 END) totalProcessedFiles,"
|
501 |
Â
." sum(CASE WHEN status = 2 AND compression_type = 1 THEN 1 ELSE 0 END) totalProcLossyFiles,"
|
503 |
Â
." sum(CASE WHEN status = 2 AND compression_type = 0 THEN 1 ELSE 0 END) totalProcLosslessFiles"
|
504 |
Â
." FROM {$this->db->getPrefix()}shortpixel_meta WHERE status <> -1";
|
505 |
Â
$rows = $this->db->query($sql);
|
506 |
+
|
507 |
Â
$filesWithErrors = array();
|
508 |
Â
$sql = "SELECT id, name, path, message FROM {$this->db->getPrefix()}shortpixel_meta WHERE status < -1 AND retries >= 3 LIMIT 30";
|
509 |
Â
$failRows = $this->db->query($sql);
|
515 |
Â
$moreFilesWithErrors++;
|
516 |
Â
}
|
517 |
Â
}
|
518 |
+
|
519 |
Â
if(!isset($rows[0])) {
|
520 |
Â
$rows[0] = (object)array('totalFiles' => 0, 'totalProcessedFiles' => 0, 'totalProcLossyFiles' => 0, 'totalProcGlossyFiles' => 0, 'totalProcLosslessFiles' => 0);
|
521 |
Â
}
|
522 |
+
|
523 |
+
return array("totalFiles" => $rows[0]->totalFiles, "mainFiles" => $rows[0]->totalFiles,
|
524 |
Â
"totalProcessedFiles" => $rows[0]->totalProcessedFiles, "mainProcessedFiles" => $rows[0]->totalProcessedFiles,
|
525 |
Â
"totalProcLossyFiles" => $rows[0]->totalProcLossyFiles, "mainProcLossyFiles" => $rows[0]->totalProcLossyFiles,
|
526 |
Â
"totalProcGlossyFiles" => $rows[0]->totalProcGlossyFiles, "mainProcGlossyFiles" => $rows[0]->totalProcGlossyFiles,
|
527 |
Â
"totalProcLosslessFiles" => $rows[0]->totalProcLosslessFiles, "mainProcLosslessFiles" => $rows[0]->totalProcLosslessFiles,
|
528 |
+
"totalCustomFiles" => $rows[0]->totalFiles, "mainCustomFiles" => $rows[0]->totalFiles,
|
529 |
Â
"totalProcessedCustomFiles" => $rows[0]->totalProcessedFiles, "mainProcessedCustomFiles" => $rows[0]->totalProcessedFiles,
|
530 |
Â
"totalProcLossyCustomFiles" => $rows[0]->totalProcLossyFiles, "mainProcLossyCustomFiles" => $rows[0]->totalProcLossyFiles,
|
531 |
Â
"totalProcGlossyCustomFiles" => $rows[0]->totalProcGlossyFiles, "mainProcGlossyCustomFiles" => $rows[0]->totalProcGlossyFiles,
|
533 |
Â
"filesWithErrors" => $filesWithErrors,
|
534 |
Â
"moreFilesWithErrors" => $moreFilesWithErrors
|
535 |
Â
);
|
536 |
+
|
537 |
Â
}
|
538 |
Â
}
|
@@ -283,6 +283,9 @@ class ShortPixelMetaFacade {
|
|
283 |
Â
$this->updateMeta();
|
284 |
Â
} else {
|
285 |
Â
if($status) {
|
Â
|
|
Â
|
|
Â
|
|
286 |
Â
$this->rawMeta['ShortPixel']['WaitingProcessing'] = true;
|
287 |
Â
unset($this->rawMeta['ShortPixel']['ErrCode']);
|
288 |
Â
} else {
|
@@ -703,9 +706,7 @@ class ShortPixelMetaFacade {
|
|
703 |
Â
}
|
704 |
Â
}
|
705 |
Â
|
706 |
-
public function optimizationStarted() {
|
707 |
-
|
708 |
-
do_action( 'shortpixel_start_image_optimisation', $this->getId() );
|
709 |
-
}
|
710 |
Â
}
|
711 |
Â
}
|
283 |
Â
$this->updateMeta();
|
284 |
Â
} else {
|
285 |
Â
if($status) {
|
286 |
+
if(!isset($this->rawMeta['ShortPixel']['WaitingProcessing']) || !$this->rawMeta['ShortPixel']['WaitingProcessing']) {
|
287 |
+
self::optimizationStarted($this->getId());
|
288 |
+
}
|
289 |
Â
$this->rawMeta['ShortPixel']['WaitingProcessing'] = true;
|
290 |
Â
unset($this->rawMeta['ShortPixel']['ErrCode']);
|
291 |
Â
} else {
|
706 |
Â
}
|
707 |
Â
}
|
708 |
Â
|
709 |
+
public static function optimizationStarted($id) {
|
710 |
+
do_action( 'shortpixel_start_image_optimisation', $id );
|
Â
|
|
Â
|
|
711 |
Â
}
|
712 |
Â
}
|
@@ -1,14 +1,14 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
class WpShortPixelDb implements ShortPixelDb {
|
4 |
-
|
5 |
Â
protected $prefix;
|
6 |
Â
protected $defaultShowErrors;
|
7 |
-
|
8 |
Â
public function __construct($prefix = null) {
|
9 |
Â
$this->prefix = $prefix;
|
10 |
Â
}
|
11 |
-
|
12 |
Â
public static function createUpdateSchema($tableDefinitions) {
|
13 |
Â
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
14 |
Â
$res = array();
|
@@ -17,7 +17,7 @@ class WpShortPixelDb implements ShortPixelDb {
|
|
17 |
Â
}
|
18 |
Â
return $res;
|
19 |
Â
}
|
20 |
-
|
21 |
Â
public static function checkCustomTables() {
|
22 |
Â
global $wpdb;
|
23 |
Â
if(function_exists("is_multisite") && is_multisite()) {
|
@@ -30,28 +30,28 @@ class WpShortPixelDb implements ShortPixelDb {
|
|
30 |
Â
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb($prefix));
|
31 |
Â
$spMetaDao->createUpdateShortPixelTables();
|
32 |
Â
}
|
33 |
-
|
34 |
Â
} else {
|
35 |
Â
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb());
|
36 |
Â
$spMetaDao->createUpdateShortPixelTables();
|
37 |
-
}
|
38 |
Â
}
|
39 |
-
|
40 |
Â
public function getCharsetCollate() {
|
41 |
Â
global $wpdb;
|
42 |
Â
return $wpdb->get_charset_collate();
|
43 |
Â
}
|
44 |
-
|
45 |
Â
public function getPrefix() {
|
46 |
Â
global $wpdb;
|
47 |
Â
return $this->prefix ? $this->prefix : $wpdb->prefix;
|
48 |
Â
}
|
49 |
-
|
50 |
Â
public function getDbName() {
|
51 |
Â
global $wpdb;
|
52 |
Â
return $wpdb->dbname;
|
53 |
Â
}
|
54 |
-
|
55 |
Â
public function query($sql, $params = false) {
|
56 |
Â
global $wpdb;
|
57 |
Â
if($params) {
|
@@ -65,18 +65,26 @@ class WpShortPixelDb implements ShortPixelDb {
|
|
65 |
Â
$wpdb->insert($table, $params, $format);
|
66 |
Â
return $wpdb->insert_id;
|
67 |
Â
}
|
68 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
69 |
Â
public function prepare($query, $args) {
|
70 |
Â
global $wpdb;
|
71 |
Â
return $wpdb->prepare($query, $args);
|
72 |
Â
}
|
73 |
-
|
74 |
Â
public function hideErrors() {
|
75 |
Â
global $wpdb;
|
76 |
Â
$this->defaultShowErrors = $wpdb->show_errors;
|
77 |
Â
$wpdb->show_errors = false;
|
78 |
Â
}
|
79 |
-
|
80 |
Â
public function restoreErrors() {
|
81 |
Â
global $wpdb;
|
82 |
Â
$wpdb->show_errors = $this->defaultShowErrors;
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
class WpShortPixelDb implements ShortPixelDb {
|
4 |
+
|
5 |
Â
protected $prefix;
|
6 |
Â
protected $defaultShowErrors;
|
7 |
+
|
8 |
Â
public function __construct($prefix = null) {
|
9 |
Â
$this->prefix = $prefix;
|
10 |
Â
}
|
11 |
+
|
12 |
Â
public static function createUpdateSchema($tableDefinitions) {
|
13 |
Â
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
14 |
Â
$res = array();
|
17 |
Â
}
|
18 |
Â
return $res;
|
19 |
Â
}
|
20 |
+
|
21 |
Â
public static function checkCustomTables() {
|
22 |
Â
global $wpdb;
|
23 |
Â
if(function_exists("is_multisite") && is_multisite()) {
|
30 |
Â
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb($prefix));
|
31 |
Â
$spMetaDao->createUpdateShortPixelTables();
|
32 |
Â
}
|
33 |
+
|
34 |
Â
} else {
|
35 |
Â
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb());
|
36 |
Â
$spMetaDao->createUpdateShortPixelTables();
|
37 |
+
}
|
38 |
Â
}
|
39 |
+
|
40 |
Â
public function getCharsetCollate() {
|
41 |
Â
global $wpdb;
|
42 |
Â
return $wpdb->get_charset_collate();
|
43 |
Â
}
|
44 |
+
|
45 |
Â
public function getPrefix() {
|
46 |
Â
global $wpdb;
|
47 |
Â
return $this->prefix ? $this->prefix : $wpdb->prefix;
|
48 |
Â
}
|
49 |
+
|
50 |
Â
public function getDbName() {
|
51 |
Â
global $wpdb;
|
52 |
Â
return $wpdb->dbname;
|
53 |
Â
}
|
54 |
+
|
55 |
Â
public function query($sql, $params = false) {
|
56 |
Â
global $wpdb;
|
57 |
Â
if($params) {
|
65 |
Â
$wpdb->insert($table, $params, $format);
|
66 |
Â
return $wpdb->insert_id;
|
67 |
Â
}
|
68 |
+
|
69 |
+
public function update($table, $params, $where, $format = null, $where_format = null)
|
70 |
+
{
|
71 |
+
global $wpdb;
|
72 |
+
$updated = $wpdb->update($table, $params, $where, $format, $where_format);
|
73 |
+
return $updated;
|
74 |
+
|
75 |
+
}
|
76 |
+
|
77 |
Â
public function prepare($query, $args) {
|
78 |
Â
global $wpdb;
|
79 |
Â
return $wpdb->prepare($query, $args);
|
80 |
Â
}
|
81 |
+
|
82 |
Â
public function hideErrors() {
|
83 |
Â
global $wpdb;
|
84 |
Â
$this->defaultShowErrors = $wpdb->show_errors;
|
85 |
Â
$wpdb->show_errors = false;
|
86 |
Â
}
|
87 |
+
|
88 |
Â
public function restoreErrors() {
|
89 |
Â
global $wpdb;
|
90 |
Â
$wpdb->show_errors = $this->defaultShowErrors;
|
@@ -287,11 +287,8 @@ class WpShortPixelMediaLbraryAdapter {
|
|
287 |
Â
$thumbs[]= $th;
|
288 |
Â
}
|
289 |
Â
}
|
290 |
-
if( defined('
|
291 |
Â
$suffixes = defined('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES') ? explode(',', SHORTPIXEL_CUSTOM_THUMB_SUFFIXES) : array();
|
292 |
-
if( defined('SHORTPIXEL_CUSTOM_THUMB_SUFFIX') ){
|
293 |
-
$suffixes[] = SHORTPIXEL_CUSTOM_THUMB_SUFFIX;
|
294 |
-
}
|
295 |
Â
foreach ($suffixes as $suffix){
|
296 |
Â
$pattern = '/' . preg_quote($base, '/') . '-\d+x\d+'. $suffix . '\.'. $ext .'/';
|
297 |
Â
foreach($thumbsCandidates as $th) {
|
287 |
Â
$thumbs[]= $th;
|
288 |
Â
}
|
289 |
Â
}
|
290 |
+
if( defined('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES') ){
|
291 |
Â
$suffixes = defined('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES') ? explode(',', SHORTPIXEL_CUSTOM_THUMB_SUFFIXES) : array();
|
Â
|
|
Â
|
|
Â
|
|
292 |
Â
foreach ($suffixes as $suffix){
|
293 |
Â
$pattern = '/' . preg_quote($base, '/') . '-\d+x\d+'. $suffix . '\.'. $ext .'/';
|
294 |
Â
foreach($thumbsCandidates as $th) {
|
@@ -26,23 +26,33 @@ class ShortPixelImgToPictureWebp
|
|
26 |
Â
{
|
27 |
Â
// Don't do anything with the RSS feed.
|
28 |
Â
if (is_feed() || is_admin()) {
|
29 |
-
return $content;
|
30 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
31 |
Â
|
32 |
-
return preg_replace_callback('/<img[^>]*>/', array('ShortPixelImgToPictureWebp', 'convertImage'), $content);
|
33 |
Â
}
|
34 |
Â
|
35 |
Â
public static function convertImage($match)
|
36 |
Â
{
|
37 |
Â
// Do nothing with images that have the 'sp-no-webp' class.
|
38 |
Â
if (strpos($match[0], 'sp-no-webp')) {
|
39 |
-
return $match[0];
|
40 |
Â
}
|
41 |
Â
|
42 |
Â
$img = self::get_attributes($match[0]);
|
Â
|
|
Â
|
|
Â
|
|
43 |
Â
|
44 |
Â
$srcInfo = self::lazyGet($img, 'src');
|
45 |
Â
$src = $srcInfo['value'];
|
Â
|
|
46 |
Â
$srcPrefix = $srcInfo['prefix'];
|
47 |
Â
|
48 |
Â
$srcsetInfo = self::lazyGet($img, 'srcset');
|
@@ -62,7 +72,8 @@ class ShortPixelImgToPictureWebp
|
|
62 |
Â
}
|
63 |
Â
$imageBase = dirname(get_attached_file($id)) . '/';
|
64 |
Â
*/
|
65 |
-
|
Â
|
|
66 |
Â
$proto = explode("://", $src);
|
67 |
Â
if (count($proto) > 1) {
|
68 |
Â
//check that baseurl uses the same http/https proto and if not, change
|
@@ -73,12 +84,31 @@ class ShortPixelImgToPictureWebp
|
|
73 |
Â
$updir['baseurl'] = $proto . "://" . $base[1];
|
74 |
Â
}
|
75 |
Â
}
|
76 |
-
}
|
77 |
-
|
78 |
-
|
79 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
80 |
Â
}
|
81 |
Â
$imageBase = dirname($imageBase) . '/';
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
82 |
Â
|
83 |
Â
// We don't wanna have src-ish attributes on the <picture>
|
84 |
Â
unset($img['src']);
|
@@ -88,6 +118,7 @@ class ShortPixelImgToPictureWebp
|
|
88 |
Â
unset($img['sizes']);
|
89 |
Â
unset($img['alt']);
|
90 |
Â
$srcsetWebP = '';
|
Â
|
|
91 |
Â
if ($srcset) {
|
92 |
Â
$defs = explode(",", $srcset);
|
93 |
Â
foreach ($defs as $item) {
|
@@ -112,7 +143,6 @@ class ShortPixelImgToPictureWebp
|
|
112 |
Â
} else {
|
113 |
Â
$srcset = trim($src);
|
114 |
Â
|
115 |
-
// die(var_dump($match));
|
116 |
Â
|
117 |
Â
$fileWebPCompat = $imageBase . wp_basename($srcset, '.' . pathinfo($srcset, PATHINFO_EXTENSION)) . '.webp';
|
118 |
Â
$fileWebP = $imageBase . wp_basename($srcset) . '.webp';
|
@@ -126,7 +156,7 @@ class ShortPixelImgToPictureWebp
|
|
126 |
Â
}
|
127 |
Â
//return($match[0]. "<!-- srcsetTZF:".$srcsetWebP." -->");
|
128 |
Â
if (!strlen($srcsetWebP)) {
|
129 |
-
return $match[0];
|
130 |
Â
}
|
131 |
Â
|
132 |
Â
//add the exclude class so if this content is processed again in other filter, the img is not converted again in picture
|
@@ -140,11 +170,143 @@ class ShortPixelImgToPictureWebp
|
|
140 |
Â
.'</picture>';
|
141 |
Â
}
|
142 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
143 |
Â
public static function get_attributes($image_node)
|
144 |
Â
{
|
145 |
Â
if (function_exists("mb_convert_encoding")) {
|
146 |
Â
$image_node = mb_convert_encoding($image_node, 'HTML-ENTITIES', 'UTF-8');
|
147 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
148 |
Â
$dom = new DOMDocument();
|
149 |
Â
@$dom->loadHTML($image_node);
|
150 |
Â
$image = $dom->getElementsByTagName('img')->item(0);
|
26 |
Â
{
|
27 |
Â
// Don't do anything with the RSS feed.
|
28 |
Â
if (is_feed() || is_admin()) {
|
29 |
+
return $content . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG convert is_feed or is_admin -->' : '');
|
30 |
Â
}
|
31 |
+
$content = preg_replace_callback('/<img[^>]*>/', array('self', 'convertImage'), $content);
|
32 |
+
//$content = preg_replace_callback('/background.*[^:](url\(.*\)[,;])/im', array('self', 'convertInlineStyle'), $content);
|
33 |
+
|
34 |
+
// [BS] No callback because we need preg_match_all
|
35 |
+
//$content = self::testInlineStyle($content);
|
36 |
+
// $content = preg_replace_callback('/background.*[^:]url\([\'|"](.*)[\'|"]\)[,;]/imU',array('self', 'convertInlineStyle'), $content);
|
37 |
+
return $content . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG WebP converted -->' : '');
|
38 |
Â
|
Â
|
|
39 |
Â
}
|
40 |
Â
|
41 |
Â
public static function convertImage($match)
|
42 |
Â
{
|
43 |
Â
// Do nothing with images that have the 'sp-no-webp' class.
|
44 |
Â
if (strpos($match[0], 'sp-no-webp')) {
|
45 |
+
return $match[0] . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG convertImage sp-no-webp -->' : '');
|
46 |
Â
}
|
47 |
Â
|
48 |
Â
$img = self::get_attributes($match[0]);
|
49 |
+
// [BS] Can return false in case of Module fail. Escape in that case with unmodified image
|
50 |
+
if ($img === false)
|
51 |
+
return $match[0];
|
52 |
Â
|
53 |
Â
$srcInfo = self::lazyGet($img, 'src');
|
54 |
Â
$src = $srcInfo['value'];
|
55 |
+
$parsed_url = parse_url($src);
|
56 |
Â
$srcPrefix = $srcInfo['prefix'];
|
57 |
Â
|
58 |
Â
$srcsetInfo = self::lazyGet($img, 'srcset');
|
72 |
Â
}
|
73 |
Â
$imageBase = dirname(get_attached_file($id)) . '/';
|
74 |
Â
*/
|
75 |
+
|
76 |
+
/* [BS] $updir = wp_upload_dir();
|
77 |
Â
$proto = explode("://", $src);
|
78 |
Â
if (count($proto) > 1) {
|
79 |
Â
//check that baseurl uses the same http/https proto and if not, change
|
84 |
Â
$updir['baseurl'] = $proto . "://" . $base[1];
|
85 |
Â
}
|
86 |
Â
}
|
87 |
+
} */
|
88 |
+
|
89 |
+
|
90 |
+
/* [BS] $imageBase = str_replace($updir['baseurl'], SHORTPIXEL_UPLOADS_BASE, $src);
|
91 |
+
if ($imageBase == $src) { //maybe the site uses a CDN or a subdomain?
|
92 |
+
$urlParsed = parse_url($src);
|
93 |
+
$srcHost = array_reverse(explode('.', $urlParsed['host']));
|
94 |
+
$baseParsed = parse_url($updir['baseurl']);
|
95 |
+
$baseurlHost = array_reverse(explode('.', $baseParsed['host']));
|
96 |
+
if ($srcHost[0] == $baseurlHost[0] && $srcHost[1] == $baseurlHost[1]
|
97 |
+
&& (strlen($srcHost[1]) > 3 || isset($srcHost[2]) && isset($srcHost[2]) && $srcHost[2] == $baseurlHost[2])) {
|
98 |
+
$baseurl = str_replace($baseParsed['scheme'] . '://' . $baseParsed['host'], $urlParsed['scheme'] . '://' . $urlParsed['host'], $updir['baseurl']);
|
99 |
+
$imageBase = str_replace($baseurl, SHORTPIXEL_UPLOADS_BASE, $src);
|
100 |
+
}
|
101 |
+
if ($imageBase == $src) { //looks like it's an external URL though...
|
102 |
+
if(isset($_GET['SHORTPIXEL_DEBUG'])) WPShortPixel::log('SPDBG baseurl ' . $updir['baseurl'] . ' doesn\'t match ' . $src, true);
|
103 |
+
return $match[0] . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG baseurl ' . $updir['baseurl'] . ' doesn\'t match ' . $src . ' -->' : '');
|
104 |
+
}
|
105 |
Â
}
|
106 |
Â
$imageBase = dirname($imageBase) . '/';
|
107 |
+
*/
|
108 |
+
$imageBase = static::getImageBase($src);
|
109 |
+
if($imageBase === false) {
|
110 |
+
return $match[0] . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG baseurl doesn\'t match ' . $src . ' -->' : '');
|
111 |
+
}
|
112 |
Â
|
113 |
Â
// We don't wanna have src-ish attributes on the <picture>
|
114 |
Â
unset($img['src']);
|
118 |
Â
unset($img['sizes']);
|
119 |
Â
unset($img['alt']);
|
120 |
Â
$srcsetWebP = '';
|
121 |
+
|
122 |
Â
if ($srcset) {
|
123 |
Â
$defs = explode(",", $srcset);
|
124 |
Â
foreach ($defs as $item) {
|
143 |
Â
} else {
|
144 |
Â
$srcset = trim($src);
|
145 |
Â
|
Â
|
|
146 |
Â
|
147 |
Â
$fileWebPCompat = $imageBase . wp_basename($srcset, '.' . pathinfo($srcset, PATHINFO_EXTENSION)) . '.webp';
|
148 |
Â
$fileWebP = $imageBase . wp_basename($srcset) . '.webp';
|
156 |
Â
}
|
157 |
Â
//return($match[0]. "<!-- srcsetTZF:".$srcsetWebP." -->");
|
158 |
Â
if (!strlen($srcsetWebP)) {
|
159 |
+
return $match[0] . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG no srcsetWebP found (' . $srcsetWebP . ') -->' : '');
|
160 |
Â
}
|
161 |
Â
|
162 |
Â
//add the exclude class so if this content is processed again in other filter, the img is not converted again in picture
|
170 |
Â
.'</picture>';
|
171 |
Â
}
|
172 |
Â
|
173 |
+
public static function testInlineStyle($content)
|
174 |
+
{
|
175 |
+
//preg_match_all('/background.*[^:](url\(.*\))[;]/isU', $content, $matches);
|
176 |
+
preg_match_all('/url\(.*\)/isU', $content, $matches);
|
177 |
+
|
178 |
+
if (count($matches) == 0)
|
179 |
+
return $content;
|
180 |
+
|
181 |
+
$content = self::convertInlineStyle($matches, $content);
|
182 |
+
return $content;
|
183 |
+
}
|
184 |
+
|
185 |
+
/** Function to convert inline CSS backgrounds to webp
|
186 |
+
* @param $match Regex match for inline style
|
187 |
+
* @return String Replaced (or not) content for webp.
|
188 |
+
* @author Bas Schuiling
|
189 |
+
*/
|
190 |
+
public static function convertInlineStyle($matches, $content)
|
191 |
+
{
|
192 |
+
// ** matches[0] = url('xx') matches[1] the img URL.
|
193 |
+
// preg_match_all('/url\(\'(.*)\'\)/imU', $match, $matches);
|
194 |
+
|
195 |
+
// if (count($matches) == 0)
|
196 |
+
// return $match; // something wrong, escape.
|
197 |
+
|
198 |
+
//$content = $match;
|
199 |
+
$allowed_exts = array('jpg', 'jpeg', 'gif', 'png');
|
200 |
+
$converted = array();
|
201 |
+
|
202 |
+
for($i = 0; $i < count($matches[0]); $i++)
|
203 |
+
{
|
204 |
+
$item = $matches[0][$i];
|
205 |
+
|
206 |
+
preg_match('/url\(\'(.*)\'\)/imU', $item, $match);
|
207 |
+
if (! isset($match[1]))
|
208 |
+
continue;
|
209 |
+
|
210 |
+
$url = $match[1];
|
211 |
+
$parsed_url = parse_url($url);
|
212 |
+
$filename = basename($url);
|
213 |
+
|
214 |
+
$fileonly = pathinfo($url, PATHINFO_FILENAME);
|
215 |
+
$ext = pathinfo($url, PATHINFO_EXTENSION);
|
216 |
+
|
217 |
+
if (! in_array($ext, $allowed_exts))
|
218 |
+
continue;
|
219 |
+
|
220 |
+
$imageBaseURL = str_replace($filename, '', $url);
|
221 |
+
|
222 |
+
$imageBase = static::getImageBase($url);
|
223 |
+
|
224 |
+
if (! $imageBase) // returns false if URL is external, do nothing with that.
|
225 |
+
continue;
|
226 |
+
|
227 |
+
$checkedFile = false;
|
228 |
+
if (file_exists($imageBase . $fileonly . '.' . $ext . '.webp'))
|
229 |
+
{
|
230 |
+
$checkedFile = $imageBaseURL . $fileonly . '.' . $ext . '.webp';
|
231 |
+
}
|
232 |
+
elseif (file_exists($imageBase . $fileonly . '.webp'))
|
233 |
+
{
|
234 |
+
$checkedFile = $imageBaseURL . $fileonly . '.webp';
|
235 |
+
}
|
236 |
+
|
237 |
+
if ($checkedFile)
|
238 |
+
{
|
239 |
+
// if webp, then add another URL() def after the targeted one. (str_replace old full URL def, with new one on main match?
|
240 |
+
$target_urldef = $matches[0][$i];
|
241 |
+
if (! isset($converted[$target_urldef])) // if the same image is on multiple elements, this replace might go double. prevent.
|
242 |
+
{
|
243 |
+
$converted[] = $target_urldef;
|
244 |
+
$new_urldef = "url('" . $checkedFile . "'), " . $target_urldef;
|
245 |
+
$content = str_replace($target_urldef, $new_urldef, $content);
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
}
|
250 |
+
|
251 |
+
return $content;
|
252 |
+
}
|
253 |
+
|
254 |
+
/* ** Utility function to get ImageBase.
|
255 |
+
** @param String $src Image Source
|
256 |
+
** @returns String The Image Base
|
257 |
+
**/
|
258 |
+
public static function getImageBase($src)
|
259 |
+
{
|
260 |
+
$updir = wp_upload_dir();
|
261 |
+
$proto = explode("://", $src);
|
262 |
+
if (count($proto) > 1) {
|
263 |
+
//check that baseurl uses the same http/https proto and if not, change
|
264 |
+
$proto = $proto[0];
|
265 |
+
if (strpos($updir['baseurl'], $proto."://") === false) {
|
266 |
+
$base = explode("://", $updir['baseurl']);
|
267 |
+
if (count($base) > 1) {
|
268 |
+
$updir['baseurl'] = $proto . "://" . $base[1];
|
269 |
+
}
|
270 |
+
}
|
271 |
+
}
|
272 |
+
|
273 |
+
$imageBase = str_replace($updir['baseurl'], SHORTPIXEL_UPLOADS_BASE, $src);
|
274 |
+
if ($imageBase == $src) { //for themes images or other non-uploads paths
|
275 |
+
$imageBase = str_replace(content_url(), WP_CONTENT_DIR, $src);
|
276 |
+
}
|
277 |
+
|
278 |
+
if ($imageBase == $src) { //maybe the site uses a CDN or a subdomain? - Or relative link
|
279 |
+
$urlParsed = parse_url($src);
|
280 |
+
$baseParsed = parse_url($updir['baseurl']);
|
281 |
+
|
282 |
+
$srcHost = array_reverse(explode('.', $urlParsed['host']));
|
283 |
+
$baseurlHost = array_reverse(explode('.', $baseParsed['host']));
|
284 |
+
|
285 |
+
if ($srcHost[0] == $baseurlHost[0] && $srcHost[1] == $baseurlHost[1]
|
286 |
+
&& (strlen($srcHost[1]) > 3 || isset($srcHost[2]) && isset($srcHost[2]) && $srcHost[2] == $baseurlHost[2])) {
|
287 |
+
|
288 |
+
$baseurl = str_replace($baseParsed['scheme'] . '://' . $baseParsed['host'], $urlParsed['scheme'] . '://' . $urlParsed['host'], $updir['baseurl']);
|
289 |
+
$imageBase = str_replace($baseurl, SHORTPIXEL_UPLOADS_BASE, $src);
|
290 |
+
}
|
291 |
+
if ($imageBase == $src) { //looks like it's an external URL though...
|
292 |
+
return false;
|
293 |
+
}
|
294 |
+
}
|
295 |
+
|
296 |
+
|
297 |
+
$imageBase = trailingslashit(dirname($imageBase));
|
298 |
+
return $imageBase;
|
299 |
+
}
|
300 |
+
|
301 |
Â
public static function get_attributes($image_node)
|
302 |
Â
{
|
303 |
Â
if (function_exists("mb_convert_encoding")) {
|
304 |
Â
$image_node = mb_convert_encoding($image_node, 'HTML-ENTITIES', 'UTF-8');
|
305 |
Â
}
|
306 |
+
// [BS] Escape when DOM Module not installed
|
307 |
+
if (! class_exists('DOMDocument'))
|
308 |
+
return false;
|
309 |
+
|
310 |
Â
$dom = new DOMDocument();
|
311 |
Â
@$dom->loadHTML($image_node);
|
312 |
Â
$image = $dom->getElementsByTagName('img')->item(0);
|
@@ -11,6 +11,7 @@ class ShortPixelEntity{
|
|
11 |
Â
}
|
12 |
Â
foreach($dataArr as $key => $val) {
|
13 |
Â
$setter = 'set' . ShortPixelTools::snakeToCamel($key);
|
Â
|
|
14 |
Â
if(method_exists($this, $setter)) {
|
15 |
Â
$this->$setter($val);
|
16 |
Â
}
|
11 |
Â
}
|
12 |
Â
foreach($dataArr as $key => $val) {
|
13 |
Â
$setter = 'set' . ShortPixelTools::snakeToCamel($key);
|
14 |
+
|
15 |
Â
if(method_exists($this, $setter)) {
|
16 |
Â
$this->$setter($val);
|
17 |
Â
}
|
@@ -2,7 +2,7 @@
|
|
2 |
Â
|
3 |
Â
class ShortPixelMeta extends ShortPixelEntity{
|
4 |
Â
const META_VERSION = 1;
|
5 |
-
|
6 |
Â
protected $id;
|
7 |
Â
protected $folderId;
|
8 |
Â
protected $extMetaId;
|
@@ -32,15 +32,23 @@ class ShortPixelMeta extends ShortPixelEntity{
|
|
32 |
Â
protected $tsAdded;
|
33 |
Â
protected $tsOptimized;
|
34 |
Â
protected $thumbs;
|
35 |
-
|
36 |
Â
const TABLE_SUFFIX = 'meta';
|
37 |
Â
const WEBP_THUMB_PREFIX = 'sp-webp-';
|
38 |
Â
const FOUND_THUMB_PREFIX = 'sp-found-';
|
39 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
40 |
Â
public function __construct($data = array()) {
|
41 |
Â
parent::__construct($data);
|
42 |
Â
}
|
43 |
-
|
44 |
Â
/**
|
45 |
Â
* @return meta string to be embedded into the image
|
46 |
Â
*/
|
@@ -48,14 +56,14 @@ class ShortPixelMeta extends ShortPixelEntity{
|
|
48 |
Â
//To be implemented
|
49 |
Â
return base64_encode("Not now John.");
|
50 |
Â
}
|
51 |
-
|
52 |
Â
function getImprovementPercent() {
|
53 |
Â
if(is_numeric($this->message)) {
|
54 |
Â
return round($this->message,2);
|
55 |
Â
}
|
56 |
Â
return 0;
|
57 |
Â
}
|
58 |
-
|
59 |
Â
function getId() {
|
60 |
Â
return $this->id;
|
61 |
Â
}
|
@@ -114,7 +122,7 @@ class ShortPixelMeta extends ShortPixelEntity{
|
|
114 |
Â
function setPath($path) {
|
115 |
Â
$this->path = $path;
|
116 |
Â
}
|
117 |
-
|
118 |
Â
function getName() {
|
119 |
Â
return $this->name;
|
120 |
Â
}
|
@@ -290,11 +298,11 @@ class ShortPixelMeta extends ShortPixelEntity{
|
|
290 |
Â
function setMessage($message) {
|
291 |
Â
$this->message = $message;
|
292 |
Â
}
|
293 |
-
|
294 |
Â
function getType() {
|
295 |
Â
return (isset($this->folderId) ? ShortPixelMetaFacade::CUSTOM_TYPE : ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
296 |
Â
}
|
297 |
-
|
298 |
Â
function getThumbs() {
|
299 |
Â
return $this->thumbs;
|
300 |
Â
}
|
@@ -302,7 +310,7 @@ class ShortPixelMeta extends ShortPixelEntity{
|
|
302 |
Â
function setThumbs($thumbs) {
|
303 |
Â
$this->thumbs = $thumbs;
|
304 |
Â
}
|
305 |
-
|
306 |
Â
function addThumbs($thumbs) {
|
307 |
Â
$this->thumbs = array_merge($this->thumbs, $thumbs);
|
308 |
Â
}
|
2 |
Â
|
3 |
Â
class ShortPixelMeta extends ShortPixelEntity{
|
4 |
Â
const META_VERSION = 1;
|
5 |
+
|
6 |
Â
protected $id;
|
7 |
Â
protected $folderId;
|
8 |
Â
protected $extMetaId;
|
32 |
Â
protected $tsAdded;
|
33 |
Â
protected $tsOptimized;
|
34 |
Â
protected $thumbs;
|
35 |
+
|
36 |
Â
const TABLE_SUFFIX = 'meta';
|
37 |
Â
const WEBP_THUMB_PREFIX = 'sp-webp-';
|
38 |
Â
const FOUND_THUMB_PREFIX = 'sp-found-';
|
39 |
+
|
40 |
+
// [BS] Attempt to shed some light on Meta Status on File.
|
41 |
+
// Anything lower than 0 is a processing error.
|
42 |
+
const FILE_STATUS_UNPROCESSED = 0;
|
43 |
+
const FILE_STATUS_PENDING = 1;
|
44 |
+
const FILE_STATUS_SUCCESS = 2;
|
45 |
+
const FILE_STATUS_RESTORED = 3;
|
46 |
+
const FILE_STATUS_TORESTORE = 4; // Used for Bulk Restore
|
47 |
+
|
48 |
Â
public function __construct($data = array()) {
|
49 |
Â
parent::__construct($data);
|
50 |
Â
}
|
51 |
+
|
52 |
Â
/**
|
53 |
Â
* @return meta string to be embedded into the image
|
54 |
Â
*/
|
56 |
Â
//To be implemented
|
57 |
Â
return base64_encode("Not now John.");
|
58 |
Â
}
|
59 |
+
|
60 |
Â
function getImprovementPercent() {
|
61 |
Â
if(is_numeric($this->message)) {
|
62 |
Â
return round($this->message,2);
|
63 |
Â
}
|
64 |
Â
return 0;
|
65 |
Â
}
|
66 |
+
|
67 |
Â
function getId() {
|
68 |
Â
return $this->id;
|
69 |
Â
}
|
122 |
Â
function setPath($path) {
|
123 |
Â
$this->path = $path;
|
124 |
Â
}
|
125 |
+
|
126 |
Â
function getName() {
|
127 |
Â
return $this->name;
|
128 |
Â
}
|
298 |
Â
function setMessage($message) {
|
299 |
Â
$this->message = $message;
|
300 |
Â
}
|
301 |
+
|
302 |
Â
function getType() {
|
303 |
Â
return (isset($this->folderId) ? ShortPixelMetaFacade::CUSTOM_TYPE : ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE);
|
304 |
Â
}
|
305 |
+
|
306 |
Â
function getThumbs() {
|
307 |
Â
return $this->thumbs;
|
308 |
Â
}
|
310 |
Â
function setThumbs($thumbs) {
|
311 |
Â
$this->thumbs = $thumbs;
|
312 |
Â
}
|
313 |
+
|
314 |
Â
function addThumbs($thumbs) {
|
315 |
Â
$this->thumbs = array_merge($this->thumbs, $thumbs);
|
316 |
Â
}
|
@@ -11,11 +11,21 @@ class ShortPixelTools {
|
|
11 |
Â
}
|
12 |
Â
return $data;
|
13 |
Â
}*/
|
14 |
-
|
15 |
Â
public static function snakeToCamel($snake_case) {
|
16 |
Â
return str_replace(' ', '', ucwords(str_replace('_', ' ', $snake_case)));
|
17 |
Â
}
|
18 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
19 |
Â
public static function requestIsFrontendAjax()
|
20 |
Â
{
|
21 |
Â
$script_filename = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '';
|
@@ -39,13 +49,38 @@ class ShortPixelTools {
|
|
39 |
Â
//If no checks triggered, we end up here - not an AJAX request.
|
40 |
Â
return false;
|
41 |
Â
}
|
42 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
43 |
Â
public static function commonPrefix($str1, $str2) {
|
44 |
Â
$limit = min(strlen($str1), strlen($str2));
|
45 |
Â
for ($i = 0; $i < $limit && $str1[$i] === $str2[$i]; $i++);
|
46 |
Â
return substr($str1, 0, $i);
|
47 |
Â
}
|
48 |
-
|
49 |
Â
/**
|
50 |
Â
* This is a simplified wp_send_json made compatible with WP 3.2.x to 3.4.x
|
51 |
Â
* @param type $response
|
@@ -55,6 +90,8 @@ class ShortPixelTools {
|
|
55 |
Â
die(json_encode($response));
|
56 |
Â
}
|
57 |
Â
|
Â
|
|
Â
|
|
58 |
Â
/**
|
59 |
Â
* finds if an array contains an item, comparing the property given as key
|
60 |
Â
* @param $item
|
@@ -69,9 +106,9 @@ class ShortPixelTools {
|
|
69 |
Â
}
|
70 |
Â
}
|
71 |
Â
return false;
|
72 |
-
}
|
73 |
Â
}
|
74 |
Â
|
75 |
Â
function ShortPixelVDD($v){
|
76 |
Â
return highlight_string("<?php\n\$data =\n" . var_export($v, true) . ";\n?>");
|
77 |
-
}
|
11 |
Â
}
|
12 |
Â
return $data;
|
13 |
Â
}*/
|
14 |
+
|
15 |
Â
public static function snakeToCamel($snake_case) {
|
16 |
Â
return str_replace(' ', '', ucwords(str_replace('_', ' ', $snake_case)));
|
17 |
Â
}
|
18 |
Â
|
19 |
+
public static function getPluginPath()
|
20 |
+
{
|
21 |
+
return plugin_dir_path(SHORTPIXEL_PLUGIN_FILE);
|
22 |
+
}
|
23 |
+
|
24 |
+
public static function namespaceit($name)
|
25 |
+
{
|
26 |
+
return '\ShortPixel\\' . $name;
|
27 |
+
}
|
28 |
+
|
29 |
Â
public static function requestIsFrontendAjax()
|
30 |
Â
{
|
31 |
Â
$script_filename = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '';
|
49 |
Â
//If no checks triggered, we end up here - not an AJAX request.
|
50 |
Â
return false;
|
51 |
Â
}
|
52 |
+
|
53 |
+
/** Function to convert dateTime object to a date output
|
54 |
+
*
|
55 |
+
* Function checks if the date is recent and then uploads are friendlier message. Taken from media library list table date function
|
56 |
+
* @param DateTime $date DateTime object
|
57 |
+
**/
|
58 |
+
public static function format_nice_date( $date ) {
|
59 |
+
|
60 |
+
if ( '0000-00-00 00:00:00' === $date->format('Y-m-d ') ) {
|
61 |
+
$h_time = '';
|
62 |
+
} else {
|
63 |
+
$time = $date->format('U'); //get_post_time( 'G', true, $post, false );
|
64 |
+
if ( ( abs( $t_diff = time() - $time ) ) < DAY_IN_SECONDS ) {
|
65 |
+
if ( $t_diff < 0 ) {
|
66 |
+
$h_time = sprintf( __( '%s from now' ), human_time_diff( $time ) );
|
67 |
+
} else {
|
68 |
+
$h_time = sprintf( __( '%s ago' ), human_time_diff( $time ) );
|
69 |
+
}
|
70 |
+
} else {
|
71 |
+
$h_time = $date->format( 'Y/m/d' );
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
return $h_time;
|
76 |
+
}
|
77 |
+
|
78 |
Â
public static function commonPrefix($str1, $str2) {
|
79 |
Â
$limit = min(strlen($str1), strlen($str2));
|
80 |
Â
for ($i = 0; $i < $limit && $str1[$i] === $str2[$i]; $i++);
|
81 |
Â
return substr($str1, 0, $i);
|
82 |
Â
}
|
83 |
+
|
84 |
Â
/**
|
85 |
Â
* This is a simplified wp_send_json made compatible with WP 3.2.x to 3.4.x
|
86 |
Â
* @param type $response
|
90 |
Â
die(json_encode($response));
|
91 |
Â
}
|
92 |
Â
|
93 |
+
|
94 |
+
|
95 |
Â
/**
|
96 |
Â
* finds if an array contains an item, comparing the property given as key
|
97 |
Â
* @param $item
|
106 |
Â
}
|
107 |
Â
}
|
108 |
Â
return false;
|
109 |
+
}
|
110 |
Â
}
|
111 |
Â
|
112 |
Â
function ShortPixelVDD($v){
|
113 |
Â
return highlight_string("<?php\n\$data =\n" . var_export($v, true) . ";\n?>");
|
114 |
+
}
|
@@ -2,14 +2,14 @@
|
|
2 |
Â
|
3 |
Â
if( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
Â
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
|
5 |
-
}
|
6 |
Â
|
7 |
Â
class ShortPixelListTable extends WP_List_Table {
|
8 |
Â
|
9 |
Â
protected $ctrl;
|
10 |
Â
protected $spMetaDao;
|
11 |
Â
protected $hasNextGen;
|
12 |
-
|
13 |
Â
public function __construct($ctrl, $spMetaDao, $hasNextGen) {
|
14 |
Â
parent::__construct( array(
|
15 |
Â
'singular' => __('Image','shortpixel-image-optimiser'), //singular name of the listed records
|
@@ -29,6 +29,7 @@ class ShortPixelListTable extends WP_List_Table {
|
|
29 |
Â
$columns['name'] = __('Filename','shortpixel-image-optimiser');
|
30 |
Â
$columns['folder'] = __('Folder','shortpixel-image-optimiser');
|
31 |
Â
$columns['media_type'] = __('Type','shortpixel-image-optimiser');
|
Â
|
|
32 |
Â
$columns['status'] = __('Status','shortpixel-image-optimiser');
|
33 |
Â
$columns['options'] = __('Options','shortpixel-image-optimiser');
|
34 |
Â
//$columns = apply_filters('shortpixel_list_columns', $columns);
|
@@ -39,45 +40,86 @@ class ShortPixelListTable extends WP_List_Table {
|
|
39 |
Â
function column_cb( $item ) {
|
40 |
Â
return sprintf('<input type="checkbox" name="bulk-optimize[]" value="%s" />', $item->id);
|
41 |
Â
}
|
42 |
-
|
43 |
Â
function column_default( $item, $column_name ) {
|
44 |
-
switch( $column_name ) {
|
45 |
Â
case 'name':
|
46 |
Â
$title = '<a href="' . ShortPixelMetaFacade::pathToWebPath($item->folder) . '" title="'.$item->folder.'" target="_blank"><strong>' . $item->name . '</strong></a>';
|
47 |
Â
|
48 |
Â
$url = ShortPixelMetaFacade::pathToWebPath($item->folder);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
49 |
Â
$actions = array(
|
50 |
-
'optimize' => sprintf(
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
'
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
'
|
63 |
-
|
64 |
-
|
65 |
-
'
|
66 |
-
|
67 |
-
__('Re-optimize glossy','shortpixel-image-optimiser')),
|
68 |
-
'quota' => sprintf( '<a href="?page=%s&action=%s&image=%s&_wpnonce=%s&noheader=true">%s</a>',
|
69 |
-
esc_attr( $_REQUEST['page'] ), 'quota', absint( $item->id ), wp_create_nonce( 'sp_check_quota' ),
|
70 |
-
__('Check quota','shortpixel-image-optimiser')),
|
71 |
Â
'view' => sprintf( '<a href="%s" target="_blank">%s</a>', $url, __('View','shortpixel-image-optimiser'))
|
72 |
Â
);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
73 |
Â
$settings = $this->ctrl->getSettings();
|
74 |
Â
$actionsEnabled = array();
|
75 |
Â
if($settings->quotaExceeded) {
|
76 |
Â
$actionsEnabled['quota'] = true;
|
77 |
-
} elseif($item->status ==
|
Â
|
|
Â
|
|
78 |
Â
$actionsEnabled['optimize'] = true;
|
79 |
-
} elseif($item->status ==
|
80 |
Â
$actionsEnabled['restore'] = true;
|
Â
|
|
81 |
Â
switch($item->compression_type) {
|
82 |
Â
case 2:
|
83 |
Â
$actionsEnabled['redolossy'] = $actionsEnabled['redolossless'] = true;
|
@@ -89,7 +131,7 @@ class ShortPixelListTable extends WP_List_Table {
|
|
89 |
Â
$actionsEnabled['redolossy'] = $actionsEnabled['redoglossy'] = true;
|
90 |
Â
}
|
91 |
Â
//$actionsEnabled['redo'.($item->compression_type == 1 ? "lossless" : "lossy")] = true;
|
92 |
-
} elseif($item->status ==
|
93 |
Â
$actionsEnabled['retry'] = true;
|
94 |
Â
}
|
95 |
Â
$actionsEnabled['view'] = true;
|
@@ -99,14 +141,19 @@ class ShortPixelListTable extends WP_List_Table {
|
|
99 |
Â
return ShortPixelMetaFacade::pathToRootRelative($item->folder);
|
100 |
Â
case 'status':
|
101 |
Â
switch($item->status) {
|
102 |
-
case
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
108 |
Â
break;
|
109 |
-
case 1: $msg = "<img src=\"" . plugins_url( 'shortpixel-image-optimiser/res/img/loading.gif') . "\" class='sp-loading-small'> "
|
110 |
Â
. __('Pending','shortpixel-image-optimiser');
|
111 |
Â
break;
|
112 |
Â
case 0: $msg = __('Waiting','shortpixel-image-optimiser');
|
@@ -121,20 +168,38 @@ class ShortPixelListTable extends WP_List_Table {
|
|
121 |
Â
return "<div id='sp-cust-msg-C-" . $item->id . "'>" . $msg . "</div>";
|
122 |
Â
break;
|
123 |
Â
case 'options':
|
124 |
-
|
125 |
-
|
126 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
127 |
Â
case 'media_type':
|
128 |
Â
return $item->$column_name;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
129 |
Â
default:
|
130 |
Â
return print_r( $item, true ) ; //Show the whole array for troubleshooting purposes
|
131 |
Â
}
|
132 |
Â
}
|
133 |
-
|
134 |
Â
public function no_items() {
|
135 |
Â
echo(__('No images avaliable. Go to <a href="options-general.php?page=wp-shortpixel#adv-settings">Advanced Settings</a> to configure additional folders to be optimized.','shortpixel-image-optimiser'));
|
136 |
Â
}
|
137 |
-
|
138 |
Â
/**
|
139 |
Â
* Columns to make sortable.
|
140 |
Â
*
|
@@ -144,19 +209,20 @@ class ShortPixelListTable extends WP_List_Table {
|
|
144 |
Â
$sortable_columns = array(
|
145 |
Â
'name' => array( 'name', true ),
|
146 |
Â
'folder' => array( 'folder', true ),
|
147 |
-
'status' => array( 'status', false )
|
Â
|
|
148 |
Â
);
|
149 |
Â
|
150 |
Â
return $sortable_columns;
|
151 |
Â
}
|
152 |
-
|
153 |
Â
/**
|
154 |
Â
* Handles data query and filter, sorting, and pagination.
|
155 |
Â
*/
|
156 |
Â
public function prepare_items() {
|
157 |
Â
|
158 |
Â
$this->_column_headers = $this->get_column_info();
|
159 |
-
|
160 |
Â
$this->_column_headers[0] = $this->get_columns();
|
161 |
Â
|
162 |
Â
/** Process actions */
|
@@ -170,15 +236,17 @@ class ShortPixelListTable extends WP_List_Table {
|
|
170 |
Â
'total_items' => $total_items, //WE have to calculate the total number of items
|
171 |
Â
'per_page' => $perPage //WE have to determine how many items to show on a page
|
172 |
Â
));
|
173 |
-
|
174 |
-
|
Â
|
|
175 |
Â
// If no order, default to asc
|
176 |
-
$order = ( ! empty($_GET['order'] ) ) ? $_GET['order'] : 'desc';
|
177 |
-
|
Â
|
|
178 |
Â
$this->items = $this->spMetaDao->getPaginatedMetas($this->hasNextGen, $this->getFilter(), $perPage, $currentPage, $orderby, $order);
|
179 |
Â
return $this->items;
|
180 |
-
}
|
181 |
-
|
182 |
Â
protected function getFilter() {
|
183 |
Â
$filter = array();
|
184 |
Â
if(isset($_GET["s"]) && strlen($_GET["s"])) {
|
@@ -186,34 +254,36 @@ class ShortPixelListTable extends WP_List_Table {
|
|
186 |
Â
}
|
187 |
Â
return $filter;
|
188 |
Â
}
|
189 |
-
|
190 |
Â
public function record_count() {
|
191 |
Â
return $this->spMetaDao->getCustomMetaCount($this->getFilter());
|
192 |
Â
}
|
193 |
-
|
194 |
Â
public function action_optimize_image( $id ) {
|
195 |
Â
$this->ctrl->optimizeCustomImage($id);
|
196 |
Â
}
|
197 |
-
|
198 |
Â
public function action_restore_image( $id ) {
|
199 |
Â
$this->ctrl->doCustomRestore($id);
|
200 |
Â
}
|
201 |
-
|
202 |
Â
public function action_redo_image( $id, $type = false ) {
|
203 |
Â
$this->ctrl->redo('C-' . $id, $type);
|
204 |
Â
}
|
205 |
-
|
206 |
Â
public function process_actions() {
|
207 |
Â
|
208 |
Â
//Detect when a bulk action is being triggered...
|
209 |
Â
$nonce = isset($_REQUEST['_wpnonce']) ? esc_attr($_REQUEST['_wpnonce']) : false;
|
Â
|
|
Â
|
|
210 |
Â
switch($this->current_action()) {
|
211 |
Â
case 'optimize':
|
212 |
Â
if (!wp_verify_nonce($nonce, 'sp_optimize_image')) {
|
213 |
Â
die('Error.');
|
214 |
Â
} else {
|
215 |
Â
$this->action_optimize_image(absint($_GET['image']));
|
216 |
-
wp_redirect(
|
217 |
Â
exit;
|
218 |
Â
}
|
219 |
Â
break;
|
@@ -222,7 +292,7 @@ class ShortPixelListTable extends WP_List_Table {
|
|
222 |
Â
die('Error.');
|
223 |
Â
} else {
|
224 |
Â
$this->action_restore_image(absint($_GET['image']));
|
225 |
-
wp_redirect(
|
226 |
Â
exit;
|
227 |
Â
}
|
228 |
Â
break;
|
@@ -230,8 +300,8 @@ class ShortPixelListTable extends WP_List_Table {
|
|
230 |
Â
if (!wp_verify_nonce($nonce, 'sp_redo_image')) {
|
231 |
Â
die('Error.');
|
232 |
Â
} else {
|
233 |
-
$this->action_redo_image(absint($_GET['image']), $_GET['type']);
|
234 |
-
wp_redirect(
|
235 |
Â
exit;
|
236 |
Â
}
|
237 |
Â
break;
|
2 |
Â
|
3 |
Â
if( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
Â
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
|
5 |
+
}
|
6 |
Â
|
7 |
Â
class ShortPixelListTable extends WP_List_Table {
|
8 |
Â
|
9 |
Â
protected $ctrl;
|
10 |
Â
protected $spMetaDao;
|
11 |
Â
protected $hasNextGen;
|
12 |
+
|
13 |
Â
public function __construct($ctrl, $spMetaDao, $hasNextGen) {
|
14 |
Â
parent::__construct( array(
|
15 |
Â
'singular' => __('Image','shortpixel-image-optimiser'), //singular name of the listed records
|
29 |
Â
$columns['name'] = __('Filename','shortpixel-image-optimiser');
|
30 |
Â
$columns['folder'] = __('Folder','shortpixel-image-optimiser');
|
31 |
Â
$columns['media_type'] = __('Type','shortpixel-image-optimiser');
|
32 |
+
$columns['date'] = __('Date', 'shortpixel-image-optimiser');
|
33 |
Â
$columns['status'] = __('Status','shortpixel-image-optimiser');
|
34 |
Â
$columns['options'] = __('Options','shortpixel-image-optimiser');
|
35 |
Â
//$columns = apply_filters('shortpixel_list_columns', $columns);
|
40 |
Â
function column_cb( $item ) {
|
41 |
Â
return sprintf('<input type="checkbox" name="bulk-optimize[]" value="%s" />', $item->id);
|
42 |
Â
}
|
43 |
+
|
44 |
Â
function column_default( $item, $column_name ) {
|
45 |
+
switch( $column_name ) {
|
46 |
Â
case 'name':
|
47 |
Â
$title = '<a href="' . ShortPixelMetaFacade::pathToWebPath($item->folder) . '" title="'.$item->folder.'" target="_blank"><strong>' . $item->name . '</strong></a>';
|
48 |
Â
|
49 |
Â
$url = ShortPixelMetaFacade::pathToWebPath($item->folder);
|
50 |
+
|
51 |
+
$admin_url = admin_url('upload.php');
|
52 |
+
$admin_url = add_query_arg(array('page' => sanitize_text_field($_REQUEST['page']), 'image' => absint($item->id), 'noheader' => 'true'), $admin_url);
|
53 |
+
|
54 |
+
// add the order options if active
|
55 |
+
if (isset($_GET['orderby']))
|
56 |
+
{
|
57 |
+
$order = isset($_GET['order']) ? sanitize_text_field($_GET['order']) : 'desc';
|
58 |
+
$admin_url = add_query_arg(array('orderby' => sanitize_text_field($_GET['orderby']), 'order' => $order), $admin_url);
|
59 |
+
}
|
60 |
+
if (isset($_GET['paged']))
|
61 |
+
{
|
62 |
+
$admin_url = add_query_arg('paged', intval($_GET['paged']), $admin_url);
|
63 |
+
}
|
64 |
+
|
65 |
Â
$actions = array(
|
66 |
+
'optimize' => sprintf('<a href="%s">%s</a>', add_query_arg(array('action' => 'optimize', '_wpnonce' => wp_create_nonce( 'sp_optimize_image' ), ), $admin_url), __('Optimize','shortpixel-image-optimiser')),
|
67 |
+
|
68 |
+
'retry' => sprintf('<a href="%s">%s</a>', add_query_arg(array('action' => 'optimize', '_wpnonce' => wp_create_nonce( 'sp_optimize_image' ), ), $admin_url), __('Retry','shortpixel-image-optimiser')),
|
69 |
+
|
70 |
+
'redolossless' => sprintf('<a href="%s">%s</a>', add_query_arg(array('action' => 'redo', '_wpnonce' => wp_create_nonce( 'sp_redo_image'), 'type' => 'lossless'),$admin_url), __('Re-optimize lossless','shortpixel-image-optimiser')),
|
71 |
+
|
72 |
+
'redolossy' => sprintf('<a href="%s">%s</a>', add_query_arg(array('action' => 'redo', '_wpnonce' => wp_create_nonce( 'sp_redo_image'), 'type' => 'lossy'), $admin_url), __('Re-optimize lossy','shortpixel-image-optimiser')),
|
73 |
+
|
74 |
+
'redoglossy' => sprintf('<a href="%s">%s</a>', add_query_arg(array('action' => 'redo', '_wpnonce' => wp_create_nonce( 'sp_redo_image'), 'type' => 'glossy'), $admin_url), __('Re-optimize glossy','shortpixel-image-optimiser')),
|
75 |
+
|
76 |
+
'quota' => sprintf('<a href="%s">%s</a>', add_query_arg(array('action' => 'quota', '_wpnonce' => wp_create_nonce( 'sp_check_quota')), $admin_url), __('Check quota','shortpixel-image-optimiser')),
|
77 |
+
|
78 |
+
'restore' => sprintf('<a href="%s">%s</a>', add_query_arg(array('action' => 'restore', '_wpnonce' => wp_create_nonce( 'sp_restore_image')), $admin_url), __('Restore','shortpixel-image-optimiser')),
|
79 |
+
|
80 |
+
|
81 |
+
'compare' => sprintf( '<a href="javascript:ShortPixel.loadComparer(\'C-' . absint($item->id) . '\');">%s</a>"',
|
82 |
+
__('Compare', 'shortpixel-image-optimiser')),
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
83 |
Â
'view' => sprintf( '<a href="%s" target="_blank">%s</a>', $url, __('View','shortpixel-image-optimiser'))
|
84 |
Â
);
|
85 |
+
|
86 |
+
|
87 |
+
/*'optimize' => sprintf( '<a href="?page=%s&action=%s&image=%s&_wpnonce=%s&noheader=true">%s</a>',
|
88 |
+
esc_attr( $_REQUEST['page'] ), 'optimize', absint( $item->id ), wp_create_nonce( 'sp_optimize_image' ),
|
89 |
+
__('Optimize','shortpixel-image-optimiser')), */
|
90 |
+
/*'retry' => sprintf( '<a href="?page=%s&action=%s&image=%s&_wpnonce=%s&noheader=true">%s</a>',
|
91 |
+
esc_attr( $_REQUEST['page'] ), 'optimize', absint( $item->id ), wp_create_nonce( 'sp_optimize_image' ),
|
92 |
+
__('Retry','shortpixel-image-optimiser')), */
|
93 |
+
|
94 |
+
/* 'redolossless' => sprintf( '<a href="?page=%s&action=%s&type=%s&image=%s&_wpnonce=%s&noheader=true">%s</a>',
|
95 |
+
esc_attr( $_REQUEST['page'] ), 'redo', 'lossless', absint( $item->id ), wp_create_nonce( 'sp_redo_image' ),
|
96 |
+
__('Re-optimize lossless','shortpixel-image-optimiser')), */
|
97 |
+
/* 'redolossy' => sprintf( '<a href="?page=%s&action=%s&type=%s&image=%s&_wpnonce=%s&noheader=true">%s</a>',
|
98 |
+
esc_attr( $_REQUEST['page'] ), 'redo', 'lossy', absint( $item->id ), wp_create_nonce( 'sp_redo_image' ),
|
99 |
+
__('Re-optimize lossy','shortpixel-image-optimiser')), */
|
100 |
+
/*'redoglossy' => sprintf( '<a href="?page=%s&action=%s&type=%s&image=%s&_wpnonce=%s&noheader=true">%s</a>',
|
101 |
+
esc_attr( $_REQUEST['page'] ), 'redo', 'glossy', absint( $item->id ), wp_create_nonce( 'sp_redo_image' ),
|
102 |
+
__('Re-optimize glossy','shortpixel-image-optimiser')), */
|
103 |
+
/*'quota' => sprintf( '<a href="?page=%s&action=%s&image=%s&_wpnonce=%s&noheader=true">%s</a>',
|
104 |
+
esc_attr( $_REQUEST['page'] ), 'quota', absint( $item->id ), wp_create_nonce( 'sp_check_quota' ),
|
105 |
+
__('Check quota','shortpixel-image-optimiser')), */
|
106 |
+
/*'restore' => sprintf( '<a href="?page=%s&action=%s&image=%s&_wpnonce=%s&noheader=true">%s</a>',
|
107 |
+
esc_attr( $_REQUEST['page'] ), 'restore', absint( $item->id ), wp_create_nonce( 'sp_restore_image' ),
|
108 |
+
__('Restore','shortpixel-image-optimiser')), */
|
109 |
+
|
110 |
+
$has_backup = $this->ctrl->getBackupFolderAny($item->folder, array());
|
111 |
+
|
112 |
Â
$settings = $this->ctrl->getSettings();
|
113 |
Â
$actionsEnabled = array();
|
114 |
Â
if($settings->quotaExceeded) {
|
115 |
Â
$actionsEnabled['quota'] = true;
|
116 |
+
} elseif($item->status == ShortPixelMeta::FILE_STATUS_UNPROCESSED ||
|
117 |
+
$item->status == ShortPixelMeta::FILE_STATUS_PENDING ||
|
118 |
+
$item->status == ShortPixelMeta::FILE_STATUS_RESTORED ) {
|
119 |
Â
$actionsEnabled['optimize'] = true;
|
120 |
+
} elseif($item->status == ShortPixelMeta::FILE_STATUS_SUCCESS && $has_backup) {
|
121 |
Â
$actionsEnabled['restore'] = true;
|
122 |
+
$actionsEnabled['compare'] = true;
|
123 |
Â
switch($item->compression_type) {
|
124 |
Â
case 2:
|
125 |
Â
$actionsEnabled['redolossy'] = $actionsEnabled['redolossless'] = true;
|
131 |
Â
$actionsEnabled['redolossy'] = $actionsEnabled['redoglossy'] = true;
|
132 |
Â
}
|
133 |
Â
//$actionsEnabled['redo'.($item->compression_type == 1 ? "lossless" : "lossy")] = true;
|
134 |
+
} elseif($item->status == ShortPixelMeta::FILE_STATUS_RESTORED || $item->status < ShortPixelMeta::FILE_STATUS_UNPROCESSED) {
|
135 |
Â
$actionsEnabled['retry'] = true;
|
136 |
Â
}
|
137 |
Â
$actionsEnabled['view'] = true;
|
141 |
Â
return ShortPixelMetaFacade::pathToRootRelative($item->folder);
|
142 |
Â
case 'status':
|
143 |
Â
switch($item->status) {
|
144 |
+
case ShortPixelMeta::FILE_STATUS_RESTORED:
|
145 |
+
$msg = __('Restored','shortpixel-image-optimiser');
|
146 |
+
break;
|
147 |
+
case ShortPixelMeta::FILE_STATUS_TORESTORE:
|
148 |
+
$msg = __('Restore Pending','shortpixel-image-optimiser');
|
149 |
+
break;
|
150 |
+
case ShortPixelMeta::FILE_STATUS_SUCCESS:
|
151 |
+
$msg = 0 + intval($item->message) == 0
|
152 |
+
? __('Bonus processing','shortpixel-image-optimiser')
|
153 |
+
: __('Reduced by','shortpixel-image-optimiser') . " <strong>" . $item->message . "%</strong>"
|
154 |
+
. (0 + intval($item->message) < 5 ? "<br>" . __('Bonus processing','shortpixel-image-optimiser') . "." : "");
|
155 |
Â
break;
|
156 |
+
case 1: $msg = "<img src=\"" . plugins_url( 'shortpixel-image-optimiser/res/img/loading.gif') . "\" class='sp-loading-small'> "
|
157 |
Â
. __('Pending','shortpixel-image-optimiser');
|
158 |
Â
break;
|
159 |
Â
case 0: $msg = __('Waiting','shortpixel-image-optimiser');
|
168 |
Â
return "<div id='sp-cust-msg-C-" . $item->id . "'>" . $msg . "</div>";
|
169 |
Â
break;
|
170 |
Â
case 'options':
|
171 |
+
// [BS] Unprocessed items have no meta. Anything displayed here would be wrong.
|
172 |
+
if (ShortPixelMeta::FILE_STATUS_UNPROCESSED == $item->status || ShortPixelMeta::FILE_STATUS_RESTORED == $item->status)
|
173 |
+
return __('', 'shortpixel-image-optimiser');
|
174 |
+
|
175 |
+
return __($item->compression_type == 2 ? 'Glossy' : ($item->compression_type == 1 ? 'Lossy' : 'Lossless'),'shortpixel-image-optimiser')
|
176 |
+
. ($item->keep_exif == 0 ? "": ", " . __('Keep EXIF','shortpixel-image-optimiser'))
|
177 |
+
. ($item->cmyk2rgb == 1 ? "": ", " . __('Preserve CMYK','shortpixel-image-optimiser'));
|
178 |
Â
case 'media_type':
|
179 |
Â
return $item->$column_name;
|
180 |
+
case 'date':
|
181 |
+
//[BS] if not optimized, show the timestamp when the file was added
|
182 |
+
|
183 |
+
/*if ( '0000-00-00 00:00:00' === $item->ts_optimized )
|
184 |
+
$usetime = $item->ts_added;
|
185 |
+
else {
|
186 |
+
$usetime = $item->ts_optimized;
|
187 |
+
} */
|
188 |
+
if ( '0000-00-00 00:00:00' === $item->ts_optimized )
|
189 |
+
return "<span class='date-C-" . $item->id . "'></span>";
|
190 |
+
|
191 |
+
$date = new DateTime($item->ts_optimized);
|
192 |
+
return "<span class='date-C-" . $item->id . "'>" . ShortPixelTools::format_nice_date($date) . "</div>";
|
193 |
+
break;
|
194 |
Â
default:
|
195 |
Â
return print_r( $item, true ) ; //Show the whole array for troubleshooting purposes
|
196 |
Â
}
|
197 |
Â
}
|
198 |
+
|
199 |
Â
public function no_items() {
|
200 |
Â
echo(__('No images avaliable. Go to <a href="options-general.php?page=wp-shortpixel#adv-settings">Advanced Settings</a> to configure additional folders to be optimized.','shortpixel-image-optimiser'));
|
201 |
Â
}
|
202 |
+
|
203 |
Â
/**
|
204 |
Â
* Columns to make sortable.
|
205 |
Â
*
|
209 |
Â
$sortable_columns = array(
|
210 |
Â
'name' => array( 'name', true ),
|
211 |
Â
'folder' => array( 'folder', true ),
|
212 |
+
'status' => array( 'status', false ),
|
213 |
+
'date' => array('ts_optimized', true),
|
214 |
Â
);
|
215 |
Â
|
216 |
Â
return $sortable_columns;
|
217 |
Â
}
|
218 |
+
|
219 |
Â
/**
|
220 |
Â
* Handles data query and filter, sorting, and pagination.
|
221 |
Â
*/
|
222 |
Â
public function prepare_items() {
|
223 |
Â
|
224 |
Â
$this->_column_headers = $this->get_column_info();
|
225 |
+
|
226 |
Â
$this->_column_headers[0] = $this->get_columns();
|
227 |
Â
|
228 |
Â
/** Process actions */
|
236 |
Â
'total_items' => $total_items, //WE have to calculate the total number of items
|
237 |
Â
'per_page' => $perPage //WE have to determine how many items to show on a page
|
238 |
Â
));
|
239 |
+
|
240 |
+
// [BS] Moving this from ts_added since often images get added at the same time, resulting in unpredictable sorting
|
241 |
+
$orderby = ( ! empty( $_GET['orderby'] ) ) ? sanitize_text_field($_GET['orderby']) : 'id';
|
242 |
Â
// If no order, default to asc
|
243 |
+
$order = ( ! empty($_GET['order'] ) ) ? sanitize_text_field($_GET['order']) : 'desc';
|
244 |
+
$currentPage = ( ! empty($_GET['paged'])) ? intval($_GET['paged']) : $currentPage;
|
245 |
+
|
246 |
Â
$this->items = $this->spMetaDao->getPaginatedMetas($this->hasNextGen, $this->getFilter(), $perPage, $currentPage, $orderby, $order);
|
247 |
Â
return $this->items;
|
248 |
+
}
|
249 |
+
|
250 |
Â
protected function getFilter() {
|
251 |
Â
$filter = array();
|
252 |
Â
if(isset($_GET["s"]) && strlen($_GET["s"])) {
|
254 |
Â
}
|
255 |
Â
return $filter;
|
256 |
Â
}
|
257 |
+
|
258 |
Â
public function record_count() {
|
259 |
Â
return $this->spMetaDao->getCustomMetaCount($this->getFilter());
|
260 |
Â
}
|
261 |
+
|
262 |
Â
public function action_optimize_image( $id ) {
|
263 |
Â
$this->ctrl->optimizeCustomImage($id);
|
264 |
Â
}
|
265 |
+
|
266 |
Â
public function action_restore_image( $id ) {
|
267 |
Â
$this->ctrl->doCustomRestore($id);
|
268 |
Â
}
|
269 |
+
|
270 |
Â
public function action_redo_image( $id, $type = false ) {
|
271 |
Â
$this->ctrl->redo('C-' . $id, $type);
|
272 |
Â
}
|
273 |
+
|
274 |
Â
public function process_actions() {
|
275 |
Â
|
276 |
Â
//Detect when a bulk action is being triggered...
|
277 |
Â
$nonce = isset($_REQUEST['_wpnonce']) ? esc_attr($_REQUEST['_wpnonce']) : false;
|
278 |
+
$redirect_url = esc_url_raw(remove_query_arg(array('action', 'image', '_wpnonce')));
|
279 |
+
|
280 |
Â
switch($this->current_action()) {
|
281 |
Â
case 'optimize':
|
282 |
Â
if (!wp_verify_nonce($nonce, 'sp_optimize_image')) {
|
283 |
Â
die('Error.');
|
284 |
Â
} else {
|
285 |
Â
$this->action_optimize_image(absint($_GET['image']));
|
286 |
+
wp_redirect($redirect_url);
|
287 |
Â
exit;
|
288 |
Â
}
|
289 |
Â
break;
|
292 |
Â
die('Error.');
|
293 |
Â
} else {
|
294 |
Â
$this->action_restore_image(absint($_GET['image']));
|
295 |
+
wp_redirect($redirect_url);
|
296 |
Â
exit;
|
297 |
Â
}
|
298 |
Â
break;
|
300 |
Â
if (!wp_verify_nonce($nonce, 'sp_redo_image')) {
|
301 |
Â
die('Error.');
|
302 |
Â
} else {
|
303 |
+
$this->action_redo_image(absint($_GET['image']), sanitize_text_field($_GET['type']));
|
304 |
+
wp_redirect($redirect_url);
|
305 |
Â
exit;
|
306 |
Â
}
|
307 |
Â
break;
|
@@ -1,20 +1,20 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
class ShortPixelView {
|
4 |
-
|
5 |
Â
private $ctrl;
|
6 |
-
|
7 |
Â
public function __construct($controller) {
|
8 |
Â
$this->ctrl = $controller;
|
9 |
Â
}
|
10 |
-
|
11 |
Â
//handling older
|
12 |
Â
public function ShortPixelView($controller) {
|
13 |
Â
$this->__construct($controller);
|
14 |
Â
}
|
15 |
Â
|
16 |
-
public function displayQuotaExceededAlert($quotaData, $averageCompression = false, $recheck = false)
|
17 |
-
{ ?>
|
18 |
Â
<br/>
|
19 |
Â
<div class="wrap sp-quota-exceeded-alert" id="short-pixel-notice-exceed">
|
20 |
Â
<?php if($averageCompression) { ?>
|
@@ -30,42 +30,42 @@ class ShortPixelView {
|
|
30 |
Â
</div>
|
31 |
Â
</div>
|
32 |
Â
<?php } ?>
|
33 |
-
<img src="<?php echo(plugins_url('/shortpixel-image-optimiser/res/img/robo-scared.png'));?>"
|
34 |
Â
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/robo-scared.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/robo-scared@2x.png' ));?> 2x'
|
35 |
Â
class='short-pixel-notice-icon'>
|
36 |
Â
<h3><?php /* translators: header of the alert box */ _e('Quota Exceeded','shortpixel-image-optimiser');?></h3>
|
37 |
-
<p><?php /* translators: body of the alert box */
|
38 |
Â
if($recheck) {
|
39 |
Â
echo('<span style="color: red">' . __('You have no available image credits. If you just bought a package, please note that sometimes it takes a few minutes for the payment confirmation to be sent to us by the payment processor.','shortpixel-image-optimiser') . '</span><br>');
|
40 |
Â
}
|
41 |
-
printf(__('The plugin has optimized <strong>%s images</strong> and stopped because it reached the available quota limit.','shortpixel-image-optimiser'),
|
42 |
-
number_format(max(0, $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric'])));?>
|
43 |
Â
<?php if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) { ?>
|
44 |
-
<?php
|
45 |
Â
printf(__('<strong>%s images and %s thumbnails</strong> are not yet optimized by ShortPixel.','shortpixel-image-optimiser'),
|
46 |
-
number_format(max(0, $quotaData['mainFiles'] - $quotaData['mainProcessedFiles'])),
|
47 |
Â
number_format(max(0, ($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles'])))); ?>
|
48 |
Â
<?php } ?></p>
|
49 |
Â
<div> <!-- style='float:right;margin-top:20px;'> -->
|
50 |
Â
<button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-right:10px;"><strong>
|
51 |
Â
<?php _e('Show me the best available options', 'shortpixel_image_optimiser'); ?></strong></button>
|
52 |
-
<a class='button button-primary' href='https://shortpixel.com/login/<?php echo($this->ctrl->getApiKey());?>'
|
53 |
Â
title='<?php _e('Go to my account and select a plan','shortpixel-image-optimiser');?>' target='_blank' style="margin-right:10px;">
|
54 |
Â
<strong><?php _e('Upgrade','shortpixel-image-optimiser');?></strong>
|
55 |
Â
</a>
|
56 |
Â
<input type='button' name='checkQuota' class='button' value='<?php _e('Confirm New Credits','shortpixel-image-optimiser');?>'
|
57 |
Â
onclick="ShortPixel.recheckQuota()">
|
58 |
Â
</div>
|
59 |
-
<p><?php _e('Get more image credits by referring ShortPixel to your friends!','shortpixel-image-optimiser');?>
|
60 |
Â
<a href="https://shortpixel.com/login/<?php echo(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey());?>/tell-a-friend" target="_blank">
|
61 |
Â
<?php _e('Check your account','shortpixel-image-optimiser');?>
|
62 |
Â
</a> <?php _e('for your unique referral link. For each user that joins, you will receive +100 additional image credits/month.','shortpixel-image-optimiser');?>
|
63 |
Â
</p>
|
64 |
-
|
65 |
Â
</div> <?php self::includeProposeUpgradePopup();
|
66 |
Â
}
|
67 |
-
|
68 |
-
public static function displayApiKeyAlert()
|
69 |
Â
{ ?>
|
70 |
Â
<p><?php _e('In order to start the optimization process, you need to validate your API Key in the '
|
71 |
Â
. '<a href="options-general.php?page=wp-shortpixel">ShortPixel Settings</a> page in your WordPress Admin.','shortpixel-image-optimiser');?>
|
@@ -75,7 +75,7 @@ class ShortPixelView {
|
|
75 |
Â
</p>
|
76 |
Â
<?php
|
77 |
Â
}
|
78 |
-
|
79 |
Â
public static function displayActivationNotice($when = 'activate', $extra = '') {
|
80 |
Â
$extraStyle = ($when == 'compat' || $when == 'fileperms' ? "background-color: #ff9999;margin: 5px 20px 15px 0;'" : '');
|
81 |
Â
$icon = false;
|
@@ -84,7 +84,7 @@ class ShortPixelView {
|
|
84 |
Â
case 'compat': $extraClass = 'notice-error below-h2';
|
85 |
Â
case 'fileperms': $icon = 'scared'; $extraClass = 'notice-error'; break;
|
86 |
Â
case 'unlisted': $icon = 'magnifier'; break;
|
87 |
-
case 'upgmonth':
|
88 |
Â
case 'upgbulk': $icon = 'notes'; $extraClass = 'notice-success'; break;
|
89 |
Â
case 'spai':
|
90 |
Â
case 'generic-err': $extraClass = 'notice-error is-dismissible'; break;
|
@@ -94,11 +94,11 @@ class ShortPixelView {
|
|
94 |
Â
<div class='notice <?php echo($extraClass);?> notice-warning' id='short-pixel-notice-<?php echo($when);?>' <?php echo($extraStyle);?>>
|
95 |
Â
<?php if($when != 'activate') { ?>
|
96 |
Â
<div style="float:right;">
|
97 |
-
<?php if($when == 'upgmonth' || $when == 'upgbulk'){ ?>
|
98 |
Â
<button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-top:10px;margin-left:10px;"><strong>
|
99 |
Â
<?php _e('Show me the best available options', 'shortpixel_image_optimiser'); ?></strong></button>
|
100 |
Â
<?php } ?>
|
101 |
-
<?php if($when == 'unlisted'){ ?>
|
102 |
Â
<a href="javascript:ShortPixel.includeUnlisted()" class="button button-primary" style="margin-top:10px;margin-left:10px;">
|
103 |
Â
<strong><?php _e('Yes, include these thumbnails','shortpixel-image-optimiser');?></strong></a>
|
104 |
Â
<?php }
|
@@ -125,7 +125,7 @@ class ShortPixelView {
|
|
125 |
Â
if($when == 'upgmonth' || $when == 'upgbulk') { echo(' '); _e('advice','shortpixel-image-optimiser');}
|
126 |
Â
?></h3> <?php
|
127 |
Â
switch($when) {
|
128 |
-
case '2h' :
|
129 |
Â
_e("Action needed. Please <a href='https://shortpixel.com/wp-apikey' target='_blank'>get your API key</a> to activate your ShortPixel plugin.",'shortpixel-image-optimiser') . "<BR><BR>";
|
130 |
Â
break;
|
131 |
Â
case '3d':
|
@@ -157,18 +157,18 @@ class ShortPixelView {
|
|
157 |
Â
case 'upgbulk' : ?>
|
158 |
Â
<p> <?php
|
159 |
Â
if($when == 'upgmonth') {
|
160 |
-
printf(__("You are adding an average of <strong>%d images and thumbnails every month</strong> to your Media Library and you have <strong>a plan of %d images/month</strong>."
|
161 |
Â
. " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel_image_optimiser'), $extra['monthAvg'], $extra['monthlyQuota']);
|
162 |
Â
} else {
|
163 |
Â
printf(__("You currently have <strong>%d images and thumbnails to optimize</strong> but you only have <strong>%d images</strong> available in your current plan."
|
164 |
Â
. " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel_image_optimiser'), $extra['filesTodo'], $extra['quotaAvailable']);
|
165 |
-
}?></p><?php
|
166 |
Â
self::includeProposeUpgradePopup();
|
167 |
Â
break;
|
168 |
Â
case 'unlisted' :
|
169 |
Â
_e("<p>ShortPixel found thumbnails which are not registered in the metadata but present alongside the other thumbnails. These thumbnails could be created and needed by some plugin or by the theme. Let ShortPixel optimize them as well?</p>", 'shortpixel-image-optimiser');?>
|
170 |
Â
<p>
|
171 |
-
<?php _e("For example, the image", 'shortpixel-image-optimiser');?>
|
172 |
Â
<a href='post.php?post=<?php echo($extra->id);?>&action=edit' target='_blank'>
|
173 |
Â
<?php echo($extra->name); ?>
|
174 |
Â
</a> has also these thumbs not listed in metadata:
|
@@ -185,10 +185,12 @@ class ShortPixelView {
|
|
185 |
Â
</div>
|
186 |
Â
<?php
|
187 |
Â
}
|
188 |
-
|
189 |
-
|
Â
|
|
Â
|
|
190 |
Â
<div id="shortPixelProposeUpgradeShade" class="sp-modal-shade" style="display:none;">
|
191 |
-
<div id="shortPixelProposeUpgrade" class="shortpixel-modal shortpixel-hide" style="min-width:
|
192 |
Â
<div class="sp-modal-title">
|
193 |
Â
<button type="button" class="sp-close-upgrade-button" onclick="ShortPixel.closeProposeUpgrade()">×</button>
|
194 |
Â
<?php _e('Upgrade your ShortPixel account', 'shortpixel-image-optimiser');?>
|
@@ -196,10 +198,10 @@ class ShortPixelView {
|
|
196 |
Â
<div class="sp-modal-body sptw-modal-spinner" style="height:auto;min-height:400px;padding:0;">
|
197 |
Â
</div>
|
198 |
Â
</div>
|
199 |
-
</div>
|
200 |
Â
<?php }
|
201 |
-
|
202 |
-
public function displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount, $bulkRan,
|
203 |
Â
$averageCompression, $filesOptimized, $savedSpace, $percent, $customCount) {
|
204 |
Â
$settings = $this->ctrl->getSettings();
|
205 |
Â
$this->ctrl->outputHSBeacon();
|
@@ -220,7 +222,7 @@ class ShortPixelView {
|
|
220 |
Â
<div class="bulk-label"><?php _e('Smaller thumbnails','shortpixel-image-optimiser');?></div>
|
221 |
Â
<div class="bulk-val"><?php echo(number_format($quotaData['totalMlFiles'] - $quotaData['mainMlFiles']));?></div>
|
222 |
Â
<div style='width:165px; display:inline-block; padding-left: 5px'>
|
223 |
-
<input type='checkbox' id='thumbnails' name='thumbnails' onclick='ShortPixel.checkThumbsUpdTotal(this)' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>>
|
224 |
Â
<?php _e('Include thumbnails','shortpixel-image-optimiser');?>
|
225 |
Â
</div><br>
|
226 |
Â
<?php if($quotaData["totalProcessedMlFiles"] > 0) { ?>
|
@@ -243,7 +245,7 @@ class ShortPixelView {
|
|
243 |
Â
<?php _e('Total to be optimized','shortpixel-image-optimiser');?>
|
244 |
Â
<div class="reset"><?php _e('(Originals and thumbnails)','shortpixel-image-optimiser');?></div>
|
245 |
Â
</div>
|
246 |
-
<div class="bulk-val bulk-total" id='displayTotal'><?php echo(number_format($customCount));?></div>
|
247 |
Â
<?php } ?>
|
248 |
Â
</div>
|
249 |
Â
<?php if(max(0, $quotaData['totalMlFiles'] - $quotaData['totalProcessedMlFiles']) + $customCount > 0) { ?>
|
@@ -275,7 +277,7 @@ class ShortPixelView {
|
|
275 |
Â
<input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup', event)" style="width:100%">
|
276 |
Â
<input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)" style="display:none">
|
277 |
Â
</div>
|
278 |
-
|
279 |
Â
<?php }
|
280 |
Â
} else {?>
|
281 |
Â
<div class="bulk-play bulk-nothing-optimize">
|
@@ -315,7 +317,7 @@ class ShortPixelView {
|
|
315 |
Â
<?php if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) { ?>
|
316 |
Â
<p><?php printf(__('%s images and %s thumbnails are not yet optimized by ShortPixel.','shortpixel-image-optimiser'),
|
317 |
Â
number_format($quotaData['mainFiles'] - $quotaData['mainProcessedFiles']),
|
318 |
-
number_format(($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles'])));?>
|
319 |
Â
</p>
|
320 |
Â
<?php } ?>
|
321 |
Â
<p><?php _e('You can continue optimizing your Media Gallery from where you left, by clicking the Resume processing button. Already optimized images will not be reprocessed.','shortpixel-image-optimiser');?></p>
|
@@ -356,15 +358,15 @@ class ShortPixelView {
|
|
356 |
Â
<div class="fb-like" data-href="https://www.facebook.com/ShortPixel" data-width="260" data-layout="button_count" data-action="like" data-show-faces="true" data-share="true"></div>
|
357 |
Â
</div>
|
358 |
Â
<div style="float:left;margin:-7px 0 0 10px">
|
359 |
-
<a href="https://twitter.com/share" class="twitter-share-button" data-url="https://shortpixel.com"
|
360 |
-
data-text="<?php
|
361 |
Â
if(0+$averageCompression>20) {
|
362 |
Â
_e("I just #optimized my site's images by ",'shortpixel-image-optimiser');
|
363 |
Â
} else {
|
364 |
Â
_e("I just #optimized my site's images ",'shortpixel-image-optimiser');
|
365 |
Â
}
|
366 |
Â
echo(round($averageCompression) ."%");
|
367 |
-
echo(__("with @ShortPixel, a #WordPress image optimization plugin",'shortpixel-image-optimiser') . " #pagespeed #seo");?>"
|
368 |
Â
data-size='large'><?php _e('Tweet','shortpixel-image-optimiser');?></a>
|
369 |
Â
</div>
|
370 |
Â
<script>
|
@@ -387,7 +389,7 @@ class ShortPixelView {
|
|
387 |
Â
</script>
|
388 |
Â
</div>
|
389 |
Â
</div>
|
390 |
-
<?php if(0+$averageCompression>30) {?>
|
391 |
Â
<div class='shortpixel-rate-us' style='float:left;padding-top:0'>
|
392 |
Â
<a href="https://wordpress.org/support/view/plugin-reviews/shortpixel-image-optimiser?rate=5#postform" target="_blank">
|
393 |
Â
<span>
|
@@ -399,13 +401,13 @@ class ShortPixelView {
|
|
399 |
Â
</div>
|
400 |
Â
<div id="sp-bulk-stats" style="display:none">
|
401 |
Â
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
402 |
-
</div>
|
403 |
Â
</div>
|
404 |
Â
<p><?php printf(__('Go to the ShortPixel <a href="%soptions-general.php?page=wp-shortpixel#stats">Stats</a>
|
405 |
Â
and see all your websites\' optimized stats. Download your detailed <a href="https://%s/v2/report.php?key=%s">Optimization Report</a>
|
406 |
Â
to check your image optimization statistics for the last 40 days.','shortpixel-image-optimiser'),
|
407 |
Â
get_admin_url(), SHORTPIXEL_API, (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) );?></p>
|
408 |
-
<?php
|
409 |
Â
$failed = $this->ctrl->getPrioQ()->getFailed();
|
410 |
Â
if(count($failed)) { ?>
|
411 |
Â
<div class="bulk-progress sp-notice sp-notice-warning sp-floating-block sp-double-width" style="margin-bottom: 15px">
|
@@ -418,20 +420,20 @@ class ShortPixelView {
|
|
418 |
Â
<div class="bulk-progress sp-notice sp-notice-info sp-floating-block sp-double-width">
|
419 |
Â
<?php
|
420 |
Â
$todo = $reopt = false;
|
421 |
-
if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) {
|
422 |
Â
$todo = true;
|
423 |
Â
$mainNotProcessed = max(0, $quotaData['mainFiles'] - $quotaData['mainProcessedFiles']);
|
424 |
Â
$thumbsNotProcessed = max(0, ($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']));
|
425 |
Â
?>
|
426 |
Â
<p>
|
427 |
-
<?php
|
428 |
Â
if($mainNotProcessed && $thumbsNotProcessed) {
|
429 |
-
printf(__("%s images and %s thumbnails are not yet optimized by ShortPixel.",'shortpixel-image-optimiser'),
|
430 |
-
number_format($mainNotProcessed), number_format($thumbsNotProcessed));
|
431 |
Â
} elseif($mainNotProcessed) {
|
432 |
-
printf(__("%s images are not yet optimized by ShortPixel.",'shortpixel-image-optimiser'), number_format($mainNotProcessed));
|
433 |
Â
} elseif($thumbsNotProcessed) {
|
434 |
-
printf(__("%s thumbnails are not yet optimized by ShortPixel.",'shortpixel-image-optimiser'), number_format($thumbsNotProcessed));
|
435 |
Â
}
|
436 |
Â
_e('','shortpixel-image-optimiser');
|
437 |
Â
if (count($quotaData['filesWithErrors'])) {
|
@@ -474,21 +476,21 @@ class ShortPixelView {
|
|
474 |
Â
$extraW = $extraO = '';
|
475 |
Â
if( !$this->ctrl->backupFolderIsEmpty()
|
476 |
Â
&& ( ($quotaData['totalProcLossyFiles'] > 0 && $settings->compressionType != 1)
|
477 |
-
|| ($quotaData['totalProcGlossyFiles'] > 0 && $settings->compressionType != 2)
|
478 |
Â
|| ($quotaData['totalProcLosslessFiles'] > 0 && $settings->compressionType != 0)))
|
479 |
-
{
|
480 |
Â
$todo = $reopt = true;
|
481 |
Â
$statType = ucfirst($otherTypes[0]);
|
482 |
Â
$thumbsCount = $quotaData['totalProc'.$statType.'Files'] - $quotaData['mainProc'.$statType.'Files'];
|
483 |
-
|
484 |
Â
$statType2 = ucfirst($otherTypes[1]);
|
485 |
Â
$thumbsCount2 = $quotaData['totalProc'.$statType2.'Files'] - $quotaData['mainProc'.$statType2.'Files'];
|
486 |
Â
if($quotaData['totalProc'.$statType2.'Files'] > 0 ) {
|
487 |
Â
if($quotaData['totalProc'.$statType.'Files'] > 0) {
|
488 |
-
$extraW = sprintf(__('%s images and %s thumbnails were optimized <strong>%s</strong>. ','shortpixel-image-optimiser'),
|
489 |
Â
number_format($quotaData['mainProc'.$statType2.'Files']),
|
490 |
Â
number_format($thumbsCount2), $otherTypes[1]);
|
491 |
-
$extraO = sprintf(__('%s images were optimized <strong>%s</strong>. ','shortpixel-image-optimiser'),
|
492 |
Â
number_format($quotaData['mainProc'.$statType2.'Files']), $otherTypes[1]);
|
493 |
Â
} else {
|
494 |
Â
$extraW = $extraO = ''; $otherTypes[0] = $otherTypes[1]; $statType = $statType2;
|
@@ -497,13 +499,13 @@ class ShortPixelView {
|
|
497 |
Â
?>
|
498 |
Â
<p id="with-thumbs" <?php echo(!$settings->processThumbnails ? 'style="display:none;"' : "");?>>
|
499 |
Â
<?php echo($extraW);
|
500 |
-
printf(__('%s images and %s thumbnails were optimized <strong>%s</strong>. You can re-optimize <strong>%s</strong> the ones that have backup.','shortpixel-image-optimiser'),
|
501 |
Â
number_format($quotaData['mainProc'.$statType.'Files']),
|
502 |
Â
number_format($thumbsCount), $otherTypes[0], $optType);?>
|
503 |
Â
</p>
|
504 |
Â
<p id="without-thumbs" <?php echo($settings->processThumbnails ? 'style="display:none;"' : "");?>>
|
505 |
-
<?php echo($extraO);
|
506 |
-
printf(__('%s images were optimized <strong>%s</strong>. You can re-optimize <strong>%s</strong> the ones that have backup. ','shortpixel-image-optimiser'),
|
507 |
Â
number_format($quotaData['mainProc'.$statType.'Files']),
|
508 |
Â
$otherTypes[0], $optType);?>
|
509 |
Â
<?php echo($thumbsCount + $thumbsCount2 ? number_format($thumbsCount + $thumbsCount2) . __(' thumbnails will be restored to originals.','shortpixel-image-optimiser') : '');?>
|
@@ -518,18 +520,23 @@ class ShortPixelView {
|
|
518 |
Â
echo(' ');
|
519 |
Â
printf(__('Already <strong>%s</strong> optimized images will not be reprocessed.','shortpixel-image-optimiser'), $todo ? ($optType) : '');
|
520 |
Â
if($reopt) { ?>
|
521 |
-
<br><?php _e('Please note that reoptimizing images as <strong>lossy/lossless</strong> may use additional credits.','shortpixel-image-optimiser')?>
|
522 |
Â
<a href="http://blog.shortpixel.com/the-all-new-re-optimization-functions-in-shortpixel/" target="_blank" class="shortpixel-help-link">
|
523 |
Â
<span class="dashicons dashicons-editor-help"></span><?php _e('More info','shortpixel-image-optimiser');?>
|
524 |
Â
</a>
|
525 |
Â
<?php } ?>
|
526 |
Â
</p>
|
527 |
Â
<form action='' method='POST' >
|
528 |
-
<input type='checkbox' id='bulk-thumbnails' name='thumbnails' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>
|
529 |
Â
onchange="ShortPixel.onBulkThumbsCheck(this)"> <?php _e('Include thumbnails','shortpixel-image-optimiser');?><br><br>
|
Â
|
|
Â
|
|
Â
|
|
530 |
Â
<input type='submit' name='bulkProcess' id='bulkProcess' class='button button-primary' value='<?php _e('Restart Optimizing','shortpixel-image-optimiser');?>'
|
531 |
Â
<?php echo($settings->quotaExceeded? "disabled title=\"" . __("Top-up your account to optimize more images.",'shortpixel-image-optimiser')."\"" : ""); ?>>
|
532 |
-
<input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore',event)" style="float: right;">
|
Â
|
|
Â
|
|
533 |
Â
<input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup',event)" style="float: right;margin-right:10px;">
|
534 |
Â
<input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)" style="display:none">
|
535 |
Â
</form>
|
@@ -608,7 +615,7 @@ class ShortPixelView {
|
|
608 |
Â
</div>
|
609 |
Â
<?php
|
610 |
Â
}
|
611 |
-
|
612 |
Â
public function displayBulkProgressBar($running, $percent, $message, $remainingQuota, $averageCompression, $type = 1, $customPending = false) {
|
613 |
Â
$percentBefore = $percentAfter = '';
|
614 |
Â
if($percent > 24) {
|
@@ -636,26 +643,26 @@ class ShortPixelView {
|
|
636 |
Â
</script>
|
637 |
Â
</div>
|
638 |
Â
</div>
|
639 |
-
<?php if($running) {
|
640 |
Â
if($type > 0) { ?>
|
641 |
-
<div class="sp-h2"><?php
|
642 |
Â
echo($type & 1 ? __('Media Library','shortpixel-image-optimiser') . " " : "");
|
643 |
Â
echo($type & 3 == 3 ? __('and','shortpixel-image-optimiser') . " " : "");
|
644 |
-
echo($type & 2 ? __('Custom folders','shortpixel-image-optimiser') . " " : "");
|
645 |
Â
_e('optimization in progress ...','shortpixel-image-optimiser');?></div>
|
646 |
Â
<p style="margin: 0 0 18px;"><?php _e('Bulk optimization has started.','shortpixel-image-optimiser');?><br>
|
647 |
-
<?php
|
648 |
Â
} elseif($type == 0) { // restore ?>
|
649 |
-
<div class="sp-h2"><?php
|
650 |
Â
_e('Media Library restore in progress ...','shortpixel-image-optimiser');?></div>
|
651 |
-
<p style="margin: 0 0 18px;"><?php _e('Bulk restore has started.','shortpixel-image-optimiser');?><br>
|
652 |
Â
<?php }
|
653 |
Â
elseif($type == -1) { // cleanup ?>
|
654 |
-
<div class="sp-h2"><?php
|
655 |
Â
_e('Media Library cleanup in progress ...','shortpixel-image-optimiser');?></div>
|
656 |
-
<p style="margin: 0 0 18px;"><?php _e('Bulk cleanup has started.','shortpixel-image-optimiser');?><br>
|
657 |
Â
<?php }
|
658 |
-
printf(__('This process will take some time, depending on the number of images in your library. In the meantime, you can continue using
|
659 |
Â
the admin as usual, <a href="%s" target="_blank">in a different browser window or tab</a>.<br>
|
660 |
Â
However, <strong>if you close this window, the bulk processing will pause</strong> until you open the media gallery or the ShortPixel bulk page again.','shortpixel-image-optimiser'), get_admin_url());?>
|
661 |
Â
</p>
|
@@ -692,7 +699,7 @@ class ShortPixelView {
|
|
692 |
Â
</div>
|
693 |
Â
<?php
|
694 |
Â
}
|
695 |
-
|
696 |
Â
public function displayBulkStats($totalOptimized, $mainOptimized, $under5PercentCount, $averageCompression, $savedSpace) {?>
|
697 |
Â
<div class="bulk-progress bulk-stats">
|
698 |
Â
<div class="label"><?php _e('Processed Images and PDFs:','shortpixel-image-optimiser');?></div><div class="stat-value"><?php echo(number_format($mainOptimized));?></div><br>
|
@@ -706,11 +713,11 @@ class ShortPixelView {
|
|
706 |
Â
</div>
|
707 |
Â
<?php
|
708 |
Â
}
|
709 |
-
|
710 |
Â
public function displayFailed($failed) {
|
711 |
Â
?>
|
712 |
Â
<div class="bulk-progress bulk-stats" style="padding-top:5px;">
|
713 |
-
<?php foreach($failed as $fail) {
|
714 |
Â
if($fail->type == ShortPixelMetaFacade::CUSTOM_TYPE) {
|
715 |
Â
$meta = $fail->meta;
|
716 |
Â
?> <div><a href="<?php echo(ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath());?>"><?php echo(substr($meta->getName(), 0, 80));?> - ID: C-<?php echo($fail->id);?></a></div><br/>
|
@@ -723,7 +730,7 @@ class ShortPixelView {
|
|
723 |
Â
<?php
|
724 |
Â
}
|
725 |
Â
function displaySettings($showApiKey, $editApiKey, $quotaData, $notice, $resources = null, $averageCompression = null, $savedSpace = null, $savedBandwidth = null,
|
726 |
-
$remainingImages = null, $totalCallsMade = null, $fileCount = null, $backupFolderSize = null,
|
727 |
Â
$customFolders = null, $folderMsg = false, $addedFolder = false, $showAdvanced = false, $cloudflareAPI = false, $htaccessWriteable = false, $isNginx = false ) {
|
728 |
Â
//wp_enqueue_script('jquery.idTabs.js', plugins_url('/js/jquery.idTabs.js',__FILE__) );
|
729 |
Â
$this->ctrl->outputHSBeacon();
|
@@ -731,7 +738,7 @@ class ShortPixelView {
|
|
731 |
Â
<div class="wrap">
|
732 |
Â
<h1><?php _e('ShortPixel Plugin Settings','shortpixel-image-optimiser');?></h1>
|
733 |
Â
<p style="font-size:18px">
|
734 |
-
<a href="https://shortpixel.com/<?php
|
735 |
Â
echo(($this->ctrl->getVerifiedKey() ? "login/".(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) : "pricing") . WPShortPixel::getAffiliateSufix());
|
736 |
Â
?>" target="_blank" style="font-size:18px">
|
737 |
Â
<?php _e('Upgrade now','shortpixel-image-optimiser');?>
|
@@ -767,7 +774,7 @@ class ShortPixelView {
|
|
767 |
Â
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-settings"><?php _e('General','shortpixel-image-optimiser');?></a></h2>
|
768 |
Â
<?php }
|
769 |
Â
$this->displaySettingsForm($showApiKey, $editApiKey, $quotaData);?>
|
770 |
-
</section>
|
771 |
Â
<?php if($this->ctrl->getVerifiedKey()) {?>
|
772 |
Â
<section <?php echo($showAdvanced ? "class='sel-tab'" : "");?> id="tab-adv-settings" class="clearfix">
|
773 |
Â
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-adv-settings"><?php _e('Advanced','shortpixel-image-optimiser');?></a></h2>
|
@@ -789,9 +796,9 @@ class ShortPixelView {
|
|
789 |
Â
<section id="tab-stats">
|
790 |
Â
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-stats"><?php _e('Statistics','shortpixel-image-optimiser');?></a></h2>
|
791 |
Â
<?php
|
792 |
-
$this->displaySettingsStats($quotaData, $averageCompression, $savedSpace, $savedBandwidth,
|
793 |
Â
$remainingImages, $totalCallsMade, $fileCount, $backupFolderSize);?>
|
794 |
-
</section>
|
795 |
Â
<?php }
|
796 |
Â
if( $resources !== null && $quotaData['APICallsQuotaOneTimeNumeric']<10000 && $quotaData['APICallsQuotaNumeric']<5000 ) {?>
|
797 |
Â
<section id="tab-resources">
|
@@ -807,15 +814,15 @@ class ShortPixelView {
|
|
807 |
Â
</script>
|
808 |
Â
</div>
|
809 |
Â
<?php
|
810 |
-
}
|
811 |
-
|
812 |
Â
public function displaySettingsForm($showApiKey, $editApiKey, $quotaData) {
|
813 |
Â
$settings = $this->ctrl->getSettings();
|
814 |
Â
$checked = ($this->ctrl->processThumbnails() ? 'checked' : '');
|
815 |
Â
$checkedBackupImages = ($this->ctrl->backupImages() ? 'checked' : '');
|
816 |
Â
$removeExif = ($settings->keepExif ? '' : 'checked');
|
817 |
Â
$resize = ($this->ctrl->getResizeImages() ? 'checked' : '');
|
818 |
-
$resizeDisabled = ($this->ctrl->getResizeImages() ? '' : 'disabled');
|
819 |
Â
$minSizes = $this->ctrl->getMaxIntermediateImageSize();
|
820 |
Â
$thumbnailsToProcess = isset($quotaData['totalFiles']) ? ($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']) : 0;
|
821 |
Â
$adminEmail = get_bloginfo('admin_email');
|
@@ -824,7 +831,7 @@ class ShortPixelView {
|
|
824 |
Â
<div class="wp-shortpixel-options wp-shortpixel-tab-content">
|
825 |
Â
<?php if($this->ctrl->getVerifiedKey()) { ?>
|
826 |
Â
<p><?php printf(__('New images uploaded to the Media Library will be optimized automatically.<br/>If you have existing images you would like to optimize, you can use the <a href="%supload.php?page=wp-short-pixel-bulk">Bulk Optimization Tool</a>.','shortpixel-image-optimiser'),get_admin_url());?></p>
|
827 |
-
<?php } else {
|
828 |
Â
if($showApiKey) {?>
|
829 |
Â
<h3><?php _e('Request an API Key:','shortpixel-image-optimiser');?></h3>
|
830 |
Â
<p style='font-size: 14px'><?php _e('If you don\'t have an API Key, you can request one for free. Just press the "Request Key" button after checking that the e-mail is correct.','shortpixel-image-optimiser');?></p>
|
@@ -869,24 +876,24 @@ class ShortPixelView {
|
|
869 |
Â
<p style='font-size: 14px'>
|
870 |
Â
<?php _e('If you already have an API Key please input it below and press Validate.','shortpixel-image-optimiser');?>
|
871 |
Â
</p>
|
872 |
-
<?php }
|
873 |
Â
}?>
|
874 |
Â
<table class="form-table">
|
875 |
Â
<tbody>
|
876 |
Â
<tr>
|
877 |
Â
<th scope="row"><label for="key"><?php _e('API Key:','shortpixel-image-optimiser');?></label></th>
|
878 |
Â
<td>
|
879 |
-
<?php
|
880 |
Â
$canValidate = false;
|
881 |
Â
if($showApiKey) {
|
882 |
Â
$canValidate = true;?>
|
883 |
-
<input name="key" type="text" id="key" value="<?php echo( $this->ctrl->getApiKey() );?>"
|
884 |
Â
class="regular-text" <?php echo($editApiKey ? "" : 'disabled') ?> <?php echo $this->ctrl->getVerifiedKey() ? 'onkeyup="ShortPixel.apiKeyChanged()"' : '' ?>>
|
885 |
-
<?php } elseif(defined("SHORTPIXEL_API_KEY")) {
|
886 |
Â
$canValidate = true;?>
|
887 |
-
<input name="key" type="text" id="key" disabled="true" placeholder="<?php
|
888 |
Â
if(defined("SHORTPIXEL_HIDE_API_KEY")) {
|
889 |
-
echo("********************");
|
890 |
Â
} else {
|
891 |
Â
_e('Multisite API Key','shortpixel-image-optimiser');
|
892 |
Â
}
|
@@ -904,7 +911,7 @@ class ShortPixelView {
|
|
904 |
Â
<?php if($showApiKey && !$editApiKey) { ?>
|
905 |
Â
<p class="settings-info"><?php _e('Key defined in wp-config.php.','shortpixel-image-optimiser');?></p>
|
906 |
Â
<?php } ?>
|
907 |
-
|
908 |
Â
</td>
|
909 |
Â
</tr>
|
910 |
Â
<?php if (!$this->ctrl->getVerifiedKey()) { //if invalid key we display the link to the API Key ?>
|
@@ -977,7 +984,7 @@ class ShortPixelView {
|
|
977 |
Â
<td>
|
978 |
Â
<input name="removeExif" type="checkbox" id="removeExif" <?php echo( $removeExif );?>>
|
979 |
Â
<label for="removeExif"><?php _e('Remove the EXIF tag of the image (recommended).','shortpixel-image-optimiser');?></label>
|
980 |
-
<p class="settings-info"> <?php _e('EXIF is a set of various pieces of information that are automatically embedded into the image upon creation. This can include GPS position, camera manufacturer, date and time, etc.
|
981 |
Â
Unless you really need that data to be preserved, we recommend removing it as it can lead to <a href="http://blog.shortpixel.com/how-much-smaller-can-be-images-without-exif-icc" target="_blank">better compression rates</a>.','shortpixel-image-optimiser');?></p>
|
982 |
Â
</td>
|
983 |
Â
</tr>
|
@@ -987,14 +994,14 @@ class ShortPixelView {
|
|
987 |
Â
<input name="resize" type="checkbox" id="resize" <?php echo( $resize );?>>
|
988 |
Â
<label for="resize"><?php _e('to maximum','shortpixel-image-optimiser');?></label>
|
989 |
Â
<input type="text" name="width" id="width" style="width:70px" class="resize-sizes"
|
990 |
-
value="<?php echo( $this->ctrl->getResizeWidth() > 0 ? $this->ctrl->getResizeWidth() : min(924, $minSizes['width']) );?>" <?php echo( $resizeDisabled );?>/> <?php
|
991 |
Â
_e('pixels wide ×','shortpixel-image-optimiser');?>
|
992 |
-
<input type="text" name="height" id="height" class="resize-sizes" style="width:70px"
|
993 |
-
value="<?php echo( $this->ctrl->getResizeHeight() > 0 ? $this->ctrl->getResizeHeight() : min(924, $minSizes['height']) );?>" <?php echo( $resizeDisabled );?>/> <?php
|
994 |
Â
_e('pixels high (original aspect ratio is preserved and image is not cropped)','shortpixel-image-optimiser');?>
|
995 |
Â
<input type="hidden" id="min-width" value="<?php echo($minSizes['width']);?>"/>
|
996 |
Â
<input type="hidden" id="min-height" value="<?php echo($minSizes['height']);?>"/>
|
997 |
-
<p class="settings-info">
|
998 |
Â
<?php _e('Recommended for large photos, like the ones taken with your phone. Saved space can go up to 80% or more after resizing.','shortpixel-image-optimiser');?>
|
999 |
Â
<a href="https://blog.shortpixel.com/resize-images/" class="shortpixel-help-link" target="_blank">
|
1000 |
Â
<span class="dashicons dashicons-editor-help"></span><?php _e('Read more','shortpixel-image-optimiser');?>
|
@@ -1002,11 +1009,11 @@ class ShortPixelView {
|
|
1002 |
Â
</p>
|
1003 |
Â
<div style="margin-top: 10px;">
|
1004 |
Â
<input type="radio" name="resize_type" id="resize_type_outer" value="outer" <?php echo($settings->resizeType == 'inner' ? '' : 'checked') ?> style="margin: -50px 10px 60px 0;">
|
1005 |
-
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-outer.png' ));?>"
|
1006 |
Â
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-outer.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-outer@2x.png' ));?> 2x'
|
1007 |
Â
title="<?php _e('Sizes will be greater or equal to the corresponding value. For example, if you set the resize dimensions at 1000x1200, an image of 2000x3000px will be resized to 1000x1500px while an image of 3000x2000px will be resized to 1800x1200px','shortpixel-image-optimiser');?>">
|
1008 |
Â
<input type="radio" name="resize_type" id="resize_type_inner" value="inner" <?php echo($settings->resizeType == 'inner' ? 'checked' : '') ?> style="margin: -50px 10px 60px 35px;">
|
1009 |
-
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?>"
|
1010 |
Â
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner@2x.png' ));?> 2x'
|
1011 |
Â
title="<?php _e('Sizes will be smaller or equal to the corresponding value. For example, if you set the resize dimensions at 1000x1200, an image of 2000x3000px will be resized to 800x1200px while an image of 3000x2000px will be resized to 1000x667px','shortpixel-image-optimiser');?>">
|
1012 |
Â
<div style="display:inline-block;margin-left: 20px;"><a href="https://blog.shortpixel.com/resize-images/" class="shortpixel-help-link" target="_blank">
|
@@ -1024,14 +1031,14 @@ class ShortPixelView {
|
|
1024 |
Â
</div>
|
1025 |
Â
<script>
|
1026 |
Â
jQuery(document).ready(function () {
|
1027 |
-
ShortPixel.setupGeneralTab(document.wp_shortpixel_options.compressionType,
|
1028 |
Â
Math.min(924, <?php echo($minSizes['width']);?>),
|
1029 |
Â
Math.min(924, <?php echo($minSizes['height']);?>));
|
1030 |
Â
});
|
1031 |
Â
</script>
|
1032 |
Â
<?php }
|
1033 |
Â
}
|
1034 |
-
|
1035 |
Â
public function displayAdvancedSettingsForm($customFolders = false, $addedFolder = false, $htaccessWriteable = false, $isNginx = false ) {
|
1036 |
Â
$settings = $this->ctrl->getSettings();
|
1037 |
Â
$minSizes = $this->ctrl->getMaxIntermediateImageSize();
|
@@ -1116,22 +1123,22 @@ class ShortPixelView {
|
|
1116 |
Â
<td></td>
|
1117 |
Â
</tr>
|
1118 |
Â
<?php foreach($customFolders as $folder) {
|
1119 |
-
$typ = $folder->getType();
|
1120 |
Â
$typ = $typ ? $typ . "<br>" : "";
|
1121 |
Â
$stat = $this->ctrl->getSpMetaDao()->getFolderOptimizationStatus($folder->getId());
|
1122 |
Â
$cnt = $folder->getFileCount();
|
1123 |
-
$st = ($cnt == 0
|
1124 |
Â
? __("Empty",'shortpixel-image-optimiser')
|
1125 |
-
: ($stat->Total == $stat->Optimized
|
1126 |
Â
? __("Optimized",'shortpixel-image-optimiser')
|
1127 |
Â
: ($stat->Optimized + $stat->Pending > 0 ? __("Pending",'shortpixel-image-optimiser') : __("Waiting",'shortpixel-image-optimiser'))));
|
1128 |
-
|
1129 |
Â
$err = $stat->Failed > 0 && !$st == __("Empty",'shortpixel-image-optimiser') ? " ({$stat->Failed} failed)" : "";
|
1130 |
-
|
1131 |
Â
$action = ($st == __("Optimized",'shortpixel-image-optimiser') || $st == __("Empty",'shortpixel-image-optimiser') ? __("Stop monitoring",'shortpixel-image-optimiser') : __("Stop optimizing",'shortpixel-image-optimiser'));
|
1132 |
-
|
1133 |
-
$fullStat = $st == __("Empty",'shortpixel-image-optimiser') ? "" : __("Optimized",'shortpixel-image-optimiser') . ": " . $stat->Optimized . ", "
|
1134 |
-
. __("Pending",'shortpixel-image-optimiser') . ": " . $stat->Pending . ", " . __("Waiting",'shortpixel-image-optimiser') . ": " . $stat->Waiting . ", "
|
1135 |
Â
. __("Failed",'shortpixel-image-optimiser') . ": " . $stat->Failed;
|
1136 |
Â
?>
|
1137 |
Â
<tr>
|
@@ -1153,42 +1160,49 @@ class ShortPixelView {
|
|
1153 |
Â
</td>
|
1154 |
Â
<td>
|
1155 |
Â
<input type="button" class="button remove-folder-button" data-value="<?php echo($folder->getPath()); ?>" title="<?php echo($action . " " . $folder->getPath()); ?>" value="<?php echo $action;?>">
|
1156 |
-
<input type="button" style="display:none;" class="button button-alert recheck-folder-button" data-value="<?php echo($folder->getPath()); ?>"
|
1157 |
-
title="<?php _e('Full folder refresh, check each file of the folder if it changed since it was optimized. Might take up to 1 min. for big folders.','shortpixel-image-optimiser');?>"
|
1158 |
Â
value="<?php _e('Refresh','shortpixel-image-optimiser');?>">
|
1159 |
Â
</td>
|
1160 |
Â
</tr>
|
1161 |
Â
<?php }?>
|
1162 |
Â
</table>
|
1163 |
Â
<?php } ?>
|
1164 |
-
|
1165 |
-
<
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
1173 |
Â
<p class="settings-info">
|
1174 |
Â
<?php _e('Use the Select... button to select site folders. ShortPixel will optimize images and PDFs from the specified folders and their subfolders. The optimization status for each image or PDF in these folders can be seen in the <a href="upload.php?page=wp-short-pixel-custom">Other Media list</a>, under the Media menu.','shortpixel-image-optimiser');?>
|
1175 |
Â
<a href="https://blog.shortpixel.com/optimize-images-outside-media-library/" target="_blank" class="shortpixel-help-link">
|
1176 |
Â
<span class="dashicons dashicons-editor-help"></span><?php _e('More info','shortpixel-image-optimiser');?>
|
1177 |
Â
</a>
|
1178 |
Â
</p>
|
1179 |
-
|
1180 |
-
|
Â
|
|
1181 |
Â
<div class="sp-modal-title"><?php _e('Select the images folder','shortpixel-image-optimiser');?></div>
|
1182 |
Â
<div class="sp-folder-picker"></div>
|
1183 |
Â
<input type="button" class="button button-info select-folder-cancel" value="<?php _e('Cancel','shortpixel-image-optimiser');?>" style="margin-right: 30px;">
|
1184 |
Â
<input type="button" class="button button-primary select-folder" value="<?php _e('Select','shortpixel-image-optimiser');?>">
|
1185 |
Â
</div>
|
1186 |
-
|
1187 |
Â
<script>
|
1188 |
Â
jQuery(document).ready(function () {
|
1189 |
Â
ShortPixel.initFolderSelector();
|
1190 |
Â
});
|
1191 |
Â
</script>
|
Â
|
|
1192 |
Â
</td>
|
1193 |
Â
</tr>
|
1194 |
Â
<?php if($hasNextGen) { ?>
|
@@ -1323,10 +1337,10 @@ class ShortPixelView {
|
|
1323 |
Â
<tr>
|
1324 |
Â
<th scope="row"><label for="excludePatterns"><?php _e('Exclude patterns','shortpixel-image-optimiser');?></label></th>
|
1325 |
Â
<td>
|
1326 |
-
<input name="excludePatterns" type="text" id="excludePatterns" value="<?php echo( $excludePatterns );?>" class="regular-text" placeholder="<?php
|
1327 |
-
_e('name:keepbig, path:/ignore_regex/i, size:1000x2000','shortpixel-image-optimiser');?>">
|
1328 |
Â
<?php _e('Exclude certain images from being optimized, based on patterns.','shortpixel-image-optimiser');?>
|
1329 |
-
<p class="settings-info">
|
1330 |
Â
<?php _e('Add patterns separated by comma. A pattern consist of a <strong>type:value</strong> pair; the accepted types are
|
1331 |
Â
<strong>"name"</strong>, <strong>"path"</strong> and <strong>"size"</strong>.
|
1332 |
Â
A file will be excluded if it matches any of the patterns.
|
@@ -1346,9 +1360,9 @@ class ShortPixelView {
|
|
1346 |
Â
<tr>
|
1347 |
Â
<th scope="row"><label for="authentication"><?php _e('HTTP AUTH credentials','shortpixel-image-optimiser');?></label></th>
|
1348 |
Â
<td>
|
1349 |
-
<input name="siteAuthUser" type="text" id="siteAuthUser" value="<?php echo( $settings->siteAuthUser );?>" class="regular-text" placeholder="<?php _e('User','shortpixel-image-optimiser');?>"><br>
|
1350 |
-
<input name="siteAuthPass" type="text" id="siteAuthPass" value="<?php echo( $settings->siteAuthPass );?>" class="regular-text" placeholder="<?php _e('Password','shortpixel-image-optimiser');?>">
|
1351 |
-
<p class="settings-info">
|
1352 |
Â
<?php _e('Only fill in these fields if your site (front-end) is not publicly accessible and visitors need a user/pass to connect to it. If you don\'t know what is this then just <strong>leave the fields empty</strong>.','shortpixel-image-optimiser');?>
|
1353 |
Â
</p>
|
1354 |
Â
</td>
|
@@ -1399,7 +1413,7 @@ class ShortPixelView {
|
|
1399 |
Â
</script>
|
1400 |
Â
<?php }
|
1401 |
Â
}
|
1402 |
-
|
1403 |
Â
/**
|
1404 |
Â
* @desc This form is used in WP back-end to allow users that use CloudFlare to save their settings
|
1405 |
Â
*
|
@@ -1425,7 +1439,7 @@ class ShortPixelView {
|
|
1425 |
Â
</th>
|
1426 |
Â
<td>
|
1427 |
Â
<input name="cloudflare-email" type="text" id="cloudflare-email" <?php echo($noCurl ? 'disabled' : '');?>
|
1428 |
-
value="<?php echo($this->ctrl->fetch_cloudflare_api_email()); ?>" class="regular-text">
|
1429 |
Â
<p class="settings-info">
|
1430 |
Â
<?php _e('The e-mail address you use to login to CloudFlare.','shortpixel-image-optimiser');?>
|
1431 |
Â
</p>
|
@@ -1437,7 +1451,7 @@ class ShortPixelView {
|
|
1437 |
Â
</th>
|
1438 |
Â
<td>
|
1439 |
Â
<input name="cloudflare-auth-key" type="text" id="cloudflare-auth-key" <?php echo($noCurl ? 'disabled' : '');?>
|
1440 |
-
value="<?php echo($this->ctrl->fetch_cloudflare_api_key()); ?>" class="regular-text">
|
1441 |
Â
<p class="settings-info">
|
1442 |
Â
<?php _e("This can be found when you're logged into your account, on the My Profile page:",'shortpixel-image-optimiser');?> <a href='https://www.cloudflare.com/a/profile' target='_blank'>https://www.cloudflare.com/a/profile</a>
|
1443 |
Â
</p>
|
@@ -1449,7 +1463,7 @@ class ShortPixelView {
|
|
1449 |
Â
</th>
|
1450 |
Â
<td>
|
1451 |
Â
<input name="cloudflare-zone-id" type="text" id="cloudflare-zone-id" <?php echo($noCurl ? 'disabled' : '');?>
|
1452 |
-
value="<?php echo($this->ctrl->fetch_cloudflare_api_zoneid()); ?>" class="regular-text">
|
1453 |
Â
<p class="settings-info">
|
1454 |
Â
<?php _e('This can be found in your Cloudflare account in the "Overview" section for your domain.','shortpixel-image-optimiser');?>
|
1455 |
Â
</p>
|
@@ -1609,29 +1623,29 @@ class ShortPixelView {
|
|
1609 |
Â
|
1610 |
Â
public function renderCustomColumn($id, $data, $extended = false){ ?>
|
1611 |
Â
<div id='sp-msg-<?php echo($id);?>' class='column-wp-shortPixel'>
|
1612 |
-
|
1613 |
Â
<?php switch($data['status']) {
|
1614 |
-
case 'n/a': ?>
|
1615 |
Â
<?php _e('Optimization N/A','shortpixel-image-optimiser');?> <?php
|
1616 |
Â
break;
|
1617 |
-
case 'notFound': ?>
|
1618 |
Â
<?php _e('Image does not exist.','shortpixel-image-optimiser');?> <?php
|
1619 |
Â
break;
|
1620 |
-
case 'invalidKey':
|
1621 |
Â
if(defined("SHORTPIXEL_API_KEY")) { // multisite key - need to be validated on each site but it's not invalid
|
1622 |
Â
?> <?php _e('Please <a href="options-general.php?page=wp-shortpixel">go to Settings</a> to validate the API Key.','shortpixel-image-optimiser');?> <?php
|
1623 |
Â
} else {
|
1624 |
Â
?> <?php _e('Invalid API Key. <a href="options-general.php?page=wp-shortpixel">Check your Settings</a>','shortpixel-image-optimiser');?> <?php
|
1625 |
-
}
|
1626 |
Â
break;
|
1627 |
-
case 'quotaExceeded':
|
1628 |
Â
echo($this->getQuotaExceededHTML(isset($data['message']) ? $data['message'] : ''));
|
1629 |
Â
break;
|
1630 |
-
case 'optimizeNow':
|
1631 |
-
if($data['showActions']) { ?>
|
1632 |
Â
<a class='button button-smaller button-primary' href="javascript:manualOptimization('<?php echo($id)?>', false)">
|
1633 |
Â
<?php _e('Optimize now','shortpixel-image-optimiser');?>
|
1634 |
-
</a>
|
1635 |
Â
<?php }
|
1636 |
Â
echo($data['message']);
|
1637 |
Â
if(isset($data['thumbsTotal']) && $data['thumbsTotal'] > 0) {
|
@@ -1643,7 +1657,7 @@ class ShortPixelView {
|
|
1643 |
Â
echo($data['message']);
|
1644 |
Â
if(isset($data['cleanup'])) {?> <a class='button button-smaller button-primary' href="javascript:manualOptimization('<?php echo($id)?>', true)">
|
1645 |
Â
<?php _e('Cleanup&Retry','shortpixel-image-optimiser');?>
|
1646 |
-
</a> <?php
|
1647 |
Â
} else {
|
1648 |
Â
if($data['status'] == 'retry') { ?>
|
1649 |
Â
<div style="overflow:hidden">
|
@@ -1659,7 +1673,7 @@ class ShortPixelView {
|
|
1659 |
Â
<?php
|
1660 |
Â
}
|
1661 |
Â
break;
|
1662 |
-
case 'pdfOptimized':
|
1663 |
Â
case 'imgOptimized':
|
1664 |
Â
$excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
|
1665 |
Â
$successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt'], $data['excludeSizes']);
|
@@ -1680,15 +1694,14 @@ class ShortPixelView {
|
|
1680 |
Â
$missingThumbs .= '</span>';
|
1681 |
Â
}
|
1682 |
Â
$successText .= ($data['webpCount'] ? "<br>+" . $data['webpCount'] . __(" WebP images", 'shortpixel-image-optimiser') : "")
|
1683 |
-
. "<br>EXIF: " . ($data['exifKept'] ? __('kept','shortpixel-image-optimiser') : __('removed','shortpixel-image-optimiser'))
|
1684 |
Â
. ($data['png2jpg'] ? '<br>' . __('Converted from PNG','shortpixel-image-optimiser'): '')
|
1685 |
Â
. "<br>" . __("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date']
|
1686 |
Â
. $excludeSizes . $missingThumbs;
|
1687 |
Â
}
|
1688 |
-
|
1689 |
Â
$this->renderListCell($id, $data['status'], $data['showActions'], $data['thumbsToOptimize'],
|
1690 |
Â
$data['backup'], $data['type'], $data['invType'], $successText);
|
1691 |
-
|
1692 |
Â
break;
|
1693 |
Â
}
|
1694 |
Â
//if($extended) {
|
@@ -1696,22 +1709,22 @@ class ShortPixelView {
|
|
1696 |
Â
//}
|
1697 |
Â
?>
|
1698 |
Â
</div>
|
1699 |
-
<?php
|
1700 |
Â
}
|
1701 |
-
|
1702 |
Â
public function getSuccessText($percent, $bonus, $type, $thumbsOpt = 0, $thumbsTotal = 0, $retinasOpt = 0, $excluded = 0) {
|
1703 |
Â
if($percent == 999) return __("Reduced by X%(unknown)");
|
1704 |
Â
return ($percent && $percent > 0 ? __('Reduced by','shortpixel-image-optimiser') . ' <strong>' . $percent . '%</strong> ' : '')
|
1705 |
Â
.(!$bonus ? ' ('.$type.')':'')
|
1706 |
-
.($bonus && $percent ? '<br>' : '')
|
1707 |
-
.($bonus ? __('Bonus processing','shortpixel-image-optimiser') : '')
|
1708 |
Â
.($bonus ? ' ('.$type.')':'') . '<br>'
|
1709 |
-
.($thumbsOpt ? ( $thumbsTotal > $thumbsOpt
|
1710 |
-
? sprintf(__('+%s of %s thumbnails optimized','shortpixel-image-optimiser'),$thumbsOpt,$thumbsTotal)
|
1711 |
Â
: sprintf(__('+%s thumbnails optimized','shortpixel-image-optimiser'),$thumbsOpt)) : '')
|
1712 |
Â
.($retinasOpt ? '<br>' . sprintf(__('+%s Retina images optimized','shortpixel-image-optimiser') , $retinasOpt) : '' );
|
1713 |
Â
}
|
1714 |
-
|
1715 |
Â
public function renderListCell($id, $status, $showActions, $thumbsRemain, $backup, $type, $invType, $message, $extraClass = '') {
|
1716 |
Â
if($showActions && ($backup || $thumbsRemain)) { ?>
|
1717 |
Â
<div class='sp-column-actions <?php echo($extraClass);?>'>
|
@@ -1727,13 +1740,13 @@ class ShortPixelView {
|
|
1727 |
Â
</a>
|
1728 |
Â
<?php }
|
1729 |
Â
if($backup) {
|
1730 |
-
if($type) {
|
1731 |
Â
//$invType = $type == 'lossy' ? 'lossless' : 'lossy'; ?>
|
1732 |
-
<a class="sp-action-reoptimize1" href="javascript:reoptimize('<?php echo($id)?>', '<?php echo($invType[0])?>');"
|
1733 |
Â
title="<?php _e('Reoptimize from the backed-up image','shortpixel-image-optimiser');?>">
|
1734 |
Â
<?php _e('Re-optimize','shortpixel-image-optimiser');?> <?php echo($invType[0])?>
|
1735 |
Â
</a>
|
1736 |
-
<a class="sp-action-reoptimize2" href="javascript:reoptimize('<?php echo($id)?>', '<?php echo($invType[1])?>');"
|
1737 |
Â
title="<?php _e('Reoptimize from the backed-up image','shortpixel-image-optimiser');?>">
|
1738 |
Â
<?php _e('Re-optimize','shortpixel-image-optimiser');?> <?php echo($invType[1])?>
|
1739 |
Â
</a><?php
|
@@ -1744,26 +1757,26 @@ class ShortPixelView {
|
|
1744 |
Â
<?php } ?>
|
1745 |
Â
</div>
|
1746 |
Â
</div>
|
1747 |
-
</div>
|
1748 |
-
<?php } ?>
|
1749 |
Â
<div class='sp-column-info'>
|
1750 |
Â
<?php echo($message);?>
|
1751 |
Â
</div> <?php
|
1752 |
Â
}
|
1753 |
-
|
1754 |
Â
public function getQuotaExceededHTML($message = '') {
|
1755 |
-
return "<div class='sp-column-actions' style='width:110px;'>
|
1756 |
Â
<a class='button button-smaller button-primary' href='https://shortpixel.com/login/". (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) . "' target='_blank'>"
|
1757 |
-
. __('Extend Quota','shortpixel-image-optimiser') .
|
1758 |
Â
"</a>
|
1759 |
-
<a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"
|
1760 |
Â
. __('Check Quota','shortpixel-image-optimiser') .
|
1761 |
Â
"</a></div>
|
1762 |
Â
<div class='sp-column-info'>" . $message . " " . __('Quota Exceeded','shortpixel-image-optimiser') . "</div>";
|
1763 |
Â
}
|
1764 |
-
|
1765 |
Â
public function outputComparerHTML() {?>
|
1766 |
-
<div class="sp-modal-shade">
|
1767 |
Â
<div id="spUploadCompare" class="shortpixel-modal shortpixel-hide">
|
1768 |
Â
<div class="sp-modal-title">
|
1769 |
Â
<button type="button" class="sp-close-button">×</button>
|
@@ -1796,7 +1809,7 @@ class ShortPixelView {
|
|
1796 |
Â
</div>
|
1797 |
Â
</div>
|
1798 |
Â
</div>
|
1799 |
-
|
1800 |
Â
<?php
|
1801 |
Â
}
|
1802 |
Â
}
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
class ShortPixelView {
|
4 |
+
|
5 |
Â
private $ctrl;
|
6 |
+
|
7 |
Â
public function __construct($controller) {
|
8 |
Â
$this->ctrl = $controller;
|
9 |
Â
}
|
10 |
+
|
11 |
Â
//handling older
|
12 |
Â
public function ShortPixelView($controller) {
|
13 |
Â
$this->__construct($controller);
|
14 |
Â
}
|
15 |
Â
|
16 |
+
public function displayQuotaExceededAlert($quotaData, $averageCompression = false, $recheck = false)
|
17 |
+
{ ?>
|
18 |
Â
<br/>
|
19 |
Â
<div class="wrap sp-quota-exceeded-alert" id="short-pixel-notice-exceed">
|
20 |
Â
<?php if($averageCompression) { ?>
|
30 |
Â
</div>
|
31 |
Â
</div>
|
32 |
Â
<?php } ?>
|
33 |
+
<img src="<?php echo(plugins_url('/shortpixel-image-optimiser/res/img/robo-scared.png'));?>"
|
34 |
Â
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/robo-scared.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/robo-scared@2x.png' ));?> 2x'
|
35 |
Â
class='short-pixel-notice-icon'>
|
36 |
Â
<h3><?php /* translators: header of the alert box */ _e('Quota Exceeded','shortpixel-image-optimiser');?></h3>
|
37 |
+
<p><?php /* translators: body of the alert box */
|
38 |
Â
if($recheck) {
|
39 |
Â
echo('<span style="color: red">' . __('You have no available image credits. If you just bought a package, please note that sometimes it takes a few minutes for the payment confirmation to be sent to us by the payment processor.','shortpixel-image-optimiser') . '</span><br>');
|
40 |
Â
}
|
41 |
+
printf(__('The plugin has optimized <strong>%s images</strong> and stopped because it reached the available quota limit.','shortpixel-image-optimiser'),
|
42 |
+
number_format(max(0, $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric'])));?>
|
43 |
Â
<?php if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) { ?>
|
44 |
+
<?php
|
45 |
Â
printf(__('<strong>%s images and %s thumbnails</strong> are not yet optimized by ShortPixel.','shortpixel-image-optimiser'),
|
46 |
+
number_format(max(0, $quotaData['mainFiles'] - $quotaData['mainProcessedFiles'])),
|
47 |
Â
number_format(max(0, ($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles'])))); ?>
|
48 |
Â
<?php } ?></p>
|
49 |
Â
<div> <!-- style='float:right;margin-top:20px;'> -->
|
50 |
Â
<button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-right:10px;"><strong>
|
51 |
Â
<?php _e('Show me the best available options', 'shortpixel_image_optimiser'); ?></strong></button>
|
52 |
+
<a class='button button-primary' href='https://shortpixel.com/login/<?php echo($this->ctrl->getApiKey());?>'
|
53 |
Â
title='<?php _e('Go to my account and select a plan','shortpixel-image-optimiser');?>' target='_blank' style="margin-right:10px;">
|
54 |
Â
<strong><?php _e('Upgrade','shortpixel-image-optimiser');?></strong>
|
55 |
Â
</a>
|
56 |
Â
<input type='button' name='checkQuota' class='button' value='<?php _e('Confirm New Credits','shortpixel-image-optimiser');?>'
|
57 |
Â
onclick="ShortPixel.recheckQuota()">
|
58 |
Â
</div>
|
59 |
+
<p><?php _e('Get more image credits by referring ShortPixel to your friends!','shortpixel-image-optimiser');?>
|
60 |
Â
<a href="https://shortpixel.com/login/<?php echo(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey());?>/tell-a-friend" target="_blank">
|
61 |
Â
<?php _e('Check your account','shortpixel-image-optimiser');?>
|
62 |
Â
</a> <?php _e('for your unique referral link. For each user that joins, you will receive +100 additional image credits/month.','shortpixel-image-optimiser');?>
|
63 |
Â
</p>
|
64 |
+
|
65 |
Â
</div> <?php self::includeProposeUpgradePopup();
|
66 |
Â
}
|
67 |
+
|
68 |
+
public static function displayApiKeyAlert()
|
69 |
Â
{ ?>
|
70 |
Â
<p><?php _e('In order to start the optimization process, you need to validate your API Key in the '
|
71 |
Â
. '<a href="options-general.php?page=wp-shortpixel">ShortPixel Settings</a> page in your WordPress Admin.','shortpixel-image-optimiser');?>
|
75 |
Â
</p>
|
76 |
Â
<?php
|
77 |
Â
}
|
78 |
+
|
79 |
Â
public static function displayActivationNotice($when = 'activate', $extra = '') {
|
80 |
Â
$extraStyle = ($when == 'compat' || $when == 'fileperms' ? "background-color: #ff9999;margin: 5px 20px 15px 0;'" : '');
|
81 |
Â
$icon = false;
|
84 |
Â
case 'compat': $extraClass = 'notice-error below-h2';
|
85 |
Â
case 'fileperms': $icon = 'scared'; $extraClass = 'notice-error'; break;
|
86 |
Â
case 'unlisted': $icon = 'magnifier'; break;
|
87 |
+
case 'upgmonth':
|
88 |
Â
case 'upgbulk': $icon = 'notes'; $extraClass = 'notice-success'; break;
|
89 |
Â
case 'spai':
|
90 |
Â
case 'generic-err': $extraClass = 'notice-error is-dismissible'; break;
|
94 |
Â
<div class='notice <?php echo($extraClass);?> notice-warning' id='short-pixel-notice-<?php echo($when);?>' <?php echo($extraStyle);?>>
|
95 |
Â
<?php if($when != 'activate') { ?>
|
96 |
Â
<div style="float:right;">
|
97 |
+
<?php if($when == 'upgmonth' || $when == 'upgbulk'){ ?>
|
98 |
Â
<button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-top:10px;margin-left:10px;"><strong>
|
99 |
Â
<?php _e('Show me the best available options', 'shortpixel_image_optimiser'); ?></strong></button>
|
100 |
Â
<?php } ?>
|
101 |
+
<?php if($when == 'unlisted'){ ?>
|
102 |
Â
<a href="javascript:ShortPixel.includeUnlisted()" class="button button-primary" style="margin-top:10px;margin-left:10px;">
|
103 |
Â
<strong><?php _e('Yes, include these thumbnails','shortpixel-image-optimiser');?></strong></a>
|
104 |
Â
<?php }
|
125 |
Â
if($when == 'upgmonth' || $when == 'upgbulk') { echo(' '); _e('advice','shortpixel-image-optimiser');}
|
126 |
Â
?></h3> <?php
|
127 |
Â
switch($when) {
|
128 |
+
case '2h' :
|
129 |
Â
_e("Action needed. Please <a href='https://shortpixel.com/wp-apikey' target='_blank'>get your API key</a> to activate your ShortPixel plugin.",'shortpixel-image-optimiser') . "<BR><BR>";
|
130 |
Â
break;
|
131 |
Â
case '3d':
|
157 |
Â
case 'upgbulk' : ?>
|
158 |
Â
<p> <?php
|
159 |
Â
if($when == 'upgmonth') {
|
160 |
+
printf(__("You are adding an average of <strong>%d images and thumbnails every month</strong> to your Media Library and you have <strong>a plan of %d images/month</strong>."
|
161 |
Â
. " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel_image_optimiser'), $extra['monthAvg'], $extra['monthlyQuota']);
|
162 |
Â
} else {
|
163 |
Â
printf(__("You currently have <strong>%d images and thumbnails to optimize</strong> but you only have <strong>%d images</strong> available in your current plan."
|
164 |
Â
. " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel_image_optimiser'), $extra['filesTodo'], $extra['quotaAvailable']);
|
165 |
+
}?></p><?php
|
166 |
Â
self::includeProposeUpgradePopup();
|
167 |
Â
break;
|
168 |
Â
case 'unlisted' :
|
169 |
Â
_e("<p>ShortPixel found thumbnails which are not registered in the metadata but present alongside the other thumbnails. These thumbnails could be created and needed by some plugin or by the theme. Let ShortPixel optimize them as well?</p>", 'shortpixel-image-optimiser');?>
|
170 |
Â
<p>
|
171 |
+
<?php _e("For example, the image", 'shortpixel-image-optimiser');?>
|
172 |
Â
<a href='post.php?post=<?php echo($extra->id);?>&action=edit' target='_blank'>
|
173 |
Â
<?php echo($extra->name); ?>
|
174 |
Â
</a> has also these thumbs not listed in metadata:
|
185 |
Â
</div>
|
186 |
Â
<?php
|
187 |
Â
}
|
188 |
+
protected static function includeProposeUpgradePopup() {
|
189 |
+
wp_enqueue_style('short-pixel-modal.min.css', plugins_url('/res/css/short-pixel-modal.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
190 |
+
?>
|
191 |
+
|
192 |
Â
<div id="shortPixelProposeUpgradeShade" class="sp-modal-shade" style="display:none;">
|
193 |
+
<div id="shortPixelProposeUpgrade" class="shortpixel-modal shortpixel-hide" style="min-width:610px;margin-left:-305px;">
|
194 |
Â
<div class="sp-modal-title">
|
195 |
Â
<button type="button" class="sp-close-upgrade-button" onclick="ShortPixel.closeProposeUpgrade()">×</button>
|
196 |
Â
<?php _e('Upgrade your ShortPixel account', 'shortpixel-image-optimiser');?>
|
198 |
Â
<div class="sp-modal-body sptw-modal-spinner" style="height:auto;min-height:400px;padding:0;">
|
199 |
Â
</div>
|
200 |
Â
</div>
|
201 |
+
</div>
|
202 |
Â
<?php }
|
203 |
+
|
204 |
+
public function displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount, $bulkRan,
|
205 |
Â
$averageCompression, $filesOptimized, $savedSpace, $percent, $customCount) {
|
206 |
Â
$settings = $this->ctrl->getSettings();
|
207 |
Â
$this->ctrl->outputHSBeacon();
|
222 |
Â
<div class="bulk-label"><?php _e('Smaller thumbnails','shortpixel-image-optimiser');?></div>
|
223 |
Â
<div class="bulk-val"><?php echo(number_format($quotaData['totalMlFiles'] - $quotaData['mainMlFiles']));?></div>
|
224 |
Â
<div style='width:165px; display:inline-block; padding-left: 5px'>
|
225 |
+
<input type='checkbox' id='thumbnails' name='thumbnails' onclick='ShortPixel.checkThumbsUpdTotal(this)' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>>
|
226 |
Â
<?php _e('Include thumbnails','shortpixel-image-optimiser');?>
|
227 |
Â
</div><br>
|
228 |
Â
<?php if($quotaData["totalProcessedMlFiles"] > 0) { ?>
|
245 |
Â
<?php _e('Total to be optimized','shortpixel-image-optimiser');?>
|
246 |
Â
<div class="reset"><?php _e('(Originals and thumbnails)','shortpixel-image-optimiser');?></div>
|
247 |
Â
</div>
|
248 |
+
<div class="bulk-val bulk-total" id='displayTotal'><?php echo(number_format($customCount));?></div>
|
249 |
Â
<?php } ?>
|
250 |
Â
</div>
|
251 |
Â
<?php if(max(0, $quotaData['totalMlFiles'] - $quotaData['totalProcessedMlFiles']) + $customCount > 0) { ?>
|
277 |
Â
<input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup', event)" style="width:100%">
|
278 |
Â
<input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)" style="display:none">
|
279 |
Â
</div>
|
280 |
+
|
281 |
Â
<?php }
|
282 |
Â
} else {?>
|
283 |
Â
<div class="bulk-play bulk-nothing-optimize">
|
317 |
Â
<?php if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) { ?>
|
318 |
Â
<p><?php printf(__('%s images and %s thumbnails are not yet optimized by ShortPixel.','shortpixel-image-optimiser'),
|
319 |
Â
number_format($quotaData['mainFiles'] - $quotaData['mainProcessedFiles']),
|
320 |
+
number_format(($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles'])));?>
|
321 |
Â
</p>
|
322 |
Â
<?php } ?>
|
323 |
Â
<p><?php _e('You can continue optimizing your Media Gallery from where you left, by clicking the Resume processing button. Already optimized images will not be reprocessed.','shortpixel-image-optimiser');?></p>
|
358 |
Â
<div class="fb-like" data-href="https://www.facebook.com/ShortPixel" data-width="260" data-layout="button_count" data-action="like" data-show-faces="true" data-share="true"></div>
|
359 |
Â
</div>
|
360 |
Â
<div style="float:left;margin:-7px 0 0 10px">
|
361 |
+
<a href="https://twitter.com/share" class="twitter-share-button" data-url="https://shortpixel.com"
|
362 |
+
data-text="<?php
|
363 |
Â
if(0+$averageCompression>20) {
|
364 |
Â
_e("I just #optimized my site's images by ",'shortpixel-image-optimiser');
|
365 |
Â
} else {
|
366 |
Â
_e("I just #optimized my site's images ",'shortpixel-image-optimiser');
|
367 |
Â
}
|
368 |
Â
echo(round($averageCompression) ."%");
|
369 |
+
echo(__("with @ShortPixel, a #WordPress image optimization plugin",'shortpixel-image-optimiser') . " #pagespeed #seo");?>"
|
370 |
Â
data-size='large'><?php _e('Tweet','shortpixel-image-optimiser');?></a>
|
371 |
Â
</div>
|
372 |
Â
<script>
|
389 |
Â
</script>
|
390 |
Â
</div>
|
391 |
Â
</div>
|
392 |
+
<?php if(0+$averageCompression>30) {?>
|
393 |
Â
<div class='shortpixel-rate-us' style='float:left;padding-top:0'>
|
394 |
Â
<a href="https://wordpress.org/support/view/plugin-reviews/shortpixel-image-optimiser?rate=5#postform" target="_blank">
|
395 |
Â
<span>
|
401 |
Â
</div>
|
402 |
Â
<div id="sp-bulk-stats" style="display:none">
|
403 |
Â
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
404 |
+
</div>
|
405 |
Â
</div>
|
406 |
Â
<p><?php printf(__('Go to the ShortPixel <a href="%soptions-general.php?page=wp-shortpixel#stats">Stats</a>
|
407 |
Â
and see all your websites\' optimized stats. Download your detailed <a href="https://%s/v2/report.php?key=%s">Optimization Report</a>
|
408 |
Â
to check your image optimization statistics for the last 40 days.','shortpixel-image-optimiser'),
|
409 |
Â
get_admin_url(), SHORTPIXEL_API, (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) );?></p>
|
410 |
+
<?php
|
411 |
Â
$failed = $this->ctrl->getPrioQ()->getFailed();
|
412 |
Â
if(count($failed)) { ?>
|
413 |
Â
<div class="bulk-progress sp-notice sp-notice-warning sp-floating-block sp-double-width" style="margin-bottom: 15px">
|
420 |
Â
<div class="bulk-progress sp-notice sp-notice-info sp-floating-block sp-double-width">
|
421 |
Â
<?php
|
422 |
Â
$todo = $reopt = false;
|
423 |
+
if($quotaData['totalProcessedFiles'] < $quotaData['totalFiles']) {
|
424 |
Â
$todo = true;
|
425 |
Â
$mainNotProcessed = max(0, $quotaData['mainFiles'] - $quotaData['mainProcessedFiles']);
|
426 |
Â
$thumbsNotProcessed = max(0, ($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']));
|
427 |
Â
?>
|
428 |
Â
<p>
|
429 |
+
<?php
|
430 |
Â
if($mainNotProcessed && $thumbsNotProcessed) {
|
431 |
+
printf(__("%s images and %s thumbnails are not yet optimized by ShortPixel.",'shortpixel-image-optimiser'),
|
432 |
+
number_format($mainNotProcessed), number_format($thumbsNotProcessed));
|
433 |
Â
} elseif($mainNotProcessed) {
|
434 |
+
printf(__("%s images are not yet optimized by ShortPixel.",'shortpixel-image-optimiser'), number_format($mainNotProcessed));
|
435 |
Â
} elseif($thumbsNotProcessed) {
|
436 |
+
printf(__("%s thumbnails are not yet optimized by ShortPixel.",'shortpixel-image-optimiser'), number_format($thumbsNotProcessed));
|
437 |
Â
}
|
438 |
Â
_e('','shortpixel-image-optimiser');
|
439 |
Â
if (count($quotaData['filesWithErrors'])) {
|
476 |
Â
$extraW = $extraO = '';
|
477 |
Â
if( !$this->ctrl->backupFolderIsEmpty()
|
478 |
Â
&& ( ($quotaData['totalProcLossyFiles'] > 0 && $settings->compressionType != 1)
|
479 |
+
|| ($quotaData['totalProcGlossyFiles'] > 0 && $settings->compressionType != 2)
|
480 |
Â
|| ($quotaData['totalProcLosslessFiles'] > 0 && $settings->compressionType != 0)))
|
481 |
+
{
|
482 |
Â
$todo = $reopt = true;
|
483 |
Â
$statType = ucfirst($otherTypes[0]);
|
484 |
Â
$thumbsCount = $quotaData['totalProc'.$statType.'Files'] - $quotaData['mainProc'.$statType.'Files'];
|
485 |
+
|
486 |
Â
$statType2 = ucfirst($otherTypes[1]);
|
487 |
Â
$thumbsCount2 = $quotaData['totalProc'.$statType2.'Files'] - $quotaData['mainProc'.$statType2.'Files'];
|
488 |
Â
if($quotaData['totalProc'.$statType2.'Files'] > 0 ) {
|
489 |
Â
if($quotaData['totalProc'.$statType.'Files'] > 0) {
|
490 |
+
$extraW = sprintf(__('%s images and %s thumbnails were optimized <strong>%s</strong>. ','shortpixel-image-optimiser'),
|
491 |
Â
number_format($quotaData['mainProc'.$statType2.'Files']),
|
492 |
Â
number_format($thumbsCount2), $otherTypes[1]);
|
493 |
+
$extraO = sprintf(__('%s images were optimized <strong>%s</strong>. ','shortpixel-image-optimiser'),
|
494 |
Â
number_format($quotaData['mainProc'.$statType2.'Files']), $otherTypes[1]);
|
495 |
Â
} else {
|
496 |
Â
$extraW = $extraO = ''; $otherTypes[0] = $otherTypes[1]; $statType = $statType2;
|
499 |
Â
?>
|
500 |
Â
<p id="with-thumbs" <?php echo(!$settings->processThumbnails ? 'style="display:none;"' : "");?>>
|
501 |
Â
<?php echo($extraW);
|
502 |
+
printf(__('%s images and %s thumbnails were optimized <strong>%s</strong>. You can re-optimize <strong>%s</strong> the ones that have backup.','shortpixel-image-optimiser'),
|
503 |
Â
number_format($quotaData['mainProc'.$statType.'Files']),
|
504 |
Â
number_format($thumbsCount), $otherTypes[0], $optType);?>
|
505 |
Â
</p>
|
506 |
Â
<p id="without-thumbs" <?php echo($settings->processThumbnails ? 'style="display:none;"' : "");?>>
|
507 |
+
<?php echo($extraO);
|
508 |
+
printf(__('%s images were optimized <strong>%s</strong>. You can re-optimize <strong>%s</strong> the ones that have backup. ','shortpixel-image-optimiser'),
|
509 |
Â
number_format($quotaData['mainProc'.$statType.'Files']),
|
510 |
Â
$otherTypes[0], $optType);?>
|
511 |
Â
<?php echo($thumbsCount + $thumbsCount2 ? number_format($thumbsCount + $thumbsCount2) . __(' thumbnails will be restored to originals.','shortpixel-image-optimiser') : '');?>
|
520 |
Â
echo(' ');
|
521 |
Â
printf(__('Already <strong>%s</strong> optimized images will not be reprocessed.','shortpixel-image-optimiser'), $todo ? ($optType) : '');
|
522 |
Â
if($reopt) { ?>
|
523 |
+
<br><?php _e('Please note that reoptimizing images as <strong>lossy/lossless</strong> may use additional credits.','shortpixel-image-optimiser')?>
|
524 |
Â
<a href="http://blog.shortpixel.com/the-all-new-re-optimization-functions-in-shortpixel/" target="_blank" class="shortpixel-help-link">
|
525 |
Â
<span class="dashicons dashicons-editor-help"></span><?php _e('More info','shortpixel-image-optimiser');?>
|
526 |
Â
</a>
|
527 |
Â
<?php } ?>
|
528 |
Â
</p>
|
529 |
Â
<form action='' method='POST' >
|
530 |
+
<input type='checkbox' id='bulk-thumbnails' name='thumbnails' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>
|
531 |
Â
onchange="ShortPixel.onBulkThumbsCheck(this)"> <?php _e('Include thumbnails','shortpixel-image-optimiser');?><br><br>
|
532 |
+
|
533 |
+
<a style="float: right;margin: 0 10px; line-height: 28px" href='<?php echo add_query_arg('part','bulk-restore-all'); ?> '><?php _e('Bulk Restore Images','shortpixel-image-optimiser'); ?></a>
|
534 |
+
|
535 |
Â
<input type='submit' name='bulkProcess' id='bulkProcess' class='button button-primary' value='<?php _e('Restart Optimizing','shortpixel-image-optimiser');?>'
|
536 |
Â
<?php echo($settings->quotaExceeded? "disabled title=\"" . __("Top-up your account to optimize more images.",'shortpixel-image-optimiser')."\"" : ""); ?>>
|
537 |
+
<!-- <input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore',event)" style="float: right;"> -->
|
538 |
+
|
539 |
+
|
540 |
Â
<input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup',event)" style="float: right;margin-right:10px;">
|
541 |
Â
<input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)" style="display:none">
|
542 |
Â
</form>
|
615 |
Â
</div>
|
616 |
Â
<?php
|
617 |
Â
}
|
618 |
+
|
619 |
Â
public function displayBulkProgressBar($running, $percent, $message, $remainingQuota, $averageCompression, $type = 1, $customPending = false) {
|
620 |
Â
$percentBefore = $percentAfter = '';
|
621 |
Â
if($percent > 24) {
|
643 |
Â
</script>
|
644 |
Â
</div>
|
645 |
Â
</div>
|
646 |
+
<?php if($running) {
|
647 |
Â
if($type > 0) { ?>
|
648 |
+
<div class="sp-h2"><?php
|
649 |
Â
echo($type & 1 ? __('Media Library','shortpixel-image-optimiser') . " " : "");
|
650 |
Â
echo($type & 3 == 3 ? __('and','shortpixel-image-optimiser') . " " : "");
|
651 |
+
echo($type & 2 ? __('Custom folders','shortpixel-image-optimiser') . " " : "");
|
652 |
Â
_e('optimization in progress ...','shortpixel-image-optimiser');?></div>
|
653 |
Â
<p style="margin: 0 0 18px;"><?php _e('Bulk optimization has started.','shortpixel-image-optimiser');?><br>
|
654 |
+
<?php
|
655 |
Â
} elseif($type == 0) { // restore ?>
|
656 |
+
<div class="sp-h2"><?php
|
657 |
Â
_e('Media Library restore in progress ...','shortpixel-image-optimiser');?></div>
|
658 |
+
<p style="margin: 0 0 18px;"><?php _e('Bulk restore has started.','shortpixel-image-optimiser');?><br>
|
659 |
Â
<?php }
|
660 |
Â
elseif($type == -1) { // cleanup ?>
|
661 |
+
<div class="sp-h2"><?php
|
662 |
Â
_e('Media Library cleanup in progress ...','shortpixel-image-optimiser');?></div>
|
663 |
+
<p style="margin: 0 0 18px;"><?php _e('Bulk cleanup has started.','shortpixel-image-optimiser');?><br>
|
664 |
Â
<?php }
|
665 |
+
printf(__('This process will take some time, depending on the number of images in your library. In the meantime, you can continue using
|
666 |
Â
the admin as usual, <a href="%s" target="_blank">in a different browser window or tab</a>.<br>
|
667 |
Â
However, <strong>if you close this window, the bulk processing will pause</strong> until you open the media gallery or the ShortPixel bulk page again.','shortpixel-image-optimiser'), get_admin_url());?>
|
668 |
Â
</p>
|
699 |
Â
</div>
|
700 |
Â
<?php
|
701 |
Â
}
|
702 |
+
|
703 |
Â
public function displayBulkStats($totalOptimized, $mainOptimized, $under5PercentCount, $averageCompression, $savedSpace) {?>
|
704 |
Â
<div class="bulk-progress bulk-stats">
|
705 |
Â
<div class="label"><?php _e('Processed Images and PDFs:','shortpixel-image-optimiser');?></div><div class="stat-value"><?php echo(number_format($mainOptimized));?></div><br>
|
713 |
Â
</div>
|
714 |
Â
<?php
|
715 |
Â
}
|
716 |
+
|
717 |
Â
public function displayFailed($failed) {
|
718 |
Â
?>
|
719 |
Â
<div class="bulk-progress bulk-stats" style="padding-top:5px;">
|
720 |
+
<?php foreach($failed as $fail) {
|
721 |
Â
if($fail->type == ShortPixelMetaFacade::CUSTOM_TYPE) {
|
722 |
Â
$meta = $fail->meta;
|
723 |
Â
?> <div><a href="<?php echo(ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath());?>"><?php echo(substr($meta->getName(), 0, 80));?> - ID: C-<?php echo($fail->id);?></a></div><br/>
|
730 |
Â
<?php
|
731 |
Â
}
|
732 |
Â
function displaySettings($showApiKey, $editApiKey, $quotaData, $notice, $resources = null, $averageCompression = null, $savedSpace = null, $savedBandwidth = null,
|
733 |
+
$remainingImages = null, $totalCallsMade = null, $fileCount = null, $backupFolderSize = null,
|
734 |
Â
$customFolders = null, $folderMsg = false, $addedFolder = false, $showAdvanced = false, $cloudflareAPI = false, $htaccessWriteable = false, $isNginx = false ) {
|
735 |
Â
//wp_enqueue_script('jquery.idTabs.js', plugins_url('/js/jquery.idTabs.js',__FILE__) );
|
736 |
Â
$this->ctrl->outputHSBeacon();
|
738 |
Â
<div class="wrap">
|
739 |
Â
<h1><?php _e('ShortPixel Plugin Settings','shortpixel-image-optimiser');?></h1>
|
740 |
Â
<p style="font-size:18px">
|
741 |
+
<a href="https://shortpixel.com/<?php
|
742 |
Â
echo(($this->ctrl->getVerifiedKey() ? "login/".(defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) : "pricing") . WPShortPixel::getAffiliateSufix());
|
743 |
Â
?>" target="_blank" style="font-size:18px">
|
744 |
Â
<?php _e('Upgrade now','shortpixel-image-optimiser');?>
|
774 |
Â
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-settings"><?php _e('General','shortpixel-image-optimiser');?></a></h2>
|
775 |
Â
<?php }
|
776 |
Â
$this->displaySettingsForm($showApiKey, $editApiKey, $quotaData);?>
|
777 |
+
</section>
|
778 |
Â
<?php if($this->ctrl->getVerifiedKey()) {?>
|
779 |
Â
<section <?php echo($showAdvanced ? "class='sel-tab'" : "");?> id="tab-adv-settings" class="clearfix">
|
780 |
Â
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-adv-settings"><?php _e('Advanced','shortpixel-image-optimiser');?></a></h2>
|
796 |
Â
<section id="tab-stats">
|
797 |
Â
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-stats"><?php _e('Statistics','shortpixel-image-optimiser');?></a></h2>
|
798 |
Â
<?php
|
799 |
+
$this->displaySettingsStats($quotaData, $averageCompression, $savedSpace, $savedBandwidth,
|
800 |
Â
$remainingImages, $totalCallsMade, $fileCount, $backupFolderSize);?>
|
801 |
+
</section>
|
802 |
Â
<?php }
|
803 |
Â
if( $resources !== null && $quotaData['APICallsQuotaOneTimeNumeric']<10000 && $quotaData['APICallsQuotaNumeric']<5000 ) {?>
|
804 |
Â
<section id="tab-resources">
|
814 |
Â
</script>
|
815 |
Â
</div>
|
816 |
Â
<?php
|
817 |
+
}
|
818 |
+
|
819 |
Â
public function displaySettingsForm($showApiKey, $editApiKey, $quotaData) {
|
820 |
Â
$settings = $this->ctrl->getSettings();
|
821 |
Â
$checked = ($this->ctrl->processThumbnails() ? 'checked' : '');
|
822 |
Â
$checkedBackupImages = ($this->ctrl->backupImages() ? 'checked' : '');
|
823 |
Â
$removeExif = ($settings->keepExif ? '' : 'checked');
|
824 |
Â
$resize = ($this->ctrl->getResizeImages() ? 'checked' : '');
|
825 |
+
$resizeDisabled = ($this->ctrl->getResizeImages() ? '' : 'disabled');
|
826 |
Â
$minSizes = $this->ctrl->getMaxIntermediateImageSize();
|
827 |
Â
$thumbnailsToProcess = isset($quotaData['totalFiles']) ? ($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']) : 0;
|
828 |
Â
$adminEmail = get_bloginfo('admin_email');
|
831 |
Â
<div class="wp-shortpixel-options wp-shortpixel-tab-content">
|
832 |
Â
<?php if($this->ctrl->getVerifiedKey()) { ?>
|
833 |
Â
<p><?php printf(__('New images uploaded to the Media Library will be optimized automatically.<br/>If you have existing images you would like to optimize, you can use the <a href="%supload.php?page=wp-short-pixel-bulk">Bulk Optimization Tool</a>.','shortpixel-image-optimiser'),get_admin_url());?></p>
|
834 |
+
<?php } else {
|
835 |
Â
if($showApiKey) {?>
|
836 |
Â
<h3><?php _e('Request an API Key:','shortpixel-image-optimiser');?></h3>
|
837 |
Â
<p style='font-size: 14px'><?php _e('If you don\'t have an API Key, you can request one for free. Just press the "Request Key" button after checking that the e-mail is correct.','shortpixel-image-optimiser');?></p>
|
876 |
Â
<p style='font-size: 14px'>
|
877 |
Â
<?php _e('If you already have an API Key please input it below and press Validate.','shortpixel-image-optimiser');?>
|
878 |
Â
</p>
|
879 |
+
<?php }
|
880 |
Â
}?>
|
881 |
Â
<table class="form-table">
|
882 |
Â
<tbody>
|
883 |
Â
<tr>
|
884 |
Â
<th scope="row"><label for="key"><?php _e('API Key:','shortpixel-image-optimiser');?></label></th>
|
885 |
Â
<td>
|
886 |
+
<?php
|
887 |
Â
$canValidate = false;
|
888 |
Â
if($showApiKey) {
|
889 |
Â
$canValidate = true;?>
|
890 |
+
<input name="key" type="text" id="key" value="<?php echo( $this->ctrl->getApiKey() );?>"
|
891 |
Â
class="regular-text" <?php echo($editApiKey ? "" : 'disabled') ?> <?php echo $this->ctrl->getVerifiedKey() ? 'onkeyup="ShortPixel.apiKeyChanged()"' : '' ?>>
|
892 |
+
<?php } elseif(defined("SHORTPIXEL_API_KEY")) {
|
893 |
Â
$canValidate = true;?>
|
894 |
+
<input name="key" type="text" id="key" disabled="true" placeholder="<?php
|
895 |
Â
if(defined("SHORTPIXEL_HIDE_API_KEY")) {
|
896 |
+
echo("********************");
|
897 |
Â
} else {
|
898 |
Â
_e('Multisite API Key','shortpixel-image-optimiser');
|
899 |
Â
}
|
911 |
Â
<?php if($showApiKey && !$editApiKey) { ?>
|
912 |
Â
<p class="settings-info"><?php _e('Key defined in wp-config.php.','shortpixel-image-optimiser');?></p>
|
913 |
Â
<?php } ?>
|
914 |
+
|
915 |
Â
</td>
|
916 |
Â
</tr>
|
917 |
Â
<?php if (!$this->ctrl->getVerifiedKey()) { //if invalid key we display the link to the API Key ?>
|
984 |
Â
<td>
|
985 |
Â
<input name="removeExif" type="checkbox" id="removeExif" <?php echo( $removeExif );?>>
|
986 |
Â
<label for="removeExif"><?php _e('Remove the EXIF tag of the image (recommended).','shortpixel-image-optimiser');?></label>
|
987 |
+
<p class="settings-info"> <?php _e('EXIF is a set of various pieces of information that are automatically embedded into the image upon creation. This can include GPS position, camera manufacturer, date and time, etc.
|
988 |
Â
Unless you really need that data to be preserved, we recommend removing it as it can lead to <a href="http://blog.shortpixel.com/how-much-smaller-can-be-images-without-exif-icc" target="_blank">better compression rates</a>.','shortpixel-image-optimiser');?></p>
|
989 |
Â
</td>
|
990 |
Â
</tr>
|
994 |
Â
<input name="resize" type="checkbox" id="resize" <?php echo( $resize );?>>
|
995 |
Â
<label for="resize"><?php _e('to maximum','shortpixel-image-optimiser');?></label>
|
996 |
Â
<input type="text" name="width" id="width" style="width:70px" class="resize-sizes"
|
997 |
+
value="<?php echo( $this->ctrl->getResizeWidth() > 0 ? $this->ctrl->getResizeWidth() : min(924, $minSizes['width']) );?>" <?php echo( $resizeDisabled );?>/> <?php
|
998 |
Â
_e('pixels wide ×','shortpixel-image-optimiser');?>
|
999 |
+
<input type="text" name="height" id="height" class="resize-sizes" style="width:70px"
|
1000 |
+
value="<?php echo( $this->ctrl->getResizeHeight() > 0 ? $this->ctrl->getResizeHeight() : min(924, $minSizes['height']) );?>" <?php echo( $resizeDisabled );?>/> <?php
|
1001 |
Â
_e('pixels high (original aspect ratio is preserved and image is not cropped)','shortpixel-image-optimiser');?>
|
1002 |
Â
<input type="hidden" id="min-width" value="<?php echo($minSizes['width']);?>"/>
|
1003 |
Â
<input type="hidden" id="min-height" value="<?php echo($minSizes['height']);?>"/>
|
1004 |
+
<p class="settings-info">
|
1005 |
Â
<?php _e('Recommended for large photos, like the ones taken with your phone. Saved space can go up to 80% or more after resizing.','shortpixel-image-optimiser');?>
|
1006 |
Â
<a href="https://blog.shortpixel.com/resize-images/" class="shortpixel-help-link" target="_blank">
|
1007 |
Â
<span class="dashicons dashicons-editor-help"></span><?php _e('Read more','shortpixel-image-optimiser');?>
|
1009 |
Â
</p>
|
1010 |
Â
<div style="margin-top: 10px;">
|
1011 |
Â
<input type="radio" name="resize_type" id="resize_type_outer" value="outer" <?php echo($settings->resizeType == 'inner' ? '' : 'checked') ?> style="margin: -50px 10px 60px 0;">
|
1012 |
+
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-outer.png' ));?>"
|
1013 |
Â
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-outer.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-outer@2x.png' ));?> 2x'
|
1014 |
Â
title="<?php _e('Sizes will be greater or equal to the corresponding value. For example, if you set the resize dimensions at 1000x1200, an image of 2000x3000px will be resized to 1000x1500px while an image of 3000x2000px will be resized to 1800x1200px','shortpixel-image-optimiser');?>">
|
1015 |
Â
<input type="radio" name="resize_type" id="resize_type_inner" value="inner" <?php echo($settings->resizeType == 'inner' ? 'checked' : '') ?> style="margin: -50px 10px 60px 35px;">
|
1016 |
+
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?>"
|
1017 |
Â
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner@2x.png' ));?> 2x'
|
1018 |
Â
title="<?php _e('Sizes will be smaller or equal to the corresponding value. For example, if you set the resize dimensions at 1000x1200, an image of 2000x3000px will be resized to 800x1200px while an image of 3000x2000px will be resized to 1000x667px','shortpixel-image-optimiser');?>">
|
1019 |
Â
<div style="display:inline-block;margin-left: 20px;"><a href="https://blog.shortpixel.com/resize-images/" class="shortpixel-help-link" target="_blank">
|
1031 |
Â
</div>
|
1032 |
Â
<script>
|
1033 |
Â
jQuery(document).ready(function () {
|
1034 |
+
ShortPixel.setupGeneralTab(document.wp_shortpixel_options.compressionType,
|
1035 |
Â
Math.min(924, <?php echo($minSizes['width']);?>),
|
1036 |
Â
Math.min(924, <?php echo($minSizes['height']);?>));
|
1037 |
Â
});
|
1038 |
Â
</script>
|
1039 |
Â
<?php }
|
1040 |
Â
}
|
1041 |
+
|
1042 |
Â
public function displayAdvancedSettingsForm($customFolders = false, $addedFolder = false, $htaccessWriteable = false, $isNginx = false ) {
|
1043 |
Â
$settings = $this->ctrl->getSettings();
|
1044 |
Â
$minSizes = $this->ctrl->getMaxIntermediateImageSize();
|
1123 |
Â
<td></td>
|
1124 |
Â
</tr>
|
1125 |
Â
<?php foreach($customFolders as $folder) {
|
1126 |
+
$typ = $folder->getType();
|
1127 |
Â
$typ = $typ ? $typ . "<br>" : "";
|
1128 |
Â
$stat = $this->ctrl->getSpMetaDao()->getFolderOptimizationStatus($folder->getId());
|
1129 |
Â
$cnt = $folder->getFileCount();
|
1130 |
+
$st = ($cnt == 0
|
1131 |
Â
? __("Empty",'shortpixel-image-optimiser')
|
1132 |
+
: ($stat->Total == $stat->Optimized
|
1133 |
Â
? __("Optimized",'shortpixel-image-optimiser')
|
1134 |
Â
: ($stat->Optimized + $stat->Pending > 0 ? __("Pending",'shortpixel-image-optimiser') : __("Waiting",'shortpixel-image-optimiser'))));
|
1135 |
+
|
1136 |
Â
$err = $stat->Failed > 0 && !$st == __("Empty",'shortpixel-image-optimiser') ? " ({$stat->Failed} failed)" : "";
|
1137 |
+
|
1138 |
Â
$action = ($st == __("Optimized",'shortpixel-image-optimiser') || $st == __("Empty",'shortpixel-image-optimiser') ? __("Stop monitoring",'shortpixel-image-optimiser') : __("Stop optimizing",'shortpixel-image-optimiser'));
|
1139 |
+
|
1140 |
+
$fullStat = $st == __("Empty",'shortpixel-image-optimiser') ? "" : __("Optimized",'shortpixel-image-optimiser') . ": " . $stat->Optimized . ", "
|
1141 |
+
. __("Pending",'shortpixel-image-optimiser') . ": " . $stat->Pending . ", " . __("Waiting",'shortpixel-image-optimiser') . ": " . $stat->Waiting . ", "
|
1142 |
Â
. __("Failed",'shortpixel-image-optimiser') . ": " . $stat->Failed;
|
1143 |
Â
?>
|
1144 |
Â
<tr>
|
1160 |
Â
</td>
|
1161 |
Â
<td>
|
1162 |
Â
<input type="button" class="button remove-folder-button" data-value="<?php echo($folder->getPath()); ?>" title="<?php echo($action . " " . $folder->getPath()); ?>" value="<?php echo $action;?>">
|
1163 |
+
<input type="button" style="display:none;" class="button button-alert recheck-folder-button" data-value="<?php echo($folder->getPath()); ?>"
|
1164 |
+
title="<?php _e('Full folder refresh, check each file of the folder if it changed since it was optimized. Might take up to 1 min. for big folders.','shortpixel-image-optimiser');?>"
|
1165 |
Â
value="<?php _e('Refresh','shortpixel-image-optimiser');?>">
|
1166 |
Â
</td>
|
1167 |
Â
</tr>
|
1168 |
Â
<?php }?>
|
1169 |
Â
</table>
|
1170 |
Â
<?php } ?>
|
1171 |
+
|
1172 |
+
<div class='addCustomFolder'>
|
1173 |
+
|
1174 |
+
<input type="hidden" name="removeFolder" id="removeFolder"/>
|
1175 |
+
<input type="hidden" name="recheckFolder" id="removeFolder"/>
|
1176 |
+
<p class='add-folder-text'><strong><?php _e('Add a custom folder', 'shortpixel-image-optimiser'); ?></strong></p>
|
1177 |
+
<input type="text" name="addCustomFolderView" id="addCustomFolderView" class="regular-text" value="<?php echo($addedFolder);?>" disabled style="">
|
1178 |
+
<input type="hidden" name="addCustomFolder" id="addCustomFolder" value="<?php echo($addedFolder);?>"/>
|
1179 |
+
<input type="hidden" id="customFolderBase" value="<?php echo WPShortPixel::getCustomFolderBase(); ?>">
|
1180 |
+
|
1181 |
+
<a class="button select-folder-button" title="<?php _e('Select the images folder on your server.','shortpixel-image-optimiser');?>" href="javascript:void(0);">
|
1182 |
+
<?php _e('Select ...','shortpixel-image-optimiser');?>
|
1183 |
+
</a>
|
1184 |
+
<input type="submit" name="saveAdv" id="saveAdvAddFolder" class="button button-primary hidden" title="<?php _e('Add this Folder','shortpixel-image-optimiser');?>" value="<?php _e('Add this Folder','shortpixel-image-optimiser');?>">
|
1185 |
Â
<p class="settings-info">
|
1186 |
Â
<?php _e('Use the Select... button to select site folders. ShortPixel will optimize images and PDFs from the specified folders and their subfolders. The optimization status for each image or PDF in these folders can be seen in the <a href="upload.php?page=wp-short-pixel-custom">Other Media list</a>, under the Media menu.','shortpixel-image-optimiser');?>
|
1187 |
Â
<a href="https://blog.shortpixel.com/optimize-images-outside-media-library/" target="_blank" class="shortpixel-help-link">
|
1188 |
Â
<span class="dashicons dashicons-editor-help"></span><?php _e('More info','shortpixel-image-optimiser');?>
|
1189 |
Â
</a>
|
1190 |
Â
</p>
|
1191 |
+
|
1192 |
+
<div class="sp-modal-shade sp-folder-picker-shade"></div>
|
1193 |
+
<div class="shortpixel-modal modal-folder-picker shortpixel-hide">
|
1194 |
Â
<div class="sp-modal-title"><?php _e('Select the images folder','shortpixel-image-optimiser');?></div>
|
1195 |
Â
<div class="sp-folder-picker"></div>
|
1196 |
Â
<input type="button" class="button button-info select-folder-cancel" value="<?php _e('Cancel','shortpixel-image-optimiser');?>" style="margin-right: 30px;">
|
1197 |
Â
<input type="button" class="button button-primary select-folder" value="<?php _e('Select','shortpixel-image-optimiser');?>">
|
1198 |
Â
</div>
|
1199 |
+
|
1200 |
Â
<script>
|
1201 |
Â
jQuery(document).ready(function () {
|
1202 |
Â
ShortPixel.initFolderSelector();
|
1203 |
Â
});
|
1204 |
Â
</script>
|
1205 |
+
</div> <!-- end of AddCustomFolder -->
|
1206 |
Â
</td>
|
1207 |
Â
</tr>
|
1208 |
Â
<?php if($hasNextGen) { ?>
|
1337 |
Â
<tr>
|
1338 |
Â
<th scope="row"><label for="excludePatterns"><?php _e('Exclude patterns','shortpixel-image-optimiser');?></label></th>
|
1339 |
Â
<td>
|
1340 |
+
<input name="excludePatterns" type="text" id="excludePatterns" value="<?php echo( $excludePatterns );?>" class="regular-text" placeholder="<?php
|
1341 |
+
_e('name:keepbig, path:/ignore_regex/i, size:1000x2000','shortpixel-image-optimiser');?>">
|
1342 |
Â
<?php _e('Exclude certain images from being optimized, based on patterns.','shortpixel-image-optimiser');?>
|
1343 |
+
<p class="settings-info">
|
1344 |
Â
<?php _e('Add patterns separated by comma. A pattern consist of a <strong>type:value</strong> pair; the accepted types are
|
1345 |
Â
<strong>"name"</strong>, <strong>"path"</strong> and <strong>"size"</strong>.
|
1346 |
Â
A file will be excluded if it matches any of the patterns.
|
1360 |
Â
<tr>
|
1361 |
Â
<th scope="row"><label for="authentication"><?php _e('HTTP AUTH credentials','shortpixel-image-optimiser');?></label></th>
|
1362 |
Â
<td>
|
1363 |
+
<input name="siteAuthUser" type="text" id="siteAuthUser" value="<?php echo( esc_html($settings->siteAuthUser ));?>" class="regular-text" placeholder="<?php _e('User','shortpixel-image-optimiser');?>"><br>
|
1364 |
+
<input name="siteAuthPass" type="text" id="siteAuthPass" value="<?php echo( esc_html($settings->siteAuthPass ));?>" class="regular-text" placeholder="<?php _e('Password','shortpixel-image-optimiser');?>">
|
1365 |
+
<p class="settings-info">
|
1366 |
Â
<?php _e('Only fill in these fields if your site (front-end) is not publicly accessible and visitors need a user/pass to connect to it. If you don\'t know what is this then just <strong>leave the fields empty</strong>.','shortpixel-image-optimiser');?>
|
1367 |
Â
</p>
|
1368 |
Â
</td>
|
1413 |
Â
</script>
|
1414 |
Â
<?php }
|
1415 |
Â
}
|
1416 |
+
|
1417 |
Â
/**
|
1418 |
Â
* @desc This form is used in WP back-end to allow users that use CloudFlare to save their settings
|
1419 |
Â
*
|
1439 |
Â
</th>
|
1440 |
Â
<td>
|
1441 |
Â
<input name="cloudflare-email" type="text" id="cloudflare-email" <?php echo($noCurl ? 'disabled' : '');?>
|
1442 |
+
value="<?php echo(esc_html($this->ctrl->fetch_cloudflare_api_email())); ?>" class="regular-text">
|
1443 |
Â
<p class="settings-info">
|
1444 |
Â
<?php _e('The e-mail address you use to login to CloudFlare.','shortpixel-image-optimiser');?>
|
1445 |
Â
</p>
|
1451 |
Â
</th>
|
1452 |
Â
<td>
|
1453 |
Â
<input name="cloudflare-auth-key" type="text" id="cloudflare-auth-key" <?php echo($noCurl ? 'disabled' : '');?>
|
1454 |
+
value="<?php echo(esc_html($this->ctrl->fetch_cloudflare_api_key())); ?>" class="regular-text">
|
1455 |
Â
<p class="settings-info">
|
1456 |
Â
<?php _e("This can be found when you're logged into your account, on the My Profile page:",'shortpixel-image-optimiser');?> <a href='https://www.cloudflare.com/a/profile' target='_blank'>https://www.cloudflare.com/a/profile</a>
|
1457 |
Â
</p>
|
1463 |
Â
</th>
|
1464 |
Â
<td>
|
1465 |
Â
<input name="cloudflare-zone-id" type="text" id="cloudflare-zone-id" <?php echo($noCurl ? 'disabled' : '');?>
|
1466 |
+
value="<?php echo(esc_html($this->ctrl->fetch_cloudflare_api_zoneid())); ?>" class="regular-text">
|
1467 |
Â
<p class="settings-info">
|
1468 |
Â
<?php _e('This can be found in your Cloudflare account in the "Overview" section for your domain.','shortpixel-image-optimiser');?>
|
1469 |
Â
</p>
|
1623 |
Â
|
1624 |
Â
public function renderCustomColumn($id, $data, $extended = false){ ?>
|
1625 |
Â
<div id='sp-msg-<?php echo($id);?>' class='column-wp-shortPixel'>
|
1626 |
+
|
1627 |
Â
<?php switch($data['status']) {
|
1628 |
+
case 'n/a': ?>
|
1629 |
Â
<?php _e('Optimization N/A','shortpixel-image-optimiser');?> <?php
|
1630 |
Â
break;
|
1631 |
+
case 'notFound': ?>
|
1632 |
Â
<?php _e('Image does not exist.','shortpixel-image-optimiser');?> <?php
|
1633 |
Â
break;
|
1634 |
+
case 'invalidKey':
|
1635 |
Â
if(defined("SHORTPIXEL_API_KEY")) { // multisite key - need to be validated on each site but it's not invalid
|
1636 |
Â
?> <?php _e('Please <a href="options-general.php?page=wp-shortpixel">go to Settings</a> to validate the API Key.','shortpixel-image-optimiser');?> <?php
|
1637 |
Â
} else {
|
1638 |
Â
?> <?php _e('Invalid API Key. <a href="options-general.php?page=wp-shortpixel">Check your Settings</a>','shortpixel-image-optimiser');?> <?php
|
1639 |
+
}
|
1640 |
Â
break;
|
1641 |
+
case 'quotaExceeded':
|
1642 |
Â
echo($this->getQuotaExceededHTML(isset($data['message']) ? $data['message'] : ''));
|
1643 |
Â
break;
|
1644 |
+
case 'optimizeNow':
|
1645 |
+
if($data['showActions']) { ?>
|
1646 |
Â
<a class='button button-smaller button-primary' href="javascript:manualOptimization('<?php echo($id)?>', false)">
|
1647 |
Â
<?php _e('Optimize now','shortpixel-image-optimiser');?>
|
1648 |
+
</a>
|
1649 |
Â
<?php }
|
1650 |
Â
echo($data['message']);
|
1651 |
Â
if(isset($data['thumbsTotal']) && $data['thumbsTotal'] > 0) {
|
1657 |
Â
echo($data['message']);
|
1658 |
Â
if(isset($data['cleanup'])) {?> <a class='button button-smaller button-primary' href="javascript:manualOptimization('<?php echo($id)?>', true)">
|
1659 |
Â
<?php _e('Cleanup&Retry','shortpixel-image-optimiser');?>
|
1660 |
+
</a> <?php
|
1661 |
Â
} else {
|
1662 |
Â
if($data['status'] == 'retry') { ?>
|
1663 |
Â
<div style="overflow:hidden">
|
1673 |
Â
<?php
|
1674 |
Â
}
|
1675 |
Â
break;
|
1676 |
+
case 'pdfOptimized':
|
1677 |
Â
case 'imgOptimized':
|
1678 |
Â
$excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
|
1679 |
Â
$successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt'], $data['excludeSizes']);
|
1694 |
Â
$missingThumbs .= '</span>';
|
1695 |
Â
}
|
1696 |
Â
$successText .= ($data['webpCount'] ? "<br>+" . $data['webpCount'] . __(" WebP images", 'shortpixel-image-optimiser') : "")
|
1697 |
+
. "<br>EXIF: " . ($data['exifKept'] ? __('kept','shortpixel-image-optimiser') : __('removed','shortpixel-image-optimiser'))
|
1698 |
Â
. ($data['png2jpg'] ? '<br>' . __('Converted from PNG','shortpixel-image-optimiser'): '')
|
1699 |
Â
. "<br>" . __("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date']
|
1700 |
Â
. $excludeSizes . $missingThumbs;
|
1701 |
Â
}
|
Â
|
|
1702 |
Â
$this->renderListCell($id, $data['status'], $data['showActions'], $data['thumbsToOptimize'],
|
1703 |
Â
$data['backup'], $data['type'], $data['invType'], $successText);
|
1704 |
+
|
1705 |
Â
break;
|
1706 |
Â
}
|
1707 |
Â
//if($extended) {
|
1709 |
Â
//}
|
1710 |
Â
?>
|
1711 |
Â
</div>
|
1712 |
+
<?php
|
1713 |
Â
}
|
1714 |
+
|
1715 |
Â
public function getSuccessText($percent, $bonus, $type, $thumbsOpt = 0, $thumbsTotal = 0, $retinasOpt = 0, $excluded = 0) {
|
1716 |
Â
if($percent == 999) return __("Reduced by X%(unknown)");
|
1717 |
Â
return ($percent && $percent > 0 ? __('Reduced by','shortpixel-image-optimiser') . ' <strong>' . $percent . '%</strong> ' : '')
|
1718 |
Â
.(!$bonus ? ' ('.$type.')':'')
|
1719 |
+
.($bonus && $percent ? '<br>' : '')
|
1720 |
+
.($bonus ? __('Bonus processing','shortpixel-image-optimiser') : '')
|
1721 |
Â
.($bonus ? ' ('.$type.')':'') . '<br>'
|
1722 |
+
.($thumbsOpt ? ( $thumbsTotal > $thumbsOpt
|
1723 |
+
? sprintf(__('+%s of %s thumbnails optimized','shortpixel-image-optimiser'),$thumbsOpt,$thumbsTotal)
|
1724 |
Â
: sprintf(__('+%s thumbnails optimized','shortpixel-image-optimiser'),$thumbsOpt)) : '')
|
1725 |
Â
.($retinasOpt ? '<br>' . sprintf(__('+%s Retina images optimized','shortpixel-image-optimiser') , $retinasOpt) : '' );
|
1726 |
Â
}
|
1727 |
+
|
1728 |
Â
public function renderListCell($id, $status, $showActions, $thumbsRemain, $backup, $type, $invType, $message, $extraClass = '') {
|
1729 |
Â
if($showActions && ($backup || $thumbsRemain)) { ?>
|
1730 |
Â
<div class='sp-column-actions <?php echo($extraClass);?>'>
|
1740 |
Â
</a>
|
1741 |
Â
<?php }
|
1742 |
Â
if($backup) {
|
1743 |
+
if($type) {
|
1744 |
Â
//$invType = $type == 'lossy' ? 'lossless' : 'lossy'; ?>
|
1745 |
+
<a class="sp-action-reoptimize1" href="javascript:reoptimize('<?php echo($id)?>', '<?php echo($invType[0])?>');"
|
1746 |
Â
title="<?php _e('Reoptimize from the backed-up image','shortpixel-image-optimiser');?>">
|
1747 |
Â
<?php _e('Re-optimize','shortpixel-image-optimiser');?> <?php echo($invType[0])?>
|
1748 |
Â
</a>
|
1749 |
+
<a class="sp-action-reoptimize2" href="javascript:reoptimize('<?php echo($id)?>', '<?php echo($invType[1])?>');"
|
1750 |
Â
title="<?php _e('Reoptimize from the backed-up image','shortpixel-image-optimiser');?>">
|
1751 |
Â
<?php _e('Re-optimize','shortpixel-image-optimiser');?> <?php echo($invType[1])?>
|
1752 |
Â
</a><?php
|
1757 |
Â
<?php } ?>
|
1758 |
Â
</div>
|
1759 |
Â
</div>
|
1760 |
+
</div>
|
1761 |
+
<?php } ?>
|
1762 |
Â
<div class='sp-column-info'>
|
1763 |
Â
<?php echo($message);?>
|
1764 |
Â
</div> <?php
|
1765 |
Â
}
|
1766 |
+
|
1767 |
Â
public function getQuotaExceededHTML($message = '') {
|
1768 |
+
return "<div class='sp-column-actions' style='width:110px;'>
|
1769 |
Â
<a class='button button-smaller button-primary' href='https://shortpixel.com/login/". (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) . "' target='_blank'>"
|
1770 |
+
. __('Extend Quota','shortpixel-image-optimiser') .
|
1771 |
Â
"</a>
|
1772 |
+
<a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"
|
1773 |
Â
. __('Check Quota','shortpixel-image-optimiser') .
|
1774 |
Â
"</a></div>
|
1775 |
Â
<div class='sp-column-info'>" . $message . " " . __('Quota Exceeded','shortpixel-image-optimiser') . "</div>";
|
1776 |
Â
}
|
1777 |
+
|
1778 |
Â
public function outputComparerHTML() {?>
|
1779 |
+
<div class="sp-modal-shade"></div>
|
1780 |
Â
<div id="spUploadCompare" class="shortpixel-modal shortpixel-hide">
|
1781 |
Â
<div class="sp-modal-title">
|
1782 |
Â
<button type="button" class="sp-close-button">×</button>
|
1809 |
Â
</div>
|
1810 |
Â
</div>
|
1811 |
Â
</div>
|
1812 |
+
|
1813 |
Â
<?php
|
1814 |
Â
}
|
1815 |
Â
}
|
@@ -0,0 +1,47 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
|
2 |
+
<div class="wrap short-pixel-bulk-page bulk-restore-all">
|
3 |
+
<form action='<?php echo remove_query_arg('part'); ?>' method='POST' >
|
4 |
+
<h1><?php _e('Bulk Image Optimization by ShortPixel','shortpixel-image-optimiser');?></h1>
|
5 |
+
|
6 |
+
<div class="sp-notice sp-notice-info sp-floating-block sp-full-width">
|
7 |
+
|
8 |
+
<h3><?php _e( "Are you sure you want to restore from backup all the images optimized with ShortPixel?", 'shortpixel-image-optimiser' ); ?></h3>
|
9 |
+
|
10 |
+
<p><?php _e('Please read carefully. This function will: ', 'shortpixel-image-optimiser'); ?> </p>
|
11 |
+
<ol>
|
12 |
+
<li><?php _e('Remove all optimized images from media library', 'shortpixel-image-optimiser'); ?></li>
|
13 |
+
<li><?php _e( sprintf('Remove all optimized images from %s selected %s other media', '<strong>', '</strong>'), 'shortpixel-image-optimiser'); ?></li>
|
14 |
+
</ol>
|
15 |
+
|
16 |
+
<section class='select_folders'>
|
17 |
+
<h4><?php _e('Select which Custom Media Folders to restore', 'shortpixel-image-optimiser'); ?></h4>
|
18 |
+
|
19 |
+
<?php $folders = $controller->getCustomFolders();
|
20 |
+
foreach($folders as $folder):
|
21 |
+
$path = $folder->getPath();
|
22 |
+
$fileCount = $folder->getFileCount();
|
23 |
+
$folder_id = $folder->getId();
|
24 |
+
// $status = $folder->getStatus();
|
25 |
+
?>
|
26 |
+
|
27 |
+
|
28 |
+
<label class='input'><input type='checkbox' name='selected_folders[]' value='<?php echo $folder_id ?>' checked /> <?php echo $path ?> <span class='filecount'> (<?php printf ('%s File(s)', $fileCount) ?>) </span></label>
|
29 |
+
<?php endforeach; ?>
|
30 |
+
</section>
|
31 |
+
|
32 |
+
<section class='random_check'>
|
33 |
+
<div><?php _e('To continue and agree with the warning, please check the correct value below', 'shortpixel-image-optimiser') ?>
|
34 |
+
<div class='random_answer'><?php echo $controller->randomAnswer(); ?></div>
|
35 |
+
</div>
|
36 |
+
|
37 |
+
<div class='inputs'><?php echo $controller->randomCheck(); ?></div>
|
38 |
+
</section>
|
39 |
+
|
40 |
+
<div class='form-controls'>
|
41 |
+
<a class='button' href="<?php echo remove_query_arg('part') ?>"><?php _e('Back', 'shortpixel-image-optimiser'); ?></a>
|
42 |
+
<button disabled aria-disabled="true" type='submit' class='button bulk restore disabled' name='bulkRestore' id='bulkRestore'><?php _e('Bulk Restore', 'shortpixel-image-optimiser'); ?></button>
|
43 |
+
</div>
|
44 |
+
|
45 |
+
</div> <!-- sp-notice -->
|
46 |
+
</form>
|
47 |
+
</div> <!-- wrap -->
|
@@ -1,21 +1,22 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
class WPShortPixel {
|
4 |
-
|
5 |
Â
const BULK_EMPTY_QUEUE = 0;
|
6 |
-
|
7 |
Â
private $_apiInterface = null;
|
8 |
Â
private $_settings = null;
|
9 |
Â
private $prioQ = null;
|
10 |
Â
private $view = null;
|
11 |
-
|
Â
|
|
12 |
Â
private $hasNextGen = false;
|
13 |
Â
private $spMetaDao = null;
|
14 |
-
|
15 |
Â
private $jsSuffix = '.min.js';
|
16 |
Â
|
17 |
Â
private $timer;
|
18 |
-
|
19 |
Â
public static $PROCESSABLE_EXTENSIONS = array('jpg', 'jpeg', 'gif', 'png', 'pdf');
|
20 |
Â
|
21 |
Â
public function __construct() {
|
@@ -26,9 +27,9 @@ class WPShortPixel {
|
|
26 |
Â
}
|
27 |
Â
|
28 |
Â
load_plugin_textdomain('shortpixel-image-optimiser', false, plugin_basename(dirname( SHORTPIXEL_PLUGIN_FILE )).'/lang');
|
29 |
-
|
30 |
Â
$isAdminUser = current_user_can( 'manage_options' );
|
31 |
-
|
32 |
Â
$this->_settings = new WPShortPixelSettings();
|
33 |
Â
$this->_apiInterface = new ShortPixelAPI($this->_settings);
|
34 |
Â
$this->cloudflareApi = new ShortPixelCloudFlareApi($this->_settings->cloudflareEmail, $this->_settings->cloudflareAuthKey, $this->_settings->cloudflareZoneID);
|
@@ -36,12 +37,19 @@ class WPShortPixel {
|
|
36 |
Â
$this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $this->_settings->excludePatterns);
|
37 |
Â
$this->prioQ = new ShortPixelQueue($this, $this->_settings);
|
38 |
Â
$this->view = new ShortPixelView($this);
|
39 |
-
|
Â
|
|
Â
|
|
Â
|
|
40 |
Â
define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
|
41 |
Â
|
42 |
-
if(
|
43 |
-
|
44 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
45 |
Â
}
|
46 |
Â
|
47 |
Â
$this->setDefaultViewModeList();//set default mode as list. only @ first run
|
@@ -51,7 +59,7 @@ class WPShortPixel {
|
|
51 |
Â
add_filter( 'plugin_action_links_' . plugin_basename(SHORTPIXEL_PLUGIN_FILE), array(&$this, 'generatePluginLinks'));//for plugin settings page
|
52 |
Â
|
53 |
Â
//add_action( 'admin_footer', array(&$this, 'handleImageProcessing'));
|
54 |
-
|
55 |
Â
//Media custom column
|
56 |
Â
add_filter( 'manage_media_columns', array( &$this, 'columns' ) );//add media library column header
|
57 |
Â
add_action( 'manage_media_custom_column', array( &$this, 'generateCustomColumn' ), 10, 2 );//generate the media library column
|
@@ -63,7 +71,7 @@ class WPShortPixel {
|
|
63 |
Â
add_action( 'add_meta_boxes', array( &$this, 'shortpixelInfoBox') );
|
64 |
Â
//for cleaning up the WebP images when an attachment is deleted
|
65 |
Â
add_action( 'delete_attachment', array( &$this, 'onDeleteImage') );
|
66 |
-
|
67 |
Â
//for NextGen
|
68 |
Â
if($this->_settings->hasCustomFolders) {
|
69 |
Â
add_filter( 'ngg_manage_images_columns', array( &$this, 'nggColumns' ) );
|
@@ -73,7 +81,7 @@ class WPShortPixel {
|
|
73 |
Â
// hook on the NextGen gallery list update
|
74 |
Â
add_action('ngg_update_addgallery_page', array( &$this, 'addNextGenGalleriesToCustom'));
|
75 |
Â
}
|
76 |
-
|
77 |
Â
// integration with WP/LR Sync plugin
|
78 |
Â
add_action( 'wplr_update_media', array( &$this, 'onWpLrUpdateMedia' ), 10, 2);
|
79 |
Â
|
@@ -88,14 +96,14 @@ class WPShortPixel {
|
|
88 |
Â
//add settings page
|
89 |
Â
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
90 |
Â
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
91 |
-
|
92 |
Â
add_action('wp_ajax_shortpixel_browse_content', array(&$this, 'browseContent'));
|
93 |
Â
add_action('wp_ajax_shortpixel_get_backup_size', array(&$this, 'getBackupSize'));
|
94 |
Â
add_action('wp_ajax_shortpixel_get_comparer_data', array(&$this, 'getComparerData'));
|
95 |
Â
|
96 |
Â
add_action('wp_ajax_shortpixel_new_api_key', array(&$this, 'newApiKey'));
|
97 |
Â
add_action('wp_ajax_shortpixel_propose_upgrade', array(&$this, 'proposeUpgrade'));
|
98 |
-
|
99 |
Â
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
100 |
Â
add_action( 'load-upload.php', array( &$this, 'handleCustomBulk'));
|
101 |
Â
|
@@ -107,7 +115,7 @@ class WPShortPixel {
|
|
107 |
Â
add_action('wp_ajax_shortpixel_optimize_thumbs', array(&$this, 'handleOptimizeThumbs'));
|
108 |
Â
|
109 |
Â
//toolbar notifications
|
110 |
-
add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
|
111 |
Â
//deactivate plugin
|
112 |
Â
add_action( 'admin_post_shortpixel_deactivate_plugin', array(&$this, 'deactivatePlugin'));
|
113 |
Â
//only if the key is not yet valid or the user hasn't bought any credits.
|
@@ -118,7 +126,7 @@ class WPShortPixel {
|
|
118 |
Â
new ShortPixelFeedback( SHORTPIXEL_PLUGIN_FILE, 'shortpixel-image-optimiser', $this->_settings->apiKey, $this);
|
119 |
Â
}
|
120 |
Â
}
|
121 |
-
|
122 |
Â
//automatic optimization
|
123 |
Â
add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
124 |
Â
//manual optimization
|
@@ -132,10 +140,11 @@ class WPShortPixel {
|
|
132 |
Â
add_action('wp_ajax_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
133 |
Â
add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
134 |
Â
//This adds the constants used in PHP to be available also in JS
|
135 |
-
add_action( 'admin_footer', array(
|
136 |
-
add_action( 'admin_head', array(
|
137 |
Â
|
138 |
-
if($this->_settings->frontBootstrap) {
|
Â
|
|
139 |
Â
//also need to have it in the front footer then
|
140 |
Â
add_action( 'wp_footer', array( &$this, 'shortPixelJS') );
|
141 |
Â
//need to add the nopriv action for when items exist in the queue and no user is logged in
|
@@ -143,14 +152,16 @@ class WPShortPixel {
|
|
143 |
Â
}
|
144 |
Â
//register a method to display admin notices if necessary
|
145 |
Â
add_action('admin_notices', array( &$this, 'displayAdminNotices'));
|
146 |
-
|
147 |
Â
$this->migrateBackupFolder();
|
148 |
Â
|
Â
|
|
149 |
Â
if(!$this->_settings->redirectedSettings && !$this->_settings->verifiedKey && (!function_exists("is_multisite") || !is_multisite())) {
|
150 |
Â
$this->_settings->redirectedSettings = 1;
|
151 |
Â
wp_redirect(admin_url("options-general.php?page=wp-shortpixel"));
|
152 |
Â
exit();
|
153 |
Â
}
|
Â
|
|
154 |
Â
}
|
155 |
Â
|
156 |
Â
//handling older
|
@@ -170,13 +181,13 @@ class WPShortPixel {
|
|
170 |
Â
/*translators: title and menu name for the Bulk Processing page*/
|
171 |
Â
add_media_page( __('ShortPixel Bulk Process','shortpixel-image-optimiser'), __('Bulk ShortPixel','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-bulk', array( &$this, 'bulkProcess' ) );
|
172 |
Â
}
|
173 |
-
|
174 |
Â
public static function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
175 |
Â
{
|
176 |
Â
self::shortPixelDeactivatePlugin();
|
177 |
Â
if(SHORTPIXEL_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments
|
178 |
Â
WPShortPixelSettings::debugResetOptions();
|
179 |
-
|
180 |
Â
$settings = new WPShortPixelSettings();
|
181 |
Â
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $settings->excludePatterns);
|
182 |
Â
$spMetaDao->dropTables();
|
@@ -186,7 +197,7 @@ class WPShortPixel {
|
|
186 |
Â
}
|
187 |
Â
WPShortPixelSettings::onActivate();
|
188 |
Â
}
|
189 |
-
|
190 |
Â
public static function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
191 |
Â
{
|
192 |
Â
ShortPixelQueue::resetBulk();
|
@@ -319,7 +330,7 @@ class WPShortPixel {
|
|
319 |
Â
}
|
320 |
Â
return $found;
|
321 |
Â
}
|
322 |
-
|
323 |
Â
public function displayAdminNotices() {
|
324 |
Â
if(!ShortPixelQueue::testQ()) {
|
325 |
Â
ShortPixelView::displayActivationNotice('fileperms');
|
@@ -329,7 +340,7 @@ class WPShortPixel {
|
|
329 |
Â
}
|
330 |
Â
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
331 |
Â
$this->_settings->dismissedNotices = $dismissed;
|
332 |
-
|
333 |
Â
if(!$this->_settings->verifiedKey) {
|
334 |
Â
$now = time();
|
335 |
Â
$act = $this->_settings->activationDate ? $this->_settings->activationDate : $now;
|
@@ -366,11 +377,11 @@ class WPShortPixel {
|
|
366 |
Â
$screen = get_current_screen();
|
367 |
Â
$stats = $this->countAllIfNeeded($this->_settings->currentStats, 86400);
|
368 |
Â
$quotaData = $stats;
|
369 |
-
|
370 |
Â
//this is for bulk page - alert on the total credits for total images
|
371 |
Â
if( !isset($dismissed['upgbulk']) && $screen && $screen->id == 'media_page_wp-short-pixel-bulk' && $this->bulkUpgradeNeeded($stats)) {
|
372 |
Â
//looks like the user hasn't got enough credits to bulk process all media library
|
373 |
-
ShortPixelView::displayActivationNotice('upgbulk', array('filesTodo' => $stats['totalFiles'] - $stats['totalProcessedFiles'],
|
374 |
Â
'quotaAvailable' => max(0, $quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'])));
|
375 |
Â
}
|
376 |
Â
//consider the monthly plus 1/6 of the available one-time credits.
|
@@ -380,7 +391,7 @@ class WPShortPixel {
|
|
380 |
Â
}
|
381 |
Â
}
|
382 |
Â
}
|
383 |
-
|
384 |
Â
public function dismissAdminNotice() {
|
385 |
Â
$noticeId = preg_replace('|[^a-z0-9]|i', '', $_GET['notice_id']);
|
386 |
Â
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
@@ -390,13 +401,13 @@ class WPShortPixel {
|
|
390 |
Â
$this->_settings->optimizeUnlisted = 1;
|
391 |
Â
}
|
392 |
Â
die(json_encode(array("Status" => 'success', "Message" => 'Notice ID: ' . $noticeId . ' dismissed')));
|
393 |
-
}
|
394 |
Â
|
395 |
Â
public function dismissMediaAlert() {
|
396 |
Â
$this->_settings->mediaAlert = 1;
|
397 |
Â
die(json_encode(array("Status" => 'success', "Message" => __('Media alert dismissed','shortpixel-image-optimiser'))));
|
398 |
-
}
|
399 |
-
|
400 |
Â
protected function getMonthAvg($stats) {
|
401 |
Â
for($i = 4, $count = 0; $i>=1; $i--) {
|
402 |
Â
if($count == 0 && $stats['totalM' . $i] == 0) continue;
|
@@ -404,7 +415,7 @@ class WPShortPixel {
|
|
404 |
Â
}
|
405 |
Â
return ($stats['totalM1'] + $stats['totalM2'] + $stats['totalM3'] + $stats['totalM4']) / max(1,$count);
|
406 |
Â
}
|
407 |
-
|
408 |
Â
protected function monthlyUpgradeNeeded($quotaData) {
|
409 |
Â
return isset($quotaData['APICallsQuotaNumeric']) && $this->getMonthAvg($quotaData) > $quotaData['APICallsQuotaNumeric'] + ($quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'])/6 + 20;
|
410 |
Â
}
|
@@ -415,9 +426,9 @@ class WPShortPixel {
|
|
415 |
Â
}
|
416 |
Â
|
417 |
Â
//set default move as "list". only set once, it won't try to set the default mode again.
|
418 |
-
public function setDefaultViewModeList()
|
419 |
Â
{
|
420 |
-
if($this->_settings->mediaLibraryViewMode === false)
|
421 |
Â
{
|
422 |
Â
$this->_settings->mediaLibraryViewMode = 1;
|
423 |
Â
$currentUserID = false;
|
@@ -427,21 +438,21 @@ class WPShortPixel {
|
|
427 |
Â
update_user_meta($currentUserID, "wp_media_library_mode", "list");
|
428 |
Â
}
|
429 |
Â
}
|
430 |
-
|
431 |
Â
}
|
432 |
Â
|
433 |
-
static function log($message) {
|
434 |
-
if (SHORTPIXEL_DEBUG === true) {
|
435 |
Â
if (is_array($message) || is_object($message)) {
|
436 |
-
self::doLog(print_r($message, true));
|
437 |
Â
} else {
|
438 |
-
self::doLog($message);
|
439 |
Â
}
|
440 |
Â
}
|
441 |
Â
}
|
442 |
-
|
443 |
-
static protected function doLog($message) {
|
444 |
-
if(defined('SHORTPIXEL_DEBUG_TARGET')) {
|
445 |
Â
file_put_contents(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log", '[' . date('Y-m-d H:i:s') . "] $message\n", FILE_APPEND);
|
446 |
Â
} else {
|
447 |
Â
error_log($message);
|
@@ -451,13 +462,14 @@ class WPShortPixel {
|
|
451 |
Â
function headCSS() {
|
452 |
Â
echo('<style>.shortpixel-hide {display:none;}</style>');
|
453 |
Â
}
|
454 |
-
|
455 |
-
function shortPixelJS() {
|
456 |
Â
//require_once(ABSPATH . 'wp-admin/includes/screen.php');
|
457 |
Â
if(function_exists('get_current_screen')) {
|
458 |
Â
$screen = get_current_screen();
|
459 |
-
|
460 |
-
|
Â
|
|
461 |
Â
//output the comparer html
|
462 |
Â
$this->view->outputComparerHTML();
|
463 |
Â
//render a template of the list cell to be used by the JS
|
@@ -468,6 +480,11 @@ class WPShortPixel {
|
|
468 |
Â
wp_enqueue_style('short-pixel-bar.min.css', plugins_url('/res/css/short-pixel-bar.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
469 |
Â
if( in_array($screen->id, array('attachment', 'upload', 'settings_page_wp-shortpixel', 'media_page_wp-short-pixel-bulk', 'media_page_wp-short-pixel-custom'))) {
|
470 |
Â
wp_enqueue_style('short-pixel.min.css', plugins_url('/res/css/short-pixel.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
471 |
Â
}
|
472 |
Â
}
|
473 |
Â
}
|
@@ -541,14 +558,14 @@ class WPShortPixel {
|
|
541 |
Â
wp_localize_script( 'shortpixel' . $this->jsSuffix, '_spTr', $jsTranslation );
|
542 |
Â
wp_localize_script( 'shortpixel' . $this->jsSuffix, 'ShortPixelConstants', $ShortPixelConstants );
|
543 |
Â
wp_enqueue_script('shortpixel' . $this->jsSuffix);
|
544 |
-
|
545 |
Â
wp_enqueue_script('jquery.knob.min.js', plugins_url('/res/js/jquery.knob.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
546 |
Â
wp_enqueue_script('jquery.tooltip.min.js', plugins_url('/res/js/jquery.tooltip.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
547 |
Â
wp_enqueue_script('punycode.min.js', plugins_url('/res/js/punycode.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
548 |
Â
}
|
549 |
Â
|
550 |
Â
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
551 |
-
|
552 |
Â
$extraClasses = " shortpixel-hide";
|
553 |
Â
/*translators: toolbar icon tooltip*/
|
554 |
Â
$id = 'short-pixel-notice-toolbar';
|
@@ -579,7 +596,7 @@ class WPShortPixel {
|
|
579 |
Â
|
580 |
Â
$args = array(
|
581 |
Â
'id' => 'shortpixel_processing',
|
582 |
-
'title' => '<div id="' . $id . '" title="' . $tooltip . '" ><img src="'
|
583 |
Â
. plugins_url( 'res/img/'.$icon, SHORTPIXEL_PLUGIN_FILE ) . '" success-url="' . $successLink . '"><span class="shp-alert">!</span>'
|
584 |
Â
.'<div class="cssload-container"><div class="cssload-speeding-wheel"></div></div></div>',
|
585 |
Â
'href' => $link,
|
@@ -623,7 +640,7 @@ class WPShortPixel {
|
|
623 |
Â
foreach( $mediaIds as $ID ) {
|
624 |
Â
$meta = wp_get_attachment_metadata($ID);
|
625 |
Â
if( ( !isset($meta['ShortPixel']) //never touched by ShortPixel
|
626 |
-
|| (isset($meta['ShortPixel']['WaitingProcessing']) && $meta['ShortPixel']['WaitingProcessing'] == true))
|
627 |
Â
&& (!isset($meta['ShortPixelImprovement']) || $meta['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser'))) {
|
628 |
Â
$this->prioQ->push($ID);
|
629 |
Â
if(!isset($meta['ShortPixel'])) {
|
@@ -632,6 +649,7 @@ class WPShortPixel {
|
|
632 |
Â
$meta['ShortPixel']['WaitingProcessing'] = true;
|
633 |
Â
//wp_update_attachment_metadata($ID, $meta);
|
634 |
Â
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
Â
|
|
635 |
Â
}
|
636 |
Â
}
|
637 |
Â
break;
|
@@ -687,11 +705,10 @@ class WPShortPixel {
|
|
687 |
Â
return $meta;
|
688 |
Â
}
|
689 |
Â
|
690 |
-
$
|
691 |
-
if(is_array($t) && isset($t[$ID])) {
|
692 |
Â
return $meta;
|
693 |
Â
}
|
694 |
-
|
695 |
Â
self::log("Handle Media Library Image Upload #{$ID}");
|
696 |
Â
//self::log("STACK: " . json_encode(debug_backtrace()));
|
697 |
Â
|
@@ -711,7 +728,7 @@ class WPShortPixel {
|
|
711 |
Â
$meta['ShortPixelImprovement'] = __('Optimization N/A', 'shortpixel-image-optimiser');
|
712 |
Â
return $meta;
|
713 |
Â
}
|
714 |
-
else
|
715 |
Â
{//the kind of file we can process. goody.
|
716 |
Â
|
717 |
Â
$this->prioQ->push($ID);
|
@@ -734,7 +751,7 @@ class WPShortPixel {
|
|
734 |
Â
//self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
735 |
Â
}
|
736 |
Â
$meta['ShortPixel']['WaitingProcessing'] = true;
|
737 |
-
|
738 |
Â
// check if the image was converted from PNG upon uploading.
|
739 |
Â
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {//for the moment
|
740 |
Â
$imagePath = $itemHandler->getMeta()->getPath();
|
@@ -743,27 +760,38 @@ class WPShortPixel {
|
|
743 |
Â
$params = $conv[$imagePath];
|
744 |
Â
unset($conv[$imagePath]);
|
745 |
Â
$this->_settings->convertedPng2Jpg == $conv;
|
746 |
-
$meta['ShortPixelPng2Jpg'] = array('originalFile' => $params['pngFile'], 'originalSizes' => array(),
|
747 |
Â
'backup' => $params['backup'], 'optimizationPercent' => $params['optimizationPercent']);
|
748 |
Â
}
|
749 |
Â
}
|
750 |
-
|
751 |
Â
return $meta;
|
752 |
-
}
|
753 |
Â
}//end handleMediaLibraryImageUpload
|
754 |
Â
|
755 |
Â
/**
|
756 |
Â
* if the image was optimized in the last hour, send a request to delete from picQueue
|
757 |
Â
* @param $itemHandler
|
758 |
Â
* @param bool $urlsAndPaths
|
Â
|
|
759 |
Â
*/
|
760 |
Â
public function maybeDumpFromProcessedOnServer($itemHandler, $urlsAndPaths) {
|
761 |
Â
$meta = $itemHandler->getMeta();
|
762 |
Â
|
763 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
764 |
Â
|
765 |
-
if
|
766 |
-
|
Â
|
|
767 |
Â
}
|
768 |
Â
}
|
769 |
Â
|
@@ -877,12 +905,30 @@ class WPShortPixel {
|
|
877 |
Â
}
|
878 |
Â
return $meta;
|
879 |
Â
}
|
880 |
-
|
881 |
Â
public function optimizeCustomImage($id) {
|
882 |
-
$
|
883 |
-
|
884 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
885 |
Â
$meta->setRetries(0);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
886 |
Â
$this->spMetaDao->update($meta);
|
887 |
Â
$this->prioQ->push('C-' . $id);
|
888 |
Â
}
|
@@ -890,34 +936,49 @@ class WPShortPixel {
|
|
890 |
Â
|
891 |
Â
public function bulkRestore(){
|
892 |
Â
global $wpdb;
|
893 |
-
|
894 |
Â
$startQueryID = $crtStartQueryID = $this->prioQ->getStartBulkId();
|
895 |
-
$endQueryID = $this->prioQ->getStopBulkId();
|
896 |
Â
|
897 |
Â
if ( $startQueryID <= $endQueryID ) {
|
898 |
Â
return false;
|
899 |
Â
}
|
900 |
-
|
901 |
Â
$this->prioQ->resetPrio();
|
902 |
Â
|
903 |
-
$startTime = time();
|
904 |
Â
$maxTime = min(30, (is_numeric(SHORTPIXEL_MAX_EXECUTION_TIME) && SHORTPIXEL_MAX_EXECUTION_TIME > 10 ? SHORTPIXEL_MAX_EXECUTION_TIME - 5 : 25));
|
905 |
Â
$maxResults = SHORTPIXEL_MAX_RESULTS_QUERY * 2;
|
906 |
Â
if(in_array($this->prioQ->getBulkType(), array(ShortPixelQueue::BULK_TYPE_CLEANUP, ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING))) {
|
907 |
Â
$maxResults *= 20;
|
908 |
Â
}
|
909 |
Â
$restored = array();
|
910 |
-
|
911 |
Â
//$ind = 0;
|
912 |
Â
while( $crtStartQueryID >= $endQueryID && time() - $startTime < $maxTime) {
|
913 |
Â
//if($ind > 1) break;
|
914 |
Â
//$ind++;
|
Â
|
|
Â
|
|
Â
|
|
915 |
Â
$resultsPostMeta = WpShortPixelMediaLbraryAdapter::getPostMetaSlice($crtStartQueryID, $endQueryID, $maxResults);
|
916 |
Â
if ( empty($resultsPostMeta) ) {
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
921 |
Â
}
|
922 |
Â
|
923 |
Â
foreach ( $resultsPostMeta as $itemMetaData ) {
|
@@ -928,7 +989,7 @@ class WPShortPixel {
|
|
928 |
Â
if($meta->getStatus() == 2 || $meta->getStatus() == 1) {
|
929 |
Â
if($meta->getStatus() == 2 && $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE) {
|
930 |
Â
$res = $this->doRestore($crtStartQueryID); //this is restore, the real
|
931 |
-
} else {
|
932 |
Â
//this is only meta cleanup, no files are replaced (BACKUP REMAINS IN PLACE TOO)
|
933 |
Â
$item->cleanupMeta($this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING);
|
934 |
Â
$res = true;
|
@@ -938,33 +999,35 @@ class WPShortPixel {
|
|
938 |
Â
if($meta->getStatus() < 0) {//also cleanup errors either for restore or cleanup
|
939 |
Â
$item->cleanupMeta();
|
940 |
Â
}
|
941 |
-
}
|
Â
|
|
Â
|
|
942 |
Â
}
|
943 |
-
|
944 |
Â
return $restored;
|
945 |
Â
}
|
946 |
-
|
947 |
Â
//TODO muta in bulkProvider
|
948 |
Â
public function getBulkItemsFromDb(){
|
949 |
Â
global $wpdb;
|
950 |
-
|
951 |
Â
$startQueryID = $this->prioQ->getStartBulkId();
|
952 |
-
$endQueryID = $this->prioQ->getStopBulkId();
|
953 |
Â
$skippedAlreadyProcessed = 0;
|
954 |
-
|
955 |
Â
if ( $startQueryID <= $endQueryID ) {
|
956 |
Â
return false;
|
957 |
Â
}
|
958 |
Â
$idList = array();
|
959 |
Â
$itemList = array();
|
960 |
-
for ($sanityCheck = 0, $crtStartQueryID = $startQueryID;
|
961 |
Â
($crtStartQueryID >= $endQueryID) && (count($itemList) < SHORTPIXEL_PRESEND_ITEMS) && ($sanityCheck < 150)
|
962 |
Â
&& (SHORTPIXEL_MAX_EXECUTION_TIME < 10 || time() - $this->timer < SHORTPIXEL_MAX_EXECUTION_TIME - 5); $sanityCheck++) {
|
963 |
-
|
964 |
Â
self::log("GETDB: current StartID: " . $crtStartQueryID);
|
965 |
Â
|
966 |
-
/* $queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
967 |
-
WHERE ( post_id <= $crtStartQueryID AND post_id >= $endQueryID )
|
968 |
Â
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )
|
969 |
Â
ORDER BY post_id DESC
|
970 |
Â
LIMIT " . SHORTPIXEL_MAX_RESULTS_QUERY;
|
@@ -987,7 +1050,7 @@ class WPShortPixel {
|
|
987 |
Â
if(!in_array($crtStartQueryID, $idList) && $this->isProcessable($crtStartQueryID, ($this->_settings->optimizePdfs ? array() : array('pdf')))) {
|
988 |
Â
$item = new ShortPixelMetaFacade($crtStartQueryID);
|
989 |
Â
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
990 |
-
|
991 |
Â
if($meta->getStatus() != 2) {
|
992 |
Â
$addIt = (strpos($meta->getMessage(), __('Image files are missing.', 'shortpixel-image-optimiser')) === false);
|
993 |
Â
|
@@ -1013,7 +1076,7 @@ class WPShortPixel {
|
|
1013 |
Â
} else {
|
1014 |
Â
$skippedAlreadyProcessed++;
|
1015 |
Â
}
|
1016 |
-
}
|
1017 |
Â
elseif( $this->_settings->processThumbnails && $meta->getThumbsOpt() !== null
|
1018 |
Â
&& ($meta->getThumbsOpt() == 0 && count($meta->getThumbs()) > 0
|
1019 |
Â
|| $meta->getThumbsOpt() < WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($meta->getThumbs(), $this->_settings->excludeSizes) && is_array($meta->getThumbsOptList()))) { //thumbs were chosen in settings
|
@@ -1036,7 +1099,7 @@ class WPShortPixel {
|
|
1036 |
Â
$leapStart = $this->prioQ->getStartBulkId();
|
1037 |
Â
$crtStartQueryID = $startQueryID = $itemMetaData->post_id - 1; //decrement it so we don't select it again
|
1038 |
Â
$res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings, $leapStart, $crtStartQueryID);
|
1039 |
-
$skippedAlreadyProcessed += $res["mainProcessedFiles"] - $res["mainProc".($this->getCompressionType() == 1 ? "Lossy" : "Lossless")."Files"];
|
1040 |
Â
self::log("GETDB: empty list. setStartBulkID to $startQueryID");
|
1041 |
Â
$this->prioQ->setStartBulkId($startQueryID);
|
1042 |
Â
} else {
|
@@ -1059,7 +1122,7 @@ class WPShortPixel {
|
|
1059 |
Â
}
|
1060 |
Â
return $items;
|
1061 |
Â
}
|
1062 |
-
|
1063 |
Â
private function checkKey($ID) {
|
1064 |
Â
if( $this->_settings->verifiedKey == false) {
|
1065 |
Â
if($ID == null){
|
@@ -1069,23 +1132,27 @@ class WPShortPixel {
|
|
1069 |
Â
$response = array("Status" => ShortPixelAPI::STATUS_NO_KEY, "ImageID" => $itemHandler ? $itemHandler->getId() : "-1", "Message" => __('Missing API Key','shortpixel-image-optimiser'));
|
1070 |
Â
$this->_settings->bulkLastStatus = $response;
|
1071 |
Â
die(json_encode($response));
|
1072 |
-
}
|
1073 |
Â
}
|
1074 |
-
|
1075 |
Â
private function sendEmptyQueue() {
|
1076 |
Â
$avg = $this->getAverageCompression();
|
1077 |
Â
$fileCount = $this->_settings->fileCount;
|
1078 |
-
$response = array("Status" => self::BULK_EMPTY_QUEUE,
|
1079 |
Â
/* translators: console message Empty queue 1234 -> 1234 */
|
1080 |
Â
"Message" => __('Empty queue ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId(),
|
1081 |
-
"BulkStatus" => ($this->prioQ->bulkRunning()
|
1082 |
Â
? "1" : ($this->prioQ->bulkPaused() ? "2" : "0")),
|
1083 |
Â
"AverageCompression" => $avg,
|
1084 |
Â
"FileCount" => $fileCount,
|
1085 |
Â
"BulkPercent" => $this->prioQ->getBulkPercent());
|
1086 |
-
die(json_encode($response));
|
1087 |
Â
}
|
1088 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
1089 |
Â
public function handleImageProcessing($ID = null) {
|
1090 |
Â
//if(rand(1,2) == 2) {
|
1091 |
Â
// header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
|
@@ -1093,18 +1160,18 @@ class WPShortPixel {
|
|
1093 |
Â
//}
|
1094 |
Â
//0: check key
|
1095 |
Â
$this->checkKey($ID);
|
1096 |
-
|
1097 |
Â
if($this->_settings->frontBootstrap && is_admin() && !ShortPixelTools::requestIsFrontendAjax()) {
|
1098 |
Â
//if in backend, and front-end is activated, mark processing from backend to shut off the front-end for 10 min.
|
1099 |
Â
$this->_settings->lastBackAction = time();
|
1100 |
Â
}
|
1101 |
-
|
1102 |
Â
$rawPrioQ = $this->prioQ->get();
|
1103 |
Â
if(count($rawPrioQ)) { self::log("HIP: 0 Priority Queue: ".json_encode($rawPrioQ)); }
|
1104 |
Â
self::log("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId);
|
1105 |
-
|
1106 |
Â
//handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
|
1107 |
-
if( $this->prioQ->bulkRunning()
|
1108 |
Â
&& ( $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE
|
1109 |
Â
|| $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP
|
1110 |
Â
|| $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING)) {
|
@@ -1112,14 +1179,14 @@ class WPShortPixel {
|
|
1112 |
Â
if($res === false) {
|
1113 |
Â
$this->sendEmptyQueue();
|
1114 |
Â
} else {
|
1115 |
-
die(json_encode(array("Status" => ShortPixelAPI::STATUS_RETRY,
|
1116 |
Â
"Message" => __('Restoring images... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId(),
|
1117 |
Â
"BulkPercent" => $this->prioQ->getBulkPercent(),
|
1118 |
Â
"Restored" => $res )));
|
1119 |
Â
}
|
1120 |
-
|
1121 |
Â
}
|
1122 |
-
|
1123 |
Â
//1: get 3 ids to process. Take them with priority from the queue
|
1124 |
Â
$ids = $this->getFromPrioAndCheck(SHORTPIXEL_PRESEND_ITEMS);
|
1125 |
Â
if(count($ids) < SHORTPIXEL_PRESEND_ITEMS ) { //take from bulk if bulk processing active
|
@@ -1145,21 +1212,22 @@ class WPShortPixel {
|
|
1145 |
Â
$customIds = false;
|
1146 |
Â
if(count($ids) < SHORTPIXEL_PRESEND_ITEMS && $this->prioQ->bulkRan() && $this->_settings->hasCustomFolders
|
1147 |
Â
&& (!$this->_settings->cancelPointer || $this->_settings->skipToCustom)
|
1148 |
-
&& !$this->_settings->customBulkPaused)
|
1149 |
Â
{ //take from custom images if any left to optimize - only if bulk was ever started
|
1150 |
Â
//but first refresh if it wasn't refreshed in the last hour
|
1151 |
Â
if(time() - $this->_settings->hasCustomFolders > 3600) {
|
1152 |
Â
$notice = null; $this->refreshCustomFolders($notice);
|
1153 |
Â
$this->_settings->hasCustomFolders = time();
|
1154 |
Â
}
|
1155 |
-
|
Â
|
|
1156 |
Â
if(is_array($customIds)) {
|
1157 |
Â
$ids = array_merge($ids, array_map(array('ShortPixelMetaFacade', 'getNewFromRow'), $customIds));
|
1158 |
Â
}
|
1159 |
Â
}
|
1160 |
Â
//var_dump($ids);
|
1161 |
Â
//die("za stop 2");
|
1162 |
-
|
1163 |
Â
//self::log("HIP: 1 Ids: ".json_encode($ids));
|
1164 |
Â
if(count($ids)) {$idl='';foreach($ids as $i){$idl.=$i->getId().' ';} self::log("HIP: 1 Selected IDs: $idl");}
|
1165 |
Â
|
@@ -1167,8 +1235,9 @@ class WPShortPixel {
|
|
1167 |
Â
for($i = 0, $itemHandler = false; $ids !== false && $i < min(SHORTPIXEL_PRESEND_ITEMS, count($ids)); $i++) {
|
1168 |
Â
$crtItemHandler = $ids[$i];
|
1169 |
Â
$tmpMeta = $crtItemHandler->getMeta();
|
Â
|
|
1170 |
Â
$compType = ($tmpMeta->getCompressionType() !== null ? $tmpMeta->getCompressionType() : $this->_settings->compressionType);
|
1171 |
-
try {
|
1172 |
Â
self::log("HIP: 1 sendToProcessing: ".$crtItemHandler->getId());
|
1173 |
Â
$URLsAndPATHs = $this->sendToProcessing($crtItemHandler, $compType, $tmpMeta->getThumbsTodo());
|
1174 |
Â
//self::log("HIP: 1 METADATA: ".json_encode($crtItemHandler->getRawMeta()));
|
@@ -1191,7 +1260,7 @@ class WPShortPixel {
|
|
1191 |
Â
if (!$itemHandler){
|
1192 |
Â
//if searching, than the script is searching for not processed items and found none yet, should be relaunced
|
1193 |
Â
if(isset($res['searching']) && $res['searching']) {
|
1194 |
-
die(json_encode(array("Status" => ShortPixelAPI::STATUS_RETRY,
|
1195 |
Â
"Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
|
1196 |
Â
}
|
1197 |
Â
//in this case the queue is really empty
|
@@ -1225,25 +1294,33 @@ class WPShortPixel {
|
|
1225 |
Â
$result["ThumbsCount"] = $meta->getThumbsOpt()
|
1226 |
Â
? $meta->getThumbsOpt() //below is the fallback for old optimized images that don't have thumbsOpt
|
1227 |
Â
: ($this->_settings->processThumbnails ? $result["ThumbsTotal"] : 0);
|
1228 |
-
|
1229 |
Â
$result["RetinasCount"] = $meta->getRetinasOpt();
|
1230 |
Â
$result["BackupEnabled"] = ($this->getBackupFolderAny($meta->getPath(), $meta->getThumbs()) ? true : false);//$this->_settings->backupImages;
|
1231 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
1232 |
Â
if(!$prio && $itemId <= $this->prioQ->getStartBulkId()) {
|
1233 |
Â
$this->advanceBulk($itemId);
|
1234 |
Â
$this->setBulkInfo($itemId, $result);
|
1235 |
Â
}
|
1236 |
Â
|
1237 |
Â
$result["AverageCompression"] = $this->getAverageCompression();
|
1238 |
-
|
1239 |
-
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
1240 |
-
|
1241 |
Â
$thumb = $bkThumb = "";
|
1242 |
Â
//$percent = 0;
|
1243 |
Â
$percent = $meta->getImprovementPercent();
|
1244 |
Â
if($percent){
|
1245 |
Â
$filePath = explode("/", $meta->getPath());
|
1246 |
-
|
1247 |
Â
//Get a suitable thumb
|
1248 |
Â
$sizes = $meta->getThumbs();
|
1249 |
Â
if('pdf' == strtolower(pathinfo($result["Filename"], PATHINFO_EXTENSION))) {
|
@@ -1350,7 +1427,7 @@ class WPShortPixel {
|
|
1350 |
Â
$prio = $this->prioQ->addToFailed($itemHandler->getQueuedId());
|
1351 |
Â
}
|
1352 |
Â
self::log("HIP RES: skipping $itemId");
|
1353 |
-
$this->advanceBulk($meta->getId());
|
1354 |
Â
if($itemHandler->getType() == ShortPixelMetaFacade::CUSTOM_TYPE) {
|
1355 |
Â
$result["CustomImageLink"] = ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath();
|
1356 |
Â
}
|
@@ -1376,23 +1453,23 @@ class WPShortPixel {
|
|
1376 |
Â
elseif($result["Status"] == ShortPixelAPI::STATUS_RETRY && is_array($customIds)) {
|
1377 |
Â
$result["CustomImageLink"] = $thumb = ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath();
|
1378 |
Â
}
|
1379 |
-
|
1380 |
Â
if($result["Status"] !== ShortPixelAPI::STATUS_RETRY) {
|
1381 |
Â
$this->_settings->bulkLastStatus = $result;
|
1382 |
Â
}
|
1383 |
Â
die(json_encode($result));
|
1384 |
Â
}
|
1385 |
-
|
1386 |
-
|
1387 |
Â
private function advanceBulk($processedID) {
|
1388 |
Â
if($processedID <= $this->prioQ->getStartBulkId()) {
|
1389 |
Â
$this->prioQ->setStartBulkId($processedID - 1);
|
1390 |
Â
$this->prioQ->logBulkProgress();
|
1391 |
Â
}
|
1392 |
Â
}
|
1393 |
-
|
1394 |
Â
private function setBulkInfo($processedID, &$result) {
|
1395 |
-
$deltaBulkPercent = $this->prioQ->getDeltaBulkPercent();
|
1396 |
Â
$minutesRemaining = $this->prioQ->getTimeRemaining();
|
1397 |
Â
$pendingMeta = $this->_settings->hasCustomFolders ? $this->spMetaDao->getPendingMetaCount() : 0;
|
1398 |
Â
$percent = $this->prioQ->getBulkPercent();
|
@@ -1406,18 +1483,18 @@ class WPShortPixel {
|
|
1406 |
Â
$result["BulkPercent"] = $percent;
|
1407 |
Â
$result["BulkMsg"] = $this->bulkProgressMessage($deltaBulkPercent, $minutesRemaining);
|
1408 |
Â
}
|
1409 |
-
|
1410 |
Â
private function sendToProcessing($itemHandler, $compressionType = false, $onlyThumbs = false) {
|
1411 |
Â
|
1412 |
Â
//conversion of PNG 2 JPG for existing images
|
1413 |
Â
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) { //currently only for ML
|
1414 |
Â
$rawMeta = $this->checkConvertMediaPng2Jpg($itemHandler);
|
1415 |
-
|
1416 |
Â
if(isset($rawMeta['type']) && $rawMeta['type'] == 'image/jpeg') {
|
1417 |
Â
$itemHandler->getMeta(true);
|
1418 |
Â
}
|
1419 |
Â
}
|
1420 |
-
|
1421 |
Â
//WpShortPixelMediaLbraryAdapter::cleanupFoundThumbs($itemHandler);
|
1422 |
Â
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
1423 |
Â
|
@@ -1426,7 +1503,7 @@ class WPShortPixel {
|
|
1426 |
Â
if( $itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE
|
1427 |
Â
&& $this->_settings->optimizeUnlisted) {
|
1428 |
Â
$mainFile = $meta->getPath();
|
1429 |
-
|
1430 |
Â
$foundThumbs = WpShortPixelMediaLbraryAdapter::findThumbs($mainFile);
|
1431 |
Â
//first identify which thumbs are not in the sizes
|
1432 |
Â
$sizes = $meta->getThumbs();
|
@@ -1460,29 +1537,29 @@ class WPShortPixel {
|
|
1460 |
Â
);
|
1461 |
Â
$ind++;
|
1462 |
Â
}
|
1463 |
-
}
|
1464 |
Â
if($ind > $start) { // at least one thumbnail added, update
|
1465 |
Â
$meta->setThumbs($sizes);
|
1466 |
Â
$itemHandler->updateMeta($meta);
|
1467 |
Â
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
1468 |
Â
}
|
1469 |
Â
}
|
1470 |
-
|
1471 |
Â
//find any missing thumbs files and mark them as such
|
1472 |
Â
$miss = $meta->getThumbsMissing();
|
1473 |
Â
/* TODO remove */if(is_numeric($miss)) $miss = array();
|
1474 |
-
if( isset($URLsAndPATHs['sizesMissing']) && count($URLsAndPATHs['sizesMissing'])
|
1475 |
Â
&& (null === $miss || count(array_diff_key($miss, array_merge($URLsAndPATHs['sizesMissing'], $miss))))) {
|
1476 |
Â
//fix missing thumbs in the metadata before sending to processing
|
1477 |
Â
$meta->setThumbsMissing($URLsAndPATHs['sizesMissing']);
|
1478 |
-
$itemHandler->updateMeta();
|
1479 |
Â
}
|
1480 |
Â
//die(var_dump($itemHandler));
|
1481 |
Â
$refresh = $meta->getStatus() === ShortPixelAPI::ERR_INCORRECT_FILE_SIZE;
|
1482 |
Â
//echo("URLS: "); die(var_dump($URLsAndPATHs));
|
1483 |
-
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $itemHandler,
|
1484 |
-
$compressionType === false ? $this->_settings->compressionType : $compressionType, $refresh);//send a request, do NOT wait for response
|
1485 |
Â
$itemHandler->setWaitingProcessing();
|
Â
|
|
Â
|
|
1486 |
Â
//$meta = wp_get_attachment_metadata($ID);
|
1487 |
Â
//$meta['ShortPixel']['WaitingProcessing'] = true;
|
1488 |
Â
//wp_update_attachment_metadata($ID, $meta);
|
@@ -1492,9 +1569,9 @@ class WPShortPixel {
|
|
1492 |
Â
public function handleManualOptimization() {
|
1493 |
Â
$imageId = $_GET['image_id'];
|
1494 |
Â
$cleanup = $_GET['cleanup'];
|
1495 |
-
|
1496 |
Â
self::log("Handle Manual Optimization #{$imageId}");
|
1497 |
-
|
1498 |
Â
switch(substr($imageId, 0, 2)) {
|
1499 |
Â
case "N-":
|
1500 |
Â
return "Add the gallery to the custom folders list in ShortPixel settings.";
|
@@ -1511,12 +1588,12 @@ class WPShortPixel {
|
|
1511 |
Â
break;
|
1512 |
Â
case "C-":
|
1513 |
Â
throw new Exception("HandleManualOptimization for custom images not implemented");
|
1514 |
-
default:
|
1515 |
Â
$this->optimizeNowHook(intval($imageId), true);
|
1516 |
Â
break;
|
1517 |
Â
}
|
1518 |
Â
//do_action('shortpixel-optimize-now', $imageId);
|
1519 |
-
|
1520 |
Â
}
|
1521 |
Â
|
1522 |
Â
public function checkStatus() {
|
@@ -1556,18 +1633,19 @@ class WPShortPixel {
|
|
1556 |
Â
* @param $postId
|
1557 |
Â
*/
|
1558 |
Â
public function thumbnailsBeforeRegenerateHook($postId) {
|
1559 |
-
$
|
1560 |
-
if($t === false) $t = array();
|
1561 |
-
$t[$postId] = true;
|
1562 |
-
set_transient("wp-short-pixel-regenerating" . $t, true, 30);
|
1563 |
Â
}
|
1564 |
Â
|
Â
|
|
1565 |
Â
/**
|
1566 |
Â
* to be called by thumbnail regeneration plugins when regenerating the thumbnails for an image
|
1567 |
Â
* @param $postId - the postId of the image
|
1568 |
Â
* @param $originalMeta - the metadata before the regeneration
|
1569 |
Â
* @param array $regeneratedSizes - the list of the regenerated thumbnails - if empty then all were regenerated.
|
1570 |
Â
* @param bool $bulk - true if the regeneration is done in bulk - in this case the image will not be immediately scheduled for processing but the user will need to launch the ShortPixel bulk after regenerating.
|
Â
|
|
Â
|
|
Â
|
|
1571 |
Â
*/
|
1572 |
Â
public function thumbnailsRegeneratedHook($postId, $originalMeta, $regeneratedSizes = array(), $bulk = false) {
|
1573 |
Â
|
@@ -1583,10 +1661,11 @@ class WPShortPixel {
|
|
1583 |
Â
foreach($regeneratedSizes as $size) {
|
1584 |
Â
if(isset($size['file']) && in_array($size['file'], $shortPixelMeta["thumbsOptList"] )) {
|
1585 |
Â
$regeneratedThumbs[] = $size['file'];
|
1586 |
-
$shortPixelMeta["thumbsOpt"] = max(0, $shortPixelMeta["thumbsOpt"] - 1);
|
1587 |
Â
$shortPixelMeta["retinasOpt"] = max(0, $shortPixelMeta["retinasOpt"] - 1);
|
1588 |
Â
}
|
1589 |
Â
}
|
Â
|
|
1590 |
Â
$shortPixelMeta["thumbsOptList"] = array_diff($shortPixelMeta["thumbsOptList"], $regeneratedThumbs);
|
1591 |
Â
}
|
1592 |
Â
$meta = wp_get_attachment_metadata($postId);
|
@@ -1597,16 +1676,12 @@ class WPShortPixel {
|
|
1597 |
Â
}
|
1598 |
Â
//wp_update_attachment_metadata($postId, $meta);
|
1599 |
Â
update_post_meta($postId, '_wp_attachment_metadata', $meta);
|
1600 |
-
$t = get_transient("wp-short-pixel-regenerating");
|
1601 |
-
if(is_array($t) && isset($t[$postId])) {
|
1602 |
-
unset($t[$postId]);
|
1603 |
-
set_transient("wp-short-pixel-regenerating" . $t, true, 30);
|
1604 |
-
}
|
1605 |
Â
|
1606 |
Â
if(!$bulk) {
|
1607 |
Â
$this->prioQ->push($postId);
|
1608 |
Â
}
|
1609 |
Â
}
|
Â
|
|
1610 |
Â
}
|
1611 |
Â
|
1612 |
Â
public function shortpixelGetBackupFilter($imagePath) {
|
@@ -1624,10 +1699,11 @@ class WPShortPixel {
|
|
1624 |
Â
$this->prioQ->push($imageId);
|
1625 |
Â
//wp_update_attachment_metadata($imageId, $meta);
|
1626 |
Â
update_post_meta($imageId, '_wp_attachment_metadata', $meta);
|
Â
|
|
1627 |
Â
}
|
1628 |
Â
}
|
1629 |
-
|
1630 |
-
|
1631 |
Â
//save error in file's meta data
|
1632 |
Â
public function handleError($ID, $result)
|
1633 |
Â
{
|
@@ -1645,7 +1721,7 @@ class WPShortPixel {
|
|
1645 |
Â
//another chance at glory, maybe cleanup was too much? (we tried first the cleaned up version for historical reason, don't disturb the sleeping dragon, right? :))
|
1646 |
Â
return $this->getBackupFolderInternal($file);
|
1647 |
Â
}
|
1648 |
-
|
1649 |
Â
private function getBackupFolderInternal($file) {
|
1650 |
Â
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1651 |
Â
$SubDir = ShortPixelMetaFacade::returnSubDir($file);
|
@@ -1668,7 +1744,7 @@ class WPShortPixel {
|
|
1668 |
Â
}
|
1669 |
Â
return SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir;
|
1670 |
Â
}
|
1671 |
-
|
1672 |
Â
public function getBackupFolderAny($file, $thumbs) {
|
1673 |
Â
$ret = $this->getBackupFolder($file);
|
1674 |
Â
//if(!$ret && !file_exists($file) && isset($thumbs)) {
|
@@ -1727,7 +1803,7 @@ class WPShortPixel {
|
|
1727 |
Â
|
1728 |
Â
$pathInfo = pathinfo($file);
|
1729 |
Â
$sizes = isset($rawMeta["sizes"]) ? $rawMeta["sizes"] : array();
|
1730 |
-
|
1731 |
Â
//check if the images were converted from PNG
|
1732 |
Â
$png2jpgMain = isset($rawMeta['ShortPixelPng2Jpg']['originalFile']) ? $rawMeta['ShortPixelPng2Jpg']['originalFile'] : false;
|
1733 |
Â
$bkFolder = $this->getBackupFolderAny($file, $sizes);
|
@@ -1893,11 +1969,11 @@ class WPShortPixel {
|
|
1893 |
Â
}
|
1894 |
Â
return false;
|
1895 |
Â
}
|
1896 |
-
|
1897 |
Â
protected function renameWithRetina($bkFile, $file) {
|
1898 |
Â
@rename($bkFile, $file);
|
1899 |
Â
@rename($this->retinaName($bkFile), $this->retinaName($file));
|
1900 |
-
|
1901 |
Â
}
|
1902 |
Â
|
1903 |
Â
protected function retinaName($file) {
|
@@ -1906,25 +1982,64 @@ class WPShortPixel {
|
|
1906 |
Â
}
|
1907 |
Â
|
1908 |
Â
public function doCustomRestore($ID) {
|
1909 |
-
|
1910 |
-
|
1911 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
1912 |
Â
$file = $meta->getPath();
|
1913 |
Â
$fullSubDir = str_replace(get_home_path(), "", dirname($file)) . '/';
|
1914 |
-
$bkFile = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir . ShortPixelAPI::MB_basename($file);
|
1915 |
Â
|
1916 |
Â
if(file_exists($bkFile)) {
|
1917 |
-
@rename($bkFile, $file);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
1918 |
Â
$meta->setStatus(3);
|
1919 |
Â
$this->spMetaDao->update($meta);
|
Â
|
|
Â
|
|
1920 |
Â
}
|
1921 |
-
|
Â
|
|
Â
|
|
Â
|
|
1922 |
Â
return $meta;
|
1923 |
Â
}
|
1924 |
-
|
1925 |
Â
public function handleRestoreBackup() {
|
1926 |
Â
$attachmentID = intval($_GET['attachment_ID']);
|
1927 |
-
|
1928 |
Â
self::log("Handle Restore Backup #{$attachmentID}");
|
1929 |
Â
$this->doRestore($attachmentID);
|
1930 |
Â
|
@@ -1936,13 +2051,13 @@ class WPShortPixel {
|
|
1936 |
Â
wp_redirect($sendback);
|
1937 |
Â
// we are done
|
1938 |
Â
}
|
1939 |
-
|
1940 |
Â
public function handleRedo() {
|
1941 |
Â
self::log("Handle Redo #{$_GET['attachment_ID']} type {$_GET['type']}");
|
1942 |
-
|
1943 |
Â
die(json_encode($this->redo($_GET['attachment_ID'], $_GET['type'])));
|
1944 |
Â
}
|
1945 |
-
|
1946 |
Â
public function redo($qID, $type = false) {
|
1947 |
Â
$compressionType = ($type == 'lossless' ? 'lossless' : ($type == 'glossy' ? 'glossy' : 'lossy')); //sanity check
|
1948 |
Â
|
@@ -1957,7 +2072,7 @@ class WPShortPixel {
|
|
1957 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
|
1958 |
Â
} else {
|
1959 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => __('Could not restore from backup: ','shortpixel-image-optimiser') . $qID);
|
1960 |
-
}
|
1961 |
Â
} else {
|
1962 |
Â
$ID = intval($qID);
|
1963 |
Â
$meta = $this->doRestore($ID);
|
@@ -1976,20 +2091,20 @@ class WPShortPixel {
|
|
1976 |
Â
//wp_update_attachment_metadata($ID, $meta);
|
1977 |
Â
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
1978 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
|
1979 |
-
}
|
1980 |
Â
} else {
|
1981 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => __('Could not restore from backup: ','shortpixel-image-optimiser') . $ID);
|
1982 |
Â
}
|
1983 |
Â
}
|
1984 |
Â
return $ret;
|
1985 |
Â
}
|
1986 |
-
|
1987 |
Â
public function handleOptimizeThumbs() {
|
1988 |
Â
$ID = intval($_GET['attachment_ID']);
|
1989 |
Â
$meta = wp_get_attachment_metadata($ID);
|
1990 |
Â
//die(var_dump($meta));
|
1991 |
Â
$thumbsCount = WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($meta['sizes'], $this->_settings->excludeSizes);
|
1992 |
-
if( isset($meta['ShortPixelImprovement'])
|
1993 |
Â
&& isset($meta['sizes']) && $thumbsCount
|
1994 |
Â
&& ( !isset($meta['ShortPixel']['thumbsOpt']) || $meta['ShortPixel']['thumbsOpt'] == 0
|
1995 |
Â
|| (isset($meta['sizes']) && isset($meta['ShortPixel']['thumbsOptList']) && $meta['ShortPixel']['thumbsOpt'] < $thumbsCount))) { //optimized without thumbs, thumbs exist
|
@@ -2009,13 +2124,13 @@ class WPShortPixel {
|
|
2009 |
Â
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
2010 |
Â
}
|
2011 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
|
2012 |
-
}
|
2013 |
Â
} else {
|
2014 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "message" => (isset($meta['ShortPixelImprovement']) ? __('No thumbnails to optimize for ID: ','shortpixel-image-optimiser') : __('Please optimize image for ID: ','shortpixel-image-optimiser')) . $ID);
|
2015 |
Â
}
|
2016 |
Â
die(json_encode($ret));
|
2017 |
Â
}
|
2018 |
-
|
2019 |
Â
public function handleCheckQuota() {
|
2020 |
Â
$this->getQuotaInformation();
|
2021 |
Â
// store the referring webpage location
|
@@ -2036,13 +2151,13 @@ class WPShortPixel {
|
|
2036 |
Â
$meta = wp_get_attachment_metadata($ID);
|
2037 |
Â
|
2038 |
Â
|
2039 |
-
if(self::_isProcessable($ID) != false) //we use the static isProcessable to bypass the exclude patterns
|
2040 |
Â
{
|
2041 |
Â
try {
|
2042 |
Â
$SubDir = ShortPixelMetaFacade::returnSubDir($file);
|
2043 |
-
|
2044 |
Â
@unlink(SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file));
|
2045 |
-
|
2046 |
Â
if ( !empty($meta['file']) )
|
2047 |
Â
{
|
2048 |
Â
$filesPath = SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir;//base BACKUP path
|
@@ -2052,14 +2167,14 @@ class WPShortPixel {
|
|
2052 |
Â
@unlink($filesPath . ShortPixelAPI::MB_basename($imageData['file']));//remove thumbs
|
2053 |
Â
}
|
2054 |
Â
}
|
2055 |
-
}
|
2056 |
-
|
2057 |
Â
} catch(Exception $e) {
|
2058 |
Â
//what to do, what to do?
|
2059 |
Â
}
|
2060 |
Â
}
|
2061 |
Â
}
|
2062 |
-
|
2063 |
Â
public function deactivatePlugin() {
|
2064 |
Â
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'sp_deactivate_plugin_nonce' ) ) {
|
2065 |
Â
wp_nonce_ays( '' );
|
@@ -2090,7 +2205,7 @@ class WPShortPixel {
|
|
2090 |
Â
if( !(defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG === true) && is_array($this->_settings->currentStats)
|
2091 |
Â
&& $this->_settings->currentStats['optimizePdfs'] == $this->_settings->optimizePdfs
|
2092 |
Â
&& isset($this->_settings->currentStats['time'])
|
2093 |
-
&& (time() - $this->_settings->currentStats['time'] < $time))
|
2094 |
Â
{
|
2095 |
Â
return $this->_settings->currentStats;
|
2096 |
Â
} else {
|
@@ -2105,7 +2220,7 @@ class WPShortPixel {
|
|
2105 |
Â
if($this->_settings->hasCustomFolders) {
|
2106 |
Â
$customImageCount = $this->spMetaDao->countAllProcessableFiles();
|
2107 |
Â
foreach($customImageCount as $key => $val) {
|
2108 |
-
$quotaData[$key] = isset($quotaData[$key])
|
2109 |
Â
? (is_array($quotaData[$key])
|
2110 |
Â
? array_merge($quotaData[$key], $val)
|
2111 |
Â
: (is_numeric($quotaData[$key])
|
@@ -2118,7 +2233,7 @@ class WPShortPixel {
|
|
2118 |
Â
return $quotaData;
|
2119 |
Â
}
|
2120 |
Â
}
|
2121 |
-
|
2122 |
Â
public function checkQuotaAndAlert($quotaData = null, $recheck = false, $refreshFiles = 300) {
|
2123 |
Â
if(!$quotaData) {
|
2124 |
Â
$quotaData = $this->getQuotaInformation();
|
@@ -2144,7 +2259,7 @@ class WPShortPixel {
|
|
2144 |
Â
}
|
2145 |
Â
return $quotaData;
|
2146 |
Â
}
|
2147 |
-
|
2148 |
Â
public function isValidMetaId($id) {
|
2149 |
Â
return substr($id, 0, 2 ) == "C-" ? $this->spMetaDao->getMeta(substr($id, 2)) : wp_get_attachment_url($id);
|
2150 |
Â
}
|
@@ -2152,8 +2267,8 @@ class WPShortPixel {
|
|
2152 |
Â
public function listCustomMedia() {
|
2153 |
Â
if( ! class_exists( 'ShortPixelListTable' ) ) {
|
2154 |
Â
require_once('view/shortpixel-list-table.php');
|
2155 |
-
}
|
2156 |
-
if(isset($_REQUEST['refresh']) && esc_attr($_REQUEST['refresh']) == 1) {
|
2157 |
Â
$notice = null;
|
2158 |
Â
$this->refreshCustomFolders($notice);
|
2159 |
Â
}
|
@@ -2161,6 +2276,7 @@ class WPShortPixel {
|
|
2161 |
Â
//die(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
|
2162 |
Â
$this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
|
2163 |
Â
}
|
Â
|
|
2164 |
Â
$customMediaListTable = new ShortPixelListTable($this, $this->spMetaDao, $this->hasNextGen);
|
2165 |
Â
$items = $customMediaListTable->prepare_items();
|
2166 |
Â
if ( isset($_GET['noheader']) ) {
|
@@ -2205,7 +2321,10 @@ class WPShortPixel {
|
|
2205 |
Â
</div>
|
2206 |
Â
</div> <?php
|
2207 |
Â
}
|
2208 |
-
|
Â
|
|
Â
|
|
Â
|
|
2209 |
Â
public function bulkProcess() {
|
2210 |
Â
global $wpdb;
|
2211 |
Â
|
@@ -2213,13 +2332,13 @@ class WPShortPixel {
|
|
2213 |
Â
ShortPixelView::displayActivationNotice();
|
2214 |
Â
return;
|
2215 |
Â
}
|
2216 |
-
|
2217 |
Â
$quotaData = $this->checkQuotaAndAlert(null, isset($_GET['checkquota']), 0);
|
2218 |
Â
//if($this->_settings->quotaExceeded != 0) {
|
2219 |
Â
//return;
|
2220 |
Â
//}
|
2221 |
-
|
2222 |
-
if(isset($_POST['bulkProcessPause']))
|
2223 |
Â
{//pause an ongoing bulk processing, it might be needed sometimes
|
2224 |
Â
$this->prioQ->pauseBulk();
|
2225 |
Â
if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
|
@@ -2227,7 +2346,7 @@ class WPShortPixel {
|
|
2227 |
Â
}
|
2228 |
Â
}
|
2229 |
Â
|
2230 |
-
if(isset($_POST['bulkProcessStop']))
|
2231 |
Â
{//stop an ongoing bulk processing
|
2232 |
Â
$this->prioQ->stopBulk();
|
2233 |
Â
if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
|
@@ -2236,9 +2355,9 @@ class WPShortPixel {
|
|
2236 |
Â
$this->_settings->cancelPointer = NULL;
|
2237 |
Â
}
|
2238 |
Â
|
2239 |
-
if(isset($_POST["bulkProcess"]))
|
2240 |
Â
{
|
2241 |
-
//set the thumbnails option
|
2242 |
Â
if ( isset($_POST['thumbnails']) ) {
|
2243 |
Â
$this->_settings->processThumbnails = 1;
|
2244 |
Â
} else {
|
@@ -2247,25 +2366,31 @@ class WPShortPixel {
|
|
2247 |
Â
//clean the custom files errors in order to process them again
|
2248 |
Â
if($this->_settings->hasCustomFolders) {
|
2249 |
Â
$this->spMetaDao->resetFailed();
|
Â
|
|
Â
|
|
2250 |
Â
}
|
2251 |
-
|
2252 |
Â
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_OPTIMIZE);
|
2253 |
Â
$this->_settings->customBulkPaused = 0;
|
2254 |
Â
self::log("BULK: Start: " . $this->prioQ->getStartBulkId() . ", stop: " . $this->prioQ->getStopBulkId() . " PrioQ: "
|
2255 |
Â
.json_encode($this->prioQ->get()));
|
2256 |
-
}//end bulk process was clicked
|
2257 |
-
|
2258 |
-
if(isset($_POST["bulkRestore"]))
|
2259 |
Â
{
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
2260 |
Â
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_RESTORE);
|
2261 |
Â
$this->_settings->customBulkPaused = 0;
|
2262 |
-
}//end bulk restore was clicked
|
2263 |
-
|
2264 |
-
if(isset($_POST["bulkCleanup"]))
|
2265 |
Â
{
|
2266 |
Â
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_CLEANUP);
|
2267 |
Â
$this->_settings->customBulkPaused = 0;
|
2268 |
-
}//end bulk restore was clicked
|
2269 |
Â
|
2270 |
Â
if(isset($_POST["bulkCleanupPending"]))
|
2271 |
Â
{
|
@@ -2279,7 +2404,7 @@ class WPShortPixel {
|
|
2279 |
Â
$this->_settings->customBulkPaused = 0;
|
2280 |
Â
}//resume was clicked
|
2281 |
Â
|
2282 |
-
if(isset($_POST["skipToCustom"]))
|
2283 |
Â
{
|
2284 |
Â
$this->_settings->skipToCustom = true;
|
2285 |
Â
}//resume was clicked
|
@@ -2298,18 +2423,18 @@ class WPShortPixel {
|
|
2298 |
Â
{
|
2299 |
Â
$msg = $this->bulkProgressMessage($this->prioQ->getDeltaBulkPercent(), $this->prioQ->getTimeRemaining());
|
2300 |
Â
|
2301 |
-
$this->view->displayBulkProcessingRunning($this->getPercent($quotaData), $msg, $quotaData['APICallsRemaining'], $this->getAverageCompression(),
|
2302 |
-
$this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE ? 0 :
|
2303 |
Â
( $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP
|
2304 |
Â
|| $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING ? -1 : ($pendingMeta !== null ? ($this->prioQ->bulkRunning() ? 3 : 2) : 1)), $quotaData);
|
2305 |
Â
|
2306 |
-
} else
|
2307 |
Â
{
|
2308 |
Â
if($this->prioQ->bulkRan() && !$this->prioQ->bulkPaused()) {
|
2309 |
Â
$this->prioQ->markBulkComplete();
|
2310 |
Â
}
|
2311 |
Â
|
2312 |
-
//image count
|
2313 |
Â
$thumbsProcessedCount = $this->_settings->thumbsCount;//amount of optimized thumbnails
|
2314 |
Â
$under5PercentCount = $this->_settings->under5Percent;//amount of under 5% optimized imgs.
|
2315 |
Â
|
@@ -2317,13 +2442,28 @@ class WPShortPixel {
|
|
2317 |
Â
$averageCompression = self::getAverageCompression();
|
2318 |
Â
$percent = $this->prioQ->bulkPaused() ? $this->getPercent($quotaData) : false;
|
2319 |
Â
|
2320 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
2321 |
Â
$this->prioQ->bulkRan(), $averageCompression, $this->_settings->fileCount,
|
2322 |
Â
self::formatBytes($this->_settings->savedSpace), $percent, $pendingMeta);
|
Â
|
|
2323 |
Â
}
|
2324 |
Â
}
|
2325 |
Â
//end bulk processing
|
2326 |
-
|
2327 |
Â
public function getPercent($quotaData) {
|
2328 |
Â
if($this->_settings->processThumbnails) {
|
2329 |
Â
return $quotaData["totalFiles"] ? min(99, round($quotaData["totalProcessedFiles"] *100.0 / $quotaData["totalFiles"])) : 0;
|
@@ -2331,7 +2471,7 @@ class WPShortPixel {
|
|
2331 |
Â
return $quotaData["mainFiles"] ? min(99, round($quotaData["mainProcessedFiles"] *100.0 / $quotaData["mainFiles"])) : 0;
|
2332 |
Â
}
|
2333 |
Â
}
|
2334 |
-
|
2335 |
Â
public function bulkProgressMessage($percent, $minutes) {
|
2336 |
Â
$timeEst = "";
|
2337 |
Â
self::log("bulkProgressMessage(): percent: " . $percent);
|
@@ -2352,10 +2492,10 @@ class WPShortPixel {
|
|
2352 |
Â
}
|
2353 |
Â
return $timeEst;
|
2354 |
Â
}
|
2355 |
-
|
2356 |
Â
public function emptyBackup(){
|
2357 |
Â
if(file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
2358 |
-
|
2359 |
Â
//extract all images from DB in an array. of course
|
2360 |
Â
// Simon: WHY?!!! commenting for now...
|
2361 |
Â
/*
|
@@ -2366,12 +2506,12 @@ class WPShortPixel {
|
|
2366 |
Â
'post_mime_type' => 'image'
|
2367 |
Â
));
|
2368 |
Â
*/
|
2369 |
-
|
2370 |
Â
//delete the actual files on disk
|
2371 |
Â
$this->deleteDir(SHORTPIXEL_BACKUP_FOLDER);//call a recursive function to empty files and sub-dirs in backup dir
|
2372 |
Â
}
|
2373 |
Â
}
|
2374 |
-
|
2375 |
Â
public function backupFolderIsEmpty() {
|
2376 |
Â
if(file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
2377 |
Â
return count(scandir(SHORTPIXEL_BACKUP_FOLDER)) > 2 ? false : true;
|
@@ -2384,14 +2524,14 @@ class WPShortPixel {
|
|
2384 |
Â
}
|
2385 |
Â
die(self::formatBytes(self::folderSize(SHORTPIXEL_BACKUP_FOLDER)));
|
2386 |
Â
}
|
2387 |
-
|
2388 |
Â
public function browseContent() {
|
2389 |
Â
if ( !current_user_can( 'manage_options' ) ) {
|
2390 |
Â
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
2391 |
Â
}
|
2392 |
-
|
2393 |
Â
$root = self::getCustomFolderBase();
|
2394 |
-
|
2395 |
Â
|
2396 |
Â
$postDir = rawurldecode($root.(isset($_POST['dir']) ? trim($_POST['dir']) : null ));
|
2397 |
Â
// set checkbox if multiSelect set to true
|
@@ -2403,7 +2543,7 @@ class WPShortPixel {
|
|
2403 |
Â
|
2404 |
Â
$files = scandir($postDir);
|
2405 |
Â
$returnDir = substr($postDir, strlen($root));
|
2406 |
-
|
2407 |
Â
natcasesort($files);
|
2408 |
Â
|
2409 |
Â
if( count($files) > 2 ) { // The 2 accounts for . and ..
|
@@ -2411,7 +2551,7 @@ class WPShortPixel {
|
|
2411 |
Â
foreach( $files as $file ) {
|
2412 |
Â
|
2413 |
Â
if($file == 'ShortpixelBackups' || ShortPixelMetaFacade::isMediaSubfolder($postDir . $file, false)) continue;
|
2414 |
-
|
2415 |
Â
$htmlRel = str_replace("'", "'", $returnDir . $file);
|
2416 |
Â
$htmlName = htmlentities($file);
|
2417 |
Â
$ext = preg_replace('/^.*\./', '', $file);
|
@@ -2431,27 +2571,53 @@ class WPShortPixel {
|
|
2431 |
Â
}
|
2432 |
Â
die();
|
2433 |
Â
}
|
2434 |
-
|
2435 |
Â
public function getComparerData() {
|
2436 |
Â
if (!isset($_POST['id']) || !current_user_can( 'upload_files' ) && !current_user_can( 'edit_posts' ) ) {
|
2437 |
Â
wp_die(json_encode((object)array('origUrl' => false, 'optUrl' => false, 'width' => 0, 'height' => 0)));
|
2438 |
Â
}
|
2439 |
-
|
2440 |
Â
$ret = array();
|
2441 |
Â
$handle = new ShortPixelMetaFacade($_POST['id']);
|
Â
|
|
2442 |
Â
$meta = $handle->getMeta();
|
2443 |
Â
$rawMeta = $handle->getRawMeta();
|
2444 |
Â
$backupUrl = content_url() . "/" . SHORTPIXEL_UPLOADS_NAME . "/" . SHORTPIXEL_BACKUP . "/";
|
2445 |
Â
$uploadsUrl = ShortPixelMetaFacade::getHomeUrl();
|
2446 |
Â
$urlBkPath = ShortPixelMetaFacade::returnSubDir($meta->getPath());
|
2447 |
Â
$ret['origUrl'] = $backupUrl . $urlBkPath . $meta->getName();
|
2448 |
-
|
2449 |
-
|
2450 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
2451 |
Â
|
2452 |
Â
die(json_encode((object)$ret));
|
2453 |
Â
}
|
2454 |
-
|
2455 |
Â
public function newApiKey() {
|
2456 |
Â
if ( !current_user_can( 'manage_options' ) ) {
|
2457 |
Â
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
@@ -2487,20 +2653,20 @@ class WPShortPixel {
|
|
2487 |
Â
if($body->Status == 'success') {
|
2488 |
Â
$key = trim($body->Details);
|
2489 |
Â
$validityData = $this->getQuotaInformation($key, true, true);
|
2490 |
-
if($validityData['APIKeyValid']) {
|
2491 |
Â
$this->_settings->apiKey = $key;
|
2492 |
Â
$this->_settings->verifiedKey = true;
|
2493 |
Â
}
|
2494 |
Â
}
|
2495 |
Â
die(json_encode($body));
|
2496 |
-
|
2497 |
Â
}
|
2498 |
-
|
2499 |
Â
public function proposeUpgrade() {
|
2500 |
Â
if ( !current_user_can( 'manage_options' ) ) {
|
2501 |
Â
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
2502 |
Â
}
|
2503 |
-
|
2504 |
Â
$stats = $this->countAllIfNeeded($this->_settings->currentStats, 300);
|
2505 |
Â
|
2506 |
Â
//$proposal = wp_remote_post($this->_settings->httpProto . "://shortpixel.com/propose-upgrade-frag", array(
|
@@ -2542,7 +2708,7 @@ class WPShortPixel {
|
|
2542 |
Â
die($proposal['body']);
|
2543 |
Â
|
2544 |
Â
}
|
2545 |
-
|
2546 |
Â
public static function getCustomFolderBase() {
|
2547 |
Â
if(is_main_site()) {
|
2548 |
Â
$base = get_home_path();
|
@@ -2552,12 +2718,12 @@ class WPShortPixel {
|
|
2552 |
Â
return realpath($up['basedir']);
|
2553 |
Â
}
|
2554 |
Â
}
|
2555 |
-
|
2556 |
Â
protected function fullRefreshCustomFolder($path, &$notice) {
|
2557 |
Â
$folder = $this->spMetaDao->getFolder($path);
|
2558 |
Â
$diff = $folder->checkFolderContents(array('ShortPixelCustomMetaDao', 'getPathFiles'));
|
2559 |
Â
}
|
2560 |
-
|
2561 |
Â
protected function refreshCustomFolders(&$notice, $ignore = false) {
|
2562 |
Â
$customFolders = array();
|
2563 |
Â
if($this->_settings->hasCustomFolders) {
|
@@ -2588,10 +2754,17 @@ class WPShortPixel {
|
|
2588 |
Â
}
|
2589 |
Â
|
2590 |
Â
protected static function alterHtaccess( $clear = false ){
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
2591 |
Â
if ( $clear ) {
|
2592 |
Â
insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', '');
|
Â
|
|
Â
|
|
2593 |
Â
} else {
|
2594 |
-
|
Â
|
|
2595 |
Â
<IfModule mod_rewrite.c>
|
2596 |
Â
RewriteEngine On
|
2597 |
Â
|
@@ -2629,7 +2802,11 @@ class WPShortPixel {
|
|
2629 |
Â
<IfModule mod_mime.c>
|
2630 |
Â
AddType image/webp .webp
|
2631 |
Â
</IfModule>
|
2632 |
-
'
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
2633 |
Â
/* insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', '
|
2634 |
Â
RewriteEngine On
|
2635 |
Â
RewriteBase /
|
@@ -2688,22 +2865,22 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2688 |
Â
if(isset($_GET['setsparchive'])) {
|
2689 |
Â
$this->_settings->downloadArchive = intval($_GET['setsparchive']);
|
2690 |
Â
}
|
2691 |
-
|
2692 |
Â
//check all custom folders and update meta table if files appeared
|
2693 |
Â
$customFolders = $this->refreshCustomFolders($notice, isset($_POST['removeFolder']) ? $_POST['removeFolder'] : null);
|
2694 |
-
|
2695 |
Â
if(isset($_POST['request']) && $_POST['request'] == 'request') {
|
2696 |
Â
//a new API Key was requested
|
2697 |
Â
if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
|
2698 |
-
|
2699 |
Â
}
|
2700 |
Â
else {
|
2701 |
-
$notice = array("status" => "error",
|
2702 |
Â
"msg" => __("Please provide a valid e-mail.",'shortpixel-image-optimiser')
|
2703 |
-
. "<BR> "
|
2704 |
Â
. __('For any question regarding obtaining your API Key, please contact us at ','shortpixel-image-optimiser')
|
2705 |
Â
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
2706 |
-
. __(' or ','shortpixel-image-optimiser')
|
2707 |
Â
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
2708 |
Â
}
|
2709 |
Â
}
|
@@ -2715,35 +2892,36 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2715 |
Â
$this->cloudflareApi->set_up($cfApi, $cfAuth, $cfZone);
|
2716 |
Â
}
|
2717 |
Â
|
2718 |
-
if( isset($_POST['save']) || isset($_POST['saveAdv'])
|
2719 |
Â
|| (isset($_POST['validate']) && $_POST['validate'] == "validate")
|
2720 |
Â
|| isset($_POST['removeFolder']) || isset($_POST['recheckFolder'])) {
|
2721 |
Â
|
2722 |
Â
//handle API Key - common for save and validate.
|
2723 |
Â
$_POST['key'] = trim(str_replace("*", "", isset($_POST['key']) ? $_POST['key'] : $this->_settings->apiKey)); //the API key might not be set if the editing is disabled.
|
2724 |
-
|
2725 |
Â
if ( strlen($_POST['key']) <> 20 ){
|
2726 |
Â
$KeyLength = strlen($_POST['key']);
|
2727 |
-
|
2728 |
-
$notice = array("status" => "error",
|
2729 |
Â
"msg" => sprintf(__("The key you provided has %s characters. The API key should have 20 characters, letters and numbers only.",'shortpixel-image-optimiser'), $KeyLength)
|
2730 |
-
. "<BR> <b>"
|
2731 |
-
. __('Please check that the API key is the same as the one you received in your confirmation email.','shortpixel-image-optimiser')
|
2732 |
-
. "</b><BR> "
|
2733 |
Â
. __('If this problem persists, please contact us at ','shortpixel-image-optimiser')
|
2734 |
Â
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
2735 |
-
. __(' or ','shortpixel-image-optimiser')
|
2736 |
Â
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
2737 |
Â
}
|
2738 |
Â
else {
|
Â
|
|
2739 |
Â
if(isset($_POST['save']) || isset($_POST['saveAdv'])) {
|
2740 |
Â
//these are needed for the call to api-status, set them first.
|
2741 |
-
$this->_settings->siteAuthUser = (isset($_POST['siteAuthUser']) ? $_POST['siteAuthUser'] : $this->_settings->siteAuthUser);
|
2742 |
-
$this->_settings->siteAuthPass = (isset($_POST['siteAuthPass']) ? $_POST['siteAuthPass'] : $this->_settings->siteAuthPass);
|
2743 |
Â
}
|
2744 |
Â
|
2745 |
Â
$validityData = $this->getQuotaInformation($_POST['key'], true, isset($_POST['validate']) && $_POST['validate'] == "validate", $_POST);
|
2746 |
-
|
2747 |
Â
$this->_settings->apiKey = $_POST['key'];
|
2748 |
Â
if($validityData['APIKeyValid']) {
|
2749 |
Â
if(isset($_POST['validate']) && $_POST['validate'] == "validate") {
|
@@ -2758,7 +2936,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2758 |
Â
$notice = array("status" => "warn", "msg" => __("API Key is valid but your site is not accessible from our servers. Please make sure that your server is accessible from the Internet before using the API or otherwise we won't be able to optimize them.",'shortpixel-image-optimiser'));
|
2759 |
Â
} else {
|
2760 |
Â
if ( function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"))
|
2761 |
-
$notice = array("status" => "success", "msg" => __("Great, your API Key is valid! <br>You seem to be running a multisite, please note that API Key can also be configured in wp-config.php like this:",'shortpixel-image-optimiser')
|
2762 |
Â
. "<BR> <b>define('SHORTPIXEL_API_KEY', '".$this->_settings->apiKey."');</b>");
|
2763 |
Â
else
|
2764 |
Â
$notice = array("status" => "success", "msg" => __('Great, your API Key is valid. Please take a few moments to review the plugin settings below before starting to optimize your images.','shortpixel-image-optimiser'));
|
@@ -2767,8 +2945,8 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2767 |
Â
$this->_settings->verifiedKey = true;
|
2768 |
Â
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
2769 |
Â
if ( !file_exists(SHORTPIXEL_BACKUP_FOLDER) && !@mkdir(SHORTPIXEL_BACKUP_FOLDER, 0777, true) )
|
2770 |
-
$notice = array("status" => "error",
|
2771 |
-
"msg" => sprintf(__("There is something preventing us to create a new folder for backing up your original files.<BR>Please make sure that folder <b>%s</b> has the necessary write and read rights.",'shortpixel-image-optimiser'),
|
2772 |
Â
WP_CONTENT_DIR . '/' . SHORTPIXEL_UPLOADS_NAME ));
|
2773 |
Â
} else {
|
2774 |
Â
if(isset($_POST['validate'])) {
|
@@ -2781,27 +2959,27 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2781 |
Â
|
2782 |
Â
//if save button - we process the rest of the form elements
|
2783 |
Â
if(isset($_POST['save']) || isset($_POST['saveAdv'])) {
|
2784 |
-
$this->_settings->compressionType = $_POST['compressionType'];
|
2785 |
Â
if(isset($_POST['thumbnails'])) { $this->_settings->processThumbnails = 1; } else { $this->_settings->processThumbnails = 0; }
|
2786 |
Â
if(isset($_POST['backupImages'])) { $this->_settings->backupImages = 1; } else { $this->_settings->backupImages = 0; }
|
2787 |
Â
if(isset($_POST['cmyk2rgb'])) { $this->_settings->CMYKtoRGBconversion = 1; } else { $this->_settings->CMYKtoRGBconversion = 0; }
|
2788 |
Â
$this->_settings->keepExif = isset($_POST['removeExif']) ? 0 : 1;
|
2789 |
Â
//delete_option('wp-short-pixel-keep-exif');
|
2790 |
Â
$this->_settings->resizeImages = (isset($_POST['resize']) ? 1: 0);
|
2791 |
-
$this->_settings->resizeType = (isset($_POST['resize_type']) ? $_POST['resize_type']: false);
|
2792 |
Â
$this->_settings->resizeWidth = (isset($_POST['width']) ? intval($_POST['width']): $this->_settings->resizeWidth);
|
2793 |
Â
$this->_settings->resizeHeight = (isset($_POST['height']) ? intval($_POST['height']): $this->_settings->resizeHeight);
|
2794 |
Â
$uploadPath = realpath(SHORTPIXEL_UPLOADS_BASE);
|
2795 |
Â
|
2796 |
-
if(isset($_POST['nextGen'])) {
|
2797 |
Â
WpShortPixelDb::checkCustomTables(); // check if custom tables are created, if not, create them
|
2798 |
Â
$prevNextGen = $this->_settings->includeNextGen;
|
2799 |
-
$this->_settings->includeNextGen = 1;
|
2800 |
Â
$ret = $this->addNextGenGalleriesToCustom($prevNextGen);
|
2801 |
Â
$folderMsg = $ret["message"];
|
2802 |
Â
$customFolders = $ret["customFolders"];
|
2803 |
-
} else {
|
2804 |
-
$this->_settings->includeNextGen = 0;
|
2805 |
Â
}
|
2806 |
Â
if(isset($_POST['addCustomFolder']) && strlen($_POST['addCustomFolder']) > 0) {
|
2807 |
Â
$folderMsg = $this->spMetaDao->newFolderFromPath(stripslashes($_POST['addCustomFolder']), $uploadPath, self::getCustomFolderBase());
|
@@ -2809,9 +2987,9 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2809 |
Â
$notice = array("status" => "success", "msg" => __('Folder added successfully.','shortpixel-image-optimiser'));
|
2810 |
Â
}
|
2811 |
Â
$customFolders = $this->spMetaDao->getFolders();
|
2812 |
-
$this->_settings->hasCustomFolders = time();
|
2813 |
Â
}
|
2814 |
-
|
2815 |
Â
$this->_settings->createWebp = (isset($_POST['createWebp']) ? 1: 0);
|
2816 |
Â
|
2817 |
Â
|
@@ -2856,11 +3034,11 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2856 |
Â
$this->_settings->optimizeUnlisted = (isset($_POST['optimizeUnlisted']) ? 1: 0);
|
2857 |
Â
$this->_settings->optimizePdfs = (isset($_POST['optimizePdfs']) ? 1: 0);
|
2858 |
Â
$this->_settings->png2jpg = (isset($_POST['png2jpg']) ? (isset($_POST['png2jpgForce']) ? 2 : 1): 0);
|
2859 |
-
|
2860 |
Â
//die(var_dump($_POST['excludePatterns']));
|
2861 |
-
|
2862 |
Â
if(isset($_POST['excludePatterns']) && strlen($_POST['excludePatterns'])) {
|
2863 |
-
$patterns = array();
|
2864 |
Â
$items = explode(',', $_POST['excludePatterns']);
|
2865 |
Â
foreach($items as $pat) {
|
2866 |
Â
$parts = explode(':', $pat);
|
@@ -2879,18 +3057,18 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2879 |
Â
$this->_settings->excludeSizes = (isset($_POST['excludeSizes']) ? $_POST['excludeSizes']: array());
|
2880 |
Â
|
2881 |
Â
//Redirect to bulk processing if requested
|
2882 |
-
if( isset($_POST['save']) && $_POST['save'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')
|
2883 |
Â
|| isset($_POST['saveAdv']) && $_POST['saveAdv'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')) {
|
2884 |
Â
wp_redirect("upload.php?page=wp-short-pixel-bulk");
|
2885 |
Â
exit();
|
2886 |
-
}
|
2887 |
Â
}
|
2888 |
-
if(isset($_POST['removeFolder']) && strlen(($_POST['removeFolder']))) {
|
2889 |
Â
$this->spMetaDao->removeFolder($_POST['removeFolder']);
|
2890 |
Â
$customFolders = $this->spMetaDao->getFolders();
|
2891 |
Â
$_POST["saveAdv"] = true;
|
2892 |
Â
}
|
2893 |
-
if(isset($_POST['recheckFolder']) && strlen(($_POST['recheckFolder']))) {
|
2894 |
Â
//$folder->fullRefreshCustomFolder($_POST['recheckFolder']); //aici singura solutie pare callback care spune daca exita url-ul complet
|
2895 |
Â
}
|
2896 |
Â
}
|
@@ -2899,14 +3077,14 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2899 |
Â
if(isset($_REQUEST['noheader'])) {
|
2900 |
Â
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
2901 |
Â
}
|
2902 |
-
|
2903 |
Â
//empty backup
|
2904 |
Â
if(isset($_POST['emptyBackup'])) {
|
2905 |
Â
$this->emptyBackup();
|
2906 |
Â
}
|
2907 |
-
|
2908 |
Â
$quotaData = $this->checkQuotaAndAlert(isset($validityData) ? $validityData : null, isset($_GET['checkquota']));
|
2909 |
-
|
2910 |
Â
if($this->hasNextGen) {
|
2911 |
Â
$ngg = array_map(array('ShortPixelNextGenAdapter','pathToAbsolute'), ShortPixelNextGenAdapter::getGalleries());
|
2912 |
Â
//die(var_dump($ngg));
|
@@ -2920,7 +3098,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2920 |
Â
$showApiKey = ( (is_main_site() || (function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY")))
|
2921 |
Â
&& !defined("SHORTPIXEL_HIDE_API_KEY"));
|
2922 |
Â
$editApiKey = !defined("SHORTPIXEL_API_KEY") && $showApiKey;
|
2923 |
-
|
2924 |
Â
if($this->_settings->verifiedKey) {
|
2925 |
Â
$fileCount = number_format($this->_settings->fileCount);
|
2926 |
Â
$savedSpace = self::formatBytes($this->_settings->savedSpace,2);
|
@@ -2941,17 +3119,17 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2941 |
Â
$cloudflareAPI = true;
|
2942 |
Â
|
2943 |
Â
$this->view->displaySettings($showApiKey, $editApiKey,
|
2944 |
-
$quotaData, $notice, $resources, $averageCompression, $savedSpace, $savedBandwidth, $remainingImages,
|
2945 |
-
$totalCallsMade, $fileCount, null /*folder size now on AJAX*/, $customFolders,
|
2946 |
Â
$folderMsg, $folderMsg ? $addedFolder : false, isset($_POST['saveAdv']), $cloudflareAPI, $htaccessWriteable, $isNginx );
|
2947 |
Â
} else {
|
2948 |
-
$this->view->displaySettings($showApiKey, $editApiKey, $quotaData, $notice);
|
2949 |
Â
}
|
2950 |
-
|
2951 |
Â
}
|
2952 |
Â
|
2953 |
Â
public function addNextGenGalleriesToCustom($silent) {
|
2954 |
-
$customFolders = array();
|
2955 |
Â
$folderMsg = "";
|
2956 |
Â
if($this->_settings->includeNextGen) {
|
2957 |
Â
//add the NextGen galleries to custom folders
|
@@ -2962,30 +3140,30 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2962 |
Â
$msg = $this->spMetaDao->newFolderFromPath($gallery, ABSPATH, self::getCustomFolderBase());
|
2963 |
Â
}
|
2964 |
Â
$folderMsg .= $msg;
|
2965 |
-
$this->_settings->hasCustomFolders = time();
|
2966 |
Â
}
|
2967 |
Â
$customFolders = $this->spMetaDao->getFolders();
|
2968 |
Â
}
|
2969 |
Â
return array("message" => $silent? "" : $folderMsg, "customFolders" => $customFolders);
|
2970 |
Â
}
|
2971 |
-
|
2972 |
Â
public function getAverageCompression(){
|
2973 |
-
return $this->_settings->totalOptimized > 0
|
2974 |
-
? round(( 1 - ( $this->_settings->totalOptimized / $this->_settings->totalOriginal ) ) * 100, 2)
|
2975 |
Â
: 0;
|
2976 |
Â
}
|
2977 |
-
|
2978 |
Â
/**
|
2979 |
-
*
|
2980 |
Â
* @param type $apiKey
|
2981 |
Â
* @param type $appendUserAgent
|
2982 |
Â
* @param type $validate - true if we are validating the api key, send also the domain name and number of pics
|
2983 |
Â
* @return type
|
2984 |
Â
*/
|
2985 |
Â
public function getQuotaInformation($apiKey = null, $appendUserAgent = false, $validate = false, $settings = false) {
|
2986 |
-
|
2987 |
Â
if(is_null($apiKey)) { $apiKey = $this->_settings->apiKey; }
|
2988 |
-
|
2989 |
Â
if($this->_settings->httpProto != 'https' && $this->_settings->httpProto != 'http') {
|
2990 |
Â
$this->_settings->httpProto = 'https';
|
2991 |
Â
}
|
@@ -3013,8 +3191,8 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3013 |
Â
$argsStr .= "&host={$args['body']['host']}";
|
3014 |
Â
if(strlen($this->_settings->siteAuthUser)) {
|
3015 |
Â
$args['body']['user'] = $this->_settings->siteAuthUser;
|
3016 |
-
$args['body']['pass'] =
|
3017 |
-
$argsStr .=
|
3018 |
Â
}
|
3019 |
Â
if($settings !== false) {
|
3020 |
Â
$args['body']['Settings'] = $settings;
|
@@ -3030,11 +3208,11 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3030 |
Â
$response = wp_remote_post($requestURL, $args);
|
3031 |
Â
|
3032 |
Â
$comm['A: ' . (number_format(microtime(true) - $time, 2))] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
3033 |
-
|
3034 |
Â
//some hosting providers won't allow https:// POST connections so we try http:// as well
|
3035 |
Â
if(is_wp_error( $response )) {
|
3036 |
Â
//echo("protocol " . $this->_settings->httpProto . " failed. switching...");
|
3037 |
-
$requestURL = $this->_settings->httpProto == 'https' ?
|
3038 |
Â
str_replace('https://', 'http://', $requestURL) :
|
3039 |
Â
str_replace('http://', 'https://', $requestURL);
|
3040 |
Â
// add or remove the sslverify
|
@@ -3043,14 +3221,14 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3043 |
Â
} else {
|
3044 |
Â
unset($args['sslverify']);
|
3045 |
Â
}
|
3046 |
-
$response = wp_remote_post($requestURL, $args);
|
3047 |
Â
$comm['B: ' . (number_format(microtime(true) - $time, 2))] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
3048 |
-
|
3049 |
Â
if(!is_wp_error( $response )){
|
3050 |
Â
$this->_settings->httpProto = ($this->_settings->httpProto == 'https' ? 'http' : 'https');
|
3051 |
Â
//echo("protocol " . $this->_settings->httpProto . " succeeded");
|
3052 |
Â
} else {
|
3053 |
-
//echo("protocol " . $this->_settings->httpProto . " failed too");
|
3054 |
Â
}
|
3055 |
Â
}
|
3056 |
Â
//Second fallback to HTTP get
|
@@ -3079,7 +3257,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3079 |
Â
$defaultData = is_array($this->_settings->currentStats) ? array_merge( $this->_settings->currentStats, $defaultData) : $defaultData;
|
3080 |
Â
|
3081 |
Â
if(is_object($response) && get_class($response) == 'WP_Error') {
|
3082 |
-
|
3083 |
Â
$urlElements = parse_url($requestURL);
|
3084 |
Â
$portConnect = @fsockopen($urlElements['host'],8,$errno,$errstr,15);
|
3085 |
Â
if(!$portConnect) {
|
@@ -3103,10 +3281,10 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3103 |
Â
return $defaultData;
|
3104 |
Â
}
|
3105 |
Â
|
3106 |
-
if ( ( $data->APICallsMade + $data->APICallsMadeOneTime ) < ( $data->APICallsQuota + $data->APICallsQuotaOneTime ) ) //reset quota exceeded flag -> user is allowed to process more images.
|
3107 |
Â
$this->resetQuotaExceeded();
|
3108 |
Â
else
|
3109 |
-
$this->_settings->quotaExceeded = 1;//activate quota limiting
|
3110 |
Â
|
3111 |
Â
//if a non-valid status exists, delete it
|
3112 |
Â
$lastStatus = $this->_settings->bulkLastStatus = null;
|
@@ -3135,7 +3313,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3135 |
Â
|
3136 |
Â
return $dataArray;
|
3137 |
Â
}
|
3138 |
-
|
3139 |
Â
public function resetQuotaExceeded() {
|
3140 |
Â
if( $this->_settings->quotaExceeded == 1) {
|
3141 |
Â
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
@@ -3155,7 +3333,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3155 |
Â
return;
|
3156 |
Â
}
|
3157 |
Â
|
3158 |
-
$file = get_attached_file($id);
|
3159 |
Â
$data = ShortPixelMetaFacade::sanitizeMeta(wp_get_attachment_metadata($id));
|
3160 |
Â
|
3161 |
Â
if($extended && isset($_GET['SHORTPIXEL_DEBUG'])) {
|
@@ -3175,25 +3353,25 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3175 |
Â
$this->view->renderCustomColumn($id, $renderData, $extended);
|
3176 |
Â
return;
|
3177 |
Â
}
|
3178 |
-
|
3179 |
Â
//empty data means document, we handle only PDF
|
3180 |
Â
elseif (empty($data)) { //TODO asta devine if si decomentam returnurile
|
3181 |
Â
if($fileExtension == "pdf") {
|
3182 |
Â
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
3183 |
Â
$renderData['message'] = __('PDF not processed.','shortpixel-image-optimiser');
|
3184 |
-
}
|
3185 |
Â
else { //Optimization N/A
|
3186 |
Â
$renderData['status'] = 'n/a';
|
3187 |
Â
}
|
3188 |
Â
$this->view->renderCustomColumn($id, $renderData, $extended);
|
3189 |
Â
return;
|
3190 |
-
}
|
3191 |
-
|
3192 |
Â
if(!isset($data['ShortPixelImprovement'])) { //new image
|
3193 |
Â
$data['ShortPixelImprovement'] = '';
|
3194 |
Â
}
|
3195 |
-
|
3196 |
-
if( is_numeric($data['ShortPixelImprovement'])
|
3197 |
Â
&& !($data['ShortPixelImprovement'] == 0 && isset($data['ShortPixel']['WaitingProcessing'])) //for images that erroneously have ShortPixelImprovement = 0 when WaitingProcessing
|
3198 |
Â
) { //already optimized
|
3199 |
Â
$sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
|
@@ -3209,7 +3387,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3209 |
Â
}
|
3210 |
Â
}
|
3211 |
Â
}
|
3212 |
-
|
3213 |
Â
$renderData['status'] = $fileExtension == "pdf" ? 'pdfOptimized' : 'imgOptimized';
|
3214 |
Â
$renderData['percent'] = $this->optimizationPercentIfPng2Jpg($data);
|
3215 |
Â
$renderData['bonus'] = ($data['ShortPixelImprovement'] < 5);
|
@@ -3226,7 +3404,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3226 |
Â
$renderData['exifKept'] = isset($data['ShortPixel']['exifKept']) ? $data['ShortPixel']['exifKept'] : null;
|
3227 |
Â
$renderData['png2jpg'] = isset($data['ShortPixelPng2Jpg']) ? $data['ShortPixelPng2Jpg'] : 0;
|
3228 |
Â
$renderData['date'] = isset($data['ShortPixel']['date']) ? $data['ShortPixel']['date'] : null;
|
3229 |
-
$renderData['quotaExceeded'] = $quotaExceeded;
|
3230 |
Â
$webP = 0;
|
3231 |
Â
if($extended) {
|
3232 |
Â
if(file_exists(dirname($file) . '/' . ShortPixelAPI::MB_basename($file, '.'.$fileExtension) . '.webp' )){
|
@@ -3279,11 +3457,11 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3279 |
Â
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
3280 |
Â
$sizes = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
|
3281 |
Â
$renderData['thumbsTotal'] = $sizes;
|
3282 |
-
$renderData['message'] = ($fileExtension == "pdf" ? 'PDF' : __('Image','shortpixel-image-optimiser'))
|
3283 |
Â
. __(' not processed.','shortpixel-image-optimiser')
|
3284 |
-
. ' (<a href="https://shortpixel.com/image-compression-test?site-url=' . urlencode(ShortPixelMetaFacade::safeGetAttachmentUrl($id)) . '" target="_blank">'
|
3285 |
Â
. __('Test for free','shortpixel-image-optimiser') . '</a>)';
|
3286 |
-
}
|
3287 |
Â
$this->view->renderCustomColumn($id, $renderData, $extended);
|
3288 |
Â
}
|
3289 |
Â
}
|
@@ -3358,11 +3536,11 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3358 |
Â
);
|
3359 |
Â
}
|
3360 |
Â
}
|
3361 |
-
|
3362 |
Â
function shortpixelInfoBoxContent( $post ) {
|
3363 |
Â
$this->generateCustomColumn( 'wp-shortPixel', $post->ID, true );
|
3364 |
Â
}
|
3365 |
-
|
3366 |
Â
public function onDeleteImage($post_id) {
|
3367 |
Â
$itemHandler = new ShortPixelMetaFacade($post_id);
|
3368 |
Â
$urlsPaths = $itemHandler->getURLsAndPATHs(true, false, true, array(), true);
|
@@ -3394,9 +3572,9 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3394 |
Â
public function columns( $defaults ) {
|
3395 |
Â
$defaults['wp-shortPixel'] = __('ShortPixel Compression', 'shortpixel-image-optimiser');
|
3396 |
Â
if(current_user_can( 'manage_options' )) {
|
3397 |
-
$defaults['wp-shortPixel'] .=
|
3398 |
-
' <a href="options-general.php?page=wp-shortpixel#stats" title="'
|
3399 |
-
. __('ShortPixel Statistics','shortpixel-image-optimiser')
|
3400 |
Â
. '"><span class="dashicons dashicons-dashboard"></span></a>';
|
3401 |
Â
}
|
3402 |
Â
return $defaults;
|
@@ -3413,13 +3591,13 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3413 |
Â
public function nggCountColumns( $count ) {
|
3414 |
Â
return $count + 1;
|
3415 |
Â
}
|
3416 |
-
|
3417 |
Â
public function nggColumnHeader( $default ) {
|
3418 |
Â
return __('ShortPixel Compression','shortpixel-image-optimiser');
|
3419 |
Â
}
|
3420 |
Â
|
3421 |
Â
public function nggColumnContent( $unknown, $picture ) {
|
3422 |
-
|
3423 |
Â
$meta = $this->spMetaDao->getMetaForPath($picture->imagePath);
|
3424 |
Â
if($meta) {
|
3425 |
Â
switch($meta->getStatus()) {
|
@@ -3436,7 +3614,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3436 |
Â
'thumbsTotal' => 0,
|
3437 |
Â
'retinasOpt' => 0,
|
3438 |
Â
'backup' => true
|
3439 |
-
));
|
3440 |
Â
break;
|
3441 |
Â
}
|
3442 |
Â
} else {
|
@@ -3448,7 +3626,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3448 |
Â
'thumbsTotal' => 0,
|
3449 |
Â
'retinasOpt' => 0,
|
3450 |
Â
'message' => "Not optimized"
|
3451 |
-
));
|
3452 |
Â
}
|
3453 |
Â
// return var_dump($meta);
|
3454 |
Â
}
|
@@ -3470,17 +3648,17 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3470 |
Â
|
3471 |
Â
return round($bytes, $precision) . ' ' . $units[$pow];
|
3472 |
Â
}
|
3473 |
-
|
3474 |
Â
public function isProcessable($ID, $excludeExtensions = array()) {
|
3475 |
Â
$excludePatterns = $this->_settings->excludePatterns;
|
3476 |
Â
return self::_isProcessable($ID, $excludeExtensions, $excludePatterns);
|
3477 |
Â
}
|
3478 |
-
|
3479 |
Â
public function isProcessablePath($path, $excludeExtensions = array()) {
|
3480 |
Â
$excludePatterns = $this->_settings->excludePatterns;
|
3481 |
Â
return self::_isProcessablePath($path, $excludeExtensions, $excludePatterns);
|
3482 |
Â
}
|
3483 |
-
|
3484 |
Â
static public function _isProcessable($ID, $excludeExtensions = array(), $excludePatterns = array(), $meta = false) {
|
3485 |
Â
$path = get_attached_file($ID);//get the full file PATH
|
3486 |
Â
if(isset($excludePatterns) && is_array($excludePatterns)) {
|
@@ -3494,10 +3672,10 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3494 |
Â
}
|
3495 |
Â
}
|
3496 |
Â
}
|
3497 |
-
}
|
3498 |
Â
return $path ? self::_isProcessablePath($path, $excludeExtensions, $excludePatterns) : false;
|
3499 |
Â
}
|
3500 |
-
|
3501 |
Â
static public function _isProcessablePath($path, $excludeExtensions = array(), $excludePatterns = array()) {
|
3502 |
Â
$pathParts = pathinfo($path);
|
3503 |
Â
$ext = isset($pathParts['extension']) ? $pathParts['extension'] : false;
|
@@ -3527,7 +3705,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3527 |
Â
$heightBounds = isset($ranges[1]) ? explode("-", $ranges[1]) : false;
|
3528 |
Â
if(!isset($heightBounds[1])) $heightBounds[1] = $heightBounds[0];
|
3529 |
Â
if( $width >= 0 + $widthBounds[0] && $width <= 0 + $widthBounds[1]
|
3530 |
-
&& ( $heightBounds === false
|
3531 |
Â
|| ($height >= 0 + $heightBounds[0] && $height <= 0 + $heightBounds[1]))) {
|
3532 |
Â
return false;
|
3533 |
Â
}
|
@@ -3544,7 +3722,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3544 |
Â
public function getURLsAndPATHs($itemHandler, $meta = NULL, $onlyThumbs = false) {
|
3545 |
Â
return $itemHandler->getURLsAndPATHs($this->_settings->processThumbnails, $onlyThumbs, $this->_settings->optimizeRetina, $this->_settings->excludeSizes);
|
3546 |
Â
}
|
3547 |
-
|
3548 |
Â
|
3549 |
Â
public static function deleteDir($dirPath) {
|
3550 |
Â
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
|
@@ -3570,7 +3748,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3570 |
Â
}
|
3571 |
Â
$cleanPath = rtrim($path, '/'). '/';
|
3572 |
Â
foreach($files as $t) {
|
3573 |
-
if ($t<>"." && $t<>"..")
|
3574 |
Â
{
|
3575 |
Â
$currentFile = $cleanPath . $t;
|
3576 |
Â
if (is_dir($currentFile)) {
|
@@ -3585,7 +3763,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3585 |
Â
}
|
3586 |
Â
return $total_size;
|
3587 |
Â
}
|
3588 |
-
|
3589 |
Â
public function migrateBackupFolder() {
|
3590 |
Â
$oldBackupFolder = WP_CONTENT_DIR . '/' . SHORTPIXEL_BACKUP;
|
3591 |
Â
|
@@ -3612,7 +3790,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3612 |
Â
@mkdir(SHORTPIXEL_BACKUP_FOLDER);
|
3613 |
Â
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER.'/'.SHORTPIXEL_UPLOADS_NAME);
|
3614 |
Â
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {//just in case..
|
3615 |
-
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER);
|
3616 |
Â
}
|
3617 |
Â
}
|
3618 |
Â
//then create the wp-content level if not present
|
@@ -3621,7 +3799,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3621 |
Â
@mkdir(SHORTPIXEL_BACKUP_FOLDER);
|
3622 |
Â
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER.'/' . basename(WP_CONTENT_DIR));
|
3623 |
Â
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {//just in case..
|
3624 |
-
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER);
|
3625 |
Â
}
|
3626 |
Â
}
|
3627 |
Â
return;
|
@@ -3644,7 +3822,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3644 |
Â
}
|
3645 |
Â
return $sizes;
|
3646 |
Â
}
|
3647 |
-
|
3648 |
Â
function getMaxIntermediateImageSize() {
|
3649 |
Â
global $_wp_additional_image_sizes;
|
3650 |
Â
|
@@ -3667,7 +3845,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3667 |
Â
return array('width' => max(100, $width), 'height' => max(100, $height));
|
3668 |
Â
}
|
3669 |
Â
|
3670 |
-
public function getOtherCompressionTypes($compressionType = false) {
|
3671 |
Â
return array_values(array_diff(array(0, 1, 2), array(0 + $compressionType)));
|
3672 |
Â
}
|
3673 |
Â
|
@@ -3753,11 +3931,11 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3753 |
Â
public function getApiKey() {
|
3754 |
Â
return $this->_settings->apiKey;
|
3755 |
Â
}
|
3756 |
-
|
3757 |
Â
public function getPrioQ() {
|
3758 |
Â
return $this->prioQ;
|
3759 |
Â
}
|
3760 |
-
|
3761 |
Â
public function backupImages() {
|
3762 |
Â
return $this->_settings->backupImages;
|
3763 |
Â
}
|
@@ -3765,11 +3943,11 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3765 |
Â
public function processThumbnails() {
|
3766 |
Â
return $this->_settings->processThumbnails;
|
3767 |
Â
}
|
3768 |
-
|
3769 |
Â
public function getCMYKtoRGBconversion() {
|
3770 |
Â
return $this->_settings->CMYKtoRGBconversion;
|
3771 |
Â
}
|
3772 |
-
|
3773 |
Â
public function getSettings() {
|
3774 |
Â
return $this->_settings;
|
3775 |
Â
}
|
@@ -3801,7 +3979,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3801 |
Â
public function hasNextGen() {
|
3802 |
Â
return $this->hasNextGen;
|
3803 |
Â
}
|
3804 |
-
|
3805 |
Â
public function getSpMetaDao() {
|
3806 |
Â
return $this->spMetaDao;
|
3807 |
Â
}
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
class WPShortPixel {
|
4 |
+
|
5 |
Â
const BULK_EMPTY_QUEUE = 0;
|
6 |
+
|
7 |
Â
private $_apiInterface = null;
|
8 |
Â
private $_settings = null;
|
9 |
Â
private $prioQ = null;
|
10 |
Â
private $view = null;
|
11 |
+
private $thumbnailsRegenerating = array();
|
12 |
+
|
13 |
Â
private $hasNextGen = false;
|
14 |
Â
private $spMetaDao = null;
|
15 |
+
|
16 |
Â
private $jsSuffix = '.min.js';
|
17 |
Â
|
18 |
Â
private $timer;
|
19 |
+
|
20 |
Â
public static $PROCESSABLE_EXTENSIONS = array('jpg', 'jpeg', 'gif', 'png', 'pdf');
|
21 |
Â
|
22 |
Â
public function __construct() {
|
27 |
Â
}
|
28 |
Â
|
29 |
Â
load_plugin_textdomain('shortpixel-image-optimiser', false, plugin_basename(dirname( SHORTPIXEL_PLUGIN_FILE )).'/lang');
|
30 |
+
|
31 |
Â
$isAdminUser = current_user_can( 'manage_options' );
|
32 |
+
|
33 |
Â
$this->_settings = new WPShortPixelSettings();
|
34 |
Â
$this->_apiInterface = new ShortPixelAPI($this->_settings);
|
35 |
Â
$this->cloudflareApi = new ShortPixelCloudFlareApi($this->_settings->cloudflareEmail, $this->_settings->cloudflareAuthKey, $this->_settings->cloudflareZoneID);
|
37 |
Â
$this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $this->_settings->excludePatterns);
|
38 |
Â
$this->prioQ = new ShortPixelQueue($this, $this->_settings);
|
39 |
Â
$this->view = new ShortPixelView($this);
|
40 |
+
|
41 |
+
$controllerClass = ShortPixelTools::namespaceit('ShortPixelController');
|
42 |
+
$controllerClass::init(); // load all subclassed controllers.
|
43 |
+
|
44 |
Â
define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
|
45 |
Â
|
46 |
+
if( !defined('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES')) {
|
47 |
+
if(is_plugin_active('envira-gallery/envira-gallery.php') || is_plugin_active('soliloquy-lite/soliloquy-lite.php') || is_plugin_active('soliloquy/soliloquy.php')) {
|
48 |
+
define('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES', '_c,_tl,_tr,_br,_bl');
|
49 |
+
}
|
50 |
+
elseif(defined('SHORTPIXEL_CUSTOM_THUMB_SUFFIX')) {
|
51 |
+
define('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES', SHORTPIXEL_CUSTOM_THUMB_SUFFIX);
|
52 |
+
}
|
53 |
Â
}
|
54 |
Â
|
55 |
Â
$this->setDefaultViewModeList();//set default mode as list. only @ first run
|
59 |
Â
add_filter( 'plugin_action_links_' . plugin_basename(SHORTPIXEL_PLUGIN_FILE), array(&$this, 'generatePluginLinks'));//for plugin settings page
|
60 |
Â
|
61 |
Â
//add_action( 'admin_footer', array(&$this, 'handleImageProcessing'));
|
62 |
+
|
63 |
Â
//Media custom column
|
64 |
Â
add_filter( 'manage_media_columns', array( &$this, 'columns' ) );//add media library column header
|
65 |
Â
add_action( 'manage_media_custom_column', array( &$this, 'generateCustomColumn' ), 10, 2 );//generate the media library column
|
71 |
Â
add_action( 'add_meta_boxes', array( &$this, 'shortpixelInfoBox') );
|
72 |
Â
//for cleaning up the WebP images when an attachment is deleted
|
73 |
Â
add_action( 'delete_attachment', array( &$this, 'onDeleteImage') );
|
74 |
+
|
75 |
Â
//for NextGen
|
76 |
Â
if($this->_settings->hasCustomFolders) {
|
77 |
Â
add_filter( 'ngg_manage_images_columns', array( &$this, 'nggColumns' ) );
|
81 |
Â
// hook on the NextGen gallery list update
|
82 |
Â
add_action('ngg_update_addgallery_page', array( &$this, 'addNextGenGalleriesToCustom'));
|
83 |
Â
}
|
84 |
+
|
85 |
Â
// integration with WP/LR Sync plugin
|
86 |
Â
add_action( 'wplr_update_media', array( &$this, 'onWpLrUpdateMedia' ), 10, 2);
|
87 |
Â
|
96 |
Â
//add settings page
|
97 |
Â
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
98 |
Â
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
99 |
+
|
100 |
Â
add_action('wp_ajax_shortpixel_browse_content', array(&$this, 'browseContent'));
|
101 |
Â
add_action('wp_ajax_shortpixel_get_backup_size', array(&$this, 'getBackupSize'));
|
102 |
Â
add_action('wp_ajax_shortpixel_get_comparer_data', array(&$this, 'getComparerData'));
|
103 |
Â
|
104 |
Â
add_action('wp_ajax_shortpixel_new_api_key', array(&$this, 'newApiKey'));
|
105 |
Â
add_action('wp_ajax_shortpixel_propose_upgrade', array(&$this, 'proposeUpgrade'));
|
106 |
+
|
107 |
Â
add_action( 'delete_attachment', array( &$this, 'handleDeleteAttachmentInBackup' ) );
|
108 |
Â
add_action( 'load-upload.php', array( &$this, 'handleCustomBulk'));
|
109 |
Â
|
115 |
Â
add_action('wp_ajax_shortpixel_optimize_thumbs', array(&$this, 'handleOptimizeThumbs'));
|
116 |
Â
|
117 |
Â
//toolbar notifications
|
118 |
+
add_action( 'admin_bar_menu', array( &$this, 'toolbar_shortpixel_processing'), 999 );
|
119 |
Â
//deactivate plugin
|
120 |
Â
add_action( 'admin_post_shortpixel_deactivate_plugin', array(&$this, 'deactivatePlugin'));
|
121 |
Â
//only if the key is not yet valid or the user hasn't bought any credits.
|
126 |
Â
new ShortPixelFeedback( SHORTPIXEL_PLUGIN_FILE, 'shortpixel-image-optimiser', $this->_settings->apiKey, $this);
|
127 |
Â
}
|
128 |
Â
}
|
129 |
+
|
130 |
Â
//automatic optimization
|
131 |
Â
add_action( 'wp_ajax_shortpixel_image_processing', array( &$this, 'handleImageProcessing') );
|
132 |
Â
//manual optimization
|
140 |
Â
add_action('wp_ajax_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
141 |
Â
add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
142 |
Â
//This adds the constants used in PHP to be available also in JS
|
143 |
+
add_action( 'admin_footer', array( $this, 'shortPixelJS') );
|
144 |
+
add_action( 'admin_head', array( $this, 'headCSS') );
|
145 |
Â
|
146 |
+
if($this->_settings->frontBootstrap && shortPixelCheckQueue()) {
|
147 |
+
//only if we have something in the queue - usually we never get here if the queue is empty but for some hooks...
|
148 |
Â
//also need to have it in the front footer then
|
149 |
Â
add_action( 'wp_footer', array( &$this, 'shortPixelJS') );
|
150 |
Â
//need to add the nopriv action for when items exist in the queue and no user is logged in
|
152 |
Â
}
|
153 |
Â
//register a method to display admin notices if necessary
|
154 |
Â
add_action('admin_notices', array( &$this, 'displayAdminNotices'));
|
155 |
+
|
156 |
Â
$this->migrateBackupFolder();
|
157 |
Â
|
158 |
+
// [BS] Quite dangerous to do this in any constructor. Can hit if request is ajax to name something
|
159 |
Â
if(!$this->_settings->redirectedSettings && !$this->_settings->verifiedKey && (!function_exists("is_multisite") || !is_multisite())) {
|
160 |
Â
$this->_settings->redirectedSettings = 1;
|
161 |
Â
wp_redirect(admin_url("options-general.php?page=wp-shortpixel"));
|
162 |
Â
exit();
|
163 |
Â
}
|
164 |
+
|
165 |
Â
}
|
166 |
Â
|
167 |
Â
//handling older
|
181 |
Â
/*translators: title and menu name for the Bulk Processing page*/
|
182 |
Â
add_media_page( __('ShortPixel Bulk Process','shortpixel-image-optimiser'), __('Bulk ShortPixel','shortpixel-image-optimiser'), 'edit_others_posts', 'wp-short-pixel-bulk', array( &$this, 'bulkProcess' ) );
|
183 |
Â
}
|
184 |
+
|
185 |
Â
public static function shortPixelActivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
186 |
Â
{
|
187 |
Â
self::shortPixelDeactivatePlugin();
|
188 |
Â
if(SHORTPIXEL_RESET_ON_ACTIVATE === true && WP_DEBUG === true) { //force reset plugin counters, only on specific occasions and on test environments
|
189 |
Â
WPShortPixelSettings::debugResetOptions();
|
190 |
+
|
191 |
Â
$settings = new WPShortPixelSettings();
|
192 |
Â
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $settings->excludePatterns);
|
193 |
Â
$spMetaDao->dropTables();
|
197 |
Â
}
|
198 |
Â
WPShortPixelSettings::onActivate();
|
199 |
Â
}
|
200 |
+
|
201 |
Â
public static function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
202 |
Â
{
|
203 |
Â
ShortPixelQueue::resetBulk();
|
330 |
Â
}
|
331 |
Â
return $found;
|
332 |
Â
}
|
333 |
+
|
334 |
Â
public function displayAdminNotices() {
|
335 |
Â
if(!ShortPixelQueue::testQ()) {
|
336 |
Â
ShortPixelView::displayActivationNotice('fileperms');
|
340 |
Â
}
|
341 |
Â
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
342 |
Â
$this->_settings->dismissedNotices = $dismissed;
|
343 |
+
|
344 |
Â
if(!$this->_settings->verifiedKey) {
|
345 |
Â
$now = time();
|
346 |
Â
$act = $this->_settings->activationDate ? $this->_settings->activationDate : $now;
|
377 |
Â
$screen = get_current_screen();
|
378 |
Â
$stats = $this->countAllIfNeeded($this->_settings->currentStats, 86400);
|
379 |
Â
$quotaData = $stats;
|
380 |
+
|
381 |
Â
//this is for bulk page - alert on the total credits for total images
|
382 |
Â
if( !isset($dismissed['upgbulk']) && $screen && $screen->id == 'media_page_wp-short-pixel-bulk' && $this->bulkUpgradeNeeded($stats)) {
|
383 |
Â
//looks like the user hasn't got enough credits to bulk process all media library
|
384 |
+
ShortPixelView::displayActivationNotice('upgbulk', array('filesTodo' => $stats['totalFiles'] - $stats['totalProcessedFiles'],
|
385 |
Â
'quotaAvailable' => max(0, $quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'])));
|
386 |
Â
}
|
387 |
Â
//consider the monthly plus 1/6 of the available one-time credits.
|
391 |
Â
}
|
392 |
Â
}
|
393 |
Â
}
|
394 |
+
|
395 |
Â
public function dismissAdminNotice() {
|
396 |
Â
$noticeId = preg_replace('|[^a-z0-9]|i', '', $_GET['notice_id']);
|
397 |
Â
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
401 |
Â
$this->_settings->optimizeUnlisted = 1;
|
402 |
Â
}
|
403 |
Â
die(json_encode(array("Status" => 'success', "Message" => 'Notice ID: ' . $noticeId . ' dismissed')));
|
404 |
+
}
|
405 |
Â
|
406 |
Â
public function dismissMediaAlert() {
|
407 |
Â
$this->_settings->mediaAlert = 1;
|
408 |
Â
die(json_encode(array("Status" => 'success', "Message" => __('Media alert dismissed','shortpixel-image-optimiser'))));
|
409 |
+
}
|
410 |
+
|
411 |
Â
protected function getMonthAvg($stats) {
|
412 |
Â
for($i = 4, $count = 0; $i>=1; $i--) {
|
413 |
Â
if($count == 0 && $stats['totalM' . $i] == 0) continue;
|
415 |
Â
}
|
416 |
Â
return ($stats['totalM1'] + $stats['totalM2'] + $stats['totalM3'] + $stats['totalM4']) / max(1,$count);
|
417 |
Â
}
|
418 |
+
|
419 |
Â
protected function monthlyUpgradeNeeded($quotaData) {
|
420 |
Â
return isset($quotaData['APICallsQuotaNumeric']) && $this->getMonthAvg($quotaData) > $quotaData['APICallsQuotaNumeric'] + ($quotaData['APICallsQuotaOneTimeNumeric'] - $quotaData['APICallsMadeOneTimeNumeric'])/6 + 20;
|
421 |
Â
}
|
426 |
Â
}
|
427 |
Â
|
428 |
Â
//set default move as "list". only set once, it won't try to set the default mode again.
|
429 |
+
public function setDefaultViewModeList()
|
430 |
Â
{
|
431 |
+
if($this->_settings->mediaLibraryViewMode === false)
|
432 |
Â
{
|
433 |
Â
$this->_settings->mediaLibraryViewMode = 1;
|
434 |
Â
$currentUserID = false;
|
438 |
Â
update_user_meta($currentUserID, "wp_media_library_mode", "list");
|
439 |
Â
}
|
440 |
Â
}
|
441 |
+
|
442 |
Â
}
|
443 |
Â
|
444 |
+
static function log($message, $force = false) {
|
445 |
+
if (SHORTPIXEL_DEBUG === true || $force) {
|
446 |
Â
if (is_array($message) || is_object($message)) {
|
447 |
+
self::doLog(print_r($message, true), $force);
|
448 |
Â
} else {
|
449 |
+
self::doLog($message, $force);
|
450 |
Â
}
|
451 |
Â
}
|
452 |
Â
}
|
453 |
+
|
454 |
+
static protected function doLog($message, $force = false) {
|
455 |
+
if(defined('SHORTPIXEL_DEBUG_TARGET') || $force) {
|
456 |
Â
file_put_contents(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log", '[' . date('Y-m-d H:i:s') . "] $message\n", FILE_APPEND);
|
457 |
Â
} else {
|
458 |
Â
error_log($message);
|
462 |
Â
function headCSS() {
|
463 |
Â
echo('<style>.shortpixel-hide {display:none;}</style>');
|
464 |
Â
}
|
465 |
+
|
466 |
+
function shortPixelJS() {
|
467 |
Â
//require_once(ABSPATH . 'wp-admin/includes/screen.php');
|
468 |
Â
if(function_exists('get_current_screen')) {
|
469 |
Â
$screen = get_current_screen();
|
470 |
+
|
471 |
+
if(is_object($screen)) {
|
472 |
+
if( in_array($screen->id, array('attachment', 'upload', 'media_page_wp-short-pixel-custom'))) {
|
473 |
Â
//output the comparer html
|
474 |
Â
$this->view->outputComparerHTML();
|
475 |
Â
//render a template of the list cell to be used by the JS
|
480 |
Â
wp_enqueue_style('short-pixel-bar.min.css', plugins_url('/res/css/short-pixel-bar.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
481 |
Â
if( in_array($screen->id, array('attachment', 'upload', 'settings_page_wp-shortpixel', 'media_page_wp-short-pixel-bulk', 'media_page_wp-short-pixel-custom'))) {
|
482 |
Â
wp_enqueue_style('short-pixel.min.css', plugins_url('/res/css/short-pixel.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
483 |
+
//modal - used in settings for selecting folder
|
484 |
+
wp_enqueue_style('short-pixel-modal.min.css', plugins_url('/res/css/short-pixel-modal.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
485 |
+
|
486 |
+
wp_register_style('shortpixel-admin', plugins_url('/res/css/shortpixel-admin.css', SHORTPIXEL_PLUGIN_FILE),array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION );
|
487 |
+
wp_enqueue_style('shortpixel-admin');
|
488 |
Â
}
|
489 |
Â
}
|
490 |
Â
}
|
558 |
Â
wp_localize_script( 'shortpixel' . $this->jsSuffix, '_spTr', $jsTranslation );
|
559 |
Â
wp_localize_script( 'shortpixel' . $this->jsSuffix, 'ShortPixelConstants', $ShortPixelConstants );
|
560 |
Â
wp_enqueue_script('shortpixel' . $this->jsSuffix);
|
561 |
+
|
562 |
Â
wp_enqueue_script('jquery.knob.min.js', plugins_url('/res/js/jquery.knob.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
563 |
Â
wp_enqueue_script('jquery.tooltip.min.js', plugins_url('/res/js/jquery.tooltip.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
564 |
Â
wp_enqueue_script('punycode.min.js', plugins_url('/res/js/punycode.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
565 |
Â
}
|
566 |
Â
|
567 |
Â
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
568 |
+
|
569 |
Â
$extraClasses = " shortpixel-hide";
|
570 |
Â
/*translators: toolbar icon tooltip*/
|
571 |
Â
$id = 'short-pixel-notice-toolbar';
|
596 |
Â
|
597 |
Â
$args = array(
|
598 |
Â
'id' => 'shortpixel_processing',
|
599 |
+
'title' => '<div id="' . $id . '" title="' . $tooltip . '" ><img src="'
|
600 |
Â
. plugins_url( 'res/img/'.$icon, SHORTPIXEL_PLUGIN_FILE ) . '" success-url="' . $successLink . '"><span class="shp-alert">!</span>'
|
601 |
Â
.'<div class="cssload-container"><div class="cssload-speeding-wheel"></div></div></div>',
|
602 |
Â
'href' => $link,
|
640 |
Â
foreach( $mediaIds as $ID ) {
|
641 |
Â
$meta = wp_get_attachment_metadata($ID);
|
642 |
Â
if( ( !isset($meta['ShortPixel']) //never touched by ShortPixel
|
643 |
+
|| (isset($meta['ShortPixel']['WaitingProcessing']) && $meta['ShortPixel']['WaitingProcessing'] == true))
|
644 |
Â
&& (!isset($meta['ShortPixelImprovement']) || $meta['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser'))) {
|
645 |
Â
$this->prioQ->push($ID);
|
646 |
Â
if(!isset($meta['ShortPixel'])) {
|
649 |
Â
$meta['ShortPixel']['WaitingProcessing'] = true;
|
650 |
Â
//wp_update_attachment_metadata($ID, $meta);
|
651 |
Â
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
652 |
+
ShortPixelMetaFacade::optimizationStarted($ID);
|
653 |
Â
}
|
654 |
Â
}
|
655 |
Â
break;
|
705 |
Â
return $meta;
|
706 |
Â
}
|
707 |
Â
|
708 |
+
if(isset($this->thumbnailsRegenerating[$ID])) {
|
Â
|
|
709 |
Â
return $meta;
|
710 |
Â
}
|
711 |
+
|
712 |
Â
self::log("Handle Media Library Image Upload #{$ID}");
|
713 |
Â
//self::log("STACK: " . json_encode(debug_backtrace()));
|
714 |
Â
|
728 |
Â
$meta['ShortPixelImprovement'] = __('Optimization N/A', 'shortpixel-image-optimiser');
|
729 |
Â
return $meta;
|
730 |
Â
}
|
731 |
+
else
|
732 |
Â
{//the kind of file we can process. goody.
|
733 |
Â
|
734 |
Â
$this->prioQ->push($ID);
|
751 |
Â
//self::log("IMG: sent: " . json_encode($URLsAndPATHs));
|
752 |
Â
}
|
753 |
Â
$meta['ShortPixel']['WaitingProcessing'] = true;
|
754 |
+
|
755 |
Â
// check if the image was converted from PNG upon uploading.
|
756 |
Â
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {//for the moment
|
757 |
Â
$imagePath = $itemHandler->getMeta()->getPath();
|
760 |
Â
$params = $conv[$imagePath];
|
761 |
Â
unset($conv[$imagePath]);
|
762 |
Â
$this->_settings->convertedPng2Jpg == $conv;
|
763 |
+
$meta['ShortPixelPng2Jpg'] = array('originalFile' => $params['pngFile'], 'originalSizes' => array(),
|
764 |
Â
'backup' => $params['backup'], 'optimizationPercent' => $params['optimizationPercent']);
|
765 |
Â
}
|
766 |
Â
}
|
767 |
+
|
768 |
Â
return $meta;
|
769 |
+
}
|
770 |
Â
}//end handleMediaLibraryImageUpload
|
771 |
Â
|
772 |
Â
/**
|
773 |
Â
* if the image was optimized in the last hour, send a request to delete from picQueue
|
774 |
Â
* @param $itemHandler
|
775 |
Â
* @param bool $urlsAndPaths
|
776 |
+
* @see ShortPixelImage/maybeDump
|
777 |
Â
*/
|
778 |
Â
public function maybeDumpFromProcessedOnServer($itemHandler, $urlsAndPaths) {
|
779 |
Â
$meta = $itemHandler->getMeta();
|
780 |
Â
|
781 |
+
$doDump = false;
|
782 |
+
|
783 |
+
if ($meta->getStatus() <= 0)
|
784 |
+
{
|
785 |
+
$doDump = true; // dump any caching on files that ended in an error.
|
786 |
+
}
|
787 |
+
else if(time() - strtotime($meta->getTsOptimized()) < 3600) // check if this was optimized in last hour.
|
788 |
+
{
|
789 |
+
$doDump = true;
|
790 |
+
}
|
791 |
Â
|
792 |
+
if ($doDump)
|
793 |
+
{
|
794 |
+
$this->_apiInterface->doDumpRequests($urlsAndPaths["URLs"]);
|
795 |
Â
}
|
796 |
Â
}
|
797 |
Â
|
905 |
Â
}
|
906 |
Â
return $meta;
|
907 |
Â
}
|
908 |
+
|
909 |
Â
public function optimizeCustomImage($id) {
|
910 |
+
$itemHandler = new ShortPixelMetaFacade('C-' . $id);
|
911 |
+
$meta = $itemHandler->getMeta();
|
912 |
+
|
913 |
+
if ($meta->getStatus() <= 0) // image is in errorState. Dump when retrying.
|
914 |
+
{
|
915 |
+
$URLsAndPATHs = $itemHandler->getURLsAndPATHs(false);
|
916 |
+
$this->maybeDumpFromProcessedOnServer($itemHandler, $URLsAndPATHs);
|
917 |
+
}
|
918 |
+
if($meta->getStatus() != ShortPixelMeta::FILE_STATUS_SUCCESS) {
|
919 |
+
|
920 |
+
|
921 |
+
$meta->setStatus(ShortPixelMeta::FILE_STATUS_PENDING);
|
922 |
Â
$meta->setRetries(0);
|
923 |
+
/* [BS] This is being set because meta in other states does not keep previous values. The value 0 is problematic
|
924 |
+
since it can also mean not-initalized, new, etc . So push meta from settings.
|
925 |
+
*/
|
926 |
+
$meta->setCompressionType($this->_settings->compressionType);
|
927 |
+
$meta->setKeepExif($this->_settings->keepExif);
|
928 |
+
$meta->setCmyk2rgb($this->_settings->CMYKtoRGBconversion);
|
929 |
+
$meta->setResize($this->_settings->resizeImages);
|
930 |
+
$meta->setResizeWidth($this->_settings->resizeWidth);
|
931 |
+
$meta->setResizeHeight($this->_settings->resizeHeight);
|
932 |
Â
$this->spMetaDao->update($meta);
|
933 |
Â
$this->prioQ->push('C-' . $id);
|
934 |
Â
}
|
936 |
Â
|
937 |
Â
public function bulkRestore(){
|
938 |
Â
global $wpdb;
|
939 |
+
|
940 |
Â
$startQueryID = $crtStartQueryID = $this->prioQ->getStartBulkId();
|
941 |
+
$endQueryID = $this->prioQ->getStopBulkId();
|
942 |
Â
|
943 |
Â
if ( $startQueryID <= $endQueryID ) {
|
944 |
Â
return false;
|
945 |
Â
}
|
946 |
+
|
947 |
Â
$this->prioQ->resetPrio();
|
948 |
Â
|
949 |
+
$startTime = time();
|
950 |
Â
$maxTime = min(30, (is_numeric(SHORTPIXEL_MAX_EXECUTION_TIME) && SHORTPIXEL_MAX_EXECUTION_TIME > 10 ? SHORTPIXEL_MAX_EXECUTION_TIME - 5 : 25));
|
951 |
Â
$maxResults = SHORTPIXEL_MAX_RESULTS_QUERY * 2;
|
952 |
Â
if(in_array($this->prioQ->getBulkType(), array(ShortPixelQueue::BULK_TYPE_CLEANUP, ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING))) {
|
953 |
Â
$maxResults *= 20;
|
954 |
Â
}
|
955 |
Â
$restored = array();
|
956 |
+
|
957 |
Â
//$ind = 0;
|
958 |
Â
while( $crtStartQueryID >= $endQueryID && time() - $startTime < $maxTime) {
|
959 |
Â
//if($ind > 1) break;
|
960 |
Â
//$ind++;
|
961 |
+
|
962 |
+
// [BS] Request StartQueryID everytime to query for updated AdvanceBulk status
|
963 |
+
$crtStartQueryID = $this->prioQ->getStartBulkId();
|
964 |
Â
$resultsPostMeta = WpShortPixelMediaLbraryAdapter::getPostMetaSlice($crtStartQueryID, $endQueryID, $maxResults);
|
965 |
Â
if ( empty($resultsPostMeta) ) {
|
966 |
+
// check for custom work
|
967 |
+
$pendingCustomMeta = $this->spMetaDao->getPendingBulkRestore(SHORTPIXEL_MAX_RESULTS_QUERY * 2);
|
968 |
+
if (count($pendingCustomMeta) > 0)
|
969 |
+
{
|
970 |
+
foreach($pendingCustomMeta as $cObj)
|
971 |
+
{
|
972 |
+
$this->doCustomRestore($cObj->id);
|
973 |
+
}
|
974 |
+
}
|
975 |
+
else
|
976 |
+
{
|
977 |
+
$crtStartQueryID -= $maxResults; // this basically nukes the bulk.
|
978 |
+
$startQueryID = $crtStartQueryID;
|
979 |
+
$this->prioQ->setStartBulkId($startQueryID);
|
980 |
+
continue;
|
981 |
+
}
|
982 |
Â
}
|
983 |
Â
|
984 |
Â
foreach ( $resultsPostMeta as $itemMetaData ) {
|
989 |
Â
if($meta->getStatus() == 2 || $meta->getStatus() == 1) {
|
990 |
Â
if($meta->getStatus() == 2 && $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE) {
|
991 |
Â
$res = $this->doRestore($crtStartQueryID); //this is restore, the real
|
992 |
+
} else {
|
993 |
Â
//this is only meta cleanup, no files are replaced (BACKUP REMAINS IN PLACE TOO)
|
994 |
Â
$item->cleanupMeta($this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING);
|
995 |
Â
$res = true;
|
999 |
Â
if($meta->getStatus() < 0) {//also cleanup errors either for restore or cleanup
|
1000 |
Â
$item->cleanupMeta();
|
1001 |
Â
}
|
1002 |
+
}
|
1003 |
+
// [BS] Fixed Bug. Advance Bulk was outside of this loop, causing infinite loops to happen.
|
1004 |
+
$this->advanceBulk($crtStartQueryID);
|
1005 |
Â
}
|
1006 |
+
|
1007 |
Â
return $restored;
|
1008 |
Â
}
|
1009 |
+
|
1010 |
Â
//TODO muta in bulkProvider
|
1011 |
Â
public function getBulkItemsFromDb(){
|
1012 |
Â
global $wpdb;
|
1013 |
+
|
1014 |
Â
$startQueryID = $this->prioQ->getStartBulkId();
|
1015 |
+
$endQueryID = $this->prioQ->getStopBulkId();
|
1016 |
Â
$skippedAlreadyProcessed = 0;
|
1017 |
+
|
1018 |
Â
if ( $startQueryID <= $endQueryID ) {
|
1019 |
Â
return false;
|
1020 |
Â
}
|
1021 |
Â
$idList = array();
|
1022 |
Â
$itemList = array();
|
1023 |
+
for ($sanityCheck = 0, $crtStartQueryID = $startQueryID;
|
1024 |
Â
($crtStartQueryID >= $endQueryID) && (count($itemList) < SHORTPIXEL_PRESEND_ITEMS) && ($sanityCheck < 150)
|
1025 |
Â
&& (SHORTPIXEL_MAX_EXECUTION_TIME < 10 || time() - $this->timer < SHORTPIXEL_MAX_EXECUTION_TIME - 5); $sanityCheck++) {
|
1026 |
+
|
1027 |
Â
self::log("GETDB: current StartID: " . $crtStartQueryID);
|
1028 |
Â
|
1029 |
+
/* $queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
1030 |
+
WHERE ( post_id <= $crtStartQueryID AND post_id >= $endQueryID )
|
1031 |
Â
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )
|
1032 |
Â
ORDER BY post_id DESC
|
1033 |
Â
LIMIT " . SHORTPIXEL_MAX_RESULTS_QUERY;
|
1050 |
Â
if(!in_array($crtStartQueryID, $idList) && $this->isProcessable($crtStartQueryID, ($this->_settings->optimizePdfs ? array() : array('pdf')))) {
|
1051 |
Â
$item = new ShortPixelMetaFacade($crtStartQueryID);
|
1052 |
Â
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
1053 |
+
|
1054 |
Â
if($meta->getStatus() != 2) {
|
1055 |
Â
$addIt = (strpos($meta->getMessage(), __('Image files are missing.', 'shortpixel-image-optimiser')) === false);
|
1056 |
Â
|
1076 |
Â
} else {
|
1077 |
Â
$skippedAlreadyProcessed++;
|
1078 |
Â
}
|
1079 |
+
}
|
1080 |
Â
elseif( $this->_settings->processThumbnails && $meta->getThumbsOpt() !== null
|
1081 |
Â
&& ($meta->getThumbsOpt() == 0 && count($meta->getThumbs()) > 0
|
1082 |
Â
|| $meta->getThumbsOpt() < WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($meta->getThumbs(), $this->_settings->excludeSizes) && is_array($meta->getThumbsOptList()))) { //thumbs were chosen in settings
|
1099 |
Â
$leapStart = $this->prioQ->getStartBulkId();
|
1100 |
Â
$crtStartQueryID = $startQueryID = $itemMetaData->post_id - 1; //decrement it so we don't select it again
|
1101 |
Â
$res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings, $leapStart, $crtStartQueryID);
|
1102 |
+
$skippedAlreadyProcessed += $res["mainProcessedFiles"] - $res["mainProc".($this->getCompressionType() == 1 ? "Lossy" : "Lossless")."Files"];
|
1103 |
Â
self::log("GETDB: empty list. setStartBulkID to $startQueryID");
|
1104 |
Â
$this->prioQ->setStartBulkId($startQueryID);
|
1105 |
Â
} else {
|
1122 |
Â
}
|
1123 |
Â
return $items;
|
1124 |
Â
}
|
1125 |
+
|
1126 |
Â
private function checkKey($ID) {
|
1127 |
Â
if( $this->_settings->verifiedKey == false) {
|
1128 |
Â
if($ID == null){
|
1132 |
Â
$response = array("Status" => ShortPixelAPI::STATUS_NO_KEY, "ImageID" => $itemHandler ? $itemHandler->getId() : "-1", "Message" => __('Missing API Key','shortpixel-image-optimiser'));
|
1133 |
Â
$this->_settings->bulkLastStatus = $response;
|
1134 |
Â
die(json_encode($response));
|
1135 |
+
}
|
1136 |
Â
}
|
1137 |
+
|
1138 |
Â
private function sendEmptyQueue() {
|
1139 |
Â
$avg = $this->getAverageCompression();
|
1140 |
Â
$fileCount = $this->_settings->fileCount;
|
1141 |
+
$response = array("Status" => self::BULK_EMPTY_QUEUE,
|
1142 |
Â
/* translators: console message Empty queue 1234 -> 1234 */
|
1143 |
Â
"Message" => __('Empty queue ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId(),
|
1144 |
+
"BulkStatus" => ($this->prioQ->bulkRunning()
|
1145 |
Â
? "1" : ($this->prioQ->bulkPaused() ? "2" : "0")),
|
1146 |
Â
"AverageCompression" => $avg,
|
1147 |
Â
"FileCount" => $fileCount,
|
1148 |
Â
"BulkPercent" => $this->prioQ->getBulkPercent());
|
1149 |
+
die(json_encode($response));
|
1150 |
Â
}
|
1151 |
Â
|
1152 |
+
/* Main Image Processing Function. Called from JS loop
|
1153 |
+
*
|
1154 |
+
* @param String $ID ApiKey
|
1155 |
+
*/
|
1156 |
Â
public function handleImageProcessing($ID = null) {
|
1157 |
Â
//if(rand(1,2) == 2) {
|
1158 |
Â
// header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
|
1160 |
Â
//}
|
1161 |
Â
//0: check key
|
1162 |
Â
$this->checkKey($ID);
|
1163 |
+
|
1164 |
Â
if($this->_settings->frontBootstrap && is_admin() && !ShortPixelTools::requestIsFrontendAjax()) {
|
1165 |
Â
//if in backend, and front-end is activated, mark processing from backend to shut off the front-end for 10 min.
|
1166 |
Â
$this->_settings->lastBackAction = time();
|
1167 |
Â
}
|
1168 |
+
|
1169 |
Â
$rawPrioQ = $this->prioQ->get();
|
1170 |
Â
if(count($rawPrioQ)) { self::log("HIP: 0 Priority Queue: ".json_encode($rawPrioQ)); }
|
1171 |
Â
self::log("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId);
|
1172 |
+
|
1173 |
Â
//handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
|
1174 |
+
if( $this->prioQ->bulkRunning()
|
1175 |
Â
&& ( $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE
|
1176 |
Â
|| $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP
|
1177 |
Â
|| $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING)) {
|
1179 |
Â
if($res === false) {
|
1180 |
Â
$this->sendEmptyQueue();
|
1181 |
Â
} else {
|
1182 |
+
die(json_encode(array("Status" => ShortPixelAPI::STATUS_RETRY,
|
1183 |
Â
"Message" => __('Restoring images... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId(),
|
1184 |
Â
"BulkPercent" => $this->prioQ->getBulkPercent(),
|
1185 |
Â
"Restored" => $res )));
|
1186 |
Â
}
|
1187 |
+
|
1188 |
Â
}
|
1189 |
+
|
1190 |
Â
//1: get 3 ids to process. Take them with priority from the queue
|
1191 |
Â
$ids = $this->getFromPrioAndCheck(SHORTPIXEL_PRESEND_ITEMS);
|
1192 |
Â
if(count($ids) < SHORTPIXEL_PRESEND_ITEMS ) { //take from bulk if bulk processing active
|
1212 |
Â
$customIds = false;
|
1213 |
Â
if(count($ids) < SHORTPIXEL_PRESEND_ITEMS && $this->prioQ->bulkRan() && $this->_settings->hasCustomFolders
|
1214 |
Â
&& (!$this->_settings->cancelPointer || $this->_settings->skipToCustom)
|
1215 |
+
&& !$this->_settings->customBulkPaused)
|
1216 |
Â
{ //take from custom images if any left to optimize - only if bulk was ever started
|
1217 |
Â
//but first refresh if it wasn't refreshed in the last hour
|
1218 |
Â
if(time() - $this->_settings->hasCustomFolders > 3600) {
|
1219 |
Â
$notice = null; $this->refreshCustomFolders($notice);
|
1220 |
Â
$this->_settings->hasCustomFolders = time();
|
1221 |
Â
}
|
1222 |
+
|
1223 |
+
$customIds = $this->spMetaDao->getPendingMetas( SHORTPIXEL_PRESEND_ITEMS - count($ids));
|
1224 |
Â
if(is_array($customIds)) {
|
1225 |
Â
$ids = array_merge($ids, array_map(array('ShortPixelMetaFacade', 'getNewFromRow'), $customIds));
|
1226 |
Â
}
|
1227 |
Â
}
|
1228 |
Â
//var_dump($ids);
|
1229 |
Â
//die("za stop 2");
|
1230 |
+
|
1231 |
Â
//self::log("HIP: 1 Ids: ".json_encode($ids));
|
1232 |
Â
if(count($ids)) {$idl='';foreach($ids as $i){$idl.=$i->getId().' ';} self::log("HIP: 1 Selected IDs: $idl");}
|
1233 |
Â
|
1235 |
Â
for($i = 0, $itemHandler = false; $ids !== false && $i < min(SHORTPIXEL_PRESEND_ITEMS, count($ids)); $i++) {
|
1236 |
Â
$crtItemHandler = $ids[$i];
|
1237 |
Â
$tmpMeta = $crtItemHandler->getMeta();
|
1238 |
+
|
1239 |
Â
$compType = ($tmpMeta->getCompressionType() !== null ? $tmpMeta->getCompressionType() : $this->_settings->compressionType);
|
1240 |
+
try {
|
1241 |
Â
self::log("HIP: 1 sendToProcessing: ".$crtItemHandler->getId());
|
1242 |
Â
$URLsAndPATHs = $this->sendToProcessing($crtItemHandler, $compType, $tmpMeta->getThumbsTodo());
|
1243 |
Â
//self::log("HIP: 1 METADATA: ".json_encode($crtItemHandler->getRawMeta()));
|
1260 |
Â
if (!$itemHandler){
|
1261 |
Â
//if searching, than the script is searching for not processed items and found none yet, should be relaunced
|
1262 |
Â
if(isset($res['searching']) && $res['searching']) {
|
1263 |
+
die(json_encode(array("Status" => ShortPixelAPI::STATUS_RETRY,
|
1264 |
Â
"Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
|
1265 |
Â
}
|
1266 |
Â
//in this case the queue is really empty
|
1294 |
Â
$result["ThumbsCount"] = $meta->getThumbsOpt()
|
1295 |
Â
? $meta->getThumbsOpt() //below is the fallback for old optimized images that don't have thumbsOpt
|
1296 |
Â
: ($this->_settings->processThumbnails ? $result["ThumbsTotal"] : 0);
|
1297 |
+
|
1298 |
Â
$result["RetinasCount"] = $meta->getRetinasOpt();
|
1299 |
Â
$result["BackupEnabled"] = ($this->getBackupFolderAny($meta->getPath(), $meta->getThumbs()) ? true : false);//$this->_settings->backupImages;
|
1300 |
+
|
1301 |
+
$tsOptimized = $meta->getTsOptimized();
|
1302 |
+
if (! is_null($tsOptimized))
|
1303 |
+
{
|
1304 |
+
$tsOptObj = new DateTime($tsOptimized);
|
1305 |
+
if ($tsOptObj)
|
1306 |
+
$result['TsOptimized'] = ShortPixelTools::format_nice_date($tsOptObj);
|
1307 |
+
}
|
1308 |
+
|
1309 |
Â
if(!$prio && $itemId <= $this->prioQ->getStartBulkId()) {
|
1310 |
Â
$this->advanceBulk($itemId);
|
1311 |
Â
$this->setBulkInfo($itemId, $result);
|
1312 |
Â
}
|
1313 |
Â
|
1314 |
Â
$result["AverageCompression"] = $this->getAverageCompression();
|
1315 |
+
|
1316 |
+
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
1317 |
+
|
1318 |
Â
$thumb = $bkThumb = "";
|
1319 |
Â
//$percent = 0;
|
1320 |
Â
$percent = $meta->getImprovementPercent();
|
1321 |
Â
if($percent){
|
1322 |
Â
$filePath = explode("/", $meta->getPath());
|
1323 |
+
|
1324 |
Â
//Get a suitable thumb
|
1325 |
Â
$sizes = $meta->getThumbs();
|
1326 |
Â
if('pdf' == strtolower(pathinfo($result["Filename"], PATHINFO_EXTENSION))) {
|
1427 |
Â
$prio = $this->prioQ->addToFailed($itemHandler->getQueuedId());
|
1428 |
Â
}
|
1429 |
Â
self::log("HIP RES: skipping $itemId");
|
1430 |
+
$this->advanceBulk($meta->getId());
|
1431 |
Â
if($itemHandler->getType() == ShortPixelMetaFacade::CUSTOM_TYPE) {
|
1432 |
Â
$result["CustomImageLink"] = ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath();
|
1433 |
Â
}
|
1453 |
Â
elseif($result["Status"] == ShortPixelAPI::STATUS_RETRY && is_array($customIds)) {
|
1454 |
Â
$result["CustomImageLink"] = $thumb = ShortPixelMetaFacade::getHomeUrl() . $meta->getWebPath();
|
1455 |
Â
}
|
1456 |
+
|
1457 |
Â
if($result["Status"] !== ShortPixelAPI::STATUS_RETRY) {
|
1458 |
Â
$this->_settings->bulkLastStatus = $result;
|
1459 |
Â
}
|
1460 |
Â
die(json_encode($result));
|
1461 |
Â
}
|
1462 |
+
|
1463 |
+
|
1464 |
Â
private function advanceBulk($processedID) {
|
1465 |
Â
if($processedID <= $this->prioQ->getStartBulkId()) {
|
1466 |
Â
$this->prioQ->setStartBulkId($processedID - 1);
|
1467 |
Â
$this->prioQ->logBulkProgress();
|
1468 |
Â
}
|
1469 |
Â
}
|
1470 |
+
|
1471 |
Â
private function setBulkInfo($processedID, &$result) {
|
1472 |
+
$deltaBulkPercent = $this->prioQ->getDeltaBulkPercent();
|
1473 |
Â
$minutesRemaining = $this->prioQ->getTimeRemaining();
|
1474 |
Â
$pendingMeta = $this->_settings->hasCustomFolders ? $this->spMetaDao->getPendingMetaCount() : 0;
|
1475 |
Â
$percent = $this->prioQ->getBulkPercent();
|
1483 |
Â
$result["BulkPercent"] = $percent;
|
1484 |
Â
$result["BulkMsg"] = $this->bulkProgressMessage($deltaBulkPercent, $minutesRemaining);
|
1485 |
Â
}
|
1486 |
+
|
1487 |
Â
private function sendToProcessing($itemHandler, $compressionType = false, $onlyThumbs = false) {
|
1488 |
Â
|
1489 |
Â
//conversion of PNG 2 JPG for existing images
|
1490 |
Â
if($itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) { //currently only for ML
|
1491 |
Â
$rawMeta = $this->checkConvertMediaPng2Jpg($itemHandler);
|
1492 |
+
|
1493 |
Â
if(isset($rawMeta['type']) && $rawMeta['type'] == 'image/jpeg') {
|
1494 |
Â
$itemHandler->getMeta(true);
|
1495 |
Â
}
|
1496 |
Â
}
|
1497 |
+
|
1498 |
Â
//WpShortPixelMediaLbraryAdapter::cleanupFoundThumbs($itemHandler);
|
1499 |
Â
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
1500 |
Â
|
1503 |
Â
if( $itemHandler->getType() == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE
|
1504 |
Â
&& $this->_settings->optimizeUnlisted) {
|
1505 |
Â
$mainFile = $meta->getPath();
|
1506 |
+
|
1507 |
Â
$foundThumbs = WpShortPixelMediaLbraryAdapter::findThumbs($mainFile);
|
1508 |
Â
//first identify which thumbs are not in the sizes
|
1509 |
Â
$sizes = $meta->getThumbs();
|
1537 |
Â
);
|
1538 |
Â
$ind++;
|
1539 |
Â
}
|
1540 |
+
}
|
1541 |
Â
if($ind > $start) { // at least one thumbnail added, update
|
1542 |
Â
$meta->setThumbs($sizes);
|
1543 |
Â
$itemHandler->updateMeta($meta);
|
1544 |
Â
$URLsAndPATHs = $this->getURLsAndPATHs($itemHandler, NULL, $onlyThumbs);
|
1545 |
Â
}
|
1546 |
Â
}
|
1547 |
+
|
1548 |
Â
//find any missing thumbs files and mark them as such
|
1549 |
Â
$miss = $meta->getThumbsMissing();
|
1550 |
Â
/* TODO remove */if(is_numeric($miss)) $miss = array();
|
1551 |
+
if( isset($URLsAndPATHs['sizesMissing']) && count($URLsAndPATHs['sizesMissing'])
|
1552 |
Â
&& (null === $miss || count(array_diff_key($miss, array_merge($URLsAndPATHs['sizesMissing'], $miss))))) {
|
1553 |
Â
//fix missing thumbs in the metadata before sending to processing
|
1554 |
Â
$meta->setThumbsMissing($URLsAndPATHs['sizesMissing']);
|
1555 |
+
$itemHandler->updateMeta();
|
1556 |
Â
}
|
1557 |
Â
//die(var_dump($itemHandler));
|
1558 |
Â
$refresh = $meta->getStatus() === ShortPixelAPI::ERR_INCORRECT_FILE_SIZE;
|
1559 |
Â
//echo("URLS: "); die(var_dump($URLsAndPATHs));
|
Â
|
|
Â
|
|
1560 |
Â
$itemHandler->setWaitingProcessing();
|
1561 |
+
$this->_apiInterface->doRequests($URLsAndPATHs['URLs'], false, $itemHandler,
|
1562 |
+
$compressionType === false ? $this->_settings->compressionType : $compressionType, $refresh);//send a request, do NOT wait for response
|
1563 |
Â
//$meta = wp_get_attachment_metadata($ID);
|
1564 |
Â
//$meta['ShortPixel']['WaitingProcessing'] = true;
|
1565 |
Â
//wp_update_attachment_metadata($ID, $meta);
|
1569 |
Â
public function handleManualOptimization() {
|
1570 |
Â
$imageId = $_GET['image_id'];
|
1571 |
Â
$cleanup = $_GET['cleanup'];
|
1572 |
+
|
1573 |
Â
self::log("Handle Manual Optimization #{$imageId}");
|
1574 |
+
|
1575 |
Â
switch(substr($imageId, 0, 2)) {
|
1576 |
Â
case "N-":
|
1577 |
Â
return "Add the gallery to the custom folders list in ShortPixel settings.";
|
1588 |
Â
break;
|
1589 |
Â
case "C-":
|
1590 |
Â
throw new Exception("HandleManualOptimization for custom images not implemented");
|
1591 |
+
default:
|
1592 |
Â
$this->optimizeNowHook(intval($imageId), true);
|
1593 |
Â
break;
|
1594 |
Â
}
|
1595 |
Â
//do_action('shortpixel-optimize-now', $imageId);
|
1596 |
+
|
1597 |
Â
}
|
1598 |
Â
|
1599 |
Â
public function checkStatus() {
|
1633 |
Â
* @param $postId
|
1634 |
Â
*/
|
1635 |
Â
public function thumbnailsBeforeRegenerateHook($postId) {
|
1636 |
+
$this->thumbnailsRegenerating[$postId] = true;
|
Â
|
|
Â
|
|
Â
|
|
1637 |
Â
}
|
1638 |
Â
|
1639 |
+
|
1640 |
Â
/**
|
1641 |
Â
* to be called by thumbnail regeneration plugins when regenerating the thumbnails for an image
|
1642 |
Â
* @param $postId - the postId of the image
|
1643 |
Â
* @param $originalMeta - the metadata before the regeneration
|
1644 |
Â
* @param array $regeneratedSizes - the list of the regenerated thumbnails - if empty then all were regenerated.
|
1645 |
Â
* @param bool $bulk - true if the regeneration is done in bulk - in this case the image will not be immediately scheduled for processing but the user will need to launch the ShortPixel bulk after regenerating.
|
1646 |
+
*
|
1647 |
+
*
|
1648 |
+
* Note - $regeneratedSizes expects a metadata array, with filename, not just the resized data.
|
1649 |
Â
*/
|
1650 |
Â
public function thumbnailsRegeneratedHook($postId, $originalMeta, $regeneratedSizes = array(), $bulk = false) {
|
1651 |
Â
|
1661 |
Â
foreach($regeneratedSizes as $size) {
|
1662 |
Â
if(isset($size['file']) && in_array($size['file'], $shortPixelMeta["thumbsOptList"] )) {
|
1663 |
Â
$regeneratedThumbs[] = $size['file'];
|
1664 |
+
$shortPixelMeta["thumbsOpt"] = max(0, $shortPixelMeta["thumbsOpt"] - 1); // this is a complicated count of number of thumbnails
|
1665 |
Â
$shortPixelMeta["retinasOpt"] = max(0, $shortPixelMeta["retinasOpt"] - 1);
|
1666 |
Â
}
|
1667 |
Â
}
|
1668 |
+
// This retains the thumbnails that were already regenerated, and removes what is passed via regeneratedSizes.
|
1669 |
Â
$shortPixelMeta["thumbsOptList"] = array_diff($shortPixelMeta["thumbsOptList"], $regeneratedThumbs);
|
1670 |
Â
}
|
1671 |
Â
$meta = wp_get_attachment_metadata($postId);
|
1676 |
Â
}
|
1677 |
Â
//wp_update_attachment_metadata($postId, $meta);
|
1678 |
Â
update_post_meta($postId, '_wp_attachment_metadata', $meta);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
1679 |
Â
|
1680 |
Â
if(!$bulk) {
|
1681 |
Â
$this->prioQ->push($postId);
|
1682 |
Â
}
|
1683 |
Â
}
|
1684 |
+
unset($this->thumbnailsRegenerating[$postId]);
|
1685 |
Â
}
|
1686 |
Â
|
1687 |
Â
public function shortpixelGetBackupFilter($imagePath) {
|
1699 |
Â
$this->prioQ->push($imageId);
|
1700 |
Â
//wp_update_attachment_metadata($imageId, $meta);
|
1701 |
Â
update_post_meta($imageId, '_wp_attachment_metadata', $meta);
|
1702 |
+
ShortPixelMetaFacade::optimizationStarted($imageId);
|
1703 |
Â
}
|
1704 |
Â
}
|
1705 |
+
|
1706 |
+
|
1707 |
Â
//save error in file's meta data
|
1708 |
Â
public function handleError($ID, $result)
|
1709 |
Â
{
|
1721 |
Â
//another chance at glory, maybe cleanup was too much? (we tried first the cleaned up version for historical reason, don't disturb the sleeping dragon, right? :))
|
1722 |
Â
return $this->getBackupFolderInternal($file);
|
1723 |
Â
}
|
1724 |
+
|
1725 |
Â
private function getBackupFolderInternal($file) {
|
1726 |
Â
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1727 |
Â
$SubDir = ShortPixelMetaFacade::returnSubDir($file);
|
1744 |
Â
}
|
1745 |
Â
return SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir;
|
1746 |
Â
}
|
1747 |
+
|
1748 |
Â
public function getBackupFolderAny($file, $thumbs) {
|
1749 |
Â
$ret = $this->getBackupFolder($file);
|
1750 |
Â
//if(!$ret && !file_exists($file) && isset($thumbs)) {
|
1803 |
Â
|
1804 |
Â
$pathInfo = pathinfo($file);
|
1805 |
Â
$sizes = isset($rawMeta["sizes"]) ? $rawMeta["sizes"] : array();
|
1806 |
+
|
1807 |
Â
//check if the images were converted from PNG
|
1808 |
Â
$png2jpgMain = isset($rawMeta['ShortPixelPng2Jpg']['originalFile']) ? $rawMeta['ShortPixelPng2Jpg']['originalFile'] : false;
|
1809 |
Â
$bkFolder = $this->getBackupFolderAny($file, $sizes);
|
1969 |
Â
}
|
1970 |
Â
return false;
|
1971 |
Â
}
|
1972 |
+
|
1973 |
Â
protected function renameWithRetina($bkFile, $file) {
|
1974 |
Â
@rename($bkFile, $file);
|
1975 |
Â
@rename($this->retinaName($bkFile), $this->retinaName($file));
|
1976 |
+
|
1977 |
Â
}
|
1978 |
Â
|
1979 |
Â
protected function retinaName($file) {
|
1982 |
Â
}
|
1983 |
Â
|
1984 |
Â
public function doCustomRestore($ID) {
|
1985 |
+
//$meta = $this->spMetaDao->getMeta($ID);
|
1986 |
+
// meta facade as a custom image
|
1987 |
+
$itemHandler = new ShortPixelMetaFacade('C-' . $ID);
|
1988 |
+
$meta = $itemHandler->getMeta();
|
1989 |
+
|
1990 |
+
// do this before putting the meta down, since maybeDump check for last timestamp
|
1991 |
+
// do this before checks, so it can clear ahead, and in case or errors
|
1992 |
+
$URLsAndPATHs = $itemHandler->getURLsAndPATHs(false);
|
1993 |
+
$this->maybeDumpFromProcessedOnServer($itemHandler, $URLsAndPATHs);
|
1994 |
+
|
1995 |
+
// TODO On manual restore also put status to toRestore, then run this function.
|
1996 |
+
if(!$meta || ($meta->getStatus() != shortPixelMeta::FILE_STATUS_SUCCESS && $meta->getStatus() != shortpixelMeta::FILE_STATUS_TORESTORE ) )
|
1997 |
+
{
|
1998 |
+
return false;
|
1999 |
+
}
|
2000 |
+
|
2001 |
Â
$file = $meta->getPath();
|
2002 |
Â
$fullSubDir = str_replace(get_home_path(), "", dirname($file)) . '/';
|
2003 |
+
$bkFile = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir . ShortPixelAPI::MB_basename($file);
|
2004 |
Â
|
2005 |
Â
if(file_exists($bkFile)) {
|
2006 |
+
$rename_result = @rename($bkFile, $file);
|
2007 |
+
if (! $rename_result)
|
2008 |
+
{
|
2009 |
+
self::log('Failure on rename to : ' . $file);
|
2010 |
+
}
|
2011 |
+
|
2012 |
+
|
2013 |
+
/* [BS] Reset all generated image meta. Bring back to start state.
|
2014 |
+
* Since Wpdb->prepare doesn't support 'null', zero values in this table should not be trusted */
|
2015 |
+
|
2016 |
+
$meta->setTsOptimized(0);
|
2017 |
+
$meta->setCompressedSize(0);
|
2018 |
+
$meta->setCompressionType(0);
|
2019 |
+
$meta->setKeepExif(0);
|
2020 |
+
$meta->setCmyk2rgb(0);
|
2021 |
+
$meta->setMessage('');
|
2022 |
+
$meta->setRetries(0);
|
2023 |
+
$meta->setBackup(0);
|
2024 |
+
$meta->setResizeWidth(0);
|
2025 |
+
$meta->setResizeHeight(0);
|
2026 |
+
$meta->setResize(0);
|
2027 |
+
|
2028 |
Â
$meta->setStatus(3);
|
2029 |
Â
$this->spMetaDao->update($meta);
|
2030 |
+
|
2031 |
+
|
2032 |
Â
}
|
2033 |
+
else {
|
2034 |
+
self::log('File ' . $bkFile . ' not found in backups');
|
2035 |
+
}
|
2036 |
+
|
2037 |
Â
return $meta;
|
2038 |
Â
}
|
2039 |
+
|
2040 |
Â
public function handleRestoreBackup() {
|
2041 |
Â
$attachmentID = intval($_GET['attachment_ID']);
|
2042 |
+
|
2043 |
Â
self::log("Handle Restore Backup #{$attachmentID}");
|
2044 |
Â
$this->doRestore($attachmentID);
|
2045 |
Â
|
2051 |
Â
wp_redirect($sendback);
|
2052 |
Â
// we are done
|
2053 |
Â
}
|
2054 |
+
|
2055 |
Â
public function handleRedo() {
|
2056 |
Â
self::log("Handle Redo #{$_GET['attachment_ID']} type {$_GET['type']}");
|
2057 |
+
|
2058 |
Â
die(json_encode($this->redo($_GET['attachment_ID'], $_GET['type'])));
|
2059 |
Â
}
|
2060 |
+
|
2061 |
Â
public function redo($qID, $type = false) {
|
2062 |
Â
$compressionType = ($type == 'lossless' ? 'lossless' : ($type == 'glossy' ? 'glossy' : 'lossy')); //sanity check
|
2063 |
Â
|
2072 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_SUCCESS, "Message" => "");
|
2073 |
Â
} else {
|
2074 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => __('Could not restore from backup: ','shortpixel-image-optimiser') . $qID);
|
2075 |
+
}
|
2076 |
Â
} else {
|
2077 |
Â
$ID = intval($qID);
|
2078 |
Â
$meta = $this->doRestore($ID);
|
2091 |
Â
//wp_update_attachment_metadata($ID, $meta);
|
2092 |
Â
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
2093 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
|
2094 |
+
}
|
2095 |
Â
} else {
|
2096 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "Message" => __('Could not restore from backup: ','shortpixel-image-optimiser') . $ID);
|
2097 |
Â
}
|
2098 |
Â
}
|
2099 |
Â
return $ret;
|
2100 |
Â
}
|
2101 |
+
|
2102 |
Â
public function handleOptimizeThumbs() {
|
2103 |
Â
$ID = intval($_GET['attachment_ID']);
|
2104 |
Â
$meta = wp_get_attachment_metadata($ID);
|
2105 |
Â
//die(var_dump($meta));
|
2106 |
Â
$thumbsCount = WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($meta['sizes'], $this->_settings->excludeSizes);
|
2107 |
+
if( isset($meta['ShortPixelImprovement'])
|
2108 |
Â
&& isset($meta['sizes']) && $thumbsCount
|
2109 |
Â
&& ( !isset($meta['ShortPixel']['thumbsOpt']) || $meta['ShortPixel']['thumbsOpt'] == 0
|
2110 |
Â
|| (isset($meta['sizes']) && isset($meta['ShortPixel']['thumbsOptList']) && $meta['ShortPixel']['thumbsOpt'] < $thumbsCount))) { //optimized without thumbs, thumbs exist
|
2124 |
Â
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
2125 |
Â
}
|
2126 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_FAIL, "Message" => $e->getMessage());
|
2127 |
+
}
|
2128 |
Â
} else {
|
2129 |
Â
$ret = array("Status" => ShortPixelAPI::STATUS_SKIP, "message" => (isset($meta['ShortPixelImprovement']) ? __('No thumbnails to optimize for ID: ','shortpixel-image-optimiser') : __('Please optimize image for ID: ','shortpixel-image-optimiser')) . $ID);
|
2130 |
Â
}
|
2131 |
Â
die(json_encode($ret));
|
2132 |
Â
}
|
2133 |
+
|
2134 |
Â
public function handleCheckQuota() {
|
2135 |
Â
$this->getQuotaInformation();
|
2136 |
Â
// store the referring webpage location
|
2151 |
Â
$meta = wp_get_attachment_metadata($ID);
|
2152 |
Â
|
2153 |
Â
|
2154 |
+
if(self::_isProcessable($ID) != false) //we use the static isProcessable to bypass the exclude patterns
|
2155 |
Â
{
|
2156 |
Â
try {
|
2157 |
Â
$SubDir = ShortPixelMetaFacade::returnSubDir($file);
|
2158 |
+
|
2159 |
Â
@unlink(SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir . ShortPixelAPI::MB_basename($file));
|
2160 |
+
|
2161 |
Â
if ( !empty($meta['file']) )
|
2162 |
Â
{
|
2163 |
Â
$filesPath = SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir;//base BACKUP path
|
2167 |
Â
@unlink($filesPath . ShortPixelAPI::MB_basename($imageData['file']));//remove thumbs
|
2168 |
Â
}
|
2169 |
Â
}
|
2170 |
+
}
|
2171 |
+
|
2172 |
Â
} catch(Exception $e) {
|
2173 |
Â
//what to do, what to do?
|
2174 |
Â
}
|
2175 |
Â
}
|
2176 |
Â
}
|
2177 |
+
|
2178 |
Â
public function deactivatePlugin() {
|
2179 |
Â
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'sp_deactivate_plugin_nonce' ) ) {
|
2180 |
Â
wp_nonce_ays( '' );
|
2205 |
Â
if( !(defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG === true) && is_array($this->_settings->currentStats)
|
2206 |
Â
&& $this->_settings->currentStats['optimizePdfs'] == $this->_settings->optimizePdfs
|
2207 |
Â
&& isset($this->_settings->currentStats['time'])
|
2208 |
+
&& (time() - $this->_settings->currentStats['time'] < $time))
|
2209 |
Â
{
|
2210 |
Â
return $this->_settings->currentStats;
|
2211 |
Â
} else {
|
2220 |
Â
if($this->_settings->hasCustomFolders) {
|
2221 |
Â
$customImageCount = $this->spMetaDao->countAllProcessableFiles();
|
2222 |
Â
foreach($customImageCount as $key => $val) {
|
2223 |
+
$quotaData[$key] = isset($quotaData[$key])
|
2224 |
Â
? (is_array($quotaData[$key])
|
2225 |
Â
? array_merge($quotaData[$key], $val)
|
2226 |
Â
: (is_numeric($quotaData[$key])
|
2233 |
Â
return $quotaData;
|
2234 |
Â
}
|
2235 |
Â
}
|
2236 |
+
|
2237 |
Â
public function checkQuotaAndAlert($quotaData = null, $recheck = false, $refreshFiles = 300) {
|
2238 |
Â
if(!$quotaData) {
|
2239 |
Â
$quotaData = $this->getQuotaInformation();
|
2259 |
Â
}
|
2260 |
Â
return $quotaData;
|
2261 |
Â
}
|
2262 |
+
|
2263 |
Â
public function isValidMetaId($id) {
|
2264 |
Â
return substr($id, 0, 2 ) == "C-" ? $this->spMetaDao->getMeta(substr($id, 2)) : wp_get_attachment_url($id);
|
2265 |
Â
}
|
2267 |
Â
public function listCustomMedia() {
|
2268 |
Â
if( ! class_exists( 'ShortPixelListTable' ) ) {
|
2269 |
Â
require_once('view/shortpixel-list-table.php');
|
2270 |
+
}
|
2271 |
+
if(isset($_REQUEST['refresh']) && esc_attr($_REQUEST['refresh']) == 1) {
|
2272 |
Â
$notice = null;
|
2273 |
Â
$this->refreshCustomFolders($notice);
|
2274 |
Â
}
|
2276 |
Â
//die(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
|
2277 |
Â
$this->prioQ->push(ShortPixelMetaFacade::queuedId(ShortPixelMetaFacade::CUSTOM_TYPE, $_REQUEST['image']));
|
2278 |
Â
}
|
2279 |
+
|
2280 |
Â
$customMediaListTable = new ShortPixelListTable($this, $this->spMetaDao, $this->hasNextGen);
|
2281 |
Â
$items = $customMediaListTable->prepare_items();
|
2282 |
Â
if ( isset($_GET['noheader']) ) {
|
2321 |
Â
</div>
|
2322 |
Â
</div> <?php
|
2323 |
Â
}
|
2324 |
+
|
2325 |
+
/** Front End function that controls bulk processes.
|
2326 |
+
*
|
2327 |
+
*/
|
2328 |
Â
public function bulkProcess() {
|
2329 |
Â
global $wpdb;
|
2330 |
Â
|
2332 |
Â
ShortPixelView::displayActivationNotice();
|
2333 |
Â
return;
|
2334 |
Â
}
|
2335 |
+
|
2336 |
Â
$quotaData = $this->checkQuotaAndAlert(null, isset($_GET['checkquota']), 0);
|
2337 |
Â
//if($this->_settings->quotaExceeded != 0) {
|
2338 |
Â
//return;
|
2339 |
Â
//}
|
2340 |
+
|
2341 |
+
if(isset($_POST['bulkProcessPause']))
|
2342 |
Â
{//pause an ongoing bulk processing, it might be needed sometimes
|
2343 |
Â
$this->prioQ->pauseBulk();
|
2344 |
Â
if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
|
2346 |
Â
}
|
2347 |
Â
}
|
2348 |
Â
|
2349 |
+
if(isset($_POST['bulkProcessStop']))
|
2350 |
Â
{//stop an ongoing bulk processing
|
2351 |
Â
$this->prioQ->stopBulk();
|
2352 |
Â
if($this->_settings->hasCustomFolders && $this->spMetaDao->getPendingMetaCount()) {
|
2355 |
Â
$this->_settings->cancelPointer = NULL;
|
2356 |
Â
}
|
2357 |
Â
|
2358 |
+
if(isset($_POST["bulkProcess"]))
|
2359 |
Â
{
|
2360 |
+
//set the thumbnails option
|
2361 |
Â
if ( isset($_POST['thumbnails']) ) {
|
2362 |
Â
$this->_settings->processThumbnails = 1;
|
2363 |
Â
} else {
|
2366 |
Â
//clean the custom files errors in order to process them again
|
2367 |
Â
if($this->_settings->hasCustomFolders) {
|
2368 |
Â
$this->spMetaDao->resetFailed();
|
2369 |
+
$this->spMetaDao->resetRestored();
|
2370 |
+
|
2371 |
Â
}
|
2372 |
+
|
2373 |
Â
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_OPTIMIZE);
|
2374 |
Â
$this->_settings->customBulkPaused = 0;
|
2375 |
Â
self::log("BULK: Start: " . $this->prioQ->getStartBulkId() . ", stop: " . $this->prioQ->getStopBulkId() . " PrioQ: "
|
2376 |
Â
.json_encode($this->prioQ->get()));
|
2377 |
+
}//end bulk process was clicked
|
2378 |
+
|
2379 |
+
if(isset($_POST["bulkRestore"]))
|
2380 |
Â
{
|
2381 |
+
$bulkRestore = new \ShortPixel\BulkRestoreAll();
|
2382 |
+
$bulkRestore->setShortPixel($this);
|
2383 |
+
$bulkRestore->setupBulk();
|
2384 |
+
|
2385 |
Â
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_RESTORE);
|
2386 |
Â
$this->_settings->customBulkPaused = 0;
|
2387 |
+
}//end bulk restore was clicked
|
2388 |
+
|
2389 |
+
if(isset($_POST["bulkCleanup"]))
|
2390 |
Â
{
|
2391 |
Â
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_CLEANUP);
|
2392 |
Â
$this->_settings->customBulkPaused = 0;
|
2393 |
+
}//end bulk restore was clicked
|
2394 |
Â
|
2395 |
Â
if(isset($_POST["bulkCleanupPending"]))
|
2396 |
Â
{
|
2404 |
Â
$this->_settings->customBulkPaused = 0;
|
2405 |
Â
}//resume was clicked
|
2406 |
Â
|
2407 |
+
if(isset($_POST["skipToCustom"]))
|
2408 |
Â
{
|
2409 |
Â
$this->_settings->skipToCustom = true;
|
2410 |
Â
}//resume was clicked
|
2423 |
Â
{
|
2424 |
Â
$msg = $this->bulkProgressMessage($this->prioQ->getDeltaBulkPercent(), $this->prioQ->getTimeRemaining());
|
2425 |
Â
|
2426 |
+
$this->view->displayBulkProcessingRunning($this->getPercent($quotaData), $msg, $quotaData['APICallsRemaining'], $this->getAverageCompression(),
|
2427 |
+
$this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_RESTORE ? 0 :
|
2428 |
Â
( $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP
|
2429 |
Â
|| $this->prioQ->getBulkType() == ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING ? -1 : ($pendingMeta !== null ? ($this->prioQ->bulkRunning() ? 3 : 2) : 1)), $quotaData);
|
2430 |
Â
|
2431 |
+
} else
|
2432 |
Â
{
|
2433 |
Â
if($this->prioQ->bulkRan() && !$this->prioQ->bulkPaused()) {
|
2434 |
Â
$this->prioQ->markBulkComplete();
|
2435 |
Â
}
|
2436 |
Â
|
2437 |
+
//image count
|
2438 |
Â
$thumbsProcessedCount = $this->_settings->thumbsCount;//amount of optimized thumbnails
|
2439 |
Â
$under5PercentCount = $this->_settings->under5Percent;//amount of under 5% optimized imgs.
|
2440 |
Â
|
2442 |
Â
$averageCompression = self::getAverageCompression();
|
2443 |
Â
$percent = $this->prioQ->bulkPaused() ? $this->getPercent($quotaData) : false;
|
2444 |
Â
|
2445 |
+
// [BS] If some template part is around, use it and find the controller.
|
2446 |
+
$template_part = isset($_GET['part']) ? sanitize_text_field($_GET['part']) : false;
|
2447 |
+
$controller = ShortPixelTools::namespaceit('ShortPixelController');
|
2448 |
+
$partControl = $controller::findControllerbySlug($template_part);
|
2449 |
+
|
2450 |
+
if ($partControl)
|
2451 |
+
{
|
2452 |
+
$viewObj = new $partControl();
|
2453 |
+
$viewObj->setShortPixel($this);
|
2454 |
+
$viewObj->loadView();
|
2455 |
+
}
|
2456 |
+
|
2457 |
+
if (! $template_part)
|
2458 |
+
{
|
2459 |
+
$this->view->displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount,
|
2460 |
Â
$this->prioQ->bulkRan(), $averageCompression, $this->_settings->fileCount,
|
2461 |
Â
self::formatBytes($this->_settings->savedSpace), $percent, $pendingMeta);
|
2462 |
+
}
|
2463 |
Â
}
|
2464 |
Â
}
|
2465 |
Â
//end bulk processing
|
2466 |
+
|
2467 |
Â
public function getPercent($quotaData) {
|
2468 |
Â
if($this->_settings->processThumbnails) {
|
2469 |
Â
return $quotaData["totalFiles"] ? min(99, round($quotaData["totalProcessedFiles"] *100.0 / $quotaData["totalFiles"])) : 0;
|
2471 |
Â
return $quotaData["mainFiles"] ? min(99, round($quotaData["mainProcessedFiles"] *100.0 / $quotaData["mainFiles"])) : 0;
|
2472 |
Â
}
|
2473 |
Â
}
|
2474 |
+
|
2475 |
Â
public function bulkProgressMessage($percent, $minutes) {
|
2476 |
Â
$timeEst = "";
|
2477 |
Â
self::log("bulkProgressMessage(): percent: " . $percent);
|
2492 |
Â
}
|
2493 |
Â
return $timeEst;
|
2494 |
Â
}
|
2495 |
+
|
2496 |
Â
public function emptyBackup(){
|
2497 |
Â
if(file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
2498 |
+
|
2499 |
Â
//extract all images from DB in an array. of course
|
2500 |
Â
// Simon: WHY?!!! commenting for now...
|
2501 |
Â
/*
|
2506 |
Â
'post_mime_type' => 'image'
|
2507 |
Â
));
|
2508 |
Â
*/
|
2509 |
+
|
2510 |
Â
//delete the actual files on disk
|
2511 |
Â
$this->deleteDir(SHORTPIXEL_BACKUP_FOLDER);//call a recursive function to empty files and sub-dirs in backup dir
|
2512 |
Â
}
|
2513 |
Â
}
|
2514 |
+
|
2515 |
Â
public function backupFolderIsEmpty() {
|
2516 |
Â
if(file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
2517 |
Â
return count(scandir(SHORTPIXEL_BACKUP_FOLDER)) > 2 ? false : true;
|
2524 |
Â
}
|
2525 |
Â
die(self::formatBytes(self::folderSize(SHORTPIXEL_BACKUP_FOLDER)));
|
2526 |
Â
}
|
2527 |
+
|
2528 |
Â
public function browseContent() {
|
2529 |
Â
if ( !current_user_can( 'manage_options' ) ) {
|
2530 |
Â
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
2531 |
Â
}
|
2532 |
+
|
2533 |
Â
$root = self::getCustomFolderBase();
|
2534 |
+
|
2535 |
Â
|
2536 |
Â
$postDir = rawurldecode($root.(isset($_POST['dir']) ? trim($_POST['dir']) : null ));
|
2537 |
Â
// set checkbox if multiSelect set to true
|
2543 |
Â
|
2544 |
Â
$files = scandir($postDir);
|
2545 |
Â
$returnDir = substr($postDir, strlen($root));
|
2546 |
+
|
2547 |
Â
natcasesort($files);
|
2548 |
Â
|
2549 |
Â
if( count($files) > 2 ) { // The 2 accounts for . and ..
|
2551 |
Â
foreach( $files as $file ) {
|
2552 |
Â
|
2553 |
Â
if($file == 'ShortpixelBackups' || ShortPixelMetaFacade::isMediaSubfolder($postDir . $file, false)) continue;
|
2554 |
+
|
2555 |
Â
$htmlRel = str_replace("'", "'", $returnDir . $file);
|
2556 |
Â
$htmlName = htmlentities($file);
|
2557 |
Â
$ext = preg_replace('/^.*\./', '', $file);
|
2571 |
Â
}
|
2572 |
Â
die();
|
2573 |
Â
}
|
2574 |
+
|
2575 |
Â
public function getComparerData() {
|
2576 |
Â
if (!isset($_POST['id']) || !current_user_can( 'upload_files' ) && !current_user_can( 'edit_posts' ) ) {
|
2577 |
Â
wp_die(json_encode((object)array('origUrl' => false, 'optUrl' => false, 'width' => 0, 'height' => 0)));
|
2578 |
Â
}
|
2579 |
+
|
2580 |
Â
$ret = array();
|
2581 |
Â
$handle = new ShortPixelMetaFacade($_POST['id']);
|
2582 |
+
|
2583 |
Â
$meta = $handle->getMeta();
|
2584 |
Â
$rawMeta = $handle->getRawMeta();
|
2585 |
Â
$backupUrl = content_url() . "/" . SHORTPIXEL_UPLOADS_NAME . "/" . SHORTPIXEL_BACKUP . "/";
|
2586 |
Â
$uploadsUrl = ShortPixelMetaFacade::getHomeUrl();
|
2587 |
Â
$urlBkPath = ShortPixelMetaFacade::returnSubDir($meta->getPath());
|
2588 |
Â
$ret['origUrl'] = $backupUrl . $urlBkPath . $meta->getName();
|
2589 |
+
if ($meta->getType() == ShortPixelMetaFacade::CUSTOM_TYPE)
|
2590 |
+
{
|
2591 |
+
$ret['optUrl'] = $uploadsUrl . $meta->getWebPath();
|
2592 |
+
self::log('Getting image - ' . $urlBkPath . $meta->getPath());
|
2593 |
+
// [BS] Another bug? Width / Height not stored in Shortpixel meta.
|
2594 |
+
$ret['width'] = $meta->getActualWidth();
|
2595 |
+
$ret['height'] = $meta->getActualHeight();
|
2596 |
+
|
2597 |
+
if (is_null($ret['width']))
|
2598 |
+
{
|
2599 |
+
|
2600 |
+
// $imageSizes = getimagesize($ret['optUrl']);
|
2601 |
+
// [BS] Fix - Use real path instead of URL on getimagesize.
|
2602 |
+
$imageSizes = getimagesize($meta->getPath());
|
2603 |
+
|
2604 |
+
if ($imageSizes)
|
2605 |
+
{
|
2606 |
+
$ret['width'] = $imageSizes[0];
|
2607 |
+
$ret['height']= $imageSizes[1];
|
2608 |
+
}
|
2609 |
+
}
|
2610 |
+
}
|
2611 |
+
else
|
2612 |
+
{
|
2613 |
+
$ret['optUrl'] = wp_get_attachment_url( $_POST['id'] ); //$uploadsUrl . $urlBkPath . $meta->getName();
|
2614 |
+
$ret['width'] = $rawMeta['width'];
|
2615 |
+
$ret['height'] = $rawMeta['height'];
|
2616 |
+
}
|
2617 |
Â
|
2618 |
Â
die(json_encode((object)$ret));
|
2619 |
Â
}
|
2620 |
+
|
2621 |
Â
public function newApiKey() {
|
2622 |
Â
if ( !current_user_can( 'manage_options' ) ) {
|
2623 |
Â
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
2653 |
Â
if($body->Status == 'success') {
|
2654 |
Â
$key = trim($body->Details);
|
2655 |
Â
$validityData = $this->getQuotaInformation($key, true, true);
|
2656 |
+
if($validityData['APIKeyValid']) {
|
2657 |
Â
$this->_settings->apiKey = $key;
|
2658 |
Â
$this->_settings->verifiedKey = true;
|
2659 |
Â
}
|
2660 |
Â
}
|
2661 |
Â
die(json_encode($body));
|
2662 |
+
|
2663 |
Â
}
|
2664 |
+
|
2665 |
Â
public function proposeUpgrade() {
|
2666 |
Â
if ( !current_user_can( 'manage_options' ) ) {
|
2667 |
Â
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
2668 |
Â
}
|
2669 |
+
|
2670 |
Â
$stats = $this->countAllIfNeeded($this->_settings->currentStats, 300);
|
2671 |
Â
|
2672 |
Â
//$proposal = wp_remote_post($this->_settings->httpProto . "://shortpixel.com/propose-upgrade-frag", array(
|
2708 |
Â
die($proposal['body']);
|
2709 |
Â
|
2710 |
Â
}
|
2711 |
+
|
2712 |
Â
public static function getCustomFolderBase() {
|
2713 |
Â
if(is_main_site()) {
|
2714 |
Â
$base = get_home_path();
|
2718 |
Â
return realpath($up['basedir']);
|
2719 |
Â
}
|
2720 |
Â
}
|
2721 |
+
|
2722 |
Â
protected function fullRefreshCustomFolder($path, &$notice) {
|
2723 |
Â
$folder = $this->spMetaDao->getFolder($path);
|
2724 |
Â
$diff = $folder->checkFolderContents(array('ShortPixelCustomMetaDao', 'getPathFiles'));
|
2725 |
Â
}
|
2726 |
+
|
2727 |
Â
protected function refreshCustomFolders(&$notice, $ignore = false) {
|
2728 |
Â
$customFolders = array();
|
2729 |
Â
if($this->_settings->hasCustomFolders) {
|
2754 |
Â
}
|
2755 |
Â
|
2756 |
Â
protected static function alterHtaccess( $clear = false ){
|
2757 |
+
// [BS] Backward compat. 11/03/2019 - remove possible settings from root .htaccess
|
2758 |
+
$upload_dir = wp_upload_dir();
|
2759 |
+
$upload_base = trailingslashit($upload_dir['basedir']);
|
2760 |
+
|
2761 |
Â
if ( $clear ) {
|
2762 |
Â
insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', '');
|
2763 |
+
insert_with_markers( $upload_base . '.htaccess', 'ShortPixelWebp', '');
|
2764 |
+
insert_with_markers( trailingslashit(WP_CONTENT_DIR) . '.htaccess', 'ShortPixelWebp', '');
|
2765 |
Â
} else {
|
2766 |
+
|
2767 |
+
$rules = '
|
2768 |
Â
<IfModule mod_rewrite.c>
|
2769 |
Â
RewriteEngine On
|
2770 |
Â
|
2802 |
Â
<IfModule mod_mime.c>
|
2803 |
Â
AddType image/webp .webp
|
2804 |
Â
</IfModule>
|
2805 |
+
' ;
|
2806 |
+
|
2807 |
+
insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', $rules);
|
2808 |
+
insert_with_markers( $upload_base . '.htaccess', 'ShortPixelWebp', $rules);
|
2809 |
+
insert_with_markers( trailingslashit(WP_CONTENT_DIR) . '.htaccess', 'ShortPixelWebp', $rules);
|
2810 |
Â
/* insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', '
|
2811 |
Â
RewriteEngine On
|
2812 |
Â
RewriteBase /
|
2865 |
Â
if(isset($_GET['setsparchive'])) {
|
2866 |
Â
$this->_settings->downloadArchive = intval($_GET['setsparchive']);
|
2867 |
Â
}
|
2868 |
+
|
2869 |
Â
//check all custom folders and update meta table if files appeared
|
2870 |
Â
$customFolders = $this->refreshCustomFolders($notice, isset($_POST['removeFolder']) ? $_POST['removeFolder'] : null);
|
2871 |
+
|
2872 |
Â
if(isset($_POST['request']) && $_POST['request'] == 'request') {
|
2873 |
Â
//a new API Key was requested
|
2874 |
Â
if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
|
2875 |
+
|
2876 |
Â
}
|
2877 |
Â
else {
|
2878 |
+
$notice = array("status" => "error",
|
2879 |
Â
"msg" => __("Please provide a valid e-mail.",'shortpixel-image-optimiser')
|
2880 |
+
. "<BR> "
|
2881 |
Â
. __('For any question regarding obtaining your API Key, please contact us at ','shortpixel-image-optimiser')
|
2882 |
Â
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
2883 |
+
. __(' or ','shortpixel-image-optimiser')
|
2884 |
Â
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
2885 |
Â
}
|
2886 |
Â
}
|
2892 |
Â
$this->cloudflareApi->set_up($cfApi, $cfAuth, $cfZone);
|
2893 |
Â
}
|
2894 |
Â
|
2895 |
+
if( isset($_POST['save']) || isset($_POST['saveAdv'])
|
2896 |
Â
|| (isset($_POST['validate']) && $_POST['validate'] == "validate")
|
2897 |
Â
|| isset($_POST['removeFolder']) || isset($_POST['recheckFolder'])) {
|
2898 |
Â
|
2899 |
Â
//handle API Key - common for save and validate.
|
2900 |
Â
$_POST['key'] = trim(str_replace("*", "", isset($_POST['key']) ? $_POST['key'] : $this->_settings->apiKey)); //the API key might not be set if the editing is disabled.
|
2901 |
+
|
2902 |
Â
if ( strlen($_POST['key']) <> 20 ){
|
2903 |
Â
$KeyLength = strlen($_POST['key']);
|
2904 |
+
|
2905 |
+
$notice = array("status" => "error",
|
2906 |
Â
"msg" => sprintf(__("The key you provided has %s characters. The API key should have 20 characters, letters and numbers only.",'shortpixel-image-optimiser'), $KeyLength)
|
2907 |
+
. "<BR> <b>"
|
2908 |
+
. __('Please check that the API key is the same as the one you received in your confirmation email.','shortpixel-image-optimiser')
|
2909 |
+
. "</b><BR> "
|
2910 |
Â
. __('If this problem persists, please contact us at ','shortpixel-image-optimiser')
|
2911 |
Â
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
2912 |
+
. __(' or ','shortpixel-image-optimiser')
|
2913 |
Â
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
2914 |
Â
}
|
2915 |
Â
else {
|
2916 |
+
|
2917 |
Â
if(isset($_POST['save']) || isset($_POST['saveAdv'])) {
|
2918 |
Â
//these are needed for the call to api-status, set them first.
|
2919 |
+
$this->_settings->siteAuthUser = (isset($_POST['siteAuthUser']) ? sanitize_text_field($_POST['siteAuthUser']) : $this->_settings->siteAuthUser);
|
2920 |
+
$this->_settings->siteAuthPass = (isset($_POST['siteAuthPass']) ? sanitize_text_field($_POST['siteAuthPass']) : $this->_settings->siteAuthPass);
|
2921 |
Â
}
|
2922 |
Â
|
2923 |
Â
$validityData = $this->getQuotaInformation($_POST['key'], true, isset($_POST['validate']) && $_POST['validate'] == "validate", $_POST);
|
2924 |
+
|
2925 |
Â
$this->_settings->apiKey = $_POST['key'];
|
2926 |
Â
if($validityData['APIKeyValid']) {
|
2927 |
Â
if(isset($_POST['validate']) && $_POST['validate'] == "validate") {
|
2936 |
Â
$notice = array("status" => "warn", "msg" => __("API Key is valid but your site is not accessible from our servers. Please make sure that your server is accessible from the Internet before using the API or otherwise we won't be able to optimize them.",'shortpixel-image-optimiser'));
|
2937 |
Â
} else {
|
2938 |
Â
if ( function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"))
|
2939 |
+
$notice = array("status" => "success", "msg" => __("Great, your API Key is valid! <br>You seem to be running a multisite, please note that API Key can also be configured in wp-config.php like this:",'shortpixel-image-optimiser')
|
2940 |
Â
. "<BR> <b>define('SHORTPIXEL_API_KEY', '".$this->_settings->apiKey."');</b>");
|
2941 |
Â
else
|
2942 |
Â
$notice = array("status" => "success", "msg" => __('Great, your API Key is valid. Please take a few moments to review the plugin settings below before starting to optimize your images.','shortpixel-image-optimiser'));
|
2945 |
Â
$this->_settings->verifiedKey = true;
|
2946 |
Â
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
2947 |
Â
if ( !file_exists(SHORTPIXEL_BACKUP_FOLDER) && !@mkdir(SHORTPIXEL_BACKUP_FOLDER, 0777, true) )
|
2948 |
+
$notice = array("status" => "error",
|
2949 |
+
"msg" => sprintf(__("There is something preventing us to create a new folder for backing up your original files.<BR>Please make sure that folder <b>%s</b> has the necessary write and read rights.",'shortpixel-image-optimiser'),
|
2950 |
Â
WP_CONTENT_DIR . '/' . SHORTPIXEL_UPLOADS_NAME ));
|
2951 |
Â
} else {
|
2952 |
Â
if(isset($_POST['validate'])) {
|
2959 |
Â
|
2960 |
Â
//if save button - we process the rest of the form elements
|
2961 |
Â
if(isset($_POST['save']) || isset($_POST['saveAdv'])) {
|
2962 |
+
$this->_settings->compressionType = intval($_POST['compressionType']);
|
2963 |
Â
if(isset($_POST['thumbnails'])) { $this->_settings->processThumbnails = 1; } else { $this->_settings->processThumbnails = 0; }
|
2964 |
Â
if(isset($_POST['backupImages'])) { $this->_settings->backupImages = 1; } else { $this->_settings->backupImages = 0; }
|
2965 |
Â
if(isset($_POST['cmyk2rgb'])) { $this->_settings->CMYKtoRGBconversion = 1; } else { $this->_settings->CMYKtoRGBconversion = 0; }
|
2966 |
Â
$this->_settings->keepExif = isset($_POST['removeExif']) ? 0 : 1;
|
2967 |
Â
//delete_option('wp-short-pixel-keep-exif');
|
2968 |
Â
$this->_settings->resizeImages = (isset($_POST['resize']) ? 1: 0);
|
2969 |
+
$this->_settings->resizeType = (isset($_POST['resize_type']) ? sanitize_text_field($_POST['resize_type']) : false);
|
2970 |
Â
$this->_settings->resizeWidth = (isset($_POST['width']) ? intval($_POST['width']): $this->_settings->resizeWidth);
|
2971 |
Â
$this->_settings->resizeHeight = (isset($_POST['height']) ? intval($_POST['height']): $this->_settings->resizeHeight);
|
2972 |
Â
$uploadPath = realpath(SHORTPIXEL_UPLOADS_BASE);
|
2973 |
Â
|
2974 |
+
if(isset($_POST['nextGen'])) {
|
2975 |
Â
WpShortPixelDb::checkCustomTables(); // check if custom tables are created, if not, create them
|
2976 |
Â
$prevNextGen = $this->_settings->includeNextGen;
|
2977 |
+
$this->_settings->includeNextGen = 1;
|
2978 |
Â
$ret = $this->addNextGenGalleriesToCustom($prevNextGen);
|
2979 |
Â
$folderMsg = $ret["message"];
|
2980 |
Â
$customFolders = $ret["customFolders"];
|
2981 |
+
} else {
|
2982 |
+
$this->_settings->includeNextGen = 0;
|
2983 |
Â
}
|
2984 |
Â
if(isset($_POST['addCustomFolder']) && strlen($_POST['addCustomFolder']) > 0) {
|
2985 |
Â
$folderMsg = $this->spMetaDao->newFolderFromPath(stripslashes($_POST['addCustomFolder']), $uploadPath, self::getCustomFolderBase());
|
2987 |
Â
$notice = array("status" => "success", "msg" => __('Folder added successfully.','shortpixel-image-optimiser'));
|
2988 |
Â
}
|
2989 |
Â
$customFolders = $this->spMetaDao->getFolders();
|
2990 |
+
$this->_settings->hasCustomFolders = time();
|
2991 |
Â
}
|
2992 |
+
|
2993 |
Â
$this->_settings->createWebp = (isset($_POST['createWebp']) ? 1: 0);
|
2994 |
Â
|
2995 |
Â
|
3034 |
Â
$this->_settings->optimizeUnlisted = (isset($_POST['optimizeUnlisted']) ? 1: 0);
|
3035 |
Â
$this->_settings->optimizePdfs = (isset($_POST['optimizePdfs']) ? 1: 0);
|
3036 |
Â
$this->_settings->png2jpg = (isset($_POST['png2jpg']) ? (isset($_POST['png2jpgForce']) ? 2 : 1): 0);
|
3037 |
+
|
3038 |
Â
//die(var_dump($_POST['excludePatterns']));
|
3039 |
+
|
3040 |
Â
if(isset($_POST['excludePatterns']) && strlen($_POST['excludePatterns'])) {
|
3041 |
+
$patterns = array();
|
3042 |
Â
$items = explode(',', $_POST['excludePatterns']);
|
3043 |
Â
foreach($items as $pat) {
|
3044 |
Â
$parts = explode(':', $pat);
|
3057 |
Â
$this->_settings->excludeSizes = (isset($_POST['excludeSizes']) ? $_POST['excludeSizes']: array());
|
3058 |
Â
|
3059 |
Â
//Redirect to bulk processing if requested
|
3060 |
+
if( isset($_POST['save']) && $_POST['save'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')
|
3061 |
Â
|| isset($_POST['saveAdv']) && $_POST['saveAdv'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')) {
|
3062 |
Â
wp_redirect("upload.php?page=wp-short-pixel-bulk");
|
3063 |
Â
exit();
|
3064 |
+
}
|
3065 |
Â
}
|
3066 |
+
if(isset($_POST['removeFolder']) && strlen(($_POST['removeFolder']))) {
|
3067 |
Â
$this->spMetaDao->removeFolder($_POST['removeFolder']);
|
3068 |
Â
$customFolders = $this->spMetaDao->getFolders();
|
3069 |
Â
$_POST["saveAdv"] = true;
|
3070 |
Â
}
|
3071 |
+
if(isset($_POST['recheckFolder']) && strlen(($_POST['recheckFolder']))) {
|
3072 |
Â
//$folder->fullRefreshCustomFolder($_POST['recheckFolder']); //aici singura solutie pare callback care spune daca exita url-ul complet
|
3073 |
Â
}
|
3074 |
Â
}
|
3077 |
Â
if(isset($_REQUEST['noheader'])) {
|
3078 |
Â
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
3079 |
Â
}
|
3080 |
+
|
3081 |
Â
//empty backup
|
3082 |
Â
if(isset($_POST['emptyBackup'])) {
|
3083 |
Â
$this->emptyBackup();
|
3084 |
Â
}
|
3085 |
+
|
3086 |
Â
$quotaData = $this->checkQuotaAndAlert(isset($validityData) ? $validityData : null, isset($_GET['checkquota']));
|
3087 |
+
|
3088 |
Â
if($this->hasNextGen) {
|
3089 |
Â
$ngg = array_map(array('ShortPixelNextGenAdapter','pathToAbsolute'), ShortPixelNextGenAdapter::getGalleries());
|
3090 |
Â
//die(var_dump($ngg));
|
3098 |
Â
$showApiKey = ( (is_main_site() || (function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY")))
|
3099 |
Â
&& !defined("SHORTPIXEL_HIDE_API_KEY"));
|
3100 |
Â
$editApiKey = !defined("SHORTPIXEL_API_KEY") && $showApiKey;
|
3101 |
+
|
3102 |
Â
if($this->_settings->verifiedKey) {
|
3103 |
Â
$fileCount = number_format($this->_settings->fileCount);
|
3104 |
Â
$savedSpace = self::formatBytes($this->_settings->savedSpace,2);
|
3119 |
Â
$cloudflareAPI = true;
|
3120 |
Â
|
3121 |
Â
$this->view->displaySettings($showApiKey, $editApiKey,
|
3122 |
+
$quotaData, $notice, $resources, $averageCompression, $savedSpace, $savedBandwidth, $remainingImages,
|
3123 |
+
$totalCallsMade, $fileCount, null /*folder size now on AJAX*/, $customFolders,
|
3124 |
Â
$folderMsg, $folderMsg ? $addedFolder : false, isset($_POST['saveAdv']), $cloudflareAPI, $htaccessWriteable, $isNginx );
|
3125 |
Â
} else {
|
3126 |
+
$this->view->displaySettings($showApiKey, $editApiKey, $quotaData, $notice);
|
3127 |
Â
}
|
3128 |
+
|
3129 |
Â
}
|
3130 |
Â
|
3131 |
Â
public function addNextGenGalleriesToCustom($silent) {
|
3132 |
+
$customFolders = array();
|
3133 |
Â
$folderMsg = "";
|
3134 |
Â
if($this->_settings->includeNextGen) {
|
3135 |
Â
//add the NextGen galleries to custom folders
|
3140 |
Â
$msg = $this->spMetaDao->newFolderFromPath($gallery, ABSPATH, self::getCustomFolderBase());
|
3141 |
Â
}
|
3142 |
Â
$folderMsg .= $msg;
|
3143 |
+
$this->_settings->hasCustomFolders = time();
|
3144 |
Â
}
|
3145 |
Â
$customFolders = $this->spMetaDao->getFolders();
|
3146 |
Â
}
|
3147 |
Â
return array("message" => $silent? "" : $folderMsg, "customFolders" => $customFolders);
|
3148 |
Â
}
|
3149 |
+
|
3150 |
Â
public function getAverageCompression(){
|
3151 |
+
return $this->_settings->totalOptimized > 0
|
3152 |
+
? round(( 1 - ( $this->_settings->totalOptimized / $this->_settings->totalOriginal ) ) * 100, 2)
|
3153 |
Â
: 0;
|
3154 |
Â
}
|
3155 |
+
|
3156 |
Â
/**
|
3157 |
+
*
|
3158 |
Â
* @param type $apiKey
|
3159 |
Â
* @param type $appendUserAgent
|
3160 |
Â
* @param type $validate - true if we are validating the api key, send also the domain name and number of pics
|
3161 |
Â
* @return type
|
3162 |
Â
*/
|
3163 |
Â
public function getQuotaInformation($apiKey = null, $appendUserAgent = false, $validate = false, $settings = false) {
|
3164 |
+
|
3165 |
Â
if(is_null($apiKey)) { $apiKey = $this->_settings->apiKey; }
|
3166 |
+
|
3167 |
Â
if($this->_settings->httpProto != 'https' && $this->_settings->httpProto != 'http') {
|
3168 |
Â
$this->_settings->httpProto = 'https';
|
3169 |
Â
}
|
3191 |
Â
$argsStr .= "&host={$args['body']['host']}";
|
3192 |
Â
if(strlen($this->_settings->siteAuthUser)) {
|
3193 |
Â
$args['body']['user'] = $this->_settings->siteAuthUser;
|
3194 |
+
$args['body']['pass'] = $this->_settings->siteAuthPass;
|
3195 |
+
$argsStr .= '&user=' . urlencode($args['body']['user']) . '&pass=' . urlencode($args['body']['pass']);
|
3196 |
Â
}
|
3197 |
Â
if($settings !== false) {
|
3198 |
Â
$args['body']['Settings'] = $settings;
|
3208 |
Â
$response = wp_remote_post($requestURL, $args);
|
3209 |
Â
|
3210 |
Â
$comm['A: ' . (number_format(microtime(true) - $time, 2))] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
3211 |
+
|
3212 |
Â
//some hosting providers won't allow https:// POST connections so we try http:// as well
|
3213 |
Â
if(is_wp_error( $response )) {
|
3214 |
Â
//echo("protocol " . $this->_settings->httpProto . " failed. switching...");
|
3215 |
+
$requestURL = $this->_settings->httpProto == 'https' ?
|
3216 |
Â
str_replace('https://', 'http://', $requestURL) :
|
3217 |
Â
str_replace('http://', 'https://', $requestURL);
|
3218 |
Â
// add or remove the sslverify
|
3221 |
Â
} else {
|
3222 |
Â
unset($args['sslverify']);
|
3223 |
Â
}
|
3224 |
+
$response = wp_remote_post($requestURL, $args);
|
3225 |
Â
$comm['B: ' . (number_format(microtime(true) - $time, 2))] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
3226 |
+
|
3227 |
Â
if(!is_wp_error( $response )){
|
3228 |
Â
$this->_settings->httpProto = ($this->_settings->httpProto == 'https' ? 'http' : 'https');
|
3229 |
Â
//echo("protocol " . $this->_settings->httpProto . " succeeded");
|
3230 |
Â
} else {
|
3231 |
+
//echo("protocol " . $this->_settings->httpProto . " failed too");
|
3232 |
Â
}
|
3233 |
Â
}
|
3234 |
Â
//Second fallback to HTTP get
|
3257 |
Â
$defaultData = is_array($this->_settings->currentStats) ? array_merge( $this->_settings->currentStats, $defaultData) : $defaultData;
|
3258 |
Â
|
3259 |
Â
if(is_object($response) && get_class($response) == 'WP_Error') {
|
3260 |
+
|
3261 |
Â
$urlElements = parse_url($requestURL);
|
3262 |
Â
$portConnect = @fsockopen($urlElements['host'],8,$errno,$errstr,15);
|
3263 |
Â
if(!$portConnect) {
|
3281 |
Â
return $defaultData;
|
3282 |
Â
}
|
3283 |
Â
|
3284 |
+
if ( ( $data->APICallsMade + $data->APICallsMadeOneTime ) < ( $data->APICallsQuota + $data->APICallsQuotaOneTime ) ) //reset quota exceeded flag -> user is allowed to process more images.
|
3285 |
Â
$this->resetQuotaExceeded();
|
3286 |
Â
else
|
3287 |
+
$this->_settings->quotaExceeded = 1;//activate quota limiting
|
3288 |
Â
|
3289 |
Â
//if a non-valid status exists, delete it
|
3290 |
Â
$lastStatus = $this->_settings->bulkLastStatus = null;
|
3313 |
Â
|
3314 |
Â
return $dataArray;
|
3315 |
Â
}
|
3316 |
+
|
3317 |
Â
public function resetQuotaExceeded() {
|
3318 |
Â
if( $this->_settings->quotaExceeded == 1) {
|
3319 |
Â
$dismissed = $this->_settings->dismissedNotices ? $this->_settings->dismissedNotices : array();
|
3333 |
Â
return;
|
3334 |
Â
}
|
3335 |
Â
|
3336 |
+
$file = get_attached_file($id);
|
3337 |
Â
$data = ShortPixelMetaFacade::sanitizeMeta(wp_get_attachment_metadata($id));
|
3338 |
Â
|
3339 |
Â
if($extended && isset($_GET['SHORTPIXEL_DEBUG'])) {
|
3353 |
Â
$this->view->renderCustomColumn($id, $renderData, $extended);
|
3354 |
Â
return;
|
3355 |
Â
}
|
3356 |
+
|
3357 |
Â
//empty data means document, we handle only PDF
|
3358 |
Â
elseif (empty($data)) { //TODO asta devine if si decomentam returnurile
|
3359 |
Â
if($fileExtension == "pdf") {
|
3360 |
Â
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
3361 |
Â
$renderData['message'] = __('PDF not processed.','shortpixel-image-optimiser');
|
3362 |
+
}
|
3363 |
Â
else { //Optimization N/A
|
3364 |
Â
$renderData['status'] = 'n/a';
|
3365 |
Â
}
|
3366 |
Â
$this->view->renderCustomColumn($id, $renderData, $extended);
|
3367 |
Â
return;
|
3368 |
+
}
|
3369 |
+
|
3370 |
Â
if(!isset($data['ShortPixelImprovement'])) { //new image
|
3371 |
Â
$data['ShortPixelImprovement'] = '';
|
3372 |
Â
}
|
3373 |
+
|
3374 |
+
if( is_numeric($data['ShortPixelImprovement'])
|
3375 |
Â
&& !($data['ShortPixelImprovement'] == 0 && isset($data['ShortPixel']['WaitingProcessing'])) //for images that erroneously have ShortPixelImprovement = 0 when WaitingProcessing
|
3376 |
Â
) { //already optimized
|
3377 |
Â
$sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
|
3387 |
Â
}
|
3388 |
Â
}
|
3389 |
Â
}
|
3390 |
+
|
3391 |
Â
$renderData['status'] = $fileExtension == "pdf" ? 'pdfOptimized' : 'imgOptimized';
|
3392 |
Â
$renderData['percent'] = $this->optimizationPercentIfPng2Jpg($data);
|
3393 |
Â
$renderData['bonus'] = ($data['ShortPixelImprovement'] < 5);
|
3404 |
Â
$renderData['exifKept'] = isset($data['ShortPixel']['exifKept']) ? $data['ShortPixel']['exifKept'] : null;
|
3405 |
Â
$renderData['png2jpg'] = isset($data['ShortPixelPng2Jpg']) ? $data['ShortPixelPng2Jpg'] : 0;
|
3406 |
Â
$renderData['date'] = isset($data['ShortPixel']['date']) ? $data['ShortPixel']['date'] : null;
|
3407 |
+
$renderData['quotaExceeded'] = $quotaExceeded;
|
3408 |
Â
$webP = 0;
|
3409 |
Â
if($extended) {
|
3410 |
Â
if(file_exists(dirname($file) . '/' . ShortPixelAPI::MB_basename($file, '.'.$fileExtension) . '.webp' )){
|
3457 |
Â
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
3458 |
Â
$sizes = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
|
3459 |
Â
$renderData['thumbsTotal'] = $sizes;
|
3460 |
+
$renderData['message'] = ($fileExtension == "pdf" ? 'PDF' : __('Image','shortpixel-image-optimiser'))
|
3461 |
Â
. __(' not processed.','shortpixel-image-optimiser')
|
3462 |
+
. ' (<a href="https://shortpixel.com/image-compression-test?site-url=' . urlencode(ShortPixelMetaFacade::safeGetAttachmentUrl($id)) . '" target="_blank">'
|
3463 |
Â
. __('Test for free','shortpixel-image-optimiser') . '</a>)';
|
3464 |
+
}
|
3465 |
Â
$this->view->renderCustomColumn($id, $renderData, $extended);
|
3466 |
Â
}
|
3467 |
Â
}
|
3536 |
Â
);
|
3537 |
Â
}
|
3538 |
Â
}
|
3539 |
+
|
3540 |
Â
function shortpixelInfoBoxContent( $post ) {
|
3541 |
Â
$this->generateCustomColumn( 'wp-shortPixel', $post->ID, true );
|
3542 |
Â
}
|
3543 |
+
|
3544 |
Â
public function onDeleteImage($post_id) {
|
3545 |
Â
$itemHandler = new ShortPixelMetaFacade($post_id);
|
3546 |
Â
$urlsPaths = $itemHandler->getURLsAndPATHs(true, false, true, array(), true);
|
3572 |
Â
public function columns( $defaults ) {
|
3573 |
Â
$defaults['wp-shortPixel'] = __('ShortPixel Compression', 'shortpixel-image-optimiser');
|
3574 |
Â
if(current_user_can( 'manage_options' )) {
|
3575 |
+
$defaults['wp-shortPixel'] .=
|
3576 |
+
' <a href="options-general.php?page=wp-shortpixel#stats" title="'
|
3577 |
+
. __('ShortPixel Statistics','shortpixel-image-optimiser')
|
3578 |
Â
. '"><span class="dashicons dashicons-dashboard"></span></a>';
|
3579 |
Â
}
|
3580 |
Â
return $defaults;
|
3591 |
Â
public function nggCountColumns( $count ) {
|
3592 |
Â
return $count + 1;
|
3593 |
Â
}
|
3594 |
+
|
3595 |
Â
public function nggColumnHeader( $default ) {
|
3596 |
Â
return __('ShortPixel Compression','shortpixel-image-optimiser');
|
3597 |
Â
}
|
3598 |
Â
|
3599 |
Â
public function nggColumnContent( $unknown, $picture ) {
|
3600 |
+
|
3601 |
Â
$meta = $this->spMetaDao->getMetaForPath($picture->imagePath);
|
3602 |
Â
if($meta) {
|
3603 |
Â
switch($meta->getStatus()) {
|
3614 |
Â
'thumbsTotal' => 0,
|
3615 |
Â
'retinasOpt' => 0,
|
3616 |
Â
'backup' => true
|
3617 |
+
));
|
3618 |
Â
break;
|
3619 |
Â
}
|
3620 |
Â
} else {
|
3626 |
Â
'thumbsTotal' => 0,
|
3627 |
Â
'retinasOpt' => 0,
|
3628 |
Â
'message' => "Not optimized"
|
3629 |
+
));
|
3630 |
Â
}
|
3631 |
Â
// return var_dump($meta);
|
3632 |
Â
}
|
3648 |
Â
|
3649 |
Â
return round($bytes, $precision) . ' ' . $units[$pow];
|
3650 |
Â
}
|
3651 |
+
|
3652 |
Â
public function isProcessable($ID, $excludeExtensions = array()) {
|
3653 |
Â
$excludePatterns = $this->_settings->excludePatterns;
|
3654 |
Â
return self::_isProcessable($ID, $excludeExtensions, $excludePatterns);
|
3655 |
Â
}
|
3656 |
+
|
3657 |
Â
public function isProcessablePath($path, $excludeExtensions = array()) {
|
3658 |
Â
$excludePatterns = $this->_settings->excludePatterns;
|
3659 |
Â
return self::_isProcessablePath($path, $excludeExtensions, $excludePatterns);
|
3660 |
Â
}
|
3661 |
+
|
3662 |
Â
static public function _isProcessable($ID, $excludeExtensions = array(), $excludePatterns = array(), $meta = false) {
|
3663 |
Â
$path = get_attached_file($ID);//get the full file PATH
|
3664 |
Â
if(isset($excludePatterns) && is_array($excludePatterns)) {
|
3672 |
Â
}
|
3673 |
Â
}
|
3674 |
Â
}
|
3675 |
+
}
|
3676 |
Â
return $path ? self::_isProcessablePath($path, $excludeExtensions, $excludePatterns) : false;
|
3677 |
Â
}
|
3678 |
+
|
3679 |
Â
static public function _isProcessablePath($path, $excludeExtensions = array(), $excludePatterns = array()) {
|
3680 |
Â
$pathParts = pathinfo($path);
|
3681 |
Â
$ext = isset($pathParts['extension']) ? $pathParts['extension'] : false;
|
3705 |
Â
$heightBounds = isset($ranges[1]) ? explode("-", $ranges[1]) : false;
|
3706 |
Â
if(!isset($heightBounds[1])) $heightBounds[1] = $heightBounds[0];
|
3707 |
Â
if( $width >= 0 + $widthBounds[0] && $width <= 0 + $widthBounds[1]
|
3708 |
+
&& ( $heightBounds === false
|
3709 |
Â
|| ($height >= 0 + $heightBounds[0] && $height <= 0 + $heightBounds[1]))) {
|
3710 |
Â
return false;
|
3711 |
Â
}
|
3722 |
Â
public function getURLsAndPATHs($itemHandler, $meta = NULL, $onlyThumbs = false) {
|
3723 |
Â
return $itemHandler->getURLsAndPATHs($this->_settings->processThumbnails, $onlyThumbs, $this->_settings->optimizeRetina, $this->_settings->excludeSizes);
|
3724 |
Â
}
|
3725 |
+
|
3726 |
Â
|
3727 |
Â
public static function deleteDir($dirPath) {
|
3728 |
Â
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
|
3748 |
Â
}
|
3749 |
Â
$cleanPath = rtrim($path, '/'). '/';
|
3750 |
Â
foreach($files as $t) {
|
3751 |
+
if ($t<>"." && $t<>"..")
|
3752 |
Â
{
|
3753 |
Â
$currentFile = $cleanPath . $t;
|
3754 |
Â
if (is_dir($currentFile)) {
|
3763 |
Â
}
|
3764 |
Â
return $total_size;
|
3765 |
Â
}
|
3766 |
+
|
3767 |
Â
public function migrateBackupFolder() {
|
3768 |
Â
$oldBackupFolder = WP_CONTENT_DIR . '/' . SHORTPIXEL_BACKUP;
|
3769 |
Â
|
3790 |
Â
@mkdir(SHORTPIXEL_BACKUP_FOLDER);
|
3791 |
Â
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER.'/'.SHORTPIXEL_UPLOADS_NAME);
|
3792 |
Â
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {//just in case..
|
3793 |
+
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER);
|
3794 |
Â
}
|
3795 |
Â
}
|
3796 |
Â
//then create the wp-content level if not present
|
3799 |
Â
@mkdir(SHORTPIXEL_BACKUP_FOLDER);
|
3800 |
Â
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER.'/' . basename(WP_CONTENT_DIR));
|
3801 |
Â
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {//just in case..
|
3802 |
+
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER);
|
3803 |
Â
}
|
3804 |
Â
}
|
3805 |
Â
return;
|
3822 |
Â
}
|
3823 |
Â
return $sizes;
|
3824 |
Â
}
|
3825 |
+
|
3826 |
Â
function getMaxIntermediateImageSize() {
|
3827 |
Â
global $_wp_additional_image_sizes;
|
3828 |
Â
|
3845 |
Â
return array('width' => max(100, $width), 'height' => max(100, $height));
|
3846 |
Â
}
|
3847 |
Â
|
3848 |
+
public function getOtherCompressionTypes($compressionType = false) {
|
3849 |
Â
return array_values(array_diff(array(0, 1, 2), array(0 + $compressionType)));
|
3850 |
Â
}
|
3851 |
Â
|
3931 |
Â
public function getApiKey() {
|
3932 |
Â
return $this->_settings->apiKey;
|
3933 |
Â
}
|
3934 |
+
|
3935 |
Â
public function getPrioQ() {
|
3936 |
Â
return $this->prioQ;
|
3937 |
Â
}
|
3938 |
+
|
3939 |
Â
public function backupImages() {
|
3940 |
Â
return $this->_settings->backupImages;
|
3941 |
Â
}
|
3943 |
Â
public function processThumbnails() {
|
3944 |
Â
return $this->_settings->processThumbnails;
|
3945 |
Â
}
|
3946 |
+
|
3947 |
Â
public function getCMYKtoRGBconversion() {
|
3948 |
Â
return $this->_settings->CMYKtoRGBconversion;
|
3949 |
Â
}
|
3950 |
+
|
3951 |
Â
public function getSettings() {
|
3952 |
Â
return $this->_settings;
|
3953 |
Â
}
|
3979 |
Â
public function hasNextGen() {
|
3980 |
Â
return $this->hasNextGen;
|
3981 |
Â
}
|
3982 |
+
|
3983 |
Â
public function getSpMetaDao() {
|
3984 |
Â
return $this->spMetaDao;
|
3985 |
Â
}
|
@@ -61,7 +61,7 @@ class WPShortPixelSettings {
|
|
61 |
Â
'thumbsCount' => array('key' => 'wp-short-pixel-thumbnail-count', 'default' => 0, 'group' => 'state'),
|
62 |
Â
'under5Percent' => array('key' => 'wp-short-pixel-files-under-5-percent', 'default' => 0, 'group' => 'state'),
|
63 |
Â
'savedSpace' => array('key' => 'wp-short-pixel-savedSpace', 'default' => 0, 'group' => 'state'),
|
64 |
-
'averageCompression' => array('key' => 'wp-short-pixel-averageCompression', 'default' => null, 'group' => 'state'),
|
65 |
Â
'apiRetries' => array('key' => 'wp-short-pixel-api-retries', 'default' => 0, 'group' => 'state'),
|
66 |
Â
'totalOptimized' => array('key' => 'wp-short-pixel-total-optimized', 'default' => 0, 'group' => 'state'),
|
67 |
Â
'totalOriginal' => array('key' => 'wp-short-pixel-total-original', 'default' => 0, 'group' => 'state'),
|
61 |
Â
'thumbsCount' => array('key' => 'wp-short-pixel-thumbnail-count', 'default' => 0, 'group' => 'state'),
|
62 |
Â
'under5Percent' => array('key' => 'wp-short-pixel-files-under-5-percent', 'default' => 0, 'group' => 'state'),
|
63 |
Â
'savedSpace' => array('key' => 'wp-short-pixel-savedSpace', 'default' => 0, 'group' => 'state'),
|
64 |
+
//'averageCompression' => array('key' => 'wp-short-pixel-averageCompression', 'default' => null, 'group' => 'state'),
|
65 |
Â
'apiRetries' => array('key' => 'wp-short-pixel-api-retries', 'default' => 0, 'group' => 'state'),
|
66 |
Â
'totalOptimized' => array('key' => 'wp-short-pixel-total-optimized', 'default' => 0, 'group' => 'state'),
|
67 |
Â
'totalOriginal' => array('key' => 'wp-short-pixel-total-original', 'default' => 0, 'group' => 'state'),
|
@@ -4,7 +4,7 @@ Tags: compressor, image, compression, optimize, image optimizer, image optimiser
|
|
4 |
Â
Requires at least: 3.2.0
|
5 |
Â
Tested up to: 5.1
|
6 |
Â
Requires PHP: 5.2
|
7 |
-
Stable tag: 4.
|
8 |
Â
License: GPLv2 or later
|
9 |
Â
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
Â
|
@@ -241,6 +241,21 @@ The ShortPixel Image Optimiser plugin calls the following actions and filters:
|
|
241 |
Â
|
242 |
Â
== Changelog ==
|
243 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
244 |
Â
= 4.12.8 =
|
245 |
Â
|
246 |
Â
Release date: 25th February 2019
|
4 |
Â
Requires at least: 3.2.0
|
5 |
Â
Tested up to: 5.1
|
6 |
Â
Requires PHP: 5.2
|
7 |
+
Stable tag: 4.13.0
|
8 |
Â
License: GPLv2 or later
|
9 |
Â
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
Â
|
241 |
Â
|
242 |
Â
== Changelog ==
|
243 |
Â
|
244 |
+
= 4.13.0 =
|
245 |
+
|
246 |
+
Release date: 10th April 2019
|
247 |
+
* Bulk restore for the Other Media
|
248 |
+
* make the filename extension be updated when manually optimizing a PNG from Media Library, if the convert to JPG is active, without refreshing the page
|
249 |
+
* Integration with Regenerate Thumbnails Advanced new 2.0 beta version
|
250 |
+
* Add the rules for WebP in the WP-CONTENT .htaccess
|
251 |
+
* ShortPixel Other Media - display the time of optimization in the grid and offer option to sort by it
|
252 |
+
* Keep sort order when optimizing / refreshing page on Other Media
|
253 |
+
* offer the visual comparer for Other Media too
|
254 |
+
* resolve the Settings inconsistency in Other Media (settings displayed were from when adding the folder not from when actually optimizing)
|
255 |
+
* Make pressing Escape or clicking outside of any popup close it.
|
256 |
+
* Fixed: Restoring an Other Media item and then Optimizing it again optimizes it Lossless
|
257 |
+
* fix generating the WebP <picture> tags when the images are either on a subdomain or on a CDN domain having the same root domain as the main site.
|
258 |
+
|
259 |
Â
= 4.12.8 =
|
260 |
Â
|
261 |
Â
Release date: 25th February 2019
|
@@ -41,3 +41,7 @@ li.shortpixel-toolbar-processing.shortpixel-alert > a.ab-item > div,
|
|
41 |
Â
width:100%;
|
42 |
Â
float:left;
|
43 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
41 |
Â
width:100%;
|
42 |
Â
float:left;
|
43 |
Â
}
|
44 |
+
.short-pixel-notice-icon {
|
45 |
+
float:left;
|
46 |
+
margin: 10px 10px 10px 0;
|
47 |
+
}
|
@@ -1 +1 @@
|
|
1 |
-
li.shortpixel-toolbar-processing>a.ab-item>div,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div{height:33px;margin-top:-1px;padding:0 3px}li.shortpixel-toolbar-processing>a.ab-item>div>img,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div>img{margin-right:2px;margin-top:6px}li.shortpixel-toolbar-processing>a.ab-item>div>span.shp-alert,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div>span.shp-alert{display:none}li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div>span.shp-alert,#wpadminbar li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div>span.shp-alert{display:inline;font-size:26px;color:red;font-weight:bold;vertical-align:top}li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div,#wpadminbar li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div{background-image:none}.sp-quota-exceeded-alert{background-color:#fff;border-left:4px solid red;box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);padding:1px 12px}.shortpixel-clearfix{width:100%;float:left}
|
1 |
+
li.shortpixel-toolbar-processing>a.ab-item>div,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div{height:33px;margin-top:-1px;padding:0 3px}li.shortpixel-toolbar-processing>a.ab-item>div>img,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div>img{margin-right:2px;margin-top:6px}li.shortpixel-toolbar-processing>a.ab-item>div>span.shp-alert,#wpadminbar li.shortpixel-toolbar-processing>a.ab-item>div>span.shp-alert{display:none}li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div>span.shp-alert,#wpadminbar li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div>span.shp-alert{display:inline;font-size:26px;color:red;font-weight:bold;vertical-align:top}li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div,#wpadminbar li.shortpixel-toolbar-processing.shortpixel-alert>a.ab-item>div{background-image:none}.sp-quota-exceeded-alert{background-color:#fff;border-left:4px solid red;box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);padding:1px 12px}.shortpixel-clearfix{width:100%;float:left}.short-pixel-notice-icon{float:left;margin:10px 10px 10px 0}
|
@@ -0,0 +1,46 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
div.sp-modal-shade {
|
2 |
+
display: none; /* Hidden by default */
|
3 |
+
position: fixed; /* Stay in place */
|
4 |
+
z-index: 10; /* Sit on top */
|
5 |
+
left: 0;
|
6 |
+
top: 0;
|
7 |
+
width: 100%; /* Full width */
|
8 |
+
height: 100%; /* Full height */
|
9 |
+
overflow: auto; /* Enable scroll if needed */
|
10 |
+
background-color: rgb(0,0,0); /* Fallback color */
|
11 |
+
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
12 |
+
}
|
13 |
+
div.shortpixel-modal {
|
14 |
+
background-color: #fefefe;
|
15 |
+
/*margin: 8% auto; 15% from the top and centered */
|
16 |
+
padding: 20px;
|
17 |
+
border: 1px solid #888;
|
18 |
+
width: 30%; /* Could be more or less, depending on screen size */
|
19 |
+
min-width: 300px; /* Could be more or less, depending on screen size */
|
20 |
+
z-index: 100; /* Proper z-index */
|
21 |
+
position: fixed;
|
22 |
+
top: 10%;
|
23 |
+
left: 50%;
|
24 |
+
max-height: 90%;
|
25 |
+
overflow-y: auto;
|
26 |
+
}
|
27 |
+
div.shortpixel-modal .sp-close-button, div.shortpixel-modal .sp-close-upgrade-button {
|
28 |
+
float: right;
|
29 |
+
margin-top: 0px;
|
30 |
+
background: transparent;
|
31 |
+
border: none;
|
32 |
+
font-size: 22px;
|
33 |
+
line-height: 10px;
|
34 |
+
cursor: pointer;
|
35 |
+
}
|
36 |
+
div.shortpixel-modal .sptw-modal-spinner {
|
37 |
+
background-image: url("../img/spinner2.gif");
|
38 |
+
background-repeat: no-repeat;
|
39 |
+
background-position: center;
|
40 |
+
}
|
41 |
+
div.sp-modal-title {
|
42 |
+
font-size: 22px;
|
43 |
+
}
|
44 |
+
div.sp-modal-body {
|
45 |
+
margin-top: 20px;
|
46 |
+
}
|
@@ -0,0 +1 @@
|
|
Â
|
1 |
+
div.sp-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0,0.4)}div.shortpixel-modal{background-color:#fefefe;padding:20px;border:1px solid #888;width:30%;min-width:300px;z-index:100;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.shortpixel-modal .sp-close-button,div.shortpixel-modal .sp-close-upgrade-button{float:right;margin-top:0;background:transparent;border:0;font-size:22px;line-height:10px;cursor:pointer}div.shortpixel-modal .sptw-modal-spinner{background-image:url("../img/spinner2.gif");background-repeat:no-repeat;background-position:center}div.sp-modal-title{font-size:22px}div.sp-modal-body{margin-top:20px}
|
@@ -29,7 +29,7 @@
|
|
29 |
Â
background-color: #3e8e41;
|
30 |
Â
}
|
31 |
Â
*/
|
32 |
-
|
33 |
Â
/* The container <div> - needed to position the dropdown content */
|
34 |
Â
.sp-dropdown {
|
35 |
Â
position: relative;
|
@@ -63,10 +63,10 @@
|
|
63 |
Â
|
64 |
Â
div.fb-like {
|
65 |
Â
transform: scale(1.3);
|
66 |
-
-ms-transform: scale(1.3);
|
67 |
-
-webkit-transform: scale(1.3);
|
68 |
-
-o-transform: scale(1.3);
|
69 |
-
-moz-transform: scale(1.3);
|
70 |
Â
transform-origin: bottom left;
|
71 |
Â
-ms-transform-origin: bottom left;
|
72 |
Â
-webkit-transform-origin: bottom left;
|
@@ -282,56 +282,16 @@ div.shortpixel-rate-us > a:focus {
|
|
282 |
Â
margin-right: 5px;
|
283 |
Â
}
|
284 |
Â
|
285 |
-
div.sp-modal-shade {
|
286 |
-
display: none; /* Hidden by default */
|
287 |
-
position: fixed; /* Stay in place */
|
288 |
-
z-index: 10; /* Sit on top */
|
289 |
-
left: 0;
|
290 |
-
top: 0;
|
291 |
-
width: 100%; /* Full width */
|
292 |
-
height: 100%; /* Full height */
|
293 |
-
overflow: auto; /* Enable scroll if needed */
|
294 |
-
background-color: rgb(0,0,0); /* Fallback color */
|
295 |
-
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
296 |
-
}
|
297 |
-
div.shortpixel-modal {
|
298 |
-
background-color: #fefefe;
|
299 |
-
margin: 8% auto; /* 15% from the top and centered */
|
300 |
-
padding: 20px;
|
301 |
-
border: 1px solid #888;
|
302 |
-
width: 30%; /* Could be more or less, depending on screen size */
|
303 |
-
min-width: 300px; /* Could be more or less, depending on screen size */
|
304 |
-
}
|
305 |
-
div.shortpixel-modal .sp-close-button, div.shortpixel-modal .sp-close-upgrade-button {
|
306 |
-
float: right;
|
307 |
-
margin-top: 0px;
|
308 |
-
background: transparent;
|
309 |
-
border: none;
|
310 |
-
font-size: 22px;
|
311 |
-
line-height: 10px;
|
312 |
-
cursor: pointer;
|
313 |
-
}
|
314 |
Â
.twentytwenty-horizontal .twentytwenty-before-label:before, .twentytwenty-horizontal .twentytwenty-after-label:before {
|
315 |
Â
font-family: inherit;
|
316 |
Â
font-size: 16px;
|
317 |
Â
}
|
318 |
-
div.sp-modal-title {
|
319 |
-
font-size: 22px;
|
320 |
-
}
|
321 |
-
div.sp-modal-body {
|
322 |
-
margin-top: 20px;
|
323 |
-
}
|
324 |
Â
.short-pixel-bulk-page p {
|
325 |
Â
margin: 0.6em 0;
|
326 |
Â
}
|
327 |
-
div.shortpixel-modal .sptw-modal-spinner {
|
328 |
-
background-image: url("../img/spinner2.gif");
|
329 |
-
background-repeat: no-repeat;
|
330 |
-
background-position: center;
|
331 |
-
}
|
332 |
Â
.short-pixel-bulk-page form.start {
|
333 |
-
display:table;
|
334 |
-
content:" ";
|
335 |
Â
width:98%;
|
336 |
Â
background-color:white;
|
337 |
Â
padding:10px 10px 0;
|
@@ -340,8 +300,8 @@ div.shortpixel-modal .sptw-modal-spinner {
|
|
340 |
Â
}
|
341 |
Â
|
342 |
Â
.bulk-stats-container{
|
343 |
-
display: inline-block;
|
344 |
-
min-width:450px;
|
345 |
Â
width: 45%;
|
346 |
Â
float:left;
|
347 |
Â
padding-right: 50px;
|
@@ -349,8 +309,8 @@ div.shortpixel-modal .sptw-modal-spinner {
|
|
349 |
Â
line-height: 1.5em;
|
350 |
Â
}
|
351 |
Â
.bulk-text-container{
|
352 |
-
display: inline-block;
|
353 |
-
min-width:440px;
|
354 |
Â
width: 45%;
|
355 |
Â
float:left;
|
356 |
Â
padding-right: 50px;
|
@@ -361,27 +321,27 @@ div.shortpixel-modal .sptw-modal-spinner {
|
|
361 |
Â
padding-bottom: 0.5em;
|
362 |
Â
}
|
363 |
Â
.bulk-wide {
|
364 |
-
display: inline-block;
|
365 |
Â
width: 90%;
|
366 |
-
float:left;
|
367 |
Â
margin-top: 25px;
|
368 |
Â
}
|
369 |
Â
.bulk-stats-container .bulk-label{
|
370 |
-
width:220px;
|
371 |
Â
display:inline-block;
|
372 |
Â
}
|
373 |
Â
.bulk-stats-container .bulk-val{
|
374 |
-
width:50px;
|
375 |
-
display:inline-block;
|
376 |
Â
text-align: right;
|
377 |
Â
}
|
378 |
Â
.bulk-stats-container .bulk-total{
|
379 |
-
font-weight: bold;
|
380 |
Â
margin-top:10px;
|
381 |
Â
margin-bottom:10px;
|
382 |
Â
}
|
383 |
Â
.wp-core-ui .bulk-play{
|
384 |
-
display: inline;
|
385 |
Â
width: 310px;
|
386 |
Â
float:left;
|
387 |
Â
margin-bottom:20px;
|
@@ -392,7 +352,7 @@ div.shortpixel-modal .sptw-modal-spinner {
|
|
392 |
Â
border: 1px solid;
|
393 |
Â
border-radius: 5px;
|
394 |
Â
margin-top: 60px;
|
395 |
-
padding: 5px 12px;
|
396 |
Â
}
|
397 |
Â
.wp-core-ui .bulk-play a.button{
|
398 |
Â
height:60px;
|
@@ -442,10 +402,6 @@ th.sorted.column-wp-shortPixel a {
|
|
442 |
Â
.wp-core-ui .bulk-play a.button .bulk-btn-txt span.total {
|
443 |
Â
font-size: 1.4em;
|
444 |
Â
}
|
445 |
-
.short-pixel-notice-icon {
|
446 |
-
float:left;
|
447 |
-
margin: 10px 10px 10px 0;
|
448 |
-
}
|
449 |
Â
.bulk-progress {
|
450 |
Â
padding: 20px 32px 17px;
|
451 |
Â
background-color: #ffffff;
|
@@ -544,8 +500,8 @@ th.sorted.column-wp-shortPixel a {
|
|
544 |
Â
}
|
545 |
Â
.bulk-slider .img-original,
|
546 |
Â
.bulk-slider .img-optimized{
|
547 |
-
display:inline-block;
|
548 |
-
margin-right:20px;
|
549 |
Â
text-align: center;
|
550 |
Â
}
|
551 |
Â
.bulk-slider .img-original div,
|
@@ -558,9 +514,9 @@ th.sorted.column-wp-shortPixel a {
|
|
558 |
Â
max-width: 300px;
|
559 |
Â
}
|
560 |
Â
.bulk-slider .img-info{
|
561 |
-
display:inline-block;
|
562 |
Â
vertical-align: top;
|
563 |
-
font-size: 48px;
|
564 |
Â
max-width: 150px;
|
565 |
Â
padding: 10px 0 0 20px;
|
566 |
Â
}
|
@@ -570,7 +526,7 @@ th.sorted.column-wp-shortPixel a {
|
|
570 |
Â
padding: 15px 0 0 20px;
|
571 |
Â
}
|
572 |
Â
p.settings-info {
|
573 |
-
padding-top: 0px;
|
574 |
Â
color: #818181;
|
575 |
Â
font-size:13px !important;
|
576 |
Â
}
|
@@ -871,4 +827,4 @@ section#tab-resources p {
|
|
871 |
Â
|
872 |
Â
@-moz-keyframes cssload-spin {
|
873 |
Â
100%{ -moz-transform: rotate(360deg); transform: rotate(360deg); }
|
874 |
-
}
|
29 |
Â
background-color: #3e8e41;
|
30 |
Â
}
|
31 |
Â
*/
|
32 |
+
|
33 |
Â
/* The container <div> - needed to position the dropdown content */
|
34 |
Â
.sp-dropdown {
|
35 |
Â
position: relative;
|
63 |
Â
|
64 |
Â
div.fb-like {
|
65 |
Â
transform: scale(1.3);
|
66 |
+
-ms-transform: scale(1.3);
|
67 |
+
-webkit-transform: scale(1.3);
|
68 |
+
-o-transform: scale(1.3);
|
69 |
+
-moz-transform: scale(1.3);
|
70 |
Â
transform-origin: bottom left;
|
71 |
Â
-ms-transform-origin: bottom left;
|
72 |
Â
-webkit-transform-origin: bottom left;
|
282 |
Â
margin-right: 5px;
|
283 |
Â
}
|
284 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
285 |
Â
.twentytwenty-horizontal .twentytwenty-before-label:before, .twentytwenty-horizontal .twentytwenty-after-label:before {
|
286 |
Â
font-family: inherit;
|
287 |
Â
font-size: 16px;
|
288 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
289 |
Â
.short-pixel-bulk-page p {
|
290 |
Â
margin: 0.6em 0;
|
291 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
292 |
Â
.short-pixel-bulk-page form.start {
|
293 |
+
display:table;
|
294 |
+
content:" ";
|
295 |
Â
width:98%;
|
296 |
Â
background-color:white;
|
297 |
Â
padding:10px 10px 0;
|
300 |
Â
}
|
301 |
Â
|
302 |
Â
.bulk-stats-container{
|
303 |
+
display: inline-block;
|
304 |
+
min-width:450px;
|
305 |
Â
width: 45%;
|
306 |
Â
float:left;
|
307 |
Â
padding-right: 50px;
|
309 |
Â
line-height: 1.5em;
|
310 |
Â
}
|
311 |
Â
.bulk-text-container{
|
312 |
+
display: inline-block;
|
313 |
+
min-width:440px;
|
314 |
Â
width: 45%;
|
315 |
Â
float:left;
|
316 |
Â
padding-right: 50px;
|
321 |
Â
padding-bottom: 0.5em;
|
322 |
Â
}
|
323 |
Â
.bulk-wide {
|
324 |
+
display: inline-block;
|
325 |
Â
width: 90%;
|
326 |
+
float:left;
|
327 |
Â
margin-top: 25px;
|
328 |
Â
}
|
329 |
Â
.bulk-stats-container .bulk-label{
|
330 |
+
width:220px;
|
331 |
Â
display:inline-block;
|
332 |
Â
}
|
333 |
Â
.bulk-stats-container .bulk-val{
|
334 |
+
width:50px;
|
335 |
+
display:inline-block;
|
336 |
Â
text-align: right;
|
337 |
Â
}
|
338 |
Â
.bulk-stats-container .bulk-total{
|
339 |
+
font-weight: bold;
|
340 |
Â
margin-top:10px;
|
341 |
Â
margin-bottom:10px;
|
342 |
Â
}
|
343 |
Â
.wp-core-ui .bulk-play{
|
344 |
+
display: inline;
|
345 |
Â
width: 310px;
|
346 |
Â
float:left;
|
347 |
Â
margin-bottom:20px;
|
352 |
Â
border: 1px solid;
|
353 |
Â
border-radius: 5px;
|
354 |
Â
margin-top: 60px;
|
355 |
+
padding: 5px 12px;
|
356 |
Â
}
|
357 |
Â
.wp-core-ui .bulk-play a.button{
|
358 |
Â
height:60px;
|
402 |
Â
.wp-core-ui .bulk-play a.button .bulk-btn-txt span.total {
|
403 |
Â
font-size: 1.4em;
|
404 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
405 |
Â
.bulk-progress {
|
406 |
Â
padding: 20px 32px 17px;
|
407 |
Â
background-color: #ffffff;
|
500 |
Â
}
|
501 |
Â
.bulk-slider .img-original,
|
502 |
Â
.bulk-slider .img-optimized{
|
503 |
+
display:inline-block;
|
504 |
+
margin-right:20px;
|
505 |
Â
text-align: center;
|
506 |
Â
}
|
507 |
Â
.bulk-slider .img-original div,
|
514 |
Â
max-width: 300px;
|
515 |
Â
}
|
516 |
Â
.bulk-slider .img-info{
|
517 |
+
display:inline-block;
|
518 |
Â
vertical-align: top;
|
519 |
+
font-size: 48px;
|
520 |
Â
max-width: 150px;
|
521 |
Â
padding: 10px 0 0 20px;
|
522 |
Â
}
|
526 |
Â
padding: 15px 0 0 20px;
|
527 |
Â
}
|
528 |
Â
p.settings-info {
|
529 |
+
padding-top: 0px;
|
530 |
Â
color: #818181;
|
531 |
Â
font-size:13px !important;
|
532 |
Â
}
|
827 |
Â
|
828 |
Â
@-moz-keyframes cssload-spin {
|
829 |
Â
100%{ -moz-transform: rotate(360deg); transform: rotate(360deg); }
|
830 |
+
}
|
@@ -1 +1 @@
|
|
1 |
-
.reset{font-weight:normal;font-style:normal}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}.resumeLabel{float:right;line-height:30px;margin-right:20px;font-size:16px}.sp-dropbtn.button{padding:1px 24px 20px 5px;font-size:20px;cursor:pointer}.sp-dropdown{position:relative;display:inline-block}.sp-dropdown-content{display:none;right:0;position:absolute;background-color:#f9f9f9;min-width:190px;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2);z-index:1}.sp-dropdown-content a{color:black;padding:12px 16px;text-decoration:none;display:block}.sp-dropdown-content a:hover{background-color:#f1f1f1}.sp-dropdown.sp-show .sp-dropdown-content{display:block}div.fb-like{transform:scale(1.3);-ms-transform:scale(1.3);-webkit-transform:scale(1.3);-o-transform:scale(1.3);-moz-transform:scale(1.3);transform-origin:bottom left;-ms-transform-origin:bottom left;-webkit-transform-origin:bottom left;-moz-transform-origin:bottom left;-webkit-transform-origin:bottom left}.wp-core-ui .button.button-alert,.wp-core-ui .button.button-alert:hover{background:#f79797}.wp-core-ui .button.remove-folder-button{min-width:120px}.sp-notice{background:#fff;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:1px 12px}.sp-notice img{vertical-align:bottom}@media(max-width:1249px){.sp-notice{margin:5px 15px 2px}}.sp-notice-info{border-left-color:#00a0d2}.sp-notice-success{border-left-color:#46b450}.sp-notice-warning{border-left-color:#f1e02a}.sp-conflict-plugins{display:table;border-spacing:10px;border-collapse:separate}.sp-conflict-plugins li{display:table-row}.sp-conflict-plugins li>*{display:table-cell}li.sp-conflict-plugins-list{line-height:28px;list-style:disc;margin-left:80px}li.sp-conflict-plugins-list a.button{margin-left:10px}div.short-pixel-bulk-page input.dial{font-size:16px !important}div.short-pixel-bulk-page h1{margin-bottom:20px}div.bulk-progress div.sp-h2{margin-top:0;margin-bottom:10px;font-size:23px;font-weight:400;padding:9px 15px 4px 0;line-height:29px}div.bulk-progress-partners{margin-top:20px}div.bulk-progress.bulk-progress-partners a div{display:inline-block;vertical-align:top;line-height:50px;margin-left:30px;font-size:1.2em}div.bulk-progress .bulk-progress-indicator,div.sp-quota-exceeded-alert .bulk-progress-indicator{display:inline-block;text-align:center;padding:0 10px;margin-left:10px;float:left;height:90px;overflow:hidden;border:1px solid #1caecb}div.wrap.short-pixel-bulk-page .bulk-notice-container{margin-top:15px;position:absolute;width:500px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg{text-align:center;margin:10px 0 0 32px;overflow:hidden;border:1px solid #1caecb;background-color:#9ddbe0;border-radius:5px;padding:7px 10px 10px;display:none;max-width:600px;margin-right:20px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error{border:1px solid #b5914d;background-color:#ffe996;margin-right:20px;position:relative;z-index:10}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error.bulk-error-fatal{border:1px solid #c32525;background-color:#ff969d}div.wrap.short-pixel-bulk-page .bulk-notice-msg img{float:left;margin-top:3px;margin-right:5px}div.sp-bulk-summary{float:right;margin:8px 5px 3px 20px}.sp-notice .bulk-error-show{cursor:pointer}.sp-notice div.bulk-error-list{background-color:#f1f1f1;padding:0 10px;display:none;max-height:200px;overflow-y:scroll}.sp-notice div.bulk-error-list ul{padding:3px 0 0;margin-top:5px}.sp-notice div.bulk-error-list ul>li:not(:last-child){border-bottom:1px solid white;padding-bottom:4px}input.dial{box-shadow:none}.shortpixel-table .column-filename{max-width:32em;width:40%}.shortpixel-table .column-folder{max-width:20em;width:20%}.shortpixel-table .column-media_type{max-width:8em;width:10%}.shortpixel-table .column-status{max-width:16em;width:15%}.shortpixel-table .column-options{max-width:16em;width:15%}.form-table th{width:220px}.form-table td{position:relative}.form-table table.shortpixel-folders-list tr{background-color:#eee}.form-table table.shortpixel-folders-list td{padding:5px 10px}div.shortpixel-rate-us{display:inline-block;margin-left:10px;vertical-align:top;font-weight:bold}div.shortpixel-rate-us>a{vertical-align:middle;padding:1px 5px 0;text-align:center;display:inline-block}div.shortpixel-rate-us>a>span{display:inline-block;vertical-align:top;margin-top:5px}div.shortpixel-rate-us>a>img{padding-top:7px}div.shortpixel-rate-us>a:active,div.shortpixel-rate-us>a:hover,div.shortpixel-rate-us>a:focus{outline:0;border-style:none}.sp-loading-small{margin-top:2px;float:left;margin-right:5px}div.sp-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0,0.4)}div.shortpixel-modal{background-color:#fefefe;margin:8% auto;padding:20px;border:1px solid #888;width:30%;min-width:300px}div.shortpixel-modal .sp-close-button,div.shortpixel-modal .sp-close-upgrade-button{float:right;margin-top:0;background:transparent;border:0;font-size:22px;line-height:10px;cursor:pointer}.twentytwenty-horizontal .twentytwenty-before-label:before,.twentytwenty-horizontal .twentytwenty-after-label:before{font-family:inherit;font-size:16px}div.sp-modal-title{font-size:22px}div.sp-modal-body{margin-top:20px}.short-pixel-bulk-page p{margin:.6em 0}div.shortpixel-modal .sptw-modal-spinner{background-image:url("../img/spinner2.gif");background-repeat:no-repeat;background-position:center}.short-pixel-bulk-page form.start{display:table;content:" ";width:98%;background-color:white;padding:10px 10px 0;position:relative}.bulk-stats-container{display:inline-block;min-width:450px;width:45%;float:left;padding-right:50px;font-size:1.1em;line-height:1.5em}.bulk-text-container{display:inline-block;min-width:440px;width:45%;float:left;padding-right:50px}.bulk-text-container h3{border-bottom:1px solid #a8a8a8;margin-bottom:.5em;padding-bottom:.5em}.bulk-wide{display:inline-block;width:90%;float:left;margin-top:25px}.bulk-stats-container .bulk-label{width:220px;display:inline-block}.bulk-stats-container .bulk-val{width:50px;display:inline-block;text-align:right}.bulk-stats-container .bulk-total{font-weight:bold;margin-top:10px;margin-bottom:10px}.wp-core-ui .bulk-play{display:inline;width:310px;float:left;margin-bottom:20px}.wp-core-ui .bulk-play.bulk-nothing-optimize{font-weight:bold;color:#0080b2;border:1px solid;border-radius:5px;margin-top:60px;padding:5px 12px}.wp-core-ui .bulk-play a.button{height:60px;margin-top:27px;overflow:hidden}.wp-core-ui .column-wp-shortPixel .sp-column-actions{max-width:140px;float:right;text-align:right}.wp-core-ui .column-wp-shortPixel .sp-column-actions .button.button-smaller{margin-right:0}.wp-core-ui .column-wp-shortPixel .button.button-smaller{font-size:13px;padding:0 5px;margin-bottom:4px;height:20px;line-height:16px;float:right}th.sortable.column-wp-shortPixel a,th.sorted.column-wp-shortPixel a{display:inline-block}.column-wp-shortPixel .sorting-indicator{display:inline-block}.wp-core-ui .bulk-play a.button .bulk-btn-img{display:inline-block;padding-top:6px}.wp-core-ui .bulk-play a.button .bulk-btn-txt{display:inline-block;text-align:right;line-height:1.3em;margin:11px 10px}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.label{font-size:1.6em}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.total{font-size:1.4em}.short-pixel-notice-icon{float:left;margin:10px 10px 10px 0}.bulk-progress{padding:20px 32px 17px;background-color:#fff}.bulk-progress.bulk-stats>div{display:inline-block}.bulk-progress.bulk-stats>div.label{width:320px}.bulk-progress.bulk-stats>div.stat-value{width:80px;text-align:right}.short-pixel-bulk-page .progress{background-color:#ecedee;height:30px;position:relative;width:60%;display:inline-block;margin-right:28px;overflow:visible}.progress .progress-img{position:absolute;top:-10px;z-index:2;margin-left:-35px;line-height:48px;font-size:22px;font-weight:bold}.progress .progress-img span{vertical-align:top;margin-left:-7px}.progress .progress-left{background-color:#1cbecb;bottom:0;left:0;position:absolute;top:0;z-index:1;font-size:22px;font-weight:bold;line-height:28px;text-align:center;color:#fff}.bulk-estimate{font-size:20px;line-height:30px;vertical-align:top;display:inline-block}.wp-core-ui .button-primary.bulk-cancel{float:right;height:30px}.short-pixel-block-title{font-size:22px;font-weight:bold;text-align:center;margin-bottom:30px}.sp-floating-block.bulk-slider-container{display:none}.sp-floating-block.sp-notice.bulk-notices-parent{padding:0;margin:0;float:right;margin-right:500px !important}.bulk-slider-container{margin-top:20px;min-height:300px;overflow:hidden}.bulk-slider-container h2{margin-bottom:15px}.bulk-slider-container span.filename{font-weight:normal}.bulk-slider{display:table;margin:0 auto}.bulk-slider .bulk-slide{margin:0 auto;padding-left:120px;display:inline-block;font-weight:bold}.bulk-slider .img-original,.bulk-slider .img-optimized{display:inline-block;margin-right:20px;text-align:center}.bulk-slider .img-original div,.bulk-slider .img-optimized div{max-height:450px;overflow:hidden}.bulk-slider .img-original img,.bulk-slider .img-optimized img{max-width:300px}.bulk-slider .img-info{display:inline-block;vertical-align:top;font-size:48px;max-width:150px;padding:10px 0 0 20px}.bulk-slide-images{display:inline-block;border:1px solid #1caecb;padding:15px 0 0 20px}p.settings-info{padding-top:0;color:#818181;font-size:13px !important}p.settings-info.shortpixel-settings-error{color:#c32525}.shortpixel-key-valid{font-weight:bold}.shortpixel-key-valid .dashicons-yes:before{font-size:2em;line-height:25px;color:#3485ba;margin-left:-20px}.shortpixel-compression .shortpixel-compression-options{color:#999}.shortpixel-compression strong{line-height:22px}.shortpixel-compression .shortpixel-compression-options{display:inline-block}.shortpixel-compression label{width:158px;margin:0 -2px;background-color:#e2faff;font-weight:bold;display:inline-block}.shortpixel-compression label span{text-align:center;font-size:18px;padding:8px 0;display:block}.shortpixel-compression label input{display:none}.shortpixel-compression input:checked+span{background-color:#0085ba;color:#f7f7f7}.shortpixel-compression .shortpixel-radio-info{min-height:60px}article.sp-tabs{position:relative;display:block;width:100%;margin:2em auto}article.sp-tabs section{position:absolute;display:block;top:1.8em;left:0;width:100%;max-width:100%;box-sizing:border-box;padding:10px 20px;z-index:0}article.sp-tabs section.sel-tab{box-shadow:0 3px 3px rgba(0,0,0,0.1)}article.sp-tabs section .wp-shortpixel-tab-content{visibility:hidden}article.sp-tabs section.sel-tab .wp-shortpixel-tab-content{visibility:visible}article.sp-tabs section:first-child{z-index:1}article.sp-tabs section h2{position:absolute;font-size:1.3em;font-weight:normal;width:180px;height:1.8em;top:-1.8em;left:10px;padding:0;margin:0;color:#999;background-color:#ddd}article.sp-tabs section:nth-child(2) h2{left:192px}article.sp-tabs section:nth-child(3) h2{left:374px}article.sp-tabs section:nth-child(4) h2{left:556px}article.sp-tabs section:nth-child(5) h2{left:738px}article.sp-tabs section h2 a{display:block;width:100%;line-height:1.8em;text-align:center;text-decoration:none;color:#23282d;outline:0 none}article.sp-tabs section h2 a:focus,article.sp-tabs section#tab-resources a:focus{box-shadow:none;outline:0}article.sp-tabs section.sel-tab,article.sp-tabs section.sel-tab h2{color:#333;background-color:#fff;z-index:2}#tab-stats .sp-bulk-summary{position:absolute;right:0;top:0;z-index:100}.deliverWebpSettings,.deliverWebpTypes,.deliverWebpAlteringTypes{display:none}.deliverWebpTypes .sp-notice{color:red}.deliverWebpSettings{margin:16px 0}.deliverWebpSettings input:disabled+label{color:#818181}.deliverWebpTypes,.deliverWebpAlteringTypes{margin:16px 0 16px 16px}#png2jpg:not(:checked) ~ #png2jpgForce,#png2jpg:not(:checked) ~ label[for=png2jpgForce]{display:none}article.sp-tabs section #createWebp:checked ~ .deliverWebpSettings,article.sp-tabs section #deliverWebp:checked ~ .deliverWebpTypes,article.sp-tabs section #deliverWebpAltered:checked ~ .deliverWebpAlteringTypes{display:block}.shortpixel-help-link span.dashicons{text-decoration:none;margin-top:-1px}@media(min-width:1000px){section#tab-resources .col-md-6{display:inline-block;width:45%}}@media(max-width:999px){section#tab-resources .col-sm-12{display:inline-block;width:100%}}section#tab-resources .text-center{text-align:center}section#tab-resources p{font-size:16px}.wrap.short-pixel-bulk-page{margin-right:0}.sp-container{overflow:hidden;display:block;width:100%}.sp-floating-block{overflow:hidden;display:inline-block;float:left;margin-right:1.1% !important}.sp-full-width{width:98.8%;box-sizing:border-box}.sp-double-width{width:65.52%;box-sizing:border-box}.sp-single-width{width:32.23%;box-sizing:border-box}@media(max-width:1759px){.sp-floating-block{margin-right:1.3% !important}.sp-double-width,.sp-full-width{width:98.65%}.sp-single-width{width:48.7%}}@media(max-width:1249px){.sp-floating-block{margin-right:2% !important}.sp-double-width,.sp-full-width,.sp-single-width{width:97%}}.sp-tabs h2:before{content:none}.sp-column-actions-template+.sp-column-info{display:none}#wpadminbar .shortpixel-toolbar-processing .cssload-container{width:100%;height:24px;text-align:center;position:absolute;top:0;left:-1px}#wpadminbar .shortpixel-toolbar-processing.shortpixel-quota-exceeded .cssload-container,#wpadminbar .shortpixel-toolbar-processing.shortpixel-alert .cssload-container{display:none}#wpadminbar .shortpixel-toolbar-processing .cssload-speeding-wheel{width:24px;height:24px;opacity:.7;margin:0 auto;border:4px solid #1cbfcb;border-radius:50%;border-left-color:transparent;animation:cssload-spin 2000ms infinite linear;-o-animation:cssload-spin 2000ms infinite linear;-ms-animation:cssload-spin 2000ms infinite linear;-webkit-animation:cssload-spin 2000ms infinite linear;-moz-animation:cssload-spin 2000ms infinite linear}@keyframes cssload-spin{100%{transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes cssload-spin{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes cssload-spin{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes cssload-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes cssload-spin{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}
|
1 |
+
.reset{font-weight:normal;font-style:normal}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}.resumeLabel{float:right;line-height:30px;margin-right:20px;font-size:16px}.sp-dropbtn.button{padding:1px 24px 20px 5px;font-size:20px;cursor:pointer}.sp-dropdown{position:relative;display:inline-block}.sp-dropdown-content{display:none;right:0;position:absolute;background-color:#f9f9f9;min-width:190px;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2);z-index:1}.sp-dropdown-content a{color:black;padding:12px 16px;text-decoration:none;display:block}.sp-dropdown-content a:hover{background-color:#f1f1f1}.sp-dropdown.sp-show .sp-dropdown-content{display:block}div.fb-like{transform:scale(1.3);-ms-transform:scale(1.3);-webkit-transform:scale(1.3);-o-transform:scale(1.3);-moz-transform:scale(1.3);transform-origin:bottom left;-ms-transform-origin:bottom left;-webkit-transform-origin:bottom left;-moz-transform-origin:bottom left;-webkit-transform-origin:bottom left}.wp-core-ui .button.button-alert,.wp-core-ui .button.button-alert:hover{background:#f79797}.wp-core-ui .button.remove-folder-button{min-width:120px}.sp-notice{background:#fff;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:1px 12px}.sp-notice img{vertical-align:bottom}@media(max-width:1249px){.sp-notice{margin:5px 15px 2px}}.sp-notice-info{border-left-color:#00a0d2}.sp-notice-success{border-left-color:#46b450}.sp-notice-warning{border-left-color:#f1e02a}.sp-conflict-plugins{display:table;border-spacing:10px;border-collapse:separate}.sp-conflict-plugins li{display:table-row}.sp-conflict-plugins li>*{display:table-cell}li.sp-conflict-plugins-list{line-height:28px;list-style:disc;margin-left:80px}li.sp-conflict-plugins-list a.button{margin-left:10px}div.short-pixel-bulk-page input.dial{font-size:16px !important}div.short-pixel-bulk-page h1{margin-bottom:20px}div.bulk-progress div.sp-h2{margin-top:0;margin-bottom:10px;font-size:23px;font-weight:400;padding:9px 15px 4px 0;line-height:29px}div.bulk-progress-partners{margin-top:20px}div.bulk-progress.bulk-progress-partners a div{display:inline-block;vertical-align:top;line-height:50px;margin-left:30px;font-size:1.2em}div.bulk-progress .bulk-progress-indicator,div.sp-quota-exceeded-alert .bulk-progress-indicator{display:inline-block;text-align:center;padding:0 10px;margin-left:10px;float:left;height:90px;overflow:hidden;border:1px solid #1caecb}div.wrap.short-pixel-bulk-page .bulk-notice-container{margin-top:15px;position:absolute;width:500px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg{text-align:center;margin:10px 0 0 32px;overflow:hidden;border:1px solid #1caecb;background-color:#9ddbe0;border-radius:5px;padding:7px 10px 10px;display:none;max-width:600px;margin-right:20px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error{border:1px solid #b5914d;background-color:#ffe996;margin-right:20px;position:relative;z-index:10}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error.bulk-error-fatal{border:1px solid #c32525;background-color:#ff969d}div.wrap.short-pixel-bulk-page .bulk-notice-msg img{float:left;margin-top:3px;margin-right:5px}div.sp-bulk-summary{float:right;margin:8px 5px 3px 20px}.sp-notice .bulk-error-show{cursor:pointer}.sp-notice div.bulk-error-list{background-color:#f1f1f1;padding:0 10px;display:none;max-height:200px;overflow-y:scroll}.sp-notice div.bulk-error-list ul{padding:3px 0 0;margin-top:5px}.sp-notice div.bulk-error-list ul>li:not(:last-child){border-bottom:1px solid white;padding-bottom:4px}input.dial{box-shadow:none}.shortpixel-table .column-filename{max-width:32em;width:40%}.shortpixel-table .column-folder{max-width:20em;width:20%}.shortpixel-table .column-media_type{max-width:8em;width:10%}.shortpixel-table .column-status{max-width:16em;width:15%}.shortpixel-table .column-options{max-width:16em;width:15%}.form-table th{width:220px}.form-table td{position:relative}.form-table table.shortpixel-folders-list tr{background-color:#eee}.form-table table.shortpixel-folders-list td{padding:5px 10px}div.shortpixel-rate-us{display:inline-block;margin-left:10px;vertical-align:top;font-weight:bold}div.shortpixel-rate-us>a{vertical-align:middle;padding:1px 5px 0;text-align:center;display:inline-block}div.shortpixel-rate-us>a>span{display:inline-block;vertical-align:top;margin-top:5px}div.shortpixel-rate-us>a>img{padding-top:7px}div.shortpixel-rate-us>a:active,div.shortpixel-rate-us>a:hover,div.shortpixel-rate-us>a:focus{outline:0;border-style:none}.sp-loading-small{margin-top:2px;float:left;margin-right:5px}.twentytwenty-horizontal .twentytwenty-before-label:before,.twentytwenty-horizontal .twentytwenty-after-label:before{font-family:inherit;font-size:16px}.short-pixel-bulk-page p{margin:.6em 0}.short-pixel-bulk-page form.start{display:table;content:" ";width:98%;background-color:white;padding:10px 10px 0;position:relative}.bulk-stats-container{display:inline-block;min-width:450px;width:45%;float:left;padding-right:50px;font-size:1.1em;line-height:1.5em}.bulk-text-container{display:inline-block;min-width:440px;width:45%;float:left;padding-right:50px}.bulk-text-container h3{border-bottom:1px solid #a8a8a8;margin-bottom:.5em;padding-bottom:.5em}.bulk-wide{display:inline-block;width:90%;float:left;margin-top:25px}.bulk-stats-container .bulk-label{width:220px;display:inline-block}.bulk-stats-container .bulk-val{width:50px;display:inline-block;text-align:right}.bulk-stats-container .bulk-total{font-weight:bold;margin-top:10px;margin-bottom:10px}.wp-core-ui .bulk-play{display:inline;width:310px;float:left;margin-bottom:20px}.wp-core-ui .bulk-play.bulk-nothing-optimize{font-weight:bold;color:#0080b2;border:1px solid;border-radius:5px;margin-top:60px;padding:5px 12px}.wp-core-ui .bulk-play a.button{height:60px;margin-top:27px;overflow:hidden}.wp-core-ui .column-wp-shortPixel .sp-column-actions{max-width:140px;float:right;text-align:right}.wp-core-ui .column-wp-shortPixel .sp-column-actions .button.button-smaller{margin-right:0}.wp-core-ui .column-wp-shortPixel .button.button-smaller{font-size:13px;padding:0 5px;margin-bottom:4px;height:20px;line-height:16px;float:right}th.sortable.column-wp-shortPixel a,th.sorted.column-wp-shortPixel a{display:inline-block}.column-wp-shortPixel .sorting-indicator{display:inline-block}.wp-core-ui .bulk-play a.button .bulk-btn-img{display:inline-block;padding-top:6px}.wp-core-ui .bulk-play a.button .bulk-btn-txt{display:inline-block;text-align:right;line-height:1.3em;margin:11px 10px}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.label{font-size:1.6em}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.total{font-size:1.4em}.bulk-progress{padding:20px 32px 17px;background-color:#fff}.bulk-progress.bulk-stats>div{display:inline-block}.bulk-progress.bulk-stats>div.label{width:320px}.bulk-progress.bulk-stats>div.stat-value{width:80px;text-align:right}.short-pixel-bulk-page .progress{background-color:#ecedee;height:30px;position:relative;width:60%;display:inline-block;margin-right:28px;overflow:visible}.progress .progress-img{position:absolute;top:-10px;z-index:2;margin-left:-35px;line-height:48px;font-size:22px;font-weight:bold}.progress .progress-img span{vertical-align:top;margin-left:-7px}.progress .progress-left{background-color:#1cbecb;bottom:0;left:0;position:absolute;top:0;z-index:1;font-size:22px;font-weight:bold;line-height:28px;text-align:center;color:#fff}.bulk-estimate{font-size:20px;line-height:30px;vertical-align:top;display:inline-block}.wp-core-ui .button-primary.bulk-cancel{float:right;height:30px}.short-pixel-block-title{font-size:22px;font-weight:bold;text-align:center;margin-bottom:30px}.sp-floating-block.bulk-slider-container{display:none}.sp-floating-block.sp-notice.bulk-notices-parent{padding:0;margin:0;float:right;margin-right:500px !important}.bulk-slider-container{margin-top:20px;min-height:300px;overflow:hidden}.bulk-slider-container h2{margin-bottom:15px}.bulk-slider-container span.filename{font-weight:normal}.bulk-slider{display:table;margin:0 auto}.bulk-slider .bulk-slide{margin:0 auto;padding-left:120px;display:inline-block;font-weight:bold}.bulk-slider .img-original,.bulk-slider .img-optimized{display:inline-block;margin-right:20px;text-align:center}.bulk-slider .img-original div,.bulk-slider .img-optimized div{max-height:450px;overflow:hidden}.bulk-slider .img-original img,.bulk-slider .img-optimized img{max-width:300px}.bulk-slider .img-info{display:inline-block;vertical-align:top;font-size:48px;max-width:150px;padding:10px 0 0 20px}.bulk-slide-images{display:inline-block;border:1px solid #1caecb;padding:15px 0 0 20px}p.settings-info{padding-top:0;color:#818181;font-size:13px !important}p.settings-info.shortpixel-settings-error{color:#c32525}.shortpixel-key-valid{font-weight:bold}.shortpixel-key-valid .dashicons-yes:before{font-size:2em;line-height:25px;color:#3485ba;margin-left:-20px}.shortpixel-compression .shortpixel-compression-options{color:#999}.shortpixel-compression strong{line-height:22px}.shortpixel-compression .shortpixel-compression-options{display:inline-block}.shortpixel-compression label{width:158px;margin:0 -2px;background-color:#e2faff;font-weight:bold;display:inline-block}.shortpixel-compression label span{text-align:center;font-size:18px;padding:8px 0;display:block}.shortpixel-compression label input{display:none}.shortpixel-compression input:checked+span{background-color:#0085ba;color:#f7f7f7}.shortpixel-compression .shortpixel-radio-info{min-height:60px}article.sp-tabs{position:relative;display:block;width:100%;margin:2em auto}article.sp-tabs section{position:absolute;display:block;top:1.8em;left:0;width:100%;max-width:100%;box-sizing:border-box;padding:10px 20px;z-index:0}article.sp-tabs section.sel-tab{box-shadow:0 3px 3px rgba(0,0,0,0.1)}article.sp-tabs section .wp-shortpixel-tab-content{visibility:hidden}article.sp-tabs section.sel-tab .wp-shortpixel-tab-content{visibility:visible}article.sp-tabs section:first-child{z-index:1}article.sp-tabs section h2{position:absolute;font-size:1.3em;font-weight:normal;width:180px;height:1.8em;top:-1.8em;left:10px;padding:0;margin:0;color:#999;background-color:#ddd}article.sp-tabs section:nth-child(2) h2{left:192px}article.sp-tabs section:nth-child(3) h2{left:374px}article.sp-tabs section:nth-child(4) h2{left:556px}article.sp-tabs section:nth-child(5) h2{left:738px}article.sp-tabs section h2 a{display:block;width:100%;line-height:1.8em;text-align:center;text-decoration:none;color:#23282d;outline:0 none}article.sp-tabs section h2 a:focus,article.sp-tabs section#tab-resources a:focus{box-shadow:none;outline:0}article.sp-tabs section.sel-tab,article.sp-tabs section.sel-tab h2{color:#333;background-color:#fff;z-index:2}#tab-stats .sp-bulk-summary{position:absolute;right:0;top:0;z-index:100}.deliverWebpSettings,.deliverWebpTypes,.deliverWebpAlteringTypes{display:none}.deliverWebpTypes .sp-notice{color:red}.deliverWebpSettings{margin:16px 0}.deliverWebpSettings input:disabled+label{color:#818181}.deliverWebpTypes,.deliverWebpAlteringTypes{margin:16px 0 16px 16px}#png2jpg:not(:checked) ~ #png2jpgForce,#png2jpg:not(:checked) ~ label[for=png2jpgForce]{display:none}article.sp-tabs section #createWebp:checked ~ .deliverWebpSettings,article.sp-tabs section #deliverWebp:checked ~ .deliverWebpTypes,article.sp-tabs section #deliverWebpAltered:checked ~ .deliverWebpAlteringTypes{display:block}.shortpixel-help-link span.dashicons{text-decoration:none;margin-top:-1px}@media(min-width:1000px){section#tab-resources .col-md-6{display:inline-block;width:45%}}@media(max-width:999px){section#tab-resources .col-sm-12{display:inline-block;width:100%}}section#tab-resources .text-center{text-align:center}section#tab-resources p{font-size:16px}.wrap.short-pixel-bulk-page{margin-right:0}.sp-container{overflow:hidden;display:block;width:100%}.sp-floating-block{overflow:hidden;display:inline-block;float:left;margin-right:1.1% !important}.sp-full-width{width:98.8%;box-sizing:border-box}.sp-double-width{width:65.52%;box-sizing:border-box}.sp-single-width{width:32.23%;box-sizing:border-box}@media(max-width:1759px){.sp-floating-block{margin-right:1.3% !important}.sp-double-width,.sp-full-width{width:98.65%}.sp-single-width{width:48.7%}}@media(max-width:1249px){.sp-floating-block{margin-right:2% !important}.sp-double-width,.sp-full-width,.sp-single-width{width:97%}}.sp-tabs h2:before{content:none}.sp-column-actions-template+.sp-column-info{display:none}#wpadminbar .shortpixel-toolbar-processing .cssload-container{width:100%;height:24px;text-align:center;position:absolute;top:0;left:-1px}#wpadminbar .shortpixel-toolbar-processing.shortpixel-quota-exceeded .cssload-container,#wpadminbar .shortpixel-toolbar-processing.shortpixel-alert .cssload-container{display:none}#wpadminbar .shortpixel-toolbar-processing .cssload-speeding-wheel{width:24px;height:24px;opacity:.7;margin:0 auto;border:4px solid #1cbfcb;border-radius:50%;border-left-color:transparent;animation:cssload-spin 2000ms infinite linear;-o-animation:cssload-spin 2000ms infinite linear;-ms-animation:cssload-spin 2000ms infinite linear;-webkit-animation:cssload-spin 2000ms infinite linear;-moz-animation:cssload-spin 2000ms infinite linear}@keyframes cssload-spin{100%{transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes cssload-spin{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes cssload-spin{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes cssload-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes cssload-spin{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}
|
@@ -0,0 +1,35 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
.short-pixel-bulk-page.bulk-restore-all ol li {
|
2 |
+
font-weight: 700; }
|
3 |
+
.short-pixel-bulk-page.bulk-restore-all section.select_folders {
|
4 |
+
margin: 20px 0; }
|
5 |
+
.short-pixel-bulk-page.bulk-restore-all section.select_folders .input {
|
6 |
+
margin: 10px 0 10px 15px;
|
7 |
+
font-size: 16px;
|
8 |
+
display: block;
|
9 |
+
clear: both; }
|
10 |
+
.short-pixel-bulk-page.bulk-restore-all section.select_folders .filecount {
|
11 |
+
font-size: 12px; }
|
12 |
+
.short-pixel-bulk-page.bulk-restore-all section.random_check .random_answer {
|
13 |
+
font-size: 16px;
|
14 |
+
font-weight: 700;
|
15 |
+
padding: 8px;
|
16 |
+
border: 1px solid #ccc;
|
17 |
+
display: inline-block; }
|
18 |
+
.short-pixel-bulk-page.bulk-restore-all section.random_check .inputs {
|
19 |
+
margin: 15px 0; }
|
20 |
+
.short-pixel-bulk-page.bulk-restore-all section.random_check .inputs span {
|
21 |
+
margin-right: 8px; }
|
22 |
+
.short-pixel-bulk-page.bulk-restore-all .button {
|
23 |
+
margin: 10px 0;
|
24 |
+
margin-right: 8px; }
|
25 |
+
|
26 |
+
/* Specific styles for advanced settings tab */
|
27 |
+
#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder {
|
28 |
+
margin: 10px 0; }
|
29 |
+
#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder .add-folder-text {
|
30 |
+
margin-left: 5px; }
|
31 |
+
#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder input[type="text"] {
|
32 |
+
width: 50em;
|
33 |
+
max-width: 70%; }
|
34 |
+
#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder input[name="saveAdv"] {
|
35 |
+
margin-left: 8px; }
|
@@ -0,0 +1 @@
|
|
Â
|
1 |
+
.short-pixel-bulk-page.bulk-restore-all ol li{font-weight:700}.short-pixel-bulk-page.bulk-restore-all section.select_folders{margin:20px 0}.short-pixel-bulk-page.bulk-restore-all section.select_folders .input{margin:10px 0 10px 15px;font-size:16px;display:block;clear:both}.short-pixel-bulk-page.bulk-restore-all section.select_folders .filecount{font-size:12px}.short-pixel-bulk-page.bulk-restore-all section.random_check .random_answer{font-size:16px;font-weight:700;padding:8px;border:1px solid #ccc;display:inline-block}.short-pixel-bulk-page.bulk-restore-all section.random_check .inputs{margin:15px 0}.short-pixel-bulk-page.bulk-restore-all section.random_check .inputs span{margin-right:8px}.short-pixel-bulk-page.bulk-restore-all .button{margin:10px 0;margin-right:8px}#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder{margin:10px 0}#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder .add-folder-text{margin-left:5px}#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder input[type="text"]{width:50em;max-width:70%}#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder input[name="saveAdv"]{margin-left:8px}
|
@@ -2,28 +2,40 @@ div.sp-folder-picker {
|
|
2 |
Â
margin: 20px 0; /* 15% from the top and centered */
|
3 |
Â
border: 1px solid #888;
|
4 |
Â
max-height: 400px;
|
Â
|
|
5 |
Â
overflow: auto;}
|
6 |
Â
|
7 |
Â
UL.jqueryFileTree LI.directory.selected {
|
8 |
Â
background-color: #209fd2;
|
9 |
Â
}
|
10 |
Â
|
Â
|
|
11 |
Â
UL.jqueryFileTree {
|
12 |
Â
font-family: Verdana, sans-serif;
|
13 |
Â
font-size: 11px;
|
14 |
Â
line-height: 18px;
|
15 |
-
padding:
|
16 |
Â
margin: 0;
|
17 |
Â
display: none;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
18 |
Â
}
|
Â
|
|
19 |
Â
UL.jqueryFileTree LI {
|
20 |
Â
list-style: none;
|
21 |
Â
padding: 0;
|
22 |
-
padding-left: 20px;
|
23 |
Â
margin: 0;
|
24 |
Â
white-space: nowrap;
|
25 |
Â
}
|
26 |
-
UL.jqueryFileTree LI
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
27 |
Â
background: url(../img/file-tree/directory.png) left top no-repeat;
|
28 |
Â
}
|
29 |
Â
UL.jqueryFileTree LI.directory-locked {
|
2 |
Â
margin: 20px 0; /* 15% from the top and centered */
|
3 |
Â
border: 1px solid #888;
|
4 |
Â
max-height: 400px;
|
5 |
+
min-height: 100px;
|
6 |
Â
overflow: auto;}
|
7 |
Â
|
8 |
Â
UL.jqueryFileTree LI.directory.selected {
|
9 |
Â
background-color: #209fd2;
|
10 |
Â
}
|
11 |
Â
|
12 |
+
|
13 |
Â
UL.jqueryFileTree {
|
14 |
Â
font-family: Verdana, sans-serif;
|
15 |
Â
font-size: 11px;
|
16 |
Â
line-height: 18px;
|
17 |
+
padding: 3px;
|
18 |
Â
margin: 0;
|
19 |
Â
display: none;
|
20 |
+
margin-left: 20px;
|
21 |
+
}
|
22 |
+
.sp-folder-picker > UL.jqueryFileTree
|
23 |
+
{
|
24 |
+
margin: 0;
|
25 |
Â
}
|
26 |
+
|
27 |
Â
UL.jqueryFileTree LI {
|
28 |
Â
list-style: none;
|
29 |
Â
padding: 0;
|
30 |
+
/* padding-left: 20px; */
|
31 |
Â
margin: 0;
|
32 |
Â
white-space: nowrap;
|
33 |
Â
}
|
34 |
+
UL.jqueryFileTree LI a
|
35 |
+
{
|
36 |
+
padding-left: 20px;
|
37 |
+
}
|
38 |
+
UL.jqueryFileTree LI.directory a {
|
39 |
Â
background: url(../img/file-tree/directory.png) left top no-repeat;
|
40 |
Â
}
|
41 |
Â
UL.jqueryFileTree LI.directory-locked {
|
@@ -1,2 +1 @@
|
|
1 |
-
|
2 |
-
div.sp-folder-picker{margin:20px 0;border:1px solid #888;max-height:400px;overflow:auto}UL.jqueryFileTree LI.directory.selected{background-color:#209fd2}UL.jqueryFileTree{font-family:Verdana,sans-serif;font-size:11px;line-height:18px;padding:0;margin:0;display:none}UL.jqueryFileTree LI{list-style:none;padding:0;padding-left:20px;margin:0;white-space:nowrap}UL.jqueryFileTree LI.directory{background:url(../img/file-tree/directory.png) left top no-repeat}UL.jqueryFileTree LI.directory-locked{background:url(../img/file-tree/directory-lock.png) left top no-repeat}UL.jqueryFileTree LI.expanded{background:url(../img/file-tree/folder_open.png) left top no-repeat}UL.jqueryFileTree LI.file{background:url(../img/file-tree/file.png) left top no-repeat}UL.jqueryFileTree LI.file-locked{background:url(../img/file-tree/file-lock.png) left top no-repeat !important}UL.jqueryFileTree LI.wait{background:url(../img/file-tree/spinner.gif) left top no-repeat}UL.jqueryFileTree LI.selected>a{font-weight:bold}UL.jqueryFileTree LI.ext_3gp{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_afp{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_afpa{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_asp{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_aspx{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_avi{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_bat{background:url(../img/file-tree/application.png) left top no-repeat}UL.jqueryFileTree LI.ext_bmp{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_c{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_cfm{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_cgi{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_com{background:url(../img/file-tree/application.png) left top no-repeat}UL.jqueryFileTree LI.ext_cpp{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_css{background:url(../img/file-tree/css.png) left top no-repeat}UL.jqueryFileTree LI.ext_doc{background:url(../img/file-tree/doc.png) left top no-repeat}UL.jqueryFileTree LI.ext_exe{background:url(../img/file-tree/application.png) left top no-repeat}UL.jqueryFileTree LI.ext_gif{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_fla{background:url(../img/file-tree/flash.png) left top no-repeat}UL.jqueryFileTree LI.ext_h{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_htm{background:url(../img/file-tree/html.png) left top no-repeat}UL.jqueryFileTree LI.ext_html{background:url(../img/file-tree/html.png) left top no-repeat}UL.jqueryFileTree LI.ext_jar{background:url(../img/file-tree/java.png) left top no-repeat}UL.jqueryFileTree LI.ext_jpg{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_jpeg{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_js{background:url(../img/file-tree/script.png) left top no-repeat}UL.jqueryFileTree LI.ext_lasso{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_log{background:url(../img/file-tree/txt.png) left top no-repeat}UL.jqueryFileTree LI.ext_m4p{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_mov{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_mp3{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_mp4{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_mpg{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_mpeg{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_ogg{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_ogv{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_pcx{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_pdf{background:url(../img/file-tree/pdf.png) left top no-repeat}UL.jqueryFileTree LI.ext_php{background:url(../img/file-tree/php.png) left top no-repeat}UL.jqueryFileTree LI.ext_png{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_ppt{background:url(../img/file-tree/ppt.png) left top no-repeat}UL.jqueryFileTree LI.ext_psd{background:url(../img/file-tree/psd.png) left top no-repeat}UL.jqueryFileTree LI.ext_pl{background:url(../img/file-tree/script.png) left top no-repeat}UL.jqueryFileTree LI.ext_py{background:url(../img/file-tree/script.png) left top no-repeat}UL.jqueryFileTree LI.ext_rb{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_rbx{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_rhtml{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_rpm{background:url(../img/file-tree/linux.png) left top no-repeat}UL.jqueryFileTree LI.ext_ruby{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_sql{background:url(../img/file-tree/db.png) left top no-repeat}UL.jqueryFileTree LI.ext_swf{background:url(../img/file-tree/flash.png) left top no-repeat}UL.jqueryFileTree LI.ext_tif{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_tiff{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_txt{background:url(../img/file-tree/txt.png) left top no-repeat}UL.jqueryFileTree LI.ext_vb{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_wav{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_webm{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_wmv{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_xls{background:url(../img/file-tree/xls.png) left top no-repeat}UL.jqueryFileTree LI.ext_xml{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_zip{background:url(../img/file-tree/zip.png) left top no-repeat}UL.jqueryFileTree A{color:#333;text-decoration:none;display:inline-block;padding:0 2px;cursor:pointer}UL.jqueryFileTree A:hover{background:#BDF}
|
1 |
+
div.sp-folder-picker{margin:20px 0;border:1px solid #888;max-height:400px;min-height:100px;overflow:auto}UL.jqueryFileTree LI.directory.selected{background-color:#209fd2}UL.jqueryFileTree{font-family:Verdana,sans-serif;font-size:11px;line-height:18px;padding:3px;margin:0;display:none;margin-left:20px}.sp-folder-picker>UL.jqueryFileTree{margin:0}UL.jqueryFileTree LI{list-style:none;padding:0;margin:0;white-space:nowrap}UL.jqueryFileTree LI a{padding-left:20px}UL.jqueryFileTree LI.directory a{background:url(../img/file-tree/directory.png) left top no-repeat}UL.jqueryFileTree LI.directory-locked{background:url(../img/file-tree/directory-lock.png) left top no-repeat}UL.jqueryFileTree LI.expanded{background:url(../img/file-tree/folder_open.png) left top no-repeat}UL.jqueryFileTree LI.file{background:url(../img/file-tree/file.png) left top no-repeat}UL.jqueryFileTree LI.file-locked{background:url(../img/file-tree/file-lock.png) left top no-repeat !important}UL.jqueryFileTree LI.wait{background:url(../img/file-tree/spinner.gif) left top no-repeat}UL.jqueryFileTree LI.selected>a{font-weight:bold}UL.jqueryFileTree LI.ext_3gp{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_afp{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_afpa{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_asp{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_aspx{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_avi{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_bat{background:url(../img/file-tree/application.png) left top no-repeat}UL.jqueryFileTree LI.ext_bmp{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_c{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_cfm{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_cgi{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_com{background:url(../img/file-tree/application.png) left top no-repeat}UL.jqueryFileTree LI.ext_cpp{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_css{background:url(../img/file-tree/css.png) left top no-repeat}UL.jqueryFileTree LI.ext_doc{background:url(../img/file-tree/doc.png) left top no-repeat}UL.jqueryFileTree LI.ext_exe{background:url(../img/file-tree/application.png) left top no-repeat}UL.jqueryFileTree LI.ext_gif{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_fla{background:url(../img/file-tree/flash.png) left top no-repeat}UL.jqueryFileTree LI.ext_h{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_htm{background:url(../img/file-tree/html.png) left top no-repeat}UL.jqueryFileTree LI.ext_html{background:url(../img/file-tree/html.png) left top no-repeat}UL.jqueryFileTree LI.ext_jar{background:url(../img/file-tree/java.png) left top no-repeat}UL.jqueryFileTree LI.ext_jpg{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_jpeg{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_js{background:url(../img/file-tree/script.png) left top no-repeat}UL.jqueryFileTree LI.ext_lasso{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_log{background:url(../img/file-tree/txt.png) left top no-repeat}UL.jqueryFileTree LI.ext_m4p{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_mov{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_mp3{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_mp4{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_mpg{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_mpeg{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_ogg{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_ogv{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_pcx{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_pdf{background:url(../img/file-tree/pdf.png) left top no-repeat}UL.jqueryFileTree LI.ext_php{background:url(../img/file-tree/php.png) left top no-repeat}UL.jqueryFileTree LI.ext_png{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_ppt{background:url(../img/file-tree/ppt.png) left top no-repeat}UL.jqueryFileTree LI.ext_psd{background:url(../img/file-tree/psd.png) left top no-repeat}UL.jqueryFileTree LI.ext_pl{background:url(../img/file-tree/script.png) left top no-repeat}UL.jqueryFileTree LI.ext_py{background:url(../img/file-tree/script.png) left top no-repeat}UL.jqueryFileTree LI.ext_rb{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_rbx{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_rhtml{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_rpm{background:url(../img/file-tree/linux.png) left top no-repeat}UL.jqueryFileTree LI.ext_ruby{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_sql{background:url(../img/file-tree/db.png) left top no-repeat}UL.jqueryFileTree LI.ext_swf{background:url(../img/file-tree/flash.png) left top no-repeat}UL.jqueryFileTree LI.ext_tif{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_tiff{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_txt{background:url(../img/file-tree/txt.png) left top no-repeat}UL.jqueryFileTree LI.ext_vb{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_wav{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_webm{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_wmv{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_xls{background:url(../img/file-tree/xls.png) left top no-repeat}UL.jqueryFileTree LI.ext_xml{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_zip{background:url(../img/file-tree/zip.png) left top no-repeat}UL.jqueryFileTree A{color:#333;text-decoration:none;display:inline-block;padding:0 2px;cursor:pointer}UL.jqueryFileTree A:hover{background:#BDF}
|
Â
|
File without changes
|
Binary file
|
@@ -4,7 +4,6 @@
|
|
4 |
Â
|
5 |
Â
jQuery(document).ready(function(){ShortPixel.init();});
|
6 |
Â
|
7 |
-
|
8 |
Â
var ShortPixel = function() {
|
9 |
Â
|
10 |
Â
function init() {
|
@@ -50,11 +49,11 @@ var ShortPixel = function() {
|
|
50 |
Â
ShortPixel[opt] = options[opt];
|
51 |
Â
}
|
52 |
Â
}
|
53 |
-
|
54 |
Â
function isEmailValid(email) {
|
55 |
Â
return /^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(email);
|
56 |
Â
}
|
57 |
-
|
58 |
Â
function updateSignupEmail() {
|
59 |
Â
var email = jQuery('#pluginemail').val();
|
60 |
Â
if(ShortPixel.isEmailValid(email)) {
|
@@ -62,12 +61,12 @@ var ShortPixel = function() {
|
|
62 |
Â
}
|
63 |
Â
jQuery('#request_key').attr('href', jQuery('#request_key').attr('href').split('?')[0] + '?pluginemail=' + email);
|
64 |
Â
}
|
65 |
-
|
66 |
Â
function validateKey(){
|
67 |
Â
jQuery('#valid').val('validate');
|
68 |
Â
jQuery('#wp_shortpixel_options').submit();
|
69 |
Â
}
|
70 |
-
|
71 |
Â
jQuery("#key").keypress(function(e) {
|
72 |
Â
if(e.which == 13) {
|
73 |
Â
jQuery('#valid').val('validate');
|
@@ -81,7 +80,7 @@ var ShortPixel = function() {
|
|
81 |
Â
jQuery("#width,#height").attr("disabled", "disabled");
|
82 |
Â
}
|
83 |
Â
}
|
84 |
-
|
85 |
Â
function setupGeneralTab(rad, minWidth, minHeight) {
|
86 |
Â
for(var i = 0, prev = null; i < rad.length; i++) {
|
87 |
Â
rad[i].onclick = function() {
|
@@ -137,7 +136,7 @@ var ShortPixel = function() {
|
|
137 |
Â
jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display", "none");
|
138 |
Â
jQuery(".wp-shortpixel-options button#validate").css("display", "inline-block");
|
139 |
Â
}
|
140 |
-
|
141 |
Â
function setupAdvancedTab() {
|
142 |
Â
jQuery("input.remove-folder-button").click(function(){
|
143 |
Â
var path = jQuery(this).data("value");
|
@@ -194,7 +193,7 @@ var ShortPixel = function() {
|
|
194 |
Â
}
|
195 |
Â
});
|
196 |
Â
}
|
197 |
-
|
198 |
Â
function switchSettingsTab(target){
|
199 |
Â
var tab = target.replace("tab-",""),
|
200 |
Â
beacon = "",
|
@@ -228,7 +227,7 @@ var ShortPixel = function() {
|
|
228 |
Â
HS.beacon.suggest(beacon);
|
229 |
Â
}
|
230 |
Â
}
|
231 |
-
|
232 |
Â
function adjustSettingsTabsHeight(){
|
233 |
Â
var sectionHeight = jQuery('section#tab-settings .wp-shortpixel-options').height() + 90;
|
234 |
Â
sectionHeight = Math.max(sectionHeight, jQuery('section#tab-adv-settings .wp-shortpixel-options').height() + 20);
|
@@ -247,14 +246,14 @@ var ShortPixel = function() {
|
|
247 |
Â
}
|
248 |
Â
});
|
249 |
Â
}
|
250 |
-
|
251 |
Â
function checkQuota() {
|
252 |
Â
var data = { action : 'shortpixel_check_quota'};
|
253 |
Â
jQuery.get(ShortPixel.AJAX_URL, data, function() {
|
254 |
Â
console.log("quota refreshed");
|
255 |
Â
});
|
256 |
Â
}
|
257 |
-
|
258 |
Â
function onBulkThumbsCheck(check) {
|
259 |
Â
if(check.checked) {
|
260 |
Â
jQuery("#with-thumbs").css('display', 'inherit');
|
@@ -264,7 +263,7 @@ var ShortPixel = function() {
|
|
264 |
Â
jQuery("#with-thumbs").css('display', 'none');
|
265 |
Â
}
|
266 |
Â
}
|
267 |
-
|
268 |
Â
function successMsg(id, percent, type, thumbsCount, retinasCount) {
|
269 |
Â
return (percent > 0 ? "<div class='sp-column-info'>" + _spTr.reducedBy + " <strong><span class='percent'>" + percent + "%</span></strong> " : "")
|
270 |
Â
+ (percent > 0 && percent < 5 ? "<br>" : '')
|
@@ -274,7 +273,7 @@ var ShortPixel = function() {
|
|
274 |
Â
+ (0 + retinasCount > 0 ? "<br>" + _spTr.plusXretinasOpt.format(retinasCount) :"")
|
275 |
Â
+ "</div>";
|
276 |
Â
}
|
277 |
-
|
278 |
Â
function percentDial(query, size) {
|
279 |
Â
jQuery(query).knob({
|
280 |
Â
'readOnly': true,
|
@@ -285,22 +284,22 @@ var ShortPixel = function() {
|
|
285 |
Â
return value + '%';
|
286 |
Â
}
|
287 |
Â
});
|
288 |
-
}
|
289 |
-
|
290 |
Â
function successActions(id, type, thumbsCount, thumbsTotal, backupEnabled, fileName) {
|
291 |
Â
if(backupEnabled == 1) {
|
292 |
-
|
293 |
Â
var successActions = jQuery('.sp-column-actions-template').clone();
|
294 |
Â
|
295 |
-
if(!successActions.length) return false;
|
296 |
-
|
297 |
Â
var otherTypes;
|
298 |
Â
if(type.length == 0) {
|
299 |
Â
otherTypes = ['lossy', 'lossless'];
|
300 |
Â
} else {
|
301 |
Â
otherTypes = ['lossy','glossy','lossless'].filter(function(el) {return !(el == type);});
|
302 |
-
}
|
303 |
-
|
304 |
Â
successActions.html(successActions.html().replace(/__SP_ID__/g, id));
|
305 |
Â
if(fileName.substr(fileName.lastIndexOf('.') + 1).toLowerCase() == 'pdf') {
|
306 |
Â
jQuery('.sp-action-compare', successActions).remove();
|
@@ -314,10 +313,10 @@ var ShortPixel = function() {
|
|
314 |
Â
successActions.html(successActions.html().replace(/__SP_FIRST_TYPE__/g, otherTypes[0]));
|
315 |
Â
successActions.html(successActions.html().replace(/__SP_SECOND_TYPE__/g, otherTypes[1]));
|
316 |
Â
return successActions.html();
|
317 |
-
}
|
318 |
Â
return "";
|
319 |
Â
}
|
320 |
-
|
321 |
Â
function otherMediaUpdateActions(id, actions) {
|
322 |
Â
id = id.substring(2);
|
323 |
Â
if(jQuery(".shortpixel-other-media").length) {
|
@@ -330,7 +329,7 @@ var ShortPixel = function() {
|
|
330 |
Â
}
|
331 |
Â
}
|
332 |
Â
}
|
333 |
-
|
334 |
Â
function retry(msg) {
|
335 |
Â
ShortPixel.retries++;
|
336 |
Â
if(isNaN(ShortPixel.retries)) ShortPixel.retries = 1;
|
@@ -339,17 +338,17 @@ var ShortPixel = function() {
|
|
339 |
Â
setTimeout(checkBulkProgress, 5000);
|
340 |
Â
} else {
|
341 |
Â
ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: " + msg + ")", "");
|
342 |
-
console.log("Invalid response from server 6 times. Giving up.");
|
343 |
Â
}
|
344 |
Â
}
|
345 |
-
|
346 |
Â
function browseContent(browseData) {
|
347 |
Â
browseData.action = 'shortpixel_browse_content';
|
348 |
Â
var browseResponse = "";
|
349 |
Â
jQuery.ajax({
|
350 |
Â
type: "POST",
|
351 |
-
url: ShortPixel.AJAX_URL,
|
352 |
-
data: browseData,
|
353 |
Â
success: function(response) {
|
354 |
Â
browseResponse = response;
|
355 |
Â
},
|
@@ -357,14 +356,14 @@ var ShortPixel = function() {
|
|
357 |
Â
});
|
358 |
Â
return browseResponse;
|
359 |
Â
}
|
360 |
-
|
361 |
Â
function getBackupSize() {
|
362 |
Â
var browseData = { 'action': 'shortpixel_get_backup_size'};
|
363 |
Â
var browseResponse = "";
|
364 |
Â
jQuery.ajax({
|
365 |
Â
type: "POST",
|
366 |
-
url: ShortPixel.AJAX_URL,
|
367 |
-
data: browseData,
|
368 |
Â
success: function(response) {
|
369 |
Â
browseResponse = response;
|
370 |
Â
},
|
@@ -393,8 +392,8 @@ var ShortPixel = function() {
|
|
393 |
Â
jQuery.ajax({
|
394 |
Â
type: "POST",
|
395 |
Â
async: false,
|
396 |
-
url: ShortPixel.AJAX_URL,
|
397 |
-
data: browseData,
|
398 |
Â
success: function(response) {
|
399 |
Â
data = JSON.parse(response);
|
400 |
Â
if(data["Status"] == 'success') {
|
@@ -418,7 +417,8 @@ var ShortPixel = function() {
|
|
418 |
Â
jQuery('#request_key').removeClass('disabled');
|
419 |
Â
jQuery('#pluginemail_spinner').removeClass('is-active');
|
420 |
Â
}
|
421 |
-
|
Â
|
|
422 |
Â
function proposeUpgrade() {
|
423 |
Â
//first open the popup window with the spinner
|
424 |
Â
jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass('sptw-modal-spinner');
|
@@ -429,15 +429,15 @@ var ShortPixel = function() {
|
|
429 |
Â
var browseData = { 'action': 'shortpixel_propose_upgrade'};
|
430 |
Â
jQuery.ajax({
|
431 |
Â
type: "POST",
|
432 |
-
url: ShortPixel.AJAX_URL,
|
433 |
-
data: browseData,
|
434 |
Â
success: function(response) {
|
435 |
Â
jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass('sptw-modal-spinner');
|
436 |
Â
jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(response);
|
437 |
Â
}
|
438 |
Â
});
|
439 |
Â
}
|
440 |
-
|
441 |
Â
function closeProposeUpgrade() {
|
442 |
Â
jQuery("#shortPixelProposeUpgradeShade").css("display", "none");
|
443 |
Â
jQuery("#shortPixelProposeUpgrade").addClass('shortpixel-hide');
|
@@ -445,7 +445,7 @@ var ShortPixel = function() {
|
|
445 |
Â
ShortPixel.recheckQuota();
|
446 |
Â
}
|
447 |
Â
}
|
448 |
-
|
449 |
Â
function includeUnlisted() {
|
450 |
Â
jQuery("#short-pixel-notice-unlisted").hide();
|
451 |
Â
jQuery("#optimizeUnlisted").prop('checked', true);
|
@@ -460,34 +460,57 @@ var ShortPixel = function() {
|
|
460 |
Â
});
|
461 |
Â
}
|
462 |
Â
|
463 |
-
|
464 |
Â
function initFolderSelector() {
|
465 |
Â
jQuery(".select-folder-button").click(function(){
|
466 |
-
jQuery(".sp-folder-picker-shade").css("display", "block");
|
467 |
-
jQuery(".
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
468 |
Â
script: ShortPixel.browseContent,
|
469 |
Â
//folderEvent: 'dblclick',
|
470 |
Â
multiFolder: false
|
471 |
Â
//onlyFolders: true
|
472 |
Â
});
|
473 |
Â
});
|
474 |
-
jQuery(".shortpixel-modal input.select-folder-cancel").click(function(){
|
475 |
-
jQuery(".sp-folder-picker-shade").css("display", "none");
|
Â
|
|
476 |
Â
});
|
477 |
-
jQuery(".shortpixel-modal input.select-folder").click(function(){
|
478 |
-
var subPath = jQuery("UL.jqueryFileTree LI.directory.selected A").attr("rel").trim();
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
479 |
Â
if(subPath) {
|
480 |
Â
var fullPath = jQuery("#customFolderBase").val() + subPath;
|
481 |
Â
if(fullPath.slice(-1) == '/') fullPath = fullPath.slice(0, -1);
|
482 |
Â
jQuery("#addCustomFolder").val(fullPath);
|
483 |
Â
jQuery("#addCustomFolderView").val(fullPath);
|
484 |
-
jQuery(".sp-folder-picker-shade").
|
Â
|
|
Â
|
|
485 |
Â
} else {
|
486 |
Â
alert("Please select a folder from the list.");
|
487 |
Â
}
|
488 |
Â
});
|
489 |
Â
}
|
490 |
-
|
491 |
Â
function bulkShowLengthyMsg(id, fileName, customLink){
|
492 |
Â
var notice = jQuery(".bulk-notice-msg.bulk-lengthy");
|
493 |
Â
if(notice.length == 0) return;
|
@@ -498,24 +521,24 @@ var ShortPixel = function() {
|
|
498 |
Â
} else {
|
499 |
Â
link.attr("href", link.data("href").replace("__ID__", id));
|
500 |
Â
}
|
501 |
-
|
502 |
Â
notice.css("display", "block");
|
503 |
Â
}
|
504 |
-
|
505 |
Â
function bulkHideLengthyMsg(){
|
506 |
Â
jQuery(".bulk-notice-msg.bulk-lengthy").css("display", "none");
|
507 |
Â
}
|
508 |
-
|
509 |
Â
function bulkShowMaintenanceMsg(type){
|
510 |
Â
var notice = jQuery(".bulk-notice-msg.bulk-" + type);
|
511 |
Â
if(notice.length == 0) return;
|
512 |
Â
notice.css("display", "block");
|
513 |
Â
}
|
514 |
-
|
515 |
Â
function bulkHideMaintenanceMsg(type){
|
516 |
Â
jQuery(".bulk-notice-msg.bulk-" + type).css("display", "none");
|
517 |
Â
}
|
518 |
-
|
519 |
Â
function bulkShowError(id, msg, fileName, customLink) {
|
520 |
Â
var noticeTpl = jQuery("#bulk-error-template");
|
521 |
Â
if(noticeTpl.length == 0) return;
|
@@ -537,9 +560,9 @@ var ShortPixel = function() {
|
|
537 |
Â
}
|
538 |
Â
link.text(fileName);
|
539 |
Â
noticeTpl.after(notice);
|
540 |
-
notice.css("display", "block");
|
541 |
Â
}
|
542 |
-
|
543 |
Â
function confirmBulkAction(type, e) {
|
544 |
Â
if(!confirm(_spTr['confirmBulk' + type])) {
|
545 |
Â
e.stopPropagation();
|
@@ -549,19 +572,39 @@ var ShortPixel = function() {
|
|
549 |
Â
return true;
|
550 |
Â
}
|
551 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
552 |
Â
function removeBulkMsg(me) {
|
553 |
Â
jQuery(me).parent().parent().remove();
|
554 |
Â
}
|
555 |
-
|
556 |
Â
function isCustomImageId(id) {
|
557 |
Â
return id.substring(0,2) == "C-";
|
558 |
Â
}
|
559 |
-
|
560 |
Â
function recheckQuota() {
|
561 |
Â
var parts = window.location.href.split('#');
|
562 |
Â
window.location.href=parts[0]+(parts[0].indexOf('?')>0?'&':'?')+'checkquota=1' + (typeof parts[1] === 'undefined' ? '' : '#' + parts[1]);
|
563 |
Â
}
|
564 |
-
|
565 |
Â
function openImageMenu(e) {
|
566 |
Â
e.preventDefault();
|
567 |
Â
//install (lazily) a window click event to close the menus
|
@@ -577,15 +620,14 @@ var ShortPixel = function() {
|
|
577 |
Â
jQuery('.sp-dropdown.sp-show').removeClass('sp-show');
|
578 |
Â
if(!shown) e.target.parentElement.classList.add("sp-show");
|
579 |
Â
}
|
580 |
-
|
581 |
Â
function loadComparer(id) {
|
582 |
Â
this.comparerData.origUrl = false;
|
583 |
-
|
584 |
-
if(this.comparerData.cssLoaded === false) {
|
585 |
Â
jQuery('<link>')
|
586 |
Â
.appendTo('head')
|
587 |
Â
.attr({
|
588 |
-
type: 'text/css',
|
589 |
Â
rel: 'stylesheet',
|
590 |
Â
href: this.WP_PLUGIN_URL + '/res/css/twentytwenty.min.css'
|
591 |
Â
});
|
@@ -599,13 +641,13 @@ var ShortPixel = function() {
|
|
599 |
Â
}
|
600 |
Â
});
|
601 |
Â
this.comparerData.jsLoaded = 1;
|
602 |
-
jQuery(".sp-close-button").click(ShortPixel.closeComparerPopup);
|
603 |
Â
}
|
604 |
Â
if(this.comparerData.origUrl === false) {
|
605 |
Â
jQuery.ajax({
|
606 |
Â
type: "POST",
|
607 |
-
url: ShortPixel.AJAX_URL,
|
608 |
-
data: { action : 'shortpixel_get_comparer_data', id : id },
|
609 |
Â
success: function(response) {
|
610 |
Â
data = JSON.parse(response);
|
611 |
Â
jQuery.extend(ShortPixel.comparerData, data);
|
@@ -624,23 +666,36 @@ var ShortPixel = function() {
|
|
624 |
Â
//depending on the sizes choose the right modal
|
625 |
Â
var sideBySide = (height < 150 || width < 350);
|
626 |
Â
var modal = jQuery(sideBySide ? '#spUploadCompareSideBySide' : '#spUploadCompare');
|
Â
|
|
Â
|
|
627 |
Â
if(!sideBySide) {
|
628 |
Â
jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>');
|
629 |
Â
}
|
630 |
Â
//calculate the modal size
|
631 |
Â
width = Math.max(350, Math.min(800, (width < 350 ? (width + 25) * 2 : (height < 150 ? width + 25 : width))));
|
632 |
Â
height = Math.max(150, (sideBySide ? (origWidth > 350 ? 2 * (height + 45) : height + 45) : height * width / origWidth));
|
Â
|
|
Â
|
|
Â
|
|
633 |
Â
//set modal sizes and display
|
634 |
Â
jQuery(".sp-modal-body", modal).css("width", width);
|
635 |
Â
jQuery(".shortpixel-slider", modal).css("width", width);
|
636 |
Â
modal.css("width", width);
|
Â
|
|
637 |
Â
jQuery(".sp-modal-body", modal).css("height", height);
|
638 |
-
modal.
|
639 |
-
modal.parent().css('display', 'block');
|
Â
|
|
Â
|
|
640 |
Â
if(!sideBySide) {
|
641 |
Â
jQuery("#spCompareSlider").twentytwenty({slider_move: "mousemove"});
|
642 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
643 |
Â
jQuery(document).on('keyup.sp_modal_active', ShortPixel.closeComparerPopup);
|
Â
|
|
Â
|
|
644 |
Â
//change images srcs
|
645 |
Â
var imgOpt = jQuery(".spUploadCompareOptimized", modal);
|
646 |
Â
jQuery(".spUploadCompareOriginal", modal).attr("src", imgOriginal);
|
@@ -653,12 +708,15 @@ var ShortPixel = function() {
|
|
653 |
Â
});
|
654 |
Â
imgOpt.attr("src", imgOptimized);
|
655 |
Â
}
|
656 |
-
|
657 |
Â
function closeComparerPopup(e) {
|
658 |
-
|
659 |
-
jQuery("#spUploadCompareSideBySide").
|
660 |
-
jQuery("#spUploadCompare").
|
Â
|
|
661 |
Â
jQuery(document).unbind('keyup.sp_modal_active');
|
Â
|
|
Â
|
|
662 |
Â
}
|
663 |
Â
|
664 |
Â
function convertPunycode(url) {
|
@@ -705,6 +763,7 @@ var ShortPixel = function() {
|
|
705 |
Â
bulkHideMaintenanceMsg : bulkHideMaintenanceMsg,
|
706 |
Â
bulkShowError : bulkShowError,
|
707 |
Â
confirmBulkAction : confirmBulkAction,
|
Â
|
|
708 |
Â
removeBulkMsg : removeBulkMsg,
|
709 |
Â
isCustomImageId : isCustomImageId,
|
710 |
Â
recheckQuota : recheckQuota,
|
@@ -731,7 +790,7 @@ function showToolBarAlert($status, $message, id) {
|
|
731 |
Â
var robo = jQuery("li.shortpixel-toolbar-processing");
|
732 |
Â
switch($status) {
|
733 |
Â
case ShortPixel.STATUS_QUOTA_EXCEEDED:
|
734 |
-
if( window.location.href.search("wp-short-pixel-bulk") > 0
|
735 |
Â
&& jQuery(".sp-quota-exceeded-alert").length == 0) { //if we're in bulk and the alert is not displayed reload to see all options
|
736 |
Â
location.reload();
|
737 |
Â
return;
|
@@ -743,7 +802,7 @@ function showToolBarAlert($status, $message, id) {
|
|
743 |
Â
//jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click to top-up");
|
744 |
Â
jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click for details.");
|
745 |
Â
break;
|
746 |
-
case ShortPixel.STATUS_SKIP:
|
747 |
Â
case ShortPixel.STATUS_FAIL:
|
748 |
Â
robo.addClass("shortpixel-alert shortpixel-processing");
|
749 |
Â
jQuery("a div", robo).attr("title", $message);
|
@@ -785,11 +844,11 @@ function checkQuotaExceededAlert() {
|
|
785 |
Â
}
|
786 |
Â
}
|
787 |
Â
/**
|
788 |
-
* JavaScript image processing - this method gets executed on every footer load and afterwards
|
789 |
Â
* calls itself until receives an Empty queue message
|
790 |
Â
*/
|
791 |
Â
function checkBulkProgress() {
|
792 |
-
//the replace stands for malformed urls on some sites, like wp-admin//upload.php which are accepted by the browser.
|
793 |
Â
//using a replacer function to avoid replacing the first occurence (https:// ...)
|
794 |
Â
var replacer = function(match) {
|
795 |
Â
if(!first) {
|
@@ -801,16 +860,16 @@ function checkBulkProgress() {
|
|
801 |
Â
|
802 |
Â
var first = false; //arm replacer
|
803 |
Â
var url = window.location.href.toLowerCase().replace(/\/\//g , replacer);
|
804 |
-
|
805 |
Â
first = false; //rearm replacer
|
806 |
Â
var adminUrl = ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g , replacer);
|
807 |
-
|
808 |
Â
//handle possible Punycode domain names.
|
809 |
Â
if(url.search(adminUrl) < 0) {
|
810 |
Â
url = ShortPixel.convertPunycode(url);
|
811 |
Â
adminUrl = ShortPixel.convertPunycode(adminUrl);
|
812 |
Â
}
|
813 |
-
|
814 |
Â
if( url.search(adminUrl + "upload.php") < 0
|
815 |
Â
&& url.search(adminUrl + "edit.php") < 0
|
816 |
Â
&& url.search(adminUrl + "edit-tags.php") < 0
|
@@ -822,20 +881,20 @@ function checkBulkProgress() {
|
|
822 |
Â
hideToolBarAlert();
|
823 |
Â
return;
|
824 |
Â
}
|
825 |
-
|
826 |
Â
//if i'm the bulk processor and i'm not the bulk page and a bulk page comes around, leave the bulk processor role
|
827 |
-
if(ShortPixel.bulkProcessor == true && window.location.href.search("wp-short-pixel-bulk") < 0
|
828 |
Â
&& typeof localStorage.bulkPage !== 'undefined' && localStorage.bulkPage > 0) {
|
829 |
Â
ShortPixel.bulkProcessor = false;
|
830 |
Â
}
|
831 |
-
|
832 |
Â
//if i'm the bulk page, steal the bulk processor
|
833 |
Â
if( window.location.href.search("wp-short-pixel-bulk") >= 0 ) {
|
834 |
Â
ShortPixel.bulkProcessor = true;
|
835 |
Â
localStorage.bulkTime = Math.floor(Date.now() / 1000);
|
836 |
Â
localStorage.bulkPage = 1;
|
837 |
Â
}
|
838 |
-
|
839 |
Â
//if I'm not the bulk processor, check every 20 sec. if the bulk processor is running, otherwise take the role
|
840 |
Â
if(ShortPixel.bulkProcessor == true || typeof localStorage.bulkTime == 'undefined' || Math.floor(Date.now() / 1000) - localStorage.bulkTime > 90) {
|
841 |
Â
ShortPixel.bulkProcessor = true;
|
@@ -854,8 +913,8 @@ function checkBulkProcessingCallApi(){
|
|
854 |
Â
jQuery.ajax({
|
855 |
Â
type: "POST",
|
856 |
Â
url: ShortPixel.AJAX_URL, //formerly ajaxurl , but changed it because it's not available in the front-end and now we have an option to run in the front-end
|
857 |
-
data: data,
|
858 |
-
success: function(response)
|
859 |
Â
{
|
860 |
Â
if(response.length > 0) {
|
861 |
Â
var data = null;
|
@@ -866,7 +925,7 @@ function checkBulkProcessingCallApi(){
|
|
866 |
Â
return;
|
867 |
Â
}
|
868 |
Â
ShortPixel.retries = 0;
|
869 |
-
|
870 |
Â
var id = data["ImageID"];
|
871 |
Â
|
872 |
Â
var isBulkPage = (jQuery("div.short-pixel-bulk-page").length > 0);
|
@@ -878,7 +937,7 @@ function checkBulkProcessingCallApi(){
|
|
878 |
Â
showToolBarAlert(ShortPixel.STATUS_NO_KEY);
|
879 |
Â
break;
|
880 |
Â
case ShortPixel.STATUS_QUOTA_EXCEEDED:
|
881 |
-
setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"
|
882 |
Â
+ ShortPixel.API_KEY + "\" target=\"_blank\">" + _spTr.extendQuota + "</a>"
|
883 |
Â
+ "<a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>" + _spTr.check__Quota + "</a>");
|
884 |
Â
showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);
|
@@ -888,7 +947,7 @@ function checkBulkProcessingCallApi(){
|
|
888 |
Â
ShortPixel.otherMediaUpdateActions(id, ['quota','view']);
|
889 |
Â
break;
|
890 |
Â
case ShortPixel.STATUS_FAIL:
|
891 |
-
setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('" + id + "', false)\">"
|
892 |
Â
+ _spTr.retry + "</a>");
|
893 |
Â
showToolBarAlert(ShortPixel.STATUS_FAIL, data["Message"], id);
|
894 |
Â
if(isBulkPage) {
|
@@ -925,11 +984,29 @@ function checkBulkProcessingCallApi(){
|
|
925 |
Â
|
926 |
Â
showToolBarAlert(ShortPixel.STATUS_SUCCESS, "");
|
927 |
Â
//for now, until 4.1
|
928 |
-
var successActions = ShortPixel.isCustomImageId(id)
|
929 |
-
? ""
|
930 |
Â
: ShortPixel.successActions(id, data["Type"], data['ThumbsCount'], data['ThumbsTotal'], data["BackupEnabled"], data['Filename']);
|
931 |
-
|
Â
|
|
932 |
Â
setCellMessage(id, ShortPixel.successMsg(id, percent, data["Type"], data['ThumbsCount'], data['RetinasCount']), successActions);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
933 |
Â
var actions = jQuery(['restore', 'view', 'redolossy', 'redoglossy', 'redolossless']).not(['redo'+data["Type"]]).get();
|
934 |
Â
ShortPixel.otherMediaUpdateActions(id, actions);
|
935 |
Â
var animator = new PercentageAnimator("#sp-msg-" + id + " span.percent", percent);
|
@@ -945,7 +1022,8 @@ function checkBulkProcessingCallApi(){
|
|
945 |
Â
ShortPixel.percentDial("#sp-avg-optimization .dial", 60);
|
946 |
Â
}
|
947 |
Â
}
|
948 |
-
}
|
Â
|
|
949 |
Â
console.log('Server response: ' + response);
|
950 |
Â
if(isBulkPage && typeof data["BulkPercent"] !== 'undefined') {
|
951 |
Â
progressUpdate(data["BulkPercent"], data["BulkMsg"]);
|
@@ -1010,11 +1088,11 @@ function setCellMessage(id, message, actions){
|
|
1010 |
Â
msg.html("<div class='sp-column-actions'>" + actions + "</div>"
|
1011 |
Â
+ "<div class='sp-column-info'>" + message + "</div>");
|
1012 |
Â
msg.css("color", "");
|
1013 |
-
}
|
1014 |
Â
msg = jQuery("#sp-cust-msg-" + id);
|
1015 |
Â
if(msg.length > 0) {
|
1016 |
Â
msg.html("<div class='sp-column-info'>" + message + "</div>");
|
1017 |
-
}
|
1018 |
Â
}
|
1019 |
Â
|
1020 |
Â
function manualOptimization(id, cleanup) {
|
@@ -1031,6 +1109,7 @@ function manualOptimization(id, cleanup) {
|
|
1031 |
Â
success: function(response) {
|
1032 |
Â
var resp = JSON.parse(response);
|
1033 |
Â
if(resp["Status"] == ShortPixel.STATUS_SUCCESS) {
|
Â
|
|
1034 |
Â
setTimeout(checkBulkProgress, 2000);
|
1035 |
Â
} else {
|
1036 |
Â
setCellMessage(id, typeof resp["Message"] !== "undefined" ? resp["Message"] : _spTr.thisContentNotProcessable, "");
|
@@ -1122,7 +1201,7 @@ function PercentageAnimator(outputSelector, targetPercentage) {
|
|
1122 |
Â
this.curPercentage = 0;
|
1123 |
Â
this.targetPercentage = targetPercentage;
|
1124 |
Â
this.outputSelector = outputSelector;
|
1125 |
-
|
1126 |
Â
this.animate = function(percentage) {
|
1127 |
Â
this.targetPercentage = percentage;
|
1128 |
Â
setTimeout(PercentageTimer.bind(null, this), this.animationSpeed);
|
@@ -1131,9 +1210,9 @@ function PercentageAnimator(outputSelector, targetPercentage) {
|
|
1131 |
Â
|
1132 |
Â
function PercentageTimer(animator) {
|
1133 |
Â
if (animator.curPercentage - animator.targetPercentage < -animator.increment) {
|
1134 |
-
animator.curPercentage += animator.increment;
|
1135 |
Â
} else if (animator.curPercentage - animator.targetPercentage > animator.increment) {
|
1136 |
-
animator.curPercentage -= animator.increment;
|
1137 |
Â
} else {
|
1138 |
Â
animator.curPercentage = animator.targetPercentage;
|
1139 |
Â
}
|
@@ -1141,7 +1220,7 @@ function PercentageTimer(animator) {
|
|
1141 |
Â
jQuery(animator.outputSelector).text(animator.curPercentage + "%");
|
1142 |
Â
|
1143 |
Â
if (animator.curPercentage != animator.targetPercentage) {
|
1144 |
-
setTimeout(PercentageTimer.bind(null,animator), animator.animationSpeed)
|
1145 |
Â
}
|
1146 |
Â
}
|
1147 |
Â
|
@@ -1155,7 +1234,7 @@ function progressUpdate(percent, message) {
|
|
1155 |
Â
jQuery(".progress-left", progress).html(percent + "%");
|
1156 |
Â
} else {
|
1157 |
Â
jQuery(".progress-img span", progress).html(percent + "%");
|
1158 |
-
jQuery(".progress-left", progress).html("");
|
1159 |
Â
}
|
1160 |
Â
jQuery(".bulk-estimate").html(message);
|
1161 |
Â
}
|
@@ -1167,7 +1246,7 @@ function sliderUpdate(id, thumb, bkThumb, percent, filename){
|
|
1167 |
Â
var oldSlide = jQuery(".bulk-slider div.bulk-slide:first-child");
|
1168 |
Â
if(oldSlide.length === 0) {
|
1169 |
Â
return;
|
1170 |
-
}
|
1171 |
Â
if(oldSlide.attr("id") != "empty-slide") {
|
1172 |
Â
oldSlide.hide();
|
1173 |
Â
}
|
@@ -1190,10 +1269,10 @@ function sliderUpdate(id, thumb, bkThumb, percent, filename){
|
|
1190 |
Â
jQuery(".img-original", newSlide).css("display", "none");
|
1191 |
Â
}
|
1192 |
Â
jQuery(".bulk-opt-percent", newSlide).html('<input type="text" class="dial" value="' + percent + '"/>');
|
1193 |
-
|
1194 |
Â
jQuery(".bulk-slider").append(newSlide);
|
1195 |
Â
ShortPixel.percentDial("#" + newSlide.attr("id") + " .dial", 100);
|
1196 |
-
|
1197 |
Â
jQuery(".bulk-slider-container span.filename").html(" " + filename);
|
1198 |
Â
if(oldSlide.attr("id") == "empty-slide") {
|
1199 |
Â
oldSlide.remove();
|
@@ -1213,11 +1292,11 @@ function hideSlider() {
|
|
1213 |
Â
function showStats() {
|
1214 |
Â
var statsDiv = jQuery(".bulk-stats");
|
1215 |
Â
if(statsDiv.length > 0) {
|
1216 |
-
|
1217 |
Â
}
|
1218 |
Â
}
|
1219 |
Â
|
1220 |
-
if (!(typeof String.prototype.format == 'function')) {
|
1221 |
Â
String.prototype.format = function() {
|
1222 |
Â
var s = this,
|
1223 |
Â
i = arguments.length;
|
4 |
Â
|
5 |
Â
jQuery(document).ready(function(){ShortPixel.init();});
|
6 |
Â
|
Â
|
|
7 |
Â
var ShortPixel = function() {
|
8 |
Â
|
9 |
Â
function init() {
|
49 |
Â
ShortPixel[opt] = options[opt];
|
50 |
Â
}
|
51 |
Â
}
|
52 |
+
|
53 |
Â
function isEmailValid(email) {
|
54 |
Â
return /^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(email);
|
55 |
Â
}
|
56 |
+
|
57 |
Â
function updateSignupEmail() {
|
58 |
Â
var email = jQuery('#pluginemail').val();
|
59 |
Â
if(ShortPixel.isEmailValid(email)) {
|
61 |
Â
}
|
62 |
Â
jQuery('#request_key').attr('href', jQuery('#request_key').attr('href').split('?')[0] + '?pluginemail=' + email);
|
63 |
Â
}
|
64 |
+
|
65 |
Â
function validateKey(){
|
66 |
Â
jQuery('#valid').val('validate');
|
67 |
Â
jQuery('#wp_shortpixel_options').submit();
|
68 |
Â
}
|
69 |
+
|
70 |
Â
jQuery("#key").keypress(function(e) {
|
71 |
Â
if(e.which == 13) {
|
72 |
Â
jQuery('#valid').val('validate');
|
80 |
Â
jQuery("#width,#height").attr("disabled", "disabled");
|
81 |
Â
}
|
82 |
Â
}
|
83 |
+
|
84 |
Â
function setupGeneralTab(rad, minWidth, minHeight) {
|
85 |
Â
for(var i = 0, prev = null; i < rad.length; i++) {
|
86 |
Â
rad[i].onclick = function() {
|
136 |
Â
jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display", "none");
|
137 |
Â
jQuery(".wp-shortpixel-options button#validate").css("display", "inline-block");
|
138 |
Â
}
|
139 |
+
|
140 |
Â
function setupAdvancedTab() {
|
141 |
Â
jQuery("input.remove-folder-button").click(function(){
|
142 |
Â
var path = jQuery(this).data("value");
|
193 |
Â
}
|
194 |
Â
});
|
195 |
Â
}
|
196 |
+
|
197 |
Â
function switchSettingsTab(target){
|
198 |
Â
var tab = target.replace("tab-",""),
|
199 |
Â
beacon = "",
|
227 |
Â
HS.beacon.suggest(beacon);
|
228 |
Â
}
|
229 |
Â
}
|
230 |
+
|
231 |
Â
function adjustSettingsTabsHeight(){
|
232 |
Â
var sectionHeight = jQuery('section#tab-settings .wp-shortpixel-options').height() + 90;
|
233 |
Â
sectionHeight = Math.max(sectionHeight, jQuery('section#tab-adv-settings .wp-shortpixel-options').height() + 20);
|
246 |
Â
}
|
247 |
Â
});
|
248 |
Â
}
|
249 |
+
|
250 |
Â
function checkQuota() {
|
251 |
Â
var data = { action : 'shortpixel_check_quota'};
|
252 |
Â
jQuery.get(ShortPixel.AJAX_URL, data, function() {
|
253 |
Â
console.log("quota refreshed");
|
254 |
Â
});
|
255 |
Â
}
|
256 |
+
|
257 |
Â
function onBulkThumbsCheck(check) {
|
258 |
Â
if(check.checked) {
|
259 |
Â
jQuery("#with-thumbs").css('display', 'inherit');
|
263 |
Â
jQuery("#with-thumbs").css('display', 'none');
|
264 |
Â
}
|
265 |
Â
}
|
266 |
+
|
267 |
Â
function successMsg(id, percent, type, thumbsCount, retinasCount) {
|
268 |
Â
return (percent > 0 ? "<div class='sp-column-info'>" + _spTr.reducedBy + " <strong><span class='percent'>" + percent + "%</span></strong> " : "")
|
269 |
Â
+ (percent > 0 && percent < 5 ? "<br>" : '')
|
273 |
Â
+ (0 + retinasCount > 0 ? "<br>" + _spTr.plusXretinasOpt.format(retinasCount) :"")
|
274 |
Â
+ "</div>";
|
275 |
Â
}
|
276 |
+
|
277 |
Â
function percentDial(query, size) {
|
278 |
Â
jQuery(query).knob({
|
279 |
Â
'readOnly': true,
|
284 |
Â
return value + '%';
|
285 |
Â
}
|
286 |
Â
});
|
287 |
+
}
|
288 |
+
|
289 |
Â
function successActions(id, type, thumbsCount, thumbsTotal, backupEnabled, fileName) {
|
290 |
Â
if(backupEnabled == 1) {
|
291 |
+
|
292 |
Â
var successActions = jQuery('.sp-column-actions-template').clone();
|
293 |
Â
|
294 |
+
if(!successActions.length) return false;
|
295 |
+
|
296 |
Â
var otherTypes;
|
297 |
Â
if(type.length == 0) {
|
298 |
Â
otherTypes = ['lossy', 'lossless'];
|
299 |
Â
} else {
|
300 |
Â
otherTypes = ['lossy','glossy','lossless'].filter(function(el) {return !(el == type);});
|
301 |
+
}
|
302 |
+
|
303 |
Â
successActions.html(successActions.html().replace(/__SP_ID__/g, id));
|
304 |
Â
if(fileName.substr(fileName.lastIndexOf('.') + 1).toLowerCase() == 'pdf') {
|
305 |
Â
jQuery('.sp-action-compare', successActions).remove();
|
313 |
Â
successActions.html(successActions.html().replace(/__SP_FIRST_TYPE__/g, otherTypes[0]));
|
314 |
Â
successActions.html(successActions.html().replace(/__SP_SECOND_TYPE__/g, otherTypes[1]));
|
315 |
Â
return successActions.html();
|
316 |
+
}
|
317 |
Â
return "";
|
318 |
Â
}
|
319 |
+
|
320 |
Â
function otherMediaUpdateActions(id, actions) {
|
321 |
Â
id = id.substring(2);
|
322 |
Â
if(jQuery(".shortpixel-other-media").length) {
|
329 |
Â
}
|
330 |
Â
}
|
331 |
Â
}
|
332 |
+
|
333 |
Â
function retry(msg) {
|
334 |
Â
ShortPixel.retries++;
|
335 |
Â
if(isNaN(ShortPixel.retries)) ShortPixel.retries = 1;
|
338 |
Â
setTimeout(checkBulkProgress, 5000);
|
339 |
Â
} else {
|
340 |
Â
ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: " + msg + ")", "");
|
341 |
+
console.log("Invalid response from server 6 times. Giving up.");
|
342 |
Â
}
|
343 |
Â
}
|
344 |
+
|
345 |
Â
function browseContent(browseData) {
|
346 |
Â
browseData.action = 'shortpixel_browse_content';
|
347 |
Â
var browseResponse = "";
|
348 |
Â
jQuery.ajax({
|
349 |
Â
type: "POST",
|
350 |
+
url: ShortPixel.AJAX_URL,
|
351 |
+
data: browseData,
|
352 |
Â
success: function(response) {
|
353 |
Â
browseResponse = response;
|
354 |
Â
},
|
356 |
Â
});
|
357 |
Â
return browseResponse;
|
358 |
Â
}
|
359 |
+
|
360 |
Â
function getBackupSize() {
|
361 |
Â
var browseData = { 'action': 'shortpixel_get_backup_size'};
|
362 |
Â
var browseResponse = "";
|
363 |
Â
jQuery.ajax({
|
364 |
Â
type: "POST",
|
365 |
+
url: ShortPixel.AJAX_URL,
|
366 |
+
data: browseData,
|
367 |
Â
success: function(response) {
|
368 |
Â
browseResponse = response;
|
369 |
Â
},
|
392 |
Â
jQuery.ajax({
|
393 |
Â
type: "POST",
|
394 |
Â
async: false,
|
395 |
+
url: ShortPixel.AJAX_URL,
|
396 |
+
data: browseData,
|
397 |
Â
success: function(response) {
|
398 |
Â
data = JSON.parse(response);
|
399 |
Â
if(data["Status"] == 'success') {
|
417 |
Â
jQuery('#request_key').removeClass('disabled');
|
418 |
Â
jQuery('#pluginemail_spinner').removeClass('is-active');
|
419 |
Â
}
|
420 |
+
|
421 |
+
// [TODO] Check where this function is called and if modal is working here.
|
422 |
Â
function proposeUpgrade() {
|
423 |
Â
//first open the popup window with the spinner
|
424 |
Â
jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass('sptw-modal-spinner');
|
429 |
Â
var browseData = { 'action': 'shortpixel_propose_upgrade'};
|
430 |
Â
jQuery.ajax({
|
431 |
Â
type: "POST",
|
432 |
+
url: ShortPixel.AJAX_URL,
|
433 |
+
data: browseData,
|
434 |
Â
success: function(response) {
|
435 |
Â
jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass('sptw-modal-spinner');
|
436 |
Â
jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(response);
|
437 |
Â
}
|
438 |
Â
});
|
439 |
Â
}
|
440 |
+
|
441 |
Â
function closeProposeUpgrade() {
|
442 |
Â
jQuery("#shortPixelProposeUpgradeShade").css("display", "none");
|
443 |
Â
jQuery("#shortPixelProposeUpgrade").addClass('shortpixel-hide');
|
445 |
Â
ShortPixel.recheckQuota();
|
446 |
Â
}
|
447 |
Â
}
|
448 |
+
|
449 |
Â
function includeUnlisted() {
|
450 |
Â
jQuery("#short-pixel-notice-unlisted").hide();
|
451 |
Â
jQuery("#optimizeUnlisted").prop('checked', true);
|
460 |
Â
});
|
461 |
Â
}
|
462 |
Â
|
463 |
+
|
464 |
Â
function initFolderSelector() {
|
465 |
Â
jQuery(".select-folder-button").click(function(){
|
466 |
+
jQuery(".sp-folder-picker-shade").fadeIn(100); //.css("display", "block");
|
467 |
+
jQuery(".shortpixel-modal.modal-folder-picker").show();
|
468 |
+
|
469 |
+
var picker = jQuery(".sp-folder-picker");
|
470 |
+
picker.parent().css('margin-left', -picker.width() / 2);
|
471 |
+
picker.fileTree({
|
472 |
Â
script: ShortPixel.browseContent,
|
473 |
Â
//folderEvent: 'dblclick',
|
474 |
Â
multiFolder: false
|
475 |
Â
//onlyFolders: true
|
476 |
Â
});
|
477 |
Â
});
|
478 |
+
jQuery(".shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade").click(function(){
|
479 |
+
jQuery(".sp-folder-picker-shade").fadeOut(100); //.css("display", "none");
|
480 |
+
jQuery(".shortpixel-modal.modal-folder-picker").hide();
|
481 |
Â
});
|
482 |
+
jQuery(".shortpixel-modal input.select-folder").click(function(e){
|
483 |
+
//var subPath = jQuery("UL.jqueryFileTree LI.directory.selected A").attr("rel").trim();
|
484 |
+
|
485 |
+
// check if selected item is a directory. If so, we are good.
|
486 |
+
var selected = jQuery('UL.jqueryFileTree LI.directory.selected');
|
487 |
+
|
488 |
+
// if not a file might be selected, check the nearest directory.
|
489 |
+
if (jQuery(selected).length == 0 )
|
490 |
+
var selected = jQuery('UL.jqueryFileTree LI.selected').parents('.directory');
|
491 |
+
|
492 |
+
// fail-saif check if there is really a rel.
|
493 |
+
var subPath = jQuery(selected).children('a').attr('rel');
|
494 |
+
|
495 |
+
if (typeof subPath === 'undefined') // nothing is selected
|
496 |
+
return;
|
497 |
+
|
498 |
+
subPath = subPath.trim();
|
499 |
+
|
500 |
Â
if(subPath) {
|
501 |
Â
var fullPath = jQuery("#customFolderBase").val() + subPath;
|
502 |
Â
if(fullPath.slice(-1) == '/') fullPath = fullPath.slice(0, -1);
|
503 |
Â
jQuery("#addCustomFolder").val(fullPath);
|
504 |
Â
jQuery("#addCustomFolderView").val(fullPath);
|
505 |
+
jQuery(".sp-folder-picker-shade").fadeOut(100);
|
506 |
+
jQuery(".shortpixel-modal.modal-folder-picker").css("display", "none");
|
507 |
+
jQuery('input[name="saveAdv"]').removeClass('hidden');
|
508 |
Â
} else {
|
509 |
Â
alert("Please select a folder from the list.");
|
510 |
Â
}
|
511 |
Â
});
|
512 |
Â
}
|
513 |
+
|
514 |
Â
function bulkShowLengthyMsg(id, fileName, customLink){
|
515 |
Â
var notice = jQuery(".bulk-notice-msg.bulk-lengthy");
|
516 |
Â
if(notice.length == 0) return;
|
521 |
Â
} else {
|
522 |
Â
link.attr("href", link.data("href").replace("__ID__", id));
|
523 |
Â
}
|
524 |
+
|
525 |
Â
notice.css("display", "block");
|
526 |
Â
}
|
527 |
+
|
528 |
Â
function bulkHideLengthyMsg(){
|
529 |
Â
jQuery(".bulk-notice-msg.bulk-lengthy").css("display", "none");
|
530 |
Â
}
|
531 |
+
|
532 |
Â
function bulkShowMaintenanceMsg(type){
|
533 |
Â
var notice = jQuery(".bulk-notice-msg.bulk-" + type);
|
534 |
Â
if(notice.length == 0) return;
|
535 |
Â
notice.css("display", "block");
|
536 |
Â
}
|
537 |
+
|
538 |
Â
function bulkHideMaintenanceMsg(type){
|
539 |
Â
jQuery(".bulk-notice-msg.bulk-" + type).css("display", "none");
|
540 |
Â
}
|
541 |
+
|
542 |
Â
function bulkShowError(id, msg, fileName, customLink) {
|
543 |
Â
var noticeTpl = jQuery("#bulk-error-template");
|
544 |
Â
if(noticeTpl.length == 0) return;
|
560 |
Â
}
|
561 |
Â
link.text(fileName);
|
562 |
Â
noticeTpl.after(notice);
|
563 |
+
notice.css("display", "block");
|
564 |
Â
}
|
565 |
+
|
566 |
Â
function confirmBulkAction(type, e) {
|
567 |
Â
if(!confirm(_spTr['confirmBulk' + type])) {
|
568 |
Â
e.stopPropagation();
|
572 |
Â
return true;
|
573 |
Â
}
|
574 |
Â
|
575 |
+
// used in bulk restore all interface
|
576 |
+
function checkRandomAnswer(e)
|
577 |
+
{
|
578 |
+
var value = jQuery(e.target).val();
|
579 |
+
var answer = jQuery('input[name="random_answer"]').val();
|
580 |
+
var target = jQuery('input[name="random_answer"]').data('target');
|
581 |
+
|
582 |
+
if (value == answer)
|
583 |
+
{
|
584 |
+
jQuery(target).removeClass('disabled').prop('disabled', false);
|
585 |
+
jQuery(target).removeAttr('aria-disabled');
|
586 |
+
|
587 |
+
}
|
588 |
+
else
|
589 |
+
{
|
590 |
+
jQuery(target).addClass('disabled').prop('disabled', true);
|
591 |
+
}
|
592 |
+
|
593 |
+
}
|
594 |
+
|
595 |
Â
function removeBulkMsg(me) {
|
596 |
Â
jQuery(me).parent().parent().remove();
|
597 |
Â
}
|
598 |
+
|
599 |
Â
function isCustomImageId(id) {
|
600 |
Â
return id.substring(0,2) == "C-";
|
601 |
Â
}
|
602 |
+
|
603 |
Â
function recheckQuota() {
|
604 |
Â
var parts = window.location.href.split('#');
|
605 |
Â
window.location.href=parts[0]+(parts[0].indexOf('?')>0?'&':'?')+'checkquota=1' + (typeof parts[1] === 'undefined' ? '' : '#' + parts[1]);
|
606 |
Â
}
|
607 |
+
|
608 |
Â
function openImageMenu(e) {
|
609 |
Â
e.preventDefault();
|
610 |
Â
//install (lazily) a window click event to close the menus
|
620 |
Â
jQuery('.sp-dropdown.sp-show').removeClass('sp-show');
|
621 |
Â
if(!shown) e.target.parentElement.classList.add("sp-show");
|
622 |
Â
}
|
623 |
+
|
624 |
Â
function loadComparer(id) {
|
625 |
Â
this.comparerData.origUrl = false;
|
626 |
+
if(this.comparerData.cssLoaded === false) {
|
Â
|
|
627 |
Â
jQuery('<link>')
|
628 |
Â
.appendTo('head')
|
629 |
Â
.attr({
|
630 |
+
type: 'text/css',
|
631 |
Â
rel: 'stylesheet',
|
632 |
Â
href: this.WP_PLUGIN_URL + '/res/css/twentytwenty.min.css'
|
633 |
Â
});
|
641 |
Â
}
|
642 |
Â
});
|
643 |
Â
this.comparerData.jsLoaded = 1;
|
644 |
+
//jQuery(".sp-close-button").click(ShortPixel.closeComparerPopup);
|
645 |
Â
}
|
646 |
Â
if(this.comparerData.origUrl === false) {
|
647 |
Â
jQuery.ajax({
|
648 |
Â
type: "POST",
|
649 |
+
url: ShortPixel.AJAX_URL,
|
650 |
+
data: { action : 'shortpixel_get_comparer_data', id : id },
|
651 |
Â
success: function(response) {
|
652 |
Â
data = JSON.parse(response);
|
653 |
Â
jQuery.extend(ShortPixel.comparerData, data);
|
666 |
Â
//depending on the sizes choose the right modal
|
667 |
Â
var sideBySide = (height < 150 || width < 350);
|
668 |
Â
var modal = jQuery(sideBySide ? '#spUploadCompareSideBySide' : '#spUploadCompare');
|
669 |
+
var modalShade = jQuery('.sp-modal-shade');
|
670 |
+
|
671 |
Â
if(!sideBySide) {
|
672 |
Â
jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>');
|
673 |
Â
}
|
674 |
Â
//calculate the modal size
|
675 |
Â
width = Math.max(350, Math.min(800, (width < 350 ? (width + 25) * 2 : (height < 150 ? width + 25 : width))));
|
676 |
Â
height = Math.max(150, (sideBySide ? (origWidth > 350 ? 2 * (height + 45) : height + 45) : height * width / origWidth));
|
677 |
+
|
678 |
+
var marginLeft = '-' + Math.round(width/2); // center
|
679 |
+
|
680 |
Â
//set modal sizes and display
|
681 |
Â
jQuery(".sp-modal-body", modal).css("width", width);
|
682 |
Â
jQuery(".shortpixel-slider", modal).css("width", width);
|
683 |
Â
modal.css("width", width);
|
684 |
+
modal.css('marginLeft', marginLeft + 'px');
|
685 |
Â
jQuery(".sp-modal-body", modal).css("height", height);
|
686 |
+
modal.show();
|
687 |
+
//modal.parent().css('display', 'block');
|
688 |
+
modalShade.show();
|
689 |
+
|
690 |
Â
if(!sideBySide) {
|
691 |
Â
jQuery("#spCompareSlider").twentytwenty({slider_move: "mousemove"});
|
692 |
Â
}
|
693 |
+
|
694 |
+
// Close Options
|
695 |
+
jQuery(".sp-close-button").on('click', ShortPixel.closeComparerPopup);
|
696 |
Â
jQuery(document).on('keyup.sp_modal_active', ShortPixel.closeComparerPopup);
|
697 |
+
jQuery('.sp-modal-shade').on('click', ShortPixel.closeComparerPopup);
|
698 |
+
|
699 |
Â
//change images srcs
|
700 |
Â
var imgOpt = jQuery(".spUploadCompareOptimized", modal);
|
701 |
Â
jQuery(".spUploadCompareOriginal", modal).attr("src", imgOriginal);
|
708 |
Â
});
|
709 |
Â
imgOpt.attr("src", imgOptimized);
|
710 |
Â
}
|
711 |
+
|
712 |
Â
function closeComparerPopup(e) {
|
713 |
+
// jQuery("#spUploadCompareSideBySide").parent().css("display", 'none');
|
714 |
+
jQuery("#spUploadCompareSideBySide").hide();
|
715 |
+
jQuery("#spUploadCompare").hide();
|
716 |
+
jQuery('.sp-modal-shade').hide();
|
717 |
Â
jQuery(document).unbind('keyup.sp_modal_active');
|
718 |
+
jQuery('.sp-modal-shade').off('click');
|
719 |
+
jQuery(".sp-close-button").off('click');
|
720 |
Â
}
|
721 |
Â
|
722 |
Â
function convertPunycode(url) {
|
763 |
Â
bulkHideMaintenanceMsg : bulkHideMaintenanceMsg,
|
764 |
Â
bulkShowError : bulkShowError,
|
765 |
Â
confirmBulkAction : confirmBulkAction,
|
766 |
+
checkRandomAnswer : checkRandomAnswer,
|
767 |
Â
removeBulkMsg : removeBulkMsg,
|
768 |
Â
isCustomImageId : isCustomImageId,
|
769 |
Â
recheckQuota : recheckQuota,
|
790 |
Â
var robo = jQuery("li.shortpixel-toolbar-processing");
|
791 |
Â
switch($status) {
|
792 |
Â
case ShortPixel.STATUS_QUOTA_EXCEEDED:
|
793 |
+
if( window.location.href.search("wp-short-pixel-bulk") > 0
|
794 |
Â
&& jQuery(".sp-quota-exceeded-alert").length == 0) { //if we're in bulk and the alert is not displayed reload to see all options
|
795 |
Â
location.reload();
|
796 |
Â
return;
|
802 |
Â
//jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click to top-up");
|
803 |
Â
jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click for details.");
|
804 |
Â
break;
|
805 |
+
case ShortPixel.STATUS_SKIP:
|
806 |
Â
case ShortPixel.STATUS_FAIL:
|
807 |
Â
robo.addClass("shortpixel-alert shortpixel-processing");
|
808 |
Â
jQuery("a div", robo).attr("title", $message);
|
844 |
Â
}
|
845 |
Â
}
|
846 |
Â
/**
|
847 |
+
* JavaScript image processing - this method gets executed on every footer load and afterwards
|
848 |
Â
* calls itself until receives an Empty queue message
|
849 |
Â
*/
|
850 |
Â
function checkBulkProgress() {
|
851 |
+
//the replace stands for malformed urls on some sites, like wp-admin//upload.php which are accepted by the browser.
|
852 |
Â
//using a replacer function to avoid replacing the first occurence (https:// ...)
|
853 |
Â
var replacer = function(match) {
|
854 |
Â
if(!first) {
|
860 |
Â
|
861 |
Â
var first = false; //arm replacer
|
862 |
Â
var url = window.location.href.toLowerCase().replace(/\/\//g , replacer);
|
863 |
+
|
864 |
Â
first = false; //rearm replacer
|
865 |
Â
var adminUrl = ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g , replacer);
|
866 |
+
|
867 |
Â
//handle possible Punycode domain names.
|
868 |
Â
if(url.search(adminUrl) < 0) {
|
869 |
Â
url = ShortPixel.convertPunycode(url);
|
870 |
Â
adminUrl = ShortPixel.convertPunycode(adminUrl);
|
871 |
Â
}
|
872 |
+
|
873 |
Â
if( url.search(adminUrl + "upload.php") < 0
|
874 |
Â
&& url.search(adminUrl + "edit.php") < 0
|
875 |
Â
&& url.search(adminUrl + "edit-tags.php") < 0
|
881 |
Â
hideToolBarAlert();
|
882 |
Â
return;
|
883 |
Â
}
|
884 |
+
|
885 |
Â
//if i'm the bulk processor and i'm not the bulk page and a bulk page comes around, leave the bulk processor role
|
886 |
+
if(ShortPixel.bulkProcessor == true && window.location.href.search("wp-short-pixel-bulk") < 0
|
887 |
Â
&& typeof localStorage.bulkPage !== 'undefined' && localStorage.bulkPage > 0) {
|
888 |
Â
ShortPixel.bulkProcessor = false;
|
889 |
Â
}
|
890 |
+
|
891 |
Â
//if i'm the bulk page, steal the bulk processor
|
892 |
Â
if( window.location.href.search("wp-short-pixel-bulk") >= 0 ) {
|
893 |
Â
ShortPixel.bulkProcessor = true;
|
894 |
Â
localStorage.bulkTime = Math.floor(Date.now() / 1000);
|
895 |
Â
localStorage.bulkPage = 1;
|
896 |
Â
}
|
897 |
+
|
898 |
Â
//if I'm not the bulk processor, check every 20 sec. if the bulk processor is running, otherwise take the role
|
899 |
Â
if(ShortPixel.bulkProcessor == true || typeof localStorage.bulkTime == 'undefined' || Math.floor(Date.now() / 1000) - localStorage.bulkTime > 90) {
|
900 |
Â
ShortPixel.bulkProcessor = true;
|
913 |
Â
jQuery.ajax({
|
914 |
Â
type: "POST",
|
915 |
Â
url: ShortPixel.AJAX_URL, //formerly ajaxurl , but changed it because it's not available in the front-end and now we have an option to run in the front-end
|
916 |
+
data: data,
|
917 |
+
success: function(response)
|
918 |
Â
{
|
919 |
Â
if(response.length > 0) {
|
920 |
Â
var data = null;
|
925 |
Â
return;
|
926 |
Â
}
|
927 |
Â
ShortPixel.retries = 0;
|
928 |
+
|
929 |
Â
var id = data["ImageID"];
|
930 |
Â
|
931 |
Â
var isBulkPage = (jQuery("div.short-pixel-bulk-page").length > 0);
|
937 |
Â
showToolBarAlert(ShortPixel.STATUS_NO_KEY);
|
938 |
Â
break;
|
939 |
Â
case ShortPixel.STATUS_QUOTA_EXCEEDED:
|
940 |
+
setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"
|
941 |
Â
+ ShortPixel.API_KEY + "\" target=\"_blank\">" + _spTr.extendQuota + "</a>"
|
942 |
Â
+ "<a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>" + _spTr.check__Quota + "</a>");
|
943 |
Â
showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);
|
947 |
Â
ShortPixel.otherMediaUpdateActions(id, ['quota','view']);
|
948 |
Â
break;
|
949 |
Â
case ShortPixel.STATUS_FAIL:
|
950 |
+
setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('" + id + "', false)\">"
|
951 |
Â
+ _spTr.retry + "</a>");
|
952 |
Â
showToolBarAlert(ShortPixel.STATUS_FAIL, data["Message"], id);
|
953 |
Â
if(isBulkPage) {
|
984 |
Â
|
985 |
Â
showToolBarAlert(ShortPixel.STATUS_SUCCESS, "");
|
986 |
Â
//for now, until 4.1
|
987 |
+
var successActions = ShortPixel.isCustomImageId(id)
|
988 |
+
? ""
|
989 |
Â
: ShortPixel.successActions(id, data["Type"], data['ThumbsCount'], data['ThumbsTotal'], data["BackupEnabled"], data['Filename']);
|
990 |
+
|
991 |
+
// [BS] Set success message to Box.
|
992 |
Â
setCellMessage(id, ShortPixel.successMsg(id, percent, data["Type"], data['ThumbsCount'], data['RetinasCount']), successActions);
|
993 |
+
|
994 |
+
// [BS] Replace fileName in Media Library Row to return fileName.
|
995 |
+
if (jQuery('#post-' + id).length > 0)
|
996 |
+
jQuery('#post-' + id).find('.filename').text(data['Filename']);
|
997 |
+
|
998 |
+
// [BS] Replace filename if in media item edit view
|
999 |
+
if (jQuery('.misc-pub-filename strong').length > 0)
|
1000 |
+
jQuery('.misc-pub-filename strong').text(data['Filename']);
|
1001 |
+
|
1002 |
+
// [BS] Only update date on Custom Media Page.
|
1003 |
+
if (ShortPixel.isCustomImageId(id) && data['TsOptimized'] && data['TsOptimized'].length > 0)
|
1004 |
+
{
|
1005 |
+
console.log(id);
|
1006 |
+
jQuery('.date-' + id).text(data['TsOptimized']);
|
1007 |
+
}
|
1008 |
+
|
1009 |
+
|
1010 |
Â
var actions = jQuery(['restore', 'view', 'redolossy', 'redoglossy', 'redolossless']).not(['redo'+data["Type"]]).get();
|
1011 |
Â
ShortPixel.otherMediaUpdateActions(id, actions);
|
1012 |
Â
var animator = new PercentageAnimator("#sp-msg-" + id + " span.percent", percent);
|
1022 |
Â
ShortPixel.percentDial("#sp-avg-optimization .dial", 60);
|
1023 |
Â
}
|
1024 |
Â
}
|
1025 |
+
}
|
1026 |
+
|
1027 |
Â
console.log('Server response: ' + response);
|
1028 |
Â
if(isBulkPage && typeof data["BulkPercent"] !== 'undefined') {
|
1029 |
Â
progressUpdate(data["BulkPercent"], data["BulkMsg"]);
|
1088 |
Â
msg.html("<div class='sp-column-actions'>" + actions + "</div>"
|
1089 |
Â
+ "<div class='sp-column-info'>" + message + "</div>");
|
1090 |
Â
msg.css("color", "");
|
1091 |
+
}
|
1092 |
Â
msg = jQuery("#sp-cust-msg-" + id);
|
1093 |
Â
if(msg.length > 0) {
|
1094 |
Â
msg.html("<div class='sp-column-info'>" + message + "</div>");
|
1095 |
+
}
|
1096 |
Â
}
|
1097 |
Â
|
1098 |
Â
function manualOptimization(id, cleanup) {
|
1109 |
Â
success: function(response) {
|
1110 |
Â
var resp = JSON.parse(response);
|
1111 |
Â
if(resp["Status"] == ShortPixel.STATUS_SUCCESS) {
|
1112 |
+
//TODO - when calling several manual optimizations, the checkBulkProgress gets scheduled several times so several loops run in || - make only one.
|
1113 |
Â
setTimeout(checkBulkProgress, 2000);
|
1114 |
Â
} else {
|
1115 |
Â
setCellMessage(id, typeof resp["Message"] !== "undefined" ? resp["Message"] : _spTr.thisContentNotProcessable, "");
|
1201 |
Â
this.curPercentage = 0;
|
1202 |
Â
this.targetPercentage = targetPercentage;
|
1203 |
Â
this.outputSelector = outputSelector;
|
1204 |
+
|
1205 |
Â
this.animate = function(percentage) {
|
1206 |
Â
this.targetPercentage = percentage;
|
1207 |
Â
setTimeout(PercentageTimer.bind(null, this), this.animationSpeed);
|
1210 |
Â
|
1211 |
Â
function PercentageTimer(animator) {
|
1212 |
Â
if (animator.curPercentage - animator.targetPercentage < -animator.increment) {
|
1213 |
+
animator.curPercentage += animator.increment;
|
1214 |
Â
} else if (animator.curPercentage - animator.targetPercentage > animator.increment) {
|
1215 |
+
animator.curPercentage -= animator.increment;
|
1216 |
Â
} else {
|
1217 |
Â
animator.curPercentage = animator.targetPercentage;
|
1218 |
Â
}
|
1220 |
Â
jQuery(animator.outputSelector).text(animator.curPercentage + "%");
|
1221 |
Â
|
1222 |
Â
if (animator.curPercentage != animator.targetPercentage) {
|
1223 |
+
setTimeout(PercentageTimer.bind(null,animator), animator.animationSpeed)
|
1224 |
Â
}
|
1225 |
Â
}
|
1226 |
Â
|
1234 |
Â
jQuery(".progress-left", progress).html(percent + "%");
|
1235 |
Â
} else {
|
1236 |
Â
jQuery(".progress-img span", progress).html(percent + "%");
|
1237 |
+
jQuery(".progress-left", progress).html("");
|
1238 |
Â
}
|
1239 |
Â
jQuery(".bulk-estimate").html(message);
|
1240 |
Â
}
|
1246 |
Â
var oldSlide = jQuery(".bulk-slider div.bulk-slide:first-child");
|
1247 |
Â
if(oldSlide.length === 0) {
|
1248 |
Â
return;
|
1249 |
+
}
|
1250 |
Â
if(oldSlide.attr("id") != "empty-slide") {
|
1251 |
Â
oldSlide.hide();
|
1252 |
Â
}
|
1269 |
Â
jQuery(".img-original", newSlide).css("display", "none");
|
1270 |
Â
}
|
1271 |
Â
jQuery(".bulk-opt-percent", newSlide).html('<input type="text" class="dial" value="' + percent + '"/>');
|
1272 |
+
|
1273 |
Â
jQuery(".bulk-slider").append(newSlide);
|
1274 |
Â
ShortPixel.percentDial("#" + newSlide.attr("id") + " .dial", 100);
|
1275 |
+
|
1276 |
Â
jQuery(".bulk-slider-container span.filename").html(" " + filename);
|
1277 |
Â
if(oldSlide.attr("id") == "empty-slide") {
|
1278 |
Â
oldSlide.remove();
|
1292 |
Â
function showStats() {
|
1293 |
Â
var statsDiv = jQuery(".bulk-stats");
|
1294 |
Â
if(statsDiv.length > 0) {
|
1295 |
+
|
1296 |
Â
}
|
1297 |
Â
}
|
1298 |
Â
|
1299 |
+
if (!(typeof String.prototype.format == 'function')) {
|
1300 |
Â
String.prototype.format = function() {
|
1301 |
Â
var s = this,
|
1302 |
Â
i = arguments.length;
|
@@ -1 +1 @@
|
|
1 |
-
jQuery(document).ready(function(){ShortPixel.init()});var ShortPixel=function(){function I(){if(typeof ShortPixel.API_KEY!=="undefined"){return}if(jQuery("table.wp-list-table.media").length>0){jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">'+_spTr.optimizeWithSP+'</option><option value="short-pixel-bulk-lossy"> → '+_spTr.redoLossy+'</option><option value="short-pixel-bulk-glossy"> → '+_spTr.redoGlossy+'</option><option value="short-pixel-bulk-lossless"> → '+_spTr.redoLossless+'</option><option value="short-pixel-bulk-restore"> → '+_spTr.restoreOriginal+"</option>")}ShortPixel.setOptions(ShortPixelConstants[0]);if(jQuery("#backup-folder-size").length){jQuery("#backup-folder-size").html(ShortPixel.getBackupSize())}if(ShortPixel.MEDIA_ALERT=="todo"&&jQuery("div.media-frame.mode-grid").length>0){jQuery("div.media-frame.mode-grid").before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'+_spTr.changeMLToListMode.format('<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">'," </span>",'</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">',"</a>")+"</p></div>")}jQuery(window).on("beforeunload",function(){if(ShortPixel.bulkProcessor==true){clearBulkProcessor()}});checkQuotaExceededAlert();checkBulkProgress()}function m(Q){for(var R in Q){ShortPixel[R]=Q[R]}}function t(Q){return/^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(Q)}function n(){var Q=jQuery("#pluginemail").val();if(ShortPixel.isEmailValid(Q)){jQuery("#request_key").removeClass("disabled")}jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+Q)}function a(){jQuery("#valid").val("validate");jQuery("#wp_shortpixel_options").submit()}jQuery("#key").keypress(function(Q){if(Q.which==13){jQuery("#valid").val("validate")}});function L(Q){if(jQuery(Q).is(":checked")){jQuery("#width,#height").removeAttr("disabled")}else{jQuery("#width,#height").attr("disabled","disabled")}}function e(Q,S,U){for(var R=0,T=null;R<Q.length;R++){Q[R].onclick=function(){if(this!==T){T=this}if(typeof ShortPixel.setupGeneralTabAlert!=="undefined"){return}alert(_spTr.alertOnlyAppliesToNewImages);ShortPixel.setupGeneralTabAlert=1}}ShortPixel.enableResize("#resize");jQuery("#resize").change(function(){L(this)});jQuery(".resize-sizes").blur(function(W){var X=jQuery(this);if(ShortPixel.resizeSizesAlert==X.val()){return}ShortPixel.resizeSizesAlert=X.val();var V=jQuery("#min-"+X.attr("name")).val();if(X.val()<Math.min(V,1024)){if(V>1024){alert(_spTr.pleaseDoNotSetLesser1024.format(X.attr("name")))}else{alert(_spTr.pleaseDoNotSetLesserSize.format(X.attr("name"),X.attr("name"),V))}W.preventDefault();X.focus()}else{this.defaultValue=X.val()}});jQuery(".shortpixel-confirm").click(function(W){var V=confirm(W.target.getAttribute("data-confirm"));if(!V){W.preventDefault();return false}return true})}function C(){jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display","none");jQuery(".wp-shortpixel-options button#validate").css("display","inline-block")}function u(){jQuery("input.remove-folder-button").click(function(){var R=jQuery(this).data("value");var Q=confirm(_spTr.areYouSureStopOptimizing.format(R));if(Q==true){jQuery("#removeFolder").val(R);jQuery("#wp_shortpixel_options").submit()}});jQuery("input.recheck-folder-button").click(function(){var R=jQuery(this).data("value");var Q=confirm(_spTr.areYouSureStopOptimizing.format(R));if(Q==true){jQuery("#recheckFolder").val(R);jQuery("#wp_shortpixel_options").submit()}})}function K(Q){var R=jQuery("#"+(Q.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(R);jQuery("#displayTotal").text(R)}function g(){ShortPixel.adjustSettingsTabs();jQuery(window).resize(function(){ShortPixel.adjustSettingsTabs()});if(window.location.hash){var Q=("tab-"+window.location.hash.substring(window.location.hash.indexOf("#")+1)).replace(/\//,"");if(jQuery("section#"+Q).length){ShortPixel.switchSettingsTab(Q)}}jQuery("article.sp-tabs a.tab-link").click(function(){var R=jQuery(this).data("id");ShortPixel.switchSettingsTab(R)});jQuery("input[type=radio][name=deliverWebpType]").change(function(){if(this.value=="deliverWebpAltered"){if(window.confirm(_spTr.alertDeliverWebPAltered)){var R=jQuery("input[type=radio][name=deliverWebpAlteringType]:checked").length;if(R==0){jQuery("#deliverWebpAlteredWP").prop("checked",true)}}else{jQuery(this).prop("checked",false)}}else{if(this.value=="deliverWebpUnaltered"){window.alert(_spTr.alertDeliverWebPUnaltered)}}})}function x(U){var S=U.replace("tab-",""),Q="",T=jQuery("section#"+U),R=location.href.replace(location.hash,"")+"#"+S;if(history.pushState){history.pushState(null,null,R)}else{location.hash=R}if(T.length>0){jQuery("section").removeClass("sel-tab");jQuery("section#"+U).addClass("sel-tab")}if(typeof HS.beacon.suggest!=="undefined"){switch(S){case"settings":Q=shortpixel_suggestions_settings;break;case"adv-settings":Q=shortpixel_suggestions_adv_settings;break;case"cloudflare":case"stats":Q=shortpixel_suggestions_cloudflare;break;default:break}HS.beacon.suggest(Q)}}function y(){var Q=jQuery("section#tab-settings .wp-shortpixel-options").height()+90;Q=Math.max(Q,jQuery("section#tab-adv-settings .wp-shortpixel-options").height()+20);Q=Math.max(Q,jQuery("section#tab-resources .area1").height()+60);jQuery("#shortpixel-settings-tabs").css("height",Q)}function M(){var Q={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,Q,function(R){Q=JSON.parse(R);if(Q.Status=="success"){jQuery("#short-pixel-media-alert").hide();console.log("dismissed")}})}function k(){var Q={action:"shortpixel_check_quota"};jQuery.get(ShortPixel.AJAX_URL,Q,function(){console.log("quota refreshed")})}function B(Q){if(Q.checked){jQuery("#with-thumbs").css("display","inherit");jQuery("#without-thumbs").css("display","none")}else{jQuery("#without-thumbs").css("display","inherit");jQuery("#with-thumbs").css("display","none")}}function b(U,S,R,T,Q){return(S>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+S+"%</span></strong> ":"")+(S>0&&S<5?"<br>":"")+(S<5?_spTr.bonusProcessing:"")+(R.length>0?" ("+R+")":"")+(0+T>0?"<br>"+_spTr.plusXthumbsOpt.format(T):"")+(0+Q>0?"<br>"+_spTr.plusXretinasOpt.format(Q):"")+"</div>"}function p(R,Q){jQuery(R).knob({readOnly:true,width:Q,height:Q,fgColor:"#1CAECB",format:function(S){return S+"%"}})}function c(X,S,V,U,R,W){if(R==1){var T=jQuery(".sp-column-actions-template").clone();if(!T.length){return false}var Q;if(S.length==0){Q=["lossy","lossless"]}else{Q=["lossy","glossy","lossless"].filter(function(Y){return !(Y==S)})}T.html(T.html().replace(/__SP_ID__/g,X));if(W.substr(W.lastIndexOf(".")+1).toLowerCase()=="pdf"){jQuery(".sp-action-compare",T).remove()}if(V==0&&U>0){T.html(T.html().replace("__SP_THUMBS_TOTAL__",U))}else{jQuery(".sp-action-optimize-thumbs",T).remove();jQuery(".sp-dropbtn",T).removeClass("button-primary")}T.html(T.html().replace(/__SP_FIRST_TYPE__/g,Q[0]));T.html(T.html().replace(/__SP_SECOND_TYPE__/g,Q[1]));return T.html()}return""}function i(U,T){U=U.substring(2);if(jQuery(".shortpixel-other-media").length){var S=["optimize","retry","restore","redo","quota","view"];for(var R=0,Q=S.length;R<Q;R++){jQuery("#"+S[R]+"_"+U).css("display","none")}for(var R=0,Q=T.length;R<Q;R++){jQuery("#"+T[R]+"_"+U).css("display","")}}}function j(Q){ShortPixel.retries++;if(isNaN(ShortPixel.retries)){ShortPixel.retries=1}if(ShortPixel.retries<6){console.log("Invalid response from server (Error: "+Q+"). Retrying pass "+(ShortPixel.retries+1)+"...");setTimeout(checkBulkProgress,5000)}else{ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: "+Q+")","");console.log("Invalid response from server 6 times. Giving up.")}}function l(Q){Q.action="shortpixel_browse_content";var R="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:Q,success:function(S){R=S},async:false});return R}function d(){var Q={action:"shortpixel_get_backup_size"};var R="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:Q,success:function(S){R=S},async:false});return R}function f(R){if(!jQuery("#tos").is(":checked")){R.preventDefault();jQuery("#tos-robo").fadeIn(400,function(){jQuery("#tos-hand").fadeIn()});jQuery("#tos").click(function(){jQuery("#tos-robo").css("display","none");jQuery("#tos-hand").css("display","none")});return}jQuery("#request_key").addClass("disabled");jQuery("#pluginemail_spinner").addClass("is-active");ShortPixel.updateSignupEmail();if(ShortPixel.isEmailValid(jQuery("#pluginemail").val())){jQuery("#pluginemail-error").css("display","none");var Q={action:"shortpixel_new_api_key",email:jQuery("#pluginemail").val()};jQuery.ajax({type:"POST",async:false,url:ShortPixel.AJAX_URL,data:Q,success:function(S){data=JSON.parse(S);if(data.Status=="success"){R.preventDefault();window.location.reload()}else{if(data.Status=="invalid"){jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>");jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");R.preventDefault()}else{}}}});jQuery("#request_key").removeAttr("onclick")}else{jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");R.preventDefault()}jQuery("#request_key").removeClass("disabled");jQuery("#pluginemail_spinner").removeClass("is-active")}function N(){jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html("");jQuery("#shortPixelProposeUpgradeShade").css("display","block");jQuery("#shortPixelProposeUpgrade").removeClass("shortpixel-hide");var Q={action:"shortpixel_propose_upgrade"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:Q,success:function(R){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(R)}})}function G(){jQuery("#shortPixelProposeUpgradeShade").css("display","none");jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide");if(ShortPixel.toRefresh){ShortPixel.recheckQuota()}}function v(){jQuery("#short-pixel-notice-unlisted").hide();jQuery("#optimizeUnlisted").prop("checked",true);var Q={action:"shortpixel_dismiss_notice",notice_id:"unlisted",notice_data:"true"};jQuery.get(ShortPixel.AJAX_URL,Q,function(R){Q=JSON.parse(R);if(Q.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function o(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").css("display","block");jQuery(".sp-folder-picker").fileTree({script:ShortPixel.browseContent,multiFolder:false})});jQuery(".shortpixel-modal input.select-folder-cancel").click(function(){jQuery(".sp-folder-picker-shade").css("display","none")});jQuery(".shortpixel-modal input.select-folder").click(function(){var Q=jQuery("UL.jqueryFileTree LI.directory.selected A").attr("rel").trim();if(Q){var R=jQuery("#customFolderBase").val()+Q;if(R.slice(-1)=="/"){R=R.slice(0,-1)}jQuery("#addCustomFolder").val(R);jQuery("#addCustomFolderView").val(R);jQuery(".sp-folder-picker-shade").css("display","none")}else{alert("Please select a folder from the list.")}})}function F(U,T,S){var R=jQuery(".bulk-notice-msg.bulk-lengthy");if(R.length==0){return}var Q=jQuery("a",R);Q.text(T);if(S){Q.attr("href",S)}else{Q.attr("href",Q.data("href").replace("__ID__",U))}R.css("display","block")}function A(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")}function w(Q){var R=jQuery(".bulk-notice-msg.bulk-"+Q);if(R.length==0){return}R.css("display","block")}function O(Q){jQuery(".bulk-notice-msg.bulk-"+Q).css("display","none")}function s(W,U,V,T){var Q=jQuery("#bulk-error-template");if(Q.length==0){return}var S=Q.clone();S.attr("id","bulk-error-"+W);if(W==-1){jQuery("span.sp-err-title",S).remove();S.addClass("bulk-error-fatal")}else{jQuery("img",S).remove();jQuery("#bulk-error-".id).remove()}jQuery("span.sp-err-content",S).html(U);var R=jQuery("a.sp-post-link",S);if(T){R.attr("href",T)}else{R.attr("href",R.attr("href").replace("__ID__",W))}R.text(V);Q.after(S);S.css("display","block")}function D(Q,R){if(!confirm(_spTr["confirmBulk"+Q])){R.stopPropagation();R.preventDefault();return false}return true}function r(Q){jQuery(Q).parent().parent().remove()}function H(Q){return Q.substring(0,2)=="C-"}function J(){var Q=window.location.href.split("#");window.location.href=Q[0]+(Q[0].indexOf("?")>0?"&":"?")+"checkquota=1"+(typeof Q[1]==="undefined"?"":"#"+Q[1])}function h(R){R.preventDefault();if(!this.menuCloseEvent){jQuery(window).click(function(S){if(!S.target.matches(".sp-dropbtn")){jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}});this.menuCloseEvent=true}var Q=R.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show");if(!Q){R.target.parentElement.classList.add("sp-show")}}function P(Q){this.comparerData.origUrl=false;if(this.comparerData.cssLoaded===false){jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"});this.comparerData.cssLoaded=2}if(this.comparerData.jsLoaded===false){jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2;if(ShortPixel.comparerData.origUrl.length>0){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}});this.comparerData.jsLoaded=1;jQuery(".sp-close-button").click(ShortPixel.closeComparerPopup)}if(this.comparerData.origUrl===false){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:Q},success:function(R){data=JSON.parse(R);jQuery.extend(ShortPixel.comparerData,data);if(ShortPixel.comparerData.jsLoaded==2){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}});this.comparerData.origUrl=""}}function E(U,S,R,T){var X=U;var W=(S<150||U<350);var V=jQuery(W?"#spUploadCompareSideBySide":"#spUploadCompare");if(!W){jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>')}U=Math.max(350,Math.min(800,(U<350?(U+25)*2:(S<150?U+25:U))));S=Math.max(150,(W?(X>350?2*(S+45):S+45):S*U/X));jQuery(".sp-modal-body",V).css("width",U);jQuery(".shortpixel-slider",V).css("width",U);V.css("width",U);jQuery(".sp-modal-body",V).css("height",S);V.css("display","block");V.parent().css("display","block");if(!W){jQuery("#spCompareSlider").twentytwenty({slider_move:"mousemove"})}jQuery(document).on("keyup.sp_modal_active",ShortPixel.closeComparerPopup);var Q=jQuery(".spUploadCompareOptimized",V);jQuery(".spUploadCompareOriginal",V).attr("src",R);setTimeout(function(){jQuery(window).trigger("resize")},1000);Q.load(function(){jQuery(window).trigger("resize")});Q.attr("src",T)}function q(Q){jQuery("#spUploadCompareSideBySide").parent().css("display","none");jQuery("#spUploadCompareSideBySide").css("display","none");jQuery("#spUploadCompare").css("display","none");jQuery(document).unbind("keyup.sp_modal_active")}function z(Q){var R=document.createElement("a");R.href=Q;if(Q.indexOf(R.protocol+"//"+R.hostname)<0){return R.href}return Q.replace(R.protocol+"//"+R.hostname,R.protocol+"//"+R.hostname.split(".").map(function(S){return sp_punycode.toASCII(S)}).join("."))}return{init:I,setOptions:m,isEmailValid:t,updateSignupEmail:n,validateKey:a,enableResize:L,setupGeneralTab:e,apiKeyChanged:C,setupAdvancedTab:u,checkThumbsUpdTotal:K,initSettings:g,switchSettingsTab:x,adjustSettingsTabs:y,onBulkThumbsCheck:B,dismissMediaAlert:M,checkQuota:k,percentDial:p,successMsg:b,successActions:c,otherMediaUpdateActions:i,retry:j,initFolderSelector:o,browseContent:l,getBackupSize:d,newApiKey:f,proposeUpgrade:N,closeProposeUpgrade:G,includeUnlisted:v,bulkShowLengthyMsg:F,bulkHideLengthyMsg:A,bulkShowMaintenanceMsg:w,bulkHideMaintenanceMsg:O,bulkShowError:s,confirmBulkAction:D,removeBulkMsg:r,isCustomImageId:H,recheckQuota:J,openImageMenu:h,menuCloseEvent:false,loadComparer:P,displayComparerPopup:E,closeComparerPopup:q,convertPunycode:z,comparerData:{cssLoaded:false,jsLoaded:false,origUrl:false,optUrl:false,width:0,height:0},toRefresh:false,resizeSizesAlert:false}}();function showToolBarAlert(c,b,d){var a=jQuery("li.shortpixel-toolbar-processing");switch(c){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&jQuery(".sp-quota-exceeded-alert").length==0){location.reload();return}a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:a.addClass("shortpixel-alert shortpixel-processing");jQuery("a div",a).attr("title",b);if(typeof d!=="undefined"){jQuery("a",a).attr("href","post.php?post="+d+"&action=edit")}break;case ShortPixel.STATUS_NO_KEY:a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:a.addClass("shortpixel-processing");a.removeClass("shortpixel-alert");jQuery("a",a).removeAttr("target");jQuery("a",a).attr("href",jQuery("a img",a).attr("success-url"))}a.removeClass("shortpixel-hide")}function hideToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-processing").addClass("shortpixel-hide")}function hideQuotaExceededToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide")}function checkQuotaExceededAlert(){if(typeof shortPixelQuotaExceeded!="undefined"){if(shortPixelQuotaExceeded==1){showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED)}else{hideQuotaExceededToolBarAlert()}}}function checkBulkProgress(){var b=function(e){if(!d){d=true;return e}return"/"};var d=false;var a=window.location.href.toLowerCase().replace(/\/\//g,b);d=false;var c=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,b);if(a.search(c)<0){a=ShortPixel.convertPunycode(a);c=ShortPixel.convertPunycode(c)}if(a.search(c+"upload.php")<0&&a.search(c+"edit.php")<0&&a.search(c+"edit-tags.php")<0&&a.search(c+"post-new.php")<0&&a.search(c+"post.php")<0&&a.search("page=nggallery-manage-gallery")<0&&(ShortPixel.FRONT_BOOTSTRAP==0||a.search(c)==0)){hideToolBarAlert();return}if(ShortPixel.bulkProcessor==true&&window.location.href.search("wp-short-pixel-bulk")<0&&typeof localStorage.bulkPage!=="undefined"&&localStorage.bulkPage>0){ShortPixel.bulkProcessor=false}if(window.location.href.search("wp-short-pixel-bulk")>=0){ShortPixel.bulkProcessor=true;localStorage.bulkTime=Math.floor(Date.now()/1000);localStorage.bulkPage=1}if(ShortPixel.bulkProcessor==true||typeof localStorage.bulkTime=="undefined"||Math.floor(Date.now()/1000)-localStorage.bulkTime>90){ShortPixel.bulkProcessor=true;localStorage.bulkPage=(window.location.href.search("wp-short-pixel-bulk")>=0?1:0);localStorage.bulkTime=Math.floor(Date.now()/1000);console.log(localStorage.bulkTime);checkBulkProcessingCallApi()}else{setTimeout(checkBulkProgress,5000)}}function checkBulkProcessingCallApi(){var a={action:"shortpixel_image_processing"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:a,success:function(g){if(g.length>0){var i=null;try{var i=JSON.parse(g)}catch(k){ShortPixel.retry(k.message);return}ShortPixel.retries=0;var d=i.ImageID;var j=(jQuery("div.short-pixel-bulk-page").length>0);switch(i.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey"+ShortPixel.AFFILIATE+'" target="_blank">'+_spTr.getApiKey+"</a>");showToolBarAlert(ShortPixel.STATUS_NO_KEY);break;case ShortPixel.STATUS_QUOTA_EXCEEDED:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"+ShortPixel.API_KEY+'" target="_blank">'+_spTr.extendQuota+"</a><a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"+_spTr.check__Quota+"</a>");showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);if(i.Stop==false){setTimeout(checkBulkProgress,5000)}ShortPixel.otherMediaUpdateActions(d,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+d+"', false)\">"+_spTr.retry+"</a>");showToolBarAlert(ShortPixel.STATUS_FAIL,i.Message,d);if(j){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink);if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}ShortPixel.otherMediaUpdateActions(d,["retry","view"])}console.log(i.Message);setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(i.Message);clearBulkProcessor();hideToolBarAlert();var c=jQuery("#bulk-progress");if(j&&c.length&&i.BulkStatus!="2"){progressUpdate(100,"Bulk finished!");jQuery("a.bulk-cancel").attr("disabled","disabled");hideSlider();setTimeout(function(){window.location.reload()},3000)}break;case ShortPixel.STATUS_SUCCESS:if(j){ShortPixel.bulkHideLengthyMsg();ShortPixel.bulkHideMaintenanceMsg()}var l=i.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var b=ShortPixel.isCustomImageId(d)?"":ShortPixel.successActions(d,i.Type,i.ThumbsCount,i.ThumbsTotal,i.BackupEnabled,i.Filename);setCellMessage(d,ShortPixel.successMsg(d,l,i.Type,i.ThumbsCount,i.RetinasCount),b);var h=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+i.Type]).get();ShortPixel.otherMediaUpdateActions(d,h);var f=new PercentageAnimator("#sp-msg-"+d+" span.percent",l);f.animate(l);if(j&&typeof i.Thumb!=="undefined"){if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}if(i.Thumb.length>0){sliderUpdate(d,i.Thumb,i.BkThumb,i.PercentImprovement,i.Filename);if(typeof i.AverageCompression!=="undefined"&&0+i.AverageCompression>0){jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(i.AverageCompression)+'"/>');ShortPixel.percentDial("#sp-avg-optimization .dial",60)}}}console.log("Server response: "+g);if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_SKIP:if(i.Silent!==1){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink)}case ShortPixel.STATUS_ERROR:if(typeof i.Message!=="undefined"){showToolBarAlert(ShortPixel.STATUS_SKIP,i.Message+" Image ID: "+d);setCellMessage(d,i.Message,"")}ShortPixel.otherMediaUpdateActions(d,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+g);showToolBarAlert(ShortPixel.STATUS_RETRY,"");if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}if(j&&i.Count>3){ShortPixel.bulkShowLengthyMsg(d,i.Filename,i.CustomImageLink)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance");setTimeout(checkBulkProgress,60000);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full");setTimeout(checkBulkProgress,60000);break;default:ShortPixel.retry("Unknown status "+i.Status+". Retrying...");break}}},error:function(b){ShortPixel.retry(b.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=false;localStorage.bulkTime=0;if(window.location.href.search("wp-short-pixel-bulk")>=0){localStorage.bulkPage=0}}function setCellMessage(d,a,c){var b=jQuery("#sp-msg-"+d);if(b.length>0){b.html("<div class='sp-column-actions'>"+c+"</div><div class='sp-column-info'>"+a+"</div>");b.css("color","")}b=jQuery("#sp-cust-msg-"+d);if(b.length>0){b.html("<div class='sp-column-info'>"+a+"</div>")}}function manualOptimization(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be processed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_manual_optimization",image_id:c,cleanup:a};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(d){var e=JSON.parse(d);if(e.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(c,typeof e.Message!=="undefined"?e.Message:_spTr.thisContentNotProcessable,"")}},error:function(d){b.action="shortpixel_check_status";jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(e){var f=JSON.parse(e);if(f.Status!==ShortPixel.STATUS_SUCCESS){setCellMessage(c,typeof f.Message!=="undefined"?f.Message:_spTr.thisContentNotProcessable,"")}}})}})}function reoptimize(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be reprocessed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_redo",attachment_ID:c,type:a};jQuery.get(ShortPixel.AJAX_URL,b,function(d){b=JSON.parse(d);if(b.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{$msg=typeof b.Message!=="undefined"?b.Message:_spTr.thisContentNotProcessable;setCellMessage(c,$msg,"");showToolBarAlert(ShortPixel.STATUS_FAIL,$msg)}})}function optimizeThumbs(b){setCellMessage(b,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>"+_spTr.imageWaitOptThumbs,"");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var a={action:"shortpixel_optimize_thumbs",attachment_ID:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(b,typeof a.Message!=="undefined"?a.Message:_spTr.thisContentNotProcessable,"")}})}function dismissShortPixelNoticeExceed(b){jQuery("#wp-admin-bar-shortpixel_processing").hide();var a={action:"shortpixel_dismiss_notice",notice_id:"exceed"};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}});b.preventDefault()}function dismissShortPixelNotice(b){jQuery("#short-pixel-notice-"+b).hide();var a={action:"shortpixel_dismiss_notice",notice_id:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function PercentageAnimator(b,a){this.animationSpeed=10;this.increment=2;this.curPercentage=0;this.targetPercentage=a;this.outputSelector=b;this.animate=function(c){this.targetPercentage=c;setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(a){if(a.curPercentage-a.targetPercentage<-a.increment){a.curPercentage+=a.increment}else{if(a.curPercentage-a.targetPercentage>a.increment){a.curPercentage-=a.increment}else{a.curPercentage=a.targetPercentage}}jQuery(a.outputSelector).text(a.curPercentage+"%");if(a.curPercentage!=a.targetPercentage){setTimeout(PercentageTimer.bind(null,a),a.animationSpeed)}}function progressUpdate(c,b){var a=jQuery("#bulk-progress");if(a.length){jQuery(".progress-left",a).css("width",c+"%");jQuery(".progress-img",a).css("left",c+"%");if(c>24){jQuery(".progress-img span",a).html("");jQuery(".progress-left",a).html(c+"%")}else{jQuery(".progress-img span",a).html(c+"%");jQuery(".progress-left",a).html("")}jQuery(".bulk-estimate").html(b)}}function sliderUpdate(g,c,d,e,b){var f=jQuery(".bulk-slider div.bulk-slide:first-child");if(f.length===0){return}if(f.attr("id")!="empty-slide"){f.hide()}f.css("z-index",1000);jQuery(".bulk-img-opt",f).attr("src","");if(typeof d==="undefined"){d=""}if(d.length>0){jQuery(".bulk-img-orig",f).attr("src","")}var a=f.clone();a.attr("id","slide-"+g);jQuery(".bulk-img-opt",a).attr("src",c);if(d.length>0){jQuery(".img-original",a).css("display","inline-block");jQuery(".bulk-img-orig",a).attr("src",d)}else{jQuery(".img-original",a).css("display","none")}jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+e+'"/>');jQuery(".bulk-slider").append(a);ShortPixel.percentDial("#"+a.attr("id")+" .dial",100);jQuery(".bulk-slider-container span.filename").html(" "+b);if(f.attr("id")=="empty-slide"){f.remove();jQuery(".bulk-slider-container").css("display","block")}else{f.animate({left:f.width()+f.position().left},"slow","swing",function(){f.remove();a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){var a=jQuery(".bulk-stats");if(a.length>0){}}if(!(typeof String.prototype.format=="function")){String.prototype.format=function(){var b=this,a=arguments.length;while(a--){b=b.replace(new RegExp("\\{"+a+"\\}","gm"),arguments[a])}return b}};
|
1 |
+
jQuery(document).ready(function(){ShortPixel.init()});var ShortPixel=function(){function J(){if(typeof ShortPixel.API_KEY!=="undefined"){return}if(jQuery("table.wp-list-table.media").length>0){jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">'+_spTr.optimizeWithSP+'</option><option value="short-pixel-bulk-lossy"> → '+_spTr.redoLossy+'</option><option value="short-pixel-bulk-glossy"> → '+_spTr.redoGlossy+'</option><option value="short-pixel-bulk-lossless"> → '+_spTr.redoLossless+'</option><option value="short-pixel-bulk-restore"> → '+_spTr.restoreOriginal+"</option>")}ShortPixel.setOptions(ShortPixelConstants[0]);if(jQuery("#backup-folder-size").length){jQuery("#backup-folder-size").html(ShortPixel.getBackupSize())}if(ShortPixel.MEDIA_ALERT=="todo"&&jQuery("div.media-frame.mode-grid").length>0){jQuery("div.media-frame.mode-grid").before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'+_spTr.changeMLToListMode.format('<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">'," </span>",'</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">',"</a>")+"</p></div>")}jQuery(window).on("beforeunload",function(){if(ShortPixel.bulkProcessor==true){clearBulkProcessor()}});checkQuotaExceededAlert();checkBulkProgress()}function m(R){for(var S in R){ShortPixel[S]=R[S]}}function t(R){return/^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(R)}function n(){var R=jQuery("#pluginemail").val();if(ShortPixel.isEmailValid(R)){jQuery("#request_key").removeClass("disabled")}jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+R)}function a(){jQuery("#valid").val("validate");jQuery("#wp_shortpixel_options").submit()}jQuery("#key").keypress(function(R){if(R.which==13){jQuery("#valid").val("validate")}});function M(R){if(jQuery(R).is(":checked")){jQuery("#width,#height").removeAttr("disabled")}else{jQuery("#width,#height").attr("disabled","disabled")}}function e(R,T,V){for(var S=0,U=null;S<R.length;S++){R[S].onclick=function(){if(this!==U){U=this}if(typeof ShortPixel.setupGeneralTabAlert!=="undefined"){return}alert(_spTr.alertOnlyAppliesToNewImages);ShortPixel.setupGeneralTabAlert=1}}ShortPixel.enableResize("#resize");jQuery("#resize").change(function(){M(this)});jQuery(".resize-sizes").blur(function(X){var Y=jQuery(this);if(ShortPixel.resizeSizesAlert==Y.val()){return}ShortPixel.resizeSizesAlert=Y.val();var W=jQuery("#min-"+Y.attr("name")).val();if(Y.val()<Math.min(W,1024)){if(W>1024){alert(_spTr.pleaseDoNotSetLesser1024.format(Y.attr("name")))}else{alert(_spTr.pleaseDoNotSetLesserSize.format(Y.attr("name"),Y.attr("name"),W))}X.preventDefault();Y.focus()}else{this.defaultValue=Y.val()}});jQuery(".shortpixel-confirm").click(function(X){var W=confirm(X.target.getAttribute("data-confirm"));if(!W){X.preventDefault();return false}return true})}function D(){jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display","none");jQuery(".wp-shortpixel-options button#validate").css("display","inline-block")}function u(){jQuery("input.remove-folder-button").click(function(){var S=jQuery(this).data("value");var R=confirm(_spTr.areYouSureStopOptimizing.format(S));if(R==true){jQuery("#removeFolder").val(S);jQuery("#wp_shortpixel_options").submit()}});jQuery("input.recheck-folder-button").click(function(){var S=jQuery(this).data("value");var R=confirm(_spTr.areYouSureStopOptimizing.format(S));if(R==true){jQuery("#recheckFolder").val(S);jQuery("#wp_shortpixel_options").submit()}})}function L(R){var S=jQuery("#"+(R.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(S);jQuery("#displayTotal").text(S)}function g(){ShortPixel.adjustSettingsTabs();jQuery(window).resize(function(){ShortPixel.adjustSettingsTabs()});if(window.location.hash){var R=("tab-"+window.location.hash.substring(window.location.hash.indexOf("#")+1)).replace(/\//,"");if(jQuery("section#"+R).length){ShortPixel.switchSettingsTab(R)}}jQuery("article.sp-tabs a.tab-link").click(function(){var S=jQuery(this).data("id");ShortPixel.switchSettingsTab(S)});jQuery("input[type=radio][name=deliverWebpType]").change(function(){if(this.value=="deliverWebpAltered"){if(window.confirm(_spTr.alertDeliverWebPAltered)){var S=jQuery("input[type=radio][name=deliverWebpAlteringType]:checked").length;if(S==0){jQuery("#deliverWebpAlteredWP").prop("checked",true)}}else{jQuery(this).prop("checked",false)}}else{if(this.value=="deliverWebpUnaltered"){window.alert(_spTr.alertDeliverWebPUnaltered)}}})}function y(V){var T=V.replace("tab-",""),R="",U=jQuery("section#"+V),S=location.href.replace(location.hash,"")+"#"+T;if(history.pushState){history.pushState(null,null,S)}else{location.hash=S}if(U.length>0){jQuery("section").removeClass("sel-tab");jQuery("section#"+V).addClass("sel-tab")}if(typeof HS.beacon.suggest!=="undefined"){switch(T){case"settings":R=shortpixel_suggestions_settings;break;case"adv-settings":R=shortpixel_suggestions_adv_settings;break;case"cloudflare":case"stats":R=shortpixel_suggestions_cloudflare;break;default:break}HS.beacon.suggest(R)}}function z(){var R=jQuery("section#tab-settings .wp-shortpixel-options").height()+90;R=Math.max(R,jQuery("section#tab-adv-settings .wp-shortpixel-options").height()+20);R=Math.max(R,jQuery("section#tab-resources .area1").height()+60);jQuery("#shortpixel-settings-tabs").css("height",R)}function N(){var R={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,R,function(S){R=JSON.parse(S);if(R.Status=="success"){jQuery("#short-pixel-media-alert").hide();console.log("dismissed")}})}function k(){var R={action:"shortpixel_check_quota"};jQuery.get(ShortPixel.AJAX_URL,R,function(){console.log("quota refreshed")})}function C(R){if(R.checked){jQuery("#with-thumbs").css("display","inherit");jQuery("#without-thumbs").css("display","none")}else{jQuery("#without-thumbs").css("display","inherit");jQuery("#with-thumbs").css("display","none")}}function b(V,T,S,U,R){return(T>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+T+"%</span></strong> ":"")+(T>0&&T<5?"<br>":"")+(T<5?_spTr.bonusProcessing:"")+(S.length>0?" ("+S+")":"")+(0+U>0?"<br>"+_spTr.plusXthumbsOpt.format(U):"")+(0+R>0?"<br>"+_spTr.plusXretinasOpt.format(R):"")+"</div>"}function p(S,R){jQuery(S).knob({readOnly:true,width:R,height:R,fgColor:"#1CAECB",format:function(T){return T+"%"}})}function c(Y,T,W,V,S,X){if(S==1){var U=jQuery(".sp-column-actions-template").clone();if(!U.length){return false}var R;if(T.length==0){R=["lossy","lossless"]}else{R=["lossy","glossy","lossless"].filter(function(Z){return !(Z==T)})}U.html(U.html().replace(/__SP_ID__/g,Y));if(X.substr(X.lastIndexOf(".")+1).toLowerCase()=="pdf"){jQuery(".sp-action-compare",U).remove()}if(W==0&&V>0){U.html(U.html().replace("__SP_THUMBS_TOTAL__",V))}else{jQuery(".sp-action-optimize-thumbs",U).remove();jQuery(".sp-dropbtn",U).removeClass("button-primary")}U.html(U.html().replace(/__SP_FIRST_TYPE__/g,R[0]));U.html(U.html().replace(/__SP_SECOND_TYPE__/g,R[1]));return U.html()}return""}function i(V,U){V=V.substring(2);if(jQuery(".shortpixel-other-media").length){var T=["optimize","retry","restore","redo","quota","view"];for(var S=0,R=T.length;S<R;S++){jQuery("#"+T[S]+"_"+V).css("display","none")}for(var S=0,R=U.length;S<R;S++){jQuery("#"+U[S]+"_"+V).css("display","")}}}function j(R){ShortPixel.retries++;if(isNaN(ShortPixel.retries)){ShortPixel.retries=1}if(ShortPixel.retries<6){console.log("Invalid response from server (Error: "+R+"). Retrying pass "+(ShortPixel.retries+1)+"...");setTimeout(checkBulkProgress,5000)}else{ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: "+R+")","");console.log("Invalid response from server 6 times. Giving up.")}}function l(R){R.action="shortpixel_browse_content";var S="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:R,success:function(T){S=T},async:false});return S}function d(){var R={action:"shortpixel_get_backup_size"};var S="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:R,success:function(T){S=T},async:false});return S}function f(S){if(!jQuery("#tos").is(":checked")){S.preventDefault();jQuery("#tos-robo").fadeIn(400,function(){jQuery("#tos-hand").fadeIn()});jQuery("#tos").click(function(){jQuery("#tos-robo").css("display","none");jQuery("#tos-hand").css("display","none")});return}jQuery("#request_key").addClass("disabled");jQuery("#pluginemail_spinner").addClass("is-active");ShortPixel.updateSignupEmail();if(ShortPixel.isEmailValid(jQuery("#pluginemail").val())){jQuery("#pluginemail-error").css("display","none");var R={action:"shortpixel_new_api_key",email:jQuery("#pluginemail").val()};jQuery.ajax({type:"POST",async:false,url:ShortPixel.AJAX_URL,data:R,success:function(T){data=JSON.parse(T);if(data.Status=="success"){S.preventDefault();window.location.reload()}else{if(data.Status=="invalid"){jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>");jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");S.preventDefault()}else{}}}});jQuery("#request_key").removeAttr("onclick")}else{jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");S.preventDefault()}jQuery("#request_key").removeClass("disabled");jQuery("#pluginemail_spinner").removeClass("is-active")}function O(){jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html("");jQuery("#shortPixelProposeUpgradeShade").css("display","block");jQuery("#shortPixelProposeUpgrade").removeClass("shortpixel-hide");var R={action:"shortpixel_propose_upgrade"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:R,success:function(S){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(S)}})}function H(){jQuery("#shortPixelProposeUpgradeShade").css("display","none");jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide");if(ShortPixel.toRefresh){ShortPixel.recheckQuota()}}function v(){jQuery("#short-pixel-notice-unlisted").hide();jQuery("#optimizeUnlisted").prop("checked",true);var R={action:"shortpixel_dismiss_notice",notice_id:"unlisted",notice_data:"true"};jQuery.get(ShortPixel.AJAX_URL,R,function(S){R=JSON.parse(S);if(R.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function o(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").fadeIn(100);jQuery(".shortpixel-modal.modal-folder-picker").show();var R=jQuery(".sp-folder-picker");R.parent().css("margin-left",-R.width()/2);R.fileTree({script:ShortPixel.browseContent,multiFolder:false})});jQuery(".shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade").click(function(){jQuery(".sp-folder-picker-shade").fadeOut(100);jQuery(".shortpixel-modal.modal-folder-picker").hide()});jQuery(".shortpixel-modal input.select-folder").click(function(U){var T=jQuery("UL.jqueryFileTree LI.directory.selected");if(jQuery(T).length==0){var T=jQuery("UL.jqueryFileTree LI.selected").parents(".directory")}var R=jQuery(T).children("a").attr("rel");if(typeof R==="undefined"){return}R=R.trim();if(R){var S=jQuery("#customFolderBase").val()+R;if(S.slice(-1)=="/"){S=S.slice(0,-1)}jQuery("#addCustomFolder").val(S);jQuery("#addCustomFolderView").val(S);jQuery(".sp-folder-picker-shade").fadeOut(100);jQuery(".shortpixel-modal.modal-folder-picker").css("display","none");jQuery('input[name="saveAdv"]').removeClass("hidden")}else{alert("Please select a folder from the list.")}})}function G(V,U,T){var S=jQuery(".bulk-notice-msg.bulk-lengthy");if(S.length==0){return}var R=jQuery("a",S);R.text(U);if(T){R.attr("href",T)}else{R.attr("href",R.data("href").replace("__ID__",V))}S.css("display","block")}function B(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")}function w(R){var S=jQuery(".bulk-notice-msg.bulk-"+R);if(S.length==0){return}S.css("display","block")}function P(R){jQuery(".bulk-notice-msg.bulk-"+R).css("display","none")}function s(X,V,W,U){var R=jQuery("#bulk-error-template");if(R.length==0){return}var T=R.clone();T.attr("id","bulk-error-"+X);if(X==-1){jQuery("span.sp-err-title",T).remove();T.addClass("bulk-error-fatal")}else{jQuery("img",T).remove();jQuery("#bulk-error-".id).remove()}jQuery("span.sp-err-content",T).html(V);var S=jQuery("a.sp-post-link",T);if(U){S.attr("href",U)}else{S.attr("href",S.attr("href").replace("__ID__",X))}S.text(W);R.after(T);T.css("display","block")}function E(R,S){if(!confirm(_spTr["confirmBulk"+R])){S.stopPropagation();S.preventDefault();return false}return true}function x(U){var S=jQuery(U.target).val();var R=jQuery('input[name="random_answer"]').val();var T=jQuery('input[name="random_answer"]').data("target");if(S==R){jQuery(T).removeClass("disabled").prop("disabled",false);jQuery(T).removeAttr("aria-disabled")}else{jQuery(T).addClass("disabled").prop("disabled",true)}}function r(R){jQuery(R).parent().parent().remove()}function I(R){return R.substring(0,2)=="C-"}function K(){var R=window.location.href.split("#");window.location.href=R[0]+(R[0].indexOf("?")>0?"&":"?")+"checkquota=1"+(typeof R[1]==="undefined"?"":"#"+R[1])}function h(S){S.preventDefault();if(!this.menuCloseEvent){jQuery(window).click(function(T){if(!T.target.matches(".sp-dropbtn")){jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}});this.menuCloseEvent=true}var R=S.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show");if(!R){S.target.parentElement.classList.add("sp-show")}}function Q(R){this.comparerData.origUrl=false;if(this.comparerData.cssLoaded===false){jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"});this.comparerData.cssLoaded=2}if(this.comparerData.jsLoaded===false){jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2;if(ShortPixel.comparerData.origUrl.length>0){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}});this.comparerData.jsLoaded=1}if(this.comparerData.origUrl===false){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:R},success:function(S){data=JSON.parse(S);jQuery.extend(ShortPixel.comparerData,data);if(ShortPixel.comparerData.jsLoaded==2){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}});this.comparerData.origUrl=""}}function F(T,Z,aa,U){var Y=T;var S=(Z<150||T<350);var X=jQuery(S?"#spUploadCompareSideBySide":"#spUploadCompare");var V=jQuery(".sp-modal-shade");if(!S){jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>')}T=Math.max(350,Math.min(800,(T<350?(T+25)*2:(Z<150?T+25:T))));Z=Math.max(150,(S?(Y>350?2*(Z+45):Z+45):Z*T/Y));var W="-"+Math.round(T/2);jQuery(".sp-modal-body",X).css("width",T);jQuery(".shortpixel-slider",X).css("width",T);X.css("width",T);X.css("marginLeft",W+"px");jQuery(".sp-modal-body",X).css("height",Z);X.show();V.show();if(!S){jQuery("#spCompareSlider").twentytwenty({slider_move:"mousemove"})}jQuery(".sp-close-button").on("click",ShortPixel.closeComparerPopup);jQuery(document).on("keyup.sp_modal_active",ShortPixel.closeComparerPopup);jQuery(".sp-modal-shade").on("click",ShortPixel.closeComparerPopup);var R=jQuery(".spUploadCompareOptimized",X);jQuery(".spUploadCompareOriginal",X).attr("src",aa);setTimeout(function(){jQuery(window).trigger("resize")},1000);R.load(function(){jQuery(window).trigger("resize")});R.attr("src",U)}function q(R){jQuery("#spUploadCompareSideBySide").hide();jQuery("#spUploadCompare").hide();jQuery(".sp-modal-shade").hide();jQuery(document).unbind("keyup.sp_modal_active");jQuery(".sp-modal-shade").off("click");jQuery(".sp-close-button").off("click")}function A(R){var S=document.createElement("a");S.href=R;if(R.indexOf(S.protocol+"//"+S.hostname)<0){return S.href}return R.replace(S.protocol+"//"+S.hostname,S.protocol+"//"+S.hostname.split(".").map(function(T){return sp_punycode.toASCII(T)}).join("."))}return{init:J,setOptions:m,isEmailValid:t,updateSignupEmail:n,validateKey:a,enableResize:M,setupGeneralTab:e,apiKeyChanged:D,setupAdvancedTab:u,checkThumbsUpdTotal:L,initSettings:g,switchSettingsTab:y,adjustSettingsTabs:z,onBulkThumbsCheck:C,dismissMediaAlert:N,checkQuota:k,percentDial:p,successMsg:b,successActions:c,otherMediaUpdateActions:i,retry:j,initFolderSelector:o,browseContent:l,getBackupSize:d,newApiKey:f,proposeUpgrade:O,closeProposeUpgrade:H,includeUnlisted:v,bulkShowLengthyMsg:G,bulkHideLengthyMsg:B,bulkShowMaintenanceMsg:w,bulkHideMaintenanceMsg:P,bulkShowError:s,confirmBulkAction:E,checkRandomAnswer:x,removeBulkMsg:r,isCustomImageId:I,recheckQuota:K,openImageMenu:h,menuCloseEvent:false,loadComparer:Q,displayComparerPopup:F,closeComparerPopup:q,convertPunycode:A,comparerData:{cssLoaded:false,jsLoaded:false,origUrl:false,optUrl:false,width:0,height:0},toRefresh:false,resizeSizesAlert:false}}();function showToolBarAlert(c,b,d){var a=jQuery("li.shortpixel-toolbar-processing");switch(c){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&jQuery(".sp-quota-exceeded-alert").length==0){location.reload();return}a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:a.addClass("shortpixel-alert shortpixel-processing");jQuery("a div",a).attr("title",b);if(typeof d!=="undefined"){jQuery("a",a).attr("href","post.php?post="+d+"&action=edit")}break;case ShortPixel.STATUS_NO_KEY:a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:a.addClass("shortpixel-processing");a.removeClass("shortpixel-alert");jQuery("a",a).removeAttr("target");jQuery("a",a).attr("href",jQuery("a img",a).attr("success-url"))}a.removeClass("shortpixel-hide")}function hideToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-processing").addClass("shortpixel-hide")}function hideQuotaExceededToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide")}function checkQuotaExceededAlert(){if(typeof shortPixelQuotaExceeded!="undefined"){if(shortPixelQuotaExceeded==1){showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED)}else{hideQuotaExceededToolBarAlert()}}}function checkBulkProgress(){var b=function(e){if(!d){d=true;return e}return"/"};var d=false;var a=window.location.href.toLowerCase().replace(/\/\//g,b);d=false;var c=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,b);if(a.search(c)<0){a=ShortPixel.convertPunycode(a);c=ShortPixel.convertPunycode(c)}if(a.search(c+"upload.php")<0&&a.search(c+"edit.php")<0&&a.search(c+"edit-tags.php")<0&&a.search(c+"post-new.php")<0&&a.search(c+"post.php")<0&&a.search("page=nggallery-manage-gallery")<0&&(ShortPixel.FRONT_BOOTSTRAP==0||a.search(c)==0)){hideToolBarAlert();return}if(ShortPixel.bulkProcessor==true&&window.location.href.search("wp-short-pixel-bulk")<0&&typeof localStorage.bulkPage!=="undefined"&&localStorage.bulkPage>0){ShortPixel.bulkProcessor=false}if(window.location.href.search("wp-short-pixel-bulk")>=0){ShortPixel.bulkProcessor=true;localStorage.bulkTime=Math.floor(Date.now()/1000);localStorage.bulkPage=1}if(ShortPixel.bulkProcessor==true||typeof localStorage.bulkTime=="undefined"||Math.floor(Date.now()/1000)-localStorage.bulkTime>90){ShortPixel.bulkProcessor=true;localStorage.bulkPage=(window.location.href.search("wp-short-pixel-bulk")>=0?1:0);localStorage.bulkTime=Math.floor(Date.now()/1000);console.log(localStorage.bulkTime);checkBulkProcessingCallApi()}else{setTimeout(checkBulkProgress,5000)}}function checkBulkProcessingCallApi(){var a={action:"shortpixel_image_processing"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:a,success:function(g){if(g.length>0){var i=null;try{var i=JSON.parse(g)}catch(k){ShortPixel.retry(k.message);return}ShortPixel.retries=0;var d=i.ImageID;var j=(jQuery("div.short-pixel-bulk-page").length>0);switch(i.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey"+ShortPixel.AFFILIATE+'" target="_blank">'+_spTr.getApiKey+"</a>");showToolBarAlert(ShortPixel.STATUS_NO_KEY);break;case ShortPixel.STATUS_QUOTA_EXCEEDED:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"+ShortPixel.API_KEY+'" target="_blank">'+_spTr.extendQuota+"</a><a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"+_spTr.check__Quota+"</a>");showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);if(i.Stop==false){setTimeout(checkBulkProgress,5000)}ShortPixel.otherMediaUpdateActions(d,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+d+"', false)\">"+_spTr.retry+"</a>");showToolBarAlert(ShortPixel.STATUS_FAIL,i.Message,d);if(j){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink);if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}ShortPixel.otherMediaUpdateActions(d,["retry","view"])}console.log(i.Message);setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(i.Message);clearBulkProcessor();hideToolBarAlert();var c=jQuery("#bulk-progress");if(j&&c.length&&i.BulkStatus!="2"){progressUpdate(100,"Bulk finished!");jQuery("a.bulk-cancel").attr("disabled","disabled");hideSlider();setTimeout(function(){window.location.reload()},3000)}break;case ShortPixel.STATUS_SUCCESS:if(j){ShortPixel.bulkHideLengthyMsg();ShortPixel.bulkHideMaintenanceMsg()}var l=i.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var b=ShortPixel.isCustomImageId(d)?"":ShortPixel.successActions(d,i.Type,i.ThumbsCount,i.ThumbsTotal,i.BackupEnabled,i.Filename);setCellMessage(d,ShortPixel.successMsg(d,l,i.Type,i.ThumbsCount,i.RetinasCount),b);if(jQuery("#post-"+d).length>0){jQuery("#post-"+d).find(".filename").text(i.Filename)}if(jQuery(".misc-pub-filename strong").length>0){jQuery(".misc-pub-filename strong").text(i.Filename)}if(ShortPixel.isCustomImageId(d)&&i.TsOptimized&&i.TsOptimized.length>0){console.log(d);jQuery(".date-"+d).text(i.TsOptimized)}var h=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+i.Type]).get();ShortPixel.otherMediaUpdateActions(d,h);var f=new PercentageAnimator("#sp-msg-"+d+" span.percent",l);f.animate(l);if(j&&typeof i.Thumb!=="undefined"){if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}if(i.Thumb.length>0){sliderUpdate(d,i.Thumb,i.BkThumb,i.PercentImprovement,i.Filename);if(typeof i.AverageCompression!=="undefined"&&0+i.AverageCompression>0){jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(i.AverageCompression)+'"/>');ShortPixel.percentDial("#sp-avg-optimization .dial",60)}}}console.log("Server response: "+g);if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_SKIP:if(i.Silent!==1){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink)}case ShortPixel.STATUS_ERROR:if(typeof i.Message!=="undefined"){showToolBarAlert(ShortPixel.STATUS_SKIP,i.Message+" Image ID: "+d);setCellMessage(d,i.Message,"")}ShortPixel.otherMediaUpdateActions(d,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+g);showToolBarAlert(ShortPixel.STATUS_RETRY,"");if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}if(j&&i.Count>3){ShortPixel.bulkShowLengthyMsg(d,i.Filename,i.CustomImageLink)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance");setTimeout(checkBulkProgress,60000);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full");setTimeout(checkBulkProgress,60000);break;default:ShortPixel.retry("Unknown status "+i.Status+". Retrying...");break}}},error:function(b){ShortPixel.retry(b.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=false;localStorage.bulkTime=0;if(window.location.href.search("wp-short-pixel-bulk")>=0){localStorage.bulkPage=0}}function setCellMessage(d,a,c){var b=jQuery("#sp-msg-"+d);if(b.length>0){b.html("<div class='sp-column-actions'>"+c+"</div><div class='sp-column-info'>"+a+"</div>");b.css("color","")}b=jQuery("#sp-cust-msg-"+d);if(b.length>0){b.html("<div class='sp-column-info'>"+a+"</div>")}}function manualOptimization(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be processed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_manual_optimization",image_id:c,cleanup:a};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(d){var e=JSON.parse(d);if(e.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(c,typeof e.Message!=="undefined"?e.Message:_spTr.thisContentNotProcessable,"")}},error:function(d){b.action="shortpixel_check_status";jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(e){var f=JSON.parse(e);if(f.Status!==ShortPixel.STATUS_SUCCESS){setCellMessage(c,typeof f.Message!=="undefined"?f.Message:_spTr.thisContentNotProcessable,"")}}})}})}function reoptimize(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be reprocessed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_redo",attachment_ID:c,type:a};jQuery.get(ShortPixel.AJAX_URL,b,function(d){b=JSON.parse(d);if(b.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{$msg=typeof b.Message!=="undefined"?b.Message:_spTr.thisContentNotProcessable;setCellMessage(c,$msg,"");showToolBarAlert(ShortPixel.STATUS_FAIL,$msg)}})}function optimizeThumbs(b){setCellMessage(b,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>"+_spTr.imageWaitOptThumbs,"");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var a={action:"shortpixel_optimize_thumbs",attachment_ID:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(b,typeof a.Message!=="undefined"?a.Message:_spTr.thisContentNotProcessable,"")}})}function dismissShortPixelNoticeExceed(b){jQuery("#wp-admin-bar-shortpixel_processing").hide();var a={action:"shortpixel_dismiss_notice",notice_id:"exceed"};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}});b.preventDefault()}function dismissShortPixelNotice(b){jQuery("#short-pixel-notice-"+b).hide();var a={action:"shortpixel_dismiss_notice",notice_id:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function PercentageAnimator(b,a){this.animationSpeed=10;this.increment=2;this.curPercentage=0;this.targetPercentage=a;this.outputSelector=b;this.animate=function(c){this.targetPercentage=c;setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(a){if(a.curPercentage-a.targetPercentage<-a.increment){a.curPercentage+=a.increment}else{if(a.curPercentage-a.targetPercentage>a.increment){a.curPercentage-=a.increment}else{a.curPercentage=a.targetPercentage}}jQuery(a.outputSelector).text(a.curPercentage+"%");if(a.curPercentage!=a.targetPercentage){setTimeout(PercentageTimer.bind(null,a),a.animationSpeed)}}function progressUpdate(c,b){var a=jQuery("#bulk-progress");if(a.length){jQuery(".progress-left",a).css("width",c+"%");jQuery(".progress-img",a).css("left",c+"%");if(c>24){jQuery(".progress-img span",a).html("");jQuery(".progress-left",a).html(c+"%")}else{jQuery(".progress-img span",a).html(c+"%");jQuery(".progress-left",a).html("")}jQuery(".bulk-estimate").html(b)}}function sliderUpdate(g,c,d,e,b){var f=jQuery(".bulk-slider div.bulk-slide:first-child");if(f.length===0){return}if(f.attr("id")!="empty-slide"){f.hide()}f.css("z-index",1000);jQuery(".bulk-img-opt",f).attr("src","");if(typeof d==="undefined"){d=""}if(d.length>0){jQuery(".bulk-img-orig",f).attr("src","")}var a=f.clone();a.attr("id","slide-"+g);jQuery(".bulk-img-opt",a).attr("src",c);if(d.length>0){jQuery(".img-original",a).css("display","inline-block");jQuery(".bulk-img-orig",a).attr("src",d)}else{jQuery(".img-original",a).css("display","none")}jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+e+'"/>');jQuery(".bulk-slider").append(a);ShortPixel.percentDial("#"+a.attr("id")+" .dial",100);jQuery(".bulk-slider-container span.filename").html(" "+b);if(f.attr("id")=="empty-slide"){f.remove();jQuery(".bulk-slider-container").css("display","block")}else{f.animate({left:f.width()+f.position().left},"slow","swing",function(){f.remove();a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){var a=jQuery(".bulk-stats");if(a.length>0){}}if(!(typeof String.prototype.format=="function")){String.prototype.format=function(){var b=this,a=arguments.length;while(a--){b=b.replace(new RegExp("\\{"+a+"\\}","gm"),arguments[a])}return b}};
|
@@ -0,0 +1,3 @@
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
|
2 |
+
@import 'view/bulk-restore-all';
|
3 |
+
@import 'view/settings-advanced';
|
@@ -0,0 +1,54 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
|
2 |
+
.short-pixel-bulk-page.bulk-restore-all{
|
3 |
+
|
4 |
+
ol {
|
5 |
+
li {
|
6 |
+
font-weight: 700;
|
7 |
+
}
|
8 |
+
}
|
9 |
+
|
10 |
+
section.select_folders
|
11 |
+
{
|
12 |
+
// border-bottom: 1px solid #ccc;
|
13 |
+
margin: 20px 0;
|
14 |
+
.input
|
15 |
+
{
|
16 |
+
margin: 10px 0 10px 15px;
|
17 |
+
font-size: 16px;
|
18 |
+
display: block;
|
19 |
+
clear: both;
|
20 |
+
}
|
21 |
+
|
22 |
+
.filecount
|
23 |
+
{
|
24 |
+
font-size: 12px;
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
section.random_check
|
29 |
+
{
|
30 |
+
.random_answer
|
31 |
+
{
|
32 |
+
font-size:16px;
|
33 |
+
font-weight: 700;
|
34 |
+
padding: 8px;
|
35 |
+
border: 1px solid #ccc;
|
36 |
+
display: inline-block;
|
37 |
+
|
38 |
+
}
|
39 |
+
|
40 |
+
.inputs
|
41 |
+
{
|
42 |
+
margin: 15px 0;
|
43 |
+
span { margin-right: 8px; }
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
|
48 |
+
|
49 |
+
.button
|
50 |
+
{
|
51 |
+
margin: 10px 0;
|
52 |
+
margin-right: 8px;
|
53 |
+
}
|
54 |
+
}
|
@@ -0,0 +1,26 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
/* Specific styles for advanced settings tab */
|
2 |
+
|
3 |
+
#shortpixel-settings-tabs #tab-adv-settings
|
4 |
+
{
|
5 |
+
|
6 |
+
.addCustomFolder
|
7 |
+
{
|
8 |
+
margin: 10px 0;
|
9 |
+
.add-folder-text
|
10 |
+
{
|
11 |
+
margin-left: 5px;
|
12 |
+
}
|
13 |
+
input[type="text"]
|
14 |
+
{
|
15 |
+
width: 50em;
|
16 |
+
max-width: 70%;
|
17 |
+
}
|
18 |
+
input[name="saveAdv"]
|
19 |
+
{
|
20 |
+
margin-left: 8px;
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
|
26 |
+
}
|
@@ -1,874 +1,884 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !function_exists( 'download_url' ) ) {
|
3 |
-
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
4 |
-
}
|
5 |
-
|
6 |
-
class ShortPixelAPI {
|
7 |
-
|
8 |
-
const STATUS_SUCCESS = 1;
|
9 |
-
const STATUS_UNCHANGED = 0;
|
10 |
-
const STATUS_ERROR = -1;
|
11 |
-
const STATUS_FAIL = -2;
|
12 |
-
const STATUS_QUOTA_EXCEEDED = -3;
|
13 |
-
const STATUS_SKIP = -4;
|
14 |
-
const STATUS_NOT_FOUND = -5;
|
15 |
-
const STATUS_NO_KEY = -6;
|
16 |
-
const STATUS_RETRY = -7;
|
17 |
-
const STATUS_QUEUE_FULL = -404;
|
18 |
-
const STATUS_MAINTENANCE = -500;
|
19 |
-
|
20 |
-
const ERR_FILE_NOT_FOUND = -2;
|
21 |
-
const ERR_TIMEOUT = -3;
|
22 |
-
const ERR_SAVE = -4;
|
23 |
-
const ERR_SAVE_BKP = -5;
|
24 |
-
const ERR_INCORRECT_FILE_SIZE = -6;
|
25 |
-
const ERR_DOWNLOAD = -7;
|
26 |
-
const ERR_PNG2JPG_MEMORY = -8;
|
27 |
-
const ERR_POSTMETA_CORRUPT = -9;
|
28 |
-
const ERR_UNKNOWN = -999;
|
29 |
-
|
30 |
-
private $_settings;
|
31 |
-
private $_apiEndPoint;
|
32 |
-
private $_apiDumpEndPoint;
|
33 |
-
|
34 |
-
|
35 |
-
public function __construct($settings) {
|
36 |
-
$this->_settings = $settings;
|
37 |
-
$this->_apiEndPoint = $this->_settings->httpProto . '://' . SHORTPIXEL_API . '/v2/reducer.php';
|
38 |
-
$this->_apiDumpEndPoint = $this->_settings->httpProto . '://' . SHORTPIXEL_API . '/v2/cleanup.php';
|
39 |
-
}
|
40 |
-
|
41 |
-
protected function prepareRequest($requestParameters, $Blocking = false) {
|
42 |
-
$arguments = array(
|
43 |
-
'method' => 'POST',
|
44 |
-
'timeout' => 15,
|
45 |
-
'redirection' => 3,
|
46 |
-
'sslverify' => false,
|
47 |
-
'httpversion' => '1.0',
|
48 |
-
'blocking' => $Blocking,
|
49 |
-
'headers' => array(),
|
50 |
-
'body' => json_encode($requestParameters),
|
51 |
-
'cookies' => array()
|
52 |
-
);
|
53 |
-
//die(var_dump($requestParameters));
|
54 |
-
//add this explicitely only for https, otherwise (for http) it slows down the request
|
55 |
-
if($this->_settings->httpProto !== 'https') {
|
56 |
-
unset($arguments['sslverify']);
|
57 |
-
}
|
58 |
-
|
59 |
-
return $arguments;
|
60 |
-
}
|
61 |
-
|
62 |
-
public function doDumpRequests($URLs) {
|
63 |
-
if(!count($URLs)) {
|
64 |
-
return false;
|
65 |
-
}
|
66 |
-
|
67 |
-
'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
|
68 |
-
'key' => $this->_settings->apiKey,
|
69 |
-
'urllist' => $URLs
|
70 |
-
) ) );
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
*
|
76 |
-
* @param
|
77 |
-
* @param
|
78 |
-
* @param
|
79 |
-
* @param bool $
|
80 |
-
* @
|
81 |
-
* @
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
$
|
90 |
-
|
91 |
-
|
92 |
-
$
|
93 |
-
$
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
$
|
106 |
-
|
107 |
-
'
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
'
|
114 |
-
'
|
115 |
-
'
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
*
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
$
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
$
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
$apiRetries
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
}
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
if
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
if
|
268 |
-
$
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
$err = array("Status" => self::
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
$
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
case -
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
}
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
if
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
if
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
$returnMessage = array(
|
428 |
-
"
|
429 |
-
"
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
"
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
{
|
457 |
-
|
458 |
-
}
|
459 |
-
//
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
{
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
if($
|
497 |
-
return array("Status" => self::
|
498 |
-
}
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
$
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
$
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
if
|
600 |
-
|
601 |
-
}
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
$
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
$
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
$
|
744 |
-
$
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
$
|
753 |
-
$
|
754 |
-
$meta->
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
$meta->
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
$meta->
|
765 |
-
$
|
766 |
-
|
767 |
-
|
768 |
-
$
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
$
|
819 |
-
$
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
$
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
if ( !function_exists( 'download_url' ) ) {
|
3 |
+
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
4 |
+
}
|
5 |
+
|
6 |
+
class ShortPixelAPI {
|
7 |
+
|
8 |
+
const STATUS_SUCCESS = 1;
|
9 |
+
const STATUS_UNCHANGED = 0;
|
10 |
+
const STATUS_ERROR = -1;
|
11 |
+
const STATUS_FAIL = -2;
|
12 |
+
const STATUS_QUOTA_EXCEEDED = -3;
|
13 |
+
const STATUS_SKIP = -4;
|
14 |
+
const STATUS_NOT_FOUND = -5;
|
15 |
+
const STATUS_NO_KEY = -6;
|
16 |
+
const STATUS_RETRY = -7;
|
17 |
+
const STATUS_QUEUE_FULL = -404;
|
18 |
+
const STATUS_MAINTENANCE = -500;
|
19 |
+
|
20 |
+
const ERR_FILE_NOT_FOUND = -2;
|
21 |
+
const ERR_TIMEOUT = -3;
|
22 |
+
const ERR_SAVE = -4;
|
23 |
+
const ERR_SAVE_BKP = -5;
|
24 |
+
const ERR_INCORRECT_FILE_SIZE = -6;
|
25 |
+
const ERR_DOWNLOAD = -7;
|
26 |
+
const ERR_PNG2JPG_MEMORY = -8;
|
27 |
+
const ERR_POSTMETA_CORRUPT = -9;
|
28 |
+
const ERR_UNKNOWN = -999;
|
29 |
+
|
30 |
+
private $_settings;
|
31 |
+
private $_apiEndPoint;
|
32 |
+
private $_apiDumpEndPoint;
|
33 |
+
|
34 |
+
|
35 |
+
public function __construct($settings) {
|
36 |
+
$this->_settings = $settings;
|
37 |
+
$this->_apiEndPoint = $this->_settings->httpProto . '://' . SHORTPIXEL_API . '/v2/reducer.php';
|
38 |
+
$this->_apiDumpEndPoint = $this->_settings->httpProto . '://' . SHORTPIXEL_API . '/v2/cleanup.php';
|
39 |
+
}
|
40 |
+
|
41 |
+
protected function prepareRequest($requestParameters, $Blocking = false) {
|
42 |
+
$arguments = array(
|
43 |
+
'method' => 'POST',
|
44 |
+
'timeout' => 15,
|
45 |
+
'redirection' => 3,
|
46 |
+
'sslverify' => false,
|
47 |
+
'httpversion' => '1.0',
|
48 |
+
'blocking' => $Blocking,
|
49 |
+
'headers' => array(),
|
50 |
+
'body' => json_encode($requestParameters),
|
51 |
+
'cookies' => array()
|
52 |
+
);
|
53 |
+
//die(var_dump($requestParameters));
|
54 |
+
//add this explicitely only for https, otherwise (for http) it slows down the request
|
55 |
+
if($this->_settings->httpProto !== 'https') {
|
56 |
+
unset($arguments['sslverify']);
|
57 |
+
}
|
58 |
+
|
59 |
+
return $arguments;
|
60 |
+
}
|
61 |
+
|
62 |
+
public function doDumpRequests($URLs) {
|
63 |
+
if(!count($URLs)) {
|
64 |
+
return false;
|
65 |
+
}
|
66 |
+
$ret = wp_remote_post($this->_apiDumpEndPoint, $this->prepareRequest(array(
|
67 |
+
'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
|
68 |
+
'key' => $this->_settings->apiKey,
|
69 |
+
'urllist' => $URLs
|
70 |
+
) ) );
|
71 |
+
return $ret;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* sends a compression request to the API
|
76 |
+
* @param array $URLs - list of urls to send to API
|
77 |
+
* @param Boolean $Blocking - true means it will wait for an answer
|
78 |
+
* @param ShortPixelMetaFacade $itemHandler - the Facade that manages different types of image metadatas: MediaLibrary (postmeta table), ShortPixel custom (shortpixel_meta table)
|
79 |
+
* @param bool|int $compressionType 1 - lossy, 2 - glossy, 0 - lossless
|
80 |
+
* @param bool $refresh
|
81 |
+
* @return Array response from wp_remote_post or error
|
82 |
+
* @throws Exception
|
83 |
+
*/
|
84 |
+
public function doRequests($URLs, $Blocking, $itemHandler, $compressionType = false, $refresh = false) {
|
85 |
+
|
86 |
+
if(!count($URLs)) {
|
87 |
+
$meta = $itemHandler->getMeta();
|
88 |
+
if(count($meta->getThumbsMissing())) {
|
89 |
+
$added = array();
|
90 |
+
$files = " (";
|
91 |
+
foreach ($meta->getThumbsMissing() as $miss) {
|
92 |
+
if(isset($added[$miss])) continue;
|
93 |
+
$files .= $miss . ", ";
|
94 |
+
$added[$miss] = true;
|
95 |
+
}
|
96 |
+
if(strrpos($files, ', ')) {
|
97 |
+
$files = substr_replace($files , ')', strrpos($files , ', '));
|
98 |
+
}
|
99 |
+
throw new Exception(__('Image files are missing.', 'shortpixel-image-optimiser') . (strlen($files) > 1 ? $files : ''));
|
100 |
+
}
|
101 |
+
else throw new Exception(__('Image files are missing.', 'shortpixel-image-optimiser'));
|
102 |
+
}
|
103 |
+
|
104 |
+
$apiKey = $this->_settings->apiKey;
|
105 |
+
if(strlen($apiKey) < 20) { //found in the logs many cases when the API Key is '', probably deleted from the DB but the verifiedKey setting is not changed
|
106 |
+
$this->_settings->verifiedKey = false;
|
107 |
+
throw new Exception(__('Invalid API Key', 'shortpixel-image-optimiser'));
|
108 |
+
}
|
109 |
+
|
110 |
+
// WpShortPixel::log("DO REQUESTS for META: " . json_encode($itemHandler->getRawMeta()) . " STACK: " . json_encode(debug_backtrace()));
|
111 |
+
|
112 |
+
$requestParameters = array(
|
113 |
+
'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
|
114 |
+
'key' => $apiKey,
|
115 |
+
'lossy' => $compressionType === false ? $this->_settings->compressionType : $compressionType,
|
116 |
+
'cmyk2rgb' => $this->_settings->CMYKtoRGBconversion,
|
117 |
+
'keep_exif' => ($this->_settings->keepExif ? "1" : "0"),
|
118 |
+
'convertto' => ($this->_settings->createWebp ? urlencode("+webp") : ""),
|
119 |
+
'resize' => $this->_settings->resizeImages ? 1 + 2 * ($this->_settings->resizeType == 'inner' ? 1 : 0) : 0,
|
120 |
+
'resize_width' => $this->_settings->resizeWidth,
|
121 |
+
'resize_height' => $this->_settings->resizeHeight,
|
122 |
+
'urllist' => $URLs
|
123 |
+
);
|
124 |
+
if(/*false &&*/ $this->_settings->downloadArchive == 7 && class_exists('PharData')) {
|
125 |
+
$requestParameters['group'] = $itemHandler->getId();
|
126 |
+
}
|
127 |
+
if($refresh) {
|
128 |
+
$requestParameters['refresh'] = 1;
|
129 |
+
}
|
130 |
+
|
131 |
+
//WpShortPixel::log("ShortPixel API Request Settings: " . json_encode($requestParameters));
|
132 |
+
|
133 |
+
$response = wp_remote_post($this->_apiEndPoint, $this->prepareRequest($requestParameters, $Blocking) );
|
134 |
+
|
135 |
+
//WpShortPixel::log('RESPONSE: ' . json_encode($response));
|
136 |
+
|
137 |
+
//only if $Blocking is true analyze the response
|
138 |
+
if ( $Blocking )
|
139 |
+
{
|
140 |
+
//WpShortPixel::log("API response : " . json_encode($response));
|
141 |
+
|
142 |
+
//die(var_dump(array('URL: ' => $this->_apiEndPoint, '<br><br>REQUEST:' => $requestParameters, '<br><br>RESPONSE: ' => $response, '<br><br>BODY: ' => isset($response['body']) ? $response['body'] : '' )));
|
143 |
+
//there was an error, save this error inside file's SP optimization field
|
144 |
+
if ( is_object($response) && get_class($response) == 'WP_Error' )
|
145 |
+
{
|
146 |
+
$errorMessage = $response->errors['http_request_failed'][0];
|
147 |
+
$errorCode = 503;
|
148 |
+
}
|
149 |
+
elseif ( isset($response['response']['code']) && $response['response']['code'] <> 200 )
|
150 |
+
{
|
151 |
+
$errorMessage = $response['response']['code'] . " - " . $response['response']['message'];
|
152 |
+
$errorCode = $response['response']['code'];
|
153 |
+
}
|
154 |
+
|
155 |
+
if ( isset($errorMessage) )
|
156 |
+
{//set details inside file so user can know what happened
|
157 |
+
$itemHandler->incrementRetries(1, $errorCode, $errorMessage);
|
158 |
+
return array("response" => array("code" => $errorCode, "message" => $errorMessage ));
|
159 |
+
}
|
160 |
+
|
161 |
+
return $response;//this can be an error or a good response
|
162 |
+
}
|
163 |
+
|
164 |
+
return $response;
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* parse the JSON response
|
169 |
+
* @param $response
|
170 |
+
* @return array parsed
|
171 |
+
*/
|
172 |
+
public function parseResponse($response) {
|
173 |
+
$data = $response['body'];
|
174 |
+
$data = json_decode($data);
|
175 |
+
return (array)$data;
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* handles the processing of the image using the ShortPixel API
|
180 |
+
* @param array $URLs - list of urls to send to API
|
181 |
+
* @param array $PATHs - list of local paths for the images
|
182 |
+
* @param ShortPixelMetaFacade $itemHandler - the Facade that manages different types of image metadatas: MediaLibrary (postmeta table), ShortPixel custom (shortpixel_meta table)
|
183 |
+
* @return array status/message array
|
184 |
+
*/
|
185 |
+
public function processImage($URLs, $PATHs, $itemHandler = null) {
|
186 |
+
return $this->processImageRecursive($URLs, $PATHs, $itemHandler, 0);
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* handles the processing of the image using the ShortPixel API - cals itself recursively until success
|
191 |
+
* @param array $URLs - list of urls to send to API
|
192 |
+
* @param array $PATHs - list of local paths for the images
|
193 |
+
* @param ShortPixelMetaFacade $itemHandler - the Facade that manages different types of image metadatas: MediaLibrary (postmeta table), ShortPixel custom (shortpixel_meta table)
|
194 |
+
* @param int $startTime - time of the first call
|
195 |
+
* @return array status/message array
|
196 |
+
*/
|
197 |
+
private function processImageRecursive($URLs, $PATHs, $itemHandler = null, $startTime = 0)
|
198 |
+
{
|
199 |
+
//WPShortPixel::log("processImageRecursive ID: " . $itemHandler->getId() . " PATHs: " . json_encode($PATHs));
|
200 |
+
|
201 |
+
$PATHs = self::CheckAndFixImagePaths($PATHs);//check for images to make sure they exist on disk
|
202 |
+
if ( $PATHs === false || isset($PATHs['error'])) {
|
203 |
+
$missingFiles = '';
|
204 |
+
if(isset($PATHs['error'])) {
|
205 |
+
foreach($PATHs['error'] as $errPath) {
|
206 |
+
$missingFiles .= (strlen($missingFiles) ? ', ':'') . basename(stripslashes($errPath));
|
207 |
+
}
|
208 |
+
}
|
209 |
+
$msg = __('The file(s) do not exist on disk: ','shortpixel-image-optimiser') . $missingFiles;
|
210 |
+
$itemHandler->setError(self::ERR_FILE_NOT_FOUND, $msg );
|
211 |
+
return array("Status" => self::STATUS_SKIP, "Message" => $msg, "Silent" => $itemHandler->getType() == ShortPixelMetaFacade::CUSTOM_TYPE ? 1 : 0);
|
212 |
+
}
|
213 |
+
|
214 |
+
//tries multiple times (till timeout almost reached) to fetch images.
|
215 |
+
if($startTime == 0) {
|
216 |
+
$startTime = time();
|
217 |
+
}
|
218 |
+
$apiRetries = $this->_settings->apiRetries;
|
219 |
+
|
220 |
+
if( time() - $startTime > SHORTPIXEL_MAX_EXECUTION_TIME2)
|
221 |
+
{//keeps track of time
|
222 |
+
if ( $apiRetries > SHORTPIXEL_MAX_API_RETRIES )//we tried to process this time too many times, giving up...
|
223 |
+
{
|
224 |
+
$itemHandler->incrementRetries(1, self::ERR_TIMEOUT, __('Timed out while processing.','shortpixel-image-optimiser'));
|
225 |
+
$this->_settings->apiRetries = 0; //fai added to solve a bug?
|
226 |
+
return array("Status" => self::STATUS_SKIP,
|
227 |
+
"Message" => ($itemHandler->getType() == ShortPixelMetaFacade::CUSTOM_TYPE ? __('Image ID','shortpixel-image-optimiser') : __('Media ID','shortpixel-image-optimiser'))
|
228 |
+
. ": " . $itemHandler->getId() .' ' . __('Skip this image, try the next one.','shortpixel-image-optimiser'));
|
229 |
+
}
|
230 |
+
else
|
231 |
+
{//we'll try again next time user visits a page on admin panel
|
232 |
+
$apiRetries++;
|
233 |
+
$this->_settings->apiRetries = $apiRetries;
|
234 |
+
return array("Status" => self::STATUS_RETRY, "Message" => __('Timed out while processing.','shortpixel-image-optimiser') . ' (pass '.$apiRetries.')',
|
235 |
+
"Count" => $apiRetries);
|
236 |
+
}
|
237 |
+
}
|
238 |
+
|
239 |
+
//#$compressionType = isset($meta['ShortPixel']['type']) ? ($meta['ShortPixel']['type'] == 'lossy' ? 1 : 0) : $this->_settings->compressionType;
|
240 |
+
$meta = $itemHandler->getMeta();
|
241 |
+
$compressionType = $meta->getCompressionType() !== null ? $meta->getCompressionType() : $this->_settings->compressionType;
|
242 |
+
$response = $this->doRequests($URLs, true, $itemHandler, $compressionType);//send requests to API
|
243 |
+
|
244 |
+
//die($response['body']);
|
245 |
+
|
246 |
+
if($response['response']['code'] != 200) {//response <> 200 -> there was an error apparently?
|
247 |
+
return array("Status" => self::STATUS_FAIL, "Message" => __('There was an error and your request was not processed.', 'shortpixel-image-optimiser')
|
248 |
+
. (isset($response['response']['message']) ? ' (' . $response['response']['message'] . ')' : ''), "Code" => $response['response']['code']);
|
249 |
+
}
|
250 |
+
|
251 |
+
$APIresponse = $this->parseResponse($response);//get the actual response from API, its an array
|
252 |
+
|
253 |
+
if ( isset($APIresponse[0]) ) //API returned image details
|
254 |
+
{
|
255 |
+
foreach ( $APIresponse as $imageObject ) {//this part makes sure that all the sizes were processed and ready to be downloaded
|
256 |
+
if ( isset($imageObject->Status) && ( $imageObject->Status->Code == 0 || $imageObject->Status->Code == 1 ) ) {
|
257 |
+
sleep(1);
|
258 |
+
return $this->processImageRecursive($URLs, $PATHs, $itemHandler, $startTime);
|
259 |
+
}
|
260 |
+
}
|
261 |
+
|
262 |
+
$firstImage = $APIresponse[0];//extract as object first image
|
263 |
+
switch($firstImage->Status->Code)
|
264 |
+
{
|
265 |
+
case 2:
|
266 |
+
//handle image has been processed
|
267 |
+
if(!isset($firstImage->Status->QuotaExceeded)) {
|
268 |
+
$this->_settings->quotaExceeded = 0;//reset the quota exceeded flag
|
269 |
+
}
|
270 |
+
return $this->handleSuccess($APIresponse, $PATHs, $itemHandler, $compressionType);
|
271 |
+
default:
|
272 |
+
//handle error
|
273 |
+
$incR = 1;
|
274 |
+
if ( !file_exists($PATHs[0]) ) {
|
275 |
+
$err = array("Status" => self::STATUS_NOT_FOUND, "Message" => "File not found on disk. "
|
276 |
+
. ($itemHandler->getType() == ShortPixelMetaFacade::CUSTOM_TYPE ? "Image" : "Media")
|
277 |
+
. " ID: " . $itemHandler->getId(), "Code" => self::ERR_FILE_NOT_FOUND);
|
278 |
+
$incR = 3;
|
279 |
+
}
|
280 |
+
elseif ( isset($APIresponse[0]->Status->Message) ) {
|
281 |
+
//return array("Status" => self::STATUS_FAIL, "Message" => "There was an error and your request was not processed (" . $APIresponse[0]->Status->Message . "). REQ: " . json_encode($URLs));
|
282 |
+
$err = array("Status" => self::STATUS_FAIL, "Code" => (isset($APIresponse[0]->Status->Code) ? $APIresponse[0]->Status->Code : self::ERR_UNKNOWN),
|
283 |
+
"Message" => __('There was an error and your request was not processed.','shortpixel-image-optimiser')
|
284 |
+
. " (" . wp_basename($APIresponse[0]->OriginalURL) . ": " . $APIresponse[0]->Status->Message . ")");
|
285 |
+
} else {
|
286 |
+
$err = array("Status" => self::STATUS_FAIL, "Message" => __('There was an error and your request was not processed.','shortpixel-image-optimiser'),
|
287 |
+
"Code" => (isset($APIresponse[0]->Status->Code) ? $APIresponse[0]->Status->Code : self::ERR_UNKNOWN));
|
288 |
+
}
|
289 |
+
|
290 |
+
$itemHandler->incrementRetries($incR, $err["Code"], $err["Message"]);
|
291 |
+
$meta = $itemHandler->getMeta();
|
292 |
+
if($meta->getRetries() >= SHORTPIXEL_MAX_FAIL_RETRIES) {
|
293 |
+
$meta->setStatus($APIresponse[0]->Status->Code);
|
294 |
+
$meta->setMessage($APIresponse[0]->Status->Message);
|
295 |
+
$itemHandler->updateMeta($meta);
|
296 |
+
}
|
297 |
+
return $err;
|
298 |
+
}
|
299 |
+
}
|
300 |
+
|
301 |
+
if(!isset($APIresponse['Status'])) {
|
302 |
+
WpShortPixel::log("API Response Status unfound : " . json_encode($APIresponse));
|
303 |
+
return array("Status" => self::STATUS_FAIL, "Message" => __('Unrecognized API response. Please contact support.','shortpixel-image-optimiser'),
|
304 |
+
"Code" => self::ERR_UNKNOWN, "Debug" => ' (SERVER RESPONSE: ' . json_encode($response) . ')');
|
305 |
+
} else {
|
306 |
+
switch($APIresponse['Status']->Code)
|
307 |
+
{
|
308 |
+
case -403:
|
309 |
+
@delete_option('bulkProcessingStatus');
|
310 |
+
$this->_settings->quotaExceeded = 1;
|
311 |
+
return array("Status" => self::STATUS_QUOTA_EXCEEDED, "Message" => __('Quota exceeded.','shortpixel-image-optimiser'));
|
312 |
+
break;
|
313 |
+
case -404:
|
314 |
+
return array("Status" => self::STATUS_QUEUE_FULL, "Message" => $APIresponse['Status']->Message);
|
315 |
+
case -500:
|
316 |
+
return array("Status" => self::STATUS_MAINTENANCE, "Message" => $APIresponse['Status']->Message);
|
317 |
+
}
|
318 |
+
|
319 |
+
//sometimes the response array can be different
|
320 |
+
if (is_numeric($APIresponse['Status']->Code)) {
|
321 |
+
return array("Status" => self::STATUS_FAIL, "Message" => $APIresponse['Status']->Message);
|
322 |
+
} else {
|
323 |
+
return array("Status" => self::STATUS_FAIL, "Message" => $APIresponse[0]->Status->Message);
|
324 |
+
}
|
325 |
+
}
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* sets the preferred protocol of URL using the globally set preferred protocol.
|
330 |
+
* If global protocol not set, sets it by testing the download of a http test image from ShortPixel site.
|
331 |
+
* If http works then it's http, otherwise sets https
|
332 |
+
* @param string $url
|
333 |
+
* @param bool $reset - forces recheck even if preferred protocol is already set
|
334 |
+
* @return string url with the preferred protocol
|
335 |
+
*/
|
336 |
+
public function setPreferredProtocol($url, $reset = false) {
|
337 |
+
//switch protocol based on the formerly detected working protocol
|
338 |
+
if($this->_settings->downloadProto == '' || $reset) {
|
339 |
+
//make a test to see if the http is working
|
340 |
+
$testURL = 'http://' . SHORTPIXEL_API . '/img/connection-test-image.png';
|
341 |
+
$result = download_url($testURL, 10);
|
342 |
+
$this->_settings->downloadProto = is_wp_error( $result ) ? 'https' : 'http';
|
343 |
+
}
|
344 |
+
return $this->_settings->downloadProto == 'http' ?
|
345 |
+
str_replace('https://', 'http://', $url) :
|
346 |
+
str_replace('http://', 'https://', $url);
|
347 |
+
|
348 |
+
|
349 |
+
}
|
350 |
+
|
351 |
+
function fromArchive($path, $optimizedUrl, $optimizedSize, $originalSize, $webpUrl) {
|
352 |
+
$webpTempFile = "NA";
|
353 |
+
if($webpUrl !== "NA") {
|
354 |
+
$webpTempFile = $path . '/' . wp_basename($webpUrl);
|
355 |
+
$webpTempFile = file_exists($webpTempFile) ? $webpTempFile : 'NA';
|
356 |
+
}
|
357 |
+
|
358 |
+
//if there is no improvement in size then we do not download this file
|
359 |
+
if ( $originalSize == $optimizedSize )
|
360 |
+
return array("Status" => self::STATUS_UNCHANGED, "Message" => "File wasn't optimized so we do not download it.", "WebP" => $webpTempFile);
|
361 |
+
|
362 |
+
$correctFileSize = $optimizedSize;
|
363 |
+
$tempFile = $path . '/' . wp_basename($optimizedUrl);
|
364 |
+
|
365 |
+
if(file_exists($tempFile)) {
|
366 |
+
//on success we return this
|
367 |
+
if( filesize($tempFile) != $correctFileSize) {
|
368 |
+
$size = filesize($tempFile);
|
369 |
+
@unlink($tempFile);
|
370 |
+
@unlink($webpTempFile);
|
371 |
+
$returnMessage = array(
|
372 |
+
"Status" => self::STATUS_ERROR,
|
373 |
+
"Code" => self::ERR_INCORRECT_FILE_SIZE,
|
374 |
+
"Message" => sprintf(__('Error in archive - incorrect file size (downloaded: %s, correct: %s )','shortpixel-image-optimiser'),$size, $correctFileSize));
|
375 |
+
} else {
|
376 |
+
$returnMessage = array("Status" => self::STATUS_SUCCESS, "Message" => $tempFile, "WebP" => $webpTempFile);
|
377 |
+
}
|
378 |
+
} else {
|
379 |
+
$returnMessage = array("Status" => self::STATUS_ERROR,
|
380 |
+
"Code" => self::ERR_FILE_NOT_FOUND,
|
381 |
+
"Message" => __('Unable to locate downloaded file','shortpixel-image-optimiser') . " " . $tempFile);
|
382 |
+
}
|
383 |
+
|
384 |
+
return $returnMessage;
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* handles the download of an optimized image from ShortPixel API
|
389 |
+
* @param string $optimizedUrl
|
390 |
+
* @param int $optimizedSize
|
391 |
+
* @param int $originalSize
|
392 |
+
* @param string $webpUrl
|
393 |
+
* @return array status /message array
|
394 |
+
*/
|
395 |
+
private function handleDownload($optimizedUrl, $optimizedSize, $originalSize, $webpUrl){
|
396 |
+
|
397 |
+
$downloadTimeout = max(ini_get('max_execution_time') - 10, 15);
|
398 |
+
|
399 |
+
$webpTempFile = "NA";
|
400 |
+
if($webpUrl !== "NA") {
|
401 |
+
$webpURL = $this->setPreferredProtocol(urldecode($webpUrl));
|
402 |
+
$webpTempFile = download_url($webpURL, $downloadTimeout);
|
403 |
+
$webpTempFile = is_wp_error( $webpTempFile ) ? "NA" : $webpTempFile;
|
404 |
+
}
|
405 |
+
|
406 |
+
//if there is no improvement in size then we do not download this file
|
407 |
+
if ( $originalSize == $optimizedSize )
|
408 |
+
return array("Status" => self::STATUS_UNCHANGED, "Message" => "File wasn't optimized so we do not download it.", "WebP" => $webpTempFile);
|
409 |
+
|
410 |
+
$correctFileSize = $optimizedSize;
|
411 |
+
$fileURL = $this->setPreferredProtocol(urldecode($optimizedUrl));
|
412 |
+
|
413 |
+
$tempFile = download_url($fileURL, $downloadTimeout);
|
414 |
+
WPShortPixel::log('Downloading file: '.json_encode($tempFile));
|
415 |
+
if(is_wp_error( $tempFile ))
|
416 |
+
{ //try to switch the default protocol
|
417 |
+
$fileURL = $this->setPreferredProtocol(urldecode($optimizedUrl), true); //force recheck of the protocol
|
418 |
+
$tempFile = download_url($fileURL, $downloadTimeout);
|
419 |
+
}
|
420 |
+
|
421 |
+
//on success we return this
|
422 |
+
$returnMessage = array("Status" => self::STATUS_SUCCESS, "Message" => $tempFile, "WebP" => $webpTempFile);
|
423 |
+
|
424 |
+
if ( is_wp_error( $tempFile ) ) {
|
425 |
+
@unlink($tempFile);
|
426 |
+
@unlink($webpTempFile);
|
427 |
+
$returnMessage = array(
|
428 |
+
"Status" => self::STATUS_ERROR,
|
429 |
+
"Code" => self::ERR_DOWNLOAD,
|
430 |
+
"Message" => __('Error downloading file','shortpixel-image-optimiser') . " ({$optimizedUrl}) " . $tempFile->get_error_message());
|
431 |
+
}
|
432 |
+
//check response so that download is OK
|
433 |
+
elseif (!file_exists($tempFile)) {
|
434 |
+
$returnMessage = array("Status" => self::STATUS_ERROR,
|
435 |
+
"Code" => self::ERR_FILE_NOT_FOUND,
|
436 |
+
"Message" => __('Unable to locate downloaded file','shortpixel-image-optimiser') . " " . $tempFile);
|
437 |
+
}
|
438 |
+
elseif( filesize($tempFile) != $correctFileSize) {
|
439 |
+
$size = filesize($tempFile);
|
440 |
+
@unlink($tempFile);
|
441 |
+
@unlink($webpTempFile);
|
442 |
+
$returnMessage = array(
|
443 |
+
"Status" => self::STATUS_ERROR,
|
444 |
+
"Code" => self::ERR_INCORRECT_FILE_SIZE,
|
445 |
+
"Message" => sprintf(__('Error downloading file - incorrect file size (downloaded: %s, correct: %s )','shortpixel-image-optimiser'),$size, $correctFileSize));
|
446 |
+
}
|
447 |
+
return $returnMessage;
|
448 |
+
}
|
449 |
+
|
450 |
+
public static function backupImage($mainPath, $PATHs) {
|
451 |
+
//$fullSubDir = str_replace(wp_normalize_path(get_home_path()), "", wp_normalize_path(dirname($itemHandler->getMeta()->getPath()))) . '/';
|
452 |
+
//$SubDir = ShortPixelMetaFacade::returnSubDir($itemHandler->getMeta()->getPath(), $itemHandler->getType());
|
453 |
+
$fullSubDir = ShortPixelMetaFacade::returnSubDir($mainPath);
|
454 |
+
$source = $PATHs; //array with final paths for these files
|
455 |
+
|
456 |
+
if( !file_exists(SHORTPIXEL_BACKUP_FOLDER) && !@mkdir(SHORTPIXEL_BACKUP_FOLDER, 0777, true) ) {//creates backup folder if it doesn't exist
|
457 |
+
return array("Status" => self::STATUS_FAIL, "Message" => __('Backup folder does not exist and it cannot be created','shortpixel-image-optimiser'));
|
458 |
+
}
|
459 |
+
//create subdir in backup folder if needed
|
460 |
+
@mkdir( SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir, 0777, true);
|
461 |
+
|
462 |
+
foreach ( $source as $fileID => $filePATH )//create destination files array
|
463 |
+
{
|
464 |
+
$destination[$fileID] = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir . self::MB_basename($source[$fileID]);
|
465 |
+
}
|
466 |
+
//die("IZ BACKUP: " . SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir . var_dump($destination));
|
467 |
+
|
468 |
+
//now that we have original files and where we should back them up we attempt to do just that
|
469 |
+
if(is_writable(SHORTPIXEL_BACKUP_FOLDER))
|
470 |
+
{
|
471 |
+
foreach ( $destination as $fileID => $filePATH )
|
472 |
+
{
|
473 |
+
if ( !file_exists($filePATH) )
|
474 |
+
{
|
475 |
+
if ( !@copy($source[$fileID], $filePATH) )
|
476 |
+
{//file couldn't be saved in backup folder
|
477 |
+
$msg = sprintf(__('Cannot save file <i>%s</i> in backup directory','shortpixel-image-optimiser'),self::MB_basename($source[$fileID]));
|
478 |
+
return array("Status" => self::STATUS_FAIL, "Message" => $msg);
|
479 |
+
}
|
480 |
+
}
|
481 |
+
}
|
482 |
+
return array("Status" => self::STATUS_SUCCESS);
|
483 |
+
}
|
484 |
+
else {//cannot write to the backup dir, return with an error
|
485 |
+
$msg = __('Cannot save file in backup directory','shortpixel-image-optimiser');
|
486 |
+
return array("Status" => self::STATUS_FAIL, "Message" => $msg);
|
487 |
+
}
|
488 |
+
}
|
489 |
+
|
490 |
+
private function createArchiveTempFolder($archiveBasename) {
|
491 |
+
$archiveTempDir = get_temp_dir() . '/' . $archiveBasename;
|
492 |
+
if(file_exists($archiveTempDir) && is_dir($archiveTempDir) && (time() - filemtime($archiveTempDir) < max(30, SHORTPIXEL_MAX_EXECUTION_TIME) + 10)) {
|
493 |
+
WPShortPixel::log("CONFLICT. Folder already exists and is modified in the last minute. Current IP:" . $_SERVER['REMOTE_ADDR']);
|
494 |
+
return array("Status" => self::STATUS_RETRY, "Code" => 1, "Message" => "Pending");
|
495 |
+
}
|
496 |
+
if( !file_exists($archiveTempDir) && !@mkdir($archiveTempDir) ) {
|
497 |
+
return array("Status" => self::STATUS_ERROR, "Code" => self::ERR_SAVE, "Message" => "Could not create temporary folder.");
|
498 |
+
}
|
499 |
+
return array("Status" => self::STATUS_SUCCESS, "Dir" => $archiveTempDir);
|
500 |
+
}
|
501 |
+
|
502 |
+
private function downloadArchive($archive, $compressionType, $first = true) {
|
503 |
+
if($archive->ArchiveStatus->Code == 1 || $archive->ArchiveStatus->Code == 0) {
|
504 |
+
return array("Status" => self::STATUS_RETRY, "Code" => 1, "Message" => "Pending");
|
505 |
+
} elseif($archive->ArchiveStatus->Code == 2) {
|
506 |
+
|
507 |
+
$suffix = ($compressionType == 0 ? "-lossless" : "");
|
508 |
+
$archiveURL = "Archive" . ($compressionType == 0 ? "Lossless" : "") . "URL";
|
509 |
+
$archiveSize = "Archive" . ($compressionType == 0 ? "Lossless" : "") . "Size";
|
510 |
+
|
511 |
+
$archiveTemp = $this->createArchiveTempFolder(wp_basename($archive->$archiveURL, '.tar'));
|
512 |
+
if($archiveTemp["Status"] == self::STATUS_SUCCESS) { $archiveTempDir = $archiveTemp["Dir"]; }
|
513 |
+
else { return $archiveTemp; }
|
514 |
+
|
515 |
+
$downloadResult = $this->handleDownload($archive->$archiveURL, $archive->$archiveSize, 0, 'NA');
|
516 |
+
|
517 |
+
if ( $downloadResult['Status'] == self::STATUS_SUCCESS ) {
|
518 |
+
$archiveFile = $downloadResult['Message'];
|
519 |
+
if(filesize($archiveFile) !== $archive->$archiveSize) {
|
520 |
+
@unlink($archiveFile);
|
521 |
+
ShortpixelFolder::deleteFolder($archiveTempDir);
|
522 |
+
return array("Status" => self::STATUS_RETRY, "Code" => 1, "Message" => "Pending");
|
523 |
+
}
|
524 |
+
$pharData = new PharData($archiveFile);
|
525 |
+
try {
|
526 |
+
if (SHORTPIXEL_DEBUG === true) {
|
527 |
+
$info = "Current IP:" . $_SERVER['REMOTE_ADDR'] . "ARCHIVE CONTENTS: COUNT " . $pharData->count() . ", ";
|
528 |
+
foreach($pharData as $file) {
|
529 |
+
$info .= $file . ", ";
|
530 |
+
}
|
531 |
+
WPShortPixel::log($info);
|
532 |
+
}
|
533 |
+
$pharData->extractTo($archiveTempDir, null, true);
|
534 |
+
WPShortPixel::log("ARCHIVE EXTRACTED " . json_encode(scandir($archiveTempDir)));
|
535 |
+
@unlink($archiveFile);
|
536 |
+
} catch (Exception $ex) {
|
537 |
+
@unlink($archiveFile);
|
538 |
+
ShortpixelFolder::deleteFolder($archiveTempDir);
|
539 |
+
return array("Status" => self::STATUS_ERROR, "Code" => $ex->getCode(), "Message" => $ex->getMessage());
|
540 |
+
}
|
541 |
+
return array("Status" => self::STATUS_SUCCESS, "Code" => 2, "Message" => "Success", "Path" => $archiveTempDir);
|
542 |
+
|
543 |
+
} else {
|
544 |
+
WPShortPixel::log("ARCHIVE ERROR (" . $archive->$archiveURL . "): " . json_encode($downloadResult));
|
545 |
+
if($first && $downloadResult['Code'] == self::ERR_INCORRECT_FILE_SIZE) {
|
546 |
+
WPShortPixel::log("RETRYING AFTER ARCHIVE ERROR");
|
547 |
+
return $this->downloadArchive($archive, $compressionType, false); // try again, maybe the archive was flushing...
|
548 |
+
}
|
549 |
+
@rmdir($archiveTempDir); //in the case it was just created and it's empty...
|
550 |
+
return array("Status" => $downloadResult['Status'], "Code" => $downloadResult['Code'], "Message" => $downloadResult['Message']);
|
551 |
+
}
|
552 |
+
}
|
553 |
+
return false;
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* handles a successful optimization, setting metadata and handling download for each file in the set
|
558 |
+
* @param array $APIresponse - the response from the API - contains the optimized images URLs to download
|
559 |
+
* @param array $PATHs - list of local paths for the files
|
560 |
+
* @param ShortPixelMetaFacade $itemHandler - the Facade that manages different types of image metadatas: MediaLibrary (postmeta table), ShortPixel custom (shortpixel_meta table)
|
561 |
+
* @param int $compressionType - 1 - lossy, 2 - glossy, 0 - lossless
|
562 |
+
* @return array status/message
|
563 |
+
*/
|
564 |
+
private function handleSuccess($APIresponse, $PATHs, $itemHandler, $compressionType) {
|
565 |
+
WPShortPixel::log('Handling Success!');
|
566 |
+
|
567 |
+
$counter = $savedSpace = $originalSpace = $optimizedSpace /* = $averageCompression */ = 0;
|
568 |
+
$NoBackup = true;
|
569 |
+
|
570 |
+
if($compressionType) {
|
571 |
+
$fileType = "LossyURL";
|
572 |
+
$fileSize = "LossySize";
|
573 |
+
} else {
|
574 |
+
$fileType = "LosslessURL";
|
575 |
+
$fileSize = "LoselessSize";
|
576 |
+
}
|
577 |
+
$webpType = "WebP" . $fileType;
|
578 |
+
|
579 |
+
$archive = /*false &&*/
|
580 |
+
($this->_settings->downloadArchive == 7 && class_exists('PharData') && isset($APIresponse[count($APIresponse) - 1]->ArchiveStatus))
|
581 |
+
? $this->downloadArchive($APIresponse[count($APIresponse) - 1], $compressionType) : false;
|
582 |
+
if($archive !== false && $archive['Status'] !== self::STATUS_SUCCESS) {
|
583 |
+
return $archive;
|
584 |
+
}
|
585 |
+
|
586 |
+
//download each file from array and process it
|
587 |
+
foreach ( $APIresponse as $fileData )
|
588 |
+
{
|
589 |
+
if(!isset($fileData->Status)) continue; //if optimized images archive is activated, last entry of APIResponse if the Archive data.
|
590 |
+
|
591 |
+
if ( $fileData->Status->Code == 2 ) //file was processed OK
|
592 |
+
{
|
593 |
+
if ( $counter == 0 ) { //save percent improvement for main file
|
594 |
+
$percentImprovement = $fileData->PercentImprovement;
|
595 |
+
} else { //count thumbnails only
|
596 |
+
$this->_settings->thumbsCount = $this->_settings->thumbsCount + 1;
|
597 |
+
}
|
598 |
+
//TODO la sfarsit sa faca fallback la handleDownload
|
599 |
+
if($archive) {
|
600 |
+
$downloadResult = $this->fromArchive($archive['Path'], $fileData->$fileType, $fileData->$fileSize, $fileData->OriginalSize, isset($fileData->$webpType) ? $fileData->$webpType : 'NA');
|
601 |
+
} else {
|
602 |
+
$downloadResult = $this->handleDownload($fileData->$fileType, $fileData->$fileSize, $fileData->OriginalSize, isset($fileData->$webpType) ? $fileData->$webpType : 'NA');
|
603 |
+
}
|
604 |
+
|
605 |
+
$tempFiles[$counter] = $downloadResult;
|
606 |
+
if ( $downloadResult['Status'] == self::STATUS_SUCCESS ) {
|
607 |
+
//nothing to do
|
608 |
+
}
|
609 |
+
//when the status is STATUS_UNCHANGED we just skip the array line for that one
|
610 |
+
elseif( $downloadResult['Status'] == self::STATUS_UNCHANGED ) {
|
611 |
+
//this image is unchanged so won't be copied below, only the optimization stats need to be computed
|
612 |
+
$originalSpace += $fileData->OriginalSize;
|
613 |
+
$optimizedSpace += $fileData->$fileSize;
|
614 |
+
}
|
615 |
+
else {
|
616 |
+
self::cleanupTemporaryFiles($archive, $tempFiles);
|
617 |
+
return array("Status" => $downloadResult['Status'], "Code" => $downloadResult['Code'], "Message" => $downloadResult['Message']);
|
618 |
+
}
|
619 |
+
|
620 |
+
}
|
621 |
+
else { //there was an error while trying to download a file
|
622 |
+
$tempFiles[$counter] = "";
|
623 |
+
}
|
624 |
+
$counter++;
|
625 |
+
}
|
626 |
+
|
627 |
+
//figure out in what SubDir files should land
|
628 |
+
$mainPath = $itemHandler->getMeta()->getPath();
|
629 |
+
|
630 |
+
//if backup is enabled - we try to save the images
|
631 |
+
if( $this->_settings->backupImages )
|
632 |
+
{
|
633 |
+
$backupStatus = self::backupImage($mainPath, $PATHs);
|
634 |
+
if($backupStatus == self::STATUS_FAIL) {
|
635 |
+
$itemHandler->incrementRetries(1, self::ERR_SAVE_BKP, $backupStatus["Message"]);
|
636 |
+
self::cleanupTemporaryFiles($archive, empty($tempFiles) ? array() : $tempFiles);
|
637 |
+
return array("Status" => self::STATUS_FAIL, "Code" =>"backup-fail", "Message" => "Failed to back the image up.");
|
638 |
+
}
|
639 |
+
$NoBackup = false;
|
640 |
+
}//end backup section
|
641 |
+
|
642 |
+
$writeFailed = 0;
|
643 |
+
$width = $height = null;
|
644 |
+
$resize = $this->_settings->resizeImages;
|
645 |
+
$retinas = 0;
|
646 |
+
$thumbsOpt = 0;
|
647 |
+
$thumbsOptList = array();
|
648 |
+
|
649 |
+
if ( !empty($tempFiles) )
|
650 |
+
{
|
651 |
+
//overwrite the original files with the optimized ones
|
652 |
+
foreach ( $tempFiles as $tempFileID => $tempFile )
|
653 |
+
{
|
654 |
+
if(!is_array($tempFile)) continue;
|
655 |
+
|
656 |
+
$targetFile = $PATHs[$tempFileID];
|
657 |
+
$isRetina = ShortPixelMetaFacade::isRetina($targetFile);
|
658 |
+
|
659 |
+
if( ($tempFile['Status'] == self::STATUS_UNCHANGED || $tempFile['Status'] == self::STATUS_SUCCESS) && !$isRetina
|
660 |
+
&& $targetFile !== $mainPath) {
|
661 |
+
$thumbsOpt++;
|
662 |
+
$thumbsOptList[] = self::MB_basename($targetFile);
|
663 |
+
}
|
664 |
+
|
665 |
+
if($tempFile['Status'] == self::STATUS_SUCCESS) { //if it's unchanged it will still be in the array but only for WebP (handled below)
|
666 |
+
$tempFilePATH = $tempFile["Message"];
|
667 |
+
if ( file_exists($tempFilePATH) && file_exists($targetFile) && is_writable($targetFile) ) {
|
668 |
+
copy($tempFilePATH, $targetFile);
|
669 |
+
if(ShortPixelMetaFacade::isRetina($targetFile)) {
|
670 |
+
$retinas ++;
|
671 |
+
}
|
672 |
+
if($resize && $itemHandler->getMeta()->getPath() == $targetFile) { //this is the main image
|
673 |
+
$size = getimagesize($PATHs[$tempFileID]);
|
674 |
+
$width = $size[0];
|
675 |
+
$height = $size[1];
|
676 |
+
}
|
677 |
+
//Calculate the saved space
|
678 |
+
$fileData = $APIresponse[$tempFileID];
|
679 |
+
$savedSpace += $fileData->OriginalSize - $fileData->$fileSize;
|
680 |
+
$originalSpace += $fileData->OriginalSize;
|
681 |
+
$optimizedSpace += $fileData->$fileSize;
|
682 |
+
//$averageCompression += $fileData->PercentImprovement;
|
683 |
+
WPShortPixel::log("HANDLE SUCCESS: Image " . $PATHs[$tempFileID] . " original size: ".$fileData->OriginalSize . " optimized: " . $fileData->$fileSize);
|
684 |
+
|
685 |
+
//add the number of files with < 5% optimization
|
686 |
+
if ( ( ( 1 - $APIresponse[$tempFileID]->$fileSize/$APIresponse[$tempFileID]->OriginalSize ) * 100 ) < 5 ) {
|
687 |
+
$this->_settings->under5Percent++;
|
688 |
+
}
|
689 |
+
}
|
690 |
+
else {
|
691 |
+
if($archive && SHORTPIXEL_DEBUG === true) {
|
692 |
+
if(!file_exists($tempFilePATH)) {
|
693 |
+
WPShortPixel::log("MISSING FROM ARCHIVE. tempFilePath: $tempFilePATH with ID: $tempFileID");
|
694 |
+
} elseif(!file_exists($targetFile)){
|
695 |
+
WPShortPixel::log("MISSING TARGET: $targetFile");
|
696 |
+
} elseif(!is_writable($targetFile)){
|
697 |
+
WPShortPixel::log("TARGET NOT WRITABLE: $targetFile");
|
698 |
+
}
|
699 |
+
}
|
700 |
+
$writeFailed++;
|
701 |
+
}
|
702 |
+
@unlink($tempFilePATH);
|
703 |
+
}
|
704 |
+
|
705 |
+
$tempWebpFilePATH = $tempFile["WebP"];
|
706 |
+
if(file_exists($tempWebpFilePATH)) {
|
707 |
+
$targetWebPFileCompat = dirname($targetFile) . '/'. self::MB_basename($targetFile, '.' . pathinfo($targetFile, PATHINFO_EXTENSION)) . ".webp";
|
708 |
+
$targetWebPFile = dirname($targetFile) . '/' . self::MB_basename($targetFile) . ".webp";
|
709 |
+
//if the WebP fileCompat already exists, it means that there is another file with the same basename but different extension which has its .webP counterpart
|
710 |
+
//save it with double extension
|
711 |
+
if(file_exists($targetWebPFileCompat)) {
|
712 |
+
copy($targetWebPFile,$targetWebPFile);
|
713 |
+
} else {
|
714 |
+
copy($tempWebpFilePATH, $targetWebPFileCompat);
|
715 |
+
}
|
716 |
+
@unlink($tempWebpFilePATH);
|
717 |
+
}
|
718 |
+
}
|
719 |
+
self::cleanupTemporaryFiles($archive, $tempFiles);
|
720 |
+
|
721 |
+
if ( $writeFailed > 0 )//there was an error
|
722 |
+
{
|
723 |
+
if($archive && SHORTPIXEL_DEBUG === true) {
|
724 |
+
WPShortPixel::log("ARCHIVE HAS MISSING FILES. EXPECTED: " . json_encode($PATHs)
|
725 |
+
. " AND: " . json_encode($APIresponse)
|
726 |
+
. " GOT ARCHIVE: " . $APIresponse[count($APIresponse) - 1]->ArchiveURL . " LOSSLESS: " . $APIresponse[count($APIresponse) - 1]->ArchiveLosslessURL
|
727 |
+
. " CONTAINING: " . json_encode(scandir($archive['Path'])));
|
728 |
+
}
|
729 |
+
$msg = sprintf(__('Optimized version of %s file(s) couldn\'t be updated.','shortpixel-image-optimiser'),$writeFailed);
|
730 |
+
$itemHandler->incrementRetries(1, self::ERR_SAVE, $msg);
|
731 |
+
$this->_settings->bulkProcessingStatus = "error";
|
732 |
+
return array("Status" => self::STATUS_FAIL, "Code" =>"write-fail", "Message" => $msg);
|
733 |
+
}
|
734 |
+
} elseif( 0 + $fileData->PercentImprovement < 5) {
|
735 |
+
$this->_settings->under5Percent++;
|
736 |
+
}
|
737 |
+
//old average counting
|
738 |
+
$this->_settings->savedSpace += $savedSpace;
|
739 |
+
//$averageCompression = $this->_settings->averageCompression * $this->_settings->fileCount / ($this->_settings->fileCount + count($APIresponse));
|
740 |
+
//$this->_settings->averageCompression = $averageCompression;
|
741 |
+
$this->_settings->fileCount += count($APIresponse);
|
742 |
+
//new average counting
|
743 |
+
$this->_settings->totalOriginal += $originalSpace;
|
744 |
+
$this->_settings->totalOptimized += $optimizedSpace;
|
745 |
+
|
746 |
+
//update metadata for this file
|
747 |
+
$meta = $itemHandler->getMeta();
|
748 |
+
// die(var_dump($percentImprovement));
|
749 |
+
if($meta->getThumbsTodo()) {
|
750 |
+
$percentImprovement = $meta->getImprovementPercent();
|
751 |
+
}
|
752 |
+
$png2jpg = $meta->getPng2Jpg();
|
753 |
+
$png2jpg = is_array($png2jpg) ? $png2jpg['optimizationPercent'] : 0;
|
754 |
+
$meta->setMessage($originalSpace
|
755 |
+
? number_format(100.0 * (1.0 - $optimizedSpace / $originalSpace), 2)
|
756 |
+
: "Couldn't compute thumbs optimization percent. Main image: " . $percentImprovement);
|
757 |
+
WPShortPixel::log("HANDLE SUCCESS: Image optimization: ".$meta->getMessage());
|
758 |
+
$meta->setCompressionType($compressionType);
|
759 |
+
$meta->setCompressedSize(@filesize($meta->getPath()));
|
760 |
+
$meta->setKeepExif($this->_settings->keepExif);
|
761 |
+
$meta->setTsOptimized(date("Y-m-d H:i:s"));
|
762 |
+
$meta->setThumbsOptList(is_array($meta->getThumbsOptList()) ? array_unique(array_merge($meta->getThumbsOptList(), $thumbsOptList)) : $thumbsOptList);
|
763 |
+
$meta->setThumbsOpt(($meta->getThumbsTodo() || $this->_settings->processThumbnails) ? count($meta->getThumbsOptList()) : 0);
|
764 |
+
$meta->setRetinasOpt($retinas);
|
765 |
+
if(null !== $this->_settings->excludeSizes) {
|
766 |
+
$meta->setExcludeSizes($this->_settings->excludeSizes);
|
767 |
+
}
|
768 |
+
$meta->setThumbsTodo(false);
|
769 |
+
//* Not yet as it doesn't seem to work... */$meta->addThumbs($webpSizes);
|
770 |
+
if($width && $height) {
|
771 |
+
$meta->setActualWidth($width);
|
772 |
+
$meta->setActualHeight($height);
|
773 |
+
}
|
774 |
+
$meta->setRetries($meta->getRetries() + 1);
|
775 |
+
$meta->setBackup(!$NoBackup);
|
776 |
+
$meta->setStatus(2);
|
777 |
+
|
778 |
+
$itemHandler->updateMeta($meta);
|
779 |
+
$itemHandler->optimizationSucceeded();
|
780 |
+
WPShortPixel::log("HANDLE SUCCESS: Metadata saved.");
|
781 |
+
|
782 |
+
if(!$originalSpace) { //das kann nicht sein, alles klar?!
|
783 |
+
throw new Exception("OriginalSpace = 0. APIResponse" . json_encode($APIresponse));
|
784 |
+
}
|
785 |
+
|
786 |
+
//we reset the retry counter in case of success
|
787 |
+
$this->_settings->apiRetries = 0;
|
788 |
+
|
789 |
+
return array("Status" => self::STATUS_SUCCESS, "Message" => 'Success: No pixels remained unsqueezed :-)',
|
790 |
+
"PercentImprovement" => $originalSpace
|
791 |
+
? number_format(100.0 * (1.0 - (1.0 - $png2jpg / 100.0) * $optimizedSpace / $originalSpace), 2)
|
792 |
+
: "Couldn't compute thumbs optimization percent. Main image: " . $percentImprovement);
|
793 |
+
}//end handleSuccess
|
794 |
+
|
795 |
+
/**
|
796 |
+
* @param $archive
|
797 |
+
* @param $tempFiles
|
798 |
+
*/
|
799 |
+
protected static function cleanupTemporaryFiles($archive, $tempFiles)
|
800 |
+
{
|
801 |
+
if ($archive) {
|
802 |
+
ShortpixelFolder::deleteFolder($archive['Path']);
|
803 |
+
} else {
|
804 |
+
if (!empty($tempFiles) && is_array($tempFiles)) {
|
805 |
+
foreach ($tempFiles as $tmpFile) {
|
806 |
+
@unlink($tmpFile["Message"]);
|
807 |
+
}
|
808 |
+
}
|
809 |
+
}
|
810 |
+
}
|
811 |
+
|
812 |
+
/**
|
813 |
+
* a basename alternative that deals OK with multibyte charsets (e.g. Arabic)
|
814 |
+
* @param string $Path
|
815 |
+
* @return string
|
816 |
+
*/
|
817 |
+
static public function MB_basename($Path, $suffix = false){
|
818 |
+
$Separator = " qq ";
|
819 |
+
$qqPath = preg_replace("/[^ ]/u", $Separator."\$0".$Separator, $Path);
|
820 |
+
if(!$qqPath) { //this is not an UTF8 string!! Don't rely on basename either, since if filename starts with a non-ASCII character it strips it off
|
821 |
+
$fileName = end(explode(DIRECTORY_SEPARATOR, $Path));
|
822 |
+
$pos = strpos($fileName, $suffix);
|
823 |
+
if($pos !== false) {
|
824 |
+
return substr($fileName, 0, $pos);
|
825 |
+
}
|
826 |
+
return $fileName;
|
827 |
+
}
|
828 |
+
$suffix = preg_replace("/[^ ]/u", $Separator."\$0".$Separator, $suffix);
|
829 |
+
$Base = basename($qqPath, $suffix);
|
830 |
+
$Base = str_replace($Separator, "", $Base);
|
831 |
+
return $Base;
|
832 |
+
}
|
833 |
+
|
834 |
+
/**
|
835 |
+
* sometimes, the paths to the files as defined in metadata are wrong, we try to automatically correct them
|
836 |
+
* @param array $PATHs
|
837 |
+
* @return boolean|string
|
838 |
+
*/
|
839 |
+
static public function CheckAndFixImagePaths($PATHs){
|
840 |
+
|
841 |
+
$ErrorCount = 0;
|
842 |
+
$Tmp = explode("/", SHORTPIXEL_UPLOADS_BASE);
|
843 |
+
$TmpCount = count($Tmp);
|
844 |
+
$StichString = $Tmp[$TmpCount-2] . "/" . $Tmp[$TmpCount-1];
|
845 |
+
//files exist on disk?
|
846 |
+
$missingFiles = array();
|
847 |
+
foreach ( $PATHs as $Id => $File )
|
848 |
+
{
|
849 |
+
//we try again with a different path
|
850 |
+
if ( !file_exists($File) ){
|
851 |
+
//$NewFile = $uploadDir['basedir'] . "/" . substr($File,strpos($File, $StichString));//+strlen($StichString));
|
852 |
+
$NewFile = SHORTPIXEL_UPLOADS_BASE . substr($File,strpos($File, $StichString)+strlen($StichString));
|
853 |
+
if (file_exists($NewFile)) {
|
854 |
+
$PATHs[$Id] = $NewFile;
|
855 |
+
} else {
|
856 |
+
$NewFile = SHORTPIXEL_UPLOADS_BASE . "/" . $File;
|
857 |
+
if (file_exists($NewFile)) {
|
858 |
+
$PATHs[$Id] = $NewFile;
|
859 |
+
} else {
|
860 |
+
$missingFiles[] = $File;
|
861 |
+
$ErrorCount++;
|
862 |
+
}
|
863 |
+
}
|
864 |
+
}
|
865 |
+
}
|
866 |
+
|
867 |
+
if ( $ErrorCount > 0 ) {
|
868 |
+
return array("error" => $missingFiles);//false;
|
869 |
+
} else {
|
870 |
+
return $PATHs;
|
871 |
+
}
|
872 |
+
}
|
873 |
+
|
874 |
+
static public function getCompressionTypeName($compressionType) {
|
875 |
+
if(is_array($compressionType)) {
|
876 |
+
return array_map(array('ShortPixelAPI', 'getCompressionTypeName'), $compressionType);
|
877 |
+
}
|
878 |
+
return 0 + $compressionType == 2 ? 'glossy' : (0 + $compressionType == 1 ? 'lossy' : 'lossless');
|
879 |
+
}
|
880 |
+
|
881 |
+
static public function getCompressionTypeCode($compressionName) {
|
882 |
+
return $compressionName == 'glossy' ? 2 : ($compressionName == 'lossy' ? 1 : 0);
|
883 |
+
}
|
884 |
+
}
|
@@ -29,8 +29,11 @@ require_once('class/view/shortpixel_view.php');
|
|
29 |
Â
|
30 |
Â
require_once('class/shortpixel-tools.php');
|
31 |
Â
|
Â
|
|
Â
|
|
Â
|
|
32 |
Â
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
33 |
-
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
34 |
Â
|
35 |
Â
// for retro compatibility with WP < 3.5
|
36 |
Â
if( !function_exists('wp_normalize_path') ){
|
@@ -41,15 +44,13 @@ if( !function_exists('wp_normalize_path') ){
|
|
41 |
Â
$path = ucfirst( $path );
|
42 |
Â
}
|
43 |
Â
return $path;
|
44 |
-
}
|
45 |
Â
}
|
46 |
Â
|
47 |
Â
/*
|
48 |
Â
if ( !is_plugin_active( 'wpmandrill/wpmandrill.php' ) //avoid conflicts with some plugins
|
49 |
-
&& !is_plugin_active( 'wp-ses/wp-ses.php' )
|
50 |
Â
&& !is_plugin_active( 'wordfence/wordfence.php') ) {
|
51 |
Â
require_once( ABSPATH . 'wp-includes/pluggable.php' );
|
52 |
-
}
|
53 |
Â
*/
|
54 |
-
|
55 |
-
|
29 |
Â
|
30 |
Â
require_once('class/shortpixel-tools.php');
|
31 |
Â
|
32 |
+
require_once('class/controller/controller.php');
|
33 |
+
require_once('class/controller/bulk-restore-all.php');
|
34 |
+
|
35 |
Â
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
36 |
+
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
37 |
Â
|
38 |
Â
// for retro compatibility with WP < 3.5
|
39 |
Â
if( !function_exists('wp_normalize_path') ){
|
44 |
Â
$path = ucfirst( $path );
|
45 |
Â
}
|
46 |
Â
return $path;
|
47 |
+
}
|
48 |
Â
}
|
49 |
Â
|
50 |
Â
/*
|
51 |
Â
if ( !is_plugin_active( 'wpmandrill/wpmandrill.php' ) //avoid conflicts with some plugins
|
52 |
+
&& !is_plugin_active( 'wp-ses/wp-ses.php' )
|
53 |
Â
&& !is_plugin_active( 'wordfence/wordfence.php') ) {
|
54 |
Â
require_once( ABSPATH . 'wp-includes/pluggable.php' );
|
55 |
+
}
|
56 |
Â
*/
|
Â
|
|
Â
|
@@ -1,238 +1,245 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
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 > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
-
* Version: 4.
|
7 |
-
* Author: ShortPixel
|
8 |
-
* Author URI: https://shortpixel.com
|
9 |
-
* Text Domain: shortpixel-image-optimiser
|
10 |
-
* Domain Path: /lang
|
11 |
-
*/
|
12 |
-
|
13 |
-
define('SHORTPIXEL_RESET_ON_ACTIVATE', false); //if true TODO set false
|
14 |
-
//define('SHORTPIXEL_DEBUG', true);
|
15 |
-
//define('SHORTPIXEL_DEBUG_TARGET', true);
|
16 |
-
|
17 |
-
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
18 |
-
|
19 |
-
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
20 |
-
|
21 |
-
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.
|
22 |
-
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
23 |
-
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
24 |
-
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
25 |
-
define('SHORTPIXEL_MAX_API_RETRIES', 50);
|
26 |
-
define('SHORTPIXEL_MAX_ERR_RETRIES', 5);
|
27 |
-
define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);
|
28 |
-
if(!defined('SHORTPIXEL_MAX_THUMBS')) { //can be defined in wp-config.php
|
29 |
-
define('SHORTPIXEL_MAX_THUMBS', 149);
|
30 |
-
}
|
31 |
-
|
32 |
-
define('SHORTPIXEL_PRESEND_ITEMS', 3);
|
33 |
-
define('SHORTPIXEL_API', 'api.shortpixel.com');
|
34 |
-
|
35 |
-
define('SHORTPIXEL_MAX_EXECUTION_TIME', ini_get('max_execution_time'));
|
36 |
-
|
37 |
-
require_once(ABSPATH . 'wp-admin/includes/file.php');
|
38 |
-
|
39 |
-
$sp__uploads = wp_upload_dir();
|
40 |
-
define('SHORTPIXEL_UPLOADS_BASE', (file_exists($sp__uploads['basedir']) ? '' : ABSPATH) . $sp__uploads['basedir'] );
|
41 |
-
//define('SHORTPIXEL_UPLOADS_URL', is_main_site() ? $sp__uploads['baseurl'] : dirname(dirname($sp__uploads['baseurl'])));
|
42 |
-
define('SHORTPIXEL_UPLOADS_NAME', basename(is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE))));
|
43 |
-
$sp__backupBase = is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE));
|
44 |
-
define('SHORTPIXEL_BACKUP_FOLDER', $sp__backupBase . '/' . SHORTPIXEL_BACKUP);
|
45 |
-
define('SHORTPIXEL_BACKUP_URL',
|
46 |
-
((is_main_site() || (defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL))
|
47 |
-
? $sp__uploads['baseurl']
|
48 |
-
: dirname(dirname($sp__uploads['baseurl'])))
|
49 |
-
. '/' . SHORTPIXEL_BACKUP);
|
50 |
-
|
51 |
-
/*
|
52 |
-
if ( is_numeric(SHORTPIXEL_MAX_EXECUTION_TIME) && SHORTPIXEL_MAX_EXECUTION_TIME > 10 )
|
53 |
-
define('SHORTPIXEL_MAX_EXECUTION_TIME', SHORTPIXEL_MAX_EXECUTION_TIME - 5 ); //in seconds
|
54 |
-
else
|
55 |
-
define('SHORTPIXEL_MAX_EXECUTION_TIME', 25 );
|
56 |
-
*/
|
57 |
-
|
58 |
-
define('SHORTPIXEL_MAX_EXECUTION_TIME2', 2 );
|
59 |
-
define("SHORTPIXEL_MAX_RESULTS_QUERY", 30);
|
60 |
-
|
61 |
-
function shortpixelInit() {
|
62 |
-
global $shortPixelPluginInstance;
|
63 |
-
//limit to certain admin pages if function available
|
64 |
-
$loadOnThisPage = !function_exists('get_current_screen');
|
65 |
-
if(!$loadOnThisPage) {
|
66 |
-
$screen = get_current_screen();
|
67 |
-
if(is_object($screen) && !in_array($screen->id, array('upload', 'edit', 'edit-tags', 'post-new', 'post'))) {
|
68 |
-
return;
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
$
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
$shortPixelPluginInstance
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
}
|
139 |
-
|
140 |
-
function
|
141 |
-
require_once('wp-shortpixel-req.php');
|
142 |
-
WPShortPixel::
|
143 |
-
}
|
144 |
-
|
145 |
-
function
|
146 |
-
require_once('wp-shortpixel-req.php');
|
147 |
-
WPShortPixel::
|
148 |
-
}
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
$
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
}
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/**
|
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 > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
+
* Version: 4.13.0
|
7 |
+
* Author: ShortPixel
|
8 |
+
* Author URI: https://shortpixel.com
|
9 |
+
* Text Domain: shortpixel-image-optimiser
|
10 |
+
* Domain Path: /lang
|
11 |
+
*/
|
12 |
+
|
13 |
+
define('SHORTPIXEL_RESET_ON_ACTIVATE', false); //if true TODO set false
|
14 |
+
//define('SHORTPIXEL_DEBUG', true);
|
15 |
+
//define('SHORTPIXEL_DEBUG_TARGET', true);
|
16 |
+
|
17 |
+
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
18 |
+
|
19 |
+
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
20 |
+
|
21 |
+
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.13.0");
|
22 |
+
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
23 |
+
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
24 |
+
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
25 |
+
define('SHORTPIXEL_MAX_API_RETRIES', 50);
|
26 |
+
define('SHORTPIXEL_MAX_ERR_RETRIES', 5);
|
27 |
+
define('SHORTPIXEL_MAX_FAIL_RETRIES', 3);
|
28 |
+
if(!defined('SHORTPIXEL_MAX_THUMBS')) { //can be defined in wp-config.php
|
29 |
+
define('SHORTPIXEL_MAX_THUMBS', 149);
|
30 |
+
}
|
31 |
+
|
32 |
+
define('SHORTPIXEL_PRESEND_ITEMS', 3);
|
33 |
+
define('SHORTPIXEL_API', 'api.shortpixel.com');
|
34 |
+
|
35 |
+
define('SHORTPIXEL_MAX_EXECUTION_TIME', ini_get('max_execution_time'));
|
36 |
+
|
37 |
+
require_once(ABSPATH . 'wp-admin/includes/file.php');
|
38 |
+
|
39 |
+
$sp__uploads = wp_upload_dir();
|
40 |
+
define('SHORTPIXEL_UPLOADS_BASE', (file_exists($sp__uploads['basedir']) ? '' : ABSPATH) . $sp__uploads['basedir'] );
|
41 |
+
//define('SHORTPIXEL_UPLOADS_URL', is_main_site() ? $sp__uploads['baseurl'] : dirname(dirname($sp__uploads['baseurl'])));
|
42 |
+
define('SHORTPIXEL_UPLOADS_NAME', basename(is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE))));
|
43 |
+
$sp__backupBase = is_main_site() ? SHORTPIXEL_UPLOADS_BASE : dirname(dirname(SHORTPIXEL_UPLOADS_BASE));
|
44 |
+
define('SHORTPIXEL_BACKUP_FOLDER', $sp__backupBase . '/' . SHORTPIXEL_BACKUP);
|
45 |
+
define('SHORTPIXEL_BACKUP_URL',
|
46 |
+
((is_main_site() || (defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL))
|
47 |
+
? $sp__uploads['baseurl']
|
48 |
+
: dirname(dirname($sp__uploads['baseurl'])))
|
49 |
+
. '/' . SHORTPIXEL_BACKUP);
|
50 |
+
|
51 |
+
/*
|
52 |
+
if ( is_numeric(SHORTPIXEL_MAX_EXECUTION_TIME) && SHORTPIXEL_MAX_EXECUTION_TIME > 10 )
|
53 |
+
define('SHORTPIXEL_MAX_EXECUTION_TIME', SHORTPIXEL_MAX_EXECUTION_TIME - 5 ); //in seconds
|
54 |
+
else
|
55 |
+
define('SHORTPIXEL_MAX_EXECUTION_TIME', 25 );
|
56 |
+
*/
|
57 |
+
|
58 |
+
define('SHORTPIXEL_MAX_EXECUTION_TIME2', 2 );
|
59 |
+
define("SHORTPIXEL_MAX_RESULTS_QUERY", 30);
|
60 |
+
|
61 |
+
function shortpixelInit() {
|
62 |
+
global $shortPixelPluginInstance;
|
63 |
+
//limit to certain admin pages if function available
|
64 |
+
$loadOnThisPage = !function_exists('get_current_screen');
|
65 |
+
if(!$loadOnThisPage) {
|
66 |
+
$screen = get_current_screen();
|
67 |
+
if(is_object($screen) && !in_array($screen->id, array('upload', 'edit', 'edit-tags', 'post-new', 'post'))) {
|
68 |
+
return;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
$isAjaxButNotSP = false; //defined( 'DOING_AJAX' ) && DOING_AJAX && !(isset($_REQUEST['action']) && (strpos($_REQUEST['action'], 'shortpixel_') === 0));
|
72 |
+
if (!isset($shortPixelPluginInstance)
|
73 |
+
&& ( (shortPixelCheckQueue() && get_option('wp-short-pixel-front-bootstrap'))
|
74 |
+
|| is_admin() && !$isAjaxButNotSP
|
75 |
+
&& (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.
|
76 |
+
&& ( current_user_can( 'manage_options' )
|
77 |
+
|| current_user_can( 'upload_files' )
|
78 |
+
|| current_user_can( 'edit_posts' )
|
79 |
+
)
|
80 |
+
)
|
81 |
+
)
|
82 |
+
{
|
83 |
+
require_once('wp-shortpixel-req.php');
|
84 |
+
$shortPixelPluginInstance = new WPShortPixel;
|
85 |
+
}
|
86 |
+
|
87 |
+
}
|
88 |
+
|
89 |
+
function shortPixelCheckQueue(){
|
90 |
+
require_once('class/shortpixel_queue.php');
|
91 |
+
$prio = ShortPixelQueue::get();
|
92 |
+
return $prio && is_array($prio) && count($prio);
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* this is hooked into wp_generate_attachment_metadata
|
97 |
+
* @param $meta
|
98 |
+
* @param null $ID
|
99 |
+
* @return WPShortPixel the instance
|
100 |
+
*/
|
101 |
+
function shortPixelHandleImageUploadHook($meta, $ID = null) {
|
102 |
+
global $shortPixelPluginInstance;
|
103 |
+
if(!isset($shortPixelPluginInstance)) {
|
104 |
+
require_once('wp-shortpixel-req.php');
|
105 |
+
$shortPixelPluginInstance = new WPShortPixel;
|
106 |
+
}
|
107 |
+
return $shortPixelPluginInstance->handleMediaLibraryImageUpload($meta, $ID);
|
108 |
+
}
|
109 |
+
|
110 |
+
function shortPixelReplaceHook($params) {
|
111 |
+
if(isset($params['post_id'])) { //integration with EnableMediaReplace - that's an upload for replacing an existing ID
|
112 |
+
global $shortPixelPluginInstance;
|
113 |
+
if (!isset($shortPixelPluginInstance)) {
|
114 |
+
require_once('wp-shortpixel-req.php');
|
115 |
+
$shortPixelPluginInstance = new WPShortPixel;
|
116 |
+
}
|
117 |
+
$itemHandler = $shortPixelPluginInstance->onDeleteImage($params['post_id']);
|
118 |
+
$itemHandler->deleteAllSPMeta();
|
119 |
+
}
|
120 |
+
}
|
121 |
+
|
122 |
+
function shortPixelPng2JpgHook($params) {
|
123 |
+
global $shortPixelPluginInstance;
|
124 |
+
if(!isset($shortPixelPluginInstance)) {
|
125 |
+
require_once('wp-shortpixel-req.php');
|
126 |
+
$shortPixelPluginInstance = new WPShortPixel;
|
127 |
+
}
|
128 |
+
return $shortPixelPluginInstance->convertPng2Jpg($params);
|
129 |
+
}
|
130 |
+
|
131 |
+
function shortPixelNggAdd($image) {
|
132 |
+
global $shortPixelPluginInstance;
|
133 |
+
if(!isset($shortPixelPluginInstance)) {
|
134 |
+
require_once('wp-shortpixel-req.php');
|
135 |
+
$shortPixelPluginInstance = new WPShortPixel;
|
136 |
+
}
|
137 |
+
$shortPixelPluginInstance->handleNextGenImageUpload($image);
|
138 |
+
}
|
139 |
+
|
140 |
+
function shortPixelActivatePlugin () {
|
141 |
+
require_once('wp-shortpixel-req.php');
|
142 |
+
WPShortPixel::shortPixelActivatePlugin();
|
143 |
+
}
|
144 |
+
|
145 |
+
function shortPixelDeactivatePlugin () {
|
146 |
+
require_once('wp-shortpixel-req.php');
|
147 |
+
WPShortPixel::shortPixelDeactivatePlugin();
|
148 |
+
}
|
149 |
+
|
150 |
+
function shortPixelUninstallPlugin () {
|
151 |
+
require_once('wp-shortpixel-req.php');
|
152 |
+
WPShortPixel::shortPixelUninstallPlugin();
|
153 |
+
}
|
154 |
+
|
155 |
+
//Picture generation, hooked on the_content filter
|
156 |
+
function shortPixelConvertImgToPictureAddWebp($content) {
|
157 |
+
if(function_exists('is_amp_endpoint') && is_amp_endpoint()) {
|
158 |
+
//for AMP pages the <picture> tag is not allowed
|
159 |
+
return $content . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG is AMP -->' : '');
|
160 |
+
}
|
161 |
+
require_once('class/front/img-to-picture-webp.php');
|
162 |
+
return ShortPixelImgToPictureWebp::convert($content);// . "<!-- PICTURE TAGS BY SHORTPIXEL -->";
|
163 |
+
}
|
164 |
+
function shortPixelAddPictureJs() {
|
165 |
+
// Don't do anything with the RSS feed.
|
166 |
+
if ( is_feed() || is_admin() ) { return; }
|
167 |
+
|
168 |
+
echo '<script>'
|
169 |
+
. 'var spPicTest = document.createElement( "picture" );'
|
170 |
+
. 'if(!window.HTMLPictureElement && document.addEventListener) {'
|
171 |
+
. 'window.addEventListener("DOMContentLoaded", function() {'
|
172 |
+
. 'var scriptTag = document.createElement("script");'
|
173 |
+
. 'scriptTag.src = "' . plugins_url('/res/js/picturefill.min.js', __FILE__) . '";'
|
174 |
+
. 'document.body.appendChild(scriptTag);'
|
175 |
+
. '});'
|
176 |
+
. '}'
|
177 |
+
. '</script>';
|
178 |
+
}
|
179 |
+
|
180 |
+
add_filter( 'gform_save_field_value', 'shortPixelGravityForms', 10, 5 );
|
181 |
+
|
182 |
+
function shortPixelGravityForms( $value, $lead, $field, $form ) {
|
183 |
+
global $shortPixelPluginInstance;
|
184 |
+
if($field->type == 'post_image') {
|
185 |
+
require_once('wp-shortpixel-req.php');
|
186 |
+
$shortPixelPluginInstance = new WPShortPixel;
|
187 |
+
$shortPixelPluginInstance->handleGravityFormsImageField($value);
|
188 |
+
}
|
189 |
+
return $value;
|
190 |
+
}
|
191 |
+
|
192 |
+
function shortPixelInitOB() {
|
193 |
+
if(!is_admin() || (function_exists("wp_doing_ajax") && wp_doing_ajax()) || (defined( 'DOING_AJAX' ) && DOING_AJAX)) {
|
194 |
+
ob_start('shortPixelConvertImgToPictureAddWebp');
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
function shortPixelIsPluginActive($plugin) {
|
199 |
+
$activePlugins = apply_filters( 'active_plugins', get_option( 'active_plugins', array()));
|
200 |
+
if ( is_multisite() ) {
|
201 |
+
$activePlugins = array_merge($activePlugins, get_site_option( 'active_sitewide_plugins'));
|
202 |
+
}
|
203 |
+
return in_array( $plugin, $activePlugins);
|
204 |
+
}
|
205 |
+
|
206 |
+
// [BS] Start runtime here
|
207 |
+
$option = get_option('wp-short-pixel-create-webp-markup');
|
208 |
+
if ( $option ) {
|
209 |
+
if(shortPixelIsPluginActive('shortpixel-adaptive-images/short-pixel-ai.php')) {
|
210 |
+
set_transient("shortpixel_thrown_notice", array('when' => 'spai', 'extra' => __('Please deactivate the ShortPixel Image Optimizer\'s
|
211 |
+
<a href="options-general.php?page=wp-shortpixel#adv-settings">Deliver WebP using PICTURE tag</a>
|
212 |
+
option when the ShortPixel Adaptive Images plugin is active.','shortpixel-image-optimiser')), 1800);
|
213 |
+
}
|
214 |
+
elseif( $option == 1 ){
|
215 |
+
add_action( 'wp_head', 'shortPixelAddPictureJs'); // adds polyfill JS to the header
|
216 |
+
add_action( 'init', 'shortPixelInitOB', 1 ); // start output buffer to capture content
|
217 |
+
} elseif ($option == 2){
|
218 |
+
add_filter( 'the_content', 'shortPixelConvertImgToPictureAddWebp', 10000 ); // priority big, so it will be executed last
|
219 |
+
add_filter( 'the_excerpt', 'shortPixelConvertImgToPictureAddWebp', 10000 );
|
220 |
+
add_filter( 'post_thumbnail_html', 'shortPixelConvertImgToPictureAddWebp');
|
221 |
+
}
|
222 |
+
// add_action( 'wp_enqueue_scripts', 'spAddPicturefillJs' );
|
223 |
+
}
|
224 |
+
|
225 |
+
if ( !function_exists( 'vc_action' ) || vc_action() !== 'vc_inline' ) { //handle incompatibility with Visual Composer
|
226 |
+
add_action( 'init', 'shortpixelInit');
|
227 |
+
add_action('ngg_added_new_image', 'shortPixelNggAdd');
|
228 |
+
|
229 |
+
$autoPng2Jpg = get_option('wp-short-pixel-png2jpg');
|
230 |
+
$autoMediaLibrary = get_option('wp-short-pixel-auto-media-library');
|
231 |
+
if($autoPng2Jpg && $autoMediaLibrary) {
|
232 |
+
add_action( 'wp_handle_upload', 'shortPixelPng2JpgHook');
|
233 |
+
add_action( 'mpp_handle_upload', 'shortPixelPng2JpgHook');
|
234 |
+
}
|
235 |
+
add_action('wp_handle_replace', 'shortPixelReplaceHook');
|
236 |
+
if($autoMediaLibrary) {
|
237 |
+
add_filter( 'wp_generate_attachment_metadata', 'shortPixelHandleImageUploadHook', 10, 2 );
|
238 |
+
add_filter( 'mpp_generate_metadata', 'shortPixelHandleImageUploadHook', 10, 2 );
|
239 |
+
}
|
240 |
+
|
241 |
+
register_activation_hook( __FILE__, 'shortPixelActivatePlugin' );
|
242 |
+
register_deactivation_hook( __FILE__, 'shortPixelDeactivatePlugin' );
|
243 |
+
register_uninstall_hook(__FILE__, 'shortPixelUninstallPlugin');
|
244 |
+
}
|
245 |
+
?>
|