Implement locking mechanism for bib ranges with AJAX support

This commit introduces a locking feature for bib ranges, allowing users to lock or unlock sequences via a new AJAX endpoint. The PHP code is updated to check for locked statuses before performing actions, enhancing data integrity. Additionally, new JavaScript functions are added to handle user interactions for locking and unlocking, along with corresponding CSS styles for visual feedback. This improves the user experience by preventing modifications to locked sequences and providing clear confirmation messages.
This commit is contained in:
2026-06-18 09:55:49 -04:00
parent 33a5e0a410
commit 27e581c40a
6 changed files with 413 additions and 15 deletions

View File

@ -73,6 +73,20 @@ if ($action == 'delete') {
if ($id > 0) {
$rowLock = $objDatabase->fxGetRow("
SELECT epr_bib_locked
FROM inscriptions_epreuves_bib
WHERE epr_bib_id = $id
");
if ($rowLock && (int)($rowLock['epr_bib_locked'] ?? 0) === 1) {
echo json_encode([
'success' => false,
'message' => fxBibMsg('bib_v4_ajax_range_locked')
]);
exit;
}
$range = fxInfosBibRange(0,$id);
$epr_id = $range[1]["epr_id"];
@ -169,8 +183,20 @@ if ($action == 'save') {
// =====================
if (!$is_new) {
$sqlGet = "SELECT epr_id FROM inscriptions_epreuves_bib WHERE epr_bib_id = $id";
$epr_id = (int)$objDatabase->fxGetVar($sqlGet);
$sqlGet = "SELECT epr_id, epr_bib_locked FROM inscriptions_epreuves_bib WHERE epr_bib_id = $id";
$rowRange = $objDatabase->fxGetRow($sqlGet);
if (!$rowRange || (int)($rowRange['epr_id'] ?? 0) <= 0) {
echo json_encode(['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_not_found')]);
exit;
}
if ((int)($rowRange['epr_bib_locked'] ?? 0) === 1) {
echo json_encode(['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_locked')]);
exit;
}
$epr_id = (int)$rowRange['epr_id'];
if ($epr_id <= 0) {
echo json_encode(['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_not_found')]);
@ -373,6 +399,15 @@ if ($action == 'batch_go') {
// Liste des ranges sélectionnés (JSON → array PHP)
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
$lockCheck = fxBibAssertRangesUnlocked($epr_id, is_array($ranges) ? $ranges : []);
if (!$lockCheck['success']) {
echo json_encode([
'success' => false,
'message' => $lockCheck['message'] ?? fxBibMsg('bib_v4_ajax_range_locked')
]);
exit;
}
// Ordre choisi (table bib_assignements)
$ba_id = intval($_POST['ba_id'] ?? 0);
@ -444,6 +479,15 @@ if ($action == 'batch_apply') {
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
$ba_id = intval($_POST['ba_id'] ?? 0);
$lockCheck = fxBibAssertRangesUnlocked($epr_id, is_array($ranges) ? $ranges : []);
if (!$lockCheck['success']) {
echo json_encode([
'success' => false,
'message' => $lockCheck['message'] ?? fxBibMsg('bib_v4_ajax_range_locked')
]);
exit;
}
$participants = fxGetParticipantsForBatchAssign($epr_id, $ba_id);
$tabRanges = fxGetRangesForBatchAssign($epr_id, $ranges);
@ -506,6 +550,15 @@ if ($action == 'reset_preview') {
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
$lockCheck = fxBibAssertRangesUnlocked($epr_id, is_array($ranges) ? $ranges : []);
if (!$lockCheck['success']) {
echo json_encode([
'success' => false,
'message' => $lockCheck['message'] ?? fxBibMsg('bib_v4_ajax_range_locked')
]);
exit;
}
$participants = fxGetParticipantsForBatchReset($epr_id, $ranges);
$html = renderBibView(
@ -535,6 +588,15 @@ if ($action == 'reset_apply') {
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
$lockCheck = fxBibAssertRangesUnlocked($epr_id, is_array($ranges) ? $ranges : []);
if (!$lockCheck['success']) {
echo json_encode([
'success' => false,
'message' => $lockCheck['message'] ?? fxBibMsg('bib_v4_ajax_range_locked')
]);
exit;
}
$participants = fxGetParticipantsForBatchReset($epr_id, $ranges);
$count = 0;
@ -611,6 +673,51 @@ if ($action == 'save_team_mode') {
exit;
}
// MSIN-4379 — Verrouillage séquence (cadenas ouvert/fermé)
if ($action == 'toggle_lock') {
if (!fxBibRequirePromoteurSession()) {
echo json_encode([
'success' => false,
'message' => fxBibMsg('bib_v4_ajax_session_invalid')
]);
exit;
}
if (!fxBibValidateCsrf($_POST['csrf_token'] ?? '')) {
echo json_encode([
'success' => false,
'message' => fxBibMsg('bib_v4_ajax_unauthorized')
]);
exit;
}
$epr_bib_id = intval($_POST['epr_bib_id'] ?? 0);
$epr_id = intval($_POST['epr_id'] ?? 0);
$locked = intval($_POST['locked'] ?? 0) === 1;
$result = fxBibSetRangeLocked($epr_bib_id, $locked, $epr_id);
if (!$result['success']) {
echo json_encode([
'success' => false,
'message' => $result['message'] ?? fxBibMsg('bib_v4_ajax_error')
]);
exit;
}
$epr_id = (int)$result['epr_id'];
$tabBibStats = fxInfosBibRange($epr_id);
echo json_encode([
'success' => true,
'locked' => !empty($result['locked']),
'auto_active' => fxIsBibAutoActive($epr_id),
'html' => renderBibRanges($tabBibStats, $epr_id, 'assign')
]);
exit;
}
// MSIN-4379 — Étape 2
// Endpoint AJAX : sauvegarde ou désactivation de la config auto (epr_bib_auto).
// Paramètres : epr_id, active (0|1), ranges (JSON des epr_bib_id), csrf_token.

View File

@ -1813,10 +1813,11 @@ a.ms1-trad-link.btn-aide-trad{
width:100%;
}
/* MSIN-4379 — View/OK/Suppr icônes ; stats regroupées ; badge auto à droite. */
/* MSIN-4379 — Cadenas + view/OK/stats ; badge auto à droite. */
.epr-line{
display:grid;
grid-template-columns:
32px
40px
58px
58px
@ -1832,6 +1833,7 @@ a.ms1-trad-link.btn-aide-trad{
.bib-container.batch-mode .epr-line{
grid-template-columns:
32px
40px
58px
58px
@ -1841,6 +1843,52 @@ a.ms1-trad-link.btn-aide-trad{
28px;
}
.epr-col-lock{
display:flex;
align-items:center;
justify-content:center;
min-width:0;
}
.btn-bib-lock{
width:100%;
padding-left:0;
padding-right:0;
border-width:1px;
border-style:solid;
}
.btn-bib-lock--open{
background-color:#28a745;
border-color:#218838;
color:#fff;
}
.btn-bib-lock--open:hover,
.btn-bib-lock--open:focus{
background-color:#218838;
border-color:#1e7e34;
color:#fff;
}
.btn-bib-lock--closed{
background-color:#dc3545;
border-color:#c82333;
color:#fff;
}
.btn-bib-lock--closed:hover,
.btn-bib-lock--closed:focus{
background-color:#c82333;
border-color:#bd2130;
color:#fff;
}
.bib-range--locked .bib-start,
.bib-range--locked .bib-end{
background-color:#f1f3f5;
}
.epr-col-stats{
display:grid;
grid-template-columns:56px 48px 48px;

View File

@ -1975,6 +1975,10 @@ if ($strLangue == 'fr') {
return moduleBib.dataset[attr] || '';
}
function bibJsConfirm(attr) {
return bibJs(attr).replace(/\\n/g, '\n');
}
function bibJsFmt(attr) {
var tpl = bibJs(attr);
var args = Array.prototype.slice.call(arguments, 1);
@ -2546,6 +2550,59 @@ if ($strLangue == 'fr') {
return;
}
// =====================
// LOCK / UNLOCK SEQUENCE
// =====================
let btnLock = e.target.closest('.btn-bib-lock');
if (btnLock) {
e.preventDefault();
let row = btnLock.closest('.epr-row');
if (!row) return;
let isLocked = btnLock.dataset.locked === '1';
let confirmMsg = isLocked
? bibJsConfirm('jsUnlockConfirm')
: bibJsConfirm('jsLockConfirm');
if (!confirm(confirmMsg)) {
return;
}
fetch('/ajax_bib_range.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body:
'action=toggle_lock'
+ '&epr_bib_id=' + encodeURIComponent(btnLock.dataset.rangeId)
+ '&epr_id=' + encodeURIComponent(btnLock.dataset.eprId || row.dataset.eprId)
+ '&locked=' + encodeURIComponent(isLocked ? '0' : '1')
+ '&csrf_token=' + encodeURIComponent(bibCsrfToken())
+ bibAjaxLangSuffix()
})
.then(res => res.json())
.then(data => {
if (!data.success) {
alert(data.message || bibJs('jsErrGeneric'));
return;
}
if (typeof data.auto_active !== 'undefined') {
row.dataset.autoActive = data.auto_active ? '1' : '0';
syncAutoUiState(row, data.auto_active);
}
if (data.html) {
setBibContainerHtml(row, data.html);
}
});
return;
}
// =====================
// DELETE
// =====================

View File

@ -2917,6 +2917,8 @@ function fxBibModuleJsDataAttrs() {
'batch-summary-short' => 'bib_v4_ajax_sim_summary',
'batch-reset-count' => 'bib_v4_ajax_reset_preview_count',
'auto-select-hint' => 'bib_v4_auto_select_hint',
'lock-confirm' => 'bib_v4_js_lock_confirm',
'unlock-confirm' => 'bib_v4_js_unlock_confirm',
];
$html = '';
foreach ($map as $attr => $clef) {
@ -3073,9 +3075,122 @@ function fxBibIsRangeAvailableForAuto($epr_id, $epr_bib_id) {
return false;
}
if (fxBibRangeIsLocked($rows[1])) {
return false;
}
return fxBibRangeDispoFromRow($rows[1]) > 0;
}
/** Séquence verrouillée (epr_bib_locked = 1) — plus de modification ni assignation. */
function fxBibRangeIsLocked(array $range) {
return (int)($range['epr_bib_locked'] ?? 0) === 1;
}
/** Vérifie qu'aucune des séquences listées n'est verrouillée. */
function fxBibAssertRangesUnlocked($epr_id, $rangeIds) {
global $objDatabase;
$epr_id = (int)$epr_id;
if ($epr_id <= 0 || empty($rangeIds) || !is_array($rangeIds)) {
return ['success' => true];
}
$ids = array_values(array_filter(array_map('intval', $rangeIds)));
if (empty($ids)) {
return ['success' => true];
}
$strIds = implode(',', $ids);
$sql = "
SELECT COUNT(*)
FROM inscriptions_epreuves_bib
WHERE epr_id = $epr_id
AND epr_bib_id IN ($strIds)
AND epr_bib_locked = 1
";
if ((int)$objDatabase->fxGetVar($sql) > 0) {
return ['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_locked')];
}
return ['success' => true];
}
/** Bascule le verrou d'une séquence (0 = ouvert, 1 = fermé). */
function fxBibSetRangeLocked($epr_bib_id, $locked, $epr_id = 0) {
global $objDatabase;
$epr_bib_id = (int)$epr_bib_id;
$epr_id = (int)$epr_id;
$locked = $locked ? 1 : 0;
if ($epr_bib_id <= 0) {
return ['success' => false, 'message' => fxBibMsg('bib_v4_ajax_id_invalid')];
}
$sqlGet = "
SELECT epr_id
FROM inscriptions_epreuves_bib
WHERE epr_bib_id = $epr_bib_id
";
$rowEprId = (int)$objDatabase->fxGetVar($sqlGet);
if ($rowEprId <= 0) {
return ['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_not_found')];
}
if ($epr_id > 0 && $rowEprId !== $epr_id) {
return ['success' => false, 'message' => fxBibMsg('bib_v4_ajax_seq_invalid')];
}
$objDatabase->fxQuery("
UPDATE inscriptions_epreuves_bib
SET epr_bib_locked = $locked
WHERE epr_bib_id = $epr_bib_id
");
if ($locked === 1) {
$objDatabase->fxQuery("
UPDATE inscriptions_epreuves_bib
SET epr_bib_auto = 0
WHERE epr_bib_id = $epr_bib_id
");
}
return [
'success' => true,
'epr_id' => $rowEprId,
'locked' => $locked === 1,
];
}
/** Bouton cadenas (vert ouvert / rouge fermé) devant une séquence enregistrée. */
function fxBibRenderRangeLockButton(array $range, $epr_id = 0) {
if ((int)($range['epr_bib_id'] ?? 0) <= 0) {
return '<div class="epr-col-lock"></div>';
}
$locked = fxBibRangeIsLocked($range);
$strClass = $locked ? 'btn-bib-lock--closed' : 'btn-bib-lock--open';
$strIcon = $locked ? 'fa-lock' : 'fa-unlock';
$strTip = $locked ? 'bib_v4_tip_lock_closed' : 'bib_v4_tip_lock_open';
return '<button type="button"'
. ' class="btn btn-sm btn-bib-lock ' . $strClass . '"'
. ' data-range-id="' . (int)$range['epr_bib_id'] . '"'
. ' data-epr-id="' . (int)$epr_id . '"'
. ' data-locked="' . ($locked ? '1' : '0') . '"'
. ' aria-pressed="' . ($locked ? 'true' : 'false') . '"'
. fxBibTippyAttr($strTip)
. '>'
. '<i class="fa ' . $strIcon . '" aria-hidden="true"></i>'
. '</button>';
}
/** Badge « Assignation automatique » sur une ligne de séquence (epr_bib_auto = 1). */
function fxBibRenderRangeAutoBadge(array $range, $mode = 'assign') {
if ($mode !== 'assign') {
@ -3087,6 +3202,9 @@ function fxBibRenderRangeAutoBadge(array $range, $mode = 'assign') {
if ((int)($range['epr_bib_auto'] ?? 0) !== 1) {
return '';
}
if (fxBibRangeIsLocked($range)) {
return '';
}
if (fxBibRangeDispoFromRow($range) <= 0) {
return '';
}
@ -3302,6 +3420,7 @@ function renderBibRangeHeader() {
ob_start();
?>
<div class="epr-line epr-line-header">
<div class="epr-col-lock"><?php echo fxBibColHeader('bib_v4_col_lock'); ?></div>
<div><?php echo fxBibColHeader('bib_v4_col_view'); ?></div>
<div><?php echo fxBibColHeader('bib_v4_col_start'); ?></div>
<div><?php echo fxBibColHeader('bib_v4_col_end'); ?></div>
@ -3617,6 +3736,7 @@ function fxInfosBibRange($epr_id = 0, $epr_bib_id = 0){
b.epr_bib_start,
b.epr_bib_finish,
b.epr_bib_auto, /* MSIN-4379 — Étape 1 : flag par séquence (pool auto). */
b.epr_bib_locked,
COUNT(p.no_bib) AS nb_utilises,
MAX(p.no_bib) AS dernier_bib,
@ -3713,7 +3833,8 @@ function fxInfosBibRange($epr_id = 0, $epr_bib_id = 0){
b.epr_id,
b.epr_bib_start,
b.epr_bib_finish,
b.epr_bib_auto
b.epr_bib_auto,
b.epr_bib_locked
ORDER BY b.epr_bib_start
";
@ -3741,6 +3862,7 @@ function fxIsBibAutoActive($epr_id) {
FROM inscriptions_epreuves_bib
WHERE epr_id = $epr_id
AND epr_bib_auto = 1
AND epr_bib_locked = 0
";
return (int)$objDatabase->fxGetVar($sql) > 0;
@ -3802,6 +3924,11 @@ function fxSaveBibAutoConfig($epr_id, $ranges, $active = true) {
}
}
$lockCheck = fxBibAssertRangesUnlocked($epr_id, $ids);
if (!$lockCheck['success']) {
return $lockCheck;
}
$objDatabase->fxQuery("
UPDATE inscriptions_epreuves_bib
SET epr_bib_auto = 1
@ -3830,6 +3957,7 @@ function fxGetAutoBibRangeIds($epr_id) {
FROM inscriptions_epreuves_bib
WHERE epr_id = $epr_id
AND epr_bib_auto = 1
AND epr_bib_locked = 0
ORDER BY epr_bib_start
";
@ -4095,10 +4223,16 @@ $nb_utilises = (int)($range['nb_utilises'] ?? 0);
$mem_dispo = max(0, $nb_total - $nb_utilises);
$blnRangeLocked = fxBibRangeIsLocked($range);
?>
<div class="bib-range epr-line" data-id="<?php echo $range['epr_bib_id']; ?>">
<div class="bib-range epr-line<?php echo $blnRangeLocked ? ' bib-range--locked' : ''; ?>"
data-id="<?php echo $range['epr_bib_id']; ?>"
data-locked="<?php echo $blnRangeLocked ? '1' : '0'; ?>">
<?php echo fxBibRenderRangeLockButton($range, $epr_id); ?>
<?php if ((int)$range['epr_bib_id'] > 0) { ?>
<button type="button"
@ -4113,22 +4247,26 @@ $mem_dispo = max(0, $nb_total - $nb_utilises);
<input type="number"
class="form-control form-control-sm bib-start"
value="<?php echo $range['epr_bib_start']; ?>">
value="<?php echo $range['epr_bib_start']; ?>"
<?php echo $blnRangeLocked ? 'readonly' : ''; ?>>
<input type="number"
class="form-control form-control-sm bib-end"
value="<?php echo $range['epr_bib_finish']; ?>">
value="<?php echo $range['epr_bib_finish']; ?>"
<?php echo $blnRangeLocked ? 'readonly' : ''; ?>>
<button type="button"
class="btn btn-sm btn-primary btn-save-range"
data-id="<?php echo $range['epr_bib_id']; ?>"
data-epr-id="<?php echo (int)$epr_id; ?>">
data-epr-id="<?php echo (int)$epr_id; ?>"
<?php echo $blnRangeLocked ? 'disabled' : ''; ?>>
<?php fxBibTexte('bib_v4_btn_ok', 1); ?>
</button>
<?php if ((int)$range['epr_bib_id'] > 0) { ?>
<button type="button"
class="btn btn-sm btn-danger btn-delete-range"
data-id="<?php echo $range['epr_bib_id']; ?>">
data-id="<?php echo $range['epr_bib_id']; ?>"
<?php echo $blnRangeLocked ? 'disabled' : ''; ?>>
<i class="fa fa-trash"></i>
</button>
<?php } else { ?>
@ -4148,28 +4286,28 @@ $mem_dispo = max(0, $nb_total - $nb_utilises);
$showCheckbox = false;
if (
if (!$blnRangeLocked && (
$mode === 'assign'
&& $mem_dispo > 0
&& (int)$range['epr_bib_id'] > 0
) {
)) {
$showCheckbox = true;
}
if (
if (!$blnRangeLocked && (
$mode === 'reset'
&& (int)$range['nb_utilises'] > 0
&& (int)$range['epr_bib_id'] > 0
) {
)) {
$showCheckbox = true;
}
// MSIN-4379 — Étape 2 : mode « auto » — séquences avec dossards disponibles seulement.
if (
if (!$blnRangeLocked && (
$mode === 'auto'
&& $mem_dispo > 0
&& (int)$range['epr_bib_id'] > 0
) {
)) {
$showCheckbox = true;
}

View File

@ -0,0 +1,5 @@
-- MSIN-4379 — Verrouillage de séquence de dossards (cadenas ouvert/fermé)
ALTER TABLE inscriptions_epreuves_bib
ADD COLUMN epr_bib_locked TINYINT(1) NOT NULL DEFAULT 0
AFTER epr_bib_auto;

View File

@ -0,0 +1,43 @@
-- MSIN-4379 — i18n verrouillage séquences de dossards
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_col_lock', 'fr', '', 'Verrouiller ou déverrouiller la séquence.', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_col_lock' AND info_langue = 'fr' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_col_lock', 'en', '', 'Lock or unlock the sequence.', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_col_lock' AND info_langue = 'en' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_tip_lock_open', 'fr', 'Séquence ouverte', 'Cliquez pour verrouiller : la plage, les dossards et les assignations ne pourront plus être modifiés.', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_tip_lock_open' AND info_langue = 'fr' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_tip_lock_open', 'en', 'Sequence unlocked', 'Click to lock: range, bibs and assignments can no longer be changed.', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_tip_lock_open' AND info_langue = 'en' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_tip_lock_closed', 'fr', 'Séquence verrouillée', 'Cliquez pour déverrouiller (confirmation requise).', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_tip_lock_closed' AND info_langue = 'fr' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_tip_lock_closed', 'en', 'Sequence locked', 'Click to unlock (confirmation required).', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_tip_lock_closed' AND info_langue = 'en' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_js_lock_confirm', 'fr', 'Verrouiller cette séquence ?\n\nTant qu''elle est verrouillée, vous ne pourrez plus modifier la plage de numéros, supprimer la séquence, réinitialiser les dossards ni l''utiliser pour l''assignation automatique ou groupée.', '', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_lock_confirm' AND info_langue = 'fr' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_js_lock_confirm', 'en', 'Lock this sequence?\n\nWhile locked, you cannot change the number range, delete the sequence, reset bibs, or use it for automatic or batch assignment.', '', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_lock_confirm' AND info_langue = 'en' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_js_unlock_confirm', 'fr', 'Déverrouiller cette séquence ?\n\nAttention : des dossards peuvent déjà avoir été imprimés ou communiqués. Déverrouiller pourrait compromettre la cohérence de vos données.\n\nConfirmez-vous le déverrouillage ?', '', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_unlock_confirm' AND info_langue = 'fr' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_js_unlock_confirm', 'en', 'Unlock this sequence?\n\nWarning: bibs may already have been printed or distributed. Unlocking could compromise your data.\n\nDo you confirm unlocking?', '', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_unlock_confirm' AND info_langue = 'en' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_ajax_range_locked', 'fr', 'Cette séquence est verrouillée et ne peut pas être modifiée', '', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_ajax_range_locked' AND info_langue = 'fr' AND info_prg = 'compte.php');
INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
SELECT 'bib_v4_ajax_range_locked', 'en', 'This sequence is locked and cannot be modified', '', 'compte.php', '', 0, 1, '', '', '', NOW()
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_ajax_range_locked' AND info_langue = 'en' AND info_prg = 'compte.php');