Completed
Pull Request — master (#2472)
by Kevin
23:34 queued 05:01
created

html/inc/team.inc::user_erase_team_owner()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 3
nop 1
dl 0
loc 8
rs 9.2
c 0
b 0
f 0
1
<?php
2
// This file is part of BOINC.
3
// http://boinc.berkeley.edu
4
// Copyright (C) 2008 University of California
5
//
6
// BOINC is free software; you can redistribute it and/or modify it
7
// under the terms of the GNU Lesser General Public License
8
// as published by the Free Software Foundation,
9
// either version 3 of the License, or (at your option) any later version.
10
//
11
// BOINC is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
// See the GNU Lesser General Public License for more details.
15
//
16
// You should have received a copy of the GNU Lesser General Public License
17
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
18
19
require_once("../inc/util.inc");
20
require_once("../inc/boinc_db.inc");
21
require_once("../inc/forum_db.inc");
22
require_once("../inc/forum.inc");
23
require_once("../inc/sanitize_html.inc");
24
require_once("../inc/countries.inc");
25
require_once("../inc/credit.inc");
26
require_once("../inc/team_types.inc");
27
require_once("../inc/time.inc");
28
require_once("../inc/stats_sites.inc");
29
30
function team_search_form($params) {
31
    if (!$params) {
32
        $params = new StdClass;
33
        $params->keywords = "";
34
        $params->country = "";
35
        $params->type = "";
36
        $params->active = false;
37
    }
38
    echo '<form name="form" action="team_search.php">';
39
    start_table();
40
    row2('<b>'.tra('Search criteria (use one or more)').'</b>', '');
41
    row2(
42
        tra('Key words').'<br><small>'.tra('Find teams with these words in their names or descriptions').'</small>',
43
        '<input class="form-control" type="text" name="keywords" value="' . htmlspecialchars($params->keywords) . '">');
44
    row2_init(tra('Country'), '');
45
    echo '<select class="form-control" name="country"><option value="" selected>---</option>';
46
    $country = $params->country;
47
    if (!$country || $country == 'None') $country = "XXX";
48
    echo country_select_options($country);
49
    echo "</select></td></tr>\n";
50
    row2(tra('Type of team'), team_type_select($params->type, true));
51
    $checked = $params->active?"checked":"";
52
    row2(tra('Show only active teams'), "<input type=checkbox name=active $checked>");
53
    row2("", "<input class=\"btn btn-primary\" type=submit name=submit value=\"".tra('Search')."\">");
54
    end_table();
55
    echo '</form>';
56
}
57
58
function foundership_transfer_link($user, $team) {
59
    $now = time();
60
    if ($team->ping_user == $user->id) {
61
        if (transfer_ok($team, $now)) {
62
            return tra('Requested by you, and founder response deadline has passed.').'
63
                <br>
64
                <a href="team_founder_transfer_form.php">'.tra('Complete foundership transfer').'</a>.
65
            ';
66
        } else {
67
            $deadline = date_str(transfer_ok_time($team));
68
            return '<a href="team_founder_transfer_form.php">'.tra('Requested by you').'</a>; '.tra('founder response deadline is %1', $deadline);
69
        }
70
    }
71
    if (new_transfer_request_ok($team, $now)) {
72
        if ($team->userid == $user->id) {
73
            return tra('None');
74
        } else {
75
            return '<a href="team_founder_transfer_form.php">'.tra('Initiate request').'</a>';
76
        }
77
    }
78
    return '<a href="team_founder_transfer_form.php">'.tra('Deferred').'</a>';
79
}
80
81
// $team is the team record with a bunch of additional data
82
// (see team_display.php)
83
// $user is viewer (not necessarily team founder) or null
84
//
85
function display_team_page($team, $user) {
86
    global $team_name_sites;
87
    page_head("$team->name");
88
89
    echo sanitize_html($team->name_html);
90
    echo "<p>";
91
    start_table();
92
    row1(tra('Team info'));
93
    if (strlen($team->description)) {
94
        row2(tra('Description'), sanitize_html($team->description));
95
    }
96
    row2("Created", date_str($team->create_time));
97
    if (defined("SHOW_NONVALIDATED_TEAMS")) {
98
        $founder = $team->founder;
99
        row2("Founder email validated", $founder->email_validated?"Yes":"No (team will not be exported)");
100
    }
101
    if (strlen($team->url)) {;
102
        if (strstr($team->url, "http://")) {
103
            $x = $team->url;
104
        } else {
105
            $x = "http://$team->url";
106
        }
107
        row2(tra('Web site'), "<a href=$x>$x</a>");
108
    }
109
110 View Code Duplication
    if (!NO_STATS) {
111
        row2(tra('Total credit'), format_credit_large($team->total_credit));
112
        row2(tra('Recent average credit'), format_credit_large($team->expavg_credit));
113
        if (function_exists('project_team_credit')) {
114
            project_team_credit($team);
115
        }
116
    }
117
    show_badges_row(false, $team);
118
    if (!NO_STATS) {
119
        $x = "";
120
        shuffle($team_name_sites);
121
        foreach ($team_name_sites as $t) {
122
            $url = $t[0];
123
            $site_name = $t[1];
124
            $encoding = $t[2];
125
            if ($encoding == "hashlc") {
126
                $key = md5(strtolower($team->name));
127
            } else if ($encoding == 'hash') {
128
                $key = md5($team->name);
129
            } else {
130
                $key = urlencode($team->name);
131
            }
132
            $x .= "<a href=$url".$key.">$site_name</a><br>\n";
133
        }
134
        row2(tra('Cross-project stats'), $x);
135
    }
136
    row2(tra('Country'), $team->country);
137
    row2(tra('Type'), team_type_name($team->type));
138
139
    if ($team->forum && is_forum_visible_to_user($team->forum, $user)) {
140
        $f = $team->forum;
141
        row2('<a href="team_forum.php?teamid='.$team->id.'">'.tra('Message board').'</a>',
142
            tra('Threads').': '.$f->threads.'<br>'.tra('Posts').': '.$f->posts.'<br>'.tra('Last post').': '.time_diff_str($f->timestamp, time())
143
        );
144
    }
145
    if ($user) {
146
        if ($user->teamid != $team->id) {
147 View Code Duplication
            if ($team->joinable) {
148
                $tokens = url_tokens($user->authenticator);
149
                row2("",
150
                    '<a class="btn btn-success" href="team_join.php?'.$tokens.'&amp;teamid='.$team->id.'">'.tra('Join this team').'</a>
151
                    <br><p class=\"text-muted\">'.tra('Note: if \'OK to email\' is set in your project preferences, joining a team gives its founder access to your email address.').'</p>'
152
                );
153
            } else {
154
                row2(tra("Not accepting new members"), "");
155
            }
156
        }
157
        if (($user->teamid == $team->id)) {
158
            if (($user->id == $team->userid)) {
159
                if ($team->ping_user) {
160
                    $deadline = date_str(transfer_ok_time($team));
161
                    row2(tra('Foundership change requested'),
162
                        '<a href="team_change_founder_form.php?teamid='.$team->id.'">'.tra('Respond by %1', $deadline).'</a>'
163
                    );
164
                }
165
            } else {
166
                row2(tra('Team foundership change'), foundership_transfer_link($user, $team));
167
            }
168
        }
169
    }
170
    row1(tra('Members'));
171
    row2(tra('Founder'),
172
        $team->founder?user_links($team->founder, BADGE_HEIGHT_MEDIUM):"---"
173
    );
174
    if (count($team->admins)) {
175
        $first = true;
176
        $x = "";
177 View Code Duplication
        foreach ($team->admins as $a) {
178
            if ($first) {
179
                $first = false;
180
            } else {
181
                $x .= " &middot; ";
182
            }
183
            $x .= user_links($a, BADGE_HEIGHT_MEDIUM);
184
        }
185
        row2(tra('Admins'), $x);
186
    }
187
    $x = "0";
188
    if (count($team->new_members)) {
189
        $first = true;
190
        $x = "";
191 View Code Duplication
        foreach ($team->new_members as $a) {
192
            if ($first) {
193
                $first = false;
194
            } else {
195
                $x .= " &middot; ";
196
            }
197
            $x .= user_links($a, BADGE_HEIGHT_MEDIUM);
198
        }
199
    }
200
    row2(tra('New members in last day'), $x);
201
    row2(tra('Total members'), "$team->nusers (<a href=team_members.php?teamid=$team->id&amp;offset=0&amp;sort_by=expavg_credit>".tra('view')."</a>)");
202
    if (!NO_STATS) {
203
        row2(tra('Active members'), "$team->nusers_active (<a href=team_members.php?teamid=$team->id&amp;offset=0&amp;sort_by=expavg_credit>".tra('view')."</a>)");
204
        row2(tra('Members with credit'), "$team->nusers_worked (<a href=team_members.php?teamid=$team->id&amp;offset=0&amp;sort_by=total_credit>".tra('view')."</a>)");
205
    }
206
    end_table();
207
}
208
209
function display_team_members($team, $offset, $sort_by) {
210
    $n = 20;
211
212
    $admins = BoincTeamAdmin::enum("teamid=$team->id");
213
214
    // there aren't indices to support sorting by credit.
215
    // set the following variable to disable sorted output.
216
    // (though since caching is generally used this shouldn't be needed)
217
    //
218
    $nosort = false;
219
220
    if ($sort_by == "total_credit") {
221
        $sort_clause = "total_credit desc";
222
    } else {
223
        $sort_clause = "expavg_credit desc";
224
    }
225
226
    start_table();
227
    $x = array();
228
    $a = array();
229
    $x[] = tra('Name');
230
    $a[] = "";
231
    if (!NO_STATS) {
232
        if ($nosort) {
233
            $x[] = tra('Total credit');
234
            $x[] = tra('Recent average credit');
235
        } else {
236 View Code Duplication
            if ($sort_by == "total_credit") {
237
                $x[] = tra('Total credit');
238
            } else {
239
                $x[] = "<href=team_members.php?teamid=$team->id&amp;sort_by=total_credit&amp;offset=$offset>".tra('Total credit')."</a>";
240
            }
241 View Code Duplication
            if ($sort_by == "expavg_credit") {
242
                $x[] = tra('Recent average credit');
243
            } else {
244
                $x[] = "<href=team_members.php?teamid=$team->id&amp;sort_by=expavg_credit&amp;offset=$offset>".tra('Recent average credit').'</a>';
245
            }
246
        }
247
        $a[] = ALIGN_RIGHT;
248
        $a[] = ALIGN_RIGHT;
249
    }
250
251
    $x[] = tra('Country');
252
    $a[] = "";
253
    row_heading_array($x, $a);
254
    
255
    $cache_args = "teamid=".$team->id."&mosort=".$nosort."&order=".$sort_clause."&limit=".$offset."_".$n;
256
    $users = unserialize(get_cached_data(TEAM_PAGE_TTL, $cache_args));
257
    if (!$users) {
258
        if ($nosort) {
259
            $users = BoincUser::enum("teamid=$team->id limit $offset,$n");
260
        } else {
261
            $users = BoincUser::enum("teamid=$team->id order by $sort_clause limit $offset,$n");
262
        }
263
        set_cached_data(TEAM_PAGE_TTL, serialize($users), $cache_args);
264
    }
265
266
    $j = $offset + 1;
267
    foreach ($users as $user) {
268
        $user_total_credit = format_credit_large($user->total_credit);
269
        $user_expavg_credit = format_credit($user->expavg_credit);
270
        $x = user_links($user, BADGE_HEIGHT_MEDIUM);
271
        if ($user->id == $team->userid) {
272
            $x .= ' ['.tra('Founder').']';
273
        } else if (is_team_admin_aux($user, $admins)) {
274
            $x .= ' ['.tra('Admin').']';
275
        }
276
        echo "<tr class=row1>
277
            <td align=left>$j) $x
278
        </td>";
279
        if (!NO_STATS) {
280
            echo "
281
                <td align=right>$user_total_credit</td>
282
                <td align=right>$user_expavg_credit</td>
283
            ";
284
        }
285
        echo "
286
            <td>$user->country</td>
287
            </tr>
288
        ";
289
        $j++;
290
    }
291
    echo "</table>";
292
293
    if ($offset > 0) {
294
        $new_offset = $offset - $n;
295
        echo "<a href=team_members.php?teamid=$team->id&amp;sort_by=$sort_by&amp;offset=$new_offset>".tra('Previous %1', $n)."</a> &middot; ";
296
    }
297
    if ($j == $offset + $n + 1) {
298
        $new_offset = $offset + $n;
299
        echo "<a href=team_members.php?teamid=$team->id&amp;sort_by=$sort_by&amp;offset=$new_offset>".tra('Next %1', $n)."</a>";
300
    }
301
}
302
303
// check that the team exists
304
//
305
function require_team($team) {
306
    if (!$team) {
307
        error_page(tra('No such team.'));
308
    }
309
}
310
311
function is_team_founder($user, $team) {
312
    return $user->id == $team->userid;
313
}
314
315
// check that the user is founder of the team
316
//
317
function require_founder_login($user, $team) {
318
    require_team($team);
319
    if ($user->id != $team->userid) {
320
        error_page(tra('This operation requires foundership.'));
321
    }
322
}
323
324
function is_team_admin($user, $team) {
325
    if (!$user) return false;
326
    if ($user->id == $team->userid) return true;
327
    $admin = BoincTeamAdmin::lookup($team->id, $user->id);
328
    if ($admin) return true;
329
    return false;
330
}
331
332
// use this when you're displaying a long list of users
333
// and don't want to do a lookup for each one
334
//
335
function is_team_admin_aux($user, $admins) {
336
    foreach ($admins as $a) {
337
        if ($a->userid == $user->id) return true;
338
    }
339
    return false;
340
}
341
342
function require_admin($user, $team) {
343
    if (!is_team_admin($user, $team)) {
344
        error_page(tra('This operation requires team admin privileges'));
345
    }
346
}
347
348
function new_member_list($teamid) {
349
    $new_members = array();
350
    $yesterday = time() - 86400;
351
    $deltas = BoincTeamDelta::enum("teamid=$teamid and timestamp>$yesterday and joining=1 group by userid");
352
    if (count($deltas)) {
353
        foreach ($deltas as $delta) {
354
            $u = BoincUser::lookup_id($delta->userid);
355
            if ($u->teamid == $teamid) {
356
                $new_members[] = $u;  // they might have later quit
357
            }
358
        }
359
    }
360
    return $new_members;
361
}
362
363
function admin_list($teamid) {
364
    $u = array();
365
    $admins = BoincTeamAdmin::enum("teamid=$teamid");
366
    foreach ($admins as $admin) {
367
        $user = BoincUser::lookup_id($admin->userid);
368
        $u[] = $user;
369
    }
370
    return $u;
371
}
372
373
function team_table_start($sort_by, $type_url) {
374
    $x = array();
375
    $x[] = tra('Rank');
376
    $x[] = tra('Name');
377
    $x[] = tra('Members');
378
    $a = array("", "", ALIGN_RIGHT);
379
    if (!NO_STATS) {
380
        if ($sort_by == "total_credit") {
381
            $x[] = "<a href=top_teams.php?sort_by=expavg_credit".$type_url.">".tra('Recent average credit')."</a>";
382
            $x[] = tra('Total credit');
383
        } else {
384
            $x[] = tra('Recent average credit');
385
            $x[] = "<a href=top_teams.php?sort_by=total_credit".$type_url.">".tra('Total credit')."</a>";
386
        }
387
        $a[] = ALIGN_RIGHT;
388
        $a[] = ALIGN_RIGHT;
389
    }
390
    $x[] = tra('Country');
391
    $x[] = tra("Type");
392
    $a[] = "";
393
    $a[] = "";
394
395
    row_heading_array($x, $a);
396
}
397
398
function team_links($team) {
399
    $b = badges_string(false, $team, BADGE_HEIGHT_MEDIUM);
400
    return "<a href=team_display.php?teamid=$team->id>$team->name</a> $b";
401
}
402
403
function show_team_row($team, $i) {
404
    $team_expavg_credit = format_credit_large($team->expavg_credit);
405
    $team_total_credit = format_credit_large($team->total_credit);
406
    echo "<tr>
407
        <td>$i</td>
408
        <td>".team_links($team)."</td>
409
        <td align=right>".$team->nusers."</td>
410
    ";
411
    if (!NO_STATS) {
412
        echo "
413
            <td align=right>$team_expavg_credit</td>
414
            <td align=right>$team_total_credit</td>
415
        ";
416
    }
417
    echo "
418
        <td>$team->country</td>
419
        <td>".team_type_name($team->type)."</td>
420
        </tr>
421
    ";
422
}
423
424
function user_join_team($team, $user) {
425
    user_quit_team($user);
426
    $res = $user->update("teamid=$team->id");
427
    if ($res) {
428
        $now = time();
429
        BoincTeamDelta::insert("(userid, teamid, timestamp, joining, total_credit) values ($user->id, $team->id, $now, 1, $user->total_credit)");
430
        return true;
431
    }
432
    return false;
433
}
434
435
function user_quit_team($user) {
436
    if (!$user->teamid) return;
437
    $user->update("teamid=0");
438
    $team = BoincTeam::lookup_id($user->teamid);
439
    if ($team && $team->ping_user==$user->id) {
440
        $team->update("ping_user=-ping_user");
441
    }
442
    BoincTeamAdmin::delete("teamid=$user->teamid and userid=$user->id");
443
    $now = time();
444
    BoincTeamDelta::insert("(userid, teamid, timestamp, joining, total_credit) values ($user->id, $user->teamid, $now, 0, $user->total_credit)");
445
}
446
447
function user_erase_team_owner($user) {
448
    if ($user->teamid) {
449
        $team = BoincTeam::lookup_id($user->teamid);
450
        if ($team && $team.userid == $user->id) {
451
            $team->update("userid=0");
452
        }
453
    }
454
}
455
456
function user_erase_team_delta($user) {
457
    BoincTeamDelta::delete_for_user($user->id);
458
}
459
460
function team_edit_form($team, $label, $url) {
461
    global $team_types, $recaptcha_public_key;
462
    echo "<form method=post action=$url>\n";
463
    if ($team) {
464
        echo "<input type=hidden name=teamid value=$team->id>\n";
465
        if ($team->seti_id) {
466
            echo "<p class=\"text-danger\">".tra("WARNING: this is a BOINC-wide team. If you make changes here, they will soon be overwritten. Edit the %1 BOINC-wide team %2 instead.", "<a href=https://boinc.berkeley.edu/teams/>", "</a>")
467
            ."</p>";
468
        }
469
    }
470
    echo '
471
        <p>
472
        '.tra('%1 Privacy note %2: if you create a team, your project preferences (resource share, graphics preferences) will be visible to the public.', '<b>', '</b>').'
473
        <p>
474
    ';
475
    start_table();
476
    row2(tra('Team name, text version').'
477
        <br><p class=\"text-muted\">'.tra('Don\'t use HTML tags.').'</p>',
478
        '<input class="form-control" name="name" type="text" size="50" value="'.($team?$team->name:"").'">'
479
    );
480
    row2(tra('Team name, HTML version').'
481
        <br><p class=\"text-muted\">
482
        '.tra('You may use %1 limited HTML tags %2.', '<a href="html.php" target="_new">', '</a>').'
483
        '.tra('If you don\'t know HTML, leave this box blank.').'</p>',
484
        '<input class="form-control" name="name_html" type="text" size="50" value="'.str_replace('"',"'",($team?$team->name_html:"")).'">'
485
    );
486
    row2(tra('URL of team web page, if any').':<br><font size=-2>('.tra('without "http://"').')
487
        '.tra('This URL will be linked to from the team\'s page on this site.'),
488
        '<input class="form-control" type="text" name="url" size="60" value="'.($team?$team->url:"").'">'
489
    );
490
    row2(tra('Description of team').':
491
        <br><p class=\"text-muted\">
492
        '.tra('You may use %1 limited HTML tags %2.', '<a href="html.php" target="_new">', '</a>').'
493
        </p>',
494
        '<textarea class="form-control" name="description" rows=10>'.($team?$team->description:"").'</textarea>'
495
    );
496
497
    row2(tra('Type of team').':', team_type_select($team?$team->type:null));
498
499
    row2_init(tra('Country'),
500
        '<select class="form-control" name="country">'
501
    );
502
    echo country_select_options($team?$team->country:null);
503
504
    echo "</select></td></tr>\n";
505
    $x = (!$team || $team->joinable)?"checked":"";
506
    row2(tra("Accept new members?"), "<input type=checkbox name=joinable $x>");
507
    // Check if we're using reCaptcha to prevent spam accounts
508
    //
509
    if (!$team && $recaptcha_public_key) {
510
        row2(
511
            "",
512
            boinc_recaptcha_get_html($recaptcha_public_key)
513
        );
514
    }
515
    row2("",
516
        "<input class=\"btn btn-success\" type=submit name=new value='$label'>"
517
    );
518
    end_table();
519
    echo "</form>\n";
520
}
521
522
// decay a team's average credit
523
//
524 View Code Duplication
function team_decay_credit($team) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
525
    $avg = $team->expavg_credit;
526
    $avg_time = $team->expavg_time;
527
    $now = time(0);
528
    update_average($now, 0, 0, $avg, $avg_time);
529
    $team->update("expavg_credit=$avg, expavg_time=$now");
530
531
}
532
// if the team hasn't received new credit for ndays,
533
// decay its average and return true
534
//
535
function team_inactive_ndays($team, $ndays) {
536
    $diff = time() - $team->expavg_time;
537
    if ($diff > $ndays*86400) {
538
        team_decay_credit($team);
539
        return true;
540
    }
541
    return false;
542
}
543
544
function team_count_members($teamid) {
545
    return BoincUser::count("teamid=$teamid");
546
}
547
548
// These functions determine the rules for foundership transfer, namely:
549
// - A transfer request is allowed if either:
550
//   - there is no active request, and it's been at least 60 days
551
//     since the last request (this protects the founder from
552
//     being bombarded with frequest requests)
553
//   - there's an active request older than 90 days
554
//     (this lets a 2nd requester eventually get a chance)
555
// - Suppose someone (X) requests foundership at time T.
556
//   An email is sent to the founder (Y).
557
//   The request is "active" (ping_user is set to X's ID)
558
// - If Y declines the change, an email is sent to X,
559
//   and the request is cleared.
560
// - If Y accepts the change, an email is sent to X
561
//   and the request is cleared.
562
// - After T + 60 days, X can become founder
563
// - After T + 90 days, new requests are allowed even if there's
564
//   an active request, i.e. after the 60 days elapse X has another
565
//   30 days to assume foundership before someone elase can request it
566
//
567
function new_transfer_request_ok($team, $now) {
568 View Code Duplication
    if ($team->ping_user <= 0) {
569
        if ($team->ping_time < $now - 60 * 86400) {
570
            return true;
571
        }
572
        return false;
573
    }
574
    if ($team->ping_time < $now - 90 * 86400) {
575
        return true;
576
    }
577
    return false;
578
}
579
580
// the time at which we can actually change foundership
581
// if the founder hasn't responded
582
//
583
function transfer_ok_time($team) {
584
    return $team->ping_time + 60*86400;
585
}
586
587
function transfer_ok($team, $now) {
588
    if ($now > transfer_ok_time($team)) return true;
589
    return false;
590
}
591
592
// Make a team; args are untrusted, so cleanse and validate them
593
//
594
function make_team(
595
    $userid, $name, $url, $type, $name_html, $description, $country
596
) {
597
    $name = BoincDb::escape_string(sanitize_tags($name));
598
    if (strlen($name) == 0) return null;
599
    $name_lc = strtolower($name);
600
    $url = BoincDb::escape_string(sanitize_tags($url));
601
    if (strstr($url, "http://")) {
602
        $url = substr($url, 7);
603
    }
604
    $name_html = BoincDb::escape_string($name_html);
605
    $description = BoincDb::escape_string($description);
606
    if (!is_valid_country($country)) {
607
        $country = tra('None');
608
    }
609
    $country = BoincDb::escape_string($country);  // for Cote d'Ivoire
610
611
    $clause = sprintf(
612
        "(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())",
613
        $userid,
614
        time(),
615
        $name,
616
        $name_lc,
617
        $url,
618
        $type,
619
        $name_html,
620
        $description,
621
        $country,
622
        0
623
    );
624
    $id = BoincTeam::insert($clause);
625
    if ($id) {
626
        return BoincTeam::lookup_id($id);
627
    } else {
628
        return null;
629
    }
630
}
631
632
$cvs_version_tracker[]="\$Id$";  //Generated automatically - do not edit
633
634
?>
635