2024-07-10 05:16:05 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Http\Controllers\Groups;
|
|
|
|
|
|
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
use Illuminate\Support\Facades\RateLimiter;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
use App\Services\AccountService;
|
|
|
|
use App\Services\GroupService;
|
|
|
|
use App\Follower;
|
|
|
|
use App\Profile;
|
|
|
|
use App\Models\Group;
|
|
|
|
use App\Models\GroupMember;
|
|
|
|
use App\Models\GroupInvitation;
|
2024-07-23 07:29:56 +00:00
|
|
|
use App\Util\ActivityPub\Helpers;
|
|
|
|
use App\Services\Groups\GroupActivityPubService;
|
2024-07-10 05:16:05 +00:00
|
|
|
|
|
|
|
class GroupsSearchController extends Controller
|
|
|
|
{
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
$this->middleware('auth');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function inviteFriendsToGroup(Request $request)
|
|
|
|
{
|
|
|
|
abort_if(!$request->user(), 404);
|
|
|
|
$this->validate($request, [
|
|
|
|
'uids' => 'required',
|
|
|
|
'g' => 'required',
|
|
|
|
]);
|
|
|
|
$uid = $request->input('uids');
|
|
|
|
$gid = $request->input('g');
|
|
|
|
$pid = $request->user()->profile_id;
|
|
|
|
$group = Group::findOrFail($gid);
|
|
|
|
abort_if(!$group->isMember($pid), 404);
|
|
|
|
abort_if(
|
|
|
|
GroupInvitation::whereGroupId($group->id)
|
|
|
|
->whereFromProfileId($pid)
|
|
|
|
->count() >= 20,
|
|
|
|
422,
|
|
|
|
'Invite limit reached'
|
|
|
|
);
|
|
|
|
|
|
|
|
$profiles = collect($uid)
|
|
|
|
->map(function($u) {
|
|
|
|
return Profile::find($u);
|
|
|
|
})
|
|
|
|
->filter(function($u) use($pid) {
|
|
|
|
return $u &&
|
|
|
|
$u->id != $pid &&
|
|
|
|
isset($u->id) &&
|
|
|
|
Follower::whereFollowingId($pid)
|
|
|
|
->whereProfileId($u->id)
|
|
|
|
->exists();
|
|
|
|
})
|
|
|
|
->filter(function($u) use($group, $pid) {
|
|
|
|
return GroupInvitation::whereGroupId($group->id)
|
|
|
|
->whereFromProfileId($pid)
|
|
|
|
->whereToProfileId($u->id)
|
|
|
|
->exists() == false;
|
|
|
|
})
|
|
|
|
->each(function($u) use($gid, $pid) {
|
|
|
|
$gi = new GroupInvitation;
|
|
|
|
$gi->group_id = $gid;
|
|
|
|
$gi->from_profile_id = $pid;
|
|
|
|
$gi->to_profile_id = $u->id;
|
|
|
|
$gi->to_local = true;
|
|
|
|
$gi->from_local = $u->domain == null;
|
|
|
|
$gi->save();
|
|
|
|
// GroupMemberInvite::dispatch($gi);
|
|
|
|
});
|
|
|
|
return [200];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function searchFriendsToInvite(Request $request)
|
|
|
|
{
|
|
|
|
abort_if(!$request->user(), 404);
|
|
|
|
$this->validate($request, [
|
|
|
|
'q' => 'required|min:2|max:40',
|
|
|
|
'g' => 'required',
|
|
|
|
'v' => 'required|in:0.2'
|
|
|
|
]);
|
|
|
|
$q = $request->input('q');
|
|
|
|
$gid = $request->input('g');
|
|
|
|
$pid = $request->user()->profile_id;
|
|
|
|
$group = Group::findOrFail($gid);
|
|
|
|
abort_if(!$group->isMember($pid), 404);
|
|
|
|
|
|
|
|
$res = Profile::where('username', 'like', "%{$q}%")
|
|
|
|
->whereNull('profiles.domain')
|
|
|
|
->join('followers', 'profiles.id', '=', 'followers.profile_id')
|
|
|
|
->where('followers.following_id', $pid)
|
|
|
|
->take(10)
|
|
|
|
->get()
|
|
|
|
->filter(function($p) use($group) {
|
|
|
|
return $group->isMember($p->profile_id) == false;
|
|
|
|
})
|
|
|
|
->filter(function($p) use($group, $pid) {
|
|
|
|
return GroupInvitation::whereGroupId($group->id)
|
|
|
|
->whereFromProfileId($pid)
|
|
|
|
->whereToProfileId($p->profile_id)
|
|
|
|
->exists() == false;
|
|
|
|
})
|
|
|
|
->map(function($gm) use ($gid) {
|
|
|
|
$a = AccountService::get($gm->profile_id);
|
|
|
|
return [
|
|
|
|
'id' => (string) $gm->profile_id,
|
|
|
|
'username' => $a['acct'],
|
|
|
|
'url' => url("/groups/{$gid}/user/{$a['id']}?rf=group_search")
|
|
|
|
];
|
|
|
|
})
|
|
|
|
->values();
|
|
|
|
|
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function searchGlobalResults(Request $request)
|
|
|
|
{
|
|
|
|
abort_if(!$request->user(), 404);
|
|
|
|
$this->validate($request, [
|
2024-07-23 07:29:56 +00:00
|
|
|
'q' => 'required|min:2|max:140',
|
2024-07-10 05:16:05 +00:00
|
|
|
'v' => 'required|in:0.2'
|
|
|
|
]);
|
|
|
|
$q = $request->input('q');
|
|
|
|
|
2024-07-23 07:29:56 +00:00
|
|
|
if(str_starts_with($q, 'https://')) {
|
|
|
|
$res = Helpers::getSignedFetch($q);
|
|
|
|
if($res && $res = json_decode($res, true)) {
|
2024-07-10 05:16:05 +00:00
|
|
|
|
2024-07-23 07:29:56 +00:00
|
|
|
}
|
|
|
|
if($res && isset($res['type']) && in_array($res['type'], ['Group', 'Note', 'Page'])) {
|
|
|
|
if($res['type'] === 'Group') {
|
|
|
|
return GroupActivityPubService::fetchGroup($q, true);
|
|
|
|
}
|
|
|
|
$resp = GroupActivityPubService::fetchGroupPost($q, true);
|
|
|
|
$resp['name'] = 'Group Post';
|
|
|
|
$resp['url'] = '/groups/' . $resp['group_id'] . '/p/' . $resp['id'];
|
|
|
|
return [$resp];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Group::whereNull('status')
|
|
|
|
->where('name', 'like', '%' . $q . '%')
|
|
|
|
->orderBy('id')
|
|
|
|
->take(10)
|
|
|
|
->pluck('id')
|
|
|
|
->map(function($group) {
|
|
|
|
return GroupService::get($group);
|
|
|
|
});
|
2024-07-10 05:16:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function searchLocalAutocomplete(Request $request)
|
|
|
|
{
|
|
|
|
abort_if(!$request->user(), 404);
|
|
|
|
$this->validate($request, [
|
|
|
|
'q' => 'required|min:2|max:40',
|
|
|
|
'g' => 'required',
|
|
|
|
'v' => 'required|in:0.2'
|
|
|
|
]);
|
|
|
|
$q = $request->input('q');
|
|
|
|
$gid = $request->input('g');
|
|
|
|
$pid = $request->user()->profile_id;
|
|
|
|
$group = Group::findOrFail($gid);
|
|
|
|
abort_if(!$group->isMember($pid), 404);
|
|
|
|
|
|
|
|
$res = GroupMember::whereGroupId($gid)
|
|
|
|
->join('profiles', 'group_members.profile_id', '=', 'profiles.id')
|
|
|
|
->where('profiles.username', 'like', "%{$q}%")
|
|
|
|
->take(10)
|
|
|
|
->get()
|
|
|
|
->map(function($gm) use ($gid) {
|
|
|
|
$a = AccountService::get($gm->profile_id);
|
|
|
|
return [
|
|
|
|
'username' => $a['username'],
|
|
|
|
'url' => url("/groups/{$gid}/user/{$a['id']}?rf=group_search")
|
|
|
|
];
|
|
|
|
});
|
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function searchAddRecent(Request $request)
|
|
|
|
{
|
|
|
|
$this->validate($request, [
|
|
|
|
'q' => 'required|min:2|max:40',
|
|
|
|
'g' => 'required',
|
|
|
|
]);
|
|
|
|
$q = $request->input('q');
|
|
|
|
$gid = $request->input('g');
|
|
|
|
$pid = $request->user()->profile_id;
|
|
|
|
$group = Group::findOrFail($gid);
|
|
|
|
abort_if(!$group->isMember($pid), 404);
|
|
|
|
|
|
|
|
$key = 'groups:search:recent:'.$gid.':pid:'.$pid;
|
|
|
|
$ttl = now()->addDays(14);
|
|
|
|
$res = Cache::get($key);
|
|
|
|
if(!$res) {
|
|
|
|
$val = json_encode([$q]);
|
|
|
|
} else {
|
|
|
|
$ex = collect(json_decode($res))
|
|
|
|
->prepend($q)
|
|
|
|
->unique('value')
|
|
|
|
->slice(0, 3)
|
|
|
|
->values()
|
|
|
|
->all();
|
|
|
|
$val = json_encode($ex);
|
|
|
|
}
|
|
|
|
Cache::put($key, $val, $ttl);
|
|
|
|
return 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function searchGetRecent(Request $request)
|
|
|
|
{
|
|
|
|
$gid = $request->input('g');
|
|
|
|
$pid = $request->user()->profile_id;
|
|
|
|
$group = Group::findOrFail($gid);
|
|
|
|
abort_if(!$group->isMember($pid), 404);
|
|
|
|
$key = 'groups:search:recent:'.$gid.':pid:'.$pid;
|
|
|
|
return Cache::get($key);
|
|
|
|
}
|
|
|
|
}
|