web-dev-qa-db-fra.com

Filtrer la liste de publication par méta-valeur qui est une date

Cette question est presque ce que je suis en train d'essayer de réaliser. Créez un filtre pour les publications basées sur un champ personnalisé.

Mon champ personnalisé est une date et je voudrais créer un filtre de date (mensuel) basé sur ce champ personnalisé pour l'écran d'administration après publication.

Je n'utilise pas la date normale car il s'agit d'un site Web historique que je crée et dont certains articles ont été écrits il y a de nombreuses années.

5
stemie

Ajouter une variable de requête pour stocker le mois

Donc, tout d'abord, il sera nécessaire de créer une variable de requête personnalisée - elle stockera le format du mois après la fin de l'année (2012/6). Je l'appellerai custom_month, mais il est préférable de le préfixer pour éviter les conflits avec d'autres plug-ins:

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

Ajouter le menu déroulant

La variable de requête sera maintenant reconnue et toute valeur donnée stockée par WordPress dans la requête principale (global $wp_query).

Ensuite, nous créons le menu déroulant pour aller au sommet de la table post admin (ceci peut être changé pour n’importe quel type de post).

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;
    }
}

L'objet ci-dessus obtient un tableau de mois par mois et comprend:

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

Evidemment, wpse57344_get_months() n'existe pas en natif - nous le construirons plus tard.

En supposant avec un tableau de mois, nous créons le menu déroulant avec chaque option ayant la valeur de la forme yyyy/mm. J'ai donné au formulaire le même nom que la variable de requête que nous avons ajoutée}.

Modifier la requête

Lorsqu'un mois dans la liste déroulante est sélectionné, le mois dans yyyy/mm est enregistré en tant que valeur pour custom_month. Comme nous avons enregistré ce nom de variable auprès de WordPress, nous pouvons y accéder via $query->get('custom_month').

Donc, nous vérifions si c'est vide ou pas - si ce n'est pas le cas, alors nous nous limitons aux publications où se trouvent leurs métadonnées dans ce mois. Pour ce faire, nous utilisons une méta-requête et l'opérateur 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);
    }
}

Obtenez les mois

Il reste ensuite à définir la fonction wpse57344_get_months(). Nous devons interroger la table postmeta et choisir des mois distincts parmi les dates figurant dans la méta de vos publications. Dans ce qui suit, je suppose que votre date est stockée avec la clé 'customdate' et a le format (comme indiqué dans les commentaires) 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;
}

Cela retourne un tableau d'objets mois au format souhaité.

6
Stephen Harris