51 lines
2.3 KiB
PHP
51 lines
2.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Jobs\ScanDocumentForMalware;
|
|
use App\Services\Malware\DocumentScanDelivery;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Throwable;
|
|
|
|
/** A saved resource remains saved when its post-commit scan dispatch cannot be confirmed. */
|
|
final class OpportunityScanDispatch
|
|
{
|
|
/** @param array<string,mixed>|null $context */
|
|
public function dispatch(string $documentId, ?array $context): void
|
|
{
|
|
$job = new ScanDocumentForMalware($documentId, $context);
|
|
$dispatch = function () use ($documentId, $context, $job): void {
|
|
try {
|
|
// Existing uniqueness, retries and scanner are retained.
|
|
app(DocumentScanDelivery::class)->dispatch($job);
|
|
} catch (Throwable) {
|
|
try {
|
|
DB::transaction(function () use ($documentId): void {
|
|
$document = DB::table('documents')->where('id', $documentId)->lockForUpdate()->first();
|
|
if ($document && $document->deleted_at === null && $document->status !== 'deleted' && $document->malware_scan_status === 'pending') {
|
|
DB::table('documents')->where('id', $documentId)->update(['status' => 'quarantined', 'malware_scan_status' => 'failed', 'malware_failure_reason' => 'queue_dispatch_failed', 'updated_at' => now()]);
|
|
}
|
|
});
|
|
} catch (Throwable) {
|
|
try {
|
|
Log::warning('Document scan dispatch state requires verification.', ['reference' => $job->runIdentifier(), 'error_code' => 'scan_dispatch_unconfirmed']);
|
|
} catch (Throwable) {
|
|
}
|
|
}
|
|
if ($context !== null) {
|
|
app(OpportunityTechnicalIncidents::class)->recordScan($context, $job->runIdentifier(), 'scan_dispatch_unconfirmed');
|
|
}
|
|
}
|
|
};
|
|
try {
|
|
DB::afterCommit($dispatch);
|
|
} catch (Throwable) {
|
|
// Registration itself failed: never escape after a successful resource commit.
|
|
if ($context !== null) {
|
|
app(OpportunityTechnicalIncidents::class)->recordScan($context, $job->runIdentifier(), 'scan_dispatch_unconfirmed');
|
|
}
|
|
}
|
|
}
|
|
}
|