Solution 🧩/고도몰
[고도몰] 검색/페이징
yundi
2024. 2. 7. 08:38
오늘은 검색과 페이징을 정리해보려고 한다...! 파일 분석하는데 정말 오래 걸리고 힘들었지만.. 나 성장 중인 건가...!
우선 연습으로 버거킹 매장에 대한 정보를 데이터에 넣어두고 매장을 검색하는 것으로 구현을 해보았다.
gd_select_box와 gd_isset은 고도몰에 있는 내장 함수이다.
✨ 검색
검색 폼을 먼저 만들어준다!
고도몰은 모든 것을 상속받기 때문에 selectbox를 gd_select_box() 사용해 검색할 조건을 배열에 넣어주었다.
체크박스로도 원하는 매장유형을 선택해서 검색할 수 있도록 checkbox도 만들어 주었다.
<div class="table-title">매장 검색</div>
<form method="get" action="" id="searchForm">
<div class="search-detail-box">
<table class="table table-cols">
<colgroup>
<col class="width-sm"/>
<col/>
</colgroup>
<tr>
<th>검색어</th>
<td>
<div class="form-inline">
<?=gd_select_box('key', 'key', array( 'name' => '매장명', 'address' => '주소', 'shopType' => '매장유형'), '', gd_isset($search['key'])); ?>
<input type="text" name="keyword" value="<?=gd_isset($search['keyword']); ?>" class="form-control width-xl"/>
</div>
</td>
<tr class="js-search-delivery">
<th>매정 유형</th>
<td colspan="3">
<div class="checkbox">
<label class="checkbox-inline">
<input type="checkbox" name="shopType[]" value="" class="js-not-checkall" data-target-name="shopType[]" <?= in_array('', $search['shopType']) ? 'checked="checked"' : ''; ?>> 전체
</label>
<label>
<input class="checkbox-inline" type="checkbox" name="shopType[]" value="delivery" <?= in_array('delivery', $search['shopType']) ? 'checked="checked"' : ''; ?>>딜리버리
</label>
<label>
<input class="checkbox-inline" type="checkbox" name="shopType[]" value="order" <?= in_array('order', $search['shopType']) ? 'checked="checked"' : ''; ?>>킹오더
</label>
<label>
<input class="checkbox-inline" type="checkbox" name="shopType[]" value="all" <?= in_array('all', $search['shopType']) ? 'checked="checked"' : ''; ?>>24시
</label>
<label>
<input class="checkbox-inline" type="checkbox" name="shopType[]" value="morning" <?= in_array('morning', $search['shopType']) ? 'checked="checked"' : ''; ?>>아침식사
</label>
<label>
<input class="checkbox-inline" type="checkbox" name="shopType[]" value="parking" <?= in_array('parking', $search['shopType']) ? 'checked="checked"' : ''; ?>>주차가능
</label>
<label>
<input class="checkbox-inline" type="checkbox" name="shopType[]" value="drive" <?= in_array('drive', $search['shopType']) ? 'checked="checked"' : ''; ?>>드라이브스루
</label>
</div>
</td>
</tr>
</tr>
</table>
<div class="table-btn">
<input type="submit" class="btn btn-lg btn-black" value="검색">
</div>
</div>
</form>
✨ 페이징
한 페이지에 폼을 두 개를 만들어 줬는데 하나는 검색, 밑에 있는 폼은 삭제로직을 처리하기 위해서 만든 폼이다.
페이징은 Page.php를 상속받아서 튜닝해야 한다.
<form action="" method="post" id="frmList">
<input type="hidden" name="mode" value="" >
<table class="table table-rows table-fixed">
<thead>
<tr>
<th class="width-2xs center" style="width: 50px !important;">
<input type="checkbox" class="js-checkall" data-target-name="sno[]">
</th>
<th style="width: 50px;">번호</th>
<th>이미지</th>
<th style="width: 200px;">매장명</th>
<th>전화번호</th>
<th style="width: 380px;">주소</th>
<th>운영시간</th>
<th style="width: 300px;">매장 유형</th>
<th>등록일/수정일</th>
<th>수정</th>
</tr>
</thead>
<tbody>
<?php
if (isset($data) && is_array($data)) {
foreach ($data as $val) {
?>
<tr class="center">
<td class="center number">
<input type="checkbox" name="sno[]" value="<?=$val['sno']; ?>"/>
</td>
<td class="center"><?=number_format($page->idx--); ?></td>
<td>
<?php
// 이미지가 있는 경우에만 출력
if (!empty($val['imagePath'])) { ?>
<img src="<?= $val['imagePath'] ?>" alt="매장 이미지" style="width: 65px; height: 60px;">
<?php
}
?>
</td>
<td><?=$val['name']; ?></td>
<td ><?=$val['tel']; ?></td>
<td>
<?=isset($val['zipcode']) ? $val['zipcode'] : '' ?><br>
<?=isset($val['zonecode']) ? $val['zonecode'] : '' ?><br>
<?=$val['address'] ?><br>
<?=$val['addressSub'] ?>
</td>
<td >
<?=date('H:i', strtotime($val['open'])); ?> ~ <?=date('H:i', strtotime($val['close'])); ?>
</td>
<td>
<?php
$shopTypes = explode(',', $val['shopType']);
foreach ($shopTypes as $shopType) {
switch ($shopType) {
case 'delivery':
echo '<img src="/data/icon/shop_type/delivery.png" alt="딜리버리" style="margin: 5px;">';
break;
case 'order':
echo '<img src="/data/icon/shop_type/order.png" alt="킹오더" style="margin: 5px;">';
break;
case 'all':
echo '<img src="/data/icon/shop_type/all.png" alt="24시간" style="margin: 5px;">';
break;
case 'morning':
echo '<img src="/data/icon/shop_type/morning.png" alt="아침식사" style="margin: 5px;">';
break;
case 'parking':
echo '<img src="/data/icon/shop_type/parking.png" alt="주차가능" style="margin: 5px;">';
break;
case 'drive':
echo '<img src="/data/icon/shop_type/drive.png" alt="드라이브스루" style="margin: 5px;">';
break;
}
}
?>
</td>
<td >
<?=date('Y-m-d', strtotime($val['regDt'])); ?><br>
<?= $val['modDt'] ? date('Y-m-d', strtotime($val['modDt'])) : ''; ?>
</td>
<td class="center padlr10"><a href="seum_shop.php?sno=<?= intval($val['sno']); ?>" class="btn btn-white btn-sm">수정</a></td>
</tr>
<?php
}
} else {
?>
<tr>
<td class="center" colspan="4">검색된 정보가 없습니다.</td>
</tr>
<?php
}
?>
</tbody>
</table>
<div class="pull-left" style="width:100%; padding-top: 5px;">
<button type="button" class="btn btn-white js-check-delete">선택 삭제</button>
</div>
<div class="center"><?=$page->getPage();?></div>
</form>
✨ Controller
페이징 코드를 상속받아서 사용하는 것은 진짜 편리했다. (이러다 나 개발 못하는 개발자 되는 거 아니냐구~)
php는 use 키워드를 사용해서 사용할 클래스 등등을 불러오는 것 같은데 자바로 치면 import랑 비슷한 거겠군 ㅎㅎ
<?php
namespace Controller\Admin\Goods;
use Bundle\Component\Page\Page;
use Request;
class SeumLyjController extends \Controller\Admin\Controller
{
public function index()
{
$get= Request::get()->all();
$post= Request::post()->all();
$db = \App::load('DB');
try {
$this->callMenu('goods', 'batch', 'list');
$pages = $ get ['page'] ? $get ['page'] : 1;
$get ['pageNum'] = $get ['pageNum'] ? $get ['pageNum'] : 10;
$count_sql = "SELECT sno FROM 테이블 이름 WHERE is_show = 'Y'";
$data = $db->query_fetch($count_sql);
// 리스트
$str_sql = "SELECT s.*, MIN(i.imageName) AS imageName, MIN(i.imagePath) AS imagePath
FROM 테이블 이름 s
LEFT JOIN 테이블 이름 i ON s.sno = i.sno
WHERE s.is_show = 'Y'";
// 검색
if ($get ['keyword']) {
$rWhere[] = " " . $get ['key'] . " LIKE '%" . $get ['keyword'] . "%'";
}
if (!empty($get['shopType']) && !in_array('', $get['shopType'])) {
$shopType = [];
foreach ($get['shopType'] as $type) {
$shopType[] = "FIND_IN_SET('" . $type . "', s.shopType) > 0";
}
$rWhere[] = '(' . implode(' OR ', $shopType) . ')';
}
// 검색 조건이 있으면 WHERE 추가
if($rWhere) {
$rWhere = " AND " . implode(" AND ", $rWhere);
}
$str_sql .= $rWhere." GROUP BY s.sno";
$data2 = $db->query_fetch($str_sql);
// 페이징
$page = new Page($pages, count($data2), count($data), $get['pageNum']);
$page->setUrl(Request::getQueryString());
$page->setPage();
$str_sql .= " ORDER BY s.sno DESC";
$str_sql .= " LIMIT " . $page->recode['start'] . ", " . $page->recode['limit'] . "";
$data2 = $db->query_fetch($str_sql);
$this->setData('data', $data2); // 리스트
$this->setData('search', $get); // 검색어
$this->setData('page', $page); // 페이징
//삭제 로직
if ($seum_post['mode'] === 'delete_state') {
$snoList = implode(",", array_map('intval', $post['sno']));
$strSQL = "UPDATE 테이블 이름 SET is_show = 'N' WHERE sno IN ({$snoList})";
$db->query($strSQL);
header("Location: seum_lyj.php");
exit();
}
} catch (\Exception $e) {
throw $e;
}
}
}
?>
Page에서 사용한 것들
1️⃣page
현재 페이지
2️⃣pageNum
출력할 버튼 갯수
3️⃣new Page();
(현재페이지, 검색 레코드 수, 총 레코드 수, 페이지당 출력할 갯수, 페이지 블록 갯수)
4️⃣Request::getQueryString()
요청 매개변수 정보를 가져오는 것 (key와 keyword, shopType 값을 의미한다고 볼 수 있다.)