mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 06:51:10 -05:00
212 lines
6.6 KiB
PHP
212 lines
6.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Park;
|
|
use App\Models\Photo;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Intervention\Image\ImageManager;
|
|
use Intervention\Image\Drivers\Gd\Driver;
|
|
use Intervention\Image\Encoders\JpegEncoder;
|
|
use Illuminate\Support\Str;
|
|
|
|
class PhotoController extends Controller
|
|
{
|
|
/**
|
|
* Display a listing of the photos for a park.
|
|
*/
|
|
public function index(Park $park)
|
|
{
|
|
$photos = $park->photos()->ordered()->get();
|
|
|
|
return response()->json([
|
|
'photos' => $photos,
|
|
'featured_photo' => $park->featuredPhoto(),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Store a newly uploaded photo.
|
|
*/
|
|
public function store(Request $request, Park $park)
|
|
{
|
|
$request->validate([
|
|
'photo' => 'required|image|max:10240', // 10MB max
|
|
'title' => 'nullable|string|max:255',
|
|
'description' => 'nullable|string',
|
|
'alt_text' => 'nullable|string|max:255',
|
|
'credit' => 'nullable|string|max:255',
|
|
'source_url' => 'nullable|url|max:255',
|
|
'is_featured' => 'nullable|boolean',
|
|
]);
|
|
|
|
// Handle file upload
|
|
if ($request->hasFile('photo')) {
|
|
$file = $request->file('photo');
|
|
$originalFilename = $file->getClientOriginalName();
|
|
$extension = $file->getClientOriginalExtension();
|
|
|
|
// Generate a unique filename
|
|
$filename = time() . '_' . Str::slug(pathinfo($originalFilename, PATHINFO_FILENAME)) . '.' . $extension;
|
|
|
|
// Define the storage path
|
|
$storagePath = 'photos/parks/' . $park->id;
|
|
$fullPath = $storagePath . '/' . $filename;
|
|
|
|
// Store the original file
|
|
$file->storeAs('public/' . $storagePath, $filename);
|
|
|
|
// Create image manager instance
|
|
$manager = new ImageManager(new Driver());
|
|
|
|
// Get image dimensions
|
|
$image = $manager->read($file);
|
|
$width = $image->width();
|
|
$height = $image->height();
|
|
|
|
// Generate thumbnail
|
|
$thumbnailFilename = pathinfo($filename, PATHINFO_FILENAME) . '_thumb.' . $extension;
|
|
$thumbnail = $manager->read($file)->scaleDown(width: 300, height: 300);
|
|
|
|
// Save thumbnail
|
|
$encodedThumbnail = $thumbnail->encode(
|
|
new JpegEncoder(80)
|
|
);
|
|
Storage::put(
|
|
'public/' . $storagePath . '/' . $thumbnailFilename,
|
|
$encodedThumbnail->toString()
|
|
);
|
|
|
|
// Create photo record
|
|
$photo = $park->addPhoto([
|
|
'title' => $request->input('title'),
|
|
'description' => $request->input('description'),
|
|
'file_path' => $fullPath,
|
|
'file_name' => $originalFilename,
|
|
'file_size' => $file->getSize(),
|
|
'mime_type' => $file->getMimeType(),
|
|
'width' => $width,
|
|
'height' => $height,
|
|
'alt_text' => $request->input('alt_text'),
|
|
'credit' => $request->input('credit'),
|
|
'source_url' => $request->input('source_url'),
|
|
'is_featured' => $request->input('is_featured', false),
|
|
]);
|
|
|
|
return response()->json([
|
|
'message' => 'Photo uploaded successfully',
|
|
'photo' => $photo,
|
|
], 201);
|
|
}
|
|
|
|
return response()->json([
|
|
'message' => 'No photo file provided',
|
|
], 400);
|
|
}
|
|
|
|
/**
|
|
* Display the specified photo.
|
|
*/
|
|
public function show(Photo $photo)
|
|
{
|
|
return response()->json($photo);
|
|
}
|
|
|
|
/**
|
|
* Update the specified photo.
|
|
*/
|
|
public function update(Request $request, Photo $photo)
|
|
{
|
|
$request->validate([
|
|
'title' => 'nullable|string|max:255',
|
|
'description' => 'nullable|string',
|
|
'alt_text' => 'nullable|string|max:255',
|
|
'credit' => 'nullable|string|max:255',
|
|
'source_url' => 'nullable|url|max:255',
|
|
'is_featured' => 'nullable|boolean',
|
|
]);
|
|
|
|
$photo->update($request->only([
|
|
'title', 'description', 'alt_text', 'credit', 'source_url'
|
|
]));
|
|
|
|
// Handle featured status
|
|
if ($request->has('is_featured') && $request->input('is_featured')) {
|
|
$photo->setAsFeatured();
|
|
}
|
|
|
|
return response()->json([
|
|
'message' => 'Photo updated successfully',
|
|
'photo' => $photo,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Remove the specified photo.
|
|
*/
|
|
public function destroy(Photo $photo)
|
|
{
|
|
// Get the file paths
|
|
$filePath = 'public/' . $photo->file_path;
|
|
$pathInfo = pathinfo($photo->file_path);
|
|
$thumbnailPath = 'public/' . $pathInfo['dirname'] . '/' . $pathInfo['filename'] . '_thumb.' . $pathInfo['extension'];
|
|
|
|
// Delete the files
|
|
Storage::delete([$filePath, $thumbnailPath]);
|
|
|
|
// Delete the record
|
|
$photo->delete();
|
|
|
|
return response()->json([
|
|
'message' => 'Photo deleted successfully',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Reorder photos for a park.
|
|
*/
|
|
public function reorder(Request $request, Park $park)
|
|
{
|
|
$request->validate([
|
|
'photo_ids' => 'required|array',
|
|
'photo_ids.*' => 'required|integer|exists:photos,id',
|
|
]);
|
|
|
|
$success = $park->reorderPhotos($request->input('photo_ids'));
|
|
|
|
if ($success) {
|
|
return response()->json([
|
|
'message' => 'Photos reordered successfully',
|
|
]);
|
|
}
|
|
|
|
return response()->json([
|
|
'message' => 'Failed to reorder photos',
|
|
], 500);
|
|
}
|
|
|
|
/**
|
|
* Set a photo as featured.
|
|
*/
|
|
public function setFeatured(Request $request, Park $park, Photo $photo)
|
|
{
|
|
if ($photo->photoable_id !== $park->id || $photo->photoable_type !== Park::class) {
|
|
return response()->json([
|
|
'message' => 'Photo does not belong to this park',
|
|
], 400);
|
|
}
|
|
|
|
$success = $park->setFeaturedPhoto($photo);
|
|
|
|
if ($success) {
|
|
return response()->json([
|
|
'message' => 'Featured photo set successfully',
|
|
]);
|
|
}
|
|
|
|
return response()->json([
|
|
'message' => 'Failed to set featured photo',
|
|
], 500);
|
|
}
|
|
} |