resolveContext($request); $articles = $this->getArticles($audience, $locale) ->map(fn ($article) => Arr::only($article, config('help.list_fields'))) ->values(); return response()->json([ 'data' => $articles, ]); } public function show(Request $request, string $slug): JsonResponse { [$audience, $locale] = $this->resolveContext($request); $article = $this->getArticle($audience, $locale, $slug); abort_if(! $article, 404, 'Help article not found.'); return response()->json([ 'data' => $article, ]); } /** * @return array{string, string} */ private function resolveContext(Request $request): array { $this->attemptTokenAuthentication($request); $audience = Str::of($request->string('audience', 'guest'))->lower()->value(); $locale = Str::of($request->string('locale', config('help.default_locale')))->lower()->value(); if ($audience === 'admin' && ! $request->user()) { abort(401, 'Authentication required for admin help content.'); } if (! in_array($audience, config('help.audiences', []), true)) { abort(400, 'Invalid audience supplied.'); } return [$audience, $locale]; } private function attemptTokenAuthentication(Request $request): void { if ($request->user()) { return; } $bearer = $request->bearerToken(); if (! $bearer) { return; } $token = PersonalAccessToken::findToken($bearer); if (! $token) { return; } $user = $token->tokenable; if (! $user) { return; } if (method_exists($user, 'withAccessToken')) { $user->withAccessToken($token); } Auth::setUser($user); $request->setUserResolver(fn () => $user); } private function getArticles(string $audience, string $locale) { try { return $this->repository->list($audience, $locale); } catch (RuntimeException $e) { $fallback = config('help.fallback_locale'); if ($locale === $fallback) { throw $e; } return $this->repository->list($audience, $fallback); } } private function getArticle(string $audience, string $locale, string $slug): ?array { try { $article = $this->repository->find($audience, $locale, $slug); } catch (RuntimeException $e) { $fallback = config('help.fallback_locale'); if ($locale !== $fallback) { return $this->repository->find($audience, $fallback, $slug); } throw $e; } return $article; } }