generated from boboko/starter
74 lines
2.5 KiB
PHP
74 lines
2.5 KiB
PHP
<?php
|
|||
|
|
|
||
|
|
namespace App\Console\Commands;
|
||
|
|
|
||
|
|
use App\Http\Controllers\CustomFieldUploadController;
|
||
|
|
use Illuminate\Console\Command;
|
||
|
|
use Illuminate\Support\Facades\Storage;
|
||
|
|
use Lunar\Models\CartLine;
|
||
|
|
use Lunar\Models\OrderLine;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Custom-field photos are uploaded the moment a shopper picks them (see
|
||
|
|
* CustomFieldUploadController), before add-to-cart — so a shopper who picks a
|
||
|
|
* photo and then leaves, or picks a different one, leaves a file nobody
|
||
|
|
* references. This deletes those: any upload older than the grace period that
|
||
|
|
* no cart line or order line's meta.custom_fields points to.
|
||
|
|
*
|
||
|
|
* The grace period covers a shopper still on the product page with a picked
|
||
|
|
* but not-yet-added photo. A file referenced by a cart line is kept for as
|
||
|
|
* long as that cart line exists; once the line (or its cart) is removed, the
|
||
|
|
* next run deletes the file. Order line references are kept indefinitely.
|
||
|
|
*/
|
||
|
|
class PruneCustomFieldUploads extends Command
|
||
|
|
{
|
||
|
|
protected $signature = 'custom-fields:prune-uploads {--hours=24 : Only delete unreferenced uploads older than this}';
|
||
|
|
|
||
|
|
protected $description = 'Delete custom-field photo uploads not referenced by any cart or order line';
|
||
|
|
|
||
|
|
public function handle(): int
|
||
|
|
{
|
||
|
|
$disk = Storage::disk(CustomFieldUploadController::DISK);
|
||
|
|
$referenced = $this->referencedPaths();
|
||
|
|
$cutoff = now()->subHours((int) $this->option('hours'))->getTimestamp();
|
||
|
|
$deleted = 0;
|
||
|
|
|
||
|
|
foreach ($disk->files(CustomFieldUploadController::DIRECTORY) as $path) {
|
||
|
|
if (isset($referenced[$path]) || $disk->lastModified($path) > $cutoff) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
$disk->delete($path);
|
||
|
|
$deleted++;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->info("Deleted {$deleted} unreferenced custom-field upload(s).");
|
||
|
|
|
||
|
|
return self::SUCCESS;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @return array<string, true>
|
||
|
|
*/
|
||
|
|
private function referencedPaths(): array
|
||
|
|
{
|
||
|
|
$paths = [];
|
||
|
|
|
||
|
|
foreach ([CartLine::class, OrderLine::class] as $model) {
|
||
|
|
$model::query()
|
||
|
|
->where('meta', 'like', '%custom_fields%')
|
||
|
|
->select('meta')
|
||
|
|
->cursor()
|
||
|
|
->each(function ($line) use (&$paths) {
|
||
|
|
foreach ($line->meta['custom_fields'] ?? [] as $field) {
|
||
|
|
if (! empty($field['path'])) {
|
||
|
|
$paths[$field['path']] = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
return $paths;
|
||
|
|
}
|
||
|
|
}
|