🆕 新增功能
1. 自动文件重命名功能
功能描述
- 上传的图片文件会自动重命名为基于当前日期时间的格式
- 命名规则:YYYY-MM-DD-HHMMSS (例:2025-09-18-195314)
- 如果同一秒内上传多个文件,会自动添加微秒后缀确保唯一性
示例
上传文件: "大神.png"
重命名后: "2025-09-18-195314.png"
上传文件: "产品图片.jpg"
重命名后: "2025-09-18-195315.jpg"
同一秒上传第二个文件:
重命名后: "2025-09-18-195315-123456.jpg"
设置选项
在 设置 > WebP Optimizer 中新增:
- 自动重命名文件: 可开启/关闭此功能
2. 扩展图片格式支持
支持的格式大幅增加
原支持格式: JPEG, PNG, GIF
新支持格式: JPEG, JPG, PNG, GIF, BMP, WebP, TIFF, TIF, SVG, ICO
格式处理策略
格式 | 重命名 | WebP转换 | 说明 |
---|---|---|---|
JPEG/JPG | ✅ | ✅ | 完全支持 |
PNG | ✅ | ✅ | 保持透明度 |
GIF | ✅ | ✅ | 动画会变为静态 |
BMP | ✅ | ✅ | 转换为更小的WebP |
TIFF/TIF | ✅ | ✅ | 使用Imagick处理 |
WebP | ✅ | ✅ | 重新压缩优化 |
SVG | ✅ | ❌ | 矢量图不需要转换 |
ICO | ✅ | ❌ | 图标文件不转换 |
🔧 技术实现
文件重命名机制
// 使用wp_handle_upload_prefilter钩子
add_filter('wp_handle_upload_prefilter', array($this, 'rename_uploaded_file'));
// 生成时间戳文件名
$date_time = date('Y-m-d-His'); // 2025-09-18-195314
唯一性保证
- 检查同名文件是否存在
- 如存在则添加微秒后缀
- 确保文件名100%唯一
格式识别
- 支持MIME类型识别
- 自动推断文件扩展名
- 处理无扩展名的情况
📈 优化效果
文件管理优势
- 统一命名规范: 所有上传文件按时间顺序命名
- 避免中文乱码: 解决中文文件名在某些服务器环境下的问题
- 便于批量管理: 按时间顺序排列,便于查找和管理
SEO友好
- 避免特殊字符对URL的影响
- 统一的命名规范有利于搜索引擎索引
- 减少因文件名问题导致的404错误
🛠️ 使用方法
启用新功能
- 进入 WordPress后台 > 设置 > WebP Optimizer
- 勾选 "自动重命名文件" 选项
- 点击 "保存设置"
批量处理现有文件
# WP-CLI命令保持不变
wp awio convert --limit=100
验证功能
- 上传一个图片文件(任意格式)
- 检查媒体库中的文件名是否变为时间格式
- 确认文件正常显示且已转换为WebP(如适用)
📊 设置建议
推荐配置
启用WebP转换: ✅
自动重命名文件: ✅ (新功能)
删除原文件: ✅
跳过小文件: ✅
备份原文件: ❌ (节省空间)
质量设置保持不变
小文件质量: 85%
中等文件质量: 80%
大文件质量: 75%
超大文件质量: 70%
⚠️ 注意事项
兼容性
- 新功能向下兼容,不影响现有文件
- 现有上传的文件名不会被更改
- 只对新上传的文件生效
文件名变化
- 上传后无法通过原文件名搜索
- 建议通过媒体库的标题、说明等字段记录原始信息
- 可以在上传时填写图片的Alt文本和描述
性能影响
- 文件重命名操作几乎无性能影响
- 新格式支持可能略微增加处理时间
- 整体性能提升仍然显著
🔍 故障排除
常见问题
Q: 重命名功能不生效?
A:
- 检查设置页面是否启用了"自动重命名文件"
- 确认上传的是支持的图片格式
- 检查文件权限是否正确
Q: 某些格式无法转换?
A:
- TIFF格式需要Imagick扩展支持
- BMP格式在某些环境下可能不支持
- SVG和ICO格式只重命名,不转换WebP
Q: 文件名包含微秒后缀?
A: 这表示同一秒内上传了多个文件,属于正常现象
调试方法
// 在wp-config.php中启用调试
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
// 查看日志文件
tail -f /wp-content/debug.log
📚 更新历史
v1.1.0 (当前版本)
- ✅ 新增自动文件重命名功能
- ✅ 支持11种图片格式
- ✅ 改进管理界面显示
- ✅ 优化文件处理逻辑
v1.0.0 (初始版本)
- ✅ 基础WebP转换功能
- ✅ 智能质量控制
- ✅ 统计报告功能
- ✅ WP-CLI支持
🎯 下个版本预告 (v1.2.0)
计划中的新功能:
- AVIF格式支持: 下一代图像格式
- 批量重命名工具: 对现有文件应用新的命名规则
- 自定义命名模板: 支持更多命名格式选择
- 图片水印功能: 自动添加网站水印
升级建议: 建议所有用户升级到v1.1.0,享受更强大的文件管理功能和更广泛的格式支持。
插件源代码:
<?php
/**
* Plugin Name: Auto WebP Image Optimizer
* Plugin URI: https://yourwebsite.com
* Description: 自动压缩上传的图片并转换为WebP格式,完成后删除原文件
* Version: 1.1.0
* Author: Your Name
* Author URI: https://yourwebsite.com
* License: GPL v2 or later
* Text Domain: auto-webp-optimizer
* Domain Path: /languages
*
* Requires at least: 5.8
* Tested up to: 6.6
* Requires PHP: 7.4
*
* 更新说明:
* v1.1.0 - 添加自动文件重命名功能,支持更多图片格式
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('AWIO_VERSION', '1.1.0');
define('AWIO_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('AWIO_PLUGIN_URL', plugin_dir_url(__FILE__));
class AutoWebPImageOptimizer {
private $options;
public function __construct() {
// 插件激活和停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化插件
add_action('init', array($this, 'init'));
// 管理员界面
if (is_admin()) {
add_action('admin_menu', array($this, 'add_admin_menu'));
add_action('admin_init', array($this, 'admin_init'));
}
// 文件名重命名钩子 - 在文件上传前修改文件名
add_filter('wp_handle_upload_prefilter', array($this, 'rename_uploaded_file'));
// 主要功能钩子 - 使用wp_generate_attachment_metadata确保所有图片尺寸都已生成
add_filter('wp_generate_attachment_metadata', array($this, 'process_uploaded_image'), 10, 2);
// 加载选项
$this->options = get_option('awio_options', $this->get_default_options());
}
/**
* 检查是否支持转换为WebP格式
*/
private function is_supported_for_webp_conversion($mime_type) {
$webp_supported_types = array(
'image/jpeg', 'image/jpg', 'image/png', 'image/gif',
'image/bmp', 'image/webp', 'image/tiff', 'image/tif'
);
return in_array($mime_type, $webp_supported_types);
}
/**
* 重命名上传的文件
*/
public function rename_uploaded_file($file) {
// 检查是否启用文件重命名
if (!$this->options['rename_files']) {
return $file;
}
// 检查是否为支持的图片格式
if (!$this->is_supported_image_type($file['type'])) {
return $file;
}
// 获取文件扩展名
$file_info = pathinfo($file['name']);
$extension = isset($file_info['extension']) ? strtolower($file_info['extension']) : '';
// 如果没有扩展名,尝试从MIME类型推断
if (empty($extension)) {
$extension = $this->get_extension_from_mime($file['type']);
}
// 生成基于当前时间的文件名
$date_time = date('Y-m-d-His'); // 格式:2015-09-18-195314
// 确保文件名唯一性,如果存在同名文件则添加微秒
$new_filename = $date_time;
if (!empty($extension)) {
$new_filename .= '.' . $extension;
}
// 检查文件是否已存在,如果存在则添加微秒确保唯一性
$upload_dir = wp_upload_dir();
$target_path = $upload_dir['path'] . '/' . $new_filename;
if (file_exists($target_path)) {
$microtime = microtime(true);
$microseconds = sprintf("%06d", ($microtime - floor($microtime)) * 1000000);
$new_filename = $date_time . '-' . $microseconds;
if (!empty($extension)) {
$new_filename .= '.' . $extension;
}
}
// 更新文件名
$file['name'] = $new_filename;
return $file;
}
/**
* 检查是否为支持的图片类型
*/
private function is_supported_image_type($mime_type) {
return in_array($mime_type, $this->options['supported_types']);
}
/**
* 从MIME类型获取文件扩展名
*/
private function get_extension_from_mime($mime_type) {
$mime_to_ext = array(
'image/jpeg' => 'jpg',
'image/jpg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/webp' => 'webp',
'image/tiff' => 'tiff',
'image/tif' => 'tif',
'image/svg+xml' => 'svg',
'image/x-icon' => 'ico',
'image/vnd.microsoft.icon' => 'ico'
);
return isset($mime_to_ext[$mime_type]) ? $mime_to_ext[$mime_type] : '';
}
/**
* 插件激活时执行
*/
public function activate() {
// 检查系统要求
if (!$this->check_requirements()) {
deactivate_plugins(plugin_basename(__FILE__));
wp_die('Auto WebP Image Optimizer requires GD or Imagick extension with WebP support.');
}
// 初始化选项
add_option('awio_options', $this->get_default_options());
}
/**
* 插件停用时执行
*/
public function deactivate() {
// 清理任务(如有需要)
}
/**
* 初始化插件
*/
public function init() {
// 加载文本域
load_plugin_textdomain('auto-webp-optimizer', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
/**
* 检查系统要求
*/
private function check_requirements() {
// 检查GD扩展
if (extension_loaded('gd')) {
$gd_info = gd_info();
if (isset($gd_info['WebP Support']) && $gd_info['WebP Support']) {
return true;
}
}
// 检查Imagick扩展
if (extension_loaded('imagick')) {
$imagick = new Imagick();
$formats = $imagick->queryFormats('WEBP');
if (!empty($formats)) {
return true;
}
}
return false;
}
/**
* 获取默认选项
*/
private function get_default_options() {
return array(
'enable_conversion' => 1,
'quality_small' => 85, // 小于200KB图片质量
'quality_medium' => 80, // 200KB-1MB图片质量
'quality_large' => 75, // 1MB-2.5MB图片质量
'quality_xlarge' => 70, // 大于2.5MB图片质量
'delete_originals' => 1, // 删除原文件
'max_width' => 2048, // 最大宽度
'max_height' => 2048, // 最大高度
'supported_types' => array(
'image/jpeg', 'image/jpg', 'image/png', 'image/gif',
'image/bmp', 'image/webp', 'image/tiff', 'image/tif',
'image/svg+xml', 'image/x-icon', 'image/vnd.microsoft.icon'
),
'rename_files' => 1, // 是否重命名上传的文件
'skip_small_files' => 1, // 跳过小于10KB的文件
'backup_originals' => 0, // 是否备份原文件
);
}
/**
* 处理上传的图片
*/
public function process_uploaded_image($metadata, $attachment_id) {
// 检查是否启用转换
if (!$this->options['enable_conversion']) {
return $metadata;
}
$file_path = get_attached_file($attachment_id);
if (!file_exists($file_path)) {
return $metadata;
}
// 获取文件信息
$file_info = pathinfo($file_path);
$mime_type = get_post_mime_type($attachment_id);
// 检查是否为支持的图片类型(排除SVG和ICO,这些不需要转换为WebP)
if (!$this->is_supported_for_webp_conversion($mime_type)) {
return $metadata;
}
// 获取文件大小
$file_size = filesize($file_path);
// 跳过过小的文件
if ($this->options['skip_small_files'] && $file_size < 10240) { // 10KB
return $metadata;
}
try {
// 备份原文件(如果启用)
if ($this->options['backup_originals']) {
$this->backup_original($file_path);
}
// 处理主图片
$webp_path = $this->convert_to_webp($file_path, $file_size);
if ($webp_path) {
// 更新附件文件路径
update_attached_file($attachment_id, $webp_path);
// 处理所有缩略图尺寸
if (isset($metadata['sizes']) && is_array($metadata['sizes'])) {
$upload_dir = wp_upload_dir();
$base_dir = dirname($file_path);
foreach ($metadata['sizes'] as $size => &$size_data) {
$thumb_path = $base_dir . '/' . $size_data['file'];
if (file_exists($thumb_path)) {
$thumb_size = filesize($thumb_path);
$thumb_webp_path = $this->convert_to_webp($thumb_path, $thumb_size);
if ($thumb_webp_path) {
$size_data['file'] = basename($thumb_webp_path);
$size_data['mime-type'] = 'image/webp';
// 删除原缩略图
if ($this->options['delete_originals']) {
@unlink($thumb_path);
}
}
}
}
}
// 更新元数据
$metadata['file'] = str_replace($upload_dir['basedir'] . '/', '', $webp_path);
// 删除原主图片
if ($this->options['delete_originals']) {
@unlink($file_path);
}
// 记录转换信息
add_post_meta($attachment_id, '_awio_converted', 1);
add_post_meta($attachment_id, '_awio_original_size', $file_size);
add_post_meta($attachment_id, '_awio_webp_size', filesize($webp_path));
}
} catch (Exception $e) {
// 记录错误日志
error_log('Auto WebP Optimizer Error: ' . $e->getMessage());
}
return $metadata;
}
/**
* 转换图片为WebP格式
*/
private function convert_to_webp($source_path, $file_size) {
$path_info = pathinfo($source_path);
$webp_path = $path_info['dirname'] . '/' . $path_info['filename'] . '.webp';
// 根据文件大小确定质量
$quality = $this->get_quality_by_size($file_size);
// 尝试使用GD库
if ($this->convert_with_gd($source_path, $webp_path, $quality)) {
return $webp_path;
}
// 尝试使用Imagick
if ($this->convert_with_imagick($source_path, $webp_path, $quality)) {
return $webp_path;
}
return false;
}
/**
* 使用GD库转换
*/
private function convert_with_gd($source_path, $webp_path, $quality) {
if (!function_exists('imagewebp')) {
return false;
}
$mime_type = mime_content_type($source_path);
$image = false;
switch ($mime_type) {
case 'image/jpeg':
case 'image/jpg':
$image = imagecreatefromjpeg($source_path);
break;
case 'image/png':
$image = imagecreatefrompng($source_path);
// 保持透明度
imagepalettetotruecolor($image);
imagealphablending($image, true);
imagesavealpha($image, true);
break;
case 'image/gif':
$image = imagecreatefromgif($source_path);
break;
case 'image/bmp':
if (function_exists('imagecreatefrombmp')) {
$image = imagecreatefrombmp($source_path);
} else {
// 如果GD不支持BMP,尝试转换
return false;
}
break;
case 'image/webp':
if (function_exists('imagecreatefromwebp')) {
$image = imagecreatefromwebp($source_path);
}
break;
case 'image/tiff':
case 'image/tif':
// GD通常不直接支持TIFF,返回false让Imagick处理
return false;
break;
}
if (!$image) {
return false;
}
// 调整尺寸(如果需要)
$image = $this->resize_image($image);
// 转换为WebP
$result = imagewebp($image, $webp_path, $quality);
imagedestroy($image);
return $result;
}
/**
* 使用Imagick转换
*/
private function convert_with_imagick($source_path, $webp_path, $quality) {
if (!class_exists('Imagick')) {
return false;
}
try {
$imagick = new Imagick($source_path);
// 调整尺寸(如果需要)
$this->resize_imagick($imagick);
// 设置WebP格式和质量
$imagick->setImageFormat('webp');
$imagick->setImageCompressionQuality($quality);
$imagick->stripImage(); // 移除EXIF数据
// 写入文件
$result = $imagick->writeImage($webp_path);
$imagick->destroy();
return $result;
} catch (Exception $e) {
return false;
}
}
/**
* 根据文件大小获取质量参数
*/
private function get_quality_by_size($file_size) {
$size_mb = $file_size / (1024 * 1024);
if ($size_mb > 2.5) {
return $this->options['quality_xlarge'];
} elseif ($size_mb > 1) {
return $this->options['quality_large'];
} elseif ($size_mb > 0.2) {
return $this->options['quality_medium'];
} else {
return $this->options['quality_small'];
}
}
/**
* 调整GD图片尺寸
*/
private function resize_image($image) {
$width = imagesx($image);
$height = imagesy($image);
$max_width = $this->options['max_width'];
$max_height = $this->options['max_height'];
if ($width <= $max_width && $height <= $max_height) {
return $image;
}
// 计算新尺寸
$ratio = min($max_width / $width, $max_height / $height);
$new_width = (int)($width * $ratio);
$new_height = (int)($height * $ratio);
// 创建新图片
$new_image = imagecreatetruecolor($new_width, $new_height);
// 保持透明度(PNG)
imagealphablending($new_image, false);
imagesavealpha($new_image, true);
$transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
imagefilledrectangle($new_image, 0, 0, $new_width, $new_height, $transparent);
// 调整尺寸
imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
imagedestroy($image);
return $new_image;
}
/**
* 调整Imagick图片尺寸
*/
private function resize_imagick($imagick) {
$width = $imagick->getImageWidth();
$height = $imagick->getImageHeight();
$max_width = $this->options['max_width'];
$max_height = $this->options['max_height'];
if ($width <= $max_width && $height <= $max_height) {
return;
}
// 计算新尺寸
$ratio = min($max_width / $width, $max_height / $height);
$new_width = (int)($width * $ratio);
$new_height = (int)($height * $ratio);
$imagick->resizeImage($new_width, $new_height, Imagick::FILTER_LANCZOS, 1);
}
/**
* 备份原文件
*/
private function backup_original($file_path) {
$backup_dir = dirname($file_path) . '/awio_backup';
if (!is_dir($backup_dir)) {
wp_mkdir_p($backup_dir);
}
$backup_path = $backup_dir . '/' . basename($file_path);
copy($file_path, $backup_path);
}
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_options_page(
'Auto WebP Optimizer Settings',
'WebP Optimizer',
'manage_options',
'auto-webp-optimizer',
array($this, 'admin_page')
);
}
/**
* 初始化管理设置
*/
public function admin_init() {
register_setting(
'awio_settings',
'awio_options',
array($this, 'sanitize_options')
);
// 基本设置区块
add_settings_section(
'awio_basic_settings',
'基本设置',
array($this, 'basic_settings_callback'),
'awio_settings'
);
// 质量设置区块
add_settings_section(
'awio_quality_settings',
'质量设置',
array($this, 'quality_settings_callback'),
'awio_settings'
);
// 添加设置字段
$this->add_settings_fields();
}
/**
* 添加设置字段
*/
private function add_settings_fields() {
// 基本设置字段
add_settings_field(
'enable_conversion',
'启用WebP转换',
array($this, 'checkbox_field_callback'),
'awio_settings',
'awio_basic_settings',
array('name' => 'enable_conversion')
);
add_settings_field(
'rename_files',
'自动重命名文件',
array($this, 'checkbox_field_callback'),
'awio_settings',
'awio_basic_settings',
array('name' => 'rename_files', 'description' => '上传时自动将文件名改为日期时间格式')
);
add_settings_field(
'delete_originals',
'删除原文件',
array($this, 'checkbox_field_callback'),
'awio_settings',
'awio_basic_settings',
array('name' => 'delete_originals')
);
add_settings_field(
'skip_small_files',
'跳过小文件(<10KB)',
array($this, 'checkbox_field_callback'),
'awio_settings',
'awio_basic_settings',
array('name' => 'skip_small_files')
);
add_settings_field(
'backup_originals',
'备份原文件',
array($this, 'checkbox_field_callback'),
'awio_settings',
'awio_basic_settings',
array('name' => 'backup_originals')
);
// 质量设置字段
add_settings_field(
'quality_small',
'小文件质量(<200KB)',
array($this, 'number_field_callback'),
'awio_settings',
'awio_quality_settings',
array('name' => 'quality_small', 'min' => 1, 'max' => 100)
);
add_settings_field(
'quality_medium',
'中等文件质量(200KB-1MB)',
array($this, 'number_field_callback'),
'awio_settings',
'awio_quality_settings',
array('name' => 'quality_medium', 'min' => 1, 'max' => 100)
);
add_settings_field(
'quality_large',
'大文件质量(1MB-2.5MB)',
array($this, 'number_field_callback'),
'awio_settings',
'awio_quality_settings',
array('name' => 'quality_large', 'min' => 1, 'max' => 100)
);
add_settings_field(
'quality_xlarge',
'超大文件质量(>2.5MB)',
array($this, 'number_field_callback'),
'awio_settings',
'awio_quality_settings',
array('name' => 'quality_xlarge', 'min' => 1, 'max' => 100)
);
add_settings_field(
'max_width',
'最大宽度(像素)',
array($this, 'number_field_callback'),
'awio_settings',
'awio_quality_settings',
array('name' => 'max_width', 'min' => 100, 'max' => 5000)
);
add_settings_field(
'max_height',
'最大高度(像素)',
array($this, 'number_field_callback'),
'awio_settings',
'awio_quality_settings',
array('name' => 'max_height', 'min' => 100, 'max' => 5000)
);
}
/**
* 管理页面
*/
public function admin_page() {
?>
<div class="wrap">
<h1>Auto WebP Image Optimizer 设置</h1>
<?php if (!$this->check_requirements()): ?>
<div class="notice notice-error">
<p><strong>警告:</strong>您的服务器不支持WebP格式。请确保GD或Imagick扩展已安装并支持WebP。</p>
</div>
<?php endif; ?>
<form method="post" action="options.php">
<?php
settings_fields('awio_settings');
do_settings_sections('awio_settings');
submit_button('保存设置');
?>
</form>
<div class="awio-stats">
<h3>统计信息</h3>
<?php $this->display_stats(); ?>
</div>
<div class="awio-info">
<h3>支持的图片格式</h3>
<p><strong>可重命名的格式:</strong> JPEG, JPG, PNG, GIF, BMP, WebP, TIFF, TIF, SVG, ICO</p>
<p><strong>可转换为WebP的格式:</strong> JPEG, JPG, PNG, GIF, BMP, TIFF, TIF, WebP</p>
<p><strong>文件命名格式:</strong> YYYY-MM-DD-HHMMSS (如: 2025-09-18-195314.jpg)</p>
</div>
</div>
<style>
.awio-stats, .awio-info {
margin-top: 30px;
padding: 15px;
background: #f1f1f1;
border-radius: 5px;
}
.awio-info {
background: #e7f3ff;
border-left: 4px solid #2196f3;
}
.description {
font-style: italic;
color: #666;
margin-top: 5px;
}
</style>
<?php
}
/**
* 显示统计信息
*/
private function display_stats() {
global $wpdb;
$converted_count = $wpdb->get_var("
SELECT COUNT(*)
FROM {$wpdb->postmeta}
WHERE meta_key = '_awio_converted'
");
$total_original_size = $wpdb->get_var("
SELECT SUM(meta_value)
FROM {$wpdb->postmeta}
WHERE meta_key = '_awio_original_size'
");
$total_webp_size = $wpdb->get_var("
SELECT SUM(meta_value)
FROM {$wpdb->postmeta}
WHERE meta_key = '_awio_webp_size'
");
$saved_bytes = $total_original_size - $total_webp_size;
$saved_percentage = $total_original_size > 0 ? round(($saved_bytes / $total_original_size) * 100, 1) : 0;
echo "<p><strong>已转换图片:</strong> {$converted_count} 张</p>";
echo "<p><strong>原始大小:</strong> " . size_format($total_original_size) . "</p>";
echo "<p><strong>压缩后大小:</strong> " . size_format($total_webp_size) . "</p>";
echo "<p><strong>节省空间:</strong> " . size_format($saved_bytes) . " ({$saved_percentage}%)</p>";
}
/**
* 设置区块回调
*/
public function basic_settings_callback() {
echo '<p>配置WebP转换的基本选项</p>';
}
public function quality_settings_callback() {
echo '<p>根据文件大小设置不同的压缩质量</p>';
}
/**
* 复选框字段回调
*/
public function checkbox_field_callback($args) {
$name = $args['name'];
$value = isset($this->options[$name]) ? $this->options[$name] : 0;
$description = isset($args['description']) ? $args['description'] : '';
echo "<input type='checkbox' name='awio_options[{$name}]' value='1' " . checked(1, $value, false) . " />";
if (!empty($description)) {
echo "<p class='description'>{$description}</p>";
}
}
/**
* 数字字段回调
*/
public function number_field_callback($args) {
$name = $args['name'];
$value = isset($this->options[$name]) ? $this->options[$name] : '';
$min = isset($args['min']) ? $args['min'] : 1;
$max = isset($args['max']) ? $args['max'] : 100;
echo "<input type='number' name='awio_options[{$name}]' value='{$value}' min='{$min}' max='{$max}' />";
}
/**
* 选项验证
*/
public function sanitize_options($input) {
$sanitized = array();
// 布尔值字段
$bool_fields = array('enable_conversion', 'delete_originals', 'skip_small_files', 'backup_originals', 'rename_files');
foreach ($bool_fields as $field) {
$sanitized[$field] = isset($input[$field]) ? 1 : 0;
}
// 数字字段
$number_fields = array(
'quality_small' => array('min' => 1, 'max' => 100),
'quality_medium' => array('min' => 1, 'max' => 100),
'quality_large' => array('min' => 1, 'max' => 100),
'quality_xlarge' => array('min' => 1, 'max' => 100),
'max_width' => array('min' => 100, 'max' => 5000),
'max_height' => array('min' => 100, 'max' => 5000),
);
foreach ($number_fields as $field => $limits) {
$value = isset($input[$field]) ? intval($input[$field]) : $this->options[$field];
$sanitized[$field] = max($limits['min'], min($limits['max'], $value));
}
// 保持其他选项
$sanitized['supported_types'] = $this->options['supported_types'];
return $sanitized;
}
}
// 初始化插件
new AutoWebPImageOptimizer();
// 批量转换现有图片的WP-CLI命令(可选)
if (defined('WP_CLI') && WP_CLI) {
class AWIO_CLI_Command {
/**
* 批量转换现有图片为WebP格式
*
* ## OPTIONS
*
* [--limit=<number>]
* : 限制处理图片数量
*
* [--force]
* : 强制转换已转换的图片
*
* ## EXAMPLES
*
* wp awio convert --limit=100
* wp awio convert --force
*/
public function convert($args, $assoc_args) {
$limit = isset($assoc_args['limit']) ? intval($assoc_args['limit']) : 50;
$force = isset($assoc_args['force']);
global $wpdb;
// 查询图片附件
$meta_query = '';
if (!$force) {
$meta_query = "AND p.ID NOT IN (
SELECT post_id FROM {$wpdb->postmeta}
WHERE meta_key = '_awio_converted'
)";
}
$attachments = $wpdb->get_results($wpdb->prepare("
SELECT p.ID
FROM {$wpdb->posts} p
WHERE p.post_type = 'attachment'
AND p.post_mime_type IN ('image/jpeg', 'image/png', 'image/gif')
{$meta_query}
LIMIT %d
", $limit));
if (empty($attachments)) {
WP_CLI::success('没有找到需要转换的图片。');
return;
}
$optimizer = new AutoWebPImageOptimizer();
$progress = WP_CLI\Utils\make_progress_bar('Converting images', count($attachments));
foreach ($attachments as $attachment) {
$metadata = wp_get_attachment_metadata($attachment->ID);
if ($metadata) {
// 使用私有方法处理图片
$reflection = new ReflectionClass($optimizer);
$method = $reflection->getMethod('process_uploaded_image');
$method->setAccessible(true);
$method->invoke($optimizer, $metadata, $attachment->ID);
}
$progress->tick();
}
$progress->finish();
WP_CLI::success(sprintf('成功处理 %d 张图片。', count($attachments)));
}
}
WP_CLI::add_command('awio', 'AWIO_CLI_Command');
}
评论前必须登录!
注册