Jake Vanderwerf
2026-01-22 58e8ae0759ccfa97c478ccae4e0778bdce70966f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
namespace JVBase\utility;
 
use JVBase\managers\CacheManager;
 
if (!defined('ABSPATH')) {
    exit;
}
/**
 * Validates configuration arrays for content types, taxonomies, and user roles
 * Catches errors early in the registration process
 */
class Image
{
    protected ?CacheManager $cache = null;
 
    public function __construct()
    {
        $this->cache = CacheManager::for('images')->connectTo('post', 'attachment');
        if (JVB_TESTING) {
            $this->cache->clear();
        }
    }
 
    public function formatImage(int $ID, string $start = 'tiny', string $replace = 'large', bool $addLink = true, ?string $postSlug = null):string
    {
        $return = $this->cache->remember(
            ['ID' => $ID, 'start' => $start, 'replace' => $replace],
            function() use ($ID, $start, $replace) {
                // Define size order for progressive enhancement
                $sizeOrder = ['tiny', 'directory-preview', 'thumbnail', 'medium', 'large', 'full'];
                $startIndex = array_search($start, $sizeOrder);
                $replaceIndex = array_search($replace, $sizeOrder);
 
                // Fallback if invalid sizes provided
                if ($startIndex === false) $startIndex = 0;
                if ($replaceIndex === false) $replaceIndex = 2;
 
                // Get all images up to the replace size
                $images = [];
                for ($i = $startIndex; $i <= $replaceIndex; $i++) {
                    $img = wp_get_attachment_image_src($ID, $sizeOrder[$i]);
                    if ($img) {
                        $images[$sizeOrder[$i]] = $img;
                    }
                }
 
                if (empty($images)) return '';
 
                // Use first available image as src
                $firstImage = reset($images);
                $alt = get_post_meta($ID, '_wp_attachment_image_alt', true);
                $alt = ($alt=='')? '' : ' alt="'.esc_attr($alt).'" ';
 
                // Build srcset only with images from start to replace
                $srcsetParts = [];
                foreach ($images as $img) {
                    $srcsetParts[] = sprintf('%s %dw', $img[0], $img[1]);
                }
                $srcset = implode(', ', $srcsetParts);
 
                return sprintf(
                    '<img src="%s"%s srcset="%s" sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 800px" loading="lazy" decoding="async">',
                    $firstImage[0],
                    $alt,
                    $srcset
                );
            }
        );
 
        if ($addLink) {
            if (!$postSlug) {
                global $post;
                $postSlug = $post->post_name;
            }
            $full = wp_get_attachment_image_src($ID, 'full');
 
            $imgPost = get_post($ID);
            if (!$imgPost) return $return;
 
            $imgSlug = $imgPost->post_name;
            $galleryAttrs = sprintf(
                ' data-gallery="gallery-%s" data-focus="%s-%s" data-full="%s"',
                $postSlug,
                $postSlug,
                $imgSlug,
                $full[0]
            );
 
            // Add gallery attributes to img tag
            $return = str_replace('<img', '<img'.$galleryAttrs, $return);
        }
 
        return $return;
    }
 
    public function getGallerySizes(int $ID, string $replace):string
    {
        if (!wp_get_attachment_image_src($ID)) {
            return '';
        }
        if (!has_image_size($replace)) {
            $replace = 'large';
        }
 
        if ($replace == 'large') {
            return 'data-small="' .
                wp_get_attachment_image_src($ID)[0] . '" data-medium="' .
                wp_get_attachment_image_src($ID, 'large')[0] . '" data-full="' .
                wp_get_attachment_image_src($ID, 'full')[0] . '"';
        } elseif ($replace == 'medium') {
            return 'data-small="'.
                wp_get_attachment_image_src($ID, 'large')[0].'" data-medium="'.
                wp_get_attachment_image_src($ID, 'large')[0].'" data-full="'.
                wp_get_attachment_image_src($ID, 'large')[0].'"';
        } elseif ($replace == 'thumbnail') {
            return 'data-small="'.
                wp_get_attachment_image_src($ID, 'medium')[0].'" data-medium="'.
                wp_get_attachment_image_src($ID, 'medium')[0].'" data-full="'.
                wp_get_attachment_image_src($ID, 'medium')[0].'"';
        }
        return '';
    }
}