通常都是采用插件的方式来实现这个功能,但是我一直喜欢使用代码的方式来解决问题。首先我参照了一篇文章https://www.gavsblog.com/blog/regenerate-wordpress-media-image-sizes-programmaticall,他的代码如下:
require_once(ABSPATH . 'wp-admin/includes/image.php');
// Put the function in a class to make it more extendable
class GB_regen_media {
public function gb_regenerate($imageId) {
$imagePath = wp_get_original_image_path($imageId);
if ($imagePath && file_exists($imagePath)) {
wp_generate_attachment_metadata($imageId, $imagePath);
}
}
}
// Add a load function
function gb_regen_load() {
// Instantiate the class
$gb_regen_media = new GB_regen_media();
// Set the image Id
$imageId = 1;
// You can get the image Id from the url of the media screen
$gb_regen_media->gb_regenerate($imageId);
}
// Load after WordPress has finished loading
add_action('init', 'gb_regen_load');
这里边用到了几个函数功能:wp_get_original_image_path($imageId)
、wp_generate_attachment_metadata($imageId, $imagePath)
以及add_action('init', 'gb_regen_load')
。
我这里需要考虑所有上传的图片附件,所以修改了一下代码:
// Put the function in a class to make it more extendable
class GB_regen_media {
public function gb_regenerate($imageId) {
$imagePath = wp_get_original_image_path($imageId);
if ($imagePath && file_exists($imagePath)) {
// unlink();
wp_generate_attachment_metadata($imageId, $imagePath);
}
}
}
// Add a load function
function gb_regen_load($new_value,$old_value) {
// Instantiate the class
$gb_regen_media = new GB_regen_media();
$regenerate_thumbnail_value = get_option('xcm_regenerate_thumbnail_enable', '');
$args = array('post_type'=>'attachment','numberposts'=>null,'post_status'=>null);
$attachments = get_posts($args);
// You can get the image Id from the url of the media screen
if($attachments && $new_value == '1'){
require_once(ABSPATH . 'wp-admin/includes/image.php');
$new_value = '';
foreach($attachments as $attachment){
$gb_regen_media->gb_regenerate($attachment->ID);
}
}
return $new_value;
}
add_filter('pre_update_option_regenerate_thumbnail_enable', 'gb_regen_load',10,2);
此处代码的重点在于选择哪一种钩子(hook),这里列举三种:
一种是add_action('updated_option',functions)
,它将在任意option更新之后被激发,这是不必要的。
第二种是add_action('update_option_{$option}',function)
,需要注意新旧参数值( $old_value, $new_value )的前后位置,示例代码如下:
add_action( 'update_option_myoption', function( $old_value, $new_value ) {
//Do something with the new value
}, 10, 2);
但是这一方法并不能修改新的值,当新旧值完全一样时不会被触发,这一点在官方页面中有所提及:https://developer.wordpress.org/reference/hooks/update_option_option/
第三种是pre_update_option_{$option},示例代码如下:
add_filter( 'pre_update_option_myoption', function( $new_value, $old_value ) {
//Do something before returning the new value to be saved in database
return $new_value;
}, 10, 2);
我这里使用的就是这一种,它有一个好处就是能够查看新旧值并修改新值,我的逻辑是这样,首先判断”regenerate_thumbnail_enable”的新值,是否为1,为1就是运行,不为1就是不需要重新生成缩略图,如果新值为1,那么我们就运行相关功能函数,并且将新值改成空值,这样就能避免该功能在不必要的情况下被触发。
但是仍然存在一个问题,就是函数wp_generate_attachment_metadata($imageId, $imagePath)
会将所有注册过的缩略图尺寸重新生成一遍,显的不那么节省资源;此外,无用缩略图的的清理也是一个问题,不过我们可以在新缩略图生成之后,通过后台文件检索进行删除。