1000) { $lines = array_slice($lines, -1000); // Keep only last 1000 file_put_contents($logFile, implode("\n", $lines) . "\n"); } } // ========================== // Create RouterOS API object // ========================== $API = new RouterosAPI(); $API->debug = false; // ======================= // Connect to RouterOS API // ======================= if ($API->connect2($m_ip, $m_user, $m_pass, $m_port)) { echo "✅ Berhasil terhubung ke Router: {$m_ip}\n"; writeLog("[✅] Berhasil terhubung ke Router: {$m_ip}"); $batchSize = 200; // Batasi 200 voucher per batch $offset = 0; do { $ambilv1 = $pdo->prepare(" SELECT id, create_time, voucher, durasi FROM v_load_cek_voucher WHERE id_setting_mikrotik = :idsm LIMIT :limit OFFSET :offset "); $ambilv1->bindValue(':idsm', $idsm, PDO::PARAM_INT); $ambilv1->bindValue(':limit', $batchSize, PDO::PARAM_INT); $ambilv1->bindValue(':offset', $offset, PDO::PARAM_INT); $ambilv1->execute(); $rows = $ambilv1->fetchAll(PDO::FETCH_ASSOC); if (!$rows) break; foreach ($rows as $cekv1) { $iddatav1 = $cekv1['id']; $datav1 = $cekv1['voucher']; $durasi = $cekv1['durasi']; // ================================ // Convert duration to DateInterval // ================================ $inter = convertDurationToInterval($durasi); if (!$inter) { $status = "Durasi tidak valid ($durasi)"; echo "{$datav1} => $status\n"; writeLog("[⛔] {$datav1} => $status"); continue; } // ===================================== // Check if voucher exists on Hotspot // ===================================== $cek = $API->comm('/ip/hotspot/user/print', ["?name" => $datav1]); if ($cek) { // If voucher exists and has comment if (!empty($cek[0]['comment'])) { $activetime = processCommentDate($cek[0]['comment']); $Tgl = new DateTime($activetime); $Tgl->add($inter); $exp = $Tgl->format('Y-m-d H:i:s'); updateVoucher($pdo, $iddatav1, $activetime, $exp); $status = "Voucher aktif & diperbarui. Expired: $exp"; echo "{$datav1} => $status\n"; writeLog("[✅] {$datav1} => $status"); } else { markVoucherChecked($pdo, $iddatav1); $status = "Voucher ditemukan tanpa komentar, ditandai sudah dicek"; echo "{$datav1} => $status\n"; writeLog("[ℹ️] {$datav1} => $status"); } } else { // If voucher does not exist $aktif = $cekv1['create_time']; $Tgl = new DateTime($aktif); $Tgl->add($inter); $exp = $Tgl->format('Y-m-d H:i:s'); updateVoucher($pdo, $iddatav1, $aktif, $exp); $status = "Voucher tidak ditemukan, dianggap aktif sejak $aktif, expired: $exp"; echo "{$datav1} => $status\n"; writeLog("[⚠️] {$datav1} => $status"); } } $offset += $batchSize; } while (count($rows) == $batchSize); echo "✅ Selesai memproses semua voucher untuk Router {$m_ip}\n"; writeLog("[✅] Selesai memproses semua voucher untuk Router {$m_ip}"); } else { $msg = "Gagal terhubung ke Router: {$m_ip}"; echo "❌ $msg\n"; writeLog("[❌] $msg"); } // ======================= // Disconnect API session // ======================= $API->disconnect(); // ============================================ // Helper Functions // ============================================ function convertDurationToInterval($durasi) { if (substr($durasi, -1) == 'H') { return new DateInterval("PT" . rtrim($durasi, 'H') . "H"); } elseif (substr($durasi, -1) == 'D') { return new DateInterval("P" . rtrim($durasi, 'D') . "D"); } elseif (substr($durasi, -1) == 'M') { return new DateInterval("PT" . rtrim($durasi, 'M') . "M"); } else { return false; } } function processCommentDate($comment) { $modifiedDateTime = substr($comment, 6); if (substr($modifiedDateTime, 0, 4) == date('Y')) { return $modifiedDateTime; } else { $date = date_create_from_format("M/d/Y H:i:s", $modifiedDateTime); return $date ? date_format($date, "Y-m-d H:i:s") : null; } } function updateVoucher($pdo, $iddatav1, $activetime, $exp) { $updateQuery = "UPDATE ganerate_voucher SET active_time = :activetime, expaired_time = :exp WHERE id = :id"; $stmt = $pdo->prepare($updateQuery); $stmt->execute([ ':activetime' => $activetime, ':exp' => $exp, ':id' => $iddatav1 ]); } function markVoucherChecked($pdo, $iddatav1) { $updateQuery = "UPDATE ganerate_voucher SET status_cek = '1' WHERE id = :id"; $stmt = $pdo->prepare($updateQuery); $stmt->execute([':id' => $iddatav1]); } ?>