# Programmer l’expiration d’un contenu : dépublier automatiquement

> Une offre promotionnelle restée en ligne trois semaines après sa date de fin, parce que personne n'avait pensé à la dépublier : le genre d'oubli qui coûte cher.

- Auteur : Clément Hadrot
- Publié le : 2023-05-22
- Mis à jour le : 2023-05-22
- Catégorie : Tips
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tips/programmer-expiration-contenu-depublier/

## L’essentiel

- Un champ de date d'expiration s'ajoute simplement à l'écran d'édition
- wp_schedule_single_event programme l'action à la bonne heure
- Le contenu peut passer en brouillon ou rediriger selon le besoin

Une offre promotionnelle « valable jusqu'au 15 » restée visible sur un site jusqu'au 6 du mois suivant, simplement parce que personne côté client n'avait pensé à revenir la dépublier manuellement : c'est le genre d'incident qui, une fois qu'il arrive à un client, finit toujours par une demande d'automatisation. La solution consiste à ajouter un champ de date d'expiration à l'écran d'édition, puis à programmer un événement unique qui dépublie ou redirige le contenu à l'échéance exacte.

Cet article se concentre sur la mécanique de programmation elle-même ; le fonctionnement général de wp-cron, sur lequel elle s'appuie, n'est pas réexpliqué ici.

## Ajouter un champ de date d'expiration

Une métabox simple, ajoutée à l'écran d'édition des articles concernés, permet au rédacteur de saisir la date et l'heure d'expiration souhaitées, stockée en meta.

```
function promo_metabox_expiration() {
    add_meta_box(
        'promo_expiration',
        'Date d\'expiration',
        'promo_afficher_champ_expiration',
        'post',
        'side'
    );
}
add_action( 'add_meta_boxes', 'promo_metabox_expiration' );

function promo_afficher_champ_expiration( $post ) {
    $date = get_post_meta( $post->ID, 'date_expiration', true );
    wp_nonce_field( 'promo_expiration_nonce', 'promo_expiration_nonce' );
    echo '<input type="datetime-local" name="date_expiration" value="' . esc_attr( $date ) . '" />';
}
```

## Programmer l'événement à l'enregistrement

> L'essentiel à retenir : Un champ de date d'expiration s'ajoute simplement à l'écran d'édition ; wp_schedule_single_event programme l'action à la bonne heure ; Le contenu peut passer en brouillon ou rediriger selon le besoin

Au moment de l'enregistrement du contenu, si une date d'expiration a été saisie, un événement unique est programmé avec `wp_schedule_single_event()`, en veillant d'abord à retirer toute programmation précédente pour éviter les doublons en cas de modification de la date.

```
function promo_enregistrer_expiration( $post_id ) {
    if ( ! isset( $_POST['promo_expiration_nonce'] )
        || ! wp_verify_nonce( $_POST['promo_expiration_nonce'], 'promo_expiration_nonce' ) ) {
        return;
    }
    if ( empty( $_POST['date_expiration'] ) ) {
        return;
    }

    $date_expiration = sanitize_text_field( $_POST['date_expiration'] );
    update_post_meta( $post_id, 'date_expiration', $date_expiration );

    $timestamp = strtotime( $date_expiration . ' ' . wp_timezone_string() );

    // Retirer toute programmation précédente pour ce contenu
    wp_clear_scheduled_hook( 'promo_depublier_contenu', array( $post_id ) );

    if ( $timestamp > time() ) {
        wp_schedule_single_event( $timestamp, 'promo_depublier_contenu', array( $post_id ) );
    }
}
add_action( 'save_post', 'promo_enregistrer_expiration' );
```

## Traiter l'expiration au bon moment

La fonction accrochée au hook personnalisé `promo_depublier_contenu` décide du comportement à l'échéance : passage en brouillon, ou redirection vers une autre page si le contenu doit rester accessible sous une autre forme.

```
function promo_depublier_contenu( $post_id ) {
    $post = get_post( $post_id );
    if ( ! $post || 'publish' !== $post->post_status ) {
        return;
    }

    wp_update_post( array(
        'ID'          => $post_id,
        'post_status' => 'draft',
    ) );

    update_post_meta( $post_id, 'raison_depublication', 'expiration_automatique' );
}
add_action( 'promo_depublier_contenu', 'promo_depublier_contenu' );
```

Le contrôle `'publish' !== $post->post_status` évite un effet de bord si le contenu a déjà été dépublié manuellement entre-temps par un rédacteur, avant même l'échéance programmée.

## Variante : rediriger plutôt que dépublier

Pour une offre commerciale, dépublier laisse une page 404 si l'URL était partagée ou indexée. Une meta `url_redirection_expiration` associée, combinée à un `template_redirect` conditionné au statut, redirige proprement les visiteurs arrivant après l'échéance vers une page de remplacement.

```
function promo_rediriger_si_expire() {
    if ( ! is_singular( 'post' ) ) {
        return;
    }
    $expire_le = get_post_meta( get_the_ID(), 'date_expiration', true );
    $redirection = get_post_meta( get_the_ID(), 'url_redirection_expiration', true );

    if ( $expire_le && $redirection && strtotime( $expire_le ) < time() ) {
        wp_safe_redirect( esc_url_raw( $redirection ), 302 );
        exit;
    }
}
add_action( 'template_redirect', 'promo_rediriger_si_expire' );
```

## Ce qui peut mal se passer

- Un contenu modifié plusieurs fois avant expiration peut accumuler des événements programmés en double si `wp_clear_scheduled_hook()` est oublié.
- Comme toute tâche wp-cron, l'exécution dépend d'une visite au moment de l'échéance sur un site à faible trafic ; un vrai cron système reste préférable en production.
- La suppression définitive d'un contenu ne doit jamais être automatique sans confirmation explicite : le passage en brouillon reste réversible, une suppression ne l'est pas.

> Je préfère systématiquement le passage en brouillon à la suppression pure et simple pour ce type d'automatisation : un client qui souhaite reconduire une offre l'année suivante retrouve tout le contenu déjà rédigé, sans avoir à le recréer de zéro.

## En résumé

Un champ de date, un événement unique programmé avec `wp_schedule_single_event()` et un hook personnalisé traitant l'échéance suffisent à automatiser l'expiration d'un contenu, que ce soit par passage en brouillon ou par redirection. La vigilance porte surtout sur le nettoyage des événements précédents lors d'une modification, pour éviter toute dépublication en double ou à la mauvaise date.
