Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/wp-rocket/inc/Dependencies/RocketLazyload/Image.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
declare(strict_types=1);
3
+
4
+
/**
5
+
* Handles lazyloading of images
6
+
*
7
+
* @package WP_Rocket\Dependencies\RocketLazyload
8
+
*/
9
+
10
+
namespace WP_Rocket\Dependencies\RocketLazyload;
11
+
12
+
/**
13
+
* A class to provide the methods needed to lazyload images in WP Rocket and Lazyload by WP Rocket
14
+
*/
15
+
class Image {
16
+
17
+
/**
18
+
* Finds the images to be lazyloaded and call the callback method to replace them.
19
+
*
20
+
* @param string $html Original HTML.
21
+
* @param string $buffer Content to parse.
22
+
* @param bool $use_native Use native lazyload.
23
+
* @return string
24
+
*/
25
+
public function lazyloadImages( $html, $buffer, $use_native = true ) {
26
+
if ( ! preg_match_all( '#<img(?<atts>\s.+)\s?/?>#iUs', $buffer, $images, PREG_SET_ORDER ) ) {
27
+
return $html;
28
+
}
29
+
30
+
$images = array_unique( $images, SORT_REGULAR );
31
+
32
+
foreach ( $images as $image ) {
33
+
$original_image = $image;
34
+
$image = $this->canLazyload( $image );
35
+
36
+
if ( ! $image ) {
37
+
$image_no_lazy = preg_replace( '/loading=["\']lazy["\']/i', '', $original_image );
38
+
39
+
if ( null === $image_no_lazy ) {
40
+
continue;
41
+
}
42
+
43
+
$html = str_replace( $original_image, $image_no_lazy, $html );
44
+
45
+
continue;
46
+
}
47
+
48
+
$image_lazyload = $this->replaceImage( $image, $use_native );
49
+
50
+
if ( ! $use_native && $this->noscriptEnabled() ) {
51
+
$image_lazyload .= $this->noscript( $image[0] );
52
+
}
53
+
54
+
$html = str_replace( $image[0], $image_lazyload, $html );
55
+
56
+
unset( $image_lazyload );
57
+
}
58
+
59
+
return $html;
60
+
}
61
+
62
+
/**
63
+
* Applies lazyload on background images defined in style attributes
64
+
*
65
+
* @param string $html Original HTML.
66
+
* @param string $buffer Content to parse.
67
+
* @return string
68
+
*/
69
+
public function lazyloadBackgroundImages( $html, $buffer ) {
70
+
if ( ! preg_match_all( '#<(?<tag>div|figure|section|aside|span|li|a)\s+(?<before>[^>]+[\'"\s])?style\s*=\s*([\'"])(?<styles>.*?)\3(?<after>[^>]*)>#is', $buffer, $elements, PREG_SET_ORDER ) ) {
71
+
return $html;
72
+
}
73
+
74
+
foreach ( $elements as $element ) {
75
+
if ( $this->isExcluded( $element['before'] . $element['after'], $this->getExcludedAttributes() ) ) {
76
+
continue;
77
+
}
78
+
79
+
/**
80
+
* Regex to detect bg images inside CSS.
81
+
*
82
+
* @param string $regex regex to detect.
83
+
* @return string
84
+
*/
85
+
$regex = apply_filters( 'rocket_lazyload_bg_images_regex', 'background-image\s*:\s*(?<attr>\s*url\s*\((?<url>[^)]+)\))\s*;?' );
86
+
87
+
if ( @preg_match( "#$regex#is", '' ) === false ) {// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
88
+
$regex = 'background-image\s*:\s*(?<attr>\s*url\s*\((?<url>[^)]+)\))\s*;?';
89
+
}
90
+
91
+
if ( ! preg_match( "#$regex#is", $element['styles'], $url ) ) {
92
+
continue;
93
+
}
94
+
95
+
if ( preg_match( '#data:image#is', $url['url'], $img ) ) {
96
+
continue;
97
+
}
98
+
$url['url'] = esc_url(
99
+
trim(
100
+
wp_strip_all_tags(
101
+
html_entity_decode(
102
+
$url['url'],
103
+
ENT_QUOTES | ENT_HTML5
104
+
)
105
+
),
106
+
'\'" '
107
+
)
108
+
);
109
+
110
+
if ( $this->isExcluded( $url['url'], $this->getExcludedSrc() ) ) {
111
+
continue;
112
+
}
113
+
114
+
$lazy_bg = $this->addLazyCLass( $element[0] );
115
+
$lazy_bg = str_replace( $url[0], '', $lazy_bg );
116
+
$lazy_bg = str_replace( '<' . $element['tag'], '<' . $element['tag'] . ' data-bg="' . esc_attr( $url['url'] ) . '"', $lazy_bg );
117
+
118
+
$html = str_replace( $element[0], $lazy_bg, $html );
119
+
unset( $lazy_bg );
120
+
}
121
+
122
+
return $html;
123
+
}
124
+
125
+
/**
126
+
* Add the identifier class to the element
127
+
*
128
+
* @param string $element Element to add the class to.
129
+
* @return string
130
+
*/
131
+
private function addLazyClass( $element ) {
132
+
$class = $this->getClasses( $element );
133
+
134
+
if ( ! $class ) {
135
+
$result = preg_replace( '#<(img|div|figure|section|aside|li|span|a)([^>]*)>#is', '<\1 class="rocket-lazyload"\2>', $element );
136
+
137
+
if ( ! $result ) {
138
+
return $element;
139
+
}
140
+
141
+
return $result;
142
+
}
143
+
144
+
if ( empty( $class['attribute'] ) || empty( $class['classes'] ) ) {
145
+
return str_replace( $class['attribute'], 'class="rocket-lazyload"', $element );
146
+
}
147
+
148
+
$quotes = $this->getAttributeQuotes( $class['classes'] );
149
+
$classes = $this->trimOuterQuotes( $class['classes'], $quotes );
150
+
151
+
if ( empty( $classes ) ) {
152
+
return str_replace( $class['attribute'], 'class="rocket-lazyload"', $element );
153
+
}
154
+
155
+
$classes .= ' rocket-lazyload';
156
+
157
+
return str_replace(
158
+
$class['attribute'],
159
+
'class=' . $this->normalizeClasses( $classes, $quotes ),
160
+
$element
161
+
);
162
+
}
163
+
164
+
/**
165
+
* Gets the attribute value's outer quotation mark, if one exists, i.e. " or '.
166
+
*
167
+
* @param string $attribute_value The target attribute's value.
168
+
*
169
+
* @return false|string quotation character; else false when no quotation mark.
170
+
*/
171
+
private function getAttributeQuotes( $attribute_value ) {
172
+
$attribute_value = trim( $attribute_value );
173
+
$first_char = $attribute_value[0];
174
+
175
+
if ( '"' === $first_char || "'" === $first_char ) {
176
+
return $first_char;
177
+
}
178
+
179
+
return false;
180
+
}
181
+
182
+
/**
183
+
* Gets the class attribute and values from the given element, if it exists.
184
+
*
185
+
* @param string $element Given HTML element to extract classes from.
186
+
*
187
+
* @return false|string[] {
188
+
* @type string $attribute Class attribute and value, e.g. class="value"
189
+
* @type string $classes String of class attribute's value(s)
190
+
* }; else, false when no class attribute exists.
191
+
*/
192
+
private function getClasses( $element ) {
193
+
if ( ! preg_match( '#class\s*=\s*(?<classes>["\'].*?["\']|[^\s]+)#is', $element, $class ) ) {
194
+
return false;
195
+
}
196
+
197
+
if ( empty( $class['classes'] ) ) {
198
+
return false;
199
+
}
200
+
201
+
return [
202
+
'attribute' => $class[0],
203
+
'classes' => $class['classes'],
204
+
];
205
+
}
206
+
207
+
/**
208
+
* Removes outer single or double quotations.
209
+
*
210
+
* @param string $string String to strip quotes from.
211
+
* @param false|string $quotes The outer quotes to remove.
212
+
*
213
+
* @return string string without quotes.
214
+
*/
215
+
private function trimOuterQuotes( $string, $quotes ) {
216
+
$string = trim( $string );
217
+
218
+
if ( empty( $string ) ) {
219
+
return '';
220
+
}
221
+
222
+
if ( empty( $quotes ) ) {
223
+
return $string;
224
+
}
225
+
226
+
$string = ltrim( $string, $quotes );
227
+
$string = rtrim( $string, $quotes );
228
+
return trim( $string );
229
+
}
230
+
231
+
/**
232
+
* Normalizes the class attribute values to ensure well-formed.
233
+
*
234
+
* @param string $classes String of class attribute value(s).
235
+
* @param string|bool $quotes Optional. Quotation mark to wrap around the classes.
236
+
*
237
+
* @return string well-formed class attributes.
238
+
*/
239
+
private function normalizeClasses( $classes, $quotes = '"' ) {
240
+
$array_of_classes = $this->stringToArray( $classes );
241
+
$classes = implode( ' ', $array_of_classes );
242
+
243
+
if ( false === $quotes ) {
244
+
$quotes = '"';
245
+
}
246
+
247
+
return $quotes . $classes . $quotes;
248
+
}
249
+
250
+
/**
251
+
* Converts the given string into an array of strings.
252
+
*
253
+
* Note:
254
+
* 1. Removes empties.
255
+
* 2. Trims each string.
256
+
*
257
+
* @param string $string The target string to convert.
258
+
* @param non-empty-string $delimiter Optional. Default: ' ' (one space).
259
+
*
260
+
* @return array<string> An array of trimmed strings.
261
+
*/
262
+
private function stringToArray( $string, $delimiter = ' ' ) {
263
+
if ( empty( $string ) ) {
264
+
return [];
265
+
}
266
+
267
+
$array = explode( $delimiter, $string );
268
+
269
+
if ( ! $array ) {
270
+
return [];
271
+
}
272
+
273
+
$array = array_map( 'trim', $array );
274
+
275
+
// Remove empties.
276
+
return array_filter( $array );
277
+
}
278
+
279
+
/**
280
+
* Applies lazyload on picture elements found in the HTML.
281
+
*
282
+
* @param string $html Original HTML.
283
+
* @param string $buffer Content to parse.
284
+
* @return string
285
+
*/
286
+
public function lazyloadPictures( $html, $buffer ) {
287
+
if ( ! preg_match_all( '#<picture(?:.*)?>(?<sources>.*)</picture>#iUs', $buffer, $pictures, PREG_SET_ORDER ) ) {
288
+
return $html;
289
+
}
290
+
291
+
$pictures = array_unique( $pictures, SORT_REGULAR );
292
+
$excluded = array_merge( $this->getExcludedAttributes(), $this->getExcludedSrc() );
293
+
294
+
foreach ( $pictures as $picture ) {
295
+
if ( $this->isExcluded( $picture[0], $excluded ) ) {
296
+
if ( ! preg_match( '#<img(?<atts>\s.+)\s?/?>#iUs', $picture[0], $img ) ) {
297
+
continue;
298
+
}
299
+
300
+
$img = $this->canLazyload( $img );
301
+
302
+
if ( ! $img ) {
303
+
continue;
304
+
}
305
+
306
+
$nolazy_picture = str_replace( '<img', '<img data-no-lazy=""', $picture[0] );
307
+
$html = str_replace( $picture[0], $nolazy_picture, $html );
308
+
309
+
continue;
310
+
}
311
+
312
+
if ( preg_match_all( '#<source(?<atts>\s.+)>#iUs', $picture['sources'], $sources, PREG_SET_ORDER ) ) {
313
+
$lazy_sources = 0;
314
+
$sources = array_unique( $sources, SORT_REGULAR );
315
+
$lazy_picture = $picture[0];
316
+
317
+
foreach ( $sources as $source ) {
318
+
$lazyload_srcset = preg_replace( '/([\s"\'])srcset/i', '\1data-lazy-srcset', $source[0] );
319
+
320
+
if ( ! $lazyload_srcset ) {
321
+
continue;
322
+
}
323
+
324
+
$lazy_picture = str_replace( $source[0], $lazyload_srcset, $lazy_picture );
325
+
326
+
unset( $lazyload_srcset );
327
+
$lazy_sources++;
328
+
}
329
+
330
+
if ( 0 === $lazy_sources ) {
331
+
continue;
332
+
}
333
+
334
+
$html = str_replace( $picture[0], $lazy_picture, $html );
335
+
}
336
+
337
+
if ( ! preg_match( '#<img(?<atts>\s.+)\s?/?>#iUs', $picture[0], $img ) ) {
338
+
continue;
339
+
}
340
+
341
+
$img = $this->canLazyload( $img );
342
+
343
+
if ( ! $img ) {
344
+
continue;
345
+
}
346
+
347
+
$img_lazy = $this->replaceImage( $img, false );
348
+
349
+
if ( $this->noscriptEnabled() ) {
350
+
$img_lazy .= $this->noscript( $img[0] );
351
+
}
352
+
353
+
$safe_img = str_replace( '/', '\/', preg_quote( $img[0], '#' ) );
354
+
355
+
$new_html = preg_replace( '#<noscript[^>]*>.*' . $safe_img . '.*<\/noscript>(*SKIP)(*FAIL)|' . $safe_img . '#i', $img_lazy, $html );
356
+
357
+
if ( ! $new_html ) {
358
+
continue;
359
+
}
360
+
361
+
$html = $new_html;
362
+
363
+
unset( $img_lazy );
364
+
}
365
+
366
+
return $html;
367
+
}
368
+
369
+
/**
370
+
* Checks if the image can be lazyloaded
371
+
*
372
+
* @param array<string> $image Array of image data coming from Regex.
373
+
*
374
+
* @return false|array<string>
375
+
*/
376
+
private function canLazyload( $image ) {
377
+
if ( $this->isExcluded( $image['atts'], $this->getExcludedAttributes() ) ) {
378
+
return false;
379
+
}
380
+
381
+
// Given the previous regex pattern, $image['atts'] starts with a whitespace character.
382
+
if ( ! preg_match( '@\ssrc\s*=\s*(\'|")(?<src>.*)\1@iUs', $image['atts'], $atts ) ) {
383
+
return false;
384
+
}
385
+
386
+
$image['src'] = trim( $atts['src'] );
387
+
388
+
if ( '' === $image['src'] ) {
389
+
return false;
390
+
}
391
+
392
+
if ( $this->isExcluded( $image['src'], $this->getExcludedSrc() ) ) {
393
+
return false;
394
+
}
395
+
396
+
return $image;
397
+
}
398
+
399
+
/**
400
+
* Checks if the provided string matches with the provided excluded patterns
401
+
*
402
+
* @param string $string String to check.
403
+
* @param array<string> $excluded_values Patterns to match against.
404
+
*
405
+
* @return bool
406
+
*/
407
+
public function isExcluded( $string, $excluded_values ) {
408
+
if ( ! is_array( $excluded_values ) ) {
409
+
$excluded_values = (array) $excluded_values;
410
+
}
411
+
412
+
$excluded_values = array_filter( $excluded_values );
413
+
414
+
if ( empty( $excluded_values ) ) {
415
+
return false;
416
+
}
417
+
418
+
foreach ( $excluded_values as $excluded_value ) {
419
+
if ( strpos( $string, $excluded_value ) !== false ) {
420
+
return true;
421
+
}
422
+
}
423
+
424
+
return false;
425
+
}
426
+
427
+
/**
428
+
* Returns the list of excluded attributes
429
+
*
430
+
* @return array<string>
431
+
*/
432
+
public function getExcludedAttributes() {
433
+
/**
434
+
* Filters the attributes used to prevent lazylad from being applied
435
+
*
436
+
* @since 1.0
437
+
*
438
+
* @param array $excluded_attributes An array of excluded attributes.
439
+
*/
440
+
return apply_filters(
441
+
'rocket_lazyload_excluded_attributes',
442
+
[
443
+
'data-src=',
444
+
'data-no-lazy=',
445
+
'data-lazy-original=',
446
+
'data-lazy-src=',
447
+
'data-lazysrc=',
448
+
'data-lazyload=',
449
+
'data-bgposition=',
450
+
'data-envira-src=',
451
+
'fullurl=',
452
+
'lazy-slider-img=',
453
+
'data-srcset=',
454
+
'class="ls-l',
455
+
'class="ls-bg',
456
+
'soliloquy-image',
457
+
'loading="eager"',
458
+
'swatch-img',
459
+
'data-height-percentage',
460
+
'data-large_image',
461
+
'avia-bg-style-fixed',
462
+
'data-skip-lazy',
463
+
'skip-lazy',
464
+
'image-compare__',
465
+
]
466
+
);
467
+
}
468
+
469
+
/**
470
+
* Returns the list of excluded src
471
+
*
472
+
* @return array<string>
473
+
*/
474
+
public function getExcludedSrc() {
475
+
/**
476
+
* Filters the src used to prevent lazylad from being applied
477
+
*
478
+
* @since 1.0
479
+
*
480
+
* @param array $excluded_src An array of excluded src.
481
+
*/
482
+
return apply_filters(
483
+
'rocket_lazyload_excluded_src',
484
+
[
485
+
'/wpcf7_captcha/',
486
+
'timthumb.php?src',
487
+
'woocommerce/assets/images/placeholder.png',
488
+
]
489
+
);
490
+
}
491
+
492
+
/**
493
+
* Replaces the original image by the lazyload one
494
+
*
495
+
* @param array<string> $image Array of matches elements.
496
+
* @param bool $use_native Use native lazyload.
497
+
*
498
+
* @return string
499
+
*/
500
+
private function replaceImage( $image, $use_native = true ) {
501
+
if ( empty( $image ) ) {
502
+
return '';
503
+
}
504
+
505
+
$native_pattern = '@\sloading\s*=\s*(\'|")(?:lazy|auto)\1@i';
506
+
$image_lazyload = $image[0];
507
+
508
+
if ( $use_native ) {
509
+
if ( preg_match( $native_pattern, $image[0] ) ) {
510
+
return $image[0];
511
+
}
512
+
513
+
$image_lazyload = str_replace( '<img', '<img loading="lazy"', $image_lazyload );
514
+
} else {
515
+
$width = 0;
516
+
$height = 0;
517
+
518
+
if ( preg_match( '@[\s"\']width\s*=\s*(\'|")(?<width>.*)\1@iUs', $image['atts'], $atts ) ) {
519
+
$width = absint( $atts['width'] );
520
+
}
521
+
522
+
if ( preg_match( '@[\s"\']height\s*=\s*(\'|")(?<height>.*)\1@iUs', $image['atts'], $atts ) ) {
523
+
$height = absint( $atts['height'] );
524
+
}
525
+
526
+
// Only match src attributes with safe values (no spaces, quotes, or angle brackets).
527
+
$placeholder_atts = preg_replace(
528
+
'@\ssrc\s*=\s*(\'|")(?<src>[^\s"\'>]+)\1@iUs',
529
+
' src="' . $this->getPlaceholder( $width, $height ) . '"',
530
+
$image['atts']
531
+
);
532
+
533
+
$image_lazyload = str_replace(
534
+
$image['atts'],
535
+
$placeholder_atts . ' data-lazy-src="' . esc_url( $image['src'] ) . '"',
536
+
$image_lazyload
537
+
);
538
+
539
+
if ( preg_match( $native_pattern, $image_lazyload ) ) {
540
+
$result = preg_replace( $native_pattern, '', $image_lazyload );
541
+
542
+
if ( is_string( $result ) ) {
543
+
$image_lazyload = $result;
544
+
}
545
+
}
546
+
}
547
+
548
+
/**
549
+
* Filter the LazyLoad HTML output
550
+
*
551
+
* @since 1.0
552
+
*
553
+
* @param string $html Output that will be printed
554
+
*/
555
+
$image_lazyload = apply_filters( 'rocket_lazyload_html', $image_lazyload );
556
+
557
+
return $image_lazyload;
558
+
}
559
+
560
+
/**
561
+
* Checks if the noscript tag is enabled
562
+
*
563
+
* @return mixed
564
+
*/
565
+
private function noscriptEnabled() {
566
+
/**
567
+
* Filter to enable or disable noscript tag
568
+
*
569
+
* @param bool $enable_noscript Enable or disable noscript tag.
570
+
*/
571
+
return wpm_apply_filters_typed( 'boolean', 'rocket_lazyload_noscript', true );
572
+
}
573
+
574
+
/**
575
+
* Returns the HTML tag wrapped inside noscript tags
576
+
*
577
+
* @param string $element Element to wrap.
578
+
* @return string
579
+
*/
580
+
private function noscript( $element ) {
581
+
return '<noscript>' . $element . '</noscript>';
582
+
}
583
+
584
+
/**
585
+
* Applies lazyload on srcset and sizes attributes
586
+
*
587
+
* @param string $html HTML image tag.
588
+
* @return string
589
+
*/
590
+
public function lazyloadResponsiveAttributes( $html ) {
591
+
$data_srcset = preg_replace( '/[\s|"|\'](srcset)\s*=\s*("|\')([^"|\']+)\2/i', ' data-lazy-$1=$2$3$2', $html );
592
+
593
+
if ( ! $data_srcset ) {
594
+
return $html;
595
+
}
596
+
597
+
$html = $data_srcset;
598
+
599
+
$lazy_responsive = preg_replace( '/[\s|"|\'](sizes)\s*=\s*("|\')([^"|\']+)\2/i', ' data-lazy-$1=$2$3$2', $html );
600
+
601
+
if ( ! $lazy_responsive ) {
602
+
return $html;
603
+
}
604
+
605
+
return $lazy_responsive;
606
+
}
607
+
608
+
/**
609
+
* Finds patterns matching smiley and call the callback method to replace them with the image
610
+
*
611
+
* @param string $text Content to search in.
612
+
* @return string
613
+
*/
614
+
public function convertSmilies( $text ) {
615
+
global $wp_smiliessearch;
616
+
617
+
if ( empty( $text ) || ! is_string( $text ) ) {
618
+
return $text;
619
+
}
620
+
621
+
if ( ! get_option( 'use_smilies' ) || empty( $wp_smiliessearch ) ) {
622
+
return $text;
623
+
}
624
+
625
+
$output = '';
626
+
// HTML loop taken from texturize function, could possible be consolidated.
627
+
$textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between.
628
+
629
+
if ( ! $textarr ) {
630
+
return $text;
631
+
}
632
+
633
+
$stop = count( $textarr );// loop stuff.
634
+
635
+
// Ignore processing of specific tags.
636
+
$tags_to_ignore = 'code|pre|style|script|textarea';
637
+
$ignore_block_element = '';
638
+
639
+
for ( $i = 0; $i < $stop; $i++ ) {
640
+
$content = $textarr[ $i ];
641
+
642
+
// If we're in an ignore block, wait until we find its closing tag.
643
+
if ( '' === $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) {
644
+
$ignore_block_element = $matches[1];
645
+
}
646
+
647
+
// If it's not a tag and not in ignore block.
648
+
if ( '' === $ignore_block_element && strlen( $content ) > 0 && '<' !== $content[0] ) {
649
+
$content = preg_replace_callback( $wp_smiliessearch, [ $this, 'translateSmiley' ], $content );
650
+
}
651
+
652
+
// did we exit ignore block.
653
+
if ( '' !== $ignore_block_element && '</' . $ignore_block_element . '>' === $content ) {
654
+
$ignore_block_element = '';
655
+
}
656
+
657
+
$output .= $content;
658
+
}
659
+
660
+
return $output;
661
+
}
662
+
663
+
/**
664
+
* Replace matches by smiley image, lazyloaded
665
+
*
666
+
* @param array<string> $matches Array of matches.
667
+
*
668
+
* @return string
669
+
*/
670
+
private function translateSmiley( $matches ) {
671
+
global $wpsmiliestrans;
672
+
673
+
if ( count( $matches ) === 0 ) {
674
+
return '';
675
+
}
676
+
677
+
$smiley = trim( reset( $matches ) );
678
+
$img = $wpsmiliestrans[ $smiley ];
679
+
680
+
$matches = [];
681
+
$ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false;
682
+
$image_exts = [ 'jpg', 'jpeg', 'jpe', 'gif', 'png' ];
683
+
684
+
// Don't convert smilies that aren't images - they're probably emoji.
685
+
if ( ! in_array( $ext, $image_exts, true ) ) {
686
+
return $img;
687
+
}
688
+
689
+
/**
690
+
* Filter the Smiley image URL before it's used in the image element.
691
+
*
692
+
* @since 2.9.0
693
+
*
694
+
* @param string $smiley_url URL for the smiley image.
695
+
* @param string $img Filename for the smiley image.
696
+
* @param string $site_url Site URL, as returned by site_url().
697
+
*/
698
+
$src_url = apply_filters( 'smilies_src', includes_url( "images/smilies/$img" ), $img, site_url() ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
699
+
700
+
// Don't LazyLoad if process is stopped for these reasons.
701
+
if ( is_feed() || is_preview() ) {
702
+
return sprintf( ' <img src="%s" alt="%s" class="wp-smiley" /> ', esc_url( $src_url ), esc_attr( $smiley ) );
703
+
}
704
+
705
+
return sprintf( ' <img src="%s" data-lazy-src="%s" alt="%s" class="wp-smiley" /> ', $this->getPlaceholder(), esc_url( $src_url ), esc_attr( $smiley ) );
706
+
}
707
+
708
+
/**
709
+
* Returns the placeholder for the src attribute
710
+
*
711
+
* @since 1.2
712
+
*
713
+
* @param int $width Width of the placeholder image. Default 0.
714
+
* @param int $height Height of the placeholder image. Default 0.
715
+
* @return string
716
+
*/
717
+
public function getPlaceholder( $width = 0, $height = 0 ) {
718
+
$width = 0 === $width ? 0 : absint( $width );
719
+
$height = 0 === $height ? 0 : absint( $height );
720
+
721
+
$placeholder = str_replace( ' ', '%20', "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 $width $height'%3E%3C/svg%3E" );
722
+
/**
723
+
* Filter the image lazyLoad placeholder on src attribute
724
+
*
725
+
* @since 1.1
726
+
*
727
+
* @param string $placeholder Placeholder that will be printed.
728
+
* @param int $width Placeholder width.
729
+
* @param int $height Placeholder height.
730
+
*/
731
+
return apply_filters( 'rocket_lazyload_placeholder', $placeholder, $width, $height );
732
+
}
733
+
}
734
+