Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RES-1910 Event chat and attendee count inconsistencies #668

Merged
merged 10 commits into from
Aug 23, 2023
31 changes: 31 additions & 0 deletions app/Events/UserConfirmedEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Events;

use App\Group;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class UserConfirmedEvent
{
use Dispatchable, InteractsWithSockets, SerializesModels;

public $idevents;
public $iduser;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct($idevents, $iduser)
{
$this->idevents = $idevents;
$this->iduser = $iduser;
}
}
31 changes: 31 additions & 0 deletions app/Events/UserLeftEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Events;

use App\Group;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class UserLeftEvent
{
use Dispatchable, InteractsWithSockets, SerializesModels;

public $idevents;
public $iduser;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct($idevents, $iduser)
{
$this->idevents = $idevents;
$this->iduser = $iduser;
}
}
5 changes: 5 additions & 0 deletions app/EventsUsers.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public function volunteer()
return $this->hasOne(\App\User::class, 'id', 'user');
}

public function event()
{
return $this->hasOne(\App\Party::class, 'id', 'event');
}

public function getFullName()
{
if (! is_null($this->full_name)) {
Expand Down
19 changes: 12 additions & 7 deletions app/Http/Controllers/API/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,18 @@ public function addVolunteer(Request $request, $idevents)
$full_name = null;
}

// User is null, this volunteer is either anonymous or no user exists.
$eventRole = Role::RESTARTER;

if ($request->has('user') && $request->input('user') !== 'not-registered') {
// User is null, this volunteer is either anonymous or no user exists.
$user = $request->input('user');

if ($user) {
$u = User::find($user);

// A host of the group who is added to an event becomes a host of the event.
$eventRole = $u && $u->role == Role::HOST && Fixometer::userIsHostOfGroup($party->group, $user) ? Role::HOST : Role::RESTARTER;
Copy link
Contributor

@ngm ngm Aug 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should just be

$eventRole = $u && Fixometer::userIsHostOfGroup($party->group, $user) ? Role::HOST : Role::RESTARTER;

as there could be admins or network coordinators who are host of the group, and should get set with $eventRole = Role::HOST, even if their overall role ($u->role) might not be Role::HOST.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I've made that change.

}
} else {
$user = null;
}
Expand All @@ -173,7 +182,7 @@ public function addVolunteer(Request $request, $idevents)
->where('user', $user)
->where('status', '<>', 1)
->whereNotNull('status')
->where('role', 4);
->where('role', $eventRole);
$userWasInvited = $invitedUserQuery->count() == 1;

if ($userWasInvited) {
Expand All @@ -186,13 +195,11 @@ public function addVolunteer(Request $request, $idevents)
'event' => $idevents,
'user' => $user,
'status' => 1,
'role' => 4,
'role' => $eventRole,
'full_name' => $full_name,
]);
}

$party->increment('volunteers');

if (!is_null($volunteer_email_address)) {
// Send email.
$from = User::find(Auth::user()->id);
Expand Down Expand Up @@ -491,8 +498,6 @@ public function createEventv2(Request $request)
'role' => Role::HOST,
]);

$party->increment('volunteers');

// Notify relevant users.
$usersToNotify = Fixometer::usersWhoHavePreference('admin-moderate-event');
foreach ($party->associatedNetworkCoordinators() as $coordinator) {
Expand Down
46 changes: 10 additions & 36 deletions app/Http/Controllers/PartyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -418,15 +418,12 @@ public function getJoinEvent($event_id)
]);


$event->increment('volunteers');

$flashData = [];
if (! Auth::user()->isInGroup($event->theGroup->idgroups)) {
$flashData['prompt-follow-group'] = true;
}

$this->notifyHostsOfRsvp($user_event, $event_id);
$this->addToDiscourseThread($event, Auth::user());

return redirect()->back()->with($flashData);
}
Expand Down Expand Up @@ -473,30 +470,6 @@ public function notifyHostsOfRsvp($user_event, $event_id)
}
}

public function addToDiscourseThread($event, $user)
{
if ($event->discourse_thread) {
// We want a host of the event to add the user to the thread.
try {
$hosts = User::join('events_users', 'events_users.user', '=', 'users.id')
->where('events_users.event', $event->idevents)
->where('events_users.role', 3)
->select('users.*')
->get();
} catch (\Exception $e) {
$hosts = null;
}

if (! is_null($hosts) && count($hosts)) {
$this->discourseService->addUserToPrivateMessage(
$event->discourse_thread,
$hosts[0]->username,
$user->username
);
}
}
}

public static function stats($id)
{
$event = Party::where('idevents', $id)->first();
Expand Down Expand Up @@ -605,11 +578,6 @@ public function removeVolunteer(Request $request)
$delete_user = $volunteer->delete();

if ($delete_user == 1) {
//If the user accepted the invitation, we decrement
if ($volunteer->status == 1) {
Party::find($event_id)->decrement('volunteers');
}

//Return JSON
$return = [
'success' => true,
Expand Down Expand Up @@ -750,10 +718,8 @@ public function confirmInvite($event_id, $hash)

// Increment volunteers column to include latest invite
$event = Party::find($event_id);
$event->increment('volunteers');

$this->notifyHostsOfRsvp($user_event, $event_id);
$this->addToDiscourseThread($event, Auth::user());

return redirect('/party/view/'.$user_event->event);
}
Expand All @@ -764,7 +730,10 @@ public function confirmInvite($event_id, $hash)

public function cancelInvite($event_id)
{
EventsUsers::where('user', Auth::user()->id)->where('event', $event_id)->delete();
// We have to do a loop to avoid the gotcha where bulk delete operations don't invoke observers.
foreach (EventsUsers::where('user', Auth::user()->id)->where('event', $event_id)->get() as $delete) {
$delete->delete();
};

return redirect('/party/view/'.intval($event_id))->with('success', __('events.invite_cancelled'));
}
Expand Down Expand Up @@ -865,7 +834,12 @@ public function deleteEvent($id)

Audits::where('auditable_type', \App\Party::class)->where('auditable_id', $id)->delete();
Device::where('event', $id)->delete();
EventsUsers::where('event', $id)->delete();

// We have to do a loop to avoid the gotcha where bulk delete operations don't invoke observers.
foreach (EventsUsers::where('event', $id)->get() as $delete) {
$delete->delete();
};

$event->delete();

event(new EventDeleted($event));
Expand Down
50 changes: 50 additions & 0 deletions app/Listeners/AddUserToDiscourseThreadForEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace App\Listeners;

use App\Events\UserConfirmedEvent;
use App\Party;
use App\Role;
use App\Services\DiscourseService;
use App\User;
use Illuminate\Contracts\Queue\ShouldQueue;

class AddUserToDiscourseThreadForEvent implements ShouldQueue {
private $discourseService;

public function __construct(DiscourseService $discourseService)
{
$this->discourseService = $discourseService;
}

private function getHost($idevents) {
$hosts = User::join('events_users', 'events_users.user', '=', 'users.id')
->where('events_users.event', $idevents)
->where('events_users.role', Role::HOST)
->select('users.*')
->get();

return $hosts->count() ? $hosts[0] : null;
}

public function handle(UserConfirmedEvent $e) {
if ($e->iduser) {
$event = Party::find($e->idevents);
$user = User::find($e->iduser);

// Might not exist - timing windows.
if ($event && $user && $event->discourse_thread) {
// We need a host of the event to add the user to the thread.
$host = $this->getHost($event->idevents);

if ($host) {
$this->discourseService->addUserToPrivateMessage(
$event->discourse_thread,
$host->username,
$user->username
);
}
}
}
}
}
50 changes: 50 additions & 0 deletions app/Listeners/RemoveUserFromDiscourseThreadForEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace App\Listeners;

use App\Events\UserLeftEvent;
use App\Party;
use App\Role;
use App\Services\DiscourseService;
use App\User;
use Illuminate\Contracts\Queue\ShouldQueue;

class RemoveUserFromDiscourseThreadForEvent implements ShouldQueue {
private $discourseService;

public function __construct(DiscourseService $discourseService)
{
$this->discourseService = $discourseService;
}

private function getHost($idevents) {
$hosts = User::join('events_users', 'events_users.user', '=', 'users.id')
->where('events_users.event', $idevents)
->where('events_users.role', Role::HOST)
->select('users.*')
->get();

return $hosts->count() ? $hosts[0] : null;
}

public function handle(UserLeftEvent $e) {
if ($e->iduser) {
$event = Party::find($e->idevents);
$user = User::find($e->iduser);

// Might not exist - timing windows.
if ($event && $user && $event->discourse_thread) {
// We need a host of the event to add the user to the thread.
$host = $this->getHost($event->idevents);

if ($host) {
$this->discourseService->removeUserFromPrivateMessage(
$event->discourse_thread,
$host->username,
$user->username
);
}
}
}
}
}
Loading