289 lines
7.0 KiB
PHP
289 lines
7.0 KiB
PHP
<?php
|
||
// filename: /www/wwwroot/bilspro/load/check_voucher_all/check_voucher.php
|
||
|
||
ini_set('display_errors', 1);
|
||
error_reporting(E_ALL);
|
||
|
||
if (php_sapi_name() !== 'cli') {
|
||
exit("CLI only\n");
|
||
}
|
||
|
||
// ============================
|
||
// ⏱ START TIMER (WAJIB!)
|
||
// ============================
|
||
$start_time = microtime(true);
|
||
|
||
// ============================
|
||
// DEBUG AWAL
|
||
// ============================
|
||
file_put_contents("/tmp/debug_check_voucher.log", date('Y-m-d H:i:s') . " RUN\n", FILE_APPEND);
|
||
|
||
include "/www/wwwroot/bilspro/config/connect.php";
|
||
include "/www/wwwroot/bilspro/config/routeros_api.class.php";
|
||
|
||
// ============================
|
||
// PARAMETER CLI
|
||
// ============================
|
||
$m_ip = $argv[1] ?? '';
|
||
$m_user = $argv[2] ?? '';
|
||
$m_pass = $argv[3] ?? '';
|
||
$m_port = $argv[4] ?? '';
|
||
$idsm = $argv[5] ?? '';
|
||
$nama = $argv[6] ?? 'unknown';
|
||
|
||
// ============================
|
||
// VALIDASI PARAMETER
|
||
// ============================
|
||
if (!$m_ip || !$m_user) {
|
||
file_put_contents("/tmp/debug_check_voucher.log", "PARAM ERROR\n", FILE_APPEND);
|
||
exit;
|
||
}
|
||
|
||
// ============================
|
||
// LOG DIR
|
||
// ============================
|
||
$nama_safe = preg_replace('/[^A-Za-z0-9_\-]/', '_', $nama);
|
||
if (!$nama_safe) {
|
||
$nama_safe = 'unknown';
|
||
}
|
||
|
||
$logDir = "/www/wwwroot/bilspro/load/check_voucher_all/logs";
|
||
|
||
if (!is_dir($logDir)) {
|
||
mkdir($logDir, 0777, true);
|
||
}
|
||
|
||
$logFile = "{$logDir}/voucher_{$nama_safe}.log";
|
||
|
||
// ============================
|
||
// GLOBAL SUMMARY LOG
|
||
// ============================
|
||
$mainLogFile = "/www/wwwroot/bilspro/load/check_voucher_all/main_cli.log";
|
||
|
||
// ============================
|
||
// FUNCTION LOG (NEW TOP + LIMIT 5000)
|
||
// ============================
|
||
function writeLog($msg)
|
||
{
|
||
global $logFile;
|
||
|
||
$line = "[" . date('Y-m-d H:i:s') . "] $msg\n";
|
||
|
||
$old = file_exists($logFile) ? file_get_contents($logFile) : '';
|
||
|
||
$newContent = $line . $old;
|
||
|
||
$lines = explode("\n", $newContent);
|
||
|
||
if (count($lines) > 10000) {
|
||
$lines = array_slice($lines, 0, 10000);
|
||
}
|
||
|
||
$final = implode("\n", $lines);
|
||
|
||
if (!file_put_contents($logFile, $final, LOCK_EX)) {
|
||
file_put_contents("/tmp/fallback.log", $line, FILE_APPEND);
|
||
}
|
||
}
|
||
|
||
// ============================
|
||
// START LOG
|
||
// ============================
|
||
writeLog("🚀 START {$m_ip} - {$nama}");
|
||
|
||
// ============================
|
||
// API
|
||
// ============================
|
||
$API = new RouterosAPI();
|
||
$API->timeout = 3;
|
||
|
||
// ============================
|
||
// CONNECT
|
||
// ============================
|
||
if (!$API->connect2($m_ip, $m_user, $m_pass, $m_port)) {
|
||
writeLog("❌ Gagal konek ke {$m_ip}");
|
||
|
||
// SUMMARY FAIL
|
||
file_put_contents($mainLogFile,
|
||
"[" . date('Y-m-d H:i:s') . "] FAIL | {$m_ip} | {$nama}\n",
|
||
FILE_APPEND | LOCK_EX
|
||
);
|
||
|
||
exit;
|
||
}
|
||
|
||
writeLog("✅ Connected ke {$m_ip} : Mulai Check Voucher");
|
||
|
||
// ============================
|
||
// HOTSPOT CACHE
|
||
// ============================
|
||
$hotspot = $API->comm('/ip/hotspot/user/print');
|
||
|
||
$userMap = [];
|
||
if (is_array($hotspot)) {
|
||
foreach ($hotspot as $u) {
|
||
$userMap[$u['name']] = $u;
|
||
}
|
||
}
|
||
|
||
// ============================
|
||
// LOOP DB
|
||
// ============================
|
||
$batchSize = 200;
|
||
$offset = 0;
|
||
|
||
do {
|
||
|
||
$stmt = $pdo->prepare("
|
||
SELECT id, create_time, voucher, durasi
|
||
FROM v_load_cek_voucher
|
||
WHERE id_setting_mikrotik = :idsm
|
||
LIMIT {$batchSize} OFFSET {$offset}
|
||
");
|
||
|
||
$stmt->bindValue(':idsm', $idsm, PDO::PARAM_INT);
|
||
$stmt->execute();
|
||
|
||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||
if (!$rows) break;
|
||
|
||
foreach ($rows as $r) {
|
||
|
||
$id = $r['id'];
|
||
$voucher = $r['voucher'];
|
||
$durasi = $r['durasi'];
|
||
|
||
$interval = convertDurationToInterval($durasi);
|
||
if (!$interval) {
|
||
writeLog("⛔ {$voucher} durasi invalid");
|
||
continue;
|
||
}
|
||
|
||
if (isset($userMap[$voucher])) {
|
||
|
||
$comment = $userMap[$voucher]['comment'] ?? '';
|
||
|
||
if ($comment) {
|
||
$activetime = processCommentDate($comment);
|
||
|
||
if (!$activetime) {
|
||
writeLog("❌ {$voucher} tanggal invalid");
|
||
continue;
|
||
}
|
||
|
||
$tgl = new DateTime($activetime);
|
||
$tgl->add($interval);
|
||
|
||
$exp = $tgl->format('Y-m-d H:i:s');
|
||
|
||
updateVoucher($pdo, $id, $activetime, $exp);
|
||
|
||
writeLog("✅ {$voucher} aktif : {$activetime} , exp: {$exp}");
|
||
|
||
} else {
|
||
markVoucherChecked($pdo, $id);
|
||
writeLog("ℹ️ {$voucher} tanpa comment");
|
||
}
|
||
|
||
} else {
|
||
|
||
$aktif = $r['create_time'];
|
||
|
||
$tgl = new DateTime($aktif);
|
||
$tgl->add($interval);
|
||
|
||
$exp = $tgl->format('Y-m-d H:i:s');
|
||
|
||
updateVoucher($pdo, $id, $aktif, $exp);
|
||
|
||
writeLog("⚠️ {$voucher} tidak ada di Mikrotik, aktif: {$aktif}, exp: {$exp}");
|
||
}
|
||
|
||
usleep(50000);
|
||
}
|
||
|
||
$offset += $batchSize;
|
||
|
||
} while (count($rows) == $batchSize);
|
||
|
||
// ============================
|
||
// FINISH
|
||
// ============================
|
||
$API->disconnect();
|
||
|
||
$end_time = microtime(true);
|
||
$duration = $end_time - $start_time;
|
||
$duration_format = gmdate("H:i:s", (int)$duration);
|
||
|
||
// log biasa
|
||
writeLog("✅ SELESAI {$m_ip} | Durasi: {$duration_format} ({$duration} detik) | Last cek " . date('Y-m-d H:i:s'));
|
||
|
||
// ============================
|
||
// 🔥 SUMMARY KE MAIN LOG
|
||
// ============================
|
||
$logLine = sprintf(
|
||
"[%s] OK | %-15s | %-25s | Durasi: %s (%.2f detik)",
|
||
date('Y-m-d H:i:s'),
|
||
$m_ip,
|
||
$nama,
|
||
$duration_format,
|
||
$duration
|
||
);
|
||
|
||
// baca log lama
|
||
$oldContent = file_exists($mainLogFile) ? file($mainLogFile, FILE_IGNORE_NEW_LINES) : [];
|
||
|
||
// filter: hapus yang sama (IP + Nama)
|
||
$newContent = [];
|
||
foreach ($oldContent as $line) {
|
||
if (strpos($line, $m_ip) !== false && strpos($line, $nama) !== false) {
|
||
continue; // skip yang lama
|
||
}
|
||
$newContent[] = $line;
|
||
}
|
||
|
||
// tambahkan yang baru di paling atas
|
||
array_unshift($newContent, $logLine);
|
||
|
||
// tulis ulang file
|
||
file_put_contents(
|
||
$mainLogFile,
|
||
implode("\n", $newContent) . "\n",
|
||
LOCK_EX
|
||
);
|
||
|
||
|
||
// ============================
|
||
// HELPER
|
||
// ============================
|
||
function convertDurationToInterval($d)
|
||
{
|
||
if (substr($d, -1) == 'H') return new DateInterval("PT" . rtrim($d, 'H') . "H");
|
||
if (substr($d, -1) == 'D') return new DateInterval("P" . rtrim($d, 'D') . "D");
|
||
if (substr($d, -1) == 'M') return new DateInterval("PT" . rtrim($d, 'M') . "M");
|
||
return false;
|
||
}
|
||
|
||
function processCommentDate($c)
|
||
{
|
||
$d = substr($c, 6);
|
||
|
||
if (substr($d, 0, 4) == date('Y')) {
|
||
return $d;
|
||
}
|
||
|
||
$date = date_create_from_format("M/d/Y H:i:s", $d);
|
||
return $date ? date_format($date, "Y-m-d H:i:s") : null;
|
||
}
|
||
|
||
function updateVoucher($pdo, $id, $a, $e)
|
||
{
|
||
$stmt = $pdo->prepare("UPDATE ganerate_voucher SET active_time=?, expaired_time=? WHERE id=?");
|
||
$stmt->execute([$a, $e, $id]);
|
||
}
|
||
|
||
function markVoucherChecked($pdo, $id)
|
||
{
|
||
$stmt = $pdo->prepare("UPDATE ganerate_voucher SET status_cek='1' WHERE id=?");
|
||
$stmt->execute([$id]);
|
||
} |