Изменение фильтра даты на странице администратора для настраиваемого типа записи для ссылки на настраиваемое поле


Приношу извинения, если подобный вопрос уже был задан, но я, похоже, не могу найти точную функциональность, которую ищу.

В основном у меня есть пользовательский тип сообщения (проповеди), который имеет "recorded_date" в качестве пользовательского поля метаданных. Что я хотел бы сделать на странице администратора пользовательских сообщений (где отображаются все сообщения), так это изменить существующее действие фильтра даты на фильтрацию по этому полю "recorded_date", а не по post_date, как это обычно делается. Мне удалось измениться раскрывающийся список фильтра даты с использованием следующего:

add_filter('months_dropdown_results', 'custom_date_dropdown');
function custom_date_dropdown($months){
        global $wpdb;
        $months = $wpdb->get_results("SELECT DISTINCT YEAR( meta_value ) AS year, 
        MONTH(meta_value) AS month FROM wp_postmeta 
        WHERE meta_key = 'recorded_date' ORDER BY meta_value DESC");
        return $months;
}

, который отлично работает. Но выбор любого значения и фильтрация фильтруют по post_date. Могу ли я в любом случае перехватить это поведение и изменить запрос фильтра на свой собственный пользовательский запрос? Или мне лучше удалить фильтр и добавить пользовательский с нуля?

Заранее спасибо за любую помощь.

Author: grahamt, 2015-05-29

1 answers

Используйте действие pre_get_posts, чтобы переопределить запрос по умолчанию. В администраторе запрос даты будет представлять собой запрос var m в формате YYYYMM. Предполагая, что ваши мета-даты хранятся так же, как даты MySQL (YYYY-MM-DD), вы можете использовать следующее:

function wpse_189824_date_meta_query( $wp_query ) {
    if ( is_admin() && $wp_query->is_main_query() && $wp_query->get( 'post_type' ) === 'sermons' ) {
        if ( $m = $wp_query->get( 'm' ) ) {
            $y = substr( $m, 0, 4 ); // Year
            $m = substr( $m, 4, 2 ); // Month

            if ( ! $meta_query = $wp_query->get( 'meta_query' ) ) // Keep meta query if there currently is one
                $meta_query = array();

            // Using LIKE query

            $meta_query[] = array(
                'key' => 'recorded_date',
                'value' => "$y-$m-%",
                'compare' => 'LIKE',
            );

            /*

            // OR using DATE

            $meta_query[] = array(
                'key' => 'recorded_date',
                'cast' => 'DATE',
                'value' => array( "$y-$m-01", "$y-$m-31" ),
                'compare' => 'BETWEEN',
            );

            */

            $wp_query->set( 'meta_query', $meta_query );
            $wp_query->set( 'm', null );
        }
    }
}

add_action( 'pre_get_posts', 'wpse_189824_date_meta_query' );

Я привел два варианта (LIKE или DATE), возможно, вы захотите протестировать и посмотреть, какой из них дает наилучшую производительность.

 3
Author: TheDeadMedic, 2019-11-21 00:36:44