<?php
 namespace App\Http\Controllers\Api\Admin; use App\Http\Controllers\Controller; use App\Http\Requests\Admin\ImportSubscribersRequest; use App\Http\Requests\Admin\SegmentSubscribersRequest; use App\Http\Requests\Admin\StoreSubscriberRequest; use App\Models\EmailMarketingList; use App\Models\EmailMarketingSubscriber; use App\Services\CsvSubscriberImportService; use App\Services\EmailMarketingSegmentService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class EmailMarketingSubscriberApiController extends Controller { public function records(Request $request, EmailMarketingList $list): JsonResponse { $draw = (int) $request->input('draw', 1); $start = (int) $request->input('start', 0); $length = (int) $request->input('length', 25); $search = $request->input('search.value', ''); $base = $list->subscribers(); if ($status = $request->input('filter.status')) { $base->where('email_marketing_subscribers.status', $status); } if ($source = $request->input('filter.source')) { $base->where('email_marketing_list_subscriber.source', $source); } $total = $base->count(); if ($search !== '') { $base->where(function ($q) use ($search) { $q->where('email_marketing_subscribers.email', 'like', "%$search%") ->orWhere('first_name', 'like', "%$search%") ->orWhere('last_name', 'like', "%$search%"); }); } $filtered = $base->count(); $rows = $base->orderByPivot('joined_at', 'desc') ->skip($start)->take($length) ->get(); return response()->json([ 'draw' => $draw, 'recordsTotal' => $total, 'recordsFiltered' => $filtered, 'data' => $rows->map(fn ($s) => [ 'id' => $s->id, 'email' => $s->email, 'name' => trim(($s->first_name ?? '').' '.($s->last_name ?? '')) ?: null, 'status' => $s->status, 'source' => $s->pivot->source, 'joined_at' => $s->pivot->joined_at ? \Carbon\Carbon::parse($s->pivot->joined_at)->format('Y-m-d H:i') : null, ]), ]); } public function store(StoreSubscriberRequest $request, EmailMarketingList $list): JsonResponse { return DB::transaction(function () use ($request, $list) { $sub = EmailMarketingSubscriber::firstOrCreate( ['email' => $request->email], [ 'first_name' => $request->first_name, 'last_name' => $request->last_name, 'status' => 'subscribed', 'source' => 'manual', ], ); $list->subscribers()->syncWithoutDetaching([ $sub->id => ['joined_at' => now(), 'source' => 'manual'], ]); $list->recountSubscribers(); return response()->json(['success' => true, 'subscriber_id' => $sub->id]); }); } public function destroy(Request $request, EmailMarketingList $list, EmailMarketingSubscriber $subscriber): JsonResponse { $list->subscribers()->detach($subscriber->id); $list->recountSubscribers(); return response()->json(['success' => true]); } public function segmentPreview( SegmentSubscribersRequest $request, EmailMarketingList $list, EmailMarketingSegmentService $svc ): JsonResponse { return response()->json([ 'success' => true, 'count' => $svc->preview($request->criterion, $request->validated()), ]); } public function segmentAttach( SegmentSubscribersRequest $request, EmailMarketingList $list, EmailMarketingSegmentService $svc ): JsonResponse { $added = 0; $skipped = 0; DB::transaction(function () use ($request, $list, $svc, &$added, &$skipped) { foreach ($svc->emails($request->criterion, $request->validated()) as $row) { $sub = EmailMarketingSubscriber::firstOrCreate( ['email' => $row['email']], [ 'first_name' => $row['first_name'], 'last_name' => $row['last_name'], 'client_id' => $row['client_id'], 'status' => 'subscribed', 'source' => 'segment', ], ); $alreadyAttached = $list->subscribers() ->where('email_marketing_subscriber_id', $sub->id) ->exists(); if ($alreadyAttached) { $skipped++; continue; } $list->subscribers()->attach($sub->id, [ 'joined_at' => now(), 'source' => 'segment', ]); $added++; } $list->recountSubscribers(); }); return response()->json([ 'success' => true, 'added' => $added, 'skipped' => $skipped, ]); } public function import( ImportSubscribersRequest $request, EmailMarketingList $list, CsvSubscriberImportService $svc ): JsonResponse { $result = $svc->import($list, $request->file('csv')); return response()->json(array_merge(['success' => true], $result)); } } 