Files
back-meditation/app/Http/Controllers/InteractionController.php
T
2026-06-13 17:20:42 +03:30

77 lines
2.3 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
class InteractionController extends Controller
{
/**
* Comment and/or rate an item in a single request.
* Body: { content?: string, stars?: int (1-5) }
* - content → adds a comment
* - stars → sets/updates this user's rating
* At least one is required.
*/
public function store(Request $request, $type, $id)
{
$data = $request->validate([
'content' => 'nullable|string|max:1000',
'stars' => 'nullable|integer|min:1|max:5',
]);
if (!$request->filled('content') && !$request->filled('stars')) {
throw ValidationException::withMessages([
'content' => ['Provide a comment (content) and/or a rating (stars).'],
]);
}
$model = $this->getModel($type, $id);
if (!$model) {
return response()->json(['message' => 'Item not found'], 404);
}
$comment = null;
if ($request->filled('content')) {
$comment = $model->comments()->create([
'user_id' => auth()->id(),
'content' => $data['content'],
])->load('user');
}
$rating = null;
if ($request->filled('stars')) {
$rating = $model->ratings()->updateOrCreate(
['user_id' => auth()->id()],
['stars' => $data['stars']]
);
}
$model = $model->fresh();
return response()->json([
'message' => 'Interaction saved successfully',
'comment' => $comment,
'your_rating' => $rating?->stars,
'average_rating' => $model->average_rating,
'ratings_count' => $model->ratings_count,
'comments_count' => $model->comments_count,
]);
}
private function getModel($type, $id)
{
// media, music and playlist all support comments + ratings.
$models = [
'music' => \App\Models\Music::class,
'media' => \App\Models\Media::class,
'playlist' => \App\Models\MusicPlaylist::class,
];
$class = $models[$type] ?? null;
return $class ? $class::find($id) : null;
}
}