PluginProbe ʕ •ᴥ•ʔ
Aruba HiSpeed Cache / 3.0.15
Aruba HiSpeed Cache v3.0.15
3.0.15 3.0.14 3.0.13 1.2.4 1.2.5 1.2.6 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.17 2.0.18 2.0.19 2.0.20 2.0.21 2.0.22 2.0.23 2.0.24 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0.0 3.0.1 3.0.10 3.0.11 3.0.12 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3
aruba-hispeed-cache / src / AHSC_Lazyload.php
aruba-hispeed-cache / src Last commit date
APC 3 days ago Events 3 days ago Purger 3 days ago assets 3 days ago AHSC_Apc.php 3 days ago AHSC_Check.php 3 days ago AHSC_Config.php 3 days ago AHSC_Dboptimization.php 3 days ago AHSC_Functions.php 3 days ago AHSC_HtmlOptimizer.php 5 months ago AHSC_Lazyload.php 3 days ago AHSC_Preconnect.php 5 months ago AHSC_Static.php 4 months ago AHSC_Version.php 5 months ago AHSC_Warmer.php 3 days ago AHSC_XmlRPC.php 5 months ago index.php 5 months ago
AHSC_Lazyload.php
282 lines
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 if ( isset( AHSC_CONSTANT['ARUBA_HISPEED_CACHE_OPTIONS']['ahsc_lazy_load'] ) &&
7 AHSC_CONSTANT['ARUBA_HISPEED_CACHE_OPTIONS']['ahsc_lazy_load'] ) {
8 add_action( 'template_redirect', 'ahsc_wp_lazy_loading_initialize_filters', 10 );
9 add_action( 'template_redirect', 'ahsc_control_lazyload_param',11);
10
11 }
12
13 function ahsc_wp_lazy_loading_initialize_filters() {
14 if(!is_admin()) {
15 if(!is_customize_preview()) {
16 foreach (
17 array(
18 'the_content',
19 'the_excerpt',
20 'widget_text_content',
21 'do_shortcode_tag',
22 'render_block',
23 'post_thumbnail_html'
24 ) as $filter
25 ) {
26 add_filter( $filter, 'ahsc_wp_filter_content_tags' );
27 //add_filter( $filter, 'ahsc_add_image_dimensions' );
28 }
29 add_filter( 'wp_get_attachment_image_attributes', 'ahsc_wp_lazy_loading_add_attribute_to_attachment_image' );
30 add_filter( 'get_avatar', 'ahsc_wp_lazy_loading_add_attribute_to_avatar' );
31 }
32 }
33 }
34
35 function ahsc_wp_lazy_loading_add_attribute_to_avatar( $avatar ) {
36 if ( ahsc_wp_lazy_loading_enabled( 'img', 'get_avatar' ) && false === strpos( $avatar, ' loading=' ) ) {
37 // Only the first occurrence: `<img ` can also appear inside an attribute
38 // value, where inserting attributes would break out of that value.
39 $avatar = preg_replace( '/<img\s/i', '<img decoding="async" loading="lazy" ', $avatar, 1 );
40 }
41
42 return $avatar;
43 }
44
45 function ahsc_wp_lazy_loading_add_attribute_to_attachment_image( $attr ) {
46 if ( ahsc_wp_lazy_loading_enabled( 'img', 'wp_get_attachment_image' ) && ! isset( $attr['loading'] ) ) {
47 $attr['loading'] = 'lazy';
48 $attr['decoding'] = 'async';
49 }
50 return $attr;
51 }
52
53 function ahsc_wp_lazy_loading_enabled( $tag_name, $context ) {
54 $default = ( 'img' === $tag_name );
55 //@phpcs:ignore
56 return (bool) apply_filters( 'wp_lazy_loading_enabled', $default, $tag_name, $context );
57 }
58
59 function ahsc_wp_filter_content_tags( $content, $context = null ) {
60 if ( null === $context ) {
61 $context = current_filter();
62 }
63 //$add_loading_attr = ahsc_wp_lazy_loading_enabled( 'img', $context );
64
65 if ( false === strpos( $content, '<img' ) ) {
66 return $content;
67 }
68
69 if ( ! preg_match_all( '/<img\s[^>]+>/', $content, $matches ) ) {
70 return $content;
71 }
72
73 $images = array();
74
75 foreach ( $matches[0] as $image ) {
76 if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) {
77 $attachment_id = absint( $class_id[1] );
78
79 if ( $attachment_id ) {
80 $images[ $image ] = $attachment_id;
81 continue;
82 }
83 }/*elseif ( preg_match( '/< *img[^>]*src *= *["\']?([^"\']*)/i', $image, $class_id ) ){
84 $images[ $image ] = attachment_url_to_postid($class_id[1]);
85
86 }*/else {
87 $images[ $image ] = 0;
88 }
89 }
90
91 $attachment_ids = array_unique( array_filter( array_values( $images ) ) );
92 if ( count( $attachment_ids ) > 1 ) {
93 _prime_post_caches( $attachment_ids, false, true );
94 }
95
96
97 foreach ( $images as $image => $attachment_id ) {
98 $filtered_image = $image;
99
100 if ( $attachment_id >= 0 && false === strpos( $filtered_image, ' srcset=' ) ) {
101 $filtered_image = ahsc_wp_img_tag_add_srcset_and_sizes_attr( $filtered_image, $context, $attachment_id );
102 }
103 if ( false === strpos( $filtered_image, ' loading=' ) ) {
104 $filtered_image = ahsc_wp_img_tag_add_loading_attr( $filtered_image, $context );
105 }
106
107 if ( $filtered_image !== $image ) {
108 $content = str_replace( $image, $filtered_image, $content );
109 }
110 }
111 return $content;
112 }
113
114 function ahsc_wp_img_tag_add_loading_attr( $image, $context ) {
115 //@phpcs:ignore
116 $value = apply_filters( 'wp_img_tag_add_loading_attr', 'lazy', $image, $context );
117
118 if ( $value ) {
119 if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) {
120 $value = 'lazy';
121 }
122 // Insert at the start of the tag only: a literal `<img` can also occur
123 // inside an attribute value, where inserting would break out of it.
124 if ( 0 !== stripos( $image, '<img' ) ) {
125 return $image;
126 }
127
128 return substr_replace( $image, '<img decoding="async" loading="' . $value . '"', 0, 4 );
129 }
130
131 return $image;
132 }
133
134 function ahsc_wp_img_tag_add_srcset_and_sizes_attr( $image, $context, $attachment_id ) {
135 //@phpcs:ignore
136 $add = apply_filters( 'wp_img_tag_add_srcset_and_sizes_attr', true, $image, $context, $attachment_id );
137
138 if ( true === $add ) {
139 $image_meta = wp_get_attachment_metadata( $attachment_id ,true);
140 return wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id );
141 }
142
143 return $image;
144 }
145
146 function ahsc_add_image_dimensions( $content ) {
147
148 preg_match_all( '/<img[^>]+>/i', $content, $images);
149
150 if (count($images) < 1)
151 return $content;
152
153 foreach ($images[0] as $image) {
154 preg_match_all( '/(alt|title|src|width|class|id|height|style)=("[^"]*")/i', $image, $img );
155
156 if ( !in_array( 'src', $img[1] ) )
157 continue;
158
159 if ( !in_array( 'width', $img[1] ) || !in_array( 'height', $img[1] ) ) {
160 $src = $img[2][ array_search('src', $img[1]) ];
161 $alt = in_array( 'alt', $img[1] ) ? ' alt=' . $img[2][ array_search('alt', $img[1]) ] : '';
162 $title = in_array( 'title', $img[1] ) ? ' title=' . $img[2][ array_search('title', $img[1]) ] : '';
163 $class = in_array( 'class', $img[1] ) ? ' class=' . $img[2][ array_search('class', $img[1]) ] : '';
164 $id = in_array( 'id', $img[1] ) ? ' id=' . $img[2][ array_search('id', $img[1]) ] : '';
165 $style = in_array( 'style', $img[1] ) ? ' style=' . $img[2][ array_search('style', $img[1]) ] : '';
166 list( $width, $height, $type, $attr ) = getimagesize( str_replace( "\"", "" , $src ) );
167
168 $image_tag = sprintf( '<img src=%s%s%s%s%s%s width="%d" height="%d" />', $src, $alt, $title, $class, $id,$style, $width, $height );
169 $content = str_replace($image, $image_tag, $content);
170 }
171 }
172
173 return $content;
174 }
175 /**
176 * Splits an img tag into its ordered list of attributes.
177 *
178 * Attributes must never be rewritten with plain string or non-greedy regex
179 * replacements: a `loading=` sequence sitting inside another attribute value is
180 * indistinguishable from a real attribute, so removing or inserting text at that
181 * position splices the tag and can turn harmless markup into an event handler.
182 * This walks the tag from its start, so every offset it acts on is known to be
183 * an attribute boundary, and gives up on anything it cannot read with certainty
184 * so that callers can leave such tags untouched.
185 *
186 * @param string $tag A single tag, from `<img` up to and including its `>`.
187 *
188 * @return array|false Array with the `attributes` and `self_closing` keys, or
189 * false when the tag cannot be parsed safely.
190 */
191 function ahsc_parse_img_tag( $tag ) {
192 if ( ! preg_match( '#^<img\b#i', $tag ) ) {
193 return false;
194 }
195
196 $attributes = array();
197 $offset = 4;
198 $length = strlen( $tag );
199
200 while ( $offset < $length ) {
201 // Whitespace separating attributes.
202 if ( preg_match( '/\s+/A', $tag, $whitespace, 0, $offset ) ) {
203 $offset += strlen( $whitespace[0] );
204 }
205
206 // End of the tag, which is always the end of the matched string.
207 if ( preg_match( '/\/?>\z/A', $tag, $end, 0, $offset ) ) {
208 return array(
209 'attributes' => $attributes,
210 'self_closing' => ( '/>' === $end[0] ),
211 );
212 }
213
214 // An attribute name, followed by an optional quoted or unquoted value.
215 if ( ! preg_match( '/([^\s\/>="\']+)(?:\s*=\s*("[^"]*"|\'[^\']*\'|[^\s>]*))?/A', $tag, $attribute, 0, $offset ) ) {
216 return false;
217 }
218
219 $attributes[] = array(
220 'name' => strtolower( $attribute[1] ),
221 'source' => $attribute[0],
222 );
223 $offset += strlen( $attribute[0] );
224 }
225
226 return false;
227 }
228
229 function ahsc_control_lazyload_param($buffer){
230 if(!is_admin()) {
231 if(!is_customize_preview()){
232 ob_start( function ( $buffer ) {
233 preg_match_all( '#<(script|style|noscript|template)\b[^>]*>.*?</\1>|<img\b[^>]*>#is', $buffer, $allImgs );
234 $total = count( $allImgs[0] ) - 1;
235 $limit = intval( $total / 3 );
236 $control = min( 9, $limit );
237 $count = 0;
238
239 return preg_replace_callback(
240 '#<(script|style|noscript|template)\b[^>]*>.*?</\1>|<img\b[^>]*>#is',
241 function ( $matches ) use ( &$count, $control ) {
242
243 if ( $count >= $control ) {
244 return $matches[0];
245 }
246
247 $parsed = ahsc_parse_img_tag( $matches[0] );
248
249 // Skipped elements and anything unparsable are left alone.
250 if ( false === $parsed ) {
251 return $matches[0];
252 }
253
254 $attributes = array();
255 $has_fetchpriority = false;
256
257 foreach ( $parsed['attributes'] as $attribute ) {
258 if ( 'loading' === $attribute['name'] || 'decoding' === $attribute['name'] ) {
259 continue;
260 }
261 if ( 'fetchpriority' === $attribute['name'] ) {
262 $has_fetchpriority = true;
263 }
264 // Re-emitted verbatim, so no quoting decisions are made here.
265 $attributes[] = $attribute['source'];
266 }
267
268 if ( ! $has_fetchpriority ) {
269 array_unshift( $attributes, 'fetchpriority=\'high\'' );
270 }
271
272 $count ++;
273
274 return '<img' . ( $attributes ? ' ' . implode( ' ', $attributes ) : '' ) .
275 ( $parsed['self_closing'] ? ' /' : '' ) . '>';
276 },
277 $buffer
278 );
279 } );
280 }
281 }
282 }