Obține o listă de ani în care au fost publicate articole
Vreau să creez o listă de postări dintr-un Tip Personalizat de Postare și să adaug niște filtre pe care utilizatorii le pot folosi pentru a filtra lista.
Am adăugat filtre pentru toate categoriile folosind funcția get_terms(). Acum vreau să adaug filtre după an, așa că am nevoie de o metodă pentru a obține o listă cu toți anii în care a fost publicat cel puțin un articol...
Am nevoie de ceva de genul:
$years = get_all_years_with_posts();
// returnează array( 2011, 2013, 2014 )
Știu că pot să obțin toate postările, să verific anul lor și să construiesc lista manual, dar nu există vreo altă abordare?
Întrebarea ta este destul de veche, dar am vrut să adaug o soluție reală la problema ta. Iată o funcție care va returna un array cu anii în care ai publicat articole. Poți plasa această funcție în fișierul functions.php sau într-un plugin sau oriunde dorești.
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;
}
Va trebui să o modifici ușor pentru post types personalizate... doar adaugă AND wp_posts.post_type = 'my_cpt'
undeva în interogare.

A trebuit să-l ajustez ușor. Cred că prepare() necesită să furnizezi cel puțin un argument de format %s (vezi https://wordpress.stackexchange.com/a/270970/11914. Dar a funcționat și am dat upvote.

@idleberg Pentru că în momentul în care am postat răspunsul meu, cealaltă persoană care a răspuns a înțeles greșit întrebarea. Au dat un exemplu despre cum să obții toate postările sortate după an, dar OP dorea să obțină o listă cu anii care au postări.

Această metodă funcționează, dar returnează toate articolele indiferent de tip - asigură-te că aplici un filtru adecvat pentru tipul de articol (WHERE post_type = 'posts') altfel va returna și pagini.

Primesc o notificare 'The query argument of wpdb::prepare() must have a placeholder' cu acest cod când modul debug este activat. Te rog editează acest răspuns să includă placeholder-e.

Puteți utiliza această funcție pentru a obține toți anii postărilor într-un array, pe care îl puteți folosi pentru a parcurge cu un loop.
$terms_year = array(
'post_type' => array('YOUR_CPT'),
);
$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');
if(!in_array($year, $years)){
$years[] = $year;
}
endwhile;
wp_reset_postdata();
endif;
// Afișați anii oriunde doriți
echo '<pre>';
print_r($years);
echo '</pre>';

Puteți utiliza o funcție WP și un shortcode în felul următor:
add_shortcode( 'arhive', '_get_archived_posts' );
function _get_archived_posts( $atts ) {
$a = shortcode_atts( array(
'type' => 'yearly', // tipul arhivei (anuală)
'limit' => '', // limită număr articole
'format' => '', // format afișare
'before' => '', // text înainte de arhivă
'after' => '', // text după arhivă
'show_post_count' => false, // afișare număr articole
'echo' => 0, // returnare sau afișare directă
'order' => 'DESC' // ordonare (DESC/ASC)
), $atts, 'filter_archives_sc' );
return wp_get_archives($a);
}

// Obține toți anii în care au fost publicate postări
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;
}

Am luat soluția de la @Gavin și am îmbunătățit-o pentru a adăuga suport pentru orice tip de postare și orice statut al postării:
/**
* Obține un array cu anii disponibili pentru orice tip de postare cu orice statuturi
* @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;
/** Convertim array-ul $post_stati în echivalentul MySql IN */
$post_status_in = "('" . implode("', '", array_map('esc_sql', $post_stati)) . "')";
/** Pregătim interogarea cu tipul de postare selectat */
$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);
}
Exemplu de utilizare: Obține toate postările publicate și viitoare de tipul event
:
$avaliable_years = get_years_with_posts('event', ['publish', 'future']);
