feat: report reviews etc ...

This commit is contained in:
2026-05-23 12:15:11 +02:00
parent 49419c1e7b
commit 4af28f3828
15 changed files with 146 additions and 0 deletions
@@ -6,6 +6,7 @@ use App\Enums\ModerationCaseStatus;
use App\Enums\ReportStatus;
use App\Models\MealPosts;
use App\Models\ModerationCase;
use App\Models\PostReviews;
use App\Models\User;
use Filament\Actions\Action;
use Filament\Actions\EditAction;
@@ -36,6 +37,7 @@ class ModerationCasesTable
return $query->where(function (Builder $query) use ($search): void {
$query
->whereHasMorph('caseable', [MealPosts::class], fn (Builder $query): Builder => $query->where('title', 'like', "%{$search}%"))
->orWhereHasMorph('caseable', [PostReviews::class], fn (Builder $query): Builder => $query->where('comment', 'like', "%{$search}%"))
->orWhereHasMorph('caseable', [User::class], fn (Builder $query): Builder => $query->where('name', 'like', "%{$search}%"));
});
}),
@@ -80,6 +82,7 @@ class ModerationCasesTable
->label(__('admin.moderation_cases.filters.target_type'))
->options([
MealPosts::class => __('admin.moderation_cases.targets.meal_post'),
PostReviews::class => __('admin.moderation_cases.targets.post_review'),
User::class => __('admin.moderation_cases.targets.user'),
]),
])
@@ -58,6 +58,22 @@ class PostReviewsController extends Controller
->setStatusCode(201);
}
public function mine(Request $request, MealPosts $mealPost): JsonResponse|PostReviewsResource
{
$this->abortIfUnavailable($mealPost);
$postReview = $mealPost->reviews()
->where('user_id', $request->user()->getKey())
->with('user:id,name,avatar_url')
->first();
if (! $postReview) {
return response()->json(['data' => null]);
}
return new PostReviewsResource($postReview);
}
public function show(PostReviews $postReview): PostReviewsResource
{
$postReview->loadMissing('mealPost.user');
+19
View File
@@ -6,6 +6,7 @@ use App\Enums\ReportReason;
use App\Http\Requests\StoreReportRequest;
use App\Http\Resources\ReportResource;
use App\Models\MealPosts;
use App\Models\PostReviews;
use App\Models\User;
use App\Services\ModerationReportService;
use Illuminate\Http\JsonResponse;
@@ -47,4 +48,22 @@ class ReportController extends Controller
->response()
->setStatusCode(201);
}
public function storePostReview(
StoreReportRequest $request,
PostReviews $postReview,
ModerationReportService $reports,
): JsonResponse {
$report = $reports->report(
reportable: $postReview,
reporter: $request->user(),
reason: ReportReason::from($request->validated('reason')),
details: $request->validated('details'),
);
return (new ReportResource($report))
->additional(['message' => __('api.reports.created')])
->response()
->setStatusCode(201);
}
}
+2
View File
@@ -3,6 +3,7 @@
namespace App\Http\Resources;
use App\Models\MealPosts;
use App\Models\PostReviews;
use App\Models\Report;
use App\Models\User;
use Illuminate\Http\Request;
@@ -31,6 +32,7 @@ class ReportResource extends JsonResource
{
return match ($this->reportable_type) {
MealPosts::class => 'meal_post',
PostReviews::class => 'post_review',
User::class => 'user',
default => 'unknown',
};
+5
View File
@@ -52,6 +52,7 @@ class ModerationCase extends Model
{
return match ($this->caseable_type) {
MealPosts::class => 'meal_post',
PostReviews::class => 'post_review',
User::class => 'user',
default => 'unknown',
};
@@ -61,6 +62,7 @@ class ModerationCase extends Model
{
return match ($this->caseable_type) {
MealPosts::class => __('admin.moderation_cases.targets.meal_post'),
PostReviews::class => __('admin.moderation_cases.targets.post_review'),
User::class => __('admin.moderation_cases.targets.user'),
default => __('admin.moderation_cases.targets.unknown'),
};
@@ -72,6 +74,9 @@ class ModerationCase extends Model
return match (true) {
$target instanceof MealPosts => $target->title,
$target instanceof PostReviews => filled($target->comment)
? str($target->comment)->limit(80)->toString()
: __('admin.moderation_cases.targets.post_review'),
$target instanceof User => $target->name,
default => (string) $this->caseable_id,
};
+12
View File
@@ -5,6 +5,8 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\MorphOne;
class PostReviews extends Model
{
@@ -27,6 +29,16 @@ class PostReviews extends Model
return $this->belongsTo(User::class);
}
public function reports(): MorphMany
{
return $this->morphMany(Report::class, 'reportable');
}
public function moderationCase(): MorphOne
{
return $this->morphOne(ModerationCase::class, 'caseable');
}
protected function casts(): array
{
return [
+7
View File
@@ -8,6 +8,7 @@ use App\Enums\ReportStatus;
use App\Enums\UserRole;
use App\Models\MealPosts;
use App\Models\ModerationCase;
use App\Models\PostReviews;
use App\Models\Report;
use App\Models\User;
use Filament\Notifications\Notification as FilamentNotification;
@@ -135,6 +136,12 @@ class ModerationReportService
422,
__('api.reports.cannot_report_own_meal'),
);
abort_if(
$reportable instanceof PostReviews && $reportable->user_id === $reporter->getKey(),
422,
__('api.reports.cannot_report_own_review'),
);
}
private function isDuplicateReportException(QueryException $exception): bool