66 lines
2.0 KiB
PHP
66 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Database\DetectsLostConnections;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Throwable;
|
|
|
|
/** Never remove bytes whose database outcome or reference status is uncertain. */
|
|
final class OpportunityResourceFileCleanup
|
|
{
|
|
use DetectsLostConnections;
|
|
|
|
/** @param list<string> $keys */
|
|
public function afterFailure(array $keys, Throwable $failure): void
|
|
{
|
|
try {
|
|
$uncertain = $this->causedByLostConnection($failure);
|
|
} catch (Throwable) {
|
|
$uncertain = true;
|
|
}
|
|
if ($uncertain) {
|
|
$this->unconfirmed();
|
|
|
|
return;
|
|
}
|
|
foreach (array_unique($keys) as $key) {
|
|
if (preg_match('/^opportunity-resources\/[a-f0-9-]{36}$/D', $key) !== 1) {
|
|
continue;
|
|
}
|
|
try {
|
|
$referenced = DB::transaction(function () use ($key) {
|
|
$visibility = DB::selectOne("SELECT row_security_active('documents'::regclass) AS active");
|
|
if ($visibility?->active !== false) {
|
|
return null;
|
|
}
|
|
|
|
return DB::table('documents')->where('storage_key', $key)->exists();
|
|
});
|
|
if ($referenced !== false) {
|
|
if ($referenced === null) {
|
|
$this->unconfirmed();
|
|
}
|
|
|
|
continue;
|
|
}
|
|
if (Storage::disk('local')->delete($key) !== true) {
|
|
$this->unconfirmed();
|
|
}
|
|
} catch (Throwable) {
|
|
$this->unconfirmed();
|
|
}
|
|
}
|
|
}
|
|
|
|
private function unconfirmed(): void
|
|
{
|
|
try {
|
|
Log::warning('Opportunity resource cleanup requires verification.', ['error_code' => 'resource_cleanup_unconfirmed']);
|
|
} catch (Throwable) { /* Preserve the original operation failure and retained bytes. */
|
|
}
|
|
}
|
|
}
|