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 | WebP Express |
Version | 0.8.0 |
Comparing to | |
See all releases |
Code changes from version 0.7.2 to 0.8.0
- BACKERS.md +38 -0
- README.md +63 -13
- README.txt +19 -8
- changelog.txt +10 -0
- docs/development.md +3 -0
- lib/admin.php +4 -67
- lib/classes/Config.php +3 -0
- lib/classes/ConvertersHelper.php +5 -2
- lib/classes/FileHelper.php +23 -0
- lib/classes/HTAccess.php +2 -1
- lib/classes/Paths.php +9 -5
- lib/migrate/migrate.php +3 -4
- lib/migrate/migrate3.php +103 -42
- lib/options/converter-options/cwebp.php +61 -0
- lib/options/converter-options/ewww.php +23 -0
- lib/options/converter-options/gd.php +14 -0
- lib/options/converter-options/imagick.php +17 -0
- lib/options/converter-options/imagickbinary.php +24 -0
- lib/options/converter-options/wpc.php +86 -0
- lib/options/css/webp-express-options-page.css +6 -2
- lib/options/enqueue_scripts.php +2 -2
- lib/options/js/converters.js +52 -30
- lib/options/page-messages.php +2 -0
- lib/options/page.php +42 -293
- lib/options/submit.php +4 -1
- test/test-run.php +59 -3
- webp-express.php +1 -1
- wod/webp-on-demand.php +25 -18
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
|
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.
|
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 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
98 |
|
99 |
-
For more info, see the closed issues on the 0.
|
100 |
|
101 |
-
##
|
102 |
-
|
103 |
|
104 |
-
|
|
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://
|
4 |
Tags: webp, images, performance
|
5 |
Requires at least: 4.0
|
6 |
Tested up to: 5.0
|
7 |
-
Stable tag: 0.
|
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 |
-
*[
|
|
|
|
|
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
|
152 |
-
|
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.
|
217 |
-
|
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', '
|
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' =>
|
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'
|
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 |
-
"?
|
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 |
-
|
|
|
|
|
|
|
|
|
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
|
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 |
-
|
6 |
-
|
|
|
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 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
function webpexpress_migrate3() {
|
18 |
|
19 |
-
$
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
}
|
40 |
-
if ($
|
41 |
-
|
42 |
-
|
43 |
-
|
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$/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(.*)$/', '/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. –
|
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 |
-
|
81 |
-
#converters li[data-id='
|
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.
|
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.
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 += '&
|
|
|
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
|
483 |
-
var q = document.getElementById('
|
484 |
-
document.getElementById('
|
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
|
313 |
-
'"auto".
|
|
|
|
|
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. –
|
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 |
-
or
|
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 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
</select>
|
600 |
-
</div>
|
601 |
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
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 |
* 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 |
-
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
// Calculate destination
|
53 |
-
$
|
54 |
$imageRoot = $contentDirAbs . '/webp-images';
|
55 |
|
56 |
-
if
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
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)$/', '.webp', $source);
|
77 |
|
78 |
|
|
|
|
|
|
|
79 |
WebPConvert::convertAndServe($source, $destination, $options);
|