add controllers, servoices

This commit is contained in:
root
2026-03-09 02:52:13 -04:00
parent c8de5f7edc
commit d76c871cb7
501 changed files with 34439 additions and 21843 deletions
@@ -0,0 +1,184 @@
<?php
namespace App\Http\Controllers\Api\Email;
use App\Http\Controllers\Api\BaseApiController;
use App\Services\BroadcastEmail\BroadcastEmailComposerService;
use App\Services\BroadcastEmail\BroadcastEmailDispatchService;
use App\Services\BroadcastEmail\BroadcastEmailImageService;
use App\Services\BroadcastEmail\BroadcastEmailRecipientService;
use App\Services\BroadcastEmail\BroadcastEmailSenderOptionsService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class BroadcastEmailController extends BaseApiController
{
private BroadcastEmailSenderOptionsService $senderOptions;
private BroadcastEmailRecipientService $recipients;
private BroadcastEmailComposerService $composer;
private BroadcastEmailDispatchService $dispatch;
private BroadcastEmailImageService $imageService;
public function __construct(
BroadcastEmailSenderOptionsService $senderOptions,
BroadcastEmailRecipientService $recipients,
BroadcastEmailComposerService $composer,
BroadcastEmailDispatchService $dispatch,
BroadcastEmailImageService $imageService
) {
parent::__construct();
$this->senderOptions = $senderOptions;
$this->recipients = $recipients;
$this->composer = $composer;
$this->dispatch = $dispatch;
$this->imageService = $imageService;
}
public function options(): JsonResponse
{
return response()->json([
'ok' => true,
'parents' => $this->recipients->parentsWithEmails(),
'fromOptions' => $this->senderOptions->listOptions(),
]);
}
public function send(Request $request): JsonResponse
{
$mode = (string) ($request->input('mode') ?? 'standard');
$subject = trim((string) ($request->input('subject') ?? ''));
$fromKey = trim((string) ($request->input('from_key') ?? 'general'));
$body = (string) ($request->input('body_html') ?? '');
$wrapLayout = (bool) $request->boolean('wrap_layout');
$preheader = (string) ($request->input('preheader') ?? '');
$ctaText = (string) ($request->input('cta_text') ?? '');
$ctaUrl = (string) ($request->input('cta_url') ?? '');
$testEmail = trim((string) ($request->input('test_email') ?? ''));
$isTestOnly = (bool) $request->boolean('send_test_only');
$body = $this->composer->sanitizeHtml($body);
if ($subject === '' || $body === '') {
return response()->json([
'ok' => false,
'message' => 'Subject and Body are required.',
], 422);
}
$personalize = $mode === 'personalized';
if ($isTestOnly) {
if ($testEmail === '') {
return response()->json([
'ok' => false,
'message' => 'Provide a test email address.',
], 422);
}
$result = $this->dispatch->sendTest([
'wrap_layout' => $wrapLayout,
'subject' => $subject,
'body_html' => $body,
'recipient_name' => 'Parent',
'preheader' => $preheader,
'cta_text' => $ctaText,
'cta_url' => $ctaUrl,
'personalize' => $personalize,
'test_email' => $testEmail,
'from_key' => $fromKey,
]);
return response()->json($result, $result['ok'] ? 200 : 500);
}
$rawIds = $request->input('parent_ids', []);
$ids = $this->normalizeIds($rawIds);
if (empty($ids)) {
return response()->json([
'ok' => false,
'message' => 'Please select at least one parent.',
], 422);
}
$recipients = $this->recipients->recipientsByIds($ids);
if (empty($recipients)) {
return response()->json([
'ok' => false,
'message' => 'No valid parent emails found.',
], 422);
}
$stats = $this->dispatch->sendBroadcast([
'wrap_layout' => $wrapLayout,
'subject' => $subject,
'body_html' => $body,
'preheader' => $preheader,
'cta_text' => $ctaText,
'cta_url' => $ctaUrl,
'personalize' => $personalize,
'from_key' => $fromKey,
'mode' => $mode,
], $recipients);
$message = sprintf(
'Broadcast finished. Mode: %s. Sent: %d/%d. Failures: %d.',
$stats['mode'],
$stats['sent'],
$stats['attempted'],
$stats['failed']
);
return response()->json([
'ok' => $stats['failed'] === 0,
'stats' => $stats,
'message' => $message,
]);
}
public function uploadImage(Request $request): JsonResponse
{
$file = $request->file('image');
if (!$file || !$file->isValid()) {
return response()->json([
'success' => false,
'error' => 'No image uploaded',
], 400);
}
$result = $this->imageService->store($file);
if (!$result['ok']) {
return response()->json([
'success' => false,
'error' => $result['error'] ?? 'Upload failed',
], $result['status'] ?? 400);
}
$newHash = function_exists('csrf_hash') ? csrf_hash() : csrf_token();
return response()->json([
'success' => true,
'url' => $result['url'],
'csrf_hash' => $newHash,
])->header('X-CSRF-HASH', (string) $newHash);
}
private function normalizeIds($rawIds): array
{
$ids = [];
$raw = is_array($rawIds) ? $rawIds : [$rawIds];
foreach ($raw as $value) {
if (is_string($value) && strpos($value, ',') !== false) {
foreach (explode(',', $value) as $piece) {
$ids[] = (int) $piece;
}
continue;
}
$ids[] = (int) $value;
}
return array_values(array_unique(array_filter($ids)));
}
}