관리자 목록 게시 화면에서 검색 컨텍스트 확장


34

사용자 정의 게시물 유형을 만들고 여기에 일부 사용자 정의 필드를 첨부했습니다. 이제 저자가 사용자 정의 게시물 목록 화면 (관리자 백엔드)에서 메타 필드에서도 수행 할 수 있고 일반적인 제목과 내용 만 볼 수있는 검색을 원합니다.

어디에 연결하고 어떤 코드를 사용해야합니까?

이미지 예 여기에 이미지 설명을 입력하십시오

스테파노


1
오래된 질문이지만 ..i는 스크린 샷에서 이메일 주소와 이름을 숨기고 자합니다.
Erenor Paz

답변:


37

postmeta 테이블에 조인을 추가하고 where 절을 변경하여 쿼리 필터링을 해결했습니다. WHERE 절 필터링에 대한 팁 (종종 정규식 검색 및 교체 필요)은 코덱에 있습니다 .

add_filter( 'posts_join', 'segnalazioni_search_join' );
function segnalazioni_search_join ( $join ) {
    global $pagenow, $wpdb;

    // I want the filter only when performing a search on edit page of Custom Post Type named "segnalazioni".
    if ( is_admin() && 'edit.php' === $pagenow && 'segnalazioni' === $_GET['post_type'] && ! empty( $_GET['s'] ) ) {    
        $join .= 'LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }
    return $join;
}

add_filter( 'posts_where', 'segnalazioni_search_where' );
function segnalazioni_search_where( $where ) {
    global $pagenow, $wpdb;

    // I want the filter only when performing a search on edit page of Custom Post Type named "segnalazioni".
    if ( is_admin() && 'edit.php' === $pagenow && 'segnalazioni' === $_GET['post_type'] && ! empty( $_GET['s'] ) ) {
        $where = preg_replace(
            "/\(\s*" . $wpdb->posts . ".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(" . $wpdb->posts . ".post_title LIKE $1) OR (" . $wpdb->postmeta . ".meta_value LIKE $1)", $where );
    }
    return $where;
}

1
와우! 내가 찾던 것. 그러나 게시물 제목을 검색 할 때 버그가 발견되어 일치하는 결과가 5 번 중복됩니다!?! imgur.com/eE52gIA
jnthnclrk

다음은 SQL을 인쇄 한 또 다른 방법입니다. tinypic.com/view.php?pic=124tqb6&s=5 5 개의 항목을 얻는 이유를 알 수 없습니다!?!
jnthnclrk

1
다음 속는 버그 수정에 별도의 질문을 게시 wordpress.stackexchange.com/questions/111185/...
jnthnclrk을

이 게시물과 아래 게시물은 나에게 유용했습니다. 이제 게시물 작성자를 검색하여 게시물을 표시하는 방법을 찾으십시오.
Shawn Rebelo

@ 스테파노, 검색 결과가 작동합니다. 기본 필드 "게시물 제목", 검색 레코드가 여러 번 반복되고 관리자 측에 문제가 있습니다. 참조 : imgur.com/a/W4wmXhO
슈퍼 모델

10

스테파노의 대답은 훌륭하지만 별개의 절이 없습니다.

function segnalazioni_search_distinct( $where ){
    global $pagenow, $wpdb;

    if ( is_admin() && $pagenow=='edit.php' && $_GET['post_type']=='segnalazioni' && $_GET['s'] != '') {
    return "DISTINCT";

    }
    return $where;
}
add_filter( 'posts_distinct', 'segnalazioni_search_distinct' );

위의 코드를 업데이트하면 중복없이 작동합니다.


7

이 작동합니다

function custom_search_query( $query ) {
    $custom_fields = array(
        // put all the meta fields you want to search for here
        "rg_first_name",
        "rg_1job_designation"
    );
    $searchterm = $query->query_vars['s'];

    // we have to remove the "s" parameter from the query, because it will prevent the posts from being found
    $query->query_vars['s'] = "";

    if ($searchterm != "") {
        $meta_query = array('relation' => 'OR');
        foreach($custom_fields as $cf) {
            array_push($meta_query, array(
                'key' => $cf,
                'value' => $searchterm,
                'compare' => 'LIKE'
            ));
        }
        $query->set("meta_query", $meta_query);
    };
}
add_filter( "pre_get_posts", "custom_search_query");

1
탄원은 코드를 올바르게 들여 쓰고, 왜 그리고 어떻게 작동 하는지에 대한 설명을 포함합니다 .
tfrommen

처음에 그것을 상향 조정했지만 불행히도 이것이 모든 검색에서 작동하므로 프런트 엔드 검색이 중단 될 수 있음을 깨달았습니다.
Maciej Paprocki 2016 년

if ( $query->query['post_type'] != 'your_custom_post_type' ){ return; }함수 상단에 체크 표시를 추가하면 다른 검색에서이 기능이 실행되지 않습니다. 이 답변의 기술은 더 이상 post_title을 검색하지 않으며 다시 추가하는 것이 쉽지 않습니다.
jwinn

하나 더 문제 - 표시등 "<키워드>"에 대한 검색 결과 호출을 get_search_query()더 통화 get_query_var( 's' ). "s"가 빈 문자열로 설정되어 있으므로 ""에 대한 검색 결과 는 항상 따옴표 사이에 빈 값을 갖습니다. 이 문제를 해결하는이 솔루션에 대한 조정이 있습니까?
jschrab

1

답변 1 : 이 코드를 함수 파일에 추가하고 사용자 정의 게시물 유형에 사용한 열 이름을 변경하고 추가하십시오.

function extend_admin_search( $query ) {

    // use your post type
    $post_type = 'document';
    // Use your Custom fields/column name to search for
    $custom_fields = array(
        "_file_name",
    );

    if( ! is_admin() )
        return;

    if ( $query->query['post_type'] != $post_type )
        return;

    $search_term = $query->query_vars['s'];

    // Set to empty, otherwise it won't find anything
    $query->query_vars['s'] = '';

    if ( $search_term != '' ) {
        $meta_query = array( 'relation' => 'OR' );

        foreach( $custom_fields as $custom_field ) {
            array_push( $meta_query, array(
                'key' => $custom_field,
                'value' => $search_term,
                'compare' => 'LIKE'
            ));
        }

        $query->set( 'meta_query', $meta_query );
    };
}

add_action( 'pre_get_posts', 'extend_admin_search' );

답변 2 : 권장 사항 이 코드를 기능 파일에서 변경없이 사용하십시오

function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );

0

검색이 아니라 고유 한 값으로 "선택"됩니다.

functions-iworks-posts-filter.zip 파일 에 일부 meta_key로 일반 게시물에 대한 필터를 추가하는 방법에 대한 예제가 있습니다. 변환하기 쉽다고 생각합니다.


도와 주셔서 감사합니다 ... 지금 당신의 첨부 파일을 살펴 보겠습니다. 조사 결과를 알려 드리겠습니다 ;-) Stefano
Stefano

Marcin "날짜 별"과 같은 필터를 참조한다고 생각하지만 위의 "무료 검색"필드에 연결해야합니다. 어쨌든 방금 솔루션을 게시했습니다. 어쨌든 감사합니다.
Stefano

0

pre_get_posts에서 검색 WP_Query의 meta_query 매개 변수를 수정하는 몇 가지 답변의 코드 버전이 더 이상 post_title을 검색하지 않았습니다. 검색 할 수있는 기능 중 하나 게시물 제목을 추가, 또는 메타 값에이 질문에 정성 들여으로, 불행하게도 SQL을 수정하지 않고 WP_Query에서 직접 수행 할 수 없습니다 ( 'S') 검색 쿼리 메타 쿼리 ( 'meta_query')를 사용하여

preg_replaces 및 너무 많은 SQL 수정을 피하는 작동 버전을 얻기 위해 여기에 몇 가지 기술을 결합했습니다 (전적으로 피할 수 있기를 바랍니다). 유일한 단점은 검색 후 페이지 상단의 자막 텍스트에 "검색 결과 ''"가 있다는 것입니다. 플러그인의 사용자 정의 게시물 유형에 CSS를 사용하여 숨겼습니다.

/**
 * Extend custom post type search to also search meta fields
 * @param  WP_Query $query
 */
function extend_cpt_admin_search( $query ) {
  // Make sure we're in the admin area and that this is our custom post type
  if ( !is_admin() || $query->query['post_type'] != 'your_custom_post_type' ){
    return;
  }

  // Put all the meta fields you want to search for here
  $custom_fields = array(
    "your_custom_meta_field",
    "your_custom_meta_field2",
    "your_custom_meta_field3"
  );
  // The string submitted via the search form
  $searchterm = $query->query_vars['s'];

  // Set to empty, otherwise no results will be returned.
  // The one downside is that the displayed search text is empty at the top of the page.
  $query->query_vars['s'] = '';

  if ($searchterm != ""){
    // Add additional meta_query parameter to the WP_Query object.
    // Reference: https://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
    $meta_query = array();
    foreach($custom_fields as $cf) {
      array_push($meta_query, array(
        'key' => $cf,
        'value' => $searchterm,
        'compare' => 'LIKE'
      ));
    }
    // Use an 'OR' comparison for each additional custom meta field.
    if (count($meta_query) > 1){
      $meta_query['relation'] = 'OR';
    }
    // Set the meta_query parameter
    $query->set('meta_query', $meta_query);


    // To allow the search to also return "OR" results on the post_title
    $query->set('_meta_or_title', $searchterm);
  }
}
add_action('pre_get_posts', 'extend_cpt_admin_search');



/**
 * WP_Query parameter _meta_or_title to allow searching post_title when also
 * checking searching custom meta values
 * https://wordpress.stackexchange.com/questions/78649/using-meta-query-meta-query-with-a-search-query-s
 * https://wordpress.stackexchange.com/a/178492
 * This looks a little scary, but basically it's modifying the WHERE clause in the 
 * SQL to say "[like the post_title] OR [the existing WHERE clause]"
 * @param  WP_Query $q
 */
function meta_or_title_search( $q ){
  if( $title = $q->get( '_meta_or_title' ) ){
    add_filter( 'get_meta_sql', function( $sql ) use ( $title ){
      global $wpdb;

      // Only run once:
      static $nr = 0;
      if( 0 != $nr++ ) return $sql;

      // Modified WHERE
      $sql['where'] = sprintf(
          " AND ( (%s) OR (%s) ) ",
          $wpdb->prepare( "{$wpdb->posts}.post_title LIKE '%%%s%%'", $title),
          mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
      );

      return $sql;
    });
  }
}
add_action('pre_get_posts', 'meta_or_title_search');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.