From 763e3f49185d4529311d690dd7d44fbfa49294fe Mon Sep 17 00:00:00 2001
From: tracer <tracer@24unix.net>
Date: Tue, 15 Nov 2022 17:11:25 +0100
Subject: [PATCH] small cli tool to purge unused avatar uploads

---
 src/Command/CronRunCommand.php | 72 ++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 src/Command/CronRunCommand.php

diff --git a/src/Command/CronRunCommand.php b/src/Command/CronRunCommand.php
new file mode 100644
index 0000000..8704968
--- /dev/null
+++ b/src/Command/CronRunCommand.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace App\Command;
+
+use App\Repository\UserRepository;
+use Symfony\Component\Console\Attribute\AsCommand;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+#[AsCommand(
+    name: 'cron:run',
+    description: 'Cleanup stale avatars',
+)]
+class CronRunCommand extends Command
+{
+    public function __construct(private readonly UserRepository $userRepository)
+    {
+        parent::__construct();
+    }
+
+    protected function configure(): void
+    {
+        /*
+        $this
+            ->addArgument('arg1', InputArgument::OPTIONAL, 'Argument description')
+            ->addOption('option1', null, InputOption::VALUE_NONE, 'Option description')
+        ;
+        */
+    }
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $io = new SymfonyStyle($input, $output);
+
+        $verbose = $input->getOption('verbose');
+
+        $staleCount = $this->deleteStaleAvatars();
+
+        if ($verbose) {
+            if ($staleCount > 0) {
+                $io->writeln("There were " . $staleCount . " stale avatars.");
+            } else {
+                $io->writeln("There were no stale avatars younger than 24 hours.");
+            }
+        }
+
+        return Command::SUCCESS;
+    }
+
+    private function deleteStaleAvatars(): int
+    {
+        $avatarDir = dirname(__DIR__, 2) . '/public/uploads/avatars';
+        $keepTime = 86400; // 24 hours
+        $deletedFiles = 0;
+
+        foreach (glob($avatarDir . '/*') as $entry) {
+            $filectime = filectime($entry);
+            if ($filectime && $filectime + $keepTime < time()) {
+                // check if it in use
+                if ($user = $this->userRepository->findOneBy(['avatar' => basename($entry)])) {
+                    echo basename($entry) . " is in use by: " . $user->getUserIdentifier() . PHP_EOL;
+                }
+                unlink($entry);
+                $deletedFiles++;
+            }
+
+        }
+        return $deletedFiles;
+    }
+}