2026-08-24 21:06:11 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Modules\Core\Privacy\Jobs;
|
|
|
|
|
|
2026-09-16 00:24:18 +03:00
|
|
|
use Throwable;
|
2026-08-24 21:06:11 +03:00
|
|
|
use Illuminate\Bus\Queueable;
|
|
|
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
|
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
|
|
|
|
use Illuminate\Queue\InteractsWithQueue;
|
|
|
|
|
use Illuminate\Queue\SerializesModels;
|
|
|
|
|
use Illuminate\Support\Facades\Event;
|
|
|
|
|
use Modules\Core\Privacy\CustomerSubject;
|
|
|
|
|
use Modules\Core\Privacy\Events\PersonalDataGathered;
|
|
|
|
|
use Modules\Core\Privacy\ExportReport;
|
|
|
|
|
use Modules\Core\Privacy\ExportRequestStatus;
|
|
|
|
|
use Modules\Core\Privacy\Models\DataExportRequest;
|
|
|
|
|
use Modules\Core\Privacy\PrivacyManager;
|
|
|
|
|
use Modules\Core\Privacy\UserSubject;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gathers every registered PersonalDataProvider's export data for one request, all
|
|
|
|
|
* sequentially in this single job — deliberately not fanned out into one job per
|
|
|
|
|
* provider. Per-subject export work is small (a handful of indexed queries per
|
|
|
|
|
* provider), so there's no real parallelism win, and one job means "finished" is
|
|
|
|
|
* just "handle() returned," with no Bus::batch()/completion-counting needed. If a
|
|
|
|
|
* future provider ever does something genuinely slow (an external API call, a
|
|
|
|
|
* generated PDF), that's the point to reconsider — not before.
|
|
|
|
|
*
|
|
|
|
|
* Calls each provider's *ForCustomer() or *ForUser() method depending on the
|
|
|
|
|
* request's polymorphic subject — see Modules\Core\Privacy\PrivacyService and
|
|
|
|
|
* docs/privacy.md "User-scope vs Customer-scope".
|
|
|
|
|
*
|
|
|
|
|
* Writing the gathered data to a file is intentionally NOT done here — see
|
|
|
|
|
* PersonalDataGathered and Modules\Core\Privacy\Listeners\WriteExportToCsvListener,
|
|
|
|
|
* which keeps the export *format* swappable without touching how data is gathered.
|
|
|
|
|
*/
|
|
|
|
|
class ExportDataSubjectJob implements ShouldQueue
|
|
|
|
|
{
|
|
|
|
|
use Dispatchable;
|
|
|
|
|
use InteractsWithQueue;
|
|
|
|
|
use Queueable;
|
|
|
|
|
use SerializesModels;
|
|
|
|
|
|
|
|
|
|
public function __construct(
|
|
|
|
|
public readonly DataExportRequest $request,
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
public function handle(PrivacyManager $manager): void
|
|
|
|
|
{
|
|
|
|
|
if ($this->request->isForCustomer()) {
|
|
|
|
|
$subject = new CustomerSubject(customerId: $this->request->subject_id);
|
|
|
|
|
$results = array_map(fn ($provider) => $provider->exportForCustomer($subject), $manager->providers());
|
|
|
|
|
} else {
|
|
|
|
|
$subject = new UserSubject(userId: $this->request->subject_id, email: $this->request->email);
|
|
|
|
|
$results = array_map(fn ($provider) => $provider->exportForUser($subject), $manager->providers());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Event::dispatch(new PersonalDataGathered(
|
|
|
|
|
$this->request,
|
|
|
|
|
new ExportReport($subject, $results)
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
2026-09-16 00:24:18 +03:00
|
|
|
public function failed(Throwable $exception): void
|
2026-08-24 21:06:11 +03:00
|
|
|
{
|
|
|
|
|
$this->request->update(['status' => ExportRequestStatus::Failed]);
|
|
|
|
|
}
|
|
|
|
|
}
|