自动下载文章中的所有远程图片,并将它们保存到本地

错误信息表明 wp_generate_attachment_metadata 函数未定义。这是因为在 WordPress 中,wp_generate_attachment_metadata 函数位于 wp-admin/includes/image.php 文件中,而这个文件默认不会在插件或主题中自动加载。


解决方法

在调用 wp_generate_attachment_metadata 之前,需要手动引入 wp-admin/includes/image.php 文件。以下是修复后的代码:

php
复制
<?php
/*
Plugin Name: MY Auto Save Remote Image
Plugin URI: http://www.devsaab.com/wordpress/
Description: This plugin automatically downloads all remote images from a post and saves them locally.
Version: 1.4
Author: Prebhdev Singh
Disclaimer: No warranty or guarantee of any kind! Use this at your own risk.
*/

add_action('publish_post', 'fetch_images');

function fetch_images($post_ID) {
    // 检查是否正在自动保存
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    // 检查用户权限
    if (!current_user_can('edit_post', $post_ID)) {
        return;
    }

    // 引入 WordPress 图像处理函数
    require_once(ABSPATH . 'wp-admin/includes/image.php');

    // 获取文章内容
    $post = get_post($post_ID);
    $updated = $post->post_content;

    // 提取所有图片 URL
    if (preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches)) {
        $first_images = $matches[1];

        foreach ($first_images as $first_image) {
            // 检查图片域名是否与当前站点一致
            if (strpos($first_image, $_SERVER['HTTP_HOST']) === false) {
                // 处理 HTTPS
                $first_image = str_replace('http://', 'https://', $first_image);

                // 下载图片
                $get = wp_remote_get($first_image);
                if (!is_wp_error($get)) {
                    $type = wp_remote_retrieve_header($get, 'content-type');
                    if (strpos($type, 'image') === false) {
                        continue; // 如果不是图片,跳过
                    }

                    // 生成唯一文件名
                    $filename = wp_unique_filename(wp_upload_dir()['path'], rawurldecode(basename($first_image)));

                    // 保存图片
                    $mirror = wp_upload_bits($filename, '', wp_remote_retrieve_body($get));

                    if (!$mirror['error']) {
                        // 创建附件
                        $attachment = array(
                            'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
                            'post_mime_type' => $type
                        );
                        $attach_id = wp_insert_attachment($attachment, $mirror['file'], $post_ID);

                        if (!is_wp_error($attach_id)) {
                            // 生成附件元数据并更新
                            $attach_data = wp_generate_attachment_metadata($attach_id, $mirror['file']);
                            wp_update_attachment_metadata($attach_id, $attach_data);

                            // 替换文章中的图片 URL
                            $updated = str_replace($first_image, $mirror['url'], $updated);
                        }
                    } else {
                        error_log('Failed to save image: ' . $first_image);
                    }
                } else {
                    error_log('Failed to download image: ' . $first_image);
                }
            }
        }

        // 更新文章内容
        if ($updated !== $post->post_content) {
            wp_update_post(array('ID' => $post_ID, 'post_content' => $updated));
        }
    }
}
?>

关键修复点

  1. 引入 wp-admin/includes/image.php

    • 在函数开头添加以下代码:

      php
      复制
      require_once(ABSPATH . 'wp-admin/includes/image.php');
    • 这确保了 wp_generate_attachment_metadata 函数可用。

  2. 确保文件路径正确

    • ABSPATH 是 WordPress 根目录的绝对路径,确保路径拼接正确。


测试步骤

  1. 将修复后的代码保存为 my-auto-save-remote-image.php

  2. 上传到 WordPress 的 wp-content/plugins/ 目录。

  3. 在 WordPress 后台激活插件。

  4. 发布一篇包含远程图片的文章,检查插件是否正常工作。


注意事项

  1. 权限问题

    • 确保 WordPress 的上传目录(wp-content/uploads)有正确的写权限。

  2. HTTPS 支持

    • 如果远程图片使用 HTTPS,确保服务器支持 HTTPS 请求。

  3. 性能监控

    • 如果文章中有大量图片,可能会影响发布速度,建议监控服务器性能。

This entry was posted in 网络相关. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *