입력필드를 범위로 검색

안녕하세요. 케이보드 감사히 잘 사용하고 있습니다.

list페이지에서 입력필드의 텍스트 값을 검색 가능하도록 하는 것은 찾아보며 해결했습니다.

검색 조건에 숫자 범위를 지정해서 범위에 해당하는 입력필드 숫자값을 가진 게시물들을 불러오려면 어떻게 해야할까요?

가격을 입력하는 '가격' 입력필드가 있고 메타키는 'meta_price' 라고 하면,

list페이지에서 최소가격과 최대가격을 셀렉트 박스로 선택해서 검색 가능하게 하려고 합니다.

커뮤니티 여러 글을 참고하며 아래까지 해보았는데 적용이 안됩니다 ㅜㅜ 

놓친 부분이 있을까요?

 

list.php

<?php $meta_price_start = isset($kboard_search_option['meta_price_start']['value']) ? $kboard_search_option['meta_price_start']['value'] : '';?>
<input type="hidden" name="kboard_search_option[meta_price_start][key]" value="meta_price_start">
<input type="hidden" name="kboard_search_option[meta_price_start][compare]" value=">=">
<select name="kboard_search_option[meta_price_start][value]">
    <option value="0">최소금액</option>
    <option value="0"<?php if($meta_price_start == '0'):?> selected<?php endif?>>0</option>
    <option value="10000"<?php if($meta_price_start == '10000'):?> selected<?php endif?>>1만</option>
    <option value="20000"<?php if($meta_price_start == '20000'):?> selected<?php endif?>>2만</option>
    <option value="200000"<?php if($meta_price_start == '200000'):?> selected<?php endif?>>20만</option>
</select>

<span> ~ </span>

<?php $meta_price_end = isset($kboard_search_option['meta_price_end']['value']) ? $kboard_search_option['meta_price_end']['value'] : '';?>
<input type="hidden" name="kboard_search_option[meta_price_end][key]" value="meta_price_end">
<input type="hidden" name="kboard_search_option[meta_price_end][compare]" value="<=">
<select name="kboard_search_option[meta_price_end][value]">
    <option value="">최대금액</option>
    <option value="10000"<?php if($meta_price_end == '10000'):?> selected<?php endif?>>1만</option>
    <option value="20000"<?php if($meta_price_end == '20000'):?> selected<?php endif?>>2만</option>
    <option value="200000"<?php if($meta_price_end == '200000'):?> selected<?php endif?>>20만</option>
    <option value="1000000000000"<?php if($meta_price_end == '1000000000000'):?> selected<?php endif?>>제한없음</option>
</select>

 

function.php

add_filter('kboard_list_where', 'kboard_list_where_20220815', 10, 3);
function kboard_list_where_20220815($where, $board_id, $content_list){

    if($content_list->is_latest && $board_id == '8'){ // 실제 게시판 id로 적용해주세요.
        $meta_price_start = $_GET['kboard_search_option'][meta_price_start][value];
        $meta_price_end = $_GET['kboard_search_option'][meta_price_end][value];

        $where .= " AND `meta_price` >= '{$meta_price_start}' AND `meta_price` <= '{$meta_price_end}' ";
    }

    return $where;
}

 

워드프레스 에러 기술지원 서비스 전문가에게 맡기세요
좋은 정보와 인맥을 동시에, 워드프레스 사용자 단톡방 참여하기
  • 안녕하세요~^^

    코드만 봤을때는 맞는 방향인 듯 합니다.

     

    남겨주신 코드 중

    if($content_list->is_latest && $board_id == '8'){
    

    부분을

    if($board_id == '8'){

    로 변경해서 해보시겠어요?

    고맙습니다.

  • 답변 감사드립니다. 수정해보았는데 검색이 잘 되지 않습니다 ㅜㅜ
    $where 를 출력해보니 아래처럼 나오는데요,

    'meta_price'는 입력필드 메타키로 있는 값이지만 'meta_price_start', 'meta_price_end'는 입력필드 메타키에 없지만 범위 설정을 위해 list.php에 임의로 넣은 값입니다.

    그런데 아래와같이 option_meta_price_end 로 검색을 하고 있고 이 부분 때문에 검색이 제대로 안되는 것 같습니다.

    `option_meta_price_end` 가 포함된 괄호가 검색 옵션값들이 들어가는 부분으로 이해했습니다.

    이곳에서 'meta_price_start', 'meta_price_end' 등 임의 값을 제외하려면 어떻게 해야하나요?

     

    `wp_kboard_board_content`.`board_id`='8'
    AND `wp_kboard_board_content`.`parent_uid`='0'
    AND (
        `option_meta_price_end`.`option_key`='meta_price_end'
        AND `option_meta_price_end`.`option_value` >= '10000000'
        )
    AND `wp_kboard_board_content`.`notice`=''
    AND (
        `wp_kboard_board_content`.`status` IS NULL
        OR `wp_kboard_board_content`.`status`=''
        OR `wp_kboard_board_content`.`status`='pending_approval'
        )
    AND `meta_price` >= '0'
    AND `meta_price` <= '10000000'

     

  • 출력된 where를 수정하여

    그대로 return 해주면 될 듯 합니다.

     

    아래 코드를 참고하여 적용해보시겠어요?

    function kboard_list_where_20220815($where, $board_id, $content_list){
    
        if($content_list->is_latest && $board_id == '8'){ // 실제 게시판 id로 적용해주세요.
            $meta_price_start = $_GET['kboard_search_option'][meta_price_start][value];
            $meta_price_end = $_GET['kboard_search_option'][meta_price_end][value];
    
            $where = "`wp_kboard_board_content`.`board_id`='8' AND `wp_kboard_board_content`.`parent_uid`='0' AND `wp_kboard_board_content`.`notice`='' AND (`wp_kboard_board_content`.`status` IS NULL OR `wp_kboard_board_content`.`status`='' OR `wp_kboard_board_content`.`status`='pending_approval') AND `meta_price` >= '{$meta_price_start}' AND `meta_price` <= '{$meta_price_end}'";
    	}
    
        return $where;
    }

    예상으로만 작성된 코드라 오류가 있을 수 있습니다.

    로직에 맞는지 확인하며 적용해보시겠어요?

    고맙습니다.

  • 답변해주셔서 감사합니다.

    몇 가지 에러가 있어서 방법을 찾아보며 아래와 같이 구성하니 결과값이 나오는 것 같습니다.

    가이드 해주신 코드와 다르다 보니 혹시 코드에 결함이 있거나 보안 위험이 있는지 한 번 살펴주시면 감사드리겠습니다.

    그리고 SELCET 부터의 전체 쿼리문을 보려면 어떻게 해야하는지 몰라서 DEBUG를 켜고 일부러 에러를 내면서 확인했는데 간편하게 확인할 수 있는 방법이 있는지요? 

     

    작성한 코드입니다. 

    list.php

    // 임의값 쿼리문에 자동 추가되지 않도록 변경
    // 1. name 등을 kboard_search_option[meta_price][value] 형식에서 meta_price[value] 형식으로 변경
    // 2. 첫줄 isset 부분에서 $_GET으로 조회하도록 변경 
    
    
    <?php $meta_price_start = isset($_GET['meta_price_start']['value']) ? $_GET['meta_price_start']['value'] : '';?>
    <input type="hidden" name="meta_price_start[key]" value="meta_price_start">
    <input type="hidden" name="meta_price_start[compare]" value=">=">
    <select name="meta_price_start[value]">
        <option value="">최소금액</option>
        <option value="0"<?php if($meta_price_start == '0'):?> selected<?php endif?>>0</option>
        <option value="10000"<?php if($meta_price_start == '10000'):?> selected<?php endif?>>1만</option>
        <option value="20000"<?php if($meta_price_start == '20000'):?> selected<?php endif?>>2만</option>
        <option value="200000"<?php if($meta_price_start == '200000'):?> selected<?php endif?>>20만</option>
    </select>
    
    <span> ~ </span>
    
    <?php $meta_price_end = isset($_GET['meta_price_end']['value']) ? $_GET['meta_price_end']['value'] : '';?>
    <input type="hidden" name="meta_price_end[key]" value="meta_price_end">
    <input type="hidden" name="meta_price_end[compare]" value=">=">
    <select name="meta_price_end[value]">
        <option value="">최대금액</option>
        <option value="10000"<?php if($meta_price_end == '10000'):?> selected<?php endif?>>1만</option>
        <option value="20000"<?php if($meta_price_end == '20000'):?> selected<?php endif?>>2만</option>
        <option value="200000"<?php if($meta_price_end == '200000'):?> selected<?php endif?>>20만</option>
        <option value="10000000"<?php if($meta_price_end == '10000000'):?> selected<?php endif?>>제한없음</option>
    </select>

    function.php - kboard_list_where

    // 1. 리스트 검색에 타이틀, 입력필드 값, 입력필드 범위 등 검색 조건이 많기 때문에 자동 구성 where절에 덧붙이는 .= 형식으로 적용
    // 2. 메타키 검색 코드를 AND `meta_price` >= '0' 형식에서 아래와 같이 변경
    // 3. 숫자값을 검색하므로 {$meta_price_start}를 감싸는 홑따옴표 제거
    
    
    add_filter('kboard_list_where', 'kboard_list_where_20220815', 10, 3);
    function kboard_list_where_20220815($where, $board_id, $content_list){
    
        if($board_id == '8'){ // 실제 게시판 id로 적용해주세요.
    
            // meta_price
            if (!empty($_GET['meta_price_start']['value'])) { $meta_price_start = $_GET['meta_price_start']['value']; }
            if (!empty($_GET['meta_price_end']['value'])) { $meta_price_end = $_GET['meta_price_end']['value']; }
    
            if (!empty($meta_price_start) && !empty($meta_price_end)) {
                $where .= " AND (";
                $where .= "(`option_meta_price`.`option_key`='meta_price' AND `option_meta_price`.`option_value` >= {$meta_price_start})";
                $where .= " AND (`option_meta_price`.`option_key`='meta_price' AND `option_meta_price`.`option_value` <= {$meta_price_end})";
                $where .= ")";
    
            } else if (!empty($meta_price_start)) {
                $where .= " AND (`option_meta_price`.`option_key`='meta_price' AND `option_meta_price`.`option_value` >= {$meta_price_start}) ";
            } else if (!empty($meta_price_end)) {
                $where .= " AND (`option_meta_price`.`option_key`='meta_price' AND `option_meta_price`.`option_value` <= {$meta_price_end}) ";
            }
    
        }
    
        return $where;
    }

    function.php - kboard_list_form

    // 검색시 list.php에 실제 메타키에 대한 input이 없고 임의값만 넘기기 때문에 `option_meta_pirce`등이 없다고 나옴. from절에서 입력필드 메타키에 대한 INNER JOIN 추가
    
    add_filter('kboard_list_from', 'kboard_list_from_20220815', 10, 3);
    function kboard_list_from_20220815($from, $board_id, $content_list){
        global $wpdb;
    
        if($board_id == '8'){
            if ( !empty($_GET['meta_price_start']['value']) ) { $meta_price_start = $_GET['meta_price_start']['value']; }
            if ( !empty($_GET['meta_price_end']['value']) ) { $meta_price_start = $_GET['meta_price_end']['value']; }
    
            if (!empty($meta_price_start) || !empty($meta_price_end)) {
                $from .= " INNER JOIN `{$wpdb->prefix}kboard_board_option` AS `option_meta_price` ON `{$wpdb->prefix}kboard_board_content`.`uid` = `option_meta_price`.`content_uid`";
            }
        }
        return $from;
    }

     

     

     

     

  • 경우를 세분화하여 쿼리를 작성하신 듯 합니다.

    나쁘지 않습니다.

     

    결과만 정상적으로 나온다면

    크게 문제는 없어보입니다.

    고맙습니다.

좋은 정보와 인맥을 동시에, 워드프레스 사용자 단톡방 참여하기