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) |
||
0 ignored issues
–
show
|
|||
154 | { |
||
155 | throw new MessageException(trans('tontine.invite.errors.invite_expired')); |
||
156 | } |
||
157 | if(!$invite->is_pending) |
||
0 ignored issues
–
show
|
|||
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) |
||
0 ignored issues
–
show
|
|||
179 | { |
||
180 | throw new MessageException(trans('tontine.invite.errors.invite_expired')); |
||
181 | } |
||
182 | if(!$invite->is_pending) |
||
0 ignored issues
–
show
|
|||
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) |
||
0 ignored issues
–
show
|
|||
204 | { |
||
205 | throw new MessageException(trans('tontine.invite.errors.invite_expired')); |
||
206 | } |
||
207 | if(!$invite->is_pending) |
||
0 ignored issues
–
show
|
|||
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.