Как уже писал, этот сайт использует мультиблоговый движок LibArea. Из него попробовал сделать собственный блог с небольшими доработками, что собственно вы и видите здесь. Теперь вот понадобилось сделать консольную команду на удаление неиспользуемых изображений в текущем месяце. То есть тех, что оказались не вставлены ни в один существующий текст поста или ответа.
Планирую поставить команду выполняться по cron раз в день. Часто ставить не стоит, так как кто-то может в это время создавать пост с изображениями, а тут они удалятся. Можно выборочно удалить и те изображения, которые указаны в постах и ответах помеченных 'delete', то есть удалённых.
Если вы хотите наладить подобный процесс у себя, то перед первым пробным удалением неплохо бы сделать бэкап папки с картинками за текущий месяц, на всякий случай. А после проверки, что все удалилось корректно, удалить и сам бэкап.
Вот сама консольная команда:
<?php
/* Файл app/Commands/RemoveUnusedPostImages.php */
namespace App\Commands;
class RemoveUnusedPostImages extends \Hleb\Scheme\App\Commands\MainTask
{
/** php console remove-unused-post-images [--all] **/
const DESCRIPTION = "Remove unused images";
protected function execute($arg = null)
{
$allPosts = \DB::run("SELECT * FROM posts")->fetchAll();
$allAnswers = \DB::run("SELECT * FROM answers")->fetchAll();
$data = array_merge($allPosts, $allAnswers);
foreach ($data as $key => $value) {
$data[$key]['content'] = $value['post_content'] ?? $value['answer_content'];
$data[$key]['is_deleted'] = $value['post_is_deleted'] ?? $value['answer_is_deleted'];
}
if (!$data) {
echo PHP_EOL . "Posts and answers not found!" . PHP_EOL;
return;
}
$countPosts = count($data);
$images = [];
$imagePath = "/uploads/posts/content/" . date("Y") . "/" . date("n") . "/";
$dir = HLEB_PUBLIC_DIR . $imagePath;
if (!file_exists($dir)) {
echo PHP_EOL . "Images directory not found!" . PHP_EOL;
return;
}
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
$images[] = $imagePath . $file;
}
}
}
$countImages = count($images);
if (!$images) {
echo PHP_EOL . "Images not found!" . PHP_EOL;
return;
}
foreach ($data as $post) {
if ($post['content']) {
foreach ($images as $key => $image) {
if ($post["is_deleted"] === 1 && $arg === "--all") {
continue;
}
if (strpos($post['content'], $image) !== false){
unset($images[$key]);
}
}
}
}
// Если удаляются все изображения, то явно что-то пошло не так.
if (count($images) === $countImages) {
echo PHP_EOL . "Something went wrong!" . PHP_EOL;
return;
}
foreach ($images as $key => $image) {
unlink(HLEB_PUBLIC_DIR . $image);
unset($images[$key]);
}
echo PHP_EOL . "POSTS: $countPosts | IMAGES: $countImages | DELETED: " . ($countImages - count($images)) . PHP_EOL;
echo PHP_EOL . __CLASS__ . " done." . PHP_EOL;
}
}
Вызвать её можно через php console remove-unused-post-images --all, где необязательный параметр --all устанавливает удаление неиспользуемых изображений и в удалённых постах и ответах.