Version Description
(released 5 mar 2019) * Multisite support (!) * A new operation mode: "No conversion", if you do not want to use WebP Express for converting. Replaces the old "Just redirect" mode * Added capability testing of .htaccess. The .htaccess rules are now tailored to the capabilities on the system. For example, on some platforms the filename of a requested image is passed to the converter script through the query string, but on platforms that supports passing it through an environment variable, that method is used instead * Picturefill.js is now optional (alter html, picture tag) * A great bunch more!
For more info, see the closed issues on the 0.12.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/12?closed=1
Release Info
Developer | rosell.dk |
Plugin | WebP Express |
Version | 0.12.0 |
Comparing to | |
See all releases |
Code changes from version 0.11.3 to 0.12.0
- README.md +46 -10
- README.txt +65 -9
- changelog.txt +19 -0
- docs/development.md +1 -1
- htaccess-capability-tests/.htaccess +6 -0
- htaccess-capability-tests/has-mod-header/.htaccess +3 -0
- htaccess-capability-tests/has-mod-header/test.php +9 -0
- htaccess-capability-tests/has-mod-rewrite/.htaccess +11 -0
- htaccess-capability-tests/has-mod-rewrite/1.php +2 -0
- htaccess-capability-tests/has-mod-rewrite/test.php +2 -0
- htaccess-capability-tests/pass-server-var-through-header/.htaccess +15 -0
- htaccess-capability-tests/pass-server-var-through-header/test.php +9 -0
- htaccess-capability-tests/pass-through-environment-var/.htaccess +13 -0
- htaccess-capability-tests/pass-through-environment-var/test.php +27 -0
- htaccess-capability-tests/request-uri-usable-in-this-dir/.htaccess +11 -0
- htaccess-capability-tests/request-uri-usable-in-this-dir/test.php +3 -0
- htaccess-capability-tests/request-uri-usable-in-this-dir/test2.php +51 -0
- htaccess-capability-tests/urls.txt +12 -0
- lib/activate-first-time.php +16 -10
- lib/admin.php +28 -9
- lib/classes/Actions.php +4 -2
- lib/classes/AlterHtmlHelper.php +10 -1
- lib/classes/AlterHtmlImageUrls.php +0 -48
- lib/classes/AlterHtmlInit.php +10 -8
- lib/classes/CapabilityTest.php +96 -0
- lib/classes/Config.php +57 -16
- lib/classes/FileHelper.php +42 -0
- lib/classes/HTAccess.php +161 -79
- lib/classes/KeepEwwwSubscriptionAlive.php +60 -0
- lib/classes/Messenger.php +5 -3
- lib/classes/Multisite.php +36 -0
- lib/classes/Option.php +39 -0
- lib/classes/Paths.php +13 -12
- lib/classes/State.php +5 -2
- lib/migrate/migrate.php +8 -34
- lib/migrate/migrate1.php +9 -8
- lib/migrate/migrate2.php +3 -1
- lib/migrate/migrate3.php +2 -1
- lib/migrate/migrate4.php +2 -1
- lib/migrate/migrate5.php +6 -4
- lib/migrate/migrate6.php +3 -10
- lib/migrate/migrate7.php +94 -0
- lib/options/css/webp-express-options-page.css +129 -2
- lib/options/enqueue_scripts.php +13 -9
- lib/options/js/page.js +142 -98
- lib/options/options-hooks.php +30 -15
- lib/options/options/alter-html/alter-html-options.inc +132 -39
- lib/options/options/alter-html/alter-html.inc +6 -9
- lib/options/options/conversion-options/conversion-options.inc +2 -17
- lib/options/options/conversion-options/destination-extension.inc +0 -24
- lib/options/options/conversion-options/metadata.inc +0 -1
- lib/options/options/{serve-options → general}/cache-control.inc +11 -21
- lib/options/options/general/destination-extension.inc +60 -0
- lib/options/options/{conversion-options → general}/destination-folder.inc +0 -0
- lib/options/options/general/general.inc +21 -0
- lib/options/options/{redirection-rules → general}/image-types.inc +11 -6
- lib/options/options/operation-mode.inc +12 -11
- lib/options/options/redirection-rules/enable-redirection-to-converter.inc +4 -4
- lib/options/options/redirection-rules/enable-redirection-to-webp-realizer.inc +4 -3
- lib/options/options/redirection-rules/only-redirect-to-converter-for-webp-enabled-browsers.inc +3 -2
- lib/options/options/redirection-rules/only-redirect-to-converter-on-cache-miss.inc +4 -4
- lib/options/options/redirection-rules/redirect-to-existing.inc +21 -4
- lib/options/options/redirection-rules/redirection-rules.inc +50 -26
- lib/options/options/serve-options/response-on-failure.inc +0 -1
- lib/options/options/serve-options/response-on-success.inc +0 -1
- lib/options/options/serve-options/serve-options.inc +0 -5
- lib/options/options/web-service-options/web-service-options.inc +1 -7
- lib/options/page-messages.php +97 -5
- lib/options/page.php +85 -29
- lib/options/submit.php +46 -22
- lib/uninstall.php +3 -2
- webp-express.php +15 -2
- wod/webp-on-demand.php +98 -29
- wod/webp-realizer.php +91 -22
@@ -31,9 +31,11 @@ The plugin builds on [WebPConvert](https://github.com/rosell-dk/webp-convert) an
|
|
31 |
- Less bandwidth consumption - makes a huge difference in the parts of the world where the internet is slow and costly (you know, ~80% of the world population lives under these circumstances).
|
32 |
- Currently ~73% of all traffic, and ~79% of mobile browsing traffic are done with browsers supporting webp. With Mozilla and Microsoft [finally on board](https://medium.com/@richard_90141/webp-image-support-an-8-year-saga-7aa2bedb8d02), these numbers are bound to increase. Check current numbers on [caniuse.com](https://caniuse.com/webp)).
|
33 |
|
|
|
|
|
|
|
34 |
|
35 |
## Installation
|
36 |
-
|
37 |
1. Upload the plugin files to the `/wp-content/plugins/webp-express` directory, or install the plugin through the WordPress plugins screen directly.
|
38 |
2. Activate the plugin through the 'Plugins' screen in WordPress
|
39 |
3. Configure it (the plugin doesn't do anything until configured)
|
@@ -100,14 +102,10 @@ The redirect rules created in *.htaccess* are pointing to a PHP script. If you h
|
|
100 |
*Note:*
|
101 |
Do not simply remove the plugin without deactivating it first. Deactivation takes care of removing the rules in the *.htaccess* file. With the rules there, but converter gone, your Google Chrome visitors will not see any jpeg images.
|
102 |
|
103 |
-
*Note:*
|
104 |
-
The plugin has not been tested in multisite configurations.
|
105 |
-
|
106 |
|
107 |
## Limitations
|
108 |
|
109 |
-
* The plugin
|
110 |
-
* The plugin has not been tested with multisite installation
|
111 |
|
112 |
## Frequently Asked Questions
|
113 |
|
@@ -146,6 +144,8 @@ It is possible to make WebP Express work on NGINX, but it requires manually inse
|
|
146 |
|
147 |
There are two different approaches to achieve the redirections. One based on *rewrite* and one based on *try_files*. As *try_files* performs best, I shall recommend that.
|
148 |
|
|
|
|
|
149 |
#### method 1 (try_files)
|
150 |
|
151 |
Lets take this step by step.
|
@@ -247,7 +247,7 @@ Insert the following in the `server` context:
|
|
247 |
# WebP Express rules
|
248 |
# --------------------
|
249 |
if ($http_accept ~* "webp"){
|
250 |
-
rewrite ^/(.*).(jpe?g|png)$ /wp-content/plugins/webp-express/wod/webp-on-demand.php?wp-content=wp-content break;
|
251 |
}
|
252 |
# ------------------- (WebP Express rules ends here)
|
253 |
```
|
@@ -330,6 +330,7 @@ location ~* ^/wp-content/.*\.webp$ {
|
|
330 |
Discussion on this topic [here](https://wordpress.org/support/topic/nginx-rewrite-rules-4/)
|
331 |
And here: https://github.com/rosell-dk/webp-express/issues/166
|
332 |
|
|
|
333 |
|
334 |
### I am on a WAMP stack
|
335 |
It has been reported that WebP Express *almost* works on WAMP stack (Windows, Apache, MySQL, PHP). I'd love to debug this, but do not own a Windows server or access to one... Can you help?
|
@@ -447,7 +448,7 @@ To make *WebP Express* work on a free Cloudflare account, you have the following
|
|
447 |
|
448 |
2. You can set up another CDN (on another provider), which you just use for handling the images. You need to configure that CDN to forward the *Accept header*. You also need to install a Wordpress plugin that points images to that CDN.
|
449 |
|
450 |
-
3. You can switch operation mode to "
|
451 |
|
452 |
### WebP Express / ShortPixel setup
|
453 |
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.
|
@@ -555,21 +556,56 @@ In a webp-enabled browser, the HTML may look like this: `<img src="image.webp">`
|
|
555 |
### Does it work with lazy loaded images?
|
556 |
No plugins/frameworks has yet been discovered, which does not work with *WebP Express*.
|
557 |
|
558 |
-
The most common way of lazy-loading is by setting a *data-src* attribute on the image and let javascript use that value for
|
559 |
|
560 |
The following lazy load plugins/frameworks has been tested and works with *WebP Express*:
|
561 |
- [BJ Lazy Load](https://da.wordpress.org/plugins/bj-lazy-load/)
|
562 |
- [Owl Carousel 2](https://owlcarousel2.github.io/OwlCarousel2/)
|
|
|
563 |
|
564 |
I have only tested the above in *Varied image responses* mode, but it should also work in *CDN friendly* mode. Both *Alter HTML* options have been designed to work with standard lazy load attributes.
|
565 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
566 |
### When is feature X coming? / Roadmap
|
567 |
No schedule. I move forward as time allows. I currently spend a lot of time answering questions in the support forum. If someone would be nice and help out answering questions here, it would allow me to spend that time developing. Also, donations would allow me to turn down some of the more boring requests from my customers, and speed things up here.
|
568 |
|
569 |
-
Here are my current plans ahead:
|
570 |
|
571 |
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.
|
572 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
573 |
## Changes in 0.11.0
|
574 |
- Alter HTML to point to webp files (choose between picture tags or simply altering all image urls)
|
575 |
- Convert non-existing webp-files upon request (means you can reference the converted webp files before they are actually converted!)
|
31 |
- Less bandwidth consumption - makes a huge difference in the parts of the world where the internet is slow and costly (you know, ~80% of the world population lives under these circumstances).
|
32 |
- Currently ~73% of all traffic, and ~79% of mobile browsing traffic are done with browsers supporting webp. With Mozilla and Microsoft [finally on board](https://medium.com/@richard_90141/webp-image-support-an-8-year-saga-7aa2bedb8d02), these numbers are bound to increase. Check current numbers on [caniuse.com](https://caniuse.com/webp)).
|
33 |
|
34 |
+
### Recent news
|
35 |
+
Feb 2019: Multisite is now supported (0.12.0)
|
36 |
+
Jan 2019: Plugin can now alter HTML (0.11.0)
|
37 |
|
38 |
## Installation
|
|
|
39 |
1. Upload the plugin files to the `/wp-content/plugins/webp-express` directory, or install the plugin through the WordPress plugins screen directly.
|
40 |
2. Activate the plugin through the 'Plugins' screen in WordPress
|
41 |
3. Configure it (the plugin doesn't do anything until configured)
|
102 |
*Note:*
|
103 |
Do not simply remove the plugin without deactivating it first. Deactivation takes care of removing the rules in the *.htaccess* file. With the rules there, but converter gone, your Google Chrome visitors will not see any jpeg images.
|
104 |
|
|
|
|
|
|
|
105 |
|
106 |
## Limitations
|
107 |
|
108 |
+
* The plugin has not been tested by the developer on Microsoft IIS server. [Some however reports that it works](https://wordpress.org/support/topic/iis-and-webp-works/)
|
|
|
109 |
|
110 |
## Frequently Asked Questions
|
111 |
|
144 |
|
145 |
There are two different approaches to achieve the redirections. One based on *rewrite* and one based on *try_files*. As *try_files* performs best, I shall recommend that.
|
146 |
|
147 |
+
For multisite on NGINX, read [here](https://github.com/rosell-dk/webp-express/issues/8)
|
148 |
+
|
149 |
#### method 1 (try_files)
|
150 |
|
151 |
Lets take this step by step.
|
247 |
# WebP Express rules
|
248 |
# --------------------
|
249 |
if ($http_accept ~* "webp"){
|
250 |
+
rewrite ^/(.*).(jpe?g|png)$ /wp-content/plugins/webp-express/wod/webp-on-demand.php?xsource=x$request_filename&wp-content=wp-content break;
|
251 |
}
|
252 |
# ------------------- (WebP Express rules ends here)
|
253 |
```
|
330 |
Discussion on this topic [here](https://wordpress.org/support/topic/nginx-rewrite-rules-4/)
|
331 |
And here: https://github.com/rosell-dk/webp-express/issues/166
|
332 |
|
333 |
+
Here are rules if you need to replace the file extension with ".webp" rather than appending ".webp" to it: https://www.keycdn.com/support/optimus/configuration-to-deliver-webp
|
334 |
|
335 |
### I am on a WAMP stack
|
336 |
It has been reported that WebP Express *almost* works on WAMP stack (Windows, Apache, MySQL, PHP). I'd love to debug this, but do not own a Windows server or access to one... Can you help?
|
448 |
|
449 |
2. You can set up another CDN (on another provider), which you just use for handling the images. You need to configure that CDN to forward the *Accept header*. You also need to install a Wordpress plugin that points images to that CDN.
|
450 |
|
451 |
+
3. You can switch operation mode to "CDN friendly" and use HTML altering.
|
452 |
|
453 |
### WebP Express / ShortPixel setup
|
454 |
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.
|
556 |
### Does it work with lazy loaded images?
|
557 |
No plugins/frameworks has yet been discovered, which does not work with *WebP Express*.
|
558 |
|
559 |
+
The most common way of lazy-loading is by setting a *data-src* attribute on the image and let javascript use that value for setting the *src* attribute. That method works, as the image request, seen from the server side, is indistinguishable from any other image request. It could however be that some obscure lazy load implementation would load the image with an XHR request. In that case, the *Accept* header will not contain 'image/webp', but '*/*', and a jpeg will be served, even though the browser supports webp.
|
560 |
|
561 |
The following lazy load plugins/frameworks has been tested and works with *WebP Express*:
|
562 |
- [BJ Lazy Load](https://da.wordpress.org/plugins/bj-lazy-load/)
|
563 |
- [Owl Carousel 2](https://owlcarousel2.github.io/OwlCarousel2/)
|
564 |
+
- [Lazy Load by WP Rocket](https://wordpress.org/plugins/rocket-lazy-load/)
|
565 |
|
566 |
I have only tested the above in *Varied image responses* mode, but it should also work in *CDN friendly* mode. Both *Alter HTML* options have been designed to work with standard lazy load attributes.
|
567 |
|
568 |
+
### Can I make an exceptions for some images?
|
569 |
+
There can be instances where you actually need to serve a jpeg or png. For example if you are demonstrating how a jpeg looks using some compression settings. It is possible to bypass both the redirection and the HTML altering for certain images. Here is how:
|
570 |
+
|
571 |
+
*Alter HTML*
|
572 |
+
Alter HTML is programmed not to substitute image URLs with query strings (better safe than sorry). You can exploit that and simply add ie ?original to the image URLs in question.
|
573 |
+
|
574 |
+
*Redirection*
|
575 |
+
To bypass the *redirection*, you can add the following in the `.htaccess` where *WebP Express* has placed its rules (this is usually in the `wp-content` folder). The rules needs to be added *above* the rules inserted by *WebP Express*.
|
576 |
+
|
577 |
+
```
|
578 |
+
RewriteCond %{QUERY_STRING} original
|
579 |
+
RewriteCond %{REQUEST_FILENAME} -f
|
580 |
+
RewriteRule . - [L]
|
581 |
+
```
|
582 |
+
With those rules in place, you can add "?original" to the URLs of those images that you want to keep serving as jpg / png.
|
583 |
+
|
584 |
+
Alternatively, you can specify the filenames individually in the `.htaccess`:
|
585 |
+
|
586 |
+
```
|
587 |
+
RewriteRule ^uploads/2019/02/example-of-jpg-compressed-to-80\.jpg - [L]
|
588 |
+
RewriteRule ^uploads/2019/02/image2\.jpg - [L]
|
589 |
+
RewriteRule . - [L]
|
590 |
+
```
|
591 |
+
If you got any further questions, look at, or comment on [this topic](https://wordpress.org/support/topic/can-i-make-an-exception-for-specific-post-image/)
|
592 |
+
|
593 |
### When is feature X coming? / Roadmap
|
594 |
No schedule. I move forward as time allows. I currently spend a lot of time answering questions in the support forum. If someone would be nice and help out answering questions here, it would allow me to spend that time developing. Also, donations would allow me to turn down some of the more boring requests from my customers, and speed things up here.
|
595 |
|
596 |
+
Here are my current plans ahead: 0.13 might be bulk conversion and addition of a diagnose tool – this should release some time spend in the forum. 0.14 could be focused on PNG. 0.15 might be displaying rules for NGINX. 0.16 might be supporting Save-Data header (send extra compressed images to clients who wants to use as little bandwidth as possible). 0.17 might be a file manager-like interface for inspecting generated webp files. 0.18 might be an effort to allow webp for all browsers using [this javascript library](http://libwebpjs.hohenlimburg.org/v0.6.0/). Unfortunately, the javascript librare does not (currently) support srcset attributes, which is why I moved this item down the priority list. We need srcset to be supported for the feature to be useful. 0.19 might be WAMP support. The current milestones, their subtasks and their progress can be viewed here: https://github.com/rosell-dk/webp-express/milestones
|
597 |
|
598 |
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.
|
599 |
|
600 |
+
## Changes in 0.12.0
|
601 |
+
- Multisite support (!)
|
602 |
+
- A new operation mode: "No conversion", if you do not want to use WebP Express for converting. Replaces the old "Just redirect" mode
|
603 |
+
- Added capability testing of .htaccess. The .htaccess rules are now tailored to the capabilities on the system. For example, on some platforms the filename of a requested image is passed to the converter script through the query string, but on platforms that supports passing it through an environment variable, that method is used instead
|
604 |
+
- Picturefill.js is now optional (alter html, picture tag)
|
605 |
+
- A great bunch more!
|
606 |
+
|
607 |
+
For more info, see the closed issues on the 0.12.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/12?closed=1
|
608 |
+
|
609 |
## Changes in 0.11.0
|
610 |
- Alter HTML to point to webp files (choose between picture tags or simply altering all image urls)
|
611 |
- Convert non-existing webp-files upon request (means you can reference the converted webp files before they are actually converted!)
|
@@ -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.1
|
7 |
-
Stable tag: 0.
|
8 |
Requires PHP: 5.6
|
9 |
License: GPLv3
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
@@ -37,6 +37,10 @@ The plugin builds on [WebPConvert](https://github.com/rosell-dk/webp-convert) an
|
|
37 |
- Less bandwidth consumption - makes a huge difference in the parts of the world where the internet is slow and costly (you know, ~80% of the world population lives under these circumstances).
|
38 |
- Currently ~73% of all traffic, and ~79% of mobile browsing traffic are done with browsers supporting webp. With Mozilla and Microsoft [finally on board](https://medium.com/@richard_90141/webp-image-support-an-8-year-saga-7aa2bedb8d02), these numbers are bound to increase. Check current numbers on [caniuse.com](https://caniuse.com/webp)).
|
39 |
|
|
|
|
|
|
|
|
|
40 |
== Installation ==
|
41 |
|
42 |
1. Upload the plugin files to the `/wp-content/plugins/webp-express` directory, or install the plugin through the WordPress plugins screen directly.
|
@@ -87,13 +91,9 @@ The redirect rules created in *.htaccess* are pointing to a PHP script. If you h
|
|
87 |
*Note:*
|
88 |
Do not simply remove the plugin without deactivating it first. Deactivation takes care of removing the rules in the *.htaccess* file. With the rules there, but converter gone, your Google Chrome visitors will not see any jpeg images.
|
89 |
|
90 |
-
*Note:*
|
91 |
-
The plugin has not been tested in multisite configurations. It's on the roadmap...
|
92 |
-
|
93 |
== Limitations ==
|
94 |
|
95 |
-
* The plugin
|
96 |
-
* The plugin has not been tested with multisite installation (it is on the roadmap!).
|
97 |
|
98 |
== Supporting WebP Express ==
|
99 |
Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue wasting time on this plugin:
|
@@ -154,6 +154,8 @@ It is possible to make WebP Express work on NGINX, but it requires manually inse
|
|
154 |
|
155 |
There are two different approaches to achieve the redirections. One based on *rewrite* and one based on *try_files*. As *try_files* performs best, I shall recommend that.
|
156 |
|
|
|
|
|
157 |
**method 1 (try_files)**
|
158 |
|
159 |
Lets take this step by step.
|
@@ -252,7 +254,8 @@ Insert the following in the `server` context:
|
|
252 |
|
253 |
`
|
254 |
if ($http_accept ~* "webp"){
|
255 |
-
rewrite ^/(.*).(jpe?g|png)$ /wp-content/plugins/webp-express/wod/webp-on-demand.php?wp-content=wp-content break;
|
|
|
256 |
}
|
257 |
`
|
258 |
|
@@ -328,6 +331,8 @@ location ~* ^/wp-content/.*\.webp$ {
|
|
328 |
Discussion on this topic [here](https://wordpress.org/support/topic/nginx-rewrite-rules-4/)
|
329 |
And here: https://github.com/rosell-dk/webp-express/issues/166
|
330 |
|
|
|
|
|
331 |
|
332 |
= I am on a WAMP stack =
|
333 |
It has been reported that WebP Express *almost* works on WAMP stack. I'd love to debug this, but do not own a Windows server or access to one... Can you help?
|
@@ -443,7 +448,7 @@ To make *WebP Express* work on a free Cloudflare account, you have the following
|
|
443 |
|
444 |
2. You can set up another CDN (on another provider), which you just use for handling the images. You need to configure that CDN to forward the *Accept header*. You also need to install a Wordpress plugin that points images to that CDN.
|
445 |
|
446 |
-
3. You can switch operation mode to "
|
447 |
|
448 |
### WebP Express / ShortPixel setup
|
449 |
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.
|
@@ -559,10 +564,35 @@ The following lazy load plugins/frameworks has been tested and works with *WebP
|
|
559 |
|
560 |
I have only tested the above in *Varied image responses* mode, but it should also work in *CDN friendly* mode. Both *Alter HTML* options have been designed to work with standard lazy load attributes.
|
561 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
562 |
= When is feature X coming? / Roadmap =
|
563 |
No schedule. I move forward as time allows. I currently spend a lot of time answering questions in the support forum. If someone would be nice and help out answering questions here, it would allow me to spend that time developing. Also, donations would allow me to turn down some of the more boring requests from my customers, and speed things up here.
|
564 |
|
565 |
-
Here are my current plans ahead:
|
566 |
|
567 |
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.
|
568 |
|
@@ -574,7 +604,19 @@ Easy enough! - [Go here!](https://ko-fi.com/rosell). Or [here](https://buymeacof
|
|
574 |
1. WebP Express settings
|
575 |
|
576 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
577 |
= 0.11.3 =
|
|
|
578 |
* Fixed bug: Alter HTML caused media library not to display images on some systems. Alter HTML is now disabled in admin mode.
|
579 |
* Alter HTML (picture tags) could produce the source tags with "src" attribute. But source tags inside picture tags must use "srcset" attribute. Fixed.
|
580 |
* Alter HTML (image urls): srcsets containing "x" descriptors wasn't handled (ie, srcset="image.jpg 1x")
|
@@ -583,19 +625,23 @@ Easy enough! - [Go here!](https://ko-fi.com/rosell). Or [here](https://buymeacof
|
|
583 |
* Fixed bug: The code that determined if WebP Express had placed rules in a .htaccess failed in "CDN friendly" mode. The effect was that these rules was not cleaned up upon plugin deactivation
|
584 |
|
585 |
= 0.11.2 =
|
|
|
586 |
* Fixed bug which caused Alter HTML to fail miserably on some setups
|
587 |
* AlterHTML now also looks for lazy load attributes in DIV and LI tags.
|
588 |
|
589 |
= 0.11.1 =
|
|
|
590 |
* Fixed bug which caused the new "Convert non-existing webp-files upon request" not to work on all setups
|
591 |
|
592 |
= 0.11.0 =
|
|
|
593 |
* Alter HTML to point to webp files (choose between picture tags or simply altering all image urls)
|
594 |
* Convert non-existing webp-files upon request (means you can reference the converted webp files before they are actually converted!)
|
595 |
|
596 |
For more info, see the closed issues on the 0.11.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/14?closed=1
|
597 |
|
598 |
= 0.10.0 =
|
|
|
599 |
* Introduced "Operation modes" in order to keep setting screens simple but still allow tweaking
|
600 |
* WebP Express can now be used in conjunction with Cache Enabler and ShortPixel
|
601 |
* Cache-Control header is now added in *.htaccess*, when redirecting directly to existing webp
|
@@ -615,9 +661,11 @@ For more info, see the closed issues on the 0.10.0 milestone on the github repos
|
|
615 |
For more info, see the closed issues on the 0.9.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.9.0
|
616 |
|
617 |
= 0.8.1 =
|
|
|
618 |
* Fixed javascript bug
|
619 |
|
620 |
= 0.8.0 =
|
|
|
621 |
* New conversion method, which calls imagick binary directly. This will make WebP express work out of the box on more systems
|
622 |
* Made sure not to trigger LFI warning i Wordfence (to activate, click the force .htaccess button)
|
623 |
* Imagick can now be configured to set quality to auto on systems where the auto option isn't generally available
|
@@ -628,17 +676,21 @@ For more info, see the closed issues on the 0.9.0 milestone on the github reposi
|
|
628 |
For more info, see the closed issues on the 0.8.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0
|
629 |
|
630 |
= 0.7.2 =
|
|
|
631 |
Fixed a critical bug which generated an error message which caused corrupt images. It was not the bug itself, but the error message it generated, that caused the images to be corrupted. It only happened when debugging was enabled in php.ini
|
632 |
|
633 |
= 0.7.1 =
|
|
|
634 |
Fixed minor "bug". The Api version combobox in Remote WebP Express converter was showing on new sites, but I only want it to show when old api is being used.
|
635 |
|
636 |
= 0.7.0 =
|
|
|
637 |
This version added option to provide conversion service to other sites!
|
638 |
|
639 |
For more info, see the closed issues on the 0.7.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.7.0
|
640 |
|
641 |
= 0.6.0 =
|
|
|
642 |
This version added option for setting caching header, fixed a serious issue with *Imagick*, added a new converter, *Gmagick*, added a great deal of options to *Cwebp* and generally improved the interface.
|
643 |
|
644 |
* Added option for caching
|
@@ -656,6 +708,7 @@ This version added option for setting caching header, fixed a serious issue with
|
|
656 |
For more info, see the closed issues on the 0.6.0 milestone on our github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.6.0
|
657 |
|
658 |
= 0.5.0 =
|
|
|
659 |
This version works on many more setups than the previous. Also uses less resources and handles when images are changed.
|
660 |
|
661 |
* Configuration is now stored in a separate configuration file instead of storing directly in the *.htaccess* file and passing it on via query string. When updating, these settings are migrated automatically.
|
@@ -682,6 +735,9 @@ For older releases, check out changelog.txt
|
|
682 |
|
683 |
== Upgrade Notice ==
|
684 |
|
|
|
|
|
|
|
685 |
= 0.11.3 =
|
686 |
Fixed several bugs. You should update :)
|
687 |
|
4 |
Tags: webp, images, performance
|
5 |
Requires at least: 4.0
|
6 |
Tested up to: 5.1
|
7 |
+
Stable tag: 0.12.0
|
8 |
Requires PHP: 5.6
|
9 |
License: GPLv3
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
37 |
- Less bandwidth consumption - makes a huge difference in the parts of the world where the internet is slow and costly (you know, ~80% of the world population lives under these circumstances).
|
38 |
- Currently ~73% of all traffic, and ~79% of mobile browsing traffic are done with browsers supporting webp. With Mozilla and Microsoft [finally on board](https://medium.com/@richard_90141/webp-image-support-an-8-year-saga-7aa2bedb8d02), these numbers are bound to increase. Check current numbers on [caniuse.com](https://caniuse.com/webp)).
|
39 |
|
40 |
+
### Recent news
|
41 |
+
Feb 2019: Multisite is now supported (0.12.0)
|
42 |
+
Jan 2019: Plugin can now alter HTML (0.11.0)
|
43 |
+
|
44 |
== Installation ==
|
45 |
|
46 |
1. Upload the plugin files to the `/wp-content/plugins/webp-express` directory, or install the plugin through the WordPress plugins screen directly.
|
91 |
*Note:*
|
92 |
Do not simply remove the plugin without deactivating it first. Deactivation takes care of removing the rules in the *.htaccess* file. With the rules there, but converter gone, your Google Chrome visitors will not see any jpeg images.
|
93 |
|
|
|
|
|
|
|
94 |
== Limitations ==
|
95 |
|
96 |
+
* The plugin has not been tested by the developer on Microsoft IIS server. [Some however reports that it works](https://wordpress.org/support/topic/iis-and-webp-works/)
|
|
|
97 |
|
98 |
== Supporting WebP Express ==
|
99 |
Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue wasting time on this plugin:
|
154 |
|
155 |
There are two different approaches to achieve the redirections. One based on *rewrite* and one based on *try_files*. As *try_files* performs best, I shall recommend that.
|
156 |
|
157 |
+
For multisite on NGINX, read [here](https://github.com/rosell-dk/webp-express/issues/8)
|
158 |
+
|
159 |
**method 1 (try_files)**
|
160 |
|
161 |
Lets take this step by step.
|
254 |
|
255 |
`
|
256 |
if ($http_accept ~* "webp"){
|
257 |
+
rewrite ^/(.*).(jpe?g|png)$ /wp-content/plugins/webp-express/wod/webp-on-demand.php?xsource=x$request_filename&wp-content=wp-content break;
|
258 |
+
}
|
259 |
}
|
260 |
`
|
261 |
|
331 |
Discussion on this topic [here](https://wordpress.org/support/topic/nginx-rewrite-rules-4/)
|
332 |
And here: https://github.com/rosell-dk/webp-express/issues/166
|
333 |
|
334 |
+
Here are rules if you need to replace the file extension with ".webp" rather than appending ".webp" to it: https://www.keycdn.com/support/optimus/configuration-to-deliver-webp
|
335 |
+
|
336 |
|
337 |
= I am on a WAMP stack =
|
338 |
It has been reported that WebP Express *almost* works on WAMP stack. I'd love to debug this, but do not own a Windows server or access to one... Can you help?
|
448 |
|
449 |
2. You can set up another CDN (on another provider), which you just use for handling the images. You need to configure that CDN to forward the *Accept header*. You also need to install a Wordpress plugin that points images to that CDN.
|
450 |
|
451 |
+
3. You can switch operation mode to "CDN friendly" and use HTML altering.
|
452 |
|
453 |
### WebP Express / ShortPixel setup
|
454 |
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.
|
564 |
|
565 |
I have only tested the above in *Varied image responses* mode, but it should also work in *CDN friendly* mode. Both *Alter HTML* options have been designed to work with standard lazy load attributes.
|
566 |
|
567 |
+
= Can I make an exceptions for some images? =
|
568 |
+
There can be instances where you actually need to serve a jpeg or png. For example if you are demonstrating how a jpeg looks using some compression settings. It is possible to bypass both the redirection and the HTML altering for certain images. Here is how:
|
569 |
+
|
570 |
+
*Alter HTML*
|
571 |
+
Alter HTML is programmed not to substitute image URLs with query strings (better safe than sorry). You can exploit that and simply add ie ?original to the image URLs in question.
|
572 |
+
|
573 |
+
*Redirection*
|
574 |
+
To bypass the *redirection*, you can add the following in the `.htaccess` where *WebP Express* has placed its rules (this is usually in the `wp-content` folder). The rules needs to be added *above* the rules inserted by *WebP Express*.
|
575 |
+
|
576 |
+
`
|
577 |
+
RewriteCond %{QUERY_STRING} original
|
578 |
+
RewriteCond %{REQUEST_FILENAME} -f
|
579 |
+
RewriteRule . - [L]
|
580 |
+
`
|
581 |
+
With those rules in place, you can add "?original" to the URLs of those images that you want to keep serving as jpg / png.
|
582 |
+
|
583 |
+
Alternatively, you can specify the filenames individually in the `.htaccess`:
|
584 |
+
|
585 |
+
`
|
586 |
+
RewriteRule ^uploads/2019/02/example-of-jpg-compressed-to-80\.jpg - [L]
|
587 |
+
RewriteRule ^uploads/2019/02/image2\.jpg - [L]
|
588 |
+
RewriteRule . - [L]
|
589 |
+
`
|
590 |
+
If you got any further questions, look at, or comment on [this topic](https://wordpress.org/support/topic/can-i-make-an-exception-for-specific-post-image/)
|
591 |
+
|
592 |
= When is feature X coming? / Roadmap =
|
593 |
No schedule. I move forward as time allows. I currently spend a lot of time answering questions in the support forum. If someone would be nice and help out answering questions here, it would allow me to spend that time developing. Also, donations would allow me to turn down some of the more boring requests from my customers, and speed things up here.
|
594 |
|
595 |
+
Here are my current plans ahead: 0.13 might be bulk conversion and addition of a diagnose tool – this should release some time spend in the forum. 0.14 could be focused on PNG. 0.15 might be displaying rules for NGINX. 0.16 might be supporting Save-Data header (send extra compressed images to clients who wants to use as little bandwidth as possible). 0.17 might be a file manager-like interface for inspecting generated webp files. 0.18 might be an effort to allow webp for all browsers using [this javascript library](http://libwebpjs.hohenlimburg.org/v0.6.0/). Unfortunately, the javascript librare does not (currently) support srcset attributes, which is why I moved this item down the priority list. We need srcset to be supported for the feature to be useful. 0.19 might be WAMP support. The current milestones, their subtasks and their progress can be viewed here: https://github.com/rosell-dk/webp-express/milestones
|
596 |
|
597 |
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.
|
598 |
|
604 |
1. WebP Express settings
|
605 |
|
606 |
== Changelog ==
|
607 |
+
|
608 |
+
= 0.12.0 =
|
609 |
+
*(released 5 mar 2019)*
|
610 |
+
* Multisite support (!)
|
611 |
+
* A new operation mode: "No conversion", if you do not want to use WebP Express for converting. Replaces the old "Just redirect" mode
|
612 |
+
* Added capability testing of .htaccess. The .htaccess rules are now tailored to the capabilities on the system. For example, on some platforms the filename of a requested image is passed to the converter script through the query string, but on platforms that supports passing it through an environment variable, that method is used instead
|
613 |
+
* Picturefill.js is now optional (alter html, picture tag)
|
614 |
+
* A great bunch more!
|
615 |
+
|
616 |
+
For more info, see the closed issues on the 0.12.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/12?closed=1
|
617 |
+
|
618 |
= 0.11.3 =
|
619 |
+
*(released 18 feb 2019)*
|
620 |
* Fixed bug: Alter HTML caused media library not to display images on some systems. Alter HTML is now disabled in admin mode.
|
621 |
* Alter HTML (picture tags) could produce the source tags with "src" attribute. But source tags inside picture tags must use "srcset" attribute. Fixed.
|
622 |
* Alter HTML (image urls): srcsets containing "x" descriptors wasn't handled (ie, srcset="image.jpg 1x")
|
625 |
* Fixed bug: The code that determined if WebP Express had placed rules in a .htaccess failed in "CDN friendly" mode. The effect was that these rules was not cleaned up upon plugin deactivation
|
626 |
|
627 |
= 0.11.2 =
|
628 |
+
*(released 14 feb 2019)*
|
629 |
* Fixed bug which caused Alter HTML to fail miserably on some setups
|
630 |
* AlterHTML now also looks for lazy load attributes in DIV and LI tags.
|
631 |
|
632 |
= 0.11.1 =
|
633 |
+
*(released 6 feb 2019)*
|
634 |
* Fixed bug which caused the new "Convert non-existing webp-files upon request" not to work on all setups
|
635 |
|
636 |
= 0.11.0 =
|
637 |
+
*(released 6 feb 2019)*
|
638 |
* Alter HTML to point to webp files (choose between picture tags or simply altering all image urls)
|
639 |
* Convert non-existing webp-files upon request (means you can reference the converted webp files before they are actually converted!)
|
640 |
|
641 |
For more info, see the closed issues on the 0.11.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/14?closed=1
|
642 |
|
643 |
= 0.10.0 =
|
644 |
+
*(released 7 jan 2019)*
|
645 |
* Introduced "Operation modes" in order to keep setting screens simple but still allow tweaking
|
646 |
* WebP Express can now be used in conjunction with Cache Enabler and ShortPixel
|
647 |
* Cache-Control header is now added in *.htaccess*, when redirecting directly to existing webp
|
661 |
For more info, see the closed issues on the 0.9.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.9.0
|
662 |
|
663 |
= 0.8.1 =
|
664 |
+
*(released 11 dec 2018)*
|
665 |
* Fixed javascript bug
|
666 |
|
667 |
= 0.8.0 =
|
668 |
+
*(released 11 dec 2018)*
|
669 |
* New conversion method, which calls imagick binary directly. This will make WebP express work out of the box on more systems
|
670 |
* Made sure not to trigger LFI warning i Wordfence (to activate, click the force .htaccess button)
|
671 |
* Imagick can now be configured to set quality to auto on systems where the auto option isn't generally available
|
676 |
For more info, see the closed issues on the 0.8.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0
|
677 |
|
678 |
= 0.7.2 =
|
679 |
+
*(released 21 nov 2018)*
|
680 |
Fixed a critical bug which generated an error message which caused corrupt images. It was not the bug itself, but the error message it generated, that caused the images to be corrupted. It only happened when debugging was enabled in php.ini
|
681 |
|
682 |
= 0.7.1 =
|
683 |
+
*(released 9 nov 2018)*
|
684 |
Fixed minor "bug". The Api version combobox in Remote WebP Express converter was showing on new sites, but I only want it to show when old api is being used.
|
685 |
|
686 |
= 0.7.0 =
|
687 |
+
*(released 9 nov 2018)*
|
688 |
This version added option to provide conversion service to other sites!
|
689 |
|
690 |
For more info, see the closed issues on the 0.7.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.7.0
|
691 |
|
692 |
= 0.6.0 =
|
693 |
+
*(released 4 okt 2018)*
|
694 |
This version added option for setting caching header, fixed a serious issue with *Imagick*, added a new converter, *Gmagick*, added a great deal of options to *Cwebp* and generally improved the interface.
|
695 |
|
696 |
* Added option for caching
|
708 |
For more info, see the closed issues on the 0.6.0 milestone on our github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.6.0
|
709 |
|
710 |
= 0.5.0 =
|
711 |
+
*(released 14 sep 2018)*
|
712 |
This version works on many more setups than the previous. Also uses less resources and handles when images are changed.
|
713 |
|
714 |
* Configuration is now stored in a separate configuration file instead of storing directly in the *.htaccess* file and passing it on via query string. When updating, these settings are migrated automatically.
|
735 |
|
736 |
== Upgrade Notice ==
|
737 |
|
738 |
+
= 0.12.0 =
|
739 |
+
Multisite support and a new operation mode
|
740 |
+
|
741 |
= 0.11.3 =
|
742 |
Fixed several bugs. You should update :)
|
743 |
|
@@ -1,4 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
= 0.11.3 =
|
|
|
2 |
* Fixed bug: Alter HTML caused media library not to display images on some systems. Alter HTML is now disabled in admin mode.
|
3 |
* Alter HTML (picture tags) could produce the source tags with "src" attribute. But source tags inside picture tags must use "srcset" attribute. Fixed.
|
4 |
* Alter HTML (image urls): srcsets containing "x" descriptors wasn't handled (ie, srcset="image.jpg 1x")
|
@@ -7,19 +18,23 @@
|
|
7 |
* Fixed bug: The code that determined if WebP Express had placed rules in a .htaccess failed in "CDN friendly" mode. The effect was that these rules was not cleaned up upon plugin deactivation
|
8 |
|
9 |
= 0.11.2 =
|
|
|
10 |
* Fixed bug which caused Alter HTML to fail miserably on some setups
|
11 |
* AlterHTML now also looks for lazy load attributes in DIV and LI tags.
|
12 |
|
13 |
= 0.11.1 =
|
|
|
14 |
* Fixed bug which caused the new "Convert non-existing webp-files upon request" not to work on all setups
|
15 |
|
16 |
= 0.11.0 =
|
|
|
17 |
* Alter HTML to point to webp files (choose between picture tags or simply altering all image urls)
|
18 |
* Convert non-existing webp-files upon request (means you can reference the converted webp files before they are actually converted!)
|
19 |
|
20 |
For more info, see the closed issues on the 0.11.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/14?closed=1
|
21 |
|
22 |
= 0.10.0 =
|
|
|
23 |
* Introduced "Operation modes" in order to keep setting screens simple but still allow tweaking
|
24 |
* WebP Express can now be used in conjunction with Cache Enabler and ShortPixel
|
25 |
* Cache-Control header is now added in *.htaccess*, when redirecting directly to existing webp
|
@@ -54,17 +69,21 @@ For more info, see the closed issues on the 0.9.0 milestone on the github reposi
|
|
54 |
For more info, see the closed issues on the 0.8.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0
|
55 |
|
56 |
= 0.7.2 =
|
|
|
57 |
Fixed a critical bug which generated an error message which caused corrupt images. It was not the bug itself, but the error message it generated, that caused the images to be corrupted. It only happened when debugging was enabled in php.ini
|
58 |
|
59 |
= 0.7.1 =
|
|
|
60 |
Fixed minor "bug". The Api version combobox in Remote WebP Express converter was showing on new sites, but I only want it to show when old api is being used.
|
61 |
|
62 |
= 0.7.0 =
|
|
|
63 |
This version added option to provide conversion service to other sites!
|
64 |
|
65 |
For more info, see the closed issues on the 0.7.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.7.0
|
66 |
|
67 |
= 0.6.0 =
|
|
|
68 |
This version added option for setting caching header, fixed a serious issue with *Imagick*, added a new converter, *Gmagick*, added a great deal of options to *Cwebp* and generally improved the interface.
|
69 |
|
70 |
* Added option for caching
|
1 |
+
= 0.12.0 =
|
2 |
+
*(released 5 mar 2019)*
|
3 |
+
* Multisite support (!)
|
4 |
+
* A new operation mode: "No conversion", if you do not want to use WebP Express for converting. Replaces the old "Just redirect" mode
|
5 |
+
* Added capability testing of .htaccess. The .htaccess rules are now tailored to the capabilities on the system. For example, on some platforms the filename of a requested image is passed to the converter script through the query string, but on platforms that supports passing it through an environment variable, that method is used instead
|
6 |
+
* Picturefill.js is now optional (alter html, picture tag)
|
7 |
+
* A great bunch more!
|
8 |
+
|
9 |
+
For more info, see the closed issues on the 0.12.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/12?closed=1
|
10 |
+
|
11 |
= 0.11.3 =
|
12 |
+
*(released 18 feb 2019)*
|
13 |
* Fixed bug: Alter HTML caused media library not to display images on some systems. Alter HTML is now disabled in admin mode.
|
14 |
* Alter HTML (picture tags) could produce the source tags with "src" attribute. But source tags inside picture tags must use "srcset" attribute. Fixed.
|
15 |
* Alter HTML (image urls): srcsets containing "x" descriptors wasn't handled (ie, srcset="image.jpg 1x")
|
18 |
* Fixed bug: The code that determined if WebP Express had placed rules in a .htaccess failed in "CDN friendly" mode. The effect was that these rules was not cleaned up upon plugin deactivation
|
19 |
|
20 |
= 0.11.2 =
|
21 |
+
*(released 14 feb 2019)*
|
22 |
* Fixed bug which caused Alter HTML to fail miserably on some setups
|
23 |
* AlterHTML now also looks for lazy load attributes in DIV and LI tags.
|
24 |
|
25 |
= 0.11.1 =
|
26 |
+
*(released 6 feb 2019)*
|
27 |
* Fixed bug which caused the new "Convert non-existing webp-files upon request" not to work on all setups
|
28 |
|
29 |
= 0.11.0 =
|
30 |
+
*(released 6 feb 2019)*
|
31 |
* Alter HTML to point to webp files (choose between picture tags or simply altering all image urls)
|
32 |
* Convert non-existing webp-files upon request (means you can reference the converted webp files before they are actually converted!)
|
33 |
|
34 |
For more info, see the closed issues on the 0.11.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/14?closed=1
|
35 |
|
36 |
= 0.10.0 =
|
37 |
+
*(released 7 jan 2019)*
|
38 |
* Introduced "Operation modes" in order to keep setting screens simple but still allow tweaking
|
39 |
* WebP Express can now be used in conjunction with Cache Enabler and ShortPixel
|
40 |
* Cache-Control header is now added in *.htaccess*, when redirecting directly to existing webp
|
69 |
For more info, see the closed issues on the 0.8.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.8.0
|
70 |
|
71 |
= 0.7.2 =
|
72 |
+
*(released 21 nov 2018)*
|
73 |
Fixed a critical bug which generated an error message which caused corrupt images. It was not the bug itself, but the error message it generated, that caused the images to be corrupted. It only happened when debugging was enabled in php.ini
|
74 |
|
75 |
= 0.7.1 =
|
76 |
+
*(released 9 nov 2018)*
|
77 |
Fixed minor "bug". The Api version combobox in Remote WebP Express converter was showing on new sites, but I only want it to show when old api is being used.
|
78 |
|
79 |
= 0.7.0 =
|
80 |
+
*(released 9 nov 2018)*
|
81 |
This version added option to provide conversion service to other sites!
|
82 |
|
83 |
For more info, see the closed issues on the 0.7.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/issues?q=is%3Aclosed+milestone%3A0.7.0
|
84 |
|
85 |
= 0.6.0 =
|
86 |
+
*(released 4 okt 2018)*
|
87 |
This version added option for setting caching header, fixed a serious issue with *Imagick*, added a new converter, *Gmagick*, added a great deal of options to *Cwebp* and generally improved the interface.
|
88 |
|
89 |
* Added option for caching
|
@@ -1,3 +1,3 @@
|
|
1 |
The plugin published on github now uses composer. I still include the vendor files on the svn (the Wordpress "codex").
|
2 |
|
3 |
-
For the few, who might be using this thing here on github: To get the dependent libraries, you need to cd into the plugin dir and run `composer
|
1 |
The plugin published on github now uses composer. I still include the vendor files on the svn (the Wordpress "codex").
|
2 |
|
3 |
+
For the few, who might be using this thing here on github: To get the dependent libraries, you need to cd into the plugin dir and run `composer install`. This gets you the latest dev releases of "webp-convert" and "webp-convert-cloud-service" on github. You must change the composer.json if you rather want the latest stable release (remove the repositories and change the minimum requirements). On the svn, I simply rsync everything, including the vendor folder, before committing.
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<IfModule mod_rewrite.c>
|
2 |
+
#RewriteEngine on
|
3 |
+
#RewriteCond %{REQUEST_URI} !request-uri-usable
|
4 |
+
#RewriteRule ^(.*)$ request-uri-usable/$1
|
5 |
+
|
6 |
+
</IfModule>
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<IfModule mod_headers.c>
|
2 |
+
RequestHeader set HEADERFORTEST "test"
|
3 |
+
</IfModule>
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
//echo '<pre>'. print_r($_SERVER, 1) . '</pre>';
|
4 |
+
|
5 |
+
if (isset($_SERVER['HTTP_HEADERFORTEST'])) {
|
6 |
+
echo ($_SERVER['HTTP_HEADERFORTEST'] == 'test' ? 1 : 0);
|
7 |
+
exit;
|
8 |
+
}
|
9 |
+
echo '0';
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<IfModule mod_rewrite.c>
|
2 |
+
|
3 |
+
# Testing for mod_rewrite
|
4 |
+
# -----------------------
|
5 |
+
# If mod_rewrite is enabled, redirect to 1.php, which returns "1".
|
6 |
+
# If mod_rewrite is disabled, the rewriting fails, and we end at test.php, which always returns 0.
|
7 |
+
|
8 |
+
RewriteEngine On
|
9 |
+
RewriteRule ^test\.php$ 1.php [L]
|
10 |
+
|
11 |
+
</IfModule>
|
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
echo '1';
|
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
echo '0';
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
|
4 |
+
<IfModule mod_rewrite.c>
|
5 |
+
RewriteEngine On
|
6 |
+
|
7 |
+
# PASSTHROUGHHEADERing if we can pass environment variable through request header
|
8 |
+
# We pass document root, because that can easily be checked by the script
|
9 |
+
|
10 |
+
<IfModule mod_headers.c>
|
11 |
+
RequestHeader set PASSTHROUGHHEADER "%{PASSTHROUGHHEADER}e" env=PASSTHROUGHHEADER
|
12 |
+
</IfModule>
|
13 |
+
RewriteRule ^test\.php$ - [E=PASSTHROUGHHEADER:%{DOCUMENT_ROOT},L]
|
14 |
+
|
15 |
+
</IfModule>
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
//echo '<pre>'. print_r($_SERVER, 1) . '</pre>';
|
4 |
+
|
5 |
+
if (isset($_SERVER['HTTP_PASSTHROUGHHEADER'])) {
|
6 |
+
echo ($_SERVER['HTTP_PASSTHROUGHHEADER'] == $_SERVER['DOCUMENT_ROOT'] ? 1 : 0);
|
7 |
+
exit;
|
8 |
+
}
|
9 |
+
echo '0';
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
|
4 |
+
|
5 |
+
<IfModule mod_rewrite.c>
|
6 |
+
|
7 |
+
# Testing if we can pass environment variable from .htaccess to script in a RewriteRule
|
8 |
+
# We pass document root, because that can easily be checked by the script
|
9 |
+
|
10 |
+
RewriteEngine On
|
11 |
+
RewriteRule ^test\.php$ - [E=PASSTHROUGHENV:%{DOCUMENT_ROOT},L]
|
12 |
+
|
13 |
+
</IfModule>
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Get environment variable set with mod_rewrite module
|
5 |
+
* Return false if the environment variable isn't found
|
6 |
+
*/
|
7 |
+
function getEnvPassedInRewriteRule($envName) {
|
8 |
+
// Envirenment variables passed through the REWRITE module have "REWRITE_" as a prefix (in Apache, not Litespeed, if I recall correctly)
|
9 |
+
// Multiple iterations causes multiple REWRITE_ prefixes, and we get many environment variables set.
|
10 |
+
// We simply look for an environment variable that ends with what we are looking for.
|
11 |
+
// (so make sure to make it unique)
|
12 |
+
$len = strlen($envName);
|
13 |
+
foreach ($_SERVER as $key => $item) {
|
14 |
+
if (substr($key, -$len) == $envName) {
|
15 |
+
return $item;
|
16 |
+
}
|
17 |
+
}
|
18 |
+
return false;
|
19 |
+
}
|
20 |
+
|
21 |
+
|
22 |
+
$result = getEnvPassedInRewriteRule('PASSTHROUGHENV');
|
23 |
+
if ($result === false) {
|
24 |
+
echo '0';
|
25 |
+
exit;
|
26 |
+
}
|
27 |
+
echo ($result == $_SERVER['DOCUMENT_ROOT'] ? '1' : '0');
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<IfModule mod_rewrite.c>
|
2 |
+
|
3 |
+
# Testing for mod_rewrite
|
4 |
+
# -----------------------
|
5 |
+
# If mod_rewrite is enabled, redirect to 1.php, which returns "1".
|
6 |
+
# If mod_rewrite is disabled, the rewriting fails, and we end at test.php, which always returns 0.
|
7 |
+
|
8 |
+
RewriteEngine On
|
9 |
+
RewriteRule ^test\.php$ test2.php [L]
|
10 |
+
|
11 |
+
</IfModule>
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
echo '0';
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
//echo '<pre>'. print_r($_SERVER, 1) . '</pre>';
|
4 |
+
|
5 |
+
/*
|
6 |
+
Something like this is fine
|
7 |
+
[REQUEST_URI] => /wp-content/webp-express/capability-tests/request-uri-usable/test.php
|
8 |
+
[SCRIPT_NAME] => /wp-content/webp-express/capability-tests/request-uri-usable/test2.php
|
9 |
+
|
10 |
+
But this is indication of failure:
|
11 |
+
[REQUEST_URI] => /wp-content/webp-express/capability-tests/request-uri-usable/test.php
|
12 |
+
[SCRIPT_NAME] => /my_subdir/wp-content/webp-express/capability-tests/request-uri-usable/test2.php
|
13 |
+
*/
|
14 |
+
|
15 |
+
function stripFilename($dirName) {
|
16 |
+
//echo 'dir:' . $dirName . '<br>';
|
17 |
+
//echo 'pos: ' . strrpos($dirName, '/') . '<br>';
|
18 |
+
return substr($dirName, 0, strrpos($dirName, '/'));
|
19 |
+
|
20 |
+
}
|
21 |
+
//echo stripFilename($_SERVER['REQUEST_URI']) . '<br>';
|
22 |
+
//echo stripFilename($_SERVER['SCRIPT_NAME']) . '<br>';
|
23 |
+
|
24 |
+
$equalDirs = (stripFilename($_SERVER['REQUEST_URI']) == stripFilename($_SERVER['SCRIPT_NAME']));
|
25 |
+
|
26 |
+
echo $equalDirs ? '1' : '0';
|
27 |
+
|
28 |
+
|
29 |
+
//echo preg_match('#$#')
|
30 |
+
|
31 |
+
//$_SERVER['REQUEST_URI'];
|
32 |
+
//$_SERVER['SCRIPT_NAME'];
|
33 |
+
|
34 |
+
|
35 |
+
/*
|
36 |
+
function getEnvPassedInRewriteRule($envName) {
|
37 |
+
// Envirenment variables passed through the REWRITE module have "REWRITE_" as a prefix (in Apache, not Litespeed)
|
38 |
+
// Multiple iterations causes multiple REWRITE_ prefixes, and we get many environment variables set.
|
39 |
+
// We simply look for an environment variable that ends with what we are looking for.
|
40 |
+
// (so make sure to make it unique)
|
41 |
+
$len = strlen($envName);
|
42 |
+
foreach ($_SERVER as $key => $item) {
|
43 |
+
if (substr($key, -$len) == $envName) {
|
44 |
+
return $item;
|
45 |
+
}
|
46 |
+
}
|
47 |
+
return false;
|
48 |
+
}
|
49 |
+
|
50 |
+
//$result = getEnvPassedInRewriteRule('PASSTHROUGHENV');
|
51 |
+
*/
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
We 0:
|
2 |
+
|
3 |
+
http://we0/wp-content-moved/webp-express/capability-tests/has-mod-rewrite/test.php
|
4 |
+
http://we0/wp-content-moved/webp-express/capability-tests/pass-through-environment-var/test.php
|
5 |
+
http://we0/wp-content-moved/webp-express/capability-tests/pass-server-var-through-header/test.php
|
6 |
+
http://we0/wp-content-moved/webp-express/capability-tests/request-uri-usable/test.php
|
7 |
+
|
8 |
+
|
9 |
+
|
10 |
+
We 7:
|
11 |
+
------
|
12 |
+
http://we7/wp-content/webp-express/capability-tests/request-uri-usable/test.php
|
@@ -3,6 +3,9 @@
|
|
3 |
include_once __DIR__ . '/classes/Actions.php';
|
4 |
use \WebPExpress\Actions;
|
5 |
|
|
|
|
|
|
|
6 |
include_once __DIR__ . '/classes/Config.php';
|
7 |
use \WebPExpress\Config;
|
8 |
|
@@ -18,31 +21,31 @@ use \WebPExpress\PlatformInfo;
|
|
18 |
include_once __DIR__ . '/classes/State.php';
|
19 |
use \WebPExpress\State;
|
20 |
|
|
|
21 |
// First check basic requirements.
|
22 |
// -------------------------------
|
23 |
|
24 |
if (PlatformInfo::isMicrosoftIis()) {
|
25 |
-
Messenger::addMessage(
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
return;
|
30 |
}
|
31 |
|
32 |
|
33 |
if ( is_multisite() ) {
|
34 |
-
Messenger::addMessage(
|
35 |
-
|
36 |
-
|
|
|
|
|
37 |
}
|
38 |
|
39 |
if (!version_compare(PHP_VERSION, '5.5.0', '>=')) {
|
40 |
-
//$msg = sprintf(__( 'You are on a very old version of PHP (%s). WebP Express may not work as intended.', 'webp-express' ), phpversion());
|
41 |
Messenger::addMessage(
|
42 |
'warning',
|
43 |
'You are on a very old version of PHP. WebP Express may not work correctly. Your PHP version:' . phpversion()
|
44 |
);
|
45 |
-
return;
|
46 |
}
|
47 |
|
48 |
// Next issue warnings, if any
|
@@ -66,3 +69,6 @@ Messenger::addMessage(
|
|
66 |
'WebP Express was installed successfully. To start using it, you must ' .
|
67 |
'<a href="' . Paths::getSettingsUrl() . '">configure it here</a>.'
|
68 |
);
|
|
|
|
|
|
3 |
include_once __DIR__ . '/classes/Actions.php';
|
4 |
use \WebPExpress\Actions;
|
5 |
|
6 |
+
include_once __DIR__ . '/classes/CapabilityTest.php';
|
7 |
+
use \WebPExpress\CapabilityTest;
|
8 |
+
|
9 |
include_once __DIR__ . '/classes/Config.php';
|
10 |
use \WebPExpress\Config;
|
11 |
|
21 |
include_once __DIR__ . '/classes/State.php';
|
22 |
use \WebPExpress\State;
|
23 |
|
24 |
+
|
25 |
// First check basic requirements.
|
26 |
// -------------------------------
|
27 |
|
28 |
if (PlatformInfo::isMicrosoftIis()) {
|
29 |
+
Messenger::addMessage(
|
30 |
+
'warning',
|
31 |
+
'You are on Microsoft IIS server. The developer of WebP Express has no money for Microsoft products, so no testing have been done on IIS. Use at own risk. If you are on WAMP, things might work. Without Apache, you will need to create redirect rules yourself.'
|
32 |
+
);
|
|
|
33 |
}
|
34 |
|
35 |
|
36 |
if ( is_multisite() ) {
|
37 |
+
Messenger::addMessage(
|
38 |
+
'warning',
|
39 |
+
'Multisite functionality in WebP Express has just been added with current release (0.12.0). ' .
|
40 |
+
'While it has been tested on several setups, there might be a bug or two yet to be found.'
|
41 |
+
);
|
42 |
}
|
43 |
|
44 |
if (!version_compare(PHP_VERSION, '5.5.0', '>=')) {
|
|
|
45 |
Messenger::addMessage(
|
46 |
'warning',
|
47 |
'You are on a very old version of PHP. WebP Express may not work correctly. Your PHP version:' . phpversion()
|
48 |
);
|
|
|
49 |
}
|
50 |
|
51 |
// Next issue warnings, if any
|
69 |
'WebP Express was installed successfully. To start using it, you must ' .
|
70 |
'<a href="' . Paths::getSettingsUrl() . '">configure it here</a>.'
|
71 |
);
|
72 |
+
|
73 |
+
// While not neccessary, lets get those tests copied right away. Some servers are a bit slow to pick up on changes in the filesystem
|
74 |
+
CapabilityTest::copyCapabilityTestsToWpContent();
|
@@ -1,23 +1,26 @@
|
|
1 |
<?php
|
2 |
use \WebPExpress\State;
|
|
|
|
|
3 |
|
4 |
// When an update requires a migration, the number should be increased
|
5 |
-
define('WEBPEXPRESS_MIGRATION_VERSION', '
|
6 |
|
7 |
-
if (WEBPEXPRESS_MIGRATION_VERSION !=
|
8 |
// run migration logic
|
9 |
include __DIR__ . '/migrate/migrate.php';
|
10 |
}
|
11 |
|
12 |
// uncomment next line to test-run a migration
|
13 |
-
//
|
14 |
|
15 |
// uncomment next line to debug an error during activation
|
16 |
//include __DIR__ . "/debug.php";
|
17 |
|
18 |
include __DIR__ . '/options/options-hooks.php';
|
19 |
|
20 |
-
register_activation_hook(WEBPEXPRESS_PLUGIN, function () {
|
|
|
21 |
include __DIR__ . '/activate-hook.php';
|
22 |
});
|
23 |
|
@@ -25,13 +28,14 @@ register_deactivation_hook(WEBPEXPRESS_PLUGIN, function () {
|
|
25 |
include __DIR__ . '/deactivate.php';
|
26 |
});
|
27 |
|
28 |
-
if (
|
29 |
include_once __DIR__ . '/classes/Messenger.php';
|
30 |
-
|
|
|
31 |
\WebPExpress\Messenger::printPendingMessages();
|
32 |
});
|
33 |
}
|
34 |
-
if (
|
35 |
include_once __DIR__ . '/classes/Actions.php';
|
36 |
\WebPExpress\Actions::processQueuedActions();
|
37 |
}
|
@@ -46,9 +50,24 @@ register_uninstall_hook(WEBPEXPRESS_PLUGIN, 'webp_express_uninstall');
|
|
46 |
|
47 |
// Add settings link on the plugins page
|
48 |
add_filter('plugin_action_links_' . plugin_basename(WEBPEXPRESS_PLUGIN), function ( $links ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
$mylinks = array(
|
50 |
-
'<a href="' .
|
51 |
-
'<a href="https://ko-fi.com/rosell" target="_blank">
|
52 |
);
|
53 |
return array_merge($links, $mylinks);
|
54 |
});
|
1 |
<?php
|
2 |
use \WebPExpress\State;
|
3 |
+
use \WebPExpress\Option;
|
4 |
+
use \WebPExpress\Multisite;
|
5 |
|
6 |
// When an update requires a migration, the number should be increased
|
7 |
+
define('WEBPEXPRESS_MIGRATION_VERSION', '7');
|
8 |
|
9 |
+
if (WEBPEXPRESS_MIGRATION_VERSION != Option::getOption('webp-express-migration-version', 0)) {
|
10 |
// run migration logic
|
11 |
include __DIR__ . '/migrate/migrate.php';
|
12 |
}
|
13 |
|
14 |
// uncomment next line to test-run a migration
|
15 |
+
//include __DIR__ . '/migrate/migrate7.php';
|
16 |
|
17 |
// uncomment next line to debug an error during activation
|
18 |
//include __DIR__ . "/debug.php";
|
19 |
|
20 |
include __DIR__ . '/options/options-hooks.php';
|
21 |
|
22 |
+
register_activation_hook(WEBPEXPRESS_PLUGIN, function ($network_active) {
|
23 |
+
Multisite::overrideIsNetworkActivated($network_active);
|
24 |
include __DIR__ . '/activate-hook.php';
|
25 |
});
|
26 |
|
28 |
include __DIR__ . '/deactivate.php';
|
29 |
});
|
30 |
|
31 |
+
if (Option::getOption('webp-express-messages-pending')) {
|
32 |
include_once __DIR__ . '/classes/Messenger.php';
|
33 |
+
|
34 |
+
add_action(Multisite::isNetworkActivated() ? 'network_admin_notices' : 'admin_notices', function() {
|
35 |
\WebPExpress\Messenger::printPendingMessages();
|
36 |
});
|
37 |
}
|
38 |
+
if (Option::getOption('webp-express-actions-pending')) {
|
39 |
include_once __DIR__ . '/classes/Actions.php';
|
40 |
\WebPExpress\Actions::processQueuedActions();
|
41 |
}
|
50 |
|
51 |
// Add settings link on the plugins page
|
52 |
add_filter('plugin_action_links_' . plugin_basename(WEBPEXPRESS_PLUGIN), function ( $links ) {
|
53 |
+
if (Multisite::isNetworkActivated()) {
|
54 |
+
$mylinks= [
|
55 |
+
'<a href="https://ko-fi.com/rosell" target="_blank">donate?</a>',
|
56 |
+
];
|
57 |
+
} else {
|
58 |
+
$mylinks = array(
|
59 |
+
'<a href="' . admin_url('options-general.php?page=webp_express_settings_page') . '">Settings</a>',
|
60 |
+
'<a href="https://ko-fi.com/rosell" target="_blank">Provide coffee for the developer</a>',
|
61 |
+
);
|
62 |
+
|
63 |
+
}
|
64 |
+
return array_merge($links, $mylinks);
|
65 |
+
});
|
66 |
+
|
67 |
+
add_filter('network_admin_plugin_action_links_' . plugin_basename(WEBPEXPRESS_PLUGIN), function ( $links ) {
|
68 |
$mylinks = array(
|
69 |
+
'<a href="' . network_admin_url('settings.php?page=webp_express_settings_page') . '">Settings</a>',
|
70 |
+
'<a href="https://ko-fi.com/rosell" target="_blank">donate?</a>',
|
71 |
);
|
72 |
return array_merge($links, $mylinks);
|
73 |
});
|
@@ -5,6 +5,8 @@ namespace WebPExpress;
|
|
5 |
include_once "State.php";
|
6 |
use \WebPExpress\State;
|
7 |
|
|
|
|
|
8 |
/**
|
9 |
*
|
10 |
*/
|
@@ -15,7 +17,7 @@ class Actions
|
|
15 |
* $action: identifier
|
16 |
*/
|
17 |
public static function procastinate($action) {
|
18 |
-
|
19 |
|
20 |
$pendingActions = State::getState('pendingActions', []);
|
21 |
$pendingActions[] = $action;
|
@@ -40,7 +42,7 @@ class Actions
|
|
40 |
}
|
41 |
|
42 |
State::setState('pendingActions', []);
|
43 |
-
|
44 |
|
45 |
}
|
46 |
}
|
5 |
include_once "State.php";
|
6 |
use \WebPExpress\State;
|
7 |
|
8 |
+
use \WebPExpress\Option;
|
9 |
+
|
10 |
/**
|
11 |
*
|
12 |
*/
|
17 |
* $action: identifier
|
18 |
*/
|
19 |
public static function procastinate($action) {
|
20 |
+
Option::updateOption('webp-express-actions-pending', true, true);
|
21 |
|
22 |
$pendingActions = State::getState('pendingActions', []);
|
23 |
$pendingActions[] = $action;
|
42 |
}
|
43 |
|
44 |
State::setState('pendingActions', []);
|
45 |
+
Option::updateOption('webp-express-actions-pending', false, true);
|
46 |
|
47 |
}
|
48 |
}
|
@@ -10,6 +10,10 @@ use \WebPExpress\Paths;
|
|
10 |
include_once "PathHelper.php";
|
11 |
use \WebPExpress\PathHelper;
|
12 |
|
|
|
|
|
|
|
|
|
13 |
class AlterHtmlHelper
|
14 |
{
|
15 |
|
@@ -144,6 +148,7 @@ class AlterHtmlHelper
|
|
144 |
*/
|
145 |
private static function getWebPUrlInBase($sourceUrl, $baseUrl, $baseDir)
|
146 |
{
|
|
|
147 |
|
148 |
$srcPathRel = self::getRelUrlPath($sourceUrl, $baseUrl);
|
149 |
|
@@ -205,7 +210,7 @@ class AlterHtmlHelper
|
|
205 |
public static function getWebPUrl($sourceUrl, $returnValueOnFail)
|
206 |
{
|
207 |
if (!isset(self::$options)) {
|
208 |
-
self::$options = json_decode(
|
209 |
}
|
210 |
|
211 |
|
@@ -239,6 +244,10 @@ class AlterHtmlHelper
|
|
239 |
}
|
240 |
|
241 |
foreach (self::$options['bases'] as $id => list($baseDir, $baseUrl)) {
|
|
|
|
|
|
|
|
|
242 |
|
243 |
$result = self::getWebPUrlInBase($sourceUrl, $baseUrl, $baseDir);
|
244 |
if ($result !== false) {
|
10 |
include_once "PathHelper.php";
|
11 |
use \WebPExpress\PathHelper;
|
12 |
|
13 |
+
use \WebPExpress\Multisite;
|
14 |
+
|
15 |
+
use \WebPExpress\Option;
|
16 |
+
|
17 |
class AlterHtmlHelper
|
18 |
{
|
19 |
|
148 |
*/
|
149 |
private static function getWebPUrlInBase($sourceUrl, $baseUrl, $baseDir)
|
150 |
{
|
151 |
+
//error_log('getWebPUrlInBase:' . $sourceUrl . ':' . $baseUrl . ':' . $baseDir);
|
152 |
|
153 |
$srcPathRel = self::getRelUrlPath($sourceUrl, $baseUrl);
|
154 |
|
210 |
public static function getWebPUrl($sourceUrl, $returnValueOnFail)
|
211 |
{
|
212 |
if (!isset(self::$options)) {
|
213 |
+
self::$options = json_decode(Option::getOption('webp-express-alter-html-options', null), true);
|
214 |
}
|
215 |
|
216 |
|
244 |
}
|
245 |
|
246 |
foreach (self::$options['bases'] as $id => list($baseDir, $baseUrl)) {
|
247 |
+
if (Multisite::isMultisite() && ($id == 'uploads')) {
|
248 |
+
$baseUrl = Paths::getUploadUrl();
|
249 |
+
$baseDir = Paths::getUploadDirAbs();
|
250 |
+
}
|
251 |
|
252 |
$result = self::getWebPUrlInBase($sourceUrl, $baseUrl, $baseDir);
|
253 |
if ($result !== false) {
|
@@ -32,52 +32,4 @@ class AlterHtmlImageUrls extends ImageUrlReplacer
|
|
32 |
//return preg_match('#^(src|srcset|data-(src|srcset|cvpsrc|cvpset|thumb|bg-url|large_image|lazyload|source-url|srcsmall|srclarge|srcfull|slide-img|lazy-original))$#i', $attrName);
|
33 |
}
|
34 |
|
35 |
-
/*
|
36 |
-
public static function alter($content) {
|
37 |
-
require_once "AlterHtmlHelper.php";
|
38 |
-
|
39 |
-
|
40 |
-
//Find image urls in HTML attributes.
|
41 |
-
//- Ignore URLs with query string
|
42 |
-
//- Matches src, src-set and data-attributes in a limited set of tags
|
43 |
-
//- Only jpeg, jpg or png (NO GIFs)
|
44 |
-
//- Both relative and absolute URLs are matched
|
45 |
-
//- tag name is returned in $1, url in $&
|
46 |
-
|
47 |
-
//Pattern for attributes can be tested here: https://regexr.com/46jat
|
48 |
-
//PS: Based on regex found in Cache Enabler 1.3.2: https://regexr.com/46isf
|
49 |
-
|
50 |
-
//TODO: Dont match PNG, unless choosen
|
51 |
-
$regex_rule = '#(?<=(?:<(img|source|input|iframe)[^>]*\s+(src|srcset|data-[^=]*)\s*=\s*[\"\']?))(?:[^\"\'>]+)(\.png|\.jp[e]?g)(\s\d+w)?(?=\/?[\"\'\s\>])#';
|
52 |
-
return preg_replace_callback($regex_rule, 'self::replaceCallback', $content);
|
53 |
-
|
54 |
-
// TODO: css too. I already got the regex ready: https://regexr.com/46jcg
|
55 |
-
|
56 |
-
|
57 |
-
}
|
58 |
-
|
59 |
-
/*
|
60 |
-
private static function replaceCallback($match) {
|
61 |
-
list($attrValue, $attrName) = $match;
|
62 |
-
|
63 |
-
// A data attribute contain a srcset or single url.
|
64 |
-
// We should probably examine the attrValue further. For now, we however just use the attrName as a clue.
|
65 |
-
// If it contains "set", we handle it as a srcset. This takes care of both "data-cvpset" and "srcset"
|
66 |
-
if (strpos($attrName, 'set') > 0) {
|
67 |
-
$srcsetArr = explode(',', $attrValue);
|
68 |
-
foreach ($srcsetArr as $i => $srcSetEntry) {
|
69 |
-
// $srcSetEntry is ie "http://example.com/image.jpg 520w"
|
70 |
-
list($src, $width) = preg_split('/\s+/', trim($srcSetEntry)); // $width might not be set, but thats ok.
|
71 |
-
|
72 |
-
$webpUrl = \WebPExpress\AlterHtmlHelper::getWebPUrl($src, false);
|
73 |
-
if ($webpUrl !== false) {
|
74 |
-
$srcsetArr[$i] = $webpUrl . (isset($width) ? ' ' . $width : '');
|
75 |
-
}
|
76 |
-
}
|
77 |
-
return implode(', ', $srcsetArr);
|
78 |
-
} else {
|
79 |
-
return \WebPExpress\AlterHtmlHelper::getWebPUrl($attrValue, $attrValue);
|
80 |
-
}
|
81 |
-
}*/
|
82 |
-
|
83 |
}
|
32 |
//return preg_match('#^(src|srcset|data-(src|srcset|cvpsrc|cvpset|thumb|bg-url|large_image|lazyload|source-url|srcsmall|srclarge|srcfull|slide-img|lazy-original))$#i', $attrName);
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
}
|
@@ -5,6 +5,8 @@ namespace WebPExpress;
|
|
5 |
include_once "AlterHtmlHelper.php";
|
6 |
use AlterHtmlHelper;
|
7 |
|
|
|
|
|
8 |
class AlterHtmlInit
|
9 |
{
|
10 |
public static $options = null;
|
@@ -27,7 +29,7 @@ class AlterHtmlInit
|
|
27 |
return $content;
|
28 |
}
|
29 |
|
30 |
-
if (
|
31 |
if(function_exists('is_amp_endpoint') && is_amp_endpoint()) {
|
32 |
//for AMP pages the <picture> tag is not allowed
|
33 |
return $content;
|
@@ -35,7 +37,7 @@ class AlterHtmlInit
|
|
35 |
}
|
36 |
|
37 |
if (!isset(self::$options)) {
|
38 |
-
self::$options = json_decode(
|
39 |
//AlterHtmlHelper::$options = self::$options;
|
40 |
}
|
41 |
|
@@ -43,7 +45,7 @@ class AlterHtmlInit
|
|
43 |
return $content;
|
44 |
}
|
45 |
|
46 |
-
if (
|
47 |
require_once __DIR__ . "/../../vendor/autoload.php";
|
48 |
require_once __DIR__ . '/AlterHtmlHelper.php';
|
49 |
require_once __DIR__ . '/AlterHtmlPicture.php';
|
@@ -56,7 +58,7 @@ class AlterHtmlInit
|
|
56 |
}
|
57 |
}
|
58 |
|
59 |
-
public static function
|
60 |
{
|
61 |
// Don't do anything with the RSS feed.
|
62 |
// - and no need for PictureJs in the admin
|
@@ -67,7 +69,7 @@ class AlterHtmlInit
|
|
67 |
. 'if(!window.HTMLPictureElement && document.addEventListener) {'
|
68 |
. 'window.addEventListener("DOMContentLoaded", function() {'
|
69 |
. 'var s = document.createElement("script");'
|
70 |
-
. 's.src = "' . plugins_url('/js/picturefill.min.js',
|
71 |
. 'document.body.appendChild(s);'
|
72 |
. '});'
|
73 |
. '}'
|
@@ -76,11 +78,11 @@ class AlterHtmlInit
|
|
76 |
|
77 |
public static function setHooks() {
|
78 |
|
79 |
-
if (
|
80 |
-
|
81 |
}
|
82 |
|
83 |
-
if (
|
84 |
/* TODO:
|
85 |
Which hook should we use, and should we make it optional?
|
86 |
- Cache enabler uses 'template_redirect'
|
5 |
include_once "AlterHtmlHelper.php";
|
6 |
use AlterHtmlHelper;
|
7 |
|
8 |
+
use \WebPExpress\Option;
|
9 |
+
|
10 |
class AlterHtmlInit
|
11 |
{
|
12 |
public static $options = null;
|
29 |
return $content;
|
30 |
}
|
31 |
|
32 |
+
if (Option::getOption('webp-express-alter-html-replacement') == 'picture') {
|
33 |
if(function_exists('is_amp_endpoint') && is_amp_endpoint()) {
|
34 |
//for AMP pages the <picture> tag is not allowed
|
35 |
return $content;
|
37 |
}
|
38 |
|
39 |
if (!isset(self::$options)) {
|
40 |
+
self::$options = json_decode(Option::getOption('webp-express-alter-html-options', null), true);
|
41 |
//AlterHtmlHelper::$options = self::$options;
|
42 |
}
|
43 |
|
45 |
return $content;
|
46 |
}
|
47 |
|
48 |
+
if (Option::getOption('webp-express-alter-html-replacement') == 'picture') {
|
49 |
require_once __DIR__ . "/../../vendor/autoload.php";
|
50 |
require_once __DIR__ . '/AlterHtmlHelper.php';
|
51 |
require_once __DIR__ . '/AlterHtmlPicture.php';
|
58 |
}
|
59 |
}
|
60 |
|
61 |
+
public static function addPictureFillJs()
|
62 |
{
|
63 |
// Don't do anything with the RSS feed.
|
64 |
// - and no need for PictureJs in the admin
|
69 |
. 'if(!window.HTMLPictureElement && document.addEventListener) {'
|
70 |
. 'window.addEventListener("DOMContentLoaded", function() {'
|
71 |
. 'var s = document.createElement("script");'
|
72 |
+
. 's.src = "' . plugins_url('/js/picturefill.min.js', WEBPEXPRESS_PLUGIN) . '";'
|
73 |
. 'document.body.appendChild(s);'
|
74 |
. '});'
|
75 |
. '}'
|
78 |
|
79 |
public static function setHooks() {
|
80 |
|
81 |
+
if (Option::getOption('webp-express-alter-html-add-picturefill-js')) {
|
82 |
+
add_action( 'wp_head', '\\WebPExpress\\AlterHtmlInit::addPictureFillJs');
|
83 |
}
|
84 |
|
85 |
+
if (Option::getOption('webp-express-alter-html-hooks', 'ob') == 'ob') {
|
86 |
/* TODO:
|
87 |
Which hook should we use, and should we make it optional?
|
88 |
- Cache enabler uses 'template_redirect'
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WebPExpress;
|
4 |
+
|
5 |
+
use \WebPExpress\FileHelper;
|
6 |
+
use \WebPExpress\Paths;
|
7 |
+
|
8 |
+
class CapabilityTest
|
9 |
+
{
|
10 |
+
|
11 |
+
public static function copyCapabilityTestsToWpContent()
|
12 |
+
{
|
13 |
+
return FileHelper::cpdir(Paths::getWebPExpressPluginDirAbs() . '/htaccess-capability-tests', Paths::getWebPExpressContentDirAbs() . '/htaccess-capability-tests');
|
14 |
+
}
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Run one of the tests in wp-content/webp-express/capability-tests
|
19 |
+
* Three possible outcomes: true, false or null (null if request fails)
|
20 |
+
*/
|
21 |
+
public static function runTest($testDir)
|
22 |
+
{
|
23 |
+
//echo 'running test:' . $testDir . '<br>';
|
24 |
+
if (!@file_exists(Paths::getWebPExpressPluginDirAbs() . '/htaccess-capability-tests/' . $testDir)) {
|
25 |
+
// test does not even exist
|
26 |
+
//echo 'test does not exist: ' . $testDir . '<br>';
|
27 |
+
return null;
|
28 |
+
}
|
29 |
+
|
30 |
+
if (!@file_exists(Paths::getWebPExpressContentDirAbs() . '/htaccess-capability-tests/' . $testDir)) {
|
31 |
+
self::copyCapabilityTestsToWpContent();
|
32 |
+
}
|
33 |
+
|
34 |
+
// If copy failed, we can use the test in plugin path
|
35 |
+
if (!@file_exists(Paths::getWebPExpressContentDirAbs() . '/htaccess-capability-tests/' . $testDir)) {
|
36 |
+
$testUrl = Paths::getContentUrl() . '/' . 'webp-express/htaccess-capability-tests/' . $testDir . '/test.php';
|
37 |
+
} else {
|
38 |
+
$testUrl = Paths::getPluginUrl() . '/' . 'htaccess-capability-tests/' . $testDir . '/test.php';
|
39 |
+
}
|
40 |
+
|
41 |
+
//echo 'test url: ' . $testUrl . '<br>';
|
42 |
+
// TODO: Should we test if wp_remote_get exists first? - and if not, include wp-includes/http.php ?
|
43 |
+
|
44 |
+
$response = wp_remote_get($testUrl, ['timeout' => 10]);
|
45 |
+
//echo '<pre>' . print_r($response, true) . '</pre>';
|
46 |
+
if (wp_remote_retrieve_response_code($response) != '200') {
|
47 |
+
return null;
|
48 |
+
}
|
49 |
+
$responseBody = wp_remote_retrieve_body($response);
|
50 |
+
if ($responseBody == '') {
|
51 |
+
return null; // Some failure
|
52 |
+
}
|
53 |
+
if ($responseBody == '0') {
|
54 |
+
return false;
|
55 |
+
}
|
56 |
+
if ($responseBody == '1') {
|
57 |
+
return true;
|
58 |
+
}
|
59 |
+
return null;
|
60 |
+
}
|
61 |
+
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Three possible outcomes: true, false or null (null if failed to run test)
|
65 |
+
*/
|
66 |
+
public static function modRewriteWorking()
|
67 |
+
{
|
68 |
+
return self::runTest('has-mod-rewrite');
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Three possible outcomes: true, false or null (null if failed to run test)
|
73 |
+
*/
|
74 |
+
public static function modHeaderWorking()
|
75 |
+
{
|
76 |
+
return self::runTest('has-mod-header');
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Three possible outcomes: true, false or null (null if failed to run test)
|
81 |
+
*/
|
82 |
+
public static function passThroughEnvWorking()
|
83 |
+
{
|
84 |
+
return self::runTest('pass-through-environment-var');
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Three possible outcomes: true, false or null (null if failed to run test)
|
89 |
+
*/
|
90 |
+
public static function passThroughHeaderWorking()
|
91 |
+
{
|
92 |
+
return self::runTest('pass-server-var-through-header');
|
93 |
+
}
|
94 |
+
|
95 |
+
|
96 |
+
}
|
@@ -23,6 +23,8 @@ use \WebPExpress\State;
|
|
23 |
include_once "TestRun.php";
|
24 |
use \WebPExpress\TestRun;
|
25 |
|
|
|
|
|
26 |
class Config
|
27 |
{
|
28 |
|
@@ -67,14 +69,14 @@ class Config
|
|
67 |
|
68 |
return [
|
69 |
|
70 |
-
'operation-mode' => 'varied-responses',
|
71 |
|
72 |
// redirection rules
|
73 |
'enable-redirection-to-converter' => true,
|
74 |
'image-types' => 1,
|
75 |
'only-redirect-to-converter-on-cache-miss' => false,
|
76 |
'only-redirect-to-converter-for-webp-enabled-browsers' => true,
|
77 |
-
'do-not-pass-source-in-query-string' => false,
|
78 |
'redirect-to-existing-in-htaccess' => true,
|
79 |
'forward-query-string' => false,
|
80 |
'enable-redirection-to-webp-realizer' => true,
|
@@ -101,8 +103,9 @@ class Config
|
|
101 |
'enabled' => false,
|
102 |
'replacement' => 'picture', // "picture" or "url"
|
103 |
'hooks' => 'ob', // "content-hooks" or "ob"
|
104 |
-
'only-for-webp-enabled-browsers' =>
|
105 |
'only-for-webps-that-exists' => false,
|
|
|
106 |
],
|
107 |
|
108 |
// web service
|
@@ -130,29 +133,30 @@ class Config
|
|
130 |
public static function applyOperationMode($config)
|
131 |
{
|
132 |
if (!isset($config['operation-mode'])) {
|
133 |
-
$config['operation-mode'] = 'varied-responses';
|
134 |
}
|
135 |
|
136 |
-
if ($config['operation-mode'] == 'varied-responses') {
|
137 |
$config = array_merge($config, [
|
138 |
'enable-redirection-to-converter' => true,
|
139 |
'only-redirect-to-converter-for-webp-enabled-browsers' => true,
|
140 |
'only-redirect-to-converter-on-cache-miss' => false,
|
141 |
-
'do-not-pass-source-in-query-string' => true,
|
142 |
//'redirect-to-existing-in-htaccess' => true,
|
143 |
'fail' => 'original',
|
144 |
'success-response' => 'converted',
|
145 |
]);
|
146 |
-
} elseif ($config['operation-mode'] == '
|
147 |
$config = array_merge($config, [
|
148 |
'only-redirect-to-converter-for-webp-enabled-browsers' => false,
|
149 |
'only-redirect-to-converter-on-cache-miss' => true,
|
150 |
-
'do-not-pass-source-in-query-string' => true,
|
151 |
'redirect-to-existing-in-htaccess' => false,
|
152 |
'fail' => 'original',
|
153 |
'success-response' => 'original',
|
|
|
154 |
]);
|
155 |
-
} elseif ($config['operation-mode'] == '
|
156 |
|
157 |
// TODO: Go through these...
|
158 |
|
@@ -161,6 +165,9 @@ class Config
|
|
161 |
'destination-folder' => 'mingled',
|
162 |
'enable-redirection-to-webp-realizer' => false,
|
163 |
]);
|
|
|
|
|
|
|
164 |
}
|
165 |
|
166 |
return $config;
|
@@ -188,13 +195,23 @@ class Config
|
|
188 |
$config = self::applyOperationMode($config);
|
189 |
|
190 |
if (!isset($config['web-service'])) {
|
191 |
-
$config['web-service'] = [
|
|
|
|
|
192 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
if (($config['cache-control'] == 'set') && ($config['cache-control-max-age'] == '')) {
|
194 |
$config['cache-control-max-age'] = 'one-week';
|
195 |
}
|
196 |
|
197 |
-
if ($config['converters']
|
198 |
$config['converters'] = [];
|
199 |
}
|
200 |
|
@@ -251,9 +268,20 @@ class Config
|
|
251 |
}
|
252 |
}
|
253 |
|
|
|
254 |
return $config;
|
255 |
}
|
256 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
/**
|
258 |
* Loads Config (if available), fills in the rest with defaults
|
259 |
* also applies operation mode.
|
@@ -372,11 +400,13 @@ class Config
|
|
372 |
{
|
373 |
$config = self::fix($config, false);
|
374 |
|
375 |
-
|
376 |
-
|
377 |
-
|
|
|
|
|
378 |
|
379 |
-
//
|
380 |
|
381 |
$obj = $config['alter-html'];
|
382 |
unset($obj['enabled']);
|
@@ -394,7 +424,7 @@ class Config
|
|
394 |
];
|
395 |
$obj['image-types'] = $config['image-types']; // 0=none,1=jpg, 2=png, 3=both
|
396 |
|
397 |
-
|
398 |
'webp-express-alter-html-options',
|
399 |
json_encode($obj, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK),
|
400 |
true
|
@@ -551,6 +581,7 @@ class Config
|
|
551 |
*/
|
552 |
public static function saveConfigurationAndHTAccess($config, $forceRuleUpdating = false)
|
553 |
{
|
|
|
554 |
// Important to do this check before saving config, because the method
|
555 |
// compares against existing config.
|
556 |
|
@@ -594,4 +625,14 @@ class Config
|
|
594 |
];
|
595 |
}
|
596 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
}
|
23 |
include_once "TestRun.php";
|
24 |
use \WebPExpress\TestRun;
|
25 |
|
26 |
+
use \WebPExpress\Option;
|
27 |
+
|
28 |
class Config
|
29 |
{
|
30 |
|
69 |
|
70 |
return [
|
71 |
|
72 |
+
'operation-mode' => 'varied-image-responses',
|
73 |
|
74 |
// redirection rules
|
75 |
'enable-redirection-to-converter' => true,
|
76 |
'image-types' => 1,
|
77 |
'only-redirect-to-converter-on-cache-miss' => false,
|
78 |
'only-redirect-to-converter-for-webp-enabled-browsers' => true,
|
79 |
+
'do-not-pass-source-in-query-string' => false, // In 0.13 we can remove this. migration7.php depends on it
|
80 |
'redirect-to-existing-in-htaccess' => true,
|
81 |
'forward-query-string' => false,
|
82 |
'enable-redirection-to-webp-realizer' => true,
|
103 |
'enabled' => false,
|
104 |
'replacement' => 'picture', // "picture" or "url"
|
105 |
'hooks' => 'ob', // "content-hooks" or "ob"
|
106 |
+
'only-for-webp-enabled-browsers' => true, // If true, there will be two HTML versions of each page
|
107 |
'only-for-webps-that-exists' => false,
|
108 |
+
'alter-html-add-picturefill-js' => true,
|
109 |
],
|
110 |
|
111 |
// web service
|
133 |
public static function applyOperationMode($config)
|
134 |
{
|
135 |
if (!isset($config['operation-mode'])) {
|
136 |
+
$config['operation-mode'] = 'varied-image-responses';
|
137 |
}
|
138 |
|
139 |
+
if ($config['operation-mode'] == 'varied-image-responses') {
|
140 |
$config = array_merge($config, [
|
141 |
'enable-redirection-to-converter' => true,
|
142 |
'only-redirect-to-converter-for-webp-enabled-browsers' => true,
|
143 |
'only-redirect-to-converter-on-cache-miss' => false,
|
144 |
+
'do-not-pass-source-in-query-string' => true, // Will be removed in 0.13
|
145 |
//'redirect-to-existing-in-htaccess' => true,
|
146 |
'fail' => 'original',
|
147 |
'success-response' => 'converted',
|
148 |
]);
|
149 |
+
} elseif ($config['operation-mode'] == 'cdn-friendly') {
|
150 |
$config = array_merge($config, [
|
151 |
'only-redirect-to-converter-for-webp-enabled-browsers' => false,
|
152 |
'only-redirect-to-converter-on-cache-miss' => true,
|
153 |
+
'do-not-pass-source-in-query-string' => true, // Will be removed in 0.13
|
154 |
'redirect-to-existing-in-htaccess' => false,
|
155 |
'fail' => 'original',
|
156 |
'success-response' => 'original',
|
157 |
+
// cache-control => 'no-header' (we do not need this, as it is not important what it is set to in cdn-friendly mode, and we dont the value to be lost when switching operation mode)
|
158 |
]);
|
159 |
+
} elseif ($config['operation-mode'] == 'no-conversion') {
|
160 |
|
161 |
// TODO: Go through these...
|
162 |
|
165 |
'destination-folder' => 'mingled',
|
166 |
'enable-redirection-to-webp-realizer' => false,
|
167 |
]);
|
168 |
+
$config['alter-html']['only-for-webps-that-exists'] = true;
|
169 |
+
$config['web-service']['enabled'] = false;
|
170 |
+
|
171 |
}
|
172 |
|
173 |
return $config;
|
195 |
$config = self::applyOperationMode($config);
|
196 |
|
197 |
if (!isset($config['web-service'])) {
|
198 |
+
$config['web-service'] = [
|
199 |
+
'enabled' => false
|
200 |
+
];
|
201 |
}
|
202 |
+
if (!is_array($config['web-service']['whitelist'])) {
|
203 |
+
$config['web-service']['whitelist'] = [];
|
204 |
+
}
|
205 |
+
// remove whitelist entries without required fields (label, ip)
|
206 |
+
$config['web-service']['whitelist'] = array_filter($config['web-service']['whitelist'], function($var) {
|
207 |
+
return (isset($var['label']) && (isset($var['ip'])));
|
208 |
+
});
|
209 |
+
|
210 |
if (($config['cache-control'] == 'set') && ($config['cache-control-max-age'] == '')) {
|
211 |
$config['cache-control-max-age'] = 'one-week';
|
212 |
}
|
213 |
|
214 |
+
if (!is_array($config['converters'])) {
|
215 |
$config['converters'] = [];
|
216 |
}
|
217 |
|
268 |
}
|
269 |
}
|
270 |
|
271 |
+
|
272 |
return $config;
|
273 |
}
|
274 |
|
275 |
+
|
276 |
+
public static function runAndStoreCapabilityTests(&$config)
|
277 |
+
{
|
278 |
+
$config['base-htaccess-on-these-capability-tests'] = [
|
279 |
+
'passThroughHeaderWorking' => CapabilityTest::passThroughHeaderWorking(),
|
280 |
+
'passThroughEnvWorking' => CapabilityTest::passThroughEnvWorking(),
|
281 |
+
'modHeaderWorking' => CapabilityTest::modHeaderWorking(),
|
282 |
+
];
|
283 |
+
}
|
284 |
+
|
285 |
/**
|
286 |
* Loads Config (if available), fills in the rest with defaults
|
287 |
* also applies operation mode.
|
400 |
{
|
401 |
$config = self::fix($config, false);
|
402 |
|
403 |
+
Option::updateOption('webp-express-alter-html', $config['alter-html']['enabled'], true);
|
404 |
+
Option::updateOption('webp-express-alter-html-hooks', $config['alter-html']['hooks'], true);
|
405 |
+
Option::updateOption('webp-express-alter-html-replacement', $config['alter-html']['replacement'], true);
|
406 |
+
Option::updateOption('webp-express-alter-html-add-picturefill-js', (($config['alter-html']['replacement'] == 'picture') && (isset($config['alter-html']['alter-html-add-picturefill-js']) && $config['alter-html']['alter-html-add-picturefill-js'])), true);
|
407 |
+
|
408 |
|
409 |
+
//Option::updateOption('webp-express-alter-html', $config['alter-html']['enabled'], true);
|
410 |
|
411 |
$obj = $config['alter-html'];
|
412 |
unset($obj['enabled']);
|
424 |
];
|
425 |
$obj['image-types'] = $config['image-types']; // 0=none,1=jpg, 2=png, 3=both
|
426 |
|
427 |
+
Option::updateOption(
|
428 |
'webp-express-alter-html-options',
|
429 |
json_encode($obj, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK),
|
430 |
true
|
581 |
*/
|
582 |
public static function saveConfigurationAndHTAccess($config, $forceRuleUpdating = false)
|
583 |
{
|
584 |
+
|
585 |
// Important to do this check before saving config, because the method
|
586 |
// compares against existing config.
|
587 |
|
625 |
];
|
626 |
}
|
627 |
}
|
628 |
+
|
629 |
+
public static function getConverterByName($config, $converterName)
|
630 |
+
{
|
631 |
+
foreach ($config['converters'] as $i => $converter) {
|
632 |
+
if ($converter['converter'] == $converterName) {
|
633 |
+
return $converter;
|
634 |
+
}
|
635 |
+
}
|
636 |
+
}
|
637 |
+
|
638 |
}
|
@@ -255,4 +255,46 @@ class FileHelper
|
|
255 |
}
|
256 |
}
|
257 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
}
|
255 |
}
|
256 |
}
|
257 |
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Copy dir and all its files.
|
261 |
+
* Existing files are overwritten.
|
262 |
+
*
|
263 |
+
* @return $success
|
264 |
+
*/
|
265 |
+
public static function cpdir($sourceDir, $destinationDir)
|
266 |
+
{
|
267 |
+
if (!@is_dir($sourceDir)) {
|
268 |
+
return false;
|
269 |
+
}
|
270 |
+
if (!@file_exists($destinationDir)) {
|
271 |
+
if (!@mkdir($destinationDir)) {
|
272 |
+
return false;
|
273 |
+
}
|
274 |
+
}
|
275 |
+
|
276 |
+
$fileIterator = new \FilesystemIterator($sourceDir);
|
277 |
+
$success = true;
|
278 |
+
|
279 |
+
while ($fileIterator->valid()) {
|
280 |
+
$filename = $fileIterator->getFilename();
|
281 |
+
|
282 |
+
if (($filename != ".") && ($filename != "..")) {
|
283 |
+
//$filePerm = FileHelper::filePermWithFallback($filename, 0777);
|
284 |
+
|
285 |
+
if (@is_dir($sourceDir . "/" . $filename)) {
|
286 |
+
if (!self::cpdir($sourceDir . "/" . $filename, $destinationDir . "/" . $filename)) {
|
287 |
+
$success = false;
|
288 |
+
}
|
289 |
+
} else {
|
290 |
+
// its a file.
|
291 |
+
if (!copy($sourceDir . "/" . $filename, $destinationDir . "/" . $filename)) {
|
292 |
+
$success = false;
|
293 |
+
}
|
294 |
+
}
|
295 |
+
}
|
296 |
+
$fileIterator->next();
|
297 |
+
}
|
298 |
+
return $success;
|
299 |
+
}
|
300 |
}
|
@@ -23,6 +23,9 @@ class HTAccess
|
|
23 |
// So, in order to not have to use isset() all over the place, set to values
|
24 |
// that results in same behaviour as before the option was introduced.
|
25 |
// Beware that this may not be same as the default value in the UI (but it is generally)
|
|
|
|
|
|
|
26 |
$defaults = [
|
27 |
'enable-redirection-to-converter' => true,
|
28 |
'forward-query-string' => true,
|
@@ -40,6 +43,29 @@ class HTAccess
|
|
40 |
return '# WebP Express does not need to write any rules (it has not been set up to redirect to converter, nor to existing webp, and the "convert non-existing webp-files upon request" option has not been enabled)';
|
41 |
}
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
/* Calculate $fileExt */
|
44 |
$imageTypes = $config['image-types'];
|
45 |
$fileExtensions = [];
|
@@ -78,48 +104,54 @@ class HTAccess
|
|
78 |
$ccRules .= " </IfModule>\n\n";
|
79 |
|
80 |
// Fall back to mod_expires if mod_headers is unavailable
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
}
|
93 |
}
|
94 |
-
}
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
|
|
111 |
}
|
112 |
-
}
|
113 |
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
|
|
123 |
}
|
124 |
}
|
125 |
|
@@ -186,7 +218,6 @@ class HTAccess
|
|
186 |
break;
|
187 |
}
|
188 |
|
189 |
-
$passSourceInQS = !($config['do-not-pass-source-in-query-string']);
|
190 |
|
191 |
// TODO: Is it possible to handle when wp-content is outside document root?
|
192 |
|
@@ -224,6 +255,23 @@ class HTAccess
|
|
224 |
|
225 |
}
|
226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
if ($config['enable-redirection-to-webp-realizer']) {
|
228 |
/*
|
229 |
# Pass REQUEST_FILENAME to PHP in request header
|
@@ -239,7 +287,6 @@ class HTAccess
|
|
239 |
RewriteCond %{DOCUMENT_ROOT}/wordpress/uploads-moved/$1 -f
|
240 |
RewriteRule ^(.*)\.(webp)$ /plugins-moved/webp-express/wod/webp-realizer.php?wp-content=wp-content-moved [NC,L]
|
241 |
*/
|
242 |
-
$passSourceInQSRealizer = $passSourceInQS;
|
243 |
|
244 |
$basicConditionsRealizer = '';
|
245 |
$basicConditionsRealizer .= " RewriteCond %{REQUEST_FILENAME} !-f\n";
|
@@ -253,22 +300,32 @@ class HTAccess
|
|
253 |
//$basicConditionsRealizer .= " RewriteCond %{DOCUMENT_ROOT}/" . $cacheDirRel . "/" . $htaccessDirRel . "/$1.$2.webp !-f\n";
|
254 |
}
|
255 |
|
256 |
-
|
257 |
-
$rules .= " # Pass REQUEST_FILENAME to webp-realizer.php in request header\n";
|
258 |
-
$rules .= $basicConditionsRealizer;
|
259 |
-
$rules .= " RewriteRule " . $rewriteRuleStart . "\.(webp)$ - [E=REQFN:%{REQUEST_FILENAME}]\n" .
|
260 |
-
" <IfModule mod_headers.c>\n" .
|
261 |
-
" RequestHeader set REQFN \"%{REQFN}e\" env=REQFN\n" .
|
262 |
-
" </IfModule>\n\n";
|
263 |
-
|
264 |
$rules .= " # WebP Realizer: Redirect non-existing webp images to webp-realizer.php, which will locate corresponding jpg/png, convert it, and deliver the webp (if possible) \n";
|
265 |
$rules .= $basicConditionsRealizer;
|
266 |
|
|
|
267 |
$rules .= " RewriteRule " . $rewriteRuleStart . "\.(webp)$ " .
|
268 |
"/" . Paths::getWebPRealizerUrlPath() .
|
269 |
-
($
|
270 |
"wp-content=" . Paths::getContentDirRel() .
|
271 |
-
" [NC,L]\n\n"; // E=WOD:1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
272 |
|
273 |
if (!$config['redirect-to-existing-in-htaccess']) {
|
274 |
$rules .= $ccRules;
|
@@ -293,16 +350,6 @@ class HTAccess
|
|
293 |
}
|
294 |
}
|
295 |
|
296 |
-
|
297 |
-
if (!$passSourceInQS) {
|
298 |
-
$rules .= " # Pass REQUEST_FILENAME to webp-on-demand.php in request header\n";
|
299 |
-
$rules .= $basicConditions;
|
300 |
-
$rules .= " RewriteRule ^(.*)\.(" . $fileExt . ")$ - [E=REQFN:%{REQUEST_FILENAME}]\n" .
|
301 |
-
" <IfModule mod_headers.c>\n" .
|
302 |
-
" RequestHeader set REQFN \"%{REQFN}e\" env=REQFN\n" .
|
303 |
-
" </IfModule>\n\n";
|
304 |
-
}
|
305 |
-
|
306 |
$rules .= " # Redirect images to webp-on-demand.php ";
|
307 |
if ($config['only-redirect-to-converter-for-webp-enabled-browsers']) {
|
308 |
$rules .= "(if browser supports webp)\n";
|
@@ -327,34 +374,51 @@ class HTAccess
|
|
327 |
// https://github.com/rosell-dk/webp-convert/issues/95
|
328 |
// (and try testing spaces in directory paths)
|
329 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
// TODO: When $rewriteRuleStart is empty, we don't need the .*, do we? - test
|
331 |
$rules .= " RewriteRule " . $rewriteRuleStart . "\.(" . $fileExt . ")$ " .
|
332 |
"/" . Paths::getWodUrlPath() .
|
333 |
-
|
334 |
-
"
|
335 |
-
|
336 |
-
|
|
|
|
|
|
|
337 |
|
338 |
-
|
|
|
339 |
$rules .= " <IfModule mod_setenvif.c>\n";
|
340 |
|
341 |
-
|
342 |
-
|
343 |
-
" # The purpose is to make CDN aware that the response varies with the Accept header, so it should not just use the URL as cache key, but also the Accept header. \n" .
|
344 |
" SetEnvIf Request_URI \"\.(" . $fileExt . ")\" ADDVARY\n" .
|
345 |
" Header append \"Vary\" \"Accept\" env=ADDVARY\n\n";
|
346 |
-
}
|
347 |
|
348 |
-
$
|
|
|
349 |
" # Apache appends \"REDIRECT_\" in front of the environment variables defined in mod_rewrite, but LiteSpeed does not.\n" .
|
350 |
" # So, the next line is for Apache, in order to set environment variables without \"REDIRECT_\"\n" .
|
351 |
" SetEnvIf REDIRECT_EXISTING 1 EXISTING=1\n" .
|
352 |
//" SetEnvIf REDIRECT_WOD 1 WOD=1\n\n" .
|
353 |
//" # Set the debug header\n" .
|
354 |
-
" Header set \"X-WebP-Express\" \"Redirected directly to existing webp\" env=EXISTING\n"
|
355 |
//" Header set \"X-WebP-Express\" \"Redirected to image converter\" env=WOD\n" .
|
356 |
-
|
357 |
-
|
|
|
358 |
}
|
359 |
$rules .="</IfModule>\n";
|
360 |
|
@@ -430,7 +494,6 @@ class HTAccess
|
|
430 |
$propsToCompare = [
|
431 |
'forward-query-string' => true,
|
432 |
'image-types' => 1,
|
433 |
-
'do-not-pass-source-in-query-string' => false,
|
434 |
'redirect-to-existing-in-htaccess' => false,
|
435 |
'only-redirect-to-converter-on-cache-miss' => false,
|
436 |
'success-response' => 'converted',
|
@@ -438,6 +501,8 @@ class HTAccess
|
|
438 |
'cache-control-custom' => 'public, max-age:3600',
|
439 |
'cache-control-max-age' => 'one-week',
|
440 |
'cache-control-public' => true,
|
|
|
|
|
441 |
];
|
442 |
|
443 |
if (isset($newConfig['redirect-to-existing-in-htaccess']) && $newConfig['redirect-to-existing-in-htaccess']) {
|
@@ -509,7 +574,7 @@ class HTAccess
|
|
509 |
|
510 |
/**
|
511 |
* Sneak peak into .htaccess to see if we have rules in it
|
512 |
-
* This may not be possible
|
513 |
* Return true, false, or null if we just can't tell
|
514 |
*/
|
515 |
public static function haveWeRulesInThisHTAccess($filename) {
|
@@ -549,6 +614,7 @@ class HTAccess
|
|
549 |
// We were not allowed to sneak-peak.
|
550 |
// Well, good thing that we stored successful .htaccess write locations ;)
|
551 |
// If we recorded a successful write, then we assume there are still rules there
|
|
|
552 |
$dir = FileHelper::dirName($filename);
|
553 |
return self::hasRecordOfSavingHTAccessToDir($dir);
|
554 |
}
|
@@ -665,11 +731,25 @@ class HTAccess
|
|
665 |
|
666 |
public static function testLinks($config) {
|
667 |
if (isset($_SERVER['HTTP_ACCEPT']) && (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false )) {
|
668 |
-
if ($config['
|
669 |
-
$
|
670 |
-
|
671 |
-
|
672 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
673 |
}
|
674 |
}
|
675 |
return '';
|
@@ -730,6 +810,8 @@ class HTAccess
|
|
730 |
}
|
731 |
} else {
|
732 |
$mainResult = 'wp-content';
|
|
|
|
|
733 |
HTAccess::saveHTAccessRulesToFile(Paths::getIndexDirAbs() . '/.htaccess', '# WebP Express has placed its rules in your wp-content dir. Go there.', false);
|
734 |
}
|
735 |
|
23 |
// So, in order to not have to use isset() all over the place, set to values
|
24 |
// that results in same behaviour as before the option was introduced.
|
25 |
// Beware that this may not be same as the default value in the UI (but it is generally)
|
26 |
+
|
27 |
+
// TODO: can we use the new fix method instead?
|
28 |
+
|
29 |
$defaults = [
|
30 |
'enable-redirection-to-converter' => true,
|
31 |
'forward-query-string' => true,
|
43 |
return '# WebP Express does not need to write any rules (it has not been set up to redirect to converter, nor to existing webp, and the "convert non-existing webp-files upon request" option has not been enabled)';
|
44 |
}
|
45 |
|
46 |
+
if (isset($config['base-htaccess-on-these-capability-tests'])) {
|
47 |
+
$capTests = $config['base-htaccess-on-these-capability-tests'];
|
48 |
+
$modHeaderDefinitelyUnavailable = ($capTests['modHeaderWorking'] === false);
|
49 |
+
$passThroughHeaderDefinitelyUnavailable = ($capTests['passThroughHeaderWorking'] === false);
|
50 |
+
$passThroughHeaderDefinitelyAavailable = ($capTests['passThroughHeaderWorking'] === true);
|
51 |
+
$passThrougEnvVarDefinitelyUnavailable = ($capTests['passThroughEnvWorking'] === false);
|
52 |
+
$passThrougEnvVarDefinitelyAvailable =($capTests['passThroughEnvWorking'] === true);
|
53 |
+
} else {
|
54 |
+
$modHeaderDefinitelyUnavailable = false;
|
55 |
+
$passThroughHeaderDefinitelyUnavailable = false;
|
56 |
+
$passThroughHeaderDefinitelyAavailable = false;
|
57 |
+
$passThrougEnvVarDefinitelyUnavailable = false;
|
58 |
+
$passThrougEnvVarDefinitelyAvailable = false;
|
59 |
+
}
|
60 |
+
|
61 |
+
$setEnvVar = !$passThrougEnvVarDefinitelyUnavailable;
|
62 |
+
$passFullFilePathInQS = false;
|
63 |
+
$passRelativeFilePathInQS = !($passThrougEnvVarDefinitelyAvailable || $passThroughHeaderDefinitelyAavailable);
|
64 |
+
$passFullFilePathInQSRealizer = false;
|
65 |
+
$passRelativeFilePathInQSRealizer = $passRelativeFilePathInQS;
|
66 |
+
|
67 |
+
|
68 |
+
|
69 |
/* Calculate $fileExt */
|
70 |
$imageTypes = $config['image-types'];
|
71 |
$fileExtensions = [];
|
104 |
$ccRules .= " </IfModule>\n\n";
|
105 |
|
106 |
// Fall back to mod_expires if mod_headers is unavailable
|
107 |
+
|
108 |
+
|
109 |
+
|
110 |
+
if ($modHeaderDefinitelyUnavailable) {
|
111 |
+
$cacheControl = $config['cache-control'];
|
112 |
+
|
113 |
+
if ($cacheControl == 'custom') {
|
114 |
+
$expires = '';
|
115 |
+
|
116 |
+
// Do not add Expire header if private is set
|
117 |
+
// - because then the user don't want caching in proxies / CDNs.
|
118 |
+
// the Expires header doesn't differentiate between private/public
|
119 |
+
if (!(preg_match('/private/', $config['cache-control-custom']))) {
|
120 |
+
if (preg_match('/max-age=(\d+)/', $config['cache-control-custom'], $matches)) {
|
121 |
+
if (isset($matches[1])) {
|
122 |
+
$expires = $matches[1] . ' seconds';
|
123 |
+
}
|
124 |
}
|
125 |
}
|
|
|
126 |
|
127 |
+
} elseif ($cacheControl == 'no-header') {
|
128 |
+
$expires = '';
|
129 |
+
} elseif ($cacheControl == 'set') {
|
130 |
+
if ($config['cache-control-public']) {
|
131 |
+
$cacheControlOptions = [
|
132 |
+
'no-header' => '',
|
133 |
+
'one-second' => '1 seconds',
|
134 |
+
'one-minute' => '1 minutes',
|
135 |
+
'one-hour' => '1 hours',
|
136 |
+
'one-day' => '1 days',
|
137 |
+
'one-week' => '1 weeks',
|
138 |
+
'one-month' => '1 months',
|
139 |
+
'one-year' => '1 years',
|
140 |
+
];
|
141 |
+
$expires = $cacheControlOptions[$config['cache-control-max-age']];
|
142 |
+
}
|
143 |
}
|
|
|
144 |
|
145 |
+
if ($expires != '') {
|
146 |
+
// in case mod_headers is missing, try mod_expires
|
147 |
+
$ccRules .= " # Fall back to mod_expires if mod_headers is unavailable\n";
|
148 |
+
$ccRules .= " <IfModule !mod_headers.c>\n";
|
149 |
+
$ccRules .= " <IfModule mod_expires.c>\n";
|
150 |
+
$ccRules .= " ExpiresActive On\n";
|
151 |
+
$ccRules .= " ExpiresByType image/webp \"access plus " . $expires . "\"\n";
|
152 |
+
$ccRules .= " </IfModule>\n";
|
153 |
+
$ccRules .= " </IfModule>\n\n";
|
154 |
+
}
|
155 |
}
|
156 |
}
|
157 |
|
218 |
break;
|
219 |
}
|
220 |
|
|
|
221 |
|
222 |
// TODO: Is it possible to handle when wp-content is outside document root?
|
223 |
|
255 |
|
256 |
}
|
257 |
|
258 |
+
// Do not add header magic if passing through env is definitely working
|
259 |
+
// Do not add either, if we definitily know it isn't working
|
260 |
+
if ((!$passThrougEnvVarDefinitelyAvailable) && (!$passThroughHeaderDefinitelyUnavailable)) {
|
261 |
+
if ($config['enable-redirection-to-converter']) {
|
262 |
+
$rules .= " # Pass REQUEST_FILENAME to webp-on-demand.php in request header\n";
|
263 |
+
//$rules .= $basicConditions;
|
264 |
+
//$rules .= " RewriteRule ^(.*)\.(" . $fileExt . ")$ - [E=REQFN:%{REQUEST_FILENAME}]\n" .
|
265 |
+
$rules .= " <IfModule mod_headers.c>\n" .
|
266 |
+
" RequestHeader set REQFN \"%{REQFN}e\" env=REQFN\n" .
|
267 |
+
" </IfModule>\n\n";
|
268 |
+
|
269 |
+
}
|
270 |
+
if ($config['enable-redirection-to-webp-realizer']) {
|
271 |
+
// We haven't implemented a clever way to pass through header for webp-realizer yet
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
if ($config['enable-redirection-to-webp-realizer']) {
|
276 |
/*
|
277 |
# Pass REQUEST_FILENAME to PHP in request header
|
287 |
RewriteCond %{DOCUMENT_ROOT}/wordpress/uploads-moved/$1 -f
|
288 |
RewriteRule ^(.*)\.(webp)$ /plugins-moved/webp-express/wod/webp-realizer.php?wp-content=wp-content-moved [NC,L]
|
289 |
*/
|
|
|
290 |
|
291 |
$basicConditionsRealizer = '';
|
292 |
$basicConditionsRealizer .= " RewriteCond %{REQUEST_FILENAME} !-f\n";
|
300 |
//$basicConditionsRealizer .= " RewriteCond %{DOCUMENT_ROOT}/" . $cacheDirRel . "/" . $htaccessDirRel . "/$1.$2.webp !-f\n";
|
301 |
}
|
302 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
$rules .= " # WebP Realizer: Redirect non-existing webp images to webp-realizer.php, which will locate corresponding jpg/png, convert it, and deliver the webp (if possible) \n";
|
304 |
$rules .= $basicConditionsRealizer;
|
305 |
|
306 |
+
/*
|
307 |
$rules .= " RewriteRule " . $rewriteRuleStart . "\.(webp)$ " .
|
308 |
"/" . Paths::getWebPRealizerUrlPath() .
|
309 |
+
($passFullFilePathInQS ? "?xdestination=x%{SCRIPT_FILENAME}&" : "?") .
|
310 |
"wp-content=" . Paths::getContentDirRel() .
|
311 |
+
" [" . ($setEnvVar ? ('E=REQFN:%{REQUEST_FILENAME}' . ','): '') . "NC,L]\n\n"; // E=WOD:1
|
312 |
+
*/
|
313 |
+
$params = [];
|
314 |
+
if ($passFullFilePathInQSRealizer) {
|
315 |
+
$params[] = 'xdestination=x%{SCRIPT_FILENAME}';
|
316 |
+
} elseif ($passRelativeFilePathInQSRealizer) {
|
317 |
+
$params[] = 'xdestination-rel=x' . $htaccessDirRel . '/$1.$2';
|
318 |
+
}
|
319 |
+
if (!$passThrougEnvVarDefinitelyAvailable) {
|
320 |
+
$params[] = "wp-content=" . Paths::getContentDirRel();
|
321 |
+
}
|
322 |
+
|
323 |
+
// TODO: When $rewriteRuleStart is empty, we don't need the .*, do we? - test
|
324 |
+
$rules .= " RewriteRule " . $rewriteRuleStart . "\.(webp)$ " .
|
325 |
+
"/" . Paths::getWebPRealizerUrlPath() .
|
326 |
+
((count($params) > 0) ? "?" . implode('&', $params) : '') .
|
327 |
+
" [" . ($setEnvVar ? ('E=DESTINATIONREL:' . $htaccessDirRel . '/$0' . ','): '') . (!$passThrougEnvVarDefinitelyUnavailable ? 'E=WPCONTENT:' . Paths::getContentDirRel() . ',' : '') . "NC,L]\n\n"; // E=WOD:1
|
328 |
+
|
329 |
|
330 |
if (!$config['redirect-to-existing-in-htaccess']) {
|
331 |
$rules .= $ccRules;
|
350 |
}
|
351 |
}
|
352 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
$rules .= " # Redirect images to webp-on-demand.php ";
|
354 |
if ($config['only-redirect-to-converter-for-webp-enabled-browsers']) {
|
355 |
$rules .= "(if browser supports webp)\n";
|
374 |
// https://github.com/rosell-dk/webp-convert/issues/95
|
375 |
// (and try testing spaces in directory paths)
|
376 |
|
377 |
+
$params = [];
|
378 |
+
if ($passFullFilePathInQS) {
|
379 |
+
$params[] = 'xsource=x%{SCRIPT_FILENAME}';
|
380 |
+
} elseif ($passRelativeFilePathInQS) {
|
381 |
+
$params[] = 'xsource-rel=x' . $htaccessDirRel . '/$1.$2';
|
382 |
+
}
|
383 |
+
if (!$passThrougEnvVarDefinitelyAvailable) {
|
384 |
+
$params[] = "wp-content=" . Paths::getContentDirRel();
|
385 |
+
}
|
386 |
+
if ($config['forward-query-string']) {
|
387 |
+
$params[] = '%1';
|
388 |
+
}
|
389 |
+
|
390 |
// TODO: When $rewriteRuleStart is empty, we don't need the .*, do we? - test
|
391 |
$rules .= " RewriteRule " . $rewriteRuleStart . "\.(" . $fileExt . ")$ " .
|
392 |
"/" . Paths::getWodUrlPath() .
|
393 |
+
"?" . implode('&', $params) .
|
394 |
+
" [" . ($setEnvVar ? ('E=REQFN:%{REQUEST_FILENAME},'): '') . (!$passThrougEnvVarDefinitelyUnavailable ? 'E=WPCONTENT:' . Paths::getContentDirRel() . ',' : '') . "NC,L]\n"; // E=WOD:1
|
395 |
+
|
396 |
+
$rules .= "\n";
|
397 |
+
}
|
398 |
+
|
399 |
+
$addVary = ($config['enable-redirection-to-converter'] && ($config['success-response'] == 'converted')) || ($config['redirect-to-existing-in-htaccess']);
|
400 |
|
401 |
+
if ($addVary) {
|
402 |
+
$rules .= " <IfModule mod_headers.c>\n";
|
403 |
$rules .= " <IfModule mod_setenvif.c>\n";
|
404 |
|
405 |
+
$rules .= " # Set Vary:Accept header for the image types handled by WebP Express.\n" .
|
406 |
+
" # The purpose is to make proxies and CDNs aware that the response varies with the Accept header. \n" .
|
|
|
407 |
" SetEnvIf Request_URI \"\.(" . $fileExt . ")\" ADDVARY\n" .
|
408 |
" Header append \"Vary\" \"Accept\" env=ADDVARY\n\n";
|
|
|
409 |
|
410 |
+
if ($config['redirect-to-existing-in-htaccess']) {
|
411 |
+
$rules .= " # Set X-WebP-Express header for diagnose purposes\n" .
|
412 |
" # Apache appends \"REDIRECT_\" in front of the environment variables defined in mod_rewrite, but LiteSpeed does not.\n" .
|
413 |
" # So, the next line is for Apache, in order to set environment variables without \"REDIRECT_\"\n" .
|
414 |
" SetEnvIf REDIRECT_EXISTING 1 EXISTING=1\n" .
|
415 |
//" SetEnvIf REDIRECT_WOD 1 WOD=1\n\n" .
|
416 |
//" # Set the debug header\n" .
|
417 |
+
" Header set \"X-WebP-Express\" \"Redirected directly to existing webp\" env=EXISTING\n";
|
418 |
//" Header set \"X-WebP-Express\" \"Redirected to image converter\" env=WOD\n" .
|
419 |
+
}
|
420 |
+
$rules .= " </IfModule>\n" .
|
421 |
+
" </IfModule>\n\n";
|
422 |
}
|
423 |
$rules .="</IfModule>\n";
|
424 |
|
494 |
$propsToCompare = [
|
495 |
'forward-query-string' => true,
|
496 |
'image-types' => 1,
|
|
|
497 |
'redirect-to-existing-in-htaccess' => false,
|
498 |
'only-redirect-to-converter-on-cache-miss' => false,
|
499 |
'success-response' => 'converted',
|
501 |
'cache-control-custom' => 'public, max-age:3600',
|
502 |
'cache-control-max-age' => 'one-week',
|
503 |
'cache-control-public' => true,
|
504 |
+
'enable-redirection-to-webp-realizer' => false,
|
505 |
+
'enable-redirection-to-converter' => true
|
506 |
];
|
507 |
|
508 |
if (isset($newConfig['redirect-to-existing-in-htaccess']) && $newConfig['redirect-to-existing-in-htaccess']) {
|
574 |
|
575 |
/**
|
576 |
* Sneak peak into .htaccess to see if we have rules in it
|
577 |
+
* This may not be possible (it requires read permission)
|
578 |
* Return true, false, or null if we just can't tell
|
579 |
*/
|
580 |
public static function haveWeRulesInThisHTAccess($filename) {
|
614 |
// We were not allowed to sneak-peak.
|
615 |
// Well, good thing that we stored successful .htaccess write locations ;)
|
616 |
// If we recorded a successful write, then we assume there are still rules there
|
617 |
+
// If we did not, we assume there are no rules there
|
618 |
$dir = FileHelper::dirName($filename);
|
619 |
return self::hasRecordOfSavingHTAccessToDir($dir);
|
620 |
}
|
731 |
|
732 |
public static function testLinks($config) {
|
733 |
if (isset($_SERVER['HTTP_ACCEPT']) && (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false )) {
|
734 |
+
if ($config['operation-mode'] != 'no-conversion') {
|
735 |
+
if ($config['image-types'] != 0) {
|
736 |
+
$webpExpressRoot = Paths::getPluginUrlPath();
|
737 |
+
if ($config['enable-redirection-to-converter']) {
|
738 |
+
$links = '<br>';
|
739 |
+
$links .= '<a href="/' . $webpExpressRoot . '/test/test.jpg?debug&time=' . time() . '" target="_blank">Convert test image (show debug)</a><br>';
|
740 |
+
$links .= '<a href="/' . $webpExpressRoot . '/test/test.jpg?' . time() . '" target="_blank">Convert test image</a><br>';
|
741 |
+
}
|
742 |
+
// TODO: webp-realizer test links (to missing webp)
|
743 |
+
if ($config['enable-redirection-to-webp-realizer']) {
|
744 |
+
}
|
745 |
+
|
746 |
+
// TODO: test link for testing redirection to existing
|
747 |
+
if ($config['redirect-to-existing-in-htaccess']) {
|
748 |
+
|
749 |
+
}
|
750 |
+
|
751 |
+
return $links;
|
752 |
+
}
|
753 |
}
|
754 |
}
|
755 |
return '';
|
810 |
}
|
811 |
} else {
|
812 |
$mainResult = 'wp-content';
|
813 |
+
// TODO: Change to something like "The rules are placed in the .htaccess file in your wp-content dir."
|
814 |
+
// BUT! - current text is searched for in page-messages.php
|
815 |
HTAccess::saveHTAccessRulesToFile(Paths::getIndexDirAbs() . '/.htaccess', '# WebP Express has placed its rules in your wp-content dir. Go there.', false);
|
816 |
}
|
817 |
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WebPExpress;
|
4 |
+
|
5 |
+
use \WebPExpress\Config;
|
6 |
+
use \WebPExpress\Messenger;
|
7 |
+
use \WebPExpress\State;
|
8 |
+
use \WebPConvert\Converters\Ewww;
|
9 |
+
|
10 |
+
/**
|
11 |
+
*
|
12 |
+
*/
|
13 |
+
|
14 |
+
class KeepEwwwSubscriptionAlive
|
15 |
+
{
|
16 |
+
public static function keepAlive($config = null) {
|
17 |
+
include_once __DIR__ . '/../../vendor/autoload.php';
|
18 |
+
|
19 |
+
if (is_null($config)) {
|
20 |
+
$config = Config::loadConfigAndFix(false); // false, because we do not need to test if quality detection is working
|
21 |
+
}
|
22 |
+
|
23 |
+
$ewww = Config::getConverterByName($config, 'ewww');
|
24 |
+
if (!isset($ewww['options']['key'])) {
|
25 |
+
return;
|
26 |
+
}
|
27 |
+
if (!$ewww['working']) {
|
28 |
+
return;
|
29 |
+
}
|
30 |
+
|
31 |
+
$ewwwConvertResult = Ewww::keepSubscriptionAlive(__DIR__ . '/../../test/very-small.jpg', $ewww['options']['key']);
|
32 |
+
if ($ewwwConvertResult === true) {
|
33 |
+
Messenger::addMessage(
|
34 |
+
'info',
|
35 |
+
'Successfully optimized regular jpg with <i>ewww</i> converter in order to keep the subscription alive'
|
36 |
+
);
|
37 |
+
State::setState('last-ewww-optimize', time());
|
38 |
+
} else {
|
39 |
+
Messenger::addMessage(
|
40 |
+
'warning',
|
41 |
+
'Failed optimizing regular jpg with <i>ewww</i> converter in order to keep the subscription alive'
|
42 |
+
);
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
public static function keepAliveIfItIsTime($config = null) {
|
47 |
+
|
48 |
+
$timeSinseLastSuccesfullOptimize = time() - State::getState('last-ewww-optimize', 0);
|
49 |
+
if ($timeSinseLastSuccesfullOptimize > 3 * 30 * 24 * 60 * 60) {
|
50 |
+
|
51 |
+
$timeSinseLastOptimizeAttempt = time() - State::getState('last-ewww-optimize-attempt', 0);
|
52 |
+
if ($timeSinseLastOptimizeAttempt > 14 * 24 * 60 * 60) {
|
53 |
+
State::setState('last-ewww-optimize-attempt', time());
|
54 |
+
self::keepAlive($config);
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
}
|
59 |
+
|
60 |
+
}
|
@@ -5,6 +5,8 @@ namespace WebPExpress;
|
|
5 |
include_once "State.php";
|
6 |
use \WebPExpress\State;
|
7 |
|
|
|
|
|
8 |
class Messenger
|
9 |
{
|
10 |
private static $printedStyles = false;
|
@@ -17,8 +19,9 @@ class Messenger
|
|
17 |
* $msg = sprintf(__( 'You are on a very old version of PHP (%s). WebP Express may not work as intended.', 'webp-express' ), phpversion());
|
18 |
*/
|
19 |
public static function addMessage($level, $msg) {
|
|
|
20 |
|
21 |
-
|
22 |
$pendingMessages = State::getState('pendingMessages', []);
|
23 |
|
24 |
// Ensure we do not add a message that is already pending.
|
@@ -80,7 +83,6 @@ class Messenger
|
|
80 |
|
81 |
public static function printPendingMessages() {
|
82 |
|
83 |
-
|
84 |
$messages = State::getState('pendingMessages', []);
|
85 |
|
86 |
foreach ($messages as $message) {
|
@@ -88,6 +90,6 @@ class Messenger
|
|
88 |
}
|
89 |
|
90 |
State::setState('pendingMessages', []);
|
91 |
-
|
92 |
}
|
93 |
}
|
5 |
include_once "State.php";
|
6 |
use \WebPExpress\State;
|
7 |
|
8 |
+
use \WebPExpress\Option;
|
9 |
+
|
10 |
class Messenger
|
11 |
{
|
12 |
private static $printedStyles = false;
|
19 |
* $msg = sprintf(__( 'You are on a very old version of PHP (%s). WebP Express may not work as intended.', 'webp-express' ), phpversion());
|
20 |
*/
|
21 |
public static function addMessage($level, $msg) {
|
22 |
+
//error_log('add message:' . $msg);
|
23 |
|
24 |
+
Option::updateOption('webp-express-messages-pending', true, true); // We want this option to be autoloaded
|
25 |
$pendingMessages = State::getState('pendingMessages', []);
|
26 |
|
27 |
// Ensure we do not add a message that is already pending.
|
83 |
|
84 |
public static function printPendingMessages() {
|
85 |
|
|
|
86 |
$messages = State::getState('pendingMessages', []);
|
87 |
|
88 |
foreach ($messages as $message) {
|
90 |
}
|
91 |
|
92 |
State::setState('pendingMessages', []);
|
93 |
+
Option::updateOption('webp-express-messages-pending', false, true);
|
94 |
}
|
95 |
}
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WebPExpress;
|
4 |
+
|
5 |
+
class Multisite
|
6 |
+
{
|
7 |
+
public static $networkActive;
|
8 |
+
|
9 |
+
/*
|
10 |
+
Needed because is_plugin_active_for_network() does not return true right after network activation
|
11 |
+
*/
|
12 |
+
public static function overrideIsNetworkActivated($networkActive)
|
13 |
+
{
|
14 |
+
self::$networkActive = $networkActive;
|
15 |
+
}
|
16 |
+
|
17 |
+
public static function isNetworkActivated()
|
18 |
+
{
|
19 |
+
if (!is_null(self::$networkActive)) {
|
20 |
+
return self::$networkActive;
|
21 |
+
}
|
22 |
+
if (!self::isMultisite()) {
|
23 |
+
return false;
|
24 |
+
}
|
25 |
+
if (!function_exists( 'is_plugin_active_for_network')) {
|
26 |
+
require_once(ABSPATH . '/wp-admin/includes/plugin.php');
|
27 |
+
}
|
28 |
+
return is_plugin_active_for_network('webp-express/webp-express.php');
|
29 |
+
}
|
30 |
+
|
31 |
+
public static function isMultisite()
|
32 |
+
{
|
33 |
+
return is_multisite();
|
34 |
+
}
|
35 |
+
|
36 |
+
}
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WebPExpress;
|
4 |
+
|
5 |
+
use \WebPExpress\Multisite;
|
6 |
+
|
7 |
+
class Option
|
8 |
+
{
|
9 |
+
|
10 |
+
public static function getOption($optionName, $default = false)
|
11 |
+
{
|
12 |
+
if (Multisite::isNetworkActivated()) {
|
13 |
+
return get_site_option($optionName, $default);
|
14 |
+
} else {
|
15 |
+
return get_option($optionName, $default);
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
public static function updateOption($optionName, $value, $autoload = null)
|
20 |
+
{
|
21 |
+
if (Multisite::isNetworkActivated()) {
|
22 |
+
//error_log('update option (network):' . $optionName . ':' . $value);
|
23 |
+
return update_site_option($optionName, $value);
|
24 |
+
} else {
|
25 |
+
//error_log('update option:' . $optionName . ':' . $value);
|
26 |
+
return update_option($optionName, $value, $autoload);
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
public static function deleteOption($optionName)
|
31 |
+
{
|
32 |
+
if (Multisite::isNetworkActivated()) {
|
33 |
+
return delete_site_option($optionName);
|
34 |
+
} else {
|
35 |
+
return delete_option($optionName);
|
36 |
+
}
|
37 |
+
|
38 |
+
}
|
39 |
+
}
|
@@ -8,6 +8,8 @@ use \WebPExpress\PathHelper;
|
|
8 |
include_once "FileHelper.php";
|
9 |
use \WebPExpress\FileHelper;
|
10 |
|
|
|
|
|
11 |
class Paths
|
12 |
{
|
13 |
|
@@ -252,7 +254,7 @@ APACHE
|
|
252 |
|
253 |
public static function getPluginDirAbs()
|
254 |
{
|
255 |
-
return
|
256 |
}
|
257 |
|
258 |
public static function getPluginDirRel()
|
@@ -274,7 +276,7 @@ APACHE
|
|
274 |
|
275 |
public static function getWebPExpressPluginDirAbs()
|
276 |
{
|
277 |
-
return
|
278 |
}
|
279 |
|
280 |
public static function getAbsDirId($absDir) {
|
@@ -379,7 +381,7 @@ APACHE
|
|
379 |
|
380 |
|
381 |
/**
|
382 |
-
* Get Url to plugin (this is in fact an incomplete URL, you need to append ie '/webp-on-demand.php' to get a full URL)
|
383 |
*/
|
384 |
public static function getPluginUrl()
|
385 |
{
|
@@ -433,18 +435,17 @@ APACHE
|
|
433 |
];
|
434 |
}
|
435 |
|
436 |
-
|
437 |
-
public static function getAdminUrl()
|
438 |
{
|
439 |
-
if (!function_exists('
|
440 |
require_once ABSPATH . 'wp-includes/link-template.php';
|
441 |
}
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
}
|
449 |
|
450 |
}
|
8 |
include_once "FileHelper.php";
|
9 |
use \WebPExpress\FileHelper;
|
10 |
|
11 |
+
use \WebPExpress\Multisite;
|
12 |
+
|
13 |
class Paths
|
14 |
{
|
15 |
|
254 |
|
255 |
public static function getPluginDirAbs()
|
256 |
{
|
257 |
+
return self::getAbsDir(WP_PLUGIN_DIR);
|
258 |
}
|
259 |
|
260 |
public static function getPluginDirRel()
|
276 |
|
277 |
public static function getWebPExpressPluginDirAbs()
|
278 |
{
|
279 |
+
return self::getAbsDir(WEBPEXPRESS_PLUGIN_DIR);
|
280 |
}
|
281 |
|
282 |
public static function getAbsDirId($absDir) {
|
381 |
|
382 |
|
383 |
/**
|
384 |
+
* Get Url to WebP Express plugin (this is in fact an incomplete URL, you need to append ie '/webp-on-demand.php' to get a full URL)
|
385 |
*/
|
386 |
public static function getPluginUrl()
|
387 |
{
|
435 |
];
|
436 |
}
|
437 |
|
438 |
+
public static function getSettingsUrl()
|
|
|
439 |
{
|
440 |
+
if (!function_exists('admin_url')) {
|
441 |
require_once ABSPATH . 'wp-includes/link-template.php';
|
442 |
}
|
443 |
+
if (Multisite::isNetworkActivated()) {
|
444 |
+
// network_admin_url is also defined in link-template.php.
|
445 |
+
return network_admin_url('settings.php?page=webp_express_settings_page');
|
446 |
+
} else {
|
447 |
+
return admin_url('options-general.php?page=webp_express_settings_page');
|
448 |
+
}
|
449 |
}
|
450 |
|
451 |
}
|
@@ -2,6 +2,8 @@
|
|
2 |
|
3 |
namespace WebPExpress;
|
4 |
|
|
|
|
|
5 |
/**
|
6 |
* Store state in db
|
7 |
* We are using update_option WITHOUT autoloading.
|
@@ -9,12 +11,13 @@ namespace WebPExpress;
|
|
9 |
* For such things, use update_option / get_option directly
|
10 |
*/
|
11 |
|
|
|
12 |
class State
|
13 |
{
|
14 |
|
15 |
public static function getStateObj() {
|
16 |
// TODO: cache
|
17 |
-
$json =
|
18 |
return json_decode($json, true);
|
19 |
}
|
20 |
|
@@ -37,6 +40,6 @@ class State
|
|
37 |
$json = json_encode($currentStateObj, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
|
38 |
|
39 |
// Store in db. No autoloading.
|
40 |
-
|
41 |
}
|
42 |
}
|
2 |
|
3 |
namespace WebPExpress;
|
4 |
|
5 |
+
use \WebPExpress\Option;
|
6 |
+
|
7 |
/**
|
8 |
* Store state in db
|
9 |
* We are using update_option WITHOUT autoloading.
|
11 |
* For such things, use update_option / get_option directly
|
12 |
*/
|
13 |
|
14 |
+
|
15 |
class State
|
16 |
{
|
17 |
|
18 |
public static function getStateObj() {
|
19 |
// TODO: cache
|
20 |
+
$json = Option::getOption('webp-express-state', '[]');
|
21 |
return json_decode($json, true);
|
22 |
}
|
23 |
|
40 |
$json = json_encode($currentStateObj, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
|
41 |
|
42 |
// Store in db. No autoloading.
|
43 |
+
Option::updateOption('webp-express-state', $json, false);
|
44 |
}
|
45 |
}
|
@@ -3,16 +3,16 @@
|
|
3 |
include_once __DIR__ . '/../classes/State.php';
|
4 |
use \WebPExpress\State;
|
5 |
|
6 |
-
use \WebPConvert\Converters\Ewww;
|
7 |
use \WebPExpress\Messenger;
|
8 |
use \WebPExpress\Config;
|
|
|
9 |
|
10 |
|
11 |
/*
|
12 |
In 0.4.0, we had a 'webp-express-configured' option.
|
13 |
As long as there are still users on 0.4 or below, we must do the following:
|
14 |
*/
|
15 |
-
if (
|
16 |
State::setState('configured', true);
|
17 |
}
|
18 |
|
@@ -21,8 +21,8 @@ In 0.1, we did not have the 'webp-express-configured' option.
|
|
21 |
To determine if WebP Express was configured in 0.1, we can test the (now obsolete) webp_express_converters option
|
22 |
As long as there are still users on 0.1, we must do the following:
|
23 |
*/
|
24 |
-
if (!
|
25 |
-
if (!is_null(
|
26 |
State::setState('configured', true);
|
27 |
}
|
28 |
}
|
@@ -31,11 +31,11 @@ if (!get_option('webp-express-configured', false)) {
|
|
31 |
if (!(State::getState('configured', false))) {
|
32 |
// Options has never has been saved, so no migration is needed.
|
33 |
// We can set migrate-version to current
|
34 |
-
|
35 |
} else {
|
36 |
|
37 |
-
for ($x = intval(
|
38 |
-
if (intval(
|
39 |
// run migration X+1, which upgrades from X to X+1
|
40 |
// It must take care of updating the "webp-express-migration-version" option to X+1, - if successful.
|
41 |
// If unsuccessful, it must leaves the option unaltered, which will prevent
|
@@ -46,30 +46,4 @@ if (!(State::getState('configured', false))) {
|
|
46 |
}
|
47 |
}
|
48 |
|
49 |
-
|
50 |
-
function webpexpress_keepEwwwSubscriptionAlive() {
|
51 |
-
include_once __DIR__ . '/../../vendor/autoload.php';
|
52 |
-
include_once __DIR__ . '/../classes/Messenger.php';
|
53 |
-
include_once __DIR__ . '/../classes/Config.php';
|
54 |
-
|
55 |
-
$config = Config::loadConfigAndFix(false);
|
56 |
-
foreach ($config['converters'] as $i => $converter) {
|
57 |
-
if (
|
58 |
-
($converter['converter'] == 'ewww') &&
|
59 |
-
(!(isset($converter['deactivated'])) || (!$converter['deactivated'])) &&
|
60 |
-
(isset($converter['options']['key'])))
|
61 |
-
{
|
62 |
-
$ewwwConvertResult = Ewww::keepSubscriptionAlive(__DIR__ . '/../../test/very-small.jpg', $converter['options']['key']);
|
63 |
-
|
64 |
-
if ($ewwwConvertResult === true) {
|
65 |
-
Messenger::addMessage(
|
66 |
-
'info',
|
67 |
-
'Successfully optimized regular jpg with <i>ewww</i> converter in order to keep the subscription alive'
|
68 |
-
);
|
69 |
-
}
|
70 |
-
}
|
71 |
-
}
|
72 |
-
}
|
73 |
-
|
74 |
-
// create
|
75 |
-
webpexpress_keepEwwwSubscriptionAlive();
|
3 |
include_once __DIR__ . '/../classes/State.php';
|
4 |
use \WebPExpress\State;
|
5 |
|
|
|
6 |
use \WebPExpress\Messenger;
|
7 |
use \WebPExpress\Config;
|
8 |
+
use \WebPExpress\Option;
|
9 |
|
10 |
|
11 |
/*
|
12 |
In 0.4.0, we had a 'webp-express-configured' option.
|
13 |
As long as there are still users on 0.4 or below, we must do the following:
|
14 |
*/
|
15 |
+
if (Option::getOption('webp-express-configured', false)) {
|
16 |
State::setState('configured', true);
|
17 |
}
|
18 |
|
21 |
To determine if WebP Express was configured in 0.1, we can test the (now obsolete) webp_express_converters option
|
22 |
As long as there are still users on 0.1, we must do the following:
|
23 |
*/
|
24 |
+
if (!Option::getOption('webp-express-configured', false)) {
|
25 |
+
if (!is_null(Option::getOption('webp_express_converters', null))) {
|
26 |
State::setState('configured', true);
|
27 |
}
|
28 |
}
|
31 |
if (!(State::getState('configured', false))) {
|
32 |
// Options has never has been saved, so no migration is needed.
|
33 |
// We can set migrate-version to current
|
34 |
+
Option::updateOption('webp-express-migration-version', WEBPEXPRESS_MIGRATION_VERSION);
|
35 |
} else {
|
36 |
|
37 |
+
for ($x = intval(Option::getOption('webp-express-migration-version', 0)); $x < WEBPEXPRESS_MIGRATION_VERSION; $x++) {
|
38 |
+
if (intval(Option::getOption('webp-express-migration-version', 0)) == $x) {
|
39 |
// run migration X+1, which upgrades from X to X+1
|
40 |
// It must take care of updating the "webp-express-migration-version" option to X+1, - if successful.
|
41 |
// If unsuccessful, it must leaves the option unaltered, which will prevent
|
46 |
}
|
47 |
}
|
48 |
|
49 |
+
//KeepEwwwSubscriptionAlive::keepAliveIfItIsTime($config);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -14,10 +14,11 @@ use \WebPExpress\Paths;
|
|
14 |
include_once __DIR__ . '/../classes/Messenger.php';
|
15 |
use \WebPExpress\Messenger;
|
16 |
|
17 |
-
|
|
|
18 |
|
19 |
// On successful migration:
|
20 |
-
//
|
21 |
|
22 |
function webp_express_migrate1_createFolders()
|
23 |
{
|
@@ -59,15 +60,15 @@ function webp_express_migrate1_createDummyConfigFiles()
|
|
59 |
|
60 |
function webpexpress_migrate1_migrateOptions()
|
61 |
{
|
62 |
-
$converters = json_decode(
|
63 |
foreach ($converters as &$converter) {
|
64 |
unset ($converter['id']);
|
65 |
}
|
66 |
|
67 |
$options = [
|
68 |
-
'image-types' => intval(
|
69 |
-
'max-quality' => intval(
|
70 |
-
'fail' =>
|
71 |
'converters' => $converters,
|
72 |
'forward-query-string' => true
|
73 |
];
|
@@ -168,7 +169,7 @@ function webpexpress_migrate1_deleteOldOptions() {
|
|
168 |
|
169 |
];
|
170 |
foreach ($optionsToDelete as $i => $optionName) {
|
171 |
-
|
172 |
}
|
173 |
}
|
174 |
|
@@ -199,7 +200,7 @@ if (webp_express_migrate1_createFolders()) {
|
|
199 |
if (webpexpress_migrate1_migrateOptions()) {
|
200 |
webpexpress_migrate1_deleteOldOptions();
|
201 |
webpexpress_migrate1_deleteOldWebPImages();
|
202 |
-
|
203 |
}
|
204 |
}
|
205 |
}
|
14 |
include_once __DIR__ . '/../classes/Messenger.php';
|
15 |
use \WebPExpress\Messenger;
|
16 |
|
17 |
+
use \WebPExpress\Option;
|
18 |
+
|
19 |
|
20 |
// On successful migration:
|
21 |
+
// Option::updateOption('webp-express-migration-version', '1', true);
|
22 |
|
23 |
function webp_express_migrate1_createFolders()
|
24 |
{
|
60 |
|
61 |
function webpexpress_migrate1_migrateOptions()
|
62 |
{
|
63 |
+
$converters = json_decode(Option::getOption('webp_express_converters', '[]'), true);
|
64 |
foreach ($converters as &$converter) {
|
65 |
unset ($converter['id']);
|
66 |
}
|
67 |
|
68 |
$options = [
|
69 |
+
'image-types' => intval(Option::getOption('webp_express_image_types_to_convert', 1)),
|
70 |
+
'max-quality' => intval(Option::getOption('webp_express_max_quality', 80)),
|
71 |
+
'fail' => Option::getOption('webp_express_failure_response', 'original'),
|
72 |
'converters' => $converters,
|
73 |
'forward-query-string' => true
|
74 |
];
|
169 |
|
170 |
];
|
171 |
foreach ($optionsToDelete as $i => $optionName) {
|
172 |
+
Option::deleteOption($optionName);
|
173 |
}
|
174 |
}
|
175 |
|
200 |
if (webpexpress_migrate1_migrateOptions()) {
|
201 |
webpexpress_migrate1_deleteOldOptions();
|
202 |
webpexpress_migrate1_deleteOldWebPImages();
|
203 |
+
Option::updateOption('webp-express-migration-version', '1');
|
204 |
}
|
205 |
}
|
206 |
}
|
@@ -11,6 +11,8 @@ use \WebPExpress\Messenger;
|
|
11 |
include_once __DIR__ . '/../classes/TestRun.php';
|
12 |
use \WebPExpress\TestRun;
|
13 |
|
|
|
|
|
14 |
/* helper. Remove dir recursively. No warnings - fails silently
|
15 |
Set $removeTheDirItself to false if you want to empty the dir
|
16 |
*/
|
@@ -68,4 +70,4 @@ Messenger::addMessage(
|
|
68 |
);
|
69 |
|
70 |
|
71 |
-
|
11 |
include_once __DIR__ . '/../classes/TestRun.php';
|
12 |
use \WebPExpress\TestRun;
|
13 |
|
14 |
+
use \WebPExpress\Option;
|
15 |
+
|
16 |
/* helper. Remove dir recursively. No warnings - fails silently
|
17 |
Set $removeTheDirItself to false if you want to empty the dir
|
18 |
*/
|
70 |
);
|
71 |
|
72 |
|
73 |
+
Option::updateOption('webp-express-migration-version', '2');
|
@@ -15,6 +15,7 @@ use \WebPExpress\PathHelper;
|
|
15 |
include_once __DIR__ . '/../classes/Messenger.php';
|
16 |
use \WebPExpress\Messenger;
|
17 |
|
|
|
18 |
|
19 |
if ( ! function_exists('webp_express_glob_recursive'))
|
20 |
{
|
@@ -120,7 +121,7 @@ function webpexpress_migrate3() {
|
|
120 |
|
121 |
|
122 |
// PSST: When creating new migration files, remember to update WEBPEXPRESS_MIGRATION_VERSION in admin.php
|
123 |
-
|
124 |
|
125 |
}
|
126 |
|
15 |
include_once __DIR__ . '/../classes/Messenger.php';
|
16 |
use \WebPExpress\Messenger;
|
17 |
|
18 |
+
use \WebPExpress\Option;
|
19 |
|
20 |
if ( ! function_exists('webp_express_glob_recursive'))
|
21 |
{
|
121 |
|
122 |
|
123 |
// PSST: When creating new migration files, remember to update WEBPEXPRESS_MIGRATION_VERSION in admin.php
|
124 |
+
Option::updateOption('webp-express-migration-version', '3');
|
125 |
|
126 |
}
|
127 |
|
@@ -9,6 +9,7 @@ use \WebPExpress\Config;
|
|
9 |
include_once __DIR__ . '/../classes/Messenger.php';
|
10 |
use \WebPExpress\Messenger;
|
11 |
|
|
|
12 |
|
13 |
function webpexpress_migrate4() {
|
14 |
$config = Config::loadConfig();
|
@@ -61,7 +62,7 @@ function webpexpress_migrate4() {
|
|
61 |
}
|
62 |
|
63 |
// PSST: When creating new migration files, remember to update WEBPEXPRESS_MIGRATION_VERSION in admin.php
|
64 |
-
|
65 |
|
66 |
}
|
67 |
|
9 |
include_once __DIR__ . '/../classes/Messenger.php';
|
10 |
use \WebPExpress\Messenger;
|
11 |
|
12 |
+
use \WebPExpress\Option;
|
13 |
|
14 |
function webpexpress_migrate4() {
|
15 |
$config = Config::loadConfig();
|
62 |
}
|
63 |
|
64 |
// PSST: When creating new migration files, remember to update WEBPEXPRESS_MIGRATION_VERSION in admin.php
|
65 |
+
Option::updateOption('webp-express-migration-version', '4');
|
66 |
|
67 |
}
|
68 |
|
@@ -12,6 +12,8 @@ use \WebPExpress\Messenger;
|
|
12 |
include_once __DIR__ . '/../classes/CacheMover.php';
|
13 |
use \WebPExpress\CacheMover;
|
14 |
|
|
|
|
|
15 |
function webpexpress_migrate5() {
|
16 |
|
17 |
// Regenerate configuration file and wod-options.json.
|
@@ -20,7 +22,7 @@ function webpexpress_migrate5() {
|
|
20 |
// By regenerating wod-options.json, we ensure that the new "paths" option is there, which is required in "mingled" mode for
|
21 |
// determining if an image resides in the uploads folder or not.
|
22 |
|
23 |
-
$config = Config::loadConfigAndFix();
|
24 |
if ($config['operation-mode'] == 'just-convert') {
|
25 |
$config['operation-mode'] = 'no-varied-responses';
|
26 |
}
|
@@ -37,16 +39,16 @@ function webpexpress_migrate5() {
|
|
37 |
|
38 |
Messenger::addMessage(
|
39 |
'info',
|
40 |
-
'Successfully migrated
|
41 |
);
|
42 |
|
43 |
// PSST: When creating new migration files, remember to update WEBPEXPRESS_MIGRATION_VERSION in admin.php
|
44 |
-
|
45 |
|
46 |
} else {
|
47 |
Messenger::addMessage(
|
48 |
'error',
|
49 |
-
'Failed migrating
|
50 |
);
|
51 |
}
|
52 |
|
12 |
include_once __DIR__ . '/../classes/CacheMover.php';
|
13 |
use \WebPExpress\CacheMover;
|
14 |
|
15 |
+
use \WebPExpress\Option;
|
16 |
+
|
17 |
function webpexpress_migrate5() {
|
18 |
|
19 |
// Regenerate configuration file and wod-options.json.
|
22 |
// By regenerating wod-options.json, we ensure that the new "paths" option is there, which is required in "mingled" mode for
|
23 |
// determining if an image resides in the uploads folder or not.
|
24 |
|
25 |
+
$config = Config::loadConfigAndFix(false); // false, because we do not need to test if quality detection is working
|
26 |
if ($config['operation-mode'] == 'just-convert') {
|
27 |
$config['operation-mode'] = 'no-varied-responses';
|
28 |
}
|
39 |
|
40 |
Messenger::addMessage(
|
41 |
'info',
|
42 |
+
'Successfully migrated <i>WebP Express</i> options for 0.11+'
|
43 |
);
|
44 |
|
45 |
// PSST: When creating new migration files, remember to update WEBPEXPRESS_MIGRATION_VERSION in admin.php
|
46 |
+
Option::updateOption('webp-express-migration-version', '5');
|
47 |
|
48 |
} else {
|
49 |
Messenger::addMessage(
|
50 |
'error',
|
51 |
+
'Failed migrating WebP Express options to 0.11+. Probably you need to grant write permissions in your wp-content folder.'
|
52 |
);
|
53 |
}
|
54 |
|
@@ -2,18 +2,11 @@
|
|
2 |
|
3 |
namespace WebPExpress;
|
4 |
|
5 |
-
|
6 |
-
include_once __DIR__ . '/../classes/Config.php';
|
7 |
use \WebPExpress\Config;
|
8 |
-
|
9 |
-
include_once __DIR__ . '/../classes/Messenger.php';
|
10 |
use \WebPExpress\Messenger;
|
11 |
-
|
12 |
-
include_once __DIR__ . '/../classes/HTAccess.php';
|
13 |
use \WebPExpress\HTAccess;
|
14 |
-
|
15 |
-
include_once __DIR__ . '/../classes/Paths.php';
|
16 |
use \WebPExpress\Paths;
|
|
|
17 |
|
18 |
/**
|
19 |
* Fix records - if possible
|
@@ -35,7 +28,7 @@ function webpexpress_migrate6() {
|
|
35 |
// Regenerate .htaccess file if placed in root (so rewrites does not apply in wp-admin area)
|
36 |
if (HTAccess::isInActiveHTAccessDirsArray('index')) {
|
37 |
if (Config::isConfigFileThere()) {
|
38 |
-
$config = Config::loadConfigAndFix();
|
39 |
|
40 |
$rules = HTAccess::generateHTAccessRulesFromConfigObj($config, 'index');
|
41 |
$success = (HTAccess::saveHTAccessRulesToFile(Paths::getIndexDirAbs() . '/.htaccess', $rules, true));
|
@@ -69,7 +62,7 @@ function webpexpress_migrate6() {
|
|
69 |
webpexpress_migrate6_fixHtaccessRecordsForDir($dirId);
|
70 |
}
|
71 |
|
72 |
-
|
73 |
}
|
74 |
|
75 |
webpexpress_migrate6();
|
2 |
|
3 |
namespace WebPExpress;
|
4 |
|
|
|
|
|
5 |
use \WebPExpress\Config;
|
|
|
|
|
6 |
use \WebPExpress\Messenger;
|
|
|
|
|
7 |
use \WebPExpress\HTAccess;
|
|
|
|
|
8 |
use \WebPExpress\Paths;
|
9 |
+
use \WebPExpress\Option;
|
10 |
|
11 |
/**
|
12 |
* Fix records - if possible
|
28 |
// Regenerate .htaccess file if placed in root (so rewrites does not apply in wp-admin area)
|
29 |
if (HTAccess::isInActiveHTAccessDirsArray('index')) {
|
30 |
if (Config::isConfigFileThere()) {
|
31 |
+
$config = Config::loadConfigAndFix(false); // false, because we do not need to test if quality detection is working
|
32 |
|
33 |
$rules = HTAccess::generateHTAccessRulesFromConfigObj($config, 'index');
|
34 |
$success = (HTAccess::saveHTAccessRulesToFile(Paths::getIndexDirAbs() . '/.htaccess', $rules, true));
|
62 |
webpexpress_migrate6_fixHtaccessRecordsForDir($dirId);
|
63 |
}
|
64 |
|
65 |
+
Option::updateOption('webp-express-migration-version', '6');
|
66 |
}
|
67 |
|
68 |
webpexpress_migrate6();
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WebPExpress;
|
4 |
+
|
5 |
+
use \WebPExpress\Config;
|
6 |
+
use \WebPExpress\HTAccess;
|
7 |
+
use \WebPExpress\Messenger;
|
8 |
+
use \WebPExpress\CapabilityTest;
|
9 |
+
|
10 |
+
function webpexpress_migrate7() {
|
11 |
+
|
12 |
+
$config = Config::loadConfigAndFix(false); // false, because we do not need to test if quality detection is working
|
13 |
+
if ($config['operation-mode'] == 'just-redirect') {
|
14 |
+
$config['operation-mode'] = 'no-conversion';
|
15 |
+
}
|
16 |
+
if ($config['operation-mode'] == 'no-varied-responses') {
|
17 |
+
$config['operation-mode'] = 'cdn-friendly';
|
18 |
+
}
|
19 |
+
if ($config['operation-mode'] == 'varied-responses') {
|
20 |
+
$config['operation-mode'] = 'varied-image-responses';
|
21 |
+
}
|
22 |
+
if (isset($config['do-not-pass-source-in-query-string'])) {
|
23 |
+
unset($config['do-not-pass-source-in-query-string']);
|
24 |
+
}
|
25 |
+
|
26 |
+
// Migrate some configurations to the new "No conversion" mode
|
27 |
+
if ((!$config['enable-redirection-to-webp-realizer']) && (!$config['enable-redirection-to-converter']) && ($config['destination-folder'] == 'mingled') && ($config['operation-mode'] == 'cdn-friendly') && (!($config['web-service']['enabled']))) {
|
28 |
+
$config['operation-mode'] = 'no-conversion';
|
29 |
+
}
|
30 |
+
|
31 |
+
// In next migration, we can remove do-not-pass-source-in-query-string
|
32 |
+
// unset($config['do-not-pass-source-in-query-string']);
|
33 |
+
// and also do: grep -r 'do-not-pass' .
|
34 |
+
|
35 |
+
if (Config::saveConfigurationFileAndWodOptions($config)) {
|
36 |
+
|
37 |
+
$msg = 'Successfully migrated <i>WebP Express</i> options for 0.12. ';
|
38 |
+
// The webp realizer rules where errornous, so recreate rules, if neccessary. (see issue #195)
|
39 |
+
|
40 |
+
if (($config['enable-redirection-to-webp-realizer']) && ($config['destination-folder'] != 'mingled')) {
|
41 |
+
HTAccess::saveRules($config);
|
42 |
+
$msg .= 'Also fixed <a target="_blank" href="https://github.com/rosell-dk/webp-express/issues/195">buggy</a> <i>.htaccess</i> rules. ';
|
43 |
+
}
|
44 |
+
|
45 |
+
if (!$config['alter-html']['enabled']) {
|
46 |
+
if ($config['operation-mode'] == 'varied-responses') {
|
47 |
+
$msg .= '<br>In WebP Express 0.12, the <i>Alter HTML</i> option is no longer in beta. ' .
|
48 |
+
'<i>You should consider to go and <a href="' . Paths::getSettingsUrl() . '">activate it</a></i> - ' .
|
49 |
+
'It works great in <i>Varied Image Responses</i> mode too. ';
|
50 |
+
} else {
|
51 |
+
$msg .= '<br>In WebP Express 0.12, Alter HTML is no longer in beta. ' .
|
52 |
+
'<i>Now would be a good time to <a href="' . Paths::getSettingsUrl() . '">go and activate it!</a></i>. ';
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
// Display announcement. But only show while it is fresh news (we don't want this to show when one is upgrading from 0.11 to 0.14 or something)
|
57 |
+
// - the next release with a migration in it will not show the announcement
|
58 |
+
if (WEBPEXPRESS_MIGRATION_VERSION == 7) {
|
59 |
+
$msg .= '<br><br>Btw: From this release and onward, WebP Express is <i>multisite compliant</i>.';
|
60 |
+
}
|
61 |
+
|
62 |
+
Messenger::addMessage(
|
63 |
+
'info',
|
64 |
+
$msg
|
65 |
+
);
|
66 |
+
|
67 |
+
if ($config['operation-mode'] == 'no-conversion') {
|
68 |
+
Messenger::addMessage(
|
69 |
+
'info',
|
70 |
+
'WebP Express introduces a new operation mode: "No conversion". ' .
|
71 |
+
'Your configuration has been migrated to this mode, because your previous settings matched that mode (nothing where set up to trigger a conversion).'
|
72 |
+
);
|
73 |
+
}
|
74 |
+
|
75 |
+
// PSST: When creating new migration files, remember to update WEBPEXPRESS_MIGRATION_VERSION in admin.php
|
76 |
+
Option::updateOption('webp-express-migration-version', '7');
|
77 |
+
|
78 |
+
|
79 |
+
CapabilityTest::copyCapabilityTestsToWpContent();
|
80 |
+
|
81 |
+
// Not completely sure if this could fail miserably, so commented out.
|
82 |
+
// We should probably do it in upcoming migrations
|
83 |
+
// \WebPExpress\KeepEwwwSubscriptionAlive::keepAliveIfItIsTime($config);
|
84 |
+
|
85 |
+
} else {
|
86 |
+
Messenger::addMessage(
|
87 |
+
'error',
|
88 |
+
'Failed migrating webp express options to 0.12+. Probably you need to grant write permissions in your wp-content folder.'
|
89 |
+
);
|
90 |
+
}
|
91 |
+
|
92 |
+
}
|
93 |
+
|
94 |
+
webpexpress_migrate7();
|
@@ -20,12 +20,12 @@
|
|
20 |
}*/
|
21 |
|
22 |
@media (min-width: 782px) {
|
23 |
-
#webpexpress_settings .form-table th {
|
24 |
padding-top: 5px;
|
25 |
padding-bottom: 5px;
|
26 |
width: 200px;
|
27 |
}
|
28 |
-
#webpexpress_settings .form-table td {
|
29 |
padding-top: 1px;
|
30 |
padding-bottom: 5px;
|
31 |
}
|
@@ -428,6 +428,133 @@
|
|
428 |
font-style: italic;
|
429 |
}
|
430 |
|
|
|
431 |
#alter_html_options_div > div {
|
432 |
margin-top: 15px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
433 |
}
|
20 |
}*/
|
21 |
|
22 |
@media (min-width: 782px) {
|
23 |
+
#webpexpress_settings .form-table > tbody > tr > th {
|
24 |
padding-top: 5px;
|
25 |
padding-bottom: 5px;
|
26 |
width: 200px;
|
27 |
}
|
28 |
+
#webpexpress_settings .form-table > tbody > tr > td {
|
29 |
padding-top: 1px;
|
30 |
padding-bottom: 5px;
|
31 |
}
|
428 |
font-style: italic;
|
429 |
}
|
430 |
|
431 |
+
/*
|
432 |
#alter_html_options_div > div {
|
433 |
margin-top: 15px;
|
434 |
+
}*/
|
435 |
+
|
436 |
+
.form-table table th {
|
437 |
+
font-weight: unset;
|
438 |
+
padding: 5px 0px;
|
439 |
+
width: auto;
|
440 |
+
}
|
441 |
+
|
442 |
+
.form-table table td {
|
443 |
+
padding: 0 10px;
|
444 |
+
width: auto;
|
445 |
+
}
|
446 |
+
|
447 |
+
|
448 |
+
.form-table td input[type=checkbox] {
|
449 |
+
margin-top: 6px;
|
450 |
+
}
|
451 |
+
|
452 |
+
.form-table h2 {
|
453 |
+
/*font-size: 1.6em;*/
|
454 |
+
text-transform: uppercase;
|
455 |
+
color: #222;
|
456 |
+
}
|
457 |
+
.form-table th[colspan='2'] {
|
458 |
+
font-weight: normal;
|
459 |
+
font-size: 14px;
|
460 |
+
}
|
461 |
+
.form-table th.header-section h2 {
|
462 |
+
margin-top: 30px;
|
463 |
+
margin-bottom: 10px;
|
464 |
+
}
|
465 |
+
.form-table th.header-section h2 + p {
|
466 |
+
margin-top: 10px;
|
467 |
+
}
|
468 |
+
.form-table th.header-section p,
|
469 |
+
.form-table th.header-section h2,
|
470 |
+
fieldset.block p,
|
471 |
+
fieldset.block div.p {
|
472 |
+
max-width: 750px;
|
473 |
+
}
|
474 |
+
|
475 |
+
.toggler.effect-slider {
|
476 |
+
overflow-y: hidden;
|
477 |
+
transition: all 0.3s ease-in-out;
|
478 |
+
/*transition: all 0.5s cubic-bezier(0, 1, 0.5, 1);*/
|
479 |
+
}
|
480 |
+
.toggler.effect-slider.closed {
|
481 |
+
transition: all 0.5s cubic-bezier(0, 1, 0.5, 1);
|
482 |
+
max-height: 0px !important;
|
483 |
+
}
|
484 |
+
|
485 |
+
.toggler.effect-opacity.closed {
|
486 |
+
opacity: 0.5;
|
487 |
+
pointer-events: none;
|
488 |
+
font-weight: 300 !important;
|
489 |
+
}
|
490 |
+
.form-table .toggler.effect-opacity.closed th {
|
491 |
+
font-weight: 400 !important;
|
492 |
+
}
|
493 |
+
|
494 |
+
.toggler.effect-visibility {
|
495 |
+
/*position: static;
|
496 |
+
visibility: inherit;*/
|
497 |
+
}
|
498 |
+
.toggler.effect-visibility.closed {
|
499 |
+
visibility: hidden;
|
500 |
+
position: absolute;
|
501 |
+
}
|
502 |
+
|
503 |
+
.form-table h4 {
|
504 |
+
margin-bottom: 0;
|
505 |
+
text-decoration: underline;
|
506 |
+
}
|
507 |
+
|
508 |
+
table.designed {
|
509 |
+
border-collapse: collapse;
|
510 |
+
margin-bottom: 20px;
|
511 |
+
/*box-shadow: 2px 2px 5px 2px rgba(0, 0, 0, 0.1)*/
|
512 |
+
}
|
513 |
+
table.designed th {
|
514 |
+
font-weight: bold;
|
515 |
+
background-color: #fff;
|
516 |
+
}
|
517 |
+
table.designed td,
|
518 |
+
table.designed th {
|
519 |
+
text-align: left;
|
520 |
+
padding: 9px 17px;
|
521 |
+
border: 1px solid #999;
|
522 |
+
vertical-align: top;
|
523 |
+
}
|
524 |
+
table.designed td,
|
525 |
+
table.designed th,
|
526 |
+
table.designed p {
|
527 |
+
font-size: 12px;
|
528 |
+
line-height: 1.3;
|
529 |
+
}
|
530 |
+
table.designed td > p:first-child {
|
531 |
+
margin-top: 0;
|
532 |
+
}
|
533 |
+
table.designed tr:nth-child(odd) > td {
|
534 |
+
background-color: #eee;
|
535 |
+
}
|
536 |
+
table.designed tr:nth-child(even) > td {
|
537 |
+
background-color: #ddd;
|
538 |
+
}
|
539 |
+
table.designed th:first-child {
|
540 |
+
border-left-width: 0;
|
541 |
+
}
|
542 |
+
table.designed tr:first-child > th {
|
543 |
+
border-top-width: 0;
|
544 |
+
}
|
545 |
+
table.designed tr > *:last-child {
|
546 |
+
border-right-width: 0;
|
547 |
+
}
|
548 |
+
|
549 |
+
#hide_alterhtml_chart_btn {
|
550 |
+
margin-bottom: 20px;
|
551 |
+
}
|
552 |
+
|
553 |
+
/*table.designed tr:last-child > * {
|
554 |
+
border-bottom-width: 0;
|
555 |
+
}*/
|
556 |
+
|
557 |
+
ul.with-bullets {
|
558 |
+
padding-left: 20px;
|
559 |
+
list-style: unset;
|
560 |
}
|
@@ -6,16 +6,20 @@ use \WebPExpress\Paths;
|
|
6 |
include_once __DIR__ . '/../classes/Config.php';
|
7 |
use \WebPExpress\Config;
|
8 |
|
9 |
-
$version = '0.
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
wp_add_inline_script
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
17 |
}
|
18 |
}
|
|
|
19 |
wp_register_script('sortable', plugins_url('js/sortable.min.js', __FILE__), [], '1.9.0');
|
20 |
wp_enqueue_script('sortable');
|
21 |
|
@@ -24,7 +28,7 @@ wp_enqueue_script('daspopup');
|
|
24 |
|
25 |
$config = Config::getConfigForOptionsPage();
|
26 |
|
27 |
-
if (!(isset($config['operation-mode']) && $config['operation-mode'] == '
|
28 |
|
29 |
// Remove empty options arrays.
|
30 |
// These cause trouble in json because they are encoded as [] rather than {}
|
6 |
include_once __DIR__ . '/../classes/Config.php';
|
7 |
use \WebPExpress\Config;
|
8 |
|
9 |
+
$version = '0.12.0';
|
10 |
+
|
11 |
+
|
12 |
+
if (!function_exists('webp_express_add_inline_script')) {
|
13 |
+
function webp_express_add_inline_script($id, $script, $position) {
|
14 |
+
if (function_exists('wp_add_inline_script')) {
|
15 |
+
// wp_add_inline_script is available from Wordpress 4.5
|
16 |
+
wp_add_inline_script($id, $script, $position);
|
17 |
+
} else {
|
18 |
+
echo '<script>' . $script . '</script>';
|
19 |
+
}
|
20 |
}
|
21 |
}
|
22 |
+
|
23 |
wp_register_script('sortable', plugins_url('js/sortable.min.js', __FILE__), [], '1.9.0');
|
24 |
wp_enqueue_script('sortable');
|
25 |
|
28 |
|
29 |
$config = Config::getConfigForOptionsPage();
|
30 |
|
31 |
+
if (!(isset($config['operation-mode']) && $config['operation-mode'] == 'no-conversion')) {
|
32 |
|
33 |
// Remove empty options arrays.
|
34 |
// These cause trouble in json because they are encoded as [] rather than {}
|
@@ -1,156 +1,200 @@
|
|
1 |
-
function
|
2 |
var elm = document.getElementById(elmId);
|
3 |
if (!elm) {
|
4 |
return;
|
5 |
}
|
|
|
|
|
|
|
|
|
|
|
6 |
if (show) {
|
7 |
-
elm.
|
8 |
-
elm.style['position'] = 'static';
|
9 |
} else {
|
10 |
-
elm.
|
11 |
-
elm.style['position'] = 'absolute';
|
12 |
}
|
13 |
}
|
14 |
|
15 |
-
function
|
16 |
-
|
17 |
-
|
18 |
}
|
19 |
-
}
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
}
|
25 |
-
}
|
26 |
|
27 |
|
|
|
|
|
|
|
28 |
|
29 |
-
function updateCacheControlCustomVisibility() {
|
30 |
|
31 |
-
|
32 |
-
// Well, it seems that the cache control option isn't available in this operation mode
|
33 |
-
return;
|
34 |
-
}
|
35 |
-
if (document.getElementById('cache_control_custom') == null) {
|
36 |
-
alert('document.getElementById("cache_control_custom") returns null. Strange! Please report.');
|
37 |
-
return;
|
38 |
-
}
|
39 |
-
if (document.getElementById('cache_control_public') == null) {
|
40 |
-
alert('document.getElementById("cache_control_public") returns null. Strange! Please report.');
|
41 |
-
return;
|
42 |
-
}
|
43 |
|
44 |
-
var cacheControlValue = document.getElementById('cache_control_select').value;
|
45 |
-
/*
|
46 |
-
var customEl = document.getElementById('cache_control_custom');
|
47 |
-
if (cacheControlValue == 'custom') {
|
48 |
-
customEl.setAttribute('type', 'text');
|
49 |
-
} else {
|
50 |
-
customEl.setAttribute('type', 'hidden');
|
51 |
-
}*/
|
52 |
|
53 |
-
setOptionVisibility('cache_control_custom_div', (cacheControlValue == 'custom'));
|
54 |
|
55 |
-
|
|
|
|
|
|
|
|
|
56 |
|
57 |
-
|
|
|
|
|
|
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
//alert(qualityAutoValue);
|
69 |
-
if (qualityAutoValue == 'auto_on') {
|
70 |
-
maxQualityRowEl.style['display'] = 'table-row';
|
71 |
-
qualitySpecificRowEl.style['display'] = 'none';
|
72 |
-
} else {
|
73 |
-
maxQualityRowEl.style['display'] = 'none';
|
74 |
-
qualitySpecificRowEl.style['display'] = 'table-row';
|
75 |
-
}
|
76 |
-
}
|
77 |
|
78 |
-
|
79 |
-
var destinationFolderEl = document.getElementById('destination_folder');
|
80 |
-
if (!destinationFolderEl) {
|
81 |
-
return;
|
82 |
-
}
|
83 |
-
var destinationFolderValue = destinationFolderEl.value;
|
84 |
-
var destinationExtensionEl = document.getElementById('destination_extension_row');
|
85 |
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
91 |
}
|
92 |
|
93 |
-
}
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
}
|
100 |
-
var enabled = enabledEl.checked;
|
101 |
-
//document.getElementById('whitelist_row').style['display'] = (enabled ? 'table-row' : 'none');
|
102 |
-
//document.getElementById('server_url').style['display'] = (enabled ? 'table-row' : 'none');
|
103 |
-
document.getElementById('whitelist_div').style['display'] = (enabled ? 'block' : 'none');
|
104 |
-
}
|
105 |
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
updateCacheControlCustomVisibility();
|
118 |
});
|
119 |
}
|
120 |
|
121 |
-
|
122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
updateQualityVisibility();
|
124 |
});
|
125 |
}
|
126 |
|
127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
document.getElementById('destination_folder').addEventListener('change', function() {
|
129 |
updateDestinationExtensionVisibility();
|
130 |
});
|
131 |
}
|
132 |
|
133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
document.getElementById('web_service_enabled').addEventListener('change', function() {
|
135 |
updateServerSettingsVisibility();
|
136 |
});
|
137 |
}
|
138 |
|
139 |
-
|
140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
updateAlterHTMLVisibility();
|
142 |
});
|
143 |
}
|
144 |
|
145 |
-
|
146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
updateAlterHTMLReplaceVisibility();
|
148 |
});
|
149 |
-
|
150 |
updateAlterHTMLReplaceVisibility();
|
151 |
});
|
152 |
}
|
153 |
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
|
155 |
|
156 |
document.getElementById('change_operation_mode').addEventListener('change', function() {
|
1 |
+
function toggleVisibility(elmId, show) {
|
2 |
var elm = document.getElementById(elmId);
|
3 |
if (!elm) {
|
4 |
return;
|
5 |
}
|
6 |
+
elm.classList.add('toggler');
|
7 |
+
/*
|
8 |
+
if (!elm.style.maxHeight) {
|
9 |
+
elm.style['maxHeight'] = (elm.clientHeight + 40) + 'px';
|
10 |
+
}*/
|
11 |
if (show) {
|
12 |
+
elm.classList.remove('closed');
|
|
|
13 |
} else {
|
14 |
+
elm.classList.add('closed');
|
|
|
15 |
}
|
16 |
}
|
17 |
|
18 |
+
function updateAlterHTMLChartVisibility(show) {
|
19 |
+
function el(elmId) {
|
20 |
+
return document.getElementById(elmId);
|
21 |
}
|
|
|
22 |
|
23 |
+
|
24 |
+
var elm = el('alter_html_comparison_chart');
|
25 |
+
//elm.style['maxHeight'] = (elm.clientHeight + 40) + 'px';
|
26 |
+
//elm.style['maxHeight'] = '600px';
|
27 |
+
//elm.style.display = (show ? 'block' : 'none');
|
28 |
+
if (show) {
|
29 |
+
elm.classList.remove('closed');
|
30 |
+
} else {
|
31 |
+
elm.classList.add('closed');
|
32 |
}
|
|
|
33 |
|
34 |
|
35 |
+
el('hide_alterhtml_chart_btn').style.display = (show ? 'block' : 'none');
|
36 |
+
el('show_alterhtml_chart_btn').style.display = (show ? 'none' : 'inline-block');
|
37 |
+
el('ui_show_alter_html_chart').value = (show ? 'true' : 'false');
|
38 |
|
|
|
39 |
|
40 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
|
|
43 |
|
44 |
+
document.addEventListener('DOMContentLoaded', function() {
|
45 |
+
//resetToDefaultConverters();
|
46 |
+
function el(elmId) {
|
47 |
+
return document.getElementById(elmId);
|
48 |
+
}
|
49 |
|
50 |
+
if (el('cache_control_select') && el('cache_control_custom_div') && el('cache_control_set_div')) {
|
51 |
+
el('cache_control_custom_div').classList.add('effect-visibility');
|
52 |
+
el('cache_control_set_div').classList.add('effect-visibility');
|
53 |
+
function updateCacheControlCustomVisibility() {
|
54 |
|
55 |
+
var cacheControlValue = document.getElementById('cache_control_select').value;
|
56 |
+
/*
|
57 |
+
var customEl = document.getElementById('cache_control_custom');
|
58 |
+
if (cacheControlValue == 'custom') {
|
59 |
+
customEl.setAttribute('type', 'text');
|
60 |
+
} else {
|
61 |
+
customEl.setAttribute('type', 'hidden');
|
62 |
+
}*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
+
toggleVisibility('cache_control_custom_div', (cacheControlValue == 'custom'));
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
+
toggleVisibility('cache_control_set_div', (cacheControlValue == 'set'));
|
67 |
+
|
68 |
+
}
|
69 |
+
updateCacheControlCustomVisibility();
|
70 |
+
el('cache_control_select').addEventListener('change', function() {
|
71 |
+
updateCacheControlCustomVisibility();
|
72 |
+
});
|
73 |
}
|
74 |
|
|
|
75 |
|
76 |
+
// In "No conversion" and "CDN friendly" mode, toggle cache control div when redirect is enabled/disabled
|
77 |
+
if (el('operation_mode') && (el('operation_mode').value == 'no-conversion')) {
|
78 |
+
if (el('redirect_to_existing_in_htaccess') && el('cache_control_div')) {
|
79 |
+
el('cache_control_div').classList.add('effect-opacity');
|
80 |
+
function updateCacheControlHeaderVisibility() {
|
81 |
+
toggleVisibility('cache_control_div', el('redirect_to_existing_in_htaccess').checked);
|
82 |
+
}
|
83 |
+
updateCacheControlHeaderVisibility();
|
84 |
+
el('redirect_to_existing_in_htaccess').addEventListener('change', function() {
|
85 |
+
updateCacheControlHeaderVisibility();
|
86 |
+
});
|
87 |
+
}
|
88 |
}
|
|
|
|
|
|
|
|
|
|
|
89 |
|
90 |
+
if (el('only_redirect_to_converter_for_webp_enabled_browsers_row') && el('enable_redirection_to_converter')) {
|
91 |
+
el('only_redirect_to_converter_for_webp_enabled_browsers_row').classList.add('effect-opacity');
|
92 |
+
el('only_redirect_to_converter_on_cache_miss_row').classList.add('effect-opacity');
|
93 |
+
function updateRedirectionOnlyWebPVisibility() {
|
94 |
+
toggleVisibility('only_redirect_to_converter_for_webp_enabled_browsers_row', el('enable_redirection_to_converter').checked);
|
95 |
+
toggleVisibility('only_redirect_to_converter_on_cache_miss_row', el('enable_redirection_to_converter').checked);
|
96 |
+
|
97 |
+
}
|
98 |
+
updateRedirectionOnlyWebPVisibility();
|
99 |
+
el('enable_redirection_to_converter').addEventListener('change', function() {
|
100 |
+
updateRedirectionOnlyWebPVisibility();
|
|
|
101 |
});
|
102 |
}
|
103 |
|
104 |
+
|
105 |
+
// Toggle Quality (auto / specific)
|
106 |
+
if (el('quality_auto_select') && el('max_quality_row') && el('quality_specific_row')) {
|
107 |
+
function updateQualityVisibility() {
|
108 |
+
var qualityAutoValue = el('quality_auto_select').value;
|
109 |
+
if (qualityAutoValue == 'auto_on') {
|
110 |
+
el('max_quality_row').style['display'] = 'table-row';
|
111 |
+
el('quality_specific_row').style['display'] = 'none';
|
112 |
+
} else {
|
113 |
+
el('max_quality_row').style['display'] = 'none';
|
114 |
+
el('quality_specific_row').style['display'] = 'table-row';
|
115 |
+
}
|
116 |
+
}
|
117 |
+
updateQualityVisibility();
|
118 |
+
el('quality_auto_select').addEventListener('change', function() {
|
119 |
updateQualityVisibility();
|
120 |
});
|
121 |
}
|
122 |
|
123 |
+
// Toggle File Extension (only show when "mingled" is selected)
|
124 |
+
if (el('destination_folder') && el('destination_extension_row') && el('destination_extension')) {
|
125 |
+
el('destination_extension_row').classList.add('effect-opacity');
|
126 |
+
function updateDestinationExtensionVisibility() {
|
127 |
+
toggleVisibility('destination_extension_row', el('destination_folder').value == 'mingled');
|
128 |
+
|
129 |
+
if (el('destination_folder').value == 'separate') {
|
130 |
+
el('destination_extension').value = 'append';
|
131 |
+
}
|
132 |
+
/*
|
133 |
+
if (document.getElementById('destination_folder').value == 'mingled') {
|
134 |
+
el('destination_extension_row').style['display'] = 'table-row';
|
135 |
+
} else {
|
136 |
+
el('destination_extension_row').style['display'] = 'none';
|
137 |
+
}*/
|
138 |
+
|
139 |
+
}
|
140 |
+
updateDestinationExtensionVisibility();
|
141 |
document.getElementById('destination_folder').addEventListener('change', function() {
|
142 |
updateDestinationExtensionVisibility();
|
143 |
});
|
144 |
}
|
145 |
|
146 |
+
// Toggle webservice
|
147 |
+
if (el('web_service_enabled') && el('whitelist_div')) {
|
148 |
+
el('whitelist_div').classList.add('effect-opacity');
|
149 |
+
function updateServerSettingsVisibility() {
|
150 |
+
toggleVisibility('whitelist_div', el('web_service_enabled').checked);
|
151 |
+
//document.getElementById('whitelist_div').style['display'] = (el('web_service_enabled').checked ? 'block' : 'none');
|
152 |
+
}
|
153 |
+
updateServerSettingsVisibility();
|
154 |
document.getElementById('web_service_enabled').addEventListener('change', function() {
|
155 |
updateServerSettingsVisibility();
|
156 |
});
|
157 |
}
|
158 |
|
159 |
+
// Toggle Alter HTML options
|
160 |
+
if (el('alter_html_enabled') && (el('alter_html_options_div'))) {
|
161 |
+
el('alter_html_options_div').classList.add('effect-opacity');
|
162 |
+
el('alter_html_comparison_chart').classList.add('effect-slider');
|
163 |
+
function updateAlterHTMLVisibility() {
|
164 |
+
toggleVisibility('alter_html_options_div', el('alter_html_enabled').checked);
|
165 |
+
// toggleVisibility('alter_html_comparison_chart', el('alter_html_enabled').checked);
|
166 |
+
|
167 |
+
}
|
168 |
+
updateAlterHTMLVisibility();
|
169 |
+
el('alter_html_enabled').addEventListener('change', function() {
|
170 |
updateAlterHTMLVisibility();
|
171 |
});
|
172 |
}
|
173 |
|
174 |
+
// Show/hide "Only do the replacements in webp enabled browsers" when "What to replace" is changed
|
175 |
+
if (el('alter_html_replacement_url') && el('alter_html_url_options_div')) {
|
176 |
+
el('alter_html_url_options_div').classList.add('effect-opacity');
|
177 |
+
el('alter_html_picture_options_div').classList.add('effect-opacity');
|
178 |
+
function updateAlterHTMLReplaceVisibility() {
|
179 |
+
toggleVisibility('alter_html_url_options_div', el('alter_html_replacement_url').checked);
|
180 |
+
toggleVisibility('alter_html_picture_options_div', el('alter_html_replacement_picture').checked);
|
181 |
+
}
|
182 |
+
updateAlterHTMLReplaceVisibility();
|
183 |
+
|
184 |
+
el('alter_html_replacement_url').addEventListener('change', function() {
|
185 |
updateAlterHTMLReplaceVisibility();
|
186 |
});
|
187 |
+
el('alter_html_replacement_picture').addEventListener('change', function() {
|
188 |
updateAlterHTMLReplaceVisibility();
|
189 |
});
|
190 |
}
|
191 |
|
192 |
+
if (el('ui_show_alter_html_chart') && el('alter_html_comparison_chart')) {
|
193 |
+
var elm = el('alter_html_comparison_chart');
|
194 |
+
elm.style['maxHeight'] = (elm.clientHeight + 80) + 'px';
|
195 |
+
|
196 |
+
updateAlterHTMLChartVisibility(el('ui_show_alter_html_chart').value == 'true');
|
197 |
+
}
|
198 |
|
199 |
|
200 |
document.getElementById('change_operation_mode').addEventListener('change', function() {
|
@@ -1,16 +1,30 @@
|
|
1 |
<?php
|
|
|
|
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
add_action('admin_post_webpexpress_settings_submit', function() {
|
16 |
include __DIR__ . '/submit.php';
|
@@ -25,11 +39,12 @@ function webp_express_settings_page_content()
|
|
25 |
function webp_express_admin_init() {
|
26 |
|
27 |
global $pagenow;
|
28 |
-
if (
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
}
|
|
|
33 |
}
|
34 |
|
35 |
add_action( 'admin_init', 'webp_express_admin_init');
|
1 |
<?php
|
2 |
+
use \WebPExpress\Config;
|
3 |
+
use \WebPExpress\Multisite;
|
4 |
|
5 |
+
if (Multisite::isNetworkActivated()) {
|
6 |
+
add_action("network_admin_menu", function() {
|
7 |
+
add_submenu_page(
|
8 |
+
'settings.php', // Parent element
|
9 |
+
'WebP Express settings (for network)', // Text in browser title bar
|
10 |
+
'WebP Express', // Text to be displayed in the menu.
|
11 |
+
'manage_network_options', // Capability
|
12 |
+
'webp_express_settings_page', // slug
|
13 |
+
'webp_express_settings_page_content' // Callback function which displays the page
|
14 |
+
);
|
15 |
+
});
|
16 |
+
} else {
|
17 |
+
add_action( 'admin_menu', function() {
|
18 |
+
//Add Settings Page
|
19 |
+
add_options_page(
|
20 |
+
'WebP Express Settings', //Page Title
|
21 |
+
'WebP Express', //Menu Title
|
22 |
+
'manage_options', //capability
|
23 |
+
'webp_express_settings_page', // slug
|
24 |
+
'webp_express_settings_page_content' //The function to be called to output the content for this page.
|
25 |
+
);
|
26 |
+
});
|
27 |
+
}
|
28 |
|
29 |
add_action('admin_post_webpexpress_settings_submit', function() {
|
30 |
include __DIR__ . '/submit.php';
|
39 |
function webp_express_admin_init() {
|
40 |
|
41 |
global $pagenow;
|
42 |
+
if ((('options-general.php' === $pagenow) || (('settings.php' === $pagenow))) && (isset( $_GET['page'])) && ('webp_express_settings_page' === $_GET['page'])) {
|
43 |
+
add_action( 'admin_enqueue_scripts', function () {
|
44 |
+
include __DIR__ . '/enqueue_scripts.php';
|
45 |
+
} );
|
46 |
}
|
47 |
+
|
48 |
}
|
49 |
|
50 |
add_action( 'admin_init', 'webp_express_admin_init');
|
@@ -1,9 +1,9 @@
|
|
1 |
<tr>
|
2 |
-
<th scope="row">Alter HTML
|
3 |
'<p>Alter HTML to either use picture tag syntax for pointing to webp versions or point directly to webps.</p>' .
|
4 |
-
'<p>
|
5 |
-
'
|
6 |
-
(($config['operation-mode'] == 'varied-responses') ?
|
7 |
'<p>You do not need to enable this in <i>Varied image responses</i> operation mode, but enabling it has some benefits: ' .
|
8 |
'Caching is improved if you are on a CDN as the webp images that are requested directly does not need to be keyed by the Accept header. ' .
|
9 |
'Also, when a user downloads an image, it will have the correct extension.</p>' : '')
|
@@ -18,37 +18,130 @@
|
|
18 |
value="true"
|
19 |
type="checkbox"
|
20 |
>
|
|
|
|
|
|
|
|
|
21 |
<div id="alter_html_options_div">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
<div>
|
23 |
<label>What to replace:</label>
|
|
|
24 |
<?php
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
30 |
'This effectively points webp-enabled browsers to the webp variant and other browsers to ' .
|
31 |
-
'the original image
|
32 |
-
'that doesnt support the picture tag.</p>' .
|
33 |
'<p><em>Beware that this structural change may affect styling!</em></p>' .
|
34 |
'<p>PS: This functionality is handled by ' .
|
35 |
'<a target="_blank" href="https://github.com/rosell-dk/dom-util-for-webp">this external library</a>' .
|
36 |
-
' (I have pushed the code to an external library so it can be used by other projects besides this plugin)</p>'
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
'the webp <i>rather than</i> the original. Handles src, srcset, common lazy-load attributes and even ' .
|
39 |
'inline styles</p>' .
|
40 |
'<p>Note that you will have to do something for the browsers that does not support webp. ' .
|
41 |
-
'
|
42 |
'will show up when you enable this option. ' .
|
43 |
-
'Or you can
|
44 |
-
'
|
45 |
'<p>PS: This replace functionality is handled by ' .
|
46 |
'<a target="_blank" href="https://github.com/rosell-dk/dom-util-for-webp">this external library</a>' .
|
47 |
-
', created for the purpose.</p>'
|
48 |
-
]
|
49 |
);
|
50 |
?>
|
51 |
-
|
|
|
52 |
<?php
|
53 |
webpexpress_checkbox(
|
54 |
'alter-html-only-for-webp-enabled-browsers',
|
@@ -56,32 +149,32 @@
|
|
56 |
'Only do the replacements in webp enabled browsers',
|
57 |
'If you enable this option, the replacements will only be made, when the request is from ' .
|
58 |
'a browser that supports webp. Note that this will not play well with plugins that caches ' .
|
59 |
-
'the page.
|
60 |
-
'which does the same, but with page caching.'
|
61 |
);
|
62 |
?>
|
63 |
-
</div>
|
64 |
-
|
65 |
-
|
66 |
-
<div style="margin-left: 11px">
|
67 |
-
<?php
|
68 |
-
webpexpress_checkbox(
|
69 |
-
'alter-html-for-webps-that-has-yet-to-exist',
|
70 |
-
(!$config['alter-html']['only-for-webps-that-exists']),
|
71 |
-
'Reference webps that hasn\'t been converted yet',
|
72 |
-
'If you enable this option, there will be references to webp files that doesnt exist yet. ' .
|
73 |
-
'And that will be ok! - Just make sure to enable the option to convert missing webp files ' .
|
74 |
-
'upon request'
|
75 |
-
);
|
76 |
-
?>
|
77 |
-
</div>
|
78 |
</div>
|
79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
<label>Where to replace: <?php echo helpIcon(
|
81 |
'<p></p>',
|
82 |
'no-margin-left set-margin-right');
|
83 |
?></label>
|
84 |
-
|
85 |
<?php
|
86 |
webpexpress_radioButtons('alter-html-hooks', $config['alter-html']['hooks'], [
|
87 |
'content-hooks' => 'Use content filtering hooks (the_content, the_excerpt, etc)',
|
@@ -94,5 +187,5 @@
|
|
94 |
|
95 |
</div>
|
96 |
|
97 |
-
</
|
98 |
</tr>
|
1 |
<tr>
|
2 |
+
<th scope="row">Alter HTML?</span><?php echo helpIcon(
|
3 |
'<p>Alter HTML to either use picture tag syntax for pointing to webp versions or point directly to webps.</p>' .
|
4 |
+
'<p>Pro picture tag syntax: The browser selects the webp if it supports it.</p>' .
|
5 |
+
'<p>Pro image urls: Also works on inline styles</p>' .
|
6 |
+
(($config['operation-mode'] == 'varied-image-responses') ?
|
7 |
'<p>You do not need to enable this in <i>Varied image responses</i> operation mode, but enabling it has some benefits: ' .
|
8 |
'Caching is improved if you are on a CDN as the webp images that are requested directly does not need to be keyed by the Accept header. ' .
|
9 |
'Also, when a user downloads an image, it will have the correct extension.</p>' : '')
|
18 |
value="true"
|
19 |
type="checkbox"
|
20 |
>
|
21 |
+
</td>
|
22 |
+
</tr>
|
23 |
+
<tr>
|
24 |
+
<th scope="row" colspan=2>
|
25 |
<div id="alter_html_options_div">
|
26 |
+
<p>
|
27 |
+
Two distinct methods for altering HTML are supported. <a id="show_alterhtml_chart_btn" href="javascript:updateAlterHTMLChartVisibility(true);">View comparison chart</a>
|
28 |
+
<input type="hidden" name="ui-show-alter-html-chart" id="ui_show_alter_html_chart" value="<?php echo 'false'; ?>">
|
29 |
+
</p>
|
30 |
+
<div id="alter_html_comparison_chart" name="alter-html-comparison-chart" class="toggler effect-slider">
|
31 |
+
<table class="designed">
|
32 |
+
<tr>
|
33 |
+
<th></th>
|
34 |
+
<th>Method 1: Replacing <img> tags with <picture> tags</th>
|
35 |
+
<th>Method 2: Replacing image URLs</th>
|
36 |
+
</tr>
|
37 |
+
<tr>
|
38 |
+
<th>How it works</th>
|
39 |
+
<td>
|
40 |
+
<p>
|
41 |
+
It replaces <img> tags with <picture> tags, adding two <source> tags - one for the original image(s), and one
|
42 |
+
for the webp image(s).
|
43 |
+
Browsers that supports webp picks the <source> tag with <i>type</i> attribute set to "image/webp".
|
44 |
+
A small javascript can be optionally added for dynamically loading picturefill.js on browsers that doesn't support the picture tag.
|
45 |
+
</p>
|
46 |
+
<p>
|
47 |
+
We are using <a target="_blank" href="https://github.com/rosell-dk/dom-util-for-webp">this library</a>.
|
48 |
+
You can visit it for more information.
|
49 |
+
</p>
|
50 |
+
</td>
|
51 |
+
<td>
|
52 |
+
It replaces any image url it can find.
|
53 |
+
We are using <a target="_blank" href="https://github.com/rosell-dk/dom-util-for-webp">this library</a>.
|
54 |
+
You can visit it for more information.
|
55 |
+
</td>
|
56 |
+
</tr>
|
57 |
+
<tr>
|
58 |
+
<th>Page caching</th>
|
59 |
+
<td>Works great with page caching, because all browsers are served the same HTML</td>
|
60 |
+
<td>
|
61 |
+
<p>
|
62 |
+
As the HTML varies with the webp-capability of the browser, page caching is tricky.
|
63 |
+
However, it can be achieved with the wonderful <i>Cache Enabler</i> plugin, which maintains two cached versions of each page.<br><br>
|
64 |
+
<span style="font-size:10px">
|
65 |
+
Note: <i>Cache Enabler</i> also has HTML altering, but their implementation has <a target="_blank" href="https://github.com/keycdn/cache-enabler/issues/51">limitations</a>.
|
66 |
+
It for example doesn't replace background images in inline styles and it does not look for all common lazy load attributes. It also has some problems in edge cases.
|
67 |
+
For this reason, I recommend activating HTML altering in WebP Express, even when <i>Cache Enabler</i> is used.
|
68 |
+
By doing that, both plugins will have a go at it (WebP Express comes first).
|
69 |
+
At least it will take care of the limitations in <i>Cache Enabler</i>.
|
70 |
+
It does however not cure the edge cases where Cache Enabler replaces things it should not.
|
71 |
+
</span>
|
72 |
+
</p>
|
73 |
+
</td>
|
74 |
+
</tr>
|
75 |
+
<tr>
|
76 |
+
<th><nobr>Styling and javascript</nobr></th>
|
77 |
+
<td>May break because of changed HTML structure</td>
|
78 |
+
<td>No problems</td>
|
79 |
+
</tr>
|
80 |
+
<tr>
|
81 |
+
<th>Comprehensiveness</th>
|
82 |
+
<td>Only replaces <img> tags - other images are untouched</td>
|
83 |
+
<td>Very comprehensive. Replaces images in inline styles, image urls in lazy load attributes set in <div> or <li> tags, etc.</td>
|
84 |
+
</tr>
|
85 |
+
</table>
|
86 |
+
<p>
|
87 |
+
Note: The altering only happens for images that are converted and which exists in the same folder as the source with the extension selected in the GENERAL section.
|
88 |
+
</p>
|
89 |
+
</div>
|
90 |
+
<a id="hide_alterhtml_chart_btn" href="javascript:updateAlterHTMLChartVisibility(false);">Hide comparison chart</a>
|
91 |
<div>
|
92 |
<label>What to replace:</label>
|
93 |
+
<ul style="margin-left: 20px; margin-top: 5px"><li>
|
94 |
<?php
|
95 |
+
webpexpress_radioButton(
|
96 |
+
'alter-html-replacement',
|
97 |
+
'picture',
|
98 |
+
'Replace <img> tags with <picture> tags, adding the webp to srcset.',
|
99 |
+
$config['alter-html']['replacement'],
|
100 |
+
'<p>"Picture tag" replaces <img> tags with <picture> tags and adds the webp as an extra source. ' .
|
101 |
'This effectively points webp-enabled browsers to the webp variant and other browsers to ' .
|
102 |
+
'the original image.</p>' .
|
|
|
103 |
'<p><em>Beware that this structural change may affect styling!</em></p>' .
|
104 |
'<p>PS: This functionality is handled by ' .
|
105 |
'<a target="_blank" href="https://github.com/rosell-dk/dom-util-for-webp">this external library</a>' .
|
106 |
+
' (I have pushed the code to an external library so it can be used by other projects besides this plugin)</p>'
|
107 |
+
);
|
108 |
+
?>
|
109 |
+
</li>
|
110 |
+
<li><div id="alter_html_picture_options_div" style="margin-left:18px; margin-bottom: 13px;">
|
111 |
+
<?php
|
112 |
+
webpexpress_checkbox(
|
113 |
+
'alter-html-add-picturefill-js',
|
114 |
+
$config['alter-html']['alter-html-add-picturefill-js'],
|
115 |
+
'Dynamically load picturefill.js on older browsers',
|
116 |
+
'If you enable this option, a small script will be added which detects if picture tags are supported and loads ' .
|
117 |
+
'<a href="https://github.com/scottjehl/picturefill" target="_blank">picturefill.js</a> if not. ' .
|
118 |
+
'It is recommended to activate this option, unless your theme or another plugin adds such a script. ' .
|
119 |
+
'Picture tag support is currently <a href="https://caniuse.com/#feat=picture" target="_blank">~88%</a>'
|
120 |
+
);
|
121 |
+
?>
|
122 |
+
</div></li>
|
123 |
+
<li>
|
124 |
+
<?php
|
125 |
+
webpexpress_radioButton(
|
126 |
+
'alter-html-replacement',
|
127 |
+
'url',
|
128 |
+
'Replace image URLs',
|
129 |
+
$config['alter-html']['replacement'],
|
130 |
+
'<p>"Image URLs" replaces the image URLs to point to ' .
|
131 |
'the webp <i>rather than</i> the original. Handles src, srcset, common lazy-load attributes and even ' .
|
132 |
'inline styles</p>' .
|
133 |
'<p>Note that you will have to do something for the browsers that does not support webp. ' .
|
134 |
+
'And that something is in most cases to enable the <i>Only do the replacements in webp enabled browsers</i> option, which ' .
|
135 |
'will show up when you enable this option. ' .
|
136 |
+
'Or you can experiment with javascript solutions. There is for example the <a href="https://webpjs.appspot.com/">webpjs</a> javascript library. ' .
|
137 |
+
'But it does not support srcset, which is a showstopper. There are other libraries out there. ' .
|
138 |
'<p>PS: This replace functionality is handled by ' .
|
139 |
'<a target="_blank" href="https://github.com/rosell-dk/dom-util-for-webp">this external library</a>' .
|
140 |
+
', created for the purpose.</p>'
|
|
|
141 |
);
|
142 |
?>
|
143 |
+
</li>
|
144 |
+
<li><div id="alter_html_url_options_div" style="margin-left:18px; margin-bottom: 13px;">
|
145 |
<?php
|
146 |
webpexpress_checkbox(
|
147 |
'alter-html-only-for-webp-enabled-browsers',
|
149 |
'Only do the replacements in webp enabled browsers',
|
150 |
'If you enable this option, the replacements will only be made, when the request is from ' .
|
151 |
'a browser that supports webp. Note that this will not play well with plugins that caches ' .
|
152 |
+
'the page. To overcome that, you can use the Cache Enabler plugin, '
|
|
|
153 |
);
|
154 |
?>
|
155 |
+
</div></li>
|
156 |
+
</ul>
|
157 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
</div>
|
159 |
+
<?php
|
160 |
+
if ($config['operation-mode'] != 'no-conversion') {
|
161 |
+
echo '<div><div style="margin-left: 11px">';
|
162 |
+
webpexpress_checkbox(
|
163 |
+
'alter-html-for-webps-that-has-yet-to-exist',
|
164 |
+
(!$config['alter-html']['only-for-webps-that-exists']),
|
165 |
+
'Reference webps that hasn\'t been converted yet',
|
166 |
+
'If you enable this option, there will be references to webp files that doesnt exist yet. ' .
|
167 |
+
'And that will be ok! - Just make sure to enable the option to convert missing webp files ' .
|
168 |
+
'upon request'
|
169 |
+
);
|
170 |
+
echo '</div></div>';
|
171 |
+
}
|
172 |
+
?>
|
173 |
+
<div style="margin-top: 20px">
|
174 |
<label>Where to replace: <?php echo helpIcon(
|
175 |
'<p></p>',
|
176 |
'no-margin-left set-margin-right');
|
177 |
?></label>
|
|
|
178 |
<?php
|
179 |
webpexpress_radioButtons('alter-html-hooks', $config['alter-html']['hooks'], [
|
180 |
'content-hooks' => 'Use content filtering hooks (the_content, the_excerpt, etc)',
|
187 |
|
188 |
</div>
|
189 |
|
190 |
+
</th>
|
191 |
</tr>
|
@@ -1,6 +1,11 @@
|
|
1 |
-
<?php if ($config['operation-mode'] == 'tweaked') : ?>
|
2 |
<fieldset class="block">
|
3 |
<h3>Alter HTML</h3>
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
<table class="form-table">
|
5 |
<tbody>
|
6 |
<?php
|
@@ -9,11 +14,3 @@
|
|
9 |
</tbody>
|
10 |
</table>
|
11 |
</fieldset>
|
12 |
-
<?php
|
13 |
-
else:
|
14 |
-
|
15 |
-
if ($config['operation-mode'] != 'just-redirect') {
|
16 |
-
include_once 'alter-html-options.inc';
|
17 |
-
}
|
18 |
-
endif;
|
19 |
-
?>
|
|
|
1 |
<fieldset class="block">
|
2 |
<h3>Alter HTML</h3>
|
3 |
+
<p>
|
4 |
+
Enabling this alters the HTML code such that webp images are served to browsers that supports webp.
|
5 |
+
It is <i>recommended to enable</i> this even when the redirection is also enabled, so the varied image responses are only used for
|
6 |
+
those images that cannot be replaced in HTML. The varied responses generally leads to poorer caching in proxies and CDN's. And if
|
7 |
+
users download those images, they will have jpg/png extension, even though they are webp.
|
8 |
+
</p>
|
9 |
<table class="form-table">
|
10 |
<tbody>
|
11 |
<?php
|
14 |
</tbody>
|
15 |
</table>
|
16 |
</fieldset>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,28 +1,13 @@
|
|
1 |
-
<?php if ($config['operation-mode'] == 'tweaked') : ?>
|
2 |
<fieldset class="block">
|
3 |
-
<h3>Conversion
|
4 |
-
|
5 |
<table class="form-table">
|
6 |
<tbody>
|
7 |
<?php
|
8 |
include_once 'quality.inc';
|
9 |
include_once 'metadata.inc';
|
10 |
include_once 'converters.inc';
|
11 |
-
include_once 'destination-folder.inc';
|
12 |
-
include_once 'destination-extension.inc';
|
13 |
?>
|
14 |
</tbody>
|
15 |
</table>
|
16 |
</fieldset>
|
17 |
-
<?php
|
18 |
-
else:
|
19 |
-
include_once 'quality.inc';
|
20 |
-
include_once 'metadata.inc';
|
21 |
-
include_once 'converters.inc';
|
22 |
-
|
23 |
-
if (($config['operation-mode'] == 'varied-responses') || ($config['operation-mode'] == 'no-varied-responses')) {
|
24 |
-
include_once 'destination-folder.inc';
|
25 |
-
}
|
26 |
-
include_once 'destination-extension.inc';
|
27 |
-
endif;
|
28 |
-
?>
|
|
|
1 |
<fieldset class="block">
|
2 |
+
<h3>Conversion</h3>
|
3 |
+
<!--<p><i>The options here affects the conversion process</i></p>-->
|
4 |
<table class="form-table">
|
5 |
<tbody>
|
6 |
<?php
|
7 |
include_once 'quality.inc';
|
8 |
include_once 'metadata.inc';
|
9 |
include_once 'converters.inc';
|
|
|
|
|
10 |
?>
|
11 |
</tbody>
|
12 |
</table>
|
13 |
</fieldset>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,24 +0,0 @@
|
|
1 |
-
<tr id="destination_extension_row"><th scope="row">File extension<?php
|
2 |
-
echo helpIcon(
|
3 |
-
'<p>Controls the filename of the converted file.</p>' .
|
4 |
-
'<p>The "Append" option result in file names such as "image.png.webp". ' .
|
5 |
-
'The "Set" option results in file names such as "image.webp". ' .
|
6 |
-
'Note that if you choose "Set", it will be a problem if you ie both have a logo.jpg and a logo.png in the same folder. ' .
|
7 |
-
'If you are using WebP Express together with <a target="blank" href="https://da.wordpress.org/plugins/cache-enabler/">Cache enabler</a> ' .
|
8 |
-
'or <a target="_blank" href="https://wordpress.org/plugins/shortpixel-image-optimiser/">Shortpixel</a>, set this option to Set"</p>' .
|
9 |
-
(($config['operation-mode'] == 'no-varied-responses') ? '<p>In this mode, the webp files will be stored in the same folder as the originals, except for images that are not inside the uploads folder (these are stored in wp-content/webp-express/webp-images/doc-root).</p>' : '') .
|
10 |
-
'<p>Changing this option will cause existing webp images to be renamed (only those in the upload folder, and only those that has a ' .
|
11 |
-
'corresponding source image)</p>'
|
12 |
-
);?>
|
13 |
-
</th>
|
14 |
-
<td>
|
15 |
-
<select name="destination-extension">
|
16 |
-
<?php
|
17 |
-
webpexpress_selectBoxOptions($config['destination-extension'], [
|
18 |
-
'append' => 'Append ".webp"',
|
19 |
-
'set' => 'Set to ".webp"',
|
20 |
-
]);
|
21 |
-
?>
|
22 |
-
</select>
|
23 |
-
</td>
|
24 |
-
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1,7 +1,6 @@
|
|
1 |
<?php
|
2 |
// Metadata
|
3 |
// --------------------
|
4 |
-
//$maxQuality = get_option('webp_express_max_quality');
|
5 |
$metadata = $config['metadata'];
|
6 |
|
7 |
echo '<tr><th scope="row">Metadata';
|
1 |
<?php
|
2 |
// Metadata
|
3 |
// --------------------
|
|
|
4 |
$metadata = $config['metadata'];
|
5 |
|
6 |
echo '<tr><th scope="row">Metadata';
|
@@ -1,19 +1,22 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
//$maxQuality = get_option('webp_express_max_quality');
|
4 |
$cacheControl = $config['cache-control'];
|
5 |
$cacheControlCustom = $config['cache-control-custom'];
|
6 |
$cacheControlMaxAge = $config['cache-control-max-age'];
|
7 |
$cacheControlPublic = $config['cache-control-public'];
|
8 |
?>
|
9 |
|
10 |
-
<tr>
|
11 |
-
<th scope="row">Cache-Control header <?php
|
12 |
-
|
13 |
-
'
|
14 |
-
|
15 |
-
'
|
16 |
-
|
|
|
|
|
|
|
|
|
17 |
?>
|
18 |
</th>
|
19 |
<td>
|
@@ -21,19 +24,6 @@ $cacheControlPublic = $config['cache-control-public'];
|
|
21 |
<option value="no-header" <?php if ($cacheControl == 'no-header') echo ' selected' ?>>Do not set</option>
|
22 |
<option value="set" <?php if ($cacheControl == 'set') echo ' selected' ?>>Set</option>
|
23 |
<option value="custom" <?php if ($cacheControl == 'custom') echo ' selected' ?>>Custom</option>
|
24 |
-
<?php
|
25 |
-
/*
|
26 |
-
echo '<option value="no-header"' . ($cacheControl == 'no-header' ? ' selected' : '') . '>Do not set Cache-Control header</option>';
|
27 |
-
echo '<option value="one-second"' . ($cacheControl == 'one-second' ? ' selected' : '') . '>One second</option>';
|
28 |
-
echo '<option value="one-minute"' . ($cacheControl == 'one-minute' ? ' selected' : '') . '>One minute</option>';
|
29 |
-
echo '<option value="one-hour"' . ($cacheControl == 'one-hour' ? ' selected' : '') . '>One hour</option>';
|
30 |
-
echo '<option value="one-day"' . ($cacheControl == 'one-day' ? ' selected' : '') . '>One day</option>';
|
31 |
-
echo '<option value="one-week"' . ($cacheControl == 'one-week' ? ' selected' : '') . '>One week</option>';
|
32 |
-
echo '<option value="one-month"' . ($cacheControl == 'one-month' ? ' selected' : '') . '>One month</option>';
|
33 |
-
echo '<option value="one-year"' . ($cacheControl == 'one-year' ? ' selected' : '') . '>One year</option>';
|
34 |
-
echo '<option value="custom"' . ($cacheControl == 'custom' ? ' selected' : '') . '>Custom Cache-Control header</option>';
|
35 |
-
*/
|
36 |
-
?>
|
37 |
</select>
|
38 |
<div id="cache_control_custom_div" style="display:inline-block;">
|
39 |
<input type="text" id="cache_control_custom" name="cache-control-custom" value="<?php echo $cacheControlCustom ?>">
|
1 |
<?php
|
2 |
|
|
|
3 |
$cacheControl = $config['cache-control'];
|
4 |
$cacheControlCustom = $config['cache-control-custom'];
|
5 |
$cacheControlMaxAge = $config['cache-control-max-age'];
|
6 |
$cacheControlPublic = $config['cache-control-public'];
|
7 |
?>
|
8 |
|
9 |
+
<tr id="cache_control_div">
|
10 |
+
<th scope="row">Cache-Control header <?php
|
11 |
+
if ($config['operation-mode'] == 'no-conversion') {
|
12 |
+
echo helpIcon('<p>Optionally set cache-control header for the internally redirected images (recommended!)</p>');
|
13 |
+
} else {
|
14 |
+
echo helpIcon('<p>Controls the cache-control header on successful conversion and direct redirection to converted ' .
|
15 |
+
'image in .htaccess. In case of convert failure, headers will be sent to prevent caching.</p>' .
|
16 |
+
'<p>PS: In order to set <i>stale-while-revalidate</i> and <i>stale-if-error directives<i>, you must ' .
|
17 |
+
'currently choose "Custom". <a target="_blank" href="https://www.fastly.com/blog/stale-while-revalidate-stale-if-error-available-today">It is a good idea to set these</a>.' .
|
18 |
+
'</p>');
|
19 |
+
}
|
20 |
?>
|
21 |
</th>
|
22 |
<td>
|
24 |
<option value="no-header" <?php if ($cacheControl == 'no-header') echo ' selected' ?>>Do not set</option>
|
25 |
<option value="set" <?php if ($cacheControl == 'set') echo ' selected' ?>>Set</option>
|
26 |
<option value="custom" <?php if ($cacheControl == 'custom') echo ' selected' ?>>Custom</option>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
</select>
|
28 |
<div id="cache_control_custom_div" style="display:inline-block;">
|
29 |
<input type="text" id="cache_control_custom" name="cache-control-custom" value="<?php echo $cacheControlCustom ?>">
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<tr id="destination_extension_row"><?php
|
2 |
+
|
3 |
+
if ($config['operation-mode'] == 'no-conversion') {
|
4 |
+
echo '<th scope="row">Filename of the webp files';
|
5 |
+
echo helpIcon(
|
6 |
+
'<p>Select under which naming convention the webp files are stored. ' .
|
7 |
+
'It is assumed that webp files are located in the same folder as the originals.</p>' .
|
8 |
+
'<style>' .
|
9 |
+
'#plugin-conventions th {font-style:italic;}' .
|
10 |
+
'#plugin-conventions td, #plugin-conventions th {padding:0;}' .
|
11 |
+
'#plugin-conventions td:last-child, #plugin-conventions th:last-child {padding-left:10px;}' .
|
12 |
+
'</style>' .
|
13 |
+
'<table id="plugin-conventions"><tbody>' .
|
14 |
+
'<tr><th>Plugin</td><th>Convention</th></tr>' .
|
15 |
+
//'<tr><td><a target="blank" href="https://wordpress.org/plugins/cache-enabler/">Cache enabler</a></td><td>Replaces extension</td></tr>' .
|
16 |
+
'<tr><td><a target="_blank" href="https://wordpress.org/plugins/shortpixel-image-optimiser/">Shortpixel</a></td><td>Replaces extension</td></tr>' .
|
17 |
+
'<tr><td><a target="_blank" href="https://wordpress.org/plugins/ewww-image-optimizer/">Ewww</a></td><td>Appends extension</td></tr>' .
|
18 |
+
'<tr><td><a target="_blank" href="https://optimus.io/en/">Optimus HQ</a></td><td>Replaces extension</td></tr>' .
|
19 |
+
// todo:
|
20 |
+
'</tbody></table>'
|
21 |
+
);
|
22 |
+
} else {
|
23 |
+
echo '<th scope="row">File extension';
|
24 |
+
echo helpIcon(
|
25 |
+
'<p>Controls the filename of the converted file.</p>' .
|
26 |
+
'<p>The "Append" option result in file names such as "image.png.webp". ' .
|
27 |
+
'The "Set" option results in file names such as "image.webp". ' .
|
28 |
+
'Note that if you choose "Set", it will be a problem if you ie both have a logo.jpg and a logo.png in the same folder. ' .
|
29 |
+
'If you are using WebP Express together with <a target="blank" href="https://wordpress.org/plugins/cache-enabler/">Cache enabler</a> ' .
|
30 |
+
'or <a target="_blank" href="https://wordpress.org/plugins/shortpixel-image-optimiser/">Shortpixel</a>, set this option to Set"</p>' .
|
31 |
+
(($config['operation-mode'] == 'cdn-friendly') ? '<p>In this mode, the webp files will be stored in the same folder as the originals, except for images that are not inside the uploads folder (these are stored in wp-content/webp-express/webp-images/doc-root).</p>' : '') .
|
32 |
+
'<p>Changing this option will cause existing webp images to be renamed (only those in the upload folder, and only those that has a ' .
|
33 |
+
'corresponding source image)</p>'
|
34 |
+
);
|
35 |
+
}
|
36 |
+
?>
|
37 |
+
</th>
|
38 |
+
<td>
|
39 |
+
<?php
|
40 |
+
if ($config['operation-mode'] == 'no-conversion') {
|
41 |
+
webpexpress_radioButtons('destination-extension', $config['destination-extension'], [
|
42 |
+
'append' => 'Original extension is kept (ie "image.jpg.webp")',
|
43 |
+
'set' => 'Original extension is replaced (ie "image.webp")',
|
44 |
+
], [
|
45 |
+
'append' => 'Original extension is kept and ".webp" is appended. ',
|
46 |
+
'set' => 'Original extension is replaced with ".webp".'
|
47 |
+
], 'margin-left: 0px; margin-top: 5px');
|
48 |
+
|
49 |
+
} else {
|
50 |
+
echo '<select name="destination-extension" id="destination_extension">';
|
51 |
+
webpexpress_selectBoxOptions($config['destination-extension'], [
|
52 |
+
'append' => 'Append ".webp"',
|
53 |
+
'set' => 'Set to ".webp"',
|
54 |
+
]);
|
55 |
+
echo '</select>';
|
56 |
+
}
|
57 |
+
?>
|
58 |
+
|
59 |
+
</td>
|
60 |
+
</tr>
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<fieldset class="block">
|
2 |
+
<h3>General</h3>
|
3 |
+
<!--<div><i>The options here affects the rules created in the .htaccess. <?php echo helpIcon('And so does some other options. If "Redirect directly to converted image" is set, the "Destination folder" and "File Extension" and "Caching" options will be used'); ?></i></div>-->
|
4 |
+
<table class="form-table">
|
5 |
+
<tbody>
|
6 |
+
<?php
|
7 |
+
include_once 'image-types.inc';
|
8 |
+
|
9 |
+
if (($config['operation-mode'] != 'no-conversion')) {
|
10 |
+
include_once 'destination-folder.inc';
|
11 |
+
}
|
12 |
+
include_once 'destination-extension.inc';
|
13 |
+
|
14 |
+
if (($config['operation-mode'] == 'tweaked') || ($config['operation-mode'] == 'varied-image-responses')) {
|
15 |
+
include_once 'cache-control.inc';
|
16 |
+
}
|
17 |
+
|
18 |
+
?>
|
19 |
+
</tbody>
|
20 |
+
</table>
|
21 |
+
</fieldset>
|
@@ -3,20 +3,26 @@
|
|
3 |
// ------------
|
4 |
echo '<tr><th scope="row">';
|
5 |
switch ($config['operation-mode']) {
|
6 |
-
case 'varied-responses':
|
7 |
echo 'Image types to work on';
|
8 |
break;
|
9 |
-
case '
|
10 |
echo 'Image types to convert';
|
11 |
break;
|
12 |
-
case '
|
13 |
-
echo 'Image types to
|
14 |
break;
|
15 |
case 'tweaked':
|
16 |
echo 'Image types to send to the converter';
|
17 |
break;
|
18 |
}
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
echo '</th><td>';
|
21 |
|
22 |
// bitmask
|
@@ -24,7 +30,6 @@ echo '</th><td>';
|
|
24 |
// 2: PNG's
|
25 |
// Converting only jpegs is thus "1"
|
26 |
// Converting both jpegs and pngs is (1+2) = 3
|
27 |
-
//$imageTypes = get_option('webp_express_image_types_to_convert');
|
28 |
$imageTypes = $config['image-types'];
|
29 |
|
30 |
echo '<select name="image-types">';
|
3 |
// ------------
|
4 |
echo '<tr><th scope="row">';
|
5 |
switch ($config['operation-mode']) {
|
6 |
+
case 'varied-image-responses':
|
7 |
echo 'Image types to work on';
|
8 |
break;
|
9 |
+
case 'cdn-friendly':
|
10 |
echo 'Image types to convert';
|
11 |
break;
|
12 |
+
case 'no-conversion':
|
13 |
+
echo 'Image types to work on';
|
14 |
break;
|
15 |
case 'tweaked':
|
16 |
echo 'Image types to send to the converter';
|
17 |
break;
|
18 |
}
|
19 |
+
if ($config['operation-mode'] == 'no-conversion') {
|
20 |
+
echo helpIcon('<p>Select which types of images you would like to redirect and/or have altered in the HTML</p>');
|
21 |
+
|
22 |
+
} else {
|
23 |
+
echo helpIcon('<p>Beware that the Gd conversion method cannot handle transparency for PNGs. PNG conversions havent been tested much yet. Please report any problems with PNG images <a target="_blank" href="https://github.com/rosell-dk/webp-convert/issues/42">here</a></p><p>The term "send" means an internal redirect on the server (not to be confused with an external redirect, such as a 301 or 302 response)</p>');
|
24 |
+
|
25 |
+
}
|
26 |
echo '</th><td>';
|
27 |
|
28 |
// bitmask
|
30 |
// 2: PNG's
|
31 |
// Converting only jpegs is thus "1"
|
32 |
// Converting both jpegs and pngs is (1+2) = 3
|
|
|
33 |
$imageTypes = $config['image-types'];
|
34 |
|
35 |
echo '<select name="image-types">';
|
@@ -12,14 +12,14 @@ $operationMode = $config['operation-mode'];
|
|
12 |
?>
|
13 |
<input type="hidden" name="operation-mode" id="operation_mode" value="<?php echo $operationMode ?>">
|
14 |
<select name="change-operation-mode" id="change_operation_mode">
|
15 |
-
<option value="varied-responses"<?php if ($operationMode == 'varied-responses') echo ' selected'?>>Varied image responses</option>
|
16 |
-
<option value="
|
17 |
-
<option value="
|
18 |
<option value="tweaked"<?php if ($operationMode == 'tweaked') echo ' selected'?>>Tweaked</option>
|
19 |
</select></h3>
|
20 |
|
21 |
-
<?php if ($config['operation-mode'] == 'varied-responses') : ?>
|
22 |
-
<p><div>
|
23 |
<i>In the "Varied image responses" mode, WebP Express creates redirection rules for images, such that a request for a jpeg will
|
24 |
result in a webp – but only if the request comes from a webp-enabled browser.
|
25 |
If a webp already exists, it is served immediately. Otherwise it is converted and then served.
|
@@ -27,8 +27,8 @@ $operationMode = $config['operation-mode'];
|
|
27 |
</i>
|
28 |
</div></p>
|
29 |
<?php endif; ?>
|
30 |
-
<?php if ($config['operation-mode'] == '
|
31 |
-
<p><div>
|
32 |
<i>In "CDN friendly" mode, a jpeg is always served as a jpeg.
|
33 |
Instead of varying the image response, WebP Express alters the HTML for webp usage.</i>
|
34 |
<div class="help">?<div class="popup">
|
@@ -50,11 +50,12 @@ $operationMode = $config['operation-mode'];
|
|
50 |
<i>A couple of options are available for automatically triggering webp conversion.</i>
|
51 |
</div></p>
|
52 |
<?php endif; ?>
|
53 |
-
<?php if ($config['operation-mode'] == '
|
54 |
<p>
|
55 |
-
<div>
|
56 |
-
<i>
|
57 |
-
|
|
|
58 |
</div>
|
59 |
</p>
|
60 |
<?php endif; ?>
|
12 |
?>
|
13 |
<input type="hidden" name="operation-mode" id="operation_mode" value="<?php echo $operationMode ?>">
|
14 |
<select name="change-operation-mode" id="change_operation_mode">
|
15 |
+
<option value="varied-image-responses"<?php if ($operationMode == 'varied-image-responses') echo ' selected'?>>Varied image responses</option>
|
16 |
+
<option value="cdn-friendly"<?php if ($operationMode == 'cdn-friendly') echo ' selected'?>>CDN friendly</option>
|
17 |
+
<option value="no-conversion"<?php if ($operationMode == 'no-conversion') echo ' selected'?>>No conversion</option>
|
18 |
<option value="tweaked"<?php if ($operationMode == 'tweaked') echo ' selected'?>>Tweaked</option>
|
19 |
</select></h3>
|
20 |
|
21 |
+
<?php if ($config['operation-mode'] == 'varied-image-responses') : ?>
|
22 |
+
<p><div class="p">
|
23 |
<i>In the "Varied image responses" mode, WebP Express creates redirection rules for images, such that a request for a jpeg will
|
24 |
result in a webp – but only if the request comes from a webp-enabled browser.
|
25 |
If a webp already exists, it is served immediately. Otherwise it is converted and then served.
|
27 |
</i>
|
28 |
</div></p>
|
29 |
<?php endif; ?>
|
30 |
+
<?php if ($config['operation-mode'] == 'cdn-friendly') : ?>
|
31 |
+
<p><div class="p">
|
32 |
<i>In "CDN friendly" mode, a jpeg is always served as a jpeg.
|
33 |
Instead of varying the image response, WebP Express alters the HTML for webp usage.</i>
|
34 |
<div class="help">?<div class="popup">
|
50 |
<i>A couple of options are available for automatically triggering webp conversion.</i>
|
51 |
</div></p>
|
52 |
<?php endif; ?>
|
53 |
+
<?php if ($config['operation-mode'] == 'no-conversion') : ?>
|
54 |
<p>
|
55 |
+
<div class="p">
|
56 |
+
<i>The "No conversion" mode is for scenarios where you are using another plugin for converting images.
|
57 |
+
Perhaps the other plugin doesn't have the redirection or alter HTML feature, or perhaps it doesn't do it as well
|
58 |
+
as WebP Express does. PS: The two methods below works great in tandem.</i>
|
59 |
</div>
|
60 |
</p>
|
61 |
<?php endif; ?>
|
@@ -1,9 +1,9 @@
|
|
1 |
<tr>
|
2 |
<th scope="row">
|
3 |
-
<?php if ($config['operation-mode'] == '
|
4 |
-
|
5 |
echo helpIcon(
|
6 |
-
//'<p><em>The auto-
|
7 |
'<p>This works the following way:' .
|
8 |
'<ol>' .
|
9 |
'<li>WebP adds rules in the <i>.htaccess</i> that redirects requests for jpg/png images to the converter, <i>when no corresponding webp image is found</i></li>' .
|
@@ -14,7 +14,7 @@
|
|
14 |
'the rule will not trigger because it now detects a corresponding webp</p>' .
|
15 |
'<p>Note: After the introduction of the <i>Convert non-existing webp-files upon request?</i> option, ' .
|
16 |
'you probably will not need this option. There are however rare cases, where it could be useful. ' .
|
17 |
-
'
|
18 |
); ?>
|
19 |
<?php else: ?>
|
20 |
Enable redirection to converter?<?php echo helpIcon('This will add rules in the .htaccess that redirects images (jpg/png) to the script'); ?>
|
1 |
<tr>
|
2 |
<th scope="row">
|
3 |
+
<?php if ($config['operation-mode'] == 'cdn-friendly'): ?>
|
4 |
+
Redirect requests for jpg/png to converter, but only when there is no webp, and serve the original<?php
|
5 |
echo helpIcon(
|
6 |
+
//'<p><em>The auto-conversion works this way: When an image is requested, a rule in the .htaccess detects if that image has been converted. If not, the request is redirected to the converter, which creates the webp and returns <em>the original</em> image</em></p>
|
7 |
'<p>This works the following way:' .
|
8 |
'<ol>' .
|
9 |
'<li>WebP adds rules in the <i>.htaccess</i> that redirects requests for jpg/png images to the converter, <i>when no corresponding webp image is found</i></li>' .
|
14 |
'the rule will not trigger because it now detects a corresponding webp</p>' .
|
15 |
'<p>Note: After the introduction of the <i>Convert non-existing webp-files upon request?</i> option, ' .
|
16 |
'you probably will not need this option. There are however rare cases, where it could be useful. ' .
|
17 |
+
'</p>'
|
18 |
); ?>
|
19 |
<?php else: ?>
|
20 |
Enable redirection to converter?<?php echo helpIcon('This will add rules in the .htaccess that redirects images (jpg/png) to the script'); ?>
|
@@ -1,9 +1,10 @@
|
|
1 |
<tr>
|
2 |
<th scope="row">
|
3 |
-
|
4 |
<?php echo helpIcon(
|
5 |
-
'<p>Have ie. "image.jpg.webp" automatically generated from "image.jpg" the first time the webp is requested
|
6 |
-
'
|
|
|
7 |
'<ol>' .
|
8 |
'<li>WebP adds rules in the <i>.htaccess</i> that redirects requests for non-existing webp files to <i>webp-realizer.php</i></li>' .
|
9 |
'<li><i>webp-realizer.php</i> looks for a corresponding jpg/png. If found, it is converted and saved, so the webp will be directly available the next time it is requested – and it tells the browser to fetch the same URL again (302 redirect to same location). In case no corresponding jpg/png is found, a 404 is returned</li>' .
|
1 |
<tr>
|
2 |
<th scope="row">
|
3 |
+
Redirect requests for non-existing webp-files to converter</span>
|
4 |
<?php echo helpIcon(
|
5 |
+
'<p>Have ie. "image.jpg.webp" automatically generated from "image.jpg" the first time the webp is requested. ' .
|
6 |
+
'This way you can reference webps before they actually exists.</p>' .
|
7 |
+
'<p>The feature works the following way:' .
|
8 |
'<ol>' .
|
9 |
'<li>WebP adds rules in the <i>.htaccess</i> that redirects requests for non-existing webp files to <i>webp-realizer.php</i></li>' .
|
10 |
'<li><i>webp-realizer.php</i> looks for a corresponding jpg/png. If found, it is converted and saved, so the webp will be directly available the next time it is requested – and it tells the browser to fetch the same URL again (302 redirect to same location). In case no corresponding jpg/png is found, a 404 is returned</li>' .
|
@@ -1,10 +1,11 @@
|
|
1 |
-
<tr>
|
2 |
<th scope="row">
|
3 |
-
Only redirect to converter for webp-enabled browsers?<?php echo helpIcon('If checked, a condition is added to the .htaccess, that the <i>Accept</i> header contains "image/webp"'); ?>
|
4 |
</th>
|
5 |
<td>
|
|
|
6 |
<input
|
7 |
name="only-redirect-to-converter-for-webp-enabled-browsers"
|
|
|
8 |
<?php echo ($config['only-redirect-to-converter-for-webp-enabled-browsers'] ? 'checked="checked"' : '') ?>
|
9 |
value="true"
|
10 |
type="checkbox"
|
1 |
+
<tr id="only_redirect_to_converter_for_webp_enabled_browsers_row">
|
2 |
<th scope="row">
|
|
|
3 |
</th>
|
4 |
<td>
|
5 |
+
Only redirect to converter for webp-enabled browsers?<?php echo helpIcon('If checked, a condition is added to the .htaccess, that the <i>Accept</i> header contains "image/webp"'); ?>
|
6 |
<input
|
7 |
name="only-redirect-to-converter-for-webp-enabled-browsers"
|
8 |
+
id="only_redirect_to_converter_for_webp_enabled_browsers"
|
9 |
<?php echo ($config['only-redirect-to-converter-for-webp-enabled-browsers'] ? 'checked="checked"' : '') ?>
|
10 |
value="true"
|
11 |
type="checkbox"
|
@@ -1,16 +1,16 @@
|
|
1 |
-
<tr>
|
2 |
<th scope="row">
|
|
|
|
|
3 |
Only redirect to converter if no webp exists <?php
|
4 |
echo helpIcon(
|
5 |
'<p>This extra condition is not needed if you enabled the ' .
|
6 |
'<i>Redirect directly to converted image when available</i> option.</p>' .
|
7 |
'<p>The option was created in order to make it possible to achieve the functionality behind the ' .
|
8 |
-
'<i>
|
9 |
'"CDN friendly" operation mode.</p>'
|
10 |
);
|
11 |
?>
|
12 |
-
</th>
|
13 |
-
<td>
|
14 |
<input type="checkbox" name="only-redirect-to-converter-on-cache-miss" value="true" <?php echo ($config['only-redirect-to-converter-on-cache-miss'] ? 'checked="checked"' : '') ?> >
|
15 |
</td>
|
16 |
</tr>
|
1 |
+
<tr id="only_redirect_to_converter_on_cache_miss_row">
|
2 |
<th scope="row">
|
3 |
+
</th>
|
4 |
+
<td>
|
5 |
Only redirect to converter if no webp exists <?php
|
6 |
echo helpIcon(
|
7 |
'<p>This extra condition is not needed if you enabled the ' .
|
8 |
'<i>Redirect directly to converted image when available</i> option.</p>' .
|
9 |
'<p>The option was created in order to make it possible to achieve the functionality behind the ' .
|
10 |
+
'<i>Redirect requests for non-existing webp-files to converter</i> option found in the ' .
|
11 |
'"CDN friendly" operation mode.</p>'
|
12 |
);
|
13 |
?>
|
|
|
|
|
14 |
<input type="checkbox" name="only-redirect-to-converter-on-cache-miss" value="true" <?php echo ($config['only-redirect-to-converter-on-cache-miss'] ? 'checked="checked"' : '') ?> >
|
15 |
</td>
|
16 |
</tr>
|
@@ -1,11 +1,28 @@
|
|
1 |
<tr>
|
2 |
<th scope="row">
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
</th>
|
8 |
<td>
|
9 |
<input type="checkbox" id="redirect_to_existing_in_htaccess" name="redirect-to-existing-in-htaccess" value="true" <?php echo ($config['redirect-to-existing-in-htaccess'] ? 'checked="checked"' : '') ?> >
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
</td>
|
11 |
</tr>
|
1 |
<tr>
|
2 |
<th scope="row">
|
3 |
+
<?php
|
4 |
+
|
5 |
+
if ($config['operation-mode'] == 'no-conversion') {
|
6 |
+
echo 'Activate redirection';
|
7 |
+
echo helpIcon('This will add rules in the .htaccess that redirects directly to existing converted files (note that it is an internal redirect, which is much faster than a 301 or 302 redirect).');
|
8 |
+
} else {
|
9 |
+
echo 'Redirect directly to existing converted images';
|
10 |
+
echo helpIcon('This will add rules in the .htaccess that redirects directly to existing converted files. ' .
|
11 |
+
'If you do not activate this setting, it will be the PHP script that handles the redirection to existing ' .
|
12 |
+
'webp files. Best performance is achieved by redirecting in .htaccess');
|
13 |
+
}
|
14 |
+
?>
|
15 |
</th>
|
16 |
<td>
|
17 |
<input type="checkbox" id="redirect_to_existing_in_htaccess" name="redirect-to-existing-in-htaccess" value="true" <?php echo ($config['redirect-to-existing-in-htaccess'] ? 'checked="checked"' : '') ?> >
|
18 |
+
|
19 |
+
<?php
|
20 |
+
/*if ($config['operation-mode'] == 'no-conversion') {
|
21 |
+
// Cache control header
|
22 |
+
echo '<div id="cache_control_div"><table style="margin-top: 10px">';
|
23 |
+
include_once __DIR__ . '/../serve-options/cache-control.inc';
|
24 |
+
echo '</table></div>';
|
25 |
+
}*/
|
26 |
+
?>
|
27 |
</td>
|
28 |
</tr>
|
@@ -1,35 +1,59 @@
|
|
1 |
-
<?php if ($config['operation-mode'] == 'tweaked') : ?>
|
2 |
<fieldset class="block">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
<h3>Redirection rules</h3>
|
4 |
-
<div><i>The options here affects the rules created in the .htaccess
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
<table class="form-table">
|
6 |
<tbody>
|
7 |
<?php
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
?>
|
16 |
</tbody>
|
17 |
</table>
|
18 |
</fieldset>
|
19 |
-
<?php
|
20 |
-
else:
|
21 |
-
if ($config['operation-mode'] == 'no-varied-responses') {
|
22 |
-
// ps: we call it "auto convert", when in this mode
|
23 |
-
// PPS: we include it directly in page.php now.
|
24 |
-
//include_once 'enable-redirection-to-converter.inc';
|
25 |
-
|
26 |
-
//include_once 'only-redirect-to-converter-on-cache-miss.inc';
|
27 |
-
|
28 |
-
}
|
29 |
-
if ($config['operation-mode'] == 'varied-responses') {
|
30 |
-
include_once 'redirect-to-existing.inc';
|
31 |
-
//include_once 'enable-redirection-to-webp-realizer.inc';
|
32 |
-
}
|
33 |
-
include_once 'image-types.inc';
|
34 |
-
endif;
|
35 |
-
?>
|
|
|
1 |
<fieldset class="block">
|
2 |
+
<?php if ($config['operation-mode'] == 'no-conversion') : ?>
|
3 |
+
<h2>Redirecting jpeg/png to existing webp (varied image response)</h2>
|
4 |
+
<p>
|
5 |
+
Enabling this adds rules to the <i>.htaccess</i> which internally redirects jpg/pngs to webp
|
6 |
+
and sets the <i>Vary:Accept</i> response header.
|
7 |
+
<i>Beware that special attention is needed if you are using a CDN (see FAQ).</i>
|
8 |
+
</p>
|
9 |
+
<?php elseif ($config['operation-mode'] == 'cdn-friendly') : ?>
|
10 |
+
<h2><i>.htaccess</i> rules for webp generation</h2>
|
11 |
+
<p>
|
12 |
+
The following redirect rules will not produce varied image responses.
|
13 |
+
Their job is simply to trigger webp conversion. Note that this is achieved <i>without</i> producing varied responses.
|
14 |
+
On most systems you need only to activate the first option. The second option can be used if the first one fails on your system.
|
15 |
+
</p>
|
16 |
+
<?php elseif ($config['operation-mode'] == 'varied-image-responses') : ?>
|
17 |
<h3>Redirection rules</h3>
|
18 |
+
<div><i>The options here affects the rules created in the .htaccess.<br>
|
19 |
+
Note: The option for enabling/disabling redirects to the converter is not available in this operation mode, as
|
20 |
+
that redirection is part of what defines this mode.
|
21 |
+
<?php echo helpIcon('Note: The general options also affects the rules.'); ?></i></div>
|
22 |
+
<?php else : ?>
|
23 |
+
<h3>Redirection rules</h3>
|
24 |
+
<div><i>The options here affects the rules created in the .htaccess. <?php echo helpIcon('Note: The general options also affects the rules.'); ?></i></div>
|
25 |
+
<?php endif; ?>
|
26 |
+
|
27 |
<table class="form-table">
|
28 |
<tbody>
|
29 |
<?php
|
30 |
+
switch ($config['operation-mode']) {
|
31 |
+
case 'tweaked':
|
32 |
+
include_once 'enable-redirection-to-converter.inc';
|
33 |
+
include_once 'only-redirect-to-converter-for-webp-enabled-browsers.inc';
|
34 |
+
include_once 'only-redirect-to-converter-on-cache-miss.inc';
|
35 |
+
include_once 'do-not-pass-source-path-in-query-string.inc';
|
36 |
+
include_once 'redirect-to-existing.inc';
|
37 |
+
include_once 'enable-redirection-to-webp-realizer.inc';
|
38 |
+
break;
|
39 |
+
case 'no-conversion':
|
40 |
+
include_once 'redirect-to-existing.inc';
|
41 |
+
include_once __DIR__. '/../general/cache-control.inc';
|
42 |
+
|
43 |
+
break;
|
44 |
+
case 'cdn-friendly':
|
45 |
+
//include_once 'redirect-to-existing.inc';
|
46 |
+
include_once 'enable-redirection-to-webp-realizer.inc';
|
47 |
+
|
48 |
+
// ps: we call it "auto convert", when in this mode
|
49 |
+
include_once 'enable-redirection-to-converter.inc';
|
50 |
+
break;
|
51 |
+
case 'varied-image-responses':
|
52 |
+
include_once 'redirect-to-existing.inc';
|
53 |
+
include_once 'enable-redirection-to-webp-realizer.inc';
|
54 |
+
break;
|
55 |
+
}
|
56 |
?>
|
57 |
</tbody>
|
58 |
</table>
|
59 |
</fieldset>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -5,7 +5,6 @@ echo '<tr><th scope="row">Response on failure';
|
|
5 |
echo helpIcon('Determines what to serve in case the image conversion should fail.');
|
6 |
echo '</th><td>';
|
7 |
|
8 |
-
//$fail = get_option('webp_express_failure_response');
|
9 |
$fail = $config['fail'];
|
10 |
echo '<select name="fail">';
|
11 |
echo '<option value="original"' . ($fail == 'original' ? ' selected' : '') . '>Original image</option>';
|
5 |
echo helpIcon('Determines what to serve in case the image conversion should fail.');
|
6 |
echo '</th><td>';
|
7 |
|
|
|
8 |
$fail = $config['fail'];
|
9 |
echo '<select name="fail">';
|
10 |
echo '<option value="original"' . ($fail == 'original' ? ' selected' : '') . '>Original image</option>';
|
@@ -3,7 +3,6 @@ echo '<tr><th scope="row">Response on success';
|
|
3 |
echo helpIcon('<p>Determines what to serve when conversion is a success. If you are using the Cache Enabler plugin, set to "Original image", otherwise you would normally set it to "Converted image".</p><p>If set to "Converted image", a Vary:Accept header will be sent to indicate that the response depends on the Accept header (which indicates if a browser supports webp images or not)</p><p>If set to "Original image", make sure to disable the "Redirect directly to converted image when available" option in the Redirect rules</p>');
|
4 |
echo '</th><td>';
|
5 |
|
6 |
-
//$successResponse = get_option('webp_express_failure_response');
|
7 |
$successResponse = $config['success-response'];
|
8 |
echo '<select name="success-response">';
|
9 |
echo '<option value="original"' . ($successResponse == 'original' ? ' selected' : '') . '>Original image</option>';
|
3 |
echo helpIcon('<p>Determines what to serve when conversion is a success. If you are using the Cache Enabler plugin, set to "Original image", otherwise you would normally set it to "Converted image".</p><p>If set to "Converted image", a Vary:Accept header will be sent to indicate that the response depends on the Accept header (which indicates if a browser supports webp images or not)</p><p>If set to "Original image", make sure to disable the "Redirect directly to converted image when available" option in the Redirect rules</p>');
|
4 |
echo '</th><td>';
|
5 |
|
|
|
6 |
$successResponse = $config['success-response'];
|
7 |
echo '<select name="success-response">';
|
8 |
echo '<option value="original"' . ($successResponse == 'original' ? ' selected' : '') . '>Original image</option>';
|
@@ -5,7 +5,6 @@
|
|
5 |
<table class="form-table">
|
6 |
<tbody>
|
7 |
<?php
|
8 |
-
include_once 'cache-control.inc';
|
9 |
include_once 'response-on-failure.inc';
|
10 |
include_once 'response-on-success.inc';
|
11 |
?>
|
@@ -13,9 +12,5 @@
|
|
13 |
</table>
|
14 |
</fieldset>
|
15 |
<?php
|
16 |
-
else:
|
17 |
-
if ($config['operation-mode'] != 'no-varied-responses') {
|
18 |
-
include_once 'cache-control.inc';
|
19 |
-
}
|
20 |
endif;
|
21 |
?>
|
5 |
<table class="form-table">
|
6 |
<tbody>
|
7 |
<?php
|
|
|
8 |
include_once 'response-on-failure.inc';
|
9 |
include_once 'response-on-success.inc';
|
10 |
?>
|
12 |
</table>
|
13 |
</fieldset>
|
14 |
<?php
|
|
|
|
|
|
|
|
|
15 |
endif;
|
16 |
?>
|
@@ -1,5 +1,4 @@
|
|
1 |
-
|
2 |
-
<fieldset class="block">
|
3 |
<h3>Web service</h3>
|
4 |
<table class="form-table">
|
5 |
<tbody>
|
@@ -9,8 +8,3 @@
|
|
9 |
</tbody>
|
10 |
</table>
|
11 |
</fieldset>
|
12 |
-
<?php
|
13 |
-
else:
|
14 |
-
include_once 'web-service.inc';
|
15 |
-
endif;
|
16 |
-
?>
|
1 |
+
<fieldset class="block">
|
|
|
2 |
<h3>Web service</h3>
|
3 |
<table class="form-table">
|
4 |
<tbody>
|
8 |
</tbody>
|
9 |
</table>
|
10 |
</fieldset>
|
|
|
|
|
|
|
|
|
|
@@ -7,7 +7,7 @@ use \WebPExpress\State;
|
|
7 |
use \WebPExpress\Messenger;
|
8 |
use \WebPExpress\PlatformInfo;
|
9 |
use \WebPExpress\FileHelper;
|
10 |
-
|
11 |
//include __DIR__ . "/page-welcome.php";
|
12 |
|
13 |
//echo 'display errors:' . ini_get('display_errors');
|
@@ -16,12 +16,102 @@ if ((!State::getState('configured', false))) {
|
|
16 |
include __DIR__ . "/page-welcome.php";
|
17 |
}
|
18 |
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
Messenger::printMessage(
|
21 |
-
'
|
22 |
-
|
23 |
);
|
24 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
/*
|
26 |
if (Config::isConfigFileThereAndOk() ) { // && PlatformInfo::definitelyGotModEnv()
|
27 |
if (!isset($_SERVER['HTACCESS'])) {
|
@@ -81,6 +171,8 @@ $haveRulesInIndexDir = HTAccess::haveWeRulesInThisHTAccessBestGuess(Paths::getIn
|
|
81 |
$haveRulesInContentDir = HTAccess::haveWeRulesInThisHTAccessBestGuess(Paths::getContentDirAbs() . '/.htaccess');
|
82 |
|
83 |
if ($haveRulesInIndexDir && $haveRulesInContentDir) {
|
|
|
|
|
84 |
if (!HTAccess::saveHTAccessRulesToFile(Paths::getIndexDirAbs() . '/.htaccess', '# WebP Express has placed its rules in your wp-content dir. Go there.', false)) {
|
85 |
Messenger::printMessage(
|
86 |
'warning',
|
@@ -104,7 +196,7 @@ if ($ht !== false) {
|
|
104 |
'In order for the "Convert non-existing webp-files upon request" functionality to work, you need to either:<br>' .
|
105 |
'- Move the WebP Express rules above the Wordpress rules in the .htaccess file located in your root dir<br>' .
|
106 |
'- Grant the webserver permission to your wp-content dir, so it can create its rules there instead.'
|
107 |
-
);
|
108 |
}
|
109 |
}
|
110 |
}
|
7 |
use \WebPExpress\Messenger;
|
8 |
use \WebPExpress\PlatformInfo;
|
9 |
use \WebPExpress\FileHelper;
|
10 |
+
use \WebPExpress\CapabilityTest;
|
11 |
//include __DIR__ . "/page-welcome.php";
|
12 |
|
13 |
//echo 'display errors:' . ini_get('display_errors');
|
16 |
include __DIR__ . "/page-welcome.php";
|
17 |
}
|
18 |
|
19 |
+
|
20 |
+
/*
|
21 |
+
if (CapabilityTest::modRewriteWorking()) {
|
22 |
+
echo 'mod rewrite works. that is nice';
|
23 |
+
}*/
|
24 |
+
|
25 |
+
/*if (CapabilityTest::modHeaderWorking() === true) {
|
26 |
+
//echo 'nice!';
|
27 |
+
}*/
|
28 |
+
/*
|
29 |
+
if (CapabilityTest::copyCapabilityTestsToWpContent()) {
|
30 |
+
echo 'copy ok!';
|
31 |
+
} else {
|
32 |
+
echo 'copy failed!';
|
33 |
+
}*/
|
34 |
+
|
35 |
+
|
36 |
+
|
37 |
+
$anyRedirectionToConverterEnabled = (($config['enable-redirection-to-converter']) || ($config['enable-redirection-to-webp-realizer']));
|
38 |
+
$anyRedirectionEnabled = ($anyRedirectionToConverterEnabled || $config['redirect-to-existing-in-htaccess']);
|
39 |
+
|
40 |
+
if ($anyRedirectionEnabled) {
|
41 |
+
if (PlatformInfo::definitelyNotGotModRewrite()) {
|
42 |
+
Messenger::printMessage(
|
43 |
+
'error',
|
44 |
+
"Rewriting isn't enabled on your server. ' .
|
45 |
+
'Currently, the only way to make WebP Express generate webp files is with rewriting. '
|
46 |
+
'If you got the webp files through other means, you can use CDN friendly mode and disable the rewrites. ' .
|
47 |
+
'Or perhaps you want to enable rewriting? Tell your host or system administrator to enable the 'mod_rewrite' module. ' .
|
48 |
+
'If you are on a shared host, chances are that mod_rewrite can be turned on in your control panel."
|
49 |
+
);
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
$cacheEnablerActivated = in_array('cache-enabler/cache-enabler.php', get_option('active_plugins', []));
|
54 |
+
if ($cacheEnablerActivated) {
|
55 |
+
$cacheEnablerSettings = get_option('cache-enabler', []);
|
56 |
+
$webpEnabled = (isset($cacheEnablerSettings['webp']) && $cacheEnablerSettings['webp']);
|
57 |
+
}
|
58 |
+
|
59 |
+
if ($cacheEnablerActivated && !$webpEnabled) {
|
60 |
Messenger::printMessage(
|
61 |
+
'warning',
|
62 |
+
'You are using Cache Enabler, but have not enabled the webp option, so Cache Enabler is not operating with a separate cache for webp-enabled browsers.'
|
63 |
);
|
64 |
}
|
65 |
+
|
66 |
+
if (($config['operation-mode'] == 'cdn-friendly') && !$config['alter-html']['enabled']) {
|
67 |
+
//echo print_r(get_option('cache-enabler'), true);
|
68 |
+
|
69 |
+
|
70 |
+
if ($cacheEnablerActivated) {
|
71 |
+
if ($webpEnabled) {
|
72 |
+
Messenger::printMessage(
|
73 |
+
'info',
|
74 |
+
'You should consider enabling Alter HTML. This is not neccessary, as you have <i>Cache Enabler</i> enabled, which alters HTML. ' .
|
75 |
+
'However, it is a good idea because currently <i>Cache Enabler</i> does not replace as many URLs as WebP Express (ie background images in inline styles)'
|
76 |
+
);
|
77 |
+
}
|
78 |
+
|
79 |
+
} else {
|
80 |
+
Messenger::printMessage(
|
81 |
+
'warning',
|
82 |
+
'You are in CDN friendly mode but have not enabled Alter HTML (and you are not using Cache Enabler either). ' .
|
83 |
+
'This is usually a misconfiguration because in this mode, the only way to get webp files is by referencing them in the HTML.'
|
84 |
+
);
|
85 |
+
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
if (!$anyRedirectionToConverterEnabled && ($config['operation-mode'] == 'cdn-friendly')) {
|
90 |
+
// this can not happen in varied image responses. it is ok in no-conversion, and also tweaked, because one could wish to tweak the no-conversion mode
|
91 |
+
Messenger::printMessage(
|
92 |
+
'warning',
|
93 |
+
'You have not enabled any of the redirects to the converter. ' .
|
94 |
+
'At least one of the redirects is required for triggering WebP generation.'
|
95 |
+
);
|
96 |
+
}
|
97 |
+
|
98 |
+
if ($config['alter-html']['enabled'] && !$config['alter-html']['only-for-webps-that-exists'] && !$config['enable-redirection-to-webp-realizer']) {
|
99 |
+
Messenger::printMessage(
|
100 |
+
'warning',
|
101 |
+
'You have configured Alter HTML to make references to WebP files that are yet to exist, ' .
|
102 |
+
'<i>but you have not enabled the option that makes these files come true when requested</i>. Do that!'
|
103 |
+
);
|
104 |
+
}
|
105 |
+
|
106 |
+
if ($config['enable-redirection-to-webp-realizer'] && $config['alter-html']['enabled'] && $config['alter-html']['only-for-webps-that-exists']) {
|
107 |
+
Messenger::printMessage(
|
108 |
+
'warning',
|
109 |
+
'You have enabled the option that redirects requests for non-existing webp files to the converter, ' .
|
110 |
+
'<i>but you have not enabled the option to point to these in Alter HTML</i>. Please do that!'
|
111 |
+
);
|
112 |
+
}
|
113 |
+
|
114 |
+
|
115 |
/*
|
116 |
if (Config::isConfigFileThereAndOk() ) { // && PlatformInfo::definitelyGotModEnv()
|
117 |
if (!isset($_SERVER['HTACCESS'])) {
|
171 |
$haveRulesInContentDir = HTAccess::haveWeRulesInThisHTAccessBestGuess(Paths::getContentDirAbs() . '/.htaccess');
|
172 |
|
173 |
if ($haveRulesInIndexDir && $haveRulesInContentDir) {
|
174 |
+
// TODO: Use new method for determining if htaccess contains rules.
|
175 |
+
// (either haveWeRulesInThisHTAccessBestGuess($filename) or haveWeRulesInThisHTAccess($filename))
|
176 |
if (!HTAccess::saveHTAccessRulesToFile(Paths::getIndexDirAbs() . '/.htaccess', '# WebP Express has placed its rules in your wp-content dir. Go there.', false)) {
|
177 |
Messenger::printMessage(
|
178 |
'warning',
|
196 |
'In order for the "Convert non-existing webp-files upon request" functionality to work, you need to either:<br>' .
|
197 |
'- Move the WebP Express rules above the Wordpress rules in the .htaccess file located in your root dir<br>' .
|
198 |
'- Grant the webserver permission to your wp-content dir, so it can create its rules there instead.'
|
199 |
+
);
|
200 |
}
|
201 |
}
|
202 |
}
|
@@ -15,6 +15,9 @@ use \WebPExpress\HTAccess;
|
|
15 |
include_once __DIR__ . '/../classes/Messenger.php';
|
16 |
use \WebPExpress\Messenger;
|
17 |
|
|
|
|
|
|
|
18 |
include_once __DIR__ . '/../classes/Paths.php';
|
19 |
use \WebPExpress\Paths;
|
20 |
|
@@ -27,12 +30,13 @@ use \WebPExpress\State;
|
|
27 |
include_once __DIR__ . '/../classes/TestRun.php';
|
28 |
use \WebPExpress\TestRun;
|
29 |
|
|
|
30 |
if (!current_user_can('manage_options')) {
|
31 |
wp_die('You do not have sufficient permissions to access this page.');
|
32 |
}
|
33 |
?>
|
34 |
<div class="wrap">
|
35 |
-
<h2>WebP Express Settings
|
36 |
|
37 |
<?php
|
38 |
|
@@ -64,12 +68,15 @@ function printAutoQualityOptionForConverter($converterId) {
|
|
64 |
</div>
|
65 |
<?php
|
66 |
}
|
67 |
-
//update_option('webp-express-migration-version', '1');
|
68 |
|
69 |
$canDetectQuality = TestRun::isLocalQualityDetectionWorking();
|
70 |
$testResult = TestRun::getConverterStatus();
|
71 |
$config = Config::getConfigForOptionsPage();
|
72 |
|
|
|
|
|
|
|
|
|
73 |
if (!$testResult) {
|
74 |
Messenger::printMessage(
|
75 |
'error',
|
@@ -98,9 +105,11 @@ $webpexpress_settings_nonce = wp_create_nonce('webpexpress_settings_nonce');
|
|
98 |
<?php
|
99 |
//echo get_theme_root_uri();
|
100 |
|
101 |
-
include_once __DIR__ . '/../classes/AlterHtmlHelper.php';
|
|
|
|
|
102 |
|
103 |
-
echo '<form id="webpexpress_settings" action="' . esc_url(
|
104 |
?>
|
105 |
<input type="hidden" name="action" value="webpexpress_settings_submit">
|
106 |
<input type="hidden" name="webpexpress_settings_nonce" value="<?php echo $webpexpress_settings_nonce ?>" />
|
@@ -141,11 +150,30 @@ function webpexpress_selectBoxOptions($selected, $options) {
|
|
141 |
}
|
142 |
}
|
143 |
|
144 |
-
function
|
145 |
-
|
146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
$id = str_replace('-', '_', $optionName . '_' . $optionValue);
|
148 |
echo '<li>';
|
|
|
|
|
|
|
|
|
149 |
echo '<input type="radio" id="' . $id . '"';
|
150 |
if ($optionValue == $selected) {
|
151 |
echo ' checked="checked"';
|
@@ -157,6 +185,7 @@ function webpexpress_radioButtons($optionName, $selected, $options, $helpTexts =
|
|
157 |
echo helpIcon($helpTexts[$optionValue]);
|
158 |
}
|
159 |
echo '</label>';
|
|
|
160 |
echo '</li>';
|
161 |
}
|
162 |
echo '</ul>';
|
@@ -182,44 +211,71 @@ function webpexpress_checkbox($optionName, $checked, $label, $helpText = '') {
|
|
182 |
}
|
183 |
|
184 |
include_once 'options/operation-mode.inc';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
|
186 |
if ($config['operation-mode'] != 'tweaked') {
|
187 |
-
echo '<fieldset class="block">';
|
188 |
-
echo '<table class="form-table"><tbody>';
|
189 |
}
|
190 |
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
|
|
|
|
196 |
include_once 'options/conversion-options/destination-extension.inc';
|
197 |
-
|
198 |
-
|
199 |
|
200 |
-
|
201 |
include_once 'options/alter-html/alter-html.inc';
|
202 |
-
}
|
|
|
|
|
|
|
|
|
203 |
|
204 |
-
|
205 |
-
include_once 'options/redirection-rules/enable-redirection-to-webp-realizer.inc';
|
206 |
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
|
211 |
-
|
212 |
-
|
213 |
-
}
|
214 |
|
|
|
|
|
|
|
|
|
215 |
|
216 |
-
if ($config['operation-mode'] != 'just-redirect') {
|
217 |
include_once 'options/web-service-options/web-service-options.inc';
|
218 |
}
|
219 |
|
220 |
if ($config['operation-mode'] != 'tweaked') {
|
221 |
-
echo '</tbody></table>';
|
222 |
-
echo '</fieldset>';
|
223 |
}
|
224 |
|
225 |
?>
|
15 |
include_once __DIR__ . '/../classes/Messenger.php';
|
16 |
use \WebPExpress\Messenger;
|
17 |
|
18 |
+
include_once __DIR__ . '/../classes/Multisite.php';
|
19 |
+
use \WebPExpress\Multisite;
|
20 |
+
|
21 |
include_once __DIR__ . '/../classes/Paths.php';
|
22 |
use \WebPExpress\Paths;
|
23 |
|
30 |
include_once __DIR__ . '/../classes/TestRun.php';
|
31 |
use \WebPExpress\TestRun;
|
32 |
|
33 |
+
|
34 |
if (!current_user_can('manage_options')) {
|
35 |
wp_die('You do not have sufficient permissions to access this page.');
|
36 |
}
|
37 |
?>
|
38 |
<div class="wrap">
|
39 |
+
<h2>WebP Express Settings<?php echo Multisite::isNetworkActivated() ? ' (network)' : ''; ?></h2>
|
40 |
|
41 |
<?php
|
42 |
|
68 |
</div>
|
69 |
<?php
|
70 |
}
|
|
|
71 |
|
72 |
$canDetectQuality = TestRun::isLocalQualityDetectionWorking();
|
73 |
$testResult = TestRun::getConverterStatus();
|
74 |
$config = Config::getConfigForOptionsPage();
|
75 |
|
76 |
+
//State::setState('last-ewww-optimize-attempt', 0);
|
77 |
+
//State::setState('last-ewww-optimize', 0);
|
78 |
+
\WebPExpress\KeepEwwwSubscriptionAlive::keepAliveIfItIsTime($config);
|
79 |
+
|
80 |
if (!$testResult) {
|
81 |
Messenger::printMessage(
|
82 |
'error',
|
105 |
<?php
|
106 |
//echo get_theme_root_uri();
|
107 |
|
108 |
+
//include_once __DIR__ . '/../classes/AlterHtmlHelper.php';
|
109 |
+
//$actionUrl = Multisite::isNetworkActivated() ? network_admin_url( 'admin-post.php' ) : admin_url( 'admin-post.php' );
|
110 |
+
$actionUrl = admin_url('admin-post.php');
|
111 |
|
112 |
+
echo '<form id="webpexpress_settings" action="' . esc_url($actionUrl) . '" method="post" >';
|
113 |
?>
|
114 |
<input type="hidden" name="action" value="webpexpress_settings_submit">
|
115 |
<input type="hidden" name="webpexpress_settings_nonce" value="<?php echo $webpexpress_settings_nonce ?>" />
|
150 |
}
|
151 |
}
|
152 |
|
153 |
+
function webpexpress_radioButton($optionName, $optionValue, $label, $selectedValue, $helpText = null) {
|
154 |
+
$id = str_replace('-', '_', $optionName . '_' . $optionValue);
|
155 |
+
echo '<input type="radio" id="' . $id . '"';
|
156 |
+
if ($optionValue == $selectedValue) {
|
157 |
+
echo ' checked="checked"';
|
158 |
+
}
|
159 |
+
echo ' name="' . $optionName . '" value="' . $optionValue . '" style="margin-right: 10px">';
|
160 |
+
echo '<label for="' . $id . '">';
|
161 |
+
echo $label;
|
162 |
+
if (!is_null($helpText)) {
|
163 |
+
echo helpIcon($helpText);
|
164 |
+
}
|
165 |
+
echo '</label>';
|
166 |
+
}
|
167 |
+
|
168 |
+
function webpexpress_radioButtons($optionName, $selected, $options, $helpTexts = [], $style='margin-left: 20px; margin-top: 5px') {
|
169 |
+
echo '<ul style="' . $style . '">';
|
170 |
+
foreach ($options as $optionValue => $label) {
|
171 |
$id = str_replace('-', '_', $optionName . '_' . $optionValue);
|
172 |
echo '<li>';
|
173 |
+
|
174 |
+
webpexpress_radioButton($optionName, $optionValue, $label, $selected, isset($helpTexts[$optionValue]) ? $helpTexts[$optionValue] : null);
|
175 |
+
|
176 |
+
/*
|
177 |
echo '<input type="radio" id="' . $id . '"';
|
178 |
if ($optionValue == $selected) {
|
179 |
echo ' checked="checked"';
|
185 |
echo helpIcon($helpTexts[$optionValue]);
|
186 |
}
|
187 |
echo '</label>';
|
188 |
+
*/
|
189 |
echo '</li>';
|
190 |
}
|
191 |
echo '</ul>';
|
211 |
}
|
212 |
|
213 |
include_once 'options/operation-mode.inc';
|
214 |
+
include_once 'options/general/general.inc';
|
215 |
+
|
216 |
+
|
217 |
+
/*
|
218 |
+
idea:
|
219 |
+
|
220 |
+
$options = [
|
221 |
+
'tweaked' => [
|
222 |
+
'general' => [
|
223 |
+
'image-types',
|
224 |
+
'destination-folder',
|
225 |
+
'destination-extension',
|
226 |
+
'cache-control'
|
227 |
+
]
|
228 |
+
],
|
229 |
+
...
|
230 |
+
];
|
231 |
+
*/
|
232 |
+
|
233 |
|
234 |
if ($config['operation-mode'] != 'tweaked') {
|
235 |
+
// echo '<fieldset class="block">';
|
236 |
+
// echo '<table class="form-table"><tbody>';
|
237 |
}
|
238 |
|
239 |
+
if ($config['operation-mode'] == 'no-conversion') {
|
240 |
+
|
241 |
+
// General
|
242 |
+
/*
|
243 |
+
echo '<tr><th colspan=2>';
|
244 |
+
echo '<h2>General</h2>';
|
245 |
+
echo '</th></tr>';
|
246 |
include_once 'options/conversion-options/destination-extension.inc';
|
247 |
+
include_once 'options/general/image-types.inc';
|
248 |
+
*/
|
249 |
|
250 |
+
include_once 'options/redirection-rules/redirection-rules.inc';
|
251 |
include_once 'options/alter-html/alter-html.inc';
|
252 |
+
} else {
|
253 |
+
include_once 'options/redirection-rules/redirection-rules.inc';
|
254 |
+
include_once 'options/conversion-options/conversion-options.inc';
|
255 |
+
//include_once 'options/conversion-options/destination-extension.inc';
|
256 |
+
include_once 'options/serve-options/serve-options.inc';
|
257 |
|
258 |
+
include_once 'options/alter-html/alter-html.inc';
|
|
|
259 |
|
260 |
+
/*
|
261 |
+
if ($config['operation-mode'] == 'cdn-friendly') {
|
262 |
+
include_once 'options/redirection-rules/enable-redirection-to-webp-realizer.inc';
|
263 |
|
264 |
+
// ps: we call it "auto convert", when in this mode
|
265 |
+
include_once 'options/redirection-rules/enable-redirection-to-converter.inc';
|
266 |
+
}
|
267 |
|
268 |
+
if ($config['operation-mode'] == 'varied-image-responses') {
|
269 |
+
include_once 'options/redirection-rules/enable-redirection-to-webp-realizer.inc';
|
270 |
+
}
|
271 |
+
*/
|
272 |
|
|
|
273 |
include_once 'options/web-service-options/web-service-options.inc';
|
274 |
}
|
275 |
|
276 |
if ($config['operation-mode'] != 'tweaked') {
|
277 |
+
// echo '</tbody></table>';
|
278 |
+
// echo '</fieldset>';
|
279 |
}
|
280 |
|
281 |
?>
|
@@ -15,6 +15,9 @@ use \WebPExpress\Messenger;
|
|
15 |
include_once __DIR__ . '/../classes/Paths.php';
|
16 |
use \WebPExpress\Paths;
|
17 |
|
|
|
|
|
|
|
18 |
// https://premium.wpmudev.org/blog/handling-form-submissions/
|
19 |
// checkout https://codex.wordpress.org/Function_Reference/sanitize_meta
|
20 |
|
@@ -26,7 +29,7 @@ function webp_express_sanitize_quality_field($text) {
|
|
26 |
return max(0, min($q, 100));
|
27 |
}
|
28 |
|
29 |
-
$config = Config::loadConfigAndFix();
|
30 |
$oldConfig = $config;
|
31 |
|
32 |
// Set options that are available in all operation modes
|
@@ -40,7 +43,7 @@ $config = array_merge($config, [
|
|
40 |
]);
|
41 |
|
42 |
// Set options that are available in all operation modes, except the "CDN friendly" mode
|
43 |
-
if ($_POST['operation-mode'] != '
|
44 |
|
45 |
$cacheControl = sanitize_text_field($_POST['cache-control']);
|
46 |
$config['cache-control'] = $cacheControl;
|
@@ -58,13 +61,35 @@ if ($_POST['operation-mode'] != 'no-varied-responses') {
|
|
58 |
}
|
59 |
}
|
60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
-
// Set options that are available in all operation modes, except the "just-redirect" mode
|
63 |
-
if ($_POST['operation-mode'] != 'just-redirect') {
|
64 |
|
65 |
-
|
|
|
66 |
|
67 |
|
|
|
|
|
68 |
// Metadata
|
69 |
// --------
|
70 |
$config['metadata'] = sanitize_text_field($_POST['metadata']);
|
@@ -142,37 +167,30 @@ if ($_POST['operation-mode'] != 'just-redirect') {
|
|
142 |
}
|
143 |
}
|
144 |
}
|
145 |
-
|
146 |
-
// Alter HTML
|
147 |
-
|
148 |
-
$config['alter-html'] = [];
|
149 |
-
$config['alter-html']['enabled'] = isset($_POST['alter-html-enabled']);
|
150 |
-
if ($_POST['alter-html-replacement'] == 'url') {
|
151 |
-
$config['alter-html']['only-for-webp-enabled-browsers'] = isset($_POST['alter-html-only-for-webp-enabled-browsers']);
|
152 |
-
} else {
|
153 |
-
$config['alter-html']['only-for-webp-enabled-browsers'] = false;
|
154 |
-
}
|
155 |
-
$config['alter-html']['only-for-webps-that-exists'] = (!isset($_POST['alter-html-for-webps-that-has-yet-to-exist']));
|
156 |
-
$config['alter-html']['replacement'] = $_POST['alter-html-replacement'];
|
157 |
-
$config['alter-html']['hooks'] = $_POST['alter-html-hooks'];
|
158 |
-
|
159 |
}
|
160 |
|
|
|
161 |
switch ($_POST['operation-mode']) {
|
162 |
-
case 'varied-responses':
|
163 |
$config = array_merge($config, [
|
164 |
'redirect-to-existing-in-htaccess' => isset($_POST['redirect-to-existing-in-htaccess']),
|
165 |
'destination-folder' => $_POST['destination-folder'],
|
166 |
'destination-extension' => (($_POST['destination-folder'] == 'mingled') ? $_POST['destination-extension'] : 'append'),
|
167 |
]);
|
168 |
break;
|
169 |
-
case '
|
170 |
$config = array_merge($config, [
|
171 |
'destination-folder' => $_POST['destination-folder'],
|
172 |
'destination-extension' => (($_POST['destination-folder'] == 'mingled') ? $_POST['destination-extension'] : 'append'),
|
173 |
'enable-redirection-to-converter' => isset($_POST['enable-redirection-to-converter']), // PS: its called "autoconvert" in this mode
|
174 |
]);
|
175 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
case 'tweaked':
|
177 |
$config = array_merge($config, [
|
178 |
'enable-redirection-to-converter' => isset($_POST['enable-redirection-to-converter']),
|
@@ -194,6 +212,12 @@ if ($_POST['operation-mode'] != $_POST['change-operation-mode']) {
|
|
194 |
$config = Config::applyOperationMode($config);
|
195 |
}
|
196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
// SAVE!
|
198 |
// -----
|
199 |
$result = Config::saveConfigurationAndHTAccess($config, isset($_POST['force']));
|
@@ -312,7 +336,7 @@ if (!$result['saved-both-config']) {
|
|
312 |
|
313 |
Messenger::addMessage(
|
314 |
'success',
|
315 |
-
'Configuration saved
|
316 |
(Paths::isWPContentDirMoved() ? ' (which you moved, btw)' : '') .
|
317 |
($savedToPluginsToo ? ' as well as in your <i>plugins</i> folder' : '') .
|
318 |
((Paths::isWPContentDirMoved() && $savedToPluginsToo) ? ' (you moved that as well!)' : '.') .
|
15 |
include_once __DIR__ . '/../classes/Paths.php';
|
16 |
use \WebPExpress\Paths;
|
17 |
|
18 |
+
use \WebPExpress\CapabilityTest;
|
19 |
+
|
20 |
+
|
21 |
// https://premium.wpmudev.org/blog/handling-form-submissions/
|
22 |
// checkout https://codex.wordpress.org/Function_Reference/sanitize_meta
|
23 |
|
29 |
return max(0, min($q, 100));
|
30 |
}
|
31 |
|
32 |
+
$config = Config::loadConfigAndFix(false); // false, because we do not need to test if quality detection is working
|
33 |
$oldConfig = $config;
|
34 |
|
35 |
// Set options that are available in all operation modes
|
43 |
]);
|
44 |
|
45 |
// Set options that are available in all operation modes, except the "CDN friendly" mode
|
46 |
+
if ($_POST['operation-mode'] != 'cdn-friendly') {
|
47 |
|
48 |
$cacheControl = sanitize_text_field($_POST['cache-control']);
|
49 |
$config['cache-control'] = $cacheControl;
|
61 |
}
|
62 |
}
|
63 |
|
64 |
+
// Set options that are available in ALL operation modes
|
65 |
+
|
66 |
+
// Alter HTML
|
67 |
+
$config['alter-html'] = [];
|
68 |
+
$config['alter-html']['enabled'] = isset($_POST['alter-html-enabled']);
|
69 |
+
if ($_POST['alter-html-replacement'] == 'url') {
|
70 |
+
$config['alter-html']['only-for-webp-enabled-browsers'] = isset($_POST['alter-html-only-for-webp-enabled-browsers']);
|
71 |
+
} else {
|
72 |
+
$config['alter-html']['only-for-webp-enabled-browsers'] = false;
|
73 |
+
}
|
74 |
+
if ($_POST['alter-html-replacement'] == 'picture') {
|
75 |
+
$config['alter-html']['alter-html-add-picturefill-js'] = isset($_POST['alter-html-add-picturefill-js']);
|
76 |
+
}
|
77 |
+
if ($_POST['operation-mode'] != 'no-conversion') {
|
78 |
+
$config['alter-html']['only-for-webps-that-exists'] = (!isset($_POST['alter-html-for-webps-that-has-yet-to-exist']));
|
79 |
+
} else {
|
80 |
+
$config['alter-html']['only-for-webps-that-exists'] = true;
|
81 |
+
}
|
82 |
+
|
83 |
+
$config['alter-html']['replacement'] = $_POST['alter-html-replacement'];
|
84 |
+
$config['alter-html']['hooks'] = $_POST['alter-html-hooks'];
|
85 |
|
|
|
|
|
86 |
|
87 |
+
// Set options that are available in all operation modes, except the "no-conversion" mode
|
88 |
+
if ($_POST['operation-mode'] != 'no-conversion') {
|
89 |
|
90 |
|
91 |
+
$config['enable-redirection-to-webp-realizer'] = isset($_POST['enable-redirection-to-webp-realizer']);
|
92 |
+
|
93 |
// Metadata
|
94 |
// --------
|
95 |
$config['metadata'] = sanitize_text_field($_POST['metadata']);
|
167 |
}
|
168 |
}
|
169 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
}
|
171 |
|
172 |
+
|
173 |
switch ($_POST['operation-mode']) {
|
174 |
+
case 'varied-image-responses':
|
175 |
$config = array_merge($config, [
|
176 |
'redirect-to-existing-in-htaccess' => isset($_POST['redirect-to-existing-in-htaccess']),
|
177 |
'destination-folder' => $_POST['destination-folder'],
|
178 |
'destination-extension' => (($_POST['destination-folder'] == 'mingled') ? $_POST['destination-extension'] : 'append'),
|
179 |
]);
|
180 |
break;
|
181 |
+
case 'cdn-friendly':
|
182 |
$config = array_merge($config, [
|
183 |
'destination-folder' => $_POST['destination-folder'],
|
184 |
'destination-extension' => (($_POST['destination-folder'] == 'mingled') ? $_POST['destination-extension'] : 'append'),
|
185 |
'enable-redirection-to-converter' => isset($_POST['enable-redirection-to-converter']), // PS: its called "autoconvert" in this mode
|
186 |
]);
|
187 |
break;
|
188 |
+
case 'no-conversion':
|
189 |
+
$config = array_merge($config, [
|
190 |
+
'redirect-to-existing-in-htaccess' => isset($_POST['redirect-to-existing-in-htaccess']),
|
191 |
+
'destination-extension' => $_POST['destination-extension'],
|
192 |
+
]);
|
193 |
+
break;
|
194 |
case 'tweaked':
|
195 |
$config = array_merge($config, [
|
196 |
'enable-redirection-to-converter' => isset($_POST['enable-redirection-to-converter']),
|
212 |
$config = Config::applyOperationMode($config);
|
213 |
}
|
214 |
|
215 |
+
// If we are going to save .htaccess, run and store capability tests first (we should only store results when .htaccess is updated as well)
|
216 |
+
if (isset($_POST['force']) || HTAccess::doesRewriteRulesNeedUpdate($config)) {
|
217 |
+
Config::runAndStoreCapabilityTests($config);
|
218 |
+
}
|
219 |
+
|
220 |
+
|
221 |
// SAVE!
|
222 |
// -----
|
223 |
$result = Config::saveConfigurationAndHTAccess($config, isset($_POST['force']));
|
336 |
|
337 |
Messenger::addMessage(
|
338 |
'success',
|
339 |
+
'Configuration saved.<br>Rewrite rules were saved to your <i>.htaccess</i> in your <i>' . $mainResult . '</i> folder' .
|
340 |
(Paths::isWPContentDirMoved() ? ' (which you moved, btw)' : '') .
|
341 |
($savedToPluginsToo ? ' as well as in your <i>plugins</i> folder' : '') .
|
342 |
((Paths::isWPContentDirMoved() && $savedToPluginsToo) ? ' (you moved that as well!)' : '.') .
|
@@ -6,6 +6,7 @@
|
|
6 |
include_once __DIR__ . '/classes/Paths.php';
|
7 |
use \WebPExpress\Paths;
|
8 |
|
|
|
9 |
|
10 |
/* helper. Remove dir recursively. No warnings - fails silently */
|
11 |
function webpexpress_rrmdir($dir) {
|
@@ -32,8 +33,8 @@ $optionsToDelete = [
|
|
32 |
'webp-express-migration-version'
|
33 |
];
|
34 |
foreach ($optionsToDelete as $i => $optionName) {
|
35 |
-
|
36 |
}
|
37 |
|
38 |
-
// remove content dir (config plus images)
|
39 |
webpexpress_rrmdir(Paths::getWebPExpressContentDirAbs());
|
6 |
include_once __DIR__ . '/classes/Paths.php';
|
7 |
use \WebPExpress\Paths;
|
8 |
|
9 |
+
use \WebPExpress\Option;
|
10 |
|
11 |
/* helper. Remove dir recursively. No warnings - fails silently */
|
12 |
function webpexpress_rrmdir($dir) {
|
33 |
'webp-express-migration-version'
|
34 |
];
|
35 |
foreach ($optionsToDelete as $i => $optionName) {
|
36 |
+
Option::deleteOption($optionName);
|
37 |
}
|
38 |
|
39 |
+
// remove content dir (config plus images plus htaccess-tests)
|
40 |
webpexpress_rrmdir(Paths::getWebPExpressContentDirAbs());
|
@@ -3,10 +3,11 @@
|
|
3 |
* Plugin Name: WebP Express
|
4 |
* Plugin URI: https://github.com/rosell-dk/webp-express
|
5 |
* Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
|
6 |
-
* Version: 0.
|
7 |
* Author: Bjørn Rosell
|
8 |
* Author URI: https://www.bitwise-it.dk
|
9 |
* License: GPL2
|
|
|
10 |
*/
|
11 |
|
12 |
/*
|
@@ -16,6 +17,17 @@ Note: Perhaps create a plugin page on my website?, ie https://www.bitwise-it.dk/
|
|
16 |
define('WEBPEXPRESS_PLUGIN', __FILE__);
|
17 |
define('WEBPEXPRESS_PLUGIN_DIR', __DIR__);
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
if (is_admin()) {
|
20 |
include __DIR__ . '/lib/admin.php';
|
21 |
}
|
@@ -36,7 +48,8 @@ function webp_express_process_post() {
|
|
36 |
}
|
37 |
add_action( 'init', 'webp_express_process_post' );
|
38 |
|
39 |
-
|
|
|
40 |
require_once __DIR__ . '/lib/classes/AlterHtmlInit.php';
|
41 |
\WebPExpress\AlterHtmlInit::setHooks();
|
42 |
}
|
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.12.0
|
7 |
* Author: Bjørn Rosell
|
8 |
* Author URI: https://www.bitwise-it.dk
|
9 |
* License: GPL2
|
10 |
+
* Network: true
|
11 |
*/
|
12 |
|
13 |
/*
|
17 |
define('WEBPEXPRESS_PLUGIN', __FILE__);
|
18 |
define('WEBPEXPRESS_PLUGIN_DIR', __DIR__);
|
19 |
|
20 |
+
use \WebPExpress\Option;
|
21 |
+
|
22 |
+
spl_autoload_register('webpexpress_autoload');
|
23 |
+
function webpexpress_autoload($class) {
|
24 |
+
//echo $class . "\n<br>";
|
25 |
+
if (strpos($class, 'WebPExpress\\') === 0) {
|
26 |
+
//echo WEBPEXPRESS_PLUGIN_DIR . '/lib/classes/' . substr($class, 12) . '.php' . "\n<br><br>";
|
27 |
+
require_once WEBPEXPRESS_PLUGIN_DIR . '/lib/classes/' . substr($class, 12) . '.php';
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
if (is_admin()) {
|
32 |
include __DIR__ . '/lib/admin.php';
|
33 |
}
|
48 |
}
|
49 |
add_action( 'init', 'webp_express_process_post' );
|
50 |
|
51 |
+
|
52 |
+
if (Option::getOption('webp-express-alter-html', false)) {
|
53 |
require_once __DIR__ . '/lib/classes/AlterHtmlInit.php';
|
54 |
\WebPExpress\AlterHtmlInit::setHooks();
|
55 |
}
|
@@ -15,6 +15,36 @@ error_reporting(E_ALL);
|
|
15 |
use \WebPConvert\WebPConvert;
|
16 |
use \WebPConvert\ServeExistingOrHandOver;
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
function loadConfig($configFilename) {
|
19 |
if (!file_exists($configFilename)) {
|
20 |
header('X-WebP-Express-Error: Configuration file not found!', true);
|
@@ -30,61 +60,100 @@ function loadConfig($configFilename) {
|
|
30 |
return json_decode($json, true);
|
31 |
}
|
32 |
|
33 |
-
function getSource(
|
34 |
-
|
|
|
35 |
|
36 |
// First check if it is in an environment variable - thats the safest way
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
}
|
41 |
}
|
42 |
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
if (isset($_SERVER['HTTP_REQFN'])) {
|
45 |
return $_SERVER['HTTP_REQFN'];
|
46 |
}
|
47 |
}
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
|
|
55 |
}
|
56 |
|
57 |
// Last resort is to use $_SERVER['REQUEST_URI'], well knowing that it does not give the
|
58 |
// correct result in all setups (ie "folder method 1")
|
59 |
$requestUriNoQS = explode('?', $_SERVER['REQUEST_URI'])[0];
|
60 |
-
|
61 |
$source = $docRoot . urldecode($requestUriNoQS);
|
62 |
if (file_exists($source)) {
|
63 |
return $source;
|
64 |
}
|
65 |
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
|
|
|
|
|
|
|
|
|
|
70 |
}
|
71 |
-
|
72 |
-
|
|
|
|
|
73 |
}
|
74 |
-
|
|
|
|
|
75 |
}
|
76 |
|
77 |
$docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
|
78 |
-
$
|
79 |
-
$
|
80 |
-
$webExpressContentDirAbs = $docRoot . '/' . $webExpressContentDirRel;
|
81 |
-
$configFilename = $webExpressContentDirAbs . '/config/wod-options.json';
|
82 |
-
|
83 |
-
$options = loadConfig($configFilename);
|
84 |
|
85 |
-
$
|
86 |
-
$allowInHeader = true; // todo: implement setting
|
87 |
-
$source = getSource($allowInQS, $allowInHeader);
|
88 |
//$source = getSource(false, false);
|
89 |
|
90 |
//echo $source; exit;
|
15 |
use \WebPConvert\WebPConvert;
|
16 |
use \WebPConvert\ServeExistingOrHandOver;
|
17 |
|
18 |
+
function exitWithError($msg) {
|
19 |
+
header('X-WebP-Express-Error: ' . $msg, true);
|
20 |
+
echo $msg;
|
21 |
+
exit;
|
22 |
+
}
|
23 |
+
|
24 |
+
if (preg_match('#webp-on-demand.php#', $_SERVER['REQUEST_URI'])) {
|
25 |
+
exitWithError('Direct access is not allowed');
|
26 |
+
exit;
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Get environment variable set with mod_rewrite module
|
31 |
+
* Return false if the environment variable isn't found
|
32 |
+
*/
|
33 |
+
function getEnvPassedInRewriteRule($envName) {
|
34 |
+
// Envirenment variables passed through the REWRITE module have "REWRITE_" as a prefix (in Apache, not Litespeed, if I recall correctly)
|
35 |
+
// Multiple iterations causes multiple REWRITE_ prefixes, and we get many environment variables set.
|
36 |
+
// Multiple iterations causes multiple REWRITE_ prefixes, and we get many environment variables set.
|
37 |
+
// We simply look for an environment variable that ends with what we are looking for.
|
38 |
+
// (so make sure to make it unique)
|
39 |
+
$len = strlen($envName);
|
40 |
+
foreach ($_SERVER as $key => $item) {
|
41 |
+
if (substr($key, -$len) == $envName) {
|
42 |
+
return $item;
|
43 |
+
}
|
44 |
+
}
|
45 |
+
return false;
|
46 |
+
}
|
47 |
+
|
48 |
function loadConfig($configFilename) {
|
49 |
if (!file_exists($configFilename)) {
|
50 |
header('X-WebP-Express-Error: Configuration file not found!', true);
|
60 |
return json_decode($json, true);
|
61 |
}
|
62 |
|
63 |
+
function getSource() {
|
64 |
+
global $options;
|
65 |
+
global $docRoot;
|
66 |
|
67 |
// First check if it is in an environment variable - thats the safest way
|
68 |
+
$source = getEnvPassedInRewriteRule('REQFN');
|
69 |
+
if ($source !== false) {
|
70 |
+
return $source;
|
|
|
71 |
}
|
72 |
|
73 |
+
// Then header
|
74 |
+
if (isset($options['base-htaccess-on-these-capability-tests'])) {
|
75 |
+
$capTests = $options['base-htaccess-on-these-capability-tests'];
|
76 |
+
$passThroughHeaderDefinitelyUnavailable = ($capTests['passThroughHeaderWorking'] === false);
|
77 |
+
$passThrougEnvVarDefinitelyAvailable =($capTests['passThroughEnvWorking'] === true);
|
78 |
+
} else {
|
79 |
+
$passThroughHeaderDefinitelyUnavailable = false;
|
80 |
+
$passThrougEnvVarDefinitelyAvailable = false;
|
81 |
+
}
|
82 |
+
if ((!$passThrougEnvVarDefinitelyAvailable) && (!$passThroughHeaderDefinitelyUnavailable)) {
|
83 |
if (isset($_SERVER['HTTP_REQFN'])) {
|
84 |
return $_SERVER['HTTP_REQFN'];
|
85 |
}
|
86 |
}
|
87 |
|
88 |
+
// Then querystring (full path)
|
89 |
+
if (isset($_GET['xsource'])) {
|
90 |
+
return substr($_GET['xsource'], 1); // No url decoding needed as $_GET is already decoded
|
91 |
+
} elseif (isset($_GET['source'])) {
|
92 |
+
return $_GET['source'];
|
93 |
+
}
|
94 |
+
|
95 |
+
// Then querystring (relative path)
|
96 |
+
$srcRel = '';
|
97 |
+
if (isset($_GET['xsource-rel'])) {
|
98 |
+
$srcRel = substr($_GET['xsource-rel'], 1);
|
99 |
+
} elseif (isset($_GET['source-rel'])) {
|
100 |
+
$srcRel = $_GET['source-rel'];
|
101 |
+
}
|
102 |
+
if ($srcRel != '') {
|
103 |
+
if (isset($_GET['source-rel-filter'])) {
|
104 |
+
if ($_GET['source-rel-filter'] == 'discard-parts-before-wp-content') {
|
105 |
+
$parts = explode('/', $srcRel);
|
106 |
+
$wp_content = isset($_GET['wp-content']) ? $_GET['wp-content'] : 'wp-content';
|
107 |
+
|
108 |
+
if (in_array($wp_content, $parts)) {
|
109 |
+
foreach($parts as $index => $part) {
|
110 |
+
if($part !== $wp_content) {
|
111 |
+
unset($parts[$index]);
|
112 |
+
} else {
|
113 |
+
break;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
$srcRel = implode('/', $parts);
|
117 |
+
}
|
118 |
+
}
|
119 |
}
|
120 |
+
return $docRoot . '/' . $srcRel;
|
121 |
}
|
122 |
|
123 |
// Last resort is to use $_SERVER['REQUEST_URI'], well knowing that it does not give the
|
124 |
// correct result in all setups (ie "folder method 1")
|
125 |
$requestUriNoQS = explode('?', $_SERVER['REQUEST_URI'])[0];
|
126 |
+
//$docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
|
127 |
$source = $docRoot . urldecode($requestUriNoQS);
|
128 |
if (file_exists($source)) {
|
129 |
return $source;
|
130 |
}
|
131 |
|
132 |
+
// No luck whatsoever!
|
133 |
+
exitWithError('webp-on-demand.php was not passed any filename to convert');
|
134 |
+
}
|
135 |
+
|
136 |
+
function getWpContentRel() {
|
137 |
+
// Passed in env variable?
|
138 |
+
$wpContentDirRel = getEnvPassedInRewriteRule('WPCONTENT');
|
139 |
+
if ($wpContentDirRel !== false) {
|
140 |
+
return $wpContentDirRel;
|
141 |
}
|
142 |
+
|
143 |
+
// Passed in QS?
|
144 |
+
if (isset($_GET['wp-content'])) {
|
145 |
+
return $_GET['wp-content'];
|
146 |
}
|
147 |
+
|
148 |
+
// In case above fails, fall back to standard location
|
149 |
+
return 'wp-content';
|
150 |
}
|
151 |
|
152 |
$docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
|
153 |
+
$webExpressContentDirAbs = $docRoot . '/' . getWpContentRel() . '/webp-express';
|
154 |
+
$options = loadConfig($webExpressContentDirAbs . '/config/wod-options.json');
|
|
|
|
|
|
|
|
|
155 |
|
156 |
+
$source = getSource();
|
|
|
|
|
157 |
//$source = getSource(false, false);
|
158 |
|
159 |
//echo $source; exit;
|
@@ -10,11 +10,39 @@ error_reporting(E_ALL);
|
|
10 |
//require 'webp-on-demand-1.inc';
|
11 |
//require '../vendor/autoload.php';
|
12 |
|
13 |
-
//print_r($_GET); exit;
|
14 |
-
|
15 |
use \WebPConvert\WebPConvert;
|
16 |
use \WebPConvert\ServeExistingOrHandOver;
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
function loadConfig($configFilename) {
|
19 |
if (!file_exists($configFilename)) {
|
20 |
header('X-WebP-Express-Error: Configuration file not found!', true);
|
@@ -30,6 +58,7 @@ function loadConfig($configFilename) {
|
|
30 |
return json_decode($json, true);
|
31 |
}
|
32 |
|
|
|
33 |
function getDestinationRealPath($dest) {
|
34 |
//echo $_SERVER["DOCUMENT_ROOT"] . '<br>' . $dest . '<br>';
|
35 |
if (strpos($dest, $_SERVER["DOCUMENT_ROOT"]) === 0) {
|
@@ -37,21 +66,51 @@ function getDestinationRealPath($dest) {
|
|
37 |
} else {
|
38 |
return $dest;
|
39 |
}
|
40 |
-
}
|
|
|
|
|
|
|
|
|
41 |
|
42 |
-
function getDestination($allowInQS, $allowInHeader) {
|
43 |
// First check if it is in an environment variable - thats the safest way
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
}
|
48 |
}
|
49 |
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
|
|
55 |
}
|
56 |
|
57 |
// Last resort is to use $_SERVER['REQUEST_URI'], well knowing that it does not give the
|
@@ -62,20 +121,30 @@ function getDestination($allowInQS, $allowInHeader) {
|
|
62 |
return $dest;
|
63 |
}
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
$docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
|
66 |
-
$
|
67 |
-
$
|
68 |
-
$webExpressContentDirAbs = $docRoot . '/' . $webExpressContentDirRel;
|
69 |
-
$configFilename = $webExpressContentDirAbs . '/config/wod-options.json';
|
70 |
|
71 |
-
$
|
72 |
|
73 |
-
|
74 |
-
$allowInHeader = true; // todo: implement setting
|
75 |
-
$destination = getDestination($allowInQS, $allowInHeader);
|
76 |
-
//$destination = getDestination(false, false);
|
77 |
|
78 |
-
//echo $destination; exit;
|
79 |
|
80 |
// Try to find source in same folder.
|
81 |
// Return false on failure
|
10 |
//require 'webp-on-demand-1.inc';
|
11 |
//require '../vendor/autoload.php';
|
12 |
|
|
|
|
|
13 |
use \WebPConvert\WebPConvert;
|
14 |
use \WebPConvert\ServeExistingOrHandOver;
|
15 |
|
16 |
+
function exitWithError($msg) {
|
17 |
+
header('X-WebP-Express-Error: ' . $msg, true);
|
18 |
+
echo $msg;
|
19 |
+
exit;
|
20 |
+
}
|
21 |
+
|
22 |
+
if (preg_match('#webp-realizer.php#', $_SERVER['REQUEST_URI'])) {
|
23 |
+
exitWithError('Direct access is not allowed');
|
24 |
+
exit;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Get environment variable set with mod_rewrite module
|
29 |
+
* Return false if the environment variable isn't found
|
30 |
+
*/
|
31 |
+
function getEnvPassedInRewriteRule($envName) {
|
32 |
+
// Envirenment variables passed through the REWRITE module have "REWRITE_" as a prefix (in Apache, not Litespeed, if I recall correctly)
|
33 |
+
// Multiple iterations causes multiple REWRITE_ prefixes, and we get many environment variables set.
|
34 |
+
// Multiple iterations causes multiple REWRITE_ prefixes, and we get many environment variables set.
|
35 |
+
// We simply look for an environment variable that ends with what we are looking for.
|
36 |
+
// (so make sure to make it unique)
|
37 |
+
$len = strlen($envName);
|
38 |
+
foreach ($_SERVER as $key => $item) {
|
39 |
+
if (substr($key, -$len) == $envName) {
|
40 |
+
return $item;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
return false;
|
44 |
+
}
|
45 |
+
|
46 |
function loadConfig($configFilename) {
|
47 |
if (!file_exists($configFilename)) {
|
48 |
header('X-WebP-Express-Error: Configuration file not found!', true);
|
58 |
return json_decode($json, true);
|
59 |
}
|
60 |
|
61 |
+
/*
|
62 |
function getDestinationRealPath($dest) {
|
63 |
//echo $_SERVER["DOCUMENT_ROOT"] . '<br>' . $dest . '<br>';
|
64 |
if (strpos($dest, $_SERVER["DOCUMENT_ROOT"]) === 0) {
|
66 |
} else {
|
67 |
return $dest;
|
68 |
}
|
69 |
+
}*/
|
70 |
+
|
71 |
+
function getDestination() {
|
72 |
+
global $options;
|
73 |
+
global $docRoot;
|
74 |
|
|
|
75 |
// First check if it is in an environment variable - thats the safest way
|
76 |
+
$destinationRel = getEnvPassedInRewriteRule('DESTINATIONREL');
|
77 |
+
if ($destinationRel !== false) {
|
78 |
+
return $docRoot . '/' . $destinationRel;
|
|
|
79 |
}
|
80 |
|
81 |
+
// Next, check querystring (full path)
|
82 |
+
if (isset($_GET['xdestination'])) {
|
83 |
+
return substr($_GET['xdestination'], 1); // No url decoding needed as $_GET is already decoded
|
84 |
+
} elseif (isset($_GET['destination'])) {
|
85 |
+
return $_GET['destination'];
|
86 |
+
}
|
87 |
+
|
88 |
+
// Next, check querystring (relative path)
|
89 |
+
$destinationRel = '';
|
90 |
+
if (isset($_GET['xdestination-rel'])) {
|
91 |
+
$destinationRel = substr($_GET['xdestination-rel'], 1);
|
92 |
+
} elseif (isset($_GET['destination-rel'])) {
|
93 |
+
$destinationRel = $_GET['destination-rel'];
|
94 |
+
}
|
95 |
+
if ($destinationRel != '') {
|
96 |
+
if (isset($_GET['source-rel-filter'])) {
|
97 |
+
if ($_GET['source-rel-filter'] == 'discard-parts-before-wp-content') {
|
98 |
+
$parts = explode('/', $destinationRel);
|
99 |
+
$wp_content = isset($_GET['wp-content']) ? $_GET['wp-content'] : 'wp-content';
|
100 |
+
|
101 |
+
if (in_array($wp_content, $parts)) {
|
102 |
+
foreach($parts as $index => $part) {
|
103 |
+
if($part !== $wp_content) {
|
104 |
+
unset($parts[$index]);
|
105 |
+
} else {
|
106 |
+
break;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
$destinationRel = implode('/', $parts);
|
110 |
+
}
|
111 |
+
}
|
112 |
}
|
113 |
+
return $docRoot . '/' . $destinationRel;
|
114 |
}
|
115 |
|
116 |
// Last resort is to use $_SERVER['REQUEST_URI'], well knowing that it does not give the
|
121 |
return $dest;
|
122 |
}
|
123 |
|
124 |
+
function getWpContentRel() {
|
125 |
+
// Passed in env variable?
|
126 |
+
$wpContentDirRel = getEnvPassedInRewriteRule('WPCONTENT');
|
127 |
+
if ($wpContentDirRel !== false) {
|
128 |
+
return $wpContentDirRel;
|
129 |
+
}
|
130 |
+
|
131 |
+
// Passed in QS?
|
132 |
+
if (isset($_GET['wp-content'])) {
|
133 |
+
return $_GET['wp-content'];
|
134 |
+
}
|
135 |
+
|
136 |
+
// In case above fails, fall back to standard location
|
137 |
+
return 'wp-content';
|
138 |
+
}
|
139 |
+
|
140 |
$docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
|
141 |
+
$webExpressContentDirAbs = $docRoot . '/' . getWpContentRel() . '/webp-express';
|
142 |
+
$options = loadConfig($webExpressContentDirAbs . '/config/wod-options.json');
|
|
|
|
|
143 |
|
144 |
+
$destination = getDestination();
|
145 |
|
146 |
+
//echo 'destination: ' . $destination; exit;
|
|
|
|
|
|
|
147 |
|
|
|
148 |
|
149 |
// Try to find source in same folder.
|
150 |
// Return false on failure
|