MSIN-4464 — Enhance audit logging functionality for participant management. Introduce new functions to track last touch events and handle cancellation/restoration of participant registrations. Update admin interface to display recent logs and improve oversight of audit activities, ensuring better traceability of changes made to participant records.
This commit is contained in:
@ -315,6 +315,139 @@ function fxFicheAuditRecordChange(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MSIN-4464 — Dernière intervention seule (édition fiche, etc.), sans old→new.
|
||||
*/
|
||||
function fxFicheAuditRecordLastTouchOnly($intParId, $strTriggerField, $strSource = '', $intEveId = 0)
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
$intParId = intval($intParId);
|
||||
$strTriggerField = preg_replace('/[^a-z0-9_]/i', '', (string)$strTriggerField);
|
||||
if ($strTriggerField === '') {
|
||||
$strTriggerField = 'fiche';
|
||||
}
|
||||
if ($intParId <= 0 || !isset($objDatabase) || !fxFicheAuditTablesReady()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$arrSettings = fxFicheAuditGetSettings();
|
||||
if (intval($arrSettings['track_last_touch']) !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($intEveId <= 0) {
|
||||
$intEveId = intval($objDatabase->fxGetVar(
|
||||
'SELECT eve_id FROM resultats_participants WHERE par_id = ' . $intParId . ' LIMIT 1'
|
||||
));
|
||||
}
|
||||
|
||||
$arrActor = fxFicheAuditResolveActor();
|
||||
fxFicheAuditInsertLogRow(
|
||||
$intParId,
|
||||
$intEveId,
|
||||
'last_touch',
|
||||
'',
|
||||
$strTriggerField,
|
||||
$arrActor,
|
||||
$strSource
|
||||
);
|
||||
fxFicheAuditTrimField($intParId, 'last_touch', $arrSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Après annulation / rétablissement sur une commande (tous les par_id du pec).
|
||||
*/
|
||||
function fxFicheAuditRecordCancelRestoreForPec($intPecId, $strOld, $strNew, $strSource, $intEveId = 0)
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
$intPecId = intval($intPecId);
|
||||
if ($intPecId <= 0 || !isset($objDatabase) || !fxFicheAuditTablesReady()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = 'SELECT par_id, eve_id FROM resultats_participants WHERE pec_id = ' . $intPecId;
|
||||
$arrRows = $objDatabase->fxGetResults($sql);
|
||||
if (!is_array($arrRows)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($arrRows as $row) {
|
||||
if (!is_array($row) || empty($row['par_id'])) {
|
||||
continue;
|
||||
}
|
||||
$intEveRow = intval($row['eve_id'] ?? 0);
|
||||
if ($intEveRow <= 0) {
|
||||
$intEveRow = intval($intEveId);
|
||||
}
|
||||
fxFicheAuditRecordChange(
|
||||
intval($row['par_id']),
|
||||
'is_cancelled',
|
||||
$strOld,
|
||||
$strNew,
|
||||
$strSource,
|
||||
$intEveRow
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Événements pour le sélecteur admin (actifs récents + ceux déjà dans les logs).
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
function fxFicheAuditAdminListEvents()
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
if (!isset($objDatabase) || !fxFicheAuditTablesReady()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sql = 'SELECT e.eve_id, e.eve_nom_fr, e.eve_date_debut,'
|
||||
. ' (SELECT COUNT(*) FROM inscriptions_fiche_audit_log l WHERE l.eve_id = e.eve_id) AS fal_nb'
|
||||
. ' FROM inscriptions_evenements e'
|
||||
. ' WHERE e.eve_actif = 1'
|
||||
. ' OR EXISTS (SELECT 1 FROM inscriptions_fiche_audit_log l2 WHERE l2.eve_id = e.eve_id)'
|
||||
. ' ORDER BY e.eve_date_debut DESC, e.eve_id DESC'
|
||||
. ' LIMIT 300';
|
||||
$arrRows = $objDatabase->fxGetResults($sql);
|
||||
|
||||
return is_array($arrRows) ? $arrRows : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Derniers logs d'un événement (contrôle admin).
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
function fxFicheAuditAdminListRecentByEve($intEveId, $intLimit = 100)
|
||||
{
|
||||
global $objDatabase;
|
||||
|
||||
$intEveId = intval($intEveId);
|
||||
$intLimit = intval($intLimit);
|
||||
if ($intLimit !== 200) {
|
||||
$intLimit = 100;
|
||||
}
|
||||
if ($intEveId <= 0 || !isset($objDatabase) || !fxFicheAuditTablesReady()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sql = 'SELECT l.fal_id, l.par_id, l.eve_id, l.field_key, l.old_value, l.new_value,'
|
||||
. ' l.changed_by_com_id, l.changed_by_label, l.source, l.created_at,'
|
||||
. ' p.par_prenom, p.par_nom, p.no_bib'
|
||||
. ' FROM inscriptions_fiche_audit_log l'
|
||||
. ' LEFT JOIN resultats_participants p ON p.par_id = l.par_id'
|
||||
. ' WHERE l.eve_id = ' . $intEveId
|
||||
. ' ORDER BY l.created_at DESC, l.fal_id DESC'
|
||||
. ' LIMIT ' . $intLimit;
|
||||
$arrRows = $objDatabase->fxGetResults($sql);
|
||||
|
||||
return is_array($arrRows) ? $arrRows : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{com_id:int,label:string} $arrActor
|
||||
*/
|
||||
|
||||
@ -310,6 +310,18 @@ function fxAnnulerRetablirInscription($tabEpreuve, $int_pec_id) {
|
||||
if (!$qryInscription || !$qryParticipants) {
|
||||
$tabRetour['state'] = 'error';
|
||||
fxcreer_log("Erreur d'annulation d'inscription : " . $_SESSION['com_info']['com_courriel']);
|
||||
} else {
|
||||
// MSIN-4464 — audit annulation
|
||||
if (!function_exists('fxFicheAuditRecordCancelRestoreForPec')) {
|
||||
require_once dirname(__FILE__) . '/inc_fx_fiche_audit.php';
|
||||
}
|
||||
fxFicheAuditRecordCancelRestoreForPec(
|
||||
intval($int_pec_id),
|
||||
'0',
|
||||
'1',
|
||||
'annuler',
|
||||
intval($tabEpreuve['eve_id'] ?? 0)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$tabRetour['action'] = 'retablir';
|
||||
@ -327,6 +339,18 @@ function fxAnnulerRetablirInscription($tabEpreuve, $int_pec_id) {
|
||||
if (!$qryInscription || !$qryParticipants) {
|
||||
$tabRetour['state'] = 'error';
|
||||
fxcreer_log("Erreur d'annulation d'inscription : " . $_SESSION['com_info']['com_courriel']);
|
||||
} else {
|
||||
// MSIN-4464 — audit rétablissement
|
||||
if (!function_exists('fxFicheAuditRecordCancelRestoreForPec')) {
|
||||
require_once dirname(__FILE__) . '/inc_fx_fiche_audit.php';
|
||||
}
|
||||
fxFicheAuditRecordCancelRestoreForPec(
|
||||
intval($int_pec_id),
|
||||
'1',
|
||||
'0',
|
||||
'retablir',
|
||||
intval($tabEpreuve['eve_id'] ?? 0)
|
||||
);
|
||||
}
|
||||
|
||||
// ajuster qte epreuve
|
||||
|
||||
@ -797,11 +797,26 @@ LEFT JOIN inscriptions_panier_epreuves ee on e.epr_id=ee.epr_id
|
||||
$intDiff = ($tabAncienneEpreuve['epr_nb_participants'] - $tabNouvelleEpreuve['epr_nb_participants']);
|
||||
|
||||
for ($i = count($tabInscription); $i > $tabNouvelleEpreuve['epr_nb_participants']; $i--) {
|
||||
$sqlUpdate = "UPDATE resultats_participants SET is_cancelled = 1, par_modification_promoteur = 1 WHERE par_id = " . intval($tabInscription[$i]['par_id']);
|
||||
$intParCancel = intval($tabInscription[$i]['par_id']);
|
||||
$sqlUpdate = "UPDATE resultats_participants SET is_cancelled = 1, par_modification_promoteur = 1 WHERE par_id = " . $intParCancel;
|
||||
$qryUpdate = $objDatabase->fxQuery($sqlUpdate);
|
||||
|
||||
if (!$qryUpdate)
|
||||
if (!$qryUpdate) {
|
||||
fxcreer_log("Erreur lors du changemenet d'épreuve par le promoteur.");
|
||||
} else {
|
||||
// MSIN-4464 — participants surplus annulés au changement d'épreuve
|
||||
if (!function_exists('fxFicheAuditRecordChange')) {
|
||||
require_once dirname(__FILE__) . '/inc_fx_fiche_audit.php';
|
||||
}
|
||||
fxFicheAuditRecordChange(
|
||||
$intParCancel,
|
||||
'is_cancelled',
|
||||
'0',
|
||||
'1',
|
||||
'changement_epreuve',
|
||||
intval($tabInscription[$i]['eve_id'] ?? ($tabEvenement['general']['eve_id'] ?? 0))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$sqlUpdate = "UPDATE resultats_epreuves_commandees SET pec_equipe = " . $tabNouvelleEpreuve['epr_equipe'] . " WHERE pec_id_original = " . $intpec_id;
|
||||
@ -921,6 +936,17 @@ LEFT JOIN inscriptions_panier_epreuves ee on e.epr_id=ee.epr_id
|
||||
|
||||
if (!$qryUpdate) {
|
||||
fxcreer_log('Erreur dans la mise à jour des participants.(' . $tabInscription[1]['par_courriel'] . ')');
|
||||
} elseif ($strTableSqlPart === 'resultats_participants' && $strModMarker !== '') {
|
||||
// MSIN-4464 — édition fiche promoteur : dernière intervention (pas le détail de chaque champ).
|
||||
if (!function_exists('fxFicheAuditRecordLastTouchOnly')) {
|
||||
require_once dirname(__FILE__) . '/inc_fx_fiche_audit.php';
|
||||
}
|
||||
fxFicheAuditRecordLastTouchOnly(
|
||||
intval($intParId),
|
||||
'fiche',
|
||||
'fiche_edit',
|
||||
intval($tabEvenement['general']['eve_id'] ?? 0)
|
||||
);
|
||||
}
|
||||
// catégorie
|
||||
if ($tabEvenement['general']['eve_categorie_auto'] == 1) {
|
||||
@ -4094,8 +4120,15 @@ function fxMajEpreuvesCommandees($str_ancien_no_panier, $pec_id_old, $pec_id_new
|
||||
$sqlUpdate = "UPDATE resultats_participants SET is_cancelled = 1, par_modification_promoteur = 1, par_maj = '" . fxGetDateTime() . "' WHERE pec_id = " . intval($pec_id_old);
|
||||
$qryUpdateParticipants = $objDatabase->fxQuery($sqlUpdate);
|
||||
|
||||
if (!$qryUpdateEpreuve || !$qryUpdateParticipants)
|
||||
if (!$qryUpdateEpreuve || !$qryUpdateParticipants) {
|
||||
fxcreer_log("Erreur de désactivation de l'ancienne épreuve lors d'un upgrade ou transfert.");
|
||||
} else {
|
||||
// MSIN-4464 — annulation suite upgrade / transfert
|
||||
if (!function_exists('fxFicheAuditRecordCancelRestoreForPec')) {
|
||||
require_once dirname(__FILE__) . '/inc_fx_fiche_audit.php';
|
||||
}
|
||||
fxFicheAuditRecordCancelRestoreForPec(intval($pec_id_old), '0', '1', 'transfert_upgrade', 0);
|
||||
}
|
||||
}
|
||||
|
||||
unset($_SESSION['ancien_no_panier']);
|
||||
|
||||
@ -1789,6 +1789,11 @@ function fxShowBibNumbersTable($tab_epreuve, $strLangue, $intEveId = 0) {
|
||||
function fxSetBibNumbers($tab_data, $int_epr_id, $int_start, $int_finish, $int_type, $int_par_equipe, $str_action = '', $int_mode,$int_finish_dispo=999999) {
|
||||
global $strLangue, $objDatabase, $vDomaine;
|
||||
|
||||
// MSIN-4464 — audit dossards batch
|
||||
if (!function_exists('fxFicheAuditRecordChange')) {
|
||||
require_once dirname(__FILE__) . '/inc_fx_fiche_audit.php';
|
||||
}
|
||||
|
||||
if ($strLangue == 'fr') {
|
||||
$strPage = '/compte';
|
||||
} else {
|
||||
@ -1902,6 +1907,9 @@ function fxSetBibNumbers($tab_data, $int_epr_id, $int_start, $int_finish, $int_t
|
||||
for ($i = 1; $i <= count($tabInscriptions); $i++) {
|
||||
|
||||
if ($tabInscriptions[$i]['rol_id'] != 3 && $tabInscriptions[$i]['rol_id'] != 4) {
|
||||
$intParBatch = intval($tabInscriptions[$i]['par_id']);
|
||||
$strOldBibBatch = (string)($tabInscriptions[$i]['no_bib'] ?? '');
|
||||
$strNewBibBatch = ($str_action == 'reset') ? '' : (string)($intNoBib + $intCtr);
|
||||
$sqlUpdate = "UPDATE resultats_participants ";
|
||||
if ($str_action == 'reset') {
|
||||
$sqlUpdate .= "SET no_bib = '', par_date_bib = null";
|
||||
@ -1919,8 +1927,18 @@ function fxSetBibNumbers($tab_data, $int_epr_id, $int_start, $int_finish, $int_t
|
||||
$sqlUpdate .= " WHERE par_id = " . $tabInscriptions[$i]['par_id'] . " AND is_cancelled = 0";
|
||||
$qryUpdate = $objDatabase->fxQuery($sqlUpdate);
|
||||
|
||||
if (!$qryUpdate)
|
||||
if (!$qryUpdate) {
|
||||
fxcreer_log('Erreur lors de mise a jour du numero de dossard du participant ' . $tabInscriptions[$i]['par_id']);
|
||||
} else {
|
||||
fxFicheAuditRecordChange(
|
||||
$intParBatch,
|
||||
'no_bib',
|
||||
$strOldBibBatch,
|
||||
$strNewBibBatch,
|
||||
($str_action == 'reset') ? 'bib_batch_reset' : 'bib_batch',
|
||||
intval($tabInscriptions[$i]['eve_id'] ?? 0)
|
||||
);
|
||||
}
|
||||
|
||||
$sqlUpdate = "UPDATE resultats_epreuves_commandees SET no_equipe = '" . $objDatabase->fxEscape($intNoBib + $intCtr) . "' WHERE epr_id = " . intval($tabInscriptions[$i]['epr_id']) . " AND pec_id_original = " . $tabInscriptions[$i]['pec_id'];
|
||||
$qryUpdate = $objDatabase->fxQuery($sqlUpdate);
|
||||
@ -1967,16 +1985,29 @@ function fxSetBibNumbers($tab_data, $int_epr_id, $int_start, $int_finish, $int_t
|
||||
} else{
|
||||
$intNoBib = $strNumeroEquipe;
|
||||
}
|
||||
$intParEqBatch = intval($tabEquipe[$j]['par_id']);
|
||||
$strOldBibEq = (string)($tabEquipe[$j]['no_bib'] ?? '');
|
||||
$strNewBibEq = (string)$intNoBib;
|
||||
if($tabInscriptions[$i]['par_date_bib'] == null){
|
||||
$sqlUpdatePart = "UPDATE resultats_participants SET par_date_bib = '" . fxGetDateTime() . "', no_bib = '" . $objDatabase->fxEscape($intNoBib). "' WHERE par_id = " . intval($tabEquipe[$j]['par_id']);
|
||||
$sqlUpdatePart = "UPDATE resultats_participants SET par_date_bib = '" . fxGetDateTime() . "', no_bib = '" . $objDatabase->fxEscape($intNoBib). "' WHERE par_id = " . $intParEqBatch;
|
||||
} else{
|
||||
$sqlUpdatePart = "UPDATE resultats_participants SET no_bib = '" . $objDatabase->fxEscape($intNoBib) . "' WHERE par_id = " . intval($tabEquipe[$j]['par_id']);
|
||||
$sqlUpdatePart = "UPDATE resultats_participants SET no_bib = '" . $objDatabase->fxEscape($intNoBib) . "' WHERE par_id = " . $intParEqBatch;
|
||||
// $sqlUpdatePart = "UPDATE resultats_participants SET par_maj = '" . fxGetDateTime() . "', no_bib = '" . $objDatabase->fxEscape($intNoBib) . "' WHERE par_id = " . intval($tabEquipe[$j]['par_id']);
|
||||
// $sqlUpdatePart = "UPDATE resultats_participants SET par_maj = '" . fxGetDateTime() . "', par_modification_promoteur = 1, no_bib = '" . $objDatabase->fxEscape($intNoBib) . "' WHERE par_id = " . intval($tabEquipe[$j]['par_id']);
|
||||
}
|
||||
$qryUpdatePart = $objDatabase->fxQuery($sqlUpdatePart);
|
||||
if (!$qryUpdatePart)
|
||||
if (!$qryUpdatePart) {
|
||||
fxcreer_log('Erreur lors de mise a jour du numero de dossard du participant ' . $tabInscriptions[$i]['par_id']);
|
||||
} else {
|
||||
fxFicheAuditRecordChange(
|
||||
$intParEqBatch,
|
||||
'no_bib',
|
||||
$strOldBibEq,
|
||||
$strNewBibEq,
|
||||
'bib_batch',
|
||||
intval($tabEquipe[$j]['eve_id'] ?? 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$intCtr++;
|
||||
|
||||
@ -47,7 +47,10 @@ include('inc_header.php');
|
||||
<div class="col-md-9 col-lg-10 order-first order-md-last py-3">
|
||||
<?php
|
||||
require_once dirname(__FILE__) . '/../php/inc_fx_superadm_v2_ui.php';
|
||||
fxSuperadmV2PanelOpen('Traçabilité fiche — Champs & rétention', array(
|
||||
$strV2Title = !empty($_GET['voir_logs'])
|
||||
? 'Traçabilité fiche — Logs'
|
||||
: 'Traçabilité fiche — Champs & rétention';
|
||||
fxSuperadmV2PanelOpen($strV2Title, array(
|
||||
'zone_class' => 'superadm-content-v2-zone superadm-content-v2-zone--flush',
|
||||
));
|
||||
fxFicheAuditAdminRenderPage($strFlash, $strError);
|
||||
|
||||
@ -16,6 +16,11 @@ function fxFicheAuditAdminRenderPage($strFlash = '', $strError = '')
|
||||
$arrSettings = fxFicheAuditGetSettings();
|
||||
$arrFields = fxFicheAuditGetFieldsForAdmin();
|
||||
$strDisabled = ($blnCanEdit && $blnTablesOk) ? '' : ' disabled';
|
||||
$intEveLogs = isset($_GET['eve_id']) ? intval($_GET['eve_id']) : 0;
|
||||
$intLimitLogs = (isset($_GET['limit']) && intval($_GET['limit']) === 200) ? 200 : 100;
|
||||
$blnShowLogs = ($blnTablesOk && $intEveLogs > 0 && isset($_GET['voir_logs']));
|
||||
$arrEvents = $blnTablesOk ? fxFicheAuditAdminListEvents() : array();
|
||||
$arrLogs = $blnShowLogs ? fxFicheAuditAdminListRecentByEve($intEveLogs, $intLimitLogs) : array();
|
||||
|
||||
if ($strFlash !== '') {
|
||||
echo '<div class="alert alert-success">' . htmlspecialchars($strFlash, ENT_QUOTES, 'UTF-8') . '</div>';
|
||||
@ -35,7 +40,7 @@ function fxFicheAuditAdminRenderPage($strFlash = '', $strError = '')
|
||||
|
||||
<?php if (!$blnCanEdit) { ?>
|
||||
<div class="alert alert-info py-2">
|
||||
Lecture seule : vous pouvez consulter la configuration. Modification réservée.
|
||||
Lecture seule : vous pouvez consulter la configuration et les logs. Modification réservée.
|
||||
</div>
|
||||
<?php } ?>
|
||||
|
||||
@ -50,8 +55,9 @@ function fxFicheAuditAdminRenderPage($strFlash = '', $strError = '')
|
||||
<li><strong>Rétention</strong> — on ne garde pas un log sans fin : durée max + nombre max d'entrées par champ × participant.</li>
|
||||
</ul>
|
||||
<p class="mb-0 text-muted">
|
||||
L'enregistrement est actif pour statut, dossard et dossard remis (selon whitelist / dernière intervention).
|
||||
L'affichage « ? » sur la fiche et le droit promoteur associé viennent dans une étape suivante.
|
||||
Points branchés : statut, dossard manuel, dossard remis, annulation/rétablissement, édition fiche,
|
||||
batch dossards, surplus changement d'épreuve, transfert/upgrade.
|
||||
L'affichage « ? » sur la fiche et le droit promoteur associé viennent ensuite.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -136,5 +142,135 @@ function fxFicheAuditAdminRenderPage($strFlash = '', $strError = '')
|
||||
</button>
|
||||
<?php } ?>
|
||||
</form>
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header py-2">
|
||||
<strong><i class="fa fa-list" aria-hidden="true"></i> Contrôle des logs (admin)</strong>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="small text-muted mb-3">
|
||||
Affiche les dernières entrées enregistrées pour un événement — utile pour valider que ça logue bien.
|
||||
</p>
|
||||
<?php if (!$blnTablesOk) { ?>
|
||||
<p class="text-muted mb-0">Tables absentes — impossible d'afficher les logs.</p>
|
||||
<?php } else { ?>
|
||||
<form method="get" action="fiche_audit.php" class="form-row align-items-end">
|
||||
<input type="hidden" name="voir_logs" value="1">
|
||||
<div class="form-group col-md-6 mb-2">
|
||||
<label for="eve_id_logs">Événement</label>
|
||||
<select class="form-control" id="eve_id_logs" name="eve_id" required>
|
||||
<option value="">— choisir —</option>
|
||||
<?php foreach ($arrEvents as $arrEve) {
|
||||
$intEveOpt = intval($arrEve['eve_id'] ?? 0);
|
||||
if ($intEveOpt <= 0) {
|
||||
continue;
|
||||
}
|
||||
$strNomEve = trim((string)($arrEve['eve_nom_fr'] ?? ''));
|
||||
if ($strNomEve === '') {
|
||||
$strNomEve = 'Événement #' . $intEveOpt;
|
||||
}
|
||||
$intNb = intval($arrEve['fal_nb'] ?? 0);
|
||||
$strDate = trim((string)($arrEve['eve_date_debut'] ?? ''));
|
||||
$strLabel = $strNomEve
|
||||
. ($strDate !== '' && $strDate !== '0000-00-00' ? ' (' . $strDate . ')' : '')
|
||||
. ' — #' . $intEveOpt
|
||||
. ($intNb > 0 ? ' · ' . $intNb . ' log(s)' : '');
|
||||
?>
|
||||
<option value="<?= $intEveOpt ?>"<?= $intEveLogs === $intEveOpt ? ' selected' : '' ?>>
|
||||
<?= htmlspecialchars($strLabel, ENT_QUOTES, 'UTF-8') ?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-md-6 mb-2">
|
||||
<button type="submit" name="limit" value="100" class="btn btn-outline-primary mr-2">
|
||||
100 derniers
|
||||
</button>
|
||||
<button type="submit" name="limit" value="200" class="btn btn-outline-primary">
|
||||
200 derniers
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($blnShowLogs) {
|
||||
fxFicheAuditAdminRenderLogsTable($intEveLogs, $intLimitLogs, $arrLogs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array[] $arrLogs
|
||||
*/
|
||||
function fxFicheAuditAdminRenderLogsTable($intEveId, $intLimit, $arrLogs)
|
||||
{
|
||||
$intEveId = intval($intEveId);
|
||||
$intLimit = intval($intLimit);
|
||||
$intCount = is_array($arrLogs) ? count($arrLogs) : 0;
|
||||
?>
|
||||
<div class="card mb-3" id="fiche-audit-logs">
|
||||
<div class="card-header py-2 d-flex justify-content-between align-items-center">
|
||||
<strong>
|
||||
Logs — événement #<?= $intEveId ?>
|
||||
<span class="text-muted font-weight-normal">(<?= $intCount ?> / <?= $intLimit ?> max)</span>
|
||||
</strong>
|
||||
<a class="btn btn-sm btn-outline-secondary" href="fiche_audit.php">Fermer</a>
|
||||
</div>
|
||||
<div class="card-body p-0">
|
||||
<?php if ($intCount === 0) { ?>
|
||||
<p class="p-3 mb-0 text-muted">Aucun log pour cet événement.</p>
|
||||
<?php } else { ?>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-striped table-hover mb-0 small">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th>Quand</th>
|
||||
<th>Participant</th>
|
||||
<th>Champ</th>
|
||||
<th>Avant</th>
|
||||
<th>Après</th>
|
||||
<th>Par</th>
|
||||
<th>Source</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($arrLogs as $row) {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
$strNom = trim(
|
||||
(string)($row['par_prenom'] ?? '') . ' ' . (string)($row['par_nom'] ?? '')
|
||||
);
|
||||
if ($strNom === '') {
|
||||
$strNom = 'par#' . intval($row['par_id'] ?? 0);
|
||||
}
|
||||
$strBib = trim((string)($row['no_bib'] ?? ''));
|
||||
if ($strBib !== '') {
|
||||
$strNom .= ' · #' . $strBib;
|
||||
}
|
||||
$strField = (string)($row['field_key'] ?? '');
|
||||
if ($strField === 'last_touch') {
|
||||
$strField = 'dernière intervention';
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td class="text-nowrap"><?= htmlspecialchars((string)($row['created_at'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td><?= htmlspecialchars($strNom, ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td><code><?= htmlspecialchars($strField, ENT_QUOTES, 'UTF-8') ?></code></td>
|
||||
<td><?= htmlspecialchars((string)($row['old_value'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td><?= htmlspecialchars((string)($row['new_value'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td><?= htmlspecialchars((string)($row['changed_by_label'] ?? ''), ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td><code><?= htmlspecialchars((string)($row['source'] ?? ''), ENT_QUOTES, 'UTF-8') ?></code></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user