feat(blog): add city_id to blogs for city-specific scoping
- Introduced a new nullable city_id column in the blogs table to allow scoping of blog posts to specific cities. - Updated Blog entity to include a ManyToOne relationship with the City entity. - Enhanced BlogController to handle city_id in the request, allowing filtering of posts by city. - Modified BlogRepository to support querying published posts based on city_id. - Added tests to ensure correct behavior for city-scoped and nationwide posts, including creation and updating of posts with city associations.
This commit is contained in:
@@ -14,9 +14,11 @@ class BlogRepository extends ServiceEntityRepository
|
||||
public function findBySlug(string $slug): ?Blog { return $this->findOneBy(['slug' => $slug]); }
|
||||
|
||||
/** @return Blog[] published, newest first */
|
||||
public function findPublished(int $page = 1, int $limit = 20, ?string $tag = null): array
|
||||
public function findPublished(int $page = 1, int $limit = 20, ?string $tag = null, ?int $cityId = null): array
|
||||
{
|
||||
$qb = $this->createQueryBuilder('b')
|
||||
->leftJoin('b.city', 'c')
|
||||
->addSelect('c')
|
||||
->where('b.status = :status')
|
||||
->setParameter('status', Blog::STATUS_PUBLISHED)
|
||||
->orderBy('b.createdAt', 'DESC')
|
||||
@@ -24,11 +26,12 @@ class BlogRepository extends ServiceEntityRepository
|
||||
->setMaxResults($limit);
|
||||
|
||||
$this->applyTagFilter($qb, $tag);
|
||||
$this->applyCityFilter($qb, $cityId);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function countPublished(?string $tag = null): int
|
||||
public function countPublished(?string $tag = null, ?int $cityId = null): int
|
||||
{
|
||||
$qb = $this->createQueryBuilder('b')
|
||||
->select('COUNT(b.id)')
|
||||
@@ -36,10 +39,26 @@ class BlogRepository extends ServiceEntityRepository
|
||||
->setParameter('status', Blog::STATUS_PUBLISHED);
|
||||
|
||||
$this->applyTagFilter($qb, $tag);
|
||||
$this->applyCityFilter($qb, $cityId);
|
||||
|
||||
return (int) $qb->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* دامنهٔ یک شهر باید پستهای همان شهر **و** پستهای سراسری را ببیند — پست
|
||||
* سراسری (city NULL) روی همهٔ دامنهها منتشر است، فقط canonicalش روی دامنهٔ اصلی
|
||||
* مینشیند. بدون شرط NULL، دامنههای شهری محتوای عمومی را از دست میدادند.
|
||||
*/
|
||||
private function applyCityFilter(\Doctrine\ORM\QueryBuilder $qb, ?int $cityId): void
|
||||
{
|
||||
if ($cityId === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$qb->andWhere('b.city = :cityId OR b.city IS NULL')
|
||||
->setParameter('cityId', $cityId);
|
||||
}
|
||||
|
||||
private function applyTagFilter(\Doctrine\ORM\QueryBuilder $qb, ?string $tag): void
|
||||
{
|
||||
if ($tag === null || $tag === '') {
|
||||
|
||||
Reference in New Issue
Block a user