WordPress Version: 6.3
/**
* Displays archive links based on type and format.
*
* @since 1.2.0
* @since 4.4.0 The `$post_type` argument was added.
* @since 5.2.0 The `$year`, `$monthnum`, `$day`, and `$w` arguments were added.
*
* @see get_archives_link()
*
* @global wpdb $wpdb WordPress database abstraction object.
* @global WP_Locale $wp_locale WordPress date and time locale object.
*
* @param string|array $args {
* Default archive links arguments. Optional.
*
* @type string $type Type of archive to retrieve. Accepts 'daily', 'weekly', 'monthly',
* 'yearly', 'postbypost', or 'alpha'. Both 'postbypost' and 'alpha'
* display the same archive link list as well as post titles instead
* of displaying dates. The difference between the two is that 'alpha'
* will order by post title and 'postbypost' will order by post date.
* Default 'monthly'.
* @type string|int $limit Number of links to limit the query to. Default empty (no limit).
* @type string $format Format each link should take using the $before and $after args.
* Accepts 'link' (`<link>` tag), 'option' (`<option>` tag), 'html'
* (`<li>` tag), or a custom format, which generates a link anchor
* with $before preceding and $after succeeding. Default 'html'.
* @type string $before Markup to prepend to the beginning of each link. Default empty.
* @type string $after Markup to append to the end of each link. Default empty.
* @type bool $show_post_count Whether to display the post count alongside the link. Default false.
* @type bool|int $echo Whether to echo or return the links list. Default 1|true to echo.
* @type string $order Whether to use ascending or descending order. Accepts 'ASC', or 'DESC'.
* Default 'DESC'.
* @type string $post_type Post type. Default 'post'.
* @type string $year Year. Default current year.
* @type string $monthnum Month number. Default current month number.
* @type string $day Day. Default current day.
* @type string $w Week. Default current week.
* }
* @return void|string Void if 'echo' argument is true, archive links if 'echo' is false.
*/
function wp_get_archives($args = '')
{
global $wpdb, $wp_locale;
$defaults = array('type' => 'monthly', 'limit' => '', 'format' => 'html', 'before' => '', 'after' => '', 'show_post_count' => false, 'echo' => 1, 'order' => 'DESC', 'post_type' => 'post', 'year' => get_query_var('year'), 'monthnum' => get_query_var('monthnum'), 'day' => get_query_var('day'), 'w' => get_query_var('w'));
$parsed_args = wp_parse_args($args, $defaults);
$post_type_object = get_post_type_object($parsed_args['post_type']);
if (!is_post_type_viewable($post_type_object)) {
return;
}
$parsed_args['post_type'] = $post_type_object->name;
if ('' === $parsed_args['type']) {
$parsed_args['type'] = 'monthly';
}
if (!empty($parsed_args['limit'])) {
$parsed_args['limit'] = absint($parsed_args['limit']);
$parsed_args['limit'] = ' LIMIT ' . $parsed_args['limit'];
}
$order = strtoupper($parsed_args['order']);
if ('ASC' !== $order) {
$order = 'DESC';
}
// This is what will separate dates on weekly archive links.
$archive_week_separator = '–';
$sql_where = $wpdb->prepare("WHERE post_type = %s AND post_status = 'publish'", $parsed_args['post_type']);
/**
* Filters the SQL WHERE clause for retrieving archives.
*
* @since 2.2.0
*
* @param string $sql_where Portion of SQL query containing the WHERE clause.
* @param array $parsed_args An array of default arguments.
*/
$where = apply_filters('getarchives_where', $sql_where, $parsed_args);
/**
* Filters the SQL JOIN clause for retrieving archives.
*
* @since 2.2.0
*
* @param string $sql_join Portion of SQL query containing JOIN clause.
* @param array $parsed_args An array of default arguments.
*/
$join = apply_filters('getarchives_join', '', $parsed_args);
$output = '';
$last_changed = wp_cache_get_last_changed('posts');
$limit = $parsed_args['limit'];
if ('monthly' === $parsed_args['type']) {
$query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM {$wpdb->posts} {$join} {$where} GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date {$order} {$limit}";
$key = md5($query);
$key = "wp_get_archives:{$key}:{$last_changed}";
$results = wp_cache_get($key, 'post-queries');
if (!$results) {
$results = $wpdb->get_results($query);
wp_cache_set($key, $results, 'post-queries');
}
if ($results) {
$after = $parsed_args['after'];
foreach ((array) $results as $result) {
$url = get_month_link($result->year, $result->month);
if ('post' !== $parsed_args['post_type']) {
$url = add_query_arg('post_type', $parsed_args['post_type'], $url);
}
/* translators: 1: Month name, 2: 4-digit year. */
$text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($result->month), $result->year);
if ($parsed_args['show_post_count']) {
$parsed_args['after'] = ' (' . $result->posts . ')' . $after;
}
$selected = is_archive() && (string) $parsed_args['year'] === $result->year && (string) $parsed_args['monthnum'] === $result->month;
$output .= get_archives_link($url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected);
}
}
} elseif ('yearly' === $parsed_args['type']) {
$query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM {$wpdb->posts} {$join} {$where} GROUP BY YEAR(post_date) ORDER BY post_date {$order} {$limit}";
$key = md5($query);
$key = "wp_get_archives:{$key}:{$last_changed}";
$results = wp_cache_get($key, 'post-queries');
if (!$results) {
$results = $wpdb->get_results($query);
wp_cache_set($key, $results, 'post-queries');
}
if ($results) {
$after = $parsed_args['after'];
foreach ((array) $results as $result) {
$url = get_year_link($result->year);
if ('post' !== $parsed_args['post_type']) {
$url = add_query_arg('post_type', $parsed_args['post_type'], $url);
}
$text = sprintf('%d', $result->year);
if ($parsed_args['show_post_count']) {
$parsed_args['after'] = ' (' . $result->posts . ')' . $after;
}
$selected = is_archive() && (string) $parsed_args['year'] === $result->year;
$output .= get_archives_link($url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected);
}
}
} elseif ('daily' === $parsed_args['type']) {
$query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, DAYOFMONTH(post_date) AS `dayofmonth`, count(ID) as posts FROM {$wpdb->posts} {$join} {$where} GROUP BY YEAR(post_date), MONTH(post_date), DAYOFMONTH(post_date) ORDER BY post_date {$order} {$limit}";
$key = md5($query);
$key = "wp_get_archives:{$key}:{$last_changed}";
$results = wp_cache_get($key, 'post-queries');
if (!$results) {
$results = $wpdb->get_results($query);
wp_cache_set($key, $results, 'post-queries');
}
if ($results) {
$after = $parsed_args['after'];
foreach ((array) $results as $result) {
$url = get_day_link($result->year, $result->month, $result->dayofmonth);
if ('post' !== $parsed_args['post_type']) {
$url = add_query_arg('post_type', $parsed_args['post_type'], $url);
}
$date = sprintf('%1$d-%2$02d-%3$02d 00:00:00', $result->year, $result->month, $result->dayofmonth);
$text = mysql2date(get_option('date_format'), $date);
if ($parsed_args['show_post_count']) {
$parsed_args['after'] = ' (' . $result->posts . ')' . $after;
}
$selected = is_archive() && (string) $parsed_args['year'] === $result->year && (string) $parsed_args['monthnum'] === $result->month && (string) $parsed_args['day'] === $result->dayofmonth;
$output .= get_archives_link($url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected);
}
}
} elseif ('weekly' === $parsed_args['type']) {
$week = _wp_mysql_week('`post_date`');
$query = "SELECT DISTINCT {$week} AS `week`, YEAR( `post_date` ) AS `yr`, DATE_FORMAT( `post_date`, '%Y-%m-%d' ) AS `yyyymmdd`, count( `ID` ) AS `posts` FROM `{$wpdb->posts}` {$join} {$where} GROUP BY {$week}, YEAR( `post_date` ) ORDER BY `post_date` {$order} {$limit}";
$key = md5($query);
$key = "wp_get_archives:{$key}:{$last_changed}";
$results = wp_cache_get($key, 'post-queries');
if (!$results) {
$results = $wpdb->get_results($query);
wp_cache_set($key, $results, 'post-queries');
}
$arc_w_last = '';
if ($results) {
$after = $parsed_args['after'];
foreach ((array) $results as $result) {
if ($result->week != $arc_w_last) {
$arc_year = $result->yr;
$arc_w_last = $result->week;
$arc_week = get_weekstartend($result->yyyymmdd, get_option('start_of_week'));
$arc_week_start = date_i18n(get_option('date_format'), $arc_week['start']);
$arc_week_end = date_i18n(get_option('date_format'), $arc_week['end']);
$url = add_query_arg(array('m' => $arc_year, 'w' => $result->week), home_url('/'));
if ('post' !== $parsed_args['post_type']) {
$url = add_query_arg('post_type', $parsed_args['post_type'], $url);
}
$text = $arc_week_start . $archive_week_separator . $arc_week_end;
if ($parsed_args['show_post_count']) {
$parsed_args['after'] = ' (' . $result->posts . ')' . $after;
}
$selected = is_archive() && (string) $parsed_args['year'] === $result->yr && (string) $parsed_args['w'] === $result->week;
$output .= get_archives_link($url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected);
}
}
}
} elseif ('postbypost' === $parsed_args['type'] || 'alpha' === $parsed_args['type']) {
$orderby = ('alpha' === $parsed_args['type']) ? 'post_title ASC ' : 'post_date DESC, ID DESC ';
$query = "SELECT * FROM {$wpdb->posts} {$join} {$where} ORDER BY {$orderby} {$limit}";
$key = md5($query);
$key = "wp_get_archives:{$key}:{$last_changed}";
$results = wp_cache_get($key, 'post-queries');
if (!$results) {
$results = $wpdb->get_results($query);
wp_cache_set($key, $results, 'post-queries');
}
if ($results) {
foreach ((array) $results as $result) {
if ('0000-00-00 00:00:00' !== $result->post_date) {
$url = get_permalink($result);
if ($result->post_title) {
/** This filter is documented in wp-includes/post-template.php */
$text = strip_tags(apply_filters('the_title', $result->post_title, $result->ID));
} else {
$text = $result->ID;
}
$selected = get_the_ID() === $result->ID;
$output .= get_archives_link($url, $text, $parsed_args['format'], $parsed_args['before'], $parsed_args['after'], $selected);
}
}
}
}
if ($parsed_args['echo']) {
echo $output;
} else {
return $output;
}
}