Si vous êtes le propriétaire de cette adresse, merci de vous connecter avec cette adresse.
Sinon, merci de choisir une autre adresse."); } } Liberation_jeu_de_resultat_bdd($reponse); } if ($message_erreur == "") // Si les contrôles ne sont pas invalides, on créé le nouvel utilisateur : { // Génération d'un MDP aléatoire : $password = Mdp_aleatoire(6); // Si l'adresse email est vide, il est inutile de préparer un mdp... // Création du ShipMember : $requete = 'INSERT INTO TB_Shipmembers(Nom, Prenom, Entreprise, Rue, Code_postal, Ville, ID_PAYS, Telephone, Email, ID_LANGUAGES, Mdp, Date_creation_compte) VALUES (?,?,?,?,?,?,?,?,?,(SELECT ID FROM TB_Langues WHERE Prefix=?),?,?)'; Requete_preparee_bdd($requete, array( array('s', $_SESSION['shipmember']['Nom']), array('s', $_SESSION['shipmember']['Prenom']), array('s', $_SESSION['shipmember']['Entreprise']), array('s', $_SESSION['shipmember']['Rue']), array('s', $_SESSION['shipmember']['Code_postal']), array('s', $_SESSION['shipmember']['Ville']), array('i', $_SESSION['shipmember']['ID_Pays']), array('s', $_SESSION['shipmember']['Telephone']), array('s', $_SESSION['shipmember']['Email']), array('s', $_SESSION['langue']), array('s', password_hash($password, PASSWORD_DEFAULT)), array('s', date("Y-m-d H:i:s"))), __FILE__, __LINE__); $_SESSION['shipmember']['Cle_primaire'] = Recuperation_id_cree_bdd(); $requete = 'INSERT INTO TB_Activation(ID_SHIPMEMBERS, Date_creation_mdp) VALUES (?, ?)'; Requete_preparee_bdd($requete, array( array('s', $_SESSION['shipmember']['Cle_primaire']), array('s', date("Y-m-d H:i:s"))), __FILE__, __LINE__); // Mise à jour du libellé du pays : $requete = 'SELECT Texte AS Libelle_pays FROM TB_Textes_traduction WHERE ID_TEXTES=(SELECT ID_NOM FROM TB_Pays WHERE ID=?) AND ID_LANGUAGES=(SELECT ID FROM TB_Langues WHERE Prefix=?)'; $reponse = Requete_preparee_bdd($requete, array( array('i', $_SESSION['shipmember']['ID_Pays']), array('s', $_SESSION['langue'])), __FILE__, __LINE__); $donnees = Recherche_ligne_bdd($reponse); $_SESSION['shipmember']['libelle_pays'] = $donnees['Libelle_pays']; Liberation_jeu_de_resultat_bdd($reponse); // Calcul de la date limite d'activation du compte : $date = date_create("now"); // Date courante date_add($date, date_interval_create_from_date_string(''.$_SESSION['Config__Time_out_activation_compte'].' days')); // Date courante + Nb jour configurés $date_maxi_activation = date_format($date, "d/m/Y à H:i"); //......................................................................... // Préparation et envoi de l'email de confirmation de création de compte : $texte_email = t("

Félicitations !

Votre compte ShipMember est créé, vous y êtes presque.

Nom : [[Prenom]] [[Nom]]

Email : [[Email]]

Mot de passe provisoire : [[Password]]

Plus qu’un clic : Connectez-vous sur [[Url_site]] pour valider votre compte ShipMember en modifiant votre mot de passe provisoire (*). C’est une garantie de sécurité à ne pas négliger.

Et ensuite, où que vous soyez et dès que votre ShipHeart est installé, accédez à votre bateau via votre accès privilégié ShipMember !

Bienvenue parmi nous !

L'équipage ShipHeart

(*) L'activation devra être faite avant le [[Date_maxi_activation]]. Mais pas d'inquiétude ; si vous ne le faites pas avant, vous pourrez toujours demander un nouveau mot de passe provisoire.

"); // Mise à jour des parametres du texte : $texte_email = str_replace("[[Prenom]]", $_SESSION['shipmember']['Prenom'], $texte_email); $texte_email = str_replace("[[Nom]]", $_SESSION['shipmember']['Nom'], $texte_email); $texte_email = str_replace("[[Email]]", $_SESSION['shipmember']['Email'], $texte_email); $texte_email = str_replace("[[Password]]", $password, $texte_email); $texte_email = str_replace("[[Url_site]]", URL_SITE, $texte_email); $texte_email = str_replace("[[Date_maxi_activation]]", $date_maxi_activation, $texte_email); Envoi_email('', $_SESSION['shipmember']['Email'], t("Votre accès ShipMember - Un dernier clic pour accéder à votre bateau !"), $texte_email, "ShipHeart by Koriolan", $_SESSION['Config__Adresse_email_shipmember'], ''); //Fin......................................................................... //............................................................................ // Message d'information : $message = t("Un email vient d'être envoyé à [[Prenom]] [[Nom]] ([[Email]]) avec un mot de passe provisoire."); $message = str_replace("[[Prenom]]", $_SESSION['shipmember']['Prenom'], $message); $message = str_replace("[[Nom]]", $_SESSION['shipmember']['Nom'], $message); $message = str_replace("[[Email]]", $_SESSION['shipmember']['Email'], $message); $message_information .= $message; //Fin......................................................................... // Pas de connexion automatique après la création : l'adresse e-mail n'est prouvée qu'à la première connexion avec // le mot de passe provisoire reçu (activation). Sans cela, n'importe qui pourrait créer un compte avec l'adresse d'un // autre et accepter aussitôt les invitations destinées à cette adresse (synthèse §47). $_SESSION['shipmember']['Cle_primaire'] = 0; $_SESSION['Shipmembers']['page'] = "Login"; $message_information .= "
".t("Connectez-vous avec ce mot de passe provisoire pour activer votre compte."); } } //--------------------------------------------------------------------------- // Invitations (synthèse §47) : acceptation, refus, saisie manuelle d'un code. Réservé à un utilisateur connecté // (acceptation et refus) ; les conditions (adresse, statut, expiration, compte activé) sont vérifiées par // Accepter_invitation() / Refuser_invitation(). Puis redirection (un rafraîchissement ne rejoue pas l'action). if ((isset($_POST['accepter_invitation']) || isset($_POST['refuser_invitation'])) && $_SESSION['acces_valide']) { if (isset($_POST['accepter_invitation'])) { $resultat = Accepter_invitation((int)$_POST['accepter_invitation'], $_SESSION['shipmember']['Cle_primaire'], $_SESSION['shipmember']['Email']); if ($resultat['ok']) { Rafraichir_acces_session($_SESSION['shipmember']['Cle_primaire']); $_SESSION['Shipmembers']['flash_information'] = t("Invitation acceptée : le bateau est maintenant accessible dans « Mon bateau »."); } else $_SESSION['Shipmembers']['flash_erreur'] = $resultat['raison']; } else { if (Refuser_invitation((int)$_POST['refuser_invitation'], $_SESSION['shipmember']['Email'])) $_SESSION['Shipmembers']['flash_information'] = t("Invitation refusée."); else $_SESSION['Shipmembers']['flash_erreur'] = t("Cette invitation n'est plus valable."); } $_SESSION['Shipmembers']['page'] = "Accueil"; Fermeture_bdd(); header('Location: shipmembers.php'); exit(); } if (isset($_POST['saisie_code_invitation'])) { $code = Normaliser_code_invitation($_POST['code_invitation'] ?? ''); if ($code === false) $message_erreur .= t("Ce code n'a pas le bon format (8 caractères, par exemple K7QX-M3PW)."); else { $_SESSION['code_acces'] = $code; // Examiné ci-dessous (page Accueil, ou bandeau de la page Login) if ($_SESSION['acces_valide']) $_SESSION['Shipmembers']['page'] = "Accueil"; } } //--------------------------------------------------------------------------- // Lecture de l'email et du mot de passe et filtrage contre les injections SQL : if (isset($_POST['validation_login_shipmember']) AND isset($_POST['email_validation']) AND isset($_POST['mdp_validation'])) { // if (preg_match("#^[a-z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$#", $_POST['email_validation']) != 1) $message_information .= "Erreur de PERG MATCH
"; if (($_POST['email_validation'] != NULL) AND ($_POST['mdp_validation'] != NULL) AND (preg_match("#^[a-z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$#", $_POST['email_validation']) == 1)) // Ce Preg-Match semble bien plus efficace que le "filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)"... { $email = Protection_mysql(strtolower($_POST['email_validation'])); // On ajoute les caractères d'échappement sur l'email qui sera envoyé dans la requête $mdp = $_POST['mdp_validation']; // Le MDP n'est pas envoyé... $requete = 'SELECT ID AS Cle_primaire, Validite, Nom, Prenom, Entreprise, Rue, Code_postal, Ville, Telephone, Email, Mdp, Date_creation_compte, Niveau_acces, ID_PAYS AS ID_Pays, ID_LANGUAGES, (SELECT 1 FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Compte_a_activer, (SELECT Date_creation_mdp FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Date_creation_mdp FROM TB_Shipmembers WHERE Email=? '; // NB : variable dédiée ($reponse_login) - le corps de la boucle exécute d'autres requêtes qui réutilisaient $reponse ; // la libération finale visait alors un résultat déjà libéré (erreur fatale en PHP 8 - synthèse §47) : $reponse_login = Requete_preparee_bdd($requete, array( array('s', $email)), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse_login)) { if (password_verify($mdp, $donnees['Mdp'])) { $_SESSION['shipmember'] = $donnees; // Sauvegarde des informations du ShipMember if ($donnees['Compte_a_activer'] != 0) { $date = date_create("now"); // Date courante date_sub($date, date_interval_create_from_date_string(''.$_SESSION['Config__Time_out_activation_compte'].' days')); // Date courante - Nb jour configurés $date_creation = date_create_from_format('Y-m-d H:i:s', $donnees['Date_creation_mdp']); if ($date < $date_creation) // Si le Mdp provisoire est toujours valable : { $_SESSION['Shipmembers']['page'] = "Activation"; } else // Si le Mdp provisoireest expiré : { $message_erreur .= t("Désolé, votre compte n'a pas été activé dans le délai maximal.
Vous pouvez demander la génération d'un nouveau mot de passe provisoire en cliquant sur le bouton ci-dessous. Il vous sera adressé immédiatement par email."); } } else { // Mémorisation dans l'historique de la connexion : $requete = 'INSERT INTO TB_Historique(Type, Sous_type, ID_ELEMENT, Valeur, Description) VALUES (?, ?, ?, ?, ?)'; Requete_preparee_bdd($requete, array( array('i', SYSTEME), array('i', SYSTEME_CONNEXION_USER), array('i', $_SESSION['shipmember']['Cle_primaire']), array('i', 0), array('s', 'Connexion de '.$donnees['Prenom'].' '.$donnees['Nom'].' [N° '.$_SESSION['shipmember']['Cle_primaire'].']')), __FILE__, __LINE__); // Recherche des informations du ShipMember : $requete = 'SELECT ID AS Cle_primaire, Validite, Nom, Prenom, Entreprise, Rue, Code_postal, Ville, Telephone, Email, Mdp, Date_creation_compte, Niveau_acces, ID_PAYS AS ID_Pays, ID_LANGUAGES, (SELECT 1 FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Compte_a_activer, (SELECT Date_creation_mdp FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Date_creation_mdp FROM TB_Shipmembers WHERE ID=?'; $reponse = Requete_preparee_bdd($requete, array( array('i', $_SESSION['shipmember']['Cle_primaire'])), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse)) $_SESSION['shipmember'] = $donnees; Liberation_jeu_de_resultat_bdd($reponse); // Mise à jour du libellé du pays : $requete = 'SELECT Texte AS Libelle_pays FROM TB_Textes_traduction WHERE ID_TEXTES=(SELECT ID_NOM FROM TB_Pays WHERE ID=?) AND ID_LANGUAGES=(SELECT ID FROM TB_Langues WHERE Prefix=?)'; $reponse = Requete_preparee_bdd($requete, array( array('i', $_SESSION['shipmember']['ID_Pays']), array('s', $_SESSION['langue'])), __FILE__, __LINE__); $donnees = Recherche_ligne_bdd($reponse); $_SESSION['shipmember']['libelle_pays'] = $donnees['Libelle_pays']; Liberation_jeu_de_resultat_bdd($reponse); // Message de bienvenue : $message_information .= t("Bienvenue !"); $_SESSION['acces_valide'] = true; Rafraichir_acces_session($_SESSION['shipmember']['Cle_primaire']); // Accès actifs (synthèse §47) $_SESSION['Shipmembers']['page'] = "Accueil"; } break; // Dans le cas où il y aurait plus d'une entrée avec le bon email ET le bon mdp, on ne traite que le premier... } // else $message_information .= "MDP ne matchent pas. "; } Liberation_jeu_de_resultat_bdd($reponse_login); } // else $message_information .= "Email ou MDP non valides : [".$_POST['email_validation']."] et [".$_POST['mdp_validation']."]."; else $message_erreur .= "Email ou MDP non valides"; } //--------------------------------------------------------------------------- // Activation Shipmember : if (isset($_POST['validation_activation_shipmember']) AND isset($_POST['Mot_de_passe_1']) AND isset($_POST['Mot_de_passe_2'])) { if (($_POST['Mot_de_passe_1'] == $_POST['Mot_de_passe_2']) AND (Check_mdp($_POST['Mot_de_passe_1']) == 1)) { $new_mdp = $_POST['Mot_de_passe_1']; // Recherche du MDP existant de l'adhérent : $requete = 'SELECT ID AS Cle_primaire, Validite, Nom, Prenom, Entreprise, Rue, Code_postal, Ville, Telephone, Email, Mdp, Date_creation_compte, Niveau_acces, ID_PAYS AS ID_Pays, ID_LANGUAGES, (SELECT 1 FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Compte_a_activer, (SELECT Date_creation_mdp FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Date_creation_mdp FROM TB_Shipmembers WHERE ID=?'; $reponse = Requete_preparee_bdd($requete, array( array('i', $_SESSION['shipmember']['Cle_primaire'])), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse)) $shipmember = $donnees; Liberation_jeu_de_resultat_bdd($reponse); // Vérification que le mot de passe est changé : // if (Hash_Mdp($new_mdp) == $shipmember['Mdp']) $message_erreur .= nl2br(Recuperation_texte('all','all','erreurs','pwd_egal_temporaire')); if (password_verify($new_mdp, $shipmember['Mdp'])) $message_erreur .= t("Pour des raisons de sécurité, votre nouveau mot de passe ne peut pas être identique au mot de passe provisoire."); else { // Mise à jour du nouveau mot de passe : // NB : haché tel quel - l'ancien code hachait la version échappée pour SQL (Protection_mysql), qui ne correspond // plus au mot de passe saisi à la connexion dès qu'il contient un caractère échappé (synthèse §47) : $requete = 'UPDATE TB_Shipmembers SET Mdp=? WHERE ID=?'; Requete_preparee_bdd($requete, array( array('s', password_hash($new_mdp, PASSWORD_DEFAULT)), array('i', $_SESSION['shipmember']['Cle_primaire'])), __FILE__, __LINE__); $requete = 'DELETE FROM TB_Activation WHERE ID_SHIPMEMBERS=?'; Requete_preparee_bdd($requete, array( array('i', $_SESSION['shipmember']['Cle_primaire'])), __FILE__, __LINE__); $_SESSION['acces_valide'] = true; Rafraichir_acces_session($_SESSION['shipmember']['Cle_primaire']); // Accès actifs (synthèse §47) // $_SESSION['acces_valide'] = true; $_SESSION['Shipmembers']['page'] = "Accueil"; $_SESSION['Shipmembers']['page'] = "Accueil"; $message_information .= t("Félicitations : votre compte est maintenant activé et vous êtes d'ores et déjà connecté.e.").' !'; } } else { if ($_POST['Mot_de_passe_1'] != $_POST['Mot_de_passe_2']) $message_erreur .= t("Les deux mots de passe saisis doivent être identiques."); else $message_erreur .= nl2br(t("Le mot de passe renseigné n'est pas conforme. Pour la sécurité de vos données, il doit contenir entre 6 et 20 caractères, et être composé exclusivement de minuscules, de majuscules, de chiffres ou des caractères spéciaux suivants _-!*=.")); } } //--------------------------------------------------------------------------- // Regenération du mot de passe : if (isset($_POST['regenerer_mdp_shipmember']) AND isset($_POST['Email'])) { $_SESSION['shipmember']['Email'] = strtolower(trim($_POST['Email'])); // Vérifications : if (preg_match("#^[a-z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$#", $_SESSION['shipmember']['Email']) != 1) // Ce Preg-Match semble bien plus efficace que le "filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)"... { $message_erreur .= t("[Email] est invalide !"); } // Vérification si l'email existe bien dans la base : if ($message_erreur == "") { $nb_emails_valides = 0; $requete = 'SELECT ID AS Cle_primaire, Validite, Nom, Prenom, Entreprise, Rue, Code_postal, Ville, Telephone, Email, Mdp, Date_creation_compte, Niveau_acces, ID_PAYS AS ID_Pays, ID_LANGUAGES, (SELECT 1 FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Compte_a_activer, (SELECT Date_creation_mdp FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Date_creation_mdp FROM TB_Shipmembers WHERE Validite=1 AND Email=? '; $reponse = Requete_preparee_bdd($requete, array( array('s', $_SESSION['shipmember']['Email'])), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse)) { // Ces informations ne servent qu'à composer l'e-mail : NE PAS écrire // $_SESSION['shipmember'], pour ne pas laisser en session l'identité d'un // compte QUE L'ON N'A PAS ENCORE AUTHENTIFIÉ (n'importe qui peut demander la // réinitialisation du mot de passe d'une adresse qui n'est pas la sienne). $cle_primaire_demande = $donnees['Cle_primaire']; $prenom_demande = $donnees['Prenom']; $nom_demande = $donnees['Nom']; $nb_emails_valides ++; } Liberation_jeu_de_resultat_bdd($reponse); if ($nb_emails_valides > 0) { // Génération d'un MDP aléatoire : $password = Mdp_aleatoire(6); // Si l'adresse email est vide, il est inutile de préparer un mdp... // Mise à jour du nouveau mot de passe : $requete = 'DELETE FROM TB_Activation WHERE ID_SHIPMEMBERS=?'; Requete_preparee_bdd($requete, array( array('i', $cle_primaire_demande)), __FILE__, __LINE__); $requete = 'UPDATE TB_Shipmembers SET Mdp=? WHERE ID=?'; Requete_preparee_bdd($requete, array( array('s', password_hash($password, PASSWORD_DEFAULT)), array('i', $cle_primaire_demande)), __FILE__, __LINE__); $requete = 'INSERT INTO TB_Activation(ID_SHIPMEMBERS) VALUES (?)'; Requete_preparee_bdd($requete, array( array('s', $cle_primaire_demande)), __FILE__, __LINE__); // Mémorisation dans l'historique de la connexion : $requete = 'INSERT INTO TB_Historique(Type, Sous_type, ID_ELEMENT, Valeur, Description) VALUES (?, ?, ?, ?, ?)'; Requete_preparee_bdd($requete, array( array('i', SYSTEME), array('i', SYSTEME_REINIT_MDP_USER), array('i', $cle_primaire_demande), array('i', 0), array('s', 'Réinitialisation du mot de passe de '.$prenom_demande.' '.$prenom_demande.' [N° '.$cle_primaire_demande.']')), __FILE__, __LINE__); // Calcul de la date limite d'activation du compte : $date = date_create("now"); // Date courante date_add($date, date_interval_create_from_date_string(''.$_SESSION['Config__Time_out_activation_compte'].' days')); // Date courante + Nb jour configurés $date_maxi_activation = date_format($date, "d/m/Y à H:i"); //......................................................................... // Préparation et envoi de l'email de regénération de mot de passe : $texte_email = t("

Bonjour,

Le mot de passe de votre compte ShipMember vient d'être réinitialisé à votre demande.

Nom : [[Prenom]] [[Nom]]

Email : [[Email]]

Mot de passe provisoire : [[Password]]

Plus qu’un clic : Connectez-vous sur [[Url_site]] pour activer votre compte ShipMember en modifiant votre mot de passe provisoire (*).

Bienvenue à nouveau parmi nous !

L'équipage ShipHeart

(*) L'activation devra être faite avant le [[Date_maxi_activation]]. Mais pas d'inquiétude ; si vous ne le faites pas avant, vous pourrez toujours demander un nouveau mot de passe provisoire.

"); // Mise à jour des parametres du texte : $texte_email = str_replace("[[Prenom]]", $prenom_demande, $texte_email); $texte_email = str_replace("[[Nom]]", $nom_demande, $texte_email); $texte_email = str_replace("[[Email]]", $_SESSION['shipmember']['Email'], $texte_email); $texte_email = str_replace("[[Password]]", $password, $texte_email); $texte_email = str_replace("[[Url_site]]", URL_SITE, $texte_email); $texte_email = str_replace("[[Date_maxi_activation]]", $date_maxi_activation, $texte_email); Envoi_email('', $_SESSION['shipmember']['Email'], t("Votre demande concernant votre accès ShipMember"), $texte_email, "ShipHeart by Koriolan", $_SESSION['Config__Adresse_email_shipmember'], ''); //............................................................................ // Message d'information : $message = t("Un email vient d'être envoyé à [[Prenom]] [[Nom]] ([[Email]]) avec les informations relatives à votre inscription.")."
"; $message = str_replace("[[Prenom]]", $prenom_demande, $message); $message = str_replace("[[Nom]]", $nom_demande, $message); $message = str_replace("[[Email]]", $_SESSION['shipmember']['Email'], $message); $message_information .= $message; //......................................................................... // $_SESSION['acces_valide'] = true; // $_SESSION['Shipmembers']['page'] = "Accueil"; } $_SESSION['Shipmembers']['page'] = "Login"; } } //--------------------------------------------------------------------------- // Modifications ShipMember : if (isset($_POST['validation_modification_shipmember']) AND isset($_POST['Prenom']) AND isset($_POST['Nom']) AND isset($_POST['Entreprise']) AND isset($_POST['Rue']) AND isset($_POST['Code_postal']) AND isset($_POST['Ville']) AND isset($_POST['ID_Pays']) AND isset($_POST['Email']) AND isset($_POST['Telephone']) AND isset($_POST['Mot_de_passe_1']) AND isset($_POST['Mot_de_passe_2'])) { // Mémorisation des valeurs saisies pour éviter de les perdre en cas d'erreur rendant la création impossible : $old_email = $_SESSION['shipmember']['Email']; $_SESSION['shipmember']['Prenom'] = trim($_POST['Prenom']); $_SESSION['shipmember']['Nom'] = trim($_POST['Nom']); $_SESSION['shipmember']['Entreprise'] = trim($_POST['Entreprise']); $_SESSION['shipmember']['Rue'] = trim($_POST['Rue']); $_SESSION['shipmember']['Code_postal'] = trim($_POST['Code_postal']); $_SESSION['shipmember']['Ville'] = trim($_POST['Ville']); $_SESSION['shipmember']['ID_Pays'] = $_POST['ID_Pays']; $_SESSION['shipmember']['Telephone'] = trim($_POST['Telephone']); $_SESSION['shipmember']['Email'] = strtolower(trim($_POST['Email'])); // Numéro normalisé au format international (synthèse §51) - un seul numéro par ShipMember, utilisé pour les SMS : $telephone_normalise = Normaliser_telephone($_SESSION['shipmember']['Telephone'], $_SESSION['shipmember']['ID_Pays']); if ($telephone_normalise === false) $message_erreur .= t("Numéro de téléphone invalide : saisissez-le au format international (par exemple +33 6 12 34 56 78)."); else $_SESSION['shipmember']['Telephone'] = $telephone_normalise; if ($old_email != $_SESSION['shipmember']['Email']) $flag_new_email = true; else $flag_new_email = false; // Vérifications : $message_erreur .= check_longueur_champ('prenom_titre', $_SESSION['shipmember']['Prenom'], MIN_LONGUEUR_PRENOM, MAX_LONGUEUR_PRENOM); $message_erreur .= check_longueur_champ('nom_titre', $_SESSION['shipmember']['Nom'], MIN_LONGUEUR_NOM, MAX_LONGUEUR_NOM); $message_erreur .= check_longueur_champ('rue_titre', $_SESSION['shipmember']['Rue'], MIN_LONGUEUR_RUE, MAX_LONGUEUR_RUE); $message_erreur .= check_longueur_champ('code_postal_titre', $_SESSION['shipmember']['Code_postal'], MIN_LONGUEUR_CODE_POSTAL, MAX_LONGUEUR_CODE_POSTAL); $message_erreur .= check_longueur_champ('ville_titre', $_SESSION['shipmember']['Ville'], MIN_LONGUEUR_VILLE, MAX_LONGUEUR_VILLE); $message_erreur .= check_longueur_champ('telephone_titre', $_SESSION['shipmember']['Telephone'], MIN_LONGUEUR_TELEPHONE, MAX_LONGUEUR_TELEPHONE); if (preg_match("#^[a-z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$#", $_SESSION['shipmember']['Email']) != 1) // Ce Preg-Match semble bien plus efficace que le "filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)"... { $message_erreur .= t("[Email] est invalide !"); } // Vérification si l'email n'existe pas déjà : if (($message_erreur == "") AND ($flag_new_email)) { $requete = 'SELECT count(ID) AS Nb_shipmembers FROM TB_Shipmembers WHERE Validite=1 AND Email=?'; $reponse = Requete_preparee_bdd($requete, array( array('s', $_SESSION['shipmember']['Email'])), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse)) { if ($donnees['Nb_shipmembers'] != 0) { $message_erreur .= t("[Email] est déjà utilisée par un ShipMember.
Si vous êtes le propriétaire de cette adresse, merci de vous connecter avec cette adresse.
Sinon, merci de choisir une autre adresse."); } } Liberation_jeu_de_resultat_bdd($reponse); } // Vérification des nouveaux mots de passe : $flag_new_pwd = false; if (strlen($_POST['Mot_de_passe_1']) != 0) // Si le premier mot de passe est vide, on considère qu'aucune mise à jour de MDP n'est demandée. { if ($_POST['Mot_de_passe_1'] != $_POST['Mot_de_passe_2']) $message_erreur .= t("Les deux mots de passe saisis doivent être identiques."); elseif (Check_mdp($_POST['Mot_de_passe_1']) != 1) $message_erreur .= t("Le mot de passe renseigné n'est pas conforme. Pour la sécurité de vos données, il doit contenir entre 6 et 20 caractères, et être composé exclusivement de minuscules, de majuscules, de chiffres ou des caractères spéciaux suivants _-!*=."); else $flag_new_pwd = true; } // Si les contrôles ne sont pas invalides, on met à jour le ShipMember : if ($message_erreur == "") { // Numéro MODIFIÉ : il n'est plus vérifié pour les SMS d'alerte (synthèse §51) - affectation évaluée avant celle du numéro : $requete = 'UPDATE TB_Shipmembers SET Prenom=?, Nom=?, Entreprise=?, Rue=?, Code_postal=?, Ville=?, ID_Pays=?, Telephone_verifie=IF(Telephone <=> ?, Telephone_verifie, 0), Code_telephone_empreinte=IF(Telephone <=> ?, Code_telephone_empreinte, NULL), Telephone=?, Email=? WHERE ID=?'; Requete_preparee_bdd($requete, array( array('s', $_SESSION['shipmember']['Prenom']), array('s', $_SESSION['shipmember']['Nom']), array('s', $_SESSION['shipmember']['Entreprise']), array('s', $_SESSION['shipmember']['Rue']), array('s', $_SESSION['shipmember']['Code_postal']), array('s', $_SESSION['shipmember']['Ville']), array('i', $_SESSION['shipmember']['ID_Pays']), array('s', $_SESSION['shipmember']['Telephone']), array('s', $_SESSION['shipmember']['Telephone']), array('s', $_SESSION['shipmember']['Telephone']), array('s', Protection_mysql($_SESSION['shipmember']['Email'])), // On protège l'Email contre les injections car c'est lui qui va servir aux requetes tant qu'on n'a pas la Clé_primaire. array('i', $_SESSION['shipmember']['Cle_primaire'])), __FILE__, __LINE__); // Mise à jour du nouveau mot de passe : if ($flag_new_pwd) { $requete = 'UPDATE TB_Shipmembers SET Mdp=? WHERE ID=?'; Requete_preparee_bdd($requete, array( array('s', password_hash($_POST['Mot_de_passe_1'], PASSWORD_DEFAULT)), // Haché tel quel (et non échappé : synthèse §47, §51) array('i', $_SESSION['shipmember']['Cle_primaire'])), __FILE__, __LINE__); $requete = 'DELETE FROM TB_Activation WHERE ID_SHIPMEMBERS=?'; Requete_preparee_bdd($requete, array( array('i', $_SESSION['shipmember']['Cle_primaire'])), __FILE__, __LINE__); // NB : on met à 0 le flag 'compte_a_activer' car il se peut qu'on soit là juste après la création (en accès temporaire). Dans ce cas, si on a mis à jour les mots de passe, // il est inutile de demander ensuite une activation. } // Mise à jour du libellé du pays : $requete = 'SELECT Texte AS Libelle_pays FROM TB_Textes_traduction WHERE ID_TEXTES=(SELECT ID_NOM FROM TB_Pays WHERE ID=?) AND ID_LANGUAGES=(SELECT ID FROM TB_Langues WHERE Prefix=?)'; $reponse = Requete_preparee_bdd($requete, array( array('i', $_SESSION['shipmember']['ID_Pays']), array('s', $_SESSION['langue'])), __FILE__, __LINE__); $donnees = Recherche_ligne_bdd($reponse); $_SESSION['shipmember']['libelle_pays'] = $donnees['Libelle_pays']; Liberation_jeu_de_resultat_bdd($reponse); // Mise à jour de l'email : if ($flag_new_email) { //......................................................................... // Préparation et envoi de l'email de modification d'adresse email : $texte_email = t("

Bonjour,

L'adresse email associée à votre compte ShipMember vient d'être modifiée à votre demande :

Ancienne adresse : [[Old_email]]

Nouvelle adresse : [[New_email]]

Si vous n'êtes pas à l'origine de ce changement d'adresse, merci de contacter sans attendre l'administrateur du site à : [[Adresse_email_alertes]]

L'équipage ShipHeart

"); // Mise à jour des parametres du texte : $texte_email = str_replace("[[Old_email]]", $old_email, $texte_email); $texte_email = str_replace("[[New_email]]", $_SESSION['shipmember']['Email'], $texte_email); $texte_email = str_replace("[[Adresse_email_alertes]]", $_SESSION['Config__Adresse_email_alertes'], $texte_email); Envoi_email('', $_SESSION['shipmember']['Email'], t("Modifications de votre accès ShipMember"), $texte_email, "ShipHeart by Koriolan", $_SESSION['Config__Adresse_email_shipmember'], ''); //Fin......................................................................... } $_SESSION['Shipmembers']['page'] = "Profil"; } } //************************************************************************************************************************************ // Traitement des données //************************************************************************************************************************************ // Protection contre les accès directs... : if (($_SESSION['Shipmembers']['page'] != "Login") AND ($_SESSION['Shipmembers']['page'] != "Activation") AND ($_SESSION['Shipmembers']['page'] != "Generation_mdp") AND (!$_SESSION['acces_valide'])) { Fermeture_bdd(); header('Location:shipmembers.php?action=navigation&destination=Login'); exit(); } // $_SESSION['code_acces'] = $_GET['code_acces']; // if (isset($_GET['code_acces']) && !isset($_SESSION['code_acces'])) $_SESSION['code_acces'] = $_GET['code_acces']; switch ($_SESSION['Shipmembers']['page']) { //**************************************************************************************************************************** case "Login": { //--------------------------------------------------------------------- // Saut à l'accueil sans login si on est déjà identifié : if ($_SESSION['acces_valide']) { Fermeture_bdd(); header('Location:shipmembers.php?action=navigation&destination=Accueil'); exit(); } // Lien d'invitation ouvert sans être connecté : bandeau explicatif (synthèse §47) : $invitation_login = null; if (isset($_SESSION['code_acces']) && $_SESSION['code_acces'] != '') { $invitation_login = Invitation_par_code($_SESSION['code_acces']); if ($invitation_login === null || $invitation_login['Statut'] != 'en_attente' || $invitation_login['Expiree']) { $message_erreur .= t("Cette invitation n'est plus valable (code inconnu, déjà utilisé, révoqué ou expiré)."); $invitation_login = null; $_SESSION['code_acces'] = ''; } } //--------------------------------------------------------------------- // Récupération des informations sur les pays : $nb_pays = 0; $requete = 'SELECT ID, ID AS Cle_primaire, Code_alpha2, Code_alpha3, (SELECT Texte AS Libelle_pays FROM TB_Textes_traduction WHERE ID_TEXTES=ID_NOM AND ID_TYPE = 1 AND ID_LANGUAGES=(SELECT ID FROM TB_Langues WHERE Prefix=?)) AS Nom FROM TB_Pays ORDER BY Nom ASC'; $reponse = Requete_preparee_bdd($requete, array( array('s', $_SESSION['langue'])), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse)) { $pays[$nb_pays ++] = $donnees; } Liberation_jeu_de_resultat_bdd($reponse); break; } //**************************************************************************************************************************** case "Activation": { //--------------------------------------------------------------------- // Saut à l'accueil sans login si on est déjà identifié : if ($_SESSION['acces_valide']) { Fermeture_bdd(); header('Location:shipmembers.php?action=navigation&destination=Accueil'); exit(); } break; } //**************************************************************************************************************************** case "Generation_mdp": { //--------------------------------------------------------------------- // Saut à l'accueil sans login si on est déjà identifié : if ($_SESSION['acces_valide']) { Fermeture_bdd(); header('Location:shipmembers.php?action=navigation&destination=Accueil'); exit(); } break; } //**************************************************************************************************************************** case "Accueil": { // Mise à jour des données du ShipMember (au cas où) : $requete = 'SELECT ID AS Cle_primaire, Validite, Nom, Prenom, Entreprise, Rue, Code_postal, Ville, Telephone, Email, Mdp, Date_creation_compte, Niveau_acces, ID_PAYS AS ID_Pays, ID_LANGUAGES, (SELECT 1 FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Compte_a_activer, (SELECT Date_creation_mdp FROM TB_Activation WHERE ID_SHIPMEMBERS=ID) AS Date_creation_mdp FROM TB_Shipmembers WHERE ID=?'; $reponse = Requete_preparee_bdd($requete, array( array('i', $_SESSION['shipmember']['Cle_primaire'])), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse)) { $_SESSION['shipmember'] = $donnees; } Liberation_jeu_de_resultat_bdd($reponse); Rafraichir_acces_session($_SESSION['shipmember']['Cle_primaire']); // Accès actifs (synthèse §47) // Code d'invitation reçu par lien ou saisi (synthèse §47) : on explique ce qu'il en est, l'acceptation elle-même // se fait par le bouton de la liste "Mes invitations" ci-dessous : if (isset($_SESSION['code_acces']) && $_SESSION['code_acces'] != '') { $invitation_code = Invitation_par_code($_SESSION['code_acces']); if ($invitation_code === null) $message_erreur .= t("Ce code d'invitation est inconnu."); else if ($invitation_code['Statut'] != 'en_attente') $message_erreur .= t("Cette invitation a déjà été utilisée ou révoquée."); else if ($invitation_code['Expiree']) $message_erreur .= t("Cette invitation a expiré : demandez-en une nouvelle à la personne qui vous l'a envoyée."); else if (strtolower($invitation_code['Email_invite']) != strtolower($_SESSION['shipmember']['Email'])) { $message_erreur .= str_replace("[[Email]]", Masquer_email($invitation_code['Email_invite']), t("Cette invitation est réservée à l'adresse [[Email]] : connectez-vous avec le compte ShipMember de cette adresse pour l'accepter.")); } else $message_information .= str_replace("[[Bateau]]", htmlspecialchars($invitation_code['Nom_bateau']), t("Vous avez été invité(e) à accéder au bateau [[Bateau]] : acceptez ou refusez l'invitation ci-dessous.")); $_SESSION['code_acces'] = ''; } // Invitations en attente adressées à ce compte (seul un compte activé peut en accepter) : $invitations = Compte_est_active($_SESSION['shipmember']['Cle_primaire']) ? Invitations_en_attente($_SESSION['shipmember']['Email']) : array(); // $_SESSION['acces_valide'] = true; break; } //**************************************************************************************************************************** case "Profil": { //--------------------------------------------------------------------- // Récupération des informations sur les pays : $nb_pays = 0; $requete = 'SELECT ID, Code_alpha2, Code_alpha3, (SELECT Texte FROM TB_Textes_traduction WHERE ID_TEXTES=ID_NOM AND ID_TYPE = 1 AND ID_LANGUAGES=(SELECT ID FROM TB_Langues WHERE Prefix=?)) AS Nom FROM TB_Pays WHERE ID=?'; $reponse = Requete_preparee_bdd($requete, array( array('s', $_SESSION['langue']), array('i', $_SESSION['shipmember']['ID_Pays'])), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse)) { $pays = $donnees; } Liberation_jeu_de_resultat_bdd($reponse); break; } //**************************************************************************************************************************** case "Modifier_profil": { //--------------------------------------------------------------------- // Récupération des informations sur les pays : $nb_pays = 0; $requete = 'SELECT ID, ID AS Cle_primaire, Code_alpha2, Code_alpha3, (SELECT Texte AS Libelle_pays FROM TB_Textes_traduction WHERE ID_TEXTES=ID_NOM AND ID_TYPE = 1 AND ID_LANGUAGES=(SELECT ID FROM TB_Langues WHERE Prefix=?)) AS Nom FROM TB_Pays ORDER BY Nom ASC'; $reponse = Requete_preparee_bdd($requete, array( array('s', $_SESSION['langue'])), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse)) { $pays[$nb_pays ++] = $donnees; } Liberation_jeu_de_resultat_bdd($reponse); break; } //**************************************************************************************************************************** case "Bateau": { // Bateaux accessibles : accès ACTIFS uniquement (synthèse §47). Le repli sur le bateau de démonstration // (liens portant le code "0000") est retiré, comme le bateau 25 de bateaux.php - à reprendre plus tard. Rafraichir_acces_session($_SESSION['shipmember']['Cle_primaire']); $nb_bateaux = 0; foreach ($_SESSION['bateau_shipmember'] as $acces) { $reponse = Requete_preparee_bdd('SELECT * FROM TB_Bateaux WHERE Cle_primaire=? AND Validite=1', array(array('i', $acces['ID_Bateau'])), __FILE__, __LINE__); while ($donnees = Recherche_ligne_bdd($reponse)) $bateaux[$nb_bateaux ++] = $donnees; Liberation_jeu_de_resultat_bdd($reponse); } break; } default: { $_SESSION['Shipmembers']['page'] = "Accueil"; break; } } Fermeture_bdd(); // Déconnexion de MySQL //************************************************************************************************************************************ // Affichage //************************************************************************************************************************************ Entete_page_html(); //******************************************************************************************************************************** // Affichage principal : echo '
'; echo '
'; // Permet de remonter au début de page par défaut //========================================================================================= // Entête : Entete_page($message_erreur, $message_information); // if (isset($_SESSION['code_acces'])) echo $_SESSION['code_acces']; switch ($_SESSION['Shipmembers']['page']) { //************************************************************************************************************************ case "Login": { echo '
'; echo '

'.t("Connectez-vous").'

'; // Lien d'invitation ouvert sans être connecté (synthèse §47) : if ($invitation_login !== null) { $texte = t("Vous avez été invité(e) à accéder au bateau [[Bateau]] ([[Type]]). Pour accepter cette invitation, connectez-vous - ou créez votre compte - avec l'adresse [[Email]]."); $texte = str_replace("[[Bateau]]", ''.htmlspecialchars($invitation_login['Nom_bateau']).'', $texte); $texte = str_replace("[[Type]]", htmlspecialchars((string)$invitation_login['Type_acces']), $texte); $texte = str_replace("[[Email]]", ''.htmlspecialchars(Masquer_email($invitation_login['Email_invite'])).'', $texte); echo '
'.$texte.'
'; } echo '
'; //--------------------------------------------------------------------------- // Déjà ShipMember : echo ''; //--------------------------------------------------------------------------- // Nouveau ShipMember : echo ''; echo '
'; break; } //************************************************************************************************************************ case "Activation": { echo '
'; echo '

'.t("Mon espace ShipMember").'

'; echo '
'; echo '
'; echo '

'.t("Activation de mon compte").'

'; echo '

'.t("Votre compte n'a pas encore été activé. Pour cela, merci de changer votre mot de passe provisoire ci-dessous.").'

'; echo '
'; echo '
'.t("Prénom").'
'.$_SESSION['shipmember']['Prenom'].'
'; echo '
'.t("Nom").'
'.$_SESSION['shipmember']['Nom'].'
'; echo '
'.t("Email").'
'.$_SESSION['shipmember']['Email'].'
'; echo '
'.t("Nouveau mot de passe").'
'; echo '
'.t("Nouveau mot de passe (2)").'
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; break; } //************************************************************************************************************************ case "Generation_mdp": { echo '
'; echo '

'.t("Mon espace ShipMember").'

'; echo '
'; echo '
'; echo '

'.t("Générer un nouveau mot de passe provisoire").'

'; echo '

'.t("Renseignez votre adresse email puis confirmez votre demande.
Si votre adresse existe bien dans la liste des ShipMembers, un email vous sera adressé immédiatement avec un nouveau mot de passe provisoire.").'

'.t("Attention : dès validation, seul ce nouveau mot de passe provisoire sera valide pour vous connecter. Si vous n'avez pas reçu cet email dans les prochaines minutes, merci de vérifier s'il ne se trouve pas dans vos courriers indésirables. ").'

'; echo '
'; echo '
'.t("Email").'*
'; echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; break; } //************************************************************************************************************************ case "Accueil": { echo '
'; echo '

'.t("Mon espace ShipMember").'

'; echo '
'; echo '

'.t("Bienvenue dans votre espace ShipMember !").'

'.t("Vous trouverez ici toutes les informations que nous conservons vous concernant. Notre objectif est de ne conserver que celles nécessaires au traitement de vos commandes et, surtout, vous permettant de profiter pleinement de toutes les fonctions de votre ShipHeart.").'

'.t("Enfin, nous vous rappelons que Koriolan ne diffuse et ne diffusera jamais la moindre de ces informations à d'autres sociétés. Pour plus de précisions sur le traitement de vos données personnelles, n'hésitez pas à consulter nos mentions légales accessibles en bas de cette page.").'

'; echo '
'; //--------------------------------------------------------------------------- // Mes invitations (synthèse §47) : echo '
'; echo '

'.t("Mes invitations").'

'; if (count($invitations) == 0) echo '

'.t("Aucune invitation en attente.").'

'; foreach ($invitations as $invitation) { $texte = t("Bateau [[Bateau]] - accès [[Type]], proposé par [[Invitant]] (valable jusqu'au [[Date]])."); $texte = str_replace("[[Bateau]]", ''.htmlspecialchars($invitation['Nom_bateau']).'', $texte); $texte = str_replace("[[Type]]", htmlspecialchars((string)$invitation['Type_acces']), $texte); $texte = str_replace("[[Invitant]]", htmlspecialchars(trim($invitation['Prenom_invitant'].' '.$invitation['Nom_invitant'])), $texte); $texte = str_replace("[[Date]]", date_format(date_create($invitation['Expiration_invitation']), 'd/m/Y'), $texte); echo '
'; echo '

'.$texte.'

'; echo ' '; echo ''; echo '
'; } // Saisie manuelle d'un code (invitation papier, sans appareil photo) : echo '
'; echo ' '; echo ' '; echo ''; echo '
'; echo '
'; echo '
'; echo ' '.t("Mes informations").' '; echo ' '.t("Mon bateau").' '; echo ' '.t("Déconnexion").' '; // Accès au menu d'administration : // if (isset($_SESSION['shipmember']['Niveau_administration']) && $_SESSION['shipmember']['Niveau_administration'] != '') if ($_SESSION['shipmember']['Niveau_acces'] >= NIVEAU_ACCES_MINI_ADMINISTRATEUR) { echo ' Administration '; } echo '
'; echo ''; break; } //************************************************************************************************************************ case "Profil": { echo '
'; echo '

'.t("Mon espace ShipMember").'

'; echo '
'; //--------------------------------------------------------------------------- // Profil ShipMember : echo '
'; echo '

'.t("Mes informations").'

'; /* echo '
'.t("Numéro de ShipMember").'
'.$_SESSION['shipmember']['Cle_primaire'].'
'; */ echo '
'.t("Prénom").'
'.$_SESSION['shipmember']['Prenom'].'
'; echo '
'.t("Nom").'
'.$_SESSION['shipmember']['Nom'].'
'; echo '
'.t("Entreprise").'
'.$_SESSION['shipmember']['Entreprise'].'
'; echo '
'.t("Numéro et rue").'
'.$_SESSION['shipmember']['Rue'].'
'; echo '
'.t("Code postal").'
'.$_SESSION['shipmember']['Code_postal'].'
'; echo '
'.t("Ville").'
'.$_SESSION['shipmember']['Ville'].'
'; echo '
'.t("Pays").'
'.$pays['Nom'].'
'; echo '
'.t("Téléphone").'
'.$_SESSION['shipmember']['Telephone'].'
'; echo '
'.t("Email").'
'.$_SESSION['shipmember']['Email'].'
'; echo '
'; echo '
'; echo ' '.t("Modifier").' '; echo ' '.t("Retour").' '; echo '
'; echo '
'; break; } //************************************************************************************************************************ case "Modifier_profil": { echo '
'; echo '

'.t("Modifier mes informations").'

'; echo '
'; //--------------------------------------------------------------------------- // Profil ShipMember : echo '
'; echo '

'.t("Modifier mes informations").'

'; echo '
'.t("Prénom").'*
'; echo '
'.t("Nom").'*
'; echo '
'.t("Entreprise").'
'; echo '
'.t("Numéro et rue").'
'; echo '
'.t("Code postal").'
'; echo '
'.t("Ville").'
'; echo '
'.t("Pays").'
'; echo '
'.t("Téléphone").'
'; echo '
'.t("Email").'*
'; // Modification MDP : echo '

'.t("Si vous souhaitez modifier votre mot de passe, entrez votre nouveau mot de passe deux fois ci-dessous. Sinon, laissez ces deux champs vides.").'

'; echo '
'.t("Nouveau mot de passe").'
'; echo '
'.t("Nouveau mot de passe (2)").'
'; echo '
'; echo '
'; echo ''; echo ' '.t("Annuler").' '; echo '
'; echo '
'; break; } //************************************************************************************************************************ case "Bateau": { echo '
'; echo '

'.t("Mon espace ShipMember").'

'; echo '
'; echo '
'; if ($nb_bateaux > 1) echo '

'.t("Accès à mes bateaux").'

'; else echo '

'.t("Accès à mon bateau").'

'; if ($nb_bateaux == 0) // Si aucun bateau n'est configuré pour ce ShipMember : { echo '

'.t("Vous n'avez pas encore de ShipHeart activé.").'

'.t("Mais dès que ce sera le cas, vous trouverez ici l'accès à votre ou vos bateaux.").'

'.t("Pour chacun d'eux, vous visualiserez l'état de tous les circuits, leur consommation, le niveau des réservoirs et des batteries, mais aussi toutes les valeurs de vos capteurs : températures, pression atmosphérique, humidité, position géographique, etc...
Vous aurez également accès aux courbes historiques de toutes ces valeurs.").'

'.t("C'est également ici que vous pourrez créer des profils [Propriétaire], [Installateur] ou [Skipper] afin de donner accès de façon contrôlée à votre ou à vos bateaux. Sans aucune limite !").'

'; } else // Si au moins un bateau est configuré pour ce ShipMember { for ($i=0; $i<$nb_bateaux; $i ++) { echo ' '.$bateaux[$i]['Nom'].' '; } } echo '
'; echo '
'; echo ' '.t("Retour").' '; echo '
'; echo '
'; break; } } echo '
'; echo '
'; //******************************************************************************************************************************** // Menu de pieds de page : Pied_de_page();