Segnalare un articolo vecchio in modo automatico /2

news-of-the-world

Vi pubblico una versione aggiornata della funzione per controllare l’età di un post e visualizzare un messaggio. Ne parlai tanti anni fa e, mentre stavo facendo ordine tra i miei script, ci ho voluto mettere mano. Da tempo ne conservo una copia su Gist, che oggi ho aggiornato.

Ecco la funzione:

  1/**
  2 * Check if a post is older than a certain date and, if so, returns a message.
  3 * The message can also be triggered under certain taxonomies.
  4 * In addition posts that have certain taxonomies could ever be excluded.
  5 * The message can be displayed only on single posts.
  6 *
  7 * @param array $args {
  8 *    The options for the function.
  9 *
 10 *    @type string           $time             The time unit where to calculate the age of the post.
 11 *                                             Default 'year'.
 12 *                                             Accepts 'month', 'week', 'day', 'hour', 'minute'.
 13 *    @type integer          $max_quantity     The maximum value for the age of the post.
 14 *    @type string           $taxonomy_include The name of the taxonomy under which the message is triggered.
 15 *                                             Default empty.
 16 *                                             Accepts any taxonomy name.
 17 *    @type string|int|array $term_include     The term name/term_id/slug or array of them to check for.
 18 *    @type string           $taxonomy_exclude The name of the taxonomy under which the message is not triggered.
 19 *    @type string|int|array $term_exclude     The term name/term_id/slug or array of them to check for.
 20 *    @type bool             $on_single_only   Whether the function should be executed only on single posts.
 21 *    @type string           $message          The message to be displayed.
 22 *                                             The string must contain '%s' in order to display the number (1 year, 5 months, ecc.).
 23 * }
 24 *
 25 * @example We want to display an alert message only
 26 *    - on technical posts that have the category 'Tech Ninja' and/or the category 'Computer Experts';
 27 *    - older than 6 months ago;
 28 *    - but we do not want the message on those posts that have the tag 'Featured' and/or the tag 'Premium Post'.
 29 *    - Also the message must be displayed on single posts only.
 30 *    In this case, here how to call the function:
 31 *    $args = array(
 32 *       'time'             => 'month',
 33 *       'max_quantity'     => 6,
 34 *       'taxonomy_include' => 'category',
 35 *       'term_include'     => array( 'Tech Ninja', 'Computer Experts' ),
 36 *       'taxonomy_exclude' => 'post_tag',
 37 *       'term_exclude'     => array( 'Featured', 'Premium post' ),
 38 *       'on_single_only'   => true,
 39 *       'message'          => 'This is a technical post of %s ago. Instructions could not be valid anymore.'
 40 *    );
 41 *    check_post_age( $args );
 42 *
 43 * @return string A HTML P element with a notice.
 44 */
 45function check_post_age( $args ) {
 46    $defaults = array(
 47        'time'             => 'year',
 48        'max_quantity'     => 1,
 49        'taxonomy_include' => '',
 50        'term_include'     => '',
 51        'taxonomy_exclude' => '',
 52        'term_exclude'     => '',
 53        'on_single_only'   => true,
 54        'message'          => __( 'This post is obsolete! It was written %s ago.', 'my-translation-domain')
 55    );
 56    $args = wp_parse_args( $args, $defaults );
 57    extract( $args, EXTR_SKIP );
 58
 59    /*
 60     * Check if on single posts we have to hide the message and make sure we are on a single post.
 61     * Otherwise stop the function.
 62     */
 63    if ( $on_single_only && ! is_single() )
 64        return;
 65
 66    // Let's define $diff_time, the difference in seconds between today and the time of the post.
 67    global $post;
 68    $today = current_time( 'timestamp' );
 69    $post_time = get_the_time( 'U', $post->ID );
 70    $diff_time = $today - $post_time;
 71
 72    // Make sure $max_quantity is a non-negative integer.
 73    $max_quantity = absint( $max_quantity );
 74
 75    // Lets define $limit_time, the time beyond which the message is triggered.
 76    switch ( $time ) :
 77        case 'year' :
 78            $limit_time = YEAR_IN_SECONDS * $max_quantity;
 79        break;
 80        case 'month' :
 81            $limit_time = 30 * DAY_IN_SECONDS * $max_quantity;
 82        break;
 83        case 'week' :
 84            $limit_time = WEEK_IN_SECONDS * $max_quantity;
 85        break;
 86        case 'day' :
 87            $limit_time = DAY_IN_SECONDS * $max_quantity;
 88        break;
 89        case 'hour' :
 90            $limit_time = HOUR_IN_SECONDS * $max_quantity;
 91        break;
 92        case 'minute' :
 93            $limit_time = MINUTE_IN_SECONDS * $max_quantity;
 94        break;
 95    endswitch;
 96
 97    $output = '';
 98
 99    // Check if the age of the post is beyond the limit time.
100    if ( $diff_time > $limit_time ) {
101        /*
102         * Check these conditions:
103         *      1. if $taxonomy_include is empty OR the post has the specified taxonomy
104         *      2. AND the post has not the specified taxonomy.
105         *
106         * The function empty( $taxonomy_include ) triggers the notice in case we do not specify any taxonomy,
107         * for example if we want that all posts older that the limit time should trigger the notice.
108         */
109        if ( ( empty( $taxonomy_include ) || has_term( $term_include, $taxonomy_include, $post->ID ) ) && ! has_term( $term_exclude, $taxonomy_exclude, $post->ID ) ) {
110            $message = sprintf( $message, human_time_diff( $post_time, $today ) );
111            $output .= "\n" . '<!--googleoff: all-->' . "\n";
112            $output .= '<p class="obsolete-post-warning">' . $message . '</p>' . "\n";
113            $output .= '<!--googleon: all-->' . "\n\n";
114        }
115    }
116
117    return $output;
118}

Rispetto al post di tanti anni fa, la funzione è ora unica. Utilizzata così com’è, visualizza l’avviso su qualunque post più vecchio di un anno fa e va richiamata in questo modo:

1function check_this_post_age( $content ) {
2    $args = array();
3    $content = check_post_age( $args ) . $content;
4    return $content;
5}
6add_filter( 'the_content', 'check_this_post_age' );

Qualora si voglia visualizzare il messaggio solo su determinati post su cui è bene avvisare l’utente (ad esempio su post più tecnici che possano essere diventati obsoleti), questi i parametri da personalizzare:

 1function check_this_post_age( $content ) {
 2    $args = array(
 3        'time'             => 'year',
 4        'max_quantity'     => 1,
 5        'taxonomy_include' => 'category',
 6        'term_include'     => array( 'Tech Ninja', 'Wi-Fi Stereo' ),
 7        'taxonomy_exclude' => 'post_tag',
 8        'term_exclude'     => array( 'Safe Tag', 'Save my post' ),
 9        'on_single_only'   => true,
10        'message'          => 'This is a technical post I wrote %s ago. Be careful and test everything!',
11     );
12    $content = check_post_age( $args ) . $content;
13    return $content;
14}
15add_filter( 'the_content', 'check_this_post_age' );

In questo caso, l’avviso sarà mostrato se il post ha una certa età (1 anno) e se appartiene alla categoria «Tech Ninja» e/o «Wi-Fi Stereo». Se però il post ha il tag «Safe Tag» e/o «Save my post» il messaggio non sarà visualizzato. Il messaggio, inoltre, viene visualizzato solo sul post singolo e non sulla pagina degli archivi o sulla pagina indice. Qualora lo si voglia anche in questi casi, basta dichiarare false il parametro on_single_only.

Il parametro message restituisce il messaggio, appunto, e se contiene la stringa %s essa verrà sostituita dalla quantità di tempo trascorsa.

Alcuni esempi di applicazione di questa funzione possono essere visti in questo articolo (un post tecnico, pubblicato più di un anno fa) e in quest’altro articolo (un post tecnico con un tag che evita l’apparizione del messaggio di avviso).

Un’ultima annotazione. Quel <!--googleoff: all--> e <!--googleon: all--> dice al motore di ricerca di Google di non indicizzare il blocco di testo che ci sta in mezzo, altrimenti nei risultati di ricerca si vedrà sempre il testo «Questo è un post tecnico ecc…», laddove Google in genere mostra lo snippet del testo. Qui si trovano per maggiori informazioni.