*/ public array $backoff = [10, 30, 60]; public function __construct(public Subscriber $subscriber) { $this->onQueue('mailwizz'); } public function uniqueId(): string { return (string) $this->subscriber->getKey(); } public function handle(): void { $subscriber = Subscriber::query() ->with(['preregistrationPage.mailwizzConfig']) ->find($this->subscriber->id); if ($subscriber === null) { return; } $page = $subscriber->preregistrationPage; $config = $page?->mailwizzConfig; if ($page === null || $config === null) { return; } if (! $this->configIsComplete($config, $page->phone_enabled)) { Log::warning('SyncSubscriberToMailwizz: incomplete Mailwizz config', [ 'subscriber_id' => $subscriber->id, 'page_id' => $page->id, ]); $this->fail(new RuntimeException('Incomplete Mailwizz configuration.')); return; } $apiKey = $config->api_key; if (! is_string($apiKey) || $apiKey === '') { Log::warning('SyncSubscriberToMailwizz: missing API key', ['subscriber_id' => $subscriber->id]); $this->fail(new RuntimeException('Mailwizz API key is missing.')); return; } $service = new MailwizzService($apiKey); $listUid = $config->list_uid; $search = $service->searchSubscriber($listUid, $subscriber->email); if ($search === null) { $this->createInMailwizz($service, $subscriber, $config, $listUid); } else { $this->updateInMailwizz($service, $subscriber, $config, $listUid, $search['subscriber_uid']); } $subscriber->update([ 'synced_to_mailwizz' => true, 'synced_at' => now(), ]); } public function failed(?Throwable $exception): void { Log::error('SyncSubscriberToMailwizz failed', [ 'subscriber_id' => $this->subscriber->id, 'message' => $exception?->getMessage(), ]); } private function configIsComplete(MailwizzConfig $config, bool $phoneEnabled): bool { if ($config->list_uid === '' || $config->field_email === '' || $config->field_first_name === '' || $config->field_last_name === '') { return false; } if ($phoneEnabled && ($config->field_phone === null || $config->field_phone === '')) { return false; } if ($config->tag_field === null || $config->tag_field === '' || $config->tag_value === null || $config->tag_value === '') { return false; } return true; } private function buildBasePayload(Subscriber $subscriber, MailwizzConfig $config, bool $phoneEnabled): array { $data = [ $config->field_email => $subscriber->email, $config->field_first_name => $subscriber->first_name, $config->field_last_name => $subscriber->last_name, ]; if ($phoneEnabled && $config->field_phone !== null && $config->field_phone !== '') { $phone = $subscriber->phone; if ($phone !== null && $phone !== '') { $data[$config->field_phone] = $phone; } } return $data; } private function createInMailwizz( MailwizzService $service, Subscriber $subscriber, MailwizzConfig $config, string $listUid ): void { $page = $subscriber->preregistrationPage; $data = $this->buildBasePayload($subscriber, $config, (bool) $page->phone_enabled); $tagField = $config->tag_field; $tagValue = $config->tag_value; if ($tagField !== null && $tagField !== '' && $tagValue !== null && $tagValue !== '') { $data[$tagField] = [$tagValue]; } $service->createSubscriber($listUid, $data); } private function updateInMailwizz( MailwizzService $service, Subscriber $subscriber, MailwizzConfig $config, string $listUid, string $subscriberUid ): void { $page = $subscriber->preregistrationPage; $data = $this->buildBasePayload($subscriber, $config, (bool) $page->phone_enabled); $tagField = $config->tag_field; $tagValue = $config->tag_value; if ($tagField !== null && $tagField !== '' && $tagValue !== null && $tagValue !== '') { $full = $service->getSubscriber($listUid, $subscriberUid); if ($full === null) { throw new RuntimeException('Mailwizz getSubscriber returned an empty payload.'); } $existingCsv = $this->extractTagCsvFromResponse($full, $tagField); $merged = $this->mergeCheckboxlistTags($existingCsv, $tagValue); $data[$tagField] = $merged; } $service->updateSubscriber($listUid, $subscriberUid, $data); } /** * @param array $apiResponse */ private function extractTagCsvFromResponse(array $apiResponse, string $tagField): string { $record = data_get($apiResponse, 'data.record'); if (! is_array($record)) { $record = data_get($apiResponse, 'data'); } if (! is_array($record)) { return ''; } $raw = $record[$tagField] ?? data_get($record, "fields.{$tagField}"); if (is_array($raw)) { return implode(',', array_map(static fn (mixed $v): string => is_scalar($v) ? (string) $v : '', $raw)); } return is_string($raw) ? $raw : ''; } /** * @return list */ private function mergeCheckboxlistTags(string $existingCsv, string $newValue): array { $parts = array_filter(array_map('trim', explode(',', $existingCsv)), static fn (string $s): bool => $s !== ''); if (! in_array($newValue, $parts, true)) { $parts[] = $newValue; } return array_values($parts); } }