compte les publications de termes de taxonomie personnalisés par année

4

Je souhaite créer des tableaux de type statistique contenant le nombre de messages dans des termes de taxonomie personnalisés et les afficher par année, ainsi que le nombre total de messages de cette année.

Par exemple:

  

2014

     

| _Taxonomie Terme A: 8 messages

     

| _ Taxonomie Terme B: 12 articles

     

Nombre total de messages en 2014: 20 messages

.

La fonction doit évidemment effectuer les opérations suivantes:

  • comptez les messages de mon type personnalisé postés publiés en 2014, 2013, ... (nombre total par an)
  • compter les postes dans chaque terme de taxonomie à partir de my-custom-taxonomy sur la base annuelle

Pour créer une liste dynamique pour les années , j'ai utilisé un extrait de code que j'ai trouvé quelque part et qui ressemble à ceci:

function posts_by_year() {
  // array to use for results
  $years = array();

  // get posts from WP
  $posts = get_posts(array(
    'numberposts' => -1,
    'orderby' => 'post_date',
    'order' => 'ASC',
    'post_type' => 'my-custom-post-type',
    'post_status' => 'publish'
  ));

  // loop through posts, populating $years arrays
  foreach($posts as $post) {
    $years[date('Y', strtotime($post->post_date))][] = $post;
  }

  // reverse sort by year
  krsort($years);
  return $years;
}

Dans mon modèle de page personnalisé, j'utilise:

<?php foreach(posts_by_year() as $year => $posts) : ?>
<h2><?php echo $year; ?></h2>
// the code that I need to display the post counts per year
<?php endforeach; ?>

Ma question est la suivante:

Comment est-ce que je construis wp_query pour pouvoir générer le nombre de posts par terme de taxonomie par an? Je serais si heureux si quelqu'un m'aidait à résoudre ce problème.

PS: J'ai déjà une table qui compte TOUS les articles publiés de my-custom-post-type par terme de taxonomie, j'ai trouvé de l'aide ici et a utilisé le code de deflime.

Modifier:

Voici l'extrait de Pieter Goosen avec mes modifications:

$oldest = get_posts( 'post_type=my-custom-post-type&post_status=publish&posts_per_page=1&order=ASC' );
$oldest_date = $oldest[0]->post_date;

$first_date = date('Y', strtotime($oldest_date));
$todays_date = date('Y');

$year_range = range($todays_date, $first_date);

foreach ($year_range as $year) { // dynamic year-based tables
    echo '<h2>' . $year . '</h2>';
    $terms = get_terms('my-custom-taxonomy');
    $total_posts = 0;

    if ( !empty( $terms ) && !is_wp_error( $terms ) ) { // table body

        echo '
            <table class="statistics">
            <tbody>
            ';
        echo '
            <thead>
                <tr>
                    <td>Taxonomy Term</td>
                    <td>Percentage</td>
                    <td class="chart-count">Count</td>
                </tr>
            </thead>
            ';
        echo '
            <tfoot>
                <tr>
                <td colspan="2">Posts total</td>
                <td class="chart-count">'.$total_posts.'</td>
                </tr>
            </tfoot>
            ';

        foreach ( $terms as $term ) { // setup table <tr> per taxonomy term
            $args = array(
                'posts_per_page'    => -1,
                'post_type'         => 'my-custom-post-type',
                'post_status'       => 'publish',
                'year'              => $year,
                'tax_query' => array(
                    array(
                        'taxonomy' => 'my-custom-taxonomy',
                        'field'    => 'slug',
                        'terms'    => $term->slug
                    ),
                ),
            );

            $total_posts += $term->count;
            // Get  %, round to 2 decimal places
            $percentage = round( (($yearly_posts_per_term->post_count / $total_posts)*100), 2 );
            // will add up to 100 at the end?
            $total_check += $percentage;

            $yearly_posts_per_term = new WP_Query($args);

            echo '
                <tr>
                    <td class="chart-item">'.$term->name.'</td>
                    <td class="chart-visual"><div class="chart-bar" style="width:'.$percentage.'%;"></div> '.$percentage.'%</td>
                    <td class="chart-count">'.$yearly_posts_per_term->post_count.'</td>
                </tr>
            ';

        } // endforeach
        echo '
            </tbody>
            </table>
            '; 
    } //end of table
} // end of year-based list
    
posée okiedokey 11.08.2014 - 11:58

3 réponses

4

EDIT 2

Voici une autre version du code dans EDIT 1 . Ce code est beaucoup plus rapide. Voici mon test entre le code dans EDIT 1 et EDIT 2

  • EDIT 1 heure d'interrogation de la base de données = +/- 0,25 et interrogations de la base de données = 69

  • EDIT 2 heure d'interrogation de la base de données = +/- 0.07 et interrogations de la base de données = 29

Voici le code

<?php

 $oldest = get_posts( 'post_type=post&post_status=publish&posts_per_page=1&order=ASC' );
    $oldest_date = $oldest[0]->post_date;

    $first_date = date('Y', strtotime($oldest_date));
    $todays_date = date('Y');

    $year_range = range($todays_date, $first_date);

    foreach ($year_range as $year) { // dynamic year-based tables
        echo '<h2>' . $year . '</h2>';
        $terms = get_terms('category');

        $term_slugs = array();

        if ( !empty( $terms ) && !is_wp_error( $terms ) ) { // table body

            foreach ( $terms as $key=>$term){
                $term_slugs[$key] = $term->slug;
            }

            echo '
                <table class="statistics">
                <tbody>
                ';
            echo '
                <thead>
                    <tr>
                        <td>Taxonomy Term</td>
                        <td>Percentage</td>
                        <td class="chart-count">Count</td>
                    </tr>
                </thead>
                ';

            $posts_count = array(); // Holds all term post counts in an array
            $terms_array = array();  // Holds all term names in an array 

                $args = array(
                    'posts_per_page'    => -1,
                    'post_type'         => 'post',
                    'post_status'       => 'publish',
                    'year'              => $year,
                    'tax_query' => array(
                        array(
                            'taxonomy'          => 'category',
                            'field'             => 'slug',
                            'terms'             => $term_slugs,
                            'include_children'  => false 
                        ),
                    ),
                );

                $yearly_posts_per_term = new WP_Query($args);
                    $posts_count[] = $yearly_posts_per_term->post_count; //Collects post counts and send them to an array

                if($yearly_posts_per_term->have_posts()):
                    while($yearly_posts_per_term->have_posts()): $yearly_posts_per_term->the_post();

                        $terms = get_the_terms( $post->ID, 'category' );

                        if ( $terms && ! is_wp_error( $terms ) ) {
                            foreach ( $terms as $term ) {
                                $terms_array[] = $term->slug;
                            }
                        } 

                    endwhile;
                endif;

        }

        $total_posts = array_sum($posts_count); //Use array_sum to add up all the separate post counts

        $result = array_count_values($terms_array);

        foreach ($result as $term_name=>$count) {

            $percentage = round( (($count / $total_posts)*100), 2 ); //Calculate the percentages of each term post cound to total year post count

            echo '
                    <tr>
                        <td class="chart-item">'.$term_name.'</td>
                        <td class="chart-visual"><div class="chart-bar" style="width:'.$percentage.'%;"></div> '.$percentage.'%</td>
                        <td class="chart-count">'.$count.'</td>
                    </tr>
                ';
        }   

            echo '
                <tfoot>
                    <tr>
                    <td colspan="2">Posts total</td>
                    <td class="chart-count">'.$total_posts.'</td>
                    </tr>
                </tfoot>
                ';

            echo '
                </tbody>
                </table>
                '; 
    } // end of year-based list

?>

Ceci restitue le même résultat que le tableau dans EDIT 1 , sauf qu'il ne montre pas les termes vides, seuls les termes avec posts sont affichés

.

MODIFIER1

Devotrequestionmodifiée,voicilabandedunouveaucode.J'aidûsupprimeruneoudeuxchosesicietréorganisercertainsélémentspourquecelafonctionne.Legranddéficonsistaitalorsàcalculerlespourcentages,carlesvariablesutiliséespourlecalculervivaientdansdesbouclesforeachdistinctes.Lesvariablesdanslesbouclesforeachneviventquedanscetteforeach,etnonpasendehors

Lesmodificationsimportantesapportéesaucode(àpartirdemaréponseoriginale,[email protected]égré)depuisvotreéditionsont

  • Déplacementdesdeuxtablescontenantlenombretotaldepublications,ainsiquelespourcentagesetlesnomsdetermes,justeen-dessousdu$termsforeachloop

  • Transférerlesnomsetpublicationsdetermesdechaquetermedansuntableausituéendehorsdelaboucle$termsforeach

  • [email protected],suppressionde$total_posts=0;etconservationetmodificationuniquementde$percentage=round((($yearly_posts_per_term->post_count/$total_posts)*100),2);

  • Utilisé array_sum pour obtenir le nombre total de publications pour l'année à partir du tableau des comptes de postes par terme

  • Utilisé array_combine pour créer un tableau associatif avec les noms de terme et publier des comptes pour chaque terme

  • Enfin, j'ai utilisé une boucle foreach pour obtenir chaque nom de terme et le nombre de publications associé, pour les intégrer dans la table

Voici le code final

<?php

 $oldest = get_posts( 'post_type=post&post_status=publish&posts_per_page=1&order=ASC' );
    $oldest_date = $oldest[0]->post_date;

    $first_date = date('Y', strtotime($oldest_date));
    $todays_date = date('Y');

    $year_range = range($todays_date, $first_date);

    foreach ($year_range as $year) { // dynamic year-based tables
        echo '<h2>' . $year . '</h2>';
        $terms = get_terms('category');

        if ( !empty( $terms ) && !is_wp_error( $terms ) ) { // table body

            echo '
                <table class="statistics">
                <tbody>
                ';
            echo '
                <thead>
                    <tr>
                        <td>Taxonomy Term</td>
                        <td>Percentage</td>
                        <td class="chart-count">Count</td>
                    </tr>
                </thead>
                ';

            $posts_count = array(); // Holds all term post counts in an array
            $term_names = array();  // Holds all term names in an array

            foreach($terms as $term) {
                $term_names[] = $term->name; //Collects term names and send them to an array

                $args = array(
                    'posts_per_page'    => -1,
                    'post_type'         => 'post',
                    'post_status'       => 'publish',
                    'year'              => $year,
                    'tax_query' => array(
                        array(
                            'taxonomy'          => 'category',
                            'field'             => 'slug',
                            'terms'             => $term->slug,
                            'include_children'  => false 
                        ),
                    ),
                );

                $yearly_posts_per_term = new WP_Query($args);
                    $posts_count[] = $yearly_posts_per_term->post_count; //Collects post counts and send them to an array

            } // endforeach

            unset($term);

        }

        $total_posts = array_sum($posts_count); //Use array_sum to add up all the separate post counts

        $combine = array_combine($term_names,$posts_count); //Use array_combine to combine term names and post counts into assosiative array

        foreach ($combine as $term_name=>$count) {

            $percentage = round( (($count / $total_posts)*100), 2 ); //Calculate the percentages of each term post cound to total year post count

            echo '
                    <tr>
                        <td class="chart-item">'.$term_name.'</td>
                        <td class="chart-visual"><div class="chart-bar" style="width:'.$percentage.'%;"></div> '.$percentage.'%</td>
                        <td class="chart-count">'.$count.'</td>
                    </tr>
                ';
        }   

            echo '
                <tfoot>
                    <tr>
                    <td colspan="2">Posts total</td>
                    <td class="chart-count">'.$total_posts.'</td>
                    </tr>
                </tfoot>
                ';

            echo '
                </tbody>
                </table>
                '; 
    } // end of year-based list

?>

Remarque Comme dans ma réponse d'origine, j'ai modifié le type de publication en post et la taxonomie en category aux fins de test.

Votre résultat final est une table ressemblant à ceci. Veuillez noter Tous les noms de mes termes sont en afrikaans comme je l'ai testé sur mon site de test en afrikaans.

RÉPONSEORIGINALE

Ceciestuneébauchetrèsbrèved'uneidéequej'avaissurlafaçondeprocéder.Jen'aiinclusaucunebaliseHTMLetutiliséletypedemessagepardéfautpostetlataxonomieintégréecategorypourtesterlecode.

Voicicommentj'aiconstruitlarequêtecomplète

  • Toutd’abord,obtenezladatedumessageleplusancien(lepremiermessage)surlesite.Cetteopérationesteffectuéeàl'aided'unesimplerequête get_posts . Modifiez selon vos besoins

    $oldest = get_posts( 'post_status=publish&posts_per_page=1&order=ASC' );
        $oldest_date = $oldest[0]->post_date;
    
  • Désactivez ensuite la date renvoyée pour obtenir uniquement l'année à partir de la date de publication. Utilisez la fonction strtotime() pour convertir l'année en un horodatage Unix

    $first_date = date('Y', strtotime($oldest_date));
    
  • Renvoyez la date actuelle, vous ne voudriez que l'année. Utilisez la fonction date()

    $current_date = date('Y');
    
  • Renvoyez les deux dates à la fonction range() pour imprimer une plage d'années entre les deux dates.

    $year_range = range($current_date, $first_date);
    
  • Ajoutez ces plages dans un foreach loop pour obtenir vos publications dans des listes par année

  • J'ai utilisé get_terms() pour obtenir une liste de tous les termes disponibles de la taxonomie en question

    $terms = get_terms('category');
    
  • Maintenant, toutes ces informations doivent être réintroduites dans un tax_query à l'aide de WP_Query

    $args = array(
            'posts_per_page'    => -1,
            'post_type'         => 'post',
            'post_status'       => 'publish',
            'year'              => $year,
            'tax_query' => array(
                array(
                    'taxonomy' => 'category',
                    'field'    => 'slug',
                    'terms'    => $term->slug
                ),
            ),
        );
    
    $posts = new WP_Query($args);
    
  • Enfin, vous souhaitez renvoyer le nom du terme et le nombre de messages par terme

    echo $term->name . '(' . $posts->post_count . ')';
    

Maintenant tous ensemble !!

<?php
$oldest = get_posts( 'post_status=publish&posts_per_page=1&order=ASC' );
    $oldest_date = $oldest[0]->post_date;

$first_date = date('Y', strtotime($oldest_date));
$current_date = date('Y');

$year_range = range($current_date, $first_date);

foreach ($year_range as $year) {
    echo $year;

    $terms = get_terms('category');
    if ( !empty( $terms ) && !is_wp_error( $terms ) ){

        foreach ( $terms as $term ) {
            $args = array(
                'posts_per_page'    => -1,
                'post_type'         => 'post',
                'post_status'       => 'publish',
                'year'              => $year,
                'tax_query' => array(
                    array(
                        'taxonomy' => 'category',
                        'field'    => 'slug',
                        'terms'    => $term->slug
                    ),
                ),
            );

            $posts = new WP_Query($args);

                echo $term->name . '(' . $posts->post_count . ')';
        }
    }
}
 ?>

Comme cela a été dit, cela peut être affiné, alors prenez cette idée et codez-la, adaptez-la et modifiez-la à votre guise. J'espère que cela vous aidera.

    
réponse donnée Pieter Goosen 11.08.2014 - 21:22
1

Il existe une solution beaucoup plus simple que celle que vous avez acceptée, en utilisant une seule requête. J'illustre ici le type d'article personnalisé 'product' et la taxonomie personnalisée 'product_cat' (egory) dans Woocommerce, simplement parce que je dispose d'une installation pratique pour le tester. Le $query est:

SELECT YEAR(p.post_date), t.name, COUNT(*), GROUP_CONCAT(p.ID), GROUP_CONCAT(p.post_title)
FROM wp_posts p
JOIN wp_term_relationships tr ON p.ID = tr.object_id
JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms t ON tt.term_id = t.term_id
WHERE tt.taxonomy = 'product_cat' AND p.post_type = 'product' AND p.post_status='publish'
GROUP BY YEAR(p.post_date), tt.term_taxonomy_id
ORDER by YEAR(p.post_date) DESC, tt.term_taxonomy_id ASC

Dans mon exemple d'installation, cela donne:

Ainsi,parexemple,ilya10postesd’habillementen2013et2en2012.

Ilvoussuffitd'appeler$wpdb->get_results($query)(etd'utiliserlepréfixe$wpdb->aulieude"wp_") pour obtenir cette table dans un tableau ou un objet, calculer les pourcentages et les afficher. Les colonnes group_concat sont ajoutées principalement pour le débogage (par conséquent, vous voudrez probablement les supprimer), mais d'un autre côté, l'id peut aussi être utile pour un autre traitement (en décomposant les valeurs de la colonne dans des tableaux).

    
réponse donnée adelval 17.08.2014 - 16:30
0

Si quelqu'un recherche un code plus simple et plus simple pour afficher uniquement une année donnée au lieu d'exécuter une boucle pour afficher toutes les années à compter de la publication. C’est le code .

Ceciinclutégalementunlienversl'archivedestermesdetaxonomie.'

$terms=get_terms('your-taxonomy');//grabthetaxonomyname$year=2015;//Theyearyouwanttopullthetermsandcountfromif(!empty($terms)&&!is_wp_error($terms)){echo'<divclass="barometer">'; //class to apply css if you want
        echo '<ul>'; 

            foreach ( $terms as $term ) { 
                $args = array(
            //'posts_per_page'    => -1,
            'post_type'         => 'post', // disable this line if you want to grap from all post types
            'post_status'       => 'publish',
            'year'              => $year,
            'tax_query' => array(
                array(
                    'taxonomy' => 'your-taxonomy',
                    'field'    => 'slug',
                    'terms'    => $term->slug
                    ),
                ),
            );

            $post_year = new WP_Query($args); 

                $term = sanitize_term( $term, 'your-taxonomy' ); 
                $term_link = get_term_link( $term, 'your-taxonomy' ); //Get the links to the term archive page

        // If the term has no post, it does not display. You can remove the if statement from here if you want to display empty terms   
        if ($post_year->post_count > 0 ) {

            echo '<li><a href="' . esc_url( $term_link ) .'" title="' . sprintf( __( 'View all %s stories','media-foundation' ), $term->name ) . '">' . $term->name . '<span>' .$post_year->post_count. '</span>' . '</a></li>'; 

        } // End of if $post_year->post_count

    } // End of Foreach term loop
        echo '</ul>';
    echo '</div>';          
} 

'

    
réponse donnée icyNETS 20.11.2015 - 21:59

Lire d'autres questions sur les étiquettes