3 namespace App\Http\Controllers;
5 use App\Models\Channel;
6 use App\Models\Episode;
7 use App\Models\EpisodeCrew;
10 use Illuminate\Http\Request;
11 use Illuminate\Support\Facades\DB;
13 class EpisodeController extends Controller
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',
24 $channel = Channel::find($validatedData['channel_id']);
25 $this->authorize('addEpisode', $channel);
27 foreach ($episode->channels as $c) {
28 if ($c->id == $channel->id) {
29 throw new \Exception('channel already exists on episode');
33 $validatedProps = $request->validate([
34 'accept_comms' => 'boolean',
35 'accept_tracker' => 'boolean',
38 $episode->channels()->attach($channel, $validatedProps);
40 return $episode->load('channels')->toJson();
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',
54 $channel = Channel::find($validatedData['channel_id']);
55 $this->authorize('editRestream', $channel);
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'])
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'];
71 $crew->confirmed = true;
75 if (isset($validatedData['confirm'])) {
76 $crew = EpisodeCrew::find($validatedData['confirm']);
77 $crew->confirmed = true;
81 if (isset($validatedData['remove'])) {
82 $crew = EpisodeCrew::find($validatedData['remove']);
88 if (isset($validatedData['unconfirm'])) {
89 $crew = EpisodeCrew::find($validatedData['unconfirm']);
90 $crew->confirmed = false;
94 $user = $request->user();
95 if ($user->isPrivileged()) {
96 return $episode->load(['crew', 'crew.user'])->toJson();
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'));
109 public function crewSignup(Request $request, Episode $episode) {
110 if (!$request->user()) {
111 throw new \Exception('requires user to sign up');
113 $validatedData = $request->validate([
114 'as' => 'string|in:commentary,tracking',
115 'channel_id' => 'numeric|exists:App\Models\Channel,id',
118 $channel = $episode->channels()->find($validatedData['channel_id']);
120 throw new \Exception('channel not found');
123 $as = $validatedData['as'];
124 if ($as == 'commentary' && !$channel->pivot->accept_comms) {
125 throw new \Exception('channel not looking for commentary');
127 if ($as == 'tracking' && !$channel->pivot->accept_tracker) {
128 throw new \Exception('channel not looking for trackers');
131 $user = $request->user();
133 foreach ($episode->crew as $crew) {
134 if ($crew->user_id == $user->id && $crew->role == $as) {
135 throw new \Exception('already signed up');
139 $episode->crew()->create([
140 'channel_id' => $channel->id,
142 'user_id' => $user->id,
145 if ($user->isPrivileged()) {
146 return $episode->load(['crew', 'crew.user'])->toJson();
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'));
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',
165 $channel = Channel::find($validatedData['channel_id']);
166 $this->authorize('editRestream', $channel);
168 $validatedChanges = $request->validate([
169 'accept_comms' => 'boolean',
170 'accept_tracker' => 'boolean',
173 $episode->channels()->updateExistingPivot($channel, $validatedChanges);
175 return $episode->load('channels')->toJson();
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',
184 $channel = Channel::find($validatedData['channel_id']);
185 $this->authorize('removeEpisode', $channel);
187 $episode->channels()->detach($channel);
189 return $episode->load('channels')->toJson();
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',
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')
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']);
217 if (isset($validatedData['before'])) {
218 $episodes = $episodes->where('episodes.start', '<=', $validatedData['before']);
220 if (!empty($validatedData['event'])) {
221 $episodes = $episodes->whereIn('episodes.event_id', $validatedData['event']);
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'));
235 $episodes = $episodes->with([
236 'crew' => function ($query) {
237 $query->where('confirmed', true);
242 $episodes->limit($limit);
243 return $episodes->get()->toJson();
246 public function single(Request $request, Episode $episode) {
247 $this->authorize('view', $episode);
248 return $episode->toJson();