# Créer ses propres commandes WP-CLI pour automatiser les tâches récurrentes

> Au-delà des commandes intégrées, WP-CLI permet d'écrire les siennes. Voici comment on encapsule nos scripts de maintenance dans de vraies commandes réutilisables.

- Auteur : Clément Hadrot
- Publié le : 2021-06-10
- Mis à jour le : 2021-06-10
- Catégorie : Outils &amp; workflow
- URL : https://wpmoderne.dev.wordpress-developpement.fr/outils/creer-commandes-wp-cli-personnalisees/

## L’essentiel

- WP_CLI_Command comme point de départ pour toute commande custom
- wp scaffold package pour générer la structure d'un plugin de commande
- Idéal pour les scripts de maintenance exécutés régulièrement

Passé un certain nombre de scripts de maintenance — nettoyage de transients, réindexation d'un moteur de recherche interne, régénération de miniatures pour certaines catégories seulement — on finit toujours par vouloir les rendre accessibles comme de vraies commandes WP-CLI, avec leur propre aide, leurs propres arguments et leur propre validation. C'est exactement ce que permet l'extension de WP-CLI via `WP_CLI_Command`.

Voici comment on structure nos commandes personnalisées, du script isolé jusqu'au petit plugin de commandes réutilisable d'un projet à l'autre.

## La structure minimale d'une commande

Une commande WP-CLI personnalisée est une classe PHP qui étend `WP_CLI_Command`, enregistrée via `WP_CLI::add_command()`. On la place généralement dans un mu-plugin ou dans un plugin dédié, chargé uniquement dans le contexte WP-CLI :

```
<?php
/**
 * Plugin Name: Commandes maison
 */

if ( ! defined( 'WP_CLI' ) ) {
    return;
}

class Agence_Maintenance_Command extends WP_CLI_Command {

    /**
     * Nettoie les transients expirés et les révisions anciennes.
     *
     * ## OPTIONS
     *
     * [--dry-run]
     * : N'affiche que ce qui serait supprimé, sans rien exécuter.
     *
     * ## EXAMPLES
     *
     *     wp agence nettoyer --dry-run
     *
     * @when after_wp_load
     */
    public function nettoyer( $args, $assoc_args ) {
        $dry_run = WP_CLI\Utils\get_flag_value( $assoc_args, 'dry-run', false );

        $revisions = get_posts( [
            'post_type'      => 'revision',
            'posts_per_page' => -1,
            'fields'         => 'ids',
        ] );

        WP_CLI::log( sprintf( '%d révisions trouvées.', count( $revisions ) ) );

        if ( $dry_run ) {
            WP_CLI::success( 'Simulation terminée, aucune suppression effectuée.' );
            return;
        }

        foreach ( $revisions as $id ) {
            wp_delete_post_revision( $id );
        }

        WP_CLI::success( sprintf( '%d révisions supprimées.', count( $revisions ) ) );
    }
}

WP_CLI::add_command( 'agence', 'Agence_Maintenance_Command' );
```

> L'essentiel à retenir : WP_CLI_Command comme point de départ pour toute commande custom ; wp scaffold package pour générer la structure d'un plugin de commande ; Idéal pour les scripts de maintenance exécutés régulièrement

Cette commande devient alors utilisable exactement comme n'importe quelle commande native : `wp agence nettoyer --dry-run`. Le bloc de documentation en commentaire n'est pas décoratif : WP-CLI l'utilise pour générer l'aide accessible via `wp agence nettoyer --help`.

## Les bonnes pratiques qu'on applique systématiquement

- Toujours proposer une option `--dry-run` sur les commandes qui modifient des données, sans exception
- Utiliser `WP_CLI::log()`, `WP_CLI::success()` et `WP_CLI::error()` plutôt que `echo`, pour un affichage cohérent avec le reste de WP-CLI
- Ajouter `@when after_wp_load` quand la commande a besoin que WordPress soit entièrement chargé, notamment pour utiliser les fonctions du cœur
- Utiliser `WP_CLI\Utils\make_progress_bar()` pour les opérations longues sur de gros volumes de contenu

## Un exemple avec barre de progression

```
public function regenerer_miniatures( $args, $assoc_args ) {
    $categorie = WP_CLI\Utils\get_flag_value( $assoc_args, 'categorie', '' );

    $query = new WP_Query( [
        'post_type'      => 'post',
        'category_name'  => $categorie,
        'posts_per_page' => -1,
    ] );

    $progress = WP_CLI\Utils\make_progress_bar( 'Régénération', $query->post_count );

    foreach ( $query->posts as $post ) {
        $thumbnail_id = get_post_thumbnail_id( $post->ID );
        if ( $thumbnail_id ) {
            wp_update_attachment_metadata(
                $thumbnail_id,
                wp_generate_attachment_metadata( $thumbnail_id, get_attached_file( $thumbnail_id ) )
            );
        }
        $progress->tick();
    }

    $progress->finish();
    WP_CLI::success( 'Miniatures régénérées.' );
}
```

## Aller plus loin : un package WP-CLI distribuable

Pour des commandes réutilisées sur plusieurs projets, on préfère les distribuer comme un package Composer indépendant plutôt que de les dupliquer dans chaque mu-plugin. La commande `wp scaffold package` génère la structure de base :

```
wp scaffold package agence/wp-cli-maintenance --require=wp-cli/wp-cli:^2
composer config repositories.wp-cli-maintenance vcs https://github.com/agence/wp-cli-maintenance
composer require agence/wp-cli-maintenance
```

Cette approche a un avantage concret : on met à jour la commande une seule fois, dans son propre dépôt, et tous les projets qui la consomment en bénéficient à la prochaine mise à jour Composer.

> Une commande WP-CLI personnalisée bien pensée finit toujours par remplacer un script bash fragile plein de `ssh` et de `grep`. Le gain n'est pas seulement esthétique : elle bénéficie de la validation d'arguments, de l'aide intégrée et d'un comportement cohérent avec le reste de l'écosystème.

## En résumé

Dès qu'un script de maintenance revient plus de deux ou trois fois, ça vaut le coup de l'encapsuler dans une vraie commande WP-CLI. C'est peu de code supplémentaire — une classe, une méthode, un enregistrement — pour un gain réel en fiabilité, en documentation et en réutilisabilité entre projets.
