mirror of
https://github.com/JMP-MS/ASPIC.git
synced 2026-10-27 16:07:10 +00:00
V1.17.18 Modifications consignes correction bugs
This commit is contained in:
+130
-13
@@ -22,6 +22,14 @@
|
||||
* retourne alors ce même type de tableau (valeurs mises à jour, mêmes clés),
|
||||
* un Test retourne toujours un simple bool. Voir
|
||||
* consigne_completer_code_postal() ci-dessous pour un exemple.
|
||||
* - Test à UN champ avec accès base (8 septembre 2026) : une fonction de Test
|
||||
* qui a besoin d'interroger la base (ex. vérifier qu'une valeur n'est pas
|
||||
* déjà utilisée ailleurs) peut déclarer deux paramètres supplémentaires,
|
||||
* dans cet ordre : (string $valeur, PDO $pdo, ?int $idExclusion): bool — le
|
||||
* moteur les fournit systématiquement à tout Test à un champ (voir
|
||||
* moteur_consignes.php), $idExclusion étant l'identifiant de la fiche en
|
||||
* cours de modification (null en Création). Voir consigne_mail_unique() et
|
||||
* consigne_portable_unique() ci-dessous, premier cas réel.
|
||||
* - Jumeau "_seraitDeclenchee" (7 septembre 2026, soir) : toute fonction de
|
||||
* Traitement qui interroge un service externe (IA) et porte
|
||||
* FON_VisuelAttenteIA = 'O' DOIT avoir, en plus, une fonction nommée
|
||||
@@ -34,15 +42,20 @@
|
||||
* qu'interroge consignes_apercu.php pour piloter le badge IA générique côté
|
||||
* écran, voir ce fichier et moteur_consignes.php
|
||||
* (auMoinsUneConsigneIaSeraitDeclenchee()).
|
||||
* Fichier volontairement sans dépendance à la session ni à la base de
|
||||
* données : chaque fonction ne fait que transformer ou tester une ou
|
||||
* plusieurs valeurs qu'on lui passe. Exception depuis le 7 septembre 2026
|
||||
* (soir) : une fonction peut interroger un service externe (API d'IA, voir
|
||||
* consigne_completer_code_postal()) quand la consigne elle-même l'exige
|
||||
* explicitement — jamais la session ni la base ASPIC, seulement un appel
|
||||
* réseau sortant, et toujours avec un repli silencieux (valeurs inchangées)
|
||||
* en cas d'échec : un Traitement ne doit jamais faire échouer un
|
||||
* enregistrement à cause d'un service tiers indisponible.
|
||||
* Fichier volontairement sans dépendance à la session : chaque fonction ne
|
||||
* fait que transformer ou tester une ou plusieurs valeurs qu'on lui passe (et,
|
||||
* depuis le 8 septembre 2026, éventuellement interroger $pdo — voir ci-dessus
|
||||
* — mais jamais $_SESSION). Deux exceptions à la dépendance base/réseau :
|
||||
* - Depuis le 7 septembre 2026 (soir) : une fonction de Traitement peut
|
||||
* interroger un service externe (API d'IA, voir
|
||||
* consigne_completer_code_postal()) quand la consigne elle-même l'exige
|
||||
* explicitement, toujours avec un repli silencieux (valeurs inchangées) en
|
||||
* cas d'échec : un Traitement ne doit jamais faire échouer un
|
||||
* enregistrement à cause d'un service tiers indisponible.
|
||||
* - Depuis le 8 septembre 2026 : une fonction de Test à un champ peut
|
||||
* interroger $pdo, reçu directement du moteur (voir "Test à UN champ avec
|
||||
* accès base" ci-dessus) — jamais de connexion ouverte ici, toujours celle
|
||||
* déjà établie par l'appelant (db.php).
|
||||
*/
|
||||
|
||||
// ASP_Fonctions.FON_Nom = 'MAJUSCULE' (Nature=Traitement)
|
||||
@@ -104,6 +117,21 @@ function consigne_mail_valide(string $valeur): bool
|
||||
return filter_var($valeur, FILTER_VALIDATE_EMAIL) !== false;
|
||||
}
|
||||
|
||||
// ASP_Fonctions.FON_Nom = 'RETIRER_POINTS' (Nature=Traitement), 8 septembre
|
||||
// 2026. Retire tous les points (".") d'une valeur, sans autre transformation
|
||||
// — demandée pour un numéro de téléphone saisi avec des points comme
|
||||
// séparateurs (ex. "02.98.12.34.56" -> "0298123456"). Générique et
|
||||
// réutilisable tel quel sur n'importe quel champ texte, même principe que
|
||||
// SANS_CHIFFRE ci-dessus : aucune fonction par champ, juste une ligne dans
|
||||
// ASP_Consignes par champ concerné (CNT_Tel et/ou CNT_Portable). Volontairement
|
||||
// limitée aux points, sur la demande telle que formulée par Jean-Marc — à
|
||||
// étendre (espaces, tirets...) le jour où un besoin réel et concret se
|
||||
// présentera, pas par anticipation.
|
||||
function consigne_retirer_points(string $valeur): string
|
||||
{
|
||||
return str_replace('.', '', $valeur);
|
||||
}
|
||||
|
||||
// ASP_Fonctions.FON_Nom = 'SANS_CHIFFRE' (Nature=Test), 7 septembre 2026.
|
||||
// Vrai si la valeur ne contient aucun chiffre, faux sinon — champ facultatif
|
||||
// (une valeur vide est conforme, même principe que consigne_mail_valide() :
|
||||
@@ -140,10 +168,15 @@ function consigne_sans_chiffre(string $valeur): bool
|
||||
// (ex. arrondissements de Paris/Lyon/Marseille) doit renvoyer null plutôt que
|
||||
// de deviner — c'est écrit explicitement dans la consigne envoyée au modèle.
|
||||
//
|
||||
// Toute défaillance (clé absente, réseau, quota, réponse inattendue) se
|
||||
// traduit par un retour silencieux des valeurs inchangées : un Traitement ne
|
||||
// doit jamais bloquer l'enregistrement d'un contact à cause d'un service
|
||||
// externe (voir commentaire d'en-tête de moteur_consignes.php) — contrairement
|
||||
// Toute défaillance (clé absente, réseau, quota, réponse inattendue) laisse
|
||||
// toujours CNT_AdrCP inchangé — un Traitement ne doit jamais bloquer
|
||||
// l'enregistrement d'un contact à cause d'un service externe (voir
|
||||
// commentaire d'en-tête de moteur_consignes.php) — mais n'est PLUS silencieuse
|
||||
// pour autant depuis le 8 septembre 2026 (correctif demandé par Jean-Marc,
|
||||
// constat d'un échec resté invisible sur une ville inconnue) : chaque cas
|
||||
// d'échec pose désormais un "_avertissement" pour l'écran, et un
|
||||
// "_realisation" quand un appel a réellement été tenté (voir le corps de la
|
||||
// fonction ci-dessous) — contrairement
|
||||
// à un Test, dont l'échec est lui affiché à l'utilisateur.
|
||||
// Jumeau "_seraitDeclenchee" (voir en-tête de fichier) : réplique à elle
|
||||
// seule la condition de déclenchement de consigne_completer_code_postal()
|
||||
@@ -169,6 +202,17 @@ function consigne_completer_code_postal(array $valeurs): array
|
||||
|
||||
$apiKey = trim((string) getenv('OPENAI_API_KEY'));
|
||||
if (!$apiKey) {
|
||||
// Panne de configuration (8 septembre 2026) : jusqu'ici un retour
|
||||
// totalement silencieux — repéré par Jean-Marc comme le même défaut
|
||||
// que celui déjà corrigé le 7 septembre pour une ville ambiguë
|
||||
// ("un constat d'échec doit toujours être visible, jamais un simple
|
||||
// silence"). Pas de "_realisation" ici : aucun appel réseau n'a
|
||||
// réellement eu lieu, donc rien à journaliser comme un coût engagé
|
||||
// (voir en-tête de moteur_consignes.php) — seulement l'avertissement
|
||||
// écran, pour que l'utilisateur ne reste pas devant un champ vide
|
||||
// sans explication.
|
||||
$valeurs['_avertissement'] = "Code postal non déterminé pour « $ville » "
|
||||
. "(service indisponible). Saisissez le code postal vous-même.";
|
||||
return $valeurs;
|
||||
}
|
||||
|
||||
@@ -226,6 +270,18 @@ function consigne_completer_code_postal(array $valeurs): array
|
||||
curl_close($ch);
|
||||
|
||||
if ($reponseBrute === false || $codeHttp !== 200) {
|
||||
// Échec réseau/HTTP (8 septembre 2026) : contrairement au cas
|
||||
// "clé API absente" ci-dessus, un appel a bien été tenté (et peut
|
||||
// avoir un coût, selon où l'échec survient côté fournisseur) — donc
|
||||
// journalisé comme le cas "ville ambiguë" plus bas, sur le même
|
||||
// principe posé le 7 septembre par Jean-Marc ("un appel fait à l'IA
|
||||
// [doit laisser] une trace dans les réalisations").
|
||||
$valeurs['_realisation'] = [
|
||||
'action' => 'IA_CP',
|
||||
'commentaire' => "Échec technique de l'appel IA pour la ville « $ville » (HTTP $codeHttp).",
|
||||
];
|
||||
$valeurs['_avertissement'] = "Code postal non déterminé pour « $ville » "
|
||||
. "(service temporairement indisponible). Saisissez le code postal vous-même.";
|
||||
return $valeurs;
|
||||
}
|
||||
|
||||
@@ -289,3 +345,64 @@ function consigne_completer_code_postal(array $valeurs): array
|
||||
|
||||
return $valeurs;
|
||||
}
|
||||
|
||||
// ASP_Fonctions.FON_Nom = 'MAIL_UNIQUE' (Nature=Test), 8 septembre 2026.
|
||||
// Vrai si l'adresse mail n'est pas déjà utilisée par un AUTRE contact actif,
|
||||
// faux sinon. Champ facultatif, même principe que consigne_mail_valide()
|
||||
// ci-dessus : une valeur vide est toujours conforme (deux fiches sans mail ne
|
||||
// sont pas en conflit) — le caractère obligatoire reste la responsabilité
|
||||
// d'une consigne NON_VIDE séparée, combinable sur le même champ.
|
||||
//
|
||||
// Fonction dédiée à CNT_Mail plutôt qu'un test générique "valeur unique"
|
||||
// paramétrable par nom de champ (demande explicite de Jean-Marc, 8 septembre
|
||||
// 2026) : contrairement à SANS_CHIFFRE ci-dessus, volontairement générique
|
||||
// parce que ça a du sens sur Nom/Prénom/Ville indifféremment, une contrainte
|
||||
// d'unicité n'a de sens QUE sur certains champs précis — l'ouvrir à un
|
||||
// paramétrage libre depuis ASP_Consignes exposerait un futur opérateur du
|
||||
// catalogue à l'appliquer par erreur à un champ comme Prénom, où deux
|
||||
// contacts homonymes sont parfaitement normaux. Voir consigne_portable_unique()
|
||||
// ci-dessous, jumelle sur CNT_Portable — toutes deux appuyées sur le même
|
||||
// utilitaire privé valeurDejaUtilisee() pour ne pas dupliquer la requête SQL.
|
||||
function consigne_mail_unique(string $valeur, PDO $pdo, ?int $idExclusion = null): bool
|
||||
{
|
||||
return !valeurDejaUtilisee($pdo, 'CNT_Mail', $valeur, $idExclusion);
|
||||
}
|
||||
|
||||
// ASP_Fonctions.FON_Nom = 'PORTABLE_UNIQUE' (Nature=Test), 8 septembre 2026.
|
||||
// Même principe que consigne_mail_unique() ci-dessus, appliqué à
|
||||
// CNT_Portable — fonction séparée plutôt qu'un simple paramétrage de la même
|
||||
// fonction sur un autre champ, pour la même raison (voir commentaire de
|
||||
// consigne_mail_unique()).
|
||||
function consigne_portable_unique(string $valeur, PDO $pdo, ?int $idExclusion = null): bool
|
||||
{
|
||||
return !valeurDejaUtilisee($pdo, 'CNT_Portable', $valeur, $idExclusion);
|
||||
}
|
||||
|
||||
// Utilitaire privé partagé par consigne_mail_unique() et
|
||||
// consigne_portable_unique() ci-dessus — pas une fonction du catalogue
|
||||
// (aucun ASP_Fonctions.FON_NomPHP ne pointe dessus, jamais appelée depuis
|
||||
// ASP_Consignes) : factorise uniquement la requête SQL commune aux deux.
|
||||
// $champ vient toujours d'une constante écrite en dur dans l'une des deux
|
||||
// fonctions ci-dessus, jamais d'une donnée utilisateur — pas de risque
|
||||
// d'injection SQL malgré l'interpolation dans le nom de colonne.
|
||||
// $idExclusion (identifiant du contact en cours de modification, voir
|
||||
// moteur_consignes.php) permet à une fiche de conserver sa propre valeur sans
|
||||
// se bloquer elle-même ; toujours null en Création, où rien n'existe encore à
|
||||
// exclure.
|
||||
function valeurDejaUtilisee(PDO $pdo, string $champ, string $valeur, ?int $idExclusion): bool
|
||||
{
|
||||
$valeur = trim($valeur);
|
||||
if ($valeur === '') return false;
|
||||
|
||||
$sql = "SELECT 1 FROM ASP_Contacts WHERE $champ = ? AND CNT_Actif = 1";
|
||||
$params = [$valeur];
|
||||
if ($idExclusion !== null) {
|
||||
$sql .= ' AND CNT_Incr != ?';
|
||||
$params[] = $idExclusion;
|
||||
}
|
||||
$sql .= ' LIMIT 1';
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
return (bool)$stmt->fetchColumn();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user