व्यवस्थापक सूची पोस्ट स्क्रीन में खोज प्रसंग का विस्तार


34

मैंने एक कस्टम पोस्ट प्रकार बनाया है और इसमें कुछ कस्टम फ़ील्ड संलग्न किए हैं। अब मैं यह खोज करना चाहूंगा कि लेखक कस्टम पोस्ट सूची स्क्रीन (एडमिन बैकएंड पर) में भी मेटा फ़ील्ड पर प्रदर्शन कर सकते हैं और न केवल शीर्षक और सामग्री में हमेशा की तरह देख सकते हैं।

मैं कहां हुक कर सकता हूं और मुझे किस कोड का उपयोग करना होगा?

उदाहरण छवि यहाँ छवि विवरण दर्ज करें

Stefano


1
एक पुराना प्रश्न, लेकिन..मैं स्क्रीनशॉट से ईमेल पते और नामों को छिपाने का सुझाव देना चाहूंगा ...
इरेनर पाज़

जवाबों:


37

मैंने पोस्टमेटा टेबल पर जॉइन को जोड़कर और जहां क्लॉज को बदलकर क्वेरी को फ़िल्टर करने का हल किया। 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


यह और नीचे की पोस्ट मेरे लिए उपयोगी थी। अब पोस्ट लेखक की खोज को शामिल करने और उनके द्वारा किए गए पोस्ट दिखाने का एक तरीका खोजने के लिए।
शॉन रेबेलो

@Stefano, खोज परिणाम काम कर रहा है। एक मुद्दा है, डिफ़ॉल्ट फ़ील्ड "पोस्ट शीर्षक", खोज रिकॉर्ड कई बार और व्यवस्थापक पक्ष दोहरा रहा है। देखें: 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

हालाँकि मैंने पहली बार इसे उतारा, लेकिन मुझे एहसास हुआ कि दुर्भाग्य से, यह हर खोज पर काम करेगा, यह आगे के अंत की खोज को तोड़ सकता है।
मकीज पपरोकी

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

यह एक खोज नहीं है, लेकिन कुछ अलग-अलग मूल्य से "चयन" करते हैं।

फ़ाइल फ़ंक्शंस में-iworks-posts-filter.zip आपके पास एक उदाहरण है कि कुछ मेटा_की द्वारा नियमित पोस्ट के लिए फ़िल्टर कैसे जोड़ा जाए। मुझे लगता है कि इसे रूपांतरित करना आसान है।


मदद के लिए धन्यवाद ... मैं अभी आपके अटैचमेंट को देखने जा रहा हूं। मैं आपको अपनी जांच के परिणाम बताऊंगा ;-) स्टेफानो
स्टेफानो

मार्सिन मुझे लगता है कि आप "जैसे तारीख" आदि के लिए फ़िल्टर के लिए फिर से विचार कर रहे हैं ... लेकिन मुझे ऊपर "मुफ्त खोज" फ़ील्ड में हुक करने की आवश्यकता है। वैसे भी मैंने अभी अपना समाधान पोस्ट किया है, शायद यह वैसे भी धन्यवाद करने में मदद करता है!
स्टेफानो

0

एक जोड़े में यहां कोड का संस्करण उत्तर देता है कि खोज के WP_Query के मेटा_क्वेरी पैरामीटर को पूर्व__तोस्तों में बदल देता है जो अब post_title नहीं खोज रहा था। पोस्ट शीर्षक, या मेटा मानों की खोज करने की क्षमता को जोड़ने से SQL को दुर्भाग्य से संशोधित किए बिना सीधे WP_Query में नहीं किया जा सकता है, क्योंकि यह प्रश्न इस पर विस्तृत करता है: खोज क्वेरी ('s') के साथ मेटा क्वेरी ('मेटा_क्वेरी') का उपयोग करना।

मैंने यहाँ कुछ तकनीकों को संयोजित किया है ताकि एक कार्यशील संस्करण प्राप्त किया जा सके जो preg_replaces और बहुत अधिक SQL संशोधन से बचता है (काश यह पूरी तरह से टाला जा सके)। केवल नकारात्मक पक्ष यह है कि खोज के बाद, पृष्ठ के शीर्ष पर उपशीर्षक पाठ "" के लिए खोज परिणाम "" कहता है। मैं अपने प्लगइन के कस्टम पोस्ट प्रकार के लिए सीएसएस के साथ छिपा हुआ हूं।

/**
 * 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');
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.