PublicApiController.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use App\{
  5. Hashtag,
  6. Follower,
  7. Like,
  8. Media,
  9. Notification,
  10. Profile,
  11. StatusHashtag,
  12. Status,
  13. };
  14. use Auth,Cache;
  15. use Carbon\Carbon;
  16. use League\Fractal;
  17. use App\Transformer\Api\{
  18. AccountTransformer,
  19. StatusTransformer,
  20. };
  21. use App\Jobs\StatusPipeline\NewStatusPipeline;
  22. use League\Fractal\Serializer\ArraySerializer;
  23. use League\Fractal\Pagination\IlluminatePaginatorAdapter;
  24. class PublicApiController extends Controller
  25. {
  26. protected $fractal;
  27. public function __construct()
  28. {
  29. $this->middleware('throttle:3000, 30');
  30. $this->fractal = new Fractal\Manager();
  31. $this->fractal->setSerializer(new ArraySerializer());
  32. }
  33. protected function getUserData()
  34. {
  35. if(false == Auth::check()) {
  36. return [];
  37. } else {
  38. $profile = Auth::user()->profile;
  39. $user = new Fractal\Resource\Item($profile, new AccountTransformer());
  40. return $this->fractal->createData($user)->toArray();
  41. }
  42. }
  43. protected function getLikes($status)
  44. {
  45. if(false == Auth::check()) {
  46. return [];
  47. } else {
  48. $profile = Auth::user()->profile;
  49. $likes = $status->likedBy()->orderBy('created_at','desc')->paginate(10);
  50. $collection = new Fractal\Resource\Collection($likes, new AccountTransformer());
  51. return $this->fractal->createData($collection)->toArray();
  52. }
  53. }
  54. protected function getShares($status)
  55. {
  56. if(false == Auth::check()) {
  57. return [];
  58. } else {
  59. $profile = Auth::user()->profile;
  60. $shares = $status->sharedBy()->orderBy('created_at','desc')->paginate(10);
  61. $collection = new Fractal\Resource\Collection($shares, new AccountTransformer());
  62. return $this->fractal->createData($collection)->toArray();
  63. }
  64. }
  65. public function status(Request $request, $username, int $postid)
  66. {
  67. $profile = Profile::whereUsername($username)->first();
  68. $status = Status::whereProfileId($profile->id)->find($postid);
  69. $this->scopeCheck($profile, $status);
  70. $item = new Fractal\Resource\Item($status, new StatusTransformer());
  71. $res = [
  72. 'status' => $this->fractal->createData($item)->toArray(),
  73. 'user' => $this->getUserData(),
  74. 'likes' => $this->getLikes($status),
  75. 'shares' => $this->getShares($status),
  76. 'reactions' => [
  77. 'liked' => $status->liked(),
  78. 'shared' => $status->shared(),
  79. 'bookmarked' => $status->bookmarked(),
  80. ],
  81. ];
  82. return response()->json($res, 200, [], JSON_PRETTY_PRINT);
  83. }
  84. public function statusComments(Request $request, $username, int $postId)
  85. {
  86. $this->validate($request, [
  87. 'min_id' => 'nullable|integer|min:1',
  88. 'max_id' => 'nullable|integer|min:1|max:'.PHP_INT_MAX,
  89. 'limit' => 'nullable|integer|min:5|max:50'
  90. ]);
  91. $limit = $request->limit ?? 10;
  92. $profile = Profile::whereUsername($username)->first();
  93. $status = Status::whereProfileId($profile->id)->find($postId);
  94. $this->scopeCheck($profile, $status);
  95. if($request->filled('min_id') || $request->filled('max_id')) {
  96. if($request->filled('min_id')) {
  97. $replies = $status->comments()
  98. ->select('id', 'caption', 'rendered', 'profile_id', 'in_reply_to_id', 'created_at')
  99. ->where('id', '>=', $request->min_id)
  100. ->orderBy('id', 'desc')
  101. ->paginate($limit);
  102. }
  103. if($request->filled('max_id')) {
  104. $replies = $status->comments()
  105. ->select('id', 'caption', 'rendered', 'profile_id', 'in_reply_to_id', 'created_at')
  106. ->where('id', '<=', $request->max_id)
  107. ->orderBy('id', 'desc')
  108. ->paginate($limit);
  109. }
  110. } else {
  111. $replies = $status->comments()
  112. ->select('id', 'caption', 'rendered', 'profile_id', 'in_reply_to_id', 'created_at')
  113. ->orderBy('id', 'desc')
  114. ->paginate($limit);
  115. }
  116. $resource = new Fractal\Resource\Collection($replies, new StatusTransformer(), 'data');
  117. $resource->setPaginator(new IlluminatePaginatorAdapter($replies));
  118. $res = $this->fractal->createData($resource)->toArray();
  119. return response()->json($res, 200, [], JSON_PRETTY_PRINT);
  120. }
  121. public function statusLikes(Request $request, $username, $id)
  122. {
  123. $profile = Profile::whereUsername($username)->first();
  124. $status = Status::whereProfileId($profile->id)->find($id);
  125. $this->scopeCheck($profile, $status);
  126. $likes = $this->getLikes($status);
  127. return response()->json([
  128. 'data' => $likes
  129. ]);
  130. }
  131. public function statusShares(Request $request, $username, $id)
  132. {
  133. $profile = Profile::whereUsername($username)->first();
  134. $status = Status::whereProfileId($profile->id)->find($id);
  135. $this->scopeCheck($profile, $status);
  136. $shares = $this->getShares($status);
  137. return response()->json([
  138. 'data' => $shares
  139. ]);
  140. }
  141. protected function scopeCheck(Profile $profile, Status $status)
  142. {
  143. if($profile->is_private == true && Auth::check() == false) {
  144. abort(404);
  145. }
  146. switch ($status->scope) {
  147. case 'public':
  148. case 'unlisted':
  149. case 'private':
  150. $user = Auth::check() ? Auth::user() : false;
  151. if($user && $profile->is_private) {
  152. $follows = Follower::whereProfileId($user->profile->id)
  153. ->whereFollowingId($profile->id)
  154. ->exists();
  155. if($follows == false && $profile->id !== $user->profile->id) {
  156. abort(404);
  157. }
  158. }
  159. break;
  160. case 'direct':
  161. abort(404);
  162. break;
  163. case 'draft':
  164. abort(404);
  165. break;
  166. default:
  167. abort(404);
  168. break;
  169. }
  170. }
  171. }