diff --git a/ajax_bib_range.php b/ajax_bib_range.php index 97f1408..af204f6 100644 --- a/ajax_bib_range.php +++ b/ajax_bib_range.php @@ -433,11 +433,11 @@ if ($action == 'global_batch_panel') { if ($action == 'batch_global_analysis') { $int_eve_id = (int)($_POST['eve_id'] ?? 0); - $ba_id = (int)($_POST['ba_id'] ?? 0); + list($strSort1, $strSort2) = fxBibParseBatchSortFromPost(); $plans = json_decode($_POST['plans'] ?? '[]', true); $tabPlans = fxBibParseGlobalBatchPlans($plans, $int_eve_id); - if ($int_eve_id <= 0 || $ba_id <= 0 || empty($tabPlans)) { + if ($int_eve_id <= 0 || $strSort1 === '' || empty($tabPlans)) { echo json_encode([ 'success' => false, 'message' => fxBibMsg('bib_v4_global_batch_plan_invalid'), @@ -454,7 +454,7 @@ if ($action == 'batch_global_analysis') { $epr_id = (int)$plan['epr_id']; $ranges = $plan['ranges']; - $participants = fxGetParticipantsForBatchAssign($epr_id, $ba_id); + $participants = fxGetParticipantsForBatchAssign($epr_id, $strSort1, $strSort2); $tabRangesInfos = fxInfosBibRange($epr_id); $ids = array_map('intval', $ranges); $tabRangesInfos = array_filter($tabRangesInfos, function ($r) use ($ids) { @@ -495,11 +495,11 @@ if ($action == 'batch_global_analysis') { if ($action == 'batch_global_simulate') { $int_eve_id = (int)($_POST['eve_id'] ?? 0); - $ba_id = (int)($_POST['ba_id'] ?? 0); + list($strSort1, $strSort2) = fxBibParseBatchSortFromPost(); $plans = json_decode($_POST['plans'] ?? '[]', true); $tabPlans = fxBibParseGlobalBatchPlans($plans, $int_eve_id); - if ($int_eve_id <= 0 || $ba_id <= 0 || empty($tabPlans)) { + if ($int_eve_id <= 0 || $strSort1 === '' || empty($tabPlans)) { echo json_encode([ 'success' => false, 'message' => fxBibMsg('bib_v4_global_batch_plan_invalid'), @@ -517,7 +517,7 @@ if ($action == 'batch_global_simulate') { $epr_id = (int)$plan['epr_id']; $ranges = $plan['ranges']; - $participants = fxGetParticipantsForBatchAssign($epr_id, $ba_id); + $participants = fxGetParticipantsForBatchAssign($epr_id, $strSort1, $strSort2); $tabRanges = fxGetRangesForBatchAssign($epr_id, $ranges); $simu = fxProcessBatchAssignments($epr_id, $participants, $tabRanges, 'simulation'); @@ -658,15 +658,10 @@ if ($action == 'batch_go') { exit; } - // Ordre choisi (table bib_assignements) - $ba_id = intval($_POST['ba_id'] ?? 0); + list($strSort1, $strSort2) = fxBibParseBatchSortFromPost(); + fxBibSaveEpreuveBatchSort($epr_id, $strSort1, $strSort2); - // DEBUG : on retourne tout pour validation - // ===================== -// TEST fxGetParticipantsForBatchAssign -// ===================== - - $participants = fxGetParticipantsForBatchAssign($epr_id, $ba_id); + $participants = fxGetParticipantsForBatchAssign($epr_id, $strSort1, $strSort2); // ===================== // UTILISER LA FONCTION PROPRE // ===================== @@ -727,7 +722,7 @@ if ($action == 'batch_apply') { $epr_id = intval($_POST['epr_id'] ?? 0); $ranges = json_decode($_POST['ranges'] ?? '[]', true); - $ba_id = intval($_POST['ba_id'] ?? 0); + list($strSort1, $strSort2) = fxBibParseBatchSortFromPost(); $lockCheck = fxBibAssertRangesUnlocked($epr_id, is_array($ranges) ? $ranges : []); if (!$lockCheck['success']) { @@ -738,7 +733,9 @@ if ($action == 'batch_apply') { exit; } - $participants = fxGetParticipantsForBatchAssign($epr_id, $ba_id); + fxBibSaveEpreuveBatchSort($epr_id, $strSort1, $strSort2); + + $participants = fxGetParticipantsForBatchAssign($epr_id, $strSort1, $strSort2); $tabRanges = fxGetRangesForBatchAssign($epr_id, $ranges); $exec = fxProcessBatchAssignments($epr_id, $participants, $tabRanges, 'execute'); @@ -758,7 +755,7 @@ if ($action == 'batch_apply_chunk') { $epr_id = intval($_POST['epr_id'] ?? 0); $ranges = json_decode($_POST['ranges'] ?? '[]', true); - $ba_id = intval($_POST['ba_id'] ?? 0); + list($strSort1, $strSort2) = fxBibParseBatchSortFromPost(); $intChunkSize = (int)($_POST['chunk_size'] ?? 50); $intTotalInitial = (int)($_POST['total_initial'] ?? 0); $blnBatchReset = ((int)($_POST['batch_reset'] ?? 0) === 1); @@ -783,11 +780,12 @@ if ($action == 'batch_apply_chunk') { if ($blnBatchReset) { $_SESSION[$strSessionKey] = []; + fxBibSaveEpreuveBatchSort($epr_id, $strSort1, $strSort2); } elseif (!isset($_SESSION[$strSessionKey]) || !is_array($_SESSION[$strSessionKey])) { $_SESSION[$strSessionKey] = []; } - $participants = fxGetParticipantsForBatchAssign($epr_id, $ba_id); + $participants = fxGetParticipantsForBatchAssign($epr_id, $strSort1, $strSort2); if ($intTotalInitial <= 0) { $intTotalInitial = count($participants) + count($_SESSION[$strSessionKey]); @@ -817,7 +815,7 @@ if ($action == 'batch_apply_chunk') { $_SESSION[$strSessionKey] = array_merge($_SESSION[$strSessionKey], $execChunk); - $intRemaining = count(fxGetParticipantsForBatchAssign($epr_id, $ba_id)); + $intRemaining = count(fxGetParticipantsForBatchAssign($epr_id, $strSort1, $strSort2)); $intProcessed = max(0, $intTotalInitial - $intRemaining); $blnComplete = ($intRemaining === 0); diff --git a/js/v2/bib-assignments.js b/js/v2/bib-assignments.js index e398b1e..f39b979 100644 --- a/js/v2/bib-assignments.js +++ b/js/v2/bib-assignments.js @@ -201,13 +201,45 @@ }); } - function bibFetchBatchApplyChunk(row, selected, ba_id, opts) { + function bibGetRowSortKeys(row) { + if (!row) { + return { sort1: '', sort2: '' }; + } + var s1 = row.querySelector('.batch-order'); + var s2 = row.querySelector('.batch-order-2'); + return { + sort1: s1 ? s1.value : '', + sort2: s2 ? s2.value : '' + }; + } + + function bibGetGlobalBatchSortKeys(panel) { + if (!panel) { + return { sort1: '', sort2: '' }; + } + var s1 = panel.querySelector('.bib-global-batch-order'); + var s2 = panel.querySelector('.bib-global-batch-order-2'); + return { + sort1: s1 ? s1.value : '', + sort2: s2 ? s2.value : '' + }; + } + + function bibAppendBatchSortParams(body, sortKeys) { + sortKeys = sortKeys || {}; + return body + + '&sort_1=' + encodeURIComponent(sortKeys.sort1 || '') + + '&sort_2=' + encodeURIComponent(sortKeys.sort2 || ''); + } + + function bibFetchBatchApplyChunk(row, selected, sortKeys, opts) { opts = opts || {}; + sortKeys = sortKeys || bibGetRowSortKeys(row); var body = 'action=batch_apply_chunk' + '&epr_id=' + encodeURIComponent(row.dataset.eprId) + '&ranges=' + encodeURIComponent(JSON.stringify(selected)) - + '&ba_id=' + encodeURIComponent(ba_id) + + bibAppendBatchSortParams('', sortKeys) + '&chunk_size=' + BIB_BATCH_CHUNK_SIZE + '&total_initial=' + (opts.totalInitial || 0) + '&batch_reset=' + (opts.batchReset ? 1 : 0) @@ -232,7 +264,7 @@ }); } - function bibRunBatchApplyChunks(row, selected, ba_id, options) { + function bibRunBatchApplyChunks(row, selected, sortKeys, options) { options = options || {}; var showResult = options.showResult !== false; var manageLoader = options.manageLoader !== false; @@ -255,7 +287,7 @@ return Promise.reject(new Error(bibJs('jsErrGeneric'))); } - return bibFetchBatchApplyChunk(row, selected, ba_id, { + return bibFetchBatchApplyChunk(row, selected, sortKeys, { batchReset: batchReset, totalInitial: totalInitial }).then(function (data) { @@ -438,9 +470,9 @@ var plans = bibCollectGlobalBatchPlans(); var infoEl = bibGlobalBatchPanel.querySelector('.bib-global-batch__info'); - var baSelect = bibGlobalBatchPanel.querySelector('.bib-global-batch-order'); + var sortKeys = bibGetGlobalBatchSortKeys(bibGlobalBatchPanel); - if (!infoEl || !baSelect) { + if (!infoEl) { return Promise.resolve(); } @@ -471,7 +503,7 @@ body: 'action=batch_global_analysis' + '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '') - + '&ba_id=' + encodeURIComponent(baSelect.value) + + bibAppendBatchSortParams('', sortKeys) + '&plans=' + encodeURIComponent(JSON.stringify(plans)) + bibAjaxLangSuffix() }) @@ -503,7 +535,7 @@ } var plans = bibCollectGlobalBatchPlans(); - var baSelect = bibGlobalBatchPanel.querySelector('.bib-global-batch-order'); + var sortKeys = bibGetGlobalBatchSortKeys(bibGlobalBatchPanel); if (plans.length === 0) { alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone')); @@ -515,15 +547,13 @@ return; } - var ba_id = baSelect ? baSelect.value : ''; - fetch('/ajax_bib_range.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=batch_global_analysis' + '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '') - + '&ba_id=' + encodeURIComponent(ba_id) + + bibAppendBatchSortParams('', sortKeys) + '&plans=' + encodeURIComponent(JSON.stringify(plans)) + bibAjaxLangSuffix() }) @@ -558,7 +588,7 @@ var pendingBefore = bibRowPendingBibs(row); var offset = completedOffset; - return bibRunBatchApplyChunks(row, plan.ranges, ba_id, { + return bibRunBatchApplyChunks(row, plan.ranges, sortKeys, { showResult: false, manageLoader: false, deferUiRefresh: true, @@ -680,9 +710,9 @@ e.preventDefault(); var bibGlobalBatchPanel = bibGetGlobalBatchPanel(); var plans = bibCollectGlobalBatchPlans(); - var baSelect = bibGlobalBatchPanel - ? bibGlobalBatchPanel.querySelector('.bib-global-batch-order') - : null; + var sortKeys = bibGlobalBatchPanel + ? bibGetGlobalBatchSortKeys(bibGlobalBatchPanel) + : { sort1: '', sort2: '' }; if (plans.length === 0) { alert(bibJs('jsGlobalNoEpr') || bibJs('jsBatchNone')); @@ -695,7 +725,7 @@ body: 'action=batch_global_simulate' + '&eve_id=' + encodeURIComponent(moduleBib.dataset.eveId || '') - + '&ba_id=' + encodeURIComponent(baSelect ? baSelect.value : '') + + bibAppendBatchSortParams('', sortKeys) + '&plans=' + encodeURIComponent(JSON.stringify(plans)) + bibAjaxLangSuffix() }) @@ -727,7 +757,7 @@ }); moduleBib.addEventListener('change', function (e) { - if (!e.target.matches('.bib-global-epr-select, .bib-global-range-select, .bib-global-batch-order')) { + if (!e.target.matches('.bib-global-epr-select, .bib-global-range-select, .bib-global-batch-order, .bib-global-batch-order-2')) { return; } @@ -1694,6 +1724,7 @@ bibSetVisible('.epr-auto-info-group', showAutoReady, row); bibSetVisible('.batch-reset-warning', showBatchReady && modes.reset, row); bibSetVisible('.epr-batch-order-wrap', showBatchReady && !modes.reset, row); + bibSetVisible('.epr-batch-order-wrap--secondary', showBatchReady && !modes.reset, row); bibSetVisible('.epr-action-sim-group', showBatchReady && !modes.reset, row); bibSetVisible('.epr-action-go-group', showBatchReady, row); bibSyncResetAllEprButton(row); @@ -2399,7 +2430,7 @@ return; } let isResetMode = row.dataset.mode === 'reset'; - let ba_id = row.querySelector('.batch-order').value; + let sortKeys = bibGetRowSortKeys(row); bibFetch('/ajax_bib_range.php', { method: 'POST', @@ -2410,7 +2441,7 @@ (isResetMode ? 'action=reset_preview' : 'action=batch_go') + '&epr_id=' + encodeURIComponent(row.dataset.eprId) + '&ranges=' + encodeURIComponent(JSON.stringify(selected)) - + '&ba_id=' + encodeURIComponent(ba_id) + + bibAppendBatchSortParams('', sortKeys) + bibAjaxLangSuffix() }) .then(res => res.json()) @@ -2559,7 +2590,7 @@ return; } let isResetMode = row.dataset.mode === 'reset'; - let ba_id = row.querySelector('.batch-order').value; + let sortKeys = bibGetRowSortKeys(row); if (isResetMode) { bibFetch('/ajax_bib_range.php', { @@ -2571,7 +2602,7 @@ 'action=reset_apply' + '&epr_id=' + encodeURIComponent(row.dataset.eprId) + '&ranges=' + encodeURIComponent(JSON.stringify(selected)) - + '&ba_id=' + encodeURIComponent(ba_id) + + bibAppendBatchSortParams('', sortKeys) + bibAjaxLangSuffix() }) .then(res => res.json()) @@ -2588,7 +2619,7 @@ return; } - bibRunBatchApplyChunks(row, selected, ba_id); + bibRunBatchApplyChunks(row, selected, sortKeys); return; } diff --git a/php/inc_fx_promoteur.php b/php/inc_fx_promoteur.php index 5807ac5..d436728 100644 --- a/php/inc_fx_promoteur.php +++ b/php/inc_fx_promoteur.php @@ -2640,8 +2640,339 @@ function renderBibBatchPickPrompt() { return ob_get_clean(); } +// v2 — options d'ordre batch (table bib_assignements + questions par épreuve) + +/** MSIN-4436 — Normalise une clé de tri (ba:5, que:123 ou legacy entier). */ +function fxBibNormalizeSortKey($mix) { + if ($mix === null || $mix === '' || $mix === '0' || $mix === 0) { + return ''; + } + + if (is_numeric($mix) && (int)$mix > 0) { + return 'ba:' . (int)$mix; + } + + $str = trim((string)$mix); + if (preg_match('/^(ba|que):\d+$/', $str)) { + return $str; + } + + return ''; +} + +/** MSIN-4436 — Clé de tri depuis ba_id legacy. */ +function fxBibSortKeyFromBaId($int_ba_id) { + $int_ba_id = (int)$int_ba_id; + return $int_ba_id > 0 ? 'ba:' . $int_ba_id : ''; +} + +/** MSIN-4436 — Tris mémorisés sur l'épreuve (repli sur ba_id). */ +function fxBibGetEpreuveDefaultSortKeys(array $tabEpreuve) { + $strSort1 = fxBibNormalizeSortKey($tabEpreuve['ba_bib_sort_1'] ?? ''); + $strSort2 = fxBibNormalizeSortKey($tabEpreuve['ba_bib_sort_2'] ?? ''); + + if ($strSort1 === '') { + $strSort1 = fxBibSortKeyFromBaId((int)($tabEpreuve['ba_id'] ?? 0)); + } + if ($strSort1 === '') { + $strSort1 = 'ba:2'; + } + + return [$strSort1, $strSort2]; +} + +/** MSIN-4436 — Persiste le tri batch sur l'épreuve (+ ba_id si tri fixe). */ +function fxBibSaveEpreuveBatchSort($epr_id, $sort1, $sort2 = '') { + global $objDatabase; + + $epr_id = (int)$epr_id; + $strSort1 = fxBibNormalizeSortKey($sort1); + $strSort2 = fxBibNormalizeSortKey($sort2); + + if ($epr_id <= 0 || $strSort1 === '') { + return false; + } + + if ($strSort1 === $strSort2) { + $strSort2 = ''; + } + + $intBaId = 0; + if (preg_match('/^ba:(\d+)$/', $strSort1, $m)) { + $intBaId = (int)$m[1]; + } + + $sql = " + UPDATE inscriptions_epreuves + SET ba_bib_sort_1 = '" . $objDatabase->fxEscape($strSort1) . "', + ba_bib_sort_2 = '" . $objDatabase->fxEscape($strSort2) . "' + " . ($intBaId > 0 ? ", ba_id = $intBaId" : '') . " + WHERE epr_id = $epr_id + LIMIT 1 + "; + + return (bool)$objDatabase->fxQuery($sql); +} + +/** MSIN-4436 — Lit sort_1 / sort_2 depuis POST (repli ba_id). */ +function fxBibParseBatchSortFromPost() { + $strSort1 = fxBibNormalizeSortKey($_POST['sort_1'] ?? ''); + $strSort2 = fxBibNormalizeSortKey($_POST['sort_2'] ?? ''); + + if ($strSort1 === '') { + $strSort1 = fxBibNormalizeSortKey($_POST['ba_id'] ?? ''); + } + + if ($strSort1 === '') { + $strSort1 = 'ba:2'; + } + + if ($strSort1 === $strSort2) { + $strSort2 = ''; + } + + return [$strSort1, $strSort2]; +} + +/** MSIN-4436 — Questions éligibles au tri pour une épreuve. */ +function fxBibGetQuestionSortOptions($epr_id, $eve_id, $strLangue = 'fr') { + global $objDatabase; + + $epr_id = (int)$epr_id; + $eve_id = (int)$eve_id; + if ($epr_id <= 0 || $eve_id <= 0) { + return []; + } + + $strCol = ($strLangue === 'en') ? 'que_question_en' : 'que_question_fr'; + $sql = " + SELECT que_id, $strCol AS que_label, que_validation + FROM inscriptions_questions + WHERE que_actif = 1 + AND eve_id = $eve_id + AND (FIND_IN_SET($epr_id, que_epreuves_incluses) OR que_epreuves_incluses = '' OR que_epreuves_incluses IS NULL) + AND que_validation NOT IN ('image', 'pdf') + ORDER BY que_tri, que_id + "; + $rows = $objDatabase->fxGetResults($sql); + if (!is_array($rows)) { + return []; + } + + $out = []; + foreach ($rows as $row) { + $intQueId = (int)($row['que_id'] ?? 0); + if ($intQueId <= 0) { + continue; + } + $strLabel = trim((string)($row['que_label'] ?? '')); + if ($strLabel === '') { + $strLabel = 'Question #' . $intQueId; + } + if (mb_strlen($strLabel) > 72) { + $strLabel = mb_substr($strLabel, 0, 69) . '…'; + } + $out[] = [ + 'key' => 'que:' . $intQueId, + 'label' => $strLabel, + 'group' => 'question', + ]; + } + + return $out; +} + +/** MSIN-4436 — Options de tri (fixes + questions) pour une épreuve. */ +function fxBibGetSortOptionsForEpreuve($epr_id, $eve_id, $strLangue = 'fr', $blnTeamEpreuve = false, $blnIncludeQuestions = true) { + global $objDatabase; + + $out = []; + $rows = $objDatabase->fxGetResults( + "SELECT * FROM bib_assignements WHERE ba_actif = 1 ORDER BY ba_tri" + ); + + if (is_array($rows)) { + foreach ($rows as $row) { + if ((int)($row['ba_equipe'] ?? 0) === 1 && !$blnTeamEpreuve) { + continue; + } + $intBaId = (int)($row['ba_id'] ?? 0); + if ($intBaId <= 0) { + continue; + } + $strLabel = trim((string)($row['ba_nom_' . $strLangue] ?? '')); + if ($strLabel === '') { + $strLabel = trim((string)($row['ba_nom_fr'] ?? '')); + } + $out[] = [ + 'key' => 'ba:' . $intBaId, + 'label' => $strLabel !== '' ? $strLabel : ('ba:' . $intBaId), + 'group' => 'fixed', + ]; + } + } + + if ($blnIncludeQuestions && (int)$epr_id > 0 && (int)$eve_id > 0) { + $out = array_merge($out, fxBibGetQuestionSortOptions($epr_id, $eve_id, $strLangue)); + } + + return $out; +} + +/** MSIN-4436 — Vérifie qu'une question est liée à l'épreuve. */ +function fxBibQuestionSortAllowedForEpreuve($epr_id, $que_id, $eve_id) { + global $objDatabase; + + $epr_id = (int)$epr_id; + $que_id = (int)$que_id; + $eve_id = (int)$eve_id; + if ($epr_id <= 0 || $que_id <= 0 || $eve_id <= 0) { + return false; + } + + $sql = " + SELECT COUNT(*) + FROM inscriptions_questions + WHERE que_id = $que_id + AND eve_id = $eve_id + AND que_actif = 1 + AND que_validation NOT IN ('image', 'pdf') + AND (FIND_IN_SET($epr_id, que_epreuves_incluses) OR que_epreuves_incluses = '' OR que_epreuves_incluses IS NULL) + "; + + return (int)$objDatabase->fxGetVar($sql) > 0; +} + +/** MSIN-4436 — Fragment ORDER BY pour une clé de tri. */ +function fxBibResolveSortClause($epr_id, $sortKey, $strLangue = 'fr', $eve_id = 0) { + global $objDatabase; + + $sortKey = fxBibNormalizeSortKey($sortKey); + if ($sortKey === '') { + return ''; + } + + if (preg_match('/^ba:(\d+)$/', $sortKey, $m)) { + $intBaId = (int)$m[1]; + $orderBy = trim((string)$objDatabase->fxGetVar( + "SELECT ba_sql_order FROM bib_assignements WHERE ba_id = $intBaId AND ba_actif = 1 LIMIT 1" + )); + return $orderBy !== '' ? $orderBy : ''; + } + + if (preg_match('/^que:(\d+)$/', $sortKey, $m)) { + $que_id = (int)$m[1]; + $epr_id = (int)$epr_id; + if ($epr_id <= 0) { + return ''; + } + if ($eve_id <= 0) { + $eve_id = (int)$objDatabase->fxGetVar( + "SELECT eve_id FROM inscriptions_epreuves WHERE epr_id = $epr_id LIMIT 1" + ); + } + if (!fxBibQuestionSortAllowedForEpreuve($epr_id, $que_id, $eve_id)) { + return ''; + } + $strCol = ($strLangue === 'en') ? 'que_choix_en' : 'que_choix_fr'; + return "( + SELECT TRIM(rq.$strCol) + FROM resultats_questions rq + WHERE rq.que_actif = 1 + AND rq.que_id = $que_id + AND rq.par_id = p.par_id + AND rq.pec_id = p.pec_id + LIMIT 1 + )"; + } + + return ''; +} + +/** MSIN-4436 — ORDER BY complet (2 niveaux + tie-breaker). */ +function fxBibBuildBatchOrderBy($epr_id, $sort1, $sort2 = '', $strLangue = 'fr', $eve_id = 0) { + $epr_id = (int)$epr_id; + if ($eve_id <= 0 && $epr_id > 0) { + global $objDatabase; + $eve_id = (int)$objDatabase->fxGetVar( + "SELECT eve_id FROM inscriptions_epreuves WHERE epr_id = $epr_id LIMIT 1" + ); + } + + $tabParts = []; + foreach ([$sort1, $sort2] as $mixKey) { + $strClause = fxBibResolveSortClause($epr_id, $mixKey, $strLangue, $eve_id); + if ($strClause !== '' && !in_array($strClause, $tabParts, true)) { + $tabParts[] = $strClause; + } + } + + if (empty($tabParts)) { + $tabParts[] = 'p.par_nom, p.par_prenom'; + } + + $tabParts[] = 'p.par_id ASC'; + + return implode(', ', $tabParts); +} + +/** MSIN-4436 — Rendu des '; + } + + $tabFixed = []; + $tabQuestions = []; + foreach ($tabOptions as $opt) { + if (($opt['group'] ?? '') === 'question') { + $tabQuestions[] = $opt; + } else { + $tabFixed[] = $opt; + } + } + + if (!empty($tabFixed)) { + $html .= ''; + } + + if (!empty($tabQuestions)) { + $html .= ''; + } + + return $html; +} + // v2 — options d'ordre batch (table bib_assignements) -function renderBatchConfig($tabBibAssignments, $strLangue = 'fr', $isTeamEpreuve = false) { +function renderBatchConfig($epr_id, $eve_id, $strLangue = 'fr', $isTeamEpreuve = false, $strSort1 = '', $strSort2 = '') { + $epr_id = (int)$epr_id; + $eve_id = (int)$eve_id; + $strSort1 = fxBibNormalizeSortKey($strSort1); + $strSort2 = fxBibNormalizeSortKey($strSort2); + if ($strSort1 === '') { + $strSort1 = 'ba:2'; + } + + $tabOptions = fxBibGetSortOptionsForEpreuve($epr_id, $eve_id, $strLangue, $isTeamEpreuve, true); ob_start(); ?> @@ -2650,21 +2981,17 @@ function renderBatchConfig($tabBibAssignments, $strLangue = 'fr', $isTeamEpreuve