Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.20% covered (success)
90.20%
46 / 51
0.00% covered (danger)
0.00%
0 / 1
CRAP
n/a
0 / 0
archives_shortcode
95.83% covered (success)
95.83%
46 / 48
0.00% covered (danger)
0.00%
0 / 1
15
1<?php
2/**
3 * Archives shortcode
4 *
5 * @author bubel & nickmomrik
6 * [archives limit=10]
7 *
8 * @package automattic/jetpack
9 */
10
11if ( ! defined( 'ABSPATH' ) ) {
12    exit( 0 );
13}
14
15add_shortcode( 'archives', 'archives_shortcode' );
16
17/**
18 * Display Archives shortcode.
19 *
20 * @param array $atts Shortcode attributes.
21 */
22function archives_shortcode( $atts ) {
23    if ( is_feed() ) {
24        return '[archives]';
25    }
26
27    global $allowedposttags;
28
29    $default_atts = array(
30        'type'      => 'postbypost',
31        'limit'     => '',
32        'format'    => 'html',
33        'showcount' => false,
34        'before'    => '',
35        'after'     => '',
36        'order'     => 'desc',
37    );
38
39    $attr = shortcode_atts( $default_atts, $atts, 'archives' );
40
41    if ( ! in_array( $attr['type'], array( 'yearly', 'monthly', 'daily', 'weekly', 'postbypost' ), true ) ) {
42        $attr['type'] = 'postbypost';
43    }
44
45    if ( ! in_array( $attr['format'], array( 'html', 'option', 'custom' ), true ) ) {
46        $attr['format'] = 'html';
47    }
48
49    $limit = (int) $attr['limit'];
50    // A Limit of 0 makes no sense so revert back to the default.
51    if ( empty( $limit ) ) {
52        $limit = '';
53    }
54
55    /*
56     * The `postbypost` type (also the default) lists one entry per published
57     * post. Left unbounded, wp_get_archives() materializes the entire post table
58     * in a single request, which can exhaust PHP memory and fatal on large sites.
59     * Apply a sane, filterable default cap when no explicit limit was supplied.
60     */
61    if ( 'postbypost' === $attr['type'] && '' === $limit ) {
62        /**
63         * Filter the default number of entries listed by the [archives] shortcode
64         * when using the unbounded `postbypost` type with no explicit `limit`.
65         *
66         * Set to 0 to restore the previous (unlimited) behavior, though this is
67         * not recommended on sites with a large number of posts.
68         *
69         * @module shortcodes
70         *
71         * @since $$next-version$$
72         *
73         * @param int $limit Default maximum number of posts to list. Default 100.
74         */
75        $default_limit = (int) apply_filters( 'jetpack_archives_shortcode_default_limit', 100 );
76
77        if ( $default_limit > 0 ) {
78            $limit = $default_limit;
79        }
80    }
81
82    $showcount = false !== $attr['showcount'] && 'false' !== $attr['showcount'];
83    $before    = wp_kses( $attr['before'], $allowedposttags );
84    $after     = wp_kses( $attr['after'], $allowedposttags );
85
86    // Get the archives.
87    $archives = wp_get_archives(
88        array(
89            'type'            => $attr['type'],
90            'limit'           => $limit,
91            'format'          => $attr['format'],
92            'echo'            => false,
93            'show_post_count' => $showcount,
94            'before'          => $before,
95            'after'           => $after,
96        )
97    );
98
99    if ( 'asc' === $attr['order'] ) {
100        $archives = implode( "\n", array_reverse( explode( "\n", $archives ) ) );
101    }
102
103    // Check to see if there are any archives.
104    if ( empty( $archives ) ) {
105        $archives = '<p>' . __( 'Your blog does not currently have any published posts.', 'jetpack' ) . '</p>';
106    } elseif ( 'option' === $attr['format'] ) {
107        $is_amp           = class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request();
108        $change_attribute = $is_amp ? 'on="change:AMP.navigateTo(url=event.value)"' : 'onchange="document.location.href=this.options[this.selectedIndex].value;"';
109        $archives         = '<select name="archive-dropdown" ' . $change_attribute . '><option value="' . get_permalink() . '">--</option>' . $archives . '</select>';
110    } elseif ( 'html' === $attr['format'] ) {
111        $archives = '<ul>' . $archives . '</ul>';
112    }
113
114    return $archives;
115}