function number_format_autoprecision_html($n, $suffix = false) { return "<span title=\"" . number_format_autoprecision($n, 8) . ($suffix ? $suffix : "") . "\">" . number_format_autoprecision($n) . ($suffix ? $suffix : "") . "</span>"; }
/** * Format a number to a human readable amount of precision. */ function number_format_human($n, $extra_precision = 0) { if (abs($n) < 0.0001) { return number_format_autoprecision($n, 8 + $extra_precision, '.', ''); } else { if (abs($n) < 0.01) { return number_format_autoprecision($n, 6 + $extra_precision, '.', ''); } else { if (abs($n) < 10000.0) { return number_format_autoprecision($n, 4 + $extra_precision, '.', ''); } else { if (abs($n) < 1000000.0) { return number_format_autoprecision($n, 2 + $extra_precision, '.', ''); } else { return number_format_autoprecision($n, 0 + $extra_precision, '.', ''); } } } } }
/** * @return a HTML string that can be used in an e-mail, listing all prices */ function get_html_premium_prices() { $prices = array(); foreach (get_site_config('premium_currencies') as $currency) { $prices[] = " " . get_currency_abbr($currency) . ": " . number_format_autoprecision(get_premium_price($currency, 'monthly')) . " " . get_currency_abbr($currency) . "/month, or " . number_format_autoprecision(get_premium_price($currency, 'yearly')) . " " . get_currency_abbr($currency) . "/year" . (get_site_config('premium_' . $currency . '_discount') ? " (" . (int) (get_site_config('premium_' . $currency . '_discount') * 100) . "% off)" : ""); } return implode("<br>\n", $prices); }
throw new PurchaseException(t("Could not generate :currency address for purchase; please try again later.", array(':currency' => get_currency_abbr($currency)))); } // register it to the system as a normal blockchain address, but we need to get received rather than balance $q = db()->prepare("INSERT INTO addresses SET user_id=:user_id, address=:address, currency=:currency, is_received=1"); $q->execute(array("user_id" => get_site_config('system_user_id'), "address" => $address['address'], "currency" => $currency)); $new_address_id = db()->lastInsertId(); // create a new outstanding premium $q = db()->prepare("INSERT INTO outstanding_premiums SET user_id=:user_id, premium_address_id=:pid, address_id=:aid, balance=:balance, months=:months, years=:years"); $q->execute(array("user_id" => user_id(), "pid" => $address['id'], "aid" => $new_address_id, "balance" => $cost, "months" => $months, "years" => $years)); $purchase_id = db()->lastInsertId(); // address is now in use $q = db()->prepare("UPDATE premium_addresses SET is_used=1,used_at=NOW() WHERE id=?"); $q->execute(array($address['id'])); // try sending email, if an email address has been registered if ($user['email']) { send_user_email($user, "purchase", array("name" => $user['name'] ? $user['name'] : $user['email'], "amount" => number_format_autoprecision($cost), "currency" => get_currency_abbr($currency), "currency_name" => get_currency_name($currency), "address" => $address['address'], "explorer" => get_explorer_address($currency, $address['address']), "url" => absolute_url(url_for("user#user_outstanding")))); } // success! inform the user redirect(url_for('user#user_outstanding', array('new_purchase' => $purchase_id))); } catch (PurchaseException $e) { log_uncaught_exception($e); $errors[] = $e->getMessage(); } } page_header(t("Purchase Premium"), "page_purchase", array('js' => 'purchase')); ?> <h1><?php echo ht("Purchase Premium with :currency", array(':currency' => get_currency_name($currency))); ?> </h1>
function api_v1_graphs($graph) { $start_time = microtime(true); $result = array(); /** * Graph rendering goes like this: * 0. check graph rendering permissions * 1. get raw graph data (from a {@link GraphRenderer} through {@link construct_graph_renderer()}) * 2. apply deltas as necessary * 3. add technicals as necessary * 4. strip dates outside of the requested ?days parameter (e.g. from extra_days) * 5. construct heading and links * 6. construct subheading and revise last_updated * 7. return data * that is, deltas and technicals are done on the server-side; not the client-side. */ $renderer = construct_graph_renderer($graph['graph_type'], $graph['arg0'], $graph['arg0_resolved']); // 0. check graph rendering permissions if ($renderer->requiresUser()) { if (!isset($graph['user_id']) || !$graph['user_id']) { throw new GraphException("No user specified for authenticated graph"); } if (!isset($graph['user_hash']) || !$graph['user_hash']) { throw new GraphException("No user hash specified for authenticated graph"); } $user = get_user($graph['user_id']); if (!$user) { throw new GraphException("No such user found"); } if (!has_expected_user_graph_hash($graph['user_hash'], $user)) { throw new GraphException("Mismatched user hash for user " . $graph['user_id'] . " with graph type " . $graph['graph_type']); } if ($renderer->requiresAdmin()) { if (!$user['is_admin']) { throw new GraphException("Graph requires administrator privileges"); } } $renderer->setUser($user['id']); } if ($renderer->usesDays()) { // 0.5 limit 'days' parameter as necessary $get_permitted_days = get_permitted_days(); $has_valid_days = false; foreach ($get_permitted_days as $key => $days) { if ($days['days'] == $graph['days']) { $has_valid_days = true; } } if (!$has_valid_days) { throw new GraphException("Invalid days '" . $graph['days'] . "' for graph that requires days"); } } // 1. get raw graph data try { $data = $renderer->getData($graph['days']); $original_count = count($data['data']); $result['type'] = $renderer->getChartType(); // 2. apply deltas as necessary $data['data'] = calculate_graph_deltas($graph, $data['data'], false); // if there is no data, bail out early if (count($data['data']) == 0) { $result['type'] = 'nodata'; } else { if ($renderer->canHaveTechnicals()) { // 3. add technicals as necessary // (only if there is at least one point of data, otherwise calculate_technicals() will throw an error) $technicals = calculate_technicals($graph, $data['data'], $data['columns'], false); $data['columns'] = $technicals['headings']; $data['data'] = $technicals['data']; } } // 4. discard early data if ($renderer->usesDays()) { $data['data'] = discard_early_data($data['data'], $graph['days']); $after_discard_count = count($data['data']); } $result['columns'] = $data['columns']; $result['key'] = $data['key']; $result['data'] = $data['data']; // clean up columns foreach ($result['columns'] as $key => $value) { $result['columns'][$key]['technical'] = isset($result['columns'][$key]['technical']) && $result['columns'][$key]['technical'] ? true : false; if ($result['columns'][$key]['technical']) { if (!isset($result['columns'][$key]['type'])) { $result['columns'][$key]['type'] = 'number'; } } } } catch (NoDataGraphException_AddAccountsAddresses $e) { $result['type'] = 'nodata'; $result['text'] = ct("Either you have not specified any accounts or addresses, or these addresses and accounts have not yet been updated by :site_name."); $result['args'] = array(':site_name' => get_site_config('site_name')); $result['data'] = array(); $data['last_updated'] = false; $data['add_accounts_addresses'] = true; } catch (NoDataGraphException_AddCurrencies $e) { $result['type'] = 'nodata'; $result['text'] = ct("Either you have not enabled this currency, or your summaries for this currency have not yet been updated by :site_name."); $result['args'] = array(':site_name' => get_site_config('site_name')); $result['data'] = array(); $data['last_updated'] = false; $data['add_more_currencies'] = true; } // 5. construct heading and links $result['heading'] = array('label' => $renderer->getTitle(), 'args' => $renderer->getTitleArgs(), 'url' => $renderer->getURL(), 'title' => $renderer->getLabel()); if (isset($data['h1'])) { $result['h1'] = $data['h1']; } if (isset($data['h2'])) { $result['h2'] = $data['h2']; } if (isset($data['no_header'])) { $result['noHeader'] = $data['no_header']; } // 6. construct subheading and revise last_updated\ if ($result['type'] != 'nodata' && $renderer->hasSubheading()) { $suffix = ""; if ($graph['delta'] == 'percent') { $suffix .= '%'; } if ($renderer->getCustomSubheading() !== false) { $result['subheading'] = number_format_html($renderer->getCustomSubheading(), 4, $suffix); } else { if ($result['type'] == 'piechart') { // sum up the first row and use that as a total if (count($data['data']) != 1) { throw new GraphException("Expected one row of data for a piechart, got " . count($data['data'])); } $sum = 0; foreach ($data['data'] as $ignored => $row) { foreach ($row as $value) { $sum += $value; } } $result['subheading'] = number_format_html($sum, 4, $suffix); } else { $result['subheading'] = format_subheading_values_objects($graph, $data['data'], $data['columns']); } } } $result['lastUpdated'] = recent_format_html($data['last_updated']); $result['timestamp'] = iso_date(); $result['classes'] = $renderer->getClasses(); $result['graph_type'] = $graph['graph_type']; if (is_localhost()) { $result['_debug'] = $graph; if (isset($after_discard_count)) { $result['_debug']['data_discarded'] = $original_count - $after_discard_count; } else { $result['_debug']['data_not_discarded'] = true; } } // make sure that all 'number'-typed data is numeric foreach ($result['data'] as $i => $row) { foreach ($row as $key => $value) { $column = $result['columns'][$key]; if ($column['type'] == 'number' || $column['type'] == 'percent') { $result['data'][$i][$key] = (double) $value; if (is_localhost()) { $result['_debug']['number_formatted'] = true; } } } } // make sure that all data rows are numeric arrays and not objects // i.e. reindex everything to be numeric arrays, so they aren't output as JSON objects foreach ($result['data'] as $i => $row) { $new_row = array_values($row); foreach ($row as $key => $value) { $new_row[$key] = $value; } $result['data'][$i] = $new_row; } // format any extra text from the result if (isset($data['add_more_currencies'])) { $result['extra'] = array('classes' => 'add_accounts', 'href' => url_for('wizard_currencies'), 'label' => ct("Add more currencies"), 'args' => array()); } if (isset($data['add_accounts_addresses'])) { $result['extra'] = array('classes' => 'add_accounts', 'href' => url_for('wizard_accounts'), 'label' => ct("Add accounts and addresses"), 'args' => array()); } // 7. calculate if the graph data may be out of date if ($renderer->requiresUser() && $renderer->getUser()) { $user = get_user($renderer->getUser()); if ($user && $renderer->usesSummaries() && (!$user['has_added_account'] || !$user['is_first_report_sent'] || strtotime($user['last_account_change']) > strtotime($user['last_sum_job']))) { $result['outofdate'] = true; } } $end_time = microtime(true); $time_diff = ($end_time - $start_time) * 1000; $result['time'] = (double) number_format_autoprecision($time_diff, 1, '.', ''); $result['hash'] = $graph['hash']; // 7. return data return $result; }
function testNumberFormatAutoprecision() { $this->assertSame("1", number_format_autoprecision("1.000")); $this->assertSame("1.1", number_format_autoprecision("1.100")); $this->assertSame("0.01", number_format_autoprecision("0.010")); $this->assertSame("0.011", number_format_autoprecision("0.011")); $this->assertSame("0.01100010", number_format_autoprecision("0.0110001")); $this->assertSame("1", number_format_autoprecision("1.000", 2)); $this->assertSame("1.10", number_format_autoprecision("1.100", 2)); $this->assertSame("0.01", number_format_autoprecision("0.010", 2)); $this->assertSame("0.01", number_format_autoprecision("0.011", 2)); $this->assertSame("0.01", number_format_autoprecision("0.0110001", 2)); }
?> "<?php echo $instance && $instance['trigger_condition'] == $key ? " selected" : ""; ?> ><?php echo htmlspecialchars($value); ?> </option> <?php } ?> </select> <span class="notification_value"> <input type="text" name="value" value="<?php echo number_format_autoprecision($instance ? $instance['trigger_value'] : 1); ?> "> <span class="notification_percent_on"> <select id="notification_percent" name="percent"> <option value="1"<?php echo $instance ? $instance['is_percent'] ? " selected" : "" : " selected"; ?> >%</option> <option value="0" class="value_label"<?php echo $instance ? $instance['is_percent'] ? "" : " selected" : ""; ?> >USD/BTC</option> </select> </span>
$q->execute(array($data['job_type'])); $job = $q->fetch(); } } echo "<td class=\"number\">" . number_format($summary['s']) . "</td>\n"; if ($data['disabled']) { echo "<td class=\"disabled\">disabled</a>\n"; } else { if ($summary['s'] == 0) { echo "<td class=\"disabled\">no data</a>\n"; } else { if ($summary['s'] == $summary['manually_disabled']) { echo "<td class=\"disabled\">all manually disabled</a>\n"; } else { $pct = 1 - ($summary['disabled'] - $summary['manually_disabled']) / ($summary['s'] - $summary['manually_disabled']); echo "<td class=\"status_percent " . get_error_class($pct) . "\">" . number_format_autoprecision($pct * 100, 2) . " %</td>\n"; } } } echo "<td class=\"number\">" . number_format($summary['manually_disabled']) . "</td>\n"; echo "<td>" . recent_format_html($summary['lq']) . "</td>\n"; ?> <td class="number"> <?php if ($job) { ?> <a href="<?php echo htmlspecialchars(url_for('admin_run_job', array('job_id' => $job['id'], 'force' => true))); ?> "><?php echo number_format($job['id']);
<?php if ($account_type['hashrate']) { echo "<td class=\"balances hashrate\">"; $found_hashrate = false; foreach (array($a['exchange'], $a['exchange'] . "_sha", $a['exchange'] . "_scrypt") as $exchange_key) { $q = db()->prepare("SELECT * FROM hashrates WHERE exchange=? AND account_id=? AND user_id=? AND is_recent=1 LIMIT 1"); $q->execute(array($exchange_key, $a['id'], $a['user_id'])); if ($mhash = $q->fetch()) { $found_hashrate = true; if (substr($mhash['exchange'], -strlen("_sha")) == "_sha") { echo number_format_autoprecision($mhash['mhash'], 1) . " MH/s"; } else { if (substr($mhash['exchange'], -strlen("_sha")) == "_sha") { echo number_format_autoprecision($mhash['mhash'] * 1000, 1) . " KH/s"; } else { echo $mhash['mhash'] ? !(isset($a['khash']) && $a['khash']) ? number_format_autoprecision($mhash['mhash'], 1) . " MH/s" : number_format_autoprecision($mhash['mhash'] * 1000, 1) . " KH/s" : "-"; } } echo "<br>"; } } if (!$found_hashrate) { echo "-"; } echo "</td>"; } ?> <?php if ($account_type['has_transactions']) { $q = db()->prepare("SELECT * FROM transaction_creators WHERE exchange=? AND account_id=?"); $q->execute(array($a['exchange'], $a['id']));
crypto_log("Sent e-mail to " . htmlspecialchars($user['email']) . "."); } } } else { // have we reminded recently? if (!$address['last_reminder'] || strtotime($address['last_reminder'] . " +" . get_site_config('outstanding_reminder_hours') . " hour") < time()) { // send a reminder if ($user['email']) { send_user_email($user, "purchase_reminder", array("name" => $user['name'] ? $user['name'] : $user['email'], "amount" => number_format_autoprecision($address['balance']), "received" => number_format_autoprecision($balance['balance']), "currency" => get_currency_abbr($address['currency']), "currency_name" => get_currency_name($address['currency']), "address" => $address['address'], "explorer" => get_explorer_address($address['currency'], $address['address']), "url" => absolute_url(url_for("user#user_outstanding")), "reminder" => $reminder, "cancelled" => $cancelled)); crypto_log("Sent e-mail to " . htmlspecialchars($user['email']) . "."); } $q = db()->prepare("UPDATE outstanding_premiums SET last_reminder=NOW() WHERE id=?"); $q->execute(array($address['id'])); crypto_log("Sent reminder message on outstanding premium payment."); } } } else { if ($balance['balance'] > 0 && $balance['balance'] > $address['last_balance']) { // issue #231: have we made a new payment since we looked last? // send a reminder if ($user['email']) { send_user_email($user, "purchase_further", array("name" => $user['name'] ? $user['name'] : $user['email'], "amount" => number_format_autoprecision($address['balance']), "received" => number_format_autoprecision($balance['balance']), "difference" => number_format_autoprecision($balance['balance'] - $address['last_balance']), "currency" => get_currency_abbr($address['currency']), "currency_name" => get_currency_name($address['currency']), "address" => $address['address'], "explorer" => get_explorer_address($address['currency'], $address['address']), "url" => absolute_url(url_for("user#user_outstanding")), "reminder" => $reminder, "cancelled" => $cancelled)); crypto_log("Sent e-mail to " . htmlspecialchars($user['email']) . "."); } $q = db()->prepare("UPDATE outstanding_premiums SET last_balance=? WHERE id=?"); $q->execute(array($balance['balance'], $address['id'])); crypto_log("Sent received payment message on outstanding premium payment."); } } } }