你可能遇到了这样的一种情况,需要从别的不知名系统导入产品到 wordpress 的 woocommerce,有产品的源图片包,已经把产品数据写入了现有系统,现在需要给产品数据新增首图。下面的处理可以帮助你完成这一工作。
(wp 6.5.5, wc 8.9.3, 导入产品使用的插件 WP All Import, 插件高级版本提供了图片的选项,但是我没有深入测试)

  1. 将产品图片文件放到 wp 的上传目录中,比如 /wp-content/uploads/oldimg/
  2. 根据源数据中产品唯一标记(eg:sku),整理出产品图片的写入数据,在 wp 中资源文件也是记录在 wp_posts 中的,

    INSERT INTO `wp_posts`(`post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_status`, `comment_status`, `ping_status`,  `post_name`,  `post_modified`, 
     `post_modified_gmt`, `guid`, `post_type`, `post_mime_type`) VALUES
     (1,'2024-07-02 14:06:03', '2024-07-02 06:06:03', 'pid', 'reactor', 'inherit', 'open', 'closed', 'reactor', '2024-06-22 14:06:03', '2024-06-22 06:06:03', 'url', 'attachment', 'image/png')

    这条语句中,我把 pid 作为标记存在图片帖子的 content 中,后面好做数据处理,url 填入图片的完整链接地址, post_mime_type 需要注意图片的类型,其他字段按照示例值,此外这个语句中还有几个字段需要给出默认值,这里没写,可以直接给 ''.

  3. 这里给 wc 的产品写入主图,wc 的产品在 wp_postmeta 中对应的 post_id 有一个名为 _thumbnail_id 的 meta_key,meta_value 对应的则是图片帖子的 ID.

    INSERT INTO `wp_postmeta`(`post_id`, `meta_key`, `meta_value`) 
    SELECT id, '_thumbnail_id', mid from 
    (SELECT ID FROM `wp_posts` WHERE post_type = 'product' and post_status = 'publish') as p left join 
    (select ID as mid, post_content FROM `wp_posts` where post_type = 'attachment' and id > 8710) as m on m.post_content = p.id

    需要注意添加额外条件确定执行 sql 的范围,这个按照实际情况来咯,比如这里的 id > 8710

  4. 好,当你完成上述步骤,想着图片帖子写入,wc 的 meta 数据也已映射,这下子是不是就可以看到产品图片完完整整的 show 出来了呢,呵呵,白高兴。因为 wp 在处理图片的时候,给图片分了不同的尺寸大小,所以图片帖子也有自己的 meta 数据,这里发现是每个两条。先处理第一条 meta.

    INSERT INTO `wp_postmeta`(`post_id`, `meta_key`, `meta_value`) 
    SELECT ID, '_wp_attached_file', SUBSTRING_INDEX(guid, '/wp-content/uploads/', -1) AS fname FROM `wp_posts` WHERE ID > 8710

    这里需要给图片的 posts 写入一条 meta_key = '_wp_attached_file' 的数据,value 是图片 url (字段为 guid) 在 uploads 下的相对路径,这里也记得给 sql 添加边界。

  5. 第二条 meta 需要用到 wp 的处理,可以将代码加到主题 func 中,执行一次:

    include( ABSPATH . 'wp-admin/includes/image.php' );
    
    $star = 8711;
    for ($i = 0; $i < 542; $i++) {
     $id = $star + $i;
     if ($id < 9131) {
         continue;
     }
     $thumbnail_url = wp_get_attachment_url($id);
     if (!$thumbnail_url) {
         continue;
     }
     $metadata = wp_generate_attachment_metadata($id, $thumbnail_url);
     wp_update_attachment_metadata($id, $metadata);
    }

    好了,现在应该就可以看到图片了。至此,你也应该知道 wp 为啥这样臃肿了吧。
    mysql 大小写不敏感,上面的语句中有些没区分大小写,你写的时候可以在意下。