WebP Express - Version 0.3.1

Version Description

  • The "Only jpeg" setting wasn't respected in 0.3.0. It now works again
Download this release

Release Info

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

Code changes from version 0.2.0.1 to 0.3.1

README.md CHANGED
@@ -52,6 +52,8 @@ Note that the plugin does not change any HTML. In the HTML the image src is stil
52
  - Reload the page
53
  - Find a jpeg or png image in the list. In the "type" column, it should say "webp"
54
 
 
 
55
  You can also append `?debug` after any image url, in order to run a conversion, and see the conversion report. Btw: If you append `?reconvert` after an image url, you will force a reconversion of the image.
56
 
57
 
52
  - Reload the page
53
  - Find a jpeg or png image in the list. In the "type" column, it should say "webp"
54
 
55
+ In order to test that the image is not being reconverted every time, look at the Response headers of the image. There should be a "X-WebP-On-Demand" header. It should say Routed to image converter" the first time, but "Routed to existing converted image" on subsequent requests (WebP-Express is based upon WebP On Demand).
56
+
57
  You can also append `?debug` after any image url, in order to run a conversion, and see the conversion report. Btw: If you append `?reconvert` after an image url, you will force a reconversion of the image.
58
 
59
 
README.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.bitwise-it.dk/contact
4
  Tags: webp, images, performance
5
  Requires at least: 4.7.5
6
  Tested up to: 4.9.7
7
- Stable tag: 0.2.0.1
8
  Requires PHP: 5.5
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -59,6 +59,8 @@ Note that the plugin does not change any HTML. In the HTML the image src is stil
59
  - Reload the page
60
  - Find a jpeg or png image in the list. In the "type" column, it should say "webp"
61
 
 
 
62
  You can also append ?debug after any image url, in order to run a conversion, and see the conversion report.
63
  Btw: If you append ?reconvert after an image url, you will force a reconversion of the image.
64
 
@@ -94,8 +96,12 @@ Putting this question in the "frequently" asked questions section is of course s
94
 
95
  == Changelog ==
96
 
97
- = 0.2 =
98
- * Plugin created. Enjoy!
 
 
 
 
99
 
100
  == Roadmap ==
101
 
4
  Tags: webp, images, performance
5
  Requires at least: 4.7.5
6
  Tested up to: 4.9.7
7
+ Stable tag: 0.3.1
8
  Requires PHP: 5.5
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
59
  - Reload the page
60
  - Find a jpeg or png image in the list. In the "type" column, it should say "webp"
61
 
62
+ In order to test that the image is not being reconverted every time, look at the Response headers of the image. There should be a "X-WebP-On-Demand" header. It should say Routed to image converter" the first time, but "Routed to existing converted image" on subsequent requests (WebP-Express is based upon WebP On Demand).
63
+
64
  You can also append ?debug after any image url, in order to run a conversion, and see the conversion report.
65
  Btw: If you append ?reconvert after an image url, you will force a reconversion of the image.
66
 
96
 
97
  == Changelog ==
98
 
99
+ = 0.3.1 =
100
+ * The "Only jpeg" setting wasn't respected in 0.3.0. It now works again
101
+
102
+ = 0.3 =
103
+ * Now works on LiteSpeed webservers
104
+ * Now sends X-WebP-On-Demand headers for easier debugging
105
 
106
  == Roadmap ==
107
 
assets/banner-772x250.jpg DELETED
Binary file
assets/icon-128x128.png DELETED
Binary file
assets/icon-256x256.png DELETED
Binary file
assets/icon.svg DELETED
@@ -1,27 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
-
4
- <svg
5
- xmlns:dc="http://purl.org/dc/elements/1.1/"
6
- xmlns:cc="http://creativecommons.org/ns#"
7
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
- xmlns:svg="http://www.w3.org/2000/svg"
9
- xmlns="http://www.w3.org/2000/svg"
10
- version="1.1"
11
- width="150"
12
- height="150"
13
- id="svg3062"
14
- xml:space="preserve"><metadata
15
- id="metadata3068"><rdf:RDF><cc:Work
16
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
17
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
18
- id="defs3066" /><g
19
- transform="matrix(1.25,0,0,-1.25,0,150)"
20
- id="g3070"><g
21
- id="g3072"><path
22
- d="M 0,0 120,0 120,120 0,120 0,0 z"
23
- id="path3074"
24
- style="fill:#154889;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
25
- d="m 39.695,22.855 -31.695,0 23.77,74.29 10.648,0 -2.723,-74.29 z m 8.914,0 -2.722,74.29 10.648,0 8.008,-25.036 c 6.035,6.606 13.895,11.528 22.473,14.075 l -9.563,8.027 c -0.875,0.773 -0.535,2.473 0.574,2.844 0.172,0.058 0.352,0.09 0.536,0.09 l 31.761,0 c 1.102,0 1.969,-1.313 1.547,-2.325 L 99.566,65.535 c -0.453,-1.078 -2.171,-1.297 -2.875,-0.363 -0.113,0.144 -0.199,0.305 -0.253,0.476 l -4.727,14.106 c -4.535,-1.649 -8.715,-4.25 -11.859,-7.379 -3.145,-3.129 -5.243,-6.773 -5.95,-10.34 l -0.05,-0.277 C 72.445,54.531 73.543,43.988 76.738,34 l 3.567,-11.145 -31.696,0 z"
26
- id="path3076"
27
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /></g></g></svg>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/screenshot-1.png DELETED
Binary file
lib/activate.php CHANGED
@@ -41,7 +41,7 @@ class WebPExpressActivate {
41
 
42
  // Create upload dir
43
  $urlsAndPaths = WebPExpressHelpers::calculateUrlsAndPaths();
44
- $ourUploadDir = $urlsAndPaths['filePaths']['uploadPath'];
45
 
46
  if ( ! file_exists( $ourUploadDir ) ) {
47
  wp_mkdir_p( $ourUploadDir );
41
 
42
  // Create upload dir
43
  $urlsAndPaths = WebPExpressHelpers::calculateUrlsAndPaths();
44
+ $ourUploadDir = $urlsAndPaths['filePaths']['destinationRoot'];
45
 
46
  if ( ! file_exists( $ourUploadDir ) ) {
47
  wp_mkdir_p( $ourUploadDir );
lib/helpers.php CHANGED
@@ -7,15 +7,15 @@ class WebPExpressHelpers
7
  {
8
  // Calculate URL's
9
  $upload_dir = wp_upload_dir();
10
- $uploadUrlAbs = $upload_dir['baseurl'] . '/' . 'webp-express';
11
 
12
  // Calculate url path to directory of image converter
13
  $pluginUrlAbs = plugins_url('', WEBPEXPRESS_PLUGIN);
14
 
15
  $converterUrlPath = parse_url($pluginUrlAbs)['path'];
16
 
17
- // Calculate upload url path
18
- $uploadUrlPath = parse_url($uploadUrlAbs)['path'];
19
 
20
  // Calculate Wordpress url path
21
  // If site for example is accessed example.com/blog/, then the url path is "blog"
@@ -28,24 +28,44 @@ class WebPExpressHelpers
28
  // Calculate file dirs
29
  // --------------------
30
 
31
- $uploadDir = trailingslashit($upload_dir['basedir']) . 'webp-express';
32
 
33
- $uploadPathRelativeToWebExpressRoot = untrailingslashit(WebPExpressHelpers::get_rel_dir(WEBPEXPRESS_PLUGIN_DIR, $uploadDir));
 
 
 
 
 
 
 
34
 
35
  return [
36
  'urls' => [
37
  'webpExpressRoot' => untrailingslashit($converterUrlPath),
38
  'convert' => untrailingslashit($converterUrlPath) . 'convert.php',
39
- 'destinationRoot' => untrailingslashit($uploadUrlPath),
40
  'wpRoot' => untrailingslashit($wpUrlPath), // ie "/blog" or ""
41
  'converterUrlPathRelativeToSiteUrl' => $converterUrlPathRelativeToSiteUrl,
42
  'siteUrlPathRelativeToConverterPath' => $siteUrlPathRelativeToConverterPath
43
  ],
44
  'filePaths' => [
45
- 'destinationRoot' => untrailingslashit($uploadDir),
46
- 'webpExpressRoot' => untrailingslashit(WEBPEXPRESS_PLUGIN_DIR),
47
- 'uploadPath' => $uploadDir,
48
- 'uploadPathRelativeToWebExpressRoot' => $uploadPathRelativeToWebExpressRoot
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  ]
50
  ];
51
  }
@@ -87,26 +107,104 @@ class WebPExpressHelpers
87
  }
88
  $fileExt = implode('|', $fileExtensions);
89
 
 
 
 
 
90
  if ($imageTypes == 0) {
91
  $rules = '# Configured not to convert anything!';
92
  //$rules .= 'php_value include_path ".:/usr/local/lib/php:/your/dir"';
93
  $rules .= 'php_value include_path ".:/usr/local/lib/php:/hsphere/local/home/z84733/mingo.net/wp-content/plugins/webp-express/vendor/webp-convert/Converters/Binaries"';
94
  } else {
95
  $rules = "<IfModule mod_rewrite.c>\n" .
96
- " RewriteEngine On\n" .
 
 
 
 
 
 
 
97
  " RewriteCond %{HTTP_ACCEPT} image/webp\n" .
98
  " RewriteCond %{QUERY_STRING} (^reconvert.*)|(^debug.*) [OR]\n" .
99
  " RewriteCond %{DOCUMENT_ROOT}" . $urls['destinationRoot'] . "/$1.$2.webp !-f\n" .
100
  " RewriteCond %{QUERY_STRING} (.*)\n" .
101
- " RewriteRule ^(.*)\.(" . $fileExt . ")$ " . $urls['converterUrlPathRelativeToSiteUrl'] . "convert.php?source=" . $urls['siteUrlPathRelativeToConverterPath'] . "$1.$2&destination-root=" . $filePaths['uploadPathRelativeToWebExpressRoot'] . $options . "&%1 [NC,T=image/webp,E=accept:1]\n" .
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  " RewriteCond %{HTTP_ACCEPT} image/webp\n" .
103
  " RewriteCond %{QUERY_STRING} !((^reconvert.*)|(^debug.*))\n" .
104
- " RewriteCond %{DOCUMENT_ROOT}" . $urls['destinationRoot'] . "/$1.$2.webp -f\n" .
105
- " RewriteRule ^(.*)\.(" . $fileExt . ")$ " . $urls['destinationRoot'] . "/$1.$2.webp [NC,T=image/webp,E=accept:1,QSD]\n" .
106
- "</IfModule>\n" .
 
 
 
 
 
 
 
 
107
  "<IfModule mod_headers.c>\n" .
108
- " Header append Vary Accept env=REDIRECT_accept\n" .
109
- "</IfModule>\n" .
 
 
 
 
 
 
 
 
 
 
 
110
  "AddType image/webp .webp\n";
111
  }
112
  return $rules;
@@ -168,8 +266,17 @@ class WebPExpressHelpers
168
  from: /var/www/wordpress/wp-content/plugins/webp-express
169
  to: /var/www/wordpress/wp-content/uploads
170
  result: ../../uploads/
 
 
 
 
 
 
171
  */
172
  public static function get_rel_dir($from_dir, $to_dir) {
 
 
 
173
  $from_dir_parts = explode('/', str_replace( '\\', '/', $from_dir ));
174
  $to_dir_parts = explode('/', str_replace( '\\', '/', $to_dir ));
175
  $i = 0;
@@ -184,6 +291,9 @@ class WebPExpressHelpers
184
  for ($j = $i; $j < count($to_dir_parts); $j++) {
185
  $rel .= $to_dir_parts[$j] . '/';
186
  }
 
 
 
187
  return $rel;
188
  }
189
 
7
  {
8
  // Calculate URL's
9
  $upload_dir = wp_upload_dir();
10
+ $destinationRootUrlPathAbs = $upload_dir['baseurl'] . '/' . 'webp-express';
11
 
12
  // Calculate url path to directory of image converter
13
  $pluginUrlAbs = plugins_url('', WEBPEXPRESS_PLUGIN);
14
 
15
  $converterUrlPath = parse_url($pluginUrlAbs)['path'];
16
 
17
+ // Calculate destination root url path
18
+ $destinationRootUrlPath = parse_url($destinationRootUrlPathAbs)['path'];
19
 
20
  // Calculate Wordpress url path
21
  // If site for example is accessed example.com/blog/, then the url path is "blog"
28
  // Calculate file dirs
29
  // --------------------
30
 
31
+ $destinationRoot = trailingslashit($upload_dir['basedir']) . 'webp-express';
32
 
33
+ $WebExpressRoot = untrailingslashit(WEBPEXPRESS_PLUGIN_DIR);
34
+
35
+ $destinationRootRelativeToWebExpressRoot = untrailingslashit(WebPExpressHelpers::get_rel_dir($WebExpressRoot, $destinationRoot));
36
+
37
+ // $destinationRoot is ie '/webp-express-test/wordpress/wp-content/uploads/webp-express/'
38
+ // $wordpressRoot is ie '/mnt/Work/playground/webp-express-test/wordpress/'
39
+ $wordpressRoot = untrailingslashit(ABSPATH);
40
+ $destinationRootRelativeToWordpressRoot = untrailingslashit(WebPExpressHelpers::get_rel_dir($wordpressRoot . '/', $destinationRoot));
41
 
42
  return [
43
  'urls' => [
44
  'webpExpressRoot' => untrailingslashit($converterUrlPath),
45
  'convert' => untrailingslashit($converterUrlPath) . 'convert.php',
46
+ 'destinationRoot' => untrailingslashit($destinationRootUrlPath),
47
  'wpRoot' => untrailingslashit($wpUrlPath), // ie "/blog" or ""
48
  'converterUrlPathRelativeToSiteUrl' => $converterUrlPathRelativeToSiteUrl,
49
  'siteUrlPathRelativeToConverterPath' => $siteUrlPathRelativeToConverterPath
50
  ],
51
  'filePaths' => [
52
+ 'wordpressRoot' => $wordpressRoot,
53
+ 'destinationRoot' => $destinationRoot,
54
+ 'webpExpressRoot' => $WebExpressRoot,
55
+ 'destinationRootRelativeToWebExpressRoot' => $destinationRootRelativeToWebExpressRoot,
56
+ 'destinationRootRelativeToWordpressRoot' => $destinationRootRelativeToWordpressRoot
57
+ ],
58
+ // TODO: read up on this, and make complete tests
59
+ // https://wordpress.stackexchange.com/questions/188448/whats-the-difference-between-get-home-path-and-abspath
60
+ 'pathsForHtaccess' => [
61
+ //$basePath, $destinationRoot, $scriptPath
62
+ 'basePath' => untrailingslashit(WebPExpressHelpers::get_rel_dir($_SERVER['DOCUMENT_ROOT'], untrailingslashit(ABSPATH))),
63
+ 'destinationRoot' => $destinationRootRelativeToWordpressRoot, // Where to place converted files, relative to the base path.
64
+ 'scriptPath' => untrailingslashit($converterUrlPathRelativeToSiteUrl),
65
+
66
+ //'abspath' => ABSPATH,
67
+ //'dr' => $_SERVER['DOCUMENT_ROOT'],
68
+ //'bp' => str_replace($_SERVER['DOCUMENT_ROOT'] . '/', '', untrailingslashit(ABSPATH)),
69
  ]
70
  ];
71
  }
107
  }
108
  $fileExt = implode('|', $fileExtensions);
109
 
110
+ $paths = $urlsAndPaths['pathsForHtaccess'];
111
+ return self::generateHTAccessRules2($fileExt, $paths['basePath'], $paths['destinationRoot'], $paths['scriptPath'], $options);
112
+ }
113
+ /*
114
  if ($imageTypes == 0) {
115
  $rules = '# Configured not to convert anything!';
116
  //$rules .= 'php_value include_path ".:/usr/local/lib/php:/your/dir"';
117
  $rules .= 'php_value include_path ".:/usr/local/lib/php:/hsphere/local/home/z84733/mingo.net/wp-content/plugins/webp-express/vendor/webp-convert/Converters/Binaries"';
118
  } else {
119
  $rules = "<IfModule mod_rewrite.c>\n" .
120
+
121
+ " RewriteEngine On\n\n" .
122
+ " # Redirect to existing converted image (under appropriate circumstances)\n" .
123
+ " RewriteCond %{HTTP_ACCEPT} image/webp\n" .
124
+ " RewriteCond %{QUERY_STRING} !((^reconvert.*)|(^debug.*))\n" .
125
+ " RewriteCond %{DOCUMENT_ROOT}" . $urls['destinationRoot'] . "/$1.$2.webp -f\n" .
126
+ " RewriteRule ^\\/?(.*)\.(" . $fileExt . ")$ " . $urls['destinationRoot'] . "/$1.$2.webp [NC,T=image/webp,E=webpaccept:1,E=WEBPEXISTING:1,QSD]\n\n" .
127
+ " # Redirect to image converter (under appropriate circumstances)\n" .
128
  " RewriteCond %{HTTP_ACCEPT} image/webp\n" .
129
  " RewriteCond %{QUERY_STRING} (^reconvert.*)|(^debug.*) [OR]\n" .
130
  " RewriteCond %{DOCUMENT_ROOT}" . $urls['destinationRoot'] . "/$1.$2.webp !-f\n" .
131
  " RewriteCond %{QUERY_STRING} (.*)\n" .
132
+ //" RewriteRule ^\\/?(.*)\.(" . $fileExt . ")$ " . $urls['converterUrlPathRelativeToSiteUrl'] . "convert.php?source=" . $urls['siteUrlPathRelativeToConverterPath'] . "$1.$2&destination-root=" . $filePaths['destinationRootRelativeToWebExpressRoot'] . $options . "&%1 [NC,E=accept:1]\n" .
133
+ " RewriteRule ^\\/?(.*)\.(" . $fileExt . ")$ " . $urls['converterUrlPathRelativeToSiteUrl'] . "convert.php?htaccess-path=" . $filePaths['wordpressRoot'] . '&destination-root-rel-to-htaccess-path=' . $filePaths['destinationRootRelativeToWordpressRoot'] . '&source-rel-to-htaccess-path=$1.$2' . $options . "&%1 [NC,E=webpaccept:1,E=WEBPNEW]\n" .
134
+
135
+ "</IfModule>\n" .
136
+
137
+ "<IfModule mod_headers.c>\n" .
138
+ " # Apache appends \"REDIRECT_\" in front of the environment variables, but LiteSpeed does not\n" .
139
+ " # These next three lines are for Apache, in order to set environment variables without \"REDIRECT_\"\n" .
140
+ " SetEnvIf REDIRECT_WEBPACCEPT 1 WEBPACCEPT=1\n" .
141
+ " SetEnvIf REDIRECT_WEBPEXISTING 1 WEBPEXISTING=1\n" .
142
+ " SetEnvIf REDIRECT_WEBPNEW 1 WEBPNEW=1\n\n" .
143
+
144
+ " # Make CDN caching possible." .
145
+ " Header append Vary Accept env=WEBPACCEPT\n\n" .
146
+
147
+ " # Add headers for debugging\n" .
148
+ " Header append X-WebP-Express \"Routed to existing converted image\" env=WEBPEXISTING\n" .
149
+ " Header append X-WebP-Express \"Routed to image converter\" env=WEBPNEW\n" .
150
+ "</IfModule>\n\n" .
151
+ "AddType image/webp .webp\n";
152
+ }
153
+ return $rules;
154
+ }
155
+ */
156
+ /**
157
+ Create rewrite rules for WebP On Demand.
158
+
159
+ @param $fileExt To convert both jpegs and pngs, use "jpe?g|png". To disable converting, use ""
160
+ @param $basePath Path of the .htaccess relative to document root. Ie "." or "my-sub-site"
161
+ @param $destinationRoot Where to place converted files, relative to the base path.
162
+ @param $scriptPath Url path to webp-on-demand.php, relative to the base directory.
163
+ @param $options String of options. If not empty, it must start with "&". Ie "&converters=cwebp,gd&quality=auto"
164
+
165
+ Note: None of the paths supplied may start or end with a forward slash.
166
+ */
167
+ private static function generateHTAccessRules2($fileExt, $basePath, $destinationRoot, $scriptPath, $options)
168
+ {
169
+ if ($basePath == '') {
170
+ //$basePath = '.';
171
+ }
172
+ $rules = '';
173
+ if ($fileExt == '') {
174
+ $rules .= '# Configured not to convert anything!';
175
+ } else {
176
+ $rules .= "<IfModule mod_rewrite.c>\n" .
177
+
178
+ " RewriteEngine On\n\n" .
179
+
180
+ " # Redirect to existing converted image (under appropriate circumstances)\n" .
181
  " RewriteCond %{HTTP_ACCEPT} image/webp\n" .
182
  " RewriteCond %{QUERY_STRING} !((^reconvert.*)|(^debug.*))\n" .
183
+ " RewriteCond %{DOCUMENT_ROOT}/" . $basePath . "/" . $destinationRoot . "/$1.$2.webp -f\n" .
184
+ " RewriteRule ^\/?(.*)\.(jpe?g|png)$ /" . $basePath . "/" . $destinationRoot . "/$1.$2.webp [NC,T=image/webp,E=WEBPACCEPT:1,E=WEBPEXISTING:1,QSD]\n\n" .
185
+
186
+ " # Redirect to converter (under appropriate circumstances)\n" .
187
+ " RewriteCond %{HTTP_ACCEPT} image/webp\n" .
188
+ " RewriteCond %{QUERY_STRING} (^reconvert.*)|(^debug.*) [OR]\n" .
189
+ " RewriteCond %{DOCUMENT_ROOT}/" . $basePath . "/" . $destinationRoot . "/$1.$2.webp !-f\n" .
190
+ " RewriteCond %{QUERY_STRING} (.*)\n" .
191
+ " RewriteRule ^\/?(.*)\.(" . $fileExt . ")$ " . $scriptPath . "/webp-on-demand.php?base-path=" . $basePath . "&destination-root=" . $destinationRoot . "&source=$1.$2" . $options . "&%1 [NC,E=WEBPACCEPT:1,E=WEBPNEW:1]\n" .
192
+ "</IfModule>\n\n" .
193
+
194
  "<IfModule mod_headers.c>\n" .
195
+ " # Apache appends \"REDIRECT_\" in front of the environment variables, but LiteSpeed does not\n" .
196
+ " # These next three lines are for Apache, in order to set environment variables without \"REDIRECT_\"\n" .
197
+ " SetEnvIf REDIRECT_WEBPACCEPT 1 WEBPACCEPT=1\n" .
198
+ " SetEnvIf REDIRECT_WEBPEXISTING 1 WEBPEXISTING=1\n" .
199
+ " SetEnvIf REDIRECT_WEBPNEW 1 WEBPNEW=1\n\n" .
200
+
201
+ " # Make CDN caching possible.\n" .
202
+ " Header append Vary Accept env=WEBPACCEPT\n\n" .
203
+
204
+ " # Add headers for debugging\n" .
205
+ " Header append X-WebP-On-Demand \"Routed to existing converted image\" env=WEBPEXISTING\n" .
206
+ " Header append X-WebP-On-Demand \"Routed to image converter\" env=WEBPNEW\n" .
207
+ "</IfModule>\n\n" .
208
  "AddType image/webp .webp\n";
209
  }
210
  return $rules;
266
  from: /var/www/wordpress/wp-content/plugins/webp-express
267
  to: /var/www/wordpress/wp-content/uploads
268
  result: ../../uploads/
269
+
270
+ or
271
+ from: /mnt/Work/playground/webp-express-test/wordpress/
272
+ to: /mnt/Work/playground/webp-express-test/wordpress/wp-content/uploads/webp-express
273
+ result: wp-content/uploads/webp-express
274
+
275
  */
276
  public static function get_rel_dir($from_dir, $to_dir) {
277
+ $from_dir = untrailingslashit($from_dir);
278
+ $to_dir = untrailingslashit($to_dir);
279
+
280
  $from_dir_parts = explode('/', str_replace( '\\', '/', $from_dir ));
281
  $to_dir_parts = explode('/', str_replace( '\\', '/', $to_dir ));
282
  $i = 0;
291
  for ($j = $i; $j < count($to_dir_parts); $j++) {
292
  $rel .= $to_dir_parts[$j] . '/';
293
  }
294
+ if ($rel == '') {
295
+ $rel = '.';
296
+ }
297
  return $rel;
298
  }
299
 
vendor/webp-on-demand/PathHelper.php DELETED
@@ -1,170 +0,0 @@
1
- <?php
2
-
3
- namespace WebPOnDemand;
4
-
5
- class PathHelper
6
- {
7
-
8
- // Canonicalize a path by resolving '../' and './'
9
- // Got it from a comment here: http://php.net/manual/en/function.realpath.php
10
- // But fixed it (it could not handle './../')
11
- public static function canonicalize($path)
12
- {
13
- $parts = explode('/', $path);
14
-
15
- // Remove parts containing just '.' (and the empty holes afterwards)
16
- $parts = array_values(array_filter($parts, function ($var) {
17
- return ($var != '.');
18
- }));
19
-
20
- // Remove parts containing '..' and the preceding
21
- $keys = array_keys($parts, '..');
22
- foreach ($keys as $keypos => $key) {
23
- array_splice($parts, $key - ($keypos * 2 + 1), 2);
24
- }
25
- return implode('/', $parts);
26
- }
27
-
28
- // We do not operate with backslashes here. Windows is a big boy now,
29
- // it can handle forward slashes
30
- public static function replaceBackslashes($str)
31
- {
32
- return str_replace('\\', '/', $str);
33
- }
34
-
35
- public static function removeDoubleSlash($str)
36
- {
37
- return preg_replace('/\/\//', '/', $str);
38
- }
39
-
40
- /* Get relative path between one dir and the other.
41
- ie
42
- from: /var/www/wordpress/wp-content/plugins/webp-express
43
- to: /var/www/wordpress/wp-content/uploads
44
- result: ../../uploads/
45
- */
46
- public static function getRelDir($from_dir, $to_dir)
47
- {
48
- $fromDirParts = explode('/', str_replace('\\', '/', $from_dir));
49
- $toDirParts = explode('/', str_replace('\\', '/', $to_dir));
50
- $i = 0;
51
- while (($i < count($fromDirParts)) && ($i < count($toDirParts)) && ($fromDirParts[$i] == $toDirParts[$i])) {
52
- $i++;
53
- }
54
- $rel = "";
55
- for ($j = $i; $j < count($fromDirParts); $j++) {
56
- $rel .= "../";
57
- }
58
-
59
- for ($j = $i; $j < count($toDirParts); $j++) {
60
- $rel .= $toDirParts[$j];
61
- if ($j < count($toDirParts)-1) {
62
- $rel .= '/';
63
- }
64
- }
65
- return $rel;
66
- }
67
-
68
- // Strip filename from path
69
- // Similar to dirname, but does not localize
70
- public static function getFolder($path_with_filename) {
71
- $parts = explode('/', $path_with_filename);
72
- array_pop($parts);
73
- return implode('/', $parts);
74
- }
75
-
76
-
77
- /**
78
- * Calculates absolute path from relative path, but handles absolute path too
79
- * Relative path is per default taken to be relative to DOCUMENT_ROOT.
80
- * This can however be altered by providing another root
81
- *
82
- * If path starts with "/", it is considered an absolute path, and it is just
83
- * passed through
84
- *
85
- * @param path Relative or absolute path (relative to document root).
86
- */
87
- public static function abspath($relativeOrAbsolutePath, $root = null)
88
- {
89
- if (!isset($root)) {
90
- $root = $_SERVER['DOCUMENT_ROOT'];
91
- }
92
- $relativeOrAbsolutePath = self::replaceBackslashes($relativeOrAbsolutePath);
93
- if ((substr($relativeOrAbsolutePath, 0, 1) == '/')) {
94
- return $relativeOrAbsolutePath;
95
- } else {
96
- return self::canonicalize(self::removeDoubleSlash($root . '/' . $relativeOrAbsolutePath));
97
- }
98
- }
99
-
100
- /**
101
- * Calculates relative path from absolute path, but handles absolute path too
102
- * Relative path is per default taken to be relative to DOCUMENT_ROOT.
103
- * This can however be altered by providing another root
104
- *
105
- * If path starts with "/", it is considered an absolute path, and it is just
106
- * passed through
107
- *
108
- * @param path Relative or absolute path (relative to document root).
109
- */
110
- public static function relpath($absPath, $root = null)
111
- {
112
- $absPath = self::abspath($absPath);
113
- // self::logmsg('Source path: "' . $absPath . '"');
114
- if (!isset($root)) {
115
- $root = $_SERVER['DOCUMENT_ROOT'];
116
- }
117
- $source_rel = self::getRelDir($root, $absPath);
118
-
119
- if (preg_match('/\.\.\//', $source_rel)) {
120
- // self::logmsg('<b>Note</b>: path is outside document root. You are allowed to, but its unusual setup. When used to calculate destination folder, the "../"s will be removed');
121
- }
122
- return $source_rel;
123
- }
124
-
125
- /**
126
- * Calculates absolute destination path
127
- * Calculated like this : [desired destination root] + [relative path of source file] + ".webp"
128
- *
129
- * If you want converted files to be put in the same folder as the originals, just leave out
130
- * the destination_root parameter.
131
- *
132
- * If you want all converted files to reside in their own folder, set the destination_root
133
- * parameter to point to that folder. The converted files will be stored in a hierarchy that
134
- * matches the source files. With destination_root set to "webp-cache", the source file
135
- * "images/2017/cool.jpg" will be stored at "webp-cache/images/2017/cool.jpg.webp"
136
- * You can provide absolute path or relative path for destination_root.
137
- * If the path starts with "/", it is considered an absolute path (also true for source argument)
138
- * Examples of valid paths "webp-cache", "/var/www/webp-cache", "..", "../images", "."
139
- *
140
- * @param source path to source file.
141
- * May be absolute or relative (relative to document root or provided $root).
142
- * @param destination_root path to destination root
143
- *
144
- * @return destination_path absolute path for destination file
145
- */
146
- public static function getDestinationPath($source, $destination_root = '', $root = null)
147
- {
148
-
149
- if (!isset($root)) {
150
- $root = $_SERVER['DOCUMENT_ROOT'];
151
- }
152
-
153
- // Step 1: Get relative path of source
154
- $source_rel = self::relpath($source, $root);
155
-
156
- // Step 2: Get absolute destination root
157
- if ((substr($destination_root, 0, 1) == '/')) {
158
- // Its already an absolute path. Do nothing
159
- } else {
160
- $destination_root = self::replaceBackslashes($destination_root);
161
- if ($destination_root == '') {
162
- $destination_root = '.';
163
- }
164
- $destination_root = self::canonicalize(self::removeDoubleSlash($root . '/' . $destination_root));
165
- }
166
-
167
- // Step 3: Put the two together, and append ".wepb"
168
- return self::canonicalize(self::removeDoubleSlash($destination_root . '/' . preg_replace('/\.\.\//', '', $source_rel) . '.webp'));
169
- }
170
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/webp-on-demand/WebPOnDemand.php CHANGED
@@ -2,23 +2,33 @@
2
  /*
3
  URL parameters:
4
 
5
- source: Path to source file.
6
- Can be absolute or relative to $root, that is passed in
7
- If it starts with "/", it is considered an absolute path.
8
-
9
- destination-root (optional):
10
- The final destination will be calculated like this:
11
- [destination-root] + [relative path of source file] + ".webp".
 
12
 
13
- - Both absolute paths and relative paths are accepted (if the path starts with "/", it is considered an absolute
14
- path).
15
- - Double-dots in paths are allowed, ie "../webp-cache"
 
 
16
 
 
 
17
  If you want converted files to be put in the same folder as the originals, you can set destination-root to ".", or
18
  leave it blank. If you on the other hand want all converted files to reside in their own folder, set the
19
  destination-root to point to that folder. The converted files will be stored in a hierarchy that matches the source
20
  files. With destination-root set to "webp-cache", the source file "images/2017/cool.jpg" will be stored at
21
  "webp-cache/images/2017/cool.jpg.webp".
 
 
 
 
 
22
 
23
  quality (optional):
24
  The quality of the generated WebP image, "auto" or 0-100. Defaults to "auto"
@@ -99,11 +109,12 @@ namespace WebPOnDemand;
99
 
100
  use WebPConvertAndServe\WebPConvertAndServe;
101
  use WebPConvert\WebPConvert;
102
- use WebPOnDemand\PathHelper;
103
  use WebPConvert\Converters\ConverterHelper;
104
 
105
  class WebPOnDemand
106
  {
 
 
107
  private static function transformFallbackOptions($converters) {
108
  foreach ($converters as $i => &$converter) {
109
  $duplicateConverter = false;
@@ -143,22 +154,78 @@ class WebPOnDemand
143
  break;
144
  }
145
  }
146
- public static function serve($root)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  {
148
 
149
  $debug = (isset($_GET['debug']) ? ($_GET['debug'] != 'no') : false);
150
 
151
  //$source = $root . '/' . $_GET['source'];
152
- $source = PathHelper::abspath($_GET['source'], $root);
153
 
154
- $source = PathHelper::removeDoubleSlash($source);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
 
 
 
 
 
156
 
157
- if (isset($_GET['destination-root'])) {
158
- $destination = PathHelper::getDestinationPath($source, $_GET['destination-root'], $root);
 
 
 
 
 
 
 
159
  } else {
160
- $destination = $source . '.webp';
161
  }
 
 
 
 
162
 
163
  $options = [];
164
 
@@ -263,34 +330,16 @@ class WebPOnDemand
263
 
264
  // TODO
265
  // As we do not want to leak api keys, I have commented out the following.
266
- /*
267
  echo 'GET parameters:<br>';
268
  foreach ($_GET as $key => $value) {
269
  echo '<i>' . $key . '</i>: ' . htmlspecialchars($value) . '<br>';
270
  }
271
- echo '<br>';
272
- */
273
  //echo $_SERVER['DOCUMENT_ROOT'];
274
  WebPConvertAndServe::convertAndReport($source, $destination, $options);
275
  return 1;
276
  }
277
  }
278
- /*
279
- $root = (
280
- isset($_GET['root-folder']) ?
281
- PathHelper::removeDoubleSlash($_SERVER['DOCUMENT_ROOT'] . '/' . $_GET['root-folder']) :
282
- null
283
- );*/
284
- /*
285
- destination (optional): (TODO)
286
- Path to destination file. Can be absolute or relative (relative to document root).
287
- You can choose not to specify destination. In that case, the path will be created based upon source,
288
- destination-root and root-folder settings. If all these are blank, the destination will be same folder as source,
289
- and the filename will have ".webp" appended to it (ie image.jpeg.webp)
290
-
291
- root-folder (optional):
292
- Usually, you will not need to supply anything. Might be relevant in rare occasions where the converter that
293
- generates the URL cannot pass all of the relative path. For example, an .htaccess located in a subfolder may have
294
- trouble passing the parent folders.*/
295
- //$source = PathHelper::abspath($_GET['source'], $root);*/
296
  }
2
  /*
3
  URL parameters:
4
 
5
+ base-path:
6
+ Sets the base path used for "source" and "destination-root" options.
7
+ Must be relative to document root, or absolute (not recommended)
8
+ When used in .htaccess, set it to the folder containing the .htaccess file, relative to document root.
9
+ If for example document root is /var/www/example.com/ and you have a subdirectory "wordpress", which you
10
+ want WebPOnDemand to work on, you should place .htaccess rules in the "wordpress" directory, and
11
+ your "base-path" will be "wordpress"
12
+ If not set, it defaults to be the path of webp-on-demand.php
13
 
14
+ source: Path to source file.
15
+ Path to source file, relative to 'base-path' option.
16
+ The final path is calculated like this:
17
+ [base-path] + [path to source file] + ".webp".
18
+ absolute path is depreciated, but supported for backwards compatability.
19
 
20
+ destination-root:
21
+ The path of where you want the converted files to reside, relative to the 'base-path' option.
22
  If you want converted files to be put in the same folder as the originals, you can set destination-root to ".", or
23
  leave it blank. If you on the other hand want all converted files to reside in their own folder, set the
24
  destination-root to point to that folder. The converted files will be stored in a hierarchy that matches the source
25
  files. With destination-root set to "webp-cache", the source file "images/2017/cool.jpg" will be stored at
26
  "webp-cache/images/2017/cool.jpg.webp".
27
+ Double-dots in paths are allowed, ie "../webp-cache"
28
+ The final destination is calculated like this:
29
+ [base-path] + [destination-root] + [path to source file] + ".webp".
30
+ Default is "."
31
+ You can also supply an absolute path
32
 
33
  quality (optional):
34
  The quality of the generated WebP image, "auto" or 0-100. Defaults to "auto"
109
 
110
  use WebPConvertAndServe\WebPConvertAndServe;
111
  use WebPConvert\WebPConvert;
 
112
  use WebPConvert\Converters\ConverterHelper;
113
 
114
  class WebPOnDemand
115
  {
116
+ // transform options with '-2' postfix into new converters
117
+ // Idea: rename function to ie "transformFallbackOptionsIntoNewConverters"
118
  private static function transformFallbackOptions($converters) {
119
  foreach ($converters as $i => &$converter) {
120
  $duplicateConverter = false;
154
  break;
155
  }
156
  }
157
+ private static function removeDoubleSlash($str)
158
+ {
159
+ return preg_replace('/\/\//', '/', $str);
160
+ }
161
+ private static function getRelDir($from_dir, $to_dir)
162
+ {
163
+ $fromDirParts = explode('/', str_replace('\\', '/', $from_dir));
164
+ $toDirParts = explode('/', str_replace('\\', '/', $to_dir));
165
+ $i = 0;
166
+ while (($i < count($fromDirParts)) && ($i < count($toDirParts)) && ($fromDirParts[$i] == $toDirParts[$i])) {
167
+ $i++;
168
+ }
169
+ $rel = "";
170
+ for ($j = $i; $j < count($fromDirParts); $j++) {
171
+ $rel .= "../";
172
+ }
173
+
174
+ for ($j = $i; $j < count($toDirParts); $j++) {
175
+ $rel .= $toDirParts[$j];
176
+ if ($j < count($toDirParts)-1) {
177
+ $rel .= '/';
178
+ }
179
+ }
180
+ return $rel;
181
+ }
182
+
183
+ public static function serve($scriptPath)
184
  {
185
 
186
  $debug = (isset($_GET['debug']) ? ($_GET['debug'] != 'no') : false);
187
 
188
  //$source = $root . '/' . $_GET['source'];
 
189
 
190
+ if (!isset($_GET['base-path'])) {
191
+ $basePath = $scriptPath;
192
+ } else {
193
+ $basePath = $_GET['base-path'];
194
+ if ((substr($basePath, 0, 1) == '/')) {
195
+ } else {
196
+ $basePath = $_SERVER["DOCUMENT_ROOT"] . '/' . $basePath;
197
+ }
198
+ }
199
+
200
+ // Calculate $source and $sourceRelToBasePath (needed for calculating $destination)
201
+ $sourcePath = $_GET['source']; // this path includes filename
202
+ if ((substr($sourcePath, 0, 1) == '/')) {
203
+ $sourcePathAbs = $sourcePath;
204
+ $sourceRelToBasePath = self::getRelDir($basePath, $sourcePathAbs);
205
+ //echo $basePath . '<br>' . $sourcePathAbs . '<br>' . $sourceRelToBasePath . '<br><br>';
206
 
207
+ } else {
208
+ $sourceRelToBasePath = $sourcePath;
209
+ $sourcePathAbs = $basePath . '/' . $sourcePath;
210
+ }
211
+ $source = self::removeDoubleSlash($sourcePathAbs);
212
 
213
+ // Calculate $destination from destination-root and $basePath
214
+ if (!isset($_GET['destination-root'])) {
215
+ $destinationRoot = '.';
216
+ } else {
217
+ $destinationRoot = $_GET['destination-root'];
218
+ }
219
+ if ((substr($destinationRoot, 0, 1) == '/')) {
220
+ // absolute path - overrides basepath
221
+ $destinationRootAbs = $destinationRoot;
222
  } else {
223
+ $destinationRootAbs = $basePath . '/' . $destinationRoot;
224
  }
225
+ $destination = self::removeDoubleSlash($destinationRootAbs . '/' . $sourceRelToBasePath . '.webp');
226
+
227
+
228
+
229
 
230
  $options = [];
231
 
330
 
331
  // TODO
332
  // As we do not want to leak api keys, I have commented out the following.
333
+ /*
334
  echo 'GET parameters:<br>';
335
  foreach ($_GET as $key => $value) {
336
  echo '<i>' . $key . '</i>: ' . htmlspecialchars($value) . '<br>';
337
  }
338
+ echo '<br>';*/
339
+
340
  //echo $_SERVER['DOCUMENT_ROOT'];
341
  WebPConvertAndServe::convertAndReport($source, $destination, $options);
342
  return 1;
343
  }
344
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
  }
webp-express.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WebP Express
4
  * Plugin URI: https://github.com/rosell-dk/webp-express
5
  * Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
6
- * Version: 0.1
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2
3
  * Plugin Name: WebP Express
4
  * Plugin URI: https://github.com/rosell-dk/webp-express
5
  * Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
6
+ * Version: 0.3.0
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2
webp-on-demand.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ //require 'webp-on-demand/vendor/autoload.php';
4
+
5
+ require 'vendor/webp-on-demand/autoload.php';
6
+ //require 'vendor/webp-convert-and-serve/autoload.php';
7
+ //require 'vendor/webp-on-demand/autoload.php';
8
+
9
+ //echo '<br>done';
10
+
11
+ //require '../webp-convert/WebPConvert.php';
12
+
13
+
14
+ /*use WebPConvert\WebPConvert;
15
+
16
+ $source = __DIR__ . '/test/test.jpg';
17
+ $destination = __DIR__ . '/test/test.jpg.webp';
18
+
19
+ // .. fire up WebP conversion
20
+ $success = WebPConvert::convert($source, $destination, array(
21
+ 'quality' => 90,
22
+ // more options available!
23
+ ));
24
+
25
+
26
+ //$status = WebPOnDemand::serve(__DIR__);
27
+
28
+ //echo 'hi';
29
+ */
30
+
31
+
32
+ use WebPOnDemand\WebPOnDemand;
33
+
34
+ $status = WebPOnDemand::serve(__DIR__);
35
+ if ($status < 0) {
36
+ // Conversion failed.
37
+ // you could message your application about the problem here...
38
+ }