Version Description
(released: 3 Oct 2019)
- Fixed NGINX rules in FAQ (added xdestination for the create webp upon request functionality)
- Fixed issue with Alter HTML. Thanks to @jonathanernst for discovering issue and supplying the patch.
- WebP Express now works on WP Engine. Check out the new "I am on WP Engine" section in the FAQ
- Miscellaneous bug fixes
For more info, see the closed issues on the 0.17.1 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/27?closed=1
Download this release
Release Info
Developer | rosell.dk |
Plugin | WebP Express |
Version | 0.17.1 |
Comparing to | |
See all releases |
Code changes from version 0.17.0 to 0.17.1
- README.md +27 -3
- README.txt +35 -8
- changelog.txt +10 -0
- lib/classes/AlterHtmlHelper.php +4 -5
- lib/classes/Convert.php +2 -2
- lib/classes/ConvertHelperIndependent.php +1 -1
- lib/classes/PlatformInfo.php +4 -2
- lib/classes/SanityCheck.php +32 -10
- lib/classes/SelfTestHelper.php +203 -167
- lib/classes/SelfTestRedirectToConverter.php +93 -76
- lib/classes/SelfTestRedirectToExisting.php +91 -94
- lib/classes/SelfTestRedirectToWebPRealizer.php +64 -66
- lib/classes/WebPOnDemand.php +35 -1
- lib/classes/WebPRealizer.php +17 -8
- lib/classes/WodConfigLoader.php +36 -0
- lib/options/page-welcome.php +4 -2
- vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebP.php +17 -2
- webp-express.php +1 -47
- wod/.htaccess +1 -0
- wod/autoloader.php +8 -0
- wod/webp-on-demand.php +3 -20
- wod/webp-realizer.php +3 -20
README.md
CHANGED
@@ -132,8 +132,7 @@ Don't fret - you have options!
|
|
132 |
- 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. There is also this [test/troubleshooting script](https://github.com/rosell-dk/webp-convert/wiki/A-PHP-script-for-the-webhost) which is handy when messing around with this.
|
133 |
- Finally, if you have access to another 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.
|
134 |
|
135 |
-
Of course, there is also the option of using another plugin altogether. I can recommend [
|
136 |
-
|
137 |
|
138 |
### It doesn't work - Although test conversions work, it still serves jpeg images.
|
139 |
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.
|
@@ -237,7 +236,7 @@ location ~* ^/?wp-content/.*\.(png|jpe?g)$ {
|
|
237 |
location ~* ^/?wp-content/.*\.(png|jpe?g)\.webp$ {
|
238 |
try_files
|
239 |
$uri
|
240 |
-
/wp-content/plugins/webp-express/wod/webp-realizer.php?wp-content=wp-content
|
241 |
;
|
242 |
}
|
243 |
# ------------------- (WebP Express rules ends here)
|
@@ -491,6 +490,20 @@ To make *WebP Express* work on a free Cloudflare account, you have the following
|
|
491 |
|
492 |
3. You can switch operation mode to "CDN friendly" and use HTML altering.
|
493 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
494 |
### WebP Express / ShortPixel setup
|
495 |
Here is a recipe for using WebP Express together with ShortPixel, such that WebP Express generates the webp's, and ShortPixel only is used to create `<picture>` tags, when it detects a webp image in the same folder as an original.
|
496 |
|
@@ -638,11 +651,22 @@ Here are my current plans ahead: 0.17 will probably be a file manager-like inter
|
|
638 |
|
639 |
If you wish to affect priorities, it is certainly possible. You can try to argue your case in the forum or you can simply let the money do the talking. By donating as little as a cup of coffee on [ko-fi.com/rosell](https://ko-fi.com/rosell), you can leave a wish. I shall take these wishes into account when prioritizing between new features.
|
640 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
641 |
## Changes in 0.17.0
|
642 |
*(released: 27 sep 2019)*
|
643 |
|
644 |
* Cwebp conversion method runs on more systems (not subject to open_basedir restrictions and also tries "pure" cwebp command). Thanks to cng11 for reaching out so I spotted this.
|
645 |
* Ewww conversion method no longer does a remote api-key check for each conversion - so it is faster. If an ewww conversions fails due to a non-functional key, the key will not be tried again (until next time the options are saved)
|
|
|
646 |
|
647 |
## Changes in 0.16.0
|
648 |
*(released: 24 sep 2019)*
|
132 |
- 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. There is also this [test/troubleshooting script](https://github.com/rosell-dk/webp-convert/wiki/A-PHP-script-for-the-webhost) which is handy when messing around with this.
|
133 |
- Finally, if you have access to another 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.
|
134 |
|
135 |
+
Of course, there is also the option of using another plugin altogether. I can recommend Optimole. If you want to try that out and want to support me in the process, [follow this link](https://optimole.pxf.io/20b0M). It is an affiliate link and will give me a reward in case you decide to sign up.
|
|
|
136 |
|
137 |
### It doesn't work - Although test conversions work, it still serves jpeg images.
|
138 |
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.
|
236 |
location ~* ^/?wp-content/.*\.(png|jpe?g)\.webp$ {
|
237 |
try_files
|
238 |
$uri
|
239 |
+
/wp-content/plugins/webp-express/wod/webp-realizer.php?xdestination=x$request_filename&wp-content=wp-content
|
240 |
;
|
241 |
}
|
242 |
# ------------------- (WebP Express rules ends here)
|
490 |
|
491 |
3. You can switch operation mode to "CDN friendly" and use HTML altering.
|
492 |
|
493 |
+
### I am on WP Engine
|
494 |
+
From version 0.17.1 on WebP Express works with WP engine and this combination will be tested before each release.
|
495 |
+
|
496 |
+
You can use the plugin both in "Varied image responses" mode and in "CDN friendly mode".
|
497 |
+
|
498 |
+
To make the redirection work, you must:
|
499 |
+
1) Grab the nginx configuration found in the "I am on Nginx/OpenResty" section in this FAQ. Use the "try_files" variant.
|
500 |
+
2) Contact help center and ask them to insert that configuration.
|
501 |
+
3) Make sure the settings match this configuration. Follow the "beware" statements in the "I am on Nginx/OpenResty" section.
|
502 |
+
|
503 |
+
WebP Express tweaks the workings of "Redirect to converter" a bit for WP engine. That PHP script usually serves the webp directly, along with a Vary:Accept header. This header is however overwritten by the caching machinery on WP engine. As a work-around, I modified the response of the script for WP engine. Instead of serving the image, it serves a redirect to itself. As there now IS a corresponding webp, this repeated request will not be redirected to the PHP script, but directly to the webp. And headers are OK for those redirects. You can hit the "Live test" button next to "Enable redirection to converter?" to verify that this works as just described.
|
504 |
+
|
505 |
+
If you (contrary to this headline!) are in fact not on WP Engine, but might want to be, I have an affiliate link for you. It will give you 3 months free and it will give me a reward too, if you should decide to stay there. Here you go: [Get 3 months free when you sign up for WP Engine.](https://shareasale.com/r.cfm?b=1343154&u=2194916&m=41388&urllink=&afftrack=)
|
506 |
+
|
507 |
### WebP Express / ShortPixel setup
|
508 |
Here is a recipe for using WebP Express together with ShortPixel, such that WebP Express generates the webp's, and ShortPixel only is used to create `<picture>` tags, when it detects a webp image in the same folder as an original.
|
509 |
|
651 |
|
652 |
If you wish to affect priorities, it is certainly possible. You can try to argue your case in the forum or you can simply let the money do the talking. By donating as little as a cup of coffee on [ko-fi.com/rosell](https://ko-fi.com/rosell), you can leave a wish. I shall take these wishes into account when prioritizing between new features.
|
653 |
|
654 |
+
## Changes in 0.17.1
|
655 |
+
*(released: 3 Oct 2019)*
|
656 |
+
|
657 |
+
- Fixed NGINX rules in FAQ (added xdestination for the create webp upon request functionality)
|
658 |
+
- Fixed issue with Alter HTML. Thanks to @jonathanernst for discovering issue and supplying the patch.
|
659 |
+
- WebP Express now works on WP Engine. Check out the new "I am on WP Engine" section in the FAQ
|
660 |
+
- Miscellaneous bug fixes
|
661 |
+
|
662 |
+
For more info, see the closed issues on the 0.17.1 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/27?closed=1
|
663 |
+
|
664 |
## Changes in 0.17.0
|
665 |
*(released: 27 sep 2019)*
|
666 |
|
667 |
* Cwebp conversion method runs on more systems (not subject to open_basedir restrictions and also tries "pure" cwebp command). Thanks to cng11 for reaching out so I spotted this.
|
668 |
* Ewww conversion method no longer does a remote api-key check for each conversion - so it is faster. If an ewww conversions fails due to a non-functional key, the key will not be tried again (until next time the options are saved)
|
669 |
+
* Updated cwebp binaries to version 1.0.3
|
670 |
|
671 |
## Changes in 0.16.0
|
672 |
*(released: 24 sep 2019)*
|
README.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://ko-fi.com/rosell
|
|
4 |
Tags: webp, images, performance
|
5 |
Requires at least: 4.0
|
6 |
Tested up to: 5.2
|
7 |
-
Stable tag: 0.17.
|
8 |
Requires PHP: 5.6
|
9 |
License: GPLv3
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
@@ -134,7 +134,7 @@ Don't fret - you have options!
|
|
134 |
- 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. There is also this [test/troubleshooting script](https://github.com/rosell-dk/webp-convert/wiki/A-PHP-script-for-the-webhost) which is handy when messing around with this.
|
135 |
- Finally, if you have access to another 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.
|
136 |
|
137 |
-
Of course, there is also the option of using another plugin altogether. I can recommend [
|
138 |
|
139 |
= It doesn't work - Although test conversions work, it still serves jpeg images =
|
140 |
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.
|
@@ -162,7 +162,7 @@ WebP Express has three ways of distributing webp to webp-enabled browsers while
|
|
162 |
Can some of these go wrong?
|
163 |
Yes. All!
|
164 |
|
165 |
-
|
166 |
The "Varied image responses" method adds rules to the `.htaccess` which redirects jpegs and pngs to the corresponding webps (if they exist). The rules have a condition that makes sure they only trigger for browsers supports webp images (this is established by examining the "accept" header).
|
167 |
|
168 |
I the method "varied image responses" because the response on a given image URL *varies* (the webp is served on the same URL as the jpeg/png).
|
@@ -180,12 +180,12 @@ I do not believe it can go wrong in other ways. To be certain, please check out
|
|
180 |
|
181 |
Since WebP Express 0.15.0 you can use the "Live test" button to check that browsers not supporting webp gets the original files and that the Vary:Accept header is returned. Note however that it may not detect CDN caching problems if the CDN doesn't cache a new image immediately - and across all its nodes.
|
182 |
|
183 |
-
|
184 |
IMG tags are replaced with PICTURE tags which has two sources. One of them points to the webp and has the "content-type" set to "image/webp". The other points to the original. The browser will select the webp source if it supports webp and the other source if it doesn't.
|
185 |
|
186 |
Method 2 can go wrong on old browser that doesn't support the picture tag syntax. However, simply enable the "Dynamically load picturefill.js on older browsers" option, and it will take care of that issue.
|
187 |
|
188 |
-
|
189 |
In this solution, the URLs in the HTML are modified for browsers that supports webp. Again, this is determined by examining the "accept" header. So, actually the complete page HTML varies with this method.
|
190 |
|
191 |
Method 3 can go wrong if you are using a page caching plugin if that plugin does not create a separate webp cache for webp-enabled browsers. The *Cache Enabler* plugin handles this. I don't believe there are other page caching plugins that does. There is a FAQ section in this FAQ describing how to set *Cache Enabler* up to work in tandem with WebP Express.
|
@@ -238,7 +238,7 @@ location ~* ^/?wp-content/.*\.(png|jpe?g)$ {
|
|
238 |
location ~* ^/?wp-content/.*\.(png|jpe?g)\.webp$ {
|
239 |
try_files
|
240 |
$uri
|
241 |
-
/wp-content/plugins/webp-express/wod/webp-realizer.php?wp-content=wp-content
|
242 |
;
|
243 |
}
|
244 |
# ------------------- (WebP Express rules ends here)
|
@@ -432,7 +432,7 @@ You can also make it "work" on some CDN's by bypassing cache for images. But I r
|
|
432 |
*Status of some CDN's*:
|
433 |
|
434 |
- *KeyCDN*: Does not support varied image responses. I have added a feature request [here](https://community.keycdn.com/t/support-vary-accept-header-for-conditional-webp/1864). You can give it a +1 if you like!
|
435 |
-
- *Cloudflare*: See the "I am on Cloudflare"
|
436 |
- *Cloudfront*: Works, but needs to be configured to forward the accept header. Go to *Distribution settings*, find the *Behavior tab*, select the Behavior and click the Edit button. Choose *Whitelist* from *Forward Headers* and then add the "Accept" header to the whitelist.
|
437 |
|
438 |
I shall add more to the list. You are welcome to help out [here](https://wordpress.org/support/topic/which-cdns-works-in-standard-mode/).
|
@@ -490,7 +490,21 @@ To make *WebP Express* work on a free Cloudflare account, you have the following
|
|
490 |
|
491 |
3. You can switch operation mode to "CDN friendly" and use HTML altering.
|
492 |
|
493 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
494 |
Here is a recipe for using WebP Express together with ShortPixel, such that WebP Express generates the webp's, and ShortPixel only is used to create `<picture>` tags, when it detects a webp image in the same folder as an original.
|
495 |
|
496 |
**There is really no need to do this anymore, because WebP Express is now capable of replacing img tags with picture tags (check out the Alter HTML option)**
|
@@ -645,6 +659,16 @@ Easy enough! - [Go here!](https://ko-fi.com/rosell). Or [here](https://buymeacof
|
|
645 |
|
646 |
== Changelog ==
|
647 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
648 |
= 0.17.0 =
|
649 |
*(released: 27 sep 2019)*
|
650 |
|
@@ -1026,6 +1050,9 @@ For older releases, check out changelog.txt
|
|
1026 |
|
1027 |
== Upgrade Notice ==
|
1028 |
|
|
|
|
|
|
|
1029 |
= 0.17.0 =
|
1030 |
* Improved Cwebp availability and Ewww performance. And updated cwebp binaries to version 1.0.3
|
1031 |
|
4 |
Tags: webp, images, performance
|
5 |
Requires at least: 4.0
|
6 |
Tested up to: 5.2
|
7 |
+
Stable tag: 0.17.1
|
8 |
Requires PHP: 5.6
|
9 |
License: GPLv3
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
134 |
- 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. There is also this [test/troubleshooting script](https://github.com/rosell-dk/webp-convert/wiki/A-PHP-script-for-the-webhost) which is handy when messing around with this.
|
135 |
- Finally, if you have access to another 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.
|
136 |
|
137 |
+
Of course, there is also the option of using another plugin altogether. I can recommend Optimole. If you want to try that out and want to support me in the process, [follow this link](https://optimole.pxf.io/20b0M). It is an affiliate link and will give me a reward in case you decide to sign up.
|
138 |
|
139 |
= It doesn't work - Although test conversions work, it still serves jpeg images =
|
140 |
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.
|
162 |
Can some of these go wrong?
|
163 |
Yes. All!
|
164 |
|
165 |
+
**Method 1: Varied image responses**
|
166 |
The "Varied image responses" method adds rules to the `.htaccess` which redirects jpegs and pngs to the corresponding webps (if they exist). The rules have a condition that makes sure they only trigger for browsers supports webp images (this is established by examining the "accept" header).
|
167 |
|
168 |
I the method "varied image responses" because the response on a given image URL *varies* (the webp is served on the same URL as the jpeg/png).
|
180 |
|
181 |
Since WebP Express 0.15.0 you can use the "Live test" button to check that browsers not supporting webp gets the original files and that the Vary:Accept header is returned. Note however that it may not detect CDN caching problems if the CDN doesn't cache a new image immediately - and across all its nodes.
|
182 |
|
183 |
+
**Method 2: Altering HTML to use picture tags**
|
184 |
IMG tags are replaced with PICTURE tags which has two sources. One of them points to the webp and has the "content-type" set to "image/webp". The other points to the original. The browser will select the webp source if it supports webp and the other source if it doesn't.
|
185 |
|
186 |
Method 2 can go wrong on old browser that doesn't support the picture tag syntax. However, simply enable the "Dynamically load picturefill.js on older browsers" option, and it will take care of that issue.
|
187 |
|
188 |
+
**Method 3: Altering HTML to point directly to webps in webp enabled browsers**
|
189 |
In this solution, the URLs in the HTML are modified for browsers that supports webp. Again, this is determined by examining the "accept" header. So, actually the complete page HTML varies with this method.
|
190 |
|
191 |
Method 3 can go wrong if you are using a page caching plugin if that plugin does not create a separate webp cache for webp-enabled browsers. The *Cache Enabler* plugin handles this. I don't believe there are other page caching plugins that does. There is a FAQ section in this FAQ describing how to set *Cache Enabler* up to work in tandem with WebP Express.
|
238 |
location ~* ^/?wp-content/.*\.(png|jpe?g)\.webp$ {
|
239 |
try_files
|
240 |
$uri
|
241 |
+
/wp-content/plugins/webp-express/wod/webp-realizer.php?xdestination=x$request_filename&wp-content=wp-content
|
242 |
;
|
243 |
}
|
244 |
# ------------------- (WebP Express rules ends here)
|
432 |
*Status of some CDN's*:
|
433 |
|
434 |
- *KeyCDN*: Does not support varied image responses. I have added a feature request [here](https://community.keycdn.com/t/support-vary-accept-header-for-conditional-webp/1864). You can give it a +1 if you like!
|
435 |
+
- *Cloudflare*: See the "I am on Cloudflare" section
|
436 |
- *Cloudfront*: Works, but needs to be configured to forward the accept header. Go to *Distribution settings*, find the *Behavior tab*, select the Behavior and click the Edit button. Choose *Whitelist* from *Forward Headers* and then add the "Accept" header to the whitelist.
|
437 |
|
438 |
I shall add more to the list. You are welcome to help out [here](https://wordpress.org/support/topic/which-cdns-works-in-standard-mode/).
|
490 |
|
491 |
3. You can switch operation mode to "CDN friendly" and use HTML altering.
|
492 |
|
493 |
+
= I am on WP Engine =
|
494 |
+
From version 0.17.1 on WebP Express works with WP engine and this combination will be tested before each release.
|
495 |
+
|
496 |
+
You can use the plugin both in "Varied image responses" mode and in "CDN friendly mode".
|
497 |
+
|
498 |
+
To make the redirection work, you must:
|
499 |
+
1) Grab the nginx configuration found in the "I am on Nginx/OpenResty" section in this FAQ. Use the "try_files" variant.
|
500 |
+
2) Contact help center and ask them to insert that configuration.
|
501 |
+
3) Make sure the settings match this configuration. Follow the "beware" statements in the "I am on Nginx/OpenResty" section.
|
502 |
+
|
503 |
+
WebP Express tweaks the workings of "Redirect to converter" a bit for WP engine. That PHP script usually serves the webp directly, along with a Vary:Accept header. This header is however overwritten by the caching machinery on WP engine. As a work-around, I modified the response of the script for WP engine. Instead of serving the image, it serves a redirect to itself. As there now IS a corresponding webp, this repeated request will not be redirected to the PHP script, but directly to the webp. And headers are OK for those redirects. You can hit the "Live test" button next to "Enable redirection to converter?" to verify that this works as just described.
|
504 |
+
|
505 |
+
If you (contrary to this headline!) are in fact not on WP Engine, but might want to be, I have an affiliate link for you. It will give you 3 months free and it will give me a reward too, if you should decide to stay there. Here you go: [Get 3 months free when you sign up for WP Engine.](https://shareasale.com/r.cfm?b=1343154&u=2194916&m=41388&urllink=&afftrack=)
|
506 |
+
|
507 |
+
= WebP Express / ShortPixel setup =
|
508 |
Here is a recipe for using WebP Express together with ShortPixel, such that WebP Express generates the webp's, and ShortPixel only is used to create `<picture>` tags, when it detects a webp image in the same folder as an original.
|
509 |
|
510 |
**There is really no need to do this anymore, because WebP Express is now capable of replacing img tags with picture tags (check out the Alter HTML option)**
|
659 |
|
660 |
== Changelog ==
|
661 |
|
662 |
+
= 0.17.1 =
|
663 |
+
*(released: 3 Oct 2019)*
|
664 |
+
|
665 |
+
* Fixed NGINX rules in FAQ (added xdestination for the create webp upon request functionality)
|
666 |
+
* Fixed issue with Alter HTML. Thanks to @jonathanernst for discovering issue and supplying the patch.
|
667 |
+
* WebP Express now works on WP Engine. Check out the new "I am on WP Engine" section in the FAQ
|
668 |
+
* Miscellaneous bug fixes
|
669 |
+
|
670 |
+
For more info, see the closed issues on the 0.17.1 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/27?closed=1
|
671 |
+
|
672 |
= 0.17.0 =
|
673 |
*(released: 27 sep 2019)*
|
674 |
|
1050 |
|
1051 |
== Upgrade Notice ==
|
1052 |
|
1053 |
+
= 0.17.1 =
|
1054 |
+
* Miscellaneous bug fixes. Including the NGINX rules in the FAQ (added "xdestination" argument to webp-realizer.php). Now works with WP Engine.
|
1055 |
+
|
1056 |
= 0.17.0 =
|
1057 |
* Improved Cwebp availability and Ewww performance. And updated cwebp binaries to version 1.0.3
|
1058 |
|
changelog.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
= 0.17.0 =
|
2 |
*(released: 27 sep 2019)*
|
3 |
|
1 |
+
= 0.17.1 =
|
2 |
+
*(released: 3 Oct 2019)*
|
3 |
+
|
4 |
+
* Fixed NGINX rules in FAQ (added xdestination for the create webp upon request functionality)
|
5 |
+
* Fixed issue with Alter HTML. Thanks to @jonathanernst for discovering issue and supplying the patch.
|
6 |
+
* WebP Express now works on WP Engine. Check out the new "I am on WP Engine" section in the FAQ
|
7 |
+
* Miscellaneous bug fixes
|
8 |
+
|
9 |
+
For more info, see the closed issues on the 0.17.1 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/27?closed=1
|
10 |
+
|
11 |
= 0.17.0 =
|
12 |
*(released: 27 sep 2019)*
|
13 |
|
lib/classes/AlterHtmlHelper.php
CHANGED
@@ -208,6 +208,10 @@ class AlterHtmlHelper
|
|
208 |
*/
|
209 |
public static function getWebPUrl($sourceUrl, $returnValueOnFail)
|
210 |
{
|
|
|
|
|
|
|
|
|
211 |
|
212 |
// Fail for webp-disabled browsers (when "only-for-webp-enabled-browsers" is set)
|
213 |
if ((self::$options['only-for-webp-enabled-browsers']) && (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') === false)) {
|
@@ -219,11 +223,6 @@ class AlterHtmlHelper
|
|
219 |
return $returnValueOnFail;
|
220 |
}
|
221 |
|
222 |
-
// Get the options
|
223 |
-
if (!isset(self::$options)) {
|
224 |
-
self::$options = json_decode(Option::getOption('webp-express-alter-html-options', null), true);
|
225 |
-
}
|
226 |
-
|
227 |
// Fail if the image type isn't enabled
|
228 |
switch (self::$options['image-types']) {
|
229 |
case 0:
|
208 |
*/
|
209 |
public static function getWebPUrl($sourceUrl, $returnValueOnFail)
|
210 |
{
|
211 |
+
// Get the options
|
212 |
+
if (!isset(self::$options)) {
|
213 |
+
self::$options = json_decode(Option::getOption('webp-express-alter-html-options', null), true);
|
214 |
+
}
|
215 |
|
216 |
// Fail for webp-disabled browsers (when "only-for-webp-enabled-browsers" is set)
|
217 |
if ((self::$options['only-for-webp-enabled-browsers']) && (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') === false)) {
|
223 |
return $returnValueOnFail;
|
224 |
}
|
225 |
|
|
|
|
|
|
|
|
|
|
|
226 |
// Fail if the image type isn't enabled
|
227 |
switch (self::$options['image-types']) {
|
228 |
case 0:
|
lib/classes/Convert.php
CHANGED
@@ -79,12 +79,12 @@ class Convert
|
|
79 |
$checking = 'destination';
|
80 |
$destination = self::getDestination($source, $config);
|
81 |
|
82 |
-
$destination = SanityCheck::
|
83 |
|
84 |
// Check log dir
|
85 |
// -------------------------------
|
86 |
$checking = 'conversion log dir';
|
87 |
-
$logDir = SanityCheck::
|
88 |
|
89 |
|
90 |
} catch (\Exception $e) {
|
79 |
$checking = 'destination';
|
80 |
$destination = self::getDestination($source, $config);
|
81 |
|
82 |
+
$destination = SanityCheck::absPath($destination);
|
83 |
|
84 |
// Check log dir
|
85 |
// -------------------------------
|
86 |
$checking = 'conversion log dir';
|
87 |
+
$logDir = SanityCheck::absPath(Paths::getWebPExpressContentDirAbs() . '/log');
|
88 |
|
89 |
|
90 |
} catch (\Exception $e) {
|
lib/classes/ConvertHelperIndependent.php
CHANGED
@@ -571,7 +571,7 @@ APACHE
|
|
571 |
$text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
|
572 |
|
573 |
// TODO: Put version number somewhere else. Ie \WebPExpress\VersionNumber::version
|
574 |
-
$text = 'WebP Express 0.17.
|
575 |
|
576 |
$logFile = self::getLogFilename($source, $logDir);
|
577 |
|
571 |
$text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
|
572 |
|
573 |
// TODO: Put version number somewhere else. Ie \WebPExpress\VersionNumber::version
|
574 |
+
$text = 'WebP Express 0.17.1. ' . $msgTop . ', ' . date("Y-m-d H:i:s") . "\n\r\n\r" . $text;
|
575 |
|
576 |
$logFile = self::getLogFilename($source, $logDir);
|
577 |
|
lib/classes/PlatformInfo.php
CHANGED
@@ -11,10 +11,12 @@ class PlatformInfo
|
|
11 |
return ( strpos( $server, 'microsoft-iis') !== false );
|
12 |
}
|
13 |
|
|
|
|
|
|
|
14 |
public static function isApache()
|
15 |
{
|
16 |
-
|
17 |
-
return ( strpos( $server, 'apache') !== false );
|
18 |
}
|
19 |
|
20 |
public static function isLiteSpeed()
|
11 |
return ( strpos( $server, 'microsoft-iis') !== false );
|
12 |
}
|
13 |
|
14 |
+
/**
|
15 |
+
* Check if Apache handles the PHP requests (Note that duel setups are possible and ie Nginx could be handling the image requests).
|
16 |
+
*/
|
17 |
public static function isApache()
|
18 |
{
|
19 |
+
return (stripos($_SERVER['SERVER_SOFTWARE'], 'apache') !== false);
|
|
|
20 |
}
|
21 |
|
22 |
public static function isLiteSpeed()
|
lib/classes/SanityCheck.php
CHANGED
@@ -12,7 +12,9 @@ class SanityCheck
|
|
12 |
private static function fail($errorMsg, $input)
|
13 |
{
|
14 |
// sanitize input before calling error_log(), it might be sent to file, mail, syslog etc.
|
|
|
15 |
error_log($errorMsg . '. input:' . Sanitize::removeNUL($input));
|
|
|
16 |
//error_log(get_magic_quotes_gpc() ? 'on' :'off');
|
17 |
throw new SanityException($errorMsg); // . '. Check debug.log for details (and make sure debugging is enabled)'
|
18 |
}
|
@@ -268,7 +270,9 @@ class SanityCheck
|
|
268 |
|
269 |
|
270 |
/**
|
271 |
-
* Test that absolute path is in document root.
|
|
|
|
|
272 |
*
|
273 |
* TODO: Instead of this method, we shoud check
|
274 |
*
|
@@ -279,26 +283,44 @@ class SanityCheck
|
|
279 |
{
|
280 |
self::absPath($input);
|
281 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
282 |
$docRoot = self::absPath($_SERVER["DOCUMENT_ROOT"]);
|
283 |
$docRoot = rtrim($docRoot, '/');
|
284 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
|
286 |
// Use realpath to expand symbolic links and check if it exists
|
287 |
$docRootSymLinksExpanded = @realpath($docRoot);
|
288 |
if ($docRootSymLinksExpanded === false) {
|
289 |
-
|
290 |
-
|
|
|
|
|
|
|
|
|
291 |
}
|
292 |
$docRootSymLinksExpanded = rtrim($docRootSymLinksExpanded, '/');
|
293 |
$docRootSymLinksExpanded = self::absPathExists($docRootSymLinksExpanded, 'Document root does not exist!');
|
294 |
$docRootSymLinksExpanded = self::absPathExistsAndIsDir($docRootSymLinksExpanded, 'Document root is not a directory!');
|
295 |
|
296 |
-
|
297 |
-
|
298 |
-
self::pathBeginsWith($input, $docRoot . '/', $errorMsg);
|
299 |
-
} catch (SanityException $e) {
|
300 |
-
self::pathBeginsWithSymLinksExpanded($input, $docRootSymLinksExpanded . '/', $errorMsg);
|
301 |
-
}
|
302 |
|
303 |
return $input;
|
304 |
}
|
12 |
private static function fail($errorMsg, $input)
|
13 |
{
|
14 |
// sanitize input before calling error_log(), it might be sent to file, mail, syslog etc.
|
15 |
+
//error_log($errorMsg . '. input:' . Sanitize::removeNUL($input) . 'backtrace: ' . print_r(debug_backtrace(), true));
|
16 |
error_log($errorMsg . '. input:' . Sanitize::removeNUL($input));
|
17 |
+
|
18 |
//error_log(get_magic_quotes_gpc() ? 'on' :'off');
|
19 |
throw new SanityException($errorMsg); // . '. Check debug.log for details (and make sure debugging is enabled)'
|
20 |
}
|
270 |
|
271 |
|
272 |
/**
|
273 |
+
* Test that path is an absolute path and it is in document root.
|
274 |
+
*
|
275 |
+
* If DOCUMENT_ROOT is not available, then only the absPath check will be done.
|
276 |
*
|
277 |
* TODO: Instead of this method, we shoud check
|
278 |
*
|
283 |
{
|
284 |
self::absPath($input);
|
285 |
|
286 |
+
if (!isset($_SERVER["DOCUMENT_ROOT"])) {
|
287 |
+
return $input;
|
288 |
+
}
|
289 |
+
if ($_SERVER["DOCUMENT_ROOT"] == '') {
|
290 |
+
return $input;
|
291 |
+
}
|
292 |
+
|
293 |
$docRoot = self::absPath($_SERVER["DOCUMENT_ROOT"]);
|
294 |
$docRoot = rtrim($docRoot, '/');
|
295 |
+
|
296 |
+
try {
|
297 |
+
$docRoot = self::absPathExistsAndIsDir($docRoot);
|
298 |
+
} catch (SanityException $e) {
|
299 |
+
return $input;
|
300 |
+
}
|
301 |
+
|
302 |
+
// See if $filePath begins with $dirPath + '/'. If it does, we are done and OK!
|
303 |
+
if (strpos($input, $docRoot . '/') === 0) {
|
304 |
+
return $input;
|
305 |
+
}
|
306 |
+
|
307 |
|
308 |
// Use realpath to expand symbolic links and check if it exists
|
309 |
$docRootSymLinksExpanded = @realpath($docRoot);
|
310 |
if ($docRootSymLinksExpanded === false) {
|
311 |
+
// probably outside open basedir restriction.
|
312 |
+
//$errorMsg = 'Cannot resolve document root';
|
313 |
+
//self::fail($errorMsg, $input);
|
314 |
+
|
315 |
+
// Cannot resolve document root, so cannot test if in document root
|
316 |
+
return $input;
|
317 |
}
|
318 |
$docRootSymLinksExpanded = rtrim($docRootSymLinksExpanded, '/');
|
319 |
$docRootSymLinksExpanded = self::absPathExists($docRootSymLinksExpanded, 'Document root does not exist!');
|
320 |
$docRootSymLinksExpanded = self::absPathExistsAndIsDir($docRootSymLinksExpanded, 'Document root is not a directory!');
|
321 |
|
322 |
+
$errorMsg = 'Path is outside resolved document root (' . $docRootSymLinksExpanded . ')';
|
323 |
+
self::pathBeginsWithSymLinksExpanded($input, $docRootSymLinksExpanded . '/', $errorMsg);
|
|
|
|
|
|
|
|
|
324 |
|
325 |
return $input;
|
326 |
}
|
lib/classes/SelfTestHelper.php
CHANGED
@@ -50,22 +50,22 @@ class SelfTestHelper
|
|
50 |
|
51 |
public static function copyFile($source, $destination)
|
52 |
{
|
53 |
-
$
|
54 |
if (@copy($source, $destination)) {
|
55 |
-
return [true, $
|
56 |
} else {
|
57 |
-
$
|
58 |
if (!@file_exists($source)) {
|
59 |
-
$
|
60 |
} else {
|
61 |
if (!@file_exists(dirname($destination))) {
|
62 |
-
$
|
63 |
} else {
|
64 |
-
$
|
65 |
'write files in the directory (*' . dirname($destination) . '*)';
|
66 |
}
|
67 |
}
|
68 |
-
return [false, $
|
69 |
}
|
70 |
}
|
71 |
|
@@ -84,7 +84,7 @@ class SelfTestHelper
|
|
84 |
{
|
85 |
// TODO: Copy to a subfolder instead
|
86 |
// TODO: Use smaller jpeg / pngs please.
|
87 |
-
$
|
88 |
switch ($imageType) {
|
89 |
case 'jpeg':
|
90 |
$fileNameToCopy = 'very-small.jpg';
|
@@ -96,30 +96,30 @@ class SelfTestHelper
|
|
96 |
$testSource = Paths::getPluginDirAbs() . '/webp-express/test/' . $fileNameToCopy;
|
97 |
$filenameOfDestination = self::randomDigitsAndLetters(6) . '.' . strtoupper($imageType);
|
98 |
//$filenameOfDestination = self::randomDigitsAndLetters(6) . '.' . $imageType;
|
99 |
-
$
|
100 |
|
101 |
$destDir = Paths::getAbsDirById($rootId) . '/webp-express-test-images';
|
102 |
$destination = $destDir . '/' . $filenameOfDestination;
|
103 |
|
104 |
if (!@file_exists($destDir)) {
|
105 |
if (!@mkdir($destDir)) {
|
106 |
-
$
|
107 |
-
$
|
108 |
-
return [$
|
109 |
}
|
110 |
}
|
111 |
|
112 |
list($success, $errors) = self::copyFile($testSource, $destination);
|
113 |
if (!$success) {
|
114 |
-
$
|
115 |
-
$
|
116 |
-
return [$
|
117 |
} else {
|
118 |
-
$
|
119 |
-
$
|
120 |
-
$
|
121 |
}
|
122 |
-
return [$
|
123 |
}
|
124 |
|
125 |
public static function copyTestImageToUploadFolder($imageType = 'jpeg')
|
@@ -129,25 +129,25 @@ class SelfTestHelper
|
|
129 |
|
130 |
public static function copyDummyWebPToCacheFolder($rootId, $destinationFolder, $destinationExtension, $destinationStructure, $sourceFileName, $imageType = 'jpeg')
|
131 |
{
|
132 |
-
$
|
133 |
$dummyWebP = Paths::getPluginDirAbs() . '/webp-express/test/test.jpg.webp';
|
134 |
|
135 |
-
$
|
136 |
$destDir = Paths::getCacheDirForImageRoot($destinationFolder, $destinationStructure, $rootId);
|
137 |
if (!file_exists($destDir)) {
|
138 |
-
$
|
139 |
if (!mkdir($destDir, 0777, true)) {
|
140 |
-
$
|
141 |
-
return [$
|
142 |
}
|
143 |
}
|
144 |
$destDir .= '/webp-express-test-images';
|
145 |
if (!file_exists($destDir)) {
|
146 |
if (!mkdir($destDir, 0755, false)) {
|
147 |
-
$
|
148 |
-
$
|
149 |
-
$
|
150 |
-
return [$
|
151 |
}
|
152 |
}
|
153 |
|
@@ -163,48 +163,84 @@ class SelfTestHelper
|
|
163 |
|
164 |
list($success, $errors) = self::copyFile($dummyWebP, $destination);
|
165 |
if (!$success) {
|
166 |
-
$
|
167 |
-
$
|
168 |
-
return [$
|
169 |
} else {
|
170 |
-
$
|
171 |
-
$
|
172 |
-
$
|
173 |
-
$
|
174 |
}
|
175 |
-
return [$
|
176 |
}
|
177 |
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
{
|
180 |
-
$
|
181 |
-
$
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
if ($
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
$result[] = 'Body:';
|
200 |
-
$result[] = print_r($return['body'], true);
|
201 |
-
}
|
202 |
|
|
|
|
|
|
|
|
|
|
|
|
|
203 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
|
205 |
-
|
|
|
|
|
|
|
206 |
}
|
207 |
-
|
|
|
|
|
208 |
}
|
209 |
|
210 |
public static function hasHeaderContaining($headers, $headerToInspect, $containString)
|
@@ -265,23 +301,23 @@ class SelfTestHelper
|
|
265 |
|
266 |
public static function flattenHeaders($headers)
|
267 |
{
|
268 |
-
$
|
269 |
foreach ($headers as $headerName => $headerValue) {
|
270 |
if (gettype($headerValue) == 'array') {
|
271 |
foreach ($headerValue as $i => $value) {
|
272 |
-
$
|
273 |
}
|
274 |
} else {
|
275 |
-
$
|
276 |
}
|
277 |
}
|
278 |
-
return $
|
279 |
}
|
280 |
|
281 |
public static function printHeaders($headers)
|
282 |
{
|
283 |
-
$
|
284 |
-
$
|
285 |
|
286 |
$headersFlat = self::flattenHeaders($headers);
|
287 |
//
|
@@ -289,10 +325,10 @@ class SelfTestHelper
|
|
289 |
if ($headerName == 'x-webp-express-error') {
|
290 |
$headerValue = '**' . $headerValue . '**{: .error}';
|
291 |
}
|
292 |
-
$
|
293 |
}
|
294 |
-
$
|
295 |
-
return $
|
296 |
}
|
297 |
|
298 |
private static function trueFalseNullString($var)
|
@@ -308,109 +344,109 @@ class SelfTestHelper
|
|
308 |
|
309 |
public static function systemInfo()
|
310 |
{
|
311 |
-
$
|
312 |
-
$
|
313 |
-
$
|
314 |
-
$
|
315 |
-
$
|
316 |
-
$
|
317 |
if (PathHelper::isDocRootAvailable()) {
|
318 |
-
$
|
319 |
}
|
320 |
if (PathHelper::isDocRootAvailableAndResolvable()) {
|
321 |
if ($_SERVER['DOCUMENT_ROOT'] != realpath($_SERVER['DOCUMENT_ROOT'])) {
|
322 |
-
$
|
323 |
}
|
324 |
}
|
325 |
|
326 |
-
$
|
327 |
-
$
|
328 |
-
$
|
329 |
-
return $
|
330 |
}
|
331 |
|
332 |
public static function wordpressInfo()
|
333 |
{
|
334 |
-
$
|
335 |
-
$
|
336 |
-
$
|
337 |
-
$
|
338 |
-
$
|
339 |
-
$
|
340 |
-
$
|
341 |
|
342 |
-
$
|
343 |
|
344 |
-
$
|
345 |
foreach (Paths::getImageRootIds() as $rootId) {
|
346 |
$absDir = Paths::getAbsDirById($rootId);
|
347 |
|
348 |
if (PathHelper::pathExistsAndIsResolvable($absDir) && ($absDir != realpath($absDir))) {
|
349 |
-
$
|
350 |
} else {
|
351 |
-
$
|
352 |
|
353 |
}
|
354 |
}
|
355 |
|
356 |
-
$
|
357 |
foreach (Paths::getImageRootIds() as $rootId) {
|
358 |
$absPath = Paths::getAbsDirById($rootId);
|
359 |
if (PathHelper::canCalculateRelPathFromDocRootToDir($absPath)) {
|
360 |
-
$
|
361 |
} else {
|
362 |
-
$
|
363 |
}
|
364 |
}
|
365 |
|
366 |
-
$
|
367 |
foreach (Paths::getImageRootIds() as $rootId) {
|
368 |
$url = Paths::getUrlById($rootId);
|
369 |
-
$
|
370 |
}
|
371 |
|
372 |
|
373 |
-
return $
|
374 |
}
|
375 |
|
376 |
public static function configInfo($config)
|
377 |
{
|
378 |
-
$
|
379 |
-
$
|
380 |
-
$
|
381 |
-
$
|
382 |
-
$
|
383 |
-
//$
|
384 |
-
//$
|
385 |
-
$
|
386 |
-
return $
|
387 |
}
|
388 |
|
389 |
public static function htaccessInfo($config, $printRules = true)
|
390 |
{
|
391 |
-
$
|
392 |
-
//$
|
393 |
-
//$
|
394 |
-
$
|
395 |
$rootIds = HTAccess::getRootsWithWebPExpressRulesIn();
|
396 |
foreach ($rootIds as $imageRootId) {
|
397 |
-
$
|
398 |
}
|
399 |
|
400 |
foreach ($rootIds as $imageRootId) {
|
401 |
-
$
|
402 |
}
|
403 |
|
404 |
-
return $
|
405 |
}
|
406 |
|
407 |
public static function rulesInImageRoot($config, $imageRootId)
|
408 |
{
|
409 |
-
$
|
410 |
-
$
|
411 |
$file = Paths::getAbsDirById($imageRootId) . '/.htaccess';
|
412 |
if (!HTAccess::haveWeRulesInThisHTAccess($file)) {
|
413 |
-
$
|
414 |
} else {
|
415 |
$weRules = HTAccess::extractWebPExpressRulesFromHTAccess($file);
|
416 |
// remove unindented comments
|
@@ -423,9 +459,9 @@ class SelfTestHelper
|
|
423 |
}
|
424 |
$weRules = implode("\n", $weRulesArr);
|
425 |
|
426 |
-
$
|
427 |
}
|
428 |
-
return $
|
429 |
}
|
430 |
|
431 |
public static function rulesInUpload($config)
|
@@ -435,117 +471,117 @@ class SelfTestHelper
|
|
435 |
|
436 |
public static function allInfo($config)
|
437 |
{
|
438 |
-
$
|
439 |
-
$
|
440 |
-
$
|
441 |
-
$
|
442 |
-
$
|
443 |
-
$
|
444 |
-
//$
|
445 |
-
//$
|
446 |
-
return $
|
447 |
}
|
448 |
|
449 |
public static function capabilityTests($config)
|
450 |
{
|
451 |
$capTests = $config['base-htaccess-on-these-capability-tests'];
|
452 |
-
$
|
453 |
-
$
|
454 |
-
/*$
|
455 |
'makes some live tests to verify if a certain feature in fact works. This is done by creating ' .
|
456 |
'test files (*.htaccess* files and php files) in a dir inside the content dir and running these. ' .
|
457 |
'These test results are used when creating the rewrite rules. Here are the results:';*/
|
458 |
|
459 |
-
// $
|
460 |
-
$
|
461 |
-
$
|
462 |
-
/*$
|
463 |
self::trueFalseNullString($capTests['passThroughHeaderWorking']);*/
|
464 |
-
$
|
465 |
-
return $
|
466 |
}
|
467 |
|
468 |
public static function diagnoseFailedRewrite($config)
|
469 |
{
|
470 |
if (($config['destination-structure'] == 'image-roots') && (!PathHelper::isDocRootAvailableAndResolvable())) {
|
471 |
-
$
|
472 |
if (!PathHelper::isDocRootAvailable()) {
|
473 |
-
$
|
474 |
} else {
|
475 |
-
$
|
476 |
}
|
477 |
-
$
|
478 |
-
$
|
479 |
|
480 |
-
$
|
481 |
'But if it is, there you have it. The line beginning with "RewriteCond %{REQUEST_FILENAME}"" points to your resolved root, ' .
|
482 |
'but it should point to your symlinked root. WebP Express cannot do that for you because it cannot discover what the symlink is. ' .
|
483 |
'Try changing the line manually. When it works, you can move the rules outside the WebP Express block so they dont get ' .
|
484 |
'overwritten. OR you can change your server configuration (document root / open_basedir restrictions)';
|
485 |
}
|
486 |
|
487 |
-
//$
|
488 |
if (PlatformInfo::isNginx()) {
|
489 |
// Nginx
|
490 |
-
$
|
491 |
'have any effect. ';
|
492 |
-
$
|
493 |
-
$
|
494 |
|
495 |
-
$
|
496 |
-
return $
|
497 |
}
|
498 |
|
499 |
$modRewriteWorking = CapabilityTest::modRewriteWorking();
|
500 |
if ($modRewriteWorking !== null) {
|
501 |
-
$
|
502 |
}
|
503 |
if ($modRewriteWorking === true) {
|
504 |
-
$
|
505 |
-
$
|
506 |
'to change "Destination structure" - the rules there are quite different.';
|
507 |
-
$
|
508 |
'does that. In that case, simply give it a few minutes and try again.';
|
509 |
} elseif ($modRewriteWorking === false) {
|
510 |
-
$
|
511 |
if (PlatformInfo::definitelyNotGotModRewrite()) {
|
512 |
-
$
|
513 |
'**You must enable mod_rewrite on the server**';
|
514 |
} elseif (PlatformInfo::definitelyGotApacheModule('mod_rewrite')) {
|
515 |
-
$
|
516 |
'*.htaccess* files has been disabled for configuration on your server. ' .
|
517 |
'In that case, you need to copy the WebP Express rules from the *.htaccess* files into your virtual host configuration files. ' .
|
518 |
'(WebP Express generates multiple *.htaccess* files. Look in the upload folder, the wp-content folder, etc).';
|
519 |
-
$
|
520 |
'Some servers caches the *.htaccess* rules for a bit. In that case, simply give it a few minutes and try again.';
|
521 |
} else {
|
522 |
-
$
|
523 |
'Give it a few minutes and try again.';
|
524 |
}
|
525 |
} else {
|
526 |
// The mod_rewrite test could not conclude anything.
|
527 |
if (PlatformInfo::definitelyNotGotApacheModule('mod_rewrite')) {
|
528 |
-
$
|
529 |
'**You must enable mod_rewrite on the server**';
|
530 |
} elseif (PlatformInfo::definitelyGotApacheModule('mod_rewrite')) {
|
531 |
-
$
|
532 |
'However, it could be that your server setup has disabled *.htaccess* files for configuration. ' .
|
533 |
'In that case, you need to copy the WebP Express rules from the *.htaccess* files into your virtual host configuration files. ' .
|
534 |
'(WebP Express generates multiple *.htaccess* files. Look in the upload folder, the wp-content folder, etc). ';
|
535 |
} else {
|
536 |
-
$
|
537 |
-
$
|
538 |
'does that. In that case, simply give it a few minutes and try again.';
|
539 |
}
|
540 |
}
|
541 |
-
$
|
542 |
'rely on the "Alter HTML" functionality to point to the webp images. If you do a bulk conversion ' .
|
543 |
'and make sure that "Convert upon upload" is activated, you should be all set. Alter HTML even handles ' .
|
544 |
'inline css (unless you select "picture tag" syntax). It does however not handle images in external css or ' .
|
545 |
'which is added dynamically with javascript.';
|
546 |
|
547 |
-
$
|
548 |
-
$
|
549 |
-
return $
|
550 |
}
|
551 |
}
|
50 |
|
51 |
public static function copyFile($source, $destination)
|
52 |
{
|
53 |
+
$log = [];
|
54 |
if (@copy($source, $destination)) {
|
55 |
+
return [true, $log];
|
56 |
} else {
|
57 |
+
$log[] = 'Failed to copy *' . $source . '* to *' . $destination . '*';
|
58 |
if (!@file_exists($source)) {
|
59 |
+
$log[] = 'The source file was not found';
|
60 |
} else {
|
61 |
if (!@file_exists(dirname($destination))) {
|
62 |
+
$log[] = 'The destination folder does not exist!';
|
63 |
} else {
|
64 |
+
$log[] = 'This is probably a permission issue. Check that your webserver has permission to ' .
|
65 |
'write files in the directory (*' . dirname($destination) . '*)';
|
66 |
}
|
67 |
}
|
68 |
+
return [false, $log];
|
69 |
}
|
70 |
}
|
71 |
|
84 |
{
|
85 |
// TODO: Copy to a subfolder instead
|
86 |
// TODO: Use smaller jpeg / pngs please.
|
87 |
+
$log = [];
|
88 |
switch ($imageType) {
|
89 |
case 'jpeg':
|
90 |
$fileNameToCopy = 'very-small.jpg';
|
96 |
$testSource = Paths::getPluginDirAbs() . '/webp-express/test/' . $fileNameToCopy;
|
97 |
$filenameOfDestination = self::randomDigitsAndLetters(6) . '.' . strtoupper($imageType);
|
98 |
//$filenameOfDestination = self::randomDigitsAndLetters(6) . '.' . $imageType;
|
99 |
+
$log[] = 'Copying ' . strtoupper($imageType) . ' to ' . $rootId . ' folder (*webp-express-test-images/' . $filenameOfDestination . '*)';
|
100 |
|
101 |
$destDir = Paths::getAbsDirById($rootId) . '/webp-express-test-images';
|
102 |
$destination = $destDir . '/' . $filenameOfDestination;
|
103 |
|
104 |
if (!@file_exists($destDir)) {
|
105 |
if (!@mkdir($destDir)) {
|
106 |
+
$log[count($log) - 1] .= '. FAILED';
|
107 |
+
$log[] = 'Failed to create folder for test images: ' . $destDir;
|
108 |
+
return [$log, false, ''];
|
109 |
}
|
110 |
}
|
111 |
|
112 |
list($success, $errors) = self::copyFile($testSource, $destination);
|
113 |
if (!$success) {
|
114 |
+
$log[count($log) - 1] .= '. FAILED';
|
115 |
+
$log = array_merge($log, $errors);
|
116 |
+
return [$log, false, ''];
|
117 |
} else {
|
118 |
+
$log[count($log) - 1] .= '. ok!';
|
119 |
+
$log[] = 'We now have a ' . $imageType . ' stored here:';
|
120 |
+
$log[] = '*' . $destination . '*';
|
121 |
}
|
122 |
+
return [$log, true, $filenameOfDestination];
|
123 |
}
|
124 |
|
125 |
public static function copyTestImageToUploadFolder($imageType = 'jpeg')
|
129 |
|
130 |
public static function copyDummyWebPToCacheFolder($rootId, $destinationFolder, $destinationExtension, $destinationStructure, $sourceFileName, $imageType = 'jpeg')
|
131 |
{
|
132 |
+
$log = [];
|
133 |
$dummyWebP = Paths::getPluginDirAbs() . '/webp-express/test/test.jpg.webp';
|
134 |
|
135 |
+
$log[] = 'Copying dummy webp to the cache root for ' . $rootId;
|
136 |
$destDir = Paths::getCacheDirForImageRoot($destinationFolder, $destinationStructure, $rootId);
|
137 |
if (!file_exists($destDir)) {
|
138 |
+
$log[] = 'The folder did not exist. Creating folder at: ' . $destinationFolder;
|
139 |
if (!mkdir($destDir, 0777, true)) {
|
140 |
+
$log[] = 'Failed creating folder!';
|
141 |
+
return [$log, false, ''];
|
142 |
}
|
143 |
}
|
144 |
$destDir .= '/webp-express-test-images';
|
145 |
if (!file_exists($destDir)) {
|
146 |
if (!mkdir($destDir, 0755, false)) {
|
147 |
+
$log[] = 'Failed creating the folder for the test images:';
|
148 |
+
$log[] = $destDir;
|
149 |
+
$log[] = 'To run this test, you must grant write permissions';
|
150 |
+
return [$log, false, ''];
|
151 |
}
|
152 |
}
|
153 |
|
163 |
|
164 |
list($success, $errors) = self::copyFile($dummyWebP, $destination);
|
165 |
if (!$success) {
|
166 |
+
$log[count($log) - 1] .= '. FAILED';
|
167 |
+
$log = array_merge($log, $errors);
|
168 |
+
return [$log, false, ''];
|
169 |
} else {
|
170 |
+
$log[count($log) - 1] .= '. ok!';
|
171 |
+
$log[] = 'We now have a webp file stored here:';
|
172 |
+
$log[] = '*' . $destination . '*';
|
173 |
+
$log[] = '';
|
174 |
}
|
175 |
+
return [$log, true, $destination];
|
176 |
}
|
177 |
|
178 |
+
/**
|
179 |
+
* Perform HTTP request.
|
180 |
+
*
|
181 |
+
* @param string $requestUrl URL
|
182 |
+
* @param array $args Args to pass to wp_remote_get. Note however that "redirection" is set to 0
|
183 |
+
* @param int $maxRedirects For internal use
|
184 |
+
* @return array The result
|
185 |
+
* $success (boolean): If we got a 200 response in the end (after max 2 redirects)
|
186 |
+
* $log (array) : Message log
|
187 |
+
* $results : Array of results from wp_remote_get. If no redirection occured, it will only contain one item.
|
188 |
+
*
|
189 |
+
*/
|
190 |
+
public static function remoteGet($requestUrl, $args = [], $maxRedirects = 2)
|
191 |
{
|
192 |
+
$log = [];
|
193 |
+
$args['redirection'] = 0;
|
194 |
+
|
195 |
+
$log[] = 'Request URL: ' . $requestUrl;
|
196 |
+
|
197 |
+
$results = [];
|
198 |
+
$wpResult = wp_remote_get($requestUrl, $args);
|
199 |
+
if (!isset($wpResult['headers'])) {
|
200 |
+
$wpResult['headers'] = [];
|
201 |
+
}
|
202 |
+
$results[] = $wpResult;
|
203 |
+
if (is_wp_error($wpResult)) {
|
204 |
+
$log[] = 'The remote request errored';
|
205 |
+
return [false, $log, $results];
|
206 |
+
}
|
207 |
+
$responseCode = $wpResult['response']['code'];
|
208 |
+
|
209 |
+
$log[] = 'Response: ' . $responseCode . ' ' . $wpResult['response']['message'];
|
210 |
+
$log = array_merge($log, SelfTestHelper::printHeaders($wpResult['headers']));
|
|
|
|
|
|
|
211 |
|
212 |
+
if (isset($wpResult['headers']['content-type'])) {
|
213 |
+
if (strpos($wpResult['headers']['content-type'], 'text/html') !== false) {
|
214 |
+
if (isset($wpResult['body']) && (!empty($wpResult['body']))) {
|
215 |
+
$log[] = 'Body:';
|
216 |
+
$log[] = print_r($wpResult['body'], true);
|
217 |
+
}
|
218 |
}
|
219 |
+
}
|
220 |
+
|
221 |
+
if (($responseCode == '302') || ($responseCode == '301')) {
|
222 |
+
if ($maxRedirects > 0) {
|
223 |
+
if (isset($wpResult['headers']['location'])) {
|
224 |
+
$url = $wpResult['headers']['location'];
|
225 |
+
if (strpos($url, 'http') !== 0) {
|
226 |
+
$url = $requestUrl . $url;
|
227 |
+
}
|
228 |
+
$log[] = 'Following that redirect';
|
229 |
+
|
230 |
+
list($success, $newLog, $newResult) = self::remoteGet($url, $args, $maxRedirects - 1);
|
231 |
+
$log = array_merge($log, $newLog);
|
232 |
+
$results = array_merge($results, $newResult);
|
233 |
+
|
234 |
+
return [$success, $log, $results];
|
235 |
|
236 |
+
}
|
237 |
+
} else {
|
238 |
+
$log[] = 'Not following the redirect (max redirects exceeded)';
|
239 |
+
}
|
240 |
}
|
241 |
+
|
242 |
+
$success = ($responseCode == '200');
|
243 |
+
return [$success, $log, $results];
|
244 |
}
|
245 |
|
246 |
public static function hasHeaderContaining($headers, $headerToInspect, $containString)
|
301 |
|
302 |
public static function flattenHeaders($headers)
|
303 |
{
|
304 |
+
$log = [];
|
305 |
foreach ($headers as $headerName => $headerValue) {
|
306 |
if (gettype($headerValue) == 'array') {
|
307 |
foreach ($headerValue as $i => $value) {
|
308 |
+
$log[] = [$headerName, $value];
|
309 |
}
|
310 |
} else {
|
311 |
+
$log[] = [$headerName, $headerValue];
|
312 |
}
|
313 |
}
|
314 |
+
return $log;
|
315 |
}
|
316 |
|
317 |
public static function printHeaders($headers)
|
318 |
{
|
319 |
+
$log = [];
|
320 |
+
$log[] = '#### Response headers:';
|
321 |
|
322 |
$headersFlat = self::flattenHeaders($headers);
|
323 |
//
|
325 |
if ($headerName == 'x-webp-express-error') {
|
326 |
$headerValue = '**' . $headerValue . '**{: .error}';
|
327 |
}
|
328 |
+
$log[] = '- ' . $headerName . ': ' . $headerValue;
|
329 |
}
|
330 |
+
$log[] = '';
|
331 |
+
return $log;
|
332 |
}
|
333 |
|
334 |
private static function trueFalseNullString($var)
|
344 |
|
345 |
public static function systemInfo()
|
346 |
{
|
347 |
+
$log = [];
|
348 |
+
$log[] = '#### System info:';
|
349 |
+
$log[] = '- PHP version: ' . phpversion();
|
350 |
+
$log[] = '- OS: ' . PHP_OS;
|
351 |
+
$log[] = '- Server software: ' . $_SERVER["SERVER_SOFTWARE"];
|
352 |
+
$log[] = '- Document Root status: ' . Paths::docRootStatusText();
|
353 |
if (PathHelper::isDocRootAvailable()) {
|
354 |
+
$log[] = '- Document Root: ' . $_SERVER['DOCUMENT_ROOT'];
|
355 |
}
|
356 |
if (PathHelper::isDocRootAvailableAndResolvable()) {
|
357 |
if ($_SERVER['DOCUMENT_ROOT'] != realpath($_SERVER['DOCUMENT_ROOT'])) {
|
358 |
+
$log[] = '- Document Root (symlinked resolved): ' . realpath($_SERVER['DOCUMENT_ROOT']);
|
359 |
}
|
360 |
}
|
361 |
|
362 |
+
$log[] = '- Document Root: ' . Paths::docRootStatusText();
|
363 |
+
$log[] = '- Apache module "mod_rewrite" enabled?: ' . self::trueFalseNullString(PlatformInfo::gotApacheModule('mod_rewrite'));
|
364 |
+
$log[] = '- Apache module "mod_headers" enabled?: ' . self::trueFalseNullString(PlatformInfo::gotApacheModule('mod_headers'));
|
365 |
+
return $log;
|
366 |
}
|
367 |
|
368 |
public static function wordpressInfo()
|
369 |
{
|
370 |
+
$log = [];
|
371 |
+
$log[] = '#### Wordpress info:';
|
372 |
+
$log[] = '- Version: ' . get_bloginfo('version');
|
373 |
+
$log[] = '- Multisite?: ' . self::trueFalseNullString(is_multisite());
|
374 |
+
$log[] = '- Is wp-content moved?: ' . self::trueFalseNullString(Paths::isWPContentDirMoved());
|
375 |
+
$log[] = '- Is uploads moved out of wp-content?: ' . self::trueFalseNullString(Paths::isUploadDirMovedOutOfWPContentDir());
|
376 |
+
$log[] = '- Is plugins moved out of wp-content?: ' . self::trueFalseNullString(Paths::isPluginDirMovedOutOfWpContent());
|
377 |
|
378 |
+
$log[] = '';
|
379 |
|
380 |
+
$log[] = '#### Image roots (absolute paths)';
|
381 |
foreach (Paths::getImageRootIds() as $rootId) {
|
382 |
$absDir = Paths::getAbsDirById($rootId);
|
383 |
|
384 |
if (PathHelper::pathExistsAndIsResolvable($absDir) && ($absDir != realpath($absDir))) {
|
385 |
+
$log[] = '*' . $rootId . '*: ' . $absDir . ' (resolved for symlinks: ' . realpath($absDir) . ')';
|
386 |
} else {
|
387 |
+
$log[] = '*' . $rootId . '*: ' . $absDir;
|
388 |
|
389 |
}
|
390 |
}
|
391 |
|
392 |
+
$log[] = '#### Image roots (relative to document root)';
|
393 |
foreach (Paths::getImageRootIds() as $rootId) {
|
394 |
$absPath = Paths::getAbsDirById($rootId);
|
395 |
if (PathHelper::canCalculateRelPathFromDocRootToDir($absPath)) {
|
396 |
+
$log[] = '*' . $rootId . '*: ' . PathHelper::getRelPathFromDocRootToDirNoDirectoryTraversalAllowed($absPath);
|
397 |
} else {
|
398 |
+
$log[] = '*' . $rootId . '*: ' . 'n/a (not within document root)';
|
399 |
}
|
400 |
}
|
401 |
|
402 |
+
$log[] = '#### Image roots (URLs)';
|
403 |
foreach (Paths::getImageRootIds() as $rootId) {
|
404 |
$url = Paths::getUrlById($rootId);
|
405 |
+
$log[] = '*' . $rootId . '*: ' . $url;
|
406 |
}
|
407 |
|
408 |
|
409 |
+
return $log;
|
410 |
}
|
411 |
|
412 |
public static function configInfo($config)
|
413 |
{
|
414 |
+
$log = [];
|
415 |
+
$log[] = '#### WebP Express configuration info:';
|
416 |
+
$log[] = '- Destination folder: ' . $config['destination-folder'];
|
417 |
+
$log[] = '- Destination extension: ' . $config['destination-extension'];
|
418 |
+
$log[] = '- Destination structure: ' . $config['destination-structure'];
|
419 |
+
//$log[] = 'Image types: ' . ;
|
420 |
+
//$log[] = '';
|
421 |
+
$log[] = '(To view all configuration, take a look at the config file, which is stored in *' . Paths::getConfigFileName() . '*)';
|
422 |
+
return $log;
|
423 |
}
|
424 |
|
425 |
public static function htaccessInfo($config, $printRules = true)
|
426 |
{
|
427 |
+
$log = [];
|
428 |
+
//$log[] = '*.htaccess info:*';
|
429 |
+
//$log[] = '- Image roots with WebP Express rules: ' . implode(', ', HTAccess::getRootsWithWebPExpressRulesIn());
|
430 |
+
$log[] = '#### .htaccess files that WebP Express have placed rules in the following files:';
|
431 |
$rootIds = HTAccess::getRootsWithWebPExpressRulesIn();
|
432 |
foreach ($rootIds as $imageRootId) {
|
433 |
+
$log[] = '- ' . Paths::getAbsDirById($imageRootId) . '/.htaccess';
|
434 |
}
|
435 |
|
436 |
foreach ($rootIds as $imageRootId) {
|
437 |
+
$log = array_merge($log, self::rulesInImageRoot($config, $imageRootId));
|
438 |
}
|
439 |
|
440 |
+
return $log;
|
441 |
}
|
442 |
|
443 |
public static function rulesInImageRoot($config, $imageRootId)
|
444 |
{
|
445 |
+
$log = [];
|
446 |
+
$log[] = '#### WebP rules in *' . $imageRootId . '*:';
|
447 |
$file = Paths::getAbsDirById($imageRootId) . '/.htaccess';
|
448 |
if (!HTAccess::haveWeRulesInThisHTAccess($file)) {
|
449 |
+
$log[] = '**NONE!**{: .warn}';
|
450 |
} else {
|
451 |
$weRules = HTAccess::extractWebPExpressRulesFromHTAccess($file);
|
452 |
// remove unindented comments
|
459 |
}
|
460 |
$weRules = implode("\n", $weRulesArr);
|
461 |
|
462 |
+
$log[] = '```' . $weRules . '```';
|
463 |
}
|
464 |
+
return $log;
|
465 |
}
|
466 |
|
467 |
public static function rulesInUpload($config)
|
471 |
|
472 |
public static function allInfo($config)
|
473 |
{
|
474 |
+
$log = [];
|
475 |
+
$log = array_merge($log, self::systemInfo());
|
476 |
+
$log = array_merge($log, self::wordpressInfo());
|
477 |
+
$log = array_merge($log, self::configInfo($config));
|
478 |
+
$log = array_merge($log, self::capabilityTests($config));
|
479 |
+
$log = array_merge($log, self::htaccessInfo($config, true));
|
480 |
+
//$log = array_merge($log, self::rulesInImageRoot($config, 'upload'));
|
481 |
+
//$log = array_merge($log, self::rulesInImageRoot($config, 'wp-content'));
|
482 |
+
return $log;
|
483 |
}
|
484 |
|
485 |
public static function capabilityTests($config)
|
486 |
{
|
487 |
$capTests = $config['base-htaccess-on-these-capability-tests'];
|
488 |
+
$log = [];
|
489 |
+
$log[] = '#### Live tests of .htaccess capabilities:';
|
490 |
+
/*$log[] = 'Exactly what you can do in a *.htaccess* depends on the server setup. WebP Express ' .
|
491 |
'makes some live tests to verify if a certain feature in fact works. This is done by creating ' .
|
492 |
'test files (*.htaccess* files and php files) in a dir inside the content dir and running these. ' .
|
493 |
'These test results are used when creating the rewrite rules. Here are the results:';*/
|
494 |
|
495 |
+
// $log[] = '';
|
496 |
+
$log[] = '- mod_rewrite working?: ' . self::trueFalseNullString(CapabilityTest::modRewriteWorking());
|
497 |
+
$log[] = '- mod_header working?: ' . self::trueFalseNullString($capTests['modHeaderWorking']);
|
498 |
+
/*$log[] = '- pass variable from *.htaccess* to script through header working?: ' .
|
499 |
self::trueFalseNullString($capTests['passThroughHeaderWorking']);*/
|
500 |
+
$log[] = '- passing variables from *.htaccess* to PHP script through environment variable working?: ' . self::trueFalseNullString($capTests['passThroughEnvWorking']);
|
501 |
+
return $log;
|
502 |
}
|
503 |
|
504 |
public static function diagnoseFailedRewrite($config)
|
505 |
{
|
506 |
if (($config['destination-structure'] == 'image-roots') && (!PathHelper::isDocRootAvailableAndResolvable())) {
|
507 |
+
$log[] = 'The problem is probably this combination:';
|
508 |
if (!PathHelper::isDocRootAvailable()) {
|
509 |
+
$log[] = '1. Your document root isn`t available';
|
510 |
} else {
|
511 |
+
$log[] = '1. Your document root isn`t resolvable for symlinks (it is probably subject to open_basedir restriction)';
|
512 |
}
|
513 |
+
$log[] = '2. Your document root is symlinked';
|
514 |
+
$log[] = '3. The wordpress function that tells the path of the uploads folder returns the symlink resolved path';
|
515 |
|
516 |
+
$log[] = 'I cannot check if your document root is in fact symlinked (as document root isnt resolvable). ' .
|
517 |
'But if it is, there you have it. The line beginning with "RewriteCond %{REQUEST_FILENAME}"" points to your resolved root, ' .
|
518 |
'but it should point to your symlinked root. WebP Express cannot do that for you because it cannot discover what the symlink is. ' .
|
519 |
'Try changing the line manually. When it works, you can move the rules outside the WebP Express block so they dont get ' .
|
520 |
'overwritten. OR you can change your server configuration (document root / open_basedir restrictions)';
|
521 |
}
|
522 |
|
523 |
+
//$log[] = '## Diagnosing';
|
524 |
if (PlatformInfo::isNginx()) {
|
525 |
// Nginx
|
526 |
+
$log[] = 'Notice that you are on Nginx and the rules that WebP Express stores in the *.htaccess* files probably does not ' .
|
527 |
'have any effect. ';
|
528 |
+
$log[] = 'Please read the "I am on Nginx" section in the FAQ (https://wordpress.org/plugins/webp-express/)';
|
529 |
+
$log[] = 'And did you remember to restart the nginx service after updating the configuration?';
|
530 |
|
531 |
+
$log[] = 'PS: If you cannot get the redirect to work, you can simply rely on Alter HTML as described in the FAQ.';
|
532 |
+
return $log;
|
533 |
}
|
534 |
|
535 |
$modRewriteWorking = CapabilityTest::modRewriteWorking();
|
536 |
if ($modRewriteWorking !== null) {
|
537 |
+
$log[] = 'Running a special designed capability test to test if rewriting works with *.htaccess* files';
|
538 |
}
|
539 |
if ($modRewriteWorking === true) {
|
540 |
+
$log[] = 'Result: Yes, rewriting works.';
|
541 |
+
$log[] = 'It seems something is wrong with the *.htaccess* rules then. You could try ' .
|
542 |
'to change "Destination structure" - the rules there are quite different.';
|
543 |
+
$log[] = 'It could also be that the server has cached the configuration a while. Some servers ' .
|
544 |
'does that. In that case, simply give it a few minutes and try again.';
|
545 |
} elseif ($modRewriteWorking === false) {
|
546 |
+
$log[] = 'Result: No, rewriting does not seem to work within *.htaccess* rules.';
|
547 |
if (PlatformInfo::definitelyNotGotModRewrite()) {
|
548 |
+
$log[] = 'It actually seems "mod_write" is disabled on your server. ' .
|
549 |
'**You must enable mod_rewrite on the server**';
|
550 |
} elseif (PlatformInfo::definitelyGotApacheModule('mod_rewrite')) {
|
551 |
+
$log[] = 'However, "mod_write" *is* enabled on your server. This seems to indicate that ' .
|
552 |
'*.htaccess* files has been disabled for configuration on your server. ' .
|
553 |
'In that case, you need to copy the WebP Express rules from the *.htaccess* files into your virtual host configuration files. ' .
|
554 |
'(WebP Express generates multiple *.htaccess* files. Look in the upload folder, the wp-content folder, etc).';
|
555 |
+
$log[] = 'It could however alse simply be that your server simply needs some time. ' .
|
556 |
'Some servers caches the *.htaccess* rules for a bit. In that case, simply give it a few minutes and try again.';
|
557 |
} else {
|
558 |
+
$log[] = 'However, this could be due to your server being a bit slow on picking up changes in *.htaccess*.' .
|
559 |
'Give it a few minutes and try again.';
|
560 |
}
|
561 |
} else {
|
562 |
// The mod_rewrite test could not conclude anything.
|
563 |
if (PlatformInfo::definitelyNotGotApacheModule('mod_rewrite')) {
|
564 |
+
$log[] = 'It actually seems "mod_write" is disabled on your server. ' .
|
565 |
'**You must enable mod_rewrite on the server**';
|
566 |
} elseif (PlatformInfo::definitelyGotApacheModule('mod_rewrite')) {
|
567 |
+
$log[] = '"mod_write" is enabled on your server, so rewriting ought to work. ' .
|
568 |
'However, it could be that your server setup has disabled *.htaccess* files for configuration. ' .
|
569 |
'In that case, you need to copy the WebP Express rules from the *.htaccess* files into your virtual host configuration files. ' .
|
570 |
'(WebP Express generates multiple *.htaccess* files. Look in the upload folder, the wp-content folder, etc). ';
|
571 |
} else {
|
572 |
+
$log[] = 'It seems something is wrong with the *.htaccess* rules. ';
|
573 |
+
$log[] = 'Or perhaps the server has cached the configuration a while. Some servers ' .
|
574 |
'does that. In that case, simply give it a few minutes and try again.';
|
575 |
}
|
576 |
}
|
577 |
+
$log[] = 'Note that if you cannot get redirection to work, you can switch to "CDN friendly" mode and ' .
|
578 |
'rely on the "Alter HTML" functionality to point to the webp images. If you do a bulk conversion ' .
|
579 |
'and make sure that "Convert upon upload" is activated, you should be all set. Alter HTML even handles ' .
|
580 |
'inline css (unless you select "picture tag" syntax). It does however not handle images in external css or ' .
|
581 |
'which is added dynamically with javascript.';
|
582 |
|
583 |
+
$log[] = '## Info for manually diagnosing';
|
584 |
+
$log = array_merge($log, self::allInfo($config));
|
585 |
+
return $log;
|
586 |
}
|
587 |
}
|
lib/classes/SelfTestRedirectToConverter.php
CHANGED
@@ -10,175 +10,192 @@ class SelfTestRedirectToConverter extends SelfTestRedirectAbstract
|
|
10 |
*
|
11 |
* @param string $rootId (ie "uploads" or "themes")
|
12 |
* @param string $imageType ("jpeg" or "png")
|
13 |
-
* @return array [$success, $
|
14 |
*/
|
15 |
protected function runTestForImageType($rootId, $imageType)
|
16 |
{
|
17 |
-
$
|
18 |
$createdTestFiles = false;
|
19 |
$noWarningsYet = true;
|
20 |
|
21 |
// Copy test image (jpeg)
|
22 |
list($subResult, $success, $sourceFileName) = SelfTestHelper::copyTestImageToRoot($rootId, $imageType);
|
23 |
-
$
|
24 |
if (!$success) {
|
25 |
-
$
|
26 |
-
return [false, $
|
27 |
}
|
28 |
$createdTestFiles = true;
|
29 |
|
30 |
$requestUrl = Paths::getUrlById($rootId) . '/webp-express-test-images/' . $sourceFileName;
|
31 |
|
32 |
-
$
|
33 |
'when the ' . $imageType . ' is requested';
|
34 |
-
$
|
35 |
$requestArgs = [
|
36 |
'headers' => [
|
37 |
'ACCEPT' => 'image/webp'
|
38 |
-
]
|
39 |
];
|
40 |
-
list($success, $
|
|
|
|
|
41 |
|
42 |
if (!$success) {
|
43 |
-
|
44 |
-
$
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
48 |
}
|
49 |
-
//$
|
50 |
-
|
51 |
|
52 |
-
|
53 |
|
54 |
if (!isset($headers['content-type'])) {
|
55 |
-
$
|
56 |
-
return [false, $
|
57 |
}
|
58 |
|
59 |
if ($headers['content-type'] == 'image/' . $imageType) {
|
60 |
-
$
|
61 |
-
$
|
62 |
-
$
|
63 |
|
64 |
if (isset($headers['x-webp-convert-log'])) {
|
65 |
-
//$
|
66 |
// 'should have your answer (it is probably because you do not have any conversion methods working).';
|
67 |
if (SelfTestHelper::hasHeaderContaining($headers, 'x-webp-convert-log', 'Performing fail action: original')) {
|
68 |
-
$
|
69 |
'**The conversion failed**{: .error}. ';
|
70 |
}
|
71 |
} else {
|
72 |
-
$
|
73 |
'The PHP script should set "x-webp-convert-log" response headers, but there are none. ';
|
74 |
'While these headers could have been eaten in a Cloudflare-like setup, the problem is ';
|
75 |
'probably that the redirection simply failed';
|
76 |
|
77 |
-
$
|
78 |
-
$
|
79 |
}
|
80 |
-
return [false, $
|
81 |
}
|
82 |
|
83 |
if ($headers['content-type'] != 'image/webp') {
|
84 |
-
$
|
85 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
86 |
-
$
|
87 |
-
|
88 |
-
$result[] = 'Body:';
|
89 |
-
$result[] = print_r($return['body'], true);
|
90 |
-
}
|
91 |
-
return [false, $result, $createdTestFiles];
|
92 |
}
|
93 |
|
94 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
if (!SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
97 |
-
$
|
98 |
-
$
|
99 |
'That header should be set in order to tell proxies that the response varies depending on the ' .
|
100 |
'Accept header. Otherwise browsers not supporting webp might get a cached webp and vice versa.**{: .warn}';
|
101 |
$noWarningsYet = false;
|
102 |
}
|
103 |
if (!SelfTestHelper::hasCacheControlOrExpiresHeader($headers)) {
|
104 |
-
$
|
105 |
'It is recommended to do so. Set it nice and big once you are sure the webps have a good quality/compression compromise.**{: .warn}';
|
106 |
}
|
107 |
-
$
|
108 |
|
109 |
|
110 |
// Check browsers NOT supporting webp
|
111 |
// -----------------------------------
|
112 |
-
$
|
113 |
-
$
|
114 |
-
list($success, $
|
|
|
|
|
115 |
|
116 |
if (!$success) {
|
117 |
-
$
|
118 |
-
$
|
119 |
-
$
|
120 |
-
|
121 |
-
return [false, $result, $createdTestFiles];
|
122 |
}
|
123 |
-
//$
|
124 |
-
|
125 |
|
126 |
-
|
127 |
|
128 |
if (!isset($headers['content-type'])) {
|
129 |
-
$
|
130 |
-
return [false, $
|
131 |
}
|
132 |
|
133 |
if ($headers['content-type'] == 'image/webp') {
|
134 |
-
$
|
135 |
'So even browsers not supporting webp gets webp. Not good!';
|
136 |
-
$
|
137 |
|
138 |
-
$
|
139 |
// TODO: We could examine the headers for common CDN responses
|
140 |
|
141 |
-
$
|
142 |
'the image is returned from a CDN cache? ' .
|
143 |
-
$
|
144 |
'*How do I configure my CDN in “Varied image responses” operation mode?* section in the FAQ ' .
|
145 |
'(https://wordpress.org/plugins/webp-express/)';
|
146 |
|
147 |
if (PlatformInfo::isApache()) {
|
148 |
-
$
|
149 |
-
$
|
150 |
} elseif (PlatformInfo::isNginx()) {
|
151 |
-
$
|
152 |
' "I am on Nginx" section in the FAQ (https://wordpress.org/plugins/webp-express/)';
|
153 |
} else {
|
154 |
-
$
|
155 |
'in the *.htaccess* rules generated by WebP Express that are not working.';
|
156 |
}
|
157 |
|
158 |
-
$
|
159 |
-
$
|
160 |
|
161 |
|
162 |
-
return [false, $
|
163 |
}
|
164 |
|
165 |
if ($headers['content-type'] != 'image/' . $imageType) {
|
166 |
-
$
|
167 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
168 |
-
$
|
169 |
-
return [false, $
|
170 |
}
|
171 |
-
$
|
172 |
|
173 |
if (!SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
174 |
-
$
|
175 |
-
$
|
176 |
'That header should be set in order to tell proxies that the response varies depending on the ' .
|
177 |
'Accept header. Otherwise browsers not supporting webp might get a cached webp and vice versa.**{: .warn}';
|
178 |
$noWarningsYet = false;
|
179 |
}
|
180 |
|
181 |
-
return [$noWarningsYet, $
|
182 |
}
|
183 |
|
184 |
protected function getSuccessMessage()
|
@@ -190,12 +207,12 @@ class SelfTestRedirectToConverter extends SelfTestRedirectAbstract
|
|
190 |
|
191 |
public function startupTests()
|
192 |
{
|
193 |
-
$
|
194 |
if (!$this->config['enable-redirection-to-converter']) {
|
195 |
-
$
|
196 |
-
return [false, $
|
197 |
}
|
198 |
-
return [true, $
|
199 |
}
|
200 |
|
201 |
public static function runTest()
|
10 |
*
|
11 |
* @param string $rootId (ie "uploads" or "themes")
|
12 |
* @param string $imageType ("jpeg" or "png")
|
13 |
+
* @return array [$success, $log, $createdTestFiles]
|
14 |
*/
|
15 |
protected function runTestForImageType($rootId, $imageType)
|
16 |
{
|
17 |
+
$log = [];
|
18 |
$createdTestFiles = false;
|
19 |
$noWarningsYet = true;
|
20 |
|
21 |
// Copy test image (jpeg)
|
22 |
list($subResult, $success, $sourceFileName) = SelfTestHelper::copyTestImageToRoot($rootId, $imageType);
|
23 |
+
$log = array_merge($log, $subResult);
|
24 |
if (!$success) {
|
25 |
+
$log[] = 'The test cannot be completed';
|
26 |
+
return [false, $log, $createdTestFiles];
|
27 |
}
|
28 |
$createdTestFiles = true;
|
29 |
|
30 |
$requestUrl = Paths::getUrlById($rootId) . '/webp-express-test-images/' . $sourceFileName;
|
31 |
|
32 |
+
$log[] = '### Lets check that browsers supporting webp gets a freshly converted WEBP ' .
|
33 |
'when the ' . $imageType . ' is requested';
|
34 |
+
$log[] = 'Making a HTTP request for the test image (pretending to be a client that supports webp, by setting the "Accept" header to "image/webp")';
|
35 |
$requestArgs = [
|
36 |
'headers' => [
|
37 |
'ACCEPT' => 'image/webp'
|
38 |
+
],
|
39 |
];
|
40 |
+
list($success, $remoteGetLog, $results) = SelfTestHelper::remoteGet($requestUrl, $requestArgs);
|
41 |
+
$headers = $results[count($results)-1]['headers'];
|
42 |
+
$log = array_merge($log, $remoteGetLog);
|
43 |
|
44 |
if (!$success) {
|
45 |
+
//$log[count($log) - 1] .= '. FAILED';
|
46 |
+
$log[] = 'The request FAILED';
|
47 |
+
//$log = array_merge($log, $remoteGetLog);
|
48 |
+
$log[] = 'The test cannot be completed';
|
49 |
+
//$log[count($log) - 1] .= '. FAILED';
|
50 |
+
return [false, $log, $createdTestFiles];
|
51 |
}
|
52 |
+
//$log[count($log) - 1] .= '. ok!';
|
53 |
+
//$log[] = '*' . $requestUrl . '*';
|
54 |
|
55 |
+
//$log = array_merge($log, SelfTestHelper::printHeaders($headers));
|
56 |
|
57 |
if (!isset($headers['content-type'])) {
|
58 |
+
$log[] = 'Bummer. There is no "content-type" response header. The test FAILED';
|
59 |
+
return [false, $log, $createdTestFiles];
|
60 |
}
|
61 |
|
62 |
if ($headers['content-type'] == 'image/' . $imageType) {
|
63 |
+
$log[] = 'Bummer. As the "content-type" header reveals, we got the ' . $imageType . '.';
|
64 |
+
$log[] = 'The test **failed**{: .error}.';
|
65 |
+
$log[] = 'Now, what went wrong?';
|
66 |
|
67 |
if (isset($headers['x-webp-convert-log'])) {
|
68 |
+
//$log[] = 'Inspect the "x-webp-convert-log" headers above, and you ' .
|
69 |
// 'should have your answer (it is probably because you do not have any conversion methods working).';
|
70 |
if (SelfTestHelper::hasHeaderContaining($headers, 'x-webp-convert-log', 'Performing fail action: original')) {
|
71 |
+
$log[] = 'The answer lies in the "x-convert-log" response headers: ' .
|
72 |
'**The conversion failed**{: .error}. ';
|
73 |
}
|
74 |
} else {
|
75 |
+
$log[] = 'Well, there is indication that the redirection isnt working. ' .
|
76 |
'The PHP script should set "x-webp-convert-log" response headers, but there are none. ';
|
77 |
'While these headers could have been eaten in a Cloudflare-like setup, the problem is ';
|
78 |
'probably that the redirection simply failed';
|
79 |
|
80 |
+
$log[] = '### Diagnosing redirection problems';
|
81 |
+
$log = array_merge($log, SelfTestHelper::diagnoseFailedRewrite($this->config));
|
82 |
}
|
83 |
+
return [false, $log, $createdTestFiles];
|
84 |
}
|
85 |
|
86 |
if ($headers['content-type'] != 'image/webp') {
|
87 |
+
$log[] = 'However. As the "content-type" header reveals, we did not get a webp' .
|
88 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
89 |
+
$log[] = 'The test FAILED.';
|
90 |
+
return [false, $log, $createdTestFiles];
|
|
|
|
|
|
|
|
|
91 |
}
|
92 |
|
93 |
+
if (isset($headers['x-webp-convert-log'])) {
|
94 |
+
$log[] = 'Alrighty. We got a webp, and we got it from the PHP script. **Great!**{: .ok}';
|
95 |
+
} else {
|
96 |
+
if (count($results) > 1) {
|
97 |
+
if (isset($results[0]['headers']['x-webp-convert-log'])) {
|
98 |
+
$log[] = '**Great!**{: .ok}. The PHP script created a webp and redirected the image request ' .
|
99 |
+
'back to itself. A refresh, if you wish. The refresh got us the webp (relying on there being ' .
|
100 |
+
'a rule which redirect images to existing converted images for webp-enabled browsers - which there is!). ' .
|
101 |
+
(SelfTestHelper::hasVaryAcceptHeader($headers) ? 'And we got the Vary:Accept header set too. **Super!**{: .ok}!' : '');
|
102 |
+
}
|
103 |
+
} else {
|
104 |
+
$log[] = 'We got a webp. However, it seems we did not get it from the PHP script.';
|
105 |
+
|
106 |
+
}
|
107 |
+
|
108 |
+
//$log[] = print_r($return, true);
|
109 |
+
//error_log(print_r($return, true));
|
110 |
+
}
|
111 |
|
112 |
if (!SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
113 |
+
$log[count($log) - 1] .= '. **BUT!**';
|
114 |
+
$log[] = '**Warning: We did not receive a Vary:Accept header. ' .
|
115 |
'That header should be set in order to tell proxies that the response varies depending on the ' .
|
116 |
'Accept header. Otherwise browsers not supporting webp might get a cached webp and vice versa.**{: .warn}';
|
117 |
$noWarningsYet = false;
|
118 |
}
|
119 |
if (!SelfTestHelper::hasCacheControlOrExpiresHeader($headers)) {
|
120 |
+
$log[] = '**Notice: No cache-control or expires header has been set. ' .
|
121 |
'It is recommended to do so. Set it nice and big once you are sure the webps have a good quality/compression compromise.**{: .warn}';
|
122 |
}
|
123 |
+
$log[] = '';
|
124 |
|
125 |
|
126 |
// Check browsers NOT supporting webp
|
127 |
// -----------------------------------
|
128 |
+
$log[] = '### Now lets check that browsers *not* supporting webp gets the ' . strtoupper($imageType);
|
129 |
+
$log[] = 'Making a HTTP request for the test image (without setting the "Accept" header)';
|
130 |
+
list($success, $remoteGetLog, $results) = SelfTestHelper::remoteGet($requestUrl);
|
131 |
+
$headers = $results[count($results)-1]['headers'];
|
132 |
+
$log = array_merge($log, $remoteGetLog);
|
133 |
|
134 |
if (!$success) {
|
135 |
+
$log[] = 'The request FAILED';
|
136 |
+
$log[] = 'The test cannot be completed';
|
137 |
+
//$log[count($log) - 1] .= '. FAILED';
|
138 |
+
return [false, $log, $createdTestFiles];
|
|
|
139 |
}
|
140 |
+
//$log[count($log) - 1] .= '. ok!';
|
141 |
+
//$log[] = '*' . $requestUrl . '*';
|
142 |
|
143 |
+
//$log = array_merge($log, SelfTestHelper::printHeaders($headers));
|
144 |
|
145 |
if (!isset($headers['content-type'])) {
|
146 |
+
$log[] = 'Bummer. There is no "content-type" response header. The test FAILED';
|
147 |
+
return [false, $log, $createdTestFiles];
|
148 |
}
|
149 |
|
150 |
if ($headers['content-type'] == 'image/webp') {
|
151 |
+
$log[] = '**Bummer**{: .error}. As the "content-type" header reveals, we got the webp. ' .
|
152 |
'So even browsers not supporting webp gets webp. Not good!';
|
153 |
+
$log[] = 'The test FAILED.';
|
154 |
|
155 |
+
$log[] = '### What to do now?';
|
156 |
// TODO: We could examine the headers for common CDN responses
|
157 |
|
158 |
+
$log[] = 'First, examine the response headers above. Is there any indication that ' .
|
159 |
'the image is returned from a CDN cache? ' .
|
160 |
+
$log[] = 'If there is: Check out the ' .
|
161 |
'*How do I configure my CDN in “Varied image responses” operation mode?* section in the FAQ ' .
|
162 |
'(https://wordpress.org/plugins/webp-express/)';
|
163 |
|
164 |
if (PlatformInfo::isApache()) {
|
165 |
+
$log[] = 'If not: please report this in the forum, as it seems the .htaccess rules ';
|
166 |
+
$log[] = 'just arent working on your system.';
|
167 |
} elseif (PlatformInfo::isNginx()) {
|
168 |
+
$log[] = 'Also, as you are on Nginx, check out the ' .
|
169 |
' "I am on Nginx" section in the FAQ (https://wordpress.org/plugins/webp-express/)';
|
170 |
} else {
|
171 |
+
$log[] = 'If not: please report this in the forum, as it seems that there is something ' .
|
172 |
'in the *.htaccess* rules generated by WebP Express that are not working.';
|
173 |
}
|
174 |
|
175 |
+
$log[] = '### System info (for manual diagnosing):';
|
176 |
+
$log = array_merge($log, SelfTestHelper::allInfo($this->config));
|
177 |
|
178 |
|
179 |
+
return [false, $log, $createdTestFiles];
|
180 |
}
|
181 |
|
182 |
if ($headers['content-type'] != 'image/' . $imageType) {
|
183 |
+
$log[] = 'Bummer. As the "content-type" header reveals, we did not get the ' . $imageType .
|
184 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
185 |
+
$log[] = 'The test FAILED.';
|
186 |
+
return [false, $log, $createdTestFiles];
|
187 |
}
|
188 |
+
$log[] = 'Alrighty. We got the ' . $imageType . '. **Great!**{: .ok}.';
|
189 |
|
190 |
if (!SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
191 |
+
$log[count($log) - 1] .= '. **BUT!**';
|
192 |
+
$log[] = '**We did not receive a Vary:Accept header. ' .
|
193 |
'That header should be set in order to tell proxies that the response varies depending on the ' .
|
194 |
'Accept header. Otherwise browsers not supporting webp might get a cached webp and vice versa.**{: .warn}';
|
195 |
$noWarningsYet = false;
|
196 |
}
|
197 |
|
198 |
+
return [$noWarningsYet, $log, $createdTestFiles];
|
199 |
}
|
200 |
|
201 |
protected function getSuccessMessage()
|
207 |
|
208 |
public function startupTests()
|
209 |
{
|
210 |
+
$log[] = '# Testing redirection to converter';
|
211 |
if (!$this->config['enable-redirection-to-converter']) {
|
212 |
+
$log[] = 'Turned off, nothing to test (if you just turned it on without saving, remember: this is a live test so you need to save settings)';
|
213 |
+
return [false, $log];
|
214 |
}
|
215 |
+
return [true, $log];
|
216 |
}
|
217 |
|
218 |
public static function runTest()
|
lib/classes/SelfTestRedirectToExisting.php
CHANGED
@@ -9,26 +9,26 @@ class SelfTestRedirectToExisting extends SelfTestRedirectAbstract
|
|
9 |
*
|
10 |
* @param string $rootId (ie "uploads" or "themes")
|
11 |
* @param string $imageType ("jpeg" or "png")
|
12 |
-
* @return array [$success, $
|
13 |
*/
|
14 |
protected function runTestForImageType($rootId, $imageType)
|
15 |
{
|
16 |
-
$
|
17 |
$createdTestFiles = false;
|
18 |
$noWarningsYet = true;
|
19 |
|
20 |
-
$
|
21 |
|
22 |
// Copy test image
|
23 |
list($subResult, $success, $sourceFileName) = SelfTestHelper::copyTestImageToRoot($rootId, $imageType);
|
24 |
-
$
|
25 |
if (!$success) {
|
26 |
-
$
|
27 |
-
return [false, $
|
28 |
}
|
29 |
$createdTestFiles = true;
|
30 |
|
31 |
-
$
|
32 |
|
33 |
// Copy dummy webp
|
34 |
list($subResult, $success, $destinationFile) = SelfTestHelper::copyDummyWebPToCacheFolder(
|
@@ -39,191 +39,188 @@ class SelfTestRedirectToExisting extends SelfTestRedirectAbstract
|
|
39 |
$sourceFileName,
|
40 |
$imageType
|
41 |
);
|
42 |
-
$
|
43 |
if (!$success) {
|
44 |
-
$
|
45 |
-
return [false, $
|
46 |
}
|
47 |
|
48 |
$requestUrl = Paths::getUrlById($rootId) . '/webp-express-test-images/' . $sourceFileName;
|
49 |
-
$
|
50 |
-
$
|
51 |
$requestArgs = [
|
52 |
'headers' => [
|
53 |
'ACCEPT' => 'image/webp'
|
54 |
]
|
55 |
];
|
56 |
-
|
|
|
|
|
|
|
57 |
|
58 |
if (!$success) {
|
59 |
-
$
|
60 |
-
$
|
61 |
-
|
62 |
-
//$result[count($result) - 1] .= '. FAILED';
|
63 |
-
return [false, $result, $createdTestFiles];
|
64 |
}
|
65 |
-
//$
|
66 |
-
|
67 |
|
68 |
-
|
69 |
|
70 |
if (!isset($headers['content-type'])) {
|
71 |
-
$
|
72 |
-
return [false, $
|
73 |
}
|
74 |
|
75 |
if ($headers['content-type'] != 'image/webp') {
|
76 |
|
77 |
if ($headers['content-type'] == 'image/' . $imageType) {
|
78 |
-
$
|
79 |
} else {
|
80 |
-
$
|
81 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
82 |
-
if (strpos($headers['content-type'], 'text/html') !== false) {
|
83 |
-
$result[] = 'Body:';
|
84 |
-
$result[] = print_r($return['body'], true);
|
85 |
-
}
|
86 |
}
|
87 |
|
88 |
if (isset($headers['content-length'])) {
|
89 |
if ($headers['content-length'] == '6964') {
|
90 |
-
$
|
91 |
'(we know that the file we put is exactly 6964 bytes). ' .
|
92 |
'So it is "just" the content-type header that was not set correctly.';
|
93 |
|
94 |
if (PlatformInfo::isNginx()) {
|
95 |
-
$
|
96 |
'in your *mime.types* configuration file: ';
|
97 |
-
$
|
98 |
} else {
|
99 |
-
$
|
100 |
'in the folder containing the webp (or a parent):';
|
101 |
-
$
|
102 |
|
103 |
-
$
|
104 |
-
$
|
105 |
}
|
106 |
|
107 |
-
$
|
108 |
} else {
|
109 |
-
$
|
110 |
'(we know that the file we put is exactly 6964 bytes). ' .
|
111 |
'So we can conclude that the rewrite did not happen';
|
112 |
-
$
|
113 |
-
$
|
114 |
-
$
|
115 |
}
|
116 |
} else {
|
117 |
-
$
|
118 |
-
$
|
119 |
-
$
|
120 |
-
$
|
121 |
-
$
|
122 |
}
|
123 |
|
124 |
-
return [false, $
|
125 |
}
|
126 |
|
127 |
if (isset($headers['x-webp-convert-log'])) {
|
128 |
-
$
|
129 |
'redirection. This webp was returned by the PHP script. Although this works, it takes more ' .
|
130 |
'resources to ignite the PHP engine for each image request than redirecting directly to the image.';
|
131 |
-
$
|
132 |
|
133 |
-
$
|
134 |
-
$
|
135 |
-
$
|
136 |
|
137 |
-
return [false, $
|
138 |
} else {
|
139 |
-
$
|
140 |
}
|
141 |
if (!SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
142 |
-
$
|
143 |
-
$
|
144 |
'That header should be set in order to tell proxies that the response varies depending on the ' .
|
145 |
'Accept header. Otherwise browsers not supporting webp might get a cached webp and vice versa.**{: .warn}';
|
146 |
$noWarningsYet = false;
|
147 |
}
|
148 |
if (!SelfTestHelper::hasCacheControlOrExpiresHeader($headers)) {
|
149 |
-
$
|
150 |
'It is recommended to do so. Set it nice and big once you are sure the webps have a good quality/compression compromise.**{: .warn}';
|
151 |
}
|
152 |
-
$
|
153 |
|
154 |
|
155 |
// Check browsers NOT supporting webp
|
156 |
// -----------------------------------
|
157 |
-
$
|
158 |
-
$
|
159 |
-
list($success, $
|
|
|
|
|
160 |
|
161 |
if (!$success) {
|
162 |
-
$
|
163 |
-
$
|
164 |
-
|
165 |
-
//$result[count($result) - 1] .= '. FAILED';
|
166 |
-
return [false, $result, $createdTestFiles];
|
167 |
}
|
168 |
-
//$
|
169 |
-
|
170 |
|
171 |
-
|
172 |
|
173 |
if (!isset($headers['content-type'])) {
|
174 |
-
$
|
175 |
-
return [false, $
|
176 |
}
|
177 |
|
178 |
if ($headers['content-type'] == 'image/webp') {
|
179 |
-
$
|
180 |
'So even browsers not supporting webp gets webp. Not good!';
|
181 |
-
$
|
182 |
|
183 |
-
$
|
184 |
// TODO: We could examine the headers for common CDN responses
|
185 |
|
186 |
-
$
|
187 |
'the image is returned from a CDN cache? ' .
|
188 |
-
$
|
189 |
'*How do I configure my CDN in “Varied image responses” operation mode?* section in the FAQ ' .
|
190 |
'(https://wordpress.org/plugins/webp-express/)';
|
191 |
|
192 |
if (PlatformInfo::isApache()) {
|
193 |
-
$
|
194 |
-
$
|
195 |
} elseif (PlatformInfo::isNginx()) {
|
196 |
-
$
|
197 |
' "I am on Nginx" section in the FAQ (https://wordpress.org/plugins/webp-express/)';
|
198 |
} else {
|
199 |
-
$
|
200 |
'in the *.htaccess* rules generated by WebP Express that are not working.';
|
201 |
}
|
202 |
|
203 |
-
$
|
204 |
-
$
|
205 |
|
206 |
|
207 |
-
return [false, $
|
208 |
}
|
209 |
|
210 |
if ($headers['content-type'] != 'image/' . $imageType) {
|
211 |
-
$
|
212 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
213 |
-
$
|
214 |
-
return [false, $
|
215 |
}
|
216 |
-
$
|
217 |
|
218 |
if (!SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
219 |
-
$
|
220 |
-
$
|
221 |
'That header should be set in order to tell proxies that the response varies depending on the ' .
|
222 |
'Accept header. Otherwise browsers not supporting webp might get a cached webp and vice versa.**{: .warn}';
|
223 |
$noWarningsYet = false;
|
224 |
}
|
225 |
|
226 |
-
return [$noWarningsYet, $
|
227 |
}
|
228 |
|
229 |
protected function getSuccessMessage()
|
@@ -236,12 +233,12 @@ class SelfTestRedirectToExisting extends SelfTestRedirectAbstract
|
|
236 |
|
237 |
public function startupTests()
|
238 |
{
|
239 |
-
$
|
240 |
if (!$this->config['redirect-to-existing-in-htaccess']) {
|
241 |
-
$
|
242 |
-
return [false, $
|
243 |
}
|
244 |
-
return [true, $
|
245 |
}
|
246 |
|
247 |
public static function runTest()
|
9 |
*
|
10 |
* @param string $rootId (ie "uploads" or "themes")
|
11 |
* @param string $imageType ("jpeg" or "png")
|
12 |
+
* @return array [$success, $log, $createdTestFiles]
|
13 |
*/
|
14 |
protected function runTestForImageType($rootId, $imageType)
|
15 |
{
|
16 |
+
$log = [];
|
17 |
$createdTestFiles = false;
|
18 |
$noWarningsYet = true;
|
19 |
|
20 |
+
$log[] = '### Copying files for testing';
|
21 |
|
22 |
// Copy test image
|
23 |
list($subResult, $success, $sourceFileName) = SelfTestHelper::copyTestImageToRoot($rootId, $imageType);
|
24 |
+
$log = array_merge($log, $subResult);
|
25 |
if (!$success) {
|
26 |
+
$log[] = 'The test cannot be completed';
|
27 |
+
return [false, $log, $createdTestFiles];
|
28 |
}
|
29 |
$createdTestFiles = true;
|
30 |
|
31 |
+
$log[] = '';
|
32 |
|
33 |
// Copy dummy webp
|
34 |
list($subResult, $success, $destinationFile) = SelfTestHelper::copyDummyWebPToCacheFolder(
|
39 |
$sourceFileName,
|
40 |
$imageType
|
41 |
);
|
42 |
+
$log = array_merge($log, $subResult);
|
43 |
if (!$success) {
|
44 |
+
$log[] = 'The test cannot be completed';
|
45 |
+
return [false, $log, $createdTestFiles];
|
46 |
}
|
47 |
|
48 |
$requestUrl = Paths::getUrlById($rootId) . '/webp-express-test-images/' . $sourceFileName;
|
49 |
+
$log[] = '### Lets check that browsers supporting webp gets the WEBP when the ' . strtoupper($imageType) . ' is requested';
|
50 |
+
$log[] = 'Making a HTTP request for the test image (pretending to be a client that supports webp, by setting the "Accept" header to "image/webp")';
|
51 |
$requestArgs = [
|
52 |
'headers' => [
|
53 |
'ACCEPT' => 'image/webp'
|
54 |
]
|
55 |
];
|
56 |
+
|
57 |
+
list($success, $remoteGetLog, $results) = SelfTestHelper::remoteGet($requestUrl, $requestArgs);
|
58 |
+
$headers = $results[count($results)-1]['headers'];
|
59 |
+
$log = array_merge($log, $remoteGetLog);
|
60 |
|
61 |
if (!$success) {
|
62 |
+
$log[] = 'The request FAILED';
|
63 |
+
$log[] = 'The test cannot be completed';
|
64 |
+
return [false, $log, $createdTestFiles];
|
|
|
|
|
65 |
}
|
66 |
+
//$log[count($log) - 1] .= '. ok!';
|
67 |
+
//$log[] = '*' . $requestUrl . '*';
|
68 |
|
69 |
+
//$log = array_merge($log, SelfTestHelper::printHeaders($headers));
|
70 |
|
71 |
if (!isset($headers['content-type'])) {
|
72 |
+
$log[] = 'Bummer. There is no "content-type" response header. The test FAILED';
|
73 |
+
return [false, $log, $createdTestFiles];
|
74 |
}
|
75 |
|
76 |
if ($headers['content-type'] != 'image/webp') {
|
77 |
|
78 |
if ($headers['content-type'] == 'image/' . $imageType) {
|
79 |
+
$log[] = 'Bummer. As the "content-type" header reveals, we got the ' . $imageType . '. ';
|
80 |
} else {
|
81 |
+
$log[] = 'Bummer. As the "content-type" header reveals, we did not get a webp' .
|
82 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
|
|
|
|
|
|
|
|
83 |
}
|
84 |
|
85 |
if (isset($headers['content-length'])) {
|
86 |
if ($headers['content-length'] == '6964') {
|
87 |
+
$log[] = 'However, the content-length reveals that we actually GOT the webp ' .
|
88 |
'(we know that the file we put is exactly 6964 bytes). ' .
|
89 |
'So it is "just" the content-type header that was not set correctly.';
|
90 |
|
91 |
if (PlatformInfo::isNginx()) {
|
92 |
+
$log[] = 'As you are on Nginx, you probably need to add the following line ' .
|
93 |
'in your *mime.types* configuration file: ';
|
94 |
+
$log[] = '```image/webp webp;```';
|
95 |
} else {
|
96 |
+
$log[] = 'Perhaps you dont have *mod_mime* installed, or the following lines are not in a *.htaccess* ' .
|
97 |
'in the folder containing the webp (or a parent):';
|
98 |
+
$log[] = "```<IfModule mod_mime.c>\n AddType image/webp .webp\n</IfModule>```";
|
99 |
|
100 |
+
$log[] = '### .htaccess status';
|
101 |
+
$log = array_merge($log, SelfTestHelper::htaccessInfo($this->config, true));
|
102 |
}
|
103 |
|
104 |
+
$log[] = 'The test **FAILED**{: .error}.';
|
105 |
} else {
|
106 |
+
$log[] = 'Additionally, the content-length reveals that we did not get the webp ' .
|
107 |
'(we know that the file we put is exactly 6964 bytes). ' .
|
108 |
'So we can conclude that the rewrite did not happen';
|
109 |
+
$log[] = 'The test **FAILED**{: .error}.';
|
110 |
+
$log[] = '#### Diagnosing rewrites';
|
111 |
+
$log = array_merge($log, SelfTestHelper::diagnoseFailedRewrite($this->config));
|
112 |
}
|
113 |
} else {
|
114 |
+
$log[] = 'In addition, we did not get a *content-length* header either.' .
|
115 |
+
$log[] = 'It seems we can conclude that the rewrite did not happen.';
|
116 |
+
$log[] = 'The test **FAILED**{: .error}.';
|
117 |
+
$log[] = '#### Diagnosing rewrites';
|
118 |
+
$log = array_merge($log, SelfTestHelper::diagnoseFailedRewrite($this->config));
|
119 |
}
|
120 |
|
121 |
+
return [false, $log, $createdTestFiles];
|
122 |
}
|
123 |
|
124 |
if (isset($headers['x-webp-convert-log'])) {
|
125 |
+
$log[] = 'Bummer. Although we did get a webp, we did not get it as a result of a direct ' .
|
126 |
'redirection. This webp was returned by the PHP script. Although this works, it takes more ' .
|
127 |
'resources to ignite the PHP engine for each image request than redirecting directly to the image.';
|
128 |
+
$log[] = 'The test FAILED.';
|
129 |
|
130 |
+
$log[] = 'It seems something went wrong with the redirection.';
|
131 |
+
$log[] = '#### Diagnosing redirects';
|
132 |
+
$log = array_merge($log, SelfTestHelper::diagnoseFailedRewrite($this->config));
|
133 |
|
134 |
+
return [false, $log, $createdTestFiles];
|
135 |
} else {
|
136 |
+
$log[] = 'Alrighty. We got a webp. Just what we wanted. **Great!**{: .ok}';
|
137 |
}
|
138 |
if (!SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
139 |
+
$log[count($log) - 1] .= '. **BUT!**';
|
140 |
+
$log[] = '**Warning: We did not receive a Vary:Accept header. ' .
|
141 |
'That header should be set in order to tell proxies that the response varies depending on the ' .
|
142 |
'Accept header. Otherwise browsers not supporting webp might get a cached webp and vice versa.**{: .warn}';
|
143 |
$noWarningsYet = false;
|
144 |
}
|
145 |
if (!SelfTestHelper::hasCacheControlOrExpiresHeader($headers)) {
|
146 |
+
$log[] = '**Notice: No cache-control or expires header has been set. ' .
|
147 |
'It is recommended to do so. Set it nice and big once you are sure the webps have a good quality/compression compromise.**{: .warn}';
|
148 |
}
|
149 |
+
$log[] = '';
|
150 |
|
151 |
|
152 |
// Check browsers NOT supporting webp
|
153 |
// -----------------------------------
|
154 |
+
$log[] = '### Now lets check that browsers *not* supporting webp gets the ' . strtoupper($imageType);
|
155 |
+
$log[] = 'Making a HTTP request for the test image (without setting the "Accept" header)';
|
156 |
+
list($success, $remoteGetLog, $results) = SelfTestHelper::remoteGet($requestUrl);
|
157 |
+
$headers = $results[count($results)-1]['headers'];
|
158 |
+
$log = array_merge($log, $remoteGetLog);
|
159 |
|
160 |
if (!$success) {
|
161 |
+
$log[] = 'The request FAILED';
|
162 |
+
$log[] = 'The test cannot be completed';
|
163 |
+
return [false, $log, $createdTestFiles];
|
|
|
|
|
164 |
}
|
165 |
+
//$log[count($log) - 1] .= '. ok!';
|
166 |
+
//$log[] = '*' . $requestUrl . '*';
|
167 |
|
168 |
+
//$log = array_merge($log, SelfTestHelper::printHeaders($headers));
|
169 |
|
170 |
if (!isset($headers['content-type'])) {
|
171 |
+
$log[] = 'Bummer. There is no "content-type" response header. The test FAILED';
|
172 |
+
return [false, $log, $createdTestFiles];
|
173 |
}
|
174 |
|
175 |
if ($headers['content-type'] == 'image/webp') {
|
176 |
+
$log[] = '**Bummer**{: .error}. As the "content-type" header reveals, we got the webp. ' .
|
177 |
'So even browsers not supporting webp gets webp. Not good!';
|
178 |
+
$log[] = 'The test FAILED.';
|
179 |
|
180 |
+
$log[] = '#### What to do now?';
|
181 |
// TODO: We could examine the headers for common CDN responses
|
182 |
|
183 |
+
$log[] = 'First, examine the response headers above. Is there any indication that ' .
|
184 |
'the image is returned from a CDN cache? ' .
|
185 |
+
$log[] = 'If there is: Check out the ' .
|
186 |
'*How do I configure my CDN in “Varied image responses” operation mode?* section in the FAQ ' .
|
187 |
'(https://wordpress.org/plugins/webp-express/)';
|
188 |
|
189 |
if (PlatformInfo::isApache()) {
|
190 |
+
$log[] = 'If not: please report this in the forum, as it seems the .htaccess rules ';
|
191 |
+
$log[] = 'just arent working on your system.';
|
192 |
} elseif (PlatformInfo::isNginx()) {
|
193 |
+
$log[] = 'Also, as you are on Nginx, check out the ' .
|
194 |
' "I am on Nginx" section in the FAQ (https://wordpress.org/plugins/webp-express/)';
|
195 |
} else {
|
196 |
+
$log[] = 'If not: please report this in the forum, as it seems that there is something ' .
|
197 |
'in the *.htaccess* rules generated by WebP Express that are not working.';
|
198 |
}
|
199 |
|
200 |
+
$log[] = '### System info (for manual diagnosing):';
|
201 |
+
$log = array_merge($log, SelfTestHelper::allInfo($this->config));
|
202 |
|
203 |
|
204 |
+
return [false, $log, $createdTestFiles];
|
205 |
}
|
206 |
|
207 |
if ($headers['content-type'] != 'image/' . $imageType) {
|
208 |
+
$log[] = 'Bummer. As the "content-type" header reveals, we did not get the ' . $imageType .
|
209 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
210 |
+
$log[] = 'The test FAILED.';
|
211 |
+
return [false, $log, $createdTestFiles];
|
212 |
}
|
213 |
+
$log[] = 'Alrighty. We got the ' . $imageType . '. **Great!**{: .ok}.';
|
214 |
|
215 |
if (!SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
216 |
+
$log[count($log) - 1] .= '. **BUT!**';
|
217 |
+
$log[] = '**We did not receive a Vary:Accept header. ' .
|
218 |
'That header should be set in order to tell proxies that the response varies depending on the ' .
|
219 |
'Accept header. Otherwise browsers not supporting webp might get a cached webp and vice versa.**{: .warn}';
|
220 |
$noWarningsYet = false;
|
221 |
}
|
222 |
|
223 |
+
return [$noWarningsYet, $log, $createdTestFiles];
|
224 |
}
|
225 |
|
226 |
protected function getSuccessMessage()
|
233 |
|
234 |
public function startupTests()
|
235 |
{
|
236 |
+
$log[] = '# Testing redirection to existing webp';
|
237 |
if (!$this->config['redirect-to-existing-in-htaccess']) {
|
238 |
+
$log[] = 'Turned off, nothing to test (if you just turned it on without saving, remember: this is a live test so you need to save settings)';
|
239 |
+
return [false, $log];
|
240 |
}
|
241 |
+
return [true, $log];
|
242 |
}
|
243 |
|
244 |
public static function runTest()
|
lib/classes/SelfTestRedirectToWebPRealizer.php
CHANGED
@@ -10,20 +10,20 @@ class SelfTestRedirectToWebPRealizer extends SelfTestRedirectAbstract
|
|
10 |
*
|
11 |
* @param string $rootId (ie "uploads" or "themes")
|
12 |
* @param string $imageType ("jpeg" or "png")
|
13 |
-
* @return array [$success, $
|
14 |
*/
|
15 |
protected function runTestForImageType($rootId, $imageType)
|
16 |
{
|
17 |
-
$
|
18 |
$createdTestFiles = false;
|
19 |
$noWarningsYet = true;
|
20 |
|
21 |
// Copy test image
|
22 |
list($subResult, $success, $sourceFileName) = SelfTestHelper::copyTestImageToRoot($rootId, $imageType);
|
23 |
-
$
|
24 |
if (!$success) {
|
25 |
-
$
|
26 |
-
return [false, $
|
27 |
}
|
28 |
$createdTestFiles = true;
|
29 |
|
@@ -47,149 +47,147 @@ class SelfTestRedirectToWebPRealizer extends SelfTestRedirectAbstract
|
|
47 |
);
|
48 |
|
49 |
|
50 |
-
$
|
51 |
'when a non-existing WEBP is requested, which has a corresponding source';
|
52 |
-
$
|
53 |
$requestArgs = [
|
54 |
'headers' => [
|
55 |
'ACCEPT' => 'image/webp'
|
56 |
]
|
57 |
];
|
58 |
-
list($success, $
|
|
|
|
|
59 |
|
60 |
if (!$success) {
|
61 |
-
//$
|
62 |
-
//$
|
63 |
|
64 |
-
$
|
65 |
-
$
|
66 |
|
67 |
-
$
|
68 |
'or it could be that the PHP script could not locate a source image corresponding to the destination URL. ' .
|
69 |
'Currently, this analysis cannot dertermine which was the case and it cannot be helpful ' .
|
70 |
'if the latter is the case (sorry!). However, if the redirection rules are the problem, here is some info:';
|
71 |
|
72 |
-
$
|
73 |
-
$
|
74 |
|
75 |
|
76 |
-
//$
|
77 |
-
return [false, $
|
78 |
}
|
79 |
-
//$
|
80 |
-
|
81 |
|
82 |
-
|
83 |
|
84 |
if (!isset($headers['content-type'])) {
|
85 |
-
$
|
86 |
-
return [false, $
|
87 |
}
|
88 |
|
89 |
if ($headers['content-type'] == 'image/' . $imageType) {
|
90 |
-
$
|
91 |
-
$
|
92 |
-
$
|
93 |
|
94 |
if (isset($headers['x-webp-convert-log'])) {
|
95 |
-
//$
|
96 |
// 'should have your answer (it is probably because you do not have any conversion methods working).';
|
97 |
if (SelfTestHelper::hasHeaderContaining($headers, 'x-webp-convert-log', 'Performing fail action: original')) {
|
98 |
-
$
|
99 |
'**The conversion failed**{: .error}. ';
|
100 |
}
|
101 |
} else {
|
102 |
-
$
|
103 |
'The PHP script should set "x-webp-convert-log" response headers, but there are none. ';
|
104 |
'While these headers could have been eaten in a Cloudflare-like setup, the problem is ';
|
105 |
'probably that the redirection simply failed';
|
106 |
|
107 |
-
$
|
108 |
-
$
|
109 |
}
|
110 |
-
return [false, $
|
111 |
}
|
112 |
|
113 |
if ($headers['content-type'] != 'image/webp') {
|
114 |
-
$
|
115 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
116 |
-
$
|
117 |
-
|
118 |
-
$result[] = 'Body:';
|
119 |
-
$result[] = print_r($return['body'], true);
|
120 |
-
}
|
121 |
-
return [false, $result, $createdTestFiles];
|
122 |
}
|
123 |
|
124 |
-
$
|
125 |
if (isset($headers['x-webp-convert-log'])) {
|
126 |
-
$
|
127 |
} else {
|
128 |
-
$
|
129 |
'the PHP script always produces such. Could it be you have some weird setup that eats these headers?';
|
130 |
}
|
131 |
|
132 |
if (SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
133 |
-
$
|
134 |
|
135 |
-
$
|
136 |
'That header need not to be set. Actually, it is a little bit bad for performance ' .
|
137 |
'as proxies are currently doing a bad job maintaining several caches (in many cases they simply do not)**{: .warn}';
|
138 |
$noWarningsYet = false;
|
139 |
}
|
140 |
if (!SelfTestHelper::hasCacheControlOrExpiresHeader($headers)) {
|
141 |
-
$
|
142 |
'It is recommended to do so. Set it nice and big once you are sure the webps have a good quality/compression compromise.**{: .warn}';
|
143 |
}
|
144 |
-
$
|
145 |
|
146 |
-
return [$noWarningsYet, $
|
147 |
}
|
148 |
|
149 |
/*
|
150 |
private static function doRunTest($this->config)
|
151 |
{
|
152 |
-
$
|
153 |
-
$
|
154 |
|
155 |
$createdTestFiles = false;
|
156 |
if (!file_exists(Paths::getConfigFileName())) {
|
157 |
-
$
|
158 |
-
return [true, $
|
159 |
}
|
160 |
|
161 |
|
162 |
if ($this->config['image-types'] == 0) {
|
163 |
-
$
|
164 |
-
return [true, $
|
165 |
}
|
166 |
|
167 |
if ($this->config['image-types'] & 1) {
|
168 |
list($success, $subResult, $createdTestFiles) = self::runTestForImageType($this->config, 'jpeg');
|
169 |
-
$
|
170 |
|
171 |
if ($success) {
|
172 |
if ($this->config['image-types'] & 2) {
|
173 |
-
$
|
174 |
list($success, $subResult, $createdTestFiles2) = self::runTestForImageType($this->config, 'png');
|
175 |
$createdTestFiles = $createdTestFiles || $createdTestFiles2;
|
176 |
if ($success) {
|
177 |
-
//$
|
178 |
-
$
|
179 |
-
$
|
180 |
} else {
|
181 |
-
$
|
182 |
}
|
183 |
}
|
184 |
}
|
185 |
} else {
|
186 |
list($success, $subResult, $createdTestFiles) = self::runTestForImageType($this->config, 'png');
|
187 |
-
$
|
188 |
}
|
189 |
|
190 |
if ($success) {
|
191 |
-
$
|
192 |
-
$
|
193 |
'However, notice that this test only tested an image which was placed in the *uploads* folder. ' .
|
194 |
'The rest of the image roots (such as theme images) have not been tested (it is on the TODO). ' .
|
195 |
'Also on the TODO: If one image type is disabled, check that it does not redirect to the conversion script. ' .
|
@@ -197,7 +195,7 @@ class SelfTestRedirectToWebPRealizer extends SelfTestRedirectAbstract
|
|
197 |
}
|
198 |
|
199 |
|
200 |
-
return [true, $
|
201 |
}*/
|
202 |
|
203 |
protected function getSuccessMessage()
|
@@ -209,12 +207,12 @@ class SelfTestRedirectToWebPRealizer extends SelfTestRedirectAbstract
|
|
209 |
|
210 |
public function startupTests()
|
211 |
{
|
212 |
-
$
|
213 |
if (!$this->config['enable-redirection-to-webp-realizer']) {
|
214 |
-
$
|
215 |
-
return [false, $
|
216 |
}
|
217 |
-
return [true, $
|
218 |
}
|
219 |
|
220 |
public static function runTest()
|
10 |
*
|
11 |
* @param string $rootId (ie "uploads" or "themes")
|
12 |
* @param string $imageType ("jpeg" or "png")
|
13 |
+
* @return array [$success, $log, $createdTestFiles]
|
14 |
*/
|
15 |
protected function runTestForImageType($rootId, $imageType)
|
16 |
{
|
17 |
+
$log = [];
|
18 |
$createdTestFiles = false;
|
19 |
$noWarningsYet = true;
|
20 |
|
21 |
// Copy test image
|
22 |
list($subResult, $success, $sourceFileName) = SelfTestHelper::copyTestImageToRoot($rootId, $imageType);
|
23 |
+
$log = array_merge($log, $subResult);
|
24 |
if (!$success) {
|
25 |
+
$log[] = 'The test cannot be completed';
|
26 |
+
return [false, $log, $createdTestFiles];
|
27 |
}
|
28 |
$createdTestFiles = true;
|
29 |
|
47 |
);
|
48 |
|
49 |
|
50 |
+
$log[] = '### Lets check that browsers supporting webp gets a freshly converted WEBP ' .
|
51 |
'when a non-existing WEBP is requested, which has a corresponding source';
|
52 |
+
$log[] = 'Making a HTTP request for the test image (pretending to be a client that supports webp, by setting the "Accept" header to "image/webp")';
|
53 |
$requestArgs = [
|
54 |
'headers' => [
|
55 |
'ACCEPT' => 'image/webp'
|
56 |
]
|
57 |
];
|
58 |
+
list($success, $remoteGetLog, $results) = SelfTestHelper::remoteGet($requestUrl, $requestArgs);
|
59 |
+
$headers = $results[count($results)-1]['headers'];
|
60 |
+
$log = array_merge($log, $remoteGetLog);
|
61 |
|
62 |
if (!$success) {
|
63 |
+
//$log[count($log) - 1] .= '. FAILED';
|
64 |
+
//$log[] = '*' . $requestUrl . '*';
|
65 |
|
66 |
+
$log = array_merge($log, $errors);
|
67 |
+
$log[] = 'The test **failed**{: .error}';
|
68 |
|
69 |
+
$log[] = 'Why did it fail? It could either be that the redirection rule did not trigger ' .
|
70 |
'or it could be that the PHP script could not locate a source image corresponding to the destination URL. ' .
|
71 |
'Currently, this analysis cannot dertermine which was the case and it cannot be helpful ' .
|
72 |
'if the latter is the case (sorry!). However, if the redirection rules are the problem, here is some info:';
|
73 |
|
74 |
+
$log[] = '### Diagnosing redirection problems (presuming it is the redirection to the script that is failing)';
|
75 |
+
$log = array_merge($log, SelfTestHelper::diagnoseFailedRewrite($this->config));
|
76 |
|
77 |
|
78 |
+
//$log[count($log) - 1] .= '. FAILED';
|
79 |
+
return [false, $log, $createdTestFiles];
|
80 |
}
|
81 |
+
//$log[count($log) - 1] .= '. ok!';
|
82 |
+
//$log[] = '*' . $requestUrl . '*';
|
83 |
|
84 |
+
//$log = array_merge($log, SelfTestHelper::printHeaders($headers));
|
85 |
|
86 |
if (!isset($headers['content-type'])) {
|
87 |
+
$log[] = 'Bummer. There is no "content-type" response header. The test FAILED';
|
88 |
+
return [false, $log, $createdTestFiles];
|
89 |
}
|
90 |
|
91 |
if ($headers['content-type'] == 'image/' . $imageType) {
|
92 |
+
$log[] = 'Bummer. As the "content-type" header reveals, we got the ' . $imageType . '.';
|
93 |
+
$log[] = 'The test **failed**{: .error}.';
|
94 |
+
$log[] = 'Now, what went wrong?';
|
95 |
|
96 |
if (isset($headers['x-webp-convert-log'])) {
|
97 |
+
//$log[] = 'Inspect the "x-webp-convert-log" headers above, and you ' .
|
98 |
// 'should have your answer (it is probably because you do not have any conversion methods working).';
|
99 |
if (SelfTestHelper::hasHeaderContaining($headers, 'x-webp-convert-log', 'Performing fail action: original')) {
|
100 |
+
$log[] = 'The answer lies in the "x-convert-log" response headers: ' .
|
101 |
'**The conversion failed**{: .error}. ';
|
102 |
}
|
103 |
} else {
|
104 |
+
$log[] = 'Well, there is indication that the redirection isnt working. ' .
|
105 |
'The PHP script should set "x-webp-convert-log" response headers, but there are none. ';
|
106 |
'While these headers could have been eaten in a Cloudflare-like setup, the problem is ';
|
107 |
'probably that the redirection simply failed';
|
108 |
|
109 |
+
$log[] = '### Diagnosing redirection problems';
|
110 |
+
$log = array_merge($log, SelfTestHelper::diagnoseFailedRewrite($this->config));
|
111 |
}
|
112 |
+
return [false, $log, $createdTestFiles];
|
113 |
}
|
114 |
|
115 |
if ($headers['content-type'] != 'image/webp') {
|
116 |
+
$log[] = 'However. As the "content-type" header reveals, we did not get a webp' .
|
117 |
'Surprisingly we got: "' . $headers['content-type'] . '"';
|
118 |
+
$log[] = 'The test FAILED.';
|
119 |
+
return [false, $log, $createdTestFiles];
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
|
122 |
+
$log[] = '**Alrighty**{: .ok}. We got a webp.';
|
123 |
if (isset($headers['x-webp-convert-log'])) {
|
124 |
+
$log[] = 'The "x-webp-convert-log" headers reveals we got the webp from the PHP script. **Great!**{: .ok}';
|
125 |
} else {
|
126 |
+
$log[] = 'Interestingly, there are no "x-webp-convert-log" headers even though ' .
|
127 |
'the PHP script always produces such. Could it be you have some weird setup that eats these headers?';
|
128 |
}
|
129 |
|
130 |
if (SelfTestHelper::hasVaryAcceptHeader($headers)) {
|
131 |
+
$log[] = 'All is however not super-duper:';
|
132 |
|
133 |
+
$log[] = '**Notice: We received a Vary:Accept header. ' .
|
134 |
'That header need not to be set. Actually, it is a little bit bad for performance ' .
|
135 |
'as proxies are currently doing a bad job maintaining several caches (in many cases they simply do not)**{: .warn}';
|
136 |
$noWarningsYet = false;
|
137 |
}
|
138 |
if (!SelfTestHelper::hasCacheControlOrExpiresHeader($headers)) {
|
139 |
+
$log[] = '**Notice: No cache-control or expires header has been set. ' .
|
140 |
'It is recommended to do so. Set it nice and big once you are sure the webps have a good quality/compression compromise.**{: .warn}';
|
141 |
}
|
142 |
+
$log[] = '';
|
143 |
|
144 |
+
return [$noWarningsYet, $log, $createdTestFiles];
|
145 |
}
|
146 |
|
147 |
/*
|
148 |
private static function doRunTest($this->config)
|
149 |
{
|
150 |
+
$log = [];
|
151 |
+
$log[] = '# Testing redirection to converter';
|
152 |
|
153 |
$createdTestFiles = false;
|
154 |
if (!file_exists(Paths::getConfigFileName())) {
|
155 |
+
$log[] = 'Hold on. You need to save options before you can run this test. There is no config file yet.';
|
156 |
+
return [true, $log, $createdTestFiles];
|
157 |
}
|
158 |
|
159 |
|
160 |
if ($this->config['image-types'] == 0) {
|
161 |
+
$log[] = 'No image types have been activated, nothing to test';
|
162 |
+
return [true, $log, $createdTestFiles];
|
163 |
}
|
164 |
|
165 |
if ($this->config['image-types'] & 1) {
|
166 |
list($success, $subResult, $createdTestFiles) = self::runTestForImageType($this->config, 'jpeg');
|
167 |
+
$log = array_merge($log, $subResult);
|
168 |
|
169 |
if ($success) {
|
170 |
if ($this->config['image-types'] & 2) {
|
171 |
+
$log[] = '### Performing same tests for PNG';
|
172 |
list($success, $subResult, $createdTestFiles2) = self::runTestForImageType($this->config, 'png');
|
173 |
$createdTestFiles = $createdTestFiles || $createdTestFiles2;
|
174 |
if ($success) {
|
175 |
+
//$log[count($log) - 1] .= '. **ok**{: .ok}';
|
176 |
+
$log[] .= 'All tests passed for PNG as well.';
|
177 |
+
$log[] = '(I shall spare you for the report, which is almost identical to the one above)';
|
178 |
} else {
|
179 |
+
$log = array_merge($log, $subResult);
|
180 |
}
|
181 |
}
|
182 |
}
|
183 |
} else {
|
184 |
list($success, $subResult, $createdTestFiles) = self::runTestForImageType($this->config, 'png');
|
185 |
+
$log = array_merge($log, $subResult);
|
186 |
}
|
187 |
|
188 |
if ($success) {
|
189 |
+
$log[] = '### Conclusion';
|
190 |
+
$log[] = 'Everything **seems to work**{: .ok} as it should. ' .
|
191 |
'However, notice that this test only tested an image which was placed in the *uploads* folder. ' .
|
192 |
'The rest of the image roots (such as theme images) have not been tested (it is on the TODO). ' .
|
193 |
'Also on the TODO: If one image type is disabled, check that it does not redirect to the conversion script. ' .
|
195 |
}
|
196 |
|
197 |
|
198 |
+
return [true, $log, $createdTestFiles];
|
199 |
}*/
|
200 |
|
201 |
protected function getSuccessMessage()
|
207 |
|
208 |
public function startupTests()
|
209 |
{
|
210 |
+
$log[] = '# Testing "WebP Realizer" functionality';
|
211 |
if (!$this->config['enable-redirection-to-webp-realizer']) {
|
212 |
+
$log[] = 'Turned off, nothing to test (if you just turned it on without saving, remember: this is a live test so you need to save settings)';
|
213 |
+
return [false, $log];
|
214 |
}
|
215 |
+
return [true, $log];
|
216 |
}
|
217 |
|
218 |
public static function runTest()
|
lib/classes/WebPOnDemand.php
CHANGED
@@ -17,6 +17,7 @@ use \WebPExpress\SanityException;
|
|
17 |
use \WebPExpress\ValidateException;
|
18 |
use \WebPExpress\Validate;
|
19 |
use \WebPExpress\WodConfigLoader;
|
|
|
20 |
|
21 |
class WebPOnDemand extends WodConfigLoader
|
22 |
{
|
@@ -82,7 +83,7 @@ class WebPOnDemand extends WodConfigLoader
|
|
82 |
// Check querystring (full path)
|
83 |
// - But only on Nginx (our Apache .htaccess rules never passes absolute url)
|
84 |
if (
|
85 |
-
(
|
86 |
(isset($_GET['source']) || isset($_GET['xsource']))
|
87 |
) {
|
88 |
self::$checking = 'source (passed as absolute path on nginx)';
|
@@ -206,6 +207,39 @@ class WebPOnDemand extends WodConfigLoader
|
|
206 |
}
|
207 |
//echo $source . '<br>' . $destination; exit;
|
208 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
ConvertHelperIndependent::serveConverted(
|
210 |
$source,
|
211 |
$destination,
|
17 |
use \WebPExpress\ValidateException;
|
18 |
use \WebPExpress\Validate;
|
19 |
use \WebPExpress\WodConfigLoader;
|
20 |
+
use WebPConvert\Loggers\EchoLogger;
|
21 |
|
22 |
class WebPOnDemand extends WodConfigLoader
|
23 |
{
|
83 |
// Check querystring (full path)
|
84 |
// - But only on Nginx (our Apache .htaccess rules never passes absolute url)
|
85 |
if (
|
86 |
+
(self::isNginxHandlingImages()) &&
|
87 |
(isset($_GET['source']) || isset($_GET['xsource']))
|
88 |
) {
|
89 |
self::$checking = 'source (passed as absolute path on nginx)';
|
207 |
}
|
208 |
//echo $source . '<br>' . $destination; exit;
|
209 |
|
210 |
+
/*
|
211 |
+
// No caching!
|
212 |
+
// - perhaps this will solve it for WP engine.
|
213 |
+
// but no... Perhaps a 302 redirect to self then? (if redirect to existing is activated).
|
214 |
+
// TODO: try!
|
215 |
+
//$serveOptions['serve-image']['headers']['vary-accept'] = false;
|
216 |
+
|
217 |
+
*/
|
218 |
+
/*
|
219 |
+
include_once __DIR__ . '/../../vendor/autoload.php';
|
220 |
+
$convertLogger = new \WebPConvert\Loggers\BufferLogger();
|
221 |
+
\WebPConvert\WebPConvert::convert($source, $destination, $serveOptions['convert'], $convertLogger);
|
222 |
+
header('Location: ?fresh' , 302);
|
223 |
+
*/
|
224 |
+
|
225 |
+
if (isset($_SERVER['WPENGINE_ACCOUNT'])) {
|
226 |
+
// Redirect to self rather than serve directly for WP Engine.
|
227 |
+
// This overcomes that Vary:Accept header set from PHP is lost on WP Engine.
|
228 |
+
// To prevent endless loop in case "redirect to existing webp" isn't set up correctly,
|
229 |
+
// only activate when destination is missing.
|
230 |
+
// (actually it does not prevent anything on wpengine as the first request is cached!
|
231 |
+
// -even though we try to prevent it:)
|
232 |
+
// Well well. Those users better set up "redirect to existing webp" as well!
|
233 |
+
$serveOptions['serve-image']['headers']['cache-control'] = true;
|
234 |
+
$serveOptions['serve-image']['headers']['expires'] = false;
|
235 |
+
$serveOptions['serve-image']['cache-control-header'] = 'no-store, no-cache, must-revalidate, max-age=0';
|
236 |
+
//header("Pragma: no-cache", true);
|
237 |
+
|
238 |
+
if (!@file_exists($destination)) {
|
239 |
+
$serveOptions['redirect-to-self-instead-of-serving'] = true;
|
240 |
+
}
|
241 |
+
}
|
242 |
+
|
243 |
ConvertHelperIndependent::serveConverted(
|
244 |
$source,
|
245 |
$destination,
|
lib/classes/WebPRealizer.php
CHANGED
@@ -39,21 +39,30 @@ class WebPRealizer extends WodConfigLoader
|
|
39 |
|
40 |
// Check querystring (full path)
|
41 |
// - But only on Nginx (our Apache .htaccess rules never passes absolute url)
|
42 |
-
if (
|
43 |
-
(stripos($_SERVER["SERVER_SOFTWARE"], 'nginx') !== false) &&
|
44 |
-
(isset($_GET['destination']) || isset($_GET['xdestination']))
|
45 |
-
) {
|
46 |
if (isset($_GET['destination'])) {
|
47 |
-
|
48 |
-
}
|
|
|
49 |
$xdest = SanityCheck::noControlChars($_GET['xdestination']);
|
50 |
-
|
51 |
}
|
52 |
}
|
53 |
|
54 |
// Last resort is to use $_SERVER['REQUEST_URI'], well knowing that it does not give the
|
55 |
-
// correct result in all setups (ie "folder method 1")
|
|
|
56 |
$destRel = SanityCheck::pathWithoutDirectoryTraversal(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
$destination = SanityCheck::absPath($docRoot . $destRel);
|
58 |
return SanityCheck::absPathIsInDocRoot($destination);
|
59 |
}
|
39 |
|
40 |
// Check querystring (full path)
|
41 |
// - But only on Nginx (our Apache .htaccess rules never passes absolute url)
|
42 |
+
if (self::isNginxHandlingImages()) {
|
|
|
|
|
|
|
43 |
if (isset($_GET['destination'])) {
|
44 |
+
return SanityCheck::absPathIsInDocRoot($_GET['destination']);
|
45 |
+
}
|
46 |
+
if (isset($_GET['xdestination'])) {
|
47 |
$xdest = SanityCheck::noControlChars($_GET['xdestination']);
|
48 |
+
return SanityCheck::absPathIsInDocRoot(substr($xdest, 1));
|
49 |
}
|
50 |
}
|
51 |
|
52 |
// Last resort is to use $_SERVER['REQUEST_URI'], well knowing that it does not give the
|
53 |
+
// correct result in all setups (ie "folder method 1").
|
54 |
+
// On nginx, it can even return the path to webp-realizer.php. TODO: Handle that better than now
|
55 |
$destRel = SanityCheck::pathWithoutDirectoryTraversal(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
|
56 |
+
if ($destRel) {
|
57 |
+
if (preg_match('#webp-realizer\.php$#', $destRel)) {
|
58 |
+
throw new \Exception(
|
59 |
+
'webp-realizer.php need to know the file path and cannot simply use $_SERVER["REQUEST_URI"] ' .
|
60 |
+
'as that points to itself rather than the image requested. ' .
|
61 |
+
'On Nginx, please add: "&xdestination=x$request_filename" to the URL in the rules in the nginx config ' .
|
62 |
+
'(sorry, the parameter was missing in the rules in the README for a while, but it is back)'
|
63 |
+
);
|
64 |
+
}
|
65 |
+
}
|
66 |
$destination = SanityCheck::absPath($docRoot . $destRel);
|
67 |
return SanityCheck::absPathIsInDocRoot($destination);
|
68 |
}
|
lib/classes/WodConfigLoader.php
CHANGED
@@ -35,6 +35,42 @@ class WodConfigLoader
|
|
35 |
exit;
|
36 |
}
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
/**
|
39 |
* Get environment variable set with mod_rewrite module
|
40 |
* Return false if the environment variable isn't found
|
35 |
exit;
|
36 |
}
|
37 |
|
38 |
+
/**
|
39 |
+
* Check if Apache handles the PHP requests (Note that duel setups are possible and ie Nginx could be handling the image requests).
|
40 |
+
*/
|
41 |
+
public static function isApache()
|
42 |
+
{
|
43 |
+
return (stripos($_SERVER['SERVER_SOFTWARE'], 'apache') !== false);
|
44 |
+
}
|
45 |
+
|
46 |
+
protected static function isNginxHandlingImages()
|
47 |
+
{
|
48 |
+
if (stripos($_SERVER["SERVER_SOFTWARE"], 'nginx') !== false) {
|
49 |
+
return true;
|
50 |
+
}
|
51 |
+
|
52 |
+
// On WP Engine, SERVER_SOFTWARE is "Apache", but images are handled by NGINX.
|
53 |
+
if (isset($_SERVER['WPENGINE_ACCOUNT'])) {
|
54 |
+
return true;
|
55 |
+
};
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
|
59 |
+
public static function preventDirectAccess($filename)
|
60 |
+
{
|
61 |
+
// Protect against directly accessing webp-on-demand.php
|
62 |
+
// Only protect on Apache. We know for sure that the method is not reliable on nginx.
|
63 |
+
// We have not tested on litespeed yet, so we dare not.
|
64 |
+
if (self::isApache() && (!self::isNginxHandlingImages())) {
|
65 |
+
if (strpos($_SERVER['REQUEST_URI'], $filename) !== false) {
|
66 |
+
self::exitWithError(
|
67 |
+
'It seems you are visiting this file (plugins/webp-express/wod/' . $filename . ') directly. We do not allow this.'
|
68 |
+
);
|
69 |
+
exit;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
/**
|
75 |
* Get environment variable set with mod_rewrite module
|
76 |
* Return false if the environment variable isn't found
|
lib/options/page-welcome.php
CHANGED
@@ -35,8 +35,10 @@ if ($weKnowThereAreNoWorkingConverters) {
|
|
35 |
'<li>You can try to meet the server requirements of cwebp, imagick, vips, gmagick or gd. Check out <a target="_blank" href="https://github.com/rosell-dk/webp-convert/wiki/Meeting-the-requirements-of-the-converters">this wiki page</a> on how to do that</li>' .
|
36 |
'</ol>' .
|
37 |
'<p>Of course, there is also the option of using another plugin altogether. ' .
|
38 |
-
'I can recommend ' .
|
39 |
-
'
|
|
|
|
|
40 |
'</p>' .
|
41 |
"<p>Btw, don't worry, your images still works. The rewrite rules will not be saved until you click the " .
|
42 |
'"Save settings" button.</p>';
|
35 |
'<li>You can try to meet the server requirements of cwebp, imagick, vips, gmagick or gd. Check out <a target="_blank" href="https://github.com/rosell-dk/webp-convert/wiki/Meeting-the-requirements-of-the-converters">this wiki page</a> on how to do that</li>' .
|
36 |
'</ol>' .
|
37 |
'<p>Of course, there is also the option of using another plugin altogether. ' .
|
38 |
+
'I can recommend <i>Optimole</i>. ' .
|
39 |
+
'If you want to try that out and want to support me in the process, ' .
|
40 |
+
'<a href="https://optimole.pxf.io/20b0M">follow this link</a> ' .
|
41 |
+
'(it will give me a reward in case you decide to sign up).' .
|
42 |
'</p>' .
|
43 |
"<p>Btw, don't worry, your images still works. The rewrite rules will not be saved until you click the " .
|
44 |
'"Save settings" button.</p>';
|
vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebP.php
CHANGED
@@ -49,6 +49,8 @@ class ServeConvertedWebP
|
|
49 |
new BooleanOption('serve-original', false),
|
50 |
new BooleanOption('show-report', false),
|
51 |
new BooleanOption('suppress-warnings', true),
|
|
|
|
|
52 |
new ArrayOption('serve-image', []),
|
53 |
new SensitiveArrayOption('convert', [])
|
54 |
);
|
@@ -180,6 +182,12 @@ class ServeConvertedWebP
|
|
180 |
self::serveOriginal($source, $options['serve-image']);
|
181 |
}
|
182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
$filesizeDestination = @filesize($destination);
|
184 |
$filesizeSource = @filesize($source);
|
185 |
if (($filesizeSource !== false) &&
|
@@ -189,7 +197,14 @@ class ServeConvertedWebP
|
|
189 |
self::serveOriginal($source, $options['serve-image']);
|
190 |
}
|
191 |
|
192 |
-
|
193 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
}
|
195 |
}
|
49 |
new BooleanOption('serve-original', false),
|
50 |
new BooleanOption('show-report', false),
|
51 |
new BooleanOption('suppress-warnings', true),
|
52 |
+
new BooleanOption('redirect-to-self-instead-of-serving', false),
|
53 |
+
//new BooleanOption('redirect-to-self-instead-of-serving-destination', false),
|
54 |
new ArrayOption('serve-image', []),
|
55 |
new SensitiveArrayOption('convert', [])
|
56 |
);
|
182 |
self::serveOriginal($source, $options['serve-image']);
|
183 |
}
|
184 |
|
185 |
+
if ($options['redirect-to-self-instead-of-serving']) {
|
186 |
+
Header::addLogHeader('Redirecting to self! (hope you got redirection to existing webps set up, otherwise you will get a loop!)', $serveLogger);
|
187 |
+
header('Location: ?fresh' , 302);
|
188 |
+
return;
|
189 |
+
}
|
190 |
+
|
191 |
$filesizeDestination = @filesize($destination);
|
192 |
$filesizeSource = @filesize($source);
|
193 |
if (($filesizeSource !== false) &&
|
197 |
self::serveOriginal($source, $options['serve-image']);
|
198 |
}
|
199 |
|
200 |
+
/*if ($options['redirect-to-self-instead-of-serving-destination']) {
|
201 |
+
Header::addLogHeader('Redirecting to self! (hope you got redirection to existing webps set up, otherwise you will get a loop!)', $serveLogger);
|
202 |
+
header('Location: ?fresh' , 302);
|
203 |
+
} else {*/
|
204 |
+
Header::addLogHeader('Serving converted file', $serveLogger);
|
205 |
+
self::serveDestination($destination, $options['serve-image']);
|
206 |
+
//}
|
207 |
+
|
208 |
+
|
209 |
}
|
210 |
}
|
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.17.
|
7 |
* Author: Bjørn Rosell
|
8 |
* Author URI: https://www.bitwise-it.dk
|
9 |
* License: GPL2
|
@@ -52,55 +52,9 @@ if (Option::getOption('webp-express-alter-html', false)) {
|
|
52 |
\WebPExpress\AlterHtmlInit::setHooks();
|
53 |
}
|
54 |
|
55 |
-
/*
|
56 |
-
$filters = [];
|
57 |
-
add_action('all', function() {
|
58 |
-
global $filters;
|
59 |
-
$filter = current_filter();
|
60 |
-
if (!in_array($filter, $filters)) {
|
61 |
-
$filters[] = $filter;
|
62 |
-
error_log($filter);
|
63 |
-
}
|
64 |
-
});
|
65 |
-
*/
|
66 |
-
|
67 |
// When images are uploaded with Gutenberg, is_admin() returns false, so, hook needs to be added here
|
68 |
add_filter('wp_handle_upload', array('\WebPExpress\HandleUploadHooks', 'handleUpload'), 10, 2);
|
69 |
add_filter('image_make_intermediate_size', array('\WebPExpress\HandleUploadHooks', 'handleMakeIntermediateSize'), 10, 1);
|
70 |
add_filter('wp_delete_file', array('\WebPExpress\HandleDeleteFileHook', 'deleteAssociatedWebP'), 10, 2);
|
71 |
|
72 |
-
/*
|
73 |
-
add_action('wp_handle_upload', function($a) {
|
74 |
-
error_log('yes, it is called'. (is_admin() ? 'admin' : 'not admin'));
|
75 |
-
\WebPExpress\HandleUploadHooks::handleUpload($a, true);
|
76 |
-
return $a;
|
77 |
-
});*/
|
78 |
-
|
79 |
-
|
80 |
-
/*
|
81 |
-
function webpexpress_addWebPJs() {
|
82 |
-
$url = plugins_url('webpjs/webpjs-0.0.2.min.js', __FILE__);
|
83 |
-
$script = <<<EOD
|
84 |
-
<script>
|
85 |
-
(function(){
|
86 |
-
var WebP=new Image();
|
87 |
-
WebP.onload=WebP.onerror=function(){
|
88 |
-
if(WebP.height!=2){
|
89 |
-
var sc=document.createElement('script');
|
90 |
-
sc.type='text/javascript';
|
91 |
-
sc.async=true;
|
92 |
-
var s=document.getElementsByTagName('script')[0];
|
93 |
-
sc.src='$url';
|
94 |
-
s.parentNode.insertBefore(sc,s);
|
95 |
-
}
|
96 |
-
};
|
97 |
-
WebP.src='data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
|
98 |
-
})();
|
99 |
-
</script>
|
100 |
-
EOD;
|
101 |
-
echo $script;
|
102 |
-
}
|
103 |
-
|
104 |
-
add_action( 'wp_head', 'webpexpress_addWebPJs');
|
105 |
-
*/
|
106 |
//add_action( 'template_redirect', 'webp_express_template_redirect' );
|
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.17.1
|
7 |
* Author: Bjørn Rosell
|
8 |
* Author URI: https://www.bitwise-it.dk
|
9 |
* License: GPL2
|
52 |
\WebPExpress\AlterHtmlInit::setHooks();
|
53 |
}
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
// When images are uploaded with Gutenberg, is_admin() returns false, so, hook needs to be added here
|
56 |
add_filter('wp_handle_upload', array('\WebPExpress\HandleUploadHooks', 'handleUpload'), 10, 2);
|
57 |
add_filter('image_make_intermediate_size', array('\WebPExpress\HandleUploadHooks', 'handleMakeIntermediateSize'), 10, 1);
|
58 |
add_filter('wp_delete_file', array('\WebPExpress\HandleDeleteFileHook', 'deleteAssociatedWebP'), 10, 2);
|
59 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
//add_action( 'template_redirect', 'webp_express_template_redirect' );
|
wod/.htaccess
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
<FilesMatch "(webp-on-demand|webp-realizer)\.php$">
|
2 |
<IfModule !mod_authz_core.c>
|
3 |
Order deny,allow
|
1 |
+
# Grant access to webp-on-demand.php and webp-realizer.php
|
2 |
<FilesMatch "(webp-on-demand|webp-realizer)\.php$">
|
3 |
<IfModule !mod_authz_core.c>
|
4 |
Order deny,allow
|
wod/autoloader.php
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
define('WOD_DIR', __DIR__);
|
3 |
+
function webpexpress_autoloader($class) {
|
4 |
+
if (strpos($class, 'WebPExpress\\') === 0) {
|
5 |
+
require_once WOD_DIR . '/../lib/classes/' . substr($class, 12) . '.php';
|
6 |
+
}
|
7 |
+
}
|
8 |
+
spl_autoload_register('webpexpress_autoloader');
|
wod/webp-on-demand.php
CHANGED
@@ -1,25 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
-
// Only protect on Apache. We know for sure that the method is not reliable on nginx. We have not tested on litespeed yet, so we dare not.
|
7 |
-
if (stripos($_SERVER["SERVER_SOFTWARE"], 'apache') !== false && stripos($_SERVER["SERVER_SOFTWARE"], 'nginx') === false) {
|
8 |
-
if (strpos($_SERVER['REQUEST_URI'], 'webp-on-demand.php') !== false) {
|
9 |
-
WebPOnDemand::exitWithError(
|
10 |
-
'It seems you are visiting this file (plugins/webp-express/wod/webp-on-demand.php) directly. We do not allow this.'
|
11 |
-
);
|
12 |
-
exit;
|
13 |
-
}
|
14 |
-
}
|
15 |
-
|
16 |
-
define('WOD_DIR', __DIR__);
|
17 |
-
|
18 |
-
function webpexpress_autoloader($class) {
|
19 |
-
if (strpos($class, 'WebPExpress\\') === 0) {
|
20 |
-
require_once WOD_DIR . '/../lib/classes/' . substr($class, 12) . '.php';
|
21 |
-
}
|
22 |
-
}
|
23 |
-
spl_autoload_register('webpexpress_autoloader');
|
24 |
|
|
|
25 |
WebPOnDemand::processRequest();
|
1 |
<?php
|
2 |
|
3 |
+
namespace WebPExpress;
|
4 |
|
5 |
+
include 'autoloader.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
+
WebPOnDemand::preventDirectAccess('webp-on-demand.php');
|
8 |
WebPOnDemand::processRequest();
|
wod/webp-realizer.php
CHANGED
@@ -1,25 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
-
// Only protect on Apache. We know for sure that the method is not reliable on nginx. We have not tested on litespeed yet, so we dare not.
|
7 |
-
if (stripos($_SERVER["SERVER_SOFTWARE"], 'apache') !== false && stripos($_SERVER["SERVER_SOFTWARE"], 'nginx') === false) {
|
8 |
-
if (strpos($_SERVER['REQUEST_URI'], 'webp-realizer.php') !== false) {
|
9 |
-
WebPOnDemand::exitWithError(
|
10 |
-
'It seems you are visiting this file (plugins/webp-express/wod/webp-realizer.php) directly. We do not allow this.'
|
11 |
-
);
|
12 |
-
exit;
|
13 |
-
}
|
14 |
-
}
|
15 |
-
|
16 |
-
define('WOD_DIR', __DIR__);
|
17 |
-
|
18 |
-
function webpexpress_autoloader($class) {
|
19 |
-
if (strpos($class, 'WebPExpress\\') === 0) {
|
20 |
-
require_once WOD_DIR . '/../lib/classes/' . substr($class, 12) . '.php';
|
21 |
-
}
|
22 |
-
}
|
23 |
-
spl_autoload_register('webpexpress_autoloader');
|
24 |
|
|
|
25 |
WebPRealizer::processRequest();
|
1 |
<?php
|
2 |
|
3 |
+
namespace WebPExpress;
|
4 |
|
5 |
+
include 'autoloader.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
+
WebPRealizer::preventDirectAccess('webp-realizer.php');
|
8 |
WebPRealizer::processRequest();
|