WebP Express - Version 0.17.0

Version Description

(released: 27 sep 2019)

  • Cwebp conversion method runs on more systems (not subject to open_basedir restrictions and also tries "pure" cwebp command). Thanks to cng11 for reaching out so I spotted this.
  • Ewww conversion method no longer does a remote api-key check for each conversion - so it is faster. If an ewww conversions fails due to a non-functional key, the key will not be tried again (until next time the options are saved)
  • Updated cwebp binaries to version 1.0.3
Download this release

Release Info

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

Code changes from version 0.16.0 to 0.17.0

Files changed (33) hide show
  1. README.md +7 -1
  2. README.txt +11 -1
  3. changelog.txt +7 -0
  4. composer.lock +9 -9
  5. docs/development.md +1 -1
  6. lib/classes/Config.php +8 -79
  7. lib/classes/Convert.php +16 -0
  8. lib/classes/ConvertHelperIndependent.php +3 -1
  9. lib/classes/EwwwTools.php +113 -0
  10. lib/classes/FileHelper.php +29 -0
  11. lib/classes/PluginActivate.php +2 -1
  12. lib/classes/SelfTestHelper.php +1 -1
  13. lib/classes/WebPOnDemand.php +2 -0
  14. lib/classes/WebPRealizer.php +1 -0
  15. lib/classes/WodConfigLoader.php +17 -0
  16. lib/options/page-welcome.php +3 -3
  17. vendor/composer/installed.json +10 -10
  18. vendor/rosell-dk/webp-convert/composer.json +0 -2
  19. vendor/rosell-dk/webp-convert/src/Convert/Converters/AbstractConverter.php +1 -1
  20. vendor/rosell-dk/webp-convert/src/Convert/Converters/BaseTraits/WarningLoggerTrait.php +16 -1
  21. vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-fbsd → cwebp-0.6.0-fbsd} +0 -0
  22. vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-sol → cwebp-0.6.0-solaris} +0 -0
  23. vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-linux-0.6.1 → cwebp-0.6.1-linux-x86-64} +0 -0
  24. vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-linux-1.0.2-shared → cwebp-1.0.3-linux-x86-64} +0 -0
  25. vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-linux-1.0.2-static → cwebp-1.0.3-linux-x86-64-static} +0 -0
  26. vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/cwebp-1.0.3-mac-10.14 +0 -0
  27. vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/cwebp-1.0.3-windows-x64.exe +0 -0
  28. vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/cwebp-mac12 +0 -0
  29. vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/cwebp.exe +0 -0
  30. vendor/rosell-dk/webp-convert/src/Convert/Converters/Cwebp.php +176 -112
  31. vendor/rosell-dk/webp-convert/src/Convert/Converters/Ewww.php +44 -40
  32. vendor/rosell-dk/webp-convert/src/Helpers/PathChecker.php +13 -1
  33. webp-express.php +1 -1
README.md CHANGED
@@ -638,7 +638,13 @@ Here are my current plans ahead: 0.17 will probably be a file manager-like inter
638
 
639
  If you wish to affect priorities, it is certainly possible. You can try to argue your case in the forum or you can simply let the money do the talking. By donating as little as a cup of coffee on [ko-fi.com/rosell](https://ko-fi.com/rosell), you can leave a wish. I shall take these wishes into account when prioritizing between new features.
640
 
641
- ## Changes in 0.16.0 =
 
 
 
 
 
 
642
  *(released: 24 sep 2019)*
643
 
644
  - Added option to specify CDN urls in Alter HTML. Thanks to Gunnar Peipman from Estonia for suggesting this.
638
 
639
  If you wish to affect priorities, it is certainly possible. You can try to argue your case in the forum or you can simply let the money do the talking. By donating as little as a cup of coffee on [ko-fi.com/rosell](https://ko-fi.com/rosell), you can leave a wish. I shall take these wishes into account when prioritizing between new features.
640
 
641
+ ## Changes in 0.17.0
642
+ *(released: 27 sep 2019)*
643
+
644
+ * Cwebp conversion method runs on more systems (not subject to open_basedir restrictions and also tries "pure" cwebp command). Thanks to cng11 for reaching out so I spotted this.
645
+ * Ewww conversion method no longer does a remote api-key check for each conversion - so it is faster. If an ewww conversions fails due to a non-functional key, the key will not be tried again (until next time the options are saved)
646
+
647
+ ## Changes in 0.16.0
648
  *(released: 24 sep 2019)*
649
 
650
  - Added option to specify CDN urls in Alter HTML. Thanks to Gunnar Peipman from Estonia for suggesting this.
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.16.0
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -645,6 +645,13 @@ Easy enough! - [Go here!](https://ko-fi.com/rosell). Or [here](https://buymeacof
645
 
646
  == Changelog ==
647
 
 
 
 
 
 
 
 
648
  = 0.16.0 =
649
  *(released: 24 sep 2019)*
650
 
@@ -1019,6 +1026,9 @@ For older releases, check out changelog.txt
1019
 
1020
  == Upgrade Notice ==
1021
 
 
 
 
1022
  = 0.16.0 =
1023
  * Various improvements and fixes
1024
 
4
  Tags: webp, images, performance
5
  Requires at least: 4.0
6
  Tested up to: 5.2
7
+ Stable tag: 0.17.0
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
645
 
646
  == Changelog ==
647
 
648
+ = 0.17.0 =
649
+ *(released: 27 sep 2019)*
650
+
651
+ * Cwebp conversion method runs on more systems (not subject to open_basedir restrictions and also tries "pure" cwebp command). Thanks to cng11 for reaching out so I spotted this.
652
+ * Ewww conversion method no longer does a remote api-key check for each conversion - so it is faster. If an ewww conversions fails due to a non-functional key, the key will not be tried again (until next time the options are saved)
653
+ * Updated cwebp binaries to version 1.0.3
654
+
655
  = 0.16.0 =
656
  *(released: 24 sep 2019)*
657
 
1026
 
1027
  == Upgrade Notice ==
1028
 
1029
+ = 0.17.0 =
1030
+ * Improved Cwebp availability and Ewww performance. And updated cwebp binaries to version 1.0.3
1031
+
1032
  = 0.16.0 =
1033
  * Various improvements and fixes
1034
 
changelog.txt CHANGED
@@ -1,3 +1,10 @@
 
 
 
 
 
 
 
1
  = 0.16.0 =
2
  *(released: 24 sep 2019)*
3
 
1
+ = 0.17.0 =
2
+ *(released: 27 sep 2019)*
3
+
4
+ * Cwebp conversion method runs on more systems (not subject to open_basedir restrictions and also tries "pure" cwebp command). Thanks to cng11 for reaching out so I spotted this.
5
+ * Ewww conversion method no longer does a remote api-key check for each conversion - so it is faster. If an ewww conversions fails due to a non-functional key, the key will not be tried again (until next time the options are saved)
6
+ * Updated cwebp binaries to version 1.0.3
7
+
8
  = 0.16.0 =
9
  *(released: 24 sep 2019)*
10
 
composer.lock CHANGED
@@ -118,16 +118,16 @@
118
  },
119
  {
120
  "name": "rosell-dk/webp-convert",
121
- "version": "2.1.6",
122
  "source": {
123
  "type": "git",
124
  "url": "https://github.com/rosell-dk/webp-convert.git",
125
- "reference": "5cb744d2786468fb51883d1f3a90562166df3320"
126
  },
127
  "dist": {
128
  "type": "zip",
129
- "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/5cb744d2786468fb51883d1f3a90562166df3320",
130
- "reference": "5cb744d2786468fb51883d1f3a90562166df3320",
131
  "shasum": ""
132
  },
133
  "require": {
@@ -168,13 +168,13 @@
168
  "authors": [
169
  {
170
  "name": "Bjørn Rosell",
171
- "role": "Project Author",
172
- "homepage": "https://www.bitwise-it.dk/contact"
173
  },
174
  {
175
  "name": "Martin Folkers",
176
- "role": "Collaborator",
177
- "homepage": "https://twobrain.io"
178
  }
179
  ],
180
  "description": "Convert JPEG & PNG to WebP with PHP",
@@ -190,7 +190,7 @@
190
  "png",
191
  "png2webp"
192
  ],
193
- "time": "2019-08-10T22:04:08+00:00"
194
  },
195
  {
196
  "name": "rosell-dk/webp-convert-cloud-service",
118
  },
119
  {
120
  "name": "rosell-dk/webp-convert",
121
+ "version": "2.2.2",
122
  "source": {
123
  "type": "git",
124
  "url": "https://github.com/rosell-dk/webp-convert.git",
125
+ "reference": "1c3f7f228dfa1fc066ef90957c91f4b99f44dd45"
126
  },
127
  "dist": {
128
  "type": "zip",
129
+ "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/1c3f7f228dfa1fc066ef90957c91f4b99f44dd45",
130
+ "reference": "1c3f7f228dfa1fc066ef90957c91f4b99f44dd45",
131
  "shasum": ""
132
  },
133
  "require": {
168
  "authors": [
169
  {
170
  "name": "Bjørn Rosell",
171
+ "homepage": "https://www.bitwise-it.dk/contact",
172
+ "role": "Project Author"
173
  },
174
  {
175
  "name": "Martin Folkers",
176
+ "homepage": "https://twobrain.io",
177
+ "role": "Collaborator"
178
  }
179
  ],
180
  "description": "Convert JPEG & PNG to WebP with PHP",
190
  "png",
191
  "png2webp"
192
  ],
193
+ "time": "2019-09-27T10:34:05+00:00"
194
  },
195
  {
196
  "name": "rosell-dk/webp-convert-cloud-service",
docs/development.md CHANGED
@@ -14,7 +14,7 @@ It actually seems that the mappings are not needed. It seems to work fine when I
14
  rm -r vendor/rosell-dk/webp-convert/docs
15
  rm -r vendor/rosell-dk/webp-convert/src/Helpers/*.txt
16
  rm vendor/rosell-dk/dom-util-for-webp/phpstan.neon
17
-
18
  ```
19
 
20
  3. Commit on git
14
  rm -r vendor/rosell-dk/webp-convert/docs
15
  rm -r vendor/rosell-dk/webp-convert/src/Helpers/*.txt
16
  rm vendor/rosell-dk/dom-util-for-webp/phpstan.neon
17
+ rmdir vendor/bin
18
  ```
19
 
20
  3. Commit on git
lib/classes/Config.php CHANGED
@@ -14,34 +14,6 @@ use \WebPExpress\Option;
14
  class Config
15
  {
16
 
17
- /**
18
- * @return object|false Returns parsed file the file exists and can be read. Otherwise it returns false
19
- */
20
- public static function loadJSONOptions($filename)
21
- {
22
- $json = FileHelper::loadFile($filename);
23
- if ($json === false) {
24
- return false;
25
- }
26
-
27
- $options = json_decode($json, true);
28
- if ($options === null) {
29
- return false;
30
- }
31
- return $options;
32
- }
33
-
34
- public static function saveJSONOptions($filename, $obj)
35
- {
36
- $result = @file_put_contents(
37
- $filename,
38
- json_encode($obj, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT)
39
- );
40
- /*if ($result === false) {
41
- echo 'COULD NOT' . $filename;
42
- }*/
43
- return ($result !== false);
44
- }
45
 
46
 
47
  /**
@@ -49,7 +21,7 @@ class Config
49
  */
50
  public static function loadConfig()
51
  {
52
- return self::loadJSONOptions(Paths::getConfigFileName());
53
  }
54
 
55
  public static function getDefaultConfig($skipQualityAuto = false) {
@@ -285,53 +257,6 @@ class Config
285
  } else {
286
  // This is first time visit!
287
  $config['converters'] = ConvertersHelper::$defaultConverters;
288
-
289
- /*
290
- // This is first time visit!
291
- // We must add converters.
292
- // We want to order them according to which ones that are working,
293
- // so we run
294
- $testResult = TestRun::getConverterStatus();
295
- $workingConverters = [];
296
- if ($testResult) {
297
- $workingConverters = $testResult['workingConverters'];
298
- //print_r($testResult);
299
- }
300
-
301
- $defaultConverters = ConvertersHelper::$defaultConverters;
302
-
303
-
304
- if (count($workingConverters) == 0) {
305
- // No converters are working
306
- // Send ewww converter to top
307
- $resultPart1 = [];
308
- $resultPart2 = [];
309
- foreach ($defaultConverters as $converter) {
310
- $converterId = $converter['converter'];
311
- if ($converterId == 'ewww') {
312
- $resultPart1[] = $converter;
313
- } else {
314
- $resultPart2[] = $converter;
315
- }
316
- }
317
- $config['converters'] = array_merge($resultPart1, $resultPart2);
318
- } else {
319
- // Send converters not working to the bottom
320
- // - and also deactivate them..
321
- $resultPart1 = [];
322
- $resultPart2 = [];
323
- foreach ($defaultConverters as $converter) {
324
- $converterId = $converter['converter'];
325
- if (in_array($converterId, $workingConverters)) {
326
- $resultPart1[] = $converter;
327
- } else {
328
- $converter['deactivated'] = true;
329
- $resultPart2[] = $converter;
330
- }
331
- }
332
- $config['converters'] = array_merge($resultPart1, $resultPart2);
333
- }
334
- */
335
  }
336
 
337
 
@@ -456,7 +381,7 @@ class Config
456
 
457
  public static function loadWodOptions()
458
  {
459
- return self::loadJSONOptions(Paths::getWodOptionsFileName());
460
  }
461
 
462
  /**
@@ -532,7 +457,7 @@ class Config
532
  ];
533
 
534
  if (Paths::createConfigDirIfMissing()) {
535
- $success = self::saveJSONOptions(Paths::getConfigFileName(), $config);
536
  if ($success) {
537
  State::setState('configured', true);
538
  self::updateAutoloadedOptions($config);
@@ -599,6 +524,10 @@ class Config
599
  }
600
  }
601
 
 
 
 
 
602
  // 'id', 'working' and 'error' attributes are used internally in webp-express,
603
  // no need to have it in the wod configuration file.
604
  unset ($c['id']);
@@ -717,7 +646,7 @@ class Config
717
  public static function saveWodOptionsFile($options)
718
  {
719
  if (Paths::createConfigDirIfMissing()) {
720
- return self::saveJSONOptions(Paths::getWodOptionsFileName(), $options);
721
  }
722
  return false;
723
  }
14
  class Config
15
  {
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
 
19
  /**
21
  */
22
  public static function loadConfig()
23
  {
24
+ return FileHelper::loadJSONOptions(Paths::getConfigFileName());
25
  }
26
 
27
  public static function getDefaultConfig($skipQualityAuto = false) {
257
  } else {
258
  // This is first time visit!
259
  $config['converters'] = ConvertersHelper::$defaultConverters;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  }
261
 
262
 
381
 
382
  public static function loadWodOptions()
383
  {
384
+ return FileHelper::loadJSONOptions(Paths::getWodOptionsFileName());
385
  }
386
 
387
  /**
457
  ];
458
 
459
  if (Paths::createConfigDirIfMissing()) {
460
+ $success = FileHelper::saveJSONOptions(Paths::getConfigFileName(), $config);
461
  if ($success) {
462
  State::setState('configured', true);
463
  self::updateAutoloadedOptions($config);
524
  }
525
  }
526
 
527
+ if ($c['converter'] == 'ewww') {
528
+ $c['options']['check-key-status-before-converting'] = false;
529
+ }
530
+
531
  // 'id', 'working' and 'error' attributes are used internally in webp-express,
532
  // no need to have it in the wod configuration file.
533
  unset ($c['id']);
646
  public static function saveWodOptionsFile($options)
647
  {
648
  if (Paths::createConfigDirIfMissing()) {
649
+ return FileHelper::saveJSONOptions(Paths::getWodOptionsFileName(), $options);
650
  }
651
  return false;
652
  }
lib/classes/Convert.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace WebPExpress;
4
 
 
 
5
  use \WebPExpress\ConvertHelperIndependent;
6
  use \WebPExpress\Config;
7
  use \WebPExpress\ConvertersHelper;
@@ -98,6 +100,20 @@ class Convert
98
  //return false;
99
  $result = ConvertHelperIndependent::convert($source, $destination, $convertOptions, $logDir, $converter);
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  if ($result['success'] === true) {
102
  $result['filesize-original'] = @filesize($source);
103
  $result['filesize-webp'] = @filesize($destination);
2
 
3
  namespace WebPExpress;
4
 
5
+ use \WebPConvert\Convert\Converters\Ewww;
6
+
7
  use \WebPExpress\ConvertHelperIndependent;
8
  use \WebPExpress\Config;
9
  use \WebPExpress\ConvertersHelper;
100
  //return false;
101
  $result = ConvertHelperIndependent::convert($source, $destination, $convertOptions, $logDir, $converter);
102
 
103
+ //error_log('looki:' . $source . $converter);
104
+ // If we are using stack converter, check if Ewww discovered invalid api key
105
+ //if (is_null($converter)) {
106
+ if (isset(Ewww::$nonFunctionalApiKeysDiscoveredDuringConversion)) {
107
+ // We got an invalid or exceeded api key (at least one).
108
+ //error_log('look:' . print_r(Ewww::$nonFunctionalApiKeysDiscoveredDuringConversion, true));
109
+ EwwwTools::markApiKeysAsNonFunctional(
110
+ Ewww::$nonFunctionalApiKeysDiscoveredDuringConversion,
111
+ Paths::getConfigDirAbs()
112
+ );
113
+ }
114
+ //}
115
+
116
+
117
  if ($result['success'] === true) {
118
  $result['filesize-original'] = @filesize($source);
119
  $result['filesize-webp'] = @filesize($destination);
lib/classes/ConvertHelperIndependent.php CHANGED
@@ -10,6 +10,7 @@ use \WebPConvert\WebPConvert;
10
  use \WebPConvert\Convert\ConverterFactory;
11
  use \WebPConvert\Exceptions\WebPConvertException;
12
  use \WebPConvert\Loggers\BufferLogger;
 
13
  use \WebPExpress\FileHelper;
14
  use \WebPExpress\SanityCheck;
15
  use \WebPExpress\SanityException;
@@ -569,7 +570,8 @@ APACHE
569
 
570
  $text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
571
 
572
- $text = 'WebP Express 0.16.0. ' . $msgTop . ', ' . date("Y-m-d H:i:s") . "\n\r\n\r" . $text;
 
573
 
574
  $logFile = self::getLogFilename($source, $logDir);
575
 
10
  use \WebPConvert\Convert\ConverterFactory;
11
  use \WebPConvert\Exceptions\WebPConvertException;
12
  use \WebPConvert\Loggers\BufferLogger;
13
+
14
  use \WebPExpress\FileHelper;
15
  use \WebPExpress\SanityCheck;
16
  use \WebPExpress\SanityException;
570
 
571
  $text = preg_replace('#' . preg_quote($_SERVER["DOCUMENT_ROOT"]) . '#', '[doc-root]', $text);
572
 
573
+ // TODO: Put version number somewhere else. Ie \WebPExpress\VersionNumber::version
574
+ $text = 'WebP Express 0.17.0. ' . $msgTop . ', ' . date("Y-m-d H:i:s") . "\n\r\n\r" . $text;
575
 
576
  $logFile = self::getLogFilename($source, $logDir);
577
 
lib/classes/EwwwTools.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ // This class does NOT, and MAY NOT rely on Wordpress functions (it is used in WebPOnDemand)
6
+ class EwwwTools
7
+ {
8
+ /**
9
+ * Mark ewww api keys as non functional in config.json
10
+ *
11
+ * @return boolean If it went well.
12
+ */
13
+ private static function markApiKeysAsNonFunctionalInConfig($apiKeysToMarkAsNonFunctional, $configDir)
14
+ {
15
+ $config = FileHelper::loadJSONOptions($configDir . '/config.json');
16
+ if ($config === false) {
17
+ return false;
18
+ }
19
+ if (!isset($config['converters'])) {
20
+ return false;
21
+ }
22
+
23
+ if (!is_array($config['converters'])) {
24
+ return false;
25
+ }
26
+
27
+ foreach ($config['converters'] as &$c) {
28
+ if (!isset($c['converter'])) {
29
+ continue;
30
+ }
31
+ if ($c['converter'] == 'ewww') {
32
+ if (!isset($c['non-functional-api-keys'])) {
33
+ $c['non-functional-api-keys'] = [];
34
+ }
35
+ $c['non-functional-api-keys'] = array_unique(
36
+ array_merge($c['non-functional-api-keys'], $apiKeysToMarkAsNonFunctional)
37
+ );
38
+
39
+ // Do we have an api-key-2 which is not "blacklisted"?
40
+ $haveBackupKey = (isset($c['options']['api-key-2']) && !empty($c['options']['api-key-2']));
41
+ $switchToBackupKey = $haveBackupKey && (!in_array($c['options']['api-key-2'], $c['non-functional-api-keys']));
42
+
43
+ if ($switchToBackupKey) {
44
+ $temp = $c['options']['api-key'];
45
+ $c['options']['api-key'] = $c['options']['api-key-2'];
46
+ $c['options']['api-key-2'] = $temp;
47
+ } else {
48
+ // deactivate converter, we must then.
49
+ $c['deactivated'] = true;
50
+ $c['working'] = false;
51
+ }
52
+
53
+ //$successfulWrite = Config::saveConfigurationFileAndWodOptions($config);
54
+ $successfulWrite = FileHelper::saveJSONOptions($configDir . '/config.json', $config);
55
+ return $successfulWrite;
56
+ }
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Remove ewww in wod-options.json
62
+ *
63
+ * @return boolean If it went well.
64
+ */
65
+ private static function removeEwwwFromWodOptions($apiKeysToMarkAsNonFunctional, $configDir)
66
+ {
67
+ $wodOptions = FileHelper::loadJSONOptions($configDir . '/wod-options.json');
68
+ if ($config === false) {
69
+ return false;
70
+ }
71
+ if (!isset($wodOptions['webp-convert']['convert']['converters'])) {
72
+ return false;
73
+ }
74
+
75
+ if (!is_array($wodOptions['webp-convert']['convert']['converters'])) {
76
+ return false;
77
+ }
78
+
79
+ foreach ($wodOptions['webp-convert']['convert']['converters'] as $i => $c) {
80
+ if (!isset($c['converter'])) {
81
+ continue;
82
+ }
83
+ if ($c['converter'] == 'ewww') {
84
+ //unset($wodOptions['webp-convert']['convert']['converters'][$i]);
85
+ array_splice($wodOptions['webp-convert']['convert']['converters'], $i, 1);
86
+
87
+ //$successfulWrite = Config::saveConfigurationFileAndWodOptions($config);
88
+ $successfulWrite = FileHelper::saveJSONOptions($configDir . '/wod-options.json', $wodOptions);
89
+ return $successfulWrite;
90
+ }
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Mark ewww api keys as non functional.
96
+ *
97
+ * Current implementation simply removes ewww from wod-options.json.
98
+ * It will reappear when options are saved - but be removed again upon next failure
99
+ *
100
+ * @return boolean If it went well.
101
+ */
102
+ public static function markApiKeysAsNonFunctional($apiKeysToMarkAsNonFunctional, $configDir)
103
+ {
104
+ //self::markApiKeysAsNonFunctionalInConfig($apiKeysToMarkAsNonFunctional, $configDir);
105
+
106
+ // TODO: We should update the key to api-key-2 the first time.
107
+ // But I am going to change the structure of wod-options so ewww becomes a stack converter, so
108
+ // I don't bother implementing this right now.
109
+ self::removeEwwwFromWodOptions($apiKeysToMarkAsNonFunctional, $configDir);
110
+
111
+ }
112
+
113
+ }
lib/classes/FileHelper.php CHANGED
@@ -354,4 +354,33 @@ class FileHelper
354
  return preg_replace("#[\\\/]+#", $newSeparator, $path);
355
  }
356
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
357
  }
354
  return preg_replace("#[\\\/]+#", $newSeparator, $path);
355
  }
356
 
357
+ /**
358
+ * @return object|false Returns parsed file the file exists and can be read. Otherwise it returns false
359
+ */
360
+ public static function loadJSONOptions($filename)
361
+ {
362
+ $json = self::loadFile($filename);
363
+ if ($json === false) {
364
+ return false;
365
+ }
366
+
367
+ $options = json_decode($json, true);
368
+ if ($options === null) {
369
+ return false;
370
+ }
371
+ return $options;
372
+ }
373
+
374
+ public static function saveJSONOptions($filename, $obj)
375
+ {
376
+ $result = @file_put_contents(
377
+ $filename,
378
+ json_encode($obj, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT)
379
+ );
380
+ /*if ($result === false) {
381
+ echo 'COULD NOT' . $filename;
382
+ }*/
383
+ return ($result !== false);
384
+ }
385
+
386
  }
lib/classes/PluginActivate.php CHANGED
@@ -45,7 +45,8 @@ class PluginActivate
45
  'success',
46
  'WebP Express re-activated successfully.<br>' .
47
  'The image redirections are in effect again.<br><br>' .
48
- 'Just a quick reminder: If you at some point change the upload directory or move Wordpress, the <i>.htaccess</i> will need to be regenerated.<br>' .
 
49
  'You do that by re-saving the settings ' .
50
  '<a href="' . Paths::getSettingsUrl() . '">(here)</a>'
51
  );
45
  'success',
46
  'WebP Express re-activated successfully.<br>' .
47
  'The image redirections are in effect again.<br><br>' .
48
+ 'Just a quick reminder: If you at some point change the upload directory or move Wordpress, ' .
49
+ 'the <i>.htaccess</i> files will need to be regenerated.<br>' .
50
  'You do that by re-saving the settings ' .
51
  '<a href="' . Paths::getSettingsUrl() . '">(here)</a>'
52
  );
lib/classes/SelfTestHelper.php CHANGED
@@ -135,7 +135,7 @@ class SelfTestHelper
135
  $result[] = 'Copying dummy webp to the cache root for ' . $rootId;
136
  $destDir = Paths::getCacheDirForImageRoot($destinationFolder, $destinationStructure, $rootId);
137
  if (!file_exists($destDir)) {
138
- $result[] = 'The folder did not exist. Creating folder at: ' . $destinationDir;
139
  if (!mkdir($destDir, 0777, true)) {
140
  $result[] = 'Failed creating folder!';
141
  return [$result, false, ''];
135
  $result[] = 'Copying dummy webp to the cache root for ' . $rootId;
136
  $destDir = Paths::getCacheDirForImageRoot($destinationFolder, $destinationStructure, $rootId);
137
  if (!file_exists($destDir)) {
138
+ $result[] = 'The folder did not exist. Creating folder at: ' . $destinationFolder;
139
  if (!mkdir($destDir, 0777, true)) {
140
  $result[] = 'Failed creating folder!';
141
  return [$result, false, ''];
lib/classes/WebPOnDemand.php CHANGED
@@ -213,6 +213,8 @@ class WebPOnDemand extends WodConfigLoader
213
  self::$webExpressContentDirAbs . '/log',
214
  'Conversion triggered with the conversion script (wod/webp-on-demand.php)'
215
  );
 
 
216
  }
217
 
218
  public static function processRequest() {
213
  self::$webExpressContentDirAbs . '/log',
214
  'Conversion triggered with the conversion script (wod/webp-on-demand.php)'
215
  );
216
+
217
+ self::fixConfigIfEwwwDiscoveredNonFunctionalApiKeys();
218
  }
219
 
220
  public static function processRequest() {
lib/classes/WebPRealizer.php CHANGED
@@ -237,6 +237,7 @@ class WebPRealizer extends WodConfigLoader
237
  'Conversion triggered with the conversion script (wod/webp-realizer.php)'
238
  );
239
 
 
240
  }
241
 
242
  public static function processRequest() {
237
  'Conversion triggered with the conversion script (wod/webp-realizer.php)'
238
  );
239
 
240
+ self::fixConfigIfEwwwDiscoveredNonFunctionalApiKeys();
241
  }
242
 
243
  public static function processRequest() {
lib/classes/WodConfigLoader.php CHANGED
@@ -10,6 +10,8 @@ Calling Wordpress functions will FAIL. Make sure not to do that in either this c
10
 
11
  namespace WebPExpress;
12
 
 
 
13
  use \WebPExpress\ImageRoots;
14
  use \WebPExpress\Sanitize;
15
  use \WebPExpress\SanityCheck;
@@ -177,4 +179,19 @@ class WodConfigLoader
177
  self::$wodOptions = self::$options['wod'];
178
  }
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  }
10
 
11
  namespace WebPExpress;
12
 
13
+ use \WebPConvert\Convert\Converters\Ewww;
14
+
15
  use \WebPExpress\ImageRoots;
16
  use \WebPExpress\Sanitize;
17
  use \WebPExpress\SanityCheck;
179
  self::$wodOptions = self::$options['wod'];
180
  }
181
 
182
+ /**
183
+ * Must be called after conversion.
184
+ */
185
+ protected static function fixConfigIfEwwwDiscoveredNonFunctionalApiKeys()
186
+ {
187
+ if (isset(Ewww::$nonFunctionalApiKeysDiscoveredDuringConversion)) {
188
+ // We got an invalid or exceeded api key (at least one).
189
+ //error_log('look:' . print_r(Ewww::$nonFunctionalApiKeysDiscoveredDuringConversion, true));
190
+ EwwwTools::markApiKeysAsNonFunctional(
191
+ Ewww::$nonFunctionalApiKeysDiscoveredDuringConversion,
192
+ self::$webExpressContentDirAbs . '/config'
193
+ );
194
+ }
195
+
196
+ }
197
  }
lib/options/page-welcome.php CHANGED
@@ -24,11 +24,11 @@ echo '<h3>Welcome!</h3>';
24
  //}
25
 
26
  if ($weKnowThereAreNoWorkingConverters) {
27
- echo '<p>Unfortunately none of the "local" conversion methods are available on your server. That is: ' .
28
- 'Your server cannot convert webp files in PHP without resorting to cloud conversion.</p>' .
29
  '<p>But do not despear! - You have options!</p>' .
30
  '<ol style="list-style-position:outside">' .
31
- '<li>You can install this plugin on another website, which supports a local conversion method and connect to that using the "Remote WebP Express" conversion method' .
32
  '<li>You can purchase a key for the <a target="_blank" href="https://ewww.io/plans/">ewww cloud converter</a>. They do not charge credits for webp conversions, so all you ever have to pay is the one dollar start-up fee :)</li>' .
33
  '<li>I have written a <a target="_blank" href="https://github.com/rosell-dk/webp-convert/wiki/A-template-letter-for-shared-hosts">template letter</a> which you can try sending to your webhost</li>' .
34
  '<li>You can set up a <a target="_blank" href="https://github.com/rosell-dk/webp-convert-cloud-service">webp-convert-cloud-service</a> on another server and connect to that. Its open source.</li>' .
24
  //}
25
 
26
  if ($weKnowThereAreNoWorkingConverters) {
27
+ // server does not meet the requirements for converting images to webp without resorting to cloud conversion
28
+ echo '<p>Unfortunately your server cannot convert webp files in PHP without resorting to cloud conversion.</p>' .
29
  '<p>But do not despear! - You have options!</p>' .
30
  '<ol style="list-style-position:outside">' .
31
+ '<li>You can install this plugin on another website, which supports a "local" webp conversion method and connect to that using the "Remote WebP Express" conversion method' .
32
  '<li>You can purchase a key for the <a target="_blank" href="https://ewww.io/plans/">ewww cloud converter</a>. They do not charge credits for webp conversions, so all you ever have to pay is the one dollar start-up fee :)</li>' .
33
  '<li>I have written a <a target="_blank" href="https://github.com/rosell-dk/webp-convert/wiki/A-template-letter-for-shared-hosts">template letter</a> which you can try sending to your webhost</li>' .
34
  '<li>You can set up a <a target="_blank" href="https://github.com/rosell-dk/webp-convert-cloud-service">webp-convert-cloud-service</a> on another server and connect to that. Its open source.</li>' .
vendor/composer/installed.json CHANGED
@@ -115,17 +115,17 @@
115
  },
116
  {
117
  "name": "rosell-dk/webp-convert",
118
- "version": "2.1.6",
119
- "version_normalized": "2.1.6.0",
120
  "source": {
121
  "type": "git",
122
  "url": "https://github.com/rosell-dk/webp-convert.git",
123
- "reference": "5cb744d2786468fb51883d1f3a90562166df3320"
124
  },
125
  "dist": {
126
  "type": "zip",
127
- "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/5cb744d2786468fb51883d1f3a90562166df3320",
128
- "reference": "5cb744d2786468fb51883d1f3a90562166df3320",
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-08-10T22:04:08+00:00",
147
  "type": "library",
148
  "extra": {
149
  "scripts-descriptions": {
@@ -168,13 +168,13 @@
168
  "authors": [
169
  {
170
  "name": "Bjørn Rosell",
171
- "role": "Project Author",
172
- "homepage": "https://www.bitwise-it.dk/contact"
173
  },
174
  {
175
  "name": "Martin Folkers",
176
- "role": "Collaborator",
177
- "homepage": "https://twobrain.io"
178
  }
179
  ],
180
  "description": "Convert JPEG & PNG to WebP with PHP",
115
  },
116
  {
117
  "name": "rosell-dk/webp-convert",
118
+ "version": "2.2.2",
119
+ "version_normalized": "2.2.2.0",
120
  "source": {
121
  "type": "git",
122
  "url": "https://github.com/rosell-dk/webp-convert.git",
123
+ "reference": "1c3f7f228dfa1fc066ef90957c91f4b99f44dd45"
124
  },
125
  "dist": {
126
  "type": "zip",
127
+ "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/1c3f7f228dfa1fc066ef90957c91f4b99f44dd45",
128
+ "reference": "1c3f7f228dfa1fc066ef90957c91f4b99f44dd45",
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-09-27T10:34:05+00:00",
147
  "type": "library",
148
  "extra": {
149
  "scripts-descriptions": {
168
  "authors": [
169
  {
170
  "name": "Bjørn Rosell",
171
+ "homepage": "https://www.bitwise-it.dk/contact",
172
+ "role": "Project Author"
173
  },
174
  {
175
  "name": "Martin Folkers",
176
+ "homepage": "https://twobrain.io",
177
+ "role": "Collaborator"
178
  }
179
  ],
180
  "description": "Convert JPEG & PNG to WebP with PHP",
vendor/rosell-dk/webp-convert/composer.json CHANGED
@@ -6,7 +6,6 @@
6
  "keywords": ["webp", "images", "cwebp", "imagick", "gd", "jpg2webp", "png2webp", "jpg", "png", "image conversion"],
7
  "scripts": {
8
  "ci": [
9
- "@build",
10
  "@test",
11
  "@phpcs-all",
12
  "@composer validate --no-check-all --strict",
@@ -23,7 +22,6 @@
23
  "phpcs": "phpcs --standard=PSR2",
24
  "phpcs-all": "phpcs --standard=PSR2 src",
25
  "phpcbf": "phpcbf --standard=PSR2",
26
- "build": "php build-scripts/build.php",
27
  "phpstan": "vendor/bin/phpstan analyse src --level=4",
28
  "phpstan-global": "~/.composer/vendor/bin/phpstan analyse src --level=4"
29
  },
6
  "keywords": ["webp", "images", "cwebp", "imagick", "gd", "jpg2webp", "png2webp", "jpg", "png", "image conversion"],
7
  "scripts": {
8
  "ci": [
 
9
  "@test",
10
  "@phpcs-all",
11
  "@composer validate --no-check-all --strict",
22
  "phpcs": "phpcs --standard=PSR2",
23
  "phpcs-all": "phpcs --standard=PSR2 src",
24
  "phpcbf": "phpcbf --standard=PSR2",
 
25
  "phpstan": "vendor/bin/phpstan analyse src --level=4",
26
  "phpstan-global": "~/.composer/vendor/bin/phpstan analyse src --level=4"
27
  },
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.1.4', '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.2.2', '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/BaseTraits/WarningLoggerTrait.php CHANGED
@@ -23,7 +23,7 @@ trait WarningLoggerTrait
23
  * Handle warnings and notices during conversion by logging them and passing them on.
24
  *
25
  * The function is a callback used with "set_error_handler".
26
- * It is declared public because it needs to be accessible from the point where the warning happened.
27
  *
28
  * @param integer $errno
29
  * @param string $errstr
@@ -45,6 +45,21 @@ trait WarningLoggerTrait
45
 
46
  - Because we want to log all warnings and errors (also the ones that was suppressed with @)
47
  https://secure.php.net/manual/en/language.operators.errorcontrol.php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  */
49
 
50
  $errorTypes = [
23
  * Handle warnings and notices during conversion by logging them and passing them on.
24
  *
25
  * The function is a callback used with "set_error_handler".
26
+ * It is declared public because it needs to be accessible from the point where the warning is triggered.
27
  *
28
  * @param integer $errno
29
  * @param string $errstr
45
 
46
  - Because we want to log all warnings and errors (also the ones that was suppressed with @)
47
  https://secure.php.net/manual/en/language.operators.errorcontrol.php
48
+
49
+ If we were to decide suppressing the ones with @, I could do this:
50
+
51
+ if (error_reporting() == 0) {
52
+ /// @ sign temporary disabled error reporting
53
+ return;
54
+ }
55
+ [https://stackoverflow.com/questions/7380782/error-suppression-operator-and-set-error-handler]
56
+
57
+ However, that would also disable the warnings on systems with error reporting set to E_NONE.
58
+ And I really want the conversion log file to contain these warnings on all systems.
59
+
60
+ If it was possible to suppress the warnings with @ without suppressing warnings on systems
61
+ with error reporting set to E_NONE, I would do that.
62
+
63
  */
64
 
65
  $errorTypes = [
vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-fbsd → cwebp-0.6.0-fbsd} RENAMED
File without changes
vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-sol → cwebp-0.6.0-solaris} RENAMED
File without changes
vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-linux-0.6.1 → cwebp-0.6.1-linux-x86-64} RENAMED
File without changes
vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-linux-1.0.2-shared → cwebp-1.0.3-linux-x86-64} RENAMED
Binary file
vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/{cwebp-linux-1.0.2-static → cwebp-1.0.3-linux-x86-64-static} RENAMED
Binary file
vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/cwebp-1.0.3-mac-10.14 ADDED
Binary file
vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/cwebp-1.0.3-windows-x64.exe ADDED
Binary file
vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/cwebp-mac12 DELETED
Binary file
vendor/rosell-dk/webp-convert/src/Convert/Converters/Binaries/cwebp.exe DELETED
Binary file
vendor/rosell-dk/webp-convert/src/Convert/Converters/Cwebp.php CHANGED
@@ -37,6 +37,7 @@ class Cwebp extends AbstractConverter
37
  $this->options2->addOptions(
38
  new StringOption('command-line-options', ''),
39
  new SensitiveStringOption('rel-path-to-precompiled-binaries', './Binaries'),
 
40
  new BooleanOption('try-common-system-paths', true),
41
  new BooleanOption('try-supplied-binary-for-os', true)
42
  );
@@ -44,7 +45,7 @@ class Cwebp extends AbstractConverter
44
 
45
  // System paths to look for cwebp binary
46
  private static $cwebpDefaultPaths = [
47
- 'cwebp',
48
  '/usr/bin/cwebp',
49
  '/usr/local/bin/cwebp',
50
  '/usr/gnu/bin/cwebp',
@@ -56,34 +57,63 @@ class Cwebp extends AbstractConverter
56
  // (possible values, see here: https://stackoverflow.com/questions/738823/possible-values-for-php-os)
57
  // Got the precompiled binaries here: https://developers.google.com/speed/webp/docs/precompiled
58
  private static $suppliedBinariesInfo = [
59
- 'WINNT' => [['cwebp.exe', '49e9cb98db30bfa27936933e6fd94d407e0386802cb192800d9fd824f6476873']],
60
- 'Darwin' => [['cwebp-mac12', 'a06a3ee436e375c89dbc1b0b2e8bd7729a55139ae072ed3f7bd2e07de0ebb379']],
61
- 'SunOS' => [['cwebp-sol', '1febaffbb18e52dc2c524cda9eefd00c6db95bc388732868999c0f48deb73b4f']],
62
- 'FreeBSD' => [['cwebp-fbsd', 'e5cbea11c97fadffe221fdf57c093c19af2737e4bbd2cb3cd5e908de64286573']],
 
 
 
 
 
 
 
 
 
 
 
 
63
  'Linux' => [
64
  // Dynamically linked executable.
65
  // It seems it is slightly faster than the statically linked
66
- ['cwebp-linux-1.0.2-shared', 'd6142e9da2f1cab541de10a31527c597225fff5644e66e31d62bb391c41bfbf4'],
67
 
68
  // Statically linked executable
69
  // It may be that it on some systems works, where the dynamically linked does not (see #196)
70
- ['cwebp-linux-1.0.2-static', 'a67092563d9de0fbced7dde61b521d60d10c0ad613327a42a81845aefa612b29'],
71
 
72
- // Old executable for systems where both of the above fails
73
- ['cwebp-linux-0.6.1', '916623e5e9183237c851374d969aebdb96e0edc0692ab7937b95ea67dc3b2568'],
74
  ]
75
  ];
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  public function checkOperationality()
78
  {
79
  $this->checkOperationalityExecTrait();
80
 
81
  $options = $this->options;
82
- if (!$options['try-supplied-binary-for-os'] && !$options['try-common-system-paths']) {
83
  throw new ConverterNotOperationalException(
84
- 'Configured to neither look for cweb binaries in common system locations, ' .
85
- 'nor to use one of the supplied precompiled binaries. But these are the only ways ' .
86
- 'this converter can convert images. No conversion can be made!'
 
87
  );
88
  }
89
  }
@@ -164,7 +194,7 @@ class Cwebp extends AbstractConverter
164
  *
165
  * The "-near_lossless" param is not supported on older versions of cwebp, so skip on those.
166
  *
167
- * @param string $version Version of cwebp.
168
  * @return string
169
  */
170
  private function createCommandLineOptions($version)
@@ -304,7 +334,7 @@ class Cwebp extends AbstractConverter
304
  */
305
  private function getSuppliedBinaryPathForOS()
306
  {
307
- $this->log('Checking if we have a supplied binary for OS: ' . PHP_OS . '... ');
308
 
309
  // Try supplied binary (if available for OS, and hash is correct)
310
  $options = $this->options;
@@ -312,12 +342,13 @@ class Cwebp extends AbstractConverter
312
  $this->logLn('No we dont - not for that OS');
313
  return [];
314
  }
315
- $this->logLn('We do.');
316
 
317
  $result = [];
318
  $files = self::$suppliedBinariesInfo[PHP_OS];
319
- if (count($files) > 0) {
320
- $this->logLn('We in fact have ' . count($files));
 
 
321
  }
322
 
323
  foreach ($files as $i => list($file, $hash)) {
@@ -368,51 +399,14 @@ class Cwebp extends AbstractConverter
368
  return $result;
369
  }
370
 
371
- private function discoverBinaries()
372
  {
373
- $this->logLn('Locating cwebp binaries');
374
-
375
- if (defined('WEBPCONVERT_CWEBP_PATH')) {
376
- $this->logLn('WEBPCONVERT_CWEBP_PATH was defined, so using that path and ignoring any other');
377
- //$this->logLn('Value: "' . getenv('WEBPCONVERT_CWEBP_PATH') . '"');
378
- return [constant('WEBPCONVERT_CWEBP_PATH')];
379
- }
380
- if (!empty(getenv('WEBPCONVERT_CWEBP_PATH'))) {
381
- $this->logLn(
382
- 'WEBPCONVERT_CWEBP_PATH environment variable was set, so using that path and ignoring any other'
383
- );
384
- //$this->logLn('Value: "' . getenv('WEBPCONVERT_CWEBP_PATH') . '"');
385
- return [getenv('WEBPCONVERT_CWEBP_PATH')];
386
- }
387
-
388
- $binaries = [];
389
- if ($this->options['try-common-system-paths']) {
390
- foreach (self::$cwebpDefaultPaths as $binary) {
391
- if (@file_exists($binary)) {
392
- $binaries[] = $binary;
393
- }
394
- }
395
- if (count($binaries) == 0) {
396
- $this->logLn('No cwebp binaries where located in common system locations');
397
- } else {
398
- $this->logLn(strval(count($binaries)) . ' cwebp binaries found in common system locations');
399
- }
400
- }
401
- // TODO: exec('whereis cwebp');
402
- if ($this->options['try-supplied-binary-for-os']) {
403
- $suppliedBinaries = $this->getSuppliedBinaryPathForOS();
404
- foreach ($suppliedBinaries as $suppliedBinary) {
405
- $binaries[] = $suppliedBinary;
406
- }
407
  } else {
408
- $this->logLn('Configured not to try the cwebp binary that comes bundled with webp-convert');
409
- }
410
-
411
- if (count($binaries) == 0) {
412
- $this->logLn('No cwebp binaries to try!');
413
  }
414
- $this->logLn('A total of ' . strval(count($binaries)) . ' cwebp binaries where found');
415
- return $binaries;
416
  }
417
 
418
  /**
@@ -421,32 +415,30 @@ class Cwebp extends AbstractConverter
421
  */
422
  private function detectVersion($binary)
423
  {
424
- //$this->logLn('Examining binary: ' . $binary);
425
  $command = $binary . ' -version';
426
- $this->log('Executing: ' . $command);
427
  exec($command, $output, $returnCode);
428
 
429
  if ($returnCode == 0) {
430
- //$this->logLn('Success');
431
  if (isset($output[0])) {
432
- $this->logLn('. Result: version: ' . $output[0]);
433
  return $output[0];
434
  }
435
  } else {
436
- $this->logExecOutput($output);
437
- $this->logLn('');
438
  if ($returnCode == 127) {
439
- $this->logLn('Exec failed (the cwebp binary was not found at path: ' . $binary. ')');
440
  } else {
441
- $this->logLn(
442
- 'Exec failed (return code: ' . $returnCode . ')'
443
- );
444
  if ($returnCode == 126) {
445
  $this->logLn(
446
- 'PS: Return code 126 means "Permission denied". The user that the command was run with does ' .
447
- 'not have permission to execute that binary.'
 
 
 
 
448
  );
449
- // TODO: further info: shell_exec('whoami')
450
  }
451
  }
452
  return $returnCode;
@@ -454,18 +446,16 @@ class Cwebp extends AbstractConverter
454
  }
455
 
456
  /**
457
- * Check versions for binaries, and return array (indexed by the binary, value being the version of the binary).
458
  *
459
- * @return array
 
460
  */
461
  private function detectVersions($binaries)
462
  {
463
  $binariesWithVersions = [];
464
  $binariesWithFailCodes = [];
465
 
466
- $this->logLn(
467
- 'Detecting versions of the cwebp binaries found (and verifying that they can be executed in the process)'
468
- );
469
  foreach ($binaries as $binary) {
470
  $versionStringOrFailCode = $this->detectVersion($binary);
471
  // $this->logLn($binary . ': ' . $versionString);
@@ -479,9 +469,63 @@ class Cwebp extends AbstractConverter
479
  }
480
 
481
  /**
482
- * @return boolean success or not.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483
  */
484
- private function tryBinary($binary, $version, $useNice)
485
  {
486
 
487
  //$this->logLn('Trying binary: ' . $binary);
@@ -505,57 +549,77 @@ class Cwebp extends AbstractConverter
505
  }
506
  }
507
 
508
- protected function doActualConvert()
 
 
 
 
 
 
509
  {
510
- $binaries = $this->discoverBinaries();
511
 
512
- if (count($binaries) == 0) {
513
- throw new SystemRequirementsNotMetException(
514
- 'No cwebp binaries located. Check the conversion log for details.'
515
- );
516
- }
517
 
518
- $versions = $this->detectVersions($binaries);
519
- if (count($versions['detected']) == 0) {
520
- //$this->logLn('None of the cwebp files located can be executed.');
521
- if (count($binaries) == 1) {
522
- $errorMsg = 'The cwebp file found cannot be can be executed.';
523
- } else {
524
- $errorMsg = 'None of the cwebp files located can be executed.';
525
  }
526
- $uniqueFailCodes = array_unique(array_values($versions['failed']));
527
- if (count($uniqueFailCodes) == 1) {
528
- $errorMsg .= ' ' . (count($binaries) == 1 ? 'It' : 'All') .
529
- ' failed with return code ' . $uniqueFailCodes[0];
530
- if ($uniqueFailCodes[0] == 126) {
531
- $errorMsg .= ' (permission denied)';
532
- }
533
- } else {
534
- $errorMsg .= ' Failure codes : ' . implode(', ', $uniqueFailCodes);
535
  }
 
536
 
537
- throw new SystemRequirementsNotMetException($errorMsg);
 
 
 
 
 
 
 
 
 
538
  }
 
 
539
 
 
 
 
540
  $binaryVersions = $versions['detected'];
 
 
541
 
542
- if (count($binaries) > 1) {
543
- $this->logLn(
544
- 'Trying executing the cwebs found until success. Starting with the ones with highest version number.'
545
  );
546
  }
547
- //$this->logLn('binary versions: ' . print_r($binaryVersions, true));
548
 
549
  // Sort binaries so those with highest numbers comes first
550
  arsort($binaryVersions);
 
 
 
 
 
 
551
 
552
- //$this->logLn('binary versions (ordered by version): ' . print_r($binaryVersions, true));
553
-
 
 
554
  $useNice = (($this->options['use-nice']) && self::hasNiceSupport());
555
-
556
  $success = false;
557
  foreach ($binaryVersions as $binary => $version) {
558
- if ($this->tryBinary($binary, $version, $useNice)) {
559
  $success = true;
560
  break;
561
  }
37
  $this->options2->addOptions(
38
  new StringOption('command-line-options', ''),
39
  new SensitiveStringOption('rel-path-to-precompiled-binaries', './Binaries'),
40
+ new BooleanOption('try-cwebp', true),
41
  new BooleanOption('try-common-system-paths', true),
42
  new BooleanOption('try-supplied-binary-for-os', true)
43
  );
45
 
46
  // System paths to look for cwebp binary
47
  private static $cwebpDefaultPaths = [
48
+ //'cwebp',
49
  '/usr/bin/cwebp',
50
  '/usr/local/bin/cwebp',
51
  '/usr/gnu/bin/cwebp',
57
  // (possible values, see here: https://stackoverflow.com/questions/738823/possible-values-for-php-os)
58
  // Got the precompiled binaries here: https://developers.google.com/speed/webp/docs/precompiled
59
  private static $suppliedBinariesInfo = [
60
+ 'WINNT' => [
61
+ ['cwebp-1.0.3-windows-x64.exe', 'b3aaab03ca587e887f11f6ae612293d034ee04f4f7f6bc7a175321bb47a10169'],
62
+ ],
63
+ 'Darwin' => [
64
+ ['cwebp-1.0.3-mac-10.14', '7332ed5f0d4091e2379b1eaa32a764f8c0d51b7926996a1dc8b4ef4e3c441a12'],
65
+ ],
66
+ 'SunOS' => [
67
+ // Got this from ewww Wordpress plugin, which unfortunately still uses the old 0.6.0 versions
68
+ // Can you help me get a 1.0.3 version?
69
+ ['cwebp-0.6.0-solaris', '1febaffbb18e52dc2c524cda9eefd00c6db95bc388732868999c0f48deb73b4f']
70
+ ],
71
+ 'FreeBSD' => [
72
+ // Got this from ewww Wordpress plugin, which unfortunately still uses the old 0.6.0 versions
73
+ // Can you help me get a 1.0.3 version?
74
+ ['cwebp-0.6.0-fbsd', 'e5cbea11c97fadffe221fdf57c093c19af2737e4bbd2cb3cd5e908de64286573']
75
+ ],
76
  'Linux' => [
77
  // Dynamically linked executable.
78
  // It seems it is slightly faster than the statically linked
79
+ ['cwebp-1.0.3-linux-x86-64', 'a663215a46d347f63e1ca641c18527a1ae7a2c9a0ae85ca966a97477ea13dfe0'],
80
 
81
  // Statically linked executable
82
  // It may be that it on some systems works, where the dynamically linked does not (see #196)
83
+ ['cwebp-1.0.3-linux-x86-64-static', 'ab96f01b49336da8b976c498528080ff614112d5985da69943b48e0cb1c5228a'],
84
 
85
+ // Old executable for systems in case both of the above fails
86
+ ['cwebp-0.6.1-linux-x86-64', '916623e5e9183237c851374d969aebdb96e0edc0692ab7937b95ea67dc3b2568'],
87
  ]
88
  ];
89
 
90
+ /**
91
+ * Check all hashes of the precompiled binaries.
92
+ *
93
+ * This isn't used when converting, but can be used as a startup check.
94
+ */
95
+ public function checkAllHashes()
96
+ {
97
+ foreach (self::$suppliedBinariesInfo as $os => $arr) {
98
+ foreach ($arr as $i => list($filename, $hash)) {
99
+ if ($hash != hash_file("sha256", __DIR__ . '/Binaries/' . $filename)) {
100
+ throw new \Exception('Hash for ' . $filename . ' is incorrect!');
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
  public function checkOperationality()
107
  {
108
  $this->checkOperationalityExecTrait();
109
 
110
  $options = $this->options;
111
+ if (!$options['try-supplied-binary-for-os'] && !$options['try-common-system-paths'] && !$options['try-cwebp']) {
112
  throw new ConverterNotOperationalException(
113
+ 'Configured to neither try pure cwebp command, ' .
114
+ 'nor look for cweb binaries in common system locations and ' .
115
+ 'nor to use one of the supplied precompiled binaries. ' .
116
+ 'But these are the only ways this converter can convert images. No conversion can be made!'
117
  );
118
  }
119
  }
194
  *
195
  * The "-near_lossless" param is not supported on older versions of cwebp, so skip on those.
196
  *
197
+ * @param string $version Version of cwebp (ie "1.0.3")
198
  * @return string
199
  */
200
  private function createCommandLineOptions($version)
334
  */
335
  private function getSuppliedBinaryPathForOS()
336
  {
337
+ $this->log('Checking if we have a supplied precompiled binary for your OS (' . PHP_OS . ')... ');
338
 
339
  // Try supplied binary (if available for OS, and hash is correct)
340
  $options = $this->options;
342
  $this->logLn('No we dont - not for that OS');
343
  return [];
344
  }
 
345
 
346
  $result = [];
347
  $files = self::$suppliedBinariesInfo[PHP_OS];
348
+ if (count($files) == 1) {
349
+ $this->logLn('We do.');
350
+ } else {
351
+ $this->logLn('We do. We in fact have ' . count($files));
352
  }
353
 
354
  foreach ($files as $i => list($file, $hash)) {
399
  return $result;
400
  }
401
 
402
+ private function who()
403
  {
404
+ exec('whoami', $whoOutput, $whoReturnCode);
405
+ if (($whoReturnCode == 0) && (isset($whoOutput[0]))) {
406
+ return 'user: "' . $whoOutput[0] . '"';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
407
  } else {
408
+ return 'the user that the command was run with';
 
 
 
 
409
  }
 
 
410
  }
411
 
412
  /**
415
  */
416
  private function detectVersion($binary)
417
  {
 
418
  $command = $binary . ' -version';
419
+ $this->log('- Executing: ' . $command);
420
  exec($command, $output, $returnCode);
421
 
422
  if ($returnCode == 0) {
 
423
  if (isset($output[0])) {
424
+ $this->logLn('. Result: version: *' . $output[0] . '*');
425
  return $output[0];
426
  }
427
  } else {
428
+ $this->log('. Result: ');
 
429
  if ($returnCode == 127) {
430
+ $this->logLn('*Exec failed* (the cwebp binary was not found at path: ' . $binary. ')');
431
  } else {
 
 
 
432
  if ($returnCode == 126) {
433
  $this->logLn(
434
+ '*Exec failed*. ' .
435
+ 'Permission denied (' . $this->who() . ' does not have permission to execute that binary)'
436
+ );
437
+ } else {
438
+ $this->logLn(
439
+ '*Exec failed* (return code: ' . $returnCode . ')'
440
  );
441
+ $this->logExecOutput($output);
442
  }
443
  }
444
  return $returnCode;
446
  }
447
 
448
  /**
449
+ * Check versions for an array of binaries.
450
  *
451
+ * @return array the "detected" key holds working binaries and their version numbers, the
452
+ * the "failed" key holds failed binaries and their error codes.
453
  */
454
  private function detectVersions($binaries)
455
  {
456
  $binariesWithVersions = [];
457
  $binariesWithFailCodes = [];
458
 
 
 
 
459
  foreach ($binaries as $binary) {
460
  $versionStringOrFailCode = $this->detectVersion($binary);
461
  // $this->logLn($binary . ': ' . $versionString);
469
  }
470
 
471
  /**
472
+ * Detect versions of all cwebps that are of relevance (according to configuration).
473
+ *
474
+ * @return array the "detected" key holds working binaries and their version numbers, the
475
+ * the "failed" key holds failed binaries and their error codes.
476
+ */
477
+ private function getCwebpVersions()
478
+ {
479
+ // TODO: Check out if exec('whereis cwebp'); would be a good idea
480
+
481
+ if (defined('WEBPCONVERT_CWEBP_PATH')) {
482
+ $this->logLn('WEBPCONVERT_CWEBP_PATH was defined, so using that path and ignoring any other');
483
+ return $this->detectVersions([constant('WEBPCONVERT_CWEBP_PATH')]);
484
+ }
485
+ if (!empty(getenv('WEBPCONVERT_CWEBP_PATH'))) {
486
+ $this->logLn(
487
+ 'WEBPCONVERT_CWEBP_PATH environment variable was set, so using that path and ignoring any other'
488
+ );
489
+ return $this->detectVersions([getenv('WEBPCONVERT_CWEBP_PATH')]);
490
+ }
491
+
492
+ $versions = [];
493
+ if ($this->options['try-cwebp']) {
494
+ $this->logLn(
495
+ 'Detecting version of cwebp command (it may not be available, but we try nonetheless)'
496
+ );
497
+ $versions = $this->detectVersions(['cwebp']);
498
+ }
499
+ if ($this->options['try-common-system-paths']) {
500
+ // Note:
501
+ // We used to do a file_exists($binary) check.
502
+ // That was not a good idea because it could trigger open_basedir errors. The open_basedir
503
+ // restriction does not operate on the exec command. So note to self: Do not do that again.
504
+ $this->logLn(
505
+ 'Detecting versions of the cwebp binaries in common system paths ' .
506
+ '(some may not be found, that is to be expected)'
507
+ );
508
+ $versions = array_merge_recursive($versions, $this->detectVersions(self::$cwebpDefaultPaths));
509
+ }
510
+ if ($this->options['try-supplied-binary-for-os']) {
511
+ $versions = array_merge_recursive(
512
+ $versions,
513
+ $this->detectVersions($this->getSuppliedBinaryPathForOS())
514
+ );
515
+ }
516
+ return $versions;
517
+ }
518
+
519
+ /**
520
+ * Try executing a cwebp binary (or command, like: "cwebp")
521
+ *
522
+ * @param string $binary
523
+ * @param string $version Version of cwebp (ie "1.0.3")
524
+ * @param boolean $useNice Whether to use "nice" command or not
525
+ *
526
+ * @return boolean success or not.
527
  */
528
+ private function tryCwebpBinary($binary, $version, $useNice)
529
  {
530
 
531
  //$this->logLn('Trying binary: ' . $binary);
549
  }
550
  }
551
 
552
+ /**
553
+ * Helper for composing an error message when no converters are working.
554
+ *
555
+ * @param array $versions The array which we get from calling ::getCwebpVersions()
556
+ * @return string An informative and to the point error message.
557
+ */
558
+ private function composeMeaningfullErrorMessageNoVersionsWorking($versions)
559
  {
 
560
 
561
+ // PS: array_values() is used to reindex
562
+ $uniqueFailCodes = array_values(array_unique(array_values($versions['failed'])));
563
+ $justOne = (count($versions['failed']) == 1);
 
 
564
 
565
+ if (count($uniqueFailCodes) == 1) {
566
+ if ($uniqueFailCodes[0] == 127) {
567
+ return 'No cwebp binaries located. Check the conversion log for details.';
 
 
 
 
568
  }
569
+ }
570
+ // If there are more failures than 127, the 127 failures are unintesting.
571
+ // It is to be expected that some of the common system paths does not contain a cwebp.
572
+ $uniqueFailCodesBesides127 = array_values(array_diff($uniqueFailCodes, [127]));
573
+
574
+ if (count($uniqueFailCodesBesides127) == 1) {
575
+ if ($uniqueFailCodesBesides127[0] == 126) {
576
+ return 'No cwebp binaries could be executed (permission denied for ' . $this->who() . ').';
 
577
  }
578
+ }
579
 
580
+ $errorMsg = '';
581
+ if ($justOne) {
582
+ $errorMsg .= 'The cwebp file found cannot be can be executed ';
583
+ } else {
584
+ $errorMsg .= 'None of the cwebp files can be executed ';
585
+ }
586
+ if (count($uniqueFailCodesBesides127) == 1) {
587
+ $errorMsg .= '(failure code: ' . $uniqueFailCodesBesides127[0] . ')';
588
+ } else {
589
+ $errorMsg .= '(failure codes: ' . implode(', ', $uniqueFailCodesBesides127) . ')';
590
  }
591
+ return $errorMsg;
592
+ }
593
 
594
+ protected function doActualConvert()
595
+ {
596
+ $versions = $this->getCwebpVersions();
597
  $binaryVersions = $versions['detected'];
598
+ if (count($binaryVersions) == 0) {
599
+ // No working cwebp binaries found.
600
 
601
+ throw new SystemRequirementsNotMetException(
602
+ $this->composeMeaningfullErrorMessageNoVersionsWorking($versions)
 
603
  );
604
  }
 
605
 
606
  // Sort binaries so those with highest numbers comes first
607
  arsort($binaryVersions);
608
+ $this->logLn(
609
+ 'Here is what we found, ordered by version number.'
610
+ );
611
+ foreach ($binaryVersions as $binary => $version) {
612
+ $this->logLn('- ' . $binary . ': (version: ' . $version .')');
613
+ }
614
 
615
+ // Execute!
616
+ $this->logLn(
617
+ 'Trying the first of these. If that should fail (it should not), the next will be tried and so on.'
618
+ );
619
  $useNice = (($this->options['use-nice']) && self::hasNiceSupport());
 
620
  $success = false;
621
  foreach ($binaryVersions as $binary => $version) {
622
+ if ($this->tryCwebpBinary($binary, $version, $useNice)) {
623
  $success = true;
624
  break;
625
  }
vendor/rosell-dk/webp-convert/src/Convert/Converters/Ewww.php CHANGED
@@ -9,6 +9,7 @@ use WebPConvert\Convert\Exceptions\ConversionFailedException;
9
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperationalException;
10
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperational\InvalidApiKeyException;
11
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperational\SystemRequirementsNotMetException;
 
12
  use WebPConvert\Options\SensitiveStringOption;
13
 
14
  /**
@@ -23,6 +24,9 @@ class Ewww extends AbstractConverter
23
  use CloudConverterTrait;
24
  use CurlTrait;
25
 
 
 
 
26
  protected function getUnsupportedDefaultOptions()
27
  {
28
  return [
@@ -39,7 +43,8 @@ class Ewww extends AbstractConverter
39
  parent::createOptions();
40
 
41
  $this->options2->addOptions(
42
- new SensitiveStringOption('api-key', '')
 
43
  );
44
  }
45
 
@@ -95,16 +100,18 @@ class Ewww extends AbstractConverter
95
  // Check for curl requirements
96
  $this->checkOperationalityForCurlTrait();
97
 
98
- $keyStatus = self::getKeyStatus($apiKey);
99
- switch ($keyStatus) {
100
- case 'great':
101
- break;
102
- case 'exceeded':
103
- throw new ConverterNotOperationalException('Quota has exceeded');
104
- break;
105
- case 'invalid':
106
- throw new InvalidApiKeyException('Api key is invalid');
107
- break;
 
 
108
  }
109
  }
110
 
@@ -167,14 +174,28 @@ class Ewww extends AbstractConverter
167
  //echo curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
168
  curl_close($ch);
169
 
170
- /* May return this: {"error":"invalid","t":"exceeded"} */
 
 
 
171
  $responseObj = json_decode($response);
172
  if (isset($responseObj->error)) {
173
- //echo 'error:' . $responseObj->error . '<br>';
174
- //echo $response;
175
- //self::blacklistKey($key);
176
- //throw new SystemRequirementsNotMetException('The key is invalid. Blacklisted it!');
177
- throw new InvalidApiKeyException('The api key is invalid');
 
 
 
 
 
 
 
 
 
 
 
178
  }
179
 
180
  throw new ConversionFailedException(
@@ -274,20 +295,11 @@ class Ewww extends AbstractConverter
274
 
275
  curl_setopt($ch, CURLOPT_URL, "https://optimize.exactlywww.com/verify/");
276
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
277
- curl_setopt(
278
- $ch,
279
- CURLOPT_POSTFIELDS,
280
- [
281
  'api_key' => $key
282
- ]
283
- );
284
 
285
- // The 403 forbidden is avoided with this line.
286
- curl_setopt(
287
- $ch,
288
- CURLOPT_USERAGENT,
289
- 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)'
290
- );
291
 
292
  $response = curl_exec($ch);
293
  // echo $response;
@@ -339,18 +351,10 @@ class Ewww extends AbstractConverter
339
 
340
  curl_setopt($ch, CURLOPT_URL, "https://optimize.exactlywww.com/quota/");
341
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
342
- curl_setopt(
343
- $ch,
344
- CURLOPT_POSTFIELDS,
345
- [
346
  'api_key' => $key
347
- ]
348
- );
349
- curl_setopt(
350
- $ch,
351
- CURLOPT_USERAGENT,
352
- 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)'
353
- );
354
 
355
  $response = curl_exec($ch);
356
  return $response; // ie -830 23. Seems to return empty for invalid keys
9
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperationalException;
10
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperational\InvalidApiKeyException;
11
  use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperational\SystemRequirementsNotMetException;
12
+ use WebPConvert\Options\BooleanOption;
13
  use WebPConvert\Options\SensitiveStringOption;
14
 
15
  /**
24
  use CloudConverterTrait;
25
  use CurlTrait;
26
 
27
+ /** @var array Array of invalid or exceeded api keys discovered during conversions (during the request) */
28
+ public static $nonFunctionalApiKeysDiscoveredDuringConversion;
29
+
30
  protected function getUnsupportedDefaultOptions()
31
  {
32
  return [
43
  parent::createOptions();
44
 
45
  $this->options2->addOptions(
46
+ new SensitiveStringOption('api-key', ''),
47
+ new BooleanOption('check-key-status-before-converting', true)
48
  );
49
  }
50
 
100
  // Check for curl requirements
101
  $this->checkOperationalityForCurlTrait();
102
 
103
+ if ($this->options['check-key-status-before-converting']) {
104
+ $keyStatus = self::getKeyStatus($apiKey);
105
+ switch ($keyStatus) {
106
+ case 'great':
107
+ break;
108
+ case 'exceeded':
109
+ throw new ConverterNotOperationalException('Quota has exceeded');
110
+ break;
111
+ case 'invalid':
112
+ throw new InvalidApiKeyException('Api key is invalid');
113
+ break;
114
+ }
115
  }
116
  }
117
 
174
  //echo curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
175
  curl_close($ch);
176
 
177
+ /*
178
+ For bogus or expired key it returns: {"error":"invalid","t":"exceeded"}
179
+ For exceeded key it returns: {"error":"exceeded"}
180
+ */
181
  $responseObj = json_decode($response);
182
  if (isset($responseObj->error)) {
183
+ $this->logLn('We received the following error response: ' . $responseObj->error);
184
+ $this->logLn('Complete response: ' . json_encode($responseObj));
185
+
186
+ // Store the invalid key in array so it can be received once the Stack is completed
187
+ // (even when stack succeeds)
188
+ if (!isset(self::$nonFunctionalApiKeysDiscoveredDuringConversion)) {
189
+ self::$nonFunctionalApiKeysDiscoveredDuringConversion = [];
190
+ }
191
+ if (!in_array($options['api-key'], self::$nonFunctionalApiKeysDiscoveredDuringConversion)) {
192
+ self::$nonFunctionalApiKeysDiscoveredDuringConversion[] = $options['api-key'];
193
+ }
194
+ if ($responseObj->error == "invalid") {
195
+ throw new InvalidApiKeyException('The api key is invalid (or expired)');
196
+ } else {
197
+ throw new InvalidApiKeyException('The quota is exceeded for the api-key');
198
+ }
199
  }
200
 
201
  throw new ConversionFailedException(
295
 
296
  curl_setopt($ch, CURLOPT_URL, "https://optimize.exactlywww.com/verify/");
297
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
298
+ curl_setopt($ch, CURLOPT_POSTFIELDS, [
 
 
 
299
  'api_key' => $key
300
+ ]);
 
301
 
302
+ curl_setopt($ch, CURLOPT_USERAGENT, 'WebPConvert');
 
 
 
 
 
303
 
304
  $response = curl_exec($ch);
305
  // echo $response;
351
 
352
  curl_setopt($ch, CURLOPT_URL, "https://optimize.exactlywww.com/quota/");
353
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
354
+ curl_setopt($ch, CURLOPT_POSTFIELDS, [
 
 
 
355
  'api_key' => $key
356
+ ]);
357
+ curl_setopt($ch, CURLOPT_USERAGENT, 'WebPConvert');
 
 
 
 
 
358
 
359
  $response = curl_exec($ch);
360
  return $response; // ie -830 23. Seems to return empty for invalid keys
vendor/rosell-dk/webp-convert/src/Helpers/PathChecker.php CHANGED
@@ -49,9 +49,10 @@ class PathChecker
49
  }
50
 
51
  // Prevent directory traversal
 
52
  if (preg_match('#\.\.\/#', $absFilePath)) {
53
  throw new InvalidInputException('Directory traversal is not allowed in ' . $text . ' path');
54
- }
55
 
56
  // Prevent stream wrappers ("phar://", "php://" and the like)
57
  // https://www.php.net/manual/en/wrappers.phar.php
@@ -90,6 +91,17 @@ class PathChecker
90
  throw new InvalidInputException('Destination argument missing');
91
  }
92
  self::checkAbsolutePath($destination, 'destination');
 
 
 
 
 
 
 
 
 
 
 
93
  if (@is_dir($destination)) {
94
  throw new InvalidInputException('Destination is a directory');
95
  }
49
  }
50
 
51
  // Prevent directory traversal
52
+ /* Disabled. We DO allow it again (#203)
53
  if (preg_match('#\.\.\/#', $absFilePath)) {
54
  throw new InvalidInputException('Directory traversal is not allowed in ' . $text . ' path');
55
+ }*/
56
 
57
  // Prevent stream wrappers ("phar://", "php://" and the like)
58
  // https://www.php.net/manual/en/wrappers.phar.php
91
  throw new InvalidInputException('Destination argument missing');
92
  }
93
  self::checkAbsolutePath($destination, 'destination');
94
+
95
+ if (!preg_match('#\.webp$#i', $destination)) {
96
+ // Prevent overriding important files.
97
+ // Overriding an .htaccess file would lay down the website.
98
+ throw new InvalidInputException(
99
+ 'Destination file must end with ".webp". ' .
100
+ 'If you deliberately want to store the webp files with another extension, you must rename ' .
101
+ 'the file after successful conversion'
102
+ );
103
+ }
104
+
105
  if (@is_dir($destination)) {
106
  throw new InvalidInputException('Destination is a directory');
107
  }
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.16.0
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2
3
  * Plugin Name: WebP Express
4
  * Plugin URI: https://github.com/rosell-dk/webp-express
5
  * Description: Serve autogenerated WebP images instead of jpeg/png to browsers that supports WebP. Works on anything (media library images, galleries, theme images etc).
6
+ * Version: 0.17.0
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2