97 lines
3.1 KiB
PHP
97 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Repositories\Cs;
|
|
|
|
use App\Models\GcBoard;
|
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
final class NoticeRepository
|
|
{
|
|
private function baseVisible(): Builder
|
|
{
|
|
// 기존 스코프 유지 (gubun=notice + hiding=N 등)
|
|
return GcBoard::query()->visibleNotice();
|
|
}
|
|
|
|
public function paginate(string $q, int $perPage = 15): LengthAwarePaginator
|
|
{
|
|
$q = trim($q);
|
|
|
|
$query = $this->baseVisible()
|
|
->when($q !== '', function (Builder $query) use ($q) {
|
|
$query->where(function (Builder $w) use ($q) {
|
|
$w->where('subject', 'like', "%{$q}%")
|
|
->orWhere('content', 'like', "%{$q}%");
|
|
});
|
|
});
|
|
|
|
// 기존 정렬 스코프 유지
|
|
$query->noticeOrder();
|
|
|
|
return $query->paginate($perPage);
|
|
}
|
|
|
|
public function findOrFail(int $seq): GcBoard
|
|
{
|
|
return $this->baseVisible()
|
|
->where('seq', $seq)
|
|
->firstOrFail();
|
|
}
|
|
|
|
public function incrementHit(int $seq): void
|
|
{
|
|
// 단순 hit 증가
|
|
GcBoard::query()
|
|
->where('seq', $seq)
|
|
->increment('hit');
|
|
}
|
|
|
|
/**
|
|
* 리스트 정렬 기준(공지 우선 + 최신 우선)을 아래처럼 가정/고정:
|
|
* 1) first_sign DESC
|
|
* 2) seq DESC
|
|
*
|
|
* ⚠️ 기존 noticeOrder()가 regdate를 포함해도 무방하지만,
|
|
* prev/next는 "가장 가까운 글"을 잡아야 해서 여기서는 명시적으로 처리.
|
|
*/
|
|
public function findPrev(GcBoard $cur): ?GcBoard
|
|
{
|
|
$curFirst = (int)($cur->first_sign ?? 0);
|
|
$curSeq = (int)$cur->seq;
|
|
|
|
return $this->baseVisible()
|
|
->where(function (Builder $w) use ($curFirst, $curSeq) {
|
|
// COALESCE(first_sign,0) < curFirst
|
|
$w->whereRaw('COALESCE(first_sign,0) < ?', [$curFirst])
|
|
->orWhere(function (Builder $w2) use ($curFirst, $curSeq) {
|
|
// COALESCE(first_sign,0) = curFirst AND seq < curSeq
|
|
$w2->whereRaw('COALESCE(first_sign,0) = ?', [$curFirst])
|
|
->where('seq', '<', $curSeq);
|
|
});
|
|
})
|
|
->orderByRaw('COALESCE(first_sign,0) desc')
|
|
->orderBy('seq', 'desc')
|
|
->first();
|
|
}
|
|
|
|
public function findNext(GcBoard $cur): ?GcBoard
|
|
{
|
|
$curFirst = (int)($cur->first_sign ?? 0);
|
|
$curSeq = (int)$cur->seq;
|
|
|
|
// "가장 가까운 앞"을 위해 ASC로 뒤집어서 first()
|
|
return $this->baseVisible()
|
|
->where(function (Builder $w) use ($curFirst, $curSeq) {
|
|
$w->whereRaw('COALESCE(first_sign,0) > ?', [$curFirst])
|
|
->orWhere(function (Builder $w2) use ($curFirst, $curSeq) {
|
|
$w2->whereRaw('COALESCE(first_sign,0) = ?', [$curFirst])
|
|
->where('seq', '>', $curSeq);
|
|
});
|
|
})
|
|
->orderByRaw('COALESCE(first_sign,0) asc')
|
|
->orderBy('seq', 'asc')
|
|
->first();
|
|
}
|
|
}
|