1
0

GroupsSearchController.php 7.2 KB

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