From 75a097a018a0090f5902758353c578fce4aa2a25 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sat, 23 May 2026 18:43:42 +0000
Subject: [PATCH] =CustomBlocks.php overhaul relatively complete. Also refactored the gallery in gallery.min.js and the jvbRenderGallery.

---
 inc/utility/Image.php |  121 ++++++++++++++++++++++++++++++++-------
 1 files changed, 98 insertions(+), 23 deletions(-)

diff --git a/inc/utility/Image.php b/inc/utility/Image.php
index 8ecbd83..b888008 100644
--- a/inc/utility/Image.php
+++ b/inc/utility/Image.php
@@ -1,7 +1,7 @@
 <?php
 namespace JVBase\utility;
 
-use JVBase\managers\CacheManager;
+use JVBase\managers\Cache;
 
 if (!defined('ABSPATH')) {
 	exit;
@@ -12,50 +12,98 @@
  */
 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
@@ -85,4 +133,31 @@
 		}
 		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);
+	}
+
 }

--
Gitblit v1.10.0