IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Mise au point d'un formulaire multipage


Sujet :

Langage PHP

  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 579
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 579
    Points : 804
    Points
    804
    Par défaut Mise au point d'un formulaire multipage
    Bonjour à tous,

    Pour une application de généalogie, je crée un formulaire sur plusieurs pages, initialement basé sur ce modèle. Ce modèle ne comporte pas de gestion d'erreurs. Pour la gestion des erreurs, je me suis donc tourné en complément sur celui-ci. J'ai également du apporter des modifications pour mes propres besoins.
    Le but du formulaire est de permettre à un utilisateur de proposer des mises à jour (créations ou modifications.
    La première page permet d'identifier le demandeur, les pages suivantes permettent de saisir les données à créer ou modifier.

    Mon problème est que la variable de session contenant les données d'une page s'efface lorsque je reviens en arrière sur une étape précedente. Les autres variables de session persistent, ce n'est donc pas un problème de session_start() dans la page parentPage.php.

    Voici le code de la page mère updateQuery.php (elle même incluse dans une page mère plus générale parentPage.php).
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    <?php
     
    // Demande de mise à jour d'une personne
     
    // A FAIRE
    /*
    	Faire test des erreurs
    	Ajouter les contrôles en JavaScript
    */
     
    ##################################################################### SECTION TETE : PARAMETRAGE AUTORISATION ##########################################################
     
    if (!isset($isIncluded)) {
    	header('Location: '.URL_SITE.INDEX_PAGE);
    	exit;
    }
     
    ##################################################################### Fin SECTION TETE : PARAMETRAGE AUTORISATION ######################################################
     
    ##################################################################### SECTION MODELE ###################################################################################
     
    connect();
     
    // Liste des colonnes d'une table
    function getColumnsFromTable($table) {
    	global $db;
     
    	$query = "SELECT COLUMN_NAME AS col
    		FROM information_schema.COLUMNS
    		WHERE TABLE_NAME='$table'
    	;";
    	$result = $db->query($query);
    	return $result->fetchAll(PDO::FETCH_ASSOC);
    }
     
    function getPersonTitle($id) {
    	global $db;
     
    	$dateFormat = LOCAL_DATE_FORMAT;
    	$query = "
    		SELECT
    			CONCAT(COALESCE(first_name, ''), ' ', COALESCE(last_name, '')) AS full_name,
    			CONCAT('(clef=', id, ')') AS full_id
    		FROM dat_persons
    		WHERE id=:id
    		LIMIT 1
    	;";
    	$result = $db->prepare($query);
    	$result->bindParam(':id', $id);
    	$result->execute();
    	return $result->fetch();
    }
     
    function getPerson($id) {
    	global $db;
     
    	$dateFormat = LOCAL_DATE_FORMAT;
    	$query = "
    		SELECT id, gender, last_name, first_name, middle_name, DATE_FORMAT(birth_date, '$dateFormat') AS birth_date, birth_place,
    			DATE_FORMAT(christening_date, '$dateFormat') AS christening_date, DATE_FORMAT(death_date, '$dateFormat') AS death_date, death_place,
    			profession, comment, father_id, mother_id, birth_order
    		FROM dat_persons
    		WHERE id=:id
    		LIMIT 1
    	;";
    	$result = $db->prepare($query);
    	$result->bindParam('id', $id);
    	$result->execute();
    	return $result->fetch(PDO::FETCH_ASSOC);
    }
     
    ##################################################################### FIN section MODELE ###############################################################################
     
    ##################################################################### SECTION CONTROLE #################################################################################
     
    define('CFG_FORM_ACTION', URL_SITE.'parentPage.php?childPageKey=11');
    define('REQ_FORMS', ['req_sender.php', 'req_person.php', 'req_biog.php', 'req_marriage.php', 'req_send']);
    define('STAGE_NB', count(REQ_FORMS));
    define('CFG_STAGE_ID', filter_input(INPUT_GET, 'stage', FILTER_VALIDATE_INT, [ 'options' => ['default'=>0, 'min_range'=>0, 'max_range'=>STAGE_NB] ]) );
    define('CFG_BACK_FORM', "Location:".CFG_FORM_ACTION."&stage=".strval(CFG_STAGE_ID-1) );
    define('CFG_NEXT_FORM', CFG_FORM_ACTION."&stage=".strval(CFG_STAGE_ID+1) );
    define('NAV_LNK', "<a href='".CFG_FORM_ACTION."&stage=%d'>%d - %s</a>");
     
    // Suppression des balises html
    function cleanPost($field) {
    	if ( is_string($field) ) {
    		$field = strip_tags($field);
    	}
    	if ( is_array($field) ) {
    		$field = array_map('strip_tags', $field);
    	}
    	return $field;
    }
     
    function filterPost() {
    	foreach ($_POST as $postName=>&$postValue) {
    		if ( strpos($postName, "src_") === 0 ) {
    			$toSave[$postName] = (int) $postValue;
    		}
    		switch ($postName) {
    			// Clés
    			case 'sender_id':
    			case 'idMain':
    			case 'father_id':
    			case 'mother_id':
    			case 'birth_order':
    				$toSave[$postName] = (int) $postValue;
    				if ( !empty($postValue) and $toSave[$postName] === 0 ) {
    					$errors[] = sprintf(REQ_ERR_KEYN, "<q>$postValue</q>");
    				}
    				break;
    			case 'sender_mail':
    				$toSave[$postName] = filter_input(INPUT_POST, $postName, FILTER_SANITIZE_EMAIL);
    				break;
    			// Téléphone de l'expéditeur
    			case 'sender_phone':
    				$toSave[$postName] = filter_input(INPUT_POST, $postName, FILTER_SANITIZE_NUMBER_INT);
    				break;
    			// Dates
    			case 'birth_date':
    			case 'death_date':
    			case 'christening_date':
    				$toSave[$postName] = convertDateFromEurToSQL($_POST[$postName], NULL);
    				if ( $toSave[$postName] === false ) {
    					$errors[] = sprintf(REQ_ERR_DATE, "<q>$postValue</q>");
    				}
    				break;
    			// Données textuelles ou non définies
    			default:
    				$toSave[$postName] = filter_input(INPUT_POST, $postName, FILTER_SANITIZE_STRING);
    				break;
    		}
    	}
    	return $toSave;
    }
     
    // Création du menu du haut de la page
    function makeMenuH() {
    	$items = [];
    	$_SESSION['updateQuery']['maxVisitedStage'] = empty($_SESSION['updateQuery']['maxVisitedStage']) ? 0: $_SESSION['updateQuery']['maxVisitedStage'];
    	if ($_SESSION['updateQuery']['maxVisitedStage'] < CFG_STAGE_ID) {
    		$_SESSION['updateQuery']['maxVisitedStage'] = CFG_STAGE_ID;
    	}
    	foreach(REQ_NAV_H as $formId => $formName) {
    		if ($formId >= $_SESSION['updateQuery']['maxVisitedStage']) {
    			$items[] = "<span>".strval($formId + 1)." - $formName</span>";
    		}
    		else {
    			$items[] = sprintf(NAV_LNK, $formId+1, $formId+1, $formName);
    		}
    	}
    	// Remplacement de la valeur définie dans la boucle précédente pour forcer le lien sur 'Résumé'
    	$navigH = implode('</li><li>', $items);
    	return "<ul class='menuH'><li>$navigH</li></ul>";//'<ul class="menuH"><li>'.$navigH.'</li></ul>';
    }
     
    // Fin des fonctions et des définitions ....................................................................................................................
     
    $errors[0] = '';
    $errors = ( !empty($_SESSION['updateQuery']['errors']) ) ? $_SESSION['updateQuery']['errors']: [''];
     
    // Récupération et contrôle de l'id de la personne à éditer
    if (isset($_POST['idMain'])) {
    	$_SESSION['updateQuery']['idMain'] = (int) $_POST['idMain'];
    	if ( ! checkIfIdIsInAbo($_SESSION['updateQuery']['idMain']) ) {
    		$errors[1] = sprintf(insertFrSpace(REQ_ERR_KEYN), "<q>{$_SESSION['updateQuery']['idMain']}</q>");
    		goto endPHP;
    	}
    }
    elseif (isset($_POST['new'])) {
    	$_SESSION['updateQuery']['idMain'] = 0;
    }
    if ( !isset($_SESSION['updateQuery']['idMain'] ) ) {
    	$errors[] = REQ_ERR_NOBODY;
    	goto endPHP;
    }
    $idMain = $_SESSION['updateQuery']['idMain'];
    unset($_POST['idMain'], $_POST['edit'], $_POST['new']);
     
    $navigH = makeMenuH();
     
    // Nettoyage des données envoyées par le $_POST
    if (!empty($_POST)) {
    	$_POST = array_map('cleanPost', $_POST);
    }
     
    // Récupération des informations, affichage des sous-formulaires
     
    switch(CFG_STAGE_ID) {
     
    	// Ouverture étape 1 (Etat-civil), Contrôle et enregistrement du demandeur (formulaire 0)
    	case 1:
    		unset($_POST['next']);
     
    		// Contrôle des saisies
    		if ( ! checkIfIdIsInAbo( (int) $_POST['sender_id'] ) ) { $errors[] = sprintf(insertFrSpace(REQ_ERR_KEYN), "<q>{$_POST['sender_id']}</q>"); }
    		if (empty($_POST['sender_lastname'])) { $errors[] = insertFrSpace(REQ_ERR_FROM_LAST); }
    		if (empty($_POST['sender_firstname'])) { $errors[] = insertFrSpace(REQ_ERR_FROM_FIRST); }
    		if (empty($_POST['sender_mail'])) {
    			if ( empty($_POST['sender_address']) or empty($_POST['sender_country']) or empty($_POST['sender_postcode']) or empty($_POST['sender_locality']) ) {
    				$errors[] = insertFrSpace(REQ_ERR_FROM_ADDRESSES);
    			}
    		}
    		if ($_POST['sender_mail'] and !ctl_email($_POST['sender_mail'])) { $errors[] = insertFrSpace(REQ_ERR_MAIL); }
    		if (!ctl_postcode($_POST['sender_postcode'])) { $errors[] = insertFrSpace(REQ_ERR_ZIPCODE); }
    		$_SESSION['updateQuery'][CFG_STAGE_ID-1] = filterPost();
     
    		// Retour au formulaire précédent en cas d'erreur
    		if ( count($errors) >1 ) {$_SESSION['updateQuery']['errors'] = $errors; header(CFG_BACK_FORM); exit; }
    		break;
     
    	// Ouverture étape 2 (biographie), contrôle et enregistrement de l'état-civil (formulaire 1)
    	case 2:
    		unset($_POST['next']);
     
    		// Contrôle des saisies
    		if (empty($_POST['gender'])) { $errors[] = insertFrSpace(REQ_ERR_GENDER); }
    		if (empty($_POST['last_name'])) { $errors[] = insertFrSpace(REQ_ERR_LAST); }
    		if (empty($_POST['first_name'])) { $errors[] = insertFrSpace(REQ_ERR_FIRST); }
    		if ($_POST['last_name'] == '?' and $_POST['first_name'] == '?') {
    			$errors[] = insertFrSpace(REQ_ERR_NO_NAME);
    		}
    		$_SESSION['updateQuery'][CFG_STAGE_ID-1] = filterPost();
     
    		// Retour au formulaire précédent en cas d'erreur
    		if ( count($errors) >1 ) {$_SESSION['updateQuery']['errors'] = $errors; header(CFG_BACK_FORM); exit; }
    		break;
     
    	// Ouverture étape 3 (marriages), contrôle et enregistrement de la biographie (formulaire 2)
    	case 3:
    		// Contrôle des saisies
    		if ($_POST['text'] and empty($_POST['author'])) { $errors[] = insertFrSpace(REQ_ERR_AUTHOR); }
    		if ($_POST['text'] and empty($_POST['sources'])) { $errors[] = insertFrSpace(REQ_ERR_SOURCES); }
    		$_SESSION['updateQuery'][CFG_STAGE_ID-1] = filterPost();
     
    		// Retour au formulaire précédent en cas d'erreur
    		if ( count($errors) >1 ) {$_SESSION['updateQuery']['errors'] = $errors; header(CFG_BACK_FORM); exit; }
    		break;
     
    	// Mariages
    	case 4:
    		break;
     
    	// Envoi formulaire / Enregistrement
    	case STAGE_NB:
    		break;
     
    	default:
    		break;
    }
     
    $form = 'includes/forms/'.REQ_FORMS[CFG_STAGE_ID];
     
    endPHP:
     
    // Titre général du formulaire
    $personTitle = getPersonTitle($idMain);
    $h2 = ( !empty($personTitle) ) ? sprintf(REQ_H2_PARAM, $personTitle->full_name, $personTitle->full_id): REQ_H2_NEW;
     
    // Définition des options de boutons radio src_*
    $srcOptions = '';
    foreach (REQ_SRC_OPTIONS as $value=>$text) {
    	$srcOptions .= "<option value='$value'>$text</option>".PHP_EOL;
    }
     
    ##################################################################### FIN section CONTROLE #############################################################################
     
    ##################################################################### SECTION VUE ######################################################################################
     
    ?>
     
    <h2><?= $h2 ?></h2>
     
    <?php
    if ( isset($_SESSION['updateQuery']['errors']) ) {
    	echo '<p>'.displayErrors($_SESSION['updateQuery']['errors']).'</p>';
    	unset($_SESSION['updateQuery']['errors']);
    }
    ?>
     
    <?= $navigH; ?>
     
    <h3><?= REQ_NAV_H[CFG_STAGE_ID]; ?></h3>
     
    <p class="note"><?= MUST_FIELD ?></p>
     
    <?php
    if (file_exists($form))
    	require_once($form);
    ?>
     
    <script src="libraries/common.js"></script>
     
    <?php
     
    ##################################################################### FIN section VUE ##################################################################################
    Et un sous formulaire
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    <?php
     
    // Demande de mise à jour d'une personne - Form 1
     
    ##################################################################### SECTION TETE : PARAMETRAGE AUTORISATION ##########################################################
     
    if (!isset($isIncluded)) {
    	header('Location: '.URL_SITE.INDEX_PAGE);
    	exit;
    }
     
    ##################################################################### Fin SECTION TETE : PARAMETRAGE AUTORISATION ######################################################
     
    ##################################################################### SECTION MODELE ###################################################################################
     
    connect();
     
    // checks if a column exists in the table
    function columnExists($column){
    	global $db;
     
    	$query = "SELECT COUNT(*) AS cpt
    		FROM information_schema.COLUMNS
    		WHERE COLUMN_NAME='$column' and TABLE_NAME='lst_countries'
    	;";
    	$result = $db->query($query);
    	$exists = $result->fetch();
    	if (boolval($exists->cpt)) return true;
    	return false;
    }
     
    ##################################################################### FIN section MODELE ###############################################################################
     
    ##################################################################### SECTION CONTROLE #################################################################################
     
    // Initialisation des données du formulaire
    if ( !empty($_SESSION['updateQuery'][CFG_STAGE_ID]) ) { $_POST = $_SESSION['updateQuery'][CFG_STAGE_ID]; }
    else {
    	$_POST = array_merge( $_POST, array_fill_keys([
    	'sender_id',
    	'sender_lastname',
    	'sender_firstname',
    	'sender_mail',
    	'sender_address',
    	'sender_country',
    	'sender_postcode',
    	'sender_locality',
    	'sender_phone' ,
    	'message',
    	], '' ) );
    }
     
    // Récupération de la liste des pays en base de données
    $colName = "en_name";
    if (columnExists($language."_name")) {
    	$colName = $language."_name";
    }
    $objCountries = new readTable($db, 'lst_countries', ['id', $colName], 1);
    $objCountries->set_filter('filter', 1);
    $countries = $objCountries->get_data();
     
    // Création de la liste de choix des pays
    $lstCountries = new optListSelect("sender_country");
    $lstCountries->addOption(new optListOption(''));
    foreach ($countries as $country) {
    	$selected = '';
    	if (isset($_POST['sender_country']) and strtoupper($_POST['sender_country']) == strtoupper($country['id'])) {
    		$selected = ' selected';
    	}
    	$lstCountries->addOption(new optListOption($country[$colName], $country['id'], $selected));
    }
    unset($selected, $country);
     
    ##################################################################### FIN section CONTROLE #############################################################################
     
    ##################################################################### SECTION VUE ######################################################################################
     
    ?>
     
    <form method="post" action="<?= CFG_NEXT_FORM; ?>" class="L">
     
    	<label for="sender_id" class="mustField"><?= REQ_LBL_KEY ?>&nbsp;<sup>(a)</sup></label>
    		<input type="text" name="sender_id" id="sender_id" value="<?= $_POST['sender_id']; ?>" placeholder="1234" required /><br/>
    	<label for="sender_lastname" class="mustField"><?= REQ_LBL_LAST ?></label>
    		<input type="text" name="sender_lastname" id="sender_lastname" value="<?= $_POST['sender_lastname']; ?>" required /><br/>
    	<label for="sender_firstname" class="mustField"><?= REQ_LBL_FIRST ?></label>
    		<input type="text" name="sender_firstname" id="sender_firstname" value="<?= $_POST['sender_firstname']; ?>" required /><br/>
    	<label for="sender_mail"><?= REQ_LBL_MAIL ?>&nbsp;<sup>(b)</sup></label>
    		<input type="text" name="sender_mail" id="sender_mail" value="<?= $_POST['sender_mail']; ?>" /><br/>
    	<label for="sender_address"><?= REQ_LBL_ADDRESS ?>&nbsp;<sup>(b)</sup></label>
    		<textarea name="sender_address" id="sender_address"><?= $_POST['sender_address']; ?></textarea><br/>
    	<label for="sender_country"><?= REQ_LBL_COUNTRY ?>&nbsp;<sup>(b)</sup></label>
    		<?= $lstCountries ?><br/>
    	<label for="sender_postcode"><?= REQ_LBL_ZIP ?>&nbsp;<sup>(b)</sup></label>
    		<input type="text" name="sender_postcode" id="sender_postcode" value="<?= $_POST['sender_postcode']; ?>" /><br/>
    	<label for="sender_locality"><?= REQ_LBL_LOCALITY ?>&nbsp;<sup>(b)</sup></label>
    		<input type="text" name="sender_locality" id="sender_locality" value="<?= $_POST['sender_locality']; ?>" /><br/>
    	<label for="sender_phone"><?= REQ_LBL_PHONE ?>&nbsp;<sup>(c)</sup></label>
    		<input type="text" name="sender_phone" id="sender_phone" value="<?= $_POST['sender_phone']; ?>" /><br/>
    	<label for="message"><?= REQ_LBL_MESSAGE; ?></label>
    		<textarea name="message" id="message" /><?= $_POST['message']; ?></textarea><br/>
    	<p class="note">
    		<sup>(a)</sup>&nbsp;<?= REQ_NOTE_FOR_KEY ?><br/>
    		<sup>(b)</sup>&nbsp;<?= REQ_NOTE_FOR_ADDRESSES ?><br/>
    		<sup>(c)</sup>&nbsp;<?= REQ_NOTE_FOR_PHONE ?><br/>
    	</p>
    	<p><input type="submit" name="next" value="<?= BTN_NEXT; ?>" /></p>
     
    </form>
     
    <?php
     
    ##################################################################### FIN section VUE ##################################################################################

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 579
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 579
    Points : 804
    Points
    804
    Par défaut
    Je ne m'en sors pas.
    J'ai avancé dans le sens où j'ai à la fois complété mon code et supprimé quelques bugs. Mais la perte de variables de session persiste.
    J'ai testé avec des var_dump mais je ne trouve pas ce qui ne va pas.
    La perte se fait lorsque après l'étape 3 ou 4, je reviens en arrière à l'étape 1 et que je passe à puis repasse à nouveau vers une étape suivante (2 ou 3). A ce moment là les variables de session des étapes 1 ou 2 sont effacées sans que je comprennent pourquoi. Je vous mets le code complet parce que je n'arrive pas à localiser la partie de code en cause.
    Si je parcours toutes les étapes dans l'ordre, tout se passe bien.
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    <?php
     
    // Demande de mise à jour d'une personne
     
    // RESTE A FAIRE
    /*
        Voir où on perd la session
        Contrôler les dates AVANT les erreurs et AVANT enregistrement
        Faire test des erreurs
        Ajouter les contrôles en JavaScript
    */
     
    ##################################################################### SECTION TETE : PARAMETRAGE AUTORISATION ##########################################################
     
    if (!isset($isIncluded)) {
        header('Location: '.URL_SITE.INDEX_PAGE);
        exit;
    }
     
    ##################################################################### Fin SECTION TETE : PARAMETRAGE AUTORISATION ######################################################
     
    ##################################################################### SECTION MODELE ###################################################################################
     
    connect();
     
    // Liste des colonnes d'une table
    function getColumnsFromTable($table) {
        global $db;
     
        $query = "SELECT COLUMN_NAME AS col
            FROM information_schema.COLUMNS
            WHERE TABLE_NAME='$table'
        ;";
        $result = $db->query($query);
        return $result->fetchAll(PDO::FETCH_ASSOC);
    }
     
    function getPersonTitle($id) {
        global $db;
     
        $dateFormat = LOCAL_DATE_FORMAT;
        $query = "
            SELECT
                CONCAT(COALESCE(first_name, ''), ' ', COALESCE(last_name, '')) AS full_name,
                CONCAT('(clef=', id, ')') AS full_id
            FROM dat_persons
            WHERE id=:id
            LIMIT 1
        ;";
        $result = $db->prepare($query);
        $result->bindParam(':id', $id);
        $result->execute();
        return $result->fetch();
    }
     
    function getPerson($id) {
        global $db;
     
        $dateFormat = LOCAL_DATE_FORMAT;
        $query = "
            SELECT id, gender, last_name, first_name, middle_name, DATE_FORMAT(birth_date, '$dateFormat') AS birth_date, birth_place,
                DATE_FORMAT(christening_date, '$dateFormat') AS christening_date, DATE_FORMAT(death_date, '$dateFormat') AS death_date, death_place,
                profession, comment, father_id, mother_id, birth_order
            FROM dat_persons
            WHERE id=:id
            LIMIT 1
        ;";
        $result = $db->prepare($query);
        $result->bindParam('id', $id);
        $result->execute();
        return $result->fetch(PDO::FETCH_ASSOC);
    }
     
    function saveData($toSave) {
        global $db;
     
        var_dump($toSave);
        $id = $toSave['idMain'];
     
        $db->beginTransaction();
     
        try {
            // Enregistrement de la demande
            $query = "
                INSERT INTO req_request (
                    id_abo, sender_id, sender_lastname, sender_firstname, sender_mail, sender_address, sender_country, sender_postcode, sender_locality, sender_phone, message
                )
                VALUES (
                    :id_abo, :sender_id, :sender_lastname, :sender_firstname, :sender_mail, :sender_address, :sender_country, :sender_postcode, :sender_locality, :sender_phone, :message
                )
            ;";
            $result = $db->prepare($query);
            $result->execute($toSave[0]);
            if ($result->rowCount() == 1) { $requestId = $db->lastInsertId(); }
     
            // Enregistrement des données d'état-civil
            $toSave[1]['id_req'] = $requestId;
            $query = "
                INSERT IGNORE INTO req_persons (
                    id_req, id_abo, id, gender, last_name, first_name, middle_name, birth_date, birth_place, death_date, death_place, christening_date, 
                    profession, comment, father_id, mother_id, birth_order, 
                    src_gender, src_last_name, src_first_name, src_middle_name, src_birth_date, src_birth_place, src_death_date, src_death_place, 
                    src_father_id, src_mother_id, src_birth_order
                )
                VALUES (
                    :id_req, :id_abo, :id, :gender, :last_name, :first_name, :middle_name, :birth_date, :birth_place, :death_date, :death_place, :christening_date, 
                    :profession, :comment, :father_id, :mother_id, :birth_order, 
                    :src_gender, :src_last_name, :src_first_name, :src_middle_name, :src_birth_date, :src_birth_place, :src_death_date, :src_death_place, 
                    :src_father_id, :src_mother_id, :src_birth_order
                )
            ;";
            $result = $db->prepare($query);
            $result->execute($toSave[1]);
     
            // Enregistrement de la biographie
            $toSave[2]['id_req'] = $requestId;
            $query = "
                INSERT IGNORE INTO req_biographies (
                    id_req, id_abo, id, text, author, sources, picture, picturetype
                )
                VALUES (
                    :id_req, :id_abo, :id, :text, :author, :sources, :picture, :picturetype
                )
            ;";
            $result = $db->prepare($query);
            $result->execute($toSave[2]);
     
            // Enregistrement des données des mariages
            // Reste à faire
        }
     
        catch (Exception $e) {
            if ( IS_LOCAL ) { var_dump($e->getMessage(), $e->getLine()); }
            $db->rollback();
            return false;
        }
     
        $db->commit();
        return $requestId;
    }
     
    // d'après https://laethy.developpez.com/temp/Stocker-images-dans-MySQL/
    function dataUpload() {
        global $errors;
     
        if ($_FILES['picture']['error'] == UPLOAD_ERR_NO_FILE) {
            return ['picture'=>NULL, 'picturetype'=>NULL];
        }
        if ( !is_uploaded_file($_FILES['picture']['tmp_name']) ) {
            $errors[] = REQ_ERR_UPLOAD;
            return false;
        }
     
        $imgBlob = '';
        $imgType = '';
     
        // Contrôle du fichier image
        $upl = new uploadCtl('picture', MAX_FILE_SIZE);
        $upl->set_maxImgSizes(MAX_IMG_SIZES);
        $upl->set_onlyAllowedTypes(ALLOWED_TYPES);
        $ctl = $upl->ctl();
        // Préparation du fichier image
        if (count($ctl) == 1 and $ctl[0] == 0)
        {
            $imgType = $_FILES['picture']['type'];
            $imgBlob = file_get_contents($_FILES['picture']['tmp_name']);
            $imgBlob = addslashes($imgBlob);
        }
        else {
            foreach ($ctl as $err) {
                if ( $err == 0 ) continue;
                $errors[] = UPL_ERR[$err];
                return false;
            }
        }
        return ['picture'=>$imgBlob, 'picturetype'=>$imgType];
    }
     
    ##################################################################### FIN section MODELE ###############################################################################
     
    ##################################################################### SECTION CONTROLE #################################################################################
     
    define('CFG_FORM_ACTION', URL_SITE.'parentPage.php?childPageKey=11'); // Ajouté URL_SITE
    define('REQ_FORMS', ['req_sender.php', 'req_person.php', 'req_biog.php', 'req_marriage_2.php', 'req_submit.php']);
    define('STAGE_NB', count(REQ_FORMS));
    define('CFG_STAGE_ID', filter_input(INPUT_GET, 'stage', FILTER_VALIDATE_INT, [ 'options' => ['default'=>0, 'min_range'=>0, 'max_range'=>STAGE_NB] ]) );
    define('CFG_BACK_FORM', "Location:".CFG_FORM_ACTION."&stage=".strval(CFG_STAGE_ID-1) );
    define('CFG_NEXT_FORM', CFG_FORM_ACTION."&stage=".strval(CFG_STAGE_ID+1) );
    define('NAV_LNK', "<a href='".CFG_FORM_ACTION."&stage=%d'>%d - %s</a>");
    define('MAX_FILE_SIZE', 150000);
    define('MAX_IMG_SIZES', [300, 300]);
    define('ALLOWED_TYPES', "gif, jpg, jpeg, png");
     
    // Contrôle d'existence d'une date européenne
    function checkDateEur($date, $format, $empty='') {
        if ( empty($date) ) return $empty;
        $values    = preg_split("#[\./ -]#", $date);
        $keys    = preg_split("#[\./ -]#", $format);
        $arr = array_combine($keys, $values);
        if ( count($arr) <3 ) { return false; }
        return checkdate( $arr['m'], $arr['d'], $arr['Y'] );
    }
     
    // Suppression des balises html
    function cleanPost($field) {
        if ( is_string($field) ) {
            $field = strip_tags($field);
        }
        if ( is_array($field) ) {
            $field = array_map('strip_tags', $field);
        }
        return $field;
    }
     
    function filterPost() {
        global $errors;
     
        foreach ($_POST as $postName=>&$postValue) {
            if ( strpos($postName, "src_") === 0 ) {
                $data[$postName] = (int) $postValue;
            }
            switch ($postName) {
                // Clés
                case 'sender_id':
                case 'idMain':
                case 'father_id':
                case 'mother_id':
                case 'birth_order':
                    var_dump(__line__);
                    $data[$postName] = (int) $postValue;
                    if ( !empty($postValue) and $data[$postName] === 0 ) {
                        $errors[] = sprintf(REQ_ERR_KEYN, "<q>$postValue</q>");
                    }
                    break;
                case 'sender_mail':
                    var_dump(__line__);
                    $data[$postName] = filter_input(INPUT_POST, $postName, FILTER_SANITIZE_EMAIL);
                    break;
                // Téléphone de l'expéditeur
                case 'sender_phone':
                    var_dump(__line__);
                    $data[$postName] = filter_input(INPUT_POST, $postName, FILTER_SANITIZE_NUMBER_INT);
                    break;
                // Dates
                case 'birth_date':
                case 'death_date':
                case 'christening_date':
                    $data[$postName] = checkDateEur( $_POST[$postName], str_replace('%', '', LOCAL_DATE_FORMAT) );
                    if ( $data[$postName] === false ) { $errors[] = sprintf(REQ_ERR_DATE, "<q>$postValue</q>"); }
                    break;
                // Image
                case 'picture':
                case 'MAX_FILE_SIZE':
                    break;
                // Données textuelles ou non définies
                default:
                    $data[$postName] = filter_input(INPUT_POST, $postName, FILTER_SANITIZE_STRING);
                    break;
            }
        }
        if ( empty($data) ) { return []; }
        return $data;
    }
     
    // Création du menu du haut de la page
    function makeMenuH() {
        $items = [];
        $_SESSION['updateQuery']['maxVisitedStage'] = empty($_SESSION['updateQuery']['maxVisitedStage']) ? 0: $_SESSION['updateQuery']['maxVisitedStage'];
        if ($_SESSION['updateQuery']['maxVisitedStage'] < CFG_STAGE_ID) {
            $_SESSION['updateQuery']['maxVisitedStage'] = CFG_STAGE_ID;
        }
        foreach(REQ_NAV_H as $formId => $formName) {
            if ($formId >= $_SESSION['updateQuery']['maxVisitedStage']) {
                $items[] = "<span>".strval($formId + 1)." - $formName</span>";
            }
            else {
                $items[] = sprintf(NAV_LNK, $formId, $formId+1, $formName);
            }
        }
        $navigH = implode('</li><li>', $items);
        return "<ul class='menuH'><li>$navigH</li></ul>";
    }
     
    // Fin des fonctions et des définitions ....................................................................................................................
     
    $errors[0] = '';
    $errors = ( !empty($_SESSION['updateQuery']['errors']) ) ? $_SESSION['updateQuery']['errors']: [''];
     
    // Récupération et contrôle de l'id de la personne à éditer
    if (isset($_POST['idMain'])) {
        $_SESSION['updateQuery']['idMain'] = (int) $_POST['idMain'];
        if ( ! checkIfIdIsInAbo($_SESSION['updateQuery']['idMain']) ) {
            $errors[1] = sprintf(insertFrSpace(REQ_ERR_KEYN), "<q>{$_SESSION['updateQuery']['idMain']}</q>");
            goto endPHP;
        }
    }
    elseif (isset($_POST['new'])) {
        $_SESSION['updateQuery']['idMain'] = 0;
    }
    if ( !isset($_SESSION['updateQuery']['idMain'] ) ) {
        $errors[] = REQ_ERR_NOBODY;
        goto endPHP;
    }
    $idMain = $_SESSION['updateQuery']['idMain'];
    unset($_POST['idMain'], $_POST['edit'], $_POST['new']);
     
    $navigH = makeMenuH();
     
    // Nettoyage des données envoyées par le $_POST
    if (!empty($_POST)) {
        $_POST = array_map('cleanPost', $_POST);
    }
     
    // Récupération des informations, affichage des sous-formulaires
     
    // Mettre verrouillage en démo
     
    var_dump(CFG_STAGE_ID);
    switch(CFG_STAGE_ID) {
     
        case 0:
            break;
     
        // Contrôle et enregistrement en session du formulaire 0 (demandeur)
        case 1:
            unset($_POST['next']);
            var_dump(__line__);
     
            // Contrôle des saisies
            if ( ! checkIfIdIsInAbo( (int) $_POST['sender_id'] ) ) { $errors[] = sprintf(insertFrSpace(REQ_ERR_KEYN), "<q>{$_POST['sender_id']}</q>"); }
            if (empty($_POST['sender_lastname'])) { $errors[] = insertFrSpace(REQ_ERR_FROM_LAST); }
            if (empty($_POST['sender_firstname'])) { $errors[] = insertFrSpace(REQ_ERR_FROM_FIRST); }
            if (empty($_POST['sender_mail'])) {
                if ( empty($_POST['sender_address']) or empty($_POST['sender_country']) or empty($_POST['sender_postcode']) or empty($_POST['sender_locality']) ) {
                    $errors[] = insertFrSpace(REQ_ERR_FROM_ADDRESSES);
                }
            }
            if ($_POST['sender_mail'] and !ctl_email($_POST['sender_mail'])) { $errors[] = insertFrSpace(REQ_ERR_MAIL); }
            if (!ctl_postcode($_POST['sender_postcode'])) { $errors[] = insertFrSpace(REQ_ERR_ZIPCODE); }
     
            $_SESSION['updateQuery'][CFG_STAGE_ID-1] = filterPost();
     
            // Retour au formulaire 0 en cas d'erreur
            if ( count($errors) >1 ) {$_SESSION['updateQuery']['errors'] = $errors; header(CFG_BACK_FORM); exit; }
            break;
     
        // Contrôle et enregistrement en session du formulaire 1 (Etat-civil))
        case 2:
            unset($_POST['next']);
            var_dump(__line__);
     
            // Contrôle des saisies
            if (empty($_POST['gender'])) { $errors[] = insertFrSpace(REQ_ERR_GENDER); }
            if (empty($_POST['last_name'])) { $errors[] = insertFrSpace(REQ_ERR_LAST); }
            if (empty($_POST['first_name'])) { $errors[] = insertFrSpace(REQ_ERR_FIRST); }
            if ($_POST['last_name'] == '?' and $_POST['first_name'] == '?') {
                $errors[] = insertFrSpace(REQ_ERR_NO_NAME);
            }
     
            $_SESSION['updateQuery'][CFG_STAGE_ID-1] = filterPost();
     
            // Retour au formulaire 1 en cas d'erreur
            if ( count($errors) >1 ) {$_SESSION['updateQuery']['errors'] = $errors; header(CFG_BACK_FORM); exit; }
            break;
     
        // Contrôle et enregistrement en session du formulaire 2 (biographie)
        case 3:
            unset($_POST['next']);
            var_dump(__line__);
     
            // Contrôle des saisies
            if ($_POST['text'] and empty($_POST['author'])) { $errors[] = insertFrSpace(REQ_ERR_AUTHOR); }
            if ($_POST['text'] and empty($_POST['sources'])) { $errors[] = insertFrSpace(REQ_ERR_SOURCES); }
     
            $_SESSION['updateQuery'][CFG_STAGE_ID-1] = filterPost();
     
            // Ajout de l'image et de son type
            $dataUploaded = dataUpload();
            if ( $dataUploaded ) {
                unset( $_SESSION['updateQuery'][CFG_STAGE_ID-1]['MAX_FILE_SIZE'] );
                $_SESSION['updateQuery'][CFG_STAGE_ID-1] = array_merge( $_SESSION['updateQuery'][CFG_STAGE_ID-1], $dataUploaded );
            }
     
            // Retour au formulaire 2 en cas d'erreur
            if ( count($errors) >1 ) {$_SESSION['updateQuery']['errors'] = $errors; header(CFG_BACK_FORM); exit; }
            break;
     
        // Contrôle et enregistrement en session du formulaire 3 (mariages)
        case 4:
            unset($_POST['next']);
            var_dump(__line__);
     
            // Contrôle des saisies
            // En attente de finir de traiter le formulaire
     
            $_SESSION['updateQuery'][CFG_STAGE_ID-1] = filterPost();
     
            // Retour au formulaire 3 en cas d'erreur
            if ( count($errors) >1 ) {$_SESSION['updateQuery']['errors'] = $errors; header(CFG_BACK_FORM); exit; }
     
            $toSave = $_SESSION['updateQuery'];
            //$ctl = saveData($toSave);
            //var_dump($ctl);
            break;
     
        // Envoi formulaire / Enregistrement
        default:
            unset($_POST['next']);
            break;
    }
    //var_dump(CFG_STAGE_ID, $_SESSION['updateQuery']);
     
    $form = 'includes/forms/'.REQ_FORMS[CFG_STAGE_ID];
     
    endPHP:
    //var_dump(CFG_STAGE_ID, $_SESSION['updateQuery']);
    //exit;
     
    // Titre général du formulaire
    $personTitle = getPersonTitle($idMain);
    $h2 = ( !empty($personTitle) ) ? sprintf(REQ_H2_PARAM, $personTitle->full_name, $personTitle->full_id): REQ_H2_NEW;
     
    // Définition des options de boutons radio src_*
    $srcOptions = '';
    foreach (REQ_SRC_OPTIONS as $value=>$text) {
        $srcOptions .= "<option value='$value'>$text</option>".PHP_EOL;
    }
     
    ##################################################################### FIN section CONTROLE #############################################################################
     
    ##################################################################### SECTION VUE ######################################################################################
     
    ?>
     
    <h2><?= $h2 ?></h2>
     
    <?php
    if ( isset($_SESSION['updateQuery']['errors']) ) {
        echo '<p>'.displayErrors($_SESSION['updateQuery']['errors']).'</p>';
        unset($_SESSION['updateQuery']['errors']);
    }
    ?>
     
    <?= $navigH; ?>
     
    <h3><?= REQ_NAV_H[CFG_STAGE_ID]; ?></h3>
     
    <p class="note"><?= MUST_FIELD ?></p>
     
    <?php
    if (file_exists($form)) { require_once($form); }
    ?>
     
    <script src="libraries/common.js"></script>
     
    <?php
     
    ##################################################################### FIN section VUE ##################################################################################

  3. #3
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    ben normalement, quand tu reviens en arrière tu dois pré-remplir le formulaire avec les données déjà en session. Ainsi, le formulaire soumis ne perdra pas ses données, sinon dans la plupart des cas, tu soumets un formulaire vide qui du coup te purge les données de session.
    Ton fichier contient trop de traitements

  4. #4
    Membre éclairé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 579
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 579
    Points : 804
    Points
    804
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    ben normalement, quand tu reviens en arrière tu dois pré-remplir le formulaire avec les données déjà en session. Ainsi, le formulaire soumis ne perdra pas ses données, sinon dans la plupart des cas, tu soumets un formulaire vide qui du coup te purge les données de session.
    Cela, je l'ai bien compris et c'est bien ce que je fais dans le formulaire (voir exemple ci-dessous) et c'est pourquoi je ne comprends pas ce qui se passe.
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Initialisation des données du formulaire
    if ( !empty($_SESSION['updateQuery'][CFG_STAGE_ID]) ) { $_POST = $_SESSION['updateQuery'][CFG_STAGE_ID]; }
    else {
    	$_POST = array_fill_keys([
    	'author',
    	'sources',
    	'text',
    	], '' );
    }
    Citation Envoyé par rawsrc Voir le message
    Ton fichier contient trop de traitements
    Il faut bien que je traite tout ce qui est à traiter!

  5. #5
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    ah la vache je n'avais pas fais gaffe mais tu ne dois jamais tripatouiller le contenu des variables super globales :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $_POST = $_SESSION['updateQuery'][CFG_STAGE_ID];
    c'est une source de bogues sans pareille

    Citation Envoyé par moimp Voir le message
    Il faut bien que je traite tout ce qui est à traiter!

    ça je m'en doute sauf que même en parcourant ton code dans tous les sens je me suis noyé.
    Formulaire muti-onglets => tu devrais avoir un fichier PHP de traitement par onglet

Discussions similaires

  1. Mise en page d'un formulaire en vb
    Par vivah dans le forum IHM
    Réponses: 1
    Dernier message: 07/12/2005, 14h58
  2. Mise au point d'un bon algo
    Par cryptorchild dans le forum Langage
    Réponses: 3
    Dernier message: 08/10/2005, 17h04
  3. Petite mise au point avec gluUnProject.
    Par fatpat94 dans le forum OpenGL
    Réponses: 1
    Dernier message: 27/07/2005, 15h40
  4. [Mise au point] dhcp
    Par Ernest dans le forum Développement
    Réponses: 5
    Dernier message: 07/10/2004, 17h56
  5. Questions de mise aux points
    Par nicoo dans le forum DirectX
    Réponses: 5
    Dernier message: 11/05/2004, 14h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo