WebP Express - Version 0.13.0

Version Description

(released: 21 mar 2019) * Bulk Conversion * Fixed problems with Gd converter and PNG * Optinally auto convert upon media upload * Windows fix (thanks, lwxbr!)

For more info, see the closed issues on the 0.13.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/16?closed=1

Download this release

Release Info

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

Code changes from version 0.12.2 to 0.13.0

Files changed (58) hide show
  1. .gitignore +1 -0
  2. README.md +9 -3
  3. README.txt +16 -5
  4. changelog.txt +7 -0
  5. composer.json +1 -1
  6. lib/activate-first-time.php +0 -74
  7. lib/activate-hook.php +0 -11
  8. lib/admin.php +0 -73
  9. lib/classes/Actions.php +1 -3
  10. lib/classes/AdminInit.php +90 -0
  11. lib/classes/AdminUi.php +68 -0
  12. lib/classes/AlterHtmlHelper.php +0 -5
  13. lib/classes/AlterHtmlImageUrls.php +1 -3
  14. lib/classes/AlterHtmlInit.php +0 -1
  15. lib/classes/BulkConvert.php +213 -0
  16. lib/classes/CacheMover.php +3 -4
  17. lib/classes/CachePurge.php +155 -0
  18. lib/classes/Config.php +58 -69
  19. lib/classes/Convert.php +60 -0
  20. lib/classes/ConvertHelperIndependent.php +201 -0
  21. lib/classes/ConvertersHelper.php +3 -1
  22. lib/classes/FileHelper.php +27 -1
  23. lib/classes/HTAccess.php +1 -7
  24. lib/classes/HandleUploadHooks.php +102 -0
  25. lib/classes/Messenger.php +1 -3
  26. lib/classes/OptionsPage.php +20 -0
  27. lib/classes/OptionsPageHooks.php +16 -0
  28. lib/classes/Paths.php +4 -7
  29. lib/classes/PluginActivate.php +129 -0
  30. lib/classes/PluginDeactivate.php +30 -0
  31. lib/classes/PluginUninstall.php +33 -0
  32. lib/classes/TestRun.php +0 -7
  33. lib/deactivate.php +0 -37
  34. lib/migrate/migrate.php +2 -7
  35. lib/migrate/migrate1.php +1 -10
  36. lib/migrate/migrate2.php +2 -8
  37. lib/migrate/migrate3.php +2 -11
  38. lib/migrate/migrate4.php +0 -5
  39. lib/migrate/migrate5.php +1 -8
  40. lib/migrate/migrate7.php +2 -1
  41. lib/migrate/migrate8.php +98 -0
  42. lib/options/enqueue_scripts.php +12 -3
  43. lib/options/js/bulk-convert.js +224 -0
  44. lib/options/js/purge-cache.js +40 -0
  45. lib/options/options-hooks.php +0 -50
  46. lib/options/options/conversion-options/bulk-convert.inc +22 -0
  47. lib/options/options/conversion-options/conversion-options.inc +2 -0
  48. lib/options/options/conversion-options/convert-on-upload.inc +16 -0
  49. lib/options/options/conversion-options/converter-options/gd.php +3 -3
  50. lib/options/options/general/general.inc +3 -1
  51. lib/options/page-messages.php +7 -4
  52. lib/options/page.php +1 -20
  53. lib/options/submit.php +2 -11
  54. lib/reactivate.php +0 -73
  55. lib/uninstall.php +0 -40
  56. webp-express.php +30 -11
  57. wod/webp-on-demand.php +10 -62
  58. wod/webp-realizer.php +9 -75
.gitignore CHANGED
@@ -1,3 +1,4 @@
1
  composer.lock
2
  composer.phar
3
  /vendor
 
1
  composer.lock
2
  composer.phar
3
  /vendor
4
+ .vscode
README.md CHANGED
@@ -105,7 +105,7 @@ Do not simply remove the plugin without deactivating it first. Deactivation take
105
 
106
  ## Limitations
107
 
108
- * The plugin has not been tested by the developer on Microsoft IIS server. [Some however reports that it works](https://wordpress.org/support/topic/iis-and-webp-works/)
109
 
110
  ## Frequently Asked Questions
111
 
@@ -332,8 +332,8 @@ And here: https://github.com/rosell-dk/webp-express/issues/166
332
 
333
  Here are rules if you need to replace the file extension with ".webp" rather than appending ".webp" to it: https://www.keycdn.com/support/optimus/configuration-to-deliver-webp
334
 
335
- ### I am on a WAMP stack
336
- It has been reported that WebP Express *almost* works on WAMP stack (Windows, Apache, MySQL, PHP). I'd love to debug this, but do not own a Windows server or access to one... Can you help?
337
 
338
  ### I am using Jetpack
339
  If you install Jetpack and enable the "Speed up image load times" then Jetpack will alter the HTML such that images are pointed to their CDN.
@@ -597,6 +597,12 @@ Here are my current plans ahead: 0.13 might be bulk conversion and addition of a
597
 
598
  If you wish to affect priorities, it is certainly possible. You can try to argue your case in the forum or you can simply let the money do the talking. By donating as little as a cup of coffee on [ko-fi.com/rosell](https://ko-fi.com/rosell), you can leave a wish. I shall take these wishes into account when prioritizing between new features.
599
 
 
 
 
 
 
 
600
  ## Changes in 0.12.0
601
  - Multisite support (!)
602
  - A new operation mode: "No conversion", if you do not want to use WebP Express for converting. Replaces the old "Just redirect" mode
105
 
106
  ## Limitations
107
 
108
+ * The plugin [should now work on Microsoft IIS server](https://github.com/rosell-dk/webp-express/pull/213), but it has not been tested thoroughly.
109
 
110
  ## Frequently Asked Questions
111
 
332
 
333
  Here are rules if you need to replace the file extension with ".webp" rather than appending ".webp" to it: https://www.keycdn.com/support/optimus/configuration-to-deliver-webp
334
 
335
+ ### I am on a Windows server
336
+ Good news! It should work now, thanks to a guy that calls himself lwxbr. At least on XAMPP 7.3.1, Windows 10. https://github.com/rosell-dk/webp-express/pull/213.
337
 
338
  ### I am using Jetpack
339
  If you install Jetpack and enable the "Speed up image load times" then Jetpack will alter the HTML such that images are pointed to their CDN.
597
 
598
  If you wish to affect priorities, it is certainly possible. You can try to argue your case in the forum or you can simply let the money do the talking. By donating as little as a cup of coffee on [ko-fi.com/rosell](https://ko-fi.com/rosell), you can leave a wish. I shall take these wishes into account when prioritizing between new features.
599
 
600
+ ## Changes in 0.13.0
601
+ - Bulk Conversion
602
+ - Fixed problems with Gd converter and PNG
603
+ - Optinally auto convert upon media upload
604
+ - Windows fix (thanks, lwxbr!)
605
+
606
  ## Changes in 0.12.0
607
  - Multisite support (!)
608
  - A new operation mode: "No conversion", if you do not want to use WebP Express for converting. Replaces the old "Just redirect" mode
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.1
7
- Stable tag: 0.12.2
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -93,7 +93,7 @@ Do not simply remove the plugin without deactivating it first. Deactivation take
93
 
94
  == Limitations ==
95
 
96
- * The plugin has not been tested by the developer on Microsoft IIS server. [Some however reports that it works](https://wordpress.org/support/topic/iis-and-webp-works/)
97
 
98
  == Supporting WebP Express ==
99
  Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue wasting time on this plugin:
@@ -333,9 +333,8 @@ And here: https://github.com/rosell-dk/webp-express/issues/166
333
 
334
  Here are rules if you need to replace the file extension with ".webp" rather than appending ".webp" to it: https://www.keycdn.com/support/optimus/configuration-to-deliver-webp
335
 
336
-
337
- = I am on a WAMP stack =
338
- It has been reported that WebP Express *almost* works on WAMP stack. I'd love to debug this, but do not own a Windows server or access to one... Can you help?
339
 
340
  = I am using Jetpack =
341
  If you install Jetpack and enable the "Speed up image load times" then Jetpack will alter the HTML such that images are pointed to their CDN.
@@ -605,6 +604,15 @@ Easy enough! - [Go here!](https://ko-fi.com/rosell). Or [here](https://buymeacof
605
 
606
  == Changelog ==
607
 
 
 
 
 
 
 
 
 
 
608
  = 0.12.2 =
609
  *(released 8 mar 2019)*
610
  * Fixed bug: On some nginx configurations, the newly added protection against directly calling the converter scripts were triggering also when it should not.
@@ -743,6 +751,9 @@ For older releases, check out changelog.txt
743
 
744
  == Upgrade Notice ==
745
 
 
 
 
746
  = 0.12.2 =
747
  * Fixed bug: On some nginx configurations, the newly added protection against directly calling the converter scripts were triggering also when it should not.
748
 
4
  Tags: webp, images, performance
5
  Requires at least: 4.0
6
  Tested up to: 5.1
7
+ Stable tag: 0.13.0
8
  Requires PHP: 5.6
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
93
 
94
  == Limitations ==
95
 
96
+ * The plugin [should now work on Microsoft IIS server](https://github.com/rosell-dk/webp-express/pull/213), but it has not been tested thoroughly.
97
 
98
  == Supporting WebP Express ==
99
  Bread on the table don't come for free, even though this plugin does, and always will. I enjoy developing this, and supporting you guys, but I kind of need the bread too. Please make it possible for me to continue wasting time on this plugin:
333
 
334
  Here are rules if you need to replace the file extension with ".webp" rather than appending ".webp" to it: https://www.keycdn.com/support/optimus/configuration-to-deliver-webp
335
 
336
+ = I am on a Windows server =
337
+ Good news! It should work now, thanks to a guy that calls himself lwxbr. At least on XAMPP 7.3.1, Windows 10. https://github.com/rosell-dk/webp-express/pull/213.
 
338
 
339
  = I am using Jetpack =
340
  If you install Jetpack and enable the "Speed up image load times" then Jetpack will alter the HTML such that images are pointed to their CDN.
604
 
605
  == Changelog ==
606
 
607
+ = 0.13.0 =
608
+ *(released: 21 mar 2019)*
609
+ * Bulk Conversion
610
+ * Fixed problems with Gd converter and PNG
611
+ * Optinally auto convert upon media upload
612
+ * Windows fix (thanks, lwxbr!)
613
+
614
+ For more info, see the closed issues on the 0.13.0 milestone on the github repository: https://github.com/rosell-dk/webp-express/milestone/16?closed=1
615
+
616
  = 0.12.2 =
617
  *(released 8 mar 2019)*
618
  * Fixed bug: On some nginx configurations, the newly added protection against directly calling the converter scripts were triggering also when it should not.
751
 
752
  == Upgrade Notice ==
753
 
754
+ = 0.13.0 =
755
+ * Bulk Conversion, fixed problem with Gd converter and PNGs and more...
756
+
757
  = 0.12.2 =
758
  * Fixed bug: On some nginx configurations, the newly added protection against directly calling the converter scripts were triggering also when it should not.
759
 
changelog.txt CHANGED
@@ -1,3 +1,10 @@
 
 
 
 
 
 
 
1
  = 0.12.2 =
2
  *(released 8 mar 2019)*
3
  * Fixed bug: On some nginx configurations, the newly added protection against directly calling the converter scripts were triggering also when it should not.
1
+ = 0.13.0 =
2
+ *(released: 21 mar 2019)*
3
+ * Bulk Conversion
4
+ * Fixed problems with Gd converter and PNG
5
+ * Optinally auto convert upon media upload
6
+ * Windows fix (thanks, lwxbr!)
7
+
8
  = 0.12.2 =
9
  *(released 8 mar 2019)*
10
  * Fixed bug: On some nginx configurations, the newly added protection against directly calling the converter scripts were triggering also when it should not.
composer.json CHANGED
@@ -15,7 +15,7 @@
15
  }
16
  ],
17
  "require": {
18
- "rosell-dk/webp-convert": "^1.3.3",
19
  "rosell-dk/webp-convert-cloud-service": "^1.0.0",
20
  "rosell-dk/dom-util-for-webp": "^0.3.0"
21
  },
15
  }
16
  ],
17
  "require": {
18
+ "rosell-dk/webp-convert": "^1.3.8",
19
  "rosell-dk/webp-convert-cloud-service": "^1.0.0",
20
  "rosell-dk/dom-util-for-webp": "^0.3.0"
21
  },
lib/activate-first-time.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
-
3
- include_once __DIR__ . '/classes/Actions.php';
4
- use \WebPExpress\Actions;
5
-
6
- include_once __DIR__ . '/classes/CapabilityTest.php';
7
- use \WebPExpress\CapabilityTest;
8
-
9
- include_once __DIR__ . '/classes/Config.php';
10
- use \WebPExpress\Config;
11
-
12
- include_once __DIR__ . '/classes/Messenger.php';
13
- use \WebPExpress\Messenger;
14
-
15
- include_once __DIR__ . '/classes/Paths.php';
16
- use \WebPExpress\Paths;
17
-
18
- include_once __DIR__ . '/classes/PlatformInfo.php';
19
- use \WebPExpress\PlatformInfo;
20
-
21
- include_once __DIR__ . '/classes/State.php';
22
- use \WebPExpress\State;
23
-
24
-
25
- // First check basic requirements.
26
- // -------------------------------
27
-
28
- if (PlatformInfo::isMicrosoftIis()) {
29
- Messenger::addMessage(
30
- 'warning',
31
- 'You are on Microsoft IIS server. The developer of WebP Express has no money for Microsoft products, so no testing have been done on IIS. Use at own risk. If you are on WAMP, things might work. Without Apache, you will need to create redirect rules yourself.'
32
- );
33
- }
34
-
35
-
36
- if ( is_multisite() ) {
37
- Messenger::addMessage(
38
- 'warning',
39
- 'Multisite functionality in WebP Express has just been added with current release (0.12.0). ' .
40
- 'While it has been tested on several setups, there might be a bug or two yet to be found.'
41
- );
42
- }
43
-
44
- if (!version_compare(PHP_VERSION, '5.5.0', '>=')) {
45
- Messenger::addMessage(
46
- 'warning',
47
- 'You are on a very old version of PHP. WebP Express may not work correctly. Your PHP version:' . phpversion()
48
- );
49
- }
50
-
51
- // Next issue warnings, if any
52
- // -------------------------------
53
-
54
- if (PlatformInfo::isApache() || PlatformInfo::isLiteSpeed()) {
55
- // all is well.
56
- } else {
57
- Messenger::addMessage(
58
- 'warning',
59
- 'You are not on Apache server, nor on LiteSpeed. WebP Express only works out of the box on Apache and LiteSpeed.<br>' .
60
- 'But you may get it to work. WebP Express will print you rewrite rules for Apache. You could try to configure your server to do similar routing.<br>' .
61
- 'Btw: your server is: ' . $_SERVER['SERVER_SOFTWARE']
62
- );
63
- }
64
-
65
- // Welcome!
66
- // -------------------------------
67
- Messenger::addMessage(
68
- 'info',
69
- 'WebP Express was installed successfully. To start using it, you must ' .
70
- '<a href="' . Paths::getSettingsUrl() . '">configure it here</a>.'
71
- );
72
-
73
- // While not neccessary, lets get those tests copied right away. Some servers are a bit slow to pick up on changes in the filesystem
74
- CapabilityTest::copyCapabilityTestsToWpContent();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/activate-hook.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- include_once __DIR__ . '/classes/State.php';
4
- use \WebPExpress\State;
5
-
6
- // Test if plugin is activated for the first time, or simply reactivated
7
- if (State::getState('configured', false)) {
8
- include __DIR__ . "/reactivate.php";
9
- } else {
10
- include __DIR__ . "/activate-first-time.php";
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/admin.php DELETED
@@ -1,73 +0,0 @@
1
- <?php
2
- use \WebPExpress\State;
3
- use \WebPExpress\Option;
4
- use \WebPExpress\Multisite;
5
-
6
- // When an update requires a migration, the number should be increased
7
- define('WEBPEXPRESS_MIGRATION_VERSION', '7');
8
-
9
- if (WEBPEXPRESS_MIGRATION_VERSION != Option::getOption('webp-express-migration-version', 0)) {
10
- // run migration logic
11
- include __DIR__ . '/migrate/migrate.php';
12
- }
13
-
14
- // uncomment next line to test-run a migration
15
- //include __DIR__ . '/migrate/migrate7.php';
16
-
17
- // uncomment next line to debug an error during activation
18
- //include __DIR__ . "/debug.php";
19
-
20
- include __DIR__ . '/options/options-hooks.php';
21
-
22
- register_activation_hook(WEBPEXPRESS_PLUGIN, function ($network_active) {
23
- Multisite::overrideIsNetworkActivated($network_active);
24
- include __DIR__ . '/activate-hook.php';
25
- });
26
-
27
- register_deactivation_hook(WEBPEXPRESS_PLUGIN, function () {
28
- include __DIR__ . '/deactivate.php';
29
- });
30
-
31
- if (Option::getOption('webp-express-messages-pending')) {
32
- include_once __DIR__ . '/classes/Messenger.php';
33
-
34
- add_action(Multisite::isNetworkActivated() ? 'network_admin_notices' : 'admin_notices', function() {
35
- \WebPExpress\Messenger::printPendingMessages();
36
- });
37
- }
38
- if (Option::getOption('webp-express-actions-pending')) {
39
- include_once __DIR__ . '/classes/Actions.php';
40
- \WebPExpress\Actions::processQueuedActions();
41
- }
42
-
43
- function webp_express_uninstall() {
44
- include __DIR__ . '/uninstall.php';
45
- }
46
-
47
- // interestingly, I get "Serialization of 'Closure' is not allowed" if I pass anonymous function
48
- // ... perhaps we should not do that in the other hooks either.
49
- register_uninstall_hook(WEBPEXPRESS_PLUGIN, 'webp_express_uninstall');
50
-
51
- // Add settings link on the plugins page
52
- add_filter('plugin_action_links_' . plugin_basename(WEBPEXPRESS_PLUGIN), function ( $links ) {
53
- if (Multisite::isNetworkActivated()) {
54
- $mylinks= [
55
- '<a href="https://ko-fi.com/rosell" target="_blank">donate?</a>',
56
- ];
57
- } else {
58
- $mylinks = array(
59
- '<a href="' . admin_url('options-general.php?page=webp_express_settings_page') . '">Settings</a>',
60
- '<a href="https://ko-fi.com/rosell" target="_blank">Provide coffee for the developer</a>',
61
- );
62
-
63
- }
64
- return array_merge($links, $mylinks);
65
- });
66
-
67
- add_filter('network_admin_plugin_action_links_' . plugin_basename(WEBPEXPRESS_PLUGIN), function ( $links ) {
68
- $mylinks = array(
69
- '<a href="' . network_admin_url('settings.php?page=webp_express_settings_page') . '">Settings</a>',
70
- '<a href="https://ko-fi.com/rosell" target="_blank">donate?</a>',
71
- );
72
- return array_merge($links, $mylinks);
73
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/classes/Actions.php CHANGED
@@ -2,10 +2,8 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once "State.php";
6
- use \WebPExpress\State;
7
-
8
  use \WebPExpress\Option;
 
9
 
10
  /**
11
  *
2
 
3
  namespace WebPExpress;
4
 
 
 
 
5
  use \WebPExpress\Option;
6
+ use \WebPExpress\State;
7
 
8
  /**
9
  *
lib/classes/AdminInit.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ use \WebPExpress\Config;
6
+ use \WebPExpress\State;
7
+ use \WebPExpress\Option;
8
+ use \WebPExpress\Multisite;
9
+
10
+ /**
11
+ *
12
+ */
13
+
14
+ class AdminInit
15
+ {
16
+ public static function init() {
17
+
18
+ self::runMigrationIfNeeded();
19
+
20
+ // uncomment next line to debug an error during activation
21
+ //include __DIR__ . "/../debug.php";
22
+
23
+ if (Option::getOption('webp-express-actions-pending')) {
24
+ \WebPExpress\Actions::processQueuedActions();
25
+ }
26
+
27
+ self::addHooks();
28
+ }
29
+
30
+ public static function runMigrationIfNeeded()
31
+ {
32
+ // When an update requires a migration, the number should be increased
33
+ define('WEBPEXPRESS_MIGRATION_VERSION', '8');
34
+
35
+ if (WEBPEXPRESS_MIGRATION_VERSION != Option::getOption('webp-express-migration-version', 0)) {
36
+ // run migration logic
37
+ include WEBPEXPRESS_PLUGIN_DIR . '/lib/migrate/migrate.php';
38
+ }
39
+
40
+ // uncomment next line to test-run a migration
41
+ //include WEBPEXPRESS_PLUGIN_DIR . '/lib/migrate/migrate8.php';
42
+ }
43
+
44
+ public static function adminInitHandler()
45
+ {
46
+ global $pagenow;
47
+ if ((('options-general.php' === $pagenow) || (('settings.php' === $pagenow))) && (isset($_GET['page'])) && ('webp_express_settings_page' === $_GET['page'])) {
48
+ add_action('admin_enqueue_scripts', array('\WebPExpress\OptionsPage', 'enqueueScripts'));
49
+ }
50
+ }
51
+
52
+ public static function addHooks()
53
+ {
54
+
55
+ // Plugin activation, deactivation and uninstall
56
+ register_activation_hook(WEBPEXPRESS_PLUGIN, array('\WebPExpress\PluginActivate', 'activate'));
57
+ register_deactivation_hook(WEBPEXPRESS_PLUGIN, array('\WebPExpress\PluginDeactivate', 'deactivate'));
58
+ register_uninstall_hook(WEBPEXPRESS_PLUGIN, array('\WebPExpress\PluginUninstall', 'uninstall'));
59
+
60
+ // Hooks related to options page
61
+ if (Multisite::isNetworkActivated()) {
62
+ add_action("network_admin_menu", array('\WebPExpress\AdminUi', 'networAdminMenuHook'));
63
+ } else {
64
+ add_action("admin_menu", array('\WebPExpress\AdminUi', 'adminMenuHook'));
65
+ }
66
+ add_action("admin_post_webpexpress_settings_submit", array('\WebPExpress\OptionsPageHooks', 'submitHandler'));
67
+ add_action("admin_init", array('\WebPExpress\AdminInit', 'adminInitHandler'));
68
+
69
+ // Print pending messages, if any
70
+ if (Option::getOption('webp-express-messages-pending')) {
71
+ add_action(Multisite::isNetworkActivated() ? 'network_admin_notices' : 'admin_notices', array('\WebPExpress\Messenger', 'printPendingMessages'));
72
+ }
73
+
74
+ // Add settings link on the plugins page
75
+ add_filter('plugin_action_links_' . plugin_basename(WEBPEXPRESS_PLUGIN), array('\WebPExpress\AdminUi', 'pluginActionLinksFilter'), 10, 2);
76
+
77
+ // Add settings link in multisite
78
+ add_filter('network_admin_plugin_action_links_' . plugin_basename(WEBPEXPRESS_PLUGIN), array('\WebPExpress\AdminUi', 'networkPluginActionLinksFilter'), 10, 2);
79
+
80
+ // Ajax actions
81
+ add_action('wp_ajax_list_unconverted_files', array('\WebPExpress\BulkConvert', 'processAjaxListUnconvertedFiles'));
82
+ add_action('wp_ajax_convert_file', array('\WebPExpress\BulkConvert', 'processAjaxConvertFile'));
83
+ add_action('wp_ajax_webpexpress_purge_cache', array('\WebPExpress\CachePurge', 'processAjaxPurgeCache'));
84
+
85
+ // Filters for processing upload hooks (in order to convert images upon upload)
86
+ //add_filter('wp_handle_upload', array('\WebPExpress\HandleUploadHooks', 'handleUpload'), 10, 2);
87
+ //add_filter('image_make_intermediate_size', array('\WebPExpress\HandleUploadHooks', 'handleMakeIntermediateSize'), 10, 1);
88
+
89
+ }
90
+ }
lib/classes/AdminUi.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ use \WebPExpress\Multisite;
6
+
7
+ /**
8
+ *
9
+ */
10
+
11
+ class AdminUi
12
+ {
13
+
14
+ // Add settings link on the plugins page
15
+ // The hook was registred in AdminInit
16
+ public static function pluginActionLinksFilter($links)
17
+ {
18
+ if (Multisite::isNetworkActivated()) {
19
+ $mylinks= [
20
+ '<a href="https://ko-fi.com/rosell" target="_blank">donate?</a>',
21
+ ];
22
+ } else {
23
+ $mylinks = array(
24
+ '<a href="' . admin_url('options-general.php?page=webp_express_settings_page') . '">Settings</a>',
25
+ '<a href="https://ko-fi.com/rosell" target="_blank">Provide coffee for the developer</a>',
26
+ );
27
+
28
+ }
29
+ return array_merge($links, $mylinks);
30
+ }
31
+
32
+ // Add settings link in multisite
33
+ // The hook was registred in AdminInit
34
+ public static function networkPluginActionLinksFilter($links)
35
+ {
36
+ $mylinks = array(
37
+ '<a href="' . network_admin_url('settings.php?page=webp_express_settings_page') . '">Settings</a>',
38
+ '<a href="https://ko-fi.com/rosell" target="_blank">donate?</a>',
39
+ );
40
+ return array_merge($links, $mylinks);
41
+ }
42
+
43
+ // callback for 'network_admin_menu' (registred in AdminInit)
44
+ public static function networAdminMenuHook()
45
+ {
46
+ add_submenu_page(
47
+ 'settings.php', // Parent element
48
+ 'WebP Express settings (for network)', // Text in browser title bar
49
+ 'WebP Express', // Text to be displayed in the menu.
50
+ 'manage_network_options', // Capability
51
+ 'webp_express_settings_page', // slug
52
+ array('\WebPExpress\OptionsPage', 'display') // Callback function which displays the page
53
+ );
54
+ }
55
+
56
+ public static function adminMenuHook()
57
+ {
58
+ //Add Settings Page
59
+ add_options_page(
60
+ 'WebP Express Settings', //Page Title
61
+ 'WebP Express', //Menu Title
62
+ 'manage_options', //capability
63
+ 'webp_express_settings_page', // slug
64
+ array('\WebPExpress\OptionsPage', 'display') //The function to be called to output the content for this page.
65
+ );
66
+
67
+ }
68
+ }
lib/classes/AlterHtmlHelper.php CHANGED
@@ -4,14 +4,9 @@ namespace WebPExpress;
4
 
5
  //use AlterHtmlInit;
6
 
7
- include_once "Paths.php";
8
  use \WebPExpress\Paths;
9
-
10
- include_once "PathHelper.php";
11
  use \WebPExpress\PathHelper;
12
-
13
  use \WebPExpress\Multisite;
14
-
15
  use \WebPExpress\Option;
16
 
17
  class AlterHtmlHelper
4
 
5
  //use AlterHtmlInit;
6
 
 
7
  use \WebPExpress\Paths;
 
 
8
  use \WebPExpress\PathHelper;
 
9
  use \WebPExpress\Multisite;
 
10
  use \WebPExpress\Option;
11
 
12
  class AlterHtmlHelper
lib/classes/AlterHtmlImageUrls.php CHANGED
@@ -2,10 +2,8 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once "Paths.php";
6
- use \WebPExpress\Paths;
7
-
8
  use \WebPExpress\AlterHtmlInit;
 
9
 
10
  /**
11
  * Class AlterHtmlImageUrls - convert image urls to webp
2
 
3
  namespace WebPExpress;
4
 
 
 
 
5
  use \WebPExpress\AlterHtmlInit;
6
+ use \WebPExpress\Paths;
7
 
8
  /**
9
  * Class AlterHtmlImageUrls - convert image urls to webp
lib/classes/AlterHtmlInit.php CHANGED
@@ -2,7 +2,6 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once "AlterHtmlHelper.php";
6
  use AlterHtmlHelper;
7
 
8
  use \WebPExpress\Option;
2
 
3
  namespace WebPExpress;
4
 
 
5
  use AlterHtmlHelper;
6
 
7
  use \WebPExpress\Option;
lib/classes/BulkConvert.php ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ use \WebPExpress\ConvertHelperIndependent;
6
+ use \WebPExpress\Paths;
7
+
8
+ class BulkConvert
9
+ {
10
+
11
+ public static function getUploadFolder($destinationFolder)
12
+ {
13
+ switch ($destinationFolder) {
14
+ case 'mingled':
15
+ return Paths::getUploadDirAbs();
16
+ case 'separate':
17
+ return Paths::getCacheDirAbs() . '/doc-root/' . Paths::getUploadDirRel();
18
+ }
19
+ }
20
+
21
+ public static function getList($config)
22
+ {
23
+ //$cacheDir = self::getUploadFolder($config['destination-folder']);
24
+
25
+
26
+ /*
27
+ isUploadDirMovedOutOfWPContentDir
28
+ isUploadDirMovedOutOfAbsPath
29
+ isPluginDirMovedOutOfAbsPath
30
+ isPluginDirMovedOutOfWpContent
31
+ isWPContentDirMovedOutOfAbsPath */
32
+
33
+
34
+ $listOptions = [
35
+ //'root' => Paths::getUploadDirAbs(),
36
+ //'cache-root' => self::getUploadFolder($config['destination-folder']),
37
+ 'ext' => $config['destination-extension'],
38
+ 'destination-folder' => $config['destination-folder'], /* hm, "destination-folder" is a bad name... */
39
+ 'webExpressContentDirAbs' => Paths::getWebPExpressContentDirAbs(),
40
+ 'uploadDirAbs' => Paths::getUploadDirAbs(),
41
+ 'filter' => [
42
+ 'only-converted' => false,
43
+ 'only-unconverted' => true,
44
+ 'image-types' => $config['image-types'],
45
+ ]
46
+ ];
47
+
48
+ $groups = [];
49
+
50
+ $groups[] = [
51
+ 'groupName' => 'wp-content',
52
+ 'root' => Paths::getContentDirAbs(),
53
+ ];
54
+
55
+ if (Paths::isUploadDirMovedOutOfWPContentDir()) {
56
+ $groups[] = [
57
+ 'groupName' => 'uploads',
58
+ 'root' => Paths::getUploadDirAbs(),
59
+ ];
60
+ }
61
+
62
+ if (Paths::isPluginDirMovedOutOfWpContent()) {
63
+ $groups[] = [
64
+ 'groupName' => 'plugins',
65
+ 'root' => Paths::getPluginDirAbs(),
66
+ ];
67
+ }
68
+
69
+ foreach ($groups as $i => &$group) {
70
+ $listOptions['root'] = $group['root'];
71
+ /*
72
+ No use, because if uploads is in wp-content, the cache root will be different for the files in uploads (if mingled)
73
+ $group['cache-root'] = ConvertHelperIndependent::getDestinationFolder(
74
+ $group['root'],
75
+ $listOptions['destination-folder'],
76
+ $listOptions['ext'],
77
+ $listOptions['webExpressContentDirAbs'],
78
+ $listOptions['uploadDirAbs']
79
+ );*/
80
+ $group['files'] = self::getListRecursively('.', $listOptions);
81
+ //'cache-root' => ConvertHelperIndependent::getDestinationFolder()
82
+ }
83
+
84
+
85
+
86
+ return $groups;
87
+ //self::moveRecursively($toDir, $fromDir, $srcDir, $fromExt, $toExt);
88
+ }
89
+
90
+ /**
91
+ * $filter: all | converted | not-converted. "not-converted" for example returns paths to images that has not been converted
92
+ */
93
+ public static function getListRecursively($relDir, &$listOptions)
94
+ {
95
+ $dir = $listOptions['root'] . '/' . $relDir;
96
+
97
+ if (!@file_exists($dir) || !@is_dir($dir)) {
98
+ return [];
99
+ }
100
+
101
+ $fileIterator = new \FilesystemIterator($dir);
102
+
103
+ $results = [];
104
+ $filter = &$listOptions['filter'];
105
+
106
+ while ($fileIterator->valid()) {
107
+ $filename = $fileIterator->getFilename();
108
+
109
+ if (($filename != ".") && ($filename != "..")) {
110
+
111
+ if (@is_dir($dir . "/" . $filename)) {
112
+ $results = array_merge($results, self::getListRecursively($relDir . "/" . $filename, $listOptions));
113
+ } else {
114
+ // its a file - check if its a jpeg or png
115
+
116
+ if (!isset($filter['_regexPattern'])) {
117
+ $imageTypes = $filter['image-types'];
118
+ $fileExtensions = [];
119
+ if ($imageTypes & 1) {
120
+ $fileExtensions[] = 'jpe?g';
121
+ }
122
+ if ($imageTypes & 2) {
123
+ $fileExtensions[] = 'png';
124
+ }
125
+ $filter['_regexPattern'] = '#\.(' . implode('|', $fileExtensions) . ')$#';
126
+ }
127
+
128
+ if (preg_match($filter['_regexPattern'], $filename)) {
129
+ $addThis = true;
130
+
131
+ if (($filter['only-converted']) || ($filter['only-unconverted'])) {
132
+ //$cacheDir = $listOptions['cache-root'] . '/' . $relDir;
133
+ $destination = ConvertHelperIndependent::getDestination(
134
+ $dir . "/" . $filename,
135
+ $listOptions['destination-folder'],
136
+ $listOptions['ext'],
137
+ $listOptions['webExpressContentDirAbs'],
138
+ $listOptions['uploadDirAbs']
139
+ );
140
+ $webpExists = @file_exists($destination);
141
+
142
+ // Check if corresponding webp exists
143
+ /*
144
+ if ($listOptions['ext'] == 'append') {
145
+ $webpExists = @file_exists($cacheDir . "/" . $filename . '.webp');
146
+ } else {
147
+ $webpExists = @file_exists(preg_replace("/\.(jpe?g|png)\.webp$/", '.webp', $filename));
148
+ }*/
149
+
150
+ if (!$webpExists && ($filter['only-converted'])) {
151
+ $addThis = false;
152
+ }
153
+ if ($webpExists && ($filter['only-unconverted'])) {
154
+ $addThis = false;
155
+ }
156
+ } else {
157
+ $addThis = true;
158
+ }
159
+
160
+ if ($addThis) {
161
+ $results[] = substr($relDir . "/", 2) . $filename; // (we cut the leading "./" off with substr)
162
+ }
163
+ }
164
+ }
165
+ }
166
+ $fileIterator->next();
167
+ }
168
+ return $results;
169
+ }
170
+
171
+ /*
172
+ public static function convertFile($source)
173
+ {
174
+ $config = Config::loadConfigAndFix();
175
+ $options = Config::generateWodOptionsFromConfigObj($config);
176
+
177
+ $destination = ConvertHelperIndependent::getDestination(
178
+ $source,
179
+ $options['destination-folder'],
180
+ $options['destination-extension'],
181
+ Paths::getWebPExpressContentDirAbs(),
182
+ Paths::getUploadDirAbs()
183
+ );
184
+ $result = ConvertHelperIndependent::convert($source, $destination, $options);
185
+
186
+ //$result['destination'] = $destination;
187
+ if ($result['success']) {
188
+ $result['filesize-original'] = @filesize($source);
189
+ $result['filesize-webp'] = @filesize($destination);
190
+ }
191
+ return $result;
192
+ }
193
+ */
194
+
195
+ public static function processAjaxListUnconvertedFiles()
196
+ {
197
+ $config = Config::loadConfigAndFix();
198
+ $arr = self::getList($config);
199
+ echo json_encode($arr, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
200
+ wp_die();
201
+ }
202
+
203
+ public static function processAjaxConvertFile()
204
+ {
205
+ $filename = $_POST['filename'];
206
+
207
+ $result = Convert::convertFile($filename);
208
+
209
+ echo json_encode($result, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
210
+ wp_die();
211
+ }
212
+
213
+ }
lib/classes/CacheMover.php CHANGED
@@ -2,10 +2,7 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once "FileHelper.php";
6
  use \WebPExpress\FileHelper;
7
-
8
- include_once "Paths.php";
9
  use \WebPExpress\Paths;
10
 
11
  class CacheMover
@@ -78,6 +75,7 @@ class CacheMover
78
  echo 'ext:' . $fromExt . ' => ' . $toExt . '<br>';
79
  echo '</pre>';*/
80
 
 
81
 
82
  $result = self::moveRecursively($fromDir, $toDir, $srcDir, $fromExt, $toExt);
83
  self::chmodFixSubDirs($toDir, ($newConfig['destination-folder'] == 'separate'));
@@ -95,7 +93,8 @@ class CacheMover
95
  return [0, 0];
96
  }
97
  if (!@file_exists($toDir)) {
98
- if (!@mkdir($toDir)) {
 
99
  return [0, 0];
100
  }
101
  }
2
 
3
  namespace WebPExpress;
4
 
 
5
  use \WebPExpress\FileHelper;
 
 
6
  use \WebPExpress\Paths;
7
 
8
  class CacheMover
75
  echo 'ext:' . $fromExt . ' => ' . $toExt . '<br>';
76
  echo '</pre>';*/
77
 
78
+ //error_log('move to:' . $toDir . ' ( ' . (file_exists($toDir) ? 'exists' : 'does not exist ') . ')');
79
 
80
  $result = self::moveRecursively($fromDir, $toDir, $srcDir, $fromExt, $toExt);
81
  self::chmodFixSubDirs($toDir, ($newConfig['destination-folder'] == 'separate'));
93
  return [0, 0];
94
  }
95
  if (!@file_exists($toDir)) {
96
+ // Note: 0777 is default. Default umask is 0022, so the default result is 0755
97
+ if (!@mkdir($toDir, 0777, true)) {
98
  return [0, 0];
99
  }
100
  }
lib/classes/CachePurge.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ use \WebPExpress\Convert;
6
+ use \WebPExpress\FileHelper;
7
+ use \WebPExpress\Paths;
8
+
9
+ class CachePurge
10
+ {
11
+
12
+ /**
13
+ * - Removes cache dir
14
+ * - Removes all files with ".webp" extension in upload dir (if set to mingled)
15
+ */
16
+ public static function purge($config, $onlyPng)
17
+ {
18
+ $filter = [
19
+ 'only-png' => $onlyPng,
20
+ 'only-with-corresponding-original' => false
21
+ ];
22
+
23
+ $numDeleted = 0;
24
+ $numFailed = 0;
25
+
26
+ list($numDeleted, $numFailed) = self::purgeWebPFilesInDir(Paths::getCacheDirAbs(), $filter, $config);
27
+
28
+ if ($config['destination-folder'] == 'mingled') {
29
+ list($d, $f) = self::purgeWebPFilesInDir(Paths::getUploadDirAbs(), $filter, $config);
30
+
31
+ $numDeleted += $d;
32
+ $numFailed += $f;
33
+ }
34
+
35
+ return [
36
+ 'delete-count' => $numDeleted,
37
+ 'fail-count' => $numFailed
38
+ ];
39
+
40
+ //$successInRemovingCacheDir = FileHelper::rrmdir(Paths::getCacheDirAbs());
41
+
42
+ }
43
+
44
+
45
+ /**
46
+ * Purge webp files in a dir
47
+ * Warning: the "only-png" option only works for mingled mode.
48
+ * (when not mingled, you can simply delete the whole cache dir instead)
49
+ *
50
+ * @param $filter.
51
+ * only-png: If true, it will only be deleted if extension is .png.webp or a corresponding png exists.
52
+ *
53
+ * @return [num files deleted, num files failed to delete]
54
+ */
55
+ public static function purgeWebPFilesInDir($dir, &$filter, &$config)
56
+ {
57
+ if (!@file_exists($dir) || !@is_dir($dir)) {
58
+ return [0, 0];
59
+ }
60
+
61
+ $numFilesDeleted = 0;
62
+ $numFilesFailedDeleting = 0;
63
+
64
+ $fileIterator = new \FilesystemIterator($dir);
65
+ while ($fileIterator->valid()) {
66
+ $filename = $fileIterator->getFilename();
67
+
68
+ if (($filename != ".") && ($filename != "..")) {
69
+
70
+ if (@is_dir($dir . "/" . $filename)) {
71
+ list($r1, $r2) = self::purgeWebPFilesInDir($dir . "/" . $filename, $filter, $config);
72
+ $numFilesDeleted += $r1;
73
+ $numFilesFailedDeleting += $r2;
74
+ } else {
75
+
76
+ // its a file
77
+ // Run through filters, which each may set "skipThis" to true
78
+
79
+ $skipThis = false;
80
+
81
+ // filter: It must be a webp
82
+ if (!$skipThis && !preg_match('#\.webp$#', $filename)) {
83
+ $skipThis = true;
84
+ }
85
+
86
+ // filter: only with corresponding original
87
+ $source = '';
88
+ if (!$skipThis && $filter['only-with-corresponding-original']) {
89
+ $source = Convert::findSource($dir . "/" . $filename, $config);
90
+ if ($source === false) {
91
+ $skipThis = true;
92
+ }
93
+ }
94
+
95
+ // filter: only png
96
+ if (!$skipThis && $filter['only-png']) {
97
+
98
+ // turn logic around - we skip deletion, unless we deem it a png
99
+ $skipThis = true;
100
+
101
+ // If extension is "png.webp", its a png
102
+ if (preg_match('#\.png\.webp$#', $filename)) {
103
+ // its a png
104
+ $skipThis = false;
105
+ } else {
106
+ if (preg_match('#\.jpe?g\.webp$#', $filename)) {
107
+ // It is a jpeg, no need to investigate further.
108
+ } else {
109
+
110
+ if (!$filter['only-with-corresponding-original']) {
111
+ $source = Convert::findSource($dir . "/" . $filename, $config);
112
+ }
113
+ if ($source === false) {
114
+ // We could not find corresponding source.
115
+ // Should we delete?
116
+ // No, I guess we need more evidence, so we skip
117
+ // In the future, we could detect mime
118
+ } else {
119
+ if (preg_match('#\.png$#', $source)) {
120
+ // its a png
121
+ $skipThis = false;
122
+ }
123
+ }
124
+ }
125
+
126
+ }
127
+
128
+ }
129
+
130
+ if (!$skipThis) {
131
+ if (@unlink($dir . "/" . $filename)) {
132
+ $numFilesDeleted++;
133
+ } else {
134
+ $numFilesFailedDeleting++;
135
+ }
136
+ }
137
+ }
138
+ }
139
+ $fileIterator->next();
140
+ }
141
+ return [$numFilesDeleted, $numFilesFailedDeleting];
142
+ }
143
+
144
+ public static function processAjaxPurgeCache()
145
+ {
146
+
147
+ $onlyPng = ($_POST['only-png'] == 'true');
148
+
149
+ $config = Config::loadConfigAndFix();
150
+ $result = self::purge($config, $onlyPng);
151
+
152
+ echo json_encode($result, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK | JSON_PRETTY_PRINT);
153
+ wp_die();
154
+ }
155
+ }
lib/classes/Config.php CHANGED
@@ -2,27 +2,13 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once "ConvertersHelper.php";
6
  use \WebPExpress\ConvertersHelper;
7
-
8
- include_once "FileHelper.php";
9
  use \WebPExpress\FileHelper;
10
-
11
- include_once "HTAccess.php";
12
  use \WebPExpress\HTAccess;
13
-
14
- include_once "Messenger.php";
15
  use \WebPExpress\Messenger;
16
-
17
- include_once "Paths.php";
18
  use \WebPExpress\Paths;
19
-
20
- include_once "State.php";
21
  use \WebPExpress\State;
22
-
23
- include_once "TestRun.php";
24
  use \WebPExpress\TestRun;
25
-
26
  use \WebPExpress\Option;
27
 
28
  class Config
@@ -71,9 +57,17 @@ class Config
71
 
72
  'operation-mode' => 'varied-image-responses',
73
 
 
 
 
 
 
 
 
 
 
74
  // redirection rules
75
  'enable-redirection-to-converter' => true,
76
- 'image-types' => 1,
77
  'only-redirect-to-converter-on-cache-miss' => false,
78
  'only-redirect-to-converter-for-webp-enabled-browsers' => true,
79
  'do-not-pass-source-in-query-string' => false, // In 0.13 we can remove this. migration7.php depends on it
@@ -87,14 +81,9 @@ class Config
87
  'max-quality' => 80,
88
  'quality-specific' => 70,
89
  'metadata' => 'none',
90
- 'destination-folder' => 'separate',
91
- 'destination-extension' => 'append',
92
 
93
  // serve options
94
- 'cache-control' => 'no-header', /* can be "no-header", "set" or "custom" */
95
- 'cache-control-custom' => 'public, max-age:86400, stale-while-revalidate=604800, stale-if-error=604800',
96
- 'cache-control-max-age' => 'one-week',
97
- 'cache-control-public' => false,
98
  'fail' => 'original',
99
  'success-response' => 'converted',
100
 
@@ -299,13 +288,6 @@ class Config
299
  return self::$configForOptionsPage;
300
  }
301
 
302
- // Test converters
303
- $testResult = TestRun::getConverterStatus();
304
- $workingConverters = [];
305
- if ($testResult) {
306
- $workingConverters = $testResult['workingConverters'];
307
- //print_r($testResult);
308
- }
309
 
310
  $config = self::loadConfigAndFix();
311
 
@@ -326,53 +308,59 @@ class Config
326
  }
327
  }
328
 
329
- // Set "working" and "error" properties
330
- if ($testResult) {
331
- foreach ($config['converters'] as &$converter) {
332
- $converterId = $converter['converter'];
333
- $hasError = isset($testResult['errors'][$converterId]);
334
- $working = !$hasError;
335
-
336
- /*
337
- Don't print this stuff here. It can end up in the head tag.
338
- TODO: Move it somewhere
339
- if (isset($converter['working']) && ($converter['working'] != $working)) {
340
-
341
- // TODO: webpexpress_converterName($converterId)
342
- if ($working) {
343
- Messenger::printMessage(
344
- 'info',
345
- 'Hurray! - The <i>' . $converterId . '</i> conversion method is working now!'
346
- );
347
- } else {
348
- Messenger::printMessage(
349
- 'warning',
350
- 'Sad news. The <i>' . $converterId . '</i> conversion method is not working anymore. What happened?'
351
- );
352
- }
353
- }
354
- */
355
- $converter['working'] = $working;
356
- if ($hasError) {
357
- $error = $testResult['errors'][$converterId];
358
- if ($converterId == 'wpc') {
359
- if (preg_match('/Missing URL/', $error)) {
360
- $error = 'Not configured';
361
- }
362
- if ($error == 'No remote host has been set up') {
363
- $error = 'Not configured';
364
- }
365
 
366
- if (preg_match('/cloud service is not enabled/', $error)) {
367
- $error = 'The server is not enabled. Click the "Enable web service" on WebP Express settings on the site you are trying to connect to.';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  }
369
  }
370
- $converter['error'] = $error;
371
- } else {
372
- unset($converter['error']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
373
  }
374
  }
375
  }
 
376
  self::$configForOptionsPage = $config; // cache the result
377
  return $config;
378
  }
@@ -534,6 +522,7 @@ class Config
534
  unset($options['only-redirect-to-converter-for-webp-enabled-browsers']);
535
  unset($options['only-redirect-to-converter-on-cache-miss']);
536
  unset($options['enable-redirection-to-webp-realizer']);
 
537
 
538
 
539
  //unset($options['']);
2
 
3
  namespace WebPExpress;
4
 
 
5
  use \WebPExpress\ConvertersHelper;
 
 
6
  use \WebPExpress\FileHelper;
 
 
7
  use \WebPExpress\HTAccess;
 
 
8
  use \WebPExpress\Messenger;
 
 
9
  use \WebPExpress\Paths;
 
 
10
  use \WebPExpress\State;
 
 
11
  use \WebPExpress\TestRun;
 
12
  use \WebPExpress\Option;
13
 
14
  class Config
57
 
58
  'operation-mode' => 'varied-image-responses',
59
 
60
+ // general
61
+ 'image-types' => 1,
62
+ 'destination-folder' => 'separate',
63
+ 'destination-extension' => 'append',
64
+ 'cache-control' => 'no-header', /* can be "no-header", "set" or "custom" */
65
+ 'cache-control-custom' => 'public, max-age:86400, stale-while-revalidate=604800, stale-if-error=604800',
66
+ 'cache-control-max-age' => 'one-week',
67
+ 'cache-control-public' => false,
68
+
69
  // redirection rules
70
  'enable-redirection-to-converter' => true,
 
71
  'only-redirect-to-converter-on-cache-miss' => false,
72
  'only-redirect-to-converter-for-webp-enabled-browsers' => true,
73
  'do-not-pass-source-in-query-string' => false, // In 0.13 we can remove this. migration7.php depends on it
81
  'max-quality' => 80,
82
  'quality-specific' => 70,
83
  'metadata' => 'none',
84
+ 'convert-on-upload' => true,
 
85
 
86
  // serve options
 
 
 
 
87
  'fail' => 'original',
88
  'success-response' => 'converted',
89
 
288
  return self::$configForOptionsPage;
289
  }
290
 
 
 
 
 
 
 
 
291
 
292
  $config = self::loadConfigAndFix();
293
 
308
  }
309
  }
310
 
311
+ if ($config['operation-mode'] != 'no-conversion') {
312
+ // Test converters
313
+ $testResult = TestRun::getConverterStatus();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
 
315
+ // Set "working" and "error" properties
316
+ if ($testResult) {
317
+ foreach ($config['converters'] as &$converter) {
318
+ $converterId = $converter['converter'];
319
+ $hasError = isset($testResult['errors'][$converterId]);
320
+ $working = !$hasError;
321
+
322
+ /*
323
+ Don't print this stuff here. It can end up in the head tag.
324
+ TODO: Move it somewhere
325
+ if (isset($converter['working']) && ($converter['working'] != $working)) {
326
+
327
+ // TODO: webpexpress_converterName($converterId)
328
+ if ($working) {
329
+ Messenger::printMessage(
330
+ 'info',
331
+ 'Hurray! - The <i>' . $converterId . '</i> conversion method is working now!'
332
+ );
333
+ } else {
334
+ Messenger::printMessage(
335
+ 'warning',
336
+ 'Sad news. The <i>' . $converterId . '</i> conversion method is not working anymore. What happened?'
337
+ );
338
  }
339
  }
340
+ */
341
+ $converter['working'] = $working;
342
+ if ($hasError) {
343
+ $error = $testResult['errors'][$converterId];
344
+ if ($converterId == 'wpc') {
345
+ if (preg_match('/Missing URL/', $error)) {
346
+ $error = 'Not configured';
347
+ }
348
+ if ($error == 'No remote host has been set up') {
349
+ $error = 'Not configured';
350
+ }
351
+
352
+ if (preg_match('/cloud service is not enabled/', $error)) {
353
+ $error = 'The server is not enabled. Click the "Enable web service" on WebP Express settings on the site you are trying to connect to.';
354
+ }
355
+ }
356
+ $converter['error'] = $error;
357
+ } else {
358
+ unset($converter['error']);
359
+ }
360
  }
361
  }
362
  }
363
+
364
  self::$configForOptionsPage = $config; // cache the result
365
  return $config;
366
  }
522
  unset($options['only-redirect-to-converter-for-webp-enabled-browsers']);
523
  unset($options['only-redirect-to-converter-on-cache-miss']);
524
  unset($options['enable-redirection-to-webp-realizer']);
525
+ unset($options['convert-on-upload']);
526
 
527
 
528
  //unset($options['']);
lib/classes/Convert.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ This class is made to be independent of other classes, and must be kept like that.
5
+ It is used by webp-on-demand.php, which does not register an auto loader. It is also used for bulk conversion.
6
+ */
7
+ namespace WebPExpress;
8
+
9
+ use \WebPExpress\ConvertHelperIndependent;
10
+
11
+ class Convert
12
+ {
13
+
14
+ public static function getDestination($source, &$config = null)
15
+ {
16
+ if (is_null($config)) {
17
+ $config = Config::loadConfigAndFix();
18
+ }
19
+ return ConvertHelperIndependent::getDestination(
20
+ $source,
21
+ $config['destination-folder'],
22
+ $config['destination-extension'],
23
+ Paths::getWebPExpressContentDirAbs(),
24
+ Paths::getUploadDirAbs()
25
+ );
26
+ }
27
+
28
+ public static function convertFile($source, $config = null)
29
+ {
30
+ if (is_null($config)) {
31
+ $config = Config::loadConfigAndFix();
32
+ }
33
+ $options = Config::generateWodOptionsFromConfigObj($config);
34
+
35
+ $destination = self::getDestination($source, $config);
36
+
37
+ $result = ConvertHelperIndependent::convert($source, $destination, $options);
38
+
39
+ //$result['destination'] = $destination;
40
+ if ($result['success']) {
41
+ $result['filesize-original'] = @filesize($source);
42
+ $result['filesize-webp'] = @filesize($destination);
43
+ }
44
+ return $result;
45
+ }
46
+
47
+ public static function findSource($destination, &$config = null)
48
+ {
49
+ if (is_null($config)) {
50
+ $config = Config::loadConfigAndFix();
51
+ }
52
+ return ConvertHelperIndependent::findSource(
53
+ $destination,
54
+ $config['destination-folder'],
55
+ $config['destination-extension'],
56
+ Paths::getWebPExpressContentDirAbs()
57
+ );
58
+ }
59
+
60
+ }
lib/classes/ConvertHelperIndependent.php ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ This class is made to be independent of other classes, and must be kept like that.
5
+ It is used by webp-on-demand.php, which does not register an auto loader. It is also used for bulk conversion.
6
+ */
7
+ namespace WebPExpress;
8
+
9
+ use \WebPConvert\WebPConvert;
10
+ use \WebPConvert\Loggers\BufferLogger;
11
+ use \WebPExpress\FileHelper;
12
+
13
+
14
+ class ConvertHelperIndependent
15
+ {
16
+
17
+ public static function storeMingledOrNot($source, $destinationFolder, $uploadDirAbs)
18
+ {
19
+ if ($destinationFolder != 'mingled') {
20
+ return false;
21
+ }
22
+
23
+ // Option is set for mingled, but this does not neccessarily means we should store "mingled".
24
+ // - because the mingled option only applies to upload folder, the rest is stored in separate cache folder
25
+ // So, return true, if $source is located in upload folder
26
+ return (strpos($source, $uploadDirAbs) === 0);
27
+ }
28
+
29
+ /**
30
+ * Verify if source is inside in document root
31
+ * Note: This function relies on the existence of both.
32
+ *
33
+ * @return true if windows; false if not.
34
+ */
35
+ public static function sourceIsInsideDocRoot($source, $docRoot){
36
+
37
+ $normalizedSource = realpath($source);
38
+ $normalizedDocRoot = realpath($docRoot);
39
+
40
+ return strpos($normalizedSource, $normalizedDocRoot) === 0;
41
+ }
42
+
43
+ /*
44
+ public static function getDestinationFolder($sourceDir, $destinationFolder, $destinationExt, $webExpressContentDirAbs, $uploadDirAbs)
45
+ {
46
+ if (self::storeMingledOrNot($sourceDir, $destinationFolder, $uploadDirAbs)) {
47
+ return $sourceDir;
48
+ } else {
49
+
50
+ $docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
51
+ $imageRoot = $webExpressContentDirAbs . '/webp-images';
52
+
53
+ // Check if source dir is residing inside document root.
54
+ // (it is, if path starts with document root + '/')
55
+ if (substr($sourceDir, 0, strlen($docRoot) + 1) === $docRoot . '/') {
56
+
57
+ // We store relative to document root.
58
+ // "Eat" the left part off the source parameter which contains the document root.
59
+ // and also eat the slash (+1)
60
+ $sourceDirRel = substr($sourceDir, strlen($docRoot) + 1);
61
+ return $imageRoot . '/doc-root/' . $sourceDirRel;
62
+ } else {
63
+ // Source file is residing outside document root.
64
+ // we must add complete path to structure
65
+ return $imageRoot . '/abs' . $sourceDir;
66
+ }
67
+ }
68
+ }*/
69
+
70
+ /**
71
+ * Get destination from source (and some configurations)
72
+ */
73
+ public static function getDestination($source, $destinationFolder, $destinationExt, $webExpressContentDirAbs, $uploadDirAbs)
74
+ {
75
+ if (self::storeMingledOrNot($source, $destinationFolder, $uploadDirAbs)) {
76
+ if ($destinationExt == 'append') {
77
+ return $source . '.webp';
78
+ } else {
79
+ return preg_replace('/\\.(jpe?g|png)$/', '', $source) . '.webp';
80
+ }
81
+ } else {
82
+
83
+ $docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
84
+ $imageRoot = $webExpressContentDirAbs . '/webp-images';
85
+
86
+ // Check if source is residing inside document root.
87
+ // (it is, if path starts with document root + '/')
88
+ if (self::sourceIsInsideDocRoot($source, $docRoot) ) {
89
+
90
+ // We store relative to document root.
91
+ // "Eat" the left part off the source parameter which contains the document root.
92
+ // and also eat the slash (+1)
93
+ $sourceRel = substr($source, strlen($docRoot) + 1);
94
+ return $imageRoot . '/doc-root/' . $sourceRel . '.webp';
95
+ } else {
96
+ // Source file is residing outside document root.
97
+ // we must add complete path to structure
98
+ return $imageRoot . '/abs' . $source . '.webp';
99
+ }
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Find source corresponding to destination, separate
105
+ * We can rely on destinationExt being "append" for separate
106
+ * Returns false if not found. Otherwise returns path to source
107
+ */
108
+ private static function findSourceSeparate($destination, $webExpressContentDirAbs)
109
+ {
110
+ $imageRoot = $webExpressContentDirAbs . '/webp-images';
111
+
112
+ // Check if destination is residing inside "doc-root" folder
113
+ // TODO: This does not work on Windows yet.
114
+ // NOTE: WE CANNOT DO AS WITH sourceIsInsideDocRoot, because it relies on realpath, which only translates EXISTING paths.
115
+ // $destination does not exist yet, when this method is called from webp-realizer.php
116
+ if (strpos($destination, $imageRoot . '/doc-root/') === 0) {
117
+
118
+ $imageRoot .= '/doc-root';
119
+ // "Eat" the left part off the $destination parameter. $destination is for example:
120
+ // "/var/www/webp-express-tests/we0/wp-content-moved/webp-express/webp-images/doc-root/wordpress/uploads-moved/2018/12/tegning5-300x265.jpg.webp"
121
+ // We also eat the slash (+1)
122
+ $sourceRel = substr($destination, strlen($imageRoot) + 1);
123
+
124
+ $docRoot = rtrim(realpath($_SERVER["DOCUMENT_ROOT"]), '/');
125
+ $source = $docRoot . '/' . $sourceRel;
126
+ $source = preg_replace('/\\.(webp)$/', '', $source);
127
+ } else {
128
+ $imageRoot .= '/abs';
129
+ $sourceRel = substr($destination, strlen($imageRoot) + 1);
130
+ $source = $sourceRel;
131
+ $source = preg_replace('/\\.(webp)$/', '', $source);
132
+ }
133
+ if (!@file_exists($source)) {
134
+ return false;
135
+ }
136
+ return $source;
137
+ }
138
+
139
+ /**
140
+ * Find source corresponding to destination (mingled)
141
+ * Returns false if not found. Otherwise returns path to source
142
+ */
143
+ private static function findSourceMingled($destination, $destinationExt)
144
+ {
145
+ global $options;
146
+ global $destination;
147
+ if ($destinationExt == 'append') {
148
+ $source = preg_replace('/\\.(webp)$/', '', $destination);
149
+ } else {
150
+ $source = preg_replace('/\\.webp$/', '.jpg', $destination);
151
+ if (!@file_exists($source)) {
152
+ $source = preg_replace('/\\.webp$/', '.jpeg', $destination);
153
+ }
154
+ if (!@file_exists($source)) {
155
+ $source = preg_replace('/\\.webp$/', '.png', $destination);
156
+ }
157
+ }
158
+ if (!@file_exists($source)) {
159
+ return false;
160
+ }
161
+ return $source;
162
+ }
163
+
164
+ /**
165
+ * Get source from destination (and some configurations)
166
+ * Returns false if not found. Otherwise returns path to source
167
+ */
168
+ public static function findSource($destination, $destinationFolder, $destinationExt, $webExpressContentDirAbs)
169
+ {
170
+ if ($destinationFolder == 'mingled') {
171
+ $result = self::findSourceMingled($destination, $destinationExt);
172
+ if ($result === false) {
173
+ $result = self::findSourceSeparate($destination, $webExpressContentDirAbs);
174
+ }
175
+ return $result;
176
+ } else {
177
+ return self::findSourceSeparate($destination, $webExpressContentDirAbs);
178
+ }
179
+ }
180
+
181
+ public static function convert($source, $destination, $options) {
182
+ include_once __DIR__ . '/../../vendor/autoload.php';
183
+
184
+ $success = false;
185
+ $msg = '';
186
+ $logger = new BufferLogger();
187
+ try {
188
+ $success = WebPConvert::convert($source, $destination, $options, $logger);
189
+ } catch (\Exception $e) {
190
+ $msg = $e->getMessage();
191
+ }
192
+
193
+ return [
194
+ 'success' => $success,
195
+ 'msg' => $msg,
196
+ 'log' => $logger->getHtml(),
197
+ ];
198
+
199
+ }
200
+
201
+ }
lib/classes/ConvertersHelper.php CHANGED
@@ -5,7 +5,9 @@ namespace WebPExpress;
5
  class ConvertersHelper
6
  {
7
  public static $defaultConverters = [
8
- ['converter' => 'gd', 'options' => ['skip-pngs' => true]],
 
 
9
  ['converter' => 'cwebp', 'options' => [
10
  'use-nice' => true,
11
  'try-common-system-paths' => true,
5
  class ConvertersHelper
6
  {
7
  public static $defaultConverters = [
8
+ ['converter' => 'gd', 'options' => [
9
+ 'skip-pngs' => false
10
+ ]],
11
  ['converter' => 'cwebp', 'options' => [
12
  'use-nice' => true,
13
  'try-common-system-paths' => true,
lib/classes/FileHelper.php CHANGED
@@ -73,6 +73,9 @@ class FileHelper
73
  }
74
 
75
  public static function chmod_r($dir, $dirPerm = null, $filePerm = null, $uid = null, $gid = null, $regexFileMatchPattern = null, $regexDirMatchPattern = null) {
 
 
 
76
  $fileIterator = new \FilesystemIterator($dir);
77
 
78
  while ($fileIterator->valid()) {
@@ -149,7 +152,7 @@ class FileHelper
149
  if (!@file_exists($dirName)) {
150
  return false;
151
  }
152
- if (@is_writable($dirName) && @is_executable($dirName)) {
153
  return true;
154
  }
155
 
@@ -297,4 +300,27 @@ class FileHelper
297
  }
298
  return $success;
299
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  }
73
  }
74
 
75
  public static function chmod_r($dir, $dirPerm = null, $filePerm = null, $uid = null, $gid = null, $regexFileMatchPattern = null, $regexDirMatchPattern = null) {
76
+ if (!@file_exists($dir) || (!@is_dir($dir))) {
77
+ return;
78
+ }
79
  $fileIterator = new \FilesystemIterator($dir);
80
 
81
  while ($fileIterator->valid()) {
152
  if (!@file_exists($dirName)) {
153
  return false;
154
  }
155
+ if (@is_writable($dirName) && @is_executable($dirName) || self::isWindows() ) {
156
  return true;
157
  }
158
 
300
  }
301
  return $success;
302
  }
303
+
304
+
305
+ /**
306
+ * Verify if OS is Windows
307
+ *
308
+ *
309
+ * @return true if windows; false if not.
310
+ */
311
+ public static function isWindows(){
312
+ return (boolean) preg_match('/^win/i', PHP_OS);
313
+ }
314
+
315
+
316
+ /**
317
+ * Normalize separators of directory paths
318
+ *
319
+ *
320
+ * @return $normalized_path
321
+ */
322
+ public static function normalizeSeparator($path, $newSeparator = DIRECTORY_SEPARATOR){
323
+ return preg_replace("#[\\\/]+#", $newSeparator, $path);
324
+ }
325
+
326
  }
lib/classes/HTAccess.php CHANGED
@@ -2,16 +2,9 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once "Config.php";
6
  use \WebPExpress\Config;
7
-
8
- include_once "FileHelper.php";
9
  use \WebPExpress\FileHelper;
10
-
11
- include_once "Paths.php";
12
  use \WebPExpress\Paths;
13
-
14
- include_once "State.php";
15
  use \WebPExpress\State;
16
 
17
  class HTAccess
@@ -734,6 +727,7 @@ class HTAccess
734
  if ($config['operation-mode'] != 'no-conversion') {
735
  if ($config['image-types'] != 0) {
736
  $webpExpressRoot = Paths::getPluginUrlPath();
 
737
  if ($config['enable-redirection-to-converter']) {
738
  $links = '<br>';
739
  $links .= '<a href="/' . $webpExpressRoot . '/test/test.jpg?debug&time=' . time() . '" target="_blank">Convert test image (show debug)</a><br>';
2
 
3
  namespace WebPExpress;
4
 
 
5
  use \WebPExpress\Config;
 
 
6
  use \WebPExpress\FileHelper;
 
 
7
  use \WebPExpress\Paths;
 
 
8
  use \WebPExpress\State;
9
 
10
  class HTAccess
727
  if ($config['operation-mode'] != 'no-conversion') {
728
  if ($config['image-types'] != 0) {
729
  $webpExpressRoot = Paths::getPluginUrlPath();
730
+ $links = '';
731
  if ($config['enable-redirection-to-converter']) {
732
  $links = '<br>';
733
  $links .= '<a href="/' . $webpExpressRoot . '/test/test.jpg?debug&time=' . time() . '" target="_blank">Convert test image (show debug)</a><br>';
lib/classes/HandleUploadHooks.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ use \WebPExpress\Config;
6
+ use \WebPExpress\Convert;
7
+
8
+ class HandleUploadHooks
9
+ {
10
+
11
+ private static $config;
12
+
13
+
14
+ private static function getMimeTypeOfMedia($filename)
15
+ {
16
+ // Try the Wordpress function. It tries exif_imagetype and getimagesize and returns false if no methods are available
17
+ $mimeType = wp_get_image_mime($filename);
18
+ if ($mimeType !== false) {
19
+ return $mimeType;
20
+ }
21
+
22
+ // Try mime_content_type
23
+ if (function_exists('mime_content_type')) {
24
+ $mimeType = mime_content_type($filename);
25
+ if ($mimeType !== false) {
26
+ return $mimeType;
27
+ }
28
+ }
29
+
30
+ // Try wordpress method, which simply uses the file extension and a map
31
+ $mimeType = wp_check_filetype($filePath)['type'];
32
+ if ($mimeType !== false) {
33
+ return $mimeType;
34
+ }
35
+
36
+ // Don't say we didn't try!
37
+ return 'unknown';
38
+ }
39
+
40
+ /**
41
+ * Convert if:
42
+ * - Option has been enabled
43
+ * - We are not in "No conversion" mode
44
+ * - The mime type is one of the ones the user has activated (in config)
45
+ */
46
+ private static function convertIf($filename)
47
+ {
48
+ if (!isset(self::$config)) {
49
+ self::$config = Config::loadConfigAndFix();
50
+ }
51
+
52
+ $config = &self::$config;
53
+
54
+ if (!$config['convert-on-upload']) {
55
+ return;
56
+ }
57
+ if ($config['operation-mode'] == 'no-conversion') {
58
+ return;
59
+ }
60
+
61
+ //$mimeType = getimagesize($filename)['mime'];
62
+
63
+ $allowedMimeTypes = [];
64
+ $imageTypes = $config['image-types'];
65
+ if ($imageTypes & 1) {
66
+ $allowedMimeTypes[] = 'image/jpeg';
67
+ $allowedMimeTypes[] = 'image/jpg'; /* don't think "image/jpg" is neccessary, but just in case */
68
+ }
69
+ if ($imageTypes & 2) {
70
+ $allowedMimeTypes[] = 'image/png';
71
+ }
72
+
73
+ if (!in_array(self::getMimeTypeOfMedia($filename), $allowedMimeTypes)) {
74
+ return;
75
+ }
76
+
77
+ Convert::convertFile($filename, $config);
78
+
79
+ }
80
+
81
+ /**
82
+ * hook: handle_upload
83
+ * $filename is ie "/var/www/webp-express-tests/we0/wordpress/uploads-moved/image4-10-150x150.jpg"
84
+ */
85
+ public static function handleUpload($filearray, $overrides, $ignore = false)
86
+ {
87
+ $filename = $filearray['file'];
88
+ self::convertIf($filename);
89
+
90
+ return $filearray;
91
+ }
92
+
93
+ /**
94
+ * hook: image_make_intermediate_size
95
+ * $filename is ie "/var/www/webp-express-tests/we0/wordpress/uploads-moved/image4-10-150x150.jpg"
96
+ */
97
+ public static function handleMakeIntermediateSize($filename)
98
+ {
99
+ self::convertIf($filename);
100
+ return $filename;
101
+ }
102
+ }
lib/classes/Messenger.php CHANGED
@@ -2,10 +2,8 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once "State.php";
6
- use \WebPExpress\State;
7
-
8
  use \WebPExpress\Option;
 
9
 
10
  class Messenger
11
  {
2
 
3
  namespace WebPExpress;
4
 
 
 
 
5
  use \WebPExpress\Option;
6
+ use \WebPExpress\State;
7
 
8
  class Messenger
9
  {
lib/classes/OptionsPage.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ /**
6
+ *
7
+ */
8
+
9
+ class OptionsPage
10
+ {
11
+
12
+ // callback (registred in AdminUi)
13
+ public static function display() {
14
+ include WEBPEXPRESS_PLUGIN_DIR . '/lib/options/page.php';
15
+ }
16
+
17
+ public static function enqueueScripts() {
18
+ include WEBPEXPRESS_PLUGIN_DIR . '/lib/options/enqueue_scripts.php';
19
+ }
20
+ }
lib/classes/OptionsPageHooks.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ /**
6
+ *
7
+ */
8
+
9
+ class OptionsPageHooks
10
+ {
11
+
12
+ // callback for 'admin_post_webpexpress_settings_submit' (registred in AdminInit::addHooks)
13
+ public static function submitHandler() {
14
+ include WEBPEXPRESS_PLUGIN_DIR . '/lib/options/submit.php';
15
+ }
16
+ }
lib/classes/Paths.php CHANGED
@@ -2,13 +2,9 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once "PathHelper.php";
6
- use \WebPExpress\PathHelper;
7
-
8
- include_once "FileHelper.php";
9
  use \WebPExpress\FileHelper;
10
-
11
  use \WebPExpress\Multisite;
 
12
 
13
  class Paths
14
  {
@@ -117,7 +113,8 @@ class Paths
117
  return false;
118
  }
119
 
120
- // ------------ WP Content Dir -------------
 
121
  public static function getContentDirAbs()
122
  {
123
  return self::getAbsDir(WP_CONTENT_DIR);
@@ -138,7 +135,7 @@ class Paths
138
  }
139
 
140
 
141
- // ------------ Content Dir -------------
142
  // (the "webp-express" directory inside wp-content)
143
 
144
  public static function getWebPExpressContentDirAbs()
2
 
3
  namespace WebPExpress;
4
 
 
 
 
 
5
  use \WebPExpress\FileHelper;
 
6
  use \WebPExpress\Multisite;
7
+ use \WebPExpress\PathHelper;
8
 
9
  class Paths
10
  {
113
  return false;
114
  }
115
 
116
+ // ------------ Content Dir (the "WP" content dir) -------------
117
+
118
  public static function getContentDirAbs()
119
  {
120
  return self::getAbsDir(WP_CONTENT_DIR);
135
  }
136
 
137
 
138
+ // ------------ WebPExpress Content Dir -------------
139
  // (the "webp-express" directory inside wp-content)
140
 
141
  public static function getWebPExpressContentDirAbs()
lib/classes/PluginActivate.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ use \WebPExpress\Config;
6
+ use \WebPExpress\HTAccess;
7
+ use \WebPExpress\Messenger;
8
+ use \WebPExpress\Multisite;
9
+ use \WebPExpress\Paths;
10
+ use \WebPExpress\PlatformInfo;
11
+ use \WebPExpress\State;
12
+
13
+ class PluginActivate
14
+ {
15
+ // callback for 'register_activation_hook' (registred in AdminInit)
16
+ public static function activate($network_active) {
17
+
18
+ Multisite::overrideIsNetworkActivated($network_active);
19
+
20
+ // Test if plugin is activated for the first time or reactivated
21
+ if (State::getState('configured', false)) {
22
+ self::reactivate();
23
+ } else {
24
+ self::activateFirstTime();
25
+ }
26
+
27
+ }
28
+
29
+ private static function reactivate()
30
+ {
31
+ $config = Config::loadConfig();
32
+ if ($config === false) {
33
+ Messenger::addMessage(
34
+ 'error',
35
+ 'The config file seems to have gone missing. You will need to reconfigure WebP Express ' .
36
+ '<a href="' . Paths::getSettingsUrl() . '">(here)</a>.'
37
+ );
38
+ } else {
39
+ $rulesResult = HTAccess::saveRules($config);
40
+ /*
41
+ 'mainResult' // 'index', 'wp-content' or 'failed'
42
+ 'minRequired' // 'index' or 'wp-content'
43
+ 'pluginToo' // 'yes', 'no' or 'depends'
44
+ 'pluginFailed' // true if failed to write to plugin folder (it only tries that, if pluginToo == 'yes')
45
+ 'pluginFailedBadly' // true if plugin failed AND it seems we have rewrite rules there
46
+ 'overidingRulesInWpContentWarning' // true if main result is 'index' but we cannot remove those in wp-content
47
+ 'rules' // the rules that were generated
48
+ */
49
+ $mainResult = $rulesResult['mainResult'];
50
+ $rules = $rulesResult['rules'];
51
+
52
+ if ($mainResult != 'failed') {
53
+ Messenger::addMessage(
54
+ 'success',
55
+ 'WebP Express re-activated successfully.<br>' .
56
+ 'The image redirections are in effect again.<br><br>' .
57
+ '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>' .
58
+ 'You do that by re-saving the settings ' .
59
+ '<a href="' . Paths::getSettingsUrl() . '">(here)</a>'
60
+ );
61
+ } else {
62
+ Messenger::addMessage(
63
+ 'warning',
64
+ 'WebP Express could not regenerate the rewrite rules<br>' .
65
+ 'You need to change some permissions. Head to the ' .
66
+ '<a href="' . Paths::getSettingsUrl() . '">settings page</a> ' .
67
+ 'and try to save the settings there (it will provide more information about the problem)'
68
+ );
69
+
70
+ }
71
+ }
72
+ }
73
+
74
+ private static function activateFirstTime()
75
+ {
76
+ // First check basic requirements.
77
+ // -------------------------------
78
+
79
+ if (PlatformInfo::isMicrosoftIis()) {
80
+ Messenger::addMessage(
81
+ 'warning',
82
+ 'You are on Microsoft IIS server. ' .
83
+ 'WebP Express <a href="https://github.com/rosell-dk/webp-express/pull/213">should work on Windows now</a>, but it has not been tested thoroughly.'
84
+
85
+ );
86
+ }
87
+
88
+
89
+ if ( is_multisite() ) {
90
+ Messenger::addMessage(
91
+ 'warning',
92
+ 'Multisite functionality in still new in WebP Express (it was added in release 0.12.0). ' .
93
+ 'While it has been tested on several setups, there might be a bug or two yet to be found.'
94
+ );
95
+ }
96
+
97
+ if (!version_compare(PHP_VERSION, '5.5.0', '>=')) {
98
+ Messenger::addMessage(
99
+ 'warning',
100
+ 'You are on a very old version of PHP. WebP Express may not work correctly. Your PHP version:' . phpversion()
101
+ );
102
+ }
103
+
104
+ // Next issue warnings, if any
105
+ // -------------------------------
106
+
107
+ if (PlatformInfo::isApache() || PlatformInfo::isLiteSpeed()) {
108
+ // all is well.
109
+ } else {
110
+ Messenger::addMessage(
111
+ 'warning',
112
+ 'You are not on Apache server, nor on LiteSpeed. WebP Express only works out of the box on Apache and LiteSpeed.<br>' .
113
+ 'But you may get it to work. WebP Express will print you rewrite rules for Apache. You could try to configure your server to do similar routing.<br>' .
114
+ 'Btw: your server is: ' . $_SERVER['SERVER_SOFTWARE']
115
+ );
116
+ }
117
+
118
+ // Welcome!
119
+ // -------------------------------
120
+ Messenger::addMessage(
121
+ 'info',
122
+ 'WebP Express was installed successfully. To start using it, you must ' .
123
+ '<a href="' . Paths::getSettingsUrl() . '">configure it here</a>.'
124
+ );
125
+
126
+ // While not neccessary, lets get those tests copied right away. Some servers are a bit slow to pick up on changes in the filesystem
127
+ CapabilityTest::copyCapabilityTestsToWpContent();
128
+ }
129
+ }
lib/classes/PluginDeactivate.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ use \WebPExpress\HTAccess;
6
+ use \WebPExpress\Messenger;
7
+
8
+ class PluginDeactivate
9
+ {
10
+ // The hook was registred in AdminInit
11
+ public static function deactivate() {
12
+
13
+ $result = HTAccess::deactivateHTAccessRules();
14
+ if ($result !== true) {
15
+ // Oh no. We failed removing the rules
16
+ $msg = "<b>Sorry, can't let you disable WebP Express!</b><br>" .
17
+ 'There are rewrite rules in the <i>.htaccess</i> that could not be removed. If these are not removed, it would break all images.<br>' .
18
+ 'Please make your <i>.htaccess</i> writable and then try to disable WebPExpress again.<br>Alternatively, remove the rules manually in your <i>.htaccess</i> file and try disabling again.' .
19
+ '<br>It concerns the following files:<br>' . implode('<br>', $result);
20
+
21
+ Messenger::addMessage(
22
+ 'error',
23
+ $msg
24
+ );
25
+
26
+ wp_redirect( $_SERVER['HTTP_REFERER']);
27
+ exit;
28
+ }
29
+ }
30
+ }
lib/classes/PluginUninstall.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ use \WebPExpress\FileHelper;
6
+ use \WebPExpress\Option;
7
+ use \WebPExpress\Paths;
8
+
9
+ /**
10
+ *
11
+ */
12
+
13
+ class PluginUninstall
14
+ {
15
+ // The hook was registred in AdminInit
16
+ public static function uninstall() {
17
+
18
+ $optionsToDelete = [
19
+ 'webp-express-messages-pending',
20
+ 'webp-express-action-pending',
21
+ 'webp-express-state',
22
+ 'webp-express-version',
23
+ 'webp-express-activation-error',
24
+ 'webp-express-migration-version'
25
+ ];
26
+ foreach ($optionsToDelete as $i => $optionName) {
27
+ Option::deleteOption($optionName);
28
+ }
29
+
30
+ // remove content dir (config plus images plus htaccess-tests)
31
+ FileHelper::rrmdir(Paths::getWebPExpressContentDirAbs());
32
+ }
33
+ }
lib/classes/TestRun.php CHANGED
@@ -2,16 +2,9 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once "Config.php";
6
  use \WebPExpress\Config;
7
-
8
- include_once __DIR__ . '/../classes/ConvertersHelper.php';
9
  use \WebPExpress\ConvertersHelper;
10
-
11
- include_once "Paths.php";
12
  use \WebPExpress\Paths;
13
-
14
- include_once "FileHelper.php";
15
  use \WebPExpress\FileHelper;
16
 
17
  include_once __DIR__ . '/../../vendor/autoload.php';
2
 
3
  namespace WebPExpress;
4
 
 
5
  use \WebPExpress\Config;
 
 
6
  use \WebPExpress\ConvertersHelper;
 
 
7
  use \WebPExpress\Paths;
 
 
8
  use \WebPExpress\FileHelper;
9
 
10
  include_once __DIR__ . '/../../vendor/autoload.php';
lib/deactivate.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
-
3
- include_once __DIR__ . '/classes/Actions.php';
4
- use \WebPExpress\Actions;
5
-
6
- /*include_once __DIR__ . '/classes/Config.php';
7
- use \WebPExpress\Config;*/
8
-
9
- include_once __DIR__ . '/classes/HTAccess.php';
10
- use \WebPExpress\HTAccess;
11
-
12
- include_once __DIR__ . '/classes/Messenger.php';
13
- use \WebPExpress\Messenger;
14
-
15
- include_once __DIR__ . '/classes/Paths.php';
16
- use \WebPExpress\Paths;
17
-
18
-
19
-
20
- function webpexpress_deny_deactivate($msg) {
21
- Messenger::addMessage(
22
- 'error',
23
- $msg
24
- );
25
- wp_redirect( $_SERVER['HTTP_REFERER']);
26
- exit;
27
- }
28
-
29
- $result = HTAccess::deactivateHTAccessRules();
30
- if ($result !== true) {
31
- // Oh no. We failed removing the rules
32
- $msg = "<b>Sorry, can't let you disable WebP Express!</b><br>" .
33
- 'There are rewrite rules in the <i>.htaccess</i> that could not be removed. If these are not removed, it would break all images.<br>' .
34
- 'Please make your <i>.htaccess</i> writable and then try to disable WebPExpress again.<br>Alternatively, remove the rules manually in your <i>.htaccess</i> file and try disabling again.' .
35
- '<br>It concerns the following files:<br>' . implode('<br>', $result);
36
- webpexpress_deny_deactivate($msg);
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/migrate/migrate.php CHANGED
@@ -1,12 +1,9 @@
1
  <?php
2
 
3
- include_once __DIR__ . '/../classes/State.php';
4
- use \WebPExpress\State;
5
-
6
- use \WebPExpress\Messenger;
7
  use \WebPExpress\Config;
 
8
  use \WebPExpress\Option;
9
-
10
 
11
  /*
12
  In 0.4.0, we had a 'webp-express-configured' option.
@@ -27,7 +24,6 @@ if (!Option::getOption('webp-express-configured', false)) {
27
  }
28
  }
29
 
30
-
31
  if (!(State::getState('configured', false))) {
32
  // Options has never has been saved, so no migration is needed.
33
  // We can set migrate-version to current
@@ -42,7 +38,6 @@ if (!(State::getState('configured', false))) {
42
  // newer migrations to run, until the problem with that migration is fixed.
43
  include __DIR__ . '/migrate' . ($x + 1) . '.php';
44
  }
45
-
46
  }
47
  }
48
 
1
  <?php
2
 
 
 
 
 
3
  use \WebPExpress\Config;
4
+ use \WebPExpress\Messenger;
5
  use \WebPExpress\Option;
6
+ use \WebPExpress\State;
7
 
8
  /*
9
  In 0.4.0, we had a 'webp-express-configured' option.
24
  }
25
  }
26
 
 
27
  if (!(State::getState('configured', false))) {
28
  // Options has never has been saved, so no migration is needed.
29
  // We can set migrate-version to current
38
  // newer migrations to run, until the problem with that migration is fixed.
39
  include __DIR__ . '/migrate' . ($x + 1) . '.php';
40
  }
 
41
  }
42
  }
43
 
lib/migrate/migrate1.php CHANGED
@@ -2,20 +2,11 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once __DIR__ . '/../classes/Config.php';
6
  use \WebPExpress\Config;
7
-
8
- include_once __DIR__ . '/../classes/HTAccess.php';
9
  use \WebPExpress\HTAccess;
10
-
11
- include_once __DIR__ . '/../classes/Paths.php';
12
- use \WebPExpress\Paths;
13
-
14
- include_once __DIR__ . '/../classes/Messenger.php';
15
  use \WebPExpress\Messenger;
16
-
17
  use \WebPExpress\Option;
18
-
19
 
20
  // On successful migration:
21
  // Option::updateOption('webp-express-migration-version', '1', true);
2
 
3
  namespace WebPExpress;
4
 
 
5
  use \WebPExpress\Config;
 
 
6
  use \WebPExpress\HTAccess;
 
 
 
 
 
7
  use \WebPExpress\Messenger;
 
8
  use \WebPExpress\Option;
9
+ use \WebPExpress\Paths;
10
 
11
  // On successful migration:
12
  // Option::updateOption('webp-express-migration-version', '1', true);
lib/migrate/migrate2.php CHANGED
@@ -2,16 +2,10 @@
2
 
3
  namespace WebPExpress;
4
 
5
- include_once __DIR__ . '/../classes/Paths.php';
6
- use \WebPExpress\Paths;
7
-
8
- include_once __DIR__ . '/../classes/Messenger.php';
9
  use \WebPExpress\Messenger;
10
-
11
- include_once __DIR__ . '/../classes/TestRun.php';
12
- use \WebPExpress\TestRun;
13
-
14
  use \WebPExpress\Option;
 
 
15
 
16
  /* helper. Remove dir recursively. No warnings - fails silently
17
  Set $removeTheDirItself to false if you want to empty the dir
2
 
3
  namespace WebPExpress;
4
 
 
 
 
 
5
  use \WebPExpress\Messenger;
 
 
 
 
6
  use \WebPExpress\Option;
7
+ use \WebPExpress\Paths;
8
+ use \WebPExpress\TestRun;
9
 
10
  /* helper. Remove dir recursively. No warnings - fails silently
11
  Set $removeTheDirItself to false if you want to empty the dir
lib/migrate/migrate3.php CHANGED
@@ -2,20 +2,11 @@
2
 
3
  namespace WebPExpress;
4
 
5
-
6
- include_once __DIR__ . '/../classes/FileHelper.php';
7
  use \WebPExpress\FileHelper;
8
-
9
- include_once __DIR__ . '/../classes/Paths.php';
10
- use \WebPExpress\Paths;
11
-
12
- include_once __DIR__ . '/../classes/PathHelper.php';
13
- use \WebPExpress\PathHelper;
14
-
15
- include_once __DIR__ . '/../classes/Messenger.php';
16
  use \WebPExpress\Messenger;
17
-
18
  use \WebPExpress\Option;
 
 
19
 
20
  if ( ! function_exists('webp_express_glob_recursive'))
21
  {
2
 
3
  namespace WebPExpress;
4
 
 
 
5
  use \WebPExpress\FileHelper;
 
 
 
 
 
 
 
 
6
  use \WebPExpress\Messenger;
 
7
  use \WebPExpress\Option;
8
+ use \WebPExpress\Paths;
9
+ use \WebPExpress\PathHelper;
10
 
11
  if ( ! function_exists('webp_express_glob_recursive'))
12
  {
lib/migrate/migrate4.php CHANGED
@@ -2,13 +2,8 @@
2
 
3
  namespace WebPExpress;
4
 
5
-
6
- include_once __DIR__ . '/../classes/Config.php';
7
  use \WebPExpress\Config;
8
-
9
- include_once __DIR__ . '/../classes/Messenger.php';
10
  use \WebPExpress\Messenger;
11
-
12
  use \WebPExpress\Option;
13
 
14
  function webpexpress_migrate4() {
2
 
3
  namespace WebPExpress;
4
 
 
 
5
  use \WebPExpress\Config;
 
 
6
  use \WebPExpress\Messenger;
 
7
  use \WebPExpress\Option;
8
 
9
  function webpexpress_migrate4() {
lib/migrate/migrate5.php CHANGED
@@ -2,16 +2,9 @@
2
 
3
  namespace WebPExpress;
4
 
5
-
6
- include_once __DIR__ . '/../classes/Config.php';
7
  use \WebPExpress\Config;
8
-
9
- include_once __DIR__ . '/../classes/Messenger.php';
10
  use \WebPExpress\Messenger;
11
-
12
- include_once __DIR__ . '/../classes/CacheMover.php';
13
- use \WebPExpress\CacheMover;
14
-
15
  use \WebPExpress\Option;
16
 
17
  function webpexpress_migrate5() {
2
 
3
  namespace WebPExpress;
4
 
5
+ use \WebPExpress\CacheMover;
 
6
  use \WebPExpress\Config;
 
 
7
  use \WebPExpress\Messenger;
 
 
 
 
8
  use \WebPExpress\Option;
9
 
10
  function webpexpress_migrate5() {
lib/migrate/migrate7.php CHANGED
@@ -2,10 +2,11 @@
2
 
3
  namespace WebPExpress;
4
 
 
5
  use \WebPExpress\Config;
6
  use \WebPExpress\HTAccess;
7
  use \WebPExpress\Messenger;
8
- use \WebPExpress\CapabilityTest;
9
 
10
  function webpexpress_migrate7() {
11
 
2
 
3
  namespace WebPExpress;
4
 
5
+ use \WebPExpress\CapabilityTest;
6
  use \WebPExpress\Config;
7
  use \WebPExpress\HTAccess;
8
  use \WebPExpress\Messenger;
9
+ use \WebPExpress\Option;
10
 
11
  function webpexpress_migrate7() {
12
 
lib/migrate/migrate8.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WebPExpress;
4
+
5
+ use \WebPExpress\Config;
6
+ use \WebPExpress\Messenger;
7
+ use \WebPExpress\Option;
8
+ use \WebPExpress\Paths;
9
+
10
+ function webpexpress_migrate8() {
11
+
12
+ $config = Config::loadConfigAndFix(false); // false, because we do not need to test if quality detection is working
13
+ $converters = $config['converters'];
14
+ if (is_array($converters)) {
15
+
16
+ $firstActiveAndWorking;
17
+ foreach ($converters as $converter) {
18
+ if (isset($converter['deactivated']) && $converter['deactivated']) {
19
+ continue;
20
+ }
21
+ if (isset($converter['working']) && !$converter['working']) {
22
+ continue;
23
+ }
24
+ $firstActiveAndWorking = $converter;
25
+ break;
26
+ }
27
+ if (isset($firstActiveAndWorking)) {
28
+ if (isset($firstActiveAndWorking['converter']) && $firstActiveAndWorking['converter'] == 'gd') {
29
+
30
+ // First working converter is Gd.
31
+ if (isset($firstActiveAndWorking['options']) && $firstActiveAndWorking['options']['skip-pngs'] === false) {
32
+ // And it is set up to convert PNG's
33
+
34
+ Messenger::addMessage(
35
+ 'info',
36
+ 'Service notice from WebP Express:<br>' .
37
+ 'You have been using <i>Gd</i> to convert PNGs. ' .
38
+ 'However, due to a bug, in some cases transparency was lost in the webp. ' .
39
+ 'It is recommended that you delete and reconvert all PNGs. ' .
40
+ 'There are new buttons for doing just that on the ' .
41
+ '<a href="' . Paths::getSettingsUrl() . '">settings screen</a> (look below the conversion methods).'
42
+ );
43
+
44
+ } else {
45
+
46
+ Messenger::addMessage(
47
+ 'info',
48
+ 'Service notice from WebP Express:<br>' .
49
+ 'You have configured <i>Gd</i> to skip converting PNGs. ' .
50
+ 'However, the <i>Gd</i> conversion method has been fixed and is doing ok now!'
51
+ );
52
+
53
+
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ if (WEBPEXPRESS_MIGRATION_VERSION == '8') {
60
+ Messenger::addMessage(
61
+ 'info',
62
+ 'New in WebP Express 0.13.0:' .
63
+ '<ul style="list-style-type:disc; list-style-position: inside">' .
64
+ '<li>Bulk Conversion</li>' .
65
+ '<li>New option to automatically convert images upon upload</li>' .
66
+ '<li>Better support for Windows servers</li>' .
67
+ '<li>- <a href="https://github.com/rosell-dk/webp-express/milestone/16?closed=1" target="_blank">and more</a></li>' .
68
+ '</ul>'
69
+ );
70
+
71
+ }
72
+
73
+ Option::updateOption('webp-express-migration-version', '8');
74
+
75
+ // Find out if Gd is the first active and working converter.
76
+ // We check wod options, because it has already filtered out the disabled converters.
77
+ /*
78
+ $options = Config::loadWodOptions();
79
+ if ($options !== false) {
80
+ $converters = $options['converters'];
81
+ if (is_array($converters) && count($converters) > 0) {
82
+
83
+ if ($converters[0]['converter'] == 'gd') {
84
+ if (isset($converters[0]['options']) && ($converters[0]['options']['skip-pngs'] === true)) {
85
+ //
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ if ($config['operation-mode'] != 'no-conversion') {
92
+ Config::getConverterByName('gd')
93
+ }*/
94
+
95
+
96
+ }
97
+
98
+ webpexpress_migrate8();
lib/options/enqueue_scripts.php CHANGED
@@ -6,7 +6,7 @@ use \WebPExpress\Paths;
6
  include_once __DIR__ . '/../classes/Config.php';
7
  use \WebPExpress\Config;
8
 
9
- $version = '0.12.2';
10
 
11
 
12
  if (!function_exists('webp_express_add_inline_script')) {
@@ -28,7 +28,9 @@ wp_enqueue_script('daspopup');
28
 
29
  $config = Config::getConfigForOptionsPage();
30
 
31
- if (!(isset($config['operation-mode']) && $config['operation-mode'] == 'no-conversion')) {
 
 
32
 
33
  // Remove empty options arrays.
34
  // These cause trouble in json because they are encoded as [] rather than {}
@@ -45,12 +47,19 @@ if (!(isset($config['operation-mode']) && $config['operation-mode'] == 'no-conv
45
  webp_express_add_inline_script('converters', 'window.converters = ' . json_encode($config['converters']) . ';', 'before');
46
  wp_enqueue_script('converters');
47
 
48
-
49
  // Whitelist
50
  wp_register_script('whitelist', plugins_url('js/whitelist.js', __FILE__), ['daspopup'], $version);
51
  webp_express_add_inline_script('whitelist', 'window.whitelist = ' . json_encode($config['web-service']['whitelist']) . ';', 'before');
52
  wp_enqueue_script('whitelist');
53
 
 
 
 
 
 
 
 
 
54
  }
55
 
56
  //wp_register_script('api_keys', plugins_url('js/api-keys.js', __FILE__), ['daspopup'], '0.7.0-dev8');
6
  include_once __DIR__ . '/../classes/Config.php';
7
  use \WebPExpress\Config;
8
 
9
+ $version = '0.13.0';
10
 
11
 
12
  if (!function_exists('webp_express_add_inline_script')) {
28
 
29
  $config = Config::getConfigForOptionsPage();
30
 
31
+
32
+ // Add converter, bulk convert and whitelist script, EXCEPT for "no conversion" mode
33
+ if (!(isset($config['operation-mode']) && ($config['operation-mode'] == 'no-conversion'))) {
34
 
35
  // Remove empty options arrays.
36
  // These cause trouble in json because they are encoded as [] rather than {}
47
  webp_express_add_inline_script('converters', 'window.converters = ' . json_encode($config['converters']) . ';', 'before');
48
  wp_enqueue_script('converters');
49
 
 
50
  // Whitelist
51
  wp_register_script('whitelist', plugins_url('js/whitelist.js', __FILE__), ['daspopup'], $version);
52
  webp_express_add_inline_script('whitelist', 'window.whitelist = ' . json_encode($config['web-service']['whitelist']) . ';', 'before');
53
  wp_enqueue_script('whitelist');
54
 
55
+ // bulk convert
56
+ wp_register_script('bulkconvert', plugins_url('js/bulk-convert.js', __FILE__), [], $version);
57
+ wp_enqueue_script('bulkconvert');
58
+
59
+ // purge cache
60
+ wp_register_script('purgecache', plugins_url('js/purge-cache.js', __FILE__), [], $version);
61
+ wp_enqueue_script('purgecache');
62
+
63
  }
64
 
65
  //wp_register_script('api_keys', plugins_url('js/api-keys.js', __FILE__), ['daspopup'], '0.7.0-dev8');
lib/options/js/bulk-convert.js ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ function openBulkConvertPopup() {
3
+ document.getElementById('bulkconvertcontent').innerHTML = '<div>Receiving list of files to convert...</div>';
4
+ tb_show('Bulk Convert', '#TB_inline?inlineId=bulkconvertpopup');
5
+
6
+ var data = {
7
+ 'action': 'list_unconverted_files',
8
+ //'whatever': ajax_object.we_value // We pass php values differently!
9
+ };
10
+ jQuery.post(ajaxurl, data, function(response) {
11
+ var bulkInfo = {
12
+ 'groups': JSON.parse(response),
13
+ 'groupPointer': 0,
14
+ 'filePointer': 0,
15
+ 'paused': false,
16
+ 'webpTotalFilesize': 0,
17
+ 'orgTotalFilesize': 0,
18
+ };
19
+ window.webpexpress_bulkconvert = bulkInfo;
20
+
21
+ // count files
22
+ var numFiles = 0;
23
+ for (var i=0; i<bulkInfo.groups.length; i++) {
24
+ numFiles += bulkInfo.groups[i].files.length;
25
+ }
26
+
27
+ //console.log(JSON.parse(response));
28
+ var html = '';
29
+ if (numFiles == 0) {
30
+ html += '<p>There are no unconverted files</p>';
31
+ } else {
32
+ html += '<div>'
33
+ html += '<p>There are ' + numFiles + ' unconverted files.</p><br>';
34
+ html += '<button onclick="startBulkConversion()" class="button button-primary" type="button">Start conversion</button>';
35
+ html += '</div>';
36
+
37
+ }
38
+ document.getElementById('bulkconvertcontent').innerHTML = html;
39
+ });
40
+ }
41
+
42
+ function pauseBulkConversion() {
43
+ var bulkInfo = window.webpexpress_bulkconvert;
44
+ bulkInfo.paused = true;
45
+ }
46
+
47
+ function pauseOrResumeBulkConversion() {
48
+ var bulkInfo = window.webpexpress_bulkconvert;
49
+ bulkInfo.paused = !bulkInfo.paused;
50
+
51
+ document.getElementById('bulkPauseResumeBtn').innerText = (bulkInfo.paused ? 'Resume' : 'Pause');
52
+
53
+ if (!bulkInfo.paused) {
54
+ convertNextInBulkQueue();
55
+ }
56
+ }
57
+
58
+ function startBulkConversion() {
59
+ var html = '<br>';
60
+ html += '<style>' +
61
+ '.has-tip {cursor:pointer; position:relative;}\n' +
62
+ '.has-tip .tip {display: none}\n' +
63
+ '.has-tip:hover .tip {display: block}\n' +
64
+ '.tip{padding: 5px 10px; background-color:#ff9;position:absolute; right: 0; min-width:110px; font-size:10px; color: black; border:1px solid black; max-width:90%;z-index:10}\n' +
65
+ '.reduction {float:right;}\n' +
66
+ '</style>';
67
+ html += '<button id="bulkPauseResumeBtn" onclick="pauseOrResumeBulkConversion()" class="button button-primary" type="button">Pause</button>';
68
+ html += '<div id="bulkconvertlog"></div>';
69
+ document.getElementById('bulkconvertcontent').innerHTML = html;
70
+
71
+ convertNextInBulkQueue();
72
+ }
73
+
74
+ function convertDone() {
75
+ var bulkInfo = window.webpexpress_bulkconvert;
76
+ document.getElementById('bulkconvertlog').innerHTML += '<p><b>Done!</b></p>' +
77
+ '<p>Total reduction: ' + getReductionHtml(bulkInfo['orgTotalFilesize'], bulkInfo['webpTotalFilesize'], 'Total size of converted originals', 'Total size of converted webp files') + '</p>'
78
+
79
+ document.getElementById('bulkPauseResumeBtn').style.display = 'none';
80
+ }
81
+
82
+ function getPrintableSizeInfo(orgSize, webpSize) {
83
+ if (orgSize < 10000) {
84
+ return {
85
+ 'org': orgSize + ' bytes',
86
+ 'webp': webpSize + ' bytes'
87
+ };
88
+ } else {
89
+ return {
90
+ 'org': Math.round(orgSize / 1024) + ' kb',
91
+ 'webp': Math.round(webpSize / 1024) + ' kb'
92
+ };
93
+ }
94
+ }
95
+
96
+ function getReductionHtml(orgSize, webpSize, sizeOfOriginalText, sizeOfWebpText) {
97
+ var reduction = Math.round((orgSize - webpSize)/orgSize * 100);
98
+ var sizeInfo = getPrintableSizeInfo(orgSize, webpSize);
99
+ var hoverText = sizeOfOriginalText + ': ' + sizeInfo['org'] + '.<br>' + sizeOfWebpText + ': ' + sizeInfo['webp'];
100
+ return '<span class="has-tip reduction">' + reduction + '%' +
101
+ '<span class="tip">' + hoverText + '</span>' +
102
+ '</span><br>';
103
+ }
104
+
105
+ function convertNextInBulkQueue() {
106
+ var html;
107
+ var bulkInfo = window.webpexpress_bulkconvert;
108
+ //console.log('convertNextInBulkQueue', bulkInfo);
109
+
110
+ // Current group might contain 0, - skip if that is the case
111
+ while ((bulkInfo.groupPointer < bulkInfo.groups.length) && (bulkInfo.filePointer >= bulkInfo.groups[bulkInfo.groupPointer].files.length)) {
112
+ html = '<h3>' + bulkInfo.groups[bulkInfo.groupPointer].groupName + '</h3>';
113
+ html += '<p>Nothing to convert</p>';
114
+ document.getElementById('bulkconvertlog').innerHTML += html;
115
+
116
+ bulkInfo.groupPointer++;
117
+ bulkInfo.filePointer = 0;
118
+ }
119
+
120
+ if (bulkInfo.groupPointer >= bulkInfo.groups.length) {
121
+ convertDone();
122
+ return;
123
+ }
124
+
125
+ var group = bulkInfo.groups[bulkInfo.groupPointer];
126
+ var filename = group.files[bulkInfo.filePointer];
127
+
128
+ if (bulkInfo.filePointer == 0) {
129
+ html = '<h3>' + group.groupName + '</h3>';
130
+ //html += '<p>root: ' + group.root + '</p><br>';
131
+ document.getElementById('bulkconvertlog').innerHTML += html;
132
+ }
133
+
134
+ html = 'Converting <i>' + filename + '</i>';
135
+ document.getElementById('bulkconvertlog').innerHTML += html;
136
+
137
+ var data = {
138
+ 'action': 'convert_file',
139
+ 'filename': group.root + '/' + filename
140
+
141
+ //'whatever': ajax_object.we_value // We pass php values differently!
142
+ };
143
+
144
+ function responseCallback(response){
145
+ var result = typeof response.requestError !== 'boolean' ? JSON.parse(response) : {
146
+ success: false,
147
+ msg: '',
148
+ log: '',
149
+ };
150
+
151
+ var bulkInfo = window.webpexpress_bulkconvert;
152
+ var group = bulkInfo.groups[bulkInfo.groupPointer];
153
+
154
+ var result = JSON.parse(response);
155
+ //console.log(result);
156
+
157
+ var html = '';
158
+ if (result['success']) {
159
+
160
+ var orgSize = result['filesize-original'];
161
+ var webpSize = result['filesize-webp'];
162
+ var orgSizePrint, webpSizePrint;
163
+
164
+ bulkInfo['orgTotalFilesize'] += orgSize;
165
+ bulkInfo['webpTotalFilesize'] += webpSize;
166
+
167
+ html += ' <span style="color:green" class="has-tip">ok<span class="tip">' + result['log'] + '</span></span>' +
168
+ getReductionHtml(orgSize, webpSize, 'Size of original', 'Size of webp')
169
+ } else {
170
+ html += ' <span style="color:red">failed</span><br>';
171
+ if (result['msg'] != '') {
172
+ html += ' <span style="">' + result['msg'] + '</span>';
173
+ }
174
+ if (result['log'] != '') {
175
+ html += ' <span style="font-size:10px">' + result['log'] + '</span>';
176
+ }
177
+ }
178
+ document.getElementById('bulkconvertlog').innerHTML += html;
179
+
180
+
181
+ // Get next
182
+ bulkInfo.filePointer++;
183
+ if (bulkInfo.filePointer == group.files.length) {
184
+ bulkInfo.filePointer = 0;
185
+ bulkInfo.groupPointer++;
186
+ }
187
+ if (bulkInfo.groupPointer == bulkInfo.groups.length) {
188
+ convertDone();
189
+ } else {
190
+ if (bulkInfo.paused) {
191
+ document.getElementById('bulkconvertlog').innerHTML += '<p><i>on pause</i><br>' +
192
+ 'Reduction this far: ' + getReductionHtml(bulkInfo['orgTotalFilesize'], bulkInfo['webpTotalFilesize'], 'Total size of originals this far', 'Total size of webp files this far') + '</p>'
193
+
194
+ bulkInfo['orgTotalFilesize'] += orgSize;
195
+ bulkInfo['webpTotalFilesize'] += webpSize;
196
+
197
+ } else {
198
+ convertNextInBulkQueue();
199
+ }
200
+ }
201
+
202
+ }
203
+
204
+ // jQuery.post(ajaxurl, data, responseCallback);
205
+ jQuery.ajax({
206
+ method: 'POST',
207
+ url: ajaxurl,
208
+ data: data,
209
+ success: (response) => {
210
+ responseCallback(response);
211
+ },
212
+ error: () => {
213
+ responseCallback({requestError: true});
214
+ },
215
+ });
216
+ }
217
+
218
+
219
+
220
+ //alert('bulk');
221
+ /*
222
+ jQuery(document).ready(function($) {
223
+ });
224
+ */
lib/options/js/purge-cache.js ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ function openDeleteConvertedFilesPopup() {
3
+ var html = '';
4
+ html += '<p>To delete all converted files, click this button:<br>';
5
+ html += '<button onclick="purgeCache(false)" class="button button-secondary" type="button">Delete all converted files</button>';
6
+ html += '</p>';
7
+ html += '<p>Or perhaps, you only want to delete the converted <i>PNGs</i>? Then this button is for you:<br>';
8
+ html += '<button onclick="purgeCache(true)" class="button button-secondary" type="button">Delete converted PNGs</button>';
9
+ html += '</p>';
10
+
11
+ document.getElementById('purgecachecontent').innerHTML = html;
12
+ tb_show('Purge cache', '#TB_inline?inlineId=purgecachepopup');
13
+ // purgeCache();
14
+ }
15
+
16
+ function purgeCache(onlyPng) {
17
+ var data = {
18
+ 'action': 'webpexpress_purge_cache',
19
+ 'only-png': onlyPng
20
+ };
21
+ jQuery.post(ajaxurl, data, function(response) {
22
+ var result = JSON.parse(response);
23
+ console.log(result);
24
+
25
+ if (result['fail-count'] == 0) {
26
+ if (result['delete-count'] == 0) {
27
+ alert('No webp files were found, so none was deleted.');
28
+ } else {
29
+ alert('Successfully deleted ' + result['delete-count'] + ' webp files');
30
+ }
31
+ } else {
32
+ if (result['delete-count'] == 0) {
33
+ alert('Failed deleting ' + result['fail-count'] + ' webp files. None was deleted, in fact.');
34
+ } else {
35
+ alert('Deleted ' + result['delete-count'] + ' webp files. However, failed deleting ' + result['fail-count'] + ' webp files.');
36
+ }
37
+ }
38
+
39
+ });
40
+ }
lib/options/options-hooks.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
- use \WebPExpress\Config;
3
- use \WebPExpress\Multisite;
4
-
5
- if (Multisite::isNetworkActivated()) {
6
- add_action("network_admin_menu", function() {
7
- add_submenu_page(
8
- 'settings.php', // Parent element
9
- 'WebP Express settings (for network)', // Text in browser title bar
10
- 'WebP Express', // Text to be displayed in the menu.
11
- 'manage_network_options', // Capability
12
- 'webp_express_settings_page', // slug
13
- 'webp_express_settings_page_content' // Callback function which displays the page
14
- );
15
- });
16
- } else {
17
- add_action( 'admin_menu', function() {
18
- //Add Settings Page
19
- add_options_page(
20
- 'WebP Express Settings', //Page Title
21
- 'WebP Express', //Menu Title
22
- 'manage_options', //capability
23
- 'webp_express_settings_page', // slug
24
- 'webp_express_settings_page_content' //The function to be called to output the content for this page.
25
- );
26
- });
27
- }
28
-
29
- add_action('admin_post_webpexpress_settings_submit', function() {
30
- include __DIR__ . '/submit.php';
31
- });
32
-
33
- function webp_express_settings_page_content()
34
- {
35
- //include __DIR__ . '/enqueue_scripts.php'; // we don't do that, because our inline scripts would not be written in head on wordpress 4.4 and below
36
- include __DIR__ . '/page.php';
37
- }
38
-
39
- function webp_express_admin_init() {
40
-
41
- global $pagenow;
42
- if ((('options-general.php' === $pagenow) || (('settings.php' === $pagenow))) && (isset( $_GET['page'])) && ('webp_express_settings_page' === $_GET['page'])) {
43
- add_action( 'admin_enqueue_scripts', function () {
44
- include __DIR__ . '/enqueue_scripts.php';
45
- } );
46
- }
47
-
48
- }
49
-
50
- add_action( 'admin_init', 'webp_express_admin_init');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/options/options/conversion-options/bulk-convert.inc ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <tr>
2
+ <th scope="row">
3
+ Bulk convert
4
+ <?php
5
+ echo helpIcon(
6
+ 'Click the button to open dialog for bulk converting. PS: The bulk conversion is using the last saved settings.</p>'
7
+ );
8
+ ?>
9
+ </th>
10
+ <td>
11
+ <div>
12
+ <button onclick="openBulkConvertPopup()" class="button button-secondary" type="button">Bulk Convert</button>
13
+ <div id="bulkconvertpopup" style="display:none;">
14
+ <div id="bulkconvertcontent"></div>
15
+ </div>
16
+ <button onclick="openDeleteConvertedFilesPopup()" class="button button-secondary" type="button">Delete converted files</button>
17
+ <div id="purgecachepopup" style="display:none;">
18
+ <div id="purgecachecontent"></div>
19
+ </div>
20
+ </div>
21
+ </td>
22
+ </tr>
lib/options/options/conversion-options/conversion-options.inc CHANGED
@@ -7,6 +7,8 @@
7
  include_once 'quality.inc';
8
  include_once 'metadata.inc';
9
  include_once 'converters.inc';
 
 
10
  ?>
11
  </tbody>
12
  </table>
7
  include_once 'quality.inc';
8
  include_once 'metadata.inc';
9
  include_once 'converters.inc';
10
+ include_once 'convert-on-upload.inc';
11
+ include_once 'bulk-convert.inc';
12
  ?>
13
  </tbody>
14
  </table>
lib/options/options/conversion-options/convert-on-upload.inc ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <tr>
2
+ <th scope="row">
3
+ Convert on upload
4
+ <?php
5
+ echo helpIcon(
6
+ '<p>Convert images at the moment they have been uploaded through the media library. ' .
7
+ 'Of course, the "Image types to work on" setting is respected.</p>' .
8
+ '<p>Technically, we are hooking into the <i>handle_upload</i> filter to trigger conversion of the image ' .
9
+ 'and the <i>image_make_intermediate_size</i> filter for the thumbnails.</p>'
10
+ );
11
+ ?>
12
+ </th>
13
+ <td>
14
+ <input type="checkbox" id="convert_on_upload" name="convert-on-upload" value="true" <?php echo ($config['convert-on-upload'] ? 'checked="checked"' : '') ?> >
15
+ </td>
16
+ </tr>
lib/options/options/conversion-options/converter-options/gd.php CHANGED
@@ -4,9 +4,9 @@
4
  <div>
5
  <label for="gd_skip_pngs">Skip PNGs</label>
6
  <input type="checkbox" id="gd_skip_pngs">
7
- <br>Gd is not suited for converting PNGs into webp. &ndash;
8
- The filesize is generally much larger than the original.
9
- For this reason, the converter defaults to skip PNG's.
10
  </div>
11
  <br>
12
  <?php webp_express_printUpdateButtons() ?>
4
  <div>
5
  <label for="gd_skip_pngs">Skip PNGs</label>
6
  <input type="checkbox" id="gd_skip_pngs">
7
+ <br>
8
+ You can choose to skip PNG's for Gd (which means the next working and active converter in the stack will handle it, if there is any).
9
+ In our first implementation, Gd had problems with transparency. This is however solved now.
10
  </div>
11
  <br>
12
  <?php webp_express_printUpdateButtons() ?>
lib/options/options/general/general.inc CHANGED
@@ -10,7 +10,9 @@
10
  include_once 'destination-folder.inc';
11
  }
12
  include_once 'destination-extension.inc';
13
-
 
 
14
  if (($config['operation-mode'] == 'tweaked') || ($config['operation-mode'] == 'varied-image-responses')) {
15
  include_once 'cache-control.inc';
16
  }
10
  include_once 'destination-folder.inc';
11
  }
12
  include_once 'destination-extension.inc';
13
+
14
+ // TODO:
15
+ // Perhaps also show cache control in cdn-friendly mode?
16
  if (($config['operation-mode'] == 'tweaked') || ($config['operation-mode'] == 'varied-image-responses')) {
17
  include_once 'cache-control.inc';
18
  }
lib/options/page-messages.php CHANGED
@@ -8,9 +8,11 @@ use \WebPExpress\Messenger;
8
  use \WebPExpress\PlatformInfo;
9
  use \WebPExpress\FileHelper;
10
  use \WebPExpress\CapabilityTest;
11
- //include __DIR__ . "/page-welcome.php";
12
 
13
- //echo 'display errors:' . ini_get('display_errors');
 
 
 
14
 
15
  if ((!State::getState('configured', false))) {
16
  include __DIR__ . "/page-welcome.php";
@@ -80,12 +82,13 @@ if (($config['operation-mode'] == 'cdn-friendly') && !$config['alter-html']['ena
80
  Messenger::printMessage(
81
  'warning',
82
  'You are in CDN friendly mode but have not enabled Alter HTML (and you are not using Cache Enabler either). ' .
83
- 'This is usually a misconfiguration because in this mode, the only way to get webp files is by referencing them in the HTML.'
84
  );
85
 
86
  }
87
  }
88
 
 
89
  if (!$anyRedirectionToConverterEnabled && ($config['operation-mode'] == 'cdn-friendly')) {
90
  // this can not happen in varied image responses. it is ok in no-conversion, and also tweaked, because one could wish to tweak the no-conversion mode
91
  Messenger::printMessage(
@@ -93,7 +96,7 @@ if (!$anyRedirectionToConverterEnabled && ($config['operation-mode'] == 'cdn-fri
93
  'You have not enabled any of the redirects to the converter. ' .
94
  'At least one of the redirects is required for triggering WebP generation.'
95
  );
96
- }
97
 
98
  if ($config['alter-html']['enabled'] && !$config['alter-html']['only-for-webps-that-exists'] && !$config['enable-redirection-to-webp-realizer']) {
99
  Messenger::printMessage(
8
  use \WebPExpress\PlatformInfo;
9
  use \WebPExpress\FileHelper;
10
  use \WebPExpress\CapabilityTest;
 
11
 
12
+ //use \WebPExpress\BulkConvert;
13
+ //echo '<pre>' . print_r(BulkConvert::getList($config), true) . "</pre>";
14
+ //echo '<pre>' . print_r(BulkConvert::convertFile('/var/www/webp-express-tests/we0/wordpress/uploads-moved/space in name.jpg'), true) . "</pre>";
15
+
16
 
17
  if ((!State::getState('configured', false))) {
18
  include __DIR__ . "/page-welcome.php";
82
  Messenger::printMessage(
83
  'warning',
84
  'You are in CDN friendly mode but have not enabled Alter HTML (and you are not using Cache Enabler either). ' .
85
+ 'This is usually a misconfiguration because in this mode, the only way to get webp files delivered is by referencing them in the HTML.'
86
  );
87
 
88
  }
89
  }
90
 
91
+ /*
92
  if (!$anyRedirectionToConverterEnabled && ($config['operation-mode'] == 'cdn-friendly')) {
93
  // this can not happen in varied image responses. it is ok in no-conversion, and also tweaked, because one could wish to tweak the no-conversion mode
94
  Messenger::printMessage(
96
  'You have not enabled any of the redirects to the converter. ' .
97
  'At least one of the redirects is required for triggering WebP generation.'
98
  );
99
+ }*/
100
 
101
  if ($config['alter-html']['enabled'] && !$config['alter-html']['only-for-webps-that-exists'] && !$config['enable-redirection-to-webp-realizer']) {
102
  Messenger::printMessage(
lib/options/page.php CHANGED
@@ -1,39 +1,20 @@
1
  <?php
2
 
3
- include_once __DIR__ . '/../classes/Config.php';
4
  use \WebPExpress\Config;
5
-
6
- include_once __DIR__ . '/../classes/ConvertersHelper.php';
7
  use \WebPExpress\ConvertersHelper;
8
-
9
- include_once __DIR__ . '/../classes/FileHelper.php';
10
  use \WebPExpress\FileHelper;
11
-
12
- include_once __DIR__ . '/../classes/HTAccess.php';
13
  use \WebPExpress\HTAccess;
14
-
15
- include_once __DIR__ . '/../classes/Messenger.php';
16
  use \WebPExpress\Messenger;
17
-
18
- include_once __DIR__ . '/../classes/Multisite.php';
19
  use \WebPExpress\Multisite;
20
-
21
- include_once __DIR__ . '/../classes/Paths.php';
22
  use \WebPExpress\Paths;
23
-
24
- include_once __DIR__ . '/../classes/PlatformInfo.php';
25
  use \WebPExpress\PlatformInfo;
26
-
27
- include_once __DIR__ . '/../classes/State.php';
28
  use \WebPExpress\State;
29
-
30
- include_once __DIR__ . '/../classes/TestRun.php';
31
  use \WebPExpress\TestRun;
32
 
33
-
34
  if (!current_user_can('manage_options')) {
35
  wp_die('You do not have sufficient permissions to access this page.');
36
  }
 
37
  ?>
38
  <div class="wrap">
39
  <h2>WebP Express Settings<?php echo Multisite::isNetworkActivated() ? ' (network)' : ''; ?></h2>
1
  <?php
2
 
 
3
  use \WebPExpress\Config;
 
 
4
  use \WebPExpress\ConvertersHelper;
 
 
5
  use \WebPExpress\FileHelper;
 
 
6
  use \WebPExpress\HTAccess;
 
 
7
  use \WebPExpress\Messenger;
 
 
8
  use \WebPExpress\Multisite;
 
 
9
  use \WebPExpress\Paths;
 
 
10
  use \WebPExpress\PlatformInfo;
 
 
11
  use \WebPExpress\State;
 
 
12
  use \WebPExpress\TestRun;
13
 
 
14
  if (!current_user_can('manage_options')) {
15
  wp_die('You do not have sufficient permissions to access this page.');
16
  }
17
+
18
  ?>
19
  <div class="wrap">
20
  <h2>WebP Express Settings<?php echo Multisite::isNetworkActivated() ? ' (network)' : ''; ?></h2>
lib/options/submit.php CHANGED
@@ -1,23 +1,12 @@
1
  <?php
2
 
3
- include_once __DIR__ . '/../classes/CacheMover.php';
4
  use \WebPExpress\CacheMover;
5
-
6
- include_once __DIR__ . '/../classes/Config.php';
7
  use \WebPExpress\Config;
8
-
9
- include_once __DIR__ . '/../classes/HTAccess.php';
10
  use \WebPExpress\HTAccess;
11
-
12
- include_once __DIR__ . '/../classes/Messenger.php';
13
  use \WebPExpress\Messenger;
14
-
15
- include_once __DIR__ . '/../classes/Paths.php';
16
  use \WebPExpress\Paths;
17
-
18
  use \WebPExpress\CapabilityTest;
19
 
20
-
21
  // https://premium.wpmudev.org/blog/handling-form-submissions/
22
  // checkout https://codex.wordpress.org/Function_Reference/sanitize_meta
23
 
@@ -107,6 +96,8 @@ if ($_POST['operation-mode'] != 'no-conversion') {
107
  $config['quality-specific'] = webp_express_sanitize_quality_field($_POST['quality-specific']);
108
  }
109
 
 
 
110
  // Web Service
111
  // -------------
112
 
1
  <?php
2
 
 
3
  use \WebPExpress\CacheMover;
 
 
4
  use \WebPExpress\Config;
 
 
5
  use \WebPExpress\HTAccess;
 
 
6
  use \WebPExpress\Messenger;
 
 
7
  use \WebPExpress\Paths;
 
8
  use \WebPExpress\CapabilityTest;
9
 
 
10
  // https://premium.wpmudev.org/blog/handling-form-submissions/
11
  // checkout https://codex.wordpress.org/Function_Reference/sanitize_meta
12
 
96
  $config['quality-specific'] = webp_express_sanitize_quality_field($_POST['quality-specific']);
97
  }
98
 
99
+ $config['convert-on-upload'] = isset($_POST['convert-on-upload']);
100
+
101
  // Web Service
102
  // -------------
103
 
lib/reactivate.php DELETED
@@ -1,73 +0,0 @@
1
- <?php
2
-
3
- include_once __DIR__ . '/classes/Config.php';
4
- use \WebPExpress\Config;
5
-
6
- include_once __DIR__ . '/classes/HTAccess.php';
7
- use \WebPExpress\HTAccess;
8
-
9
- include_once __DIR__ . '/classes/Messenger.php';
10
- use \WebPExpress\Messenger;
11
-
12
- include_once __DIR__ . '/classes/Actions.php';
13
- use \WebPExpress\Actions;
14
-
15
- include_once __DIR__ . '/classes/Paths.php';
16
- use \WebPExpress\Paths;
17
-
18
- include_once __DIR__ . '/classes/PlatformInfo.php';
19
- use \WebPExpress\PlatformInfo;
20
-
21
- include_once __DIR__ . '/classes/State.php';
22
- use \WebPExpress\State;
23
-
24
-
25
- // The plugin has been reactivated.
26
- // We must regenerate the .htaccess rules.
27
- // (config dir and options and of course still there, no need to do anything about that)
28
-
29
- // Messenger::addMessage('error', 'You are on Microsof IIS server. The plugin does not work on IIS (yet)');
30
- //Actions::procastinate('deactivate');
31
-
32
- $config = Config::loadConfig();
33
- if ($config === false) {
34
- Messenger::addMessage(
35
- 'error',
36
- 'The config file seems to have gone missing. You will need to reconfigure WebP Express ' .
37
- '<a href="' . Paths::getSettingsUrl() . '">(here)</a>.'
38
- );
39
- } else {
40
- $rulesResult = HTAccess::saveRules($config);
41
- /*
42
- 'mainResult' // 'index', 'wp-content' or 'failed'
43
- 'minRequired' // 'index' or 'wp-content'
44
- 'pluginToo' // 'yes', 'no' or 'depends'
45
- 'pluginFailed' // true if failed to write to plugin folder (it only tries that, if pluginToo == 'yes')
46
- 'pluginFailedBadly' // true if plugin failed AND it seems we have rewrite rules there
47
- 'overidingRulesInWpContentWarning' // true if main result is 'index' but we cannot remove those in wp-content
48
- 'rules' // the rules that were generated
49
- */
50
- $mainResult = $rulesResult['mainResult'];
51
- $rules = $rulesResult['rules'];
52
-
53
- if ($mainResult != 'failed') {
54
- Messenger::addMessage(
55
- 'success',
56
- 'WebP Express re-activated successfully.<br>' .
57
- 'The image redirections are in effect again.<br><br>' .
58
- '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>' .
59
- 'You do that by re-saving the settings ' .
60
- '<a href="' . Paths::getSettingsUrl() . '">(here)</a>'
61
- );
62
- } else {
63
- Messenger::addMessage(
64
- 'warning',
65
- 'WebP Express could not regenerate the rewrite rules<br>' .
66
- 'You need to change some permissions. Head to the ' .
67
- '<a href="' . Paths::getSettingsUrl() . '">settings page</a> ' .
68
- 'and try to save the settings there (it will provide more information about the problem)'
69
- );
70
-
71
- }
72
-
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/uninstall.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
-
3
- //include_once __DIR__ . '/classes/Config.php';
4
- //use \WebPExpress\Config;
5
-
6
- include_once __DIR__ . '/classes/Paths.php';
7
- use \WebPExpress\Paths;
8
-
9
- use \WebPExpress\Option;
10
-
11
- /* helper. Remove dir recursively. No warnings - fails silently */
12
- function webpexpress_rrmdir($dir) {
13
- if (@is_dir($dir)) {
14
- $objects = @scandir($dir);
15
- foreach ($objects as $object) {
16
- if ($object != "." && $object != "..") {
17
- if (@is_dir($dir."/".$object))
18
- webpexpress_rrmdir($dir."/".$object);
19
- else
20
- @unlink($dir."/".$object);
21
- }
22
- }
23
- @rmdir($dir);
24
- }
25
- }
26
-
27
- $optionsToDelete = [
28
- 'webp-express-messages-pending',
29
- 'webp-express-action-pending',
30
- 'webp-express-state',
31
- 'webp-express-version',
32
- 'webp-express-activation-error',
33
- 'webp-express-migration-version'
34
- ];
35
- foreach ($optionsToDelete as $i => $optionName) {
36
- Option::deleteOption($optionName);
37
- }
38
-
39
- // remove content dir (config plus images plus htaccess-tests)
40
- webpexpress_rrmdir(Paths::getWebPExpressContentDirAbs());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.12.2
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2
@@ -14,27 +14,24 @@
14
  Note: Perhaps create a plugin page on my website?, ie https://www.bitwise-it.dk/software/wordpress/webp-express
15
  */
16
 
 
 
 
17
  define('WEBPEXPRESS_PLUGIN', __FILE__);
18
  define('WEBPEXPRESS_PLUGIN_DIR', __DIR__);
19
 
20
- use \WebPExpress\Option;
21
-
22
  spl_autoload_register('webpexpress_autoload');
23
  function webpexpress_autoload($class) {
24
- //echo $class . "\n<br>";
25
  if (strpos($class, 'WebPExpress\\') === 0) {
26
- //echo WEBPEXPRESS_PLUGIN_DIR . '/lib/classes/' . substr($class, 12) . '.php' . "\n<br><br>";
27
  require_once WEBPEXPRESS_PLUGIN_DIR . '/lib/classes/' . substr($class, 12) . '.php';
28
  }
29
  }
30
 
31
  if (is_admin()) {
32
- include __DIR__ . '/lib/admin.php';
33
  }
34
 
35
- //add_action( 'wp_ajax_foobar', 'my_ajax_foobar_handler' );
36
-
37
-
38
  function webp_express_process_post() {
39
  // strip query string
40
  $requestUriNoQS = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
@@ -42,18 +39,40 @@ function webp_express_process_post() {
42
  if (!preg_match('/webp-express-web-service$/', $requestUriNoQS)) {
43
  return;
44
  }
45
- //include __DIR__ . '/lib/wpc.php';
46
  include __DIR__ . '/web-service/wpc.php';
47
  die();
48
  }
49
  add_action( 'init', 'webp_express_process_post' );
50
 
51
-
52
  if (Option::getOption('webp-express-alter-html', false)) {
53
  require_once __DIR__ . '/lib/classes/AlterHtmlInit.php';
54
  \WebPExpress\AlterHtmlInit::setHooks();
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  /*
58
  function webpexpress_addWebPJs() {
59
  $url = plugins_url('webpjs/webpjs-0.0.2.min.js', __FILE__);
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.13.0
7
  * Author: Bjørn Rosell
8
  * Author URI: https://www.bitwise-it.dk
9
  * License: GPL2
14
  Note: Perhaps create a plugin page on my website?, ie https://www.bitwise-it.dk/software/wordpress/webp-express
15
  */
16
 
17
+ use \WebPExpress\AdminInit;
18
+ use \WebPExpress\Option;
19
+
20
  define('WEBPEXPRESS_PLUGIN', __FILE__);
21
  define('WEBPEXPRESS_PLUGIN_DIR', __DIR__);
22
 
23
+ // Autoloading rules!
 
24
  spl_autoload_register('webpexpress_autoload');
25
  function webpexpress_autoload($class) {
 
26
  if (strpos($class, 'WebPExpress\\') === 0) {
 
27
  require_once WEBPEXPRESS_PLUGIN_DIR . '/lib/classes/' . substr($class, 12) . '.php';
28
  }
29
  }
30
 
31
  if (is_admin()) {
32
+ \WebPExpress\AdminInit::init();
33
  }
34
 
 
 
 
35
  function webp_express_process_post() {
36
  // strip query string
37
  $requestUriNoQS = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
39
  if (!preg_match('/webp-express-web-service$/', $requestUriNoQS)) {
40
  return;
41
  }
 
42
  include __DIR__ . '/web-service/wpc.php';
43
  die();
44
  }
45
  add_action( 'init', 'webp_express_process_post' );
46
 
 
47
  if (Option::getOption('webp-express-alter-html', false)) {
48
  require_once __DIR__ . '/lib/classes/AlterHtmlInit.php';
49
  \WebPExpress\AlterHtmlInit::setHooks();
50
  }
51
 
52
+ /*
53
+ $filters = [];
54
+ add_action('all', function() {
55
+ global $filters;
56
+ $filter = current_filter();
57
+ if (!in_array($filter, $filters)) {
58
+ $filters[] = $filter;
59
+ error_log($filter);
60
+ }
61
+ });
62
+ */
63
+
64
+ // When images are uploaded with Gutenberg, is_admin() returns false, so, hook needs to be added here
65
+ add_filter('wp_handle_upload', array('\WebPExpress\HandleUploadHooks', 'handleUpload'), 10, 2);
66
+ add_filter('image_make_intermediate_size', array('\WebPExpress\HandleUploadHooks', 'handleMakeIntermediateSize'), 10, 1);
67
+
68
+ /*
69
+ add_action('wp_handle_upload', function($a) {
70
+ error_log('yes, it is called'. (is_admin() ? 'admin' : 'not admin'));
71
+ \WebPExpress\HandleUploadHooks::handleUpload($a, true);
72
+ return $a;
73
+ });*/
74
+
75
+
76
  /*
77
  function webpexpress_addWebPJs() {
78
  $url = plugins_url('webpjs/webpjs-0.0.2.min.js', __FILE__);
wod/webp-on-demand.php CHANGED
@@ -15,6 +15,9 @@ error_reporting(E_ALL);
15
  use \WebPConvert\WebPConvert;
16
  use \WebPConvert\ServeExistingOrHandOver;
17
 
 
 
 
18
  function exitWithError($msg) {
19
  header('X-WebP-Express-Error: ' . $msg, true);
20
  echo $msg;
@@ -172,68 +175,13 @@ if (!file_exists($source)) {
172
  exit;
173
  }
174
 
175
- // Determine if we should store mingled or not
176
- function storeMingled() {
177
- global $options;
178
- global $source;
179
- global $docRoot;
180
-
181
- $destinationOptionSetToMingled = (isset($options['destination-folder']) && ($options['destination-folder'] == 'mingled'));
182
- if (!$destinationOptionSetToMingled) {
183
- return false;
184
- }
185
-
186
- // Option is set for mingled.
187
- // But we will only store "mingled", for images in upload folder
188
-
189
- if (!isset($options['paths']['uploadDirRel'])) {
190
- // Hm, we dont know the upload dir, as the configuration hasn't been regenerated.
191
- // This should not happen because configuration file is saved upon migration to 0.11
192
- // So we can do this wild guess:
193
- return preg_match('/\\/uploads\\//', $source);
194
- }
195
-
196
- $uploadDirAbs = $docRoot . '/' . $options['paths']['uploadDirRel'];
197
- if (strpos($source, $uploadDirAbs) === 0) {
198
- // We are in upload folder
199
- return true;
200
- }
201
- return false;
202
- }
203
-
204
-
205
- // Calculate $destination
206
- // ----------------------
207
-
208
- if (storeMingled($options)) {
209
- if (isset($options['destination-extension']) && ($options['destination-extension'] == 'append')) {
210
- $destination = $source . '.webp';
211
- } else {
212
- $destination = preg_replace('/\\.(jpe?g|png)$/', '', $source) . '.webp';
213
- }
214
- } else {
215
-
216
- $imageRoot = $webExpressContentDirAbs . '/webp-images';
217
-
218
- // Check if source is residing inside document root.
219
- // (it is, if path starts with document root + '/')
220
- if (substr($source, 0, strlen($docRoot) + 1) === $docRoot . '/') {
221
-
222
- // We store relative to document root.
223
- // "Eat" the left part off the source parameter which contains the document root.
224
- // and also eat the slash (+1)
225
- $sourceRel = substr($source, strlen($docRoot) + 1);
226
- $destination = $imageRoot . '/doc-root/' . $sourceRel . '.webp';
227
- } else {
228
- // Source file is residing outside document root.
229
- // we must add complete path to structure
230
- $destination = $imageRoot . '/abs' . $source . '.webp';
231
- }
232
- }
233
-
234
-
235
-
236
-
237
 
238
  //echo $destination; exit;
239
 
15
  use \WebPConvert\WebPConvert;
16
  use \WebPConvert\ServeExistingOrHandOver;
17
 
18
+ include_once "../lib/classes/ConvertHelperIndependent.php";
19
+ use \WebPExpress\ConvertHelperIndependent;
20
+
21
  function exitWithError($msg) {
22
  header('X-WebP-Express-Error: ' . $msg, true);
23
  echo $msg;
175
  exit;
176
  }
177
 
178
+ $destination = ConvertHelperIndependent::getDestination(
179
+ $source,
180
+ $options['destination-folder'],
181
+ $options['destination-extension'],
182
+ $webExpressContentDirAbs,
183
+ $docRoot . '/' . $options['paths']['uploadDirRel']
184
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
  //echo $destination; exit;
187
 
wod/webp-realizer.php CHANGED
@@ -13,6 +13,9 @@ error_reporting(E_ALL);
13
  use \WebPConvert\WebPConvert;
14
  use \WebPConvert\ServeExistingOrHandOver;
15
 
 
 
 
16
  function exitWithError($msg) {
17
  header('X-WebP-Express-Error: ' . $msg, true);
18
  echo $msg;
@@ -149,72 +152,12 @@ $destination = getDestination();
149
 
150
  //echo 'destination: ' . $destination; exit;
151
 
152
-
153
- // Try to find source in same folder.
154
- // Return false on failure
155
- function findSourceMingled() {
156
- global $options;
157
- global $destination;
158
- if (isset($options['destination-extension']) && ($options['destination-extension'] == 'append')) {
159
- $source = preg_replace('/\\.(webp)$/', '', $destination);
160
- } else {
161
- $source = preg_replace('/\\.webp$/', '.jpg', $destination);
162
- if (!@file_exists($source)) {
163
- $source = preg_replace('/\\.webp$/', '.jpeg', $destination);
164
- }
165
- if (!@file_exists($source)) {
166
- $source = preg_replace('/\\.webp$/', '.png', $destination);
167
- }
168
- }
169
- if (!@file_exists($source)) {
170
- return false;
171
- }
172
- return $source;
173
- }
174
-
175
- function findSourceSeparate() {
176
- global $options;
177
- global $destination;
178
- global $webExpressContentDirAbs;
179
- global $docRoot;
180
-
181
- $imageRoot = $webExpressContentDirAbs . '/webp-images';
182
-
183
- // Check if destination is residing inside "doc-root" folder
184
- if (strpos($destination, $imageRoot . '/doc-root/') === 0) {
185
-
186
- $imageRoot .= '/doc-root';
187
- // "Eat" the left part off the $destination parameter. $destination is for example:
188
- // "/var/www/webp-express-tests/we0/wp-content-moved/webp-express/webp-images/doc-root/wordpress/uploads-moved/2018/12/tegning5-300x265.jpg.webp"
189
- // We also eat the slash (+1)
190
- $sourceRel = substr($destination, strlen($imageRoot) + 1);
191
-
192
- $source = $docRoot . '/' . $sourceRel;
193
- $source = preg_replace('/\\.(webp)$/', '', $source);
194
- } else {
195
- $imageRoot .= '/abs';
196
- $sourceRel = substr($destination, strlen($imageRoot) + 1);
197
- $source = $sourceRel;
198
- $source = preg_replace('/\\.(webp)$/', '', $source);
199
- }
200
-
201
- if (!@file_exists($source)) {
202
- return false;
203
- }
204
- return $source;
205
- }
206
-
207
-
208
- $mingled = (isset($options['destination-folder']) && ($options['destination-folder'] == 'mingled'));
209
-
210
- if ($mingled) {
211
- $source = findSourceMingled();
212
- if ($source === false) {
213
- $source = findSourceSeparate();
214
- }
215
- } else {
216
- $source = findSourceSeparate();
217
- }
218
 
219
  if ($source === false) {
220
  header('X-WebP-Express-Error: webp-realizer.php could not find an existing jpg or png that corresponds to the webp requested', true);
@@ -225,15 +168,6 @@ if ($source === false) {
225
  //echo 'destination requested:<br><i>' . $destination . '</i>';
226
  }
227
 
228
-
229
-
230
-
231
- //echo $destination; exit;
232
-
233
-
234
- //echo '<pre>' . print_r($options, true) . '</pre>';
235
- //exit;
236
-
237
  foreach ($options['converters'] as &$converter) {
238
  if (isset($converter['converter'])) {
239
  $converterId = $converter['converter'];
13
  use \WebPConvert\WebPConvert;
14
  use \WebPConvert\ServeExistingOrHandOver;
15
 
16
+ include_once "../lib/classes/ConvertHelperIndependent.php";
17
+ use \WebPExpress\ConvertHelperIndependent;
18
+
19
  function exitWithError($msg) {
20
  header('X-WebP-Express-Error: ' . $msg, true);
21
  echo $msg;
152
 
153
  //echo 'destination: ' . $destination; exit;
154
 
155
+ $source = ConvertHelperIndependent::findSource(
156
+ $destination,
157
+ $options['destination-folder'],
158
+ $options['destination-extension'],
159
+ $webExpressContentDirAbs
160
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
  if ($source === false) {
163
  header('X-WebP-Express-Error: webp-realizer.php could not find an existing jpg or png that corresponds to the webp requested', true);
168
  //echo 'destination requested:<br><i>' . $destination . '</i>';
169
  }
170
 
 
 
 
 
 
 
 
 
 
171
  foreach ($options['converters'] as &$converter) {
172
  if (isset($converter['converter'])) {
173
  $converterId = $converter['converter'];