'image/webp' ] ); } public static function webp( int $id, array $widths ): array { $file = (string) get_attached_file( $id ); $meta = wp_get_attachment_metadata( $id ); $full = (int) ( $meta['width'] ?? 0 ); if ( ! $full || '' === $file || ! file_exists( $file ) || ! self::raster( $id ) ) { return []; } $widths = array_filter( array_map( 'intval', $widths ), static fn ( int $w ): bool => $w > 0 && $w < $full ); $widths = array_unique( array_merge( $widths, [ $full ] ) ); sort( $widths ); $have = get_post_meta( $id, self::META, true ); $have = is_array( $have ) ? $have : []; $uploads = wp_get_upload_dir(); $out = []; $changed = false; foreach ( $widths as $w ) { $entry = $have[ $w ] ?? null; if ( ! is_array( $entry ) || empty( $entry['file'] ) || ! file_exists( $uploads['basedir'] . '/' . $entry['file'] ) ) { $entry = self::make( $file, $w ); if ( null === $entry ) { continue; } $have[ $w ] = $entry; $changed = true; } $out[ $uploads['baseurl'] . '/' . $entry['file'] ] = (int) $entry['width']; } if ( $changed ) { update_post_meta( $id, self::META, $have ); } return $out; } private static function make( string $file, int $width ): ?array { $editor = wp_get_image_editor( $file ); if ( is_wp_error( $editor ) ) { return null; } $size = $editor->get_size(); if ( $width < (int) ( $size['width'] ?? 0 ) && is_wp_error( $editor->resize( $width, null ) ) ) { return null; } $editor->set_quality( self::QUALITY ); $saved = $editor->save( (string) preg_replace( '/\.[a-z0-9]+$/i', '', $file ) . '-' . $width . 'w.webp', 'image/webp' ); if ( is_wp_error( $saved ) || empty( $saved['path'] ) ) { return null; } return [ 'file' => (string) _wp_relative_upload_path( (string) $saved['path'] ), 'width' => (int) $saved['width'], 'height' => (int) $saved['height'] ]; } public static function delete( $id ): void { $base = wp_get_upload_dir()['basedir'] . '/'; $have = get_post_meta( (int) $id, self::META, true ); foreach ( is_array( $have ) ? $have : [] as $entry ) { if ( is_array( $entry ) && ! empty( $entry['file'] ) && file_exists( $base . $entry['file'] ) ) { wp_delete_file( $base . $entry['file'] ); } } } }