152 lines
4.1 KiB
PHP
152 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
class RatingController extends Controller
|
|
{
|
|
/**
|
|
* Add or update rating for any model
|
|
*
|
|
* @param Request $request
|
|
* @param string $type (music, media, etc.)
|
|
* @param int $id
|
|
*/
|
|
public function rate(Request $request, $type, $id)
|
|
{
|
|
$request->validate([
|
|
'stars' => 'required|integer|min:1|max:5',
|
|
]);
|
|
|
|
$model = $this->getModel($type, $id);
|
|
$this->checkAccess($model);
|
|
|
|
$rating = $model->ratings()->updateOrCreate(
|
|
['user_id' => auth()->id()],
|
|
['stars' => $request->stars]
|
|
);
|
|
|
|
return response()->json([
|
|
'message' => 'Rating submitted successfully',
|
|
'rating' => $rating,
|
|
'average_rating' => $model->fresh()->average_rating,
|
|
'user_rating' => $rating->stars,
|
|
'total_ratings' => $model->fresh()->ratings_count,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get user's rating for a model
|
|
*/
|
|
public function getUserRating($type, $id)
|
|
{
|
|
$model = $this->getModel($type, $id);
|
|
|
|
$rating = $model->ratings()
|
|
->where('user_id', auth()->id())
|
|
->first();
|
|
|
|
return response()->json([
|
|
'rating' => $rating ? $rating->stars : null,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Delete user's rating
|
|
*/
|
|
public function deleteRating($type, $id)
|
|
{
|
|
$model = $this->getModel($type, $id);
|
|
|
|
$deleted = $model->ratings()
|
|
->where('user_id', auth()->id())
|
|
->delete();
|
|
|
|
return response()->json([
|
|
'message' => $deleted ? 'Rating deleted successfully' : 'No rating found',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get all ratings for a model
|
|
*/
|
|
public function getRatings($type, $id)
|
|
{
|
|
$model = $this->getModel($type, $id);
|
|
$this->checkAccess($model);
|
|
|
|
$ratings = $model->ratings()
|
|
->with('user')
|
|
->latest()
|
|
->paginate(20);
|
|
|
|
return response()->json([
|
|
'average' => $model->average_rating,
|
|
'total' => $model->ratings_count,
|
|
'ratings' => $ratings,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get top rated items
|
|
*/
|
|
public function topRated($type)
|
|
{
|
|
$modelClass = $this->getModelClass($type);
|
|
$userId = auth()->id();
|
|
|
|
$items = $modelClass::with(['image', 'user'])
|
|
->withAvg('ratings', 'stars')
|
|
->where(function($query) use ($modelClass, $userId) {
|
|
if (method_exists($modelClass, 'isAccessible')) {
|
|
// Use model-specific access logic
|
|
} elseif (property_exists($modelClass, 'type')) {
|
|
$query->where('type', 'public')
|
|
->orWhere(function($q) use ($userId) {
|
|
$q->where('type', 'private')
|
|
->where('user_id', $userId);
|
|
});
|
|
}
|
|
})
|
|
->having('ratings_avg_stars', '>', 0)
|
|
->orderBy('ratings_avg_stars', 'desc')
|
|
->limit(10)
|
|
->get();
|
|
|
|
return response()->json($items);
|
|
}
|
|
|
|
private function getModel($type, $id)
|
|
{
|
|
$modelClass = $this->getModelClass($type);
|
|
$model = $modelClass::findOrFail($id);
|
|
|
|
return $model;
|
|
}
|
|
|
|
private function getModelClass($type)
|
|
{
|
|
$models = [
|
|
'music' => \App\Models\Music::class,
|
|
'media' => \App\Models\Media::class,
|
|
];
|
|
|
|
if (!isset($models[$type])) {
|
|
abort(404, 'Invalid model type');
|
|
}
|
|
|
|
return $models[$type];
|
|
}
|
|
|
|
private function checkAccess($model)
|
|
{
|
|
// Check if model has 'type' property (public/private)
|
|
if (property_exists($model, 'type') && $model->type === 'private') {
|
|
if (auth()->id() !== $model->user_id) {
|
|
abort(403, 'You do not have access to this item');
|
|
}
|
|
}
|
|
}
|
|
}
|