Enhance Torn Vault Tracker: Add documentation, improve exception handling, and update styles
Deploy website via FTP / Deploy (push) Skipped
Deploy website via FTP / Deploy (push) Skipped
- Updated .gitignore to exclude new directories and files. - Enhanced config.php with detailed PHPDoc comments for better clarity. - Refactored functions.php to include PHPDoc comments and improve code readability. - Added custom exceptions in exceptions.php with detailed documentation. - Improved utilities.php with better documentation and error handling. - Updated index.php with structured comments and improved readability. - Refined style.css for better visual consistency. - Introduced phpcs.xml for coding style checks and standards enforcement.
This commit is contained in:
@@ -3,3 +3,5 @@ backup/
|
|||||||
debug.log
|
debug.log
|
||||||
data/*
|
data/*
|
||||||
!data/.gitkeep
|
!data/.gitkeep
|
||||||
|
.claude/
|
||||||
|
phpcs-results.txt
|
||||||
|
|||||||
+13
-3
@@ -1,10 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
// Configuration file for settings like database and API keys
|
/**
|
||||||
|
* Configuration file for settings like database and API keys
|
||||||
|
*
|
||||||
|
* PHP version 8.1+
|
||||||
|
*
|
||||||
|
* @category Configuration
|
||||||
|
* @package TornVaultTracker
|
||||||
|
* @author Keith Solomon <ksolomon@gmail.com>
|
||||||
|
* @license Unlicense https://unlicense.org/
|
||||||
|
* @link https://github.com/ksolomon/TornVaultTracker
|
||||||
|
*/
|
||||||
|
|
||||||
// Database settings
|
// Database settings
|
||||||
define('DB_DSN', 'sqlite:data/vault.db'); // Path to your SQLite database
|
define('DB_DSN', 'sqlite:data/vault.db'); // Path to your SQLite database
|
||||||
define('DB_USER', null); // Not needed for SQLite
|
define('DB_USER', null); // Not needed for SQLite
|
||||||
define('DB_PASSWORD', null); // Not needed for SQLite
|
define('DB_PASSWORD', null); // Not needed for SQLite
|
||||||
|
|
||||||
// User-specific keys for accessing logs
|
// User-specific keys for accessing logs
|
||||||
const USER_KEYS = [
|
const USER_KEYS = [
|
||||||
|
|||||||
+226
-199
@@ -1,199 +1,226 @@
|
|||||||
<?php
|
<?php
|
||||||
// Include settings from a separate configuration file
|
/**
|
||||||
require_once __DIR__ . '/config.php';
|
* Functions for the Torn Vault Tracker application.
|
||||||
|
*
|
||||||
// Include utility functions
|
* PHP version 8.1+
|
||||||
require_once 'includes/exceptions.php';
|
*
|
||||||
require_once 'includes/utilities.php';
|
* @category Functions
|
||||||
|
* @package TornVaultTracker
|
||||||
/** Returns a PDO connection to the database
|
* @author Keith Solomon <ksolomon@gmail.com>
|
||||||
* This function creates the database connection and creates the database
|
* @license Unlicense https://unlicense.org/
|
||||||
* file if it doesn't exist, and the vault table if it doesn't exist.
|
* @link https://github.com/ksolomon/TornVaultTracker
|
||||||
*
|
*/
|
||||||
* @return PDO
|
|
||||||
*/
|
// Include settings from configuration file
|
||||||
function getDatabaseConnection() {
|
require_once __DIR__ . '/config.php';
|
||||||
static $pdo = null;
|
|
||||||
|
// Include utility functions
|
||||||
// SQL to create the vault table if it doesn't exist
|
require_once 'includes/exceptions.php';
|
||||||
$createTableSQL = "CREATE TABLE IF NOT EXISTS vault (
|
require_once 'includes/utilities.php';
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
user TEXT NOT NULL,
|
/**
|
||||||
timestamp INTEGER NOT NULL,
|
* Returns a PDO connection to the database
|
||||||
description TEXT NOT NULL,
|
* This function creates the database connection and creates the database
|
||||||
amount REAL NOT NULL
|
* file if it doesn't exist, and the vault table if it doesn't exist.
|
||||||
);";
|
*
|
||||||
|
* @return PDO
|
||||||
if ($pdo === null) {
|
*/
|
||||||
try {
|
function getDatabaseConnection() {
|
||||||
$pdo = new PDO(DB_DSN, DB_USER, DB_PASSWORD);
|
static $pdo = null;
|
||||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
|
// SQL to create the vault table if it doesn't exist
|
||||||
$pdo->exec($createTableSQL);
|
$createTableSQL = "CREATE TABLE IF NOT EXISTS vault (
|
||||||
} catch (PDOException $e) {
|
id TEXT PRIMARY KEY,
|
||||||
die("Database connection failed: " . $e->getMessage());
|
user TEXT NOT NULL,
|
||||||
}
|
timestamp INTEGER NOT NULL,
|
||||||
}
|
description TEXT NOT NULL,
|
||||||
|
amount REAL NOT NULL
|
||||||
return $pdo;
|
);";
|
||||||
}
|
|
||||||
|
if ($pdo === null) {
|
||||||
/** Pulls and stores all vault transaction logs for a user from the Torn API.
|
try {
|
||||||
*
|
$pdo = new PDO(DB_DSN, DB_USER, DB_PASSWORD);
|
||||||
* This function retrieves all transaction logs related to vault deposits and
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
* withdrawals for a specified user. It continues fetching logs until no more
|
|
||||||
* entries are available, and stores each entry in the database. Each log entry
|
$pdo->exec($createTableSQL);
|
||||||
* is uniquely identified by its ID and includes details such as timestamp,
|
} catch (PDOException $e) {
|
||||||
* description, and amount. The function requires the user's API key to
|
die("Database connection failed: " . $e->getMessage());
|
||||||
* authenticate requests to the Torn API.
|
}
|
||||||
*
|
}
|
||||||
* @param string $user The user whose transaction logs are to be retrieved and stored.
|
|
||||||
*/
|
return $pdo;
|
||||||
function firstRun($user) {
|
}
|
||||||
$apiKey = USER_KEYS[$user];
|
|
||||||
|
/**
|
||||||
$pdo = getDatabaseConnection();
|
* Pulls and stores all vault transaction logs for a user from the Torn API.
|
||||||
|
*
|
||||||
$to = time();
|
* This function retrieves all transaction logs related to vault deposits and
|
||||||
|
* withdrawals for a specified user. It continues fetching logs until no more
|
||||||
do {
|
* entries are available, and stores each entry in the database. Each log entry
|
||||||
$url = "https://api.torn.com/v2/user?selections=log&log=5850,5851&to=$to";
|
* is uniquely identified by its ID and includes details such as timestamp,
|
||||||
$ch = curl_init($url);
|
* description, and amount. The function requires the user's API key to
|
||||||
|
* authenticate requests to the Torn API.
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
*
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
* @param string $user The user whose transaction logs are to be retrieved and stored.
|
||||||
'accept: application/json',
|
*
|
||||||
"Authorization: ApiKey $apiKey"
|
* @throws ApiKeyMissingException If the user does not have an API key configured.
|
||||||
]);
|
* @throws CurlErrorException If there is an error during the API call.
|
||||||
|
* @throws Exception If there is an error decoding the JSON response or if the response is invalid.
|
||||||
$response = curl_exec($ch);
|
*
|
||||||
|
* @return void
|
||||||
curl_close($ch);
|
*/
|
||||||
|
function firstRun($user) {
|
||||||
$data = json_decode($response, true);
|
$apiKey = USER_KEYS[$user];
|
||||||
|
$pdo = getDatabaseConnection();
|
||||||
if (empty($data['log'])) { break; }
|
$to = time();
|
||||||
|
|
||||||
foreach ($data['log'] as $key => $entry) {
|
do {
|
||||||
$description = $entry['title'];
|
$url = "https://api.torn.com/v2/user?selections=log&log=5850,5851&to=$to";
|
||||||
$timestamp = $entry['timestamp'];
|
$ch = curl_init($url);
|
||||||
$amount = isset($entry['data']['deposited']) ? $entry['data']['deposited'] : -$entry['data']['withdrawn'];
|
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
$stmt = $pdo->prepare('INSERT INTO vault (ID, user, timestamp, description, amount) VALUES (:id, :user, :timestamp, :description, :amount)');
|
curl_setopt(
|
||||||
|
$ch, CURLOPT_HTTPHEADER, [
|
||||||
$stmt->bindValue(':id', $key);
|
'accept: application/json',
|
||||||
$stmt->bindValue(':user', $user);
|
"Authorization: ApiKey $apiKey"
|
||||||
$stmt->bindValue(':timestamp', $timestamp);
|
]
|
||||||
$stmt->bindValue(':description', $description);
|
);
|
||||||
$stmt->bindValue(':amount', $amount);
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
$stmt->execute();
|
|
||||||
}
|
curl_close($ch);
|
||||||
|
|
||||||
$to = end($data['log'])['timestamp'];
|
$data = json_decode($response, true);
|
||||||
} while (true);
|
|
||||||
}
|
if (empty($data['log'])) {
|
||||||
|
break;
|
||||||
/** Retrieves the user's log entries from the Torn API
|
}
|
||||||
*
|
|
||||||
* @param string $user The user to retrieve the log for
|
foreach ($data['log'] as $key => $entry) {
|
||||||
* @param boolean $debug Whether to output debug information (default: false)
|
$description = $entry['title'];
|
||||||
*
|
$timestamp = $entry['timestamp'];
|
||||||
* @throws Exception If the user does not have an API key configured,
|
$amount = isset($entry['data']['deposited']) ? $entry['data']['deposited'] : -$entry['data']['withdrawn'];
|
||||||
* if the API call fails, or if the log data is invalid
|
|
||||||
*/
|
$stmt = $pdo->prepare('INSERT INTO vault (ID, user, timestamp, description, amount) VALUES (:id, :user, :timestamp, :description, :amount)');
|
||||||
function getLog($user, $debug = false) {
|
|
||||||
$pdo = getDatabaseConnection();
|
$stmt->bindValue(':id', $key);
|
||||||
|
$stmt->bindValue(':user', $user);
|
||||||
ensureUserHasApiKey($user);
|
$stmt->bindValue(':timestamp', $timestamp);
|
||||||
|
$stmt->bindValue(':description', $description);
|
||||||
$stmt = $pdo->query("SELECT MAX(timestamp) AS max_timestamp FROM vault WHERE user = '$user'");
|
$stmt->bindValue(':amount', $amount);
|
||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
||||||
|
$stmt->execute();
|
||||||
$from = $row['max_timestamp'];
|
}
|
||||||
$to = time();
|
|
||||||
|
$to = end($data['log'])['timestamp'];
|
||||||
$apiKey = USER_KEYS[$user];
|
} while (true);
|
||||||
$apiEndpoint = "https://api.torn.com/user/?selections=log&log=5850,5851&to=$to&from=$from&key=$apiKey";
|
}
|
||||||
|
|
||||||
$responseData = executeApiCall($apiEndpoint);
|
/**
|
||||||
validateApiResponse($responseData);
|
* Retrieves the user's log entries from the Torn API
|
||||||
|
*
|
||||||
$checkStmt = prepareCheckStatement($pdo);
|
* @param string $user The user to retrieve the log for
|
||||||
$insertStmt = prepareInsertStatement($pdo);
|
* @param boolean $debug Whether to output debug information (default: false)
|
||||||
|
*
|
||||||
processLogEntries($responseData['log'], $user, $checkStmt, $insertStmt, $debug);
|
* @throws Exception If the user does not have an API key configured,
|
||||||
}
|
* if the API call fails, or if the log data is invalid
|
||||||
|
*
|
||||||
/** Generate the current balance for a user or all users
|
* @return void
|
||||||
*
|
*/
|
||||||
* @param string $name (optional) The user to get the balance for. If not provided, all users' balances will be added.
|
function getLog($user, $debug = false) {
|
||||||
*
|
$pdo = getDatabaseConnection();
|
||||||
* @return string The balance as a formatted string
|
|
||||||
*/
|
ensureUserHasApiKey($user);
|
||||||
function generateBalance($name=null) {
|
|
||||||
$balance = vaultLoop($name);
|
$stmt = $pdo->query("SELECT MAX(timestamp) AS max_timestamp FROM vault WHERE user = '$user'");
|
||||||
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
return number_format($balance, 0); // Format the balance as an integer
|
|
||||||
}
|
$from = $row['max_timestamp'];
|
||||||
|
$to = time();
|
||||||
/** Calculate the available vault space for a user or all users.
|
|
||||||
*
|
$apiKey = USER_KEYS[$user];
|
||||||
* This function calculates the remaining space in the vault based on the
|
$apiEndpoint = "https://api.torn.com/user/?selections=log&log=5850,5851&to=$to&from=$from&key=$apiKey";
|
||||||
* 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.
|
$responseData = executeApiCall($apiEndpoint);
|
||||||
* If no user is specified, the available space is calculated against a
|
validateApiResponse($responseData);
|
||||||
* total vault limit of 1,000,000,000.
|
|
||||||
*
|
$checkStmt = prepareCheckStatement($pdo);
|
||||||
* @param string|null $name (optional) The user to calculate the vault space for.
|
$insertStmt = prepareInsertStatement($pdo);
|
||||||
* If not provided, calculates for all users.
|
|
||||||
*
|
processLogEntries($responseData['log'], $user, $checkStmt, $insertStmt, $debug);
|
||||||
* @return string The available vault space as a formatted string.
|
}
|
||||||
*/
|
|
||||||
|
/**
|
||||||
function getSpace($name=null) {
|
* Generate the current balance for a user or all users
|
||||||
$space = vaultLoop($name);
|
*
|
||||||
|
* @param string $name (optional) The user to get the balance for. If not provided, all users' balances will be added.
|
||||||
if ($name === null) {
|
*
|
||||||
$space = 1000000000 - $space;
|
* @return string The balance as a formatted string
|
||||||
} else {
|
*/
|
||||||
$space = 500000000 - $space;
|
function generateBalance($name=null) {
|
||||||
}
|
$balance = vaultLoop($name);
|
||||||
|
|
||||||
return number_format($space, 0); // Format the balance as an integer
|
return number_format($balance, 0); // Format the balance as an integer
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Builds an HTML table of all transactions in the vault
|
/**
|
||||||
*
|
* Calculate the available vault space for a user or all users.
|
||||||
* 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.
|
* 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,
|
||||||
* @return void
|
* the available space is calculated against a limit of 500,000,000.
|
||||||
*/
|
* If no user is specified, the available space is calculated against a
|
||||||
function buildTable () {
|
* total vault limit of 1,000,000,000.
|
||||||
$records = fetchVaultRecords();
|
*
|
||||||
|
* @param string|null $name (optional) The user to calculate the vault space for.
|
||||||
foreach ($records as $entry) {
|
* If not provided, calculates for all users.
|
||||||
$user = $entry['user'];
|
*
|
||||||
$timestamp = $entry['timestamp'];
|
* @return string The available vault space as a formatted string.
|
||||||
$description = $entry['description'];
|
*/
|
||||||
$amount = $entry['amount'];
|
function getSpace($name=null) {
|
||||||
$sign = getSign($amount);
|
$space = vaultLoop($name);
|
||||||
|
|
||||||
if ($description == 'Vault withdraw') {
|
if ($name === null) {
|
||||||
$class = 'debit';
|
$space = 1000000000 - $space;
|
||||||
$amount = substr($amount, 1); // Remove the negative sign
|
} else {
|
||||||
} else {
|
$space = 500000000 - $space;
|
||||||
$class = 'credit';
|
}
|
||||||
}
|
|
||||||
|
return number_format($space, 0); // Format the balance as an integer
|
||||||
$amount = number_format($amount, 0); // Format the amount as an integer
|
}
|
||||||
|
|
||||||
echo '<tr class="'.$class.'">';
|
/**
|
||||||
echo '<td>'.$user.'</td>';
|
* Builds an HTML table of all transactions in the vault
|
||||||
echo '<td>'.date("F j, Y / H:i", $timestamp).'</td>';
|
*
|
||||||
echo '<td>'.$description.'</td>';
|
* Loops over all records in the vault and builds a table of the user, timestamp,
|
||||||
echo '<td>'.$sign.$amount.'</td>';
|
* description and amount of each transaction. Amounts are formatted as integers.
|
||||||
echo '</tr>';
|
*
|
||||||
}
|
* @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 '<tr class="'.$class.'">';
|
||||||
|
echo '<td>'.$user.'</td>';
|
||||||
|
echo '<td>'.date("F j, Y / H:i", $timestamp).'</td>';
|
||||||
|
echo '<td>'.$description.'</td>';
|
||||||
|
echo '<td>'.$sign.$amount.'</td>';
|
||||||
|
echo '</tr>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+88
-12
@@ -1,24 +1,100 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Custom exceptions for API interactions.
|
||||||
|
*
|
||||||
|
* PHP version 8.1+
|
||||||
|
*
|
||||||
|
* @category Exception
|
||||||
|
* @package TornVaultTracker
|
||||||
|
* @author Keith Solomon <ksolomon@gmail.com>
|
||||||
|
* @license Unlicense https://unlicense.org/
|
||||||
|
* @link https://github.com/ksolomon/Torn-Vault-Tracker
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when API key is missing.
|
||||||
|
*
|
||||||
|
* @category Exception
|
||||||
|
* @package TornVaultTracker
|
||||||
|
* @author Keith Solomon <ksolomon@gmail.com>
|
||||||
|
* @license Unlicense https://unlicense.org/
|
||||||
|
* @link https://github.com/ksolomon/Torn-Vault-Tracker
|
||||||
|
*/
|
||||||
class ApiKeyMissingException extends Exception {
|
class ApiKeyMissingException extends Exception {
|
||||||
public function __construct($message, $code = 0, Throwable $previous = null) {
|
/**
|
||||||
parent::__construct($message, $code, $previous);
|
* Constructor.
|
||||||
}
|
*
|
||||||
|
* @param string $message The exception message.
|
||||||
|
* @param int $code The exception code.
|
||||||
|
* @param Throwable $previous The previous throwable.
|
||||||
|
*/
|
||||||
|
public function __construct($message, $code = 0, Throwable $previous = null) {
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown on CURL errors.
|
||||||
|
*
|
||||||
|
* @category Exception
|
||||||
|
* @package TornVaultTracker
|
||||||
|
* @author Keith Solomon <ksolomon@gmail.com>
|
||||||
|
* @license Unlicense https://unlicense.org/
|
||||||
|
* @link https://github.com/ksolomon/Torn-Vault-Tracker
|
||||||
|
*/
|
||||||
class CurlErrorException extends Exception {
|
class CurlErrorException extends Exception {
|
||||||
public function __construct($message, $code = 0, Throwable $previous = null) {
|
/**
|
||||||
parent::__construct($message, $code, $previous);
|
* Constructor.
|
||||||
}
|
*
|
||||||
|
* @param string $message The exception message.
|
||||||
|
* @param int $code The exception code.
|
||||||
|
* @param Throwable $previous The previous throwable.
|
||||||
|
*/
|
||||||
|
public function __construct($message, $code = 0, Throwable $previous = null) {
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown on JSON data errors.
|
||||||
|
*
|
||||||
|
* @category Exception
|
||||||
|
* @package TornVaultTracker
|
||||||
|
* @author Keith Solomon <ksolomon@gmail.com>
|
||||||
|
* @license Unlicense https://unlicense.org/
|
||||||
|
* @link https://github.com/ksolomon/Torn-Vault-Tracker
|
||||||
|
*/
|
||||||
class JsonDataException extends Exception {
|
class JsonDataException extends Exception {
|
||||||
public function __construct($message, $code = 0, Throwable $previous = null) {
|
/**
|
||||||
parent::__construct($message, $code, $previous);
|
* Constructor.
|
||||||
}
|
*
|
||||||
|
* @param string $message The exception message.
|
||||||
|
* @param int $code The exception code.
|
||||||
|
* @param Throwable $previous The previous throwable.
|
||||||
|
*/
|
||||||
|
public function __construct($message, $code = 0, Throwable $previous = null) {
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown on API validation errors.
|
||||||
|
*
|
||||||
|
* @category Exception
|
||||||
|
* @package TornVaultTracker
|
||||||
|
* @author Keith Solomon <ksolomon@gmail.com>
|
||||||
|
* @license Unlicense https://unlicense.org/
|
||||||
|
* @link https://github.com/ksolomon/Torn-Vault-Tracker
|
||||||
|
*/
|
||||||
class ApiValidationException extends Exception {
|
class ApiValidationException extends Exception {
|
||||||
public function __construct($message, $code = 0, Throwable $previous = null) {
|
/**
|
||||||
parent::__construct($message, $code, $previous);
|
* Constructor.
|
||||||
}
|
*
|
||||||
|
* @param string $message The exception message.
|
||||||
|
* @param int $code The exception code.
|
||||||
|
* @param Throwable $previous The previous throwable.
|
||||||
|
*/
|
||||||
|
public function __construct($message, $code = 0, Throwable $previous = null) {
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+135
-96
@@ -1,5 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
/** Checks if the database is new and empty.
|
/**
|
||||||
|
* Utility functions for the Torn Vault Tracker application.
|
||||||
|
*
|
||||||
|
* This file contains helper functions for database operations, API calls,
|
||||||
|
* and vault record management.
|
||||||
|
*
|
||||||
|
* PHP version 8.1+
|
||||||
|
*
|
||||||
|
* @category Utility
|
||||||
|
* @package TornVaultTracker
|
||||||
|
* @author Keith Solomon <ksolomon@gmail.com>
|
||||||
|
* @license Unlicense https://unlicense.org/
|
||||||
|
* @link https://github.com/ksolomon/Torn-Vault-Tracker
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the database is new and empty.
|
||||||
*
|
*
|
||||||
* This function checks if the 'vault' table in the database has any entries.
|
* This function checks if the 'vault' table in the database has any entries.
|
||||||
* If it does not, it returns true, indicating that the database is new and
|
* If it does not, it returns true, indicating that the database is new and
|
||||||
@@ -8,25 +24,29 @@
|
|||||||
* @return boolean True if the database is new and empty, false otherwise.
|
* @return boolean True if the database is new and empty, false otherwise.
|
||||||
*/
|
*/
|
||||||
function dbNew() {
|
function dbNew() {
|
||||||
$pdo = getDatabaseConnection();
|
$pdo = getDatabaseConnection();
|
||||||
$stmt = $pdo->query("SELECT COUNT(*) FROM vault");
|
$stmt = $pdo->query("SELECT COUNT(*) FROM vault");
|
||||||
|
|
||||||
return $stmt->fetchColumn() == 0;
|
return $stmt->fetchColumn() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Ensures that a user has an API key configured.
|
/**
|
||||||
|
* Ensures that a user has an API key configured.
|
||||||
*
|
*
|
||||||
* @param string $user The user to check the API key for
|
* @param string $user The user to check the API key for
|
||||||
*
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
* @throws Exception If the user does not have an API key configured
|
* @throws Exception If the user does not have an API key configured
|
||||||
*/
|
*/
|
||||||
function ensureUserHasApiKey($user) {
|
function ensureUserHasApiKey($user) {
|
||||||
if (!array_key_exists($user, USER_KEYS)) {
|
if (!array_key_exists($user, USER_KEYS)) {
|
||||||
throw new ApiKeyMissingException("User does not have an API key configured.");
|
throw new ApiKeyMissingException("User does not have an API key configured.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Executes a GET request to the given API endpoint and returns the JSON response as an associative array.
|
/**
|
||||||
|
* Executes a GET request to the given API endpoint and returns the JSON response as an associative array.
|
||||||
*
|
*
|
||||||
* @param string $apiEndpoint The URL of the API endpoint to call
|
* @param string $apiEndpoint The URL of the API endpoint to call
|
||||||
*
|
*
|
||||||
@@ -35,112 +55,125 @@ function ensureUserHasApiKey($user) {
|
|||||||
* @return array The JSON response from the API
|
* @return array The JSON response from the API
|
||||||
*/
|
*/
|
||||||
function executeApiCall($apiEndpoint) {
|
function executeApiCall($apiEndpoint) {
|
||||||
$headers = ["Content-Type: application/json"];
|
$headers = ["Content-Type: application/json"];
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
curl_setopt($ch, CURLOPT_URL, $apiEndpoint);
|
curl_setopt($ch, CURLOPT_URL, $apiEndpoint);
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
$response = curl_exec($ch);
|
||||||
|
|
||||||
if (curl_errno($ch)) {
|
if (curl_errno($ch)) {
|
||||||
throw new CurlErrorException("cURL error: " . curl_error($ch));
|
throw new CurlErrorException("cURL error: " . curl_error($ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
$responseData = json_decode($response, true);
|
$responseData = json_decode($response, true);
|
||||||
|
|
||||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
throw new JsonDataException("Failed to decode JSON response: " . json_last_error_msg());
|
throw new JsonDataException("Failed to decode JSON response: " . json_last_error_msg());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $responseData;
|
return $responseData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Validates the API response data for the presence of a log array.
|
/**
|
||||||
|
* Validates the API response data for the presence of a log array.
|
||||||
*
|
*
|
||||||
* @param array $responseData The API response data to validate.
|
* @param array $responseData The API response data to validate.
|
||||||
*
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
* @throws Exception If the log data is missing or not an array.
|
* @throws Exception If the log data is missing or not an array.
|
||||||
*/
|
*/
|
||||||
function validateApiResponse($responseData) {
|
function validateApiResponse($responseData) {
|
||||||
if (!isset($responseData['log']) || !is_array($responseData['log'])) {
|
if (!isset($responseData['log']) || !is_array($responseData['log'])) {
|
||||||
throw new ApiValidationException("Invalid log data received from the API.");
|
throw new ApiValidationException("Invalid log data received from the API.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prepare a PDO statement for checking if a given vault transaction already exists in the database.
|
/**
|
||||||
|
* Prepare a PDO statement for checking if a given vault transaction already exists in the database.
|
||||||
*
|
*
|
||||||
* @param PDO $pdo The PDO instance to prepare the statement with
|
* @param PDO $pdo The PDO instance to prepare the statement with
|
||||||
*
|
*
|
||||||
* @return PDOStatement The prepared statement
|
* @return PDOStatement The prepared statement
|
||||||
*/
|
*/
|
||||||
function prepareCheckStatement($pdo) {
|
function prepareCheckStatement($pdo) {
|
||||||
$checkQuery = "SELECT COUNT(*) FROM vault WHERE user = :user AND timestamp = :timestamp AND amount = :amount";
|
$checkQuery = "SELECT COUNT(*) FROM vault WHERE user = :user AND timestamp = :timestamp AND amount = :amount";
|
||||||
return $pdo->prepare($checkQuery);
|
return $pdo->prepare($checkQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prepare a PDO statement for inserting a new vault transaction into the database.
|
/**
|
||||||
|
* Prepare a PDO statement for inserting a new vault transaction into the database.
|
||||||
*
|
*
|
||||||
* @param PDO $pdo The PDO instance to prepare the statement with
|
* @param PDO $pdo The PDO instance to prepare the statement with
|
||||||
*
|
*
|
||||||
* @return PDOStatement The prepared statement
|
* @return PDOStatement The prepared statement
|
||||||
*/
|
*/
|
||||||
function prepareInsertStatement($pdo) {
|
function prepareInsertStatement($pdo) {
|
||||||
$insertQuery = "INSERT INTO vault (ID, user, timestamp, description, amount) VALUES (:id, :user, :timestamp, :description, :amount)";
|
$insertQuery = "INSERT INTO vault (ID, user, timestamp, description, amount) VALUES (:id, :user, :timestamp, :description, :amount)";
|
||||||
return $pdo->prepare($insertQuery);
|
return $pdo->prepare($insertQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Process an array of log entries retrieved from the Torn API.
|
/**
|
||||||
|
* Process an array of log entries retrieved from the Torn API.
|
||||||
*
|
*
|
||||||
* Goes through each log entry and checks if it's a vault deposit or withdrawal.
|
* Goes through each log entry and checks if it's a vault deposit or withdrawal.
|
||||||
* If it is, it checks if the entry already exists in the database. If it
|
* If it is, it checks if the entry already exists in the database. If it
|
||||||
* doesn't, it inserts the entry into the database.
|
* doesn't, it inserts the entry into the database.
|
||||||
*
|
*
|
||||||
* @param array $logEntries The array of log entries to process
|
* @param array $logEntries The array of log entries to process
|
||||||
* @param string $user The user whose log entries are being processed
|
* @param string $user The user whose log entries are being processed
|
||||||
* @param PDOStatement $checkStmt A prepared statement to check if an entry
|
* @param PDOStatement $checkStmt A prepared statement to check if an entry
|
||||||
* already exists in the database
|
* already exists in the database
|
||||||
* @param PDOStatement $insertStmt A prepared statement to insert a new entry
|
* @param PDOStatement $insertStmt A prepared statement to insert a new entry
|
||||||
* into the database
|
* into the database
|
||||||
* @param boolean $debug Whether to output debug information (default: false)
|
* @param boolean $debug Whether to output debug information (default: false)
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
function processLogEntries($logEntries, $user, $checkStmt, $insertStmt, $debug) {
|
function processLogEntries($logEntries, $user, $checkStmt, $insertStmt, $debug) {
|
||||||
foreach ($logEntries as $key =>$entry) {
|
foreach ($logEntries as $key =>$entry) {
|
||||||
if ($debug) {
|
if ($debug) {
|
||||||
$logMessage = "Raw entry:\n" . print_r($entry, true);
|
$logMessage = "Raw entry:\n" . print_r($entry, true);
|
||||||
file_put_contents(__DIR__ . '/debug.log', $logMessage, FILE_APPEND);
|
file_put_contents(__DIR__ . '/debug.log', $logMessage, FILE_APPEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
$timestamp = $entry['timestamp'];
|
||||||
|
$description = $entry['title'];
|
||||||
|
$amount = $entry['log'] === 5850 ? $entry['data']['deposited'] : -$entry['data']['withdrawn'];
|
||||||
|
|
||||||
|
if ($debug) {
|
||||||
|
$logMessage = "Vault entry:\n\tUser: $user,\n\tTimestamp: $timestamp,\n\tDescription: $description,\n\tAmount: $amount\n";
|
||||||
|
file_put_contents(__DIR__ . '/debug.log', $logMessage, FILE_APPEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
$checkStmt->execute(
|
||||||
|
[
|
||||||
|
':user' => $user,
|
||||||
|
':timestamp' => $timestamp,
|
||||||
|
':amount' => $amount
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($checkStmt->fetchColumn() == 0) {
|
||||||
|
$insertStmt->execute(
|
||||||
|
[
|
||||||
|
':id' => $key,
|
||||||
|
':user' => $user,
|
||||||
|
':timestamp' => $timestamp,
|
||||||
|
':description' => $description,
|
||||||
|
':amount' => $amount
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$timestamp = $entry['timestamp'];
|
|
||||||
$description = $entry['title'];
|
|
||||||
$amount = $entry['log'] === 5850 ? $entry['data']['deposited'] : -$entry['data']['withdrawn'];
|
|
||||||
|
|
||||||
if ($debug) {
|
|
||||||
$logMessage = "Vault entry:\n\tUser: $user,\n\tTimestamp: $timestamp,\n\tDescription: $description,\n\tAmount: $amount\n";
|
|
||||||
file_put_contents(__DIR__ . '/debug.log', $logMessage, FILE_APPEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
$checkStmt->execute([
|
|
||||||
':user' => $user,
|
|
||||||
':timestamp' => $timestamp,
|
|
||||||
':amount' => $amount
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($checkStmt->fetchColumn() == 0) {
|
|
||||||
$insertStmt->execute([
|
|
||||||
':id' => $key,
|
|
||||||
':user' => $user,
|
|
||||||
':timestamp' => $timestamp,
|
|
||||||
':description' => $description,
|
|
||||||
':amount' => $amount
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fetch vault records from the database
|
/**
|
||||||
|
* Fetch vault records from the database
|
||||||
* If a user is provided, only that user's records
|
* If a user is provided, only that user's records
|
||||||
* are returned. Otherwise, all records are returned.
|
* are returned. Otherwise, all records are returned.
|
||||||
*
|
*
|
||||||
@@ -149,29 +182,30 @@ function processLogEntries($logEntries, $user, $checkStmt, $insertStmt, $debug)
|
|||||||
* @return array An array of records, or an empty array on error
|
* @return array An array of records, or an empty array on error
|
||||||
*/
|
*/
|
||||||
function fetchVaultRecords($user = null) {
|
function fetchVaultRecords($user = null) {
|
||||||
$pdo = getDatabaseConnection();
|
$pdo = getDatabaseConnection();
|
||||||
|
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$query = "SELECT * FROM vault WHERE user = :user ORDER BY timestamp DESC";
|
$query = "SELECT * FROM vault WHERE user = :user ORDER BY timestamp DESC";
|
||||||
$params = [':user' => $user];
|
$params = [':user' => $user];
|
||||||
} else {
|
} else {
|
||||||
$query = "SELECT * FROM vault ORDER BY timestamp DESC";
|
$query = "SELECT * FROM vault ORDER BY timestamp DESC";
|
||||||
$params = [];
|
$params = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $pdo->prepare($query);
|
$stmt = $pdo->prepare($query);
|
||||||
$stmt->execute($params);
|
$stmt->execute($params);
|
||||||
|
|
||||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
echo "Error fetching records: " . $e->getMessage();
|
echo "Error fetching records: " . $e->getMessage();
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Iterate over all vault records for the given user (or all users if no user is given),
|
/**
|
||||||
|
* Iterate over all vault records for the given user (or all users if no user is given),
|
||||||
*
|
*
|
||||||
* @param string|null $name (optional) The user to loop over records for.
|
* @param string|null $name (optional) The user to loop over records for.
|
||||||
* If not provided, all users' records will be looped over.
|
* If not provided, all users' records will be looped over.
|
||||||
@@ -179,15 +213,18 @@ function fetchVaultRecords($user = null) {
|
|||||||
* @return int The total balance of the given user (or all users if no user is given).
|
* @return int The total balance of the given user (or all users if no user is given).
|
||||||
*/
|
*/
|
||||||
function vaultLoop ($name=null) {
|
function vaultLoop ($name=null) {
|
||||||
$vault = fetchVaultRecords($name);
|
$vault = fetchVaultRecords($name);
|
||||||
$balance = 0;
|
$balance = 0;
|
||||||
|
|
||||||
foreach ($vault as $entry) { $balance += $entry['amount']; }
|
foreach ($vault as $entry) {
|
||||||
|
$balance += $entry['amount'];
|
||||||
|
}
|
||||||
|
|
||||||
return $balance;
|
return $balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a string indicating the sign of a number, with a dollar symbol.
|
/**
|
||||||
|
* Returns a string indicating the sign of a number, with a dollar symbol.
|
||||||
*
|
*
|
||||||
* @param int|float $number The number to check.
|
* @param int|float $number The number to check.
|
||||||
*
|
*
|
||||||
@@ -195,7 +232,9 @@ function vaultLoop ($name=null) {
|
|||||||
* number is negative.
|
* number is negative.
|
||||||
*/
|
*/
|
||||||
function getSign($number) {
|
function getSign($number) {
|
||||||
if (substr($number, 0, 1) == '-') { return '-$'; }
|
if (substr($number, 0, 1) == '-') {
|
||||||
|
return '-$';
|
||||||
|
}
|
||||||
|
|
||||||
return '$';
|
return '$';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,92 +1,103 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once __DIR__ . '/config.php';
|
/**
|
||||||
include_once __DIR__ . '/functions.php';
|
* Main entry point for the Torn Vault Tracker application.
|
||||||
|
*
|
||||||
if (dbNew()) {
|
* PHP version 8.1+
|
||||||
foreach (USER_KEYS as $key => $value) {
|
*
|
||||||
firstRun($key);
|
* @category Main
|
||||||
}
|
* @package TornVaultTracker
|
||||||
header('Location: /');
|
* @author Keith Solomon <ksolmon@gmail.com>
|
||||||
} else {
|
* @license Unlicense https://unlicense.org/
|
||||||
foreach (USER_KEYS as $key => $value) {
|
* @link https://github.com/ksolmon/torn-vault-tracker
|
||||||
getLog($key);
|
*/
|
||||||
}
|
require_once __DIR__ . '/config.php';
|
||||||
}
|
require_once __DIR__ . '/functions.php';
|
||||||
?>
|
|
||||||
|
if (dbNew()) {
|
||||||
<!DOCTYPE html>
|
foreach (USER_KEYS as $key => $value) {
|
||||||
<html lang="en">
|
firstRun($key);
|
||||||
|
}
|
||||||
<head>
|
header('Location: /');
|
||||||
<meta charset="UTF-8">
|
} else {
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
foreach (USER_KEYS as $key => $value) {
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
getLog($key);
|
||||||
<title>Torn Vault Tracker</title>
|
}
|
||||||
<link rel="icon" type="image/png" href="favicon.png">
|
}
|
||||||
|
?>
|
||||||
<link rel="stylesheet" href="style.css?v=<?php echo filemtime('style.css'); ?>">
|
|
||||||
|
<!DOCTYPE html>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<html lang="en">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital@0;1&display=swap" rel="stylesheet">
|
<head>
|
||||||
</head>
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<body>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<h1>Torn Vault Tracker</h1>
|
<title>Torn Vault Tracker</title>
|
||||||
|
<link rel="icon" type="image/png" href="favicon.png">
|
||||||
<div class="grid">
|
|
||||||
<div class="gridLeft">
|
<link rel="stylesheet" href="style.css?v=<?php echo filemtime('style.css'); ?>">
|
||||||
<h1>Transactions</h1>
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<table id="data">
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<thead>
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital@0;1&display=swap" rel="stylesheet">
|
||||||
<tr>
|
</head>
|
||||||
<th><h4>User</h4></th>
|
|
||||||
<th><h4>Date / Time (TCT)</h4></th>
|
<body>
|
||||||
<th><h4>Operation</h4></th>
|
<h1>Torn Vault Tracker</h1>
|
||||||
<th><h4>Amount</h4></th>
|
|
||||||
</tr>
|
<div class="grid">
|
||||||
</thead>
|
<div class="gridLeft">
|
||||||
|
<h1>Transactions</h1>
|
||||||
<tbody>
|
|
||||||
<?php buildTable(); ?>
|
<table id="data">
|
||||||
</tbody>
|
<thead>
|
||||||
</table>
|
<tr>
|
||||||
|
<th><h4>User</h4></th>
|
||||||
<div id="pagination-controls">
|
<th><h4>Date / Time (TCT)</h4></th>
|
||||||
<button onclick="changePage(-999)">«</button>
|
<th><h4>Operation</h4></th>
|
||||||
<button onclick="changePage(-1)">‹</button>
|
<th><h4>Amount</h4></th>
|
||||||
<div id="page-info">Page x of y</div>
|
</tr>
|
||||||
<button onclick="changePage(1)">›</button>
|
</thead>
|
||||||
<button onclick="changePage(999)">»</button>
|
|
||||||
</div>
|
<tbody>
|
||||||
</div>
|
<?php buildTable(); ?>
|
||||||
|
</tbody>
|
||||||
<div class="gridRight">
|
</table>
|
||||||
<h1>Balances</h1>
|
|
||||||
|
<div id="pagination-controls">
|
||||||
<section class="vault">
|
<button onclick="changePage(-999)">«</button>
|
||||||
<h2>Vault Balance: $<?php echo generateBalance(); ?></h2>
|
<button onclick="changePage(-1)">‹</button>
|
||||||
<h3>Space left: $<?php echo getSpace(); ?></h3>
|
<div id="page-info">Page x of y</div>
|
||||||
</section>
|
<button onclick="changePage(1)">›</button>
|
||||||
|
<button onclick="changePage(999)">»</button>
|
||||||
<h2>Shares</h2>
|
</div>
|
||||||
<div class="grid">
|
</div>
|
||||||
<?php foreach (USER_KEYS as $key => $value) { ?>
|
|
||||||
<section class="user">
|
<div class="gridRight">
|
||||||
<h3><?php echo ucfirst($key); ?> balance: $<?php echo generateBalance($key); ?></h3>
|
<h1>Balances</h1>
|
||||||
<h4>Share left: $<?php echo getSpace($key); ?></h4>
|
|
||||||
</section>
|
<section class="vault">
|
||||||
<?php } ?>
|
<h2>Vault Balance: $<?php echo generateBalance(); ?></h2>
|
||||||
</div>
|
<h3>Space left: $<?php echo getSpace(); ?></h3>
|
||||||
</div>
|
</section>
|
||||||
</div>
|
|
||||||
|
<h2>Shares</h2>
|
||||||
<script src="script.js"></script>
|
<div class="grid">
|
||||||
<script>
|
<?php foreach (USER_KEYS as $key => $value) { ?>
|
||||||
let rowsPerPage = <?php echo ROWS_PER_PAGE; ?>; // Set in config.php
|
<section class="user">
|
||||||
|
<h3><?php echo ucfirst($key); ?> balance: $<?php echo generateBalance($key); ?></h3>
|
||||||
paginate();
|
<h4>Share left: $<?php echo getSpace($key); ?></h4>
|
||||||
</script>
|
</section>
|
||||||
</body>
|
<?php } ?>
|
||||||
</html>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="script.js"></script>
|
||||||
|
<script>
|
||||||
|
let rowsPerPage = <?php echo ROWS_PER_PAGE; ?>; // Set in config.php
|
||||||
|
|
||||||
|
paginate();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<ruleset name="Coding Style Checks">
|
||||||
|
<description>Coding Style Checks</description>
|
||||||
|
<ini name="error_reporting" value="E_ALL & ~E_DEPRECATED" />
|
||||||
|
|
||||||
|
<arg value="sp"/>
|
||||||
|
<arg name="colors"/>
|
||||||
|
<arg name="extensions" value="php,html,css"/>
|
||||||
|
<arg name="parallel" value="2048"/>
|
||||||
|
|
||||||
|
<exclude-pattern>vendor/</exclude-pattern>
|
||||||
|
<exclude-pattern>node_modules/</exclude-pattern>
|
||||||
|
|
||||||
|
<rule ref="PEAR">
|
||||||
|
<exclude name="PEAR.Classes.ClassDeclaration"/>
|
||||||
|
<exclude name="PEAR.Functions.FunctionDeclaration"/>
|
||||||
|
<exclude name="Generic.Files.LineLength.TooLong"/>
|
||||||
|
<exclude name="Generic.WhiteSpace.DisallowSpaceIndent.SpacesUsed"/>
|
||||||
|
<exclude name="Generic.Functions.CallTimePassByReference"/>
|
||||||
|
<exclude name="Squiz.Commenting.FileComment.MissingPackageTag"/>
|
||||||
|
<exclude name="Squiz.Commenting.FileComment.Missing"/>
|
||||||
|
<exclude name="Squiz.Commenting.FileComment.WrongStyle"/>
|
||||||
|
<exclude name="Squiz.Commenting.InlineComment.InvalidEndChar"/>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="Internal.NoCodeFound">
|
||||||
|
<severity>0</severity>
|
||||||
|
</rule>
|
||||||
|
</ruleset>
|
||||||
@@ -1,60 +1,60 @@
|
|||||||
:root {
|
:root {
|
||||||
--red: #f77e82;
|
--red: #f77e82;
|
||||||
--green: #08817d;
|
--green: #08817d;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: #000;
|
background: #000;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: 'Roboto', sans-serif;
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
color: #000;
|
color: #000;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
table, tr, td, th {
|
table, tr, td, th {
|
||||||
border: 1px solid #333;
|
border: 1px solid #333;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
thead th {
|
thead th {
|
||||||
background: #ccc;
|
background: #ccc;
|
||||||
color: #000;
|
color: #000;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: .15em 1em;
|
padding: .15em 1em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.debit { background-color: var(--red); }
|
tr.debit { background-color: var(--red); }
|
||||||
|
|
||||||
tr.credit { background-color: var(--green); color: #fff; }
|
tr.credit { background-color: var(--green); color: #fff; }
|
||||||
|
|
||||||
td { padding: .15em 1em; }
|
td { padding: .15em 1em; }
|
||||||
|
|
||||||
#pagination-controls {
|
#pagination-controls {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 1em;
|
gap: 1em;
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2, h3, h4 { margin: 0; }
|
h2, h3, h4 { margin: 0; }
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
grid-template-rows: 1fr;
|
grid-template-rows: 1fr;
|
||||||
grid-column-gap: 4em;
|
grid-column-gap: 4em;
|
||||||
grid-row-gap: 0px;
|
grid-row-gap: 0px;
|
||||||
margin-top: .5em;
|
margin-top: .5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vault { margin: 0 0 3em; }
|
.vault { margin: 0 0 3em; }
|
||||||
|
|
||||||
.vault h3, h4 { font-style: italic; }
|
.vault h3, h4 { font-style: italic; }
|
||||||
|
|||||||
Reference in New Issue
Block a user