validate([ 'tid' => 'required|exists:textures', 'reason' => 'required', ]); /** @var User */ $reporter = auth()->user(); $tid = $data['tid']; $reason = $data['reason']; $can = $filter->apply('user_can_report', true, [$tid, $reason, $reporter]); if ($can instanceof Rejection) { return json($can->getReason(), 1); } $dispatcher->dispatch('report.submitting', [$tid, $reason, $reporter]); if (Report::where('reporter', $reporter->uid)->where('tid', $tid)->count() > 0) { return json(trans('skinlib.report.duplicate'), 1); } $score = option('reporter_score_modification', 0); if ($score < 0 && $reporter->score < -$score) { return json(trans('skinlib.upload.lack-score'), 1); } $reporter->score += $score; $reporter->save(); $report = new Report(); $report->tid = $tid; $report->uploader = Texture::find($tid)->uploader; $report->reporter = $reporter->uid; $report->reason = $reason; $report->status = Report::PENDING; $report->save(); $dispatcher->dispatch('report.submitted', [$report]); return json(trans('skinlib.report.success'), 0); } public function track() { $reports = Report::where('reporter', auth()->id()) ->orderBy('report_at', 'desc') ->paginate(10); return view('user.report', ['reports' => $reports]); } public function manage(Request $request) { $q = $request->input('q'); return Report::usingSearchString($q) ->with(['texture', 'textureUploader', 'informer']) ->paginate(9); } public function review( Report $report, Request $request, Dispatcher $dispatcher ) { $data = $request->validate([ 'action' => ['required', Rule::in(['delete', 'ban', 'reject'])], ]); $action = $data['action']; $dispatcher->dispatch('report.reviewing', [$report, $action]); if ($action == 'reject') { if ( $report->informer && ($score = option('reporter_score_modification', 0)) > 0 && $report->status == Report::PENDING ) { $report->informer->score -= $score; $report->informer->save(); } $report->status = Report::REJECTED; $report->save(); $dispatcher->dispatch('report.rejected', [$report]); return json(trans('general.op-success'), 0, ['status' => Report::REJECTED]); } switch ($action) { case 'delete': /** @var Texture */ $texture = $report->texture; if ($texture) { $dispatcher->dispatch('texture.deleting', [$texture]); Storage::disk('textures')->delete($texture->hash); $texture->delete(); $dispatcher->dispatch('texture.deleted', [$texture]); } else { // The texture has been deleted by its uploader // We will return the score, but will not give the informer any reward self::returnScore($report); $report->status = Report::RESOLVED; $report->save(); $dispatcher->dispatch('report.resolved', [$report, $action]); return json(trans('general.texture-deleted'), 0, ['status' => Report::RESOLVED]); } break; case 'ban': $uploader = User::find($report->uploader); if (!$uploader) { return json(trans('admin.users.operations.non-existent'), 1); } if (auth()->user()->permission <= $uploader->permission) { return json(trans('admin.users.operations.no-permission'), 1); } $uploader->permission = User::BANNED; $uploader->save(); $dispatcher->dispatch('user.banned', [$uploader]); break; } self::returnScore($report); self::giveAward($report); $report->status = Report::RESOLVED; $report->save(); $dispatcher->dispatch('report.resolved', [$report, $action]); return json(trans('general.op-success'), 0, ['status' => Report::RESOLVED]); } public static function returnScore($report) { if ($report->status == Report::PENDING && ($score = option('reporter_score_modification', 0)) < 0) { $report->informer->score -= $score; $report->informer->save(); } } public static function giveAward($report) { if ($report->status == Report::PENDING) { $report->informer->score += option('reporter_reward_score', 0); $report->informer->save(); } } }