| | |
| | | <?php |
| | | namespace JVBase\utility; |
| | | |
| | | use JVBase\managers\CacheManager; |
| | | use JVBase\managers\Cache; |
| | | |
| | | if (!defined('ABSPATH')) { |
| | | exit; |
| | |
| | | */ |
| | | class Image |
| | | { |
| | | protected ?CacheManager $cache = null; |
| | | protected ?Cache $cache = null; |
| | | protected ?Cache $imgData = null; |
| | | |
| | | public function __construct() |
| | | { |
| | | $this->cache = CacheManager::for('images')->connectTo('post', 'attachment'); |
| | | $this->cache = Cache::for('images')->connect('post'); |
| | | $this->imgData = Cache::for('imageData')->connect('post'); |
| | | if (JVB_TESTING) { |
| | | $this->cache->flush(); |
| | | $this->imgData->flush(); |
| | | } |
| | | } |
| | | |
| | | 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], |
| | | $return = $this->cache->remember( |
| | | $this->cache->generateKey(['ID' => $ID, 'start' => $start, 'replace' => $replace]), |
| | | function() use ($ID, $start, $replace) { |
| | | $img = wp_get_attachment_image_src($ID, $start); |
| | | if (!$img) { |
| | | return''; |
| | | // 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; |
| | | } |
| | | } |
| | | $img = $img[0]; |
| | | |
| | | $data = $this->getGallerySizes($ID, $replace); |
| | | 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="'.$alt.'" '; |
| | | return '<img width="100%" height="auto" src="'.$img.'"'.$alt.$data.' loading="lazy" decoding="async">'; |
| | | $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 |
| | | ); |
| | | } |
| | | ); |
| | | |
| | | $aOpen = $aClose = ''; |
| | | if ($addLink) { |
| | | if (!$postSlug) { |
| | | global $post; |
| | | $postSlug = $post->post_name; |
| | | if (is_singular()) { |
| | | global $post; |
| | | $postSlug = $post->post_name; |
| | | }else if (is_tax()) { |
| | | $tax = get_queried_object(); |
| | | $postSlug = jvbNoBase($tax->taxonomy); |
| | | }elseif (is_post_type_archive()) { |
| | | $obj = get_queried_object(); |
| | | $postSlug = jvbNoBase($obj->post_type); |
| | | } |
| | | |
| | | } |
| | | $full = wp_get_attachment_image_src($ID, 'full'); |
| | | |
| | | $imgPost = get_post($ID); |
| | | if (!$imgPost) { |
| | | return $return; |
| | | } |
| | | if (!$imgPost) return $return; |
| | | |
| | | $imgSlug = $imgPost->post_name; |
| | | $aOpen = '<a class="open-gallery" target="_blank" rel="nofollow" data-opens="gallery-'.$postSlug.'" data-focus="'.$postSlug.'-'.$imgSlug.'">'; |
| | | $aClose = '</a>'; |
| | | $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 $aOpen.$return.$aClose; |
| | | |
| | | return $return; |
| | | } |
| | | |
| | | public function getGallerySizes(int $ID, string $replace):string |
| | |
| | | } |
| | | return ''; |
| | | } |
| | | |
| | | public function getImageData(int $imgID):array |
| | | { |
| | | return $this->imgData->remember( |
| | | $imgID, |
| | | function() use ($imgID) { |
| | | if (!wp_get_attachment_image($imgID, 'tiny')) { |
| | | return []; |
| | | } |
| | | return [ |
| | | 'tiny' => wp_get_attachment_image_src($imgID, 'tiny')[0], |
| | | 'small' => wp_get_attachment_image_src($imgID, 'medium')[0], |
| | | 'medium' => wp_get_attachment_image_src($imgID, 'large')[0], |
| | | 'large' => wp_get_attachment_image_src($imgID, 'full')[0], |
| | | 'image-alt-text'=> get_post_meta($imgID, '_wp_attachment_image_alt', true), |
| | | 'image-title' => get_the_title($imgID), |
| | | 'image-caption' => get_the_excerpt($imgID), |
| | | ]; |
| | | } |
| | | ); |
| | | } |
| | | |
| | | public static function getData(int $imgID):array |
| | | { |
| | | return (new Image)->getImageData($imgID); |
| | | } |
| | | |
| | | } |