Мастерская iPloGic
+7 (926) 961-66-26

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

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

При использовании 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");


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

agent


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


21.06.2017