Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 1120 minDébutant

Faire évoluer un site avec les données de l'organisation

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • formuler un besoin en récits utilisateurs et critères d'acceptation ;
  • choisir entre import de fichier, API et accès à une base ;
  • lire une extension WordPress qui importe des données ;
  • protéger les données internes et personnelles exploitées par le site.

3 exercices corrigés1 schéma

Faire évoluer un site exploitant les données de l'organisation, c'est lui ajouter une fonction qui s'appuie sur les informations que l'organisation gère déjà ailleurs : un catalogue alimenté par le logiciel de stock, un agenda tiré de la base des animations, une prise de rendez-vous reliée au planning, des horaires mis à jour depuis une source unique. C'est la troisième activité de la compétence « présence en ligne » du référentiel. Ce chapitre suit un projet complet à la Cyclerie, de l'expression du besoin à la mesure du résultat, et compare les façons techniques de relier un site aux données de l'organisation sans les mettre en danger.

Ce que demande le référentiel

L'activité s'intitule « participer à l'évolution d'un site Web exploitant les données de l'organisation », et l'indicateur correspondant est que « le site a évolué conformément au besoin exprimé ». Trois mots comptent :

  • participer : tu n'as pas à tout faire seul, mais ta contribution doit être identifiable ;
  • exploitant les données de l'organisation : il ne s'agit pas de changer une couleur ou d'ajouter une page de texte, mais d'afficher ou de collecter des données qui ont une existence dans le système d'information ;
  • conformément au besoin exprimé : il faut un besoin formulé au départ, et une preuve qu'il est satisfait à l'arrivée.
Exemple d'évolutionDonnées exploitéesPlutôt SLAMPlutôt SISR
Catalogue des vélos d'occasionStock du logiciel de caisseDévelopper l'extension qui importe et affiche les vélosMettre en place l'échange sécurisé, la tâche planifiée, la supervision
Agenda des animations d'une médiathèqueBase des animationsPage alimentée par la base, filtres par publicHébergement, sauvegarde, sous-domaine et certificat
Prise de rendez-vous en lignePlanning de l'atelierFormulaire relié au planning, confirmation par courrielConfiguration de l'outil, messagerie (SPF, DKIM), droits des utilisateurs
Carte des points de collecte d'une collectivitéFichier des points tenu par un serviceImport et affichage sur une carte accessibleAutomatisation de l'import, contrôle des données
Annuaire des professionnels d'un réseauBase des adhérentsRecherche et fiches, en ne publiant que les données autoriséesGestion des comptes, sauvegardes, journalisation

De la demande à la mise en production

Une évolution de site est un petit projet (travailler en mode projet). À la rentrée de sa deuxième année, la gérante confie à Ondine le catalogue des vélos d'occasion qu'elle avait évoqué lors du choix du CMS (chapitre 3). Léo suit les étapes suivantes.

1. Recueillir et formuler le besoin. La gérante explique : « Les clients appellent sans arrêt pour savoir si on a un vélo d'occasion à leur taille. Je voudrais qu'ils voient sur le site ce qu'on a en magasin, sans que la vendeuse ressaisisse tout. » Léo reformule par écrit et fait valider : afficher sur le site les vélos d'occasion en vente, à partir du logiciel de caisse et de stock, mis à jour automatiquement, sans ressaisie.

2. Écrire les récits utilisateurs et les critères d'acceptation. Un récit utilisateur (user story) décrit un besoin du point de vue de celui qui utilise le site ; les critères d'acceptation disent comment on vérifiera qu'il est satisfait.

Récit utilisateurCritères d'acceptation
En tant que client, je veux voir les vélos d'occasion disponibles pour savoir si ça vaut le déplacementLa page /velos-occasion/ liste tous les vélos au statut « en vente » dans le stock ; chaque fiche montre la photo, le type, la taille de cadre, l'année, l'état et le prix ; un vélo vendu disparaît du site dans l'heure
En tant que client, je veux filtrer par taille et par type pour trouver vite un vélo qui me convientFiltres « taille » et « type » utilisables au clavier ; le nombre de résultats s'affiche
En tant que vendeuse, je ne veux rien ressaisirAucune saisie dans WordPress : un vélo ajouté dans le logiciel de stock apparaît sur le site dans l'heure
En tant que gérante, je veux qu'aucune information interne ne soit publiéeLe prix d'achat, le nom du déposant et les notes internes n'apparaissent ni sur le site, ni dans la base WordPress

3. Analyser l'existant. Le logiciel de caisse de la Cyclerie, en SaaS, propose une API REST en lecture : on peut lui demander, en HTTPS et avec une clé, la liste des articles d'une catégorie.

4. Maquetter la page dans le respect de la charte graphique (chapitre 5), et la faire valider.

5. Développer et tester sur la préproduction, avec un cahier de recette qui reprend chaque critère d'acceptation (cours tests).

6. Faire la recette avec la gérante, corriger, obtenir sa validation écrite (recette et procès-verbal).

7. Mettre en production, documenter (fonctionnement, procédure en cas de panne de l'import), former la vendeuse.

8. Mesurer l'effet (chapitre 7).

Trois façons de relier le site aux données

ApprochePrincipeAvantagesLimites
Import d'un fichierLe logiciel exporte un fichier (CSV, JSON) déposé sur le serveur par SFTP ; une tâche planifiée l'importeSimple, marche avec presque tout logiciel, découple les deux systèmesDonnées à jour seulement à chaque export ; format à surveiller
Appel d'une APILe site interroge une API du logiciel, côté serveur, et met le résultat en cache ou en baseDonnées fraîches, format documenté, accès limité par une cléIl faut que le logiciel propose une API ; gérer les pannes et les quotas
Accès direct à la baseLe site se connecte directement à la base du logiciel métierDonnées en temps réelÀ éviter depuis Internet : la base du système d'information exposée au serveur web, un seul défaut et toutes les données sont en danger

Dans les trois cas, une règle : le visiteur du site ne touche jamais le système de l'organisation. C'est le serveur du site qui récupère les données, les filtre, et ne garde que ce qui doit être publié.

Logiciel de stockvélos, prix d'achat,déposants, notesAPI RESTlecture seule,vélos en vente,champs publicsseulementsystème d'informationsite publicHTTPS+ cléTâche planifiéeWordPress, chaque heure1. appelle l'API2. vérifie et nettoie3. crée ou met à jour4. dépublie les vélosvendusSite WordPressfichesvelo_occasionpage/velos-occasion/Visiteurnavigateur
Le site copie seulement ce qu'il publie, à intervalle régulier : le visiteur n'atteint jamais le système d'information de l'organisation

Léo retient l'API, déjà proposée par le logiciel, avec une clé en lecture seule limitée à la catégorie « occasion ». Il demande au support de l'éditeur de configurer la réponse pour qu'elle ne contienne que les champs publics : c'est la minimisation des données à la source.

Le catalogue, côté WordPress

Le développement tient dans une petite extension WordPress, écrite par Léo et relue par son tuteur. Elle déclare un type de contenu dédié, velo_occasion, pour que les vélos aient leurs propres fiches, leur adresse (/velos-occasion/…) et leur page de liste :

php
<?php
/**
 * Plugin Name: Cyclerie – Vélos d'occasion
 * Description: Publie les vélos d'occasion du logiciel de stock.
 */

function cyclerie_cpt() {
    register_post_type( 'velo_occasion', array(
        'labels'       => array(
            'name'          => "Vélos d'occasion",
            'singular_name' => "Vélo d'occasion",
        ),
        'public'       => true,
        'has_archive'  => true,
        'rewrite'      => array( 'slug' => 'velos-occasion' ),
        'supports'     => array( 'title', 'editor', 'thumbnail' ),
        'show_in_rest' => true,
    ) );
}
add_action( 'init', 'cyclerie_cpt' );

L'import, déclenché toutes les heures par le planificateur de WordPress, appelle l'API et crée ou met à jour une fiche par vélo :

php
function cyclerie_importer_velos() {
    $reponse = wp_remote_get( CYCLERIE_STOCK_URL . '/articles?categorie=occasion&statut=en_vente', array(
        'headers' => array( 'Authorization' => 'Bearer ' . CYCLERIE_STOCK_CLE ),
        'timeout' => 15,
    ) );

    // En cas d'erreur, on garde le catalogue actuel et on le note dans le journal
    if ( is_wp_error( $reponse ) || 200 !== wp_remote_retrieve_response_code( $reponse ) ) {
        error_log( 'Cyclerie : import des vélos impossible' );
        return;
    }

    $velos = json_decode( wp_remote_retrieve_body( $reponse ), true );
    if ( ! is_array( $velos ) ) {
        error_log( 'Cyclerie : réponse de l\'API illisible' );
        return;
    }

    $references_en_vente = array();
    foreach ( $velos as $velo ) {
        $reference = sanitize_text_field( $velo['reference'] ?? '' );
        if ( '' === $reference ) {
            continue;
        }
        $references_en_vente[] = $reference;

        $existants = get_posts( array(
            'post_type'   => 'velo_occasion',
            'post_status' => 'any',
            'meta_key'    => 'reference',
            'meta_value'  => $reference,
            'numberposts' => 1,
            'fields'      => 'ids',
        ) );

        $fiche = array(
            'post_type'   => 'velo_occasion',
            'post_status' => 'publish',
            'post_title'  => sanitize_text_field( $velo['designation'] ?? '' ),
            'meta_input'  => array(
                'reference'   => $reference,
                'type'        => sanitize_text_field( $velo['type'] ?? '' ),
                'taille'      => sanitize_text_field( $velo['taille_cadre'] ?? '' ),
                'annee'       => absint( $velo['annee'] ?? 0 ),
                'etat'        => sanitize_text_field( $velo['etat'] ?? '' ),
                'prix'        => round( (float) ( $velo['prix_vente'] ?? 0 ), 2 ),
            ),
        );
        if ( $existants ) {
            $fiche['ID'] = $existants[0];
        }
        wp_insert_post( $fiche );
    }

    // Les vélos absents de la réponse ont été vendus : on retire leur fiche du site
    $publies = get_posts( array(
        'post_type'   => 'velo_occasion',
        'post_status' => 'publish',
        'numberposts' => -1,
        'fields'      => 'ids',
    ) );
    foreach ( $publies as $id ) {
        if ( ! in_array( get_post_meta( $id, 'reference', true ), $references_en_vente, true ) ) {
            wp_update_post( array( 'ID' => $id, 'post_status' => 'draft' ) );
        }
    }
}
add_action( 'cyclerie_import_horaire', 'cyclerie_importer_velos' );

register_activation_hook( __FILE__, function () {
    if ( ! wp_next_scheduled( 'cyclerie_import_horaire' ) ) {
        wp_schedule_event( time(), 'hourly', 'cyclerie_import_horaire' );
    }
    // Déclare le type de contenu puis régénère les adresses : sans cela, /velos-occasion/ renvoie une 404
    cyclerie_cpt();
    flush_rewrite_rules();
} );

register_deactivation_hook( __FILE__, function () {
    wp_clear_scheduled_hook( 'cyclerie_import_horaire' );
    unregister_post_type( 'velo_occasion' );
    flush_rewrite_rules();
} );

L'import des photos (téléchargement de l'image et rattachement à la fiche) est omis ici pour garder l'exemple lisible ; il suit le même principe.

Quelques choix à savoir justifier devant un jury :

  • l'adresse de l'API et la clé sont des constantes définies dans wp-config.php (CYCLERIE_STOCK_URL, CYCLERIE_STOCK_CLE), pas dans le code de l'extension, qui pourrait se retrouver dans un dépôt Git ;
  • chaque valeur reçue est nettoyée (sanitize_text_field, absint, conversion en nombre) avant d'être enregistrée : on ne fait jamais confiance à une source externe, même interne à l'organisation ;
  • si l'API ne répond pas, l'import s'arrête sans rien supprimer : le site garde le catalogue de l'heure précédente plutôt que d'afficher une page vide ;
  • à l'activation, l'extension déclare le type de contenu et régénère les règles d'adresses (flush_rewrite_rules), sinon /velos-occasion/ renvoie une 404 tant que personne n'a réenregistré les permaliens ; à la désactivation, elle supprime sa tâche planifiée (wp_clear_scheduled_hook) et retire ses adresses, pour ne laisser ni import orphelin ni règle inutile ;
  • les vélos vendus passent en brouillon plutôt que d'être supprimés, ce qui garde un historique et permet de les republier s'ils reviennent en stock ;
  • à l'affichage, le thème échappe chaque valeur (esc_html, esc_url) pour empêcher qu'un contenu inattendu soit interprété comme du code dans la page (faille XSS).

Pour le référencement, chaque fiche reçoit un titre et une description générés à partir de ses données (« VTC électrique taille M, 2023, très bon état – 1 290 € »), et des données structurées Product avec une offre (Offer) au prix et à la disponibilité réels (chapitre 6).

Sécurité et données personnelles

Exploiter les données de l'organisation sur un site public impose quelques garde-fous :

RisqueGarde-fou
Publier une donnée interne (prix d'achat, marge, note interne)Minimisation à la source (l'API ne renvoie que les champs publics) et dans le code (on n'enregistre que les champs prévus)
Publier une donnée personnelle (nom du déposant d'un vélo en dépôt-vente)Ne jamais l'importer ; vérifier la réponse de l'API pendant la recette
Vol de la clé d'APIClé en lecture seule, limitée à une catégorie, stockée hors du code, renouvelée si un doute existe
Injection ou affichage de code malveillantNettoyage à l'entrée, échappement à la sortie, requêtes préparées si on interroge une base (cours SQL)
Indisponibilité du logiciel sourceImport qui conserve les dernières données, alerte en cas d'échecs répétés
Formulaire qui collecte des données (rendez-vous, réservation)Information des personnes, durée de conservation, accès limité (chapitre 9)

Mesurer le résultat

Le besoin exprimé par la gérante était de réduire les appels et de faire venir les clients. Trois mois après la mise en ligne, Léo relève : 1 380 visites de la page /velos-occasion/, la page la plus consultée après l'accueil ; 46 clics sur le bouton « Réserver un essai » ; et, selon la vendeuse, nettement moins d'appels pour demander « ce que vous avez en taille M ». Le délai moyen entre la mise en stock et la vente d'un vélo d'occasion, tiré du logiciel de caisse, est passé de 24 à 17 jours. C'est ce genre de résultat, chiffré et relié au besoin, qui prouve que « le site a évolué conformément au besoin exprimé ».

Exercices

Exercice 1 sur 3 Écrire des critères d'acceptation Réussi À revoir

Une médiathèque veut que son agenda en ligne soit alimenté par la base des animations tenue par les bibliothécaires. Écris un récit utilisateur pour un usager et un pour une bibliothécaire, avec deux critères d'acceptation chacun.

Voir la réponseMasquer la réponse de l'exercice 1

Une proposition :

  • En tant qu'usager, je veux voir les animations à venir pour choisir celles qui m'intéressent. Critères : la page « Agenda » liste les animations dont la date est postérieure à aujourd'hui, triées par date ; chaque animation affiche le titre, la date, l'horaire, le public visé et le lieu ; une animation passée disparaît de la liste le lendemain.
  • En tant que bibliothécaire, je veux saisir une animation une seule fois. Critères : une animation créée dans la base des animations apparaît sur le site sans autre saisie, dans un délai annoncé (par exemple une heure) ; une animation annulée dans la base est retirée du site ou affichée « annulée » dans le même délai.

Un bon critère est vérifiable pendant la recette : « rapide » ou « joli » ne le sont pas, « dans l'heure » ou « utilisable au clavier » le sont.

Tu avais trouvé ?

Exercice 2 sur 3 Choisir l'approche technique Réussi À revoir

Pour chaque situation, choisis entre import de fichier, appel d'API et accès direct à la base, et justifie.

  1. Un club sportif tient la liste de ses créneaux dans un tableur partagé, mis à jour une fois par mois.
  2. Une entreprise de location de salles utilise un logiciel de réservation en SaaS qui propose une API documentée ; le site doit afficher les disponibilités du jour.
  3. Un stagiaire propose de connecter directement le site public à la base MySQL de l'ERP de l'entreprise « pour que ce soit en temps réel ».
Voir la réponseMasquer la réponse de l'exercice 2
  1. Import de fichier : un export CSV mensuel, importé par une tâche planifiée ou même manuellement, suffit. Une API serait disproportionnée pour des données qui changent une fois par mois.
  2. Appel d'API côté serveur, avec un cache de quelques minutes : les données doivent être fraîches et l'éditeur prévoit cet usage.
  3. Refuser l'accès direct : il exposerait la base de l'ERP (clients, factures, salaires peut-être) au serveur web public ; une faille du site deviendrait une fuite de tout le système d'information. Proposer à la place une API en lecture seule qui n'expose que les données à publier, ou un export filtré.

Tu avais trouvé ?

Exercice 3 sur 3 Repérer la fuite Réussi À revoir

Pendant la recette, Léo affiche la réponse brute de l'API pour un vélo :

json
{
  "reference": "OCC-2026-041",
  "designation": "VTC électrique taille M",
  "type": "VTC électrique",
  "taille_cadre": "M",
  "annee": 2023,
  "etat": "Très bon état",
  "prix_vente": 1290.00,
  "prix_achat": 850.00,
  "deposant": "Mme Lefort, 06 12 34 56 78",
  "note_interne": "batterie à 82 %, à signaler au client"
}
  1. Quels champs ne doivent jamais arriver sur le site ?
  2. Le code de l'extension montré plus haut les publie-t-il ?
  3. Que fait Léo quand même, et pourquoi ?
Voir la réponseMasquer la réponse de l'exercice 3
  1. prix_achat (information commerciale interne), deposant (donnée personnelle d'une cliente en dépôt-vente : nom et téléphone) et note_interne. Remarque : l'information sur la batterie doit être donnée au client, mais rédigée par la vendeuse dans la description, pas recopiée d'une note interne.
  2. Non : l'extension n'enregistre que les champs listés dans meta_input (référence, type, taille, année, état, prix de vente). C'est la minimisation dans le code.
  3. Il demande à l'éditeur du logiciel de retirer ces champs de la réponse de l'API pour la clé du site (minimisation à la source). Tant qu'ils sont transmis, ils circulent jusqu'au serveur web : en cas de compromission du site, de journalisation trop bavarde ou d'une future modification du code, ils pourraient fuiter. Il note le point dans le cahier de recette.

Tu avais trouvé ?

Chapitre terminé !

Fais les 3 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : La présence en ligne à l'E5 : réalisations et questions du juryRevoir le sommaire du cours