diff --git a/php/chronotrack_api/fx_chronotrack_admin.php b/php/chronotrack_api/fx_chronotrack_admin.php index c2de4c6..8efceba 100644 --- a/php/chronotrack_api/fx_chronotrack_admin.php +++ b/php/chronotrack_api/fx_chronotrack_admin.php @@ -232,15 +232,6 @@ function fxChronotrackApiAdminRenderPushPanel($intEveId, $blnClosed = false) { echo ' Actualiser '; echo ''; - echo '
'; - echo ' '; - echo ''; - echo ''; - echo 'Remise à zéro pour tests : passe les entries en WITHDRAWN via POST event/{id}/entry '; - echo '(même API que le push — DELETE est refusé par ChronoTrack). MS1 intact ; un push remet CONF.'; - echo '
'; echo '
'; echo ''; } @@ -754,8 +745,6 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed var intAlreadyCt = res.already_in_ct || 0; var intWillCreate = res.will_create || res.to_create || 0; var intCtTotal = res.ct_total || 0; - var intCtActive = (typeof res.ct_active !== 'undefined') ? res.ct_active : intCtTotal; - var intCtWithdrawn = res.ct_withdrawn || 0; var html = '

Avant le prochain push — lecture MS1 + ChronoTrack Live :

'; html += '
'; @@ -764,10 +753,7 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed html += '
'; html += '' + intBlocked + 'exclus
'; html += '
' + intAlreadyCt + 'déjà sur CT Live
'; - html += '
' + intCtActive + 'entries CT actives
'; - if (intCtWithdrawn > 0) { - html += '
' + intCtWithdrawn + 'WITHDRAWN
'; - } + html += '
' + intCtTotal + 'entries CT (total)
'; html += '
'; if (intTransfer > 0) { @@ -794,10 +780,6 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed $sum.html(html); renderBlockedPanel(res); $btn.prop('disabled', intTransfer <= 0); - var intCtActiveBtn = (objPushPreview && typeof objPushPreview.ct_active !== 'undefined') - ? objPushPreview.ct_active : intCtTotal; - $('#ct_api_btn_ct_wipe').prop('disabled', intCtActiveBtn <= 0); - $('#ct_api_btn_probe_withdraw').prop('disabled', intCtActiveBtn <= 0); } function renderPushResult(res, strTitle) { @@ -819,40 +801,6 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed }); strHtml += ''; } - if (res && res.delete_probe && res.delete_probe.attempts && res.delete_probe.attempts.length) { - strHtml += '

Sonde DELETE (entry ' - + escHtml(String(res.delete_probe.entry_id || '')) + ') :

'; - strHtml += ''; - } - if (res && typeof res.found_before !== 'undefined') { - strHtml += '

'; - if (typeof res.active_before !== 'undefined') { - strHtml += 'Actives avant : ' + escHtml(String(res.active_before)) + ''; - if (typeof res.active_after !== 'undefined' && res.active_after >= 0) { - strHtml += ' · actives après : ' + escHtml(String(res.active_after)) + ''; - } - } else { - strHtml += 'Entries API avant : ' + escHtml(String(res.found_before)) + ''; - if (typeof res.remaining_after !== 'undefined' && res.remaining_after >= 0) { - strHtml += ' · après : ' + escHtml(String(res.remaining_after)) + ''; - } - } - if (res.wipe_method) { - strHtml += ' · méthode : ' + escHtml(String(res.wipe_method)); - } - if (res.ct_event_id) { - strHtml += ' · event CT #' + escHtml(String(res.ct_event_id)); - } - strHtml += '

'; - } $res.html(strHtml); } @@ -907,75 +855,6 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed }); }); - $('#ct_api_btn_probe_withdraw').on('click', function () { - if (!window.confirm('Tester POST WITHDRAWN sur la première entry active ?\n\nSi ça réussit, cette entry sera retirée (statut WITHDRAWN).')) { - return; - } - var $btn = $(this); - var $res = $('#ct_api_push_result'); - $btn.prop('disabled', true); - $res.html(waitHtml('Sonde WITHDRAWN (1 entry)…')); - $.post(strAjaxUrl, { a: 'sync_probe_withdraw', eve_id: intEveId }, function (res) { - if (rejectIfSessionLost(res)) { - return; - } - var strClass = (res && (res.state === 'ok' || res.state === 'warning')) ? 'text-success' : 'text-danger'; - if (res && res.state === 'warning') { - strClass = 'text-warning'; - } - var strHtml = '
Sonde WITHDRAWN — ' - + escHtml((res && res.message) ? res.message : 'Erreur') + '
'; - if (res && res.payload) { - strHtml += '
'
-                        + escHtml(JSON.stringify(res.payload, null, 2)) + '
'; - } - if (res && res.status_before) { - strHtml += '

Statut : ' - + escHtml(res.status_before) + ' → ' + escHtml(res.status_after || '?') + '

'; - } - if (res && res.response_body) { - strHtml += '
'
-                        + escHtml(res.response_body) + '
'; - } - $res.html(strHtml); - if (res && res.state === 'ok') { - loadPushPreview(); - } - }, 'json').fail(function () { - $res.html('
Erreur réseau (sonde WITHDRAWN).
'); - }).always(function () { - $btn.prop('disabled', false); - }); - }); - - $('#ct_api_btn_ct_wipe').on('click', function () { - var intCtId = (objPushPreview && objPushPreview.ct_event_id) ? objPushPreview.ct_event_id : intLinkedCtEventId; - var intCtActive = (objPushPreview && typeof objPushPreview.ct_active !== 'undefined') - ? objPushPreview.ct_active : ((objPushPreview && objPushPreview.ct_total) ? objPushPreview.ct_total : 0); - var strConfirm = 'Retirer via l\'API (POST WITHDRAWN) toutes les entries actives ?\n\n'; - strConfirm += 'Event CT ID : ' + intCtId + '\n'; - strConfirm += 'Entries actives (CONF, etc.) : ' + intCtActive + '\n\n'; - strConfirm += 'MS1 ne sera pas modifié. Un push ultérieur remettra CONF.'; - if (!window.confirm(strConfirm)) { - return; - } - var $btn = $(this); - var $res = $('#ct_api_push_result'); - $btn.prop('disabled', true); - $res.html(waitHtml('Retrait WITHDRAWN des entries ChronoTrack Live…')); - $.post(strAjaxUrl, { a: 'sync_ct_wipe', eve_id: intEveId }, function (res) { - if (rejectIfSessionLost(res)) { - return; - } - renderPushResult(res, 'Retirer entries CT'); - loadPushPreview(); - }, 'json').fail(function () { - $res.html('
Erreur réseau (vider CT).
'); - }).always(function () { - $btn.prop('disabled', false); - }); - }); - $('#ct_api_btn_push').on('click', function () { if (!window.confirm('Envoyer les participants éligibles vers ChronoTrack ?\n\nMS1 ne sera pas modifié.')) { return; diff --git a/php/chronotrack_api/fx_chronotrack_oauth.php b/php/chronotrack_api/fx_chronotrack_oauth.php index 4a5b8b0..fcfc15c 100644 --- a/php/chronotrack_api/fx_chronotrack_oauth.php +++ b/php/chronotrack_api/fx_chronotrack_oauth.php @@ -168,274 +168,3 @@ function fxChronotrackApiOAuthApiPost($strPath, $mixBody, $arrQuery = array()) { 'http' => $arrHttp, ); } - -function fxChronotrackApiOAuthApiPut($strPath, $mixBody, $arrQuery = array()) { - $arrToken = fxChronotrackApiOAuthFetchToken(false); - if ($arrToken['state'] !== 'ok') { - return $arrToken; - } - - $arrQuery['client_id'] = fxChronotrackApiGetClientId(); - $strUrl = fxChronotrackApiGetApiBaseUrl() . '/' . ltrim($strPath, '/'); - if (!empty($arrQuery)) { - $strUrl .= '?' . http_build_query($arrQuery); - } - - $strBody = json_encode($mixBody, JSON_UNESCAPED_UNICODE); - if (!is_string($strBody)) { - return array('state' => 'error', 'message' => 'json_encode a échoué'); - } - - $arrHttp = fxChronotrackApiHttpRequest('PUT', $strUrl, array( - 'headers' => array( - 'Authorization: Bearer ' . $arrToken['access_token'], - 'Content-Type: application/json', - 'Accept: application/json', - ), - 'body' => $strBody, - )); - - if ($arrHttp['state'] === 'ok') { - return array('state' => 'ok', 'json' => $arrHttp['json'], 'http' => $arrHttp); - } - - return array( - 'state' => 'error', - 'message' => fxChronotrackApiHttpGetJsonErrorMessage($arrHttp), - 'http' => $arrHttp, - ); -} - -function fxChronotrackApiOAuthFetchTokenInline($arrExtraQuery = array()) { - if (!fxChronotrackApiSettingsConfigured()) { - return array('state' => 'error', 'message' => fxChronotrackApiSettingsErrorMessage()); - } - - $arrQuery = array_merge(array( - 'grant_type' => 'password', - 'username' => fxChronotrackApiGetServiceUser(), - 'password' => fxChronotrackApiGetServicePass(), - ), $arrExtraQuery); - - $strUrl = fxChronotrackApiGetBaseUrl() . '/oauth2/token?' . http_build_query($arrQuery); - $arrHttp = fxChronotrackApiHttpRequest('GET', $strUrl, array( - 'basic_user' => fxChronotrackApiGetClientId(), - 'basic_pass' => fxChronotrackApiGetClientSecret(), - )); - - if ($arrHttp['state'] !== 'ok' || !is_array($arrHttp['json'])) { - return array( - 'state' => 'error', - 'message' => fxChronotrackApiHttpGetJsonErrorMessage($arrHttp), - ); - } - - $strToken = trim((string)($arrHttp['json']['access_token'] ?? '')); - if ($strToken === '') { - return array('state' => 'error', 'message' => 'access_token absent (token inline)'); - } - - return array('state' => 'ok', 'access_token' => $strToken); -} - -function fxChronotrackApiOAuthApiDelete($strPath, $arrQuery = array(), $arrOptions = array()) { - $strAccessToken = ''; - if (!empty($arrOptions['access_token'])) { - $strAccessToken = trim((string)$arrOptions['access_token']); - } else { - $arrToken = fxChronotrackApiOAuthFetchToken(false); - if ($arrToken['state'] !== 'ok') { - return $arrToken; - } - $strAccessToken = $arrToken['access_token']; - } - - $arrQuery['client_id'] = fxChronotrackApiGetClientId(); - $strUrl = fxChronotrackApiGetApiBaseUrl() . '/' . ltrim($strPath, '/'); - if (!empty($arrQuery)) { - $strUrl .= '?' . http_build_query($arrQuery); - } - - $arrHeaders = array( - 'Authorization: Bearer ' . $strAccessToken, - 'Accept: application/json', - ); - if (!empty($arrOptions['headers']) && is_array($arrOptions['headers'])) { - $arrHeaders = array_merge($arrHeaders, $arrOptions['headers']); - } - - $strMethod = 'DELETE'; - if (!empty($arrOptions['method_override'])) { - $strMethod = 'POST'; - $arrHeaders[] = 'X-Http-Method-Override: ' . trim((string)$arrOptions['method_override']); - } - - $arrHttp = fxChronotrackApiHttpRequest($strMethod, $strUrl, array( - 'headers' => $arrHeaders, - 'body' => isset($arrOptions['body']) ? $arrOptions['body'] : null, - )); - - if ($arrHttp['state'] === 'ok') { - return array('state' => 'ok', 'json' => $arrHttp['json'], 'http' => $arrHttp); - } - - return array( - 'state' => 'error', - 'message' => fxChronotrackApiHttpGetJsonErrorMessage($arrHttp), - 'http' => $arrHttp, - ); -} - -/** - * DELETE entry — CT exige un contexte « activity » (souvent = event_id) que la doc DELETE ne mentionne pas. - */ -function fxChronotrackApiOAuthApiDeleteEntryAttempts($intCtEventId, $strEntryId) { - $intCtEventId = intval($intCtEventId); - $strEntryId = trim((string)$strEntryId); - $tabAttempts = array(); - - if ($intCtEventId > 0) { - $tabAttempts[] = array( - 'path' => 'event/' . $intCtEventId . '/entry/' . $strEntryId, - 'query' => array(), - 'label' => 'DELETE event/{event_id}/entry/{entry_id}', - ); - $tabAttempts[] = array( - 'path' => 'entry/' . $strEntryId, - 'query' => array('activity' => $intCtEventId), - 'label' => 'DELETE entry/{id}?activity={event_id}', - ); - $tabAttempts[] = array( - 'path' => 'entry/' . $strEntryId, - 'query' => array('event_id' => $intCtEventId), - 'label' => 'DELETE entry/{id}?event_id={event_id}', - ); - $tabAttempts[] = array( - 'path' => 'entry/' . $strEntryId, - 'query' => array('activity' => $intCtEventId), - 'label' => 'POST+Override DELETE entry/{id}?activity=', - 'options' => array('method_override' => 'DELETE'), - ); - $tabAttempts[] = array( - 'path' => 'event/' . $intCtEventId . '/entry/' . $strEntryId, - 'query' => array(), - 'label' => 'POST+Override DELETE event/{event_id}/entry/{entry_id}', - 'options' => array('method_override' => 'DELETE'), - ); - foreach (array('Activity', 'X-Activity-Id', 'X-ChronoTrack-Activity') as $strHeaderName) { - $tabAttempts[] = array( - 'path' => 'entry/' . $strEntryId, - 'query' => array(), - 'label' => 'DELETE entry/{id} + header ' . $strHeaderName . ':{event_id}', - 'options' => array('headers' => array($strHeaderName . ': ' . $intCtEventId)), - ); - } - $tabAttempts[] = array( - 'path' => 'entry/' . $strEntryId, - 'query' => array('activity' => $intCtEventId), - 'label' => 'DELETE entry/{id}?activity= + token OAuth ?activity=', - 'token_activity' => $intCtEventId, - ); - } - - $tabAttempts[] = array( - 'path' => 'entry/' . $strEntryId, - 'query' => array(), - 'label' => 'DELETE entry/{id} (doc CT)', - ); - - return $tabAttempts; -} - -function fxChronotrackApiOAuthApiDeleteEntryAttempt($arrAttempt) { - $arrOptions = isset($arrAttempt['options']) && is_array($arrAttempt['options']) ? $arrAttempt['options'] : array(); - - if (!empty($arrAttempt['token_activity'])) { - $arrToken = fxChronotrackApiOAuthFetchTokenInline(array( - 'activity' => intval($arrAttempt['token_activity']), - )); - if ($arrToken['state'] !== 'ok') { - return $arrToken; - } - $arrOptions['access_token'] = $arrToken['access_token']; - } - - return fxChronotrackApiOAuthApiDelete($arrAttempt['path'], $arrAttempt['query'] ?? array(), $arrOptions); -} - -function fxChronotrackApiOAuthApiDeleteEntryProbe($intCtEventId, $strEntryId) { - $strEntryId = trim((string)$strEntryId); - if ($strEntryId === '') { - return array('state' => 'error', 'message' => 'entry_id manquant'); - } - - $tabResults = array(); - $arrWin = null; - - foreach (fxChronotrackApiOAuthApiDeleteEntryAttempts($intCtEventId, $strEntryId) as $arrAttempt) { - $arrDel = fxChronotrackApiOAuthApiDeleteEntryAttempt($arrAttempt); - $intCode = intval($arrDel['http']['http_code'] ?? 0); - $tabResults[] = array( - 'label' => $arrAttempt['label'], - 'http' => $intCode, - 'message' => ($arrDel['state'] === 'ok') ? 'OK' : ($arrDel['message'] ?? 'erreur'), - ); - if ($arrDel['state'] === 'ok' && $arrWin === null) { - $arrWin = $arrAttempt; - } - } - - return array( - 'state' => ($arrWin !== null) ? 'ok' : 'error', - 'entry_id' => $strEntryId, - 'ct_event_id' => intval($intCtEventId), - 'attempts' => $tabResults, - 'working_label'=> ($arrWin !== null) ? ($arrWin['label'] ?? '') : '', - 'message' => ($arrWin !== null) - ? 'DELETE OK via ' . ($arrWin['label'] ?? '') - : 'Aucune variante DELETE n\'a réussi (voir attempts).', - ); -} - -function fxChronotrackApiOAuthApiDeleteEntry($intCtEventId, $strEntryId, $strKnownLabel = null) { - $strEntryId = trim((string)$strEntryId); - if ($strEntryId === '') { - return array('state' => 'error', 'message' => 'entry_id manquant'); - } - - $tabAttempts = fxChronotrackApiOAuthApiDeleteEntryAttempts($intCtEventId, $strEntryId); - if ($strKnownLabel !== null && $strKnownLabel !== '') { - foreach ($tabAttempts as $arrAttempt) { - if ($arrAttempt['label'] === $strKnownLabel) { - $tabAttempts = array($arrAttempt); - break; - } - } - } - - $strLastMessage = 'Erreur DELETE entry'; - $tabTried = array(); - - foreach ($tabAttempts as $arrAttempt) { - $arrDel = fxChronotrackApiOAuthApiDeleteEntryAttempt($arrAttempt); - $tabTried[] = $arrAttempt['label']; - if ($arrDel['state'] === 'ok') { - $arrDel['delete_path'] = $arrAttempt['label']; - return $arrDel; - } - $strLastMessage = $arrDel['message'] ?? $strLastMessage; - $intCode = intval($arrDel['http']['http_code'] ?? 0); - if ($intCode === 401 && stripos($strLastMessage, 'activity') !== false) { - continue; - } - if ($intCode === 404) { - continue; - } - } - - return array( - 'state' => 'error', - 'message' => $strLastMessage, - 'delete_tried'=> $tabTried, - ); -} diff --git a/php/chronotrack_api/fx_chronotrack_sync.php b/php/chronotrack_api/fx_chronotrack_sync.php index fa4671f..bd51c44 100644 --- a/php/chronotrack_api/fx_chronotrack_sync.php +++ b/php/chronotrack_api/fx_chronotrack_sync.php @@ -551,7 +551,7 @@ function fxChronotrackApiSyncProbePush($intEveId) { /** * Liste toutes les entries CT (pagination), dédupliquées par entry_id. - * Ne filtre pas sur external_id — requis pour le wipe et le décompte réel. + * Ne filtre pas sur external_id — décompte réel côté CT. */ function fxChronotrackApiSyncFetchAllCtEntryEntities($intCtEventId) { $intCtEventId = intval($intCtEventId); @@ -666,312 +666,6 @@ function fxChronotrackApiSyncFetchCtEntryRows($intCtEventId) { ); } -function fxChronotrackApiSyncEntryRowStatus(array $arrRow) { - $arrEntity = $arrRow['entity'] ?? array(); - if (!is_array($arrEntity)) { - return ''; - } - return strtoupper(trim(fxChronotrackApiRaceField($arrEntity, array('entry_status', 'status')))); -} - -function fxChronotrackApiSyncIsCtEntryWithdrawn(array $arrRow) { - $strStatus = fxChronotrackApiSyncEntryRowStatus($arrRow); - return in_array($strStatus, array('WITHDRAWN', 'WD', 'CANCELLED', 'CANCEL', 'REFUND'), true); -} - -function fxChronotrackApiSyncSummarizeCtEntryRows(array $tabRows) { - $intWithdrawn = 0; - foreach ($tabRows as $arrRow) { - if (fxChronotrackApiSyncIsCtEntryWithdrawn($arrRow)) { - $intWithdrawn++; - } - } - $intTotal = count($tabRows); - return array( - 'total' => $intTotal, - 'active' => max(0, $intTotal - $intWithdrawn), - 'withdrawn' => $intWithdrawn, - ); -} - -function fxChronotrackApiSyncBuildWithdrawPayload(array $arrRow, $strStatus = 'WITHDRAWN') { - $arrEntity = $arrRow['entity'] ?? array(); - $arrPayload = array( - 'entry_status' => strtoupper(trim((string)$strStatus)), - ); - - $strEntryId = trim((string)($arrRow['entry_id'] ?? '')); - if ($strEntryId !== '') { - $arrPayload['entry_id'] = $strEntryId; - } - - $strExternalId = trim((string)($arrRow['external_id'] ?? '')); - if ($strExternalId !== '') { - $arrPayload['external_id'] = $strExternalId; - } - - if (is_array($arrEntity)) { - $intRaceId = intval(fxChronotrackApiRaceField($arrEntity, array('race_id', 'event_race_id'))); - if ($intRaceId > 0) { - $arrPayload['race_id'] = $intRaceId; - } - $strBib = fxChronotrackApiRaceField($arrEntity, array('bib', 'bib_number', 'entry_bib')); - if ($strBib !== '') { - $arrPayload['bib'] = $strBib; - } - } - - return $arrPayload; -} - -function fxChronotrackApiSyncFindCtEntryRowById($intCtEventId, $strEntryId) { - $arrFetch = fxChronotrackApiSyncFetchCtEntryRows($intCtEventId); - if ($arrFetch['state'] !== 'ok') { - return null; - } - foreach ($arrFetch['rows'] as $arrRow) { - if ((string)$arrRow['entry_id'] === (string)$strEntryId) { - return $arrRow; - } - } - return null; -} - -function fxChronotrackApiSyncWithdrawEntriesBatch($intCtEventId, array $tabPayloads) { - if (count($tabPayloads) === 0) { - return array('state' => 'error', 'message' => 'Lot WITHDRAWN vide'); - } - return fxChronotrackApiSyncPostEntries($intCtEventId, $tabPayloads); -} - -function fxChronotrackApiSyncProbeWithdraw($intEveId) { - $arrConfig = fxChronotrackApiConfigGet($intEveId); - if ($arrConfig === null) { - return array('state' => 'error', 'message' => 'Événement non lié à ChronoTrack'); - } - - $intCtEventId = intval($arrConfig['ct_event_id']); - $arrFetch = fxChronotrackApiSyncFetchCtEntryRows($intCtEventId); - if ($arrFetch['state'] !== 'ok') { - return $arrFetch; - } - - $arrTarget = null; - foreach ($arrFetch['rows'] as $arrRow) { - if (!fxChronotrackApiSyncIsCtEntryWithdrawn($arrRow)) { - $arrTarget = $arrRow; - break; - } - } - if ($arrTarget === null) { - return array('state' => 'warning', 'message' => 'Aucune entry active à retirer (toutes déjà WITHDRAWN ?).'); - } - - $strEntryId = (string)$arrTarget['entry_id']; - $strStatusBefore = fxChronotrackApiSyncEntryRowStatus($arrTarget); - $arrPayload = fxChronotrackApiSyncBuildWithdrawPayload($arrTarget, 'WITHDRAWN'); - $arrPost = fxChronotrackApiSyncWithdrawEntriesBatch($intCtEventId, array($arrPayload)); - - $arrRet = array( - 'state' => $arrPost['state'], - 'message' => $arrPost['message'] ?? '', - 'ct_event_id' => $intCtEventId, - 'entry_id' => $strEntryId, - 'external_id' => $arrTarget['external_id'] ?? '', - 'status_before' => $strStatusBefore, - 'payload' => $arrPayload, - 'http_code' => intval($arrPost['http']['http_code'] ?? 0), - 'response_body' => substr(trim((string)($arrPost['http']['body'] ?? '')), 0, 2000), - 'method' => 'POST event/{id}/entry + entry_status=WITHDRAWN', - ); - - $arrAfter = fxChronotrackApiSyncFindCtEntryRowById($intCtEventId, $strEntryId); - if ($arrAfter !== null) { - $strStatusAfter = fxChronotrackApiSyncEntryRowStatus($arrAfter); - $arrRet['status_after'] = $strStatusAfter; - if ($arrPost['state'] === 'ok' && fxChronotrackApiSyncIsCtEntryWithdrawn($arrAfter)) { - $arrRet['state'] = 'ok'; - $arrRet['message'] = 'Entry ' . $strEntryId . ' retirée (statut ' . $strStatusBefore - . ' → ' . $strStatusAfter . ') via POST WITHDRAWN.'; - } elseif ($arrPost['state'] === 'ok') { - $arrRet['state'] = 'warning'; - $arrRet['message'] = 'POST HTTP OK mais statut CT inchangé (' . $strStatusAfter - . '). Vérifier le nom du champ entry_status côté CT.'; - } - } - - return $arrRet; -} - -function fxChronotrackApiSyncWithdrawCtEvent($intEveId) { - $arrConfig = fxChronotrackApiConfigGet($intEveId); - if ($arrConfig === null) { - return array('state' => 'error', 'message' => 'Événement non lié à ChronoTrack'); - } - - if (!fxChronotrackApiSettingsConfigured()) { - return array('state' => 'error', 'message' => fxChronotrackApiSettingsErrorMessage()); - } - - $intCtEventId = intval($arrConfig['ct_event_id']); - $arrFetch = fxChronotrackApiSyncFetchCtEntryRows($intCtEventId); - if ($arrFetch['state'] !== 'ok') { - return $arrFetch; - } - - $arrSummaryBefore = fxChronotrackApiSyncSummarizeCtEntryRows($arrFetch['rows']); - $tabActiveRows = array(); - foreach ($arrFetch['rows'] as $arrRow) { - if (!fxChronotrackApiSyncIsCtEntryWithdrawn($arrRow)) { - $tabActiveRows[] = $arrRow; - } - } - - if (count($tabActiveRows) === 0) { - return array( - 'state' => 'warning', - 'message' => 'Aucune entry active sur CT #' . $intCtEventId - . ' (' . $arrSummaryBefore['withdrawn'] . ' déjà WITHDRAWN sur ' - . $arrSummaryBefore['total'] . '). MS1 intact.', - 'ct_event_id' => $intCtEventId, - 'found_before' => $arrSummaryBefore['total'], - 'active_before' => 0, - 'withdrawn_ok' => 0, - 'withdrawn_error' => 0, - 'active_after' => 0, - 'remaining_after' => $arrSummaryBefore['total'], - 'wipe_method' => 'withdraw_post', - 'errors' => array(), - ); - } - - $arrProbe = fxChronotrackApiSyncProbeWithdraw($intEveId); - if ($arrProbe['state'] !== 'ok' && $arrProbe['state'] !== 'warning') { - return array( - 'state' => 'error', - 'message' => 'Impossible de retirer les entries via POST WITHDRAWN (sonde entry ' - . ($arrProbe['entry_id'] ?? '?') . ') : ' . ($arrProbe['message'] ?? 'erreur'), - 'ct_event_id' => $intCtEventId, - 'found_before' => $arrSummaryBefore['total'], - 'active_before' => count($tabActiveRows), - 'withdrawn_ok' => 0, - 'withdrawn_error' => count($tabActiveRows), - 'active_after' => count($tabActiveRows), - 'remaining_after' => $arrSummaryBefore['total'], - 'wipe_method' => 'withdraw_post', - 'withdraw_probe' => $arrProbe, - 'errors' => array($arrProbe['message'] ?? 'Erreur sonde WITHDRAWN'), - ); - } - - $intOk = ($arrProbe['state'] === 'ok') ? 1 : 0; - $intErr = 0; - $tabErrors = array(); - $intBatchSize = MSIN_API_CHRONOTRACK_SYNC_BATCH_SIZE; - $intStartIdx = ($arrProbe['state'] === 'ok') ? 1 : 0; - - for ($intIdx = $intStartIdx; $intIdx < count($tabActiveRows); $intIdx += $intBatchSize) { - $tabBatch = array(); - $tabBatchMeta = array(); - for ($intJ = $intIdx; $intJ < min($intIdx + $intBatchSize, count($tabActiveRows)); $intJ++) { - $arrRow = $tabActiveRows[$intJ]; - $tabBatch[] = fxChronotrackApiSyncBuildWithdrawPayload($arrRow, 'WITHDRAWN'); - $tabBatchMeta[] = $arrRow; - } - - $arrPost = fxChronotrackApiSyncWithdrawEntriesBatch($intCtEventId, $tabBatch); - if ($arrPost['state'] === 'ok') { - $intOk += count($tabBatch); - foreach ($tabBatchMeta as $arrRow) { - fxChronotrackApiSyncLog( - $intEveId, - 0, - 'ct_withdraw_entry', - 'ok', - 'entry_id=' . $arrRow['entry_id'] . ' external_id=' . ($arrRow['external_id'] ?? '') - ); - } - continue; - } - - $intErr += count($tabBatch); - $strMsg = $arrPost['message'] ?? 'Erreur POST WITHDRAWN'; - if (count($tabErrors) < 10) { - $tabErrors[] = 'lot ' . ($intIdx + 1) . '-' . min($intIdx + $intBatchSize, count($tabActiveRows)) - . ' — ' . $strMsg; - } - foreach ($tabBatchMeta as $arrRow) { - fxChronotrackApiSyncLog( - $intEveId, - 0, - 'ct_withdraw_entry', - 'error', - 'entry_id=' . $arrRow['entry_id'] . ' — ' . $strMsg - ); - } - } - - $arrFetchAfter = fxChronotrackApiSyncFetchCtEntryRows($intCtEventId); - $arrSummaryAfter = ($arrFetchAfter['state'] === 'ok') - ? fxChronotrackApiSyncSummarizeCtEntryRows($arrFetchAfter['rows']) - : array('total' => -1, 'active' => -1, 'withdrawn' => -1); - - $intActiveAfter = intval($arrSummaryAfter['active']); - if ($intActiveAfter === 0 && $intErr === 0) { - $strState = 'ok'; - $strMessage = $intOk . ' entry(s) retirée(s) (WITHDRAWN) sur ChronoTrack Live (event #' . $intCtEventId . ').'; - $strMessage .= ' Actives restantes : 0. MS1 intact — un push remettra CONF.'; - } elseif ($intOk > 0) { - $strState = 'partial'; - $strMessage = $intOk . ' retirée(s), ' . $intErr . ' erreur(s).'; - if ($intActiveAfter >= 0) { - $strMessage .= ' Actives restantes : ' . $intActiveAfter . '.'; - } - } else { - $strState = 'error'; - $strMessage = 'Échec retrait WITHDRAWN (' . $intErr . ' erreur(s)).'; - } - - return array( - 'state' => $strState, - 'message' => $strMessage, - 'ct_event_id' => $intCtEventId, - 'found_before' => $arrSummaryBefore['total'], - 'active_before' => count($tabActiveRows), - 'withdrawn_ok' => $intOk, - 'withdrawn_error' => $intErr, - 'active_after' => $intActiveAfter, - 'remaining_after' => intval($arrSummaryAfter['total']), - 'wipe_method' => 'withdraw_post', - 'errors' => $tabErrors, - ); -} - -function fxChronotrackApiSyncProbeDelete($intEveId) { - $arrConfig = fxChronotrackApiConfigGet($intEveId); - if ($arrConfig === null) { - return array('state' => 'error', 'message' => 'Événement non lié à ChronoTrack'); - } - - $intCtEventId = intval($arrConfig['ct_event_id']); - $arrFetch = fxChronotrackApiSyncFetchCtEntryRows($intCtEventId); - if ($arrFetch['state'] !== 'ok') { - return $arrFetch; - } - if (count($arrFetch['rows']) === 0) { - return array('state' => 'warning', 'message' => 'Aucune entry CT à tester (GET event/' . $intCtEventId . '/entry).'); - } - - $strEntryId = (string)$arrFetch['rows'][0]['entry_id']; - $arrProbe = fxChronotrackApiOAuthApiDeleteEntryProbe($intCtEventId, $strEntryId); - $arrProbe['external_id'] = $arrFetch['rows'][0]['external_id'] ?? ''; - return $arrProbe; -} - -function fxChronotrackApiSyncWipeCtEvent($intEveId) { - return fxChronotrackApiSyncWithdrawCtEvent($intEveId); -} - function fxChronotrackApiSyncBuildPreview($intEveId) { $arrConfig = fxChronotrackApiConfigGet($intEveId); if ($arrConfig === null) { @@ -1005,12 +699,6 @@ function fxChronotrackApiSyncBuildPreview($intEveId) { $tabCtEntries = $arrCtFetch['entries']; $intCtTotal = intval($arrCtFetch['total_entry_count'] ?? count($tabCtEntries)); $intCtWithoutExt = intval($arrCtFetch['without_external_id'] ?? 0); - $arrCtStats = array('total' => $intCtTotal, 'active' => $intCtTotal, 'withdrawn' => 0); - $arrCtRowsFetch = fxChronotrackApiSyncFetchCtEntryRows($intCtEventId); - if ($arrCtRowsFetch['state'] === 'ok') { - $arrCtStats = fxChronotrackApiSyncSummarizeCtEntryRows($arrCtRowsFetch['rows']); - } - $intCtActive = intval($arrCtStats['active']); $intAlreadyInCt = 0; $intToCreate = 0; @@ -1050,8 +738,6 @@ function fxChronotrackApiSyncBuildPreview($intEveId) { 'duplicate_bib_numbers' => $arrClass['duplicate_bib_numbers'], 'anomalies' => $arrClass['blocked'], 'ct_total' => $intCtTotal, - 'ct_active' => $intCtActive, - 'ct_withdrawn' => intval($arrCtStats['withdrawn']), 'already_in_ct' => $intAlreadyInCt, 'will_update' => $intAlreadyInCt, 'to_create' => $intToCreate, diff --git a/superadm/ajax_chronotrack_api.php b/superadm/ajax_chronotrack_api.php index 3d548a4..fb8e1f2 100644 --- a/superadm/ajax_chronotrack_api.php +++ b/superadm/ajax_chronotrack_api.php @@ -103,24 +103,6 @@ switch ($strAction) { $tabRetour = fxChronotrackApiSyncProbePush($intEveId); break; - case 'sync_probe_delete': - if ($intEveId <= 0) { - $tabRetour = array('state' => 'error', 'message' => 'eve_id manquant'); - break; - } - set_time_limit(120); - $tabRetour = fxChronotrackApiSyncProbeDelete($intEveId); - break; - - case 'sync_probe_withdraw': - if ($intEveId <= 0) { - $tabRetour = array('state' => 'error', 'message' => 'eve_id manquant'); - break; - } - set_time_limit(120); - $tabRetour = fxChronotrackApiSyncProbeWithdraw($intEveId); - break; - case 'sync_push': if ($intEveId <= 0) { $tabRetour = array('state' => 'error', 'message' => 'eve_id manquant'); @@ -130,15 +112,6 @@ switch ($strAction) { $tabRetour = fxChronotrackApiSyncPushEvent($intEveId); break; - case 'sync_ct_wipe': - if ($intEveId <= 0) { - $tabRetour = array('state' => 'error', 'message' => 'eve_id manquant'); - break; - } - set_time_limit(600); - $tabRetour = fxChronotrackApiSyncWipeCtEvent($intEveId); - break; - default: break; }