pushHandler(new StreamHandler('php://stderr', Logger::ERROR));
// Connexion BDD
$dbConnection = new DatabaseConnection($logger, $config->getSection('database'));
$pdo = $dbConnection->getConnection();
// Charger le produit
$stmt = $pdo->prepare("SELECT * FROM eex_v2_mega_catalog WHERE id = ? AND provider = 'EEX'");
$stmt->execute([$productId]);
$product = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$product) {
die("❌ Produit EEX #$productId introuvable");
}
?>
$message
";
flush();
}
try {
$startTime = microtime(true);
logMessage("
🚀 DÉMARRAGE SCRAPING EEX", 'step');
logMessage("Produit : {$product['product_name']}", 'info');
logMessage("Code API : {$product['api_symbol']}", 'data');
logMessage("Type : {$product['product_type']}", 'info');
logMessage("", 'info');
// Calcul du nombre de jours en arrière
$targetDateObj = new DateTime($date);
$today = new DateTime();
$daysBack = (int)$today->diff($targetDateObj)->days;
logMessage("📅 Date cible : {$date} (il y a {$daysBack} jour(s))", 'data');
logMessage("", 'info');
// Vérifier le type de produit
$productType = $product['product_type'];
$apiSymbol = $product['api_symbol'];
if (in_array($productType, ['POWER_FUTURE', 'GAS_FUTURE', 'CO2_FUTURE', 'GO'])) {
// === FUTURES ===
logMessage("
ÉTAPE 1 : Scraping FUTURES", 'step');
logMessage("💡 Mode : Code générique (récupère TOUS les contrats de la famille)", 'info');
logMessage("", 'info');
// Créer le client API
$apiClient = new EexApiClient($logger, $daysBack);
logMessage("🌐 Appel API EEX Futures...", 'step');
logMessage(" → Méthode : getFutures()", 'data');
logMessage(" → Code : {$apiSymbol}", 'data');
logMessage(" → Jours en arrière : {$daysBack}", 'data');
logMessage("", 'info');
// Appel API
$rawData = $apiClient->getFutures($apiSymbol, $daysBack);
if (empty($rawData)) {
logMessage("⚠️ Aucune donnée retournée par l'API", 'warning');
logMessage("💡 Raisons possibles :", 'info');
logMessage(" - Marché fermé ce jour-là (week-end/férié)", 'info');
logMessage(" - Données pas encore disponibles", 'info');
logMessage(" - Code produit invalide", 'info');
$recordsInserted = 0;
} else {
$contractCount = count($rawData);
logMessage("✅ {$contractCount} contrats reçus de l'API", 'success');
logMessage("", 'info');
// Aperçu des contrats
logMessage("
ÉTAPE 2 : Aperçu des contrats", 'step');
$preview = array_slice($rawData, 0, 5);
foreach ($preview as $idx => $contract) {
$symbol = $contract['pricesymbol'] ?? $contract['productCode'] ?? 'N/A';
$price = $contract['close'] ?? $contract['settlementPrice'] ?? 'N/A';
$volume = $contract['onexchtradevolumeeex'] ?? $contract['volume'] ?? 'N/A';
logMessage(" " . ($idx + 1) . ". {$symbol} - Prix: {$price} - Volume: {$volume}", 'data');
}
if ($contractCount > 5) {
logMessage(" ... et " . ($contractCount - 5) . " autres contrats", 'data');
}
logMessage("", 'info');
// Insertion en base
logMessage("
ÉTAPE 3 : Insertion en base de données", 'step');
$futuresRepo = new FuturesRepository($pdo, $logger);
$inserted = 0;
$errors = 0;
foreach ($rawData as $contractData) {
try {
$futuresRepo->insertFutureData($contractData);
$inserted++;
} catch (Throwable $e) {
// Les doublons sont ignorés
if (!str_contains($e->getMessage(), 'Duplicate entry')) {
$errors++;
if ($errors <= 3) {
logMessage("⚠️ Erreur : " . $e->getMessage(), 'warning');
}
}
}
}
if ($errors > 3) {
logMessage("⚠️ ... et " . ($errors - 3) . " autres erreurs", 'warning');
}
$recordsInserted = $inserted;
logMessage("✅ {$inserted} enregistrements insérés (doublons ignorés)", 'success');
}
} elseif ($productType === 'GAS_SPOT') {
// === GAS SPOT ===
logMessage("
ÉTAPE 1 : Scraping GAS SPOT", 'step');
logMessage("⚠️ Le scraping Gas Spot nécessite une implémentation spécifique", 'warning');
logMessage("💡 À implémenter avec getSpot()", 'info');
$recordsInserted = 0;
} else {
logMessage("❌ Type de produit non supporté : {$productType}", 'error');
$recordsInserted = -1;
}
$duration = round(microtime(true) - $startTime, 2);
logMessage("", 'info');
logMessage("
🎉 SCRAPING TERMINÉ", 'success');
logMessage("⏱️ Durée : {$duration}s", 'info');
} catch (Throwable $e) {
$duration = round(microtime(true) - $startTime, 2);
logMessage("", 'error');
logMessage("
❌ ERREUR CRITIQUE", 'error');
logMessage($e->getMessage(), 'error');
logMessage("Fichier : " . $e->getFile() . " (ligne " . $e->getLine() . ")", 'error');
logMessage("⏱️ Temps avant erreur : {$duration}s", 'warning');
$recordsInserted = -1;
}
?>