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 && Fixometer::userIsHostOfGroup($party->group, $user) ? Role::HOST : Role::RESTARTER;
}
} 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