diff --git a/app/Http/Controllers/StatusController.php b/app/Http/Controllers/StatusController.php index cda8c77ee..4e2d1a16a 100644 --- a/app/Http/Controllers/StatusController.php +++ b/app/Http/Controllers/StatusController.php @@ -21,422 +21,398 @@ use App\Util\Media\Filter; use Illuminate\Support\Str; use App\Services\HashidService; use App\Services\StatusService; +use App\Util\Media\License; class StatusController extends Controller { - public function show(Request $request, $username, int $id) - { - $user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); + public function show(Request $request, $username, int $id) + { + $user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); - if($user->status != null) { - return ProfileController::accountCheck($user); - } + if($user->status != null) { + return ProfileController::accountCheck($user); + } - $status = Status::whereProfileId($user->id) - ->whereNull('reblog_of_id') - ->whereIn('scope', ['public','unlisted', 'private']) - ->findOrFail($id); + $status = Status::whereProfileId($user->id) + ->whereNull('reblog_of_id') + ->whereIn('scope', ['public','unlisted', 'private']) + ->findOrFail($id); - if($status->uri || $status->url) { - $url = $status->uri ?? $status->url; - if(ends_with($url, '/activity')) { - $url = str_replace('/activity', '', $url); - } - return redirect($url); - } + if($status->uri || $status->url) { + $url = $status->uri ?? $status->url; + if(ends_with($url, '/activity')) { + $url = str_replace('/activity', '', $url); + } + return redirect($url); + } - if($status->visibility == 'private' || $user->is_private) { - if(!Auth::check()) { - abort(404); - } - $pid = Auth::user()->profile; - if($user->followedBy($pid) == false && $user->id !== $pid->id && Auth::user()->is_admin == false) { - abort(404); - } - } + if($status->visibility == 'private' || $user->is_private) { + if(!Auth::check()) { + abort(404); + } + $pid = Auth::user()->profile; + if($user->followedBy($pid) == false && $user->id !== $pid->id && Auth::user()->is_admin == false) { + abort(404); + } + } - if($status->type == 'archived') { - if(Auth::user()->profile_id !== $status->profile_id) { - abort(404); - } - } + if($status->type == 'archived') { + if(Auth::user()->profile_id !== $status->profile_id) { + abort(404); + } + } - if($request->user() && $request->user()->profile_id != $status->profile_id) { - StatusView::firstOrCreate([ - 'status_id' => $status->id, - 'status_profile_id' => $status->profile_id, - 'profile_id' => $request->user()->profile_id - ]); - } + if($request->user() && $request->user()->profile_id != $status->profile_id) { + StatusView::firstOrCreate([ + 'status_id' => $status->id, + 'status_profile_id' => $status->profile_id, + 'profile_id' => $request->user()->profile_id + ]); + } - if ($request->wantsJson() && config('federation.activitypub.enabled')) { - return $this->showActivityPub($request, $status); - } + if ($request->wantsJson() && config('federation.activitypub.enabled')) { + return $this->showActivityPub($request, $status); + } - $template = $status->in_reply_to_id ? 'status.reply' : 'status.show'; - // $template = $status->type === 'video' && - // $request->has('video_beta') && - // $request->video_beta == 1 && - // $request->user() ? - // 'status.show_video' : 'status.show'; + $template = $status->in_reply_to_id ? 'status.reply' : 'status.show'; - return view($template, compact('user', 'status')); - } + return view($template, compact('user', 'status')); + } - public function shortcodeRedirect(Request $request, $id) - { - abort_if(strlen($id) < 5, 404); - if(!Auth::check()) { - return redirect('/login?next='.urlencode('/' . $request->path())); - } - $id = HashidService::decode($id); - $status = Status::find($id); - if(!$status) { - return redirect('/404'); - } - return redirect($status->url()); - } + public function shortcodeRedirect(Request $request, $id) + { + abort_if(strlen($id) < 5, 404); + if(!Auth::check()) { + return redirect('/login?next='.urlencode('/' . $request->path())); + } + $id = HashidService::decode($id); + $status = Status::find($id); + if(!$status) { + return redirect('/404'); + } + return redirect($status->url()); + } - public function showId(int $id) - { - abort(404); - $status = Status::whereNull('reblog_of_id') - ->whereIn('scope', ['public', 'unlisted']) - ->findOrFail($id); - return redirect($status->url()); - } + public function showId(int $id) + { + abort(404); + $status = Status::whereNull('reblog_of_id') + ->whereIn('scope', ['public', 'unlisted']) + ->findOrFail($id); + return redirect($status->url()); + } - public function showEmbed(Request $request, $username, int $id) - { - $profile = Profile::whereNull(['domain','status']) - ->whereIsPrivate(false) - ->whereUsername($username) - ->first(); - if(!$profile) { - $content = view('status.embed-removed'); - return response($content)->header('X-Frame-Options', 'ALLOWALL'); - } - $status = Status::whereProfileId($profile->id) - ->whereNull('uri') - ->whereScope('public') - ->whereIsNsfw(false) - ->whereIn('type', ['photo', 'video','photo:album']) - ->find($id); - if(!$status) { - $content = view('status.embed-removed'); - return response($content)->header('X-Frame-Options', 'ALLOWALL'); - } - $showLikes = $request->filled('likes') && $request->likes == true; - $showCaption = $request->filled('caption') && $request->caption !== false; - $layout = $request->filled('layout') && $request->layout == 'compact' ? 'compact' : 'full'; - $content = view('status.embed', compact('status', 'showLikes', 'showCaption', 'layout')); - return response($content)->withHeaders(['X-Frame-Options' => 'ALLOWALL']); - } + public function showEmbed(Request $request, $username, int $id) + { + $profile = Profile::whereNull(['domain','status']) + ->whereIsPrivate(false) + ->whereUsername($username) + ->first(); + if(!$profile) { + $content = view('status.embed-removed'); + return response($content)->header('X-Frame-Options', 'ALLOWALL'); + } + $status = Status::whereProfileId($profile->id) + ->whereNull('uri') + ->whereScope('public') + ->whereIsNsfw(false) + ->whereIn('type', ['photo', 'video','photo:album']) + ->find($id); + if(!$status) { + $content = view('status.embed-removed'); + return response($content)->header('X-Frame-Options', 'ALLOWALL'); + } + $showLikes = $request->filled('likes') && $request->likes == true; + $showCaption = $request->filled('caption') && $request->caption !== false; + $layout = $request->filled('layout') && $request->layout == 'compact' ? 'compact' : 'full'; + $content = view('status.embed', compact('status', 'showLikes', 'showCaption', 'layout')); + return response($content)->withHeaders(['X-Frame-Options' => 'ALLOWALL']); + } - public function showObject(Request $request, $username, int $id) - { - $user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); + public function showObject(Request $request, $username, int $id) + { + $user = Profile::whereNull('domain')->whereUsername($username)->firstOrFail(); - if($user->status != null) { - return ProfileController::accountCheck($user); - } + if($user->status != null) { + return ProfileController::accountCheck($user); + } - $status = Status::whereProfileId($user->id) - ->whereNotIn('visibility',['draft','direct']) - ->findOrFail($id); + $status = Status::whereProfileId($user->id) + ->whereNotIn('visibility',['draft','direct']) + ->findOrFail($id); - abort_if($status->uri, 404); + abort_if($status->uri, 404); - if($status->visibility == 'private' || $user->is_private) { - if(!Auth::check()) { - abort(403); - } - $pid = Auth::user()->profile; - if($user->followedBy($pid) == false && $user->id !== $pid->id) { - abort(403); - } - } + if($status->visibility == 'private' || $user->is_private) { + if(!Auth::check()) { + abort(403); + } + $pid = Auth::user()->profile; + if($user->followedBy($pid) == false && $user->id !== $pid->id) { + abort(403); + } + } - return $this->showActivityPub($request, $status); - } + return $this->showActivityPub($request, $status); + } - public function compose() - { - $this->authCheck(); + public function compose() + { + $this->authCheck(); - return view('status.compose'); - } + return view('status.compose'); + } - public function store(Request $request) - { - return; - } + public function store(Request $request) + { + return; + } - public function delete(Request $request) - { - $this->authCheck(); + public function delete(Request $request) + { + $this->authCheck(); - $this->validate($request, [ - 'item' => 'required|integer|min:1', - ]); + $this->validate($request, [ + 'item' => 'required|integer|min:1', + ]); - $status = Status::findOrFail($request->input('item')); + $status = Status::findOrFail($request->input('item')); - $user = Auth::user(); + $user = Auth::user(); - if($status->profile_id != $user->profile->id && - $user->is_admin == true && - $status->uri == null - ) { - $media = $status->media; + if($status->profile_id != $user->profile->id && + $user->is_admin == true && + $status->uri == null + ) { + $media = $status->media; - $ai = new AccountInterstitial; - $ai->user_id = $status->profile->user_id; - $ai->type = 'post.removed'; - $ai->view = 'account.moderation.post.removed'; - $ai->item_type = 'App\Status'; - $ai->item_id = $status->id; - $ai->has_media = (bool) $media->count(); - $ai->blurhash = $media->count() ? $media->first()->blurhash : null; - $ai->meta = json_encode([ - 'caption' => $status->caption, - 'created_at' => $status->created_at, - 'type' => $status->type, - 'url' => $status->url(), - 'is_nsfw' => $status->is_nsfw, - 'scope' => $status->scope, - 'reblog' => $status->reblog_of_id, - 'likes_count' => $status->likes_count, - 'reblogs_count' => $status->reblogs_count, - ]); - $ai->save(); + $ai = new AccountInterstitial; + $ai->user_id = $status->profile->user_id; + $ai->type = 'post.removed'; + $ai->view = 'account.moderation.post.removed'; + $ai->item_type = 'App\Status'; + $ai->item_id = $status->id; + $ai->has_media = (bool) $media->count(); + $ai->blurhash = $media->count() ? $media->first()->blurhash : null; + $ai->meta = json_encode([ + 'caption' => $status->caption, + 'created_at' => $status->created_at, + 'type' => $status->type, + 'url' => $status->url(), + 'is_nsfw' => $status->is_nsfw, + 'scope' => $status->scope, + 'reblog' => $status->reblog_of_id, + 'likes_count' => $status->likes_count, + 'reblogs_count' => $status->reblogs_count, + ]); + $ai->save(); - $u = $status->profile->user; - $u->has_interstitial = true; - $u->save(); - } + $u = $status->profile->user; + $u->has_interstitial = true; + $u->save(); + } - Cache::forget('_api:statuses:recent_9:' . $status->profile_id); - Cache::forget('profile:status_count:' . $status->profile_id); - Cache::forget('profile:embed:' . $status->profile_id); - StatusService::del($status->id); - if ($status->profile_id == $user->profile->id || $user->is_admin == true) { - Cache::forget('profile:status_count:'.$status->profile_id); - StatusDelete::dispatch($status); - } + Cache::forget('_api:statuses:recent_9:' . $status->profile_id); + Cache::forget('profile:status_count:' . $status->profile_id); + Cache::forget('profile:embed:' . $status->profile_id); + StatusService::del($status->id); + if ($status->profile_id == $user->profile->id || $user->is_admin == true) { + Cache::forget('profile:status_count:'.$status->profile_id); + StatusDelete::dispatch($status); + } - if($request->wantsJson()) { - return response()->json(['Status successfully deleted.']); - } else { - return redirect($user->url()); - } - } + if($request->wantsJson()) { + return response()->json(['Status successfully deleted.']); + } else { + return redirect($user->url()); + } + } - public function storeShare(Request $request) - { - $this->authCheck(); - - $this->validate($request, [ - 'item' => 'required|integer|min:1', - ]); + public function storeShare(Request $request) + { + $this->authCheck(); - $user = Auth::user(); - $profile = $user->profile; - $status = Status::withCount('shares') - ->whereIn('scope', ['public', 'unlisted']) - ->findOrFail($request->input('item')); + $this->validate($request, [ + 'item' => 'required|integer|min:1', + ]); - $count = $status->shares()->count(); + $user = Auth::user(); + $profile = $user->profile; + $status = Status::withCount('shares') + ->whereIn('scope', ['public', 'unlisted']) + ->findOrFail($request->input('item')); - $exists = Status::whereProfileId(Auth::user()->profile->id) - ->whereReblogOfId($status->id) - ->count(); - if ($exists !== 0) { - $shares = Status::whereProfileId(Auth::user()->profile->id) - ->whereReblogOfId($status->id) - ->get(); - foreach ($shares as $share) { - $share->delete(); - $count--; - } - } else { - $share = new Status(); - $share->profile_id = $profile->id; - $share->reblog_of_id = $status->id; - $share->in_reply_to_profile_id = $status->profile_id; - $share->save(); - $count++; - SharePipeline::dispatch($share); - } - - if($count >= 0) { - $status->reblogs_count = $count; - $status->save(); - } - - Cache::forget('status:'.$status->id.':sharedby:userid:'.$user->id); - StatusService::del($status->id); - - if ($request->ajax()) { - $response = ['code' => 200, 'msg' => 'Share saved', 'count' => $count]; - } else { - $response = redirect($status->url()); - } + $count = $status->shares()->count(); - return $response; - } + $exists = Status::whereProfileId(Auth::user()->profile->id) + ->whereReblogOfId($status->id) + ->count(); + if ($exists !== 0) { + $shares = Status::whereProfileId(Auth::user()->profile->id) + ->whereReblogOfId($status->id) + ->get(); + foreach ($shares as $share) { + $share->delete(); + $count--; + } + } else { + $share = new Status(); + $share->profile_id = $profile->id; + $share->reblog_of_id = $status->id; + $share->in_reply_to_profile_id = $status->profile_id; + $share->save(); + $count++; + SharePipeline::dispatch($share); + } - public function showActivityPub(Request $request, $status) - { - $fractal = new Fractal\Manager(); - $resource = new Fractal\Resource\Item($status, new Note()); - $res = $fractal->createData($resource)->toArray(); + if($count >= 0) { + $status->reblogs_count = $count; + $status->save(); + } - return response()->json($res['data'], 200, ['Content-Type' => 'application/activity+json'], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); - } + Cache::forget('status:'.$status->id.':sharedby:userid:'.$user->id); + StatusService::del($status->id); - public function edit(Request $request, $username, $id) - { - $this->authCheck(); - $user = Auth::user()->profile; - $status = Status::whereProfileId($user->id) - ->with(['media']) - ->where('created_at', '>', now()->subHours(24)) - ->findOrFail($id); - return view('status.edit', compact('user', 'status')); - } + if ($request->ajax()) { + $response = ['code' => 200, 'msg' => 'Share saved', 'count' => $count]; + } else { + $response = redirect($status->url()); + } - public function editStore(Request $request, $username, $id) - { - $this->authCheck(); - $user = Auth::user()->profile; - $status = Status::whereProfileId($user->id) - ->with(['media']) - ->where('created_at', '>', now()->subHours(24)) - ->findOrFail($id); + return $response; + } - $this->validate($request, [ - 'id' => 'required|integer|min:1', - 'caption' => 'nullable', - 'filter' => 'nullable|alpha_dash|max:30', - ]); + public function showActivityPub(Request $request, $status) + { + $fractal = new Fractal\Manager(); + $resource = new Fractal\Resource\Item($status, new Note()); + $res = $fractal->createData($resource)->toArray(); - $id = $request->input('id'); - $caption = $request->input('caption'); - $filter = $request->input('filter'); + return response()->json($res['data'], 200, ['Content-Type' => 'application/activity+json'], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); + } - $media = Media::whereProfileId($user->id) - ->whereStatusId($status->id) - ->findOrFail($id); + public function edit(Request $request, $username, $id) + { + $this->authCheck(); + $user = Auth::user()->profile; + $status = Status::whereProfileId($user->id) + ->with(['media']) + ->findOrFail($id); + $licenses = License::get(); + return view('status.edit', compact('user', 'status', 'licenses')); + } - $changed = false; + public function editStore(Request $request, $username, $id) + { + $this->authCheck(); + $user = Auth::user()->profile; + $status = Status::whereProfileId($user->id) + ->with(['media']) + ->findOrFail($id); - if ($media->caption != $caption) { - $media->caption = $caption; - $changed = true; - } + $this->validate($request, [ + 'license' => 'nullable|integer|min:1|max:16', + ]); - if ($media->filter_class != $filter && in_array($filter, Filter::classes())) { - $media->filter_class = $filter; - $changed = true; - } + $licenseId = $request->input('license'); - if ($changed === true) { - $media->save(); - Cache::forget('status:transformer:media:attachments:'.$media->status_id); - } + $status->media->each(function($media) use($licenseId) { + $media->license = $licenseId; + $media->save(); + Cache::forget('status:transformer:media:attachments:'.$media->status_id); + }); - return response()->json([], 200); - } + return redirect($status->url()); + } - protected function authCheck() - { - if (Auth::check() == false) { - abort(403); - } - } + protected function authCheck() + { + if (Auth::check() == false) { + abort(403); + } + } - protected function validateVisibility($visibility) - { - $allowed = ['public', 'unlisted', 'private']; - return in_array($visibility, $allowed) ? $visibility : 'public'; - } + protected function validateVisibility($visibility) + { + $allowed = ['public', 'unlisted', 'private']; + return in_array($visibility, $allowed) ? $visibility : 'public'; + } - public static function mimeTypeCheck($mimes) - { - $allowed = explode(',', config('pixelfed.media_types')); - $count = count($mimes); - $photos = 0; - $videos = 0; - foreach($mimes as $mime) { - if(in_array($mime, $allowed) == false && $mime !== 'video/mp4') { - continue; - } - if(str_contains($mime, 'image/')) { - $photos++; - } - if(str_contains($mime, 'video/')) { - $videos++; - } - } - if($photos == 1 && $videos == 0) { - return 'photo'; - } - if($videos == 1 && $photos == 0) { - return 'video'; - } - if($photos > 1 && $videos == 0) { - return 'photo:album'; - } - if($videos > 1 && $photos == 0) { - return 'video:album'; - } - if($photos >= 1 && $videos >= 1) { - return 'photo:video:album'; - } - } + public static function mimeTypeCheck($mimes) + { + $allowed = explode(',', config('pixelfed.media_types')); + $count = count($mimes); + $photos = 0; + $videos = 0; + foreach($mimes as $mime) { + if(in_array($mime, $allowed) == false && $mime !== 'video/mp4') { + continue; + } + if(str_contains($mime, 'image/')) { + $photos++; + } + if(str_contains($mime, 'video/')) { + $videos++; + } + } + if($photos == 1 && $videos == 0) { + return 'photo'; + } + if($videos == 1 && $photos == 0) { + return 'video'; + } + if($photos > 1 && $videos == 0) { + return 'photo:album'; + } + if($videos > 1 && $photos == 0) { + return 'video:album'; + } + if($photos >= 1 && $videos >= 1) { + return 'photo:video:album'; + } + } - public function toggleVisibility(Request $request) { - $this->authCheck(); - $this->validate($request, [ - 'item' => 'required|string|min:1|max:20', - 'disableComments' => 'required|boolean' - ]); + public function toggleVisibility(Request $request) { + $this->authCheck(); + $this->validate($request, [ + 'item' => 'required|string|min:1|max:20', + 'disableComments' => 'required|boolean' + ]); - $user = Auth::user(); - $id = $request->input('item'); - $state = $request->input('disableComments'); + $user = Auth::user(); + $id = $request->input('item'); + $state = $request->input('disableComments'); - $status = Status::findOrFail($id); + $status = Status::findOrFail($id); - if($status->profile_id != $user->profile->id && $user->is_admin == false) { - abort(403); - } + if($status->profile_id != $user->profile->id && $user->is_admin == false) { + abort(403); + } - $status->comments_disabled = $status->comments_disabled == true ? false : true; - $status->save(); + $status->comments_disabled = $status->comments_disabled == true ? false : true; + $status->save(); - return response()->json([200]); - } + return response()->json([200]); + } - public function storeView(Request $request) - { - abort_if(!$request->user(), 403); + public function storeView(Request $request) + { + abort_if(!$request->user(), 403); - $this->validate($request, [ - 'status_id' => 'required|integer|exists:statuses,id', - 'profile_id' => 'required|integer|exists:profiles,id' - ]); + $this->validate($request, [ + 'status_id' => 'required|integer|exists:statuses,id', + 'profile_id' => 'required|integer|exists:profiles,id' + ]); - $sid = (int) $request->input('status_id'); - $pid = (int) $request->input('profile_id'); + $sid = (int) $request->input('status_id'); + $pid = (int) $request->input('profile_id'); - StatusView::firstOrCreate([ - 'status_id' => $sid, - 'status_profile_id' => $pid, - 'profile_id' => $request->user()->profile_id - ]); + StatusView::firstOrCreate([ + 'status_id' => $sid, + 'status_profile_id' => $pid, + 'profile_id' => $request->user()->profile_id + ]); - return response()->json(1); - } + return response()->json(1); + } } diff --git a/resources/views/status/edit.blade.php b/resources/views/status/edit.blade.php index 5d7203ade..fafda8072 100644 --- a/resources/views/status/edit.blade.php +++ b/resources/views/status/edit.blade.php @@ -5,99 +5,27 @@