Files
h4b-image-optim/includes/class-attachment-meta.php
Henk 7e1c86f215 feat: initial v0.1.0 MVP
Replaces Smush Pro's optimisation pipeline without the grey-wash bug.

CLI commands working:
  wp h4b-img status
  wp h4b-img optimise --id=<n>
  wp h4b-img bulk
  wp h4b-img rescue

Verified on dev.rds.ink:
- ICC profile preservation works (the Smush-bug fix)
- Bulk: 20 attachments → 487 KB saved (10.4%), 0 errors
- Rescue: end-to-end mechanism verified on WorkingAsOne_horse fixture
- WebP synchronous, AVIF queued via WP-Cron
- Originals backed up to wp-content/h4b-img-originals/

See CHANGELOG.md for details + ../DESIGN-h4b-image-optim.md for architecture.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 13:41:03 +10:00

72 lines
2.1 KiB
PHP

<?php
/**
* Tracks per-attachment optimisation history.
*
* Stored as a single postmeta key `_h4b_img_optim` containing:
* [
* 'version' => '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 );
}
}
}