/**
  * If we have a ?job_id parameter, then select only this job
  */
 function findJob(Connection $db, Logger $logger)
 {
     if ($this->isJobsDisabled($logger)) {
         return false;
     }
     // mark all once-failed test jobs as failing
     $q = $db->prepare("SELECT * FROM jobs WHERE is_executing=0 AND is_error=0 AND is_test_job=1 AND execution_count >= ?");
     $q->execute(array(1));
     if ($failed = $q->fetchAll()) {
         $logger->info("Found " . number_format(count($failed)) . " test jobs that have failed once");
         foreach ($failed as $job) {
             $q = $db->prepare("UPDATE jobs SET is_executed=1,is_error=1 WHERE id=?");
             $q->execute(array($job['id']));
             $logger->info("Marked test job " . $job['id'] . " as failed");
         }
     }
     // mark all jobs that have been executing for far too long as failed
     $q = $db->prepare("SELECT * FROM jobs WHERE is_executing=1 AND execution_started <= DATE_SUB(NOW(), INTERVAL 30 MINUTE)");
     $q->execute(array());
     if ($timeout = $q->fetchAll()) {
         $logger->info("Found " . number_format(count($timeout)) . " jobs that have timed out");
         foreach ($timeout as $job) {
             $q = $db->prepare("UPDATE jobs SET is_timeout=1, is_executing=0 WHERE id=?");
             $q->execute(array($job['id']));
             $logger->info("Marked job " . $job['id'] . " as timed out");
         }
     }
     if (require_get("job_id", false)) {
         $q = $db->prepare("SELECT * FROM jobs WHERE id=? LIMIT 1");
         $q->execute(array(require_get("job_id")));
         return $q->fetch();
     } else {
         return parent::findJob($db, $logger);
     }
 }
示例#2
0
 function getConfig()
 {
     // load graph data, which is also used to construct the hash
     $config = array('days' => require_get("days", false), 'delta' => require_get("delta", false), 'arg0' => require_get('arg0', false), 'arg0_resolved' => require_get('arg0_resolved', false), 'technical_type' => require_get('technical_type', false), 'technical_period' => require_get('technical_period', false), 'user_id' => require_get('user_id', false), 'user_hash' => require_get('user_hash', false));
     if (!$config['days']) {
         $config['days'] = 45;
         // default
     }
     return $config;
 }
示例#3
0
function batch_footer()
{
    if (require_get("key", false)) {
        // we're running from a web browser
        // include page gen times etc
        page_footer();
    } else {
        // we are running from the CLI
        // we still need to calculate performance metrics
        performance_metrics_page_end();
    }
}
示例#4
0
 /**
  * Execute OAuth2 authentication and return the user.
  */
 static function auth(ProviderInterface $provider)
 {
     if (!require_get("code", false)) {
         redirect($provider->getAuthorizationUrl());
         return false;
     } else {
         // optionally check for abuse etc
         if (!\Openclerk\Events::trigger('oauth2_auth', $provider)) {
             throw new UserAuthenticationException("Login was cancelled by the system.");
         }
         $token = $provider->getAccessToken('authorization_code', array('code' => require_get("code")));
         // now find the relevant user
         return $provider->getUserDetails($token);
     }
 }
示例#5
0
 function run($reporter)
 {
     $only = require_get("only", false);
     // we just load all PHP files within this directory
     if ($handle = opendir('.')) {
         echo "<ul style=\"padding: 10px; list-style: none;\">";
         echo "<li style=\"display: inline-block; margin-right: 5px;\"><a href=\"" . url_for('tests/') . "\"><b>All tests</b></a></li>\n";
         while (false !== ($entry = readdir($handle))) {
             if ($entry != "." && $entry != ".." && substr(strtolower($entry), -4) == ".php" && strtolower($entry) != 'index.php') {
                 echo "<li style=\"display: inline-block; margin-right: 5px;\"><a href=\"" . url_for('tests/', array('only' => $entry)) . "\">" . htmlspecialchars($entry) . "</a></li>\n";
             }
         }
         echo "</ul>";
         closedir($handle);
     }
     parent::run($reporter);
 }
示例#6
0
<?php

/**
 * Purchase premium accounts.
 */
require_login();
require __DIR__ . "/../layout/templates.php";
$messages = array();
$errors = array();
$user = get_user(user_id());
require_user($user);
$currency = require_post("currency", require_get("currency", false));
if (!$currency || !is_valid_currency($currency) || !in_array($currency, get_site_config('premium_currencies'))) {
    $errors[] = t("Unknown currency or no currency specified.");
    set_temporary_errors($errors);
    redirect(url_for('premium'));
}
$messages = array();
$errors = array();
class PurchaseException extends Exception
{
}
if (require_post("months", false) || require_post("years", false)) {
    try {
        $months = require_post("months", false);
        $years = require_post("years", false);
        if (!is_numeric($months) || !is_numeric($years) || !($months > 0 || $years > 0) || $months > 99 || $years > 99) {
            throw new PurchaseException(t("Invalid period selection."));
        }
        $cost = 0;
        if ($months > 0) {
示例#7
0
class OpenclerkJobRunnerType extends \Core\OpenclerkJobRunner
{
    var $job_prefix;
    function __construct($job_prefix)
    {
        parent::__construct();
        $this->job_prefix = $job_prefix;
    }
    /**
     * Find a job that starts with the given prefix
     */
    function findJob(Connection $db, Logger $logger)
    {
        if ($this->isJobsDisabled($logger)) {
            return false;
        }
        $q = $db->prepare("SELECT * FROM jobs WHERE (job_prefix=? OR job_type=?) AND " . $this->defaultFindJobQuery() . " LIMIT 1");
        $q->execute(array($this->job_prefix, $this->job_prefix));
        return $q->fetch();
    }
}
if (isset($argv)) {
    $job_prefix = $argv[2];
} else {
    $job_prefix = require_get("type");
}
$logger = new \Monolog\Logger("batch_run");
$logger->pushHandler(new \Core\MyLogger());
$logger->info("Running job type '{$job_prefix}'");
$runner = new OpenclerkJobRunnerType($job_prefix);
$runner->runOne(db(), $logger);
示例#8
0
<?php

$value1 = require_get("value1", "1");
$currency1 = require_get("currency1", "btc");
$value2 = require_get("value2", "");
$currency2 = require_get("currency2", "usd");
?>

<div class="calculator">
<span class="row">
<input type="text" id="value1" value="<?php 
echo htmlspecialchars($value1);
?>
">
<select id="currency1">
<?php 
foreach (get_all_currencies() as $cur) {
    echo "<option value=\"" . htmlspecialchars($cur) . "\" class=\"currency_name_" . htmlspecialchars($cur) . "\"" . ($cur == $currency1 ? " selected" : "") . ">" . get_currency_abbr($cur) . "</option>\n";
}
?>
</select>
</span>

<span class="row">
<span class="equals">=</span>
</span>

<span class="row">
<input type="text" id="value2" value="<?php 
echo htmlspecialchars($value2);
?>
<?php

/**
 * Admin status page: jobs distribution
 */
require_admin();
require __DIR__ . "/../layout/templates.php";
$messages = array();
$errors = array();
page_header("Admin: Jobs Distribution", "page_admin_jobs_distribution");
$q = db()->prepare("SELECT COUNT(*) AS c, SUM(is_error) AS errors, SUM(execution_count) AS execs, AVG(priority) AS priority, job_type FROM (SELECT * FROM jobs WHERE is_executed=1 ORDER BY id DESC LIMIT " . (int) require_get("n", 4000) . ") AS j GROUP BY job_type ORDER BY c DESC");
$q->execute();
$jobs = $q->fetchAll();
$total_c = 0;
foreach ($jobs as $job) {
    $total_c += $job['c'];
}
// where 0..100% = fine; 110% = good; etc
function get_error_class($n)
{
    if ($n <= 1) {
        // 0%
        return "perfect";
    } else {
        if ($n <= 1.25) {
            return "good";
        } else {
            if ($n <= 1.5) {
                return "ok";
            } else {
                if ($n <= 1.75) {
示例#10
0
<thead>
  <tr>
    <th>Job ID</th>
    <th>Priority</th>
    <th>Job type</th>
    <th>Manual</th>
    <th>Executing</th>
    <th>Attempts</th>
    <th>Created at</th>
    <th>User</th>
    <th></th>
  </tr>
</thead>
<tbody>
<?php 
$order_by = require_get("oldest", false) ? "created_at ASC, priority ASC, id ASC" : "priority ASC, id ASC";
$q = db()->prepare("SELECT jobs.*, users.email FROM jobs\n    LEFT JOIN users ON jobs.user_id=users.id\n    WHERE is_executed=0 ORDER BY {$order_by} LIMIT 50");
$q->execute();
while ($job = $q->fetch()) {
    ?>
  <tr>
    <td><?php 
    echo number_format($job['id']);
    ?>
</td>
    <td><?php 
    echo number_format($job['priority']);
    ?>
</td>
    <td><?php 
    echo htmlspecialchars($job['job_type']);
示例#11
0
<?php

require __DIR__ . "/../layout/templates.php";
$q = require_get("q");
if (!is_string($q)) {
    set_temporary_errors(array(t("Invalid article key.")));
    redirect(url_for('help'));
}
if (!$q) {
    redirect(url_for('help'));
}
// we define all knowledge base articles ourselves, so that there's no chance
// of a security breach/injection
$knowledge = get_knowledge_base();
global $title;
$title = false;
foreach ($knowledge as $label => $a) {
    if (isset($a[$q])) {
        $title = $a[$q];
    }
}
if (!$title) {
    set_temporary_errors(array(t("No such knowledge base article ':key'.", array(':key' => htmlspecialchars($q)))));
    redirect(url_for('help'));
}
if (is_array($title)) {
    global $kb_inline;
    $kb_inline = $title['inline'];
    $title = $title['title'];
    $q = 'inline';
}
示例#12
0
<?php

/**
 * Allows users to add additional OAuth2 locations for their account.
 * Issue #266
 */
require_login();
// POST overrides GET
$oauth2 = require_post("oauth2", require_get("oauth2", false));
$messages = array();
$errors = array();
try {
    if ($oauth2) {
        $user = \Users\User::getInstance(db());
        $args = array("oauth2" => $oauth2);
        $url = absolute_url(url_for('oauth2_add', $args));
        $provider = Users\OAuth2Providers::createProvider($oauth2, $url);
        try {
            \Users\UserOAuth2::addIdentity(db(), $user, $provider);
            $messages[] = t("Added OAuth2 identity ':identity' to your account.", array(':identity' => htmlspecialchars($provider->getKey())));
            // redirect
            $destination = url_for('user#user_openid');
            set_temporary_messages($messages);
            set_temporary_errors($errors);
            redirect($destination);
        } catch (\Users\UserSignupException $e) {
            $errors[] = $e->getMessage();
        }
    }
} catch (Exception $e) {
    if (!$e instanceof EscapedException) {
示例#13
0
<?php

throw new Exception("This functionality is currently unavailable.");
$email = trim(require_post("email", require_get("email", false)));
$hash = require_post("hash", require_get("hash", false));
$password = require_post("password", require_get("password", false));
if ($password && !is_string($password)) {
    throw new Exception(t("Invalid password parameter"));
}
$password2 = require_post("password2", require_get("password2", false));
if ($password2 && !is_string($password2)) {
    throw new Exception(t("Invalid repeated password parameter"));
}
$messages = array();
$errors = array();
if ($email && $password) {
    if (!$hash) {
        $errors[] = t("No hash specified.");
    }
    if ($password && (strlen($password) < 6 || strlen($password) > 255)) {
        $errors[] = t("Please select a password between :min-:max characters long.", array(':min' => 6, ':max' => 255));
    }
    if ($password && $password != $password2) {
        $errors[] = t("Those passwords do not match.");
    }
    // check the request hash
    $q = db()->prepare("SELECT * FROM users WHERE email=? AND ISNULL(password_hash) = 0");
    $q->execute(array($email));
    $user = $q->fetch();
    if (!$user) {
        $errors[] = t("No such user account exists.");
示例#14
0
<?php 
}
?>
</tbody>
</table>
</div>

<div class="finance-form">

<h2><?php 
echo ht("Add Account");
?>
</h2>

<?php 
$account = array('title' => require_get('title', ""), 'description' => require_get('description', ""), 'gst' => require_get('gst', ""));
?>

<form action="<?php 
echo htmlspecialchars(url_for('finance_accounts'));
?>
" method="post">
<table>
<tr>
  <th><?php 
echo ht("Title:");
?>
</th>
  <td><input type="text" name="title" size="32" value="<?php 
echo htmlspecialchars($account['title']);
?>
示例#15
0
                // possible injection here... strip all protocol information to prevent redirection to external site
                $destination = str_replace('#[a-z]+://#im', '', $destination);
                redirect($destination);
            }
        }
    }
} catch (Exception $e) {
    if (!$e instanceof EscapedException) {
        $e = new EscapedException(htmlspecialchars($e->getMessage()), (int) $e->getCode(), $e);
    }
    $errors[] = $e->getMessage();
}
if (require_get("need_admin", false)) {
    $errors[] = t("You need to be logged in as an administrator to do that.");
}
if ($destination && !require_get("pause", false)) {
    $errors[] = t("You need to be logged in to proceed.");
}
require __DIR__ . "/../layout/templates.php";
page_header(t("Login"), "page_login", array('js' => 'auth'));
?>

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

<div class="authentication-form">
<h2><?php 
echo ht("Login");
?>
</h2>
global $user;
$user = get_user(user_id());
require_user($user);
// get all of our notifications
$q = db()->prepare("SELECT * FROM notifications WHERE user_id=? ORDER BY notification_type DESC, id ASC");
$q->execute(array(user_id()));
$notifications = $q->fetchAll();
// are we editing one?
$instance = false;
$account = false;
if (require_get("edit", false)) {
    $q = db()->prepare("SELECT * FROM notifications WHERE id=? AND user_id=?");
    $q->execute(array(require_get("edit"), user_id()));
    $instance = $q->fetch();
    if (!$instance) {
        $errors[] = t("Could not find your notification :key to edit.", array(':key' => htmlspecialchars(require_get("edit"))));
    }
    switch ($instance['notification_type']) {
        case "ticker":
            $q = db()->prepare("SELECT * FROM notifications_ticker WHERE id=?");
            $q->execute(array($instance['type_id']));
            $account = $q->fetch();
            // if false, we can still display default editing options
            break;
        case "summary_instance":
            $q = db()->prepare("SELECT * FROM notifications_summary_instances WHERE id=?");
            $q->execute(array($instance['type_id']));
            $account = $q->fetch();
            // if false, we can still display default editing options
            break;
        default:
示例#17
0
 (<?php 
    echo plural("graph", count($managed_graphs[$key]));
    ?>
)</label>
        <?php 
    print_graph_types($managed_graphs[$key]);
    ?>
      <?php 
}
?>
    </ul>
  </li>

  <li>
    <label><input type="radio" name="preference" value="none"<?php 
echo require_get("preference", $user['graph_managed_type']) == 'none' ? ' checked' : '';
?>
> <?php 
echo t("I will manage my own graphs and pages.");
?>
</label>
  </li>

</ul>

<div style="clear:both;"></div>

<div class="wizard-buttons">
<a class="button" href="<?php 
echo htmlspecialchars(url_for('wizard_accounts'));
?>
示例#18
0
while ($ticker = $q->fetch()) {
    // TODO strip out currencies we aren't officially tracking yet
    if (!in_array($ticker['currency1'], get_all_currencies())) {
        continue;
    }
    if (!in_array($ticker['currency2'], get_all_currencies())) {
        continue;
    }
    $key = $ticker['currency1'] . $ticker['currency2'];
    $pairs[$key] = $ticker;
}
// if none is selected, use defaults
global $currency1;
global $currency2;
$currency1 = require_get("currency1", "usd");
$currency2 = require_get("currency2", "btc");
if (!in_array($currency1, get_all_currencies())) {
    $currency1 = "usd";
}
if (!in_array($currency2, get_all_currencies())) {
    $currency1 = "btc";
}
if (!isset($pairs[$currency1 . $currency2])) {
    $currency1 = "usd";
    $currency2 = "btc";
}
page_header(t("Market Average: :pair", array(':pair' => get_currency_name($currency1) . "/" . get_currency_name($currency2))), "page_average", array('jsapi' => true));
$graph_id = 0;
?>

<h1><?php 
示例#19
0
if (!$user['email']) {
    ?>
<div class="warning">
<ul>
  <li><?php 
    echo ht("Warning: Without a valid e-mail address specified in your contact details, you will not receive important announcements\n    and notifications about your accounts and user profile.");
    ?>
</li>
</ul>
</div>
<?php 
}
?>

<?php 
if (strtotime($user['created_at']) >= strtotime("-1 hour") || require_get("welcome", false)) {
    ?>
<div class="success">
<ul>
  <li><?php 
    echo ht("Welcome to :site_name!");
    ?>
</li>
  <li><?php 
    echo t("To get started, you should update your :preferences.", array(':preferences' => "<a href=\"" . htmlspecialchars(url_for('wizard_currencies')) . "\">" . ht("currency, accounts and reporting preferences") . "</a>"));
    ?>
</li>
</ul>
</div>
<?php 
}
示例#20
0
foreach ($add_types as $exchange) {
    echo "<option value=\"" . htmlspecialchars($exchange) . "\"" . ($exchange == require_get("exchange", false) ? " selected" : "") . ">";
    echo htmlspecialchars($add_type_names[$exchange]);
    echo "</option>\n";
}
?>
      </select>
    </td>
  </tr>
  <tr>
    <th><label for="title"><?php 
echo ht("Title:");
?>
</label></th>
    <td><input id="title" type="text" name="title" size="18" maxlength="64" value="<?php 
echo htmlspecialchars(require_get("title", ""));
?>
"> <?php 
echo ht("(optional)");
?>
</td>
  </tr>
  <tr id="add_account_template" style="display:none;">
    <th><label for="ignored">Parameter:</label></th>
    <td><input id="ignored" type="text" name="ignored" size="18" maxlength="64" value=""></td>
  </tr>
  <tr id="add_account_template_dropdown" style="display:none;">
    <th><label for="ignored">Parameter:</label></th>
    <td><select id="ignored" name="ignored">
      <option id="option_template"></option>
    </select></td>
示例#21
0
 premium"><a href="<?php 
echo htmlspecialchars(url_for('profile', $args));
?>
">
    <?php 
echo ht("Your Securities");
?>
 (<?php 
echo number_format($securities_count);
?>
)
  </a></li>
  <?php 
$args = array();
if (require_get("demo", false)) {
    $args['demo'] = require_get("demo");
}
?>
  <li class="page_tabtransactions<?php 
if (isset($your_transactions) && $your_transactions) {
    echo " page_current";
}
?>
"><a href="<?php 
echo htmlspecialchars(url_for('your_transactions', $args));
?>
">
    <?php 
echo ht("Your Transactions");
?>
 <span class="new"><?php 
示例#22
0
<?php

// router.php
require __DIR__ . "/../inc/global.php";
$path = require_get("path", "index");
use Pages\PageRenderer;
use Openclerk\Router;
PageRenderer::addTemplatesLocation(__DIR__ . "/../templates");
PageRenderer::addTemplatesLocation(__DIR__ . "/../config/templates");
/**
 * Include compiled header code, this was a hack to work around
 * Grunt/build/deploy issues. TODO clean this up and remove this workaround
 */
function include_head_compiled()
{
    echo "<!-- compiled head -->";
    $head_compiled = __DIR__ . "/head-compiled.html";
    if (file_exists($head_compiled)) {
        require $head_compiled;
    } else {
        // fix relative paths
        $input = file_get_contents(__DIR__ . "/../layout/head.html");
        $input = str_replace("src=\"", "src=\"" . htmlspecialchars(calculate_relative_path()), $input);
        echo $input;
    }
    echo "<!-- /compiled head -->";
}
try {
    \Openclerk\Router::process($path);
} catch (\Openclerk\RouterException $e) {
    header("HTTP/1.0 404 Not Found");
示例#23
0
/**
 * Scales the given number down if the ?demo parameter is supplied as part of the request.
 * Useful for displaying demo data.
 */
function demo_scale($value)
{
    if (require_get("demo", false)) {
        return $value * 0.05;
    }
    return $value;
}
 public function getData($days)
 {
     $columns = array();
     $key_column = array('type' => 'date', 'title' => ct("Date"));
     // $columns = $this->getTickerColumns();
     // TODO extra_days_necessary
     $extra_days = 10;
     $sources = $this->getCompositionSources($days, $extra_days);
     $args = $this->getCompositionArgs();
     $data = array();
     $last_updated = false;
     $exchanges_found = array();
     $maximum_balances = array();
     // only used to check for non-zero accounts
     $data_temp = array();
     $hide_missing_data = !require_get("debug_show_missing_data", false);
     $latest = array();
     foreach ($sources as $source) {
         $q = db()->prepare($source['query']);
         $q->execute($args);
         while ($ticker = $q->fetch()) {
             $key = date('Y-m-d', strtotime($ticker[$source['key']]));
             if (!isset($data_temp[$key])) {
                 $data_temp[$key] = array();
             }
             if (!isset($data_temp[$key][$ticker['exchange']])) {
                 $data_temp[$key][$ticker['exchange']] = 0;
             }
             $data_temp[$key][$ticker['exchange']] += $ticker[$source['balance_key']];
             $last_updated = max($last_updated, strtotime($ticker['created_at']));
             $exchanges_found[$ticker['exchange']] = $ticker['exchange'];
             if (!isset($maximum_balances[$ticker['exchange']])) {
                 $maximum_balances[$ticker['exchange']] = 0;
             }
             $maximum_balances[$ticker['exchange']] = max($ticker[$source['balance_key']], $maximum_balances[$ticker['exchange']]);
             if (!isset($latest[$ticker['exchange']])) {
                 $latest[$ticker['exchange']] = 0;
             }
             $latest[$ticker['exchange']] = max($latest[$ticker['exchange']], strtotime($ticker[$source['key']]));
         }
     }
     // get rid of any exchange summaries that had zero data
     foreach ($maximum_balances as $key => $balance) {
         if ($balance == 0) {
             foreach ($data_temp as $dt_key => $values) {
                 unset($data_temp[$dt_key][$key]);
             }
             unset($exchanges_found[$key]);
         }
     }
     // sort by date so we can get previous dates if necessary for missing data
     ksort($data_temp);
     $data = array();
     // add headings after we know how many exchanges we've found
     $first_heading = array('title' => t("Date"));
     $headings = array($first_heading);
     $i = 0;
     // sort them so they're always in the same order
     ksort($exchanges_found);
     foreach ($exchanges_found as $key => $ignored) {
         $headings[$key] = array('title' => $this->getHeadingTitle($key, $args));
     }
     // $data[0] = $headings;
     // add '0' for exchanges that we've found at one point, but don't have a data point
     // but reset to '0' for exchanges that are no longer present (i.e. from graph_data_balances archives)
     // this fixes a bug where old securities data is still displayed as present in long historical graphs
     $previous_row = array();
     foreach ($data_temp as $date => $values) {
         $row = array();
         foreach ($exchanges_found as $key => $ignored) {
             if (!$hide_missing_data || strtotime($date) <= $latest[$key]) {
                 if (!isset($values[$key])) {
                     $row[$key] = graph_number_format(isset($previous_row[$key]) ? $previous_row[$key] : 0);
                 } else {
                     $row[$key] = graph_number_format(demo_scale($values[$key]));
                 }
             } else {
                 $row[$key] = graph_number_format(0);
             }
         }
         if (count($row) > 0) {
             // don't add empty rows
             $data[$date] = $row;
             $previous_row = $row;
         }
     }
     // sort each row by the biggest value in the most recent data
     // so e.g. BTC comes first, LTC comes second, regardless of order of summary_instances, balances etc
     $keys = array_keys($data);
     // we can only sort if we actually have data
     if (count($keys) == 0) {
         // bail early
         throw new NoDataGraphException_AddCurrencies();
     }
     $last_row = $data[$keys[count($keys) - 1]];
     arsort($last_row);
     $data_temp = array();
     foreach ($data as $row => $columns) {
         $temp = array();
         foreach ($last_row as $key => $ignored) {
             $temp[$key] = $columns[$key];
         }
         $data_temp[$row] = $temp;
     }
     $data = $data_temp;
     // convert columns and data into numeric indices
     $result_columns = array();
     $result_column_map = array();
     foreach ($columns as $key => $column) {
         $result_columns[] = array('type' => 'number', 'title' => $this->getHeadingTitle($key, $args));
         // if the key is a currency, use the same currency colour across all graphs
         if (in_array(strtolower($key), get_all_currencies())) {
             $result_columns[count($result_columns) - 1]['color'] = array_search(strtolower($key), get_all_currencies());
         }
         $result_column_map[$key] = count($result_columns) - 1;
     }
     $result_data = array();
     foreach ($data as $date => $row) {
         $new_row = array();
         foreach ($row as $key => $value) {
             $new_row[$result_column_map[$key]] = $value;
         }
         $result_data[$date] = $new_row;
     }
     // find the last row, and calculate its total for later
     $last_row = array();
     $last_row_total = 0;
     foreach ($result_data as $date => $row) {
         $last_row = $row;
     }
     foreach ($row as $value) {
         $last_row_total += $value;
     }
     // sort the last row, and then use this new order to resort all
     // of the columns and data
     arsort($last_row);
     $sorted_columns = array();
     $sorted_data = array();
     foreach ($last_row as $i => $ignored) {
         $sorted_columns[] = $result_columns[$i];
     }
     foreach ($result_data as $date => $rows) {
         $sorted_row = array();
         foreach ($last_row as $i => $ignored) {
             $sorted_row[] = $rows[$i];
         }
         $sorted_rows[$date] = $sorted_row;
     }
     return array('key' => $key_column, 'columns' => $sorted_columns, 'data' => $sorted_rows, 'last_updated' => $last_updated, 'last_row_total' => $last_row_total);
 }
示例#25
0
/**
 * Render the HTML on the page necessary for rendering a graph to the user.
 *
 * @param $graph = array(
 *    'graph_type' => $id,
 *    'width' => 8,
 *    'height' => 4,
 *    'page_order' => 0,
 *    'days' => $days,
 *    'id' => 0,
 *    'arg0_resolved' => $name,
 *    'delta' => $delta,
 *    'public' => true,
 *    'no_technicals' => true,
 *  );
 * @param $include_user_hash if true, include user_id and user_hash in the graph data, necessary for
 *        graphs that require user authentication; default is false
 */
function render_graph_new($graph, $include_user_hash = false)
{
    global $_rendered_graph_contents;
    if (!$_rendered_graph_contents) {
        // calculate the relevant text for outofdate indicators
        $title = "";
        if (user_logged_in()) {
            $user = get_user(user_id());
            $plural_hours = plural("hour", user_is_new($user) ? get_site_config('refresh_queue_hours_premium') : get_premium_value($user, "refresh_queue_hours"));
            if ($user['is_first_report_sent']) {
                $title = t("This graph will take up to :hours to be updated with recently added or removed accounts.", array(':hours' => $plural_hours));
            } else {
                if ($user['has_added_account']) {
                    $title = t("As a new user, it will take up to :hours for this graph to be populated with initial data.", array(':hours' => $plural_hours));
                } else {
                    $title = t("You need to add some account data for this graph to display.");
                }
            }
        }
        ?>
    <div id="graph_contents_template" style="display:none;">
      <div class="graph_headings">
        <h1 class="h1"></h1>
        <h2 class="h2"></h2>
        <h2 class="graph_title">
          <a href=""></a>
        </h2>
        <span class="outofdate" style="display:none;" title="<?php 
        echo htmlspecialchars($title);
        ?>
"></span>
        <span class="subheading"></span>
        <span class="last-updated"></span>
        <ul class="graph_controls">
          <li class="move_up"><a><?php 
        echo ht("Move up");
        ?>
</a></li>
          <li class="move_down"><a><?php 
        echo ht("Move down");
        ?>
</a></li>
          <li class="remove"><a><?php 
        echo ht("Remove");
        ?>
</a></li>
          <li class="edit"><a><?php 
        echo ht("Edit");
        ?>
</a></li>
        </ul>
        <div class="edit_target" style="display:none;">
          <ul class="graph_edit_controls">
            <li class="close"><a><?php 
        echo ht("Close");
        ?>
</a></li>
          </ul>
        </div>
      </div>
      <div class="graph-target"><span class="status_loading"><?php 
        echo ht("Loading...");
        ?>
</span></div>
      <div class="graph_extra extra" style="display:none;"><a href="#"></a></span></div>
      <div class="admin-stats-wrapper hide-admin"><span class="admin-stats render_time"></span></div>
    </div>
    <div id="graph_table_template" class="overflow_wrapper extra-text-container" style="display:none;">
      <table class="standard graph_table">
      </table>
    </div>
    <?php 
    }
    if (user_logged_in()) {
        $user = get_user(user_id());
        $graph['can_be_edited'] = !($user['graph_managed_type'] == 'auto' && isset($graph['is_managed']) && $graph['is_managed']);
    }
    if (isset($graph['page_id']) && isset($graph['id'])) {
        $graph['move_up_link'] = url_for('profile', array('page' => $graph['page_id'], 'move_up' => $graph['id']));
        $graph['move_down_link'] = url_for('profile', array('page' => $graph['page_id'], 'move_down' => $graph['id']));
        $graph['remove_link'] = url_for('profile', array('page' => $graph['page_id'], 'remove' => $graph['id']));
    }
    if (isset($graph['id']) && $graph['id']) {
        $graph_id = "graph_" . $graph['id'];
    } else {
        $graph_id = "graph_" . rand(0, 0xffff);
    }
    $graph['target'] = $graph_id;
    $graph['graphWidth'] = get_site_config('default_graph_width') * $graph['width'];
    $graph['computedWidth'] = $graph['graphWidth'];
    $graph['graphHeight'] = get_site_config('default_graph_height') * $graph['height'];
    $graph['computedHeight'] = $graph['graphHeight'] + 30;
    // if we are logged in, also provide the user ID and computed user hash, to verify that we can
    // correctly access this graph (also means that we don't have to initialise sessions on the API)
    if ($include_user_hash && user_logged_in()) {
        $graph['user_id'] = user_id();
        $graph['user_hash'] = compute_user_graph_hash(get_user(user_id()));
    }
    // enable demo if necessary
    if (require_get("demo", false)) {
        $graph['demo'] = true;
    }
    // we set the widths and heights initially here so that the page layout doesn't move around
    // a lot as the graphs are loaded via AJAX
    $inline_styles = "overflow: hidden; width: " . $graph['computedWidth'] . "px; height: " . $graph['computedHeight'] . "px;";
    switch ($graph['graph_type']) {
        case "linebreak":
        case "heading":
            // don't render anything! this rendering is handled by profile.php
            return;
        case "calculator":
            // a special case for the Calculator widget; it doesn't seem a good idea to
            // have this as an API call that returns a mixture of HTML and Javascript
            ?>
      <div id="<?php 
            echo htmlspecialchars($graph_id);
            ?>
" class="graph graph_calculator" style="<?php 
            echo $inline_styles;
            ?>
">
        <div class="graph_headings">
          <h2 class="graph_title"><?php 
            echo ht("Currency converter");
            ?>
</h2>
        </div>
        <div class="graph-target">
          <?php 
            require __DIR__ . "/../pages/_calculator.php";
            ?>
        </div>
      </div>
      <script type="text/javascript">
      $(document).ready(function() {
        Graphs.render(<?php 
            echo json_encode($graph);
            ?>
, true /* static graph */);
        initialise_calculator($("#<?php 
            echo htmlspecialchars($graph_id);
            ?>
"))
      });
      </script>
      <?php 
            return;
    }
    // 'overflow: hidden;' is to fix a Chrome rendering bug
    ?>
    <div id="<?php 
    echo htmlspecialchars($graph_id);
    ?>
" class="graph" style="<?php 
    echo $inline_styles;
    ?>
"></div>
    <script type="text/javascript">
      Graphs.render(<?php 
    echo json_encode($graph);
    ?>
);
    </script>
  <?php 
}
示例#26
0
        // just remove it
        $q = db()->prepare("UPDATE graphs SET is_removed=1 WHERE id=? LIMIT 1");
        $q->execute(array($graph['id']));
        if (!require_get('undo', false)) {
            $messages[] = t("Graph removed [:undo]", array(':undo' => link_to(url_for('profile', array('page' => $graph['page_id'], 'restore' => $graph['id'], 'undo' => 1)), t("undo"))));
        }
    } else {
        throw new Exception("Could not find a graph ID " . htmlspecialchars($graph_id));
    }
}
if (require_get("restore", false)) {
    $enable_editing = true;
    // current graph
    $graph_id = require_get("restore");
    $q = db()->prepare("SELECT graphs.* FROM graphs\n    JOIN graph_pages ON graphs.page_id=graph_pages.id\n    WHERE graph_pages.user_id=? AND graphs.id=?");
    $q->execute(array(user_id(), $graph_id));
    $graph = $q->fetch();
    if ($graph) {
        // just remove it
        $q = db()->prepare("UPDATE graphs SET is_removed=0 WHERE id=? LIMIT 1");
        $q->execute(array($graph['id']));
        if (!require_get('undo', false)) {
            $messages[] = t("Graph restored [:undo]", array(':undo' => link_to(url_for('profile', array('page' => $graph['page_id'], 'remove' => $graph['id'], 'undo' => 1)), t("undo"))));
        }
    } else {
        throw new Exception("Could not find a graph ID " . htmlspecialchars($graph_id));
    }
}
if (require_get("graph", false)) {
    $enable_editing = true;
}
示例#27
0
 * 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()");
$query->execute(array($user["id"], $user_key));
// update session data
$_SESSION["user_id"] = $user["id"];
示例#28
0
<?php

/**
 * Admin: run a job (without displaying automated_key publically)
 */
require_admin();
require __DIR__ . "/../layout/templates.php";
define('ADMIN_RUN_JOB', true);
$options = array();
if (require_get("refresh", false)) {
    $options['refresh'] = require_get("refresh");
}
page_header("Run Job", "page_run_job", $options);
$_GET['key'] = get_site_config('automated_key');
require __DIR__ . "/../batch/batch_run.php";
page_footer();
示例#29
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");
<?php

/**
 * Callback for Ajax to update wizard table for manual testing.
 */
require __DIR__ . "/../layout/templates.php";
$user = get_user(user_id());
require_user($user);
$exchange = require_get('exchange');
$id = require_get('id');
// make sure that we actually have a valid account
$account_data = false;
$accounts = array();
foreach (account_data_grouped() as $label => $data) {
    foreach ($data as $key => $value) {
        if ($key == $exchange) {
            // we've found a valid account type
            $account_data = get_accounts_wizard_config($key);
            $account_type = get_wizard_account_type($value['wizard']);
            $add_types[] = $key;
            $add_type_names[$key] = get_exchange_name($key) . (isset($value['suffix']) ? $value['suffix'] : "");
            $q = db()->prepare("SELECT * FROM " . $account_data['table'] . "\n        WHERE user_id=? AND id=? ORDER BY title ASC");
            $q->execute(array(user_id(), $id));
            while ($r = $q->fetch()) {
                $r['exchange'] = $key;
                $r['khash'] = $account_data['khash'];
                $accounts[] = $r;
            }
        }
    }
}