json([ 'status' => 'success', 'data' => $specializations ]); } catch (\Exception $e) { return response()->json([ 'status' => 'error', 'message' => 'Gagal mengambil data spesialisasi', 'error' => $e->getMessage() ], 500); } } public function store(Request $request) { try { $validator = Validator::make($request->all(), [ 'name' => 'required|string|max:255', 'category' => 'required|string|max:255', 'icon' => 'nullable|string', 'photo' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048' ]); if ($validator->fails()) { \Log::error('Validation failed', ['errors' => $validator->errors()]); return response()->json([ 'status' => 'error', 'message' => $validator->errors() ], 422); } $specialization = new TailorSpecialization(); $specialization->name = $request->name; $specialization->category = $request->category; $specialization->icon = $request->icon; $specialization->save(); if ($request->hasFile('photo')) { try { $photo = $request->file('photo'); \Log::info('Photo file information', [ 'original_name' => $photo->getClientOriginalName(), 'mime_type' => $photo->getMimeType(), 'size' => $photo->getSize(), 'error' => $photo->getError() ]); if (!$photo->isValid()) { throw new \Exception('Invalid file upload: ' . $photo->getErrorMessage()); } // Simpan file menggunakan putFileAs $filename = 'specialization_' . time() . '_' . $specialization->id . '.' . $photo->getClientOriginalExtension(); // Pastikan direktori exists $path = storage_path('app/public/specialization_photos'); if (!file_exists($path)) { mkdir($path, 0755, true); } // Simpan file menggunakan move $photo->move($path, $filename); // Verifikasi file exists if (!file_exists($path . '/' . $filename)) { throw new \Exception('File not found after moving'); } $specialization->photo = '/storage/specialization_photos/' . $filename; $specialization->save(); \Log::info('File saved successfully', [ 'path' => $path . '/' . $filename, 'exists' => file_exists($path . '/' . $filename), 'url' => $specialization->photo ]); } catch (\Exception $e) { \Log::error('Error handling photo upload', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); throw new \Exception('Error handling photo: ' . $e->getMessage()); } } return response()->json([ 'status' => 'success', 'message' => 'Spesialisasi berhasil ditambahkan', 'data' => $specialization ], 201); } catch (\Exception $e) { \Log::error('Error in store method', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return response()->json([ 'status' => 'error', 'message' => 'Terjadi kesalahan saat menambahkan spesialisasi: ' . $e->getMessage() ], 500); } } public function show($id) { try { $specialization = TailorSpecialization::findOrFail($id); return response()->json([ 'status' => 'success', 'data' => $specialization ]); } catch (\Exception $e) { return response()->json([ 'status' => 'error', 'message' => 'Spesialisasi tidak ditemukan', 'error' => $e->getMessage() ], 404); } } public function update(Request $request, $id) { try { \Log::info('Update request received', [ 'id' => $id, 'request_data' => $request->all(), 'has_file' => $request->hasFile('photo'), 'content_type' => $request->header('Content-Type'), 'files' => $_FILES, // Log PHP's native FILES array 'method' => $request->method() ]); // Alternate way to get form data for PUT requests $input = []; if ($request->isMethod('put') && empty($request->all())) { // Try to get data from PHP's input directly for PUT parse_str(file_get_contents("php://input"), $putData); \Log::info('PUT data parsed', ['put_data' => $putData]); // Basic fields $input['name'] = $putData['name'] ?? null; $input['category'] = $putData['category'] ?? null; $input['icon'] = $putData['icon'] ?? null; // Use native FILES for the photo if (!empty($_FILES['photo']['name'])) { $input['photo'] = $_FILES['photo']; } } else { $input = $request->all(); } // Debug untuk memastikan data diterima dengan benar \Log::info('Input data', [ 'input' => $input, 'name_exists' => isset($input['name']), 'category_exists' => isset($input['category']), ]); $validator = Validator::make($input, [ 'name' => 'required|string|max:255', 'category' => 'required|string|max:255', 'icon' => 'nullable|string', 'photo' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048' ]); if ($validator->fails()) { \Log::error('Validation failed', [ 'errors' => $validator->errors() ]); return response()->json([ 'status' => 'error', 'message' => 'Validasi gagal', 'errors' => $validator->errors() ], 422); } $specialization = TailorSpecialization::findOrFail($id); \Log::info('Current specialization data', [ 'before_update' => $specialization->toArray() ]); // Update basic fields $specialization->name = $input['name']; $specialization->category = $input['category']; $specialization->icon = $input['icon'] ?? null; if ($request->hasFile('photo')) { \Log::info('Processing photo upload'); // Delete old photo if exists if ($specialization->photo) { $oldPhotoPath = str_replace('/storage/', '', $specialization->photo); if (Storage::disk('public')->exists($oldPhotoPath)) { Storage::disk('public')->delete($oldPhotoPath); \Log::info('Old photo deleted', ['path' => $oldPhotoPath]); } } $photo = $request->file('photo'); $filename = 'specialization_' . time() . '_' . $id . '.' . $photo->getClientOriginalExtension(); // Pastikan direktori exists $path = storage_path('app/public/specialization_photos'); if (!file_exists($path)) { mkdir($path, 0755, true); } // Simpan file menggunakan move $photo->move($path, $filename); $specialization->photo = '/storage/specialization_photos/' . $filename; \Log::info('New photo saved', ['path' => $specialization->photo]); } $specialization->save(); // Force refresh from database $specialization = TailorSpecialization::findOrFail($id); \Log::info('Specialization updated successfully', [ 'after_update' => $specialization->toArray() ]); return response()->json([ 'status' => 'success', 'message' => 'Spesialisasi berhasil diperbarui', 'data' => $specialization ]); } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { \Log::error('Specialization not found', ['id' => $id]); return response()->json([ 'status' => 'error', 'message' => 'Spesialisasi tidak ditemukan' ], 404); } catch (\Exception $e) { \Log::error('Update failed', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return response()->json([ 'status' => 'error', 'message' => 'Gagal memperbarui spesialisasi', 'error' => $e->getMessage() ], 500); } } public function destroy($id) { try { $specialization = TailorSpecialization::findOrFail($id); // Hapus foto jika ada if ($specialization->photo) { $photoPath = str_replace('/storage/', '', $specialization->photo); if (Storage::disk('public')->exists($photoPath)) { Storage::disk('public')->delete($photoPath); } } // Hapus spesialisasi $specialization->delete(); return response()->json([ 'status' => 'success', 'message' => 'Spesialisasi berhasil dihapus' ]); } catch (\Exception $e) { return response()->json([ 'status' => 'error', 'message' => 'Gagal menghapus spesialisasi', 'error' => $e->getMessage() ], 500); } } /** * Get all specializations with photos grouped by category */ public function getAllSpecializations() { try { $specializations = TailorSpecialization::all() ->groupBy('category') ->map(function ($items) { return $items->map(function ($item) { return [ 'id' => $item->id, 'name' => $item->name, 'photo' => $item->photo, 'category' => $item->category ]; }); }); return response()->json([ 'status' => 'success', 'message' => 'Data spesialisasi berhasil diambil', 'data' => $specializations ]); } catch (\Exception $e) { return response()->json([ 'status' => 'error', 'message' => 'Terjadi kesalahan saat mengambil data spesialisasi', 'error' => $e->getMessage() ], 500); } } /** * Update foto spesialisasi */ public function updatePhoto(Request $request, $id) { try { \Log::info('User attempting to update photo', [ 'user' => auth()->user(), 'id' => $id ]); if (!auth()->user()->isAdmin()) { \Log::warning('Unauthorized access attempt', [ 'user' => auth()->user(), 'role' => auth()->user()->role ]); return response()->json([ 'status' => 'error', 'message' => 'Unauthorized', 'error' => 'Only admin can update specialization photos' ], 403); } $validator = Validator::make($request->all(), [ 'photo' => 'required|image|mimes:jpeg,png,jpg|max:2048' ]); if ($validator->fails()) { \Log::error('Validation failed', [ 'errors' => $validator->errors() ]); return response()->json([ 'status' => 'error', 'message' => 'Error validasi', 'errors' => $validator->errors() ], 422); } $specialization = TailorSpecialization::findOrFail($id); // Hapus foto lama jika ada if ($specialization->photo) { $oldPhotoPath = str_replace('/storage/', '', $specialization->photo); if (Storage::disk('public')->exists($oldPhotoPath)) { Storage::disk('public')->delete($oldPhotoPath); } } // Upload dan simpan foto baru $photo = $request->file('photo'); $fileName = 'specialization_' . time() . '_' . $id . '.' . $photo->getClientOriginalExtension(); $photo->storeAs('specialization_photos', $fileName, 'public'); // Update path foto di database $specialization->photo = '/storage/specialization_photos/' . $fileName; $specialization->save(); \Log::info('Photo updated successfully', [ 'specialization_id' => $id, 'file_name' => $fileName ]); return response()->json([ 'status' => 'success', 'message' => 'Foto spesialisasi berhasil diupdate', 'data' => [ 'photo' => $specialization->photo ] ]); } catch (\Exception $e) { \Log::error('Error updating photo', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return response()->json([ 'status' => 'error', 'message' => 'Error update foto', 'error' => $e->getMessage() ], 500); } } }