Ottieni l'elenco degli anni in cui sono stati pubblicati i post
Voglio creare un elenco di post da un Custom Post Type e aggiungere alcuni filtri che l'utente può cliccare per filtrare la lista.
Ho già aggiunto i filtri per tutte le categorie usando la funzione get_terms(). Ora voglio aggiungere filtri per anno, quindi ho bisogno di un modo per recuperare un elenco di tutti gli anni in cui è stato pubblicato almeno un post...
Mi serve qualcosa tipo:
$years = get_all_years_with_posts();
// restituisce array( 2011, 2013, 2014 )
So che potrei recuperare tutti i post, controllare il loro anno e costruire la lista manualmente, ma non esiste qualche altro approccio?
La tua domanda è piuttosto vecchia, ma volevo solo aggiungere una soluzione reale alla tua richiesta. Ecco una funzione che restituirà un array degli anni in cui hai pubblicato post. Puoi inserire questa funzione in functions.php o in un plugin o dove preferisci.
function get_posts_years_array() {
global $wpdb;
$result = array();
$years = $wpdb->get_results(
$wpdb->prepare(
"SELECT YEAR(post_date) FROM {$wpdb->posts} WHERE post_status = 'publish' GROUP BY YEAR(post_date) DESC"
),
ARRAY_N
);
if ( is_array( $years ) && count( $years ) > 0 ) {
foreach ( $years as $year ) {
$result[] = $year[0];
}
}
return $result;
}
Dovrai modificarla leggermente per i custom post type... basta aggiungere AND wp_posts.post_type = 'my_cpt'
da qualche parte nella query.

Ho avuto bisogno di apportare una piccola modifica. Penso che prepare() richieda di fornire almeno un argomento di formato %s (vedi https://wordpress.stackexchange.com/a/270970/11914. Ma ha funzionato e ho dato un voto positivo.

@idleberg Perché al momento in cui ho pubblicato la mia risposta, l'altra persona che ha risposto aveva frainteso la domanda. Hanno fornito un esempio su come ottenere tutti i post ordinati per anno, ma l'OP voleva ottenere un elenco di anni che hanno post.

Questo funziona, tuttavia recupera tutti i post indipendentemente dal tipo -- assicurati di applicare il filtro appropriato per il tipo di post (WHERE post_type = 'posts') altrimenti restituirà anche i post di tipo pagina.

Ricevo un avviso 'The query argument of wpdb::prepare() must have a placeholder' con questo codice quando la modalità di debug è attiva. Per favore modifica questa risposta per includere i placeholder.

Puoi utilizzare questa funzione per ottenere tutti gli anni degli articoli in un array, che puoi poi usare per eseguire un loop.
$terms_year = array(
'post_type' => array('TUA_CPT'), // Sostituisci con il tuo Custom Post Type
);
$years = array();
$query_year = new WP_Query( $terms_year );
if ( $query_year->have_posts() ) :
while ( $query_year->have_posts() ) : $query_year->the_post();
$year = get_the_date('Y'); // Ottiene l'anno della pubblicazione
if(!in_array($year, $years)){
$years[] = $year; // Aggiunge l'anno all'array se non è già presente
}
endwhile;
wp_reset_postdata(); // Resetta i dati della query
endif;
// Mostra gli anni dove vuoi
echo '<pre>';
print_r($years); // Stampa l'array degli anni
echo '</pre>';

Puoi utilizzare una funzione di WordPress e uno shortcode in questo modo:
add_shortcode( 'archives', '_get_archived_posts' );
function _get_archived_posts( $atts ) {
$a = shortcode_atts( array(
'type' => 'yearly', // Tipo di archivio (annuale)
'limit' => '', // Limite risultati
'format' => '', // Formattazione
'before' => '', // Testo prima dell'archivio
'after' => '', // Testo dopo l'archivio
'show_post_count' => false, // Mostra conteggio articoli
'echo' => 0, // Echo o return
'order' => 'DESC' // Ordine (DESC o ASC)
), $atts, 'filter_archives_sc' );
return wp_get_archives($a); // Restituisce gli archivi
}

// Ottieni tutti gli anni in cui sono stati pubblicati i post;
function get_posts_years_array($post_type = 'post') {
global $wpdb;
$result = array();
$query_prepare = $wpdb->prepare("SELECT YEAR(post_date) FROM ($wpdb->posts) WHERE post_status = 'publish' AND post_type = %s GROUP BY YEAR(post_date) DESC", $post_type);
$years = $wpdb->get_results($query_prepare);
if ( is_array( $years ) && count( $years ) > 0 ) {
foreach ( $years as $year ) {
$result[] = json_decode(json_encode($year), true);
}
}
return $result;
}

Ho preso la soluzione di @Gavin e l'ho migliorata per aggiungere il supporto a qualsiasi tipo di post e qualsiasi stato del post:
/**
* Ottiene un array di anni disponibili per qualsiasi tipo di post con qualsiasi stato
* @see https://wordpress.stackexchange.com/a/273627/18713
*/
private function get_years_with_posts(
string $post_type = 'post',
array $post_stati = ['publish']
): array {
/** @var wpdb $wpdb */
global $wpdb;
/** Converte l'array $post_stati nell'equivalente IN di MySql */
$post_status_in = "('" . implode("', '", array_map('esc_sql', $post_stati)) . "')";
/** Prepara la query con il tipo di post selezionato */
$query = $wpdb->prepare(
"SELECT YEAR(post_date)
FROM {$wpdb->posts}
WHERE post_status IN $post_status_in
AND post_type = %s
GROUP BY YEAR(post_date) DESC",
$post_type
);
$years = $wpdb->get_results($query, ARRAY_N);
return array_column($years, 0);
}
Esempio di utilizzo: Recupera tutti i post pubblicati e programmati del tipo event
:
$avaliable_years = get_years_with_posts('event', ['publish', 'future']);
