Files
preregister/app/Services/CleanupSubscriberIntegrationsService.php
bert.hausmans 1e7ee14540 fix: clear Mailwizz checkboxlist tag when deleting subscriber
Encode empty checkboxlist arrays as an empty scalar so multipart requests
include the field. On delete, PUT only coupon and tag fields to Mailwizz
after merging the tag CSV from getSubscriber.

Made-with: Cursor
2026-04-05 13:33:56 +02:00

146 lines
4.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Services;
use App\Models\MailwizzConfig;
use App\Models\PreregistrationPage;
use App\Models\Subscriber;
use App\Models\WeeztixConfig;
use Illuminate\Support\Facades\Log;
use RuntimeException;
use Throwable;
/**
* Before a subscriber row is deleted, best-effort cleanup in Weeztix (coupon code) and Mailwizz (strip source tag, clear coupon field).
* Failures are logged only; local delete must still proceed.
*/
final class CleanupSubscriberIntegrationsService
{
public function runBeforeDelete(Subscriber $subscriber): void
{
$subscriber->loadMissing(['preregistrationPage.mailwizzConfig', 'preregistrationPage.weeztixConfig']);
$page = $subscriber->preregistrationPage;
if ($page === null) {
return;
}
try {
$this->cleanupWeeztixIfApplicable($subscriber, $page);
} catch (Throwable $e) {
Log::error('CleanupSubscriberIntegrations: Weeztix cleanup failed', [
'subscriber_id' => $subscriber->id,
'preregistration_page_id' => $page->id,
'message' => $e->getMessage(),
]);
}
try {
$this->cleanupMailwizzIfApplicable($subscriber, $page);
} catch (Throwable $e) {
Log::error('CleanupSubscriberIntegrations: Mailwizz cleanup failed', [
'subscriber_id' => $subscriber->id,
'preregistration_page_id' => $page->id,
'message' => $e->getMessage(),
]);
}
}
private function cleanupWeeztixIfApplicable(Subscriber $subscriber, PreregistrationPage $page): void
{
$config = $page->weeztixConfig;
if ($config === null || ! $config->is_connected) {
return;
}
$code = $subscriber->coupon_code;
if (! is_string($code) || trim($code) === '') {
return;
}
if (! $this->weeztixCanManageCodes($config)) {
return;
}
$fresh = $config->fresh();
if ($fresh === null) {
return;
}
(new WeeztixService($fresh))->deleteCouponCodeByCodeString($code);
}
private function weeztixCanManageCodes(WeeztixConfig $config): bool
{
$company = $config->company_guid;
$coupon = $config->coupon_guid;
return is_string($company) && $company !== '' && is_string($coupon) && $coupon !== '';
}
private function cleanupMailwizzIfApplicable(Subscriber $subscriber, PreregistrationPage $page): void
{
$config = $page->mailwizzConfig;
if ($config === null) {
return;
}
if (! $this->mailwizzConfigAllowsUpdate($config)) {
return;
}
$apiKey = $config->api_key;
if (! is_string($apiKey) || $apiKey === '') {
return;
}
$service = new MailwizzService($apiKey);
$listUid = $config->list_uid;
$search = $service->searchSubscriber($listUid, $subscriber->email);
if ($search === null) {
return;
}
$subscriberUid = $search['subscriber_uid'];
/** @var array<string, mixed> $data */
$data = [];
$couponField = $config->field_coupon_code;
if (is_string($couponField) && $couponField !== '') {
$data[$couponField] = '';
}
$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 = MailwizzCheckboxlistTags::extractCsvFromSubscriberResponse($full, $tagField);
$data[$tagField] = MailwizzCheckboxlistTags::removeValueFromCsv($existingCsv, $tagValue);
}
if ($data === []) {
return;
}
$service->updateSubscriber($listUid, $subscriberUid, $data);
}
private function mailwizzConfigAllowsUpdate(MailwizzConfig $config): bool
{
if ($config->list_uid === '' || $config->field_email === '' || $config->field_first_name === '' || $config->field_last_name === '') {
return false;
}
$hasTagWork = $config->tag_field !== null && $config->tag_field !== ''
&& $config->tag_value !== null && $config->tag_value !== '';
$hasCouponField = is_string($config->field_coupon_code) && $config->field_coupon_code !== '';
return $hasTagWork || $hasCouponField;
}
}