การขยายบริบทการค้นหาในหน้าจอโพสต์รายการผู้ดูแลระบบ


34

ฉันสร้างประเภทโพสต์ที่กำหนดเองและได้แนบฟิลด์ที่กำหนดเองไว้กับมัน ตอนนี้ฉันต้องการการค้นหาที่ผู้เขียนสามารถทำได้ในหน้าจอรายการโพสต์ที่กำหนดเอง (ในแบ็กเอนด์ผู้ดูแลระบบ) เพื่อดำเนินการในฟิลด์เมตาและไม่เพียง แต่ดูในชื่อและเนื้อหาตามปกติ

ฉันจะขอติดตั้งและใช้รหัสอะไรได้บ้าง

ภาพตัวอย่าง ป้อนคำอธิบายรูปภาพที่นี่

สเตฟาโน


1
คำถามที่เก่า but..i อยากจะแนะนำให้ที่อยู่อีเมลซ่อนและชื่อจากหน้าจอ ...
Erenor ลาปาซ

คำตอบ:


37

ฉันแก้ไขการกรองแบบสอบถามด้วยการเพิ่มการเข้าร่วมในตาราง postmeta และเปลี่ยนตำแหน่งคำสั่ง เคล็ดลับในการกรอง WHERE clause (มักต้องการการค้นหาและแทนที่ expression ปกติ) อยู่ที่นี่ใน codex :

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
โพสต์คำถามแยกต่างหากเกี่ยวกับการแก้ไขข้อบกพร่องของ dupe: wordpress.stackexchange.com/questions/111185/ …
jnthnclrk

สิ่งนี้และโพสต์ด้านล่างมีประโยชน์สำหรับฉัน ตอนนี้เพื่อหาวิธีในการรวมการค้นหาผู้เขียนโพสต์และแสดงการโพสต์โดยพวกเขา
Shawn Rebelo

@Stefano ผลการค้นหาใช้งานได้ มีปัญหาฟิลด์เริ่มต้น "โพสต์ชื่อ" บันทึกการค้นหาซ้ำหลายครั้งและด้านผู้ดูแลระบบ ดู: imgur.com/a/W4wmXhO
รุ่นซุปเปอร์

10

คำตอบของ Stefano นั้นยอดเยี่ยม แต่ไม่มีประโยคที่ชัดเจน:

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

การเพิ่มการตรวจสอบ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

มันไม่ใช่การค้นหา แต่บางอย่าง "เลือก" โดยค่าที่แตกต่าง

ในไฟล์function-iworks-posts-filter.zipคุณมีตัวอย่างวิธีการเพิ่มตัวกรองสำหรับการโพสต์ปกติโดยบาง meta_key ฉันคิดว่ามันง่ายที่จะแปลง


ขอบคุณสำหรับความช่วยเหลือ ... ฉันจะดูไฟล์แนบของคุณตอนนี้ ฉันจะแจ้งให้คุณทราบผลการสอบสวนของฉัน ;-) Stefano
Stefano

Marcin ฉันคิดว่าคุณกำลัง refferring ตัวกรองเช่น "ตามวันที่" ฯลฯ ... แต่ฉันต้องขอในช่อง "ค้นหาฟรี" ด้านบน อย่างไรก็ตามฉันเพิ่งโพสต์โซลูชันของฉันบางทีมันอาจช่วยได้
Stefano

0

รุ่นของรหัสที่นี่ในสองสามคำตอบที่ปรับเปลี่ยนพารามิเตอร์ meta_query ของ WP_Query ของการค้นหาใน pre_get_posts ไม่ได้ค้นหา post_title อีกต่อไป การเพิ่มความสามารถในการค้นหาทั้งชื่อโพสต์หรือค่าเมตาไม่สามารถทำได้โดยตรงใน WP_Query โดยไม่ต้องแก้ไข SQL โชคไม่ดีเนื่องจากคำถามนี้มีความละเอียดเมื่อ: การใช้แบบสอบถาม meta ('meta_query') กับคำค้นหา ('s)

ฉันได้รวมเทคนิคบางอย่างที่นี่เพื่อรับรุ่นทำงานที่หลีกเลี่ยง 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.