blessing-skin-server/app/Http/Controllers/SkinlibController.php

346 lines
11 KiB
PHP
Raw Normal View History

2016-07-21 22:01:57 +08:00
<?php
2016-08-28 10:05:21 +08:00
namespace App\Http\Controllers;
2016-07-21 22:01:57 +08:00
use View;
use Utils;
use Option;
use Storage;
use Session;
2016-07-21 22:01:57 +08:00
use App\Models\User;
use App\Models\Closet;
use App\Models\Player;
2016-07-21 22:01:57 +08:00
use App\Models\Texture;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Exceptions\PrettyPageException;
2016-10-23 11:41:52 +08:00
use App\Services\Repositories\UserRepository;
2016-07-21 22:01:57 +08:00
class SkinlibController extends Controller
2016-07-21 22:01:57 +08:00
{
2018-02-16 17:31:04 +08:00
protected $user = null;
2016-07-21 22:01:57 +08:00
2016-10-23 11:41:52 +08:00
public function __construct(UserRepository $users)
2016-07-21 22:01:57 +08:00
{
2016-10-23 11:41:52 +08:00
// Try to load user by uid stored in session.
// If there is no uid stored in session or the uid is invalid
// it will return a null value.
$this->user = $users->get(session('uid'));
2016-07-21 22:01:57 +08:00
}
public function index()
2016-07-21 22:01:57 +08:00
{
return view('skinlib.index', ['user' => $this->user]);
}
2016-07-21 22:01:57 +08:00
/**
* Get skin library data filtered.
* Available Query String: filter, uploader, page, sort, keyword, items_per_page.
*
* @param Request $request [description]
2017-11-24 18:54:30 +08:00
* @return JsonResponse
*/
public function getSkinlibFiltered(Request $request)
{
2016-07-26 13:36:24 +08:00
// Available filters: skin, steve, alex, cape
$filter = $request->input('filter', 'skin');
2016-07-21 22:01:57 +08:00
// Filter result by uploader's uid
$uploader = intval($request->input('uploader', 0));
2017-05-05 12:43:53 +08:00
// Available sorting methods: time, likes
$sort = $request->input('sort', 'time');
$sortBy = ($sort == "time") ? "upload_at" : $sort;
2017-05-05 12:43:53 +08:00
// Current page
$page = $request->input('page', 1);
$currentPage = ($page <= 0) ? 1 : $page;
2016-08-13 22:31:24 +08:00
// How many items to show in one page
$itemsPerPage = $request->input('items_per_page', 20);
2017-11-24 18:54:30 +08:00
$itemsPerPage = $itemsPerPage <= 0 ? 20 : $itemsPerPage;
2016-07-24 11:12:52 +08:00
// Keyword to search
$keyword = $request->input('keyword', '');
2016-07-21 22:01:57 +08:00
// Check if user logged in
$anonymous = is_null($this->user);
2016-07-21 22:01:57 +08:00
if ($filter == "skin") {
$query = Texture::where(function ($innerQuery) {
// Nested condition, DO NOT MODIFY
$innerQuery->where('type', '=', 'steve')->orWhere('type', '=', 'alex');
});
} else {
$query = Texture::where('type', $filter);
}
2016-07-21 22:01:57 +08:00
if ($keyword !== "") {
$query = $query->like('name', $keyword);
}
2016-07-21 22:01:57 +08:00
if ($uploader !== 0) {
$query = $query->where('uploader', $uploader);
}
if ($anonymous) {
// Show public textures only to anonymous visitors
$query = $query->where('public', 1);
2016-07-21 22:01:57 +08:00
} else {
// Show private textures when show uploaded textures of current user
if ($uploader != $this->user->uid && !$this->user->isAdmin()) {
$query = $query->where(function ($innerQuery) {
$innerQuery->where('public', '=', '1')->orWhere('uploader', '=', $this->user->uid);
});
}
2016-07-21 22:01:57 +08:00
}
2017-11-24 18:54:30 +08:00
$totalPages = ceil($query->count() / $itemsPerPage);
$textures = $query->orderBy($sortBy, 'desc')
->skip(($currentPage - 1) * $itemsPerPage)
->take($itemsPerPage)
->get();
if (! $anonymous) {
foreach ($textures as $item) {
$item->liked = $this->user->getCloset()->has($item->tid);
}
}
return response()->json([
'items' => $textures,
'anonymous' => $anonymous,
'total_pages' => $totalPages
]);
2016-07-21 22:01:57 +08:00
}
public function show($tid)
2016-07-21 22:01:57 +08:00
{
$texture = Texture::find($tid);
2018-02-16 17:31:04 +08:00
if (! $texture || $texture && !Storage::disk('textures')->has($texture->hash)) {
if (option('auto_del_invalid_texture')) {
if ($texture) {
2016-08-28 20:33:35 +08:00
$texture->delete();
}
2016-08-28 20:33:35 +08:00
2016-09-24 22:49:20 +08:00
abort(404, trans('skinlib.show.deleted'));
}
2016-09-24 22:49:20 +08:00
abort(404, trans('skinlib.show.deleted').trans('skinlib.show.contact-admin'));
2016-08-16 22:58:21 +08:00
}
2016-07-21 22:01:57 +08:00
if ($texture->public == "0") {
2016-10-23 11:41:52 +08:00
if (is_null($this->user) || ($this->user->uid != $texture->uploader && !$this->user->isAdmin()))
abort(403, trans('skinlib.show.private'));
2016-07-21 22:01:57 +08:00
}
return view('skinlib.show')->with('texture', $texture)->with('with_out_filter', true)->with('user', $this->user);
2016-07-21 22:01:57 +08:00
}
public function info($tid)
{
2016-12-10 19:49:45 +08:00
if ($t = Texture::find($tid)) {
return json($t->toArray());
} else {
return json([]);
}
2016-07-21 22:01:57 +08:00
}
public function upload()
{
return view('skinlib.upload')->with('user', $this->user)->with('with_out_filter', true);
2016-07-21 22:01:57 +08:00
}
public function handleUpload(Request $request)
2016-07-21 22:01:57 +08:00
{
if (($response = $this->checkUpload($request)) instanceof JsonResponse) {
return $response;
}
2016-07-21 22:01:57 +08:00
2016-07-24 09:36:34 +08:00
$t = new Texture();
$t->name = $request->input('name');
$t->type = $request->input('type');
2016-08-14 13:31:56 +08:00
$t->likes = 1;
$t->hash = bs_hash_file($request->file('file'));
2017-11-24 18:54:30 +08:00
$t->size = ceil($request->file('file')->getSize() / 1024);
$t->public = ($request->input('public') == 'true') ? "1" : "0";
2016-07-24 09:36:34 +08:00
$t->uploader = $this->user->uid;
$t->upload_at = Utils::getTimeFormatted();
2016-07-21 22:01:57 +08:00
$cost = $t->size * (($t->public == "1") ? Option::get('score_per_storage') : Option::get('private_score_per_storage'));
2017-04-22 23:35:25 +08:00
$cost += option('score_per_closet_item');
if ($this->user->getScore() < $cost)
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.upload.lack-score'), 7);
2016-07-21 22:01:57 +08:00
$results = Texture::where('hash', $t->hash)->get();
2018-02-16 17:31:04 +08:00
if (! $results->isEmpty()) {
2016-07-21 22:01:57 +08:00
foreach ($results as $result) {
2017-11-24 18:54:30 +08:00
// if the texture already uploaded was set to private,
// then allow to re-upload it.
if ($result->type == $t->type && $result->public == "1") {
return json(trans('skinlib.upload.repeated'), 0, [
2016-07-22 10:45:36 +08:00
'tid' => $result->tid
]);
2016-07-21 22:01:57 +08:00
}
}
}
if (! Storage::disk('textures')->exists($t->hash)) {
Storage::disk('textures')->put($t->hash, file_get_contents($request->file('file')));
}
2016-07-21 22:01:57 +08:00
$t->save();
$this->user->setScore($cost, 'minus');
2016-07-21 22:01:57 +08:00
2016-10-23 11:41:52 +08:00
if ($this->user->getCloset()->add($t->tid, $t->name)) {
return json(trans('skinlib.upload.success', ['name' => $request->input('name')]), 0, [
2016-07-21 22:01:57 +08:00
'tid' => $t->tid
]);
}
2017-11-24 18:54:30 +08:00
} // @codeCoverageIgnore
2016-07-21 22:01:57 +08:00
2017-04-26 16:24:19 +08:00
public function delete(Request $request, UserRepository $users)
2016-07-21 22:01:57 +08:00
{
$result = Texture::find($request->tid);
2016-07-21 22:01:57 +08:00
2018-02-16 17:31:04 +08:00
if (! $result) {
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.non-existent'), 1);
}
2016-07-21 22:01:57 +08:00
if ($result->uploader != $this->user->uid && !$this->user->isAdmin()) {
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.no-permission'), 1);
}
2016-07-21 22:01:57 +08:00
2016-07-24 15:56:23 +08:00
// check if file occupied
2017-11-24 18:54:30 +08:00
if (Texture::where('hash', $result->hash)->count() == 1) {
Storage::disk('textures')->delete($result->hash);
}
2016-07-21 22:01:57 +08:00
if (option('return_score')) {
2017-11-07 20:45:29 +08:00
if ($u = $users->get($result->uploader)) {
if ($result->public == 1) {
$u->setScore(
$result->size * option('score_per_storage'), 'plus'
);
} else {
$u->setScore(
$result->size * option('private_score_per_storage'), 'plus'
);
2017-04-22 23:35:25 +08:00
}
}
}
2016-07-24 15:56:23 +08:00
if ($result->delete()) {
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.delete.success'), 0);
}
2017-11-24 18:54:30 +08:00
} // @codeCoverageIgnore
2016-07-21 22:01:57 +08:00
2017-04-26 16:24:19 +08:00
public function privacy(Request $request, UserRepository $users)
2016-07-21 22:01:57 +08:00
{
$t = Texture::find($request->input('tid'));
2016-07-24 15:56:23 +08:00
2018-02-16 17:31:04 +08:00
if (! $t)
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.non-existent'), 1);
2016-07-24 15:56:23 +08:00
2016-10-23 11:41:52 +08:00
if ($t->uploader != $this->user->uid && !$this->user->isAdmin())
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.no-permission'), 1);
2016-07-24 15:56:23 +08:00
2017-09-18 19:28:38 +08:00
$score_diff = $t->size * (option('private_score_per_storage') - option('score_per_storage')) * ($t->public == 1 ? -1 : 1);
if ($users->get($t->uploader)->getScore() + $score_diff < 0) {
return json(trans('skinlib.upload.lack-score'), 1);
}
2017-11-24 18:54:30 +08:00
$type = $t->type;
Player::where("tid_$type", $t->tid)
->where('uid', '<>', session('uid'))
->get()
->each(function ($player) use ($type) {
$player->setTexture(["tid_$type" => 0]);
});
2017-11-07 20:45:29 +08:00
@$users->get($t->uploader)->setScore($score_diff, 'plus');
2017-04-21 18:44:11 +08:00
2016-07-21 22:01:57 +08:00
if ($t->setPrivacy(!$t->public)) {
2016-09-10 21:39:45 +08:00
return json([
2016-07-21 22:01:57 +08:00
'errno' => 0,
2016-09-24 22:49:20 +08:00
'msg' => trans('skinlib.privacy.success', ['privacy' => ($t->public == "0" ? trans('general.private') : trans('general.public'))]),
2016-07-21 22:01:57 +08:00
'public' => $t->public
]);
}
2017-11-24 18:54:30 +08:00
} // @codeCoverageIgnore
2016-07-21 22:01:57 +08:00
public function rename(Request $request) {
$this->validate($request, [
'tid' => 'required|integer',
'new_name' => 'required|no_special_chars'
]);
2016-07-24 15:56:23 +08:00
$t = Texture::find($request->input('tid'));
2016-07-24 15:56:23 +08:00
2018-02-16 17:31:04 +08:00
if (! $t)
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.non-existent'), 1);
2016-07-24 15:56:23 +08:00
2016-10-23 11:41:52 +08:00
if ($t->uploader != $this->user->uid && !$this->user->isAdmin())
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.no-permission'), 1);
2016-07-24 15:56:23 +08:00
$t->name = $request->input('new_name');
2016-07-24 15:56:23 +08:00
if ($t->save()) {
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.rename.success', ['name' => $request->input('new_name')]), 0);
2016-07-24 15:56:23 +08:00
}
2017-11-24 18:54:30 +08:00
} // @codeCoverageIgnore
2016-07-24 15:56:23 +08:00
/**
* Check Uploaded Files
*
* @param Request $request
2017-11-24 18:54:30 +08:00
* @return JsonResponse
*/
2018-02-16 17:31:04 +08:00
protected function checkUpload(Request $request)
2016-07-21 22:01:57 +08:00
{
if ($file = $request->files->get('file')) {
if ($file->getError() !== UPLOAD_ERR_OK) {
return json(Utils::convertUploadFileError($file->getError()), $file->getError());
}
}
$this->validate($request, [
'name' => 'required|no_special_chars',
'file' => 'required|max:'.option('max_upload_file_size'),
'public' => 'required'
]);
if (extension_loaded('fileinfo')) {
$mime = $request->file('file')->getMimeType();
} else {
$mime = $_FILES['file']['type'];
}
2017-11-24 18:54:30 +08:00
if ($mime != "image/png" && $mime != "image/x-png") {
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.upload.type-error'), 1);
}
$type = $request->input('type');
2017-11-24 18:54:30 +08:00
$size = getimagesize($request->file('file'));
$ratio = $size[0] / $size[1];
if ($type == "steve" || $type == "alex") {
if ($ratio != 2 && $ratio != 1)
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.upload.invalid-size', ['type' => trans('general.skin'), 'width' => $size[0], 'height' => $size[1]]), 1);
2017-01-25 15:34:43 +08:00
if ($size[0] % 64 != 0 || $size[1] % 32 != 0)
return json(trans('skinlib.upload.invalid-hd-skin', ['type' => trans('general.skin'), 'width' => $size[0], 'height' => $size[1]]), 1);
} elseif ($type == "cape") {
if ($ratio != 2)
2016-09-24 22:49:20 +08:00
return json(trans('skinlib.upload.invalid-size', ['type' => trans('general.cape'), 'width' => $size[0], 'height' => $size[1]]), 1);
2016-07-21 22:01:57 +08:00
} else {
2016-09-24 22:49:20 +08:00
return json(trans('general.illegal-parameters'), 1);
2016-07-21 22:01:57 +08:00
}
2017-11-24 18:54:30 +08:00
} // @codeCoverageIgnore
2016-07-21 22:01:57 +08:00
}