GroupsSearchController.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. namespace App\Http\Controllers\Groups;
  3. use Illuminate\Support\Facades\Cache;
  4. use Illuminate\Support\Facades\RateLimiter;
  5. use App\Http\Controllers\Controller;
  6. use Illuminate\Http\Request;
  7. use App\Services\AccountService;
  8. use App\Services\GroupService;
  9. use App\Follower;
  10. use App\Profile;
  11. use App\Models\Group;
  12. use App\Models\GroupMember;
  13. use App\Models\GroupInvitation;
  14. class GroupsSearchController extends Controller
  15. {
  16. public function __construct()
  17. {
  18. $this->middleware('auth');
  19. }
  20. public function inviteFriendsToGroup(Request $request)
  21. {
  22. abort_if(!$request->user(), 404);
  23. $this->validate($request, [
  24. 'uids' => 'required',
  25. 'g' => 'required',
  26. ]);
  27. $uid = $request->input('uids');
  28. $gid = $request->input('g');
  29. $pid = $request->user()->profile_id;
  30. $group = Group::findOrFail($gid);
  31. abort_if(!$group->isMember($pid), 404);
  32. abort_if(
  33. GroupInvitation::whereGroupId($group->id)
  34. ->whereFromProfileId($pid)
  35. ->count() >= 20,
  36. 422,
  37. 'Invite limit reached'
  38. );
  39. $profiles = collect($uid)
  40. ->map(function($u) {
  41. return Profile::find($u);
  42. })
  43. ->filter(function($u) use($pid) {
  44. return $u &&
  45. $u->id != $pid &&
  46. isset($u->id) &&
  47. Follower::whereFollowingId($pid)
  48. ->whereProfileId($u->id)
  49. ->exists();
  50. })
  51. ->filter(function($u) use($group, $pid) {
  52. return GroupInvitation::whereGroupId($group->id)
  53. ->whereFromProfileId($pid)
  54. ->whereToProfileId($u->id)
  55. ->exists() == false;
  56. })
  57. ->each(function($u) use($gid, $pid) {
  58. $gi = new GroupInvitation;
  59. $gi->group_id = $gid;
  60. $gi->from_profile_id = $pid;
  61. $gi->to_profile_id = $u->id;
  62. $gi->to_local = true;
  63. $gi->from_local = $u->domain == null;
  64. $gi->save();
  65. // GroupMemberInvite::dispatch($gi);
  66. });
  67. return [200];
  68. }
  69. public function searchFriendsToInvite(Request $request)
  70. {
  71. abort_if(!$request->user(), 404);
  72. $this->validate($request, [
  73. 'q' => 'required|min:2|max:40',
  74. 'g' => 'required',
  75. 'v' => 'required|in:0.2'
  76. ]);
  77. $q = $request->input('q');
  78. $gid = $request->input('g');
  79. $pid = $request->user()->profile_id;
  80. $group = Group::findOrFail($gid);
  81. abort_if(!$group->isMember($pid), 404);
  82. $res = Profile::where('username', 'like', "%{$q}%")
  83. ->whereNull('profiles.domain')
  84. ->join('followers', 'profiles.id', '=', 'followers.profile_id')
  85. ->where('followers.following_id', $pid)
  86. ->take(10)
  87. ->get()
  88. ->filter(function($p) use($group) {
  89. return $group->isMember($p->profile_id) == false;
  90. })
  91. ->filter(function($p) use($group, $pid) {
  92. return GroupInvitation::whereGroupId($group->id)
  93. ->whereFromProfileId($pid)
  94. ->whereToProfileId($p->profile_id)
  95. ->exists() == false;
  96. })
  97. ->map(function($gm) use ($gid) {
  98. $a = AccountService::get($gm->profile_id);
  99. return [
  100. 'id' => (string) $gm->profile_id,
  101. 'username' => $a['acct'],
  102. 'url' => url("/groups/{$gid}/user/{$a['id']}?rf=group_search")
  103. ];
  104. })
  105. ->values();
  106. return $res;
  107. }
  108. public function searchGlobalResults(Request $request)
  109. {
  110. abort_if(!$request->user(), 404);
  111. $this->validate($request, [
  112. 'q' => 'required|min:2|max:40',
  113. 'v' => 'required|in:0.2'
  114. ]);
  115. $q = $request->input('q');
  116. $key = 'groups:search:global:by_name:' . hash('sha256', $q);
  117. if(RateLimiter::tooManyAttempts('groups:search:global:'.$request->user()->id, 25) ) {
  118. return response()->json([
  119. 'error' => [
  120. 'message' => 'Too many attempts, please try again later'
  121. ]
  122. ], 422);
  123. }
  124. RateLimiter::hit('groups:search:global:'.$request->user()->id);
  125. return Cache::remember($key, 3600, function() use($q) {
  126. return Group::whereNull('status')
  127. ->where('name', 'like', '%' . $q . '%')
  128. ->orderBy('id')
  129. ->take(10)
  130. ->pluck('id')
  131. ->map(function($group) {
  132. return GroupService::get($group);
  133. });
  134. });
  135. }
  136. public function searchLocalAutocomplete(Request $request)
  137. {
  138. abort_if(!$request->user(), 404);
  139. $this->validate($request, [
  140. 'q' => 'required|min:2|max:40',
  141. 'g' => 'required',
  142. 'v' => 'required|in:0.2'
  143. ]);
  144. $q = $request->input('q');
  145. $gid = $request->input('g');
  146. $pid = $request->user()->profile_id;
  147. $group = Group::findOrFail($gid);
  148. abort_if(!$group->isMember($pid), 404);
  149. $res = GroupMember::whereGroupId($gid)
  150. ->join('profiles', 'group_members.profile_id', '=', 'profiles.id')
  151. ->where('profiles.username', 'like', "%{$q}%")
  152. ->take(10)
  153. ->get()
  154. ->map(function($gm) use ($gid) {
  155. $a = AccountService::get($gm->profile_id);
  156. return [
  157. 'username' => $a['username'],
  158. 'url' => url("/groups/{$gid}/user/{$a['id']}?rf=group_search")
  159. ];
  160. });
  161. return $res;
  162. }
  163. public function searchAddRecent(Request $request)
  164. {
  165. $this->validate($request, [
  166. 'q' => 'required|min:2|max:40',
  167. 'g' => 'required',
  168. ]);
  169. $q = $request->input('q');
  170. $gid = $request->input('g');
  171. $pid = $request->user()->profile_id;
  172. $group = Group::findOrFail($gid);
  173. abort_if(!$group->isMember($pid), 404);
  174. $key = 'groups:search:recent:'.$gid.':pid:'.$pid;
  175. $ttl = now()->addDays(14);
  176. $res = Cache::get($key);
  177. if(!$res) {
  178. $val = json_encode([$q]);
  179. } else {
  180. $ex = collect(json_decode($res))
  181. ->prepend($q)
  182. ->unique('value')
  183. ->slice(0, 3)
  184. ->values()
  185. ->all();
  186. $val = json_encode($ex);
  187. }
  188. Cache::put($key, $val, $ttl);
  189. return 200;
  190. }
  191. public function searchGetRecent(Request $request)
  192. {
  193. $gid = $request->input('g');
  194. $pid = $request->user()->profile_id;
  195. $group = Group::findOrFail($gid);
  196. abort_if(!$group->isMember($pid), 404);
  197. $key = 'groups:search:recent:'.$gid.':pid:'.$pid;
  198. return Cache::get($key);
  199. }
  200. }