CollectionController.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use Auth;
  5. use App\{
  6. Collection,
  7. CollectionItem,
  8. Profile,
  9. Status
  10. };
  11. use League\Fractal;
  12. use App\Transformer\Api\{
  13. AccountTransformer,
  14. StatusTransformer,
  15. };
  16. use League\Fractal\Serializer\ArraySerializer;
  17. use League\Fractal\Pagination\IlluminatePaginatorAdapter;
  18. class CollectionController extends Controller
  19. {
  20. public function create(Request $request)
  21. {
  22. abort_if(!Auth::check(), 403);
  23. $profile = Auth::user()->profile;
  24. $collection = Collection::firstOrCreate([
  25. 'profile_id' => $profile->id,
  26. 'published_at' => null
  27. ]);
  28. return view('collection.create', compact('collection'));
  29. }
  30. public function show(Request $request, int $collection)
  31. {
  32. $collection = Collection::with('profile')->whereNotNull('published_at')->findOrFail($collection);
  33. if($collection->profile->status != null) {
  34. abort(404);
  35. }
  36. if($collection->visibility !== 'public') {
  37. abort_if(!Auth::check() || Auth::user()->profile_id != $collection->profile_id, 404);
  38. }
  39. return view('collection.show', compact('collection'));
  40. }
  41. public function index(Request $request)
  42. {
  43. abort_if(!Auth::check(), 403);
  44. return $request->all();
  45. }
  46. public function store(Request $request, $id)
  47. {
  48. abort_if(!Auth::check(), 403);
  49. $this->validate($request, [
  50. 'title' => 'nullable',
  51. 'description' => 'nullable',
  52. 'visibility' => 'nullable|string|in:public,private'
  53. ]);
  54. $profile = Auth::user()->profile;
  55. $collection = Collection::whereProfileId($profile->id)->findOrFail($id);
  56. $collection->title = e($request->input('title'));
  57. $collection->description = e($request->input('description'));
  58. $collection->visibility = e($request->input('visibility'));
  59. $collection->save();
  60. return 200;
  61. }
  62. public function publish(Request $request, int $id)
  63. {
  64. abort_if(!Auth::check(), 403);
  65. $this->validate($request, [
  66. 'title' => 'nullable',
  67. 'description' => 'nullable',
  68. 'visibility' => 'required|alpha|in:public,private'
  69. ]);
  70. $profile = Auth::user()->profile;
  71. $collection = Collection::whereProfileId($profile->id)->findOrFail($id);
  72. if($collection->items()->count() == 0) {
  73. abort(404);
  74. }
  75. $collection->title = e($request->input('title'));
  76. $collection->description = e($request->input('description'));
  77. $collection->visibility = e($request->input('visibility'));
  78. $collection->published_at = now();
  79. $collection->save();
  80. return $collection->url();
  81. }
  82. public function delete(Request $request, int $id)
  83. {
  84. abort_if(!Auth::check(), 403);
  85. $user = Auth::user();
  86. $collection = Collection::whereProfileId($user->profile_id)->findOrFail($id);
  87. $collection->items()->delete();
  88. $collection->delete();
  89. if($request->wantsJson()) {
  90. return 200;
  91. }
  92. return redirect('/');
  93. }
  94. public function storeId(Request $request)
  95. {
  96. $this->validate($request, [
  97. 'collection_id' => 'required|int|min:1|exists:collections,id',
  98. 'post_id' => 'required|int|min:1|exists:statuses,id'
  99. ]);
  100. $profileId = Auth::user()->profile_id;
  101. $collectionId = $request->input('collection_id');
  102. $postId = $request->input('post_id');
  103. $collection = Collection::whereProfileId($profileId)->findOrFail($collectionId);
  104. $count = $collection->items()->count();
  105. $max = config('pixelfed.max_collection_length');
  106. if($count >= $max) {
  107. abort(400, 'You can only add '.$max.' posts per collection');
  108. }
  109. $status = Status::whereScope('public')
  110. ->whereIn('type', ['photo', 'photo:album', 'video'])
  111. ->findOrFail($postId);
  112. $item = CollectionItem::firstOrCreate([
  113. 'collection_id' => $collection->id,
  114. 'object_type' => 'App\Status',
  115. 'object_id' => $status->id
  116. ],[
  117. 'order' => $count,
  118. ]);
  119. return 200;
  120. }
  121. public function get(Request $request, $id)
  122. {
  123. $profile = Auth::check() ? Auth::user()->profile : [];
  124. $collection = Collection::whereVisibility('public')->findOrFail($id);
  125. if($collection->published_at == null) {
  126. if(!Auth::check() || $profile->id !== $collection->profile_id) {
  127. abort(404);
  128. }
  129. }
  130. return [
  131. 'id' => $collection->id,
  132. 'title' => $collection->title,
  133. 'description' => $collection->description,
  134. 'visibility' => $collection->visibility
  135. ];
  136. }
  137. public function getItems(Request $request, int $id)
  138. {
  139. $collection = Collection::findOrFail($id);
  140. if($collection->visibility !== 'public') {
  141. abort_if(!Auth::check() || Auth::user()->profile_id != $collection->profile_id, 404);
  142. }
  143. $posts = $collection->posts()->orderBy('order', 'asc')->get();
  144. $fractal = new Fractal\Manager();
  145. $fractal->setSerializer(new ArraySerializer());
  146. $resource = new Fractal\Resource\Collection($posts, new StatusTransformer());
  147. $res = $fractal->createData($resource)->toArray();
  148. return response()->json($res);
  149. }
  150. public function getUserCollections(Request $request, int $id)
  151. {
  152. $profile = Profile::whereNull('status')
  153. ->whereNull('domain')
  154. ->findOrFail($id);
  155. if($profile->is_private) {
  156. abort_if(!Auth::check(), 404);
  157. abort_if(!$profile->followedBy(Auth::user()->profile) && $profile->id != Auth::user()->profile_id, 404);
  158. }
  159. return $profile
  160. ->collections()
  161. ->has('posts')
  162. ->with('posts')
  163. ->whereVisibility('public')
  164. ->whereNotNull('published_at')
  165. ->orderByDesc('published_at')
  166. ->paginate(9)
  167. ->map(function($collection) {
  168. return [
  169. 'id' => $collection->id,
  170. 'title' => $collection->title,
  171. 'description' => $collection->description,
  172. 'thumb' => $collection->posts()->first()->thumb(),
  173. 'url' => $collection->url(),
  174. 'published_at' => $collection->published_at
  175. ];
  176. });
  177. }
  178. public function deleteId(Request $request)
  179. {
  180. $this->validate($request, [
  181. 'collection_id' => 'required|int|min:1|exists:collections,id',
  182. 'post_id' => 'required|int|min:1|exists:statuses,id'
  183. ]);
  184. $profileId = Auth::user()->profile_id;
  185. $collectionId = $request->input('collection_id');
  186. $postId = $request->input('post_id');
  187. $collection = Collection::whereProfileId($profileId)->findOrFail($collectionId);
  188. $count = $collection->items()->count();
  189. if($count == 1) {
  190. abort(400, 'You cannot delete the only post of a collection!');
  191. }
  192. $status = Status::whereScope('public')
  193. ->whereIn('type', ['photo', 'photo:album', 'video'])
  194. ->findOrFail($postId);
  195. $item = CollectionItem::whereCollectionId($collection->id)
  196. ->whereObjectType('App\Status')
  197. ->whereObjectId($status->id)
  198. ->firstOrFail();
  199. $item->delete();
  200. return 200;
  201. }
  202. }