<?php
|
namespace JVBase\utility;
|
|
use JVBase\managers\Cache;
|
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
/**
|
* Validates configuration arrays for content types, taxonomies, and user roles
|
* Catches errors early in the registration process
|
*/
|
class Image
|
{
|
protected ?Cache $cache = null;
|
protected ?Cache $imgData = null;
|
|
public function __construct()
|
{
|
$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(
|
$this->cache->generateKey(['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) {
|
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;
|
|
$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 '';
|
}
|
|
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);
|
}
|
|
public static function gallery(string $ids, ?string $type = null):string
|
{
|
$ids = explode(',', $ids);
|
$inner = implode('', array_map(function ($ID) {
|
$caption = wp_get_attachment_caption($ID);
|
if (!empty($caption)) {
|
$caption = sprintf('<figcaption>%s</figcaption', $caption);
|
}
|
return sprintf(
|
'<li><figure>%s%s</figure></li>',
|
self::image($ID),
|
$caption
|
);
|
}, $ids));
|
return sprintf(
|
'<ul class="gallery%s">%s</ul>',
|
$type? ' '.$type : '',
|
$inner
|
);
|
}
|
|
public static function image(int $id, string $start = 'tiny', string $replace = 'large', bool $addLink = true, ?string $postSlug = null):string
|
{
|
return (new Image)->formatImage($id, $start, $replace, $addLink, $postSlug);
|
}
|
|
}
|