orderByDesc('id') ->get() ->map(fn (PublicSourceChannel $channel) => $this->toRow($channel, $request)) ->values(); return response()->json(['data' => $channels]); } public function store(Request $request): JsonResponse { $data = $request->validate([ 'source_code' => [ 'required', 'string', 'min:2', 'max:64', 'regex:/^[A-Za-z0-9_-]{2,64}$/', Rule::unique('public_source_channels', 'source_code'), ], 'source_name' => ['required', 'string', 'min:1', 'max:100'], 'status' => ['sometimes', Rule::in(PublicSourceChannel::STATUSES)], ]); $channel = PublicSourceChannel::query()->create([ 'source_code' => trim($data['source_code']), 'source_name' => trim($data['source_name']), 'status' => $data['status'] ?? PublicSourceChannel::STATUS_ENABLED, ]); return response()->json($this->toRow($channel, $request), 201); } public function show(Request $request, PublicSourceChannel $publicSourceChannel): JsonResponse { return response()->json($this->toRow($publicSourceChannel, $request)); } public function update(Request $request, PublicSourceChannel $publicSourceChannel): JsonResponse { $data = $request->validate([ 'source_code' => [ 'sometimes', 'string', 'min:2', 'max:64', 'regex:/^[A-Za-z0-9_-]{2,64}$/', Rule::unique('public_source_channels', 'source_code')->ignore($publicSourceChannel->id), ], 'source_name' => ['sometimes', 'string', 'min:1', 'max:100'], 'status' => ['sometimes', Rule::in(PublicSourceChannel::STATUSES)], ]); if (array_key_exists('source_code', $data)) { $publicSourceChannel->source_code = trim($data['source_code']); } if (array_key_exists('source_name', $data)) { $publicSourceChannel->source_name = trim($data['source_name']); } if (array_key_exists('status', $data)) { $publicSourceChannel->status = $data['status']; } $publicSourceChannel->save(); return response()->json($this->toRow($publicSourceChannel, $request)); } public function destroy(PublicSourceChannel $publicSourceChannel): Response { $publicSourceChannel->status = PublicSourceChannel::STATUS_DISABLED; $publicSourceChannel->save(); return response()->noContent(); } /** * @return array */ private function toRow(PublicSourceChannel $channel, Request $request): array { return [ 'id' => $channel->id, 'source_code' => $channel->source_code, 'source_name' => $channel->source_name, 'status' => $channel->status, 'entry_url' => $this->entryUrl($channel, $request), 'created_at' => $channel->created_at?->toIso8601String(), 'updated_at' => $channel->updated_at?->toIso8601String(), ]; } private function entryUrl(PublicSourceChannel $channel, Request $request): string { $base = trim((string) config('public_source.frontend_url')); if ($base === '') { $base = $request->getSchemeAndHttpHost(); } return rtrim($base, '/').'/?src='.rawurlencode($channel->source_code); } }