HomeAuthor: Kervyn
0
Your Wishlist : 0 listings
0
Close
%s. Without it, new thumbnail images can't be generated.", 'regenerate-thumbnails' ),
_wp_relative_upload_path( $this->fullsizepath )
),
array(
'status' => 404,
'fullsizepath' => _wp_relative_upload_path( $this->fullsizepath ),
'attachment' => $this->attachment,
)
);
$this->fullsizepath = $error;
}
return $this->fullsizepath;
}
/**
* Regenerate the thumbnails for this instance's attachment.
*
* @since 3.0.0
*
* @param array|string $args {
* Optional. Array or string of arguments for thumbnail regeneration.
*
* @type bool $only_regenerate_missing_thumbnails Skip regenerating existing thumbnail files. Default true.
* @type bool $delete_unregistered_thumbnail_files Delete any thumbnail sizes that are no longer registered. Default false.
* }
*
* @return mixed|WP_Error Metadata for attachment (see wp_generate_attachment_metadata()), or WP_Error on error.
*/
public function regenerate( $args = array() ) {
global $wpdb;
$args = wp_parse_args( $args, array(
'only_regenerate_missing_thumbnails' => true,
'delete_unregistered_thumbnail_files' => false,
) );
$fullsizepath = $this->get_fullsizepath();
if ( is_wp_error( $fullsizepath ) ) {
$fullsizepath->add_data( array( 'attachment' => $this->attachment ) );
return $fullsizepath;
}
$this->old_metadata = wp_get_attachment_metadata( $this->attachment->ID );
if ( $args['only_regenerate_missing_thumbnails'] ) {
add_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_image_sizes_to_only_missing_thumbnails' ), 10, 2 );
}
require_once( ABSPATH . 'wp-admin/includes/admin.php' );
$new_metadata = wp_generate_attachment_metadata( $this->attachment->ID, $fullsizepath );
if ( $args['only_regenerate_missing_thumbnails'] ) {
// Thumbnail sizes that existed were removed and need to be added back to the metadata.
foreach ( $this->skipped_thumbnails as $skipped_thumbnail ) {
if ( ! empty( $this->old_metadata['sizes'][ $skipped_thumbnail ] ) ) {
$new_metadata['sizes'][ $skipped_thumbnail ] = $this->old_metadata['sizes'][ $skipped_thumbnail ];
}
}
$this->skipped_thumbnails = array();
remove_filter( 'intermediate_image_sizes_advanced', array( $this, 'filter_image_sizes_to_only_missing_thumbnails' ), 10 );
}
$wp_upload_dir = dirname( $fullsizepath ) . DIRECTORY_SEPARATOR;
if ( $args['delete_unregistered_thumbnail_files'] ) {
// Delete old sizes that are still in the metadata.
$intermediate_image_sizes = get_intermediate_image_sizes();
foreach ( $this->old_metadata['sizes'] as $old_size => $old_size_data ) {
if ( in_array( $old_size, $intermediate_image_sizes ) ) {
continue;
}
wp_delete_file( $wp_upload_dir . $old_size_data['file'] );
unset( $new_metadata['sizes'][ $old_size ] );
}
$relative_path = dirname( $new_metadata['file'] ) . DIRECTORY_SEPARATOR;
// It's possible to upload an image with a filename like image-123x456.jpg and it shouldn't be deleted.
$whitelist = $wpdb->get_col( $wpdb->prepare( "
SELECT
meta_value
FROM
{$wpdb->postmeta}
WHERE
meta_key = '_wp_attached_file'
AND meta_value REGEXP %s
/* Regenerate Thumbnails */
",
'^' . preg_quote( $relative_path ) . '[^' . preg_quote( DIRECTORY_SEPARATOR ) . ']+-[0-9]+x[0-9]+\.'
) );
$whitelist = array_map( 'basename', $whitelist );
$filelist = array();
foreach ( scandir( $wp_upload_dir ) as $file ) {
if ( '.' == $file || '..' == $file || ! is_file( $wp_upload_dir . $file ) ) {
continue;
}
$filelist[] = $file;
}
$registered_thumbnails = array();
foreach ( $new_metadata['sizes'] as $size ) {
$registered_thumbnails[] = $size['file'];
}
$fullsize_parts = pathinfo( $fullsizepath );
foreach ( $filelist as $file ) {
if ( in_array( $file, $whitelist ) || in_array( $file, $registered_thumbnails ) ) {
continue;
}
if ( ! preg_match( '#^' . preg_quote( $fullsize_parts['filename'], '#' ) . '-[0-9]+x[0-9]+\.' . preg_quote( $fullsize_parts['extension'], '#' ) . '$#', $file ) ) {
continue;
}
wp_delete_file( $wp_upload_dir . $file );
}
} elseif ( ! empty( $this->old_metadata ) && ! empty( $this->old_metadata['sizes'] ) && is_array( $this->old_metadata['sizes'] ) ) {
// If not deleting, rename any size conflicts to avoid them being lost if the file still exists.
foreach ( $this->old_metadata['sizes'] as $old_size => $old_size_data ) {
if ( empty( $new_metadata['sizes'][ $old_size ] ) ) {
$new_metadata['sizes'][ $old_size ] = $this->old_metadata['sizes'][ $old_size ];
continue;
}
$new_size_data = $new_metadata['sizes'][ $old_size ];
if (
$new_size_data['width'] !== $old_size_data['width']
&& $new_size_data['height'] !== $old_size_data['height']
&& file_exists( $wp_upload_dir . $old_size_data['file'] )
) {
$new_metadata['sizes'][ $old_size . '_old_' . $old_size_data['width'] . 'x' . $old_size_data['height'] ] = $old_size_data;
}
}
}
wp_update_attachment_metadata( $this->attachment->ID, $new_metadata );
return $new_metadata;
}
/**
* Filters the list of thumbnail sizes to only include those which have missing files.
*
* @since 3.0.0
*
* @param array $sizes An associative array of registered thumbnail image sizes.
* @param array $fullsize_metadata An associative array of fullsize image metadata: width, height, file.
*
* @return array An associative array of image sizes.
*/
public function filter_image_sizes_to_only_missing_thumbnails( $sizes, $fullsize_metadata ) {
if ( ! $sizes ) {
return $sizes;
}
$fullsizepath = $this->get_fullsizepath();
if ( is_wp_error( $fullsizepath ) ) {
return $sizes;
}
$editor = wp_get_image_editor( $fullsizepath );
if ( is_wp_error( $editor ) ) {
return $sizes;
}
$metadata = $this->old_metadata;
// This is based on WP_Image_Editor_GD::multi_resize() and others.
foreach ( $sizes as $size => $size_data ) {
if ( empty( $metadata['sizes'][ $size ] ) ) {
continue;
}
if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) {
continue;
}
if ( ! isset( $size_data['width'] ) ) {
$size_data['width'] = null;
}
if ( ! isset( $size_data['height'] ) ) {
$size_data['height'] = null;
}
if ( ! isset( $size_data['crop'] ) ) {
$size_data['crop'] = false;
}
$thumbnail = $this->get_thumbnail(
$editor,
$fullsize_metadata['width'],
$fullsize_metadata['height'],
$size_data['width'],
$size_data['height'],
$size_data['crop']
);
// The false check filters out thumbnails that would be larger than the fullsize image.
// The size comparison makes sure that the size is also correct.
if (
false === $thumbnail
|| (
$thumbnail['width'] === $metadata['sizes'][ $size ]['width']
&& $thumbnail['height'] === $metadata['sizes'][ $size ]['height']
&& file_exists( $thumbnail['filename'] )
)
) {
$this->skipped_thumbnails[] = $size;
unset( $sizes[ $size ] );
}
}
/**
* Filters the list of missing thumbnail sizes if you want to add/remove any.
*
* @since 3.1.0
*
* @param array $sizes An associative array of image sizes that are missing.
* @param array $fullsize_metadata An associative array of fullsize image metadata: width, height, file.
* @param object $this The current instance of this class.
*
* @return array An associative array of image sizes.
*/
return apply_filters( 'regenerate_thumbnails_missing_thumbnails', $sizes, $fullsize_metadata, $this );
}
/**
* Generate the thumbnail filename and dimensions for a given set of constraint dimensions.
*
* @since 3.0.0
*
* @param WP_Image_Editor|WP_Error $editor An instance of WP_Image_Editor, as returned by wp_get_image_editor().
* @param int $fullsize_width The width of the fullsize image.
* @param int $fullsize_height The height of the fullsize image.
* @param int $thumbnail_width The width of the thumbnail.
* @param int $thumbnail_height The height of the thumbnail.
* @param bool $crop Whether to crop or not.
*
* @return array|false An array of the filename, thumbnail width, and thumbnail height,
* or false on failure to resize such as the thumbnail being larger than the fullsize image.
*/
public function get_thumbnail( $editor, $fullsize_width, $fullsize_height, $thumbnail_width, $thumbnail_height, $crop ) {
$dims = image_resize_dimensions( $fullsize_width, $fullsize_height, $thumbnail_width, $thumbnail_height, $crop );
if ( ! $dims ) {
return false;
}
list( , , , , $dst_w, $dst_h ) = $dims;
$suffix = "{$dst_w}x{$dst_h}";
$file_ext = strtolower( pathinfo( $this->get_fullsizepath(), PATHINFO_EXTENSION ) );
return array(
'filename' => $editor->generate_filename( $suffix, null, $file_ext ),
'width' => $dst_w,
'height' => $dst_h,
);
}
/**
* Update the post content of any public post types (posts and pages by default)
* that make use of this attachment.
*
* @since 3.0.0
*
* @param array|string $args {
* Optional. Array or string of arguments for controlling the updating.
*
* @type array $post_type The post types to update. Defaults to public post types (posts and pages by default).
* @type array $post_ids Specific post IDs to update as opposed to any that uses the attachment.
* @type int $posts_per_loop How many posts to query at a time to keep memory usage down. You shouldn't need to modify this.
* }
*
* @return array|WP_Error List of post IDs that were modified. The key is the post ID and the value is either the post ID again or a WP_Error object if wp_update_post() failed.
*/
public function update_usages_in_posts( $args = array() ) {
// Temporarily disabled until it can be even better tested for edge cases
return array();
$args = wp_parse_args( $args, array(
'post_type' => array(),
'post_ids' => array(),
'posts_per_loop' => 10,
) );
if ( empty( $args['post_type'] ) ) {
$args['post_type'] = array_values( get_post_types( array( 'public' => true ) ) );
unset( $args['post_type']['attachment'] );
}
$offset = 0;
$posts_updated = array();
while ( true ) {
$posts = get_posts( array(
'numberposts' => $args['posts_per_loop'],
'offset' => $offset,
'orderby' => 'ID',
'order' => 'ASC',
'include' => $args['post_ids'],
'post_type' => $args['post_type'],
's' => 'wp-image-' . $this->attachment->ID,
// For faster queries.
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
) );
if ( ! $posts ) {
break;
}
$offset += $args['posts_per_loop'];
foreach ( $posts as $post ) {
$content = $post->post_content;
$search = array();
$replace = array();
// Find all