"; start_table(); row2("Search criteria (use one or more)", ""); row2('Key words
Find teams with these words in their names or descriptions', ''); row2_init("Country", ""); echo '\n"; row2("Type of team", team_type_select($params->type, true)); $checked = $params->active?"checked":""; row2("Show only active teams", ""); row2("", ''); end_table(); echo " "; } function foundership_transfer_link($user, $team) { $now = time(); if ($team->ping_user == $user->id) { if (transfer_ok($team, $now)) { return "Requested by you, and founder response deadline has passed.
Complete foundership transfer. "; } else { $deadline = date_str(transfer_ok_time($team)); return 'Requested by you; founder response deadline is '.$deadline; } } if (new_transfer_request_ok($team, $now)) { if ($team->userid == $user->id) { return "None"; } else { return 'Initiate request'; } } return "Deferred"; } function display_team_page($team, $user) { page_head("$team->name"); echo sanitize_html($team->name_html); echo "

"; start_table(); row1("Team info"); if (strlen($team->description)) { row2("Description", sanitize_html($team->description)); } if (strlen($team->url)) {; if (strstr($team->url, "http://")) { $x = $team->url; } else { $x = "http://$team->url"; } row2("Web site", "$x"); } if (!no_computing()) { row2("Total credit", format_credit_large($team->total_credit)); row2("Recent average credit", format_credit_large($team->expavg_credit)); } row2("Country", $team->country); row2("Type", team_type_name($team->type)); if ($team->forum && is_forum_visible_to_user($team->forum, $user)) { $f = $team->forum; row2("id>Message board", "Threads: $f->threads
Posts: $f->posts
Last post: ".time_diff_str($f->timestamp, time()) ); } if ($user) { if ($user->teamid != $team->id) { $tokens = url_tokens($user->authenticator); row2("", "Join this team
Note: if 'OK to email' is set in your project preferences, joining a team gives its founder access to your email address." ); } if (($user->teamid == $team->id)) { if (($user->id == $team->userid)) { if ($team->ping_user) { $deadline = date_str(transfer_ok_time($team)); row2("Foundership change requested", "id>Respond by $deadline" ); } } else { row2("Team foundership change", foundership_transfer_link($user, $team)); } } } row1("Members"); row2("Founder", user_links($team->founder)); if (count($team->admins)) { $first = true; $x = ""; foreach ($team->admins as $a) { if ($first) { $first = false; } else { $x .= " | "; } $x .= user_links($a); } row2("Admins", $x); } $x = "0"; if (count($team->new_members)) { $first = true; $x = ""; foreach ($team->new_members as $a) { if ($first) { $first = false; } else { $x .= " | "; } $x .= user_links($a); } } row2("New members in last day", $x); row2("Total members", "$team->nusers (id&offset=0&sort_by=expavg_credit>view)"); row2("Active members", "$team->nusers_active (id&offset=0&sort_by=expavg_credit>view)"); row2("Members with credit", "$team->nusers_worked (id&offset=0&sort_by=total_credit>view)"); end_table(); } function display_team_members($team, $offset, $sort_by) { $n = 20; $admins = BoincTeamAdmin::enum("teamid=$team->id"); // there aren't indices to support sorting by credit. // set the following variable to disable sorted output. // (though since caching is generally used this shouldn't needed) // $nosort = false; if ($sort_by == "total_credit") { $sort_clause = "total_credit desc"; } else { $sort_clause = "expavg_credit desc"; } start_table(); echo " Name "; if (!no_computing()) { if ($nosort) { echo " Total credit Recent average credit "; } else { if ($sort_by == "total_credit") { echo "Total credit"; } else { echo "id&sort_by=total_credit&offset=$offset>Total credit"; } if ($sort_by == "expavg_credit") { echo "Recent average credit"; } else { echo "id&sort_by=expavg_credit&offset=$offset>Recent average credit"; } } } echo " Country "; if ($nosort) { $users = BoincUser::enum("teamid=$team->id limit $offset,$n"); } else { $users = BoincUser::enum("teamid=$team->id order by $sort_clause limit $offset,$n"); } $j = $offset + 1; foreach ($users as $user) { $user_total_credit = format_credit_large($user->total_credit); $user_expavg_credit = format_credit($user->expavg_credit); $x = user_links($user); if ($user->id == $team->userid) { $x .= " [Founder]"; } else if (is_team_admin_aux($user, $admins)) { $x .= " [Admin]"; } echo " $j) $x "; if (!no_computing()) { echo " $user_total_credit $user_expavg_credit "; } echo " $user->country "; $j++; } echo ""; if ($offset > 0) { $new_offset = $offset - $n; echo "id&sort_by=$sort_by&offset=$new_offset>Last $n | "; } if ($j == $offset + $n + 1) { $new_offset = $offset + $n; echo "id&sort_by=$sort_by&offset=$new_offset>Next $n"; } } // check that the team exists // function require_team($team) { if (!$team) { error_page("No such team."); } } function is_team_founder($user, $team) { return $user->id == $team->userid; } // check that the user is founder of the team // function require_founder_login($user, $team) { require_team($team); if ($user->id != $team->userid) { error_page("This operation requires foundership."); } } function is_team_admin($user, $team) { if (!$user) return false; if ($user->id == $team->userid) return true; $admin = BoincTeamAdmin::lookup($team->id, $user->id); if ($admin) return true; return false; } // use this when you're displaying a long list of users // and don't want to do a lookup for each one // function is_team_admin_aux($user, $admins) { foreach ($admins as $a) { if ($a->userid == $user->id) return true; } return false; } function require_admin($user, $team) { if (!is_team_admin($user, $team)) { error_page("This operation requires team admin privileges"); } } function new_member_list($teamid) { $new_members = array(); $yesterday = time() - 86400; $deltas = BoincTeamDelta::enum("teamid=$teamid and timestamp>$yesterday and joining=1 group by userid"); if (count($deltas)) { foreach ($deltas as $delta) { $u = BoincUser::lookup_id($delta->userid); if ($u->teamid == $teamid) { $new_members[] = $u; // they might have later quit } } } return $new_members; } function admin_list($teamid) { $u = array(); $admins = BoincTeamAdmin::enum("teamid=$teamid"); foreach ($admins as $admin) { $user = BoincUser::lookup_id($admin->userid); $u[] = $user; } return $u; } function team_table_start($sort_by, $type_url) { echo " ".tra("Rank")." ".tra("Name")." ".tra("Members")." "; if ($sort_by == "total_credit") { echo " ".tra("Recent average credit")." ".tra("Total credit")." "; } else { echo " ".tra("Recent average credit")." ".tra("Total credit")." "; } echo " ".tra("Country")." Type "; } function show_team_row($team, $i) { $team_expavg_credit = format_credit_large($team->expavg_credit); $team_total_credit = format_credit_large($team->total_credit); echo" $i id>$team->name ".$team->nusers." $team_expavg_credit $team_total_credit $team->country ".team_type_name($team->type)." \n"; } function user_join_team($team, $user) { user_quit_team($user); $res = $user->update("teamid=$team->id"); if ($res) { $now = time(); BoincTeamDelta::insert("(userid, teamid, timestamp, joining, total_credit) values ($user->id, $team->id, $now, 1, $user->total_credit)"); return true; } return false; } function user_quit_team($user) { if (!$user->teamid) return; $user->update("teamid=0"); $team = BoincTeam::lookup_id($user->teamid); if ($team && $team->ping_user=$user->id) { $team->update("ping_user=-ping_user"); } BoincTeamAdmin::delete("teamid=$user->teamid and userid=$user->id"); $now = time(); BoincTeamDelta::insert("(userid, teamid, timestamp, joining, total_credit) values ($user->id, $user->teamid, $now, 0, $user->total_credit)"); } function team_edit_form($team, $label, $url) { global $team_types; echo "

\n"; if ($team) { echo "id>\n"; } echo "

Privacy note: if you create a team, your project preferences (resource share, graphics preferences) will be visible to the public.

"; start_table(); row2( "Team name, text version
Don't use HTML tags. ", "" ); row2("Team name, HTML version
You may use limited HTML tags. If you don't know HTML, leave this box blank.", "name_html)."\">" ); row2("URL of team web page, if any:
(without \"http://\") This URL will be linked to from the team's page on this site.", "" ); row2("Description of team:
You may use limited HTML tags. ", "" ); row2("Type of team:", team_type_select($team->type)); row2_init("Country", "\n"; row2("", "" ); end_table(); echo "\n"; } // decay a team's average credit // function team_decay_credit($team) { $avg = $team->expavg_credit; $avg_time = $team->expavg_time; $now = time(0); update_average($now, 0, 0, $avg, $avg_time); $team->update("expavg_credit=$avg, expavg_time=$now"); } // if the team hasn't received new credit for ndays, // decay its average and return true // function team_inactive_ndays($team, $ndays) { $diff = time() - $team->expavg_time; if ($diff > $ndays*86400) { team_decay_credit($team); return true; } return false; } function team_count_members($teamid) { return BoincUser::count("teamid=$teamid"); } // These functions determine the rules for foundership transfer, namely: // - A transfer request is allowed if either: // - there is no active request, and it's been at least 60 days // since the last request (this protects the founder from // being bombarded with frequest requests) // - there's an active request older than 90 days // (this lets a 2nd requester eventually get a chance) // - Suppose someone (X) requests foundership at time T. // An email is sent to the founder (Y). // The request is "active" (ping_user is set to X's ID) // - If Y declines the change, an email is sent to X, // and the request is cleared. // - If Y accepts the change, an email is sent to X // and the request is cleared. // - After T + 60 days, X can become founder // - After T + 90 days, new requests are allowed even if there's // an active request, i.e. after the 60 days elapse X has another // 30 days to assume foundership before someone elase can request it // function new_transfer_request_ok($team, $now) { if ($team->ping_user <= 0) { if ($team->ping_time < $now - 60 * 86400) { return true; } return false; } if ($team->ping_time < $now - 90 * 86400) { return true; } return false; } // the time at which we can actually change foundership // if the founder hasn't responded // function transfer_ok_time($team) { return $team->ping_time + 60*86400; } function transfer_ok($team, $now) { if ($now > transfer_ok_time($team)) return true; return false; } // Make a team; args are untrusted, so cleanse and validate them // function make_team( $userid, $name, $url, $type, $name_html, $description, $country ) { $name = process_user_text(strip_tags($name)); if (strlen($name) == 0) return null; $name_lc = strtolower($name); $url = process_user_text(strip_tags($url)); if (strstr($url, "http://")) { $url = substr($url, 7); } $name_html = process_user_text($name_html); $description = process_user_text($description); $country = process_user_text($country); if (!is_valid_country($country)) { $country = 'None'; } $country = boinc_real_escape_string($country); // for Cote d'Ivoire $clause = sprintf( "(userid, create_time, name, name_lc, url, type, name_html, description, country, nusers, expavg_time) values(%d, %d, '%s', '%s', '%s', %d, '%s', '%s', '%s', %d, unix_timestamp())", $userid, time(), $name, $name_lc, $url, $type, $name_html, $description, $country, 0 ); $id = BoincTeam::insert($clause); if ($id) { return BoincTeam::lookup_id($id); } else { return null; } } $cvs_version_tracker[]="\$Id$"; //Generated automatically - do not edit ?>