diff --git a/html/inc/boinc_db.inc b/html/inc/boinc_db.inc
index 51146d89d0..cb00a2547c 100644
--- a/html/inc/boinc_db.inc
+++ b/html/inc/boinc_db.inc
@@ -684,4 +684,18 @@ class BoincCreditTeam {
}
}
+// DEPRECATED: use BoincDb::escape_string where possible
+//
+// apply this to any user-supplied strings used in queries
+//
+function boinc_real_escape_string($x) {
+ if (version_compare(phpversion(),"4.3.0")>=0) {
+ return BoincDb::escape_string($x);
+ } else {
+ $x = str_replace("'", "\'", $x);
+ $x = str_replace("\"", "\\\"", $x);
+ return $x;
+ }
+}
+
?>
diff --git a/html/inc/db.inc b/html/inc/db.inc
index e239d4aabe..533ad16d65 100644
--- a/html/inc/db.inc
+++ b/html/inc/db.inc
@@ -16,8 +16,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see .
-require_once('../inc/util.inc');
-require_once('../inc/boinc_db.inc');
+require_once('../project/project.inc');
// database-related functions.
// Presentation code (HTML) shouldn't be here
@@ -25,6 +24,21 @@ require_once('../inc/boinc_db.inc');
// DEPRECATED; use boinc_db.inc instead.
// TODO: replace calls to these functions
+// use mysqli if available,
+// but let projects not use it if they want
+// (by define('NO_MYSQLI', true) in project.inc)
+//
+if (defined('NO_MYSQLI') && NO_MYSQLI) {
+ define("MYSQLI", false);
+} else {
+ if (class_exists("mysqli")) {
+ define("MYSQLI", true);
+ $mysqli = null;
+ } else {
+ define("MYSQLI", false);
+ }
+}
+
if (MYSQLI) {
function _mysql_connect($host, $user, $pass, $dbname) {
global $mysqli;
@@ -170,20 +184,6 @@ function db_init_aux($try_replica=false) {
return 0;
}
-// DEPRECATED: use BoincDb::escape_string where possible
-//
-// apply this to any user-supplied strings used in queries
-//
-function boinc_real_escape_string($x) {
- if (version_compare(phpversion(),"4.3.0")>=0) {
- return BoincDb::escape_string($x);
- } else {
- $x = str_replace("'", "\'", $x);
- $x = str_replace("\"", "\\\"", $x);
- return $x;
- }
-}
-
// escape a string for MySQL "like"
//
function escape_pattern($str) {
diff --git a/html/inc/db_conn.inc b/html/inc/db_conn.inc
index 6e4ef49a3f..da9092dd50 100644
--- a/html/inc/db_conn.inc
+++ b/html/inc/db_conn.inc
@@ -16,23 +16,6 @@
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see .
-require_once("../project/project.inc");
-
-// use mysqli if available,
-// but let projects not use it if they want
-// (by define('NO_MYSQLI', true) in project.inc)
-//
-if (defined('NO_MYSQLI') && NO_MYSQLI) {
- define("MYSQLI", false);
-} else {
- if (class_exists("mysqli")) {
- define("MYSQLI", true);
- $mysqli = null;
- } else {
- define("MYSQLI", false);
- }
-}
-
// represents a connection to a database.
// Intended to be subclassed (e.g., BoincDb, BossaDb)
//
diff --git a/html/inc/team.inc b/html/inc/team.inc
index ce45b1c01f..e0db7e5caa 100644
--- a/html/inc/team.inc
+++ b/html/inc/team.inc
@@ -383,14 +383,18 @@ function team_table_start($sort_by, $type_url) {
";
}
+function team_links($team) {
+ $b = badges_string(false, $team, BADGE_HEIGHT_MEDIUM);
+ return "id>$team->name $b";
+}
+
function show_team_row($team, $i) {
$team_expavg_credit = format_credit_large($team->expavg_credit);
$team_total_credit = format_credit_large($team->total_credit);
$j = $i % 2;
- $b = badges_string(false, $team, BADGE_HEIGHT_MEDIUM);
echo"
$i |
- id>$team->name $b |
+ ".team_links($team)." |
".$team->nusers." |
$team_expavg_credit |
$team_total_credit |
diff --git a/html/user/per_app_list.php b/html/user/per_app_list.php
new file mode 100644
index 0000000000..c5afb5fe73
--- /dev/null
+++ b/html/user/per_app_list.php
@@ -0,0 +1,129 @@
+.
+
+// show top users or teams, ordered by per-app credit
+//
+// URL args:
+// is_team: if nonzero, show teams
+// appid: ID of app for sorting; default is first app returned by enum
+// is_total: if nonzero, sort by total credit
+
+require_once("../inc/util.inc");
+
+// return a column title (Average or Total),
+// hyperlinked if this is not the current sort column
+//
+function col_title($is_team, $app, $appid, $is_total, $i) {
+ $x = $i?"Total":"Average";
+ if ($app->id == $appid && ($is_total?$i:!$i)) {
+ return $x;
+ } else {
+ return "id&is_team=$is_team&is_total=$i>$x";
+ }
+}
+
+// print a row of app names,
+// under each of which are columns for Average and Total
+//
+function show_header($is_team, $apps, $appid, $is_total) {
+ echo "
| ";
+ foreach ($apps as $app) {
+ echo "$app->name | \n";
+ }
+ echo "
";
+
+ echo "";
+ echo "Rank | Name | \n";
+ foreach ($apps as $app) {
+ for ($i=0; $i<2; $i++) {
+ $x = col_title($is_team, $app, $appid, $is_total, $i);
+ echo "$x | \n";
+ }
+ }
+ echo "
";
+
+}
+
+// show a user or team, with their credit for each app
+//
+function show_row($item, $apps, $is_team, $i) {
+ $j = $i % 2;
+ if ($is_team) {
+ $team = BoincTeam::lookup_id($item->teamid);
+ if (!$team) return;
+ $x = "".team_links($team)." | \n";
+ } else {
+ $user = BoincUser::lookup_id($item->userid);
+ if (!$user) return;
+ $x= "".user_links($user, BADGE_HEIGHT_MEDIUM)." | \n";
+ }
+ echo "";
+ echo "$i | \n";
+ echo $x;
+
+ foreach ($apps as $app) {
+ if ($app->id == $item->appid) {
+ $c = $item;
+ } else {
+ if ($is_team) {
+ $c = BoincCreditTeam::lookup("teamid=$item->teamid and appid=$app->id");
+ } else {
+ $c = BoincCreditUser::lookup("userid=$item->userid and appid=$app->id");
+ }
+ if (!$c) {
+ $c = new StdClass;
+ $c->expavg = 0;
+ $c->total = 0;
+ }
+ }
+ echo "".format_credit($c->expavg)." | ".format_credit_large($c->total)." | \n";
+ }
+ echo "
\n";
+}
+
+function show_list($is_team, $appid, $is_total) {
+ $x = $is_team?"teams":"participants";
+ page_head("Top $x by application");
+ $apps = BoincApp::enum("deprecated=0");
+ if (!$appid) {
+ $appid = $apps[0]->id;
+ }
+ start_table();
+ show_header($is_team, $apps, $appid, $is_total);
+ $x = $is_total?"total":"expavg";
+ if ($is_team) {
+ $items = BoincCreditTeam::enum("appid=$appid order by $x desc");
+ } else {
+ $items = BoincCreditUser::enum("appid=$appid order by $x desc");
+ }
+ $i = 0;
+ foreach ($items as $item) {
+ show_row($item, $apps, $is_team, $i);
+ $i++;
+ }
+ end_table();
+ page_tail();
+}
+
+$is_team = get_int('is_team', true);
+$appid = get_int('appid', true);
+$is_total = get_int('is_total', true);
+
+show_list($is_team, $appid, $is_total);
+
+?>
diff --git a/html/user/stats.php b/html/user/stats.php
index 5177966377..62fbd2f4fe 100644
--- a/html/user/stats.php
+++ b/html/user/stats.php
@@ -22,20 +22,29 @@ page_head(tra('Statistics and leaderboards'));
check_get_args(array());
+$credit_by_app = parse_bool(get_config(), "credit_by_app");
+
start_table();
echo "
"
. tra("Statistics for %1",PROJECT).":
|