WebP Express - Version 0.8.0

Version Description

  • New conversion method, which calls imagick binary directly. This will make WebP express work out of the box on more systems
  • Made sure not to trigger LFI warning i Wordfence (to activate, click the force .htaccess button)
  • Imagick can now be configured to set quality to auto on systems where the auto option isn't generally available
  • Added Last-Modified header to images. This makes image caching work better
  • On some systems, converted files where stored in ie ..doc-rootwp-content.. rather than ..doc-root/wp-content... This is fixed, a clean-up script corrects the file structure upon upgrade.
  • Added condition in .htaccess that checks that source file exists before handing over to converter

For more info, see the closed issues on the 0.8.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0

Download this release

Release Info

Developer rosell.dk
Plugin Icon 128x128 WebP Express
Version 0.8.0
Comparing to
See all releases

Code changes from version 0.7.2 to 0.8.0

BACKERS.md ADDED
@@ -0,0 +1,38 @@
1
+ There are no backers yet. Become the first, by backing me up financially at patreon.com.
2
+ Your name will then appear here.
3
+
4
+ My page at patreon: https://www.patreon.com/rosell
5
+
6
+
7
+ ## Generous backers via Patron
8
+
9
+ There are no generous backers yet. [Be the first!](https://www.patreon.com/rosell)
10
+
11
+ Generous backers will get their names listed here, along with a message - max 100 chars, and it may contain one link (the link url does not count any chars).
12
+
13
+ Examples:
14
+
15
+ | Name | Date | Message (70 chars limit, one link allowed) |
16
+ | --------------------- | ---------- | ----------------------------------------------------------------------- |
17
+ | John Doe | 2018-11-23 | I have a similar plugin. [Check it out!](https://example.com/plugin)|
18
+ | John Doe 2 | 2018-11-23 | I do in fact sell shoes - with WebP Express logo! [Check it out!]((https://printed-shoes.com/) |
19
+
20
+ <small>
21
+ I reserve the right to disallow inappropriate messages and links. No xxx sites or anything freaky or fishy, please. You may however advertise non-freaky-or-fishy things, if you wish. Just remember the audience. No point in trying to sell shoes here</small>
22
+
23
+
24
+ ## Backers via Patron
25
+
26
+ There are no backers yet. [Be the first!](https://www.patreon.com/rosell)
27
+
28
+ Backers will get their names listed here, along with a message (max 70 chars, plain text only).
29
+
30
+ Examples:
31
+
32
+ | Name | Date | Message |
33
+ | --------------------- | ---------- | ----------------------------------------------------------------------- |
34
+ | John Doe | 2018-11-23 | Your children shouldn't just eat bananas. Buy some oranges too! |
35
+ | John Doe 2 | 2018-11-23 | Perhaps you could work on multisite support? |
36
+ | John Doe 3 | 2018-11-23 | Thank you. Your plugin changed my life! |
37
+
38
+ <small>I reserve the right to disallow inappropriate messages. No Trump hooting or bashing here, please. And don't be aggressive, obscene or anything unpleasant. But I don't have to point that out, do I?</small>
README.md CHANGED
@@ -12,11 +12,11 @@ The plugin basically routes jpeg/png images to an image converter, or - if the i
12
The plugin builds on [WebPConvert](https://github.com/rosell-dk/webp-convert) and its "WebP On Demand" solution described [here](https://github.com/rosell-dk/webp-convert/blob/master/docs/webp-on-demand/webp-on-demand.md)
13
14
#### Benefits
15
- - Much faster load time for images in blink based browsers such as Chrome and Opera (overall accounting for ~73% of all traffic, and ~78% of mobile browsing trafic, according to [caniuse.com](https://caniuse.com/webp)).
16
- - The converted images are typically *less than half the size* (for jpeg), while maintaining the same quality. Bear in mind that for most web sites, images are responsible for the largest part of the waiting time.
17
- Better user experience (whether performance goes from terrible to bad, or from good to impressive, it is a benefit)
18
- Better ranking in Google searches (performance is taken into account by Google)
19
- Less bandwidth consumption - makes a huge difference in the parts of the world where the internet is slow and costly (you know, ~80% of the world population lives under these circumstances).
20
21
22
## Installation
@@ -72,16 +72,63 @@ The redirect rules created in *.htaccess* are pointing to a PHP script. If you h
72
Do not simply remove the plugin without deactivating it first. Deactivation takes care of removing the rules in the *.htaccess* file. With the rules there, but converter gone, your Google Chrome visitors will not see any jpeg images.
73
74
*Note:*
75
- The plugin has not been tested in multisite configurations. It's on the roadmap...
76
77
78
## Limitations
79
80
- * The plugin does not work on Microsoft IIS server
81
* The plugin has not been tested with multisite installation
82
83
## Frequently Asked Questions
84
85
### Why do I not see the option to set WebP quality to auto?
86
The option will only display, if your system is able to detect jpeg qualities. To make your server capable to do that, install *Imagick* or *Gmagick*
87
@@ -90,15 +137,18 @@ Chances are that the default setting of your CDN is not to forward any headers t
90
91
The plugin takes care of setting the "Vary" HTTP header to "Accept" when routing WebP images. When the CDN sees this, it knows that the response varies, depending on the "Accept" header. The CDN is thus instructed not to cache the response on URL only, but also on the "Accept" header. This means that it will store an image for every accept header it meets. Luckily, there are (not that many variants for images)[https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values#Values_for_an_image], so it is not an issue.
92
93
- ### How do I donate?
94
- Putting this question in the "frequently" asked questions section is of course some mixture of humour, sarcasm and wishful thinking. In case there really is someone out there wanting to donate, you can simply write to me, and we can arrange. My contact information is available here https://www.bitwise-it.dk/contact. I have paypal, mobilepay and of course an ordinary bank account.
95
-
96
- ## Changes in 0.7.0
97
- This version added option to provide conversion service to other sites!
98
99
- For more info, see the closed issues on the 0.7.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.7.0
100
101
- ## Silly dance-ware
102
- If you enjoy this software, feel free to express yourself now through bodily movements. Don't - be - shy!
103
104
- *No animals were harmed and no women were sexually harassed either during the production of this plugin*
12
The plugin builds on [WebPConvert](https://github.com/rosell-dk/webp-convert) and its "WebP On Demand" solution described [here](https://github.com/rosell-dk/webp-convert/blob/master/docs/webp-on-demand/webp-on-demand.md)
13
14
#### Benefits
15
+ - Much faster load time for images in browsers that supports webp. The converted images are typically *less than half the size* (for jpeg), while maintaining the same quality. Bear in mind that for most web sites, images are responsible for the largest part of the waiting time.
16
- Better user experience (whether performance goes from terrible to bad, or from good to impressive, it is a benefit)
17
- Better ranking in Google searches (performance is taken into account by Google)
18
- Less bandwidth consumption - makes a huge difference in the parts of the world where the internet is slow and costly (you know, ~80% of the world population lives under these circumstances).
19
+ - Currently ~73% of all traffic, and ~78% of mobile browsing traffic are done with browsers supporting webp. With Mozilla and Microsoft [finally on board](https://medium.com/@richard_90141/webp-image-support-an-8-year-saga-7aa2bedb8d02), these numbers are bound to increase. Check current numbers on [caniuse.com](https://caniuse.com/webp)).
20
21
22
## Installation
72
Do not simply remove the plugin without deactivating it first. Deactivation takes care of removing the rules in the *.htaccess* file. With the rules there, but converter gone, your Google Chrome visitors will not see any jpeg images.
73
74
*Note:*
75
+ The plugin has not been tested in multisite configurations.
76
77
78
## Limitations
79
80
+ * The plugin does not work on Microsoft IIS server, nor in WAMP
81
* The plugin has not been tested with multisite installation
82
83
## Frequently Asked Questions
84
85
+ ### How do I verify that the plugin is working?
86
+ See the "Verifying that it works section"
87
+
88
+ ### No conversions methods are working out of the box
89
+ Don't fret - you have options!
90
+
91
+ - If you a controlling another WordPress site (where the local conversion methods DO work), you can set up WebP Express there, and then connect to it by configuring the “Remote WebP Express” conversion method.
92
+ - You can also setup the ewww conversion method. To use it, you need to purchase an api key. They do not charge credits for webp conversions, so all you ever have to pay is the one dollar start-up fee 🙂 (unless they change their pricing – I have no control over that). You can buy an api key here: https://ewww.io/plans/
93
+ - If you are up to it, you can try to get one of the local converters working. Check out [this page](https://github.com/rosell-dk/webp-convert/wiki/Meeting-the-requirements-of-the-converters) on the webp-convert wiki
94
+ - Finally, if you have access to a server and are comfortable with installing projects with composer, you can install [webp-convert-cloud-service](https://github.com/rosell-dk/webp-convert-cloud-service). It's open source.
95
+
96
+ ### It doesn't work - Although test conversions work, it still serves jpeg images.
97
+ Actually, you might be mistaking, so first, make sure that you didn't make the very common mistake of thinking that something with the URL *example.com/image.jpg* must be a jpeg image. The plugin serves webp images on same URL as the original (unconverted) images, so do not let appearances fool you! Confused? See next FAQ item.
98
+
99
+ Assuming that you have inspected the *content type* header, and it doesn't show "image/webp", please make sure that:
100
+ 1) You tested with a browser that supports webp (such as Chrome)
101
+ 2) The image URL you are looking at are not pointing to another server (such as gravatar.com)
102
+
103
+ Assuming that all above is in place, please look at the response headers to see if there is a *X-WebP-Convert-Status* header. If there isn't, well, then it seems that the problem is that the image request isn't handed over to WebP Express. Reasons for that can be:
104
+
105
+ - You are on NGINX (or an Apache/Nginx combination). NGINX requires special attention, please look at that FAQ item
106
+ - You are on WAMP. Please look at that FAQ item
107
+
108
+ I shall write more on this FAQ item... Stay tuned.
109
+
110
+ ### How can a webp image be served on an URL ending with "jpg"?
111
+ Easy enough. Browsers looks at the *content type* header rather than the URL to determine what it is that it gets. So, although it can be confusing that the resource at *example.com/image.jpg* is a webp image, rest asure that the browsers are not confused. To determine if the plugin is working, you must therefore examine the *content type* response header rather than the URL. See the "How do I verify that the plugin is working?" Faq item.
112
+
113
+ I am btw considering making an option to have the plugin redirect to the webp instead of serving immediately. That would remove the apparent mismatch between file extension and content type header. However, the cost of doing that will be an extra request for each image, which means extra time and worse performance. I believe you'd be ill advised to use that option, so I guess I will not implement it. But perhaps you have good reasons to use it? If you do, please let me know!
114
+
115
+ ### I am on NGINX / OpenResty
116
+ It is possible to make WebP Express work on NGINX, but it requieres manually inserting redirection rules in the NGINX configuration file (nginx.conf). For standard wordpress installations, the following rules should work:
117
+
118
+ ```
119
+ if ($http_accept ~* “webp”){
120
+ rewrite ^/(.*).(jpe?g|png)$ /wp-content/plugins/webp-express/wod/webp-on-demand.php?source=$document_root$request_uri&wp-content=wp-content&%1 break;
121
+ }
122
+ ```
123
+ However, the location of the wp-content folder and the plugins folder can be customized with Wordpress. In that case, the above rule must be changed accordingly.
124
+
125
+ I'd like to make the plugin print the NGINX rules that needs to be inserted, when running on NGINX / NGINX based setup (ie [OpenResty](https://openresty.org/en/)). Please help make that possible by [contributing](https://www.patreon.com/rosell).
126
+
127
+ Discussion on this topic here: https://wordpress.org/support/topic/nginx-rewrite-rules-4/
128
+
129
+ ### I am on a WAMP stack
130
+ It has been reported that WebP Express *almost* works on WAMP stack (Windows, Apache, MySQL, PHP). I'd love to debug this, but do not own a Windows server or access to one... Can you help?
131
+
132
### Why do I not see the option to set WebP quality to auto?
133
The option will only display, if your system is able to detect jpeg qualities. To make your server capable to do that, install *Imagick* or *Gmagick*
134
137
138
The plugin takes care of setting the "Vary" HTTP header to "Accept" when routing WebP images. When the CDN sees this, it knows that the response varies, depending on the "Accept" header. The CDN is thus instructed not to cache the response on URL only, but also on the "Accept" header. This means that it will store an image for every accept header it meets. Luckily, there are (not that many variants for images)[https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values#Values_for_an_image], so it is not an issue.
139
140
+ ## Changes in 0.8.0
141
+ - New conversion method, which calls imagick binary directly. This will make WebP express work out of the box on more systems
142
+ - Made sure not to trigger LFI warning i Wordfence (to activate, click the force .htaccess button)
143
+ - Imagick can now be configured to set quality to auto (but only when the "auto" option isn't generally available)
144
+ - Added Last-Modified header to images. This makes image caching work better
145
+ - On some systems, converted files where stored in ie *..doc-rootwp-content..* rather than *..doc-root/wp-content..*. This is fixed, a clean-up script corrects the file structure upon upgrade.
146
+ - Added condition in .htaccess that checks that source file exists before handing over to converter
147
148
+ For more info, see the closed issues on the 0.8.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0
149
150
+ ## Supporting WebP Express
151
+ Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue putting effort into this plugin:
152
153
+ - [Buy me a Coffee](https://ko-fi.com/rosell)
154
+ - [Become a backer or sponsor on Patreon](https://www.patreon.com/rosell).
README.txt CHANGED
@@ -1,10 +1,10 @@
1
=== WebP Express ===
2
Contributors: rosell.dk
3
- Donate link: https://www.patreon.com/rosell
4
Tags: webp, images, performance
5
Requires at least: 4.0
6
Tested up to: 5.0
7
- Stable tag: 0.7.2
8
Requires PHP: 5.6
9
License: GPLv3
10
License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -72,7 +72,9 @@ The plugin has not been tested in multisite configurations. It's on the roadmap.
72
== Supporting WebP Express ==
73
Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue wasting time on this plugin:
74
75
- *[Become a backer or sponsor on Patreon](https://www.patreon.com/rosell)*.
76
77
== Frequently Asked Questions ==
78
@@ -148,9 +150,8 @@ The plugin takes care of setting the "Vary" HTTP header to "Accept" when routing
148
https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values#Values_for_an_image
149
- so it is not an issue.
150
151
- = How do I donate? =
152
- Putting this question in the "frequently" asked questions section is of course some mixture of humour, sarcasm and wishful thinking. In case there really is someone out there wanting to donate, you can simply write to me, and we can arrange. My contact information is available here https://www.bitwise-it.dk/contact. I have paypal, mobilepay and of course an ordinary bank account.
153
-
154
155
== Screenshots ==
156
@@ -158,6 +159,16 @@ Putting this question in the "frequently" asked questions section is of course s
158
159
== Changelog ==
160
161
= 0.7.2 =
162
Fixed a critical bug which generated an error message which caused corrupt images. It was not the bug itself, but the error message it generated, that caused the images to be corrupted. It only happened when debugging was enabled in php.ini
163
@@ -213,5 +224,5 @@ For older releases, check out changelog.txt
213
214
== Upgrade Notice ==
215
216
- = 0.7.1 =
217
- This version added option to provide conversion service to other sites!
1
=== WebP Express ===
2
Contributors: rosell.dk
3
+ Donate link: https://ko-fi.com/rosell
4
Tags: webp, images, performance
5
Requires at least: 4.0
6
Tested up to: 5.0
7
+ Stable tag: 0.8.0
8
Requires PHP: 5.6
9
License: GPLv3
10
License URI: https://www.gnu.org/licenses/gpl-3.0.html
72
== Supporting WebP Express ==
73
Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue wasting time on this plugin:
74
75
+ * [Buy me a Coffee](https://ko-fi.com/rosell)
76
+ * [Become a backer or sponsor on Patreon](https://www.patreon.com/rosell)
77
+
78
79
== Frequently Asked Questions ==
80
150
https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values#Values_for_an_image
151
- so it is not an issue.
152
153
+ = How do I buy you a cup of coffee? =
154
+ Easy enough! - [Go here!](https://ko-fi.com/rosell)
155
156
== Screenshots ==
157
159
160
== Changelog ==
161
162
+ = 0.8.0 =
163
+ * New conversion method, which calls imagick binary directly. This will make WebP express work out of the box on more systems
164
+ * Made sure not to trigger LFI warning i Wordfence (to activate, click the force .htaccess button)
165
+ * Imagick can now be configured to set quality to auto on systems where the auto option isn't generally available
166
+ * Added Last-Modified header to images. This makes image caching work better
167
+ * On some systems, converted files where stored in ie *..doc-rootwp-content..* rather than *..doc-root/wp-content..*. This is fixed, a clean-up script corrects the file structure upon upgrade.
168
+ * Added condition in .htaccess that checks that source file exists before handing over to converter
169
+
170
+ For more info, see the closed issues on the 0.8.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0
171
+
172
= 0.7.2 =
173
Fixed a critical bug which generated an error message which caused corrupt images. It was not the bug itself, but the error message it generated, that caused the images to be corrupted. It only happened when debugging was enabled in php.ini
174
224
225
== Upgrade Notice ==
226
227
+ = 0.8.0 =
228
+ New converter and miscellaneous improvements
changelog.txt CHANGED
@@ -1,3 +1,13 @@
1
= 0.7.2 =
2
Fixed a critical bug which generated an error message which caused corrupt images. It was not the bug itself, but the error message it generated, that caused the images to be corrupted. It only happened when debugging was enabled in php.ini
3
1
+ = 0.8.0 =
2
+ * New conversion method, which calls imagick binary directly. This will make WebP express work out of the box on more systems
3
+ * Made sure not to trigger LFI warning i Wordfence (to activate, click the force .htaccess button)
4
+ * Imagick can now be configured to set quality to auto on systems where the auto option isn't generally available
5
+ * Added Last-Modified header to images. This makes image caching work better
6
+ * Added condition in .htaccess that checks that source file exists before handing over to converter
7
+ * On some systems, converted files where stored in ie *..doc-rootwp-content..* rather than *..doc-root/wp-content..*. This is fixed, a clean-up script corrects the file structure upon upgrade.
8
+
9
+ For more info, see the closed issues on the 0.8.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0
10
+
11
= 0.7.2 =
12
Fixed a critical bug which generated an error message which caused corrupt images. It was not the bug itself, but the error message it generated, that caused the images to be corrupted. It only happened when debugging was enabled in php.ini
13
docs/development.md ADDED
@@ -0,0 +1,3 @@
1
+ The plugin published on github now uses composer. I still include the vendor files on the svn (the Wordpress "codex").
2
+
3
+ For the few, who might be using this thing here on github: To get the dependent libraries, you need to cd into the plugin dir and run `composer update`. This gets you the latest dev releases of "webp-convert" and "webp-convert-cloud-service" on github. You must change the composer.json if you rather want the latest stable release (remove the repositories and change the minimum requirements). On the svn, I simply rsync everything, including the vendor folder, before committing.
lib/admin.php CHANGED
@@ -2,13 +2,15 @@
2
use \WebPExpress\State;
3
4
// When an update requires a migration, the number should be increased
5
- define('WEBPEXPRESS_MIGRATION_VERSION', '2');
6
7
if (WEBPEXPRESS_MIGRATION_VERSION != get_option('webp-express-migration-version', 0)) {
8
// run migration logic
9
include __DIR__ . '/migrate/migrate.php';
10
}
11
12
// uncomment next line to debug an error during activation
13
//include __DIR__ . "/debug.php";
14
@@ -45,72 +47,7 @@ register_uninstall_hook(WEBPEXPRESS_PLUGIN, 'webp_express_uninstall');
45
add_filter('plugin_action_links_' . plugin_basename(WEBPEXPRESS_PLUGIN), function ( $links ) {
46
$mylinks = array(
47
'<a href="' . admin_url( 'options-general.php?page=webp_express_settings_page' ) . '">Settings</a>',
48
);
49
return array_merge($links, $mylinks);
50
});
51
-
52
- add_action('wp_ajax_webpexpress_start_listening', 'webpexpress_start_listening');
53
- function webpexpress_start_listening() {
54
- include_once __DIR__ . '/classes/State.php';
55
- State::setState('listening', true);
56
- State::setState('request', null);
57
- wp_die();
58
- }
59
-
60
- add_action('wp_ajax_webpexpress_stop_listening', 'webpexpress_stop_listening');
61
- function webpexpress_stop_listening() {
62
- include_once __DIR__ . '/classes/State.php';
63
- State::setState('listening', false);
64
- State::setState('request', null);
65
- wp_die();
66
- }
67
-
68
- add_action('wp_ajax_webpexpress_get_request', 'webpexpress_get_request');
69
- function webpexpress_get_request() {
70
- include_once __DIR__ . '/classes/State.php';
71
- echo json_encode(State::getState('request', null), JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
72
- wp_die();
73
- }
74
-
75
- add_action('wp_ajax_webpexpress_request_access', 'webpexpress_request_access');
76
- function webpexpress_request_access() {
77
-
78
- $ch = curl_init();
79
-
80
- curl_setopt_array(
81
- $ch,
82
- [
83
- CURLOPT_URL => 'http://we0/wordpress/webp-express-server',
84
- CURLOPT_HTTPHEADER => [
85
- 'User-Agent: WebPConvert',
86
- ],
87
- CURLOPT_POSTFIELDS => [
88
- 'action' => 'request-access',
89
- 'label' => 'test',
90
- 'key' => 'test-key'
91
- ],
92
- CURLOPT_RETURNTRANSFER => true,
93
- CURLOPT_HEADER => false,
94
- CURLOPT_SSL_VERIFYPEER => false
95
- ]
96
- );
97
- $response = curl_exec($ch);
98
- if (curl_errno($ch)) {
99
- }
100
-
101
- $returnObj = [
102
- 'success' => true
103
- ];
104
- echo json_encode($returnObj, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
105
-
106
- wp_die();
107
- }
108
- /*
109
- add_action('wp_ajax_webpexpress_accept_request', 'webpexpress_accept_request');
110
- function webpexpress_accept_request() {
111
- include_once __DIR__ . '/classes/State.php';
112
-
113
- State::setState('listening', true);
114
- State::setState('request', null);
115
- wp_die();
116
- }*/
2
use \WebPExpress\State;
3
4
// When an update requires a migration, the number should be increased
5
+ define('WEBPEXPRESS_MIGRATION_VERSION', '3');
6
7
if (WEBPEXPRESS_MIGRATION_VERSION != get_option('webp-express-migration-version', 0)) {
8
// run migration logic
9
include __DIR__ . '/migrate/migrate.php';
10
}
11
12
+ // include __DIR__ . '/migrate/migrate3.php'; // test-running a migration
13
+
14
// uncomment next line to debug an error during activation
15
//include __DIR__ . "/debug.php";
16
47
add_filter('plugin_action_links_' . plugin_basename(WEBPEXPRESS_PLUGIN), function ( $links ) {
48
$mylinks = array(
49
'<a href="' . admin_url( 'options-general.php?page=webp_express_settings_page' ) . '">Settings</a>',
50
+ '<a href="https://ko-fi.com/rosell" target="_blank">Buy the maintainer a cup of coffee</a>',
51
);
52
return array_merge($links, $mylinks);
53
});
lib/classes/Config.php CHANGED
@@ -106,6 +106,9 @@ class Config
106
unset ($c['id']);
107
unset($c['working']);
108
unset($c['error']);
109
if (!isset($c['options'])) {
110
$c = $c['converter'];
111
}
106
unset ($c['id']);
107
unset($c['working']);
108
unset($c['error']);
109
+ if (isset($c['options']['quality']) && ($c['options']['quality'] == 'inherit')) {
110
+ unset ($c['options']['quality']);
111
+ }
112
if (!isset($c['options'])) {
113
$c = $c['converter'];
114
}
lib/classes/ConvertersHelper.php CHANGED
@@ -7,7 +7,7 @@ class ConvertersHelper
7
public static $defaultConverters = [
8
['converter' => 'gd', 'options' => ['skip-pngs' => true]],
9
['converter' => 'cwebp', 'options' => [
10
- 'use-nice' => false,
11
'try-common-system-paths' => true,
12
'try-supplied-binary-for-os' => true,
13
'method' => 6,
@@ -17,8 +17,11 @@ class ConvertersHelper
17
]],
18
['converter' => 'imagick'],
19
['converter' => 'gmagick'],
20
- ['converter' => 'wpc', 'options' => ['quality' => 'auto']], // we should not set api-version default - it is handled in the javascript
21
['converter' => 'ewww'],
22
];
23
24
public static function getDefaultConverterNames()
7
public static $defaultConverters = [
8
['converter' => 'gd', 'options' => ['skip-pngs' => true]],
9
['converter' => 'cwebp', 'options' => [
10
+ 'use-nice' => true,
11
'try-common-system-paths' => true,
12
'try-supplied-binary-for-os' => true,
13
'method' => 6,
17
]],
18
['converter' => 'imagick'],
19
['converter' => 'gmagick'],
20
+ ['converter' => 'wpc'], // we should not set api-version default - it is handled in the javascript
21
['converter' => 'ewww'],
22
+ ['converter' => 'imagickbinary', 'options' => [
23
+ 'use-nice' => true,
24
+ ]],
25
];
26
27
public static function getDefaultConverterNames()
lib/classes/FileHelper.php CHANGED
@@ -160,4 +160,27 @@ class FileHelper
160
}
161
return $return;
162
}
163
}
160
}
161
return $return;
162
}
163
+
164
+
165
+ /* Remove dir and files in it recursively.
166
+ No warnings
167
+ returns $success
168
+ */
169
+ public static function rrmdir($dir) {
170
+ if (@is_dir($dir)) {
171
+ $objects = @scandir($dir);
172
+ foreach ($objects as $object) {
173
+ if ($object != "." && $object != "..") {
174
+ if (@is_dir($dir . "/" . $object))
175
+ self::rrmdir($dir . "/" . $object);
176
+ else
177
+ @unlink($dir . "/" . $object);
178
+ }
179
+ }
180
+ return @rmdir($dir);
181
+ } else {
182
+ return false;
183
+ }
184
+ }
185
+
186
}
lib/classes/HTAccess.php CHANGED
@@ -60,12 +60,13 @@ class HTAccess
60
61
$rules .= " # Redirect images to webp-on-demand.php (if browser supports webp)\n";
62
$rules .= " RewriteCond %{HTTP_ACCEPT} image/webp\n";
63
if ($config['forward-query-string']) {
64
$rules .= " RewriteCond %{QUERY_STRING} (.*)\n";
65
}
66
$rules .= " RewriteRule ^(.*)\.(" . $fileExt . ")$ " .
67
"/" . Paths::getWodUrlPath() .
68
- "?source=%{SCRIPT_FILENAME}" .
69
"&wp-content=" . Paths::getWPContentDirRel() .
70
($config['forward-query-string'] ? '&%1' : '') .
71
" [NC,L]\n";
60
61
$rules .= " # Redirect images to webp-on-demand.php (if browser supports webp)\n";
62
$rules .= " RewriteCond %{HTTP_ACCEPT} image/webp\n";
63
+ $rules .= " RewriteCond %{REQUEST_FILENAME} -f\n";
64
if ($config['forward-query-string']) {
65
$rules .= " RewriteCond %{QUERY_STRING} (.*)\n";
66
}
67
$rules .= " RewriteRule ^(.*)\.(" . $fileExt . ")$ " .
68
"/" . Paths::getWodUrlPath() .
69
+ "?xsource=x%{SCRIPT_FILENAME}" .
70
"&wp-content=" . Paths::getWPContentDirRel() .
71
($config['forward-query-string'] ? '&%1' : '') .
72
" [NC,L]\n";
lib/classes/Paths.php CHANGED
@@ -115,18 +115,21 @@ class Paths
115
}
116
117
// ------------ Upload Dir -------------
118
- // (can be moved out of wp-content dir. But not (rarely? - I suppose someone could enter dots) out of abspath)
119
120
public static function getUploadDirAbs()
121
{
122
- // Pst: When supporting multisite, we could use wp_upload_dir instead
123
- // https://developer.wordpress.org/reference/functions/wp_upload_dir/
124
if ( defined( 'UPLOADS' ) ) {
125
return ABSPATH . rtrim(UPLOADS, '/');
126
} else {
127
return self::getWPContentDirAbs() . '/uploads';
128
}
129
- }
130
131
public static function isUploadDirMovedOutOfWPContentDir()
132
{
@@ -313,7 +316,8 @@ APACHE
313
],
314
'filePaths' => [
315
'webpExpressRoot' => self::getWebPExpressPluginDirAbs(),
316
- 'destinationRoot' => self::getCacheDirAbs()
317
]
318
];
319
}
115
}
116
117
// ------------ Upload Dir -------------
118
+ public static function getUploadDirAbs()
119
+ {
120
+ $upload_dir = wp_upload_dir(null, false);
121
+ return $upload_dir['basedir'];
122
+ }
123
124
+ /*
125
public static function getUploadDirAbs()
126
{
127
if ( defined( 'UPLOADS' ) ) {
128
return ABSPATH . rtrim(UPLOADS, '/');
129
} else {
130
return self::getWPContentDirAbs() . '/uploads';
131
}
132
+ }*/
133
134
public static function isUploadDirMovedOutOfWPContentDir()
135
{
316
],
317
'filePaths' => [
318
'webpExpressRoot' => self::getWebPExpressPluginDirAbs(),
319
+ 'destinationRoot' => self::getCacheDirAbs(),
320
+ 'configRelToDocRoot' => self::getConfigDirRel()
321
]
322
];
323
}
lib/migrate/migrate.php CHANGED
@@ -3,7 +3,6 @@
3
include_once __DIR__ . '/../classes/State.php';
4
use \WebPExpress\State;
5
6
-
7
/*
8
In 0.4.0, we had a 'webp-express-configured' option.
9
As long as there are still users on 0.4 or below, we must do the following:
@@ -42,10 +41,10 @@ if (!(State::getState('configured', false))) {
42
include __DIR__ . '/migrate2.php';
43
}
44
45
- /*
46
// We make sure to grab the option again - it might have been changed in the migration above
47
if (intval(get_option('webp-express-migration-version', 0)) == 2) {
48
- // run migration 2
49
include __DIR__ . '/migrate3.php';
50
- }*/
51
}
3
include_once __DIR__ . '/../classes/State.php';
4
use \WebPExpress\State;
5
6
/*
7
In 0.4.0, we had a 'webp-express-configured' option.
8
As long as there are still users on 0.4 or below, we must do the following:
41
include __DIR__ . '/migrate2.php';
42
}
43
44
+
45
// We make sure to grab the option again - it might have been changed in the migration above
46
if (intval(get_option('webp-express-migration-version', 0)) == 2) {
47
+ // run migration 3
48
include __DIR__ . '/migrate3.php';
49
+ }
50
}
lib/migrate/migrate3.php CHANGED
@@ -1,66 +1,127 @@
1
<?php
2
- /*
3
namespace WebPExpress;
4
5
- include_once __DIR__ . '/../classes/Config.php';
6
- use \WebPExpress\Config;
7
8
include_once __DIR__ . '/../classes/Paths.php';
9
use \WebPExpress\Paths;
10
11
include_once __DIR__ . '/../classes/Messenger.php';
12
use \WebPExpress\Messenger;
13
14
- include_once __DIR__ . '/../classes/TestRun.php';
15
- use \WebPExpress\TestRun;
16
17
function webpexpress_migrate3() {
18
19
- $changedSomething = false;
20
- $config = Config::loadConfig();
21
- if ($config !== false) {
22
- if (isset($config['converters'])) {
23
- foreach ($config['converters'] as &$converter) {
24
- if (isset($converter['converter']) && ($converter['converter'] == 'wpc') && (isset($converter['options']))) {
25
- if (isset($converter['options']['secret'])) {
26
- $converter['options']['api-key'] = $converter['options']['secret'];
27
- unset($converter['options']['secret']);
28
- $converter['options']['api-version'] = 0;
29
- } else {
30
- $converter['options']['api-version'] = 1;
31
- }
32
-
33
- unset($converter['options']['url-2']);
34
- unset($converter['options']['secret-2']);
35
-
36
- $changedSomething = true;
37
-
38
- }
39
}
40
- if ($changedSomething) {
41
- if (Config::saveConfigurationFileAndWodOptions($config)) {
42
- Messenger::addMessage(
43
- 'info',
44
- 'WebP Express successfully migrated configuration file to 0.7.0 format'
45
- );
46
- } else {
47
- Messenger::addMessage(
48
- 'warning',
49
- 'WebP Express could not migrated configuration files to 0.7.0 format, because it failed saving the files. ' .
50
- 'If you use the wpc converter, you should change the configuration files manually (located in wp-content/webp-express/config). ' .
51
- 'You should change "secret" to "api-key"'
52
- );
53
- return;
54
- }
55
}
56
}
57
}
58
59
- // PSST: When creating new migration files, remember to update WEBPEXPRESS_MIGRATION_VERSION in admin.php
60
61
update_option('webp-express-migration-version', '3');
62
63
}
64
65
webpexpress_migrate3();
66
- */
1
<?php
2
+
3
namespace WebPExpress;
4
5
+
6
+ include_once __DIR__ . '/../classes/FileHelper.php';
7
+ use \WebPExpress\FileHelper;
8
9
include_once __DIR__ . '/../classes/Paths.php';
10
use \WebPExpress\Paths;
11
12
+ include_once __DIR__ . '/../classes/PathHelper.php';
13
+ use \WebPExpress\PathHelper;
14
+
15
include_once __DIR__ . '/../classes/Messenger.php';
16
use \WebPExpress\Messenger;
17
18
+
19
+ if ( ! function_exists('webp_express_glob_recursive'))
20
+ {
21
+ // Does not support flag GLOB_BRACE
22
+
23
+ function webp_express_glob_recursive($pattern, $flags = 0)
24
+ {
25
+ $files = glob($pattern, $flags);
26
+
27
+ foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir)
28
+ {
29
+ $files = array_merge($files, webp_express_glob_recursive($dir.'/'.basename($pattern), $flags));
30
+ }
31
+
32
+ return $files;
33
+ }
34
+ }
35
36
function webpexpress_migrate3() {
37
38
+ $dirs = glob(PathHelper::canonicalize(Paths::getCacheDirAbs()) . '/doc-root*');
39
+
40
+ $movedAtLeastOneFile = false;
41
+ $failedMovingAtLeastOneFile = false;
42
+ $atLeastOneFileMustBeMoved = false;
43
+ $failedRemovingAtLeastOneDir = false;
44
+
45
+ foreach ($dirs as $dir) {
46
+ if (preg_match('/\/doc-root#x2F;i', $dir)) {
47
+ // do not process the "doc-root" dir
48
+ continue;
49
+ }
50
+
51
+ $files = webp_express_glob_recursive($dir . '/*.webp');
52
+ foreach ($files as $file) {
53
+ $atLeastOneFileMustBeMoved = true;
54
+ $newName = preg_replace('/\/doc-root(.*)#x2F;', '/doc-root/$1', $file);
55
+ $dirName = FileHelper::dirName($newName);
56
+ if (!file_exists($dirName)) {
57
+ mkdir($dirName, 0775, true);
58
}
59
+ if (@rename($file, $newName)) {
60
+ $movedAtLeastOneFile = true;
61
+ } else {
62
+ $failedMovingAtLeastOneFile = true;
63
}
64
}
65
+
66
+ if (!FileHelper::rrmdir($dir)) {
67
+ $failedRemovingAtLeastOneDir = true;
68
+ }
69
+ }
70
+
71
+
72
+ if ($atLeastOneFileMustBeMoved) {
73
+ if ($movedAtLeastOneFile && !$failedMovingAtLeastOneFile && !$failedRemovingAtLeastOneDir) {
74
+ Messenger::addMessage(
75
+ 'info',
76
+ 'Successfully fixed cache directory structure. Dont know what its all about? Never mind, all is okay.'
77
+ );
78
+ } else {
79
+ if ($failedRemovingAtLeastOneDir) {
80
+ Messenger::addMessage(
81
+ 'warning',
82
+ 'A minor bug caused the cache directory structure to be wrong on your system ' .
83
+ '(<a href="https://github.com/rosell-dk/webp-express/issues/96" target="_blank">issue #96</a>). ' .
84
+ 'The bug has been fixed, but unfortunately the file permissions does not allow WebP Convert to clean up the file structure. ' .
85
+ 'To clean up manually, delete all folders in your wp-content/webp-express/webp-images folder beginning with "doc-root" (but not the "doc-root" folder itself)'
86
+ );
87
+ }
88
+ }
89
+ }
90
+
91
+ // Show "Whats new" message.
92
+ // We test the version, because we do not want a whole lot of "whats new" messages
93
+ // to show when updating many versions in one go. Just the recent, please.
94
+ if (WEBPEXPRESS_MIGRATION_VERSION == '3') {
95
+ Messenger::addMessage(
96
+ 'info',
97
+ '<i>New in WebP Express 0.8.0:</i>' .
98
+ '<ul style="list-style-type:disc;margin-left:20px">' .
99
+ '<li>New conversion method, which calls imagick binary directly</li>' .
100
+ '<li>Made sure not to trigger LFI warning i Wordfence (to activate, click the force .htaccess button)</li>' .
101
+ "<li>Imagick can now be configured to set quality to auto on systems where the auto option isn't generally available</li>" .
102
+ '<li><a href="https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0">and more...</a></li>' .
103
+ '</ul>' .
104
+ '</ul>' .
105
+ '<br><i>Roadmap / wishlist:</i>' .
106
+ '<ul style="list-style-type:disc;margin-left:20px">' .
107
+ '<li>Rule in .htaccess to serve already converted images immediately (optional)</li>' .
108
+ '<li>Better NGINX support (print rules that needs to be manually inserted in nginx.conf)</li>' .
109
+ '<li>Diagnose button</li>' .
110
+ '<li>A file explorer for viewing converted images, reconverting them, and seeing them side by side with the original</li>' .
111
+ '<li>IIS support, WAMP support, Multisite support</li>' .
112
+ '<li><a href="https://github.com/rosell-dk/webp-express/issues">and more...</a></li>' .
113
+ '</ul>' .
114
+ '<b>Please help me making this happen faster / happen at all by donating even a small sum. ' .
115
+ '<a href="https://ko-fi.com/rosell" target="_blank" >Buy me a coffee</a>, ' .
116
+ 'or support me on <a href="http://www.patreon.com/rosell" target="_blank" >patreon.com</a>' .
117
+ '</b>'
118
+ );
119
}
120
121
122
+ // PSST: When creating new migration files, remember to update WEBPEXPRESS_MIGRATION_VERSION in admin.php
123
update_option('webp-express-migration-version', '3');
124
125
}
126
127
webpexpress_migrate3();
lib/options/converter-options/cwebp.php ADDED
@@ -0,0 +1,61 @@
1
+ <div id="cwebp" style="display:none;">
2
+ <div class="cwebp converter-options">
3
+ <h3>cweb options</h3>
4
+ <div>
5
+ <label for="cwebp_use_nice">Use nice</label>
6
+ <input type="checkbox" id="cwebp_use_nice">
7
+ <br>Enabling this option saves system resources at the cost of slightly slower conversion
8
+ </div>
9
+ <div>
10
+ <label for="cwebp_try_common_system_paths">Try to execute cweb binary at common locations</label>
11
+ <input type="checkbox" id="cwebp_try_common_system_paths">
12
+ <br>If checked, we will look for binaries in common locations, such as <i>/usr/bin/cwebp</i>
13
+ </div>
14
+ <div>
15
+ <label for="cwebp_try_common_system_paths">Try precompiled cwebp</label>
16
+ <input type="checkbox" id="cwebp_try_supplied_binary">
17
+ <br>This plugin ships with precompiled cweb binaries for different platforms. If checked, and we have a precompiled binary for your OS, we will try to exectute it
18
+ </div>
19
+ <div>
20
+ <label for="cwebp_method">Method (0-6)</label>
21
+ <input type="text" size="2" id="cwebp_method">
22
+ <br>This parameter controls the trade off between encoding speed and the compressed file size and quality.
23
+ Possible values range from 0 to 6. 0 is fastest. 6 results in best quality.
24
+ </div>
25
+ <div>
26
+ <label for="cwebp_set_size">Set size option (and ignore quality option)</label>
27
+ <input type="checkbox" id="cwebp_set_size">
28
+ <br>This option activates the size option below.
29
+ <?php
30
+ if ($canDetectQuality) {
31
+ echo 'As you have quality detection working on your server, it is probably best to use that, rather ';
32
+ echo 'than the "size" option. Using the size option takes more ressources (it takes about 2.5 times ';
33
+ echo 'longer for cwebp to do a a conversion with the size option than the quality option). Long ';
34
+ echo 'story short, you should probably <i>not</i> activate the size option.';
35
+ } else {
36
+ echo 'As you do not have quality detection working on your server, it is probably a good ';
37
+ echo 'idea to use the size option to avoid making conversions with a higher quality setting ';
38
+ echo 'than the source image. ';
39
+ echo 'Beware, though, that cwebp takes about 2.5 times longer to do a a conversion with the size option set.';
40
+ }
41
+ ?>
42
+ </div>
43
+ <div>
44
+ <label for="cwebp_size_in_percentage">Size (in percentage of source)</label>
45
+ <input type="text" size="2" id="cwebp_size_in_percentage">
46
+ <br>Set the cwebp should aim for, in percentage of the original.
47
+ Usually cwebp can reduce to ~45% of original without loosing quality.
48
+ </div>
49
+ <div>
50
+ <label for="cwebp_command_line_options">Extra command line options</label><br>
51
+ <input type="text" size="40" id="cwebp_command_line_options" style="width:100%">
52
+ <br>This allows you to set any parameter available for cwebp in the same way as
53
+ you would do when executing <i>cwebp</i>. As a syntax example, you could ie. set it to
54
+ "-low_memory -af -f 50 -sharpness 0 -mt -crop 10 10 40 40" (do not include the quotes).
55
+ Read more about all the available parameters in
56
+ <a target="_blank" href="https://developers.google.com/speed/webp/docs/cwebp">the docs</a>
57
+ </div>
58
+ <br>
59
+ <?php webp_express_printUpdateButtons() ?>
60
+ </div>
61
+ </div>
lib/options/converter-options/ewww.php ADDED
@@ -0,0 +1,23 @@
1
+ <div id="ewww" style="display:none;">
2
+ <div class="ewww converter-options">
3
+ <h3>Ewww</h3>
4
+ <p>
5
+ ewww is a cloud service for converting images.
6
+ To use it, you need to purchase a key <a target="_blank" href="https://ewww.io/plans/">here</a>.
7
+ They do not charge credits for webp conversions, so all you ever have to pay is the one dollar start-up fee :)
8
+ </p>
9
+ <h3>Options</h3>
10
+ <div>
11
+ <label for="ewww_key">Key</label>
12
+ <input type="text" id="ewww_key" placeholder="Your API key here">
13
+ </div>
14
+ <br>
15
+ <h4>Fallback (optional)</h4>
16
+ <div>
17
+ <label for="ewww_key_2">key</label>
18
+ <input type="text" id="ewww_key_2" placeholder="In case the first one expires...">
19
+ </div>
20
+ <br>
21
+ <?php webp_express_printUpdateButtons() ?>
22
+ </div>
23
+ </div>
lib/options/converter-options/gd.php ADDED
@@ -0,0 +1,14 @@
1
+ <div id="gd" style="display:none;">
2
+ <div class="gd converter-options">
3
+ <h3>Gd options</h3>
4
+ <div>
5
+ <label for="gd_skip_pngs">Skip PNGs</label>
6
+ <input type="checkbox" id="gd_skip_pngs">
7
+ <br>Gd is not suited for converting PNGs into webp. &ndash;
8
+ The filesize is generally much larger than the original.
9
+ For this reason, the converter defaults to skip PNG's.
10
+ </div>
11
+ <br>
12
+ <?php webp_express_printUpdateButtons() ?>
13
+ </div>
14
+ </div>
lib/options/converter-options/imagick.php ADDED
@@ -0,0 +1,17 @@
1
+ <div id="imagick" style="display:none;">
2
+ <div class="imagick converter-options">
3
+ <h3>Imagick options</h3>
4
+ <?php
5
+ if ($canDetectQuality) {
6
+ echo '<div class="info">imagick has no special options.</div>';
7
+ } else {
8
+ echo '<br>';
9
+ printAutoQualityOptionForConverter('imagick');
10
+ }
11
+ ?>
12
+ <!--
13
+ <button onclick="updateConverterOptions()" class="button button-primary" type="button">Update</button>
14
+ -->
15
+ <!-- <a href="javascript: tb_remove();">close</a> -->
16
+ </div>
17
+ </div>
lib/options/converter-options/imagickbinary.php ADDED
@@ -0,0 +1,24 @@
1
+ <div id="imagickbinary" style="display:none;">
2
+ <div class="imagickbinary converter-options">
3
+
4
+ <h3>Imagick binary options</h3>
5
+ <p>This conversion method works by executing imagick binary (the 'convert' command).</p>
6
+
7
+ <div>
8
+ <label for="imagickbinary_use_nice">Use nice</label>
9
+ <input type="checkbox" id="imagickbinary_use_nice">
10
+ <br>Enabling this option saves system resources at the cost of slightly slower conversion
11
+ </div>
12
+
13
+ <?php
14
+ if (!$canDetectQuality) {
15
+ printAutoQualityOptionForConverter('imagickbinary');
16
+ }
17
+ ?>
18
+ <!--
19
+ <button onclick="updateConverterOptions()" class="button button-primary" type="button">Update</button>
20
+ -->
21
+ <!-- <a href="javascript: tb_remove();">close</a> -->
22
+ <?php webp_express_printUpdateButtons() ?>
23
+ </div>
24
+ </div>
lib/options/converter-options/wpc.php ADDED
@@ -0,0 +1,86 @@
1
+ <div id="wpc" style="display:none;">
2
+ <div class="wpc converter-options">
3
+ <h3>Remote WebP Express</h3>
4
+ Use a WebP Express installed on another Wordpress site to convert. Remote WepP Express is based
5
+ on <a href="https://github.com/rosell-dk/webp-convert-cloud-service" target="blank">WPC</a>,
6
+ and you can use it to connect to WPC as well.
7
+
8
+ <?php
9
+ if ((!extension_loaded('curl')) || (!function_exists('curl_init'))) {
10
+ echo '<p><b style="color:red">Your server does not have curl installed. Curl is required!</b></p>';
11
+ }
12
+ ?>
13
+
14
+ <h3>Options</h3>
15
+ <!--
16
+ <div>
17
+ <label for="wpc_web_services">Web Services</label>
18
+ <div style="display:inline-block">
19
+ <div id="wpc_web_services_div"></div>
20
+ <button type="button" id="wpc_web_services_request" onclick="openWpcConnectPopup()" class="button button-secondary" >Add web service</button>
21
+ </div>
22
+ </div>
23
+ -->
24
+
25
+ <div id="wpc_api_version_div">
26
+ <label for="wpc_api_version">
27
+ Api version
28
+ <?php echo helpIcon('Select 1, if connecting to a remote webp-express. Api 0 was never used with this plugin, and should only be used to connect to webp-convert-cloud-service v.0.1 instances'); ?>
29
+ </label>
30
+ <select id="wpc_api_version" onchange="wpcApiVersionChanged()">
31
+ <option value="0">0</option>
32
+ <option value="1">1</option>
33
+ </select>
34
+ </div>
35
+
36
+ <div>
37
+ <label for="wpc_url">
38
+ URL
39
+ <?php echo helpIcon('The endpoint of the web service. Copy it from the remote setup.'); ?>
40
+ </label>
41
+ <input type="text" id="wpc_url" placeholder="Url to your Remote WebP Express">
42
+ </div>
43
+
44
+ <div id="wpc_secret_div">
45
+ <label for="wpc_secret">
46
+ Secret
47
+ <?php echo helpIcon('Must match the one set up in webp-convert-cloud-service v0.1'); ?>
48
+ </label>
49
+ <input type="text" id="wpc_secret" placeholder="">
50
+ </div>
51
+
52
+ <div id="wpc_api_key_div">
53
+ <label id="wpc_api_key_label_1" for="wpc_api_key">
54
+ Secret
55
+ <?php echo helpIcon('The secret set up on the wpc server. Copy that.'); ?>
56
+ </label>
57
+ <label id="wpc_api_key_label_2" for="wpc_api_key">
58
+ Api key
59
+ <?php echo helpIcon('The API key is set up on the remote. Copy that.'); ?>
60
+ </label>
61
+ <input id="wpc_new_api_key" type="password">
62
+ <a id="wpc_change_api_key" href="javascript:wpcChangeApiKey()">
63
+ Click to change
64
+ </a>
65
+ </div>
66
+
67
+ <div id="wpc_crypt_api_key_in_transfer_div">
68
+ <label for="wpc_crypt_api_key_in_transfer">
69
+ Crypt api key in transfer?
70
+ <?php echo helpIcon('If checked, the api key will be crypted in requests. Crypting the api-key protects it from being stolen during transfer.'); ?>
71
+ </label>
72
+ <input id="wpc_crypt_api_key_in_transfer" type="checkbox">
73
+ </div>
74
+
75
+ <?php
76
+ if (!$canDetectQuality) {
77
+ printAutoQualityOptionForConverter('wpc');
78
+ }
79
+ ?>
80
+
81
+ <p>
82
+ <b>Psst. The IP of your website is: <?php echo $_SERVER['SERVER_ADDR']; ?>.</b>
83
+ </p>
84
+ <?php webp_express_printUpdateButtons() ?>
85
+ </div>
86
+ </div>
lib/options/css/webp-express-options-page.css CHANGED
@@ -77,8 +77,8 @@
77
#converters li a {
78
cursor: pointer;
79
}
80
- #converters li[data-id='gmagick'] a.configure-converter,
81
- #converters li[data-id='imagick'] a.configure-converter {
82
visibility: hidden;
83
}
84
@@ -201,6 +201,10 @@
201
.converter-options button {
202
margin-top: 15px;
203
}
204
.converter-options div {
205
margin-bottom: 15px;
206
}
77
#converters li a {
78
cursor: pointer;
79
}
80
+
81
+ #converters li[data-id='gmagick'] a.configure-converter {
82
visibility: hidden;
83
}
84
201
.converter-options button {
202
margin-top: 15px;
203
}
204
+ .converter-options button.button-primary {
205
+ margin-right: 10px;
206
+ }
207
+
208
.converter-options div {
209
margin-bottom: 15px;
210
}
lib/options/enqueue_scripts.php CHANGED
@@ -9,7 +9,7 @@ wp_enqueue_script('sortable');
9
wp_register_script('daspopup', plugins_url('js/das-popup.js', __FILE__), [], '0.7.0-dev5');
10
wp_enqueue_script('daspopup');
11
12
- wp_register_script('converters', plugins_url('js/converters.js', __FILE__), ['sortable','daspopup'], '0.7.0-dev24');
13
wp_enqueue_script('converters');
14
15
wp_register_script('whitelist', plugins_url('js/whitelist.js', __FILE__), ['daspopup'], '0.7.0-dev15');
@@ -29,7 +29,7 @@ if (function_exists('wp_add_inline_script')) {
29
}
30
31
// Register styles
32
- wp_register_style('webp-express-options-page-css', plugins_url('css/webp-express-options-page.css', __FILE__), null, '0.7.0-dev6');
33
wp_enqueue_style('webp-express-options-page-css');
34
35
wp_register_style('das-popup-css', plugins_url('css/das-popup.css', __FILE__), null, '0.7.0-dev5');
9
wp_register_script('daspopup', plugins_url('js/das-popup.js', __FILE__), [], '0.7.0-dev5');
10
wp_enqueue_script('daspopup');
11
12
+ wp_register_script('converters', plugins_url('js/converters.js', __FILE__), ['sortable','daspopup'], '0.8.0-dev7');
13
wp_enqueue_script('converters');
14
15
wp_register_script('whitelist', plugins_url('js/whitelist.js', __FILE__), ['daspopup'], '0.7.0-dev15');
29
}
30
31
// Register styles
32
+ wp_register_style('webp-express-options-page-css', plugins_url('css/webp-express-options-page.css', __FILE__), null, '0.8.0-dev4');
33
wp_enqueue_style('webp-express-options-page-css');
34
35
wp_register_style('das-popup-css', plugins_url('css/das-popup.css', __FILE__), null, '0.7.0-dev5');
lib/options/js/converters.js CHANGED
@@ -55,6 +55,7 @@ function getConversionMethodDescription(converterId) {
55
'gd': 'Gd extension',
56
'imagick': 'Imagick extension',
57
'gmagick': 'Gmagick extension',
58
};
59
if (descriptions[converterId]) {
60
return descriptions[converterId];
@@ -240,6 +241,13 @@ function configureConverter(id) {
240
var converter = window.convertersMap[id];
241
window.currentlyEditing = id;
242
243
switch (converter['converter']) {
244
case 'ewww':
245
document.getElementById('ewww_key').value = getConverterOption(converter, 'key', '');
@@ -312,13 +320,6 @@ function configureConverter(id) {
312
313
//wpcUpdateWebServicesHTML();
314
315
- var q = getConverterOption(converter, 'quality', 'not_set');
316
- if (document.getElementById('wpc_quality')) {
317
- document.getElementById('wpc_quality').value = q;
318
- document.getElementById('wpc_max_quality_div').style['display'] = (q == 'auto' ? 'block' : 'none');
319
- document.getElementById('wpc_max_quality').value = getConverterOption(converter, 'max-quality', 85);
320
- }
321
-
322
break;
323
case 'gd':
324
document.getElementById('gd_skip_pngs').checked = getConverterOption(converter, 'skip-pngs', '');
@@ -332,13 +333,31 @@ function configureConverter(id) {
332
document.getElementById('cwebp_size_in_percentage').value = getConverterOption(converter, 'size-in-percentage', '');
333
document.getElementById('cwebp_command_line_options').value = getConverterOption(converter, 'command-line-options', '');
334
break;
335
-
336
}
337
tb_show("Configure " + converter['id'] + ' converter', '#TB_inline?inlineId=' + converter['converter']);
338
}
339
340
function updateConverterOptions() {
341
- var converter = window.convertersMap[window.currentlyEditing];
342
343
switch (converter['converter']) {
344
case 'ewww':
@@ -370,20 +389,6 @@ function updateConverterOptions() {
370
deleteConverterOption(converter, 'new-api-key');
371
}
372
373
-
374
- if (document.getElementById('wpc_quality')) {
375
- var q = document.getElementById('wpc_quality').value;
376
- if (q == 'auto') {
377
- setConverterOption(converter, 'quality', 'auto');
378
- setConverterOption(converter, 'max-quality', document.getElementById('wpc_max_quality').value);
379
- } else {
380
- delete converter['options']['quality'];
381
- delete converter['options']['max-quality'];
382
- }
383
- } else {
384
- delete converter['options']['quality'];
385
- delete converter['options']['max-quality'];
386
- }
387
break;
388
case 'gd':
389
setConverterOption(converter, 'skip-pngs', document.getElementById('gd_skip_pngs').checked);
@@ -397,11 +402,27 @@ function updateConverterOptions() {
397
setConverterOption(converter, 'size-in-percentage', document.getElementById('cwebp_size_in_percentage').value);
398
setConverterOption(converter, 'command-line-options', document.getElementById('cwebp_command_line_options').value);
399
break;
400
}
401
updateInputValue();
402
tb_remove();
403
document.getElementById('webpexpress_settings').submit();
404
}
405
406
function testConverter(id) {
407
//alert('h' + id);
@@ -418,13 +439,14 @@ function testConverter(id) {
418
419
// test images here: http://nottinghamtec.co.uk/~aer/TestPatterns/1080/
420
filename = 'test.jpg';
421
- filename = 'stones.jpg';
422
filename = 'architecture2.jpg';
423
filename = 'test1.png';
424
- filename = 'focus.jpg';
425
426
- url += '?source=' + paths['webpExpressRoot'] + '/test/' + filename;
427
- url += '&destination=' + paths['destinationRoot'] + '/test-conversions/' + filename + '.webp';
428
url += '&converter=' + converter['converter'];
429
if (document.getElementById('max_quality')) {
430
url += '&max-quality=' + document.getElementById('max_quality').value;
@@ -479,9 +501,9 @@ function activateConverter(id) {
479
/* WPC */
480
/* ------------- */
481
482
- function wpcQualityChanged() {
483
- var q = document.getElementById('wpc_quality').value;
484
- document.getElementById('wpc_max_quality_div').style['display'] = (q == 'auto' ? 'block' : 'none');
485
}
486
487
function wpcShowAwaitingApprovalPopup() {
55
'gd': 'Gd extension',
56
'imagick': 'Imagick extension',
57
'gmagick': 'Gmagick extension',
58
+ 'imagickbinary': 'Imagick binary'
59
};
60
if (descriptions[converterId]) {
61
return descriptions[converterId];
241
var converter = window.convertersMap[id];
242
window.currentlyEditing = id;
243
244
+ var q = getConverterOption(converter, 'quality', 'auto');
245
+ if (document.getElementById(id + '_quality')) {
246
+ document.getElementById(id + '_quality').value = q;
247
+ document.getElementById(id + '_max_quality_div').style['display'] = (q == 'auto' ? 'block' : 'none');
248
+ document.getElementById(id + '_max_quality').value = getConverterOption(converter, 'max-quality', 85);
249
+ }
250
+
251
switch (converter['converter']) {
252
case 'ewww':
253
document.getElementById('ewww_key').value = getConverterOption(converter, 'key', '');
320
321
//wpcUpdateWebServicesHTML();
322
323
break;
324
case 'gd':
325
document.getElementById('gd_skip_pngs').checked = getConverterOption(converter, 'skip-pngs', '');
333
document.getElementById('cwebp_size_in_percentage').value = getConverterOption(converter, 'size-in-percentage', '');
334
document.getElementById('cwebp_command_line_options').value = getConverterOption(converter, 'command-line-options', '');
335
break;
336
+ case 'imagickbinary':
337
+ document.getElementById('imagickbinary_use_nice').checked = getConverterOption(converter, 'use-nice', '');
338
+ break;
339
}
340
tb_show("Configure " + converter['id'] + ' converter', '#TB_inline?inlineId=' + converter['converter']);
341
}
342
343
function updateConverterOptions() {
344
+ var id = window.currentlyEditing;
345
+ var converter = window.convertersMap[id];
346
+
347
+ if (document.getElementById(id + '_quality')) {
348
+ var q = document.getElementById(id + '_quality').value;
349
+ if (q == 'auto') {
350
+ setConverterOption(converter, 'quality', 'auto');
351
+ setConverterOption(converter, 'max-quality', document.getElementById(id + '_max_quality').value);
352
+ } else {
353
+ //delete converter['options']['quality'];
354
+ setConverterOption(converter, 'quality', 'inherit');
355
+ delete converter['options']['max-quality'];
356
+ }
357
+ } else {
358
+ delete converter['options']['quality'];
359
+ delete converter['options']['max-quality'];
360
+ }
361
362
switch (converter['converter']) {
363
case 'ewww':
389
deleteConverterOption(converter, 'new-api-key');
390
}
391
392
break;
393
case 'gd':
394
setConverterOption(converter, 'skip-pngs', document.getElementById('gd_skip_pngs').checked);
402
setConverterOption(converter, 'size-in-percentage', document.getElementById('cwebp_size_in_percentage').value);
403
setConverterOption(converter, 'command-line-options', document.getElementById('cwebp_command_line_options').value);
404
break;
405
+ case 'imagickbinary':
406
+ setConverterOption(converter, 'use-nice', document.getElementById('imagickbinary_use_nice').checked);
407
+ break;
408
}
409
updateInputValue();
410
tb_remove();
411
+ }
412
+
413
+ function updateConverterOptionsAndSave() {
414
+ updateConverterOptions();
415
document.getElementById('webpexpress_settings').submit();
416
}
417
+ /** Encode path before adding to querystring.
418
+ * Paths in querystring triggers LFI warning in Wordfence.
419
+ * By encoding it, Wordpfence will not detect our misdeed!
420
+ *
421
+ * see https://github.com/rosell-dk/webp-express/issues/87
422
+ */
423
+ function encodePathforQS(path) {
424
+ return path.replace('/', '**');
425
+ }
426
427
function testConverter(id) {
428
//alert('h' + id);
439
440
// test images here: http://nottinghamtec.co.uk/~aer/TestPatterns/1080/
441
filename = 'test.jpg';
442
+ /* filename = 'stones.jpg';
443
filename = 'architecture2.jpg';
444
filename = 'test1.png';
445
+ filename = 'focus.jpg';*/
446
447
+ url += '?source=' + encodePathforQS(paths['webpExpressRoot'] + '/test/' + filename);
448
+ url += '&configDirRel=' + encodePathforQS(paths['configRelToDocRoot']);
449
+ url += '&destination=' + encodePathforQS(paths['destinationRoot'] + '/test-conversions/' + filename + '.webp');
450
url += '&converter=' + converter['converter'];
451
if (document.getElementById('max_quality')) {
452
url += '&max-quality=' + document.getElementById('max_quality').value;
501
/* WPC */
502
/* ------------- */
503
504
+ function converterQualityChanged(converterId) {
505
+ var q = document.getElementById(converterId + '_quality').value;
506
+ document.getElementById(converterId + '_max_quality_div').style['display'] = (q == 'auto' ? 'block' : 'none');
507
}
508
509
function wpcShowAwaitingApprovalPopup() {
lib/options/page-messages.php CHANGED
@@ -10,6 +10,8 @@ use \WebPExpress\FileHelper;
10
11
//include __DIR__ . "/page-welcome.php";
12
13
if ((!State::getState('configured', false))) {
14
include __DIR__ . "/page-welcome.php";
15
}
10
11
//include __DIR__ . "/page-welcome.php";
12
13
+ //echo 'display errors:' . ini_get('display_errors');
14
+
15
if ((!State::getState('configured', false))) {
16
include __DIR__ . "/page-welcome.php";
17
}
lib/options/page.php CHANGED
@@ -43,6 +43,29 @@ function webpexpress_converterName($converterId) {
43
return $converterId;
44
}
45
46
//update_option('webp-express-migration-version', '1');
47
48
// Test converters
@@ -59,7 +82,6 @@ if ($testResult) {
59
);
60
}
61
62
- $canDetectQuality = TestRun::isLocalQualityDetectionWorking();
63
64
include __DIR__ . "/page-messages.php";
65
@@ -309,8 +331,10 @@ if ($canDetectQuality) {
309
echo helpIcon('All converted images will be encoded with this quality');
310
} else {
311
echo helpIcon('All converted images will be encoded with this quality. ' .
312
- 'For the Remote WebP Express converter, you will however have the option to use override this, and use ' .
313
- '"auto". If you install imagick or gmagick, quality can have "auto" for all convertion methods. '
314
);
315
}
316
echo '</th><td>';
@@ -375,298 +399,23 @@ echo '<a target="_blank" href="https://github.com/rosell-dk/webp-convert/blob/ma
375
// https://github.com/RubaXa/Sortable
376
377
// Empty list of converters. The list will be populated by the javascript
378
- echo '<ul id="converters" style="margin-top: -13px"></ul>';
379
- ?>
380
- <div id="cwebp" style="display:none;">
381
- <div class="cwebp converter-options">
382
- <h3>cweb options</h3>
383
- <div>
384
- <label for="cwebp_use_nice">Use nice</label>
385
- <input type="checkbox" id="cwebp_use_nice">
386
- <br>Enabling this option saves system resources at the cost of slightly slower conversion
387
- </div>
388
- <div>
389
- <label for="cwebp_try_common_system_paths">Try to execute cweb binary at common locations</label>
390
- <input type="checkbox" id="cwebp_try_common_system_paths">
391
- <br>If checked, we will look for binaries in common locations, such as <i>/usr/bin/cwebp</i>
392
- </div>
393
- <div>
394
- <label for="cwebp_try_common_system_paths">Try precompiled cwebp</label>
395
- <input type="checkbox" id="cwebp_try_supplied_binary">
396
- <br>This plugin ships with precompiled cweb binaries for different platforms. If checked, and we have a precompiled binary for your OS, we will try to exectute it
397
- </div>
398
- <div>
399
- <label for="cwebp_method">Method (0-6)</label>
400
- <input type="text" size="2" id="cwebp_method">
401
- <br>This parameter controls the trade off between encoding speed and the compressed file size and quality.
402
- Possible values range from 0 to 6. 0 is fastest. 6 results in best quality.
403
- </div>
404
- <div>
405
- <label for="cwebp_set_size">Set size option (and ignore quality option)</label>
406
- <input type="checkbox" id="cwebp_set_size">
407
- <br>This option activates the size option below.
408
- <?php
409
- if ($canDetectQuality) {
410
- echo 'As you have quality detection working on your server, it is probably best to use that, rather ';
411
- echo 'than the "size" option. Using the size option takes more ressources (it takes about 2.5 times ';
412
- echo 'longer for cwebp to do a a conversion with the size option than the quality option). Long ';
413
- echo 'story short, you should probably <i>not</i> activate the size option.';
414
- } else {
415
- echo 'As you do not have quality detection working on your server, it is probably a good ';
416
- echo 'idea to use the size option to avoid making conversions with a higher quality setting ';
417
- echo 'than the source image. ';
418
- echo 'Beware, though, that cwebp takes about 2.5 times longer to do a a conversion with the size option set.';
419
- }
420
- ?>
421
- </div>
422
- <div>
423
- <label for="cwebp_size_in_percentage">Size (in percentage of source)</label>
424
- <input type="text" size="2" id="cwebp_size_in_percentage">
425
- <br>Set the cwebp should aim for, in percentage of the original.
426
- Usually cwebp can reduce to ~45% of original without loosing quality.
427
- </div>
428
- <div>
429
- <label for="cwebp_command_line_options">Extra command line options</label><br>
430
- <input type="text" size="40" id="cwebp_command_line_options" style="width:100%">
431
- <br>This allows you to set any parameter available for cwebp in the same way as
432
- you would do when executing <i>cwebp</i>. As a syntax example, you could ie. set it to
433
- "-low_memory -af -f 50 -sharpness 0 -mt -crop 10 10 40 40" (do not include the quotes).
434
- Read more about all the available parameters in
435
- <a target="_blank" href="https://developers.google.com/speed/webp/docs/cwebp">the docs</a>
436
- </div>
437
- <br>
438
- <button onclick="updateConverterOptions()" class="button button-primary" type="button">Update and save settings</button>
439
- <!-- <a href="javascript: tb_remove();">close</a> -->
440
- </div>
441
- </div>
442
- <div id="gd" style="display:none;">
443
- <div class="gd converter-options">
444
- <h3>Gd options</h3>
445
- <div>
446
- <label for="gd_skip_pngs">Skip PNGs</label>
447
- <input type="checkbox" id="gd_skip_pngs">
448
- <br>Gd is not suited for converting PNGs into webp. &ndash;
449
- The filesize is generally much larger than the original.
450
- For this reason, the converter defaults to skip PNG's.
451
- </div>
452
- <br>
453
- <button onclick="updateConverterOptions()" class="button button-primary" type="button">Update and save settings</button>
454
- <!-- <a href="javascript: tb_remove();">close</a> -->
455
- </div>
456
- </div>
457
- <div id="imagick" style="display:none;">
458
- <div class="imagick converter-options">
459
- <h3>Imagick options</h3>
460
- <div class="info">
461
- imagick has no special options.
462
- </div>
463
- <br>
464
- <!--
465
- <button onclick="updateConverterOptions()" class="button button-primary" type="button">Update</button>
466
- -->
467
- <!-- <a href="javascript: tb_remove();">close</a> -->
468
- </div>
469
- </div>
470
- <div id="ewww" style="display:none;">
471
- <div class="ewww converter-options">
472
- <h3>Ewww</h3>
473
- <p>
474
- ewww is a cloud service for converting images.
475
- To use it, you need to purchase a key <a target="_blank" href="https://ewww.io/plans/">here</a>.
476
- They do not charge credits for webp conversions, so all you ever have to pay is the one dollar start-up fee :)
477
- </p>
478
- <h3>Options</h3>
479
- <div>
480
- <label for="ewww_key">Key</label>
481
- <input type="text" id="ewww_key" placeholder="Your API key here">
482
- </div>
483
- <br>
484
- <h4>Fallback (optional)</h4>
485
- <div>
486
- <label for="ewww_key_2">key</label>
487
- <input type="text" id="ewww_key_2" placeholder="In case the first one expires...">
488
- </div>
489
- <br>
490
- <button onclick="updateConverterOptions()" class="button button-primary" type="button">Update and save settings</button>
491
- <!-- <a href="javascript: tb_remove();">close</a> -->
492
- </div>
493
- </div>
494
- <!--
495
- <div id="wpc_successfully_connected_popup" class="das-popup">
496
- <h3>Your request has been approved</h3>
497
- All you need now is to save settings (both places)
498
- <button onclick="closeDasPopup()" class="button button-primary" type="button" style="position:absolute; bottom:20px">Close</button>
499
- </div>
500
- <div id="wpc_awaiting_approval_popup" class="das-popup">
501
- <h3>Avaiting approval<span class="animated-dots">...</span></h3>
502
- In the remote WebP Express settings, the screen should now show "Incoming request".
503
- Click the "Grant access" button there, and then return here.
504
- </div>
505
- <div id="wpc_connect_popup" class="das-popup">
506
- <h3>Request access to web service</h3>
507
- <div style="font-size:90%">
508
- Before requesting access, the website you want to request access to must be <i>listening</i>
509
- for requests. If you control that website, open a new tab and do the following. Otherwise,
510
- make sure the admin does the following:
511
- <ol>
512
- <li>Log in to the Wordpress site you want to connect to.</li>
513
- <li>In WebP Express settings, make sure that "enable web service?" is checked.</li>
514
- <li>Click "+ Authorize new website"</li>
515
- <li>An URL will display, which you must copy to the field below:</li>
516
- </ol>
517
- Paste URL here:<br>
518
- <input id="wpc_request_access_url" style="width:100%">
519
- </div>
520
- <div style="position:absolute; bottom:20px; line-height:28px">
521
- <button onclick="wpcRequestAccess()" class="button button-primary" type="button">Request access</button>
522
- &nbsp;or&nbsp;
523
- <button onclick="wpcAddManually()" class="button button-secondary" type="button">Add manually</button>
524
- </div>
525
- </div>
526
- <div id="wpc_properties_popup" class="das-popup">
527
- <h3 class="hide-in-edit">Add connection to web service</h3>
528
- <h3 class="hide-in-add">Edit connection to web service</h3>
529
- <input type="hidden" id="wpc_i">
530
- <div>
531
- <label for="wpc_label">
532
- Label
533
- <?php echo helpIcon('The label is purely for your own reference'); ?>
534
- </label>
535
- <input id="wpc_label" type="text">
536
- </div>
537
- <div>
538
- <label for="wpc_url">
539
- URL
540
- <?php echo helpIcon('The endpoint of the web service.'); ?>
541
- </label>
542
- <input id="wpc_url" type="text">
543
- </div>
544
- <div>
545
- <label for="wpc_api_key">
546
- Api key
547
- <?php echo helpIcon('The API key is set up on the remote. Copy that.'); ?>
548
- </label>
549
- <input id="wpc_api_key" type="password" class="hide-in-edit">
550
- <a href="javascript:wpcChangeApiKey()" class="hide-in-add" style="display:inline-block;line-height:34px">Change api key</a>
551
- </div>
552
- <div>
553
- <label for="wpc_crypt_api_key_in_transfer">
554
- Crypt api key in transfer?
555
- <?php echo helpIcon('If checked, the api key will be crypted in requests. Crypting the api-key protects it from being stolen during transfer.'); ?>
556
- </label>
557
- <input id="wpc_crypt_api_key_in_transfer" type="checkbox">
558
- </div>
559
- <button id="wpc_properties_add_button" onclick="wpcAddEntry()" class="hide-in-edit button button-primary" type="button" style="position:absolute; bottom:20px">
560
- Add
561
- </button>
562
- <button id="wpc_properties_update_button" onclick="wpcUpdateEntry()" class="hide-in-add button button-primary" type="button" style="position:absolute; bottom:20px">
563
- Update
564
- </button>
565
- </div>
566
- -->
567
- <div id="wpc" style="display:none;">
568
- <div class="wpc converter-options">
569
- <h3>Remote WebP Express</h3>
570
- Use a WebP Express installed on another Wordpress site to convert. Remote WepP Express is based
571
- on <a href="https://github.com/rosell-dk/webp-convert-cloud-service" target="blank">WPC</a>,
572
- and you can use it to connect to WPC as well.
573
-
574
- <?php
575
- if ((!extension_loaded('curl')) || (!function_exists('curl_init'))) {
576
- echo '<p><b style="color:red">Your server does not have curl installed. Curl is required!</b></p>';
577
- }
578
- ?>
579
-
580
- <h3>Options</h3>
581
- <!--
582
- <div>
583
- <label for="wpc_web_services">Web Services</label>
584
- <div style="display:inline-block">
585
- <div id="wpc_web_services_div"></div>
586
- <button type="button" id="wpc_web_services_request" onclick="openWpcConnectPopup()" class="button button-secondary" >Add web service</button>
587
- </div>
588
- </div>
589
- -->
590
591
- <div id="wpc_api_version_div">
592
- <label for="wpc_api_version">
593
- Api version
594
- <?php echo helpIcon('Select 1, if connecting to a remote webp-express. Api 0 was never used with this plugin, and should only be used to connect to webp-convert-cloud-service v.0.1 instances'); ?>
595
- </label>
596
- <select id="wpc_api_version" onchange="wpcApiVersionChanged()">
597
- <option value="0">0</option>
598
- <option value="1">1</option>
599
- </select>
600
- </div>
601
602
- <div>
603
- <label for="wpc_url">
604
- URL
605
- <?php echo helpIcon('The endpoint of the web service. Copy it from the remote setup.'); ?>
606
- </label>
607
- <input type="text" id="wpc_url" placeholder="Url to your Remote WebP Express">
608
- </div>
609
-
610
- <div id="wpc_secret_div">
611
- <label for="wpc_secret">
612
- Secret
613
- <?php echo helpIcon('Must match the one set up in webp-convert-cloud-service v0.1'); ?>
614
- </label>
615
- <input type="text" id="wpc_secret" placeholder="">
616
- </div>
617
-
618
- <div id="wpc_api_key_div">
619
- <label id="wpc_api_key_label_1" for="wpc_api_key">
620
- Secret
621
- <?php echo helpIcon('The secret set up on the wpc server. Copy that.'); ?>
622
- </label>
623
- <label id="wpc_api_key_label_2" for="wpc_api_key">
624
- Api key
625
- <?php echo helpIcon('The API key is set up on the remote. Copy that.'); ?>
626
- </label>
627
- <input id="wpc_new_api_key" type="password">
628
- <a id="wpc_change_api_key" href="javascript:wpcChangeApiKey()">
629
- Click to change
630
- </a>
631
- </div>
632
-
633
- <div id="wpc_crypt_api_key_in_transfer_div">
634
- <label for="wpc_crypt_api_key_in_transfer">
635
- Crypt api key in transfer?
636
- <?php echo helpIcon('If checked, the api key will be crypted in requests. Crypting the api-key protects it from being stolen during transfer.'); ?>
637
- </label>
638
- <input id="wpc_crypt_api_key_in_transfer" type="checkbox">
639
- </div>
640
-
641
- <?php
642
- if (!$canDetectQuality) { ?>
643
- <div>
644
- <label for="wpc_quality">
645
- Quality
646
- <?php echo helpIcon('If "Auto" is selected, the converted image will get same quality as source. Auto is recommended!'); ?>
647
- </label>
648
- <!--
649
- Your server cannot detect quality of jpeg files. But you can have the cloud server do it for you
650
- (provided that <i>it</i> can) -->
651
- <select id="wpc_quality" onchange="wpcQualityChanged()">
652
- <option value="not_set">Use global settings</option>
653
- <option value="auto">Auto</option>
654
- </select>
655
- </div>
656
- <div id="wpc_max_quality_div">
657
- <label>
658
- Max quality
659
- <?php echo helpIcon('Enter number (0-100). Converted images will be encoded with same quality as the source image, but not more than this setting'); ?>
660
- </label>
661
- <input type="text" size=3 id="wpc_max_quality">
662
- </div>
663
- <?php } ?>
664
- <p>
665
- <b>Psst. The IP of your website is: <?php echo $_SERVER['SERVER_ADDR']; ?>.</b>
666
- </p>
667
- <button onclick="updateConverterOptions()" class="button button-primary" type="button">Update and save settings</button>
668
- </div>
669
- </div>
670
</td></tr>
671
<?php
672
43
return $converterId;
44
}
45
46
+ $canDetectQuality = TestRun::isLocalQualityDetectionWorking();
47
+
48
+ function printAutoQualityOptionForConverter($converterId) {
49
+ ?>
50
+ <div>
51
+ <label for="<?php echo $converterId; ?>_quality">
52
+ Quality
53
+ <?php echo helpIcon('If "Auto" is selected, the converted image will get same quality as source. Auto is recommended!'); ?>
54
+ </label>
55
+ <select id="<?php echo $converterId; ?>_quality" onchange="converterQualityChanged('<?php echo $converterId; ?>')">
56
+ <option value="inherit">Use global settings</option>
57
+ <option value="auto">Auto</option>
58
+ </select>
59
+ </div>
60
+ <div id="<?php echo $converterId; ?>_max_quality_div">
61
+ <label>
62
+ Max quality
63
+ <?php echo helpIcon('Enter number (0-100). Converted images will be encoded with same quality as the source image, but not more than this setting'); ?>
64
+ </label>
65
+ <input type="text" size=3 id="<?php echo $converterId; ?>_max_quality">
66
+ </div>
67
+ <?php
68
+ }
69
//update_option('webp-express-migration-version', '1');
70
71
// Test converters
82
);
83
}
84
85
86
include __DIR__ . "/page-messages.php";
87
331
echo helpIcon('All converted images will be encoded with this quality');
332
} else {
333
echo helpIcon('All converted images will be encoded with this quality. ' .
334
+ 'For Remote WebP Express and Imagick, you however have the option to use override this, and use ' .
335
+ '"auto". With some setup, you can get quality detection working and you will then be able to set ' .
336
+ 'quality to "auto" generally. For that you either need to get the imagick extension running ' .
337
+ '(PECL >= 2.2.2) or exec() rights and either imagick or gmagick installed.'
338
);
339
}
340
echo '</th><td>';
399
// https://github.com/RubaXa/Sortable
400
401
// Empty list of converters. The list will be populated by the javascript
402
403
+ function webp_express_printUpdateButtons() {
404
+ ?>
405
+ <button onclick="updateConverterOptionsAndSave()" class="button button-primary" type="button">Update and save settings</button>
406
+ <button onclick="updateConverterOptions()" class="button button-secondary" type="button">Update, but do not save yet</button>
407
+ <?php
408
+ //echo '<a href="javascript: tb_remove();">close</a>';
409
+ }
410
+ echo '<ul id="converters" style="margin-top: -13px"></ul>';
411
412
+ include 'converter-options/cwebp.php';
413
+ include 'converter-options/gd.php';
414
+ include 'converter-options/imagick.php';
415
+ include 'converter-options/ewww.php';
416
+ include 'converter-options/wpc.php';
417
+ include 'converter-options/imagickbinary.php';
418
+ ?>
419
</td></tr>
420
<?php
421
lib/options/submit.php CHANGED
@@ -124,6 +124,9 @@ if ($auto) {
124
$config['quality-specific'] = webp_express_sanitize_quality_field($_POST['quality-specific']);
125
}
126
127
// remove id's
128
foreach ($config['converters'] as &$converter) {
129
unset ($converter['id']);
@@ -175,10 +178,10 @@ foreach ($config['converters'] as &$converter) {
175
} else {
176
$converter['options']['api-key'] = $existingWpcApiKey;
177
}
178
-
179
}
180
}
181
182
// create password hashes for new passwords
183
/*
184
foreach ($config['server']['whitelist'] as &$entry) {
124
$config['quality-specific'] = webp_express_sanitize_quality_field($_POST['quality-specific']);
125
}
126
127
+ //echo '<pre>' . print_r($config['converters'], true) . '</pre>';
128
+ //die;
129
+
130
// remove id's
131
foreach ($config['converters'] as &$converter) {
132
unset ($converter['id']);
178
} else {
179
$converter['options']['api-key'] = $existingWpcApiKey;
180
}
181
}
182
}
183
184
+
185
// create password hashes for new passwords
186
/*
187
foreach ($config['server']['whitelist'] as &$entry) {
test/test-run.php CHANGED
@@ -5,6 +5,7 @@ if (isset($_GET['stream-webp-image'])) {
5
if (@readfile($_GET['stream-webp-image']) === false) {
6
// ...
7
}
8
}
9
10
error_reporting(E_ALL);
@@ -42,9 +43,19 @@ use WebPConvert\Loggers\EchoLogger;
42
<body style="">
43
44
<?php
45
//WebPConvertAndServe::convertAndReport($source, $destination, $options);use WebPConvert\Loggers\EchoLogger;
46
- $source = $_GET['source'];
47
- $destination = $_GET['destination'];
48
$converter = $_GET['converter'];
49
50
if (isset($_GET['max-quality'])) {
@@ -74,7 +85,7 @@ function getConverterOptionsFromQueryString($converter)
74
// Set options
75
$options = [];
76
foreach ($availOptions as $optionName => $optionType) {
77
- //echo $optionName . '<br>';
78
switch ($optionType) {
79
case 'string':
80
if (isset($_GET[$optionName])) {
@@ -93,6 +104,47 @@ function getConverterOptionsFromQueryString($converter)
93
break;
94
}
95
}
96
return $options;
97
}
98
$options['converters'] = [[
@@ -100,6 +152,10 @@ $options['converters'] = [[
100
'options' => getConverterOptionsFromQueryString($converter)
101
]];
102
103
//echo '<pre>' . print_r($_GET, true) . '</pre>';
104
//echo '<pre>' . print_r($options, true) . '</pre>';
105
5
if (@readfile($_GET['stream-webp-image']) === false) {
6
// ...
7
}
8
+ exit;
9
}
10
11
error_reporting(E_ALL);
43
<body style="">
44
45
<?php
46
+
47
+ /**
48
+ * Paths passed in query string were encoded, to avoid triggering LFI warning in Wordfence
49
+ * (encoding is done in converters.js)
50
+ * see https://github.com/rosell-dk/webp-express/issues/87
51
+ */
52
+ function decodePathInQS($encodedPath) {
53
+ return preg_replace('/\*\*/', '/', $encodedPath);
54
+ }
55
+
56
//WebPConvertAndServe::convertAndReport($source, $destination, $options);use WebPConvert\Loggers\EchoLogger;
57
+ $source = decodePathInQS($_GET['source']);
58
+ $destination = decodePathInQS($_GET['destination']);
59
$converter = $_GET['converter'];
60
61
if (isset($_GET['max-quality'])) {
85
// Set options
86
$options = [];
87
foreach ($availOptions as $optionName => $optionType) {
88
+ //echo $optionName . ':' . $optionType . '<br>';
89
switch ($optionType) {
90
case 'string':
91
if (isset($_GET[$optionName])) {
104
break;
105
}
106
}
107
+
108
+ if ($converter == 'wpc') {
109
+
110
+ // Handle api key.
111
+ // If it has been modified on the options page, it is passed as 'new-api-key'.
112
+ // If it has not been modified, it is not passed at all!
113
+ // - in that case, we must load it from the config file.
114
+
115
+ if (isset($_GET['new-api-key'])) {
116
+ $options['api-key'] = $_GET['new-api-key'];
117
+ } elseif (isset($_GET['configDirRel'])) {
118
+
119
+ // Fetch api-key from configuration file.
120
+ $configFilename = $_SERVER['DOCUMENT_ROOT'] . '/' . decodePathInQS($_GET['configDirRel']) . '/config.json';
121
+
122
+ if (file_exists($configFilename)) {
123
+
124
+ $handle = @fopen($configFilename, "r");
125
+ $json = fread($handle, filesize($configFilename));
126
+ fclose($handle);
127
+
128
+ $config = json_decode($json, true);
129
+ if ($config) {
130
+ foreach ($config['converters'] as $converter) {
131
+ if ($converter['converter'] == 'wpc') {
132
+ //print_r($converter);
133
+ if (isset($converter['options']['api-key'])) {
134
+ $options['api-key'] = $converter['options']['api-key'];
135
+ //echo 'api-key:' . $converter['options']['api-key'] . '<br>';
136
+ //print_r($options);
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ if (!isset($options['api-key'])) {
144
+ echo '<p style="color:red">Warning: No Api key is set</p>';
145
+ }
146
+ }
147
+
148
return $options;
149
}
150
$options['converters'] = [[
152
'options' => getConverterOptionsFromQueryString($converter)
153
]];
154
155
+
156
+
157
+
158
+
159
//echo '<pre>' . print_r($_GET, true) . '</pre>';
160
//echo '<pre>' . print_r($options, true) . '</pre>';
161
webp-express.php CHANGED
@@ -3,7 +3,7 @@
3
* Plugin Name: WebP Express
4
* Plugin URI: https://github.com/rosell-dk/webp-express
5
* Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
6
- * Version: 0.7.2
7
* Author: Bjørn Rosell
8
* Author URI: https://www.bitwise-it.dk
9
* License: GPL2
3
* Plugin Name: WebP Express
4
* Plugin URI: https://github.com/rosell-dk/webp-express
5
* Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
6
+ * Version: 0.8.0
7
* Author: Bjørn Rosell
8
* Author URI: https://www.bitwise-it.dk
9
* License: GPL2
wod/webp-on-demand.php CHANGED
@@ -1,5 +1,8 @@
1
<?php
2
3
//require 'webp-on-demand-1.inc';
4
require '../vendor/rosell-dk/webp-convert/build/webp-on-demand-1.inc';
5
//require '../vendor/autoload.php';
@@ -21,7 +24,6 @@ $options = json_decode($json, true);
21
$options['require-for-conversion'] = 'webp-on-demand-2.inc';
22
//$options['require-for-conversion'] = '../../../autoload.php';
23
24
- $gmagickHere = false;
25
foreach ($options['converters'] as &$converter) {
26
if (isset($converter['converter'])) {
27
$converterId = $converter['converter'];
@@ -31,12 +33,6 @@ foreach ($options['converters'] as &$converter) {
31
if ($converterId == 'cwebp') {
32
$converter['options']['rel-path-to-precompiled-binaries'] = '../src/Converters/Binaries';
33
}
34
- if ($converterId == 'gmagick') {
35
- $gmagickHere = true;
36
- }
37
- }
38
- if (!$gmagickHere) {
39
- // $options['converters'][] = 'gmagick';
40
}
41
42
if ($options['forward-query-string']) {
@@ -47,26 +43,37 @@ if ($options['forward-query-string']) {
47
$options['reconvert'] = true;
48
}
49
}
50
- $source = $_GET['source'];
51
52
// Calculate destination
53
- $applicationRoot = $_SERVER["DOCUMENT_ROOT"];
54
$imageRoot = $contentDirAbs . '/webp-images';
55
56
- if (substr($source, 0, strlen($applicationRoot)) === $applicationRoot) {
57
- // Source file is residing inside document root.
58
- // We can store relative to that.
59
- $sourceRel = substr($source, strlen($applicationRoot));
60
- $destination = $imageRoot . '/doc-root' . $sourceRel . '.webp';
61
} else {
62
// Source file is residing outside document root.
63
// we must add complete path to structure
64
$destination = $imageRoot . '/abs' . $source . '.webp';
65
}
66
- //$destination = $imageRoot . $source . '.webp';
67
68
69
- //echo $source . '<br>';
70
- //echo $destination . '<br>';
71
- //echo $sourceRel;
72
WebPConvert::convertAndServe($source, $destination, $options);
1
<?php
2
3
+ //echo 'display errors:' . ini_get('display_errors');
4
+ //exit;
5
+
6
//require 'webp-on-demand-1.inc';
7
require '../vendor/rosell-dk/webp-convert/build/webp-on-demand-1.inc';
8
//require '../vendor/autoload.php';
24
$options['require-for-conversion'] = 'webp-on-demand-2.inc';
25
//$options['require-for-conversion'] = '../../../autoload.php';
26
27
foreach ($options['converters'] as &$converter) {
28
if (isset($converter['converter'])) {
29
$converterId = $converter['converter'];
33
if ($converterId == 'cwebp') {
34
$converter['options']['rel-path-to-precompiled-binaries'] = '../src/Converters/Binaries';
35
}
36
}
37
38
if ($options['forward-query-string']) {
43
$options['reconvert'] = true;
44
}
45
}
46
+
47
+ if (isset($_GET['source'])) {
48
+ $source = $_GET['source'];
49
+ } elseif (isset($_GET['xsource'])) {
50
+ $source = substr($_GET['xsource'], 1);
51
+ }
52
53
// Calculate destination
54
+ $docRoot = rtrim($_SERVER["DOCUMENT_ROOT"], '/');
55
$imageRoot = $contentDirAbs . '/webp-images';
56
57
+ // Check if source is residing inside document root.
58
+ // (it is, if path starts with document root + '/')
59
+ if (substr($source, 0, strlen($docRoot) + 1) === $docRoot . '/') {
60
+
61
+ // We store relative to document root.
62
+ // "Eat" the left part off the source parameter which contains the document root.
63
+ // and also eat the slash (+1)
64
+ $sourceRel = substr($source, strlen($docRoot) + 1);
65
+ $destination = $imageRoot . '/doc-root/' . $sourceRel . '.webp';
66
} else {
67
// Source file is residing outside document root.
68
// we must add complete path to structure
69
$destination = $imageRoot . '/abs' . $source . '.webp';
70
}
71
+
72
+ // If we wanted webp images to be located in same folder, with ie ".jpg.webp" extension:
73
+ // $destination = $source . '.webp';
74
+
75
+ // If we wanted webp images to be located in same folder, with ".webp" extension:
76
+ // $destination = preg_replace('/\.(jpg|jpeg|png)#x2F;', '.webp', $source);
77
78
79
WebPConvert::convertAndServe($source, $destination, $options);