Enhance participant import functionality in MSIN-4482 by updating the import phases and adding new fields for emergency contact details. Implement commit action in AJAX handling for result mapping validation. Increment version code.

This commit is contained in:
2026-07-24 16:16:00 -04:00
parent 84e65340b6
commit 8929236e85
3 changed files with 512 additions and 8 deletions

View File

@ -42,11 +42,12 @@ Aussi utile plus tard le **jour J** sur une course **avec** inscription en ligne
## Phases (réalignées)
1. **UI import superadm** (en cours) — dropzone, mapping colonnes + épreuves, templates persistants
2. **Écriture `resultats_*`** — upsert clé unique + questions C (sans panier)
3. **ChronoTrack** — push avec `par_external_id`
4. **Saisie / édition** — fiche rapide (+ jour J)
5. **Hub minimisé** — seulement si/quand nécessaire
1. **UI import superadm** — dropzone, mapping colonnes + épreuves, templates, bouton **Importer**
2. **Écriture `resultats_*`** — upsert clé unique + questions C (sans panier) — en place
3. **Mapping pays** (valeurs fichier → `pay_id`) — **étape 2**
4. **ChronoTrack** — push avec `par_external_id`
5. **Saisie / édition** — fiche rapide (+ jour J)
6. **Hub minimisé** — seulement si/quand nécessaire
## UI import (décisions)

View File

@ -23,6 +23,8 @@ function fxImportResultatsTargetFields() {
array('key' => 'par_age', 'label' => 'Âge', 'group' => 'Identité'),
array('key' => 'par_courriel', 'label' => 'Courriel', 'group' => 'Contact'),
array('key' => 'par_telephone1', 'label' => 'Téléphone', 'group' => 'Contact'),
array('key' => 'par_contact_urgence_nom', 'label' => 'Contact urgence — nom', 'group' => 'Contact'),
array('key' => 'par_contact_urgence_telephone', 'label' => 'Contact urgence — téléphone', 'group' => 'Contact'),
array('key' => 'par_adresse', 'label' => 'Adresse', 'group' => 'Contact'),
array('key' => 'par_ville', 'label' => 'Ville', 'group' => 'Contact'),
array('key' => 'par_codepostal', 'label' => 'Code postal', 'group' => 'Contact'),
@ -83,6 +85,8 @@ function fxImportResultatsGuessField($strHeader) {
'par_age' => array('age', 'âge'),
'par_courriel' => array('courriel', 'e-mail', 'email', 'mail'),
'par_telephone1' => array('telephone', 'téléphone', 'phone', 'mobile', 'cell', 'tel'),
'par_contact_urgence_nom' => array('emergency contact name', 'contact urgence', 'nom en cas d\'urgence', 'urgence nom'),
'par_contact_urgence_telephone' => array('emergency contact number', 'emergency contact phone', 'numéro du contact en cas d\'urgence', 'urgence tel'),
'par_adresse' => array('adresse', 'address', 'street'),
'par_ville' => array('ville', 'city', 'town'),
'par_codepostal' => array('code postal', 'postal', 'zipcode', 'zip'),
@ -662,10 +666,451 @@ function fxImportResultatsValidateMapping($intEveId, $strToken, array $arrMappin
return array(
'state' => 'ok',
'message' => 'Mapping prêt — ' . count($arrParsed['rows']) . ' ligne(s). L\'écriture dans resultats_* arrive juste après cette interface.',
'message' => 'Mapping prêt — ' . count($arrParsed['rows']) . ' ligne(s). Vous pouvez importer.',
'warnings' => $tabWarn,
'row_count' => count($arrParsed['rows']),
'commit_ready' => false,
'commit_ready' => true,
);
}
function fxImportResultatsDbEsc($str) {
global $objDatabase;
if (isset($objDatabase) && is_object($objDatabase) && method_exists($objDatabase, 'fxEscape')) {
return $objDatabase->fxEscape((string)$str);
}
return addslashes((string)$str);
}
/** MSIN-4482 — Male/Female/Other → M/F/N (aligné CT). */
function fxImportResultatsNormalizeSex($str) {
$str = trim((string)$str);
$strLow = mb_strtolower($str, 'UTF-8');
if ($strLow === 'f' || $strLow === 'female' || $strLow === 'féminin' || $strLow === 'feminin' || $strLow === 'femme') {
return 'F';
}
if ($strLow === 'm' || $strLow === 'h' || $strLow === 'male' || $strLow === 'masculin' || $strLow === 'homme') {
return 'M';
}
if ($strLow === 'other' || $strLow === 'autre' || $strLow === 'n' || $strLow === 'x') {
return 'N';
}
if ($str === 'F' || $str === 'M' || $str === 'N' || $str === 'H') {
return ($str === 'H') ? 'M' : $str;
}
return '';
}
/** MSIN-4482 — parse dates type 5/24/94 → Y-m-d. */
function fxImportResultatsNormalizeBirthdate($str) {
$str = trim((string)$str);
if ($str === '' || $str === '0000-00-00') {
return '';
}
if (preg_match('/^(\d{4})-(\d{2})-(\d{2})/', $str, $m)) {
return $m[1] . '-' . $m[2] . '-' . $m[3];
}
// m/d/y ou m/d/yyyy
if (preg_match('/^(\d{1,2})[\/\-.](\d{1,2})[\/\-.](\d{2,4})$/', $str, $m)) {
$intM = intval($m[1]);
$intD = intval($m[2]);
$intY = intval($m[3]);
if ($intY < 100) {
$intY += ($intY >= 70) ? 1900 : 2000;
}
if (checkdate($intM, $intD, $intY)) {
return sprintf('%04d-%02d-%02d', $intY, $intM, $intD);
}
// essai j/m/a
if (checkdate($intD, $intM, $intY)) {
return sprintf('%04d-%02d-%02d', $intY, $intD, $intM);
}
}
$intTs = strtotime($str);
if ($intTs !== false) {
return date('Y-m-d', $intTs);
}
return '';
}
/**
* Résout que_id pour colonnes questions (match existant ou création confirmée).
* @return array<string,int> colIndex => que_id
*/
function fxImportResultatsResolveQuestionIds($intEveId, array $tabHeaders, array $tabQuestionsMap) {
global $objDatabase;
$intEveId = intval($intEveId);
$tabOut = array();
foreach ($tabQuestionsMap as $strCol => $strQue) {
$intCol = intval($strCol);
$strQue = trim((string)$strQue);
if ($strQue === '' || $strQue === '0') {
continue;
}
if ($strQue === 'new') {
$strLabel = trim((string)($tabHeaders[$intCol] ?? ('Question ' . ($intCol + 1))));
if (mb_strlen($strLabel, 'UTF-8') > 100) {
$strLabel = mb_substr($strLabel, 0, 97, 'UTF-8') . '...';
}
// Réutiliser si même libellé déjà créé sur l'événement
$sqlFind = "SELECT que_id FROM inscriptions_questions"
. " WHERE eve_id = " . $intEveId
. " AND que_question_fr = '" . fxImportResultatsDbEsc($strLabel) . "'"
. " LIMIT 1";
$tabFind = $objDatabase->fxGetResults($sqlFind);
if (is_array($tabFind) && !empty($tabFind[1]['que_id'])) {
$tabOut[(string)$intCol] = intval($tabFind[1]['que_id']);
continue;
}
$sqlIns = "INSERT INTO inscriptions_questions SET"
. " eve_id = " . $intEveId . ","
. " que_question_fr = '" . fxImportResultatsDbEsc($strLabel) . "',"
. " que_question_en = '" . fxImportResultatsDbEsc($strLabel) . "',"
. " que_choix_fr = '',"
. " que_choix_en = '',"
. " que_liste = 0,"
. " que_epreuves_incluses = '',"
. " que_required = 0,"
. " que_tri = 900,"
. " que_participant_1 = 1,"
. " que_modifiable = 1,"
. " que_actif = 1,"
. " que_hidden = 0";
if ($objDatabase->fxQuery($sqlIns) === false) {
continue;
}
$tabOut[(string)$intCol] = intval($objDatabase->fxGetLastId());
continue;
}
$intQueId = intval($strQue);
if ($intQueId > 0) {
$tabOut[(string)$intCol] = $intQueId;
}
}
return $tabOut;
}
function fxImportResultatsSaveQuestionAnswer($intParIdOriginal, $intPecId, $intQueId, $strHeader, $strValue) {
global $objDatabase;
$intParIdOriginal = intval($intParIdOriginal);
$intPecId = intval($intPecId);
$intQueId = intval($intQueId);
$strValue = trim((string)$strValue);
$strHeader = trim((string)$strHeader);
if ($intQueId <= 0 || $intPecId <= 0) {
return;
}
$strNow = function_exists('fxGetDateTime') ? fxGetDateTime() : date('Y-m-d H:i:s');
$sqlFind = "SELECT pqu_id FROM resultats_questions"
. " WHERE pec_id = " . $intPecId
. " AND que_id = " . $intQueId
. " AND par_id = " . $intParIdOriginal
. " LIMIT 1";
$tabFind = $objDatabase->fxGetResults($sqlFind);
if (is_array($tabFind) && !empty($tabFind[1]['pqu_id'])) {
$sql = "UPDATE resultats_questions SET"
. " que_choix_fr = '" . fxImportResultatsDbEsc($strValue) . "',"
. " que_choix_en = '" . fxImportResultatsDbEsc($strValue) . "',"
. " pqu_maj = '" . fxImportResultatsDbEsc($strNow) . "'"
. " WHERE pqu_id = " . intval($tabFind[1]['pqu_id']);
$objDatabase->fxQuery($sql);
return;
}
$sql = "INSERT INTO resultats_questions SET"
. " par_id = " . $intParIdOriginal . ","
. " pec_id = " . $intPecId . ","
. " que_id = " . $intQueId . ","
. " que_question_fr = '" . fxImportResultatsDbEsc($strHeader) . "',"
. " que_question_en = '" . fxImportResultatsDbEsc($strHeader) . "',"
. " que_choix_fr = '" . fxImportResultatsDbEsc($strValue) . "',"
. " que_choix_en = '" . fxImportResultatsDbEsc($strValue) . "',"
. " que_modifiable = 1,"
. " pqu_note = '',"
. " pqu_maj = '" . fxImportResultatsDbEsc($strNow) . "',"
. " no_panier = '',"
. " no_commande = '',"
. " pqu_id_original = 0";
$objDatabase->fxQuery($sql);
}
/**
* MSIN-4482 — écriture resultats_* (sans panier), upsert sur par_external_id.
*/
function fxImportResultatsCommit($intEveId, $strToken, array $arrMapping) {
global $objDatabase;
@set_time_limit(300);
$arrVal = fxImportResultatsValidateMapping($intEveId, $strToken, $arrMapping);
if (($arrVal['state'] ?? '') !== 'ok') {
return $arrVal;
}
$intEveId = intval($intEveId);
$strPath = fxImportResultatsResolveTokenPath($intEveId, $strToken);
$arrParsed = fxImportResultatsParseFile($strPath);
if (($arrParsed['state'] ?? '') !== 'ok') {
return $arrParsed;
}
// Colonnes requises pour l'import
$sqlCol = "SELECT COUNT(*) AS n FROM information_schema.COLUMNS"
. " WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'resultats_participants'"
. " AND COLUMN_NAME = 'par_external_id'";
$tabCol = $objDatabase->fxGetResults($sqlCol);
if (!is_array($tabCol) || intval($tabCol[1]['n'] ?? 0) < 1) {
return array(
'state' => 'error',
'message' => 'Colonnes import absentes — exécuter sql/MSIN-4482-import-resultats-templates.sql en dev préprod.',
);
}
$tabHeaders = $arrParsed['headers'];
$tabRows = $arrParsed['rows'];
$tabColumns = isset($arrMapping['columns']) && is_array($arrMapping['columns']) ? $arrMapping['columns'] : array();
$tabEprValues = isset($arrMapping['epr_values']) && is_array($arrMapping['epr_values']) ? $arrMapping['epr_values'] : array();
$tabQuestionsMap = isset($arrMapping['questions']) && is_array($arrMapping['questions']) ? $arrMapping['questions'] : array();
$tabColIndex = array();
foreach ($tabColumns as $intIdx => $strKey) {
$strKey = (string)$strKey;
if ($strKey === '') {
continue;
}
$tabColIndex[$strKey] = intval($intIdx);
}
$tabQueIds = fxImportResultatsResolveQuestionIds($intEveId, $tabHeaders, $tabQuestionsMap);
$strNow = function_exists('fxGetDateTime') ? fxGetDateTime() : date('Y-m-d H:i:s');
$strOrigine = MSIN_IMPORT_RESULTATS_ORIGIN;
$intCreated = 0;
$intUpdated = 0;
$intSkipped = 0;
$tabRowErrors = array();
foreach ($tabRows as $intRowNum => $tabRow) {
$strExt = '';
if (isset($tabColIndex['par_external_id'])) {
$strExt = trim((string)($tabRow[$tabColIndex['par_external_id']] ?? ''));
}
if ($strExt === '') {
$intSkipped++;
if (count($tabRowErrors) < 15) {
$tabRowErrors[] = 'Ligne ' . ($intRowNum + 2) . ' : clé unique vide';
}
continue;
}
$strEprRaw = '';
if (isset($tabColIndex['epr'])) {
$strEprRaw = trim((string)($tabRow[$tabColIndex['epr']] ?? ''));
}
$intEprId = intval($tabEprValues[$strEprRaw] ?? 0);
if ($intEprId <= 0) {
$intSkipped++;
if (count($tabRowErrors) < 15) {
$tabRowErrors[] = 'Ligne ' . ($intRowNum + 2) . ' : épreuve non mappée (« ' . $strEprRaw . ' »)';
}
continue;
}
$arrFields = array(
'par_prenom' => '',
'par_nom' => '',
'par_sexe' => '',
'par_naissance' => '',
'par_age' => 0,
'par_courriel' => '',
'par_telephone1' => '',
'par_adresse' => '',
'par_ville' => '',
'par_codepostal' => '',
'no_bib' => '',
'par_nom_equipe' => '',
'par_no_equipe' => 0,
'par_contact_urgence_nom' => '',
'par_contact_urgence_telephone' => '',
);
foreach ($arrFields as $strKey => $mixDefault) {
if (!isset($tabColIndex[$strKey])) {
continue;
}
$strRaw = trim((string)($tabRow[$tabColIndex[$strKey]] ?? ''));
if ($strKey === 'par_sexe') {
$arrFields[$strKey] = fxImportResultatsNormalizeSex($strRaw);
} elseif ($strKey === 'par_naissance') {
$arrFields[$strKey] = fxImportResultatsNormalizeBirthdate($strRaw);
} elseif ($strKey === 'par_age' || $strKey === 'par_no_equipe') {
$arrFields[$strKey] = intval($strRaw);
} else {
$arrFields[$strKey] = $strRaw;
}
}
if (intval($arrFields['par_age']) <= 0 && $arrFields['par_naissance'] !== '') {
$intTs = strtotime($arrFields['par_naissance']);
if ($intTs !== false) {
$arrFields['par_age'] = intval(floor((time() - $intTs) / 31557600));
}
}
// Upsert participant import
$sqlExist = "SELECT par_id, pec_id, par_id_original FROM resultats_participants"
. " WHERE eve_id = " . $intEveId
. " AND par_external_id = '" . fxImportResultatsDbEsc($strExt) . "'"
. " LIMIT 1";
$tabExist = $objDatabase->fxGetResults($sqlExist);
$blnUpdate = (is_array($tabExist) && !empty($tabExist[1]['par_id']));
if ($blnUpdate) {
$intParId = intval($tabExist[1]['par_id']);
$intPecId = intval($tabExist[1]['pec_id']);
$intParOrig = intval($tabExist[1]['par_id_original']);
if ($intParOrig <= 0) {
$intParOrig = $intParId;
}
if ($intPecId > 0) {
$sqlPec = "UPDATE resultats_epreuves_commandees SET"
. " epr_id = " . $intEprId . ","
. " pec_maj = '" . fxImportResultatsDbEsc($strNow) . "'"
. " WHERE pec_id = " . $intPecId;
$objDatabase->fxQuery($sqlPec);
}
$sqlUp = "UPDATE resultats_participants SET"
. " epr_id = " . $intEprId . ","
. " par_prenom = '" . fxImportResultatsDbEsc($arrFields['par_prenom']) . "',"
. " par_nom = '" . fxImportResultatsDbEsc($arrFields['par_nom']) . "',"
. " par_sexe = '" . fxImportResultatsDbEsc($arrFields['par_sexe']) . "',"
. " par_naissance = " . ($arrFields['par_naissance'] !== '' ? ("'" . fxImportResultatsDbEsc($arrFields['par_naissance']) . "'") : "NULL") . ","
. " par_age = " . intval($arrFields['par_age']) . ","
. " par_courriel = '" . fxImportResultatsDbEsc($arrFields['par_courriel']) . "',"
. " par_telephone1 = '" . fxImportResultatsDbEsc($arrFields['par_telephone1']) . "',"
. " par_adresse = '" . fxImportResultatsDbEsc($arrFields['par_adresse']) . "',"
. " par_ville = '" . fxImportResultatsDbEsc($arrFields['par_ville']) . "',"
. " par_codepostal = '" . fxImportResultatsDbEsc($arrFields['par_codepostal']) . "',"
. " no_bib = '" . fxImportResultatsDbEsc($arrFields['no_bib']) . "',"
. " par_nom_equipe = '" . fxImportResultatsDbEsc($arrFields['par_nom_equipe']) . "',"
. " par_no_equipe = " . intval($arrFields['par_no_equipe']) . ","
. " par_origine = '" . fxImportResultatsDbEsc($strOrigine) . "',"
. " par_maj = '" . fxImportResultatsDbEsc($strNow) . "'"
. " WHERE par_id = " . $intParId;
if ($objDatabase->fxQuery($sqlUp) === false) {
$intSkipped++;
if (count($tabRowErrors) < 15) {
$tabRowErrors[] = 'Ligne ' . ($intRowNum + 2) . ' : échec UPDATE';
}
continue;
}
// urgence si colonnes présentes (ignorer erreur silencieuse)
$sqlUrg = "UPDATE resultats_participants SET"
. " par_contact_urgence_nom = '" . fxImportResultatsDbEsc($arrFields['par_contact_urgence_nom']) . "',"
. " par_contact_urgence_telephone = '" . fxImportResultatsDbEsc($arrFields['par_contact_urgence_telephone']) . "'"
. " WHERE par_id = " . $intParId;
@$objDatabase->fxQuery($sqlUrg);
$intUpdated++;
} else {
$sqlPec = "INSERT INTO resultats_epreuves_commandees SET"
. " eve_id = " . $intEveId . ","
. " epr_id = " . $intEprId . ","
. " no_panier = '',"
. " pec_label = '',"
. " pec_nom_equipe = '" . fxImportResultatsDbEsc($arrFields['par_nom_equipe']) . "',"
. " pec_equipe = 0,"
. " com_id = 0,"
. " pec_maj = '" . fxImportResultatsDbEsc($strNow) . "',"
. " pec_id_original = 0,"
. " no_commande = '',"
. " is_cancelled = 0";
if ($objDatabase->fxQuery($sqlPec) === false) {
$intSkipped++;
if (count($tabRowErrors) < 15) {
$tabRowErrors[] = 'Ligne ' . ($intRowNum + 2) . ' : échec INSERT pec';
}
continue;
}
$intPecId = intval($objDatabase->fxGetLastId());
$objDatabase->fxQuery(
"UPDATE resultats_epreuves_commandees SET pec_id_original = " . $intPecId
. " WHERE pec_id = " . $intPecId
);
$sqlPar = "INSERT INTO resultats_participants SET"
. " eve_id = " . $intEveId . ","
. " epr_id = " . $intEprId . ","
. " par_prenom = '" . fxImportResultatsDbEsc($arrFields['par_prenom']) . "',"
. " par_nom = '" . fxImportResultatsDbEsc($arrFields['par_nom']) . "',"
. " par_naissance = " . ($arrFields['par_naissance'] !== '' ? ("'" . fxImportResultatsDbEsc($arrFields['par_naissance']) . "'") : "NULL") . ","
. " par_age = " . intval($arrFields['par_age']) . ","
. " par_sexe = '" . fxImportResultatsDbEsc($arrFields['par_sexe']) . "',"
. " par_adresse = '" . fxImportResultatsDbEsc($arrFields['par_adresse']) . "',"
. " par_ville = '" . fxImportResultatsDbEsc($arrFields['par_ville']) . "',"
. " pro_id = 0,"
. " par_codepostal = '" . fxImportResultatsDbEsc($arrFields['par_codepostal']) . "',"
. " pay_id = 0,"
. " par_telephone1 = '" . fxImportResultatsDbEsc($arrFields['par_telephone1']) . "',"
. " par_courriel = '" . fxImportResultatsDbEsc($arrFields['par_courriel']) . "',"
. " com_id = 0,"
. " par_nom_equipe = '" . fxImportResultatsDbEsc($arrFields['par_nom_equipe']) . "',"
. " no_panier = '',"
. " par_maj = '" . fxImportResultatsDbEsc($strNow) . "',"
. " no_commande = '',"
. " par_id_original = 0,"
. " is_cancelled = 0,"
. " par_no_equipe = " . intval($arrFields['par_no_equipe']) . ","
. " par_equipe = 0,"
. " pec_id = " . $intPecId . ","
. " rol_id = 2,"
. " no_bib = '" . fxImportResultatsDbEsc($arrFields['no_bib']) . "',"
. " par_external_id = '" . fxImportResultatsDbEsc($strExt) . "',"
. " par_origine = '" . fxImportResultatsDbEsc($strOrigine) . "'";
if ($objDatabase->fxQuery($sqlPar) === false) {
$intSkipped++;
if (count($tabRowErrors) < 15) {
$tabRowErrors[] = 'Ligne ' . ($intRowNum + 2) . ' : échec INSERT participant';
}
continue;
}
$intParId = intval($objDatabase->fxGetLastId());
$intParOrig = $intParId;
$objDatabase->fxQuery(
"UPDATE resultats_participants SET par_id_original = " . $intParId
. " WHERE par_id = " . $intParId
);
$sqlUrg = "UPDATE resultats_participants SET"
. " par_contact_urgence_nom = '" . fxImportResultatsDbEsc($arrFields['par_contact_urgence_nom']) . "',"
. " par_contact_urgence_telephone = '" . fxImportResultatsDbEsc($arrFields['par_contact_urgence_telephone']) . "'"
. " WHERE par_id = " . $intParId;
@$objDatabase->fxQuery($sqlUrg);
$intCreated++;
}
foreach ($tabQueIds as $strCol => $intQueId) {
$intCol = intval($strCol);
$strVal = trim((string)($tabRow[$intCol] ?? ''));
$strH = (string)($tabHeaders[$intCol] ?? '');
fxImportResultatsSaveQuestionAnswer($intParOrig, $intPecId, $intQueId, $strH, $strVal);
}
}
$strMsg = 'Import terminé : ' . $intCreated . ' créé(s), ' . $intUpdated . ' mis à jour, '
. $intSkipped . ' ignoré(s) sur ' . count($tabRows) . ' ligne(s).';
if (count($tabRowErrors) > 0) {
$strMsg .= ' Exemples : ' . implode(' · ', $tabRowErrors);
}
return array(
'state' => 'ok',
'message' => $strMsg,
'created' => $intCreated,
'updated' => $intUpdated,
'skipped' => $intSkipped,
'row_count' => count($tabRows),
'errors_sample' => $tabRowErrors,
);
}
@ -779,9 +1224,12 @@ function fxImportResultatsRenderEventPanel($intEveId) {
<button type="button" class="btn btn-outline-primary btn-sm mb-2 mr-2" id="ms1_import_save_tpl">
<i class="fa fa-save" aria-hidden="true"></i> Enregistrer le template
</button>
<button type="button" class="btn btn-primary btn-sm mb-2" id="ms1_import_validate">
<button type="button" class="btn btn-outline-secondary btn-sm mb-2 mr-2" id="ms1_import_validate">
<i class="fa fa-check" aria-hidden="true"></i> Valider le mapping
</button>
<button type="button" class="btn btn-success btn-sm mb-2" id="ms1_import_commit">
<i class="fa fa-play" aria-hidden="true"></i> Importer dans MS1
</button>
</div>
</div>
</div>
@ -1132,6 +1580,44 @@ function fxImportResultatsRenderEventPanel($intEveId) {
showStatus('danger', 'Erreur réseau (validation).');
});
});
$('#ms1_import_commit').on('click', function () {
if (!state || !state.token) return;
var mapping = collectMapping();
if (!window.confirm('Importer / mettre à jour les participants dans resultats_* pour cet événement ?\n(Sans panier ni paiement — upsert sur la clé unique.)')) {
return;
}
var $btn = $(this);
$btn.prop('disabled', true);
showStatus('info', 'Import en cours — cela peut prendre une minute pour un gros fichier…');
$.ajax({
url: ajaxUrl,
method: 'POST',
dataType: 'text',
data: {
a: 'commit',
eve_id: eveId,
token: state.token,
mapping: JSON.stringify(mapping)
}
}).done(function (raw) {
$btn.prop('disabled', false);
var res = parseAjaxJson(raw);
if (!res || res.state !== 'ok') {
showStatus('danger', (res && res.message) ? res.message : 'Échec import');
return;
}
showStatus('success', res.message || 'Import terminé.');
}).fail(function (xhr) {
$btn.prop('disabled', false);
var res = parseAjaxJson(xhr && xhr.responseText);
if (res && res.state === 'ok') {
showStatus('success', res.message || 'Import terminé.');
return;
}
showStatus('danger', 'Erreur réseau (import). Timeout possible sur très gros fichiers — réessayez ou coupez le fichier.');
});
});
})(window.jQuery);
</script>
<?php

View File

@ -67,6 +67,23 @@ switch ($strAction) {
$tabRetour = fxImportResultatsValidateMapping($intEveId, $strToken, $arrMapping);
break;
case 'commit':
if ($intEveId <= 0) {
$tabRetour = array('state' => 'error', 'message' => 'eve_id manquant');
break;
}
$strToken = trim((string)($_REQUEST['token'] ?? ''));
$arrMapping = $_REQUEST['mapping'] ?? array();
if (is_string($arrMapping)) {
$arrDecoded = json_decode($arrMapping, true);
$arrMapping = is_array($arrDecoded) ? $arrDecoded : array();
}
if (!is_array($arrMapping)) {
$arrMapping = array();
}
$tabRetour = fxImportResultatsCommit($intEveId, $strToken, $arrMapping);
break;
default:
$tabRetour = array('state' => 'error', 'message' => 'action_invalide');
break;