Version Description
=
Release date: 17th June 2019 * Add new filters proposed by WP Stateless: shortpixel_backup_folder, shortpixel_image_exists, shortpixel_image_urls * Better placement of the elements on the Other Media page * Fix custom bulk for PDFs when the pdf thumbnails are not activated * Fix selecting items from DB twice for bulk in some circumstances * Warn user that converting PNG to JPG while keeping EXIF in options doesn't keep it (no EXIF for PNGs). * When SHORTPIXEL_DEBUG=x get parameter is provided, display a floating link to the shortpixel_log file * Adaptive Max execution time and capped to 90 sec. for the bulk background AJAX calls. (Kinsta has a max_execution_time of 300 sec. in PHP but the HTTP connection is cut after 180 sec.) * Fix custom 404 page for missing images not working when using .htaccess for WebP * Fix WebP picture tag with relative URLs not working in some circumstances * Fix replacing the inside an existing
Release Info
Developer | ShortPixel |
Plugin | ShortPixel Image Optimizer |
Version | 4.14.0 |
Comparing to | |
See all releases |
Code changes from version 4.13.1 to 4.14.0
- class/controller/bulk-restore-all.php +2 -0
- class/controller/controller.php +102 -15
- class/controller/debug.php +266 -0
- class/controller/notice.php +134 -0
- class/controller/settings.php +523 -0
- class/db/shortpixel-custom-meta-dao.php +21 -6
- class/db/shortpixel-meta-facade.php +30 -8
- class/db/wp-shortpixel-media-library-adapter.php +31 -32
- class/external/helpscout.php +128 -0
- class/external/nextgen.php +62 -0
- class/front/img-to-picture-webp.php +101 -13
- class/model/notice_model.php +87 -0
- class/model/shortpixel-debug.php +140 -0
- class/model/shortpixel-folder.php +51 -23
- class/model/shortpixel-image.php +32 -0
- class/shortpixel-model.php +149 -0
- class/shortpixel-tools.php +2 -1
- class/shortpixel_queue.php +65 -56
- class/view/settings/part-advanced.php +357 -0
- class/view/settings/part-cloudflare.php +66 -0
- class/view/settings/part-debug.php +40 -0
- class/view/settings/part-general.php +186 -0
- class/view/settings/part-nokey.php +129 -0
- class/view/settings/part-statistics.php +170 -0
- class/view/shortpixel-list-table.php +1 -1
- class/view/shortpixel_view.php +66 -28
- class/view/view-debug-box.php +44 -0
- class/view/view-restore-all.php +3 -0
- class/view/view-settings.php +59 -0
- class/wp-short-pixel.php +481 -141
- class/wp-shortpixel-settings.php +61 -26
- readme.txt +21 -2
- res/css/short-pixel-modal.min.css +1 -1
- res/css/short-pixel.css +3 -36
- res/css/short-pixel.min.css +1 -1
- res/css/shortpixel-admin.css +76 -0
- res/css/shortpixel-admin.min.css +1 -1
- res/css/sp-file-tree.min.css +1 -1
- res/img/notes-sp.png +0 -0
- res/img/notes-sp@2x.png +0 -0
- res/js/shortpixel.js +72 -25
- res/js/shortpixel.min.js +1 -1
- res/scss/shortpixel-admin.scss +4 -1
- res/scss/utils/_notices.scss +39 -0
- res/scss/view/_bulk_dashboard.scss +8 -0
- res/scss/view/_settings.scss +85 -0
- shortpixel-plugin.php +192 -0
- shortpixel_api.php +33 -12
- wp-shortpixel-req.php +44 -8
- wp-shortpixel.php +9 -5
@@ -64,6 +64,8 @@ class BulkRestoreAll extends ShortPixelController
|
|
64 |
|
65 |
public function setupBulk()
|
66 |
{
|
|
|
|
|
67 |
// handle the custom folders if there are any.
|
68 |
if (count($this->selected_folders) > 0)
|
69 |
{
|
64 |
|
65 |
public function setupBulk()
|
66 |
{
|
67 |
+
$this->checkPost(); // check if any POST vars are there ( which should be if custom restore is on )
|
68 |
+
|
69 |
// handle the custom folders if there are any.
|
70 |
if (count($this->selected_folders) > 0)
|
71 |
{
|
@@ -1,16 +1,22 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
namespace ShortPixel;
|
|
|
4 |
|
5 |
class ShortPixelController
|
6 |
{
|
7 |
protected static $controllers = array();
|
|
|
8 |
|
9 |
-
protected $
|
10 |
-
protected $postData = array(); // data coming from form posts.
|
11 |
-
protected $layout; // object to use in the view.
|
12 |
|
|
|
13 |
protected $template = null; // template name to include when loading.
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
public static function init()
|
16 |
{
|
@@ -20,10 +26,17 @@ class ShortPixelController
|
|
20 |
}
|
21 |
}
|
22 |
|
|
|
|
|
|
|
|
|
23 |
public static function findControllerbySlug($name)
|
24 |
{
|
25 |
foreach(self::$controllers as $className)
|
26 |
{
|
|
|
|
|
|
|
27 |
if ($className::$slug == $name)
|
28 |
{
|
29 |
return $className; // found!
|
@@ -33,9 +46,22 @@ class ShortPixelController
|
|
33 |
|
34 |
public function __construct()
|
35 |
{
|
36 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
if (isset($_POST) && count($_POST) > 0)
|
38 |
{
|
|
|
39 |
$this->processPostData($_POST);
|
40 |
}
|
41 |
}
|
@@ -47,37 +73,98 @@ class ShortPixelController
|
|
47 |
|
48 |
public function setShortPixel($pixel)
|
49 |
{
|
50 |
-
$this->shortPixel = $pixel;
|
51 |
}
|
52 |
|
53 |
-
|
|
|
|
|
|
|
|
|
54 |
{
|
55 |
-
if (
|
|
|
|
|
|
|
56 |
{
|
57 |
// error
|
58 |
return false;
|
59 |
}
|
|
|
|
|
60 |
|
61 |
-
$
|
62 |
$controller = $this;
|
63 |
|
64 |
-
$template_path = \ShortPixelTools::getPluginPath() . 'class/view/' . $
|
65 |
if (file_exists($template_path))
|
|
|
66 |
include($template_path);
|
|
|
|
|
|
|
|
|
|
|
67 |
|
68 |
}
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
protected function processPostData($post)
|
71 |
{
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
{
|
75 |
-
|
|
|
|
|
|
|
|
|
76 |
}
|
77 |
-
}
|
78 |
|
|
|
|
|
79 |
|
|
|
80 |
|
|
|
81 |
|
|
|
|
|
|
|
|
|
82 |
|
83 |
-
}
|
1 |
<?php
|
|
|
2 |
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortPixelLogger as Log;
|
4 |
|
5 |
class ShortPixelController
|
6 |
{
|
7 |
protected static $controllers = array();
|
8 |
+
protected static $modelsLoaded = array(); // don't require twice, limit amount of require looksups..
|
9 |
|
10 |
+
protected $shortPixel;
|
|
|
|
|
11 |
|
12 |
+
protected $model;
|
13 |
protected $template = null; // template name to include when loading.
|
14 |
+
protected $data = array(); // data array for usage with databases data and such
|
15 |
+
protected $postData = array(); // data coming from form posts.
|
16 |
+
protected $mapper; // Mapper is array of View Name => Model Name. Convert between the two
|
17 |
+
protected $is_form_submit = false;
|
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 |
{
|
26 |
}
|
27 |
}
|
28 |
|
29 |
+
/* Static function to use for finding a associated controller within the WP page ecosystem
|
30 |
+
*
|
31 |
+
* e.g. My page path in Wp-admin is bulk-restore-all, it can autofind needed controller ( and view )
|
32 |
+
*/
|
33 |
public static function findControllerbySlug($name)
|
34 |
{
|
35 |
foreach(self::$controllers as $className)
|
36 |
{
|
37 |
+
if (! isset($className::$slug)) // controllers not connected by slugs
|
38 |
+
continue;
|
39 |
+
|
40 |
if ($className::$slug == $name)
|
41 |
{
|
42 |
return $className; // found!
|
46 |
|
47 |
public function __construct()
|
48 |
{
|
49 |
+
$this->view = new \stdClass;
|
50 |
+
// Basic View Construct
|
51 |
+
$this->view->notices = null; // Notices of class notice, for everything noticable
|
52 |
+
$this->view->data = null; // Data(base), to separate from regular view data
|
53 |
+
|
54 |
+
|
55 |
+
}
|
56 |
+
|
57 |
+
/* Check if postData has been submitted.
|
58 |
+
* This function should always be called at any ACTION function ( load, load_$action etc ).
|
59 |
+
*/
|
60 |
+
protected function checkPost()
|
61 |
+
{
|
62 |
if (isset($_POST) && count($_POST) > 0)
|
63 |
{
|
64 |
+
$this->is_form_submit = true;
|
65 |
$this->processPostData($_POST);
|
66 |
}
|
67 |
}
|
73 |
|
74 |
public function setShortPixel($pixel)
|
75 |
{
|
76 |
+
$this->shortPixel = $pixel; // notice the capital, case-sensitive!
|
77 |
}
|
78 |
|
79 |
+
/** Loads a view
|
80 |
+
*
|
81 |
+
*
|
82 |
+
*/
|
83 |
+
public function loadView($template = null)
|
84 |
{
|
85 |
+
if (strlen(trim($template)) == 0)
|
86 |
+
$template = null;
|
87 |
+
|
88 |
+
if (is_null($this->template) && is_null($template))
|
89 |
{
|
90 |
// error
|
91 |
return false;
|
92 |
}
|
93 |
+
// load either param or class template.
|
94 |
+
$template = (is_null($template)) ? $this->template : $template;
|
95 |
|
96 |
+
$view = $this->view;
|
97 |
$controller = $this;
|
98 |
|
99 |
+
$template_path = \ShortPixelTools::getPluginPath() . 'class/view/' . $template . '.php';
|
100 |
if (file_exists($template_path))
|
101 |
+
{
|
102 |
include($template_path);
|
103 |
+
}
|
104 |
+
else {
|
105 |
+
Log::addError("View $template could not be found in " . $template_path,
|
106 |
+
array('class' => get_class($this), 'req' => $_REQUEST));
|
107 |
+
}
|
108 |
|
109 |
}
|
110 |
|
111 |
+
/** Loads the Model Data Structure upon request
|
112 |
+
*
|
113 |
+
* @param string $name Name of the model
|
114 |
+
*/
|
115 |
+
protected function loadModel($name){
|
116 |
+
$path = \ShortPixelTools::getPluginPath() . 'class/model/' . $name . '_model.php';
|
117 |
+
|
118 |
+
if (! in_array($name, self::$modelsLoaded))
|
119 |
+
{
|
120 |
+
self::$modelsLoaded[] = $name;
|
121 |
+
if(file_exists($path)){
|
122 |
+
require_once($path);
|
123 |
+
}
|
124 |
+
else {
|
125 |
+
Log::addError('Model $name could not be found');
|
126 |
+
}
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
/** Accepts POST data, maps, checks missing fields, and applies sanitization to it.
|
131 |
+
* @param array $post POST data
|
132 |
+
*/
|
133 |
protected function processPostData($post)
|
134 |
{
|
135 |
+
|
136 |
+
// If there is something to map, map.
|
137 |
+
if ($this->mapper && is_array($this->mapper) && count($this->mapper) > 0)
|
138 |
+
{
|
139 |
+
foreach($this->mapper as $item => $replace)
|
140 |
+
{
|
141 |
+
if ( isset($post[$item]))
|
142 |
+
{
|
143 |
+
$post[$replace] = $post[$item];
|
144 |
+
unset($post[$item]);
|
145 |
+
}
|
146 |
+
}
|
147 |
+
}
|
148 |
+
|
149 |
+
if (is_null($this->model))
|
150 |
{
|
151 |
+
foreach($post as $name => $value )
|
152 |
+
{
|
153 |
+
$this->postData[sanitize_text_field($name)] = sanitize_text_field($value);
|
154 |
+
return true;
|
155 |
+
}
|
156 |
}
|
|
|
157 |
|
158 |
+
$model = $this->model;
|
159 |
+
$this->postData = $model->getSanitizedData($post);
|
160 |
|
161 |
+
return $this->postData;
|
162 |
|
163 |
+
}
|
164 |
|
165 |
+
public function setControllerURL($url)
|
166 |
+
{
|
167 |
+
$this->url = $url;
|
168 |
+
}
|
169 |
|
170 |
+
} // controller
|
@@ -0,0 +1,266 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
|
4 |
+
/*** Logger class
|
5 |
+
*
|
6 |
+
* Class uses the debug data model for keeping log entries.
|
7 |
+
*/
|
8 |
+
class ShortPixelLogger extends shortPixelController
|
9 |
+
{
|
10 |
+
static protected $instance = null;
|
11 |
+
protected $start_time;
|
12 |
+
|
13 |
+
protected $is_active = false;
|
14 |
+
protected $is_manual_request = false;
|
15 |
+
protected $show_debug_view = false;
|
16 |
+
|
17 |
+
protected $items = array();
|
18 |
+
protected $logPath = false;
|
19 |
+
protected $logMode = FILE_APPEND;
|
20 |
+
|
21 |
+
protected $logLevel;
|
22 |
+
protected $format = "[ %%time%% ] %%color%% %%level%% %%color_end%% \t %%message%% \t %%caller%% ( %%time_passed%% )";
|
23 |
+
protected $format_data = "\t %%data%% ";
|
24 |
+
|
25 |
+
/* protected $hooks = array(
|
26 |
+
'shortpixel_image_exists' => array('numargs' => 3),
|
27 |
+
'shortpixel_webp_image_base' => array('numargs' => 2),
|
28 |
+
'shortpixel_image_urls' => array('numargs' => 2),
|
29 |
+
); // @todo monitor hooks, but this should be more dynamic. Do when moving to module via config.
|
30 |
+
*/
|
31 |
+
protected $hooks = array();
|
32 |
+
|
33 |
+
protected $template = 'view-debug-box';
|
34 |
+
|
35 |
+
/** Debugger constructor
|
36 |
+
* 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
|
37 |
+
* 2) Put SHORTPIXEL_DEBUG in the request. Either true or number.
|
38 |
+
*/
|
39 |
+
public function __construct()
|
40 |
+
{
|
41 |
+
$this->start_time = microtime(true);
|
42 |
+
$this->logLevel = DebugItem::LEVEL_WARN;
|
43 |
+
|
44 |
+
if (isset($_REQUEST['SHORTPIXEL_DEBUG'])) // manual takes precedence over constants
|
45 |
+
{
|
46 |
+
$this->is_manual_request = true;
|
47 |
+
$this->is_active = true;
|
48 |
+
|
49 |
+
if ($_REQUEST['SHORTPIXEL_DEBUG'] === 'true')
|
50 |
+
{
|
51 |
+
$this->logLevel = DebugItem::LEVEL_INFO;
|
52 |
+
}
|
53 |
+
else {
|
54 |
+
$this->logLevel = intval($_REQUEST['SHORTPIXEL_DEBUG']);
|
55 |
+
}
|
56 |
+
|
57 |
+
}
|
58 |
+
else if ( (defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG > 0) )
|
59 |
+
{
|
60 |
+
$this->is_active = true;
|
61 |
+
if (SHORTPIXEL_DEBUG === true)
|
62 |
+
$this->logLevel = DebugItem::LEVEL_INFO;
|
63 |
+
else {
|
64 |
+
$this->logLevel = intval(SHORTPIXEL_DEBUG);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
if (defined('SHORTPIXEL_DEBUG_TARGET') && SHORTPIXEL_DEBUG_TARGET || $this->is_manual_request)
|
69 |
+
{
|
70 |
+
$this->logPath = SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log";
|
71 |
+
//$this->logMode = defined('SHORTPIXEL_LOG_OVERWRITE') ? 0 : FILE_APPEND;
|
72 |
+
if (defined('SHORTPIXEL_LOG_OVERWRITE')) // if overwrite, do this on init once.
|
73 |
+
file_put_contents($this->logPath,'-- Log Reset -- ' .PHP_EOL);
|
74 |
+
|
75 |
+
}
|
76 |
+
|
77 |
+
$user_is_administrator = (current_user_can('manage_options')) ? true : false;
|
78 |
+
|
79 |
+
if ($this->is_active && $this->is_manual_request && $user_is_administrator )
|
80 |
+
{
|
81 |
+
$this->layout = new \stdClass;
|
82 |
+
$this->layout->logLink = SHORTPIXEL_BACKUP_URL . "/shortpixel_log";
|
83 |
+
|
84 |
+
add_action('admin_footer', array($this, 'loadView'));
|
85 |
+
}
|
86 |
+
|
87 |
+
if ($this->is_active && count($this->hooks) > 0)
|
88 |
+
$this->monitorHooks();
|
89 |
+
}
|
90 |
+
|
91 |
+
public static function getInstance()
|
92 |
+
{
|
93 |
+
if ( self::$instance === null)
|
94 |
+
{
|
95 |
+
self::$instance = new ShortPixelLogger();
|
96 |
+
}
|
97 |
+
return self::$instance;
|
98 |
+
}
|
99 |
+
|
100 |
+
protected static function addLog($message, $level, $data = array())
|
101 |
+
{
|
102 |
+
$log = self::getInstance();
|
103 |
+
|
104 |
+
// don't log anything too low.
|
105 |
+
if ($log->logLevel < $level)
|
106 |
+
{
|
107 |
+
return;
|
108 |
+
}
|
109 |
+
|
110 |
+
$arg = array();
|
111 |
+
$args['level'] = $level;
|
112 |
+
$args['data'] = $data;
|
113 |
+
|
114 |
+
$newItem = new \ShortPixel\DebugItem($message, $args);
|
115 |
+
$log->items[] = $newItem;
|
116 |
+
|
117 |
+
if ($log->is_active)
|
118 |
+
{
|
119 |
+
$log->write($newItem);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
/** Writes to log File. */
|
124 |
+
protected function write($debugItem, $mode = 'file')
|
125 |
+
{
|
126 |
+
$items = $debugItem->getForFormat();
|
127 |
+
$items['time_passed'] = round ( ($items['time'] - $this->start_time), 5);
|
128 |
+
$items['time'] = date('Y-m-d H:i:s', $items['time'] );
|
129 |
+
|
130 |
+
if ( ($items['caller']) && is_array($items['caller']) && count($items['caller']) > 0)
|
131 |
+
{
|
132 |
+
$caller = $items['caller'];
|
133 |
+
$items['caller'] = $caller['file'] . ' in ' . $caller['function'] . '(' . $caller['line'] . ')';
|
134 |
+
}
|
135 |
+
|
136 |
+
$line = $this->formatLine($items);
|
137 |
+
|
138 |
+
if ($this->logPath)
|
139 |
+
{
|
140 |
+
file_put_contents($this->logPath,$line, FILE_APPEND);
|
141 |
+
}
|
142 |
+
else {
|
143 |
+
error_log($line);
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
protected function formatLine($args = array() )
|
148 |
+
{
|
149 |
+
$line= $this->format;
|
150 |
+
foreach($args as $key => $value)
|
151 |
+
{
|
152 |
+
if (! is_array($value) && ! is_object($value))
|
153 |
+
$line = str_replace('%%' . $key . '%%', $value, $line);
|
154 |
+
}
|
155 |
+
|
156 |
+
$line .= PHP_EOL;
|
157 |
+
|
158 |
+
if (isset($args['data']))
|
159 |
+
{
|
160 |
+
$data = array_filter($args['data']);
|
161 |
+
if (count($data) > 0)
|
162 |
+
{
|
163 |
+
foreach($data as $item)
|
164 |
+
{
|
165 |
+
$line .= $item . PHP_EOL;
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
return $line;
|
171 |
+
}
|
172 |
+
|
173 |
+
protected function setLogLevel($level)
|
174 |
+
{
|
175 |
+
$this->logLevel = $level;
|
176 |
+
}
|
177 |
+
|
178 |
+
protected function getEnv($name)
|
179 |
+
{
|
180 |
+
if (isset($this->{$name}))
|
181 |
+
{
|
182 |
+
return $this->{$name};
|
183 |
+
}
|
184 |
+
else {
|
185 |
+
return false;
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
public static function addError($message, $args = array())
|
190 |
+
{
|
191 |
+
$level = DebugItem::LEVEL_ERROR;
|
192 |
+
static::addLog($message, $level, $args);
|
193 |
+
}
|
194 |
+
public static function addWarn($message, $args = array())
|
195 |
+
{
|
196 |
+
$level = DebugItem::LEVEL_WARN;
|
197 |
+
static::addLog($message, $level, $args);
|
198 |
+
}
|
199 |
+
public static function addInfo($message, $args = array())
|
200 |
+
{
|
201 |
+
$level = DebugItem::LEVEL_INFO;
|
202 |
+
static::addLog($message, $level, $args);
|
203 |
+
}
|
204 |
+
public static function addDebug($message, $args = array())
|
205 |
+
{
|
206 |
+
$level = DebugItem::LEVEL_DEBUG;
|
207 |
+
static::addLog($message, $level, $args);
|
208 |
+
}
|
209 |
+
|
210 |
+
public static function logLevel($level)
|
211 |
+
{
|
212 |
+
$log = self::getInstance();
|
213 |
+
static::addInfo('Changing Log level' . $level);
|
214 |
+
$log->setLogLevel($level);
|
215 |
+
}
|
216 |
+
|
217 |
+
public static function getLogLevel()
|
218 |
+
{
|
219 |
+
$log = self::getInstance();
|
220 |
+
return $log->getEnv('logLevel');
|
221 |
+
}
|
222 |
+
|
223 |
+
public static function isManualDebug()
|
224 |
+
{
|
225 |
+
$log = self::getInstance();
|
226 |
+
return $log->getEnv('is_manual_request');
|
227 |
+
}
|
228 |
+
|
229 |
+
public static function getLogPath()
|
230 |
+
{
|
231 |
+
$log = self::getInstance();
|
232 |
+
return $log->getEnv('logPath');
|
233 |
+
}
|
234 |
+
|
235 |
+
/** Function to test if the debugger is active
|
236 |
+
* @return boolean true when active.
|
237 |
+
*/
|
238 |
+
public static function debugIsActive()
|
239 |
+
{
|
240 |
+
$log = self::getInstance();
|
241 |
+
return $log->getEnv('is_active');
|
242 |
+
}
|
243 |
+
|
244 |
+
protected function monitorHooks()
|
245 |
+
{
|
246 |
+
|
247 |
+
foreach($this->hooks as $hook => $data)
|
248 |
+
{
|
249 |
+
$numargs = isset($data['numargs']) ? $data['numargs'] : 1;
|
250 |
+
$prio = isset($data['priority']) ? $data['priority'] : 10;
|
251 |
+
|
252 |
+
add_filter($hook, function($value) use ($hook) {
|
253 |
+
$args = func_get_args();
|
254 |
+
return $this->logHook($hook, $value, $args); }, $prio, $numargs);
|
255 |
+
}
|
256 |
+
}
|
257 |
+
|
258 |
+
public function logHook($hook, $value, $args)
|
259 |
+
{
|
260 |
+
array_shift($args);
|
261 |
+
self::addInfo('[Hook] - ' . $hook . ' with ' . var_export($value,true), $args);
|
262 |
+
return $value;
|
263 |
+
}
|
264 |
+
|
265 |
+
|
266 |
+
} // class debugController
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
class NoticeController extends ShortPixelController
|
6 |
+
{
|
7 |
+
protected static $notices;
|
8 |
+
protected static $instance = null;
|
9 |
+
public $notice_count = 0;
|
10 |
+
|
11 |
+
protected $has_stored = false;
|
12 |
+
|
13 |
+
public function __construct()
|
14 |
+
{
|
15 |
+
$this->loadModel('notice');
|
16 |
+
$this->loadNotices();
|
17 |
+
}
|
18 |
+
|
19 |
+
|
20 |
+
protected function loadNotices()
|
21 |
+
{
|
22 |
+
$notices = get_option('shortpixel-notices', false);
|
23 |
+
$cnotice = (is_array($notices)) ? count($notices) : 0;
|
24 |
+
Log::addDebug('Notice Control - #num notices' . $cnotice);
|
25 |
+
if ($notices !== false)
|
26 |
+
{
|
27 |
+
self::$notices = $notices;
|
28 |
+
$this->has_stored = true;
|
29 |
+
}
|
30 |
+
else {
|
31 |
+
self::$notices = array();
|
32 |
+
$this->has_stored = false;
|
33 |
+
}
|
34 |
+
$this->countNotices();
|
35 |
+
}
|
36 |
+
|
37 |
+
public function addNotice($message, $code)
|
38 |
+
{
|
39 |
+
$notice = new NoticeModel($message, $code);
|
40 |
+
self::$notices[] = $notice;
|
41 |
+
$this->countNotices();
|
42 |
+
Log::addDebug('Adding notice - ', $notice);
|
43 |
+
$this->update();
|
44 |
+
return $notice;
|
45 |
+
}
|
46 |
+
|
47 |
+
/** Update the notices to store, check what to remove, returns count. */
|
48 |
+
public function update()
|
49 |
+
{
|
50 |
+
if (! is_array(self::$notices) || count(self::$notices) == 0)
|
51 |
+
{
|
52 |
+
if ($this->has_stored)
|
53 |
+
delete_option('shortpixel-notices');
|
54 |
+
|
55 |
+
return 0;
|
56 |
+
}
|
57 |
+
|
58 |
+
$new_notices = array();
|
59 |
+
foreach(self::$notices as $item)
|
60 |
+
{
|
61 |
+
if (! $item->isDone() )
|
62 |
+
{
|
63 |
+
$new_notices[] = $item;
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
update_option('shortpixel-notices', $new_notices);
|
68 |
+
self::$notices = $new_notices;
|
69 |
+
|
70 |
+
return $this->countNotices();
|
71 |
+
}
|
72 |
+
|
73 |
+
public function countNotices()
|
74 |
+
{
|
75 |
+
$this->notice_count = count(self::$notices);
|
76 |
+
return $this->notice_count;
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
public function getNotices()
|
81 |
+
{
|
82 |
+
return self::$notices;
|
83 |
+
}
|
84 |
+
|
85 |
+
public static function getInstance()
|
86 |
+
{
|
87 |
+
if ( self::$instance === null)
|
88 |
+
{
|
89 |
+
self::$instance = new NoticeController();
|
90 |
+
}
|
91 |
+
|
92 |
+
return self::$instance;
|
93 |
+
}
|
94 |
+
|
95 |
+
/** Adds a notice, quick and fast method
|
96 |
+
* @param String $message The Message you want to notify
|
97 |
+
* @param int $code A value of messageType as defined in model
|
98 |
+
* @returm Object Instance of noticeModel
|
99 |
+
*/
|
100 |
+
|
101 |
+
public static function addNormal($message)
|
102 |
+
{
|
103 |
+
$noticeController = self::getInstance();
|
104 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_NORMAL);
|
105 |
+
return $notice;
|
106 |
+
|
107 |
+
}
|
108 |
+
|
109 |
+
public static function addError($message)
|
110 |
+
{
|
111 |
+
$noticeController = self::getInstance();
|
112 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_ERROR);
|
113 |
+
return $notice;
|
114 |
+
|
115 |
+
}
|
116 |
+
|
117 |
+
public static function addWarning($message)
|
118 |
+
{
|
119 |
+
$noticeController = self::getInstance();
|
120 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_WARNING);
|
121 |
+
return $notice;
|
122 |
+
|
123 |
+
}
|
124 |
+
|
125 |
+
public static function addSuccess($message)
|
126 |
+
{
|
127 |
+
$noticeController = self::getInstance();
|
128 |
+
$notice = $noticeController->addNotice($message, NoticeModel::NOTICE_SUCCESS);
|
129 |
+
return $notice;
|
130 |
+
|
131 |
+
}
|
132 |
+
|
133 |
+
|
134 |
+
}
|
@@ -0,0 +1,523 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortPixelLogger as Log;
|
4 |
+
use ShortPixel\DebugItem as DebugItem;
|
5 |
+
use ShortPixel\NoticeController as Notice;
|
6 |
+
|
7 |
+
|
8 |
+
class SettingsController extends shortPixelController
|
9 |
+
{
|
10 |
+
|
11 |
+
//env
|
12 |
+
protected $is_nginx;
|
13 |
+
protected $is_verifiedkey;
|
14 |
+
protected $is_htaccess_writable;
|
15 |
+
protected $is_multisite;
|
16 |
+
protected $is_mainsite;
|
17 |
+
protected $is_constant_key;
|
18 |
+
protected $hide_api_key;
|
19 |
+
protected $has_nextgen;
|
20 |
+
protected $do_redirect = false;
|
21 |
+
protected $postkey_needs_validation = false;
|
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
|
43 |
+
public function load()
|
44 |
+
{
|
45 |
+
$this->loadEnv();
|
46 |
+
$this->checkPost(); // sets up post data
|
47 |
+
|
48 |
+
$this->model->redirectedSettings = 2; // not sure what this does.
|
49 |
+
$this->checkKey(); // needs post data
|
50 |
+
|
51 |
+
|
52 |
+
if ($this->is_form_submit)
|
53 |
+
{
|
54 |
+
$this->processSave();
|
55 |
+
}
|
56 |
+
|
57 |
+
$this->load_settings();
|
58 |
+
}
|
59 |
+
|
60 |
+
// this is the nokey form, submitting api key
|
61 |
+
public function action_addkey()
|
62 |
+
{
|
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->checkKey();
|
70 |
+
if (isset($this->postData['verifiedKey']) && $this->postData['verifiedKey'])
|
71 |
+
{
|
72 |
+
$this->model->apiKey = $this->postData['apiKey'];
|
73 |
+
$this->model->verifiedKey = $this->postData['verifiedKey'];
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
$this->doRedirect();
|
78 |
+
//exit();
|
79 |
+
|
80 |
+
}
|
81 |
+
|
82 |
+
public function processSave()
|
83 |
+
{
|
84 |
+
Log::addDebug('after process postData', $this->postData);
|
85 |
+
// Split this in the several screens. I.e. settings, advanced, Key Request IF etc.
|
86 |
+
|
87 |
+
if ($this->postData['includeNextGen'] == 1)
|
88 |
+
{
|
89 |
+
$nextgen = new NextGen($this->shortPixel);
|
90 |
+
$previous = $this->model->includeNextGen;
|
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');
|
103 |
+
else {
|
104 |
+
$this->doRedirect();
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
/* Loads the view data and the view */
|
109 |
+
public function load_settings()
|
110 |
+
{
|
111 |
+
$this->loadQuotaData();
|
112 |
+
$this->view->data = (Object) $this->model->getData();
|
113 |
+
if (($this->is_constant_key))
|
114 |
+
$this->view->data->apiKey = SHORTPIXEL_API_KEY;
|
115 |
+
|
116 |
+
$this->view->minSizes = $this->getMaxIntermediateImageSize();
|
117 |
+
$this->view->customFolders= $this->loadCustomFolders();
|
118 |
+
$this->view->allThumbSizes = $this->shortPixel->getAllThumbnailSizes();
|
119 |
+
$this->view->averageCompression = $this->shortPixel->getAverageCompression();
|
120 |
+
$this->view->savedBandwidth = \WpShortPixel::formatBytes($this->view->data->savedSpace * 10000,2);
|
121 |
+
$this->view->resources = wp_remote_post($this->model->httpProto . "://shortpixel.com/resources-frag");
|
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 |
+
public function loadEnv()
|
130 |
+
{
|
131 |
+
$this->is_nginx = strpos($_SERVER["SERVER_SOFTWARE"], 'nginx') !== false ? true : false;
|
132 |
+
$this->is_gd_installed = function_exists('imagecreatefrompng');
|
133 |
+
$this->is_curl_installed = function_exists('curl_init');
|
134 |
+
|
135 |
+
$this->is_htaccess_writable = $this->HTisWritable();
|
136 |
+
|
137 |
+
$this->is_multisite = (function_exists("is_multisite") && is_multisite()) ? true : false;
|
138 |
+
$this->is_mainsite = is_main_site();
|
139 |
+
|
140 |
+
$this->has_nextgen = \ShortPixelNextGenAdapter::hasNextGen();
|
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 |
+
$this->is_constant_key = (defined("SHORTPIXEL_API_KEY")) ? true : false;
|
149 |
+
$this->hide_api_key = (defined("SHORTPIXEL_HIDE_API_KEY")) ? SHORTPIXEL_HIDE_API_KEY : false;
|
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 |
+
//Log::addDebug()
|
157 |
+
if($this->is_constant_key)
|
158 |
+
{
|
159 |
+
if (strlen(SHORTPIXEL_API_KEY) <> 20)
|
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 |
+
$key = isset($this->postData['apiKey']) ? $this->postData['apiKey'] : $this->model->apiKey;
|
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
|
187 |
+
if ($this->is_form_submit)
|
188 |
+
{
|
189 |
+
if (strlen($this->postData['siteAuthUser']) > 0 || strlen($this->postData['siteAuthPass']) > 0)
|
190 |
+
{
|
191 |
+
$this->model->siteAuthUser = $this->postData['siteAuthUser'];
|
192 |
+
$this->model->siteAuthPass = $this->postData['siteAuthPass'];
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
$this->quotaData = $this->shortPixel->getQuotaInformation($key, true, 'validate', $this->postData);
|
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 |
+
$this->postData['verifiedKey'] = $this->is_verifiedkey;
|
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.
|
255 |
+
* @todo Should be replaced when File / Folder model are complete. Function check should go there.
|
256 |
+
*/
|
257 |
+
private function HTisWritable()
|
258 |
+
{
|
259 |
+
if ($this->is_nginx)
|
260 |
+
return false;
|
261 |
+
|
262 |
+
if (file_exists(get_home_path() . 'htaccess') && is_writable(get_home_path() . 'htaccess'))
|
263 |
+
{
|
264 |
+
return true;
|
265 |
+
}
|
266 |
+
if (file_exists(get_home_path()) && is_writable(get_home_path()))
|
267 |
+
{
|
268 |
+
return true;
|
269 |
+
}
|
270 |
+
return false;
|
271 |
+
// (is_writable(get_home_path() . 'htaccess')) ? true : false;
|
272 |
+
}
|
273 |
+
|
274 |
+
protected function getMaxIntermediateImageSize() {
|
275 |
+
global $_wp_additional_image_sizes;
|
276 |
+
|
277 |
+
$width = 0;
|
278 |
+
$height = 0;
|
279 |
+
$get_intermediate_image_sizes = get_intermediate_image_sizes();
|
280 |
+
|
281 |
+
// Create the full array with sizes and crop info
|
282 |
+
if(is_array($get_intermediate_image_sizes)) foreach( $get_intermediate_image_sizes as $_size ) {
|
283 |
+
if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
|
284 |
+
$width = max($width, get_option( $_size . '_size_w' ));
|
285 |
+
$height = max($height, get_option( $_size . '_size_h' ));
|
286 |
+
//$sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
|
287 |
+
} elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
|
288 |
+
$width = max($width, $_wp_additional_image_sizes[ $_size ]['width']);
|
289 |
+
$height = max($height, $_wp_additional_image_sizes[ $_size ]['height']);
|
290 |
+
//'crop' => $_wp_additional_image_sizes[ $_size ]['crop']
|
291 |
+
}
|
292 |
+
}
|
293 |
+
return array('width' => max(100, $width), 'height' => max(100, $height));
|
294 |
+
}
|
295 |
+
|
296 |
+
protected function loadQuotaData()
|
297 |
+
{
|
298 |
+
// @todo Probably good idea to put this in a 2-5 min transient or so.
|
299 |
+
if (is_null($this->quotaData))
|
300 |
+
$this->quotaData = $this->shortPixel->checkQuotaAndAlert();
|
301 |
+
|
302 |
+
$quotaData = $this->quotaData;
|
303 |
+
$this->view->thumbnailsToProcess = isset($quotaData['totalFiles']) ? ($quotaData['totalFiles'] - $quotaData['mainFiles']) - ($quotaData['totalProcessedFiles'] - $quotaData['mainProcessedFiles']) : 0;
|
304 |
+
|
305 |
+
$remainingImages = $quotaData['APICallsRemaining'];
|
306 |
+
$remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
|
307 |
+
$this->view->remainingImages = $remainingImages;
|
308 |
+
|
309 |
+
$this->view->totalCallsMade = array( 'plan' => $quotaData['APICallsMadeNumeric'] , 'oneTime' => $quotaData['APICallsMadeOneTimeNumeric'] );
|
310 |
+
|
311 |
+
}
|
312 |
+
|
313 |
+
protected function loadCustomFolders()
|
314 |
+
{
|
315 |
+
$notice = null;
|
316 |
+
$customFolders = $this->shortPixel->refreshCustomFolders($notice);
|
317 |
+
|
318 |
+
if (! is_null($notice))
|
319 |
+
{
|
320 |
+
$message = $notice['msg'];
|
321 |
+
if ($notice['status'] == 'error')
|
322 |
+
Notice::addError($message);
|
323 |
+
else
|
324 |
+
Notice::addNormal($message);
|
325 |
+
|
326 |
+
|
327 |
+
}
|
328 |
+
|
329 |
+
if ($this->has_nextgen)
|
330 |
+
{
|
331 |
+
$ngg = array_map(array('ShortPixelNextGenAdapter','pathToAbsolute'), \ShortPixelNextGenAdapter::getGalleries());
|
332 |
+
for($i = 0; $i < count($customFolders); $i++) {
|
333 |
+
if(in_array($customFolders[$i]->getPath(), $ngg )) {
|
334 |
+
$customFolders[$i]->setType("NextGen");
|
335 |
+
}
|
336 |
+
}
|
337 |
+
}
|
338 |
+
return $customFolders;
|
339 |
+
}
|
340 |
+
|
341 |
+
// This is done before handing it off to the parent controller, to sanitize and check against model.
|
342 |
+
protected function processPostData($post)
|
343 |
+
{
|
344 |
+
Log::addDebug('raw post data', $post);
|
345 |
+
|
346 |
+
if (isset($post['display_part']) && strlen($post['display_part']) > 0)
|
347 |
+
{
|
348 |
+
$this->display_part = sanitize_text_field($post['display_part']);
|
349 |
+
}
|
350 |
+
unset($post['display_part']);
|
351 |
+
|
352 |
+
// analyse the save button
|
353 |
+
if (isset($post['save_bulk']))
|
354 |
+
{
|
355 |
+
$this->do_redirect = true;
|
356 |
+
}
|
357 |
+
unset($post['save_bulk']);
|
358 |
+
unset($post['save']);
|
359 |
+
|
360 |
+
// handle 'reverse' checkbox.
|
361 |
+
$keepExif = isset($post['removeExif']) ? 0 : 1;
|
362 |
+
$post['keepExif'] = $keepExif;
|
363 |
+
unset($post['removeExif']);
|
364 |
+
|
365 |
+
// checkbox overloading
|
366 |
+
$png2jpg = (isset($post['png2jpg']) ? (isset($post['png2jpgForce']) ? 2 : 1): 0);
|
367 |
+
$post['png2jpg'] = $png2jpg;
|
368 |
+
unset($post['png2jpgForce']);
|
369 |
+
|
370 |
+
// must be an array
|
371 |
+
$post['excludeSizes'] = (isset($post['excludeSizes']) && is_array($post['excludeSizes']) ? $post['excludeSizes']: array());
|
372 |
+
|
373 |
+
// key check, if validate is set to valid, check the key
|
374 |
+
if (isset($post['validate']))
|
375 |
+
{
|
376 |
+
if ($post['validate'] == 'validate')
|
377 |
+
$this->postkey_needs_validation = true;
|
378 |
+
|
379 |
+
unset($post['validate']);
|
380 |
+
}
|
381 |
+
|
382 |
+
if (isset($post['addCustomFolder']) && strlen($post['addCustomFolder']) > 0)
|
383 |
+
{
|
384 |
+
$folder = sanitize_text_field(stripslashes($post['addCustomFolder']));
|
385 |
+
$uploadPath = realpath(SHORTPIXEL_UPLOADS_BASE);
|
386 |
+
|
387 |
+
$metaDao = $this->shortPixel->getSpMetaDao();
|
388 |
+
$folderMsg = $metaDao->newFolderFromPath($folder, $uploadPath, \WPShortPixel::getCustomFolderBase());
|
389 |
+
$is_warning = true;
|
390 |
+
if(!$folderMsg) {
|
391 |
+
//$notice = array("status" => "success", "msg" => __('Folder added successfully.','shortpixel-image-optimiser'));
|
392 |
+
$folderMsg = __('Folder added successfully.','shortpixel-image-optimiser');
|
393 |
+
|
394 |
+
$is_warning = false;
|
395 |
+
}
|
396 |
+
if ($is_warning)
|
397 |
+
Notice::addWarning($folderMsg);
|
398 |
+
else
|
399 |
+
Notice::addNormal($folderMsg);
|
400 |
+
|
401 |
+
$this->model->hasCustomFolders = time();
|
402 |
+
}
|
403 |
+
unset($post['addCustomFolder']);
|
404 |
+
|
405 |
+
if(isset($post['removeFolder']) && strlen( trim($post['removeFolder'])) > 0) {
|
406 |
+
$metaDao = $this->shortPixel->getSpMetaDao();
|
407 |
+
Log::addDebug('Removing folder ' . $post['removeFolder']);
|
408 |
+
$metaDao->removeFolder( sanitize_text_field($post['removeFolder']) );
|
409 |
+
|
410 |
+
}
|
411 |
+
unset($post['removeFolder']);
|
412 |
+
|
413 |
+
if (isset($post['emptyBackup']))
|
414 |
+
{
|
415 |
+
$this->shortPixel->emptyBackup();
|
416 |
+
}
|
417 |
+
unset($post['emptyBackup']);
|
418 |
+
|
419 |
+
|
420 |
+
$post = $this->processWebp($post);
|
421 |
+
$post = $this->processExcludeFolders($post);
|
422 |
+
|
423 |
+
parent::processPostData($post);
|
424 |
+
|
425 |
+
}
|
426 |
+
|
427 |
+
/** Function for the WebP settings overload
|
428 |
+
*
|
429 |
+
*/
|
430 |
+
protected function processWebP($post)
|
431 |
+
{
|
432 |
+
$deliverwebp = 0;
|
433 |
+
\WPShortPixel::alterHtaccess(true); // always remove the statements.
|
434 |
+
|
435 |
+
if (isset($post['createWebp']) && $post['createWebp'] == 1)
|
436 |
+
{
|
437 |
+
if (isset($post['deliverWebp']) && $post['deliverWebp'] == 1)
|
438 |
+
{
|
439 |
+
$type = isset($post['deliverWebpType']) ? $post['deliverWebpType'] : '';
|
440 |
+
$altering = isset($post['deliverWebpAlteringType']) ? $post['deliverWebpAlteringType'] : '';
|
441 |
+
|
442 |
+
if ($type == 'deliverWebpAltered')
|
443 |
+
{
|
444 |
+
if ($altering == 'deliverWebpAlteredWP')
|
445 |
+
{
|
446 |
+
$deliverwebp = 2;
|
447 |
+
}
|
448 |
+
elseif($altering = 'deliverWebpAlteredGlobal')
|
449 |
+
{
|
450 |
+
$deliverwebp = 1;
|
451 |
+
}
|
452 |
+
}
|
453 |
+
elseif ($type == 'deliverWebpUnaltered') {
|
454 |
+
$deliverwebp = 3;
|
455 |
+
}
|
456 |
+
}
|
457 |
+
}
|
458 |
+
|
459 |
+
if (! $this->is_nginx && $deliverwebp == 3) // unaltered wepb via htaccess
|
460 |
+
{
|
461 |
+
\WPShortPixel::alterHtaccess();
|
462 |
+
}
|
463 |
+
|
464 |
+
|
465 |
+
$post['deliverWebp'] = $deliverwebp;
|
466 |
+
unset($post['deliverWebpAlteringType']);
|
467 |
+
unset($post['deliverWebpType']);
|
468 |
+
|
469 |
+
return $post;
|
470 |
+
}
|
471 |
+
|
472 |
+
protected function processExcludeFolders($post)
|
473 |
+
{
|
474 |
+
$patterns = array();
|
475 |
+
if(isset($post['excludePatterns']) && strlen($post['excludePatterns'])) {
|
476 |
+
$items = explode(',', $post['excludePatterns']);
|
477 |
+
foreach($items as $pat) {
|
478 |
+
$parts = explode(':', $pat);
|
479 |
+
if(count($parts) == 1) {
|
480 |
+
$patterns[] = array("type" =>"name", "value" => str_replace('\\\\','\\',trim($pat)));
|
481 |
+
} else {
|
482 |
+
$patterns[] = array("type" =>trim($parts[0]), "value" => str_replace('\\\\','\\',trim($parts[1])));
|
483 |
+
}
|
484 |
+
}
|
485 |
+
|
486 |
+
}
|
487 |
+
$post['excludePatterns'] = $patterns;
|
488 |
+
return $post;
|
489 |
+
}
|
490 |
+
|
491 |
+
|
492 |
+
protected function doRedirect($redirect = 'self')
|
493 |
+
{
|
494 |
+
if ($redirect == 'self')
|
495 |
+
{
|
496 |
+
$url = add_query_arg('part', $this->display_part);
|
497 |
+
$url = remove_query_arg('noheader', $url);
|
498 |
+
$url = remove_query_arg('sp-action', $url);
|
499 |
+
}
|
500 |
+
elseif($redirect == 'bulk')
|
501 |
+
{
|
502 |
+
$url = "upload.php?page=wp-short-pixel-bulk";
|
503 |
+
}
|
504 |
+
Log::addDebug('Redirecting: ', $url );
|
505 |
+
wp_redirect($url);
|
506 |
+
exit();
|
507 |
+
}
|
508 |
+
|
509 |
+
protected function NoticeApiKeyLength($key)
|
510 |
+
{
|
511 |
+
$KeyLength = strlen($key);
|
512 |
+
|
513 |
+
$notice = sprintf(__("The key you provided has %s characters. The API key should have 20 characters, letters and numbers only.",'shortpixel-image-optimiser'), $KeyLength)
|
514 |
+
. "<BR> <b>"
|
515 |
+
. __('Please check that the API key is the same as the one you received in your confirmation email.','shortpixel-image-optimiser')
|
516 |
+
. "</b><BR> "
|
517 |
+
. __('If this problem persists, please contact us at ','shortpixel-image-optimiser')
|
518 |
+
. "<a href='mailto:help@shortpixel.com?Subject=API Key issues' target='_top'>help@shortpixel.com</a>"
|
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,4 +1,6 @@
|
|
1 |
<?php
|
|
|
|
|
2 |
|
3 |
class ShortPixelCustomMetaDao {
|
4 |
const META_VERSION = 1;
|
@@ -176,17 +178,29 @@ class ShortPixelCustomMetaDao {
|
|
176 |
public function removeFolder($folderPath) {
|
177 |
$sql = "SELECT id FROM {$this->db->getPrefix()}shortpixel_folders WHERE path = %s";
|
178 |
$row = $this->db->query($sql, array(stripslashes($folderPath)));
|
|
|
179 |
if(!isset($row[0]->id)) return false;
|
180 |
$id = $row[0]->id;
|
181 |
$sql = "UPDATE {$this->db->getPrefix()}shortpixel_folders SET status = -1 WHERE id = %d";
|
182 |
$this->db->query($sql, array($id));
|
183 |
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
$
|
188 |
-
|
189 |
-
$this->db->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
190 |
}
|
191 |
|
192 |
public function newFolderFromPath($path, $uploadPath, $rootPath) {
|
@@ -390,6 +404,7 @@ class ShortPixelCustomMetaDao {
|
|
390 |
*/
|
391 |
public function setBulkRestore($folder_id)
|
392 |
{
|
|
|
393 |
if (! is_numeric($folder_id) || $folder_id <= 0)
|
394 |
return false;
|
395 |
|
1 |
<?php
|
2 |
+
use ShortPixel\ShortPixelLogger as Log;
|
3 |
+
|
4 |
|
5 |
class ShortPixelCustomMetaDao {
|
6 |
const META_VERSION = 1;
|
178 |
public function removeFolder($folderPath) {
|
179 |
$sql = "SELECT id FROM {$this->db->getPrefix()}shortpixel_folders WHERE path = %s";
|
180 |
$row = $this->db->query($sql, array(stripslashes($folderPath)));
|
181 |
+
|
182 |
if(!isset($row[0]->id)) return false;
|
183 |
$id = $row[0]->id;
|
184 |
$sql = "UPDATE {$this->db->getPrefix()}shortpixel_folders SET status = -1 WHERE id = %d";
|
185 |
$this->db->query($sql, array($id));
|
186 |
|
187 |
+
//$this->db->hideErrors();
|
188 |
+
// If images are optimized, not all are removed here.
|
189 |
+
$sql = "DELETE FROM {$this->db->getPrefix()}shortpixel_meta WHERE folder_id = %d AND status <> %d AND status <> %d";
|
190 |
+
$this->db->query($sql, array($id, ShortPixelMeta::FILE_STATUS_PENDING, ShortPixelMeta::FILE_STATUS_SUCCESS));
|
191 |
+
|
192 |
+
$sql = "SELECT FROM {$this->db->getPrefix()}shortpixel_meta WHERE folder_id = %d ";
|
193 |
+
$still_has_images = $this->db->query($sql, array($id));
|
194 |
+
|
195 |
+
// if there are no images left, remove the folder. Otherwise keep it at -1.
|
196 |
+
if (count($still_has_images) == 0)
|
197 |
+
{
|
198 |
+
$sql = "DELETE FROM {$this->db->getPrefix()}shortpixel_folders WHERE path = %s";
|
199 |
+
$this->db->query($sql, array($folderPath));
|
200 |
+
}
|
201 |
+
|
202 |
+
|
203 |
+
//$this->db->restoreErrors();
|
204 |
}
|
205 |
|
206 |
public function newFolderFromPath($path, $uploadPath, $rootPath) {
|
404 |
*/
|
405 |
public function setBulkRestore($folder_id)
|
406 |
{
|
407 |
+
LOG::addDebug('Set Bulk Restore', array('folderid' => $folder_id));
|
408 |
if (! is_numeric($folder_id) || $folder_id <= 0)
|
409 |
return false;
|
410 |
|
@@ -86,9 +86,9 @@ class ShortPixelMetaFacade {
|
|
86 |
}
|
87 |
}
|
88 |
|
89 |
-
static function sanitizeMeta($rawMeta){
|
90 |
if(!is_array($rawMeta)) {
|
91 |
-
if($rawMeta == '') { return array('ShortPixel' => array()); }
|
92 |
else {
|
93 |
$meta = @unserialize($rawMeta);
|
94 |
if(is_array($meta)) {
|
@@ -203,7 +203,7 @@ class ShortPixelMetaFacade {
|
|
203 |
//status and optimization percent in the same time, for sorting purposes :)
|
204 |
$status = $this->meta->getStatus();
|
205 |
if($status == 2) {
|
206 |
-
$status += 0.01 * $rawMeta['ShortPixelImprovement'];
|
207 |
}
|
208 |
update_post_meta($_ID, '_shortpixel_status', number_format($status, 4));
|
209 |
|
@@ -368,10 +368,19 @@ class ShortPixelMetaFacade {
|
|
368 |
$filePaths[] = $meta->getPath();
|
369 |
} else {
|
370 |
$path = get_attached_file($this->ID);//get the full file PATH
|
371 |
-
$mainExists = file_exists($path);
|
372 |
$url = self::safeGetAttachmentUrl($this->ID);
|
373 |
$urlList = array(); $filePaths = array();
|
374 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
375 |
if($mainExists) {
|
376 |
$urlList[] = $url;
|
377 |
$filePaths[] = $path;
|
@@ -419,14 +428,27 @@ class ShortPixelMetaFacade {
|
|
419 |
$count++;
|
420 |
|
421 |
$origPath = $tPath = str_replace(ShortPixelAPI::MB_basename($path), $thumbnailInfo['file'], $path);
|
422 |
-
|
|
|
|
|
423 |
$tPath = SHORTPIXEL_UPLOADS_BASE . substr($tPath, strpos($tPath, $StichString) + strlen($StichString));
|
424 |
}
|
425 |
-
|
|
|
426 |
$tPath = trailingslashit(SHORTPIXEL_UPLOADS_BASE) . $origPath;
|
427 |
}
|
428 |
-
|
429 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
430 |
if(in_array($tUrl, $urlList)) continue;
|
431 |
$urlList[] = $tUrl;
|
432 |
$filePaths[] = $tPath;
|
86 |
}
|
87 |
}
|
88 |
|
89 |
+
static function sanitizeMeta($rawMeta, $createSPArray = true){
|
90 |
if(!is_array($rawMeta)) {
|
91 |
+
if($rawMeta == '') { return $createSPArray ? array('ShortPixel' => array()) : array(); }
|
92 |
else {
|
93 |
$meta = @unserialize($rawMeta);
|
94 |
if(is_array($meta)) {
|
203 |
//status and optimization percent in the same time, for sorting purposes :)
|
204 |
$status = $this->meta->getStatus();
|
205 |
if($status == 2) {
|
206 |
+
$status += 0.01 * intval($rawMeta['ShortPixelImprovement']);
|
207 |
}
|
208 |
update_post_meta($_ID, '_shortpixel_status', number_format($status, 4));
|
209 |
|
368 |
$filePaths[] = $meta->getPath();
|
369 |
} else {
|
370 |
$path = get_attached_file($this->ID);//get the full file PATH
|
371 |
+
$mainExists = apply_filters('shortpixel_image_exists', file_exists($path), $path, $this->ID);
|
372 |
$url = self::safeGetAttachmentUrl($this->ID);
|
373 |
$urlList = array(); $filePaths = array();
|
374 |
|
375 |
+
if(!$mainExists) {
|
376 |
+
//try and download the image from the URL (images present only on CDN)
|
377 |
+
$downloadTimeout = max(ini_get('max_execution_time') - 10, 15);
|
378 |
+
$tempOriginal = download_url($url, $downloadTimeout);
|
379 |
+
if(!is_wp_error( $tempOriginal )) {
|
380 |
+
$mainExists = @copy($tempOriginal, $path);
|
381 |
+
}
|
382 |
+
}
|
383 |
+
|
384 |
if($mainExists) {
|
385 |
$urlList[] = $url;
|
386 |
$filePaths[] = $path;
|
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);
|
433 |
+
if ( !$file_exists && !file_exists($tPath) ) {
|
434 |
$tPath = SHORTPIXEL_UPLOADS_BASE . substr($tPath, strpos($tPath, $StichString) + strlen($StichString));
|
435 |
}
|
436 |
+
|
437 |
+
if ( !$file_exists && !file_exists($tPath) ) {
|
438 |
$tPath = trailingslashit(SHORTPIXEL_UPLOADS_BASE) . $origPath;
|
439 |
}
|
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)) {
|
446 |
+
$tPath = $origPath;
|
447 |
+
}
|
448 |
+
}
|
449 |
+
}
|
450 |
+
|
451 |
+
if ($file_exists || file_exists($tPath)) {
|
452 |
if(in_array($tUrl, $urlList)) continue;
|
453 |
$urlList[] = $tUrl;
|
454 |
$filePaths[] = $tPath;
|
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
class WpShortPixelMediaLbraryAdapter {
|
4 |
-
|
5 |
//count all the processable files in media library (while limiting the results to max 10000)
|
6 |
public static function countAllProcessableFiles($settings = array(), $maxId = PHP_INT_MAX, $minId = 0){
|
7 |
global $wpdb;
|
@@ -30,18 +30,18 @@ class WpShortPixelMediaLbraryAdapter {
|
|
30 |
}
|
31 |
|
32 |
$counter = 0; $foundUnlistedThumbs = false;
|
33 |
-
|
34 |
-
//count all the files, main and thumbs
|
35 |
while ( 1 ) {
|
36 |
$idInfo = self::getPostIdsChunk($minId, $maxId, $pointer, $limit);
|
37 |
-
if($idInfo === null) {
|
38 |
break; //we parsed all the results
|
39 |
-
}
|
40 |
elseif(count($idInfo->ids) == 0) {
|
41 |
$pointer += $limit;
|
42 |
continue;
|
43 |
}
|
44 |
-
|
45 |
$filesList= $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "postmeta
|
46 |
WHERE post_id IN (" . implode(',', $idInfo->ids) . ")
|
47 |
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )");
|
@@ -51,12 +51,12 @@ class WpShortPixelMediaLbraryAdapter {
|
|
51 |
$limit = 1000;
|
52 |
continue;
|
53 |
}
|
54 |
-
|
55 |
-
foreach ( $filesList as $file )
|
56 |
-
{
|
57 |
$totalFilesThis = $processedFilesThis = 0;
|
58 |
//if($file->post_id == 945) {var_dump($file);}
|
59 |
-
|
60 |
if ( $file->meta_key == "_wp_attached_file" )
|
61 |
{//count pdf files only
|
62 |
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
@@ -65,7 +65,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
65 |
$totalFiles++;
|
66 |
$totalFilesThis++;
|
67 |
$mainFiles++;
|
68 |
-
$filesMap[$file->meta_value] = 1;
|
69 |
}
|
70 |
}
|
71 |
elseif ( $file->meta_key == "_wp_attachment_metadata" ) //_wp_attachment_metadata
|
@@ -81,8 +81,8 @@ class WpShortPixelMediaLbraryAdapter {
|
|
81 |
{
|
82 |
$filePath = isset($attachment['file']) ? trailingslashit(SHORTPIXEL_UPLOADS_BASE).$attachment['file'] : false;
|
83 |
if ($filePath && file_exists($filePath) && isset($attachment['sizes']) &&
|
84 |
-
( !isset($attachment['ShortPixelImprovement']) || $attachment['ShortPixelImprovement'] === 0
|
85 |
-
|| $attachment['ShortPixelImprovement'] === 0.0 || $attachment['ShortPixelImprovement'] === "0"))
|
86 |
{
|
87 |
$foundThumbs = WpShortPixelMediaLbraryAdapter::findThumbs($filePath);
|
88 |
$foundCount = count($foundThumbs);
|
@@ -102,10 +102,10 @@ class WpShortPixelMediaLbraryAdapter {
|
|
102 |
} else {
|
103 |
$counter--; // will take the next one
|
104 |
$realSizesCount = $sizesCount;
|
105 |
-
}
|
106 |
}
|
107 |
$counter++;
|
108 |
-
|
109 |
//processable
|
110 |
$isProcessable = false;
|
111 |
$isProcessed = isset($attachment['ShortPixelImprovement'])
|
@@ -150,14 +150,14 @@ class WpShortPixelMediaLbraryAdapter {
|
|
150 |
$procUndefMainFiles++;
|
151 |
$procUndefTotalFiles++;
|
152 |
}
|
153 |
-
|
154 |
//get the thumbs processed for that attachment
|
155 |
$thumbs = $allThumbs = 0;
|
156 |
if ( isset($attachment['ShortPixel']['thumbsOpt']) ) {
|
157 |
$thumbs = $attachment['ShortPixel']['thumbsOpt'];
|
158 |
}
|
159 |
elseif ( isset($attachment['sizes']) ) {
|
160 |
-
$thumbs = $sizesCount;
|
161 |
}
|
162 |
if(!isset($attachment['file'])) { //for the pdfs that have thumbs, have to add the thumbs too (not added above )
|
163 |
$totalFiles += $thumbs;
|
@@ -167,8 +167,8 @@ class WpShortPixelMediaLbraryAdapter {
|
|
167 |
|
168 |
if ( isset($attachment['sizes']) && $sizesCount > $thumbs + count($thumbsMissing)) {
|
169 |
$mainUnprocessedThumbs++;
|
170 |
-
}
|
171 |
-
|
172 |
//increment with thumbs processed
|
173 |
$processedTotalFiles += $thumbs;
|
174 |
$processedFilesThis += $thumbs;
|
@@ -179,7 +179,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
179 |
} else {
|
180 |
$procLosslessTotalFiles += $thumbs;
|
181 |
}
|
182 |
-
|
183 |
if ( isset($attachment['file']) ) {
|
184 |
$processedFilesMap[$attachment['file']] = 1;
|
185 |
}
|
@@ -208,12 +208,12 @@ class WpShortPixelMediaLbraryAdapter {
|
|
208 |
$totalFilesM4 += $totalFilesThis;
|
209 |
}
|
210 |
}
|
211 |
-
}
|
212 |
unset($filesList);
|
213 |
$pointer += $limit;
|
214 |
}//end while
|
215 |
|
216 |
-
return array("totalFiles" => $totalFiles, "mainFiles" => $mainFiles,
|
217 |
"totalProcessedFiles" => $processedTotalFiles, "mainProcessedFiles" => $processedMainFiles,
|
218 |
"totalProcLossyFiles" => $procLossyTotalFiles, "mainProcLossyFiles" => $procLossyMainFiles,
|
219 |
"totalProcGlossyFiles" => $procGlossyTotalFiles, "mainProcGlossyFiles" => $procGlossyMainFiles,
|
@@ -229,19 +229,19 @@ class WpShortPixelMediaLbraryAdapter {
|
|
229 |
"moreFilesWithErrors" => $moreFilesWithErrors,
|
230 |
"foundUnlistedThumbs" => $foundUnlistedThumbs
|
231 |
);
|
232 |
-
}
|
233 |
-
|
234 |
public static function getPostMetaSlice($startId, $endId, $limit) {
|
235 |
global $wpdb;
|
236 |
-
$queryPostMeta = "SELECT pm
|
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 |
-
return $wpdb->get_results($queryPostMeta);
|
243 |
}
|
244 |
-
|
245 |
public static function getSizesNotExcluded($sizes, $exclude = false) {
|
246 |
$uniq = array();
|
247 |
$exclude = is_array($exclude) ? $exclude : array(); //this is because it sometimes receives directly the setting which could be false
|
@@ -257,12 +257,11 @@ class WpShortPixelMediaLbraryAdapter {
|
|
257 |
return $uniq;
|
258 |
}
|
259 |
|
260 |
-
public static function countSizesNotExcluded($sizes, $exclude
|
261 |
{
|
262 |
return count(self::getSizesNotExcluded($sizes, $exclude));
|
263 |
}
|
264 |
|
265 |
-
|
266 |
public static function cleanupFoundThumbs($itemHandler) {
|
267 |
$meta = $itemHandler->getMeta();
|
268 |
$sizesAll = $meta->getThumbs();
|
@@ -280,7 +279,7 @@ class WpShortPixelMediaLbraryAdapter {
|
|
280 |
$meta->setThumbs($sizes);
|
281 |
$itemHandler->updateMeta($meta, true);
|
282 |
}
|
283 |
-
|
284 |
public static function findThumbs($mainFile) {
|
285 |
$ext = pathinfo($mainFile, PATHINFO_EXTENSION);
|
286 |
$base = substr($mainFile, 0, strlen($mainFile) - strlen($ext) - 1);
|
@@ -329,10 +328,10 @@ class WpShortPixelMediaLbraryAdapter {
|
|
329 |
return 500;
|
330 |
}
|
331 |
}
|
332 |
-
|
333 |
protected static function getPostIdsChunk($minId, $maxId, $pointer, $limit) {
|
334 |
global $wpdb;
|
335 |
-
|
336 |
$ids = $idDates = array();
|
337 |
$idList = $wpdb->get_results("SELECT ID, post_mime_type, post_date FROM " . $wpdb->prefix . "posts
|
338 |
WHERE ( ID <= $maxId AND ID > $minId )
|
1 |
<?php
|
2 |
|
3 |
class WpShortPixelMediaLbraryAdapter {
|
4 |
+
|
5 |
//count all the processable files in media library (while limiting the results to max 10000)
|
6 |
public static function countAllProcessableFiles($settings = array(), $maxId = PHP_INT_MAX, $minId = 0){
|
7 |
global $wpdb;
|
30 |
}
|
31 |
|
32 |
$counter = 0; $foundUnlistedThumbs = false;
|
33 |
+
|
34 |
+
//count all the files, main and thumbs
|
35 |
while ( 1 ) {
|
36 |
$idInfo = self::getPostIdsChunk($minId, $maxId, $pointer, $limit);
|
37 |
+
if($idInfo === null) {
|
38 |
break; //we parsed all the results
|
39 |
+
}
|
40 |
elseif(count($idInfo->ids) == 0) {
|
41 |
$pointer += $limit;
|
42 |
continue;
|
43 |
}
|
44 |
+
|
45 |
$filesList= $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "postmeta
|
46 |
WHERE post_id IN (" . implode(',', $idInfo->ids) . ")
|
47 |
AND ( meta_key = '_wp_attached_file' OR meta_key = '_wp_attachment_metadata' )");
|
51 |
$limit = 1000;
|
52 |
continue;
|
53 |
}
|
54 |
+
|
55 |
+
foreach ( $filesList as $file )
|
56 |
+
{
|
57 |
$totalFilesThis = $processedFilesThis = 0;
|
58 |
//if($file->post_id == 945) {var_dump($file);}
|
59 |
+
|
60 |
if ( $file->meta_key == "_wp_attached_file" )
|
61 |
{//count pdf files only
|
62 |
$extension = substr($file->meta_value, strrpos($file->meta_value,".") + 1 );
|
65 |
$totalFiles++;
|
66 |
$totalFilesThis++;
|
67 |
$mainFiles++;
|
68 |
+
$filesMap[$file->meta_value] = 1;
|
69 |
}
|
70 |
}
|
71 |
elseif ( $file->meta_key == "_wp_attachment_metadata" ) //_wp_attachment_metadata
|
81 |
{
|
82 |
$filePath = isset($attachment['file']) ? trailingslashit(SHORTPIXEL_UPLOADS_BASE).$attachment['file'] : false;
|
83 |
if ($filePath && file_exists($filePath) && isset($attachment['sizes']) &&
|
84 |
+
( !isset($attachment['ShortPixelImprovement']) || $attachment['ShortPixelImprovement'] === 0
|
85 |
+
|| $attachment['ShortPixelImprovement'] === 0.0 || $attachment['ShortPixelImprovement'] === "0"))
|
86 |
{
|
87 |
$foundThumbs = WpShortPixelMediaLbraryAdapter::findThumbs($filePath);
|
88 |
$foundCount = count($foundThumbs);
|
102 |
} else {
|
103 |
$counter--; // will take the next one
|
104 |
$realSizesCount = $sizesCount;
|
105 |
+
}
|
106 |
}
|
107 |
$counter++;
|
108 |
+
|
109 |
//processable
|
110 |
$isProcessable = false;
|
111 |
$isProcessed = isset($attachment['ShortPixelImprovement'])
|
150 |
$procUndefMainFiles++;
|
151 |
$procUndefTotalFiles++;
|
152 |
}
|
153 |
+
|
154 |
//get the thumbs processed for that attachment
|
155 |
$thumbs = $allThumbs = 0;
|
156 |
if ( isset($attachment['ShortPixel']['thumbsOpt']) ) {
|
157 |
$thumbs = $attachment['ShortPixel']['thumbsOpt'];
|
158 |
}
|
159 |
elseif ( isset($attachment['sizes']) ) {
|
160 |
+
$thumbs = $sizesCount;
|
161 |
}
|
162 |
if(!isset($attachment['file'])) { //for the pdfs that have thumbs, have to add the thumbs too (not added above )
|
163 |
$totalFiles += $thumbs;
|
167 |
|
168 |
if ( isset($attachment['sizes']) && $sizesCount > $thumbs + count($thumbsMissing)) {
|
169 |
$mainUnprocessedThumbs++;
|
170 |
+
}
|
171 |
+
|
172 |
//increment with thumbs processed
|
173 |
$processedTotalFiles += $thumbs;
|
174 |
$processedFilesThis += $thumbs;
|
179 |
} else {
|
180 |
$procLosslessTotalFiles += $thumbs;
|
181 |
}
|
182 |
+
|
183 |
if ( isset($attachment['file']) ) {
|
184 |
$processedFilesMap[$attachment['file']] = 1;
|
185 |
}
|
208 |
$totalFilesM4 += $totalFilesThis;
|
209 |
}
|
210 |
}
|
211 |
+
}
|
212 |
unset($filesList);
|
213 |
$pointer += $limit;
|
214 |
}//end while
|
215 |
|
216 |
+
return array("totalFiles" => $totalFiles, "mainFiles" => $mainFiles,
|
217 |
"totalProcessedFiles" => $processedTotalFiles, "mainProcessedFiles" => $processedMainFiles,
|
218 |
"totalProcLossyFiles" => $procLossyTotalFiles, "mainProcLossyFiles" => $procLossyMainFiles,
|
219 |
"totalProcGlossyFiles" => $procGlossyTotalFiles, "mainProcGlossyFiles" => $procGlossyMainFiles,
|
229 |
"moreFilesWithErrors" => $moreFilesWithErrors,
|
230 |
"foundUnlistedThumbs" => $foundUnlistedThumbs
|
231 |
);
|
232 |
+
}
|
233 |
+
|
234 |
public static function getPostMetaSlice($startId, $endId, $limit) {
|
235 |
global $wpdb;
|
236 |
+
$queryPostMeta = "SELECT DISTINCT pm.post_id FROM " . $wpdb->prefix . "postmeta pm
|
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 |
+
return $wpdb->get_results($queryPostMeta);
|
243 |
}
|
244 |
+
|
245 |
public static function getSizesNotExcluded($sizes, $exclude = false) {
|
246 |
$uniq = array();
|
247 |
$exclude = is_array($exclude) ? $exclude : array(); //this is because it sometimes receives directly the setting which could be false
|
257 |
return $uniq;
|
258 |
}
|
259 |
|
260 |
+
public static function countSizesNotExcluded($sizes, $exclude= false)
|
261 |
{
|
262 |
return count(self::getSizesNotExcluded($sizes, $exclude));
|
263 |
}
|
264 |
|
|
|
265 |
public static function cleanupFoundThumbs($itemHandler) {
|
266 |
$meta = $itemHandler->getMeta();
|
267 |
$sizesAll = $meta->getThumbs();
|
279 |
$meta->setThumbs($sizes);
|
280 |
$itemHandler->updateMeta($meta, true);
|
281 |
}
|
282 |
+
|
283 |
public static function findThumbs($mainFile) {
|
284 |
$ext = pathinfo($mainFile, PATHINFO_EXTENSION);
|
285 |
$base = substr($mainFile, 0, strlen($mainFile) - strlen($ext) - 1);
|
328 |
return 500;
|
329 |
}
|
330 |
}
|
331 |
+
|
332 |
protected static function getPostIdsChunk($minId, $maxId, $pointer, $limit) {
|
333 |
global $wpdb;
|
334 |
+
|
335 |
$ids = $idDates = array();
|
336 |
$idList = $wpdb->get_results("SELECT ID, post_mime_type, post_date FROM " . $wpdb->prefix . "posts
|
337 |
WHERE ( ID <= $maxId AND ID > $minId )
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
|
4 |
+
// Integration class for HelpScout
|
5 |
+
class HelpScout
|
6 |
+
{
|
7 |
+
public static function outputBeacon($apiKey)
|
8 |
+
{
|
9 |
+
?>
|
10 |
+
<style>
|
11 |
+
.shortpixel-hs-blind {
|
12 |
+
position: fixed;
|
13 |
+
bottom: 18px;
|
14 |
+
right: 0;
|
15 |
+
z-index: 20003;
|
16 |
+
background-color: white;
|
17 |
+
width: 87px;
|
18 |
+
height: 174px;
|
19 |
+
border-radius: 20px 0 0 20px;
|
20 |
+
}
|
21 |
+
.shortpixel-hs-button-blind {
|
22 |
+
display:none;
|
23 |
+
position: fixed;
|
24 |
+
bottom: 115px;right: 0;
|
25 |
+
z-index: 20003;
|
26 |
+
background-color: white;
|
27 |
+
width: 237px;
|
28 |
+
height: 54px;
|
29 |
+
}
|
30 |
+
.shortpixel-hs-tools {
|
31 |
+
position: fixed;
|
32 |
+
bottom: 116px;
|
33 |
+
right: 0px;
|
34 |
+
z-index: 20003;
|
35 |
+
background-color: #ecf9fc;
|
36 |
+
padding: 8px 18px 3px 12px;
|
37 |
+
border-radius: 26px 0 0 26px;
|
38 |
+
-webkit-box-shadow: 1px 1px 5px 0px rgba(6,109,117,1);
|
39 |
+
-moz-box-shadow: 1px 1px 5px 0px rgba(6,109,117,1);
|
40 |
+
box-shadow: 1px 1px 10px 0px rgb(172, 173, 173);
|
41 |
+
}
|
42 |
+
@media (max-width: 767px) {
|
43 |
+
.shortpixel-hs-blind {
|
44 |
+
bottom: 8px;
|
45 |
+
height: 194px;
|
46 |
+
}
|
47 |
+
.shortpixel-hs-button-blind {
|
48 |
+
bottom: 100px;
|
49 |
+
}
|
50 |
+
}
|
51 |
+
</style>
|
52 |
+
<div id="shortpixel-hs-blind" class="shortpixel-hs-blind"></div>
|
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>
|
59 |
+
<script>
|
60 |
+
window.shortpixelHSOpen = -1;
|
61 |
+
function shortpixelToggleHS() {
|
62 |
+
if(window.shortpixelHSOpen == -1) {
|
63 |
+
HS.beacon.init();
|
64 |
+
}
|
65 |
+
if(window.shortpixelHSOpen == 1) {
|
66 |
+
HS.beacon.close();
|
67 |
+
jQuery("#shortpixel-hs-button-blind").css('display', 'none');
|
68 |
+
window.shortpixelHSOpen = 0;
|
69 |
+
} else {
|
70 |
+
HS.beacon.open();
|
71 |
+
jQuery("#shortpixel-hs-button-blind").css('display', 'block');
|
72 |
+
window.shortpixelHSOpen = 1;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
</script>
|
76 |
+
<script type="text/javascript" src="https://quriobot.com/qb/widget/KoPqxmzqzjbg5eNl/V895xbyndnmeqZYd" async defer></script>
|
77 |
+
|
78 |
+
<script>
|
79 |
+
<?php
|
80 |
+
$screen = get_current_screen();
|
81 |
+
if($screen) {
|
82 |
+
switch($screen->id) {
|
83 |
+
case 'media_page_wp-short-pixel-bulk':
|
84 |
+
echo("var shortpixel_suggestions = [ '5a5de2782c7d3a19436843af', '5a5de6902c7d3a19436843e9', '5a5de5c42c7d3a19436843d0', '5a9945e42c7d3a75495145d0', '5a5de1c2042863193801047c', '5a5de66f2c7d3a19436843e0', '5a9946e62c7d3a75495145d8', '5a5de4f02c7d3a19436843c8', '5a5de65f042863193801049f', '5a5de2df0428631938010485' ]; ");
|
85 |
+
$suggestions = "shortpixel_suggestions";
|
86 |
+
break;
|
87 |
+
case 'settings_page_wp-shortpixel-settings':
|
88 |
+
echo("var shortpixel_suggestions_settings = [ '5a5de1de2c7d3a19436843a8', '5a6612032c7d3a39e6263a1d', '5a5de1c2042863193801047c', '5a5de2782c7d3a19436843af', '5a6610c62c7d3a39e6263a02', '5a9945e42c7d3a75495145d0', '5a5de66f2c7d3a19436843e0', '5a6597e80428632faf620487', '5a5de5c42c7d3a19436843d0', '5a5de5642c7d3a19436843cc' ]; ");
|
89 |
+
echo("var shortpixel_suggestions_adv_settings = [ '5a5de4f02c7d3a19436843c8', '5a8431f00428634376d01dc4', '5a5de58b0428631938010497', '5a5de65f042863193801049f', '5a9945e42c7d3a75495145d0', '5a9946e62c7d3a75495145d8', '5a5de57c0428631938010495', '5a5de2d22c7d3a19436843b1', '5a5de5c42c7d3a19436843d0', '5a5de5642c7d3a19436843cc' ]; ");
|
90 |
+
echo("var shortpixel_suggestions_cloudflare = [ '5a5de1f62c7d3a19436843a9', '5a5de58b0428631938010497', '5a5de66f2c7d3a19436843e0', '5a5de5c42c7d3a19436843d0', '5a5de6902c7d3a19436843e9', '5a5de51a2c7d3a19436843c9', '5a9946e62c7d3a75495145d8', '5a5de46c2c7d3a19436843c1', '5a5de1de2c7d3a19436843a8', '5a6597e80428632faf620487' ]; ");
|
91 |
+
$suggestions = "shortpixel_suggestions_settings";
|
92 |
+
break;
|
93 |
+
case 'media_page_wp-short-pixel-custom':
|
94 |
+
echo("var shortpixel_suggestions = [ '5a9946e62c7d3a75495145d8', '5a5de1c2042863193801047c', '5a5de2782c7d3a19436843af', '5a5de6902c7d3a19436843e9', '5a5de4f02c7d3a19436843c8', '5a6610c62c7d3a39e6263a02', '5a9945e42c7d3a75495145d0', '5a5de46c2c7d3a19436843c1', '5a5de1de2c7d3a19436843a8', '5a5de25c2c7d3a19436843ad' ]; ");
|
95 |
+
$suggestions = "shortpixel_suggestions";
|
96 |
+
break;
|
97 |
+
}
|
98 |
+
}
|
99 |
+
?>
|
100 |
+
!function(e,o,n){ window.HSCW=o,window.HS=n,n.beacon=n.beacon||{};var t=n.beacon;t.userConfig={
|
101 |
+
color: "#1CBECB",
|
102 |
+
icon: "question",
|
103 |
+
instructions: "Send ShortPixel a message",
|
104 |
+
topArticles: true,
|
105 |
+
poweredBy: false,
|
106 |
+
showContactFields: true,
|
107 |
+
showName: false,
|
108 |
+
showSubject: true,
|
109 |
+
translation: {
|
110 |
+
searchLabel: "What can ShortPixel help you with?",
|
111 |
+
contactSuccessDescription: "Thanks for reaching out! Someone from our team will get back to you in 24h max."
|
112 |
+
}
|
113 |
+
|
114 |
+
},t.readyQueue=[],t.config=function(e){this.userConfig=e},t.ready=function(e){this.readyQueue.push(e)},o.config={docs:{enabled:!0,baseUrl:"//shortpixel.helpscoutdocs.com/"},contact:{enabled:!0,formId:"278a7825-fce0-11e7-b466-0ec85169275a"}};var r=e.getElementsByTagName("script")[0],c=e.createElement("script");
|
115 |
+
c.type="text/javascript",c.async=!0,c.src="https://djtflbt20bdde.cloudfront.net/",r.parentNode.insertBefore(c,r);
|
116 |
+
}(document,window.HSCW||{},window.HS||{});
|
117 |
+
|
118 |
+
window.HS.beacon.ready(function(){
|
119 |
+
HS.beacon.identify({
|
120 |
+
email: "<?php $u = wp_get_current_user(); echo($u->user_email); ?>",
|
121 |
+
apiKey: "<?php echo($apiKey);?>"
|
122 |
+
});
|
123 |
+
HS.beacon.suggest( <?php echo( $suggestions ) ?> );
|
124 |
+
});
|
125 |
+
</script>
|
126 |
+
<?php
|
127 |
+
}
|
128 |
+
}
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\NoticeController as Notice;
|
4 |
+
|
5 |
+
class NextGen
|
6 |
+
{
|
7 |
+
protected $shortPixel;
|
8 |
+
|
9 |
+
/** @todo Temporary constructor. In future, shortpixel should not have to be passed all the time */
|
10 |
+
public function __construct($shortPixel)
|
11 |
+
{
|
12 |
+
$this->shortPixel = $shortPixel;
|
13 |
+
}
|
14 |
+
|
15 |
+
/** Enables nextGen, add galleries to custom folders
|
16 |
+
* @param boolean $silent Throw a notice or not. This seems to be based if nextgen was already activated previously or not.
|
17 |
+
*/
|
18 |
+
public function nextGenEnabled($silent)
|
19 |
+
{
|
20 |
+
\WpShortPixelDb::checkCustomTables(); // check if custom tables are created, if not, create them
|
21 |
+
// $prevNextGen = $this->_settings->includeNextGen;
|
22 |
+
$this->addNextGenGalleriesToCustom($silent);
|
23 |
+
// $folderMsg = $ret["message"];
|
24 |
+
// $customFolders = $ret["customFolders"];
|
25 |
+
}
|
26 |
+
|
27 |
+
/** Adds nextGen galleries to custom table
|
28 |
+
* Note - this function does *Not* check if nextgen is enabled, not if checks custom Tables. Use nextgenEnabled for this.
|
29 |
+
* Enabled checks are not an external class issue, so must be done before calling.
|
30 |
+
*/
|
31 |
+
public function addNextGenGalleriesToCustom($silent = true) {
|
32 |
+
// $customFolders = array();
|
33 |
+
$folderMsg = "";
|
34 |
+
|
35 |
+
//add the NextGen galleries to custom folders
|
36 |
+
$ngGalleries = \ShortPixelNextGenAdapter::getGalleries();
|
37 |
+
$meta = $this->shortPixel->getSpMetaDao();
|
38 |
+
foreach($ngGalleries as $gallery) {
|
39 |
+
$msg = $meta->newFolderFromPath($gallery, get_home_path(), \WPShortPixel::getCustomFolderBase());
|
40 |
+
if($msg) { //try again with ABSPATH as maybe WP is in a subdir
|
41 |
+
$msg = $meta->newFolderFromPath($gallery, ABSPATH, \WPShortPixel::getCustomFolderBase());
|
42 |
+
}
|
43 |
+
$folderMsg .= $msg;
|
44 |
+
//$this->_settings->hasCustomFolders = time();
|
45 |
+
}
|
46 |
+
|
47 |
+
if (count($ngGalleries) > 0)
|
48 |
+
{
|
49 |
+
// put timestamp to this setting.
|
50 |
+
$settings = new \WPShortPixelSettings();
|
51 |
+
$settings->hasCustomFolders = time();
|
52 |
+
|
53 |
+
}
|
54 |
+
// $customFolders = $this->spMetaDao->getFolders();
|
55 |
+
if (! $silent)
|
56 |
+
{
|
57 |
+
Notice::addNormal($folderMsg);
|
58 |
+
}
|
59 |
+
|
60 |
+
// return array("message" => $silent? "" : $folderMsg, "customFolders" => $customFolders);
|
61 |
+
}
|
62 |
+
}
|
@@ -4,8 +4,12 @@
|
|
4 |
* thanks to the Responsify WP plugin for some of the code
|
5 |
*/
|
6 |
|
|
|
|
|
|
|
7 |
class ShortPixelImgToPictureWebp
|
8 |
{
|
|
|
9 |
public static function lazyGet($img, $type)
|
10 |
{
|
11 |
return array(
|
@@ -26,23 +30,80 @@ class ShortPixelImgToPictureWebp
|
|
26 |
{
|
27 |
// Don't do anything with the RSS feed.
|
28 |
if (is_feed() || is_admin()) {
|
29 |
-
|
|
|
30 |
}
|
|
|
|
|
|
|
|
|
|
|
31 |
$content = preg_replace_callback('/<img[^>]*>/', array('self', 'convertImage'), $content);
|
32 |
//$content = preg_replace_callback('/background.*[^:](url\(.*\)[,;])/im', array('self', 'convertInlineStyle'), $content);
|
33 |
|
34 |
// [BS] No callback because we need preg_match_all
|
35 |
-
|
36 |
// $content = preg_replace_callback('/background.*[^:]url\([\'|"](.*)[\'|"]\)[,;]/imU',array('self', 'convertInlineStyle'), $content);
|
37 |
-
|
|
|
|
|
38 |
|
39 |
}
|
40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
public static function convertImage($match)
|
42 |
{
|
43 |
// Do nothing with images that have the 'sp-no-webp' class.
|
44 |
if (strpos($match[0], 'sp-no-webp')) {
|
45 |
-
|
|
|
46 |
}
|
47 |
|
48 |
$img = self::get_attributes($match[0]);
|
@@ -64,6 +125,7 @@ class ShortPixelImgToPictureWebp
|
|
64 |
$sizesPrefix = $sizesInfo['prefix'];
|
65 |
|
66 |
$altAttr = isset($img['alt']) && strlen($img['alt']) ? ' alt="' . $img['alt'] . '"' : '';
|
|
|
67 |
|
68 |
//check if there are webps
|
69 |
/*$id = $thisClass::url_to_attachment_id( $src );
|
@@ -105,11 +167,15 @@ class ShortPixelImgToPictureWebp
|
|
105 |
}
|
106 |
$imageBase = dirname($imageBase) . '/';
|
107 |
*/
|
108 |
-
|
|
|
|
|
109 |
if($imageBase === false) {
|
110 |
-
return $match[0] . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG baseurl doesn\'t match ' . $src . ' -->' : '');
|
|
|
111 |
}
|
112 |
|
|
|
113 |
// We don't wanna have src-ish attributes on the <picture>
|
114 |
unset($img['src']);
|
115 |
unset($img['data-src']);
|
@@ -117,6 +183,7 @@ class ShortPixelImgToPictureWebp
|
|
117 |
unset($img['srcset']);
|
118 |
unset($img['sizes']);
|
119 |
unset($img['alt']);
|
|
|
120 |
$srcsetWebP = '';
|
121 |
|
122 |
if ($srcset) {
|
@@ -128,7 +195,7 @@ class ShortPixelImgToPictureWebp
|
|
128 |
|
129 |
$fileWebPCompat = $imageBase . wp_basename($parts[0], '.' . pathinfo($parts[0], PATHINFO_EXTENSION)) . '.webp';
|
130 |
$fileWebP = $imageBase . wp_basename($parts[0]) . '.webp';
|
131 |
-
if (file_exists($fileWebP)) {
|
132 |
$srcsetWebP .= (strlen($srcsetWebP) ? ',': '')
|
133 |
. $parts[0].'.webp'
|
134 |
. (isset($parts[1]) ? ' ' . $parts[1] : '');
|
@@ -138,6 +205,9 @@ class ShortPixelImgToPictureWebp
|
|
138 |
.preg_replace('/\.[a-zA-Z0-9]+$/', '.webp', $parts[0])
|
139 |
.(isset($parts[1]) ? ' ' . $parts[1] : '');
|
140 |
}
|
|
|
|
|
|
|
141 |
}
|
142 |
//$srcsetWebP = preg_replace('/\.[a-zA-Z0-9]+\s+/', '.webp ', $srcset);
|
143 |
} else {
|
@@ -146,17 +216,21 @@ class ShortPixelImgToPictureWebp
|
|
146 |
|
147 |
$fileWebPCompat = $imageBase . wp_basename($srcset, '.' . pathinfo($srcset, PATHINFO_EXTENSION)) . '.webp';
|
148 |
$fileWebP = $imageBase . wp_basename($srcset) . '.webp';
|
149 |
-
if (file_exists($fileWebP)) {
|
150 |
$srcsetWebP = $srcset.".webp";
|
151 |
} else {
|
152 |
-
if (file_exists($fileWebPCompat)) {
|
153 |
$srcsetWebP = preg_replace('/\.[a-zA-Z0-9]+$/', '.webp', $srcset);
|
154 |
}
|
|
|
|
|
|
|
155 |
}
|
156 |
}
|
157 |
//return($match[0]. "<!-- srcsetTZF:".$srcsetWebP." -->");
|
158 |
if (!strlen($srcsetWebP)) {
|
159 |
-
return $match[0]
|
|
|
160 |
}
|
161 |
|
162 |
//add the exclude class so if this content is processed again in other filter, the img is not converted again in picture
|
@@ -165,7 +239,7 @@ class ShortPixelImgToPictureWebp
|
|
165 |
return '<picture ' . self::create_attributes($img) . '>'
|
166 |
.'<source ' . $srcsetPrefix . 'srcset="' . $srcsetWebP . '"' . ($sizes ? ' ' . $sizesPrefix . 'sizes="' . $sizes . '"' : '') . ' type="image/webp">'
|
167 |
.'<source ' . $srcsetPrefix . 'srcset="' . $srcset . '"' . ($sizes ? ' ' . $sizesPrefix . 'sizes="' . $sizes . '"' : '') . '>'
|
168 |
-
.'<img ' . $srcPrefix . 'src="' . $src . '" ' . self::create_attributes($img) . $altAttr
|
169 |
. (strlen($srcset) ? ' srcset="' . $srcset . '"': '') . (strlen($sizes) ? ' sizes="' . $sizes . '"': '') . '>'
|
170 |
.'</picture>';
|
171 |
}
|
@@ -257,7 +331,20 @@ class ShortPixelImgToPictureWebp
|
|
257 |
**/
|
258 |
public static function getImageBase($src)
|
259 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
260 |
$updir = wp_upload_dir();
|
|
|
|
|
|
|
261 |
$proto = explode("://", $src);
|
262 |
if (count($proto) > 1) {
|
263 |
//check that baseurl uses the same http/https proto and if not, change
|
@@ -276,7 +363,6 @@ class ShortPixelImgToPictureWebp
|
|
276 |
}
|
277 |
|
278 |
if ($imageBase == $src) { //maybe the site uses a CDN or a subdomain? - Or relative link
|
279 |
-
$urlParsed = parse_url($src);
|
280 |
$baseParsed = parse_url($updir['baseurl']);
|
281 |
|
282 |
$srcHost = array_reverse(explode('.', $urlParsed['host']));
|
@@ -305,8 +391,10 @@ class ShortPixelImgToPictureWebp
|
|
305 |
}
|
306 |
// [BS] Escape when DOM Module not installed
|
307 |
if (! class_exists('DOMDocument'))
|
|
|
|
|
308 |
return false;
|
309 |
-
|
310 |
$dom = new DOMDocument();
|
311 |
@$dom->loadHTML($image_node);
|
312 |
$image = $dom->getElementsByTagName('img')->item(0);
|
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 |
{
|
12 |
+
/** If lazy loading is happening, get source (src) from those values */
|
13 |
public static function lazyGet($img, $type)
|
14 |
{
|
15 |
return array(
|
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');
|
34 |
+
return $content; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- -->' : '');
|
35 |
}
|
36 |
+
|
37 |
+
$new_content = self::testPictures($content);
|
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
|
45 |
+
$content = self::testInlineStyle($content);
|
46 |
// $content = preg_replace_callback('/background.*[^:]url\([\'|"](.*)[\'|"]\)[,;]/imU',array('self', 'convertInlineStyle'), $content);
|
47 |
+
Log::addDebug('SPDBG WebP process done');
|
48 |
+
|
49 |
+
return $content; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG WebP converted -->' : '');
|
50 |
|
51 |
}
|
52 |
|
53 |
+
public static function testPictures($content)
|
54 |
+
{
|
55 |
+
// [BS] Escape when DOM Module not installed
|
56 |
+
if (! class_exists('DOMDocument'))
|
57 |
+
return false;
|
58 |
+
|
59 |
+
//$dom = new DOMDocument();
|
60 |
+
//@$dom->loadHTML($content, LIBXML_HTML_NOIMPLIED, LIBXML_HTML_NODEFDTD);
|
61 |
+
|
62 |
+
$dom = new DomDocument();
|
63 |
+
$fragment = $dom->createDocumentFragment();
|
64 |
+
$fragment->appendXML($content);
|
65 |
+
$dom->appendChild($fragment);
|
66 |
+
|
67 |
+
$elements = $dom->getElementsByTagName('picture');
|
68 |
+
|
69 |
+
if ($elements->length == 0)
|
70 |
+
return false;
|
71 |
+
|
72 |
+
foreach($elements as $element)
|
73 |
+
{
|
74 |
+
if ($element->hasChildNodes() )
|
75 |
+
{
|
76 |
+
foreach($element->childNodes as $elchild)
|
77 |
+
{
|
78 |
+
if ($elchild->tagName == 'img')
|
79 |
+
{
|
80 |
+
$class = ($elchild->hasAttribute('class')) ? $elchild->getAttribute('class') . ' ' : '';
|
81 |
+
$class .= 'sp-no-webp';
|
82 |
+
$elchild->setAttribute('class', $class);
|
83 |
+
Log::addInfo('Found Picture with Img, added skip class', array($elchild->getAttribute('src')) );
|
84 |
+
}
|
85 |
+
}
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
return $dom->saveHTML();
|
90 |
+
|
91 |
+
}
|
92 |
+
|
93 |
+
/* This might be a future solution for regex callbacks.
|
94 |
+
public static function processImageNode($node, $type)
|
95 |
+
{
|
96 |
+
$srcsets = $node->getElementsByTagName('srcset');
|
97 |
+
$srcs = $node->getElementsByTagName('src');
|
98 |
+
$imgs = $node->getElementsByTagName('img');
|
99 |
+
} */
|
100 |
+
|
101 |
public static function convertImage($match)
|
102 |
{
|
103 |
// Do nothing with images that have the 'sp-no-webp' class.
|
104 |
if (strpos($match[0], 'sp-no-webp')) {
|
105 |
+
Log::addInfo('SPDBG convertImage skipped, sp-no-webp found');
|
106 |
+
return $match[0]; //. (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG convertImage sp-no-webp -->' : '');
|
107 |
}
|
108 |
|
109 |
$img = self::get_attributes($match[0]);
|
125 |
$sizesPrefix = $sizesInfo['prefix'];
|
126 |
|
127 |
$altAttr = isset($img['alt']) && strlen($img['alt']) ? ' alt="' . $img['alt'] . '"' : '';
|
128 |
+
$idAttr = isset($img['id']) && strlen($img['id']) ? ' id="' . $img['id'] . '"' : '';
|
129 |
|
130 |
//check if there are webps
|
131 |
/*$id = $thisClass::url_to_attachment_id( $src );
|
167 |
}
|
168 |
$imageBase = dirname($imageBase) . '/';
|
169 |
*/
|
170 |
+
|
171 |
+
$imageBase = apply_filters( 'shortpixel_webp_image_base', static::getImageBase($src), $src);
|
172 |
+
|
173 |
if($imageBase === false) {
|
174 |
+
return $match[0]; // . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG baseurl doesn\'t match ' . $src . ' -->' : '');
|
175 |
+
Log::addInfo('SPDBG baseurl doesn\'t match ' . $src);
|
176 |
}
|
177 |
|
178 |
+
|
179 |
// We don't wanna have src-ish attributes on the <picture>
|
180 |
unset($img['src']);
|
181 |
unset($img['data-src']);
|
183 |
unset($img['srcset']);
|
184 |
unset($img['sizes']);
|
185 |
unset($img['alt']);
|
186 |
+
unset($img['id']);
|
187 |
$srcsetWebP = '';
|
188 |
|
189 |
if ($srcset) {
|
195 |
|
196 |
$fileWebPCompat = $imageBase . wp_basename($parts[0], '.' . pathinfo($parts[0], PATHINFO_EXTENSION)) . '.webp';
|
197 |
$fileWebP = $imageBase . wp_basename($parts[0]) . '.webp';
|
198 |
+
if (apply_filters( 'shortpixel_image_exists', file_exists($fileWebP), $fileWebP)) {
|
199 |
$srcsetWebP .= (strlen($srcsetWebP) ? ',': '')
|
200 |
. $parts[0].'.webp'
|
201 |
. (isset($parts[1]) ? ' ' . $parts[1] : '');
|
205 |
.preg_replace('/\.[a-zA-Z0-9]+$/', '.webp', $parts[0])
|
206 |
.(isset($parts[1]) ? ' ' . $parts[1] : '');
|
207 |
}
|
208 |
+
else {
|
209 |
+
Log::addDebug('Image srcset for webp doesn\'t exist', array($fileWebP));
|
210 |
+
}
|
211 |
}
|
212 |
//$srcsetWebP = preg_replace('/\.[a-zA-Z0-9]+\s+/', '.webp ', $srcset);
|
213 |
} else {
|
216 |
|
217 |
$fileWebPCompat = $imageBase . wp_basename($srcset, '.' . pathinfo($srcset, PATHINFO_EXTENSION)) . '.webp';
|
218 |
$fileWebP = $imageBase . wp_basename($srcset) . '.webp';
|
219 |
+
if (apply_filters( 'shortpixel_image_exists', file_exists($fileWebP), $fileWebP)) {
|
220 |
$srcsetWebP = $srcset.".webp";
|
221 |
} else {
|
222 |
+
if (apply_filters( 'shortpixel_image_exists', file_exists($fileWebPCompat), $fileWebPCompat) ) {
|
223 |
$srcsetWebP = preg_replace('/\.[a-zA-Z0-9]+$/', '.webp', $srcset);
|
224 |
}
|
225 |
+
else {
|
226 |
+
Log::addDebug('Image file for webp doesn\'t exist', array($fileWebP));
|
227 |
+
}
|
228 |
}
|
229 |
}
|
230 |
//return($match[0]. "<!-- srcsetTZF:".$srcsetWebP." -->");
|
231 |
if (!strlen($srcsetWebP)) {
|
232 |
+
return $match[0]; //. (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG no srcsetWebP found (' . $srcsetWebP . ') -->' : '');
|
233 |
+
Log::addInfo(' SPDBG no srcsetWebP found (' . $srcsetWebP . ')');
|
234 |
}
|
235 |
|
236 |
//add the exclude class so if this content is processed again in other filter, the img is not converted again in picture
|
239 |
return '<picture ' . self::create_attributes($img) . '>'
|
240 |
.'<source ' . $srcsetPrefix . 'srcset="' . $srcsetWebP . '"' . ($sizes ? ' ' . $sizesPrefix . 'sizes="' . $sizes . '"' : '') . ' type="image/webp">'
|
241 |
.'<source ' . $srcsetPrefix . 'srcset="' . $srcset . '"' . ($sizes ? ' ' . $sizesPrefix . 'sizes="' . $sizes . '"' : '') . '>'
|
242 |
+
.'<img ' . $srcPrefix . 'src="' . $src . '" ' . self::create_attributes($img) . $idAttr . $altAttr
|
243 |
. (strlen($srcset) ? ' srcset="' . $srcset . '"': '') . (strlen($sizes) ? ' sizes="' . $sizes . '"': '') . '>'
|
244 |
.'</picture>';
|
245 |
}
|
331 |
**/
|
332 |
public static function getImageBase($src)
|
333 |
{
|
334 |
+
$urlParsed = parse_url($src);
|
335 |
+
if(!isset($urlParsed['host'])) {
|
336 |
+
if($src[0] == '/') { //absolute URL, current domain
|
337 |
+
$src = get_site_url() . $src;
|
338 |
+
} else {
|
339 |
+
global $wp;
|
340 |
+
$src = trailingslashit(home_url( $wp->request )) . $src;
|
341 |
+
}
|
342 |
+
$urlParsed = parse_url($src);
|
343 |
+
}
|
344 |
$updir = wp_upload_dir();
|
345 |
+
if(substr($src, 0, 2) == '//') {
|
346 |
+
$src = (stripos($_SERVER['SERVER_PROTOCOL'],'https') === false ? 'http:' : 'https:') . $src;
|
347 |
+
}
|
348 |
$proto = explode("://", $src);
|
349 |
if (count($proto) > 1) {
|
350 |
//check that baseurl uses the same http/https proto and if not, change
|
363 |
}
|
364 |
|
365 |
if ($imageBase == $src) { //maybe the site uses a CDN or a subdomain? - Or relative link
|
|
|
366 |
$baseParsed = parse_url($updir['baseurl']);
|
367 |
|
368 |
$srcHost = array_reverse(explode('.', $urlParsed['host']));
|
391 |
}
|
392 |
// [BS] Escape when DOM Module not installed
|
393 |
if (! class_exists('DOMDocument'))
|
394 |
+
{
|
395 |
+
Log::addWarn('Webp Active, but DomDocument class not found ( missing xmldom library )');
|
396 |
return false;
|
397 |
+
}
|
398 |
$dom = new DOMDocument();
|
399 |
@$dom->loadHTML($image_node);
|
400 |
$image = $dom->getElementsByTagName('img')->item(0);
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace ShortPixel;
|
4 |
+
|
5 |
+
class NoticeModel extends ShortPixelModel
|
6 |
+
{
|
7 |
+
protected $message;
|
8 |
+
public $code;
|
9 |
+
|
10 |
+
protected $viewed = false;
|
11 |
+
public $is_persistent = false; // This is a fatal issue, display until something was fixed.
|
12 |
+
public $is_removable = true; // if removable, display a notice dialog with red X or so.
|
13 |
+
public $messageType = self::NOTICE_NORMAL;
|
14 |
+
|
15 |
+
const NOTICE_NORMAL = 1;
|
16 |
+
const NOTICE_ERROR = 2;
|
17 |
+
const NOTICE_SUCCESS = 3;
|
18 |
+
const NOTICE_WARNING = 4;
|
19 |
+
|
20 |
+
|
21 |
+
public function __construct($message, $messageType = self::NOTICE_NORMAL)
|
22 |
+
{
|
23 |
+
$this->message = $message;
|
24 |
+
$this->messageType = $messageType;
|
25 |
+
|
26 |
+
}
|
27 |
+
|
28 |
+
public function isDone()
|
29 |
+
{
|
30 |
+
if ($this->viewed && ! $this->is_persistent)
|
31 |
+
return true;
|
32 |
+
else
|
33 |
+
return false;
|
34 |
+
|
35 |
+
}
|
36 |
+
|
37 |
+
public function getForDisplay()
|
38 |
+
{
|
39 |
+
$this->viewed = true;
|
40 |
+
$class = 'shortpixel notice ';
|
41 |
+
|
42 |
+
$icon = 'slider';
|
43 |
+
|
44 |
+
switch($this->messageType)
|
45 |
+
{
|
46 |
+
case self::NOTICE_ERROR:
|
47 |
+
$class .= 'notice-error ';
|
48 |
+
$icon = 'scared';
|
49 |
+
break;
|
50 |
+
case self::NOTICE_SUCCESS:
|
51 |
+
$class .= 'notice-success ';
|
52 |
+
break;
|
53 |
+
case self::NOTICE_WARNING:
|
54 |
+
$class .= 'notice-warning ';
|
55 |
+
break;
|
56 |
+
case self::NOTICE_NORMAL:
|
57 |
+
default:
|
58 |
+
$class .= 'notice-info ';
|
59 |
+
break;
|
60 |
+
}
|
61 |
+
|
62 |
+
$image = '<img src="' . plugins_url('/shortpixel-image-optimiser/res/img/robo-' . $icon . '.png') . '"
|
63 |
+
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">';
|
64 |
+
|
65 |
+
|
66 |
+
if ($this->is_removable)
|
67 |
+
{
|
68 |
+
$class .= 'is-dismissible ';
|
69 |
+
}
|
70 |
+
|
71 |
+
if ($this->is_persistent)
|
72 |
+
{
|
73 |
+
$class .= '';
|
74 |
+
}
|
75 |
+
|
76 |
+
return "<div class='$class'>" . $image . "<p>" . $this->message . "</p></div>";
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
|
81 |
+
|
82 |
+
// @todo Transient save, since that is used in some parts.
|
83 |
+
// save
|
84 |
+
// load
|
85 |
+
|
86 |
+
|
87 |
+
}
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// The data models.
|
3 |
+
namespace ShortPixel;
|
4 |
+
|
5 |
+
|
6 |
+
class DebugItem // extends ShortPixelModel Too early init for this.
|
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 |
+
$i = 4;
|
127 |
+
if (isset($debug[$i]))
|
128 |
+
{
|
129 |
+
$info = $debug[$i];
|
130 |
+
$line = isset($info['line']) ? $info['line'] : 'Line unknown';
|
131 |
+
$file = isset($info['file']) ? basename($info['file']) : 'File not set';
|
132 |
+
|
133 |
+
$this->caller = array('line' => $line, 'file' => $file, 'function' => $info['function']);
|
134 |
+
}
|
135 |
+
|
136 |
+
|
137 |
+
}
|
138 |
+
|
139 |
+
|
140 |
+
}
|
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
class ShortPixelFolder extends ShortPixelEntity{
|
4 |
const META_VERSION = 1;
|
5 |
-
|
6 |
protected $id;
|
7 |
protected $path;
|
8 |
protected $type;
|
@@ -10,28 +10,56 @@ class ShortPixelFolder extends ShortPixelEntity{
|
|
10 |
protected $fileCount;
|
11 |
protected $tsCreated;
|
12 |
protected $tsUpdated;
|
13 |
-
|
14 |
protected $excludePatterns;
|
15 |
-
|
16 |
const TABLE_SUFFIX = 'folders';
|
17 |
-
|
18 |
public function __construct($data, $excludePatterns = false) {
|
19 |
parent::__construct($data);
|
20 |
$this->excludePatterns = $excludePatterns;
|
21 |
}
|
22 |
-
|
23 |
public static function checkFolder($folder, $base) {
|
24 |
if(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' && substr($folder, 0, 1) !== '/') {
|
25 |
$folder = '/' . $folder;
|
26 |
}
|
27 |
if(is_dir($folder)) {
|
28 |
return $folder;
|
29 |
-
} elseif(is_dir($base . $folder)) {
|
30 |
return $base . $folder;
|
31 |
}
|
32 |
return false;
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
public static function deleteFolder($dirname) {
|
36 |
if (is_dir($dirname))
|
37 |
$dir_handle = opendir($dirname);
|
@@ -49,7 +77,7 @@ class ShortPixelFolder extends ShortPixelEntity{
|
|
49 |
@rmdir($dirname);
|
50 |
return true;
|
51 |
}
|
52 |
-
|
53 |
/**
|
54 |
* returns the first from parents that is a parent folder of $folder
|
55 |
* @param string $folder
|
@@ -67,7 +95,7 @@ class ShortPixelFolder extends ShortPixelEntity{
|
|
67 |
}
|
68 |
return false;
|
69 |
}
|
70 |
-
|
71 |
/**
|
72 |
* finds the first from the subfolders that has the folder as parent
|
73 |
* @param string $folder
|
@@ -104,11 +132,11 @@ class ShortPixelFolder extends ShortPixelEntity{
|
|
104 |
$size += $this->countFiles($tpath);
|
105 |
} elseif(WPShortPixel::_isProcessablePath($tpath, array(), $this->excludePatterns)) {
|
106 |
$size++;
|
107 |
-
}
|
108 |
}
|
109 |
return $size;
|
110 |
-
}
|
111 |
-
|
112 |
public function getFileList($onlyNewerThan = 0) {
|
113 |
$fileListPath = tempnam(SHORTPIXEL_UPLOADS_BASE . '/', 'sp_');
|
114 |
$fileHandle = fopen($fileListPath, 'w+');
|
@@ -116,14 +144,14 @@ class ShortPixelFolder extends ShortPixelEntity{
|
|
116 |
fclose($fileHandle);
|
117 |
return $fileListPath;
|
118 |
}
|
119 |
-
|
120 |
protected static function getFileListRecursive($path, $fileHandle, $onlyNewerThan) {
|
121 |
$ignore = array('.','..');
|
122 |
$files = scandir($path);
|
123 |
$add = (filemtime($path) > $onlyNewerThan);
|
124 |
/*
|
125 |
if($add && $onlyNewerThan) {
|
126 |
-
echo("<br> FOLDER UPDATED: " . $path);
|
127 |
}
|
128 |
*/
|
129 |
foreach($files as $t) {
|
@@ -133,16 +161,16 @@ class ShortPixelFolder extends ShortPixelEntity{
|
|
133 |
self::getFileListRecursive($tpath, $fileHandle, $onlyNewerThan);
|
134 |
} elseif($add && WPShortPixel::_isProcessablePath($tpath, array(), WPShortPixelSettings::getOpt('excludePatterns'))) {
|
135 |
fwrite($fileHandle, $tpath . "\n");
|
136 |
-
}
|
137 |
}
|
138 |
}
|
139 |
-
|
140 |
public function checkFolderContents($callback) {
|
141 |
$changed = array();
|
142 |
self::checkFolderContentsRecursive($this->getPath(), $changed, $callback);
|
143 |
return $changed;
|
144 |
}
|
145 |
-
|
146 |
protected static function checkFolderContentsRecursive($path, &$changed, $callback) {
|
147 |
$ignore = array('.','..');
|
148 |
$files = scandir($path);
|
@@ -155,14 +183,14 @@ class ShortPixelFolder extends ShortPixelEntity{
|
|
155 |
} elseif( WPShortPixel::_isProcessablePath($tpath, array(), WPShortPixelSettings::getOpt('excludePatterns'))
|
156 |
&& !(in_array($tpath, $reference) && $reference[$tpath]->compressedSize == filesize($tpath))) {
|
157 |
$changed[] = $tpath;
|
158 |
-
}
|
159 |
}
|
160 |
}
|
161 |
-
|
162 |
public function getFolderContentsChangeDate() {
|
163 |
return self::getFolderContentsChangeDateRecursive($this->getPath(), 0, strtotime($this->getTsUpdated()));
|
164 |
}
|
165 |
-
|
166 |
protected static function getFolderContentsChangeDateRecursive($path, $mtime, $refMtime) {
|
167 |
$ignore = array('.','..');
|
168 |
if(!is_writable($path)) {
|
@@ -176,11 +204,11 @@ class ShortPixelFolder extends ShortPixelEntity{
|
|
176 |
if (is_dir($tpath)) {
|
177 |
$mtime = max($mtime, filemtime($tpath));
|
178 |
self::getFolderContentsChangeDateRecursive($tpath, $mtime, $refMtime);
|
179 |
-
}
|
180 |
}
|
181 |
return $mtime;
|
182 |
-
}
|
183 |
-
|
184 |
function getId() {
|
185 |
return $this->id;
|
186 |
}
|
@@ -236,7 +264,7 @@ class ShortPixelFolder extends ShortPixelEntity{
|
|
236 |
function setTsUpdated($tsUpdated) {
|
237 |
$this->tsUpdated = $tsUpdated;
|
238 |
}
|
239 |
-
|
240 |
/**
|
241 |
* needed as callback
|
242 |
* @param ShortPixelFolder $item
|
2 |
|
3 |
class ShortPixelFolder extends ShortPixelEntity{
|
4 |
const META_VERSION = 1;
|
5 |
+
|
6 |
protected $id;
|
7 |
protected $path;
|
8 |
protected $type;
|
10 |
protected $fileCount;
|
11 |
protected $tsCreated;
|
12 |
protected $tsUpdated;
|
13 |
+
|
14 |
protected $excludePatterns;
|
15 |
+
|
16 |
const TABLE_SUFFIX = 'folders';
|
17 |
+
|
18 |
public function __construct($data, $excludePatterns = false) {
|
19 |
parent::__construct($data);
|
20 |
$this->excludePatterns = $excludePatterns;
|
21 |
}
|
22 |
+
|
23 |
public static function checkFolder($folder, $base) {
|
24 |
if(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' && substr($folder, 0, 1) !== '/') {
|
25 |
$folder = '/' . $folder;
|
26 |
}
|
27 |
if(is_dir($folder)) {
|
28 |
return $folder;
|
29 |
+
} elseif(is_dir($base . $folder)) {
|
30 |
return $base . $folder;
|
31 |
}
|
32 |
return false;
|
33 |
}
|
34 |
|
35 |
+
/** This creates the general backup folder **/
|
36 |
+
public static function createBackUpFolder($folder = SHORTPIXEL_BACKUP_FOLDER)
|
37 |
+
{
|
38 |
+
// create backup folder
|
39 |
+
$result = @mkdir($folder, 0777, true);
|
40 |
+
|
41 |
+
if ($result)
|
42 |
+
{
|
43 |
+
self::protectDirectoryListing($folder);
|
44 |
+
}
|
45 |
+
|
46 |
+
return $result;
|
47 |
+
}
|
48 |
+
|
49 |
+
public static function protectDirectoryListing($dirname)
|
50 |
+
{
|
51 |
+
$rules = "Options -Indexes";
|
52 |
+
/* Plugin init is before loading these admin scripts. So it can happen misc.php is not yet loaded */
|
53 |
+
if (! function_exists('insert_with_markers'))
|
54 |
+
{
|
55 |
+
require_once( ABSPATH . 'wp-admin/includes/misc.php' );
|
56 |
+
}
|
57 |
+
insert_with_markers( trailingslashit($dirname) . '.htaccess', 'ShortPixel', $rules);
|
58 |
+
// note - this doesn't bring the same protection. Subdirs without files written will still be listable.
|
59 |
+
file_put_contents(trailingslashit($dirname) . 'index.html', chr(0)); // extra - for non-apache
|
60 |
+
|
61 |
+
}
|
62 |
+
|
63 |
public static function deleteFolder($dirname) {
|
64 |
if (is_dir($dirname))
|
65 |
$dir_handle = opendir($dirname);
|
77 |
@rmdir($dirname);
|
78 |
return true;
|
79 |
}
|
80 |
+
|
81 |
/**
|
82 |
* returns the first from parents that is a parent folder of $folder
|
83 |
* @param string $folder
|
95 |
}
|
96 |
return false;
|
97 |
}
|
98 |
+
|
99 |
/**
|
100 |
* finds the first from the subfolders that has the folder as parent
|
101 |
* @param string $folder
|
132 |
$size += $this->countFiles($tpath);
|
133 |
} elseif(WPShortPixel::_isProcessablePath($tpath, array(), $this->excludePatterns)) {
|
134 |
$size++;
|
135 |
+
}
|
136 |
}
|
137 |
return $size;
|
138 |
+
}
|
139 |
+
|
140 |
public function getFileList($onlyNewerThan = 0) {
|
141 |
$fileListPath = tempnam(SHORTPIXEL_UPLOADS_BASE . '/', 'sp_');
|
142 |
$fileHandle = fopen($fileListPath, 'w+');
|
144 |
fclose($fileHandle);
|
145 |
return $fileListPath;
|
146 |
}
|
147 |
+
|
148 |
protected static function getFileListRecursive($path, $fileHandle, $onlyNewerThan) {
|
149 |
$ignore = array('.','..');
|
150 |
$files = scandir($path);
|
151 |
$add = (filemtime($path) > $onlyNewerThan);
|
152 |
/*
|
153 |
if($add && $onlyNewerThan) {
|
154 |
+
echo("<br> FOLDER UPDATED: " . $path);
|
155 |
}
|
156 |
*/
|
157 |
foreach($files as $t) {
|
161 |
self::getFileListRecursive($tpath, $fileHandle, $onlyNewerThan);
|
162 |
} elseif($add && WPShortPixel::_isProcessablePath($tpath, array(), WPShortPixelSettings::getOpt('excludePatterns'))) {
|
163 |
fwrite($fileHandle, $tpath . "\n");
|
164 |
+
}
|
165 |
}
|
166 |
}
|
167 |
+
|
168 |
public function checkFolderContents($callback) {
|
169 |
$changed = array();
|
170 |
self::checkFolderContentsRecursive($this->getPath(), $changed, $callback);
|
171 |
return $changed;
|
172 |
}
|
173 |
+
|
174 |
protected static function checkFolderContentsRecursive($path, &$changed, $callback) {
|
175 |
$ignore = array('.','..');
|
176 |
$files = scandir($path);
|
183 |
} elseif( WPShortPixel::_isProcessablePath($tpath, array(), WPShortPixelSettings::getOpt('excludePatterns'))
|
184 |
&& !(in_array($tpath, $reference) && $reference[$tpath]->compressedSize == filesize($tpath))) {
|
185 |
$changed[] = $tpath;
|
186 |
+
}
|
187 |
}
|
188 |
}
|
189 |
+
|
190 |
public function getFolderContentsChangeDate() {
|
191 |
return self::getFolderContentsChangeDateRecursive($this->getPath(), 0, strtotime($this->getTsUpdated()));
|
192 |
}
|
193 |
+
|
194 |
protected static function getFolderContentsChangeDateRecursive($path, $mtime, $refMtime) {
|
195 |
$ignore = array('.','..');
|
196 |
if(!is_writable($path)) {
|
204 |
if (is_dir($tpath)) {
|
205 |
$mtime = max($mtime, filemtime($tpath));
|
206 |
self::getFolderContentsChangeDateRecursive($tpath, $mtime, $refMtime);
|
207 |
+
}
|
208 |
}
|
209 |
return $mtime;
|
210 |
+
}
|
211 |
+
|
212 |
function getId() {
|
213 |
return $this->id;
|
214 |
}
|
264 |
function setTsUpdated($tsUpdated) {
|
265 |
$this->tsUpdated = $tsUpdated;
|
266 |
}
|
267 |
+
|
268 |
/**
|
269 |
* needed as callback
|
270 |
* @param ShortPixelFolder $item
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// NOT FOR COMMIT
|
3 |
+
namespace shortPixel;
|
4 |
+
|
5 |
+
/* Image class.
|
6 |
+
*
|
7 |
+
*
|
8 |
+
* - Represents a -single- image.
|
9 |
+
* - Can handle any type
|
10 |
+
* - Usually controllers would use a collection of images
|
11 |
+
* -
|
12 |
+
*
|
13 |
+
*/
|
14 |
+
class shortPixelImage
|
15 |
+
{
|
16 |
+
|
17 |
+
protected $meta; // MetaFacade
|
18 |
+
|
19 |
+
public function __construct($path)
|
20 |
+
{
|
21 |
+
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
}
|
26 |
+
|
27 |
+
/*
|
28 |
+
// do this before putting the meta down, since maybeDump check for last timestamp
|
29 |
+
$URLsAndPATHs = $itemHandler->getURLsAndPATHs(false);
|
30 |
+
$this->maybeDumpFromProcessedOnServer($itemHandler, $URLsAndPATHs);
|
31 |
+
|
32 |
+
*/
|
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortPixelLogger as Log;
|
4 |
+
use ShortPixel\DebugItem as DebugItem;
|
5 |
+
|
6 |
+
|
7 |
+
abstract class ShortPixelModel
|
8 |
+
{
|
9 |
+
protected $model = array();
|
10 |
+
|
11 |
+
public function getData()
|
12 |
+
{
|
13 |
+
$data = array();
|
14 |
+
foreach($this->model as $item => $options)
|
15 |
+
{
|
16 |
+
$data[$item] = $this->{$item};
|
17 |
+
}
|
18 |
+
return $data;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function getModel()
|
22 |
+
{
|
23 |
+
return array_keys($this->model); // only the variable names are public.
|
24 |
+
}
|
25 |
+
|
26 |
+
protected function sanitize($name, $value)
|
27 |
+
{
|
28 |
+
if (! isset($this->model[$name]))
|
29 |
+
return null;
|
30 |
+
|
31 |
+
// if no sanitize method is set, default to strictest string.
|
32 |
+
$sanitize = isset($this->model[$name]['s']) ? $this->model[$name]['s'] : 'string';
|
33 |
+
switch($sanitize)
|
34 |
+
{
|
35 |
+
case "string":
|
36 |
+
$value = $this->sanitizeString($value);
|
37 |
+
break;
|
38 |
+
case "int":
|
39 |
+
$value = $this->sanitizeInteger($value);
|
40 |
+
break;
|
41 |
+
case "boolean":
|
42 |
+
$value = $this->sanitizeBoolean($value);
|
43 |
+
break;
|
44 |
+
case 'array':
|
45 |
+
case 'Array':
|
46 |
+
$value = $this->sanitizeArray($value);
|
47 |
+
break;
|
48 |
+
case 'exception': // for exceptional situations. The data will not be sanitized! Need to do this elsewhere.
|
49 |
+
return $value;
|
50 |
+
break;
|
51 |
+
case 'skip': // skips should not be in any save candidate and not be sanitized.
|
52 |
+
return null;
|
53 |
+
break;
|
54 |
+
}
|
55 |
+
|
56 |
+
return $value;
|
57 |
+
}
|
58 |
+
|
59 |
+
/** Sanitize the passed post data against the model attribute formats.
|
60 |
+
*
|
61 |
+
* @param Array $post The Post data
|
62 |
+
* @param boolean $missing If fields are missing, include them empty in the output
|
63 |
+
* @return Array Sanitized Post Data
|
64 |
+
*/
|
65 |
+
public function getSanitizedData($post, $missing = true)
|
66 |
+
{
|
67 |
+
$postData = array();
|
68 |
+
foreach($post as $name => $value)
|
69 |
+
{
|
70 |
+
$name = sanitize_text_field($name);
|
71 |
+
$value = $this->sanitize($name, $value);
|
72 |
+
if ($value !== null)
|
73 |
+
$postData[$name] = $value;
|
74 |
+
else {
|
75 |
+
Log::addWarn("Provided field $name not part of model " . get_class() );
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
if ($missing)
|
80 |
+
{
|
81 |
+
$model_fields = $this->getModel();
|
82 |
+
$post_fields = array_keys($postData);
|
83 |
+
|
84 |
+
$missing_fields = array_diff($model_fields, $post_fields);
|
85 |
+
foreach($missing_fields as $index => $field_name)
|
86 |
+
{
|
87 |
+
$field_name = sanitize_text_field($field_name);
|
88 |
+
$type = $this->getType($field_name);
|
89 |
+
if ($type === 'boolean')
|
90 |
+
{
|
91 |
+
$postData[$field_name] = 0;
|
92 |
+
}
|
93 |
+
elseif ($type !== false && $type !== 'skip')
|
94 |
+
{
|
95 |
+
$postData[$field_name] = '';
|
96 |
+
}
|
97 |
+
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
return $postData;
|
102 |
+
}
|
103 |
+
|
104 |
+
|
105 |
+
public function getType($name)
|
106 |
+
{
|
107 |
+
if (! isset($this->model[$name]))
|
108 |
+
{
|
109 |
+
return null;
|
110 |
+
Log::addWarn("Provided field $name not part of model " . get_class() );
|
111 |
+
}
|
112 |
+
|
113 |
+
|
114 |
+
$type = isset($this->model[$name]['s']) ? $this->model[$name]['s'] : false;
|
115 |
+
return $type;
|
116 |
+
}
|
117 |
+
|
118 |
+
public function sanitizeString($string)
|
119 |
+
{
|
120 |
+
return (string) sanitize_text_field($string);
|
121 |
+
}
|
122 |
+
public function sanitizeInteger($int)
|
123 |
+
{
|
124 |
+
return intval($int);
|
125 |
+
}
|
126 |
+
public function sanitizeBoolean($bool)
|
127 |
+
{
|
128 |
+
return ($bool) ? true : false;
|
129 |
+
}
|
130 |
+
|
131 |
+
public function sanitizeArray($array)
|
132 |
+
{
|
133 |
+
if (! is_array($array))
|
134 |
+
{
|
135 |
+
Log::addWarn('Field is of type Array, but Array not provided');
|
136 |
+
return null;
|
137 |
+
}
|
138 |
+
$new_array = array();
|
139 |
+
foreach($array as $key => $value)
|
140 |
+
{
|
141 |
+
$newkey = $this->sanitizeString($key);
|
142 |
+
$newval = $this->sanitizeString($value);
|
143 |
+
$new_array[$newkey] = $newval ;
|
144 |
+
}
|
145 |
+
|
146 |
+
return $new_array;
|
147 |
+
}
|
148 |
+
|
149 |
+
}
|
@@ -23,7 +23,7 @@ class ShortPixelTools {
|
|
23 |
|
24 |
public static function namespaceit($name)
|
25 |
{
|
26 |
-
return '\ShortPixel\\' . $name;
|
27 |
}
|
28 |
|
29 |
public static function requestIsFrontendAjax()
|
@@ -88,6 +88,7 @@ class ShortPixelTools {
|
|
88 |
public static function sendJSON($response) {
|
89 |
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
90 |
die(json_encode($response));
|
|
|
91 |
}
|
92 |
|
93 |
|
23 |
|
24 |
public static function namespaceit($name)
|
25 |
{
|
26 |
+
return '\ShortPixel\\' . $name;
|
27 |
}
|
28 |
|
29 |
public static function requestIsFrontendAjax()
|
88 |
public static function sendJSON($response) {
|
89 |
@header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
|
90 |
die(json_encode($response));
|
91 |
+
//wp_send_json($response); // send json proper, dies.
|
92 |
}
|
93 |
|
94 |
|
@@ -1,10 +1,10 @@
|
|
1 |
<?php
|
2 |
|
3 |
class ShortPixelQueue {
|
4 |
-
|
5 |
private $ctrl;
|
6 |
private $settings;
|
7 |
-
|
8 |
const BULK_TYPE_OPTIMIZE = 0;
|
9 |
const BULK_TYPE_RESTORE = 1;
|
10 |
const BULK_TYPE_CLEANUP = 2;
|
@@ -14,12 +14,12 @@ class ShortPixelQueue {
|
|
14 |
const BULK_RUNNING = 1; //bulk is running
|
15 |
const BULK_PAUSED = 2; //bulk is paused
|
16 |
const BULK_FINISHED = 3; //bulk finished
|
17 |
-
|
18 |
public function __construct($controller, $settings) {
|
19 |
$this->ctrl = $controller;
|
20 |
$this->settings = $settings;
|
21 |
}
|
22 |
-
|
23 |
//handling older
|
24 |
public function ShortPixelQueue($controller) {
|
25 |
$this->__construct($controller);
|
@@ -88,42 +88,42 @@ class ShortPixelQueue {
|
|
88 |
protected static function parseQ($items) {
|
89 |
return explode(',', preg_replace("/[^0-9,C-]/", "", $items));
|
90 |
}
|
91 |
-
|
92 |
public function skip($id) {
|
93 |
if(is_array($this->settings->prioritySkip)) {
|
94 |
$this->settings->prioritySkip = array_merge($this->settings->prioritySkip, array($id));
|
95 |
} else {
|
96 |
$this->settings->prioritySkip = array($id);
|
97 |
-
}
|
98 |
}
|
99 |
|
100 |
public function unskip($id) {
|
101 |
$prioSkip = $this->settings->prioritySkip;
|
102 |
$this->settings->prioritySkip = is_array($prioSkip) ? array_diff($prioSkip, array($id)) : array();
|
103 |
}
|
104 |
-
|
105 |
public function allSkipped() {
|
106 |
if( !is_array($this->settings->prioritySkip) ) return false;
|
107 |
count(array_diff($this->get(), $this->settings->prioritySkip));
|
108 |
}
|
109 |
-
|
110 |
public function skippedCount() {
|
111 |
-
return is_array($this->settings->prioritySkip) ? count($this->settings->prioritySkip) : 0;
|
112 |
}
|
113 |
-
|
114 |
public function isSkipped($id) {
|
115 |
return is_array($this->settings->prioritySkip) && in_array($id, $this->settings->prioritySkip);
|
116 |
}
|
117 |
-
|
118 |
public function isPrio($id) {
|
119 |
$prioItems = $this->get();
|
120 |
return is_array($prioItems) && in_array($id, $prioItems);
|
121 |
}
|
122 |
-
|
123 |
public function getSkipped() {
|
124 |
return $this->settings->prioritySkip;
|
125 |
}
|
126 |
-
|
127 |
public function reverse() {
|
128 |
$this->apply('array_reverse');
|
129 |
//$this->settings->priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"] = array_reverse($_SESSION["wp-short-pixel-priorityQueue"]);
|
@@ -162,7 +162,7 @@ class ShortPixelQueue {
|
|
162 |
$count = min(count($priorityQueue), $count);
|
163 |
return(array_slice($priorityQueue, count($priorityQueue) - $count, $count));
|
164 |
}
|
165 |
-
|
166 |
public function getFromPrioAndCheck() {
|
167 |
$idsPrio = $this->get();
|
168 |
|
@@ -183,7 +183,7 @@ class ShortPixelQueue {
|
|
183 |
$this->remove($rId);
|
184 |
}
|
185 |
return $ids;
|
186 |
-
}
|
187 |
|
188 |
public function remove($ID)//remove an ID from priority queue
|
189 |
{
|
@@ -210,7 +210,7 @@ class ShortPixelQueue {
|
|
210 |
$this->closeQ($fp);
|
211 |
return $found;
|
212 |
}
|
213 |
-
|
214 |
public function removeFromFailed($ID) {
|
215 |
$failed = explode(",", $this->settings->failedImages);
|
216 |
$key = array_search($ID, $failed);
|
@@ -218,14 +218,14 @@ class ShortPixelQueue {
|
|
218 |
unset($failed[$key]);
|
219 |
$failed = array_values($failed);
|
220 |
$this->settings->failedImages = implode(",", $failed) ;
|
221 |
-
}
|
222 |
}
|
223 |
-
|
224 |
public function addToFailed($ID) {
|
225 |
$failed = $this->settings->failedImages;
|
226 |
if(!in_array($ID, explode(",", $failed))) {
|
227 |
$this->settings->failedImages = (strlen($failed) ? $failed . "," : "") . $ID;
|
228 |
-
}
|
229 |
}
|
230 |
|
231 |
public function getFailed() {
|
@@ -233,11 +233,11 @@ class ShortPixelQueue {
|
|
233 |
if(!strlen($failed)) return array();
|
234 |
$ret = explode(",", $failed);
|
235 |
$fails = array();
|
236 |
-
foreach($ret as $fail) {
|
237 |
if(ShortPixelMetaFacade::isCustomQueuedId($fail)) {
|
238 |
$meta = $this->ctrl->getSpMetaDao()->getMeta(ShortPixelMetaFacade::stripQueuedIdType($fail));
|
239 |
if($meta) {
|
240 |
-
$fails[] = (object)array("id" => ShortPixelMetaFacade::stripQueuedIdType($fail), "type" => ShortPixelMetaFacade::CUSTOM_TYPE, "meta" => $meta);
|
241 |
}
|
242 |
} else {
|
243 |
$meta = wp_get_attachment_metadata($fail);
|
@@ -255,21 +255,21 @@ class ShortPixelQueue {
|
|
255 |
//$bulkProcessingStatus = get_option('bulkProcessingStatus');
|
256 |
return $this->settings->startBulkId > $this->settings->stopBulkId;
|
257 |
}
|
258 |
-
|
259 |
public function bulkPaused() {
|
260 |
//WPShortPixel::log("Bulk Paused: " . $this->settings->cancelPointer);
|
261 |
return $this->settings->cancelPointer;
|
262 |
}
|
263 |
-
|
264 |
public function bulkRan() {
|
265 |
return $this->settings->bulkEverRan != 0;
|
266 |
}
|
267 |
-
|
268 |
public function processing() {
|
269 |
//WPShortPixel::log("QUEUE: processing(): get:" . json_encode($this->get()));
|
270 |
return $this->bulkRunning() || count($this->get());
|
271 |
}
|
272 |
-
|
273 |
public function getFlagBulkId() {
|
274 |
return $this->settings->flagId;
|
275 |
}
|
@@ -281,7 +281,7 @@ class ShortPixelQueue {
|
|
281 |
public function resetStartBulkId() {
|
282 |
$this->setStartBulkId(ShortPixelMetaFacade::getMaxMediaId());
|
283 |
}
|
284 |
-
|
285 |
public function setStartBulkId($start){
|
286 |
$this->settings->startBulkId = $start;
|
287 |
}
|
@@ -293,12 +293,12 @@ class ShortPixelQueue {
|
|
293 |
public function resetStopBulkId() {
|
294 |
$this->settings->stopBulkId = ShortPixelMetaFacade::getMinMediaId();
|
295 |
}
|
296 |
-
|
297 |
public function setBulkPreviousPercent() {
|
298 |
//processable and already processed
|
299 |
$res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->settings, $this->getFlagBulkId(), $this->settings->stopBulkId);
|
300 |
$this->settings->bulkCount = $res["mainFiles"];
|
301 |
-
|
302 |
//if compression type changed, add also the images with the other compression type
|
303 |
switch (0 + $this->ctrl->getCompressionType()) {
|
304 |
case 2:
|
@@ -310,7 +310,7 @@ class ShortPixelQueue {
|
|
310 |
default: //lossless
|
311 |
$this->settings->bulkAlreadyDoneCount = $res["mainProcessedFiles"] - $res["mainProcLossyFiles"] - $res["mainProcGlossyFiles"];
|
312 |
break;
|
313 |
-
|
314 |
}
|
315 |
//$this->settings->bulkAlreadyDoneCount = $res["mainProcessedFiles"] - $res["mainProc".((0 + $this->ctrl->getCompressionType() == 1) ? "Lossless" : "Lossy")."Files"];
|
316 |
|
@@ -318,41 +318,49 @@ class ShortPixelQueue {
|
|
318 |
if($this->settings->processThumbnails) {
|
319 |
$this->settings->bulkAlreadyDoneCount -= $res["mainUnprocessedThumbs"];
|
320 |
}
|
321 |
-
|
322 |
//percent already done
|
323 |
$this->settings->bulkPreviousPercent = round($this->settings->bulkAlreadyDoneCount / ($this->settings->bulkCount ? $this->settings->bulkCount : 1) * 100);
|
324 |
}
|
325 |
-
|
326 |
public function getBulkToProcess() {
|
327 |
//check numeric as per https://secure.helpscout.net/conversation/764815647/12934?folderId=1117588
|
328 |
if(!is_numeric($this->settings->bulkCount)) $this->settings->bulkCount = 0;
|
329 |
if(!is_numeric($this->settings->bulkAlreadyDoneCount)) $this->settings->bulkAlreadyDoneCount = 0;
|
330 |
return $this->settings->bulkCount - $this->settings->bulkAlreadyDoneCount;
|
331 |
}
|
332 |
-
|
333 |
public function flagBulkStart() {
|
334 |
$this->settings->flagId = $this->settings->startBulkId;
|
335 |
-
$this->settings->bulkProcessingStatus = 'running';//set bulk flag
|
336 |
}
|
337 |
-
|
338 |
public function setBulkType($type) {
|
339 |
$this->settings->bulkType = $type;
|
340 |
}
|
341 |
-
|
342 |
public function getBulkType() {
|
343 |
return $this->settings->bulkType;
|
344 |
}
|
345 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
346 |
public function startBulk($type = self::BULK_TYPE_OPTIMIZE) {
|
347 |
-
$this->resetStartBulkId(); //start downwards from the biggest item ID
|
348 |
$this->resetStopBulkId();
|
349 |
-
$this->flagBulkStart(); //we use this to detect new added files while bulk is running
|
350 |
$this->setBulkPreviousPercent();
|
351 |
$this->resetBulkCurrentlyProcessed();
|
352 |
$this->setBulkType($type);
|
353 |
$this->settings->bulkEverRan = 1;
|
354 |
}
|
355 |
-
|
356 |
public function pauseBulk() {
|
357 |
$cancelPointer = $this->settings->startBulkId;
|
358 |
$bulkStartId = $this->getFlagBulkId();
|
@@ -367,50 +375,51 @@ class ShortPixelQueue {
|
|
367 |
}
|
368 |
$this->stopBulk();
|
369 |
}
|
370 |
-
|
371 |
public function cancelBulk() {
|
372 |
$this->pauseBulk();
|
373 |
WPShortPixel::log("STOP, delete pointer.");
|
374 |
$this->settings->cancelPointer = NULL;
|
375 |
}
|
376 |
-
|
377 |
public function stopBulk() {
|
378 |
$this->settings->startBulkId = ShortPixelMetaFacade::getMaxMediaId();
|
379 |
$this->settings->stopBulkId = $this->settings->startBulkId;
|
380 |
$this->settings->bulkProcessingStatus = null;
|
381 |
return $this->settings->bulkEverRan;
|
382 |
}
|
383 |
-
|
384 |
public function resumeBulk() {
|
385 |
$this->settings->startBulkId = $this->settings->cancelPointer;
|
386 |
$this->settings->stopBulkId = ShortPixelMetaFacade::getMinMediaId();
|
387 |
//$this->settings->setOpt("wp-short-pixel-flag-id", $this->startBulkId);//we use to detect new added files while bulk is running
|
388 |
-
$this->settings->bulkProcessingStatus = 'running';//set bulk flag
|
389 |
$this->settings->cancelPointer = null;
|
390 |
WPShortPixel::log("Resumed: (pause says: " . $this->bulkPaused() . ") Start from: " . $this->settings->startBulkId . " to " . $this->settings->stopBulkId);
|
391 |
}
|
392 |
-
|
393 |
public function resetBulkCurrentlyProcessed() {
|
394 |
$this->settings->bulkCurrentlyProcessed = 0;
|
395 |
}
|
396 |
-
|
397 |
public function incrementBulkCurrentlyProcessed() {
|
398 |
$this->settings->bulkCurrentlyProcessed = $this->settings->bulkCurrentlyProcessed + 1;
|
399 |
}
|
400 |
-
|
401 |
public function markBulkComplete() {
|
402 |
$this->settings->bulkProcessingStatus = null;
|
403 |
$this->settings->cancelPointer = null;
|
|
|
404 |
}
|
405 |
-
|
406 |
public static function resetBulk() {
|
407 |
-
delete_option('wp-short-pixel-bulk-type');
|
408 |
-
delete_option('bulkProcessingStatus');
|
409 |
delete_option( 'wp-short-pixel-cancel-pointer');
|
410 |
delete_option( "wp-short-pixel-flag-id");
|
411 |
$startBulkId = $stopBulkId = ShortPixelMetaFacade::getMaxMediaId();
|
412 |
update_option( 'wp-short-pixel-query-id-stop', $startBulkId, 'no');
|
413 |
-
update_option( 'wp-short-pixel-query-id-start', $startBulkId, 'no');
|
414 |
delete_option( "wp-short-pixel-bulk-previous-percent");
|
415 |
delete_option( "wp-short-pixel-bulk-processed-items");
|
416 |
delete_option('wp-short-pixel-bulk-running-time');
|
@@ -420,12 +429,12 @@ class ShortPixelQueue {
|
|
420 |
delete_option( "wp-short-pixel-bulk-count");
|
421 |
delete_option( "wp-short-pixel-bulk-done-count");
|
422 |
}
|
423 |
-
|
424 |
public static function resetPrio() {
|
425 |
//delete_option( "wp-short-pixel-priorityQueue");
|
426 |
self::set(array());
|
427 |
}
|
428 |
-
|
429 |
public function logBulkProgress() {
|
430 |
$t = time();
|
431 |
$this->incrementBulkCurrentlyProcessed();
|
@@ -438,26 +447,26 @@ class ShortPixelQueue {
|
|
438 |
$this->settings->lastBulkSuccessTime = $t;
|
439 |
}
|
440 |
}
|
441 |
-
|
442 |
public function getBulkPercent() {
|
443 |
$previousPercent = $this->settings->bulkPreviousPercent;
|
444 |
//WPShortPixel::log("QUEUE - BulkPrevPercent: " . $previousPercent . " BulkCurrentlyProcessing: "
|
445 |
// . $this->settings->bulkCurrentlyProcessed . " out of " . $this->getBulkToProcess());
|
446 |
-
|
447 |
if($this->getBulkToProcess() <= 0) return ($this->processing () ? 99: 100);
|
448 |
// return maximum 99%
|
449 |
$percent = $previousPercent + round($this->settings->bulkCurrentlyProcessed / $this->getBulkToProcess()
|
450 |
* (100 - $previousPercent));
|
451 |
|
452 |
//WPShortPixel::log("QUEUE - Calculated Percent: " . $percent);
|
453 |
-
|
454 |
return min(99, $percent);
|
455 |
}
|
456 |
|
457 |
public function getDeltaBulkPercent() {
|
458 |
return $this->getBulkPercent() - $this->settings->bulkPreviousPercent;
|
459 |
}
|
460 |
-
|
461 |
public function getTimeRemaining (){
|
462 |
$p = $this->getBulkPercent();
|
463 |
$pAlready = $this->settings->bulkCount == 0 ? 0 : round($this->settings->bulkAlreadyDoneCount / $this->settings->bulkCount * 100);
|
1 |
<?php
|
2 |
|
3 |
class ShortPixelQueue {
|
4 |
+
|
5 |
private $ctrl;
|
6 |
private $settings;
|
7 |
+
|
8 |
const BULK_TYPE_OPTIMIZE = 0;
|
9 |
const BULK_TYPE_RESTORE = 1;
|
10 |
const BULK_TYPE_CLEANUP = 2;
|
14 |
const BULK_RUNNING = 1; //bulk is running
|
15 |
const BULK_PAUSED = 2; //bulk is paused
|
16 |
const BULK_FINISHED = 3; //bulk finished
|
17 |
+
|
18 |
public function __construct($controller, $settings) {
|
19 |
$this->ctrl = $controller;
|
20 |
$this->settings = $settings;
|
21 |
}
|
22 |
+
|
23 |
//handling older
|
24 |
public function ShortPixelQueue($controller) {
|
25 |
$this->__construct($controller);
|
88 |
protected static function parseQ($items) {
|
89 |
return explode(',', preg_replace("/[^0-9,C-]/", "", $items));
|
90 |
}
|
91 |
+
|
92 |
public function skip($id) {
|
93 |
if(is_array($this->settings->prioritySkip)) {
|
94 |
$this->settings->prioritySkip = array_merge($this->settings->prioritySkip, array($id));
|
95 |
} else {
|
96 |
$this->settings->prioritySkip = array($id);
|
97 |
+
}
|
98 |
}
|
99 |
|
100 |
public function unskip($id) {
|
101 |
$prioSkip = $this->settings->prioritySkip;
|
102 |
$this->settings->prioritySkip = is_array($prioSkip) ? array_diff($prioSkip, array($id)) : array();
|
103 |
}
|
104 |
+
|
105 |
public function allSkipped() {
|
106 |
if( !is_array($this->settings->prioritySkip) ) return false;
|
107 |
count(array_diff($this->get(), $this->settings->prioritySkip));
|
108 |
}
|
109 |
+
|
110 |
public function skippedCount() {
|
111 |
+
return is_array($this->settings->prioritySkip) ? count($this->settings->prioritySkip) : 0;
|
112 |
}
|
113 |
+
|
114 |
public function isSkipped($id) {
|
115 |
return is_array($this->settings->prioritySkip) && in_array($id, $this->settings->prioritySkip);
|
116 |
}
|
117 |
+
|
118 |
public function isPrio($id) {
|
119 |
$prioItems = $this->get();
|
120 |
return is_array($prioItems) && in_array($id, $prioItems);
|
121 |
}
|
122 |
+
|
123 |
public function getSkipped() {
|
124 |
return $this->settings->prioritySkip;
|
125 |
}
|
126 |
+
|
127 |
public function reverse() {
|
128 |
$this->apply('array_reverse');
|
129 |
//$this->settings->priorityQueue = $_SESSION["wp-short-pixel-priorityQueue"] = array_reverse($_SESSION["wp-short-pixel-priorityQueue"]);
|
162 |
$count = min(count($priorityQueue), $count);
|
163 |
return(array_slice($priorityQueue, count($priorityQueue) - $count, $count));
|
164 |
}
|
165 |
+
|
166 |
public function getFromPrioAndCheck() {
|
167 |
$idsPrio = $this->get();
|
168 |
|
183 |
$this->remove($rId);
|
184 |
}
|
185 |
return $ids;
|
186 |
+
}
|
187 |
|
188 |
public function remove($ID)//remove an ID from priority queue
|
189 |
{
|
210 |
$this->closeQ($fp);
|
211 |
return $found;
|
212 |
}
|
213 |
+
|
214 |
public function removeFromFailed($ID) {
|
215 |
$failed = explode(",", $this->settings->failedImages);
|
216 |
$key = array_search($ID, $failed);
|
218 |
unset($failed[$key]);
|
219 |
$failed = array_values($failed);
|
220 |
$this->settings->failedImages = implode(",", $failed) ;
|
221 |
+
}
|
222 |
}
|
223 |
+
|
224 |
public function addToFailed($ID) {
|
225 |
$failed = $this->settings->failedImages;
|
226 |
if(!in_array($ID, explode(",", $failed))) {
|
227 |
$this->settings->failedImages = (strlen($failed) ? $failed . "," : "") . $ID;
|
228 |
+
}
|
229 |
}
|
230 |
|
231 |
public function getFailed() {
|
233 |
if(!strlen($failed)) return array();
|
234 |
$ret = explode(",", $failed);
|
235 |
$fails = array();
|
236 |
+
foreach($ret as $fail) {
|
237 |
if(ShortPixelMetaFacade::isCustomQueuedId($fail)) {
|
238 |
$meta = $this->ctrl->getSpMetaDao()->getMeta(ShortPixelMetaFacade::stripQueuedIdType($fail));
|
239 |
if($meta) {
|
240 |
+
$fails[] = (object)array("id" => ShortPixelMetaFacade::stripQueuedIdType($fail), "type" => ShortPixelMetaFacade::CUSTOM_TYPE, "meta" => $meta);
|
241 |
}
|
242 |
} else {
|
243 |
$meta = wp_get_attachment_metadata($fail);
|
255 |
//$bulkProcessingStatus = get_option('bulkProcessingStatus');
|
256 |
return $this->settings->startBulkId > $this->settings->stopBulkId;
|
257 |
}
|
258 |
+
|
259 |
public function bulkPaused() {
|
260 |
//WPShortPixel::log("Bulk Paused: " . $this->settings->cancelPointer);
|
261 |
return $this->settings->cancelPointer;
|
262 |
}
|
263 |
+
|
264 |
public function bulkRan() {
|
265 |
return $this->settings->bulkEverRan != 0;
|
266 |
}
|
267 |
+
|
268 |
public function processing() {
|
269 |
//WPShortPixel::log("QUEUE: processing(): get:" . json_encode($this->get()));
|
270 |
return $this->bulkRunning() || count($this->get());
|
271 |
}
|
272 |
+
|
273 |
public function getFlagBulkId() {
|
274 |
return $this->settings->flagId;
|
275 |
}
|
281 |
public function resetStartBulkId() {
|
282 |
$this->setStartBulkId(ShortPixelMetaFacade::getMaxMediaId());
|
283 |
}
|
284 |
+
|
285 |
public function setStartBulkId($start){
|
286 |
$this->settings->startBulkId = $start;
|
287 |
}
|
293 |
public function resetStopBulkId() {
|
294 |
$this->settings->stopBulkId = ShortPixelMetaFacade::getMinMediaId();
|
295 |
}
|
296 |
+
|
297 |
public function setBulkPreviousPercent() {
|
298 |
//processable and already processed
|
299 |
$res = WpShortPixelMediaLbraryAdapter::countAllProcessableFiles($this->settings, $this->getFlagBulkId(), $this->settings->stopBulkId);
|
300 |
$this->settings->bulkCount = $res["mainFiles"];
|
301 |
+
|
302 |
//if compression type changed, add also the images with the other compression type
|
303 |
switch (0 + $this->ctrl->getCompressionType()) {
|
304 |
case 2:
|
310 |
default: //lossless
|
311 |
$this->settings->bulkAlreadyDoneCount = $res["mainProcessedFiles"] - $res["mainProcLossyFiles"] - $res["mainProcGlossyFiles"];
|
312 |
break;
|
313 |
+
|
314 |
}
|
315 |
//$this->settings->bulkAlreadyDoneCount = $res["mainProcessedFiles"] - $res["mainProc".((0 + $this->ctrl->getCompressionType() == 1) ? "Lossless" : "Lossy")."Files"];
|
316 |
|
318 |
if($this->settings->processThumbnails) {
|
319 |
$this->settings->bulkAlreadyDoneCount -= $res["mainUnprocessedThumbs"];
|
320 |
}
|
321 |
+
|
322 |
//percent already done
|
323 |
$this->settings->bulkPreviousPercent = round($this->settings->bulkAlreadyDoneCount / ($this->settings->bulkCount ? $this->settings->bulkCount : 1) * 100);
|
324 |
}
|
325 |
+
|
326 |
public function getBulkToProcess() {
|
327 |
//check numeric as per https://secure.helpscout.net/conversation/764815647/12934?folderId=1117588
|
328 |
if(!is_numeric($this->settings->bulkCount)) $this->settings->bulkCount = 0;
|
329 |
if(!is_numeric($this->settings->bulkAlreadyDoneCount)) $this->settings->bulkAlreadyDoneCount = 0;
|
330 |
return $this->settings->bulkCount - $this->settings->bulkAlreadyDoneCount;
|
331 |
}
|
332 |
+
|
333 |
public function flagBulkStart() {
|
334 |
$this->settings->flagId = $this->settings->startBulkId;
|
335 |
+
$this->settings->bulkProcessingStatus = 'running';//set bulk flag
|
336 |
}
|
337 |
+
|
338 |
public function setBulkType($type) {
|
339 |
$this->settings->bulkType = $type;
|
340 |
}
|
341 |
+
|
342 |
public function getBulkType() {
|
343 |
return $this->settings->bulkType;
|
344 |
}
|
345 |
+
|
346 |
+
// hack
|
347 |
+
public function getBulkTypeForDisplay()
|
348 |
+
{
|
349 |
+
$bulk = $this->settings->bulkType;
|
350 |
+
$this->settings->bulkType = null;
|
351 |
+
return $bulk;
|
352 |
+
}
|
353 |
+
|
354 |
public function startBulk($type = self::BULK_TYPE_OPTIMIZE) {
|
355 |
+
$this->resetStartBulkId(); //start downwards from the biggest item ID
|
356 |
$this->resetStopBulkId();
|
357 |
+
$this->flagBulkStart(); //we use this to detect new added files while bulk is running
|
358 |
$this->setBulkPreviousPercent();
|
359 |
$this->resetBulkCurrentlyProcessed();
|
360 |
$this->setBulkType($type);
|
361 |
$this->settings->bulkEverRan = 1;
|
362 |
}
|
363 |
+
|
364 |
public function pauseBulk() {
|
365 |
$cancelPointer = $this->settings->startBulkId;
|
366 |
$bulkStartId = $this->getFlagBulkId();
|
375 |
}
|
376 |
$this->stopBulk();
|
377 |
}
|
378 |
+
|
379 |
public function cancelBulk() {
|
380 |
$this->pauseBulk();
|
381 |
WPShortPixel::log("STOP, delete pointer.");
|
382 |
$this->settings->cancelPointer = NULL;
|
383 |
}
|
384 |
+
|
385 |
public function stopBulk() {
|
386 |
$this->settings->startBulkId = ShortPixelMetaFacade::getMaxMediaId();
|
387 |
$this->settings->stopBulkId = $this->settings->startBulkId;
|
388 |
$this->settings->bulkProcessingStatus = null;
|
389 |
return $this->settings->bulkEverRan;
|
390 |
}
|
391 |
+
|
392 |
public function resumeBulk() {
|
393 |
$this->settings->startBulkId = $this->settings->cancelPointer;
|
394 |
$this->settings->stopBulkId = ShortPixelMetaFacade::getMinMediaId();
|
395 |
//$this->settings->setOpt("wp-short-pixel-flag-id", $this->startBulkId);//we use to detect new added files while bulk is running
|
396 |
+
$this->settings->bulkProcessingStatus = 'running';//set bulk flag
|
397 |
$this->settings->cancelPointer = null;
|
398 |
WPShortPixel::log("Resumed: (pause says: " . $this->bulkPaused() . ") Start from: " . $this->settings->startBulkId . " to " . $this->settings->stopBulkId);
|
399 |
}
|
400 |
+
|
401 |
public function resetBulkCurrentlyProcessed() {
|
402 |
$this->settings->bulkCurrentlyProcessed = 0;
|
403 |
}
|
404 |
+
|
405 |
public function incrementBulkCurrentlyProcessed() {
|
406 |
$this->settings->bulkCurrentlyProcessed = $this->settings->bulkCurrentlyProcessed + 1;
|
407 |
}
|
408 |
+
|
409 |
public function markBulkComplete() {
|
410 |
$this->settings->bulkProcessingStatus = null;
|
411 |
$this->settings->cancelPointer = null;
|
412 |
+
// $this->settings->bulkType = null;
|
413 |
}
|
414 |
+
|
415 |
public static function resetBulk() {
|
416 |
+
delete_option('wp-short-pixel-bulk-type');
|
417 |
+
delete_option('bulkProcessingStatus');
|
418 |
delete_option( 'wp-short-pixel-cancel-pointer');
|
419 |
delete_option( "wp-short-pixel-flag-id");
|
420 |
$startBulkId = $stopBulkId = ShortPixelMetaFacade::getMaxMediaId();
|
421 |
update_option( 'wp-short-pixel-query-id-stop', $startBulkId, 'no');
|
422 |
+
update_option( 'wp-short-pixel-query-id-start', $startBulkId, 'no');
|
423 |
delete_option( "wp-short-pixel-bulk-previous-percent");
|
424 |
delete_option( "wp-short-pixel-bulk-processed-items");
|
425 |
delete_option('wp-short-pixel-bulk-running-time');
|
429 |
delete_option( "wp-short-pixel-bulk-count");
|
430 |
delete_option( "wp-short-pixel-bulk-done-count");
|
431 |
}
|
432 |
+
|
433 |
public static function resetPrio() {
|
434 |
//delete_option( "wp-short-pixel-priorityQueue");
|
435 |
self::set(array());
|
436 |
}
|
437 |
+
|
438 |
public function logBulkProgress() {
|
439 |
$t = time();
|
440 |
$this->incrementBulkCurrentlyProcessed();
|
447 |
$this->settings->lastBulkSuccessTime = $t;
|
448 |
}
|
449 |
}
|
450 |
+
|
451 |
public function getBulkPercent() {
|
452 |
$previousPercent = $this->settings->bulkPreviousPercent;
|
453 |
//WPShortPixel::log("QUEUE - BulkPrevPercent: " . $previousPercent . " BulkCurrentlyProcessing: "
|
454 |
// . $this->settings->bulkCurrentlyProcessed . " out of " . $this->getBulkToProcess());
|
455 |
+
|
456 |
if($this->getBulkToProcess() <= 0) return ($this->processing () ? 99: 100);
|
457 |
// return maximum 99%
|
458 |
$percent = $previousPercent + round($this->settings->bulkCurrentlyProcessed / $this->getBulkToProcess()
|
459 |
* (100 - $previousPercent));
|
460 |
|
461 |
//WPShortPixel::log("QUEUE - Calculated Percent: " . $percent);
|
462 |
+
|
463 |
return min(99, $percent);
|
464 |
}
|
465 |
|
466 |
public function getDeltaBulkPercent() {
|
467 |
return $this->getBulkPercent() - $this->settings->bulkPreviousPercent;
|
468 |
}
|
469 |
+
|
470 |
public function getTimeRemaining (){
|
471 |
$p = $this->getBulkPercent();
|
472 |
$pAlready = $this->settings->bulkCount == 0 ? 0 : round($this->settings->bulkAlreadyDoneCount / $this->settings->bulkCount * 100);
|
@@ -0,0 +1,357 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
?>
|
4 |
+
|
5 |
+
<section id="tab-adv-settings" class="clearfix <?php echo ($this->display_part == 'adv-settings') ? ' sel-tab ' :''; ?> ">
|
6 |
+
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-adv-settings"><?php _e('Advanced','shortpixel-image-optimiser');?></a></h2>
|
7 |
+
|
8 |
+
<?php
|
9 |
+
$deliverWebpAlteredDisabled = '';
|
10 |
+
$deliverWebpUnalteredDisabled = '';
|
11 |
+
$deliverWebpAlteredDisabledNotice = false;
|
12 |
+
$deliverWebpUnalteredLabel ='';
|
13 |
+
|
14 |
+
if( $this->is_nginx ){
|
15 |
+
$deliverWebpUnaltered = ''; // Uncheck
|
16 |
+
$deliverWebpUnalteredDisabled = 'disabled'; // Disable
|
17 |
+
$deliverWebpUnalteredLabel = __('It looks like you\'re running your site on an NginX server. This means that you can only achieve this functionality by directly configuring the server config files. Please follow this link for instructions on how to achieve this:','shortpixel-image-optimiser')." <a href=\"javascript:void(0)\" data-beacon-article=\"5bfeb9de2c7d3a31944e78ee\">Open article</a>";
|
18 |
+
} else {
|
19 |
+
if( !$this->is_htaccess_writable ){
|
20 |
+
$deliverWebpUnalteredDisabled = 'disabled'; // Disable
|
21 |
+
if( $deliverWebp == 3 ){
|
22 |
+
$deliverWebpAlteredDisabled = 'disabled'; // Disable
|
23 |
+
$deliverWebpUnalteredLabel = __('It looks like you recently moved from an Apache server to an NGINX server, while the option to use .htacces was in use. Please follow this tutorial to see how you could implement by yourself this functionality, outside of the WP plugin. ','shortpixel-image-optimiser');
|
24 |
+
} else {
|
25 |
+
$deliverWebpUnalteredLabel = __('It looks like your .htaccess file cannot be written. Please fix this and then return to refresh this page to enable this option.','shortpixel-image-optimiser');
|
26 |
+
}
|
27 |
+
} elseif (strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') !== false) {
|
28 |
+
// Show a message about the risks and caveats of serving WEBP images via .htaccess
|
29 |
+
$deliverWebpUnalteredLabel = '<span style="color: initial;">'.__('Based on testing your particular hosting configuration, we determined that your server','shortpixel-image-optimiser').
|
30 |
+
' <img src="'. plugins_url( 'res/img/test.jpg' , SHORTPIXEL_PLUGIN_FILE) .'"> '.
|
31 |
+
__('serve the WEBP versions of the JPEG files seamlessly, via .htaccess.','shortpixel-image-optimiser').' <a href="javascript:void(0)" data-beacon-article="5c1d050e04286304a71d9ce4">Open article to read more about this.</a></span>';
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
|
36 |
+
|
37 |
+
$excludePatterns = '';
|
38 |
+
if($view->data->excludePatterns) {
|
39 |
+
foreach($view->data->excludePatterns as $item) {
|
40 |
+
$excludePatterns .= $item['type'] . ":" . $item['value'] . ", ";
|
41 |
+
}
|
42 |
+
$excludePatterns = substr($excludePatterns, 0, -2);
|
43 |
+
}
|
44 |
+
?>
|
45 |
+
|
46 |
+
<div class="wp-shortpixel-options wp-shortpixel-tab-content" style='visibility: hidden'>
|
47 |
+
<table class="form-table">
|
48 |
+
<tbody>
|
49 |
+
<tr>
|
50 |
+
<th scope="row"><label for="additional-media"><?php _e('Additional media folders','shortpixel-image-optimiser');?></label></th>
|
51 |
+
<td>
|
52 |
+
<span style="display:none;">Current PHP version: <?php echo(phpversion()) ?></span>
|
53 |
+
<?php if($view->customFolders) { ?>
|
54 |
+
<table class="shortpixel-folders-list">
|
55 |
+
<tr style="font-weight: bold;">
|
56 |
+
<td><?php _e('Folder name','shortpixel-image-optimiser');?></td>
|
57 |
+
<td><?php _e('Type &<br>Status','shortpixel-image-optimiser');?></td>
|
58 |
+
<td><?php _e('Files','shortpixel-image-optimiser');?></td>
|
59 |
+
<td><?php _e('Last change','shortpixel-image-optimiser');?></td>
|
60 |
+
<td></td>
|
61 |
+
</tr>
|
62 |
+
<?php foreach($view->customFolders as $folder) {
|
63 |
+
$typ = $folder->getType();
|
64 |
+
$typ = $typ ? $typ . "<br>" : "";
|
65 |
+
$stat = $this->shortPixel->getSpMetaDao()->getFolderOptimizationStatus($folder->getId());
|
66 |
+
$cnt = $folder->getFileCount();
|
67 |
+
$st = ($cnt == 0
|
68 |
+
? __("Empty",'shortpixel-image-optimiser')
|
69 |
+
: ($stat->Total == $stat->Optimized
|
70 |
+
? __("Optimized",'shortpixel-image-optimiser')
|
71 |
+
: ($stat->Optimized + $stat->Pending > 0 ? __("Pending",'shortpixel-image-optimiser') : __("Waiting",'shortpixel-image-optimiser'))));
|
72 |
+
|
73 |
+
$err = $stat->Failed > 0 && !$st == __("Empty",'shortpixel-image-optimiser') ? " ({$stat->Failed} failed)" : "";
|
74 |
+
|
75 |
+
$action = ($st == __("Optimized",'shortpixel-image-optimiser') || $st == __("Empty",'shortpixel-image-optimiser') ? __("Stop monitoring",'shortpixel-image-optimiser') : __("Stop optimizing",'shortpixel-image-optimiser'));
|
76 |
+
|
77 |
+
$fullStat = $st == __("Empty",'shortpixel-image-optimiser') ? "" : __("Optimized",'shortpixel-image-optimiser') . ": " . $stat->Optimized . ", "
|
78 |
+
. __("Pending",'shortpixel-image-optimiser') . ": " . $stat->Pending . ", " . __("Waiting",'shortpixel-image-optimiser') . ": " . $stat->Waiting . ", "
|
79 |
+
. __("Failed",'shortpixel-image-optimiser') . ": " . $stat->Failed;
|
80 |
+
?>
|
81 |
+
<tr>
|
82 |
+
<td>
|
83 |
+
<?php echo($folder->getPath()); ?>
|
84 |
+
</td>
|
85 |
+
<td>
|
86 |
+
<?php if(!($st == "Empty")) { ?>
|
87 |
+
<a href="javascript:none();" title="<?php echo $fullStat; ?>" style="text-decoration: none;">
|
88 |
+
<img src='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/info-icon.png' ));?>' style="margin-bottom: -2px;"/>
|
89 |
+
</a> <?php } echo($typ.$st.$err); ?>
|
90 |
+
|
91 |
+
</td>
|
92 |
+
<td>
|
93 |
+
<?php echo($cnt); ?> files
|
94 |
+
</td>
|
95 |
+
<td>
|
96 |
+
<?php echo($folder->getTsUpdated()); ?>
|
97 |
+
</td>
|
98 |
+
<td>
|
99 |
+
<input type="button" class="button remove-folder-button" data-value="<?php echo($folder->getPath()); ?>" title="<?php echo($action . " " . $folder->getPath()); ?>" value="<?php echo $action;?>">
|
100 |
+
<input type="button" style="display:none;" class="button button-alert recheck-folder-button" data-value="<?php echo($folder->getPath()); ?>"
|
101 |
+
title="<?php _e('Full folder refresh, check each file of the folder if it changed since it was optimized. Might take up to 1 min. for big folders.','shortpixel-image-optimiser');?>"
|
102 |
+
value="<?php _e('Refresh','shortpixel-image-optimiser');?>">
|
103 |
+
</td>
|
104 |
+
</tr>
|
105 |
+
<?php }?>
|
106 |
+
</table>
|
107 |
+
<?php } ?>
|
108 |
+
|
109 |
+
<div class='addCustomFolder'>
|
110 |
+
|
111 |
+
<input type="hidden" name="removeFolder" id="removeFolder"/>
|
112 |
+
<p class='add-folder-text'><strong><?php _e('Add a custom folder', 'shortpixel-image-optimiser'); ?></strong></p>
|
113 |
+
<input type="text" name="addCustomFolderView" id="addCustomFolderView" class="regular-text" value="" disabled style="">
|
114 |
+
<input type="hidden" name="addCustomFolder" id="addCustomFolder" value=""/>
|
115 |
+
<input type="hidden" id="customFolderBase" value="<?php echo $this->shortPixel->getCustomFolderBase(); ?>">
|
116 |
+
|
117 |
+
<a class="button select-folder-button" title="<?php _e('Select the images folder on your server.','shortpixel-image-optimiser');?>" href="javascript:void(0);">
|
118 |
+
<?php _e('Select ...','shortpixel-image-optimiser');?>
|
119 |
+
</a>
|
120 |
+
<input type="submit" name="save" id="saveAdvAddFolder" class="button button-primary hidden" title="<?php _e('Add this Folder','shortpixel-image-optimiser');?>" value="<?php _e('Add this Folder','shortpixel-image-optimiser');?>">
|
121 |
+
<p class="settings-info">
|
122 |
+
<?php _e('Use the Select... button to select site folders. ShortPixel will optimize images and PDFs from the specified folders and their subfolders. The optimization status for each image or PDF in these folders can be seen in the <a href="upload.php?page=wp-short-pixel-custom">Other Media list</a>, under the Media menu.','shortpixel-image-optimiser');?>
|
123 |
+
<a href="https://blog.shortpixel.com/optimize-images-outside-media-library/" target="_blank" class="shortpixel-help-link">
|
124 |
+
<span class="dashicons dashicons-editor-help"></span><?php _e('More info','shortpixel-image-optimiser');?>
|
125 |
+
</a>
|
126 |
+
</p>
|
127 |
+
|
128 |
+
<div class="sp-modal-shade sp-folder-picker-shade"></div>
|
129 |
+
<div class="shortpixel-modal modal-folder-picker shortpixel-hide">
|
130 |
+
<div class="sp-modal-title"><?php _e('Select the images folder','shortpixel-image-optimiser');?></div>
|
131 |
+
<div class="sp-folder-picker"></div>
|
132 |
+
<input type="button" class="button button-info select-folder-cancel" value="<?php _e('Cancel','shortpixel-image-optimiser');?>" style="margin-right: 30px;">
|
133 |
+
<input type="button" class="button button-primary select-folder" value="<?php _e('Select','shortpixel-image-optimiser');?>">
|
134 |
+
</div>
|
135 |
+
|
136 |
+
<script>
|
137 |
+
jQuery(document).ready(function () {
|
138 |
+
ShortPixel.initFolderSelector();
|
139 |
+
});
|
140 |
+
</script>
|
141 |
+
</div> <!-- end of AddCustomFolder -->
|
142 |
+
</td>
|
143 |
+
</tr>
|
144 |
+
<?php if($this->has_nextgen) { ?>
|
145 |
+
<tr>
|
146 |
+
<th scope="row"><?php _e('Optimize NextGen galleries','shortpixel-image-optimiser');?></th>
|
147 |
+
<td>
|
148 |
+
<input name="includeNextGen" type="checkbox" id="nextGen" value='1' <?php echo checked($view->data->includeNextGen,'1' );?>> <label for="nextGen"><?php _e('Optimize NextGen galleries.','shortpixel-image-optimiser');?></label>
|
149 |
+
<p class="settings-info">
|
150 |
+
<?php _e('Check this to add all your current NextGen galleries to the custom folders list and to also have all the future NextGen galleries and images optimized automatically by ShortPixel.','shortpixel-image-optimiser');?>
|
151 |
+
</p>
|
152 |
+
</td>
|
153 |
+
</tr>
|
154 |
+
<?php } ?>
|
155 |
+
<tr>
|
156 |
+
<th scope="row"><?php _e('Convert PNG images to JPEG','shortpixel-image-optimiser');?></th>
|
157 |
+
<td>
|
158 |
+
<input name="png2jpg" type="checkbox" id="png2jpg" value="1" <?php checked( ($view->data->png2jpg > 0), true);?> <?php echo($this->is_gd_installed ? '' : 'disabled') ?>>
|
159 |
+
<label for="png2jpg"><?php _e('Automatically convert the PNG images to JPEG if possible.','shortpixel-image-optimiser');
|
160 |
+
if(!$this->is_gd_installed) {echo(" <span style='color:red;'>" . __('You need PHP GD for this. Please ask your hosting to install it.','shortpixel-image-optimiser') . "</span>");}
|
161 |
+
?></label>
|
162 |
+
<p class="settings-info">
|
163 |
+
<?php _e('Converts all PNGs that don\'t have transparent pixels to JPEG. This can dramatically reduce the file size, especially if you have camera pictures that are saved in PNG format. The plugin will also search for references of the image in posts and will replace them.','shortpixel-image-optimiser');?>
|
164 |
+
<strong><?php _e('The image will NOT be converted if the resulting JPEG is larger than the original PNG.','shortpixel-image-optimiser');?></strong>
|
165 |
+
</p><br>
|
166 |
+
<?php // @todo Issue with this. png2jpg > 0, is force ?>
|
167 |
+
<input name="png2jpgForce" type="checkbox" id="png2jpgForce" value="1" <?php checked(($view->data->png2jpg > 1), true);?> <?php echo($this->is_gd_installed ? '' : 'disabled') ?>>
|
168 |
+
<label for="png2jpgForce">
|
169 |
+
<?php _e('Also force the conversion of images with transparency.','shortpixel-image-optimiser'); ?>
|
170 |
+
</label>
|
171 |
+
</td>
|
172 |
+
</tr>
|
173 |
+
<tr class='exif_warning view-notice-row'>
|
174 |
+
<th scope="row"> </th>
|
175 |
+
<td>
|
176 |
+
<div class='view-notice warning'><p><?php printf(__('Warning - Converting from PNG to JPG will %s not %s keep the EXIF-information!'), "<strong>","</strong>"); ?></p></div>
|
177 |
+
</td>
|
178 |
+
</tr>
|
179 |
+
<tr>
|
180 |
+
<th scope="row"><?php _e('CMYK to RGB conversion','shortpixel-image-optimiser');?></th>
|
181 |
+
<td>
|
182 |
+
<input name="cmyk2rgb" type="checkbox" id="cmyk2rgb" value="1" <?php checked( $view->data->CMYKtoRGBconversion, "1" );?>>
|
183 |
+
<label for="cmyk2rgb"><?php _e('Adjust your images\' colours for computer and mobile screen display.','shortpixel-image-optimiser');?></label>
|
184 |
+
<p class="settings-info"><?php _e('Images for the web only need RGB format and converting them from CMYK to RGB makes them smaller.','shortpixel-image-optimiser');?></p>
|
185 |
+
</td>
|
186 |
+
</tr>
|
187 |
+
<tr>
|
188 |
+
<th scope="row"><?php _e('WebP Images:','shortpixel-image-optimiser');?></th>
|
189 |
+
<td>
|
190 |
+
<input name="createWebp" type="checkbox" id="createWebp" value="1" <?php checked( $view->data->createWebp, "1" );?>>
|
191 |
+
<label for="createWebp">
|
192 |
+
<?php _e('Also create <a href="http://blog.shortpixel.com/how-webp-images-can-speed-up-your-site/" target="_blank">WebP versions</a> of the images, <strong>for free</strong>.','shortpixel-image-optimiser');?>
|
193 |
+
</label>
|
194 |
+
<p class="settings-info">
|
195 |
+
<?php _e('WebP images can be up to three times smaller than PNGs and 25% smaller than JPGs. Choosing this option <strong>does not use up additional credits</strong>.','shortpixel-image-optimiser');?>
|
196 |
+
<a href="http://blog.shortpixel.com/how-webp-images-can-speed-up-your-site/" target="_blank" class="shortpixel-help-link">
|
197 |
+
<span class="dashicons dashicons-editor-help"></span><?php _e('More info','shortpixel-image-optimiser');?>
|
198 |
+
</a>
|
199 |
+
</p>
|
200 |
+
<div class="deliverWebpSettings">
|
201 |
+
<input name="deliverWebp" type="checkbox" id="deliverWebp" value="1" <?php checked( ($view->data->deliverWebp > 0), true);?>>
|
202 |
+
<label for="deliverWebp">
|
203 |
+
<?php _e('Deliver the WebP versions of the images in the front-end:','shortpixel-image-optimiser');?>
|
204 |
+
</label>
|
205 |
+
<ul class="deliverWebpTypes">
|
206 |
+
<li>
|
207 |
+
<input type="radio" name="deliverWebpType" id="deliverWebpAltered" <?php checked( ($view->data->deliverWebp >= 1 && $view->data->deliverWebp <= 2), true); ?> <?php echo( $deliverWebpAlteredDisabled );?> value="deliverWebpAltered">
|
208 |
+
<label for="deliverWebpAltered">
|
209 |
+
<?php _e('Using the <PICTURE> tag syntax','shortpixel-image-optimiser');?>
|
210 |
+
</label>
|
211 |
+
<?php if($deliverWebpAlteredDisabledNotice){ ?>
|
212 |
+
<p class="sp-notice">
|
213 |
+
<?php _e('After the option to work on .htaccess was selected, the .htaccess file has become unaccessible / readonly. Please make the .htaccess file writeable again to be able to further set up this option.','shortpixel-image-optimiser')?>
|
214 |
+
</p>
|
215 |
+
<?php } ?>
|
216 |
+
<p class="settings-info">
|
217 |
+
<?php _e('Each <img> will be replaced with a <picture> tag that will also provide the WebP image as a choice for browsers that support it. Also loads the picturefill.js for browsers that don\'t support the <picture> tag. You don\'t need to activate this if you\'re using the Cache Enabler plugin because your WebP images are already handled by this plugin. <strong>Please make a test before using this option</strong>, as if the styles that your theme is using rely on the position of your <img> tag, you might experience display problems.','shortpixel-image-optimiser'); ?>
|
218 |
+
<strong><?php _e('You can revert anytime to the previous state by just deactivating the option.','shortpixel-image-optimiser'); ?></strong>
|
219 |
+
</p>
|
220 |
+
<ul class="deliverWebpAlteringTypes">
|
221 |
+
<li>
|
222 |
+
<input type="radio" name="deliverWebpAlteringType" id="deliverWebpAlteredWP" <?php checked(($view->data->deliverWebp == 2), true);?> value="deliverWebpAlteredWP">
|
223 |
+
<label for="deliverWebpAlteredWP">
|
224 |
+
<?php _e('Only via Wordpress hooks (like the_content, the_excerpt, etc)');?>
|
225 |
+
</label>
|
226 |
+
</li>
|
227 |
+
<li>
|
228 |
+
<input type="radio" name="deliverWebpAlteringType" id="deliverWebpAlteredGlobal" <?php checked(($view->data->deliverWebp == 1),true)?> value="deliverWebpAlteredGlobal">
|
229 |
+
<label for="deliverWebpAlteredGlobal">
|
230 |
+
<?php _e('Global (processes the whole output buffer before sending the HTML to the browser)','shortpixel-image-optimiser');?>
|
231 |
+
</label>
|
232 |
+
</li>
|
233 |
+
</ul>
|
234 |
+
</li>
|
235 |
+
<li>
|
236 |
+
<input type="radio" name="deliverWebpType" id="deliverWebpUnaltered" <?php checked(($view->data->deliverWebp == 3), true);?> <?php echo( $deliverWebpUnalteredDisabled );?> value="deliverWebpUnaltered">
|
237 |
+
<label for="deliverWebpUnaltered">
|
238 |
+
<?php _e('Without altering the page code (via .htaccess)','shortpixel-image-optimiser')?>
|
239 |
+
</label>
|
240 |
+
<?php if($deliverWebpUnalteredLabel){ ?>
|
241 |
+
<p class="sp-notice">
|
242 |
+
<?php echo( $deliverWebpUnalteredLabel );?>
|
243 |
+
</p>
|
244 |
+
<?php } ?>
|
245 |
+
</li>
|
246 |
+
</ul>
|
247 |
+
</div>
|
248 |
+
</td>
|
249 |
+
</tr>
|
250 |
+
<tr>
|
251 |
+
<th scope="row"><?php _e('Optimize Retina images','shortpixel-image-optimiser');?></th>
|
252 |
+
<td>
|
253 |
+
<input name="optimizeRetina" type="checkbox" id="optimizeRetina" value="1" <?php checked( $view->data->optimizeRetina, "1"); ?>>
|
254 |
+
<label for="optimizeRetina"><?php _e('Also optimize the Retina images (@2x) if they exist.','shortpixel-image-optimiser');?></label>
|
255 |
+
<p class="settings-info">
|
256 |
+
<?php _e('If you have a Retina plugin that generates Retina-specific images (@2x), ShortPixel can optimize them too, alongside the regular Media Library images and thumbnails.','shortpixel-image-optimiser');?>
|
257 |
+
<a href="http://blog.shortpixel.com/how-to-use-optimized-retina-images-on-your-wordpress-site-for-best-user-experience-on-apple-devices/" target="_blank" class="shortpixel-help-link">
|
258 |
+
<span class="dashicons dashicons-editor-help"></span><?php _e('More info','shortpixel-image-optimiser');?>
|
259 |
+
</a>
|
260 |
+
</p>
|
261 |
+
</td>
|
262 |
+
</tr>
|
263 |
+
<tr>
|
264 |
+
<th scope="row"><?php _e('Optimize other thumbs','shortpixel-image-optimiser');?></th>
|
265 |
+
<td>
|
266 |
+
<input name="optimizeUnlisted" type="checkbox" id="optimizeUnlisted" value="1" <?php checked( $view->data->optimizeUnlisted, "1" );?>>
|
267 |
+
<label for="optimizeUnlisted"><?php _e('Also optimize the unlisted thumbs if found.','shortpixel-image-optimiser');?></label>
|
268 |
+
<p class="settings-info">
|
269 |
+
<?php _e('Some plugins create thumbnails which are not registered in the metadata but instead only create them alongside the other thumbnails. Let ShortPixel optimize them as well.','shortpixel-image-optimiser');?>
|
270 |
+
</p>
|
271 |
+
</td>
|
272 |
+
</tr>
|
273 |
+
<tr>
|
274 |
+
<th scope="row"><?php _e('Optimize PDFs','shortpixel-image-optimiser');?></th>
|
275 |
+
<td>
|
276 |
+
<input name="optimizePdfs" type="checkbox" id="optimizePdfs" value="1" <?php checked( $view->data->optimizePdfs, "1" );?>>
|
277 |
+
<label for="optimizePdfs"><?php _e('Automatically optimize PDF documents.','shortpixel-image-optimiser');?></label>
|
278 |
+
</td>
|
279 |
+
</tr>
|
280 |
+
<tr>
|
281 |
+
<th scope="row"><label for="excludePatterns"><?php _e('Exclude patterns','shortpixel-image-optimiser');?></label></th>
|
282 |
+
<td>
|
283 |
+
<input name="excludePatterns" type="text" id="excludePatterns" value="<?php echo( $excludePatterns );?>" class="regular-text" placeholder="<?php
|
284 |
+
_e('name:keepbig, path:/ignore_regex/i, size:1000x2000','shortpixel-image-optimiser');?>">
|
285 |
+
<?php _e('Exclude certain images from being optimized, based on patterns.','shortpixel-image-optimiser');?>
|
286 |
+
<p class="settings-info">
|
287 |
+
<?php _e('Add patterns separated by comma. A pattern consist of a <strong>type:value</strong> pair; the accepted types are
|
288 |
+
<strong>"name"</strong>, <strong>"path"</strong> and <strong>"size"</strong>.
|
289 |
+
A file will be excluded if it matches any of the patterns.
|
290 |
+
<br>For a <strong>"name"</strong> pattern only the filename will be matched but for a <strong>"path"</strong>,
|
291 |
+
all the path will be matched (useful for excluding certain subdirectories altoghether).
|
292 |
+
For these you can also use regular expressions accepted by preg_match, but without "," or ":".
|
293 |
+
A pattern will be considered a regex if it starts with a "/" and is valid.
|
294 |
+
<br>For the <strong>"size"</strong> type,
|
295 |
+
which applies only to Media Library images, <strong>the main images (not thumbnails)</strong> that have the size in the specified range will be excluded.
|
296 |
+
The format for the "size" exclude is: <strong>minWidth</strong>-<strong>maxWidth</strong>x<strong>minHeight</strong>-<strong>maxHeight</strong>, for example <strong>size:1000-1100x2000-2200</strong>. You can also specify a precise size, as <strong>1000x2000</strong>.','shortpixel-image-optimiser');?>
|
297 |
+
<a href="http://blog.shortpixel.com/shortpixel-how-to-exclude-images-and-folders-from-optimization/" target="_blank" class="shortpixel-help-link">
|
298 |
+
<span class="dashicons dashicons-editor-help"></span><?php _e('More info','shortpixel-image-optimiser');?>
|
299 |
+
</a>
|
300 |
+
</p>
|
301 |
+
</td>
|
302 |
+
</tr>
|
303 |
+
<tr>
|
304 |
+
<th scope="row"><label for="authentication"><?php _e('HTTP AUTH credentials','shortpixel-image-optimiser');?></label></th>
|
305 |
+
<td>
|
306 |
+
<input name="siteAuthUser" type="text" id="siteAuthUser" value="<?php echo( stripslashes(esc_html($view->data->siteAuthUser )));?>" class="regular-text" placeholder="<?php _e('User','shortpixel-image-optimiser');?>"><br>
|
307 |
+
<input name="siteAuthPass" type="text" id="siteAuthPass" value="<?php echo( stripslashes(esc_html($view->data->siteAuthPass )));?>" class="regular-text" placeholder="<?php _e('Password','shortpixel-image-optimiser');?>">
|
308 |
+
<p class="settings-info">
|
309 |
+
<?php _e('Only fill in these fields if your site (front-end) is not publicly accessible and visitors need a user/pass to connect to it. If you don\'t know what is this then just <strong>leave the fields empty</strong>.','shortpixel-image-optimiser');?>
|
310 |
+
</p>
|
311 |
+
</td>
|
312 |
+
</tr>
|
313 |
+
<tr>
|
314 |
+
<th scope="row"><?php _e('Process in front-end','shortpixel-image-optimiser');?></th>
|
315 |
+
<td>
|
316 |
+
<input name="frontBootstrap" type="checkbox" id="frontBootstrap" value="1" <?php checked( $view->data->frontBootstrap, '1' );?>>
|
317 |
+
<label for="frontBootstrap"><?php _e('Automatically optimize images added by users in front end.','shortpixel-image-optimiser');?></label>
|
318 |
+
<p class="settings-info">
|
319 |
+
<?php _e('Check this if you have users that add images or PDF documents from custom forms in the front-end. This could increase the load on your server if you have a lot of users simultaneously connected.','shortpixel-image-optimiser');?>
|
320 |
+
</p>
|
321 |
+
</td>
|
322 |
+
</tr>
|
323 |
+
<tr>
|
324 |
+
<th scope="row"><?php _e('Optimize media on upload','shortpixel-image-optimiser');?></th>
|
325 |
+
<td>
|
326 |
+
<input name="autoMediaLibrary" type="checkbox" id="autoMediaLibrary" value="1" <?php checked( $view->data->autoMediaLibrary, "1" );?>>
|
327 |
+
<label for="autoMediaLibrary"><?php _e('Automatically optimize Media Library items after they are uploaded (recommended).','shortpixel-image-optimiser');?></label>
|
328 |
+
<p class="settings-info">
|
329 |
+
<?php _e('By default, ShortPixel will automatically optimize all the freshly uploaded image and PDF files. If you uncheck this you\'ll need to either run Bulk ShortPixel or go to Media Library (in list view) and click on the right side "Optimize now" button(s).','shortpixel-image-optimiser');?>
|
330 |
+
</p>
|
331 |
+
</td>
|
332 |
+
</tr>
|
333 |
+
<tr>
|
334 |
+
<th scope="row"><label for="excludeSizes"><?php _e('Exclude thumbnail sizes','shortpixel-image-optimiser');?></label></th>
|
335 |
+
<td>
|
336 |
+
<?php foreach($view->allThumbSizes as $sizeKey => $sizeVal) {?>
|
337 |
+
<span style="margin-right: 20px;white-space:nowrap">
|
338 |
+
<input name="excludeSizes[]" type="checkbox" id="excludeSizes_<?php echo($sizeKey);?>" <?php echo((in_array($sizeKey, $view->data->excludeSizes) ? 'checked' : ''));?>
|
339 |
+
value="<?php echo($sizeKey);?>"> <?php $w=$sizeVal['width']?$sizeVal['width'].'px':'*';$h=$sizeVal['height']?$sizeVal['height'].'px':'*';echo("$sizeKey ({$w} × {$h})");?>
|
340 |
+
</span><br>
|
341 |
+
<?php } ?>
|
342 |
+
<p class="settings-info">
|
343 |
+
<?php _e('Please check the thumbnail sizes you would like to <strong>exclude</strong> from optimization. There might be sizes created by themes or plugins which do not appear here, because they were not properly registered with WordPress. If you want to ignore them too, please uncheck the option <strong>Optimize other thumbs</strong> above.','shortpixel-image-optimiser');?>
|
344 |
+
</p>
|
345 |
+
</td>
|
346 |
+
</tr>
|
347 |
+
</tbody>
|
348 |
+
</table>
|
349 |
+
<p class="submit">
|
350 |
+
<input type="submit" name="save" id="saveAdv" class="button button-primary" title="<?php _e('Save Changes','shortpixel-image-optimiser');?>" value="<?php _e('Save Changes','shortpixel-image-optimiser');?>">
|
351 |
+
<input type="submit" name="save_bulk" id="bulkAdvGo" class="button button-primary" title="<?php _e('Save and go to the Bulk Processing page','shortpixel-image-optimiser');?>" value="<?php _e('Save and Go to Bulk Process','shortpixel-image-optimiser');?>">
|
352 |
+
</p>
|
353 |
+
</div>
|
354 |
+
<script>
|
355 |
+
jQuery(document).ready(function () { ShortPixel.setupAdvancedTab();});
|
356 |
+
</script>
|
357 |
+
</section>
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
?>
|
4 |
+
|
5 |
+
<section id="tab-cloudflare" <?php echo ($this->display_part == 'cloudflare') ? ' class="sel-tab" ' :''; ?>>
|
6 |
+
<h2><a class='tab-link' href='javascript:void(0);'
|
7 |
+
data-id="tab-cloudflare"><?php _e('Cloudflare API', 'shortpixel-image-optimiser'); ?></a>
|
8 |
+
</h2>
|
9 |
+
|
10 |
+
<div class="wp-shortpixel-tab-content" style="visibility: hidden">
|
11 |
+
<?php
|
12 |
+
|
13 |
+
if(! $this->is_curl_installed) {
|
14 |
+
echo('<p style="font-weight:bold;color:red">' . __("Please enable PHP cURL extension for the Cloudflare integration to work.", 'shortpixel-image-optimiser') . '</p>' );
|
15 |
+
}
|
16 |
+
?>
|
17 |
+
<p><?php _e("If you're using Cloudflare on your site then we advise you to fill in the details below. This will allow ShortPixel to work seamlessly with Cloudflare so that any image optimized/restored by ShortPixel will be automatically updated on Cloudflare as well.",'shortpixel-image-optimiser');?></p>
|
18 |
+
|
19 |
+
<table class="form-table">
|
20 |
+
<tbody>
|
21 |
+
<tr>
|
22 |
+
<th scope="row">
|
23 |
+
<label for="cloudflare-email"><?php _e('Cloudflare E-mail:', 'shortpixel-image-optimiser'); ?></label>
|
24 |
+
</th>
|
25 |
+
<td>
|
26 |
+
<input name="cloudflareEmail" type="text" id="cloudflare-email" <?php echo(! $this->is_curl_installed ? 'disabled' : '');?>
|
27 |
+
value="<?php echo( stripslashes(esc_html($view->data->cloudflareEmail))); ?>" class="regular-text">
|
28 |
+
<p class="settings-info">
|
29 |
+
<?php _e('The e-mail address you use to login to CloudFlare.','shortpixel-image-optimiser');?>
|
30 |
+
</p>
|
31 |
+
</td>
|
32 |
+
</tr>
|
33 |
+
<tr>
|
34 |
+
<th scope="row"><label
|
35 |
+
for="cloudflare-auth-key"><?php _e('Global API Key:', 'shortpixel-image-optimiser'); ?></label>
|
36 |
+
</th>
|
37 |
+
<td>
|
38 |
+
<input name="cloudflareAuthKey" type="text" id="cloudflare-auth-key" <?php echo(! $this->is_curl_installed ? 'disabled' : '');?>
|
39 |
+
value="<?php echo(stripslashes(esc_html($view->data->cloudflareAuthKey))); ?>" class="regular-text">
|
40 |
+
<p class="settings-info">
|
41 |
+
<?php _e("This can be found when you're logged into your account, on the My Profile page:",'shortpixel-image-optimiser');?> <a href='https://www.cloudflare.com/a/profile' target='_blank'>https://www.cloudflare.com/a/profile</a>
|
42 |
+
</p>
|
43 |
+
</td>
|
44 |
+
</tr>
|
45 |
+
<tr>
|
46 |
+
<th scope="row"><label
|
47 |
+
for="cloudflare-zone-id"><?php _e('Zone ID:', 'shortpixel-image-optimiser'); ?></label>
|
48 |
+
</th>
|
49 |
+
<td>
|
50 |
+
<input name="cloudflareZoneID" type="text" id="cloudflare-zone-id" <?php echo(! $this->is_curl_installed ? 'disabled' : '');?>
|
51 |
+
value="<?php echo(stripslashes(esc_html($view->data->cloudflareZoneID))); ?>" class="regular-text">
|
52 |
+
<p class="settings-info">
|
53 |
+
<?php _e('This can be found in your Cloudflare account in the "Overview" section for your domain.','shortpixel-image-optimiser');?>
|
54 |
+
</p>
|
55 |
+
</td>
|
56 |
+
</tr>
|
57 |
+
</tbody>
|
58 |
+
</table>
|
59 |
+
<p class="submit">
|
60 |
+
<input type="submit" name="saveCloudflare" id="saveCloudflare" class="button button-primary"
|
61 |
+
title="<?php _e('Save Changes', 'shortpixel-image-optimiser'); ?>"
|
62 |
+
value="<?php _e('Save Changes', 'shortpixel-image-optimiser'); ?>">
|
63 |
+
</p>
|
64 |
+
</div>
|
65 |
+
|
66 |
+
</section>
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
|
4 |
+
?>
|
5 |
+
|
6 |
+
<section id="tab-debug" <?php echo ($this->display_part == 'debug') ? ' class="sel-tab" ' :''; ?>>
|
7 |
+
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-debug">
|
8 |
+
<?php _e('Debug','shortpixel-image-optimiser');?></a>
|
9 |
+
</h2>
|
10 |
+
|
11 |
+
<div class="wp-shortpixel-options wp-shortpixel-tab-content" style="visibility: hidden">
|
12 |
+
<div class='env'>
|
13 |
+
<h3><?php _e('Environment', 'shortpixel'); ?></h3>
|
14 |
+
<div class='flex'>
|
15 |
+
<span>Nginx</span><span><?php var_export($this->is_nginx); ?></span>
|
16 |
+
<span>KeyVerified</span><span><?php var_export($this->is_verifiedkey); ?></span>
|
17 |
+
<span>HtAccess writable</span><span><?php var_export($this->is_htaccess_writable); ?></span>
|
18 |
+
<span>Multisite</span><span><?php var_export($this->is_multisite); ?></span>
|
19 |
+
<span>Main site</span><span><?php var_export($this->is_mainsite); ?></span>
|
20 |
+
<span>Constant key</span><span><?php var_export($this->is_constant_key); ?></span>
|
21 |
+
<span>Hide Key</span><span><?php var_export($this->hide_api_key); ?></span>
|
22 |
+
<span>Has Nextgen</span><span><?php var_export($this->has_nextgen); ?></span>
|
23 |
+
|
24 |
+
</div>
|
25 |
+
</div>
|
26 |
+
|
27 |
+
<div class='settings'>
|
28 |
+
<h3><?php _e('Settings', 'shortpixel'); ?></h3>
|
29 |
+
<?php $local = $this->view->data;
|
30 |
+
$local->apiKey = strlen($local->apiKey) . ' chars'; ?>
|
31 |
+
<pre><?php var_export($local); ?></pre>
|
32 |
+
</div>
|
33 |
+
|
34 |
+
<div class='quotadata'>
|
35 |
+
<h3><?php _e('Quota Data', 'shortpixel'); ?></h3>
|
36 |
+
<pre><?php var_export($this->quotaData); ?></pre>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
</div> <!-- tab-content -->
|
40 |
+
</section>
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php namespace ShortPixel; ?>
|
2 |
+
<section id="tab-settings" <?php echo ($this->display_part == 'settings') ? ' class="sel-tab" ' :''; ?> >
|
3 |
+
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-settings">
|
4 |
+
<?php _e('General','shortpixel-image-optimiser');?></a>
|
5 |
+
</h2>
|
6 |
+
|
7 |
+
<div class="wp-shortpixel-options wp-shortpixel-tab-content" style="visibility: hidden">
|
8 |
+
|
9 |
+
<p><?php printf(__('New images uploaded to the Media Library will be optimized automatically.<br/>If you have existing images you would like to optimize, you can use the <a href="%supload.php?page=wp-short-pixel-bulk">Bulk Optimization Tool</a>.','shortpixel-image-optimiser'),get_admin_url());?></p>
|
10 |
+
<table class="form-table">
|
11 |
+
<tbody>
|
12 |
+
<tr>
|
13 |
+
<th scope="row"><label for="key"><?php _e('API Key:','shortpixel-image-optimiser');?></label></th>
|
14 |
+
<td>
|
15 |
+
<?php
|
16 |
+
$canValidate = false;
|
17 |
+
// Several conditions for showing API key.
|
18 |
+
if ($this->hide_api_key)
|
19 |
+
$showApiKey = false;
|
20 |
+
elseif($this->is_multisite && $this->is_constant_key)
|
21 |
+
$showApiKey = false;
|
22 |
+
else {
|
23 |
+
$showApiKey = true; // is_mainsite, multisite, no constant.
|
24 |
+
}
|
25 |
+
|
26 |
+
$editApiKey = (! $this->is_constant_key && $showApiKey) ? true : false; ;
|
27 |
+
|
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') ?> <?php echo $this->is_verifiedkey ? 'onkeyup="ShortPixel.apiKeyChanged()"' : '' ?> >
|
32 |
+
<?php
|
33 |
+
}
|
34 |
+
elseif(defined("SHORTPIXEL_API_KEY")) {
|
35 |
+
$canValidate = true;?>
|
36 |
+
<input name="key" type="text" id="key" disabled="true" placeholder="<?php
|
37 |
+
if( $this->hide_api_key ) {
|
38 |
+
echo("********************");
|
39 |
+
} else {
|
40 |
+
_e('Multisite API Key','shortpixel-image-optimiser');
|
41 |
+
}
|
42 |
+
?>" class="regular-text">
|
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>
|
53 |
+
<?php if($this->is_constant_key) { ?>
|
54 |
+
<p class="settings-info"><?php _e('Key defined in wp-config.php.','shortpixel-image-optimiser');?></p>
|
55 |
+
<?php } ?>
|
56 |
+
|
57 |
+
</td>
|
58 |
+
</tr>
|
59 |
+
<?php if (! $this->is_verifiedkey) { //if invalid key we display the link to the API Key ?>
|
60 |
+
</tbody>
|
61 |
+
</table>
|
62 |
+
<?php } else { //if valid key we display the rest of the options ?>
|
63 |
+
<tr>
|
64 |
+
<th scope="row">
|
65 |
+
<label for="compressionType"><?php _e('Compression type:','shortpixel-image-optimiser');?></label>
|
66 |
+
</th>
|
67 |
+
<td>
|
68 |
+
<div class="shortpixel-compression">
|
69 |
+
<div class="shortpixel-compression-options">
|
70 |
+
<label class="lossy" title="<?php _e('This is the recommended option in most cases, producing results that look the same as the original to the human eye.','shortpixel-image-optimiser');?>">
|
71 |
+
<input type="radio" class="shortpixel-radio-lossy" name="compressionType" value="1" <?php echo( $view->data->compressionType == 1 ? "checked" : "" );?>><span><?php _e('Lossy','shortpixel-image-optimiser');?></span>
|
72 |
+
</label>
|
73 |
+
<label class="glossy" title="<?php _e('Best option for photographers and other professionals that use very high quality images on their sites and want best compression while keeping the quality untouched.','shortpixel-image-optimiser');?>">
|
74 |
+
<input type="radio" class="shortpixel-radio-glossy" name="compressionType" value="2" <?php echo( $view->data->compressionType == 2 ? "checked" : "" );?>><span><?php _e('Glossy','shortpixel-image-optimiser');?></span>
|
75 |
+
</label>
|
76 |
+
<label class="lossless" title="<?php _e('Make sure not a single pixel looks different in the optimized image compared with the original. In some rare cases you will need to use this type of compression. Some technical drawings or images from vector graphics are possible situations.','shortpixel-image-optimiser');?>">
|
77 |
+
<input type="radio" class="shortpixel-radio-lossless" name="compressionType" value="0" <?php echo( $view->data->compressionType == 0 ? "checked" : "" );?>><span><?php _e('Lossless','shortpixel-image-optimiser');?></span>
|
78 |
+
</label>
|
79 |
+
<?php _e('<a href="https://shortpixel.com/online-image-compression" style="margin-left:20px;" target="_blank">Make a few tests</a> to help you decide.'); ?>
|
80 |
+
</div>
|
81 |
+
<p class="settings-info shortpixel-radio-info shortpixel-radio-lossy" <?php echo( $view->data->compressionType == 1 ? "" : 'style="display:none"' );?>>
|
82 |
+
<?php _e('<b>Lossy compression (recommended): </b>offers the best compression rate.</br> This is the recommended option for most users, producing results that look the same as the original to the human eye.','shortpixel-image-optimiser');?>
|
83 |
+
</p>
|
84 |
+
<p class="settings-info shortpixel-radio-info shortpixel-radio-glossy" <?php echo( $view->data->compressionType == 2 ? "" : 'style="display:none"' );?>>
|
85 |
+
<?php _e('<b>Glossy compression: </b>creates images that are almost pixel-perfect identical to the originals.</br> Best option for photographers and other professionals that use very high quality images on their sites and want best compression while keeping the quality untouched.','shortpixel-image-optimiser');?>
|
86 |
+
<a href="http://blog.shortpixel.com/glossy-image-optimization-for-photographers/" target="_blank" class="shortpixel-help-link">
|
87 |
+
<span class="dashicons dashicons-editor-help"></span><?php _e('More info about glossy','shortpixel-image-optimiser');?>
|
88 |
+
</a></p>
|
89 |
+
<p class="settings-info shortpixel-radio-info shortpixel-radio-lossless" <?php echo( $view->data->compressionType == 0 ? "" : 'style="display:none"' );?>>
|
90 |
+
<?php _e('<b>Lossless compression: </b> the resulting image is pixel-identical with the original image.</br>Make sure not a single pixel looks different in the optimized image compared with the original.
|
91 |
+
In some rare cases you will need to use this type of compression. Some technical drawings or images from vector graphics are possible situations.','shortpixel-image-optimiser');?>
|
92 |
+
</p>
|
93 |
+
</div>
|
94 |
+
<script>
|
95 |
+
// @todo Remove JS from interface
|
96 |
+
function shortpixelCompressionLevelInfo() {
|
97 |
+
jQuery(".shortpixel-compression p").css("display", "none");
|
98 |
+
jQuery(".shortpixel-compression p." + jQuery(".shortpixel-compression-options input:radio:checked").attr('class')).css("display", "block");
|
99 |
+
}
|
100 |
+
//shortpixelCompressionLevelInfo();
|
101 |
+
jQuery(".shortpixel-compression-options input:radio").change(shortpixelCompressionLevelInfo);
|
102 |
+
</script>
|
103 |
+
</td>
|
104 |
+
</tr>
|
105 |
+
<tr>
|
106 |
+
<th scope="row"><?php _e('Also include thumbnails:','shortpixel-image-optimiser');?></th>
|
107 |
+
<td><input name="processThumbnails" type="checkbox" id="thumbnails" value="1" <?php checked($view->data->processThumbnails, '1');?>>
|
108 |
+
<label for="thumbnails"><?php _e('Apply compression also to <strong>image thumbnails.</strong> ','shortpixel-image-optimiser');?></label>
|
109 |
+
<?php echo($view->thumbnailsToProcess > 0 ? "(" . number_format($view->thumbnailsToProcess) . " " . __('thumbnails to optimize','shortpixel-image-optimiser') . ")" : "");?>
|
110 |
+
<p class="settings-info">
|
111 |
+
<?php _e('It is highly recommended that you optimize the thumbnails as they are usually the images most viewed by end users and can generate most traffic.<br>Please note that thumbnails count up to your total quota.','shortpixel-image-optimiser');?>
|
112 |
+
</p>
|
113 |
+
</td>
|
114 |
+
</tr>
|
115 |
+
<tr>
|
116 |
+
<th scope="row"><?php _e('Image backup','shortpixel-image-optimiser');?></th>
|
117 |
+
<td>
|
118 |
+
<input name="backupImages" type="checkbox" id="backupImages" value="1" <?php checked($view->data->backupImages,'1'); ?>>
|
119 |
+
<label for="backupImages"><?php _e('Save and keep a backup of your original images in a separate folder.','shortpixel-image-optimiser');?></label>
|
120 |
+
<p class="settings-info"><?php _e('You <strong>need to have backup active</strong> in order to be able to restore images to originals or to convert from Lossy to Lossless and back.','shortpixel-image-optimiser');?></p>
|
121 |
+
</td>
|
122 |
+
</tr>
|
123 |
+
<tr>
|
124 |
+
<th scope="row"><?php _e('Remove EXIF','shortpixel-image-optimiser');?></th>
|
125 |
+
<td>
|
126 |
+
<input name="removeExif" type="checkbox" id="removeExif" value="1" <?php checked($view->data->keepExif, 0);?>>
|
127 |
+
<label for="removeExif"><?php _e('Remove the EXIF tag of the image (recommended).','shortpixel-image-optimiser');?></label>
|
128 |
+
<p class="settings-info"> <?php _e('EXIF is a set of various pieces of information that are automatically embedded into the image upon creation. This can include GPS position, camera manufacturer, date and time, etc.
|
129 |
+
Unless you really need that data to be preserved, we recommend removing it as it can lead to <a href="http://blog.shortpixel.com/how-much-smaller-can-be-images-without-exif-icc" target="_blank">better compression rates</a>.','shortpixel-image-optimiser');?></p>
|
130 |
+
</td>
|
131 |
+
</tr>
|
132 |
+
<tr class='exif_warning view-notice-row'>
|
133 |
+
<th scope="row"> </th>
|
134 |
+
<td>
|
135 |
+
<div class='view-notice warning'><p><?php printf(__('Warning - Converting from PNG to JPG will %s not %s keep the EXIF-information!'), "<strong>","</strong>"); ?></p></div>
|
136 |
+
</td>
|
137 |
+
</tr>
|
138 |
+
<tr>
|
139 |
+
<?php $resizeDisabled = (! $this->view->data->resizeImages) ? 'disabled' : '';
|
140 |
+
// @todo Inline styling here can be decluttered.
|
141 |
+
?>
|
142 |
+
<th scope="row"><?php _e('Resize large images','shortpixel-image-optimiser');?></th>
|
143 |
+
<td>
|
144 |
+
<input name="resizeImages" type="checkbox" id="resize" value="1" <?php checked( $view->data->resizeImages, true );?>>
|
145 |
+
<label for="resize"><?php _e('to maximum','shortpixel-image-optimiser');?></label>
|
146 |
+
<input type="text" name="resizeWidth" id="width" style="width:70px" class="resize-sizes"
|
147 |
+
value="<?php echo( $view->data->resizeWidth > 0 ? $view->data->resizeWidth : min(924, $view->minSizes['width']) );?>" <?php echo( $resizeDisabled );?>/> <?php
|
148 |
+
_e('pixels wide ×','shortpixel-image-optimiser');?>
|
149 |
+
<input type="text" name="resizeHeight" id="height" class="resize-sizes" style="width:70px"
|
150 |
+
value="<?php echo( $view->data->resizeHeight > 0 ? $view->data->resizeHeight : min(924, $view->minSizes['height']) );?>" <?php echo( $resizeDisabled );?>/> <?php
|
151 |
+
_e('pixels high (original aspect ratio is preserved and image is not cropped)','shortpixel-image-optimiser');?>
|
152 |
+
<input type="hidden" id="min-resizeWidth" value="<?php echo($view->minSizes['width']);?>" data-nicename="<?php _e('Width', 'shortpixel-image-optimiser'); ?>" />
|
153 |
+
<input type="hidden" id="min-resizeHeight" value="<?php echo($view->minSizes['height']);?>" data-nicename="<?php _e('Height', 'shortpixel-image-optimiser'); ?>"/>
|
154 |
+
<p class="settings-info">
|
155 |
+
<?php _e('Recommended for large photos, like the ones taken with your phone. Saved space can go up to 80% or more after resizing.','shortpixel-image-optimiser');?>
|
156 |
+
<a href="https://blog.shortpixel.com/resize-images/" class="shortpixel-help-link" target="_blank">
|
157 |
+
<span class="dashicons dashicons-editor-help"></span><?php _e('Read more','shortpixel-image-optimiser');?>
|
158 |
+
</a><br/>
|
159 |
+
</p>
|
160 |
+
<div style="margin-top: 10px;">
|
161 |
+
<input type="radio" name="resizeType" id="resize_type_outer" value="outer" <?php echo($view->data->resizeType == 'inner' ? '' : 'checked') ?> style="margin: -50px 10px 60px 0;">
|
162 |
+
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-outer.png' ));?>"
|
163 |
+
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-outer.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-outer@2x.png' ));?> 2x'
|
164 |
+
title="<?php _e('Sizes will be greater or equal to the corresponding value. For example, if you set the resize dimensions at 1000x1200, an image of 2000x3000px will be resized to 1000x1500px while an image of 3000x2000px will be resized to 1800x1200px','shortpixel-image-optimiser');?>">
|
165 |
+
<input type="radio" name="resizeType" id="resize_type_inner" value="inner" <?php echo($view->data->resizeType == 'inner' ? 'checked' : '') ?> style="margin: -50px 10px 60px 35px;">
|
166 |
+
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?>"
|
167 |
+
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/resize-inner@2x.png' ));?> 2x'
|
168 |
+
title="<?php _e('Sizes will be smaller or equal to the corresponding value. For example, if you set the resize dimensions at 1000x1200, an image of 2000x3000px will be resized to 800x1200px while an image of 3000x2000px will be resized to 1000x667px','shortpixel-image-optimiser');?>">
|
169 |
+
<div style="display:inline-block;margin-left: 20px;"><a href="https://blog.shortpixel.com/resize-images/" class="shortpixel-help-link" target="_blank">
|
170 |
+
<span class="dashicons dashicons-editor-help"></span><?php _e('What is this?','shortpixel-image-optimiser');?></a>
|
171 |
+
</div>
|
172 |
+
</div>
|
173 |
+
</td>
|
174 |
+
</tr>
|
175 |
+
</tbody>
|
176 |
+
</table>
|
177 |
+
|
178 |
+
|
179 |
+
<?php } ?>
|
180 |
+
<p class="submit">
|
181 |
+
<input type="submit" name="save" id="save" class="button button-primary" title="<?php _e('Save Changes','shortpixel-image-optimiser');?>" value="<?php _e('Save Changes','shortpixel-image-optimiser');?>">
|
182 |
+
<input type="submit" name="save_bulk" id="bulk" class="button button-primary" title="<?php _e('Save and go to the Bulk Processing page','shortpixel-image-optimiser');?>" value="<?php _e('Save and Go to Bulk Process','shortpixel-image-optimiser');?>">
|
183 |
+
</p>
|
184 |
+
</div>
|
185 |
+
|
186 |
+
</section>
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
8 |
+
if ($this->hide_api_key)
|
9 |
+
$showApiKey = false;
|
10 |
+
elseif($this->is_multisite && $this->is_constant_key)
|
11 |
+
$showApiKey = false;
|
12 |
+
else {
|
13 |
+
$showApiKey = true; // is_mainsite, multisite, no constant.
|
14 |
+
}
|
15 |
+
|
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 has API key hidden, but no API key has been entered. Please do so, or remove the Hide constant', 'shortpixel-image-optimiser'));
|
22 |
+
}
|
23 |
+
elseif ($this->is_constant_key && ! $this->is_verifiedkey)
|
24 |
+
{
|
25 |
+
$dkey = ($this->hide_api_key) ? '' : '(' . SHORTPIXEL_API_KEY. ')';
|
26 |
+
Notice::addError(sprintf(__('Constant API Key is not verified. Please check if this is a valid API key %s'),$dkey));
|
27 |
+
}
|
28 |
+
|
29 |
+
$adminEmail = get_bloginfo('admin_email');
|
30 |
+
if($adminEmail == 'noreply@addendio.com') $adminEmail = false; //hack for the addendio sandbox e-mail
|
31 |
+
|
32 |
+
?>
|
33 |
+
<section id="tab-settings" <?php echo ($this->display_part == 'settings') ? ' class="sel-tab" ' :''; ?> >
|
34 |
+
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-settings">
|
35 |
+
<?php _e('Join ShortPixel','shortpixel-image-optimiser');?></a>
|
36 |
+
</h2>
|
37 |
+
<div class="wp-shortpixel-options wp-shortpixel-tab-content">
|
38 |
+
<?php if($showApiKey): ?>
|
39 |
+
<h3><?php _e('Request an API Key:','shortpixel-image-optimiser');?></h3>
|
40 |
+
<p style='font-size: 14px'><?php _e('If you don\'t have an API Key, you can request one for free. Just press the "Request Key" button after checking that the e-mail is correct.','shortpixel-image-optimiser');?></p>
|
41 |
+
|
42 |
+
<table class="form-table">
|
43 |
+
<tbody>
|
44 |
+
<tr>
|
45 |
+
<th scope="row"><label for="key"><?php _e('E-mail address:','shortpixel-image-optimiser');?></label></th>
|
46 |
+
<td>
|
47 |
+
<input name="pluginemail" type="text" id="pluginemail" value="<?php echo( $adminEmail );?>"
|
48 |
+
onchange="ShortPixel.updateSignupEmail();" class="regular-text">
|
49 |
+
<span class="spinner" id="pluginemail_spinner" style="float:none;"></span>
|
50 |
+
<a type="button" id="request_key" class="button button-primary" title="<?php _e('Request a new API key','shortpixel-image-optimiser');?>"
|
51 |
+
href="https://shortpixel.com/free-sign-up?pluginemail=<?php echo( $adminEmail );?>"
|
52 |
+
onclick="ShortPixel.newApiKey(event);"
|
53 |
+
onmouseenter="ShortPixel.updateSignupEmail();">
|
54 |
+
<?php _e('Request Key','shortpixel-image-optimiser');?>
|
55 |
+
</a>
|
56 |
+
<p class="settings-info shortpixel-settings-error" style='display:none;' id='pluginemail-error'>
|
57 |
+
<b><?php _e('Please provide a valid e-mail address.', 'shortpixel-image-optimiser');?></b>
|
58 |
+
</p>
|
59 |
+
<p class="settings-info" id='pluginemail-info'>
|
60 |
+
<?php if($adminEmail) {
|
61 |
+
printf(__('<b>%s</b> is the e-mail address in your WordPress Settings. You can use it, or change it to any valid e-mail address that you own.','shortpixel-image-optimiser'), $adminEmail);
|
62 |
+
} else {
|
63 |
+
_e('Please input your e-mail address and press the Request Key button.','shortpixel-image-optimiser');
|
64 |
+
}
|
65 |
+
?><br><span style="position:relative;">
|
66 |
+
<input name="tos" type="checkbox" id="tos">
|
67 |
+
<img id="tos-robo" src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?>" style="position: absolute;left: -95px;bottom: -26px;display:none;">
|
68 |
+
<img id="tos-hand" src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/point.png' ));?>" style="position: absolute;left: -39px;bottom: -9px;display:none;">
|
69 |
+
</span>
|
70 |
+
<?php _e('I have read and I agree to the <a href="https://shortpixel.com/tos" target="_blank">Terms of Service</a> and the <a href="https://shortpixel.com/privacy" target="_blank">Privacy Policy</a> (<a href="https://shortpixel.com/privacy#gdpr" target="_blank">GDPR compliant</a>).','shortpixel-image-optimiser');
|
71 |
+
?>
|
72 |
+
</p>
|
73 |
+
</td>
|
74 |
+
</tr>
|
75 |
+
</tbody>
|
76 |
+
</table>
|
77 |
+
<?php endif; ?>
|
78 |
+
<h3>
|
79 |
+
<?php _e('Already have an API Key:','shortpixel-image-optimiser');?>
|
80 |
+
</h3>
|
81 |
+
<p style='font-size: 14px'>
|
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')) ?>" id="shortpixel-form-nokey">
|
86 |
+
<table class="form-table">
|
87 |
+
<tbody>
|
88 |
+
<tr>
|
89 |
+
<th scope="row"><label for="key"><?php _e('API Key:','shortpixel-image-optimiser');?></label></th>
|
90 |
+
<td>
|
91 |
+
<?php
|
92 |
+
if($showApiKey) {
|
93 |
+
|
94 |
+
if (! $this->is_constant_key)
|
95 |
+
$canValidate = true;
|
96 |
+
|
97 |
+
?>
|
98 |
+
<input name="key" type="text" id="key" value="<?php echo( $view->data->apiKey );?>"
|
99 |
+
class="regular-text" <?php echo($editApiKey ? "" : 'disabled') ?> >
|
100 |
+
<?php
|
101 |
+
}
|
102 |
+
elseif(defined("SHORTPIXEL_API_KEY")) {
|
103 |
+
$canValidate = true;?>
|
104 |
+
<input name="key" type="text" id="key" disabled="true" placeholder="<?php
|
105 |
+
if( $this->hide_api_key ) {
|
106 |
+
echo("********************");
|
107 |
+
} else {
|
108 |
+
_e('Multisite API Key','shortpixel-image-optimiser');
|
109 |
+
}
|
110 |
+
?>" class="regular-text">
|
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="button" id="validate" class="button button-primary" title="<?php _e('Validate the provided API key','shortpixel-image-optimiser');?>"
|
115 |
+
onclick="ShortPixel.validateKey(this)" <?php echo $canValidate ? "" : "disabled"?> >
|
116 |
+
<?php _e('Validate','shortpixel-image-optimiser');?>
|
117 |
+
</button>
|
118 |
+
|
119 |
+
<?php if($this->is_constant_key) { ?>
|
120 |
+
<p class="settings-info"><?php _e('Key defined in wp-config.php.','shortpixel-image-optimiser');?></p>
|
121 |
+
<?php } ?>
|
122 |
+
|
123 |
+
</td>
|
124 |
+
</tr>
|
125 |
+
</tbody>
|
126 |
+
</table>
|
127 |
+
</form>
|
128 |
+
</div> <!-- tab content -->
|
129 |
+
</section>
|
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
|
4 |
+
$quotaData = $this->quotaData;
|
5 |
+
|
6 |
+
?>
|
7 |
+
|
8 |
+
<section id="tab-stats" <?php echo ($this->display_part == 'stats') ? ' class="sel-tab" ' :''; ?>>
|
9 |
+
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-stats"><?php _e('Statistics','shortpixel-image-optimiser');?></a></h2>
|
10 |
+
|
11 |
+
<div class="wp-shortpixel-tab-content" style="visibility: hidden">
|
12 |
+
<a id="facts"></a>
|
13 |
+
<h3><?php _e('Your ShortPixel Stats','shortpixel-image-optimiser');?></h3>
|
14 |
+
<table class="form-table">
|
15 |
+
<tbody>
|
16 |
+
<tr>
|
17 |
+
<th scope="row">
|
18 |
+
<?php _e('Average compression of your files:','shortpixel-image-optimiser');?>
|
19 |
+
</th>
|
20 |
+
<td>
|
21 |
+
<strong><?php echo($view->averageCompression);?>%</strong>
|
22 |
+
<div class="sp-bulk-summary">
|
23 |
+
<input type="text" value="<?php echo("" . round($view->averageCompression))?>" id="sp-total-optimization-dial" class="dial">
|
24 |
+
</div>
|
25 |
+
<div id="sp-bulk-stats" style="display:none">
|
26 |
+
<?php
|
27 |
+
$under5PercentCount = $view->data->under5Percent; //amount of under 5% optimized imgs.
|
28 |
+
$totalOptimized = isset($quotaData['totalProcessedFiles']) ? $quotaData['totalProcessedFiles'] : 0;
|
29 |
+
$mainOptimized = isset($quotaData['mainProcessedFiles']) ? $quotaData['mainProcessedFiles'] : 0;
|
30 |
+
?>
|
31 |
+
<div class="bulk-progress bulk-stats">
|
32 |
+
<div class="label"><?php _e('Processed Images and PDFs:','shortpixel-image-optimiser');?></div><div class="stat-value"><?php echo(number_format($mainOptimized));?></div><br>
|
33 |
+
<div class="label"><?php _e('Processed Thumbnails:','shortpixel-image-optimiser');?></div><div class="stat-value"><?php echo(number_format($totalOptimized - $mainOptimized));?></div><br>
|
34 |
+
<div class="label totals"><?php _e('Total files processed:','shortpixel-image-optimiser');?></div><div class="stat-value"><?php echo(number_format($totalOptimized));?></div><br>
|
35 |
+
<div class="label totals"><?php _e('Minus files with <5% optimization (free):','shortpixel-image-optimiser');?></div><div class="stat-value"><?php echo(number_format($under5PercentCount));?></div><br><br>
|
36 |
+
<div class="label totals"><?php _e('Used quota:','shortpixel-image-optimiser');?></div><div class="stat-value"><?php echo(number_format($totalOptimized - $under5PercentCount));?></div><br>
|
37 |
+
<br>
|
38 |
+
<div class="label"><?php _e('Average optimization:','shortpixel-image-optimiser');?></div><div class="stat-value"><?php echo($view->averageCompression);?>%</div><br>
|
39 |
+
<div class="label"><?php _e('Saved space:','shortpixel-image-optimiser');?></div><div class="stat-value"><?php echo($view->data->savedSpace);?></div>
|
40 |
+
</div>
|
41 |
+
</div>
|
42 |
+
<script>
|
43 |
+
jQuery(function() {
|
44 |
+
jQuery("#sp-total-optimization-dial").val("<?php echo("" . round($view->averageCompression))?>");
|
45 |
+
ShortPixel.percentDial("#sp-total-optimization-dial", 160);
|
46 |
+
|
47 |
+
jQuery(".sp-bulk-summary").spTooltip({
|
48 |
+
tooltipSource: "inline",
|
49 |
+
tooltipSourceID: "#sp-bulk-stats"
|
50 |
+
});
|
51 |
+
});
|
52 |
+
!function(d,s,id){//Just optimized my site with ShortPixel image optimization plugin
|
53 |
+
var js,
|
54 |
+
fjs=d.getElementsByTagName(s)[0],
|
55 |
+
p=/^http:/.test(d.location)?'http':'https';
|
56 |
+
if(!d.getElementById(id)){js=d.createElement(s);
|
57 |
+
js.id=id;js.src=p+'://platform.twitter.com/widgets.js';
|
58 |
+
fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');
|
59 |
+
</script>
|
60 |
+
</td>
|
61 |
+
</tr>
|
62 |
+
<tr>
|
63 |
+
<th scope="row">
|
64 |
+
<?php _e('Disk space saved by ShortPixel:','shortpixel-image-optimiser');?>
|
65 |
+
</th>
|
66 |
+
<td><?php echo(\WpShortPixel::formatBytes($view->data->savedSpace));?></td>
|
67 |
+
</tr>
|
68 |
+
<tr>
|
69 |
+
<th scope="row">
|
70 |
+
<?php _e('Bandwith* saved by ShortPixel:','shortpixel-image-optimiser');?>
|
71 |
+
</th>
|
72 |
+
<td><?php echo($view->savedBandwidth);?></td>
|
73 |
+
</tr>
|
74 |
+
</tbody>
|
75 |
+
</table>
|
76 |
+
|
77 |
+
<h3><?php _e('Your ShortPixel Credits','shortpixel-image-optimiser');?></h3>
|
78 |
+
<table class="form-table">
|
79 |
+
<tbody>
|
80 |
+
<tr>
|
81 |
+
<th scope="row" bgcolor="#ffffff">
|
82 |
+
<?php _e('Your monthly plan','shortpixel-image-optimiser');?>:
|
83 |
+
</th>
|
84 |
+
<td bgcolor="#ffffff">
|
85 |
+
<?php
|
86 |
+
$DateNow = time();
|
87 |
+
$DateSubscription = strtotime($quotaData['APILastRenewalDate']);
|
88 |
+
$DaysToReset = 30 - ((($DateNow - $DateSubscription) / 84600) % 30);
|
89 |
+
printf(__('%s/month, renews in %s days, on %s ( <a href="https://shortpixel.com/login/%s" target="_blank">Need More? See the options available</a> )','shortpixel-image-optimiser'),
|
90 |
+
$quotaData['APICallsQuota'], $DaysToReset,
|
91 |
+
date('M d, Y', strtotime(date('M d, Y') . ' + ' . $DaysToReset . ' days')), ( $this->hide_api_key) ? '' : $view->data->apiKey ); ?><br/>
|
92 |
+
<?php printf(__('<a href="https://shortpixel.com/login/%s/tell-a-friend" target="_blank">Join our friend referral system</a> to win more credits. For each user that joins, you receive +100 images credits/month.','shortpixel-image-optimiser'),
|
93 |
+
( $this->hide_api_key ? '' : $view->data->apiKey));?>
|
94 |
+
<br><br>
|
95 |
+
<?php _e('Consumed: ','shortpixel-image-optimiser'); ?>
|
96 |
+
<strong><?php echo( number_format( $view->totalCallsMade['plan'] ) ); ?></strong>
|
97 |
+
<?php _e('; Remaining: ','shortpixel-image-optimiser'); ?>
|
98 |
+
<strong><?php echo( number_format( $quotaData['APICallsQuotaNumeric'] - $view->totalCallsMade['plan'] ) ); ?></strong>
|
99 |
+
</td>
|
100 |
+
</tr>
|
101 |
+
<tr>
|
102 |
+
<th scope="row">
|
103 |
+
<?php _e('Your One Time credits:','shortpixel-image-optimiser');?>
|
104 |
+
</th>
|
105 |
+
<td>
|
106 |
+
<?php _e('Total: ','shortpixel-image-optimiser'); ?>
|
107 |
+
<strong><?php echo( number_format($quotaData['APICallsQuotaOneTimeNumeric'])); ?></strong>
|
108 |
+
<br><br>
|
109 |
+
<?php _e('Consumed: ','shortpixel-image-optimiser'); ?>
|
110 |
+
<strong><?php echo( number_format($view->totalCallsMade['oneTime']) ); ?></strong>
|
111 |
+
<?php _e('; Remaining: ','shortpixel-image-optimiser'); ?>
|
112 |
+
<strong><?php echo( number_format( $quotaData['APICallsQuotaOneTimeNumeric'] - $view->totalCallsMade['oneTime'] ) ); ?></strong>**
|
113 |
+
</td>
|
114 |
+
</tr>
|
115 |
+
<tr>
|
116 |
+
<th><a href="https://<?php echo(SHORTPIXEL_API);?>/v2/report.php?key=<?php echo($this->hide_api_key ? '' : $view->data->apiKey);?>" target="_blank">
|
117 |
+
<?php _e('See report (last 40 days)','shortpixel-image-optimiser');?>
|
118 |
+
</a></th>
|
119 |
+
<td> </td>
|
120 |
+
</tr>
|
121 |
+
<tr>
|
122 |
+
<th scope="row">
|
123 |
+
<?php _e('Credits consumed on','shortpixel-image-optimiser');?>
|
124 |
+
<?php echo(parse_url(get_site_url(),PHP_URL_HOST));?>:
|
125 |
+
</th>
|
126 |
+
<td><strong><?php echo($view->data->fileCount);?></strong></td>
|
127 |
+
</tr>
|
128 |
+
<?php
|
129 |
+
// @todo This is always true, but must it be?
|
130 |
+
if(true || $view->data->backupImages) { ?>
|
131 |
+
<tr>
|
132 |
+
<th scope="row">
|
133 |
+
<?php _e('Original images are stored in a backup folder. Your backup folder\'s size is now:','shortpixel-image-optimiser');?>
|
134 |
+
</th>
|
135 |
+
<td>
|
136 |
+
<form action="" method="POST">
|
137 |
+
<?php $backupFolderSize = null; ?>
|
138 |
+
<?php if ($backupFolderSize === null) { ?>
|
139 |
+
<span id='backup-folder-size'>Calculating...</span>
|
140 |
+
<?php } else { echo($backupFolderSize); }?>
|
141 |
+
<input type="submit" style="margin-left: 15px; vertical-align: middle;" class="button button-secondary shortpixel-confirm"
|
142 |
+
name="emptyBackup" value="<?php _e('Empty backups','shortpixel-image-optimiser');?>"
|
143 |
+
data-confirm="<?php _e('Are you sure you want to delete all the backup images? You won\'t be able to restore from backup or to reoptimize with different settings if you delete the backups.','shortpixel-image-optimiser'); ?>"/>
|
144 |
+
</form>
|
145 |
+
</td>
|
146 |
+
</tr>
|
147 |
+
<?php } ?>
|
148 |
+
</tbody>
|
149 |
+
</table>
|
150 |
+
<div style="display:none">
|
151 |
+
|
152 |
+
</div>
|
153 |
+
<p style="padding-top: 0px; color: #818181;" ><?php _e('* Saved bandwidth is calculated at 10,000 impressions/image','shortpixel-image-optimiser');?></p>
|
154 |
+
<p style="padding-top: 0px; color: #818181;" >
|
155 |
+
<?php printf(__('** Increase your image quota by <a href="https://shortpixel.com/login/%s" target="_blank">upgrading your ShortPixel plan.</a>','shortpixel-image-optimiser'),
|
156 |
+
$this->hide_api_key ? '' : $view->data->apiKey );?>
|
157 |
+
</p>
|
158 |
+
</div>
|
159 |
+
</section>
|
160 |
+
|
161 |
+
<?php
|
162 |
+
|
163 |
+
if( $view->resources !== null && $quotaData['APICallsQuotaOneTimeNumeric']<10000 && $quotaData['APICallsQuotaNumeric']<5000 ) {?>
|
164 |
+
<section id="tab-resources" <?php echo ($this->display_part == 'resources') ? ' class="sel-tab" ' :''; ?>>
|
165 |
+
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-resources"><?php _e('WP Resources','shortpixel-image-optimiser');?></a></h2>
|
166 |
+
<div class="wp-shortpixel-tab-content" style="visibility: hidden">
|
167 |
+
<?php echo((isset($view->resources['body']) ? $view->resources['body'] : __("Please reload",'shortpixel-image-optimiser')));?>
|
168 |
+
</div>
|
169 |
+
</section>
|
170 |
+
<?php } ?>
|
@@ -197,7 +197,7 @@ class ShortPixelListTable extends WP_List_Table {
|
|
197 |
}
|
198 |
|
199 |
public function no_items() {
|
200 |
-
echo(__('No images avaliable. Go to <a href="options-general.php?page=wp-shortpixel
|
201 |
}
|
202 |
|
203 |
/**
|
197 |
}
|
198 |
|
199 |
public function no_items() {
|
200 |
+
echo(__('No images avaliable. Go to <a href="options-general.php?page=wp-shortpixel-settings&part=adv-settings">Advanced Settings</a> to configure additional folders to be optimized.','shortpixel-image-optimiser'));
|
201 |
}
|
202 |
|
203 |
/**
|
@@ -1,9 +1,12 @@
|
|
1 |
<?php
|
|
|
2 |
|
3 |
class ShortPixelView {
|
4 |
|
5 |
private $ctrl;
|
6 |
|
|
|
|
|
7 |
public function __construct($controller) {
|
8 |
$this->ctrl = $controller;
|
9 |
}
|
@@ -48,7 +51,7 @@ class ShortPixelView {
|
|
48 |
<?php } ?></p>
|
49 |
<div> <!-- style='float:right;margin-top:20px;'> -->
|
50 |
<button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-right:10px;"><strong>
|
51 |
-
<?php _e('Show me the best available options', '
|
52 |
<a class='button button-primary' href='https://shortpixel.com/login/<?php echo($this->ctrl->getApiKey());?>'
|
53 |
title='<?php _e('Go to my account and select a plan','shortpixel-image-optimiser');?>' target='_blank' style="margin-right:10px;">
|
54 |
<strong><?php _e('Upgrade','shortpixel-image-optimiser');?></strong>
|
@@ -68,7 +71,7 @@ class ShortPixelView {
|
|
68 |
public static function displayApiKeyAlert()
|
69 |
{ ?>
|
70 |
<p><?php _e('In order to start the optimization process, you need to validate your API Key in the '
|
71 |
-
. '<a href="options-general.php?page=wp-shortpixel">ShortPixel Settings</a> page in your WordPress Admin.','shortpixel-image-optimiser');?>
|
72 |
</p>
|
73 |
<p><?php _e('If you don’t have an API Key, you can get one delivered to your inbox, for free.','shortpixel-image-optimiser');?></p>
|
74 |
<p><?php _e('Please <a href="https://shortpixel.com/wp-apikey' . WPShortPixel::getAffiliateSufix() . '" target="_blank">sign up to get your API key.</a>','shortpixel-image-optimiser');?>
|
@@ -96,7 +99,7 @@ class ShortPixelView {
|
|
96 |
<div style="float:right;">
|
97 |
<?php if($when == 'upgmonth' || $when == 'upgbulk'){ ?>
|
98 |
<button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-top:10px;margin-left:10px;"><strong>
|
99 |
-
<?php _e('Show me the best available options', '
|
100 |
<?php } ?>
|
101 |
<?php if($when == 'unlisted'){ ?>
|
102 |
<a href="javascript:ShortPixel.includeUnlisted()" class="button button-primary" style="margin-top:10px;margin-left:10px;">
|
@@ -158,10 +161,10 @@ class ShortPixelView {
|
|
158 |
<p> <?php
|
159 |
if($when == 'upgmonth') {
|
160 |
printf(__("You are adding an average of <strong>%d images and thumbnails every month</strong> to your Media Library and you have <strong>a plan of %d images/month</strong>."
|
161 |
-
. " You might need to upgrade your plan in order to have all your images optimized.", '
|
162 |
} else {
|
163 |
printf(__("You currently have <strong>%d images and thumbnails to optimize</strong> but you only have <strong>%d images</strong> available in your current plan."
|
164 |
-
. " You might need to upgrade your plan in order to have all your images optimized.", '
|
165 |
}?></p><?php
|
166 |
self::includeProposeUpgradePopup();
|
167 |
break;
|
@@ -204,7 +207,11 @@ class ShortPixelView {
|
|
204 |
public function displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount, $bulkRan,
|
205 |
$averageCompression, $filesOptimized, $savedSpace, $percent, $customCount) {
|
206 |
$settings = $this->ctrl->getSettings();
|
207 |
-
|
|
|
|
|
|
|
|
|
208 |
?>
|
209 |
<div class="wrap short-pixel-bulk-page">
|
210 |
<h1><?php _e('Bulk Image Optimization by ShortPixel','shortpixel-image-optimiser');?></h1>
|
@@ -271,19 +278,27 @@ class ShortPixelView {
|
|
271 |
</div>
|
272 |
</a>
|
273 |
</div>
|
274 |
-
<?php
|
275 |
-
<div style="position: absolute;bottom: 10px;right: 10px;">
|
276 |
-
<input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore', event)" style="margin-bottom:10px;"><br>
|
277 |
-
<input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup', event)" style="width:100%">
|
278 |
-
<input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)" style="display:none">
|
279 |
-
</div>
|
280 |
-
|
281 |
-
<?php }
|
282 |
-
} else {?>
|
283 |
<div class="bulk-play bulk-nothing-optimize">
|
284 |
<?php _e('Nothing to optimize! The images that you add to Media Gallery will be automatically optimized after upload.','shortpixel-image-optimiser');?>
|
285 |
</div>
|
286 |
<?php } ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
</form>
|
288 |
</div>
|
289 |
<?php if($quotaData['totalFiles'] - $quotaData['totalProcessedFiles'] > 0) { ?>
|
@@ -329,16 +344,24 @@ class ShortPixelView {
|
|
329 |
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?>"
|
330 |
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider@2x.png' ));?> 2x'>
|
331 |
</div>
|
332 |
-
<div class="sp-bulk-summary">
|
333 |
<input type="text" value="<?php echo("" . round($averageCompression))?>" id="sp-total-optimization-dial" class="dial">
|
334 |
</div>
|
|
|
335 |
<p style="margin-top:4px;">
|
336 |
<span style="font-size:1.2em;font-weight:bold"><?php _e('Congratulations!','shortpixel-image-optimiser');?></span><br>
|
337 |
<?php _e('Your media library has been successfully optimized!','shortpixel-image-optimiser');?>
|
338 |
<span class="sp-bulk-summary"><a href='javascript:void(0);'><?php _e('Summary','shortpixel-image-optimiser');?></a></span>
|
339 |
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
340 |
</div>
|
341 |
-
<div class='sp-notice sp-notice-success sp-floating-block sp-single-width' style="height: 80px;overflow:hidden;padding-right: 0;">
|
342 |
<div style="float:left; margin-top:-5px">
|
343 |
<p style='margin-bottom: -2px; font-weight: bold;'>
|
344 |
<?php _e('Share your optimization results:','shortpixel-image-optimiser');?>
|
@@ -399,11 +422,11 @@ class ShortPixelView {
|
|
399 |
</div>
|
400 |
<?php } ?>
|
401 |
</div>
|
402 |
-
<div id="sp-bulk-stats" style="display:none">
|
403 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
404 |
</div>
|
405 |
</div>
|
406 |
-
<p><?php printf(__('Go to the ShortPixel <a href="%soptions-general.php?page=wp-shortpixel
|
407 |
and see all your websites\' optimized stats. Download your detailed <a href="https://%s/v2/report.php?key=%s">Optimization Report</a>
|
408 |
to check your image optimization statistics for the last 40 days.','shortpixel-image-optimiser'),
|
409 |
get_admin_url(), SHORTPIXEL_API, (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) );?></p>
|
@@ -530,7 +553,7 @@ class ShortPixelView {
|
|
530 |
<input type='checkbox' id='bulk-thumbnails' name='thumbnails' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>
|
531 |
onchange="ShortPixel.onBulkThumbsCheck(this)"> <?php _e('Include thumbnails','shortpixel-image-optimiser');?><br><br>
|
532 |
|
533 |
-
<a style="float: right;
|
534 |
|
535 |
<input type='submit' name='bulkProcess' id='bulkProcess' class='button button-primary' value='<?php _e('Restart Optimizing','shortpixel-image-optimiser');?>'
|
536 |
<?php echo($settings->quotaExceeded? "disabled title=\"" . __("Top-up your account to optimize more images.",'shortpixel-image-optimiser')."\"" : ""); ?>>
|
@@ -538,7 +561,9 @@ class ShortPixelView {
|
|
538 |
|
539 |
|
540 |
<input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup',event)" style="float: right;margin-right:10px;">
|
541 |
-
|
|
|
|
|
542 |
</form>
|
543 |
</div>
|
544 |
<?php } ?>
|
@@ -623,16 +648,25 @@ class ShortPixelView {
|
|
623 |
} else {
|
624 |
$percentAfter = $percent . "%";
|
625 |
}
|
|
|
|
|
|
|
|
|
626 |
?>
|
627 |
<div class="sp-notice sp-notice-info bulk-progress sp-floating-block sp-full-width">
|
628 |
<div style="float:right">
|
629 |
-
<?php if(false) { ?>
|
630 |
<div class="bulk-progress-indicator">
|
631 |
<div style="margin-bottom:5px"><?php _e('Remaining credits','shortpixel-image-optimiser');?></div>
|
632 |
<div style="margin-top:22px;margin-bottom: 5px;font-size:2em;font-weight: bold;"><?php echo(number_format($remainingQuota))?></div>
|
633 |
<div>images</div>
|
634 |
</div>
|
635 |
<?php } ?>
|
|
|
|
|
|
|
|
|
|
|
636 |
<div class="bulk-progress-indicator">
|
637 |
<div style="margin-bottom:5px"><?php _e('Average reduction','shortpixel-image-optimiser');?></div>
|
638 |
<div id="sp-avg-optimization"><input type="text" id="sp-avg-optimization-dial-bulk" value="<?php echo("" . round($averageCompression))?>" class="dial"></div>
|
@@ -642,6 +676,7 @@ class ShortPixelView {
|
|
642 |
});
|
643 |
</script>
|
644 |
</div>
|
|
|
645 |
</div>
|
646 |
<?php if($running) {
|
647 |
if($type > 0) { ?>
|
@@ -694,7 +729,7 @@ class ShortPixelView {
|
|
694 |
<span class="resumeLabel"><?php echo( !$running ? __('Resume: ','shortpixel-image-optimiser') : "");?></span>
|
695 |
</form>
|
696 |
<?php } else { ?>
|
697 |
-
<a href="options-general.php?page=wp-shortpixel" class="button button-primary bulk-cancel" style="margin-left:10px"><?php _e('Manage custom folders','shortpixel-image-optimiser');?></a>
|
698 |
<?php }?>
|
699 |
</div>
|
700 |
<?php
|
@@ -729,6 +764,8 @@ class ShortPixelView {
|
|
729 |
</div>
|
730 |
<?php
|
731 |
}
|
|
|
|
|
732 |
function displaySettings($showApiKey, $editApiKey, $quotaData, $notice, $resources = null, $averageCompression = null, $savedSpace = null, $savedBandwidth = null,
|
733 |
$remainingImages = null, $totalCallsMade = null, $fileCount = null, $backupFolderSize = null,
|
734 |
$customFolders = null, $folderMsg = false, $addedFolder = false, $showAdvanced = false, $cloudflareAPI = false, $htaccessWriteable = false, $isNginx = false ) {
|
@@ -768,7 +805,7 @@ class ShortPixelView {
|
|
768 |
<?php } ?>
|
769 |
|
770 |
<article id="shortpixel-settings-tabs" class="sp-tabs">
|
771 |
-
<form name='wp_shortpixel_options' action='options-general.php?page=wp-shortpixel&noheader=true' method='post' id='wp_shortpixel_options'>
|
772 |
<section <?php echo($showAdvanced ? "" : "class='sel-tab'");?> id="tab-settings">
|
773 |
<?php if($this->ctrl->getVerifiedKey()) { ?>
|
774 |
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-settings"><?php _e('General','shortpixel-image-optimiser');?></a></h2>
|
@@ -1417,7 +1454,7 @@ class ShortPixelView {
|
|
1417 |
/**
|
1418 |
* @desc This form is used in WP back-end to allow users that use CloudFlare to save their settings
|
1419 |
*
|
1420 |
-
* @link wp-admin/options-general.php?page=wp-shortpixel
|
1421 |
*/
|
1422 |
function display_cloudflare_settings_form()
|
1423 |
{ ?>
|
@@ -1429,7 +1466,7 @@ class ShortPixelView {
|
|
1429 |
}
|
1430 |
?>
|
1431 |
<p><?php _e("If you're using Cloudflare on your site then we advise you to fill in the details below. This will allow ShortPixel to work seamlessly with Cloudflare so that any image optimized/restored by ShortPixel will be automatically updated on Cloudflare as well.",'shortpixel-image-optimiser');?></p>
|
1432 |
-
<form name='wp_shortpixel_cloudflareAPI' action='options-general.php?page=wp-shortpixel&noheader=true'
|
1433 |
method='post' id='wp_shortpixel_cloudflareAPI'>
|
1434 |
<table class="form-table">
|
1435 |
<tbody>
|
@@ -1633,9 +1670,9 @@ class ShortPixelView {
|
|
1633 |
break;
|
1634 |
case 'invalidKey':
|
1635 |
if(defined("SHORTPIXEL_API_KEY")) { // multisite key - need to be validated on each site but it's not invalid
|
1636 |
-
?> <?php _e('Please <a href="options-general.php?page=wp-shortpixel">go to Settings</a> to validate the API Key.','shortpixel-image-optimiser');?> <?php
|
1637 |
} else {
|
1638 |
-
?> <?php _e('Invalid API Key. <a href="options-general.php?page=wp-shortpixel">Check your Settings</a>','shortpixel-image-optimiser');?> <?php
|
1639 |
}
|
1640 |
break;
|
1641 |
case 'quotaExceeded':
|
@@ -1726,6 +1763,7 @@ class ShortPixelView {
|
|
1726 |
}
|
1727 |
|
1728 |
public function renderListCell($id, $status, $showActions, $thumbsRemain, $backup, $type, $invType, $message, $extraClass = '') {
|
|
|
1729 |
if($showActions && ($backup || $thumbsRemain)) { ?>
|
1730 |
<div class='sp-column-actions <?php echo($extraClass);?>'>
|
1731 |
<div class="sp-dropdown">
|
1 |
<?php
|
2 |
+
use \ShortPixel\ShortPixelLogger as Log;
|
3 |
|
4 |
class ShortPixelView {
|
5 |
|
6 |
private $ctrl;
|
7 |
|
8 |
+
protected $bulkType;
|
9 |
+
|
10 |
public function __construct($controller) {
|
11 |
$this->ctrl = $controller;
|
12 |
}
|
51 |
<?php } ?></p>
|
52 |
<div> <!-- style='float:right;margin-top:20px;'> -->
|
53 |
<button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-right:10px;"><strong>
|
54 |
+
<?php _e('Show me the best available options', 'shortpixel-image-optimiser'); ?></strong></button>
|
55 |
<a class='button button-primary' href='https://shortpixel.com/login/<?php echo($this->ctrl->getApiKey());?>'
|
56 |
title='<?php _e('Go to my account and select a plan','shortpixel-image-optimiser');?>' target='_blank' style="margin-right:10px;">
|
57 |
<strong><?php _e('Upgrade','shortpixel-image-optimiser');?></strong>
|
71 |
public static function displayApiKeyAlert()
|
72 |
{ ?>
|
73 |
<p><?php _e('In order to start the optimization process, you need to validate your API Key in the '
|
74 |
+
. '<a href="options-general.php?page=wp-shortpixel-settings">ShortPixel Settings</a> page in your WordPress Admin.','shortpixel-image-optimiser');?>
|
75 |
</p>
|
76 |
<p><?php _e('If you don’t have an API Key, you can get one delivered to your inbox, for free.','shortpixel-image-optimiser');?></p>
|
77 |
<p><?php _e('Please <a href="https://shortpixel.com/wp-apikey' . WPShortPixel::getAffiliateSufix() . '" target="_blank">sign up to get your API key.</a>','shortpixel-image-optimiser');?>
|
99 |
<div style="float:right;">
|
100 |
<?php if($when == 'upgmonth' || $when == 'upgbulk'){ ?>
|
101 |
<button class="button button-primary" id="shortpixel-upgrade-advice" onclick="ShortPixel.proposeUpgrade()" style="margin-top:10px;margin-left:10px;"><strong>
|
102 |
+
<?php _e('Show me the best available options', 'shortpixel-image-optimiser'); ?></strong></button>
|
103 |
<?php } ?>
|
104 |
<?php if($when == 'unlisted'){ ?>
|
105 |
<a href="javascript:ShortPixel.includeUnlisted()" class="button button-primary" style="margin-top:10px;margin-left:10px;">
|
161 |
<p> <?php
|
162 |
if($when == 'upgmonth') {
|
163 |
printf(__("You are adding an average of <strong>%d images and thumbnails every month</strong> to your Media Library and you have <strong>a plan of %d images/month</strong>."
|
164 |
+
. " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel-image-optimiser'), $extra['monthAvg'], $extra['monthlyQuota']);
|
165 |
} else {
|
166 |
printf(__("You currently have <strong>%d images and thumbnails to optimize</strong> but you only have <strong>%d images</strong> available in your current plan."
|
167 |
+
. " You might need to upgrade your plan in order to have all your images optimized.", 'shortpixel-image-optimiser'), $extra['filesTodo'], $extra['quotaAvailable']);
|
168 |
}?></p><?php
|
169 |
self::includeProposeUpgradePopup();
|
170 |
break;
|
207 |
public function displayBulkProcessingForm($quotaData, $thumbsProcessedCount, $under5PercentCount, $bulkRan,
|
208 |
$averageCompression, $filesOptimized, $savedSpace, $percent, $customCount) {
|
209 |
$settings = $this->ctrl->getSettings();
|
210 |
+
//$this->ctrl->outputHSBeacon();
|
211 |
+
\ShortPixel\HelpScout::outputBeacon($this->ctrl->getApiKey());
|
212 |
+
|
213 |
+
$this->bulkType = $this->ctrl->getPrioQ()->getBulkTypeForDisplay(); // adding to the mess
|
214 |
+
$hider = ($this->bulkType == ShortPixelQueue::BULK_TYPE_RESTORE) ? 'sp-hidden' : '';
|
215 |
?>
|
216 |
<div class="wrap short-pixel-bulk-page">
|
217 |
<h1><?php _e('Bulk Image Optimization by ShortPixel','shortpixel-image-optimiser');?></h1>
|
278 |
</div>
|
279 |
</a>
|
280 |
</div>
|
281 |
+
<?php } else {?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
282 |
<div class="bulk-play bulk-nothing-optimize">
|
283 |
<?php _e('Nothing to optimize! The images that you add to Media Gallery will be automatically optimized after upload.','shortpixel-image-optimiser');?>
|
284 |
</div>
|
285 |
<?php } ?>
|
286 |
+
<?php if($quotaData['mainProcessedMlFiles'] > 0) {?>
|
287 |
+
<div style="position: absolute;bottom: 10px;right: 10px;">
|
288 |
+
<?php /* <input type='submit' name='bulkRestore' id='bulkRestore' class='button' value='<?php _e('Bulk Restore Media Library','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Restore', event)" style="margin-bottom:10px;">
|
289 |
+
*/ ?>
|
290 |
+
<p><a class='button' style="width:100%; text-align: center" href='<?php echo add_query_arg('part','bulk-restore-all'); ?> '><?php _e('Bulk Restore Images','shortpixel-image-optimiser'); ?></a></p>
|
291 |
+
|
292 |
+
|
293 |
+
<input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>'
|
294 |
+
onclick="ShortPixel.confirmBulkAction('Cleanup', event)" style="width:100%; text-align: center">
|
295 |
+
|
296 |
+
|
297 |
+
<?php if (Log::debugIsActive() ) { ?>
|
298 |
+
<input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)">
|
299 |
+
<?php } ?>
|
300 |
+
</div>
|
301 |
+
<?php } ?>
|
302 |
</form>
|
303 |
</div>
|
304 |
<?php if($quotaData['totalFiles'] - $quotaData['totalProcessedFiles'] > 0) { ?>
|
344 |
<img src="<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?>"
|
345 |
srcset='<?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider.png' ));?> 1x, <?php echo(plugins_url( 'shortpixel-image-optimiser/res/img/slider@2x.png' ));?> 2x'>
|
346 |
</div>
|
347 |
+
<div class="sp-bulk-summary <?php echo $hider ?>">
|
348 |
<input type="text" value="<?php echo("" . round($averageCompression))?>" id="sp-total-optimization-dial" class="dial">
|
349 |
</div>
|
350 |
+
<?php if ($this->bulkType != ShortPixelQueue::BULK_TYPE_RESTORE): ?>
|
351 |
<p style="margin-top:4px;">
|
352 |
<span style="font-size:1.2em;font-weight:bold"><?php _e('Congratulations!','shortpixel-image-optimiser');?></span><br>
|
353 |
<?php _e('Your media library has been successfully optimized!','shortpixel-image-optimiser');?>
|
354 |
<span class="sp-bulk-summary"><a href='javascript:void(0);'><?php _e('Summary','shortpixel-image-optimiser');?></a></span>
|
355 |
</p>
|
356 |
+
<?php else: ?>
|
357 |
+
<p style="margin-top:4px;">
|
358 |
+
<span style="font-size:1.2em;font-weight:bold"><?php _e('Restoring completed','shortpixel-image-optimiser');?></span><br>
|
359 |
+
<?php _e('Your images have been restored','shortpixel-image-optimiser');?>
|
360 |
+
<span class="sp-bulk-summary"><a href='javascript:void(0);'><?php _e('Summary','shortpixel-image-optimiser');?></a></span>
|
361 |
+
</p>
|
362 |
+
<?php endif; ?>
|
363 |
</div>
|
364 |
+
<div class='sp-notice sp-notice-success sp-floating-block sp-single-width <?php echo $hider ?>' style="height: 80px;overflow:hidden;padding-right: 0;">
|
365 |
<div style="float:left; margin-top:-5px">
|
366 |
<p style='margin-bottom: -2px; font-weight: bold;'>
|
367 |
<?php _e('Share your optimization results:','shortpixel-image-optimiser');?>
|
422 |
</div>
|
423 |
<?php } ?>
|
424 |
</div>
|
425 |
+
<div id="sp-bulk-stats <?php echo $hider ?>" style="display:none">
|
426 |
<?php $this->displayBulkStats($quotaData['totalProcessedFiles'], $quotaData['mainProcessedFiles'], $under5PercentCount, $averageCompression, $savedSpace);?>
|
427 |
</div>
|
428 |
</div>
|
429 |
+
<p><?php printf(__('Go to the ShortPixel <a href="%soptions-general.php?page=wp-shortpixel-settings&part=stats">Stats</a>
|
430 |
and see all your websites\' optimized stats. Download your detailed <a href="https://%s/v2/report.php?key=%s">Optimization Report</a>
|
431 |
to check your image optimization statistics for the last 40 days.','shortpixel-image-optimiser'),
|
432 |
get_admin_url(), SHORTPIXEL_API, (defined("SHORTPIXEL_HIDE_API_KEY") ? '' : $this->ctrl->getApiKey()) );?></p>
|
553 |
<input type='checkbox' id='bulk-thumbnails' name='thumbnails' <?php echo($this->ctrl->processThumbnails() ? "checked":"");?>
|
554 |
onchange="ShortPixel.onBulkThumbsCheck(this)"> <?php _e('Include thumbnails','shortpixel-image-optimiser');?><br><br>
|
555 |
|
556 |
+
<a class='button' style="float: right;" href='<?php echo add_query_arg('part','bulk-restore-all'); ?> '><?php _e('Bulk Restore Images','shortpixel-image-optimiser'); ?></a>
|
557 |
|
558 |
<input type='submit' name='bulkProcess' id='bulkProcess' class='button button-primary' value='<?php _e('Restart Optimizing','shortpixel-image-optimiser');?>'
|
559 |
<?php echo($settings->quotaExceeded? "disabled title=\"" . __("Top-up your account to optimize more images.",'shortpixel-image-optimiser')."\"" : ""); ?>>
|
561 |
|
562 |
|
563 |
<input type='submit' name='bulkCleanup' id='bulkCleanup' class='button' value='<?php _e('Bulk Delete SP Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('Cleanup',event)" style="float: right;margin-right:10px;">
|
564 |
+
<?php if (Log::debugIsActive() ) { ?>
|
565 |
+
<input type='submit' name='bulkCleanupPending' id='bulkCleanupPending' class='button' value='<?php _e('Bulk Delete Pending Metadata','shortpixel-image-optimiser');?>' onclick="ShortPixel.confirmBulkAction('CleanupPending', event)">
|
566 |
+
<?php } ?>
|
567 |
</form>
|
568 |
</div>
|
569 |
<?php } ?>
|
648 |
} else {
|
649 |
$percentAfter = $percent . "%";
|
650 |
}
|
651 |
+
|
652 |
+
// should not be needed.. (but for some reason works)
|
653 |
+
$this->bulkType = $this->ctrl->getPrioQ()->getBulkType(); // adding to the mess
|
654 |
+
|
655 |
?>
|
656 |
<div class="sp-notice sp-notice-info bulk-progress sp-floating-block sp-full-width">
|
657 |
<div style="float:right">
|
658 |
+
<?php if(false) { // @todo This never runs? ?>
|
659 |
<div class="bulk-progress-indicator">
|
660 |
<div style="margin-bottom:5px"><?php _e('Remaining credits','shortpixel-image-optimiser');?></div>
|
661 |
<div style="margin-top:22px;margin-bottom: 5px;font-size:2em;font-weight: bold;"><?php echo(number_format($remainingQuota))?></div>
|
662 |
<div>images</div>
|
663 |
</div>
|
664 |
<?php } ?>
|
665 |
+
|
666 |
+
<?php
|
667 |
+
Log::addDebug('bulktype', array('b' => $this->bulkType));
|
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>
|
672 |
<div id="sp-avg-optimization"><input type="text" id="sp-avg-optimization-dial-bulk" value="<?php echo("" . round($averageCompression))?>" class="dial"></div>
|
676 |
});
|
677 |
</script>
|
678 |
</div>
|
679 |
+
<?php endif; ?>
|
680 |
</div>
|
681 |
<?php if($running) {
|
682 |
if($type > 0) { ?>
|
729 |
<span class="resumeLabel"><?php echo( !$running ? __('Resume: ','shortpixel-image-optimiser') : "");?></span>
|
730 |
</form>
|
731 |
<?php } else { ?>
|
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
|
764 |
</div>
|
765 |
<?php
|
766 |
}
|
767 |
+
|
768 |
+
// @TODO Remove this function
|
769 |
function displaySettings($showApiKey, $editApiKey, $quotaData, $notice, $resources = null, $averageCompression = null, $savedSpace = null, $savedBandwidth = null,
|
770 |
$remainingImages = null, $totalCallsMade = null, $fileCount = null, $backupFolderSize = null,
|
771 |
$customFolders = null, $folderMsg = false, $addedFolder = false, $showAdvanced = false, $cloudflareAPI = false, $htaccessWriteable = false, $isNginx = false ) {
|
805 |
<?php } ?>
|
806 |
|
807 |
<article id="shortpixel-settings-tabs" class="sp-tabs">
|
808 |
+
<form name='wp_shortpixel_options' action='options-general.php?page=wp-shortpixel-settings&noheader=true' method='post' id='wp_shortpixel_options'>
|
809 |
<section <?php echo($showAdvanced ? "" : "class='sel-tab'");?> id="tab-settings">
|
810 |
<?php if($this->ctrl->getVerifiedKey()) { ?>
|
811 |
<h2><a class='tab-link' href='javascript:void(0);' data-id="tab-settings"><?php _e('General','shortpixel-image-optimiser');?></a></h2>
|
1454 |
/**
|
1455 |
* @desc This form is used in WP back-end to allow users that use CloudFlare to save their settings
|
1456 |
*
|
1457 |
+
* @link wp-admin/options-general.php?page=wp-shortpixel-settings
|
1458 |
*/
|
1459 |
function display_cloudflare_settings_form()
|
1460 |
{ ?>
|
1466 |
}
|
1467 |
?>
|
1468 |
<p><?php _e("If you're using Cloudflare on your site then we advise you to fill in the details below. This will allow ShortPixel to work seamlessly with Cloudflare so that any image optimized/restored by ShortPixel will be automatically updated on Cloudflare as well.",'shortpixel-image-optimiser');?></p>
|
1469 |
+
<form name='wp_shortpixel_cloudflareAPI' action='options-general.php?page=wp-shortpixel-settings&noheader=true'
|
1470 |
method='post' id='wp_shortpixel_cloudflareAPI'>
|
1471 |
<table class="form-table">
|
1472 |
<tbody>
|
1670 |
break;
|
1671 |
case 'invalidKey':
|
1672 |
if(defined("SHORTPIXEL_API_KEY")) { // multisite key - need to be validated on each site but it's not invalid
|
1673 |
+
?> <?php _e('Please <a href="options-general.php?page=wp-shortpixel-settings">go to Settings</a> to validate the API Key.','shortpixel-image-optimiser');?> <?php
|
1674 |
} else {
|
1675 |
+
?> <?php _e('Invalid API Key. <a href="options-general.php?page=wp-shortpixel-settings">Check your Settings</a>','shortpixel-image-optimiser');?> <?php
|
1676 |
}
|
1677 |
break;
|
1678 |
case 'quotaExceeded':
|
1763 |
}
|
1764 |
|
1765 |
public function renderListCell($id, $status, $showActions, $thumbsRemain, $backup, $type, $invType, $message, $extraClass = '') {
|
1766 |
+
|
1767 |
if($showActions && ($backup || $thumbsRemain)) { ?>
|
1768 |
<div class='sp-column-actions <?php echo($extraClass);?>'>
|
1769 |
<div class="sp-dropdown">
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Debug Box to load Log File
|
3 |
+
namespace ShortPixel;
|
4 |
+
wp_enqueue_script( 'jquery-ui-draggable' );
|
5 |
+
?>
|
6 |
+
|
7 |
+
<style>
|
8 |
+
.sp_debug_box
|
9 |
+
{
|
10 |
+
position: absolute;
|
11 |
+
right: 0px;
|
12 |
+
top: 50px;
|
13 |
+
background-color: #fff;
|
14 |
+
width: 100px;
|
15 |
+
z-index: 1000000;
|
16 |
+
border: 1px solid #000;
|
17 |
+
}
|
18 |
+
.sp_debug_box .header
|
19 |
+
{
|
20 |
+
min-height: 10px;
|
21 |
+
background: #000;
|
22 |
+
color: #fff;
|
23 |
+
}
|
24 |
+
.sp_debug_box .content_box
|
25 |
+
{
|
26 |
+
background: #ccc;
|
27 |
+
}
|
28 |
+
</style>
|
29 |
+
|
30 |
+
<script language='javascript'>
|
31 |
+
jQuery(document).ready(function($)
|
32 |
+
{
|
33 |
+
$( ".sp_debug_box" ).draggable();
|
34 |
+
|
35 |
+
});
|
36 |
+
</script>
|
37 |
+
|
38 |
+
<div class='sp_debug_box'>
|
39 |
+
<div class='header'>Debug Box </div>
|
40 |
+
<a target="_blank" href='<?php echo $this->layout->logLink ?>'>Logfile</a>
|
41 |
+
<div class='content_box'>
|
42 |
+
|
43 |
+
</div>
|
44 |
+
</div>
|
@@ -42,6 +42,9 @@
|
|
42 |
<button disabled aria-disabled="true" type='submit' class='button bulk restore disabled' name='bulkRestore' id='bulkRestore'><?php _e('Bulk Restore', 'shortpixel-image-optimiser'); ?></button>
|
43 |
</div>
|
44 |
|
|
|
|
|
|
|
45 |
</div> <!-- sp-notice -->
|
46 |
</form>
|
47 |
</div> <!-- wrap -->
|
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-optimizer'); ?></p>
|
46 |
+
</div>
|
47 |
+
|
48 |
</div> <!-- sp-notice -->
|
49 |
</form>
|
50 |
</div> <!-- wrap -->
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use Shortpixel\ShortPixelLogger as Log;
|
4 |
+
|
5 |
+
HelpScout::outputBeacon($view->data->apiKey);
|
6 |
+
|
7 |
+
?>
|
8 |
+
<div class="wrap">
|
9 |
+
<h1><?php _e('ShortPixel Plugin Settings','shortpixel-image-optimiser');?></h1>
|
10 |
+
<p class='top-menu'>
|
11 |
+
|
12 |
+
<a href="https://shortpixel.com/<?php
|
13 |
+
echo(($view->data->apiKey ? "login/".( $this->hide_api_key ? '' : $view->data->apiKey) : "pricing"));
|
14 |
+
?>" target="_blank">
|
15 |
+
<?php _e('Upgrade now','shortpixel-image-optimiser');?>
|
16 |
+
</a> | <a href="https://shortpixel.com/pricing>#faq" target="_blank"><?php _e('FAQ','shortpixel-image-optimiser');?> </a> |
|
17 |
+
<a href="https://shortpixel.com/contact" target="_blank"><?php _e('Support','shortpixel-image-optimiser');?> </a>
|
18 |
+
</p>
|
19 |
+
|
20 |
+
|
21 |
+
<article id="shortpixel-settings-tabs" class="sp-tabs">
|
22 |
+
<?php if (! $this->is_verifiedkey)
|
23 |
+
{
|
24 |
+
$this->loadView('settings/part-nokey');
|
25 |
+
} ?>
|
26 |
+
|
27 |
+
<?php
|
28 |
+
if ($this->is_verifiedkey):
|
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');
|
35 |
+
$this->loadView('settings/part-advanced');
|
36 |
+
$this->loadView('settings/part-cloudflare');
|
37 |
+
if ($view->averageCompression !== null)
|
38 |
+
{
|
39 |
+
$this->loadView('settings/part-statistics');
|
40 |
+
}
|
41 |
+
if (Log::debugIsActive())
|
42 |
+
{
|
43 |
+
$this->loadView('settings/part-debug');
|
44 |
+
}
|
45 |
+
?>
|
46 |
+
</div>
|
47 |
+
</form>
|
48 |
+
<?php
|
49 |
+
endif;
|
50 |
+
?>
|
51 |
+
|
52 |
+
</article>
|
53 |
+
|
54 |
+
<?php // @todo inline JS ?>
|
55 |
+
<script>
|
56 |
+
jQuery(document).ready(function(){
|
57 |
+
ShortPixel.initSettings();
|
58 |
+
});
|
59 |
+
</script>
|
@@ -1,5 +1,10 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
|
|
|
|
3 |
class WPShortPixel {
|
4 |
|
5 |
const BULK_EMPTY_QUEUE = 0;
|
@@ -41,6 +46,9 @@ class WPShortPixel {
|
|
41 |
$controllerClass = ShortPixelTools::namespaceit('ShortPixelController');
|
42 |
$controllerClass::init(); // load all subclassed controllers.
|
43 |
|
|
|
|
|
|
|
44 |
define('QUOTA_EXCEEDED', $this->view->getQuotaExceededHTML());
|
45 |
|
46 |
if( !defined('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES')) {
|
@@ -94,7 +102,7 @@ class WPShortPixel {
|
|
94 |
|
95 |
if($isAdminUser) {
|
96 |
//add settings page
|
97 |
-
add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
98 |
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
99 |
|
100 |
add_action('wp_ajax_shortpixel_browse_content', array(&$this, 'browseContent'));
|
@@ -140,7 +148,8 @@ class WPShortPixel {
|
|
140 |
add_action('wp_ajax_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
141 |
add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
142 |
//This adds the constants used in PHP to be available also in JS
|
143 |
-
add_action( '
|
|
|
144 |
add_action( 'admin_head', array( $this, 'headCSS') );
|
145 |
|
146 |
if($this->_settings->frontBootstrap && shortPixelCheckQueue()) {
|
@@ -156,9 +165,10 @@ class WPShortPixel {
|
|
156 |
$this->migrateBackupFolder();
|
157 |
|
158 |
// [BS] Quite dangerous to do this in any constructor. Can hit if request is ajax to name something
|
|
|
159 |
if(!$this->_settings->redirectedSettings && !$this->_settings->verifiedKey && (!function_exists("is_multisite") || !is_multisite())) {
|
160 |
$this->_settings->redirectedSettings = 1;
|
161 |
-
wp_redirect(admin_url("options-general.php?page=wp-shortpixel"));
|
162 |
exit();
|
163 |
}
|
164 |
|
@@ -169,10 +179,14 @@ class WPShortPixel {
|
|
169 |
$this->__construct();
|
170 |
}
|
171 |
|
|
|
|
|
172 |
public function registerSettingsPage() {
|
173 |
-
|
174 |
}
|
175 |
|
|
|
|
|
176 |
function registerAdminPage( ) {
|
177 |
if($this->spMetaDao->hasFoldersTable() && count($this->spMetaDao->getFolders())) {
|
178 |
/*translators: title and menu name for the Other media page*/
|
@@ -331,6 +345,9 @@ class WPShortPixel {
|
|
331 |
return $found;
|
332 |
}
|
333 |
|
|
|
|
|
|
|
334 |
public function displayAdminNotices() {
|
335 |
if(!ShortPixelQueue::testQ()) {
|
336 |
ShortPixelView::displayActivationNotice('fileperms');
|
@@ -442,40 +459,40 @@ class WPShortPixel {
|
|
442 |
}
|
443 |
|
444 |
static function log($message, $force = false) {
|
|
|
|
|
445 |
if (SHORTPIXEL_DEBUG === true || $force) {
|
446 |
if (is_array($message) || is_object($message)) {
|
447 |
self::doLog(print_r($message, true), $force);
|
448 |
} else {
|
449 |
self::doLog($message, $force);
|
450 |
}
|
451 |
-
}
|
452 |
}
|
453 |
|
|
|
454 |
static protected function doLog($message, $force = false) {
|
455 |
-
|
|
|
456 |
file_put_contents(SHORTPIXEL_BACKUP_FOLDER . "/shortpixel_log", '[' . date('Y-m-d H:i:s') . "] $message\n", FILE_APPEND);
|
457 |
} else {
|
458 |
error_log($message);
|
459 |
-
}
|
460 |
}
|
461 |
|
462 |
function headCSS() {
|
463 |
echo('<style>.shortpixel-hide {display:none;}</style>');
|
464 |
}
|
465 |
|
|
|
466 |
function shortPixelJS() {
|
|
|
467 |
//require_once(ABSPATH . 'wp-admin/includes/screen.php');
|
468 |
if(function_exists('get_current_screen')) {
|
469 |
$screen = get_current_screen();
|
470 |
|
471 |
if(is_object($screen)) {
|
472 |
-
|
473 |
-
//output the comparer html
|
474 |
-
$this->view->outputComparerHTML();
|
475 |
-
//render a template of the list cell to be used by the JS
|
476 |
-
$this->view->renderListCell("__SP_ID__", 'imgOptimized', true, "__SP_THUMBS_TOTAL__", true, true,
|
477 |
-
array("__SP_FIRST_TYPE__", "__SP_SECOND_TYPE__"), "__SP_CELL_MESSAGE__", 'sp-column-actions-template');
|
478 |
-
}
|
479 |
|
480 |
wp_enqueue_style('short-pixel-bar.min.css', plugins_url('/res/css/short-pixel-bar.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
481 |
if( in_array($screen->id, array('attachment', 'upload', 'settings_page_wp-shortpixel', 'media_page_wp-short-pixel-bulk', 'media_page_wp-short-pixel-custom'))) {
|
@@ -483,25 +500,16 @@ class WPShortPixel {
|
|
483 |
//modal - used in settings for selecting folder
|
484 |
wp_enqueue_style('short-pixel-modal.min.css', plugins_url('/res/css/short-pixel-modal.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
485 |
|
|
|
486 |
wp_register_style('shortpixel-admin', plugins_url('/res/css/shortpixel-admin.css', SHORTPIXEL_PLUGIN_FILE),array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION );
|
487 |
wp_enqueue_style('shortpixel-admin');
|
488 |
}
|
489 |
}
|
490 |
}
|
491 |
-
?>
|
492 |
-
<script type="text/javascript" >
|
493 |
-
//check after 10 seconds if ShortPixel initialized OK, if not, force the init (could happen if a JS error somewhere else stopped the JS execution).
|
494 |
-
function delayedInit() {
|
495 |
-
if(typeof ShortPixel !== "undefined") {
|
496 |
-
ShortPixel.init();
|
497 |
-
} else {
|
498 |
-
setTimeout(delayedInit, 10000);
|
499 |
-
}
|
500 |
-
}
|
501 |
-
setTimeout(delayedInit, 10000);
|
502 |
-
</script> <?php
|
503 |
|
504 |
-
|
|
|
|
|
505 |
|
506 |
// Using an Array within another Array to protect the primitive values from being cast to strings
|
507 |
$ShortPixelConstants = array(array(
|
@@ -518,13 +526,20 @@ class WPShortPixel {
|
|
518 |
'WP_PLUGIN_URL'=>plugins_url( '', SHORTPIXEL_PLUGIN_FILE ),
|
519 |
'WP_ADMIN_URL'=>admin_url(),
|
520 |
'API_KEY'=> (defined("SHORTPIXEL_HIDE_API_KEY" ) || !is_admin() ) ? '' : $this->_settings->apiKey,
|
521 |
-
'DEFAULT_COMPRESSION'=>0 + $this->_settings->compressionType,
|
522 |
'MEDIA_ALERT'=>$this->_settings->mediaAlert ? "done" : "todo",
|
523 |
'FRONT_BOOTSTRAP'=>$this->_settings->frontBootstrap && (!isset($this->_settings->lastBackAction) || (time() - $this->_settings->lastBackAction > 600)) ? 1 : 0,
|
524 |
'AJAX_URL'=>admin_url('admin-ajax.php'),
|
525 |
'AFFILIATE'=>self::getAffiliateSufix()
|
526 |
));
|
527 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
528 |
$jsTranslation = array(
|
529 |
'optimizeWithSP' => __( 'Optimize with ShortPixel', 'shortpixel-image-optimiser' ),
|
530 |
'redoLossy' => __( 'Re-optimize Lossy', 'shortpixel-image-optimiser' ),
|
@@ -564,6 +579,42 @@ class WPShortPixel {
|
|
564 |
wp_enqueue_script('punycode.min.js', plugins_url('/res/js/punycode.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
565 |
}
|
566 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
567 |
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
568 |
|
569 |
$extraClasses = " shortpixel-hide";
|
@@ -583,7 +634,7 @@ class WPShortPixel {
|
|
583 |
$tooltip = '';
|
584 |
$exceedTooltip = __('ShortPixel quota exceeded. Click for details.','shortpixel-image-optimiser');
|
585 |
//$link = "http://shortpixel.com/login/" . $this->_settings->apiKey;
|
586 |
-
$link = "options-general.php?page=wp-shortpixel";
|
587 |
//$blank = '_blank';
|
588 |
//$icon = "shortpixel-alert.png";
|
589 |
}
|
@@ -638,7 +689,21 @@ class WPShortPixel {
|
|
638 |
// 2. Perform the action
|
639 |
case 'short-pixel-bulk':
|
640 |
foreach( $mediaIds as $ID ) {
|
|
|
641 |
$meta = wp_get_attachment_metadata($ID);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
642 |
if( ( !isset($meta['ShortPixel']) //never touched by ShortPixel
|
643 |
|| (isset($meta['ShortPixel']['WaitingProcessing']) && $meta['ShortPixel']['WaitingProcessing'] == true))
|
644 |
&& (!isset($meta['ShortPixelImprovement']) || $meta['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser'))) {
|
@@ -779,7 +844,7 @@ class WPShortPixel {
|
|
779 |
$meta = $itemHandler->getMeta();
|
780 |
|
781 |
$doDump = false;
|
782 |
-
|
783 |
if ($meta->getStatus() <= 0)
|
784 |
{
|
785 |
$doDump = true; // dump any caching on files that ended in an error.
|
@@ -1020,11 +1085,19 @@ class WPShortPixel {
|
|
1020 |
}
|
1021 |
$idList = array();
|
1022 |
$itemList = array();
|
|
|
|
|
|
|
|
|
1023 |
for ($sanityCheck = 0, $crtStartQueryID = $startQueryID;
|
1024 |
($crtStartQueryID >= $endQueryID) && (count($itemList) < SHORTPIXEL_PRESEND_ITEMS) && ($sanityCheck < 150)
|
1025 |
-
&& (
|
1026 |
|
1027 |
-
|
|
|
|
|
|
|
|
|
1028 |
|
1029 |
/* $queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
1030 |
WHERE ( post_id <= $crtStartQueryID AND post_id >= $endQueryID )
|
@@ -1033,7 +1106,9 @@ class WPShortPixel {
|
|
1033 |
LIMIT " . SHORTPIXEL_MAX_RESULTS_QUERY;
|
1034 |
$resultsPostMeta = $wpdb->get_results($queryPostMeta);
|
1035 |
*/
|
1036 |
-
|
|
|
|
|
1037 |
|
1038 |
if ( empty($resultsPostMeta) ) {
|
1039 |
$crtStartQueryID -= SHORTPIXEL_MAX_RESULTS_QUERY;
|
@@ -1045,11 +1120,21 @@ class WPShortPixel {
|
|
1045 |
continue;
|
1046 |
}
|
1047 |
|
|
|
|
|
1048 |
foreach ( $resultsPostMeta as $itemMetaData ) {
|
1049 |
$crtStartQueryID = $itemMetaData->post_id;
|
|
|
|
|
|
|
|
|
|
|
1050 |
if(!in_array($crtStartQueryID, $idList) && $this->isProcessable($crtStartQueryID, ($this->_settings->optimizePdfs ? array() : array('pdf')))) {
|
1051 |
$item = new ShortPixelMetaFacade($crtStartQueryID);
|
|
|
|
|
1052 |
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
|
|
1053 |
|
1054 |
if($meta->getStatus() != 2) {
|
1055 |
$addIt = (strpos($meta->getMessage(), __('Image files are missing.', 'shortpixel-image-optimiser')) === false);
|
@@ -1079,7 +1164,9 @@ class WPShortPixel {
|
|
1079 |
}
|
1080 |
elseif( $this->_settings->processThumbnails && $meta->getThumbsOpt() !== null
|
1081 |
&& ($meta->getThumbsOpt() == 0 && count($meta->getThumbs()) > 0
|
1082 |
-
||
|
|
|
|
|
1083 |
$URLsAndPATHs = $item->getURLsAndPATHs(true, true, $this->_settings->optimizeRetina, $this->_settings->excludeSizes);
|
1084 |
if(count($URLsAndPATHs["URLs"])) {
|
1085 |
$meta->setThumbsTodo(true);
|
@@ -1104,9 +1191,12 @@ class WPShortPixel {
|
|
1104 |
$this->prioQ->setStartBulkId($startQueryID);
|
1105 |
} else {
|
1106 |
$crtStartQueryID--;
|
|
|
1107 |
}
|
1108 |
}
|
1109 |
-
|
|
|
|
|
1110 |
}
|
1111 |
|
1112 |
/**
|
@@ -1123,6 +1213,7 @@ class WPShortPixel {
|
|
1123 |
return $items;
|
1124 |
}
|
1125 |
|
|
|
1126 |
private function checkKey($ID) {
|
1127 |
if( $this->_settings->verifiedKey == false) {
|
1128 |
if($ID == null){
|
@@ -1168,7 +1259,7 @@ class WPShortPixel {
|
|
1168 |
|
1169 |
$rawPrioQ = $this->prioQ->get();
|
1170 |
if(count($rawPrioQ)) { self::log("HIP: 0 Priority Queue: ".json_encode($rawPrioQ)); }
|
1171 |
-
self::log("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId);
|
1172 |
|
1173 |
//handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
|
1174 |
if( $this->prioQ->bulkRunning()
|
@@ -1457,7 +1548,9 @@ class WPShortPixel {
|
|
1457 |
if($result["Status"] !== ShortPixelAPI::STATUS_RETRY) {
|
1458 |
$this->_settings->bulkLastStatus = $result;
|
1459 |
}
|
1460 |
-
|
|
|
|
|
1461 |
}
|
1462 |
|
1463 |
|
@@ -1566,11 +1659,12 @@ class WPShortPixel {
|
|
1566 |
return $URLsAndPATHs;
|
1567 |
}
|
1568 |
|
|
|
1569 |
public function handleManualOptimization() {
|
1570 |
-
$imageId = $_GET['image_id'];
|
1571 |
$cleanup = $_GET['cleanup'];
|
1572 |
|
1573 |
-
|
1574 |
|
1575 |
switch(substr($imageId, 0, 2)) {
|
1576 |
case "N-":
|
@@ -1587,6 +1681,7 @@ class WPShortPixel {
|
|
1587 |
return array("Status" => ShortPixelAPI::STATUS_FAIL, "message" => __('NextGen image not found','shortpixel-image-optimiser'));
|
1588 |
break;
|
1589 |
case "C-":
|
|
|
1590 |
throw new Exception("HandleManualOptimization for custom images not implemented");
|
1591 |
default:
|
1592 |
$this->optimizeNowHook(intval($imageId), true);
|
@@ -1596,13 +1691,20 @@ class WPShortPixel {
|
|
1596 |
|
1597 |
}
|
1598 |
|
|
|
|
|
|
|
|
|
1599 |
public function checkStatus() {
|
1600 |
-
$itemHandler = new ShortPixelMetaFacade($_GET['image_id']);
|
1601 |
$meta = $itemHandler->getMeta();
|
1602 |
die(json_encode(array("Status" => $meta->getStatus(), "Message" => $meta->getMessage())));
|
1603 |
}
|
1604 |
|
1605 |
-
|
|
|
|
|
|
|
1606 |
public function optimizeNowHook($imageId, $manual = false) {
|
1607 |
//WpShortPixel::log("OPTIMIZE NOW HOOK for ID: $imageId STACK: " . json_encode(debug_backtrace()));
|
1608 |
if($this->isProcessable($imageId)) {
|
@@ -1645,7 +1747,7 @@ class WPShortPixel {
|
|
1645 |
* @param bool $bulk - true if the regeneration is done in bulk - in this case the image will not be immediately scheduled for processing but the user will need to launch the ShortPixel bulk after regenerating.
|
1646 |
*
|
1647 |
*
|
1648 |
-
* Note - $regeneratedSizes expects
|
1649 |
*/
|
1650 |
public function thumbnailsRegeneratedHook($postId, $originalMeta, $regeneratedSizes = array(), $bulk = false) {
|
1651 |
|
@@ -1684,6 +1786,10 @@ class WPShortPixel {
|
|
1684 |
unset($this->thumbnailsRegenerating[$postId]);
|
1685 |
}
|
1686 |
|
|
|
|
|
|
|
|
|
1687 |
public function shortpixelGetBackupFilter($imagePath) {
|
1688 |
$backup = str_replace(dirname(dirname(dirname(SHORTPIXEL_BACKUP_FOLDER))),SHORTPIXEL_BACKUP_FOLDER, $imagePath);
|
1689 |
return file_exists($backup) ? $backup : false;
|
@@ -1704,7 +1810,10 @@ class WPShortPixel {
|
|
1704 |
}
|
1705 |
|
1706 |
|
1707 |
-
|
|
|
|
|
|
|
1708 |
public function handleError($ID, $result)
|
1709 |
{
|
1710 |
$meta = wp_get_attachment_metadata($ID);
|
@@ -1713,6 +1822,10 @@ class WPShortPixel {
|
|
1713 |
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
1714 |
}
|
1715 |
|
|
|
|
|
|
|
|
|
1716 |
public function getBackupFolder($file) {
|
1717 |
if(realpath($file)) {
|
1718 |
$ret = $this->getBackupFolderInternal(realpath($file)); //found cases when $file contains for example /wp/../wp-content - clean it up
|
@@ -1722,6 +1835,10 @@ class WPShortPixel {
|
|
1722 |
return $this->getBackupFolderInternal($file);
|
1723 |
}
|
1724 |
|
|
|
|
|
|
|
|
|
1725 |
private function getBackupFolderInternal($file) {
|
1726 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1727 |
$SubDir = ShortPixelMetaFacade::returnSubDir($file);
|
@@ -1745,6 +1862,11 @@ class WPShortPixel {
|
|
1745 |
return SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir;
|
1746 |
}
|
1747 |
|
|
|
|
|
|
|
|
|
|
|
1748 |
public function getBackupFolderAny($file, $thumbs) {
|
1749 |
$ret = $this->getBackupFolder($file);
|
1750 |
//if(!$ret && !file_exists($file) && isset($thumbs)) {
|
@@ -1752,12 +1874,20 @@ class WPShortPixel {
|
|
1752 |
//try with the thumbnails
|
1753 |
foreach($thumbs as $size) {
|
1754 |
$backup = $this->getBackupFolder(trailingslashit(dirname($file)) . $size['file']);
|
1755 |
-
if($backup)
|
|
|
|
|
|
|
1756 |
}
|
1757 |
}
|
1758 |
-
return apply_filters("shortpixel_backup_folder", $ret);
|
1759 |
}
|
1760 |
|
|
|
|
|
|
|
|
|
|
|
1761 |
protected function setFilePerms($file) {
|
1762 |
//die(getenv('USERNAME') ? getenv('USERNAME') : getenv('USER'));
|
1763 |
|
@@ -1956,6 +2086,8 @@ class WPShortPixel {
|
|
1956 |
set_transient("shortpixel_thrown_notice", array('when' => $when, 'extra' => $extra), 120);
|
1957 |
}
|
1958 |
|
|
|
|
|
1959 |
protected function catchNotice() {
|
1960 |
$notice = get_transient("shortpixel_thrown_notice");
|
1961 |
if(isset($notice['when'])) {
|
@@ -1981,6 +2113,9 @@ class WPShortPixel {
|
|
1981 |
return substr($file, 0, strlen($file) - 1 - strlen($ext)) . "@2x." . $ext;
|
1982 |
}
|
1983 |
|
|
|
|
|
|
|
1984 |
public function doCustomRestore($ID) {
|
1985 |
//$meta = $this->spMetaDao->getMeta($ID);
|
1986 |
// meta facade as a custom image
|
@@ -2006,7 +2141,7 @@ class WPShortPixel {
|
|
2006 |
$rename_result = @rename($bkFile, $file);
|
2007 |
if (! $rename_result)
|
2008 |
{
|
2009 |
-
|
2010 |
}
|
2011 |
|
2012 |
|
@@ -2031,7 +2166,7 @@ class WPShortPixel {
|
|
2031 |
|
2032 |
}
|
2033 |
else {
|
2034 |
-
|
2035 |
}
|
2036 |
|
2037 |
return $meta;
|
@@ -2099,13 +2234,15 @@ class WPShortPixel {
|
|
2099 |
return $ret;
|
2100 |
}
|
2101 |
|
|
|
2102 |
public function handleOptimizeThumbs() {
|
2103 |
$ID = intval($_GET['attachment_ID']);
|
2104 |
$meta = wp_get_attachment_metadata($ID);
|
2105 |
-
//die(var_dump($meta));
|
2106 |
|
2107 |
-
|
|
|
2108 |
$error = array('Status' => ShortPixelAPI::STATUS_SKIP, 'message' => __('Unspecified Error on Thumbnails for: ') . $ID);
|
|
|
2109 |
$includedSizes = WpShortPixelMediaLbraryAdapter::getSizesNotExcluded($meta['sizes'], $this->_settings->excludeSizes);
|
2110 |
$thumbsCount = count($includedSizes);
|
2111 |
|
@@ -2114,11 +2251,14 @@ class WPShortPixel {
|
|
2114 |
$error['message'] = __('Please optimize image for ID: ','shortpixel-image-optimiser') . $ID;
|
2115 |
die(json_encode($error));
|
2116 |
}
|
|
|
2117 |
if (! isset($meta['sizes']) || count($meta['sizes']) == 0)
|
2118 |
{
|
2119 |
$error['message'] = __('No thumbnails to optimize for ID: ','shortpixel-image-optimiser') . $ID;
|
2120 |
die(json_encode($error));
|
2121 |
}
|
|
|
|
|
2122 |
/* Check ThumbList against current Sizes. It's possible when a size was dropped, the SP meta was not updated, playing
|
2123 |
* tricks with the thumbcount.
|
2124 |
*
|
@@ -2136,16 +2276,26 @@ class WPShortPixel {
|
|
2136 |
$meta['ShortPixel']['thumbsOptList'] = $thumbList;
|
2137 |
}
|
2138 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2139 |
|
2140 |
-
|
2141 |
-
|
2142 |
-
|
2143 |
-
|
|
|
2144 |
|
2145 |
if( $thumbsCount
|
2146 |
&& (isset($meta['sizes']) && isset($meta['ShortPixel']['thumbsOptList']) && count($meta['ShortPixel']['thumbsOptList']) < $thumbsCount))
|
2147 |
{
|
2148 |
$meta['ShortPixel']['thumbsTodo'] = true;
|
|
|
2149 |
//wp_update_attachment_metadata($ID, $meta);
|
2150 |
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
2151 |
$this->prioQ->push($ID);
|
@@ -2165,6 +2315,7 @@ class WPShortPixel {
|
|
2165 |
} else {
|
2166 |
$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);
|
2167 |
}
|
|
|
2168 |
die(json_encode($ret));
|
2169 |
}
|
2170 |
|
@@ -2212,6 +2363,9 @@ class WPShortPixel {
|
|
2212 |
}
|
2213 |
}
|
2214 |
|
|
|
|
|
|
|
2215 |
public function deactivatePlugin() {
|
2216 |
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'sp_deactivate_plugin_nonce' ) ) {
|
2217 |
wp_nonce_ays( '' );
|
@@ -2230,9 +2384,12 @@ class WPShortPixel {
|
|
2230 |
|
2231 |
}
|
2232 |
|
|
|
|
|
|
|
2233 |
protected function deactivateAndRedirect($url){
|
2234 |
//die(ShortPixelVDD($url));
|
2235 |
-
deactivate_plugins( $_GET['plugin'] );
|
2236 |
wp_safe_redirect( $url );
|
2237 |
die();
|
2238 |
|
@@ -2276,7 +2433,8 @@ class WPShortPixel {
|
|
2276 |
$quotaData = $this->getQuotaInformation();
|
2277 |
}
|
2278 |
if ( !$quotaData['APIKeyValid']) {
|
2279 |
-
if(strlen($this->_settings->apiKey))
|
|
|
2280 |
return $quotaData;
|
2281 |
}
|
2282 |
//$tempus = microtime(true);
|
@@ -2286,7 +2444,7 @@ class WPShortPixel {
|
|
2286 |
if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
|
2287 |
$this->_settings->quotaExceeded = '0';
|
2288 |
$this->_settings->prioritySkip = NULL;
|
2289 |
-
|
2290 |
|
2291 |
?><script>var shortPixelQuotaExceeded = 0;</script><?php
|
2292 |
}
|
@@ -2297,10 +2455,17 @@ class WPShortPixel {
|
|
2297 |
return $quotaData;
|
2298 |
}
|
2299 |
|
|
|
|
|
|
|
|
|
2300 |
public function isValidMetaId($id) {
|
2301 |
return substr($id, 0, 2 ) == "C-" ? $this->spMetaDao->getMeta(substr($id, 2)) : wp_get_attachment_url($id);
|
2302 |
}
|
2303 |
|
|
|
|
|
|
|
2304 |
public function listCustomMedia() {
|
2305 |
if( ! class_exists( 'ShortPixelListTable' ) ) {
|
2306 |
require_once('view/shortpixel-list-table.php');
|
@@ -2319,21 +2484,22 @@ class WPShortPixel {
|
|
2319 |
if ( isset($_GET['noheader']) ) {
|
2320 |
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
2321 |
}
|
2322 |
-
|
|
|
2323 |
?>
|
2324 |
<div class="wrap shortpixel-other-media">
|
2325 |
<h2>
|
2326 |
-
<div style="float:right;">
|
2327 |
-
<a href="upload.php?page=wp-short-pixel-custom&refresh=1" id="refresh" class="button button-primary" title="<?php _e('Refresh custom folders content','shortpixel-image-optimiser');?>">
|
2328 |
-
<?php _e('Refresh folders','shortpixel-image-optimiser');?>
|
2329 |
-
</a>
|
2330 |
-
</div>
|
2331 |
<?php _e('Other Media optimized by ShortPixel','shortpixel-image-optimiser');?>
|
2332 |
</h2>
|
2333 |
|
2334 |
-
<div id="
|
2335 |
-
<div id="
|
2336 |
-
<div id="
|
|
|
|
|
|
|
|
|
|
|
2337 |
<div class="meta-box-sortables ui-sortable">
|
2338 |
<form method="get">
|
2339 |
<input type="hidden" name="page" value="wp-short-pixel-custom" />
|
@@ -2360,7 +2526,7 @@ class WPShortPixel {
|
|
2360 |
}
|
2361 |
|
2362 |
/** Front End function that controls bulk processes.
|
2363 |
-
*
|
2364 |
*/
|
2365 |
public function bulkProcess() {
|
2366 |
global $wpdb;
|
@@ -2415,7 +2581,7 @@ class WPShortPixel {
|
|
2415 |
|
2416 |
if(isset($_POST["bulkRestore"]))
|
2417 |
{
|
2418 |
-
$bulkRestore = new \ShortPixel\BulkRestoreAll();
|
2419 |
$bulkRestore->setShortPixel($this);
|
2420 |
$bulkRestore->setupBulk();
|
2421 |
|
@@ -2488,7 +2654,7 @@ class WPShortPixel {
|
|
2488 |
{
|
2489 |
$viewObj = new $partControl();
|
2490 |
$viewObj->setShortPixel($this);
|
2491 |
-
$viewObj->loadView();
|
2492 |
}
|
2493 |
|
2494 |
if (! $template_part)
|
@@ -2509,6 +2675,7 @@ class WPShortPixel {
|
|
2509 |
}
|
2510 |
}
|
2511 |
|
|
|
2512 |
public function bulkProgressMessage($percent, $minutes) {
|
2513 |
$timeEst = "";
|
2514 |
self::log("bulkProgressMessage(): percent: " . $percent);
|
@@ -2530,6 +2697,7 @@ class WPShortPixel {
|
|
2530 |
return $timeEst;
|
2531 |
}
|
2532 |
|
|
|
2533 |
public function emptyBackup(){
|
2534 |
if(file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
2535 |
|
@@ -2549,6 +2717,7 @@ class WPShortPixel {
|
|
2549 |
}
|
2550 |
}
|
2551 |
|
|
|
2552 |
public function backupFolderIsEmpty() {
|
2553 |
if(file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
2554 |
return count(scandir(SHORTPIXEL_BACKUP_FOLDER)) > 2 ? false : true;
|
@@ -2609,13 +2778,19 @@ class WPShortPixel {
|
|
2609 |
die();
|
2610 |
}
|
2611 |
|
|
|
|
|
|
|
|
|
|
|
2612 |
public function getComparerData() {
|
2613 |
if (!isset($_POST['id']) || !current_user_can( 'upload_files' ) && !current_user_can( 'edit_posts' ) ) {
|
2614 |
wp_die(json_encode((object)array('origUrl' => false, 'optUrl' => false, 'width' => 0, 'height' => 0)));
|
2615 |
}
|
2616 |
|
2617 |
$ret = array();
|
2618 |
-
|
|
|
2619 |
|
2620 |
$meta = $handle->getMeta();
|
2621 |
$rawMeta = $handle->getRawMeta();
|
@@ -2655,6 +2830,7 @@ class WPShortPixel {
|
|
2655 |
die(json_encode((object)$ret));
|
2656 |
}
|
2657 |
|
|
|
2658 |
public function newApiKey() {
|
2659 |
if ( !current_user_can( 'manage_options' ) ) {
|
2660 |
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
@@ -2678,7 +2854,7 @@ class WPShortPixel {
|
|
2678 |
)
|
2679 |
);
|
2680 |
|
2681 |
-
$newKeyResponse = wp_remote_post("https://shortpixel.com/free-sign-up-plugin"
|
2682 |
|
2683 |
if ( is_object($newKeyResponse) && get_class($newKeyResponse) == 'WP_Error' ) {
|
2684 |
die(json_encode((object)array('Status' => 'fail', 'Details' => '503')));
|
@@ -2746,6 +2922,7 @@ class WPShortPixel {
|
|
2746 |
|
2747 |
}
|
2748 |
|
|
|
2749 |
public static function getCustomFolderBase() {
|
2750 |
if(is_main_site()) {
|
2751 |
$base = get_home_path();
|
@@ -2756,12 +2933,14 @@ class WPShortPixel {
|
|
2756 |
}
|
2757 |
}
|
2758 |
|
|
|
2759 |
protected function fullRefreshCustomFolder($path, &$notice) {
|
2760 |
$folder = $this->spMetaDao->getFolder($path);
|
2761 |
$diff = $folder->checkFolderContents(array('ShortPixelCustomMetaDao', 'getPathFiles'));
|
2762 |
}
|
2763 |
|
2764 |
-
|
|
|
2765 |
$customFolders = array();
|
2766 |
if($this->_settings->hasCustomFolders) {
|
2767 |
$customFolders = $this->spMetaDao->getFolders();
|
@@ -2790,7 +2969,10 @@ class WPShortPixel {
|
|
2790 |
return $customFolders;
|
2791 |
}
|
2792 |
|
2793 |
-
|
|
|
|
|
|
|
2794 |
// [BS] Backward compat. 11/03/2019 - remove possible settings from root .htaccess
|
2795 |
$upload_dir = wp_upload_dir();
|
2796 |
$upload_base = trailingslashit($upload_dir['basedir']);
|
@@ -2842,6 +3024,11 @@ class WPShortPixel {
|
|
2842 |
' ;
|
2843 |
|
2844 |
insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', $rules);
|
|
|
|
|
|
|
|
|
|
|
2845 |
insert_with_markers( $upload_base . '.htaccess', 'ShortPixelWebp', $rules);
|
2846 |
insert_with_markers( trailingslashit(WP_CONTENT_DIR) . '.htaccess', 'ShortPixelWebp', $rules);
|
2847 |
/* insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', '
|
@@ -2857,13 +3044,16 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2857 |
}
|
2858 |
}
|
2859 |
|
|
|
|
|
|
|
2860 |
public function renderSettingsMenu() {
|
2861 |
if ( !current_user_can( 'manage_options' ) ) {
|
2862 |
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
2863 |
}
|
2864 |
|
2865 |
-
|
2866 |
-
|
2867 |
|
2868 |
//die(var_dump($_POST));
|
2869 |
$noticeHTML = "";
|
@@ -2871,13 +3061,13 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2871 |
$folderMsg = false;
|
2872 |
$addedFolder = false;
|
2873 |
|
2874 |
-
|
2875 |
|
2876 |
// Check if NGINX Server
|
2877 |
-
|
2878 |
|
2879 |
// BEGIN: Verify .htaccess writeability
|
2880 |
-
|
2881 |
if( !$isNginx ) {
|
2882 |
$htaccessPath = get_home_path() . '.htaccess';
|
2883 |
$htaccessExisted = file_exists( $htaccessPath );
|
@@ -2886,25 +3076,26 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2886 |
if( !$htaccessExisted ){
|
2887 |
unlink( $htaccessPath );
|
2888 |
}
|
2889 |
-
}
|
2890 |
// END: Verify .htaccess writeability
|
2891 |
|
2892 |
|
2893 |
//by default we try to fetch the API Key from wp-config.php (if defined)
|
2894 |
-
if ( defined("SHORTPIXEL_API_KEY") && strlen(SHORTPIXEL_API_KEY) == 20)
|
2895 |
{
|
2896 |
if(!isset($_POST['save']) && (strlen($this->getApiKey()) == 0 || SHORTPIXEL_API_KEY != $this->getApiKey())) {
|
2897 |
$_POST['validate'] = "validate";
|
2898 |
}
|
2899 |
$_POST['key'] = SHORTPIXEL_API_KEY;
|
2900 |
-
}
|
2901 |
|
2902 |
if(isset($_GET['setsparchive'])) {
|
2903 |
$this->_settings->downloadArchive = intval($_GET['setsparchive']);
|
2904 |
}
|
2905 |
|
2906 |
//check all custom folders and update meta table if files appeared
|
2907 |
-
|
|
|
2908 |
|
2909 |
if(isset($_POST['request']) && $_POST['request'] == 'request') {
|
2910 |
//a new API Key was requested
|
@@ -2922,21 +3113,21 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2922 |
}
|
2923 |
}
|
2924 |
|
2925 |
-
|
2926 |
$cfApi = $this->_settings->cloudflareEmail = sanitize_text_field( $_POST['cloudflare-email'] );
|
2927 |
$cfAuth = $this->_settings->cloudflareAuthKey = sanitize_text_field( $_POST['cloudflare-auth-key'] );
|
2928 |
-
$cfZone = $this->_settings->cloudflareZoneID = sanitize_text_field( $_POST['cloudflare-zone-id'] );
|
2929 |
$this->cloudflareApi->set_up($cfApi, $cfAuth, $cfZone);
|
2930 |
-
}
|
2931 |
|
2932 |
if( isset($_POST['save']) || isset($_POST['saveAdv'])
|
2933 |
|| (isset($_POST['validate']) && $_POST['validate'] == "validate")
|
2934 |
|| isset($_POST['removeFolder']) || isset($_POST['recheckFolder'])) {
|
2935 |
|
2936 |
//handle API Key - common for save and validate.
|
2937 |
-
|
2938 |
|
2939 |
-
|
2940 |
$KeyLength = strlen($_POST['key']);
|
2941 |
|
2942 |
$notice = array("status" => "error",
|
@@ -2958,8 +3149,8 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2958 |
}
|
2959 |
|
2960 |
$validityData = $this->getQuotaInformation($_POST['key'], true, isset($_POST['validate']) && $_POST['validate'] == "validate", $_POST);
|
2961 |
-
|
2962 |
-
|
2963 |
if($validityData['APIKeyValid']) {
|
2964 |
if(isset($_POST['validate']) && $_POST['validate'] == "validate") {
|
2965 |
// delete last status if it was no valid key
|
@@ -2981,7 +3172,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2981 |
}
|
2982 |
$this->_settings->verifiedKey = true;
|
2983 |
//test that the "uploads" have the right rights and also we can create the backup dir for ShortPixel
|
2984 |
-
if ( !file_exists(SHORTPIXEL_BACKUP_FOLDER) &&
|
2985 |
$notice = array("status" => "error",
|
2986 |
"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'),
|
2987 |
WP_CONTENT_DIR . '/' . SHORTPIXEL_UPLOADS_NAME ));
|
@@ -2991,12 +3182,12 @@ Header append Vary Accept env=REDIRECT_webp
|
|
2991 |
$notice = array("status" => "error", "msg" => $validityData["Message"]);
|
2992 |
}
|
2993 |
$this->_settings->verifiedKey = false;
|
2994 |
-
}
|
2995 |
-
|
2996 |
|
2997 |
//if save button - we process the rest of the form elements
|
2998 |
if(isset($_POST['save']) || isset($_POST['saveAdv'])) {
|
2999 |
-
|
3000 |
if(isset($_POST['thumbnails'])) { $this->_settings->processThumbnails = 1; } else { $this->_settings->processThumbnails = 0; }
|
3001 |
if(isset($_POST['backupImages'])) { $this->_settings->backupImages = 1; } else { $this->_settings->backupImages = 0; }
|
3002 |
if(isset($_POST['cmyk2rgb'])) { $this->_settings->CMYKtoRGBconversion = 1; } else { $this->_settings->CMYKtoRGBconversion = 0; }
|
@@ -3006,9 +3197,9 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3006 |
$this->_settings->resizeType = (isset($_POST['resize_type']) ? sanitize_text_field($_POST['resize_type']) : false);
|
3007 |
$this->_settings->resizeWidth = (isset($_POST['width']) ? intval($_POST['width']): $this->_settings->resizeWidth);
|
3008 |
$this->_settings->resizeHeight = (isset($_POST['height']) ? intval($_POST['height']): $this->_settings->resizeHeight);
|
3009 |
-
$uploadPath = realpath(SHORTPIXEL_UPLOADS_BASE);
|
3010 |
|
3011 |
-
if(isset($_POST['nextGen'])) {
|
3012 |
WpShortPixelDb::checkCustomTables(); // check if custom tables are created, if not, create them
|
3013 |
$prevNextGen = $this->_settings->includeNextGen;
|
3014 |
$this->_settings->includeNextGen = 1;
|
@@ -3017,21 +3208,19 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3017 |
$customFolders = $ret["customFolders"];
|
3018 |
} else {
|
3019 |
$this->_settings->includeNextGen = 0;
|
3020 |
-
}
|
3021 |
-
|
3022 |
$folderMsg = $this->spMetaDao->newFolderFromPath(stripslashes($_POST['addCustomFolder']), $uploadPath, self::getCustomFolderBase());
|
3023 |
if(!$folderMsg) {
|
3024 |
$notice = array("status" => "success", "msg" => __('Folder added successfully.','shortpixel-image-optimiser'));
|
3025 |
}
|
3026 |
$customFolders = $this->spMetaDao->getFolders();
|
3027 |
$this->_settings->hasCustomFolders = time();
|
3028 |
-
}
|
3029 |
-
|
3030 |
-
$this->_settings->createWebp = (isset($_POST['createWebp']) ? 1: 0);
|
3031 |
|
|
|
3032 |
|
3033 |
-
|
3034 |
-
if( isset( $_POST['createWebp'] ) && $_POST['createWebp'] == 'on' ){
|
3035 |
if( isset( $_POST['deliverWebp'] ) && $_POST['deliverWebp'] == 'on' ){
|
3036 |
if( isset( $_POST['deliverWebpType'] ) ) {
|
3037 |
switch( $_POST['deliverWebpType'] ) {
|
@@ -3061,20 +3250,15 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3061 |
} else {
|
3062 |
if(!$isNginx) self::alterHtaccess(true);
|
3063 |
$this->_settings->deliverWebp = 0;
|
3064 |
-
}
|
3065 |
-
|
3066 |
-
//die(ShortPixelVDD($_POST));
|
3067 |
|
3068 |
-
|
3069 |
-
|
3070 |
-
$this->_settings->optimizeRetina = (isset($_POST['optimizeRetina']) ? 1: 0);
|
3071 |
$this->_settings->optimizeUnlisted = (isset($_POST['optimizeUnlisted']) ? 1: 0);
|
3072 |
$this->_settings->optimizePdfs = (isset($_POST['optimizePdfs']) ? 1: 0);
|
3073 |
-
|
3074 |
-
|
3075 |
-
//die(var_dump($_POST['excludePatterns']));
|
3076 |
|
3077 |
-
|
3078 |
$patterns = array();
|
3079 |
$items = explode(',', $_POST['excludePatterns']);
|
3080 |
foreach($items as $pat) {
|
@@ -3089,9 +3273,10 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3089 |
} else {
|
3090 |
$this->_settings->excludePatterns = array();
|
3091 |
}
|
3092 |
-
|
3093 |
-
|
3094 |
-
|
|
|
3095 |
|
3096 |
//Redirect to bulk processing if requested
|
3097 |
if( isset($_POST['save']) && $_POST['save'] == __("Save and Go to Bulk Process",'shortpixel-image-optimiser')
|
@@ -3100,29 +3285,29 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3100 |
exit();
|
3101 |
}
|
3102 |
}
|
3103 |
-
if(isset($_POST['removeFolder']) && strlen(($_POST['removeFolder']))) {
|
3104 |
$this->spMetaDao->removeFolder($_POST['removeFolder']);
|
3105 |
$customFolders = $this->spMetaDao->getFolders();
|
3106 |
$_POST["saveAdv"] = true;
|
3107 |
-
}
|
3108 |
if(isset($_POST['recheckFolder']) && strlen(($_POST['recheckFolder']))) {
|
3109 |
//$folder->fullRefreshCustomFolder($_POST['recheckFolder']); //aici singura solutie pare callback care spune daca exita url-ul complet
|
3110 |
}
|
3111 |
}
|
3112 |
|
3113 |
//now output headers. They were prevented with noheaders=true in the form url in order to be able to redirect if bulk was pressed
|
3114 |
-
|
3115 |
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
3116 |
-
}
|
3117 |
|
3118 |
//empty backup
|
3119 |
-
if(isset($_POST['emptyBackup'])) {
|
3120 |
$this->emptyBackup();
|
3121 |
-
}
|
3122 |
|
3123 |
-
|
3124 |
|
3125 |
-
if($this->hasNextGen) {
|
3126 |
$ngg = array_map(array('ShortPixelNextGenAdapter','pathToAbsolute'), ShortPixelNextGenAdapter::getGalleries());
|
3127 |
//die(var_dump($ngg));
|
3128 |
for($i = 0; $i < count($customFolders); $i++) {
|
@@ -3130,14 +3315,14 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3130 |
$customFolders[$i]->setType("NextGen");
|
3131 |
}
|
3132 |
}
|
3133 |
-
}
|
3134 |
|
3135 |
-
$showApiKey = ( (is_main_site() || (function_exists("is_multisite") && is_multisite() && !defined("SHORTPIXEL_API_KEY")))
|
3136 |
&& !defined("SHORTPIXEL_HIDE_API_KEY"));
|
3137 |
-
$editApiKey = !defined("SHORTPIXEL_API_KEY") && $showApiKey;
|
3138 |
|
3139 |
if($this->_settings->verifiedKey) {
|
3140 |
-
$fileCount = number_format($this->_settings->fileCount);
|
3141 |
$savedSpace = self::formatBytes($this->_settings->savedSpace,2);
|
3142 |
$averageCompression = $this->getAverageCompression();
|
3143 |
$savedBandwidth = self::formatBytes($this->_settings->savedSpace * 10000,2);
|
@@ -3147,11 +3332,11 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3147 |
$remainingImages = $quotaData['APICallsRemaining'];
|
3148 |
$remainingImages = ( $remainingImages < 0 ) ? 0 : number_format($remainingImages);
|
3149 |
$totalCallsMade = array( 'plan' => $quotaData['APICallsMadeNumeric'] , 'oneTime' => $quotaData['APICallsMadeOneTimeNumeric'] );
|
3150 |
-
|
3151 |
-
|
3152 |
if(is_wp_error( $resources )) {
|
3153 |
$resources = array();
|
3154 |
-
}
|
3155 |
|
3156 |
$cloudflareAPI = true;
|
3157 |
|
@@ -3165,6 +3350,11 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3165 |
|
3166 |
}
|
3167 |
|
|
|
|
|
|
|
|
|
|
|
3168 |
public function addNextGenGalleriesToCustom($silent) {
|
3169 |
$customFolders = array();
|
3170 |
$folderMsg = "";
|
@@ -3184,6 +3374,10 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3184 |
return array("message" => $silent? "" : $folderMsg, "customFolders" => $customFolders);
|
3185 |
}
|
3186 |
|
|
|
|
|
|
|
|
|
3187 |
public function getAverageCompression(){
|
3188 |
return $this->_settings->totalOptimized > 0
|
3189 |
? round(( 1 - ( $this->_settings->totalOptimized / $this->_settings->totalOriginal ) ) * 100, 2)
|
@@ -3227,8 +3421,8 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3227 |
$args['body']['host'] = parse_url(get_site_url(),PHP_URL_HOST);
|
3228 |
$argsStr .= "&host={$args['body']['host']}";
|
3229 |
if(strlen($this->_settings->siteAuthUser)) {
|
3230 |
-
$args['body']['user'] = $this->_settings->siteAuthUser;
|
3231 |
-
$args['body']['pass'] = $this->_settings->siteAuthPass;
|
3232 |
$argsStr .= '&user=' . urlencode($args['body']['user']) . '&pass=' . urlencode($args['body']['pass']);
|
3233 |
}
|
3234 |
if($settings !== false) {
|
@@ -3275,7 +3469,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3275 |
$response = wp_remote_get($requestURL, $args);
|
3276 |
$comm['C: ' . (number_format(microtime(true) - $time, 2))] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
3277 |
}
|
3278 |
-
|
3279 |
|
3280 |
$defaultData = array(
|
3281 |
"APIKeyValid" => false,
|
@@ -3361,6 +3555,9 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3361 |
$this->_settings->quotaExceeded = 0;
|
3362 |
}
|
3363 |
|
|
|
|
|
|
|
3364 |
public function generateCustomColumn( $column_name, $id, $extended = false ) {
|
3365 |
if( 'wp-shortPixel' == $column_name ) {
|
3366 |
|
@@ -3374,9 +3571,10 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3374 |
$data = ShortPixelMetaFacade::sanitizeMeta(wp_get_attachment_metadata($id));
|
3375 |
|
3376 |
if($extended && isset($_GET['SHORTPIXEL_DEBUG'])) {
|
|
|
3377 |
var_dump(wp_get_attachment_url($id));
|
3378 |
echo('<br><br>' . json_encode(ShortPixelMetaFacade::getWPMLDuplicates($id)));
|
3379 |
-
echo('<br><br>'
|
3380 |
echo('<br><br>');
|
3381 |
}
|
3382 |
|
@@ -3503,11 +3701,22 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3503 |
}
|
3504 |
}
|
3505 |
|
|
|
|
|
|
|
|
|
|
|
3506 |
function columnRegisterSortable($columns) {
|
3507 |
$columns['wp-shortPixel'] = 'ShortPixel Compression';
|
3508 |
return $columns;
|
3509 |
}
|
3510 |
|
|
|
|
|
|
|
|
|
|
|
|
|
3511 |
function columnOrderFilterBy($vars) {
|
3512 |
if ( isset( $vars['orderby'] ) && 'ShortPixel Compression' == $vars['orderby'] ) {
|
3513 |
$vars = array_merge( $vars, array(
|
@@ -3534,6 +3743,10 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3534 |
return $vars;
|
3535 |
}
|
3536 |
|
|
|
|
|
|
|
|
|
3537 |
function mediaAddFilterDropdown() {
|
3538 |
$scr = get_current_screen();
|
3539 |
if ( $scr->base !== 'upload' ) return;
|
@@ -3556,11 +3769,19 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3556 |
. "</select>");
|
3557 |
}
|
3558 |
|
|
|
|
|
|
|
|
|
3559 |
function optimizationPercentIfPng2Jpg($meta) {
|
3560 |
$png2jpgPercent = isset($meta['ShortPixelPng2Jpg']['optimizationPercent']) ? $meta['ShortPixelPng2Jpg']['optimizationPercent'] : 0;
|
3561 |
return number_format(100.0 - (100.0 - $png2jpgPercent) * (100.0 - $meta['ShortPixelImprovement']) / 100.0, 2);
|
3562 |
}
|
3563 |
|
|
|
|
|
|
|
|
|
3564 |
function shortpixelInfoBox() {
|
3565 |
if(get_post_type( ) == 'attachment') {
|
3566 |
add_meta_box(
|
@@ -3574,10 +3795,18 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3574 |
}
|
3575 |
}
|
3576 |
|
|
|
|
|
|
|
3577 |
function shortpixelInfoBoxContent( $post ) {
|
3578 |
$this->generateCustomColumn( 'wp-shortPixel', $post->ID, true );
|
3579 |
}
|
3580 |
|
|
|
|
|
|
|
|
|
|
|
3581 |
public function onDeleteImage($post_id) {
|
3582 |
$itemHandler = new ShortPixelMetaFacade($post_id);
|
3583 |
$urlsPaths = $itemHandler->getURLsAndPATHs(true, false, true, array(), true);
|
@@ -3588,7 +3817,17 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3588 |
return $itemHandler; //return it because we call it also on replace and on replace we need to follow this by deleting SP metadata, on delete it
|
3589 |
}
|
3590 |
|
|
|
|
|
3591 |
public function deleteBackupsAndWebPs($paths) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3592 |
$backupFolder = trailingslashit($this->getBackupFolder($paths[0]));
|
3593 |
foreach($paths as $path) {
|
3594 |
$pos = strrpos($path, ".");
|
@@ -3605,18 +3844,23 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3605 |
@unlink($backupFolder . preg_replace("/\." . $extension . "$/i", '@2x.' . $extension, $fileName));
|
3606 |
}
|
3607 |
}
|
3608 |
-
|
|
|
|
|
|
|
|
|
3609 |
public function columns( $defaults ) {
|
3610 |
$defaults['wp-shortPixel'] = __('ShortPixel Compression', 'shortpixel-image-optimiser');
|
3611 |
if(current_user_can( 'manage_options' )) {
|
3612 |
$defaults['wp-shortPixel'] .=
|
3613 |
-
' <a href="options-general.php?page=wp-shortpixel
|
3614 |
. __('ShortPixel Statistics','shortpixel-image-optimiser')
|
3615 |
. '"><span class="dashicons dashicons-dashboard"></span></a>';
|
3616 |
}
|
3617 |
return $defaults;
|
3618 |
}
|
3619 |
|
|
|
3620 |
public function nggColumns( $defaults ) {
|
3621 |
$this->nggColumnIndex = count($defaults) + 1;
|
3622 |
add_filter( 'ngg_manage_images_column_' . $this->nggColumnIndex . '_header', array( &$this, 'nggColumnHeader' ) );
|
@@ -3669,11 +3913,12 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3669 |
}
|
3670 |
|
3671 |
public function generatePluginLinks($links) {
|
3672 |
-
$in = '<a href="options-general.php?page=wp-shortpixel">Settings</a>';
|
3673 |
array_unshift($links, $in);
|
3674 |
return $links;
|
3675 |
}
|
3676 |
|
|
|
3677 |
static public function formatBytes($bytes, $precision = 2) {
|
3678 |
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
3679 |
|
@@ -3686,11 +3931,21 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3686 |
return round($bytes, $precision) . ' ' . $units[$pow];
|
3687 |
}
|
3688 |
|
|
|
|
|
|
|
|
|
|
|
3689 |
public function isProcessable($ID, $excludeExtensions = array()) {
|
3690 |
$excludePatterns = $this->_settings->excludePatterns;
|
3691 |
return self::_isProcessable($ID, $excludeExtensions, $excludePatterns);
|
3692 |
}
|
3693 |
|
|
|
|
|
|
|
|
|
|
|
3694 |
public function isProcessablePath($path, $excludeExtensions = array()) {
|
3695 |
$excludePatterns = $this->_settings->excludePatterns;
|
3696 |
return self::_isProcessablePath($path, $excludeExtensions, $excludePatterns);
|
@@ -3760,7 +4015,10 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3760 |
return $itemHandler->getURLsAndPATHs($this->_settings->processThumbnails, $onlyThumbs, $this->_settings->optimizeRetina, $this->_settings->excludeSizes);
|
3761 |
}
|
3762 |
|
3763 |
-
|
|
|
|
|
|
|
3764 |
public static function deleteDir($dirPath) {
|
3765 |
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
|
3766 |
$dirPath .= '/';
|
@@ -3776,6 +4034,10 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3776 |
}
|
3777 |
}
|
3778 |
|
|
|
|
|
|
|
|
|
3779 |
static public function folderSize($path) {
|
3780 |
$total_size = 0;
|
3781 |
if(file_exists($path)) {
|
@@ -3808,7 +4070,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3808 |
|
3809 |
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
3810 |
//we check that the backup folder exists, if not we create it so we can copy into it
|
3811 |
-
if(!
|
3812 |
}
|
3813 |
|
3814 |
$scannedDirectory = array_diff(scandir($oldBackupFolder), array('..', '.'));
|
@@ -3820,11 +4082,12 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3820 |
@rmdir($oldBackupFolder);
|
3821 |
}
|
3822 |
}
|
|
|
3823 |
//now if the backup folder does not contain the uploads level, create it
|
3824 |
if( !is_dir(SHORTPIXEL_BACKUP_FOLDER . '/' . SHORTPIXEL_UPLOADS_NAME )
|
3825 |
&& !is_dir(SHORTPIXEL_BACKUP_FOLDER . '/' . basename(WP_CONTENT_DIR))) {
|
3826 |
@rename(SHORTPIXEL_BACKUP_FOLDER, SHORTPIXEL_BACKUP_FOLDER."_tmp");
|
3827 |
-
|
3828 |
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER.'/'.SHORTPIXEL_UPLOADS_NAME);
|
3829 |
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {//just in case..
|
3830 |
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER);
|
@@ -3833,12 +4096,17 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3833 |
//then create the wp-content level if not present
|
3834 |
if(!is_dir(SHORTPIXEL_BACKUP_FOLDER . '/' . basename(WP_CONTENT_DIR))) {
|
3835 |
@rename(SHORTPIXEL_BACKUP_FOLDER, SHORTPIXEL_BACKUP_FOLDER."_tmp");
|
3836 |
-
|
3837 |
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER.'/' . basename(WP_CONTENT_DIR));
|
3838 |
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {//just in case..
|
3839 |
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER);
|
3840 |
}
|
3841 |
}
|
|
|
|
|
|
|
|
|
|
|
3842 |
return;
|
3843 |
}
|
3844 |
|
@@ -3860,6 +4128,8 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3860 |
return $sizes;
|
3861 |
}
|
3862 |
|
|
|
|
|
3863 |
function getMaxIntermediateImageSize() {
|
3864 |
global $_wp_additional_image_sizes;
|
3865 |
|
@@ -3886,7 +4156,76 @@ Header append Vary Accept env=REDIRECT_webp
|
|
3886 |
return array_values(array_diff(array(0, 1, 2), array(0 + $compressionType)));
|
3887 |
}
|
3888 |
|
3889 |
-
function outputHSBeacon() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3890 |
<script>
|
3891 |
<?php
|
3892 |
$screen = get_current_screen();
|
@@ -4001,6 +4340,7 @@ Header append Vary Accept env=REDIRECT_webp
|
|
4001 |
return $this->_settings->resizeHeight;
|
4002 |
}
|
4003 |
public static function getAffiliateSufix() {
|
|
|
4004 |
// not allowed anymore by WP as of Sept.27 2018
|
4005 |
// return isset($_COOKIE["AffiliateShortPixel"])
|
4006 |
// ? "/affiliate/" . $_COOKIE["AffiliateShortPixel"]
|
1 |
<?php
|
2 |
|
3 |
+
use ShortPixel\DebugItem as DebugItem;
|
4 |
+
use ShortPixel\ShortPixelLogger as Log;
|
5 |
+
use ShortPixel\NoticeController as Notice;
|
6 |
+
|
7 |
+
|
8 |
class WPShortPixel {
|
9 |
|
10 |
const BULK_EMPTY_QUEUE = 0;
|
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 |
|
54 |
if( !defined('SHORTPIXEL_CUSTOM_THUMB_SUFFIXES')) {
|
102 |
|
103 |
if($isAdminUser) {
|
104 |
//add settings page
|
105 |
+
//add_action( 'admin_menu', array( &$this, 'registerSettingsPage' ) );//display SP in Settings menu
|
106 |
add_action( 'admin_menu', array( &$this, 'registerAdminPage' ) );
|
107 |
|
108 |
add_action('wp_ajax_shortpixel_browse_content', array(&$this, 'browseContent'));
|
148 |
add_action('wp_ajax_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
149 |
add_action('admin_action_shortpixel_check_quota', array(&$this, 'handleCheckQuota'));
|
150 |
//This adds the constants used in PHP to be available also in JS
|
151 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'shortPixelJS') );
|
152 |
+
add_action( 'admin_footer', array($this, 'admin_footer_js') );
|
153 |
add_action( 'admin_head', array( $this, 'headCSS') );
|
154 |
|
155 |
if($this->_settings->frontBootstrap && shortPixelCheckQueue()) {
|
165 |
$this->migrateBackupFolder();
|
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 |
|
179 |
$this->__construct();
|
180 |
}
|
181 |
|
182 |
+
// @hook admin menu
|
183 |
+
// @todo move to plugin class
|
184 |
public function registerSettingsPage() {
|
185 |
+
|
186 |
}
|
187 |
|
188 |
+
// @hook admin menu
|
189 |
+
// @todo move to plugin class
|
190 |
function registerAdminPage( ) {
|
191 |
if($this->spMetaDao->hasFoldersTable() && count($this->spMetaDao->getFolders())) {
|
192 |
/*translators: title and menu name for the Other media page*/
|
345 |
return $found;
|
346 |
}
|
347 |
|
348 |
+
/** Displays notices to admin, if there are any
|
349 |
+
* TODO - Probably should be a controller
|
350 |
+
*/
|
351 |
public function displayAdminNotices() {
|
352 |
if(!ShortPixelQueue::testQ()) {
|
353 |
ShortPixelView::displayActivationNotice('fileperms');
|
459 |
}
|
460 |
|
461 |
static function log($message, $force = false) {
|
462 |
+
Log::addInfo($message);
|
463 |
+
/*
|
464 |
if (SHORTPIXEL_DEBUG === true || $force) {
|
465 |
if (is_array($message) || is_object($message)) {
|
466 |
self::doLog(print_r($message, true), $force);
|
467 |
} else {
|
468 |
self::doLog($message, $force);
|
469 |
}
|
470 |
+
} */
|
471 |
}
|
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 {
|
479 |
error_log($message);
|
480 |
+
}*/
|
481 |
}
|
482 |
|
483 |
function headCSS() {
|
484 |
echo('<style>.shortpixel-hide {display:none;}</style>');
|
485 |
}
|
486 |
|
487 |
+
/** @todo Plugin init class. Try to get rid of inline JS. Also still loads on all WP pages, prevent that. */
|
488 |
function shortPixelJS() {
|
489 |
+
|
490 |
//require_once(ABSPATH . 'wp-admin/includes/screen.php');
|
491 |
if(function_exists('get_current_screen')) {
|
492 |
$screen = get_current_screen();
|
493 |
|
494 |
if(is_object($screen)) {
|
495 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
496 |
|
497 |
wp_enqueue_style('short-pixel-bar.min.css', plugins_url('/res/css/short-pixel-bar.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
498 |
if( in_array($screen->id, array('attachment', 'upload', 'settings_page_wp-shortpixel', 'media_page_wp-short-pixel-bulk', 'media_page_wp-short-pixel-custom'))) {
|
500 |
//modal - used in settings for selecting folder
|
501 |
wp_enqueue_style('short-pixel-modal.min.css', plugins_url('/res/css/short-pixel-modal.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
502 |
|
503 |
+
// @todo Might need to be removed later on
|
504 |
wp_register_style('shortpixel-admin', plugins_url('/res/css/shortpixel-admin.css', SHORTPIXEL_PLUGIN_FILE),array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION );
|
505 |
wp_enqueue_style('shortpixel-admin');
|
506 |
}
|
507 |
}
|
508 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
509 |
|
510 |
+
|
511 |
+
wp_register_script('shortpixel' . $this->jsSuffix, plugins_url('/res/js/shortpixel' . $this->jsSuffix,SHORTPIXEL_PLUGIN_FILE), array('jquery'), SHORTPIXEL_IMAGE_OPTIMISER_VERSION, true);
|
512 |
+
|
513 |
|
514 |
// Using an Array within another Array to protect the primitive values from being cast to strings
|
515 |
$ShortPixelConstants = array(array(
|
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,
|
529 |
+
'DEFAULT_COMPRESSION'=>0 + intval($this->_settings->compressionType), // no int can happen when settings are empty still
|
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'=>self::getAffiliateSufix()
|
534 |
));
|
535 |
|
536 |
+
if (Log::isManualDebug() )
|
537 |
+
{
|
538 |
+
Log::addInfo('Ajax Manual Debug Mode');
|
539 |
+
$logLevel = Log::getLogLevel();
|
540 |
+
$ShortPixelConstants[0]['AJAX_URL'] = admin_url('admin-ajax.php?SHORTPIXEL_DEBUG=' . $logLevel);
|
541 |
+
}
|
542 |
+
|
543 |
$jsTranslation = array(
|
544 |
'optimizeWithSP' => __( 'Optimize with ShortPixel', 'shortpixel-image-optimiser' ),
|
545 |
'redoLossy' => __( 'Re-optimize Lossy', 'shortpixel-image-optimiser' ),
|
579 |
wp_enqueue_script('punycode.min.js', plugins_url('/res/js/punycode.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
580 |
}
|
581 |
|
582 |
+
/** Outputs direct JS to the admin footer
|
583 |
+
* @todo Find a better solution for this */
|
584 |
+
public function admin_footer_js()
|
585 |
+
{
|
586 |
+
if(function_exists('get_current_screen')) {
|
587 |
+
$screen = get_current_screen();
|
588 |
+
if(is_object($screen)) {
|
589 |
+
|
590 |
+
if( in_array($screen->id, array('attachment', 'upload', 'media_page_wp-short-pixel-custom'))) {
|
591 |
+
//output the comparer html
|
592 |
+
$this->view->outputComparerHTML();
|
593 |
+
//render a template of the list cell to be used by the JS
|
594 |
+
$this->view->renderListCell("__SP_ID__", 'imgOptimized', true, "__SP_THUMBS_TOTAL__", true, true,
|
595 |
+
array("__SP_FIRST_TYPE__", "__SP_SECOND_TYPE__"), "__SP_CELL_MESSAGE__", 'sp-column-actions-template');
|
596 |
+
}
|
597 |
+
}
|
598 |
+
}
|
599 |
+
?>
|
600 |
+
<script type="text/javascript" >
|
601 |
+
//check after 10 seconds if ShortPixel initialized OK, if not, force the init (could happen if a JS error somewhere else stopped the JS execution).
|
602 |
+
function delayedInit() {
|
603 |
+
if(typeof ShortPixel !== "undefined") {
|
604 |
+
ShortPixel.init();
|
605 |
+
} else {
|
606 |
+
setTimeout(delayedInit, 10000);
|
607 |
+
}
|
608 |
+
}
|
609 |
+
setTimeout(delayedInit, 10000);
|
610 |
+
</script>
|
611 |
+
<?php
|
612 |
+
}
|
613 |
+
|
614 |
+
/** Displays an icon in the toolbar when processing images
|
615 |
+
* hook - admin_bar_menu
|
616 |
+
* @param Obj $wp_admin_bar
|
617 |
+
*/
|
618 |
function toolbar_shortpixel_processing( $wp_admin_bar ) {
|
619 |
|
620 |
$extraClasses = " shortpixel-hide";
|
634 |
$tooltip = '';
|
635 |
$exceedTooltip = __('ShortPixel quota exceeded. Click for details.','shortpixel-image-optimiser');
|
636 |
//$link = "http://shortpixel.com/login/" . $this->_settings->apiKey;
|
637 |
+
$link = "options-general.php?page=wp-shortpixel-settings";
|
638 |
//$blank = '_blank';
|
639 |
//$icon = "shortpixel-alert.png";
|
640 |
}
|
689 |
// 2. Perform the action
|
690 |
case 'short-pixel-bulk':
|
691 |
foreach( $mediaIds as $ID ) {
|
692 |
+
|
693 |
$meta = wp_get_attachment_metadata($ID);
|
694 |
+
if(!is_array($meta)) {
|
695 |
+
self::log('CUSTOM BULK META NOT AN ARRAY: ' . json_encode($meta));
|
696 |
+
$meta = ShortPixelMetaFacade::sanitizeMeta($meta, false);
|
697 |
+
if(isset($meta['previous_meta'])) {
|
698 |
+
self::log('COULDN\'T SANITIZE PROPERLY.');
|
699 |
+
continue;
|
700 |
+
}
|
701 |
+
else {
|
702 |
+
self::log('SANITIZED.');
|
703 |
+
}
|
704 |
+
}
|
705 |
+
|
706 |
+
if(!is_array($meta)) continue;
|
707 |
if( ( !isset($meta['ShortPixel']) //never touched by ShortPixel
|
708 |
|| (isset($meta['ShortPixel']['WaitingProcessing']) && $meta['ShortPixel']['WaitingProcessing'] == true))
|
709 |
&& (!isset($meta['ShortPixelImprovement']) || $meta['ShortPixelImprovement'] == __('Optimization N/A','shortpixel-image-optimiser'))) {
|
844 |
$meta = $itemHandler->getMeta();
|
845 |
|
846 |
$doDump = false;
|
847 |
+
|
848 |
if ($meta->getStatus() <= 0)
|
849 |
{
|
850 |
$doDump = true; // dump any caching on files that ended in an error.
|
1085 |
}
|
1086 |
$idList = array();
|
1087 |
$itemList = array();
|
1088 |
+
$timeoutMinThreshold = SHORTPIXEL_MAX_EXECUTION_TIME < 10 ? 2 : (SHORTPIXEL_MAX_EXECUTION_TIME < 30 ? 3 : 5);
|
1089 |
+
$maxTime = min(SHORTPIXEL_MAX_EXECUTION_TIME, 90);
|
1090 |
+
$timeoutThreshold = 5; // will adapt this with the maximum time needed for one pass
|
1091 |
+
$passTime = time();
|
1092 |
for ($sanityCheck = 0, $crtStartQueryID = $startQueryID;
|
1093 |
($crtStartQueryID >= $endQueryID) && (count($itemList) < SHORTPIXEL_PRESEND_ITEMS) && ($sanityCheck < 150)
|
1094 |
+
&& (time() - $this->timer < $maxTime - $timeoutThreshold); $sanityCheck++) {
|
1095 |
|
1096 |
+
$timeoutThreshold = max($timeoutThreshold, $timeoutMinThreshold + time() - $passTime);
|
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 |
+
self::log("GETDB: pass $sanityCheck current StartID: $crtStartQueryID Threshold: $timeoutThreshold, MaxResults: $maxResults" );
|
1101 |
|
1102 |
/* $queryPostMeta = "SELECT * FROM " . $wpdb->prefix . "postmeta
|
1103 |
WHERE ( post_id <= $crtStartQueryID AND post_id >= $endQueryID )
|
1106 |
LIMIT " . SHORTPIXEL_MAX_RESULTS_QUERY;
|
1107 |
$resultsPostMeta = $wpdb->get_results($queryPostMeta);
|
1108 |
*/
|
1109 |
+
|
1110 |
+
$resultsPostMeta = WpShortPixelMediaLbraryAdapter::getPostMetaSlice($crtStartQueryID, $endQueryID, $maxResults);
|
1111 |
+
if(time() - $this->timer >= 60) self::log("GETDB is SLOW. Got meta slice.");
|
1112 |
|
1113 |
if ( empty($resultsPostMeta) ) {
|
1114 |
$crtStartQueryID -= SHORTPIXEL_MAX_RESULTS_QUERY;
|
1120 |
continue;
|
1121 |
}
|
1122 |
|
1123 |
+
if($timeoutThreshold > 10) self::log("GETDB is SLOW. Meta slice has " . count($resultsPostMeta) . ' items.');
|
1124 |
+
|
1125 |
foreach ( $resultsPostMeta as $itemMetaData ) {
|
1126 |
$crtStartQueryID = $itemMetaData->post_id;
|
1127 |
+
if(time() - $this->timer >= 60) self::log("GETDB is SO SLOW. Check processable for $crtStartQueryID.");
|
1128 |
+
if(time() - $this->timer >= $maxTime - $timeoutThreshold){
|
1129 |
+
break;
|
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) self::log("GETDB is SO SLOW. Get meta for $crtStartQueryID.");
|
1136 |
$meta = $item->getMeta();//wp_get_attachment_metadata($crtStartQueryID);
|
1137 |
+
if($timeoutThreshold > 15) self::log("GETDB is SO SLOW. Got meta.");
|
1138 |
|
1139 |
if($meta->getStatus() != 2) {
|
1140 |
$addIt = (strpos($meta->getMessage(), __('Image files are missing.', 'shortpixel-image-optimiser')) === false);
|
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())))) { //thumbs were chosen in settings
|
1170 |
$URLsAndPATHs = $item->getURLsAndPATHs(true, true, $this->_settings->optimizeRetina, $this->_settings->excludeSizes);
|
1171 |
if(count($URLsAndPATHs["URLs"])) {
|
1172 |
$meta->setThumbsTodo(true);
|
1191 |
$this->prioQ->setStartBulkId($startQueryID);
|
1192 |
} else {
|
1193 |
$crtStartQueryID--;
|
1194 |
+
self::log("GETDB just decrementing. Crt: $crtStartQueryID Start: $startQueryID, list: " . json_encode($idList));
|
1195 |
}
|
1196 |
}
|
1197 |
+
$ret = array("items" => $itemList, "skipped" => $skippedAlreadyProcessed, "searching" => ($sanityCheck >= 150) || (time() - $this->timer >= $maxTime - $timeoutThreshold));
|
1198 |
+
self::log('GETDB returns ' . json_encode($ret));
|
1199 |
+
return $ret;
|
1200 |
}
|
1201 |
|
1202 |
/**
|
1213 |
return $items;
|
1214 |
}
|
1215 |
|
1216 |
+
/** Checks the API key **/
|
1217 |
private function checkKey($ID) {
|
1218 |
if( $this->_settings->verifiedKey == false) {
|
1219 |
if($ID == null){
|
1259 |
|
1260 |
$rawPrioQ = $this->prioQ->get();
|
1261 |
if(count($rawPrioQ)) { self::log("HIP: 0 Priority Queue: ".json_encode($rawPrioQ)); }
|
1262 |
+
self::log("HIP: 0 Bulk running? " . $this->prioQ->bulkRunning() . " START " . $this->_settings->startBulkId . " STOP " . $this->_settings->stopBulkId . " MaxTime: " . SHORTPIXEL_MAX_EXECUTION_TIME);
|
1263 |
|
1264 |
//handle the bulk restore and cleanup first - these are fast operations taking precedece over optimization
|
1265 |
if( $this->prioQ->bulkRunning()
|
1548 |
if($result["Status"] !== ShortPixelAPI::STATUS_RETRY) {
|
1549 |
$this->_settings->bulkLastStatus = $result;
|
1550 |
}
|
1551 |
+
$ret = json_encode($result);
|
1552 |
+
self::log("HIP RET " . $ret);
|
1553 |
+
die($ret);
|
1554 |
}
|
1555 |
|
1556 |
|
1659 |
return $URLsAndPATHs;
|
1660 |
}
|
1661 |
|
1662 |
+
/** Manual optimization request. This is only called from the Media Library, never from the Custom media */
|
1663 |
public function handleManualOptimization() {
|
1664 |
+
$imageId = intval($_GET['image_id']);
|
1665 |
$cleanup = $_GET['cleanup'];
|
1666 |
|
1667 |
+
Log::addInfo("Handle Manual Optimization #{$imageId}");
|
1668 |
|
1669 |
switch(substr($imageId, 0, 2)) {
|
1670 |
case "N-":
|
1681 |
return array("Status" => ShortPixelAPI::STATUS_FAIL, "message" => __('NextGen image not found','shortpixel-image-optimiser'));
|
1682 |
break;
|
1683 |
case "C-":
|
1684 |
+
Log::addError("Throw: HandleManualOptimization for custom images not implemented");
|
1685 |
throw new Exception("HandleManualOptimization for custom images not implemented");
|
1686 |
default:
|
1687 |
$this->optimizeNowHook(intval($imageId), true);
|
1691 |
|
1692 |
}
|
1693 |
|
1694 |
+
/** Returns status of an image *
|
1695 |
+
* Uses a request parameter for image_id, ends in json encode.
|
1696 |
+
* @hook - wp_ajax_shortpixel_check_status
|
1697 |
+
*/
|
1698 |
public function checkStatus() {
|
1699 |
+
$itemHandler = new ShortPixelMetaFacade(intval($_GET['image_id']));
|
1700 |
$meta = $itemHandler->getMeta();
|
1701 |
die(json_encode(array("Status" => $meta->getStatus(), "Message" => $meta->getMessage())));
|
1702 |
}
|
1703 |
|
1704 |
+
/** Hook action for optimization (Ajax-call)
|
1705 |
+
* @hook shortpixel-optimize-now ( seems not in use )
|
1706 |
+
* Call by handleManualOptimization
|
1707 |
+
*/
|
1708 |
public function optimizeNowHook($imageId, $manual = false) {
|
1709 |
//WpShortPixel::log("OPTIMIZE NOW HOOK for ID: $imageId STACK: " . json_encode(debug_backtrace()));
|
1710 |
if($this->isProcessable($imageId)) {
|
1747 |
* @param bool $bulk - true if the regeneration is done in bulk - in this case the image will not be immediately scheduled for processing but the user will need to launch the ShortPixel bulk after regenerating.
|
1748 |
*
|
1749 |
*
|
1750 |
+
* Note - $regeneratedSizes expects part of the metadata array called [sizes], with filename, not just the resized data.
|
1751 |
*/
|
1752 |
public function thumbnailsRegeneratedHook($postId, $originalMeta, $regeneratedSizes = array(), $bulk = false) {
|
1753 |
|
1786 |
unset($this->thumbnailsRegenerating[$postId]);
|
1787 |
}
|
1788 |
|
1789 |
+
/** Check if a certain files exists in the backup
|
1790 |
+
* ( by calling a random number of dir functions )
|
1791 |
+
* TODO - Should be of the folder model.
|
1792 |
+
*/
|
1793 |
public function shortpixelGetBackupFilter($imagePath) {
|
1794 |
$backup = str_replace(dirname(dirname(dirname(SHORTPIXEL_BACKUP_FOLDER))),SHORTPIXEL_BACKUP_FOLDER, $imagePath);
|
1795 |
return file_exists($backup) ? $backup : false;
|
1810 |
}
|
1811 |
|
1812 |
|
1813 |
+
/** on Image error, Save error in file's meta data
|
1814 |
+
* @param int $ID image_id
|
1815 |
+
* @param string $result - Error String
|
1816 |
+
*/
|
1817 |
public function handleError($ID, $result)
|
1818 |
{
|
1819 |
$meta = wp_get_attachment_metadata($ID);
|
1822 |
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
1823 |
}
|
1824 |
|
1825 |
+
/* Gets backup folder of file
|
1826 |
+
* @param string $file Filepath - probably
|
1827 |
+
* @return string backupFolder
|
1828 |
+
*/
|
1829 |
public function getBackupFolder($file) {
|
1830 |
if(realpath($file)) {
|
1831 |
$ret = $this->getBackupFolderInternal(realpath($file)); //found cases when $file contains for example /wp/../wp-content - clean it up
|
1835 |
return $this->getBackupFolderInternal($file);
|
1836 |
}
|
1837 |
|
1838 |
+
/** Gets backup from file
|
1839 |
+
* @param string $file Filename
|
1840 |
+
* @return string FolderName
|
1841 |
+
*/
|
1842 |
private function getBackupFolderInternal($file) {
|
1843 |
$fileExtension = strtolower(substr($file,strrpos($file,".")+1));
|
1844 |
$SubDir = ShortPixelMetaFacade::returnSubDir($file);
|
1862 |
return SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir;
|
1863 |
}
|
1864 |
|
1865 |
+
/** Gets BackupFolder. If that doesn't work, search thumbs for a backupFolder
|
1866 |
+
* @param string $file FileName
|
1867 |
+
* @param array $thumbs Array of thumbnails
|
1868 |
+
* @return string|boolean Returns either backupfolder or false.
|
1869 |
+
*/
|
1870 |
public function getBackupFolderAny($file, $thumbs) {
|
1871 |
$ret = $this->getBackupFolder($file);
|
1872 |
//if(!$ret && !file_exists($file) && isset($thumbs)) {
|
1874 |
//try with the thumbnails
|
1875 |
foreach($thumbs as $size) {
|
1876 |
$backup = $this->getBackupFolder(trailingslashit(dirname($file)) . $size['file']);
|
1877 |
+
if($backup) {
|
1878 |
+
$ret = $backup;
|
1879 |
+
break;
|
1880 |
+
}
|
1881 |
}
|
1882 |
}
|
1883 |
+
return apply_filters("shortpixel_backup_folder", $ret, $file, $thumbs);
|
1884 |
}
|
1885 |
|
1886 |
+
/** Sets file permissions
|
1887 |
+
* @param string $file FileName
|
1888 |
+
* @return boolean Success
|
1889 |
+
* TODO - Move to File Model
|
1890 |
+
*/
|
1891 |
protected function setFilePerms($file) {
|
1892 |
//die(getenv('USERNAME') ? getenv('USERNAME') : getenv('USER'));
|
1893 |
|
2086 |
set_transient("shortpixel_thrown_notice", array('when' => $when, 'extra' => $extra), 120);
|
2087 |
}
|
2088 |
|
2089 |
+
/** Checks if a notice was thrown
|
2090 |
+
* @return boolean true, if there are notices */
|
2091 |
protected function catchNotice() {
|
2092 |
$notice = get_transient("shortpixel_thrown_notice");
|
2093 |
if(isset($notice['when'])) {
|
2113 |
return substr($file, 0, strlen($file) - 1 - strlen($ext)) . "@2x." . $ext;
|
2114 |
}
|
2115 |
|
2116 |
+
/** Restores a non-media-library image
|
2117 |
+
* @param int $ID image_id, without any prefixes
|
2118 |
+
*/
|
2119 |
public function doCustomRestore($ID) {
|
2120 |
//$meta = $this->spMetaDao->getMeta($ID);
|
2121 |
// meta facade as a custom image
|
2141 |
$rename_result = @rename($bkFile, $file);
|
2142 |
if (! $rename_result)
|
2143 |
{
|
2144 |
+
Log::addError('Failure on rename to : ' . $file);
|
2145 |
}
|
2146 |
|
2147 |
|
2166 |
|
2167 |
}
|
2168 |
else {
|
2169 |
+
Log::addWarn('File ' . $bkFile . ' not found in backups');
|
2170 |
}
|
2171 |
|
2172 |
return $meta;
|
2234 |
return $ret;
|
2235 |
}
|
2236 |
|
2237 |
+
// TODO - [BS] json_encode should be replaced by a call to shortPixelTools:sendJson, but this crashes the JS parse - for some reason -
|
2238 |
public function handleOptimizeThumbs() {
|
2239 |
$ID = intval($_GET['attachment_ID']);
|
2240 |
$meta = wp_get_attachment_metadata($ID);
|
|
|
2241 |
|
2242 |
+
// default return;
|
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 = WpShortPixelMediaLbraryAdapter::getSizesNotExcluded($meta['sizes'], $this->_settings->excludeSizes);
|
2247 |
$thumbsCount = count($includedSizes);
|
2248 |
|
2251 |
$error['message'] = __('Please optimize image for ID: ','shortpixel-image-optimiser') . $ID;
|
2252 |
die(json_encode($error));
|
2253 |
}
|
2254 |
+
|
2255 |
if (! isset($meta['sizes']) || count($meta['sizes']) == 0)
|
2256 |
{
|
2257 |
$error['message'] = __('No thumbnails to optimize for ID: ','shortpixel-image-optimiser') . $ID;
|
2258 |
die(json_encode($error));
|
2259 |
}
|
2260 |
+
|
2261 |
+
|
2262 |
/* Check ThumbList against current Sizes. It's possible when a size was dropped, the SP meta was not updated, playing
|
2263 |
* tricks with the thumbcount.
|
2264 |
*
|
2276 |
$meta['ShortPixel']['thumbsOptList'] = $thumbList;
|
2277 |
}
|
2278 |
|
2279 |
+
/*
|
2280 |
+
if (isset($meta['Shortpixel']['thumbsOptList']))
|
2281 |
+
{
|
2282 |
+
$sizeFiles = array();
|
2283 |
+
foreach($sizeFiles as $size => $data)
|
2284 |
+
{
|
2285 |
+
$file = pathinfo($data['file'], )
|
2286 |
+
}
|
2287 |
|
2288 |
+
} */
|
2289 |
+
|
2290 |
+
/* if( $thumbsCount
|
2291 |
+
&& ( !isset($meta['ShortPixel']['thumbsOpt']) || $meta['ShortPixel']['thumbsOpt'] == 0
|
2292 |
+
|| (isset($meta['sizes']) && isset($meta['ShortPixel']['thumbsOptList']) && $meta['ShortPixel']['thumbsOpt'] < $thumbsCount))) { //optimized without thumbs, thumbs exist */
|
2293 |
|
2294 |
if( $thumbsCount
|
2295 |
&& (isset($meta['sizes']) && isset($meta['ShortPixel']['thumbsOptList']) && count($meta['ShortPixel']['thumbsOptList']) < $thumbsCount))
|
2296 |
{
|
2297 |
$meta['ShortPixel']['thumbsTodo'] = true;
|
2298 |
+
|
2299 |
//wp_update_attachment_metadata($ID, $meta);
|
2300 |
update_post_meta($ID, '_wp_attachment_metadata', $meta);
|
2301 |
$this->prioQ->push($ID);
|
2315 |
} else {
|
2316 |
$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);
|
2317 |
}
|
2318 |
+
//shortPixelTools::sendJSON($ret);
|
2319 |
die(json_encode($ret));
|
2320 |
}
|
2321 |
|
2363 |
}
|
2364 |
}
|
2365 |
|
2366 |
+
/** Runs on plugin deactivation
|
2367 |
+
* @hook admin_post_shortpixel_deactivate_plugin
|
2368 |
+
*/
|
2369 |
public function deactivatePlugin() {
|
2370 |
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'sp_deactivate_plugin_nonce' ) ) {
|
2371 |
wp_nonce_ays( '' );
|
2384 |
|
2385 |
}
|
2386 |
|
2387 |
+
/** Deactivates plugin and redirects
|
2388 |
+
* @param string @url URL to redirect after deactivate
|
2389 |
+
*/
|
2390 |
protected function deactivateAndRedirect($url){
|
2391 |
//die(ShortPixelVDD($url));
|
2392 |
+
deactivate_plugins( sanitize_text_field($_GET['plugin']) );
|
2393 |
wp_safe_redirect( $url );
|
2394 |
die();
|
2395 |
|
2433 |
$quotaData = $this->getQuotaInformation();
|
2434 |
}
|
2435 |
if ( !$quotaData['APIKeyValid']) {
|
2436 |
+
if(strlen($this->_settings->apiKey))
|
2437 |
+
Notice::addError(sprintf(__('Shortpixel Remote API Error: %s','shortpixel-image-optimizer'), $quotaData['Message'] ));
|
2438 |
return $quotaData;
|
2439 |
}
|
2440 |
//$tempus = microtime(true);
|
2444 |
if($quotaData['APICallsQuotaNumeric'] + $quotaData['APICallsQuotaOneTimeNumeric'] > $quotaData['APICallsMadeNumeric'] + $quotaData['APICallsMadeOneTimeNumeric']) {
|
2445 |
$this->_settings->quotaExceeded = '0';
|
2446 |
$this->_settings->prioritySkip = NULL;
|
2447 |
+
Log::addInfo("CHECK QUOTA: Skipped: ".json_encode($this->prioQ->getSkipped()));
|
2448 |
|
2449 |
?><script>var shortPixelQuotaExceeded = 0;</script><?php
|
2450 |
}
|
2455 |
return $quotaData;
|
2456 |
}
|
2457 |
|
2458 |
+
/** Checks if ID has a meta component
|
2459 |
+
* @param int $id $imageId
|
2460 |
+
* @return string|array|null Returns array custom metadata ( or null ) or URL to attachment.
|
2461 |
+
*/
|
2462 |
public function isValidMetaId($id) {
|
2463 |
return substr($id, 0, 2 ) == "C-" ? $this->spMetaDao->getMeta(substr($id, 2)) : wp_get_attachment_url($id);
|
2464 |
}
|
2465 |
|
2466 |
+
/** View for Custom media
|
2467 |
+
* @todo Move this
|
2468 |
+
*/
|
2469 |
public function listCustomMedia() {
|
2470 |
if( ! class_exists( 'ShortPixelListTable' ) ) {
|
2471 |
require_once('view/shortpixel-list-table.php');
|
2484 |
if ( isset($_GET['noheader']) ) {
|
2485 |
require_once(ABSPATH . 'wp-admin/admin-header.php');
|
2486 |
}
|
2487 |
+
//$this->outputHSBeacon();
|
2488 |
+
\ShortPixel\HelpScout::outputBeacon($this->getApiKey());
|
2489 |
?>
|
2490 |
<div class="wrap shortpixel-other-media">
|
2491 |
<h2>
|
|
|
|
|
|
|
|
|
|
|
2492 |
<?php _e('Other Media optimized by ShortPixel','shortpixel-image-optimiser');?>
|
2493 |
</h2>
|
2494 |
|
2495 |
+
<div id="legacy">
|
2496 |
+
<div id="legacy" class="metabox-holder">
|
2497 |
+
<div id="legacy">
|
2498 |
+
<div style="float:left;">
|
2499 |
+
<a href="upload.php?page=wp-short-pixel-custom&refresh=1" id="refresh" class="button button-primary" title="<?php _e('Refresh custom folders content','shortpixel-image-optimiser');?>">
|
2500 |
+
<?php _e('Refresh folders','shortpixel-image-optimiser');?>
|
2501 |
+
</a>
|
2502 |
+
</div>
|
2503 |
<div class="meta-box-sortables ui-sortable">
|
2504 |
<form method="get">
|
2505 |
<input type="hidden" name="page" value="wp-short-pixel-custom" />
|
2526 |
}
|
2527 |
|
2528 |
/** Front End function that controls bulk processes.
|
2529 |
+
* TODO This is a Bulk controller
|
2530 |
*/
|
2531 |
public function bulkProcess() {
|
2532 |
global $wpdb;
|
2581 |
|
2582 |
if(isset($_POST["bulkRestore"]))
|
2583 |
{
|
2584 |
+
$bulkRestore = new \ShortPixel\BulkRestoreAll(); // controller
|
2585 |
$bulkRestore->setShortPixel($this);
|
2586 |
$bulkRestore->setupBulk();
|
2587 |
|
2654 |
{
|
2655 |
$viewObj = new $partControl();
|
2656 |
$viewObj->setShortPixel($this);
|
2657 |
+
$viewObj->loadView(); // TODO [BS] This should call load, which should init and call view inside controller.
|
2658 |
}
|
2659 |
|
2660 |
if (! $template_part)
|
2675 |
}
|
2676 |
}
|
2677 |
|
2678 |
+
// TODO - Calculate time left Utility function -Called in bulkProcess.
|
2679 |
public function bulkProgressMessage($percent, $minutes) {
|
2680 |
$timeEst = "";
|
2681 |
self::log("bulkProgressMessage(): percent: " . $percent);
|
2697 |
return $timeEst;
|
2698 |
}
|
2699 |
|
2700 |
+
// TODO - Folder Model action
|
2701 |
public function emptyBackup(){
|
2702 |
if(file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
2703 |
|
2717 |
}
|
2718 |
}
|
2719 |
|
2720 |
+
|
2721 |
public function backupFolderIsEmpty() {
|
2722 |
if(file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
2723 |
return count(scandir(SHORTPIXEL_BACKUP_FOLDER)) > 2 ? false : true;
|
2778 |
die();
|
2779 |
}
|
2780 |
|
2781 |
+
/** Gets data for image comparison. Returns JSON
|
2782 |
+
*
|
2783 |
+
* @return json JSON data.
|
2784 |
+
* TODO - Should return via JSON function in tools
|
2785 |
+
*/
|
2786 |
public function getComparerData() {
|
2787 |
if (!isset($_POST['id']) || !current_user_can( 'upload_files' ) && !current_user_can( 'edit_posts' ) ) {
|
2788 |
wp_die(json_encode((object)array('origUrl' => false, 'optUrl' => false, 'width' => 0, 'height' => 0)));
|
2789 |
}
|
2790 |
|
2791 |
$ret = array();
|
2792 |
+
// This shall not be Intval, since Post_id can be custom (C-xx)
|
2793 |
+
$handle = new ShortPixelMetaFacade( sanitize_text_field($_POST['id']) );
|
2794 |
|
2795 |
$meta = $handle->getMeta();
|
2796 |
$rawMeta = $handle->getRawMeta();
|
2830 |
die(json_encode((object)$ret));
|
2831 |
}
|
2832 |
|
2833 |
+
// TODO This could be something in an install class.
|
2834 |
public function newApiKey() {
|
2835 |
if ( !current_user_can( 'manage_options' ) ) {
|
2836 |
wp_die(__('You do not have sufficient permissions to access this page.','shortpixel-image-optimiser'));
|
2854 |
)
|
2855 |
);
|
2856 |
|
2857 |
+
$newKeyResponse = wp_remote_post("https://shortpixel.com/free-sign-up-plugin", $params);
|
2858 |
|
2859 |
if ( is_object($newKeyResponse) && get_class($newKeyResponse) == 'WP_Error' ) {
|
2860 |
die(json_encode((object)array('Status' => 'fail', 'Details' => '503')));
|
2922 |
|
2923 |
}
|
2924 |
|
2925 |
+
// TODO - Part of the folder model.
|
2926 |
public static function getCustomFolderBase() {
|
2927 |
if(is_main_site()) {
|
2928 |
$base = get_home_path();
|
2933 |
}
|
2934 |
}
|
2935 |
|
2936 |
+
// TODO - Should be part of folder model
|
2937 |
protected function fullRefreshCustomFolder($path, &$notice) {
|
2938 |
$folder = $this->spMetaDao->getFolder($path);
|
2939 |
$diff = $folder->checkFolderContents(array('ShortPixelCustomMetaDao', 'getPathFiles'));
|
2940 |
}
|
2941 |
|
2942 |
+
// @todo - Should be part of folder model
|
2943 |
+
public function refreshCustomFolders(&$notice, $ignore = false) {
|
2944 |
$customFolders = array();
|
2945 |
if($this->_settings->hasCustomFolders) {
|
2946 |
$customFolders = $this->spMetaDao->getFolders();
|
2969 |
return $customFolders;
|
2970 |
}
|
2971 |
|
2972 |
+
/** Updates HTAccess files for Webp
|
2973 |
+
* @param boolean $clear Clear removes all statements from htaccess. For disabling webp.
|
2974 |
+
*/
|
2975 |
+
public static function alterHtaccess( $clear = false ){
|
2976 |
// [BS] Backward compat. 11/03/2019 - remove possible settings from root .htaccess
|
2977 |
$upload_dir = wp_upload_dir();
|
2978 |
$upload_base = trailingslashit($upload_dir['basedir']);
|
3024 |
' ;
|
3025 |
|
3026 |
insert_with_markers( get_home_path() . '.htaccess', 'ShortPixelWebp', $rules);
|
3027 |
+
|
3028 |
+
/** In uploads and on, it needs Inherit. Otherwise things such as the 404 error page will not be loaded properly
|
3029 |
+
* since the WP rewrite will not be active at that point (overruled) **/
|
3030 |
+
$rules = str_replace('RewriteEngine On', 'RewriteEngine On' . PHP_EOL . 'RewriteOptions Inherit', $rules);
|
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', '
|
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 = "";
|
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 );
|
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
|
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",
|
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
|
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 ));
|
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; }
|
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;
|
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'] ) {
|
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) {
|
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')
|
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++) {
|
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);
|
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 |
|
3350 |
|
3351 |
}
|
3352 |
|
3353 |
+
/** Adds NextGenGalleries to Custom Images Library
|
3354 |
+
* @param boolean $silent Will not return messages if silent
|
3355 |
+
* @return array Array for information
|
3356 |
+
* @todo Move to a integration class || This can be removed after nextgen.php in externals is released.
|
3357 |
+
*/
|
3358 |
public function addNextGenGalleriesToCustom($silent) {
|
3359 |
$customFolders = array();
|
3360 |
$folderMsg = "";
|
3374 |
return array("message" => $silent? "" : $folderMsg, "customFolders" => $customFolders);
|
3375 |
}
|
3376 |
|
3377 |
+
/** Gets the average compression
|
3378 |
+
* @return int Average compressions percentage
|
3379 |
+
* @todo Move to utility (?)
|
3380 |
+
*/
|
3381 |
public function getAverageCompression(){
|
3382 |
return $this->_settings->totalOptimized > 0
|
3383 |
? round(( 1 - ( $this->_settings->totalOptimized / $this->_settings->totalOriginal ) ) * 100, 2)
|
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']);
|
3427 |
}
|
3428 |
if($settings !== false) {
|
3469 |
$response = wp_remote_get($requestURL, $args);
|
3470 |
$comm['C: ' . (number_format(microtime(true) - $time, 2))] = array("sent" => "POST: " . $requestURL, "args" => $args, "received" => $response);
|
3471 |
}
|
3472 |
+
Log::addInfo("API STATUS COMM: " . json_encode($comm));
|
3473 |
|
3474 |
$defaultData = array(
|
3475 |
"APIKeyValid" => false,
|
3555 |
$this->_settings->quotaExceeded = 0;
|
3556 |
}
|
3557 |
|
3558 |
+
/** Generates column for custom media library
|
3559 |
+
* @todo Move this to custom media controller
|
3560 |
+
*/
|
3561 |
public function generateCustomColumn( $column_name, $id, $extended = false ) {
|
3562 |
if( 'wp-shortPixel' == $column_name ) {
|
3563 |
|
3571 |
$data = ShortPixelMetaFacade::sanitizeMeta(wp_get_attachment_metadata($id));
|
3572 |
|
3573 |
if($extended && isset($_GET['SHORTPIXEL_DEBUG'])) {
|
3574 |
+
// var_dump($data);
|
3575 |
var_dump(wp_get_attachment_url($id));
|
3576 |
echo('<br><br>' . json_encode(ShortPixelMetaFacade::getWPMLDuplicates($id)));
|
3577 |
+
echo('<br><br>'); print_r($data); echo ''; //json_encode($data))
|
3578 |
echo('<br><br>');
|
3579 |
}
|
3580 |
|
3701 |
}
|
3702 |
}
|
3703 |
|
3704 |
+
/** Make columns sortable in Media Library
|
3705 |
+
* @hook manage_upload_sortable_columns
|
3706 |
+
* @param array $columns Array of colums sortable
|
3707 |
+
* @todo Should be part of media library controller.
|
3708 |
+
*/
|
3709 |
function columnRegisterSortable($columns) {
|
3710 |
$columns['wp-shortPixel'] = 'ShortPixel Compression';
|
3711 |
return $columns;
|
3712 |
}
|
3713 |
|
3714 |
+
/** Apply sort filter in Media Library
|
3715 |
+
* @hook request
|
3716 |
+
* @param array $columns Array of colums sortable
|
3717 |
+
* @todo Should be part of media library controller. ( is request best hook for this?)
|
3718 |
+
*/
|
3719 |
+
|
3720 |
function columnOrderFilterBy($vars) {
|
3721 |
if ( isset( $vars['orderby'] ) && 'ShortPixel Compression' == $vars['orderby'] ) {
|
3722 |
$vars = array_merge( $vars, array(
|
3743 |
return $vars;
|
3744 |
}
|
3745 |
|
3746 |
+
/*
|
3747 |
+
* @hook restrict_manage_posts
|
3748 |
+
* @todo Should be part of media library controller. ( is request best hook for this?)
|
3749 |
+
*/
|
3750 |
function mediaAddFilterDropdown() {
|
3751 |
$scr = get_current_screen();
|
3752 |
if ( $scr->base !== 'upload' ) return;
|
3769 |
. "</select>");
|
3770 |
}
|
3771 |
|
3772 |
+
/** Calculates Optimization if PNG2Jpg does something
|
3773 |
+
* @param array $meta Image metadata
|
3774 |
+
* @return string Formatted improvement
|
3775 |
+
*/
|
3776 |
function optimizationPercentIfPng2Jpg($meta) {
|
3777 |
$png2jpgPercent = isset($meta['ShortPixelPng2Jpg']['optimizationPercent']) ? $meta['ShortPixelPng2Jpg']['optimizationPercent'] : 0;
|
3778 |
return number_format(100.0 - (100.0 - $png2jpgPercent) * (100.0 - $meta['ShortPixelImprovement']) / 100.0, 2);
|
3779 |
}
|
3780 |
|
3781 |
+
/** Meta box for shortpixel in view image
|
3782 |
+
* @hook add_meta_boxes
|
3783 |
+
* @todo move to appr. controller
|
3784 |
+
*/
|
3785 |
function shortpixelInfoBox() {
|
3786 |
if(get_post_type( ) == 'attachment') {
|
3787 |
add_meta_box(
|
3795 |
}
|
3796 |
}
|
3797 |
|
3798 |
+
/** Meta box for view image
|
3799 |
+
* @todo move to appr. controller
|
3800 |
+
*/
|
3801 |
function shortpixelInfoBoxContent( $post ) {
|
3802 |
$this->generateCustomColumn( 'wp-shortPixel', $post->ID, true );
|
3803 |
}
|
3804 |
|
3805 |
+
/** When an image is deleted
|
3806 |
+
* @hook delete_attachment
|
3807 |
+
* @param int $post_id ID of Post
|
3808 |
+
* @return itemHandler ItemHandler object.
|
3809 |
+
*/
|
3810 |
public function onDeleteImage($post_id) {
|
3811 |
$itemHandler = new ShortPixelMetaFacade($post_id);
|
3812 |
$urlsPaths = $itemHandler->getURLsAndPATHs(true, false, true, array(), true);
|
3817 |
return $itemHandler; //return it because we call it also on replace and on replace we need to follow this by deleting SP metadata, on delete it
|
3818 |
}
|
3819 |
|
3820 |
+
/** Removes webp and backup from specified paths
|
3821 |
+
*/
|
3822 |
public function deleteBackupsAndWebPs($paths) {
|
3823 |
+
/**
|
3824 |
+
* Passing a truthy value to the filter will effectively short-circuit this function.
|
3825 |
+
* So third party plugins can handle deletion by there own.
|
3826 |
+
*/
|
3827 |
+
if(apply_filters('shortpixel_skip_delete_backups_and_webps', false, $paths)){
|
3828 |
+
return;
|
3829 |
+
}
|
3830 |
+
|
3831 |
$backupFolder = trailingslashit($this->getBackupFolder($paths[0]));
|
3832 |
foreach($paths as $path) {
|
3833 |
$pos = strrpos($path, ".");
|
3844 |
@unlink($backupFolder . preg_replace("/\." . $extension . "$/i", '@2x.' . $extension, $fileName));
|
3845 |
}
|
3846 |
}
|
3847 |
+
//
|
3848 |
+
/**
|
3849 |
+
* @hook manage_media_columns
|
3850 |
+
* @todo Move to appr. controller.
|
3851 |
+
*/
|
3852 |
public function columns( $defaults ) {
|
3853 |
$defaults['wp-shortPixel'] = __('ShortPixel Compression', 'shortpixel-image-optimiser');
|
3854 |
if(current_user_can( 'manage_options' )) {
|
3855 |
$defaults['wp-shortPixel'] .=
|
3856 |
+
' <a href="options-general.php?page=wp-shortpixel-settings&part=stats" title="'
|
3857 |
. __('ShortPixel Statistics','shortpixel-image-optimiser')
|
3858 |
. '"><span class="dashicons dashicons-dashboard"></span></a>';
|
3859 |
}
|
3860 |
return $defaults;
|
3861 |
}
|
3862 |
|
3863 |
+
// todo move NGG specific function to own integration
|
3864 |
public function nggColumns( $defaults ) {
|
3865 |
$this->nggColumnIndex = count($defaults) + 1;
|
3866 |
add_filter( 'ngg_manage_images_column_' . $this->nggColumnIndex . '_header', array( &$this, 'nggColumnHeader' ) );
|
3913 |
}
|
3914 |
|
3915 |
public function generatePluginLinks($links) {
|
3916 |
+
$in = '<a href="options-general.php?page=wp-shortpixel-settings">Settings</a>';
|
3917 |
array_unshift($links, $in);
|
3918 |
return $links;
|
3919 |
}
|
3920 |
|
3921 |
+
// @todo Should be utility function
|
3922 |
static public function formatBytes($bytes, $precision = 2) {
|
3923 |
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
3924 |
|
3931 |
return round($bytes, $precision) . ' ' . $units[$pow];
|
3932 |
}
|
3933 |
|
3934 |
+
/** Checks if file can be processed. Mainly against exclusion
|
3935 |
+
* @param int $ID ImageID
|
3936 |
+
* @param array $excludeExtensions Excludes Extentions from settings
|
3937 |
+
* @todo Part of Image model
|
3938 |
+
*/
|
3939 |
public function isProcessable($ID, $excludeExtensions = array()) {
|
3940 |
$excludePatterns = $this->_settings->excludePatterns;
|
3941 |
return self::_isProcessable($ID, $excludeExtensions, $excludePatterns);
|
3942 |
}
|
3943 |
|
3944 |
+
/** Checks if path can be processed. Mainly against exclusion
|
3945 |
+
* @param string $path Path
|
3946 |
+
* @param array $excludeExtensions Excludes Extentions from settings
|
3947 |
+
* @todo Part of Image / Folder(?) model
|
3948 |
+
*/
|
3949 |
public function isProcessablePath($path, $excludeExtensions = array()) {
|
3950 |
$excludePatterns = $this->_settings->excludePatterns;
|
3951 |
return self::_isProcessablePath($path, $excludeExtensions, $excludePatterns);
|
4015 |
return $itemHandler->getURLsAndPATHs($this->_settings->processThumbnails, $onlyThumbs, $this->_settings->optimizeRetina, $this->_settings->excludeSizes);
|
4016 |
}
|
4017 |
|
4018 |
+
/** Remove a directory
|
4019 |
+
* @param string $dirPath Path of directory to remove.
|
4020 |
+
* @todo Part of folder model.
|
4021 |
+
*/
|
4022 |
public static function deleteDir($dirPath) {
|
4023 |
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
|
4024 |
$dirPath .= '/';
|
4034 |
}
|
4035 |
}
|
4036 |
|
4037 |
+
/** Gets size of folder recursivly
|
4038 |
+
* @param string $path Path
|
4039 |
+
* @todo Move to folder model
|
4040 |
+
*/
|
4041 |
static public function folderSize($path) {
|
4042 |
$total_size = 0;
|
4043 |
if(file_exists($path)) {
|
4070 |
|
4071 |
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {
|
4072 |
//we check that the backup folder exists, if not we create it so we can copy into it
|
4073 |
+
if(! ShortPixelFolder::createBackUpFolder() ) return;
|
4074 |
}
|
4075 |
|
4076 |
$scannedDirectory = array_diff(scandir($oldBackupFolder), array('..', '.'));
|
4082 |
@rmdir($oldBackupFolder);
|
4083 |
}
|
4084 |
}
|
4085 |
+
|
4086 |
//now if the backup folder does not contain the uploads level, create it
|
4087 |
if( !is_dir(SHORTPIXEL_BACKUP_FOLDER . '/' . SHORTPIXEL_UPLOADS_NAME )
|
4088 |
&& !is_dir(SHORTPIXEL_BACKUP_FOLDER . '/' . basename(WP_CONTENT_DIR))) {
|
4089 |
@rename(SHORTPIXEL_BACKUP_FOLDER, SHORTPIXEL_BACKUP_FOLDER."_tmp");
|
4090 |
+
ShortPixelFolder::createBackUpFolder();
|
4091 |
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER.'/'.SHORTPIXEL_UPLOADS_NAME);
|
4092 |
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {//just in case..
|
4093 |
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER);
|
4096 |
//then create the wp-content level if not present
|
4097 |
if(!is_dir(SHORTPIXEL_BACKUP_FOLDER . '/' . basename(WP_CONTENT_DIR))) {
|
4098 |
@rename(SHORTPIXEL_BACKUP_FOLDER, SHORTPIXEL_BACKUP_FOLDER."_tmp");
|
4099 |
+
ShortPixelFolder::createBackUpFolder();
|
4100 |
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER.'/' . basename(WP_CONTENT_DIR));
|
4101 |
if(!file_exists(SHORTPIXEL_BACKUP_FOLDER)) {//just in case..
|
4102 |
@rename(SHORTPIXEL_BACKUP_FOLDER."_tmp", SHORTPIXEL_BACKUP_FOLDER);
|
4103 |
}
|
4104 |
}
|
4105 |
+
|
4106 |
+
if (! file_exists( trailingslashit(SHORTPIXEL_BACKUP_FOLDER) . '.htaccess') )
|
4107 |
+
{
|
4108 |
+
ShortPixelFolder::protectDirectoryListing(SHORTPIXEL_BACKUP_FOLDER);
|
4109 |
+
}
|
4110 |
return;
|
4111 |
}
|
4112 |
|
4128 |
return $sizes;
|
4129 |
}
|
4130 |
|
4131 |
+
/** @todo Remove here
|
4132 |
+
* */
|
4133 |
function getMaxIntermediateImageSize() {
|
4134 |
global $_wp_additional_image_sizes;
|
4135 |
|
4156 |
return array_values(array_diff(array(0, 1, 2), array(0 + $compressionType)));
|
4157 |
}
|
4158 |
|
4159 |
+
function outputHSBeacon() {
|
4160 |
+
Log::addWarn('OutputHSBeacon called on old function');
|
4161 |
+
?>
|
4162 |
+
<style>
|
4163 |
+
.shortpixel-hs-blind {
|
4164 |
+
position: fixed;
|
4165 |
+
bottom: 18px;
|
4166 |
+
right: 0;
|
4167 |
+
z-index: 20003;
|
4168 |
+
background-color: white;
|
4169 |
+
width: 87px;
|
4170 |
+
height: 174px;
|
4171 |
+
border-radius: 20px 0 0 20px;
|
4172 |
+
}
|
4173 |
+
.shortpixel-hs-button-blind {
|
4174 |
+
display:none;
|
4175 |
+
position: fixed;
|
4176 |
+
bottom: 115px;right: 0;
|
4177 |
+
z-index: 20003;
|
4178 |
+
background-color: white;
|
4179 |
+
width: 237px;
|
4180 |
+
height: 54px;
|
4181 |
+
}
|
4182 |
+
.shortpixel-hs-tools {
|
4183 |
+
position: fixed;
|
4184 |
+
bottom: 116px;
|
4185 |
+
right: 0px;
|
4186 |
+
z-index: 20003;
|
4187 |
+
background-color: #ecf9fc;
|
4188 |
+
padding: 8px 18px 3px 12px;
|
4189 |
+
border-radius: 26px 0 0 26px;
|
4190 |
+
-webkit-box-shadow: 1px 1px 5px 0px rgba(6,109,117,1);
|
4191 |
+
-moz-box-shadow: 1px 1px 5px 0px rgba(6,109,117,1);
|
4192 |
+
box-shadow: 1px 1px 10px 0px rgb(172, 173, 173);
|
4193 |
+
}
|
4194 |
+
@media (max-width: 767px) {
|
4195 |
+
.shortpixel-hs-blind {
|
4196 |
+
bottom: 8px;
|
4197 |
+
height: 194px;
|
4198 |
+
}
|
4199 |
+
.shortpixel-hs-button-blind {
|
4200 |
+
bottom: 100px;
|
4201 |
+
}
|
4202 |
+
}
|
4203 |
+
</style>
|
4204 |
+
<div id="shortpixel-hs-blind" class="shortpixel-hs-blind"></div>
|
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>
|
4211 |
+
<script>
|
4212 |
+
window.shortpixelHSOpen = -1;
|
4213 |
+
function shortpixelToggleHS() {
|
4214 |
+
if(window.shortpixelHSOpen == -1) {
|
4215 |
+
HS.beacon.init();
|
4216 |
+
}
|
4217 |
+
if(window.shortpixelHSOpen == 1) {
|
4218 |
+
HS.beacon.close();
|
4219 |
+
jQuery("#shortpixel-hs-button-blind").css('display', 'none');
|
4220 |
+
window.shortpixelHSOpen = 0;
|
4221 |
+
} else {
|
4222 |
+
HS.beacon.open();
|
4223 |
+
jQuery("#shortpixel-hs-button-blind").css('display', 'block');
|
4224 |
+
window.shortpixelHSOpen = 1;
|
4225 |
+
}
|
4226 |
+
}
|
4227 |
+
</script>
|
4228 |
+
<script type="text/javascript" src="https://quriobot.com/qb/widget/KoPqxmzqzjbg5eNl/V895xbyndnmeqZYd" async defer></script>
|
4229 |
<script>
|
4230 |
<?php
|
4231 |
$screen = get_current_screen();
|
4340 |
return $this->_settings->resizeHeight;
|
4341 |
}
|
4342 |
public static function getAffiliateSufix() {
|
4343 |
+
Log::addDebug('Function call - getAffiliateSufix should be removed');
|
4344 |
// not allowed anymore by WP as of Sept.27 2018
|
4345 |
// return isset($_COOKIE["AffiliateShortPixel"])
|
4346 |
// ? "/affiliate/" . $_COOKIE["AffiliateShortPixel"]
|
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
class WPShortPixelSettings {
|
4 |
private $_apiKey = '';
|
5 |
private $_compressionType = 1;
|
6 |
private $_keepExif = 0;
|
@@ -8,7 +8,7 @@ class WPShortPixelSettings {
|
|
8 |
private $_CMYKtoRGBconversion = 1;
|
9 |
private $_backupImages = 1;
|
10 |
private $_verifiedKey = false;
|
11 |
-
|
12 |
private $_resizeImages = false;
|
13 |
private $_resizeWidth = 0;
|
14 |
private $_resizeHeight = 0;
|
@@ -77,7 +77,7 @@ class WPShortPixelSettings {
|
|
77 |
'mediaLibraryViewMode' => array('key' => 'wp-short-pixel-view-mode', 'default' => null, 'group' => 'state'),
|
78 |
'redirectedSettings' => array('key' => 'wp-short-pixel-redirected-settings', 'default' => null, 'group' => 'state'),
|
79 |
'convertedPng2Jpg' => array('key' => 'wp-short-pixel-converted-png2jpg', 'default' => array(), 'group' => 'state'),
|
80 |
-
|
81 |
//bulk state machine
|
82 |
'bulkType' => array('key' => 'wp-short-pixel-bulk-type', 'default' => null, 'group' => 'bulk'),
|
83 |
'bulkLastStatus' => array('key' => 'wp-short-pixel-bulk-last-status', 'default' => null, 'group' => 'bulk'),
|
@@ -96,17 +96,52 @@ class WPShortPixelSettings {
|
|
96 |
'flagId' => array('key' => 'wp-short-pixel-flag-id', 'default' => 0, 'group' => 'bulk'),
|
97 |
'failedImages' => array('key' => 'wp-short-pixel-failed-imgs', 'default' => 0, 'group' => 'bulk'),
|
98 |
'bulkProcessingStatus' => array('key' => 'bulkProcessingStatus', 'default' => null, 'group' => 'bulk'),
|
99 |
-
|
100 |
//'priorityQueue' => array('key' => 'wp-short-pixel-priorityQueue', 'default' => array()),
|
101 |
'prioritySkip' => array('key' => 'wp-short-pixel-prioritySkip', 'default' => array(), 'group' => 'state'),
|
102 |
-
|
103 |
//'' => array('key' => 'wp-short-pixel-', 'default' => null),
|
104 |
);
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
$this->populateOptions();
|
108 |
-
}
|
109 |
-
|
110 |
public function populateOptions() {
|
111 |
|
112 |
$this->_apiKey = self::getOpt('wp-short-pixel-apiKey', '');
|
@@ -115,9 +150,9 @@ class WPShortPixelSettings {
|
|
115 |
$this->_processThumbnails = self::getOpt('wp-short-process_thumbnails', $this->_processThumbnails);
|
116 |
$this->_CMYKtoRGBconversion = self::getOpt('wp-short-pixel_cmyk2rgb', $this->_CMYKtoRGBconversion);
|
117 |
$this->_backupImages = self::getOpt('wp-short-backup_images', $this->_backupImages);
|
118 |
-
$this->_resizeImages = self::getOpt( 'wp-short-pixel-resize-images', 0);
|
119 |
-
$this->_resizeWidth = self::getOpt( 'wp-short-pixel-resize-width', 0);
|
120 |
-
$this->_resizeHeight = self::getOpt( 'wp-short-pixel-resize-height', 0);
|
121 |
|
122 |
// the following lines practically set defaults for options if they're not set
|
123 |
foreach(self::$_optionsMap as $opt) {
|
@@ -128,14 +163,14 @@ class WPShortPixelSettings {
|
|
128 |
self::setOpt(self::$_optionsMap["downloadArchive"]['key'], crc32(get_site_url())%10);
|
129 |
}
|
130 |
}
|
131 |
-
|
132 |
public static function debugResetOptions() {
|
133 |
foreach(self::$_optionsMap as $key => $val) {
|
134 |
delete_option($val['key']);
|
135 |
}
|
136 |
delete_option("wp-short-pixel-bulk-previous-percent");
|
137 |
}
|
138 |
-
|
139 |
public static function onActivate() {
|
140 |
if(!self::getOpt('wp-short-pixel-verifiedKey', false)) {
|
141 |
update_option('wp-short-pixel-activation-notice', true, 'no');
|
@@ -155,12 +190,12 @@ class WPShortPixelSettings {
|
|
155 |
delete_option('wp-short-pixel-priorityQueue');
|
156 |
}
|
157 |
}
|
158 |
-
|
159 |
public static function onDeactivate() {
|
160 |
delete_option('wp-short-pixel-activation-notice');
|
161 |
}
|
162 |
|
163 |
-
|
164 |
public function __get($name)
|
165 |
{
|
166 |
if (array_key_exists($name, self::$_optionsMap)) {
|
@@ -181,8 +216,8 @@ class WPShortPixelSettings {
|
|
181 |
$this->setOpt(self::$_optionsMap[$name]['key'], $value);
|
182 |
} else {
|
183 |
delete_option(self::$_optionsMap[$name]['key']);
|
184 |
-
}
|
185 |
-
}
|
186 |
}
|
187 |
|
188 |
public static function getOpt($key, $default = null) {
|
@@ -194,7 +229,7 @@ class WPShortPixelSettings {
|
|
194 |
}
|
195 |
return get_option($key);
|
196 |
}
|
197 |
-
|
198 |
public function setOpt($key, $val) {
|
199 |
$ret = update_option($key, $val, 'no');
|
200 |
|
@@ -216,17 +251,17 @@ class WPShortPixelSettings {
|
|
216 |
$sql = "SELECT * FROM {$wpdb->prefix}options WHERE option_name = '" . $key . "'";
|
217 |
$rows = $wpdb->get_results($sql);
|
218 |
if(count($rows) === 0) {
|
219 |
-
$wpdb->insert($wpdb->prefix.'options',
|
220 |
-
array("option_name" => $key, "option_value" => (is_array($val) ? serialize($val) : $val), "autoload" => "no"),
|
221 |
array("option_name" => "%s", "option_value" => (is_numeric($val) ? "%d" : "%s")));
|
222 |
} else { //update
|
223 |
-
$sql = "update {$wpdb->prefix}options SET option_value=" .
|
224 |
-
(is_array($val)
|
225 |
-
? "'" . serialize($val) . "'"
|
226 |
: (is_numeric($val) ? $val : "'" . $val . "'")) . " WHERE option_name = '" . $key . "'";
|
227 |
$rows = $wpdb->get_results($sql);
|
228 |
}
|
229 |
-
|
230 |
if($val != get_option($key)) {
|
231 |
//tough luck, gonna use the bomb...
|
232 |
wp_cache_flush();
|
1 |
<?php
|
2 |
+
/** Settings Model **/
|
3 |
+
class WPShortPixelSettings extends ShortPixel\ShortPixelModel {
|
4 |
private $_apiKey = '';
|
5 |
private $_compressionType = 1;
|
6 |
private $_keepExif = 0;
|
8 |
private $_CMYKtoRGBconversion = 1;
|
9 |
private $_backupImages = 1;
|
10 |
private $_verifiedKey = false;
|
11 |
+
|
12 |
private $_resizeImages = false;
|
13 |
private $_resizeWidth = 0;
|
14 |
private $_resizeHeight = 0;
|
77 |
'mediaLibraryViewMode' => array('key' => 'wp-short-pixel-view-mode', 'default' => null, 'group' => 'state'),
|
78 |
'redirectedSettings' => array('key' => 'wp-short-pixel-redirected-settings', 'default' => null, 'group' => 'state'),
|
79 |
'convertedPng2Jpg' => array('key' => 'wp-short-pixel-converted-png2jpg', 'default' => array(), 'group' => 'state'),
|
80 |
+
|
81 |
//bulk state machine
|
82 |
'bulkType' => array('key' => 'wp-short-pixel-bulk-type', 'default' => null, 'group' => 'bulk'),
|
83 |
'bulkLastStatus' => array('key' => 'wp-short-pixel-bulk-last-status', 'default' => null, 'group' => 'bulk'),
|
96 |
'flagId' => array('key' => 'wp-short-pixel-flag-id', 'default' => 0, 'group' => 'bulk'),
|
97 |
'failedImages' => array('key' => 'wp-short-pixel-failed-imgs', 'default' => 0, 'group' => 'bulk'),
|
98 |
'bulkProcessingStatus' => array('key' => 'bulkProcessingStatus', 'default' => null, 'group' => 'bulk'),
|
99 |
+
|
100 |
//'priorityQueue' => array('key' => 'wp-short-pixel-priorityQueue', 'default' => array()),
|
101 |
'prioritySkip' => array('key' => 'wp-short-pixel-prioritySkip', 'default' => array(), 'group' => 'state'),
|
102 |
+
|
103 |
//'' => array('key' => 'wp-short-pixel-', 'default' => null),
|
104 |
);
|
105 |
+
|
106 |
+
// This array -- field_name -> (s)anitize mask
|
107 |
+
protected $model = array(
|
108 |
+
'apiKey' => array('s' => 'string'), // string
|
109 |
+
// 'verifiedKey' => array('s' => 'string'), // string
|
110 |
+
'compressionType' => array('s' => 'int'), // int
|
111 |
+
'resizeWidth' => array('s' => 'int'), // int
|
112 |
+
'resizeHeight' => array('s' => 'int'), // int
|
113 |
+
'processThumbnails' => array('s' => 'boolean'), // checkbox
|
114 |
+
'backupImages' => array('s' => 'boolean'), // checkbox
|
115 |
+
'keepExif' => array('s' => 'int'), // checkbox
|
116 |
+
'resizeImages' => array('s' => 'boolean'),
|
117 |
+
'resizeType' => array('s' => 'string'),
|
118 |
+
'includeNextGen' => array('s' => 'boolean'), // checkbox
|
119 |
+
'png2jpg' => array('s' => 'int'), // checkbox
|
120 |
+
'CMYKtoRGBconversion' => array('s' => 'boolean'), //checkbox
|
121 |
+
'createWebp' => array('s' => 'boolean'), // checkbox
|
122 |
+
'deliverWebp' => array('s' => 'int'), // checkbox
|
123 |
+
'optimizeRetina' => array('s' => 'boolean'), // checkbox
|
124 |
+
'optimizeUnlisted' => array('s' => 'boolean'), // $checkbox
|
125 |
+
'optimizePdfs' => array('s' => 'boolean'), //checkbox
|
126 |
+
'excludePatterns' => array('s' => 'exception'), // - processed, multi-layer, so skip
|
127 |
+
'siteAuthUser' => array('s' => 'string'), // string
|
128 |
+
'siteAuthPass' => array('s' => 'string'), // string
|
129 |
+
'frontBootstrap' => array('s' =>'boolean'), // checkbox
|
130 |
+
'autoMediaLibrary' => array('s' => 'boolean'), // checkbox
|
131 |
+
'excludeSizes' => array('s' => 'array'), // Array
|
132 |
+
'cloudflareEmail' => array('s' => 'string'), // string
|
133 |
+
'cloudflareAuthKey' => array('s' => 'string'), // string
|
134 |
+
'cloudflareZoneID' => array('s' => 'string'), // string
|
135 |
+
'savedSpace' => array('s' => 'skip'),
|
136 |
+
'fileCount' => array('s' => 'skip'), // int
|
137 |
+
'under5Percent' => array('s' => 'skip'), // int
|
138 |
+
);
|
139 |
+
|
140 |
+
// @todo Eventually, this should not happen onLoad, but on demand.
|
141 |
+
public function __construct() {
|
142 |
$this->populateOptions();
|
143 |
+
}
|
144 |
+
|
145 |
public function populateOptions() {
|
146 |
|
147 |
$this->_apiKey = self::getOpt('wp-short-pixel-apiKey', '');
|
150 |
$this->_processThumbnails = self::getOpt('wp-short-process_thumbnails', $this->_processThumbnails);
|
151 |
$this->_CMYKtoRGBconversion = self::getOpt('wp-short-pixel_cmyk2rgb', $this->_CMYKtoRGBconversion);
|
152 |
$this->_backupImages = self::getOpt('wp-short-backup_images', $this->_backupImages);
|
153 |
+
$this->_resizeImages = self::getOpt( 'wp-short-pixel-resize-images', 0);
|
154 |
+
$this->_resizeWidth = self::getOpt( 'wp-short-pixel-resize-width', 0);
|
155 |
+
$this->_resizeHeight = self::getOpt( 'wp-short-pixel-resize-height', 0);
|
156 |
|
157 |
// the following lines practically set defaults for options if they're not set
|
158 |
foreach(self::$_optionsMap as $opt) {
|
163 |
self::setOpt(self::$_optionsMap["downloadArchive"]['key'], crc32(get_site_url())%10);
|
164 |
}
|
165 |
}
|
166 |
+
|
167 |
public static function debugResetOptions() {
|
168 |
foreach(self::$_optionsMap as $key => $val) {
|
169 |
delete_option($val['key']);
|
170 |
}
|
171 |
delete_option("wp-short-pixel-bulk-previous-percent");
|
172 |
}
|
173 |
+
|
174 |
public static function onActivate() {
|
175 |
if(!self::getOpt('wp-short-pixel-verifiedKey', false)) {
|
176 |
update_option('wp-short-pixel-activation-notice', true, 'no');
|
190 |
delete_option('wp-short-pixel-priorityQueue');
|
191 |
}
|
192 |
}
|
193 |
+
|
194 |
public static function onDeactivate() {
|
195 |
delete_option('wp-short-pixel-activation-notice');
|
196 |
}
|
197 |
|
198 |
+
|
199 |
public function __get($name)
|
200 |
{
|
201 |
if (array_key_exists($name, self::$_optionsMap)) {
|
216 |
$this->setOpt(self::$_optionsMap[$name]['key'], $value);
|
217 |
} else {
|
218 |
delete_option(self::$_optionsMap[$name]['key']);
|
219 |
+
}
|
220 |
+
}
|
221 |
}
|
222 |
|
223 |
public static function getOpt($key, $default = null) {
|
229 |
}
|
230 |
return get_option($key);
|
231 |
}
|
232 |
+
|
233 |
public function setOpt($key, $val) {
|
234 |
$ret = update_option($key, $val, 'no');
|
235 |
|
251 |
$sql = "SELECT * FROM {$wpdb->prefix}options WHERE option_name = '" . $key . "'";
|
252 |
$rows = $wpdb->get_results($sql);
|
253 |
if(count($rows) === 0) {
|
254 |
+
$wpdb->insert($wpdb->prefix.'options',
|
255 |
+
array("option_name" => $key, "option_value" => (is_array($val) ? serialize($val) : $val), "autoload" => "no"),
|
256 |
array("option_name" => "%s", "option_value" => (is_numeric($val) ? "%d" : "%s")));
|
257 |
} else { //update
|
258 |
+
$sql = "update {$wpdb->prefix}options SET option_value=" .
|
259 |
+
(is_array($val)
|
260 |
+
? "'" . serialize($val) . "'"
|
261 |
: (is_numeric($val) ? $val : "'" . $val . "'")) . " WHERE option_name = '" . $key . "'";
|
262 |
$rows = $wpdb->get_results($sql);
|
263 |
}
|
264 |
+
|
265 |
if($val != get_option($key)) {
|
266 |
//tough luck, gonna use the bomb...
|
267 |
wp_cache_flush();
|
@@ -4,7 +4,7 @@ Tags: compressor, image, compression, optimize, image optimizer, image optimiser
|
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 5.2
|
6 |
Requires PHP: 5.3
|
7 |
-
Stable tag: 4.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -216,7 +216,9 @@ The ShortPixel Image Optimiser plugin calls the following actions and filters:
|
|
216 |
> do_action( 'shortpixel_image_optimised', $post_id ); //upon successful optimization
|
217 |
> do_action("shortpixel_before_restore_image", $post_id); //before restoring an image from backup
|
218 |
> do_action("shortpixel_after_restore_image", $post_id); //after succesful restore
|
219 |
-
> apply_filters("shortpixel_backup_folder", $backup_folder); //just before returning the ShortPixel backup folder, usually
|
|
|
|
|
220 |
|
221 |
|
222 |
== Screenshots ==
|
@@ -241,6 +243,23 @@ The ShortPixel Image Optimiser plugin calls the following actions and filters:
|
|
241 |
|
242 |
== Changelog ==
|
243 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
244 |
= 4.13.1 =
|
245 |
|
246 |
Release date: 16th April 2019
|
4 |
Requires at least: 3.2.0
|
5 |
Tested up to: 5.2
|
6 |
Requires PHP: 5.3
|
7 |
+
Stable tag: 4.14.0
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
216 |
> do_action( 'shortpixel_image_optimised', $post_id ); //upon successful optimization
|
217 |
> do_action("shortpixel_before_restore_image", $post_id); //before restoring an image from backup
|
218 |
> do_action("shortpixel_after_restore_image", $post_id); //after succesful restore
|
219 |
+
> apply_filters("shortpixel_backup_folder", $backup_folder, $main_file_path, $sizes); //just before returning the ShortPixel backup folder, usually /wp-content/uploads/ShortpixelBackups. The $sizes are the sizes array from metadata.
|
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 ==
|
243 |
|
244 |
== Changelog ==
|
245 |
|
246 |
+
== 4.14.0 ==
|
247 |
+
|
248 |
+
Release date: 17th June 2019
|
249 |
+
* Add new filters proposed by WP Stateless: shortpixel_backup_folder, shortpixel_image_exists, shortpixel_image_urls
|
250 |
+
* Better placement of the elements on the Other Media page
|
251 |
+
* Fix custom bulk for PDFs when the pdf thumbnails are not activated
|
252 |
+
* Fix selecting items from DB twice for bulk in some circumstances
|
253 |
+
* Warn user that converting PNG to JPG while keeping EXIF in options doesn't keep it (no EXIF for PNGs).
|
254 |
+
* When SHORTPIXEL_DEBUG=x get parameter is provided, display a floating link to the shortpixel_log file
|
255 |
+
* Adaptive Max execution time and capped to 90 sec. for the bulk background AJAX calls. (Kinsta has a max_execution_time of 300 sec. in PHP but the HTTP connection is cut after 180 sec.)
|
256 |
+
* Fix custom 404 page for missing images not working when using .htaccess for WebP
|
257 |
+
* Fix WebP picture tag with relative URLs not working in some circumstances
|
258 |
+
* Fix replacing the <img> inside an existing <picture> tag with another <picture> tag.
|
259 |
+
* Clear SP optimization cache in order to be able to optimize an image which initially had permissions error, after changing the permissions.
|
260 |
+
* Fix being able to list the contents of ShortpixelBackups on some badly configured servers.
|
261 |
+
* Fix error when inputting D'Artagnan in the AUTH pass field of settings.
|
262 |
+
|
263 |
= 4.13.1 =
|
264 |
|
265 |
Release date: 16th April 2019
|
@@ -1 +1 @@
|
|
1 |
-
div.sp-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0
|
1 |
+
div.sp-modal-shade{display:none;position:fixed;z-index:10;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:#000;background-color:rgba(0,0,0,.4)}div.shortpixel-modal{background-color:#fefefe;padding:20px;border:1px solid #888;width:30%;min-width:300px;z-index:100;position:fixed;top:10%;left:50%;max-height:90%;overflow-y:auto}div.shortpixel-modal .sp-close-button,div.shortpixel-modal .sp-close-upgrade-button{float:right;margin-top:0;background:0 0;border:none;font-size:22px;line-height:10px;cursor:pointer}div.shortpixel-modal .sptw-modal-spinner{background-image:url(../img/spinner2.gif);background-repeat:no-repeat;background-position:center}div.sp-modal-title{font-size:22px}div.sp-modal-body{margin-top:20px}
|
@@ -79,6 +79,7 @@ div.fb-like {
|
|
79 |
.wp-core-ui .button.remove-folder-button {
|
80 |
min-width: 120px;
|
81 |
}
|
|
|
82 |
.sp-notice {
|
83 |
background: #fff;
|
84 |
border-left: 4px solid #fff;
|
@@ -605,46 +606,12 @@ article.sp-tabs section .wp-shortpixel-tab-content {
|
|
605 |
visibility: hidden;
|
606 |
}
|
607 |
article.sp-tabs section.sel-tab .wp-shortpixel-tab-content {
|
608 |
-
visibility: visible;
|
609 |
}
|
610 |
article.sp-tabs section:first-child {
|
611 |
z-index: 1;
|
612 |
}
|
613 |
-
|
614 |
-
position: absolute;
|
615 |
-
font-size: 1.3em;
|
616 |
-
font-weight: normal;
|
617 |
-
width: 180px;
|
618 |
-
height: 1.8em;
|
619 |
-
top: -1.8em;
|
620 |
-
left: 10px;
|
621 |
-
padding: 0;
|
622 |
-
margin: 0;
|
623 |
-
color: #999;
|
624 |
-
background-color: #ddd;
|
625 |
-
/* border-radius: 5px 5px 0 0; */
|
626 |
-
}
|
627 |
-
article.sp-tabs section:nth-child(2) h2 {
|
628 |
-
left: 192px;
|
629 |
-
}
|
630 |
-
article.sp-tabs section:nth-child(3) h2 {
|
631 |
-
left: 374px;
|
632 |
-
}
|
633 |
-
article.sp-tabs section:nth-child(4) h2 {
|
634 |
-
left: 556px;
|
635 |
-
}
|
636 |
-
article.sp-tabs section:nth-child(5) h2 {
|
637 |
-
left: 738px;
|
638 |
-
}
|
639 |
-
article.sp-tabs section h2 a {
|
640 |
-
display: block;
|
641 |
-
width: 100%;
|
642 |
-
line-height: 1.8em;
|
643 |
-
text-align: center;
|
644 |
-
text-decoration: none;
|
645 |
-
color: #23282d;
|
646 |
-
outline: 0 none;
|
647 |
-
}
|
648 |
article.sp-tabs section h2 a:focus,
|
649 |
article.sp-tabs section#tab-resources a:focus {
|
650 |
box-shadow: none;
|
79 |
.wp-core-ui .button.remove-folder-button {
|
80 |
min-width: 120px;
|
81 |
}
|
82 |
+
/** In time this is not needed, new notice model **/
|
83 |
.sp-notice {
|
84 |
background: #fff;
|
85 |
border-left: 4px solid #fff;
|
606 |
visibility: hidden;
|
607 |
}
|
608 |
article.sp-tabs section.sel-tab .wp-shortpixel-tab-content {
|
609 |
+
visibility: visible !important;
|
610 |
}
|
611 |
article.sp-tabs section:first-child {
|
612 |
z-index: 1;
|
613 |
}
|
614 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
615 |
article.sp-tabs section h2 a:focus,
|
616 |
article.sp-tabs section#tab-resources a:focus {
|
617 |
box-shadow: none;
|
@@ -1 +1 @@
|
|
1 |
-
.reset{font-weight:normal;font-style:normal}.clearfix:before,.clearfix:after{content:" ";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}.resumeLabel{float:right;line-height:30px;margin-right:20px;font-size:16px}.sp-dropbtn.button{padding:1px 24px 20px 5px;font-size:20px;cursor:pointer}.sp-dropdown{position:relative;display:inline-block}.sp-dropdown-content{display:none;right:0;position:absolute;background-color:#f9f9f9;min-width:190px;box-shadow:0 8px 16px 0 rgba(0,0,0,0.2);z-index:1}.sp-dropdown-content a{color:black;padding:12px 16px;text-decoration:none;display:block}.sp-dropdown-content a:hover{background-color:#f1f1f1}.sp-dropdown.sp-show .sp-dropdown-content{display:block}div.fb-like{transform:scale(1.3);-ms-transform:scale(1.3);-webkit-transform:scale(1.3);-o-transform:scale(1.3);-moz-transform:scale(1.3);transform-origin:bottom left;-ms-transform-origin:bottom left;-webkit-transform-origin:bottom left;-moz-transform-origin:bottom left;-webkit-transform-origin:bottom left}.wp-core-ui .button.button-alert,.wp-core-ui .button.button-alert:hover{background:#f79797}.wp-core-ui .button.remove-folder-button{min-width:120px}.sp-notice{background:#fff;border-left:4px solid #fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:1px 12px}.sp-notice img{vertical-align:bottom}@media(max-width:1249px){.sp-notice{margin:5px 15px 2px}}.sp-notice-info{border-left-color:#00a0d2}.sp-notice-success{border-left-color:#46b450}.sp-notice-warning{border-left-color:#f1e02a}.sp-conflict-plugins{display:table;border-spacing:10px;border-collapse:separate}.sp-conflict-plugins li{display:table-row}.sp-conflict-plugins li>*{display:table-cell}li.sp-conflict-plugins-list{line-height:28px;list-style:disc;margin-left:80px}li.sp-conflict-plugins-list a.button{margin-left:10px}div.short-pixel-bulk-page input.dial{font-size:16px !important}div.short-pixel-bulk-page h1{margin-bottom:20px}div.bulk-progress div.sp-h2{margin-top:0;margin-bottom:10px;font-size:23px;font-weight:400;padding:9px 15px 4px 0;line-height:29px}div.bulk-progress-partners{margin-top:20px}div.bulk-progress.bulk-progress-partners a div{display:inline-block;vertical-align:top;line-height:50px;margin-left:30px;font-size:1.2em}div.bulk-progress .bulk-progress-indicator,div.sp-quota-exceeded-alert .bulk-progress-indicator{display:inline-block;text-align:center;padding:0 10px;margin-left:10px;float:left;height:90px;overflow:hidden;border:1px solid #1caecb}div.wrap.short-pixel-bulk-page .bulk-notice-container{margin-top:15px;position:absolute;width:500px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg{text-align:center;margin:10px 0 0 32px;overflow:hidden;border:1px solid #1caecb;background-color:#9ddbe0;border-radius:5px;padding:7px 10px 10px;display:none;max-width:600px;margin-right:20px}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error{border:1px solid #b5914d;background-color:#ffe996;margin-right:20px;position:relative;z-index:10}div.wrap.short-pixel-bulk-page .bulk-notice-container .bulk-notice-msg.bulk-error.bulk-error-fatal{border:1px solid #c32525;background-color:#ff969d}div.wrap.short-pixel-bulk-page .bulk-notice-msg img{float:left;margin-top:3px;margin-right:5px}div.sp-bulk-summary{float:right;margin:8px 5px 3px 20px}.sp-notice .bulk-error-show{cursor:pointer}.sp-notice div.bulk-error-list{background-color:#f1f1f1;padding:0 10px;display:none;max-height:200px;overflow-y:scroll}.sp-notice div.bulk-error-list ul{padding:3px 0 0;margin-top:5px}.sp-notice div.bulk-error-list ul>li:not(:last-child){border-bottom:1px solid white;padding-bottom:4px}input.dial{box-shadow:none}.shortpixel-table .column-filename{max-width:32em;width:40%}.shortpixel-table .column-folder{max-width:20em;width:20%}.shortpixel-table .column-media_type{max-width:8em;width:10%}.shortpixel-table .column-status{max-width:16em;width:15%}.shortpixel-table .column-options{max-width:16em;width:15%}.form-table th{width:220px}.form-table td{position:relative}.form-table table.shortpixel-folders-list tr{background-color:#eee}.form-table table.shortpixel-folders-list td{padding:5px 10px}div.shortpixel-rate-us{display:inline-block;margin-left:10px;vertical-align:top;font-weight:bold}div.shortpixel-rate-us>a{vertical-align:middle;padding:1px 5px 0;text-align:center;display:inline-block}div.shortpixel-rate-us>a>span{display:inline-block;vertical-align:top;margin-top:5px}div.shortpixel-rate-us>a>img{padding-top:7px}div.shortpixel-rate-us>a:active,div.shortpixel-rate-us>a:hover,div.shortpixel-rate-us>a:focus{outline:0;border-style:none}.sp-loading-small{margin-top:2px;float:left;margin-right:5px}.twentytwenty-horizontal .twentytwenty-before-label:before,.twentytwenty-horizontal .twentytwenty-after-label:before{font-family:inherit;font-size:16px}.short-pixel-bulk-page p{margin:.6em 0}.short-pixel-bulk-page form.start{display:table;content:" ";width:98%;background-color:white;padding:10px 10px 0;position:relative}.bulk-stats-container{display:inline-block;min-width:450px;width:45%;float:left;padding-right:50px;font-size:1.1em;line-height:1.5em}.bulk-text-container{display:inline-block;min-width:440px;width:45%;float:left;padding-right:50px}.bulk-text-container h3{border-bottom:1px solid #a8a8a8;margin-bottom:.5em;padding-bottom:.5em}.bulk-wide{display:inline-block;width:90%;float:left;margin-top:25px}.bulk-stats-container .bulk-label{width:220px;display:inline-block}.bulk-stats-container .bulk-val{width:50px;display:inline-block;text-align:right}.bulk-stats-container .bulk-total{font-weight:bold;margin-top:10px;margin-bottom:10px}.wp-core-ui .bulk-play{display:inline;width:310px;float:left;margin-bottom:20px}.wp-core-ui .bulk-play.bulk-nothing-optimize{font-weight:bold;color:#0080b2;border:1px solid;border-radius:5px;margin-top:60px;padding:5px 12px}.wp-core-ui .bulk-play a.button{height:60px;margin-top:27px;overflow:hidden}.wp-core-ui .column-wp-shortPixel .sp-column-actions{max-width:140px;float:right;text-align:right}.wp-core-ui .column-wp-shortPixel .sp-column-actions .button.button-smaller{margin-right:0}.wp-core-ui .column-wp-shortPixel .button.button-smaller{font-size:13px;padding:0 5px;margin-bottom:4px;height:20px;line-height:16px;float:right}th.sortable.column-wp-shortPixel a,th.sorted.column-wp-shortPixel a{display:inline-block}.column-wp-shortPixel .sorting-indicator{display:inline-block}.wp-core-ui .bulk-play a.button .bulk-btn-img{display:inline-block;padding-top:6px}.wp-core-ui .bulk-play a.button .bulk-btn-txt{display:inline-block;text-align:right;line-height:1.3em;margin:11px 10px}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.label{font-size:1.6em}.wp-core-ui .bulk-play a.button .bulk-btn-txt span.total{font-size:1.4em}.bulk-progress{padding:20px 32px 17px;background-color:#fff}.bulk-progress.bulk-stats>div{display:inline-block}.bulk-progress.bulk-stats>div.label{width:320px}.bulk-progress.bulk-stats>div.stat-value{width:80px;text-align:right}.short-pixel-bulk-page .progress{background-color:#ecedee;height:30px;position:relative;width:60%;display:inline-block;margin-right:28px;overflow:visible}.progress .progress-img{position:absolute;top:-10px;z-index:2;margin-left:-35px;line-height:48px;font-size:22px;font-weight:bold}.progress .progress-img span{vertical-align:top;margin-left:-7px}.progress .progress-left{background-color:#1cbecb;bottom:0;left:0;position:absolute;top:0;z-index:1;font-size:22px;font-weight:bold;line-height:28px;text-align:center;color:#fff}.bulk-estimate{font-size:20px;line-height:30px;vertical-align:top;display:inline-block}.wp-core-ui .button-primary.bulk-cancel{float:right;height:30px}.short-pixel-block-title{font-size:22px;font-weight:bold;text-align:center;margin-bottom:30px}.sp-floating-block.bulk-slider-container{display:none}.sp-floating-block.sp-notice.bulk-notices-parent{padding:0;margin:0;float:right;margin-right:500px !important}.bulk-slider-container{margin-top:20px;min-height:300px;overflow:hidden}.bulk-slider-container h2{margin-bottom:15px}.bulk-slider-container span.filename{font-weight:normal}.bulk-slider{display:table;margin:0 auto}.bulk-slider .bulk-slide{margin:0 auto;padding-left:120px;display:inline-block;font-weight:bold}.bulk-slider .img-original,.bulk-slider .img-optimized{display:inline-block;margin-right:20px;text-align:center}.bulk-slider .img-original div,.bulk-slider .img-optimized div{max-height:450px;overflow:hidden}.bulk-slider .img-original img,.bulk-slider .img-optimized img{max-width:300px}.bulk-slider .img-info{display:inline-block;vertical-align:top;font-size:48px;max-width:150px;padding:10px 0 0 20px}.bulk-slide-images{display:inline-block;border:1px solid #1caecb;padding:15px 0 0 20px}p.settings-info{padding-top:0;color:#818181;font-size:13px !important}p.settings-info.shortpixel-settings-error{color:#c32525}.shortpixel-key-valid{font-weight:bold}.shortpixel-key-valid .dashicons-yes:before{font-size:2em;line-height:25px;color:#3485ba;margin-left:-20px}.shortpixel-compression .shortpixel-compression-options{color:#999}.shortpixel-compression strong{line-height:22px}.shortpixel-compression .shortpixel-compression-options{display:inline-block}.shortpixel-compression label{width:158px;margin:0 -2px;background-color:#e2faff;font-weight:bold;display:inline-block}.shortpixel-compression label span{text-align:center;font-size:18px;padding:8px 0;display:block}.shortpixel-compression label input{display:none}.shortpixel-compression input:checked+span{background-color:#0085ba;color:#f7f7f7}.shortpixel-compression .shortpixel-radio-info{min-height:60px}article.sp-tabs{position:relative;display:block;width:100%;margin:2em auto}article.sp-tabs section{position:absolute;display:block;top:1.8em;left:0;width:100%;max-width:100%;box-sizing:border-box;padding:10px 20px;z-index:0}article.sp-tabs section.sel-tab{box-shadow:0 3px 3px rgba(0,0,0,0.1)}article.sp-tabs section .wp-shortpixel-tab-content{visibility:hidden}article.sp-tabs section.sel-tab .wp-shortpixel-tab-content{visibility:visible}article.sp-tabs section:first-child{z-index:1}article.sp-tabs section h2{position:absolute;font-size:1.3em;font-weight:normal;width:180px;height:1.8em;top:-1.8em;left:10px;padding:0;margin:0;color:#999;background-color:#ddd}article.sp-tabs section:nth-child(2) h2{left:192px}article.sp-tabs section:nth-child(3) h2{left:374px}article.sp-tabs section:nth-child(4) h2{left:556px}article.sp-tabs section:nth-child(5) h2{left:738px}article.sp-tabs section h2 a{display:block;width:100%;line-height:1.8em;text-align:center;text-decoration:none;color:#23282d;outline:0 none}article.sp-tabs section h2 a:focus,article.sp-tabs section#tab-resources a:focus{box-shadow:none;outline:0}article.sp-tabs section.sel-tab,article.sp-tabs section.sel-tab h2{color:#333;background-color:#fff;z-index:2}#tab-stats .sp-bulk-summary{position:absolute;right:0;top:0;z-index:100}.deliverWebpSettings,.deliverWebpTypes,.deliverWebpAlteringTypes{display:none}.deliverWebpTypes .sp-notice{color:red}.deliverWebpSettings{margin:16px 0}.deliverWebpSettings input:disabled+label{color:#818181}.deliverWebpTypes,.deliverWebpAlteringTypes{margin:16px 0 16px 16px}#png2jpg:not(:checked) ~ #png2jpgForce,#png2jpg:not(:checked) ~ label[for=png2jpgForce]{display:none}article.sp-tabs section #createWebp:checked ~ .deliverWebpSettings,article.sp-tabs section #deliverWebp:checked ~ .deliverWebpTypes,article.sp-tabs section #deliverWebpAltered:checked ~ .deliverWebpAlteringTypes{display:block}.shortpixel-help-link span.dashicons{text-decoration:none;margin-top:-1px}@media(min-width:1000px){section#tab-resources .col-md-6{display:inline-block;width:45%}}@media(max-width:999px){section#tab-resources .col-sm-12{display:inline-block;width:100%}}section#tab-resources .text-center{text-align:center}section#tab-resources p{font-size:16px}.wrap.short-pixel-bulk-page{margin-right:0}.sp-container{overflow:hidden;display:block;width:100%}.sp-floating-block{overflow:hidden;display:inline-block;float:left;margin-right:1.1% !important}.sp-full-width{width:98.8%;box-sizing:border-box}.sp-double-width{width:65.52%;box-sizing:border-box}.sp-single-width{width:32.23%;box-sizing:border-box}@media(max-width:1759px){.sp-floating-block{margin-right:1.3% !important}.sp-double-width,.sp-full-width{width:98.65%}.sp-single-width{width:48.7%}}@media(max-width:1249px){.sp-floating-block{margin-right:2% !important}.sp-double-width,.sp-full-width,.sp-single-width{width:97%}}.sp-tabs h2:before{content:none}.sp-column-actions-template+.sp-column-info{display:none}#wpadminbar .shortpixel-toolbar-processing .cssload-container{width:100%;height:24px;text-align:center;position:absolute;top:0;left:-1px}#wpadminbar .shortpixel-toolbar-processing.shortpixel-quota-exceeded .cssload-container,#wpadminbar .shortpixel-toolbar-processing.shortpixel-alert .cssload-container{display:none}#wpadminbar .shortpixel-toolbar-processing .cssload-speeding-wheel{width:24px;height:24px;opacity:.7;margin:0 auto;border:4px solid #1cbfcb;border-radius:50%;border-left-color:transparent;animation:cssload-spin 2000ms infinite linear;-o-animation:cssload-spin 2000ms infinite linear;-ms-animation:cssload-spin 2000ms infinite linear;-webkit-animation:cssload-spin 2000ms infinite linear;-moz-animation:cssload-spin 2000ms infinite linear}@keyframes cssload-spin{100%{transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes cssload-spin{100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes cssload-spin{100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes cssload-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes cssload-spin{100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}
|
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,3 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
.short-pixel-bulk-page.bulk-restore-all ol li {
|
2 |
font-weight: 700; }
|
3 |
.short-pixel-bulk-page.bulk-restore-all section.select_folders {
|
@@ -23,6 +46,9 @@
|
|
23 |
margin: 10px 0;
|
24 |
margin-right: 8px; }
|
25 |
|
|
|
|
|
|
|
26 |
/* Specific styles for advanced settings tab */
|
27 |
#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder {
|
28 |
margin: 10px 0; }
|
@@ -33,3 +59,53 @@
|
|
33 |
max-width: 70%; }
|
34 |
#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder input[name="saveAdv"] {
|
35 |
margin-left: 8px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.shortpixel.notice {
|
2 |
+
min-height: 50px;
|
3 |
+
padding: 8px; }
|
4 |
+
.shortpixel.notice img {
|
5 |
+
display: inline-block;
|
6 |
+
margin: 0 25px 0 0;
|
7 |
+
max-height: 50px; }
|
8 |
+
.shortpixel.notice .notice-dismiss {
|
9 |
+
margin-top: 10px; }
|
10 |
+
|
11 |
+
/* In-view notice ( not on top, between the options ) - styled after WP notice */
|
12 |
+
.view-notice {
|
13 |
+
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
|
14 |
+
border: 4px solid #fff;
|
15 |
+
padding: 1px 12px; }
|
16 |
+
.view-notice p {
|
17 |
+
margin: 1em 0 !important; }
|
18 |
+
.view-notice.warning {
|
19 |
+
border-left-color: #ffb900; }
|
20 |
+
|
21 |
+
.view-notice-row {
|
22 |
+
display: none; }
|
23 |
+
|
24 |
.short-pixel-bulk-page.bulk-restore-all ol li {
|
25 |
font-weight: 700; }
|
26 |
.short-pixel-bulk-page.bulk-restore-all section.select_folders {
|
46 |
margin: 10px 0;
|
47 |
margin-right: 8px; }
|
48 |
|
49 |
+
.short-pixel-bulk-page .sp-hidden {
|
50 |
+
display: none; }
|
51 |
+
|
52 |
/* Specific styles for advanced settings tab */
|
53 |
#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder {
|
54 |
margin: 10px 0; }
|
59 |
max-width: 70%; }
|
60 |
#shortpixel-settings-tabs #tab-adv-settings .addCustomFolder input[name="saveAdv"] {
|
61 |
margin-left: 8px; }
|
62 |
+
|
63 |
+
.settings_page_wp-shortpixel-settings .top-menu {
|
64 |
+
font-size: 18px; }
|
65 |
+
.settings_page_wp-shortpixel-settings .top-menu a {
|
66 |
+
font-size: 18px; }
|
67 |
+
.settings_page_wp-shortpixel-settings .wp-shortpixel-tab-content {
|
68 |
+
transition: all 1000ms linear; }
|
69 |
+
.settings_page_wp-shortpixel-settings article.sp-tabs section .wp-shortpixel-tab-content {
|
70 |
+
opacity: 0; }
|
71 |
+
.settings_page_wp-shortpixel-settings article.sp-tabs section.sel-tab .wp-shortpixel-tab-content {
|
72 |
+
opacity: 1; }
|
73 |
+
.settings_page_wp-shortpixel-settings article.sp-tabs section h2 {
|
74 |
+
position: absolute;
|
75 |
+
font-size: 1.3em;
|
76 |
+
font-weight: normal;
|
77 |
+
width: 180px;
|
78 |
+
height: 1.8em;
|
79 |
+
top: -1.8em;
|
80 |
+
left: 10px;
|
81 |
+
padding: 0;
|
82 |
+
margin: 0;
|
83 |
+
color: #999;
|
84 |
+
background-color: #ddd;
|
85 |
+
/* border-radius: 5px 5px 0 0; */ }
|
86 |
+
.settings_page_wp-shortpixel-settings article.sp-tabs section h2 a {
|
87 |
+
display: block;
|
88 |
+
width: 100%;
|
89 |
+
line-height: 1.8em;
|
90 |
+
text-align: center;
|
91 |
+
text-decoration: none;
|
92 |
+
color: #23282d;
|
93 |
+
outline: 0 none; }
|
94 |
+
.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(2) h2 {
|
95 |
+
left: 192px; }
|
96 |
+
.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(3) h2 {
|
97 |
+
left: 374px; }
|
98 |
+
.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(4) h2 {
|
99 |
+
left: 556px; }
|
100 |
+
.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(5) h2 {
|
101 |
+
left: 738px; }
|
102 |
+
.settings_page_wp-shortpixel-settings article.sp-tabs section:nth-child(6) h2 {
|
103 |
+
left: 920px; }
|
104 |
+
.settings_page_wp-shortpixel-settings section#tab-debug .flex {
|
105 |
+
display: flex; }
|
106 |
+
.settings_page_wp-shortpixel-settings section#tab-debug .env .flex {
|
107 |
+
flex-wrap: wrap;
|
108 |
+
max-width: 450px; }
|
109 |
+
.settings_page_wp-shortpixel-settings section#tab-debug .env .flex span {
|
110 |
+
width: 45%;
|
111 |
+
padding: 4px; }
|
@@ -1 +1 @@
|
|
1 |
-
.short-pixel-bulk-page.bulk-restore-all ol li{font-weight:700}.short-pixel-bulk-page.bulk-restore-all
|
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 +1 @@
|
|
1 |
-
div.sp-folder-picker{margin:20px 0;border:1px solid #888;max-height:400px;min-height:100px;overflow:auto}UL.jqueryFileTree LI.directory.selected{background-color:#209fd2}UL.jqueryFileTree{font-family:Verdana,sans-serif;font-size:11px;line-height:18px;padding:3px;margin:0;display:none;margin-left:20px}.sp-folder-picker>UL.jqueryFileTree{margin:0}UL.jqueryFileTree LI{list-style:none;padding:0;margin:0;white-space:nowrap}UL.jqueryFileTree LI a{padding-left:20px}UL.jqueryFileTree LI.directory a{background:url(../img/file-tree/directory.png) left top no-repeat}UL.jqueryFileTree LI.directory-locked{background:url(../img/file-tree/directory-lock.png) left top no-repeat}UL.jqueryFileTree LI.expanded{background:url(../img/file-tree/folder_open.png) left top no-repeat}UL.jqueryFileTree LI.file{background:url(../img/file-tree/file.png) left top no-repeat}UL.jqueryFileTree LI.file-locked{background:url(../img/file-tree/file-lock.png) left top no-repeat
|
1 |
+
div.sp-folder-picker{margin:20px 0;border:1px solid #888;max-height:400px;min-height:100px;overflow:auto}UL.jqueryFileTree LI.directory.selected{background-color:#209fd2}UL.jqueryFileTree{font-family:Verdana,sans-serif;font-size:11px;line-height:18px;padding:3px;margin:0;display:none;margin-left:20px}.sp-folder-picker>UL.jqueryFileTree{margin:0}UL.jqueryFileTree LI{list-style:none;padding:0;margin:0;white-space:nowrap}UL.jqueryFileTree LI a{padding-left:20px}UL.jqueryFileTree LI.directory a{background:url(../img/file-tree/directory.png) left top no-repeat}UL.jqueryFileTree LI.directory-locked{background:url(../img/file-tree/directory-lock.png) left top no-repeat}UL.jqueryFileTree LI.expanded{background:url(../img/file-tree/folder_open.png) left top no-repeat}UL.jqueryFileTree LI.file{background:url(../img/file-tree/file.png) left top no-repeat}UL.jqueryFileTree LI.file-locked{background:url(../img/file-tree/file-lock.png) left top no-repeat!important}UL.jqueryFileTree LI.wait{background:url(../img/file-tree/spinner.gif) left top no-repeat}UL.jqueryFileTree LI.selected>a{font-weight:700}UL.jqueryFileTree LI.ext_3gp{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_afp{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_afpa{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_asp{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_aspx{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_avi{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_bat{background:url(../img/file-tree/application.png) left top no-repeat}UL.jqueryFileTree LI.ext_bmp{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_c{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_cfm{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_cgi{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_com{background:url(../img/file-tree/application.png) left top no-repeat}UL.jqueryFileTree LI.ext_cpp{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_css{background:url(../img/file-tree/css.png) left top no-repeat}UL.jqueryFileTree LI.ext_doc{background:url(../img/file-tree/doc.png) left top no-repeat}UL.jqueryFileTree LI.ext_exe{background:url(../img/file-tree/application.png) left top no-repeat}UL.jqueryFileTree LI.ext_gif{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_fla{background:url(../img/file-tree/flash.png) left top no-repeat}UL.jqueryFileTree LI.ext_h{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_htm{background:url(../img/file-tree/html.png) left top no-repeat}UL.jqueryFileTree LI.ext_html{background:url(../img/file-tree/html.png) left top no-repeat}UL.jqueryFileTree LI.ext_jar{background:url(../img/file-tree/java.png) left top no-repeat}UL.jqueryFileTree LI.ext_jpg{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_jpeg{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_js{background:url(../img/file-tree/script.png) left top no-repeat}UL.jqueryFileTree LI.ext_lasso{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_log{background:url(../img/file-tree/txt.png) left top no-repeat}UL.jqueryFileTree LI.ext_m4p{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_mov{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_mp3{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_mp4{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_mpg{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_mpeg{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_ogg{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_ogv{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_pcx{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_pdf{background:url(../img/file-tree/pdf.png) left top no-repeat}UL.jqueryFileTree LI.ext_php{background:url(../img/file-tree/php.png) left top no-repeat}UL.jqueryFileTree LI.ext_png{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_ppt{background:url(../img/file-tree/ppt.png) left top no-repeat}UL.jqueryFileTree LI.ext_psd{background:url(../img/file-tree/psd.png) left top no-repeat}UL.jqueryFileTree LI.ext_pl{background:url(../img/file-tree/script.png) left top no-repeat}UL.jqueryFileTree LI.ext_py{background:url(../img/file-tree/script.png) left top no-repeat}UL.jqueryFileTree LI.ext_rb{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_rbx{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_rhtml{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_rpm{background:url(../img/file-tree/linux.png) left top no-repeat}UL.jqueryFileTree LI.ext_ruby{background:url(../img/file-tree/ruby.png) left top no-repeat}UL.jqueryFileTree LI.ext_sql{background:url(../img/file-tree/db.png) left top no-repeat}UL.jqueryFileTree LI.ext_swf{background:url(../img/file-tree/flash.png) left top no-repeat}UL.jqueryFileTree LI.ext_tif{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_tiff{background:url(../img/file-tree/picture.png) left top no-repeat}UL.jqueryFileTree LI.ext_txt{background:url(../img/file-tree/txt.png) left top no-repeat}UL.jqueryFileTree LI.ext_vb{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_wav{background:url(../img/file-tree/music.png) left top no-repeat}UL.jqueryFileTree LI.ext_webm{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_wmv{background:url(../img/file-tree/film.png) left top no-repeat}UL.jqueryFileTree LI.ext_xls{background:url(../img/file-tree/xls.png) left top no-repeat}UL.jqueryFileTree LI.ext_xml{background:url(../img/file-tree/code.png) left top no-repeat}UL.jqueryFileTree LI.ext_zip{background:url(../img/file-tree/zip.png) left top no-repeat}UL.jqueryFileTree A{color:#333;text-decoration:none;display:inline-block;padding:0 2px;cursor:pointer}UL.jqueryFileTree A:hover{background:#bdf}
|
Binary file
|
Binary file
|
@@ -2,6 +2,7 @@
|
|
2 |
* Short Pixel WordPress Plugin javascript
|
3 |
*/
|
4 |
|
|
|
5 |
jQuery(document).ready(function(){ShortPixel.init();});
|
6 |
|
7 |
var ShortPixel = function() {
|
@@ -62,9 +63,11 @@ var ShortPixel = function() {
|
|
62 |
jQuery('#request_key').attr('href', jQuery('#request_key').attr('href').split('?')[0] + '?pluginemail=' + email);
|
63 |
}
|
64 |
|
65 |
-
function validateKey(){
|
|
|
66 |
jQuery('#valid').val('validate');
|
67 |
-
|
|
|
68 |
}
|
69 |
|
70 |
jQuery("#key").keypress(function(e) {
|
@@ -81,30 +84,52 @@ var ShortPixel = function() {
|
|
81 |
}
|
82 |
}
|
83 |
|
84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
for(var i = 0, prev = null; i < rad.length; i++) {
|
86 |
rad[i].onclick = function() {
|
87 |
|
88 |
if(this !== prev) {
|
89 |
prev = this;
|
90 |
}
|
|
|
91 |
if(typeof ShortPixel.setupGeneralTabAlert !== 'undefined') return;
|
92 |
alert(_spTr.alertOnlyAppliesToNewImages);
|
93 |
ShortPixel.setupGeneralTabAlert = 1;
|
94 |
};
|
95 |
}
|
|
|
96 |
ShortPixel.enableResize("#resize");
|
|
|
97 |
jQuery("#resize").change(function(){ enableResize(this); });
|
98 |
jQuery(".resize-sizes").blur(function(e){
|
99 |
-
var elm = jQuery(
|
100 |
-
|
|
|
|
|
|
|
101 |
ShortPixel.resizeSizesAlert = elm.val();
|
102 |
var minSize = jQuery("#min-" + elm.attr('name')).val();
|
103 |
-
|
|
|
104 |
if(minSize > 1024) {
|
105 |
-
alert( _spTr.pleaseDoNotSetLesser1024.format(
|
106 |
} else {
|
107 |
-
alert( _spTr.pleaseDoNotSetLesserSize.format(
|
108 |
}
|
109 |
e.preventDefault();
|
110 |
//elm.val(this.defaultValue);
|
@@ -130,6 +155,13 @@ var ShortPixel = function() {
|
|
130 |
}
|
131 |
return true;
|
132 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
134 |
|
135 |
function apiKeyChanged() {
|
@@ -164,17 +196,18 @@ var ShortPixel = function() {
|
|
164 |
|
165 |
function initSettings() {
|
166 |
ShortPixel.adjustSettingsTabs();
|
|
|
167 |
jQuery( window ).resize(function() {
|
168 |
ShortPixel.adjustSettingsTabs();
|
169 |
});
|
170 |
-
if(window.location.hash) {
|
171 |
var target = ('tab-' + window.location.hash.substring(window.location.hash.indexOf("#")+1)).replace(/\//, '');
|
172 |
if(jQuery("section#" + target).length) {
|
173 |
ShortPixel.switchSettingsTab( target );
|
174 |
}
|
175 |
-
}
|
176 |
-
jQuery("article.sp-tabs a.tab-link").click(function(){
|
177 |
-
var theID = jQuery(
|
178 |
ShortPixel.switchSettingsTab( theID );
|
179 |
});
|
180 |
|
@@ -194,20 +227,33 @@ var ShortPixel = function() {
|
|
194 |
});
|
195 |
}
|
196 |
|
|
|
197 |
function switchSettingsTab(target){
|
|
|
198 |
var tab = target.replace("tab-",""),
|
199 |
beacon = "",
|
200 |
-
section = jQuery("section#" +target)
|
201 |
-
|
202 |
-
if(history.pushState) {
|
203 |
history.pushState(null, null, url);
|
204 |
}
|
205 |
else {
|
206 |
location.hash = url;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
}
|
|
|
208 |
if(section.length > 0){
|
209 |
jQuery("section").removeClass("sel-tab");
|
210 |
-
jQuery(
|
|
|
|
|
|
|
211 |
}
|
212 |
if(typeof HS.beacon.suggest !== 'undefined' ){
|
213 |
switch(tab){
|
@@ -228,11 +274,12 @@ var ShortPixel = function() {
|
|
228 |
}
|
229 |
}
|
230 |
|
|
|
231 |
function adjustSettingsTabsHeight(){
|
232 |
-
var sectionHeight = jQuery('section
|
233 |
-
sectionHeight = Math.max(sectionHeight, jQuery('section#tab-adv-settings .wp-shortpixel-options').height() + 20);
|
234 |
-
|
235 |
-
jQuery('
|
236 |
//jQuery('#shortpixel-settings-tabs section').css('height', sectionHeight);
|
237 |
}
|
238 |
|
@@ -242,7 +289,7 @@ var ShortPixel = function() {
|
|
242 |
data = JSON.parse(response);
|
243 |
if(data["Status"] == 'success') {
|
244 |
jQuery("#short-pixel-media-alert").hide();
|
245 |
-
console.log("dismissed");
|
246 |
}
|
247 |
});
|
248 |
}
|
@@ -504,7 +551,7 @@ var ShortPixel = function() {
|
|
504 |
jQuery("#addCustomFolderView").val(fullPath);
|
505 |
jQuery(".sp-folder-picker-shade").fadeOut(100);
|
506 |
jQuery(".shortpixel-modal.modal-folder-picker").css("display", "none");
|
507 |
-
jQuery('
|
508 |
} else {
|
509 |
alert("Please select a folder from the list.");
|
510 |
}
|
@@ -773,6 +820,7 @@ var ShortPixel = function() {
|
|
773 |
displayComparerPopup: displayComparerPopup,
|
774 |
closeComparerPopup : closeComparerPopup,
|
775 |
convertPunycode : convertPunycode,
|
|
|
776 |
comparerData : {
|
777 |
cssLoaded : false,
|
778 |
jsLoaded : false,
|
@@ -797,7 +845,7 @@ function showToolBarAlert($status, $message, id) {
|
|
797 |
}
|
798 |
robo.addClass("shortpixel-alert");
|
799 |
robo.addClass("shortpixel-quota-exceeded");
|
800 |
-
jQuery("a", robo).attr("href", "options-general.php?page=wp-shortpixel");
|
801 |
//jQuery("a", robo).attr("target", "_blank");
|
802 |
//jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click to top-up");
|
803 |
jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click for details.");
|
@@ -813,7 +861,7 @@ function showToolBarAlert($status, $message, id) {
|
|
813 |
case ShortPixel.STATUS_NO_KEY:
|
814 |
robo.addClass("shortpixel-alert");
|
815 |
robo.addClass("shortpixel-quota-exceeded");
|
816 |
-
jQuery("a", robo).attr("href", "options-general.php?page=wp-shortpixel");//"http://shortpixel.com/wp-apikey");
|
817 |
//jQuery("a", robo).attr("target", "_blank");
|
818 |
jQuery("a div", robo).attr("title", "Get API Key");
|
819 |
break;
|
@@ -863,7 +911,6 @@ function checkBulkProgress() {
|
|
863 |
|
864 |
first = false; //rearm replacer
|
865 |
var adminUrl = ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g , replacer);
|
866 |
-
|
867 |
//handle possible Punycode domain names.
|
868 |
if(url.search(adminUrl) < 0) {
|
869 |
url = ShortPixel.convertPunycode(url);
|
2 |
* Short Pixel WordPress Plugin javascript
|
3 |
*/
|
4 |
|
5 |
+
// init checks bulkProcess on each page. initSettings is when the settings View is being loaded.
|
6 |
jQuery(document).ready(function(){ShortPixel.init();});
|
7 |
|
8 |
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) {
|
84 |
}
|
85 |
}
|
86 |
|
87 |
+
|
88 |
+
function checkExifWarning()
|
89 |
+
{
|
90 |
+
if (! jQuery('input[name="removeExif"]').is(':checked') && jQuery('input[name="png2jpg"]').is(':checked') )
|
91 |
+
{
|
92 |
+
jQuery('.exif_warning').fadeIn();
|
93 |
+
}
|
94 |
+
else {
|
95 |
+
jQuery('.exif_warning').fadeOut();
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
function setupGeneralTab() {
|
100 |
+
var rad = 0;
|
101 |
+
if (typeof document.wp_shortpixel_options !== 'undefined')
|
102 |
+
rad = document.wp_shortpixel_options.compressionType;
|
103 |
for(var i = 0, prev = null; i < rad.length; i++) {
|
104 |
rad[i].onclick = function() {
|
105 |
|
106 |
if(this !== prev) {
|
107 |
prev = this;
|
108 |
}
|
109 |
+
// Warns once that changing compressType is only for new images.
|
110 |
if(typeof ShortPixel.setupGeneralTabAlert !== 'undefined') return;
|
111 |
alert(_spTr.alertOnlyAppliesToNewImages);
|
112 |
ShortPixel.setupGeneralTabAlert = 1;
|
113 |
};
|
114 |
}
|
115 |
+
|
116 |
ShortPixel.enableResize("#resize");
|
117 |
+
|
118 |
jQuery("#resize").change(function(){ enableResize(this); });
|
119 |
jQuery(".resize-sizes").blur(function(e){
|
120 |
+
var elm = jQuery(e.target);
|
121 |
+
|
122 |
+
if(ShortPixel.resizeSizesAlert == elm.val())
|
123 |
+
return; // returns if check in progress, presumed.
|
124 |
+
|
125 |
ShortPixel.resizeSizesAlert = elm.val();
|
126 |
var minSize = jQuery("#min-" + elm.attr('name')).val();
|
127 |
+
var niceName = jQuery("#min-" + elm.attr('name')).data('nicename');
|
128 |
+
if(elm.val() < Math.min(minSize, 1024)) { // @todo is this correct? This will always be < 1024, and give first error
|
129 |
if(minSize > 1024) {
|
130 |
+
alert( _spTr.pleaseDoNotSetLesser1024.format(niceName) );
|
131 |
} else {
|
132 |
+
alert( _spTr.pleaseDoNotSetLesserSize.format(niceName, niceName, minSize) );
|
133 |
}
|
134 |
e.preventDefault();
|
135 |
//elm.val(this.defaultValue);
|
155 |
}
|
156 |
return true;
|
157 |
});
|
158 |
+
|
159 |
+
jQuery('input[name="removeExif"], input[name="png2jpg"]').on('change', function()
|
160 |
+
{
|
161 |
+
ShortPixel.checkExifWarning();
|
162 |
+
});
|
163 |
+
ShortPixel.checkExifWarning();
|
164 |
+
|
165 |
}
|
166 |
|
167 |
function apiKeyChanged() {
|
196 |
|
197 |
function initSettings() {
|
198 |
ShortPixel.adjustSettingsTabs();
|
199 |
+
ShortPixel.setupGeneralTab(); // certain alerts.
|
200 |
jQuery( window ).resize(function() {
|
201 |
ShortPixel.adjustSettingsTabs();
|
202 |
});
|
203 |
+
/*if(window.location.hash) {
|
204 |
var target = ('tab-' + window.location.hash.substring(window.location.hash.indexOf("#")+1)).replace(/\//, '');
|
205 |
if(jQuery("section#" + target).length) {
|
206 |
ShortPixel.switchSettingsTab( target );
|
207 |
}
|
208 |
+
} */
|
209 |
+
jQuery("article.sp-tabs a.tab-link").click(function(e){
|
210 |
+
var theID = jQuery(e.target).data("id");
|
211 |
ShortPixel.switchSettingsTab( theID );
|
212 |
});
|
213 |
|
227 |
});
|
228 |
}
|
229 |
|
230 |
+
// Switch between settings tabs.
|
231 |
function switchSettingsTab(target){
|
232 |
+
|
233 |
var tab = target.replace("tab-",""),
|
234 |
beacon = "",
|
235 |
+
section = jQuery("section#" +target);
|
236 |
+
// url = location.href.replace(location.hash,"") + '#' + tab;
|
237 |
+
/*if(history.pushState) {
|
238 |
history.pushState(null, null, url);
|
239 |
}
|
240 |
else {
|
241 |
location.hash = url;
|
242 |
+
} */
|
243 |
+
jQuery('input[name="display_part"]').val(tab);
|
244 |
+
var uri = window.location.href.toString();
|
245 |
+
if (uri.indexOf("?") > 0) {
|
246 |
+
var clean_uri = uri.substring(0, uri.indexOf("?"));
|
247 |
+
clean_uri += '?' + jQuery.param({'page':'wp-shortpixel-settings', 'part': tab});
|
248 |
+
window.history.replaceState({}, document.title, clean_uri);
|
249 |
}
|
250 |
+
|
251 |
if(section.length > 0){
|
252 |
jQuery("section").removeClass("sel-tab");
|
253 |
+
jQuery('section .wp-shortpixel-tab-content').fadeOut(50);
|
254 |
+
jQuery(section).addClass("sel-tab");
|
255 |
+
ShortPixel.adjustSettingsTabs();
|
256 |
+
jQuery(section).find('.wp-shortpixel-tab-content').fadeIn(50);
|
257 |
}
|
258 |
if(typeof HS.beacon.suggest !== 'undefined' ){
|
259 |
switch(tab){
|
274 |
}
|
275 |
}
|
276 |
|
277 |
+
// Fixes the height of the current active tab.
|
278 |
function adjustSettingsTabsHeight(){
|
279 |
+
var sectionHeight = jQuery('section.sel-tab').height() + 90;
|
280 |
+
//sectionHeight = Math.max(sectionHeight, jQuery('section#tab-adv-settings .wp-shortpixel-options').height() + 20);
|
281 |
+
// sectionHeight = Math.max(sectionHeight, jQuery('section#tab-resources .area1').height() + 60);
|
282 |
+
jQuery('.section-wrapper').css('height', sectionHeight);
|
283 |
//jQuery('#shortpixel-settings-tabs section').css('height', sectionHeight);
|
284 |
}
|
285 |
|
289 |
data = JSON.parse(response);
|
290 |
if(data["Status"] == 'success') {
|
291 |
jQuery("#short-pixel-media-alert").hide();
|
292 |
+
//console.log("dismissed");
|
293 |
}
|
294 |
});
|
295 |
}
|
551 |
jQuery("#addCustomFolderView").val(fullPath);
|
552 |
jQuery(".sp-folder-picker-shade").fadeOut(100);
|
553 |
jQuery(".shortpixel-modal.modal-folder-picker").css("display", "none");
|
554 |
+
jQuery('#saveAdvAddFolder').removeClass('hidden');
|
555 |
} else {
|
556 |
alert("Please select a folder from the list.");
|
557 |
}
|
820 |
displayComparerPopup: displayComparerPopup,
|
821 |
closeComparerPopup : closeComparerPopup,
|
822 |
convertPunycode : convertPunycode,
|
823 |
+
checkExifWarning : checkExifWarning,
|
824 |
comparerData : {
|
825 |
cssLoaded : false,
|
826 |
jsLoaded : false,
|
845 |
}
|
846 |
robo.addClass("shortpixel-alert");
|
847 |
robo.addClass("shortpixel-quota-exceeded");
|
848 |
+
jQuery("a", robo).attr("href", "options-general.php?page=wp-shortpixel-settings");
|
849 |
//jQuery("a", robo).attr("target", "_blank");
|
850 |
//jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click to top-up");
|
851 |
jQuery("a div", robo).attr("title", "ShortPixel quota exceeded. Click for details.");
|
861 |
case ShortPixel.STATUS_NO_KEY:
|
862 |
robo.addClass("shortpixel-alert");
|
863 |
robo.addClass("shortpixel-quota-exceeded");
|
864 |
+
jQuery("a", robo).attr("href", "options-general.php?page=wp-shortpixel-settings");//"http://shortpixel.com/wp-apikey");
|
865 |
//jQuery("a", robo).attr("target", "_blank");
|
866 |
jQuery("a div", robo).attr("title", "Get API Key");
|
867 |
break;
|
911 |
|
912 |
first = false; //rearm replacer
|
913 |
var adminUrl = ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g , replacer);
|
|
|
914 |
//handle possible Punycode domain names.
|
915 |
if(url.search(adminUrl) < 0) {
|
916 |
url = ShortPixel.convertPunycode(url);
|
@@ -1 +1 @@
|
|
1 |
-
jQuery(document).ready(function(){ShortPixel.init()});var ShortPixel=function(){function J(){if(typeof ShortPixel.API_KEY!=="undefined"){return}if(jQuery("table.wp-list-table.media").length>0){jQuery('select[name^="action"] option:last-child').before('<option value="short-pixel-bulk">'+_spTr.optimizeWithSP+'</option><option value="short-pixel-bulk-lossy"> → '+_spTr.redoLossy+'</option><option value="short-pixel-bulk-glossy"> → '+_spTr.redoGlossy+'</option><option value="short-pixel-bulk-lossless"> → '+_spTr.redoLossless+'</option><option value="short-pixel-bulk-restore"> → '+_spTr.restoreOriginal+"</option>")}ShortPixel.setOptions(ShortPixelConstants[0]);if(jQuery("#backup-folder-size").length){jQuery("#backup-folder-size").html(ShortPixel.getBackupSize())}if(ShortPixel.MEDIA_ALERT=="todo"&&jQuery("div.media-frame.mode-grid").length>0){jQuery("div.media-frame.mode-grid").before('<div id="short-pixel-media-alert" class="notice notice-warning"><p>'+_spTr.changeMLToListMode.format('<a href="upload.php?mode=list" class="view-list"><span class="screen-reader-text">'," </span>",'</a><a class="alignright" href="javascript:ShortPixel.dismissMediaAlert();">',"</a>")+"</p></div>")}jQuery(window).on("beforeunload",function(){if(ShortPixel.bulkProcessor==true){clearBulkProcessor()}});checkQuotaExceededAlert();checkBulkProgress()}function m(R){for(var S in R){ShortPixel[S]=R[S]}}function t(R){return/^\w+([\.+-]?\w+)*@\w+([\.-]?\w+)*(\.\w{1,63})+$/.test(R)}function n(){var R=jQuery("#pluginemail").val();if(ShortPixel.isEmailValid(R)){jQuery("#request_key").removeClass("disabled")}jQuery("#request_key").attr("href",jQuery("#request_key").attr("href").split("?")[0]+"?pluginemail="+R)}function a(){jQuery("#valid").val("validate");jQuery("#wp_shortpixel_options").submit()}jQuery("#key").keypress(function(R){if(R.which==13){jQuery("#valid").val("validate")}});function M(R){if(jQuery(R).is(":checked")){jQuery("#width,#height").removeAttr("disabled")}else{jQuery("#width,#height").attr("disabled","disabled")}}function e(R,T,V){for(var S=0,U=null;S<R.length;S++){R[S].onclick=function(){if(this!==U){U=this}if(typeof ShortPixel.setupGeneralTabAlert!=="undefined"){return}alert(_spTr.alertOnlyAppliesToNewImages);ShortPixel.setupGeneralTabAlert=1}}ShortPixel.enableResize("#resize");jQuery("#resize").change(function(){M(this)});jQuery(".resize-sizes").blur(function(X){var Y=jQuery(this);if(ShortPixel.resizeSizesAlert==Y.val()){return}ShortPixel.resizeSizesAlert=Y.val();var W=jQuery("#min-"+Y.attr("name")).val();if(Y.val()<Math.min(W,1024)){if(W>1024){alert(_spTr.pleaseDoNotSetLesser1024.format(Y.attr("name")))}else{alert(_spTr.pleaseDoNotSetLesserSize.format(Y.attr("name"),Y.attr("name"),W))}X.preventDefault();Y.focus()}else{this.defaultValue=Y.val()}});jQuery(".shortpixel-confirm").click(function(X){var W=confirm(X.target.getAttribute("data-confirm"));if(!W){X.preventDefault();return false}return true})}function D(){jQuery(".wp-shortpixel-options .shortpixel-key-valid").css("display","none");jQuery(".wp-shortpixel-options button#validate").css("display","inline-block")}function u(){jQuery("input.remove-folder-button").click(function(){var S=jQuery(this).data("value");var R=confirm(_spTr.areYouSureStopOptimizing.format(S));if(R==true){jQuery("#removeFolder").val(S);jQuery("#wp_shortpixel_options").submit()}});jQuery("input.recheck-folder-button").click(function(){var S=jQuery(this).data("value");var R=confirm(_spTr.areYouSureStopOptimizing.format(S));if(R==true){jQuery("#recheckFolder").val(S);jQuery("#wp_shortpixel_options").submit()}})}function L(R){var S=jQuery("#"+(R.checked?"total":"main")+"ToProcess").val();jQuery("div.bulk-play span.total").text(S);jQuery("#displayTotal").text(S)}function g(){ShortPixel.adjustSettingsTabs();jQuery(window).resize(function(){ShortPixel.adjustSettingsTabs()});if(window.location.hash){var R=("tab-"+window.location.hash.substring(window.location.hash.indexOf("#")+1)).replace(/\//,"");if(jQuery("section#"+R).length){ShortPixel.switchSettingsTab(R)}}jQuery("article.sp-tabs a.tab-link").click(function(){var S=jQuery(this).data("id");ShortPixel.switchSettingsTab(S)});jQuery("input[type=radio][name=deliverWebpType]").change(function(){if(this.value=="deliverWebpAltered"){if(window.confirm(_spTr.alertDeliverWebPAltered)){var S=jQuery("input[type=radio][name=deliverWebpAlteringType]:checked").length;if(S==0){jQuery("#deliverWebpAlteredWP").prop("checked",true)}}else{jQuery(this).prop("checked",false)}}else{if(this.value=="deliverWebpUnaltered"){window.alert(_spTr.alertDeliverWebPUnaltered)}}})}function y(V){var T=V.replace("tab-",""),R="",U=jQuery("section#"+V),S=location.href.replace(location.hash,"")+"#"+T;if(history.pushState){history.pushState(null,null,S)}else{location.hash=S}if(U.length>0){jQuery("section").removeClass("sel-tab");jQuery("section#"+V).addClass("sel-tab")}if(typeof HS.beacon.suggest!=="undefined"){switch(T){case"settings":R=shortpixel_suggestions_settings;break;case"adv-settings":R=shortpixel_suggestions_adv_settings;break;case"cloudflare":case"stats":R=shortpixel_suggestions_cloudflare;break;default:break}HS.beacon.suggest(R)}}function z(){var R=jQuery("section#tab-settings .wp-shortpixel-options").height()+90;R=Math.max(R,jQuery("section#tab-adv-settings .wp-shortpixel-options").height()+20);R=Math.max(R,jQuery("section#tab-resources .area1").height()+60);jQuery("#shortpixel-settings-tabs").css("height",R)}function N(){var R={action:"shortpixel_dismiss_media_alert"};jQuery.get(ShortPixel.AJAX_URL,R,function(S){R=JSON.parse(S);if(R.Status=="success"){jQuery("#short-pixel-media-alert").hide();console.log("dismissed")}})}function k(){var R={action:"shortpixel_check_quota"};jQuery.get(ShortPixel.AJAX_URL,R,function(){console.log("quota refreshed")})}function C(R){if(R.checked){jQuery("#with-thumbs").css("display","inherit");jQuery("#without-thumbs").css("display","none")}else{jQuery("#without-thumbs").css("display","inherit");jQuery("#with-thumbs").css("display","none")}}function b(V,T,S,U,R){return(T>0?"<div class='sp-column-info'>"+_spTr.reducedBy+" <strong><span class='percent'>"+T+"%</span></strong> ":"")+(T>0&&T<5?"<br>":"")+(T<5?_spTr.bonusProcessing:"")+(S.length>0?" ("+S+")":"")+(0+U>0?"<br>"+_spTr.plusXthumbsOpt.format(U):"")+(0+R>0?"<br>"+_spTr.plusXretinasOpt.format(R):"")+"</div>"}function p(S,R){jQuery(S).knob({readOnly:true,width:R,height:R,fgColor:"#1CAECB",format:function(T){return T+"%"}})}function c(Y,T,W,V,S,X){if(S==1){var U=jQuery(".sp-column-actions-template").clone();if(!U.length){return false}var R;if(T.length==0){R=["lossy","lossless"]}else{R=["lossy","glossy","lossless"].filter(function(Z){return !(Z==T)})}U.html(U.html().replace(/__SP_ID__/g,Y));if(X.substr(X.lastIndexOf(".")+1).toLowerCase()=="pdf"){jQuery(".sp-action-compare",U).remove()}if(W==0&&V>0){U.html(U.html().replace("__SP_THUMBS_TOTAL__",V))}else{jQuery(".sp-action-optimize-thumbs",U).remove();jQuery(".sp-dropbtn",U).removeClass("button-primary")}U.html(U.html().replace(/__SP_FIRST_TYPE__/g,R[0]));U.html(U.html().replace(/__SP_SECOND_TYPE__/g,R[1]));return U.html()}return""}function i(V,U){V=V.substring(2);if(jQuery(".shortpixel-other-media").length){var T=["optimize","retry","restore","redo","quota","view"];for(var S=0,R=T.length;S<R;S++){jQuery("#"+T[S]+"_"+V).css("display","none")}for(var S=0,R=U.length;S<R;S++){jQuery("#"+U[S]+"_"+V).css("display","")}}}function j(R){ShortPixel.retries++;if(isNaN(ShortPixel.retries)){ShortPixel.retries=1}if(ShortPixel.retries<6){console.log("Invalid response from server (Error: "+R+"). Retrying pass "+(ShortPixel.retries+1)+"...");setTimeout(checkBulkProgress,5000)}else{ShortPixel.bulkShowError(-1,"Invalid response from server received 6 times. Please retry later by reloading this page, or <a href='https://shortpixel.com/contact' target='_blank'>contact support</a>. (Error: "+R+")","");console.log("Invalid response from server 6 times. Giving up.")}}function l(R){R.action="shortpixel_browse_content";var S="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:R,success:function(T){S=T},async:false});return S}function d(){var R={action:"shortpixel_get_backup_size"};var S="";jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:R,success:function(T){S=T},async:false});return S}function f(S){if(!jQuery("#tos").is(":checked")){S.preventDefault();jQuery("#tos-robo").fadeIn(400,function(){jQuery("#tos-hand").fadeIn()});jQuery("#tos").click(function(){jQuery("#tos-robo").css("display","none");jQuery("#tos-hand").css("display","none")});return}jQuery("#request_key").addClass("disabled");jQuery("#pluginemail_spinner").addClass("is-active");ShortPixel.updateSignupEmail();if(ShortPixel.isEmailValid(jQuery("#pluginemail").val())){jQuery("#pluginemail-error").css("display","none");var R={action:"shortpixel_new_api_key",email:jQuery("#pluginemail").val()};jQuery.ajax({type:"POST",async:false,url:ShortPixel.AJAX_URL,data:R,success:function(T){data=JSON.parse(T);if(data.Status=="success"){S.preventDefault();window.location.reload()}else{if(data.Status=="invalid"){jQuery("#pluginemail-error").html("<b>"+data.Details+"</b>");jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");S.preventDefault()}else{}}}});jQuery("#request_key").removeAttr("onclick")}else{jQuery("#pluginemail-error").css("display","");jQuery("#pluginemail-info").css("display","none");S.preventDefault()}jQuery("#request_key").removeClass("disabled");jQuery("#pluginemail_spinner").removeClass("is-active")}function O(){jQuery("#shortPixelProposeUpgrade .sp-modal-body").addClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html("");jQuery("#shortPixelProposeUpgradeShade").css("display","block");jQuery("#shortPixelProposeUpgrade").removeClass("shortpixel-hide");var R={action:"shortpixel_propose_upgrade"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:R,success:function(S){jQuery("#shortPixelProposeUpgrade .sp-modal-body").removeClass("sptw-modal-spinner");jQuery("#shortPixelProposeUpgrade .sp-modal-body").html(S)}})}function H(){jQuery("#shortPixelProposeUpgradeShade").css("display","none");jQuery("#shortPixelProposeUpgrade").addClass("shortpixel-hide");if(ShortPixel.toRefresh){ShortPixel.recheckQuota()}}function v(){jQuery("#short-pixel-notice-unlisted").hide();jQuery("#optimizeUnlisted").prop("checked",true);var R={action:"shortpixel_dismiss_notice",notice_id:"unlisted",notice_data:"true"};jQuery.get(ShortPixel.AJAX_URL,R,function(S){R=JSON.parse(S);if(R.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function o(){jQuery(".select-folder-button").click(function(){jQuery(".sp-folder-picker-shade").fadeIn(100);jQuery(".shortpixel-modal.modal-folder-picker").show();var R=jQuery(".sp-folder-picker");R.parent().css("margin-left",-R.width()/2);R.fileTree({script:ShortPixel.browseContent,multiFolder:false})});jQuery(".shortpixel-modal input.select-folder-cancel, .sp-folder-picker-shade").click(function(){jQuery(".sp-folder-picker-shade").fadeOut(100);jQuery(".shortpixel-modal.modal-folder-picker").hide()});jQuery(".shortpixel-modal input.select-folder").click(function(U){var T=jQuery("UL.jqueryFileTree LI.directory.selected");if(jQuery(T).length==0){var T=jQuery("UL.jqueryFileTree LI.selected").parents(".directory")}var R=jQuery(T).children("a").attr("rel");if(typeof R==="undefined"){return}R=R.trim();if(R){var S=jQuery("#customFolderBase").val()+R;if(S.slice(-1)=="/"){S=S.slice(0,-1)}jQuery("#addCustomFolder").val(S);jQuery("#addCustomFolderView").val(S);jQuery(".sp-folder-picker-shade").fadeOut(100);jQuery(".shortpixel-modal.modal-folder-picker").css("display","none");jQuery('input[name="saveAdv"]').removeClass("hidden")}else{alert("Please select a folder from the list.")}})}function G(V,U,T){var S=jQuery(".bulk-notice-msg.bulk-lengthy");if(S.length==0){return}var R=jQuery("a",S);R.text(U);if(T){R.attr("href",T)}else{R.attr("href",R.data("href").replace("__ID__",V))}S.css("display","block")}function B(){jQuery(".bulk-notice-msg.bulk-lengthy").css("display","none")}function w(R){var S=jQuery(".bulk-notice-msg.bulk-"+R);if(S.length==0){return}S.css("display","block")}function P(R){jQuery(".bulk-notice-msg.bulk-"+R).css("display","none")}function s(X,V,W,U){var R=jQuery("#bulk-error-template");if(R.length==0){return}var T=R.clone();T.attr("id","bulk-error-"+X);if(X==-1){jQuery("span.sp-err-title",T).remove();T.addClass("bulk-error-fatal")}else{jQuery("img",T).remove();jQuery("#bulk-error-".id).remove()}jQuery("span.sp-err-content",T).html(V);var S=jQuery("a.sp-post-link",T);if(U){S.attr("href",U)}else{S.attr("href",S.attr("href").replace("__ID__",X))}S.text(W);R.after(T);T.css("display","block")}function E(R,S){if(!confirm(_spTr["confirmBulk"+R])){S.stopPropagation();S.preventDefault();return false}return true}function x(U){var S=jQuery(U.target).val();var R=jQuery('input[name="random_answer"]').val();var T=jQuery('input[name="random_answer"]').data("target");if(S==R){jQuery(T).removeClass("disabled").prop("disabled",false);jQuery(T).removeAttr("aria-disabled")}else{jQuery(T).addClass("disabled").prop("disabled",true)}}function r(R){jQuery(R).parent().parent().remove()}function I(R){return R.substring(0,2)=="C-"}function K(){var R=window.location.href.split("#");window.location.href=R[0]+(R[0].indexOf("?")>0?"&":"?")+"checkquota=1"+(typeof R[1]==="undefined"?"":"#"+R[1])}function h(S){S.preventDefault();if(!this.menuCloseEvent){jQuery(window).click(function(T){if(!T.target.matches(".sp-dropbtn")){jQuery(".sp-dropdown.sp-show").removeClass("sp-show")}});this.menuCloseEvent=true}var R=S.target.parentElement.classList.contains("sp-show");jQuery(".sp-dropdown.sp-show").removeClass("sp-show");if(!R){S.target.parentElement.classList.add("sp-show")}}function Q(R){this.comparerData.origUrl=false;if(this.comparerData.cssLoaded===false){jQuery("<link>").appendTo("head").attr({type:"text/css",rel:"stylesheet",href:this.WP_PLUGIN_URL+"/res/css/twentytwenty.min.css"});this.comparerData.cssLoaded=2}if(this.comparerData.jsLoaded===false){jQuery.getScript(this.WP_PLUGIN_URL+"/res/js/jquery.twentytwenty.min.js",function(){ShortPixel.comparerData.jsLoaded=2;if(ShortPixel.comparerData.origUrl.length>0){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}});this.comparerData.jsLoaded=1}if(this.comparerData.origUrl===false){jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:{action:"shortpixel_get_comparer_data",id:R},success:function(S){data=JSON.parse(S);jQuery.extend(ShortPixel.comparerData,data);if(ShortPixel.comparerData.jsLoaded==2){ShortPixel.displayComparerPopup(ShortPixel.comparerData.width,ShortPixel.comparerData.height,ShortPixel.comparerData.origUrl,ShortPixel.comparerData.optUrl)}}});this.comparerData.origUrl=""}}function F(T,Z,aa,U){var Y=T;var S=(Z<150||T<350);var X=jQuery(S?"#spUploadCompareSideBySide":"#spUploadCompare");var V=jQuery(".sp-modal-shade");if(!S){jQuery("#spCompareSlider").html('<img class="spUploadCompareOriginal"/><img class="spUploadCompareOptimized"/>')}T=Math.max(350,Math.min(800,(T<350?(T+25)*2:(Z<150?T+25:T))));Z=Math.max(150,(S?(Y>350?2*(Z+45):Z+45):Z*T/Y));var W="-"+Math.round(T/2);jQuery(".sp-modal-body",X).css("width",T);jQuery(".shortpixel-slider",X).css("width",T);X.css("width",T);X.css("marginLeft",W+"px");jQuery(".sp-modal-body",X).css("height",Z);X.show();V.show();if(!S){jQuery("#spCompareSlider").twentytwenty({slider_move:"mousemove"})}jQuery(".sp-close-button").on("click",ShortPixel.closeComparerPopup);jQuery(document).on("keyup.sp_modal_active",ShortPixel.closeComparerPopup);jQuery(".sp-modal-shade").on("click",ShortPixel.closeComparerPopup);var R=jQuery(".spUploadCompareOptimized",X);jQuery(".spUploadCompareOriginal",X).attr("src",aa);setTimeout(function(){jQuery(window).trigger("resize")},1000);R.load(function(){jQuery(window).trigger("resize")});R.attr("src",U)}function q(R){jQuery("#spUploadCompareSideBySide").hide();jQuery("#spUploadCompare").hide();jQuery(".sp-modal-shade").hide();jQuery(document).unbind("keyup.sp_modal_active");jQuery(".sp-modal-shade").off("click");jQuery(".sp-close-button").off("click")}function A(R){var S=document.createElement("a");S.href=R;if(R.indexOf(S.protocol+"//"+S.hostname)<0){return S.href}return R.replace(S.protocol+"//"+S.hostname,S.protocol+"//"+S.hostname.split(".").map(function(T){return sp_punycode.toASCII(T)}).join("."))}return{init:J,setOptions:m,isEmailValid:t,updateSignupEmail:n,validateKey:a,enableResize:M,setupGeneralTab:e,apiKeyChanged:D,setupAdvancedTab:u,checkThumbsUpdTotal:L,initSettings:g,switchSettingsTab:y,adjustSettingsTabs:z,onBulkThumbsCheck:C,dismissMediaAlert:N,checkQuota:k,percentDial:p,successMsg:b,successActions:c,otherMediaUpdateActions:i,retry:j,initFolderSelector:o,browseContent:l,getBackupSize:d,newApiKey:f,proposeUpgrade:O,closeProposeUpgrade:H,includeUnlisted:v,bulkShowLengthyMsg:G,bulkHideLengthyMsg:B,bulkShowMaintenanceMsg:w,bulkHideMaintenanceMsg:P,bulkShowError:s,confirmBulkAction:E,checkRandomAnswer:x,removeBulkMsg:r,isCustomImageId:I,recheckQuota:K,openImageMenu:h,menuCloseEvent:false,loadComparer:Q,displayComparerPopup:F,closeComparerPopup:q,convertPunycode:A,comparerData:{cssLoaded:false,jsLoaded:false,origUrl:false,optUrl:false,width:0,height:0},toRefresh:false,resizeSizesAlert:false}}();function showToolBarAlert(c,b,d){var a=jQuery("li.shortpixel-toolbar-processing");switch(c){case ShortPixel.STATUS_QUOTA_EXCEEDED:if(window.location.href.search("wp-short-pixel-bulk")>0&&jQuery(".sp-quota-exceeded-alert").length==0){location.reload();return}a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","ShortPixel quota exceeded. Click for details.");break;case ShortPixel.STATUS_SKIP:case ShortPixel.STATUS_FAIL:a.addClass("shortpixel-alert shortpixel-processing");jQuery("a div",a).attr("title",b);if(typeof d!=="undefined"){jQuery("a",a).attr("href","post.php?post="+d+"&action=edit")}break;case ShortPixel.STATUS_NO_KEY:a.addClass("shortpixel-alert");a.addClass("shortpixel-quota-exceeded");jQuery("a",a).attr("href","options-general.php?page=wp-shortpixel");jQuery("a div",a).attr("title","Get API Key");break;case ShortPixel.STATUS_SUCCESS:case ShortPixel.STATUS_RETRY:a.addClass("shortpixel-processing");a.removeClass("shortpixel-alert");jQuery("a",a).removeAttr("target");jQuery("a",a).attr("href",jQuery("a img",a).attr("success-url"))}a.removeClass("shortpixel-hide")}function hideToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-processing").addClass("shortpixel-hide")}function hideQuotaExceededToolBarAlert(){jQuery("li.shortpixel-toolbar-processing.shortpixel-quota-exceeded").addClass("shortpixel-hide")}function checkQuotaExceededAlert(){if(typeof shortPixelQuotaExceeded!="undefined"){if(shortPixelQuotaExceeded==1){showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED)}else{hideQuotaExceededToolBarAlert()}}}function checkBulkProgress(){var b=function(e){if(!d){d=true;return e}return"/"};var d=false;var a=window.location.href.toLowerCase().replace(/\/\//g,b);d=false;var c=ShortPixel.WP_ADMIN_URL.toLowerCase().replace(/\/\//g,b);if(a.search(c)<0){a=ShortPixel.convertPunycode(a);c=ShortPixel.convertPunycode(c)}if(a.search(c+"upload.php")<0&&a.search(c+"edit.php")<0&&a.search(c+"edit-tags.php")<0&&a.search(c+"post-new.php")<0&&a.search(c+"post.php")<0&&a.search("page=nggallery-manage-gallery")<0&&(ShortPixel.FRONT_BOOTSTRAP==0||a.search(c)==0)){hideToolBarAlert();return}if(ShortPixel.bulkProcessor==true&&window.location.href.search("wp-short-pixel-bulk")<0&&typeof localStorage.bulkPage!=="undefined"&&localStorage.bulkPage>0){ShortPixel.bulkProcessor=false}if(window.location.href.search("wp-short-pixel-bulk")>=0){ShortPixel.bulkProcessor=true;localStorage.bulkTime=Math.floor(Date.now()/1000);localStorage.bulkPage=1}if(ShortPixel.bulkProcessor==true||typeof localStorage.bulkTime=="undefined"||Math.floor(Date.now()/1000)-localStorage.bulkTime>90){ShortPixel.bulkProcessor=true;localStorage.bulkPage=(window.location.href.search("wp-short-pixel-bulk")>=0?1:0);localStorage.bulkTime=Math.floor(Date.now()/1000);console.log(localStorage.bulkTime);checkBulkProcessingCallApi()}else{setTimeout(checkBulkProgress,5000)}}function checkBulkProcessingCallApi(){var a={action:"shortpixel_image_processing"};jQuery.ajax({type:"POST",url:ShortPixel.AJAX_URL,data:a,success:function(g){if(g.length>0){var i=null;try{var i=JSON.parse(g)}catch(k){ShortPixel.retry(k.message);return}ShortPixel.retries=0;var d=i.ImageID;var j=(jQuery("div.short-pixel-bulk-page").length>0);switch(i.Status){case ShortPixel.STATUS_NO_KEY:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/wp-apikey"+ShortPixel.AFFILIATE+'" target="_blank">'+_spTr.getApiKey+"</a>");showToolBarAlert(ShortPixel.STATUS_NO_KEY);break;case ShortPixel.STATUS_QUOTA_EXCEEDED:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"https://shortpixel.com/login/"+ShortPixel.API_KEY+'" target="_blank">'+_spTr.extendQuota+"</a><a class='button button-smaller' href='admin.php?action=shortpixel_check_quota'>"+_spTr.check__Quota+"</a>");showToolBarAlert(ShortPixel.STATUS_QUOTA_EXCEEDED);if(i.Stop==false){setTimeout(checkBulkProgress,5000)}ShortPixel.otherMediaUpdateActions(d,["quota","view"]);break;case ShortPixel.STATUS_FAIL:setCellMessage(d,i.Message,"<a class='button button-smaller button-primary' href=\"javascript:manualOptimization('"+d+"', false)\">"+_spTr.retry+"</a>");showToolBarAlert(ShortPixel.STATUS_FAIL,i.Message,d);if(j){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink);if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}ShortPixel.otherMediaUpdateActions(d,["retry","view"])}console.log(i.Message);setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_EMPTY_QUEUE:console.log(i.Message);clearBulkProcessor();hideToolBarAlert();var c=jQuery("#bulk-progress");if(j&&c.length&&i.BulkStatus!="2"){progressUpdate(100,"Bulk finished!");jQuery("a.bulk-cancel").attr("disabled","disabled");hideSlider();setTimeout(function(){window.location.reload()},3000)}break;case ShortPixel.STATUS_SUCCESS:if(j){ShortPixel.bulkHideLengthyMsg();ShortPixel.bulkHideMaintenanceMsg()}var l=i.PercentImprovement;showToolBarAlert(ShortPixel.STATUS_SUCCESS,"");var b=ShortPixel.isCustomImageId(d)?"":ShortPixel.successActions(d,i.Type,i.ThumbsCount,i.ThumbsTotal,i.BackupEnabled,i.Filename);setCellMessage(d,ShortPixel.successMsg(d,l,i.Type,i.ThumbsCount,i.RetinasCount),b);if(jQuery("#post-"+d).length>0){jQuery("#post-"+d).find(".filename").text(i.Filename)}if(jQuery(".misc-pub-filename strong").length>0){jQuery(".misc-pub-filename strong").text(i.Filename)}if(ShortPixel.isCustomImageId(d)&&i.TsOptimized&&i.TsOptimized.length>0){console.log(d);jQuery(".date-"+d).text(i.TsOptimized)}var h=jQuery(["restore","view","redolossy","redoglossy","redolossless"]).not(["redo"+i.Type]).get();ShortPixel.otherMediaUpdateActions(d,h);var f=new PercentageAnimator("#sp-msg-"+d+" span.percent",l);f.animate(l);if(j&&typeof i.Thumb!=="undefined"){if(i.BulkPercent){progressUpdate(i.BulkPercent,i.BulkMsg)}if(i.Thumb.length>0){sliderUpdate(d,i.Thumb,i.BkThumb,i.PercentImprovement,i.Filename);if(typeof i.AverageCompression!=="undefined"&&0+i.AverageCompression>0){jQuery("#sp-avg-optimization").html('<input type="text" class="dial" value="'+Math.round(i.AverageCompression)+'"/>');ShortPixel.percentDial("#sp-avg-optimization .dial",60)}}}console.log("Server response: "+g);if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_SKIP:if(i.Silent!==1){ShortPixel.bulkShowError(d,i.Message,i.Filename,i.CustomImageLink)}case ShortPixel.STATUS_ERROR:if(typeof i.Message!=="undefined"){showToolBarAlert(ShortPixel.STATUS_SKIP,i.Message+" Image ID: "+d);setCellMessage(d,i.Message,"")}ShortPixel.otherMediaUpdateActions(d,["retry","view"]);case ShortPixel.STATUS_RETRY:console.log("Server response: "+g);showToolBarAlert(ShortPixel.STATUS_RETRY,"");if(j&&typeof i.BulkPercent!=="undefined"){progressUpdate(i.BulkPercent,i.BulkMsg)}if(j&&i.Count>3){ShortPixel.bulkShowLengthyMsg(d,i.Filename,i.CustomImageLink)}setTimeout(checkBulkProgress,5000);break;case ShortPixel.STATUS_MAINTENANCE:ShortPixel.bulkShowMaintenanceMsg("maintenance");setTimeout(checkBulkProgress,60000);break;case ShortPixel.STATUS_QUEUE_FULL:ShortPixel.bulkShowMaintenanceMsg("queue-full");setTimeout(checkBulkProgress,60000);break;default:ShortPixel.retry("Unknown status "+i.Status+". Retrying...");break}}},error:function(b){ShortPixel.retry(b.statusText)}})}function clearBulkProcessor(){ShortPixel.bulkProcessor=false;localStorage.bulkTime=0;if(window.location.href.search("wp-short-pixel-bulk")>=0){localStorage.bulkPage=0}}function setCellMessage(d,a,c){var b=jQuery("#sp-msg-"+d);if(b.length>0){b.html("<div class='sp-column-actions'>"+c+"</div><div class='sp-column-info'>"+a+"</div>");b.css("color","")}b=jQuery("#sp-cust-msg-"+d);if(b.length>0){b.html("<div class='sp-column-info'>"+a+"</div>")}}function manualOptimization(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be processed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-alert");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_manual_optimization",image_id:c,cleanup:a};jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(d){var e=JSON.parse(d);if(e.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(c,typeof e.Message!=="undefined"?e.Message:_spTr.thisContentNotProcessable,"")}},error:function(d){b.action="shortpixel_check_status";jQuery.ajax({type:"GET",url:ShortPixel.AJAX_URL,data:b,success:function(e){var f=JSON.parse(e);if(f.Status!==ShortPixel.STATUS_SUCCESS){setCellMessage(c,typeof f.Message!=="undefined"?f.Message:_spTr.thisContentNotProcessable,"")}}})}})}function reoptimize(c,a){setCellMessage(c,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>Image waiting to be reprocessed","");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var b={action:"shortpixel_redo",attachment_ID:c,type:a};jQuery.get(ShortPixel.AJAX_URL,b,function(d){b=JSON.parse(d);if(b.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{$msg=typeof b.Message!=="undefined"?b.Message:_spTr.thisContentNotProcessable;setCellMessage(c,$msg,"");showToolBarAlert(ShortPixel.STATUS_FAIL,$msg)}})}function optimizeThumbs(b){setCellMessage(b,"<img src='"+ShortPixel.WP_PLUGIN_URL+"/res/img/loading.gif' class='sp-loading-small'>"+_spTr.imageWaitOptThumbs,"");jQuery("li.shortpixel-toolbar-processing").removeClass("shortpixel-hide");jQuery("li.shortpixel-toolbar-processing").addClass("shortpixel-processing");var a={action:"shortpixel_optimize_thumbs",attachment_ID:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){setTimeout(checkBulkProgress,2000)}else{setCellMessage(b,typeof a.Message!=="undefined"?a.Message:_spTr.thisContentNotProcessable,"")}})}function dismissShortPixelNoticeExceed(b){jQuery("#wp-admin-bar-shortpixel_processing").hide();var a={action:"shortpixel_dismiss_notice",notice_id:"exceed"};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}});b.preventDefault()}function dismissShortPixelNotice(b){jQuery("#short-pixel-notice-"+b).hide();var a={action:"shortpixel_dismiss_notice",notice_id:b};jQuery.get(ShortPixel.AJAX_URL,a,function(c){a=JSON.parse(c);if(a.Status==ShortPixel.STATUS_SUCCESS){console.log("dismissed")}})}function PercentageAnimator(b,a){this.animationSpeed=10;this.increment=2;this.curPercentage=0;this.targetPercentage=a;this.outputSelector=b;this.animate=function(c){this.targetPercentage=c;setTimeout(PercentageTimer.bind(null,this),this.animationSpeed)}}function PercentageTimer(a){if(a.curPercentage-a.targetPercentage<-a.increment){a.curPercentage+=a.increment}else{if(a.curPercentage-a.targetPercentage>a.increment){a.curPercentage-=a.increment}else{a.curPercentage=a.targetPercentage}}jQuery(a.outputSelector).text(a.curPercentage+"%");if(a.curPercentage!=a.targetPercentage){setTimeout(PercentageTimer.bind(null,a),a.animationSpeed)}}function progressUpdate(c,b){var a=jQuery("#bulk-progress");if(a.length){jQuery(".progress-left",a).css("width",c+"%");jQuery(".progress-img",a).css("left",c+"%");if(c>24){jQuery(".progress-img span",a).html("");jQuery(".progress-left",a).html(c+"%")}else{jQuery(".progress-img span",a).html(c+"%");jQuery(".progress-left",a).html("")}jQuery(".bulk-estimate").html(b)}}function sliderUpdate(g,c,d,e,b){var f=jQuery(".bulk-slider div.bulk-slide:first-child");if(f.length===0){return}if(f.attr("id")!="empty-slide"){f.hide()}f.css("z-index",1000);jQuery(".bulk-img-opt",f).attr("src","");if(typeof d==="undefined"){d=""}if(d.length>0){jQuery(".bulk-img-orig",f).attr("src","")}var a=f.clone();a.attr("id","slide-"+g);jQuery(".bulk-img-opt",a).attr("src",c);if(d.length>0){jQuery(".img-original",a).css("display","inline-block");jQuery(".bulk-img-orig",a).attr("src",d)}else{jQuery(".img-original",a).css("display","none")}jQuery(".bulk-opt-percent",a).html('<input type="text" class="dial" value="'+e+'"/>');jQuery(".bulk-slider").append(a);ShortPixel.percentDial("#"+a.attr("id")+" .dial",100);jQuery(".bulk-slider-container span.filename").html(" "+b);if(f.attr("id")=="empty-slide"){f.remove();jQuery(".bulk-slider-container").css("display","block")}else{f.animate({left:f.width()+f.position().left},"slow","swing",function(){f.remove();a.fadeIn("slow")})}}function hideSlider(){jQuery(".bulk-slider-container").css("display","none")}function showStats(){var a=jQuery(".bulk-stats");if(a.length>0){}}if(!(typeof String.prototype.format=="function")){String.prototype.format=function(){var b=this,a=arguments.length;while(a--){b=b.replace(new RegExp("\\{"+a+"\\}","gm"),arguments[a])}return b}};
|
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,3 +1,6 @@
|
|
1 |
|
|
|
2 |
@import 'view/bulk-restore-all';
|
3 |
-
@import 'view/
|
|
|
|
1 |
|
2 |
+
@import 'utils/notices';
|
3 |
@import 'view/bulk-restore-all';
|
4 |
+
@import 'view/bulk_dashboard';
|
5 |
+
@import 'view/settings-advanced';
|
6 |
+
@import 'view/settings';
|
@@ -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,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
.short-pixel-bulk-page
|
3 |
+
{
|
4 |
+
.sp-hidden
|
5 |
+
{
|
6 |
+
display: none;
|
7 |
+
}
|
8 |
+
}
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
// in our own scope.
|
3 |
+
.settings_page_wp-shortpixel-settings
|
4 |
+
{
|
5 |
+
.top-menu
|
6 |
+
{
|
7 |
+
font-size: 18px;
|
8 |
+
a { font-size: 18px; }
|
9 |
+
}
|
10 |
+
|
11 |
+
.wp-shortpixel-tab-content
|
12 |
+
{
|
13 |
+
transition: all 1000ms linear;
|
14 |
+
}
|
15 |
+
|
16 |
+
//tabs
|
17 |
+
article.sp-tabs
|
18 |
+
{
|
19 |
+
section
|
20 |
+
{
|
21 |
+
.wp-shortpixel-tab-content
|
22 |
+
{ opacity: 0; }
|
23 |
+
&.sel-tab .wp-shortpixel-tab-content
|
24 |
+
{
|
25 |
+
opacity: 1;
|
26 |
+
}
|
27 |
+
}
|
28 |
+
section h2 {
|
29 |
+
position: absolute;
|
30 |
+
font-size: 1.3em;
|
31 |
+
font-weight: normal;
|
32 |
+
width: 180px;
|
33 |
+
height: 1.8em;
|
34 |
+
top: -1.8em;
|
35 |
+
left: 10px;
|
36 |
+
padding: 0;
|
37 |
+
margin: 0;
|
38 |
+
color: #999;
|
39 |
+
background-color: #ddd;
|
40 |
+
/* border-radius: 5px 5px 0 0; */
|
41 |
+
a {
|
42 |
+
display: block;
|
43 |
+
width: 100%;
|
44 |
+
line-height: 1.8em;
|
45 |
+
text-align: center;
|
46 |
+
text-decoration: none;
|
47 |
+
color: #23282d;
|
48 |
+
outline: 0 none;
|
49 |
+
}
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
article.sp-tabs section:nth-child(2) h2 {
|
54 |
+
left: 192px;
|
55 |
+
}
|
56 |
+
article.sp-tabs section:nth-child(3) h2 {
|
57 |
+
left: 374px;
|
58 |
+
}
|
59 |
+
article.sp-tabs section:nth-child(4) h2 {
|
60 |
+
left: 556px;
|
61 |
+
}
|
62 |
+
article.sp-tabs section:nth-child(5) h2 {
|
63 |
+
left: 738px;
|
64 |
+
}
|
65 |
+
article.sp-tabs section:nth-child(6) h2 {
|
66 |
+
left: 920px;
|
67 |
+
}
|
68 |
+
//article.sp-tabs section h2
|
69 |
+
|
70 |
+
section#tab-debug
|
71 |
+
{
|
72 |
+
.flex {
|
73 |
+
display: flex;
|
74 |
+
}
|
75 |
+
.env .flex {
|
76 |
+
flex-wrap: wrap;
|
77 |
+
max-width: 450px;
|
78 |
+
span {
|
79 |
+
width: 45%;
|
80 |
+
padding: 4px;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
}
|
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace ShortPixel;
|
3 |
+
use ShortPixel\ShortPixelLogger as Log;
|
4 |
+
use ShortPixel\NoticeController as Notice;
|
5 |
+
|
6 |
+
|
7 |
+
/** Plugin class
|
8 |
+
* This class is meant for: WP Hooks, init of runtime and Controller Routing.
|
9 |
+
|
10 |
+
*/
|
11 |
+
class ShortPixelPlugin
|
12 |
+
{
|
13 |
+
static $instance;
|
14 |
+
private $paths = array('class', 'class/controller', 'class/external');
|
15 |
+
|
16 |
+
protected $is_noheaders = false;
|
17 |
+
|
18 |
+
protected $plugin_path;
|
19 |
+
protected $plugin_url;
|
20 |
+
|
21 |
+
public function __construct()
|
22 |
+
{
|
23 |
+
$this->plugin_path = plugin_dir_path(SHORTPIXEL_PLUGIN_FILE);
|
24 |
+
$this->plugin_url = plugin_dir_url(SHORTPIXEL_PLUGIN_FILE);
|
25 |
+
|
26 |
+
$this->initRuntime();
|
27 |
+
$this->initHooks();
|
28 |
+
|
29 |
+
if(isset($_REQUEST['noheader'])) {
|
30 |
+
$this->is_noheaders = true;
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
/** Create instance. This should not be needed to call anywhere else than main plugin file **/
|
35 |
+
public static function getInstance()
|
36 |
+
{
|
37 |
+
if (is_null(self::$instance))
|
38 |
+
{
|
39 |
+
self::$instance = new shortPixelPlugin();
|
40 |
+
}
|
41 |
+
return self::$instance;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
public function initRuntime()
|
46 |
+
{
|
47 |
+
$plugin_path = plugin_dir_path(SHORTPIXEL_PLUGIN_FILE);
|
48 |
+
foreach($this->paths as $short_path)
|
49 |
+
{
|
50 |
+
$directory_path = realpath($plugin_path . $short_path);
|
51 |
+
|
52 |
+
if ($directory_path !== false)
|
53 |
+
{
|
54 |
+
$it = new \DirectoryIterator($directory_path);
|
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);
|
62 |
+
}
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
/** Hooks for all WordPress related hooks
|
69 |
+
*/
|
70 |
+
public function initHooks()
|
71 |
+
{
|
72 |
+
add_action('admin_menu', array($this,'admin_pages'));
|
73 |
+
add_action('admin_enqueue_scripts', array($this, 'admin_scripts'));
|
74 |
+
add_action('admin_notices', array($this, 'admin_notices')); // notices occured before page load
|
75 |
+
add_action('admin_footer', array($this, 'admin_notices')); // called in views.
|
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.
|
88 |
+
*/
|
89 |
+
public function admin_scripts()
|
90 |
+
{
|
91 |
+
// FileTree in Settings
|
92 |
+
wp_register_style('sp-file-tree', plugins_url('/res/css/sp-file-tree.min.css',SHORTPIXEL_PLUGIN_FILE),array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION );
|
93 |
+
wp_register_script('sp-file-tree', plugins_url('/res/js/sp-file-tree.min.js',SHORTPIXEL_PLUGIN_FILE) );
|
94 |
+
|
95 |
+
wp_register_style('shortpixel-admin', plugins_url('/res/css/shortpixel-admin.css', SHORTPIXEL_PLUGIN_FILE),array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION );
|
96 |
+
|
97 |
+
wp_register_style('shortpixel', plugins_url('/res/css/short-pixel.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
98 |
+
//modal - used in settings for selecting folder
|
99 |
+
wp_register_style('shortpixel-modal', plugins_url('/res/css/short-pixel-modal.min.css',SHORTPIXEL_PLUGIN_FILE), array(), SHORTPIXEL_IMAGE_OPTIMISER_VERSION);
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
public function admin_notices()
|
104 |
+
{
|
105 |
+
$noticeControl = Notice::getInstance();
|
106 |
+
|
107 |
+
if ($noticeControl->countNotices() > 0)
|
108 |
+
{
|
109 |
+
foreach($noticeControl->getNotices() as $notice)
|
110 |
+
{
|
111 |
+
echo $notice->getForDisplay();
|
112 |
+
}
|
113 |
+
}
|
114 |
+
$noticeControl->update(); // puts views, and updates
|
115 |
+
}
|
116 |
+
|
117 |
+
/** Load Style via Route, on demand */
|
118 |
+
public function load_style($name)
|
119 |
+
{
|
120 |
+
if ($this->is_noheaders) // fail silently, if this is a no-headers request.
|
121 |
+
return;
|
122 |
+
|
123 |
+
if (wp_style_is($name, 'registered'))
|
124 |
+
{
|
125 |
+
wp_enqueue_style($name);
|
126 |
+
}
|
127 |
+
else {
|
128 |
+
Log::addWarn("Style $name was asked for, but not registered");
|
129 |
+
}
|
130 |
+
}
|
131 |
+
|
132 |
+
/** Load Style via Route, on demand */
|
133 |
+
public function load_script($name)
|
134 |
+
{
|
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 |
+
}
|
148 |
+
|
149 |
+
/** Route, based on the page slug
|
150 |
+
*
|
151 |
+
* Principially all page controller should be routed from here.
|
152 |
+
*/
|
153 |
+
public function route()
|
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);
|
160 |
+
$controller = false;
|
161 |
+
|
162 |
+
switch($plugin_page)
|
163 |
+
{
|
164 |
+
case 'wp-shortpixel-settings':
|
165 |
+
$this->load_style('shortpixel-admin');
|
166 |
+
$this->load_style('shortpixel');
|
167 |
+
$this->load_style('shortpixel-modal');
|
168 |
+
$this->load_style('sp-file-tree');
|
169 |
+
$this->load_script('sp-file-tree');
|
170 |
+
$controller = \shortPixelTools::namespaceit("SettingsController");
|
171 |
+
$url = menu_page_url($plugin_page, false);
|
172 |
+
break;
|
173 |
+
}
|
174 |
+
|
175 |
+
if ($controller !== false)
|
176 |
+
{
|
177 |
+
$c = new $controller();
|
178 |
+
$c->setShortPixel($shortPixelPluginInstance);
|
179 |
+
$c->setControllerURL($url);
|
180 |
+
if (method_exists($c, $action))
|
181 |
+
$c->$action();
|
182 |
+
else {
|
183 |
+
Log::addWarn("Attempted Action $action on $controller does not exist!");
|
184 |
+
$c->$default_action();
|
185 |
+
}
|
186 |
+
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
|
191 |
+
|
192 |
+
}
|
@@ -3,6 +3,8 @@ if ( !function_exists( 'download_url' ) ) {
|
|
3 |
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
4 |
}
|
5 |
|
|
|
|
|
6 |
class ShortPixelAPI {
|
7 |
|
8 |
const STATUS_SUCCESS = 1;
|
@@ -104,10 +106,12 @@ class ShortPixelAPI {
|
|
104 |
$apiKey = $this->_settings->apiKey;
|
105 |
if(strlen($apiKey) < 20) { //found in the logs many cases when the API Key is '', probably deleted from the DB but the verifiedKey setting is not changed
|
106 |
$this->_settings->verifiedKey = false;
|
|
|
107 |
throw new Exception(__('Invalid API Key', 'shortpixel-image-optimiser'));
|
108 |
}
|
109 |
|
110 |
// WpShortPixel::log("DO REQUESTS for META: " . json_encode($itemHandler->getRawMeta()) . " STACK: " . json_encode(debug_backtrace()));
|
|
|
111 |
|
112 |
$requestParameters = array(
|
113 |
'plugin_version' => SHORTPIXEL_IMAGE_OPTIMISER_VERSION,
|
@@ -411,7 +415,7 @@ class ShortPixelAPI {
|
|
411 |
$fileURL = $this->setPreferredProtocol(urldecode($optimizedUrl));
|
412 |
|
413 |
$tempFile = download_url($fileURL, $downloadTimeout);
|
414 |
-
|
415 |
if(is_wp_error( $tempFile ))
|
416 |
{ //try to switch the default protocol
|
417 |
$fileURL = $this->setPreferredProtocol(urldecode($optimizedUrl), true); //force recheck of the protocol
|
@@ -447,27 +451,42 @@ class ShortPixelAPI {
|
|
447 |
return $returnMessage;
|
448 |
}
|
449 |
|
|
|
|
|
|
|
|
|
|
|
450 |
public static function backupImage($mainPath, $PATHs) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
451 |
//$fullSubDir = str_replace(wp_normalize_path(get_home_path()), "", wp_normalize_path(dirname($itemHandler->getMeta()->getPath()))) . '/';
|
452 |
//$SubDir = ShortPixelMetaFacade::returnSubDir($itemHandler->getMeta()->getPath(), $itemHandler->getType());
|
453 |
$fullSubDir = ShortPixelMetaFacade::returnSubDir($mainPath);
|
454 |
$source = $PATHs; //array with final paths for these files
|
455 |
|
456 |
-
if( !file_exists(SHORTPIXEL_BACKUP_FOLDER) &&
|
|
|
457 |
return array("Status" => self::STATUS_FAIL, "Message" => __('Backup folder does not exist and it cannot be created','shortpixel-image-optimiser'));
|
458 |
}
|
459 |
//create subdir in backup folder if needed
|
460 |
-
|
|
|
461 |
|
462 |
foreach ( $source as $fileID => $filePATH )//create destination files array
|
463 |
{
|
464 |
$destination[$fileID] = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir . self::MB_basename($source[$fileID]);
|
465 |
}
|
466 |
-
//die("IZ BACKUP: " . SHORTPIXEL_BACKUP_FOLDER . '/' . $SubDir . var_dump($destination));
|
467 |
|
468 |
//now that we have original files and where we should back them up we attempt to do just that
|
469 |
if(is_writable(SHORTPIXEL_BACKUP_FOLDER))
|
470 |
{
|
|
|
471 |
foreach ( $destination as $fileID => $filePATH )
|
472 |
{
|
473 |
if ( !file_exists($filePATH) )
|
@@ -483,6 +502,7 @@ class ShortPixelAPI {
|
|
483 |
}
|
484 |
else {//cannot write to the backup dir, return with an error
|
485 |
$msg = __('Cannot save file in backup directory','shortpixel-image-optimiser');
|
|
|
486 |
return array("Status" => self::STATUS_FAIL, "Message" => $msg);
|
487 |
}
|
488 |
}
|
@@ -490,7 +510,7 @@ class ShortPixelAPI {
|
|
490 |
private function createArchiveTempFolder($archiveBasename) {
|
491 |
$archiveTempDir = get_temp_dir() . '/' . $archiveBasename;
|
492 |
if(file_exists($archiveTempDir) && is_dir($archiveTempDir) && (time() - filemtime($archiveTempDir) < max(30, SHORTPIXEL_MAX_EXECUTION_TIME) + 10)) {
|
493 |
-
|
494 |
return array("Status" => self::STATUS_RETRY, "Code" => 1, "Message" => "Pending");
|
495 |
}
|
496 |
if( !file_exists($archiveTempDir) && !@mkdir($archiveTempDir) ) {
|
@@ -562,7 +582,7 @@ class ShortPixelAPI {
|
|
562 |
* @return array status/message
|
563 |
*/
|
564 |
private function handleSuccess($APIresponse, $PATHs, $itemHandler, $compressionType) {
|
565 |
-
|
566 |
|
567 |
$counter = $savedSpace = $originalSpace = $optimizedSpace /* = $averageCompression */ = 0;
|
568 |
$NoBackup = true;
|
@@ -628,12 +648,15 @@ class ShortPixelAPI {
|
|
628 |
$mainPath = $itemHandler->getMeta()->getPath();
|
629 |
|
630 |
//if backup is enabled - we try to save the images
|
|
|
631 |
if( $this->_settings->backupImages )
|
632 |
{
|
633 |
$backupStatus = self::backupImage($mainPath, $PATHs);
|
|
|
634 |
if($backupStatus == self::STATUS_FAIL) {
|
635 |
$itemHandler->incrementRetries(1, self::ERR_SAVE_BKP, $backupStatus["Message"]);
|
636 |
self::cleanupTemporaryFiles($archive, empty($tempFiles) ? array() : $tempFiles);
|
|
|
637 |
return array("Status" => self::STATUS_FAIL, "Code" =>"backup-fail", "Message" => "Failed to back the image up.");
|
638 |
}
|
639 |
$NoBackup = false;
|
@@ -664,7 +687,7 @@ class ShortPixelAPI {
|
|
664 |
|
665 |
if($tempFile['Status'] == self::STATUS_SUCCESS) { //if it's unchanged it will still be in the array but only for WebP (handled below)
|
666 |
$tempFilePATH = $tempFile["Message"];
|
667 |
-
if ( file_exists($tempFilePATH) && file_exists($targetFile)
|
668 |
copy($tempFilePATH, $targetFile);
|
669 |
if(ShortPixelMetaFacade::isRetina($targetFile)) {
|
670 |
$retinas ++;
|
@@ -691,9 +714,7 @@ class ShortPixelAPI {
|
|
691 |
if($archive && SHORTPIXEL_DEBUG === true) {
|
692 |
if(!file_exists($tempFilePATH)) {
|
693 |
WPShortPixel::log("MISSING FROM ARCHIVE. tempFilePath: $tempFilePATH with ID: $tempFileID");
|
694 |
-
} elseif(!
|
695 |
-
WPShortPixel::log("MISSING TARGET: $targetFile");
|
696 |
-
} elseif(!is_writable($targetFile)){
|
697 |
WPShortPixel::log("TARGET NOT WRITABLE: $targetFile");
|
698 |
}
|
699 |
}
|
@@ -709,7 +730,7 @@ class ShortPixelAPI {
|
|
709 |
//if the WebP fileCompat already exists, it means that there is another file with the same basename but different extension which has its .webP counterpart
|
710 |
//save it with double extension
|
711 |
if(file_exists($targetWebPFileCompat)) {
|
712 |
-
copy($targetWebPFile
|
713 |
} else {
|
714 |
copy($tempWebpFilePATH, $targetWebPFileCompat);
|
715 |
}
|
@@ -847,7 +868,7 @@ class ShortPixelAPI {
|
|
847 |
foreach ( $PATHs as $Id => $File )
|
848 |
{
|
849 |
//we try again with a different path
|
850 |
-
if ( !file_exists($File) ){
|
851 |
//$NewFile = $uploadDir['basedir'] . "/" . substr($File,strpos($File, $StichString));//+strlen($StichString));
|
852 |
$NewFile = SHORTPIXEL_UPLOADS_BASE . substr($File,strpos($File, $StichString)+strlen($StichString));
|
853 |
if (file_exists($NewFile)) {
|
3 |
require_once( ABSPATH . 'wp-admin/includes/file.php' );
|
4 |
}
|
5 |
|
6 |
+
use \ShortPixel\ShortPixelLogger as Log;
|
7 |
+
|
8 |
class ShortPixelAPI {
|
9 |
|
10 |
const STATUS_SUCCESS = 1;
|
106 |
$apiKey = $this->_settings->apiKey;
|
107 |
if(strlen($apiKey) < 20) { //found in the logs many cases when the API Key is '', probably deleted from the DB but the verifiedKey setting is not changed
|
108 |
$this->_settings->verifiedKey = false;
|
109 |
+
Log::addWarn('Invalid API Key');
|
110 |
throw new Exception(__('Invalid API Key', 'shortpixel-image-optimiser'));
|
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,
|
415 |
$fileURL = $this->setPreferredProtocol(urldecode($optimizedUrl));
|
416 |
|
417 |
$tempFile = download_url($fileURL, $downloadTimeout);
|
418 |
+
Log::addInfo('Downloading file: '.json_encode($tempFile));
|
419 |
if(is_wp_error( $tempFile ))
|
420 |
{ //try to switch the default protocol
|
421 |
$fileURL = $this->setPreferredProtocol(urldecode($optimizedUrl), true); //force recheck of the protocol
|
451 |
return $returnMessage;
|
452 |
}
|
453 |
|
454 |
+
/** Tries to create backup
|
455 |
+
*
|
456 |
+
* @param $mainPath
|
457 |
+
* @param $PATHs
|
458 |
+
* @return Array Array with Status and optional Message */
|
459 |
public static function backupImage($mainPath, $PATHs) {
|
460 |
+
/**
|
461 |
+
* Passing a truthy value to the filter will effectively short-circuit this function.
|
462 |
+
* So third party plugins can handle Backup by there own.
|
463 |
+
*/
|
464 |
+
if(apply_filters('shortpixel_skip_backup', false, $mainPath, $PATHs)){
|
465 |
+
return array("Status" => self::STATUS_SUCCESS);
|
466 |
+
}
|
467 |
+
|
468 |
//$fullSubDir = str_replace(wp_normalize_path(get_home_path()), "", wp_normalize_path(dirname($itemHandler->getMeta()->getPath()))) . '/';
|
469 |
//$SubDir = ShortPixelMetaFacade::returnSubDir($itemHandler->getMeta()->getPath(), $itemHandler->getType());
|
470 |
$fullSubDir = ShortPixelMetaFacade::returnSubDir($mainPath);
|
471 |
$source = $PATHs; //array with final paths for these files
|
472 |
|
473 |
+
if( !file_exists(SHORTPIXEL_BACKUP_FOLDER) && ! ShortPixelFolder::createBackUpFolder() ) {//creates backup folder if it doesn't exist
|
474 |
+
Log::addWarn('Backup folder does not exist and it cannot be created');
|
475 |
return array("Status" => self::STATUS_FAIL, "Message" => __('Backup folder does not exist and it cannot be created','shortpixel-image-optimiser'));
|
476 |
}
|
477 |
//create subdir in backup folder if needed
|
478 |
+
//@mkdir( SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir, 0777, true);
|
479 |
+
ShortPixelFolder::createBackUpFolder(SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir);
|
480 |
|
481 |
foreach ( $source as $fileID => $filePATH )//create destination files array
|
482 |
{
|
483 |
$destination[$fileID] = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir . self::MB_basename($source[$fileID]);
|
484 |
}
|
|
|
485 |
|
486 |
//now that we have original files and where we should back them up we attempt to do just that
|
487 |
if(is_writable(SHORTPIXEL_BACKUP_FOLDER))
|
488 |
{
|
489 |
+
Log::addDebug('Creating backups from source - destination', array('source' => $source, 'destination' => $destination));
|
490 |
foreach ( $destination as $fileID => $filePATH )
|
491 |
{
|
492 |
if ( !file_exists($filePATH) )
|
502 |
}
|
503 |
else {//cannot write to the backup dir, return with an error
|
504 |
$msg = __('Cannot save file in backup directory','shortpixel-image-optimiser');
|
505 |
+
Log::addWarn('Backup directory not writable');
|
506 |
return array("Status" => self::STATUS_FAIL, "Message" => $msg);
|
507 |
}
|
508 |
}
|
510 |
private function createArchiveTempFolder($archiveBasename) {
|
511 |
$archiveTempDir = get_temp_dir() . '/' . $archiveBasename;
|
512 |
if(file_exists($archiveTempDir) && is_dir($archiveTempDir) && (time() - filemtime($archiveTempDir) < max(30, SHORTPIXEL_MAX_EXECUTION_TIME) + 10)) {
|
513 |
+
Log::addWarn("CONFLICT. Folder already exists and is modified in the last minute. Current IP:" . $_SERVER['REMOTE_ADDR']);
|
514 |
return array("Status" => self::STATUS_RETRY, "Code" => 1, "Message" => "Pending");
|
515 |
}
|
516 |
if( !file_exists($archiveTempDir) && !@mkdir($archiveTempDir) ) {
|
582 |
* @return array status/message
|
583 |
*/
|
584 |
private function handleSuccess($APIresponse, $PATHs, $itemHandler, $compressionType) {
|
585 |
+
Log::addDebug('Shortpixel API : Handling Success!');
|
586 |
|
587 |
$counter = $savedSpace = $originalSpace = $optimizedSpace /* = $averageCompression */ = 0;
|
588 |
$NoBackup = true;
|
648 |
$mainPath = $itemHandler->getMeta()->getPath();
|
649 |
|
650 |
//if backup is enabled - we try to save the images
|
651 |
+
Log::addDebug('Check setting backup', array($this->_settings->backupImages));
|
652 |
if( $this->_settings->backupImages )
|
653 |
{
|
654 |
$backupStatus = self::backupImage($mainPath, $PATHs);
|
655 |
+
Log::addDebug('Status', $backupStatus);
|
656 |
if($backupStatus == self::STATUS_FAIL) {
|
657 |
$itemHandler->incrementRetries(1, self::ERR_SAVE_BKP, $backupStatus["Message"]);
|
658 |
self::cleanupTemporaryFiles($archive, empty($tempFiles) ? array() : $tempFiles);
|
659 |
+
Log::addError('Failed to create image backup!', array('status' => $backupStatus));
|
660 |
return array("Status" => self::STATUS_FAIL, "Code" =>"backup-fail", "Message" => "Failed to back the image up.");
|
661 |
}
|
662 |
$NoBackup = false;
|
687 |
|
688 |
if($tempFile['Status'] == self::STATUS_SUCCESS) { //if it's unchanged it will still be in the array but only for WebP (handled below)
|
689 |
$tempFilePATH = $tempFile["Message"];
|
690 |
+
if ( file_exists($tempFilePATH) && (!file_exists($targetFile) || is_writable($targetFile)) ) {
|
691 |
copy($tempFilePATH, $targetFile);
|
692 |
if(ShortPixelMetaFacade::isRetina($targetFile)) {
|
693 |
$retinas ++;
|
714 |
if($archive && SHORTPIXEL_DEBUG === true) {
|
715 |
if(!file_exists($tempFilePATH)) {
|
716 |
WPShortPixel::log("MISSING FROM ARCHIVE. tempFilePath: $tempFilePATH with ID: $tempFileID");
|
717 |
+
} elseif(!wp_is_writable($targetFile)){
|
|
|
|
|
718 |
WPShortPixel::log("TARGET NOT WRITABLE: $targetFile");
|
719 |
}
|
720 |
}
|
730 |
//if the WebP fileCompat already exists, it means that there is another file with the same basename but different extension which has its .webP counterpart
|
731 |
//save it with double extension
|
732 |
if(file_exists($targetWebPFileCompat)) {
|
733 |
+
copy($tempWebpFilePATH, $targetWebPFile);
|
734 |
} else {
|
735 |
copy($tempWebpFilePATH, $targetWebPFileCompat);
|
736 |
}
|
868 |
foreach ( $PATHs as $Id => $File )
|
869 |
{
|
870 |
//we try again with a different path
|
871 |
+
if ( !apply_filters( 'shortpixel_image_exists', file_exists($File), $File ) ){
|
872 |
//$NewFile = $uploadDir['basedir'] . "/" . substr($File,strpos($File, $StichString));//+strlen($StichString));
|
873 |
$NewFile = SHORTPIXEL_UPLOADS_BASE . substr($File,strpos($File, $StichString)+strlen($StichString));
|
874 |
if (file_exists($NewFile)) {
|
@@ -1,16 +1,52 @@
|
|
1 |
<?php
|
|
|
2 |
if(defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG === true) {
|
3 |
require_once('shortpixel-debug.php');
|
4 |
} else {
|
5 |
define('SHORTPIXEL_DEBUG', false);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
}
|
7 |
|
8 |
-
|
9 |
-
|
10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
require_once('shortpixel_api.php');
|
12 |
-
require_once('class/shortpixel_queue.php');
|
13 |
-
require_once('class/shortpixel-png2jpg.php');
|
14 |
//entities
|
15 |
require_once('class/model/shortpixel-entity.php');
|
16 |
require_once('class/model/shortpixel-meta.php');
|
@@ -27,15 +63,15 @@ require_once('class/db/shortpixel-meta-facade.php');
|
|
27 |
//view
|
28 |
require_once('class/view/shortpixel_view.php');
|
29 |
|
30 |
-
require_once('class/shortpixel-tools.php');
|
31 |
|
32 |
-
require_once('class/controller/
|
33 |
-
require_once('class/controller/bulk-restore-all.php');
|
34 |
|
35 |
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
36 |
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
37 |
|
38 |
// for retro compatibility with WP < 3.5
|
|
|
39 |
if( !function_exists('wp_normalize_path') ){
|
40 |
function wp_normalize_path( $path ) {
|
41 |
$path = str_replace( '\\', '/', $path );
|
1 |
<?php
|
2 |
+
/*
|
3 |
if(defined('SHORTPIXEL_DEBUG') && SHORTPIXEL_DEBUG === true) {
|
4 |
require_once('shortpixel-debug.php');
|
5 |
} else {
|
6 |
define('SHORTPIXEL_DEBUG', false);
|
7 |
+
} */
|
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 |
+
{
|
22 |
+
define('SHORTPIXEL_DEBUG', false);
|
23 |
}
|
24 |
|
25 |
+
Log::addDebug('Plugin Req Init');
|
26 |
+
|
27 |
+
|
28 |
+
// [BS] New plugin runtime.
|
29 |
+
require_once('shortpixel-plugin.php'); // loads runtime and needed classes.
|
30 |
+
new Shortpixel\ShortPixelPlugin();
|
31 |
+
|
32 |
+
// @todo Temporary until main plugin file will receive it's unclutter. Require the things loaded by new plugin main
|
33 |
+
/*if (! class_exists('ShortPixel\ShortPixelPlugin'))
|
34 |
+
{
|
35 |
+
require_once('class/shortpixel_queue.php');
|
36 |
+
require_once('class/shortpixel-png2jpg.php');
|
37 |
+
require_once('class/wp-short-pixel.php');
|
38 |
+
require_once('class/wp-shortpixel-settings.php');
|
39 |
+
require_once('class/wp-shortpixel-cloudflare-api.php');
|
40 |
+
require_once('class/shortpixel-tools.php');
|
41 |
+
require_once('class/controller/bulk-restore-all.php');
|
42 |
+
} */
|
43 |
+
|
44 |
+
//require_once('class/wp-short-pixel.php');
|
45 |
+
//require_once('class/wp-shortpixel-settings.php');
|
46 |
+
//require_once('class/wp-shortpixel-cloudflare-api.php');
|
47 |
require_once('shortpixel_api.php');
|
48 |
+
//require_once('class/shortpixel_queue.php');
|
49 |
+
//require_once('class/shortpixel-png2jpg.php');
|
50 |
//entities
|
51 |
require_once('class/model/shortpixel-entity.php');
|
52 |
require_once('class/model/shortpixel-meta.php');
|
63 |
//view
|
64 |
require_once('class/view/shortpixel_view.php');
|
65 |
|
66 |
+
//require_once('class/shortpixel-tools.php');
|
67 |
|
68 |
+
//require_once('class/controller/bulk-restore-all.php');
|
|
|
69 |
|
70 |
require_once( ABSPATH . 'wp-admin/includes/image.php' );
|
71 |
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
72 |
|
73 |
// for retro compatibility with WP < 3.5
|
74 |
+
// @todo Move this to compatibility file.
|
75 |
if( !function_exists('wp_normalize_path') ){
|
76 |
function wp_normalize_path( $path ) {
|
77 |
$path = str_replace( '\\', '/', $path );
|
@@ -2,15 +2,16 @@
|
|
2 |
/**
|
3 |
* Plugin Name: ShortPixel Image Optimizer
|
4 |
* Plugin URI: https://shortpixel.com/
|
5 |
-
* Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel" target="_blank">Settings > ShortPixel</a> page on how to start optimizing your image library and make your website load faster.
|
6 |
-
* Version: 4.
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
10 |
* Domain Path: /lang
|
11 |
*/
|
12 |
|
13 |
-
|
|
|
14 |
//define('SHORTPIXEL_DEBUG', true);
|
15 |
//define('SHORTPIXEL_DEBUG_TARGET', true);
|
16 |
|
@@ -18,7 +19,7 @@ define('SHORTPIXEL_PLUGIN_FILE', __FILE__);
|
|
18 |
|
19 |
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
20 |
|
21 |
-
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.
|
22 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
23 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
24 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
@@ -81,6 +82,7 @@ function shortpixelInit() {
|
|
81 |
)
|
82 |
{
|
83 |
require_once('wp-shortpixel-req.php');
|
|
|
84 |
$shortPixelPluginInstance = new WPShortPixel;
|
85 |
}
|
86 |
|
@@ -158,7 +160,9 @@ function shortPixelConvertImgToPictureAddWebp($content) {
|
|
158 |
//for AMP pages the <picture> tag is not allowed
|
159 |
return $content . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG is AMP -->' : '');
|
160 |
}
|
|
|
161 |
require_once('class/front/img-to-picture-webp.php');
|
|
|
162 |
return ShortPixelImgToPictureWebp::convert($content);// . "<!-- PICTURE TAGS BY SHORTPIXEL -->";
|
163 |
}
|
164 |
function shortPixelAddPictureJs() {
|
@@ -208,7 +212,7 @@ $option = get_option('wp-short-pixel-create-webp-markup');
|
|
208 |
if ( $option ) {
|
209 |
if(shortPixelIsPluginActive('shortpixel-adaptive-images/short-pixel-ai.php')) {
|
210 |
set_transient("shortpixel_thrown_notice", array('when' => 'spai', 'extra' => __('Please deactivate the ShortPixel Image Optimizer\'s
|
211 |
-
<a href="options-general.php?page=wp-shortpixel
|
212 |
option when the ShortPixel Adaptive Images plugin is active.','shortpixel-image-optimiser')), 1800);
|
213 |
}
|
214 |
elseif( $option == 1 ){
|
2 |
/**
|
3 |
* Plugin Name: ShortPixel Image Optimizer
|
4 |
* Plugin URI: https://shortpixel.com/
|
5 |
+
* Description: ShortPixel optimizes images automatically, while guarding the quality of your images. Check your <a href="options-general.php?page=wp-shortpixel-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.0
|
7 |
* Author: ShortPixel
|
8 |
* Author URI: https://shortpixel.com
|
9 |
* Text Domain: shortpixel-image-optimiser
|
10 |
* Domain Path: /lang
|
11 |
*/
|
12 |
|
13 |
+
if (! defined('SHORTPIXEL_RESET_ON_ACTIVATE'))
|
14 |
+
define('SHORTPIXEL_RESET_ON_ACTIVATE', false); //if true TODO set false
|
15 |
//define('SHORTPIXEL_DEBUG', true);
|
16 |
//define('SHORTPIXEL_DEBUG_TARGET', true);
|
17 |
|
19 |
|
20 |
//define('SHORTPIXEL_AFFILIATE_CODE', '');
|
21 |
|
22 |
+
define('SHORTPIXEL_IMAGE_OPTIMISER_VERSION', "4.14.0");
|
23 |
define('SHORTPIXEL_MAX_TIMEOUT', 10);
|
24 |
define('SHORTPIXEL_VALIDATE_MAX_TIMEOUT', 15);
|
25 |
define('SHORTPIXEL_BACKUP', 'ShortpixelBackups');
|
82 |
)
|
83 |
{
|
84 |
require_once('wp-shortpixel-req.php');
|
85 |
+
|
86 |
$shortPixelPluginInstance = new WPShortPixel;
|
87 |
}
|
88 |
|
160 |
//for AMP pages the <picture> tag is not allowed
|
161 |
return $content . (isset($_GET['SHORTPIXEL_DEBUG']) ? '<!-- SPDBG is AMP -->' : '');
|
162 |
}
|
163 |
+
require_once('wp-shortpixel-req.php');
|
164 |
require_once('class/front/img-to-picture-webp.php');
|
165 |
+
|
166 |
return ShortPixelImgToPictureWebp::convert($content);// . "<!-- PICTURE TAGS BY SHORTPIXEL -->";
|
167 |
}
|
168 |
function shortPixelAddPictureJs() {
|
212 |
if ( $option ) {
|
213 |
if(shortPixelIsPluginActive('shortpixel-adaptive-images/short-pixel-ai.php')) {
|
214 |
set_transient("shortpixel_thrown_notice", array('when' => 'spai', 'extra' => __('Please deactivate the ShortPixel Image Optimizer\'s
|
215 |
+
<a href="options-general.php?page=wp-shortpixel-settings&part=adv-settings">Deliver WebP using PICTURE tag</a>
|
216 |
option when the ShortPixel Adaptive Images plugin is active.','shortpixel-image-optimiser')), 1800);
|
217 |
}
|
218 |
elseif( $option == 1 ){
|