Server IP : 104.21.93.192 / Your IP : 216.73.216.73 Web Server : LiteSpeed System : Linux premium900.web-hosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 User : redwjova ( 1790) PHP Version : 8.1.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/redwjova/clevorio.com/wp-content/themes/smart-mag/inc/ |
Upload File : |
<?php /** * Lazyload images for speed */ class Bunyad_Theme_Lazyload { public $image_sizes; public $svg_cache; /** * Flag to enable/disable images that follow in queue */ public $disabled = false; public $prev_state = false; public function __construct() { if (is_admin()) { return; } // Bunyad::options() isn't initialized yet, wait for it add_action('after_setup_theme', [$this, 'init']); // Process image attribs. add_filter('bunyad_media_image_options', [$this, 'process_media'], 10, 2); } public function process_media($args, $size) { if (!empty($args['no_lazy'])) { $args['attr']['loading'] = ''; $args['attr']['class'] = "attachment-$size size-$size no-lazy skip-lazy"; } return $args; } /** * All core ready - initialize */ public function init() { if (!Bunyad::options()->lazyload_enabled) { return; } // Add attributes for the normal img tags, masonry, some sliders, or legacy. add_filter('wp_get_attachment_image_attributes', [$this, 'image_attribs'], 10, 3); // Add attributes to the new background images. add_filter('bunyad_media_bg_image_attribs', [$this, 'bg_image_attribs']); /** * Elementor image widget mess up by stripping data: attribute. */ add_action('elementor/widget/before_render_content', function($widget) { if (!is_object($widget) || !is_callable([$widget, 'get_name']) || $widget->get_name() !== 'image') { return; } $this->disable(); }); add_filter('elementor/widget/render_content', function($content, $widget) { if (!is_object($widget) || !is_callable([$widget, 'get_name']) || $widget->get_name() !== 'image') { return $content; } $this->enable(); return $this->process_content($content); }, 10, 2); /** * Aggressive lazyload for sidebar and footer. */ if (Bunyad::options()->lazyload_aggressive) { // WPBakery conflicts in preview with footer buffer and widgets won't update. // vc_is_page_editable() isn't reliable at this point. if (!empty($_GET['vc_editable'])) { return; } add_action('dynamic_sidebar_before', [$this, 'start_buffer'], 10); add_action('dynamic_sidebar_after', 'ob_end_flush', 10, 0); add_action('bunyad_pre_footer', [$this, 'start_buffer'], 10); add_action('wp_footer', 'ob_end_flush', 2, 0); } // Enable bg images for thumbnails in lazyload, where possible. add_filter('bunyad_media_image_options', function($options) { if ($this->should_lazy() && $options['bg_image'] === null) { $options['bg_image'] = 'auto'; } return $options; }); // Cache image sizes - used by image_attribs() $this->image_sizes = $this->get_registered_sizes(); // Earliest in foot. We don't want it to be a blocking asset in header. add_action('wp_enqueue_scripts', [$this, 'register_assets'], 1); } /** * Setup the JS file - earlier in header. */ public function register_assets() { wp_register_script('smartmag-lazy-inline', '', [], BUNYAD_THEME_VERSION); wp_enqueue_script('smartmag-lazy-inline'); wp_add_inline_script( 'smartmag-lazy-inline', file_get_contents(get_template_directory() . '/js/lazy-inline.js') ); wp_enqueue_script( 'smartmag-lazyload', get_template_directory_uri() . '/js/lazyload.js', [], BUNYAD_THEME_VERSION, true ); wp_localize_script('smartmag-lazyload', 'BunyadLazyConf', [ 'type' => Bunyad::options()->lazyload_type ]); } /** * Disable lazy flags addition on images that follow */ public function disable() { $this->prev_state = $this->disabled; $this->disabled = true; return $this; } /** * Re-enable lazy load (enabled by default) */ public function enable() { $this->prev_state = $this->disabled; $this->disabled = false; return $this; } /** * Restore to previous state (as set by enable()/disable()) */ public function restore() { $this->disabled = $this->prev_state; return $this; } /** * Start capturing content to filter later */ public function start_buffer() { // Capture sidebar input ob_start([$this, 'process_content']); } /** * Process Raw HTML to find and replace images */ public function process_content($content = '', $type = '') { if (!$this->should_lazy()) { return $content; } preg_match_all('#<(img|iframe)[^>]*>#is', $content, $matches); $elements = $matches[0]; foreach ($elements as $key => $element) { $updated = ''; $tag = $matches[1][$key]; // Parse the tag attributes. // @todo More testing on regex OR use wp_kses_hair() preg_match_all('#(?P<name>[a-z\-]+)=("|\')(?P<value>.*?)\2#is', $element, $match); if (empty($match['name'])) { continue; } $attr = array_combine((array) $match['name'], (array) $match['value']); // @todo Include more skips when doing more aggressive lazyload in future. if (!$this->should_lazy_image($attr)) { continue; } // Native lazyload has to be handled differently. if ($type == 'native') { // Skip if an existing loading is defined - which maybe eager. if (isset($attr['loading'])) { continue; } $attr['loading'] = 'lazy'; } else { // Extend some defaults $attr = array_merge([ 'class' => '' ], $attr); // Add class $attr['class'] .= ' lazyload'; $width = (!empty($attr['width']) ? $attr['width'] : 1); $height = (!empty($attr['height']) ? $attr['height'] : 1); // Generate src $attr['data-src'] = $attr['src']; $attr['src'] = $this->svg_placeholder($width, $height); // Set srcset if exists if (!empty($attr['data-srcset'])) { $attr['data-srcset'] = $attr['srcset']; unset($attr['srcset']); } } $updated = '<' . esc_attr($tag) . ' ' . Bunyad::markup()->attribs('lazy', $attr, ['esc_src_url' => 0, 'echo' => 0]) . ($tag == 'img' ? ' />' : '>'); $content = str_replace($element, $updated, $content); } return $content; } /** * Check if lazy load should be applied */ public function should_lazy() { if ($this->disabled || is_feed() || is_preview() || is_admin() || is_embed()) { return false; } // Disable for all REST requests. We don't use REST api but AJAX instead for blocks, so it's alright. // Note: This only works after 'init' action but it's fine here. if (defined('REST_REQUEST') && REST_REQUEST) { return false; } // WPBakery page builder loads shortcode this way. // vc_is_page_editable() isn't reliable at this point. if (!empty($_GET['vc_editable'])) { return false; } if (function_exists('amp_is_request') && amp_is_request()) { return false; } // WooCommerce image zoom is bugged if (function_exists('is_product') && is_product()) { return false; } // WP Recipe Maker print. if (did_action('wprm_print_output') || doing_action('wprm_print_output')) { return false; } // Filter that can disable lazyload by returning false if (!apply_filters('bunyad_lazyload_enabled', true)) { return false; } return true; } /** * Skip adding lazyload if meets certain conditions, given the attributes of an image. * * @param array $attrs * @return boolean */ public function should_lazy_image($attrs) { if (empty($attrs) || !is_array($attrs)) { return true; } if (isset($attrs['class'])) { $skip_classes = [ // Already lazyloaded. 'lazyload', // Manual skip like wprocket. 'no-lazy', // Autoptimize compat and others. 'skip-lazy' ]; $classes = array_map('trim', explode(' ', $attrs['class'])); if (array_intersect($skip_classes, $classes)) { return false; } } return true; } /** * Add image attributes * * @see wp_get_attachment_image() * @param string $size */ public function image_attribs($attr, $attachment, $size) { if (!$this->should_lazy() || !$this->should_lazy_image($attr)) { return $attr; } /** * Get width and height */ $width = 1; $height = 1; $attachment = wp_get_attachment_metadata($attachment->ID); if (is_string($size)) { // From attachment metadata first - fallback to global setting next if (!empty($attachment['sizes']) && array_key_exists($size, $attachment['sizes'])) { $info = $attachment['sizes'][$size]; } else if (array_key_exists($size, $this->image_sizes)) { $info = $this->image_sizes[$size]; } if (!empty($info)) { $width = $info['width']; $height = $info['height']; } } // Have srcset? if (!empty($attr['srcset'])) { $attr['data-srcset'] = $attr['srcset']; unset($attr['srcset']); } // Add placeholder and move orig to data-src $attr['data-src'] = $attr['src']; $attr['src'] = esc_attr($this->svg_placeholder($width, $height)); $attr['class'] .= ' lazyload'; return $attr; } /** * Filter callback: Add the lazyload class to bg images. * * Filter: bunyad_media_bg_image_attribs */ public function bg_image_attribs($attrs) { if (!$this->should_lazy() || !$this->should_lazy_image($attrs)) { return $attrs; } // Add lazy load class. $attrs['class'] = !isset($attrs['class']) ? '' : $attrs['class']; $attrs['class'] .= ' lazyload'; return $attrs; } /** * Create an SVG placeholder for data URI * * @param integer $width * @param integer $height * @return string Data URI format svg * */ public function svg_placeholder($width = 1, $height = 1) { $id = "{$width}x{$height}"; if (!empty($this->svg_cache[$id])) { return $this->svg_cache[$id]; } $svg = "<svg viewBox='0 0 {$width} {$height}' xmlns='http://www.w3.org/2000/svg'></svg>"; $svg = base64_encode($svg); return ($this->svg_cache[$id] = 'data:image/svg+xml;base64,' . $svg); } /** * Get all registered image sizes, including default ones * * @link http://core.trac.wordpress.org/ticket/18947 Reference ticket */ public function get_registered_sizes() { global $_wp_additional_image_sizes; $default_sizes = ['thumbnail', 'medium', 'medium_large', 'large']; foreach ($default_sizes as $size) { $image_sizes[$size]['width'] = intval(get_option("{$size}_size_w")); $image_sizes[$size]['height'] = intval(get_option("{$size}_size_h")); $image_sizes[$size]['crop'] = get_option("{$size}_crop") ? get_option("{$size}_crop") : false; } if (!empty($_wp_additional_image_sizes)) { $image_sizes = array_merge($image_sizes, $_wp_additional_image_sizes); } return $image_sizes; } } // init and make available in Bunyad::get('lazyload') Bunyad::register('lazyload', [ 'class' => 'Bunyad_Theme_Lazyload', 'init' => true ]);