Обработка большого количества документов на слабом хостинге

Иногда возникает необходимость обработать сразу большое количество ресурсов, например вдруг решили, что у всех отзывов должен быть URL /review-25.html (у каждого свой id), а сейчас на сайте около 200 отзывов и у них URL формировались обычным translit'ом (ну или не совсем обычным))). Все бы ничего, да вот хостинг слабенький и на нем жестко прописано ограничение на время выполнения скрипта. И максимальное количество документов, которые успевают обработаться — 10-15.

Можно, конечно как-то оптимизировать скрипт, например, не использовать процессоры, можно вносить изменения прямо в базу через phpMyAdmin, можно запускать скрипт 20 раз вручную, пока не обработаются все ресурсы… Каждый выбирает сам.

Для себя я сделал сниппет для пошаговой работы php-скрипта, который вполне может обрабатывать и ресурсы MODX.

Итак, создаем страницу, на которой и будем вызывать наш скрипт.

В корень кладем файлики scriptoffset.css и scriptoffset.js. В файле scriptoffset.js меняем bfmn.ru/scriptoffset/scriptoffset.php на адрес своей странички.

И создаем сниппет ScriptOffset:
<?php
// Отвечаем только на Ajax
if ($_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {return;}

// Можно передавать в скрипт разный action и выполнять разные действия.
$action = $_POST['action'];
if (empty($action)) {return;}

// Получаем от клиента номер итерации
$url = $_POST['url']; if (empty($url)) return;
$offset = $_POST['offset'] ? (int) $_POST['offset'] : 0;
$limit = 10;

// Составляем список ресурсов для обработки в текущей итерации
$q = $modx->newQuery('modResource', array('parent' => 45));

// Узнаем, сколько всего ресурсов
$count = $modx->getCount('modResource', $q);

// Обрабатываем только часть, пропуская уже обработанные
$q->limit($limit,$offset);

$q->prepare();
$q->stmt->execute();
$res = $q->stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($res as $v) {
    $properties = array(
        'id' => $v['modResource_id']
      , 'context_key' => 'web'
      );
    
    // Теперь можно, напирмер, поменять псевдоним ресурса
    $properties['alias'] = $url.'-'.$v['modResource_id'];
    $response = $modx->runProcessor('resource/update', $properties);
}

// Проверяем, все ли строки обработаны
$offset = $offset + $limit;
if ($offset >= $count) {
    $sucsess = 1;
} else {
    $sucsess = round($offset / $count, 2);
}

// И возвращаем клиенту данные (номер итерации и сообщение об окончании работы)
$output = Array('offset' => $offset, 'sucsess' => $sucsess);
echo json_encode($output);
die();
(спасибо bezumkin за решение)

45 — это id ресурса-родителя всех отзывов. В поле на странице пишем, например, review и нажимаем «Старт». Если прогресс-бар ползет медленно, можете приостановить выполнение скрипта, посмотреть результаты, а потом продолжить с того же места (offset пишется в куки на 10 минут).

После того, как прогресс-бар достигнет 100% все ресурсы с родителем 45 будут иметь URL review-{id}.html

Так как за редактирование ресурса у нас отвечает процессор, то больше никаких действий делать нам будет не нужно. G+

0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.