Progress commit on report system

This commit is contained in:
Josef Citrine 2017-05-19 11:22:14 +01:00
parent fb50ef06ab
commit 11520e4d96
6 changed files with 272 additions and 0 deletions

View file

@ -0,0 +1,22 @@
<?php
namespace Poniverse\Ponyfm\Http\Controllers\Api\Web;
use Response;
use Poniverse\Ponyfm\Http\Controllers\ApiControllerBase;
use Poniverse\Ponyfm\Models\Report;
class ReportController extends ApiControllerBase
{
public function getReportCategories($type) {
$type_id = Report::getResourceTypeIdFromString($type);
$categories = Report::getCategories($type_id);
return Response::json(['categories' => $categories]);
}
public function getReports() {
$reports = Report::all();
$reports[0]['type_string'] = $reports[0]->resource();
return $reports;
}
}

View file

@ -281,6 +281,10 @@ class TracksController extends ApiControllerBase
return Response::json(Track::mapPrivateTrackShow($track), 200);
}
public function postReport() {
}
/**
* To be run after aggregating the total number of tracks for a given query.
* This is separated from applyFilters() because Postgres doesn't allow

148
app/Models/Report.php Normal file
View file

@ -0,0 +1,148 @@
<?php
namespace Poniverse\Ponyfm\Models;
use DB;
use Illuminate\Database\Eloquent\Model;
/**
* Poniverse\Ponyfm\Models\Report
*
* @property integer $id
* @property integer $reporter_id
* @property integer $resource_type
* @property integer $resource_id
* @property integer $category
* @property string $message
* @property bool $resolved
* @property integer $resolved_by
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property \Carbon\Carbon $resolved_at
*/
class Report extends Model
{
protected $dates = ['created_at', 'updated_at', 'resolved_at'];
/**
* These constants are an implementation detail of this model and should
* not be used directly in other classes. They're used to efficiently
* store the type of resource this notification is about in the database.
*
* The "resource_type" attribute is transformed into a class name at runtime
* so that the use of an integer in the database to represent this info
* remains an implementation detail of this model. Outside of this class,
* the resource_type attribute should be treated as a fully-qualified class
* name.
*/
const TYPE_TRACK = 1;
const TYPE_USER = 2;
const TYPE_COMMENT = 3;
const TYPE_NAMES = [
Report::TYPE_TRACK => "track",
Report::TYPE_USER => "user",
Report::TYPE_COMMENT => "comment"
];
/**
* These values are stored in the "report_categories" table
* Make sure when adding a new category that you write a migration
* to update that table as well.
*/
const CATEGORY_COPYRIGHT = 1;
const CATEGORY_HARASSMENT = 2;
const CATEGORY_OFFENSIVE = 3;
const CATEGORY_SPAM = 4;
const CATEGORY_NONPONY = 5;
/**
* You shouldn't be able to report comments for copyright infringement
* or being 'non-pony'. Here we outline which categories we can use
*/
const COMMENT_REPORT_CATEGORIES = [
Report::CATEGORY_HARASSMENT,
Report::CATEGORY_OFFENSIVE,
Report::CATEGORY_SPAM
];
public function reporter()
{
return $this->belongsTo(User::class, 'reporter_id', 'id');
}
public function resource()
{
return $this->morphTo('resource', 'resource_type', 'resource_id');
}
public function getResourceTypeAttribute($value)
{
switch ($value) {
case static::TYPE_TRACK:
return Track::class;
case static::TYPE_USER:
return User::class;
case static::TYPE_COMMENT:
return Comment::class;
default:
// Null must be returned here for Eloquent's eager-loading
// of the polymorphic relation to work.
return null;
}
}
public function setResourceTypeAttribute($value)
{
switch ($value) {
case Track::class:
$this->attributes['resource_type'] = static::TYPE_TRACK;
break;
case User::class:
$this->attributes['resource_type'] = static::TYPE_USER;
break;
case Comment::class:
$this->attributes['resource_type'] = static::TYPE_COMMENT;
break;
}
}
public function getResourceTypeString():string
{
return $this->getResourceTypeStringFromId($this->resource_type);
}
public static function getResourceTypeStringFromId($id):string {
if (array_key_exists($id, Report::TYPE_NAMES)) {
return Report::TYPE_NAMES[$id];
}
throw new \Exception("Unknown resource type id {$id}");
}
public static function getResourceTypeIdFromString($name):int {
$key = array_search($name, Report::TYPE_NAMES);
if ($key) {
return $key;
}
throw new \Exception("Unknown resource type {$name}");
}
public static function getCategories($type = null) {
$catQuery = DB::table('report_categories')->select('*');
if ($type == Report::TYPE_COMMENT) {
$catQuery->whereIn('report_category', Report::COMMENT_REPORT_CATEGORIES);
}
$categories = $catQuery->get();
return $categories;
}
}

View file

@ -0,0 +1,27 @@
<?php
/**
* Created by IntelliJ IDEA.
* User: Joe
* Date: 19/05/2017
* Time: 08:09
*/
namespace Poniverse\Ponyfm\Models;
use Illuminate\Database\Eloquent\Model;
/**
* Poniverse\Ponyfm\Models\ReportMessage
*
* @property integer $id
* @property integer $user_id
* @property integer $report_id
* @property string $message
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
*/
class ReportMessage extends Model
{
protected $dates = ['created_at', 'updated_at'];
}

View file

@ -0,0 +1,67 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateReportsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('report_categories', function (Blueprint $table) {
$table->unsignedTinyInteger('report_category')->primary();
$table->string('name');
$table->string('description');
});
DB::table('report_categories')->insert([
['report_category' => 1, 'name' => 'Copyright Infringement', 'description' => 'Such as re-uploading other people\'s tracks without permission'],
['report_category' => 2, 'name' => 'Harassment', 'description' => 'Attacks or threats on individuals through lyrics, repeated harassing comments, etc'],
['report_category' => 3, 'name' => 'Offensive', 'description' => 'Includes hate speech, extremely vulgar language and sexual content'],
['report_category' => 4, 'name' => 'Spam', 'description' => 'Spam and advertising are not allowed. You may advertise your social media in your descriptions but don\'t spam tracks or comments'],
['report_category' => 5, 'name' => 'Non-Pony', 'description' => 'We only host pony music and we are removing anything that is clearly non-pony. Pony inspired tracks are fine however'],
]);
Schema::create('reports', function (Blueprint $table) {
$table->increments('id');
$table->integer('reporter_id')->unsigned();
$table->integer('resource_type')->unsigned();
$table->integer('resource_id')->unsigned();
$table->unsignedTinyInteger('category');
$table->text('message', 65535);
$table->timestamps();
$table->dateTime('resolved_at')->nullable()->index();
$table->foreign('reporter_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('category')->references('report_category')->on('report_categories');
});
Schema::create('report_messages', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('report_id')->unsigned();
$table->text('message', 65535);
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('report_id')->references('id')->on('reports')->onUpdate('RESTRICT')->onDelete('RESTRICT');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('reports');
Schema::dropIfExists('report_categories');
Schema::dropIfExists('report_messages');
}
}

View file

@ -191,6 +191,8 @@ Route::group(['prefix' => 'api/web', 'middleware' => 'cors'], function () {
Route::get('/favourites/tracks', 'Api\Web\FavouritesController@getTracks');
Route::get('/favourites/albums', 'Api\Web\FavouritesController@getAlbums');
Route::get('/favourites/playlists', 'Api\Web\FavouritesController@getPlaylists');
Route::get('/report/categories/{type}', 'Api\Web\ReportController@getReportCategories');
});
Route::group(['prefix' => 'admin', 'middleware' => ['auth', 'can:access-admin-area']], function () {
@ -212,6 +214,8 @@ Route::group(['prefix' => 'api/web', 'middleware' => 'cors'], function () {
Route::post('/announcements', 'Api\Web\AnnouncementsController@postCreate');
Route::put('/announcements/{id}', 'Api\Web\AnnouncementsController@putUpdate')->where('id', '\d+');
Route::delete('/announcements/{id}', 'Api\Web\AnnouncementsController@deleteItem')->where('id', '\d+');
Route::get('/reports', 'Api\Web\ReportController@getReports');
});
Route::get('/auth/current', 'Api\Web\AccountController@getCurrentUser');