'0.1.0', * 'processed_at' => 'ISO-8601', * 'tool_chain' => ['imagick','cjpeg','jpegoptim',...], * 'sizes' => [ * 'full' => ['before'=>123, 'after'=>78, 'webp'=>45, 'avif'=>30, 'percent'=>37], * '800x524' => [...], * ], * 'backup_path' => 'wp-content/h4b-img-originals/2026/02/...', * 'errors' => [], * ] * * @package H4B\ImageOptim */ namespace H4B\ImageOptim; if ( ! defined( 'ABSPATH' ) ) { exit; } final class Attachment_Meta { public const META_KEY = '_h4b_img_optim'; public static function get( int $attachment_id ): array { $meta = get_post_meta( $attachment_id, self::META_KEY, true ); return is_array( $meta ) ? $meta : []; } public static function set( int $attachment_id, array $meta ): void { update_post_meta( $attachment_id, self::META_KEY, $meta ); } public static function is_processed( int $attachment_id ): bool { $meta = self::get( $attachment_id ); return ! empty( $meta['processed_at'] ); } public static function record_size( int $attachment_id, string $size_key, array $stats ): void { $meta = self::get( $attachment_id ); $meta['sizes'] = $meta['sizes'] ?? []; $meta['sizes'][ $size_key ] = $stats; $meta['version'] = H4B_IMG_OPTIM_VERSION; $meta['processed_at'] = current_time( 'c' ); self::set( $attachment_id, $meta ); } public static function mark_avif_pending( int $attachment_id, string $size_key ): void { $meta = self::get( $attachment_id ); $meta['avif_pending'] = $meta['avif_pending'] ?? []; $meta['avif_pending'][ $size_key ] = current_time( 'c' ); self::set( $attachment_id, $meta ); } public static function clear_avif_pending( int $attachment_id, string $size_key ): void { $meta = self::get( $attachment_id ); if ( isset( $meta['avif_pending'][ $size_key ] ) ) { unset( $meta['avif_pending'][ $size_key ] ); if ( empty( $meta['avif_pending'] ) ) { unset( $meta['avif_pending'] ); } self::set( $attachment_id, $meta ); } } }