Compare commits
1 Commits
91caa16e70
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 845665c8be |
@@ -8,6 +8,8 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\DestroySubscriberRequest;
|
||||
use App\Http\Requests\Admin\IndexSubscriberRequest;
|
||||
use App\Http\Requests\Admin\QueueMailwizzSyncRequest;
|
||||
use App\Http\Requests\Admin\SyncSubscriberMailwizzRequest;
|
||||
use App\Jobs\SyncSubscriberToMailwizz;
|
||||
use App\Models\PreregistrationPage;
|
||||
use App\Models\Subscriber;
|
||||
use App\Services\CleanupSubscriberIntegrationsService;
|
||||
@@ -79,6 +81,26 @@ class SubscriberController extends Controller
|
||||
));
|
||||
}
|
||||
|
||||
public function syncSubscriberMailwizz(
|
||||
SyncSubscriberMailwizzRequest $request,
|
||||
PreregistrationPage $page,
|
||||
Subscriber $subscriber
|
||||
): RedirectResponse {
|
||||
$page->loadMissing('mailwizzConfig');
|
||||
|
||||
if ($page->mailwizzConfig === null) {
|
||||
return redirect()
|
||||
->route('admin.pages.subscribers.index', $page)
|
||||
->with('error', __('This page has no Mailwizz integration.'));
|
||||
}
|
||||
|
||||
SyncSubscriberToMailwizz::dispatch($subscriber->fresh());
|
||||
|
||||
return redirect()
|
||||
->route('admin.pages.subscribers.index', $page)
|
||||
->with('status', __('Mailwizz sync has been queued for this subscriber.'));
|
||||
}
|
||||
|
||||
public function export(IndexSubscriberRequest $request, PreregistrationPage $page): StreamedResponse
|
||||
{
|
||||
$search = $request->validated('search');
|
||||
|
||||
36
app/Http/Requests/Admin/SyncSubscriberMailwizzRequest.php
Normal file
36
app/Http/Requests/Admin/SyncSubscriberMailwizzRequest.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\PreregistrationPage;
|
||||
use App\Models\Subscriber;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SyncSubscriberMailwizzRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
$page = $this->route('page');
|
||||
$subscriber = $this->route('subscriber');
|
||||
if (! $page instanceof PreregistrationPage || ! $subscriber instanceof Subscriber) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($subscriber->preregistration_page_id !== $page->id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->user()?->can('update', $page) ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<int, ValidationRule|string>>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,9 @@
|
||||
"Subscriber removed.": "Abonnee verwijderd.",
|
||||
"Delete this subscriber? This cannot be undone.": "Deze abonnee verwijderen? Dit kan niet ongedaan worden gemaakt.",
|
||||
"Remove": "Verwijderen",
|
||||
"Sync Mailwizz": "Mailwizz sync",
|
||||
"Mailwizz sync has been queued for this subscriber.": "Mailwizz-synchronisatie is in de wachtrij gezet voor deze abonnee.",
|
||||
"Queue a Mailwizz sync for this subscriber? The tag and coupon code will be sent when the queue worker runs.": "Mailwizz-synchronisatie voor deze abonnee in de wachtrij zetten? De tag en kortingscode worden verstuurd zodra de queue-worker draait.",
|
||||
"Actions": "Acties",
|
||||
"Fix background to viewport": "Achtergrond vastzetten op het scherm",
|
||||
"When enabled, the background image and overlay stay fixed while visitors scroll long content.": "Als dit aan staat, blijven de achtergrondafbeelding en de overlay stilstaan terwijl bezoekers door lange inhoud scrollen."
|
||||
|
||||
@@ -82,6 +82,23 @@
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-4 py-3 text-right">
|
||||
@can('update', $page)
|
||||
<div class="inline-flex flex-wrap items-center justify-end gap-1.5">
|
||||
@if ($page->mailwizzConfig !== null)
|
||||
<form
|
||||
method="post"
|
||||
action="{{ route('admin.pages.subscribers.sync-mailwizz', [$page, $subscriber]) }}"
|
||||
class="inline"
|
||||
onsubmit="return confirm(@js(__('Queue a Mailwizz sync for this subscriber? The tag and coupon code will be sent when the queue worker runs.')));"
|
||||
>
|
||||
@csrf
|
||||
<button
|
||||
type="submit"
|
||||
class="rounded-lg border border-indigo-200 bg-white px-2.5 py-1 text-xs font-semibold text-indigo-700 hover:bg-indigo-50"
|
||||
>
|
||||
{{ __('Sync Mailwizz') }}
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
<form
|
||||
method="post"
|
||||
action="{{ route('admin.pages.subscribers.destroy', [$page, $subscriber]) }}"
|
||||
@@ -97,6 +114,7 @@
|
||||
{{ __('Remove') }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endcan
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -38,6 +38,7 @@ Route::middleware(['auth', 'verified'])->prefix('admin')->name('admin.')->group(
|
||||
Route::get('pages/{page}/subscribers/export', [SubscriberController::class, 'export'])->name('pages.subscribers.export');
|
||||
Route::delete('pages/{page}/subscribers/{subscriber}', [SubscriberController::class, 'destroy'])->name('pages.subscribers.destroy');
|
||||
Route::post('pages/{page}/subscribers/queue-mailwizz-sync', [SubscriberController::class, 'queueMailwizzSync'])->name('pages.subscribers.queue-mailwizz-sync');
|
||||
Route::post('pages/{page}/subscribers/{subscriber}/sync-mailwizz', [SubscriberController::class, 'syncSubscriberMailwizz'])->name('pages.subscribers.sync-mailwizz');
|
||||
Route::get('pages/{page}/subscribers', [SubscriberController::class, 'index'])->name('pages.subscribers.index');
|
||||
|
||||
// Mailwizz configuration (nested under pages)
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Jobs\SyncSubscriberToMailwizz;
|
||||
use App\Models\MailwizzConfig;
|
||||
use App\Models\PreregistrationPage;
|
||||
use App\Models\Subscriber;
|
||||
@@ -12,6 +13,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Http\Client\Request;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Illuminate\Support\Str;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -80,6 +82,135 @@ class QueueUnsyncedMailwizzSubscribersTest extends TestCase
|
||||
$response->assertForbidden();
|
||||
}
|
||||
|
||||
public function test_owner_can_queue_single_subscriber_mailwizz_sync(): void
|
||||
{
|
||||
Queue::fake();
|
||||
|
||||
$user = User::factory()->create(['role' => 'user']);
|
||||
$page = $this->makePageWithMailwizzForUser($user);
|
||||
$subscriber = Subscriber::query()->create([
|
||||
'preregistration_page_id' => $page->id,
|
||||
'first_name' => 'One',
|
||||
'last_name' => 'Off',
|
||||
'email' => 'oneoff@example.com',
|
||||
'synced_to_mailwizz' => true,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post(
|
||||
route('admin.pages.subscribers.sync-mailwizz', [$page, $subscriber])
|
||||
);
|
||||
|
||||
$response->assertRedirect(route('admin.pages.subscribers.index', $page));
|
||||
$response->assertSessionHas('status');
|
||||
Queue::assertPushed(SyncSubscriberToMailwizz::class, function (SyncSubscriberToMailwizz $job) use ($subscriber): bool {
|
||||
return $job->subscriberId === $subscriber->id;
|
||||
});
|
||||
}
|
||||
|
||||
public function test_other_user_cannot_queue_single_subscriber_mailwizz_sync(): void
|
||||
{
|
||||
Queue::fake();
|
||||
|
||||
$owner = User::factory()->create(['role' => 'user']);
|
||||
$intruder = User::factory()->create(['role' => 'user']);
|
||||
$page = $this->makePageWithMailwizzForUser($owner);
|
||||
$subscriber = Subscriber::query()->create([
|
||||
'preregistration_page_id' => $page->id,
|
||||
'first_name' => 'A',
|
||||
'last_name' => 'B',
|
||||
'email' => 'ab@example.com',
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($intruder)->post(
|
||||
route('admin.pages.subscribers.sync-mailwizz', [$page, $subscriber])
|
||||
);
|
||||
|
||||
$response->assertForbidden();
|
||||
Queue::assertNothingPushed();
|
||||
}
|
||||
|
||||
public function test_single_subscriber_mailwizz_sync_redirects_with_error_when_page_has_no_mailwizz(): void
|
||||
{
|
||||
Queue::fake();
|
||||
|
||||
$user = User::factory()->create(['role' => 'user']);
|
||||
$page = PreregistrationPage::query()->create([
|
||||
'slug' => (string) Str::uuid(),
|
||||
'user_id' => $user->id,
|
||||
'title' => 'Fest',
|
||||
'heading' => 'Join',
|
||||
'intro_text' => null,
|
||||
'thank_you_message' => null,
|
||||
'expired_message' => null,
|
||||
'ticketshop_url' => null,
|
||||
'start_date' => now()->subHour(),
|
||||
'end_date' => now()->addMonth(),
|
||||
'phone_enabled' => false,
|
||||
'is_active' => true,
|
||||
]);
|
||||
$subscriber = Subscriber::query()->create([
|
||||
'preregistration_page_id' => $page->id,
|
||||
'first_name' => 'A',
|
||||
'last_name' => 'B',
|
||||
'email' => 'nomw@example.com',
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post(
|
||||
route('admin.pages.subscribers.sync-mailwizz', [$page, $subscriber])
|
||||
);
|
||||
|
||||
$response->assertRedirect(route('admin.pages.subscribers.index', $page));
|
||||
$response->assertSessionHas('error');
|
||||
Queue::assertNothingPushed();
|
||||
}
|
||||
|
||||
public function test_cannot_queue_single_subscriber_mailwizz_sync_with_mismatched_page(): void
|
||||
{
|
||||
Queue::fake();
|
||||
|
||||
$user = User::factory()->create(['role' => 'user']);
|
||||
$pageA = $this->makePageWithMailwizzForUser($user);
|
||||
$pageB = PreregistrationPage::query()->create([
|
||||
'slug' => (string) Str::uuid(),
|
||||
'user_id' => $user->id,
|
||||
'title' => 'Other',
|
||||
'heading' => 'Other',
|
||||
'intro_text' => null,
|
||||
'thank_you_message' => null,
|
||||
'expired_message' => null,
|
||||
'ticketshop_url' => null,
|
||||
'start_date' => now()->subHour(),
|
||||
'end_date' => now()->addMonth(),
|
||||
'phone_enabled' => false,
|
||||
'is_active' => true,
|
||||
]);
|
||||
MailwizzConfig::query()->create([
|
||||
'preregistration_page_id' => $pageB->id,
|
||||
'api_key' => 'fake-api-key',
|
||||
'list_uid' => 'list-uid-2',
|
||||
'list_name' => 'List B',
|
||||
'field_email' => 'EMAIL',
|
||||
'field_first_name' => 'FNAME',
|
||||
'field_last_name' => 'LNAME',
|
||||
'field_phone' => null,
|
||||
'tag_field' => 'TAGS',
|
||||
'tag_value' => 'b-source',
|
||||
]);
|
||||
$subscriber = Subscriber::query()->create([
|
||||
'preregistration_page_id' => $pageB->id,
|
||||
'first_name' => 'A',
|
||||
'last_name' => 'B',
|
||||
'email' => 'on-b@example.com',
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post(
|
||||
route('admin.pages.subscribers.sync-mailwizz', [$pageA, $subscriber])
|
||||
);
|
||||
|
||||
$response->assertForbidden();
|
||||
Queue::assertNothingPushed();
|
||||
}
|
||||
|
||||
private function makePageWithMailwizz(): PreregistrationPage
|
||||
{
|
||||
$user = User::factory()->create(['role' => 'user']);
|
||||
|
||||
Reference in New Issue
Block a user