File: /var/www/ipsremont-demo/app/Console/Commands/RepairAttachmentCleaner.php
<?php
namespace App\Console\Commands;
use App\Models\Repair\Repair;
use App\Models\RepairAttachment;
use App\Repository\RepairAttachment\RepairAttachmentRepository;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
use Spatie\ImageOptimizer\OptimizerChainFactory;
use Spatie\ImageOptimizer\Optimizers\Jpegoptim;
use Symfony\Component\Console\Command\Command as CommandAlias;
class RepairAttachmentCleaner extends Command
{
protected $signature = 'repair-attachment:clean';
protected $description = 'Чистит приложения нарядов';
private $totalSize = 0;
private function removeDrafts()
{
$this->info('Удаляем старые черновики');
$draft = RepairAttachmentRepository::getDrafts(date('Y-m-d', strtotime('-1 week')));
$this->line('Найдено файлов: ' . count($draft));
$size = 0;
foreach ($draft as $item) {
/** @var RepairAttachment $item */
$filePath = storage_path($item->path);
if (file_exists($filePath)) {
$size += filesize($filePath);
unlink($filePath);
} else {
$this->line('Файл не найден: ' . $item->original_name);
}
$item->delete();
}
$this->totalSize += $size;
$this->line('Освобождено места: ' . round($size / 1024 / 1024, 2) . ' Mb');
}
private function removeGarbage()
{
$this->info('Удаляем мусор которого нет в базе');
$repairAttachments = RepairAttachmentRepository::getAll();
$repairAttachmentPaths = [];
foreach ($repairAttachments as $repairAttachment) {
$repairAttachmentPaths[] = $repairAttachment->path;
}
$this->line('Файлов в базе: ' . count($repairAttachments));
$files = Storage::files(RepairAttachment::PATH);
$this->line('Файлов на сервере: ' . count($files));
$size = 0;
foreach ($files as $file) {
if (!in_array($file, $repairAttachmentPaths)) {
$filePath = storage_path($file);
$size += filesize($filePath);
$this->line('Файла нет в базе: ' . $file);
if (Storage::exists($file)) {
Storage::delete($file);
}
}
}
$this->totalSize += $size;
$this->line('Освобождено места: ' . round($size / 1024 / 1024, 2) . ' Mb');
}
private function rotateOld()
{
$this->info('Ротируем старые приложение');
$repairAttachments = RepairAttachmentRepository::getOld();
$repairIds = $repairAttachments->pluck('repair_id')->unique()->toArray();
$repairIds = Repair::query()->whereIn('id', $repairIds)->where('created_at', '<=', date('Y-m-d', strtotime('-1 year')))->pluck('id')->toArray();
$this->line('Старых заявок: ' . count($repairIds));
$toRemove = [];
foreach ($repairAttachments as $repairAttachment) {
if (!in_array($repairAttachment->repair_id, $repairIds)) {
continue;
}
$toRemove[] = $repairAttachment;
}
$this->line('Файлов на удаление: ' . count($toRemove));
$size = 0;
foreach ($toRemove as $item) {
/** @var RepairAttachment $item */
$filePath = storage_path($item->path);
if (file_exists($filePath)) {
$size += filesize($filePath);
unlink($filePath);
} else {
$this->line('Файл не найден: ' . $item->original_name);
}
$item->delete();
}
$this->totalSize += $size;
$this->line('Освобождено места: ' . round($size / 1024 / 1024, 2) . ' Mb');
}
private function optimizeBigImages()
{
$this->info('Пережимаем большие изображения');
$repairAttachments = RepairAttachmentRepository::getBigJpg();
$oldSize = 0;
$newSize = 0;
$totalCount = count($repairAttachments);
$this->line('Больших файлов: ' . $totalCount);
$count = 0;
foreach ($repairAttachments as $repairAttachment) {
$count++;
$this->line($count . '/' . $totalCount);
/** @var RepairAttachment $repairAttachment */
$filePath = storage_path($repairAttachment->path);
$oldSize += filesize($filePath);
if ($oldSize != $repairAttachment->size) {
$repairAttachment->size = $oldSize;
$repairAttachment->save();
continue;
}
$optimizerChain = OptimizerChainFactory::create();
$optimizerChain->addOptimizer(new Jpegoptim(['--m75']));
// Это надо если мы хотим старые не удалять
// $newFilePath = str_replace('.jpg', '_opt.jpg', $filePath);
// $optimizerChain->optimize($filePath, $newFilePath);
$optimizerChain->optimize($filePath);
$repairAttachment->size = $newSize;
$repairAttachment->is_optimized = true;
$repairAttachment->save();
$newSize += filesize($filePath);
}
$size = $oldSize - $newSize;
$this->totalSize += $size;
$this->line('Освобождено места: ' . round($size / 1024 / 1024, 2) . ' Mb');
}
public function handle(): int
{
$this->info($this->description);
$this->removeDrafts();
$this->removeGarbage();
$this->rotateOld();
$this->optimizeBigImages();
$this->info('Всего освобождено места: ' . round($this->totalSize / 1024 / 1024, 2) . ' Mb');
return CommandAlias::SUCCESS;
}
}