feat(blog): add city_id query parameter to blog detail endpoint for domain scoping
This commit is contained in:
@@ -115,6 +115,13 @@ class BlogController extends BaseController
|
||||
description: 'Blog slug or UUID',
|
||||
schema: new OA\Schema(type: 'string')
|
||||
),
|
||||
new OA\Parameter(
|
||||
name: 'city_id',
|
||||
in: 'query',
|
||||
required: false,
|
||||
description: 'Domain scope of the caller. A post that belongs to another city is 404 here, exactly as it is absent from GET /api/v1/blogs?city_id=…. Nationwide posts (city IS NULL) are always returned. Omit on the main domain to read any post.',
|
||||
schema: new OA\Schema(type: 'integer')
|
||||
),
|
||||
],
|
||||
responses: [
|
||||
new OA\Response(
|
||||
@@ -133,20 +140,36 @@ class BlogController extends BaseController
|
||||
]
|
||||
)
|
||||
),
|
||||
new OA\Response(response: 404, description: 'Blog post not found or not published'),
|
||||
new OA\Response(response: 404, description: 'Blog post not found, not published, or owned by another city'),
|
||||
]
|
||||
)]
|
||||
#[Route('/api/v1/blog/{slug}', methods: ['GET'])]
|
||||
public function detail(string $slug): JsonResponse
|
||||
public function detail(string $slug, Request $request): JsonResponse
|
||||
{
|
||||
$blog = $this->blogRepo->findBySlug($slug) ?? $this->blogRepo->findByUuid($slug);
|
||||
if ($blog === null || $blog->getStatus() !== Blog::STATUS_PUBLISHED) {
|
||||
return $this->error(ErrorCodes::ERR_NOT_FOUND_001, 'مقاله یافت نشد', 404);
|
||||
}
|
||||
|
||||
// یک پستِ شهریافته فقط روی دامنهٔ خودش وجود دارد. بدون این شرط، پستی که از
|
||||
// لیستِ دامنه حذف شده بود همچنان با URL مستقیم روی هر دامنهای ۲۰۰ میگرفت و
|
||||
// همان محتوا روی چند دامنه تکرار میشد. پست سراسری (city IS NULL) استثناست.
|
||||
$cityId = $request->query->get('city_id');
|
||||
if ($cityId !== null && $cityId !== '' && !$this->isVisibleOnCity($blog, (int) $cityId)) {
|
||||
return $this->error(ErrorCodes::ERR_NOT_FOUND_001, 'مقاله یافت نشد', 404);
|
||||
}
|
||||
|
||||
return $this->success(['data' => $blog->toArray()]);
|
||||
}
|
||||
|
||||
/** آینهٔ BlogRepository::applyCityFilter — پست همان شهر یا پست سراسری. */
|
||||
private function isVisibleOnCity(Blog $blog, int $cityId): bool
|
||||
{
|
||||
$owner = $blog->getCity();
|
||||
|
||||
return $owner === null || $owner->getId() === $cityId;
|
||||
}
|
||||
|
||||
// ── Admin CRUD ────────────────────────────────────────────────────────────
|
||||
|
||||
#[OA\Get(
|
||||
|
||||
Reference in New Issue
Block a user