Пример #1
0
/**
 * Extends {@link #curl_init()} to also set {@code CURLOPT_TIMEOUT}
 * and {@code CURLOPT_CONNECTTIMEOUT} appropriately.
 */
function crypto_curl_init()
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_TIMEOUT, get_site_config('get_contents_timeout'));
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, get_site_config('get_contents_timeout'));
    return $ch;
}
Пример #2
0
 function getPackageJsonVersion()
 {
     $version = get_site_config('openclerk_version');
     if (!preg_match("#^[0-9]+\\.[0-9]+\\.[0-9]+\$#", $version)) {
         $version = $version . ".0";
     }
     return $version;
 }
Пример #3
0
 function isJobsDisabled(Logger $logger)
 {
     if (!get_site_config('jobs_enabled')) {
         $logger->info("Running jobs is disabled");
         return true;
     }
     return false;
 }
Пример #4
0
 /**
  * Find a job that belongs to the system user.
  */
 function findJob(Connection $db, Logger $logger)
 {
     if ($this->isJobsDisabled($logger)) {
         return false;
     }
     $q = $db->prepare("SELECT * FROM jobs WHERE user_id = ? AND " . $this->defaultFindJobQuery() . " LIMIT 1");
     $q->execute(array(get_site_config('system_user_id')));
     return $q->fetch();
 }
Пример #5
0
/**
 * Return a HTML link for inspecting a given cryptocurrency address.
 */
function crypto_address($currency, $address)
{
    foreach (\DiscoveredComponents\Currencies::getAddressCurrencies() as $cur) {
        if ($cur === $currency) {
            $instance = \DiscoveredComponents\Currencies::getInstance($cur);
            return "<span class=\"address " . $currency . "_address\"><code>" . htmlspecialchars($address) . "</code>\n        <a class=\"inspect\" href=\"" . htmlspecialchars($instance->getBalanceURL($address)) . "\" title=\"Inspect with " . htmlspecialchars($instance->getExplorerName()) . "\">?</a>\n      </span>";
        }
    }
    foreach (get_blockchain_currencies() as $explorer => $currencies) {
        foreach ($currencies as $cur) {
            if ($cur == $currency) {
                return "<span class=\"address " . $currency . "_address\"><code>" . htmlspecialchars($address) . "</code>\n          <a class=\"inspect\" href=\"" . htmlspecialchars(sprintf(get_site_config($currency . "_address_url"), $address)) . "\" title=\"Inspect with " . htmlspecialchars($explorer) . "\">?</a>\n        </span>";
            }
        }
    }
    return htmlspecialchars($address);
}
Пример #6
0
/**
 * We're about to perform a computationally intense task that is visible
 * or accessible to the public - this method will check the current user
 * IP and make sure this IP isn't requesting too many things at once.
 *
 * If login does not work, make sure that you have set database_timezone
 * correctly.
 */
function check_heavy_request()
{
    if (get_site_config("heavy_requests_seconds") >= 0) {
        $q = db()->prepare("SELECT * FROM heavy_requests WHERE user_ip=?");
        $q->execute(array(user_ip()));
        if ($heavy = $q->fetch()) {
            // too many requests?
            // assumes the database and server times are in sync
            if (strtotime($heavy['last_request']) > strtotime("-" . get_site_config("heavy_requests_seconds") . " seconds")) {
                throw new BlockedException(t("You are making too many requests at once: please wait at least :seconds.", array(':seconds' => plural("second", get_site_config("heavy_requests_seconds")))));
            } else {
                // update database
                $q = db()->prepare("UPDATE heavy_requests SET last_request=NOW() WHERE user_ip=?");
                $q->execute(array(user_ip()));
            }
        } else {
            // insert into database
            $q = db()->prepare("INSERT INTO heavy_requests SET last_request=NOW(), user_ip=?");
            $q->execute(array(user_ip()));
        }
    }
}
Пример #7
0
 /**
  * Get a list of all jobs that need to be queued, as an array of associative
  * arrays with (job_type, arg_id, [user_id]).
  *
  * This could use e.g. {@link JobTypeFinder}
  */
 function findJobs(Connection $db, Logger $logger)
 {
     $logger->info("Creating temporary table");
     $q = $db->prepare("CREATE TABLE temp (\n        created_at_day INT NOT NULL,\n        INDEX(created_at_day)\n      )");
     $q->execute();
     $logger->info("Inserting into temporary table");
     $q = $db->prepare("INSERT INTO temp (SELECT created_at_day FROM ticker WHERE exchange = 'average' GROUP BY created_at_day)");
     $q->execute();
     $logger->info("Querying");
     $q = $db->prepare("SELECT created_at_day, min(created_at) as date, count(*) as c\n        FROM ticker\n        WHERE exchange <> 'average' AND exchange <> 'themoneyconverter' and is_daily_data=1 and created_at_day not in (SELECT created_at_day FROM temp)\n        GROUP BY created_at_day");
     $q->execute();
     $missing = $q->fetchAll();
     $logger->info("Dropping temporary table");
     $q = $db->prepare("DROP TABLE temp");
     $q->execute();
     $logger->info("Found " . number_format(count($missing)) . " days of missing average data");
     $result = array();
     foreach ($missing as $row) {
         $logger->info("Average data for " . $row['date'] . " can be reconstructed from " . number_format($row['c']) . " ticker instances");
         $result[] = array('job_type' => 'missing_average', 'arg_id' => $row['created_at_day'], 'user_id' => get_site_config('system_user_id'));
     }
     return $result;
 }
Пример #8
0
    }
    function getTitle()
    {
        return $this->title;
    }
    function load()
    {
        require __DIR__ . "/../locale/" . $this->key . ".php";
        return $result;
    }
}
$locales = array('de' => 'German', 'fr' => 'French', 'jp' => 'Japanese', 'ru' => 'Russian', 'zh' => 'Chinese');
foreach ($locales as $locale => $title) {
    I18n::addAvailableLocale(new GenericLocale($locale, $title));
}
I18n::addDefaultKeys(array(':site_name' => get_site_config('site_name')));
// set locale as necessary
if (isset($_COOKIE["locale"]) && in_array($_COOKIE["locale"], array_keys(I18n::getAvailableLocales()))) {
    I18n::setLocale($_COOKIE["locale"]);
}
\Openclerk\Events::on('i18n_missing_string', function ($data) {
    $locale = $data['locale'];
    $key = $data['key'];
    log_uncaught_exception(new LocaleException("Locale '{$locale}': Missing key '{$key}'"));
});
/**
 * Helper function to mark strings that need to be translated on the client-side.
 */
function ct($s)
{
    // do not do any translation here - we have to do it on the client side!
Пример #9
0
?>
</h1>

<?php 
if (user_logged_in() && ($user = get_user(user_id()))) {
    if ($user['is_premium']) {
        ?>
	<div class="success success_float">
		<?php 
        echo t("Thank you for supporting :site_name with :premium!", array(':premium' => link_to(url_for('user#user_premium'), ht("your premium account"))));
        ?>
		<br>
		<?php 
        echo t("Your premium account expires in :time.", array(":time" => recent_format_html($user['premium_expires'], " ago", "")));
        ?>
	</div>
<?php 
    }
}
?>

<p>
	<?php 
$result = array();
foreach (get_site_config('premium_currencies') as $currency) {
    $result[] = get_currency_name($currency);
}
echo t("You can support :site_name by purchasing a\n\tpremium account with :currencies currencies. You will also get access to exclusive, premium-only functionality such as\n\tvastly increased limits on the number of addresses and accounts you may track at once,\n\tand advanced reporting and notification functionality. Your jobs and reports will also have higher priority over free users.", array(":currencies" => implode_english($result)));
?>
</p>
Пример #10
0
function has_expected_user_graph_hash($hash, $user)
{
    $q = db()->prepare("SELECT * FROM user_valid_keys WHERE user_id=?");
    $q->execute(array($user['id']));
    while ($key = $q->fetch()) {
        if ($hash === md5(get_site_config('user_graph_hash_salt') . ":" . $user['id'] . ":" . $key['user_key'])) {
            return true;
        }
    }
    return false;
}
Пример #11
0
 * This always executes (no job framework) so it should be used sparingly or as necessary.
 *
 * Arguments (in command line, use "-" for no argument):
 *   $key/1 required the automated key
 */
define('USE_MASTER_DB', true);
// always use the master database for selects!
require __DIR__ . "/../inc/global.php";
require __DIR__ . "/_batch.php";
require_batch_key();
batch_header("Batch cleanup balances", "batch_cleanup_balances");
crypto_log("Current time: " . date('r'));
// find all ticker data that needs to be inserted into the graph_data table
// TODO currently all database dates and PHP logic is based on server side timezone, not GMT/UTC
// database values need to all be modified to GMT before we can add '+00:00' for example
$cutoff_date = date('Y-m-d', strtotime(get_site_config('archive_balances_data'))) . ' 23:59:59';
// +00:00';
$summary_date_prefix = " 00:00:00";
// +00:00
crypto_log("Cleaning up balances data earlier than " . htmlspecialchars($cutoff_date) . " into summaries...");
$q = db_master()->prepare("SELECT * FROM balances WHERE created_at <= :date ORDER BY created_at ASC");
$q->execute(array("date" => $cutoff_date));
// we're going to store this all in memory, because at least that way we don't have to
// execute logic twice
$stored = array();
$count = 0;
while ($balance = $q->fetch()) {
    $count++;
    if ($count % 100 == 0) {
        crypto_log("Processed " . number_format($count) . "...");
    }
<div class="instructions_safe">
<h2>Is it safe to provide <?php 
echo htmlspecialchars(get_site_config('site_name'));
?>
 a <?php 
echo $account_data['exchange_name'];
?>
 API key?</h2>

<ul>
	<li>At the time of writing, a <?php 
echo $account_data['exchange_name'];
?>
 API key can only be used to retrieve account balances and worker status;
		it should not be possible to perform transactions or change user details using the API key.</li>

	<li>Your <?php 
echo $account_data['exchange_name'];
?>
 API keys will <i>never</i> be displayed on the <?php 
echo htmlspecialchars(get_site_config('site_name'));
?>
		site, even if you have logged in.</li>

	<li>At the time of writing, it is not possible to change or reset your <?php 
echo $account_data['exchange_name'];
?>
 API key.</li>
</ul>
</div>
Пример #13
0
foreach ($coins as $coin) {
    ?>
  <tr class="<?php 
    echo in_array($coin['id'], $my_coins) ? "voted-coin" : "";
    ?>
">
    <td class=""><?php 
    echo htmlspecialchars($coin['code']);
    ?>
</td>
    <td class=""><?php 
    echo htmlspecialchars($coin['title']);
    ?>
</td>
    <td class="number"><?php 
    echo number_format($coin['total_votes'] * get_site_config('vote_coins_multiplier'));
    ?>
</td>
    <td class="number"><?php 
    echo number_format($coin['total_users']);
    ?>
</td>
    <?php 
    if (user_logged_in()) {
        ?>
    <td class="buttons">
      <input type="checkbox" name="coins[]" value="<?php 
        echo htmlspecialchars($coin['id']);
        ?>
"<?php 
        echo in_array($coin['id'], $my_coins) ? " checked " : "";
Пример #14
0
/**
 * @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);
}
Пример #15
0
<?php

$email = require_get("email", false);
$hash = require_get("hash", false);
// check hash
if ($hash !== md5(get_site_config('unsubscribe_salt') . $email)) {
    throw new Exception(t("Invalid hash - please recheck the link in your e-mail."));
}
// if any accounts have a password enabled, they simply cannot unsubscribe until they have at least one
// openid identity
$q = db()->prepare("SELECT * FROM users WHERE email=?");
$q->execute(array($email));
$users = $q->fetchAll();
$has_identity = false;
foreach ($users as $user) {
    $q = db()->prepare("SELECT * FROM user_passwords WHERE user_id=?");
    $q->execute(array($user['id']));
    $password_hash = $q->fetch();
    if ($password_hash) {
        $q = db()->prepare("SELECT * FROM user_openid_identities WHERE user_id=? LIMIT 1");
        $q->execute(array($user['id']));
        $has_identity = $q->fetch();
        $q = db()->prepare("SELECT * FROM user_oauth2_identities WHERE user_id=? LIMIT 1");
        $q->execute(array($user['id']));
        $has_oauth2 = $q->fetch();
        if (!$has_identity || !$has_oauth2) {
            require __DIR__ . "/../layout/templates.php";
            page_header(t("Unsubscribe unsuccessful"), "page_unsubscribe");
            ?>
      <h1><?php 
            echo ht("Unsubscribe unsuccessful");
Пример #16
0
  <div class="link">
    <a href="https://groups.google.com/group/<?php 
echo htmlspecialchars(get_site_config('google_groups_announce'));
?>
" target="_blank"><img width="132" alt="Google Groups"
    src="https://groups.google.com/groups/img/3nb/groups_bar.gif" height="26"></a>
    <a href="https://groups.google.com/group/<?php 
echo htmlspecialchars(get_site_config('google_groups_announce'));
?>
" target="_blank" class="visit"><?php 
echo ht("Visit this group");
?>
</a>
  </div>
  <form action="https://groups.google.com/group/<?php 
echo htmlspecialchars(get_site_config('google_groups_announce'));
?>
/boxsubscribe" target="_blank">
  <label class="email"><?php 
echo ht("E-mail:");
?>
  <input name="email" type="text" size="32" value="<?php 
echo htmlspecialchars($user['email']);
?>
" /></label>
  <input value="<?php 
echo ht("Subscribe");
?>
" name="sub" type="submit" />
  </form>
</div>
Пример #17
0
     // make sure that we don't add technicals that are premium only
     $graph_technical_types = graph_technical_types();
     if (!isset($graph_technical_types[$technical])) {
         $errors[] = "Could not add technical type '" . htmlspecialchars($technical) . "' - no such technical type.";
     } else {
         if ($graph_technical_types[$technical]['premium'] && !$user['is_premium']) {
             $errors[] = "Could not add technical type '" . htmlspecialchars($graph_technical_types[$technical]['title']) . "' - requires a <a href=\"" . htmlspecialchars(url_for('premium')) . "\">premium account</a>.";
         } else {
             // it's OK
             // delete any existing technicals (even if we're inserting, since this logic is used for edit too)
             // (we limit a graph to only have a single technical at the moment)
             $q = db()->prepare("DELETE FROM graph_technicals WHERE graph_id=?");
             $q->execute(array($graph_id));
             // insert a new technical
             $q = db()->prepare("INSERT INTO graph_technicals SET graph_id=:graph_id, technical_type=:type, technical_period=:period");
             $q->execute(array('graph_id' => $graph_id, 'type' => $technical, 'period' => min(get_site_config('technical_period_max'), max(1, (int) require_post("period", 0)))));
             $technical_added = htmlspecialchars($graph_technical_types[$technical]['title']);
         }
     }
 } else {
     // otherwise, delete old technicals
     $q = db()->prepare("DELETE FROM graph_technicals WHERE graph_id=?");
     $q->execute(array($graph_id));
 }
 // redirect
 $args = array(':heading' => $graph_types[$graph_type]['heading'], ':technical' => $technical_added);
 if ($is_edit) {
     if ($technical_added) {
         $messages[] = t("Edited :heading graph, with :technical.", $args);
     } else {
         $messages[] = t("Edited :heading graph.", $args);
Пример #18
0
/**
 * Get all of the defined graph types. Used for display and validation.
 */
function graph_types()
{
    $total_fiat_currencies = array();
    foreach (get_total_conversion_summary_types() as $c) {
        $total_fiat_currencies[] = $c['title'];
    }
    $total_fiat_currencies = implode_english($total_fiat_currencies);
    $data = array('category_general' => array('title' => t('General'), 'category' => true), 'subcategory_general' => array('title' => t('General graphs'), 'subcategory' => true), 'btc_equivalent' => array('title' => t('Equivalent BTC balances (pie)'), 'heading' => t('Equivalent BTC'), 'description' => t('A pie chart representing the overall proportional value of all currencies if they were all converted into BTC.') . '<p>' . t('Exchanges used:') . ' ' . get_default_exchange_text(array_diff(get_all_currencies(), array('btc'))) . '.', 'default_width' => get_site_config('default_user_graph_height'), 'uses_summaries' => true), 'btc_equivalent_graph' => array('title' => t('Equivalent BTC balances (graph)'), 'heading' => t('Equivalent BTC'), 'description' => t('A line graph displaying the historical value of all currencies if they were all converted into BTC.') . '<p>' . t('Exchanges used:') . ' ' . get_default_exchange_text(array_diff(get_all_currencies(), array('btc'))) . '.', 'days' => true, 'uses_summaries' => true), 'btc_equivalent_stacked' => array('title' => t('Equivalent BTC balances (stacked)'), 'heading' => t('Equivalent BTC'), 'description' => t('A stacked area graph displaying the historical value of all currencies if they were all converted into BTC.') . '<p>' . t('Exchanges used:') . ' ' . get_default_exchange_text(array_diff(get_all_currencies(), array('btc'))) . '.', 'days' => true, 'uses_summaries' => true), 'btc_equivalent_proportional' => array('title' => t('Equivalent BTC balances (proportional)'), 'heading' => t('Equivalent BTC'), 'description' => t('A stacked area graph displaying the proportional historical value of all currencies if they were all converted into BTC.') . '<p>' . t('Exchanges used:') . ' ' . get_default_exchange_text(array_diff(get_all_currencies(), array('btc'))) . '.', 'days' => true, 'uses_summaries' => true), 'ticker_matrix' => array('title' => t('All currencies exchange rates (matrix)'), 'heading' => t('All exchanges'), 'description' => t('A matrix displaying the current bid/ask of all of the currencies and exchanges :interested_in.', array(':interested_in' => link_to(url_for('wizard_currencies'), t('you are interested in'))))), 'balances_table' => array('title' => t('Total balances (table)'), 'heading' => t('Total balances'), 'description' => t('A table displaying the current sum of all your currencies (before any conversions).'), 'default_width' => get_site_config('default_user_graph_height'), 'uses_summaries' => true), 'total_converted_table' => array('title' => t('Total converted fiat balances (table)'), 'heading' => t('Converted fiat'), 'description' => t('A table displaying the equivalent value of all cryptocurrencies and fiat currencies if they were immediately converted into fiat currencies. Cryptocurrencies are converted via BTC.') . '<p>' . t('Supports :currencies.', array(':currencies' => $total_fiat_currencies)) . '<p>' . t('Exchanges used:') . ' ' . get_default_exchange_text(array_diff(get_all_currencies(), array('btc'))) . '.', 'default_width' => get_site_config('default_user_graph_height'), 'uses_summaries' => true), 'crypto_converted_table' => array('title' => t('Total converted crypto balances (table)'), 'heading' => t('Converted crypto'), 'description' => t('A table displaying the equivalent value of all cryptocurrencies - but not fiat currencies - if they were immediately converted into other cryptocurrencies.') . '<p>' . t('Exchanges used:') . ' ' . get_default_exchange_text(array_diff(get_all_cryptocurrencies(), array('btc'))) . '.', 'default_width' => get_site_config('default_user_graph_height'), 'uses_summaries' => true), 'balances_offset_table' => array('title' => t('Total balances with offsets (table)'), 'heading' => t('Total balances'), 'description' => t('A table displaying the current sum of all currencies (before any conversions), along with the current total offset values of each currency.'), 'uses_summaries' => true));
    $summaries = array();
    $conversions = array();
    if (user_logged_in()) {
        $summaries = get_all_summary_currencies();
        $conversions = get_all_conversion_currencies();
    }
    $data['category_summaries'] = array('title' => t('Your summaries'), 'category' => true);
    $data['subcategory_summaries_total'] = array('title' => t('Historical currency value'), 'subcategory' => true);
    // we can generate a list of summary daily graphs from all the currencies that we support
    foreach (get_summary_types() as $key => $summary) {
        $cur = $summary['currency'];
        $data["total_" . $cur . "_daily"] = array('title' => t("Total :currency historical (graph)", array(':currency' => get_currency_name($cur))), 'heading' => t("Total :currency", array(':currency' => get_currency_abbr($cur))), 'description' => t("A line graph displaying the historical sum of your :currency (before any conversions).", array(':currency' => get_currency_name($cur))), 'hide' => !isset($summaries[$cur]), 'days' => true, 'delta' => true, 'technical' => true, 'uses_summaries' => true);
    }
    $data['subcategory_summaries_crypto2'] = array('title' => t('Historical converted value'), 'subcategory' => true);
    foreach (get_crypto_conversion_summary_types() as $key => $summary) {
        $cur = $summary['currency'];
        $data["crypto2" . $key . "_daily"] = array('title' => t("Converted :title historical (graph)", array(':title' => $summary['title'])), 'heading' => t("Converted :title", array(':title' => $summary['short_title'])), 'description' => t("A line graph displaying the historical equivalent value of all cryptocurrencies - and not other fiat currencies - if they were immediately converted to :title.", array(':title' => $summary['title'])), 'hide' => !isset($conversions['summary_' . $key]), 'days' => true, 'delta' => true, 'technical' => true, 'uses_summaries' => true);
    }
    /*
     * Issue #112 reported that 'all2CUR' was not correctly converting fiat currencies other than CUR.
     * Rather than renaming 'all2CUR' as 'all cryptocurrencies and CUR', which doesn't seem to be particularly useful
     * - and it will mean we'll have to track two new summaries for every currency -
     * as of 0.19 this will now correctly be calculated as 'all cryptocurrencies and fiat currencies'. This means that there
     * will be a jump in the value of data when deployed.
     */
    foreach (get_total_conversion_summary_types() as $key => $summary) {
        $cur = $summary['currency'];
        $data["all2" . $key . "_daily"] = array('title' => t("Converted :title historical (graph)", array(':title' => $summary['title'])), 'heading' => t("Converted :title", array(':title' => $summary['short_title'])), 'description' => t("A line graph displaying the historical equivalent value of all cryptocurrencies and fiat currencies if they were immediately converted to :title (where possible).", array(':title' => $summary['title'])), 'hide' => !isset($conversions['summary_' . $key]), 'days' => true, 'delta' => true, 'technical' => true, 'uses_summaries' => true);
    }
    $data['subcategory_summaries_composition'] = array('title' => t('Total balance composition'), 'subcategory' => true);
    // we can generate a list of composition graphs from all of the currencies that we support
    foreach (get_all_currencies() as $currency) {
        $data["composition_" . $currency . "_pie"] = array('title' => t("Total :currency balance composition (pie)", array(':currency' => get_currency_name($currency))), 'heading' => t("Total :currency", array(':currency' => get_currency_abbr($currency))), 'description' => t("A pie chart representing all of the sources of your total :currency balance (before any conversions).", array(':currency' => get_currency_name($currency))), 'hide' => !isset($summaries[$currency]), 'default_width' => get_site_config('default_user_graph_height'), 'uses_summaries' => true);
    }
    $data['subcategory_summaries_graph'] = array('title' => t('All balances (graph)'), 'subcategory' => true);
    foreach (get_all_currencies() as $currency) {
        $data["composition_" . $currency . "_daily"] = array('title' => t("All :currency balances (graph)", array(':currency' => get_currency_name($currency))), 'heading' => t("All :currency balances", array(':currency' => get_currency_abbr($currency))), 'description' => t("A line graph representing all of the sources of your total :currency balance (before any conversions).", array(':currency' => get_currency_name($currency))), 'days' => true, 'hide' => !isset($summaries[$currency]), 'uses_summaries' => true);
    }
    $data['subcategory_summaries_table'] = array('title' => t('All balances (table)'), 'subcategory' => true);
    foreach (get_all_currencies() as $currency) {
        $data["composition_" . $currency . "_table"] = array('title' => t("Your :currency balances (table)", array(':currency' => get_currency_name($currency))), 'heading' => t("Your :currency balances", array(':currency' => get_currency_abbr($currency))), 'description' => t("A table displaying all of your :currency balances and the total balance (before any conversions).", array(':currency' => get_currency_name($currency))), 'hide' => !isset($summaries[$currency]), 'uses_summaries' => true);
    }
    $data['subcategory_summaries_stacked'] = array('title' => t('All balances (stacked)'), 'subcategory' => true);
    foreach (get_all_currencies() as $currency) {
        $data["composition_" . $currency . "_stacked"] = array('title' => t("All :currency balances (stacked)", array(':currency' => get_currency_name($currency))), 'heading' => t("All :currency balances", array(':currency' => get_currency_abbr($currency))), 'description' => t("A stacked area graph displaying the historical value of your total :currency balance (before any conversions).", array(':currency' => get_currency_name($currency))), 'days' => true, 'hide' => !isset($summaries[$currency]), 'uses_summaries' => true);
    }
    $data['subcategory_summaries_proportional'] = array('title' => t('All balances (proportional)'), 'subcategory' => true);
    foreach (get_all_currencies() as $currency) {
        $data["composition_" . $currency . "_proportional"] = array('title' => t("All :currency balances (proportional)", array(':currency' => get_currency_name($currency))), 'heading' => t("All :currency balances", array(':currency' => get_currency_abbr($currency))), 'description' => t("A stacked area graph displaying the proportional historical value of your total :currency balance (before any conversions).", array(':currency' => get_currency_name($currency))), 'days' => true, 'hide' => !isset($summaries[$currency]), 'uses_summaries' => true);
    }
    $data['category_hashrate'] = array('title' => t('Your mining'), 'category' => true);
    $data['category_hashrate_hashrate'] = array('title' => t('Historical hashrates'), 'subcategory' => true);
    // and for each cryptocurrency that can be hashed
    foreach (get_all_hashrate_currencies() as $cur) {
        $data["hashrate_" . $cur . "_daily"] = array('title' => t(":currency historical MHash/s (graph)", array(':currency' => get_currency_name($cur))), 'heading' => t(":currency MHash/s", array(':currency' => get_currency_abbr($cur))), 'description' => t("A line graph displaying the historical hashrate sum of all workers mining :currency across all mining pools (in MHash/s).", array(':currency' => get_currency_name($cur))), 'hide' => !isset($summaries[$cur]), 'days' => true, 'delta' => true, 'technical' => true, 'uses_summaries' => true);
    }
    // merge in graph_types_public() here
    foreach (graph_types_public($summaries) as $key => $public_data) {
        // but add 'hide' parameter to hide irrelevant currencies
        if (isset($public_data['pairs'])) {
            $pairs = $public_data['pairs'];
            $public_data['hide'] = !(isset($summaries[$pairs[0]]) && isset($summaries[$pairs[1]]));
        }
        $data[$key] = $public_data;
    }
    $data['subcategory_layout'] = array('title' => t('Layout tools'), 'subcategory' => true);
    $data['linebreak'] = array('title' => t('Line break'), 'description' => t('Forces a line break at a particular location. Select \'Enable layout editing\' to move it.'), 'heading' => t('Line break'));
    $data['heading'] = array('title' => t('Heading'), 'description' => t("Displays a line of text as a heading at a particular location. Also functions as a line break. Select 'Enable layout editing' to move it.'"), 'string0' => t("Example heading"), 'heading' => t('Heading'));
    // add sample images
    $images = array('btc_equivalent' => 'btc_equivalent.png', 'composition_btc_pie' => 'composition_btc_pie.png', 'composition_ltc_pie' => 'composition_ltc_pie.png', 'composition_nmc_pie' => 'composition_nmc_pie.png', 'btce_btcnmc_daily' => 'btce_btcnmc_daily.png', 'btce_btcftc_daily' => 'btce_btcftc_daily.png', 'btce_btcltc_daily' => 'btce_btcltc_daily.png', 'bitstamp_usdbtc_daily' => 'bitstamp_usdbtc_daily.png', 'bitnz_nzdbtc_daily' => 'bitnz_nzdbtc_daily.png', 'btcchina_cnybtc_daily' => 'btcchina_cnybtc_daily.png', 'cexio_btcghs_daily' => 'cexio_btcghs_daily.png', 'vircurex_btcltc_daily' => 'vircurex_btcltc_daily.png', 'vircurex_btcdog_daily' => 'vircurex_btcdog_daily.png', 'themoneyconverter_usdeur_daily' => 'themoneyconverter_usdeur_daily.png', 'themoneyconverter_usdaud_daily' => 'themoneyconverter_usdaud_daily.png', 'themoneyconverter_usdcad_daily' => 'themoneyconverter_usdcad_daily.png', 'themoneyconverter_usdnzd_daily' => 'themoneyconverter_usdnzd_daily.png', 'crypto2btc_daily' => 'crypto2btc_daily.png', 'crypto2ltc_daily' => 'crypto2ltc_daily.png', 'crypto2nmc_daily' => 'crypto2nmc_daily.png', 'crypto2dog_daily' => 'crypto2dog_daily.png', 'all2nzd_bitnz_daily' => 'all2nzd_bitnz_daily.png', 'all2cad_virtex_daily' => 'all2cad_virtex_daily.png', 'all2usd_bitstamp_daily' => 'all2usd_bitstamp_daily.png', 'all2usd_btce_daily' => 'all2usd_btce_daily.png', 'btc_equivalent_graph' => 'btc_equivalent_graph.png', 'btc_equivalent_proportional' => 'btc_equivalent_proportional.png', 'btc_equivalent_stacked' => 'btc_equivalent_stacked.png', 'total_btc_daily' => 'total_btc_daily.png', 'total_ltc_daily' => 'total_ltc_daily.png', 'total_nmc_daily' => 'total_nmc_daily.png', 'total_ghs_daily' => 'total_ghs_daily.png', 'hashrate_ltc_daily' => 'hashrate_ltc_daily.png', 'balances_table' => 'balances_table.png', 'balances_offset_table' => 'balances_offset_table.png', 'crypto_converted_table' => 'crypto_converted_table.png', 'total_converted_table' => 'total_converted_table.png', 'composition_btc_daily' => 'composition_btc_daily.png', 'composition_ltc_daily' => 'composition_ltc_daily.png', 'composition_nmc_daily' => 'composition_ltc_daily.png', 'composition_ftc_daily' => 'composition_ltc_daily.png', 'composition_ppc_daily' => 'composition_ltc_daily.png', 'composition_nvc_daily' => 'composition_ltc_daily.png', 'composition_dog_daily' => 'composition_dog_daily.png', 'composition_btc_table' => 'composition_btc_table.png', 'composition_ltc_table' => 'composition_ltc_table.png', 'composition_nmc_table' => 'composition_nmc_table.png', 'composition_ftc_table' => 'composition_ltc_table.png', 'composition_ppc_table' => 'composition_ltc_table.png', 'composition_nvc_table' => 'composition_ltc_table.png', 'composition_dog_table' => 'composition_dog_table.png', 'composition_btc_proportional' => 'composition_btc_proportional.png', 'composition_ltc_proportional' => 'composition_ltc_proportional.png', 'composition_nmc_proportional' => 'composition_nmc_proportional.png', 'composition_ftc_proportional' => 'composition_ltc_proportional.png', 'composition_ppc_proportional' => 'composition_ltc_proportional.png', 'composition_nvc_proportional' => 'composition_ltc_proportional.png', 'composition_btc_stacked' => 'composition_btc_stacked.png', 'composition_ltc_stacked' => 'composition_ltc_stacked.png', 'composition_nmc_stacked' => 'composition_ltc_stacked.png', 'composition_ftc_stacked' => 'composition_ltc_stacked.png', 'composition_ppc_stacked' => 'composition_ltc_stacked.png', 'composition_nvc_stacked' => 'composition_ltc_stacked.png', 'composition_ghs_stacked' => 'composition_ghs_stacked.png', 'average_usdbtc_daily' => 'average_usdbtc_daily.png', 'average_usdbtc_markets' => 'average_usdbtc_markets.png', 'average_cadbtc_daily' => 'average_cadbtc_daily.png', 'average_cadbtc_markets' => 'average_cadbtc_markets.png', 'average_audbtc_daily' => 'average_audbtc_daily.png', 'average_audbtc_markets' => 'average_audbtc_markets.png', 'average_nzdbtc_daily' => 'average_nzdbtc_daily.png', 'average_nzdbtc_markets' => 'average_nzdbtc_markets.png', 'average_btcdog_daily' => 'average_btcdog_daily.png', 'average_btcdog_markets' => 'average_btcdog_markets.png', 'average_btcltc_daily' => 'average_btcltc_daily.png', 'average_btcltc_markets' => 'average_btcltc_markets.png', 'ticker_matrix' => 'ticker_matrix.png', 'calculator' => 'calculator.png');
    $data = add_example_images($data, $images);
    return $data;
}
Пример #19
0
<?php

/**
 * This admin-only scripts allows us to "login" as another user for debugging
 * purposes. First the user must be logged in as an administrator, and the
 * 'allow_fake_login' config parameter set to true.
 * The target user also must not be an administrator.
 */
require_admin();
// TODO need to migrate to new openclerk/users framework
throw new Exception("Not implemented (#266).");
if (!get_site_config('allow_fake_login')) {
    throw new Exception("Fake login must be enabled through 'allow_fake_login' first.");
}
// login as a new user
$query = db()->prepare("SELECT * FROM users WHERE id=? LIMIT 1");
$query->execute(array(require_get("id")));
if (!($user = $query->fetch())) {
    throw new Exception("No user account found: " . require_get("id"));
}
if ($user['is_admin']) {
    throw new Exception("Cannot login as an administrator");
}
// create a log message
class FakeLogin extends Exception
{
}
log_uncaught_exception(new FakeLogin("Login emulated for user " . $user['id']));
// create new login key
$user_key = sprintf("%04x%04x%04x%04x", rand(0, 0xffff), rand(0, 0xffff), rand(0, 0xffff), rand(0, 0xffff));
$query = db()->prepare("INSERT INTO valid_user_keys SET user_id=?, user_key=?, created_at=NOW()");
Пример #20
0
<?php

echo htmlspecialchars(get_site_config('site_name'));
?>
 &copy; 2013<?php 
if (date('Y') != 2013) {
    echo "-" . date('Y');
}
?>
,
<?php 
echo t("powered by :openclerk", array(':openclerk' => '<a href="http://openclerk.org" target="_blank">openclerk.org</a>'));
?>
 <?php 
echo htmlspecialchars(get_site_config('openclerk_version'));
echo " - ";
?>
<a href="<?php 
echo htmlspecialchars(url_for('terms'));
?>
"><?php 
echo ht("Terms of Service");
?>
</a>
<?php 
echo " - ";
?>
<a href="<?php 
echo htmlspecialchars(url_for('terms#privacy'));
?>
"><?php 
Пример #21
0
<?php

/**
 * An existing free user has not logged in within X days and we
 * now need to disable their account.
 */
// get the relevant user info
$user = get_user($job['arg_id']);
if (!$user) {
    throw new JobException("Cannot find user ID " . $job['arg_id']);
}
// check that they're not a premium user etc - this should never happen
if ($user['is_premium']) {
    throw new JobException("Premium user was requested to be disabled - this should not happen");
}
// update user (before sending email)
$q = db()->prepare("UPDATE user_properties SET is_disabled=1,disabled_at=NOW() WHERE id=? LIMIT 1");
$q->execute(array($user['id']));
// construct email
if ($user['email']) {
    $disables_at = strtotime(($user['last_login'] ? $user['last_login'] : $user['created_at']) . " +" . get_site_config('user_expiry_days') . " day");
    send_user_email($user, "disable", array("name" => $user['name'] ? $user['name'] : $user['email'], "days" => number_format(get_site_config('user_expiry_days')), "disables" => iso_date($disables_at), "disables_text" => recent_format($disables_at, false, ""), "url" => absolute_url(url_for("user#user_premium")), "login" => absolute_url(url_for("login")), "profile" => absolute_url(url_for("profile"))));
    crypto_log("Sent disabled account e-mail to " . htmlspecialchars($user['email']) . ".");
} else {
    crypto_log("User had no valid e-mail address.");
}
Пример #22
0
     if ($years > 0) {
         $cost += wrap_number(get_premium_price($currency, 'yearly') * $years, 8);
     }
     if ($cost == 0) {
         throw new PurchaseException(t("Could not calculate any cost"));
     }
     // find an unused $currency address and register it to the system
     $q = db()->prepare("SELECT * FROM premium_addresses WHERE is_used=0 AND currency=?");
     $q->execute(array($currency));
     $address = $q->fetch();
     if (!$address) {
         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) {
 public function getUser()
 {
     return get_site_config('system_user_id');
 }
Пример #24
0
    set_temporary_messages($messages);
    redirect(url_for(require_post("callback")));
}
// process 'test'
if (require_post('test', false) && require_post('id', false)) {
    // do we already have a job queued up?
    $q = db()->prepare("SELECT * FROM jobs WHERE is_executed=0 AND user_id=? AND is_test_job=1 LIMIT 1");
    $q->execute(array(user_id()));
    if ($job = $q->fetch()) {
        $errors[] = t("Cannot create a :title test, because you already have a :type test pending.", array(':title' => htmlspecialchars($account_data['title']), ':type' => get_exchange_name($job['job_type'])));
    } else {
        if ($account_data['disabled']) {
            $errors[] = t("Cannot test that job; that account type is disabled.");
        } else {
            $q = db()->prepare("INSERT INTO jobs SET\n      job_type=:job_type,\n      job_prefix=:job_prefix,\n      user_id=:user_id,\n      arg_id=:arg_id,\n      priority=:priority,\n      is_test_job=1");
            $q->execute(array('job_type' => $account_data['job_type'], 'job_prefix' => \Openclerk\Jobs\JobQueuer::getJobPrefix($account_data['exchange']), 'user_id' => user_id(), 'arg_id' => require_post('id'), 'priority' => get_site_config('job_test_priority')));
            $messages[] = t("Queued up a new :title test; results should be available shortly.", array(':title' => htmlspecialchars($account_data['title'])));
            set_temporary_messages($messages);
            redirect(url_for(require_post("callback")));
        }
    }
}
// process 'enable'
if (require_post('enable', false) && require_post('id', false)) {
    if (!can_user_add($user, $account_data['exchange'])) {
        $errors[] = t("Cannot enable :title: too many existing accounts.", array(':title' => $account_data['title'])) . ($user['is_premium'] ? "" : " " . t("To add more accounts, upgrade to a :premium_account.", array(':premium_account' => link_to(url_for('premium'), t('premium account')))));
    } else {
        if ($account_data['disabled']) {
            $errors[] = t("Cannot enable that account; that account type is disabled.");
        } else {
            // reset all failure fields
Пример #25
0
function page_footer_old()
{
    ?>
  </div>
</div>

<?php 
    require_template("templates_footer");
    ?>

<div id="footer_nav">
  <ul class="footer_nav_list">
    <li><span class="title"><?php 
    echo htmlspecialchars(get_site_config('site_name'));
    ?>
</span>
      <ul>
        <li><a href="<?php 
    echo htmlspecialchars(url_for('index'));
    ?>
"><?php 
    echo ht("About");
    ?>
</a></li>
        <li><a href="<?php 
    echo htmlspecialchars(url_for('premium'));
    ?>
"><?php 
    echo ht("Get Premium");
    ?>
</a></li>
        <li><a href="<?php 
    echo htmlspecialchars(get_site_config('version_history_link'));
    ?>
"><?php 
    echo ht("Release History");
    ?>
</a></li>
        <li><a href="http://openclerk.org" target="_blank">Openclerk.org</a></li>
      </ul>
    </li>
    <li><span class="title"><?php 
    echo ht("Your Account");
    ?>
</span>
      <ul>
        <?php 
    if (user_logged_in()) {
        ?>
        <li><a href="<?php 
        echo htmlspecialchars(url_for('user'));
        ?>
"><?php 
        echo ht("User Profile");
        ?>
</a></li>
        <li><a href="<?php 
        echo htmlspecialchars(url_for('wizard_currencies'));
        ?>
"><?php 
        echo ht("Currency Preferences");
        ?>
</a></li>
        <li><a href="<?php 
        echo htmlspecialchars(url_for('wizard_accounts'));
        ?>
"><?php 
        echo ht("Configure Accounts");
        ?>
</a></li>
        <li><a href="<?php 
        echo htmlspecialchars(url_for('profile'));
        ?>
"><?php 
        echo ht("Your Reports");
        ?>
</a></li>
        <?php 
    } else {
        ?>
        <li><a href="<?php 
        echo htmlspecialchars(url_for('signup'));
        ?>
"><?php 
        echo ht("Signup");
        ?>
</a></li>
        <li><a href="<?php 
        echo htmlspecialchars(url_for('login'));
        ?>
"><?php 
        echo ht("Login");
        ?>
</a></li>
        <?php 
    }
    ?>
      </ul>
    </li>
    <li><span class="title"><?php 
    echo ht("Tools");
    ?>
</span>
      <ul>
        <li><a href="<?php 
    echo htmlspecialchars(url_for('historical'));
    ?>
"><?php 
    echo ht("Historical Data");
    ?>
</a></li>
        <li><a href="<?php 
    echo htmlspecialchars(url_for('average'));
    ?>
"><?php 
    echo ht("Market Averages");
    ?>
</a></li>
        <li><a href="<?php 
    echo htmlspecialchars(url_for('calculator'));
    ?>
"><?php 
    echo ht("Calculator");
    ?>
</a></li>
        <li><a href="<?php 
    echo htmlspecialchars(url_for('api'));
    ?>
"><?php 
    echo ht("API");
    ?>
</a></li>
      </ul>
    </li>
    <li><span class="title"><?php 
    echo ht("Support");
    ?>
</span>
      <ul>
        <li><a href="<?php 
    echo htmlspecialchars(url_for('help'));
    ?>
"><?php 
    echo ht("Help Centre");
    ?>
</a></li>
        <li><a href="<?php 
    echo htmlspecialchars(get_site_config('blog_link'));
    ?>
" target="_blank"><?php 
    echo ht("Blog");
    ?>
</a> <span class="new"><?php 
    echo ht("new");
    ?>
</span></li>
        <li><a href="<?php 
    echo htmlspecialchars(url_for('contact'));
    ?>
"><?php 
    echo ht("Contact Us");
    ?>
</a></li>
        <li><a href="<?php 
    echo htmlspecialchars(url_for('external'));
    ?>
"><?php 
    echo ht("External API Status");
    ?>
</a></li>
      </ul>
    </li>
  </ul>

  <div id="copyright">
    <?php 
    require_template("templates_copyright");
    ?>
  </div>

</div>
<?php 
    if (!(has_required_admin() || defined('BATCH_SCRIPT'))) {
        ?>
<script type="text/javascript">
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', '<?php 
        echo get_site_config('google_analytics_account');
        ?>
', 'auto');
  ga('send', 'pageview');
</script>
<?php 
    }
    ?>
</body>
</html>
<?php 
    if (defined('PAGE_RENDER_START')) {
        $end_time = microtime(true);
        $time_diff = ($end_time - PAGE_RENDER_START) * 1000;
        echo "<!-- rendered in " . number_format($time_diff, 2) . " ms -->";
    }
    performance_metrics_page_end();
    echo "\n<!--\n" . print_r(Openclerk\MetricsHandler::getInstance()->printResults(), true) . "\n-->";
    if (is_admin()) {
        echo "\n<!-- " . print_r($_SESSION, true) . "\n-->";
    }
}
Пример #26
0
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;
}
Пример #27
0
<table class="fancy">
<tr>
	<th><span class="help_name_email">Email</span></th>
	<td><a href="mailto:<?php 
echo htmlspecialchars(get_site_config('site_email'));
?>
"><?php 
echo htmlspecialchars(get_site_config('site_email'));
?>
</a></td>
</tr>
<tr>
	<th><span class="help_name_blog">Blog</span></th>
	<td><a href="<?php 
echo htmlspecialchars(get_site_config('blog_link'));
?>
">Blog</a></td>
</tr>
<tr>
	<th><span class="help_name_forum">Forum</span></th>
	<td><a href="<?php 
echo htmlspecialchars(get_site_config('forum_link'));
?>
">Forum</a></td>
</tr>
</table>
Пример #28
0
/**
 * Tag the current page as one that can be cached by the client;
 * sets Expires, Cache-Control etc headers.
 *
 * <p>Doesn't do anything with 304 Not Modified.
 *
 * <p>Uses {@code default_cache_seconds} seconds as a default cache period.
 */
function allow_cache($seconds = false)
{
    if ($seconds === false) {
        $seconds = get_site_config('default_cache_seconds');
    }
    $gmdate = 'D, d M Y H:i:s';
    header('Cache-Control: private');
    // may only be cached in private cache.
    header('Pragma: private');
    header('Last-Modified: ' . gmdate($gmdate, time()) . ' GMT');
    header('Expires: ' . gmdate($gmdate, time() + $seconds) . ' GMT');
}
Пример #29
0
foreach (get_site_config('premium_currencies') as $currency) {
    ?>
<tr>
  <th class="currency"><span class="currency_name_<?php 
    echo $currency;
    ?>
"><?php 
    echo htmlspecialchars(get_currency_name($currency));
    ?>
</span></th>
  <td class="prices">
    <?php 
    if (get_site_config('premium_' . $currency . '_discount')) {
        ?>
    <div class="discounted"><?php 
        echo t(":cost1 per month, or :cost2 per year", array(':cost1' => currency_format($currency, get_site_config('premium_' . $currency . '_monthly')), ':cost2' => currency_format($currency, get_site_config('premium_' . $currency . '_yearly'))));
        ?>
</div>
    <?php 
    }
    ?>
    <?php 
    echo t(":cost1 per month, or :cost2 per year", array(':cost1' => currency_format($currency, get_premium_price($currency, 'monthly')), ':cost2' => currency_format($currency, get_premium_price($currency, 'yearly'))));
    ?>
  </td>
  <td class="buttons">
    <form action="<?php 
    echo htmlspecialchars(url_for('purchase'));
    ?>
" method="post">
      <input type="hidden" name="currency" value="<?php 
Пример #30
0
	<img src="<?php 
echo htmlspecialchars(url_for('img/help/graph_refresh.png'));
?>
" class="help_inline">

	Yes - as of Openclerk 0.15, graphs throughout the site will update themselves automatically with the most recent data.
	By default, graphs will only update themselves every <?php 
echo plural("minute", get_site_config('graph_refresh_public'));
?>
;
	graphs displayed to <a href="<?php 
echo htmlspecialchars(url_for('premium'));
?>
">premium users</a> will update
	themselves every <?php 
echo plural("minute", get_site_config('graph_refresh_premium'));
?>
.
</p>

<p>
	Note that not all graphs have data that is updated this frequently. Your account data and reports are still only updated
	according to <a href="<?php 
echo htmlspecialchars(url_for('premium'));
?>
">your data update rates</a>
	(once every <?php 
echo plural("hour", get_premium_config('refresh_queue_hours_free'));
?>
 for free users,
	or every <?php