web-dev-qa-db-ja.com

日付であるメタ値で投稿の一覧を絞り込む

この質問 はImが達成しようとしていることのほとんどです。カスタムフィールドに基づいて投稿用のフィルタを作成します。

私のカスタムフィールドは日付であり、私は投稿リスト管理画面のためにこのカスタムフィールドに基づいて日付フィルター(毎月)を作成したいと思います。

これは私が作成した歴史的なウェブサイトであり、いくつかの投稿は何年も前のものであるため、私は通常の日付を使用していません。

5
stemie

月を格納するためのクエリ変数を追加します。

したがって、まず最初にカスタムクエリ変数を作成する必要があります。これには、(2012年/ 6年に)フォーマットした後の月が格納されます。 custom_monthと呼びますが、他のプラグインとの衝突を避けるために接頭辞を付けることをお勧めします。

add_filter('query_vars', 'wpse57344_register_query_vars' );
function wpse57344_register_query_vars( $qvars ){
    //Add these query variables
    $qvars[] = 'custom_month';
    return $qvars;
}

ドロップダウンを追加する

これで、クエリ変数が認識され、与えられた値がメインのクエリ(グローバル$wp_query)にWordPressによって保存されます。

次に、投稿管理テーブルの一番上にドロップダウンリストを作成します(これは任意の投稿タイプに変更できます)。

add_action( 'restrict_manage_posts', 'wpse57344_restrict_posts_by_metavalue' );
function wpse57344_restrict_posts_by_metavalue() {
    global $typenow;
    $months = wpse57344_get_months();
    if ($typenow == 'post') {
        $selected = get_query_var('custom_month');
        $output = "<select style='width:150px' name='custom_month' class='postform'>\n";
        $output .= '<option '.selected($selected,0,false).' value="">'.__('Show All','wpse57344_plugin').'</option>';
        if ( ! empty( $months ) ) {
            foreach ($months as $month):
                $value =esc_attr($month->year.'/'.$month->month);
                $month_dt = new DateTime($month->year.'-'.$month->month.'-01');
                $output .= "<option value='{$value}' ".selected($selected,$value,false).'>'.$month_dt->format('F Y').'</option>';
            endforeach; 
        }
        $output .= "</select>\n";       
    echo $output;
    }
}

上記は、月オブジェクトが構成される月の配列を取得します。

year => //the year of the month e.g. 2012
month => //the number of the month, e.g. 6 for July
posts => //number of posts with the date meta value in this month

明らかにwpse57344_get_months()はネイティブには存在しません - 後で構築します。

月の配列を想定して、各オプションがyyyy/mmという形式の値を持つドロップダウンを作成します。 という形式で、追加したクエリ変数と同じ名前 を付けました。

クエリを変更する

ドロップダウンの月が選択されると、yyyy/mmの月がcustom_monthの値として転記されます。この変数名はWordPressに登録されているので、$query->get('custom_month')を通してアクセスできます。

そのため、空かどうかを確認します。空でない場合は、その月のメタ値データがある投稿に限定します。そのためにはメタクエリとBETWEEN演算子を使います。

add_action( 'pre_get_posts', 'wpse57351_pre_get_posts' );
function wpse57351_pre_get_posts( $query ) {

    //Only alter query if custom variable is set.
    $month_str = $query->get('custom_month');
    if( !empty($month_str) ){

            //For debugging, uncomment following line
            //var_dump($query);

        //Be careful not override any existing meta queries.
        $meta_query = $query->get('meta_query');
        if( empty($meta_query) )
            $meta_query = array();

        //Convert 2012/05 into a datetime object get the first and last days of that month in yyyy/mm/dd format
        $month = new DateTime($month_str.'/01');

        //Get posts with date between the first and last of given month
        $meta_query[] = array(
            'key' => 'customdate',
            'value' => array($month->format('Y/m/d'),$month->format('Y/m/t')),
            'compare' => 'BETWEEN',
        );
        $query->set('meta_query',$meta_query);

            //For debugging, uncomment following line
            //var_dump($query);
    }
}

月を取得する

その場合は、関数wpse57344_get_months()を定義する必要があります。私たちはpostmetaテーブルを検索し、あなたの投稿のメタの日付から異なる月を選ぶ必要があります。以下では、私はあなたの日付がキー 'customdate'で保存され、(コメントに示されているように)yyyy/mm/ddというフォーマットを持っていると仮定します。

function wpse57344_get_months(){
    global $wpdb;
        $months = wp_cache_get( 'wpse57344_months' );
        if ( false === $months ) {
            $query = "SELECT YEAR(meta_value) AS `year`, MONTH(meta_value) AS `month`, count(post_id) as posts 
                FROM $wpdb->postmeta WHERE meta_key ='customdate'           
                GROUP BY YEAR(meta_value), MONTH(meta_value) ORDER BY meta_value DESC";
            $months = $wpdb->get_results($query);
            wp_cache_set( 'wpse57344_months', $months );
        }
        return $months;
}

これは、月オブジェクトの配列を目的の形式で返します。

6
Stephen Harris