Undangan/backend/app/Http/Controllers/Api/FormApiController.php
2025-09-19 14:59:11 +07:00

220 lines
8.1 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\Pelanggan;
use App\Models\PelangganDetail;
use App\Models\Template;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class FormApiController extends Controller
{
/**
* Convert string to slug-like field name
*/
private function slugify($text)
{
return strtolower(
preg_replace('/[^A-Za-z0-9_]/', '_', trim($text))
);
}
public function store(Request $request)
{
try {
// Log incoming request for debugging
Log::info('Form submission received', [
'template_id' => $request->template_id,
'files' => array_keys($request->allFiles()),
'data_keys' => array_keys($request->except(['_token']))
]);
// ✅ Validasi dasar
$rules = [
'template_id' => 'required|exists:templates,id',
'nama_pemesan' => 'required|string|max:255',
'no_hp' => 'required|string|max:20',
'email' => 'required|email',
];
// ✅ Ambil template + fiturnya
$template = Template::with(['fiturs', 'kategori'])->findOrFail($request->template_id);
$galleryFields = []; // Track gallery field names
// ✅ Loop fitur → buat validasi dinamis
foreach ($template->fiturs as $fitur) {
$field = $this->slugify($fitur->deskripsi);
// default text input
$rules[$field] = 'nullable|string|max:255';
// tanggal
if (str_contains(strtolower($fitur->deskripsi), 'tanggal')) {
$rules[$field] = 'nullable|date';
}
// galeri (cek jumlah: Galeri 2, Galeri 5, dll.)
if (str_contains(strtolower($fitur->deskripsi), 'galeri') ||
str_contains(strtolower($fitur->deskripsi), 'gallery')) {
preg_match('/(\d+)/', $fitur->deskripsi, $matches);
$maxFiles = isset($matches[1]) ? (int) $matches[1] : 10;
// Add gallery field to tracking
$galleryFields[] = $field;
// Validation for gallery array
$rules[$field] = "nullable|array|max:$maxFiles";
$rules[$field . '.*'] = 'file|image|mimes:jpeg,png,jpg,gif,webp|max:10240'; // 10MB
}
}
Log::info('Validation rules generated', [
'rules' => $rules,
'gallery_fields' => $galleryFields
]);
// ✅ Jalankan validasi
$validatedData = $request->validate($rules);
// ✅ Process all gallery uploads
$allGalleryPaths = [];
foreach ($galleryFields as $galleryField) {
if ($request->hasFile($galleryField)) {
$galleryPaths = [];
$files = $request->file($galleryField);
Log::info("Processing files for field: $galleryField", [
'file_count' => is_array($files) ? count($files) : 1
]);
// Handle both single file and array of files
if (!is_array($files)) {
$files = [$files];
}
foreach ($files as $file) {
try {
$path = $file->store('gallery', 'public');
$galleryPaths[] = $path;
Log::info("File uploaded successfully", [
'original_name' => $file->getClientOriginalName(),
'path' => $path
]);
} catch (\Exception $e) {
Log::error("File upload failed", [
'file' => $file->getClientOriginalName(),
'error' => $e->getMessage()
]);
throw $e;
}
}
if (!empty($galleryPaths)) {
$allGalleryPaths[$galleryField] = $galleryPaths;
$validatedData[$galleryField] = $galleryPaths;
}
}
}
Log::info('All gallery uploads processed', [
'gallery_data' => $allGalleryPaths
]);
// ✅ Simpan ke tabel pelanggan
$pelanggan = Pelanggan::create([
'nama_pemesan' => $validatedData['nama_pemesan'],
'nama_template' => $template->nama_template,
'kategori' => $template->kategori->nama ?? '-',
'email' => $validatedData['email'],
'no_tlpn' => $validatedData['no_hp'],
'harga' => $template->harga,
'catatan' => $validatedData['catatan'] ?? null,
]);
// ✅ Simpan detail form (dinamis) - include gallery paths
PelangganDetail::create([
'pelanggan_id' => $pelanggan->id,
'detail_form' => $validatedData,
]);
Log::info('Form submitted successfully', [
'pelanggan_id' => $pelanggan->id,
'template_id' => $template->id
]);
return response()->json([
'success' => true,
'message' => 'Form berhasil dikirim sesuai fitur template',
'data' => $pelanggan->load('details'),
'gallery_info' => $allGalleryPaths
], 201);
} catch (\Illuminate\Validation\ValidationException $e) {
Log::error('Validation failed', [
'errors' => $e->errors(),
'input' => $request->except(['password', '_token'])
]);
return response()->json([
'success' => false,
'message' => 'Validasi gagal',
'errors' => $e->errors()
], 422);
} catch (\Exception $e) {
Log::error('Form submission failed', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
'input' => $request->except(['password', '_token'])
]);
return response()->json([
'success' => false,
'message' => 'Terjadi kesalahan internal server',
'error' => config('app.debug') ? $e->getMessage() : 'Internal server error'
], 500);
}
}
public function getFiturs($id)
{
try {
$template = Template::with(['fiturs', 'kategori'])->findOrFail($id);
return response()->json([
'success' => true,
'template' => [
'id' => $template->id,
'nama_template' => $template->nama_template,
'kategori' => $template->kategori->nama ?? '-',
'harga' => $template->harga,
'thumbnail' => $template->thumbnail ?? null,
],
'fiturs' => $template->fiturs->map(function ($fitur) {
return [
'id' => $fitur->id,
'deskripsi' => $fitur->deskripsi,
'harga' => $fitur->harga,
];
}),
]);
} catch (\Exception $e) {
Log::error('Failed to get template fiturs', [
'template_id' => $id,
'error' => $e->getMessage()
]);
return response()->json([
'success' => false,
'message' => 'Template tidak ditemukan',
'error' => config('app.debug') ? $e->getMessage() : 'Template not found'
], 404);
}
}
}