WordPress как на ладони
Наставник Трепачёв Д.П., phphtml.net wordpress jino

Очень много данных: удаление всех постов и принадлежащих им категорий

Суть вопроса токова: Нужно удалить все категории, и их посты. Кроме категории с id 1 (и его посты не нужно трогать.

Написал скрипт:

<?php
 global $db;

 $db = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
 if(!empty($db->error)) wp_die($db->error);

 $results = $db->get_results("SELECT `term_id` FROM `wp_terms` WHERE `term_id` > 1");
 for($i = 0; $i < count($results); $i++){
  $arg[] = $results[$i]->term_id;
 }
 for($j = 0; $j < count($arg); $j++){
  $results = $db->get_results("SELECT `object_id` FROM `wp_term_relationships` WHERE `term_taxonomy_id` = $arg[$j]");
  $args[] = $results;
 }
 for($n = 0; $n < count($args); $n++){
  for($x = 0; $x < count($args[$n]); $x++){
   $argsx[] = $args[$n][$x]->object_id;
  }
 }
 if(is_array($argsx)){
  asort($argsx, SORT_NUMERIC);
 }
 for($n = 0; $n < count($argsx); $n++){
  wp_delete_post($argsx[$n], true);
 }

 for($i = 0; $i < count($arg); $i++){
  wp_delete_term($arg[$i], 'category');
 }
?>

Но он кладет базу и удаляет от силы 20 постов. Можно как-то оптимизировать запрос? Сайтов около 20, и в каждом до 30к постов.

Заранее спасибо!

0
literate_code 8 месяцев назад
  • 0
    Kama4477

    Тут наверное только разделением на несколько операций. Через JS и аякс пожалуй самое-то... Код писать время нет да и проверить не на чем... Объясню принцип пошагово.

    Напиши простой скрипт, который получает, 10 записей из всех рубрик кроме 1 и удаляет эти 10 записей. Используй get_posts(). Представим что мы запустил скрипт много раз и когда записей больше не осталось, скрипт начинает удалять уже по 20 рубрик, все кроме 1. В итоге когда-то этот скрипт удалит все что нужно...

    Делай все штатными функциями WordPress - так надежнее.

    Теперь, когда скрипт готов, посади это дело на AJAX чтобы руками его не запускать 100500 раз... И запускай уже через аякс: отправил первый аякс запрос, ВП обработал один раз, удалил 10 записей, вернул результат. Только результ. вернулся, еще раз такой же запрос и так далее пока не будет удалено все что нужно...

    Получится ты запускаешь один раз, а JS запускает скрипт много раз... Обычная процедура для обработки больших данных...

    Накидал быстро пример цикла аякса, как раз для тебя:

    <ul class="list"></ul>
    <input type="button" onclick="run_delete();" value="Go Get It!">
    
    <script>
    window.run_delete = function(){
    	// аякс запрос
    	$.post( ajaxurl, { action:'my_delete_all' }, function( result ){
    		// если все ок, продолжаем удаление
    		if( result ){
    			$('.list').append('<li>удалено: ' + data +'</li>');
    
    			run_delete(); // запускаем еще раз
    		}
    		else {
    			$('.list').append('<li>Все!</li>');
    		}
    	});
    }
    </script>

    Как это все в полный код собрать читай в статье про аякс.

    --

    Делай все это из под Админки, там аякс запросы использовать удобнее... В любой метабокс засунь запуск скрипта, например так.

    --

    П.С.

    Если будешь выполнять больше операций за раз, то:

    • На всякий можно увеличить макс. время выполнения PHP скрипта на сервере...

    • Также отключи объектный кэш на время выполнения скрипта (см. wp_suspend_cache_addition())...

    --

    П.П.С Готовым кодом если не сложно, то поделись кому-нить пригодится...

    Комментировать
  • 0
    campusboy1746 cайт: wp-plus.ru

    Я бы сделал так:
    1) Перед началом скрипта отключил кеширование запросов к БД
    2) Получил список Рубрик, кроме рубрики с ID 1
    3) Запускаю цикл полученных данных по рубрикам
    4) Получаю на каждой итерации все посты из одной рубрики и штатными методами их удаляю
    5) После прохождения всего массива включаю кеширование запросов обратно

    Я так делал обратную задача - добавление 100к постов. Без отключения кеширования запросов это нереально, а вот по такой схеме норм. И используя нативные функции для таких действий, вы реально удаляете всё (мета поля, комменты к статьям, мета для рубрик и остальной весь мусор).

    До начала операции надо выставить, чтобы скрипт мог работать более 30 секунд (обычно так по умолчанию). Если это сделать нельзя, то можно делать это по 1 рубрике, порядок действий не меняется, кроме 1 пунка - получать ID рубрик не надо, просто во 2 шаге по очереди их прописываем.

    literate_code 8 месяцев назад

    Спасибо за помощь, попробую тогда так.

    Kama 8 месяцев назад

    Под "Отключить кэширование" имеется ввиду использовать эту функцию wp_suspend_cache_addition() - вырубает кэш объектов...

    Но это нужно чтобы ошибки по недостатку памяти не было. А у тебя похоже время не хватает - оно и логично 30к постов удалить разом...

    Комментировать
На вопросы могут отвечать только зарегистрированные пользователи. Регистрация. Вход.