diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ed6e8cbd..11033743a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Update AdminCuratedRegisterController, fix existing account approval ([cbb96cfd](https://github.com/pixelfed/pixelfed/commit/cbb96cfd)) - Update ActivityPubFetchService, fix Friendica bug ([e4edc6f1](https://github.com/pixelfed/pixelfed/commit/e4edc6f1)) - Update ProfileController, fix atom feed cache ttl. Fixes #5093 ([921e2965](https://github.com/pixelfed/pixelfed/commit/921e2965)) +- Update CollectionsController, add new self route ([bc2495c6](https://github.com/pixelfed/pixelfed/commit/bc2495c6)) - ([](https://github.com/pixelfed/pixelfed/commit/)) ## [v0.12.1 (2024-05-07)](https://github.com/pixelfed/pixelfed/compare/v0.12.0...v0.12.1) diff --git a/app/Http/Controllers/CollectionController.php b/app/Http/Controllers/CollectionController.php index 85f3f30cf..447490433 100644 --- a/app/Http/Controllers/CollectionController.php +++ b/app/Http/Controllers/CollectionController.php @@ -2,72 +2,65 @@ namespace App\Http\Controllers; -use Illuminate\Http\Request; -use Auth; -use App\{ - Collection, - CollectionItem, - Profile, - Status -}; -use League\Fractal; -use App\Transformer\Api\{ - AccountTransformer, - StatusTransformer, -}; -use League\Fractal\Serializer\ArraySerializer; -use League\Fractal\Pagination\IlluminatePaginatorAdapter; +use App\Collection; +use App\CollectionItem; use App\Services\AccountService; use App\Services\CollectionService; use App\Services\FollowerService; use App\Services\StatusService; +use App\Status; +use Auth; +use Illuminate\Http\Request; class CollectionController extends Controller { public function create(Request $request) { - abort_if(!Auth::check(), 403); + abort_if(! Auth::check(), 403); $profile = Auth::user()->profile; $collection = Collection::firstOrCreate([ 'profile_id' => $profile->id, - 'published_at' => null + 'published_at' => null, ]); $collection->visibility = 'draft'; $collection->save(); + return view('collection.create', compact('collection')); } public function show(Request $request, int $id) { $user = $request->user(); - $collection = CollectionService::getCollection($id); - abort_if(!$collection, 404); - if($collection['published_at'] == null || $collection['visibility'] != 'public') { - abort_if(!$user, 404); - if($user->profile_id != $collection['pid']) { - if(!$user->is_admin) { - abort_if($collection['visibility'] != 'private', 404); - abort_if(!FollowerService::follows($user->profile_id, $collection['pid']), 404); - } - } - } - return view('collection.show', compact('collection')); + $collection = CollectionService::getCollection($id); + abort_if(! $collection, 404); + if ($collection['published_at'] == null || $collection['visibility'] != 'public') { + abort_if(! $user, 404); + if ($user->profile_id != $collection['pid']) { + if (! $user->is_admin) { + abort_if($collection['visibility'] != 'private', 404); + abort_if(! FollowerService::follows($user->profile_id, $collection['pid']), 404); + } + } + } + + return view('collection.show', compact('collection')); } public function index(Request $request) { - abort_if(!Auth::check(), 403); - return $request->all(); + abort_if(! Auth::check(), 403); + + return $request->all(); } public function store(Request $request, $id) { - abort_if(!$request->user(), 403); + abort_if(! $request->user(), 403); $this->validate($request, [ - 'title' => 'nullable|max:50', - 'description' => 'nullable|max:500', - 'visibility' => 'nullable|string|in:public,private,draft' + 'title' => 'nullable|max:50', + 'description' => 'nullable|max:500', + 'visibility' => 'nullable|string|in:public,private,draft', ]); $pid = $request->user()->profile_id; @@ -78,20 +71,21 @@ class CollectionController extends Controller $collection->save(); CollectionService::deleteCollection($id); + return CollectionService::setCollection($collection->id, $collection); } public function publish(Request $request, int $id) { - abort_if(!$request->user(), 403); + abort_if(! $request->user(), 403); $this->validate($request, [ - 'title' => 'nullable|max:50', - 'description' => 'nullable|max:500', - 'visibility' => 'required|alpha|in:public,private,draft' + 'title' => 'nullable|max:50', + 'description' => 'nullable|max:500', + 'visibility' => 'required|alpha|in:public,private,draft', ]); - $profile = Auth::user()->profile; + $profile = Auth::user()->profile; $collection = Collection::whereProfileId($profile->id)->findOrFail($id); - if($collection->items()->count() == 0) { + if ($collection->items()->count() == 0) { abort(404); } $collection->title = strip_tags($request->input('title')); @@ -99,12 +93,13 @@ class CollectionController extends Controller $collection->visibility = $request->input('visibility'); $collection->published_at = now(); $collection->save(); + return CollectionService::setCollection($collection->id, $collection); } public function delete(Request $request, int $id) { - abort_if(!$request->user(), 403); + abort_if(! $request->user(), 403); $user = $request->user(); $collection = Collection::whereProfileId($user->profile_id)->findOrFail($id); @@ -113,7 +108,7 @@ class CollectionController extends Controller CollectionService::deleteCollection($id); - if($request->wantsJson()) { + if ($request->wantsJson()) { return 200; } @@ -122,13 +117,13 @@ class CollectionController extends Controller public function storeId(Request $request) { - abort_if(!$request->user(), 403); + abort_if(! $request->user(), 403); $this->validate($request, [ 'collection_id' => 'required|int|min:1|exists:collections,id', - 'post_id' => 'required|int|min:1' + 'post_id' => 'required|int|min:1', ]); - + $profileId = $request->user()->profile_id; $collectionId = $request->input('collection_id'); $postId = $request->input('post_id'); @@ -136,20 +131,20 @@ class CollectionController extends Controller $collection = Collection::whereProfileId($profileId)->findOrFail($collectionId); $count = $collection->items()->count(); - if($count) { + if ($count) { CollectionItem::whereCollectionId($collection->id) ->get() - ->filter(function($col) { + ->filter(function ($col) { return StatusService::get($col->object_id, false) == null; }) - ->each(function($col) use($collectionId) { + ->each(function ($col) use ($collectionId) { CollectionService::removeItem($collectionId, $col->object_id); $col->delete(); }); } $max = config('pixelfed.max_collection_length'); - if($count >= $max) { + if ($count >= $max) { abort(400, 'You can only add '.$max.' posts per collection'); } @@ -160,10 +155,10 @@ class CollectionController extends Controller $item = CollectionItem::firstOrCreate([ 'collection_id' => $collection->id, - 'object_type' => 'App\Status', - 'object_id' => $status->id - ],[ - 'order' => $count, + 'object_type' => 'App\Status', + 'object_id' => $status->id, + ], [ + 'order' => $count, ]); CollectionService::deleteCollection($collection->id); @@ -177,112 +172,112 @@ class CollectionController extends Controller public function getCollection(Request $request, $id) { - $user = $request->user(); - $collection = CollectionService::getCollection($id); + $user = $request->user(); + $collection = CollectionService::getCollection($id); - if(!$collection) { + if (! $collection) { return response()->json([], 404); } - if($collection['published_at'] == null || $collection['visibility'] != 'public') { - abort_unless($user, 404); - if($user->profile_id != $collection['pid']) { - if(!$user->is_admin) { - abort_if($collection['visibility'] != 'private', 404); - abort_if(!FollowerService::follows($user->profile_id, $collection['pid']), 404); - } - } - } + if ($collection['published_at'] == null || $collection['visibility'] != 'public') { + abort_unless($user, 404); + if ($user->profile_id != $collection['pid']) { + if (! $user->is_admin) { + abort_if($collection['visibility'] != 'private', 404); + abort_if(! FollowerService::follows($user->profile_id, $collection['pid']), 404); + } + } + } return $collection; } public function getItems(Request $request, int $id) { - $user = $request->user(); - $collection = CollectionService::getCollection($id); + $user = $request->user(); + $collection = CollectionService::getCollection($id); - if(!$collection) { + if (! $collection) { return response()->json([], 404); } - if($collection['published_at'] == null || $collection['visibility'] != 'public') { - abort_unless($user, 404); - if($user->profile_id != $collection['pid']) { - if(!$user->is_admin) { - abort_if($collection['visibility'] != 'private', 404); - abort_if(!FollowerService::follows($user->profile_id, $collection['pid']), 404); - } - } - } + if ($collection['published_at'] == null || $collection['visibility'] != 'public') { + abort_unless($user, 404); + if ($user->profile_id != $collection['pid']) { + if (! $user->is_admin) { + abort_if($collection['visibility'] != 'private', 404); + abort_if(! FollowerService::follows($user->profile_id, $collection['pid']), 404); + } + } + } $page = $request->input('page') ?? 1; $start = $page == 1 ? 0 : ($page * 10 - 10); $end = $start + 10; $items = CollectionService::getItems($id, $start, $end); return collect($items) - ->map(function($id) { + ->map(function ($id) { return StatusService::get($id, false); - }) - ->filter(function($item) { - return $item && ($item['visibility'] == 'public' || $item['visibility'] == 'unlisted') && isset($item['account'], $item['media_attachments']); - }) - ->values(); + }) + ->filter(function ($item) { + return $item && ($item['visibility'] == 'public' || $item['visibility'] == 'unlisted') && isset($item['account'], $item['media_attachments']); + }) + ->values(); } public function getUserCollections(Request $request, int $id) { - $user = $request->user(); - $pid = $user ? $user->profile_id : null; - $follows = false; - $visibility = ['public']; + $user = $request->user(); + $pid = $user ? $user->profile_id : null; + $follows = false; + $visibility = ['public']; $profile = AccountService::get($id, true); - if(!$profile || !isset($profile['id'])) { + if (! $profile || ! isset($profile['id'])) { return response()->json([], 404); } - if($pid) { - $follows = FollowerService::follows($pid, $profile['id']); + if ($pid) { + $follows = FollowerService::follows($pid, $profile['id']); } - if($profile['locked']) { - abort_if(!$pid, 404); - if(!$user->is_admin) { - abort_if($profile['id'] != $pid && $follows == false, 404); + if ($profile['locked']) { + abort_if(! $pid, 404); + if (! $user->is_admin) { + abort_if($profile['id'] != $pid && $follows == false, 404); } } $owner = $pid ? $pid == $profile['id'] : false; - if($follows) { - $visibility = ['public', 'private']; + if ($follows) { + $visibility = ['public', 'private']; } - if($pid && $pid == $profile['id']) { - $visibility = ['public', 'private', 'draft']; + if ($pid && $pid == $profile['id']) { + $visibility = ['public', 'private', 'draft']; } return Collection::whereProfileId($profile['id']) - ->whereIn('visibility', $visibility) - ->when(!$owner, function($q, $owner) { - return $q->whereNotNull('published_at'); - }) + ->whereIn('visibility', $visibility) + ->when(! $owner, function ($q, $owner) { + return $q->whereNotNull('published_at'); + }) ->orderByDesc('id') ->paginate(9) - ->map(function($collection) { - return CollectionService::getCollection($collection->id); - }); + ->map(function ($collection) { + return CollectionService::getCollection($collection->id); + }); } public function deleteId(Request $request) { - abort_if(!$request->user(), 403); + abort_if(! $request->user(), 403); $this->validate($request, [ 'collection_id' => 'required|int|min:1|exists:collections,id', - 'post_id' => 'required|int|min:1' + 'post_id' => 'required|int|min:1', ]); - + $profileId = $request->user()->profile_id; $collectionId = $request->input('collection_id'); $postId = $request->input('post_id'); @@ -290,7 +285,7 @@ class CollectionController extends Controller $collection = Collection::whereProfileId($profileId)->findOrFail($collectionId); $count = $collection->items()->count(); - if($count == 1) { + if ($count == 1) { abort(400, 'You cannot delete the only post of a collection!'); } @@ -308,7 +303,7 @@ class CollectionController extends Controller CollectionItem::whereCollectionId($collection->id) ->orderBy('created_at') ->get() - ->each(function($item, $index) { + ->each(function ($item, $index) { $item->order = $index; $item->save(); }); @@ -319,4 +314,31 @@ class CollectionController extends Controller return 200; } + + public function getSelfCollections(Request $request) + { + abort_if(! $request->user(), 404); + $user = $request->user(); + $pid = $user->profile_id; + + $profile = AccountService::get($pid, true); + if (! $profile || ! isset($profile['id'])) { + return response()->json([], 404); + } + + return Collection::whereProfileId($pid) + ->orderByDesc('id') + ->paginate(9) + ->map(function ($collection) { + $c = CollectionService::getCollection($collection->id); + $c['items'] = collect(CollectionService::getItems($collection->id)) + ->map(function ($id) { + return StatusService::get($id, false); + })->filter()->values(); + + return $c; + }) + ->filter() + ->values(); + } } diff --git a/routes/api.php b/routes/api.php index af40e27bc..d2e581a37 100644 --- a/routes/api.php +++ b/routes/api.php @@ -133,6 +133,7 @@ Route::group(['prefix' => 'api'], function() use($middleware) { Route::post('update/{id}', 'CollectionController@store')->middleware($middleware); Route::delete('delete/{id}', 'CollectionController@delete')->middleware($middleware); Route::post('remove', 'CollectionController@deleteId')->middleware($middleware); + Route::get('self', 'CollectionController@getSelfCollections')->middleware($middleware); }); Route::group(['prefix' => 'direct'], function () use($middleware) { @@ -264,6 +265,7 @@ Route::group(['prefix' => 'api'], function() use($middleware) { Route::post('update/{id}', 'CollectionController@store')->middleware($middleware); Route::delete('delete/{id}', 'CollectionController@delete')->middleware($middleware); Route::post('remove', 'CollectionController@deleteId')->middleware($middleware); + Route::get('self', 'CollectionController@getSelfCollections')->middleware($middleware); }); Route::group(['prefix' => 'compose'], function () use($middleware) {