| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- <?php
- namespace App\Http\Controllers;
- /*
- * FormSubmitController — обработка отправки веб-форм с публичного сайта.
- * Маршрут: POST /forms/{slug}/submit
- * Логика: валидация по конфигурации полей, сохранение Lead, отправка email, JSON-ответ.
- */
- use App\Mail\LeadNotification;
- use App\Models\Lead;
- use App\Models\WebForm;
- use Illuminate\Http\JsonResponse;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Mail;
- use Illuminate\Validation\ValidationException;
- class FormSubmitController extends Controller
- {
- public function submit(Request $request, string $slug): JsonResponse
- {
- $form = WebForm::where('slug', $slug)->where('is_active', true)->firstOrFail();
- // Строим правила валидации из конфигурации полей формы
- $rules = [];
- foreach ($form->fields ?? [] as $field) {
- if (empty($field['name'])) {
- continue;
- }
- $fieldRules = [];
- if (! empty($field['required'])) {
- $fieldRules[] = 'required';
- } else {
- $fieldRules[] = 'nullable';
- }
- $fieldRules[] = match ($field['type'] ?? 'text') {
- 'email' => 'email|max:200',
- 'tel' => 'string|max:30',
- 'textarea' => 'string|max:3000',
- 'checkbox' => 'accepted',
- default => 'string|max:500',
- };
- $rules[$field['name']] = implode('|', $fieldRules);
- }
- try {
- $validated = $request->validate($rules);
- } catch (ValidationException $e) {
- return response()->json(['errors' => $e->errors()], 422);
- }
- // Убираем checkbox (согласие) из сохраняемых данных — только факт согласия нужен
- $data = collect($validated)
- ->filter(fn ($v, $k) => ! $this->isConsentField($form->fields ?? [], $k))
- ->toArray();
- $lead = Lead::create([
- 'form_id' => $form->id,
- 'data' => $data,
- 'ip' => $request->ip(),
- ]);
- // Отправляем email уведомление если указан notify_email
- if ($form->notify_email) {
- try {
- Mail::to($form->notify_email)->send(new LeadNotification($lead, $form));
- } catch (\Throwable) {
- // Не прерываем работу при ошибке email
- }
- }
- return response()->json(['ok' => true]);
- }
- // Является ли поле чекбоксом-согласием (не нужно хранить в заявке)
- private function isConsentField(array $fields, string $name): bool
- {
- foreach ($fields as $field) {
- if (($field['name'] ?? '') === $name && ($field['type'] ?? '') === 'checkbox') {
- return true;
- }
- }
- return false;
- }
- }
|