30 places par classe, pas une de plus : c’est la contrainte posée par un groupe scolaire multi-sites au moment de commander un module d’inscription en ligne pour ses classes de périscolaire. Le besoin semblait simple à l’oral — un formulaire, une classe, un compteur — mais la gestion correcte de la concurrence entre inscriptions simultanées a demandé plus de rigueur que prévu.
Le projet portait sur l’inscription aux activités périscolaires de six écoles d’un même groupement, chacune proposant plusieurs classes avec un nombre de places limité. L’enjeu principal n’était pas l’affichage du formulaire, mais la garantie qu’aucune classe ne dépasse jamais son quota, même en cas de pic de connexions simultanées le jour de l’ouverture des inscriptions.
Modéliser classes et inscriptions comme deux CPT liés
La structure de données retenue repose sur deux types de contenu personnalisés : classe_periscolaire, qui porte le quota maximal en métadonnée, et inscription_eleve, qui référence la classe choisie via une relation ACF de type Post Object. Ce choix évite de dupliquer l’information de quota à chaque inscription et centralise sa modification côté classe.
register_post_type( 'classe_periscolaire', array(
'label' => 'Classes',
'public' => false,
'show_ui' => true,
'supports' => array( 'title' ),
) );
register_post_meta( 'classe_periscolaire', '_quota_max', array(
'type' => 'integer',
'single' => true,
'show_in_rest' => false,
'default' => 30,
) );
Compter les inscriptions à la volée, jamais en cache figé
Stocker un compteur d’inscriptions directement sur la classe semblait plus simple, mais introduit un risque de désynchronisation en cas de suppression manuelle d’une inscription depuis l’admin. Le choix final a été de recompter systématiquement via WP_Query au moment de la vérification, en acceptant le léger coût en performance au profit de la fiabilité :

Verrouiller la vérification contre les doubles inscriptions
Le vrai piège de ce projet n’était pas le comptage en lui-même, mais la fenêtre de concurrence entre la vérification du quota et l’enregistrement de la nouvelle inscription. Deux parents soumettant le formulaire à la même seconde pour la dernière place disponible pouvaient, sans précaution, être tous les deux acceptés :
function periscolaire_inscrire_eleve( $classe_id, $donnees_eleve ) {
$verrou = 'lock_classe_' . $classe_id;
// On pose un verrou court via un transient pour sérialiser les inscriptions concurrentes.
if ( get_transient( $verrou ) ) {
return new WP_Error( 'classe_occupee', 'Une autre inscription est en cours, réessayez.' );
}
set_transient( $verrou, true, 5 );
$quota = (int) get_post_meta( $classe_id, '_quota_max', true );
$inscriptions = new WP_Query( array(
'post_type' => 'inscription_eleve',
'meta_key' => '_classe_id',
'meta_value' => $classe_id,
'posts_per_page' => -1,
'fields' => 'ids',
) );
if ( $inscriptions->post_count >= $quota ) {
delete_transient( $verrou );
return new WP_Error( 'quota_atteint', 'Cette classe est complète.' );
}
$inscription_id = wp_insert_post( array(
'post_type' => 'inscription_eleve',
'post_status' => 'publish',
'meta_input' => array( '_classe_id' => $classe_id ),
) );
delete_transient( $verrou );
return $inscription_id;
}
Ce verrou basé sur les Transients API n’est pas une solution à toute épreuve sous très forte charge (une base de données mal configurée pourrait introduire un léger délai de propagation), mais pour le volume attendu — quelques dizaines de connexions simultanées à l’ouverture — il s’est révélé largement suffisant en test de charge.
Afficher le quota restant sans exposer d’information sensible
Le formulaire affiche en temps réel le nombre de places restantes par classe, recalculé à chaque chargement, sans jamais exposer les identités des élèves déjà inscrits — une exigence explicite du groupe scolaire pour préserver la confidentialité des familles :
- Affichage du nombre de places restantes, jamais de la liste des inscrits.
- Désactivation automatique du bouton de soumission dès que le quota affiché atteint zéro.
- Nouvelle vérification côté serveur systématique, même si le bouton était déjà désactivé côté client au moment du chargement de la page.
Un quota affiché côté client n’est jamais une garantie : seule la vérification côté serveur, au moment de l’écriture en base, protège réellement contre le dépassement.
Ce qu’on retient de ce projet
Un module d’inscription avec quota semble, sur le papier, être un exercice basique de CRUD. La réalité d’un pic de connexions simultanées le jour de l’ouverture des inscriptions périscolaires a montré l’inverse : la difficulté n’est jamais de compter, mais de compter juste au bon moment, sans laisser de fenêtre de concurrence exploitable. Ce projet a aussi confirmé qu’un verrou simple, correctement dimensionné, résout des problèmes que des architectures bien plus lourdes tentent parfois de résoudre inutilement.