PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.5.2
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.5.2
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
wp-optimize / webp / class-wpo-webp-alter-html.php

class-wpo-webp-alter-html.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 4.5.2, at webp/class-wpo-webp-alter-html.php

183 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) die('No direct access allowed');
4
5 if (!class_exists('WPO_WebP_Alter_HTML')) :
6
7 class WPO_WebP_Alter_HTML {
8
9 private $tags = array('img', 'source', 'input', 'iframe', 'div', 'li', 'link', 'a', 'section', 'video');
10
11 /**
12 * Constructor
13 */
14 private function __construct() {
15
16 }
17
18 /**
19 * Returns singleton instance
20 *
21 * @return WPO_WebP_Alter_HTML
22 */
23 public static function get_instance() {
24 static $_instance = null;
25 if (null === $_instance) {
26 $_instance = new self();
27 }
28 return $_instance;
29 }
30
31 /**
32 * Alter html to change image related tags to specify webp images
33 *
34 * @param string $html - HTML document as string
35 * @return string
36 */
37 public function alter_html(string $html): string {
38 if (apply_filters('wpo_disable_webp_alter_html', false)) {
39 return $html;
40 }
41
42 // MAX_FILE_SIZE is defined in simple_html_dom.
43 // For safety, we make sure it is defined before using
44 defined('MAX_FILE_SIZE') || define('MAX_FILE_SIZE', 600000);
45
46 $dom = WP_Optimize_Utils::get_simple_html_dom_object($html);
47
48 if (false === $dom) {
49 if (strlen($html) > MAX_FILE_SIZE) {
50 return $html . "\n" . "<!-- Alter HTML was skipped because the HTML is too big to process! " .
51 "(limit is set to " . MAX_FILE_SIZE . " bytes) -->";
52 }
53 return $html . "\n" . "<!-- Alter HTML was skipped because the helper library refused to process the html -->";
54 }
55
56 // Replace attributes (src, srcset, data-src, etc)
57 foreach ($this->tags as $tag) {
58 $elems = $dom->find($tag);
59 foreach ($elems as $elem) {
60 $attributes = $elem->getAllAttributes();
61 foreach ($attributes as $attr_name => $attr_value) {
62 if ($this->is_image_attribute($attr_name)) {
63 $elem->setAttribute($attr_name, $this->handle_attribute($attr_value));
64 }
65 }
66 }
67 }
68
69 $result = $dom->save();
70 return $result;
71 }
72
73 /**
74 * Append image urls with `.webp` extension
75 *
76 * @param string $url - Image URL
77 * @return string
78 */
79 private function replace_url($url) {
80 return $url . '.webp';
81 }
82
83 /**
84 * If webp version for supplied image url is available then replace extension
85 *
86 * @param string $url - URL of image
87 * @return string
88 */
89 private function maybe_replace_url($url) {
90 if ($this->is_webp_version_available($url)) {
91 $url = $this->replace_url($url);
92 }
93 return $url;
94 }
95
96 /**
97 * Modifies src attribute value, if needed
98 *
99 * @param string $attr_value
100 * @return string
101 */
102 private function handle_src($attr_value) {
103 return $this->maybe_replace_url($attr_value);
104 }
105
106 /**
107 * Modified `srcset` attribute value, if needed
108 *
109 * @param string $attr_value
110 * @return string
111 */
112 private function handle_srcset($attr_value) {
113 // $attr_value is ie: <img data-x="1.jpg 1000w, 2.jpg">
114 $srcset_arr = explode(',', $attr_value);
115 foreach ($srcset_arr as $i => $srcset_entry) {
116 // $srcset_entry is ie "image.jpg 520w", but can also lack width, ie just "image.jpg"
117 // it can also be ie "image.jpg 2x"
118 $srcset_entry = trim($srcset_entry);
119 $entry_parts = preg_split('/\s+/', $srcset_entry, 2);
120 if (2 === count($entry_parts)) {
121 list($src, $descriptors) = $entry_parts;
122 } else {
123 $src = $srcset_entry;
124 $descriptors = null;
125 }
126
127 $url = $this->maybe_replace_url($src);
128 $srcset_arr[$i] = $url . (isset($descriptors) ? ' ' . $descriptors : '');
129 }
130 return implode(', ', $srcset_arr);
131 }
132
133 /**
134 * Decides whether given value is a `srcset` or not
135 *
136 * @param string $value
137 * @return bool
138 */
139 private function looks_like_srcset($value) {
140 if (preg_match('#\s\d*(w|x)#', $value)) {
141 return true;
142 }
143 return false;
144 }
145
146 /**
147 * Handle attribute value based on attribute name, src or srcset
148 *
149 * @param string $value
150 * @return string
151 */
152 private function handle_attribute($value) {
153 if ($this->looks_like_srcset($value)) {
154 return $this->handle_srcset($value);
155 }
156 return $this->handle_src($value);
157 }
158
159 /**
160 * Decide whether given attribute name is an image attribute or not
161 *
162 * @param string $attr_name
163 * @return bool
164 */
165 private function is_image_attribute($attr_name) {
166 return preg_match('#^(src|srcset|poster|(data-[^=]*(lazy|small|slide|img|large|src|thumb|source|set|bg-url)[^=]*))$#i', $attr_name);
167 }
168
169 /**
170 * Does webp image file exists
171 *
172 * @param string $url
173 * @return boolean
174 */
175 private function is_webp_version_available($url) {
176 $filename = WP_Optimize_Utils::get_file_path($url);
177 if (empty($filename)) return false;
178 return file_exists($filename . '.webp');
179 }
180 }
181
182 endif;
183