| 1 |
<?php |
| 2 |
|
| 3 |
namespace Yatra\Compatibility\LiteSpeed; |
| 4 |
|
| 5 |
if ( ! defined( 'ABSPATH' ) ) { |
| 6 |
exit; |
| 7 |
} |
| 8 |
|
| 9 |
/** |
| 10 |
* LiteSpeed Cache compatibility for Yatra gallery images. |
| 11 |
* |
| 12 |
* LiteSpeed Cache (and similar caching/optimisation plugins) replace an |
| 13 |
* <img src="real.jpg"> with <img src="data:image/gif;base64,..." data-src="real.jpg"> |
| 14 |
* as part of their lazy-load feature. Yatra's gallery modal JavaScript reads |
| 15 |
* image URLs directly from the DOM, so it ends up with the placeholder instead |
| 16 |
* of the real URL. |
| 17 |
* |
| 18 |
* Three-layer defence: |
| 19 |
* 1. PHP templates add `data-yatra-src` (our own attribute, never altered by |
| 20 |
* third-party plugins) and `data-no-lazy="1"` (LiteSpeed's own opt-out). |
| 21 |
* 2. This class hooks into LiteSpeed's filters to exclude Yatra gallery |
| 22 |
* selectors from the lazy-loader entirely. |
| 23 |
* 3. trip.js uses `getImageSrc()` which reads `data-yatra-src` first before |
| 24 |
* falling back to common lazy-load attributes and finally `img.src`. |
| 25 |
*/ |
| 26 |
final class Assets { |
| 27 |
|
| 28 |
/** @var bool Guard against double-registration. */ |
| 29 |
private static bool $registered = false; |
| 30 |
|
| 31 |
public static function register(): void { |
| 32 |
if ( self::$registered ) { |
| 33 |
return; |
| 34 |
} |
| 35 |
self::$registered = true; |
| 36 |
|
| 37 |
// Only wire up hooks if LiteSpeed Cache is active. |
| 38 |
if ( ! self::isActive() ) { |
| 39 |
return; |
| 40 |
} |
| 41 |
|
| 42 |
// Exclude Yatra gallery images from LiteSpeed lazy-loading. |
| 43 |
add_filter( 'litespeed_lazyload_excludes', [ self::class, 'excludeImages' ] ); |
| 44 |
|
| 45 |
// Exclude Yatra's trip.js from JS deferral / combination so the |
| 46 |
// gallery modal initialises at the correct time. |
| 47 |
add_filter( 'litespeed_optm_js_defer_excludes', [ self::class, 'excludeJs' ] ); |
| 48 |
add_filter( 'litespeed_optm_ccss_sep_posttype', [ self::class, 'excludeJs' ] ); // belt-and-suspenders |
| 49 |
|
| 50 |
// Prevent CSS combination for Yatra trip stylesheet so its selectors |
| 51 |
// remain intact (some LiteSpeed versions rewrite url() paths). |
| 52 |
add_filter( 'litespeed_optm_css_excludes', [ self::class, 'excludeCss' ] ); |
| 53 |
} |
| 54 |
|
| 55 |
// ------------------------------------------------------------------------- |
| 56 |
// Filter callbacks |
| 57 |
// ------------------------------------------------------------------------- |
| 58 |
|
| 59 |
/** |
| 60 |
* Exclude Yatra gallery image selectors from LiteSpeed lazy-loading. |
| 61 |
* |
| 62 |
* @param array<string> $excludes CSS selectors / URL patterns to exclude. |
| 63 |
* @return array<string> |
| 64 |
*/ |
| 65 |
public static function excludeImages( array $excludes ): array { |
| 66 |
$excludes[] = '.yatra-hero-main-img'; |
| 67 |
$excludes[] = '.yatra-trip-hero-slide img'; |
| 68 |
$excludes[] = '.yatra-gallery-item img'; |
| 69 |
$excludes[] = '.yatra-side-image-item img'; |
| 70 |
$excludes[] = '.yatra-gallery-modal-image'; |
| 71 |
$excludes[] = '.yatra-gallery-thumbnail img'; |
| 72 |
return $excludes; |
| 73 |
} |
| 74 |
|
| 75 |
/** |
| 76 |
* Exclude Yatra's trip.js from JS defer / combination. |
| 77 |
* |
| 78 |
* @param array<string> $excludes URL patterns. |
| 79 |
* @return array<string> |
| 80 |
*/ |
| 81 |
public static function excludeJs( array $excludes ): array { |
| 82 |
$excludes[] = 'yatra/assets/js/trip'; |
| 83 |
return $excludes; |
| 84 |
} |
| 85 |
|
| 86 |
/** |
| 87 |
* Exclude Yatra's trip.css from CSS combination. |
| 88 |
* |
| 89 |
* @param array<string> $excludes URL patterns. |
| 90 |
* @return array<string> |
| 91 |
*/ |
| 92 |
public static function excludeCss( array $excludes ): array { |
| 93 |
$excludes[] = 'yatra/assets/css/trip'; |
| 94 |
return $excludes; |
| 95 |
} |
| 96 |
|
| 97 |
// ------------------------------------------------------------------------- |
| 98 |
// Detection |
| 99 |
// ------------------------------------------------------------------------- |
| 100 |
|
| 101 |
/** |
| 102 |
* Check whether LiteSpeed Cache is active. |
| 103 |
* Supports both the free plugin and LiteSpeed's enterprise build. |
| 104 |
*/ |
| 105 |
private static function isActive(): bool { |
| 106 |
return defined( 'LSCWP_V' ) |
| 107 |
|| class_exists( '\\LiteSpeed\\Core', false ) |
| 108 |
|| class_exists( '\\LiteSpeed_Cache', false ) |
| 109 |
|| function_exists( 'litespeed_purge_all' ); |
| 110 |
} |
| 111 |
} |
| 112 |
|