Version Description
=
Release date: 22nd July 2019 * Compatibility with Flywheel hosting by not using flock if Flywheel detected * When using the PICTURE tag to deliver WebP, keep the width and height at level * Refactoring of the API Key settings page, refactoring of Other media * Performance improvements for selecting from large wp_posts and wp_postmeta tables when doing bulk optimization * Display a message when bulk is skipping many processed images, if bulk processing is ran again. * Fixed: Other media - Recompress adds "Preserve CMYK" * Fixed: duplicate error message when validating wrong API key * Conflict message: align the text vertically and provide space between text and button when displayed on any admin page * Fixed: Other media Restore fails when original file is readable, not writable
=
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 4.14.3 |
Comparing to | |
See all releases |
Code changes from version 4.14.2 to 4.14.3
- build/shortpixel/PackageLoader.php +73 -0
- build/shortpixel/autoload.php +5 -0
- build/shortpixel/composer.json +1 -0
- build/shortpixel/log/composer.json +18 -0
- build/shortpixel/log/src/DebugItem.php +141 -0
- build/shortpixel/log/src/ShortPixelLogger.php +322 -0
- build/shortpixel/log/src/view-debug-box.php +57 -0
- build/shortpixel/notices/composer.json +31 -0
- build/shortpixel/notices/src/NoticeController.php +194 -0
- build/shortpixel/notices/src/NoticeModel.php +116 -0
- build/shortpixel/notices/src/css/notices.css +21 -0
- build/shortpixel/notices/src/css/notices.min.css +1 -0
- build/shortpixel/notices/src/css/notices.scss +39 -0
- class/controller/apikey_controller.php +30 -0
- class/controller/bulk-restore-all.php +0 -1
- class/controller/controller.php +23 -7
- class/controller/filesystem_controller.php +66 -0
- class/controller/settings.php +89 -90
- class/db/shortpixel-custom-meta-dao.php +4 -1
- class/db/shortpixel-meta-facade.php +74 -71
- class/db/wp-shortpixel-media-library-adapter.php +59 -2
- class/external/flywheel.php +27 -0
- class/external/helpscout.php +39 -2
- class/external/nextgen.php +1 -1
- class/external/shortpixel_queue_db.php +330 -0
- class/front/img-to-picture-webp.php +20 -7
- class/model/apikey_model.php +294 -0
- class/model/directory_model.php +93 -0
- class/model/environment_model.php +32 -0
- class/model/file_model.php +183 -0
- class/shortpixel-model.php +1 -3
- class/shortpixel_queue.php +8 -5
- class/view/settings/part-general.php +3 -3
- class/view/settings/part-nokey.php +10 -7
- class/view/settings/part-statistics.php +9 -1
- class/view/shortpixel-list-table.php +9 -4
- class/view/shortpixel_view.php +26 -17
- class/view/view-restore-all.php +1 -1
- class/view/view-settings.php +3 -2
- class/wp-short-pixel.php +256 -409
- class/wp-shortpixel-settings.php +4 -2
- readme.txt +35 -19
- res/css/short-pixel-bar.css +22 -0
- res/css/short-pixel-bar.min.css +1 -1
- res/css/short-pixel.css +0 -20
- res/css/short-pixel.min.css +1 -1
- res/css/shortpixel-admin.min.css +1 -1
- res/js/jquery.tooltip.js +43 -38
- res/js/jquery.tooltip.min.js +1 -1
- res/js/shortpixel.js +38 -3
- res/js/shortpixel.min.js +1 -1
- shortpixel-plugin.php +27 -9
- shortpixel_api.php +7 -3
- wp-shortpixel-req.php +4 -4
- wp-shortpixel.php +24 -5
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel\Build;
|
3 |
+
|
4 |
+
class PackageLoader
|
5 |
+
{
|
6 |
+
public $dir;
|
7 |
+
|
8 |
+
public function getComposerFile()
|
9 |
+
{
|
10 |
+
return json_decode(file_get_contents($this->dir."/composer.json"), 1);
|
11 |
+
}
|
12 |
+
|
13 |
+
public function load($dir)
|
14 |
+
{
|
15 |
+
$this->dir = $dir;
|
16 |
+
$composer = $this->getComposerFile();
|
17 |
+
if(isset($composer["autoload"]["psr-4"])){
|
18 |
+
$this->loadPSR4($composer['autoload']['psr-4']);
|
19 |
+
}
|
20 |
+
if(isset($composer["autoload"]["psr-0"])){
|
21 |
+
$this->loadPSR0($composer['autoload']['psr-0']);
|
22 |
+
}
|
23 |
+
if(isset($composer["autoload"]["files"])){
|
24 |
+
$this->loadFiles($composer["autoload"]["files"]);
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
public function loadFiles($files){
|
29 |
+
foreach($files as $file){
|
30 |
+
$fullpath = $this->dir."/".$file;
|
31 |
+
if(file_exists($fullpath)){
|
32 |
+
include_once($fullpath);
|
33 |
+
}
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
public function loadPSR4($namespaces)
|
38 |
+
{
|
39 |
+
$this->loadPSR($namespaces, true);
|
40 |
+
}
|
41 |
+
|
42 |
+
public function loadPSR0($namespaces)
|
43 |
+
{
|
44 |
+
$this->loadPSR($namespaces, false);
|
45 |
+
}
|
46 |
+
|
47 |
+
public function loadPSR($namespaces, $psr4)
|
48 |
+
{
|
49 |
+
$dir = $this->dir;
|
50 |
+
// Foreach namespace specified in the composer, load the given classes
|
51 |
+
foreach ($namespaces as $namespace => $classpaths) {
|
52 |
+
if (!is_array($classpaths)) {
|
53 |
+
$classpaths = array($classpaths);
|
54 |
+
}
|
55 |
+
spl_autoload_register(function ($classname) use ($namespace, $classpaths, $dir, $psr4) {
|
56 |
+
// Check if the namespace matches the class we are looking for
|
57 |
+
if (preg_match("#^".preg_quote($namespace)."#", $classname)) {
|
58 |
+
// Remove the namespace from the file path since it's psr4
|
59 |
+
if ($psr4) {
|
60 |
+
$classname = str_replace($namespace, "", $classname);
|
61 |
+
}
|
62 |
+
$filename = preg_replace("#\\\\#", "/", $classname).".php";
|
63 |
+
foreach ($classpaths as $classpath) {
|
64 |
+
$fullpath = $this->dir."/".$classpath."/$filename";
|
65 |
+
if (file_exists($fullpath)) {
|
66 |
+
include_once $fullpath;
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
});
|
71 |
+
}
|
72 |
+
}
|
73 |
+
}
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
require_once "PackageLoader.php";
|
3 |
+
$loader = new ShortPixel\Build\PackageLoader();
|
4 |
+
$loader->load(__DIR__);
|
5 |
+
|
@@ -0,0 +1 @@
|
|
|
1 |
+
{"name":"ShortPixel\/shortpixelmodules","description":"ShortPixel submodules","type":"function","autoload":{"psr-4":{"ShortPixel\\ShortPixelLogger\\":"log\/src\/","ShortPixel\\Notices\\":"notices\/src\/"}}}
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "shortpixel/log",
|
3 |
+
"description": "ShortPixel Logging",
|
4 |
+
"version": "1.1",
|
5 |
+
"type": "library",
|
6 |
+
"license": "MIT",
|
7 |
+
"authors": [
|
8 |
+
{
|
9 |
+
"name": "Bas",
|
10 |
+
"email": "bas@weblogmechanic.com"
|
11 |
+
}
|
12 |
+
],
|
13 |
+
"minimum-stability": "dev",
|
14 |
+
"require": {},
|
15 |
+
"autoload": {
|
16 |
+
"psr-4": { "ShortPixel\\ShortPixelLogger\\" : "src/" }
|
17 |
+
}
|
18 |
+
}
|
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// The data models.
|
3 |
+
namespace ShortPixel\ShortPixelLogger;
|
4 |
+
|
5 |
+
|
6 |
+
class DebugItem
|
7 |
+
{
|
8 |
+
protected $time;
|
9 |
+
protected $level;
|
10 |
+
protected $message;
|
11 |
+
protected $data = array();
|
12 |
+
protected $caller = false; // array when filled
|
13 |
+
|
14 |
+
protected $model;
|
15 |
+
|
16 |
+
const LEVEL_ERROR = 1;
|
17 |
+
const LEVEL_WARN = 2;
|
18 |
+
const LEVEL_INFO = 3;
|
19 |
+
const LEVEL_DEBUG = 4;
|
20 |
+
|
21 |
+
public function __construct($message, $args)
|
22 |
+
{
|
23 |
+
$this->level = $args['level'];
|
24 |
+
$data = $args['data'];
|
25 |
+
|
26 |
+
$this->message = $message;
|
27 |
+
$this->time = microtime(true);
|
28 |
+
|
29 |
+
$this->setCaller();
|
30 |
+
|
31 |
+
// Add message to data if it seems to be some debug variable.
|
32 |
+
if (is_object($this->message) || is_array($this->message))
|
33 |
+
{
|
34 |
+
$data[] = $this->message;
|
35 |
+
$this->message = __('[Data]');
|
36 |
+
}
|
37 |
+
if (is_array($data) && count($data) > 0)
|
38 |
+
{
|
39 |
+
$dataType = $this->getDataType($data);
|
40 |
+
if ($dataType == 1) // singular
|
41 |
+
{
|
42 |
+
$this->data[] = print_r($data, true);
|
43 |
+
}
|
44 |
+
if ($dataType == 2) //array
|
45 |
+
{
|
46 |
+
foreach($data as $index => $item)
|
47 |
+
{
|
48 |
+
if (is_object($item) || is_array($item))
|
49 |
+
{
|
50 |
+
$this->data[] = print_r($item, true);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
} // if
|
55 |
+
elseif (! is_array($data)) // this leaves out empty default arrays
|
56 |
+
{
|
57 |
+
$this->data[] = print_r($data, true);
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
public function getData()
|
62 |
+
{
|
63 |
+
return array('time' => $this->time, 'level' => $this->level, 'message' => $this->message, 'data' => $this->data, 'caller' => $this->caller);
|
64 |
+
}
|
65 |
+
|
66 |
+
/** Test Data Array for possible values
|
67 |
+
*
|
68 |
+
* Data can be a collection of several debug vars, a single var, or just an normal array. Test if array has single types,
|
69 |
+
* which is a sign the array is not a collection.
|
70 |
+
*/
|
71 |
+
protected function getDataType($data)
|
72 |
+
{
|
73 |
+
$single_type = array('integer', 'boolean', 'string');
|
74 |
+
if (in_array(gettype(reset($data)), $single_type))
|
75 |
+
{
|
76 |
+
return 1;
|
77 |
+
}
|
78 |
+
else
|
79 |
+
{
|
80 |
+
return 2;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
public function getForFormat()
|
85 |
+
{
|
86 |
+
$data = $this->getData();
|
87 |
+
switch($this->level)
|
88 |
+
{
|
89 |
+
case self::LEVEL_ERROR:
|
90 |
+
$level = 'ERR';
|
91 |
+
$color = "\033[31m";
|
92 |
+
break;
|
93 |
+
case self::LEVEL_WARN:
|
94 |
+
$level = 'WRN';
|
95 |
+
$color = "\033[33m";
|
96 |
+
break;
|
97 |
+
case self::LEVEL_INFO:
|
98 |
+
$level = 'INF';
|
99 |
+
$color = "\033[37m";
|
100 |
+
break;
|
101 |
+
case self::LEVEL_DEBUG:
|
102 |
+
$level = 'DBG';
|
103 |
+
$color = "\033[37m";
|
104 |
+
break;
|
105 |
+
|
106 |
+
}
|
107 |
+
$color_end = "\033[0m";
|
108 |
+
|
109 |
+
$data['color'] = $color;
|
110 |
+
$data['color_end'] = $color_end;
|
111 |
+
$data['level'] = $level;
|
112 |
+
|
113 |
+
return $data;
|
114 |
+
|
115 |
+
//return array('time' => $this->time, 'level' => $level, 'message' => $this->message, 'data' => $this->data, 'color' => $color, 'color_end' => $color_end, 'caller' => $this->caller);
|
116 |
+
|
117 |
+
}
|
118 |
+
|
119 |
+
protected function setCaller()
|
120 |
+
{
|
121 |
+
if(PHP_VERSION_ID < 50400) {
|
122 |
+
$debug=debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
123 |
+
} else {
|
124 |
+
$debug=debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,5);
|
125 |
+
}
|
126 |
+
|
127 |
+
$i = 4;
|
128 |
+
if (isset($debug[$i]))
|
129 |
+
{
|
130 |
+
$info = $debug[$i];
|
131 |
+
$line = isset($info['line']) ? $info['line'] : 'Line unknown';
|
132 |
+
$file = isset($info['file']) ? basename($info['file']) : 'File not set';
|
133 |
+
|
134 |
+
$this->caller = array('line' => $line, 'file' => $file, 'function' => $info['function']);
|
135 |
+
}
|
136 |
+
|
137 |
+
|
138 |
+
}
|
139 |
+
|
140 |
+
|
141 |
+
}
|
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel\ShortPixelLogger;
|
3 |
+
|
4 |
+
/*** Logger class
|
5 |
+
*
|
6 |
+
* Class uses the debug data model for keeping log entries.
|
7 |
+
* Logger should not be called before init hook!
|
8 |
+
*/
|
9 |
+
class ShortPixelLogger
|
10 |
+
{
|
11 |
+
static protected $instance = null;
|
12 |
+
protected $start_time;
|
13 |
+
|
14 |
+
protected $is_active = false;
|
15 |
+
protected $is_manual_request = false;
|
16 |
+
protected $show_debug_view = false;
|
17 |
+
|
18 |
+
protected $items = array();
|
19 |
+
protected $logPath = false;
|
20 |
+
protected $logMode = FILE_APPEND;
|
21 |
+
|
22 |
+
protected $logLevel;
|
23 |
+
protected $format = "[ %%time%% ] %%color%% %%level%% %%color_end%% \t %%message%% \t %%caller%% ( %%time_passed%% )";
|
24 |
+
protected $format_data = "\t %%data%% ";
|
25 |
+
|
26 |
+
protected $hooks = array();
|
27 |
+
/* protected $hooks = array(
|
28 |
+
'shortpixel_image_exists' => array('numargs' => 3),
|
29 |
+
'shortpixel_webp_image_base' => array('numargs' => 2),
|
30 |
+
'shortpixel_image_urls' => array('numargs' => 2),
|
31 |
+
); // @todo monitor hooks, but this should be more dynamic. Do when moving to module via config.
|
32 |
+
*/
|
33 |
+
|
34 |
+
// utility
|
35 |
+
private $namespace;
|
36 |
+
private $view;
|
37 |
+
|
38 |
+
protected $template = 'view-debug-box';
|
39 |
+
|
40 |
+
/** Debugger constructor
|
41 |
+
* Two ways to activate the debugger. 1) Define SHORTPIXEL_DEBUG in wp-config.php. Either must be true or a number corresponding to required LogLevel
|
42 |
+
* 2) Put SHORTPIXEL_DEBUG in the request. Either true or number.
|
43 |
+
*/
|
44 |
+
public function __construct()
|
45 |
+
{
|
46 |
+
$this->start_time = microtime(true);
|
47 |
+
$this->logLevel = DebugItem::LEVEL_WARN;
|
48 |
+
|
49 |
+
$ns = __NAMESPACE__;
|
50 |
+
$this->namespace = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
|
51 |
+
|
52 |
+
if ($this->logPath === false)
|
53 |
+
{
|
54 |
+
$upload_dir = wp_upload_dir(null,false,false);
|
55 |
+
$this->logPath = $upload_dir['basedir'] . '/' . $this->namespace . ".log";
|
56 |
+
}
|
57 |
+
|
58 |
+
if (isset($_REQUEST['SHORTPIXEL_DEBUG'])) // manual takes precedence over constants
|
59 |
+
{
|
60 |
+
$this->is_manual_request = true;
|
61 |
+
$this->is_active = true;
|
62 |
+
|
63 |
+
if ($_REQUEST['SHORTPIXEL_DEBUG'] === 'true')
|
64 |
+
{
|
65 |
+
$this->logLevel = DebugItem::LEVEL_INFO;
|
66 |
+
}
|
67 |
+
else {
|
68 |
+
$this->logLevel = intval($_REQUEST['SHORTPIXEL_DEBUG']);
|
69 |
+
}
|
70 |
+
|
71 |
+
}
|
72 |
+
else if ( (defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG > 0) )
|
73 |
+
{
|
74 |
+
$this->is_active = true;
|
75 |
+
if (SHORTPIXEL_DEBUG === true)
|
76 |
+
$this->logLevel = DebugItem::LEVEL_INFO;
|
77 |
+
else {
|
78 |
+
$this->logLevel = intval(SHORTPIXEL_DEBUG);
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
if (defined('SHORTPIXEL_DEBUG_TARGET') && SHORTPIXEL_DEBUG_TARGET || $this->is_manual_request)
|
83 |
+
{
|
84 |
+
//$this->logPath = SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log";
|
85 |
+
//$this->logMode = defined('SHORTPIXEL_LOG_OVERWRITE') ? 0 : FILE_APPEND;
|
86 |
+
if (defined('SHORTPIXEL_LOG_OVERWRITE')) // if overwrite, do this on init once.
|
87 |
+
file_put_contents($this->logPath,'-- Log Reset -- ' .PHP_EOL);
|
88 |
+
|
89 |
+
}
|
90 |
+
|
91 |
+
/* On Early init, this function might not exist, then queue it when needed */
|
92 |
+
if (! function_exists('wp_get_current_user'))
|
93 |
+
add_action('plugins_loaded', array($this, 'initView'));
|
94 |
+
else
|
95 |
+
$this->initView();
|
96 |
+
|
97 |
+
|
98 |
+
if ($this->is_active && count($this->hooks) > 0)
|
99 |
+
$this->monitorHooks();
|
100 |
+
}
|
101 |
+
|
102 |
+
/** Init the view when needed. Private function ( public because of WP_HOOK )
|
103 |
+
* Never call directly */
|
104 |
+
public function initView()
|
105 |
+
{
|
106 |
+
$user_is_administrator = (current_user_can('manage_options')) ? true : false;
|
107 |
+
|
108 |
+
if ($this->is_active && $this->is_manual_request && $user_is_administrator )
|
109 |
+
{
|
110 |
+
$content_url = content_url();
|
111 |
+
$logPath = $this->logPath;
|
112 |
+
$pathpos = strpos($logPath, 'wp-content') + strlen('wp-content');
|
113 |
+
$logPart = substr($logPath, $pathpos);
|
114 |
+
$logLink = $content_url . $logPart;
|
115 |
+
|
116 |
+
$this->view = new \stdClass;
|
117 |
+
$this->view->logLink = $logLink;
|
118 |
+
add_action('admin_footer', array($this, 'loadView'));
|
119 |
+
}
|
120 |
+
}
|
121 |
+
|
122 |
+
public static function getInstance()
|
123 |
+
{
|
124 |
+
if ( self::$instance === null)
|
125 |
+
{
|
126 |
+
self::$instance = new ShortPixelLogger();
|
127 |
+
}
|
128 |
+
return self::$instance;
|
129 |
+
}
|
130 |
+
|
131 |
+
public function setLogPath($logPath)
|
132 |
+
{
|
133 |
+
$this->logPath = $logPath;
|
134 |
+
}
|
135 |
+
protected static function addLog($message, $level, $data = array())
|
136 |
+
{
|
137 |
+
$log = self::getInstance();
|
138 |
+
|
139 |
+
// don't log anything too low.
|
140 |
+
if ($log->logLevel < $level)
|
141 |
+
{
|
142 |
+
return;
|
143 |
+
}
|
144 |
+
|
145 |
+
$arg = array();
|
146 |
+
$args['level'] = $level;
|
147 |
+
$args['data'] = $data;
|
148 |
+
|
149 |
+
$newItem = new DebugItem($message, $args);
|
150 |
+
$log->items[] = $newItem;
|
151 |
+
|
152 |
+
if ($log->is_active)
|
153 |
+
{
|
154 |
+
$log->write($newItem);
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
/** Writes to log File. */
|
159 |
+
protected function write($debugItem, $mode = 'file')
|
160 |
+
{
|
161 |
+
$items = $debugItem->getForFormat();
|
162 |
+
$items['time_passed'] = round ( ($items['time'] - $this->start_time), 5);
|
163 |
+
$items['time'] = date('Y-m-d H:i:s', $items['time'] );
|
164 |
+
|
165 |
+
if ( ($items['caller']) && is_array($items['caller']) && count($items['caller']) > 0)
|
166 |
+
{
|
167 |
+
$caller = $items['caller'];
|
168 |
+
$items['caller'] = $caller['file'] . ' in ' . $caller['function'] . '(' . $caller['line'] . ')';
|
169 |
+
}
|
170 |
+
|
171 |
+
$line = $this->formatLine($items);
|
172 |
+
|
173 |
+
if ($this->logPath)
|
174 |
+
{
|
175 |
+
file_put_contents($this->logPath,$line, FILE_APPEND);
|
176 |
+
}
|
177 |
+
else {
|
178 |
+
error_log($line);
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
protected function formatLine($args = array() )
|
183 |
+
{
|
184 |
+
$line= $this->format;
|
185 |
+
foreach($args as $key => $value)
|
186 |
+
{
|
187 |
+
if (! is_array($value) && ! is_object($value))
|
188 |
+
$line = str_replace('%%' . $key . '%%', $value, $line);
|
189 |
+
}
|
190 |
+
|
191 |
+
$line .= PHP_EOL;
|
192 |
+
|
193 |
+
if (isset($args['data']))
|
194 |
+
{
|
195 |
+
$data = array_filter($args['data']);
|
196 |
+
if (count($data) > 0)
|
197 |
+
{
|
198 |
+
foreach($data as $item)
|
199 |
+
{
|
200 |
+
$line .= $item . PHP_EOL;
|
201 |
+
}
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
return $line;
|
206 |
+
}
|
207 |
+
|
208 |
+
protected function setLogLevel($level)
|
209 |
+
{
|
210 |
+
$this->logLevel = $level;
|
211 |
+
}
|
212 |
+
|
213 |
+
protected function getEnv($name)
|
214 |
+
{
|
215 |
+
if (isset($this->{$name}))
|
216 |
+
{
|
217 |
+
return $this->{$name};
|
218 |
+
}
|
219 |
+
else {
|
220 |
+
return false;
|
221 |
+
}
|
222 |
+
}
|
223 |
+
|
224 |
+
public static function addError($message, $args = array())
|
225 |
+
{
|
226 |
+
$level = DebugItem::LEVEL_ERROR;
|
227 |
+
static::addLog($message, $level, $args);
|
228 |
+
}
|
229 |
+
public static function addWarn($message, $args = array())
|
230 |
+
{
|
231 |
+
$level = DebugItem::LEVEL_WARN;
|
232 |
+
static::addLog($message, $level, $args);
|
233 |
+
}
|
234 |
+
public static function addInfo($message, $args = array())
|
235 |
+
{
|
236 |
+
$level = DebugItem::LEVEL_INFO;
|
237 |
+
static::addLog($message, $level, $args);
|
238 |
+
}
|
239 |
+
public static function addDebug($message, $args = array())
|
240 |
+
{
|
241 |
+
$level = DebugItem::LEVEL_DEBUG;
|
242 |
+
static::addLog($message, $level, $args);
|
243 |
+
}
|
244 |
+
|
245 |
+
public static function logLevel($level)
|
246 |
+
{
|
247 |
+
$log = self::getInstance();
|
248 |
+
static::addInfo('Changing Log level' . $level);
|
249 |
+
$log->setLogLevel($level);
|
250 |
+
}
|
251 |
+
|
252 |
+
public static function getLogLevel()
|
253 |
+
{
|
254 |
+
$log = self::getInstance();
|
255 |
+
return $log->getEnv('logLevel');
|
256 |
+
}
|
257 |
+
|
258 |
+
public static function isManualDebug()
|
259 |
+
{
|
260 |
+
$log = self::getInstance();
|
261 |
+
return $log->getEnv('is_manual_request');
|
262 |
+
}
|
263 |
+
|
264 |
+
public static function getLogPath()
|
265 |
+
{
|
266 |
+
$log = self::getInstance();
|
267 |
+
return $log->getEnv('logPath');
|
268 |
+
}
|
269 |
+
|
270 |
+
/** Function to test if the debugger is active
|
271 |
+
* @return boolean true when active.
|
272 |
+
*/
|
273 |
+
public static function debugIsActive()
|
274 |
+
{
|
275 |
+
$log = self::getInstance();
|
276 |
+
return $log->getEnv('is_active');
|
277 |
+
}
|
278 |
+
|
279 |
+
protected function monitorHooks()
|
280 |
+
{
|
281 |
+
|
282 |
+
foreach($this->hooks as $hook => $data)
|
283 |
+
{
|
284 |
+
$numargs = isset($data['numargs']) ? $data['numargs'] : 1;
|
285 |
+
$prio = isset($data['priority']) ? $data['priority'] : 10;
|
286 |
+
|
287 |
+
add_filter($hook, function($value) use ($hook) {
|
288 |
+
$args = func_get_args();
|
289 |
+
return $this->logHook($hook, $value, $args); }, $prio, $numargs);
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
public function logHook($hook, $value, $args)
|
294 |
+
{
|
295 |
+
array_shift($args);
|
296 |
+
self::addInfo('[Hook] - ' . $hook . ' with ' . var_export($value,true), $args);
|
297 |
+
return $value;
|
298 |
+
}
|
299 |
+
|
300 |
+
public function loadView()
|
301 |
+
{
|
302 |
+
// load either param or class template.
|
303 |
+
$template = $this->template;
|
304 |
+
|
305 |
+
$view = $this->view;
|
306 |
+
$view->namespace = $this->namespace;
|
307 |
+
$controller = $this;
|
308 |
+
|
309 |
+
$template_path = __DIR__ . '/' . $this->template . '.php';
|
310 |
+
if (file_exists($template_path))
|
311 |
+
{
|
312 |
+
|
313 |
+
include($template_path);
|
314 |
+
}
|
315 |
+
else {
|
316 |
+
self::addError("View $template could not be found in " . $template_path,
|
317 |
+
array('class' => get_class($this), 'req' => $_REQUEST));
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
|
322 |
+
} // class debugController
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Debug Box to load Log File
|
3 |
+
namespace ShortPixel\ShortPixelLogger;
|
4 |
+
wp_enqueue_script( 'jquery-ui-draggable' );
|
5 |
+
|
6 |
+
?>
|
7 |
+
|
8 |
+
<style>
|
9 |
+
.sp_debug_wrap
|
10 |
+
{
|
11 |
+
position: relative;
|
12 |
+
clear: both;
|
13 |
+
}
|
14 |
+
.sp_debug_box
|
15 |
+
{
|
16 |
+
position: absolute;
|
17 |
+
right: 0px;
|
18 |
+
top: 50px;
|
19 |
+
background-color: #fff;
|
20 |
+
width: 150px;
|
21 |
+
z-index: 1000000;
|
22 |
+
border: 1px solid #000;
|
23 |
+
|
24 |
+
}
|
25 |
+
.sp_debug_box .header
|
26 |
+
{
|
27 |
+
min-height: 10px;
|
28 |
+
background: #000;
|
29 |
+
color: #fff;
|
30 |
+
padding: 8px
|
31 |
+
}
|
32 |
+
.sp_debug_box .content_box
|
33 |
+
{
|
34 |
+
background: #ccc;
|
35 |
+
}
|
36 |
+
.content_box
|
37 |
+
{
|
38 |
+
padding: 8px;
|
39 |
+
}
|
40 |
+
</style>
|
41 |
+
|
42 |
+
<script language='javascript'>
|
43 |
+
jQuery(document).ready(function($)
|
44 |
+
{
|
45 |
+
$( ".sp_debug_box" ).draggable();
|
46 |
+
|
47 |
+
});
|
48 |
+
</script>
|
49 |
+
|
50 |
+
|
51 |
+
<div class='sp_debug_box'>
|
52 |
+
<div class='header'><?php echo $view->namespace ?> Debug Box </div>
|
53 |
+
<a target="_blank" href='<?php echo $view->logLink ?>'>Logfile</a>
|
54 |
+
<div class='content_box'>
|
55 |
+
|
56 |
+
</div>
|
57 |
+
</div>
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "shortpixel/notices",
|
3 |
+
"description": "ShortPixel WordPress Notice System",
|
4 |
+
"version": "1.1",
|
5 |
+
"type": "library",
|
6 |
+
"license": "MIT",
|
7 |
+
"authors": [
|
8 |
+
{
|
9 |
+
"name": "Bas",
|
10 |
+
"email": "bas@weblogmechanic.com"
|
11 |
+
}
|
12 |
+
],
|
13 |
+
"minimum-stability": "dev",
|
14 |
+
"require": {
|
15 |
+
"shortpixel/log" : "1.1.*"
|
16 |
+
},
|
17 |
+
"repositories": [
|
18 |
+
{
|
19 |
+
"packagist.org": false,
|
20 |
+
"type": "path",
|
21 |
+
"url": "../modules/",
|
22 |
+
"options": {
|
23 |
+
"symlink": true
|
24 |
+
}
|
25 |
+
}
|
26 |
+
],
|
27 |
+
|
28 |
+
"autoload": {
|
29 |
+
"psr-4": { "ShortPixel\\Notices\\" : "src/" }
|
30 |
+
}
|
31 |
+
}
|
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel\Notices;
|
3 |
+
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
class NoticeController //extends ShortPixelController
|
6 |
+
{
|
7 |
+
protected static $notices = array();
|
8 |
+
protected static $instance = null;
|
9 |
+
protected static $cssHookLoaded = false; // prevent css output more than once.
|
10 |
+
|
11 |
+
public $notice_count = 0;
|
12 |
+
|
13 |
+
protected $has_stored = false;
|
14 |
+
|
15 |
+
protected $notice_option = ''; // The wp_options name for notices here.
|
16 |
+
|
17 |
+
/** For backward compat. Never call constructor directly. */
|
18 |
+
public function __construct()
|
19 |
+
{
|
20 |
+
// $this->loadModel('notice');
|
21 |
+
$ns = __NAMESPACE__;
|
22 |
+
$ns = substr($ns, 0, strpos($ns, '\\')); // try to get first part of namespace
|
23 |
+
$this->notice_option = $ns . '-notices';
|
24 |
+
|
25 |
+
$this->loadNotices();
|
26 |
+
//$this->loadConfig();
|
27 |
+
}
|
28 |
+
|
29 |
+
/** Load Notices Config File, if any
|
30 |
+
*
|
31 |
+
* [ Future Use ]
|
32 |
+
*/
|
33 |
+
public function loadConfig()
|
34 |
+
{
|
35 |
+
if (file_exists('../notice_config.json'))
|
36 |
+
{
|
37 |
+
$config = file_get_contents('../notice_config.json');
|
38 |
+
$json_config = json_decode($config);
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
public function loadIcons($icons)
|
43 |
+
{
|
44 |
+
foreach($icons as $name => $icon)
|
45 |
+
NoticeModel::setIcon($name, $icon);
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
protected function loadNotices()
|
50 |
+
{
|
51 |
+
$notices = get_option($this->notice_option, false);
|
52 |
+
$cnotice = (is_array($notices)) ? count($notices) : 0;
|
53 |
+
Log::addDebug('Notice Control - #num notices' . $cnotice);
|
54 |
+
if ($notices !== false)
|
55 |
+
{
|
56 |
+
self::$notices = $notices;
|
57 |
+
$this->has_stored = true;
|
58 |
+
}
|
59 |
+
else {
|
60 |
+
self::$notices = array();
|
61 |
+
$this->has_stored = false;
|
62 |
+
}
|
63 |
+
$this->countNotices();
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
public function addNotice($message, $code)
|
68 |
+
{
|
69 |
+
$notice = new NoticeModel($message, $code);
|
70 |
+
self::$notices[] = $notice;
|
71 |
+
$this->countNotices();
|
72 |
+
Log::addDebug('Adding notice - ', $notice);
|
73 |
+
$this->update();
|
74 |
+
return $notice;
|
75 |
+
}
|
76 |
+
|
77 |
+
/** Update the notices to store, check what to remove, returns count. */
|
78 |
+
public function update()
|
79 |
+
{
|
80 |
+
if (! is_array(self::$notices) || count(self::$notices) == 0)
|
81 |
+
{
|
82 |
+
if ($this->has_stored)
|
83 |
+
delete_option($this->notice_option);
|
84 |
+
|
85 |
+
return 0;
|
86 |
+
}
|
87 |
+
|
88 |
+
$new_notices = array();
|
89 |
+
foreach(self::$notices as $item)
|
90 |
+
{
|
91 |
+
if (! $item->isDone() )
|
92 |
+
{
|
93 |
+
$new_notices[] = $item;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
update_option($this->notice_option, $new_notices);
|
98 |
+
self::$notices = $new_notices;
|
99 |
+
|
100 |
+
return $this->countNotices();
|
101 |
+
}
|
102 |
+
|
103 |
+
public function countNotices()
|
104 |
+
{
|
105 |
+
$this->notice_count = count(self::$notices);
|
106 |
+
return $this->notice_count;
|
107 |
+
}
|
108 |
+
|
109 |
+
|
110 |
+
public function getNotices()
|
111 |
+
{
|
112 |
+
return self::$notices;
|
113 |
+
}
|
114 |
+
|
115 |
+
public static function getInstance()
|
116 |
+
{
|
117 |
+
if ( self::$instance === null)
|
118 |
+
{
|
119 |
+
self::$instance = new NoticeController();
|
120 |
+
}
|
121 |
+
|
122 |
+
return self::$instance;
|
123 |
+
}
|
124 |
+
|
125 |
+
/** Adds a notice, quick and fast method
|
126 |
+
* @param String $message The Message you want to notify
|
127 |
+
* @param int $code A value of messageType as defined in model
|
128 |
+
* @returm Object Instance of noticeModel
|
129 |
+
*/
|
130 |
+
|
131 |
+
public static function addNormal($message)
|
132 |
+
{
|
133 |
+
$noticeController = self::getInstance();
|
134 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_NORMAL);
|
135 |
+
return $notice;
|
136 |
+
|
137 |
+
}
|
138 |
+
|
139 |
+
public static function addError($message)
|
140 |
+
{
|
141 |
+
$noticeController = self::getInstance();
|
142 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_ERROR);
|
143 |
+
return $notice;
|
144 |
+
|
145 |
+
}
|
146 |
+
|
147 |
+
public static function addWarning($message)
|
148 |
+
{
|
149 |
+
$noticeController = self::getInstance();
|
150 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_WARNING);
|
151 |
+
return $notice;
|
152 |
+
|
153 |
+
}
|
154 |
+
|
155 |
+
public static function addSuccess($message)
|
156 |
+
{
|
157 |
+
$noticeController = self::getInstance();
|
158 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_SUCCESS);
|
159 |
+
return $notice;
|
160 |
+
|
161 |
+
}
|
162 |
+
|
163 |
+
public function admin_notices()
|
164 |
+
{
|
165 |
+
if ($this->countNotices() > 0)
|
166 |
+
{
|
167 |
+
if (! self::$cssHookLoaded)
|
168 |
+
{
|
169 |
+
add_action('admin_print_footer_scripts', array($this, 'printNoticeStyle'));
|
170 |
+
self::$cssHookLoaded = true;
|
171 |
+
}
|
172 |
+
foreach($this->getNotices() as $notice)
|
173 |
+
{
|
174 |
+
echo $notice->getForDisplay();
|
175 |
+
}
|
176 |
+
}
|
177 |
+
$this->update(); // puts views, and updates
|
178 |
+
}
|
179 |
+
|
180 |
+
public function printNoticeStyle()
|
181 |
+
{
|
182 |
+
if (file_exists(__DIR__ . '/css/notices.css'))
|
183 |
+
{
|
184 |
+
echo '<style>' . file_get_contents(__DIR__ . '/css/notices.css') . '</style>';
|
185 |
+
}
|
186 |
+
else {
|
187 |
+
Log::addDebug('Notices : css/notices.css could not be loaded');
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
|
192 |
+
|
193 |
+
|
194 |
+
}
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel\Notices;
|
3 |
+
|
4 |
+
class NoticeModel //extends ShortPixelModel
|
5 |
+
{
|
6 |
+
protected $message;
|
7 |
+
public $code;
|
8 |
+
|
9 |
+
protected $viewed = false;
|
10 |
+
public $is_persistent = false; // This is a fatal issue, display until something was fixed.
|
11 |
+
public $is_removable = true; // if removable, display a notice dialog with red X or so.
|
12 |
+
public $messageType = self::NOTICE_NORMAL;
|
13 |
+
|
14 |
+
public static $icons = array();
|
15 |
+
|
16 |
+
const NOTICE_NORMAL = 1;
|
17 |
+
const NOTICE_ERROR = 2;
|
18 |
+
const NOTICE_SUCCESS = 3;
|
19 |
+
const NOTICE_WARNING = 4;
|
20 |
+
|
21 |
+
|
22 |
+
public function __construct($message, $messageType = self::NOTICE_NORMAL)
|
23 |
+
{
|
24 |
+
$this->message = $message;
|
25 |
+
$this->messageType = $messageType;
|
26 |
+
|
27 |
+
}
|
28 |
+
|
29 |
+
public function isDone()
|
30 |
+
{
|
31 |
+
if ($this->viewed && ! $this->is_persistent)
|
32 |
+
return true;
|
33 |
+
else
|
34 |
+
return false;
|
35 |
+
|
36 |
+
}
|
37 |
+
|
38 |
+
public static function setIcon($notice_type, $icon)
|
39 |
+
{
|
40 |
+
switch($notice_type)
|
41 |
+
{
|
42 |
+
case 'error':
|
43 |
+
$type = self::NOTICE_ERROR;
|
44 |
+
break;
|
45 |
+
case 'success':
|
46 |
+
$type = self::NOTICE_SUCCESS;
|
47 |
+
break;
|
48 |
+
case 'warning':
|
49 |
+
$type = self::NOTICE_WARNING;
|
50 |
+
break;
|
51 |
+
case 'normal':
|
52 |
+
default:
|
53 |
+
$type = self::NOTICE_NORMAL;
|
54 |
+
break;
|
55 |
+
}
|
56 |
+
self::$icons[$type] = $icon;
|
57 |
+
}
|
58 |
+
|
59 |
+
public function getForDisplay()
|
60 |
+
{
|
61 |
+
$this->viewed = true;
|
62 |
+
$class = 'shortpixel notice ';
|
63 |
+
|
64 |
+
$icon = '';
|
65 |
+
|
66 |
+
switch($this->messageType)
|
67 |
+
{
|
68 |
+
case self::NOTICE_ERROR:
|
69 |
+
$class .= 'notice-error ';
|
70 |
+
$icon = isset(self::$icons[self::NOTICE_ERROR]) ? self::$icons[self::NOTICE_ERROR] : '';
|
71 |
+
//$icon = 'scared';
|
72 |
+
break;
|
73 |
+
case self::NOTICE_SUCCESS:
|
74 |
+
$class .= 'notice-success ';
|
75 |
+
$icon = isset(self::$icons[self::NOTICE_SUCCESS]) ? self::$icons[self::NOTICE_SUCCESS] : '';
|
76 |
+
break;
|
77 |
+
case self::NOTICE_WARNING:
|
78 |
+
$class .= 'notice-warning ';
|
79 |
+
$icon = isset(self::$icons[self::NOTICE_WARNING]) ? self::$icons[self::NOTICE_WARNING] : '';
|
80 |
+
break;
|
81 |
+
case self::NOTICE_NORMAL:
|
82 |
+
$class .= 'notice-info ';
|
83 |
+
$icon = isset(self::$icons[self::NOTICE_NORMAL]) ? self::$icons[self::NOTICE_NORMAL] : '';
|
84 |
+
break;
|
85 |
+
default:
|
86 |
+
$class .= 'notice-info ';
|
87 |
+
$icon = '';
|
88 |
+
break;
|
89 |
+
}
|
90 |
+
|
91 |
+
/*$image = '<img src="' . plugins_url('/shortpixel-image-optimiser/res/img/robo-' . $icon . '.png') . '"
|
92 |
+
srcset="' . plugins_url( 'shortpixel-image-optimiser/res/img/robo-' . $icon . '.png' ) . ' 1x, ' . plugins_url( 'shortpixel-image-optimiser/res/img/robo-' . $icon . '@2x.png') . ' 2x" class="short-pixel-notice-icon">';
|
93 |
+
*/
|
94 |
+
|
95 |
+
if ($this->is_removable)
|
96 |
+
{
|
97 |
+
$class .= 'is-dismissible ';
|
98 |
+
}
|
99 |
+
|
100 |
+
if ($this->is_persistent)
|
101 |
+
{
|
102 |
+
$class .= '';
|
103 |
+
}
|
104 |
+
|
105 |
+
return "<div class='$class'>" . $icon . "<p>" . $this->message . "</p></div>";
|
106 |
+
|
107 |
+
}
|
108 |
+
|
109 |
+
|
110 |
+
|
111 |
+
// @todo Transient save, since that is used in some parts.
|
112 |
+
// save
|
113 |
+
// load
|
114 |
+
|
115 |
+
|
116 |
+
}
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.shortpixel.notice {
|
2 |
+
padding: 8px; }
|
3 |
+
.shortpixel.notice img {
|
4 |
+
display: inline-block;
|
5 |
+
margin: 0 25px 0 0;
|
6 |
+
max-height: 50px; }
|
7 |
+
.shortpixel.notice .notice-dismiss {
|
8 |
+
margin-top: 10px; }
|
9 |
+
|
10 |
+
/* In-view notice ( not on top, between the options ) - styled after WP notice */
|
11 |
+
.view-notice {
|
12 |
+
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
|
13 |
+
border: 4px solid #fff;
|
14 |
+
padding: 1px 12px; }
|
15 |
+
.view-notice p {
|
16 |
+
margin: 1em 0 !important; }
|
17 |
+
.view-notice.warning {
|
18 |
+
border-left-color: #ffb900; }
|
19 |
+
|
20 |
+
.view-notice-row {
|
21 |
+
display: none; }
|
@@ -0,0 +1 @@
|
|
|
1 |
+
.shortpixel.notice{padding:8px}.shortpixel.notice img{display:inline-block;margin:0 25px 0 0;max-height:50px}.shortpixel.notice .notice-dismiss{margin-top:10px}.view-notice{box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);border:4px solid #fff;padding:1px 12px}.view-notice p{margin:1em 0 !important}.view-notice.warning{border-left-color:#ffb900}.view-notice-row{display:none}
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
.shortpixel.notice
|
3 |
+
{
|
4 |
+
//padding: 18px;
|
5 |
+
//min-height: 50px;
|
6 |
+
padding: 8px;
|
7 |
+
img
|
8 |
+
{
|
9 |
+
display:inline-block;
|
10 |
+
margin: 0 25px 0 0;
|
11 |
+
max-height: 50px;
|
12 |
+
}
|
13 |
+
.notice-dismiss
|
14 |
+
{
|
15 |
+
margin-top: 10px;
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
/* In-view notice ( not on top, between the options ) - styled after WP notice */
|
20 |
+
.view-notice
|
21 |
+
{
|
22 |
+
|
23 |
+
box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 );
|
24 |
+
border: 4px solid #fff;
|
25 |
+
|
26 |
+
padding: 1px 12px;
|
27 |
+
p {
|
28 |
+
margin: 1em 0 !important;
|
29 |
+
}
|
30 |
+
&.warning
|
31 |
+
{
|
32 |
+
border-left-color: #ffb900;
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
.view-notice-row
|
37 |
+
{
|
38 |
+
display: none;
|
39 |
+
}
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
/* Main function of this controller is to load key on runtime
|
6 |
+
This should probably in future incorporate some apikey checking functions that shouldn't be in model.
|
7 |
+
*/
|
8 |
+
class ApiKeyController extends shortPixelController
|
9 |
+
{
|
10 |
+
|
11 |
+
public function __construct()
|
12 |
+
{
|
13 |
+
$this->loadModel('apikey');
|
14 |
+
$this->model = new apiKeyModel();
|
15 |
+
}
|
16 |
+
|
17 |
+
// glue method.
|
18 |
+
public function setShortPixel($pixel)
|
19 |
+
{
|
20 |
+
parent::setShortPixel($pixel);
|
21 |
+
$this->model->shortPixel = $pixel;
|
22 |
+
}
|
23 |
+
|
24 |
+
public function load()
|
25 |
+
{
|
26 |
+
$this->model->loadKey();
|
27 |
+
}
|
28 |
+
|
29 |
+
|
30 |
+
}
|
@@ -1,7 +1,6 @@
|
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
|
4 |
-
|
5 |
class BulkRestoreAll extends ShortPixelController
|
6 |
{
|
7 |
protected static $slug = 'bulk-restore-all';
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
|
|
|
4 |
class BulkRestoreAll extends ShortPixelController
|
5 |
{
|
6 |
protected static $slug = 'bulk-restore-all';
|
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
-
use ShortPixel\ShortPixelLogger as Log;
|
4 |
|
5 |
class ShortPixelController
|
6 |
{
|
@@ -18,6 +18,8 @@ class ShortPixelController
|
|
18 |
protected $view; // object to use in the view.
|
19 |
protected $url; // if controller is home to a page, sets the URL here. For redirects and what not.
|
20 |
|
|
|
|
|
21 |
public static function init()
|
22 |
{
|
23 |
foreach (get_declared_classes() as $class) {
|
@@ -59,8 +61,19 @@ class ShortPixelController
|
|
59 |
*/
|
60 |
protected function checkPost()
|
61 |
{
|
62 |
-
if (
|
|
|
|
|
|
|
63 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
$this->is_form_submit = true;
|
65 |
$this->processPostData($_POST);
|
66 |
}
|
@@ -122,10 +135,11 @@ class ShortPixelController
|
|
122 |
require_once($path);
|
123 |
}
|
124 |
else {
|
125 |
-
Log::addError(
|
126 |
}
|
127 |
}
|
128 |
-
}
|
|
|
129 |
|
130 |
/** Accepts POST data, maps, checks missing fields, and applies sanitization to it.
|
131 |
* @param array $post POST data
|
@@ -154,9 +168,11 @@ class ShortPixelController
|
|
154 |
return true;
|
155 |
}
|
156 |
}
|
157 |
-
|
158 |
-
|
159 |
-
|
|
|
|
|
160 |
|
161 |
return $this->postData;
|
162 |
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
|
5 |
class ShortPixelController
|
6 |
{
|
18 |
protected $view; // object to use in the view.
|
19 |
protected $url; // if controller is home to a page, sets the URL here. For redirects and what not.
|
20 |
|
21 |
+
protected $form_action = 'sp-action';
|
22 |
+
|
23 |
public static function init()
|
24 |
{
|
25 |
foreach (get_declared_classes() as $class) {
|
61 |
*/
|
62 |
protected function checkPost()
|
63 |
{
|
64 |
+
if (count($_POST) == 0) // no post, nothing to check, return silent.
|
65 |
+
return;
|
66 |
+
|
67 |
+
if (! isset($_POST['sp-nonce']) || ! wp_verify_nonce( $_POST['sp-nonce'], $this->form_action))
|
68 |
{
|
69 |
+
Log::addInfo('Check Post fails nonce check' . $this->form_action, array($_POST) );
|
70 |
+
return false;
|
71 |
+
}
|
72 |
+
else if (isset($_POST) && count($_POST) > 0)
|
73 |
+
{
|
74 |
+
check_admin_referer( $this->form_action, 'sp-nonce' ); // extra check, when we are wrong here, it dies.
|
75 |
+
unset($_POST['sp-nonce']);
|
76 |
+
unset($_POST['_wp_http_referer']);
|
77 |
$this->is_form_submit = true;
|
78 |
$this->processPostData($_POST);
|
79 |
}
|
135 |
require_once($path);
|
136 |
}
|
137 |
else {
|
138 |
+
Log::addError("Model $name could not be found");
|
139 |
}
|
140 |
}
|
141 |
+
}
|
142 |
+
|
143 |
|
144 |
/** Accepts POST data, maps, checks missing fields, and applies sanitization to it.
|
145 |
* @param array $post POST data
|
168 |
return true;
|
169 |
}
|
170 |
}
|
171 |
+
else
|
172 |
+
{
|
173 |
+
$model = $this->model;
|
174 |
+
$this->postData = $model->getSanitizedData($post);
|
175 |
+
}
|
176 |
|
177 |
return $this->postData;
|
178 |
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
|
6 |
+
/** Controller for FileSystem operations
|
7 |
+
*
|
8 |
+
* This controller is used for -compound- ( complex ) FS operations, using the provided models File en Directory.
|
9 |
+
*/
|
10 |
+
Class FileSystemController extends ShortPixelController
|
11 |
+
{
|
12 |
+
public function __construct()
|
13 |
+
{
|
14 |
+
$this->loadModel('file');
|
15 |
+
$this->loadModel('directory');
|
16 |
+
}
|
17 |
+
|
18 |
+
/** Get FileModel for a certain path. This can exist or not
|
19 |
+
*
|
20 |
+
* @param String Path Full Path to the file
|
21 |
+
* @return FileModel FileModel Object. If file does not exist, not all values are set.
|
22 |
+
*/
|
23 |
+
public function getFile($path)
|
24 |
+
{
|
25 |
+
return new FileModel($path);
|
26 |
+
}
|
27 |
+
|
28 |
+
/** Get DirectoryModel for a certain path. This can exist or not
|
29 |
+
*
|
30 |
+
* @param String $path Full Path to the Directory.
|
31 |
+
* @return DirectoryModel Object with status set on current directory.
|
32 |
+
*/
|
33 |
+
public function getDirectory($path)
|
34 |
+
{
|
35 |
+
return new DirectoryModel($path);
|
36 |
+
}
|
37 |
+
|
38 |
+
/** Get the BackupLocation for a FileModel. FileModel should be not a backup itself or it will recurse
|
39 |
+
*
|
40 |
+
* For now this function should only be used for *new* backup files. Retrieving backup files via this method
|
41 |
+
* doesn't take into account legacy ways of storage.
|
42 |
+
*
|
43 |
+
* @param FileModel $file FileModel with file that needs a backup.
|
44 |
+
* @return DirectoryModel | Boolean DirectoryModel pointing to the backup directory. Returns false if the directory could not be created, or initialized.
|
45 |
+
*/
|
46 |
+
public function getBackupDirectory(FileModel $file)
|
47 |
+
{
|
48 |
+
$wp_home = get_home_path();
|
49 |
+
$filepath = $file->getFullPath();
|
50 |
+
|
51 |
+
// Implement this bastard better here.
|
52 |
+
$backup_subdir = \ShortPixelMetaFacade::returnSubDir($filepath);
|
53 |
+
|
54 |
+
$backup_fulldir = SHORTPIXEL_BACKUP_FOLDER . '/' . $backup_subdir;
|
55 |
+
Log::addDebug('Get File BackupDirectory' . $backup_fulldir);
|
56 |
+
|
57 |
+
$directory = $this->getDirectory($backup_fulldir);
|
58 |
+
|
59 |
+
if ($directory->check())
|
60 |
+
return $directory;
|
61 |
+
else {
|
62 |
+
return false;
|
63 |
+
}
|
64 |
+
|
65 |
+
}
|
66 |
+
}
|
@@ -1,9 +1,7 @@
|
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
-
use ShortPixel\ShortPixelLogger as Log;
|
4 |
-
use ShortPixel\
|
5 |
-
use ShortPixel\NoticeController as Notice;
|
6 |
-
|
7 |
|
8 |
class SettingsController extends shortPixelController
|
9 |
{
|
@@ -22,21 +20,39 @@ class SettingsController extends shortPixelController
|
|
22 |
|
23 |
protected $quotaData = null;
|
24 |
|
|
|
|
|
25 |
protected $mapper = array(
|
26 |
'key' => 'apiKey',
|
27 |
'cmyk2rgb' => 'CMYKtoRGBconversion',
|
28 |
);
|
29 |
|
30 |
protected $display_part = 'settings';
|
|
|
31 |
|
32 |
public function __construct()
|
33 |
{
|
34 |
// @todo Remove Debug Call
|
35 |
$this->model = new \WPShortPixelSettings();
|
36 |
|
|
|
|
|
37 |
|
38 |
parent::__construct();
|
|
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
|
42 |
// default action of controller
|
@@ -45,9 +61,7 @@ class SettingsController extends shortPixelController
|
|
45 |
$this->loadEnv();
|
46 |
$this->checkPost(); // sets up post data
|
47 |
|
48 |
-
$this->model->redirectedSettings = 2; //
|
49 |
-
$this->checkKey(); // needs post data
|
50 |
-
|
51 |
|
52 |
if ($this->is_form_submit)
|
53 |
{
|
@@ -63,15 +77,16 @@ class SettingsController extends shortPixelController
|
|
63 |
$this->loadEnv();
|
64 |
$this->checkPost();
|
65 |
|
66 |
-
Log::addDebug($this->postData);
|
67 |
if ($this->is_form_submit && isset($this->postData['apiKey']))
|
68 |
{
|
69 |
-
$this->
|
70 |
-
|
|
|
71 |
{
|
72 |
$this->model->apiKey = $this->postData['apiKey'];
|
73 |
$this->model->verifiedKey = $this->postData['verifiedKey'];
|
74 |
-
}
|
75 |
}
|
76 |
|
77 |
$this->doRedirect();
|
@@ -91,12 +106,26 @@ class SettingsController extends shortPixelController
|
|
91 |
$nextgen->nextGenEnabled($previous);
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
// write checked and verified post data to model. With normal models, this should just be call to update() function
|
95 |
foreach($this->postData as $name => $value)
|
96 |
{
|
97 |
$this->model->{$name} = $value;
|
98 |
}
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
// end
|
101 |
if ($this->do_redirect)
|
102 |
$this->doRedirect('bulk');
|
@@ -108,7 +137,9 @@ class SettingsController extends shortPixelController
|
|
108 |
/* Loads the view data and the view */
|
109 |
public function load_settings()
|
110 |
{
|
111 |
-
$this->
|
|
|
|
|
112 |
$this->view->data = (Object) $this->model->getData();
|
113 |
if (($this->is_constant_key))
|
114 |
$this->view->data->apiKey = SHORTPIXEL_API_KEY;
|
@@ -122,65 +153,77 @@ class SettingsController extends shortPixelController
|
|
122 |
if (is_wp_error($this->view->resources))
|
123 |
$this->view->resources = null;
|
124 |
|
|
|
|
|
|
|
125 |
$this->loadView('view-settings');
|
126 |
}
|
127 |
|
128 |
/** Checks on things and set them for information. */
|
129 |
-
|
130 |
{
|
131 |
-
$
|
132 |
-
$this->is_gd_installed = function_exists('imagecreatefrompng');
|
133 |
-
$this->is_curl_installed = function_exists('curl_init');
|
134 |
|
135 |
-
$this->
|
|
|
|
|
136 |
|
137 |
-
$this->
|
138 |
-
$this->is_mainsite = is_main_site();
|
139 |
|
140 |
-
$this->
|
|
|
|
|
141 |
|
142 |
$this->display_part = isset($_GET['part']) ? sanitize_text_field($_GET['part']) : 'settings';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
}
|
144 |
|
145 |
/** Check if everything is OK with the Key **/
|
146 |
-
public function checkKey()
|
147 |
{
|
148 |
-
|
149 |
-
|
150 |
|
151 |
$verified_key = $this->model->verifiedKey;
|
152 |
$this->is_verifiedkey = ($verified_key) ? true : false;
|
153 |
|
154 |
$key_in_db = $this->model->apiKey;
|
155 |
|
156 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
if($this->is_constant_key)
|
158 |
{
|
159 |
-
if (
|
160 |
-
{
|
161 |
-
$this->noticeApiKeyLength(SHORTPIXEL_API_KEY);
|
162 |
-
}
|
163 |
-
elseif ($key_in_db != SHORTPIXEL_API_KEY)
|
164 |
{
|
165 |
$this->validateKey(SHORTPIXEL_API_KEY);
|
166 |
}
|
167 |
}
|
168 |
elseif ($this->postkey_needs_validation)
|
169 |
{
|
170 |
-
|
171 |
-
if (strlen($key) <> 20)
|
172 |
-
{
|
173 |
-
$this->NoticeApiKeyLength($key);
|
174 |
-
}
|
175 |
-
else // key good to go.
|
176 |
-
{
|
177 |
$this->validateKey($key);
|
178 |
-
|
179 |
} // postkey_needs_validation
|
180 |
-
}
|
181 |
|
182 |
/** Check remotely if key is alright **/
|
183 |
-
public function validateKey($key)
|
184 |
{
|
185 |
Log::addDebug('Validating Key ' . $key);
|
186 |
// first, save Auth to satisfy getquotainformation
|
@@ -193,62 +236,17 @@ class SettingsController extends shortPixelController
|
|
193 |
}
|
194 |
}
|
195 |
|
196 |
-
|
197 |
-
$this->is_verifiedkey = ($this->quotaData['APIKeyValid']) ? true : false;
|
198 |
-
|
199 |
-
Log::addDebug('Verify Result', $this->quotaData);
|
200 |
-
|
201 |
-
if ($this->is_form_submit) // are we saving a form?
|
202 |
{
|
203 |
-
|
204 |
-
$this->postData['apiKey'] = $key;
|
205 |
-
}
|
206 |
-
else { // if not, put it to the model directly.
|
207 |
-
$this->model->verifiedKey = $this->is_verifiedkey;
|
208 |
-
$this->model->apiKey = $key;
|
209 |
-
}
|
210 |
-
|
211 |
-
|
212 |
-
if (! $this->is_verifiedkey)
|
213 |
-
{
|
214 |
-
Notice::addError(sprintf(__('Error during verifying API key: %s','shortpixel-image-optimizer'), $this->quotaData['Message'] ));
|
215 |
}
|
216 |
elseif ($this->is_form_submit) {
|
217 |
$this->processNewKey();
|
218 |
}
|
219 |
|
220 |
-
}
|
221 |
-
|
222 |
-
/** Process some things when key has been added. This is from original wp-short-pixel.php */
|
223 |
-
protected function processNewKey()
|
224 |
-
{
|
225 |
-
$lastStatus = $this->model->bulkLastStatus;
|
226 |
-
if(isset($lastStatus['Status']) && $lastStatus['Status'] == \ShortPixelAPI::STATUS_NO_KEY) {
|
227 |
-
$this->model->bulkLastStatus = null;
|
228 |
-
}
|
229 |
-
//display notification
|
230 |
-
$urlParts = explode("/", get_site_url());
|
231 |
-
if( $this->quotaData['DomainCheck'] == 'NOT Accessible'){
|
232 |
-
$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'));
|
233 |
-
Notice::addWarning($notice);
|
234 |
-
} else {
|
235 |
-
if ( function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"))
|
236 |
-
$notice = __("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')
|
237 |
-
. "<BR> <b>define('SHORTPIXEL_API_KEY', '". $this->postData['apiKey'] ."');</b>";
|
238 |
-
else
|
239 |
-
$notice = __('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');
|
240 |
|
241 |
-
Notice::addSuccess($notice);
|
242 |
-
}
|
243 |
|
244 |
-
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
245 |
-
if ( !file_exists(SHORTPIXEL_BACKUP_FOLDER) && ! \ShortPixelFolder::createBackUpFolder() )
|
246 |
-
{
|
247 |
-
$notice = 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'),
|
248 |
-
WP_CONTENT_DIR . '/' . SHORTPIXEL_UPLOADS_NAME );
|
249 |
-
Notice::addError($notice);
|
250 |
-
}
|
251 |
-
}
|
252 |
|
253 |
/* Temporary function to check if HTaccess is writable.
|
254 |
* HTaccess is writable if it exists *and* is_writable, or can be written if directory is writable.
|
@@ -430,7 +428,8 @@ class SettingsController extends shortPixelController
|
|
430 |
protected function processWebP($post)
|
431 |
{
|
432 |
$deliverwebp = 0;
|
433 |
-
|
|
|
434 |
|
435 |
if (isset($post['createWebp']) && $post['createWebp'] == 1)
|
436 |
{
|
@@ -461,7 +460,6 @@ class SettingsController extends shortPixelController
|
|
461 |
\WPShortPixel::alterHtaccess();
|
462 |
}
|
463 |
|
464 |
-
|
465 |
$post['deliverWebp'] = $deliverwebp;
|
466 |
unset($post['deliverWebpAlteringType']);
|
467 |
unset($post['deliverWebpType']);
|
@@ -506,6 +504,7 @@ class SettingsController extends shortPixelController
|
|
506 |
exit();
|
507 |
}
|
508 |
|
|
|
509 |
protected function NoticeApiKeyLength($key)
|
510 |
{
|
511 |
$KeyLength = strlen($key);
|
@@ -519,5 +518,5 @@ class SettingsController extends shortPixelController
|
|
519 |
. __(' or ','shortpixel-image-optimiser')
|
520 |
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.";
|
521 |
Notice::addError($notice);
|
522 |
-
}
|
523 |
}
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
|
4 |
+
use ShortPixel\Notices\NoticeController as Notice;
|
|
|
|
|
5 |
|
6 |
class SettingsController extends shortPixelController
|
7 |
{
|
20 |
|
21 |
protected $quotaData = null;
|
22 |
|
23 |
+
protected $keyModel;
|
24 |
+
|
25 |
protected $mapper = array(
|
26 |
'key' => 'apiKey',
|
27 |
'cmyk2rgb' => 'CMYKtoRGBconversion',
|
28 |
);
|
29 |
|
30 |
protected $display_part = 'settings';
|
31 |
+
protected $form_action = 'save-settings';
|
32 |
|
33 |
public function __construct()
|
34 |
{
|
35 |
// @todo Remove Debug Call
|
36 |
$this->model = new \WPShortPixelSettings();
|
37 |
|
38 |
+
$this->loadModel('apikey');
|
39 |
+
$this->keyModel = new ApiKeyModel();
|
40 |
|
41 |
parent::__construct();
|
42 |
+
}
|
43 |
|
44 |
+
// glue method.
|
45 |
+
public function setShortPixel($pixel)
|
46 |
+
{
|
47 |
+
parent::setShortPixel($pixel);
|
48 |
+
$this->keyModel->shortPixel = $pixel;
|
49 |
+
|
50 |
+
// It's loading here since it can do validation, which requires Shortpixel.
|
51 |
+
// Otherwise this should be loaded on construct.
|
52 |
+
$this->keyModel->loadKey();
|
53 |
+
$this->is_verifiedkey = $this->keyModel->is_verified();
|
54 |
+
$this->is_constant_key = $this->keyModel->is_constant();
|
55 |
+
$this->hide_api_key = $this->keyModel->is_hidden();
|
56 |
}
|
57 |
|
58 |
// default action of controller
|
61 |
$this->loadEnv();
|
62 |
$this->checkPost(); // sets up post data
|
63 |
|
64 |
+
$this->model->redirectedSettings = 2; // Prevents any redirects after loading settings
|
|
|
|
|
65 |
|
66 |
if ($this->is_form_submit)
|
67 |
{
|
77 |
$this->loadEnv();
|
78 |
$this->checkPost();
|
79 |
|
80 |
+
Log::addDebug('Settings Action - addkey ', array($this->is_form_submit, $this->postData) );
|
81 |
if ($this->is_form_submit && isset($this->postData['apiKey']))
|
82 |
{
|
83 |
+
$this->keyModel->resetTried();
|
84 |
+
$this->keyModel->checkKey($this->postData['apiKey']);
|
85 |
+
/*if (isset($this->postData['verifiedKey']) && $this->postData['verifiedKey'])
|
86 |
{
|
87 |
$this->model->apiKey = $this->postData['apiKey'];
|
88 |
$this->model->verifiedKey = $this->postData['verifiedKey'];
|
89 |
+
} */
|
90 |
}
|
91 |
|
92 |
$this->doRedirect();
|
106 |
$nextgen->nextGenEnabled($previous);
|
107 |
}
|
108 |
|
109 |
+
$check_key = false;
|
110 |
+
if (isset($this->postData['apiKey']))
|
111 |
+
{
|
112 |
+
$check_key = $this->postData['apiKey'];
|
113 |
+
unset($this->postData['apiKey']); // unset, since keyModel does the saving.
|
114 |
+
}
|
115 |
+
|
116 |
// write checked and verified post data to model. With normal models, this should just be call to update() function
|
117 |
foreach($this->postData as $name => $value)
|
118 |
{
|
119 |
$this->model->{$name} = $value;
|
120 |
}
|
121 |
|
122 |
+
// first save all other settings ( like http credentials etc ), then check
|
123 |
+
if (! $this->keyModel->is_constant() && $check_key !== false) // don't allow settings key if there is a constant
|
124 |
+
{
|
125 |
+
$this->keyModel->resetTried(); // reset the tried api keys on a specific post request.
|
126 |
+
$this->keyModel->checkKey($check_key);
|
127 |
+
}
|
128 |
+
|
129 |
// end
|
130 |
if ($this->do_redirect)
|
131 |
$this->doRedirect('bulk');
|
137 |
/* Loads the view data and the view */
|
138 |
public function load_settings()
|
139 |
{
|
140 |
+
if ($this->is_verifiedkey) // supress quotaData alerts when handing unset API's.
|
141 |
+
$this->loadQuotaData();
|
142 |
+
|
143 |
$this->view->data = (Object) $this->model->getData();
|
144 |
if (($this->is_constant_key))
|
145 |
$this->view->data->apiKey = SHORTPIXEL_API_KEY;
|
153 |
if (is_wp_error($this->view->resources))
|
154 |
$this->view->resources = null;
|
155 |
|
156 |
+
$settings = $this->shortPixel->getSettings();
|
157 |
+
$this->view->dismissedNotices = $settings->dismissedNotices;
|
158 |
+
|
159 |
$this->loadView('view-settings');
|
160 |
}
|
161 |
|
162 |
/** Checks on things and set them for information. */
|
163 |
+
protected function loadEnv()
|
164 |
{
|
165 |
+
$env = $this->getEnv();
|
|
|
|
|
166 |
|
167 |
+
$this->is_nginx = $env->is_nginx;
|
168 |
+
$this->is_gd_installed = $env->is_gd_installed;
|
169 |
+
$this->is_curl_installed = $env->is_curl_installed;
|
170 |
|
171 |
+
$this->is_htaccess_writable = $this->HTisWritable();
|
|
|
172 |
|
173 |
+
$this->is_multisite = $env->is_multisite;
|
174 |
+
$this->is_mainsite = $env->is_mainsite;
|
175 |
+
$this->has_nextgen = $env->has_nextgen;
|
176 |
|
177 |
$this->display_part = isset($_GET['part']) ? sanitize_text_field($_GET['part']) : 'settings';
|
178 |
+
|
179 |
+
}
|
180 |
+
|
181 |
+
public function getEnv()
|
182 |
+
{
|
183 |
+
$this->loadModel('environment');
|
184 |
+
$env = new EnvironmentModel();
|
185 |
+
|
186 |
+
return $env;
|
187 |
}
|
188 |
|
189 |
/** Check if everything is OK with the Key **/
|
190 |
+
/*public function checkKey()
|
191 |
{
|
192 |
+
//$this->is_constant_key = (defined("SHORTPIXEL_API_KEY")) ? true : false;
|
193 |
+
// $this->hide_api_key = (defined("SHORTPIXEL_HIDE_API_KEY")) ? SHORTPIXEL_HIDE_API_KEY : false;
|
194 |
|
195 |
$verified_key = $this->model->verifiedKey;
|
196 |
$this->is_verifiedkey = ($verified_key) ? true : false;
|
197 |
|
198 |
$key_in_db = $this->model->apiKey;
|
199 |
|
200 |
+
// if form submit, but no validation already pushed, check if api key was changed.
|
201 |
+
if ($this->is_form_submit && ! $this->postkey_needs_validation)
|
202 |
+
{
|
203 |
+
// api key was changed on the form.
|
204 |
+
if ($this->postData['apiKey'] != $key_in_db)
|
205 |
+
{
|
206 |
+
$this->postkey_needs_validation = true;
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
if($this->is_constant_key)
|
211 |
{
|
212 |
+
if ($key_in_db != SHORTPIXEL_API_KEY)
|
|
|
|
|
|
|
|
|
213 |
{
|
214 |
$this->validateKey(SHORTPIXEL_API_KEY);
|
215 |
}
|
216 |
}
|
217 |
elseif ($this->postkey_needs_validation)
|
218 |
{
|
219 |
+
$key = isset($this->postData['apiKey']) ? $this->postData['apiKey'] : $this->model->apiKey;
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
$this->validateKey($key);
|
221 |
+
|
222 |
} // postkey_needs_validation
|
223 |
+
} */
|
224 |
|
225 |
/** Check remotely if key is alright **/
|
226 |
+
/*public function validateKey($key)
|
227 |
{
|
228 |
Log::addDebug('Validating Key ' . $key);
|
229 |
// first, save Auth to satisfy getquotainformation
|
236 |
}
|
237 |
}
|
238 |
|
239 |
+
/*if (! $this->is_verifiedkey)
|
|
|
|
|
|
|
|
|
|
|
240 |
{
|
241 |
+
Notice::addError(sprintf(__('Error during verifying API key: %s','shortpixel-image-optimiser'), $this->quotaData['Message'] ));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
}
|
243 |
elseif ($this->is_form_submit) {
|
244 |
$this->processNewKey();
|
245 |
}
|
246 |
|
247 |
+
} */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
|
|
|
|
|
249 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
|
251 |
/* Temporary function to check if HTaccess is writable.
|
252 |
* HTaccess is writable if it exists *and* is_writable, or can be written if directory is writable.
|
428 |
protected function processWebP($post)
|
429 |
{
|
430 |
$deliverwebp = 0;
|
431 |
+
if (! $this->is_nginx)
|
432 |
+
\WPShortPixel::alterHtaccess(true); // always remove the statements.
|
433 |
|
434 |
if (isset($post['createWebp']) && $post['createWebp'] == 1)
|
435 |
{
|
460 |
\WPShortPixel::alterHtaccess();
|
461 |
}
|
462 |
|
|
|
463 |
$post['deliverWebp'] = $deliverwebp;
|
464 |
unset($post['deliverWebpAlteringType']);
|
465 |
unset($post['deliverWebpType']);
|
504 |
exit();
|
505 |
}
|
506 |
|
507 |
+
/*
|
508 |
protected function NoticeApiKeyLength($key)
|
509 |
{
|
510 |
$KeyLength = strlen($key);
|
518 |
. __(' or ','shortpixel-image-optimiser')
|
519 |
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.";
|
520 |
Notice::addError($notice);
|
521 |
+
} */
|
522 |
}
|
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
use ShortPixel\ShortPixelLogger as Log;
|
3 |
|
4 |
|
5 |
class ShortPixelCustomMetaDao {
|
@@ -482,6 +482,7 @@ class ShortPixelCustomMetaDao {
|
|
482 |
$tableSuffix = "";
|
483 |
$tableSuffix = $metaClass::TABLE_SUFFIX;
|
484 |
$prefix = $this->db->getPrefix();
|
|
|
485 |
// eval( '$tableSuffix = ' . $metaClass . '::TABLE_SUFFIX;'); // horror!
|
486 |
$sql = "UPDATE " . $prefix . "shortpixel_" . $tableSuffix . " SET ";
|
487 |
foreach(self::$fields[$tableSuffix] as $field => $type) {
|
@@ -500,12 +501,14 @@ class ShortPixelCustomMetaDao {
|
|
500 |
$sql = rtrim($sql, ",");
|
501 |
$sql .= " WHERE id = %d";
|
502 |
$params[] = $meta->getId();
|
|
|
503 |
$this->db->query($sql, $params);
|
504 |
}
|
505 |
|
506 |
public function delete($meta) {
|
507 |
$metaClass = get_class($meta);
|
508 |
$tableSuffix = "";
|
|
|
509 |
eval( '$tableSuffix = ' . $metaClass . '::TABLE_SUFFIX;');
|
510 |
$sql = "DELETE FROM {$this->db->getPrefix()}shortpixel_" . $tableSuffix . " WHERE id = %d";
|
511 |
$this->db->query($sql, array($meta->getId()));
|
1 |
<?php
|
2 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
3 |
|
4 |
|
5 |
class ShortPixelCustomMetaDao {
|
482 |
$tableSuffix = "";
|
483 |
$tableSuffix = $metaClass::TABLE_SUFFIX;
|
484 |
$prefix = $this->db->getPrefix();
|
485 |
+
|
486 |
// eval( '$tableSuffix = ' . $metaClass . '::TABLE_SUFFIX;'); // horror!
|
487 |
$sql = "UPDATE " . $prefix . "shortpixel_" . $tableSuffix . " SET ";
|
488 |
foreach(self::$fields[$tableSuffix] as $field => $type) {
|
501 |
$sql = rtrim($sql, ",");
|
502 |
$sql .= " WHERE id = %d";
|
503 |
$params[] = $meta->getId();
|
504 |
+
Log::addDebug('Update Custom Meta' . $sql, $params);
|
505 |
$this->db->query($sql, $params);
|
506 |
}
|
507 |
|
508 |
public function delete($meta) {
|
509 |
$metaClass = get_class($meta);
|
510 |
$tableSuffix = "";
|
511 |
+
// @todo Why O why
|
512 |
eval( '$tableSuffix = ' . $metaClass . '::TABLE_SUFFIX;');
|
513 |
$sql = "DELETE FROM {$this->db->getPrefix()}shortpixel_" . $tableSuffix . " WHERE id = %d";
|
514 |
$this->db->query($sql, array($meta->getId()));
|
@@ -3,13 +3,13 @@
|
|
3 |
class ShortPixelMetaFacade {
|
4 |
const MEDIA_LIBRARY_TYPE = 1;
|
5 |
const CUSTOM_TYPE = 2;
|
6 |
-
|
7 |
private $ID;
|
8 |
private $type;
|
9 |
private $meta;
|
10 |
private $spMetaDao;
|
11 |
private $rawMeta;
|
12 |
-
|
13 |
public function __construct($ID) {
|
14 |
if(strpos($ID, 'C-') === 0) {
|
15 |
$this->ID = substr($ID, 2);
|
@@ -17,14 +17,14 @@ class ShortPixelMetaFacade {
|
|
17 |
} else {
|
18 |
$this->ID = $ID;
|
19 |
$this->type = self::MEDIA_LIBRARY_TYPE;
|
20 |
-
}
|
21 |
$this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb());
|
22 |
}
|
23 |
-
|
24 |
public static function getNewFromRow($item) {
|
25 |
-
return new ShortPixelMetaFacade("C-" . $item->id);
|
26 |
}
|
27 |
-
|
28 |
function setRawMeta($rawMeta) {
|
29 |
if($this->type == self::MEDIA_LIBRARY_TYPE) {
|
30 |
$this->rawMeta = $rawMeta;
|
@@ -40,11 +40,11 @@ class ShortPixelMetaFacade {
|
|
40 |
$rawMeta = $this->sanitizeMeta(wp_get_attachment_metadata($this->ID));
|
41 |
$this->meta = self::rawMetaToMeta($this->ID, $rawMeta);
|
42 |
$this->rawMeta = $rawMeta;
|
43 |
-
}
|
44 |
}
|
45 |
return $this->meta;
|
46 |
}
|
47 |
-
|
48 |
private static function rawMetaToMeta($ID, $rawMeta) {
|
49 |
$path = get_attached_file($ID);
|
50 |
return new ShortPixelMeta(array(
|
@@ -55,7 +55,7 @@ class ShortPixelMetaFacade {
|
|
55 |
"thumbs" => (isset($rawMeta["sizes"]) ? $rawMeta["sizes"] : array()),
|
56 |
"message" =>(isset($rawMeta["ShortPixelImprovement"]) ? $rawMeta["ShortPixelImprovement"] : null),
|
57 |
"png2jpg" => (isset($rawMeta["ShortPixelPng2Jpg"]) ? $rawMeta["ShortPixelPng2Jpg"] : false),
|
58 |
-
"compressionType" =>(isset($rawMeta["ShortPixel"]["type"])
|
59 |
? ($rawMeta["ShortPixel"]["type"] == 'glossy' ? 2 : ($rawMeta["ShortPixel"]["type"] == "lossy" ? 1 : 0) )
|
60 |
: null),
|
61 |
"thumbsOpt" =>(isset($rawMeta["ShortPixel"]["thumbsOpt"]) ? $rawMeta["ShortPixel"]["thumbsOpt"] : null),
|
@@ -66,12 +66,12 @@ class ShortPixelMetaFacade {
|
|
66 |
"thumbsTodo" =>(isset($rawMeta["ShortPixel"]["thumbsTodo"]) ? $rawMeta["ShortPixel"]["thumbsTodo"] : false),
|
67 |
"tsOptimized" => (isset($rawMeta["ShortPixel"]["date"]) ? $rawMeta["ShortPixel"]["date"] : false),
|
68 |
"backup" => !isset($rawMeta['ShortPixel']['NoBackup']),
|
69 |
-
"status" => (!isset($rawMeta["ShortPixel"]) ? 0
|
70 |
-
: (isset($rawMeta["ShortPixelImprovement"]) && is_numeric($rawMeta["ShortPixelImprovement"])
|
71 |
-
&& !( $rawMeta['ShortPixelImprovement'] == 0
|
72 |
-
&& ( isset($rawMeta['ShortPixel']['WaitingProcessing'])
|
73 |
-
|| isset($rawMeta['ShortPixel']['date']) && $rawMeta['ShortPixel']['date'] == '1970-01-01')) ? 2
|
74 |
-
: (isset($rawMeta["ShortPixel"]["WaitingProcessing"]) ? 1
|
75 |
: (isset($rawMeta["ShortPixel"]['ErrCode']) ? $rawMeta["ShortPixel"]['ErrCode'] : -500)))),
|
76 |
"retries" =>(isset($rawMeta["ShortPixel"]["Retries"]) ? $rawMeta["ShortPixel"]["Retries"] : 0),
|
77 |
));
|
@@ -83,9 +83,9 @@ class ShortPixelMetaFacade {
|
|
83 |
return $this->meta;
|
84 |
} else {
|
85 |
return wp_get_attachment_url($this->ID);
|
86 |
-
}
|
87 |
}
|
88 |
-
|
89 |
static function sanitizeMeta($rawMeta, $createSPArray = true){
|
90 |
if(!is_array($rawMeta)) {
|
91 |
if($rawMeta == '') { return $createSPArray ? array('ShortPixel' => array()) : array(); }
|
@@ -99,7 +99,7 @@ class ShortPixelMetaFacade {
|
|
99 |
}
|
100 |
return $rawMeta;
|
101 |
}
|
102 |
-
|
103 |
function updateMeta($newMeta = null, $replaceThumbs = false) {
|
104 |
if($newMeta) {
|
105 |
$this->meta = $newMeta;
|
@@ -117,7 +117,7 @@ class ShortPixelMetaFacade {
|
|
117 |
|
118 |
if(isset($rawMeta['sizes']) && is_array($rawMeta['sizes'])) {
|
119 |
if($replaceThumbs) {
|
120 |
-
$rawMeta['sizes'] = $this->meta->getThumbs();
|
121 |
} else {
|
122 |
//use this instead of array_merge because we don't want to duplicate numeric keys
|
123 |
foreach($this->meta->getThumbs() as $key => $val) {
|
@@ -133,7 +133,7 @@ class ShortPixelMetaFacade {
|
|
133 |
} else {
|
134 |
$rawMeta['ShortPixel']['type'] = ShortPixelAPI::getCompressionTypeName($this->meta->getCompressionType());
|
135 |
}
|
136 |
-
|
137 |
if(null === $this->meta->getKeepExif()) {
|
138 |
unset($rawMeta['ShortPixel']['exifKept']);
|
139 |
} else {
|
@@ -145,7 +145,7 @@ class ShortPixelMetaFacade {
|
|
145 |
} else {
|
146 |
$rawMeta['ShortPixel']['date'] = date("Y-m-d H:i:s", strtotime($this->meta->getTsOptimized()));
|
147 |
}
|
148 |
-
|
149 |
//thumbs were processed if settings or if they were explicitely requested
|
150 |
if(null === $this->meta->getThumbsOpt()) {
|
151 |
unset($rawMeta['ShortPixel']['thumbsOpt']);
|
@@ -168,7 +168,7 @@ class ShortPixelMetaFacade {
|
|
168 |
} else {
|
169 |
unset($rawMeta['ShortPixel']['thumbsMissing']);
|
170 |
}
|
171 |
-
|
172 |
if(null === $this->meta->getRetinasOpt()) {
|
173 |
unset($rawMeta['ShortPixel']['retinasOpt']);
|
174 |
} else {
|
@@ -211,9 +211,9 @@ class ShortPixelMetaFacade {
|
|
211 |
$this->rawMeta = $rawMeta;
|
212 |
}
|
213 |
}
|
214 |
-
}
|
215 |
}
|
216 |
-
|
217 |
function cleanupMeta($fakeOptPending = false) {
|
218 |
if($this->type == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
219 |
if(!isset($this->rawMeta)) {
|
@@ -248,7 +248,7 @@ class ShortPixelMetaFacade {
|
|
248 |
unset($this->rawMeta['ShortPixel']);
|
249 |
update_post_meta($this->ID, '_wp_attachment_metadata', $this->rawMeta);
|
250 |
//wp_update_attachment_metadata($this->ID, $this->rawMeta);
|
251 |
-
}
|
252 |
}
|
253 |
|
254 |
function deleteAllSPMeta() {
|
@@ -271,10 +271,10 @@ class ShortPixelMetaFacade {
|
|
271 |
if(!isset($this->rawMeta['ShortPixel'])) {$this->rawMeta['ShortPixel'] = array();}
|
272 |
$this->rawMeta['ShortPixel']['Retries'] = isset($this->rawMeta['ShortPixel']['Retries']) ? $this->rawMeta['ShortPixel']['Retries'] + $count : $count;
|
273 |
$this->meta->setRetries($this->rawMeta['ShortPixel']['Retries']);
|
274 |
-
}
|
275 |
$this->setError($errorCode, $errorMessage);
|
276 |
}
|
277 |
-
|
278 |
function setWaitingProcessing($status = true) {
|
279 |
if($status) {
|
280 |
$this->meta->setStatus(1);
|
@@ -293,9 +293,9 @@ class ShortPixelMetaFacade {
|
|
293 |
}
|
294 |
update_post_meta($this->ID, '_wp_attachment_metadata', $this->rawMeta);
|
295 |
//wp_update_attachment_metadata($this->ID, $this->rawMeta);
|
296 |
-
}
|
297 |
}
|
298 |
-
|
299 |
function setError($errorCode, $errorMessage) {
|
300 |
$this->meta->setMessage(__('Error','shortpixel-image-optimiser') . ': <i>' . $errorMessage . '</i>');
|
301 |
$this->meta->setStatus($errorCode);
|
@@ -311,9 +311,9 @@ class ShortPixelMetaFacade {
|
|
311 |
unset($this->rawMeta['ShortPixel']['WaitingProcessing']);
|
312 |
update_post_meta($this->ID, '_wp_attachment_metadata', $this->rawMeta);
|
313 |
//wp_update_attachment_metadata($this->ID, $this->rawMeta);
|
314 |
-
}
|
315 |
}
|
316 |
-
|
317 |
function setMessage($message) {
|
318 |
$this->meta->setMessage($message);
|
319 |
$this->meta->setStatus(-1);
|
@@ -326,12 +326,12 @@ class ShortPixelMetaFacade {
|
|
326 |
//wp_update_attachment_metadata($this->ID, $this->rawMeta);
|
327 |
}
|
328 |
}
|
329 |
-
|
330 |
public static function getHomeUrl() {
|
331 |
//trim is because we found a site set up with a tab, like this: https://modernpeasantcooking.com\t
|
332 |
return trailingslashit((function_exists("is_multisite") && is_multisite()) ? trim(network_site_url("/")) : trim(home_url()));
|
333 |
}
|
334 |
-
|
335 |
//this is in test
|
336 |
public static function getHomeUrl2() {
|
337 |
return trailingslashit(ShortPixelTools::commonPrefix(self::getHomeUrl(), content_url()));
|
@@ -343,7 +343,7 @@ class ShortPixelMetaFacade {
|
|
343 |
* @throws Exception
|
344 |
*/
|
345 |
public static function safeGetAttachmentUrl($id) {
|
346 |
-
$attURL = wp_get_attachment_url($id);
|
347 |
if(!$attURL || !strlen($attURL)) {
|
348 |
throw new Exception("Post metadata is corrupt (No attachment URL for $id)", ShortPixelAPI::ERR_POSTMETA_CORRUPT);
|
349 |
}
|
@@ -354,17 +354,17 @@ class ShortPixelMetaFacade {
|
|
354 |
return $attURL;//get the file URL
|
355 |
}
|
356 |
}
|
357 |
-
|
358 |
public function getURLsAndPATHs($processThumbnails, $onlyThumbs = false, $addRetina = true, $excludeSizes = array(), $includeOptimized = false) {
|
359 |
$sizesMissing = array();
|
360 |
-
|
361 |
if($this->type == self::CUSTOM_TYPE) {
|
362 |
$meta = $this->getMeta();
|
363 |
|
364 |
//fix for situations where site_url is lala.com/en and home_url is lala.com - if using the site_url will get a duplicated /en in the URL
|
365 |
$homeUrl = self::getHomeUrl();
|
366 |
$urlList[] = self::replaceHomePath($meta->getPath(), $homeUrl);
|
367 |
-
|
368 |
$filePaths[] = $meta->getPath();
|
369 |
} else {
|
370 |
$path = get_attached_file($this->ID);//get the full file PATH
|
@@ -374,7 +374,7 @@ class ShortPixelMetaFacade {
|
|
374 |
|
375 |
if(!$mainExists) {
|
376 |
//try and download the image from the URL (images present only on CDN)
|
377 |
-
$downloadTimeout = max(
|
378 |
$tempOriginal = download_url($url, $downloadTimeout);
|
379 |
if(!is_wp_error( $tempOriginal )) {
|
380 |
$mainExists = @copy($tempOriginal, $path);
|
@@ -388,19 +388,19 @@ class ShortPixelMetaFacade {
|
|
388 |
$this->addRetina($path, $url, $filePaths, $urlList);
|
389 |
}
|
390 |
}
|
391 |
-
|
392 |
$meta = $this->getMeta();
|
393 |
$sizes = $meta->getThumbs();
|
394 |
|
395 |
//it is NOT a PDF file and thumbs are processable
|
396 |
-
if ( /* strtolower(substr($path,strrpos($path, ".")+1)) != "pdf"
|
397 |
-
&&*/ ($processThumbnails || $onlyThumbs)
|
398 |
&& count($sizes))
|
399 |
{
|
400 |
$Tmp = explode("/", SHORTPIXEL_UPLOADS_BASE);
|
401 |
$TmpCount = count($Tmp);
|
402 |
$StichString = $Tmp[$TmpCount-2] . "/" . $Tmp[$TmpCount-1];
|
403 |
-
|
404 |
$count = 1;
|
405 |
foreach( $sizes as $thumbnailName => $thumbnailInfo ) {
|
406 |
|
@@ -419,14 +419,14 @@ class ShortPixelMetaFacade {
|
|
419 |
if(strpos($thumbnailName, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) {
|
420 |
continue;
|
421 |
}
|
422 |
-
|
423 |
if(!$includeOptimized && in_array($thumbnailInfo['file'], $meta->getThumbsOptList())) {
|
424 |
continue;
|
425 |
}
|
426 |
-
|
427 |
if($count >= SHORTPIXEL_MAX_THUMBS) break;
|
428 |
-
$count++;
|
429 |
-
|
430 |
$origPath = $tPath = str_replace(ShortPixelAPI::MB_basename($path), $thumbnailInfo['file'], $path);
|
431 |
$file_exists = apply_filters('shortpixel_image_exists', file_exists($origPath), $origPath, $this->ID);
|
432 |
$tUrl = str_replace(ShortPixelAPI::MB_basename($url), $thumbnailInfo['file'], $url);
|
@@ -440,6 +440,7 @@ class ShortPixelMetaFacade {
|
|
440 |
|
441 |
if ( !$file_exists && !file_exists($tPath) ) {
|
442 |
//try and download the image from the URL (images present only on CDN)
|
|
|
443 |
$tempThumb = download_url($tUrl, $downloadTimeout);
|
444 |
if(!is_wp_error( $tempThumb )) {
|
445 |
if(@copy($tempThumb, $origPath)) {
|
@@ -464,13 +465,13 @@ class ShortPixelMetaFacade {
|
|
464 |
if(!count($sizes)) {
|
465 |
WPShortPixel::log("getURLsAndPATHs: no meta sizes for ID " . $this->ID . " : " . json_encode($this->rawMeta));
|
466 |
}
|
467 |
-
|
468 |
if($onlyThumbs && $mainExists && count($urlList) >= 1) { //remove the main image
|
469 |
array_shift($urlList);
|
470 |
array_shift($filePaths);
|
471 |
-
}
|
472 |
}
|
473 |
-
|
474 |
//convert the + which are replaced with spaces by wp_remote_post
|
475 |
array_walk($urlList, array( &$this, 'replacePlusChar') );
|
476 |
|
@@ -479,11 +480,11 @@ class ShortPixelMetaFacade {
|
|
479 |
//die(var_dump(array("URLs" => $urlList, "PATHs" => $filePaths)));
|
480 |
return array("URLs" => $urlList, "PATHs" => $filePaths, "sizesMissing" => $sizesMissing);
|
481 |
}
|
482 |
-
|
483 |
protected function replacePlusChar(&$url) {
|
484 |
$url = str_replace("+", "%2B", $url);
|
485 |
}
|
486 |
-
|
487 |
protected function addRetina($path, $url, &$fileList, &$urlList) {
|
488 |
$ext = pathinfo($path, PATHINFO_EXTENSION);
|
489 |
$retinaPath = substr($path, 0, strlen($path) - 1 - strlen($ext)) . "@2x." . $ext;
|
@@ -497,18 +498,18 @@ class ShortPixelMetaFacade {
|
|
497 |
$baseName = pathinfo(ShortPixelAPI::MB_basename($path), PATHINFO_FILENAME);
|
498 |
return (substr($baseName, -3) === '@2x');
|
499 |
}
|
500 |
-
|
501 |
public static function getWPMLDuplicates( $id ) {
|
502 |
global $wpdb;
|
503 |
-
|
504 |
$parentId = get_post_meta ($id, '_icl_lang_duplicate_of', true );
|
505 |
if($parentId) $id = $parentId;
|
506 |
-
|
507 |
$mainFile = get_attached_file($id);
|
508 |
|
509 |
$duplicates = $wpdb->get_col( $wpdb->prepare( "
|
510 |
SELECT pm.post_id FROM {$wpdb->postmeta} pm
|
511 |
-
WHERE pm.meta_value = %s AND pm.meta_key = '_icl_lang_duplicate_of'
|
512 |
", $id ) );
|
513 |
|
514 |
//Polylang
|
@@ -548,7 +549,7 @@ class ShortPixelMetaFacade {
|
|
548 |
}
|
549 |
return array_unique($duplicates);
|
550 |
}
|
551 |
-
|
552 |
public static function pathToWebPath($path) {
|
553 |
//$upl = wp_upload_dir();
|
554 |
//return str_replace($upl["basedir"], $upl["baseurl"], $path);
|
@@ -562,11 +563,11 @@ class ShortPixelMetaFacade {
|
|
562 |
$path = implode('/', $pathParts);
|
563 |
return self::filenameToRootRelative($path);
|
564 |
}
|
565 |
-
|
566 |
public static function filenameToRootRelative($path) {
|
567 |
return self::replaceHomePath($path, "");
|
568 |
}
|
569 |
-
|
570 |
private static function replaceHomePath($path, $with) {
|
571 |
if(strpos($path, get_home_path()) === 0) {
|
572 |
return str_replace(get_home_path(), $with, $path);
|
@@ -574,7 +575,7 @@ class ShortPixelMetaFacade {
|
|
574 |
return str_replace(trailingslashit(realpath(get_home_path())), $with, $path);
|
575 |
}
|
576 |
}
|
577 |
-
|
578 |
public function getWebpSizeMeta($path) {
|
579 |
$meta = $this->getMeta();
|
580 |
$thumbs = $meta->getThumbs(); $thumbs = is_array($thumbs) ? $thumbs : array();
|
@@ -591,7 +592,7 @@ class ShortPixelMetaFacade {
|
|
591 |
return false;
|
592 |
}
|
593 |
$size = getimagesize($path);
|
594 |
-
return array('key' => ShortPixelMeta::WEBP_THUMB_PREFIX . 'main',
|
595 |
'val' => array( // it's a file that has no corresponding thumb so it's the WEBP for the main file
|
596 |
'file' => pathinfo(ShortPixelAPI::MB_basename($path), PATHINFO_FILENAME) . '.webp',
|
597 |
'width' => $size[0],
|
@@ -608,30 +609,30 @@ class ShortPixelMetaFacade {
|
|
608 |
$resultQuery = $wpdb->get_results($queryMax);
|
609 |
return $resultQuery[0]->QueryID;
|
610 |
}
|
611 |
-
|
612 |
public static function getMinMediaId() {
|
613 |
global $wpdb;
|
614 |
$queryMax = "SELECT min(post_id) as QueryID FROM " . $wpdb->prefix . "postmeta";
|
615 |
$resultQuery = $wpdb->get_results($queryMax);
|
616 |
return $resultQuery[0]->QueryID;
|
617 |
}
|
618 |
-
|
619 |
public static function isCustomQueuedId($id) {
|
620 |
return substr($id, 0, 2) == "C-";
|
621 |
}
|
622 |
-
|
623 |
public static function stripQueuedIdType($id) {
|
624 |
return intval(substr($id, 2));
|
625 |
}
|
626 |
-
|
627 |
public function getQueuedId() {
|
628 |
return self::queuedId($this->type, $this->ID);
|
629 |
}
|
630 |
-
|
631 |
public static function queuedId($type, $id) {
|
632 |
return ($type == self::CUSTOM_TYPE ? "C-" : "") . $id;
|
633 |
}
|
634 |
-
|
635 |
function getId() {
|
636 |
return $this->ID;
|
637 |
}
|
@@ -647,11 +648,11 @@ class ShortPixelMetaFacade {
|
|
647 |
function setType($type) {
|
648 |
$this->type = $type;
|
649 |
}
|
650 |
-
|
651 |
function getRawMeta() {
|
652 |
return $this->rawMeta;
|
653 |
}
|
654 |
-
|
655 |
/**
|
656 |
* return subdir for that particular attached file - if it's media library then last 3 path items, otherwise substract the uploads path
|
657 |
* Has trailing directory separator (/)
|
@@ -684,7 +685,9 @@ class ShortPixelMetaFacade {
|
|
684 |
}
|
685 |
$hp = wp_normalize_path($homePath);
|
686 |
$file = wp_normalize_path($file);
|
687 |
-
|
|
|
|
|
688 |
if(strstr($file, $hp)) {
|
689 |
$path = str_replace( $hp, "", $file);
|
690 |
} elseif( strstr($file, dirname( WP_CONTENT_DIR ))) { //in some situations the content dir is not inside the root, check this also (ex. single.shortpixel.com)
|
@@ -712,7 +715,7 @@ class ShortPixelMetaFacade {
|
|
712 |
//contains one of the year subfolders of the media library
|
713 |
if(strpos($path, $uploadPath) == 0) {
|
714 |
$pathArr = explode('/', str_replace($uploadBase . '/', "", $path));
|
715 |
-
if( count($pathArr) >= 1
|
716 |
&& is_numeric($pathArr[0]) && $pathArr[0] > 1900 && $pathArr[0] < 2100 //contains the year subfolder
|
717 |
&& ( count($pathArr) == 1 //if there is another subfolder then it's the month subfolder
|
718 |
|| (is_numeric($pathArr[1]) && $pathArr[1] > 0 && $pathArr[1] < 13) )) {
|
@@ -721,7 +724,7 @@ class ShortPixelMetaFacade {
|
|
721 |
}
|
722 |
return false;
|
723 |
}
|
724 |
-
|
725 |
public function optimizationSucceeded() {
|
726 |
if($this->getType() == self::MEDIA_LIBRARY_TYPE) {
|
727 |
do_action( 'shortpixel_image_optimised', $this->getId() );
|
3 |
class ShortPixelMetaFacade {
|
4 |
const MEDIA_LIBRARY_TYPE = 1;
|
5 |
const CUSTOM_TYPE = 2;
|
6 |
+
|
7 |
private $ID;
|
8 |
private $type;
|
9 |
private $meta;
|
10 |
private $spMetaDao;
|
11 |
private $rawMeta;
|
12 |
+
|
13 |
public function __construct($ID) {
|
14 |
if(strpos($ID, 'C-') === 0) {
|
15 |
$this->ID = substr($ID, 2);
|
17 |
} else {
|
18 |
$this->ID = $ID;
|
19 |
$this->type = self::MEDIA_LIBRARY_TYPE;
|
20 |
+
}
|
21 |
$this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb());
|
22 |
}
|
23 |
+
|
24 |
public static function getNewFromRow($item) {
|
25 |
+
return new ShortPixelMetaFacade("C-" . $item->id);
|
26 |
}
|
27 |
+
|
28 |
function setRawMeta($rawMeta) {
|
29 |
if($this->type == self::MEDIA_LIBRARY_TYPE) {
|
30 |
$this->rawMeta = $rawMeta;
|
40 |
$rawMeta = $this->sanitizeMeta(wp_get_attachment_metadata($this->ID));
|
41 |
$this->meta = self::rawMetaToMeta($this->ID, $rawMeta);
|
42 |
$this->rawMeta = $rawMeta;
|
43 |
+
}
|
44 |
}
|
45 |
return $this->meta;
|
46 |
}
|
47 |
+
|
48 |
private static function rawMetaToMeta($ID, $rawMeta) {
|
49 |
$path = get_attached_file($ID);
|
50 |
return new ShortPixelMeta(array(
|
55 |
"thumbs" => (isset($rawMeta["sizes"]) ? $rawMeta["sizes"] : array()),
|
56 |
"message" =>(isset($rawMeta["ShortPixelImprovement"]) ? $rawMeta["ShortPixelImprovement"] : null),
|
57 |
"png2jpg" => (isset($rawMeta["ShortPixelPng2Jpg"]) ? $rawMeta["ShortPixelPng2Jpg"] : false),
|
58 |
+
"compressionType" =>(isset($rawMeta["ShortPixel"]["type"])
|
59 |
? ($rawMeta["ShortPixel"]["type"] == 'glossy' ? 2 : ($rawMeta["ShortPixel"]["type"] == "lossy" ? 1 : 0) )
|
60 |
: null),
|
61 |
"thumbsOpt" =>(isset($rawMeta["ShortPixel"]["thumbsOpt"]) ? $rawMeta["ShortPixel"]["thumbsOpt"] : null),
|
66 |
"thumbsTodo" =>(isset($rawMeta["ShortPixel"]["thumbsTodo"]) ? $rawMeta["ShortPixel"]["thumbsTodo"] : false),
|
67 |
"tsOptimized" => (isset($rawMeta["ShortPixel"]["date"]) ? $rawMeta["ShortPixel"]["date"] : false),
|
68 |
"backup" => !isset($rawMeta['ShortPixel']['NoBackup']),
|
69 |
+
"status" => (!isset($rawMeta["ShortPixel"]) ? 0
|
70 |
+
: (isset($rawMeta["ShortPixelImprovement"]) && is_numeric($rawMeta["ShortPixelImprovement"])
|
71 |
+
&& !( $rawMeta['ShortPixelImprovement'] == 0
|
72 |
+
&& ( isset($rawMeta['ShortPixel']['WaitingProcessing'])
|
73 |
+
|| isset($rawMeta['ShortPixel']['date']) && $rawMeta['ShortPixel']['date'] == '1970-01-01')) ? 2
|
74 |
+
: (isset($rawMeta["ShortPixel"]["WaitingProcessing"]) ? 1
|
75 |
: (isset($rawMeta["ShortPixel"]['ErrCode']) ? $rawMeta["ShortPixel"]['ErrCode'] : -500)))),
|
76 |
"retries" =>(isset($rawMeta["ShortPixel"]["Retries"]) ? $rawMeta["ShortPixel"]["Retries"] : 0),
|
77 |
));
|
83 |
return $this->meta;
|
84 |
} else {
|
85 |
return wp_get_attachment_url($this->ID);
|
86 |
+
}
|
87 |
}
|
88 |
+
|
89 |
static function sanitizeMeta($rawMeta, $createSPArray = true){
|
90 |
if(!is_array($rawMeta)) {
|
91 |
if($rawMeta == '') { return $createSPArray ? array('ShortPixel' => array()) : array(); }
|
99 |
}
|
100 |
return $rawMeta;
|
101 |
}
|
102 |
+
|
103 |
function updateMeta($newMeta = null, $replaceThumbs = false) {
|
104 |
if($newMeta) {
|
105 |
$this->meta = $newMeta;
|
117 |
|
118 |
if(isset($rawMeta['sizes']) && is_array($rawMeta['sizes'])) {
|
119 |
if($replaceThumbs) {
|
120 |
+
$rawMeta['sizes'] = $this->meta->getThumbs();
|
121 |
} else {
|
122 |
//use this instead of array_merge because we don't want to duplicate numeric keys
|
123 |
foreach($this->meta->getThumbs() as $key => $val) {
|
133 |
} else {
|
134 |
$rawMeta['ShortPixel']['type'] = ShortPixelAPI::getCompressionTypeName($this->meta->getCompressionType());
|
135 |
}
|
136 |
+
|
137 |
if(null === $this->meta->getKeepExif()) {
|
138 |
unset($rawMeta['ShortPixel']['exifKept']);
|
139 |
} else {
|
145 |
} else {
|
146 |
$rawMeta['ShortPixel']['date'] = date("Y-m-d H:i:s", strtotime($this->meta->getTsOptimized()));
|
147 |
}
|
148 |
+
|
149 |
//thumbs were processed if settings or if they were explicitely requested
|
150 |
if(null === $this->meta->getThumbsOpt()) {
|
151 |
unset($rawMeta['ShortPixel']['thumbsOpt']);
|
168 |
} else {
|
169 |
unset($rawMeta['ShortPixel']['thumbsMissing']);
|
170 |
}
|
171 |
+
|
172 |
if(null === $this->meta->getRetinasOpt()) {
|
173 |
unset($rawMeta['ShortPixel']['retinasOpt']);
|
174 |
} else {
|
211 |
$this->rawMeta = $rawMeta;
|
212 |
}
|
213 |
}
|
214 |
+
}
|
215 |
}
|
216 |
+
|
217 |
function cleanupMeta($fakeOptPending = false) {
|
218 |
if($this->type == ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE) {
|
219 |
if(!isset($this->rawMeta)) {
|
248 |
unset($this->rawMeta['ShortPixel']);
|
249 |
update_post_meta($this->ID, '_wp_attachment_metadata', $this->rawMeta);
|
250 |
//wp_update_attachment_metadata($this->ID, $this->rawMeta);
|
251 |
+
}
|
252 |
}
|
253 |
|
254 |
function deleteAllSPMeta() {
|
271 |
if(!isset($this->rawMeta['ShortPixel'])) {$this->rawMeta['ShortPixel'] = array();}
|
272 |
$this->rawMeta['ShortPixel']['Retries'] = isset($this->rawMeta['ShortPixel']['Retries']) ? $this->rawMeta['ShortPixel']['Retries'] + $count : $count;
|
273 |
$this->meta->setRetries($this->rawMeta['ShortPixel']['Retries']);
|
274 |
+
}
|
275 |
$this->setError($errorCode, $errorMessage);
|
276 |
}
|
277 |
+
|
278 |
function setWaitingProcessing($status = true) {
|
279 |
if($status) {
|
280 |
$this->meta->setStatus(1);
|
293 |
}
|
294 |
update_post_meta($this->ID, '_wp_attachment_metadata', $this->rawMeta);
|
295 |
//wp_update_attachment_metadata($this->ID, $this->rawMeta);
|
296 |
+
}
|
297 |
}
|
298 |
+
|
299 |
function setError($errorCode, $errorMessage) {
|
300 |
$this->meta->setMessage(__('Error','shortpixel-image-optimiser') . ': <i>' . $errorMessage . '</i>');
|
301 |
$this->meta->setStatus($errorCode);
|
311 |
unset($this->rawMeta['ShortPixel']['WaitingProcessing']);
|
312 |
update_post_meta($this->ID, '_wp_attachment_metadata', $this->rawMeta);
|
313 |
//wp_update_attachment_metadata($this->ID, $this->rawMeta);
|
314 |
+
}
|
315 |
}
|
316 |
+
|
317 |
function setMessage($message) {
|
318 |
$this->meta->setMessage($message);
|
319 |
$this->meta->setStatus(-1);
|
326 |
//wp_update_attachment_metadata($this->ID, $this->rawMeta);
|
327 |
}
|
328 |
}
|
329 |
+
|
330 |
public static function getHomeUrl() {
|
331 |
//trim is because we found a site set up with a tab, like this: https://modernpeasantcooking.com\t
|
332 |
return trailingslashit((function_exists("is_multisite") && is_multisite()) ? trim(network_site_url("/")) : trim(home_url()));
|
333 |
}
|
334 |
+
|
335 |
//this is in test
|
336 |
public static function getHomeUrl2() {
|
337 |
return trailingslashit(ShortPixelTools::commonPrefix(self::getHomeUrl(), content_url()));
|
343 |
* @throws Exception
|
344 |
*/
|
345 |
public static function safeGetAttachmentUrl($id) {
|
346 |
+
$attURL = wp_get_attachment_url($id);
|
347 |
if(!$attURL || !strlen($attURL)) {
|
348 |
throw new Exception("Post metadata is corrupt (No attachment URL for $id)", ShortPixelAPI::ERR_POSTMETA_CORRUPT);
|
349 |
}
|
354 |
return $attURL;//get the file URL
|
355 |
}
|
356 |
}
|
357 |
+
|
358 |
public function getURLsAndPATHs($processThumbnails, $onlyThumbs = false, $addRetina = true, $excludeSizes = array(), $includeOptimized = false) {
|
359 |
$sizesMissing = array();
|
360 |
+
|
361 |
if($this->type == self::CUSTOM_TYPE) {
|
362 |
$meta = $this->getMeta();
|
363 |
|
364 |
//fix for situations where site_url is lala.com/en and home_url is lala.com - if using the site_url will get a duplicated /en in the URL
|
365 |
$homeUrl = self::getHomeUrl();
|
366 |
$urlList[] = self::replaceHomePath($meta->getPath(), $homeUrl);
|
367 |
+
|
368 |
$filePaths[] = $meta->getPath();
|
369 |
} else {
|
370 |
$path = get_attached_file($this->ID);//get the full file PATH
|
374 |
|
375 |
if(!$mainExists) {
|
376 |
//try and download the image from the URL (images present only on CDN)
|
377 |
+
$downloadTimeout = max(SHORTPIXEL_MAX_EXECUTION_TIME - 10, 15);
|
378 |
$tempOriginal = download_url($url, $downloadTimeout);
|
379 |
if(!is_wp_error( $tempOriginal )) {
|
380 |
$mainExists = @copy($tempOriginal, $path);
|
388 |
$this->addRetina($path, $url, $filePaths, $urlList);
|
389 |
}
|
390 |
}
|
391 |
+
|
392 |
$meta = $this->getMeta();
|
393 |
$sizes = $meta->getThumbs();
|
394 |
|
395 |
//it is NOT a PDF file and thumbs are processable
|
396 |
+
if ( /* strtolower(substr($path,strrpos($path, ".")+1)) != "pdf"
|
397 |
+
&&*/ ($processThumbnails || $onlyThumbs)
|
398 |
&& count($sizes))
|
399 |
{
|
400 |
$Tmp = explode("/", SHORTPIXEL_UPLOADS_BASE);
|
401 |
$TmpCount = count($Tmp);
|
402 |
$StichString = $Tmp[$TmpCount-2] . "/" . $Tmp[$TmpCount-1];
|
403 |
+
|
404 |
$count = 1;
|
405 |
foreach( $sizes as $thumbnailName => $thumbnailInfo ) {
|
406 |
|
419 |
if(strpos($thumbnailName, ShortPixelMeta::WEBP_THUMB_PREFIX) === 0) {
|
420 |
continue;
|
421 |
}
|
422 |
+
|
423 |
if(!$includeOptimized && in_array($thumbnailInfo['file'], $meta->getThumbsOptList())) {
|
424 |
continue;
|
425 |
}
|
426 |
+
|
427 |
if($count >= SHORTPIXEL_MAX_THUMBS) break;
|
428 |
+
$count++;
|
429 |
+
|
430 |
$origPath = $tPath = str_replace(ShortPixelAPI::MB_basename($path), $thumbnailInfo['file'], $path);
|
431 |
$file_exists = apply_filters('shortpixel_image_exists', file_exists($origPath), $origPath, $this->ID);
|
432 |
$tUrl = str_replace(ShortPixelAPI::MB_basename($url), $thumbnailInfo['file'], $url);
|
440 |
|
441 |
if ( !$file_exists && !file_exists($tPath) ) {
|
442 |
//try and download the image from the URL (images present only on CDN)
|
443 |
+
$downloadTimeout = max(SHORTPIXEL_MAX_EXECUTION_TIME - 10, 15);
|
444 |
$tempThumb = download_url($tUrl, $downloadTimeout);
|
445 |
if(!is_wp_error( $tempThumb )) {
|
446 |
if(@copy($tempThumb, $origPath)) {
|
465 |
if(!count($sizes)) {
|
466 |
WPShortPixel::log("getURLsAndPATHs: no meta sizes for ID " . $this->ID . " : " . json_encode($this->rawMeta));
|
467 |
}
|
468 |
+
|
469 |
if($onlyThumbs && $mainExists && count($urlList) >= 1) { //remove the main image
|
470 |
array_shift($urlList);
|
471 |
array_shift($filePaths);
|
472 |
+
}
|
473 |
}
|
474 |
+
|
475 |
//convert the + which are replaced with spaces by wp_remote_post
|
476 |
array_walk($urlList, array( &$this, 'replacePlusChar') );
|
477 |
|
480 |
//die(var_dump(array("URLs" => $urlList, "PATHs" => $filePaths)));
|
481 |
return array("URLs" => $urlList, "PATHs" => $filePaths, "sizesMissing" => $sizesMissing);
|
482 |
}
|
483 |
+
|
484 |
protected function replacePlusChar(&$url) {
|
485 |
$url = str_replace("+", "%2B", $url);
|
486 |
}
|
487 |
+
|
488 |
protected function addRetina($path, $url, &$fileList, &$urlList) {
|
489 |
$ext = pathinfo($path, PATHINFO_EXTENSION);
|
490 |
$retinaPath = substr($path, 0, strlen($path) - 1 - strlen($ext)) . "@2x." . $ext;
|
498 |
$baseName = pathinfo(ShortPixelAPI::MB_basename($path), PATHINFO_FILENAME);
|
499 |
return (substr($baseName, -3) === '@2x');
|
500 |
}
|
501 |
+
|
502 |
public static function getWPMLDuplicates( $id ) {
|
503 |
global $wpdb;
|
504 |
+
|
505 |
$parentId = get_post_meta ($id, '_icl_lang_duplicate_of', true );
|
506 |
if($parentId) $id = $parentId;
|
507 |
+
|
508 |
$mainFile = get_attached_file($id);
|
509 |
|
510 |
$duplicates = $wpdb->get_col( $wpdb->prepare( "
|
511 |
SELECT pm.post_id FROM {$wpdb->postmeta} pm
|
512 |
+
WHERE pm.meta_value = %s AND pm.meta_key = '_icl_lang_duplicate_of'
|
513 |
", $id ) );
|
514 |
|
515 |
//Polylang
|
549 |
}
|
550 |
return array_unique($duplicates);
|
551 |
}
|
552 |
+
|
553 |
public static function pathToWebPath($path) {
|
554 |
//$upl = wp_upload_dir();
|
555 |
//return str_replace($upl["basedir"], $upl["baseurl"], $path);
|
563 |
$path = implode('/', $pathParts);
|
564 |
return self::filenameToRootRelative($path);
|
565 |
}
|
566 |
+
|
567 |
public static function filenameToRootRelative($path) {
|
568 |
return self::replaceHomePath($path, "");
|
569 |
}
|
570 |
+
|
571 |
private static function replaceHomePath($path, $with) {
|
572 |
if(strpos($path, get_home_path()) === 0) {
|
573 |
return str_replace(get_home_path(), $with, $path);
|
575 |
return str_replace(trailingslashit(realpath(get_home_path())), $with, $path);
|
576 |
}
|
577 |
}
|
578 |
+
|
579 |
public function getWebpSizeMeta($path) {
|
580 |
$meta = $this->getMeta();
|
581 |
$thumbs = $meta->getThumbs(); $thumbs = is_array($thumbs) ? $thumbs : array();
|
592 |
return false;
|
593 |
}
|
594 |
$size = getimagesize($path);
|
595 |
+
return array('key' => ShortPixelMeta::WEBP_THUMB_PREFIX . 'main',
|
596 |
'val' => array( // it's a file that has no corresponding thumb so it's the WEBP for the main file
|
597 |
'file' => pathinfo(ShortPixelAPI::MB_basename($path), PATHINFO_FILENAME) . '.webp',
|
598 |
'width' => $size[0],
|
609 |
$resultQuery = $wpdb->get_results($queryMax);
|
610 |
return $resultQuery[0]->QueryID;
|
611 |
}
|
612 |
+
|
613 |
public static function getMinMediaId() {
|
614 |
global $wpdb;
|
615 |
$queryMax = "SELECT min(post_id) as QueryID FROM " . $wpdb->prefix . "postmeta";
|
616 |
$resultQuery = $wpdb->get_results($queryMax);
|
617 |
return $resultQuery[0]->QueryID;
|
618 |
}
|
619 |
+
|
620 |
public static function isCustomQueuedId($id) {
|
621 |
return substr($id, 0, 2) == "C-";
|
622 |
}
|
623 |
+
|
624 |
public static function stripQueuedIdType($id) {
|
625 |
return intval(substr($id, 2));
|
626 |
}
|
627 |
+
|
628 |
public function getQueuedId() {
|
629 |
return self::queuedId($this->type, $this->ID);
|
630 |
}
|
631 |
+
|
632 |
public static function queuedId($type, $id) {
|
633 |
return ($type == self::CUSTOM_TYPE ? "C-" : "") . $id;
|
634 |
}
|
635 |
+
|
636 |
function getId() {
|
637 |
return $this->ID;
|
638 |
}
|
648 |
function setType($type) {
|
649 |
$this->type = $type;
|
650 |
}
|
651 |
+
|
652 |
function getRawMeta() {
|
653 |
return $this->rawMeta;
|
654 |
}
|
655 |
+
|
656 |
/**
|
657 |
* return subdir for that particular attached file - if it's media library then last 3 path items, otherwise substract the uploads path
|
658 |
* Has trailing directory separator (/)
|
685 |
}
|
686 |
$hp = wp_normalize_path($homePath);
|
687 |
$file = wp_normalize_path($file);
|
688 |
+
|
689 |
+
// $sp__uploads = wp_upload_dir();
|
690 |
+
|
691 |
if(strstr($file, $hp)) {
|
692 |
$path = str_replace( $hp, "", $file);
|
693 |
} elseif( strstr($file, dirname( WP_CONTENT_DIR ))) { //in some situations the content dir is not inside the root, check this also (ex. single.shortpixel.com)
|
715 |
//contains one of the year subfolders of the media library
|
716 |
if(strpos($path, $uploadPath) == 0) {
|
717 |
$pathArr = explode('/', str_replace($uploadBase . '/', "", $path));
|
718 |
+
if( count($pathArr) >= 1
|
719 |
&& is_numeric($pathArr[0]) && $pathArr[0] > 1900 && $pathArr[0] < 2100 //contains the year subfolder
|
720 |
&& ( count($pathArr) == 1 //if there is another subfolder then it's the month subfolder
|
721 |
|| (is_numeric($pathArr[1]) && $pathArr[1] > 0 && $pathArr[1] < 13) )) {
|
724 |
}
|
725 |
return false;
|
726 |
}
|
727 |
+
|
728 |
public function optimizationSucceeded() {
|
729 |
if($this->getType() == self::MEDIA_LIBRARY_TYPE) {
|
730 |
do_action( 'shortpixel_image_optimised', $this->getId() );
|
@@ -1,4 +1,6 @@
|
|
1 |
<?php
|
|
|
|
|
2 |
|
3 |
class WpShortPixelMediaLbraryAdapter {
|
4 |
|
@@ -233,13 +235,68 @@ class WpShortPixelMediaLbraryAdapter {
|
|
233 |
|
234 |
public static function getPostMetaSlice($startId, $endId, $limit) {
|
235 |
global $wpdb;
|
236 |
-
$
|
|
|
237 |
INNER JOIN " . $wpdb->prefix . "posts p ON p.ID = pm.post_id
|
238 |
WHERE ( p.ID <= $startId AND p.ID >= $endId )
|
239 |
AND ( pm.meta_key = '_wp_attached_file' OR pm.meta_key = '_wp_attachment_metadata' )
|
240 |
ORDER BY pm.post_id DESC
|
241 |
LIMIT " . $limit;
|
242 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
}
|
244 |
|
245 |
public static function getSizesNotExcluded($sizes, $exclude = false) {
|
1 |
<?php
|
2 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
3 |
+
|
4 |
|
5 |
class WpShortPixelMediaLbraryAdapter {
|
6 |
|
235 |
|
236 |
public static function getPostMetaSlice($startId, $endId, $limit) {
|
237 |
global $wpdb;
|
238 |
+
$time = microtime(true);
|
239 |
+
$queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta pm
|
240 |
INNER JOIN " . $wpdb->prefix . "posts p ON p.ID = pm.post_id
|
241 |
WHERE ( p.ID <= $startId AND p.ID >= $endId )
|
242 |
AND ( pm.meta_key = '_wp_attached_file' OR pm.meta_key = '_wp_attachment_metadata' )
|
243 |
ORDER BY pm.post_id DESC
|
244 |
LIMIT " . $limit;
|
245 |
+
$result = $wpdb->get_results($queryPostMeta);
|
246 |
+
$time_end = microtime(true);
|
247 |
+
// Log::addDebug('Post Meta Slice query took ' . ($time_end-$time) . ' sec. - Result count ' . count($result), array( $queryPostMeta));
|
248 |
+
return $result;
|
249 |
+
}
|
250 |
+
|
251 |
+
public static function getPostMetaJoinLess($startId, $endId, $limit)
|
252 |
+
{
|
253 |
+
global $wpdb;
|
254 |
+
$time = microtime(true);
|
255 |
+
$sql = "SELECT ID FROM " . $wpdb->prefix . "posts WHERE ID <= %d AND ID >= %d ORDER BY ID DESC LIMIT %d ";
|
256 |
+
$sql = $wpdb->prepare($sql, $startId, $endId, $limit);
|
257 |
+
$result = $wpdb->get_col($sql);
|
258 |
+
|
259 |
+
if (is_null($result))
|
260 |
+
return array();
|
261 |
+
|
262 |
+
$id_placeholders = implode( ', ', array_fill( 0, count( $result ), '%d'));
|
263 |
+
|
264 |
+
$sqlmeta = "SELECT DISTINCT post_id, meta_key, meta_value FROM " . $wpdb->prefix . "postmeta where (meta_key = %s or meta_key = %s) and post_id in (" . $id_placeholders . ") order by post_id DESC";
|
265 |
+
|
266 |
+
$placeholders = array_merge(array('_wp_attached_file', '_wp_attachment_metadata'), array_values($result));
|
267 |
+
$sqlmeta = $wpdb->prepare($sqlmeta, $placeholders);
|
268 |
+
$metaresult = $wpdb->get_results($sql);
|
269 |
+
|
270 |
+
$time_end = microtime(true);
|
271 |
+
|
272 |
+
// Log::addDebug('Post Meta JoinLESS query took ' . ($time_end-$time) . ' sec. - Result count ' . count($metaresult), array($sql, $sqlmeta));
|
273 |
+
|
274 |
+
return $metaresult;
|
275 |
+
}
|
276 |
+
|
277 |
+
public static function getPostsJoinLessReverse($startId, $endId, $limit)
|
278 |
+
{
|
279 |
+
global $wpdb;
|
280 |
+
$time = microtime(true);
|
281 |
+
|
282 |
+
$sqlmeta = "SELECT DISTINCT post_id FROM " . $wpdb->prefix . "postmeta where (meta_key = %s or meta_key = %s) and post_id <= %d and post_id >= %d order by post_id DESC LIMIT %d";
|
283 |
+
$sqlmeta = $wpdb->prepare($sqlmeta, '_wp_attached_file', '_wp_attachment_metadata', $startId, $endId, $limit);
|
284 |
+
|
285 |
+
$result = $wpdb->get_col($sqlmeta);
|
286 |
+
|
287 |
+
$id_placeholders = implode( ', ', array_fill( 0, count( $result ), '%d'));
|
288 |
+
|
289 |
+
$sql = 'SELECT ID from ' . $wpdb->prefix . 'posts where ID in (' . $id_placeholders . ') ORDER BY ID DESC';
|
290 |
+
$sql = $wpdb->prepare($sql, array_values($result));
|
291 |
+
|
292 |
+
$postresult = $wpdb->get_col($sql);
|
293 |
+
|
294 |
+
$postAr = array_intersect($result, $postresult);
|
295 |
+
|
296 |
+
$time_end = microtime(true);
|
297 |
+
// Log::addDebug('Post Meta JoinLESS **REVERSE** query took ' . ($time_end-$time) . ' sec. - Result count ' . count($postAr), array($sql, $sqlmeta));
|
298 |
+
|
299 |
+
return $postAr;
|
300 |
}
|
301 |
|
302 |
public static function getSizesNotExcluded($sizes, $exclude = false) {
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
/* Prevent Flock Queue on FlyWheel Cloud Hosting due to performance issues.
|
6 |
+
*
|
7 |
+
* Detect Flywheel and set Constant
|
8 |
+
*/
|
9 |
+
|
10 |
+
if (isset($_SERVER['SERVER_SOFTWARE']))
|
11 |
+
{
|
12 |
+
$server = strtolower($_SERVER['SERVER_SOFTWARE']);
|
13 |
+
|
14 |
+
if (strpos($server, 'flywheel') !== false) // server detected
|
15 |
+
{
|
16 |
+
$pos = strpos($server, '/') + 1;
|
17 |
+
|
18 |
+
$version = substr($server, $pos);
|
19 |
+
|
20 |
+
if (version_compare($version, '5.0.0') >= 0)
|
21 |
+
{
|
22 |
+
Log::addInfo('Flywheel detected on ' . $server . ' . Starting NOFLOCK Queue.');
|
23 |
+
if (! defined('SHORTPIXEL_NOFLOCK'))
|
24 |
+
define('SHORTPIXEL_NOFLOCK', 1);
|
25 |
+
}
|
26 |
+
}
|
27 |
+
}
|
@@ -6,6 +6,11 @@ class HelpScout
|
|
6 |
{
|
7 |
public static function outputBeacon($apiKey)
|
8 |
{
|
|
|
|
|
|
|
|
|
|
|
9 |
?>
|
10 |
<style>
|
11 |
.shortpixel-hs-blind {
|
@@ -17,6 +22,31 @@ class HelpScout
|
|
17 |
width: 87px;
|
18 |
height: 174px;
|
19 |
border-radius: 20px 0 0 20px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
.shortpixel-hs-button-blind {
|
22 |
display:none;
|
@@ -49,10 +79,17 @@ class HelpScout
|
|
49 |
}
|
50 |
}
|
51 |
</style>
|
52 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
<div id="shortpixel-hs-button-blind" class="shortpixel-hs-button-blind"></div>
|
54 |
<div id="shortpixel-hs-tools" class="shortpixel-hs-tools">
|
55 |
-
<a href="javascript:shortpixelToggleHS();" class="shortpixel-hs-tools-docs" title="Search through our online documentation.">
|
56 |
<img src="<?php echo(plugins_url('/shortpixel-image-optimiser/res/img/notes-sp.png'));?>" style="margin-bottom: 2px;width: 36px;">
|
57 |
</a>
|
58 |
</div>
|
6 |
{
|
7 |
public static function outputBeacon($apiKey)
|
8 |
{
|
9 |
+
global $shortPixelPluginInstance;
|
10 |
+
$dismissed = $shortPixelPluginInstance->getSettings()->dismissedNotices ? $shortPixelPluginInstance->getSettings()->dismissedNotices : array();
|
11 |
+
if(isset($dismissed['help'])) {
|
12 |
+
return;
|
13 |
+
}
|
14 |
?>
|
15 |
<style>
|
16 |
.shortpixel-hs-blind {
|
22 |
width: 87px;
|
23 |
height: 174px;
|
24 |
border-radius: 20px 0 0 20px;
|
25 |
+
text-align: right;
|
26 |
+
padding-right: 15px;
|
27 |
+
}
|
28 |
+
.shortpixel-hs-blind a {
|
29 |
+
color: lightgray;
|
30 |
+
text-decoration: none;
|
31 |
+
}
|
32 |
+
.shortpixel-hs-blind .dashicons-minus {
|
33 |
+
border: 3px solid;
|
34 |
+
border-radius: 12px;
|
35 |
+
font-size: 12px;
|
36 |
+
font-weight: bold;
|
37 |
+
line-height: 15px;
|
38 |
+
height: 13px;
|
39 |
+
width: 13px;
|
40 |
+
display:none;
|
41 |
+
}
|
42 |
+
.shortpixel-hs-blind .dashicons-dismiss {
|
43 |
+
font-size: 23px;
|
44 |
+
line-height: 19px;
|
45 |
+
display: none;
|
46 |
+
}
|
47 |
+
.shortpixel-hs-blind:hover .dashicons-minus,
|
48 |
+
.shortpixel-hs-blind:hover .dashicons-dismiss {
|
49 |
+
display: inline-block;
|
50 |
}
|
51 |
.shortpixel-hs-button-blind {
|
52 |
display:none;
|
79 |
}
|
80 |
}
|
81 |
</style>
|
82 |
+
<div id="shortpixel-hs-blind" class="shortpixel-hs-blind">
|
83 |
+
<a href="javascript:ShortPixel.closeHelpPane();">
|
84 |
+
<i class="dashicons dashicons-minus" title="<?php _e('Dismiss for now', 'shortpixel-image-optimiser'); ?> "></i>
|
85 |
+
</a>
|
86 |
+
<a href="javascript:ShortPixel.dismissHelpPane();">
|
87 |
+
<i class="dashicons dashicons-dismiss" title="<?php _e('Never display again', 'shortpixel-image-optimiser'); ?>"></i>
|
88 |
+
</a>
|
89 |
+
</div>
|
90 |
<div id="shortpixel-hs-button-blind" class="shortpixel-hs-button-blind"></div>
|
91 |
<div id="shortpixel-hs-tools" class="shortpixel-hs-tools">
|
92 |
+
<a href="javascript:shortpixelToggleHS();" class="shortpixel-hs-tools-docs" title="<?php _e('Search through our online documentation.', 'shortpixel-image-optimiser'); ?>">
|
93 |
<img src="<?php echo(plugins_url('/shortpixel-image-optimiser/res/img/notes-sp.png'));?>" style="margin-bottom: 2px;width: 36px;">
|
94 |
</a>
|
95 |
</div>
|
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
-
use ShortPixel\NoticeController as Notice;
|
4 |
|
5 |
class NextGen
|
6 |
{
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
+
use ShortPixel\Notices\NoticeController as Notice;
|
4 |
|
5 |
class NextGen
|
6 |
{
|
@@ -0,0 +1,330 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
|
3 |
+
|
4 |
+
class ShortPixelQueueDB extends ShortPixelQueue{
|
5 |
+
|
6 |
+
protected $ctrl;
|
7 |
+
protected $settings;
|
8 |
+
|
9 |
+
const THE_OPTION = 'shortpixel_prioq';
|
10 |
+
const THE_TRANSIENT = 'shortpixel_prioq_lock';
|
11 |
+
|
12 |
+
const BULK_TYPE_OPTIMIZE = 0;
|
13 |
+
const BULK_TYPE_RESTORE = 1;
|
14 |
+
const BULK_TYPE_CLEANUP = 2;
|
15 |
+
const BULK_TYPE_CLEANUP_PENDING = 3;
|
16 |
+
|
17 |
+
const BULK_NEVER = 0; //bulk never ran
|
18 |
+
const BULK_RUNNING = 1; //bulk is running
|
19 |
+
const BULK_PAUSED = 2; //bulk is paused
|
20 |
+
const BULK_FINISHED = 3; //bulk finished
|
21 |
+
|
22 |
+
public function __construct($controller, $settings) {
|
23 |
+
$this->ctrl = $controller;
|
24 |
+
$this->settings = $settings;
|
25 |
+
//parent::__construct($controller, $settings);
|
26 |
+
}
|
27 |
+
|
28 |
+
//handling older
|
29 |
+
/* public function ShortPixelQueue($controller) {
|
30 |
+
$this->__construct($controller);
|
31 |
+
}
|
32 |
+
*/
|
33 |
+
|
34 |
+
// @todo Replace
|
35 |
+
public static function get() {
|
36 |
+
$queue = self::openQ(LOCK_SH);
|
37 |
+
if($queue === false) return array();
|
38 |
+
|
39 |
+
Log::addDebug('DBQ - Get ' . $queue);
|
40 |
+
$itemsRaw = $queue;
|
41 |
+
$items = strlen($itemsRaw) ? self::parseQ($itemsRaw) : array();
|
42 |
+
$fp = null;
|
43 |
+
self::closeQ($fp);
|
44 |
+
|
45 |
+
return $items;
|
46 |
+
}
|
47 |
+
|
48 |
+
// @todo Replace
|
49 |
+
public static function set($items) {
|
50 |
+
|
51 |
+
$queue = self::openQ();
|
52 |
+
if($queue === false) return false;
|
53 |
+
|
54 |
+
/* fseek($fp, 0);
|
55 |
+
ftruncate($fp, 0); // truncate file
|
56 |
+
fwrite($fp, implode(',', $items));
|
57 |
+
fflush($fp); // flush output before releasing the lock */
|
58 |
+
Log::addDebug('DBQ - Set ' . implode(',', $items));
|
59 |
+
update_option(self::THE_OPTION, implode(',', $items), false);
|
60 |
+
|
61 |
+
$fp =null;
|
62 |
+
self::closeQ($fp);
|
63 |
+
return true;
|
64 |
+
}
|
65 |
+
|
66 |
+
// @todo Replace
|
67 |
+
public function apply($callable, $extra = false) {
|
68 |
+
$queue = self::openQ();
|
69 |
+
if($queue === false) return false;
|
70 |
+
|
71 |
+
$itemsRaw = $queue;
|
72 |
+
Log::addDebug('Apply' . $itemsRaw);
|
73 |
+
$items = strlen($itemsRaw) ? self::parseQ($itemsRaw) : array();
|
74 |
+
if($extra) {
|
75 |
+
$items = call_user_func($callable, $items, $extra);
|
76 |
+
} else {
|
77 |
+
$items = call_user_func($callable, $items);
|
78 |
+
}
|
79 |
+
|
80 |
+
update_option(self::THE_OPTION, implode(',',$items), false);
|
81 |
+
/*fseek($fp, 0);
|
82 |
+
ftruncate($fp, 0); // truncate file
|
83 |
+
fwrite($fp, implode(',', $items));
|
84 |
+
fflush($fp); // flush output before releasing the lock */
|
85 |
+
$fp = null;
|
86 |
+
self::closeQ($fp);
|
87 |
+
return $items;
|
88 |
+
}
|
89 |
+
|
90 |
+
public static function testQ() {
|
91 |
+
$fp = self::openQ();
|
92 |
+
if($fp === false) return false;
|
93 |
+
self::closeQ($fp);
|
94 |
+
return true;
|
95 |
+
}
|
96 |
+
|
97 |
+
|
98 |
+
// @todo Replace - main thing here.
|
99 |
+
protected static function openQ($lock = LOCK_EX) {
|
100 |
+
|
101 |
+
//$queueName = SHORTPIXEL_UPLOADS_BASE . "/.shortpixel-q-" . get_current_blog_id();
|
102 |
+
$trans = get_transient(self::THE_TRANSIENT);
|
103 |
+
Log::addDebug('OpenQ', array($trans));
|
104 |
+
if (! $trans === false) // if lock, then no beans.
|
105 |
+
return false;
|
106 |
+
|
107 |
+
Log::addDebug('OpenQ -- opened');
|
108 |
+
|
109 |
+
wp_cache_delete( self::THE_OPTION, 'options' ); // ensure uncached goodness here.
|
110 |
+
$queue = get_option(self::THE_OPTION, '');
|
111 |
+
|
112 |
+
set_transient(self::THE_TRANSIENT, 'true', 60);
|
113 |
+
return $queue;
|
114 |
+
|
115 |
+
/* $fp = @fopen($queueName, "r+");
|
116 |
+
if(!$fp) {
|
117 |
+
$fp = @fopen($queueName, "w");
|
118 |
+
if(!$fp) return false;
|
119 |
+
}
|
120 |
+
|
121 |
+
flock($fp, $lock);
|
122 |
+
return $fp; */
|
123 |
+
}
|
124 |
+
|
125 |
+
// @todo replace
|
126 |
+
protected static function closeQ($fp) {
|
127 |
+
Log::addDebug('CloseQ');
|
128 |
+
delete_transient(self::THE_TRANSIENT);
|
129 |
+
|
130 |
+
// flock($fp, LOCK_UN); // release the lock
|
131 |
+
// fclose($fp);
|
132 |
+
}
|
133 |
+
|
134 |
+
public static function resetPrio() {
|
135 |
+
//delete_option( "wp-short-pixel-priorityQueue");
|
136 |
+
self::set(array());
|
137 |
+
}
|
138 |
+
|
139 |
+
public function processing() {
|
140 |
+
//WPShortPixel::log("QUEUE: processing(): get:" . json_encode($this->get()));
|
141 |
+
return $this->bulkRunning() || count($this->get());
|
142 |
+
}
|
143 |
+
|
144 |
+
|
145 |
+
/* protected static function parseQ($items) {
|
146 |
+
return explode(',', preg_replace("/[^0-9,C-]/", "", $items));
|
147 |
+
}
|
148 |
+
*/
|
149 |
+
|
150 |
+
/* public function skip($id) {
|
151 |
+
if(is_array($this->settings->prioritySkip)) {
|
152 |
+
$this->settings->prioritySkip = array_merge($this->settings->prioritySkip, array($id));
|
153 |
+
} else {
|
154 |
+
$this->settings->prioritySkip = array($id);
|
155 |
+
}
|
156 |
+
}
|
157 |
+
*/
|
158 |
+
/* public function unskip($id) {
|
159 |
+
$prioSkip = $this->settings->prioritySkip;
|
160 |
+
$this->settings->prioritySkip = is_array($prioSkip) ? array_diff($prioSkip, array($id)) : array();
|
161 |
+
}
|
162 |
+
*/
|
163 |
+
/* public function allSkipped() {
|
164 |
+
if( !is_array($this->settings->prioritySkip) ) return false;
|
165 |
+
count(array_diff($this->get(), $this->settings->prioritySkip));
|
166 |
+
}
|
167 |
+
*/
|
168 |
+
/* public function skippedCount() {
|
169 |
+
return is_array($this->settings->prioritySkip) ? count($this->settings->prioritySkip) : 0;
|
170 |
+
}
|
171 |
+
*/
|
172 |
+
/* public function isSkipped($id) {
|
173 |
+
return is_array($this->settings->prioritySkip) && in_array($id, $this->settings->prioritySkip);
|
174 |
+
}
|
175 |
+
*/
|
176 |
+
/* public function isPrio($id) {
|
177 |
+
$prioItems = $this->get();
|
178 |
+
return is_array($prioItems) && in_array($id, $prioItems);
|
179 |
+
}
|
180 |
+
*/
|
181 |
+
/* public function getSkipped() {
|
182 |
+
return $this->settings->prioritySkip;
|
183 |
+
}
|
184 |
+
*/
|
185 |
+
/* public function reverse() {
|
186 |
+
$this->apply('array_reverse');
|
187 |
+
//$this->settings->priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"] = array_reverse($_SESSION["wp-short-pixel-priorityQueue"]);
|
188 |
+
|
189 |
+
}
|
190 |
+
*/
|
191 |
+
/* protected function pushCallback($priorityQueue, $ID) {
|
192 |
+
WPShortPixel::log("PUSH: Push ID $ID into queue " . json_encode($priorityQueue));
|
193 |
+
array_push($priorityQueue, $ID);
|
194 |
+
$prioQ = array_unique($priorityQueue);
|
195 |
+
WPShortPixel::log("PUSH: Updated: " . json_encode($prioQ));//get_option("wp-short-pixel-priorityQueue")));
|
196 |
+
return $prioQ;
|
197 |
+
}
|
198 |
+
*/
|
199 |
+
|
200 |
+
/* public function push($ID)//add an ID to priority queue
|
201 |
+
{
|
202 |
+
$this->apply(array(&$this, 'pushCallback'), $ID);
|
203 |
+
}
|
204 |
+
*/
|
205 |
+
/* protected function enqueueCallback($priorityQueue, $ID) {
|
206 |
+
WPShortPixel::log("ENQUEUE: Enqueue ID $ID into queue " . json_encode($priorityQueue));
|
207 |
+
array_unshift($priorityQueue, $ID);
|
208 |
+
$prioQ = array_unique($priorityQueue);
|
209 |
+
WPShortPixel::log("ENQUEUE: Updated: " . json_encode($prioQ));//get_option("wp-short-pixel-priorityQueue")));
|
210 |
+
return $prioQ;
|
211 |
+
}
|
212 |
+
*/
|
213 |
+
/* public function enqueue($ID)//add an ID to priority queue as LAST
|
214 |
+
{
|
215 |
+
$this->apply(array(&$this, 'enqueueCallback'), $ID);
|
216 |
+
}
|
217 |
+
*/
|
218 |
+
/* public function getFirst($count = 1)//return the first values added to priority queue
|
219 |
+
{
|
220 |
+
$priorityQueue = $this->get();
|
221 |
+
$count = min(count($priorityQueue), $count);
|
222 |
+
return(array_slice($priorityQueue, count($priorityQueue) - $count, $count));
|
223 |
+
}
|
224 |
+
*/
|
225 |
+
/* public function getFromPrioAndCheck() {
|
226 |
+
$idsPrio = $this->get();
|
227 |
+
|
228 |
+
$ids = array();
|
229 |
+
$removeIds = array();
|
230 |
+
for($i = count($idsPrio) - 1, $cnt = 0; $i>=0 && $cnt < 3; $i--) {
|
231 |
+
if(!isset($idsPrio[$i])) continue; //saw this situation but then couldn't reproduce it to see the cause, so at least treat the effects.
|
232 |
+
$id = $idsPrio[$i];
|
233 |
+
if(!$this->isSkipped($id) && $this->ctrl->isValidMetaId($id)) {
|
234 |
+
$ids[] = $id; //valid ID
|
235 |
+
$cnt++;
|
236 |
+
} elseif(!$this->isSkipped($id)) {
|
237 |
+
$removeIds[] = $id;//not skipped, url not found, means it's absent, to remove
|
238 |
+
}
|
239 |
+
}
|
240 |
+
foreach($removeIds as $rId){
|
241 |
+
WPShortPixel::log("HIP: Unfound ID $rId Remove from Priority Queue: ".json_encode($this->get()));
|
242 |
+
$this->remove($rId);
|
243 |
+
}
|
244 |
+
return $ids;
|
245 |
+
}
|
246 |
+
*/
|
247 |
+
|
248 |
+
// @todo Replace
|
249 |
+
public function remove($ID)//remove an ID from priority queue
|
250 |
+
{
|
251 |
+
$queue = $this->openQ();
|
252 |
+
if($queue === false) return false;
|
253 |
+
$items = $queue;
|
254 |
+
$items = self::parseQ($items);
|
255 |
+
$items = is_array($items) ? $items : array();
|
256 |
+
$newItems = array();
|
257 |
+
$found = false;
|
258 |
+
foreach($items as $item) { // this instead of array_values(array_diff(.. because we need to know if we actually removed it
|
259 |
+
if($item != $ID) {
|
260 |
+
$newItems[] = $item;
|
261 |
+
} else {
|
262 |
+
$found = true;
|
263 |
+
}
|
264 |
+
}
|
265 |
+
if($found) {
|
266 |
+
/* fseek($fp, 0);
|
267 |
+
ftruncate($fp, 0);
|
268 |
+
fwrite($fp, implode(',', $newItems));
|
269 |
+
fflush($fp); // flush output before releasing the lock */
|
270 |
+
update_option(self::THE_OPTION, implode(',',$newItems), false);
|
271 |
+
Log::addDebug('DBQ - Found and Removing ' . $ID);
|
272 |
+
}
|
273 |
+
$fp = null;
|
274 |
+
$this->closeQ($fp);
|
275 |
+
return $found;
|
276 |
+
}
|
277 |
+
/*
|
278 |
+
public function removeFromFailed($ID) {
|
279 |
+
$failed = explode(",", $this->settings->failedImages);
|
280 |
+
$key = array_search($ID, $failed);
|
281 |
+
if($key !== false) {
|
282 |
+
unset($failed[$key]);
|
283 |
+
$failed = array_values($failed);
|
284 |
+
$this->settings->failedImages = implode(",", $failed) ;
|
285 |
+
}
|
286 |
+
}
|
287 |
+
*/
|
288 |
+
/*
|
289 |
+
public function addToFailed($ID) {
|
290 |
+
$failed = $this->settings->failedImages;
|
291 |
+
if(!in_array($ID, explode(",", $failed))) {
|
292 |
+
$this->settings->failedImages = (strlen($failed) ? $failed . "," : "") . $ID;
|
293 |
+
}
|
294 |
+
}
|
295 |
+
*/
|
296 |
+
|
297 |
+
/*
|
298 |
+
public function getFailed() {
|
299 |
+
$failed = $this->settings->failedImages;
|
300 |
+
if(!strlen($failed)) return array();
|
301 |
+
$ret = explode(",", $failed);
|
302 |
+
$fails = array();
|
303 |
+
foreach($ret as $fail) {
|
304 |
+
if(ShortPixelMetaFacade::isCustomQueuedId($fail)) {
|
305 |
+
$meta = $this->ctrl->getSpMetaDao()->getMeta(ShortPixelMetaFacade::stripQueuedIdType($fail));
|
306 |
+
if($meta) {
|
307 |
+
$fails[] = (object)array("id" => ShortPixelMetaFacade::stripQueuedIdType($fail), "type" => ShortPixelMetaFacade::CUSTOM_TYPE, "meta" => $meta);
|
308 |
+
}
|
309 |
+
} else {
|
310 |
+
$meta = wp_get_attachment_metadata($fail);
|
311 |
+
if(!$meta || (isset($meta["ShortPixelImprovement"]) && is_numeric($meta["ShortPixelImprovement"]))){
|
312 |
+
$this->removeFromFailed($fail);
|
313 |
+
} else {
|
314 |
+
$fails[] = (object)array("id" => $fail, "type" => ShortPixelMetaFacade::MEDIA_LIBRARY_TYPE, "meta" => $meta);
|
315 |
+
}
|
316 |
+
}
|
317 |
+
}
|
318 |
+
return $fails;
|
319 |
+
}
|
320 |
+
*/
|
321 |
+
/*
|
322 |
+
public function bulkRunning() {
|
323 |
+
//$bulkProcessingStatus = get_option('bulkProcessingStatus');
|
324 |
+
return $this->settings->startBulkId > $this->settings->stopBulkId;
|
325 |
+
}
|
326 |
+
*/
|
327 |
+
|
328 |
+
|
329 |
+
|
330 |
+
}
|
@@ -4,8 +4,8 @@
|
|
4 |
* thanks to the Responsify WP plugin for some of the code
|
5 |
*/
|
6 |
|
7 |
-
use ShortPixel\DebugItem as DebugItem;
|
8 |
-
use ShortPixel\ShortPixelLogger as Log;
|
9 |
|
10 |
class ShortPixelImgToPictureWebp
|
11 |
{
|
@@ -28,6 +28,7 @@ class ShortPixelImgToPictureWebp
|
|
28 |
|
29 |
public static function convert($content)
|
30 |
{
|
|
|
31 |
// Don't do anything with the RSS feed.
|
32 |
if (is_feed() || is_admin()) {
|
33 |
Log::addInfo('SPDBG convert is_feed or is_admin');
|
@@ -38,7 +39,7 @@ class ShortPixelImgToPictureWebp
|
|
38 |
if ($new_content !== false)
|
39 |
$content = $new_content;
|
40 |
|
41 |
-
$content = preg_replace_callback('/<img[^>]*>/', array('self', 'convertImage'), $content);
|
42 |
//$content = preg_replace_callback('/background.*[^:](url\(.*\)[,;])/im', array('self', 'convertInlineStyle'), $content);
|
43 |
|
44 |
// [BS] No callback because we need preg_match_all
|
@@ -128,9 +129,6 @@ class ShortPixelImgToPictureWebp
|
|
128 |
$sizes = $sizesInfo['value'];
|
129 |
$sizesPrefix = $sizesInfo['prefix'];
|
130 |
|
131 |
-
$altAttr = isset($img['alt']) && strlen($img['alt']) ? ' alt="' . $img['alt'] . '"' : '';
|
132 |
-
$idAttr = isset($img['id']) && strlen($img['id']) ? ' id="' . $img['id'] . '"' : '';
|
133 |
-
|
134 |
//check if there are webps
|
135 |
/*$id = $thisClass::url_to_attachment_id( $src );
|
136 |
if(!$id) {
|
@@ -179,6 +177,11 @@ class ShortPixelImgToPictureWebp
|
|
179 |
Log::addInfo('SPDBG baseurl doesn\'t match ' . $src);
|
180 |
}
|
181 |
|
|
|
|
|
|
|
|
|
|
|
182 |
|
183 |
// We don't wanna have src-ish attributes on the <picture>
|
184 |
unset($img['src']);
|
@@ -186,8 +189,12 @@ class ShortPixelImgToPictureWebp
|
|
186 |
unset($img['data-lazy-src']);
|
187 |
unset($img['srcset']);
|
188 |
unset($img['sizes']);
|
|
|
189 |
unset($img['alt']);
|
190 |
unset($img['id']);
|
|
|
|
|
|
|
191 |
$srcsetWebP = '';
|
192 |
|
193 |
if ($srcset) {
|
@@ -243,7 +250,7 @@ class ShortPixelImgToPictureWebp
|
|
243 |
return '<picture ' . self::create_attributes($img) . '>'
|
244 |
.'<source ' . $srcsetPrefix . 'srcset="' . $srcsetWebP . '"' . ($sizes ? ' ' . $sizesPrefix . 'sizes="' . $sizes . '"' : '') . ' type="image/webp">'
|
245 |
.'<source ' . $srcsetPrefix . 'srcset="' . $srcset . '"' . ($sizes ? ' ' . $sizesPrefix . 'sizes="' . $sizes . '"' : '') . '>'
|
246 |
-
.'<img ' . $srcPrefix . 'src="' . $src . '" ' . self::create_attributes($img) . $idAttr . $altAttr
|
247 |
. (strlen($srcset) ? ' srcset="' . $srcset . '"': '') . (strlen($sizes) ? ' sizes="' . $sizes . '"': '') . '>'
|
248 |
.'</picture>';
|
249 |
}
|
@@ -403,6 +410,12 @@ class ShortPixelImgToPictureWebp
|
|
403 |
@$dom->loadHTML($image_node);
|
404 |
$image = $dom->getElementsByTagName('img')->item(0);
|
405 |
$attributes = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
foreach ($image->attributes as $attr) {
|
407 |
$attributes[$attr->nodeName] = $attr->nodeValue;
|
408 |
}
|
4 |
* thanks to the Responsify WP plugin for some of the code
|
5 |
*/
|
6 |
|
7 |
+
//use ShortPixel\DebugItem as DebugItem;
|
8 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
9 |
|
10 |
class ShortPixelImgToPictureWebp
|
11 |
{
|
28 |
|
29 |
public static function convert($content)
|
30 |
{
|
31 |
+
|
32 |
// Don't do anything with the RSS feed.
|
33 |
if (is_feed() || is_admin()) {
|
34 |
Log::addInfo('SPDBG convert is_feed or is_admin');
|
39 |
if ($new_content !== false)
|
40 |
$content = $new_content;
|
41 |
|
42 |
+
$content = preg_replace_callback('/<img[^>]*>/i', array('self', 'convertImage'), $content);
|
43 |
//$content = preg_replace_callback('/background.*[^:](url\(.*\)[,;])/im', array('self', 'convertInlineStyle'), $content);
|
44 |
|
45 |
// [BS] No callback because we need preg_match_all
|
129 |
$sizes = $sizesInfo['value'];
|
130 |
$sizesPrefix = $sizesInfo['prefix'];
|
131 |
|
|
|
|
|
|
|
132 |
//check if there are webps
|
133 |
/*$id = $thisClass::url_to_attachment_id( $src );
|
134 |
if(!$id) {
|
177 |
Log::addInfo('SPDBG baseurl doesn\'t match ' . $src);
|
178 |
}
|
179 |
|
180 |
+
//some attributes should not be moved from <img>
|
181 |
+
$altAttr = isset($img['alt']) && strlen($img['alt']) ? ' alt="' . $img['alt'] . '"' : '';
|
182 |
+
$idAttr = isset($img['id']) && strlen($img['id']) ? ' id="' . $img['id'] . '"' : '';
|
183 |
+
$heightAttr = isset($img['height']) && strlen($img['height']) ? ' height="' . $img['height'] . '"' : '';
|
184 |
+
$widthAttr = isset($img['width']) && strlen($img['width']) ? ' width="' . $img['width'] . '"' : '';
|
185 |
|
186 |
// We don't wanna have src-ish attributes on the <picture>
|
187 |
unset($img['src']);
|
189 |
unset($img['data-lazy-src']);
|
190 |
unset($img['srcset']);
|
191 |
unset($img['sizes']);
|
192 |
+
//nor the ones that belong to <img>
|
193 |
unset($img['alt']);
|
194 |
unset($img['id']);
|
195 |
+
unset($img['width']);
|
196 |
+
unset($img['height']);
|
197 |
+
|
198 |
$srcsetWebP = '';
|
199 |
|
200 |
if ($srcset) {
|
250 |
return '<picture ' . self::create_attributes($img) . '>'
|
251 |
.'<source ' . $srcsetPrefix . 'srcset="' . $srcsetWebP . '"' . ($sizes ? ' ' . $sizesPrefix . 'sizes="' . $sizes . '"' : '') . ' type="image/webp">'
|
252 |
.'<source ' . $srcsetPrefix . 'srcset="' . $srcset . '"' . ($sizes ? ' ' . $sizesPrefix . 'sizes="' . $sizes . '"' : '') . '>'
|
253 |
+
.'<img ' . $srcPrefix . 'src="' . $src . '" ' . self::create_attributes($img) . $idAttr . $altAttr . $heightAttr . $widthAttr
|
254 |
. (strlen($srcset) ? ' srcset="' . $srcset . '"': '') . (strlen($sizes) ? ' sizes="' . $sizes . '"': '') . '>'
|
255 |
.'</picture>';
|
256 |
}
|
410 |
@$dom->loadHTML($image_node);
|
411 |
$image = $dom->getElementsByTagName('img')->item(0);
|
412 |
$attributes = array();
|
413 |
+
|
414 |
+
/* This can happen with mismatches, or extremely malformed HTML.
|
415 |
+
In customer case, a javascript that did for (i<imgDefer) --- </script> */
|
416 |
+
if (! is_object($image))
|
417 |
+
return false;
|
418 |
+
|
419 |
foreach ($image->attributes as $attr) {
|
420 |
$attributes[$attr->nodeName] = $attr->nodeValue;
|
421 |
}
|
@@ -0,0 +1,294 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
|
4 |
+
use ShortPixel\Notices\NoticeController as Notice;
|
5 |
+
|
6 |
+
class ApiKeyModel extends ShortPixelModel
|
7 |
+
{
|
8 |
+
|
9 |
+
// variables
|
10 |
+
protected $apiKey;
|
11 |
+
protected $apiKeyTried; // stop retrying the same key over and over if not valid.
|
12 |
+
protected $verifiedKey;
|
13 |
+
protected $redirectedSettings;
|
14 |
+
|
15 |
+
// states
|
16 |
+
// key is verified is set by checkKey *after* checks and validation
|
17 |
+
protected $key_is_verified = false; // this state doesn't have to be the same as the verifiedKey field in DB.
|
18 |
+
protected $key_is_empty = false;
|
19 |
+
protected $key_is_constant = false;
|
20 |
+
protected $key_is_hidden = false;
|
21 |
+
|
22 |
+
protected static $notified = array();
|
23 |
+
|
24 |
+
protected $model = array(
|
25 |
+
'apiKey' => array('s' => 'string',
|
26 |
+
'key' => 'wp-short-pixel-apiKey',
|
27 |
+
),
|
28 |
+
'apiKeyTried' => array('s' => 'string',
|
29 |
+
'key' => 'wp-short-pixel-apiKeyTried'
|
30 |
+
),
|
31 |
+
'verifiedKey' => array('s' => 'boolean',
|
32 |
+
'key' => 'wp-short-pixel-verifiedKey',
|
33 |
+
),
|
34 |
+
'redirectedSettings' => array('s' => 'int',
|
35 |
+
'key' => 'wp-short-pixel-redirected-settings',
|
36 |
+
),
|
37 |
+
);
|
38 |
+
|
39 |
+
public $shortPixel;
|
40 |
+
|
41 |
+
/** Constructor. Check for constants, load the key */
|
42 |
+
public function __construct()
|
43 |
+
{
|
44 |
+
$this->key_is_constant = (defined("SHORTPIXEL_API_KEY")) ? true : false;
|
45 |
+
$this->key_is_hidden = (defined("SHORTPIXEL_HIDE_API_KEY")) ? SHORTPIXEL_HIDE_API_KEY : false;
|
46 |
+
|
47 |
+
}
|
48 |
+
|
49 |
+
/** Load the key from storage. This can be a constant, or the database. Check if key is valid.
|
50 |
+
*
|
51 |
+
*/
|
52 |
+
public function loadKey()
|
53 |
+
{
|
54 |
+
$this->apiKey = get_option($this->model['apiKey']['key'], false);
|
55 |
+
$this->verifiedKey = get_option($this->model['verifiedKey']['key'], false);
|
56 |
+
$this->redirectedSettings = get_option($this->model['redirectedSettings']['key'], false);
|
57 |
+
$this->apiKeyTried = get_option($this->model['apiKeyTried']['key'], false);
|
58 |
+
|
59 |
+
if ($this->key_is_constant)
|
60 |
+
{
|
61 |
+
$key = SHORTPIXEL_API_KEY;
|
62 |
+
}
|
63 |
+
else
|
64 |
+
{
|
65 |
+
$key = $this->apiKey;
|
66 |
+
}
|
67 |
+
|
68 |
+
$valid = $this->checkKey($key);
|
69 |
+
|
70 |
+
|
71 |
+
Log::addDebug('Checked Key', array('valid' => $valid, 'verified' => $this->key_is_verified));
|
72 |
+
return $valid;
|
73 |
+
}
|
74 |
+
|
75 |
+
protected function update()
|
76 |
+
{
|
77 |
+
update_option($this->model['apiKey']['key'], trim($this->apiKey));
|
78 |
+
update_option($this->model['verifiedKey']['key'], $this->verifiedKey);
|
79 |
+
update_option($this->model['redirectedSettings']['key'], $this->redirectedSettings);
|
80 |
+
update_option($this->model['apiKeyTried']['key'], $this->apiKeyTried);
|
81 |
+
Log::addDebug('Update Verified', array($this->apiKey, $this->verifiedKey));
|
82 |
+
}
|
83 |
+
|
84 |
+
/** Resets the last APIkey that was attempted with validation
|
85 |
+
*
|
86 |
+
* The last apikey tried is saved to prevent server and notice spamming when using a constant key, or a wrong key in the database without updating.
|
87 |
+
*/
|
88 |
+
public function resetTried()
|
89 |
+
{
|
90 |
+
if (is_null($this->apiKeyTried))
|
91 |
+
{
|
92 |
+
return; // if already null, no need for additional activity
|
93 |
+
}
|
94 |
+
$this->apiKeyTried = null;
|
95 |
+
$this->update();
|
96 |
+
Log::addDebug('Reset Tried', $this->apiKeyTried);
|
97 |
+
}
|
98 |
+
|
99 |
+
/** Checks the API key to see if we have a validated situation
|
100 |
+
* @param $key String The 20-character Shortpixel API Key or empty string
|
101 |
+
* @return boolean Returns a boolean indicating valid key or not
|
102 |
+
*
|
103 |
+
* An Api key can be removed from the system by passing an empty string when the key is not hidden.
|
104 |
+
* If the key has changed from stored key, the function will pass a validation request to the server
|
105 |
+
* Failing to key a 20char string, or passing an empty key will result in notices.
|
106 |
+
*/
|
107 |
+
public function checkKey($key)
|
108 |
+
{
|
109 |
+
Log::addDebug("Model, checking key ". $key . ' not -' . $this->apiKeyTried);
|
110 |
+
if (strlen($key) == 0)
|
111 |
+
{
|
112 |
+
// first-timers, redirect to nokey screen
|
113 |
+
$this->checkRedirect(); // this should be a one-time thing.
|
114 |
+
if($this->key_is_hidden) // hidden empty keys shouldn't be checked
|
115 |
+
{
|
116 |
+
$this->key_is_verified = $this->verifiedKey;
|
117 |
+
return $this->key_is_verified;
|
118 |
+
}
|
119 |
+
elseif ($key != $this->apiKey)
|
120 |
+
{
|
121 |
+
Notice::addWarning(__('Your API Key has been removed', 'shortpixel-image-optimiser'));
|
122 |
+
$this->clearApiKey(); // notice and remove;
|
123 |
+
return false;
|
124 |
+
}
|
125 |
+
$valid = false;
|
126 |
+
|
127 |
+
}
|
128 |
+
elseif (strlen($key) <> 20 && $key != $this->apiKeyTried)
|
129 |
+
{
|
130 |
+
$this->NoticeApiKeyLength($key);
|
131 |
+
Log::addDebug('Key Wrong Length');
|
132 |
+
$valid = $this->verifiedKey; // if we already had a verified key, and a wrong new one is giving keep status.
|
133 |
+
}
|
134 |
+
elseif( ($key != $this->apiKey || ! $this->verifiedKey) && $key != $this->apiKeyTried)
|
135 |
+
{
|
136 |
+
Log::addDebug('Validate Key' . $key);
|
137 |
+
$valid = $this->validateKey($key);
|
138 |
+
}
|
139 |
+
elseif($key == $this->apiKey) // all is fine!
|
140 |
+
{
|
141 |
+
$valid = $this->verifiedKey;
|
142 |
+
}
|
143 |
+
|
144 |
+
// if key is not valid on load, means not valid at all
|
145 |
+
if (! $valid)
|
146 |
+
{
|
147 |
+
$this->verifiedKey = false;
|
148 |
+
$this->key_is_verified = false;
|
149 |
+
$this->apiKeyTried = $key;
|
150 |
+
$this->update();
|
151 |
+
}
|
152 |
+
else {
|
153 |
+
$this->key_is_verified = true;
|
154 |
+
}
|
155 |
+
|
156 |
+
return $this->key_is_verified; // first time this is set! *after* this function
|
157 |
+
}
|
158 |
+
|
159 |
+
public function is_verified()
|
160 |
+
{
|
161 |
+
return $this->key_is_verified;
|
162 |
+
}
|
163 |
+
|
164 |
+
public function is_constant()
|
165 |
+
{
|
166 |
+
return $this->key_is_constant;
|
167 |
+
}
|
168 |
+
|
169 |
+
public function is_hidden()
|
170 |
+
{
|
171 |
+
return $this->key_is_hidden;
|
172 |
+
}
|
173 |
+
|
174 |
+
public function getKey()
|
175 |
+
{
|
176 |
+
return $this->apiKey;
|
177 |
+
}
|
178 |
+
|
179 |
+
protected function clearApiKey()
|
180 |
+
{
|
181 |
+
$this->key_is_empty = true;
|
182 |
+
$this->apiKey = '';
|
183 |
+
$this->verifiedKey = false;
|
184 |
+
$this->apiKeyTried = '';
|
185 |
+
$this->key_is_verified = false;
|
186 |
+
Log::addDebug('Clearing API Key');
|
187 |
+
|
188 |
+
$this->update();
|
189 |
+
|
190 |
+
}
|
191 |
+
|
192 |
+
protected function validateKey($key)
|
193 |
+
{
|
194 |
+
Log::addDebug('Validating Key ' . $key);
|
195 |
+
// first, save Auth to satisfy getquotainformation
|
196 |
+
|
197 |
+
$quotaData = $this->remoteValidate($key);
|
198 |
+
$checked_key = ($quotaData['APIKeyValid']) ? true : false;
|
199 |
+
|
200 |
+
Log::addDebug('Verify Result', $quotaData);
|
201 |
+
Log::addDebug('Key is verified ', array( $this->verifiedKey));
|
202 |
+
|
203 |
+
if (! $checked_key)
|
204 |
+
{
|
205 |
+
Notice::addError(sprintf(__('Error during verifying API key: %s','shortpixel-image-optimiser'), $quotaData['Message'] ));
|
206 |
+
}
|
207 |
+
elseif ($checked_key) {
|
208 |
+
$this->apiKey = $key;
|
209 |
+
$this->verifiedKey = $checked_key;
|
210 |
+
$this->processNewKey($quotaData);
|
211 |
+
$this->update();
|
212 |
+
}
|
213 |
+
return $this->verifiedKey;
|
214 |
+
}
|
215 |
+
|
216 |
+
|
217 |
+
/** Process some things when key has been added. This is from original wp-short-pixel.php */
|
218 |
+
protected function processNewKey($quotaData)
|
219 |
+
{
|
220 |
+
$settingsObj = $this->shortPixel->getSettings();
|
221 |
+
$lastStatus = $settingsObj->bulkLastStatus;
|
222 |
+
if(isset($lastStatus['Status']) && $lastStatus['Status'] == \ShortPixelAPI::STATUS_NO_KEY) {
|
223 |
+
$settingsObj->bulkLastStatus = null;
|
224 |
+
}
|
225 |
+
//display notification
|
226 |
+
$urlParts = explode("/", get_site_url());
|
227 |
+
if( $quotaData['DomainCheck'] == 'NOT Accessible'){
|
228 |
+
$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'));
|
229 |
+
Notice::addWarning($notice);
|
230 |
+
} else {
|
231 |
+
if ( function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"))
|
232 |
+
$notice = __("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')
|
233 |
+
. "<BR> <b>define('SHORTPIXEL_API_KEY', '". $this->apiKey ."');</b>";
|
234 |
+
else
|
235 |
+
$notice = __('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');
|
236 |
+
|
237 |
+
Notice::addSuccess($notice);
|
238 |
+
}
|
239 |
+
|
240 |
+
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
241 |
+
if ( !file_exists(SHORTPIXEL_BACKUP_FOLDER) && ! \ShortPixelFolder::createBackUpFolder() )
|
242 |
+
{
|
243 |
+
$notice = 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'),
|
244 |
+
WP_CONTENT_DIR . '/' . SHORTPIXEL_UPLOADS_NAME );
|
245 |
+
Notice::addError($notice);
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
|
250 |
+
protected function NoticeApiKeyLength($key)
|
251 |
+
{
|
252 |
+
// repress double warning.
|
253 |
+
if (isset(self::$notified['apilength']) && self::$notified['apilength'])
|
254 |
+
return;
|
255 |
+
|
256 |
+
$KeyLength = strlen($key);
|
257 |
+
$notice = sprintf(__("The key you provided has %s characters. The API key should have 20 characters, letters and numbers only.",'shortpixel-image-optimiser'), $KeyLength)
|
258 |
+
. "<BR> <b>"
|
259 |
+
. __('Please check that the API key is the same as the one you received in your confirmation email.','shortpixel-image-optimiser')
|
260 |
+
. "</b><BR> "
|
261 |
+
. __('If this problem persists, please contact us at ','shortpixel-image-optimiser')
|
262 |
+
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
263 |
+
. __(' or ','shortpixel-image-optimiser')
|
264 |
+
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.";
|
265 |
+
self::$notified['apilength'] = true;
|
266 |
+
Notice::addError($notice);
|
267 |
+
}
|
268 |
+
|
269 |
+
// Does remote Validation of key. In due time should be replaced with something more lean.
|
270 |
+
private function remoteValidate($key)
|
271 |
+
{
|
272 |
+
|
273 |
+
return $this->shortPixel->getQuotaInformation($key, true, true);
|
274 |
+
}
|
275 |
+
|
276 |
+
protected function checkRedirect()
|
277 |
+
{
|
278 |
+
if(!$this->redirectedSettings && !$this->verifiedKey && (!function_exists("is_multisite") || ! is_multisite())) {
|
279 |
+
$this->redirectedSettings = 1;
|
280 |
+
$this->update();
|
281 |
+
wp_redirect(admin_url("options-general.php?page=wp-shortpixel-settings"));
|
282 |
+
exit();
|
283 |
+
}
|
284 |
+
/*elseif (function_exists('is_multisite') && is_multisite() && !$this->_settings->verifiedKey)
|
285 |
+
{ // @todo not optimal, License key needs it's own model to do checks upon.
|
286 |
+
$scontrolname = \shortPixelTools::namespaceit("SettingsController");
|
287 |
+
$scontrol = new $scontrolname();
|
288 |
+
$scontrol->setShortPixel($this);
|
289 |
+
$scontrol->checkKey();
|
290 |
+
} */
|
291 |
+
}
|
292 |
+
|
293 |
+
|
294 |
+
}
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
/* Model for Directories
|
6 |
+
*
|
7 |
+
* For all low-level operations on directories
|
8 |
+
*
|
9 |
+
*/
|
10 |
+
|
11 |
+
class DirectoryModel extends ShortPixelModel
|
12 |
+
{
|
13 |
+
// Directory info
|
14 |
+
protected $path;
|
15 |
+
|
16 |
+
// Directory status
|
17 |
+
protected $exists = false;
|
18 |
+
protected $is_writable = false;
|
19 |
+
|
20 |
+
protected $new_directory_permission = 0755;
|
21 |
+
|
22 |
+
/** Creates a directory model object. DirectoryModel directories don't need to exist on FileSystem */
|
23 |
+
public function __construct($path)
|
24 |
+
{
|
25 |
+
//$this->new_directory_permission = octdec(06440);
|
26 |
+
$this->path = wp_normalize_path(trailingslashit($path));
|
27 |
+
Log::addDebug("DirectoryModel LoadPath - " . $this->path);
|
28 |
+
if (file_exists($this->path))
|
29 |
+
{
|
30 |
+
$this->exists();
|
31 |
+
$this->is_writable();
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
public function __toString()
|
36 |
+
{
|
37 |
+
return (string) $this->path;
|
38 |
+
}
|
39 |
+
|
40 |
+
public function getPath()
|
41 |
+
{
|
42 |
+
return $this->path;
|
43 |
+
}
|
44 |
+
|
45 |
+
public function exists()
|
46 |
+
{
|
47 |
+
$this->exists = file_exists($this->path);
|
48 |
+
return $this->exists;
|
49 |
+
}
|
50 |
+
|
51 |
+
public function is_writable()
|
52 |
+
{
|
53 |
+
$this->is_writable = is_writable($this->path);
|
54 |
+
return $this->is_writable;
|
55 |
+
}
|
56 |
+
|
57 |
+
/** Checks the directory
|
58 |
+
*
|
59 |
+
*/
|
60 |
+
public function check($check_writable = false)
|
61 |
+
{
|
62 |
+
if (! $this->exists())
|
63 |
+
{
|
64 |
+
Log::addDebug('Direct does not exists. Try to create recursive ' . $this->path . ' with ' . $this->new_directory_permission);
|
65 |
+
$result = @mkdir($this->path, $this->new_directory_permission , true);
|
66 |
+
if (! $result)
|
67 |
+
{
|
68 |
+
$error = error_get_last();
|
69 |
+
echo $error['message'];
|
70 |
+
Log::addWarn('MkDir failed: ' . $error['message'], array($error));
|
71 |
+
}
|
72 |
+
|
73 |
+
}
|
74 |
+
if ($this->exists() && $check_writable && ! $this->is_writable())
|
75 |
+
{
|
76 |
+
chmod($this->path, $this->new_directory_permission);
|
77 |
+
}
|
78 |
+
|
79 |
+
if (! $this->exists())
|
80 |
+
{
|
81 |
+
Log::addInfo('Directory does not exist :' . $this->path);
|
82 |
+
return false;
|
83 |
+
}
|
84 |
+
if ($check_writable && !$this->is_writable())
|
85 |
+
{
|
86 |
+
Log::addInfo('Directory not writable :' . $this->path);
|
87 |
+
return false;
|
88 |
+
}
|
89 |
+
return true;
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
}
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
|
4 |
+
class EnvironmentModel extends ShortPixelModel
|
5 |
+
{
|
6 |
+
// Server and PHP
|
7 |
+
public $is_nginx;
|
8 |
+
public $is_apache;
|
9 |
+
public $is_gd_installed;
|
10 |
+
public $is_curl_installed;
|
11 |
+
|
12 |
+
// MultiSite
|
13 |
+
public $is_multisite;
|
14 |
+
public $is_mainsite;
|
15 |
+
|
16 |
+
// Integrations
|
17 |
+
public $has_nextgen;
|
18 |
+
|
19 |
+
public function __construct()
|
20 |
+
{
|
21 |
+
$this->is_nginx = strpos(strtolower($_SERVER["SERVER_SOFTWARE"]), 'nginx') !== false ? true : false;
|
22 |
+
$this->is_apache = strpos(strtolower($_SERVER["SERVER_SOFTWARE"]), 'apache') !== false ? true : false;
|
23 |
+
$this->is_gd_installed = function_exists('imagecreatefrompng');
|
24 |
+
$this->is_curl_installed = function_exists('curl_init');
|
25 |
+
|
26 |
+
$this->is_multisite = (function_exists("is_multisite") && is_multisite()) ? true : false;
|
27 |
+
$this->is_mainsite = is_main_site();
|
28 |
+
|
29 |
+
$this->has_nextgen = \ShortPixelNextGenAdapter::hasNextGen();
|
30 |
+
|
31 |
+
}
|
32 |
+
}
|
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
/* FileModel class.
|
6 |
+
*
|
7 |
+
*
|
8 |
+
* - Represents a -single- file.
|
9 |
+
* - Can handle any type
|
10 |
+
* - Usually controllers would use a collection of files
|
11 |
+
* - Meant for all low-level file operations and checks.
|
12 |
+
* - Every file can have a backup counterpart.
|
13 |
+
*
|
14 |
+
*/
|
15 |
+
class FileModel extends ShortPixelModel
|
16 |
+
{
|
17 |
+
|
18 |
+
// File info
|
19 |
+
protected $fullpath;
|
20 |
+
protected $filename;
|
21 |
+
protected $directory;
|
22 |
+
protected $extension;
|
23 |
+
|
24 |
+
// File Status
|
25 |
+
protected $exists = false;
|
26 |
+
protected $is_writable = false;
|
27 |
+
|
28 |
+
protected $backupDirectory;
|
29 |
+
|
30 |
+
/** Creates a file model object. FileModel files don't need to exist on FileSystem */
|
31 |
+
public function __construct($path)
|
32 |
+
{
|
33 |
+
$this->fullpath = wp_normalize_path($path);
|
34 |
+
$this->setFileInfo();
|
35 |
+
}
|
36 |
+
|
37 |
+
public function __toString()
|
38 |
+
{
|
39 |
+
return (string) $this->fullpath;
|
40 |
+
}
|
41 |
+
|
42 |
+
protected function setFileInfo()
|
43 |
+
{
|
44 |
+
if (file_exists($this->fullpath))
|
45 |
+
{
|
46 |
+
$this->exists = true;
|
47 |
+
$info = pathinfo($this->fullpath);
|
48 |
+
$this->filename = isset($info['basename']) ? $info['basename'] : null;
|
49 |
+
$this->extension = isset($info['extension']) ? $info['extension'] : null;
|
50 |
+
$this->directory = isset($info['dirname']) ? new DirectoryModel($info['dirname']) : null;
|
51 |
+
Log::addDebug('File info', array($info));
|
52 |
+
$this->is_writable = is_writable($this->fullpath);
|
53 |
+
}
|
54 |
+
else {
|
55 |
+
$this->exists = false;
|
56 |
+
$this->writable = false;
|
57 |
+
|
58 |
+
if (is_null($this->filename))
|
59 |
+
$this->filename = basename($this->fullpath);
|
60 |
+
|
61 |
+
if (is_null($this->directory))
|
62 |
+
$this->directory = new DirectoryModel(dirname($this->fullpath));
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
// Util function to get location of backup Directory.
|
67 |
+
private function getBackupDirectory()
|
68 |
+
{
|
69 |
+
if (is_null($this->backupDirectory))
|
70 |
+
{
|
71 |
+
$backup_dir = str_replace(get_home_path(), "", $this->directory->getPath());
|
72 |
+
Log::addDebug('Bkup ' . get_home_path() . ' ' . $this->directory->getPath() . '-->' . $backup_dir );
|
73 |
+
$backupDirectory = SHORTPIXEL_BACKUP_FOLDER . '/' . $backup_dir;
|
74 |
+
$directory = new DirectoryModel($backupDirectory);
|
75 |
+
|
76 |
+
if (! $directory->exists()) // check if exists. FileModel should not attempt to create.
|
77 |
+
return false;
|
78 |
+
|
79 |
+
$this->backupDirectory = $directory;
|
80 |
+
}
|
81 |
+
|
82 |
+
return $this->backupDirectory;
|
83 |
+
}
|
84 |
+
|
85 |
+
public function exists()
|
86 |
+
{
|
87 |
+
$this->exists = file_exists($this->fullpath);
|
88 |
+
return $this->exists;
|
89 |
+
}
|
90 |
+
|
91 |
+
public function is_writable()
|
92 |
+
{
|
93 |
+
$this->is_writable = is_writable($this->fullpath);
|
94 |
+
return $this->is_writable;
|
95 |
+
}
|
96 |
+
|
97 |
+
public function hasBackup()
|
98 |
+
{
|
99 |
+
$directory = $this->getBackupDirectory();
|
100 |
+
if (! $directory)
|
101 |
+
return false;
|
102 |
+
|
103 |
+
$backupFile = $directory . $this->filename;
|
104 |
+
|
105 |
+
if (file_exists($backupFile))
|
106 |
+
return true;
|
107 |
+
else {
|
108 |
+
return false;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
/** Tries to retrieve an *existing* BackupFile. Returns false if not present.
|
113 |
+
* This file might not be writable.
|
114 |
+
* To get writable directory reference to backup, use FileSystemController
|
115 |
+
*/
|
116 |
+
public function getBackupFile()
|
117 |
+
{
|
118 |
+
if ($this->hasBackup())
|
119 |
+
return new FileModel($this->getBackupDirectory() . $this->filename);
|
120 |
+
else
|
121 |
+
return false;
|
122 |
+
}
|
123 |
+
|
124 |
+
public function getFileDir()
|
125 |
+
{
|
126 |
+
return $this->directory;
|
127 |
+
}
|
128 |
+
|
129 |
+
/** Copy a file to somewhere
|
130 |
+
*
|
131 |
+
* @param $destination String Full Path to new file.
|
132 |
+
*/
|
133 |
+
public function copy(FileModel $destination)
|
134 |
+
{
|
135 |
+
$status = copy($this->getFullPath(), $destination->getFullPath());
|
136 |
+
if (! $status)
|
137 |
+
Log::addWarn('Could not copy file ' . $this->getFullPath() . ' to' . $destination->getFullPath());
|
138 |
+
else {
|
139 |
+
$destination->setFileInfo(); // refresh info.
|
140 |
+
}
|
141 |
+
return $status;
|
142 |
+
}
|
143 |
+
|
144 |
+
/** Deletes current file
|
145 |
+
* This uses the WP function since it has a filter that might be useful
|
146 |
+
*/
|
147 |
+
public function delete()
|
148 |
+
{
|
149 |
+
\wp_delete_file($this->fullpath);
|
150 |
+
if (! file_exists($this->fullpath))
|
151 |
+
{
|
152 |
+
$this->setFileInfo(); // update info
|
153 |
+
return true;
|
154 |
+
}
|
155 |
+
else {
|
156 |
+
return false;
|
157 |
+
Log::addWarn('File seems not removed - ' . $this->fullpath);
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
public function getFullPath()
|
162 |
+
{
|
163 |
+
return $this->fullpath;
|
164 |
+
}
|
165 |
+
|
166 |
+
public function getFileName()
|
167 |
+
{
|
168 |
+
return $this->filename;
|
169 |
+
}
|
170 |
+
|
171 |
+
public function getExtension()
|
172 |
+
{
|
173 |
+
return $this->extension;
|
174 |
+
}
|
175 |
+
|
176 |
+
}
|
177 |
+
|
178 |
+
/*
|
179 |
+
// do this before putting the meta down, since maybeDump check for last timestamp
|
180 |
+
$URLsAndPATHs = $itemHandler->getURLsAndPATHs(false);
|
181 |
+
$this->maybeDumpFromProcessedOnServer($itemHandler, $URLsAndPATHs);
|
182 |
+
|
183 |
+
*/
|
@@ -1,8 +1,6 @@
|
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
-
use ShortPixel\ShortPixelLogger as Log;
|
4 |
-
use ShortPixel\DebugItem as DebugItem;
|
5 |
-
|
6 |
|
7 |
abstract class ShortPixelModel
|
8 |
{
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
|
|
|
|
4 |
|
5 |
abstract class ShortPixelModel
|
6 |
{
|
@@ -1,9 +1,10 @@
|
|
1 |
<?php
|
|
|
2 |
|
3 |
class ShortPixelQueue {
|
4 |
|
5 |
-
|
6 |
-
|
7 |
|
8 |
const BULK_TYPE_OPTIMIZE = 0;
|
9 |
const BULK_TYPE_RESTORE = 1;
|
@@ -26,6 +27,7 @@ class ShortPixelQueue {
|
|
26 |
}
|
27 |
|
28 |
public static function get() {
|
|
|
29 |
$fp = self::openQ(LOCK_SH);
|
30 |
if(!$fp) return array();
|
31 |
$itemsRaw = fgets($fp);
|
@@ -71,6 +73,7 @@ class ShortPixelQueue {
|
|
71 |
}
|
72 |
|
73 |
protected static function openQ($lock = LOCK_EX) {
|
|
|
74 |
$queueName = SHORTPIXEL_UPLOADS_BASE . "/.shortpixel-q-" . get_current_blog_id();
|
75 |
$fp = @fopen($queueName, "r+");
|
76 |
if(!$fp) {
|
@@ -343,7 +346,7 @@ class ShortPixelQueue {
|
|
343 |
return $this->settings->bulkType;
|
344 |
}
|
345 |
|
346 |
-
// hack
|
347 |
public function getBulkTypeForDisplay()
|
348 |
{
|
349 |
$bulk = $this->settings->bulkType;
|
@@ -366,7 +369,7 @@ class ShortPixelQueue {
|
|
366 |
$bulkStartId = $this->getFlagBulkId();
|
367 |
$this->settings->cancelPointer = $cancelPointer;//we save this so we can resume bulk processing
|
368 |
$this->settings->skipToCustom = NULL;
|
369 |
-
|
370 |
//remove the bulk items from prio queue
|
371 |
foreach($this->get() as $qItem) {
|
372 |
if($qItem < $bulkStartId) {
|
@@ -378,7 +381,7 @@ class ShortPixelQueue {
|
|
378 |
|
379 |
public function cancelBulk() {
|
380 |
$this->pauseBulk();
|
381 |
-
|
382 |
$this->settings->cancelPointer = NULL;
|
383 |
}
|
384 |
|
1 |
<?php
|
2 |
+
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
|
3 |
|
4 |
class ShortPixelQueue {
|
5 |
|
6 |
+
protected $ctrl;
|
7 |
+
protected $settings;
|
8 |
|
9 |
const BULK_TYPE_OPTIMIZE = 0;
|
10 |
const BULK_TYPE_RESTORE = 1;
|
27 |
}
|
28 |
|
29 |
public static function get() {
|
30 |
+
|
31 |
$fp = self::openQ(LOCK_SH);
|
32 |
if(!$fp) return array();
|
33 |
$itemsRaw = fgets($fp);
|
73 |
}
|
74 |
|
75 |
protected static function openQ($lock = LOCK_EX) {
|
76 |
+
|
77 |
$queueName = SHORTPIXEL_UPLOADS_BASE . "/.shortpixel-q-" . get_current_blog_id();
|
78 |
$fp = @fopen($queueName, "r+");
|
79 |
if(!$fp) {
|
346 |
return $this->settings->bulkType;
|
347 |
}
|
348 |
|
349 |
+
// hack
|
350 |
public function getBulkTypeForDisplay()
|
351 |
{
|
352 |
$bulk = $this->settings->bulkType;
|
369 |
$bulkStartId = $this->getFlagBulkId();
|
370 |
$this->settings->cancelPointer = $cancelPointer;//we save this so we can resume bulk processing
|
371 |
$this->settings->skipToCustom = NULL;
|
372 |
+
Log::addDebug("PAUSE: Pointer = ".$this->settings->cancelPointer);
|
373 |
//remove the bulk items from prio queue
|
374 |
foreach($this->get() as $qItem) {
|
375 |
if($qItem < $bulkStartId) {
|
381 |
|
382 |
public function cancelBulk() {
|
383 |
$this->pauseBulk();
|
384 |
+
Log::addDebug("STOP, delete pointer.");
|
385 |
$this->settings->cancelPointer = NULL;
|
386 |
}
|
387 |
|
@@ -28,7 +28,7 @@
|
|
28 |
if($showApiKey) {
|
29 |
$canValidate = true;?>
|
30 |
<input name="key" type="text" id="key" value="<?php echo( $view->data->apiKey );?>"
|
31 |
-
class="regular-text" <?php echo($editApiKey ? "" : 'disabled') ?>
|
32 |
<?php
|
33 |
}
|
34 |
elseif(defined("SHORTPIXEL_API_KEY")) {
|
@@ -43,10 +43,10 @@
|
|
43 |
<?php } ?>
|
44 |
<input type="hidden" name="validate" id="valid" value=""/>
|
45 |
<span class="spinner" id="pluginemail_spinner" style="float:none;"></span>
|
46 |
-
|
47 |
onclick="ShortPixel.validateKey(this)" <?php echo $canValidate ? "" : "disabled"?> <?php echo $this->is_verifiedkey ? 'style="display:none;"' : '' ?>>
|
48 |
<?php _e('Validate','shortpixel-image-optimiser');?>
|
49 |
-
</button>
|
50 |
<span class="shortpixel-key-valid" <?php echo $this->is_verifiedkey ? '' : 'style="display:none;"' ?>>
|
51 |
<span class="dashicons dashicons-yes"></span><?php _e('Your API key is valid.','shortpixel-image-optimiser');?>
|
52 |
</span>
|
28 |
if($showApiKey) {
|
29 |
$canValidate = true;?>
|
30 |
<input name="key" type="text" id="key" value="<?php echo( $view->data->apiKey );?>"
|
31 |
+
class="regular-text" <?php echo($editApiKey ? "" : 'disabled') ?> >
|
32 |
<?php
|
33 |
}
|
34 |
elseif(defined("SHORTPIXEL_API_KEY")) {
|
43 |
<?php } ?>
|
44 |
<input type="hidden" name="validate" id="valid" value=""/>
|
45 |
<span class="spinner" id="pluginemail_spinner" style="float:none;"></span>
|
46 |
+
<!-- <button type="button" id="validate" class="button button-primary" title="<?php _e('Validate the provided API key','shortpixel-image-optimiser');?>"
|
47 |
onclick="ShortPixel.validateKey(this)" <?php echo $canValidate ? "" : "disabled"?> <?php echo $this->is_verifiedkey ? 'style="display:none;"' : '' ?>>
|
48 |
<?php _e('Validate','shortpixel-image-optimiser');?>
|
49 |
+
</button> -->
|
50 |
<span class="shortpixel-key-valid" <?php echo $this->is_verifiedkey ? '' : 'style="display:none;"' ?>>
|
51 |
<span class="dashicons dashicons-yes"></span><?php _e('Your API key is valid.','shortpixel-image-optimiser');?>
|
52 |
</span>
|
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
-
use ShortPixel\NoticeController as Notice;
|
4 |
-
use ShortPixel\ShortPixelLogger as Log;
|
5 |
|
6 |
$canValidate = false;
|
7 |
// Several conditions for showing API key.
|
@@ -16,9 +16,9 @@ else {
|
|
16 |
$editApiKey = (! $this->is_constant_key && $showApiKey) ? true : false;
|
17 |
|
18 |
// Notices for fringe cases
|
19 |
-
if ($this->hide_api_key && ! $this->is_constant_key)
|
20 |
{
|
21 |
-
Notice::addError(__('wp-config.php
|
22 |
}
|
23 |
elseif ($this->is_constant_key && ! $this->is_verifiedkey)
|
24 |
{
|
@@ -82,7 +82,10 @@ if($adminEmail == 'noreply@addendio.com') $adminEmail = false; //hack for the ad
|
|
82 |
<?php _e('If you already have an API Key please input it below and press Validate.','shortpixel-image-optimiser');?>
|
83 |
</p>
|
84 |
|
85 |
-
<form method="POST" action="<?php echo add_query_arg(array('noheader' => 'true', 'sp-action' => 'action_addkey')) ?>"
|
|
|
|
|
|
|
86 |
<table class="form-table">
|
87 |
<tbody>
|
88 |
<tr>
|
@@ -111,8 +114,8 @@ if($adminEmail == 'noreply@addendio.com') $adminEmail = false; //hack for the ad
|
|
111 |
<?php } ?>
|
112 |
<input type="hidden" name="validate" id="valid" value="validate"/>
|
113 |
<span class="spinner" id="pluginemail_spinner" style="float:none;"></span>
|
114 |
-
<button type="
|
115 |
-
|
116 |
<?php _e('Validate','shortpixel-image-optimiser');?>
|
117 |
</button>
|
118 |
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
+
use ShortPixel\Notices\NoticeController as Notice;
|
4 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
5 |
|
6 |
$canValidate = false;
|
7 |
// Several conditions for showing API key.
|
16 |
$editApiKey = (! $this->is_constant_key && $showApiKey) ? true : false;
|
17 |
|
18 |
// Notices for fringe cases
|
19 |
+
if (! $this->is_verifiedkey && $this->hide_api_key && ! $this->is_constant_key)
|
20 |
{
|
21 |
+
Notice::addError(__('wp-config.php is hiding the API key, but no API key was found. Remove the constant, or define the SHORTPIXEL_API_KEY constant as well', 'shortpixel-image-optimiser'));
|
22 |
}
|
23 |
elseif ($this->is_constant_key && ! $this->is_verifiedkey)
|
24 |
{
|
82 |
<?php _e('If you already have an API Key please input it below and press Validate.','shortpixel-image-optimiser');?>
|
83 |
</p>
|
84 |
|
85 |
+
<form method="POST" action="<?php echo add_query_arg(array('noheader' => 'true', 'sp-action' => 'action_addkey')) ?>"
|
86 |
+
id="shortpixel-form-nokey">
|
87 |
+
<?php wp_nonce_field($this->form_action, 'sp-nonce'); ?>
|
88 |
+
|
89 |
<table class="form-table">
|
90 |
<tbody>
|
91 |
<tr>
|
114 |
<?php } ?>
|
115 |
<input type="hidden" name="validate" id="valid" value="validate"/>
|
116 |
<span class="spinner" id="pluginemail_spinner" style="float:none;"></span>
|
117 |
+
<button type="submit" id="validate" class="button button-primary" title="<?php _e('Validate the provided API key','shortpixel-image-optimiser');?>"
|
118 |
+
>
|
119 |
<?php _e('Validate','shortpixel-image-optimiser');?>
|
120 |
</button>
|
121 |
|
@@ -113,7 +113,15 @@ $quotaData = $this->quotaData;
|
|
113 |
</td>
|
114 |
</tr>
|
115 |
<tr>
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
<?php _e('See report (last 40 days)','shortpixel-image-optimiser');?>
|
118 |
</a></th>
|
119 |
<td> </td>
|
113 |
</td>
|
114 |
</tr>
|
115 |
<tr>
|
116 |
+
<?php
|
117 |
+
|
118 |
+
if ($this->hide_api_key)
|
119 |
+
$link = 'https://shortpixel.com/login';
|
120 |
+
else {
|
121 |
+
$link = 'https://' . SHORTPIXEL_API . '/v2/report.php?key=' . $view->data->apiKey;
|
122 |
+
}
|
123 |
+
?>
|
124 |
+
<th><a href="<?php echo $link ?>" target="_blank">
|
125 |
<?php _e('See report (last 40 days)','shortpixel-image-optimiser');?>
|
126 |
</a></th>
|
127 |
<td> </td>
|
@@ -1,4 +1,6 @@
|
|
1 |
<?php
|
|
|
|
|
2 |
|
3 |
if( ! class_exists( 'WP_List_Table' ) ) {
|
4 |
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
|
@@ -260,15 +262,15 @@ class ShortPixelListTable extends WP_List_Table {
|
|
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() {
|
@@ -291,7 +293,10 @@ class ShortPixelListTable extends WP_List_Table {
|
|
291 |
if (!wp_verify_nonce($nonce, 'sp_restore_image')) {
|
292 |
die('Error.');
|
293 |
} else {
|
294 |
-
$this->action_restore_image(absint($_GET['image']))
|
|
|
|
|
|
|
295 |
wp_redirect($redirect_url);
|
296 |
exit;
|
297 |
}
|
1 |
<?php
|
2 |
+
use ShortPixel\Notices\NoticeController as Notices;
|
3 |
+
|
4 |
|
5 |
if( ! class_exists( 'WP_List_Table' ) ) {
|
6 |
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
|
262 |
}
|
263 |
|
264 |
public function action_optimize_image( $id ) {
|
265 |
+
return $this->ctrl->optimizeCustomImage($id);
|
266 |
}
|
267 |
|
268 |
public function action_restore_image( $id ) {
|
269 |
+
return $this->ctrl->doCustomRestore($id);
|
270 |
}
|
271 |
|
272 |
public function action_redo_image( $id, $type = false ) {
|
273 |
+
return $this->ctrl->redo('C-' . $id, $type);
|
274 |
}
|
275 |
|
276 |
public function process_actions() {
|
293 |
if (!wp_verify_nonce($nonce, 'sp_restore_image')) {
|
294 |
die('Error.');
|
295 |
} else {
|
296 |
+
if($this->action_restore_image(absint($_GET['image'])))
|
297 |
+
{
|
298 |
+
Notices::addSuccess(__('File Successfully restored', 'shortpixel-image-optimiser'));
|
299 |
+
}
|
300 |
wp_redirect($redirect_url);
|
301 |
exit;
|
302 |
}
|
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
use
|
3 |
|
4 |
class ShortPixelView {
|
5 |
|
@@ -153,6 +153,8 @@ class ShortPixelView {
|
|
153 |
echo('<li class="sp-conflict-plugins-list"><strong>' . $plugin['name'] . '</strong>');
|
154 |
echo('<a href="' . $link . '" class="button button-primary">'
|
155 |
. __( $action, 'shortpixel_image_optimiser' ) . '</a>');
|
|
|
|
|
156 |
}
|
157 |
echo("</ul>");
|
158 |
break;
|
@@ -399,7 +401,7 @@ class ShortPixelView {
|
|
399 |
|
400 |
jQuery(".sp-bulk-summary").spTooltip({
|
401 |
tooltipSource: "inline",
|
402 |
-
tooltipSourceID: "#sp-bulk-stats"
|
403 |
});
|
404 |
});
|
405 |
!function(d,s,id){//Just optimized my site with ShortPixel image optimization plugin
|
@@ -422,7 +424,7 @@ class ShortPixelView {
|
|
422 |
</div>
|
423 |
<?php } ?>
|
424 |
</div>
|
425 |
-
<div id="sp-bulk-stats <?php echo $hider ?>
|
426 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
427 |
</div>
|
428 |
</div>
|
@@ -614,6 +616,10 @@ class ShortPixelView {
|
|
614 |
<span class="sp-err-title"><?php _e('Error processing file:','shortpixel-image-optimiser');?><br></span>
|
615 |
<span class="sp-err-content"><?php echo $message; ?></span> <a class="sp-post-link" href="<?php echo(get_admin_url());?>/post.php?post=__ID__&action=edit" target="_blank">placeholder.png</a>
|
616 |
</div>
|
|
|
|
|
|
|
|
|
617 |
</div>
|
618 |
</div>
|
619 |
<div class="bulk-progress bulk-slider-container sp-notice sp-notice-info sp-floating-block sp-full-width">
|
@@ -664,8 +670,7 @@ class ShortPixelView {
|
|
664 |
<?php } ?>
|
665 |
|
666 |
<?php
|
667 |
-
Log::addDebug('
|
668 |
-
Log::addDebug($this->bulkType);
|
669 |
if ($this->bulkType != ShortPixelQueue::BULK_TYPE_RESTORE): ?>
|
670 |
<div class="bulk-progress-indicator">
|
671 |
<div style="margin-bottom:5px"><?php _e('Average reduction','shortpixel-image-optimiser');?></div>
|
@@ -716,7 +721,6 @@ class ShortPixelView {
|
|
716 |
<div class="bulk-estimate">
|
717 |
<?php echo($message);?>
|
718 |
</div>
|
719 |
-
<?php if (true || ($type & 1)) { //now we display the action buttons always when a type of bulk is running ?>
|
720 |
<form action='' method='POST' style="display:inline;">
|
721 |
<input type="submit" class="button button-primary bulk-cancel" onclick="clearBulkProcessor();"
|
722 |
name="bulkProcessStop" value="Stop" style="margin-left:10px"/>
|
@@ -728,9 +732,7 @@ class ShortPixelView {
|
|
728 |
<?php }?>
|
729 |
<span class="resumeLabel"><?php echo( !$running ? __('Resume: ','shortpixel-image-optimiser') : "");?></span>
|
730 |
</form>
|
731 |
-
|
732 |
-
<a href="options-general.php?page=wp-shortpixel-settings" class="button button-primary bulk-cancel" style="margin-left:10px"><?php _e('Manage custom folders','shortpixel-image-optimiser');?></a>
|
733 |
-
<?php }?>
|
734 |
</div>
|
735 |
<?php
|
736 |
}
|
@@ -1696,10 +1698,10 @@ class ShortPixelView {
|
|
1696 |
<?php _e('Cleanup&Retry','shortpixel-image-optimiser');?>
|
1697 |
</a> <?php
|
1698 |
} else {
|
1699 |
-
if($data['status'] == 'retry') { ?>
|
1700 |
<div style="overflow:hidden">
|
1701 |
<a class="button button-smaller sp-action-restore" href="admin.php?action=shortpixel_restore_backup&attachment_ID=<?php echo($id)?>" style="margin-left:5px;"
|
1702 |
-
title="
|
1703 |
<?php _e('Cleanup','shortpixel-image-optimiser');?>
|
1704 |
</a>
|
1705 |
<?php } ?>
|
@@ -1714,19 +1716,26 @@ class ShortPixelView {
|
|
1714 |
case 'imgOptimized':
|
1715 |
$excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
|
1716 |
$successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt'], $data['excludeSizes']);
|
1717 |
-
$missingThumbs = $excludeSizes = '';
|
1718 |
if($extended) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1719 |
if(isset($data['excludeSizes'])) {
|
1720 |
-
$excludeSizes .= "<br><span> <span style='font-weight: bold;'>" . __("Excluded thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
1721 |
foreach($data['excludeSizes'] as $excludedItem) {
|
1722 |
-
$excludeSizes .= "<br> •
|
1723 |
}
|
1724 |
$excludeSizes .= '</span>';
|
1725 |
}
|
1726 |
if(count($data['thumbsMissing'])) {
|
1727 |
-
$missingThumbs .= "<br><span> <span style='font-weight: bold;'>" . __("Missing thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
1728 |
foreach($data['thumbsMissing'] as $miss) {
|
1729 |
-
$missingThumbs .= "<br> •
|
1730 |
}
|
1731 |
$missingThumbs .= '</span>';
|
1732 |
}
|
@@ -1734,7 +1743,7 @@ class ShortPixelView {
|
|
1734 |
. "<br>EXIF: " . ($data['exifKept'] ? __('kept','shortpixel-image-optimiser') : __('removed','shortpixel-image-optimiser'))
|
1735 |
. ($data['png2jpg'] ? '<br>' . __('Converted from PNG','shortpixel-image-optimiser'): '')
|
1736 |
. "<br>" . __("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date']
|
1737 |
-
. $excludeSizes . $missingThumbs;
|
1738 |
}
|
1739 |
$this->renderListCell($id, $data['status'], $data['showActions'], $data['thumbsToOptimize'],
|
1740 |
$data['backup'], $data['type'], $data['invType'], $successText);
|
1 |
<?php
|
2 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
3 |
|
4 |
class ShortPixelView {
|
5 |
|
153 |
echo('<li class="sp-conflict-plugins-list"><strong>' . $plugin['name'] . '</strong>');
|
154 |
echo('<a href="' . $link . '" class="button button-primary">'
|
155 |
. __( $action, 'shortpixel_image_optimiser' ) . '</a>');
|
156 |
+
if($plugin['details']) echo('<br>');
|
157 |
+
if($plugin['details']) echo('<span>' . $plugin['details'] . '</span>');
|
158 |
}
|
159 |
echo("</ul>");
|
160 |
break;
|
401 |
|
402 |
jQuery(".sp-bulk-summary").spTooltip({
|
403 |
tooltipSource: "inline",
|
404 |
+
tooltipSourceID: "#sp-bulk-stats",
|
405 |
});
|
406 |
});
|
407 |
!function(d,s,id){//Just optimized my site with ShortPixel image optimization plugin
|
424 |
</div>
|
425 |
<?php } ?>
|
426 |
</div>
|
427 |
+
<div id="sp-bulk-stats" class='<?php echo $hider ?>' style="display:none">
|
428 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
429 |
</div>
|
430 |
</div>
|
616 |
<span class="sp-err-title"><?php _e('Error processing file:','shortpixel-image-optimiser');?><br></span>
|
617 |
<span class="sp-err-content"><?php echo $message; ?></span> <a class="sp-post-link" href="<?php echo(get_admin_url());?>/post.php?post=__ID__&action=edit" target="_blank">placeholder.png</a>
|
618 |
</div>
|
619 |
+
<div class="bulk-notice-msg bulk-searching">
|
620 |
+
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/loading-dark-big.gif' ));?>">
|
621 |
+
<?php _e('Please bear with me. ShortPixel is checking many already optimized images to see if they\'re OK, so the progress bar could stop for a while.','shortpixel-image-optimiser');?><br>
|
622 |
+
</div>
|
623 |
</div>
|
624 |
</div>
|
625 |
<div class="bulk-progress bulk-slider-container sp-notice sp-notice-info sp-floating-block sp-full-width">
|
670 |
<?php } ?>
|
671 |
|
672 |
<?php
|
673 |
+
Log::addDebug('Shortpixel View - Bulktype', array('b' => $this->bulkType));
|
|
|
674 |
if ($this->bulkType != ShortPixelQueue::BULK_TYPE_RESTORE): ?>
|
675 |
<div class="bulk-progress-indicator">
|
676 |
<div style="margin-bottom:5px"><?php _e('Average reduction','shortpixel-image-optimiser');?></div>
|
721 |
<div class="bulk-estimate">
|
722 |
<?php echo($message);?>
|
723 |
</div>
|
|
|
724 |
<form action='' method='POST' style="display:inline;">
|
725 |
<input type="submit" class="button button-primary bulk-cancel" onclick="clearBulkProcessor();"
|
726 |
name="bulkProcessStop" value="Stop" style="margin-left:10px"/>
|
732 |
<?php }?>
|
733 |
<span class="resumeLabel"><?php echo( !$running ? __('Resume: ','shortpixel-image-optimiser') : "");?></span>
|
734 |
</form>
|
735 |
+
|
|
|
|
|
736 |
</div>
|
737 |
<?php
|
738 |
}
|
1698 |
<?php _e('Cleanup&Retry','shortpixel-image-optimiser');?>
|
1699 |
</a> <?php
|
1700 |
} else {
|
1701 |
+
if($data['status'] == 'retry' && (isset($data['backup']) && $data['backup']) ) { ?>
|
1702 |
<div style="overflow:hidden">
|
1703 |
<a class="button button-smaller sp-action-restore" href="admin.php?action=shortpixel_restore_backup&attachment_ID=<?php echo($id)?>" style="margin-left:5px;"
|
1704 |
+
title="<?php _e('Restore Image from Backup', 'shortpixel-image-optimiser') ?>">
|
1705 |
<?php _e('Cleanup','shortpixel-image-optimiser');?>
|
1706 |
</a>
|
1707 |
<?php } ?>
|
1716 |
case 'imgOptimized':
|
1717 |
$excluded = (isset($data['excludeSizes']) ? count($data['excludeSizes']) : 0);
|
1718 |
$successText = $this->getSuccessText($data['percent'],$data['bonus'],$data['type'],$data['thumbsOpt'],$data['thumbsTotal'], $data['retinasOpt'], $data['excludeSizes']);
|
1719 |
+
$todoSizes = $missingThumbs = $excludeSizes = '';
|
1720 |
if($extended) {
|
1721 |
+
if(isset($data['thumbsToOptimizeList']) && count($data['thumbsToOptimizeList'])) {
|
1722 |
+
$todoSizes .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("To optimize:", 'shortpixel-image-optimiser') . "</span>";
|
1723 |
+
foreach($data['thumbsToOptimizeList'] as $todoItem) {
|
1724 |
+
$todoSizes .= "<br> • " . $todoItem;
|
1725 |
+
}
|
1726 |
+
$excludeSizes .= '</span>';
|
1727 |
+
}
|
1728 |
if(isset($data['excludeSizes'])) {
|
1729 |
+
$excludeSizes .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("Excluded thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
1730 |
foreach($data['excludeSizes'] as $excludedItem) {
|
1731 |
+
$excludeSizes .= "<br> • " . $excludedItem;
|
1732 |
}
|
1733 |
$excludeSizes .= '</span>';
|
1734 |
}
|
1735 |
if(count($data['thumbsMissing'])) {
|
1736 |
+
$missingThumbs .= "<br><span style='word-break: break-all;'> <span style='font-weight: bold;'>" . __("Missing thumbnails:", 'shortpixel-image-optimiser') . "</span>";
|
1737 |
foreach($data['thumbsMissing'] as $miss) {
|
1738 |
+
$missingThumbs .= "<br> • " . $miss;
|
1739 |
}
|
1740 |
$missingThumbs .= '</span>';
|
1741 |
}
|
1743 |
. "<br>EXIF: " . ($data['exifKept'] ? __('kept','shortpixel-image-optimiser') : __('removed','shortpixel-image-optimiser'))
|
1744 |
. ($data['png2jpg'] ? '<br>' . __('Converted from PNG','shortpixel-image-optimiser'): '')
|
1745 |
. "<br>" . __("Optimized on", 'shortpixel-image-optimiser') . ": " . $data['date']
|
1746 |
+
. $todoSizes . $excludeSizes . $missingThumbs;
|
1747 |
}
|
1748 |
$this->renderListCell($id, $data['status'], $data['showActions'], $data['thumbsToOptimize'],
|
1749 |
$data['backup'], $data['type'], $data['invType'], $successText);
|
@@ -42,7 +42,7 @@
|
|
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 class='error'><p><?php _e('It is strongly recommended to backup your uploads', 'shortpixel-image-
|
46 |
</div>
|
47 |
|
48 |
</div> <!-- sp-notice -->
|
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 class='error'><p><?php _e('It is strongly recommended to backup your uploads', 'shortpixel-image-optimiser'); ?></p>
|
46 |
</div>
|
47 |
|
48 |
</div> <!-- sp-notice -->
|
@@ -1,8 +1,8 @@
|
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
-
use
|
4 |
|
5 |
-
HelpScout::outputBeacon($view->data->apiKey);
|
6 |
|
7 |
?>
|
8 |
<div class="wrap">
|
@@ -29,6 +29,7 @@ HelpScout::outputBeacon($view->data->apiKey);
|
|
29 |
?>
|
30 |
<form name='wp_shortpixel_options' action='<?php echo add_query_arg('noheader', 'true') ?>' method='post' id='wp_shortpixel_options'>
|
31 |
<input type='hidden' name='display_part' value="<?php echo $this->display_part ?>" />
|
|
|
32 |
<div class='section-wrapper'>
|
33 |
<?php
|
34 |
$this->loadView('settings/part-general');
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
|
5 |
+
HelpScout::outputBeacon($this->hide_api_key ? '' : $view->data->apiKey);
|
6 |
|
7 |
?>
|
8 |
<div class="wrap">
|
29 |
?>
|
30 |
<form name='wp_shortpixel_options' action='<?php echo add_query_arg('noheader', 'true') ?>' method='post' id='wp_shortpixel_options'>
|
31 |
<input type='hidden' name='display_part' value="<?php echo $this->display_part ?>" />
|
32 |
+
<?php wp_nonce_field($this->form_action, 'sp-nonce'); ?>
|
33 |
<div class='section-wrapper'>
|
34 |
<?php
|
35 |
$this->loadView('settings/part-general');
|
@@ -1,9 +1,7 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
use ShortPixel\
|
4 |
-
use ShortPixel\
|
5 |
-
use ShortPixel\NoticeController as Notice;
|
6 |
-
|
7 |
|
8 |
class WPShortPixel {
|
9 |
|
@@ -26,8 +24,9 @@ class WPShortPixel {
|
|
26 |
|
27 |
public function __construct() {
|
28 |
$this->timer = time();
|
|
|
29 |
|
30 |
-
if (
|
31 |
$this->jsSuffix = '.js'; //use unminified versions for easier debugging
|
32 |
}
|
33 |
|
@@ -40,14 +39,9 @@ class WPShortPixel {
|
|
40 |
$this->cloudflareApi = new ShortPixelCloudFlareApi($this->_settings->cloudflareEmail, $this->_settings->cloudflareAuthKey, $this->_settings->cloudflareZoneID);
|
41 |
$this->hasNextGen = ShortPixelNextGenAdapter::hasNextGen();
|
42 |
$this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $this->_settings->excludePatterns);
|
43 |
-
$this->prioQ = new ShortPixelQueue($this, $this->_settings);
|
44 |
$this->view = new ShortPixelView($this);
|
45 |
|
46 |
-
$controllerClass = ShortPixelTools::namespaceit('ShortPixelController');
|
47 |
-
$controllerClass::init(); // load all subclassed controllers.
|
48 |
-
|
49 |
-
/*$debugClass = ShortPixelTools::namespaceit('Debug');
|
50 |
-
$debugClass->init(); */
|
51 |
|
52 |
define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
|
53 |
|
@@ -166,12 +160,28 @@ class WPShortPixel {
|
|
166 |
|
167 |
// [BS] Quite dangerous to do this in any constructor. Can hit if request is ajax to name something
|
168 |
// @todo This is intended to run only once, on activation. ( it does )
|
169 |
-
if(!$this->_settings->redirectedSettings && !$this->_settings->verifiedKey && (!function_exists("is_multisite") || !is_multisite())) {
|
170 |
$this->_settings->redirectedSettings = 1;
|
171 |
wp_redirect(admin_url("options-general.php?page=wp-shortpixel-settings"));
|
172 |
exit();
|
173 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
176 |
|
177 |
//handling older
|
@@ -206,7 +216,12 @@ class WPShortPixel {
|
|
206 |
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $settings->excludePatterns);
|
207 |
$spMetaDao->dropTables();
|
208 |
}
|
209 |
-
|
|
|
|
|
|
|
|
|
|
|
210 |
self::alterHtaccess(); //add the htaccess lines
|
211 |
}
|
212 |
WPShortPixelSettings::onActivate();
|
@@ -215,9 +230,15 @@ class WPShortPixel {
|
|
215 |
public static function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
216 |
{
|
217 |
ShortPixelQueue::resetBulk();
|
218 |
-
ShortPixelQueue::resetPrio();
|
219 |
WPShortPixelSettings::onDeactivate();
|
220 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
@unlink(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log");
|
222 |
}
|
223 |
|
@@ -313,18 +334,22 @@ class WPShortPixel {
|
|
313 |
*/
|
314 |
);
|
315 |
if($this->_settings->processThumbnails) {
|
|
|
|
|
316 |
$conflictPlugins = array_merge($conflictPlugins, array(
|
317 |
-
'Regenerate Thumbnails
|
318 |
=> array(
|
319 |
'action'=>'Deactivate',
|
320 |
'data'=>'regenerate-thumbnails/regenerate-thumbnails.php',
|
321 |
-
'page'=>'regenerate-thumbnails'
|
|
|
322 |
),
|
323 |
-
'Force Regenerate Thumbnails
|
324 |
=> array(
|
325 |
'action'=>'Deactivate',
|
326 |
'data'=>'force-regenerate-thumbnails/force-regenerate-thumbnails.php',
|
327 |
-
'page'=>'force-regenerate-thumbnails'
|
|
|
328 |
)
|
329 |
));
|
330 |
}
|
@@ -334,12 +359,13 @@ class WPShortPixel {
|
|
334 |
$data = ( isset($path['data']) ) ? $path['data'] : null;
|
335 |
$href = ( isset($path['href']) ) ? $path['href'] : null;
|
336 |
$page = ( isset($path['page']) ) ? $path['page'] : null;
|
|
|
337 |
if(is_plugin_active($data)) {
|
338 |
if( $data == 'jetpack/jetpack.php' ){
|
339 |
$jetPackPhoton = get_option('jetpack_active_modules') ? in_array('photon', get_option('jetpack_active_modules')) : false;
|
340 |
if( !$jetPackPhoton ){ continue; }
|
341 |
}
|
342 |
-
$found[] = array( 'name' => $name, 'action'=> $action, 'path' => $data, 'href' => $href , 'page' => $page );
|
343 |
}
|
344 |
}
|
345 |
return $found;
|
@@ -349,7 +375,8 @@ class WPShortPixel {
|
|
349 |
* TODO - Probably should be a controller
|
350 |
*/
|
351 |
public function displayAdminNotices() {
|
352 |
-
|
|
|
353 |
ShortPixelView::displayActivationNotice('fileperms');
|
354 |
}
|
355 |
if($this->catchNotice()) { //notices for errors like for example a failed restore notice - these are one time so display them with priority.
|
@@ -472,7 +499,7 @@ class WPShortPixel {
|
|
472 |
|
473 |
/** [TODO] This should report to the Shortpixel Logger **/
|
474 |
static protected function doLog($message, $force = false) {
|
475 |
-
|
476 |
/*if(defined('SHORTPIXEL_DEBUG_TARGET') || $force) {
|
477 |
file_put_contents(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log", '[' . date('Y-m-d H:i:s') . "] $message\n", FILE_APPEND);
|
478 |
} else {
|
@@ -523,6 +550,7 @@ class WPShortPixel {
|
|
523 |
'STATUS_RETRY'=>ShortPixelAPI::STATUS_RETRY,
|
524 |
'STATUS_QUEUE_FULL'=>ShortPixelAPI::STATUS_QUEUE_FULL,
|
525 |
'STATUS_MAINTENANCE'=>ShortPixelAPI::STATUS_MAINTENANCE,
|
|
|
526 |
'WP_PLUGIN_URL'=>plugins_url( '', SHORTPIXEL_PLUGIN_FILE ),
|
527 |
'WP_ADMIN_URL'=>admin_url(),
|
528 |
'API_KEY'=> (defined("SHORTPIXEL_HIDE_API_KEY" ) || !is_admin() ) ? '' : $this->_settings->apiKey,
|
@@ -530,7 +558,7 @@ class WPShortPixel {
|
|
530 |
'MEDIA_ALERT'=>$this->_settings->mediaAlert ? "done" : "todo",
|
531 |
'FRONT_BOOTSTRAP'=>$this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0,
|
532 |
'AJAX_URL'=>admin_url('admin-ajax.php'),
|
533 |
-
'AFFILIATE'=>
|
534 |
));
|
535 |
|
536 |
if (Log::isManualDebug() )
|
@@ -576,6 +604,8 @@ class WPShortPixel {
|
|
576 |
|
577 |
wp_enqueue_script('jquery.knob.min.js', plugins_url('/res/js/jquery.knob.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
578 |
wp_enqueue_script('jquery.tooltip.min.js', plugins_url('/res/js/jquery.tooltip.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
|
|
|
|
579 |
wp_enqueue_script('punycode.min.js', plugins_url('/res/js/punycode.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
580 |
}
|
581 |
|
@@ -1097,7 +1127,7 @@ class WPShortPixel {
|
|
1097 |
$passTime = time();
|
1098 |
$maxResults = $timeoutThreshold > 15 ? SHORTPIXEL_MAX_RESULTS_QUERY / 3 :
|
1099 |
($timeoutThreshold > 10 ? SHORTPIXEL_MAX_RESULTS_QUERY / 2 : SHORTPIXEL_MAX_RESULTS_QUERY);
|
1100 |
-
|
1101 |
|
1102 |
/* $queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
1103 |
WHERE ( post_id <= $crtStartQueryID AND post_id >= $endQueryID )
|
@@ -1106,35 +1136,53 @@ class WPShortPixel {
|
|
1106 |
LIMIT " . SHORTPIXEL_MAX_RESULTS_QUERY;
|
1107 |
$resultsPostMeta = $wpdb->get_results($queryPostMeta);
|
1108 |
*/
|
|
|
|
|
|
|
1109 |
|
1110 |
-
|
1111 |
-
|
1112 |
|
1113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1114 |
$crtStartQueryID -= SHORTPIXEL_MAX_RESULTS_QUERY;
|
1115 |
$startQueryID = $crtStartQueryID;
|
1116 |
if(!count($idList)) { //none found so far, so decrease the start ID
|
1117 |
-
|
1118 |
$this->prioQ->setStartBulkId($startQueryID);
|
1119 |
}
|
1120 |
continue;
|
1121 |
}
|
1122 |
|
1123 |
-
if($timeoutThreshold > 10)
|
1124 |
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
|
|
1128 |
if(time() - $this->timer >= $maxTime - $timeoutThreshold){
|
1129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1130 |
}
|
|
|
1131 |
|
1132 |
if(!in_array($crtStartQueryID, $idList) && $this->isProcessable($crtStartQueryID, ($this->_settings->optimizePdfs ? array() : array('pdf')))) {
|
1133 |
$item = new ShortPixelMetaFacade($crtStartQueryID);
|
1134 |
|
1135 |
-
if($timeoutThreshold > 15)
|
1136 |
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
1137 |
-
if($timeoutThreshold > 15)
|
1138 |
|
1139 |
if($meta->getStatus() != 2) {
|
1140 |
$addIt = (strpos($meta->getMessage(), __('Image files are missing.', 'shortpixel-image-optimiser')) === false);
|
@@ -1162,11 +1210,16 @@ class WPShortPixel {
|
|
1162 |
$skippedAlreadyProcessed++;
|
1163 |
}
|
1164 |
}
|
1165 |
-
elseif( $this->_settings->processThumbnails && $meta->getThumbsOpt() !== null
|
1166 |
-
&& ($meta->getThumbsOpt() == 0 && count($meta->getThumbs()) > 0
|
1167 |
|| is_array($meta->getThumbsOptList())
|
1168 |
&& count(array_diff(array_keys(WpShortPixelMediaLbraryAdapter::getSizesNotExcluded($meta->getThumbs(), $this->_settings->excludeSizes)),
|
1169 |
-
$meta->getThumbsOptList()))
|
|
|
|
|
|
|
|
|
|
|
1170 |
$URLsAndPATHs = $item->getURLsAndPATHs(true, true, $this->_settings->optimizeRetina, $this->_settings->excludeSizes);
|
1171 |
if(count($URLsAndPATHs["URLs"])) {
|
1172 |
$meta->setThumbsTodo(true);
|
@@ -1176,22 +1229,24 @@ class WPShortPixel {
|
|
1176 |
if(count($itemList) > SHORTPIXEL_PRESEND_ITEMS) break;
|
1177 |
}
|
1178 |
}
|
|
|
1179 |
elseif($itemMetaData->meta_key == '_wp_attachment_metadata') { //count skipped
|
1180 |
$skippedAlreadyProcessed++;
|
1181 |
}
|
|
|
1182 |
}
|
1183 |
}
|
1184 |
if(!count($idList) && $crtStartQueryID <= $startQueryID) {
|
1185 |
//daca n-am adaugat niciuna pana acum, n-are sens sa mai selectez zona asta de id-uri in bulk-ul asta.
|
1186 |
$leapStart = $this->prioQ->getStartBulkId();
|
1187 |
-
$crtStartQueryID = $startQueryID = $
|
1188 |
$res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings, $leapStart, $crtStartQueryID);
|
1189 |
$skippedAlreadyProcessed += $res["mainProcessedFiles"] - $res["mainProc".($this->getCompressionType() == 1 ? "Lossy" : "Lossless")."Files"];
|
1190 |
-
|
1191 |
$this->prioQ->setStartBulkId($startQueryID);
|
1192 |
} else {
|
1193 |
$crtStartQueryID--;
|
1194 |
-
|
1195 |
}
|
1196 |
}
|
1197 |
$ret = array("items" => $itemList, "skipped" => $skippedAlreadyProcessed, "searching" => ($sanityCheck >= 150) || (time() - $this->timer >= $maxTime - $timeoutThreshold));
|
@@ -1215,7 +1270,7 @@ class WPShortPixel {
|
|
1215 |
|
1216 |
/** Checks the API key **/
|
1217 |
private function checkKey($ID) {
|
1218 |
-
|
1219 |
if($ID == null){
|
1220 |
$ids = $this->getFromPrioAndCheck(1);
|
1221 |
$itemHandler = (count($ids) > 0 ? $ids[0] : null);
|
@@ -1229,11 +1284,23 @@ class WPShortPixel {
|
|
1229 |
private function sendEmptyQueue() {
|
1230 |
$avg = $this->getAverageCompression();
|
1231 |
$fileCount = $this->_settings->fileCount;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1232 |
$response = array("Status" => self::BULK_EMPTY_QUEUE,
|
1233 |
/* translators: console message Empty queue 1234 -> 1234 */
|
1234 |
"Message" => __('Empty queue ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId(),
|
1235 |
-
"BulkStatus" =>
|
1236 |
-
? "1" : ($this->prioQ->bulkPaused() ? "2" : "0")),
|
1237 |
"AverageCompression" => $avg,
|
1238 |
"FileCount" => $fileCount,
|
1239 |
"BulkPercent" => $this->prioQ->getBulkPercent());
|
@@ -1258,8 +1325,8 @@ class WPShortPixel {
|
|
1258 |
}
|
1259 |
|
1260 |
$rawPrioQ = $this->prioQ->get();
|
1261 |
-
if(count($rawPrioQ)) {
|
1262 |
-
|
1263 |
|
1264 |
//handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
|
1265 |
if( $this->prioQ->bulkRunning()
|
@@ -1320,7 +1387,8 @@ class WPShortPixel {
|
|
1320 |
//die("za stop 2");
|
1321 |
|
1322 |
//self::log("HIP: 1 Ids: ".json_encode($ids));
|
1323 |
-
if(count($ids)) {$idl='';foreach($ids as $i){$idl.=$i->getId().' ';}
|
|
|
1324 |
|
1325 |
//2: Send up to SHORTPIXEL_PRESEND_ITEMS files to the server for processing
|
1326 |
for($i = 0, $itemHandler = false; $ids !== false && $i < min(SHORTPIXEL_PRESEND_ITEMS, count($ids)); $i++) {
|
@@ -1351,7 +1419,7 @@ class WPShortPixel {
|
|
1351 |
if (!$itemHandler){
|
1352 |
//if searching, than the script is searching for not processed items and found none yet, should be relaunced
|
1353 |
if(isset($res['searching']) && $res['searching']) {
|
1354 |
-
die(json_encode(array("Status" => ShortPixelAPI::
|
1355 |
"Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
|
1356 |
}
|
1357 |
//in this case the queue is really empty
|
@@ -1450,6 +1518,7 @@ class WPShortPixel {
|
|
1450 |
$bkThumb = $backupUrl . $urlBkPath . $thumb;
|
1451 |
}
|
1452 |
if(strlen($thumb)) {
|
|
|
1453 |
if($itemHandler->getType() == ShortPixelMetaFacade::CUSTOM_TYPE) {
|
1454 |
$uploadsUrl = ShortPixelMetaFacade::getHomeUrl();
|
1455 |
$urlPath = ShortPixelMetaFacade::returnSubDir($meta->getPath());
|
@@ -2117,7 +2186,7 @@ class WPShortPixel {
|
|
2117 |
* @param int $ID image_id, without any prefixes
|
2118 |
*/
|
2119 |
public function doCustomRestore($ID) {
|
2120 |
-
|
2121 |
// meta facade as a custom image
|
2122 |
$itemHandler = new ShortPixelMetaFacade('C-' . $ID);
|
2123 |
$meta = $itemHandler->getMeta();
|
@@ -2137,37 +2206,48 @@ class WPShortPixel {
|
|
2137 |
$fullSubDir = str_replace(get_home_path(), "", dirname($file)) . '/';
|
2138 |
$bkFile = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir . ShortPixelAPI::MB_basename($file);
|
2139 |
|
2140 |
-
|
2141 |
-
$rename_result = @rename($bkFile, $file);
|
2142 |
-
if (! $rename_result)
|
2143 |
-
{
|
2144 |
-
Log::addError('Failure on rename to : ' . $file);
|
2145 |
-
}
|
2146 |
|
|
|
|
|
2147 |
|
2148 |
-
|
2149 |
-
|
|
|
|
|
|
|
|
|
2150 |
|
2151 |
-
|
2152 |
-
|
2153 |
-
$
|
2154 |
-
|
2155 |
-
|
2156 |
-
$
|
2157 |
-
|
2158 |
-
|
2159 |
-
|
2160 |
-
$meta->setResizeHeight(0);
|
2161 |
-
$meta->setResize(0);
|
2162 |
|
2163 |
-
|
2164 |
-
|
2165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2166 |
|
2167 |
-
|
2168 |
-
|
2169 |
-
|
2170 |
-
|
|
|
2171 |
|
2172 |
return $meta;
|
2173 |
}
|
@@ -2198,7 +2278,19 @@ class WPShortPixel {
|
|
2198 |
|
2199 |
if(ShortPixelMetaFacade::isCustomQueuedId($qID)) {
|
2200 |
$ID = ShortPixelMetaFacade::stripQueuedIdType($qID);
|
2201 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2202 |
if($meta) {
|
2203 |
$meta->setCompressionType(ShortPixelAPI::getCompressionTypeCode($compressionType));
|
2204 |
$meta->setStatus(1);
|
@@ -2243,7 +2335,8 @@ class WPShortPixel {
|
|
2243 |
//$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);
|
2244 |
$error = array('Status' => ShortPixelAPI::STATUS_SKIP, 'message' => __('Unspecified Error on Thumbnails for: ') . $ID);
|
2245 |
|
2246 |
-
$includedSizes =
|
|
|
2247 |
$thumbsCount = count($includedSizes);
|
2248 |
|
2249 |
if (! isset($meta['ShortPixelImprovement']))
|
@@ -2434,7 +2527,7 @@ class WPShortPixel {
|
|
2434 |
}
|
2435 |
if ( !$quotaData['APIKeyValid']) {
|
2436 |
if(strlen($this->_settings->apiKey))
|
2437 |
-
|
2438 |
return $quotaData;
|
2439 |
}
|
2440 |
//$tempus = microtime(true);
|
@@ -2581,6 +2674,8 @@ class WPShortPixel {
|
|
2581 |
|
2582 |
if(isset($_POST["bulkRestore"]))
|
2583 |
{
|
|
|
|
|
2584 |
$bulkRestore = new \ShortPixel\BulkRestoreAll(); // controller
|
2585 |
$bulkRestore->setShortPixel($this);
|
2586 |
$bulkRestore->setupBulk();
|
@@ -2591,25 +2686,31 @@ class WPShortPixel {
|
|
2591 |
|
2592 |
if(isset($_POST["bulkCleanup"]))
|
2593 |
{
|
|
|
2594 |
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_CLEANUP);
|
2595 |
$this->_settings->customBulkPaused = 0;
|
2596 |
}//end bulk restore was clicked
|
2597 |
|
2598 |
if(isset($_POST["bulkCleanupPending"]))
|
2599 |
{
|
|
|
2600 |
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING);
|
2601 |
$this->_settings->customBulkPaused = 0;
|
2602 |
}//end bulk restore was clicked
|
2603 |
|
2604 |
if(isset($_POST["bulkProcessResume"]))
|
2605 |
{
|
|
|
2606 |
$this->prioQ->resumeBulk();
|
2607 |
$this->_settings->customBulkPaused = 0;
|
2608 |
}//resume was clicked
|
2609 |
|
2610 |
if(isset($_POST["skipToCustom"]))
|
2611 |
{
|
|
|
2612 |
$this->_settings->skipToCustom = true;
|
|
|
|
|
2613 |
}//resume was clicked
|
2614 |
|
2615 |
//figure out the files that are left to be processed
|
@@ -2619,6 +2720,8 @@ class WPShortPixel {
|
|
2619 |
|
2620 |
//check the custom bulk
|
2621 |
$pendingMeta = $this->_settings->hasCustomFolders ? $this->spMetaDao->getPendingMetaCount() : 0;
|
|
|
|
|
2622 |
|
2623 |
if ( ($filesLeft[0]->FilesLeftToBeProcessed > 0 && $this->prioQ->bulkRunning())
|
2624 |
|| (0 + $pendingMeta > 0 && !$this->_settings->customBulkPaused && $this->prioQ->bulkRan())//bulk processing was started
|
@@ -2635,6 +2738,7 @@ class WPShortPixel {
|
|
2635 |
{
|
2636 |
if($this->prioQ->bulkRan() && !$this->prioQ->bulkPaused()) {
|
2637 |
$this->prioQ->markBulkComplete();
|
|
|
2638 |
}
|
2639 |
|
2640 |
//image count
|
@@ -3031,324 +3135,11 @@ class WPShortPixel {
|
|
3031 |
|
3032 |
insert_with_markers( $upload_base . '.htaccess', 'ShortPixelWebp', $rules);
|
3033 |
insert_with_markers( trailingslashit(WP_CONTENT_DIR) . '.htaccess', 'ShortPixelWebp', $rules);
|
3034 |
-
/* insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', '
|
3035 |
-
RewriteEngine On
|
3036 |
-
RewriteBase /
|
3037 |
-
RewriteCond %{HTTP_USER_AGENT} Chrome [OR]
|
3038 |
-
RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
|
3039 |
-
RewriteCond %{HTTP_ACCEPT} image/webp [OR]
|
3040 |
-
RewriteCond %{DOCUMENT_ROOT}/$1\.webp -f
|
3041 |
-
RewriteRule (.+)\.(?:jpe?g|png)$ $1.webp [NC,T=image/webp,E=webp,L]
|
3042 |
-
Header append Vary Accept env=REDIRECT_webp
|
3043 |
-
' ); */
|
3044 |
-
}
|
3045 |
-
}
|
3046 |
|
3047 |
-
/** Settings menu controller
|
3048 |
-
* @todo Make it a controller ||commented out means replaced
|
3049 |
-
*/
|
3050 |
-
public function renderSettingsMenu() {
|
3051 |
-
if ( !current_user_can( 'manage_options' ) ) {
|
3052 |
-
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
3053 |
}
|
|
|
3054 |
|
3055 |
-
// wp_enqueue_style('sp-file-tree.min.css', plugins_url('/res/css/sp-file-tree.min.css',SHORTPIXEL_PLUGIN_FILE) );
|
3056 |
-
// wp_enqueue_script('sp-file-tree.min.js', plugins_url('/res/js/sp-file-tree.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
3057 |
-
|
3058 |
-
//die(var_dump($_POST));
|
3059 |
-
$noticeHTML = "";
|
3060 |
-
$notice = null;
|
3061 |
-
$folderMsg = false;
|
3062 |
-
$addedFolder = false;
|
3063 |
-
|
3064 |
-
//$this->_settings->redirectedSettings = 2;
|
3065 |
-
|
3066 |
-
// Check if NGINX Server
|
3067 |
-
//$isNginx = strpos($_SERVER["SERVER_SOFTWARE"], 'nginx') !== false ? true : false;
|
3068 |
-
|
3069 |
-
// BEGIN: Verify .htaccess writeability
|
3070 |
-
/*$htaccessWriteable = true;
|
3071 |
-
if( !$isNginx ) {
|
3072 |
-
$htaccessPath = get_home_path() . '.htaccess';
|
3073 |
-
$htaccessExisted = file_exists( $htaccessPath );
|
3074 |
-
//$htaccessWriteable = insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', '' );
|
3075 |
-
$htaccessWriteable = @fopen($htaccessPath, "a+") ? true : false;
|
3076 |
-
if( !$htaccessExisted ){
|
3077 |
-
unlink( $htaccessPath );
|
3078 |
-
}
|
3079 |
-
} */
|
3080 |
-
// END: Verify .htaccess writeability
|
3081 |
-
|
3082 |
-
|
3083 |
-
//by default we try to fetch the API Key from wp-config.php (if defined)
|
3084 |
-
/*if ( defined("SHORTPIXEL_API_KEY") && strlen(SHORTPIXEL_API_KEY) == 20)
|
3085 |
-
{
|
3086 |
-
if(!isset($_POST['save']) && (strlen($this->getApiKey()) == 0 || SHORTPIXEL_API_KEY != $this->getApiKey())) {
|
3087 |
-
$_POST['validate'] = "validate";
|
3088 |
-
}
|
3089 |
-
$_POST['key'] = SHORTPIXEL_API_KEY;
|
3090 |
-
} */
|
3091 |
-
|
3092 |
-
if(isset($_GET['setsparchive'])) {
|
3093 |
-
$this->_settings->downloadArchive = intval($_GET['setsparchive']);
|
3094 |
-
}
|
3095 |
-
|
3096 |
-
//check all custom folders and update meta table if files appeared
|
3097 |
-
// This var is overwritten in the Save procedure. Notice is possibly overwritten below.
|
3098 |
-
//$customFolders = $this->refreshCustomFolders($notice, isset($_POST['removeFolder']) ? $_POST['removeFolder'] : null);
|
3099 |
-
|
3100 |
-
if(isset($_POST['request']) && $_POST['request'] == 'request') {
|
3101 |
-
//a new API Key was requested
|
3102 |
-
if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
|
3103 |
-
|
3104 |
-
}
|
3105 |
-
else {
|
3106 |
-
$notice = array("status" => "error",
|
3107 |
-
"msg" => __("Please provide a valid e-mail.",'shortpixel-image-optimiser')
|
3108 |
-
. "<BR> "
|
3109 |
-
. __('For any question regarding obtaining your API Key, please contact us at ','shortpixel-image-optimiser')
|
3110 |
-
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
3111 |
-
. __(' or ','shortpixel-image-optimiser')
|
3112 |
-
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
3113 |
-
}
|
3114 |
-
}
|
3115 |
-
|
3116 |
-
/* if ( isset( $_POST["saveCloudflare"] ) ) {
|
3117 |
-
$cfApi = $this->_settings->cloudflareEmail = sanitize_text_field( $_POST['cloudflare-email'] );
|
3118 |
-
$cfAuth = $this->_settings->cloudflareAuthKey = sanitize_text_field( $_POST['cloudflare-auth-key'] );
|
3119 |
-
$cfZone = $this->_settings->cloudflareZoneID = sanitize_text_field( $_POST['cloudflare-zone-id'] ); */
|
3120 |
-
$this->cloudflareApi->set_up($cfApi, $cfAuth, $cfZone);
|
3121 |
-
//}
|
3122 |
-
|
3123 |
-
if( isset($_POST['save']) || isset($_POST['saveAdv'])
|
3124 |
-
|| (isset($_POST['validate']) && $_POST['validate'] == "validate")
|
3125 |
-
|| isset($_POST['removeFolder']) || isset($_POST['recheckFolder'])) {
|
3126 |
-
|
3127 |
-
//handle API Key - common for save and validate.
|
3128 |
-
//$_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.
|
3129 |
-
|
3130 |
-
/* if ( strlen($_POST['key']) <> 20 ){
|
3131 |
-
$KeyLength = strlen($_POST['key']);
|
3132 |
-
|
3133 |
-
$notice = array("status" => "error",
|
3134 |
-
"msg" => sprintf(__("The key you provided has %s characters. The API key should have 20 characters, letters and numbers only.",'shortpixel-image-optimiser'), $KeyLength)
|
3135 |
-
. "<BR> <b>"
|
3136 |
-
. __('Please check that the API key is the same as the one you received in your confirmation email.','shortpixel-image-optimiser')
|
3137 |
-
. "</b><BR> "
|
3138 |
-
. __('If this problem persists, please contact us at ','shortpixel-image-optimiser')
|
3139 |
-
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
3140 |
-
. __(' or ','shortpixel-image-optimiser')
|
3141 |
-
. "<a href='https://shortpixel.com/contact' target='_blank'>" . __('here','shortpixel-image-optimiser') . "</a>.");
|
3142 |
-
}
|
3143 |
-
else {
|
3144 |
-
|
3145 |
-
if(isset($_POST['save']) || isset($_POST['saveAdv'])) {
|
3146 |
-
//these are needed for the call to api-status, set them first.
|
3147 |
-
$this->_settings->siteAuthUser = (isset($_POST['siteAuthUser']) ? sanitize_text_field($_POST['siteAuthUser']) : $this->_settings->siteAuthUser);
|
3148 |
-
$this->_settings->siteAuthPass = (isset($_POST['siteAuthPass']) ? sanitize_text_field($_POST['siteAuthPass']) : $this->_settings->siteAuthPass);
|
3149 |
-
}
|
3150 |
-
|
3151 |
-
$validityData = $this->getQuotaInformation($_POST['key'], true, isset($_POST['validate']) && $_POST['validate'] == "validate", $_POST);
|
3152 |
-
*/
|
3153 |
-
/* $this->_settings->apiKey = $_POST['key'];
|
3154 |
-
if($validityData['APIKeyValid']) {
|
3155 |
-
if(isset($_POST['validate']) && $_POST['validate'] == "validate") {
|
3156 |
-
// delete last status if it was no valid key
|
3157 |
-
$lastStatus = $this->_settings->bulkLastStatus;
|
3158 |
-
if(isset($lastStatus['Status']) && $lastStatus['Status'] == ShortPixelAPI::STATUS_NO_KEY) {
|
3159 |
-
$this->_settings->bulkLastStatus = null;
|
3160 |
-
}
|
3161 |
-
//display notification
|
3162 |
-
$urlParts = explode("/", get_site_url());
|
3163 |
-
if( $validityData['DomainCheck'] == 'NOT Accessible'){
|
3164 |
-
$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'));
|
3165 |
-
} else {
|
3166 |
-
if ( function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY"))
|
3167 |
-
$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')
|
3168 |
-
. "<BR> <b>define('SHORTPIXEL_API_KEY', '".$this->_settings->apiKey."');</b>");
|
3169 |
-
else
|
3170 |
-
$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'));
|
3171 |
-
}
|
3172 |
-
}
|
3173 |
-
$this->_settings->verifiedKey = true;
|
3174 |
-
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
3175 |
-
if ( !file_exists(SHORTPIXEL_BACKUP_FOLDER) && ! ShortPixelFolder::createBackUpFolder() )
|
3176 |
-
$notice = array("status" => "error",
|
3177 |
-
"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'),
|
3178 |
-
WP_CONTENT_DIR . '/' . SHORTPIXEL_UPLOADS_NAME ));
|
3179 |
-
} else {
|
3180 |
-
if(isset($_POST['validate'])) {
|
3181 |
-
//display notification
|
3182 |
-
$notice = array("status" => "error", "msg" => $validityData["Message"]);
|
3183 |
-
}
|
3184 |
-
$this->_settings->verifiedKey = false;
|
3185 |
-
} */
|
3186 |
-
// }
|
3187 |
-
|
3188 |
-
//if save button - we process the rest of the form elements
|
3189 |
-
if(isset($_POST['save']) || isset($_POST['saveAdv'])) {
|
3190 |
-
/* $this->_settings->compressionType = intval($_POST['compressionType']);
|
3191 |
-
if(isset($_POST['thumbnails'])) { $this->_settings->processThumbnails = 1; } else { $this->_settings->processThumbnails = 0; }
|
3192 |
-
if(isset($_POST['backupImages'])) { $this->_settings->backupImages = 1; } else { $this->_settings->backupImages = 0; }
|
3193 |
-
if(isset($_POST['cmyk2rgb'])) { $this->_settings->CMYKtoRGBconversion = 1; } else { $this->_settings->CMYKtoRGBconversion = 0; }
|
3194 |
-
$this->_settings->keepExif = isset($_POST['removeExif']) ? 0 : 1;
|
3195 |
-
//delete_option('wp-short-pixel-keep-exif');
|
3196 |
-
$this->_settings->resizeImages = (isset($_POST['resize']) ? 1: 0);
|
3197 |
-
$this->_settings->resizeType = (isset($_POST['resize_type']) ? sanitize_text_field($_POST['resize_type']) : false);
|
3198 |
-
$this->_settings->resizeWidth = (isset($_POST['width']) ? intval($_POST['width']): $this->_settings->resizeWidth);
|
3199 |
-
$this->_settings->resizeHeight = (isset($_POST['height']) ? intval($_POST['height']): $this->_settings->resizeHeight);
|
3200 |
-
$uploadPath = realpath(SHORTPIXEL_UPLOADS_BASE); */
|
3201 |
-
|
3202 |
-
/* if(isset($_POST['nextGen'])) {
|
3203 |
-
WpShortPixelDb::checkCustomTables(); // check if custom tables are created, if not, create them
|
3204 |
-
$prevNextGen = $this->_settings->includeNextGen;
|
3205 |
-
$this->_settings->includeNextGen = 1;
|
3206 |
-
$ret = $this->addNextGenGalleriesToCustom($prevNextGen);
|
3207 |
-
$folderMsg = $ret["message"];
|
3208 |
-
$customFolders = $ret["customFolders"];
|
3209 |
-
} else {
|
3210 |
-
$this->_settings->includeNextGen = 0;
|
3211 |
-
} */
|
3212 |
-
/* if(isset($_POST['addCustomFolder']) && strlen($_POST['addCustomFolder']) > 0) {
|
3213 |
-
$folderMsg = $this->spMetaDao->newFolderFromPath(stripslashes($_POST['addCustomFolder']), $uploadPath, self::getCustomFolderBase());
|
3214 |
-
if(!$folderMsg) {
|
3215 |
-
$notice = array("status" => "success", "msg" => __('Folder added successfully.','shortpixel-image-optimiser'));
|
3216 |
-
}
|
3217 |
-
$customFolders = $this->spMetaDao->getFolders();
|
3218 |
-
$this->_settings->hasCustomFolders = time();
|
3219 |
-
} */
|
3220 |
-
|
3221 |
-
// $this->_settings->createWebp = (isset($_POST['createWebp']) ? 1: 0);
|
3222 |
-
|
3223 |
-
/* if( isset( $_POST['createWebp'] ) && $_POST['createWebp'] == 'on' ){
|
3224 |
-
if( isset( $_POST['deliverWebp'] ) && $_POST['deliverWebp'] == 'on' ){
|
3225 |
-
if( isset( $_POST['deliverWebpType'] ) ) {
|
3226 |
-
switch( $_POST['deliverWebpType'] ) {
|
3227 |
-
case 'deliverWebpUnaltered':
|
3228 |
-
$this->_settings->deliverWebp = 3;
|
3229 |
-
if(!$isNginx) self::alterHtaccess();
|
3230 |
-
break;
|
3231 |
-
case 'deliverWebpAltered':
|
3232 |
-
self::alterHtaccess(true);
|
3233 |
-
if( isset( $_POST['deliverWebpAlteringType'] ) ){
|
3234 |
-
switch ($_POST['deliverWebpAlteringType']) {
|
3235 |
-
case 'deliverWebpAlteredWP':
|
3236 |
-
$this->_settings->deliverWebp = 2;
|
3237 |
-
break;
|
3238 |
-
case 'deliverWebpAlteredGlobal':
|
3239 |
-
$this->_settings->deliverWebp = 1;
|
3240 |
-
break;
|
3241 |
-
}
|
3242 |
-
}
|
3243 |
-
break;
|
3244 |
-
}
|
3245 |
-
}
|
3246 |
-
} else {
|
3247 |
-
if(!$isNginx) self::alterHtaccess(true);
|
3248 |
-
$this->_settings->deliverWebp = 0;
|
3249 |
-
}
|
3250 |
-
} else {
|
3251 |
-
if(!$isNginx) self::alterHtaccess(true);
|
3252 |
-
$this->_settings->deliverWebp = 0;
|
3253 |
-
} */
|
3254 |
-
|
3255 |
-
/*$this->_settings->optimizeRetina = (isset($_POST['optimizeRetina']) ? 1: 0);
|
3256 |
-
$this->_settings->optimizeUnlisted = (isset($_POST['optimizeUnlisted']) ? 1: 0);
|
3257 |
-
$this->_settings->optimizePdfs = (isset($_POST['optimizePdfs']) ? 1: 0);
|
3258 |
-
*/
|
3259 |
-
//$this->_settings->png2jpg = (isset($_POST['png2jpg']) ? (isset($_POST['png2jpgForce']) ? 2 : 1): 0);
|
3260 |
-
|
3261 |
-
/* if(isset($_POST['excludePatterns']) && strlen($_POST['excludePatterns'])) {
|
3262 |
-
$patterns = array();
|
3263 |
-
$items = explode(',', $_POST['excludePatterns']);
|
3264 |
-
foreach($items as $pat) {
|
3265 |
-
$parts = explode(':', $pat);
|
3266 |
-
if(count($parts) == 1) {
|
3267 |
-
$patterns[] = array("type" =>"name", "value" => str_replace('\\\\','\\',trim($pat)));
|
3268 |
-
} else {
|
3269 |
-
$patterns[] = array("type" =>trim($parts[0]), "value" => str_replace('\\\\','\\',trim($parts[1])));
|
3270 |
-
}
|
3271 |
-
}
|
3272 |
-
$this->_settings->excludePatterns = $patterns;
|
3273 |
-
} else {
|
3274 |
-
$this->_settings->excludePatterns = array();
|
3275 |
-
}
|
3276 |
-
*/
|
3277 |
-
// $this->_settings->frontBootstrap = (isset($_POST['frontBootstrap']) ? 1: 0);
|
3278 |
-
// $this->_settings->autoMediaLibrary = (isset($_POST['autoMediaLibrary']) ? 1: 0);
|
3279 |
-
// $this->_settings->excludeSizes = (isset($_POST['excludeSizes']) ? $_POST['excludeSizes']: array());
|
3280 |
-
|
3281 |
-
//Redirect to bulk processing if requested
|
3282 |
-
if( isset($_POST['save']) && $_POST['save'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')
|
3283 |
-
|| isset($_POST['saveAdv']) && $_POST['saveAdv'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')) {
|
3284 |
-
wp_redirect("upload.php?page=wp-short-pixel-bulk");
|
3285 |
-
exit();
|
3286 |
-
}
|
3287 |
-
}
|
3288 |
-
/*if(isset($_POST['removeFolder']) && strlen(($_POST['removeFolder']))) {
|
3289 |
-
$this->spMetaDao->removeFolder($_POST['removeFolder']);
|
3290 |
-
$customFolders = $this->spMetaDao->getFolders();
|
3291 |
-
$_POST["saveAdv"] = true;
|
3292 |
-
} */
|
3293 |
-
if(isset($_POST['recheckFolder']) && strlen(($_POST['recheckFolder']))) {
|
3294 |
-
//$folder->fullRefreshCustomFolder($_POST['recheckFolder']); //aici singura solutie pare callback care spune daca exita url-ul complet
|
3295 |
-
}
|
3296 |
-
}
|
3297 |
-
|
3298 |
-
//now output headers. They were prevented with noheaders=true in the form url in order to be able to redirect if bulk was pressed
|
3299 |
-
/* if(isset($_REQUEST['noheader'])) {
|
3300 |
-
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
3301 |
-
} */
|
3302 |
-
|
3303 |
-
//empty backup
|
3304 |
-
/*if(isset($_POST['emptyBackup'])) {
|
3305 |
-
$this->emptyBackup();
|
3306 |
-
} */
|
3307 |
-
|
3308 |
-
//$quotaData = $this->checkQuotaAndAlert(isset($validityData) ? $validityData : null, isset($_GET['checkquota']));
|
3309 |
-
|
3310 |
-
/* if($this->hasNextGen) {
|
3311 |
-
$ngg = array_map(array('ShortPixelNextGenAdapter','pathToAbsolute'), ShortPixelNextGenAdapter::getGalleries());
|
3312 |
-
//die(var_dump($ngg));
|
3313 |
-
for($i = 0; $i < count($customFolders); $i++) {
|
3314 |
-
if(in_array($customFolders[$i]->getPath(), $ngg )) {
|
3315 |
-
$customFolders[$i]->setType("NextGen");
|
3316 |
-
}
|
3317 |
-
}
|
3318 |
-
} */
|
3319 |
-
|
3320 |
-
/* $showApiKey = ( (is_main_site() || (function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY")))
|
3321 |
-
&& !defined("SHORTPIXEL_HIDE_API_KEY"));
|
3322 |
-
$editApiKey = !defined("SHORTPIXEL_API_KEY") && $showApiKey; */
|
3323 |
-
|
3324 |
-
if($this->_settings->verifiedKey) {
|
3325 |
-
/* $fileCount = number_format($this->_settings->fileCount);
|
3326 |
-
$savedSpace = self::formatBytes($this->_settings->savedSpace,2);
|
3327 |
-
$averageCompression = $this->getAverageCompression();
|
3328 |
-
$savedBandwidth = self::formatBytes($this->_settings->savedSpace * 10000,2);
|
3329 |
-
if (is_numeric($quotaData['APICallsQuota'])) {
|
3330 |
-
$quotaData['APICallsQuota'] .= "/month";
|
3331 |
-
}
|
3332 |
-
$remainingImages = $quotaData['APICallsRemaining'];
|
3333 |
-
$remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
|
3334 |
-
$totalCallsMade = array( 'plan' => $quotaData['APICallsMadeNumeric'] , 'oneTime' => $quotaData['APICallsMadeOneTimeNumeric'] );
|
3335 |
-
*/
|
3336 |
-
/* $resources = wp_remote_post($this->_settings->httpProto . "://shortpixel.com/resources-frag");
|
3337 |
-
if(is_wp_error( $resources )) {
|
3338 |
-
$resources = array();
|
3339 |
-
} */
|
3340 |
-
|
3341 |
-
$cloudflareAPI = true;
|
3342 |
-
|
3343 |
-
$this->view->displaySettings($showApiKey, $editApiKey,
|
3344 |
-
$quotaData, $notice, $resources, $averageCompression, $savedSpace, $savedBandwidth, $remainingImages,
|
3345 |
-
$totalCallsMade, $fileCount, null /*folder size now on AJAX*/, $customFolders,
|
3346 |
-
$folderMsg, $folderMsg ? $addedFolder : false, isset($_POST['saveAdv']), $cloudflareAPI, $htaccessWriteable, $isNginx );
|
3347 |
-
} else {
|
3348 |
-
$this->view->displaySettings($showApiKey, $editApiKey, $quotaData, $notice);
|
3349 |
-
}
|
3350 |
|
3351 |
-
}
|
3352 |
|
3353 |
/** Adds NextGenGalleries to Custom Images Library
|
3354 |
* @param boolean $silent Will not return messages if silent
|
@@ -3421,6 +3212,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3421 |
$args['body']['host'] = parse_url(get_site_url(),PHP_URL_HOST);
|
3422 |
$argsStr .= "&host={$args['body']['host']}";
|
3423 |
if(strlen($this->_settings->siteAuthUser)) {
|
|
|
3424 |
$args['body']['user'] = stripslashes($this->_settings->siteAuthUser);
|
3425 |
$args['body']['pass'] = stripslashes($this->_settings->siteAuthPass);
|
3426 |
$argsStr .= '&user=' . urlencode($args['body']['user']) . '&pass=' . urlencode($args['body']['pass']);
|
@@ -3590,7 +3382,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3590 |
}
|
3591 |
|
3592 |
//empty data means document, we handle only PDF
|
3593 |
-
elseif (empty($data)) {
|
3594 |
if($fileExtension == "pdf") {
|
3595 |
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
3596 |
$renderData['message'] = __('PDF not processed.','shortpixel-image-optimiser');
|
@@ -3609,19 +3401,8 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3609 |
if( is_numeric($data['ShortPixelImprovement'])
|
3610 |
&& !($data['ShortPixelImprovement'] == 0 && isset($data['ShortPixel']['WaitingProcessing'])) //for images that erroneously have ShortPixelImprovement = 0 when WaitingProcessing
|
3611 |
) { //already optimized
|
3612 |
-
$sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
|
3613 |
-
|
3614 |
-
$thumbsToOptimize = 0;
|
3615 |
$thumbsOptList = isset($data['ShortPixel']['thumbsOptList']) ? $data['ShortPixel']['thumbsOptList'] : array();
|
3616 |
-
|
3617 |
-
$exclude = $this->_settings->excludeSizes;
|
3618 |
-
$exclude = is_array($exclude) ? $exclude : array();
|
3619 |
-
foreach($data['sizes'] as $size => $sizeData) {
|
3620 |
-
if(!in_array($size, $exclude) && !in_array($sizeData['file'], $thumbsOptList)) {
|
3621 |
-
$thumbsToOptimize++;
|
3622 |
-
}
|
3623 |
-
}
|
3624 |
-
}
|
3625 |
|
3626 |
$renderData['status'] = $fileExtension == "pdf" ? 'pdfOptimized' : 'imgOptimized';
|
3627 |
$renderData['percent'] = $this->optimizationPercentIfPng2Jpg($data);
|
@@ -3631,7 +3412,8 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3631 |
$renderData['invType'] = ShortPixelAPI::getCompressionTypeName($this->getOtherCompressionTypes(ShortPixelAPI::getCompressionTypeCode($renderData['type'])));
|
3632 |
$renderData['thumbsTotal'] = $sizesCount;
|
3633 |
$renderData['thumbsOpt'] = isset($data['ShortPixel']['thumbsOpt']) ? $data['ShortPixel']['thumbsOpt'] : $sizesCount;
|
3634 |
-
$renderData['thumbsToOptimize'] = $
|
|
|
3635 |
$renderData['thumbsOptList'] = $thumbsOptList;
|
3636 |
$renderData['excludeSizes'] = isset($data['ShortPixel']['excludeSizes']) ? $data['ShortPixel']['excludeSizes'] : null;
|
3637 |
$renderData['thumbsMissing'] = isset($data['ShortPixel']['thumbsMissing']) ? $data['ShortPixel']['thumbsMissing'] : array();
|
@@ -3660,10 +3442,12 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3660 |
/* elseif($data['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser')) { //We don't optimize this
|
3661 |
$renderData['status'] = 'n/a';
|
3662 |
}*/
|
3663 |
-
|
|
|
3664 |
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
3665 |
$renderData['message'] = 'Waiting for bulk processing.';
|
3666 |
}
|
|
|
3667 |
elseif( trim(strip_tags($data['ShortPixelImprovement'])) == __("Cannot write optimized file",'shortpixel-image-optimiser') ) {
|
3668 |
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
3669 |
$renderData['message'] = __("Cannot write optimized file",'shortpixel-image-optimiser') . " - <a href='https://shortpixel.com/faq#cannot-write-optimized-file' target='_blank'>"
|
@@ -3701,6 +3485,37 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3701 |
}
|
3702 |
}
|
3703 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3704 |
/** Make columns sortable in Media Library
|
3705 |
* @hook manage_upload_sortable_columns
|
3706 |
* @param array $columns Array of colums sortable
|
@@ -4169,6 +3984,31 @@ Header append Vary Accept env=REDIRECT_webp
|
|
4169 |
width: 87px;
|
4170 |
height: 174px;
|
4171 |
border-radius: 20px 0 0 20px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4172 |
}
|
4173 |
.shortpixel-hs-button-blind {
|
4174 |
display:none;
|
@@ -4201,10 +4041,17 @@ Header append Vary Accept env=REDIRECT_webp
|
|
4201 |
}
|
4202 |
}
|
4203 |
</style>
|
4204 |
-
<div id="shortpixel-hs-blind" class="shortpixel-hs-blind"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4205 |
<div id="shortpixel-hs-button-blind" class="shortpixel-hs-button-blind"></div>
|
4206 |
<div id="shortpixel-hs-tools" class="shortpixel-hs-tools">
|
4207 |
-
<a href="javascript:shortpixelToggleHS();" class="shortpixel-hs-tools-docs" title="Search through our online documentation.">
|
4208 |
<img src="<?php echo(plugins_url('/shortpixel-image-optimiser/res/img/notes-sp.png'));?>" style="margin-bottom: 2px;width: 36px;">
|
4209 |
</a>
|
4210 |
</div>
|
1 |
<?php
|
2 |
+
//use ShortPixel\DebugItem as DebugItem;
|
3 |
+
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
|
4 |
+
use ShortPixel\Notices\NoticeController as Notices;
|
|
|
|
|
5 |
|
6 |
class WPShortPixel {
|
7 |
|
24 |
|
25 |
public function __construct() {
|
26 |
$this->timer = time();
|
27 |
+
|
28 |
|
29 |
+
if (Log::debugIsActive()) {
|
30 |
$this->jsSuffix = '.js'; //use unminified versions for easier debugging
|
31 |
}
|
32 |
|
39 |
$this->cloudflareApi = new ShortPixelCloudFlareApi($this->_settings->cloudflareEmail, $this->_settings->cloudflareAuthKey, $this->_settings->cloudflareZoneID);
|
40 |
$this->hasNextGen = ShortPixelNextGenAdapter::hasNextGen();
|
41 |
$this->spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $this->_settings->excludePatterns);
|
42 |
+
$this->prioQ = (! defined('SHORTPIXEL_NOFLOCK')) ? new ShortPixelQueue($this, $this->_settings) : new ShortPixelQueueDB($this, $this->_settings);
|
43 |
$this->view = new ShortPixelView($this);
|
44 |
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
|
47 |
|
160 |
|
161 |
// [BS] Quite dangerous to do this in any constructor. Can hit if request is ajax to name something
|
162 |
// @todo This is intended to run only once, on activation. ( it does )
|
163 |
+
/*if(!$this->_settings->redirectedSettings && !$this->_settings->verifiedKey && (!function_exists("is_multisite") || !is_multisite())) {
|
164 |
$this->_settings->redirectedSettings = 1;
|
165 |
wp_redirect(admin_url("options-general.php?page=wp-shortpixel-settings"));
|
166 |
exit();
|
167 |
}
|
168 |
+
elseif (function_exists('is_multisite') && is_multisite() && !$this->_settings->verifiedKey)
|
169 |
+
{ // @todo not optimal, License key needs it's own model to do checks upon.
|
170 |
+
$scontrolname = \shortPixelTools::namespaceit("SettingsController");
|
171 |
+
$scontrol = new $scontrolname();
|
172 |
+
$scontrol->setShortPixel($this);
|
173 |
+
$scontrol->checkKey();
|
174 |
+
} */
|
175 |
+
|
176 |
+
//
|
177 |
|
178 |
+
// only load backed, or when frontend processing is enabled.
|
179 |
+
if (is_admin() || $this->_settings->frontBootstrap )
|
180 |
+
{
|
181 |
+
$keyControl = new \ShortPixel\apiKeyController();
|
182 |
+
$keyControl->setShortPixel($this);
|
183 |
+
$keyControl->load();
|
184 |
+
}
|
185 |
}
|
186 |
|
187 |
//handling older
|
216 |
$spMetaDao = new ShortPixelCustomMetaDao(new WpShortPixelDb(), $settings->excludePatterns);
|
217 |
$spMetaDao->dropTables();
|
218 |
}
|
219 |
+
|
220 |
+
$settingsControl = new \ShortPixel\SettingsController();
|
221 |
+
$env = $settingsControl->getEnv();
|
222 |
+
|
223 |
+
|
224 |
+
if(WPShortPixelSettings::getOpt('deliverWebp') == 3 && ! $env->is_nginx) {
|
225 |
self::alterHtaccess(); //add the htaccess lines
|
226 |
}
|
227 |
WPShortPixelSettings::onActivate();
|
230 |
public static function shortPixelDeactivatePlugin()//reset some params to avoid trouble for plugins that were activated/deactivated/activated
|
231 |
{
|
232 |
ShortPixelQueue::resetBulk();
|
233 |
+
(! defined('SHORTPIXEL_NOFLOCK')) ? ShortPixelQueue::resetPrio() : ShortPixelQueueDB::resetPrio();
|
234 |
WPShortPixelSettings::onDeactivate();
|
235 |
+
|
236 |
+
$settingsControl = new \ShortPixel\SettingsController();
|
237 |
+
$env = $settingsControl->getEnv();
|
238 |
+
|
239 |
+
if (! $env->is_nginx)
|
240 |
+
self::alterHtaccess(true);
|
241 |
+
|
242 |
@unlink(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log");
|
243 |
}
|
244 |
|
334 |
*/
|
335 |
);
|
336 |
if($this->_settings->processThumbnails) {
|
337 |
+
$details = __('Details: recreating image files may require re-optimization of the resulting thumbnails, even if they were previously optimized. Please use <a href="https://wordpress.org/plugins/regenerate-thumbnails-advanced/" target="_blank">reGenerate Thumbnails Advanced</a> instead.','shortpixel-image-optimiser');
|
338 |
+
|
339 |
$conflictPlugins = array_merge($conflictPlugins, array(
|
340 |
+
'Regenerate Thumbnails'
|
341 |
=> array(
|
342 |
'action'=>'Deactivate',
|
343 |
'data'=>'regenerate-thumbnails/regenerate-thumbnails.php',
|
344 |
+
'page'=>'regenerate-thumbnails',
|
345 |
+
'details' => $details
|
346 |
),
|
347 |
+
'Force Regenerate Thumbnails'
|
348 |
=> array(
|
349 |
'action'=>'Deactivate',
|
350 |
'data'=>'force-regenerate-thumbnails/force-regenerate-thumbnails.php',
|
351 |
+
'page'=>'force-regenerate-thumbnails',
|
352 |
+
'details' => $details
|
353 |
)
|
354 |
));
|
355 |
}
|
359 |
$data = ( isset($path['data']) ) ? $path['data'] : null;
|
360 |
$href = ( isset($path['href']) ) ? $path['href'] : null;
|
361 |
$page = ( isset($path['page']) ) ? $path['page'] : null;
|
362 |
+
$details = ( isset($path['details']) ) ? $path['details'] : null;
|
363 |
if(is_plugin_active($data)) {
|
364 |
if( $data == 'jetpack/jetpack.php' ){
|
365 |
$jetPackPhoton = get_option('jetpack_active_modules') ? in_array('photon', get_option('jetpack_active_modules')) : false;
|
366 |
if( !$jetPackPhoton ){ continue; }
|
367 |
}
|
368 |
+
$found[] = array( 'name' => $name, 'action'=> $action, 'path' => $data, 'href' => $href , 'page' => $page, 'details' => $details);
|
369 |
}
|
370 |
}
|
371 |
return $found;
|
375 |
* TODO - Probably should be a controller
|
376 |
*/
|
377 |
public function displayAdminNotices() {
|
378 |
+
$testQ = (! defined('SHORTPIXEL_NOFLOCK')) ? ShortPixelQueue::testQ() : ShortPixelQueueDB::testQ();
|
379 |
+
if(! $testQ) {
|
380 |
ShortPixelView::displayActivationNotice('fileperms');
|
381 |
}
|
382 |
if($this->catchNotice()) { //notices for errors like for example a failed restore notice - these are one time so display them with priority.
|
499 |
|
500 |
/** [TODO] This should report to the Shortpixel Logger **/
|
501 |
static protected function doLog($message, $force = false) {
|
502 |
+
// Log::addInfo($message);
|
503 |
/*if(defined('SHORTPIXEL_DEBUG_TARGET') || $force) {
|
504 |
file_put_contents(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log", '[' . date('Y-m-d H:i:s') . "] $message\n", FILE_APPEND);
|
505 |
} else {
|
550 |
'STATUS_RETRY'=>ShortPixelAPI::STATUS_RETRY,
|
551 |
'STATUS_QUEUE_FULL'=>ShortPixelAPI::STATUS_QUEUE_FULL,
|
552 |
'STATUS_MAINTENANCE'=>ShortPixelAPI::STATUS_MAINTENANCE,
|
553 |
+
'STATUS_SEARCHING' => ShortPixelAPI::STATUS_SEARCHING,
|
554 |
'WP_PLUGIN_URL'=>plugins_url( '', SHORTPIXEL_PLUGIN_FILE ),
|
555 |
'WP_ADMIN_URL'=>admin_url(),
|
556 |
'API_KEY'=> (defined("SHORTPIXEL_HIDE_API_KEY" ) || !is_admin() ) ? '' : $this->_settings->apiKey,
|
558 |
'MEDIA_ALERT'=>$this->_settings->mediaAlert ? "done" : "todo",
|
559 |
'FRONT_BOOTSTRAP'=>$this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0,
|
560 |
'AJAX_URL'=>admin_url('admin-ajax.php'),
|
561 |
+
'AFFILIATE'=>false
|
562 |
));
|
563 |
|
564 |
if (Log::isManualDebug() )
|
604 |
|
605 |
wp_enqueue_script('jquery.knob.min.js', plugins_url('/res/js/jquery.knob.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
606 |
wp_enqueue_script('jquery.tooltip.min.js', plugins_url('/res/js/jquery.tooltip.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
607 |
+
|
608 |
+
|
609 |
wp_enqueue_script('punycode.min.js', plugins_url('/res/js/punycode.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
610 |
}
|
611 |
|
1127 |
$passTime = time();
|
1128 |
$maxResults = $timeoutThreshold > 15 ? SHORTPIXEL_MAX_RESULTS_QUERY / 3 :
|
1129 |
($timeoutThreshold > 10 ? SHORTPIXEL_MAX_RESULTS_QUERY / 2 : SHORTPIXEL_MAX_RESULTS_QUERY);
|
1130 |
+
Log::addInfo("GETDB: pass $sanityCheck current StartID: $crtStartQueryID Threshold: $timeoutThreshold, MaxResults: $maxResults" );
|
1131 |
|
1132 |
/* $queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
1133 |
WHERE ( post_id <= $crtStartQueryID AND post_id >= $endQueryID )
|
1136 |
LIMIT " . SHORTPIXEL_MAX_RESULTS_QUERY;
|
1137 |
$resultsPostMeta = $wpdb->get_results($queryPostMeta);
|
1138 |
*/
|
1139 |
+
// $resultsPostMeta = WpShortPixelMediaLbraryAdapter::getPostMetaSlice($crtStartQueryID, $endQueryID, $maxResults);
|
1140 |
+
// @todo Remove. Just Speed Test
|
1141 |
+
// Log::addDebug('PostMetaSlice took ' . (microtime(true) - $time) . ' sec.');
|
1142 |
|
1143 |
+
// $resultsPostMeta2 = WpShortPixelMediaLbraryAdapter::getPostMetaJoinLess($crtStartQueryID, $endQueryID, $maxResults);
|
1144 |
+
// Log::addDebug('PostMetaJoinLess took ' . (microtime(true) - $time) . ' sec.');
|
1145 |
|
1146 |
+
$resultsPosts = WpShortPixelMediaLbraryAdapter::getPostsJoinLessReverse($crtStartQueryID, $endQueryID, $maxResults);
|
1147 |
+
// Log::addDebug('PostMetaJoinLess *REV took ' . (microtime(true) - $time) . ' sec.');
|
1148 |
+
// */
|
1149 |
+
if(time() - $this->timer >= 60)
|
1150 |
+
Log::addWarn("GETDB is SLOW. Got meta slice.");
|
1151 |
+
|
1152 |
+
// @todo MAX RESULTS constant is not the same as queries maxResults? Is this correct?
|
1153 |
+
if ( empty($resultsPosts) ) {
|
1154 |
$crtStartQueryID -= SHORTPIXEL_MAX_RESULTS_QUERY;
|
1155 |
$startQueryID = $crtStartQueryID;
|
1156 |
if(!count($idList)) { //none found so far, so decrease the start ID
|
1157 |
+
Log::addInfo("GETDB: empty slice. setStartBulkID to $startQueryID");
|
1158 |
$this->prioQ->setStartBulkId($startQueryID);
|
1159 |
}
|
1160 |
continue;
|
1161 |
}
|
1162 |
|
1163 |
+
if($timeoutThreshold > 10) Log::addInfo("GETDB is SLOW. Meta slice has " . count($resultsPosts) . ' items.');
|
1164 |
|
1165 |
+
$counter = 0;
|
1166 |
+
foreach ( $resultsPosts as $index => $post_id ) {
|
1167 |
+
$crtStartQueryID = $post_id; // $itemMetaData->post_id;
|
1168 |
+
if(time() - $this->timer >= 60) Log::addInfo("GETDB is SO SLOW. Check processable for $crtStartQueryID.");
|
1169 |
if(time() - $this->timer >= $maxTime - $timeoutThreshold){
|
1170 |
+
if($counter == 0 && set_time_limit(30)) {
|
1171 |
+
self::log("GETDB is SO SLOW. Increasing time limit by 30 sec succeeded.");
|
1172 |
+
$maxTime += 30 - $timeoutThreshold;
|
1173 |
+
} else {
|
1174 |
+
self::log("GETDB is SO SLOW. Breaking after processing $counter items. Time limit is over: " . ($maxTime - $timeoutThreshold));
|
1175 |
+
break;
|
1176 |
+
}
|
1177 |
}
|
1178 |
+
$counter++;
|
1179 |
|
1180 |
if(!in_array($crtStartQueryID, $idList) && $this->isProcessable($crtStartQueryID, ($this->_settings->optimizePdfs ? array() : array('pdf')))) {
|
1181 |
$item = new ShortPixelMetaFacade($crtStartQueryID);
|
1182 |
|
1183 |
+
if($timeoutThreshold > 15) Log::addInfo("GETDB is SO SLOW. Get meta for $crtStartQueryID.");
|
1184 |
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
1185 |
+
if($timeoutThreshold > 15) Log::addInfo("GETDB is SO SLOW. Got meta.");
|
1186 |
|
1187 |
if($meta->getStatus() != 2) {
|
1188 |
$addIt = (strpos($meta->getMessage(), __('Image files are missing.', 'shortpixel-image-optimiser')) === false);
|
1210 |
$skippedAlreadyProcessed++;
|
1211 |
}
|
1212 |
}
|
1213 |
+
elseif( $this->_settings->processThumbnails && $meta->getThumbsOpt() !== null //thumbs were chosen in settings
|
1214 |
+
&& ($meta->getThumbsOpt() == 0 && count($meta->getThumbs()) > 0 //no thumbnails optimized
|
1215 |
|| is_array($meta->getThumbsOptList())
|
1216 |
&& count(array_diff(array_keys(WpShortPixelMediaLbraryAdapter::getSizesNotExcluded($meta->getThumbs(), $this->_settings->excludeSizes)),
|
1217 |
+
$meta->getThumbsOptList()))
|
1218 |
+
|| ( $this->_settings->optimizeUnlisted
|
1219 |
+
&& count(array_diff(WpShortPixelMediaLbraryAdapter::findThumbs($meta->getPath()), $meta->getThumbsOptList()))
|
1220 |
+
)
|
1221 |
+
)
|
1222 |
+
) {
|
1223 |
$URLsAndPATHs = $item->getURLsAndPATHs(true, true, $this->_settings->optimizeRetina, $this->_settings->excludeSizes);
|
1224 |
if(count($URLsAndPATHs["URLs"])) {
|
1225 |
$meta->setThumbsTodo(true);
|
1229 |
if(count($itemList) > SHORTPIXEL_PRESEND_ITEMS) break;
|
1230 |
}
|
1231 |
}
|
1232 |
+
/* New query selects this out, also no metadata returned.
|
1233 |
elseif($itemMetaData->meta_key == '_wp_attachment_metadata') { //count skipped
|
1234 |
$skippedAlreadyProcessed++;
|
1235 |
}
|
1236 |
+
*/
|
1237 |
}
|
1238 |
}
|
1239 |
if(!count($idList) && $crtStartQueryID <= $startQueryID) {
|
1240 |
//daca n-am adaugat niciuna pana acum, n-are sens sa mai selectez zona asta de id-uri in bulk-ul asta.
|
1241 |
$leapStart = $this->prioQ->getStartBulkId();
|
1242 |
+
$crtStartQueryID = $startQueryID = $post_id - 1; //decrement it so we don't select it again
|
1243 |
$res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->_settings, $leapStart, $crtStartQueryID);
|
1244 |
$skippedAlreadyProcessed += $res["mainProcessedFiles"] - $res["mainProc".($this->getCompressionType() == 1 ? "Lossy" : "Lossless")."Files"];
|
1245 |
+
Log::addInfo("GETDB: empty list. setStartBulkID to $startQueryID");
|
1246 |
$this->prioQ->setStartBulkId($startQueryID);
|
1247 |
} else {
|
1248 |
$crtStartQueryID--;
|
1249 |
+
Log::addInfo("GETDB just decrementing. Crt: $crtStartQueryID Start: $startQueryID, list: " . json_encode($idList));
|
1250 |
}
|
1251 |
}
|
1252 |
$ret = array("items" => $itemList, "skipped" => $skippedAlreadyProcessed, "searching" => ($sanityCheck >= 150) || (time() - $this->timer >= $maxTime - $timeoutThreshold));
|
1270 |
|
1271 |
/** Checks the API key **/
|
1272 |
private function checkKey($ID) {
|
1273 |
+
if( $this->_settings->verifiedKey == false) {
|
1274 |
if($ID == null){
|
1275 |
$ids = $this->getFromPrioAndCheck(1);
|
1276 |
$itemHandler = (count($ids) > 0 ? $ids[0] : null);
|
1284 |
private function sendEmptyQueue() {
|
1285 |
$avg = $this->getAverageCompression();
|
1286 |
$fileCount = $this->_settings->fileCount;
|
1287 |
+
|
1288 |
+
if($this->prioQ->bulkRunning())
|
1289 |
+
{
|
1290 |
+
$bulkstatus = '1';
|
1291 |
+
}
|
1292 |
+
elseif ($this->prioQ->bulkPaused())
|
1293 |
+
{
|
1294 |
+
$bulkstatus = '2';
|
1295 |
+
}
|
1296 |
+
else {
|
1297 |
+
$bulkstatus = '0';
|
1298 |
+
}
|
1299 |
+
|
1300 |
$response = array("Status" => self::BULK_EMPTY_QUEUE,
|
1301 |
/* translators: console message Empty queue 1234 -> 1234 */
|
1302 |
"Message" => __('Empty queue ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId(),
|
1303 |
+
"BulkStatus" => $bulkstatus,
|
|
|
1304 |
"AverageCompression" => $avg,
|
1305 |
"FileCount" => $fileCount,
|
1306 |
"BulkPercent" => $this->prioQ->getBulkPercent());
|
1325 |
}
|
1326 |
|
1327 |
$rawPrioQ = $this->prioQ->get();
|
1328 |
+
if(count($rawPrioQ)) { Log::addInfo("HIP: 0 Priority Queue: ".json_encode($rawPrioQ)); }
|
1329 |
+
Log::addInfo("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId . " MaxTime: " . SHORTPIXEL_MAX_EXECUTION_TIME);
|
1330 |
|
1331 |
//handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
|
1332 |
if( $this->prioQ->bulkRunning()
|
1387 |
//die("za stop 2");
|
1388 |
|
1389 |
//self::log("HIP: 1 Ids: ".json_encode($ids));
|
1390 |
+
if(count($ids)) {$idl='';foreach($ids as $i){$idl.=$i->getId().' ';}
|
1391 |
+
Log::addInfo("HIP: 1 Selected IDs: $idl");}
|
1392 |
|
1393 |
//2: Send up to SHORTPIXEL_PRESEND_ITEMS files to the server for processing
|
1394 |
for($i = 0, $itemHandler = false; $ids !== false && $i < min(SHORTPIXEL_PRESEND_ITEMS, count($ids)); $i++) {
|
1419 |
if (!$itemHandler){
|
1420 |
//if searching, than the script is searching for not processed items and found none yet, should be relaunced
|
1421 |
if(isset($res['searching']) && $res['searching']) {
|
1422 |
+
die(json_encode(array("Status" => ShortPixelAPI::STATUS_SEARCHING,
|
1423 |
"Message" => __('Searching images to optimize... ','shortpixel-image-optimiser') . $this->prioQ->getStartBulkId() . '->' . $this->prioQ->getStopBulkId() )));
|
1424 |
}
|
1425 |
//in this case the queue is really empty
|
1518 |
$bkThumb = $backupUrl . $urlBkPath . $thumb;
|
1519 |
}
|
1520 |
if(strlen($thumb)) {
|
1521 |
+
/** @todo This Check is maybe within a getType for Media_Library_Type, so this should not run. **/
|
1522 |
if($itemHandler->getType() == ShortPixelMetaFacade::CUSTOM_TYPE) {
|
1523 |
$uploadsUrl = ShortPixelMetaFacade::getHomeUrl();
|
1524 |
$urlPath = ShortPixelMetaFacade::returnSubDir($meta->getPath());
|
2186 |
* @param int $ID image_id, without any prefixes
|
2187 |
*/
|
2188 |
public function doCustomRestore($ID) {
|
2189 |
+
|
2190 |
// meta facade as a custom image
|
2191 |
$itemHandler = new ShortPixelMetaFacade('C-' . $ID);
|
2192 |
$meta = $itemHandler->getMeta();
|
2206 |
$fullSubDir = str_replace(get_home_path(), "", dirname($file)) . '/';
|
2207 |
$bkFile = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir . ShortPixelAPI::MB_basename($file);
|
2208 |
|
2209 |
+
$fs = new \ShortPixel\FileSystemController();
|
|
|
|
|
|
|
|
|
|
|
2210 |
|
2211 |
+
$fileObj = $fs->getFile($file);
|
2212 |
+
$backupFile = $fileObj->getBackupFile(); // returns FileModel
|
2213 |
|
2214 |
+
if($backupFile === false)
|
2215 |
+
{
|
2216 |
+
Log::addWarn("Custom File $ID - $file does not have a backup");
|
2217 |
+
Notices::addWarning(sprintf(__('Not able to restore file %s. Could not find backup', 'shortpixel-image-optimiser'), $file));
|
2218 |
+
return false;
|
2219 |
+
}
|
2220 |
|
2221 |
+
if ($backupFile->copy($fileObj))
|
2222 |
+
{
|
2223 |
+
$backupFile->delete();
|
2224 |
+
}
|
2225 |
+
else {
|
2226 |
+
Log::addError('Could not restore back to source' . $backupFile->getFullPath() );
|
2227 |
+
Notices::addError('The file could not be restored from backup. Plugin could not copy backup back to original location. Check file permissions. ', 'shortpixel-image-optimiser');
|
2228 |
+
return false;
|
2229 |
+
}
|
|
|
|
|
2230 |
|
2231 |
+
/* [BS] Reset all generated image meta. Bring back to start state.
|
2232 |
+
* Since Wpdb->prepare doesn't support 'null', zero values in this table should not be trusted */
|
2233 |
|
2234 |
+
$meta->setTsOptimized(0);
|
2235 |
+
$meta->setCompressedSize(0);
|
2236 |
+
$meta->setCompressionType(0);
|
2237 |
+
$meta->setKeepExif(0);
|
2238 |
+
$meta->setCmyk2rgb(0);
|
2239 |
+
$meta->setMessage('');
|
2240 |
+
$meta->setRetries(0);
|
2241 |
+
$meta->setBackup(0);
|
2242 |
+
$meta->setResizeWidth(0);
|
2243 |
+
$meta->setResizeHeight(0);
|
2244 |
+
$meta->setResize(0);
|
2245 |
|
2246 |
+
$meta->setStatus(3);
|
2247 |
+
$this->spMetaDao->update($meta);
|
2248 |
+
|
2249 |
+
|
2250 |
+
//}
|
2251 |
|
2252 |
return $meta;
|
2253 |
}
|
2278 |
|
2279 |
if(ShortPixelMetaFacade::isCustomQueuedId($qID)) {
|
2280 |
$ID = ShortPixelMetaFacade::stripQueuedIdType($qID);
|
2281 |
+
/** BS . Moved this function from customRestore to Delete, plus Re-add 19/06/2019
|
2282 |
+
* Reason: doCustomRestore puts all options to 0 including once that needs preserving, which
|
2283 |
+
* will result in setting loss.
|
2284 |
+
* *But* the backup still needs to be restoring on 'redo' *so* do restore, but ignore that meta, then delete, and readd path.
|
2285 |
+
*/
|
2286 |
+
$meta = $this->spMetaDao->getMeta($ID);
|
2287 |
+
$path = $meta->getPath();
|
2288 |
+
$folder_id = $meta->getFolderId();
|
2289 |
+
$this->doCustomRestore($ID);
|
2290 |
+
|
2291 |
+
$this->spMetaDao->delete($meta);
|
2292 |
+
$meta = $this->addPathToCustomFolder($path, $folder_id, NULL);
|
2293 |
+
|
2294 |
if($meta) {
|
2295 |
$meta->setCompressionType(ShortPixelAPI::getCompressionTypeCode($compressionType));
|
2296 |
$meta->setStatus(1);
|
2335 |
//$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);
|
2336 |
$error = array('Status' => ShortPixelAPI::STATUS_SKIP, 'message' => __('Unspecified Error on Thumbnails for: ') . $ID);
|
2337 |
|
2338 |
+
list($includedSizes, $thumbsCount) = $this->getThumbsToOptimize($meta, get_attached_file($ID));
|
2339 |
+
//WpShortPixelMediaLbraryAdapter::getSizesNotExcluded($meta['sizes'], $this->_settings->excludeSizes);
|
2340 |
$thumbsCount = count($includedSizes);
|
2341 |
|
2342 |
if (! isset($meta['ShortPixelImprovement']))
|
2527 |
}
|
2528 |
if ( !$quotaData['APIKeyValid']) {
|
2529 |
if(strlen($this->_settings->apiKey))
|
2530 |
+
Notices::addError(sprintf(__('Shortpixel Remote API Error: %s','shortpixel-image-optimiser'), $quotaData['Message'] ));
|
2531 |
return $quotaData;
|
2532 |
}
|
2533 |
//$tempus = microtime(true);
|
2674 |
|
2675 |
if(isset($_POST["bulkRestore"]))
|
2676 |
{
|
2677 |
+
Log::addInfo('Bulk Process - Bulk Restore');
|
2678 |
+
|
2679 |
$bulkRestore = new \ShortPixel\BulkRestoreAll(); // controller
|
2680 |
$bulkRestore->setShortPixel($this);
|
2681 |
$bulkRestore->setupBulk();
|
2686 |
|
2687 |
if(isset($_POST["bulkCleanup"]))
|
2688 |
{
|
2689 |
+
Log::addInfo('Bulk Process - Bulk Cleanup ');
|
2690 |
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_CLEANUP);
|
2691 |
$this->_settings->customBulkPaused = 0;
|
2692 |
}//end bulk restore was clicked
|
2693 |
|
2694 |
if(isset($_POST["bulkCleanupPending"]))
|
2695 |
{
|
2696 |
+
Log::addInfo('Bulk Process - Clean Pending');
|
2697 |
$this->prioQ->startBulk(ShortPixelQueue::BULK_TYPE_CLEANUP_PENDING);
|
2698 |
$this->_settings->customBulkPaused = 0;
|
2699 |
}//end bulk restore was clicked
|
2700 |
|
2701 |
if(isset($_POST["bulkProcessResume"]))
|
2702 |
{
|
2703 |
+
Log::addInfo('Bulk Process - Bulk Resume');
|
2704 |
$this->prioQ->resumeBulk();
|
2705 |
$this->_settings->customBulkPaused = 0;
|
2706 |
}//resume was clicked
|
2707 |
|
2708 |
if(isset($_POST["skipToCustom"]))
|
2709 |
{
|
2710 |
+
Log::addInfo('Bulk Process - Skipping to Custom Media Process');
|
2711 |
$this->_settings->skipToCustom = true;
|
2712 |
+
$this->_settings->customBulkPaused = 0;
|
2713 |
+
|
2714 |
}//resume was clicked
|
2715 |
|
2716 |
//figure out the files that are left to be processed
|
2720 |
|
2721 |
//check the custom bulk
|
2722 |
$pendingMeta = $this->_settings->hasCustomFolders ? $this->spMetaDao->getPendingMetaCount() : 0;
|
2723 |
+
Log::addInfo('Bulk Process - Pending Meta Count ' . $pendingMeta);
|
2724 |
+
Log::addInfo('Bulk Process - File left ' . $filesLeft[0]->FilesLeftToBeProcessed );
|
2725 |
|
2726 |
if ( ($filesLeft[0]->FilesLeftToBeProcessed > 0 && $this->prioQ->bulkRunning())
|
2727 |
|| (0 + $pendingMeta > 0 && !$this->_settings->customBulkPaused && $this->prioQ->bulkRan())//bulk processing was started
|
2738 |
{
|
2739 |
if($this->prioQ->bulkRan() && !$this->prioQ->bulkPaused()) {
|
2740 |
$this->prioQ->markBulkComplete();
|
2741 |
+
Log::addInfo("Bulk Process - Marked Bulk Complete");
|
2742 |
}
|
2743 |
|
2744 |
//image count
|
3135 |
|
3136 |
insert_with_markers( $upload_base . '.htaccess', 'ShortPixelWebp', $rules);
|
3137 |
insert_with_markers( trailingslashit(WP_CONTENT_DIR) . '.htaccess', 'ShortPixelWebp', $rules);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3138 |
|
|
|
|
|
|
|
|
|
|
|
|
|
3139 |
}
|
3140 |
+
}
|
3141 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3142 |
|
|
|
3143 |
|
3144 |
/** Adds NextGenGalleries to Custom Images Library
|
3145 |
* @param boolean $silent Will not return messages if silent
|
3212 |
$args['body']['host'] = parse_url(get_site_url(),PHP_URL_HOST);
|
3213 |
$argsStr .= "&host={$args['body']['host']}";
|
3214 |
if(strlen($this->_settings->siteAuthUser)) {
|
3215 |
+
|
3216 |
$args['body']['user'] = stripslashes($this->_settings->siteAuthUser);
|
3217 |
$args['body']['pass'] = stripslashes($this->_settings->siteAuthPass);
|
3218 |
$argsStr .= '&user=' . urlencode($args['body']['user']) . '&pass=' . urlencode($args['body']['pass']);
|
3382 |
}
|
3383 |
|
3384 |
//empty data means document, we handle only PDF
|
3385 |
+
elseif (empty($data)) {
|
3386 |
if($fileExtension == "pdf") {
|
3387 |
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
3388 |
$renderData['message'] = __('PDF not processed.','shortpixel-image-optimiser');
|
3401 |
if( is_numeric($data['ShortPixelImprovement'])
|
3402 |
&& !($data['ShortPixelImprovement'] == 0 && isset($data['ShortPixel']['WaitingProcessing'])) //for images that erroneously have ShortPixelImprovement = 0 when WaitingProcessing
|
3403 |
) { //already optimized
|
|
|
|
|
|
|
3404 |
$thumbsOptList = isset($data['ShortPixel']['thumbsOptList']) ? $data['ShortPixel']['thumbsOptList'] : array();
|
3405 |
+
list($thumbsToOptimizeList, $sizesCount) = $this->getThumbsToOptimize($data, $file);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3406 |
|
3407 |
$renderData['status'] = $fileExtension == "pdf" ? 'pdfOptimized' : 'imgOptimized';
|
3408 |
$renderData['percent'] = $this->optimizationPercentIfPng2Jpg($data);
|
3412 |
$renderData['invType'] = ShortPixelAPI::getCompressionTypeName($this->getOtherCompressionTypes(ShortPixelAPI::getCompressionTypeCode($renderData['type'])));
|
3413 |
$renderData['thumbsTotal'] = $sizesCount;
|
3414 |
$renderData['thumbsOpt'] = isset($data['ShortPixel']['thumbsOpt']) ? $data['ShortPixel']['thumbsOpt'] : $sizesCount;
|
3415 |
+
$renderData['thumbsToOptimize'] = count($thumbsToOptimizeList);
|
3416 |
+
$renderData['thumbsToOptimizeList'] = $thumbsToOptimizeList;
|
3417 |
$renderData['thumbsOptList'] = $thumbsOptList;
|
3418 |
$renderData['excludeSizes'] = isset($data['ShortPixel']['excludeSizes']) ? $data['ShortPixel']['excludeSizes'] : null;
|
3419 |
$renderData['thumbsMissing'] = isset($data['ShortPixel']['thumbsMissing']) ? $data['ShortPixel']['thumbsMissing'] : array();
|
3442 |
/* elseif($data['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser')) { //We don't optimize this
|
3443 |
$renderData['status'] = 'n/a';
|
3444 |
}*/
|
3445 |
+
/*
|
3446 |
+
elseif(isset($meta['ShortPixel']['BulkProcessing'])) { //Scheduled to bulk. !!! removed as the BulkProcessing is never set and it should be $data anyway.... :)
|
3447 |
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'optimizeNow';
|
3448 |
$renderData['message'] = 'Waiting for bulk processing.';
|
3449 |
}
|
3450 |
+
*/
|
3451 |
elseif( trim(strip_tags($data['ShortPixelImprovement'])) == __("Cannot write optimized file",'shortpixel-image-optimiser') ) {
|
3452 |
$renderData['status'] = $quotaExceeded ? 'quotaExceeded' : 'retry';
|
3453 |
$renderData['message'] = __("Cannot write optimized file",'shortpixel-image-optimiser') . " - <a href='https://shortpixel.com/faq#cannot-write-optimized-file' target='_blank'>"
|
3485 |
}
|
3486 |
}
|
3487 |
|
3488 |
+
/**
|
3489 |
+
* return the thumbnails that remain to optimize and the total count of sizes registered in metdata (and not excluded)
|
3490 |
+
* @param $data
|
3491 |
+
* @param $file
|
3492 |
+
* @return array
|
3493 |
+
*/
|
3494 |
+
function getThumbsToOptimize($data, $file) {
|
3495 |
+
$sizesCount = isset($data['sizes']) ? WpShortPixelMediaLbraryAdapter::countSizesNotExcluded($data['sizes']) : 0;
|
3496 |
+
$basedir = trailingslashit(dirname($file));
|
3497 |
+
$thumbsOptList = isset($data['ShortPixel']['thumbsOptList']) ? $data['ShortPixel']['thumbsOptList'] : array();
|
3498 |
+
if($sizesCount && $this->_settings->processThumbnails) {
|
3499 |
+
|
3500 |
+
$thumbsToOptimizeList = array();
|
3501 |
+
$found = $this->_settings->optimizeUnlisted ? WpShortPixelMediaLbraryAdapter::findThumbs($file) : array();
|
3502 |
+
|
3503 |
+
$exclude = $this->_settings->excludeSizes;
|
3504 |
+
$exclude = is_array($exclude) ? $exclude : array();
|
3505 |
+
foreach($data['sizes'] as $size => $sizeData) {
|
3506 |
+
unset($found[\array_search($basedir . $sizeData['file'], $found)]);
|
3507 |
+
if(!in_array($size, $exclude) && !in_array($sizeData['file'], $thumbsOptList)) {
|
3508 |
+
$thumbsToOptimizeList[] = $sizeData['file'];
|
3509 |
+
}
|
3510 |
+
}
|
3511 |
+
$found = array_diff($found, $thumbsOptList);
|
3512 |
+
foreach($found as $item) {
|
3513 |
+
$thumbsToOptimizeList[] = wp_basename($item);
|
3514 |
+
}
|
3515 |
+
}
|
3516 |
+
return array($thumbsToOptimizeList, $sizesCount);
|
3517 |
+
}
|
3518 |
+
|
3519 |
/** Make columns sortable in Media Library
|
3520 |
* @hook manage_upload_sortable_columns
|
3521 |
* @param array $columns Array of colums sortable
|
3984 |
width: 87px;
|
3985 |
height: 174px;
|
3986 |
border-radius: 20px 0 0 20px;
|
3987 |
+
text-align: right;
|
3988 |
+
padding-right: 15px;
|
3989 |
+
}
|
3990 |
+
.shortpixel-hs-blind a {
|
3991 |
+
color: lightgray;
|
3992 |
+
text-decoration: none;
|
3993 |
+
}
|
3994 |
+
.shortpixel-hs-blind .dashicons-minus {
|
3995 |
+
border: 3px solid;
|
3996 |
+
border-radius: 12px;
|
3997 |
+
font-size: 12px;
|
3998 |
+
font-weight: bold;
|
3999 |
+
line-height: 15px;
|
4000 |
+
height: 13px;
|
4001 |
+
width: 13px;
|
4002 |
+
display:none;
|
4003 |
+
}
|
4004 |
+
.shortpixel-hs-blind .dashicons-dismiss {
|
4005 |
+
font-size: 23px;
|
4006 |
+
line-height: 19px;
|
4007 |
+
display: none;
|
4008 |
+
}
|
4009 |
+
.shortpixel-hs-blind:hover .dashicons-minus,
|
4010 |
+
.shortpixel-hs-blind:hover .dashicons-dismiss {
|
4011 |
+
display: inline-block;
|
4012 |
}
|
4013 |
.shortpixel-hs-button-blind {
|
4014 |
display:none;
|
4041 |
}
|
4042 |
}
|
4043 |
</style>
|
4044 |
+
<div id="shortpixel-hs-blind" class="shortpixel-hs-blind">
|
4045 |
+
<a href="javascript:ShortPixel.closeHelpPane();">
|
4046 |
+
<i class="dashicons dashicons-minus" title="<?php _e('Dismiss for now', 'shortpixel-image-optimiser'); ?> "></i>
|
4047 |
+
</a>
|
4048 |
+
<a href="javascript:ShortPixel.dismissHelpPane();">
|
4049 |
+
<i class="dashicons dashicons-dismiss" title="<?php _e('Never display again', 'shortpixel-image-optimiser'); ?>"></i>
|
4050 |
+
</a>
|
4051 |
+
</div>
|
4052 |
<div id="shortpixel-hs-button-blind" class="shortpixel-hs-button-blind"></div>
|
4053 |
<div id="shortpixel-hs-tools" class="shortpixel-hs-tools">
|
4054 |
+
<a href="javascript:shortpixelToggleHS();" class="shortpixel-hs-tools-docs" title="<?php _e('Search through our online documentation.', 'shortpixel-image-optimiser'); ?>">
|
4055 |
<img src="<?php echo(plugins_url('/shortpixel-image-optimiser/res/img/notes-sp.png'));?>" style="margin-bottom: 2px;width: 36px;">
|
4056 |
</a>
|
4057 |
</div>
|
@@ -185,8 +185,10 @@ class WPShortPixelSettings extends ShortPixel\ShortPixelModel {
|
|
185 |
update_option('wp-short-pixel-dismissed-notices', $dismissed, 'no');
|
186 |
}
|
187 |
$formerPrio = get_option('wp-short-pixel-priorityQueue');
|
188 |
-
|
189 |
-
|
|
|
|
|
190 |
delete_option('wp-short-pixel-priorityQueue');
|
191 |
}
|
192 |
}
|
185 |
update_option('wp-short-pixel-dismissed-notices', $dismissed, 'no');
|
186 |
}
|
187 |
$formerPrio = get_option('wp-short-pixel-priorityQueue');
|
188 |
+
$qGet = (! defined('SHORTPIXEL_NOFLOCK')) ? ShortPixelQueue::get() : ShortPixelQueueDB::get();
|
189 |
+
if(is_array($formerPrio) && !count($qGet)) {
|
190 |
+
|
191 |
+
(! defined('SHORTPIXEL_NOFLOCK')) ? ShortPixelQueue::set($formerPrio) : ShortPixelQueueDB::set($formerPrio);
|
192 |
delete_option('wp-short-pixel-priorityQueue');
|
193 |
}
|
194 |
}
|
@@ -1,10 +1,10 @@
|
|
1 |
=== ShortPixel Image Optimizer ===
|
2 |
-
Contributors: ShortPixel
|
3 |
Tags: compressor, image, compression, optimize, image optimizer, image optimiser, image compression, resize, compress pdf, compress jpg, compress png, image compression
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 5.2
|
6 |
Requires PHP: 5.3
|
7 |
-
Stable tag: 4.14.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -61,17 +61,17 @@ Make an instant <a href="http://shortpixel.com/image-compression-test" target="_
|
|
61 |
* 40 days optimization report with all image details and overall statistics
|
62 |
* We are GDPR compliant! <a href="https://shortpixel.com/privacy#gdpr" target="_blank">Read more.</a>
|
63 |
* **free optimization credits for non-profits**, <a href="https://shortpixel.com/contact" target="_blank">contact us</a> for details
|
64 |
-
|
65 |
**How much does it cost?**
|
66 |
ShortPixel comes with 100 free credits/month and additional credits can be bought for as little as $4.99 for 5,000 image credits.
|
67 |
Check out <a href="https://shortpixel.com/pricing" target="_blank">our prices</a>.
|
68 |
|
69 |
-
> **Testimonials:**
|
70 |
-
> ★★★★★ **A Super Plugin works very well 62% reduction overall.** [robertvarns](https://wordpress.org/support/topic/a-super-plugin-works-very-well-62-reduction-overall/)
|
71 |
-
> ★★★★★ **The secret sauce for a WordPress website.** [mark1mark](https://wordpress.org/support/topic/the-secret-sauce-for-a-wordpress-website/)
|
72 |
-
> ★★★★★ **A must have plugin, great support!** [ElColo13](https://wordpress.org/support/topic/a-must-have-plugin-great-support/)
|
73 |
-
> ★★★★★ **Excellent Plugin! Even Better Customer Service!** [scaliendo](https://wordpress.org/support/topic/great-plugin-great-support-508/)
|
74 |
-
> ★★★★★ **Great image compression, solid plugin, equally great support.** [matters1959](https://wordpress.org/support/topic/support-shortpixel-image-
|
75 |
> [more testimonials](https://wordpress.org/support/plugin/shortpixel-image-optimiser/reviews/?filter=5)
|
76 |
|
77 |
[youtube https://www.youtube.com/watch?v=5EbX0Hsy6j4]
|
@@ -104,21 +104,21 @@ Let's get ShortPixel plugin running on your WordPress website:
|
|
104 |
= How does ShortPixel compare to other image optimisation plugins (e.g Smush, Imagify, TinyPNG, Kraken, EWWW)? =
|
105 |
ShortPixel has better compression rates, more features, supports backups and has very affordable one-time plans.
|
106 |
If you are serious about making an informed decision please take 10 minutes and read this <a href="https://blog.shortpixel.com/wp-image-optimization-wordpress-plugins/">article</a>.
|
107 |
-
|
108 |
= Can I use the same API Key on multiple web sites? =
|
109 |
-
Yes, you can.
|
110 |
As long as you have available credits you can use a single API Key on as many websites as you wish!
|
111 |
|
112 |
= Can I test/use the plugin for free? =
|
113 |
-
Yes you can.
|
114 |
We offer 100 free image optimization credits each month. Exceeding the monthly free quota will pause the optimization process till the quota is reset or extended by buying one of our plans.
|
115 |
|
116 |
= Can I optimize images that aren't in Media Library? =
|
117 |
-
Absolutely.
|
118 |
You can actually optimize any image you have on your site regardless of its place. You just need to add - in the Advanced section of the ShortPixel Settings - the folders where the images you want to optimize are located and ShortPixel will work its magic and do the rest.
|
119 |
|
120 |
= Can I optimize both past and new images? =
|
121 |
-
Sure!
|
122 |
You can optimize all your past/current images using our "Bulk ShortPixel" page in your Media with a single click.
|
123 |
|
124 |
= A credit = an optimized image? =
|
@@ -166,7 +166,7 @@ Let's get ShortPixel plugin running on your WordPress website:
|
|
166 |
Please also note that usually images in your Media Library have 3-5 thumbs associated and a credit will be used for each featured image or associated thumbnail that is optimized.
|
167 |
|
168 |
= Why shall I use a wordpress plugin and not an offline tool? =
|
169 |
-
Because ShortPixel algorithms were perfected while optimizing over a hundred million real-life images.
|
170 |
ShortPixel not only offers the best compression for JPEG, PNG, GIF and PDF files but it also saves you a lot of time. You just install it on your site and then ShortPixel will take care that all the images on your site are immediately optimized after upload.
|
171 |
|
172 |
= Does optimizing images affect my ALT tags? =
|
@@ -177,18 +177,18 @@ Let's get ShortPixel plugin running on your WordPress website:
|
|
177 |
Once optimized the images will remain optimized unless you explicitly choose to restore them. But why would you do that? :-)
|
178 |
|
179 |
= Do I have to pay monthly or one time? =
|
180 |
-
We have both options available.
|
181 |
One-time credits never expire are a bit more expensive. Check out our prices <a href="https://shortpixel.com/pricing" >here</a>
|
182 |
|
183 |
= When can I cancel a monthly plan? =
|
184 |
-
Whenever you want.
|
185 |
The credits you still have available for the current billing period will still be available until the end of the billing period. At the end of it, you won't be billed again and the plan will be reset to the free plan.
|
186 |
|
187 |
= When credits expire? =
|
188 |
Monthly credits expire after 30 days while one-time credits never expire.
|
189 |
|
190 |
= Do you have an API? =
|
191 |
-
Yes, we have several APIs and tools.
|
192 |
You can learn more about it here:
|
193 |
<a href="https://shortpixel.com/api-tools">https://shortpixel.com/api-tools</a>
|
194 |
|
@@ -220,6 +220,9 @@ The ShortPixel Image Optimiser plugin calls the following actions and filters:
|
|
220 |
> apply_filters('shortpixel_image_exists', file_exists($path), $path, $post_id); //post ID is not always set, only if it's an image from Media Library
|
221 |
> apply_filters('shortpixel_image_urls', $URLs, $post_id) // filters the URLs that will be sent to optimization, $URLs is a plain array
|
222 |
|
|
|
|
|
|
|
223 |
|
224 |
== Screenshots ==
|
225 |
|
@@ -243,10 +246,23 @@ The ShortPixel Image Optimiser plugin calls the following actions and filters:
|
|
243 |
|
244 |
== Changelog ==
|
245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
== 4.14.2 ==
|
247 |
|
248 |
Release date: 1st July 2019
|
249 |
-
*
|
250 |
|
251 |
== 4.14.1 ==
|
252 |
|
1 |
=== ShortPixel Image Optimizer ===
|
2 |
+
Contributors: ShortPixel
|
3 |
Tags: compressor, image, compression, optimize, image optimizer, image optimiser, image compression, resize, compress pdf, compress jpg, compress png, image compression
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 5.2
|
6 |
Requires PHP: 5.3
|
7 |
+
Stable tag: 4.14.3
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
61 |
* 40 days optimization report with all image details and overall statistics
|
62 |
* We are GDPR compliant! <a href="https://shortpixel.com/privacy#gdpr" target="_blank">Read more.</a>
|
63 |
* **free optimization credits for non-profits**, <a href="https://shortpixel.com/contact" target="_blank">contact us</a> for details
|
64 |
+
|
65 |
**How much does it cost?**
|
66 |
ShortPixel comes with 100 free credits/month and additional credits can be bought for as little as $4.99 for 5,000 image credits.
|
67 |
Check out <a href="https://shortpixel.com/pricing" target="_blank">our prices</a>.
|
68 |
|
69 |
+
> **Testimonials:**
|
70 |
+
> ★★★★★ **A Super Plugin works very well 62% reduction overall.** [robertvarns](https://wordpress.org/support/topic/a-super-plugin-works-very-well-62-reduction-overall/)
|
71 |
+
> ★★★★★ **The secret sauce for a WordPress website.** [mark1mark](https://wordpress.org/support/topic/the-secret-sauce-for-a-wordpress-website/)
|
72 |
+
> ★★★★★ **A must have plugin, great support!** [ElColo13](https://wordpress.org/support/topic/a-must-have-plugin-great-support/)
|
73 |
+
> ★★★★★ **Excellent Plugin! Even Better Customer Service!** [scaliendo](https://wordpress.org/support/topic/great-plugin-great-support-508/)
|
74 |
+
> ★★★★★ **Great image compression, solid plugin, equally great support.** [matters1959](https://wordpress.org/support/topic/support-shortpixel-image-optimiser/)
|
75 |
> [more testimonials](https://wordpress.org/support/plugin/shortpixel-image-optimiser/reviews/?filter=5)
|
76 |
|
77 |
[youtube https://www.youtube.com/watch?v=5EbX0Hsy6j4]
|
104 |
= How does ShortPixel compare to other image optimisation plugins (e.g Smush, Imagify, TinyPNG, Kraken, EWWW)? =
|
105 |
ShortPixel has better compression rates, more features, supports backups and has very affordable one-time plans.
|
106 |
If you are serious about making an informed decision please take 10 minutes and read this <a href="https://blog.shortpixel.com/wp-image-optimization-wordpress-plugins/">article</a>.
|
107 |
+
|
108 |
= Can I use the same API Key on multiple web sites? =
|
109 |
+
Yes, you can.
|
110 |
As long as you have available credits you can use a single API Key on as many websites as you wish!
|
111 |
|
112 |
= Can I test/use the plugin for free? =
|
113 |
+
Yes you can.
|
114 |
We offer 100 free image optimization credits each month. Exceeding the monthly free quota will pause the optimization process till the quota is reset or extended by buying one of our plans.
|
115 |
|
116 |
= Can I optimize images that aren't in Media Library? =
|
117 |
+
Absolutely.
|
118 |
You can actually optimize any image you have on your site regardless of its place. You just need to add - in the Advanced section of the ShortPixel Settings - the folders where the images you want to optimize are located and ShortPixel will work its magic and do the rest.
|
119 |
|
120 |
= Can I optimize both past and new images? =
|
121 |
+
Sure!
|
122 |
You can optimize all your past/current images using our "Bulk ShortPixel" page in your Media with a single click.
|
123 |
|
124 |
= A credit = an optimized image? =
|
166 |
Please also note that usually images in your Media Library have 3-5 thumbs associated and a credit will be used for each featured image or associated thumbnail that is optimized.
|
167 |
|
168 |
= Why shall I use a wordpress plugin and not an offline tool? =
|
169 |
+
Because ShortPixel algorithms were perfected while optimizing over a hundred million real-life images.
|
170 |
ShortPixel not only offers the best compression for JPEG, PNG, GIF and PDF files but it also saves you a lot of time. You just install it on your site and then ShortPixel will take care that all the images on your site are immediately optimized after upload.
|
171 |
|
172 |
= Does optimizing images affect my ALT tags? =
|
177 |
Once optimized the images will remain optimized unless you explicitly choose to restore them. But why would you do that? :-)
|
178 |
|
179 |
= Do I have to pay monthly or one time? =
|
180 |
+
We have both options available.
|
181 |
One-time credits never expire are a bit more expensive. Check out our prices <a href="https://shortpixel.com/pricing" >here</a>
|
182 |
|
183 |
= When can I cancel a monthly plan? =
|
184 |
+
Whenever you want.
|
185 |
The credits you still have available for the current billing period will still be available until the end of the billing period. At the end of it, you won't be billed again and the plan will be reset to the free plan.
|
186 |
|
187 |
= When credits expire? =
|
188 |
Monthly credits expire after 30 days while one-time credits never expire.
|
189 |
|
190 |
= Do you have an API? =
|
191 |
+
Yes, we have several APIs and tools.
|
192 |
You can learn more about it here:
|
193 |
<a href="https://shortpixel.com/api-tools">https://shortpixel.com/api-tools</a>
|
194 |
|
220 |
> apply_filters('shortpixel_image_exists', file_exists($path), $path, $post_id); //post ID is not always set, only if it's an image from Media Library
|
221 |
> apply_filters('shortpixel_image_urls', $URLs, $post_id) // filters the URLs that will be sent to optimization, $URLs is a plain array
|
222 |
|
223 |
+
In order to define custom thumbnails to be picked up by the optimization you have two options, both comma separated defines:
|
224 |
+
define('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES', '_tl,_tr'); will handle custom thumbnails like image-100x100_tl.jpg
|
225 |
+
define('SHORTPIXEL_CUSTOM_THUMB_INFIXES', '-uae'); will handle custom thumbnails like image-uae-100x100.jpg
|
226 |
|
227 |
== Screenshots ==
|
228 |
|
246 |
|
247 |
== Changelog ==
|
248 |
|
249 |
+
== 4.14.3 ==
|
250 |
+
|
251 |
+
Release date: 22nd July 2019
|
252 |
+
* Compatibility with Flywheel hosting by not using flock if Flywheel detected
|
253 |
+
* When using the PICTURE tag to deliver WebP, keep the width and height at <IMG> level
|
254 |
+
* Refactoring of the API Key settings page, refactoring of Other media
|
255 |
+
* Performance improvements for selecting from large wp_posts and wp_postmeta tables when doing bulk optimization
|
256 |
+
* Display a message when bulk is skipping many processed images, if bulk processing is ran again.
|
257 |
+
* Fixed: Other media - Recompress adds "Preserve CMYK"
|
258 |
+
* Fixed: duplicate error message when validating wrong API key
|
259 |
+
* Conflict message: align the text vertically and provide space between text and button when displayed on any admin page
|
260 |
+
* Fixed: Other media Restore fails when original file is readable, not writable
|
261 |
+
|
262 |
== 4.14.2 ==
|
263 |
|
264 |
Release date: 1st July 2019
|
265 |
+
* add the possibility to define custom infixes for thumbnails (like image-uai-150x150.jpg for image.jpg) - comma separated define SHORTPIXEL_CUSTOM_THUMB_INFIXES
|
266 |
|
267 |
== 4.14.1 ==
|
268 |
|
@@ -45,3 +45,25 @@ li.shortpixel-toolbar-processing.shortpixel-alert > a.ab-item > div,
|
|
45 |
float:left;
|
46 |
margin: 10px 10px 10px 0;
|
47 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
float:left;
|
46 |
margin: 10px 10px 10px 0;
|
47 |
}
|
48 |
+
|
49 |
+
.sp-conflict-plugins {
|
50 |
+
display: table;
|
51 |
+
border-spacing: 10px;
|
52 |
+
border-collapse: separate;
|
53 |
+
}
|
54 |
+
.sp-conflict-plugins li {
|
55 |
+
display: table-row;
|
56 |
+
}
|
57 |
+
.sp-conflict-plugins li > * {
|
58 |
+
display: table-cell;
|
59 |
+
}
|
60 |
+
|
61 |
+
li.sp-conflict-plugins-list {
|
62 |
+
line-height: 28px;
|
63 |
+
list-style: disc;
|
64 |
+
margin-left: 80px;
|
65 |
+
}
|
66 |
+
li.sp-conflict-plugins-list a.button {
|
67 |
+
margin-left: 10px;
|
68 |
+
}
|
69 |
+
|
@@ -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}.short-pixel-notice-icon{float:left;margin:10px 10px 10px 0}
|
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}.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}
|
@@ -105,26 +105,6 @@ div.fb-like {
|
|
105 |
border-left-color: #f1e02a;
|
106 |
}
|
107 |
|
108 |
-
.sp-conflict-plugins {
|
109 |
-
display: table;
|
110 |
-
border-spacing: 10px;
|
111 |
-
border-collapse: separate;
|
112 |
-
}
|
113 |
-
.sp-conflict-plugins li {
|
114 |
-
display: table-row;
|
115 |
-
}
|
116 |
-
.sp-conflict-plugins li > * {
|
117 |
-
display: table-cell;
|
118 |
-
}
|
119 |
-
|
120 |
-
li.sp-conflict-plugins-list {
|
121 |
-
line-height: 28px;
|
122 |
-
list-style: disc;
|
123 |
-
margin-left: 80px;
|
124 |
-
}
|
125 |
-
li.sp-conflict-plugins-list a.button {
|
126 |
-
margin-left: 10px;
|
127 |
-
}
|
128 |
div.short-pixel-bulk-page input.dial {
|
129 |
font-size: 16px !important;
|
130 |
}
|
105 |
border-left-color: #f1e02a;
|
106 |
}
|
107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
div.short-pixel-bulk-page input.dial {
|
109 |
font-size: 16px !important;
|
110 |
}
|
@@ -1 +1 @@
|
|
1 |
-
.reset{font-weight:400;font-style:normal}.clearfix:after,.clearfix:before{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,.2);z-index:1}.sp-dropdown-content a{color:#000;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 #fff;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:700}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:focus,div.shortpixel-rate-us>a:hover{outline:0;border-style:none}.sp-loading-small{margin-top:2px;float:left;margin-right:5px}.twentytwenty-horizontal .twentytwenty-after-label:before,.twentytwenty-horizontal .twentytwenty-before-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:#fff;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:700;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:700;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:700}.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:700;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:700;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:400}.bulk-slider{display:table;margin:0 auto}.bulk-slider .bulk-slide{margin:0 auto;padding-left:120px;display:inline-block;font-weight:700}.bulk-slider .img-optimized,.bulk-slider .img-original{display:inline-block;margin-right:20px;text-align:center}.bulk-slider .img-optimized div,.bulk-slider .img-original div{max-height:450px;overflow:hidden}.bulk-slider .img-optimized img,.bulk-slider .img-original 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:700}.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:700;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,.1)}article.sp-tabs section .wp-shortpixel-tab-content{visibility:hidden}article.sp-tabs section.sel-tab .wp-shortpixel-tab-content{visibility:visible!important}article.sp-tabs section:first-child{z-index:1}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}.deliverWebpAlteringTypes,.deliverWebpSettings,.deliverWebpTypes{display:none}.deliverWebpTypes .sp-notice{color:red}.deliverWebpSettings{margin:16px 0}.deliverWebpSettings input:disabled+label{color:#818181}.deliverWebpAlteringTypes,.deliverWebpTypes{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-alert .cssload-container,#wpadminbar .shortpixel-toolbar-processing.shortpixel-quota-exceeded .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 2s infinite linear;-o-animation:cssload-spin 2s infinite linear;-ms-animation:cssload-spin 2s infinite linear;-webkit-animation:cssload-spin 2s infinite linear;-moz-animation:cssload-spin 2s 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}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 !important}article.sp-tabs section:first-child{z-index:1}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 +1 @@
|
|
1 |
-
.short-pixel-bulk-page.bulk-restore-all ol li{font-weight:700}.short-pixel-bulk-page.bulk-restore-all .random_answer{font-size:16px;font-weight:700;padding:8px;border:1px solid #ccc;display:inline-block}.short-pixel-bulk-page.bulk-restore-all .inputs{margin:15px 0}.short-pixel-bulk-page.bulk-restore-all .inputs span{margin-right:8px}.short-pixel-bulk-page.bulk-restore-all .button{margin:10px 0;margin-right:8px}
|
1 |
+
.shortpixel.notice{min-height:50px;padding:8px}.shortpixel.notice img{display:inline-block;margin:0 25px 0 0;max-height:50px}.shortpixel.notice .notice-dismiss{margin-top:10px}.view-notice{box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);border:4px solid #fff;padding:1px 12px}.view-notice p{margin:1em 0 !important}.view-notice.warning{border-left-color:#ffb900}.view-notice-row{display:none}.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}.short-pixel-bulk-page .sp-hidden{display:none}#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}.settings_page_wp-shortpixel-settings .top-menu{font-size:18px}.settings_page_wp-shortpixel-settings .top-menu a{font-size:18px}.settings_page_wp-shortpixel-settings .wp-shortpixel-tab-content{transition:all 1000ms linear}.settings_page_wp-shortpixel-settings article.sp-tabs section .wp-shortpixel-tab-content{opacity:0}.settings_page_wp-shortpixel-settings article.sp-tabs section.sel-tab .wp-shortpixel-tab-content{opacity:1}.settings_page_wp-shortpixel-settings 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}.settings_page_wp-shortpixel-settings 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}.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(2) h2{left:192px}.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(3) h2{left:374px}.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(4) h2{left:556px}.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(5) h2{left:738px}.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(6) h2{left:920px}.settings_page_wp-shortpixel-settings section#tab-debug .flex{display:flex}.settings_page_wp-shortpixel-settings section#tab-debug .env .flex{flex-wrap:wrap;max-width:450px}.settings_page_wp-shortpixel-settings section#tab-debug .env .flex span{width:45%;padding:4px}
|
@@ -1,7 +1,7 @@
|
|
1 |
(function($){
|
2 |
|
3 |
$.fn.spTooltip = function(instanceSettings){
|
4 |
-
|
5 |
$.fn.spTooltip.defaultsSettings = {
|
6 |
attributeName:'title',
|
7 |
borderColor:'#ccc',
|
@@ -27,12 +27,13 @@
|
|
27 |
tooltipSourceURL:'',
|
28 |
tooltipID:'tooltip'
|
29 |
};
|
30 |
-
|
31 |
//s = settings
|
32 |
var s = $.extend({}, $.fn.spTooltip.defaultsSettings , instanceSettings || {});
|
33 |
-
|
34 |
var positionTooltip = function(e){
|
35 |
-
|
|
|
36 |
var posx = 0;
|
37 |
var posy = 0;
|
38 |
if (!e) var e = window.event;
|
@@ -44,21 +45,21 @@
|
|
44 |
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
|
45 |
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
|
46 |
}
|
47 |
-
|
48 |
var p = {
|
49 |
-
x: posx + s.positionLeft,
|
50 |
y: posy + s.positionTop,
|
51 |
-
w: $('#'+s.tooltipID).width(),
|
52 |
h: $('#'+s.tooltipID).height()
|
53 |
}
|
54 |
-
|
55 |
var v = {
|
56 |
x: $(window).scrollLeft(),
|
57 |
y: $(window).scrollTop(),
|
58 |
w: $(window).width() - 20,
|
59 |
h: $(window).height() - 20
|
60 |
};
|
61 |
-
|
62 |
//don't go off screen
|
63 |
if(p.y + p.h > v.y + v.h && p.x + p.w > v.x + v.w){
|
64 |
p.x = (p.x - p.w) - 45;
|
@@ -68,26 +69,27 @@
|
|
68 |
}else if(p.y + p.h > v.y + v.h){
|
69 |
p.y = p.y - (((p.y+p.h)-(v.y+v.h)) + 20);
|
70 |
}
|
71 |
-
|
72 |
$('#'+s.tooltipID).css({'left':p.x + 'px','top':p.y + 'px'});
|
73 |
}
|
74 |
-
|
75 |
var showTooltip = function(){
|
76 |
$('#tooltipLoader').remove();
|
|
|
77 |
$('#'+s.tooltipID+' #tooltipContent').show();
|
78 |
-
|
79 |
if($.browser.version == '6.0'){//IE6 only
|
80 |
$('#'+s.tooltipID).append('<iframe id="tooltipIE6FixIframe" style="width:'+($('#'+s.tooltipID).width()+parseFloat(s.borderSize)+parseFloat(s.borderSize)+20)+'px;height:'+($('#'+s.tooltipID).height()+parseFloat(s.borderSize)+parseFloat(s.borderSize)+20)+'px;position:absolute;top:-'+s.borderSize+'px;left:-'+s.borderSize+'px;filter:alpha(opacity=0);"src="blank.html"></iframe>');
|
81 |
};
|
82 |
}
|
83 |
-
|
84 |
var hideTooltip = function(valueOfThis){
|
85 |
$('#'+s.tooltipID).fadeOut('fast').trigger("unload").remove();
|
86 |
if($(valueOfThis).filter('[title]')){
|
87 |
$(valueOfThis).attr('title',s.titleAttributeContent);
|
88 |
}
|
89 |
}
|
90 |
-
|
91 |
var urlQueryToObject = function(s){
|
92 |
var query = {};
|
93 |
s.replace(/b([^&=]*)=([^&=]*)b/g, function (m, a, d) {
|
@@ -99,13 +101,13 @@
|
|
99 |
});
|
100 |
return query;
|
101 |
};
|
102 |
-
|
103 |
return this.each(function(index){
|
104 |
-
|
105 |
if(s.cancelClick){
|
106 |
$(this).bind("click", function(){return false});
|
107 |
}
|
108 |
-
|
109 |
if($.fn.hoverIntent){
|
110 |
$(this).hoverIntent({
|
111 |
sensitivity:s.hoverIntent.sensitivity,
|
@@ -117,36 +119,38 @@
|
|
117 |
}else{
|
118 |
$(this).hover(on,off);
|
119 |
}
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
$('body').append('<div id="'+s.tooltipID+'" style="background-repeat:no-repeat;background-image:url('+s.tooltipBGImage+');padding:'+s.tooltipPadding+'px;display:none;height:'+s.height+';width:'+s.width+';background-color:'+s.tooltipBGColor+';border:'+s.borderSize+'px solid '+s.borderColor+'; position:absolute;z-index:100000000000;"><div id="tooltipContent" style="display:none;"></div></div>');
|
124 |
-
|
125 |
var $tt = $('#'+s.tooltipID);
|
126 |
var $ttContent = $('#'+s.tooltipID+' #tooltipContent');
|
127 |
-
|
128 |
if(s.loader && s.loaderImagePath != ''){
|
129 |
-
$tt.append('<div id="tooltipLoader" style="width:'+s.loaderWidth+'px;height:'+s.loaderHeight+'px;"><img src="'+s.loaderImagePath+'" /></div>');
|
130 |
}
|
131 |
-
|
132 |
if($(this).attr('title')){
|
133 |
s.titleAttributeContent = $(this).attr('title');
|
134 |
$(this).attr('title','');
|
135 |
}
|
136 |
-
|
137 |
if($(this).is('input')){
|
138 |
$(this).focus(function(){ hideTooltip(this); });
|
139 |
}
|
140 |
-
|
141 |
e.preventDefault();//stop
|
142 |
positionTooltip(e);
|
143 |
-
|
144 |
$tt.show();
|
145 |
-
|
146 |
//get values from element clicked, or assume its passed as an option
|
147 |
s.tooltipSourceID = $(this).attr('href') || s.tooltipSourceID;
|
148 |
s.tooltipSourceURL = $(this).attr('href') || s.tooltipSourceURL;
|
149 |
-
|
|
|
|
|
|
|
150 |
switch(s.tooltipSource){
|
151 |
case 'attribute':/*/////////////////////////////// attribute //////////////////////////////////////////*/
|
152 |
$ttContent.text(s.titleAttributeContent);
|
@@ -155,11 +159,12 @@
|
|
155 |
case 'inline':/*/////////////////////////////// inline //////////////////////////////////////////*/
|
156 |
$ttContent.html($(s.tooltipSourceID).children());
|
157 |
$tt.unload(function(){// move elements back when you're finished
|
158 |
-
$(s.tooltipSourceID).html($ttContent.children());
|
159 |
});
|
160 |
showTooltip();
|
161 |
break;
|
162 |
-
case 'ajax':/*/////////////////////////////// ajax //////////////////////////////////////////*/
|
|
|
163 |
if(s.tooltipHTTPType == 'post'){
|
164 |
var urlOnly, urlQueryObject;
|
165 |
if(s.tooltipSourceURL.indexOf("?") !== -1){//has a query string
|
@@ -183,25 +188,25 @@
|
|
183 |
}
|
184 |
break;
|
185 |
};
|
186 |
-
|
187 |
return false;
|
188 |
-
|
189 |
};
|
190 |
-
|
191 |
-
|
192 |
function off(e){
|
193 |
hideTooltip(this);
|
194 |
return false;
|
195 |
};
|
196 |
-
|
197 |
if(s.followMouse){
|
198 |
$(this).bind("mousemove", function(e){
|
199 |
positionTooltip(e);
|
200 |
return false;
|
201 |
});
|
202 |
}
|
203 |
-
|
204 |
});
|
205 |
};
|
206 |
-
|
207 |
})(jQuery);
|
1 |
(function($){
|
2 |
|
3 |
$.fn.spTooltip = function(instanceSettings){
|
4 |
+
|
5 |
$.fn.spTooltip.defaultsSettings = {
|
6 |
attributeName:'title',
|
7 |
borderColor:'#ccc',
|
27 |
tooltipSourceURL:'',
|
28 |
tooltipID:'tooltip'
|
29 |
};
|
30 |
+
|
31 |
//s = settings
|
32 |
var s = $.extend({}, $.fn.spTooltip.defaultsSettings , instanceSettings || {});
|
33 |
+
|
34 |
var positionTooltip = function(e){
|
35 |
+
e.preventDefault();
|
36 |
+
|
37 |
var posx = 0;
|
38 |
var posy = 0;
|
39 |
if (!e) var e = window.event;
|
45 |
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
|
46 |
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
|
47 |
}
|
48 |
+
|
49 |
var p = {
|
50 |
+
x: posx + s.positionLeft,
|
51 |
y: posy + s.positionTop,
|
52 |
+
w: $('#'+s.tooltipID).width(),
|
53 |
h: $('#'+s.tooltipID).height()
|
54 |
}
|
55 |
+
|
56 |
var v = {
|
57 |
x: $(window).scrollLeft(),
|
58 |
y: $(window).scrollTop(),
|
59 |
w: $(window).width() - 20,
|
60 |
h: $(window).height() - 20
|
61 |
};
|
62 |
+
|
63 |
//don't go off screen
|
64 |
if(p.y + p.h > v.y + v.h && p.x + p.w > v.x + v.w){
|
65 |
p.x = (p.x - p.w) - 45;
|
69 |
}else if(p.y + p.h > v.y + v.h){
|
70 |
p.y = p.y - (((p.y+p.h)-(v.y+v.h)) + 20);
|
71 |
}
|
72 |
+
|
73 |
$('#'+s.tooltipID).css({'left':p.x + 'px','top':p.y + 'px'});
|
74 |
}
|
75 |
+
|
76 |
var showTooltip = function(){
|
77 |
$('#tooltipLoader').remove();
|
78 |
+
|
79 |
$('#'+s.tooltipID+' #tooltipContent').show();
|
80 |
+
|
81 |
if($.browser.version == '6.0'){//IE6 only
|
82 |
$('#'+s.tooltipID).append('<iframe id="tooltipIE6FixIframe" style="width:'+($('#'+s.tooltipID).width()+parseFloat(s.borderSize)+parseFloat(s.borderSize)+20)+'px;height:'+($('#'+s.tooltipID).height()+parseFloat(s.borderSize)+parseFloat(s.borderSize)+20)+'px;position:absolute;top:-'+s.borderSize+'px;left:-'+s.borderSize+'px;filter:alpha(opacity=0);"src="blank.html"></iframe>');
|
83 |
};
|
84 |
}
|
85 |
+
|
86 |
var hideTooltip = function(valueOfThis){
|
87 |
$('#'+s.tooltipID).fadeOut('fast').trigger("unload").remove();
|
88 |
if($(valueOfThis).filter('[title]')){
|
89 |
$(valueOfThis).attr('title',s.titleAttributeContent);
|
90 |
}
|
91 |
}
|
92 |
+
|
93 |
var urlQueryToObject = function(s){
|
94 |
var query = {};
|
95 |
s.replace(/b([^&=]*)=([^&=]*)b/g, function (m, a, d) {
|
101 |
});
|
102 |
return query;
|
103 |
};
|
104 |
+
|
105 |
return this.each(function(index){
|
106 |
+
|
107 |
if(s.cancelClick){
|
108 |
$(this).bind("click", function(){return false});
|
109 |
}
|
110 |
+
|
111 |
if($.fn.hoverIntent){
|
112 |
$(this).hoverIntent({
|
113 |
sensitivity:s.hoverIntent.sensitivity,
|
119 |
}else{
|
120 |
$(this).hover(on,off);
|
121 |
}
|
122 |
+
function on(e){
|
123 |
+
|
|
|
124 |
$('body').append('<div id="'+s.tooltipID+'" style="background-repeat:no-repeat;background-image:url('+s.tooltipBGImage+');padding:'+s.tooltipPadding+'px;display:none;height:'+s.height+';width:'+s.width+';background-color:'+s.tooltipBGColor+';border:'+s.borderSize+'px solid '+s.borderColor+'; position:absolute;z-index:100000000000;"><div id="tooltipContent" style="display:none;"></div></div>');
|
125 |
+
|
126 |
var $tt = $('#'+s.tooltipID);
|
127 |
var $ttContent = $('#'+s.tooltipID+' #tooltipContent');
|
128 |
+
|
129 |
if(s.loader && s.loaderImagePath != ''){
|
130 |
+
$tt.append('<div id="tooltipLoader" style="width:'+s.loaderWidth+'px;height:'+s.loaderHeight+'px;"><img src="'+s.loaderImagePath+'" /></div>');
|
131 |
}
|
132 |
+
|
133 |
if($(this).attr('title')){
|
134 |
s.titleAttributeContent = $(this).attr('title');
|
135 |
$(this).attr('title','');
|
136 |
}
|
137 |
+
|
138 |
if($(this).is('input')){
|
139 |
$(this).focus(function(){ hideTooltip(this); });
|
140 |
}
|
141 |
+
|
142 |
e.preventDefault();//stop
|
143 |
positionTooltip(e);
|
144 |
+
|
145 |
$tt.show();
|
146 |
+
|
147 |
//get values from element clicked, or assume its passed as an option
|
148 |
s.tooltipSourceID = $(this).attr('href') || s.tooltipSourceID;
|
149 |
s.tooltipSourceURL = $(this).attr('href') || s.tooltipSourceURL;
|
150 |
+
|
151 |
+
console.log(s.tooltipSourceID);
|
152 |
+
console.log(s.tooltipSourceURL);
|
153 |
+
|
154 |
switch(s.tooltipSource){
|
155 |
case 'attribute':/*/////////////////////////////// attribute //////////////////////////////////////////*/
|
156 |
$ttContent.text(s.titleAttributeContent);
|
159 |
case 'inline':/*/////////////////////////////// inline //////////////////////////////////////////*/
|
160 |
$ttContent.html($(s.tooltipSourceID).children());
|
161 |
$tt.unload(function(){// move elements back when you're finished
|
162 |
+
$(s.tooltipSourceID).html($ttContent.children());
|
163 |
});
|
164 |
showTooltip();
|
165 |
break;
|
166 |
+
case 'ajax':/*/////////////////////////////// ajax //////////////////////////////////////////*/
|
167 |
+
|
168 |
if(s.tooltipHTTPType == 'post'){
|
169 |
var urlOnly, urlQueryObject;
|
170 |
if(s.tooltipSourceURL.indexOf("?") !== -1){//has a query string
|
188 |
}
|
189 |
break;
|
190 |
};
|
191 |
+
|
192 |
return false;
|
193 |
+
|
194 |
};
|
195 |
+
|
196 |
+
|
197 |
function off(e){
|
198 |
hideTooltip(this);
|
199 |
return false;
|
200 |
};
|
201 |
+
|
202 |
if(s.followMouse){
|
203 |
$(this).bind("mousemove", function(e){
|
204 |
positionTooltip(e);
|
205 |
return false;
|
206 |
});
|
207 |
}
|
208 |
+
|
209 |
});
|
210 |
};
|
211 |
+
|
212 |
})(jQuery);
|
@@ -1 +1 @@
|
|
1 |
-
(function(a){a.fn.spTooltip=function(d){a.fn.spTooltip.defaultsSettings={attributeName:"title",borderColor:"#ccc",borderSize:"1",cancelClick:0,followMouse:1,height:"auto",hoverIntent:{sensitivity:7,interval:100,timeout:0},loader:0,loaderHeight:0,loaderImagePath:"",loaderWidth:0,positionTop:12,positionLeft:12,width:"auto",titleAttributeContent:"",tooltipBGColor:"#fff",tooltipBGImage:"none",tooltipHTTPType:"get",tooltipPadding:10,tooltipSource:"attribute",tooltipSourceID:"",tooltipSourceURL:"",tooltipID:"tooltip"};var e=a.extend({},a.fn.spTooltip.defaultsSettings,d||{});var g=function(k){var h=0;var l=0;if(!k){var k=window.event}if(k.pageX||k.pageY){h=k.pageX;l=k.pageY}else{if(k.clientX||k.clientY){h=k.clientX+document.body.scrollLeft+document.documentElement.scrollLeft;l=k.clientY+document.body.scrollTop+document.documentElement.scrollTop}}var j={x:h+e.positionLeft,y:l+e.positionTop,w:a("#"+e.tooltipID).width(),h:a("#"+e.tooltipID).height()};var i={x:a(window).scrollLeft(),y:a(window).scrollTop(),w:a(window).width()-20,h:a(window).height()-20};if(j.y+j.h>i.y+i.h&&j.x+j.w>i.x+i.w){j.x=(j.x-j.w)-45;j.y=(j.y-j.h)-45}else{if(j.x+j.w>i.x+i.w){j.x=j.x-(((j.x+j.w)-(i.x+i.w))+20)}else{if(j.y+j.h>i.y+i.h){j.y=j.y-(((j.y+j.h)-(i.y+i.h))+20)}}}a("#"+e.tooltipID).css({left:j.x+"px",top:j.y+"px"})};var f=function(){a("#tooltipLoader").remove();a("#"+e.tooltipID+" #tooltipContent").show();if(a.browser.version=="6.0"){a("#"+e.tooltipID).append('<iframe id="tooltipIE6FixIframe" style="width:'+(a("#"+e.tooltipID).width()+parseFloat(e.borderSize)+parseFloat(e.borderSize)+20)+"px;height:"+(a("#"+e.tooltipID).height()+parseFloat(e.borderSize)+parseFloat(e.borderSize)+20)+"px;position:absolute;top:-"+e.borderSize+"px;left:-"+e.borderSize+'px;filter:alpha(opacity=0);"src="blank.html"></iframe>')}};var b=function(h){a("#"+e.tooltipID).fadeOut("fast").trigger("unload").remove();if(a(h).filter("[title]")){a(h).attr("title",e.titleAttributeContent)}};var c=function(h){var i={};h.replace(/b([^&=]*)=([^&=]*)b/g,function(j,k,l){if(typeof i[k]!="undefined"){i[k]+=","+l}else{i[k]=l}});return i};return this.each(function(i){if(e.cancelClick){a(this).bind("click",function(){return false})}if(a.fn.hoverIntent){a(this).hoverIntent({sensitivity:e.hoverIntent.sensitivity,interval:e.hoverIntent.interval,over:h,timeout:e.hoverIntent.timeout,out:j})}else{a(this).hover(h,j)}function h(n){a("body").append('<div id="'+e.tooltipID+'" style="background-repeat:no-repeat;background-image:url('+e.tooltipBGImage+");padding:"+e.tooltipPadding+"px;display:none;height:"+e.height+";width:"+e.width+";background-color:"+e.tooltipBGColor+";border:"+e.borderSize+"px solid "+e.borderColor+'; position:absolute;z-index:100000000000;"><div id="tooltipContent" style="display:none;"></div></div>');var l=a("#"+e.tooltipID);var o=a("#"+e.tooltipID+" #tooltipContent");if(e.loader&&e.loaderImagePath!=""){l.append('<div id="tooltipLoader" style="width:'+e.loaderWidth+"px;height:"+e.loaderHeight+'px;"><img src="'+e.loaderImagePath+'" /></div>')}if(a(this).attr("title")){e.titleAttributeContent=a(this).attr("title");a(this).attr("title","")}if(a(this).is("input")){a(this).focus(function(){b(this)})}n.preventDefault();g(n);l.show();e.tooltipSourceID=a(this).attr("href")||e.tooltipSourceID;e.tooltipSourceURL=a(this).attr("href")||e.tooltipSourceURL;switch(e.tooltipSource){case"attribute":o.text(e.titleAttributeContent);f();break;case"inline":o.html(a(e.tooltipSourceID).children());l.unload(function(){a(e.tooltipSourceID).html(o.children())});f();break;case"ajax":if(e.tooltipHTTPType=="post"){var m,k;if(e.tooltipSourceURL.indexOf("?")!==-1){m=e.windowSourceURL.substr(0,e.windowSourceURL.indexOf("?"));k=c(e.tooltipSourceURL)}else{m=e.tooltipSourceURL;k={}}o.load(m,k,function(){f()})}else{if(e.tooltipSourceURL.indexOf("?")==-1){e.tooltipSourceURL+="?"}o.load(e.tooltipSourceURL+"&random="+(new Date().getTime()),function(){f()})}break}return false}function j(k){b(this);return false}if(e.followMouse){a(this).bind("mousemove",function(k){g(k);return false})}})}})(jQuery);
|
1 |
+
(function(a){a.fn.spTooltip=function(d){a.fn.spTooltip.defaultsSettings={attributeName:"title",borderColor:"#ccc",borderSize:"1",cancelClick:0,followMouse:1,height:"auto",hoverIntent:{sensitivity:7,interval:100,timeout:0},loader:0,loaderHeight:0,loaderImagePath:"",loaderWidth:0,positionTop:12,positionLeft:12,width:"auto",titleAttributeContent:"",tooltipBGColor:"#fff",tooltipBGImage:"none",tooltipHTTPType:"get",tooltipPadding:10,tooltipSource:"attribute",tooltipSourceID:"",tooltipSourceURL:"",tooltipID:"tooltip"};var e=a.extend({},a.fn.spTooltip.defaultsSettings,d||{});var g=function(k){k.preventDefault();var h=0;var l=0;if(!k){var k=window.event}if(k.pageX||k.pageY){h=k.pageX;l=k.pageY}else{if(k.clientX||k.clientY){h=k.clientX+document.body.scrollLeft+document.documentElement.scrollLeft;l=k.clientY+document.body.scrollTop+document.documentElement.scrollTop}}var j={x:h+e.positionLeft,y:l+e.positionTop,w:a("#"+e.tooltipID).width(),h:a("#"+e.tooltipID).height()};var i={x:a(window).scrollLeft(),y:a(window).scrollTop(),w:a(window).width()-20,h:a(window).height()-20};if(j.y+j.h>i.y+i.h&&j.x+j.w>i.x+i.w){j.x=(j.x-j.w)-45;j.y=(j.y-j.h)-45}else{if(j.x+j.w>i.x+i.w){j.x=j.x-(((j.x+j.w)-(i.x+i.w))+20)}else{if(j.y+j.h>i.y+i.h){j.y=j.y-(((j.y+j.h)-(i.y+i.h))+20)}}}a("#"+e.tooltipID).css({left:j.x+"px",top:j.y+"px"})};var f=function(){a("#tooltipLoader").remove();a("#"+e.tooltipID+" #tooltipContent").show();if(a.browser.version=="6.0"){a("#"+e.tooltipID).append('<iframe id="tooltipIE6FixIframe" style="width:'+(a("#"+e.tooltipID).width()+parseFloat(e.borderSize)+parseFloat(e.borderSize)+20)+"px;height:"+(a("#"+e.tooltipID).height()+parseFloat(e.borderSize)+parseFloat(e.borderSize)+20)+"px;position:absolute;top:-"+e.borderSize+"px;left:-"+e.borderSize+'px;filter:alpha(opacity=0);"src="blank.html"></iframe>')}};var b=function(h){a("#"+e.tooltipID).fadeOut("fast").trigger("unload").remove();if(a(h).filter("[title]")){a(h).attr("title",e.titleAttributeContent)}};var c=function(h){var i={};h.replace(/b([^&=]*)=([^&=]*)b/g,function(j,k,l){if(typeof i[k]!="undefined"){i[k]+=","+l}else{i[k]=l}});return i};return this.each(function(i){if(e.cancelClick){a(this).bind("click",function(){return false})}if(a.fn.hoverIntent){a(this).hoverIntent({sensitivity:e.hoverIntent.sensitivity,interval:e.hoverIntent.interval,over:h,timeout:e.hoverIntent.timeout,out:j})}else{a(this).hover(h,j)}function h(n){a("body").append('<div id="'+e.tooltipID+'" style="background-repeat:no-repeat;background-image:url('+e.tooltipBGImage+");padding:"+e.tooltipPadding+"px;display:none;height:"+e.height+";width:"+e.width+";background-color:"+e.tooltipBGColor+";border:"+e.borderSize+"px solid "+e.borderColor+'; position:absolute;z-index:100000000000;"><div id="tooltipContent" style="display:none;"></div></div>');var l=a("#"+e.tooltipID);var o=a("#"+e.tooltipID+" #tooltipContent");if(e.loader&&e.loaderImagePath!=""){l.append('<div id="tooltipLoader" style="width:'+e.loaderWidth+"px;height:"+e.loaderHeight+'px;"><img src="'+e.loaderImagePath+'" /></div>')}if(a(this).attr("title")){e.titleAttributeContent=a(this).attr("title");a(this).attr("title","")}if(a(this).is("input")){a(this).focus(function(){b(this)})}n.preventDefault();g(n);l.show();e.tooltipSourceID=a(this).attr("href")||e.tooltipSourceID;e.tooltipSourceURL=a(this).attr("href")||e.tooltipSourceURL;console.log(e.tooltipSourceID);console.log(e.tooltipSourceURL);switch(e.tooltipSource){case"attribute":o.text(e.titleAttributeContent);f();break;case"inline":o.html(a(e.tooltipSourceID).children());l.unload(function(){a(e.tooltipSourceID).html(o.children())});f();break;case"ajax":if(e.tooltipHTTPType=="post"){var m,k;if(e.tooltipSourceURL.indexOf("?")!==-1){m=e.windowSourceURL.substr(0,e.windowSourceURL.indexOf("?"));k=c(e.tooltipSourceURL)}else{m=e.tooltipSourceURL;k={}}o.load(m,k,function(){f()})}else{if(e.tooltipSourceURL.indexOf("?")==-1){e.tooltipSourceURL+="?"}o.load(e.tooltipSourceURL+"&random="+(new Date().getTime()),function(){f()})}break}return false}function j(k){b(this);return false}if(e.followMouse){a(this).bind("mousemove",function(k){g(k);return false})}})}})(jQuery);
|
@@ -63,12 +63,13 @@ var ShortPixel = function() {
|
|
63 |
jQuery('#request_key').attr('href', jQuery('#request_key').attr('href').split('?')[0] + '?pluginemail=' + email);
|
64 |
}
|
65 |
|
|
|
66 |
function validateKey(button){
|
67 |
console.log('validate');
|
68 |
jQuery('#valid').val('validate');
|
69 |
|
70 |
jQuery(button).parents('form').submit();
|
71 |
-
}
|
72 |
|
73 |
jQuery("#key").keypress(function(e) {
|
74 |
if(e.which == 13) {
|
@@ -294,6 +295,19 @@ var ShortPixel = function() {
|
|
294 |
});
|
295 |
}
|
296 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
function checkQuota() {
|
298 |
var data = { action : 'shortpixel_check_quota'};
|
299 |
jQuery.get(ShortPixel.AJAX_URL, data, function() {
|
@@ -780,7 +794,7 @@ var ShortPixel = function() {
|
|
780 |
setOptions : setOptions,
|
781 |
isEmailValid : isEmailValid,
|
782 |
updateSignupEmail : updateSignupEmail,
|
783 |
-
validateKey : validateKey,
|
784 |
enableResize : enableResize,
|
785 |
setupGeneralTab : setupGeneralTab,
|
786 |
apiKeyChanged : apiKeyChanged,
|
@@ -791,6 +805,8 @@ var ShortPixel = function() {
|
|
791 |
adjustSettingsTabs : adjustSettingsTabsHeight,
|
792 |
onBulkThumbsCheck : onBulkThumbsCheck,
|
793 |
dismissMediaAlert : dismissMediaAlert,
|
|
|
|
|
794 |
checkQuota : checkQuota,
|
795 |
percentDial : percentDial,
|
796 |
successMsg : successMsg,
|
@@ -830,7 +846,8 @@ var ShortPixel = function() {
|
|
830 |
height : 0
|
831 |
},
|
832 |
toRefresh : false,
|
833 |
-
resizeSizesAlert: false
|
|
|
834 |
}
|
835 |
}();
|
836 |
|
@@ -977,6 +994,15 @@ function checkBulkProcessingCallApi(){
|
|
977 |
|
978 |
var isBulkPage = (jQuery("div.short-pixel-bulk-page").length > 0);
|
979 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
980 |
switch (data["Status"]) {
|
981 |
case ShortPixel.STATUS_NO_KEY:
|
982 |
setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey"
|
@@ -1101,6 +1127,15 @@ function checkBulkProcessingCallApi(){
|
|
1101 |
}
|
1102 |
setTimeout(checkBulkProgress, 5000);
|
1103 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1104 |
case ShortPixel.STATUS_MAINTENANCE:
|
1105 |
ShortPixel.bulkShowMaintenanceMsg('maintenance');
|
1106 |
setTimeout(checkBulkProgress, 60000);
|
63 |
jQuery('#request_key').attr('href', jQuery('#request_key').attr('href').split('?')[0] + '?pluginemail=' + email);
|
64 |
}
|
65 |
|
66 |
+
/* Can be removed.
|
67 |
function validateKey(button){
|
68 |
console.log('validate');
|
69 |
jQuery('#valid').val('validate');
|
70 |
|
71 |
jQuery(button).parents('form').submit();
|
72 |
+
} */
|
73 |
|
74 |
jQuery("#key").keypress(function(e) {
|
75 |
if(e.which == 13) {
|
295 |
});
|
296 |
}
|
297 |
|
298 |
+
function closeHelpPane() {
|
299 |
+
jQuery('#shortpixel-hs-button-blind').remove();
|
300 |
+
jQuery('#shortpixel-hs-tools').remove();
|
301 |
+
jQuery('#hs-beacon').remove();
|
302 |
+
jQuery('#botbutton').remove();
|
303 |
+
jQuery('#shortpixel-hs-blind').remove();
|
304 |
+
}
|
305 |
+
|
306 |
+
function dismissHelpPane() {
|
307 |
+
closeHelpPane();
|
308 |
+
dismissShortPixelNotice('help');
|
309 |
+
}
|
310 |
+
|
311 |
function checkQuota() {
|
312 |
var data = { action : 'shortpixel_check_quota'};
|
313 |
jQuery.get(ShortPixel.AJAX_URL, data, function() {
|
794 |
setOptions : setOptions,
|
795 |
isEmailValid : isEmailValid,
|
796 |
updateSignupEmail : updateSignupEmail,
|
797 |
+
//validateKey : validateKey,
|
798 |
enableResize : enableResize,
|
799 |
setupGeneralTab : setupGeneralTab,
|
800 |
apiKeyChanged : apiKeyChanged,
|
805 |
adjustSettingsTabs : adjustSettingsTabsHeight,
|
806 |
onBulkThumbsCheck : onBulkThumbsCheck,
|
807 |
dismissMediaAlert : dismissMediaAlert,
|
808 |
+
closeHelpPane : closeHelpPane,
|
809 |
+
dismissHelpPane : dismissHelpPane,
|
810 |
checkQuota : checkQuota,
|
811 |
percentDial : percentDial,
|
812 |
successMsg : successMsg,
|
846 |
height : 0
|
847 |
},
|
848 |
toRefresh : false,
|
849 |
+
resizeSizesAlert: false,
|
850 |
+
returnedStatusSearching: 0, // How often this status has come back in a row from server.
|
851 |
}
|
852 |
}();
|
853 |
|
994 |
|
995 |
var isBulkPage = (jQuery("div.short-pixel-bulk-page").length > 0);
|
996 |
|
997 |
+
if (data["Status"] && data["Status"] != ShortPixel.STATUS_SEARCHING)
|
998 |
+
{
|
999 |
+
if (ShortPixel.returnedStatusSearching >= 2)
|
1000 |
+
jQuery('.bulk-notice-msg.bulk-searching').hide();
|
1001 |
+
|
1002 |
+
ShortPixel.returnedStatusSearching = 0;
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
|
1006 |
switch (data["Status"]) {
|
1007 |
case ShortPixel.STATUS_NO_KEY:
|
1008 |
setCellMessage(id, data["Message"], "<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey"
|
1127 |
}
|
1128 |
setTimeout(checkBulkProgress, 5000);
|
1129 |
break;
|
1130 |
+
case ShortPixel.STATUS_SEARCHING:
|
1131 |
+
console.log('Server response: ' + response);
|
1132 |
+
ShortPixel.returnedStatusSearching++;
|
1133 |
+
if (ShortPixel.returnedStatusSearching >= 2)
|
1134 |
+
{
|
1135 |
+
jQuery('.bulk-notice-msg.bulk-searching').show();
|
1136 |
+
}
|
1137 |
+
setTimeout(checkBulkProgress, 2500);
|
1138 |
+
break;
|
1139 |
case ShortPixel.STATUS_MAINTENANCE:
|
1140 |
ShortPixel.bulkShowMaintenanceMsg('maintenance');
|
1141 |
setTimeout(checkBulkProgress, 60000);
|
@@ -1 +1 @@
|
|
1 |
-
function showToolBarAlert(e,r,t){var o=jQuery("li.shortpixel-toolbar-processing");switch(e){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&0==jQuery(".sp-quota-exceeded-alert").length)return void location.reload();o.addClass("shortpixel-alert"),o.addClass("shortpixel-quota-exceeded"),jQuery("a",o).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",o).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:o.addClass("shortpixel-alert shortpixel-processing"),jQuery("a div",o).attr("title",r),void 0!==t&&jQuery("a",o).attr("href","post.php?post="+t+"&action=edit");break;case ShortPixel.STATUS_NO_KEY:o.addClass("shortpixel-alert"),o.addClass("shortpixel-quota-exceeded"),jQuery("a",o).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",o).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:o.addClass("shortpixel-processing"),o.removeClass("shortpixel-alert"),jQuery("a",o).removeAttr("target"),jQuery("a",o).attr("href",jQuery("a img",o).attr("success-url"))}o.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(){"undefined"!=typeof shortPixelQuotaExceeded&&(1==shortPixelQuotaExceeded?showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED):hideQuotaExceededToolBarAlert())}function checkBulkProgress(){var e=function(e){return r?"/":(r=!0,e)},r=!1,t=window.location.href.toLowerCase().replace(/\/\//g,e);r=!1;var o=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,e);t.search(o)<0&&(t=ShortPixel.convertPunycode(t),o=ShortPixel.convertPunycode(o)),t.search(o+"upload.php")<0&&t.search(o+"edit.php")<0&&t.search(o+"edit-tags.php")<0&&t.search(o+"post-new.php")<0&&t.search(o+"post.php")<0&&t.search("page=nggallery-manage-gallery")<0&&(0==ShortPixel.FRONT_BOOTSTRAP||0==t.search(o))?hideToolBarAlert():(1==ShortPixel.bulkProcessor&&window.location.href.search("wp-short-pixel-bulk")<0&&void 0!==localStorage.bulkPage&&localStorage.bulkPage>0&&(ShortPixel.bulkProcessor=!1),window.location.href.search("wp-short-pixel-bulk")>=0&&(ShortPixel.bulkProcessor=!0,localStorage.bulkTime=Math.floor(Date.now()/1e3),localStorage.bulkPage=1),1==ShortPixel.bulkProcessor||void 0===localStorage.bulkTime||Math.floor(Date.now()/1e3)-localStorage.bulkTime>90?(ShortPixel.bulkProcessor=!0,localStorage.bulkPage=window.location.href.search("wp-short-pixel-bulk")>=0?1:0,localStorage.bulkTime=Math.floor(Date.now()/1e3),console.log(localStorage.bulkTime),checkBulkProcessingCallApi()):setTimeout(checkBulkProgress,5e3))}function checkBulkProcessingCallApi(){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_image_processing"},success:function(e){if(e.length>0){r=null;try{var r=JSON.parse(e)}catch(e){return void ShortPixel.retry(e.message)}ShortPixel.retries=0;var t=r.ImageID,o=jQuery("div.short-pixel-bulk-page").length>0;switch(r.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(t,r.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(t,r.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),0==r.Stop&&setTimeout(checkBulkProgress,5e3),ShortPixel.otherMediaUpdateActions(t,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(t,r.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+t+"', false)\">"+_spTr.retry+"</a>"),showToolBarAlert(ShortPixel.STATUS_FAIL,r.Message,t),o&&(ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink),r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),ShortPixel.otherMediaUpdateActions(t,["retry","view"])),console.log(r.Message),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(r.Message),clearBulkProcessor(),hideToolBarAlert();var s=jQuery("#bulk-progress");o&&s.length&&"2"!=r.BulkStatus&&(progressUpdate(100,"Bulk finished!"),jQuery("a.bulk-cancel").attr("disabled","disabled"),hideSlider(),setTimeout(function(){window.location.reload()},3e3));break;case ShortPixel.STATUS_SUCCESS:o&&(ShortPixel.bulkHideLengthyMsg(),ShortPixel.bulkHideMaintenanceMsg());var i=r.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var a=ShortPixel.isCustomImageId(t)?"":ShortPixel.successActions(t,r.Type,r.ThumbsCount,r.ThumbsTotal,r.BackupEnabled,r.Filename);setCellMessage(t,ShortPixel.successMsg(t,i,r.Type,r.ThumbsCount,r.RetinasCount),a),jQuery("#post-"+t).length>0&&jQuery("#post-"+t).find(".filename").text(r.Filename),jQuery(".misc-pub-filename strong").length>0&&jQuery(".misc-pub-filename strong").text(r.Filename),ShortPixel.isCustomImageId(t)&&r.TsOptimized&&r.TsOptimized.length>0&&(console.log(t),jQuery(".date-"+t).text(r.TsOptimized));var l=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+r.Type]).get();ShortPixel.otherMediaUpdateActions(t,l);new PercentageAnimator("#sp-msg-"+t+" span.percent",i).animate(i),o&&void 0!==r.Thumb&&(r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),r.Thumb.length>0&&(sliderUpdate(t,r.Thumb,r.BkThumb,r.PercentImprovement,r.Filename),void 0!==r.AverageCompression&&0+r.AverageCompression>0&&(jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(r.AverageCompression)+'"/>'),ShortPixel.percentDial("#sp-avg-optimization .dial",60)))),console.log("Server response: "+e),o&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_SKIP:1!==r.Silent&&ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink);case ShortPixel.STATUS_ERROR:void 0!==r.Message&&(showToolBarAlert(ShortPixel.STATUS_SKIP,r.Message+" Image ID: "+t),setCellMessage(t,r.Message,"")),ShortPixel.otherMediaUpdateActions(t,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+e),showToolBarAlert(ShortPixel.STATUS_RETRY,""),o&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),o&&r.Count>3&&ShortPixel.bulkShowLengthyMsg(t,r.Filename,r.CustomImageLink),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance"),setTimeout(checkBulkProgress,6e4);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full"),setTimeout(checkBulkProgress,6e4);break;default:ShortPixel.retry("Unknown status "+r.Status+". Retrying...")}}},error:function(e){ShortPixel.retry(e.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=!1,localStorage.bulkTime=0,window.location.href.search("wp-short-pixel-bulk")>=0&&(localStorage.bulkPage=0)}function setCellMessage(e,r,t){var o=jQuery("#sp-msg-"+e);o.length>0&&(o.html("<div class='sp-column-actions'>"+t+"</div><div class='sp-column-info'>"+r+"</div>"),o.css("color","")),(o=jQuery("#sp-cust-msg-"+e)).length>0&&o.html("<div class='sp-column-info'>"+r+"</div>")}function manualOptimization(e,r){setCellMessage(e,"<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 t={action:"shortpixel_manual_optimization",image_id:e,cleanup:r};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")},error:function(r){t.action="shortpixel_check_status",jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status!==ShortPixel.STATUS_SUCCESS&&setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")}})}})}function reoptimize(e,r){setCellMessage(e,"<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 t={action:"shortpixel_redo",attachment_ID:e,type:r};jQuery.get(ShortPixel.AJAX_URL,t,function(r){(t=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):($msg=void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,setCellMessage(e,$msg,""),showToolBarAlert(ShortPixel.STATUS_FAIL,$msg))})}function optimizeThumbs(e){setCellMessage(e,"<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 r={action:"shortpixel_optimize_thumbs",attachment_ID:e};jQuery.get(ShortPixel.AJAX_URL,r,function(t){(r=JSON.parse(t)).Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):setCellMessage(e,void 0!==r.Message?r.Message:_spTr.thisContentNotProcessable,"")})}function dismissShortPixelNoticeExceed(e){jQuery("#wp-admin-bar-shortpixel_processing").hide();var r={action:"shortpixel_dismiss_notice",notice_id:"exceed"};jQuery.get(ShortPixel.AJAX_URL,r,function(e){(r=JSON.parse(e)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")}),e.preventDefault()}function dismissShortPixelNotice(e){jQuery("#short-pixel-notice-"+e).hide();var r={action:"shortpixel_dismiss_notice",notice_id:e};jQuery.get(ShortPixel.AJAX_URL,r,function(e){(r=JSON.parse(e)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})}function PercentageAnimator(e,r){this.animationSpeed=10,this.increment=2,this.curPercentage=0,this.targetPercentage=r,this.outputSelector=e,this.animate=function(e){this.targetPercentage=e,setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(e){e.curPercentage-e.targetPercentage<-e.increment?e.curPercentage+=e.increment:e.curPercentage-e.targetPercentage>e.increment?e.curPercentage-=e.increment:e.curPercentage=e.targetPercentage,jQuery(e.outputSelector).text(e.curPercentage+"%"),e.curPercentage!=e.targetPercentage&&setTimeout(PercentageTimer.bind(null,e),e.animationSpeed)}function progressUpdate(e,r){var t=jQuery("#bulk-progress");t.length&&(jQuery(".progress-left",t).css("width",e+"%"),jQuery(".progress-img",t).css("left",e+"%"),e>24?(jQuery(".progress-img span",t).html(""),jQuery(".progress-left",t).html(e+"%")):(jQuery(".progress-img span",t).html(e+"%"),jQuery(".progress-left",t).html("")),jQuery(".bulk-estimate").html(r))}function sliderUpdate(e,r,t,o,s){var i=jQuery(".bulk-slider div.bulk-slide:first-child");if(0!==i.length){"empty-slide"!=i.attr("id")&&i.hide(),i.css("z-index",1e3),jQuery(".bulk-img-opt",i).attr("src",""),void 0===t&&(t=""),t.length>0&&jQuery(".bulk-img-orig",i).attr("src","");var a=i.clone();a.attr("id","slide-"+e),jQuery(".bulk-img-opt",a).attr("src",r),t.length>0?(jQuery(".img-original",a).css("display","inline-block"),jQuery(".bulk-img-orig",a).attr("src",t)):jQuery(".img-original",a).css("display","none"),jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+o+'"/>'),jQuery(".bulk-slider").append(a),ShortPixel.percentDial("#"+a.attr("id")+" .dial",100),jQuery(".bulk-slider-container span.filename").html(" "+s),"empty-slide"==i.attr("id")?(i.remove(),jQuery(".bulk-slider-container").css("display","block")):i.animate({left:i.width()+i.position().left},"slow","swing",function(){i.remove(),a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){jQuery(".bulk-stats").length}jQuery(document).ready(function(){ShortPixel.init()});var ShortPixel=function(){function e(e){jQuery(e).is(":checked")?jQuery("#width,#height").removeAttr("disabled"):jQuery("#width,#height").attr("disabled","disabled")}return jQuery("#key").keypress(function(e){13==e.which&&jQuery("#valid").val("validate")}),{init:function(){void 0===ShortPixel.API_KEY&&(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]),jQuery("#backup-folder-size").length&&jQuery("#backup-folder-size").html(ShortPixel.getBackupSize()),"todo"==ShortPixel.MEDIA_ALERT&&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(){1==ShortPixel.bulkProcessor&&clearBulkProcessor()}),checkQuotaExceededAlert(),checkBulkProgress())},setOptions:function(e){for(var r in e)ShortPixel[r]=e[r]},isEmailValid:function(e){return/^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(e)},updateSignupEmail:function(){var e=jQuery("#pluginemail").val();ShortPixel.isEmailValid(e)&&jQuery("#request_key").removeClass("disabled"),jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+e)},validateKey:function(e){console.log("validate"),jQuery("#valid").val("validate"),jQuery(e).parents("form").submit()},enableResize:e,setupGeneralTab:function(){var r=0;void 0!==document.wp_shortpixel_options&&(r=document.wp_shortpixel_options.compressionType);for(var t=0,o=null;t<r.length;t++)r[t].onclick=function(){this!==o&&(o=this),void 0===ShortPixel.setupGeneralTabAlert&&(alert(_spTr.alertOnlyAppliesToNewImages),ShortPixel.setupGeneralTabAlert=1)};ShortPixel.enableResize("#resize"),jQuery("#resize").change(function(){e(this)}),jQuery(".resize-sizes").blur(function(e){var r=jQuery(e.target);if(ShortPixel.resizeSizesAlert!=r.val()){ShortPixel.resizeSizesAlert=r.val();var t=jQuery("#min-"+r.attr("name")).val(),o=jQuery("#min-"+r.attr("name")).data("nicename");r.val()<Math.min(t,1024)?(t>1024?alert(_spTr.pleaseDoNotSetLesser1024.format(o)):alert(_spTr.pleaseDoNotSetLesserSize.format(o,o,t)),e.preventDefault(),r.focus()):this.defaultValue=r.val()}}),jQuery(".shortpixel-confirm").click(function(e){return!!confirm(e.target.getAttribute("data-confirm"))||(e.preventDefault(),!1)}),jQuery('input[name="removeExif"], input[name="png2jpg"]').on("change",function(){ShortPixel.checkExifWarning()}),ShortPixel.checkExifWarning()},apiKeyChanged:function(){jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display","none"),jQuery(".wp-shortpixel-options button#validate").css("display","inline-block")},setupAdvancedTab:function(){jQuery("input.remove-folder-button").click(function(){var e=jQuery(this).data("value");1==confirm(_spTr.areYouSureStopOptimizing.format(e))&&(jQuery("#removeFolder").val(e),jQuery("#wp_shortpixel_options").submit())}),jQuery("input.recheck-folder-button").click(function(){var e=jQuery(this).data("value");1==confirm(_spTr.areYouSureStopOptimizing.format(e))&&(jQuery("#recheckFolder").val(e),jQuery("#wp_shortpixel_options").submit())})},checkThumbsUpdTotal:function(e){var r=jQuery("#"+(e.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(r),jQuery("#displayTotal").text(r)},initSettings:function(){ShortPixel.adjustSettingsTabs(),ShortPixel.setupGeneralTab(),jQuery(window).resize(function(){ShortPixel.adjustSettingsTabs()}),jQuery("article.sp-tabs a.tab-link").click(function(e){var r=jQuery(e.target).data("id");ShortPixel.switchSettingsTab(r)}),jQuery("input[type=radio][name=deliverWebpType]").change(function(){"deliverWebpAltered"==this.value?window.confirm(_spTr.alertDeliverWebPAltered)?0==jQuery("input[type=radio][name=deliverWebpAlteringType]:checked").length&&jQuery("#deliverWebpAlteredWP").prop("checked",!0):jQuery(this).prop("checked",!1):"deliverWebpUnaltered"==this.value&&window.alert(_spTr.alertDeliverWebPUnaltered)})},switchSettingsTab:function(e){var r=e.replace("tab-",""),t="",o=jQuery("section#"+e);jQuery('input[name="display_part"]').val(r);var s=window.location.href.toString();if(s.indexOf("?")>0){var i=s.substring(0,s.indexOf("?"));i+="?"+jQuery.param({page:"wp-shortpixel-settings",part:r}),window.history.replaceState({},document.title,i)}if(o.length>0&&(jQuery("section").removeClass("sel-tab"),jQuery("section .wp-shortpixel-tab-content").fadeOut(50),jQuery(o).addClass("sel-tab"),ShortPixel.adjustSettingsTabs(),jQuery(o).find(".wp-shortpixel-tab-content").fadeIn(50)),void 0!==HS.beacon.suggest){switch(r){case"settings":t=shortpixel_suggestions_settings;break;case"adv-settings":t=shortpixel_suggestions_adv_settings;break;case"cloudflare":case"stats":t=shortpixel_suggestions_cloudflare}HS.beacon.suggest(t)}},adjustSettingsTabs:function(){var e=jQuery("section.sel-tab").height()+90;jQuery(".section-wrapper").css("height",e)},onBulkThumbsCheck:function(e){e.checked?(jQuery("#with-thumbs").css("display","inherit"),jQuery("#without-thumbs").css("display","none")):(jQuery("#without-thumbs").css("display","inherit"),jQuery("#with-thumbs").css("display","none"))},dismissMediaAlert:function(){var e={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){"success"==(e=JSON.parse(r)).Status&&jQuery("#short-pixel-media-alert").hide()})},checkQuota:function(){jQuery.get(ShortPixel.AJAX_URL,{action:"shortpixel_check_quota"},function(){console.log("quota refreshed")})},percentDial:function(e,r){jQuery(e).knob({readOnly:!0,width:r,height:r,fgColor:"#1CAECB",format:function(e){return e+"%"}})},successMsg:function(e,r,t,o,s){return(r>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+r+"%</span></strong> ":"")+(r>0&&r<5?"<br>":"")+(r<5?_spTr.bonusProcessing:"")+(t.length>0?" ("+t+")":"")+(0+o>0?"<br>"+_spTr.plusXthumbsOpt.format(o):"")+(0+s>0?"<br>"+_spTr.plusXretinasOpt.format(s):"")+"</div>"},successActions:function(e,r,t,o,s,i){if(1==s){var a=jQuery(".sp-column-actions-template").clone();if(!a.length)return!1;var l;return l=0==r.length?["lossy","lossless"]:["lossy","glossy","lossless"].filter(function(e){return!(e==r)}),a.html(a.html().replace(/__SP_ID__/g,e)),"pdf"==i.substr(i.lastIndexOf(".")+1).toLowerCase()&&jQuery(".sp-action-compare",a).remove(),0==t&&o>0?a.html(a.html().replace("__SP_THUMBS_TOTAL__",o)):(jQuery(".sp-action-optimize-thumbs",a).remove(),jQuery(".sp-dropbtn",a).removeClass("button-primary")),a.html(a.html().replace(/__SP_FIRST_TYPE__/g,l[0])),a.html(a.html().replace(/__SP_SECOND_TYPE__/g,l[1])),a.html()}return""},otherMediaUpdateActions:function(e,r){if(e=e.substring(2),jQuery(".shortpixel-other-media").length){for(var t=["optimize","retry","restore","redo","quota","view"],o=0,s=t.length;o<s;o++)jQuery("#"+t[o]+"_"+e).css("display","none");for(var o=0,s=r.length;o<s;o++)jQuery("#"+r[o]+"_"+e).css("display","")}},retry:function(e){ShortPixel.retries++,isNaN(ShortPixel.retries)&&(ShortPixel.retries=1),ShortPixel.retries<6?(console.log("Invalid response from server (Error: "+e+"). Retrying pass "+(ShortPixel.retries+1)+"..."),setTimeout(checkBulkProgress,5e3)):(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: "+e+")",""),console.log("Invalid response from server 6 times. Giving up."))},initFolderSelector:function(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").fadeIn(100),jQuery(".shortpixel-modal.modal-folder-picker").show();var e=jQuery(".sp-folder-picker");e.parent().css("margin-left",-e.width()/2),e.fileTree({script:ShortPixel.browseContent,multiFolder:!1})}),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(e){if(r=jQuery("UL.jqueryFileTree LI.directory.selected"),0==jQuery(r).length)var r=jQuery("UL.jqueryFileTree LI.selected").parents(".directory");var t=jQuery(r).children("a").attr("rel");if(void 0!==t)if(t=t.trim()){var o=jQuery("#customFolderBase").val()+t;"/"==o.slice(-1)&&(o=o.slice(0,-1)),jQuery("#addCustomFolder").val(o),jQuery("#addCustomFolderView").val(o),jQuery(".sp-folder-picker-shade").fadeOut(100),jQuery(".shortpixel-modal.modal-folder-picker").css("display","none"),jQuery("#saveAdvAddFolder").removeClass("hidden")}else alert("Please select a folder from the list.")})},browseContent:function(e){e.action="shortpixel_browse_content";var r="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:e,success:function(e){r=e},async:!1}),r},getBackupSize:function(){var e="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_backup_size"},success:function(r){e=r},async:!1}),e},newApiKey:function(e){if(!jQuery("#tos").is(":checked"))return e.preventDefault(),jQuery("#tos-robo").fadeIn(400,function(){jQuery("#tos-hand").fadeIn()}),void jQuery("#tos").click(function(){jQuery("#tos-robo").css("display","none"),jQuery("#tos-hand").css("display","none")});if(jQuery("#request_key").addClass("disabled"),jQuery("#pluginemail_spinner").addClass("is-active"),ShortPixel.updateSignupEmail(),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:!1,url:ShortPixel.AJAX_URL,data:r,success:function(r){data=JSON.parse(r),"success"==data.Status?(e.preventDefault(),window.location.reload()):"invalid"==data.Status&&(jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>"),jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault())}}),jQuery("#request_key").removeAttr("onclick")}else jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault();jQuery("#request_key").removeClass("disabled"),jQuery("#pluginemail_spinner").removeClass("is-active")},proposeUpgrade:function(){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"),jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_propose_upgrade"},success:function(e){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner"),jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(e)}})},closeProposeUpgrade:function(){jQuery("#shortPixelProposeUpgradeShade").css("display","none"),jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide"),ShortPixel.toRefresh&&ShortPixel.recheckQuota()},includeUnlisted:function(){jQuery("#short-pixel-notice-unlisted").hide(),jQuery("#optimizeUnlisted").prop("checked",!0);var e={action:"shortpixel_dismiss_notice",notice_id:"unlisted",notice_data:"true"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){(e=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})},bulkShowLengthyMsg:function(e,r,t){var o=jQuery(".bulk-notice-msg.bulk-lengthy");if(0!=o.length){var s=jQuery("a",o);s.text(r),t?s.attr("href",t):s.attr("href",s.data("href").replace("__ID__",e)),o.css("display","block")}},bulkHideLengthyMsg:function(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")},bulkShowMaintenanceMsg:function(e){var r=jQuery(".bulk-notice-msg.bulk-"+e);0!=r.length&&r.css("display","block")},bulkHideMaintenanceMsg:function(e){jQuery(".bulk-notice-msg.bulk-"+e).css("display","none")},bulkShowError:function(e,r,t,o){var s=jQuery("#bulk-error-template");if(0!=s.length){var i=s.clone();i.attr("id","bulk-error-"+e),-1==e?(jQuery("span.sp-err-title",i).remove(),i.addClass("bulk-error-fatal")):(jQuery("img",i).remove(),jQuery("#bulk-error-".id).remove()),jQuery("span.sp-err-content",i).html(r);var a=jQuery("a.sp-post-link",i);o?a.attr("href",o):a.attr("href",a.attr("href").replace("__ID__",e)),a.text(t),s.after(i),i.css("display","block")}},confirmBulkAction:function(e,r){return!!confirm(_spTr["confirmBulk"+e])||(r.stopPropagation(),r.preventDefault(),!1)},checkRandomAnswer:function(e){var r=jQuery(e.target).val(),t=jQuery('input[name="random_answer"]').val(),o=jQuery('input[name="random_answer"]').data("target");r==t?(jQuery(o).removeClass("disabled").prop("disabled",!1),jQuery(o).removeAttr("aria-disabled")):jQuery(o).addClass("disabled").prop("disabled",!0)},removeBulkMsg:function(e){jQuery(e).parent().parent().remove()},isCustomImageId:function(e){return"C-"==e.substring(0,2)},recheckQuota:function(){var e=window.location.href.split("#");window.location.href=e[0]+(e[0].indexOf("?")>0?"&":"?")+"checkquota=1"+(void 0===e[1]?"":"#"+e[1])},openImageMenu:function(e){e.preventDefault(),this.menuCloseEvent||(jQuery(window).click(function(e){e.target.matches(".sp-dropbtn")||jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}),this.menuCloseEvent=!0);var r=e.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show"),r||e.target.parentElement.classList.add("sp-show")},menuCloseEvent:!1,loadComparer:function(e){this.comparerData.origUrl=!1,!1===this.comparerData.cssLoaded&&(jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"}),this.comparerData.cssLoaded=2),!1===this.comparerData.jsLoaded&&(jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2,ShortPixel.comparerData.origUrl.length>0&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}),this.comparerData.jsLoaded=1),!1===this.comparerData.origUrl&&(jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:e},success:function(e){data=JSON.parse(e),jQuery.extend(ShortPixel.comparerData,data),2==ShortPixel.comparerData.jsLoaded&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}),this.comparerData.origUrl="")},displayComparerPopup:function(e,r,t,o){var s=e,i=r<150||e<350,a=jQuery(i?"#spUploadCompareSideBySide":"#spUploadCompare"),l=jQuery(".sp-modal-shade");i||jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>'),e=Math.max(350,Math.min(800,e<350?2*(e+25):r<150?e+25:e)),r=Math.max(150,i?s>350?2*(r+45):r+45:r*e/s);var n="-"+Math.round(e/2);jQuery(".sp-modal-body",a).css("width",e),jQuery(".shortpixel-slider",a).css("width",e),a.css("width",e),a.css("marginLeft",n+"px"),jQuery(".sp-modal-body",a).css("height",r),a.show(),l.show(),i||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 u=jQuery(".spUploadCompareOptimized",a);jQuery(".spUploadCompareOriginal",a).attr("src",t),setTimeout(function(){jQuery(window).trigger("resize")},1e3),u.load(function(){jQuery(window).trigger("resize")}),u.attr("src",o)},closeComparerPopup:function(e){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")},convertPunycode:function(e){var r=document.createElement("a");return r.href=e,e.indexOf(r.protocol+"//"+r.hostname)<0?r.href:e.replace(r.protocol+"//"+r.hostname,r.protocol+"//"+r.hostname.split(".").map(function(e){return sp_punycode.toASCII(e)}).join("."))},checkExifWarning:function(){!jQuery('input[name="removeExif"]').is(":checked")&&jQuery('input[name="png2jpg"]').is(":checked")?jQuery(".exif_warning").fadeIn():jQuery(".exif_warning").fadeOut()},comparerData:{cssLoaded:!1,jsLoaded:!1,origUrl:!1,optUrl:!1,width:0,height:0},toRefresh:!1,resizeSizesAlert:!1}}();"function"!=typeof String.prototype.format&&(String.prototype.format=function(){for(var e=this,r=arguments.length;r--;)e=e.replace(new RegExp("\\{"+r+"\\}","gm"),arguments[r]);return e});
|
1 |
+
function showToolBarAlert(e,r,t){var o=jQuery("li.shortpixel-toolbar-processing");switch(e){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&0==jQuery(".sp-quota-exceeded-alert").length)return void location.reload();o.addClass("shortpixel-alert"),o.addClass("shortpixel-quota-exceeded"),jQuery("a",o).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",o).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:o.addClass("shortpixel-alert shortpixel-processing"),jQuery("a div",o).attr("title",r),void 0!==t&&jQuery("a",o).attr("href","post.php?post="+t+"&action=edit");break;case ShortPixel.STATUS_NO_KEY:o.addClass("shortpixel-alert"),o.addClass("shortpixel-quota-exceeded"),jQuery("a",o).attr("href","options-general.php?page=wp-shortpixel-settings"),jQuery("a div",o).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:o.addClass("shortpixel-processing"),o.removeClass("shortpixel-alert"),jQuery("a",o).removeAttr("target"),jQuery("a",o).attr("href",jQuery("a img",o).attr("success-url"))}o.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(){"undefined"!=typeof shortPixelQuotaExceeded&&(1==shortPixelQuotaExceeded?showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED):hideQuotaExceededToolBarAlert())}function checkBulkProgress(){var e=function(e){return r?"/":(r=!0,e)},r=!1,t=window.location.href.toLowerCase().replace(/\/\//g,e);r=!1;var o=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,e);t.search(o)<0&&(t=ShortPixel.convertPunycode(t),o=ShortPixel.convertPunycode(o)),t.search(o+"upload.php")<0&&t.search(o+"edit.php")<0&&t.search(o+"edit-tags.php")<0&&t.search(o+"post-new.php")<0&&t.search(o+"post.php")<0&&t.search("page=nggallery-manage-gallery")<0&&(0==ShortPixel.FRONT_BOOTSTRAP||0==t.search(o))?hideToolBarAlert():(1==ShortPixel.bulkProcessor&&window.location.href.search("wp-short-pixel-bulk")<0&&void 0!==localStorage.bulkPage&&localStorage.bulkPage>0&&(ShortPixel.bulkProcessor=!1),window.location.href.search("wp-short-pixel-bulk")>=0&&(ShortPixel.bulkProcessor=!0,localStorage.bulkTime=Math.floor(Date.now()/1e3),localStorage.bulkPage=1),1==ShortPixel.bulkProcessor||void 0===localStorage.bulkTime||Math.floor(Date.now()/1e3)-localStorage.bulkTime>90?(ShortPixel.bulkProcessor=!0,localStorage.bulkPage=window.location.href.search("wp-short-pixel-bulk")>=0?1:0,localStorage.bulkTime=Math.floor(Date.now()/1e3),console.log(localStorage.bulkTime),checkBulkProcessingCallApi()):setTimeout(checkBulkProgress,5e3))}function checkBulkProcessingCallApi(){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_image_processing"},success:function(e){if(e.length>0){r=null;try{var r=JSON.parse(e)}catch(e){return void ShortPixel.retry(e.message)}ShortPixel.retries=0;var t=r.ImageID,o=jQuery("div.short-pixel-bulk-page").length>0;switch(r.Status&&r.Status!=ShortPixel.STATUS_SEARCHING&&(ShortPixel.returnedStatusSearching>=2&&jQuery(".bulk-notice-msg.bulk-searching").hide(),ShortPixel.returnedStatusSearching=0),r.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(t,r.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(t,r.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),0==r.Stop&&setTimeout(checkBulkProgress,5e3),ShortPixel.otherMediaUpdateActions(t,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(t,r.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+t+"', false)\">"+_spTr.retry+"</a>"),showToolBarAlert(ShortPixel.STATUS_FAIL,r.Message,t),o&&(ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink),r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),ShortPixel.otherMediaUpdateActions(t,["retry","view"])),console.log(r.Message),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(r.Message),clearBulkProcessor(),hideToolBarAlert();var s=jQuery("#bulk-progress");o&&s.length&&"2"!=r.BulkStatus&&(progressUpdate(100,"Bulk finished!"),jQuery("a.bulk-cancel").attr("disabled","disabled"),hideSlider(),setTimeout(function(){window.location.reload()},3e3));break;case ShortPixel.STATUS_SUCCESS:o&&(ShortPixel.bulkHideLengthyMsg(),ShortPixel.bulkHideMaintenanceMsg());var i=r.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var a=ShortPixel.isCustomImageId(t)?"":ShortPixel.successActions(t,r.Type,r.ThumbsCount,r.ThumbsTotal,r.BackupEnabled,r.Filename);setCellMessage(t,ShortPixel.successMsg(t,i,r.Type,r.ThumbsCount,r.RetinasCount),a),jQuery("#post-"+t).length>0&&jQuery("#post-"+t).find(".filename").text(r.Filename),jQuery(".misc-pub-filename strong").length>0&&jQuery(".misc-pub-filename strong").text(r.Filename),ShortPixel.isCustomImageId(t)&&r.TsOptimized&&r.TsOptimized.length>0&&(console.log(t),jQuery(".date-"+t).text(r.TsOptimized));var l=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+r.Type]).get();ShortPixel.otherMediaUpdateActions(t,l);new PercentageAnimator("#sp-msg-"+t+" span.percent",i).animate(i),o&&void 0!==r.Thumb&&(r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),r.Thumb.length>0&&(sliderUpdate(t,r.Thumb,r.BkThumb,r.PercentImprovement,r.Filename),void 0!==r.AverageCompression&&0+r.AverageCompression>0&&(jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(r.AverageCompression)+'"/>'),ShortPixel.percentDial("#sp-avg-optimization .dial",60)))),console.log("Server response: "+e),o&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_SKIP:1!==r.Silent&&ShortPixel.bulkShowError(t,r.Message,r.Filename,r.CustomImageLink);case ShortPixel.STATUS_ERROR:void 0!==r.Message&&(showToolBarAlert(ShortPixel.STATUS_SKIP,r.Message+" Image ID: "+t),setCellMessage(t,r.Message,"")),ShortPixel.otherMediaUpdateActions(t,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+e),showToolBarAlert(ShortPixel.STATUS_RETRY,""),o&&void 0!==r.BulkPercent&&progressUpdate(r.BulkPercent,r.BulkMsg),o&&r.Count>3&&ShortPixel.bulkShowLengthyMsg(t,r.Filename,r.CustomImageLink),setTimeout(checkBulkProgress,5e3);break;case ShortPixel.STATUS_SEARCHING:console.log("Server response: "+e),ShortPixel.returnedStatusSearching++,ShortPixel.returnedStatusSearching>=2&&jQuery(".bulk-notice-msg.bulk-searching").show(),setTimeout(checkBulkProgress,2500);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance"),setTimeout(checkBulkProgress,6e4);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full"),setTimeout(checkBulkProgress,6e4);break;default:ShortPixel.retry("Unknown status "+r.Status+". Retrying...")}}},error:function(e){ShortPixel.retry(e.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=!1,localStorage.bulkTime=0,window.location.href.search("wp-short-pixel-bulk")>=0&&(localStorage.bulkPage=0)}function setCellMessage(e,r,t){var o=jQuery("#sp-msg-"+e);o.length>0&&(o.html("<div class='sp-column-actions'>"+t+"</div><div class='sp-column-info'>"+r+"</div>"),o.css("color","")),(o=jQuery("#sp-cust-msg-"+e)).length>0&&o.html("<div class='sp-column-info'>"+r+"</div>")}function manualOptimization(e,r){setCellMessage(e,"<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 t={action:"shortpixel_manual_optimization",image_id:e,cleanup:r};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")},error:function(r){t.action="shortpixel_check_status",jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:t,success:function(r){var t=JSON.parse(r);t.Status!==ShortPixel.STATUS_SUCCESS&&setCellMessage(e,void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,"")}})}})}function reoptimize(e,r){setCellMessage(e,"<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 t={action:"shortpixel_redo",attachment_ID:e,type:r};jQuery.get(ShortPixel.AJAX_URL,t,function(r){(t=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):($msg=void 0!==t.Message?t.Message:_spTr.thisContentNotProcessable,setCellMessage(e,$msg,""),showToolBarAlert(ShortPixel.STATUS_FAIL,$msg))})}function optimizeThumbs(e){setCellMessage(e,"<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 r={action:"shortpixel_optimize_thumbs",attachment_ID:e};jQuery.get(ShortPixel.AJAX_URL,r,function(t){(r=JSON.parse(t)).Status==ShortPixel.STATUS_SUCCESS?setTimeout(checkBulkProgress,2e3):setCellMessage(e,void 0!==r.Message?r.Message:_spTr.thisContentNotProcessable,"")})}function dismissShortPixelNoticeExceed(e){jQuery("#wp-admin-bar-shortpixel_processing").hide();var r={action:"shortpixel_dismiss_notice",notice_id:"exceed"};jQuery.get(ShortPixel.AJAX_URL,r,function(e){(r=JSON.parse(e)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")}),e.preventDefault()}function dismissShortPixelNotice(e){jQuery("#short-pixel-notice-"+e).hide();var r={action:"shortpixel_dismiss_notice",notice_id:e};jQuery.get(ShortPixel.AJAX_URL,r,function(e){(r=JSON.parse(e)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})}function PercentageAnimator(e,r){this.animationSpeed=10,this.increment=2,this.curPercentage=0,this.targetPercentage=r,this.outputSelector=e,this.animate=function(e){this.targetPercentage=e,setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(e){e.curPercentage-e.targetPercentage<-e.increment?e.curPercentage+=e.increment:e.curPercentage-e.targetPercentage>e.increment?e.curPercentage-=e.increment:e.curPercentage=e.targetPercentage,jQuery(e.outputSelector).text(e.curPercentage+"%"),e.curPercentage!=e.targetPercentage&&setTimeout(PercentageTimer.bind(null,e),e.animationSpeed)}function progressUpdate(e,r){var t=jQuery("#bulk-progress");t.length&&(jQuery(".progress-left",t).css("width",e+"%"),jQuery(".progress-img",t).css("left",e+"%"),e>24?(jQuery(".progress-img span",t).html(""),jQuery(".progress-left",t).html(e+"%")):(jQuery(".progress-img span",t).html(e+"%"),jQuery(".progress-left",t).html("")),jQuery(".bulk-estimate").html(r))}function sliderUpdate(e,r,t,o,s){var i=jQuery(".bulk-slider div.bulk-slide:first-child");if(0!==i.length){"empty-slide"!=i.attr("id")&&i.hide(),i.css("z-index",1e3),jQuery(".bulk-img-opt",i).attr("src",""),void 0===t&&(t=""),t.length>0&&jQuery(".bulk-img-orig",i).attr("src","");var a=i.clone();a.attr("id","slide-"+e),jQuery(".bulk-img-opt",a).attr("src",r),t.length>0?(jQuery(".img-original",a).css("display","inline-block"),jQuery(".bulk-img-orig",a).attr("src",t)):jQuery(".img-original",a).css("display","none"),jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+o+'"/>'),jQuery(".bulk-slider").append(a),ShortPixel.percentDial("#"+a.attr("id")+" .dial",100),jQuery(".bulk-slider-container span.filename").html(" "+s),"empty-slide"==i.attr("id")?(i.remove(),jQuery(".bulk-slider-container").css("display","block")):i.animate({left:i.width()+i.position().left},"slow","swing",function(){i.remove(),a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){jQuery(".bulk-stats").length}jQuery(document).ready(function(){ShortPixel.init()});var ShortPixel=function(){function e(e){jQuery(e).is(":checked")?jQuery("#width,#height").removeAttr("disabled"):jQuery("#width,#height").attr("disabled","disabled")}function r(){jQuery("#shortpixel-hs-button-blind").remove(),jQuery("#shortpixel-hs-tools").remove(),jQuery("#hs-beacon").remove(),jQuery("#botbutton").remove(),jQuery("#shortpixel-hs-blind").remove()}return jQuery("#key").keypress(function(e){13==e.which&&jQuery("#valid").val("validate")}),{init:function(){void 0===ShortPixel.API_KEY&&(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]),jQuery("#backup-folder-size").length&&jQuery("#backup-folder-size").html(ShortPixel.getBackupSize()),"todo"==ShortPixel.MEDIA_ALERT&&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(){1==ShortPixel.bulkProcessor&&clearBulkProcessor()}),checkQuotaExceededAlert(),checkBulkProgress())},setOptions:function(e){for(var r in e)ShortPixel[r]=e[r]},isEmailValid:function(e){return/^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(e)},updateSignupEmail:function(){var e=jQuery("#pluginemail").val();ShortPixel.isEmailValid(e)&&jQuery("#request_key").removeClass("disabled"),jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+e)},enableResize:e,setupGeneralTab:function(){var r=0;void 0!==document.wp_shortpixel_options&&(r=document.wp_shortpixel_options.compressionType);for(var t=0,o=null;t<r.length;t++)r[t].onclick=function(){this!==o&&(o=this),void 0===ShortPixel.setupGeneralTabAlert&&(alert(_spTr.alertOnlyAppliesToNewImages),ShortPixel.setupGeneralTabAlert=1)};ShortPixel.enableResize("#resize"),jQuery("#resize").change(function(){e(this)}),jQuery(".resize-sizes").blur(function(e){var r=jQuery(e.target);if(ShortPixel.resizeSizesAlert!=r.val()){ShortPixel.resizeSizesAlert=r.val();var t=jQuery("#min-"+r.attr("name")).val(),o=jQuery("#min-"+r.attr("name")).data("nicename");r.val()<Math.min(t,1024)?(t>1024?alert(_spTr.pleaseDoNotSetLesser1024.format(o)):alert(_spTr.pleaseDoNotSetLesserSize.format(o,o,t)),e.preventDefault(),r.focus()):this.defaultValue=r.val()}}),jQuery(".shortpixel-confirm").click(function(e){return!!confirm(e.target.getAttribute("data-confirm"))||(e.preventDefault(),!1)}),jQuery('input[name="removeExif"], input[name="png2jpg"]').on("change",function(){ShortPixel.checkExifWarning()}),ShortPixel.checkExifWarning()},apiKeyChanged:function(){jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display","none"),jQuery(".wp-shortpixel-options button#validate").css("display","inline-block")},setupAdvancedTab:function(){jQuery("input.remove-folder-button").click(function(){var e=jQuery(this).data("value");1==confirm(_spTr.areYouSureStopOptimizing.format(e))&&(jQuery("#removeFolder").val(e),jQuery("#wp_shortpixel_options").submit())}),jQuery("input.recheck-folder-button").click(function(){var e=jQuery(this).data("value");1==confirm(_spTr.areYouSureStopOptimizing.format(e))&&(jQuery("#recheckFolder").val(e),jQuery("#wp_shortpixel_options").submit())})},checkThumbsUpdTotal:function(e){var r=jQuery("#"+(e.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(r),jQuery("#displayTotal").text(r)},initSettings:function(){ShortPixel.adjustSettingsTabs(),ShortPixel.setupGeneralTab(),jQuery(window).resize(function(){ShortPixel.adjustSettingsTabs()}),jQuery("article.sp-tabs a.tab-link").click(function(e){var r=jQuery(e.target).data("id");ShortPixel.switchSettingsTab(r)}),jQuery("input[type=radio][name=deliverWebpType]").change(function(){"deliverWebpAltered"==this.value?window.confirm(_spTr.alertDeliverWebPAltered)?0==jQuery("input[type=radio][name=deliverWebpAlteringType]:checked").length&&jQuery("#deliverWebpAlteredWP").prop("checked",!0):jQuery(this).prop("checked",!1):"deliverWebpUnaltered"==this.value&&window.alert(_spTr.alertDeliverWebPUnaltered)})},switchSettingsTab:function(e){var r=e.replace("tab-",""),t="",o=jQuery("section#"+e);jQuery('input[name="display_part"]').val(r);var s=window.location.href.toString();if(s.indexOf("?")>0){var i=s.substring(0,s.indexOf("?"));i+="?"+jQuery.param({page:"wp-shortpixel-settings",part:r}),window.history.replaceState({},document.title,i)}if(o.length>0&&(jQuery("section").removeClass("sel-tab"),jQuery("section .wp-shortpixel-tab-content").fadeOut(50),jQuery(o).addClass("sel-tab"),ShortPixel.adjustSettingsTabs(),jQuery(o).find(".wp-shortpixel-tab-content").fadeIn(50)),void 0!==HS.beacon.suggest){switch(r){case"settings":t=shortpixel_suggestions_settings;break;case"adv-settings":t=shortpixel_suggestions_adv_settings;break;case"cloudflare":case"stats":t=shortpixel_suggestions_cloudflare}HS.beacon.suggest(t)}},adjustSettingsTabs:function(){var e=jQuery("section.sel-tab").height()+90;jQuery(".section-wrapper").css("height",e)},onBulkThumbsCheck:function(e){e.checked?(jQuery("#with-thumbs").css("display","inherit"),jQuery("#without-thumbs").css("display","none")):(jQuery("#without-thumbs").css("display","inherit"),jQuery("#with-thumbs").css("display","none"))},dismissMediaAlert:function(){var e={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){"success"==(e=JSON.parse(r)).Status&&jQuery("#short-pixel-media-alert").hide()})},closeHelpPane:r,dismissHelpPane:function(){r(),dismissShortPixelNotice("help")},checkQuota:function(){jQuery.get(ShortPixel.AJAX_URL,{action:"shortpixel_check_quota"},function(){console.log("quota refreshed")})},percentDial:function(e,r){jQuery(e).knob({readOnly:!0,width:r,height:r,fgColor:"#1CAECB",format:function(e){return e+"%"}})},successMsg:function(e,r,t,o,s){return(r>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+r+"%</span></strong> ":"")+(r>0&&r<5?"<br>":"")+(r<5?_spTr.bonusProcessing:"")+(t.length>0?" ("+t+")":"")+(0+o>0?"<br>"+_spTr.plusXthumbsOpt.format(o):"")+(0+s>0?"<br>"+_spTr.plusXretinasOpt.format(s):"")+"</div>"},successActions:function(e,r,t,o,s,i){if(1==s){var a=jQuery(".sp-column-actions-template").clone();if(!a.length)return!1;var l;return l=0==r.length?["lossy","lossless"]:["lossy","glossy","lossless"].filter(function(e){return!(e==r)}),a.html(a.html().replace(/__SP_ID__/g,e)),"pdf"==i.substr(i.lastIndexOf(".")+1).toLowerCase()&&jQuery(".sp-action-compare",a).remove(),0==t&&o>0?a.html(a.html().replace("__SP_THUMBS_TOTAL__",o)):(jQuery(".sp-action-optimize-thumbs",a).remove(),jQuery(".sp-dropbtn",a).removeClass("button-primary")),a.html(a.html().replace(/__SP_FIRST_TYPE__/g,l[0])),a.html(a.html().replace(/__SP_SECOND_TYPE__/g,l[1])),a.html()}return""},otherMediaUpdateActions:function(e,r){if(e=e.substring(2),jQuery(".shortpixel-other-media").length){for(var t=["optimize","retry","restore","redo","quota","view"],o=0,s=t.length;o<s;o++)jQuery("#"+t[o]+"_"+e).css("display","none");for(var o=0,s=r.length;o<s;o++)jQuery("#"+r[o]+"_"+e).css("display","")}},retry:function(e){ShortPixel.retries++,isNaN(ShortPixel.retries)&&(ShortPixel.retries=1),ShortPixel.retries<6?(console.log("Invalid response from server (Error: "+e+"). Retrying pass "+(ShortPixel.retries+1)+"..."),setTimeout(checkBulkProgress,5e3)):(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: "+e+")",""),console.log("Invalid response from server 6 times. Giving up."))},initFolderSelector:function(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").fadeIn(100),jQuery(".shortpixel-modal.modal-folder-picker").show();var e=jQuery(".sp-folder-picker");e.parent().css("margin-left",-e.width()/2),e.fileTree({script:ShortPixel.browseContent,multiFolder:!1})}),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(e){if(r=jQuery("UL.jqueryFileTree LI.directory.selected"),0==jQuery(r).length)var r=jQuery("UL.jqueryFileTree LI.selected").parents(".directory");var t=jQuery(r).children("a").attr("rel");if(void 0!==t)if(t=t.trim()){var o=jQuery("#customFolderBase").val()+t;"/"==o.slice(-1)&&(o=o.slice(0,-1)),jQuery("#addCustomFolder").val(o),jQuery("#addCustomFolderView").val(o),jQuery(".sp-folder-picker-shade").fadeOut(100),jQuery(".shortpixel-modal.modal-folder-picker").css("display","none"),jQuery("#saveAdvAddFolder").removeClass("hidden")}else alert("Please select a folder from the list.")})},browseContent:function(e){e.action="shortpixel_browse_content";var r="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:e,success:function(e){r=e},async:!1}),r},getBackupSize:function(){var e="";return jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_backup_size"},success:function(r){e=r},async:!1}),e},newApiKey:function(e){if(!jQuery("#tos").is(":checked"))return e.preventDefault(),jQuery("#tos-robo").fadeIn(400,function(){jQuery("#tos-hand").fadeIn()}),void jQuery("#tos").click(function(){jQuery("#tos-robo").css("display","none"),jQuery("#tos-hand").css("display","none")});if(jQuery("#request_key").addClass("disabled"),jQuery("#pluginemail_spinner").addClass("is-active"),ShortPixel.updateSignupEmail(),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:!1,url:ShortPixel.AJAX_URL,data:r,success:function(r){data=JSON.parse(r),"success"==data.Status?(e.preventDefault(),window.location.reload()):"invalid"==data.Status&&(jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>"),jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault())}}),jQuery("#request_key").removeAttr("onclick")}else jQuery("#pluginemail-error").css("display",""),jQuery("#pluginemail-info").css("display","none"),e.preventDefault();jQuery("#request_key").removeClass("disabled"),jQuery("#pluginemail_spinner").removeClass("is-active")},proposeUpgrade:function(){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"),jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_propose_upgrade"},success:function(e){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner"),jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(e)}})},closeProposeUpgrade:function(){jQuery("#shortPixelProposeUpgradeShade").css("display","none"),jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide"),ShortPixel.toRefresh&&ShortPixel.recheckQuota()},includeUnlisted:function(){jQuery("#short-pixel-notice-unlisted").hide(),jQuery("#optimizeUnlisted").prop("checked",!0);var e={action:"shortpixel_dismiss_notice",notice_id:"unlisted",notice_data:"true"};jQuery.get(ShortPixel.AJAX_URL,e,function(r){(e=JSON.parse(r)).Status==ShortPixel.STATUS_SUCCESS&&console.log("dismissed")})},bulkShowLengthyMsg:function(e,r,t){var o=jQuery(".bulk-notice-msg.bulk-lengthy");if(0!=o.length){var s=jQuery("a",o);s.text(r),t?s.attr("href",t):s.attr("href",s.data("href").replace("__ID__",e)),o.css("display","block")}},bulkHideLengthyMsg:function(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")},bulkShowMaintenanceMsg:function(e){var r=jQuery(".bulk-notice-msg.bulk-"+e);0!=r.length&&r.css("display","block")},bulkHideMaintenanceMsg:function(e){jQuery(".bulk-notice-msg.bulk-"+e).css("display","none")},bulkShowError:function(e,r,t,o){var s=jQuery("#bulk-error-template");if(0!=s.length){var i=s.clone();i.attr("id","bulk-error-"+e),-1==e?(jQuery("span.sp-err-title",i).remove(),i.addClass("bulk-error-fatal")):(jQuery("img",i).remove(),jQuery("#bulk-error-".id).remove()),jQuery("span.sp-err-content",i).html(r);var a=jQuery("a.sp-post-link",i);o?a.attr("href",o):a.attr("href",a.attr("href").replace("__ID__",e)),a.text(t),s.after(i),i.css("display","block")}},confirmBulkAction:function(e,r){return!!confirm(_spTr["confirmBulk"+e])||(r.stopPropagation(),r.preventDefault(),!1)},checkRandomAnswer:function(e){var r=jQuery(e.target).val(),t=jQuery('input[name="random_answer"]').val(),o=jQuery('input[name="random_answer"]').data("target");r==t?(jQuery(o).removeClass("disabled").prop("disabled",!1),jQuery(o).removeAttr("aria-disabled")):jQuery(o).addClass("disabled").prop("disabled",!0)},removeBulkMsg:function(e){jQuery(e).parent().parent().remove()},isCustomImageId:function(e){return"C-"==e.substring(0,2)},recheckQuota:function(){var e=window.location.href.split("#");window.location.href=e[0]+(e[0].indexOf("?")>0?"&":"?")+"checkquota=1"+(void 0===e[1]?"":"#"+e[1])},openImageMenu:function(e){e.preventDefault(),this.menuCloseEvent||(jQuery(window).click(function(e){e.target.matches(".sp-dropbtn")||jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}),this.menuCloseEvent=!0);var r=e.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show"),r||e.target.parentElement.classList.add("sp-show")},menuCloseEvent:!1,loadComparer:function(e){this.comparerData.origUrl=!1,!1===this.comparerData.cssLoaded&&(jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"}),this.comparerData.cssLoaded=2),!1===this.comparerData.jsLoaded&&(jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2,ShortPixel.comparerData.origUrl.length>0&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}),this.comparerData.jsLoaded=1),!1===this.comparerData.origUrl&&(jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:e},success:function(e){data=JSON.parse(e),jQuery.extend(ShortPixel.comparerData,data),2==ShortPixel.comparerData.jsLoaded&&ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}),this.comparerData.origUrl="")},displayComparerPopup:function(e,r,t,o){var s=e,i=r<150||e<350,a=jQuery(i?"#spUploadCompareSideBySide":"#spUploadCompare"),l=jQuery(".sp-modal-shade");i||jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>'),e=Math.max(350,Math.min(800,e<350?2*(e+25):r<150?e+25:e)),r=Math.max(150,i?s>350?2*(r+45):r+45:r*e/s);var n="-"+Math.round(e/2);jQuery(".sp-modal-body",a).css("width",e),jQuery(".shortpixel-slider",a).css("width",e),a.css("width",e),a.css("marginLeft",n+"px"),jQuery(".sp-modal-body",a).css("height",r),a.show(),l.show(),i||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 u=jQuery(".spUploadCompareOptimized",a);jQuery(".spUploadCompareOriginal",a).attr("src",t),setTimeout(function(){jQuery(window).trigger("resize")},1e3),u.load(function(){jQuery(window).trigger("resize")}),u.attr("src",o)},closeComparerPopup:function(e){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")},convertPunycode:function(e){var r=document.createElement("a");return r.href=e,e.indexOf(r.protocol+"//"+r.hostname)<0?r.href:e.replace(r.protocol+"//"+r.hostname,r.protocol+"//"+r.hostname.split(".").map(function(e){return sp_punycode.toASCII(e)}).join("."))},checkExifWarning:function(){!jQuery('input[name="removeExif"]').is(":checked")&&jQuery('input[name="png2jpg"]').is(":checked")?jQuery(".exif_warning").fadeIn():jQuery(".exif_warning").fadeOut()},comparerData:{cssLoaded:!1,jsLoaded:!1,origUrl:!1,optUrl:!1,width:0,height:0},toRefresh:!1,resizeSizesAlert:!1,returnedStatusSearching:0}}();"function"!=typeof String.prototype.format&&(String.prototype.format=function(){for(var e=this,r=arguments.length;r--;)e=e.replace(new RegExp("\\{"+r+"\\}","gm"),arguments[r]);return e});
|
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
-
use ShortPixel\ShortPixelLogger as Log;
|
4 |
-
use ShortPixel\NoticeController as
|
5 |
|
6 |
|
7 |
/** Plugin class
|
@@ -11,7 +11,7 @@ use ShortPixel\NoticeController as Notice;
|
|
11 |
class ShortPixelPlugin
|
12 |
{
|
13 |
static $instance;
|
14 |
-
private $paths = array('class', 'class/controller', 'class/external');
|
15 |
|
16 |
protected $is_noheaders = false;
|
17 |
|
@@ -41,8 +41,8 @@ class ShortPixelPlugin
|
|
41 |
return self::$instance;
|
42 |
}
|
43 |
|
44 |
-
|
45 |
-
|
46 |
{
|
47 |
$plugin_path = plugin_dir_path(SHORTPIXEL_PLUGIN_FILE);
|
48 |
foreach($this->paths as $short_path)
|
@@ -55,7 +55,6 @@ class ShortPixelPlugin
|
|
55 |
foreach($it as $file)
|
56 |
{
|
57 |
$file_path = $file->getRealPath();
|
58 |
-
|
59 |
if ($file->isFile() && pathinfo($file_path, PATHINFO_EXTENSION) == 'php')
|
60 |
{
|
61 |
require_once($file_path);
|
@@ -63,6 +62,10 @@ class ShortPixelPlugin
|
|
63 |
}
|
64 |
}
|
65 |
}
|
|
|
|
|
|
|
|
|
66 |
}
|
67 |
|
68 |
/** Hooks for all WordPress related hooks
|
@@ -76,12 +79,19 @@ class ShortPixelPlugin
|
|
76 |
|
77 |
}
|
78 |
|
|
|
79 |
public function admin_pages()
|
80 |
{
|
81 |
// settings page
|
82 |
add_options_page( __('ShortPixel Settings','shortpixel-image-optimiser'), 'ShortPixel', 'manage_options', 'wp-shortpixel-settings', array($this, 'route'));
|
83 |
}
|
84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
/** All scripts should be registed, not enqueued here (unless global wp-admin is needed )
|
86 |
*
|
87 |
* Not all those registered must be enqueued however.
|
@@ -102,10 +112,17 @@ class ShortPixelPlugin
|
|
102 |
|
103 |
public function admin_notices()
|
104 |
{
|
105 |
-
$noticeControl =
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
|
107 |
if ($noticeControl->countNotices() > 0)
|
108 |
{
|
|
|
109 |
foreach($noticeControl->getNotices() as $notice)
|
110 |
{
|
111 |
echo $notice->getForDisplay();
|
@@ -135,13 +152,11 @@ class ShortPixelPlugin
|
|
135 |
if ($this->is_noheaders) // fail silently, if this is a no-headers request.
|
136 |
return;
|
137 |
|
138 |
-
|
139 |
if (wp_script_is($name, 'registered'))
|
140 |
{
|
141 |
wp_enqueue_script($name);
|
142 |
}
|
143 |
else {
|
144 |
-
|
145 |
Log::addWarn("Script $name was asked for, but not registered");
|
146 |
}
|
147 |
}
|
@@ -154,6 +169,9 @@ class ShortPixelPlugin
|
|
154 |
{
|
155 |
global $plugin_page;
|
156 |
global $shortPixelPluginInstance; //brrr @todo Find better solution for this some day.
|
|
|
|
|
|
|
157 |
$default_action = 'load'; // generic action on controller.
|
158 |
$action = isset($_REQUEST['sp-action']) ? sanitize_text_field($_REQUEST['sp-action']) : $default_action;
|
159 |
Log::addDebug('Request', $_REQUEST);
|
1 |
<?php
|
2 |
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
4 |
+
use ShortPixel\Notices\NoticeController as Notices;
|
5 |
|
6 |
|
7 |
/** Plugin class
|
11 |
class ShortPixelPlugin
|
12 |
{
|
13 |
static $instance;
|
14 |
+
private $paths = array('class', 'class/controller', 'class/external'); // classes that are autoloaded
|
15 |
|
16 |
protected $is_noheaders = false;
|
17 |
|
41 |
return self::$instance;
|
42 |
}
|
43 |
|
44 |
+
/** Init Runtime. Loads all classes. */
|
45 |
+
protected function initRuntime()
|
46 |
{
|
47 |
$plugin_path = plugin_dir_path(SHORTPIXEL_PLUGIN_FILE);
|
48 |
foreach($this->paths as $short_path)
|
55 |
foreach($it as $file)
|
56 |
{
|
57 |
$file_path = $file->getRealPath();
|
|
|
58 |
if ($file->isFile() && pathinfo($file_path, PATHINFO_EXTENSION) == 'php')
|
59 |
{
|
60 |
require_once($file_path);
|
62 |
}
|
63 |
}
|
64 |
}
|
65 |
+
|
66 |
+
// Loads all subclassed controllers. This is used for slug-based discovery of which controller to run
|
67 |
+
$controllerClass = \ShortPixelTools::namespaceit('ShortPixelController');
|
68 |
+
$controllerClass::init();
|
69 |
}
|
70 |
|
71 |
/** Hooks for all WordPress related hooks
|
79 |
|
80 |
}
|
81 |
|
82 |
+
/** Hook in our admin pages */
|
83 |
public function admin_pages()
|
84 |
{
|
85 |
// settings page
|
86 |
add_options_page( __('ShortPixel Settings','shortpixel-image-optimiser'), 'ShortPixel', 'manage_options', 'wp-shortpixel-settings', array($this, 'route'));
|
87 |
}
|
88 |
|
89 |
+
/** PluginRunTime. Items that should be initialized *only* when doing our pages and territory. */
|
90 |
+
protected function initPluginRunTime()
|
91 |
+
{
|
92 |
+
|
93 |
+
}
|
94 |
+
|
95 |
/** All scripts should be registed, not enqueued here (unless global wp-admin is needed )
|
96 |
*
|
97 |
* Not all those registered must be enqueued however.
|
112 |
|
113 |
public function admin_notices()
|
114 |
{
|
115 |
+
$noticeControl = Notices::getInstance();
|
116 |
+
$noticeControl->loadIcons(array(
|
117 |
+
'normal' => '<img class="short-pixel-notice-icon" src="' . plugins_url('res/img/robo-cool.png', SHORTPIXEL_PLUGIN_FILE) . '">',
|
118 |
+
'success' => '<img class="short-pixel-notice-icon" src="' . plugins_url('res/img/robo-cool.png', SHORTPIXEL_PLUGIN_FILE) . '">',
|
119 |
+
'warning' => '<img class="short-pixel-notice-icon" src="' . plugins_url('res/img/robo-scared.png', SHORTPIXEL_PLUGIN_FILE) . '">',
|
120 |
+
'error' => '<img class="short-pixel-notice-icon" src="' . plugins_url('res/img/robo-scared.png', SHORTPIXEL_PLUGIN_FILE) . '">',
|
121 |
+
));
|
122 |
|
123 |
if ($noticeControl->countNotices() > 0)
|
124 |
{
|
125 |
+
wp_enqueue_style('shortpixel-admin'); // queue on places when it's not our runtime.
|
126 |
foreach($noticeControl->getNotices() as $notice)
|
127 |
{
|
128 |
echo $notice->getForDisplay();
|
152 |
if ($this->is_noheaders) // fail silently, if this is a no-headers request.
|
153 |
return;
|
154 |
|
|
|
155 |
if (wp_script_is($name, 'registered'))
|
156 |
{
|
157 |
wp_enqueue_script($name);
|
158 |
}
|
159 |
else {
|
|
|
160 |
Log::addWarn("Script $name was asked for, but not registered");
|
161 |
}
|
162 |
}
|
169 |
{
|
170 |
global $plugin_page;
|
171 |
global $shortPixelPluginInstance; //brrr @todo Find better solution for this some day.
|
172 |
+
|
173 |
+
$this->initPluginRunTime();
|
174 |
+
|
175 |
$default_action = 'load'; // generic action on controller.
|
176 |
$action = isset($_REQUEST['sp-action']) ? sanitize_text_field($_REQUEST['sp-action']) : $default_action;
|
177 |
Log::addDebug('Request', $_REQUEST);
|
@@ -3,7 +3,7 @@ if ( !function_exists( 'download_url' ) ) {
|
|
3 |
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
4 |
}
|
5 |
|
6 |
-
use
|
7 |
|
8 |
class ShortPixelAPI {
|
9 |
|
@@ -16,6 +16,7 @@ class ShortPixelAPI {
|
|
16 |
const STATUS_NOT_FOUND = -5;
|
17 |
const STATUS_NO_KEY = -6;
|
18 |
const STATUS_RETRY = -7;
|
|
|
19 |
const STATUS_QUEUE_FULL = -404;
|
20 |
const STATUS_MAINTENANCE = -500;
|
21 |
|
@@ -111,7 +112,7 @@ class ShortPixelAPI {
|
|
111 |
}
|
112 |
|
113 |
// WpShortPixel::log("DO REQUESTS for META: " . json_encode($itemHandler->getRawMeta()) . " STACK: " . json_encode(debug_backtrace()));
|
114 |
-
$URLs = apply_filters('shortpixel_image_urls', $URLs, $itemHandler->getId()) ;
|
115 |
|
116 |
$requestParameters = array(
|
117 |
'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
|
@@ -839,7 +840,10 @@ class ShortPixelAPI {
|
|
839 |
$Separator = " qq ";
|
840 |
$qqPath = preg_replace("/[^ ]/u", $Separator."\$0".$Separator, $Path);
|
841 |
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
|
842 |
-
|
|
|
|
|
|
|
843 |
$pos = strpos($fileName, $suffix);
|
844 |
if($pos !== false) {
|
845 |
return substr($fileName, 0, $pos);
|
3 |
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
4 |
}
|
5 |
|
6 |
+
use ShortPixel\ShortpixelLogger\ShortPixelLogger as Log;
|
7 |
|
8 |
class ShortPixelAPI {
|
9 |
|
16 |
const STATUS_NOT_FOUND = -5;
|
17 |
const STATUS_NO_KEY = -6;
|
18 |
const STATUS_RETRY = -7;
|
19 |
+
const STATUS_SEARCHING = -8; // when the Queue is looping over images, but in batch none were found.
|
20 |
const STATUS_QUEUE_FULL = -404;
|
21 |
const STATUS_MAINTENANCE = -500;
|
22 |
|
112 |
}
|
113 |
|
114 |
// WpShortPixel::log("DO REQUESTS for META: " . json_encode($itemHandler->getRawMeta()) . " STACK: " . json_encode(debug_backtrace()));
|
115 |
+
$URLs = apply_filters('shortpixel_image_urls', $URLs, $itemHandler->getId()) ;
|
116 |
|
117 |
$requestParameters = array(
|
118 |
'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
|
840 |
$Separator = " qq ";
|
841 |
$qqPath = preg_replace("/[^ ]/u", $Separator."\$0".$Separator, $Path);
|
842 |
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
|
843 |
+
|
844 |
+
// This line is separated because of 'passed by reference' errors otherwise.
|
845 |
+
$pathAr = explode(DIRECTORY_SEPARATOR, $Path);
|
846 |
+
$fileName = end($pathAr);
|
847 |
$pos = strpos($fileName, $suffix);
|
848 |
if($pos !== false) {
|
849 |
return substr($fileName, 0, $pos);
|
@@ -8,14 +8,14 @@ if(defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG === true) {
|
|
8 |
|
9 |
// Debug. Hook as early as possible.
|
10 |
require_once('class/controller/controller.php');
|
11 |
-
require_once('class/controller/debug.php');
|
12 |
-
require_once('class/model/shortpixel-debug.php');
|
13 |
|
14 |
// @todo wp-shortpixel-settings which depends on this model should be called when needed; in the model/ directory. That will be some work, so for now here.
|
15 |
require_once('class/shortpixel-model.php');
|
16 |
|
17 |
-
use ShortPixel\DebugItem as DebugItem;
|
18 |
-
use ShortPixel\ShortPixelLogger as Log;
|
19 |
|
20 |
if (! defined('SHORTPIXEL_DEBUG'))
|
21 |
{
|
8 |
|
9 |
// Debug. Hook as early as possible.
|
10 |
require_once('class/controller/controller.php');
|
11 |
+
//require_once('class/controller/debug.php');
|
12 |
+
//require_once('class/model/shortpixel-debug.php');
|
13 |
|
14 |
// @todo wp-shortpixel-settings which depends on this model should be called when needed; in the model/ directory. That will be some work, so for now here.
|
15 |
require_once('class/shortpixel-model.php');
|
16 |
|
17 |
+
//use ShortPixel\DebugItem as DebugItem;
|
18 |
+
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
|
19 |
|
20 |
if (! defined('SHORTPIXEL_DEBUG'))
|
21 |
{
|
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: ShortPixel Image Optimizer
|
4 |
* Plugin URI: https://shortpixel.com/
|
5 |
* Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel-settings" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
-
* Version: 4.14.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
@@ -16,10 +16,11 @@ if (! defined('SHORTPIXEL_RESET_ON_ACTIVATE'))
|
|
16 |
//define('SHORTPIXEL_DEBUG_TARGET', true);
|
17 |
|
18 |
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
|
|
19 |
|
20 |
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
21 |
|
22 |
-
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.14.
|
23 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
24 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
25 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
@@ -33,9 +34,15 @@ if(!defined('SHORTPIXEL_MAX_THUMBS')) { //can be defined in wp-config.php
|
|
33 |
define('SHORTPIXEL_PRESEND_ITEMS', 3);
|
34 |
define('SHORTPIXEL_API', 'api.shortpixel.com');
|
35 |
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
-
require_once(ABSPATH . 'wp-admin/includes/file.php');
|
39 |
|
40 |
$sp__uploads = wp_upload_dir();
|
41 |
define('SHORTPIXEL_UPLOADS_BASE', (file_exists($sp__uploads['basedir']) ? '' : ABSPATH) . $sp__uploads['basedir'] );
|
@@ -59,6 +66,10 @@ else
|
|
59 |
define('SHORTPIXEL_MAX_EXECUTION_TIME2', 2 );
|
60 |
define("SHORTPIXEL_MAX_RESULTS_QUERY", 30);
|
61 |
|
|
|
|
|
|
|
|
|
62 |
function shortpixelInit() {
|
63 |
global $shortPixelPluginInstance;
|
64 |
//limit to certain admin pages if function available
|
@@ -88,9 +99,11 @@ function shortpixelInit() {
|
|
88 |
|
89 |
}
|
90 |
|
|
|
91 |
function shortPixelCheckQueue(){
|
92 |
require_once('class/shortpixel_queue.php');
|
93 |
-
|
|
|
94 |
return $prio && is_array($prio) && count($prio);
|
95 |
}
|
96 |
|
@@ -208,6 +221,12 @@ function shortPixelIsPluginActive($plugin) {
|
|
208 |
}
|
209 |
|
210 |
// [BS] Start runtime here
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
$option = get_option('wp-short-pixel-create-webp-markup');
|
212 |
if ( $option ) {
|
213 |
if(shortPixelIsPluginActive('shortpixel-adaptive-images/short-pixel-ai.php')) {
|
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-settings" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
+
* Version: 4.14.3
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
16 |
//define('SHORTPIXEL_DEBUG_TARGET', true);
|
17 |
|
18 |
define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
19 |
+
define('SHORTPIXEL_PLUGIN_DIR', __DIR__);
|
20 |
|
21 |
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
22 |
|
23 |
+
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.14.3");
|
24 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
25 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
26 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
34 |
define('SHORTPIXEL_PRESEND_ITEMS', 3);
|
35 |
define('SHORTPIXEL_API', 'api.shortpixel.com');
|
36 |
|
37 |
+
$max_exec = intval(ini_get('max_execution_time'));
|
38 |
+
if ($max_exec === 0) // max execution time of zero means infinite. Quantify.
|
39 |
+
$max_exec = 60;
|
40 |
+
define('SHORTPIXEL_MAX_EXECUTION_TIME', $max_exec);
|
41 |
+
|
42 |
+
// ** @todo For what is this needed? */
|
43 |
+
//require_once(ABSPATH . 'wp-admin/includes/file.php');
|
44 |
+
require_once(SHORTPIXEL_PLUGIN_DIR . '/build/shortpixel/autoload.php');
|
45 |
|
|
|
46 |
|
47 |
$sp__uploads = wp_upload_dir();
|
48 |
define('SHORTPIXEL_UPLOADS_BASE', (file_exists($sp__uploads['basedir']) ? '' : ABSPATH) . $sp__uploads['basedir'] );
|
66 |
define('SHORTPIXEL_MAX_EXECUTION_TIME2', 2 );
|
67 |
define("SHORTPIXEL_MAX_RESULTS_QUERY", 30);
|
68 |
|
69 |
+
/** @todo This is a test in progress var */
|
70 |
+
|
71 |
+
//define("SHORTPIXEL_NOFLOCK", true);
|
72 |
+
|
73 |
function shortpixelInit() {
|
74 |
global $shortPixelPluginInstance;
|
75 |
//limit to certain admin pages if function available
|
99 |
|
100 |
}
|
101 |
|
102 |
+
|
103 |
function shortPixelCheckQueue(){
|
104 |
require_once('class/shortpixel_queue.php');
|
105 |
+
require_once('class/external/shortpixel_queue_db.php');
|
106 |
+
$prio = (! defined('SHORTPIXEL_NOFLOCK')) ? ShortPixelQueue::get() : ShortPixelQueueDB::get();
|
107 |
return $prio && is_array($prio) && count($prio);
|
108 |
}
|
109 |
|
221 |
}
|
222 |
|
223 |
// [BS] Start runtime here
|
224 |
+
$log = ShortPixel\ShortPixelLogger\ShortPixelLogger::getInstance();
|
225 |
+
$log->setLogPath(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log");
|
226 |
+
|
227 |
+
// Pre-Runtime Checks
|
228 |
+
require_once('class/external/flywheel.php'); // check if SP runs on flywheel
|
229 |
+
|
230 |
$option = get_option('wp-short-pixel-create-webp-markup');
|
231 |
if ( $option ) {
|
232 |
if(shortPixelIsPluginActive('shortpixel-adaptive-images/short-pixel-ai.php')) {
|