stefano
  • 0
Новичок

Расширение контекста поиска на экране поста со списком администраторов

  • 0

Я создал пользовательский тип записи и прикрепил к нему несколько настраиваемых полей. Теперь я хотел бы, чтобы поиск, который авторы могут выполнять на экране пользовательского списка сообщений (в админке), также выполнялся в метаполях, а не только в заголовке и содержании, как обычно.

Где я могу подключиться и какой код я должен использовать?

Пример изображения введите описание изображения здесь

Стефано

Share
  1. Старый вопрос, но я хотел бы предложить скрыть адреса электронной почты и имена со скриншотов…

    • 0
  2. Я решил отфильтровать запрос, добавив соединение в таблицу 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 );
            $where.= " GROUP BY {$wpdb->posts}.id"; // Solves duplicated results
        }
        return $where;
    }
    
    • 0
  3. Ответ Стефано великолепен, но ему не хватает отдельного пункта:

    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' );
    

    Добавьте приведенный выше код, обновите его, и он будет работать без дубликатов.

    • 0
  4. Это сработает,

    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");
    
    • 0
  5. Ответ 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
  6. С помощью этого кода вы можете выполнять поиск в списке сообщений в панели администратора WordPress с пользовательскими мета — значениями сообщений, а также с заголовком и другими полями по умолчанию.

    Пожалуйста, добавьте следующий код в файл functions.php:

    if (!function_exists('extend_admin_search')) {
        add_action('admin_init', 'extend_admin_search');
    
        /**
         * hook the posts search if we're on the admin page for our type
         */
        function extend_admin_search() {
            global $typenow;
    
            if ($typenow === 'your_custom_post_type') {
                add_filter('posts_search', 'posts_search_custom_post_type', 10, 2);
            }
        }
    
        /**
         * add query condition for custom meta
         * @param string $search the search string so far
         * @param WP_Query $query
         * @return string
         */
        function posts_search_custom_post_type($search, $query) {
            global $wpdb;
    
            if ($query->is_main_query() && !empty($query->query['s'])) {
                $sql    = "
                or exists (
                    select * from {$wpdb->postmeta} where post_id={$wpdb->posts}.ID
                    and meta_key in ('custom_field1','custom_field2')
                    and meta_value like %s
                )
            ";
                $like   = '%' . $wpdb->esc_like($query->query['s']) . '%';
                $search = preg_replace("#\({$wpdb->posts}.post_title LIKE [^)]+\)\K#",
                    $wpdb->prepare($sql, $like), $search);
            }
    
            return $search;
        }
    }
    
    • 0
  7. Это не поиск, а какая-то «выборка» по особому значению.

    В файле functions-iworks-posts-filter.zip у вас есть пример, как добавить фильтр для обычного поста по некоторому мета_ключу. Я думаю, что это легко преобразовать.

    • 0
  8. Версия кода здесь в паре ответов, которая изменяет параметр meta_query WP_Query поиска в pre_get_posts, больше не выполняла поиск post_title. Добавление возможности поиска либо по заголовку сообщения, либо по мета-значениям не может быть выполнено непосредственно в WP_Query без изменения SQL, к сожалению, поскольку этот вопрос уточняется: использование мета-запроса (‘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');
    
    • 0

Оставить ответ

You must login to add an answer.