This commit enhances the error handling in the `ajax_inscr_gestion.php` file by introducing a shutdown function that captures fatal errors and returns a structured JSON response instead of a generic 500 error. Additionally, it adds diagnostic information for invalid actions, improving the debugging process. These changes aim to provide clearer feedback to users and developers when issues arise during AJAX requests.
164 lines
7.4 KiB
PHP
164 lines
7.4 KiB
PHP
<?php
|
|
/**
|
|
* Actions AJAX reservees a la fiche de gestion des inscriptions (v2).
|
|
* N'altere pas ajax_promoteur.php ni enregistrer.php (legacy promoteur).
|
|
*/
|
|
session_start();
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
// Filet de securite : transforme tout fatal (include manquant, fonction
|
|
// indefinie, parse error...) en reponse JSON exploitable au lieu d'un 500 muet.
|
|
$GLOBALS['__inscr_gestion_done'] = false;
|
|
register_shutdown_function(function () {
|
|
if (!empty($GLOBALS['__inscr_gestion_done'])) {
|
|
return;
|
|
}
|
|
$err = error_get_last();
|
|
$strDetail = ($err && in_array($err['type'], array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR), true))
|
|
? ($err['message'] . ' @ ' . $err['file'] . ':' . $err['line'])
|
|
: 'fatal inconnu';
|
|
error_log('[ajax_inscr_gestion] ' . $strDetail);
|
|
if (!headers_sent()) {
|
|
http_response_code(200);
|
|
}
|
|
echo json_encode(array('state' => 'error', 'message' => 'fatal', 'detail' => $strDetail));
|
|
});
|
|
|
|
require_once 'php/inc_fonctions.php';
|
|
require_once 'php/inc_fx_promoteur.php';
|
|
require_once 'php/inc_fx_inscriptions_gestion.php';
|
|
|
|
$intComId = intval($_SESSION['com_id'] ?? 0);
|
|
$strAction = trim((string)($_REQUEST['a'] ?? ''));
|
|
$strLangue = trim((string)($_REQUEST['lang'] ?? 'fr'));
|
|
if ($strLangue === '') {
|
|
$strLangue = 'fr';
|
|
}
|
|
|
|
if ($intComId <= 0) {
|
|
$GLOBALS['__inscr_gestion_done'] = true;
|
|
echo json_encode(array('state' => 'error', 'message' => 'session'));
|
|
exit;
|
|
}
|
|
|
|
$tabRetour = array('state' => 'error');
|
|
|
|
try {
|
|
switch ($strAction) {
|
|
case 'par_statut_course':
|
|
$intParId = intval($_REQUEST['par_id'] ?? 0);
|
|
$strStatut = trim((string)($_REQUEST['par_statut_course'] ?? ''));
|
|
$intEveId = fxEveAccesResolveEveIdFromParId($intParId);
|
|
|
|
if ($intEveId <= 0 || !fxInscrGestionCanDo($intComId, $intEveId, 'inscriptions_gestion.statut_edit')) {
|
|
$tabRetour = array('state' => 'error', 'message' => 'unauthorized');
|
|
break;
|
|
}
|
|
|
|
$tabRetour = fxSetParStatutCourse($intParId, $strStatut, $strLangue);
|
|
break;
|
|
|
|
case 'refund_form':
|
|
// Charge le formulaire de remboursement mutualise pour la fiche de gestion (panneau repliable).
|
|
$strNoPanier = trim((string)($_REQUEST['no_panier'] ?? ''));
|
|
if ($strNoPanier === '') {
|
|
$tabRetour = array('state' => 'error', 'message' => 'no_panier_manquant');
|
|
break;
|
|
}
|
|
|
|
// Meme source que le Super Admin : la commande vient de inscriptions_panier_acheteurs.
|
|
$sqlCmd = "SELECT *, IF(a.com_id <> 0, (SELECT c.com_login FROM inscriptions_comptes c WHERE a.com_id = c.com_id), '') AS usager"
|
|
. " FROM inscriptions_panier_acheteurs a, inscriptions_panier_statuts s"
|
|
. " WHERE s.sta_id = a.sta_id AND a.no_panier = '" . $objDatabase->fxEscape($strNoPanier) . "'";
|
|
$recCommandes = $objDatabase->fxGetRow($sqlCmd);
|
|
if (!$recCommandes) {
|
|
$tabRetour = array('state' => 'error', 'message' => 'commande_introuvable');
|
|
break;
|
|
}
|
|
|
|
// L'eve_id fait foi cote serveur (jamais le client) pour le controle d'acces a l'evenement.
|
|
$intEveId = intval($recCommandes['eve_id']);
|
|
if ($intEveId <= 0 || !fxInscrGestionCanDo($intComId, $intEveId, 'inscriptions_gestion.refund')) {
|
|
$tabRetour = array('state' => 'error', 'message' => 'unauthorized');
|
|
break;
|
|
}
|
|
|
|
// Module mutualise (ne tire jamais inc_functions.php "U") : voir superadm/php/inc_fx_paypal.php
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/superadm/php/inc_fx_paypal.php';
|
|
|
|
$strRefundToken = fxRefundEnsureToken();
|
|
$arrRefundCtx = fxRefundComputeContext($recCommandes);
|
|
|
|
// Auteur = promoteur connecte (alimente l'encart "Ajoute par" du formulaire).
|
|
$strAuteur = trim((string)($_SESSION['com_info']['com_prenom'] ?? '') . ' '
|
|
. (string)($_SESSION['com_info']['com_nom'] ?? ''));
|
|
|
|
// Markup seul (sans <script>, dernier param false) car injecte via innerHTML :
|
|
// le comportement (submit AJAX) est gere par le handler delegue dans inc_footer_scripts.php.
|
|
$strForm = fxRenderRefundForm($recCommandes, $strRefundToken, $arrRefundCtx, $vDomaine, $strAuteur, null, false);
|
|
|
|
// Resume de la facture (meme rendu que facture.php cote promoteur) : permet de voir ce qu'on rembourse.
|
|
// Affiche UNIQUEMENT cote promoteur ; en Super Admin on est deja dans le visuel de la facture.
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/inc_fx_panier.php';
|
|
$strResume = fxShowPanier($recCommandes['no_panier'], 0, 'web', 1, $strLangue);
|
|
|
|
// Libelles bilingues du bouton repliable.
|
|
$strLblShow = ($strLangue === 'en') ? 'Show transaction' : 'Afficher la transaction';
|
|
$strLblHide = ($strLangue === 'en') ? 'Hide transaction' : 'Masquer la transaction';
|
|
|
|
// Panneau repliable distinct (masque par defaut) : en-tete bleu + encadre + fond teinte,
|
|
// pour qu'il ressorte clairement comme une facture et ne se fonde pas dans la page.
|
|
$strResumeBlock =
|
|
'<details id="ms1-refund-resume" class="ms1-refund-resume"'
|
|
. ' style="margin-bottom:14px;border:1px solid #2d6cdf;border-radius:10px;background:#fff;overflow:hidden;box-shadow:0 1px 4px rgba(0,0,0,.12);">'
|
|
. '<summary style="cursor:pointer;list-style:none;padding:10px 14px;font-weight:600;color:#fff;background:#2d6cdf;">'
|
|
. '<span class="ms1-resume-when-closed">▸ ' . $strLblShow . '</span>'
|
|
. '<span class="ms1-resume-when-open">▾ ' . $strLblHide . '</span>'
|
|
. '</summary>'
|
|
. '<div style="padding:14px;background:#f4f7fc;border-top:1px solid #cfe0ff;">' . $strResume . '</div>'
|
|
. '</details>'
|
|
. '<style>'
|
|
. '#ms1-refund-resume[open] .ms1-resume-when-closed{display:none;}'
|
|
. '#ms1-refund-resume:not([open]) .ms1-resume-when-open{display:none;}'
|
|
. '#ms1-refund-resume summary::-webkit-details-marker{display:none;}'
|
|
. '</style>';
|
|
|
|
$strHtml = $strResumeBlock . $strForm;
|
|
|
|
$tabRetour = array('state' => 'ok', 'html' => $strHtml);
|
|
break;
|
|
|
|
default:
|
|
// DIAGNOSTIC TEMPORAIRE : expose ce que le serveur a reellement recu
|
|
// pour comprendre pourquoi l'action ne matche aucun case.
|
|
$tabRetour = array(
|
|
'state' => 'error',
|
|
'message' => 'invalid_action',
|
|
'debug' => array(
|
|
'a_recu' => $strAction,
|
|
'a_len' => strlen($strAction),
|
|
'request_keys' => array_keys($_REQUEST),
|
|
'post_keys' => array_keys($_POST),
|
|
'get_keys' => array_keys($_GET),
|
|
'method' => $_SERVER['REQUEST_METHOD'] ?? '',
|
|
'content_type' => $_SERVER['CONTENT_TYPE'] ?? '',
|
|
),
|
|
);
|
|
error_log('[ajax_inscr_gestion] invalid_action a=' . json_encode($strAction)
|
|
. ' REQUEST_keys=' . json_encode(array_keys($_REQUEST))
|
|
. ' POST_keys=' . json_encode(array_keys($_POST)));
|
|
break;
|
|
}
|
|
} catch (\Throwable $e) {
|
|
error_log('[ajax_inscr_gestion] ' . $e->getMessage() . ' @ ' . $e->getFile() . ':' . $e->getLine());
|
|
$tabRetour = array(
|
|
'state' => 'error',
|
|
'message' => 'exception',
|
|
'detail' => $e->getMessage() . ' @ ' . $e->getFile() . ':' . $e->getLine(),
|
|
);
|
|
}
|
|
|
|
$GLOBALS['__inscr_gestion_done'] = true;
|
|
echo json_encode($tabRetour);
|