InternalApiController.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. namespace App\Http\Controllers;
  3. use Illuminate\Http\Request;
  4. use App\{
  5. Hashtag,
  6. Like,
  7. Media,
  8. Notification,
  9. Profile,
  10. StatusHashtag,
  11. Status,
  12. };
  13. use Auth,Cache;
  14. use Carbon\Carbon;
  15. use League\Fractal;
  16. use App\Transformer\Api\{
  17. AccountTransformer,
  18. StatusTransformer,
  19. };
  20. use App\Jobs\StatusPipeline\NewStatusPipeline;
  21. use League\Fractal\Serializer\ArraySerializer;
  22. use League\Fractal\Pagination\IlluminatePaginatorAdapter;
  23. class InternalApiController extends Controller
  24. {
  25. protected $fractal;
  26. public function __construct()
  27. {
  28. $this->middleware('auth');
  29. $this->fractal = new Fractal\Manager();
  30. $this->fractal->setSerializer(new ArraySerializer());
  31. }
  32. public function compose(Request $request)
  33. {
  34. $this->validate($request, [
  35. 'caption' => 'nullable|string',
  36. 'media.*' => 'required',
  37. 'media.*.id' => 'required|integer|min:1',
  38. 'media.*.filter' => 'nullable|string|max:30',
  39. 'media.*.license' => 'nullable|string|max:80',
  40. 'visibility' => 'required|string|in:public,private|min:2|max:10'
  41. ]);
  42. $profile = Auth::user()->profile;
  43. $visibility = $request->input('visibility');
  44. $medias = $request->input('media');
  45. $attachments = [];
  46. $status = new Status;
  47. foreach($medias as $k => $media) {
  48. $m = Media::findOrFail($media['id']);
  49. if($m->profile_id !== $profile->id || $m->status_id) {
  50. abort(403, 'Invalid media id');
  51. }
  52. $m->filter_class = $media['filter'];
  53. $m->license = $media['license'];
  54. $m->caption = strip_tags($media['alt']);
  55. $m->order = isset($media['cursor']) && is_int($media['cursor']) ? (int) $media['cursor'] : $k;
  56. if($media['cw'] == true) {
  57. $m->is_nsfw = true;
  58. $status->is_nsfw = true;
  59. }
  60. $m->save();
  61. $attachments[] = $m;
  62. }
  63. $status->caption = strip_tags($request->caption);
  64. $status->visibility = 'draft';
  65. $status->scope = 'draft';
  66. $status->profile_id = $profile->id;
  67. $status->save();
  68. foreach($attachments as $media) {
  69. $media->status_id = $status->id;
  70. $media->save();
  71. }
  72. $status->visibility = $visibility;
  73. $status->scope = $visibility;
  74. $status->save();
  75. NewStatusPipeline::dispatch($status);
  76. return $status->url();
  77. }
  78. public function notifications(Request $request)
  79. {
  80. $this->validate($request, [
  81. 'page' => 'nullable|min:1|max:3',
  82. ]);
  83. $profile = Auth::user()->profile;
  84. $timeago = Carbon::now()->subMonths(6);
  85. $notifications = Notification::with('actor')
  86. ->whereProfileId($profile->id)
  87. ->whereDate('created_at', '>', $timeago)
  88. ->orderBy('id', 'desc')
  89. ->simplePaginate(30);
  90. $notifications = $notifications->map(function($k, $v) {
  91. return [
  92. 'id' => $k->id,
  93. 'action' => $k->action,
  94. 'message' => $k->message,
  95. 'rendered' => $k->rendered,
  96. 'actor' => [
  97. 'avatar' => $k->actor->avatarUrl(),
  98. 'username' => $k->actor->username,
  99. 'url' => $k->actor->url(),
  100. ],
  101. 'url' => $k->item->url()
  102. ];
  103. });
  104. return response()->json($notifications, 200, [], JSON_PRETTY_PRINT);
  105. }
  106. public function discover(Request $request)
  107. {
  108. $profile = Auth::user()->profile;
  109. $following = Cache::get('feature:discover:following:'.$profile->id, []);
  110. $people = Profile::select('id', 'name', 'username')
  111. ->with('avatar')
  112. ->inRandomOrder()
  113. ->whereHas('statuses')
  114. ->whereNull('domain')
  115. ->whereNotIn('id', $following)
  116. ->whereIsPrivate(false)
  117. ->take(3)
  118. ->get();
  119. $posts = Status::select('id', 'caption', 'profile_id')
  120. ->whereHas('media')
  121. ->whereHas('profile', function($q) {
  122. $q->where('is_private', false);
  123. })
  124. ->whereIsNsfw(false)
  125. ->whereVisibility('public')
  126. ->where('profile_id', '<>', $profile->id)
  127. ->whereNotIn('profile_id', $following)
  128. ->withCount(['comments', 'likes'])
  129. ->orderBy('created_at', 'desc')
  130. ->take(21)
  131. ->get();
  132. $res = [
  133. 'people' => $people->map(function($profile) {
  134. return [
  135. 'avatar' => $profile->avatarUrl(),
  136. 'name' => $profile->name,
  137. 'username' => $profile->username,
  138. 'url' => $profile->url(),
  139. ];
  140. }),
  141. 'posts' => $posts->map(function($post) {
  142. return [
  143. 'url' => $post->url(),
  144. 'thumb' => $post->thumb(),
  145. 'comments_count' => $post->comments_count,
  146. 'likes_count' => $post->likes_count,
  147. ];
  148. })
  149. ];
  150. return response()->json($res, 200, [], JSON_PRETTY_PRINT);
  151. }
  152. }