integer('per_page') ?: $blog->posts_per_page)); $articles = Article::query() ->with(['category:id,name', 'user:id,name,username', 'tags:id,name']) ->visible() ->published() ->orderByDesc('stick') ->orderByDesc('published_at') ->paginate($perPage); return response()->json([ 'data' => $articles->getCollection()->map(fn (Article $article) => $this->summary($article))->values(), 'meta' => [ 'current_page' => $articles->currentPage(), 'last_page' => $articles->lastPage(), 'per_page' => $articles->perPage(), 'total' => $articles->total(), ], ]); } public function show(int $id, ArticleAccess $access): JsonResponse { $article = Article::query() ->with(['category:id,name', 'user:id,name,username', 'tags:id,name']) ->visible() ->published() ->findOrFail($id); // Anonymous API: never pass a user (purchased/admin full text is Web-only this phase). $decision = $access->resolve($article, null, []); $payload = [ ...$this->summary($article), 'content_format' => $article->content_format, 'keywords' => $article->keywords, 'access' => [ 'status' => $decision->status, 'message' => $decision->message, 'checkout_url' => $decision->checkoutUrl, ], ]; if ($decision->isAllow()) { $payload['content'] = $article->content; $payload['content_html'] = $article->renderedHtml(); } else { $payload['content'] = null; $payload['content_html'] = $access->publicHtml($article, $decision); $payload['teaser_html'] = $payload['content_html']; } return response()->json(['data' => $payload]); } /** * @return array */ protected function summary(Article $article): array { return [ 'id' => $article->id, 'title' => $article->title, 'slug' => $article->slug, 'description' => $article->description, 'published_at' => optional($article->published_at)?->toIso8601String(), 'views' => $article->views, 'stick' => (bool) $article->stick, 'url' => url('/show-'.$article->id.'.shtml'), 'category' => $article->category ? [ 'id' => $article->category->id, 'name' => $article->category->name, ] : null, 'author' => $article->user ? [ 'id' => $article->user->id, 'name' => $article->user->name, 'username' => $article->user->username, ] : null, 'tags' => $article->tags->map(fn ($tag) => [ 'id' => $tag->id, 'name' => $tag->name, ])->values(), ]; } }