fix: postmeta tracking on synchronous AVIF + add reconcile-meta (v0.2.2)
Two improvements after v0.2.1 deploy revealed the avif_status bug wasn't fully fixed: Fix: Format_Generator::make_avif() now calls record_avif_outcome() at the end of the synchronous path. Previously only the cron path recorded outcomes, so wp h4b-img generate-missing-siblings (synchronous) left 4067 stale 'queued' rows even though it successfully generated 603 AVIFs on disk. process_avif_job() simplified to a thin wrapper around make_avif(avif_async=false). Added: wp h4b-img reconcile-meta — walks _h4b_img_optim postmeta, checks for .webp / .avif files on disk, and updates avif_status / webp size fields to match reality. One-shot reconciliation for stale records left by earlier plugin versions. --dry-run supported. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -143,6 +143,104 @@ final class CLI_Siblings {
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconcile attachment postmeta with what's actually on disk.
|
||||
*
|
||||
* For each `_h4b_img_optim` size entry, if avif_status is 'queued' or 'never_generated'
|
||||
* but the .avif file exists on disk, update to 'done' with the actual byte size.
|
||||
* Similarly for webp.
|
||||
*
|
||||
* Use this after manual generate-missing-siblings runs OR to fix the stale
|
||||
* 'queued' values from a v0.2.0 era bulk run.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--dry-run]
|
||||
* : Report counts only.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
* wp h4b-img reconcile-meta --dry-run
|
||||
* wp h4b-img reconcile-meta
|
||||
*/
|
||||
public function reconcile_meta( $args, $assoc ): void {
|
||||
$dry_run = ! empty( $assoc['dry-run'] );
|
||||
global $wpdb;
|
||||
$basedir = trailingslashit( wp_get_upload_dir()['basedir'] );
|
||||
|
||||
$rows = $wpdb->get_results( "SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key='_h4b_img_optim'" );
|
||||
\WP_CLI::log( sprintf( 'Scanning %d attachments…', count( $rows ) ) );
|
||||
|
||||
$updates = [
|
||||
'avif_done_marked' => 0,
|
||||
'avif_already_done' => 0,
|
||||
'avif_still_missing' => 0,
|
||||
'webp_done_marked' => 0,
|
||||
];
|
||||
|
||||
foreach ( $rows as $r ) {
|
||||
$meta = @unserialize( $r->meta_value, [ 'allowed_classes' => false ] );
|
||||
if ( ! is_array( $meta ) || empty( $meta['sizes'] ) ) {
|
||||
continue;
|
||||
}
|
||||
$rel_parent = get_post_meta( $r->post_id, '_wp_attached_file', true );
|
||||
if ( ! $rel_parent ) {
|
||||
continue;
|
||||
}
|
||||
$parent_dir = dirname( $rel_parent );
|
||||
$attached_meta = wp_get_attachment_metadata( $r->post_id );
|
||||
$changed = false;
|
||||
foreach ( $meta['sizes'] as $size_key => &$entry ) {
|
||||
// Resolve the file path for this size key
|
||||
if ( $size_key === 'full' ) {
|
||||
$file_rel = $rel_parent;
|
||||
} elseif ( is_array( $attached_meta ) && ! empty( $attached_meta['sizes'][ $size_key ]['file'] ) ) {
|
||||
$f = $attached_meta['sizes'][ $size_key ]['file'];
|
||||
$file_rel = ( $parent_dir === '.' ) ? $f : "$parent_dir/$f";
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
$src = $basedir . $file_rel;
|
||||
$avif = $src . '.avif';
|
||||
$webp = $src . '.webp';
|
||||
|
||||
// AVIF
|
||||
if ( is_readable( $avif ) ) {
|
||||
if ( ( $entry['avif_status'] ?? '' ) !== 'done' ) {
|
||||
$entry['avif'] = filesize( $avif );
|
||||
$entry['avif_status'] = 'done';
|
||||
$updates['avif_done_marked']++;
|
||||
$changed = true;
|
||||
} else {
|
||||
$updates['avif_already_done']++;
|
||||
}
|
||||
} elseif ( ( $entry['avif_status'] ?? '' ) === 'queued' ) {
|
||||
$updates['avif_still_missing']++;
|
||||
}
|
||||
|
||||
// WebP — only mark if currently null/missing
|
||||
if ( is_readable( $webp ) && empty( $entry['webp'] ) ) {
|
||||
$entry['webp'] = filesize( $webp );
|
||||
$updates['webp_done_marked']++;
|
||||
$changed = true;
|
||||
}
|
||||
}
|
||||
unset( $entry );
|
||||
|
||||
if ( $changed && ! $dry_run ) {
|
||||
Attachment_Meta::set( (int) $r->post_id, $meta );
|
||||
}
|
||||
}
|
||||
|
||||
\WP_CLI::success( sprintf(
|
||||
"Reconciliation %s.\n avif_status 'queued' → 'done' on disk: %d\n avif already correctly 'done': %d\n avif still missing (queue stale): %d\n webp filesize backfilled in meta: %d",
|
||||
$dry_run ? 'dry-run' : 'done',
|
||||
$updates['avif_done_marked'],
|
||||
$updates['avif_already_done'],
|
||||
$updates['avif_still_missing'],
|
||||
$updates['webp_done_marked']
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the set of all JPG/PNG paths registered in wp_attachment_metadata.
|
||||
* Returns rel-path => true.
|
||||
|
||||
Reference in New Issue
Block a user