1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Siak\Tontine\Service\Guild; |
4
|
|
|
|
5
|
|
|
use Illuminate\Support\Collection; |
6
|
|
|
use Illuminate\Support\Facades\DB; |
7
|
|
|
use Siak\Tontine\Exception\MessageException; |
8
|
|
|
use Siak\Tontine\Model\GuestInvite; |
9
|
|
|
use Siak\Tontine\Model\Guild; |
10
|
|
|
use Siak\Tontine\Model\User; |
11
|
|
|
use Siak\Tontine\Service\TenantService; |
12
|
|
|
|
13
|
|
|
use function count; |
14
|
|
|
use function now; |
15
|
|
|
|
16
|
|
|
class UserService |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* @param TenantService $tenantService |
20
|
|
|
*/ |
21
|
|
|
public function __construct(protected TenantService $tenantService) |
22
|
|
|
{} |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Get a paginated list of invites sent. |
26
|
|
|
* |
27
|
|
|
* @param User $user |
28
|
|
|
* @param int $page |
29
|
|
|
* |
30
|
|
|
* @return Collection |
31
|
|
|
*/ |
32
|
|
|
public function getHostInvites(User $user, int $page = 0): Collection |
33
|
|
|
{ |
34
|
|
|
return $user->host_invites() |
35
|
|
|
->page($page, $this->tenantService->getLimit()) |
36
|
|
|
->orderByDesc('created_at') |
37
|
|
|
->get(); |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Get the number of members. |
42
|
|
|
* |
43
|
|
|
* @param User $user |
44
|
|
|
* |
45
|
|
|
* @return int |
46
|
|
|
*/ |
47
|
|
|
public function getHostInviteCount(User $user): int |
48
|
|
|
{ |
49
|
|
|
return $user->host_invites()->count(); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* Get a paginated list of invites received. |
54
|
|
|
* |
55
|
|
|
* @param User $user |
56
|
|
|
* @param int $page |
57
|
|
|
* |
58
|
|
|
* @return Collection |
59
|
|
|
*/ |
60
|
|
|
public function getGuestInvites(User $user, int $page = 0): Collection |
61
|
|
|
{ |
62
|
|
|
return $user->guest_invites() |
63
|
|
|
->page($page, $this->tenantService->getLimit()) |
64
|
|
|
->orderByDesc('created_at') |
65
|
|
|
->get(); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Get the number of invites. |
70
|
|
|
* |
71
|
|
|
* @param User $user |
72
|
|
|
* |
73
|
|
|
* @return int |
74
|
|
|
*/ |
75
|
|
|
public function getGuestInviteCount(User $user): int |
76
|
|
|
{ |
77
|
|
|
return $user->guest_invites()->count(); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Find an invite. |
82
|
|
|
* |
83
|
|
|
* @param User $user |
84
|
|
|
* @param int $inviteId |
85
|
|
|
* |
86
|
|
|
* @return GuestInvite|null |
87
|
|
|
*/ |
88
|
|
|
public function getHostInvite(User $user, int $inviteId): ?GuestInvite |
89
|
|
|
{ |
90
|
|
|
return $user->host_invites()->find($inviteId); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Find an invite. |
95
|
|
|
* |
96
|
|
|
* @param User $user |
97
|
|
|
* @param int $inviteId |
98
|
|
|
* |
99
|
|
|
* @return GuestInvite|null |
100
|
|
|
*/ |
101
|
|
|
public function getGuestInvite(User $user, int $inviteId): ?GuestInvite |
102
|
|
|
{ |
103
|
|
|
return $user->guest_invites()->find($inviteId); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* Create an invite. |
108
|
|
|
* |
109
|
|
|
* @param User $host |
110
|
|
|
* @param string $guestEmail |
111
|
|
|
* |
112
|
|
|
* @return void |
113
|
|
|
*/ |
114
|
|
|
public function createInvite(User $host, string $guestEmail) |
115
|
|
|
{ |
116
|
|
|
// The current user is the host. |
117
|
|
|
$guest = User::where('email', $guestEmail) |
118
|
|
|
->with('guest_invites', fn($query) => $query->where('host_id', $host->id)) |
119
|
|
|
->first(); |
120
|
|
|
if(!$guest) |
121
|
|
|
{ |
122
|
|
|
throw new MessageException(trans('tontine.invite.errors.user_not_found')); |
123
|
|
|
} |
124
|
|
|
if($guest->id === $host->id || $guest->guest_invites->count() > 0) |
125
|
|
|
{ |
126
|
|
|
throw new MessageException(trans('tontine.invite.errors.cannot_invite')); |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
$invite = new GuestInvite(); |
130
|
|
|
$invite->status = GuestInvite::STATUS_PENDING; |
131
|
|
|
$invite->active = true; |
132
|
|
|
// One week validity by default. |
133
|
|
|
$invite->expires_at = now()->addWeek(); |
134
|
|
|
$invite->host()->associate($host); |
135
|
|
|
$invite->guest()->associate($guest); |
136
|
|
|
$invite->save(); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Accept an invite. |
141
|
|
|
* |
142
|
|
|
* @param User $user |
143
|
|
|
* @param int $inviteId |
144
|
|
|
* |
145
|
|
|
* @return void |
146
|
|
|
*/ |
147
|
|
|
public function acceptInvite(User $user, int $inviteId) |
148
|
|
|
{ |
149
|
|
|
if(!($invite = $this->getGuestInvite($user, $inviteId))) |
150
|
|
|
{ |
151
|
|
|
throw new MessageException(trans('tontine.invite.errors.invite_not_found')); |
152
|
|
|
} |
153
|
|
|
if($invite->is_expired) |
|
|
|
|
154
|
|
|
{ |
155
|
|
|
throw new MessageException(trans('tontine.invite.errors.invite_expired')); |
156
|
|
|
} |
157
|
|
|
if(!$invite->is_pending) |
|
|
|
|
158
|
|
|
{ |
159
|
|
|
throw new MessageException(trans('tontine.invite.errors.not_allowed')); |
160
|
|
|
} |
161
|
|
|
$invite->update(['status' => GuestInvite::STATUS_ACCEPTED]); |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* Refuse an invite. |
166
|
|
|
* |
167
|
|
|
* @param User $user |
168
|
|
|
* @param int $inviteId |
169
|
|
|
* |
170
|
|
|
* @return void |
171
|
|
|
*/ |
172
|
|
|
public function refuseInvite(User $user, int $inviteId) |
173
|
|
|
{ |
174
|
|
|
if(!($invite = $this->getGuestInvite($user, $inviteId))) |
175
|
|
|
{ |
176
|
|
|
throw new MessageException(trans('tontine.invite.errors.invite_not_found')); |
177
|
|
|
} |
178
|
|
|
if($invite->is_expired) |
|
|
|
|
179
|
|
|
{ |
180
|
|
|
throw new MessageException(trans('tontine.invite.errors.invite_expired')); |
181
|
|
|
} |
182
|
|
|
if(!$invite->is_pending) |
|
|
|
|
183
|
|
|
{ |
184
|
|
|
throw new MessageException(trans('tontine.invite.errors.not_allowed')); |
185
|
|
|
} |
186
|
|
|
$invite->update(['status' => GuestInvite::STATUS_REFUSED]); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* Cancel an invite. |
191
|
|
|
* |
192
|
|
|
* @param User $user |
193
|
|
|
* @param int $inviteId |
194
|
|
|
* |
195
|
|
|
* @return void |
196
|
|
|
*/ |
197
|
|
|
public function cancelInvite(User $user, int $inviteId) |
198
|
|
|
{ |
199
|
|
|
if(!($invite = $this->getHostInvite($user, $inviteId))) |
200
|
|
|
{ |
201
|
|
|
throw new MessageException(trans('tontine.invite.errors.invite_not_found')); |
202
|
|
|
} |
203
|
|
|
if($invite->is_expired) |
|
|
|
|
204
|
|
|
{ |
205
|
|
|
throw new MessageException(trans('tontine.invite.errors.invite_expired')); |
206
|
|
|
} |
207
|
|
|
if(!$invite->is_pending) |
|
|
|
|
208
|
|
|
{ |
209
|
|
|
throw new MessageException(trans('tontine.invite.errors.not_allowed')); |
210
|
|
|
} |
211
|
|
|
$invite->update(['status' => GuestInvite::STATUS_CANCELLED]); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* Delete an invite. |
216
|
|
|
* |
217
|
|
|
* @param GuestInvite $invite |
218
|
|
|
* |
219
|
|
|
* @return void |
220
|
|
|
*/ |
221
|
|
|
private function deleteInvite(GuestInvite $invite) |
222
|
|
|
{ |
223
|
|
|
DB::transaction(function() use($invite) { |
224
|
|
|
DB::table('guest_options')->where('invite_id', $invite->id)->delete(); |
225
|
|
|
$invite->delete(); |
226
|
|
|
}); |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* Delete an invite. |
231
|
|
|
* |
232
|
|
|
* @param User $user |
233
|
|
|
* @param int $inviteId |
234
|
|
|
* |
235
|
|
|
* @return void |
236
|
|
|
*/ |
237
|
|
|
public function deleteHostInvite(User $user, int $inviteId) |
238
|
|
|
{ |
239
|
|
|
if(!($invite = $this->getHostInvite($user, $inviteId))) |
240
|
|
|
{ |
241
|
|
|
throw new MessageException(trans('tontine.invite.errors.invite_not_found')); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
$this->deleteInvite($invite); |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
/** |
248
|
|
|
* Delete an invite. |
249
|
|
|
* |
250
|
|
|
* @param Guild $guild |
251
|
|
|
* @param int $inviteId |
252
|
|
|
* |
253
|
|
|
* @return bool |
254
|
|
|
*/ |
255
|
|
|
public function deleteGuestInvite(Guild $guild, int $inviteId): bool |
256
|
|
|
{ |
257
|
|
|
if(!($invite = $this->getGuestInvite($guild->user, $inviteId))) |
258
|
|
|
{ |
259
|
|
|
throw new MessageException(trans('tontine.invite.errors.invite_not_found')); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
$inviteIsDeleted = DB::table('guest_options') |
263
|
|
|
->where('invite_id', $invite->id) |
264
|
|
|
->where('guild_id', $guild->id) |
265
|
|
|
->exists(); |
266
|
|
|
$this->deleteInvite($invite); |
267
|
|
|
|
268
|
|
|
return $inviteIsDeleted; |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* Get the guest access on a given guild |
273
|
|
|
* |
274
|
|
|
* @param GuestInvite $invite |
275
|
|
|
* @param Guild $guild |
276
|
|
|
* |
277
|
|
|
* @return array |
278
|
|
|
*/ |
279
|
|
|
public function getHostGuildAccess(GuestInvite $invite, Guild $guild): array |
280
|
|
|
{ |
281
|
|
|
$inviteTontine = $invite->guilds()->find($guild->id); |
282
|
|
|
return !$inviteTontine ? [] : $inviteTontine->options->access; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* Get the guest access on a given guild |
287
|
|
|
* |
288
|
|
|
* @param GuestInvite $invite |
289
|
|
|
* @param Guild $guild |
290
|
|
|
* @param array $access |
291
|
|
|
* |
292
|
|
|
* @return void |
293
|
|
|
*/ |
294
|
|
|
public function saveHostGuildAccess(GuestInvite $invite, Guild $guild, array $access) |
295
|
|
|
{ |
296
|
|
|
DB::transaction(function() use($invite, $guild, $access) { |
297
|
|
|
$invite->guilds()->detach($guild->id); |
298
|
|
|
if(count($access) > 0) |
299
|
|
|
{ |
300
|
|
|
$invite->guilds()->attach($guild->id, ['access' => $access]); |
301
|
|
|
} |
302
|
|
|
}); |
303
|
|
|
} |
304
|
|
|
} |
305
|
|
|
|
Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.