Jake Vanderwerf
7 days ago 46d681c6b825d21b3f698d793c4e630c687d90ad
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,97 @@
 */
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();
      }
   }
   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 +132,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);
   }
}