WebP Express - Version 0.14.8

Version Description

(released: 21 jun 2019)

  • Tidied up code
Download this release

Release Info

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

Code changes from version 0.14.7 to 0.14.8

Files changed (38) hide show
  1. README.txt +9 -1
  2. composer.json +1 -1
  3. composer.lock +6 -6
  4. htaccess-capability-tests/pass-through-environment-var/test.php +0 -1
  5. htaccess-capability-tests/request-uri-usable-in-this-dir/.htaccess +0 -11
  6. htaccess-capability-tests/request-uri-usable-in-this-dir/test.php +0 -3
  7. htaccess-capability-tests/request-uri-usable-in-this-dir/test2.php +0 -51
  8. lib/classes/Convert.php +3 -1
  9. lib/classes/ConvertHelperIndependent.php +2 -2
  10. lib/classes/ConvertLog.php +7 -0
  11. lib/debug.php +5 -0
  12. lib/options/enqueue_scripts.php +17 -6
  13. lib/options/js/0.14.5/bulk-convert.js +23 -16
  14. lib/options/js/0.14.5/converters.js +1 -10
  15. lib/options/js/0.14.5/escapeHTML.js +16 -0
  16. lib/options/js/0.14.5/test-convert.js +9 -5
  17. lib/options/js/0.14.5/whitelist.js +1 -8
  18. lib/options/options/alter-html/alter-html-options.inc +5 -5
  19. lib/options/options/conversion-options/jpeg.inc +4 -4
  20. lib/options/options/conversion-options/metadata.inc +4 -1
  21. lib/options/options/conversion-options/png.inc +3 -3
  22. lib/options/options/conversion-options/quality.inc +3 -3
  23. lib/options/options/general/cache-control.inc +1 -1
  24. lib/options/options/operation-mode.inc +1 -1
  25. lib/options/options/redirection-rules/do-not-pass-source-path-in-query-string.inc +6 -1
  26. lib/options/options/redirection-rules/only-redirect-to-converter-for-webp-enabled-browsers.inc +3 -1
  27. lib/options/options/redirection-rules/only-redirect-to-converter-on-cache-miss.inc +3 -1
  28. lib/options/options/redirection-rules/redirect-to-existing.inc +3 -1
  29. lib/options/options/redirection-rules/redirection-rules.inc +3 -1
  30. lib/options/options/serve-options/response-on-success.inc +6 -1
  31. lib/options/options/web-service-options/web-service.inc +13 -4
  32. lib/options/page-messages.php +11 -94
  33. lib/options/page.php +6 -22
  34. lib/options/submit.php +239 -76
  35. vendor/composer/installed.json +6 -6
  36. vendor/rosell-dk/webp-convert/src/Convert/Converters/AbstractConverter.php +1 -1
  37. vendor/rosell-dk/webp-convert/src/Convert/Converters/Cwebp.php +8 -0
  38. webp-express.php +1 -1
README.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://ko-fi.com/rosell
4
  Tags: webp, images, performance
5
  Requires at least: 4.0
6
  Tested up to: 5.2
7
- Stable tag: 0.14.7
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -605,6 +605,11 @@ Easy enough! - [Go here!](https://ko-fi.com/rosell). Or [here](https://buymeacof
605
 
606
  == Changelog ==
607
 
 
 
 
 
 
608
  = 0.14.7 =
609
  *(released: 20 jun 2019)*
610
 
@@ -834,6 +839,9 @@ For older releases, check out changelog.txt
834
 
835
  == Upgrade Notice ==
836
 
 
 
 
837
  = 0.14.7 =
838
  Removed unneccesary files from webp-convert library
839
 
4
  Tags: webp, images, performance
5
  Requires at least: 4.0
6
  Tested up to: 5.2
7
+ Stable tag: 0.14.8
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
605
 
606
  == Changelog ==
607
 
608
+ = 0.14.8 =
609
+ *(released: 21 jun 2019)*
610
+
611
+ * Tidied up code
612
+
613
  = 0.14.7 =
614
  *(released: 20 jun 2019)*
615
 
839
 
840
  == Upgrade Notice ==
841
 
842
+ = 0.14.8 =
843
+ Tidied up code
844
+
845
  = 0.14.7 =
846
  Removed unneccesary files from webp-convert library
847
 
composer.json CHANGED
@@ -4,7 +4,7 @@
4
  "type": "project",
5
  "license": "MIT",
6
  "require": {
7
- "rosell-dk/webp-convert": "^2.1.0",
8
  "rosell-dk/webp-convert-cloud-service": "^2.0.0",
9
  "rosell-dk/dom-util-for-webp": "^0.3.0"
10
  },
4
  "type": "project",
5
  "license": "MIT",
6
  "require": {
7
+ "rosell-dk/webp-convert": "^2.1.1",
8
  "rosell-dk/webp-convert-cloud-service": "^2.0.0",
9
  "rosell-dk/dom-util-for-webp": "^0.3.0"
10
  },
composer.lock CHANGED
@@ -4,7 +4,7 @@
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
- "content-hash": "e9798456dd33cb07d197bf1d9af46f7e",
8
  "packages": [
9
  {
10
  "name": "rosell-dk/dom-util-for-webp",
@@ -118,16 +118,16 @@
118
  },
119
  {
120
  "name": "rosell-dk/webp-convert",
121
- "version": "2.1.0",
122
  "source": {
123
  "type": "git",
124
  "url": "https://github.com/rosell-dk/webp-convert.git",
125
- "reference": "b142cfc2b2b8a1930b3b394c40f0923871ef2abd"
126
  },
127
  "dist": {
128
  "type": "zip",
129
- "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/b142cfc2b2b8a1930b3b394c40f0923871ef2abd",
130
- "reference": "b142cfc2b2b8a1930b3b394c40f0923871ef2abd",
131
  "shasum": ""
132
  },
133
  "require": {
@@ -190,7 +190,7 @@
190
  "png",
191
  "png2webp"
192
  ],
193
- "time": "2019-06-20T12:12:13+00:00"
194
  },
195
  {
196
  "name": "rosell-dk/webp-convert-cloud-service",
4
  "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5
  "This file is @generated automatically"
6
  ],
7
+ "content-hash": "d012f5aa2f2575b563cddf193216562a",
8
  "packages": [
9
  {
10
  "name": "rosell-dk/dom-util-for-webp",
118
  },
119
  {
120
  "name": "rosell-dk/webp-convert",
121
+ "version": "2.1.1",
122
  "source": {
123
  "type": "git",
124
  "url": "https://github.com/rosell-dk/webp-convert.git",
125
+ "reference": "cc0ceb81193a0b930b2e7c58886a7f3662fb45c6"
126
  },
127
  "dist": {
128
  "type": "zip",
129
+ "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/cc0ceb81193a0b930b2e7c58886a7f3662fb45c6",
130
+ "reference": "cc0ceb81193a0b930b2e7c58886a7f3662fb45c6",
131
  "shasum": ""
132
  },
133
  "require": {
190
  "png",
191
  "png2webp"
192
  ],
193
+ "time": "2019-06-21T11:15:37+00:00"
194
  },
195
  {
196
  "name": "rosell-dk/webp-convert-cloud-service",
htaccess-capability-tests/pass-through-environment-var/test.php CHANGED
@@ -18,7 +18,6 @@ function getEnvPassedInRewriteRule($envName) {
18
  return false;
19
  }
20
 
21
-
22
  $result = getEnvPassedInRewriteRule('PASSTHROUGHENV');
23
  if ($result === false) {
24
  echo '0';
18
  return false;
19
  }
20
 
 
21
  $result = getEnvPassedInRewriteRule('PASSTHROUGHENV');
22
  if ($result === false) {
23
  echo '0';
htaccess-capability-tests/request-uri-usable-in-this-dir/.htaccess DELETED
@@ -1,11 +0,0 @@
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>
 
 
 
 
 
 
 
 
 
 
 
htaccess-capability-tests/request-uri-usable-in-this-dir/test.php DELETED
@@ -1,3 +0,0 @@
1
- <?php
2
-
3
- echo '0';
 
 
 
htaccess-capability-tests/request-uri-usable-in-this-dir/test2.php DELETED
@@ -1,51 +0,0 @@
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
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/classes/Convert.php CHANGED
@@ -29,6 +29,7 @@ class Convert
29
 
30
  public static function convertFile($source, $config = null, $convertOptions = null, $converter = null)
31
  {
 
32
  $source = ConvertHelperIndependent::sanitizeAbsFilePath($source);
33
 
34
  if (is_null($config)) {
@@ -78,6 +79,8 @@ class Convert
78
  wp_die();
79
  }
80
 
 
 
81
  $filename = $_POST['filename'];
82
 
83
  if (isset($_POST['config-overrides'])) {
@@ -116,7 +119,6 @@ class Convert
116
  $result = self::convertFile($filename);
117
  }
118
 
119
-
120
  echo json_encode($result, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
121
  wp_die();
122
  }
29
 
30
  public static function convertFile($source, $config = null, $convertOptions = null, $converter = null)
31
  {
32
+ // PS: No need to check mime type as the WebPConvert library does that (it only accepts image/jpeg and image/png)
33
  $source = ConvertHelperIndependent::sanitizeAbsFilePath($source);
34
 
35
  if (is_null($config)) {
79
  wp_die();
80
  }
81
 
82
+ // No need to sanitize filename. self::convertFile does that for us. And the WebPConvert library also does.
83
+ // Also, no need to check mime type as the WebPConvert library also does that (it only allows image/jpeg and image/png)
84
  $filename = $_POST['filename'];
85
 
86
  if (isset($_POST['config-overrides'])) {
119
  $result = self::convertFile($filename);
120
  }
121
 
 
122
  echo json_encode($result, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
123
  wp_die();
124
  }
lib/classes/ConvertHelperIndependent.php CHANGED
@@ -270,7 +270,7 @@ APACHE
270
 
271
  $text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
272
 
273
- $text = 'WebP Express 0.14.7. ' . $msgTop . ', ' . date("Y-m-d H:i:s") . "\n\r\n\r" . $text;
274
 
275
  $logFile = self::getLogFilename($source, $logDir);
276
 
@@ -319,7 +319,7 @@ APACHE
319
  return [
320
  'success' => $success,
321
  'msg' => $msg,
322
- 'log' => $logger->getHtml(),
323
  ];
324
 
325
  }
270
 
271
  $text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
272
 
273
+ $text = 'WebP Express 0.14.8. ' . $msgTop . ', ' . date("Y-m-d H:i:s") . "\n\r\n\r" . $text;
274
 
275
  $logFile = self::getLogFilename($source, $logDir);
276
 
319
  return [
320
  'success' => $success,
321
  'msg' => $msg,
322
+ 'log' => $logger->getMarkDown("\n"),
323
  ];
324
 
325
  }
lib/classes/ConvertLog.php CHANGED
@@ -15,6 +15,12 @@ class ConvertLog
15
  }
16
  $source = $_POST['source'];
17
 
 
 
 
 
 
 
18
  $logFile = ConvertHelperIndependent::getLogFilename($source, Paths::getLogDirAbs());
19
  $msg = 'Log file: <i>' . $logFile . '</i><br><br><hr>';
20
 
@@ -35,6 +41,7 @@ class ConvertLog
35
  //file_get_contents
36
 
37
  echo json_encode($msg, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
 
38
  wp_die();
39
  }
40
 
15
  }
16
  $source = $_POST['source'];
17
 
18
+ // We need to be absolute certain that this feature can be misused.
19
+ // - so disabling until I get the time...
20
+
21
+ $msg = 'This feature is on the road map...';
22
+ echo json_encode($msg, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
23
+ /*
24
  $logFile = ConvertHelperIndependent::getLogFilename($source, Paths::getLogDirAbs());
25
  $msg = 'Log file: <i>' . $logFile . '</i><br><br><hr>';
26
 
41
  //file_get_contents
42
 
43
  echo json_encode($msg, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
44
+ */
45
  wp_die();
46
  }
47
 
lib/debug.php CHANGED
@@ -2,6 +2,11 @@
2
 
3
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
 
 
 
 
 
 
5
  function webpexpress_activated() {
6
  update_option( 'webp-express-activation-error', ob_get_contents() );
7
  }
2
 
3
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
 
5
+ /*
6
+ This file is actually not included, only when debugging activation errors, I include it manually.
7
+ Haven't used it in a quite a while...
8
+ */
9
+
10
  function webpexpress_activated() {
11
  update_option( 'webp-express-activation-error', ob_get_contents() );
12
  }
lib/options/enqueue_scripts.php CHANGED
@@ -8,8 +8,8 @@ use \WebPExpress\Paths;
8
  include_once __DIR__ . '/../classes/Config.php';
9
  use \WebPExpress\Config;
10
 
11
- $ver = '1'; // note: Minimum 1
12
- $jsDir = 'js/0.14.5';
13
 
14
  if (!function_exists('webp_express_add_inline_script')) {
15
  function webp_express_add_inline_script($id, $script, $position) {
@@ -28,6 +28,9 @@ wp_enqueue_script('sortable');
28
  wp_register_script('daspopup', plugins_url($jsDir . '/das-popup.js', __FILE__), [], $ver);
29
  wp_enqueue_script('daspopup');
30
 
 
 
 
31
  $config = Config::getConfigForOptionsPage();
32
 
33
 
@@ -44,22 +47,30 @@ if (!(isset($config['operation-mode']) && ($config['operation-mode'] == 'no-conv
44
  }
45
 
46
  // Converters
47
- wp_register_script('converters', plugins_url($jsDir . '/converters.js', __FILE__), ['sortable','daspopup'], $ver);
 
 
 
48
  webp_express_add_inline_script('converters', 'window.webpExpressPaths = ' . json_encode(Paths::getUrlsAndPathsForTheJavascript()) . ';', 'before');
 
 
49
  webp_express_add_inline_script('converters', 'window.converters = ' . json_encode($config['converters']) . ';', 'before');
50
  wp_enqueue_script('converters');
51
 
52
  // Whitelist
53
- wp_register_script('whitelist', plugins_url($jsDir . '/whitelist.js', __FILE__), ['daspopup'], $ver);
 
 
 
54
  webp_express_add_inline_script('whitelist', 'window.whitelist = ' . json_encode($config['web-service']['whitelist']) . ';', 'before');
55
  wp_enqueue_script('whitelist');
56
 
57
  // bulk convert
58
- wp_register_script('bulkconvert', plugins_url($jsDir . '/bulk-convert.js', __FILE__), [], $ver);
59
  wp_enqueue_script('bulkconvert');
60
 
61
  // test convert
62
- wp_register_script('testconvert', plugins_url($jsDir . '/test-convert.js', __FILE__), [], $ver);
63
  $canDisplayWebp = (isset($_SERVER['HTTP_ACCEPT']) && (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false ));
64
 
65
  /*
8
  include_once __DIR__ . '/../classes/Config.php';
9
  use \WebPExpress\Config;
10
 
11
+ $ver = '2'; // note: Minimum 1
12
+ $jsDir = 'js/0.14.5'; // We change dir when it is critical that no-one gets the cached version (there is a plugin that strips version strings out there...)
13
 
14
  if (!function_exists('webp_express_add_inline_script')) {
15
  function webp_express_add_inline_script($id, $script, $position) {
28
  wp_register_script('daspopup', plugins_url($jsDir . '/das-popup.js', __FILE__), [], $ver);
29
  wp_enqueue_script('daspopup');
30
 
31
+ wp_register_script('escapehtml', plugins_url($jsDir . '/escapeHTML.js', __FILE__), [], $ver);
32
+ wp_enqueue_script('escapehtml');
33
+
34
  $config = Config::getConfigForOptionsPage();
35
 
36
 
47
  }
48
 
49
  // Converters
50
+ // ----------
51
+ wp_register_script('converters', plugins_url($jsDir . '/converters.js', __FILE__), ['sortable', 'daspopup', 'escapehtml'], $ver);
52
+
53
+ // PS: no escaping/sanitizing needed as json_encode always produces something safe
54
  webp_express_add_inline_script('converters', 'window.webpExpressPaths = ' . json_encode(Paths::getUrlsAndPathsForTheJavascript()) . ';', 'before');
55
+
56
+ // PS: no escaping/sanitizing needed as json_encode always produces something safe
57
  webp_express_add_inline_script('converters', 'window.converters = ' . json_encode($config['converters']) . ';', 'before');
58
  wp_enqueue_script('converters');
59
 
60
  // Whitelist
61
+ // ---------
62
+ wp_register_script('whitelist', plugins_url($jsDir . '/whitelist.js', __FILE__), ['daspopup', 'escapehtml'], $ver);
63
+
64
+ // PS: no escaping/sanitizing needed as json_encode always produces something safe
65
  webp_express_add_inline_script('whitelist', 'window.whitelist = ' . json_encode($config['web-service']['whitelist']) . ';', 'before');
66
  wp_enqueue_script('whitelist');
67
 
68
  // bulk convert
69
+ wp_register_script('bulkconvert', plugins_url($jsDir . '/bulk-convert.js', __FILE__), ['escapehtml'], $ver);
70
  wp_enqueue_script('bulkconvert');
71
 
72
  // test convert
73
+ wp_register_script('testconvert', plugins_url($jsDir . '/test-convert.js', __FILE__), ['escapehtml'], $ver);
74
  $canDisplayWebp = (isset($_SERVER['HTTP_ACCEPT']) && (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') !== false ));
75
 
76
  /*
lib/options/js/0.14.5/bulk-convert.js CHANGED
@@ -11,7 +11,7 @@ function openBulkConvertPopup() {
11
  if ((typeof response == 'object') && (response['success'] == false)) {
12
  html = '<h1>Error</h1>';
13
  if (response['data'] && ((typeof response['data']) == 'string')) {
14
- html += response['data'];
15
  }
16
  document.getElementById('bulkconvertcontent').innerHTML = html;
17
  return
@@ -111,6 +111,8 @@ function getReductionHtml(orgSize, webpSize, sizeOfOriginalText, sizeOfWebpText)
111
  var reduction = Math.round((orgSize - webpSize)/orgSize * 100);
112
  var sizeInfo = getPrintableSizeInfo(orgSize, webpSize);
113
  var hoverText = sizeOfOriginalText + ': ' + sizeInfo['org'] + '.<br>' + sizeOfWebpText + ': ' + sizeInfo['webp'];
 
 
114
  return '<span class="has-tip reduction">' + reduction + '%' +
115
  '<span class="tip">' + hoverText + '</span>' +
116
  '</span><br>';
@@ -131,6 +133,9 @@ function logLn() {
131
 
132
  function webpexpress_viewLog(groupPointer, filePointer) {
133
 
 
 
 
134
  var bulkInfo = window.webpexpress_bulkconvert;
135
  var group = bulkInfo.groups[groupPointer];
136
  var filename = group.files[filePointer];
@@ -154,14 +159,20 @@ function webpexpress_viewLog(groupPointer, filePointer) {
154
  if ((typeof response == 'object') && (response['success'] == false)) {
155
  html = '<h1>Error</h1>';
156
  if (response['data'] && ((typeof response['data']) == 'string')) {
157
- html += response['data'];
158
  }
159
  document.getElementById('conversionlog_content').innerHTML = html;
160
- return
161
  }
162
 
163
  var result = JSON.parse(response);
164
- var html = '<h1>Conversion log</h1><br>' + result;
 
 
 
 
 
 
165
  document.getElementById('conversionlog_content').innerHTML = html;
166
  },
167
  error: () => {
@@ -172,7 +183,7 @@ function webpexpress_viewLog(groupPointer, filePointer) {
172
  //<h1>Conversion log</h1>
173
  //tb_show('Conversion log', '#TB_inline?inlineId=conversionlog');
174
  openDasPopup('conversionlog', w, h);
175
-
176
  }
177
 
178
  function convertNextInBulkQueue() {
@@ -217,7 +228,8 @@ function convertNextInBulkQueue() {
217
  if ((typeof response == 'object') && (response['success'] == false)) {
218
  html = '<h1>Error</h1>';
219
  if (response['data'] && ((typeof response['data']) == 'string')) {
220
- html += response['data'];
 
221
  }
222
  logLn(html);
223
  return
@@ -237,8 +249,11 @@ function convertNextInBulkQueue() {
237
  //console.log(result);
238
 
239
  var html = '';
240
- //var htmlViewLog = '&nbsp;&nbsp;<a style="cursor:pointer" onclick="webpexpress_viewLog(\'' + group.root + '/' + filename + '\')">view log</a>';
241
- var htmlViewLog = '&nbsp;&nbsp;<a style="cursor:pointer" onclick="webpexpress_viewLog(' + bulkInfo.groupPointer + ',' + bulkInfo.filePointer + ')">view log</a>';
 
 
 
242
  if (result['success']) {
243
 
244
  var orgSize = result['filesize-original'];
@@ -306,11 +321,3 @@ function convertNextInBulkQueue() {
306
  },
307
  });
308
  }
309
-
310
-
311
-
312
- //alert('bulk');
313
- /*
314
- jQuery(document).ready(function($) {
315
- });
316
- */
11
  if ((typeof response == 'object') && (response['success'] == false)) {
12
  html = '<h1>Error</h1>';
13
  if (response['data'] && ((typeof response['data']) == 'string')) {
14
+ html += webpexpress_escapeHTML(response['data']);
15
  }
16
  document.getElementById('bulkconvertcontent').innerHTML = html;
17
  return
111
  var reduction = Math.round((orgSize - webpSize)/orgSize * 100);
112
  var sizeInfo = getPrintableSizeInfo(orgSize, webpSize);
113
  var hoverText = sizeOfOriginalText + ': ' + sizeInfo['org'] + '.<br>' + sizeOfWebpText + ': ' + sizeInfo['webp'];
114
+
115
+ // ps: this is all safe to print
116
  return '<span class="has-tip reduction">' + reduction + '%' +
117
  '<span class="tip">' + hoverText + '</span>' +
118
  '</span><br>';
133
 
134
  function webpexpress_viewLog(groupPointer, filePointer) {
135
 
136
+ /*
137
+ disabled until I am certain that security is in place.
138
+
139
  var bulkInfo = window.webpexpress_bulkconvert;
140
  var group = bulkInfo.groups[groupPointer];
141
  var filename = group.files[filePointer];
159
  if ((typeof response == 'object') && (response['success'] == false)) {
160
  html = '<h1>Error</h1>';
161
  if (response['data'] && ((typeof response['data']) == 'string')) {
162
+ html += webpexpress_escapeHTML(response['data']);
163
  }
164
  document.getElementById('conversionlog_content').innerHTML = html;
165
+ return;
166
  }
167
 
168
  var result = JSON.parse(response);
169
+
170
+ // the "log" result is a simply form of markdown, using just italic, bold and newlines.
171
+ // It ought not to return anything evil, but for good practice, let us encode.
172
+ result = webpexpress_escapeHTML(result);
173
+
174
+ var html = '<h1>Conversion log</h1><br>' + '<pre style="white-space:pre-wrap">' + result + '</pre>';
175
+
176
  document.getElementById('conversionlog_content').innerHTML = html;
177
  },
178
  error: () => {
183
  //<h1>Conversion log</h1>
184
  //tb_show('Conversion log', '#TB_inline?inlineId=conversionlog');
185
  openDasPopup('conversionlog', w, h);
186
+ */
187
  }
188
 
189
  function convertNextInBulkQueue() {
228
  if ((typeof response == 'object') && (response['success'] == false)) {
229
  html = '<h1>Error</h1>';
230
  if (response['data'] && ((typeof response['data']) == 'string')) {
231
+ // disabled. Need to check if it is secure
232
+ //html += webpexpress_escapeHTML(response['data']);
233
  }
234
  logLn(html);
235
  return
249
  //console.log(result);
250
 
251
  var html = '';
252
+
253
+ var htmlViewLog = '';
254
+
255
+ // uncommented until I'm certain that security is in place
256
+ //var htmlViewLog = '&nbsp;&nbsp;<a style="cursor:pointer" onclick="webpexpress_viewLog(' + bulkInfo.groupPointer + ',' + bulkInfo.filePointer + ')">view log</a>';
257
  if (result['success']) {
258
 
259
  var orgSize = result['filesize-original'];
321
  },
322
  });
323
  }
 
 
 
 
 
 
 
 
lib/options/js/0.14.5/converters.js CHANGED
@@ -24,15 +24,6 @@ function getConversionMethodDescription(converterId) {
24
  return converterId;
25
  }
26
 
27
- function htmlEscape(str) {
28
- return str
29
- .replace(/&/g, '&amp;')
30
- .replace(/"/g, '&quot;')
31
- .replace(/'/g, '&#39;')
32
- .replace(/</g, '&lt;')
33
- .replace(/>/g, '&gt;');
34
- }
35
-
36
  function generateConverterHTML(converter) {
37
  html = '<li data-id="' + converter['id'] + '" class="' + (converter.deactivated ? 'deactivated' : '') + ' ' + (converter.working ? 'operational' : 'not-operational') + '">';
38
  //html += '<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="17px" height="17px" viewBox="0 0 100.000000 100.000000" preserveAspectRatio="xMidYMid meet"><g transform="translate(0.000000,100.000000) scale(0.100000,-0.100000)" fill="#444444" stroke="none"><path d="M415 920 l-80 -80 165 0 165 0 -80 80 c-44 44 -82 80 -85 80 -3 0 -41 -36 -85 -80z"/><path d="M0 695 l0 -45 500 0 500 0 0 45 0 45 -500 0 -500 0 0 -45z"/><path d="M0 500 l0 -40 500 0 500 0 0 40 0 40 -500 0 -500 0 0 -40z"/><path d="M0 305 l0 -45 500 0 500 0 0 45 0 45 -500 0 -500 0 0 -45z"/><path d="M418 78 l82 -83 82 83 83 82 -165 0 -165 0 83 -82z"/></g></svg>';
@@ -66,7 +57,7 @@ function generateConverterHTML(converter) {
66
  html += '<g fill="currentcolor" stroke="none" transform="translate(0.000000,500.000000) scale(0.100000,-0.100000)"><path d="M2315 4800 c-479 -35 -928 -217 -1303 -527 -352 -293 -615 -702 -738 -1151 -104 -380 -104 -824 0 -1204 107 -389 302 -724 591 -1013 354 -354 785 -572 1279 -646 196 -30 476 -30 672 0 494 74 925 292 1279 646 354 354 571 784 646 1279 30 197 30 475 0 672 -75 495 -292 925 -646 1279 -289 289 -624 484 -1013 591 -228 62 -528 91 -767 74z m353 -511 c458 -50 874 -272 1170 -624 417 -497 536 -1174 308 -1763 -56 -145 -176 -367 -235 -434 -4 -4 -566 552 -1250 1236 l-1243 1243 94 60 c354 229 754 327 1156 282z m864 -3200 c-67 -59 -289 -179 -434 -235 -946 -366 -2024 172 -2322 1158 -47 155 -66 276 -73 453 -13 362 84 704 290 1023 l60 94 1243 -1243 c684 -684 1240 -1246 1236 -1250z"/></g></svg>';
67
  html += '<div class="popup">';
68
 
69
- html += htmlEscape(converter['error']);
70
 
71
  html += '</div>';
72
  }
24
  return converterId;
25
  }
26
 
 
 
 
 
 
 
 
 
 
27
  function generateConverterHTML(converter) {
28
  html = '<li data-id="' + converter['id'] + '" class="' + (converter.deactivated ? 'deactivated' : '') + ' ' + (converter.working ? 'operational' : 'not-operational') + '">';
29
  //html += '<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="17px" height="17px" viewBox="0 0 100.000000 100.000000" preserveAspectRatio="xMidYMid meet"><g transform="translate(0.000000,100.000000) scale(0.100000,-0.100000)" fill="#444444" stroke="none"><path d="M415 920 l-80 -80 165 0 165 0 -80 80 c-44 44 -82 80 -85 80 -3 0 -41 -36 -85 -80z"/><path d="M0 695 l0 -45 500 0 500 0 0 45 0 45 -500 0 -500 0 0 -45z"/><path d="M0 500 l0 -40 500 0 500 0 0 40 0 40 -500 0 -500 0 0 -40z"/><path d="M0 305 l0 -45 500 0 500 0 0 45 0 45 -500 0 -500 0 0 -45z"/><path d="M418 78 l82 -83 82 83 83 82 -165 0 -165 0 83 -82z"/></g></svg>';
57
  html += '<g fill="currentcolor" stroke="none" transform="translate(0.000000,500.000000) scale(0.100000,-0.100000)"><path d="M2315 4800 c-479 -35 -928 -217 -1303 -527 -352 -293 -615 -702 -738 -1151 -104 -380 -104 -824 0 -1204 107 -389 302 -724 591 -1013 354 -354 785 -572 1279 -646 196 -30 476 -30 672 0 494 74 925 292 1279 646 354 354 571 784 646 1279 30 197 30 475 0 672 -75 495 -292 925 -646 1279 -289 289 -624 484 -1013 591 -228 62 -528 91 -767 74z m353 -511 c458 -50 874 -272 1170 -624 417 -497 536 -1174 308 -1763 -56 -145 -176 -367 -235 -434 -4 -4 -566 552 -1250 1236 l-1243 1243 94 60 c354 229 754 327 1156 282z m864 -3200 c-67 -59 -289 -179 -434 -235 -946 -366 -2024 172 -2322 1158 -47 155 -66 276 -73 453 -13 362 84 704 290 1023 l60 94 1243 -1243 c684 -684 1240 -1246 1236 -1250z"/></g></svg>';
58
  html += '<div class="popup">';
59
 
60
+ html += webpexpress_escapeHTML(converter['error']);
61
 
62
  html += '</div>';
63
  }
lib/options/js/0.14.5/escapeHTML.js ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ function htmlEscape(str) {
3
+ return str
4
+ .replace(/&/g, '&amp;')
5
+ .replace(/"/g, '&quot;')
6
+ .replace(/'/g, '&#39;')
7
+ .replace(/</g, '&lt;')
8
+ .replace(/>/g, '&gt;');
9
+ }
10
+ */
11
+ function webpexpress_escapeHTML(s)
12
+ {
13
+ return s.replace(/./gm, function(s) {
14
+ return "&#" + s.charCodeAt(0) + ";";
15
+ });
16
+ }
lib/options/js/0.14.5/test-convert.js CHANGED
@@ -207,7 +207,8 @@ function convertResponseCallback(response){
207
  }
208
 
209
  var result = JSON.parse(response);
210
- result['log'] = processLogMoveOptions(result['log']);
 
211
 
212
  //var html = document.getElementById('tc_conversion_result').innerHTML;
213
  var html = '';
@@ -258,8 +259,11 @@ function convertResponseCallback(response){
258
  html += '<i>Drag the slider above to compare original vs webp</i><br><br>'
259
  }
260
 
261
- html += '<h3>Conversion log:</h3>'
262
- html += result['log'];
 
 
 
263
 
264
  document.getElementById('tc_conversion_result').innerHTML = html;
265
  initComparisonSlider(jQuery);
@@ -268,11 +272,11 @@ function convertResponseCallback(response){
268
  html += '<h2>Result: <span style="color:red;margin-bottom:2px">Failure</span></h2>';
269
 
270
  if (result['msg'] != '') {
271
- html += ' <h3>Message: <span style="color:red; font-weight: bold">' + result['msg'] + '</span></h3>';
272
  }
273
  if (result['log'] != '') {
274
  html += '<h3>Conversion log:</h3>';
275
- html += result['log'];
276
  }
277
 
278
  document.getElementById('tc_conversion_result').innerHTML = html;
207
  }
208
 
209
  var result = JSON.parse(response);
210
+ //result['log'] = processLogMoveOptions(result['log']);
211
+
212
 
213
  //var html = document.getElementById('tc_conversion_result').innerHTML;
214
  var html = '';
259
  html += '<i>Drag the slider above to compare original vs webp</i><br><br>'
260
  }
261
 
262
+ html += '<h3>Conversion log:</h3>';
263
+
264
+ // the "log" result is a simple form of markdown, using just italic, bold and newlines.
265
+ // It ought not to return anything evil, but safety first
266
+ html += '<pre style="white-space:pre-wrap">' + webpexpress_escapeHTML(result['log']) + '</pre>';
267
 
268
  document.getElementById('tc_conversion_result').innerHTML = html;
269
  initComparisonSlider(jQuery);
272
  html += '<h2>Result: <span style="color:red;margin-bottom:2px">Failure</span></h2>';
273
 
274
  if (result['msg'] != '') {
275
+ html += ' <h3>Message: <span style="color:red; font-weight: bold">' + webpexpress_escapeHTML(result['msg']) + '</span></h3>';
276
  }
277
  if (result['log'] != '') {
278
  html += '<h3>Conversion log:</h3>';
279
+ html += '<pre style="white-space:pre-wrap">' + webpexpress_escapeHTML(result['log']) + '</pre>';
280
  }
281
 
282
  document.getElementById('tc_conversion_result').innerHTML = html;
lib/options/js/0.14.5/whitelist.js CHANGED
@@ -88,13 +88,6 @@ function whitelistRemoveEntry(i) {
88
  whitelistSetHTML();
89
  }
90
 
91
- function whitelistEncodeHTMLEntities(s)
92
- {
93
- return s.replace(/./gm, function(s) {
94
- return "&#" + s.charCodeAt(0) + ";";
95
- });
96
- }
97
-
98
  function whitelistSetHTML() {
99
  updateWhitelistInputValue();
100
  var s = '';
@@ -104,7 +97,7 @@ function whitelistSetHTML() {
104
  s+='<ul>';
105
  for (var i=0; i<window.whitelist.length; i++) {
106
  s+='<li>';
107
- s+= whitelistEncodeHTMLEntities(window.whitelist[i]['label']);
108
  s+='<div class="whitelist-links">'
109
  s+='<a href="javascript:whitelistEditEntry(' + i + ')">edit</a>';
110
  s+='<a href="javascript:whitelistRemoveEntry(' + i + ')">remove</a>';
88
  whitelistSetHTML();
89
  }
90
 
 
 
 
 
 
 
 
91
  function whitelistSetHTML() {
92
  updateWhitelistInputValue();
93
  var s = '';
97
  s+='<ul>';
98
  for (var i=0; i<window.whitelist.length; i++) {
99
  s+='<li>';
100
+ s+= webpexpress_escapeHTML(window.whitelist[i]['label']);
101
  s+='<div class="whitelist-links">'
102
  s+='<a href="javascript:whitelistEditEntry(' + i + ')">edit</a>';
103
  s+='<a href="javascript:whitelistRemoveEntry(' + i + ')">remove</a>';
lib/options/options/alter-html/alter-html-options.inc CHANGED
@@ -25,7 +25,7 @@
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">
@@ -100,7 +100,7 @@
100
  'alter-html-replacement',
101
  'picture',
102
  'Replace &lt;img&gt; tags with &lt;picture&gt; tags, adding the webp to srcset.',
103
- $config['alter-html']['replacement'],
104
  '<p>"Picture tag" replaces &lt;img&gt tags with &lt;picture&gt; tags and adds the webp as an extra source. ' .
105
  'This effectively points webp-enabled browsers to the webp variant and other browsers to ' .
106
  'the original image.</p>' .
@@ -118,7 +118,7 @@
118
  <?php
119
  webpexpress_checkbox(
120
  'alter-html-add-picturefill-js',
121
- $config['alter-html']['alter-html-add-picturefill-js'],
122
  'Dynamically load picturefill.js on older browsers',
123
  'If you enable this option, a small script will be added which detects if picture tags are supported and loads ' .
124
  '<a href="https://github.com/scottjehl/picturefill" target="_blank">picturefill.js</a> if not. ' .
@@ -133,7 +133,7 @@
133
  'alter-html-replacement',
134
  'url',
135
  'Replace image URLs',
136
- $config['alter-html']['replacement'],
137
  '<p>"Image URLs" replaces the image URLs to point to ' .
138
  'the webp <i>rather than</i> the original. Handles src, srcset, common lazy-load attributes and even ' .
139
  'inline styles</p>' .
@@ -153,7 +153,7 @@
153
  <?php
154
  webpexpress_checkbox(
155
  'alter-html-only-for-webp-enabled-browsers',
156
- $config['alter-html']['only-for-webp-enabled-browsers'],
157
  'Only do the replacements in webp enabled browsers',
158
  'If you enable this option, the replacements will only be made, when the request is from ' .
159
  'a browser that supports webp. Note that this will not play well with plugins that caches ' .
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="false">
29
  </p>
30
  <div id="alter_html_comparison_chart" name="alter-html-comparison-chart" class="toggler effect-slider">
31
  <table class="designed">
100
  'alter-html-replacement',
101
  'picture',
102
  'Replace &lt;img&gt; tags with &lt;picture&gt; tags, adding the webp to srcset.',
103
+ $config['alter-html']['replacement'], // PS: the function takes care of the escaping
104
  '<p>"Picture tag" replaces &lt;img&gt tags with &lt;picture&gt; tags and adds the webp as an extra source. ' .
105
  'This effectively points webp-enabled browsers to the webp variant and other browsers to ' .
106
  'the original image.</p>' .
118
  <?php
119
  webpexpress_checkbox(
120
  'alter-html-add-picturefill-js',
121
+ $config['alter-html']['alter-html-add-picturefill-js'], // PS: the function takes care of the escaping
122
  'Dynamically load picturefill.js on older browsers',
123
  'If you enable this option, a small script will be added which detects if picture tags are supported and loads ' .
124
  '<a href="https://github.com/scottjehl/picturefill" target="_blank">picturefill.js</a> if not. ' .
133
  'alter-html-replacement',
134
  'url',
135
  'Replace image URLs',
136
+ $config['alter-html']['replacement'], // PS: the function takes care of the escaping
137
  '<p>"Image URLs" replaces the image URLs to point to ' .
138
  'the webp <i>rather than</i> the original. Handles src, srcset, common lazy-load attributes and even ' .
139
  'inline styles</p>' .
153
  <?php
154
  webpexpress_checkbox(
155
  'alter-html-only-for-webp-enabled-browsers',
156
+ $config['alter-html']['only-for-webp-enabled-browsers'] == true,
157
  'Only do the replacements in webp enabled browsers',
158
  'If you enable this option, the replacements will only be made, when the request is from ' .
159
  'a browser that supports webp. Note that this will not play well with plugins that caches ' .
lib/options/options/conversion-options/jpeg.inc CHANGED
@@ -96,7 +96,7 @@ png
96
  <label>
97
  Limit:
98
  </label>
99
- <input type="text" size=3 id="max_quality" name="max-quality" value="<?php echo $config['max-quality']; ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
100
  <?php echo helpIcon(
101
  'Quality is expensive byte-wise. For most websites, more than 80 is a waste of bytes. ' .
102
  'This option allows you to limit the quality to whatever is lowest: ' .
@@ -105,7 +105,7 @@ png
105
  <label style="display:inline-block; margin-left:10px">
106
  Fallback:
107
  </label>
108
- <input type="text" size=3 name="quality-fallback" value="<?php echo $config['quality-specific'] ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
109
  <?php
110
  echo helpIcon(
111
  'Fallback quality in case quality detection is not available or should fail for some reason (which has yet to be seen). ' .
@@ -119,7 +119,7 @@ png
119
  </div>
120
 
121
  <div id="quality_specific_div" style="display:inline-block" class="toggler effect-visibility">
122
- <input type="text" size=3 name="quality-specific" value="<?php echo $config['quality-specific'] ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
123
  <?php
124
  echo helpIcon('Enter number (0 - 100)');
125
  ?>
@@ -150,7 +150,7 @@ png
150
  <label>
151
  "Near lossless" quality:
152
  </label>
153
- <input type="text" size=3 name="jpeg-near-lossless" value="<?php echo $config['jpeg-near-lossless'] ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
154
  <?php
155
  echo helpIcon(
156
  'The level of near-lossless image preprocessing (when trying lossless). ' .
96
  <label>
97
  Limit:
98
  </label>
99
+ <input type="text" size=3 id="max_quality" name="max-quality" value="<?php echo esc_attr($config['max-quality']); ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
100
  <?php echo helpIcon(
101
  'Quality is expensive byte-wise. For most websites, more than 80 is a waste of bytes. ' .
102
  'This option allows you to limit the quality to whatever is lowest: ' .
105
  <label style="display:inline-block; margin-left:10px">
106
  Fallback:
107
  </label>
108
+ <input type="text" size=3 name="quality-fallback" value="<?php echo esc_attr($config['quality-specific']) ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
109
  <?php
110
  echo helpIcon(
111
  'Fallback quality in case quality detection is not available or should fail for some reason (which has yet to be seen). ' .
119
  </div>
120
 
121
  <div id="quality_specific_div" style="display:inline-block" class="toggler effect-visibility">
122
+ <input type="text" size=3 name="quality-specific" value="<?php echo esc_attr($config['quality-specific']) ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
123
  <?php
124
  echo helpIcon('Enter number (0 - 100)');
125
  ?>
150
  <label>
151
  "Near lossless" quality:
152
  </label>
153
+ <input type="text" size=3 name="jpeg-near-lossless" value="<?php echo esc_attr($config['jpeg-near-lossless']) ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
154
  <?php
155
  echo helpIcon(
156
  'The level of near-lossless image preprocessing (when trying lossless). ' .
lib/options/options/conversion-options/metadata.inc CHANGED
@@ -4,7 +4,10 @@
4
  $metadata = $config['metadata'];
5
 
6
  echo '<tr><th scope="row">Metadata';
7
- echo helpIcon('Decide what to do with image metadata, such as Exif. Note that this setting is not supported by the "Gd" conversion method, as it is not possible to copy the metadata with the Gd extension. Imagickbinary also currently lacks support');
 
 
 
8
  echo '</th><td>';
9
 
10
  echo '<select id="metadata" name="metadata">';
4
  $metadata = $config['metadata'];
5
 
6
  echo '<tr><th scope="row">Metadata';
7
+ echo helpIcon(
8
+ 'Decide what to do with image metadata, such as Exif. Note that this setting is not supported by the "Gd" conversion method, ' .
9
+ 'as it is not possible to copy the metadata with the Gd extension. Imagickbinary also currently lacks support'
10
+ );
11
  echo '</th><td>';
12
 
13
  echo '<select id="metadata" name="metadata">';
lib/options/options/conversion-options/png.inc CHANGED
@@ -38,7 +38,7 @@
38
  Quality for lossy:
39
  </label>
40
 
41
- <input type="text" size=3 name="png-quality" value="<?php echo $config['png-quality'] ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
42
  <?php
43
  echo helpIcon(
44
  '<p>You probably want to set this value a bit higher than the quality for JPEGs. PNGs are often used for icons and graphics, ' .
@@ -49,7 +49,7 @@
49
  <label style="margin-left:10px">
50
  Alpha quality:
51
  </label>
52
- <input type="text" size=3 name="alpha-quality" value="<?php echo $config['alpha-quality'] ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
53
  <?php
54
  echo helpIcon(
55
  'The alpha quality is the quality of the alpha channel (the tranparency layer). ' .
@@ -85,7 +85,7 @@
85
  <label>
86
  "Near lossless" quality:
87
  </label>
88
- <input type="text" size=3 name="png-near-lossless" value="<?php echo $config['png-near-lossless'] ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
89
  <?php
90
  echo helpIcon(
91
  'The level of near-lossless image preprocessing (when trying lossless). ' .
38
  Quality for lossy:
39
  </label>
40
 
41
+ <input type="text" size=3 name="png-quality" value="<?php echo esc_attr($config['png-quality']) ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
42
  <?php
43
  echo helpIcon(
44
  '<p>You probably want to set this value a bit higher than the quality for JPEGs. PNGs are often used for icons and graphics, ' .
49
  <label style="margin-left:10px">
50
  Alpha quality:
51
  </label>
52
+ <input type="text" size=3 name="alpha-quality" value="<?php echo esc_attr($config['alpha-quality']) ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
53
  <?php
54
  echo helpIcon(
55
  'The alpha quality is the quality of the alpha channel (the tranparency layer). ' .
85
  <label>
86
  "Near lossless" quality:
87
  </label>
88
+ <input type="text" size=3 name="png-near-lossless" value="<?php echo esc_attr($config['png-near-lossless']) ?>" style="text-align:right; padding-left:0px; padding-right:4px; width:34px">
89
  <?php
90
  echo helpIcon(
91
  'The level of near-lossless image preprocessing (when trying lossless). ' .
lib/options/options/conversion-options/quality.inc CHANGED
@@ -50,7 +50,7 @@ if ($canDetectQuality) {
50
  // echo '<tr id="max_quality_div"><th scope="row">Max quality (0-100)';
51
  echo '<div id="max_quality_div">Max ';
52
  //echo '</th><td>';
53
- echo '<input type="text" size=3 id="max_quality" name="max-quality" value="' . $maxQuality . '">';
54
  echo helpIcon('Quality is expensive byte-wise. For most websites, more than 80 is a waste of bytes. ' .
55
  'This option allows you to limit the quality to whatever is lowest: ' .
56
  'the quality of the jpeg or the limit entered here. Recommended value: Somewhere between 50-85');
@@ -77,7 +77,7 @@ if ($canDetectQuality) {
77
  */
78
  //echo '</th><td>';
79
 
80
- echo '<input type="text" size=3 id="quality_specific" name="quality-specific" value="' . $qualitySpecific . '">';
81
  echo helpIcon('Enter number (0 - 100)');
82
  echo '</div>';
83
  echo '</td></tr>';
@@ -90,6 +90,6 @@ echo helpIcon(
90
  'Quality of webp, when the image that is converted is a png.'
91
  );
92
  echo '</th><td>';
93
- echo '<input type="text" size=3 id="quality_png" name="quality-png" value="' . $config['quality-png'] . '">';
94
  echo helpIcon('Enter number (0 - 100). Recommended value: Somewhere between 60-90');
95
  echo '</td></tr>';
50
  // echo '<tr id="max_quality_div"><th scope="row">Max quality (0-100)';
51
  echo '<div id="max_quality_div">Max ';
52
  //echo '</th><td>';
53
+ echo '<input type="text" size=3 id="max_quality" name="max-quality" value="' . esc_attr($maxQuality) . '">';
54
  echo helpIcon('Quality is expensive byte-wise. For most websites, more than 80 is a waste of bytes. ' .
55
  'This option allows you to limit the quality to whatever is lowest: ' .
56
  'the quality of the jpeg or the limit entered here. Recommended value: Somewhere between 50-85');
77
  */
78
  //echo '</th><td>';
79
 
80
+ echo '<input type="text" size=3 id="quality_specific" name="quality-specific" value="' . esc_attr($qualitySpecific) . '">';
81
  echo helpIcon('Enter number (0 - 100)');
82
  echo '</div>';
83
  echo '</td></tr>';
90
  'Quality of webp, when the image that is converted is a png.'
91
  );
92
  echo '</th><td>';
93
+ echo '<input type="text" size=3 id="quality_png" name="quality-png" value="' . esc_attr($config['quality-png']) . '">';
94
  echo helpIcon('Enter number (0 - 100). Recommended value: Somewhere between 60-90');
95
  echo '</td></tr>';
lib/options/options/general/cache-control.inc CHANGED
@@ -26,7 +26,7 @@ $cacheControlPublic = $config['cache-control-public'];
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 ?>">
30
  <?php echo helpIcon(
31
  'You can read about possible options ' .
32
  '<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control">here</a>',
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 esc_attr($cacheControlCustom) ?>">
30
  <?php echo helpIcon(
31
  'You can read about possible options ' .
32
  '<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control">here</a>',
lib/options/options/operation-mode.inc CHANGED
@@ -10,7 +10,7 @@ $operationMode = $config['operation-mode'];
10
  'Changing back will override the tweaks (you will lose them).</p>' .
11
  '<p>You will never loose your converter configurations by changing mode</p>');
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>
10
  'Changing back will override the tweaks (you will lose them).</p>' .
11
  '<p>You will never loose your converter configurations by changing mode</p>');
12
  ?>
13
+ <input type="hidden" name="operation-mode" id="operation_mode" value="<?php echo esc_attr($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>
lib/options/options/redirection-rules/do-not-pass-source-path-in-query-string.inc CHANGED
@@ -1,6 +1,11 @@
1
  <?php
2
  echo '<tr><th scope="row">Do not pass source in Query String';
3
- echo helpIcon('You can try unchecking this, if you are experiencing that no images are converted. In v0.8 and below, the <i>.htaccess</i> always passed the filename of the image to the script through the query string. It however seems that passing through an environment variable instead works just fine. As passing it through the query string can cause some firewalls to block the request, we no longer do this per default.');
 
 
 
 
 
4
  echo '</th><td>';
5
  echo '<input type="checkbox" id="do_not_pass_source_in_query_string" name="do-not-pass-source-in-query-string" value="true" ' . ($config['do-not-pass-source-in-query-string'] ? 'checked="checked"' : '') . '">';
6
  echo '</td></tr>';
1
  <?php
2
  echo '<tr><th scope="row">Do not pass source in Query String';
3
+ echo helpIcon(
4
+ 'You can try unchecking this, if you are experiencing that no images are converted. In v0.8 and below, the <i>.htaccess</i> ' .
5
+ 'always passed the filename of the image to the script through the query string. ' .
6
+ 'It however seems that passing through an environment variable instead works just fine. ' .
7
+ 'As passing it through the query string can cause some firewalls to block the request, we no longer do this per default.'
8
+ );
9
  echo '</th><td>';
10
  echo '<input type="checkbox" id="do_not_pass_source_in_query_string" name="do-not-pass-source-in-query-string" value="true" ' . ($config['do-not-pass-source-in-query-string'] ? 'checked="checked"' : '') . '">';
11
  echo '</td></tr>';
lib/options/options/redirection-rules/only-redirect-to-converter-for-webp-enabled-browsers.inc CHANGED
@@ -2,7 +2,9 @@
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"
2
  <th scope="row">
3
  </th>
4
  <td>
5
+ Only redirect to converter for webp-enabled browsers?<?php echo helpIcon(
6
+ 'If checked, a condition is added to the .htaccess, that the <i>Accept</i> header contains "image/webp"'
7
+ ); ?>
8
  <input
9
  name="only-redirect-to-converter-for-webp-enabled-browsers"
10
  id="only_redirect_to_converter_for_webp_enabled_browsers"
lib/options/options/redirection-rules/only-redirect-to-converter-on-cache-miss.inc CHANGED
@@ -11,6 +11,8 @@
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>
11
  '"CDN friendly" operation mode.</p>'
12
  );
13
  ?>
14
+ <input type="checkbox" name="only-redirect-to-converter-on-cache-miss" value="true" <?php
15
+ echo ($config['only-redirect-to-converter-on-cache-miss'] ? 'checked="checked"' : '')
16
+ ?> >
17
  </td>
18
  </tr>
lib/options/options/redirection-rules/redirect-to-existing.inc CHANGED
@@ -20,7 +20,9 @@
20
  ?>
21
  </th>
22
  <td>
23
- <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"' : '') ?> >
 
 
24
 
25
  <?php
26
  /*if ($config['operation-mode'] == 'no-conversion') {
20
  ?>
21
  </th>
22
  <td>
23
+ <input type="checkbox" id="redirect_to_existing_in_htaccess" name="redirect-to-existing-in-htaccess" value="true" <?php
24
+ echo ($config['redirect-to-existing-in-htaccess'] ? 'checked="checked"' : '')
25
+ ?> >
26
 
27
  <?php
28
  /*if ($config['operation-mode'] == 'no-conversion') {
lib/options/options/redirection-rules/redirection-rules.inc CHANGED
@@ -10,7 +10,9 @@
10
  <h2><i>.htaccess</i> rules for webp generation</h2>
11
  <?php else : ?>
12
  <h3>Redirection rules</h3>
13
- <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>
 
 
14
  <?php endif; ?>
15
 
16
  <table class="form-table">
10
  <h2><i>.htaccess</i> rules for webp generation</h2>
11
  <?php else : ?>
12
  <h3>Redirection rules</h3>
13
+ <div><i>The options here affects the rules created in the .htaccess. <?php
14
+ echo helpIcon('Note: The general options also affects the rules.');
15
+ ?></i></div>
16
  <?php endif; ?>
17
 
18
  <table class="form-table">
lib/options/options/serve-options/response-on-success.inc CHANGED
@@ -1,6 +1,11 @@
1
  <?php
2
  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 = $config['success-response'];
1
  <?php
2
  echo '<tr><th scope="row">Response on success';
3
+ echo helpIcon(
4
+ '<p>Determines what to serve when conversion is a success. If you are using the Cache Enabler plugin, set to "Original image", ' .
5
+ 'otherwise you would normally set it to "Converted image".</p>' .
6
+ '<p>If set to "Converted image", a Vary:Accept header will be sent to indicate that the response depends on the Accept header ' .
7
+ '(which indicates if a browser supports webp images or not)</p><p>If set to "Original image", make sure to disable the "Redirect ' .
8
+ 'directly to converted image when available" option in the Redirect rules</p>');
9
  echo '</th><td>';
10
 
11
  $successResponse = $config['success-response'];
lib/options/options/web-service-options/web-service.inc CHANGED
@@ -6,9 +6,13 @@ use \WebPExpress\Paths;
6
  //echo '<script>window.whitelist = ' . json_encode($whitelist) . '</script>';
7
  ?>
8
  <tr id="share">
9
- <th scope="row">Enable web service?<?php echo helpIcon('Enabling the web service will allow selected sites to convert webp-images through this site (more options will appear, if you enable)'); ?></th>
 
 
10
  <td>
11
- <input type="checkbox" id="web_service_enabled" name="web-service-enabled" value="true" <?php echo ($config['web-service']['enabled'] ? 'checked="checked"' : '') ?>>
 
 
12
  <input type='text' name='whitelist' id='whitelist' value='' style='visibility:hidden; height:0' />
13
  <div id="whitelist_div"></div>
14
  <div id="whitelist_properties_popup" class="das-popup">
@@ -42,11 +46,16 @@ use \WebPExpress\Paths;
42
  <div>
43
  <label for="whitelist_require_api_key_to_be_crypted_in_transfer">
44
  Require api-key to be crypted in transfer?
45
- <?php echo helpIcon('If checked, the web service will only accept crypted api keys. Crypting the api-key protects it from being stolen during transfer. On a few older server setups, clients do not have the capability to crypt'); ?>
 
 
 
46
  </label>
47
  <input id="whitelist_require_api_key_to_be_crypted_in_transfer" type="checkbox">
48
  </div>
49
- <p style="margin-top: 15px">Psst: The endpoint of the web service is: <b><?php echo Paths::getWebServiceUrl() ?></b></p>
 
 
50
  <button id="whitelist_properties_add_button" onclick="whitelistAddWhitelistEntry()" class="hide-in-edit button button-primary" type="button" style="position:absolute; bottom:20px">
51
  Add
52
  </button>
6
  //echo '<script>window.whitelist = ' . json_encode($whitelist) . '</script>';
7
  ?>
8
  <tr id="share">
9
+ <th scope="row">Enable web service?<?php echo helpIcon(
10
+ 'Enabling the web service will allow selected sites to convert webp-images through this site (more options will appear, if you enable)'
11
+ ); ?></th>
12
  <td>
13
+ <input type="checkbox" id="web_service_enabled" name="web-service-enabled" value="true" <?php
14
+ echo ($config['web-service']['enabled'] ? 'checked="checked"' : '')
15
+ ?>>
16
  <input type='text' name='whitelist' id='whitelist' value='' style='visibility:hidden; height:0' />
17
  <div id="whitelist_div"></div>
18
  <div id="whitelist_properties_popup" class="das-popup">
46
  <div>
47
  <label for="whitelist_require_api_key_to_be_crypted_in_transfer">
48
  Require api-key to be crypted in transfer?
49
+ <?php echo helpIcon(
50
+ 'If checked, the web service will only accept crypted api keys. Crypting the api-key protects it from being ' .
51
+ 'stolen during transfer. On a few older server setups, clients do not have the capability to crypt');
52
+ ?>
53
  </label>
54
  <input id="whitelist_require_api_key_to_be_crypted_in_transfer" type="checkbox">
55
  </div>
56
+ <p style="margin-top: 15px">Psst: The endpoint of the web service is: <b><?php
57
+ echo esc_url(Paths::getWebServiceUrl())
58
+ ?></b></p>
59
  <button id="whitelist_properties_add_button" onclick="whitelistAddWhitelistEntry()" class="hide-in-edit button button-primary" type="button" style="position:absolute; bottom:20px">
60
  Add
61
  </button>
lib/options/page-messages.php CHANGED
@@ -55,94 +55,6 @@ DismissableMessages::printMessages();
55
  $firstActiveAndWorkingConverterId = ConvertersHelper::getFirstWorkingAndActiveConverterId($config);
56
  $workingIds = ConvertersHelper::getWorkingConverterIds($config);
57
 
58
- /*print_r($dismissableMessageIds);
59
-
60
- foreach ($dismissableMessageIds as $pageMessageId) {
61
- switch ($pageMessageId) {
62
- case 'suggest-enable-pngs':
63
- break;
64
- case 'suggest-wipe-because-lossless':
65
- // introduced in 0.14.0 (migrate 9)
66
-
67
- $convertersSupportingEncodingAuto = ['cwebp', 'vips', 'imagick', 'imagemagick', 'gmagick', 'graphicsmagick'];
68
-
69
- if (in_array($firstActiveAndWorkingConverterId, $convertersSupportingEncodingAuto)) {
70
- DismissableMessages::printDismissableMessage(
71
- 'info',
72
- '<p>WebP Express 0.14 has new options for the conversions. Especially, it can now produce lossless webps, and ' .
73
- 'it can automatically try both lossy and lossless and select the smallest. You can play around with the ' .
74
- 'new options when your click "test" next to a converter.</p>' .
75
- '<p>Once satisfied, dont forget to ' .
76
- 'wipe your existing converted files (there is a "Delete converted files" button for that here on this page).</p>',
77
- $pageMessageId,
78
- 'Got it!'
79
- );
80
- } else {
81
-
82
- if ($firstActiveAndWorkingConverterId == 'gd') {
83
- foreach ($workingIds as $workingId) {
84
- if (in_array($workingId, $convertersSupportingEncodingAuto)) {
85
- DismissableMessages::printDismissableMessage(
86
- 'info',
87
- '<p>WebP Express 0.14 has new options for the conversions. Especially, it can now produce lossless webps, and ' .
88
- 'it can automatically try both lossy and lossless and select the smallest. You can play around with the ' .
89
- 'new options when your click "test" next to a converter.</p>' .
90
- '<p>Once satisfied, dont forget to wipe your existing converted files (there is a "Delete converted files" ' .
91
- 'button for that here on this page)</p>' .
92
- '<p>Btw: The "gd" conversion method that you are using does not support lossless encoding ' .
93
- '(in fact Gd only supports very few conversion options), but fortunately, you have the ' .
94
- '"' . $workingId . '" conversion method working, so you can simply start using that instead.</p>',
95
- $pageMessageId,
96
- 'Got it!'
97
- );
98
- break;
99
- }
100
- }
101
- }
102
- }
103
- break;
104
- case 'say-hello-to-vips':
105
- if (in_array('vips', $workingIds)) {
106
- if ($firstActiveAndWorkingConverterId == 'cwebp') {
107
- DismissableMessages::printDismissableMessage(
108
- 'info',
109
- '<p>I have good news and good news. WebP Express now supports Vips and Vips is working on your server. ' .
110
- 'Vips is one of the best method for converting WebPs, on par with cwebp, which you are currently using. ' .
111
- 'You may want to use Vips instead of cwebp. Your choice.</p>',
112
- $pageMessageId,
113
- 'Got it!'
114
- );
115
- } else {
116
- DismissableMessages::printDismissableMessage(
117
- 'info',
118
- '<p>I have good news and good news. WebP Express now supports Vips and Vips is working on your server. ' .
119
- 'Vips is one of the best method for converting WebPs and has therefore been inserted at the top of the list.' .
120
- '</p>',
121
- $pageMessageId,
122
- 'Got it!'
123
- );
124
- }
125
- } else {
126
- // show message?
127
- }
128
- break;
129
- }
130
- }
131
- */
132
- /*
133
- if ($config['image-types'] == 1) {
134
- if (!in_array('suggest-enable-pngs', $dismissedPageMessageIds)) {
135
- Messenger::printMessage(
136
- 'info',
137
- 'WebP Express 0.14 handles PNG to WebP conversions quite well. Perhaps it is time to enable PNGs? ' .
138
- 'Go to the <a href="' . Paths::getSettingsUrl() . '">options</a> page to change the "Image types to work on" option.',
139
- 2,
140
- 'Got it!'
141
- );
142
- }
143
- }
144
- */
145
-
146
  if ($config['redirect-to-existing-in-htaccess']) {
147
  if (PlatformInfo::isApacheOrLiteSpeed() && isset($config['base-htaccess-on-these-capability-tests']['modHeaderWorking']) && ($config['base-htaccess-on-these-capability-tests']['modHeaderWorking'] == false)) {
148
  Messenger::printMessage(
@@ -179,7 +91,8 @@ if ($cacheEnablerActivated) {
179
  if ($cacheEnablerActivated && !$webpEnabled) {
180
  Messenger::printMessage(
181
  'warning',
182
- '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.'
 
183
  );
184
  }
185
 
@@ -191,7 +104,8 @@ if (($config['operation-mode'] == 'cdn-friendly') && !$config['alter-html']['ena
191
  Messenger::printMessage(
192
  'info',
193
  'You should consider enabling Alter HTML. This is not neccessary, as you have <i>Cache Enabler</i> enabled, which alters HTML. ' .
194
- '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)'
 
195
  );
196
  }
197
 
@@ -199,7 +113,8 @@ if (($config['operation-mode'] == 'cdn-friendly') && !$config['alter-html']['ena
199
  Messenger::printMessage(
200
  'warning',
201
  'You are in CDN friendly mode but have not enabled Alter HTML (and you are not using Cache Enabler either). ' .
202
- 'This is usually a misconfiguration because in this mode, the only way to get webp files delivered is by referencing them in the HTML.'
 
203
  );
204
 
205
  }
@@ -267,7 +182,8 @@ if (!Paths::createContentDirIfMissing()) {
267
  Messenger::printMessage(
268
  'error',
269
  'WebP Express needs to create a directory "webp-express" under your wp-content folder, but does not have permission to do so.<br>' .
270
- 'Please create the folder manually, or change the file permissions of your wp-content folder (failed to create this folder: ' . Paths::getWebPExpressContentDirAbs() . ')'
 
271
  );
272
  } else {
273
  if (!Paths::createConfigDirIfMissing()) {
@@ -292,13 +208,14 @@ if (Config::isConfigFileThere()) {
292
  Messenger::printMessage(
293
  'warning',
294
  'Warning: The configuration file is not ok! (cant be read, or not valid json).<br>' .
295
- 'file: "' . Paths::getConfigFileName() . '"'
296
  );
297
  } else {
298
  if (HTAccess::arePathsUsedInHTAccessOutdated()) {
299
  Messenger::printMessage(
300
  'warning',
301
- 'Warning: Wordpress paths have changed since the last time the Rewrite Rules was generated. The rules needs updating! (click <i>Save settings</i> to do so)<br>'
 
302
  );
303
  }
304
  }
55
  $firstActiveAndWorkingConverterId = ConvertersHelper::getFirstWorkingAndActiveConverterId($config);
56
  $workingIds = ConvertersHelper::getWorkingConverterIds($config);
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  if ($config['redirect-to-existing-in-htaccess']) {
59
  if (PlatformInfo::isApacheOrLiteSpeed() && isset($config['base-htaccess-on-these-capability-tests']['modHeaderWorking']) && ($config['base-htaccess-on-these-capability-tests']['modHeaderWorking'] == false)) {
60
  Messenger::printMessage(
91
  if ($cacheEnablerActivated && !$webpEnabled) {
92
  Messenger::printMessage(
93
  'warning',
94
+ 'You are using Cache Enabler, but have not enabled the webp option, so Cache Enabler is not operating with a separate cache ' .
95
+ 'for webp-enabled browsers.'
96
  );
97
  }
98
 
104
  Messenger::printMessage(
105
  'info',
106
  'You should consider enabling Alter HTML. This is not neccessary, as you have <i>Cache Enabler</i> enabled, which alters HTML. ' .
107
+ 'However, it is a good idea because currently <i>Cache Enabler</i> does not replace as many URLs as WebP Express (ie ' .
108
+ 'background images in inline styles)'
109
  );
110
  }
111
 
113
  Messenger::printMessage(
114
  'warning',
115
  'You are in CDN friendly mode but have not enabled Alter HTML (and you are not using Cache Enabler either). ' .
116
+ 'This is usually a misconfiguration because in this mode, the only way to get webp files delivered ' .
117
+ 'is by referencing them in the HTML.'
118
  );
119
 
120
  }
182
  Messenger::printMessage(
183
  'error',
184
  'WebP Express needs to create a directory "webp-express" under your wp-content folder, but does not have permission to do so.<br>' .
185
+ 'Please create the folder manually, or change the file permissions of your wp-content folder (failed to create this folder: ' .
186
+ esc_html(Paths::getWebPExpressContentDirAbs()) . ')'
187
  );
188
  } else {
189
  if (!Paths::createConfigDirIfMissing()) {
208
  Messenger::printMessage(
209
  'warning',
210
  'Warning: The configuration file is not ok! (cant be read, or not valid json).<br>' .
211
+ 'file: "' . esc_html(Paths::getConfigFileName()) . '"'
212
  );
213
  } else {
214
  if (HTAccess::arePathsUsedInHTAccessOutdated()) {
215
  Messenger::printMessage(
216
  'warning',
217
+ 'Warning: Wordpress paths have changed since the last time the Rewrite Rules was generated. The rules ' .
218
+ 'needs updating! (click <i>Save settings</i> to do so)<br>'
219
  );
220
  }
221
  }
lib/options/page.php CHANGED
@@ -134,19 +134,19 @@ function helpIcon($text, $customClass = '') {
134
 
135
  function webpexpress_selectBoxOptions($selected, $options) {
136
  foreach ($options as $optionValue => $text) {
137
- echo '<option value="' . $optionValue . '"' . ($optionValue == $selected ? ' selected' : '') . '>';
138
- echo $text;
139
  echo '</option>';
140
  }
141
  }
142
 
143
  function webpexpress_radioButton($optionName, $optionValue, $label, $selectedValue, $helpText = null) {
144
- $id = str_replace('-', '_', $optionName . '_' . $optionValue);
145
  echo '<input type="radio" id="' . $id . '"';
146
  if ($optionValue == $selectedValue) {
147
  echo ' checked="checked"';
148
  }
149
- echo ' name="' . $optionName . '" value="' . $optionValue . '" style="margin-right: 10px">';
150
  echo '<label for="' . $id . '">';
151
  echo $label;
152
  if (!is_null($helpText)) {
@@ -158,34 +158,18 @@ function webpexpress_radioButton($optionName, $optionValue, $label, $selectedVal
158
  function webpexpress_radioButtons($optionName, $selected, $options, $helpTexts = [], $style='margin-left: 20px; margin-top: 5px') {
159
  echo '<ul style="' . $style . '">';
160
  foreach ($options as $optionValue => $label) {
161
- $id = str_replace('-', '_', $optionName . '_' . $optionValue);
162
  echo '<li>';
163
-
164
  webpexpress_radioButton($optionName, $optionValue, $label, $selected, isset($helpTexts[$optionValue]) ? $helpTexts[$optionValue] : null);
165
-
166
- /*
167
- echo '<input type="radio" id="' . $id . '"';
168
- if ($optionValue == $selected) {
169
- echo ' checked="checked"';
170
- }
171
- echo ' name="' . $optionName . '" value="' . $optionValue . '" style="margin-right: 10px">';
172
- echo '<label for="' . $id . '">';
173
- echo $text;
174
- if (isset($helpTexts[$optionValue])) {
175
- echo helpIcon($helpTexts[$optionValue]);
176
- }
177
- echo '</label>';
178
- */
179
  echo '</li>';
180
  }
181
  echo '</ul>';
182
  }
183
 
184
  function webpexpress_checkbox($optionName, $checked, $label, $helpText = '') {
185
- $id = str_replace('-', '_', $optionName);
186
  echo '<div style="margin:10px 0 0 10px;">';
187
  echo '<input value="true" type="checkbox" style="margin-right: 10px" ';
188
- echo 'name="' . $optionName . '"';
189
  echo 'id="' . $id . '"';
190
  if ($checked) {
191
  echo ' checked="checked"';
134
 
135
  function webpexpress_selectBoxOptions($selected, $options) {
136
  foreach ($options as $optionValue => $text) {
137
+ echo '<option value="' . esc_attr($optionValue) . '"' . ($optionValue == $selected ? ' selected' : '') . '>';
138
+ echo esc_html($text);
139
  echo '</option>';
140
  }
141
  }
142
 
143
  function webpexpress_radioButton($optionName, $optionValue, $label, $selectedValue, $helpText = null) {
144
+ $id = esc_attr(str_replace('-', '_', $optionName . '_' . $optionValue));
145
  echo '<input type="radio" id="' . $id . '"';
146
  if ($optionValue == $selectedValue) {
147
  echo ' checked="checked"';
148
  }
149
+ echo ' name="' . esc_attr($optionName) . '" value="' . esc_attr($optionValue) . '" style="margin-right: 10px">';
150
  echo '<label for="' . $id . '">';
151
  echo $label;
152
  if (!is_null($helpText)) {
158
  function webpexpress_radioButtons($optionName, $selected, $options, $helpTexts = [], $style='margin-left: 20px; margin-top: 5px') {
159
  echo '<ul style="' . $style . '">';
160
  foreach ($options as $optionValue => $label) {
 
161
  echo '<li>';
 
162
  webpexpress_radioButton($optionName, $optionValue, $label, $selected, isset($helpTexts[$optionValue]) ? $helpTexts[$optionValue] : null);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  echo '</li>';
164
  }
165
  echo '</ul>';
166
  }
167
 
168
  function webpexpress_checkbox($optionName, $checked, $label, $helpText = '') {
169
+ $id = esc_attr(str_replace('-', '_', $optionName));
170
  echo '<div style="margin:10px 0 0 10px;">';
171
  echo '<input value="true" type="checkbox" style="margin-right: 10px" ';
172
+ echo 'name="' . esc_attr($optionName) . '"';
173
  echo 'id="' . $id . '"';
174
  if ($checked) {
175
  echo ' checked="checked"';
lib/options/submit.php CHANGED
@@ -5,18 +5,23 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
5
  use \WebPExpress\CacheMover;
6
  use \WebPExpress\CapabilityTest;
7
  use \WebPExpress\Config;
 
8
  use \WebPExpress\DismissableMessages;
9
  use \WebPExpress\HTAccess;
10
  use \WebPExpress\Messenger;
11
  use \WebPExpress\Paths;
12
 
 
13
  check_admin_referer('webpexpress-save-settings-nonce');
14
 
15
  DismissableMessages::dismissMessage('0.14.0/say-hello-to-vips');
16
 
17
 
18
- // https://premium.wpmudev.org/blog/handling-form-submissions/
19
- // checkout https://codex.wordpress.org/Function_Reference/sanitize_meta
 
 
 
20
 
21
  /**
22
  * Get sanitized text (NUL removed too)
@@ -78,9 +83,9 @@ function webpexpress_getSanitizedCacheControlHeader($keyInPOST) {
78
  * Get sanitized integer
79
  *
80
  * @param string $keyInPOST key in $_POST
81
- * @param int $fallback key in $_POST
82
  *
83
- * @return int the sanitized number.
84
  */
85
  function webpexpress_getSanitizedInt($keyInPOST, $fallback=0) {
86
  $value = webpexpress_getSanitizedText($keyInPOST, strval($fallback));
@@ -115,9 +120,7 @@ function webpexpress_getSanitizedQuality($keyInPOST, $fallback = 75) {
115
  /**
116
  * Get sanitized whitelist
117
  *
118
- * @param string $keyInPOST key in $_POST
119
- *
120
- * @return int quality (0-100)
121
  */
122
  function webpexpress_getSanitizedWhitelist() {
123
  $whitelistPosted = (isset($_POST['whitelist']) ? $_POST['whitelist'] : '[]');
@@ -154,15 +157,133 @@ function webpexpress_getSanitizedWhitelist() {
154
  return $whitelistSanitized;
155
  }
156
 
157
- // ---------------
158
- $config = Config::loadConfigAndFix(false); // false, because we do not need to test if quality detection is working
159
- $oldConfig = $config;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
 
 
 
 
 
 
 
 
 
161
 
162
 
163
  // Sanitizing
164
  $sanitized = [
165
- // General
 
 
 
 
 
166
  // Note that "operation-mode" is actually the old mode. The new mode is posted in "change-operation-mode"
167
  'operation-mode' => webpexpress_getSanitizedChooseFromSet('operation-mode', 'varied-image-responses', [
168
  'varied-image-responses',
@@ -170,11 +291,29 @@ $sanitized = [
170
  'no-conversion',
171
  'tweaked'
172
  ]),
 
 
 
 
 
 
 
 
 
 
173
  'image-types' => intval(webpexpress_getSanitizedChooseFromSet('image-types', '3', [
174
  '0',
175
  '1',
176
  '3'
177
  ])),
 
 
 
 
 
 
 
 
178
  'cache-control' => webpexpress_getSanitizedChooseFromSet('cache-control', 'no-header', [
179
  'no-header',
180
  'set',
@@ -194,22 +333,18 @@ $sanitized = [
194
  ]),
195
  'cache-control-custom' => webpexpress_getSanitizedCacheControlHeader('cache-control-custom'),
196
 
197
- // Alter html
198
- 'alter-html-enabled' => isset($_POST['alter-html-enabled']),
199
- 'alter-html-only-for-webp-enabled-browsers' => isset($_POST['alter-html-only-for-webp-enabled-browsers']),
200
- 'alter-html-add-picturefill-js' => isset($_POST['alter-html-add-picturefill-js']),
201
- 'alter-html-for-webps-that-has-yet-to-exist' => isset($_POST['alter-html-for-webps-that-has-yet-to-exist']),
202
- 'alter-html-replacement' => webpexpress_getSanitizedChooseFromSet('alter-html-replacement', 'picture', [
203
- 'picture',
204
- 'url'
205
- ]),
206
- 'alter-html-hooks' => webpexpress_getSanitizedChooseFromSet('alter-html-hooks', 'content-hooks', [
207
- 'content-hooks',
208
- 'ob'
209
- ]),
210
- 'enable-redirection-to-webp-realizer' => isset($_POST['enable-redirection-to-webp-realizer']),
211
 
212
  // Conversion options
 
213
  'metadata' => webpexpress_getSanitizedChooseFromSet('metadata', 'none', [
214
  'none',
215
  'all'
@@ -241,9 +376,60 @@ $sanitized = [
241
  'auto'
242
  ]),
243
  'alpha-quality' => webpexpress_getSanitizedQuality('png-quality', 80),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  'whitelist' => webpexpress_getSanitizedWhitelist(),
 
245
  ];
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  // Set options that are available in all operation modes
248
  $config = array_merge($config, [
249
  'operation-mode' => $sanitized['operation-mode'],
@@ -293,7 +479,7 @@ $config['alter-html']['hooks'] = $sanitized['alter-html-hooks'];
293
 
294
 
295
  // Set options that are available in all operation modes, except the "no-conversion" mode
296
- if ($_POST['operation-mode'] != 'no-conversion') {
297
 
298
  $config['enable-redirection-to-webp-realizer'] = $sanitized['enable-redirection-to-webp-realizer'];
299
 
@@ -327,25 +513,15 @@ if ($_POST['operation-mode'] != 'no-conversion') {
327
  $config['png-near-lossless'] = $sanitized['png-near-lossless'];
328
  $config['alpha-quality'] = $sanitized['alpha-quality'];
329
 
330
- // Other
331
- $config['convert-on-upload'] = isset($_POST['convert-on-upload']);
332
 
333
 
334
  // Web Service
335
  // -------------
336
 
337
- /*
338
- $whitelistPosted = json_decode(wp_unslash($_POST['whitelist']), true);
339
-
340
- // Sanitize whitelist
341
- foreach ($whitelistPosted as &$whitelist) {
342
- $whitelist['label'] = sanitize_text_field($whitelist['label']);
343
- $whitelist['ip'] = sanitize_text_field($whitelist['ip']);
344
- $whitelist['api-key'] = sanitize_text_field($whitelist['api-key']);
345
- }*/
346
-
347
  $config['web-service'] = [
348
- 'enabled' => isset($_POST['web-service-enabled']),
349
  'whitelist' => $sanitized['whitelist']
350
  ];
351
 
@@ -360,7 +536,7 @@ if ($_POST['operation-mode'] != 'no-conversion') {
360
  }
361
  }
362
 
363
- // Set new api keys in web service
364
  foreach ($config['web-service']['whitelist'] as &$whitelistEntry) {
365
  if (!empty($whitelistEntry['new-api-key'])) {
366
  $whitelistEntry['api-key'] = $whitelistEntry['new-api-key'];
@@ -370,20 +546,8 @@ if ($_POST['operation-mode'] != 'no-conversion') {
370
 
371
  // Converters
372
  // -------------
373
- $convertersPosted = json_decode(wp_unslash($_POST['converters']), true); // holy moly! - https://stackoverflow.com/questions/2496455/why-are-post-variables-getting-escaped-in-php
374
-
375
- // Sanitize converters
376
- foreach ($convertersPosted as &$converter) {
377
- if (!isset($converter['options'])) continue;
378
- foreach ($converter['options'] as $optionName => $optionValue) {
379
- if (gettype($optionValue) == 'string') {
380
- $converter['options'][$optionName] = sanitize_text_field($optionValue);
381
- }
382
- }
383
- }
384
-
385
 
386
- $config['converters'] = $convertersPosted;
387
 
388
  // remove converter ids
389
  foreach ($config['converters'] as &$converter) {
@@ -416,47 +580,46 @@ if ($_POST['operation-mode'] != 'no-conversion') {
416
  }
417
 
418
 
419
- switch ($_POST['operation-mode']) {
420
  case 'varied-image-responses':
421
  $config = array_merge($config, [
422
- 'redirect-to-existing-in-htaccess' => isset($_POST['redirect-to-existing-in-htaccess']),
423
- 'destination-folder' => $_POST['destination-folder'],
424
- 'destination-extension' => (($_POST['destination-folder'] == 'mingled') ? $_POST['destination-extension'] : 'append'),
425
  ]);
426
  break;
427
  case 'cdn-friendly':
428
  $config = array_merge($config, [
429
- 'destination-folder' => sanitize_text_field($_POST['destination-folder']),
430
- 'destination-extension' => (($_POST['destination-folder'] == 'mingled') ? sanitize_text_field($_POST['destination-extension']) : 'append'),
431
- 'enable-redirection-to-converter' => isset($_POST['enable-redirection-to-converter']), // PS: its called "autoconvert" in this mode
432
  ]);
433
  break;
434
  case 'no-conversion':
435
  $config = array_merge($config, [
436
- 'redirect-to-existing-in-htaccess' => isset($_POST['redirect-to-existing-in-htaccess']),
437
- 'destination-extension' => sanitize_text_field($_POST['destination-extension']),
438
  ]);
439
  break;
440
  case 'tweaked':
441
  $config = array_merge($config, [
442
- 'enable-redirection-to-converter' => isset($_POST['enable-redirection-to-converter']),
443
- 'only-redirect-to-converter-for-webp-enabled-browsers' => isset($_POST['only-redirect-to-converter-for-webp-enabled-browsers']),
444
- 'only-redirect-to-converter-on-cache-miss' => isset($_POST['only-redirect-to-converter-on-cache-miss']),
445
- 'do-not-pass-source-in-query-string' => isset($_POST['do-not-pass-source-in-query-string']),
446
- 'redirect-to-existing-in-htaccess' => isset($_POST['redirect-to-existing-in-htaccess']),
447
- 'destination-folder' => sanitize_text_field($_POST['destination-folder']),
448
- 'destination-extension' => (($_POST['destination-folder'] == 'mingled') ? sanitize_text_field($_POST['destination-extension']) : 'append'),
449
- 'fail' => sanitize_text_field($_POST['fail']),
450
- 'success-response' => sanitize_text_field($_POST['success-response']),
451
  ]);
452
  break;
453
  }
454
 
455
- //echo '<pre>' . print_r($_POST, true) . '</pre>'; exit;
456
- if ($_POST['operation-mode'] != $_POST['change-operation-mode']) {
457
 
458
  // Operation mode changed!
459
- $config['operation-mode'] = sanitize_text_field($_POST['change-operation-mode']);
460
  $config = Config::applyOperationMode($config);
461
 
462
  if ($config['operation-mode'] == 'varied-image-responses') {
@@ -467,14 +630,14 @@ if ($_POST['operation-mode'] != $_POST['change-operation-mode']) {
467
  }
468
 
469
  // If we are going to save .htaccess, run and store capability tests first (we should only store results when .htaccess is updated as well)
470
- if (isset($_POST['force']) || HTAccess::doesRewriteRulesNeedUpdate($config)) {
471
  Config::runAndStoreCapabilityTests($config);
472
  }
473
 
474
 
475
  // SAVE!
476
  // -----
477
- $result = Config::saveConfigurationAndHTAccess($config, isset($_POST['force']));
478
 
479
  // Handle results
480
  // ---------------
5
  use \WebPExpress\CacheMover;
6
  use \WebPExpress\CapabilityTest;
7
  use \WebPExpress\Config;
8
+ use \WebPExpress\ConvertersHelper;
9
  use \WebPExpress\DismissableMessages;
10
  use \WebPExpress\HTAccess;
11
  use \WebPExpress\Messenger;
12
  use \WebPExpress\Paths;
13
 
14
+
15
  check_admin_referer('webpexpress-save-settings-nonce');
16
 
17
  DismissableMessages::dismissMessage('0.14.0/say-hello-to-vips');
18
 
19
 
20
+ /*
21
+ --------------------------------
22
+ Custom functions for sanitizing
23
+ --------------------------------
24
+ */
25
 
26
  /**
27
  * Get sanitized text (NUL removed too)
83
  * Get sanitized integer
84
  *
85
  * @param string $keyInPOST key in $_POST
86
+ * @param int $fallback fallback in case nothing in POST or if we cannot parse it as int
87
  *
88
+ * @return int the sanitized int value.
89
  */
90
  function webpexpress_getSanitizedInt($keyInPOST, $fallback=0) {
91
  $value = webpexpress_getSanitizedText($keyInPOST, strval($fallback));
120
  /**
121
  * Get sanitized whitelist
122
  *
123
+ * @return array Sanitized array of the whitelist json array received in $_POST
 
 
124
  */
125
  function webpexpress_getSanitizedWhitelist() {
126
  $whitelistPosted = (isset($_POST['whitelist']) ? $_POST['whitelist'] : '[]');
157
  return $whitelistSanitized;
158
  }
159
 
160
+ /**
161
+ * Get sanitized converters.
162
+ *
163
+ * @return array Sanitized array of the converters json array received in $_POST
164
+ */
165
+ function webpexpress_getSanitizedConverters() {
166
+ $convertersPosted = (isset($_POST['converters']) ? $_POST['converters'] : '[]');
167
+ $convertersPosted = json_decode(wp_unslash($convertersPosted), true); // holy moly! - https://stackoverflow.com/questions/2496455/why-are-post-variables-getting-escaped-in-php
168
+
169
+ $convertersSanitized = [];
170
+
171
+ // Get list of possible converter ids.
172
+ $availableConverterIDs = [];
173
+ foreach (ConvertersHelper::$defaultConverters as $converter) {
174
+ $availableConverterIDs[] = $converter['converter'];
175
+ }
176
+
177
+ // Add converters one at the time.
178
+ foreach ($convertersPosted as $unsanitizedConverter) {
179
+ if (!isset($unsanitizedConverter['converter'])) {
180
+ continue;
181
+ }
182
+
183
+ // Only add converter if its ID is a known converter.
184
+ if (!in_array($unsanitizedConverter['converter'], $availableConverterIDs)) {
185
+ continue;
186
+ }
187
+
188
+ $sanitizedConverter = [];
189
+ $sanitizedConverter['converter'] = $unsanitizedConverter['converter'];
190
+
191
+ // Sanitize and add expected fields ("options", "working", "deactivated" and "error")
192
+
193
+ // "options"
194
+ if (isset($unsanitizedConverter['options'])) {
195
+ $sanitizedConverter['options'] = [];
196
+
197
+ // Sanitize all (string) options individually
198
+ foreach ($unsanitizedConverter['options'] as $optionName => $unsanitizedOptionValue) {
199
+
200
+ $acceptedOptions = [
201
+ // vips
202
+ 'smart-subsample' => 'boolean',
203
+ 'preset' => 'string',
204
+
205
+ // gd
206
+ 'skip-pngs' => 'boolean',
207
+
208
+ // in multiple
209
+ "use-nice" => 'boolean',
210
+
211
+ // cwebp
212
+ "try-common-system-paths" => 'boolean',
213
+ "try-supplied-binary-for-os" => 'boolean',
214
+ "method" => 'string', // 0-6, // TODO: make a migration so we use integer instead
215
+ "size-in-percentage" => 'string',
216
+ "low-memory" => 'boolean',
217
+ "command-line-options" => 'string', // webp-convert takes care of sanitizing this very carefully!
218
+ "set-size" => 'boolean',
219
+
220
+ // wpc
221
+ "api-url" => 'string',
222
+ "api-version" => 'integer',
223
+ "crypt-api-key-in-transfer" => 'boolean',
224
+ "api-key" => 'string',
225
+ ];
226
+
227
+ // check that it is an accepted option name
228
+ if (!isset($acceptedOptions[$optionName])) {
229
+ continue;
230
+ }
231
+
232
+ // check that type is as expected
233
+ $expectedType = $acceptedOptions[$optionName];
234
+ if (gettype($unsanitizedOptionValue) != $expectedType) {
235
+ continue;
236
+ }
237
+ if ($expectedType == 'string') {
238
+ $sanitizedOptionValue = sanitize_text_field($unsanitizedOptionValue);
239
+ } else {
240
+ // integer and boolean are completely safe!
241
+ $sanitizedOptionValue = $unsanitizedOptionValue;
242
+ }
243
+ if (($optionName == "size-in-percentage") && ($sanitizedOptionValue == '')) {
244
+ continue;
245
+ }
246
+ $sanitizedConverter['options'][$optionName] = $sanitizedOptionValue;
247
+
248
+ }
249
+ }
250
+
251
+ // "working" (bool)
252
+ if (isset($unsanitizedConverter['working'])) {
253
+ $sanitizedConverter['working'] = ($unsanitizedConverter['working'] === true);
254
+ }
255
+
256
+ // "deactivated" (bool)
257
+ if (isset($unsanitizedConverter['deactivated'])) {
258
+ $sanitizedConverter['deactivated'] = ($unsanitizedConverter['deactivated'] === true);
259
+ }
260
+
261
+ $convertersSanitized[] = $sanitizedConverter;
262
+ }
263
+
264
+ return $convertersSanitized;
265
+ }
266
+
267
 
268
+ /*
269
+ ------------------------------------------------------
270
+
271
+ Create a sanitized object from the POST data
272
+ It reflects the POST data - it has same keys and values - except that the values have been sanitized.
273
+
274
+ After this, there must be no more references to $_POST
275
+ ------------------------------------------------------
276
+ */
277
 
278
 
279
  // Sanitizing
280
  $sanitized = [
281
+ // Force htaccess rules
282
+ 'force' => isset($_POST['force']),
283
+
284
+
285
+ // Operation mode
286
+ // --------------
287
  // Note that "operation-mode" is actually the old mode. The new mode is posted in "change-operation-mode"
288
  'operation-mode' => webpexpress_getSanitizedChooseFromSet('operation-mode', 'varied-image-responses', [
289
  'varied-image-responses',
291
  'no-conversion',
292
  'tweaked'
293
  ]),
294
+ 'change-operation-mode' => webpexpress_getSanitizedChooseFromSet('change-operation-mode', 'varied-image-responses', [
295
+ 'varied-image-responses',
296
+ 'cdn-friendly',
297
+ 'no-conversion',
298
+ 'tweaked'
299
+ ]),
300
+
301
+
302
+ // General
303
+ // --------
304
  'image-types' => intval(webpexpress_getSanitizedChooseFromSet('image-types', '3', [
305
  '0',
306
  '1',
307
  '3'
308
  ])),
309
+ 'destination-folder' => webpexpress_getSanitizedChooseFromSet('destination-folder', 'separate', [
310
+ 'separate',
311
+ 'mingled',
312
+ ]),
313
+ 'destination-extension' => webpexpress_getSanitizedChooseFromSet('destination-extension', 'append', [
314
+ 'append',
315
+ 'set',
316
+ ]),
317
  'cache-control' => webpexpress_getSanitizedChooseFromSet('cache-control', 'no-header', [
318
  'no-header',
319
  'set',
333
  ]),
334
  'cache-control-custom' => webpexpress_getSanitizedCacheControlHeader('cache-control-custom'),
335
 
336
+
337
+ // Redirection rules
338
+ // -----------------
339
+ 'redirect-to-existing-in-htaccess' => isset($_POST['redirect-to-existing-in-htaccess']),
340
+ 'enable-redirection-to-converter' => isset($_POST['enable-redirection-to-converter']),
341
+ 'only-redirect-to-converter-for-webp-enabled-browsers' => isset($_POST['only-redirect-to-converter-for-webp-enabled-browsers']),
342
+ 'only-redirect-to-converter-on-cache-miss' => isset($_POST['only-redirect-to-converter-on-cache-miss']),
343
+ 'do-not-pass-source-in-query-string' => isset($_POST['do-not-pass-source-in-query-string']),
344
+
 
 
 
 
 
345
 
346
  // Conversion options
347
+ // ------------------
348
  'metadata' => webpexpress_getSanitizedChooseFromSet('metadata', 'none', [
349
  'none',
350
  'all'
376
  'auto'
377
  ]),
378
  'alpha-quality' => webpexpress_getSanitizedQuality('png-quality', 80),
379
+ 'convert-on-upload' => isset($_POST['convert-on-upload']),
380
+ 'converters' => webpexpress_getSanitizedConverters(),
381
+
382
+
383
+ // Serve options
384
+ // ---------------
385
+ 'fail' => webpexpress_getSanitizedChooseFromSet('fail', 'original', [
386
+ 'original',
387
+ '404',
388
+ 'report'
389
+ ]),
390
+ 'success-response' => webpexpress_getSanitizedChooseFromSet('success-response', 'original', [
391
+ 'original',
392
+ 'converted',
393
+ ]),
394
+
395
+
396
+ // Alter html
397
+ // ----------
398
+ 'alter-html-enabled' => isset($_POST['alter-html-enabled']),
399
+ 'alter-html-only-for-webp-enabled-browsers' => isset($_POST['alter-html-only-for-webp-enabled-browsers']),
400
+ 'alter-html-add-picturefill-js' => isset($_POST['alter-html-add-picturefill-js']),
401
+ 'alter-html-for-webps-that-has-yet-to-exist' => isset($_POST['alter-html-for-webps-that-has-yet-to-exist']),
402
+ 'alter-html-replacement' => webpexpress_getSanitizedChooseFromSet('alter-html-replacement', 'picture', [
403
+ 'picture',
404
+ 'url'
405
+ ]),
406
+ 'alter-html-hooks' => webpexpress_getSanitizedChooseFromSet('alter-html-hooks', 'content-hooks', [
407
+ 'content-hooks',
408
+ 'ob'
409
+ ]),
410
+ 'enable-redirection-to-webp-realizer' => isset($_POST['enable-redirection-to-webp-realizer']),
411
+
412
+
413
+ // Web service
414
+ // ------------
415
+ 'web-service-enabled' => isset($_POST['web-service-enabled']),
416
  'whitelist' => webpexpress_getSanitizedWhitelist(),
417
+
418
  ];
419
 
420
+
421
+ /*
422
+ ------------------------------------------------------
423
+
424
+ Lets begin working on the data.
425
+ Remember: Use $sanitized instead of $_POST
426
+
427
+ ------------------------------------------------------
428
+ */
429
+
430
+ $config = Config::loadConfigAndFix(false); // false, because we do not need to test if quality detection is working
431
+ $oldConfig = $config;
432
+
433
  // Set options that are available in all operation modes
434
  $config = array_merge($config, [
435
  'operation-mode' => $sanitized['operation-mode'],
479
 
480
 
481
  // Set options that are available in all operation modes, except the "no-conversion" mode
482
+ if ($sanitized['operation-mode'] != 'no-conversion') {
483
 
484
  $config['enable-redirection-to-webp-realizer'] = $sanitized['enable-redirection-to-webp-realizer'];
485
 
513
  $config['png-near-lossless'] = $sanitized['png-near-lossless'];
514
  $config['alpha-quality'] = $sanitized['alpha-quality'];
515
 
516
+ // Other conversion options
517
+ $config['convert-on-upload'] = $sanitized['convert-on-upload'];
518
 
519
 
520
  // Web Service
521
  // -------------
522
 
 
 
 
 
 
 
 
 
 
 
523
  $config['web-service'] = [
524
+ 'enabled' => $sanitized['web-service-enabled'],
525
  'whitelist' => $sanitized['whitelist']
526
  ];
527
 
536
  }
537
  }
538
 
539
+ // Set changed api keys
540
  foreach ($config['web-service']['whitelist'] as &$whitelistEntry) {
541
  if (!empty($whitelistEntry['new-api-key'])) {
542
  $whitelistEntry['api-key'] = $whitelistEntry['new-api-key'];
546
 
547
  // Converters
548
  // -------------
 
 
 
 
 
 
 
 
 
 
 
 
549
 
550
+ $config['converters'] = $sanitized['converters'];
551
 
552
  // remove converter ids
553
  foreach ($config['converters'] as &$converter) {
580
  }
581
 
582
 
583
+ switch ($sanitized['operation-mode']) {
584
  case 'varied-image-responses':
585
  $config = array_merge($config, [
586
+ 'redirect-to-existing-in-htaccess' => $sanitized['redirect-to-existing-in-htaccess'],
587
+ 'destination-folder' => $sanitized['destination-folder'],
588
+ 'destination-extension' => (($sanitized['destination-folder'] == 'mingled') ? $sanitized['destination-extension'] : 'append'),
589
  ]);
590
  break;
591
  case 'cdn-friendly':
592
  $config = array_merge($config, [
593
+ 'destination-folder' => $sanitized['destination-folder'],
594
+ 'destination-extension' => (($sanitized['destination-folder'] == 'mingled') ? $sanitized['destination-extension'] : 'append'),
595
+ 'enable-redirection-to-converter' => $sanitized['enable-redirection-to-converter'], // PS: its called "autoconvert" in this mode
596
  ]);
597
  break;
598
  case 'no-conversion':
599
  $config = array_merge($config, [
600
+ 'redirect-to-existing-in-htaccess' => $sanitized['redirect-to-existing-in-htaccess'],
601
+ 'destination-extension' => $sanitized['destination-extension'],
602
  ]);
603
  break;
604
  case 'tweaked':
605
  $config = array_merge($config, [
606
+ 'enable-redirection-to-converter' => $sanitized['enable-redirection-to-converter'],
607
+ 'only-redirect-to-converter-for-webp-enabled-browsers' => $sanitized['only-redirect-to-converter-for-webp-enabled-browsers'],
608
+ 'only-redirect-to-converter-on-cache-miss' => $sanitized['only-redirect-to-converter-on-cache-miss'],
609
+ 'do-not-pass-source-in-query-string' => $sanitized['do-not-pass-source-in-query-string'],
610
+ 'redirect-to-existing-in-htaccess' => $sanitized['redirect-to-existing-in-htaccess'],
611
+ 'destination-folder' => $sanitized['destination-folder'],
612
+ 'destination-extension' => (($sanitized['destination-folder'] == 'mingled') ? $sanitized['destination-extension'] : 'append'),
613
+ 'fail' => $sanitized['fail'],
614
+ 'success-response' => $sanitized['success-response'],
615
  ]);
616
  break;
617
  }
618
 
619
+ if ($sanitized['operation-mode'] != $sanitized['change-operation-mode']) {
 
620
 
621
  // Operation mode changed!
622
+ $config['operation-mode'] = $sanitized['change-operation-mode'];
623
  $config = Config::applyOperationMode($config);
624
 
625
  if ($config['operation-mode'] == 'varied-image-responses') {
630
  }
631
 
632
  // If we are going to save .htaccess, run and store capability tests first (we should only store results when .htaccess is updated as well)
633
+ if ($sanitized['force'] || HTAccess::doesRewriteRulesNeedUpdate($config)) {
634
  Config::runAndStoreCapabilityTests($config);
635
  }
636
 
637
 
638
  // SAVE!
639
  // -----
640
+ $result = Config::saveConfigurationAndHTAccess($config, $sanitized['force']);
641
 
642
  // Handle results
643
  // ---------------
vendor/composer/installed.json CHANGED
@@ -115,17 +115,17 @@
115
  },
116
  {
117
  "name": "rosell-dk/webp-convert",
118
- "version": "2.1.0",
119
- "version_normalized": "2.1.0.0",
120
  "source": {
121
  "type": "git",
122
  "url": "https://github.com/rosell-dk/webp-convert.git",
123
- "reference": "b142cfc2b2b8a1930b3b394c40f0923871ef2abd"
124
  },
125
  "dist": {
126
  "type": "zip",
127
- "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/b142cfc2b2b8a1930b3b394c40f0923871ef2abd",
128
- "reference": "b142cfc2b2b8a1930b3b394c40f0923871ef2abd",
129
  "shasum": ""
130
  },
131
  "require": {
@@ -143,7 +143,7 @@
143
  "ext-vips": "to use Vips extension for converting.",
144
  "php-stan/php-stan": "Suggested for dev, in order to analyse code before committing"
145
  },
146
- "time": "2019-06-20T12:12:13+00:00",
147
  "type": "library",
148
  "extra": {
149
  "scripts-descriptions": {
115
  },
116
  {
117
  "name": "rosell-dk/webp-convert",
118
+ "version": "2.1.1",
119
+ "version_normalized": "2.1.1.0",
120
  "source": {
121
  "type": "git",
122
  "url": "https://github.com/rosell-dk/webp-convert.git",
123
+ "reference": "cc0ceb81193a0b930b2e7c58886a7f3662fb45c6"
124
  },
125
  "dist": {
126
  "type": "zip",
127
+ "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/cc0ceb81193a0b930b2e7c58886a7f3662fb45c6",
128
+ "reference": "cc0ceb81193a0b930b2e7c58886a7f3662fb45c6",
129
  "shasum": ""
130
  },
131
  "require": {
143
  "ext-vips": "to use Vips extension for converting.",
144
  "php-stan/php-stan": "Suggested for dev, in order to analyse code before committing"
145
  },
146
+ "time": "2019-06-21T11:15:37+00:00",
147
  "type": "library",
148
  "extra": {
149
  "scripts-descriptions": {
vendor/rosell-dk/webp-convert/src/Convert/Converters/AbstractConverter.php CHANGED
@@ -117,7 +117,7 @@ abstract class AbstractConverter
117
  $this->setProvidedOptions($options);
118
 
119
  if (!isset($this->options['_skip_input_check'])) {
120
- $this->log('WebP Convert 2.0.5', 'italic');
121
  $this->logLn(' ignited.');
122
  $this->logLn('- PHP version: ' . phpversion());
123
  if (isset($_SERVER['SERVER_SOFTWARE'])) {
117
  $this->setProvidedOptions($options);
118
 
119
  if (!isset($this->options['_skip_input_check'])) {
120
+ $this->log('WebP Convert 2.1.1', 'italic');
121
  $this->logLn(' ignited.');
122
  $this->logLn('- PHP version: ' . phpversion());
123
  if (isset($_SERVER['SERVER_SOFTWARE'])) {
vendor/rosell-dk/webp-convert/src/Convert/Converters/Cwebp.php CHANGED
@@ -124,6 +124,14 @@ class Cwebp extends AbstractConverter
124
  */
125
  private static function escapeShellArgOnCommandLineOptions($commandLineOptions)
126
  {
 
 
 
 
 
 
 
 
127
  $cmdOptions = [];
128
  $arr = explode(' -', ' ' . $commandLineOptions);
129
  foreach ($arr as $cmdOption) {
124
  */
125
  private static function escapeShellArgOnCommandLineOptions($commandLineOptions)
126
  {
127
+ if (!ctype_print($commandLineOptions)) {
128
+ throw new ConversionFailedException('Non-printable characters are not allowed in the extra command line options');
129
+ }
130
+
131
+ if (preg_match('#[^a-zA-Z0-9_\s\-]#', $commandLineOptions)) {
132
+ throw new ConversionFailedException('The extra command line options contains inacceptable characters');
133
+ }
134
+
135
  $cmdOptions = [];
136
  $arr = explode(' -', ' ' . $commandLineOptions);
137
  foreach ($arr as $cmdOption) {
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.14.7
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.14.8
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2