Очистка папки upload в Битрикс через агентa

Очистка папки upload в Битрикс через агентa

При использовании CMS Битрикс часто встает проблема увеличения объема находящихся на сервере файлов, что создает неудобства для администрации и пользователей сайта, может привести к техническим сбоям и даже полной неработоспособности ресурса. Причин проблемы может быть много. Это плодящиеся файлы кэша, бэкапы и многое другое. Мы поговорим о папке upload, в которой хранятся пользовательские файлы.

Итак, что это за папка и почему она разрастается? В папке upload Битрикса хранятся различные неисполняемые файлы, в основном изображения — например, файлы медиабиблиотеки. Но нас интересует вложенная в upload папка iblock. Она содержит изображения, прикрепленные к инфоблокам. В отличие от находящейся там же папки resize_cache, в которой содержится кэш отмасштабированных фотографий, и всю информацию из которой можно безболезненно стереть, здесь хранятся оригиналы фотографий. Если стереть изображение в ней, оно пропадет на сайте полностью.

Зачем из upload/iblock вообще что-то стирать? Дело в механизме Битрикса при работе с инфоблоками, а точнее их картинками. При прикреплении изображения к инфоблоку для картинки создается отдельная директория в папке iblock, в которую помещается картинка. Также создается запись в специальной таблице базы данных с путем к изображениям, по которой в дальнейшем она и ищется. Однако при удалении элемента инфоблока, Битрикс удаляет только запись из таблицы, а директория с изображениями остается на сервере.

Со временем изображения копятся и занимают значительный объем. Менеджеры по незнанию или лени не всегда обрабатывают загружаемые картинки, и они могут весить десятки мегабайт. Особенно остро проблема проявляется у динамичных сайтов с большим количеством информации, например, интернет-магазинов. Вот тут и встает вопрос очистки этой папки. Почему это так реализовано в Битриксе, и почему программисты должны лепить заплатки сами — не понятно, но примем как данность.

Предлагаемое решение построено на использовании агента, который будет каждые сутки чистить нашу папку. Это позволит забыть о проблеме.

Сделаем файл /bitrix/php_interface/includes/agents.php:

<?

function CleanUpUpload() {

    global $DB;

    define("NO_KEEP_STATISTIC", true);
    define("NOT_CHECK_PERMISSIONS", true);
    $deleteFiles = 'yes'; //Удалять ли найденые файлы yes/no
    $saveBackup = 'yes'; //Создаст бэкап файла yes/no
    //Папка для бэкапа
    $patchBackup = $_SERVER['DOCUMENT_ROOT'] . "/upload/iblock_Backup/";
    //Целевая папка для поиска файлов
    $rootDirPath = $_SERVER['DOCUMENT_ROOT'] . "/upload/iblock";

    $time_start = microtime(true);

    //Создание папки для бэкапа
    if (!file_exists($patchBackup)) {
        CheckDirPath($patchBackup);
    }
    // Получаем записи из таблицы b_file
    $arFilesCache = array();
    $result = $DB->Query('SELECT FILE_NAME, SUBDIR FROM b_file WHERE MODULE_ID = "iblock"');
    while ($row = $result->Fetch()) {
        $arFilesCache[$row['FILE_NAME']] = $row['SUBDIR'];
    }
    $hRootDir = opendir($rootDirPath);
    $count = 0;
    $contDir = 0;
    $countFile = 0;
    $i = 1;
    $removeFile=0;
    while (false !== ($subDirName = readdir($hRootDir))) {
        if ($subDirName == '.' || $subDirName == '..') {
            continue;
        }
        //Счётчик пройденых файлов
        $filesCount = 0;
        $subDirPath = "$rootDirPath/$subDirName"; //Путь до подкатегорий с файлами
        $hSubDir = opendir($subDirPath);
        while (false !== ($fileName = readdir($hSubDir))) {
            if ($fileName == '.' || $fileName == '..') {
                continue;
            }
            $countFile++;
            if (array_key_exists($fileName, $arFilesCache)) { //Файл с диска есть в списке файлов базы - пропуск
                $filesCount++;
                continue;
            }
            $fullPath = "$subDirPath/$fileName"; // полный путь до файла
            $backTrue = false; //для создание бэкапа
            if ($deleteFiles === 'yes') {
                if (!file_exists($patchBackup . $subDirName)) {
                    if (CheckDirPath($patchBackup . $subDirName . '/')) { //создал поддиректорию
                        $backTrue = true;
                    }
                } else {
                    $backTrue = true;
                }
                if ($backTrue) {
                    if ($saveBackup === 'yes') {
                        CopyDirFiles($fullPath, $patchBackup . $subDirName . '/' . $fileName); //копия в бэкап
                    }
                }
                //Удаление файла
                if (unlink($fullPath)) {
                    $removeFile++;
                }
            } else {
                $filesCount++;
            }
            $i++;
            $count++;
            unset($fileName, $backTrue);
        }
        closedir($hSubDir);
        //Удалить поддиректорию, если удаление активно и счётчик файлов пустой - т.е каталог пуст
        if ($deleteFiles && !$filesCount) {
            rmdir($subDirPath);
        }
        $contDir++;
    }
    closedir($hRootDir);
    return "CleanUpUpload();";
}

?>

Добавим строки в /bitrix/php_interface/init.php

if (file_exists($_SERVER["DOCUMENT_ROOT"]."/bitrix/php_interface/include/agents.php")){
    require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/php_interface/include/agents.php");
}

Последний шаг — настроить выполнение агента. Заходим в Настройки > Настройки продукта > Агенты и заполняем форму следующим образом:

Сохраняем. Все. Если выполнение агентов настроено правильно (это тема для другой статьи), то каждую ночь в 4 утра или при исполнении на хитах при первом посещении сайта после 4 утра, агент будет проверять наличие неиспользуемых файлов и удалять их без чьего-либо участия.