Intereting Posts
Почему update_post_meta не работает для определенных строк? Как исправить неинициализированное смещение строки: ошибка на флажке в WP Settings API Тема удалила ссылку «Редактировать сообщение» на лицевой стороне. Я хочу вернуться Двойной бар «|» в заголовке (по WP SEO Yoast?) отображение виджета на флажке Как скрыть <h2>, если появляется <h1> Разбор короткого кода по-разному основан на том, что он вложен в Как получить URL-адрес изображения определенного размера? Как запустить JS, PHP и т. Д. Внутри WP-сообщения? Укажите пользовательский путь загрузки только для настраиваемого типа сообщений? wp_remote_get () и javascript / noscript ситуация Атрибут категории не работает в пользовательском коротком коде Как WordPress манипулирует сообщениями, как есть папки? Применение шаблонов и принципов OO для разработки плагинов Шаблон для регулярных сообщений (без пользовательских типов сообщений)

Как удалить все неиспользуемые фотографии Функция

У меня есть текущая проблема: я запускаю веб-сайт WordPress с Woo Commerce, и каждые несколько дней я обновляю список продуктов, удаляя и импортируя более 8000 продуктов за раз.

Теперь, каждый раз, когда я получаю +/- 3500 продуктов, удаленных из базы данных, поэтому мне нужно удалить фотографии и миниатюры для каждого из них. Поэтому мне нужно удалить более 12 000 фотографий.

Использование любого плагина не является вариантом, все они замораживаются / останавливаются, поэтому мне нужно создать свою собственную / функцию или плагин, и мне нужна начальная точка.

У меня есть список со старыми продуктами, и я их удаляю следующим образом:

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'])."' " ); 

[…..]

Solutions Collecting From Web of "Как удалить все неиспользуемые фотографии Функция"

Как правило, я предлагаю вам попытаться максимально использовать основные функции WordPress при изменении базы данных, поскольку они будут обрабатывать связанные данные автоматически – например, удалять связанную мета-запись, соответствующую информацию о таксономии и т. Д. (Woocommerce хранит данные изображения продукта как продукт post_meta, подробнее см. ниже.) Это может замедлить работу по сравнению с прямым доступом к базе данных, но в результате база данных будет намного чище.

Излишне говорить, что делайте резервное копирование своей базы данных, прежде чем пытаться это сделать …

Во-первых, вам нужно работать с идентификаторами сообщений.

 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))); 

Теперь есть три разные вещи, которые вы можете удалить, в порядке возрастания «деструктивности»:

  1. Удалить ссылки на идентификаторы изображений в продуктах post_meta
  2. Удалите записи «вложения», связанные с каждым изображением, – это приведет к удалению изображений из медиафайла WordPress. Галерея
  3. Удаление фактических файлов изображений с сервера

Пункт 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); } 

Очки 2 и 3, простой случай.

Если ваши изображения уникальны для каждого продукта и не связаны нигде, их post_parent будет product_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_delete_post, поэтому вам не нужно менять решение на пункт 1 выше.

Пункты 2 и 3, общий случай. Если некоторые изображения разделяются между продуктами (некоторые из которых, возможно, не удалены в текущей партии) или связаны с другими сообщениями, вышеупомянутое решение нарушит работу.

Здесь мы должны понимать, как Woocommerce обрабатывает изображения продуктов. Изображения, связанные с продуктом, хранятся как post_meta '_thumbnail_id' и '_product_image_gallery' для идентификатора почты продукта. _thumbnail_id – это post_id изображения (сообщение с post_type = 'attachment'); _product_image_gallery – это строка с идентификаторами сообщений, разделенная запятыми.

Чтобы начать работу, вот как получить все идентификаторы сообщений прикрепления для обработки.

 $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 

И вот сложная часть: примените решение выше только к изображениям, которые можно безопасно удалить.