Converter for Media – Optimize images | Convert WebP & AVIF - Version 1.1.2

Version Description

(2020-03-03) = * [Added] Zero padding at end for odd-sized WebP files using GD library

Download this release

Release Info

Developer mateuszgbiorczyk
Plugin Icon 128x128 Converter for Media – Optimize images | Convert WebP & AVIF
Version 1.1.2
Comparing to
See all releases

Code changes from version 1.3.1 to 1.1.2

Files changed (52) hide show
  1. app/Action/Convert.php +0 -57
  2. app/Action/Delete.php +0 -30
  3. app/Action/Dir.php +0 -43
  4. app/Action/Regenerate.php +0 -23
  5. app/Action/_Core.php +0 -14
  6. app/Admin/Activation.php +6 -15
  7. app/Admin/Deactivation.php +0 -1
  8. app/Admin/Notice.php +4 -4
  9. app/Admin/Plugin.php +5 -11
  10. app/Admin/Uninstall.php +1 -9
  11. app/Admin/Update.php +0 -74
  12. app/Admin/_Core.php +0 -1
  13. app/Convert/Directory.php +3 -6
  14. app/Convert/Gd.php +11 -8
  15. app/Convert/Imagick.php +10 -7
  16. app/Convert/Server.php +0 -26
  17. app/Convert/Size.php +0 -29
  18. app/Convert/_Core.php +0 -11
  19. app/Media/Attachment.php +0 -54
  20. app/Media/Delete.php +5 -1
  21. app/Media/Htaccess.php +33 -75
  22. app/Media/Upload.php +36 -21
  23. app/Regenerate/Endpoints.php +9 -14
  24. app/Regenerate/Paths.php +46 -10
  25. app/Regenerate/Regenerate.php +11 -3
  26. app/Regenerate/Skip.php +3 -4
  27. app/Regenerate/_Core.php +0 -1
  28. app/Settings/Errors.php +10 -50
  29. app/Settings/Options.php +18 -32
  30. app/Settings/Paths.php +11 -65
  31. app/Settings/Save.php +1 -1
  32. app/Settings/Server.php +0 -78
  33. app/Settings/Values.php +1 -2
  34. app/WebpConverter.php +0 -2
  35. public/build/js/scripts.js +1 -1
  36. public/img/.htaccess +0 -6
  37. public/img/icon-after.png +0 -0
  38. public/img/icon-after.png2 +0 -0
  39. public/img/icon-before.png +0 -0
  40. public/img/icon-before.png2 +0 -0
  41. readme.txt +53 -306
  42. resources/_dev/js/classes/Regenerate.js +7 -21
  43. resources/components/notices/thanks.php +6 -6
  44. resources/components/widgets/about.php +5 -5
  45. resources/components/widgets/donate.php +3 -3
  46. resources/components/widgets/errors.php +8 -55
  47. resources/components/widgets/options.php +3 -3
  48. resources/components/widgets/regenerate.php +14 -14
  49. resources/components/widgets/server.php +4 -4
  50. resources/components/widgets/support.php +7 -7
  51. resources/views/settings.php +2 -2
  52. webp-converter-for-media.php +3 -3
app/Action/Convert.php DELETED
@@ -1,57 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Action;
4
-
5
- use WebpConverter\Convert as ConvertMethod;
6
- use WebpConverter\Media\Attachment;
7
-
8
- class Convert
9
- {
10
- public function __construct()
11
- {
12
- add_action('webpc_convert_paths', [$this, 'convertFilesByPaths']);
13
- add_action('webpc_convert_attachment', [$this, 'convertFilesByAttachment']);
14
- add_action('webpc_convert_dir', [$this, 'convertFilesByDirectory'], 10, 2);
15
- }
16
-
17
- /* ---
18
- Functions
19
- --- */
20
-
21
- public function convertFilesByPaths($paths)
22
- {
23
- $settings = apply_filters('webpc_get_values', []);
24
-
25
- if ($settings['method'] === 'gd') $convert = new ConvertMethod\Gd();
26
- else if ($settings['method'] === 'imagick') $convert = new ConvertMethod\Imagick();
27
- if (!isset($convert)) return false;
28
-
29
- foreach ($paths as $path) {
30
- $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
31
- if (!in_array($extension, $settings['extensions'])) continue;
32
-
33
- $response = $convert->convertImage($path, $settings['quality']);
34
- if (!$response['success']) $this->addErrorToLog($response['message']);
35
- }
36
- }
37
-
38
- public function convertFilesByAttachment($postId)
39
- {
40
- $paths = (new Attachment())->getAttachmentPaths($postId);
41
- do_action('webpc_convert_paths', $paths);
42
- }
43
-
44
- public function convertFilesByDirectory($dirPath, $skipExists = true)
45
- {
46
- $paths = apply_filters('webpc_dir_files', [], $dirPath, $skipExists);
47
- do_action('webpc_convert_paths', $paths);
48
- }
49
-
50
- private function addErrorToLog($message)
51
- {
52
- error_log(sprintf(
53
- 'WebP Converter for Media (Error): %s',
54
- $message
55
- ));
56
- }
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/Action/Delete.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Action;
4
-
5
- use WebpConverter\Convert\Directory;
6
-
7
- class Delete
8
- {
9
- public function __construct()
10
- {
11
- add_action('webpc_delete_paths', [$this, 'deleteFilesByPaths']);
12
- }
13
-
14
- /* ---
15
- Functions
16
- --- */
17
-
18
- public function deleteFilesByPaths($paths)
19
- {
20
- foreach ($paths as $path) {
21
- $this->deleteFileByPath($path);
22
- }
23
- }
24
-
25
- private function deleteFileByPath($path)
26
- {
27
- $source = (new Directory())->getPath($path);
28
- if (is_writable($source) && (pathinfo($source, PATHINFO_EXTENSION) === 'webp')) unlink($source);
29
- }
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/Action/Dir.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Action;
4
-
5
- class Dir
6
- {
7
- public function __construct()
8
- {
9
- add_filter('webpc_dir_files', [$this, 'getFilesByDirectory'], 10, 3);
10
- }
11
-
12
- /* ---
13
- Functions
14
- --- */
15
-
16
- public function getFilesByDirectory($value, $dirPath, $skipExists = false)
17
- {
18
- if (!file_exists($dirPath)) return $value;
19
-
20
- $settings = apply_filters('webpc_get_values', []);
21
- $excluded = apply_filters('webpc_dir_excluded', []);
22
-
23
- $paths = $this->findFilesInDirectory($dirPath, $settings['extensions'], $excluded);
24
- return apply_filters('webpc_attachment_paths', $paths, $skipExists);
25
- }
26
-
27
- private function findFilesInDirectory($dirPath, $allowedExts, $excludedDirs)
28
- {
29
- $paths = scandir($dirPath);
30
- $list = [];
31
- foreach ($paths as $path) {
32
- if (in_array($path, $excludedDirs)) continue;
33
-
34
- $currentPath = $dirPath . '/' . $path;
35
- if (is_dir($currentPath)) {
36
- $list = array_merge($list, $this->findFilesInDirectory($currentPath, $allowedExts, $excludedDirs));
37
- } else if (in_array(strtolower(pathinfo($currentPath, PATHINFO_EXTENSION)), $allowedExts)) {
38
- $list[] = $currentPath;
39
- }
40
- }
41
- return $list;
42
- }
43
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/Action/Regenerate.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Action;
4
-
5
- use WebpConverter\Regenerate\Paths;
6
-
7
- class Regenerate
8
- {
9
- public function __construct()
10
- {
11
- add_action('webpc_regenerate_all', [$this, 'runRegenerationAllImages']);
12
- }
13
-
14
- /* ---
15
- Functions
16
- --- */
17
-
18
- public function runRegenerationAllImages()
19
- {
20
- $paths = (new Paths())->getPaths(true);
21
- do_action('webpc_convert_paths', $paths);
22
- }
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/Action/_Core.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Action;
4
-
5
- class _Core
6
- {
7
- public function __construct()
8
- {
9
- new Convert();
10
- new Delete();
11
- new Dir();
12
- new Regenerate();
13
- }
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/Admin/Activation.php CHANGED
@@ -4,12 +4,9 @@
4
 
5
  class Activation
6
  {
7
- private $phpVersion = '7.0.0';
8
-
9
  public function __construct()
10
  {
11
  register_activation_hook(WEBPC_FILE, [$this, 'disablePluginForOldPhp']);
12
- register_activation_hook(WEBPC_FILE, [$this, 'createDirectoryForUploadsWebp']);
13
  register_activation_hook(WEBPC_FILE, [$this, 'addDefaultOptions']);
14
  register_activation_hook(WEBPC_FILE, [$this, 'refreshRewriteRules']);
15
  }
@@ -20,32 +17,26 @@
20
 
21
  public function disablePluginForOldPhp()
22
  {
23
- if (version_compare(PHP_VERSION, $this->phpVersion, '>=')) return;
24
 
25
  deactivate_plugins(basename(WEBPC_FILE));
26
  wp_die(sprintf(
27
- __('%sWebP Converter for Media%s plugin requires a minimum PHP %s version. Sorry about that!', 'webp-converter-for-media'),
28
  '<strong>',
29
  '</strong>',
30
- $this->phpVersion
31
  ));
32
  }
33
 
34
- public function createDirectoryForUploadsWebp()
35
- {
36
- $path = apply_filters('webpc_uploads_webp', '');
37
- if (!file_exists($path) && is_writable(dirname($path))) mkdir($path);
38
- }
39
-
40
  public function addDefaultOptions()
41
  {
42
- if (get_option('webpc_notice_hidden', false) !== false) return;
43
- add_option('webpc_notice_hidden', strtotime('+ 1 week'));
 
44
  }
45
 
46
  public function refreshRewriteRules()
47
  {
48
- do_action('webpc_rewrite_htaccess', true);
49
  flush_rewrite_rules(true);
50
  }
51
  }
4
 
5
  class Activation
6
  {
 
 
7
  public function __construct()
8
  {
9
  register_activation_hook(WEBPC_FILE, [$this, 'disablePluginForOldPhp']);
 
10
  register_activation_hook(WEBPC_FILE, [$this, 'addDefaultOptions']);
11
  register_activation_hook(WEBPC_FILE, [$this, 'refreshRewriteRules']);
12
  }
17
 
18
  public function disablePluginForOldPhp()
19
  {
20
+ if (version_compare(PHP_VERSION, '5.6.12', '>=')) return;
21
 
22
  deactivate_plugins(basename(WEBPC_FILE));
23
  wp_die(sprintf(
24
+ __('%sWebP Converter for Media%s plugin requires a minimum PHP %s version. Sorry about that!', 'webp-converter'),
25
  '<strong>',
26
  '</strong>',
27
+ $this->version
28
  ));
29
  }
30
 
 
 
 
 
 
 
31
  public function addDefaultOptions()
32
  {
33
+ if (get_option('webpc_notice_hidden', false) === false) {
34
+ add_option('webpc_notice_hidden', strtotime('+ 1 week'));
35
+ }
36
  }
37
 
38
  public function refreshRewriteRules()
39
  {
 
40
  flush_rewrite_rules(true);
41
  }
42
  }
app/Admin/Deactivation.php CHANGED
@@ -15,7 +15,6 @@
15
 
16
  public function refreshRewriteRules()
17
  {
18
- do_action('webpc_rewrite_htaccess', false);
19
  flush_rewrite_rules(true);
20
  }
21
  }
15
 
16
  public function refreshRewriteRules()
17
  {
 
18
  flush_rewrite_rules(true);
19
  }
20
  }
app/Admin/Notice.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  class Notice
6
  {
7
- private $optionKey = 'webpc_notice_hidden';
8
 
9
  public function __construct()
10
  {
@@ -26,7 +26,7 @@
26
  public function showAdminNotice()
27
  {
28
  if (($_SERVER['PHP_SELF'] !== '/wp-admin/index.php') ||
29
- (get_option($this->optionKey, 0) >= time())) return;
30
 
31
  require_once WEBPC_PATH . 'resources/components/notices/thanks.php';
32
  }
@@ -41,7 +41,7 @@
41
 
42
  public function saveOption($value)
43
  {
44
- if (get_option($this->optionKey, false) !== false) update_option($this->optionKey, $value);
45
- else add_option($this->optionKey, $value);
46
  }
47
  }
4
 
5
  class Notice
6
  {
7
+ private $option = 'webpc_notice_hidden';
8
 
9
  public function __construct()
10
  {
26
  public function showAdminNotice()
27
  {
28
  if (($_SERVER['PHP_SELF'] !== '/wp-admin/index.php') ||
29
+ (get_option($this->option, 0) >= time())) return;
30
 
31
  require_once WEBPC_PATH . 'resources/components/notices/thanks.php';
32
  }
41
 
42
  public function saveOption($value)
43
  {
44
+ if (get_option($this->option, false) !== false) update_option($this->option, $value);
45
+ else add_option($this->option, $value);
46
  }
47
  }
app/Admin/Plugin.php CHANGED
@@ -6,29 +6,23 @@
6
  {
7
  public function __construct()
8
  {
9
- add_filter('plugin_action_links_' . WEBPC_NAME, [$this, 'addLinkToSettings']);
10
- add_filter('plugin_action_links_' . WEBPC_NAME, [$this, 'addLinkToDonate']);
11
- add_filter('network_admin_plugin_action_links_' . WEBPC_NAME, [$this, 'addLinkToDonate']);
12
  }
13
 
14
  /* ---
15
  Functions
16
  --- */
17
 
18
- public function addLinkToSettings($links)
19
  {
20
  array_unshift($links, sprintf(
21
- __('%sSettings%s', 'webp-converter-for-media'),
22
  '<a href="' . menu_page_url('webpc_admin_page', false) . '">',
23
  '</a>'
24
  ));
25
- return $links;
26
- }
27
-
28
- public function addLinkToDonate($links)
29
- {
30
  $links[] = sprintf(
31
- __('%sProvide us a coffee%s', 'webp-converter-for-media'),
32
  '<a href="https://ko-fi.com/gbiorczyk/" target="_blank">',
33
  '</a>'
34
  );
6
  {
7
  public function __construct()
8
  {
9
+ add_filter('network_admin_plugin_action_links_' . WEBPC_NAME, [$this, 'addPluginLinks']);
10
+ add_filter('plugin_action_links_' . WEBPC_NAME, [$this, 'addPluginLinks']);
 
11
  }
12
 
13
  /* ---
14
  Functions
15
  --- */
16
 
17
+ public function addPluginLinks($links)
18
  {
19
  array_unshift($links, sprintf(
20
+ __('%sSettings%s', 'webp-converter'),
21
  '<a href="' . menu_page_url('webpc_admin_page', false) . '">',
22
  '</a>'
23
  ));
 
 
 
 
 
24
  $links[] = sprintf(
25
+ __('%sProvide us a coffee%s', 'webp-converter'),
26
  '<a href="https://ko-fi.com/gbiorczyk/" target="_blank">',
27
  '</a>'
28
  );
app/Admin/Uninstall.php CHANGED
@@ -17,21 +17,13 @@
17
  {
18
  delete_option('webpc_settings');
19
  delete_option('webpc_notice_hidden');
20
- delete_option('webpc_latest_version');
21
 
22
- self::removeHtaccessFile();
23
  self::removeWebpFiles();
24
  }
25
 
26
- private static function removeHtaccessFile()
27
- {
28
- $path = sprintf('%s/.htaccess', apply_filters('webpc_uploads_webp', ''));
29
- if (is_writable($path)) unlink($path);
30
- }
31
-
32
  public static function removeWebpFiles()
33
  {
34
- $path = apply_filters('webpc_uploads_webp', '');
35
  $paths = self::getPathsFromLocation($path);
36
  $paths[] = $path;
37
  self::removeFiles($paths);
17
  {
18
  delete_option('webpc_settings');
19
  delete_option('webpc_notice_hidden');
 
20
 
 
21
  self::removeWebpFiles();
22
  }
23
 
 
 
 
 
 
 
24
  public static function removeWebpFiles()
25
  {
26
+ $path = ABSPATH . apply_filters('webpc_uploads_webp', 'wp-content/uploads-webpc');
27
  $paths = self::getPathsFromLocation($path);
28
  $paths[] = $path;
29
  self::removeFiles($paths);
app/Admin/Update.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Admin;
4
-
5
- class Update
6
- {
7
- private $optionVersion = 'webpc_latest_version';
8
- private $optionSettings = 'webpc_settings';
9
-
10
- public function __construct()
11
- {
12
- add_action('admin_init', [$this, 'runActionsAfterUpdate']);
13
- }
14
-
15
- /* ---
16
- Functions
17
- --- */
18
-
19
- public function runActionsAfterUpdate()
20
- {
21
- $version = get_option($this->optionVersion, null);
22
- if ($version === WEBPC_VERSION) return;
23
-
24
- if ($version !== null) {
25
- $this->saveOptionValue($this->optionSettings, $this->updateSettingsForOldVersions($version));
26
- $this->moveFilesToUploadsSubdirectory($this->optionVersion);
27
- }
28
-
29
- do_action('webpc_rewrite_htaccess', true);
30
- flush_rewrite_rules(true);
31
- $this->saveOptionValue($this->optionVersion, WEBPC_VERSION);
32
- }
33
-
34
- private function updateSettingsForOldVersions($version)
35
- {
36
- $settings = apply_filters('webpc_get_values', []);
37
-
38
- if (version_compare($version, '1.1.2', '<=') && !in_array('only_smaller', $settings['features'])) {
39
- $settings['features'][] = 'only_smaller';
40
- }
41
-
42
- if (version_compare($version, '1.2.7', '<=') && !isset($settings['dirs'])) {
43
- $settings['dirs'] = ['uploads'];
44
- }
45
-
46
- return $settings;
47
- }
48
-
49
- private function saveOptionValue($optionKey, $value)
50
- {
51
- if (get_option($optionKey, false) !== false) update_option($optionKey, $value);
52
- else add_option($optionKey, $value);
53
- }
54
-
55
- private function moveFilesToUploadsSubdirectory($version)
56
- {
57
- if (version_compare($version, '1.2.7', '>')) return;
58
-
59
- $webpRoot = apply_filters('webpc_uploads_webp', '');
60
- if (!is_writable($webpRoot)) return;
61
-
62
- $pathParts = explode('/', apply_filters('webpc_uploads_dir', ''));
63
- $oldPaths = scandir(apply_filters('webpc_uploads_webp', ''));
64
- for ($i = 1; $i <= count($pathParts); $i++) {
65
- $dirPath = $webpRoot . '/' . implode('/', array_slice($pathParts, 0, $i));
66
- if (!file_exists($dirPath)) mkdir($dirPath);
67
- }
68
-
69
- foreach ($oldPaths as $path) {
70
- if (in_array($path, ['.', '..', '.htaccess', $pathParts[0]])) continue;
71
- rename($webpRoot . '/'. $path, $dirPath . '/'. $path);
72
- }
73
- }
74
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/Admin/_Core.php CHANGED
@@ -12,6 +12,5 @@
12
  new Notice();
13
  new Plugin();
14
  new Uninstall();
15
- new Update();
16
  }
17
  }
12
  new Notice();
13
  new Plugin();
14
  new Uninstall();
 
15
  }
16
  }
app/Convert/Directory.php CHANGED
@@ -10,12 +10,9 @@
10
 
11
  public function getPath($path, $createDirectory = false)
12
  {
13
- $webpRoot = apply_filters('webpc_uploads_webp', '');
14
- $uploadsRoot = dirname($webpRoot);
15
- $outputPath = str_replace(realpath($uploadsRoot), '', realpath($path));
16
- $outputPath = trim($outputPath, '\/');
17
-
18
- $newPath = sprintf('%s/%s.webp', $webpRoot, $outputPath);
19
  if (!$createDirectory) return $newPath;
20
 
21
  if (!$paths = $this->checkDirectories($newPath)) return $newPath;
10
 
11
  public function getPath($path, $createDirectory = false)
12
  {
13
+ $pathSource = apply_filters('webpc_uploads_path', '');
14
+ $pathOutput = apply_filters('webpc_uploads_webp', '');
15
+ $newPath = str_replace("/${pathSource}/", "/${pathOutput}/", $path) . '.webp';
 
 
 
16
  if (!$createDirectory) return $newPath;
17
 
18
  if (!$paths = $this->checkDirectories($newPath)) return $newPath;
app/Convert/Gd.php CHANGED
@@ -10,11 +10,13 @@
10
 
11
  public function convertImage($path, $quality)
12
  {
13
- (new Server())->setSettings();
 
14
 
15
  try {
16
- $status = (new Server())->checkIfFileExists($path);
17
- if ($status !== true) throw new \Exception($status);
 
18
 
19
  $response = $this->createImage($path);
20
  if (!$response['success']) throw new \Exception($response['message']);
@@ -41,7 +43,7 @@
41
 
42
  private function createImage($path)
43
  {
44
- $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
45
  $methods = apply_filters('webpc_gd_create_methods', [
46
  'imagecreatefromjpeg' => ['jpg', 'jpeg'],
47
  'imagecreatefrompng' => ['png'],
@@ -100,7 +102,9 @@
100
  private function convertToWebp($image, $path, $quality)
101
  {
102
  try {
103
- $output = (new Directory())->getPath($path, true);
 
 
104
  if (!$output) {
105
  throw new \Exception(sprintf('An error occurred creating destination directory for "%s" file.', $path));
106
  } else if (!function_exists('imagewebp')) {
@@ -112,14 +116,13 @@
112
  }
113
 
114
  if (filesize($output) % 2 === 1) file_put_contents($output, "\0", FILE_APPEND);
115
- do_action('webpc_convert_after', $output, $path);
116
-
117
  return [
118
  'success' => true,
119
  'data' => [
 
120
  'size' => [
121
  'before' => filesize($path),
122
- 'after' => filesize((file_exists($output)) ? $output : $path),
123
  ],
124
  ],
125
  ];
10
 
11
  public function convertImage($path, $quality)
12
  {
13
+ ini_set('memory_limit', '1G');
14
+ set_time_limit(120);
15
 
16
  try {
17
+ if (!is_writable($path)) {
18
+ throw new \Exception(sprintf('File "%s" does not exist.', $path));
19
+ }
20
 
21
  $response = $this->createImage($path);
22
  if (!$response['success']) throw new \Exception($response['message']);
43
 
44
  private function createImage($path)
45
  {
46
+ $extension = pathinfo($path, PATHINFO_EXTENSION);
47
  $methods = apply_filters('webpc_gd_create_methods', [
48
  'imagecreatefromjpeg' => ['jpg', 'jpeg'],
49
  'imagecreatefrompng' => ['png'],
102
  private function convertToWebp($image, $path, $quality)
103
  {
104
  try {
105
+ $directory = new Directory();
106
+ $output = $directory->getPath($path, true);
107
+
108
  if (!$output) {
109
  throw new \Exception(sprintf('An error occurred creating destination directory for "%s" file.', $path));
110
  } else if (!function_exists('imagewebp')) {
116
  }
117
 
118
  if (filesize($output) % 2 === 1) file_put_contents($output, "\0", FILE_APPEND);
 
 
119
  return [
120
  'success' => true,
121
  'data' => [
122
+ 'path' => $output,
123
  'size' => [
124
  'before' => filesize($path),
125
+ 'after' => filesize($output),
126
  ],
127
  ],
128
  ];
app/Convert/Imagick.php CHANGED
@@ -10,11 +10,13 @@
10
 
11
  public function convertImage($path, $quality)
12
  {
13
- (new Server())->setSettings();
 
14
 
15
  try {
16
- $status = (new Server())->checkIfFileExists($path);
17
- if ($status !== true) throw new \Exception($status);
 
18
 
19
  $response = $this->createImage($path);
20
  if (!$response['success']) throw new \Exception($response['message']);
@@ -37,7 +39,7 @@
37
 
38
  private function createImage($path)
39
  {
40
- $extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
41
  try {
42
  if (!extension_loaded('imagick') || !class_exists('Imagick')) {
43
  throw new \Exception('Server configuration: Imagick module is not available with this PHP installation.');
@@ -63,7 +65,8 @@
63
  private function convertToWebp($image, $path, $quality)
64
  {
65
  try {
66
- $output = (new Directory())->getPath($path, true);
 
67
  if (!$output) {
68
  throw new \Exception(sprintf('An error occurred creating destination directory for "%s" file.', $path));
69
  } else if (!in_array('WEBP', $image->queryFormats())) {
@@ -79,14 +82,14 @@
79
  if (!$success) {
80
  throw new \Exception('Error occurred while converting image.');
81
  }
82
- do_action('webpc_convert_after', $output, $path);
83
 
84
  return [
85
  'success' => true,
86
  'data' => [
 
87
  'size' => [
88
  'before' => filesize($path),
89
- 'after' => filesize((file_exists($output)) ? $output : $path),
90
  ],
91
  ],
92
  ];
10
 
11
  public function convertImage($path, $quality)
12
  {
13
+ ini_set('memory_limit', '1G');
14
+ set_time_limit(120);
15
 
16
  try {
17
+ if (!is_writable($path)) {
18
+ throw new \Exception(sprintf('File "%s" does not exist.', $path));
19
+ }
20
 
21
  $response = $this->createImage($path);
22
  if (!$response['success']) throw new \Exception($response['message']);
39
 
40
  private function createImage($path)
41
  {
42
+ $extension = pathinfo($path, PATHINFO_EXTENSION);
43
  try {
44
  if (!extension_loaded('imagick') || !class_exists('Imagick')) {
45
  throw new \Exception('Server configuration: Imagick module is not available with this PHP installation.');
65
  private function convertToWebp($image, $path, $quality)
66
  {
67
  try {
68
+ $directory = new Directory();
69
+ $output = $directory->getPath($path, true);
70
  if (!$output) {
71
  throw new \Exception(sprintf('An error occurred creating destination directory for "%s" file.', $path));
72
  } else if (!in_array('WEBP', $image->queryFormats())) {
82
  if (!$success) {
83
  throw new \Exception('Error occurred while converting image.');
84
  }
 
85
 
86
  return [
87
  'success' => true,
88
  'data' => [
89
+ 'path' => $output,
90
  'size' => [
91
  'before' => filesize($path),
92
+ 'after' => filesize($output),
93
  ],
94
  ],
95
  ];
app/Convert/Server.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Convert;
4
-
5
- class Server
6
- {
7
- /* ---
8
- Functions
9
- --- */
10
-
11
- public function setSettings()
12
- {
13
- ini_set('memory_limit', '1G');
14
-
15
- if (strpos(ini_get('disable_functions'), 'set_time_limit') === false) {
16
- set_time_limit(120);
17
- }
18
- }
19
-
20
- public function checkIfFileExists($path)
21
- {
22
- if (is_readable($path)) return true;
23
- else if (!file_exists($path)) return sprintf('File "%s" does not exist. Please check file path using.', $path);
24
- else return sprintf('File "%s" is unreadable. Please check file permissions.', $path);
25
- }
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/Convert/Size.php DELETED
@@ -1,29 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Convert;
4
-
5
- class Size
6
- {
7
- public function __construct()
8
- {
9
- add_action('webpc_convert_after', [$this, 'removeImageIfIsLarger'], 10, 2);
10
- }
11
-
12
- /* ---
13
- Functions
14
- --- */
15
-
16
- public function removeImageIfIsLarger($webpPath, $originalPath)
17
- {
18
- if ((!$settings = apply_filters('webpc_get_values', []))
19
- || !in_array('only_smaller', $settings['features'])
20
- || (!file_exists($webpPath) || !file_exists($originalPath))
21
- || (filesize($webpPath) < filesize($originalPath))) return;
22
-
23
- error_log(sprintf(
24
- 'WebP Converter for Media (Information): Image `%s` converted to WebP is larger than original and has been deleted.',
25
- $webpPath
26
- ));
27
- unlink($webpPath);
28
- }
29
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/Convert/_Core.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Convert;
4
-
5
- class _Core
6
- {
7
- public function __construct()
8
- {
9
- new Size();
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
app/Media/Attachment.php DELETED
@@ -1,54 +0,0 @@
1
- <?php
2
-
3
- namespace WebpConverter\Media;
4
-
5
- class Attachment
6
- {
7
- private $settings, $uploadDir, $imageSizes;
8
-
9
- public function __construct()
10
- {
11
- $this->settings = apply_filters('webpc_get_values', []);
12
- $this->uploadDir = wp_upload_dir();
13
- $this->imageSizes = get_intermediate_image_sizes();
14
- }
15
-
16
- /* ---
17
- Functions
18
- --- */
19
-
20
- public function getAttachmentPaths($attachmentId)
21
- {
22
- $paths = $this->getPathsByAttachment($attachmentId);
23
- return $paths;
24
- }
25
-
26
- private function getPathsByAttachment($postId)
27
- {
28
- $list = [];
29
- $metadata = wp_get_attachment_metadata($postId);
30
- if (!$metadata) return $list;
31
-
32
- $extension = strtolower(pathinfo($metadata['file'], PATHINFO_EXTENSION));
33
- if (!isset($metadata['file'])
34
- || !in_array($extension, $this->settings['extensions'])) return $list;
35
-
36
- $paths = $this->getPathsBySizes($postId, $metadata['file']);
37
- $paths = apply_filters('webpc_attachment_paths', $paths, $postId);
38
- return $paths;
39
- }
40
-
41
- private function getPathsBySizes($postId, $path)
42
- {
43
- $list = [];
44
- $list[] = str_replace('\\', '/', implode('/', [$this->uploadDir['basedir'], $path]));
45
-
46
- foreach ($this->imageSizes as $size) {
47
- $src = wp_get_attachment_image_src($postId, $size);
48
- $url = str_replace($this->uploadDir['baseurl'], $this->uploadDir['basedir'], $src[0]);
49
- $url = str_replace('\\', '/', $url);
50
- $list[] = $url;
51
- }
52
- return array_values(array_unique($list));
53
- }
54
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/Media/Delete.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace WebpConverter\Media;
4
 
 
 
5
  class Delete
6
  {
7
  public function __construct()
@@ -15,7 +17,9 @@
15
 
16
  public function deleteAttachmentFile($path)
17
  {
18
- do_action('webpc_delete_paths', [$path]);
 
 
19
  return $path;
20
  }
21
  }
2
 
3
  namespace WebpConverter\Media;
4
 
5
+ use WebpConverter\Convert as Convert;
6
+
7
  class Delete
8
  {
9
  public function __construct()
17
 
18
  public function deleteAttachmentFile($path)
19
  {
20
+ $directory = new Convert\Directory();
21
+ $source = $directory->getPath($path);
22
+ if (is_writable($source) && (pathinfo($source, PATHINFO_EXTENSION) === 'webp')) unlink($source);
23
  return $path;
24
  }
25
  }
app/Media/Htaccess.php CHANGED
@@ -6,80 +6,62 @@
6
  {
7
  public function __construct()
8
  {
9
- add_action('webpc_rewrite_htaccess', [$this, 'addRewriteRulesToWpContent'], 10, 1);
10
- add_action('webpc_rewrite_htaccess', [$this, 'addRewriteRulesToUploads'], 10, 1);
11
- add_action('webpc_rewrite_htaccess', [$this, 'addRewriteRulesToUploadsWebp'], 10, 1);
12
  }
13
 
14
  /* ---
15
  Functions
16
  --- */
17
 
18
- public function addRewriteRulesToWpContent($isActive)
19
  {
20
- $path = dirname(apply_filters('webpc_uploads_path', ''));
21
- if (!$isActive) return $this->saveRewritesInHtaccesss($path);
22
 
23
  $values = apply_filters('webpc_get_values', []);
24
- $rows = [
25
- $this->getModRewriteRules($values),
26
- ];
27
-
28
- $content = $this->addCommentsToRules($rows);
29
- $content = apply_filters('webpc_htaccess_rules', $content, $path . '/.htaccess');
30
- $this->saveRewritesInHtaccesss($path, $content);
31
- }
32
-
33
- public function addRewriteRulesToUploads($isActive)
34
- {
35
- $path = apply_filters('webpc_uploads_path', '');
36
- if (!$isActive) return $this->saveRewritesInHtaccesss($path);
37
 
38
- $values = apply_filters('webpc_get_values', []);
39
- $rows = [
40
- $this->getModRewriteRules($values, apply_filters('webpc_uploads_dir', '')),
41
- ];
42
 
 
43
  $content = $this->addCommentsToRules($rows);
44
- $content = apply_filters('webpc_htaccess_rules', $content, $path . '/.htaccess');
45
- $this->saveRewritesInHtaccesss($path, $content);
46
  }
47
 
48
- public function addRewriteRulesToUploadsWebp($isActive)
49
  {
50
- $path = apply_filters('webpc_uploads_webp', '');
51
- if (!$isActive) return $this->saveRewritesInHtaccesss($path);
52
 
53
- $values = apply_filters('webpc_get_values', []);
54
- $rows = [
55
- $this->getModMimeRules($values),
56
- $this->getModExpiresRules($values),
57
- ];
58
 
59
- $content = $this->addCommentsToRules($rows);
60
- $content = apply_filters('webpc_htaccess_rules', $content, $path . '/.htaccess');
61
- $this->saveRewritesInHtaccesss($path, $content);
62
  }
63
 
64
- private function getModRewriteRules($settings, $outputPath = null)
65
  {
66
  $content = '';
67
  if (!$settings['extensions']) return $content;
68
 
69
- $path = apply_filters('webpc_uploads_prefix', '/');
70
- $path .= apply_filters('webpc_uploads_webp', '', true);
71
- if ($outputPath !== null) $path .= '/' . $outputPath;
72
 
73
  $content .= '<IfModule mod_rewrite.c>' . PHP_EOL;
74
  $content .= ' RewriteEngine On' . PHP_EOL;
75
  foreach ($settings['extensions'] as $ext) {
76
  $content .= ' RewriteCond %{HTTP_ACCEPT} image/webp' . PHP_EOL;
77
- $content .= " RewriteCond %{DOCUMENT_ROOT}${path}/$1.${ext}.webp -f" . PHP_EOL;
78
- $content .= " RewriteRule (.+)\.${ext}$ ${path}/$1.${ext}.webp [NC,T=image/webp,E=cache-control:private,L]" . PHP_EOL;
79
  }
80
  $content .= '</IfModule>';
81
 
82
- $content = apply_filters('webpc_htaccess_mod_rewrite', $content, $path);
83
  return $content;
84
  }
85
 
@@ -97,44 +79,20 @@
97
  return $content;
98
  }
99
 
100
- private function getModMimeRules($settings)
101
- {
102
- $content = '';
103
- if (!$settings['extensions']) return $content;
104
-
105
- $content .= '<IfModule mod_mime.c>' . PHP_EOL;
106
- $content .= ' AddType image/webp .webp' . PHP_EOL;
107
- $content .= '</IfModule>';
108
-
109
- $content = apply_filters('webpc_htaccess_mod_mime', $content);
110
- return $content;
111
- }
112
-
113
  private function addCommentsToRules($rules)
114
  {
115
- if (!$rules) return '';
 
116
 
117
  $rows = [];
118
- $rows[] = '';
119
  $rows[] = '# BEGIN WebP Converter';
120
- $rows[] = '# ! --- DO NOT EDIT PREVIOUS LINE --- !';
121
- $rows = array_merge($rows, array_filter($rules));
122
- $rows[] = '# ! --- DO NOT EDIT NEXT LINE --- !';
123
  $rows[] = '# END WebP Converter';
124
- $rows[] = '';
125
-
126
- return implode(PHP_EOL, $rows);
127
- }
128
 
129
- private function saveRewritesInHtaccesss($pathDir, $rules = '')
130
- {
131
- $pathFile = $pathDir . '/.htaccess';
132
-
133
- $code = (is_readable($pathFile)) ? file_get_contents($pathFile) : '';
134
- $code = preg_replace('/((:?[\r\n|\r|\n]?)# BEGIN WebP Converter(.*?)# END WebP Converter(:?(:?[\r\n|\r|\n]+)?))/s', '', $code);
135
- if ($rules && $code) $code = PHP_EOL . $code;
136
- $code = $rules . $code;
137
-
138
- if (is_writable($pathDir)) file_put_contents($pathFile, $code);
139
  }
140
  }
6
  {
7
  public function __construct()
8
  {
9
+ add_filter('mod_rewrite_rules', [$this, 'addRewriteRules']);
 
 
10
  }
11
 
12
  /* ---
13
  Functions
14
  --- */
15
 
16
+ public function addRewriteRules($rules)
17
  {
18
+ if (isset($_GET['plugin']) && ($_GET['plugin'] === 'webp-converter-for-media/webp-converter-for-media.php')
19
+ && isset($_GET['action']) && ($_GET['action'] === 'deactivate')) return $rules;
20
 
21
  $values = apply_filters('webpc_get_values', []);
22
+ $rows = [];
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ $rows[] = $this->getModMimeRules($values);
25
+ $rows[] = $this->getModRewriteRules($values);
26
+ $rows[] = $this->getModExpiresRules($values);
 
27
 
28
+ $rows = array_filter($rows);
29
  $content = $this->addCommentsToRules($rows);
30
+ return $content . $rules;
 
31
  }
32
 
33
+ private function getModMimeRules($settings)
34
  {
35
+ $content = '';
36
+ if (!$settings['extensions']) return $content;
37
 
38
+ $content .= '<IfModule mod_mime.c>' . PHP_EOL;
39
+ $content .= ' AddType image/webp .webp' . PHP_EOL;
40
+ $content .= '</IfModule>';
 
 
41
 
42
+ $content = apply_filters('webpc_htaccess_mod_mime', $content);
43
+ return $content;
 
44
  }
45
 
46
+ private function getModRewriteRules($settings)
47
  {
48
  $content = '';
49
  if (!$settings['extensions']) return $content;
50
 
51
+ $pathUrl = parse_url(site_url('/'), PHP_URL_PATH);
52
+ $pathSource = apply_filters('webpc_uploads_path', '');
53
+ $pathOutput = apply_filters('webpc_uploads_webp', '');
54
 
55
  $content .= '<IfModule mod_rewrite.c>' . PHP_EOL;
56
  $content .= ' RewriteEngine On' . PHP_EOL;
57
  foreach ($settings['extensions'] as $ext) {
58
  $content .= ' RewriteCond %{HTTP_ACCEPT} image/webp' . PHP_EOL;
59
+ $content .= " RewriteCond %{DOCUMENT_ROOT}${pathUrl}${pathOutput}/$1.${ext}.webp -f" . PHP_EOL;
60
+ $content .= " RewriteRule ${pathSource}/(.+)\.${ext}$ ${pathOutput}/$1.${ext}.webp [T=image/webp]" . PHP_EOL;
61
  }
62
  $content .= '</IfModule>';
63
 
64
+ $content = apply_filters('webpc_htaccess_mod_rewrite', $content);
65
  return $content;
66
  }
67
 
79
  return $content;
80
  }
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  private function addCommentsToRules($rules)
83
  {
84
+ $content = '';
85
+ if (!$rules) return $content;
86
 
87
  $rows = [];
88
+ $rows[] = PHP_EOL;
89
  $rows[] = '# BEGIN WebP Converter';
90
+ $rows = array_merge($rows, $rules);
 
 
91
  $rows[] = '# END WebP Converter';
92
+ $rows[] = PHP_EOL;
 
 
 
93
 
94
+ $content = implode(PHP_EOL, $rows);
95
+ $content = apply_filters('webpc_htaccess_rules', $content);
96
+ return $content;
 
 
 
 
 
 
 
97
  }
98
  }
app/Media/Upload.php CHANGED
@@ -2,10 +2,10 @@
2
 
3
  namespace WebpConverter\Media;
4
 
 
 
5
  class Upload
6
  {
7
- private $convertedPaths = [];
8
-
9
  public function __construct()
10
  {
11
  add_filter('wp_update_attachment_metadata', [$this, 'initAttachmentConvert'], 10, 2);
@@ -18,28 +18,19 @@
18
  public function initAttachmentConvert($data, $attachmentId)
19
  {
20
  if (!$data || !isset($data['file']) || !isset($data['sizes'])) return $data;
 
 
21
 
22
- $paths = $this->getSizesPaths($data);
23
- $paths = apply_filters('webpc_attachment_paths', $paths, $attachmentId);
24
-
25
- $paths = array_diff($paths, $this->convertedPaths);
26
- $this->convertedPaths = array_merge($this->convertedPaths, $paths);
27
-
28
- do_action('webpc_convert_paths', $paths);
29
- return $data;
30
- }
31
-
32
- private function getSizesPaths($data)
33
- {
34
- $directory = $this->getAttachmentDirectory($data['file']);
35
- $list = [];
36
-
37
- $list[] = $directory . basename($data['file']);
38
  foreach ($data['sizes'] as $key => $size) {
39
- $path = $directory . $size['file'];
40
- if (!in_array($path, $list)) $list[] = $path;
 
41
  }
42
- return array_values(array_unique($list));
 
 
 
43
  }
44
 
45
  private function getAttachmentDirectory($path)
@@ -49,4 +40,28 @@
49
  $source = str_replace('\\', '/', $source);
50
  return $source;
51
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
2
 
3
  namespace WebpConverter\Media;
4
 
5
+ use WebpConverter\Convert as Convert;
6
+
7
  class Upload
8
  {
 
 
9
  public function __construct()
10
  {
11
  add_filter('wp_update_attachment_metadata', [$this, 'initAttachmentConvert'], 10, 2);
18
  public function initAttachmentConvert($data, $attachmentId)
19
  {
20
  if (!$data || !isset($data['file']) || !isset($data['sizes'])) return $data;
21
+ $path = $this->getAttachmentDirectory($data['file']);
22
+ $sizes = [];
23
 
24
+ $sizes['_source'] = $path . basename($data['file']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  foreach ($data['sizes'] as $key => $size) {
26
+ $url = $path . $size['file'];
27
+ if (in_array($url, $sizes)) continue;
28
+ $sizes[$key] = $url;
29
  }
30
+
31
+ $sizes = apply_filters('webpc_attachment_paths', $sizes, $attachmentId);
32
+ $this->convertSizes($sizes);
33
+ return $data;
34
  }
35
 
36
  private function getAttachmentDirectory($path)
40
  $source = str_replace('\\', '/', $source);
41
  return $source;
42
  }
43
+
44
+ private function convertSizes($paths)
45
+ {
46
+ $settings = apply_filters('webpc_get_values', []);
47
+
48
+ if ($settings['method'] === 'gd') $convert = new Convert\Gd();
49
+ else if ($settings['method'] === 'imagick') $convert = new Convert\Imagick();
50
+ if (!isset($convert)) return false;
51
+
52
+ foreach ($paths as $path) {
53
+ if (!in_array(pathinfo($path, PATHINFO_EXTENSION), $settings['extensions'])) continue;
54
+
55
+ $response = $convert->convertImage($path, $settings['quality']);
56
+ if (!$response['success']) $this->addErrorToLog($response['message']);
57
+ }
58
+ }
59
+
60
+ private function addErrorToLog($message)
61
+ {
62
+ error_log(sprintf(
63
+ 'WebP Converter: %s',
64
+ $message
65
+ ));
66
+ }
67
  }
app/Regenerate/Endpoints.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace WebpConverter\Regenerate;
4
 
 
 
5
  class Endpoints
6
  {
7
  public $namespace = 'webp-converter/v1';
@@ -29,16 +31,7 @@
29
  && current_user_can('manage_options'));
30
  },
31
  'callback' => [$this, 'getPaths'],
32
- 'args' => [
33
- 'regenerate_force' => [
34
- 'description' => 'Option to force all images to be converted again (set `1` to enable)',
35
- 'required' => false,
36
- 'default' => false,
37
- 'sanitize_callback' => function($value, $request, $param) {
38
- return ($value === '1') ? true : false;
39
- }
40
- ],
41
- ],
42
  ]
43
  );
44
 
@@ -68,10 +61,11 @@
68
 
69
  public function getPaths($request)
70
  {
71
- $params = $request->get_params();
72
- $skipExists = (!$params['regenerate_force']) ? true : false;
73
 
74
- $data = (new Paths())->getPaths($skipExists, 10);
 
75
  if ($data !== false) return new \WP_REST_Response($data, 200);
76
  else return new \WP_Error('webpc_rest_api_error', null, ['status' => 405]);
77
  }
@@ -79,7 +73,8 @@
79
  public function convertImages($request)
80
  {
81
  $params = $request->get_params();
82
- $data = (new Regenerate())->convertImages($params['paths']);
 
83
  if ($data !== false) return new \WP_REST_Response($data, 200);
84
  else return new \WP_Error('webpc_rest_api_error', null, ['status' => 405]);
85
  }
2
 
3
  namespace WebpConverter\Regenerate;
4
 
5
+ use WebpConverter\Convert as Convert;
6
+
7
  class Endpoints
8
  {
9
  public $namespace = 'webp-converter/v1';
31
  && current_user_can('manage_options'));
32
  },
33
  'callback' => [$this, 'getPaths'],
34
+ 'args' => [],
 
 
 
 
 
 
 
 
 
35
  ]
36
  );
37
 
61
 
62
  public function getPaths($request)
63
  {
64
+ $params = $request->get_params();
65
+ if (isset($params['skip']) && $params['skip']) new Skip();
66
 
67
+ $api = new Paths();
68
+ $data = $api->getPaths();
69
  if ($data !== false) return new \WP_REST_Response($data, 200);
70
  else return new \WP_Error('webpc_rest_api_error', null, ['status' => 405]);
71
  }
73
  public function convertImages($request)
74
  {
75
  $params = $request->get_params();
76
+ $api = new Regenerate();
77
+ $data = $api->convertImages($params['paths']);
78
  if ($data !== false) return new \WP_REST_Response($data, 200);
79
  else return new \WP_Error('webpc_rest_api_error', null, ['status' => 405]);
80
  }
app/Regenerate/Paths.php CHANGED
@@ -8,20 +8,56 @@
8
  Functions
9
  --- */
10
 
11
- public function getPaths($skipExists = false, $chunkSize = null)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  {
13
  $settings = apply_filters('webpc_get_values', []);
14
- $dirs = array_filter(array_map(function($dirName) {
15
- return apply_filters('webpc_dir_path', '', $dirName);
16
- }, $settings['dirs']));
17
 
18
- $list = [];
19
- foreach ($dirs as $dirPath) {
20
- $paths = apply_filters('webpc_dir_files', [], $dirPath, $skipExists);
21
- $list = array_merge($list, $paths);
 
 
 
 
 
 
22
  }
23
 
24
- if ($chunkSize === null) return $list;
25
- return array_chunk($list, $chunkSize);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
  }
8
  Functions
9
  --- */
10
 
11
+ public function getPaths()
12
+ {
13
+ $sizes = get_intermediate_image_sizes();
14
+ $posts = get_posts([
15
+ 'post_type' => 'attachment',
16
+ 'post_mime_type' => 'image',
17
+ 'post_status' => 'any',
18
+ 'posts_per_page' => -1,
19
+ 'fields' => 'ids',
20
+ ]);
21
+
22
+ $list = $this->parseImages($posts, $sizes);
23
+ wp_send_json_success($list);
24
+ }
25
+
26
+ private function parseImages($posts, $sizes)
27
  {
28
  $settings = apply_filters('webpc_get_values', []);
29
+ $upload = wp_upload_dir();
30
+ $list = [];
31
+ if (!$posts) return $list;
32
 
33
+ foreach ($posts as $postId) {
34
+ $metadata = wp_get_attachment_metadata($postId);
35
+ if (!isset($metadata['file'])
36
+ || !in_array(pathinfo($metadata['file'], PATHINFO_EXTENSION), $settings['extensions'])) continue;
37
+
38
+ $paths = $this->parseImageSizes($postId, $metadata['file'], $sizes, $upload);
39
+ $paths = apply_filters('webpc_attachment_paths', $paths, $postId);
40
+
41
+ if (!$paths) continue;
42
+ $list[] = $paths;
43
  }
44
 
45
+ $list = array_filter($list);
46
+ return $list;
47
+ }
48
+
49
+ private function parseImageSizes($postId, $path, $sizes, $upload)
50
+ {
51
+ $list = [];
52
+ $list['_source'] = str_replace('\\', '/', implode('/', [$upload['basedir'], $path]));
53
+ foreach ($sizes as $size) {
54
+ $src = wp_get_attachment_image_src($postId, $size);
55
+ $url = str_replace($upload['baseurl'], $upload['basedir'], $src[0]);
56
+ $url = str_replace('\\', '/', $url);
57
+
58
+ if (in_array($url, $list)) continue;
59
+ $list[$size] = $url;
60
+ }
61
+ return $list;
62
  }
63
  }
app/Regenerate/Regenerate.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  namespace WebpConverter\Regenerate;
4
 
5
- use WebpConverter\Convert as ConvertMethod;
6
 
7
  class Regenerate
8
  {
@@ -17,12 +17,13 @@
17
  $sizeBefore = 0;
18
  $sizeAfter = 0;
19
 
20
- if ($settings['method'] === 'gd') $convert = new ConvertMethod\Gd();
21
- else if ($settings['method'] === 'imagick') $convert = new ConvertMethod\Imagick();
22
  if (!isset($convert)) return false;
23
 
24
  foreach ($paths as $path) {
25
  $response = $convert->convertImage($path, $settings['quality']);
 
26
 
27
  if ($response['success'] !== true) {
28
  $errors[] = $response['message'];
@@ -40,4 +41,11 @@
40
  ],
41
  ];
42
  }
 
 
 
 
 
 
 
43
  }
2
 
3
  namespace WebpConverter\Regenerate;
4
 
5
+ use WebpConverter\Convert as Convert;
6
 
7
  class Regenerate
8
  {
17
  $sizeBefore = 0;
18
  $sizeAfter = 0;
19
 
20
+ if ($settings['method'] === 'gd') $convert = new Convert\Gd();
21
+ else if ($settings['method'] === 'imagick') $convert = new Convert\Imagick();
22
  if (!isset($convert)) return false;
23
 
24
  foreach ($paths as $path) {
25
  $response = $convert->convertImage($path, $settings['quality']);
26
+ if ($response['success'] && !$this->checkFileSize($response['data'])) continue;
27
 
28
  if ($response['success'] !== true) {
29
  $errors[] = $response['message'];
41
  ],
42
  ];
43
  }
44
+
45
+ private function checkFileSize($data)
46
+ {
47
+ if ($data['size']['after'] < $data['size']['before']) return true;
48
+ unlink($data['path']);
49
+ return false;
50
+ }
51
  }
app/Regenerate/Skip.php CHANGED
@@ -8,18 +8,17 @@
8
  {
9
  public function __construct()
10
  {
11
- add_filter('webpc_attachment_paths', [$this, 'skipExistsImages'], 10, 2);
12
  }
13
 
14
  /* ---
15
  Functions
16
  --- */
17
 
18
- public function skipExistsImages($paths, $skipExists = false)
19
  {
20
- if (!$skipExists) return $paths;
21
-
22
  $directory = new Directory();
 
23
  foreach ($paths as $key => $path) {
24
  $output = $directory->getPath($path, false);
25
  if (file_exists($output)) unset($paths[$key]);
8
  {
9
  public function __construct()
10
  {
11
+ add_filter('webpc_attachment_paths', [$this, 'skipExistsImages']);
12
  }
13
 
14
  /* ---
15
  Functions
16
  --- */
17
 
18
+ public function skipExistsImages($paths)
19
  {
 
 
20
  $directory = new Directory();
21
+
22
  foreach ($paths as $key => $path) {
23
  $output = $directory->getPath($path, false);
24
  if (file_exists($output)) unset($paths[$key]);
app/Regenerate/_Core.php CHANGED
@@ -7,6 +7,5 @@
7
  public function __construct()
8
  {
9
  new Endpoints();
10
- new Skip();
11
  }
12
  }
7
  public function __construct()
8
  {
9
  new Endpoints();
 
10
  }
11
  }
app/Settings/Errors.php CHANGED
@@ -4,8 +4,6 @@
4
 
5
  class Errors
6
  {
7
- private $list = null;
8
-
9
  public function __construct()
10
  {
11
  add_filter('webpc_server_errors', [$this, 'getServerErrors']);
@@ -17,76 +15,38 @@
17
 
18
  public function getServerErrors()
19
  {
20
- if ($this->list !== null) return $this->list;
21
-
22
  $list = [
23
- 'path_uploads' => ($this->ifUploadsPathExists() !== true),
24
- 'path_htaccess' => ($this->ifHtaccessIsWriteable() !== true),
25
- 'path_webp' => ($this->ifWebpPathExists() !== true),
26
- 'path_duplicated' => ($this->ifPathsAreDifferent() !== true),
27
- 'rest_api' => ($this->ifRestApiIsEnabled() !== true),
28
- 'methods' => ($this->ifMethodsAreAvailable() !== true),
29
- 'bypassing_apache' => ($this->ifBypassingApacheIsActive() === true),
30
  ];
31
-
32
- $this->list = array_keys(array_filter($list));
33
- return $this->list;
34
  }
35
 
36
  private function ifUploadsPathExists()
37
  {
38
- $path = apply_filters('webpc_uploads_path', '');
39
  return (is_dir($path) && ($path !== ABSPATH));
40
  }
41
 
42
- private function ifHtaccessIsWriteable()
43
- {
44
- $pathDir = apply_filters('webpc_uploads_path', '');
45
- $pathFile = $pathDir . '/.htaccess';
46
- if (file_exists($pathFile)) return (is_readable($pathFile) && is_writable($pathFile));
47
- else return is_writable($pathDir);
48
- }
49
-
50
  private function ifWebpPathExists()
51
  {
52
- $path = apply_filters('webpc_uploads_webp', '');
53
- return (is_dir($path) || is_writable(dirname($path)));
54
- }
55
-
56
- private function ifPathsAreDifferent()
57
- {
58
- $pathUploads = apply_filters('webpc_uploads_path', '');
59
- $pathWebp = apply_filters('webpc_uploads_webp', '');
60
- return ($pathUploads !== $pathWebp);
61
  }
62
 
63
- private function ifRestApiIsEnabled()
64
  {
65
  return ((apply_filters('rest_enabled', true) === true)
66
  && (apply_filters('rest_jsonp_enabled', true) === true)
67
  && (apply_filters('rest_authentication_errors', true) === true));
68
  }
69
 
70
- private function ifMethodsAreAvailable()
71
  {
72
  $config = apply_filters('webpc_get_values', []);
73
  $methods = apply_filters('webpc_get_methods', []);
74
  return (isset($config['method']) && in_array($config['method'], $methods));
75
  }
76
-
77
- private function ifBypassingApacheIsActive()
78
- {
79
- $ctx = stream_context_create([
80
- 'http' => [
81
- 'timeout' => 1,
82
- ],
83
- ]);
84
- $filePng = @file_get_contents(WEBPC_URL . 'public/img/icon-before.png', false, $ctx);
85
- if ($filePng === false) return false;
86
-
87
- $filePng2 = @file_get_contents(WEBPC_URL . 'public/img/icon-before.png2', false, $ctx);
88
- if ($filePng2 === false) return false;
89
-
90
- return (strlen($filePng) < strlen($filePng2));
91
- }
92
  }
4
 
5
  class Errors
6
  {
 
 
7
  public function __construct()
8
  {
9
  add_filter('webpc_server_errors', [$this, 'getServerErrors']);
15
 
16
  public function getServerErrors()
17
  {
 
 
18
  $list = [
19
+ 'path_uploads' => ($this->ifUploadsPathExists() !== true),
20
+ 'path_webp' => ($this->ifWebpPathExists() !== true),
21
+ 'rest_api' => ($this->ifRestApiEnabled() !== true),
22
+ 'methods' => ($this->ifMethodsAvailable() !== true),
 
 
 
23
  ];
24
+ return array_keys(array_filter($list));
 
 
25
  }
26
 
27
  private function ifUploadsPathExists()
28
  {
29
+ $path = ABSPATH . apply_filters('webpc_uploads_path', '');
30
  return (is_dir($path) && ($path !== ABSPATH));
31
  }
32
 
 
 
 
 
 
 
 
 
33
  private function ifWebpPathExists()
34
  {
35
+ $path = ABSPATH . apply_filters('webpc_uploads_webp', '');
36
+ return ((is_dir($path) || is_writable(dirname($path))) && ($path !== ABSPATH));
 
 
 
 
 
 
 
37
  }
38
 
39
+ private function ifRestApiEnabled()
40
  {
41
  return ((apply_filters('rest_enabled', true) === true)
42
  && (apply_filters('rest_jsonp_enabled', true) === true)
43
  && (apply_filters('rest_authentication_errors', true) === true));
44
  }
45
 
46
+ private function ifMethodsAvailable()
47
  {
48
  $config = apply_filters('webpc_get_values', []);
49
  $methods = apply_filters('webpc_get_methods', []);
50
  return (isset($config['method']) && in_array($config['method'], $methods));
51
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
app/Settings/Options.php CHANGED
@@ -6,20 +6,21 @@
6
  {
7
  public function __construct()
8
  {
9
- add_filter('webpc_get_options', [$this, 'getOptions']);
 
10
  }
11
 
12
  /* ---
13
  Functions
14
  --- */
15
 
16
- public function getOptions($options)
17
  {
18
  return [
19
  [
20
  'name' => 'extensions',
21
  'type' => 'checkbox',
22
- 'label' => __('List of supported files extensions', 'webp-converter-for-media'),
23
  'info' => '',
24
  'values' => [
25
  'jpg' => '.jpg',
@@ -27,47 +28,34 @@
27
  'png' => '.png',
28
  'gif' => '.gif',
29
  ],
30
- 'disabled' => $this->getDisabledValues('extensions'),
31
- ],
32
- [
33
- 'name' => 'dirs',
34
- 'type' => 'checkbox',
35
- 'label' => __('List of supported directories', 'webp-converter-for-media'),
36
- 'info' => __('Files from these directories will be supported in WebP format.', 'webp-converter-for-media'),
37
- 'values' => [
38
- 'plugins' => '/plugins',
39
- 'themes' => '/themes',
40
- 'uploads' => '/uploads',
41
- ],
42
- 'disabled' => $this->getDisabledValues('dirs'),
43
  ],
44
  [
45
  'name' => 'method',
46
  'type' => 'radio',
47
- 'label' => __('Conversion method', 'webp-converter-for-media'),
48
- 'info' => __('The configuration for advanced users.', 'webp-converter-for-media'),
49
  'values' => [
50
- 'gd' => sprintf(__('%s (recommended)', 'webp-converter-for-media'), 'GD'),
51
  'imagick' => 'Imagick',
52
  ],
53
- 'disabled' => $this->getDisabledValues('method'),
54
  ],
55
  [
56
  'name' => 'features',
57
  'type' => 'checkbox',
58
- 'label' => __('Extra features', 'webp-converter-for-media'),
59
- 'info' => __('The options allow you to enable new functionalities that will additionally speed up your website.', 'webp-converter-for-media'),
60
  'values' => [
61
- 'only_smaller' => __('Automatic removal of WebP files larger than original', 'webp-converter-for-media'),
62
- 'mod_expires' => __('Browser Caching for WebP files (saving images in browser cache memory)', 'webp-converter-for-media'),
63
  ],
64
- 'disabled' => $this->getDisabledValues('features'),
65
  ],
66
  [
67
  'name' => 'quality',
68
  'type' => 'quality',
69
- 'label' => __('Images quality', 'webp-converter-for-media'),
70
- 'info' => __('Adjust the quality of the images being converted. Remember that higher quality also means larger file sizes. The recommended value is 85%.', 'webp-converter-for-media'),
71
  'values' => [
72
  '75' => '75%',
73
  '80' => '80%',
@@ -76,20 +64,18 @@
76
  '95' => '95%',
77
  '100' => '100%',
78
  ],
79
- 'disabled' => $this->getDisabledValues('quality'),
80
  ],
81
  ];
82
  }
83
 
84
- private function getDisabledValues($optionName)
85
  {
86
- $list = [];
87
- switch ($optionName) {
88
  case 'method':
89
  $methods = apply_filters('webpc_get_methods', []);
90
  if (!in_array('gd', $methods)) $list[] = 'gd';
91
  if (!in_array('imagick', $methods)) $list[] = 'imagick';
92
- break;
93
  }
94
  return $list;
95
  }
6
  {
7
  public function __construct()
8
  {
9
+ add_filter('webpc_get_options', [$this, 'getOptions']);
10
+ add_filter('webpc_option_disabled', [$this, 'setDisabledValues'], 10, 2);
11
  }
12
 
13
  /* ---
14
  Functions
15
  --- */
16
 
17
+ public function getOptions()
18
  {
19
  return [
20
  [
21
  'name' => 'extensions',
22
  'type' => 'checkbox',
23
+ 'label' => __('List of supported files extensions', 'webp-converter'),
24
  'info' => '',
25
  'values' => [
26
  'jpg' => '.jpg',
28
  'png' => '.png',
29
  'gif' => '.gif',
30
  ],
31
+ 'disabled' => apply_filters('webpc_option_disabled', [], 'extensions'),
 
 
 
 
 
 
 
 
 
 
 
 
32
  ],
33
  [
34
  'name' => 'method',
35
  'type' => 'radio',
36
+ 'label' => __('Conversion method', 'webp-converter'),
37
+ 'info' => __('The configuration for advanced users.', 'webp-converter'),
38
  'values' => [
39
+ 'gd' => sprintf(__('%s (recommended)', 'webp-converter'), 'GD'),
40
  'imagick' => 'Imagick',
41
  ],
42
+ 'disabled' => apply_filters('webpc_option_disabled', [], 'method'),
43
  ],
44
  [
45
  'name' => 'features',
46
  'type' => 'checkbox',
47
+ 'label' => __('Extra features', 'webp-converter'),
48
+ 'info' => __('The options allow you to enable new functionalities that will additionally speed up your website.', 'webp-converter'),
49
  'values' => [
50
+ 'mod_expires' => 'Browser Caching for .webp files (saving images in browser cache memory)',
 
51
  ],
52
+ 'disabled' => apply_filters('webpc_option_disabled', [], 'features'),
53
  ],
54
  [
55
  'name' => 'quality',
56
  'type' => 'quality',
57
+ 'label' => __('Images quality', 'webp-converter'),
58
+ 'info' => __('Adjust the quality of the images being converted. Remember that higher quality also means larger file sizes. The recommended value is 85%.', 'webp-converter'),
59
  'values' => [
60
  '75' => '75%',
61
  '80' => '80%',
64
  '95' => '95%',
65
  '100' => '100%',
66
  ],
67
+ 'disabled' => apply_filters('webpc_option_disabled', [], 'quality'),
68
  ],
69
  ];
70
  }
71
 
72
+ public function setDisabledValues($list, $name)
73
  {
74
+ switch ($name) {
 
75
  case 'method':
76
  $methods = apply_filters('webpc_get_methods', []);
77
  if (!in_array('gd', $methods)) $list[] = 'gd';
78
  if (!in_array('imagick', $methods)) $list[] = 'imagick';
 
79
  }
80
  return $list;
81
  }
app/Settings/Paths.php CHANGED
@@ -4,86 +4,32 @@
4
 
5
  class Paths
6
  {
7
- private $pathUploads = 'wp-content/uploads';
8
- private $pathOutput = 'wp-content/uploads-webpc';
9
- private $dirsExcluded = ['.', '..', '.git', '.svn', 'node_modules'];
10
 
11
  public function __construct()
12
  {
13
- add_filter('webpc_uploads_path', [$this, 'getUploadsPath'], 0, 2);
14
- add_filter('webpc_uploads_webp', [$this, 'getOutputPath'], 0, 2);
15
- add_filter('webpc_uploads_path', [$this, 'parsePath'], 100, 2);
16
- add_filter('webpc_uploads_webp', [$this, 'parsePath'], 100, 2);
17
- add_filter('webpc_uploads_prefix', [$this, 'getPrefixPath'], 0);
18
- add_filter('webpc_uploads_dir', [$this, 'getUploadsDir'], 0);
19
- add_filter('webpc_dir_path', [$this, 'getPathOfDir'], 0, 2);
20
- add_filter('webpc_dir_excluded', [$this, 'getExcludedDirs'], 0);
21
  }
22
 
23
  /* ---
24
  Functions
25
  --- */
26
 
27
- public function getUploadsPath($value, $skipRoot = false)
28
  {
29
- return $this->pathUploads;
30
  }
31
 
32
- public function getOutputPath($value, $skipRoot = false)
33
  {
34
- return $this->pathOutput;
35
  }
36
 
37
- public function parsePath($value, $skipRoot = false)
38
  {
39
- if ($skipRoot) return trim($value, '\/');
40
-
41
- $path = apply_filters('webpc_uploads_root', ABSPATH);
42
- return $path . '/' . trim($value, '\/');
43
- }
44
-
45
- public function getPrefixPath($value)
46
- {
47
- $docDir = realpath($_SERVER['DOCUMENT_ROOT']);
48
- $wpDir = realpath(ABSPATH);
49
- $diffDir = trim(str_replace($docDir, '', $wpDir), '\/');
50
- $diffPath = sprintf('/%s/', $diffDir);
51
-
52
- return str_replace('//', '/', $diffPath);
53
- }
54
-
55
- public function getUploadsDir($value)
56
- {
57
- $uploadsDir = apply_filters('webpc_uploads_path', '');
58
- $uploadsParent = dirname($uploadsDir);
59
- $webpParent = dirname(apply_filters('webpc_uploads_webp', ''));
60
- if ((!$uploadsDir = realpath($uploadsDir)) || (!$uploadsParent = realpath($uploadsParent))
61
- || ($uploadsParent !== realpath($webpParent))) {
62
- return $value;
63
- }
64
-
65
- $path = str_replace($uploadsParent, '', $uploadsDir);
66
- return trim($path, '\/');
67
- }
68
-
69
- public function getPathOfDir($value, $directory)
70
- {
71
- switch ($directory) {
72
- case 'plugins':
73
- return dirname(WEBPC_PATH);
74
- break;
75
- case 'themes':
76
- return get_theme_root();
77
- break;
78
- case 'uploads':
79
- return apply_filters('webpc_uploads_path', '');
80
- break;
81
- }
82
- return null;
83
- }
84
-
85
- public function getExcludedDirs($value)
86
- {
87
- return $this->dirsExcluded;
88
  }
89
  }
4
 
5
  class Paths
6
  {
7
+ private $source = 'wp-content/uploads', $output = 'wp-content/uploads-webpc';
 
 
8
 
9
  public function __construct()
10
  {
11
+ add_filter('webpc_uploads_path', [$this, 'getSourcePath'], 0);
12
+ add_filter('webpc_uploads_webp', [$this, 'getOutputPath'], 0);
13
+ add_filter('webpc_uploads_path', [$this, 'parsePath'], 100);
14
+ add_filter('webpc_uploads_webp', [$this, 'parsePath'], 100);
 
 
 
 
15
  }
16
 
17
  /* ---
18
  Functions
19
  --- */
20
 
21
+ public function getSourcePath($value)
22
  {
23
+ return $this->source;
24
  }
25
 
26
+ public function getOutputPath($value)
27
  {
28
+ return $this->output;
29
  }
30
 
31
+ public function parsePath($value)
32
  {
33
+ return trim($value, '\/');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
  }
app/Settings/Save.php CHANGED
@@ -20,7 +20,7 @@
20
 
21
  $values = $this->getValues();
22
  $this->saveOption('webpc_settings', $values);
23
- do_action('webpc_rewrite_htaccess', true);
24
  }
25
 
26
  private function getValues()
20
 
21
  $values = $this->getValues();
22
  $this->saveOption('webpc_settings', $values);
23
+ flush_rewrite_rules(true);
24
  }
25
 
26
  private function getValues()
app/Settings/Server.php CHANGED
@@ -19,7 +19,6 @@
19
  {
20
  ob_start();
21
 
22
- echo $this->getFiltersInfo();
23
  foreach ($this->extensions as $extension) {
24
  $this->getExtensionInfo($extension);
25
  }
@@ -43,81 +42,4 @@
43
  $ext->info();
44
  endif;
45
  }
46
-
47
- private function getFiltersInfo()
48
- {
49
- ob_start();
50
-
51
- ?>
52
- <h4>apply_filters</h4>
53
- <table>
54
- <tbody>
55
- <tr>
56
- <td class="e">webpc_get_values</td>
57
- <td class="v">
58
- <?= json_encode(apply_filters('webpc_get_values', [], null)); ?>
59
- </td>
60
- </tr>
61
- <tr>
62
- <td class="e">webpc_get_methods</td>
63
- <td class="v">
64
- <?= implode(' | ', apply_filters('webpc_get_methods', [])); ?>
65
- </td>
66
- </tr>
67
- <tr>
68
- <td class="e">webpc_uploads_root</td>
69
- <td class="v">
70
- <?= apply_filters('webpc_uploads_root', ABSPATH); ?>
71
- </td>
72
- </tr>
73
- <tr>
74
- <td class="e">webpc_uploads_prefix</td>
75
- <td class="v">
76
- <?= apply_filters('webpc_uploads_prefix', '/'); ?>
77
- </td>
78
- </tr>
79
- <tr>
80
- <td class="e">webpc_uploads_path</td>
81
- <td class="v">
82
- <?= apply_filters('webpc_uploads_path', '', false); ?>
83
- </td>
84
- </tr>
85
- <tr>
86
- <td class="e">webpc_uploads_webp</td>
87
- <td class="v">
88
- <?= apply_filters('webpc_uploads_webp', '', false); ?>
89
- </td>
90
- </tr>
91
- <tr>
92
- <td class="e">webpc_dir_path <em>(plugins)</em></td>
93
- <td class="v">
94
- <?= apply_filters('webpc_dir_path', '', 'plugins'); ?>
95
- </td>
96
- </tr>
97
- <tr>
98
- <td class="e">webpc_dir_path <em>(themes)</em></td>
99
- <td class="v">
100
- <?= apply_filters('webpc_dir_path', '', 'themes'); ?>
101
- </td>
102
- </tr>
103
- <tr>
104
- <td class="e">webpc_dir_path <em>(uploads)</em></td>
105
- <td class="v">
106
- <?= apply_filters('webpc_dir_path', '', 'uploads'); ?>
107
- </td>
108
- </tr>
109
- <tr>
110
- <td class="e">webpc_dir_excluded</td>
111
- <td class="v">
112
- <?= implode(' | ', apply_filters('webpc_dir_excluded', [])); ?>
113
- </td>
114
- </tr>
115
- </tbody>
116
- </table>
117
- <?php
118
-
119
- $content = ob_get_contents();
120
- ob_end_clean();
121
- return $content;
122
- }
123
  }
19
  {
20
  ob_start();
21
 
 
22
  foreach ($this->extensions as $extension) {
23
  $this->getExtensionInfo($extension);
24
  }
42
  $ext->info();
43
  endif;
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
app/Settings/Values.php CHANGED
@@ -22,9 +22,8 @@
22
  $methods = apply_filters('webpc_get_methods', []);
23
  $value = get_option('webpc_settings', [
24
  'extensions' => ['jpg', 'jpeg', 'png'],
25
- 'dirs' => ['uploads'],
26
  'method' => ($methods) ? $methods[0] : '',
27
- 'features' => ['only_smaller', 'mod_expires'],
28
  'quality' => 85,
29
  ]);
30
  $this->config = $value;
22
  $methods = apply_filters('webpc_get_methods', []);
23
  $value = get_option('webpc_settings', [
24
  'extensions' => ['jpg', 'jpeg', 'png'],
 
25
  'method' => ($methods) ? $methods[0] : '',
26
+ 'features' => ['mod_expires'],
27
  'quality' => 85,
28
  ]);
29
  $this->config = $value;
app/WebpConverter.php CHANGED
@@ -6,9 +6,7 @@
6
  {
7
  public function __construct()
8
  {
9
- new Action\_Core();
10
  new Admin\_Core();
11
- new Convert\_Core();
12
  new Media\_Core();
13
  new Regenerate\_Core();
14
  new Settings\_Core();
6
  {
7
  public function __construct()
8
  {
 
9
  new Admin\_Core();
 
10
  new Media\_Core();
11
  new Regenerate\_Core();
12
  new Settings\_Core();
public/build/js/scripts.js CHANGED
@@ -1 +1 @@
1
- !function(e){var t={};function r(s){if(t[s])return t[s].exports;var i=t[s]={i:s,l:!1,exports:{}};return e[s].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=e,r.c=t,r.d=function(e,t,s){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(r.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(s,i,function(t){return e[t]}.bind(null,i));return s},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="/",r(r.s=0)}([function(e,t,r){r(1),e.exports=r(2)},function(e,t,r){"use strict";function s(e,t){for(var r=0;r<t.length;r++){var s=t[r];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}r.r(t);var i=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.setVars()&&this.setEvents()}var t,r,i;return t=e,(r=[{key:"setVars",value:function(){if(this.notice=document.querySelector(".notice[data-notice=webp-converter]"),this.notice)return this.settings={isHidden:!1,ajaxUrl:this.notice.getAttribute("data-url")},!0}},{key:"setEvents",value:function(){window.addEventListener("load",this.getButtons.bind(this))}},{key:"getButtons",value:function(){this.buttonClose=this.notice.querySelector(".notice-dismiss"),this.buttonPermanently=this.notice.querySelector("[data-permanently]"),this.setButtonsEvents()}},{key:"setButtonsEvents",value:function(){var e=this;this.buttonClose.addEventListener("click",(function(){e.hideNotice(!1)})),this.buttonPermanently.addEventListener("click",(function(t){t.preventDefault(),e.hideNotice(!0)}))}},{key:"hideNotice",value:function(e){this.settings.isHidden||(this.settings.isHidden=!0,jQuery.ajax(this.settings.ajaxUrl,{type:"POST",data:{is_permanently:e?1:0}}),this.buttonClose.click())}}])&&s(t.prototype,r),i&&s(t,i),e}();function n(e,t){for(var r=0;r<t.length;r++){var s=t[r];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}var a=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.setVars()&&this.setEvents()}var t,r,s;return t=e,(r=[{key:"setVars",value:function(){if(this.section=document.querySelector(".webpLoader"),this.section)return this.wrapper=this.section.querySelector(".webpLoader__status"),this.progress=this.wrapper.querySelector(".webpLoader__barProgress"),this.progressSize=this.section.querySelector(".webpLoader__sizeProgress"),this.errors=this.section.querySelector(".webpLoader__errors"),this.errorsInner=this.errors.querySelector(".webpLoader__errorsContentList"),this.errorsMessage=this.errors.querySelector(".webpLoader__errorsContentMessage"),this.success=this.section.querySelector(".webpLoader__success"),this.inputOptions=this.section.querySelectorAll('input[type="checkbox"]'),this.button=this.section.querySelector(".webpLoader__button"),this.data={count:0,max:0,items:[],size:{before:0,after:0},errors:[]},this.settings={isDisabled:!1,ajax:{urlPaths:this.section.getAttribute("data-api-paths"),urlRegenerate:this.section.getAttribute("data-api-regenerate"),errorMessage:this.section.getAttribute("data-api-error-message")},units:["kB","MB","GB"]},this.atts={progress:"data-percent"},this.classes={progressError:"webpLoader__barProgress--error",buttonDisabled:"webpLoader__button--disabled"},!0}},{key:"setEvents",value:function(){this.button.addEventListener("click",this.initRegenerate.bind(this))}},{key:"initRegenerate",value:function(e){if(e.preventDefault(),!this.settings.isDisabled){this.settings.isDisabled=!0,this.button.classList.add(this.classes.buttonDisabled);for(var t=this.inputOptions.length,r=0;r<t;r++)this.inputOptions[r].setAttribute("disabled",!0);this.wrapper.removeAttribute("hidden"),this.getImagesList()}}},{key:"getImagesList",value:function(){var e=this;jQuery.ajax(this.settings.ajax.urlPaths,{type:"POST",data:this.getDataForPathsRequest()}).done((function(t){e.data.items=t,e.data.max=t.length,e.regenerateNextImages()})).fail((function(){e.progress.classList.add(e.classes.progressError),e.errorsMessage.removeAttribute("hidden"),e.errors.removeAttribute("hidden")}))}},{key:"getDataForPathsRequest",value:function(){for(var e={},t=this.inputOptions.length,r=0;r<t;r++)e[this.inputOptions[r].getAttribute("name")]=this.inputOptions[r].checked?1:0;return e}},{key:"regenerateNextImages",value:function(){if(0===this.data.max&&this.updateProgress(),!(this.data.count>=this.data.max)){var e=this.data.items[this.data.count];this.data.count++,this.sendRequest(e)}}},{key:"sendRequest",value:function(e){var t=this;jQuery.ajax(this.settings.ajax.urlRegenerate,{type:"POST",data:{paths:e}}).done((function(e){t.updateErrors(e.errors),t.updateSize(e),t.updateProgress(),t.regenerateNextImages()})).fail((function(){var r=JSON.stringify(e),s=t.settings.ajax.errorMessage.replace("%s","<code>".concat(r,"</code>"));t.updateErrors([s]),t.regenerateNextImages()}))}},{key:"updateErrors",value:function(e){0!==e.length&&(this.data.errors=this.data.errors.concat(e),this.errorsInner.innerHTML=this.data.errors.join("<br>"),this.errors.removeAttribute("hidden"))}},{key:"updateSize",value:function(e){var t=this.data.size;t.before+=e.size.before,t.after+=e.size.after;var r=t.before-t.after;if(r<0&&(r=0),0!==r){var s=Math.round(100*(1-t.after/t.before));s<0&&(s=0);var i=-1;do{i++,r/=1024}while(r>1024);var n=r.toFixed(2),a=this.settings.units[i],o="".concat(n," ").concat(a," (").concat(s,"%)");this.progressSize.innerHTML=o}}},{key:"updateProgress",value:function(){var e=this.data.max>0?Math.floor(this.data.count/this.data.max*100):100;e>100&&(e=100),100===e&&this.success.removeAttribute("hidden"),this.progress.setAttribute(this.atts.progress,e)}}])&&n(t.prototype,r),s&&n(t,s),e}();new function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),new i,new a}},function(e,t){}]);
1
+ !function(e){var t={};function r(s){if(t[s])return t[s].exports;var i=t[s]={i:s,l:!1,exports:{}};return e[s].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=e,r.c=t,r.d=function(e,t,s){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(r.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(s,i,function(t){return e[t]}.bind(null,i));return s},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="/",r(r.s=0)}([function(e,t,r){r(1),e.exports=r(2)},function(e,t,r){"use strict";function s(e,t){for(var r=0;r<t.length;r++){var s=t[r];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}r.r(t);var i=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.setVars()&&this.setEvents()}var t,r,i;return t=e,(r=[{key:"setVars",value:function(){if(this.notice=document.querySelector(".notice[data-notice=webp-converter]"),this.notice)return this.settings={isHidden:!1,ajaxUrl:this.notice.getAttribute("data-url")},!0}},{key:"setEvents",value:function(){window.addEventListener("load",this.getButtons.bind(this))}},{key:"getButtons",value:function(){this.buttonClose=this.notice.querySelector(".notice-dismiss"),this.buttonPermanently=this.notice.querySelector("[data-permanently]"),this.setButtonsEvents()}},{key:"setButtonsEvents",value:function(){var e=this;this.buttonClose.addEventListener("click",(function(){e.hideNotice(!1)})),this.buttonPermanently.addEventListener("click",(function(t){t.preventDefault(),e.hideNotice(!0)}))}},{key:"hideNotice",value:function(e){this.settings.isHidden||(this.settings.isHidden=!0,jQuery.ajax(this.settings.ajaxUrl,{type:"POST",data:{is_permanently:e?1:0}}),this.buttonClose.click())}}])&&s(t.prototype,r),i&&s(t,i),e}();function n(e,t){for(var r=0;r<t.length;r++){var s=t[r];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}var a=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.setVars()&&this.setEvents()}var t,r,s;return t=e,(r=[{key:"setVars",value:function(){if(this.section=document.querySelector(".webpLoader"),this.section)return this.wrapper=this.section.querySelector(".webpLoader__status"),this.progress=this.wrapper.querySelector(".webpLoader__barProgress"),this.progressSize=this.section.querySelector(".webpLoader__sizeProgress"),this.errors=this.section.querySelector(".webpLoader__errors"),this.errorsInner=this.errors.querySelector(".webpLoader__errorsContentList"),this.errorsMessage=this.errors.querySelector(".webpLoader__errorsContentMessage"),this.success=this.section.querySelector(".webpLoader__success"),this.skipOption=this.section.querySelector('input[name="regenerate_skip"]'),this.button=this.section.querySelector(".webpLoader__button"),this.data={count:0,max:0,items:[],size:{before:0,after:0},errors:[]},this.settings={isDisabled:!1,ajax:{urlPaths:this.section.getAttribute("data-api-paths"),urlRegenerate:this.section.getAttribute("data-api-regenerate"),errorMessage:this.section.getAttribute("data-api-error-message")},units:["kB","MB","GB"]},this.atts={progress:"data-percent"},this.classes={progressError:"webpLoader__barProgress--error",buttonDisabled:"webpLoader__button--disabled"},!0}},{key:"setEvents",value:function(){this.button.addEventListener("click",this.initRegenerate.bind(this))}},{key:"initRegenerate",value:function(e){e.preventDefault(),this.settings.isDisabled||(this.settings.isDisabled=!0,this.skipOption.setAttribute("disabled",!0),this.button.classList.add(this.classes.buttonDisabled),this.wrapper.removeAttribute("hidden"),this.getImagesList())}},{key:"getImagesList",value:function(){var e=this;jQuery.ajax(this.settings.ajax.urlPaths,{type:"POST",data:{skip:this.skipOption.checked?1:0}}).done((function(t){e.data.items=t.data,e.data.max=t.data.length,e.regenerateNextImages()})).fail((function(){e.progress.classList.add(e.classes.progressError),e.errorsMessage.removeAttribute("hidden"),e.errors.removeAttribute("hidden")}))}},{key:"regenerateNextImages",value:function(){if(0===this.data.max&&this.updateProgress(),!(this.data.count>=this.data.max)){var e=this.data.items[this.data.count];this.data.count++,this.sendRequest(e)}}},{key:"sendRequest",value:function(e){var t=this;jQuery.ajax(this.settings.ajax.urlRegenerate,{type:"POST",data:{paths:e}}).done((function(e){t.updateErrors(e.errors),t.updateSize(e),t.updateProgress(),t.regenerateNextImages()})).fail((function(){var r=JSON.stringify(e),s=t.settings.ajax.errorMessage.replace("%s","<code>".concat(r,"</code>"));t.updateErrors([s]),t.regenerateNextImages()}))}},{key:"updateErrors",value:function(e){0!==e.length&&(this.data.errors=this.data.errors.concat(e),this.errorsInner.innerHTML=this.data.errors.join("<br>"),this.errors.removeAttribute("hidden"))}},{key:"updateSize",value:function(e){var t=this.data.size;t.before+=e.size.before,t.after+=e.size.after;var r=t.before-t.after;if(r<0&&(r=0),0!==r){var s=Math.round(100*(1-t.after/t.before));s<0&&(s=0);var i=-1;do{i++,r/=1024}while(r>1024);var n=r.toFixed(2),a=this.settings.units[i],o="".concat(n," ").concat(a," (").concat(s,"%)");this.progressSize.innerHTML=o}}},{key:"updateProgress",value:function(){var e=this.data.max>0?Math.floor(this.data.count/this.data.max*100):100;e>100&&(e=100),100===e&&this.success.removeAttribute("hidden"),this.progress.setAttribute(this.atts.progress,e)}}])&&n(t.prototype,r),s&&n(t,s),e}();new function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),new i,new a}},function(e,t){}]);
public/img/.htaccess DELETED
@@ -1,6 +0,0 @@
1
- # BEGIN WebP Converter
2
- <IfModule mod_rewrite.c>
3
- RewriteEngine On
4
- RewriteRule icon-before\.(.+)$ ./icon-after.$1 [NC,E=cache-control:private,L]
5
- </IfModule>
6
- # END WebP Converter
 
 
 
 
 
 
public/img/icon-after.png DELETED
Binary file
public/img/icon-after.png2 DELETED
Binary file
public/img/icon-before.png DELETED
Binary file
public/img/icon-before.png2 DELETED
Binary file
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === WebP Converter for Media ===
2
  Contributors: mateuszgbiorczyk
3
  Donate link: https://ko-fi.com/gbiorczyk/
4
- Tags: convert webp, webp, optimize images, images, webp converter, performance, optimisation
5
  Requires at least: 5.0
6
- Tested up to: 5.5
7
  Requires PHP: 7.0
8
  Stable tag: trunk
9
  License: GPLv2 or later
@@ -21,43 +21,26 @@ As of today, nearly 80% of users use browsers that support the WebP format. The
21
 
22
  This will be a profit both for your users who will not have to download so much data, but also for a server that will be less loaded. Remember that a better optimized website also affects your Google ranking.
23
 
24
- #### New feature
25
-
26
- Now you can also convert files from the `/uploads` directory into WebP and generated by other plugins! It allows full integration with the WebP format!
27
-
28
  #### How does this work?
29
 
30
- - By adding images to your Media Library, they are automatically converted and saved in a separate directory.
31
  - If you have just installed the plugin, you can convert all existing images with one click.
32
- - Converting to WebP format works for all image sizes. As WebP you will see all the images added to the Media Library.
33
  - Images are converted using PHP `GD` or `Imagick` extension *(you can modify the compression level)*.
34
  - When the browser tries to download an image file, the server verifies if it supports `image/webp` files and if the file exists.
35
  - If everything is OK, instead of the original image, the browser will receive its equivalent in WebP format.
36
  - **The plugin does not change image URLs, so there are no problems with saving the HTML code of website to the cache and time of its generation does not increase.** It does not matter if the image display as an `img` HTML tag or you use `background-image`. It works always!
37
- - The name of the loaded image does not contain the WebP extension. Only the source of the loaded file changes to a WebP file. As a result, you always have one URL to a file. Regardless of whether the browser supports WebP or not.
38
  - Image URLs are modified using the module `mod_rewrite` on the server, i.e. the same, and thanks to this we can use friendly links in WordPress. Additionally, the MIME type of the sent file is modified to `image/webp`.
39
- - When you try to save the image to disk *(e.g. by clicking Save as...)* the original image will be saved. WebP is only used for browser loading.
40
  - The final result is that your users download less than half of the data, and the website itself loads faster!
41
 
42
- #### Support for additional directories
43
-
44
- You can also manually convert images from the `/plugins` and `/themes` directories, as well as other images from the `/uploads` directory that are not in the Media Library *(which are e.g. generated by other plugins)*. It allows full integration with the WebP format and maximum acceleration of your website.
45
-
46
  #### WebP images are the future!
47
 
48
  Raise your website to a new level now! Install the plugin and enjoy the website that loads faster. Surely you and your users will appreciate it.
49
 
50
- #### Support to the development of plugin
51
-
52
- We spend hours working on the development of this plugin. Technical support also requires a lot of time, but we do it because we want to offer you the best plugin. We enjoy every new plugin installation.
53
-
54
- If you would like to appreciate it, you can [provide us a coffee](https://ko-fi.com/gbiorczyk/). **If every user bought at least one, we could work on the plugin 24 hours a day!**
55
-
56
  #### Please also read the FAQ below. Thank you for being with us!
57
 
58
  == Installation ==
59
 
60
- 1. Upload the plugin files to `/wp-content/plugins/webp-converter-for-media` directory, or install plugin through the WordPress plugins screen directly.
61
  2. Activate plugin through `Plugins` screen in WordPress Admin Panel.
62
  3. Use `Settings -> Settings -> WebP Converter` screen to configure the plugin.
63
  4. Click on the button `Regenerate All`.
@@ -69,19 +52,23 @@ That's all! Your website is already loading faster!
69
 
70
  = How to get technical support? (before you ask for help) =
71
 
 
 
72
  Please always adding your thread, **read all other questions in the FAQ of plugin and other threads in support forum first**. Perhaps someone had a similar problem and it has been resolved.
73
 
74
- When adding a thread, follow these steps and reply to each of them:
 
 
75
 
76
- **1.** Do you have any error on the plugin settings page? If so, which one? Have you consulted your server administrator or developer? If not, please do it first.
77
 
78
- **2.** URL of your website. If your site is not publicly available, add it to test environment.
79
 
80
- **3.** Does your server meet the technical requirements described in the FAQ? Please send configuration of your server *(link to it can be found on the settings page of plugin in the section **"We are waiting for your message"**)* - please take a screenshot of the ENTIRE page and send it to me.
81
 
82
- **4.** Do you use CDN? If so, please see the question **"Does the plugin support CDN?"** in plugin FAQ.
83
 
84
- **5.** Check if in `/wp-content/uploads-webpc` directory are all files that should be converted.
85
 
86
  If not, please enable `WP_DEBUG_LOG` in your `wp-config.php` *(more about debugging: [https://codex.wordpress.org/WP_DEBUG](https://codex.wordpress.org/WP_DEBUG))*. That's what you should have in this file:
87
 
@@ -101,57 +88,33 @@ Then follow these steps:
101
 
102
  Send a screenshot from console if an error occurred while converting images. Of you have errors in `/wp-content/debug.log` send their?
103
 
104
- **6.** If in the previous step it turned out that you have files, please do the test, which is described in the FAQ in question `How to check if plugin works?`. Please send a screenshot of Devtools with test results.
105
-
106
- **7.** Content of your `.htaccess` files from directories `/wp-content`, `/wp-content/uploads` and `/wp-content/uploads-webpc` *(pasting the code using the `CODE` shortcode in the editor)*.
107
-
108
- **8.** Do you use any plugin filters or actions from this FAQ? If so, list them all.
109
 
110
- **9.** What plugin version are you using? If it is not the latest then update and check everything again.
111
 
112
- **10.** Used Wordpress version.
113
 
114
- **11.** A list of all the plugins you use. Have you tried checking the plugin operation by turning off all others and activating the default theme? If not, please try whenever possible. **This is very important because other plugins or themes can cause problems. Therefore, we recommend disabling all necessary plugins and enabling the default theme.**
115
 
116
- Please remember to include the answers for all 11 questions by adding a thread. It is much easier and accelerate the solution of your problem.
117
 
118
- = Error on plugin settings screen? =
119
 
120
- If you have an error on the plugin settings screen, first of all please read it carefully. They are displayed when there is a problem with the configuration of your server or website.
121
-
122
- The messages are designed to reduce the number of support requests that are repeated. It saves your and our time. If you have information in the message that you should contact the administrator of your server, please do so.
123
-
124
- When contacting the administrator, give him all the information available in the message. If you still cannot solve the problem, please contact us.
125
-
126
- We want to solve as many similar problems as possible automatically. This eliminates the need to wait for our response and you can try to solve the problem alone. This is very important for us.
127
-
128
- = Error while converting? =
129
-
130
- You can get several types of errors when converting. First of all, carefully read their content. For the most part, you can solve this problem yourself. Try to do this or contact the server administrator.
131
-
132
- If you get an error: `File "%s" does not exist. Please check file path.` means that the [file_exists()](https://www.php.net/manual/en/function.file-exists.php) function in PHP returned `false` using the file path given in the error message. Check this path and make sure it is correct.
133
-
134
- If you get an error: `File "%s" is unreadable. Please check file permissions.` means that the [is_readable()](https://www.php.net/manual/en/function.is-readable.php) function in PHP returned `false` using the file path given in the error message. Check the permissions for the file and the directory in which the file is located.
135
-
136
- If you get an error: `"%s" is not a valid image file.` means that the file is damaged in some way. Download the file to disk, save it again using any graphics program and add again to the page. If the error applies to individual images then you can ignore it - just the original images will load, not WebP.
137
-
138
- In the case of the above problems, **contacting the support forum will be useless**. Unfortunately, we are unable to help you if your files are damaged. You have to fix it yourself. If you have previously used other tools that changed the original files and damaged them, you will do nothing more.
139
-
140
- Remember that it happens that other plugins can cause problems with accessing files or the REST API. Please try to disable all other plugins and set the default theme to make sure that it is not one of them that causes these types of problems.
141
 
142
  = What are requirements of plugin? =
143
 
144
- Practically every hosting meets these requirements. You must use PHP at least 7.0 and have the `GD` or `Imagick` extension installed. **The extension must support `WebP format`.** If you have an error saying that the GD or Imagick library are not installed, but you have it installed then they are probably incorrectly configured and do not have WebP support.
145
 
146
  They are required native PHP extensions, used among others by WordPress to generate thumbnails. Your server must also have the modules `mod_mime`, `mod_rewrite` and `mod_expires` enabled.
147
 
148
- An example of the correct server configuration can be found [here](https://gbiorczyk.pl/webp-converter/serverinfo.png). Link to your current configuration can be found in the administration panel, on the management plugin page in the section **"We are waiting for your message"** *(or using the URL path: `/wp-admin/options-general.php?page=webpc_admin_page&action=server`)*.
149
 
150
- **Note the items marked in red.** If the values marked in red do not appear in your case, it means that your server does not meet the technical requirements. Pay attention to the **WebP Support** value for the GD library and **WEBP in the list of supported extensions** for the Imagick library.
151
 
152
- In a situation where your server does not meet the technical requirements, please contact your server Administrator. We are not able to help you. Please do not contact us about this matter, because this is a server configuration problem, not a plugin.
153
 
154
- Also REST API must be enabled and work without additional restrictions. If you have a problem with it, please contact the Developer who created your website. He should easily find the issue with the REST API not working.
155
 
156
  = What are restrictions? =
157
 
@@ -161,29 +124,13 @@ Please remember that **Safari and Internet Explorer do not support the WebP form
161
 
162
  You can find more about WebP support by browsers [here](https://caniuse.com/#feat=webp).
163
 
164
- = Damaged images on iOS or other browsers =
165
-
166
- The plugin uses rules in the .htaccess file to redirect from the original image to an image in WebP format. Verifies whether the WebP file exists and whether your browser supports the WebP format. It does this every time you try to load an image.
167
-
168
- When you enter from a WebP supporting device, it will redirect. However, when someone uses a browser that does not support WebP, the redirection will not work and you get the original file.
169
-
170
- However, if you see corrupted images on browsers that do not support WebP, it means that your server uses cache for rewrites from the .htaccess file. Then the plugin will not work properly because the server instead of reading the rules from the .htaccess file every time uses its cache and does the redirection automatically.
171
-
172
- How can you check it? When you turn off the plugin, the rewrites from the .htaccess file are removed, which means you should see the original images on every browser. If this is not the case and you see forced redirects to WebP files, it means that your server remembers the redirects you made earlier and uses cache.
173
-
174
- In this situation, please contact your server administrator. Each configuration is different. It can be e.g. module `mod_pagespeed` or other similar. This functionality must be turned off so that the server reads and executes the rules from the .htaccess file each time the images are loaded. This cannot be ignored because it will cause problems.
175
-
176
- = What to do after installing plugin? =
177
-
178
- After installing the plugin, you should convert all existing images.
179
 
180
  In the WordPress admin panel, on the `Settings -> WebP Converter` subpage there is a module that allows you to process all your images.
181
 
182
  It uses the WordPress REST API by downloading addresses of all images and converting all files gradually.
183
 
184
- This process may take few or more than ten minutes depending on the number of files.
185
-
186
- **It should be done once after installing the plugin.** New images from the Media Library will be converted automatically. For other images, e.g. from the /themes directory, you must start manual conversion after adding new images.
187
 
188
  = How to check if plugin works? =
189
 
@@ -198,178 +145,41 @@ When you have installed plugin and converted all images, follow these steps:
198
  7. In addition, you can check weight of website before and after using plugin. The difference will be huge!
199
  8. More information: [here](https://gbiorczyk.pl/webp-converter/check-devtools.png)
200
 
201
- Please remember that URLs will remain unchanged. When you open the image in a new tab or look at its URL, you'll see the original URL. When you try to save the image to disk *(e.g. by clicking Save as...)* the original image will be saved.
202
-
203
- WebP is only used when loading a image on a website. This is done by the rules from the .htaccess file, on the server side, without the visible URL change to the image. Yes, it can be called magic :)
204
-
205
- That is why the plugin should be tested in Dev Tools. If the Type of file is `WebP`, then everything is working properly. You can also turn off the plugin for a moment and check the weight of your website, then turn it on and test again. The difference should be visible.
206
-
207
- The operation of the plugin for non-advanced users may sometimes be less understood, but everything is fine. Thanks to this, regardless of whether your browser supports WebP or not, everything works without problems.
208
-
209
- Only images from the `/uploads` directory are automatically converted. If you use other plugins that also save images in the `/uploads` directory then this may not work. Therefore, check the plugin settings and try converting all images again.
210
-
211
- = Why are some images not in WebP? =
212
-
213
- If the converted image in WebP format is larger than the original, the browser will use the original file. This converted file will be deleted. Therefore, you can also see files other than WebP on the list. When this happens, you will receive information in debug.log.
214
-
215
- If you want to force the use of WebP files, uncheck the `Automatic removal of WebP files larger than original` option in the plugin settings. Then click on the `Regenerate All` button to convert all images again.
216
-
217
- Remember that this plugin supports images from the `/wp-content` directory, e.g. files downloaded from the Media Library. Redirections will not work if your images are downloaded from another domain, i.e. from an external service.
218
-
219
- When checking the operation of the plugin, e.g. in Dev Tools, pay attention to the path from which the files are downloaded and which directories you have enabled in the settings of plugin.
220
 
221
  = Where are converted images stored? =
222
 
223
- All WebP images are stored in the `/wp-content/uploads-webpc/` directory. Inside the directory there is the same structure as in the original `/wp-content` directory. The files have original extensions in the name along with the new `.webp`.
224
-
225
- In case the location of the original file is as follows: `/wp-content/uploads/2019/06/example.jpg` then its converted version will be in the following location: `/wp-content/uploads-webpc/uploads/2019/06/example.jpg.webp`.
226
 
227
- In case the location of the original file is as follows: `/wp-content/themes/my-theme/public/img/example.jpg` then its converted version will be in the following location: `/wp-content/uploads-webpc/themes/my-theme/public/img/example.jpg.webp`.
228
 
229
- Original images are not changed. If you remove plugins, only WebP files will be deleted. Your images are not changed in any way.
230
 
231
  = How to change path to uploads? =
232
 
233
- This is possible using the following types of filters to change default paths. It is a solution for advanced users. If you are not, please skip this question.
234
 
235
- Path to the root installation directory of WordPress *(`ABSPATH` by default)*:
236
 
237
- `add_filter('webpc_uploads_root', function($path) {
238
- return ABSPATH;
239
- });`
240
-
241
- Path to `/uploads` directory *(relative to the root directory)*:
242
 
243
  `add_filter('webpc_uploads_path', function($path) {
244
  return 'wp-content/uploads';
245
  });`
246
 
247
- Directory path with converted WebP files *(relative to the root directory)*:
248
-
249
  `add_filter('webpc_uploads_webp', function($path) {
250
  return 'wp-content/uploads-webpc';
251
  });`
252
 
253
- **Note that the `/uploads-webpc` directory must be at the same nesting level as the `/uploads`, `/plugins` and `/themes` directories.**
254
-
255
- Prefix in URL of `/wp-content/` directory or equivalent *(used in .htaccess)*:
256
-
257
- `add_filter('webpc_uploads_prefix', function($prefix) {
258
- return '/';
259
- });`
260
-
261
- For the following sample custom WordPress structure:
262
-
263
- `...
264
- ├── web
265
- ...
266
- ├── app
267
- │ ├── mu-plugins
268
- │ ├── plugins
269
- │ ├── themes
270
- │ └── uploads
271
- ├── wp-config.php
272
- ...`
273
-
274
- Use the following filters:
275
-
276
- `add_filter('webpc_uploads_root', function($path) {
277
- return 'C:/WAMP/www/project/webp'; // your valid path
278
- });
279
- add_filter('webpc_uploads_path', function($path) {
280
- return 'app/uploads';
281
- });
282
- add_filter('webpc_uploads_webp', function($path) {
283
- return 'app/uploads-webpc';
284
- });`
285
- `add_filter('webpc_uploads_prefix', function($prefix) {
286
- return '/';
287
- });`
288
-
289
- After setting the filters go to `Settings -> WebP Converter` in the admin panel and click the `Save Changes` button. `.htaccess` files with appropriate rules should be created in the directories `/uploads` and `/uploads-webpc`.
290
-
291
- = How to run manually conversion? =
292
-
293
- By default, all images are converted when you click on the `Regenerate All` button. In addition, conversion is automatic when you add new files to your Media Library.
294
-
295
- Remember that our plugin takes into account images generated by WordPress. There are many plugins that generate, for example, images of a different size or in a different version.
296
-
297
- If you would like to integrate with your plugin, which generates images by yourself, you can do it. Our plugin provides the possibility of this type of integration. This works for all images in the `/wp-content` directory.
298
-
299
- It is a solution for advanced users. If you would like to integrate with another plugin, it's best to contact the author of that plugin and give him information about the actions available in our plugin. This will help you find a solution faster.
300
-
301
- You can automatically run the option to regenerate all new images. This is useful when you use external plugins that generate images themselves. To do this, use the following code:
302
-
303
- `do_action('webpc_regenerate_all', $paths);`
304
-
305
- Below is an example of how to use this action to automatically regenerate images after changing the theme:
306
-
307
- `add_action('init', function()
308
- {
309
- do_action('webpc_regenerate_all');
310
- });`
311
-
312
- To manually start converting selected files, you can use the action to which you will pass an array with a list of paths *(they must be absolute server paths)*:
313
-
314
- `do_action('webpc_convert_paths', $paths);`
315
-
316
- An alternative method is to manually start converting the selected attachment by passing the post ID from the Media Library. Remember to run this action after registering all image sizes *(i.e. after running the `add_image_size` function)*:
317
-
318
- `do_action('webpc_convert_attachment', $postId);`
319
-
320
- In addition, you can edit the list of files that will be converted. For example, to add some to the exceptions. To do this, use the following filter, which by default returns a list of all paths:
321
-
322
- `add_filter('webpc_attachment_paths', function($paths, $attachmentId) {
323
- return $paths;
324
- }, 10, 2);`
325
-
326
- Argument `$paths` is array of absolute server paths and `$attachmentId` is the post ID of attachment, added to the Media Library.
327
-
328
- To delete manually converted files, use the following action, providing as an argument an array of absolute server paths to the files *(this will delete manually converted files)*:
329
-
330
- `do_action('webpc_delete_paths', $paths);`
331
-
332
- = How to change .htaccess rules? =
333
-
334
- Manually editing the rules in the .htaccess file is a task only for experienced developers. Remember that the wrong rules can cause your website to stop working.
335
 
336
- Below is a list of filters that allow you to modify all rules. Remember that it's best to use your own rule set rather than edit parts of exists. This will ensure greater failure-free after plugin update.
337
 
338
- Returning an empty string will delete these rules the next time you save the plugin settings. You must do this after each filter edit.
339
 
340
- Rules for redirects: *(returns rules for `mod_rewrite` module)*:
341
 
342
- `add_filter('webpc_htaccess_mod_rewrite', function($rules, $path) {
343
- return '';
344
- }, 10, 2);`
345
-
346
- Argument `$path` is absolute server path for `.htaccess` file *(`/wp-content/.htaccess` or `/wp-content/uploads/.htaccess`)*.
347
-
348
- Rules for `image/webp` MIME type: *(returns rules for `mod_mime` module)*:
349
-
350
- `add_filter('webpc_htaccess_mod_mime', function($rules) {
351
- return '';
352
- });`
353
-
354
- Rules for Browser Caching: *(returns rules for `mod_expires` module)*:
355
-
356
- `add_filter('webpc_htaccess_mod_expires', function($rules) {
357
- return '';
358
- });`
359
-
360
- All rules from the files `/wp-content/.htaccess`, `/wp-content/uploads/.htaccess` and `/wp-content/uploads-webpc/.htaccess`: *(returns rules for modules: `mod_rewrite`, `mod_mime` and `mod_expires`)*:
361
-
362
- `add_filter('webpc_htaccess_rules', function($rules, $path) {
363
- return '';
364
- }, 10, 2);`
365
-
366
- Argument `$path` is absolute server path for `.htaccess` file.
367
-
368
- = What is Browser Caching? =
369
-
370
- This option allows you to speed up page loading time for returning users because they do not need to re-download files from the server. The plugin allows this by using the module `mod_expires`.
371
-
372
- It is enabled by default. If you do not want to use this functionality, you can turn it off at any time.
373
 
374
  = Does plugin support CDN? =
375
 
@@ -377,7 +187,7 @@ Unfortunately not. This is due to the logic of the plugin's operation. Plugins t
377
 
378
  The main problem when changing URLs is cache. When we modify the image URL for WebP supporting browser, then use the browser without WebP support, it will still have the URL address of an image in .webp format, because it will be in the cache.
379
 
380
- While in the case of the `img` tag you can solve this problem, in the case of `background-image` it is possible. We wanted full support so that all images would be supported - no matter how they are displayed on the website.
381
 
382
  Therefore in this plugin for browsers supporting the WebP format, only the source of the file is replaced by using the `mod_rewrite` module on the server. The URL for image remains the same. This solves the whole problem, but it is impossible to do when the files are stored on the CDN server.
383
 
@@ -406,51 +216,42 @@ and add below code in this file:
406
  `server {`
407
  ` # ...
408
 
409
- location ~ /wp-content/(?<path>.+)\.(?<ext>jpe?g|png|gif)$ {
410
  if ($http_accept !~* "image/webp") {
411
  break;
412
  }
413
  add_header Vary Accept;
414
  expires 365d;
415
- try_files /wp-content/uploads-webpc/$path.$ext.webp $uri =404;
416
  }
417
  }`
418
 
419
  = Configuration for Multisite Network =
420
 
421
- Yes, with one exception. In this mode it is not possible to automatically generate the contents of .htaccess files.
422
 
423
- Please manually paste the following code **at the beginning of .htaccess file** in the `/wp-content` directory:
424
 
425
  `# BEGIN WebP Converter`
426
- `# ! --- DO NOT EDIT PREVIOUS LINE --- !`
427
- `<IfModule mod_rewrite.c>
 
 
428
  RewriteEngine On
429
  RewriteCond %{HTTP_ACCEPT} image/webp
430
  RewriteCond %{DOCUMENT_ROOT}/wp-content/uploads-webpc/$1.jpg.webp -f
431
- RewriteRule (.+)\.jpg$ /wp-content/uploads-webpc/$1.jpg.webp [NC,T=image/webp,E=cache-control:private,L]
432
  RewriteCond %{HTTP_ACCEPT} image/webp
433
  RewriteCond %{DOCUMENT_ROOT}/wp-content/uploads-webpc/$1.jpeg.webp -f
434
- RewriteRule (.+)\.jpeg$ /wp-content/uploads-webpc/$1.jpeg.webp [NC,T=image/webp,E=cache-control:private,Lp]
435
  RewriteCond %{HTTP_ACCEPT} image/webp
436
  RewriteCond %{DOCUMENT_ROOT}/wp-content/uploads-webpc/$1.png.webp -f
437
- RewriteRule (.+)\.png$ /wp-content/uploads-webpc/$1.png.webp [NC,T=image/webp,E=cache-control:private,L]
438
- </IfModule>`
439
- `# ! --- DO NOT EDIT NEXT LINE --- !`
440
- `# END WebP Converter`
441
-
442
- And the following code **at the beginning of .htaccess file** in the `/wp-content/uploads-webpc` directory:
443
-
444
- `# BEGIN WebP Converter`
445
- `# ! --- DO NOT EDIT PREVIOUS LINE --- !`
446
- `<IfModule mod_mime.c>
447
- AddType image/webp .webp
448
  </IfModule>
449
  <IfModule mod_expires.c>
450
  ExpiresActive On
451
  ExpiresByType image/webp "access plus 1 year"
452
  </IfModule>`
453
- `# ! --- DO NOT EDIT NEXT LINE --- !`
454
  `# END WebP Converter`
455
 
456
  = Is the plugin completely free? =
@@ -472,60 +273,6 @@ This is all very important to us and allows us to do even better things for you!
472
 
473
  == Changelog ==
474
 
475
- = 1.3.1 (2020-07-03) =
476
- * `[Fixed]` Text Domain for Internationalization
477
-
478
- = 1.3.0 (2020-06-12) =
479
- * `[Removed]` Ability to skip converting existing images when `Regenerate All`
480
- * `[Fixed]` Creating `/uploads-webpc` directory webpc after re-activation plugin
481
- * `[Fixed]` Error message about not supporting old PHP version
482
- * `[Fixed]` Ignoring case sensitivity when verifying image extensions
483
- * `[Changed]` Error messages when converting images
484
- * `[Changed]` New argument for filter `webpc_htaccess_mod_rewrite` and support for multiple .htaccess files
485
- * `[Added]` Converting all images from `/uploads` directory *(also other than from Media Library)*.
486
- * `[Added]` Converting images from `/plugins` directory
487
- * `[Added]` Converting images from `/themes` directory
488
- * `[Added]` Information about used filters in `Server configuration` tab
489
- * `[Added]` Option to force all images to be converted again when `Regenerate All`
490
-
491
- = 1.2.7 (2020-06-11) =
492
- * `[Changed]` Moving converted WebP files to `/uploads-webpc/uploads` directory from `/uploads-webpc` directory *(**required manual configuration change for Nginx and WordPress Multisite**)*
493
- * `[Changed]` Validation when converting images
494
-
495
- = 1.2.6 (2020-05-28) =
496
- * `[Fixed]` Removal of WebP files larger than original during upload
497
-
498
- = 1.2.5 (2020-05-10) =
499
- * `[Removed]` Link to plugin settings on Network Admin Screen for WordPress Multisite
500
- * `[Fixed]` Path in RewriteRule for WordPress Multisite
501
- * `[Changed]` Error messages in administration panel
502
- * `[Added]` Support for `disable_functions` setting for using `set_time_limit` function
503
- * `[Added]` Support for blocked function `file_get_contents`
504
-
505
- = 1.2.4 (2020-04-24) =
506
- * `[Changed]` Error messages in administration panel
507
- * `[Added]` Action `webpc_delete_paths` to delete images by paths
508
-
509
- = 1.2.3 (2020-04-15) =
510
- * `[Added]` Blocking server cache for rewrite rules
511
- * `[Added]` Detecting whether requests to images are processed by server bypassing Apache
512
-
513
- = 1.2.2 (2020-04-08) =
514
- * `[Changed]` Moving rules for modules `mod_mime` and `mod_expires` to `/uploads-webpc/.htaccess` file
515
- * `[Changed]` New argument for filter `webpc_htaccess_rules` with server path of file
516
-
517
- = 1.2.1 (2020-04-07) =
518
- * `[Removed]` Filter `webpc_option_disabled`
519
- * `[Fixed]` Converting images multiple times when uploading to Media Library
520
- * `[Added]` Action `webpc_convert_paths` to convert images by paths
521
- * `[Added]` Action `webpc_convert_attachment` to convert images by Post ID
522
-
523
- = 1.2.0 (2020-04-05) =
524
- * `[Changed]` Moving rules from .htaccess file in root directory of WordPress to `/wp-content/uploads` directory
525
- * `[Added]` Ability to disable automatic removal of WebP files larger than original
526
- * `[Added]` Error validation for a non-writable .htaccess file
527
- * `[Added]` Filter `webpc_uploads_root` to change path for root installation directory of WordPress
528
-
529
  = 1.1.2 (2020-03-03) =
530
  * `[Added]` Zero padding at end for odd-sized WebP files using `GD` library
531
 
@@ -543,7 +290,7 @@ This is all very important to us and allows us to do even better things for you!
543
 
544
  = 1.0.8 (2019-12-19) =
545
  * `[Fixed]` File deletion for custom paths with converted WebP files
546
- * `[Changed]` Rules management in .htaccess file when activating or deactivating plugin
547
  * `[Added]` Error detection system in server configuration
548
  * `[Added]` Blocking image conversion when `GD` or `Imagick` libraries are unavailable
549
 
1
  === WebP Converter for Media ===
2
  Contributors: mateuszgbiorczyk
3
  Donate link: https://ko-fi.com/gbiorczyk/
4
+ Tags: webp, images, performance, compress, optimize
5
  Requires at least: 5.0
6
+ Tested up to: 5.3
7
  Requires PHP: 7.0
8
  Stable tag: trunk
9
  License: GPLv2 or later
21
 
22
  This will be a profit both for your users who will not have to download so much data, but also for a server that will be less loaded. Remember that a better optimized website also affects your Google ranking.
23
 
 
 
 
 
24
  #### How does this work?
25
 
26
+ - By adding images to your media library, they are automatically converted and saved in a separate directory.
27
  - If you have just installed the plugin, you can convert all existing images with one click.
 
28
  - Images are converted using PHP `GD` or `Imagick` extension *(you can modify the compression level)*.
29
  - When the browser tries to download an image file, the server verifies if it supports `image/webp` files and if the file exists.
30
  - If everything is OK, instead of the original image, the browser will receive its equivalent in WebP format.
31
  - **The plugin does not change image URLs, so there are no problems with saving the HTML code of website to the cache and time of its generation does not increase.** It does not matter if the image display as an `img` HTML tag or you use `background-image`. It works always!
 
32
  - Image URLs are modified using the module `mod_rewrite` on the server, i.e. the same, and thanks to this we can use friendly links in WordPress. Additionally, the MIME type of the sent file is modified to `image/webp`.
 
33
  - The final result is that your users download less than half of the data, and the website itself loads faster!
34
 
 
 
 
 
35
  #### WebP images are the future!
36
 
37
  Raise your website to a new level now! Install the plugin and enjoy the website that loads faster. Surely you and your users will appreciate it.
38
 
 
 
 
 
 
 
39
  #### Please also read the FAQ below. Thank you for being with us!
40
 
41
  == Installation ==
42
 
43
+ 1. Upload the plugin files to `/wp-content/plugins/webp-converter-for-media/` directory, or install plugin through the WordPress plugins screen directly.
44
  2. Activate plugin through `Plugins` screen in WordPress Admin Panel.
45
  3. Use `Settings -> Settings -> WebP Converter` screen to configure the plugin.
46
  4. Click on the button `Regenerate All`.
52
 
53
  = How to get technical support? (before you ask for help) =
54
 
55
+ We are happy to help you with any problem. Contact us about this matter.
56
+
57
  Please always adding your thread, **read all other questions in the FAQ of plugin and other threads in support forum first**. Perhaps someone had a similar problem and it has been resolved.
58
 
59
+ This will save time repeating the same issues many times and solving the same problems.
60
+
61
+ If you do not find anything and you still have a problem, then contact us. So that we can better help you need additional information.
62
 
63
+ When adding a thread, follow these steps and reply to each of them:
64
 
65
+ **1.** Does your server meet the technical requirements described in the FAQ?
66
 
67
+ **2.** Do you use CDN? If so, please see the question **"Does the plugin support CDN?"** in plugin FAQ.
68
 
69
+ **3.** Do you use other plugins to optimize images? Please disable them and check this plugin without them. Remember not to combine several optimization plugins because they can be mutually exclusive.
70
 
71
+ **4.** Check if in `/wp-content/uploads-webpc/` directory are all files that should be converted.
72
 
73
  If not, please enable `WP_DEBUG_LOG` in your `wp-config.php` *(more about debugging: [https://codex.wordpress.org/WP_DEBUG](https://codex.wordpress.org/WP_DEBUG))*. That's what you should have in this file:
74
 
88
 
89
  Send a screenshot from console if an error occurred while converting images. Of you have errors in `/wp-content/debug.log` send their?
90
 
91
+ **5.** URL of your website. If your site is not publicly available, add it to test environment.
 
 
 
 
92
 
93
+ **6.** Configuration of your server *(link to it can be found on the settings page of plugin in the section **"We are waiting for your message"**)* - please take a screenshot of the ENTIRE page and send it to me.
94
 
95
+ Directly the URL path: `/wp-admin/options-general.php?page=webpc_admin_page&action=server`
96
 
97
+ **7.** Content of your `.htaccess` file.
98
 
99
+ **8.** What plugin version are you using? If it is not the latest then update and check everything again. Please also provide the version of WordPress and the list of plugins you use.
100
 
101
+ Please remember to include the answers for all 8 questions by adding a thread. It is much easier and accelerate the solution of your problem.
102
 
103
+ And most importantly - **do not leave the thread unanswered**. If you add a thread, follow when you get a reply. Then let us know if we have helped you or not. This helps us improve technical support.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  = What are requirements of plugin? =
106
 
107
+ Practically every hosting meets these requirements. You must use PHP at least 7.0 and have the `GD` or `Imagick` extension installed. **The extension must support `WebP format`.**
108
 
109
  They are required native PHP extensions, used among others by WordPress to generate thumbnails. Your server must also have the modules `mod_mime`, `mod_rewrite` and `mod_expires` enabled.
110
 
111
+ Also REST API must be enabled and work without additional restrictions.
112
 
113
+ An example of the correct server configuration can be found [here](https://gbiorczyk.pl/webp-converter/serverinfo.png). Link to your current configuration can be found in the administration panel, on the management plugin page in the section **"We are waiting for your message"** *(or using the URL path: `/wp-admin/options-general.php?page=webpc_admin_page&action=server`)*.
114
 
115
+ **Note the items marked in red.** If your server does not meet the technical requirements, please contact your server Administrator.
116
 
117
+ He is the most competent to solve such problems. Due to the huge amount of possible server environments, we are not able to help you with its configuration. Surely the server Administrator will be able to do it best.
118
 
119
  = What are restrictions? =
120
 
124
 
125
  You can find more about WebP support by browsers [here](https://caniuse.com/#feat=webp).
126
 
127
+ = How can I convert existing images after installing? =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
  In the WordPress admin panel, on the `Settings -> WebP Converter` subpage there is a module that allows you to process all your images.
130
 
131
  It uses the WordPress REST API by downloading addresses of all images and converting all files gradually.
132
 
133
+ This process may take few or more than ten minutes depending on the number of files. **It should be done once after installing the plugin.** Then all added images will be automatically regerated.
 
 
134
 
135
  = How to check if plugin works? =
136
 
145
  7. In addition, you can check weight of website before and after using plugin. The difference will be huge!
146
  8. More information: [here](https://gbiorczyk.pl/webp-converter/check-devtools.png)
147
 
148
+ Please remember that if the converted image in WebP format is larger than the original, the browser will use the original file. Therefore, you can also see files other than WebP on the list.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
  = Where are converted images stored? =
151
 
152
+ All WebP images are stored in the `/wp-content/uploads-webpc/` directory. Inside the directory there is the same structure as in the original `uploads` directory. The files have original extensions in the name along with the new `.webp`.
 
 
153
 
154
+ In case the location of the original file is as follows: `/wp-content/uploads/2019/06/example.jpg` then its converted version will be in the following location: `/wp-content/uploads-webpc/2019/06/example.jpg.webp`.
155
 
156
+ Original images are not changed.
157
 
158
  = How to change path to uploads? =
159
 
160
+ This is possible using two filters. You can change the path of the default uploads directory and directory in which WebP files will be stored.
161
 
162
+ Remember that this is the relative path of the domain. You can not change the domain there.
163
 
164
+ Here is an example using default paths:
 
 
 
 
165
 
166
  `add_filter('webpc_uploads_path', function($path) {
167
  return 'wp-content/uploads';
168
  });`
169
 
 
 
170
  `add_filter('webpc_uploads_webp', function($path) {
171
  return 'wp-content/uploads-webpc';
172
  });`
173
 
174
+ Filter `webpc_uploads_path` modifies the default path to the original uploads files. And filter `webpc_uploads_webp` changes the path where WebP files will be saved.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
+ Then go to `Settings -> WebP Converter` in the admin panel and click the `Save Changes` button. Also remember to regenerate all images using the `Regenerate All` button.
177
 
178
+ = Can I enable browser caching for WebP images? =
179
 
180
+ Yes of course. The plugin allows this by using the module `mod_expires`. Thanks to this, we can even speed up page loading time for returning users because they do not need to re-download files from the server.
181
 
182
+ If you do not want to use this functionality, you can turn it off at any time.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
184
  = Does plugin support CDN? =
185
 
187
 
188
  The main problem when changing URLs is cache. When we modify the image URL for WebP supporting browser, then use the browser without WebP support, it will still have the URL address of an image in .webp format, because it will be in the cache.
189
 
190
+ While in the case of the `img` tag you can solve this problem, in the case of `background-image` it is possible. We wanted full support so that all images added to the media library would be supported - no matter how they are displayed on the website.
191
 
192
  Therefore in this plugin for browsers supporting the WebP format, only the source of the file is replaced by using the `mod_rewrite` module on the server. The URL for image remains the same. This solves the whole problem, but it is impossible to do when the files are stored on the CDN server.
193
 
216
  `server {`
217
  ` # ...
218
 
219
+ location ~ (?<root>.+)/uploads/(?<path>.+)\.(?<ext>jp?g|png|gif)$ {
220
  if ($http_accept !~* "image/webp") {
221
  break;
222
  }
223
  add_header Vary Accept;
224
  expires 365d;
225
+ try_files $root/uploads-webpc/$path.$ext.webp $uri =404;
226
  }
227
  }`
228
 
229
  = Configuration for Multisite Network =
230
 
231
+ Yes, with one exception. In this mode it is not possible to automatically generate the contents of .htaccess file.
232
 
233
+ Please manually paste the following code **at the beginning of .htaccess file**:
234
 
235
  `# BEGIN WebP Converter`
236
+ `<IfModule mod_mime.c>
237
+ AddType image/webp .webp
238
+ </IfModule>
239
+ <IfModule mod_rewrite.c>
240
  RewriteEngine On
241
  RewriteCond %{HTTP_ACCEPT} image/webp
242
  RewriteCond %{DOCUMENT_ROOT}/wp-content/uploads-webpc/$1.jpg.webp -f
243
+ RewriteRule wp-content/uploads/(.+)\.jpg$ wp-content/uploads-webpc/$1.jpg.webp [T=image/webp]
244
  RewriteCond %{HTTP_ACCEPT} image/webp
245
  RewriteCond %{DOCUMENT_ROOT}/wp-content/uploads-webpc/$1.jpeg.webp -f
246
+ RewriteRule wp-content/uploads/(.+)\.jpeg$ wp-content/uploads-webpc/$1.jpeg.webp [T=image/webp]
247
  RewriteCond %{HTTP_ACCEPT} image/webp
248
  RewriteCond %{DOCUMENT_ROOT}/wp-content/uploads-webpc/$1.png.webp -f
249
+ RewriteRule wp-content/uploads/(.+)\.png$ wp-content/uploads-webpc/$1.png.webp [T=image/webp]
 
 
 
 
 
 
 
 
 
 
250
  </IfModule>
251
  <IfModule mod_expires.c>
252
  ExpiresActive On
253
  ExpiresByType image/webp "access plus 1 year"
254
  </IfModule>`
 
255
  `# END WebP Converter`
256
 
257
  = Is the plugin completely free? =
273
 
274
  == Changelog ==
275
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  = 1.1.2 (2020-03-03) =
277
  * `[Added]` Zero padding at end for odd-sized WebP files using `GD` library
278
 
290
 
291
  = 1.0.8 (2019-12-19) =
292
  * `[Fixed]` File deletion for custom paths with converted WebP files
293
+ * `[Changed]` Rules management in .htaccess file when activating/deactivating plugin
294
  * `[Added]` Error detection system in server configuration
295
  * `[Added]` Blocking image conversion when `GD` or `Imagick` libraries are unavailable
296
 
resources/_dev/js/classes/Regenerate.js CHANGED
@@ -19,7 +19,7 @@ export default class Regenerate
19
  this.errorsInner = this.errors.querySelector('.webpLoader__errorsContentList');
20
  this.errorsMessage = this.errors.querySelector('.webpLoader__errorsContentMessage');
21
  this.success = this.section.querySelector('.webpLoader__success');
22
- this.inputOptions = this.section.querySelectorAll('input[type="checkbox"]');
23
  this.button = this.section.querySelector('.webpLoader__button');
24
  this.data = {
25
  count: 0,
@@ -63,15 +63,10 @@ export default class Regenerate
63
  {
64
  e.preventDefault();
65
  if (this.settings.isDisabled) return;
66
-
67
  this.settings.isDisabled = true;
 
68
  this.button.classList.add(this.classes.buttonDisabled);
69
 
70
- const { length } = this.inputOptions;
71
- for (let i = 0; i < length; i++) {
72
- this.inputOptions[i].setAttribute('disabled', true);
73
- }
74
-
75
  this.wrapper.removeAttribute('hidden');
76
  this.getImagesList();
77
  }
@@ -80,10 +75,12 @@ export default class Regenerate
80
  {
81
  jQuery.ajax(this.settings.ajax.urlPaths, {
82
  type: 'POST',
83
- data: this.getDataForPathsRequest(),
 
 
84
  }).done((response) => {
85
- this.data.items = response;
86
- this.data.max = response.length;
87
  this.regenerateNextImages();
88
  }).fail(() => {
89
  this.progress.classList.add(this.classes.progressError);
@@ -92,17 +89,6 @@ export default class Regenerate
92
  });
93
  }
94
 
95
- getDataForPathsRequest()
96
- {
97
- const options = {};
98
- const { length } = this.inputOptions;
99
- for (let i = 0; i < length; i++) {
100
- const name = this.inputOptions[i].getAttribute('name');
101
- options[name] = (this.inputOptions[i].checked) ? 1 : 0;
102
- }
103
- return options;
104
- }
105
-
106
  /* ---
107
  Regenerate request
108
  --- */
19
  this.errorsInner = this.errors.querySelector('.webpLoader__errorsContentList');
20
  this.errorsMessage = this.errors.querySelector('.webpLoader__errorsContentMessage');
21
  this.success = this.section.querySelector('.webpLoader__success');
22
+ this.skipOption = this.section.querySelector('input[name="regenerate_skip"]');
23
  this.button = this.section.querySelector('.webpLoader__button');
24
  this.data = {
25
  count: 0,
63
  {
64
  e.preventDefault();
65
  if (this.settings.isDisabled) return;
 
66
  this.settings.isDisabled = true;
67
+ this.skipOption.setAttribute('disabled', true);
68
  this.button.classList.add(this.classes.buttonDisabled);
69
 
 
 
 
 
 
70
  this.wrapper.removeAttribute('hidden');
71
  this.getImagesList();
72
  }
75
  {
76
  jQuery.ajax(this.settings.ajax.urlPaths, {
77
  type: 'POST',
78
+ data: {
79
+ skip: this.skipOption.checked ? 1 : 0,
80
+ },
81
  }).done((response) => {
82
+ this.data.items = response.data;
83
+ this.data.max = response.data.length;
84
  this.regenerateNextImages();
85
  }).fail(() => {
86
  this.progress.classList.add(this.classes.progressError);
89
  });
90
  }
91
 
 
 
 
 
 
 
 
 
 
 
 
92
  /* ---
93
  Regenerate request
94
  --- */
resources/components/notices/thanks.php CHANGED
@@ -1,11 +1,11 @@
1
  <div class="notice notice-success is-dismissible" data-notice="webp-converter" data-url="<?= apply_filters('webpc_notice_url', ''); ?>">
2
  <div class="webpContent webpContent--notice">
3
  <h4>
4
- <?= __('Thank you for using our plugin WebP Converter for Media!', 'webp-converter-for-media'); ?>
5
  </h4>
6
  <p>
7
  <?= sprintf(
8
- __('Please let us know what you think about our plugin. It is important that we can develop this tool. Thank you for all the ratings, reviews and donates. If you have a technical problem, please before you add a review %scheck our FAQ%s or contact us if you did not find help there. We will try to help you!', 'webp-converter-for-media'),
9
  '<a href="https://wordpress.org/plugins/webp-converter-for-media/#faq" target="_blank">',
10
  '</a>'
11
  ); ?>
@@ -13,19 +13,19 @@
13
  <div class="webpContent__buttons">
14
  <a href="https://wordpress.org/support/plugin/webp-converter-for-media/#new-post" target="_blank"
15
  class="webpContent__button webpButton webpButton--green">
16
- <?= __('Get help', 'webp-converter-for-media'); ?>
17
  </a>
18
  <a href="https://wordpress.org/support/plugin/webp-converter-for-media/reviews/#new-post" target="_blank"
19
  class="webpContent__button webpButton webpButton--green">
20
- <?= __('Add review', 'webp-converter-for-media'); ?>
21
  </a>
22
  <a href="https://ko-fi.com/gbiorczyk/" target="_blank"
23
  class="webpContent__button webpButton webpButton--green dashicons-heart">
24
- <?= __('Provide us a coffee', 'webp-converter-for-media'); ?>
25
  </a>
26
  <a href="#" target="_blank" data-permanently
27
  class="webpContent__button webpButton webpButton--blue">
28
- <?= __('I added review, do not show again', 'webp-converter-for-media'); ?>
29
  </a>
30
  </div>
31
  </div>
1
  <div class="notice notice-success is-dismissible" data-notice="webp-converter" data-url="<?= apply_filters('webpc_notice_url', ''); ?>">
2
  <div class="webpContent webpContent--notice">
3
  <h4>
4
+ <?= __('Thank you for using our plugin WebP Converter for Media!', 'webp-converter'); ?>
5
  </h4>
6
  <p>
7
  <?= sprintf(
8
+ __('Please let us know what you think about our plugin. It is important that we can develop this tool. Thank you for all the ratings, reviews and donates. If you have a technical problem, please before you add a review %scheck our FAQ%s or contact us if you did not find help there. We will try to help you!', 'webp-converter'),
9
  '<a href="https://wordpress.org/plugins/webp-converter-for-media/#faq" target="_blank">',
10
  '</a>'
11
  ); ?>
13
  <div class="webpContent__buttons">
14
  <a href="https://wordpress.org/support/plugin/webp-converter-for-media/#new-post" target="_blank"
15
  class="webpContent__button webpButton webpButton--green">
16
+ <?= __('Get help', 'webp-converter'); ?>
17
  </a>
18
  <a href="https://wordpress.org/support/plugin/webp-converter-for-media/reviews/#new-post" target="_blank"
19
  class="webpContent__button webpButton webpButton--green">
20
+ <?= __('Add review', 'webp-converter'); ?>
21
  </a>
22
  <a href="https://ko-fi.com/gbiorczyk/" target="_blank"
23
  class="webpContent__button webpButton webpButton--green dashicons-heart">
24
+ <?= __('Provide us a coffee', 'webp-converter'); ?>
25
  </a>
26
  <a href="#" target="_blank" data-permanently
27
  class="webpContent__button webpButton webpButton--blue">
28
+ <?= __('I added review, do not show again', 'webp-converter'); ?>
29
  </a>
30
  </div>
31
  </div>
resources/components/widgets/about.php CHANGED
@@ -1,26 +1,26 @@
1
  <div class="webpPage__widget">
2
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--second">
3
- <?= __('How does this work?', 'webp-converter-for-media'); ?>
4
  </h3>
5
  <div class="webpContent">
6
  <p>
7
  <?= sprintf(
8
- __('By adding images to your media library, they are automatically converted and saved in a separate directory. Images are converted using %sGD%s or %sImagick%s native extension for PHP.', 'webp-converter-for-media'),
9
  '<strong>', '</strong>', '<strong>', '</strong>'
10
  ); ?>
11
  </p>
12
  <p>
13
  <?= sprintf(
14
- __('When the browser tries to download an image file, the server verifies if it supports image/webp files and if the file exists. If everything is OK, instead of the original image, the browser will receive its equivalent in WebP format.', 'webp-converter-for-media'),
15
  '<strong>', '</strong>'
16
  ); ?>
17
  </p>
18
  <p>
19
- <?= __('The plugin does not change file URLs, so there are no problems with saving the page to the cache and the page generation time does not increase.', 'webp-converter-for-media'); ?>
20
  </p>
21
  <p>
22
  <?= sprintf(
23
- __('Image URLs are modified using the module %smod_rewrite%s on the server, i.e. the same, thanks to which we can use friendly links in WordPress. Additionally, the MIME type of the sent file is modified to %simage/webp%s.', 'webp-converter-for-media'),
24
  '<strong>', '</strong>', '<strong>', '</strong>'
25
  ); ?>
26
  </p>
1
  <div class="webpPage__widget">
2
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--second">
3
+ <?= __('How does this work?', 'webp-converter'); ?>
4
  </h3>
5
  <div class="webpContent">
6
  <p>
7
  <?= sprintf(
8
+ __('By adding images to your media library, they are automatically converted and saved in a separate directory. Images are converted using %sGD%s or %sImagick%s native extension for PHP.', 'webp-converter'),
9
  '<strong>', '</strong>', '<strong>', '</strong>'
10
  ); ?>
11
  </p>
12
  <p>
13
  <?= sprintf(
14
+ __('When the browser tries to download an image file, the server verifies if it supports image/webp files and if the file exists. If everything is OK, instead of the original image, the browser will receive its equivalent in WebP format.', 'webp-converter'),
15
  '<strong>', '</strong>'
16
  ); ?>
17
  </p>
18
  <p>
19
+ <?= __('The plugin does not change file URLs, so there are no problems with saving the page to the cache and the page generation time does not increase.', 'webp-converter'); ?>
20
  </p>
21
  <p>
22
  <?= sprintf(
23
+ __('Image URLs are modified using the module %smod_rewrite%s on the server, i.e. the same, thanks to which we can use friendly links in WordPress. Additionally, the MIME type of the sent file is modified to %simage/webp%s.', 'webp-converter'),
24
  '<strong>', '</strong>', '<strong>', '</strong>'
25
  ); ?>
26
  </p>
resources/components/widgets/donate.php CHANGED
@@ -1,14 +1,14 @@
1
  <div class="webpPage__widget">
2
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--second">
3
- <?= __('We love what we do!', 'webp-converter-for-media'); ?>
4
  </h3>
5
  <div class="webpContent webpContent--lastCenter">
6
  <p>
7
- <?= __('However, working on plugins and technical support requires many hours of work. If you want to appreciate it, you can provide us a coffee. Thanks everyone!', 'webp-converter-for-media'); ?>
8
  </p>
9
  <p>
10
  <a href="https://ko-fi.com/gbiorczyk/" target="_blank" class="webpButton webpButton--blue dashicons-heart">
11
- <?= __('Provide us a coffee', 'webp-converter-for-media'); ?>
12
  </a>
13
  </p>
14
  </div>
1
  <div class="webpPage__widget">
2
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--second">
3
+ <?= __('We love what we do!', 'webp-converter'); ?>
4
  </h3>
5
  <div class="webpContent webpContent--lastCenter">
6
  <p>
7
+ <?= __('However, working on plugins and technical support requires many hours of work. If you want to appreciate it, you can provide us a coffee. Thanks everyone!', 'webp-converter'); ?>
8
  </p>
9
  <p>
10
  <a href="https://ko-fi.com/gbiorczyk/" target="_blank" class="webpButton webpButton--blue dashicons-heart">
11
+ <?= __('Provide us a coffee', 'webp-converter'); ?>
12
  </a>
13
  </p>
14
  </div>
resources/components/widgets/errors.php CHANGED
@@ -1,57 +1,30 @@
1
  <?php if ($errors = apply_filters('webpc_server_errors', [])) : ?>
2
  <div class="webpPage__widget">
3
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--error">
4
- <?= __('Server configuration error', 'webp-converter-for-media'); ?>
5
  </h3>
6
  <div class="webpContent">
7
  <?php if (in_array('path_uploads', $errors)) : ?>
8
  <p>
9
  <?= sprintf(
10
- __('The path for /uploads files does not exist %s(function is_dir() returns false)%s. Use filters %s or %s to set the correct path. The current using path is: %s. Please read the plugin FAQ to learn more.', 'webp-converter-for-media'),
11
- '<em>',
12
- '</em>',
13
- '<strong>webpc_uploads_root</strong>',
14
  '<strong>webpc_uploads_path</strong>',
15
- '<strong>' . apply_filters('webpc_uploads_path', '') . '</strong>'
16
- ); ?>
17
- </p>
18
- <?php endif; ?>
19
- <?php if (in_array('path_htaccess', $errors)) : ?>
20
- <p>
21
- <?= sprintf(
22
- __('Unable to create or edit .htaccess file %s(function is_readable() or is_writable() returns false)%s. Change directory permissions. The current using path of file is: %s. Please contact your server administrator.', 'webp-converter-for-media'),
23
- '<em>',
24
- '</em>',
25
- '<strong>' . apply_filters('webpc_uploads_path', '') . '/.htaccess</strong>'
26
  ); ?>
27
  </p>
28
  <?php endif; ?>
29
  <?php if (in_array('path_webp', $errors)) : ?>
30
  <p>
31
  <?= sprintf(
32
- __('The path for saving converted WebP files does not exist and cannot be created %s(function is_writable() returns false)%s. Use filters %s or %s to set the correct path. The current using path is: %s. Please read the plugin FAQ to learn more.', 'webp-converter-for-media'),
33
- '<em>',
34
- '</em>',
35
- '<strong>webpc_uploads_root</strong>',
36
- '<strong>webpc_uploads_webp</strong>',
37
- '<strong>' . apply_filters('webpc_uploads_webp', '') . '</strong>'
38
- ); ?>
39
- </p>
40
- <?php endif; ?>
41
- <?php if (in_array('path_duplicated', $errors)) : ?>
42
- <p>
43
- <?= sprintf(
44
- __('The paths for /uploads files and for saving converted WebP files are the same. Change them using filters %s or %s. The current path for them is: %s.', 'webp-converter-for-media'),
45
- '<strong>webpc_uploads_path</strong>',
46
- '<strong>webpc_uploads_webp</strong>',
47
- '<strong>' . apply_filters('webpc_uploads_path', '') . '</strong>'
48
  ); ?>
49
  </p>
50
  <?php endif; ?>
51
  <?php if (in_array('rest_api', $errors)) : ?>
52
  <p>
53
  <?= sprintf(
54
- __('The REST API on your website is not available. Please verify this and try again. Pay special attention to the filters: %s, %s and %s.', 'webp-converter-for-media'),
55
  '<a href="https://developer.wordpress.org/reference/hooks/rest_enabled/" target="_blank">rest_enabled</a>',
56
  '<a href="https://developer.wordpress.org/reference/hooks/rest_jsonp_enabled/" target="_blank">rest_jsonp_enabled</a>',
57
  '<a href="https://developer.wordpress.org/reference/hooks/rest_authentication_errors/" target="_blank">rest_authentication_errors</a>'
@@ -61,28 +34,8 @@
61
  <?php if (in_array('methods', $errors)) : ?>
62
  <p>
63
  <?= sprintf(
64
- __('On your server is not installed %sGD%s or %sImagick%s library, or installed extension does not support WebP format. Check your server configuration %shere%s and try again. Please contact your server administrator.', 'webp-converter-for-media'),
65
- '<strong>',
66
- '</strong>',
67
- '<strong>',
68
- '</strong>',
69
- '<a href="' . sprintf('%s&action=server', menu_page_url('webpc_admin_page', false)) . '">',
70
- '</a>'
71
- ); ?>
72
- </p>
73
- <?php endif; ?>
74
- <?php if (in_array('bypassing_apache', $errors)) : ?>
75
- <p>
76
- <?= sprintf(
77
- __('Requests to images are processed by your server bypassing Apache. When loading images, rules from the .htaccess file are not executed. Check the redirects for %s.png file%s %s(for which the redirection does not work)%s and for %s.png2 file%s %s(for which the redirection works correctly)%s. Change the server settings to stop ignoring the rules in the .htaccess file. Please contact your server administrator.', 'webp-converter-for-media'),
78
- '<a href="' . WEBPC_URL . 'public/img/icon-before.png" target="_blank">',
79
- '</a>',
80
- '<em>',
81
- '</em>',
82
- '<a href="' . WEBPC_URL . 'public/img/icon-before.png2" target="_blank">',
83
- '</a>',
84
- '<em>',
85
- '</em>'
86
  ); ?>
87
  </p>
88
  <?php endif; ?>
1
  <?php if ($errors = apply_filters('webpc_server_errors', [])) : ?>
2
  <div class="webpPage__widget">
3
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--error">
4
+ <?= __('Server configuration error', 'webp-converter'); ?>
5
  </h3>
6
  <div class="webpContent">
7
  <?php if (in_array('path_uploads', $errors)) : ?>
8
  <p>
9
  <?= sprintf(
10
+ __('The path for uploads files does not exist. Please use the %s filter to set the correct path. The default path is: %s.', 'webp-converter'),
 
 
 
11
  '<strong>webpc_uploads_path</strong>',
12
+ '<strong>' . ABSPATH . 'wp-content/uploads/</strong>'
 
 
 
 
 
 
 
 
 
 
13
  ); ?>
14
  </p>
15
  <?php endif; ?>
16
  <?php if (in_array('path_webp', $errors)) : ?>
17
  <p>
18
  <?= sprintf(
19
+ __('The path for saving converted WebP files does not exist and cannot be created. Please check your server configuration and try again. The default path is: %s.', 'webp-converter'),
20
+ '<strong>' . ABSPATH . 'wp-content/uploads-webpc/</strong>'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  ); ?>
22
  </p>
23
  <?php endif; ?>
24
  <?php if (in_array('rest_api', $errors)) : ?>
25
  <p>
26
  <?= sprintf(
27
+ __('The REST API on your website is not available. Please verify this and try again. Pay special attention to the filters: %s, %s and %s.', 'webp-converter'),
28
  '<a href="https://developer.wordpress.org/reference/hooks/rest_enabled/" target="_blank">rest_enabled</a>',
29
  '<a href="https://developer.wordpress.org/reference/hooks/rest_jsonp_enabled/" target="_blank">rest_jsonp_enabled</a>',
30
  '<a href="https://developer.wordpress.org/reference/hooks/rest_authentication_errors/" target="_blank">rest_authentication_errors</a>'
34
  <?php if (in_array('methods', $errors)) : ?>
35
  <p>
36
  <?= sprintf(
37
+ __('On your server is not installed %sGD%s or %sImagick%s library, or installed extension does not support WebP format. Please check your server configuration and try again.', 'webp-converter'),
38
+ '<strong>', '</strong>', '<strong>', '</strong>'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  ); ?>
40
  </p>
41
  <?php endif; ?>
resources/components/widgets/options.php CHANGED
@@ -1,6 +1,6 @@
1
  <div class="webpPage__widget">
2
  <h3 class="webpPage__widgetTitle">
3
- <?= __('Settings', 'webp-converter-for-media'); ?>
4
  </h3>
5
  <div class="webpContent">
6
  <?php foreach ($options as $index => $option) : ?>
@@ -11,12 +11,12 @@
11
  <?php endforeach; ?>
12
  <div class="webpPage__widgetRow">
13
  <button type="submit" name="webpc_save"
14
- class="webpButton webpButton--green"><?= __('Save Changes', 'webp-converter-for-media'); ?></button>
15
  </div>
16
  <div class="webpPage__widgetRow">
17
  <p>
18
  <?= sprintf(
19
- __('If you have a problem %scheck our FAQ%s first. If you did not find help there, please %scheck support forum%s for any similar problem or contact us. Before you contact us %scheck the configuration%s of your server.', 'webp-converter-for-media'),
20
  '<a href="https://wordpress.org/plugins/webp-converter-for-media/#faq" target="_blank">',
21
  '</a>',
22
  '<a href="https://wordpress.org/support/plugin/webp-converter-for-media/" target="_blank">',
1
  <div class="webpPage__widget">
2
  <h3 class="webpPage__widgetTitle">
3
+ <?= __('Settings', 'webp-converter'); ?>
4
  </h3>
5
  <div class="webpContent">
6
  <?php foreach ($options as $index => $option) : ?>
11
  <?php endforeach; ?>
12
  <div class="webpPage__widgetRow">
13
  <button type="submit" name="webpc_save"
14
+ class="webpButton webpButton--green"><?= __('Save Changes', 'webp-converter'); ?></button>
15
  </div>
16
  <div class="webpPage__widgetRow">
17
  <p>
18
  <?= sprintf(
19
+ __('If you have a problem %scheck our FAQ%s first. If you did not find help there, please %scheck support forum%s for any similar problem or contact us. Before you contact us %scheck the configuration%s of your server.', 'webp-converter'),
20
  '<a href="https://wordpress.org/plugins/webp-converter-for-media/#faq" target="_blank">',
21
  '</a>',
22
  '<a href="https://wordpress.org/support/plugin/webp-converter-for-media/" target="_blank">',
resources/components/widgets/regenerate.php CHANGED
@@ -4,18 +4,18 @@
4
  ?>
5
  <div class="webpPage__widget">
6
  <h3 class="webpPage__widgetTitle">
7
- <?= __('Regenerate images', 'webp-converter-for-media'); ?>
8
  </h3>
9
  <div class="webpLoader webpContent"
10
  data-api-paths="<?= $apiPaths; ?>"
11
  data-api-regenerate="<?= $apiRegenerate; ?>"
12
- data-api-error-message="<?= __('An unknown error occurred while converting the images: %s', 'webp-converter-for-media'); ?>">
13
  <div class="webpPage__widgetRow">
14
  <p>
15
- <?= __('Convert all existing images with just one click! This tool uses the WordPress REST API by downloading addresses of all images and converting all files gradually. This is a process that may take a few or more than ten minutes depending on the number of files. During this process, please do not close your browser window.', 'webp-converter-for-media'); ?>
16
  </p>
17
  <p>
18
- <?= __('This operation should be performed only once after installing the plugin. New images from the Media Library will be converted automatically. For other images, e.g. from the /themes or /uploads directory that are not from the Media Library, you must start manual conversion after adding new images.', 'webp-converter-for-media'); ?>
19
  </p>
20
  <div class="webpLoader__status" hidden>
21
  <div class="webpLoader__bar">
@@ -24,20 +24,20 @@
24
  </div>
25
  <div class="webpLoader__size">
26
  <?= sprintf(
27
- __('Saving the weight of your images: %s', 'webp-converter-for-media'),
28
  '<span class="webpLoader__sizeProgress">0 kB</span>'
29
  ); ?>
30
  </div>
31
  </div>
32
  <div class="webpLoader__success" hidden>
33
- <?= __('The process was completed successfully. Your images have been converted!', 'webp-converter-for-media'); ?>
34
  </div>
35
  <div class="webpLoader__errors" hidden>
36
- <div class="webpLoader__errorsTitle"><?= __('List of errors', 'webp-converter-for-media'); ?></div>
37
  <div class="webpLoader__errorsContent">
38
  <div class="webpLoader__errorsContentList"></div>
39
  <div class="webpLoader__errorsContentMessage" hidden>
40
- <?= __('An error occurred while connecting to REST API. Please try again.', 'webp-converter-for-media'); ?>
41
  </div>
42
  </div>
43
  </div>
@@ -47,13 +47,13 @@
47
  <table class="webpPage__widgetTable">
48
  <tr>
49
  <td>
50
- <input type="checkbox" name="regenerate_force" value="1"
51
- id="webpc-regenerate-force" class="webpPage__checkbox">
52
- <label for="webpc-regenerate-force"></label>
53
  </td>
54
  <td>
55
- <label for="webpc-regenerate-force" class="webpPage__checkboxLabel">
56
- <?= __('Force convert all images again', 'webp-converter-for-media'); ?>
57
  </label>
58
  </td>
59
  </tr>
@@ -61,7 +61,7 @@
61
  <button type="button" target="_blank"
62
  class="webpLoader__button webpButton webpButton--green"
63
  <?= (apply_filters('webpc_server_errors', [])) ? 'disabled' : ''; ?>>
64
- <?= __('Regenerate All', 'webp-converter-for-media'); ?>
65
  </button>
66
  </div>
67
  </div>
4
  ?>
5
  <div class="webpPage__widget">
6
  <h3 class="webpPage__widgetTitle">
7
+ <?= __('Regenerate images', 'webp-converter'); ?>
8
  </h3>
9
  <div class="webpLoader webpContent"
10
  data-api-paths="<?= $apiPaths; ?>"
11
  data-api-regenerate="<?= $apiRegenerate; ?>"
12
+ data-api-error-message="<?= __('An unknown error occurred while converting the images: %s', 'webp-converter'); ?>">
13
  <div class="webpPage__widgetRow">
14
  <p>
15
+ <?= __('Convert all existing images with just one click! This tool uses the WordPress REST API by downloading addresses of all images and converting all files gradually. This is a process that may take a few or more than ten minutes depending on the number of files. During this process, please do not close your browser window.', 'webp-converter'); ?>
16
  </p>
17
  <p>
18
+ <?= __('This operation should be performed only once after installing the plugin. New images will be converted automatically.', 'webp-converter'); ?>
19
  </p>
20
  <div class="webpLoader__status" hidden>
21
  <div class="webpLoader__bar">
24
  </div>
25
  <div class="webpLoader__size">
26
  <?= sprintf(
27
+ __('Saving the weight of your images: %s', 'webp-converter'),
28
  '<span class="webpLoader__sizeProgress">0 kB</span>'
29
  ); ?>
30
  </div>
31
  </div>
32
  <div class="webpLoader__success" hidden>
33
+ <?= __('The process was completed successfully. Your images have been converted!', 'webp-converter'); ?>
34
  </div>
35
  <div class="webpLoader__errors" hidden>
36
+ <div class="webpLoader__errorsTitle"><?= __('List of errors', 'webp-converter'); ?></div>
37
  <div class="webpLoader__errorsContent">
38
  <div class="webpLoader__errorsContentList"></div>
39
  <div class="webpLoader__errorsContentMessage" hidden>
40
+ <?= __('An error occurred while connecting to REST API. Please try again.', 'webp-converter'); ?>
41
  </div>
42
  </div>
43
  </div>
47
  <table class="webpPage__widgetTable">
48
  <tr>
49
  <td>
50
+ <input type="checkbox" name="regenerate_skip" value="1"
51
+ id="webpc-regenerate-skip" class="webpPage__checkbox">
52
+ <label for="webpc-regenerate-skip"></label>
53
  </td>
54
  <td>
55
+ <label for="webpc-regenerate-skip" class="webpPage__checkboxLabel">
56
+ <?= __('Skip converted images', 'webp-converter'); ?>
57
  </label>
58
  </td>
59
  </tr>
61
  <button type="button" target="_blank"
62
  class="webpLoader__button webpButton webpButton--green"
63
  <?= (apply_filters('webpc_server_errors', [])) ? 'disabled' : ''; ?>>
64
+ <?= __('Regenerate All', 'webp-converter'); ?>
65
  </button>
66
  </div>
67
  </div>
resources/components/widgets/server.php CHANGED
@@ -4,18 +4,18 @@
4
  ?>
5
  <div class="webpPage__widget">
6
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--second">
7
- <?= __('Your server configuration', 'webp-converter-for-media'); ?>
8
  </h3>
9
  <div class="webpContent">
10
  <div class="webpPage__widgetRow">
11
  <p>
12
- <?= sprintf(__('Please compare your configuration with the configuration that is given in the technical requirements in %sthe plugin FAQ%s. If your server does not meet the technical requirements, please contact your server Administrator.', 'webp-converter-for-media'),
13
  '<a href="https://wordpress.org/plugins/webp-converter-for-media/#faq" target="_blank">',
14
  '</a>'
15
  ); ?>
16
  </p>
17
  <a href="<?= $pageUrl; ?>" class="webpLoader__button webpButton webpButton--blue">
18
- <?= __('Back to settings', 'webp-converter-for-media'); ?>
19
  </a>
20
  </div>
21
  <div class="webpPage__widgetRow">
@@ -23,7 +23,7 @@
23
  </div>
24
  <div class="webpPage__widgetRow">
25
  <a href="<?= $pageUrl; ?>" class="webpLoader__button webpButton webpButton--blue">
26
- <?= __('Back to settings', 'webp-converter-for-media'); ?>
27
  </a>
28
  </div>
29
  </div>
4
  ?>
5
  <div class="webpPage__widget">
6
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--second">
7
+ <?= __('Your server configuration', 'webp-converter'); ?>
8
  </h3>
9
  <div class="webpContent">
10
  <div class="webpPage__widgetRow">
11
  <p>
12
+ <?= sprintf(__('Please compare your configuration with the configuration that is given in the technical requirements in %sthe plugin FAQ%s. If your server does not meet the technical requirements, please contact your server Administrator.', 'webp-converter'),
13
  '<a href="https://wordpress.org/plugins/webp-converter-for-media/#faq" target="_blank">',
14
  '</a>'
15
  ); ?>
16
  </p>
17
  <a href="<?= $pageUrl; ?>" class="webpLoader__button webpButton webpButton--blue">
18
+ <?= __('Back to settings', 'webp-converter'); ?>
19
  </a>
20
  </div>
21
  <div class="webpPage__widgetRow">
23
  </div>
24
  <div class="webpPage__widgetRow">
25
  <a href="<?= $pageUrl; ?>" class="webpLoader__button webpButton webpButton--blue">
26
+ <?= __('Back to settings', 'webp-converter'); ?>
27
  </a>
28
  </div>
29
  </div>
resources/components/widgets/support.php CHANGED
@@ -1,14 +1,14 @@
1
  <div class="webpPage__widget">
2
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--second">
3
- <?= __('We are waiting for your message', 'webp-converter-for-media'); ?>
4
  </h3>
5
  <div class="webpContent">
6
  <p>
7
- <?= __('Do you have a technical problem? Please contact us. We will be happy to help you. Or maybe you have an idea for a new feature? Please let us know about it by filling the support form. We will try to add it!', 'webp-converter-for-media'); ?>
8
  </p>
9
  <p>
10
  <?= sprintf(
11
- __('Please %scheck our FAQ%s before adding a thread with technical problem. If you do not find help there, %scheck support forum%s for similar problems. Before you contact us check the configuration of your server and attach it in your message, e.g. as a screenshot.', 'webp-converter-for-media'),
12
  '<a href="https://wordpress.org/plugins/webp-converter-for-media/#faq" target="_blank">',
13
  '</a>',
14
  '<a href="https://wordpress.org/support/plugin/webp-converter-for-media/" target="_blank">',
@@ -17,18 +17,18 @@
17
  </p>
18
  <p>
19
  <a href="<?= sprintf('%s&action=server', menu_page_url('webpc_admin_page', false)); ?>" class="webpButton webpButton--blue">
20
- <?= __('Server configuration', 'webp-converter-for-media'); ?>
21
  </a>
22
  <a href="https://wordpress.org/support/plugin/webp-converter-for-media/" target="_blank" class="webpButton webpButton--blue">
23
- <?= __('Get help', 'webp-converter-for-media'); ?>
24
  </a>
25
  </p>
26
  <p>
27
- <?= __('Do you like our plugin? Could you rate him? Please let us know what you think about our plugin. It is important that we can develop this tool. Thank you for all the ratings, reviews and donates.', 'webp-converter-for-media'); ?>
28
  </p>
29
  <p>
30
  <a href="https://wordpress.org/support/plugin/webp-converter-for-media/reviews/#new-post" target="_blank" class="webpButton webpButton--blue">
31
- <?= __('Add review', 'webp-converter-for-media'); ?>
32
  </a>
33
  </p>
34
  </div>
1
  <div class="webpPage__widget">
2
  <h3 class="webpPage__widgetTitle webpPage__widgetTitle--second">
3
+ <?= __('We are waiting for your message', 'webp-converter'); ?>
4
  </h3>
5
  <div class="webpContent">
6
  <p>
7
+ <?= __('Do you have a technical problem? Please contact us. We will be happy to help you. Or maybe you have an idea for a new feature? Please let us know about it by filling the support form. We will try to add it!', 'webp-converter'); ?>
8
  </p>
9
  <p>
10
  <?= sprintf(
11
+ __('Please %scheck our FAQ%s before adding a thread with technical problem. If you do not find help there, %scheck support forum%s for similar problems. Before you contact us check the configuration of your server and attach it in your message, e.g. as a screenshot.', 'webp-converter'),
12
  '<a href="https://wordpress.org/plugins/webp-converter-for-media/#faq" target="_blank">',
13
  '</a>',
14
  '<a href="https://wordpress.org/support/plugin/webp-converter-for-media/" target="_blank">',
17
  </p>
18
  <p>
19
  <a href="<?= sprintf('%s&action=server', menu_page_url('webpc_admin_page', false)); ?>" class="webpButton webpButton--blue">
20
+ <?= __('Server configuration', 'webp-converter'); ?>
21
  </a>
22
  <a href="https://wordpress.org/support/plugin/webp-converter-for-media/" target="_blank" class="webpButton webpButton--blue">
23
+ <?= __('Get help', 'webp-converter'); ?>
24
  </a>
25
  </p>
26
  <p>
27
+ <?= __('Do you like our plugin? Could you rate him? Please let us know what you think about our plugin. It is important that we can develop this tool. Thank you for all the ratings, reviews and donates.', 'webp-converter'); ?>
28
  </p>
29
  <p>
30
  <a href="https://wordpress.org/support/plugin/webp-converter-for-media/reviews/#new-post" target="_blank" class="webpButton webpButton--blue">
31
+ <?= __('Add review', 'webp-converter'); ?>
32
  </a>
33
  </p>
34
  </div>
resources/views/settings.php CHANGED
@@ -5,11 +5,11 @@
5
  ?>
6
  <form method="post" action="<?= $path; ?>" class="webpPage">
7
  <div class="webpPage__inner">
8
- <h1 class="webpPage__headline"><?= __('WebP Converter for Media', 'webp-converter-for-media'); ?></h1>
9
  <ul class="webpPage__columns">
10
  <li class="webpPage__column webpPage__column--large">
11
  <?php if ($_POST) : ?>
12
- <div class="webpPage__alert"><?= __('Changes were successfully saved!', 'webp-converter-for-media'); ?></div>
13
  <?php endif; ?>
14
  <?php
15
  if (isset($_GET['action']) && ($_GET['action'] === 'server')) {
5
  ?>
6
  <form method="post" action="<?= $path; ?>" class="webpPage">
7
  <div class="webpPage__inner">
8
+ <h1 class="webpPage__headline"><?= __('WebP Converter for Media', 'webp-converter'); ?></h1>
9
  <ul class="webpPage__columns">
10
  <li class="webpPage__column webpPage__column--large">
11
  <?php if ($_POST) : ?>
12
+ <div class="webpPage__alert"><?= __('Changes were successfully saved!', 'webp-converter'); ?></div>
13
  <?php endif; ?>
14
  <?php
15
  if (isset($_GET['action']) && ($_GET['action'] === 'server')) {
webp-converter-for-media.php CHANGED
@@ -3,13 +3,13 @@
3
  /*
4
  Plugin Name: WebP Converter for Media
5
  Description: Speed up your website by serving WebP images instead of standard formats JPEG, PNG and GIF.
6
- Version: 1.3.1
7
  Author: Mateusz Gbiorczyk
8
  Author URI: https://gbiorczyk.pl/
9
- Text Domain: webp-converter-for-media
10
  */
11
 
12
- define('WEBPC_VERSION', '1.3.1');
13
  define('WEBPC_FILE', __FILE__);
14
  define('WEBPC_NAME', plugin_basename(__FILE__));
15
  define('WEBPC_PATH', plugin_dir_path(__FILE__));
3
  /*
4
  Plugin Name: WebP Converter for Media
5
  Description: Speed up your website by serving WebP images instead of standard formats JPEG, PNG and GIF.
6
+ Version: 1.1.2
7
  Author: Mateusz Gbiorczyk
8
  Author URI: https://gbiorczyk.pl/
9
+ Text Domain: webp-converter
10
  */
11
 
12
+ define('WEBPC_VERSION', '1.1.2');
13
  define('WEBPC_FILE', __FILE__);
14
  define('WEBPC_NAME', plugin_basename(__FILE__));
15
  define('WEBPC_PATH', plugin_dir_path(__FILE__));