diff --git a/public/include/classes/bitcoinwrapper.class.php b/public/include/classes/bitcoinwrapper.class.php index 9f2ad861..eb6d55e0 100644 --- a/public/include/classes/bitcoinwrapper.class.php +++ b/public/include/classes/bitcoinwrapper.class.php @@ -4,6 +4,10 @@ if (!defined('SECURITY')) die('Hacking attempt'); +/** + * We use a wrapper class around BitcoinClient to add + * some basic caching functionality and some debugging + **/ class BitcoinWrapper extends BitcoinClient { public function __construct($type, $username, $password, $host, $debug, $memcache) { $this->type = $type; diff --git a/public/include/classes/block.class.php b/public/include/classes/block.class.php index cd5e0456..cfafc85f 100644 --- a/public/include/classes/block.class.php +++ b/public/include/classes/block.class.php @@ -27,17 +27,27 @@ class Block { return $this->table; } + /** + * Specific method to fetch the latest block found + * @param none + * @return data array Array with database fields as keys + **/ public function getLast() { $stmt = $this->mysqli->prepare("SELECT * FROM $this->table ORDER BY height DESC LIMIT 1"); if ($this->checkStmt($stmt)) { $stmt->execute(); $result = $stmt->get_result(); $stmt->close(); - return $result->fetch_object(); + return $result->fetch_assoc(); } return false; } + /** + * Fetch all unaccounted blocks + * @param order string Sort order, default ASC + * @return data array Array with database fields as keys + **/ public function getAllUnaccounted($order='ASC') { $stmt = $this->mysqli->prepare("SELECT * FROM $this->table WHERE accounted = 0 ORDER BY height $order"); if ($this->checkStmt($stmt)) { @@ -49,6 +59,11 @@ class Block { return false; } + /** + * Fetch all unconfirmed blocks from table + * @param confirmations int Required confirmations to consider block confirmed + * @return data array Array with database fields as keys + **/ public function getAllUnconfirmed($confirmations='120') { $stmt = $this->mysqli->prepare("SELECT id, blockhash, confirmations FROM $this->table WHERE confirmations < ? AND confirmations > -1"); if ($this->checkStmt($stmt)) { @@ -61,6 +76,12 @@ class Block { return false; } + /** + * Update confirmations for an existing block + * @param block_id int Block ID to update + * @param confirmations int New confirmations value + * @return bool + **/ public function setConfirmations($block_id, $confirmations) { $stmt = $this->mysqli->prepare("UPDATE $this->table SET confirmations = ? WHERE id = ?"); if ($this->checkStmt($stmt)) { @@ -72,6 +93,11 @@ class Block { return false; } + /** + * Fetch all blocks ordered by DESC height + * @param order string ASC or DESC ordering + * @return data array Array with database fields as keys + **/ public function getAll($order='DESC') { $stmt = $this->mysqli->prepare("SELECT * FROM $this->table ORDER BY height $order"); if ($this->checkStmt($stmt)) { @@ -83,6 +109,11 @@ class Block { return false; } + /** + * Add new new block to the database + * @param block array Block data as an array, see bind_param + * @return bool + **/ public function addBlock($block) { $stmt = $this->mysqli->prepare("INSERT INTO $this->table (height, blockhash, confirmations, amount, difficulty, time) VALUES (?, ?, ?, ?, ?, ?)"); if ($this->checkStmt($stmt)) { @@ -99,6 +130,13 @@ class Block { return false; } + /** + * Update a single column within a single row + * @param block_id int Block ID to update + * @param field string Column name to update + * @param value string Value to insert + * @return bool + **/ private function updateSingle($block_id, $field, $value) { $stmt = $this->mysqli->prepare("UPDATE $this->table SET $field = ? WHERE id = ?"); if ($this->checkStmt($stmt)) { @@ -114,19 +152,39 @@ class Block { return false; } + /** + * Set finder of a block + * @param block_id int Block ID + * @param account_id int Account ID of finder + * @return bool + **/ public function setFinder($block_id, $account_id=NULL) { return $this->updateSingle($block_id, 'account_id', $account_id); } + /** + * Set counted shares for a block + * @param block_id int Block ID + * @param shares int Share count + * @return bool + **/ public function setShares($block_id, $shares=NULL) { return $this->updateSingle($block_id, 'shares', $shares); } + /** + * Set block to be accounted for + * @param block_id int Block ID + * @return bool + **/ public function setAccounted($block_id=NULL) { if (empty($block_id)) return false; return $this->updateSingle($block_id, 'accounted', 1); } + /** + * Helper function + **/ private function checkStmt($bState) { if ($bState ===! true) { $this->debug->append("Failed to prepare statement: " . $this->mysqli->error); @@ -137,4 +195,5 @@ class Block { } } +// Automatically load our class for furhter usage $block = new Block($debug, $mysqli, SALT); diff --git a/public/include/classes/setting.class.php b/public/include/classes/setting.class.php index 44ef8315..f2c1cbea 100644 --- a/public/include/classes/setting.class.php +++ b/public/include/classes/setting.class.php @@ -12,6 +12,11 @@ class Setting { $this->table = 'settings'; } + /** + * Fetch a value from our table + * @param name string Setting name + * @return value string Value + **/ public function getValue($name) { $query = $this->mysqli->prepare("SELECT value FROM $this->table WHERE name=? LIMIT 1"); if ($query) { @@ -27,6 +32,12 @@ class Setting { return $value; } + /** + * Insert or update a setting + * @param name string Name of the variable + * @param value string Variable value + * @return bool + **/ public function setValue($name, $value) { $stmt = $this->mysqli->prepare(" INSERT INTO $this->table (name, value) diff --git a/public/include/classes/share.class.php b/public/include/classes/share.class.php index 9a14aeeb..1fb195e0 100644 --- a/public/include/classes/share.class.php +++ b/public/include/classes/share.class.php @@ -27,13 +27,29 @@ class Share { return $this->sError; } + /** + * Fetch archive tables name for this class + * @param none + * @return data string Table name + **/ public function getArchiveTableName() { return $this->tableArchive; } + /** + * Fetch normal table name for this class + * @param none + * @return data string Table name + **/ public function getTableName() { return $this->table; } + /** + * Get all valid shares for this round + * @param previous_upstream int Previous found share accepted by upstream to limit results + * @param current_upstream int Current upstream accepted share + * @return data int Total amount of counted shares + **/ public function getRoundShares($previous_upstream=0, $current_upstream) { $stmt = $this->mysqli->prepare("SELECT count(id) as total @@ -51,6 +67,12 @@ class Share { return false; } + /** + * Fetch all shares grouped by accounts to count share per account + * @param previous_upstream int Previous found share accepted by upstream to limit results + * @param current_upstream int Current upstream accepted share + * @return data array username, valid and invalid shares from account + **/ public function getSharesForAccounts($previous_upstream=0, $current_upstream) { $stmt = $this->mysqli->prepare("SELECT a.id, @@ -90,6 +112,13 @@ class Share { return false; } + /** + * Move accounted shares to archive table, this step is optional + * @param previous_upstream int Previous found share accepted by upstream to limit results + * @param current_upstream int Current upstream accepted share + * @param block_id int Block ID to assign shares to a specific block + * @return bool + **/ public function moveArchive($previous_upstream=0, $current_upstream,$block_id) { $archive_stmt = $this->mysqli->prepare("INSERT INTO $this->tableArchive (share_id, username, our_result, upstream_result, block_id, time) SELECT id, username, our_result, upstream_result, ?, time @@ -108,6 +137,9 @@ class Share { return false; } + /** + * Set/get last found share accepted by upstream: id and accounts + **/ public function setLastUpstreamId() { $this->iLastUpstreamId = @$this->oUpstream->id ? $this->oUpstream->id : 0; } @@ -120,6 +152,12 @@ class Share { public function getUpstreamId() { return @$this->oUpstream->id; } + /** + * Find upstream accepted share that should be valid for a specific block + * We allow for +/- 5 seconds here to ensure we find a share + * @param time timestamp Time of when the block was found + * @return bool + **/ public function setUpstream($time='') { $stmt = $this->mysqli->prepare("SELECT SUBSTRING_INDEX( `username` , '.', 1 ) AS account, id @@ -141,6 +179,9 @@ class Share { return false; } + /** + * Helper function + **/ private function checkStmt($bState) { if ($bState ===! true) { $this->debug->append("Failed to prepare statement: " . $this->mysqli->error); diff --git a/public/include/classes/tools.class.php b/public/include/classes/tools.class.php index 530316e6..e97b3746 100644 --- a/public/include/classes/tools.class.php +++ b/public/include/classes/tools.class.php @@ -4,6 +4,11 @@ if (!defined('SECURITY')) die('Hacking attempt'); +/** + * Helper class for our cronjobs + * Implements some common cron tasks outside + * the scope of our web application + **/ class Tools { public function __construct($debug) { $this->debug = $debug; diff --git a/public/include/classes/transaction.class.php b/public/include/classes/transaction.class.php index 27871655..15f29c77 100644 --- a/public/include/classes/transaction.class.php +++ b/public/include/classes/transaction.class.php @@ -25,6 +25,15 @@ class Transaction { return $this->sError; } + /** + * Add a new transaction to our class table + * @param account_id int Account ID to book transaction for + * @param amount float Coin amount + * @param type string Transaction type [Credit, Debit_AP, Debit_MP, Fee, Donation, Orphan_Credit, Orphan_Fee, Orphan_Donation] + * @param block_id int Block ID to link transaction to [optional] + * @param coin_address string Coin address for this transaction [optional] + * @return bool + **/ public function addTransaction($account_id, $amount, $type='Credit', $block_id=NULL, $coin_address=NULL) { $stmt = $this->mysqli->prepare("INSERT INTO $this->table (account_id, amount, block_id, type, coin_address) VALUES (?, ?, ?, ?, ?)"); if ($this->checkStmt($stmt)) { @@ -38,6 +47,12 @@ class Transaction { return false; } + /** + * Sometimes transactions become orphans when a block associated to them is orphaned + * Updates the transaction types to Orphan_ + * @param block_id int Orphaned block ID + * @return bool + **/ public function setOrphan($block_id) { $this->debug->append("STA " . __METHOD__, 4); $stmt = $this->mysqli->prepare(" @@ -73,6 +88,12 @@ class Transaction { return true; } + /** + * Get all transactions from start for account_id + * @param account_id int Account ID + * @param start int Starting point, id of transaction + * @return data array Database fields as defined in SELECT + **/ public function getTransactions($account_id, $start=0) { $this->debug->append("STA " . __METHOD__, 4); $stmt = $this->mysqli->prepare(" @@ -144,6 +165,11 @@ class Transaction { return false; } + /** + * Get an accounts total balance + * @param account_id int Account ID + * @return data float Credit - Debit - Fees - Donation + **/ public function getBalance($account_id) { $this->debug->append("STA " . __METHOD__, 4); $stmt = $this->mysqli->prepare(" diff --git a/public/include/classes/user.class.php b/public/include/classes/user.class.php index 120014e4..d6582676 100644 --- a/public/include/classes/user.class.php +++ b/public/include/classes/user.class.php @@ -183,6 +183,14 @@ class User { return true; } + /** + * Update the accounts password + * @param userID int User ID + * @param current string Current password + * @param new1 string New password + * @param new2 string New password confirmation + * @return bool + **/ public function updatePassword($userID, $current, $new1, $new2) { $this->debug->append("STA " . __METHOD__, 4); if ($new1 !== $new2) { @@ -208,6 +216,14 @@ class User { return false; } + /** + * Update account information from the edit account page + * @param userID int User ID + * @param address string new coin address + * @param threshold float auto payout threshold + * @param donat float donation % of income + * @return bool + **/ public function updateAccount($userID, $address, $threshold, $donate) { $this->debug->append("STA " . __METHOD__, 4); $bUser = false; @@ -241,6 +257,12 @@ class User { die('Access denied'); } + /** + * Check a password for a user + * @param username string Username + * @param password string Password + * @return bool + **/ private function checkUserPassword($username, $password) { $this->debug->append("STA " . __METHOD__, 4); $user = array(); @@ -258,6 +280,11 @@ class User { return false; } + /** + * Create a PHP session for a user + * @param username string Username to create session for + * @return none + **/ private function createSession($username) { $this->debug->append("STA " . __METHOD__, 4); $this->debug->append("Log in user to _SESSION", 2); @@ -267,6 +294,11 @@ class User { $_SESSION['USERDATA'] = $this->user; } + /** + * Log out current user, destroy the session + * @param none + * @return true + **/ public function logoutUser() { $this->debug->append("STA " . __METHOD__, 4); session_destroy(); @@ -274,11 +306,20 @@ class User { return true; } + /** + * Fetch this classes table name + * @return table string This classes table name + **/ public function getTableName() { $this->debug->append("STA " . __METHOD__, 4); return $this->table; } + /** + * Fetch some basic user information to store for later user + * @param userID int User ID + * return data array Database fields as used in SELECT + **/ public function getUserData($userID) { $this->debug->append("STA " . __METHOD__, 4); $this->debug->append("Fetching user information for user id: $userID"); @@ -302,6 +343,16 @@ class User { return false; } + /** + * Register a new user in the system + * @param username string Username + * @param password1 string Password + * @param password2 string Password verification + * @param pin int 4 digit PIN code + * @param email1 string Email address + * @param email2 string Email confirmation + * @return bool + **/ public function register($username, $password1, $password2, $pin, $email1='', $email2='') { $this->debug->append("STA " . __METHOD__, 4); if (strlen($password1) < 8) { @@ -350,6 +401,13 @@ class User { return false; } + /** + * User a one time token to reset a password + * @param token string one time token + * @param new1 string New password + * @param new2 string New password verification + * @return bool + **/ public function useToken($token, $new1, $new2) { $this->debug->append("STA " . __METHOD__, 4); if ($id = $this->getIdFromToken($token)) { @@ -373,6 +431,12 @@ class User { return false; } + /** + * Reset a password by sending a password reset mail + * @param username string Username to reset password for + * @param smarty object Smarty object for mail templating + * @return bool + **/ public function resetPassword($username, $smarty) { $this->debug->append("STA " . __METHOD__, 4); // Fetch the users mail address @@ -408,4 +472,5 @@ class User { } } +// Make our class available automatically $user = new User($debug, $mysqli, SALT, $config);