CollectionController.php 7.9 KB

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