* @license Unlicense https://unlicense.org/ * @link https://github.com/ksolomon/TornVaultTracker */ // Include settings from configuration file require_once __DIR__ . '/config.php'; // Include utility functions require_once 'includes/exceptions.php'; require_once 'includes/utilities.php'; /** * Returns a PDO connection to the database * This function creates the database connection and creates the database * file if it doesn't exist, and the vault table if it doesn't exist. * * @return PDO */ function getDatabaseConnection() { static $pdo = null; // SQL to create the vault table if it doesn't exist $createTableSQL = "CREATE TABLE IF NOT EXISTS vault ( id TEXT PRIMARY KEY, user TEXT NOT NULL, timestamp INTEGER NOT NULL, description TEXT NOT NULL, amount REAL NOT NULL );"; if ($pdo === null) { try { $pdo = new PDO(DB_DSN, DB_USER, DB_PASSWORD); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->exec($createTableSQL); } catch (PDOException $e) { die("Database connection failed: " . $e->getMessage()); } } return $pdo; } /** * Pulls and stores the full vault transaction log history for a user. * * Pages through the v2 Torn API using `_metadata.links.next` until the * API reports no further pages. Intended for first-run use when the * local database is empty. Idempotent: re-running on a partially * populated database inserts only new entries (ON CONFLICT DO NOTHING). * * @param string $user The user whose logs should be fetched. * * @return void */ function backfillUserLogs($user) { $url = 'https://api.torn.com/v2/user?selections=log&log=5850,5851'; $pdo = getDatabaseConnection(); do { $next = fetchAndStoreLogPage($pdo, $user, $url); $url = $next; } while ($next !== null); } /** * Synchronizes recent vault transactions for a user. * * On a non-empty database, fetches only entries newer than the user's * most recent row. Falls back to full backfill when the database is * empty. * * @param string $user The user whose logs should be synced. * * @return void */ function syncUserLogs($user) { if (dbNew()) { backfillUserLogs($user); return; } $pdo = getDatabaseConnection(); $stmt = $pdo->prepare('SELECT MAX(timestamp) AS max_ts FROM vault WHERE user = :user'); $stmt->bindValue(':user', $user); $stmt->execute(); $lastTs = (int)$stmt->fetch(PDO::FETCH_ASSOC)['max_ts']; $url = "https://api.torn.com/v2/user?selections=log&log=5850,5851&from=" . ($lastTs + 1); do { $next = fetchAndStoreLogPage($pdo, $user, $url); $url = $next; } while ($next !== null); } /** * Generate the current balance for a user or all users * * @param string $name (optional) The user to get the balance for. If not provided, all users' balances will be added. * * @return string The balance as a formatted string */ function generateBalance($name=null) { $balance = vaultLoop($name); return number_format($balance, 0); // Format the balance as an integer } /** * Calculate the available vault space for a user or all users. * * This function calculates the remaining space in the vault based on the * transactions for a specific user or all users. If a user is specified, * the available space is calculated against a limit of 500,000,000. * If no user is specified, the available space is calculated against a * total vault limit of 1,000,000,000. * * @param string|null $name (optional) The user to calculate the vault space for. * If not provided, calculates for all users. * * @return string The available vault space as a formatted string. */ function getSpace($name=null) { $space = vaultLoop($name); if ($name === null) { $space = 1000000000 - $space; } else { $space = 500000000 - $space; } return number_format($space, 0); // Format the balance as an integer } /** * Builds an HTML table of all transactions in the vault * * Loops over all records in the vault and builds a table of the user, timestamp, * description and amount of each transaction. Amounts are formatted as integers. * * @return void */ function buildTable () { $records = fetchVaultRecords(); foreach ($records as $entry) { $user = $entry['user']; $timestamp = $entry['timestamp']; $description = $entry['description']; $amount = $entry['amount']; $sign = getSign($amount); if ($description == 'Vault withdraw') { $class = 'debit'; $amount = substr($amount, 1); // Remove the negative sign } else { $class = 'credit'; } $amount = number_format($amount, 0); // Format the amount as an integer echo '