problem with denying where a subsequent request being accepted will result in two friendships
jayenne opened this issue · 3 comments
Hi,
I've noticed a problem with deniying
requests.
Because you set the status to 'denied' and don't include an isDeniedBy()
method, we can't [out of the box] prevent a sender from re-befriending.
This problem is then compounded when a recipient denies
or blocks
a sender, then the sender subsequently re-befriends, a new entry is created with the status pending
(thus creating two entires for sender_id = x & recipient_id = y) - once that recipient accepts (or blocks etc) the sender, both enties become syncronised (accepted
or blocked
etc).
This results in multiple valid friendships for a single status
- A (less than desireable) workaround is to ignore all
deny
methods and useunfriend
instead. This will remove the befriend request thus preventing thesemultiples
- If you'd prefer to prevent re-befriendings after the first
denial
then useblockFriendRequest
instead ofunfriend
. This will maintain a status you can work with.
Yes. If user A send a friend request to user B and user B deny it, then user A can send Many duplicate friend requests to user B.
Extended my model with few methods, including:
use Friendable;
public function checkFriendship($model) {
$friendshipModelName = Interaction::getFriendshipModelName();
return $friendshipModelName::where(function ($query) use ($model) {
$query->where(function ($q) use ($model) {
$q->whereSender($this);
$q->whereRecipient($model);
})->orWhere(function ($q) use ($model) {
$q->whereRecipient($this);
$q->whereSender($model);
});
});
}
then in controller:
public function addFriend(Request $request, $id)
{
if ($request->user()->id == $id) {
return $this->code(406);
}
$to_befriend = Player::findOrFail($id);
$check = $request->user()->checkFriendship($to_befriend)->get();
if (count($check)) {
return $this->code(409, 'Friendship already '.$check[0]['status']);
}
DB::beginTransaction();
try {
$request->user()->befriend($to_befriend);
DB::commit();
return $this->code(201);
} catch(\Exception $e) {
DB::rollback();
return $this->code(500);
}
}
$this->code(500) is own json response method
I just repeated already existent getFriendship method :)
$user = User::findOrFail($id);
$check = $request->user()->getFriendship($user);