w0bm.com v1.5z FULL.RETARD.BUILD.BUT.STILL.WORKS
This commit is contained in:
92
app/Console/Commands/AddTags.php
Normal file
92
app/Console/Commands/AddTags.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Video;
|
||||
use App\Models\User;
|
||||
use App\Models\Category;
|
||||
|
||||
|
||||
class AddTags extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'tags';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Adds category names as tags and changes filters from users.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// Videos
|
||||
echo 'UPDATING VIDEOS', PHP_EOL, '===============', PHP_EOL;
|
||||
$count = 0;
|
||||
Video::withTrashed()->with('category')->chunk(200, function($videos) use ($count) {
|
||||
foreach($videos as $v) {
|
||||
echo 'Updating Video with ID: ', $v->id, PHP_EOL;
|
||||
$v->detag();
|
||||
// quick and dirty. not 100% correct though.
|
||||
if($v->category->shortname === 'pr0n')
|
||||
$v->tag('nsfw');
|
||||
else
|
||||
$v->tag('sfw');
|
||||
|
||||
$v->tag(array_filter([$v->category->shortname
|
||||
, $v->category->name
|
||||
, $v->interpret
|
||||
, $v->songtitle
|
||||
, $v->imgsource
|
||||
], function($elem) {
|
||||
return !empty(trim($elem));
|
||||
}));
|
||||
$count++;
|
||||
}
|
||||
});
|
||||
echo PHP_EOL, PHP_EOL, 'Updated ', $count, ' Videos.', PHP_EOL, PHP_EOL, PHP_EOL;
|
||||
|
||||
|
||||
// User filters
|
||||
echo 'UPDATING USERS', PHP_EOL, '==============', PHP_EOL;
|
||||
$count = 0;
|
||||
$categories = Category::withTrashed()->get()->keyBy('id');
|
||||
|
||||
User::withTrashed()->chunk(200, function($users) use (&$count, $categories) {
|
||||
foreach($users as $u) {
|
||||
echo 'Updating User: ', $u->username, PHP_EOL;
|
||||
$u->categories = array_values($categories->filter(function($cat) use($u) {
|
||||
return !in_array($cat->id, $u->categories);
|
||||
})->map(function($cat) {
|
||||
return $cat->shortname;
|
||||
})->all());
|
||||
$u->save();
|
||||
$count++;
|
||||
}
|
||||
});
|
||||
|
||||
echo PHP_EOL, PHP_EOL, 'Updated ', $count, ' Users.', PHP_EOL, PHP_EOL, PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
33
app/Console/Commands/Inspire.php
Normal file
33
app/Console/Commands/Inspire.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Foundation\Inspiring;
|
||||
|
||||
class Inspire extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'inspire';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Display an inspiring quote';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->comment(PHP_EOL.Inspiring::quote().PHP_EOL);
|
||||
}
|
||||
}
|
52
app/Console/Commands/ReadException.php
Normal file
52
app/Console/Commands/ReadException.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class ReadException extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'exception {file=php://stdin}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Decrypts encrypted exception messages';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$input = $this->argument('file');
|
||||
$c = file_get_contents($input);
|
||||
if (false === $c) {
|
||||
$this->error('File not found');
|
||||
return;
|
||||
}
|
||||
//dd(explode(PHP_EOL, $c));
|
||||
list($iv, $c) = explode(PHP_EOL, $c);
|
||||
$iv = hex2bin($iv);
|
||||
$m = openssl_decrypt($c, 'aes128', env('APP_KEY'), 0, $iv);
|
||||
$this->line($m);
|
||||
}
|
||||
}
|
32
app/Console/Kernel.php
Normal file
32
app/Console/Kernel.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
Commands\AddTags::class,
|
||||
Commands\Inspire::class,
|
||||
Commands\ReadException::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
$schedule->command('inspire')
|
||||
->hourly();
|
||||
}
|
||||
}
|
8
app/Events/Event.php
Normal file
8
app/Events/Event.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
abstract class Event
|
||||
{
|
||||
//
|
||||
}
|
69
app/Exceptions/Handler.php
Normal file
69
app/Exceptions/Handler.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of the exception types that should not be reported.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontReport = [
|
||||
HttpException::class,
|
||||
ModelNotFoundException::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Report or log an exception.
|
||||
*
|
||||
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
|
||||
*
|
||||
* @param \Exception $e
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $e)
|
||||
{
|
||||
if (app()->bound('sentry') && $this->shouldReport($e)) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
return parent::report($e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $e
|
||||
* @return \Illuminate\Http\Response
|
||||
* @todo Perhaps replace odd encrypted error with Sentry notification
|
||||
*/
|
||||
public function render($request, Exception $e)
|
||||
{
|
||||
if ($e instanceof ModelNotFoundException) {
|
||||
$e = new NotFoundHttpException($e->getMessage(), $e);
|
||||
}
|
||||
|
||||
if ($this->isUnauthorizedException($e)) {
|
||||
$e = new HttpException(403, $e->getMessage());
|
||||
}
|
||||
if ($this->isHttpException($e)) {
|
||||
return $this->toIlluminateResponse($this->renderHttpException($e), $e);
|
||||
} else {
|
||||
$res = \Response::make(
|
||||
view('errors.500', ['exception' => $e]),
|
||||
500);
|
||||
$res->exception = $e;
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
//return parent::render($request, $e);
|
||||
}
|
||||
}
|
17
app/Helpers/HumanReadable.php
Normal file
17
app/Helpers/HumanReadable.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
class HumanReadable
|
||||
{
|
||||
public static function bytesToHuman($bytes)
|
||||
{
|
||||
$units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'];
|
||||
|
||||
for ($i = 0; $bytes > 1024; $i++) {
|
||||
$bytes /= 1024;
|
||||
}
|
||||
|
||||
return round($bytes, 2) . ' ' . $units[$i];
|
||||
}
|
||||
}
|
116
app/Http/Controllers/CategoryController.php
Normal file
116
app/Http/Controllers/CategoryController.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Category;
|
||||
use App\Models\Video;
|
||||
use App\Models\Banner;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
use App\Http\Requests;
|
||||
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('categories', ['categories' => Category::all()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param string $shortname
|
||||
* @param int $id
|
||||
* @return \Response
|
||||
*/
|
||||
public function showVideo($shortname, $id = null)
|
||||
{
|
||||
$category = Category::whereShortname($shortname)->first();
|
||||
if (is_null($category)) {
|
||||
return redirect()->back()->with('error', 'Category not found');
|
||||
}
|
||||
if (is_null($id)) {
|
||||
$video = Video::getRandom($category);
|
||||
if ($video instanceof HasMany) {
|
||||
$video = $video->first();
|
||||
}
|
||||
else {
|
||||
return redirect()->back()->with('error', 'Category is empty.');
|
||||
}
|
||||
return redirect($shortname . '/' . $video->id);
|
||||
} else {
|
||||
// Don't filter on specific video.
|
||||
// TODO: Add warning page
|
||||
$video = $category->videos()->find($id);
|
||||
}
|
||||
if (is_null($video)) {
|
||||
return redirect()->back()->with('error', 'Category is empty.');
|
||||
}
|
||||
|
||||
return view('video', [
|
||||
'video' => $video,
|
||||
'related' => $category,
|
||||
'banner' => Banner::getRandom($video->isSfw())]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return \Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
237
app/Http/Controllers/CommentController.php
Normal file
237
app/Http/Controllers/CommentController.php
Normal file
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Category;
|
||||
use App\Models\Comment;
|
||||
use App\Models\Message;
|
||||
use App\Models\ModeratorLog;
|
||||
use App\Models\Video;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Http\Requests;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class CommentController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
if(!$request->has('username')) return JsonResponse::create('Not found', '304');
|
||||
$user = User::whereUsername(urldecode($request->get('username')))->first();
|
||||
if(!$user) return JsonResponse::create('Not found', '304');
|
||||
return $user->comments()->orderBy('id', 'desc')->paginate(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request, $id)
|
||||
{
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
$xhr = $request->ajax();
|
||||
|
||||
if(is_null($user)) return $xhr ? "Not logged in" : redirect()->back()->with('error', 'Not logged in');
|
||||
if(!$request->has('comment')) return $xhr ? "You need to enter a comment" : redirect()->back()->with('error', 'You need to enter a comment');
|
||||
if(mb_strlen(trim($request->get('comment'))) > 2000 ) return $xhr ? "Comment to long" : redirect()->back()->with('error', 'Comment to long');
|
||||
|
||||
$video = Video::findOrFail($id);
|
||||
|
||||
$com = new Comment();
|
||||
$com->content = trim($request->get('comment'));
|
||||
$com->user()->associate($user);
|
||||
$com->video()->associate($video);
|
||||
$com->save();
|
||||
|
||||
$sent = [];
|
||||
foreach($com->getMentioned() as $mentioned) {
|
||||
Message::send($user->id, $mentioned->id, $user->username . ' mentioned you in a comment', view('messages.commentmention', ['video' => $video, 'user' => $user, 'comment' => $com]));
|
||||
$sent[] = $mentioned;
|
||||
}
|
||||
|
||||
foreach($com->answered() as $answered) {
|
||||
if(array_search($answered, $sent) !== false)
|
||||
continue;
|
||||
Message::send($user->id, $answered->id, $user->username . ' answered on your comment', view('messages.commentanswer', ['video' => $video, 'user' => $user, 'comment' => $com]));
|
||||
$sent[] = $answered;
|
||||
}
|
||||
|
||||
if($user->id != $video->user->id)
|
||||
if(array_search($video->user, $sent) === false)
|
||||
Message::send($user->id, $video->user->id, $user->username . ' commented on your video', view('messages.videocomment', ['video' => $video, 'user' => $user, 'comment' => $com]));
|
||||
|
||||
return $xhr ? view('partials.comment', ['comment' => $com, 'mod' => $user->can('delete_comment')]) : redirect()->back()->with('success', 'Comment successfully saved');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$comment = Comment::whereId($id)->first();
|
||||
if(!is_null($comment)) {
|
||||
return JsonResponse::create(array(
|
||||
'error' => 'null',
|
||||
'comment' => Comment::whereId($id)->first()->content)
|
||||
);
|
||||
}
|
||||
return JsonResponse::create(array(
|
||||
'error' => 'comment_not_found'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
if(!($request->has('comment')))
|
||||
return JsonResponse::create(array('error' => 'invalid_request'));
|
||||
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
if(is_null($user))
|
||||
return JsonResponse::create(array('error' => 'not_logged_in'));
|
||||
|
||||
if(!$user->can('edit_comment'))
|
||||
return JsonResponse::create(array('error' => 'insufficient_permissions'));
|
||||
|
||||
if(is_null($comment = Comment::whereId($id)->first()))
|
||||
return JsonResponse::create(array('error' => 'comment_not_found'));
|
||||
|
||||
$comment->content = trim($request->get('comment'));
|
||||
$comment->save();
|
||||
|
||||
$log = new ModeratorLog();
|
||||
$log->user()->associate($user);
|
||||
$log->type = 'edit';
|
||||
$log->target_type = 'comment';
|
||||
$log->target_id = $id;
|
||||
$log->save();
|
||||
|
||||
return JsonResponse::create(array(
|
||||
'error' => 'null',
|
||||
'rendered_comment' => Comment::simplemd($comment->content)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Request $request, $id)
|
||||
{
|
||||
if(!$request->has('reason'))
|
||||
return 'invalid_request';
|
||||
|
||||
$reason = trim($request->get('reason'));
|
||||
if($reason == '')
|
||||
return 'invalid_request';
|
||||
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
if(is_null($user))
|
||||
return 'not_logged_in';
|
||||
|
||||
if(!$user->can('delete_comment'))
|
||||
return 'insufficient_permissions';
|
||||
|
||||
$comment = Comment::whereId($id)->first();
|
||||
if(is_null($comment))
|
||||
return 'comment_not_found';
|
||||
|
||||
$receiver = $comment->user;
|
||||
$video = $comment->video;
|
||||
Comment::destroy($id);
|
||||
|
||||
if($user->id != $receiver->id)
|
||||
Message::send(1, $receiver->id, 'A moderator deleted your comment', view('messages.moderation.commentdelete', ['video' => $video, 'comment' => $comment, 'reason' => $reason]));
|
||||
|
||||
$log = new ModeratorLog();
|
||||
$log->user()->associate($user);
|
||||
$log->type = 'delete';
|
||||
$log->target_type = 'comment';
|
||||
$log->target_id = $id;
|
||||
$log->reason = $reason;
|
||||
$log->save();
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
public function restore(Request $request, $id)
|
||||
{
|
||||
if(!$request->has('reason'))
|
||||
return 'invalid_request';
|
||||
|
||||
$reason = trim($request->get('reason'));
|
||||
if($reason == '')
|
||||
return 'invalid_request';
|
||||
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
if(is_null($user))
|
||||
return 'not_logged_in';
|
||||
|
||||
if(!$user->can('delete_comment'))
|
||||
return 'insufficient_permissions';
|
||||
|
||||
$comment = Comment::withTrashed()->whereId($id)->first();
|
||||
if(is_null($comment))
|
||||
return 'comment_not_found';
|
||||
|
||||
if(!$comment->trashed())
|
||||
return 'comment_not_deleted';
|
||||
|
||||
$receiver = $comment->user;
|
||||
$video = $comment->video;
|
||||
$comment->restore();
|
||||
|
||||
if($user->id != $receiver->id)
|
||||
Message::send(1, $receiver->id, 'A moderator restored your comment', view('messages.moderation.commentrestore', ['video' => $video, 'comment' => $comment, 'reason' => $reason]));
|
||||
|
||||
$log = new ModeratorLog();
|
||||
$log->user()->associate($user);
|
||||
$log->type = 'restore';
|
||||
$log->target_type = 'comment';
|
||||
$log->target_id = $id;
|
||||
$log->reason = $reason;
|
||||
$log->save();
|
||||
|
||||
return 'success';
|
||||
}
|
||||
}
|
13
app/Http/Controllers/Controller.php
Normal file
13
app/Http/Controllers/Controller.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
|
||||
abstract class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
}
|
112
app/Http/Controllers/MessageController.php
Normal file
112
app/Http/Controllers/MessageController.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Message;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class MessageController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if(!auth()->check()) return JsonResponse::create('Not found', '304');
|
||||
return auth()->user()->messagesRecv()->orderBy('id', 'desc')->paginate(15);
|
||||
}
|
||||
|
||||
public function page()
|
||||
{
|
||||
if(!auth()->check()) return redirect()->back()->with('warning', 'You are not logged in');
|
||||
return view('messages');
|
||||
}
|
||||
|
||||
public function read(Request $request)
|
||||
{
|
||||
if(!auth()->check()) return Response::create('Unauthorized', '401');
|
||||
if($request->has('m_ids')) {
|
||||
$ids = $request->get('m_ids');
|
||||
Message::whereTo(auth()->user()->id)->whereIn('id', $ids)->update(['read' => \Carbon\Carbon::now()]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public function readall()
|
||||
{
|
||||
if(!auth()->check()) return Response::create('Unauthorized', '401');
|
||||
Message::whereTo(auth()->user()->id)->unread()->update(['read' => \Carbon\Carbon::now()]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
306
app/Http/Controllers/ReportController.php
Normal file
306
app/Http/Controllers/ReportController.php
Normal file
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Report;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Http\Requests;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class ReportController extends Controller
|
||||
{
|
||||
|
||||
private $fromMail = "otter@w0bm.com";
|
||||
private $fromName = "w0bm";
|
||||
private $toMail = "admin@w0bm.com";
|
||||
private $toName = "w0bm";
|
||||
private $subject = "webm reported";
|
||||
private $baseURL = "http://w0bm.com/";
|
||||
|
||||
/**
|
||||
* Made by klee
|
||||
* Testing to make report crap
|
||||
*
|
||||
*/
|
||||
public function report(Request $request)
|
||||
{
|
||||
if(is_array($request->input('reportReasons'))) {
|
||||
$reportReasons = "<li>".implode("</li><li>", $request->input('reportReasons'));
|
||||
} else {
|
||||
$reportReasons = "<li>".$request->input('reportReasons')."</li>";
|
||||
}
|
||||
|
||||
if($request->user()->username == "" || $request->user()->username == null) {
|
||||
$username = "User is <b>anonymous</b> because he is not registered";
|
||||
} else {
|
||||
$username = $request->user()->username;
|
||||
}
|
||||
|
||||
$data = array(
|
||||
"videoURL" => $this->baseURL.$request->route('id'),
|
||||
"reportReasons" => $reportReasons,
|
||||
"reportText" => htmlspecialchars($request->input('reportText')),
|
||||
"username" => $username,
|
||||
"videoID" => $request->route('id'),
|
||||
"message" => array(
|
||||
"html" => 'html message',
|
||||
"text" => 'text message',
|
||||
"to" => array(
|
||||
array("name" => 'admin@w0bm.com', "email" => 'admin@w0bm.com')
|
||||
),
|
||||
"from_email" => 'otter@w0bm.com',
|
||||
"from_name" => 'from w0bm',
|
||||
"subject" => 'the subject',
|
||||
"track_opens" => true,
|
||||
"track_clicks" => true
|
||||
),
|
||||
"async" => false,
|
||||
"debugOutput" => print_r(get_class_methods($request), true).print_r($request->route()->parameters(), true)
|
||||
);
|
||||
//$postString = json_encode($data);
|
||||
|
||||
\Mail::send('emails.report', $data, function ($msg) {
|
||||
$msg->from($this->fromMail, $this->fromName);
|
||||
$msg->to($this->toMail, $this->toName);
|
||||
$msg->subject($this->subject);
|
||||
});
|
||||
|
||||
return redirect()->back()->with('success', 'Report successfully sent');;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
/*
|
||||
if(!$request->has('username')) return JsonResponse::create('Not found', '304');
|
||||
$user = User::whereUsername(urldecode($request->get('username')))->first();
|
||||
if(!$user) return JsonResponse::create('Not found', '304');
|
||||
return $user->comments()->orderBy('id', 'desc')->paginate(10);
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request, $id)
|
||||
{
|
||||
/*
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
$xhr = $request->ajax();
|
||||
|
||||
if(is_null($user)) return $xhr ? "Not logged in" : redirect()->back()->with('error', 'Not logged in');
|
||||
if(!$request->has('comment')) return $xhr ? "You need to enter a comment" : redirect()->back()->with('error', 'You need to enter a comment');
|
||||
if(mb_strlen(trim($request->get('comment'))) > 2000 ) return $xhr ? "Comment to long" : redirect()->back()->with('error', 'Comment to long');
|
||||
|
||||
$video = Video::findOrFail($id);
|
||||
|
||||
$com = new Comment();
|
||||
$com->content = trim($request->get('comment'));
|
||||
$com->user()->associate($user);
|
||||
$com->video()->associate($video);
|
||||
$com->save();
|
||||
|
||||
$sent = [];
|
||||
foreach($com->getMentioned() as $mentioned) {
|
||||
Message::send($user->id, $mentioned->id, $user->username . ' mentioned you in a comment', view('messages.commentmention', ['video' => $video, 'user' => $user, 'comment' => $com]));
|
||||
$sent[] = $mentioned;
|
||||
}
|
||||
|
||||
foreach($com->answered() as $answered) {
|
||||
if(array_search($answered, $sent) !== false)
|
||||
continue;
|
||||
Message::send($user->id, $answered->id, $user->username . ' answered on your comment', view('messages.commentanswer', ['video' => $video, 'user' => $user, 'comment' => $com]));
|
||||
$sent[] = $answered;
|
||||
}
|
||||
|
||||
if($user->id != $video->user->id)
|
||||
if(array_search($video->user, $sent) === false)
|
||||
Message::send($user->id, $video->user->id, $user->username . ' commented on your video', view('messages.videocomment', ['video' => $video, 'user' => $user, 'comment' => $com]));
|
||||
|
||||
return $xhr ? view('partials.comment', ['comment' => $com, 'mod' => $user->can('delete_comment')]) : redirect()->back()->with('success', 'Comment successfully saved');
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
/*
|
||||
$comment = Comment::whereId($id)->first();
|
||||
if(!is_null($comment)) {
|
||||
return JsonResponse::create(array(
|
||||
'error' => 'null',
|
||||
'comment' => Comment::whereId($id)->first()->content)
|
||||
);
|
||||
}
|
||||
return JsonResponse::create(array(
|
||||
'error' => 'comment_not_found'
|
||||
));
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
/*
|
||||
if(!($request->has('comment')))
|
||||
return JsonResponse::create(array('error' => 'invalid_request'));
|
||||
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
if(is_null($user))
|
||||
return JsonResponse::create(array('error' => 'not_logged_in'));
|
||||
|
||||
if(!$user->can('edit_comment'))
|
||||
return JsonResponse::create(array('error' => 'insufficient_permissions'));
|
||||
|
||||
if(is_null($comment = Comment::whereId($id)->first()))
|
||||
return JsonResponse::create(array('error' => 'comment_not_found'));
|
||||
|
||||
$comment->content = trim($request->get('comment'));
|
||||
$comment->save();
|
||||
|
||||
$log = new ModeratorLog();
|
||||
$log->user()->associate($user);
|
||||
$log->type = 'edit';
|
||||
$log->target_type = 'comment';
|
||||
$log->target_id = $id;
|
||||
$log->save();
|
||||
*/
|
||||
|
||||
return JsonResponse::create(array(
|
||||
'error' => 'null',
|
||||
'rendered_comment' => "test rendered comment"//Comment::simplemd($comment->content)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Request $request, $id)
|
||||
{
|
||||
/*
|
||||
if(!$request->has('reason'))
|
||||
return 'invalid_request';
|
||||
|
||||
$reason = trim($request->get('reason'));
|
||||
if($reason == '')
|
||||
return 'invalid_request';
|
||||
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
if(is_null($user))
|
||||
return 'not_logged_in';
|
||||
|
||||
if(!$user->can('delete_comment'))
|
||||
return 'insufficient_permissions';
|
||||
|
||||
$comment = Comment::whereId($id)->first();
|
||||
if(is_null($comment))
|
||||
return 'comment_not_found';
|
||||
|
||||
$receiver = $comment->user;
|
||||
$video = $comment->video;
|
||||
Comment::destroy($id);
|
||||
|
||||
if($user->id != $receiver->id)
|
||||
Message::send(1, $receiver->id, 'A moderator deleted your comment', view('messages.moderation.commentdelete', ['video' => $video, 'comment' => $comment, 'reason' => $reason]));
|
||||
|
||||
$log = new ModeratorLog();
|
||||
$log->user()->associate($user);
|
||||
$log->type = 'delete';
|
||||
$log->target_type = 'comment';
|
||||
$log->target_id = $id;
|
||||
$log->reason = $reason;
|
||||
$log->save();
|
||||
*/
|
||||
|
||||
return 'success';
|
||||
}
|
||||
|
||||
public function restore(Request $request, $id)
|
||||
{
|
||||
/*
|
||||
if(!$request->has('reason'))
|
||||
return 'invalid_request';
|
||||
|
||||
$reason = trim($request->get('reason'));
|
||||
if($reason == '')
|
||||
return 'invalid_request';
|
||||
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
if(is_null($user))
|
||||
return 'not_logged_in';
|
||||
|
||||
if(!$user->can('delete_comment'))
|
||||
return 'insufficient_permissions';
|
||||
|
||||
$comment = Comment::withTrashed()->whereId($id)->first();
|
||||
if(is_null($comment))
|
||||
return 'comment_not_found';
|
||||
|
||||
if(!$comment->trashed())
|
||||
return 'comment_not_deleted';
|
||||
|
||||
$receiver = $comment->user;
|
||||
$video = $comment->video;
|
||||
$comment->restore();
|
||||
|
||||
if($user->id != $receiver->id)
|
||||
Message::send(1, $receiver->id, 'A moderator restored your comment', view('messages.moderation.commentrestore', ['video' => $video, 'comment' => $comment, 'reason' => $reason]));
|
||||
|
||||
$log = new ModeratorLog();
|
||||
$log->user()->associate($user);
|
||||
$log->type = 'restore';
|
||||
$log->target_type = 'comment';
|
||||
$log->target_id = $id;
|
||||
$log->reason = $reason;
|
||||
$log->save();
|
||||
*/
|
||||
|
||||
return 'success';
|
||||
}
|
||||
}
|
||||
|
401
app/Http/Controllers/UserController.php
Normal file
401
app/Http/Controllers/UserController.php
Normal file
@@ -0,0 +1,401 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Category;
|
||||
use App\Models\User;
|
||||
use App\Models\UserFavorite;
|
||||
use Illuminate\Http\Request;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\ModeratorLog;
|
||||
use App\Models\Banner;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Toddish\Verify\Helpers\Verify;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return \Response
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
if($request->has('identifier') && $request->has('password')) {
|
||||
switch(\Auth::verify([
|
||||
'identifier' => $request->get('identifier'),
|
||||
'password' => $request->get('password')
|
||||
], $request->has('remember')))
|
||||
{
|
||||
case Verify::SUCCESS:
|
||||
#\Session::put('background', auth()->user()->background);
|
||||
return redirect("/")->with('success', 'Login successful');
|
||||
case Verify::INVALID_CREDENTIALS:
|
||||
return redirect()->back()->with('error', 'Invalid credentials');
|
||||
case Verify::DISABLED:
|
||||
$user = User::whereUsername($request->get('identifier'))
|
||||
->orWhere('email', $request->get('identifier'))
|
||||
->first();
|
||||
if($user->banend->eq(Carbon::createFromTimestampUTC(1))) {
|
||||
return view('banned', ['user' => $user, 'perm' => true]);
|
||||
}
|
||||
// if ban expired unban and relogin.
|
||||
if($user->banend->lt(Carbon::now())) {
|
||||
$user->banend = null;
|
||||
$user->disabled = 0;
|
||||
$user->banreason = null;
|
||||
$user->save();
|
||||
return $this->login($request);
|
||||
}
|
||||
return view('banned', ['user' => $user, 'perm' => false]);
|
||||
case Verify::UNVERIFIED:
|
||||
return redirect()->back()->with('error', 'Please verify your account');
|
||||
}
|
||||
}
|
||||
return redirect()->back()->with('error', 'Missing credentials');
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
if(!auth()->check()) return redirect()->back()->with('warning', 'You are not logged in');
|
||||
|
||||
auth()->logout();
|
||||
return redirect('/')->with('success', 'Logout successful');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tags to filter
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function filter(Request $request) {
|
||||
//dd($request->get('categories'));
|
||||
if(!auth()->check())
|
||||
return Response::create("Not logged in", 401);
|
||||
if(!$request->has('filter'))
|
||||
$filter = [];
|
||||
else
|
||||
$filter = explode(',', $request->get('filter'));
|
||||
|
||||
|
||||
auth()->user()->categories = $filter;
|
||||
auth()->user()->save();
|
||||
|
||||
if(!$request->ajax())
|
||||
return redirect()->back()->with('success', 'Filter settings saved');
|
||||
|
||||
|
||||
return Response::create(json_encode($filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
if(auth()->check()) {
|
||||
\Session::reflash();
|
||||
\Session::flash('info', 'Cannot register when logged in');
|
||||
return redirect('/');
|
||||
}
|
||||
return view('register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
if(auth()->check()) return redirect()->back()->with('info', 'Cannot register when logged in');
|
||||
$validator = \Validator::make($request->all(), [
|
||||
'username' => 'required|unique:users|min:3|max:25|alpha_num',
|
||||
//'email' => 'required|email|unique:users|confirmed',
|
||||
'password' => 'required|min:6|confirmed',
|
||||
'g-recaptcha-response' => 'required|recaptcha'
|
||||
]);
|
||||
|
||||
if($validator->fails()) {
|
||||
return redirect()->back()->withErrors($validator->errors())
|
||||
->withInput($request->except(['password', 'password_confirmation']));
|
||||
}
|
||||
|
||||
//$activation_token = str_random(8) . md5($request->get('email')) . str_random(10);
|
||||
|
||||
$user = new User();
|
||||
$user->username = $request->get('username');
|
||||
$user->email = ""; //$request->get('email');
|
||||
$user->password = $request->get('password');
|
||||
$user->activation_token = ""; //$activation_token;
|
||||
$user->disabled = 0;
|
||||
$user->verified = 1;
|
||||
$user->categories = [];
|
||||
if($user->save()) {
|
||||
/*$data = [
|
||||
'username' => $user->username,
|
||||
'activation_token' => $activation_token
|
||||
];*/
|
||||
|
||||
// Send Mail
|
||||
|
||||
/*\Mail::queue('emails.activation', $data, function($message) use ($user) {
|
||||
$message->to($user->email, $user->username)->subject('Welcome to w0bm. Activate your account');
|
||||
});*/
|
||||
|
||||
return redirect('/')->with('info', 'Congratulations! You can now login!');
|
||||
} else {
|
||||
return redirect()->back()->with('error', 'Account could not be created')->withInput($request->except(['password', 'password_confirmation']));
|
||||
}
|
||||
}
|
||||
|
||||
public function activate($token)
|
||||
{
|
||||
$user = User::where('activation_token', '=', $token)->first();
|
||||
if(!$user) {
|
||||
return redirect('/')->with('error', 'Account already activate or no account found');
|
||||
}
|
||||
$user->verified = 1;
|
||||
$user->activation_token = null;
|
||||
$user->save();
|
||||
auth()->login($user);
|
||||
return redirect('/')->with('success', 'Successfully activate and logged in.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param string $username
|
||||
* @return \Response
|
||||
*/
|
||||
public function show($username)
|
||||
{
|
||||
$user = User::where('username', '=', $username)->first();
|
||||
|
||||
if(!$user) {
|
||||
return redirect()->back()->with('error', 'Unknown username');
|
||||
}
|
||||
$vids = $user->videos()->filtered()->paginate(50);
|
||||
|
||||
return view('profile', ['title' => 'Uploads', 'user' => $user, 'videos' => $vids]);
|
||||
}
|
||||
|
||||
public function show_favs($username)
|
||||
{
|
||||
$user = UserFavorite::where('username', '=', $username)->first();
|
||||
|
||||
if (!$user) {
|
||||
return redirect()->back()->with('error', 'Unknown username');
|
||||
}
|
||||
$vids = $user->favs()->filtered()->orderBy('favorites.created_at')->paginate(50);
|
||||
|
||||
return view('profile', ['title' => 'Favorites', 'user' => $user, 'videos' => $vids]);
|
||||
}
|
||||
|
||||
public function show_comments($username)
|
||||
{
|
||||
$user = User::where('username', '=', $username)->first();
|
||||
|
||||
if(!$user) {
|
||||
return redirect()->back()->with('error', 'Unknown username');
|
||||
}
|
||||
|
||||
return view('comments', ['user' => $user]);
|
||||
}
|
||||
|
||||
public function ban(Request $request, $username)
|
||||
{
|
||||
if(!($request->has('reason') && $request->has('duration')))
|
||||
return redirect()->back()->with('error', 'Invalid Request');
|
||||
|
||||
if(trim($reason = $request->get('reason')) == '')
|
||||
return redirect()->back()->with('error', 'You need to specify a ban reason');
|
||||
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
if(is_null($user))
|
||||
return redirect()->back()->with('error', 'Not logged in');
|
||||
|
||||
if(!$user->can('edit_user'))
|
||||
return redirect()->back()->with('error', 'Insufficient permissions');
|
||||
|
||||
$perm = false;
|
||||
if(($duration = $request->get('duration')) == '-1') {
|
||||
$duration = Carbon::createFromTimestampUTC(1);
|
||||
$perm = true;
|
||||
} else {
|
||||
preg_match('/^(\d+[yYaA])?\s*(\d+M)?\s*(\d+[wW])?\s*(\d+[dD])?\s*(\d+[Hh])?\s*(\d+[m])?\s*(\d+[sS])?$/m', $duration, $duration);
|
||||
array_shift($duration);
|
||||
$duration = array_map(function($elem) {
|
||||
return intval(mb_substr($elem, 0, -1));
|
||||
}, $duration);
|
||||
$duration = Carbon::now()
|
||||
->addYears($duration[0] ?? 0)
|
||||
->addMonths($duration[1] ?? 0)
|
||||
->addWeeks($duration[2] ?? 0)
|
||||
->addDays($duration[3] ?? 0)
|
||||
->addHours($duration[4] ?? 0)
|
||||
->addMinutes($duration[5] ?? 0)
|
||||
->addSeconds($duration[6] ?? 0);
|
||||
}
|
||||
|
||||
$userToBan = User::whereUsername($username)->first();
|
||||
if(is_null($user))
|
||||
return redirect()->back()->with('error', 'User not found');
|
||||
|
||||
$userToBan->disabled = 1;
|
||||
$userToBan->banreason = $reason;
|
||||
$userToBan->banend = $duration;
|
||||
$userToBan->save();
|
||||
|
||||
$log = new ModeratorLog();
|
||||
$log->user()->associate($user);
|
||||
$log->type = 'ban';
|
||||
$log->target_type = 'user';
|
||||
$log->target_id = $userToBan->id;
|
||||
$log->reason = $reason;
|
||||
$log->save();
|
||||
|
||||
if($perm)
|
||||
return redirect()->back()->with('success', 'User ' . $userToBan->username . ' has been permanently banned');
|
||||
else
|
||||
return redirect()->back()->with('success', 'User ' . $userToBan->username . ' has been banned until ' . $userToBan->banend->format('d.m.Y H:i:s') . ' UTC');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param string $username
|
||||
* @return \Response
|
||||
*/
|
||||
public function edit($username)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return \Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function random($username) {
|
||||
$user = User::where('username', '=', $username)->first();
|
||||
|
||||
if (!$user) {
|
||||
return redirect()->back()->with('error', 'Unknown username');
|
||||
}
|
||||
|
||||
$id = $user->videos()->filtered()->countScoped()->count() - 1;
|
||||
if ($id < 0) {
|
||||
return redirect()->back()->with('error', 'User has no uploads (Check your filter settings)');
|
||||
}
|
||||
$id = mt_rand(0, $id);
|
||||
$vid = $user->videos()->filtered()->skip($id)->first()->id;
|
||||
return redirect('/user/' . $username . '/uploads/' . $vid);
|
||||
}
|
||||
|
||||
public function play($username, $id) {
|
||||
$user = User::where('username', '=', $username)->first();
|
||||
|
||||
if (!$user) {
|
||||
return redirect()->back()->with('error', 'Unknown username');
|
||||
}
|
||||
|
||||
$vid = $user->videos()->filtered()->find($id);
|
||||
if (!$vid) {
|
||||
return redirect()->back()->with('error', 'Video not found on user');
|
||||
}
|
||||
|
||||
return view('video', [
|
||||
'video' => $vid,
|
||||
'related' => $user,
|
||||
'banner' => Banner::getRandom($vid->isSfw())
|
||||
]);
|
||||
}
|
||||
|
||||
// TODO: Cleanup. less Repetion between random and random_vav/play and play_fav
|
||||
// Only difference are the redirect urls and the Base Model
|
||||
public function random_fav($username) {
|
||||
$user = UserFavorite::where('username', '=', $username)->first();
|
||||
|
||||
if (!$user) {
|
||||
return redirect()->back()->with('error', 'Unknown username');
|
||||
}
|
||||
$id = $user->videos()->filtered()->countScoped()->count() - 1;
|
||||
if ($id < 0) {
|
||||
return redirect()->back()->with('error', 'No favorites (Check your filter settings)');
|
||||
}
|
||||
$id = mt_rand(0, $id);
|
||||
$vid = $user->videos()->filtered()->skip($id)->first()->id;
|
||||
return redirect('/user/' . $username . '/favs/' . $vid);
|
||||
}
|
||||
|
||||
public function play_fav($username, $id) {
|
||||
$user = UserFavorite::where('username', '=', $username)->first();
|
||||
|
||||
if (!$user) {
|
||||
return redirect()->back()->with('error', 'Unknown username');
|
||||
}
|
||||
|
||||
$vid = $user->videos()->filtered()->find($id);
|
||||
if (!$vid) {
|
||||
return redirect()->back()->with('error', 'Video not found on user');
|
||||
}
|
||||
|
||||
return view('video', [
|
||||
'video' => $vid,
|
||||
'related' => $user,
|
||||
'banner' => Banner::getRandom($vid->isSfw())
|
||||
]);
|
||||
}
|
||||
public function setLayout(Request $request) {
|
||||
if(!auth()->check())
|
||||
return Response::create("unauthorized", 401);
|
||||
if(!$request->has('layout'))
|
||||
return Response::create("bad request", 400);
|
||||
|
||||
$layout = $request->get('layout');
|
||||
if($layout !== strval(intval($layout)))
|
||||
return Response::create("bad request", 400);
|
||||
|
||||
if(!in_array("layout" . $layout, array_map(function ($v) { return basename($v); }, glob("../resources/views/layout*"))))
|
||||
return Response::create("bad request", 400);
|
||||
|
||||
auth()->user()->layout = $request->get('layout');
|
||||
auth()->user()->save();
|
||||
|
||||
return Response::create("success", 200);
|
||||
}
|
||||
|
||||
}
|
331
app/Http/Controllers/VideoController.php
Normal file
331
app/Http/Controllers/VideoController.php
Normal file
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Category;
|
||||
use App\Models\Comment;
|
||||
use App\Models\Message;
|
||||
use App\Models\ModeratorLog;
|
||||
use App\Models\Video;
|
||||
use App\Models\Banner;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
use App\Http\Requests;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class VideoController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function index(Request $request) {
|
||||
if($request->has('q')){
|
||||
$needle = trim($request->input('q'));
|
||||
return view('index', [
|
||||
'videos' => Video::filtered()->withAnyTagsFuzzy($needle)
|
||||
->orderBy('id', 'asc')
|
||||
->paginate(20)->appends(['q' => $needle]),
|
||||
'categories' => Category::all(),
|
||||
'q' => $needle
|
||||
]);
|
||||
}
|
||||
return view('index', [
|
||||
'videos' => Video::filtered()->orderBy('id', 'ASC')->paginate(20),
|
||||
'categories' => Category::all()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
return view('upload', ['user' => $user]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
/*var_dump($request->hasFile('file'));*/ if(!$request->hasFile('file') || !$request->has('category') || !$request->has('tags'))
|
||||
return new JsonResponse(['error' => 'invalid_request']);
|
||||
|
||||
$tags = $request->get('tags');
|
||||
if(mb_strpos($tags, 'sfw') === false && mb_strpos($tags, 'nsfw') === false)
|
||||
return new JsonResponse(['error' => 'invalid_request']);
|
||||
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
if(is_null($user))
|
||||
return new JsonResponse(['error' => 'not_logged_in']);
|
||||
|
||||
if(!$user->can('break_upload_limit') && $user->videos()->newlyups()->count() >= 10)
|
||||
return new JsonResponse(['error' => 'uploadlimit_reached']);
|
||||
|
||||
$file = $request->file('file');
|
||||
|
||||
if(!$file->isValid()
|
||||
|| mb_strtolower($file->getClientOriginalExtension()) !== 'webm'
|
||||
|| mb_strtolower($file->getMimeType()) !== 'video/webm')
|
||||
return new JsonResponse(['error' => 'invalid_file']);
|
||||
|
||||
if(!$user->can('break_max_filesize') && $file->getSize() > 41943040)
|
||||
return new JsonResponse(['error' => 'file_too_big']);
|
||||
|
||||
if(($v = Video::withTrashed()->where('hash', '=', sha1_file($file->getRealPath()))->first()) !== null) {
|
||||
if($v->trashed())
|
||||
return new JsonResponse(['error' => 'already_exists']);
|
||||
return new JsonResponse([
|
||||
'error' => 'already_exists',
|
||||
'video_id' => $v->id
|
||||
]);
|
||||
}
|
||||
// meh time()
|
||||
$file = $file->move(public_path() . '/b/', 'w0bm_' . time() . '.webm');
|
||||
|
||||
$hash = sha1_file($file->getRealPath());
|
||||
|
||||
$video = new Video();
|
||||
$video->file = basename($file->getRealPath());
|
||||
if(!$video->checkFileEncoding()) {
|
||||
unlink($file->getRealPath());
|
||||
// return before $video->save() so no need to clean up db
|
||||
return new JsonResponse(['error' => 'erroneous_file_encoding']);
|
||||
}
|
||||
$video->videotitle = $request->get('videotitle', null);
|
||||
$video->interpret = $request->get('interpret', null);
|
||||
$video->songtitle = $request->get('songtitle', null);
|
||||
$video->imgsource = $request->get('imgsource', null);
|
||||
$video->user()->associate($user);
|
||||
$video->category()->associate(Category::findOrFail($request->get('category')));
|
||||
$video->hash = $hash;
|
||||
$video->save();
|
||||
|
||||
$video->tag($tags);
|
||||
$video->tag($video->videotitle);
|
||||
$video->tag($video->interpret);
|
||||
$video->tag($video->songtitle);
|
||||
$video->tag($video->imgsource);
|
||||
$video->tag($video->category->shortname);
|
||||
$video->tag($video->category->name);
|
||||
|
||||
// TODO: outsource to different process (async)
|
||||
$video->createThumbnail();
|
||||
|
||||
// Discord
|
||||
if (config('discord.enabled') && config('discord.webhookurl')) {
|
||||
$nsfw = in_array('nsfw', $video->getTagArrayNormalizedAttribute());
|
||||
$nsfw = $nsfw ? ' :exclamation: **NSFW** :exclamation:' : '';
|
||||
$message = config('discord.message');
|
||||
$message = str_replace(
|
||||
['<USER>', '<ID>', '<NSFW>'],
|
||||
[$user->username, $video->id, $nsfw],
|
||||
$message
|
||||
);
|
||||
$url = config('discord.webhookurl');
|
||||
$payload = json_encode([
|
||||
'content' => $message,
|
||||
]);
|
||||
// exec with & so it is async
|
||||
exec("curl -H \"Content-Type: application/json; charset=UTF-8\" -X POST -d '$payload' '$url' > /dev/null &");
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
'error' => 'null',
|
||||
'video_id' => $video->id
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function show($id) {
|
||||
// TODO: filter on direct id link??
|
||||
$video = Video::with('tags')->find($id);
|
||||
if(is_null($video))
|
||||
return view('deleted');
|
||||
|
||||
#->back();
|
||||
#->with('error', 'No video with that ID found');
|
||||
|
||||
$sfw = $video->tags->contains(function($key, $tag) {
|
||||
return $tag->normalized === 'sfw';
|
||||
});
|
||||
|
||||
return view('video', [
|
||||
'video' => $video,
|
||||
'banner' => Banner::getRandom($sfw)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param int $id
|
||||
* @return Response
|
||||
*/
|
||||
public function update(Request $request, $id) {
|
||||
if(!auth()->check())
|
||||
return response('Not logged in', 403);
|
||||
$user = auth()->user();
|
||||
|
||||
if(!$request->ajax())
|
||||
return response('Invalid request', 400);
|
||||
|
||||
$v = Video::findOrFail($id);
|
||||
|
||||
if(!$user->can('edit_video') && $user->id != $v->user_id)
|
||||
return response('Not enough permissions', 403);
|
||||
|
||||
if($request->has('interpret')) {
|
||||
$v->interpret = $request->input('interpret');
|
||||
$v->tag($request->input('interpret'));
|
||||
}
|
||||
if($request->has('songtitle')) {
|
||||
$v->songtitle = $request->input('songtitle');
|
||||
$v->tag($request->input('songtitle'));
|
||||
}
|
||||
if($request->has('imgsource')) {
|
||||
$v->imgsource = $request->input('imgsource');
|
||||
$v->tag($request->input('imgsource'));
|
||||
}
|
||||
if($request->has('videotitle')) {
|
||||
$v->videotitle = $request->input('videotitle');
|
||||
$v->tag($request->input('videotitle'));
|
||||
}
|
||||
if($request->has('category')) {
|
||||
$cat = Category::findOrFail($request->input('category'));
|
||||
$v->category()->associate($cat);
|
||||
$v->tag($cat->name);
|
||||
$v->tag($cat->shortname);
|
||||
}
|
||||
|
||||
$v->save();
|
||||
|
||||
$log = new ModeratorLog();
|
||||
$log->user()->associate($user);
|
||||
$log->type = 'edit';
|
||||
$log->target_type = 'video';
|
||||
$log->target_id = $v->id;
|
||||
$log->save();
|
||||
|
||||
return $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Response
|
||||
*/
|
||||
public function destroy(Request $request, $id)
|
||||
{
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
|
||||
if(is_null($user)) return new JsonResponse(['error' => 'not_logged_in']);
|
||||
|
||||
if(!$request->has('reason') || trim($request->get('reason')) == '') return new JsonResponse(['error' => 'invalid_request']);
|
||||
|
||||
$reason = trim($request->get('reason'));
|
||||
|
||||
if($user->can('delete_video')) {
|
||||
$warnings = [];
|
||||
$vid = Video::find($id);
|
||||
if(!$vid)
|
||||
return new JsonResponse(['error' => 'video_not_found']);
|
||||
|
||||
foreach($vid->comments as $comment) {
|
||||
$comment->delete(); // delete associated comments
|
||||
}
|
||||
$vid->faved()->detach();
|
||||
if(!\File::move(public_path() . '/b/' . $vid->file, storage_path() . '/deleted/' . $vid->file))
|
||||
$warnings[] = 'Could not move file';
|
||||
|
||||
$vid->delete();
|
||||
$receiver = $vid->user;
|
||||
if($user->id != $receiver->id)
|
||||
Message::send(1, $receiver->id, 'A moderator deleted your video', view('messages.moderation.videodelete', ['video' => $vid, 'reason' => $reason, 'videoinfo' => ['artist' => $vid->interpret, 'songtitle' => $vid->songtitle, 'video_source' => $vid->imgsource, 'category' => $vid->category->name]]));
|
||||
|
||||
$log = new ModeratorLog();
|
||||
$log->user()->associate($user);
|
||||
$log->type = 'delete';
|
||||
$log->target_type = 'video';
|
||||
$log->target_id = $id;
|
||||
$log->reason = $reason;
|
||||
$log->save();
|
||||
|
||||
return new JsonResponse(['error' => 'null', 'warnings' => $warnings]);
|
||||
}
|
||||
return new JsonResponse(['error' => 'insufficient_permissions']);
|
||||
}
|
||||
|
||||
public function favorite($id) {
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
$xhr = \Request::ajax();
|
||||
|
||||
if(is_null($user)) return $xhr ? "Not logged in" : redirect()->back()->with('error', 'Not logged in');
|
||||
|
||||
|
||||
if($user->hasFaved($id)) {
|
||||
$user->favs()->detach($id);
|
||||
return $xhr ? "Video removed from favorites" : redirect()->back()->with('success', 'Video removed from favorites');
|
||||
} else {
|
||||
$user->favs()->attach($id);
|
||||
return $xhr ? "Video added to favorites" : redirect()->back()->with('success', 'Video added to favorites');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return Video | Bool
|
||||
*/
|
||||
public function tag(Request $request, $id) {
|
||||
if(!$request->has('tags')) return new JsonResponse(["error" => "invalid_request"]);
|
||||
$tags = $request->get('tags');
|
||||
if(!count($tags)) return new JsonResponse(["error" => "no_tags_specified"]);
|
||||
$v = Video::findOrFail($id);
|
||||
if(is_null($v)) return new JsonResponse(["error" => "video_not_found"]);
|
||||
$v->tag($tags);
|
||||
$v['error'] = 'null';
|
||||
$v['can_edit_video'] = auth()->check() ? auth()->user()->can('edit_video') : false;
|
||||
return $v;
|
||||
}
|
||||
|
||||
public function untag(Request $request, $id) {
|
||||
if(!$request->has('tag') || trim($request->get('tag')) == "") return new JsonResponse(["error" => "invalid_request"]);
|
||||
$user = auth()->check() ? auth()->user() : null;
|
||||
if(is_null($user)) return new JsonResponse(["error" => "not_logged_in"]);
|
||||
if(!$user->can('edit_video')) return new JsonResponse(["error" => "insufficient_permissions"]);
|
||||
$tag = trim($request->get('tag'));
|
||||
$v = Video::findOrFail($id);
|
||||
if(is_null($v)) return new JsonResponse(["error" => "video_not_found"]);
|
||||
$v = $v->untag($tag);
|
||||
$v['error'] = 'null';
|
||||
return $v;
|
||||
}
|
||||
|
||||
}
|
0
app/Http/Controllers/tmp/.gitkeep
Normal file
0
app/Http/Controllers/tmp/.gitkeep
Normal file
BIN
app/Http/Controllers/tmp/test.png
Normal file
BIN
app/Http/Controllers/tmp/test.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
37
app/Http/Kernel.php
Normal file
37
app/Http/Kernel.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware = [
|
||||
\Clockwork\Support\Laravel\ClockworkMiddleware::class,
|
||||
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
|
||||
Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
Middleware\VerifyCsrfToken::class,
|
||||
Middleware\LogoutBanned::class,
|
||||
Middleware\Jsonp::class
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'guest' => Middleware\RedirectIfAuthenticated::class,
|
||||
'theme' => Middleware\Theme::class,
|
||||
];
|
||||
}
|
46
app/Http/Middleware/Authenticate.php
Normal file
46
app/Http/Middleware/Authenticate.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
|
||||
class Authenticate
|
||||
{
|
||||
/**
|
||||
* The Guard implementation.
|
||||
*
|
||||
* @var Guard
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Guard $auth
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ($this->auth->guest()) {
|
||||
if ($request->ajax()) {
|
||||
return response('Unauthorized.', 401);
|
||||
} else {
|
||||
return redirect()->guest('/login');
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
17
app/Http/Middleware/EncryptCookies.php
Normal file
17
app/Http/Middleware/EncryptCookies.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter;
|
||||
|
||||
class EncryptCookies extends BaseEncrypter
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
32
app/Http/Middleware/Jsonp.php
Normal file
32
app/Http/Middleware/Jsonp.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
class Jsonp {
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
|
||||
if ($response->headers->get('content-type') == 'application/json'
|
||||
&& $request->has('callback'))
|
||||
{
|
||||
if (get_class($response) == JsonResponse::class) {
|
||||
return $response->setCallback($request->input('callback'));
|
||||
}
|
||||
// TODO fix stripping headers
|
||||
return response()->json($response->original)->setCallback($request->input('callback'));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
25
app/Http/Middleware/LogoutBanned.php
Normal file
25
app/Http/Middleware/LogoutBanned.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class LogoutBanned
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$user = auth()->user();
|
||||
if($user && $user->isBanned()) {
|
||||
auth()->logout();
|
||||
return redirect()->back()->with('error', 'You are banned');
|
||||
}
|
||||
return $next($request);
|
||||
}
|
||||
}
|
42
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
42
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* The Guard implementation.
|
||||
*
|
||||
* @var Guard
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Guard $auth
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ($this->auth->check()) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
32
app/Http/Middleware/Theme.php
Normal file
32
app/Http/Middleware/Theme.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
class Theme
|
||||
{
|
||||
protected $auth;
|
||||
protected $view;
|
||||
|
||||
public function __construct(Guard $auth, Factory $view)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->view = $view;
|
||||
}
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$paths = $this->view->getFinder()->getPaths();
|
||||
foreach ($paths as &$p) {
|
||||
$p .= "/layout" . (auth()->check() ? auth()->user()->layout : 1);
|
||||
}
|
||||
$this->view->setFinder(new \Illuminate\View\FileViewFinder($this->view->getFinder()->getFilesystem(), $paths));
|
||||
return $next($request);
|
||||
}
|
||||
}
|
18
app/Http/Middleware/VerifyCsrfToken.php
Normal file
18
app/Http/Middleware/VerifyCsrfToken.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
|
||||
|
||||
class VerifyCsrfToken extends BaseVerifier
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'api/video/upload'
|
||||
];
|
||||
|
||||
}
|
10
app/Http/Requests/Request.php
Normal file
10
app/Http/Requests/Request.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
abstract class Request extends FormRequest
|
||||
{
|
||||
//
|
||||
}
|
149
app/Http/routes.php
Normal file
149
app/Http/routes.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register all of the routes for an application.
|
||||
| It's a breeze. Simply tell Laravel the URIs it should respond to
|
||||
| and give it the controller to call when that URI is requested.
|
||||
|
|
||||
*/
|
||||
|
||||
Route::get('/', ['as' => 'home', function () {
|
||||
Session::reflash();
|
||||
// Dummy query to calculate rows
|
||||
$video = \App\Models\Video::getRandom()->first();
|
||||
|
||||
return redirect($video->id);
|
||||
|
||||
}])->middleware('auth');
|
||||
|
||||
|
||||
Route::post('filter', 'UserController@filter');
|
||||
|
||||
// /api
|
||||
Route::group(['prefix' => 'api'], function() {
|
||||
|
||||
// /api/messages
|
||||
Route::group(['prefix' => 'messages'], function() {
|
||||
Route::get('', 'MessageController@index');
|
||||
Route::post('read', 'MessageController@read');
|
||||
Route::get('readall', 'MessageController@readall');
|
||||
});
|
||||
|
||||
// /api/comments
|
||||
Route::group(['prefix' => 'comments'], function() {
|
||||
Route::get('/', 'CommentController@index');
|
||||
Route::get('/{id}', 'CommentController@show')->where('id', '[0-9]+');
|
||||
Route::post('{id}/edit', 'CommentController@update')->where('id', '[0-9]+');
|
||||
Route::post('{id}/delete', 'CommentController@destroy')->where('id', '[0-9]+');
|
||||
Route::post('{id}/restore', 'CommentController@restore')->where('id', '[0-9]+');
|
||||
});
|
||||
|
||||
// /api/user
|
||||
Route::group(['prefix' => 'user'], function() {
|
||||
Route::post('{username}/ban', 'UserController@ban');
|
||||
Route::get('/layout', 'UserController@setLayout');
|
||||
});
|
||||
|
||||
// /api/video
|
||||
Route::group(['prefix' => 'video'], function() {
|
||||
Route::get('random', function() {
|
||||
return \App\Models\Video::getRandom()->with(['category', 'user' => function($query) {
|
||||
$query->addSelect('username', 'id');
|
||||
}])->first();
|
||||
});
|
||||
|
||||
|
||||
Route::get('latest', function(\Illuminate\Http\Request $req) {
|
||||
if ($req->has('filtered') && $req->get('filtered')) {
|
||||
return \App\Models\Video::filtered()->orderBy('id', 'DESC')->first();
|
||||
}
|
||||
return \App\Models\Video::orderBy('id', 'DESC')->first();
|
||||
});
|
||||
|
||||
Route::get('{id}', function($id) {
|
||||
$res = \App\Models\Video::with(['category', 'user' => function($query) {
|
||||
$query->addSelect('username', 'id');
|
||||
}])->find($id);
|
||||
if(!$res) {
|
||||
return response(['message' => 'Video not found'], 404);
|
||||
}
|
||||
return $res;
|
||||
})->where('id', '[0-9]+');
|
||||
Route::post('{id}/delete', 'VideoController@destroy')->where('id', '[0-9]+');
|
||||
Route::post('{id}/tag', 'VideoController@tag')->where('id', '[0-9]+');
|
||||
Route::post('{id}/untag', 'VideoController@untag')->where('id', '[0-9]+');
|
||||
Route::post('upload', 'VideoController@store')->middleware('auth.basic');
|
||||
});
|
||||
|
||||
Route::post('upload', 'VideoController@store');
|
||||
});
|
||||
|
||||
Route::group(["middleware" => "theme"], function() {
|
||||
Route::post('report/{id}', 'ReportController@report'); // added by klee
|
||||
Route::get('messages', 'MessageController@page');
|
||||
Route::get('user/{username}', 'UserController@show')->middleware('auth');
|
||||
Route::get('user/{username}/uploads', 'UserController@random')->middleware('auth');
|
||||
Route::get('user/{username}/uploads/{id}', 'UserController@play')->where('id', '[0-9]+')->middleware('auth');
|
||||
Route::get('user/{username}/favs', 'UserController@random_fav')->middleware('auth');
|
||||
Route::get('user/{username}/favs/{id}', 'UserController@play_fav')->where('id', '[0-9]+')->middleware('auth');
|
||||
Route::get('user/{username}/favs/index', 'UserController@show_favs')->middleware('auth');
|
||||
Route::get('user/{username}/comments', 'UserController@show_comments')->middleware('auth');
|
||||
Route::get('logout', 'UserController@logout');
|
||||
Route::post('login', 'UserController@login');
|
||||
Route::get('register', 'UserController@create');
|
||||
Route::post('register', 'UserController@store');
|
||||
Route::get('activate/{token}', 'UserController@activate');
|
||||
Route::get('index', 'VideoController@index')->middleware('auth');
|
||||
Route::post('index/{id}', 'VideoController@update')->middleware('auth');
|
||||
Route::get('upload', 'VideoController@create')->middleware('auth');
|
||||
Route::get('categories', 'CategoryController@index')->middleware('auth');
|
||||
Route::get('webm', function() { return view('webm'); });
|
||||
Route::get('about', function() { return view('about'); });
|
||||
Route::get('irc', function() { return view('irc'); });
|
||||
Route::get('rules', function() { return view('rules'); });
|
||||
Route::get('contact', function() { return view('contact'); });
|
||||
Route::get('privacy', function() { return view('privacy'); });
|
||||
Route::get('teamspeak', function() { return view('teamspeak'); });
|
||||
Route::get('news', function() { return view('news'); });
|
||||
Route::get('0x40', function() { return view('0x40'); });
|
||||
Route::get('stats', function() {
|
||||
return view('stats', [
|
||||
'user_count' => \App\Models\User::count(),
|
||||
'upload_count' => \App\Models\Video::count(),
|
||||
'comment_count' => \App\Models\Comment::count(),
|
||||
//'fav_count' => \App\Models\UserFavorite::count(),
|
||||
'latest_video' => \App\Models\Video::getLastId(),
|
||||
'newest_user' => \App\Models\User::orderBy('id', 'DESC')->first()->username,
|
||||
'dirsize' => shell_exec("(du -sh " . public_path() . "/b | cut -f1)")
|
||||
]);
|
||||
});
|
||||
Route::get('/latest', function () {
|
||||
Session::reflash();
|
||||
|
||||
$video = \App\Models\Video::orderBy('id', 'DESC')->first();
|
||||
|
||||
return redirect($video->id);
|
||||
});
|
||||
#Route::get('help', function() { return view('help'); });
|
||||
#Route::get('announcement', function() { return view('announcement'); });
|
||||
#Route::get('map', function() { return view('map'); });
|
||||
#Route::get('donate', function() {
|
||||
# return view('donate', [
|
||||
# 'donations' => \App\Models\Donation::orderBy('timestamp', 'DESC')->get()
|
||||
# ]);
|
||||
#});
|
||||
Route::get('transparency', function() { return view('transparency'); });
|
||||
Route::get('login', function() { return view('login'); });
|
||||
#Route::get('counter-strike', function() { return view('counter-strike'); });
|
||||
|
||||
Route::get('{id}', 'VideoController@show')->where('id', '[0-9]+');
|
||||
Route::get('{id}/fav', 'VideoController@favorite')->where('id', '[0-9]+');
|
||||
Route::post('{id}', 'CommentController@store')->where('id', '[0-9]+');
|
||||
|
||||
Route::get('{shortname}', 'CategoryController@showVideo')->where('shortname', '[a-z][a-z0-9]+')->middleware('auth');
|
||||
Route::get('{shortname}/{id}', 'CategoryController@showVideo')->where(['shortname' => '[a-z][a-z0-9]+', 'id' => '[0-9]+'])->middleware('auth');
|
||||
});
|
21
app/Jobs/Job.php
Normal file
21
app/Jobs/Job.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
||||
abstract class Job
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Queueable Jobs
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This job base class provides a central location to place any logic that
|
||||
| is shared across all of your jobs. The trait included with the class
|
||||
| provides access to the "onQueue" and "delay" queue helper methods.
|
||||
|
|
||||
*/
|
||||
|
||||
use Queueable;
|
||||
}
|
0
app/Listeners/.gitkeep
Normal file
0
app/Listeners/.gitkeep
Normal file
40
app/Models/Banner.php
Normal file
40
app/Models/Banner.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Carbon\Carbon;
|
||||
|
||||
// Maybe this will in a n to m relation with video someday
|
||||
class Banner extends Model
|
||||
{
|
||||
protected $casts = [
|
||||
'sfw' => 'boolean'
|
||||
];
|
||||
protected $dates = [
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'until'
|
||||
];
|
||||
|
||||
// If this would be in relation with video the $sfw could be
|
||||
// figured out dynamically
|
||||
public static function getRandom($sfw = true) {
|
||||
$q = static::active();
|
||||
if($sfw) $q->sfw();
|
||||
$id = $q->count() - 1;
|
||||
if ($id < 0) return null;
|
||||
$id = mt_rand(0, $id);
|
||||
$q = static::active();
|
||||
if($sfw) $q->sfw();
|
||||
return $q->skip($id)->first();
|
||||
}
|
||||
|
||||
public function scopeSfw($query) {
|
||||
return $query->where('sfw', true);
|
||||
}
|
||||
|
||||
public function scopeActive($query) {
|
||||
return $query->where('until', '>=', Carbon::now());
|
||||
}
|
||||
}
|
49
app/Models/Category.php
Normal file
49
app/Models/Category.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* App\Models\Category
|
||||
*
|
||||
* @property integer $id
|
||||
* @property string $name
|
||||
* @property string $shortname
|
||||
* @property string $description
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property string $deleted_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Video[] $videos
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Category whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Category whereName($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Category whereShortname($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Category whereDescription($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Category whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Category whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Category whereDeletedAt($value)
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|User[] $users
|
||||
*/
|
||||
class Category extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'categories';
|
||||
|
||||
public function videos() {
|
||||
return $this->hasMany(Video::class);
|
||||
}
|
||||
|
||||
public function users() {
|
||||
return $this->belongsToMany(User::class);
|
||||
}
|
||||
|
||||
public function baseurl() {
|
||||
return $this->shortname;
|
||||
}
|
||||
|
||||
public function displayName() {
|
||||
return e($this->name);
|
||||
}
|
||||
}
|
90
app/Models/Comment.php
Normal file
90
app/Models/Comment.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use App\Services\Markdown;
|
||||
|
||||
/**
|
||||
* App\Models\Comment
|
||||
*
|
||||
* @property integer $id
|
||||
* @property string $content
|
||||
* @property integer $user_id
|
||||
* @property integer $video_id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property string $deleted_at
|
||||
* @property-read User $user
|
||||
* @property-read Video $video
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Comment whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Comment whereContent($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Comment whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Comment whereVideoId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Comment whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Comment whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Comment whereDeletedAt($value)
|
||||
*/
|
||||
class Comment extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $appends = ['rendered_view'];
|
||||
|
||||
public function user() {
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function video() {
|
||||
return $this->belongsTo(Video::class);
|
||||
}
|
||||
|
||||
public static function simplemd($text) {
|
||||
$m = app()->make(Markdown::class);
|
||||
$text = $m->text($text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
public function getRenderedViewAttribute() {
|
||||
return static::simplemd($this->content);
|
||||
}
|
||||
|
||||
public function getMentioned() {
|
||||
$text = $this->content;
|
||||
$nameMatcher = '/\B@([\wÄÖÜäöü]+)/i';
|
||||
$ret = [];
|
||||
if(preg_match_all($nameMatcher, $text, $users) > 0) {
|
||||
foreach ($users[1] as $user) {
|
||||
if(User::whereUsername($user)->count() > 0) {
|
||||
$ret[] = User::whereUsername($user)->first();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($ret);
|
||||
}
|
||||
|
||||
public function answered() {
|
||||
$text = $this->content;
|
||||
$regex = '/^[!%*]*(\^+)/m';
|
||||
$answers = [];
|
||||
if(preg_match_all($regex, $text, $answered) > 0) {
|
||||
foreach($answered[1] as $a) {
|
||||
$answers[] = mb_strlen($a);
|
||||
}
|
||||
}
|
||||
$answers = array_unique($answers);
|
||||
$comments = $this->video->comments;
|
||||
$total = $comments->count();
|
||||
$ret = [];
|
||||
foreach($answers as $c) {
|
||||
$up = $total - $c - 1;
|
||||
if($up >= 0) {
|
||||
$ret[] = $comments->get($up)->user;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
20
app/Models/Donation.php
Normal file
20
app/Models/Donation.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Donation extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
public static $needed = 150;
|
||||
|
||||
public static function getPercentage() {
|
||||
return (static::getFunds() / static::$needed) * 100;
|
||||
}
|
||||
|
||||
public static function getFunds() {
|
||||
return static::sum('amount') ?? 0;
|
||||
}
|
||||
}
|
35
app/Models/Icon.php
Normal file
35
app/Models/Icon.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Icon extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
|
||||
public function roles() {
|
||||
return $this->hasMany(Role::class);
|
||||
}
|
||||
|
||||
public function users() {
|
||||
return $this->hasMany(User::class);
|
||||
}
|
||||
|
||||
public function toJson($options = 0) {
|
||||
return parent::toJson($options);
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
switch ($this->icon_type) {
|
||||
case 'fa':
|
||||
return '<i class="fa fa-' . $this->icon . '"></i>';
|
||||
case 'img':
|
||||
case 'image':
|
||||
return '<img class="icon" src="https://s.w0bm.com/' . ltrim($this->icon, '/') . '" alt="' . $this->icon . '">';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
72
app/Models/Message.php
Normal file
72
app/Models/Message.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* App\Models\Message
|
||||
*
|
||||
* @property integer $id
|
||||
* @property integer $from
|
||||
* @property integer $to
|
||||
* @property string $content
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property string $deleted_at
|
||||
* @property string $read
|
||||
* @property string $subject
|
||||
* @property-read User $fromUser
|
||||
* @property-read User $toUser
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message whereFrom($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message whereTo($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message whereContent($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message whereRead($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message whereSubject($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Message unread()
|
||||
*/
|
||||
class Message extends Model {
|
||||
use SoftDeletes;
|
||||
|
||||
public function fromUser() {
|
||||
return $this->belongsTo(User::class, 'from');
|
||||
}
|
||||
|
||||
public function toUser() {
|
||||
return $this->belongsTo(User::class, 'to');
|
||||
}
|
||||
|
||||
public static function send($from, $to, $subject, $content) {
|
||||
if(empty($subject)) return 'Subject must not be empty';
|
||||
if(empty($content)) return 'Content must not be empty';
|
||||
|
||||
try {
|
||||
if(!is_object($from))
|
||||
$from = User::findOrFail($from);
|
||||
|
||||
if(!is_object($to))
|
||||
$to = User::findOrFail($to);
|
||||
} catch (ModelNotFoundException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$message = new static();
|
||||
$message->from = $from->id;
|
||||
$message->to = $to->id;
|
||||
$message->subject = $subject;
|
||||
$message->content = $content;
|
||||
$message->save();
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
public function scopeUnread($query) {
|
||||
return $query->whereNull('read');
|
||||
}
|
||||
}
|
42
app/Models/ModeratorLog.php
Normal file
42
app/Models/ModeratorLog.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* App\Models\ModeratorLog
|
||||
*
|
||||
* @property integer $id
|
||||
* @property integer $user_id
|
||||
* @property string $type
|
||||
* @property string $target_type
|
||||
* @property integer $target_id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property-read User $user
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\ModeratorLog whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\ModeratorLog whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\ModeratorLog whereType($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\ModeratorLog whereTargetType($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\ModeratorLog whereTargetId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\ModeratorLog whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\ModeratorLog whereUpdatedAt($value)
|
||||
*/
|
||||
class ModeratorLog extends Model
|
||||
{
|
||||
public function user() {
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function getTarget() {
|
||||
$target_type = $this->target_type;
|
||||
|
||||
switch ($target_type) {
|
||||
case 'user': return User::find($this->target_id);
|
||||
case 'comment': return Comment::find($this->target_id);
|
||||
case 'video': return Video::find($this->target_id);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
12
app/Models/Role.php
Normal file
12
app/Models/Role.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Toddish\Verify\Models\Role as VerifyRole;
|
||||
|
||||
class Role extends VerifyRole
|
||||
{
|
||||
public function icon() {
|
||||
return $this->belongsTo(Icon::class, 'icon_id');
|
||||
}
|
||||
}
|
135
app/Models/User.php
Normal file
135
app/Models/User.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Toddish\Verify\Models\User as VerifyUser;
|
||||
use Carbon\Carbon;
|
||||
|
||||
/**
|
||||
* App\Models\User
|
||||
*
|
||||
* @property integer $id
|
||||
* @property string $username
|
||||
* @property string $password
|
||||
* @property string $salt
|
||||
* @property string $email
|
||||
* @property string $remember_token
|
||||
* @property boolean $verified
|
||||
* @property boolean $disabled
|
||||
* @property array $categories
|
||||
* @property \Carbon\Carbon $deleted_at
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property string $activation_token
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Video[] $videos
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Comment[] $comments
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\config('verify.models.role')[] $roles
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereUsername($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User wherePassword($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereSalt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereEmail($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereRememberToken($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereVerified($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereDisabled($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereActivationToken($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\Toddish\Verify\Models\User verified()
|
||||
* @method static \Illuminate\Database\Query\Builder|\Toddish\Verify\Models\User unverified()
|
||||
* @method static \Illuminate\Database\Query\Builder|\Toddish\Verify\Models\User disabled()
|
||||
* @method static \Illuminate\Database\Query\Builder|\Toddish\Verify\Models\User enabled()
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|ModeratorLog[] $moderator_log
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Message[] $messagesSent
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Message[] $messagesRecv
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Video[] $favs
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereBackground($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\User whereCategories($value)
|
||||
*/
|
||||
class User extends VerifyUser
|
||||
{
|
||||
protected $casts = [
|
||||
// TODO: rename db column to tag filters
|
||||
'categories' => 'array'
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'deleted_at',
|
||||
'banend'
|
||||
];
|
||||
|
||||
|
||||
public function uploads() {
|
||||
return $this->hasMany(Video::class);
|
||||
}
|
||||
|
||||
public function videos() {
|
||||
return $this->uploads();
|
||||
}
|
||||
|
||||
public function comments() {
|
||||
return $this->hasMany(Comment::class);
|
||||
}
|
||||
|
||||
public function moderator_log() {
|
||||
return $this->hasMany(ModeratorLog::class);
|
||||
}
|
||||
|
||||
public function messagesSent() {
|
||||
return $this->hasMany(Message::class, 'from');
|
||||
}
|
||||
|
||||
public function messagesRecv() {
|
||||
return $this->hasMany(Message::class, 'to');
|
||||
}
|
||||
|
||||
public function favs() {
|
||||
return $this->belongsToMany(Video::class, 'favorites');
|
||||
}
|
||||
|
||||
public function hasFaved($id) {
|
||||
return ! $this->favs->filter(function($vid) use ($id) {
|
||||
return $vid->id == $id;
|
||||
})->isEmpty();
|
||||
}
|
||||
|
||||
public function icon() {
|
||||
return $this->belongsTo(Icon::class, 'icon_id');
|
||||
}
|
||||
|
||||
public function activeIcon() {
|
||||
$icon = $this->icon;
|
||||
if($icon === null) {
|
||||
$roles = $this->roles;
|
||||
$roles = $roles->sortByDesc('level');
|
||||
|
||||
foreach($roles as $role) {
|
||||
if($role !== null) $icon = $role->icon;
|
||||
}
|
||||
}
|
||||
return $icon;
|
||||
}
|
||||
|
||||
public function isBanned() {
|
||||
if($this->disabled == 1) {
|
||||
return $this->banend->eq(Carbon::createFromTimeStampUTC(1)) || $this->banend->gt(Carbon::now());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getForeignKey() {
|
||||
return 'user_id';
|
||||
}
|
||||
|
||||
public function baseurl() {
|
||||
return 'user/' . $this->username . '/uploads';
|
||||
}
|
||||
|
||||
public function displayName() {
|
||||
return e($this->username) . ($this->activeIcon() ? " " . $this->activeIcon() : "");
|
||||
}
|
||||
|
||||
}
|
21
app/Models/UserFavorite.php
Normal file
21
app/Models/UserFavorite.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class UserFavorite extends User {
|
||||
|
||||
protected $table = 'users';
|
||||
|
||||
// Instead of uploaded Videos get favs
|
||||
public function videos() {
|
||||
return $this->favs();
|
||||
}
|
||||
|
||||
public function baseurl() {
|
||||
return 'user/' . $this->username . '/favs';
|
||||
}
|
||||
|
||||
public function displayName() {
|
||||
return 'Favorites (' . parent::displayName() . ')';
|
||||
}
|
||||
}
|
189
app/Models/Video.php
Normal file
189
app/Models/Video.php
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* App\Models\Video
|
||||
*
|
||||
* @property integer $id
|
||||
* @property string $file
|
||||
* @property string $interpret
|
||||
* @property string $songtitle
|
||||
* @property string $imgsource
|
||||
* @property integer $category_id
|
||||
* @property integer $user_id
|
||||
* @property \Carbon\Carbon $created_at
|
||||
* @property \Carbon\Carbon $updated_at
|
||||
* @property string $deleted_at
|
||||
* @property string $hash
|
||||
* @property-read User $user
|
||||
* @property-read Category $category
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Comment[] $comments
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereFile($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereInterpret($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereSongtitle($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereImgsource($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereCategoryId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereUserId($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereDeletedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video whereHash($value)
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|User[] $faved
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|Tag[] $tags
|
||||
* @property-read mixed $tag_list
|
||||
* @property-read mixed $tag_list_normalized
|
||||
* @property-read mixed $tag_array
|
||||
* @property-read mixed $tag_array_normalized
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video newlyups()
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video withAllTags($tags)
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video withAnyTags($tags = array())
|
||||
* @method static \Illuminate\Database\Query\Builder|\App\Models\Video withoutTags()
|
||||
*/
|
||||
class Video extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use \Cviebrock\EloquentTaggable\Taggable;
|
||||
|
||||
public function user() {
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function category() {
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function comments() {
|
||||
return $this->hasMany(Comment::class);
|
||||
}
|
||||
|
||||
public function faved() {
|
||||
return $this->belongsToMany(User::class, 'favorites', 'video_id', 'user_id');
|
||||
}
|
||||
|
||||
public static function getFirstId($related = null) {
|
||||
if ($related) {
|
||||
return $related->videos()->filtered()->orderBy('id', 'ASC')->first()->id;
|
||||
}
|
||||
return static::filtered()->orderBy('id', 'ASC')->first()->id;
|
||||
}
|
||||
|
||||
public static function getLastId($related = null) {
|
||||
if ($related) {
|
||||
return $related->videos()->filtered()->orderBy('id', 'DESC')->first()->id;
|
||||
}
|
||||
return static::select('id')->filtered()->orderBy('id', 'DESC')->first()->id;
|
||||
}
|
||||
|
||||
public function getNext($related = null) {
|
||||
if ($related) {
|
||||
return $related->videos()->filtered()->where('id', '>', $this->id)->orderBy('id', 'ASC')->first();
|
||||
} else {
|
||||
return static::filtered()->where('id', '>', $this->id)->orderBy('id', 'ASC')->first();
|
||||
}
|
||||
}
|
||||
|
||||
public function getPrev($related = null) {
|
||||
if ($related) {
|
||||
return $related->videos()->filtered()->where('id', '<', $this->id)->orderBy('id', 'DESC')->first();
|
||||
} else {
|
||||
return static::filtered()->where('id', '<', $this->id)->orderBy('id', 'DESC')->first();
|
||||
}
|
||||
}
|
||||
|
||||
public function scopeNewlyups($query) {
|
||||
return $query->where('created_at', '>=', Carbon::now()->subHours(12));
|
||||
}
|
||||
|
||||
public function scopeFiltered($query) {
|
||||
if(auth()->check()) {
|
||||
// TODO rename to filtered
|
||||
$filter = auth()->user()->categories;
|
||||
if(empty($filter))
|
||||
return $query;
|
||||
|
||||
return $query->withoutAnyTags($filter);
|
||||
} else {
|
||||
// TODO: filter if post has sfw & nsfw tags
|
||||
//return $query->withAllTags('sfw');
|
||||
return $query->withoutAnyTags('nsfw');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function checkFileEncoding() {
|
||||
$dat = $this->file;
|
||||
$in = public_path() . "/b";
|
||||
$tmpdir = str_replace("public", "app/Http/Controllers/tmp", public_path());
|
||||
for($i = 0; $i < 2; $i++) {
|
||||
$ret = shell_exec("ffmpeg -y -ss 0 -i {$in}/{$dat} -vframes 1 {$tmpdir}/test.png 2>&1");
|
||||
if(strpos($ret, "nothing was encoded") !== false) {
|
||||
shell_exec("ffmpeg -i {$in}/{$dat} -map 0:0 -map 0:1 -c:v copy {$tmpdir}/{$dat}");
|
||||
unlink($in . "/" . $dat);
|
||||
rename($tmpdir . "/" . $dat, $in . "/" . $dat);
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a .gif thumbnail to a given video file
|
||||
*
|
||||
* @param string $dat File of the video
|
||||
*/
|
||||
public function createThumbnail() {
|
||||
$dat = $this->file;
|
||||
$in = public_path() . "/b"; // webm-input
|
||||
$out = public_path() . "/thumbs"; //thumb-output
|
||||
$tmpdir = str_replace("public", "app/Http/Controllers/tmp", public_path());
|
||||
|
||||
$name = explode(".", $dat);
|
||||
array_pop($name);
|
||||
$name = join(".", $name);
|
||||
if(!file_exists("{$out}/{$name}.gif")) {
|
||||
$length = round(shell_exec("ffprobe -i {$in}/{$dat} -show_format -v quiet | sed -n 's/duration=//p'"));
|
||||
for ($i = 1; $i < 10; $i++) {
|
||||
$act = ($i * 10) * ($length / 100);
|
||||
$ffmpeg = shell_exec("ffmpeg -ss {$act} -i {$in}/{$dat} -vf \"scale='if(gt(a,4/3),206,-1)':'if(gt(a,4/3),-1,116)'\" -vframes 1 {$tmpdir}/{$name}_{$i}.png 2>&1");
|
||||
}
|
||||
$tmp = shell_exec("convert -delay 27 -loop 0 {$tmpdir}/{$name}_*.png {$out}/{$name}.gif 2>&1");
|
||||
if(@filesize("{$out}/{$name}.gif") < 2000)
|
||||
@unlink("{$out}/{$name}.gif");
|
||||
array_map('unlink', glob("{$tmpdir}/{$name}*.png"));
|
||||
}
|
||||
}
|
||||
|
||||
public static function getRandom($related = null) {
|
||||
if ($related) {
|
||||
$id = $related->videos()->filtered()->countScoped()->count() - 1;
|
||||
if ($id < 0) {
|
||||
return redirect()->back()->with('error', 'no videos found');
|
||||
}
|
||||
$id = mt_rand(0, $id);
|
||||
return $related->videos()->filtered()->skip($id);
|
||||
}
|
||||
$id = static::filtered()->countScoped()->count() - 1;
|
||||
if ($id < 0) {
|
||||
return redirect()->back()->with('error', 'no videos found');
|
||||
}
|
||||
$id = mt_rand(0, $id);
|
||||
return static::filtered()->skip($id);
|
||||
}
|
||||
|
||||
public function isSfw() {
|
||||
return $this->tags->contains(function ($key, $tag) {
|
||||
$tag->normalized === 'sfw';
|
||||
});
|
||||
}
|
||||
|
||||
public function filesize() {
|
||||
return filesize(getcwd() . "/b/" . $this->file);
|
||||
}
|
||||
}
|
0
app/Policies/.gitkeep
Normal file
0
app/Policies/.gitkeep
Normal file
28
app/Providers/AppServiceProvider.php
Normal file
28
app/Providers/AppServiceProvider.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
31
app/Providers/AuthServiceProvider.php
Normal file
31
app/Providers/AuthServiceProvider.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The policy mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $policies = [
|
||||
'App\Model' => 'App\Policies\ModelPolicy',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any application authentication / authorization services.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Access\Gate $gate
|
||||
* @return void
|
||||
*/
|
||||
public function boot(GateContract $gate)
|
||||
{
|
||||
parent::registerPolicies($gate);
|
||||
|
||||
//
|
||||
}
|
||||
}
|
33
app/Providers/BladeServiceProvider.php
Normal file
33
app/Providers/BladeServiceProvider.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Blade;
|
||||
|
||||
class BladeServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
/* @simplemd($var) */
|
||||
/** @var \Illuminate\View\Compilers\BladeCompiler $compiler */
|
||||
Blade::directive('simplemd', function($text) {
|
||||
return "<?php echo App\\Models\\Comment::simplemd({$text}); ?>";
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
33
app/Providers/EventServiceProvider.php
Normal file
33
app/Providers/EventServiceProvider.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event listener mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listen = [
|
||||
'App\Events\SomeEvent' => [
|
||||
'App\Listeners\EventListener',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any other events for your application.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||
* @return void
|
||||
*/
|
||||
public function boot(DispatcherContract $events)
|
||||
{
|
||||
parent::boot($events);
|
||||
|
||||
//
|
||||
}
|
||||
}
|
31
app/Providers/MarkdownServiceProvider.php
Normal file
31
app/Providers/MarkdownServiceProvider.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use App\Services\Markdown;
|
||||
|
||||
class MarkdownServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->app->singleton(Markdown::class, function ($app) {
|
||||
return Markdown::instance();
|
||||
});
|
||||
}
|
||||
}
|
44
app/Providers/RouteServiceProvider.php
Normal file
44
app/Providers/RouteServiceProvider.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* This namespace is applied to the controller routes in your routes file.
|
||||
*
|
||||
* In addition, it is set as the URL generator's root namespace.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = 'App\Http\Controllers';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
*
|
||||
* @param \Illuminate\Routing\Router $router
|
||||
* @return void
|
||||
*/
|
||||
public function boot(Router $router)
|
||||
{
|
||||
//
|
||||
|
||||
parent::boot($router);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
*
|
||||
* @param \Illuminate\Routing\Router $router
|
||||
* @return void
|
||||
*/
|
||||
public function map(Router $router)
|
||||
{
|
||||
$router->group(['namespace' => $this->namespace], function ($router) {
|
||||
require app_path('Http/routes.php');
|
||||
});
|
||||
}
|
||||
}
|
340
app/Services/Markdown.php
Normal file
340
app/Services/Markdown.php
Normal file
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
use App\Models\User;
|
||||
|
||||
class Markdown extends \Parsedown {
|
||||
|
||||
|
||||
function __construct() {
|
||||
$this->setMarkupEscaped(true);
|
||||
$this->setBreaksEnabled(true);
|
||||
$this->setUrlsLinked(true);
|
||||
$this->InlineTypes['@'][] = 'UserMention';
|
||||
#$this->InlineTypes['%'][] = 'ColoredText';
|
||||
$this->InlineTypes['['][] = 'KrebsText';
|
||||
$this->InlineTypes['['][] = 'ReichText';
|
||||
$this->InlineTypes['['][] = 'RainbowText';
|
||||
$this->InlineTypes['['][] = 'SpoilerText';
|
||||
$this->InlineTypes[':'][] = 'emojimatcherpng';
|
||||
//$this->InlineTypes[':'][] = 'emojimatchermp4';
|
||||
$this->InlineTypes[':'][] = 'ClickableTimestamp';
|
||||
$this->inlineMarkerList .= '@';
|
||||
}
|
||||
|
||||
protected function paragraph($Line) {
|
||||
$Block = array(
|
||||
'element' => array(
|
||||
'name' => 'p',
|
||||
'text' => $Line['text'],
|
||||
'handler' => 'line',
|
||||
'attributes' => [
|
||||
'class' => 'comment'
|
||||
]
|
||||
),
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
// Matches the emojis in png format
|
||||
protected function inlineemojimatcherpng($Excerpt) {
|
||||
if (preg_match('/\:(\w+)\:/mUs', $Excerpt['text'], $matches)) {
|
||||
$path = "images/comments/" . $matches[1];
|
||||
$file_ext = "";
|
||||
if(file_exists($path . ".png"))
|
||||
$file_ext = ".png";
|
||||
else if(file_exists($path . ".gif"))
|
||||
$file_ext = ".gif";
|
||||
if($file_ext === "")
|
||||
return;
|
||||
return [
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => [
|
||||
'name' => 'img',
|
||||
'handler' => 'line',
|
||||
'attributes' => [
|
||||
'class' => 'comment_emoji',
|
||||
'src' => '//s.w0bm.com/images/comments/' . $matches[1] . $file_ext,
|
||||
'alt' => ':' . $matches[1] . ':',
|
||||
'title' => ':' . $matches[1] . ':'
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Matches MP4 Emojis (Currently not possible due to Chromes shitty and malfunctioning autplay policy. Thanks idiots :*)
|
||||
//protected function inlineemojimatchermp4($Excerpt) {
|
||||
// if (preg_match('/\:(uwe)\:/mUs', $Excerpt['text'], $matches)) {
|
||||
// return [
|
||||
// 'extent' => strlen($matches[0]),
|
||||
// 'element' => [
|
||||
// 'name' => 'video',
|
||||
// 'handler' => 'line',
|
||||
// 'attributes' => [
|
||||
// 'loop' => 'true',
|
||||
// 'autoplay' => 'true',
|
||||
// 'muted' => '',
|
||||
// 'class' => 'comment_video',
|
||||
// 'src' => '/images/comments/' . $matches[1] . '.mp4'
|
||||
// ],
|
||||
// ]
|
||||
// ];
|
||||
// }
|
||||
//}
|
||||
|
||||
protected function inlineUserMention($Excerpt) {
|
||||
if (preg_match('/\B@([\wÄÖÜäöü]+)/i', $Excerpt['context'], $matches)) {
|
||||
if(User::whereUsername($matches[1])->count() > 0) {
|
||||
return [
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => [
|
||||
'name' => 'a',
|
||||
'text' => $matches[0],
|
||||
'attributes' => [
|
||||
'href' => '/user/' . $matches[1], //link to username profile
|
||||
'class' => 'user-mention', //style class of url
|
||||
],
|
||||
],
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'markup' => $matches[0],
|
||||
'extent' => strlen($matches[0]),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Matches [rb][/rb]
|
||||
protected function inlineRainbowText($Excerpt) {
|
||||
if (preg_match('/\[rb\](.+)\[\/rb]/mUs', $Excerpt['text'], $matches)) {
|
||||
return [
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => [
|
||||
'name' => 'span',
|
||||
'handler' => 'line',
|
||||
'text' => $matches[1],
|
||||
'attributes' => [
|
||||
'class' => 'rainbow'
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Matches [spoiler][/spoiler]
|
||||
protected function inlineSpoilerText($Excerpt) {
|
||||
if (preg_match('/\[spoiler\](.+)\[\/spoiler]/mUs', $Excerpt['text'], $matches)) {
|
||||
return [
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => [
|
||||
'name' => 'span',
|
||||
'handler' => 'line',
|
||||
'text' => $matches[1],
|
||||
'attributes' => [
|
||||
'class' => 'spoiler'
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Matches [krebs][/krebs]
|
||||
protected function inlineKrebsText($Excerpt) {
|
||||
if (preg_match('/\[krebs\](.+)\[\/krebs]/mUs', $Excerpt['text'], $matches)) {
|
||||
return [
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => [
|
||||
'name' => 'span',
|
||||
'handler' => 'line',
|
||||
'text' => $matches[1],
|
||||
'attributes' => [
|
||||
'class' => 'anim'
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Matches Reichtext
|
||||
protected function inlineReichText($Excerpt) {
|
||||
if (preg_match('/\[reich\](.+)\[\/reich]/mUs', $Excerpt['text'], $matches)) {
|
||||
return [
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => [
|
||||
'name' => 'span',
|
||||
'handler' => 'line',
|
||||
'text' => $matches[1],
|
||||
'attributes' => [
|
||||
'class' => 'reich'
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Matches %text% <- literally wtf error
|
||||
/*protected function inlineColoredText($Excerpt) {
|
||||
if (preg_match('/%(.+)%/', $Excerpt['text'], $matches)) {
|
||||
return [
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => [
|
||||
'name' => 'span',
|
||||
'text' => $matches[1],
|
||||
'attributes' => [
|
||||
'class' => ''
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
}*/
|
||||
|
||||
//Greentext
|
||||
protected function blockQuote($Excerpt) {
|
||||
if (preg_match('/^>[ ]?(.*)/', $Excerpt['text'], $matches)) {
|
||||
$Block = [
|
||||
'element' => [
|
||||
'name' => 'blockquote',
|
||||
'handler' => 'lines',
|
||||
'text' => (array) ('>' . $matches[1]),
|
||||
],
|
||||
];
|
||||
return $Block;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function blockQuoteContinue($Excerpt, array $Block) {
|
||||
if ($Excerpt['text'][0] === '>' && preg_match('/^>[ ]?(.*)/', $Excerpt['text'], $matches)) {
|
||||
if (isset($Block['interrupted'])) {
|
||||
$Block['element']['text'][] = '';
|
||||
unset($Block['interrupted']);
|
||||
}
|
||||
$Block['element']['text'][] = '>' . $matches[1];
|
||||
return $Block;
|
||||
}
|
||||
if (!isset($Block['interrupted'])) {
|
||||
$Block['element']['text'][] = '>' . $Excerpt['text'];
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable Lists
|
||||
protected function blockList($Excerpt) {
|
||||
return;
|
||||
}
|
||||
|
||||
protected function blockListContinue($Excerpt, array $block) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable headers
|
||||
protected function blockHeader($Excerpt) {
|
||||
return;
|
||||
}
|
||||
|
||||
protected function blockSetextHeader($Excerpt, array $block = null) {
|
||||
return;
|
||||
}
|
||||
|
||||
protected function blockTable($Excerpt, array $block = null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable markdown links
|
||||
protected function inlineLink($Excerpt) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable markdown images
|
||||
protected function inlineImage($Excerpt) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Differentiate between internal and external urls and images
|
||||
protected function inlineUrl($Excerpt) {
|
||||
$e = parent::inlineUrl($Excerpt);
|
||||
if (is_null($e)) return;
|
||||
if (static::isImage($e['element']['attributes']['href'])) {
|
||||
$e['element']['name'] = 'img';
|
||||
$e['element']['attributes']['src'] = $e['element']['attributes']['href'];
|
||||
$e['element']['attributes']['alt'] = 'Image';
|
||||
$e['element']['attributes']['class'] = 'comment_image';
|
||||
unset($e['element']['attributes']['href']);
|
||||
unset($e['element']['text']);
|
||||
return $e;
|
||||
}
|
||||
if (!static::isInternal($e['element']['attributes']['href'])) {
|
||||
$e['element']['attributes']['target'] = '_blank';
|
||||
$e['element']['attributes']['rel'] = 'extern';
|
||||
} else {
|
||||
$url = parse_url($e['element']['text']);
|
||||
$text = $url['path'];
|
||||
if (isset($url['query'])) {
|
||||
$text .= '?' . $url['query'];
|
||||
}
|
||||
if (isset($url['fragment'])) {
|
||||
$text .= '#' . $url['fragment'];
|
||||
}
|
||||
$e['element']['text'] = $text;
|
||||
}
|
||||
return $e;
|
||||
}
|
||||
|
||||
protected function inlineClickableTimestamp($Excerpt) {
|
||||
if (preg_match('/(?<=\s|^)([0-5]?\d:[0-5]\d)(?=\s|$)/', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) {
|
||||
return [
|
||||
'extent' => strlen($matches[0][0]),
|
||||
'position' => $matches[0][1],
|
||||
'element' => [
|
||||
'name' => 'a',
|
||||
'text' => $matches[0][0],
|
||||
'attributes' => [
|
||||
'href' => '#',
|
||||
'class' => 'comment_clickable_timestamp'
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
private static function isInternal($url) {
|
||||
$host = parse_url($url, PHP_URL_HOST);
|
||||
$currhost = $_SERVER['SERVER_NAME'];
|
||||
if (0 === strpos($host, 'www')) {
|
||||
$host = substr($host, 4);
|
||||
}
|
||||
if (0 === strpos($currhost, 'www')) {
|
||||
$currhost = substr($currhost, 4);
|
||||
}
|
||||
return $host === $currhost;
|
||||
}
|
||||
|
||||
private static function isImage($url) {
|
||||
$cfg = config('comments');
|
||||
$allowedHosters = $cfg['allowedHosters'];
|
||||
$allowedExtensions = $cfg['allowedImageFileExtensions'];
|
||||
$url = parse_url($url);
|
||||
if (isset($url['path'])) {
|
||||
$ext = pathinfo($url['path'], PATHINFO_EXTENSION);
|
||||
if (in_array($ext, $allowedExtensions)) {
|
||||
if (isset($url['scheme']) && $url['scheme'] === 'https') {
|
||||
foreach($allowedHosters as $hoster) {
|
||||
foreach($hoster as $regex) {
|
||||
if(preg_match($regex, $url['host'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user