Auto purge uploads from old deleted posts

Интересно, почему об этом не говорят шире? Это действительно серьёзная проблема.

Я написал PHP-скрипт, который использует CSV-файл, сгенерированный следующим SQL-запросом, перечисляющим все загрузки и их ссылки:
(увеличьте лимит, если у вас много загрузок)

SELECT 
    uploads.original_filename,
    ROUND(uploads.filesize / 1000000.0, 2) AS size_in_mb,
    uploads.extension,
    uploads.created_at,
    uploads.url,
    upload_references.upload_id,
    upload_references.target_id,
    upload_references.target_type,
    upload_references.created_at,
    upload_references.updated_at
FROM upload_references
JOIN uploads ON uploads.id = upload_references.upload_id
ORDER BY upload_references.target_type
LIMIT 90000

Суть работы скрипта: он фильтрует загрузки, которые остаются только как черновики (которые ошибочно сохраняются в базе данных, как я объяснял здесь). Скрипт выводит строку с пробелами, содержащую все имена файлов. Вы также можете изменить скрипт, чтобы он выводил полный путь (удалите функцию basename()).

Затем войдите на ваш сервер Discourse через SSH и выполните команду rm для всех этих файлов.

  • Один недостаток этого подхода: будут удалены все изображения, которые остаются в активных черновиках (но это можно ограничить, уменьшив значение удалять черновики старше n дней).
  • Второй недостаток: некорректные записи в базе данных всё ещё остаются; для этого мне нужно попросить разработчиков исправить проблему.

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

<?php
 
if (($open = fopen("test.csv", "r")) !== false) {
    while (($data = fgetcsv($open, 100000, ",")) !== false) {
        $array[] = $data;
    }
 
    fclose($open);
}
$final = array();
$i=0;
foreach ($array as $item){
	if($item[7]=="Draft"){
			foreach ($array as $item_inside){
				if(($item_inside[4]==$item[4]) && ($item_inside[7]!="Draft")) $i++; //увеличиваем i, если есть не только черновики
				}
			if($i==0)array_push($final, $item[4]); //были только черновики, можно добавить в массив
			$i=0;
		}
	}
$final_unique= array_unique($final);
//print_r($final_unique);

foreach($final_unique as $single){
	echo basename($single)." ";
	}
?>

Файл test.csv, содержащий результат запроса, должен находиться в той же директории, что и скрипт.
Если возникнут проблемы — спрашивайте!

3 лайка