photos()->get(); return response()->json([ 'success' => true, 'data' => $photos, 'profile_photo' => $person->photos()->where('is_profile_photo', true)->first() ]); } public function handlePhotoUpload($files, $personId, $captions = [], $mainPhotoIndex = null) { $uploadedPhotos = []; foreach ($files as $index => $file) { $extension = $file->getClientOriginalExtension(); $filename = Str::uuid() . '.' . $extension; $path = $file->storeAs('photos/' . $personId, $filename, 'public'); $photo = new Photo([ 'person_id' => $personId, 'filename' => $filename, 'original_filename' => $file->getClientOriginalName(), 'file_path' => Storage::url($path), 'mime_type' => $file->getMimeType(), 'file_size' => $file->getSize() / 1024, // KB 'caption' => $captions[$index] ?? null, 'is_profile_photo' => ($mainPhotoIndex !== null && $index == $mainPhotoIndex) ]); $photo->save(); $uploadedPhotos[] = $photo; } return $uploadedPhotos; } /** * Upload photos for a person */ public function upload(Request $request, $personId) { $validator = Validator::make($request->all(), [ 'photos' => 'required|array', 'photos.*' => 'required|image|max:10240', // Max 10MB per image 'captions' => 'nullable|array', 'captions.*' => 'nullable|string|max:255', 'set_as_profile' => 'nullable|boolean', ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'errors' => $validator->errors() ], 422); } // Find the person $person = Person::findOrFail($personId); $uploadedPhotos = []; // Process each uploaded photo if ($request->hasFile('photos')) { $files = $request->file('photos'); $captions = $request->input('captions', []); $setAsProfile = $request->input('set_as_profile', false); $profilePhotoSet = false; foreach ($files as $index => $file) { // Generate a unique filename $extension = $file->getClientOriginalExtension(); $filename = Str::uuid() . '.' . $extension; // Store the file $path = $file->storeAs('photos/' . $personId, $filename, 'public'); // Create photo record $photo = new Photo([ 'person_id' => $personId, 'filename' => $filename, 'original_filename' => $file->getClientOriginalName(), 'file_path' => Storage::url($path), 'mime_type' => $file->getMimeType(), 'file_size' => $file->getSize() / 1024, // Convert to KB 'caption' => $captions[$index] ?? null, 'is_profile_photo' => false ]); $photo->save(); $uploadedPhotos[] = $photo; // Set as profile photo if requested and it's the first photo if ($setAsProfile && !$profilePhotoSet) { $photo->setAsProfilePhoto(); $profilePhotoSet = true; } } } return response()->json([ 'success' => true, 'message' => 'Photos uploaded successfully', 'data' => $uploadedPhotos ]); } /** * Set a photo as the profile photo */ public function setAsProfilePhoto($photoId) { $photo = Photo::findOrFail($photoId); $result = $photo->setAsProfilePhoto(); return response()->json([ 'success' => $result, 'message' => $result ? 'Profile photo set successfully' : 'Failed to set profile photo', 'data' => $photo ]); } /** * Update photo caption */ public function updateCaption(Request $request, $photoId) { $validator = Validator::make($request->all(), [ 'caption' => 'required|string|max:255', ]); if ($validator->fails()) { return response()->json([ 'success' => false, 'errors' => $validator->errors() ], 422); } $photo = Photo::findOrFail($photoId); $photo->caption = $request->input('caption'); $photo->save(); return response()->json([ 'success' => true, 'message' => 'Caption updated successfully', 'data' => $photo ]); } /** * Delete a photo */ public function delete($photoId) { $photo = Photo::findOrFail($photoId); // Delete the physical file $path = 'public/photos/' . $photo->person_id . '/' . $photo->filename; if (Storage::exists($path)) { Storage::delete($path); } // If this was a profile photo, try to set another one if ($photo->is_profile_photo) { $nextPhoto = Photo::where('person_id', $photo->person_id) ->where('id', '!=', $photo->id) ->first(); if ($nextPhoto) { $nextPhoto->setAsProfilePhoto(); } } // Delete the database record $photo->delete(); return response()->json([ 'success' => true, 'message' => 'Photo deleted successfully' ]); } }