setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Desactivar foreign keys temporalmente para evitar errores de integridad $pdo_local->exec("SET FOREIGN_KEY_CHECKS=0"); $log = "=== Inicio Sincronización Inversa (Pull HTTP): " . date('Y-m-d H:i:s') . " ===\n"; $log .= "Origen: $remote_url\n"; $log .= "Destino: $local_host / $local_db\n\n"; // 2. Recorrer tablas y traer datos del hosting al local foreach ($tablas_a_sincronizar as $tabla) { // 3. Pedir datos al hosting vía HTTP $payload = json_encode([ 'secret_key' => $secret_key, 'tabla' => $tabla ]); $ch = curl_init($remote_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Timeout de 30 segundos $respuesta = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curl_error = curl_error($ch); curl_close($ch); if ($curl_error) { $log .= "Tabla '$tabla': ❌ ERROR cURL: $curl_error\n"; continue; } if ($http_code != 200) { $log .= "Tabla '$tabla': ❌ ERROR HTTP $http_code al contactar con el hosting.\n"; continue; } $resultado = json_decode($respuesta, true); if (!isset($resultado['success']) || !$resultado['success']) { $log .= "Tabla '$tabla': ❌ ERROR en respuesta del hosting: " . ($resultado['message'] ?? 'Desconocido') . "\n"; continue; } $datos = $resultado['data'] ?? []; if (empty($datos)) { $log .= "Tabla '$tabla': ️ Sin datos en el hosting. Omitida.\n"; continue; } // 4. Insertar o actualizar en local (UPSERT) $insertados = 0; $actualizados = 0; $errores = 0; foreach ($datos as $registro) { // Obtener columnas y valores dinámicamente $columnas = array_keys($registro); $valores = array_values($registro); // Construir INSERT ... ON DUPLICATE KEY UPDATE $placeholders = implode(', ', array_fill(0, count($columnas), '?')); $updateClauses = []; foreach ($columnas as $col) { if ($col !== 'id') { // No actualizar el ID primario $updateClauses[] = "$col = VALUES($col)"; } } $sql = "INSERT INTO $tabla (" . implode(', ', $columnas) . ") VALUES ($placeholders) ON DUPLICATE KEY UPDATE " . implode(', ', $updateClauses); try { $stmt = $pdo_local->prepare($sql); $stmt->execute($valores); if ($stmt->rowCount() == 1) { $insertados++; } else { $actualizados++; } } catch (PDOException $e) { $errores++; $log .= " ️ Error en $tabla (ID {$registro['id']}): " . $e->getMessage() . "\n"; } } $log .= "Tabla '$tabla': ✅ OK. $insertados nuevos, $actualizados actualizados"; if ($errores > 0) { $log .= ", $errores errores"; } $log .= ".\n"; } // 5. Reactivar foreign keys $pdo_local->exec("SET FOREIGN_KEY_CHECKS=1"); // 6. Guardar log file_put_contents('/var/www/html/api/sync_pull_log.txt', $log, FILE_APPEND); echo $log; } catch (PDOException $e) { echo "❌ Error de conexión a la base de datos local: " . $e->getMessage() . "\n"; } catch (Exception $e) { echo "❌ Error fatal: " . $e->getMessage() . "\n"; } ?>