Grosses mises à jour de shipmembers.php et adminstration.php pour revoir le process d'invitation sur un bateau mais aussi les sécurités de base sur les fichiers index.php et les fonctions_html.php

This commit is contained in:
2026-10-05 13:48:45 +00:00
parent 7146bce248
commit b7cb39bbe6
10 changed files with 2752 additions and 2511 deletions
+9 -8
View File
@@ -1,12 +1,13 @@
<?php <?php
require_once("fonctions_bdd.php"); // Contient les fonctions d'accès aux BDD. require_once(__DIR__.'/fonctions_acces.php'); // Contient les fonctions d'accès au site
require_once("fonctions_fichiers.php"); // Contient les fonctions de traitement des répertoires et des fichiers require_once(__DIR__.'/fonctions_bdd.php'); // Contient les fonctions d'accès aux BDD.
require_once("fonctions_ftp.php"); require_once(__DIR__.'/fonctions_fichiers.php'); // Contient les fonctions de traitement des répertoires et des fichiers
require_once("fonctions_html.php"); require_once(__DIR__.'/fonctions_ftp.php');
require_once("fonctions_mail.php"); // Contient les fonctions d'émission des emails require_once(__DIR__.'/fonctions_html.php');
require_once("fonctions_pdf.php"); // Contient les fonctions de création de fichiers PDF require_once(__DIR__.'/fonctions_mail.php'); // Contient les fonctions d'émission des emails
require_once("fonctions_traductions.php"); require_once(__DIR__.'/fonctions_pdf.php'); // Contient les fonctions de création de fichiers PDF
require_once("fonctions_utilitaires.php"); require_once(__DIR__.'/fonctions_traductions.php');
require_once(__DIR__.'/fonctions_utilitaires.php');
+324
View File
@@ -0,0 +1,324 @@
<?php
//************************************************************************************************************
// fonctions_acces.php - Accès des ShipMembers aux bateaux et invitations (synthèse §47)
//
// Regroupe ce qui était recopié dans shipmembers.php (5 blocs d'activation de code, 7 requêtes "accès actifs")
// et administration.php (1 + 1). Modèle de TB_Lien_bateau_shipmember :
// - Statut : 'en_attente' (invitation non acceptée), 'actif', 'suspendu', 'revoque' ;
// - une invitation désigne une adresse e-mail (Email_invite) : seul un compte ShipMember ACTIVÉ ayant cette
// adresse peut l'accepter (l'activation prouve le contrôle de la boîte - un compte non activé ne le prouve pas) ;
// - Expiration_invitation : date limite pour accepter ; Fin_validite : fin de l'accès accordé.
//
// Toutes les fonctions utilisent la connexion courante ($_SESSION['db'], ouverte par Ouverture_bdd()).
//************************************************************************************************************
// Alphabet des codes d'invitation : majuscules et chiffres SANS les caractères ambigus à la lecture (0/O, 1/I/L) -
// 31 symboles. 8 caractères présentés en deux groupes (ex : K7QX-M3PW), soit 31^8 = 8,5.10^11 combinaisons.
const CODE_INVITATION_ALPHABET = "23456789ABCDEFGHJKMNPQRSTUVWXYZ";
const CODE_INVITATION_LONGUEUR = 8;
// Durée de validité par défaut d'une invitation (jours), si TB_Configuration.Duree_validite_invitation n'est pas
// chargée en session :
const DUREE_VALIDITE_INVITATION_DEFAUT = 30;
//************************************************************************************************************
// Fonction : Nombre de lignes réellement modifiées par la DERNIÈRE requête exécutée sur la connexion courante.
// NB : mysqli_affected_rows() ne convient pas après Requete_preparee_bdd(), qui appelle
// mysqli_stmt_get_result() même pour un UPDATE - ce qui remet le compteur côté PHP à -1 (constaté en
// test). ROW_COUNT() interroge directement le serveur. À appeler IMMÉDIATEMENT après la requête.
// Reçoit : Rien
// Retour : Le nombre de lignes modifiées
//************************************************************************************************************
function Nb_lignes_modifiees()
{
$reponse = Requete_bdd("SELECT ROW_COUNT() AS nb", __FILE__, __LINE__);
$donnees = Recherche_ligne_bdd($reponse, MYSQLI_ASSOC);
Liberation_jeu_de_resultat_bdd($reponse);
return (int)$donnees['nb'];
}
//************************************************************************************************************
// Fonction : Liste des accès ACTIFS d'un ShipMember (statut 'actif' et Fin_validite non dépassée).
// Reçoit : La clé primaire du ShipMember
// Retour : Un tableau de lignes ['ID_Bateau', 'ID_Type_acces_bateau_shipmember'] (vide si aucun accès)
//************************************************************************************************************
function Acces_actifs_shipmember($id_shipmember)
{
$acces = [];
$requete = "SELECT ID_Bateau, ID_Type_acces_bateau_shipmember FROM TB_Lien_bateau_shipmember
WHERE ID_Shipmember=? AND Statut='actif' AND Fin_validite >= NOW()";
$reponse = Requete_preparee_bdd($requete, array(array('i', $id_shipmember)), __FILE__, __LINE__);
while ($donnees = Recherche_ligne_bdd($reponse, MYSQLI_ASSOC)) $acces[] = $donnees;
Liberation_jeu_de_resultat_bdd($reponse);
return $acces;
}
//************************************************************************************************************
// Fonction : Indique si le compte d'un ShipMember est activé, c'est-à-dire si son titulaire a prouvé qu'il
// contrôle l'adresse e-mail (connexion avec le mot de passe provisoire reçu, puis choix d'un mot de
// passe : la ligne TB_Activation est alors supprimée).
// Reçoit : La clé primaire du ShipMember
// Retour : true si activé
//************************************************************************************************************
function Compte_est_active($id_shipmember)
{
$reponse = Requete_preparee_bdd("SELECT COUNT(*) AS nb FROM TB_Activation WHERE ID_SHIPMEMBERS=?",
array(array('i', $id_shipmember)), __FILE__, __LINE__);
$donnees = Recherche_ligne_bdd($reponse, MYSQLI_ASSOC);
Liberation_jeu_de_resultat_bdd($reponse);
return ($donnees['nb'] == 0);
}
//************************************************************************************************************
// Fonction : Normalise un code d'invitation saisi ou reçu (majuscules, espaces et tirets retirés, puis tiret
// remis au milieu) et vérifie son format.
// Reçoit : La valeur brute (GET, POST, saisie manuelle...)
// Retour : Le code normalisé (ex : "K7QX-M3PW"), ou false si le format est invalide
//************************************************************************************************************
function Normaliser_code_invitation($valeur)
{
if (!is_string($valeur)) return false; // écarte ?code_acces[]=... (tableau)
$brut = strtoupper(preg_replace('/[\s-]/', '', $valeur));
$moitie = intdiv(CODE_INVITATION_LONGUEUR, 2);
if (preg_match('/^['.CODE_INVITATION_ALPHABET.']{'.CODE_INVITATION_LONGUEUR.'}\z/', $brut) !== 1) return false;
return substr($brut, 0, $moitie).'-'.substr($brut, $moitie);
}
//************************************************************************************************************
// Fonction : Génère un code d'invitation unique (générateur aléatoire cryptographique random_int).
// Reçoit : Rien
// Retour : Le code (ex : "K7QX-M3PW")
//************************************************************************************************************
function Generer_code_invitation()
{
$max = strlen(CODE_INVITATION_ALPHABET) - 1;
do
{
$brut = "";
for ($i = 0; $i < CODE_INVITATION_LONGUEUR; $i++) $brut .= CODE_INVITATION_ALPHABET[random_int(0, $max)];
$code = Normaliser_code_invitation($brut);
$reponse = Requete_preparee_bdd("SELECT COUNT(*) AS nb FROM TB_Lien_bateau_shipmember WHERE Code=?",
array(array('s', $code)), __FILE__, __LINE__);
$donnees = Recherche_ligne_bdd($reponse, MYSQLI_ASSOC);
Liberation_jeu_de_resultat_bdd($reponse);
}
while ($donnees['nb'] != 0);
return $code;
}
//************************************************************************************************************
// Fonction : Crée une invitation nominative (statut 'en_attente').
// Reçoit : Le bateau, l'adresse e-mail du destinataire (obligatoire), son prénom et son nom (facultatifs, pour
// l'affichage), le type d'accès, la fin de l'accès accordé (format 'Y-m-d', vide = sans limite) et le
// ShipMember qui invite.
// Retour : ['ok'=>true, 'id'=>int, 'code'=>string] ou ['ok'=>false, 'raison'=>string]
// NB : les droits de celui qui invite sont vérifiés par la page appelante.
//************************************************************************************************************
function Creer_invitation($id_bateau, $email, $prenom, $nom, $id_type_acces, $fin_acces, $id_cree_par)
{
$email = strtolower(trim((string)$email));
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) return ['ok' => false, 'raison' => t("Adresse e-mail invalide.")];
$prenom = trim((string)$prenom);
$nom = trim((string)$nom);
$prenom = ($prenom === '') ? null : mb_substr($prenom, 0, 50);
$nom = ($nom === '') ? null : mb_substr($nom, 0, 50);
// Type d'accès : doit exister et être valide (l'ancien type "Administrateur" est dévalidé) :
$reponse = Requete_preparee_bdd("SELECT COUNT(*) AS nb FROM TB_Types_acces_bateau_shipmember WHERE Cle_primaire=? AND Validite=1",
array(array('i', $id_type_acces)), __FILE__, __LINE__);
$donnees = Recherche_ligne_bdd($reponse, MYSQLI_ASSOC);
Liberation_jeu_de_resultat_bdd($reponse);
if ($donnees['nb'] == 0) return ['ok' => false, 'raison' => t("Type d'accès invalide.")];
// Fin de l'accès accordé : date du jour en fin de journée, ou sans limite :
if ($fin_acces === null || trim($fin_acces) === '') $fin_validite = '9999-12-31 23:59:59';
else
{
$date = date_create_from_format('Y-m-d', trim($fin_acces));
if ($date === false) return ['ok' => false, 'raison' => t("Date de fin d'accès invalide.")];
$fin_validite = $date->format('Y-m-d').' 23:59:59';
}
$duree = isset($_SESSION['Config__Duree_validite_invitation']) ? (int)$_SESSION['Config__Duree_validite_invitation'] : DUREE_VALIDITE_INVITATION_DEFAUT;
if ($duree <= 0) $duree = DUREE_VALIDITE_INVITATION_DEFAUT;
$code = Generer_code_invitation();
$requete = "INSERT INTO TB_Lien_bateau_shipmember
(Statut, ID_Shipmember, ID_Bateau, Email_invite, Prenom_invite, Nom_invite, Code, Expiration_invitation,
Fin_validite, Cree_par, ID_Type_acces_bateau_shipmember)
VALUES ('en_attente', 0, ?, ?, ?, ?, ?, DATE_ADD(NOW(), INTERVAL ? DAY), ?, ?, ?)";
Requete_preparee_bdd($requete, array(
array('i', $id_bateau), array('s', $email), array('s', $prenom), array('s', $nom),
array('s', $code), array('i', $duree), array('s', $fin_validite),
array('i', $id_cree_par), array('i', $id_type_acces)),
__FILE__, __LINE__);
return ['ok' => true, 'id' => Recuperation_id_cree_bdd(), 'code' => $code];
}
//************************************************************************************************************
// Fonction : Informations sur une invitation à partir de son code (bandeau d'accueil d'un lien d'invitation).
// Reçoit : Le code (brut ou normalisé)
// Retour : Un tableau (ID, Statut, Email_invite, Prenom_invite, Nom_invite, Nom_bateau, Type_acces,
// Expiree [0/1]) ou null si le code est inconnu ou mal formé
//************************************************************************************************************
function Invitation_par_code($code)
{
$code = Normaliser_code_invitation($code);
if ($code === false) return null;
$colonne_type = (isset($_SESSION['langue']) && $_SESSION['langue'] == 'EN') ? 'Nom_en' : 'Nom_fr';
$requete = "SELECT L.ID, L.Statut, L.Email_invite, L.Prenom_invite, L.Nom_invite, B.Nom AS Nom_bateau,
T.".$colonne_type." AS Type_acces,
(L.Expiration_invitation IS NOT NULL AND L.Expiration_invitation <= NOW()) AS Expiree
FROM TB_Lien_bateau_shipmember L
JOIN TB_Bateaux B ON B.Cle_primaire = L.ID_Bateau
LEFT JOIN TB_Types_acces_bateau_shipmember T ON T.Cle_primaire = L.ID_Type_acces_bateau_shipmember
WHERE L.Code=?";
$reponse = Requete_preparee_bdd($requete, array(array('s', $code)), __FILE__, __LINE__);
$donnees = Recherche_ligne_bdd($reponse, MYSQLI_ASSOC);
Liberation_jeu_de_resultat_bdd($reponse);
return $donnees ?: null;
}
//************************************************************************************************************
// Fonction : Invitations en attente (non expirées) adressées à une adresse e-mail.
// Reçoit : L'adresse e-mail du ShipMember connecté
// Retour : Un tableau de lignes (ID, Nom_bateau, Type_acces, Expiration_invitation, Prenom_invitant, Nom_invitant)
//************************************************************************************************************
function Invitations_en_attente($email)
{
$invitations = [];
$colonne_type = (isset($_SESSION['langue']) && $_SESSION['langue'] == 'EN') ? 'Nom_en' : 'Nom_fr';
$requete = "SELECT L.ID, B.Nom AS Nom_bateau, T.".$colonne_type." AS Type_acces, L.Expiration_invitation,
S.Prenom AS Prenom_invitant, S.Nom AS Nom_invitant
FROM TB_Lien_bateau_shipmember L
JOIN TB_Bateaux B ON B.Cle_primaire = L.ID_Bateau
LEFT JOIN TB_Types_acces_bateau_shipmember T ON T.Cle_primaire = L.ID_Type_acces_bateau_shipmember
LEFT JOIN TB_Shipmembers S ON S.ID = L.Cree_par
WHERE L.Statut='en_attente' AND L.Email_invite=?
AND (L.Expiration_invitation IS NULL OR L.Expiration_invitation > NOW())
ORDER BY L.Date_creation";
$reponse = Requete_preparee_bdd($requete, array(array('s', strtolower(trim((string)$email)))), __FILE__, __LINE__);
while ($donnees = Recherche_ligne_bdd($reponse, MYSQLI_ASSOC)) $invitations[] = $donnees;
Liberation_jeu_de_resultat_bdd($reponse);
return $invitations;
}
//************************************************************************************************************
// Fonction : Accepte une invitation pour le ShipMember connecté.
// Toutes les conditions (en attente, adresse identique, non expirée) sont vérifiées DANS la requête de
// mise à jour elle-même : une invitation ne peut donc être acceptée qu'une fois, même par deux
// requêtes simultanées.
// Reçoit : L'ID de l'invitation, la clé primaire et l'adresse e-mail du ShipMember connecté
// Retour : ['ok'=>true] ou ['ok'=>false, 'raison'=>string]
//************************************************************************************************************
function Accepter_invitation($id_lien, $id_shipmember, $email)
{
if (!Compte_est_active($id_shipmember))
{
return ['ok' => false, 'raison' => t("Votre compte doit être activé (mot de passe provisoire reçu par e-mail) avant de pouvoir accepter une invitation.")];
}
$requete = "UPDATE TB_Lien_bateau_shipmember
SET Statut='actif', ID_Shipmember=?, Date_activation=NOW()
WHERE ID=? AND Statut='en_attente' AND Email_invite=?
AND (Expiration_invitation IS NULL OR Expiration_invitation > NOW())";
Requete_preparee_bdd($requete, array(
array('i', $id_shipmember), array('i', $id_lien), array('s', strtolower(trim((string)$email)))),
__FILE__, __LINE__);
if (Nb_lignes_modifiees() == 1) return ['ok' => true];
return ['ok' => false, 'raison' => t("Cette invitation n'est plus valable (déjà utilisée, expirée, révoquée, ou adressée à une autre adresse).")];
}
//************************************************************************************************************
// Fonction : Refuse une invitation (elle passe à 'revoque').
// Reçoit : L'ID de l'invitation et l'adresse e-mail du ShipMember connecté
// Retour : true si l'invitation a bien été refusée
//************************************************************************************************************
function Refuser_invitation($id_lien, $email)
{
$requete = "UPDATE TB_Lien_bateau_shipmember SET Statut='revoque'
WHERE ID=? AND Statut='en_attente' AND Email_invite=?";
Requete_preparee_bdd($requete, array(array('i', $id_lien), array('s', strtolower(trim((string)$email)))), __FILE__, __LINE__);
return (Nb_lignes_modifiees() == 1);
}
//************************************************************************************************************
// Fonction : Masque partiellement une adresse e-mail pour l'afficher à quelqu'un qui n'est pas encore connecté
// (ex : "pierre.durand@exemple.fr" -> "p•••@exemple.fr").
// Reçoit : L'adresse
// Retour : L'adresse masquée
//************************************************************************************************************
function Masquer_email($email)
{
$position = strpos((string)$email, '@');
if ($position === false || $position == 0) return "•••";
return mb_substr($email, 0, 1).'•••'.substr($email, $position);
}
//************************************************************************************************************
// Clé du type d'accès "Propriétaire" dans TB_Types_acces_bateau_shipmember (cf Devalidation_profils = 1 : tous
// les types SAUF Propriétaire).
//************************************************************************************************************
const TYPE_ACCES_PROPRIETAIRE = 2;
//************************************************************************************************************
// Fonction : Charge un accès (ou une invitation) À CONDITION qu'il appartienne au bateau indiqué - toute action
// sur un accès passe par là, pour qu'un identifiant envoyé par le navigateur ne puisse jamais viser
// l'accès d'un autre bateau.
// Reçoit : L'ID de l'accès et la clé primaire du bateau affiché
// Retour : La ligne (ID, Statut, Code, ID_Type_acces_bateau_shipmember, Expiration_invitation) ou null
//************************************************************************************************************
function Lien_du_bateau($id_lien, $id_bateau)
{
$requete = "SELECT ID, Statut, Code, ID_Type_acces_bateau_shipmember, Expiration_invitation
FROM TB_Lien_bateau_shipmember WHERE ID=? AND ID_Bateau=?";
$reponse = Requete_preparee_bdd($requete, array(array('i', $id_lien), array('i', $id_bateau)), __FILE__, __LINE__);
$donnees = Recherche_ligne_bdd($reponse, MYSQLI_ASSOC);
Liberation_jeu_de_resultat_bdd($reponse);
return $donnees ?: null;
}
//************************************************************************************************************
// Fonction : Indique si l'utilisateur peut suspendre, réactiver ou révoquer un accès d'un type donné.
// Administrateur : toujours. Devalidation_profils = 2 : tous les types. = 1 : tous sauf Propriétaire.
// Reçoit : Les droits de l'utilisateur sur le bateau ($acces_profil), s'il est administrateur, le type visé
// Retour : true si autorisé
//************************************************************************************************************
function Peut_devalider_acces($acces_profil, $est_administrateur, $id_type_cible)
{
if ($est_administrateur) return true;
$niveau = isset($acces_profil['Devalidation_profils']) ? (int)$acces_profil['Devalidation_profils'] : 0;
if ($niveau >= 2) return true;
if ($niveau == 1) return ((int)$id_type_cible != TYPE_ACCES_PROPRIETAIRE);
return false;
}
//************************************************************************************************************
// Fonction : Met à jour en session la liste des accès actifs du ShipMember connecté ($_SESSION['bateau_shipmember']
// et $_SESSION['acces']), à partir de la base - la liste est REMPLACÉE (l'ancien code y ajoutait des
// lignes sans la vider : des accès révoqués pouvaient y rester jusqu'à la déconnexion).
// Reçoit : La clé primaire du ShipMember
// Retour : Rien
//************************************************************************************************************
function Rafraichir_acces_session($id_shipmember)
{
$_SESSION['bateau_shipmember'] = Acces_actifs_shipmember($id_shipmember);
$_SESSION['acces'] = count($_SESSION['bateau_shipmember']);
}
+396 -344
View File
@@ -1,344 +1,396 @@
<?php <?php
//************************************************************************************************************ //************************************************************************************************************
// Fonction : Initialisation de la session. A appeler avant tout envoi au client. // Fonction : Initialisation de la session. A appeler avant tout envoi au client.
// Reçoit : Rien // Reçoit : Rien
// Retour : Rien // Retour : Rien
//************************************************************************************************************ //************************************************************************************************************
function Init_session($nom_page) function Init_session($nom_page)
{ {
ini_set('arg_separator.output', '&amp;'); ini_set('arg_separator.output', '&amp;');
ini_set("url_rewriter.tags","a=href,area=href,frame=src,iframe=src,input=src"); // Ces deux lignes sont destinées à faire ajouter autoamtiquement &amp; au lieu de '&' dans la passage des variables de Session (nécessaire pour W3C validator...) ini_set("url_rewriter.tags","a=href,area=href,frame=src,iframe=src,input=src"); // Ces deux lignes sont destinées à faire ajouter autoamtiquement &amp; au lieu de '&' dans la passage des variables de Session (nécessaire pour W3C validator...)
session_set_cookie_params([ // Cookie de session : sans attribut domain (cookie réservé exactement au site), SameSite=Lax (synthèse §47) :
'lifetime' => 3600, session_set_cookie_params([
'path' => '/', 'lifetime' => 3600,
'secure' => true, 'path' => '/',
'httponly' => true, 'secure' => true,
'samesite' => 'Lax', 'httponly' => true,
]); 'samesite' => 'Lax',
]);
session_start(); // Ouverture de session (avant tout autre envoi au client!!!)
session_start(); // Ouverture de session (avant tout autre envoi au client!!!)
}
Initialiser_session();
}
//************************************************************************************************************
// Fonction : Insertion de l'entête des pages HTML ; essentiellement la partie <header></header>.
// Au passage, cette fonction étant la première appelée par chaque page (après l'ouverture //************************************************************************************************************
// de session obligatoire pour pouvoir accéder aux variables de session), on vérifie si // Fonction : Initialise une session neuve, UNE fois : valeurs par défaut, paramètres de TB_Configuration, langues,
// l'environnement est correctement positionné. Si ce n'est pas le cas, par exemple avec // textes. Auparavant fait uniquement par index.php : une page ouverte directement (lien d'invitation
// l'accès à la BDD non établi ou aucune langue sélectionnée, elle renvoit immédiatement // scanné sur un téléphone, favori...) utilisait des variables inexistantes (synthèse §47).
// vers le fichier 'index.php' qui s'en chargera. // Reçoit : Rien
// Reçoit : Rien // Retour : Rien
// Retour : Rien //************************************************************************************************************
//************************************************************************************************************ function Initialiser_session()
function Entete_page_html() {
{ if (isset($_SESSION['session_initialisee'])) return;
// Vérification à chaque ouverture de page que les variables de session sont bien initialisées (le test se fait sur quelques "échantillons" supposés représentatifs...) :
if ((!isset($_SESSION['langue'])) OR $_SESSION['acces_valide'] = false;
(!isset($_SESSION['display_menu']))) header('Location:index.php?origine='.basename($_SERVER['SCRIPT_FILENAME'])); $_SESSION['display_menu'] = false;
$_SESSION['langue'] = 'FR'; // Valeur par défaut, remplacée par Langue_par_defaut de TB_Configuration
// Entête HTML : $_SESSION['shipmember'] = array('Cle_primaire' => 0, 'Prenom' => "", 'Nom' => "", 'Entreprise' => "", 'Rue' => "",
echo '<!DOCTYPE html>'; 'Code_postal' => "", 'Ville' => "", 'ID_Pays' => 75, 'Telephone' => "", 'Email' => "",
'Commentaires' => "", 'Niveau_acces' => 0);
echo '<html lang="FR">'; $_SESSION['droits_acces'] = 0;
$_SESSION['bateau_shipmember'] = array();
echo '<head>'; $_SESSION['acces'] = 0;
echo '<meta charset="UTF-8">'; $_SESSION['modifier_texte'] = 0;
echo '<title>ShipHeart - Simplicity is true luxury</title>';
echo '<meta name="description" content="'.t("ShipHeart by Koriolan, la première centrale de vie à bord pour les bateaux de plaisance").'" />'; Ouverture_bdd();
echo '<meta name="keywords" content="ShipHeart" />';
echo '<meta content="text/html" http-equiv="content-type" />'; // Paramètres de configuration générale :
echo '<meta name="viewport" content="width=device-width, initial-scale=1">'; $reponse = Requete_bdd('SELECT Nom, Valeur FROM TB_Configuration WHERE Validite=1', __FILE__, __LINE__);
echo '<link rel="icon" type="image/png" href="images/favicon.png" />'; while ($donnees = Recherche_ligne_bdd($reponse))
{
if ($donnees['Nom'] == "Langue_par_defaut") $_SESSION['langue'] = $donnees['Valeur'];
echo "<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet'>"; else $_SESSION['Config__'.$donnees['Nom']] = $donnees['Valeur'];
echo "<link href='https://fonts.googleapis.com/css2?family=Oswald&display=swap' rel='stylesheet'>"; }
echo "<link rel='stylesheet' href='https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' integrity='sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=' crossorigin=''/>"; Liberation_jeu_de_resultat_bdd($reponse);
echo "<link rel='stylesheet' href='/vendor/noUiSlider/dist/nouislider.min.css'>"; // ID des langues selon leur préfixe :
echo "<script src='/vendor/noUiSlider/dist/nouislider.min.js'></script>"; $reponse = Requete_bdd('SELECT ID, Prefix FROM TB_Langues', __FILE__, __LINE__);
while ($donnees = Recherche_ligne_bdd($reponse)) $_SESSION['id_langue'][$donnees['Prefix']] = $donnees['ID'];
// gestion des fichiers CSS (et de scripts spécifiques à certains fichiers) : Liberation_jeu_de_resultat_bdd($reponse);
switch(basename($_SERVER['SCRIPT_FILENAME']))
{ Fermeture_bdd();
case "administration.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_administration.css" />'; break; }
case "textes.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_textes.css" />'; break; } chargement_langue(); // Textes de la langue en cours
case "bateaux.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_bateaux.css" />'; break; }
case "cartes.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_cartes.css" />'; break; } $_SESSION['session_initialisee'] = true;
case "mentions_legales.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_mentions_legales.css" />'; break; } }
case "shipmembers.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_shipmembers.css" />'; break; }
case "uploads.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_uploads.css" />'; break; }
case "versions.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_versions.css" />'; break; } //************************************************************************************************************
} // Fonction : Insertion de l'entête des pages HTML ; essentiellement la partie <header></header>.
// Au passage, cette fonction étant la première appelée par chaque page (après l'ouverture
echo '<link rel="stylesheet" type="text/css" href="/vendor/bootstrap/bootstrap.min.css" />'; // CSS de Bootstrap // de session obligatoire pour pouvoir accéder aux variables de session), on vérifie si
echo '<link rel="stylesheet" type="text/css" media="screen" href="format.css" />'; // CSS général, tous écrans. // l'environnement est correctement positionné. Si ce n'est pas le cas, par exemple avec
echo '<link rel="stylesheet" type="text/css" media="screen and (max-device-width : 667px)" href="format__telephone.css" />'; // CSS pour les petits écrans (doit être placé à la fin car il override les CSS globaux) // l'accès à la BDD non établi ou aucune langue sélectionnée, elle renvoit immédiatement
// vers le fichier 'index.php' qui s'en chargera.
// Chargement de srcipts JS généraux : // Reçoit : Rien
echo '<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>'; // Pour Google Charts (graphiques) // Retour : Rien
echo '<script src="/vendor/jQuery/jquery-3.6.0.min.js"></script>'; //************************************************************************************************************
function Entete_page_html()
{
// Vérification à chaque ouverture de page que les variables de session sont bien initialisées (le test se fait sur quelques "échantillons" supposés représentatifs...) :
if ((!isset($_SESSION['langue'])) OR
echo '</head>'; (!isset($_SESSION['display_menu'])))
{
echo '<body>'; header('Location:index.php?origine='.basename($_SERVER['SCRIPT_FILENAME']));
} exit();
}
//************************************************************************************************************
// Fonction : Insertion de l'entête des pages avec l'affichage du bandeau de titre et les menus. // Entête HTML :
// Puis affichage des messages d'erreur et d'information en les marquant de façon différenciée echo '<!DOCTYPE html>';
// selon que le menu est déployé ou non et/ou que le message d'erreur existe et/ou que le
// message d'information existe. echo '<html lang="FR">';
// Reçoit : Les message d'erreur et le message d'information (de plus, on retrouve le nom du fichier via les variables du serveur)
// Retour : Rien echo '<head>';
//************************************************************************************************************ echo '<meta charset="UTF-8">';
function Entete_page($message_erreur, $message_information) echo '<title>ShipHeart - Simplicity is true luxury</title>';
{ echo '<meta name="description" content="'.t("ShipHeart by Koriolan, la première centrale de vie à bord pour les bateaux de plaisance").'" />';
echo '<meta name="keywords" content="ShipHeart" />';
$nom_page = basename($_SERVER['SCRIPT_FILENAME']); echo '<meta content="text/html" http-equiv="content-type" />';
echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
// Détermination de la nouvelle langue par rapport à l'actuelle : echo '<link rel="icon" type="image/png" href="images/favicon.png" />';
if ($_SESSION['langue'] == "FR") $new_langue = "EN";
else $new_langue = "FR";
echo "<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet'>";
echo "<link href='https://fonts.googleapis.com/css2?family=Oswald&display=swap' rel='stylesheet'>";
echo '<div id="entete">'; echo "<link rel='stylesheet' href='https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' integrity='sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=' crossorigin=''/>";
//---------------------------------- echo "<link rel='stylesheet' href='/vendor/noUiSlider/dist/nouislider.min.css'>";
// Bandeau gauche : echo "<script src='/vendor/noUiSlider/dist/nouislider.min.js'></script>";
echo '<div id="logo_home">
<a id="home" href=""> // gestion des fichiers CSS (et de scripts spécifiques à certains fichiers) :
<a href="shipmembers.php" style="padding: 0;" id="logo_heart_a" title="'.t("Retour à l'accueil").'"> switch(basename($_SERVER['SCRIPT_FILENAME']))
<div id="logo_heart"> </div> {
<div id="logo_texte"> </div> case "administration.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_administration.css" />'; break; }
</a> case "textes.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_textes.css" />'; break; }
</a> case "bateaux.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_bateaux.css" />'; break; }
</div>'; case "cartes.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_cartes.css" />'; break; }
case "mentions_legales.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_mentions_legales.css" />'; break; }
// echo '<div id="menu_mobile"> </div> '; case "shipmembers.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_shipmembers.css" />'; break; }
// echo '<div id="nav_bar_global" style="display: none;">'; case "uploads.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_uploads.css" />'; break; }
case "versions.php" : { echo '<link rel="stylesheet" type="text/css" media="screen" href="format_versions.css" />'; break; }
//---------------------------------- }
// Bandeau droit :
echo '<div id="navbar_right">'; echo '<link rel="stylesheet" type="text/css" href="/vendor/bootstrap/bootstrap.min.css" />'; // CSS de Bootstrap
echo '<link rel="stylesheet" type="text/css" media="screen" href="format.css" />'; // CSS général, tous écrans.
//---------------------------------- echo '<link rel="stylesheet" type="text/css" media="screen and (max-device-width : 667px)" href="format__telephone.css" />'; // CSS pour les petits écrans (doit être placé à la fin car il override les CSS globaux)
// Bouton LANGUE :
echo '<div id="flag_lang">'; // Chargement de srcipts JS généraux :
echo '<a class="'.$new_langue.'_acc" title="'.t("Switch to English...").'" href="'.$nom_page.'?action=changement_langue&langue='.$new_langue.'"> echo '<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>'; // Pour Google Charts (graphiques)
</a>'; echo '<script src="/vendor/jQuery/jquery-3.6.0.min.js"></script>';
echo '</div>';
//----------------------------------
// Bouton SHIPMEMBER ACCESS :
echo '<div id="logo_shipmember">'; echo '</head>';
echo '<div id="shipmember">';
if ($_SESSION['acces_valide']) echo '<body>';
{ }
echo '<a title="'.t("Accès validé pour ").' '.$_SESSION['shipmember']['Prenom'].'" href="shipmembers.php?action=navigation&destination=Accueil">
<span class="acces_valide">'.substr($_SESSION['shipmember']['Prenom'],0,1).'</span> //************************************************************************************************************
</a>'; // Fonction : Insertion de l'entête des pages avec l'affichage du bandeau de titre et les menus.
} // Puis affichage des messages d'erreur et d'information en les marquant de façon différenciée
// else echo '<a title="'.$_SESSION['textes']['fonctions']['entete']['ligne_icones']['shipmember_a_title'].'" href="shipmembers.php?action=navigation&destination=Accueil"> </a>'; // selon que le menu est déployé ou non et/ou que le message d'erreur existe et/ou que le
echo '</div>'; // message d'information existe.
echo "</div>"; // Reçoit : Les message d'erreur et le message d'information (de plus, on retrouve le nom du fichier via les variables du serveur)
// Retour : Rien
echo '</div>'; //************************************************************************************************************
function Entete_page($message_erreur, $message_information)
{
echo '</div>';
$nom_page = basename($_SERVER['SCRIPT_FILENAME']);
//-------------------------------------------------------------------------------------------- // Détermination de la nouvelle langue par rapport à l'actuelle :
// Menu afficher / masquer -- Mobile if ($_SESSION['langue'] == "FR") $new_langue = "EN";
//-------------------------------------------------------------------------------------------- else $new_langue = "FR";
echo '<script>
window.onload = function () {
pro = document.getElementsByClassName("portail_pro"); echo '<div id="entete">';
par = document.getElementsByClassName("portail_par");
if ($(window).width() > 850) { //----------------------------------
if (pro.length > 0) { for (i = 0; i < pro.length ; i++){ pro[i].hidden=true; } document.getElementById(\'par_p\').hidden = true } // Bandeau gauche :
if (par.length > 0) { for (i = 0; i < par.length ; i++){ par[i].hidden=true; } document.getElementById(\'pro_p\').hidden = true } echo '<div id="logo_home">
document.getElementById(\'img_type\').hidden= false; <a id="home" href="">
document.getElementById(\'logo_heart_a\').href = "bienvenue.php"; <a href="shipmembers.php" style="padding: 0;" id="logo_heart_a" title="'.t("Retour à l'accueil").'">
} else { <div id="logo_heart"> </div>
if (pro.length > 0) { for (i = 0; i < pro.length ; i++){ pro[i].hidden=false; } document.getElementById(\'par_p\').hidden = false } <div id="logo_texte"> </div>
if (par.length > 0) { for (i = 0; i < par.length ; i++){ par[i].hidden=false; } document.getElementById(\'pro_p\').hidden = false } </a>
document.getElementById(\'img_type\').hidden= true; </a>
document.getElementById(\'logo_heart_a\').href = "accueil.php"; </div>';
}
} ; // echo '<div id="menu_mobile"> </div> ';
$(document).ready(function(){ // echo '<div id="nav_bar_global" style="display: none;">';
function menu_control(){
hidden_div = document.getElementById("nav_bar_global").style.display; //----------------------------------
hidden_div.replace(/[\u200B-\u200D\uFEFF]/g, \'\'); // Bandeau droit :
echo '<div id="navbar_right">';
if (hidden_div == "block") hidden_div = "none";
else if (hidden_div == "none") hidden_div = "block"; //----------------------------------
document.getElementById("nav_bar_global").style.display=hidden_div; // Bouton LANGUE :
}; echo '<div id="flag_lang">';
$("#menu_mobile").click(menu_control); echo '<a class="'.$new_langue.'_acc" title="'.t("Switch to English...").'" href="'.$nom_page.'?action=changement_langue&langue='.$new_langue.'">
}); </a>';
echo '</div>';
window.addEventListener(\'click\', function(e){ //----------------------------------
if (!document.getElementById(\'nav_bar_global\').contains(e.target) && !document.getElementById(\'menu_mobile\').contains(e.target) ){ // Bouton SHIPMEMBER ACCESS :
document.getElementById("nav_bar_global").style.display="none"; echo '<div id="logo_shipmember">';
} echo '<div id="shipmember">';
}); if ($_SESSION['acces_valide'])
{
window.addEventListener(\'touchstart\', function(e){ echo '<a title="'.t("Accès validé pour ").' '.$_SESSION['shipmember']['Prenom'].'" href="shipmembers.php?action=navigation&destination=Accueil">
if (!document.getElementById(\'nav_bar_global\').contains(e.target) && !document.getElementById(\'menu_mobile\').contains(e.target) ){ <span class="acces_valide">'.substr($_SESSION['shipmember']['Prenom'],0,1).'</span>
document.getElementById("nav_bar_global").style.display="none"; </a>';
} }
}); // else echo '<a title="'.$_SESSION['textes']['fonctions']['entete']['ligne_icones']['shipmember_a_title'].'" href="shipmembers.php?action=navigation&destination=Accueil"> </a>';
echo '</div>';
$(window).resize(function() { echo "</div>";
pro = document.getElementsByClassName("portail_pro");
par = document.getElementsByClassName("portail_par"); echo '</div>';
if ($(this).width() > 850) {
if (pro.length > 0) { for (i = 0; i < pro.length ; i++){ pro[i].hidden=true; } document.getElementById(\'par_p\').hidden = true }
if (par.length > 0) { for (i = 0; i < par.length ; i++){ par[i].hidden=true; } document.getElementById(\'pro_p\').hidden = true } echo '</div>';
document.getElementById(\'img_type\').hidden= false;
document.getElementById(\'logo_heart_a\').href = "bienvenue.php";
} else { //--------------------------------------------------------------------------------------------
if (pro.length > 0) { for (i = 0; i < pro.length ; i++){ pro[i].hidden=false; } document.getElementById(\'par_p\').hidden = false } // Menu afficher / masquer -- Mobile
if (par.length > 0) { for (i = 0; i < par.length ; i++){ par[i].hidden=false; } document.getElementById(\'pro_p\').hidden = false } //--------------------------------------------------------------------------------------------
document.getElementById(\'img_type\').hidden= true; echo '<script>
document.getElementById(\'logo_heart_a\').href = "accueil.php"; window.onload = function () {
} pro = document.getElementsByClassName("portail_pro");
}); par = document.getElementsByClassName("portail_par");
</script>'; if ($(window).width() > 850) {
if (pro.length > 0) { for (i = 0; i < pro.length ; i++){ pro[i].hidden=true; } document.getElementById(\'par_p\').hidden = true }
if (par.length > 0) { for (i = 0; i < par.length ; i++){ par[i].hidden=true; } document.getElementById(\'pro_p\').hidden = true }
//-------------------------------------------------------------------------------------------- document.getElementById(\'img_type\').hidden= false;
// Script d'affichage/masquage du menu : document.getElementById(\'logo_heart_a\').href = "bienvenue.php";
//-------------------------------------------------------------------------------------------- } else {
if (pro.length > 0) { for (i = 0; i < pro.length ; i++){ pro[i].hidden=false; } document.getElementById(\'par_p\').hidden = false }
if (par.length > 0) { for (i = 0; i < par.length ; i++){ par[i].hidden=false; } document.getElementById(\'pro_p\').hidden = false }
//-------------------------------------------------------------------------------------------- document.getElementById(\'img_type\').hidden= true;
// Affichage des messages d'erreur et d'info sous le menu : document.getElementById(\'logo_heart_a\').href = "accueil.php";
//-------------------------------------------------------------------------------------------- }
if (!PRODUCTION) $message_erreur .= "/!\ Base de données de test [".BDD_DATABASE."]<br />"; } ;
// else $message_erreur .= "Base de données de production [".BDD_DATABASE."]<br />"; $(document).ready(function(){
function menu_control(){
if ($message_erreur != "") echo '<div class="message_erreur">'.$message_erreur.'</div>'; hidden_div = document.getElementById("nav_bar_global").style.display;
if ($message_information != "") echo '<div class="message_information">'.$message_information.'</div>'; hidden_div.replace(/[\u200B-\u200D\uFEFF]/g, \'\');
} if (hidden_div == "block") hidden_div = "none";
else if (hidden_div == "none") hidden_div = "block";
document.getElementById("nav_bar_global").style.display=hidden_div;
};
$("#menu_mobile").click(menu_control);
//************************************************************************************************************ });
// Fonction : Insertion du pied de page
// Reçoit : Rien (mais on retrouve le nom du fichier via les variables du serveur)
// Retour : Rien window.addEventListener(\'click\', function(e){
//************************************************************************************************************ if (!document.getElementById(\'nav_bar_global\').contains(e.target) && !document.getElementById(\'menu_mobile\').contains(e.target) ){
function Pied_de_page() document.getElementById("nav_bar_global").style.display="none";
{ }
$nom_page = basename($_SERVER['SCRIPT_FILENAME']); });
// echo "<script src='https://unpkg.com/leaflet@1.9.4/dist/leaflet.js' integrity='sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=' crossorigin=''> </script>"; window.addEventListener(\'touchstart\', function(e){
if (!document.getElementById(\'nav_bar_global\').contains(e.target) && !document.getElementById(\'menu_mobile\').contains(e.target) ){
echo '<div id="pied_de_page" style="display: none;">'; document.getElementById("nav_bar_global").style.display="none";
echo '<div class="gauche" id="gauche" style="height: 210px;">'; }
echo '<div class="marque" id="marque"> });
<p id="marque_texte">'.t("ShipHeart ™ est une marque de Koriolan").'</p> $(window).resize(function() {
pro = document.getElementsByClassName("portail_pro");
<div class="signature" id="signature"> par = document.getElementsByClassName("portail_par");
<a style="padding: 0;" title="'.t("Accéder à notre site Koriolan").'" href="https://koriolan.tech/" target="_blank"> if ($(this).width() > 850) {
<img src="images/logo_koriolan_rvb.png"> if (pro.length > 0) { for (i = 0; i < pro.length ; i++){ pro[i].hidden=true; } document.getElementById(\'par_p\').hidden = true }
</a> if (par.length > 0) { for (i = 0; i < par.length ; i++){ par[i].hidden=true; } document.getElementById(\'pro_p\').hidden = true }
</div>'; document.getElementById(\'img_type\').hidden= false;
document.getElementById(\'logo_heart_a\').href = "bienvenue.php";
echo '</div>'; } else {
echo '</div>'; if (pro.length > 0) { for (i = 0; i < pro.length ; i++){ pro[i].hidden=false; } document.getElementById(\'par_p\').hidden = false }
if (par.length > 0) { for (i = 0; i < par.length ; i++){ par[i].hidden=false; } document.getElementById(\'pro_p\').hidden = false }
echo '<div class="droite" id="droite" style="height: 210px;">'; document.getElementById(\'img_type\').hidden= true;
document.getElementById(\'logo_heart_a\').href = "accueil.php";
echo '<div class="mentions_legales" id="mentions_legales">'; }
});
if ($nom_page != "mentions_legales.php") </script>';
{
echo '<a title="'.t("Mentions légales").'" href="mentions_legales.php">
'.t("Mentions légales").' //--------------------------------------------------------------------------------------------
</a>'; // Script d'affichage/masquage du menu :
} //--------------------------------------------------------------------------------------------
else
{
echo '<a title="'.t("Retour").'" href="shipmembers.php"> //--------------------------------------------------------------------------------------------
'.t("Retour").' // Affichage des messages d'erreur et d'info sous le menu :
</a>'; //--------------------------------------------------------------------------------------------
} if (!PRODUCTION) $message_erreur .= "/!\ Base de données de test [".BDD_DATABASE."]<br />";
echo '</div>'; // else $message_erreur .= "Base de données de production [".BDD_DATABASE."]<br />";
echo '</div>';
echo '</div>'; if ($message_erreur != "") echo '<div class="message_erreur">'.$message_erreur.'</div>';
if ($message_information != "") echo '<div class="message_information">'.$message_information.'</div>';
echo '<div id="pied_de_page_mobile" >';
echo '</div>'; }
//==================================================================================
// Script JS pour pieds de page : //************************************************************************************************************
?><script> // Fonction : Insertion du pied de page
// Reçoit : Rien (mais on retrouve le nom du fichier via les variables du serveur)
function footer () // Retour : Rien
{ //************************************************************************************************************
if (window.innerWidth <= 850) //Footer mobile : function Pied_de_page()
{ {
document.getElementById('pied_de_page_mobile').appendChild(document.getElementById('mentions_legales')); $nom_page = basename($_SERVER['SCRIPT_FILENAME']);
document.getElementById('pied_de_page_mobile').appendChild(document.getElementById('marque_texte'));
document.getElementById('pied_de_page_mobile').appendChild(document.getElementById('signature')); // echo "<script src='https://unpkg.com/leaflet@1.9.4/dist/leaflet.js' integrity='sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=' crossorigin=''> </script>";
}
else //Footer "normal" : echo '<div id="pied_de_page" style="display: none;">';
{ echo '<div class="gauche" id="gauche" style="height: 210px;">';
document.getElementById('droite').appendChild(document.getElementById('mentions_legales')); echo '<div class="marque" id="marque">
document.getElementById('marque').appendChild(document.getElementById('marque_texte'));
document.getElementById('marque').appendChild(document.getElementById('signature')); <p id="marque_texte">'.t("ShipHeart ™ est une marque de Koriolan").'</p>
}
} <div class="signature" id="signature">
<a style="padding: 0;" title="'.t("Accéder à notre site Koriolan").'" href="https://koriolan.tech/" target="_blank">
document.onreadystatechange = function() <img src="images/logo_koriolan_rvb.png">
{ </a>
footer(); </div>';
page = "<?php echo $nom_page ?>";
if (page == "faq.php") echo '</div>';
{ echo '</div>';
show_hide('0');
echo '<div class="droite" id="droite" style="height: 210px;">';
for(var k = 0; k < reponses.length; k++)
{ echo '<div class="mentions_legales" id="mentions_legales">';
document.getElementById(reponses[k].id).hidden=true;
} if ($nom_page != "mentions_legales.php")
} {
}; echo '<a title="'.t("Mentions légales").'" href="mentions_legales.php">
'.t("Mentions légales").'
window.addEventListener('resize', function(event) </a>';
{ }
footer(); else
}); {
echo '<a title="'.t("Retour").'" href="shipmembers.php">
</script><?php '.t("Retour").'
// Fin du script JS </a>';
//==================================================================================== }
echo '</div>';
echo '</div>';
echo '</body>'; echo '</div>';
echo '</html>'; echo '<div id="pied_de_page_mobile" >';
echo '</div>';
} // Fin de la fonction Pied_de_page()
//==================================================================================
// Script JS pour pieds de page :
?><script>
function footer ()
{
if (window.innerWidth <= 850) //Footer mobile :
{
document.getElementById('pied_de_page_mobile').appendChild(document.getElementById('mentions_legales'));
document.getElementById('pied_de_page_mobile').appendChild(document.getElementById('marque_texte'));
document.getElementById('pied_de_page_mobile').appendChild(document.getElementById('signature'));
}
else //Footer "normal" :
{
document.getElementById('droite').appendChild(document.getElementById('mentions_legales'));
document.getElementById('marque').appendChild(document.getElementById('marque_texte'));
document.getElementById('marque').appendChild(document.getElementById('signature'));
}
}
document.onreadystatechange = function()
{
footer();
page = "<?php echo $nom_page ?>";
if (page == "faq.php")
{
show_hide('0');
for(var k = 0; k < reponses.length; k++)
{
document.getElementById(reponses[k].id).hidden=true;
}
}
};
window.addEventListener('resize', function(event)
{
footer();
});
</script><?php
// Fin du script JS
//====================================================================================
echo '</body>';
echo '</html>';
} // Fin de la fonction Pied_de_page()
+91 -99
View File
@@ -251,92 +251,9 @@ class MYPDF2 extends TCPDF {
//******************************************************************************************************************************** //********************************************************************************************************************************
// Fonction : Génère le document PDF à partir des données reçues en paramètres // Fonction : URL d'activation d'un code d'invitation, portée par le QR code ET par le lien cliquable du PDF d'invitation.
// Reçoit : type du document (1er code généré pour le bateau, code généré par un autre utilisateur)
// client concerné a qui on envoie le pdf et le code d'accès pour générer le code QR.
// Retour : 0 si Ok, -1 si erreur
//********************************************************************************************************************************
function code_acces_pdf($code, $no, $no_serie = "XX:XX:XX:XX:XX:XX", $client = "")
{
$nom_piece = $no."_Code_acces_bateau_".$no_serie;
$pdf = new MYPDF2('LANDSCAPE', 'px', 'A4', true, 'UTF-8', false);
// set document (meta) information :
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Koriolan');
$pdf->SetTitle($nom_piece);
$pdf->SetSubject('ShipHeart');
$pdf->SetKeywords('ShipHeart by Koriolan');
$pdf->SetTextColor(0, 69, 99);
$pdf->SetFont('helvetica', '', 10);
$pdf->AddPage();
$pdf->SetDrawColor(217,217,217);
$pdf->Line(421, 0, 421, 595);
// First page
$pdf->Image('images/logo_shipheart.png', 506, 214, 252, 167, 'PNG', 'https://shipheart.tech');
// Firth page
$pdf->Image('images/logo_shipheart.png', 12, 12, 64, 45, 'PNG', 'https://shipheart.tech');
$pdf->CreateTextBox("Nous vous remercions pour votre confiance et sommes ravis de vous offrir un accès complet aux informations de votre bateau via notre platforme Ship2net.
We thank you for your trust and are delighted to offer you full access to your boat information via our Ship2net platform.", 52, 166, 317, 195, 12);
$pdf->CreateTextBox($no_serie, 0, 520, 421, 46, 12, '', 'C', 0);
// $pdf->AddPage();
$pdf->SetDrawColor(217,217,217);
$pdf->Line(421, 0, 421, 595);
// Second page
$pdf->Image('images/logo_shipheart.png', 12, 12, 64, 45, 'PNG', 'https://shipheart.tech');
$pdf->Image('images/logo_shipheart.png', 766, 12, 64, 45, 'PNG', 'https://shipheart.tech');
$pdf->CreateTextBox("Pour activer votre accès au bateau merci de scanner le QR code ci-joint et de vous connecter à votre profil ShipMember existant ou d'en créer un.
To activate your boat access please scan the attached QR code and log in to your existing ShipMember profile or create one.", 52, 218, 317, 160, 12);
// Third page
$pdf->Image(generateCode($code), 546, 216, 164, 164, 'PNG', Url_activation_code_acces($code));
// ---------------------------------------------------------
// Fermeture de l'objet PDF et enreigistrement du fichier :
ob_clean(); // Semble nécessaire ; sinon erreur du 'output' suivant
$pdf_string = $pdf->Output('pseudo.pdf', 'S'); // export du flux dans une chaine (le nom du fichier est ignoré...)
// Copie de cette chaine dans le fichier final (cette solution en 2 temps permet d'éviter de devoir utiliser un nom de fichier absolu (semble obligatoire avec Output et l'option 'F')
file_put_contents('temp/PDF/'.$nom_piece.'.pdf', $pdf_string);
$_SESSION['pdf']['src'] = 'temp/PDF/'.$nom_piece.'.pdf';
// Sauvegarder le pdf automatiquement
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=".$nom_piece.".pdf");
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
// Read the file
readfile($_SESSION['pdf']['src']);
// Suppression du pdf et codeqr du serveur
unlink('temp/CodeQR/'.$code.'.png');
unlink($_SESSION['pdf']['src']);
return(0);
}
//********************************************************************************************************************************
// Fonction : URL d'activation d'un code d'accès bateau, portée par le QR code ET par le lien cliquable du PDF d'invitation.
// Construite à partir de URL_SITE (definitions.php) : plus d'adresse écrite en dur (synthèse §47). // Construite à partir de URL_SITE (definitions.php) : plus d'adresse écrite en dur (synthèse §47).
// Reçoit : le code d'accès // Reçoit : le code d'invitation
// Retour : l'URL complète // Retour : l'URL complète
//******************************************************************************************************************************** //********************************************************************************************************************************
function Url_activation_code_acces($code) function Url_activation_code_acces($code)
@@ -344,21 +261,96 @@ function Url_activation_code_acces($code)
return 'https://'.URL_SITE.'/shipmembers.php?code_acces='.urlencode($code); return 'https://'.URL_SITE.'/shipmembers.php?code_acces='.urlencode($code);
} }
function generateCode($code){
$tempDir = "temp/CodeQR/";
$codeContents = Url_activation_code_acces($code);
$fileName = $code.'.png'; //********************************************************************************************************************************
// Fonction : Image PNG d'un QR code, produite EN MÉMOIRE (aucun fichier temporaire : l'ancienne version écrivait le QR code
$pngAbsoluteFilePath = $tempDir.$fileName; // et le PDF dans html/temp/, donc dans la partie publique du site - synthèse §47).
$urlRelativeFilePath = $tempDir.$fileName; // Reçoit : le texte à encoder
// Retour : le contenu binaire de l'image PNG
// generating //********************************************************************************************************************************
if (!file_exists($pngAbsoluteFilePath)) { function Qr_code_png($texte)
QRcode::png($codeContents, $pngAbsoluteFilePath); {
} ob_start();
return $urlRelativeFilePath; QRcode::png($texte, false, QR_ECLEVEL_M, 8, 2); // false = sortie standard, capturée par le tampon
$png = ob_get_clean();
header_remove('Content-Type'); // phpqrcode a posé un en-tête image/png : retiré, le PDF posera le sien
return $png;
} }
//********************************************************************************************************************************
// Fonction : Génère et ENVOIE au navigateur le PDF d'une invitation nominative à accéder à un bateau (synthèse §47).
// La page appelante doit s'arrêter juste après (exit) : rien ne doit suivre le PDF.
// Reçoit : l'invitation (tableau) : Code, Nom_bateau, Email_invite, Prenom_invite, Nom_invite, Type_acces,
// Expiration_invitation
// Retour : rien (le PDF est envoyé en téléchargement)
//********************************************************************************************************************************
function code_acces_pdf($invitation)
{
$code = $invitation['Code'];
$nom_bateau = $invitation['Nom_bateau'];
$email = $invitation['Email_invite'];
$destinataire = trim(($invitation['Prenom_invite'] ?? '').' '.($invitation['Nom_invite'] ?? ''));
$type_acces = $invitation['Type_acces'] ?? '';
$expiration = ($invitation['Expiration_invitation'] != NULL) ? date_format(date_create($invitation['Expiration_invitation']), 'd/m/Y') : '';
$nom_fichier = 'Invitation_'.preg_replace('/[^A-Za-z0-9_-]/', '_', $nom_bateau).'_'.$code.'.pdf';
$pdf = new MYPDF2('LANDSCAPE', 'px', 'A4', true, 'UTF-8', false);
// set document (meta) information :
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Koriolan');
$pdf->SetTitle('Invitation - '.$nom_bateau);
$pdf->SetSubject('ShipHeart');
$pdf->SetKeywords('ShipHeart by Koriolan');
$pdf->SetTextColor(0, 69, 99);
$pdf->SetFont('helvetica', '', 10);
$pdf->SetAutoPageBreak(false); // Mise en page fixe sur 2 feuilles : pas de saut de page automatique (l'ancienne version
// obtenait sa 2e feuille par un saut automatique, déclenché par le texte du bas de la 1re)
//---------------------------------------------------------
// Feuille 1 (pliée en deux : à droite la couverture, à gauche le mot d'accueil) :
$pdf->AddPage();
$pdf->SetDrawColor(217,217,217);
$pdf->Line(421, 0, 421, 595);
$pdf->Image('images/logo_shipheart.png', 506, 214, 252, 167, 'PNG', 'https://shipheart.tech'); // Couverture
$pdf->Image('images/logo_shipheart.png', 12, 12, 64, 45, 'PNG', 'https://shipheart.tech');
$salutation = ($destinataire != '') ? $destinataire.",\n\n" : '';
$pdf->CreateTextBox($salutation."Nous vous remercions pour votre confiance et sommes ravis de vous offrir un accès aux informations du bateau ".$nom_bateau." via notre plateforme Ship2net.\n\n"
."We thank you for your trust and are delighted to offer you access to the information of the boat ".$nom_bateau." via our Ship2net platform.",
52, 150, 317, 230, 12, '', 'L');
$pdf->CreateTextBox($nom_bateau.(($type_acces != '') ? ' - '.$type_acces : ''), 0, 520, 421, 46, 12, 'B', 'C');
//---------------------------------------------------------
// Feuille 2 (à gauche le mode d'emploi, à droite le QR code et le code) :
$pdf->AddPage();
$pdf->SetDrawColor(217,217,217);
$pdf->Line(421, 0, 421, 595);
$pdf->Image('images/logo_shipheart.png', 12, 12, 64, 45, 'PNG', 'https://shipheart.tech');
$pdf->Image('images/logo_shipheart.png', 766, 12, 64, 45, 'PNG', 'https://shipheart.tech');
$pdf->CreateTextBox("Cette invitation est réservée à l'adresse ".$email.".\n"
."Pour l'activer, scannez le QR code ci-contre, puis connectez-vous à votre compte ShipMember avec cette adresse (ou créez votre compte avec cette adresse).\n"
."Sans appareil photo : rendez-vous sur ".URL_SITE." et connectez-vous avec cette adresse ; l'invitation apparaîtra dans « Mes invitations ».\n"
.(($expiration != '') ? "Invitation valable jusqu'au ".$expiration.".\n" : '')
."\n"
."This invitation is reserved for the address ".$email.".\n"
."To activate it, scan the QR code opposite, then log in to your ShipMember account with this address (or create your account with this address).\n"
."Without a camera: go to ".URL_SITE." and log in with this address; the invitation will appear in \"My invitations\".\n"
.(($expiration != '') ? "Invitation valid until ".$expiration."." : ''),
52, 110, 317, 400, 11, '', 'L');
$pdf->Image('@'.Qr_code_png(Url_activation_code_acces($code)), 546, 196, 164, 164, 'PNG', Url_activation_code_acces($code));
$pdf->CreateTextBox($code, 506, 372, 244, 30, 18, 'B', 'C');
$pdf->CreateTextBox(URL_SITE, 506, 400, 244, 20, 11, '', 'C');
//---------------------------------------------------------
// Envoi direct au navigateur, sans fichier intermédiaire. Tout ce qui aurait déjà été mis en tampon (espaces,
// avertissements...) est jeté : un seul octet parasite avant le PDF le corromprait.
while (ob_get_level() > 0) ob_end_clean();
$pdf->Output($nom_fichier, 'D');
}
+2 -30
View File
@@ -162,7 +162,7 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session
// Récupération des informations sur le ou les bateaux accessibles à ce ShipMember : // Récupération des informations sur le ou les bateaux accessibles à ce ShipMember :
$nb_bateaux = 0; $nb_bateaux = 0;
$requete = 'SELECT * FROM TB_Lien_bateau_shipmember WHERE ID_SHIPMEMBER=? '; $requete = "SELECT * FROM TB_Lien_bateau_shipmember WHERE ID_SHIPMEMBER=? AND Statut IN ('actif','suspendu')"; // Hors invitations et accès révoqués (synthèse §47)
$reponse = Requete_preparee_bdd($requete, $reponse = Requete_preparee_bdd($requete,
array( array(
array('i', $_SESSION['Administration']['id_shipmember'])), array('i', $_SESSION['Administration']['id_shipmember'])),
@@ -187,36 +187,8 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session
} }
Liberation_jeu_de_resultat_bdd($reponse); Liberation_jeu_de_resultat_bdd($reponse);
} }
// Créer le lien bateau shipmember, affecter l'enregitrement a cet utilisateur
if (isset($_SESSION['code_acces']) && $_SESSION['code_acces']!=''){
$code = $_SESSION['code_acces'];
$requete = 'SELECT * FROM TB_Lien_bateau_shipmember WHERE Validite=1 AND Code=? AND ID_Shipmember=0';
$reponse = Requete_preparee_bdd($requete, array(array('s', $code)), __FILE__, __LINE__);
$donnees = Recherche_ligne_bdd($reponse);
// Vérifier si le code est tjrs valable
if ($donnees == NULL){
$message_erreur .= "Code invalide ou déjà utilisé \n";
$_SESSION['code_acces'] = '';
}
else {
$sous_req = 'UPDATE TB_Lien_bateau_shipmember SET ID_Shipmember=? WHERE Validite=1 AND Code=? AND ID_Shipmember=0';
$sous_rep = Requete_preparee_bdd($sous_req, array(array('i', $_SESSION['shipmember']['Cle_primaire']), array('s', $code)), __FILE__, __LINE__);
$_SESSION['code_acces'] = '';
// $_SESSION['droits_acces'] = $donnees['Niveau_acces'];
}
}
// Récupération des liaisons shipmember - bateau Rafraichir_acces_session($_SESSION['shipmember']['Cle_primaire']); // Accès actifs (synthèse §47)
$current_timestamp = date_format(date_create(), 'Y-m-d H:i:s');
$requete = 'SELECT ID_Bateau, ID_Type_acces_bateau_shipmember FROM TB_Lien_bateau_shipmember WHERE ID_Shipmember='.$_SESSION['shipmember']['Cle_primaire'].' AND Validite=1 AND Validite_acces=1 AND Fin_validite>="'.$current_timestamp.'"';
$reponse = Requete_bdd($requete, __FILE__, __LINE__);
$nb_acces = 0;
// $bateau_shipmember = []
while ($donnees = Recherche_ligne_bdd($reponse)) {
$_SESSION['bateau_shipmember'][$nb_acces++] = $donnees;
}
$_SESSION['acces'] = $nb_acces;
// $_SESSION['acces_valide'] = true; // $_SESSION['acces_valide'] = true;
break; break;
+257 -193
View File
@@ -11,6 +11,11 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session
$message_erreur = ""; $message_erreur = "";
$message_information = ""; $message_information = "";
// Messages transmis par une redirection (motif POST -> redirection -> GET, après une action sur les accès : un
// rafraîchissement de la page ne rejoue jamais l'action) :
if (isset($_SESSION['Bateaux']['flash_information'])) { $message_information .= $_SESSION['Bateaux']['flash_information']; unset($_SESSION['Bateaux']['flash_information']); }
if (isset($_SESSION['Bateaux']['flash_erreur'])) { $message_erreur .= $_SESSION['Bateaux']['flash_erreur']; unset($_SESSION['Bateaux']['flash_erreur']); }
Ouverture_bdd(); // Connexion à MySql Ouverture_bdd(); // Connexion à MySql
@@ -224,46 +229,12 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Modifier la validité des droits // NB : les actions sur les accès et invitations (création, suspension, réactivation, révocation, modification, PDF)
if (isset($_POST['validite_acces'])) { // sont traitées plus bas, dans la page Details_bateau, APRÈS le calcul des droits de l'utilisateur sur le bateau
// echo 'Validité = ON pour ID='.$_POST['ID'].'<br />'; // (elles étaient auparavant exécutées ici, avant tout contrôle - synthèse §47).
$requete = 'UPDATE TB_Lien_bateau_shipmember SET Validite_acces = 1 WHERE ID = '.$_POST['ID'];
$reponse = Requete_bdd($requete, __FILE__, __LINE__);
}
else if (!isset($_POST['validite_acces']) && isset($_POST['ID']) && !isset($_POST['supprimerAcces']) && !isset($_POST['modifierAcces'])){
// echo 'Validité = OFF pour ID='.$_POST['ID'].'<br />';
$requete = 'UPDATE TB_Lien_bateau_shipmember SET Validite_acces = 0 WHERE ID = '.$_POST['ID'];
$reponse = Requete_bdd($requete, __FILE__, __LINE__);
}
//---------------------------------------------------------------------------
// Supprimer l'accès
if (isset($_POST['supprimerAcces']) && isset($_POST['ID'])){
$id = $_POST['ID'];
$requete = 'UPDATE TB_Lien_bateau_shipmember SET Validite = 0 WHERE ID = ? ';
$reponse = Requete_preparee_bdd($requete,
array(
array('i', $id)),
__FILE__, __LINE__);
}
//---------------------------------------------------------------------------
// Modifier l'accès
if (isset($_POST['modifierAcces']) && isset($_POST['ID'])){
$id = $_POST['ID'];
$fin_validite = $_POST['fin_validite']." 23:59:59";
$type_profil = $_POST['type_profil'];
$requete = 'UPDATE TB_Lien_bateau_shipmember SET Fin_validite = ? , ID_Type_acces_bateau_shipmember = ? WHERE ID = ? ';
$reponse = Requete_preparee_bdd($requete,
array(
array('s', $fin_validite),
array('i', $type_profil),
array('i', $id)),
__FILE__, __LINE__);
}
//************************************************************************************************************************************ //************************************************************************************************************************************
// Traitement des données // Traitement des données
//************************************************************************************************************************************ //************************************************************************************************************************************
@@ -283,7 +254,7 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session
// Recherche des droits d'accès à un bateau en particulier : // Recherche des droits d'accès à un bateau en particulier :
if ($_SESSION['Bateaux']['page'] == "Details_bateau") if ($_SESSION['Bateaux']['page'] == "Details_bateau")
{ {
$requete = 'SELECT * FROM TB_Lien_bateau_shipmember WHERE Validite=1 AND Validite_acces=1 AND ID_SHIPMEMBER=? AND ID_BATEAU=? '; $requete = "SELECT * FROM TB_Lien_bateau_shipmember WHERE Statut='actif' AND Fin_validite >= NOW() AND ID_SHIPMEMBER=? AND ID_BATEAU=? ";
$reponse = Requete_preparee_bdd($requete, $reponse = Requete_preparee_bdd($requete,
array( array(
array('i', $_SESSION['shipmember']['Cle_primaire']), array('i', $_SESSION['shipmember']['Cle_primaire']),
@@ -299,7 +270,13 @@ Init_session(basename($_SERVER['SCRIPT_NAME'])); // Fonction ouvrant la session
} }
} while (0); } while (0);
if ($flag_sortie) header('Location:shipmembers.php?action=navigation&destination=Login'); if ($flag_sortie)
{
// exit indispensable : sans lui, le reste de la page (actions comprises) s'exécutait malgré la redirection (synthèse §47)
Fermeture_bdd();
header('Location:shipmembers.php?action=navigation&destination=Login');
exit();
}
switch ($_SESSION['Bateaux']['page']) switch ($_SESSION['Bateaux']['page'])
@@ -406,7 +383,9 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, ';
$acces_profil['Modification_acces'] = 0; $acces_profil['Modification_acces'] = 0;
// Recherche de l'ID de l'accès le plus élevé pour ce bateau et ce shipmember : // Recherche de l'ID de l'accès le plus élevé pour ce bateau et ce shipmember :
$requete = 'SELECT ID_Type_acces_bateau_shipmember FROM TB_Lien_bateau_shipmember WHERE Validite=1 AND Validite_acces=1 AND ID_Shipmember=? AND ID_Bateau=? AND Fin_validite>=? ORDER BY ID_Type_acces_bateau_shipmember DESC LIMIT 1'; // NB : "ORDER BY ... ASC" - plus la clé du type est petite, plus il donne de droits (2 Propriétaire, 3 Installateur,
// 4 Skipper). L'ancien "DESC" retenait l'accès le plus FAIBLE quand un SM en avait plusieurs (synthèse §47).
$requete = "SELECT ID_Type_acces_bateau_shipmember FROM TB_Lien_bateau_shipmember WHERE Statut='actif' AND ID_Shipmember=? AND ID_Bateau=? AND Fin_validite>=? ORDER BY ID_Type_acces_bateau_shipmember ASC LIMIT 1";
$reponse = Requete_preparee_bdd($requete, $reponse = Requete_preparee_bdd($requete,
array( array(
array('i', $_SESSION['shipmember']['Cle_primaire']), array('i', $_SESSION['shipmember']['Cle_primaire']),
@@ -434,11 +413,11 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, ';
} }
Liberation_jeu_de_resultat_bdd($reponse); Liberation_jeu_de_resultat_bdd($reponse);
} }
$acces_profil['Modification_acces'] = 0; // Modification d'un accès (type, fin) : réservée aux administrateurs
} }
// Récupération des types d'accès possibles : // Récupération des types d'accès possibles :
//$requete = 'SELECT Nom, Niveau_acces FROM TB_Lien_bateau_shipmember_acces WHERE Validite = 1 AND Niveau_acces < 99';
$requete = 'SELECT * FROM TB_Types_acces_bateau_shipmember WHERE Validite=1 '; $requete = 'SELECT * FROM TB_Types_acces_bateau_shipmember WHERE Validite=1 ';
$reponse = Requete_bdd($requete, __FILE__, __LINE__); $reponse = Requete_bdd($requete, __FILE__, __LINE__);
$type_acces_nb = 0; $type_acces_nb = 0;
@@ -451,44 +430,97 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, ';
Liberation_jeu_de_resultat_bdd($reponse); Liberation_jeu_de_resultat_bdd($reponse);
// Génération d'un nouveau code d'acces : //------------------------------------------------------------------------------------------------------------
if (isset($_POST['generer_code_acces'])){ // Actions sur les accès et invitations de CE bateau (synthèse §47). Traitées ici, APRÈS le calcul des droits :
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; // - chaque action vérifie que l'accès visé appartient bien au bateau affiché ;
$charactersLength = strlen($characters); // - créer une invitation, télécharger son PDF : administrateur, ou Creation_profils = 1 ;
$unique = false; // - suspendre, réactiver, révoquer : administrateur, ou Devalidation_profils = 2 (tous types), ou = 1 (tous
do { // Vérifier si le code n'est pas déjà utilisé // sauf Propriétaire) ; une invitation en attente peut aussi être révoquée par qui peut en créer ;
$code_acces = ''; // - modifier le type ou la fin d'un accès : administrateur.
for ($i = 0; $i < 6; $i++) { // Après chaque action : redirection vers la page (motif POST -> redirection -> GET).
$code_acces .= $characters[random_int(0, $charactersLength - 1)]; //------------------------------------------------------------------------------------------------------------
} $est_administrateur = ($_SESSION['shipmember']['Niveau_acces'] >= NIVEAU_ACCES_MINI_ADMINISTRATEUR);
$req = 'SELECT Code FROM TB_Lien_bateau_shipmember WHERE Code="'.$code_acces.'"'; $peut_inviter = ($est_administrateur || $acces_profil['Creation_profils'] == 1);
$rep = Requete_bdd($req, __FILE__, __LINE__);
$donnees = Recherche_ligne_bdd($rep);
if ($donnees == NULL) $unique = true;
} while($unique == false);
if (isset($_POST['date_validite']) && (!empty($_POST['date_validite']))){ if (isset($_POST['creer_invitation']))
$date = $_POST['date_validite']." 00:00:00"; {
if (!$peut_inviter) $_SESSION['Bateaux']['flash_erreur'] = t("Vous n'avez pas le droit d'inviter sur ce bateau.");
else
{
$resultat = Creer_invitation($bateau['Cle_primaire'], $_POST['email_invite'] ?? '', $_POST['prenom_invite'] ?? '',
$_POST['nom_invite'] ?? '', (int)($_POST['type_acces'] ?? 0), $_POST['fin_acces'] ?? '',
$_SESSION['shipmember']['Cle_primaire']);
if ($resultat['ok']) $_SESSION['Bateaux']['flash_information'] = str_replace("[[Code]]", $resultat['code'],
t("Invitation créée (code [[Code]]). Téléchargez son PDF dans la liste ci-dessous."));
else $_SESSION['Bateaux']['flash_erreur'] = $resultat['raison'];
} }
else $date = '9999-12-31 23:59:59'; Fermeture_bdd();
$requete = 'INSERT INTO TB_Lien_bateau_shipmember(ID_Bateau, Code, Fin_validite, Cree_par, ID_Type_acces_bateau_shipmember) VALUES (?,?,?,?,?)'; header('Location: bateaux.php');
$reponse = Requete_preparee_bdd($requete, array( exit();
array('i', $bateau['Cle_primaire']), }
array('s', $code_acces),
array('s', $date),
array('i', $_SESSION['shipmember']['Cle_primaire']),
array('i', $_POST['type_acces'])
),__FILE__, __LINE__);
$no = Recuperation_id_cree_bdd();
if ( code_acces_pdf($code_acces, $no, $bateau['Adresse_mac'],"")== 0 ) Entete_page_html(); if (isset($_POST['action_acces']) && isset($_POST['ID']))
{
$lien = Lien_du_bateau((int)$_POST['ID'], $bateau['Cle_primaire']);
$action = (string)$_POST['action_acces'];
// Message d'information : if ($lien === null) $_SESSION['Bateaux']['flash_erreur'] = t("Accès introuvable pour ce bateau.");
else if ($action == 'pdf')
// if (isset($_SESSION['pdf']['src']) && $_SESSION['pdf']['src'] != '') {
// $message_information.= "Télécharger le code d'accès d'<a class='download' target='_blank' href= ".$_SESSION['pdf']['src']."> ici </a> "; if (!$peut_inviter || $lien['Statut'] != 'en_attente') $_SESSION['Bateaux']['flash_erreur'] = t("Action non autorisée.");
// $_SESSION['pdf']['src'] =''; else
{
$invitation = Invitation_par_code($lien['Code']);
$invitation['Code'] = $lien['Code'];
$invitation['Expiration_invitation'] = $lien['Expiration_invitation'];
Fermeture_bdd();
code_acces_pdf($invitation);
exit();
}
}
else
{
$autorise = Peut_devalider_acces($acces_profil, $est_administrateur, $lien['ID_Type_acces_bateau_shipmember'])
|| ($action == 'revoquer' && $lien['Statut'] == 'en_attente' && $peut_inviter);
$transitions = array( 'suspendre' => array("'actif'", 'suspendu'),
'reactiver' => array("'suspendu'", 'actif'),
'revoquer' => array("'en_attente','actif','suspendu'", 'revoque'));
if (!$autorise || !isset($transitions[$action])) $_SESSION['Bateaux']['flash_erreur'] = t("Action non autorisée.");
else
{
$requete = "UPDATE TB_Lien_bateau_shipmember SET Statut=? WHERE ID=? AND ID_Bateau=? AND Statut IN (".$transitions[$action][0].")";
Requete_preparee_bdd($requete, array(
array('s', $transitions[$action][1]), array('i', $lien['ID']), array('i', $bateau['Cle_primaire'])),
__FILE__, __LINE__);
if (Nb_lignes_modifiees() == 1) $_SESSION['Bateaux']['flash_information'] = t("Accès mis à jour.");
else $_SESSION['Bateaux']['flash_erreur'] = t("Cet accès a déjà changé d'état.");
}
}
Fermeture_bdd();
header('Location: bateaux.php');
exit();
}
if (isset($_POST['modifierAcces']) && isset($_POST['ID']))
{
$lien = Lien_du_bateau((int)$_POST['ID'], $bateau['Cle_primaire']);
$date = date_create_from_format('Y-m-d', (string)($_POST['fin_validite'] ?? ''));
if (!$est_administrateur || $lien === null || $lien['Statut'] == 'revoque') $_SESSION['Bateaux']['flash_erreur'] = t("Action non autorisée.");
else if ($date === false) $_SESSION['Bateaux']['flash_erreur'] = t("Date de fin d'accès invalide.");
else
{
$requete = "UPDATE TB_Lien_bateau_shipmember SET Fin_validite=?, ID_Type_acces_bateau_shipmember=?
WHERE ID=? AND ID_Bateau=? AND EXISTS (SELECT 1 FROM TB_Types_acces_bateau_shipmember WHERE Cle_primaire=? AND Validite=1)";
Requete_preparee_bdd($requete, array(
array('s', $date->format('Y-m-d').' 23:59:59'), array('i', (int)$_POST['type_profil']),
array('i', $lien['ID']), array('i', $bateau['Cle_primaire']), array('i', (int)$_POST['type_profil'])),
__FILE__, __LINE__);
if (Nb_lignes_modifiees() == 1) $_SESSION['Bateaux']['flash_information'] = t("Accès mis à jour.");
else $_SESSION['Bateaux']['flash_erreur'] = t("Aucune modification enregistrée (type d'accès invalide, ou valeurs identiques).");
}
Fermeture_bdd();
header('Location: bateaux.php');
exit();
} }
@@ -499,34 +531,29 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, ';
//========================= //=========================
case "gerer_les_acces": case "gerer_les_acces":
{ {
$requete = 'SELECT * FROM TB_Lien_bateau_shipmember WHERE Validite=1 AND ID_Bateau='.$bateau['Cle_primaire'].' AND ID_Shipmember!=0 '; // Accès et invitations du bateau, hors révoqués (synthèse §47) - une seule requête au lieu de 3 par ligne :
$reponse = Requete_bdd($requete, __FILE__, __LINE__); $colonne_type = ($_SESSION['langue'] == "EN") ? 'Nom_en' : 'Nom_fr';
$requete = "SELECT L.*, S.Prenom AS sm_Prenom, S.Nom AS sm_Nom, S.Email AS sm_Email,
C.Prenom AS cree_par_Prenom, C.Nom AS cree_par_Nom, T.".$colonne_type." AS Niveau_acces_nom,
(L.Expiration_invitation IS NOT NULL AND L.Expiration_invitation <= NOW()) AS Expiree
FROM TB_Lien_bateau_shipmember L
LEFT JOIN TB_Shipmembers S ON S.ID = L.ID_Shipmember
LEFT JOIN TB_Shipmembers C ON C.ID = L.Cree_par
LEFT JOIN TB_Types_acces_bateau_shipmember T ON T.Cle_primaire = L.ID_Type_acces_bateau_shipmember
WHERE L.ID_Bateau=? AND L.Statut <> 'revoque'
ORDER BY FIELD(L.Statut, 'actif', 'suspendu', 'en_attente'), L.Date_creation";
$reponse = Requete_preparee_bdd($requete, array(array('i', $bateau['Cle_primaire'])), __FILE__, __LINE__);
$utilisateur_acces_nb = 0; $utilisateur_acces_nb = 0;
while ($donnees = Recherche_ligne_bdd($reponse)){ while ($donnees = Recherche_ligne_bdd($reponse, MYSQLI_ASSOC))
// Récupérer le nom et le prénom du shipmember qui a accès : {
$sous_req = ' SELECT Nom, Prenom, Email FROM TB_Shipmembers WHERE Validite=1 AND ID='.$donnees['ID_Shipmember'].''; // Destinataire affiché : le ShipMember s'il a accepté, sinon la personne invitée :
$sous_rep = Requete_bdd($sous_req, __FILE__, __LINE__); if ($donnees['Statut'] == 'en_attente') $donnees['Destinataire'] = trim($donnees['Prenom_invite'].' '.$donnees['Nom_invite']).' ['.$donnees['Email_invite'].']';
$sous_donnees = Recherche_ligne_bdd($sous_rep); else $donnees['Destinataire'] = trim($donnees['sm_Prenom'].' '.$donnees['sm_Nom']).' ['.$donnees['sm_Email'].']';
$donnees['sm_Nom'] = $sous_donnees['Nom']; $donnees['Cree_par_nom'] = trim($donnees['cree_par_Prenom'].' '.$donnees['cree_par_Nom']);
$donnees['sm_Prenom'] = $sous_donnees['Prenom']; unset($donnees['Code']); // Jamais envoyé au navigateur (le JSON de chaque ligne alimente le popup)
$donnees['sm_Email'] = $sous_donnees['Email'];
// Récupérer le nom et le prénom du shipmember qui a crée le lien :
$sous_req = ' SELECT Nom, Prenom FROM TB_Shipmembers WHERE Validite=1 AND ID='.$donnees['Cree_par'].'';
$sous_rep = Requete_bdd($sous_req, __FILE__, __LINE__);
$sous_donnees = Recherche_ligne_bdd($sous_rep);
$donnees['cree_par_Nom'] = $sous_donnees['Nom'];
$donnees['cree_par_Prenom'] = $sous_donnees['Prenom'];
// Récupérer le niveau accès garantie à l'utilisateur :
//$sous_req = ' SELECT Nom FROM TB_Lien_bateau_shipmember_acces WHERE Validite=1 AND Niveau_acces='.$donnees['Niveau_acces'].'';
$sous_req = 'SELECT * FROM TB_Types_acces_bateau_shipmember WHERE Validite=1 AND Cle_primaire='.$donnees['ID_Type_acces_bateau_shipmember'].' ';
$sous_rep = Requete_bdd($sous_req, __FILE__, __LINE__);
$sous_donnees = Recherche_ligne_bdd($sous_rep);
if ($_SESSION['langue'] == "EN") $donnees['Niveau_acces_nom'] = $sous_donnees['Nom_en'];
else $donnees['Niveau_acces_nom'] = $sous_donnees['Nom_fr'];
$utilisateur_acces[$utilisateur_acces_nb++] = $donnees; $utilisateur_acces[$utilisateur_acces_nb++] = $donnees;
} }
Liberation_jeu_de_resultat_bdd($reponse);
break; break;
} }
default: break; default: break;
@@ -713,99 +740,138 @@ $requete .= ' TB_Bateaux.Date_derniere_maj AS Date_derniere_maj, ';
//=========================================================== //===========================================================
case "gerer_les_acces": case "gerer_les_acces":
{ {
echo '<div class="gestion_acces">'; // Texte sûr pour le HTML (les données viennent des utilisateurs : noms, adresses...) :
echo ' <div class="generer_code"> $h = function($texte) { return htmlspecialchars((string)$texte, ENT_QUOTES, 'UTF-8'); };
<form action="bateaux.php" method="POST">';
echo ' <select name="type_acces" id="type_acces" required>
<option value="" disabled selected> -- '.$_SESSION['textes']['bateau']['details']['acces']['select'] .' -- </option>' ;
for ($i = 0; $i < $type_acces_nb; $i++){
echo '<option value="'.$type_acces[$i]['Cle_primaire'].'"> '.$type_acces[$i]['Nom'].' </option>';
}
echo ' </select>';
echo ' <input type="date" name="date_validite" id="date_validite"> ';
echo ' <button type="submit" name="generer_code_acces"> '.$_SESSION['textes']['bateau']['details']['acces']['generer'] .' </button>';
echo ' </form>
</div>';
echo ' <div class="users"> ';
echo ' <table>';
echo ' <tr>';
echo ' <th> '.t("Validite").' </th>';
echo ' <th> '.t("Shipmember").'</th>';
echo ' <th> '.t("Créé_par").'</th>';
echo ' <th> '.t("Type de profil").'</th>';
echo ' <th> '.t("Fin de validité").' </th>';
echo ' <th> </th>';
echo ' </tr>';
if ($utilisateur_acces_nb == 0) echo '<tr> <td colspan="5"> 0 shipmember / acces </td> </tr>';
else {
for($i = 0; $i < $utilisateur_acces_nb; $i++){
echo ' <form action="bateaux.php" method="POST">'; echo '<div class="gestion_acces">';
echo ' <tr>';
echo ' <td > <input name="validite_acces" onChange="this.form.submit()" type="checkbox" '; //--------------------------------------------
if (isset($acces_profil['Devalidation_profils']) && $acces_profil['Devalidation_profils'] == 0) echo ' disabled '; // Formulaire d'invitation nominative (synthèse §47) :
if (isset($acces_profil['Devalidation_profils']) && $acces_profil['Devalidation_profils'] == 1 && $utilisateur_acces[$i]['ID_Type_acces_bateau_shipmember'] == 2) echo ' disabled '; if ($peut_inviter)
if ($utilisateur_acces[$i]['Validite_acces'] == 1) echo 'checked'; {
echo '> </td>'; echo '<div class="generer_code">';
echo ' <td> '.$utilisateur_acces[$i]['sm_Prenom'].' '.$utilisateur_acces[$i]['sm_Nom'].' ['.$utilisateur_acces[$i]['sm_Email'].']</td>'; echo ' <form action="bateaux.php" method="POST">';
echo ' <td> '.$utilisateur_acces[$i]['cree_par_Prenom'].' '.$utilisateur_acces[$i]['cree_par_Nom'].'</td>'; echo ' <input type="email" name="email_invite" required maxlength="254" placeholder="'.$h(t("Adresse e-mail du destinataire")).'">';
echo ' <td name="niveau_acces" value="'.$utilisateur_acces[$i]['ID_Type_acces_bateau_shipmember'].'">'.$utilisateur_acces[$i]['Niveau_acces_nom'].'</td>'; echo ' <input type="text" name="prenom_invite" maxlength="50" placeholder="'.$h(t("Prénom (facultatif)")).'">';
echo ' <td name="fin_validite" value="'.$utilisateur_acces[$i]['Fin_validite'].'"> '; echo ' <input type="text" name="nom_invite" maxlength="50" placeholder="'.$h(t("Nom (facultatif)")).'">';
echo (substr($utilisateur_acces[$i]['Fin_validite'],0,-9) == "9999-12-31") ? Recuperer_texte("bateau","details","acces","aucune_fin") : substr($utilisateur_acces[$i]['Fin_validite'],0,-9) ; echo ' <select name="type_acces" required>';
echo ' </td>'; echo ' <option value="" disabled selected> -- '.$h(t("Type d'accès")).' -- </option>';
echo ' <input hidden name="ID" value="'.$utilisateur_acces[$i]['ID'].'">'; for ($i = 0; $i < $type_acces_nb; $i++) echo '<option value="'.(int)$type_acces[$i]['Cle_primaire'].'">'.$h($type_acces[$i]['Nom']).'</option>';
if ($acces_profil['Modification_acces'] == 1){ echo ' </select>';
echo ' <td id="modifier_acces" onclick="popUpEditAccess(' . htmlspecialchars(json_encode($utilisateur_acces[$i]), ENT_QUOTES, 'UTF-8') . ')"></td>'; echo ' <input type="date" name="fin_acces" title="'.$h(t("Fin de l'accès (facultatif)")).'">';
} echo ' <button type="submit" name="creer_invitation">'.$h(t("Inviter")).'</button>';
echo ' </tr>'; echo ' </form>';
echo ' </form>'; echo '</div>';
}
//--------------------------------------------
// Liste des accès et des invitations en attente :
echo '<div class="users">';
echo ' <table>';
echo ' <tr>';
echo ' <th>'.$h(t("Statut")).'</th>';
echo ' <th>'.$h(t("Shipmember")).'</th>';
echo ' <th>'.$h(t("Créé_par")).'</th>';
echo ' <th>'.$h(t("Type de profil")).'</th>';
echo ' <th>'.$h(t("Fin de validité")).'</th>';
echo ' <th></th>';
echo ' </tr>';
if ($utilisateur_acces_nb == 0) echo '<tr><td colspan="6">'.$h(t("Aucun accès ni invitation en cours.")).'</td></tr>';
for ($i = 0; $i < $utilisateur_acces_nb; $i++)
{
$acces = $utilisateur_acces[$i];
// Statut affiché :
switch ($acces['Statut'])
{
case 'actif': $statut = t("Actif"); break;
case 'suspendu': $statut = t("Suspendu"); break;
default:
if ($acces['Expiree']) $statut = t("Invitation expirée");
else $statut = str_replace("[[Date]]", date_format(date_create($acces['Expiration_invitation']), 'd/m/Y'), t("Invitation en attente (jusqu'au [[Date]])"));
break;
} }
// Actions permises sur cette ligne :
$peut_devalider = Peut_devalider_acces($acces_profil, $est_administrateur, $acces['ID_Type_acces_bateau_shipmember']);
$actions = array();
if ($acces['Statut'] == 'actif' && $peut_devalider) $actions['suspendre'] = t("Suspendre");
if ($acces['Statut'] == 'suspendu' && $peut_devalider) $actions['reactiver'] = t("Réactiver");
if ($acces['Statut'] == 'en_attente' && !$acces['Expiree'] && $peut_inviter) $actions['pdf'] = t("PDF");
if ($peut_devalider || ($acces['Statut'] == 'en_attente' && $peut_inviter)) $actions['revoquer'] = t("Révoquer");
echo ' <tr>';
echo ' <td>'.$h($statut).'</td>';
echo ' <td>'.$h($acces['Destinataire']).'</td>';
echo ' <td>'.$h($acces['Cree_par_nom']).'</td>';
echo ' <td>'.$h($acces['Niveau_acces_nom']).'</td>';
echo ' <td>'.((substr($acces['Fin_validite'], 0, 10) == "9999-12-31") ? $h(t("Aucune")) : $h(date_format(date_create($acces['Fin_validite']), 'd/m/Y'))).'</td>';
echo ' <td>';
if (count($actions) > 0)
{
echo '<form action="bateaux.php" method="POST">';
echo '<input type="hidden" name="ID" value="'.(int)$acces['ID'].'">';
foreach ($actions as $code_action => $libelle)
{
echo '<button type="submit" name="action_acces" value="'.$code_action.'"';
if ($code_action == 'revoquer') echo ' onclick="return window.confirm(\''.$h(addslashes(t("Révoquer définitivement cet accès ?"))).'\');"';
echo '>'.$h($libelle).'</button> ';
}
echo '</form>';
}
if ($acces_profil['Modification_acces'] == 1)
{
echo '<span id="modifier_acces" onclick="popUpEditAccess('.$h(json_encode($acces)).')"></span>';
}
echo ' </td>';
echo ' </tr>';
} }
echo ' </table>'; echo ' </table>';
echo ' </div>';
echo '</div>'; echo '</div>';
echo '<div id="popUpAcces" style="display: none;">'; echo '</div>'; // Fin de class="gestion_acces"
echo ' <div id="popUpAccesModal">';
echo ' <div id="top_part">'; //--------------------------------------------
echo ' <p> '.t("Titre du popup").' </p>'; // Popup de modification (administrateurs) : type d'accès et fin de validité.
echo ' <p id="close" onclick="closeEditAccess();"> </p>'; // (La suppression se fait désormais par le bouton "Révoquer" de chaque ligne.)
echo ' </div>'; if ($acces_profil['Modification_acces'] == 1)
echo ' <form action="bateaux.php" method="POST">'; {
echo ' <label for="shipmemberForm" id="ShipMember"> '; echo '<div id="popUpAcces" style="display: none;">';
echo ' <input id="shipmemberForm" type="text" value="" name="shipmember" readonly>'; echo ' <div id="popUpAccesModal">';
echo ' <span>'.t("Shipmember").'</span>'; echo ' <div id="top_part">';
echo ' </label>'; echo ' <p>'.$h(t("Titre du popup")).'</p>';
echo ' <label for="cree_parForm" id="Cree_par"> '; echo ' <p id="close" onclick="closeEditAccess();"> </p>';
echo ' <input id="cree_parForm" type="text" value="" name="cree_par" readonly>'; echo ' </div>';
echo ' <span>'.t("Créé par").'</span>'; echo ' <form action="bateaux.php" method="POST">';
echo ' </label>'; echo ' <label for="shipmemberForm" id="ShipMember">';
echo ' <label for="type_profilForm" id="Type_profil"> '; echo ' <input id="shipmemberForm" type="text" value="" readonly>';
echo ' <select name="type_profil" id="type_profilForm" required> echo ' <span>'.$h(t("Shipmember")).'</span>';
<option value="" disabled selected> -- '.$_SESSION['textes']['bateau']['details']['acces']['select'] .' -- </option>' ; echo ' </label>';
for ($i = 0; $i < $type_acces_nb; $i++){ echo ' <label for="cree_parForm" id="Cree_par">';
echo '<option value="'.$type_acces[$i]['Cle_primaire'].'"> '.$type_acces[$i]['Nom'].' </option>'; echo ' <input id="cree_parForm" type="text" value="" readonly>';
} echo ' <span>'.$h(t("Créé par")).'</span>';
echo ' </select>'; echo ' </label>';
echo ' <span>'.t("Type de profil").'</span>'; echo ' <label for="type_profilForm" id="Type_profil">';
echo ' </label>'; echo ' <select name="type_profil" id="type_profilForm" required>';
echo ' <label for="fin_validiteForm" id="Fin_validite"> '; echo ' <option value="" disabled selected> -- '.$h(t("Type d'accès")).' -- </option>';
echo ' <input id="fin_validiteForm" type="date" value="" name="fin_validite" required>'; for ($i = 0; $i < $type_acces_nb; $i++) echo '<option value="'.(int)$type_acces[$i]['Cle_primaire'].'">'.$h($type_acces[$i]['Nom']).'</option>';
echo ' <span>'.t("Fin de validite").'</span>'; echo ' </select>';
echo ' </label>'; echo ' <span>'.$h(t("Type de profil")).'</span>';
echo ' <input hidden id="idForm" name="ID" value="">'; echo ' </label>';
echo ' <button type="submit" name="supprimerAcces" onclick="return window.confirm(\''.$_SESSION["textes"]["bateau"]["edit_acces"]["popup"]["delete_confirm"].'\');"> '.t("Supprimer").' </button>'; echo ' <label for="fin_validiteForm" id="Fin_validite">';
echo ' <button type="submit" name="modifierAcces"> '.t("Mettre à jour").' </button>'; echo ' <input id="fin_validiteForm" type="date" value="" name="fin_validite" required>';
echo ' </form>'; echo ' <span>'.$h(t("Fin de validite")).'</span>';
echo ' </div>'; echo ' </label>';
echo '</div>'; echo ' <input type="hidden" id="idForm" name="ID" value="">';
echo ' <button type="submit" name="modifierAcces">'.$h(t("Mettre à jour")).'</button>';
echo ' </form>';
echo ' </div>';
echo '</div>';
}
break; break;
} }
//=========================================================== //===========================================================
// 'resume' (et toute ancienne valeur de session) : // 'resume' (et toute ancienne valeur de session) :
default: default:
@@ -1008,20 +1074,18 @@ Pied_de_page();
document.getElementById('popUpAcces').style.display = "none"; document.getElementById('popUpAcces').style.display = "none";
} }
function popUpEditAccess(data){ function popUpEditAccess(acces){
acces = data;
document.getElementById('popUpAcces').style.display = "block"; document.getElementById('popUpAcces').style.display = "block";
document.getElementById('shipmemberForm').value = acces['sm_Nom']+" "+acces['sm_Prenom']+" ["+acces['sm_Email']+"] "; document.getElementById('shipmemberForm').value = acces['Destinataire'];
document.getElementById('cree_parForm').value = acces['cree_par_Nom']+" "+acces['cree_par_Prenom']; document.getElementById('cree_parForm').value = acces['Cree_par_nom'];
document.getElementById('idForm').value = acces['ID']; document.getElementById('idForm').value = acces['ID'];
// Sélection du type actuel (comparaison en texte : la valeur d'une option est une chaîne, l'ID reçu un nombre) :
const selectElement = document.getElementById('type_profilForm'); const selectElement = document.getElementById('type_profilForm');
for (let i = 0; i < selectElement.options.length; i++) { for (let i = 0; i < selectElement.options.length; i++) {
if (selectElement.options[i].value === acces['ID_Type_acces_bateau_shipmember']) { if (selectElement.options[i].value === String(acces['ID_Type_acces_bateau_shipmember'])) {
selectElement.options[i].selected = true; selectElement.options[i].selected = true;
break; break;
} }
} }
document.getElementById('fin_validiteForm').value = acces['Fin_validite'].substring(0,10); document.getElementById('fin_validiteForm').value = acces['Fin_validite'].substring(0,10);
+11 -139
View File
@@ -1,139 +1,11 @@
<?php <?php
session_start(); // Ouverture de session (avant tout autre envoi au client!!!) //************************************************************************************************************
require_once("../config/config.php"); // index.php - Point d'entrée du site. L'initialisation de la session, auparavant faite ici, est désormais assurée
// par Init_session() pour TOUTE page (une page ouverte directement fonctionne aussi - synthèse §47).
//************************************************************************************************************
Ouverture_bdd(); // Connexion à MySql require_once("../config/config.php");
Init_session(basename($_SERVER['SCRIPT_NAME']));
// A SUPPRIMER !! header('Location: shipmembers.php');
//if (!isset($_SESSION['type_utilisateur'])) $_SESSION['type_utilisateur'] = TYPE_UTILISATEUR_PROFESSIONNEL; //TYPE_UTILISATEUR_INCONNU; exit();
//--------------------------------------------------------------------------------------------------
// Init des variables de session générales :
if (!isset($_SESSION['acces_valide'])) $_SESSION['acces_valide'] = false;
if (!isset($_SESSION['display_menu'])) $_SESSION['display_menu'] = false;
if (!isset($_SESSION['langue'])) $_SESSION['langue'] = 'FR'; // Valeur par défaut
if (!isset($_SESSION['shipmember']['Cle_primaire'])) $_SESSION['shipmember']['Cle_primaire'] = 0;
if (!isset($_SESSION['shipmember']['Prenom'])) $_SESSION['shipmember']['Prenom'] = "";
if (!isset($_SESSION['shipmember']['Nom'])) $_SESSION['shipmember']['Nom'] = "";
if (!isset($_SESSION['shipmember']['Entreprise'])) $_SESSION['shipmember']['Entreprise'] = "";
if (!isset($_SESSION['shipmember']['Rue'])) $_SESSION['shipmember']['Rue'] = "";
if (!isset($_SESSION['shipmember']['Code_postal'])) $_SESSION['shipmember']['Code_postal'] = "";
if (!isset($_SESSION['shipmember']['Ville'])) $_SESSION['shipmember']['Ville'] = "";
if (!isset($_SESSION['shipmember']['ID_Pays'])) $_SESSION['shipmember']['ID_Pays'] = 75; // FR
if (!isset($_SESSION['shipmember']['Telephone'])) $_SESSION['shipmember']['Telephone'] = "";
if (!isset($_SESSION['shipmember']['Email'])) $_SESSION['shipmember']['Email'] = "";
if (!isset($_SESSION['shipmember']['Commentaires'])) $_SESSION['shipmember']['Commentaires'] = '';
if (!isset($_SESSION['shipmember']['Niveau_acces'])) $_SESSION['shipmember']['Niveau_acces'] = '';
if (!isset($_SESSION['droits_acces'])) $_SESSION['droits_acces'] = 0;
if (!isset($_SESSION['bateau_shipmember'])) $_SESSION['bateau_shipmember']['ID_Bateau'] = '';
if (!isset($_SESSION['bateau_shipmember'])) $_SESSION['bateau_shipmember']['Niveau_acces'] = '';
if (!isset($_SESSION['pdf']['src'])) $_SESSION['pdf']['src']['Niveau_acces'] = '';
if (!isset($_SESSION['modifier_texte'])) $_SESSION['modifier_texte'] = 0;
// if (!isset($_SESSION['shipmember']['code_acces'])) $_SESSION['shipmember']['code_acces'] = $_GET['code_acces'];
//--------------------------------------------------------------------------------------------------
// Recherche des paramètres de configuration générale pour mise à jour des variables de session associées :
$requete = 'SELECT Nom, Valeur FROM TB_Configuration';
$reponse = Requete_bdd($requete, __FILE__, __LINE__);
while ($donnees = Recherche_ligne_bdd($reponse)) // boucle sur tous les enregistrements de la table
{
switch($donnees['Nom'])
{
case "Langue_par_defaut":
{
$_SESSION['langue'] = $donnees['Valeur'];
break;
}
default :
{
$_SESSION['Config__'.$donnees['Nom'].''] = $donnees['Valeur'];
break;
}
}
}
Liberation_jeu_de_resultat_bdd($reponse);
//--------------------------------------------------------------------------------------------------
// Mise à jour des ID de langue en fonction du prefixe (évite un accès à quasiment chaque requête) :
$requete = 'SELECT ID, Prefix FROM TB_Langues';
$reponse = Requete_bdd($requete, __FILE__, __LINE__);
while ($donnees = Recherche_ligne_bdd($reponse))
{
$_SESSION['id_langue'][''.$donnees['Prefix'].''] = $donnees['ID'];
}
Liberation_jeu_de_resultat_bdd($reponse);
Fermeture_bdd(); // Déconnexion de MySQL
//--------------------------------------------------------------------------------------------------
// Recherche des textes à utiliser sur les différentes pages et dans la langue en cours
// Attention : doit être rechargé à chaque fois qu'un texte est modifié dans la base
// Attention 2 : doit être rechargé à chaque fois qu'on change de langue
chargement_langue();
//--------------------------------------------------------------------------------------------------
// Affichage des informations système dans le cas d'une demande VERBOSE :
if ((!PRODUCTION) AND (isset($_GET['verbose'])))
{
Entete_page_html();
echo '<div id="Index">';
echo '<table>
<thead>
<tr>
<th>Nom de la variable</th>
<th>Valeur</th>
</tr>
</thead>
<tbody>';
// Affichage des variables de session :
echo '<tr style="line-height:40px;"><td colspan=2><strong>Variables de session</strong></tr>';
foreach ($_SESSION as $k=>$v)
{
if ($k == "db") continue; // Car la valeur stockée est un objet de type "db" qui plante l'affichage....
echo '<tr>
<td>'.$k.'</td>
<td>'.htmlspecialchars(is_array($v) ? json_encode($v) : $v).'</td>
</tr>';
}
// Affichage des variables du serveur :
echo '<tr style="line-height:40px;"><td colspan=2><strong>Variables du serveur</strong></tr>';
foreach ($_SERVER as $k=>$v)
{
echo '<tr>
<td>'.$k.'</td>
<td>'.htmlspecialchars(is_array($v) ? json_encode($v) : $v).'</td>
</tr>';
}
echo '</tbody>
</table>';
echo '<div class="boutons_selection">
<a title="Accéder au logiciel..." href="shipmembers.php">Continuer</a>
<a title="Remettre à zéro toutes les variables de session..." href="shipmembers.php?action=deconnexion">Déconnexion</a>
</div>';
echo '</div>';
echo '</body>';
echo '</html>';
}
else header('Refresh: 0; URL=shipmembers.php'); // Une fois que les variables de version sont chargées
// else header('Refresh: 0; URL=accueil.php'); // Une fois que les variables de version sont chargées
+1646 -1698
View File
File diff suppressed because it is too large Load Diff
+4
View File
@@ -0,0 +1,4 @@
-- Durée de validité (jours) d'une invitation à accéder à un bateau (synthèse §47)
INSERT INTO TB_Configuration (Validite, Nom, Description, Valeur)
VALUES (1, 'Duree_validite_invitation',
'Nombre de jours pendant lesquels une invitation à accéder à un bateau peut être acceptée', '30');
@@ -0,0 +1,12 @@
-- ============================================================================
-- TB_Lien_bateau_shipmember - refonte, PARTIE 2/2 : suppression des
-- anciennes colonnes (synthèse §47). À exécuter UNIQUEMENT après le
-- déploiement du code PHP utilisant Statut (bateaux.php, shipmembers.php,
-- administration.php) : l'ancien code échouerait sur ces colonnes absentes.
-- ============================================================================
ALTER TABLE TB_Lien_bateau_shipmember
DROP COLUMN Validite,
DROP COLUMN Validite_acces,
DROP COLUMN Niveau_acces_OLD;
SHOW CREATE TABLE TB_Lien_bateau_shipmember;