]> git.localhorst.tv Git - alttp.git/blob - app/Http/Controllers/EpisodeController.php
whispers
[alttp.git] / app / Http / Controllers / EpisodeController.php
1 <?php
2
3 namespace App\Http\Controllers;
4
5 use App\Models\Channel;
6 use App\Models\Episode;
7 use App\Models\EpisodeCrew;
8 use App\Models\User;
9 use Carbon\Carbon;
10 use Illuminate\Http\Request;
11 use Illuminate\Support\Facades\DB;
12
13 class EpisodeController extends Controller
14 {
15
16         public function addRestream(Request $request, Episode $episode) {
17                 $this->authorize('addRestream', $episode);
18                 $validatedData = $request->validate([
19                         'accept_comms' => 'boolean',
20                         'accept_tracker' => 'boolean',
21                         'channel_id' => 'numeric|exists:App\Models\Channel,id',
22                 ]);
23
24                 $channel = Channel::find($validatedData['channel_id']);
25                 $this->authorize('addEpisode', $channel);
26
27                 foreach ($episode->channels as $c) {
28                         if ($c->id == $channel->id) {
29                                 throw new \Exception('channel already exists on episode');
30                         }
31                 }
32
33                 $validatedProps = $request->validate([
34                         'accept_comms' => 'boolean',
35                         'accept_tracker' => 'boolean',
36                 ]);
37
38                 $episode->channels()->attach($channel, $validatedProps);
39
40                 return $episode->load('channels')->toJson();
41         }
42
43         public function crewManage(Request $request, Episode $episode) {
44                 $this->authorize('editRestream', $episode);
45                 $validatedData = $request->validate([
46                         'add' => 'numeric|exists:App\Models\User,id',
47                         'channel_id' => 'numeric|exists:App\Models\Channel,id',
48                         'confirm' => 'nullable|numeric|exists:App\Models\EpisodeCrew,id',
49                         'remove' => 'numeric|exists:App\Models\EpisodeCrew,id',
50                         'role' => 'string|in:commentary,setup,tracking',
51                         'unconfirm' => 'nullable|numeric|exists:App\Models\EpisodeCrew,id',
52                 ]);
53
54                 $channel = Channel::find($validatedData['channel_id']);
55                 $this->authorize('editRestream', $channel);
56
57                 if (isset($validatedData['add'])) {
58                         $crew = $episode->crew()
59                                 ->where('channel_id', '=', $channel->id)
60                                 ->where('user_id', '=', $validatedData['add'])
61                                 ->where('role', '=', $validatedData['role'])
62                                 ->first();
63                         if (!$crew) {
64                                 $add_user = User::findOrFail($validatedData['add']);
65                                 $crew = new EpisodeCrew();
66                                 $crew->channel()->associate($channel);
67                                 $crew->episode()->associate($episode);
68                                 $crew->user()->associate($add_user);
69                                 $crew->role = $validatedData['role'];
70                         }
71                         $crew->confirmed = true;
72                         $crew->save();
73                 }
74
75                 if (isset($validatedData['confirm'])) {
76                         $crew = EpisodeCrew::find($validatedData['confirm']);
77                         $crew->confirmed = true;
78                         $crew->save();
79                 }
80
81                 if (isset($validatedData['remove'])) {
82                         $crew = EpisodeCrew::find($validatedData['remove']);
83                         if ($crew) {
84                                 $crew->delete();
85                         }
86                 }
87
88                 if (isset($validatedData['unconfirm'])) {
89                         $crew = EpisodeCrew::find($validatedData['unconfirm']);
90                         $crew->confirmed = false;
91                         $crew->save();
92                 }
93
94                 $user = $request->user();
95                 if ($user->isPrivileged()) {
96                         return $episode->load(['crew', 'crew.user'])->toJson();
97                 } else {
98                         return $episode->load([
99                                 'crew' => function ($query) use ($user) {
100                                         $query->where('confirmed', true);
101                                         $query->orWhere('user_id', '=', $user->id);
102                                         $query->orWhereIn('channel_id', $user->channel_crews->pluck('channel_id'));
103                                 },
104                                 'crew.user',
105                         ])->toJson();
106                 }
107         }
108
109         public function crewSignup(Request $request, Episode $episode) {
110                 if (!$request->user()) {
111                         throw new \Exception('requires user to sign up');
112                 }
113                 $validatedData = $request->validate([
114                         'as' => 'string|in:commentary,tracking',
115                         'channel_id' => 'numeric|exists:App\Models\Channel,id',
116                 ]);
117
118                 $channel = $episode->channels()->find($validatedData['channel_id']);
119                 if (!$channel) {
120                         throw new \Exception('channel not found');
121                 }
122
123                 $as = $validatedData['as'];
124                 if ($as == 'commentary' && !$channel->pivot->accept_comms) {
125                         throw new \Exception('channel not looking for commentary');
126                 }
127                 if ($as == 'tracking' && !$channel->pivot->accept_tracker) {
128                         throw new \Exception('channel not looking for trackers');
129                 }
130
131                 $user = $request->user();
132
133                 foreach ($episode->crew as $crew) {
134                         if ($crew->user_id == $user->id && $crew->role == $as) {
135                                 throw new \Exception('already signed up');
136                         }
137                 }
138
139                 $episode->crew()->create([
140                         'channel_id' => $channel->id,
141                         'role' => $as,
142                         'user_id' => $user->id,
143                 ]);
144
145                 if ($user->isPrivileged()) {
146                         return $episode->load(['crew', 'crew.user'])->toJson();
147                 } else {
148                         return $episode->load([
149                                 'crew' => function ($query) use ($user) {
150                                         $query->where('confirmed', true);
151                                         $query->orWhere('user_id', '=', $user->id);
152                                         $query->orWhereIn('channel_id', $user->channel_crews->pluck('channel_id'));
153                                 },
154                                 'crew.user',
155                         ])->toJson();
156                 }
157         }
158
159         public function editRestream(Request $request, Episode $episode) {
160                 $this->authorize('editRestream', $episode);
161                 $validatedData = $request->validate([
162                         'channel_id' => 'numeric|exists:App\Models\Channel,id',
163                 ]);
164
165                 $channel = Channel::find($validatedData['channel_id']);
166                 $this->authorize('editRestream', $channel);
167
168                 $validatedChanges = $request->validate([
169                         'accept_comms' => 'boolean',
170                         'accept_tracker' => 'boolean',
171                 ]);
172
173                 $episode->channels()->updateExistingPivot($channel, $validatedChanges);
174
175                 return $episode->load('channels')->toJson();
176         }
177
178         public function removeRestream(Request $request, Episode $episode) {
179                 $this->authorize('removeRestream', $episode);
180                 $validatedData = $request->validate([
181                         'channel_id' => 'numeric|exists:App\Models\Channel,id',
182                 ]);
183
184                 $channel = Channel::find($validatedData['channel_id']);
185                 $this->authorize('removeEpisode', $channel);
186
187                 $episode->channels()->detach($channel);
188
189                 return $episode->load('channels')->toJson();
190         }
191
192         public function search(Request $request) {
193                 $validatedData = $request->validate([
194                         'after' => 'nullable|date',
195                         'before' => 'nullable|date',
196                         'event' => 'nullable|array',
197                         'event.*' => 'numeric',
198                         'limit' => 'numeric',
199                         'offset' => 'numeric',
200                         'reverse' => 'boolean',
201                 ]);
202                 $before = isset($validatedData['before']) ? $validatedData['before'] : Carbon::now()->add(1, 'days');
203                 $limit = isset($validatedData['limit']) ? $validatedData['limit'] : 100;
204                 $reverse = isset($validatedData['reverse']) ? $validatedData['reverse'] : false;
205                 $episodes = Episode::with(['channels', 'event', 'players', 'players.user'])
206                         ->select('episodes.*')
207                         ->join('events', 'episodes.event_id', '=', 'events.id')
208                         ->where('episodes.confirmed', '=', true)
209                         ->where('events.visible', '=', true)
210                         ->orderBy('episodes.start', $reverse ? 'DESC' : 'ASC')
211                         ->limit(1000);
212                 if (isset($validatedData['after'])) {
213                         $episodes = $episodes->where(
214                                 DB::raw('DATE_ADD(`episodes`.`start`, INTERVAL COALESCE(`episodes`.`estimate`, 0) SECOND)'),
215                                 '>=', $validatedData['after']);
216                 }
217                 if (isset($validatedData['before'])) {
218                         $episodes = $episodes->where('episodes.start', '<=', $validatedData['before']);
219                 }
220                 if (!empty($validatedData['event'])) {
221                         $episodes = $episodes->whereIn('episodes.event_id', $validatedData['event']);
222                 }
223                 if ($request->user() && $request->user()->isPrivileged()) {
224                         $episodes = $episodes->with(['crew', 'crew.user']);
225                 } else if ($request->user()) {
226                         $episodes = $episodes->with([
227                                 'crew' => function ($query) use ($request) {
228                                         $query->where('confirmed', true);
229                                         $query->orWhere('user_id', '=', $request->user()->id);
230                                         $query->orWhereIn('channel_id', $request->user()->channel_crews->pluck('channel_id'));
231                                 },
232                                 'crew.user',
233                         ]);
234                 } else {
235                         $episodes = $episodes->with([
236                                 'crew' => function ($query) {
237                                         $query->where('confirmed', true);
238                                 },
239                                 'crew.user',
240                         ]);
241                 }
242                 $episodes->limit($limit);
243                 return $episodes->get()->toJson();
244         }
245
246         public function single(Request $request, Episode $episode) {
247                 $this->authorize('view', $episode);
248                 return $episode->toJson();
249         }
250
251 }