# Registre de consentement pour un petit site associatif : une table maison sans plugin RGPD

> Pas besoin d'une suite de conformité complète pour un site associatif à faible trafic. Une table custom dans le thème suffit à journaliser proprement les consentements.

- Auteur : WordPress Développement
- Publié le : 2023-07-07
- Mis à jour le : 2023-07-07
- Catégorie : Thèmes
- URL : https://www.wpmoderne.fr/themes/theme-associatif-rgpd-registre-consentement-sans-plugin/

## L’essentiel

- Une table dédiée évite d'alourdir wp_options ou wp_postmeta
- Chaque entrée horodate la version du texte de consentement
- La solution reste proportionnée à un petit volume de visiteurs

Une association de quartier qui gère un annuaire d'adhérents sur son site WordPress n'a ni le budget ni le besoin d'une extension de conformité RGPD complète, avec ses tableaux de bord, ses connecteurs et son abonnement mensuel. Ce qu'il lui faut, concrètement, c'est pouvoir répondre à la question « quand cette personne a-t-elle donné son accord, et pour quelle version du texte ? » — rien de plus, mais rien de moins.

Cet article détaille la construction d'un registre de consentement minimal, intégré directement au thème du site, sous forme d'une table personnalisée créée à l'activation. Il ne couvre pas les obligations légales complètes du RGPD ni les cas à fort volume de données, qui appellent des outils dédiés et un accompagnement juridique.

## Créer la table à l'activation du thème

La table se crée via `dbDelta()`, la fonction WordPress conçue pour gérer les évolutions de schéma de façon idempotente. On l'accroche au hook `after_switch_theme` plutôt qu'à l'activation d'une extension, puisque la logique vit dans le thème :

```
function creer_table_consentement() {
    global $wpdb;
    $table_name      = $wpdb->prefix . 'consentements_asso';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE $table_name (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
        horodatage DATETIME NOT NULL,
        ip_tronquee VARCHAR(45) NOT NULL,
        version_texte VARCHAR(20) NOT NULL,
        identifiant_session VARCHAR(64) NOT NULL,
        PRIMARY KEY  (id)
    ) $charset_collate;";

    require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    dbDelta( $sql );
}
add_action( 'after_switch_theme', 'creer_table_consentement' );
```

L'IP est volontairement tronquée dès l'écriture — on ne conserve que les deux premiers octets d'une IPv4, par exemple `192.168.x.x` — ce qui limite déjà l'exposition de données personnelles tout en gardant une trace suffisante pour un usage de preuve interne.

## Journaliser un consentement

La fonction d'enregistrement s'appelle depuis le traitement du formulaire d'adhésion, juste après la validation de la case à cocher :

```
function enregistrer_consentement( string $version_texte ): void {
    global $wpdb;

    $ip = $_SERVER['REMOTE_ADDR'] ?? '';
    $ip_tronquee = preg_replace( '/\.\d+\.\d+$/', '.0.0', $ip );

    $wpdb->insert(
        $wpdb->prefix . 'consentements_asso',
        [
            'horodatage'          => current_time( 'mysql' ),
            'ip_tronquee'         => $ip_tronquee,
            'version_texte'       => $version_texte,
            'identifiant_session' => wp_generate_uuid4(),
        ],
        [ '%s', '%s', '%s', '%s' ]
    );
}
```

Le paramètre `version_texte` mérite une attention particulière : il correspond à un identifiant simple (par exemple `v2-2023-07`) que l'association fait évoluer chaque fois que le texte de consentement change. C'est cette valeur qui permet, des mois plus tard, de savoir précisément à quelle formulation un adhérent a consenti.

> L'essentiel à retenir : Une table dédiée évite d'alourdir wp_options ou wp_postmeta ; Chaque entrée horodate la version du texte de consentement ; La solution reste proportionnée à un petit volume de visiteurs

## Afficher le registre dans l'administration

Pour rester consultable sans extension tierce, une page d'administration simple suffit, accrochée en sous-menu via `add_submenu_page()`, qui liste les entrées récentes avec `$wpdb->get_results()` :

```
function afficher_page_registre() {
    global $wpdb;
    $table = $wpdb->prefix . 'consentements_asso';
    $lignes = $wpdb->get_results(
        "SELECT * FROM $table ORDER BY horodatage DESC LIMIT 100"
    );

    echo '<div class="wrap"><h1>Registre de consentement</h1><table class="widefat">';
    foreach ( $lignes as $ligne ) {
        printf(
            '<tr><td>%s</td><td>%s</td><td>%s</td></tr>',
            esc_html( $ligne->horodatage ),
            esc_html( $ligne->version_texte ),
            esc_html( $ligne->ip_tronquee )
        );
    }
    echo '</table></div>';
}
```

Aucune donnée nominative n'apparaît dans cette table : l'identifiant de session ne relie pas directement à un compte utilisateur, sauf si l'association choisit explicitement de croiser avec sa table d'adhérents pour un usage de preuve précis, ce qui reste une décision à documenter dans son registre de traitement.

## Purge et durée de conservation

Une tâche cron WordPress planifiée via `wp_schedule_event()` supprime les entrées trop anciennes, la durée de conservation étant un paramètre que l'association définit elle-même selon ses besoins réels de preuve, pas selon un chiffre générique :

```
add_action( 'purge_consentements_hebdo', function() {
    global $wpdb;
    $table = $wpdb->prefix . 'consentements_asso';
    $wpdb->query(
        "DELETE FROM $table WHERE horodatage < DATE_SUB(NOW(), INTERVAL 3 YEAR)"
    );
} );

if ( ! wp_next_scheduled( 'purge_consentements_hebdo' ) ) {
    wp_schedule_event( time(), 'weekly', 'purge_consentements_hebdo' );
}
```

## Limites assumées de cette approche

Cette solution convient à un site à faible volume, avec quelques dizaines ou centaines d'adhérents par an. Elle ne gère ni les demandes de droit d'accès automatisées, ni l'export structuré pour une autorité de contrôle, ni la synchronisation avec un registre de traitement plus large. Dès qu'un site associatif grandit vers plusieurs milliers de contacts ou des traitements plus complexes, une bascule vers un outil dédié devient plus pertinente que de continuer à étendre ce mécanisme artisanal.

## Verdict

Pour une petite structure avec un budget serré, cette table de quatre colonnes couvre l'essentiel : une preuve horodatée, versionnée, et facilement consultable, sans dépendance à une extension tierce ni coût récurrent. C'est une solution proportionnée, pas une solution universelle.
