如何删除所有未使用的照片功能

时间:2013-12-20 作者:Liviu ZeJah

我现在的问题是:我与Woo Commerce一起运行WordPress网站,每隔几天我就会刷新产品列表,一次删除和导入8000多个产品。

现在,每次我从数据库中删除+/-3500个产品时,我都必须删除每个产品的照片和缩略图。。所以我必须删除12000多张照片。

使用任何插件都不是一个选项,它们都会冻结/停止工作,所以我需要构建自己的/功能或插件,我需要一个起点。

我有一个旧产品的列表,我将其删除如下:

foreach($old_product_list as $oldproduct){

    $wpdb->show_errors();
    $delq = $wpdb->get_results(
                     "  DELETE a,b,c
                        FROM wp_posts a
                        LEFT JOIN wp_term_relationships b ON ( a.ID = b.object_id ) 
                        LEFT JOIN wp_postmeta c ON ( a.ID = c.post_id ) 
                        LEFT JOIN wp_term_taxonomy d ON ( d.term_taxonomy_id = b.term_taxonomy_id ) 
                        LEFT JOIN wp_terms e ON ( e.term_id = d.term_id )                    
                        WHERE a.post_title=\'".$mysqli->real_escape_string($oldproduct[\'name\'])."\' " );  
[……]

1 个回复
SO网友:adelval

通常,我建议您在修改数据库时尽量使用Wordpress的核心功能,因为它们会自动处理关联数据,例如删除关联的post meta、关联的分类信息等。(Woocommerce将产品图像数据存储为product post\\u meta,详情见下文。)与直接访问数据库相比,这可能会减慢速度,但结果是数据库会更干净。

不用说,在尝试任何操作之前,请备份您的数据库。。。

首先,您需要使用post ID。

global $wpdb;
foreach ($old_product_list as $old_product) {
   $prod_names[] = $mysqli->real_escape_string($oldproduct[\'name\']);
}

$prod_ids = $wpdb->get_results($wpdb->prepare("
                 SELECT ID FROM {$wpdb->prefix}posts 
                 WHERE post_type=\'product\' AND post_title IN (%s)",
                 explode(\',\',$prod_names)));
现在,按照“破坏性”的递增顺序,您可能需要删除三种不同的内容:

删除products post\\u meta中对图像ID的引用删除与每个图像相关的“附件”帖子-这将从Wordpress媒体库中删除图像从服务器中删除实际的图像文件Point 1. 这个很简单。但是要做到这一点,您需要使用wordpress函数,正如代码注释所希望说明的那样。

foreach ($prod_ids as $id) {
    // This will also remove all post_meta associated to the product
    // and apply any delete_post filters added by Woocommerce or other plugins
    // Second arg forces deletion, bypassing the trash
    wp_delete_post($id,true); 
} 

Points 2 and 3, simple case.

如果您的图像对于每个产品都是唯一的,并且没有从任何地方链接,则其post\\u父级将是product\\u id,因此您可以使用此版本的https://wordpress.stackexchange.com/a/109803/40965, 修改为绕过垃圾:

function delete_product_attachments($id) {
    if (\'product\' !== get_post_type($id)) return;

    $media = get_children(array(
        \'post_parent\' => $id,
        \'post_type\' => \'attachment\'
    ));

    foreach ($media as $img) {
        unlink(get_attached_file($img->ID)); //delete files from server
        wp_delete_attachment($img->ID,true); //force post deletion, bypassing trash
    }
}

add_action(\'before_delete_post\',\'delete_product_attachments\');
最后一行确保每当调用wp\\u delete\\u post时都会调用此函数,因此不需要将解决方案更改为上面的第1点。

Points 2 and 3, general case. 如果一些图片在产品之间共享(其中一些可能没有在当前批次中删除),或者从其他帖子链接,上述解决方案将打破现状。

这里是我们需要了解Woocommerce如何处理产品图像的地方。与产品关联的图像存储为产品的post\\u meta“\\u thumbnail\\u id”和“\\u product\\u image\\u gallery”。_thumbnail_id 是图像的post\\u id(post with post\\u type=\'attachment\');_product_image_gallery 是以逗号分隔的图像帖子ID字符串。

首先,这里是如何处理所有附件帖子ID的方法。

$image_ids = $wpdb->get_col($wpdb->prepare("
                 SELECT meta_value FROM {$wpdb->prefix}post_meta
                  WHERE meta_key = \'_thumbnail_id\' AND post_id in (%s)",
                 explode(\',\',$prod_ids)));
$gallery_ids = $wpdb->get_col($wpdb->prepare("
                 SELECT meta_value FROM {$wpdb->prefix}post_meta
                  WHERE meta_key = \'_product_image_gallery\' AND post_id in (%s)",
                 explode(\',\',$prod_ids)));

$gallery_ids = explode(\',\',$gallery_ids); //get all ids in a single string
$gallery_ids = array_unique(implode(\',\',$gallery_ids));
$image_ids = array_merge($image_ids,$gallery_ids);
//do something with all $image_ids
困难的部分来了:将上述解决方案仅应用于可以安全删除的图像。

结束

相关推荐

Plugins_url函数混合了系统路径和URL

在我的WordPress小部件中,我使用以下代码:wp_register_script(\'jquery-ui.widget\', plugins_url(\'assets/js/jquery-ui-1.9.2.widget.js\', dirname( __FILE__ ))); 不幸的是,代码给了我一个无效的URL,它与我的系统路径混合在一起:http://test.dev/wp-content/plugins/C:/projects/wordpress/plugins/assets/js/