// ============================================ // IMAGE SEO CLASS (FIXED) // ============================================ if (!class_exists('TimesBull_Image_SEO')) { class TimesBull_Image_SEO { private static $instance = null; private $image_count = 0; private $featured_image_id = null; public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function __construct() { add_filter('wp_get_attachment_image_attributes', [$this, 'add_image_attributes'], 10, 3); add_filter('the_content', [$this, 'auto_add_image_alt']); add_action('add_attachment', [$this, 'auto_image_seo']); add_action('wp', [$this, 'set_featured_image_id']); } public function set_featured_image_id() { if (is_singular()) { $this->featured_image_id = get_post_thumbnail_id(); } } public function add_image_attributes($attr, $attachment, $size) { $this->image_count++; // CRITICAL FIX: Check if this is the featured image $is_featured = ($attachment->ID === $this->featured_image_id); if ($is_featured) { // Featured image - ALWAYS eager, ALWAYS high priority $attr['loading'] = 'eager'; $attr['fetchpriority'] = 'high'; $attr['decoding'] = 'async'; } elseif ($this->image_count === 1 && !is_admin()) { // First non-featured image (e.g., logo) $attr['loading'] = 'eager'; $attr['fetchpriority'] = 'high'; $attr['decoding'] = 'async'; } else { // All other images - lazy load for performance $attr['loading'] = 'lazy'; $attr['decoding'] = 'async'; // Remove fetchpriority from lazy images (prevents conflict) if (isset($attr['fetchpriority'])) { unset($attr['fetchpriority']); } } // Ensure alt text is never empty if (empty($attr['alt'])) { $alt_text = get_post_meta($attachment->ID, '_wp_attachment_image_alt', true); $attr['alt'] = $alt_text ?: get_the_title($attachment->ID); } return $attr; } public function auto_add_image_alt($content) { if (empty($content) || !is_singular() || is_admin()) { return $content; } $post_title = esc_attr(get_the_title()); return preg_replace_callback('/]+)>/i', function($matches) use ($post_title) { $img_tag = $matches[0]; $attributes = $matches[1]; if (!preg_match('/alt=([\'"])(.*?)\1/i', $attributes, $alt_matches) || empty(trim($alt_matches[2]))) { if (stripos($attributes, 'alt=') !== false) { return preg_replace('/alt=([\'"])(.*?)\1/i', 'alt="' . $post_title . '"', $img_tag); } else { return str_replace(' $attachment_id, 'post_title' => $clean_title, 'post_excerpt' => $clean_title, ]); update_post_meta($attachment_id, '_wp_attachment_image_alt', $clean_title); } } TimesBull_Image_SEO::get_instance(); }