269 lines
8.6 KiB
PHP
269 lines
8.6 KiB
PHP
<?php
|
||
/**
|
||
* MSIN-4574 — Lecture ChronoTrack (entries, index, comptage).
|
||
*/
|
||
|
||
/**
|
||
* Liste toutes les entries CT (pagination), dédupliquées par entry_id.
|
||
* Ne filtre pas sur external_id — décompte réel côté CT.
|
||
*/
|
||
function fxChronotrackApiSyncFetchAllCtEntryEntities($intCtEventId) {
|
||
$intCtEventId = intval($intCtEventId);
|
||
$tabAll = array();
|
||
$tabSeenEntryIds = array();
|
||
$intPage = 1;
|
||
$intPageSize = 200;
|
||
$intMaxPages = 500;
|
||
|
||
while ($intPage <= $intMaxPages) {
|
||
$arrApi = fxChronotrackApiOAuthApiGet('event/' . $intCtEventId . '/entry', array(
|
||
'page' => $intPage,
|
||
'page_size' => $intPageSize,
|
||
));
|
||
if ($arrApi['state'] !== 'ok') {
|
||
return array(
|
||
'state' => 'error',
|
||
'message' => $arrApi['message'] ?? 'Erreur lecture entries CT',
|
||
'entities' => $tabAll,
|
||
);
|
||
}
|
||
|
||
$arrEntities = fxChronotrackApiNormalizeEntityList($arrApi['json'], 'entry');
|
||
if (count($arrEntities) === 0) {
|
||
break;
|
||
}
|
||
|
||
foreach ($arrEntities as $arrEntity) {
|
||
if (!is_array($arrEntity)) {
|
||
continue;
|
||
}
|
||
$strEntryId = fxChronotrackApiEntityId($arrEntity);
|
||
if ($strEntryId === '' || isset($tabSeenEntryIds[$strEntryId])) {
|
||
continue;
|
||
}
|
||
$tabSeenEntryIds[$strEntryId] = true;
|
||
$tabAll[] = $arrEntity;
|
||
}
|
||
|
||
if (count($arrEntities) < $intPageSize) {
|
||
break;
|
||
}
|
||
$intPage++;
|
||
}
|
||
|
||
return array(
|
||
'state' => 'ok',
|
||
'message' => '',
|
||
'entities' => $tabAll,
|
||
'count' => count($tabAll),
|
||
);
|
||
}
|
||
|
||
function fxChronotrackApiSyncFetchCtEntriesIndexed($intCtEventId) {
|
||
$arrFetchAll = fxChronotrackApiSyncFetchAllCtEntryEntities($intCtEventId);
|
||
if ($arrFetchAll['state'] !== 'ok') {
|
||
return array(
|
||
'state' => 'error',
|
||
'message' => $arrFetchAll['message'] ?? 'Erreur lecture entries CT',
|
||
'entries' => array(),
|
||
);
|
||
}
|
||
|
||
$tabIndexed = array();
|
||
foreach ($arrFetchAll['entities'] as $arrEntity) {
|
||
if (!is_array($arrEntity)) {
|
||
continue;
|
||
}
|
||
$strExt = fxChronotrackApiEntityExternalId($arrEntity);
|
||
if ($strExt === '') {
|
||
continue;
|
||
}
|
||
$tabIndexed[$strExt] = $arrEntity;
|
||
}
|
||
|
||
return array(
|
||
'state' => 'ok',
|
||
'message' => '',
|
||
'entries' => $tabIndexed,
|
||
'entities' => $arrFetchAll['entities'],
|
||
'total_entry_count' => intval($arrFetchAll['count'] ?? count($arrFetchAll['entities'])),
|
||
'without_external_id'=> max(0, intval($arrFetchAll['count'] ?? 0) - count($tabIndexed)),
|
||
);
|
||
}
|
||
|
||
function fxChronotrackApiSyncFetchCtEntryRows($intCtEventId) {
|
||
$arrFetch = fxChronotrackApiSyncFetchAllCtEntryEntities($intCtEventId);
|
||
if ($arrFetch['state'] !== 'ok') {
|
||
return $arrFetch;
|
||
}
|
||
|
||
$tabRows = array();
|
||
foreach ($arrFetch['entities'] as $arrEntity) {
|
||
if (!is_array($arrEntity)) {
|
||
continue;
|
||
}
|
||
$strEntryId = fxChronotrackApiEntityId($arrEntity);
|
||
if ($strEntryId === '') {
|
||
continue;
|
||
}
|
||
$tabRows[] = array(
|
||
'entry_id' => $strEntryId,
|
||
'external_id' => fxChronotrackApiEntityExternalId($arrEntity),
|
||
'entity' => $arrEntity,
|
||
);
|
||
}
|
||
|
||
return array(
|
||
'state' => 'ok',
|
||
'message' => '',
|
||
'rows' => $tabRows,
|
||
'count' => count($tabRows),
|
||
);
|
||
}
|
||
|
||
/**
|
||
* MSIN-4328 — total entries CT Live (sans construire le diff MS1↔CT).
|
||
* Essaie d’abord un total dans la réponse API ; sinon compte par pagination légère.
|
||
*/
|
||
function fxChronotrackApiSyncExtractCtListTotal($mixJson) {
|
||
if (!is_array($mixJson)) {
|
||
return null;
|
||
}
|
||
$tabKeys = array(
|
||
'total', 'total_count', 'totalCount', 'count', 'entry_count', 'num_results',
|
||
'results_count', 'nb_results', 'total_entries',
|
||
);
|
||
foreach ($tabKeys as $strKey) {
|
||
if (isset($mixJson[$strKey]) && is_numeric($mixJson[$strKey])) {
|
||
$intVal = intval($mixJson[$strKey]);
|
||
if ($intVal >= 0) {
|
||
return $intVal;
|
||
}
|
||
}
|
||
}
|
||
foreach (array('pagination', 'page', 'meta', 'paging') as $strNest) {
|
||
if (!isset($mixJson[$strNest]) || !is_array($mixJson[$strNest])) {
|
||
continue;
|
||
}
|
||
$intNested = fxChronotrackApiSyncExtractCtListTotal($mixJson[$strNest]);
|
||
if ($intNested !== null) {
|
||
return $intNested;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* MSIN-4328 — total entries CT Live (+ backfill ct_entry_id si eve_id fourni).
|
||
*/
|
||
function fxChronotrackApiSyncFetchCtEntryCount($intCtEventId, $intEveId = 0) {
|
||
global $objDatabase;
|
||
|
||
$intCtEventId = intval($intCtEventId);
|
||
$intEveId = intval($intEveId);
|
||
if ($intCtEventId <= 0) {
|
||
return array('state' => 'error', 'message' => 'ct_event_id manquant', 'ct_total' => null);
|
||
}
|
||
|
||
$tabByExt = array();
|
||
if ($intEveId > 0) {
|
||
$sqlMap = "SELECT par_id, par_id_original FROM resultats_participants"
|
||
. " WHERE eve_id = " . $intEveId
|
||
. " AND is_cancelled = 0"
|
||
. " AND IFNULL(par_id_original, 0) > 0";
|
||
$arrMapRows = $objDatabase->fxGetResults($sqlMap);
|
||
if (is_array($arrMapRows)) {
|
||
for ($i = 1; $i <= count($arrMapRows); $i++) {
|
||
$strExt = (string)intval($arrMapRows[$i]['par_id_original']);
|
||
$tabByExt[$strExt] = intval($arrMapRows[$i]['par_id']);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Si pas de backfill et métadonnée total dispo → 1 appel.
|
||
if (count($tabByExt) === 0) {
|
||
$arrApi = fxChronotrackApiOAuthApiGet('event/' . $intCtEventId . '/entry', array(
|
||
'page' => 1,
|
||
'page_size' => 1,
|
||
));
|
||
if ($arrApi['state'] !== 'ok') {
|
||
return array(
|
||
'state' => 'error',
|
||
'message' => $arrApi['message'] ?? 'Erreur lecture entries CT',
|
||
'ct_total' => null,
|
||
);
|
||
}
|
||
$intFromMeta = fxChronotrackApiSyncExtractCtListTotal($arrApi['json'] ?? null);
|
||
if ($intFromMeta !== null) {
|
||
return array(
|
||
'state' => 'ok',
|
||
'message' => 'Total ChronoTrack Live (métadonnée API)',
|
||
'ct_total' => $intFromMeta,
|
||
'via' => 'meta',
|
||
'backfilled'=> 0,
|
||
);
|
||
}
|
||
}
|
||
|
||
$intTotal = 0;
|
||
$intBackfilled = 0;
|
||
$intPage = 1;
|
||
$intPageSize = 250;
|
||
$intMaxPages = 200;
|
||
while ($intPage <= $intMaxPages) {
|
||
$arrPage = fxChronotrackApiOAuthApiGet('event/' . $intCtEventId . '/entry', array(
|
||
'page' => $intPage,
|
||
'page_size' => $intPageSize,
|
||
));
|
||
if ($arrPage['state'] !== 'ok') {
|
||
return array(
|
||
'state' => 'error',
|
||
'message' => $arrPage['message'] ?? 'Erreur lecture entries CT',
|
||
'ct_total' => ($intTotal > 0) ? $intTotal : null,
|
||
'backfilled' => $intBackfilled,
|
||
);
|
||
}
|
||
$arrEntities = fxChronotrackApiNormalizeEntityList($arrPage['json'], 'entry');
|
||
$intN = count($arrEntities);
|
||
$intTotal += $intN;
|
||
|
||
if (count($tabByExt) > 0) {
|
||
$tabMetaPage = array();
|
||
foreach ($arrEntities as $arrEnt) {
|
||
if (!is_array($arrEnt)) {
|
||
continue;
|
||
}
|
||
$strExt = fxChronotrackApiEntityExternalId($arrEnt);
|
||
if ($strExt === '' || !isset($tabByExt[$strExt])) {
|
||
continue;
|
||
}
|
||
$tabMetaPage[] = array(
|
||
'par_id' => $tabByExt[$strExt],
|
||
'external_id' => $strExt,
|
||
);
|
||
}
|
||
if (count($tabMetaPage) > 0) {
|
||
$intBackfilled += fxChronotrackApiSyncApplyEntryIdsFromApiJson(
|
||
array('event_entry' => $arrEntities),
|
||
$tabMetaPage
|
||
);
|
||
}
|
||
}
|
||
|
||
if ($intN < $intPageSize) {
|
||
break;
|
||
}
|
||
$intPage++;
|
||
}
|
||
|
||
return array(
|
||
'state' => 'ok',
|
||
'message' => 'Total ChronoTrack Live (comptage paginé)'
|
||
. ($intBackfilled > 0 ? (' — ' . $intBackfilled . ' entry_id liés') : ''),
|
||
'ct_total' => $intTotal,
|
||
'via' => 'pages',
|
||
'backfilled' => $intBackfilled,
|
||
);
|
||
}
|
||
|