SqlQueryString::get_select_query()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 2
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
// This file is part of BOINC.
3
// http://boinc.berkeley.edu
4
// Copyright (C) 2017 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
// functions to query various entities, and display them,
20
// in admin web pages
21
// TODO: most of this code shouldn't exist;
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
22
// use the standard code for displaying WUs etc. instead
23
24
require_once("../inc/util_basic.inc");
25
require_once("../inc/util_ops.inc");
26
require_once("../inc/result.inc");
27
require_once("../inc/boinc_db.inc");
28
29
class BoincAssignment {
30
    static function enum($where_clause = null) {
31
        $db = BoincDb::get();
32
        return $db->enum('assignment', 'BoincAssignment', $where_clause);
33
    }
34
}
35
36
define("NVALIDATE_STATES", 6);
37
38
// Converts a mysql timestamp to a user readable form
39
// NOTE: the result will say UTC but it's actually local time.
40
// Should fix at some point.
41
//
42
function mysqltime_str($x) {
43
    if(strpos($x,"-")==4) {
44
        // Syntax of supplied mysql-timestamp is YYYY-MM-DD HH:MM:SS
45
        $year = substr($x,0,4);
46
        $month = substr($x,5,2);
47
        $day = substr($x,8,2);
48
        $hour = substr($x,11,2);
49
        $minute = substr($x,14,2);
50
        $second = substr($x,17,2);
51
    } else {
52
        // Syntax of supplied mysql-timestamp is YYYYMMDDHHMMSS
53
        $year = substr($x,0,4);
54
        $month = substr($x,4,2);
55
        $day = substr($x,6,2);
56
        $hour = substr($x,8,2);
57
        $minute = substr($x,10,2);
58
        $second = substr($x,12,2);
59
60
    }
61
    $time = mktime($hour, $minute, $second, $month, $day, $year);
0 ignored issues
show
Bug introduced by
$hour of type string is incompatible with the type integer expected by parameter $hour of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
    $time = mktime(/** @scrutinizer ignore-type */ $hour, $minute, $second, $month, $day, $year);
Loading history...
Bug introduced by
$minute of type string is incompatible with the type integer expected by parameter $minute of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
    $time = mktime($hour, /** @scrutinizer ignore-type */ $minute, $second, $month, $day, $year);
Loading history...
Bug introduced by
$second of type string is incompatible with the type integer expected by parameter $second of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
    $time = mktime($hour, $minute, /** @scrutinizer ignore-type */ $second, $month, $day, $year);
Loading history...
Bug introduced by
$day of type string is incompatible with the type integer expected by parameter $day of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
    $time = mktime($hour, $minute, $second, $month, /** @scrutinizer ignore-type */ $day, $year);
Loading history...
Bug introduced by
$month of type string is incompatible with the type integer expected by parameter $month of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
    $time = mktime($hour, $minute, $second, /** @scrutinizer ignore-type */ $month, $day, $year);
Loading history...
Bug introduced by
$year of type string is incompatible with the type integer expected by parameter $year of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
    $time = mktime($hour, $minute, $second, $month, $day, /** @scrutinizer ignore-type */ $year);
Loading history...
62
    return time_str($time);
63
}
64
65
// translate type_id into human readable text
66
// http://php.net/manual/de/mysqli-result.fetch-field-direct.php
67
//
68
function mysql_fieldtype_str($type_id) {
69
    static $types;
70
    // maps php constants to mysql type names
71
    static $mysql_data_type_hash = array(
72
        MYSQLI_TYPE_TINY=>'tinyint',
73
        MYSQLI_TYPE_SHORT=>'smallint',
74
        MYSQLI_TYPE_LONG=>'int',
75
        MYSQLI_TYPE_FLOAT=>'float',
76
        MYSQLI_TYPE_DOUBLE=>'double',
77
        MYSQLI_TYPE_TIMESTAMP=>'timestamp',
78
        MYSQLI_TYPE_LONGLONG=>'bigint',
79
        MYSQLI_TYPE_INT24=>'mediumint',
80
        MYSQLI_TYPE_DATE=>'date',
81
        MYSQLI_TYPE_TIME=>'time',
82
        MYSQLI_TYPE_DATETIME=>'datetime',
83
        MYSQLI_TYPE_YEAR=>'year',
84
        MYSQLI_TYPE_BIT=>'bit',
85
        MYSQLI_TYPE_BLOB=>'blob',
86
        MYSQLI_TYPE_VAR_STRING=>'varchar',
87
        MYSQLI_TYPE_STRING=>'char',
88
        MYSQLI_TYPE_DECIMAL=>'decimal'
89
    );
90
    if (array_key_exists($type_id, $mysql_data_type_hash)) {
91
        return $mysql_data_type_hash[$type_id];
92
    }
93
    // $type_id is not well known or new so get the constant name and return that
94
    if (!isset($types)) {
95
        $types = array();
96
        $constants = get_defined_constants(true);
97
        foreach ($constants['mysqli'] as $c => $n) {
98
            if (preg_match('/^MYSQLI_TYPE_(.*)/', $c, $m)) $types[$n] = $m[1];
99
        }
100
    }
101
    return array_key_exists($type_id, $types)? strtolower($types[$type_id]) : "unknown";
102
}
103
104
// print a description of $table
105
//
106
function print_describe_table_onecol($table, $which, $columns) {
107
    $db = BoincDb::get(true);
108
    $result = $db->do_query("SELECT * from $table LIMIT 1");
109
    $fields = $result->field_count;
110
111
    $avgnum=(int)($fields/$columns);
112
    if ($avgnum*$columns<$fields) {
113
        $avgnum++;
114
    }
115
116
    $actualcolumns=0;
117
    while ($avgnum*$actualcolumns<$fields) {
118
        $actualcolumns++;
119
    }
120
121
    if ($which>$actualcolumns) {
122
        return 0;
123
    }
124
125
    $bot=($which-1)*$avgnum;
126
    $top=$which*$avgnum;
127
128
    $width=100.0/$actualcolumns;
129
130
    echo "<td>";
131
    start_table('table-striped');
132
    echo "<tr><th align=\"left\">NAME</th><th align=\"left\">Type</th><th align=\"left\">Bytes</th>\n";
133
    for ($count=$bot; $count<$top; $count++) {
134
        if ($count<$fields) {
135
            $x = $result->fetch_field_direct($count);
136
            $name = $x->name;
137
            $type = mysql_fieldtype_str($x->type);
138
            $length = $x->length;
139
        } else {
140
            $name="<br/> ";
141
            $type="<br/>";
142
            $length="<br/>";
143
        }
144
        echo "\t<tr><td><b>$name</b></td><td>$type</td><td>$length</td></tr>\n";
145
    }
146
    end_table();
147
    echo "</td>";
148
    $result->free();
149
    return 0;
150
}
151
152
function print_describe_table($table, $how_many_columns) {
153
    // Number of columns for showing table description
154
    echo "<h2>Description of <b>$table</b> table fields:</h2>\n";
155
    start_table();
156
    echo "<tr>";
157
    for ($i=1; $i<=$how_many_columns; $i++) {
158
        print_describe_table_onecol($table, $i, $how_many_columns);
159
    }
160
    echo "</tr>";
161
    end_table();
162
    return 0;
163
}
164
165
function print_detail_field() {
166
    echo "<tr><td align=\"right\">Detail level</td><td>";
167
    echo "<select name=\"detail\">
168
        <option value=\"low\">low
169
        <option value=\"high\">high
170
        </select>
171
        </td></tr>
172
    ";
173
}
174
175
function print_query_field() {
176
    $currenttime=time();
177
    $hourago=$currenttime-3600;
178
    $dayago=$currenttime-24*3600;
179
    $weekago=$currenttime-7*24*3600;
180
    echo "
181
        <tr>
182
        <td align=\"right\">Additional clauses</td>
183
        <td><input name=\"clauses\" size=\"100\"></td>
184
        </tr><tr>
185
        <td align=\"right\">Unix times</td>
186
        <td>Now:<b> $currenttime</b> Hour ago: $hourago Day ago: $dayago Week ago: $weekago</td>
187
        </tr>
188
    ";
189
}
190
191
function join_query_string($s1, $s2) {
192
    if ($s1) {
193
        if ($s2) {
194
            return "$s1&s2";
195
        } else {
196
            return $s1;
197
        }
198
    } else {
199
        return $s2;
200
    }
201
}
202
203
function append_sql_query($original,$addition,$first) {
204
    if ($first == 1) {
205
        return $original . " where " . $addition;
206
    } else {
207
        return $original . " and " . $addition;
208
    }
209
}
210
211
// SqlQueryString maps a bunch of form items to a SQL query
212
//
213
// The items are
214
// table        (name of table)
215
// id
216
// platformid
217
// appid
218
// workunitid
219
// hostid
220
// userid
221
// teamid
222
// nsecs            (modified_time > now - nsecs)
223
// received_time    (> x)
224
// server_state     (== x if z nonzero)
225
// outcome          (== x if z nonzero)
226
// client_state     (== x if z nonzero)
227
// exit_status      (== x if z nonzero)
228
// clauses          (literals added after the above)
229
// sort_by          (order by x desc added after all else)
230
//
231
// Once you've parsed the items (using parse_form_items()):
232
//
233
// get_select_query(n, m) returns the SQL query to get items from m to m+n
234
// get_url() returns the URL-encoded version of everything
235
// count() returns the number of records satisfying the query
236
237
class SqlQueryString {
238
    var $table;
239
    var $query;
240
    var $urlquery;
241
242
    function __construct() {
243
        if (isset($_GET['table'])) {
244
            $this->table = $_GET['table'];
245
        } else {
246
            $this->table = "";
247
        }
248
        $this->query = "";
249
        $this->urlquery = "";
250
    }
251
    function add($clause) {
252
        //$clause=boinc_real_escape_string($clause);
253
        if (!$this->query) {
254
            $this->query .= "where $clause";
255
        } else {
256
            $this->query .= " and $clause";
257
        }
258
    }
259
    function addclause($clause) {
260
        if ($clause) {
261
            $c = urldecode($clause);
262
            $this->add("( $c )");
263
            $clause = urlencode($clause);
264
            $this->urlquery .= "&clauses=$clause";
265
        }
266
    }
267
    function addeq($name) {
268
        if (isset($_GET[$name])) {
269
            $value = $_GET[$name];
270
        } else {
271
            $value = "";
272
        }
273
        if (strlen($value)) {
274
            $this->add("$name = '$value'");
275
            $this->urlquery .= "&$name=".urlencode($value);
276
        }
277
    }
278
    function addeq_not_CHOOSE_ALL($name) {
279
        if (isset($_GET[$name])) {
280
            $value = $_GET[$name];
281
        } else {
282
            $value = "";
283
        }
284
        // On the selection menu, the ALL selection criteria sets (for example)
285
        // outcome=='CHOOSE_ALL' rather than a numeric value.
286
        // This means that we enter no condition for this case.
287
        //
288
        if (strlen($value) && strcmp("CHOOSE_ALL", $value)) {
289
            $this->add("$name = '$value'");
290
            $this->urlquery .= "&$name=".urlencode($value);
291
        }
292
    }
293
    function addgt($name) {
294
        if (isset($_GET[$name])) {
295
            $value = $_GET[$name];
296
        } else {
297
            $value = '';
298
        }
299
        if (strlen($value) && $value > 0) {
300
            $this->add("$name > '$value'");
301
            $this->urlquery .= "&$name=".urlencode($value);
302
        }
303
    }
304
    function addsort($name, $order) {
305
        if (isset($_GET[$name])) {
306
            $value = $_GET[$name];
307
        } else {
308
            $value=null;
309
        }
310
        if (isset($_GET[$order])) {
311
             $order = $_GET[$order];
312
        } else {
313
             $order = null;
314
        }
315
        if ($value) {
316
            if ($order == 'asc') {
317
                $this->query .= " order by $value asc";
318
                $this->urlquery .= "&sort_by_order=".urlencode($order);
319
            } else {
320
                $this->query .= " order by $value desc";
321
                $this->urlquery .= "&$name=".urlencode($value);
322
            }
323
        }
324
    }
325
326
    function count() {
327
        $count_query = "select count(*) as cnt from $this->table $this->query";
328
        $db = BoincDb::get(true);
329
        $result = $db->do_query($count_query);
330
        if (!$result) return 0;
331
        $res = $result->fetch_object();
332
        $result->free();
333
        return $res->cnt;
334
    }
335
336
    function get_select_query($entries_to_show, $start_at) {
337
        if ($entries_to_show) {
338
            if ($start_at) {
339
                return "select * from $this->table $this->query limit $start_at,$entries_to_show";
340
            } else {
341
                return "select * from $this->table $this->query limit $entries_to_show";
342
            }
343
        } else {
344
            return "select * from $this->table $this->query";
345
        }
346
    }
347
348
    function get_url($base = "db_action.php") {
349
        $s = $base . "?table=$this->table$this->urlquery";
350
        return $s;
351
    }
352
353
    function process_form_items() {
354
        $this->addeq('id');
355
        $this->addeq('platformid');
356
        $this->addeq('appid');
357
        $this->addeq('workunitid');
358
        $this->addeq('hostid');
359
        $this->addeq('userid');
360
        $this->addeq('teamid');
361
        $this->addeq('app_version_id');
362
        $this->addeq('exit_status');
363
        if (isset($_GET['nsecs'])) {
364
            $_GET['mod_time'] = date("YmdHis",time() - $_GET['nsecs']);
365
        }
366
        $this->addgt('mod_time');
367
        $this->addeq_not_CHOOSE_ALL('server_state');
368
        $this->addeq_not_CHOOSE_ALL('outcome');
369
        $this->addeq_not_CHOOSE_ALL('client_state');
370
        $this->addeq_not_CHOOSE_ALL('validate_state');
371
        $clauses = get_str("clauses", true);
372
        if ($clauses && strstr($clauses, ";")) error_page("bad clause");
373
        if ($clauses) {
374
            $this->addclause($clauses);
375
        }
376
        $this->addsort('sort_by', 'sort_by_order');
377
    }
378
}
379
380
381
function link_results($n, $mq, $query, $clauses) {
382
    if ($n == '0') { // intentional compare by string
383
        return "0";
384
    } else {
385
        if(strlen($clauses)) {
386
            return "<a href=\"db_action.php?table=result&query=$mq&$query&clauses=".urlencode($clauses)."&sort_by=mod_time&detail=low\">$n</a>";
387
        } else {
388
            return "<a href=\"db_action.php?table=result&query=$mq&$query&sort_by=mod_time&detail=low\">$n</a>";
389
        }
390
391
    }
392
}
393
394
// Determines if stderr_out is an error reported and prints as human readable String
395
// @return String A human readable string if error otherwise FALSE
396
// @param String $stderr_out the stderr_out value to parse
397
//
398
function stderr_error_string($stderr_out){
399
    $y = parse_element($stderr_out, "<error_code>");
400
    $x = 0;
401
    if ($y) {
402
        $x = (int)$y;
403
    }
404
    if (0<=$x && $x<=9) {
405
        return FALSE;
406
    } else {
407
        return "$x ".error_code_str($x);
408
    }
409
}
410
411
function admin_show_result_summary() {
412
    $ntotal =0;     // TODO: how to count $result?
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
413
    $nvalid = 0;    // for SUCCESS results
414
    $ninvalid = 0;
415
    $nfile_deleted = 0;
416
417
    $server_state = array();
418
    $outcome = array();
419
    $client_state = array();
420
421
    for ($ss=1; $ss<6; $ss++) {
422
        $server_state[$ss] = 0;
423
    }
424
    for ($ro=0; $ro<8; $ro++) {
425
        $outcome[$ro] = 0;
426
    }
427
    for ($cs=1; $cs<7; $cs++) {
428
        $client_state[$cs] = 0;
429
    }
430
    for ($fds=0; $fds<4; $fds++) {
431
        $delete_state[$fds] = 0;
432
    }
433
    for ($vs=0; $vs<NVALIDATE_STATES; $vs++) {
434
        $validate_state[$vs]=0;
435
    }
436
437
    $_GET['table'] = 'result';
438
    $_GET['sort_by'] = ''; // ignore sort
439
440
    if (isset($_GET['appid'])) {
441
        $query_appid = $_GET['appid'];
442
    } else {
443
        $query_appid = "";
444
    }
445
    $query_mod_time = 0;
446
    if (isset($_GET['nsecs'])) {
447
        //$query_mod_time = time() - $_GET['nsecs'];
448
        $query_mod_time = $_GET['nsecs'];
449
    }
450
    if (isset($_GET['workunitid'])) {
451
        $query_wuid = $_GET['workunitid'];
452
    } else {
453
        $query_wuid = null;
454
    }
455
    $q = new SqlQueryString();
456
    $q->process_form_items();
457
458
// Important: these need to be kept consistent with db/boinc_db.h and lib/result_state.h
459
    $main_query = "
460
SELECT COUNT(id) AS nTotal,
461
       SUM(case when server_state = '1' then 1 else 0 end) AS serverstate_inactive,
462
       SUM(case when server_state = '2' then 1 else 0 end) AS serverstate_unset,
463
       SUM(case when server_state = '3' then 1 else 0 end) AS serverstate_unset_seq,
464
       SUM(case when server_state = '4' then 1 else 0 end) AS serverstate_inprogress,
465
       SUM(case when server_state = '5' then 1 else 0 end) AS serverstate_over,
466
       SUM(case when server_state = '5' and outcome = '0' then 1 else 0 end) AS outcome_init,
467
       SUM(case when server_state = '5' and outcome = '1' then 1 else 0 end) AS outcome_success,
468
       SUM(case when server_state = '5' and outcome = '2' then 1 else 0 end) AS outcome_couldntsend,
469
       SUM(case when server_state = '5' and outcome = '3' then 1 else 0 end) AS outcome_failure,
470
       SUM(case when server_state = '5' and outcome = '4' then 1 else 0 end) AS outcome_noreply,
471
       SUM(case when server_state = '5' and outcome = '5' then 1 else 0 end) AS outcome_didntneed,
472
       SUM(case when server_state = '5' and outcome = '6' then 1 else 0 end) AS outcome_validateerror,
473
       SUM(case when server_state = '5' and outcome = '7' then 1 else 0 end) AS outcome_clientdetached,
474
       SUM(case when server_state = '5' and outcome = '1' and validate_state = '0' then 1 else 0 end) AS validate_init,
475
       SUM(case when server_state = '5' and outcome = '1' and validate_state = '1' then 1 else 0 end) AS validate_valid,
476
       SUM(case when server_state = '5' and outcome = '1' and validate_state = '2' then 1 else 0 end) AS validate_invalid,
477
       SUM(case when server_state = '5' and outcome = '1' and validate_state = '3' then 1 else 0 end) AS validate_nocheck,
478
       SUM(case when server_state = '5' and outcome = '1' and validate_state = '4' then 1 else 0 end) AS validate_inconclusive,
479
       SUM(case when server_state = '5' and outcome = '1' and validate_state = '5' then 1 else 0 end) AS validate_too_late,
480
       SUM(case when server_state = '5' and outcome = '1' and file_delete_state = '0' then 1 else 0 end) AS filedeletestate_init,
481
       SUM(case when server_state = '5' and outcome = '1' and file_delete_state = '1' then 1 else 0 end) AS filedeletestate_ready,
482
       SUM(case when server_state = '5' and outcome = '1' and file_delete_state = '2' then 1 else 0 end) AS filedeletestate_done,
483
       SUM(case when server_state = '5' and outcome = '1' and file_delete_state = '3' then 1 else 0 end) AS filedeletestate_error,
484
       SUM(case when server_state = '5' and outcome = '3' and client_state = '0' then 1 else 0 end) AS clientstate_init,
485
       SUM(case when server_state = '5' and outcome = '3' and client_state = '1' then 1 else 0 end) AS clientstate_downloading,
486
       SUM(case when server_state = '5' and outcome = '3' and client_state = '2' then 1 else 0 end) AS clientstate_downloaded,
487
       SUM(case when server_state = '5' and outcome = '3' and client_state = '3' then 1 else 0 end) AS clientstate_computedone,
488
       SUM(case when server_state = '5' and outcome = '3' and client_state = '4' then 1 else 0 end) AS clientstate_uploading,
489
       SUM(case when server_state = '5' and outcome = '3' and client_state = '5' then 1 else 0 end) AS clientstate_uploaded,
490
       SUM(case when server_state = '5' and outcome = '3' and client_state = '6' then 1 else 0 end) AS clientstate_aborted
491
FROM result WHERE true
492
    ";
493
494
    if ($query_appid) {
495
        $main_query .= " and appid=$query_appid";
496
    }
497
    if ($query_wuid) {
498
        $main_query .= " and workunitid=$query_wuid";
499
    }
500
    if ($query_mod_time) {
501
        $start = time() - $query_mod_time;
502
503
        // If file deletion is delayed by X,
504
        // subtract X from mod time of  file-deleted results.
505
        // Otherwise we'll show lots of irrelevant results
506
        //
507
        $delay = parse_config(get_config(), "<delete_delay_hours>");
508
        if ($delay) {
509
            $start2 = $start - $delay*3600;;
510
            $main_query .= " and ((file_delete_state>1 and mod_time>FROM_UNIXTIME($start2)) or (mod_time>FROM_UNIXTIME($start)))";
511
        } else {
512
            $main_query .= " and mod_time > FROM_UNIXTIME($start)";
513
        }
514
    }
515
516
    $urlquery = $q->urlquery;
517
    $db = BoincDb::get(true);
518
    $result = $db->do_query($main_query);
519
520
    // echo "Main query was $main_query<br/>";
521
522
    if ($result) {
523
524
        $res = $result->fetch_object();
525
        $ntotal          = $res->nTotal;
526
527
        $server_state[1] = $res->serverstate_inactive;
528
        $server_state[2] = $res->serverstate_unset;
529
        $server_state[3] = $res->serverstate_unset_seq;
530
        $server_state[4] = $res->serverstate_inprogress;
531
        $server_state[5] = $res->serverstate_over;
532
533
        $outcome[0]      = $res->outcome_init;
534
        $outcome[1]      = $res->outcome_success;
535
        $outcome[2]      = $res->outcome_couldntsend;
536
        $outcome[3]      = $res->outcome_failure;
537
        $outcome[4]      = $res->outcome_noreply;
538
        $outcome[5]      = $res->outcome_didntneed;
539
        $outcome[6]      = $res->outcome_validateerror;
540
        $outcome[7]      = $res->outcome_clientdetached;
541
542
        $client_state[1] = $res->clientstate_downloading;
543
        $client_state[2] = $res->clientstate_downloaded;
544
        $client_state[3] = $res->clientstate_computedone;
545
        $client_state[4] = $res->clientstate_uploading;
546
        $client_state[5] = $res->clientstate_uploaded;
547
        $client_state[6] = $res->clientstate_aborted;
548
549
        $validate_state[0] = $res->validate_init;
550
        $validate_state[1] = $res->validate_valid;
551
        $validate_state[2] = $res->validate_invalid;
552
        $validate_state[3] = $res->validate_nocheck;
553
        $validate_state[4] = $res->validate_inconclusive;
554
        $validate_state[5] = $res->validate_too_late;
555
556
        $file_delete[0]  = $res->filedeletestate_init;
557
        $file_delete[1]  = $res->filedeletestate_ready;
558
        $file_delete[2]  = $res->filedeletestate_done;
559
        $file_delete[3]  = $res->filedeletestate_error;
560
561
        $nfile_deleted   = $res->filedeletestate_ready + $res->filedeletestate_done + $res->filedeletestate_error;
562
        $result->free();
563
    }
564
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
565
566
    start_table();
567
    echo "<tr valign=\"top\">";
568
    echo "<td><h2>" . link_results("$ntotal results", $urlquery, '', '') . "</h2></td>";
569
    echo "<td><h2>" . link_results("'Over' results", $urlquery, sprintf('server_state=%d', RESULT_SERVER_STATE_OVER), '') . "</h2></td>";
570
    echo "<td><h2>" . link_results("'Success' results", $urlquery, sprintf('outcome=%d', RESULT_OUTCOME_SUCCESS), '') . "</h2></td>";
571
    echo "<td><h2>" . link_results("'Client error' results", $urlquery, sprintf('outcome=%d', RESULT_OUTCOME_CLIENT_ERROR), '') . "</h2></td>";
572
    echo "</tr>";
573
    echo "<tr valign=\"top\">";
574
    echo "<td>";
575
    start_table('table-striped');
576
    echo "<tr><th>Server state</th><th># results</th></tr>\n";
577
    for ($ss=1; $ss<6; $ss++) {
578
        $res = new StdClass;
579
        $res->server_state = $ss;
580
        row2(result_server_state_string($res),
581
            link_results(
582
                "$server_state[$ss]",  $urlquery, "server_state=$ss", ''
583
            )
584
        );
585
    }
586
    end_table();
587
    echo "</td>";
588
589
    echo "<td>";
590
    start_table('table-striped');
591
    echo "<tr><th>Outcome</th><th># results</th></tr>\n";
592
593
    for ($ro=0; $ro<8; $ro++) {
594
        $res = new StdClass;
595
        $res->outcome = $ro;
596
        $res->exit_status = 0;
597
        c_row2(
598
            $outcome[$ro]?outcome_color($ro):'',
599
            result_outcome_string($res),
600
            link_results("$outcome[$ro]", $urlquery, "outcome=$ro", '')
601
        );
602
    }
603
    end_table();
604
    echo "</td>";
605
606
    echo "<td>";
607
    start_table('table-striped');
608
    echo "<tr><th>Validate state</th><th># results</th></tr>\n";
609
    for ($vs=0; $vs<NVALIDATE_STATES; $vs++) {
610
        $res = new StdClass;
611
        $res->validate_state = $vs;
612
        $res->exit_status = 0;
613
        c_row2(
614
            $validate_state[$vs]?validate_color($vs):'',
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $validate_state does not seem to be defined for all execution paths leading up to this point.
Loading history...
615
            validate_state_str($res),
616
            link_results(
617
                "$validate_state[$vs]",
618
                $urlquery,
619
                "validate_state=$vs",
620
                sprintf('outcome=%d', RESULT_OUTCOME_SUCCESS)
621
            )
622
        );
623
    }
624
    end_table();
625
    start_table('table-striped');
626
    echo "<tr><th>File Delete state</th><th># results</th></tr>\n";
627
628
    for ($fds=0; $fds<4; $fds++) {
629
        row2(
630
            file_delete_state_str($fds),
631
            link_results(
632
                "$file_delete[$fds]",
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $file_delete does not seem to be defined for all execution paths leading up to this point.
Loading history...
633
                $urlquery,
634
                sprintf('outcome=%d', RESULT_OUTCOME_SUCCESS),
635
                "file_delete_state=$fds"
636
            )
637
        );
638
    }
639
    row2(
640
        "Total files deleted",
641
        link_results(
642
            "$nfile_deleted",
643
            $urlquery,
644
            sprintf('outcome=%d', RESULT_OUTCOME_SUCCESS),
645
            sprintf(
646
                '(file_delete_state=%d or file_delete_state=%d or file_delete_state=%d)',
647
                FILE_DELETE_READY, FILE_DELETE_DONE, FILE_DELETE_ERROR
648
            )
649
        )
650
    );
651
    end_table();
652
    echo "</td>";
653
654
    echo "<td>";
655
    start_table('table-striped');
656
    echo "<tr><th>Client state</th><th># results</th></tr>\n";
657
    for ($cs=1; $cs<7; $cs++) {
658
        $res = new StdClass;
659
        $res->client_state = $cs;
660
        $res->exit_status = 0;
661
        row2(result_client_state_string($res),
662
            link_results(
663
                "$client_state[$cs]",
664
                $urlquery,
665
                "client_state=$cs",
666
                sprintf('outcome=%d', RESULT_OUTCOME_CLIENT_ERROR)
667
            )
668
        );
669
    }
670
    end_table();
671
    echo "</td>";
672
    end_table();
673
}
674
675
function server_state_select() {
676
    echo "
677
        <select name=\"server_state\">
678
        <option value=\"CHOOSE_ALL\" selected=\"selected\"> Any </option>
679
    ";
680
    for ($i=1; $i<6; $i++) {
681
        $res = new StdClass;
682
        $res->server_state=$i;
683
        echo "<option value=\"$i\"> "."[$i]&nbsp;&nbsp;".'   '.result_server_state_string($res)."</option>\n";
684
    }
685
    echo "</select>\n";
686
}
687
688
function outcome_select() {
689
    echo "
690
        <select name=\"outcome\">
691
        <option value=\"CHOOSE_ALL\" selected=\"selected\"> Any </option>
692
    ";
693
    for ($i=0; $i<8; $i++) {
694
        $res = new StdClass;
695
        $res->outcome = $i;
696
        $res->exit_status = 0;
697
        echo "<option value=\"$i\"> "."[$i]&nbsp;&nbsp;".'   '.result_outcome_string($res)."</option>\n";
698
    }
699
    echo "</select>\n";
700
}
701
702
function validate_state_select() {
703
    echo "
704
        <select name=\"validate_state\">
705
        <option value=\"CHOOSE_ALL\" selected=\"selected\"> Any </option>
706
        ";
707
    for ($vs=0; $vs<NVALIDATE_STATES; $vs++) {
708
        $res = new StdClass;
709
        $res->validate_state = $vs;
710
        $res->exit_status = 0;
711
        echo "<option value=\"$vs\"> "."[$vs]&nbsp;&nbsp;".'   '.validate_state_str($res)."</option>\n";
712
    }
713
    echo "</select>\n";
714
}
715
716
function client_state_select() {
717
    echo "
718
        <select name=\"client_state\">
719
        <option value=\"CHOOSE_ALL\" selected=\"selected\"> Any </option>
720
    ";
721
    for ($i=0; $i<7; $i++) {
722
        $res = new StdClass;
723
        $res->client_state = $i;
724
        $res->exit_status = 0;
725
        echo "<option value=\"$i\"> "."[$i]&nbsp;&nbsp;".result_client_state_string($res)."</option>\n";
726
    }
727
    echo "</select>\n";
728
}
729
730
function result_sort_select() {
731
    echo "
732
        <select name=\"sort_by\">
733
        <option value=\"\">None
734
        <option value=\"id\">ID
735
        <option value=\"sent_time\">Sent time
736
        <option value=\"mod_time\">Modification time
737
        <option value=\"received_time\">Received time
738
        <option value=\"exit_status\">Exit status
739
        <option value=\"hostid\">Host ID
740
        <option value=\"userid\">User ID
741
        <option value=\"app_version_num\">App Version Number
742
        <option value=\"cpu_time\">CPU time
743
        <option value=\"workunitid\">Work Unit ID
744
        </select>
745
    ";
746
}
747
748
function sort_order_select() {
749
    echo "
750
        <select name=\"sort_by_order\">
751
        <option value=\"asc\">Ascending
752
        <option value=\"desc\" selected>Descending
753
        </select>
754
    ";
755
}
756
757
function table_title($table) {
758
    switch($table) {
759
    case "platform": return "Platforms";
760
    case "app": return "Applications";
761
    case "app_version": return "Application Versions";
762
    case "host": return "Hosts";
763
    case "workunit": return "Workunits";
764
    case "result": return "Results";
765
    case "team": return "Teams";
766
    case "user": return "Users";
767
    case "profile": return "Profiles";
768
    default: return "????";
0 ignored issues
show
Coding Style introduced by
DEFAULT keyword must be indented 4 spaces from SWITCH keyword
Loading history...
Coding Style introduced by
Blank lines are not allowed after DEFAULT statements
Loading history...
769
    }
770
}
771
772
function admin_show_platform($platform) {
773
    start_table();
774
    row("ID", $platform->id);
775
    row("Created", time_str($platform->create_time));
776
    row("Name", $platform->name);
777
    row("User friendly name", $platform->user_friendly_name);
778
    row("","<a href=\"db_action.php?table=app_version&platformid=$platform->id\">App versions for this platform</a>");
779
    end_table();
780
}
781
782
function admin_show_app($app) {
783
    start_table();
784
    row("ID", $app->id);
785
    row("Created", time_str($app->create_time));
786
    row("Name", $app->name);
787
    row("User-friendly name", $app->user_friendly_name);
788
    row("Deprecated", $app->deprecated);
789
    row("Homogeneous redundancy", $app->homogeneous_redundancy);
790
    row("","<a href=\"db_action.php?table=app_version&appid=$app->id\">App Versions for this application</a>");
791
    row("","<a href=\"db_action.php?table=workunit&appid=$app->id&detail=low\">Workunits for this application</a>");
792
    end_table();
793
}
794
795
function admin_show_app_version($app_version) {
796
    start_table();
797
    row("ID", $app_version->id);
798
    row("Created", time_str($app_version->create_time));
799
    row("Application", "<a href=\"db_action.php?table=app&id=$app_version->appid\">" . app_name_by_id($app_version->appid) . "</a>");
800
    row("Version num", $app_version->version_num);
801
    row("Platform", "<a href=\"db_action.php?table=platform&id=$app_version->platformid\">" . platform_name_by_id($app_version->platformid) . "</a>" );
802
    row("Plan Class", $app_version->plan_class);
803
    row("XML doc", "<pre>".htmlspecialchars($app_version->xml_doc)."</pre>");
804
    row("min_core_version", $app_version->min_core_version);
805
    row("max_core_version", $app_version->max_core_version);
806
    row("deprecated", $app_version->deprecated);
807
    end_table();
808
}
809
810
function app_version_short_header() {
811
    echo "
812
        <tr>
813
        <th>ID</th>
814
        <th>Application</th>
815
        <th>Version</th>
816
        <th>Platform</th>
817
        <th>Plan Class</th>
818
        </tr>
819
    ";
820
}
821
822
function admin_show_app_version_short($app_version) {
823
    $x = app_name_by_id($app_version->appid);
824
    $y = platform_name_by_id($app_version->platformid);
825
    echo "
826
        <tr>
827
        <td><a href=\"db_action.php?table=app_version&id=$app_version->id\">$app_version->id</a></td>
828
        <td><a href=\"db_action.php?table=app&id=$app_version->appid\">$x</a></td>
829
        <td>$app_version->version_num</td>
830
        <td><a href=\"db_action.php?table=platform&id=$app_version->platformid\">$y</a></td>
831
        <td>$app_version->plan_class</td>
832
        </tr>
833
    ";
834
}
835
836
function host_short_header() {
837
    echo "
838
        <tr>
839
        <th>host ID</th>
840
        <th>IP address</th>
841
        <th>name</th>
842
        <th>RAC</th>
843
        <th>total credit</th>
844
        <th>CPU</th>
845
        <th>OS</th>
846
        </tr>
847
    ";
848
}
849
850
function admin_show_host_short($host) {
851
    echo "
852
        <tr>
853
        <td><a href=\"db_action.php?table=host&id=$host->id\">$host->id</a></td>
854
        <td>$host->last_ip_addr</td>
855
        <td>$host->domain_name</td>
856
    ";
857
    printf("<td>%.2f</td>", $host->expavg_credit);
858
    printf("<td>%.1f</td>", $host->total_credit);
859
    echo "<td>$host->p_vendor $host->p_model</td>
860
        <td>$host->os_name $host->os_version</td>
861
        </tr>
862
    ";
863
}
864
865
function days_string($x) {
866
    return number_format($x/86400, 2)." days";
867
}
868
869
function resource_name($x) {
870
    switch ($x) {
871
    case 2: return "CPU";
872
    case 3: return "NVIDIA";
873
    case 4: return "AMD";
874
    }
875
    return "Unknown resource: $x";
876
}
877
function hav_app_version_string($avid) {
878
    if ($avid > 1000000) {
879
        $appid = (int)($avid/1000000);
880
        $platform_name = "Anonymous platform";
881
        $version_info = resource_name($avid%1000000);
882
    } else {
883
        $av = BoincAppVersion::lookup("id=$avid");
884
        if (!$av) return "Missing app version $avid";
885
        $appid = $av->appid;
886
        $platform = BoincPlatform::lookup_id($av->platformid);
887
        if (!$platform) return "Missing platform $av->platformid";
888
        $platform_name = $platform->user_friendly_name;
889
        $version_info = "$av->version_num $av->plan_class
890
            <br>PFC: $av->pfc_avg ($av->pfc_n)
891
            <br>scale: $av->pfc_scale
892
        ";
893
    }
894
    $app = BoincApp::lookup_id($appid);
895
    if (!$app) return "Missing app $appid";
896
    return "$app->user_friendly_name
897
        <br>$platform_name
898
        <br>$version_info
899
    ";
900
}
901
902
function admin_show_host_app_versions($hostid) {
903
    start_table();
904
    table_header("app version", "PFC", "Elapsed", "Turnaround");
905
    $havs = BoincHostAppVersion::enum("host_id=$hostid");
906
    foreach ($havs as $hav) {
907
        table_row(
908
            hav_app_version_string($hav->app_version_id),
909
            "$hav->pfc_avg ($hav->pfc_n)",
910
            "$hav->et_avg ($hav->et_n)",
911
            days_string($hav->turnaround_avg)." ($hav->turnaround_n)"
912
        );
913
    }
914
    end_table();
915
}
916
917
function admin_show_host($host) {
918
    start_table();
919
920
    row("ID", $host->id);
921
    row("Created", time_str($host->create_time));
922
    row("User",
923
        "<a href=\"db_action.php?table=user&id=$host->userid\">".user_name_by_id($host->userid)."($host->userid)</a>"
924
    );
925
926
    row("Venue", $host->venue);
927
    row("Info", $host->serialnum);
928
    row("Total credit", $host->total_credit);
929
    row("Average credit", $host->expavg_credit);
930
    row("Average update time", time_str($host->expavg_time));
931
    row("IP address", "$host->last_ip_addr<br>(same the last $host->nsame_ip_addr times)");
932
    row("External IP address", "$host->external_ip_addr<br>");
933
    row("Domain name", $host->domain_name);
934
    $x = $host->timezone/3600;
935
    if ($x >= 0) $x="+$x";
936
    row("Local Standard Time", "UTC $x hours");
937
    row("Number of CPUs", $host->p_ncpus);
938
    row("CPU", "$host->p_vendor $host->p_model");
939
    row("GFLOPS", number_format($host->p_fpops/1e9, 2));
940
    row("GIOPS", number_format($host->p_iops/1e9, 2));
941
942
    row("Number of GPUs", $host->p_ngpus);
943
    row("GPU GFLOPS", number_format($host->p_gpu_fpops/1e9, 2));
944
945
    $x = $host->p_membw/(1024*1024);
946
    $y = number_format($x, 2);
947
    row("Memory bandwidth", "$y MB/sec");
948
    row("Operating System", "$host->os_name $host->os_version");
949
    $x = $host->m_nbytes/(1024*1024);
950
    $y = number_format($x, 2);
951
    row("Memory", "$y MB");
952
    $x = $host->m_cache/1024;
953
    $y = number_format($x, 2);
954
    row("Cache", "$y KB");
955
    $x = $host->m_swap/(1024*1024);
956
    $y = number_format($x, 2);
957
    row("Swap Space", "$y MB");
958
    $x = $host->d_total/(1024*1024*1024);
959
    $y = number_format($x, 2);
960
    row("Total Disk Space", "$y GB");
961
    $x = $host->d_free/(1024*1024*1024);
962
    $y = number_format($x, 2);
963
    row("Free Disk Space", "$y GB");
964
    $x = number_format($host->n_bwup/1024);
965
    row("Avg network bandwidth (upstream)", "$x kB/sec");
966
    $x = number_format($host->n_bwdown/1024);
967
    row("Avg network bandwidth (downstream)", "$x kB/sec");
968
    row("Average turnaround", days_string($host->avg_turnaround));
969
    row("Number of RPCs", $host->rpc_seqno);
970
    row("Last RPC", time_str($host->rpc_time));
971
    row("% of time client on", 100*$host->on_frac." %");
972
    row("% of time host connected", 100*$host->connected_frac." %");
973
    row("% of time user active", 100*$host->active_frac." %");
974
    row("# of results today", $host->nresults_today);
975
    row("Results", "<a href=\"db_action.php?table=result&detail=low&hostid=$host->id&sort_by=sent_time\">click here</a>");
976
    end_table();
977
    admin_show_host_app_versions($host->id);
978
}
979
980
function admin_show_workunit($wu) {
981
    $_GET = array('workunitid' => $wu->id);
982
    admin_show_result_summary();
983
984
    start_table();
985
    row("Created", time_str($wu->create_time));
986
    row("Transition Time", time_str($wu->transition_time));
987
    row("Last time modified", mysqltime_str($wu->mod_time));
988
    row("Name", $wu->name);
989
    row("XML doc", "<pre>".htmlspecialchars($wu->xml_doc)."</pre>");
990
    row("Application", "<a href=\"db_action.php?table=app&id=$wu->appid\">" . app_name_by_id($wu->appid) . " [".$wu->appid."]</a>");
991
    row("Application version number", $wu->app_version_num);
992
    row("Batch", $wu->batch);
993
    $x = number_format($wu->rsc_fpops_est/1e9, 2);
994
    row("Estimated FP Operations", "$x GFLOPS");
995
    $x = number_format($wu->rsc_fpops_bound/1e9, 2);
996
    row("Max FP Operations", "$x GFLOPS");
997
    $x = $wu->rsc_memory_bound/(1024*1024);
998
    $y = number_format($x, 2);
999
    row("Max Memory Usage", "$y MB");
1000
    $x = $wu->rsc_disk_bound/(1024*1024);
1001
    $y = number_format($x, 2);
1002
    row("Max Disk Usage", "$y MB");
1003
    row("Need validate?", ($wu->need_validate?"yes [":"no [").$wu->need_validate."]");
1004
    row("Canonical resultid",
1005
            "<a href=\"db_action.php?table=result&id=$wu->canonical_resultid\">".$wu->canonical_resultid."</a>");
1006
    row("Canonical credit", $wu->canonical_credit);
1007
    //row("Timeout check time", time_str($wu->timeout_check_time));
1008
    row("Delay bound", "$wu->delay_bound" . " =  " . time_diff($wu->delay_bound) );
1009
    row("Error mask", wu_error_mask_str($wu->error_mask, true));
1010
    row("File delete state", file_delete_state_str($wu->file_delete_state)." [".$wu->file_delete_state."]");
1011
    row("Assimilation state", assimilate_state_str($wu->assimilate_state)." [".$wu->assimilate_state."]");
1012
    // row("","<a href=db_action.php?table=result&workunitid=$wu->id&detail=low>Show associated results</a>");
1013
    row("min quorum", $wu->min_quorum);
1014
    row("target results", $wu->target_nresults);
1015
    row("max error results", $wu->max_error_results);
1016
    row("max total results", $wu->max_total_results);
1017
    row("max success results", $wu->max_success_results);
1018
    row("result template file",$wu->result_template_file);
1019
    row("hr_class", $wu->hr_class);
1020
    row("opaque", $wu->opaque);
1021
    row("Priority", $wu->priority);
1022
    row("Keywords", ($wu->keywords ? $wu->keywords : "<em>empty</em>"));
1023
    end_table();
1024
    echo "<div align=\"center\">";
1025
    echo "<a href=\"show_log.php?s=$wu->name\">GREP LOGS FOR THIS WORKUNIT</a>";
1026
    echo "</div>";
1027
    echo "<p>";
1028
}
1029
1030
function workunit_short_header() {
1031
    echo "
1032
        <tr>
1033
        <th>ID</th>
1034
        <th>name</th>
1035
        <th>canonical result</th>
1036
        <th>error_mask</th>
1037
        <th>file delete</th>
1038
        <th>assimilate</th>
1039
        </tr>
1040
    ";
1041
}
1042
1043
function admin_show_workunit_short($wu) {
1044
    if ($wu->canonical_resultid) {
1045
        $cr = sprintf('<a href="db_action.php?table=result&id=%d">%d</a>',
1046
            $wu->canonical_resultid,
1047
            $wu->canonical_resultid
1048
        );
1049
    } else {
1050
        $cr = "none";
1051
    }
1052
    $cr .= sprintf(
1053
        ' <a href="db_action.php?table=result&workunitid=%d&detail=low">all</a>',
1054
        $wu->id
1055
    );
1056
    $wu_link = sprintf(
1057
        '<a href="db_action.php?table=workunit&id=%d&detail=high">%d</a>',
1058
        $wu->id,
1059
        $wu->id
1060
    );
1061
    $e = wu_error_mask_str($wu->error_mask, true);
1062
    $f = file_delete_state_str($wu->file_delete_state);
1063
    $a = assimilate_state_str($wu->assimilate_state);
1064
    echo "
1065
        <tr>
1066
        <td>$wu_link</td>
1067
        <td>$wu->name</td>
1068
        <td>$cr</td>
1069
        <td>$e</td>
1070
        <td>$f</td>
1071
        <td>$a</td>
1072
        </tr>
1073
    ";
1074
}
1075
1076
function host_user_link($hostid) {
1077
    if (!$hostid) return '---';
1078
1079
    $h = "<a href=\"db_action.php?table=host&id=$hostid\">$hostid</a>";
1080
    $host = BoincHost::enum_fields("userid", "id=".$hostid, "limit 1");
1081
    if (!$host) return $h;
1082
    $user = BoincUser::enum_fields("id, name", "id=".$host[0]->userid, "limit 1");
1083
    if (!$user) return $h;
1084
    return "$h<br><small>(<a href=\"db_action.php?table=user&id=".$user[0]->id."\">".$user[0]->name."</a>)</small>";
1085
}
1086
1087
function validate_color($validate_state) {
1088
    switch ($validate_state) {
1089
   case 1: return '33cc33'; // valid, green
1090
   case 2: return 'ffa500'; // invalid result, orange
1091
    }
1092
    return '';
1093
}
1094
1095
function outcome_color($outcome) {
1096
    switch($outcome) {
1097
    case 0: return '9900cc'; // "Init", purple
1098
    case 1: return '33cc33'; // "Success", green
1099
    case 3: return 'ff3333'; // "Client error", red
1100
    case 4: return 'ff6699'; // "No reply", pink
1101
    case 6: return 'ffff33'; // "Validate error", yellow
1102
    }
1103
    return '';
1104
}
1105
1106
function credit_str($c) {
1107
    if ($c) {
1108
        return sprintf("%.3f", $c);
1109
    } else {
1110
        return '---';
1111
    }
1112
}
1113
1114
function admin_show_result($result) {
1115
    $wu_name = wu_name_by_id($result->workunitid);
1116
1117
    start_table();
1118
1119
    row("Created", time_str($result->create_time));
1120
    row("Sent", time_str($result->sent_time));
1121
    row("Report deadline", time_str($result->report_deadline));
1122
    row("Received", time_str($result->received_time));
1123
    row("Last time modified", mysqltime_str($result->mod_time));
1124
    row("Name", $result->name);
1125
    row("Workunit", "<a href=\"db_action.php?table=workunit&id=$result->workunitid\">" . wu_name_by_id($result->workunitid) . "</a> [$result->workunitid]" );
1126
    row("Server state", result_server_state_string($result)." [$result->server_state]");
1127
    row("Outcome", result_outcome_string($result)." [$result->outcome]");
1128
    row("Client state", result_client_state_string($result)." [$result->client_state]");
1129
    row("Exit status", exit_status_string($result->exit_status));
1130
    row("Host ID", "<a href=\"db_action.php?table=host&id=$result->hostid\">" . host_name_by_id($result->hostid) . "</a> [$result->hostid]");
1131
    row("User ID", "<a href=\"db_action.php?table=user&id=$result->userid\">" . user_name_by_id($result->userid) . "</a> [$result->userid]");
1132
    row("CPU time", $result->cpu_time);
1133
    row("Elapsed time", $result->elapsed_time);
1134
    if($error=stderr_error_string($result->stderr_out)) {
1135
        row("error in stderr out", $error);
1136
    }
1137
    row("Batch", $result->batch);
1138
    row("File delete state", file_delete_state_str($result->file_delete_state)." [$result->file_delete_state]");
1139
    row("Validate state", validate_state_str($result)." [$result->validate_state]");
1140
    row("Granted credit", $result->granted_credit);
1141
    row("Application", "<a href=\"db_action.php?table=app&id=$result->appid\">".app_name_by_id($result->appid)."</a>");
1142
    if ($result->app_version_id > 0) {
1143
        $x1 = "<a href=\"db_action.php?table=app_version&amp;id=$result->app_version_id\">";
1144
        $x2 = "</a>";
1145
    } else {
1146
        $x1 = $x2 = "";
1147
    }
1148
    row("App version", $x1.app_version_string($result).$x2);
1149
    row("App version ID", $result->app_version_id);
1150
    row("Estimated GFLOPS", number_format($result->flops_estimate/1e9, 2));
1151
    row("Random",$result->random);
1152
    row("Opaque",$result->opaque);
1153
    row("Teamid",$result->teamid);
1154
    row("Priority",$result->priority);
1155
    row("XML doc in", "<pre>".htmlspecialchars($result->xml_doc_in)."</pre>");
1156
    row("XML doc out", "<pre>".htmlspecialchars($result->xml_doc_out)."</pre>");
1157
    row("stderr out", "<pre>"
1158
        .htmlspecialchars(
1159
            $result->stderr_out,
1160
            ENT_QUOTES | (defined('ENT_SUBSTITUTE')?ENT_SUBSTITUTE:0),
1161
            'utf-8'
1162
        )
1163
        ."</pre>"
1164
    );
1165
    end_table();
1166
    echo "
1167
        <center>
1168
        <a href=\"show_log.php?s=$result->name\">GREP LOGS FOR THIS RESULT</a>
1169
        </center>
1170
        <p>
1171
    ";
1172
}
1173
1174
function result_short_header() {
1175
    echo "
1176
        <tr>
1177
        <th>result ID</th>
1178
        <th>WU ID</th>
1179
        <th>server<br>state</th>
1180
        <th>outcome</th>
1181
        <th>client<br>state</th>
1182
        <th>validate<br>state</th>
1183
        <th>delete<br>state</th>
1184
        <th>exit<br>status</th>
1185
        <th>host<br>(user)</th>
1186
        <th>app<br>ver</th>
1187
        <th>received <br><i>or</i> <font color=\"#ff3333\">dead</font><font color=\"#33cc33\">line</font> <br><i>or</i> <font color=\"#9900cc\">created</font></th>
1188
        <th>CPU<br>hours</th>
1189
        <th>granted<br>credit</th>
1190
        </tr>
1191
    ";
1192
}
1193
1194
function admin_show_result_short($result) {
1195
    $ss = result_server_state_string($result)." [$result->server_state]";
1196
    $oc = result_outcome_string($result)." [$result->outcome]";
1197
    $vs = validate_state_str($result)." [$result->validate_state]";
1198
    $cs2 = result_client_state_string($result)." [$result->client_state]";
1199
    if ($result->outcome == 3) {
1200
        $cs = result_client_state_string($result);
1201
        $oc = "$oc ($cs)";
1202
    }
1203
    if ($result->received_time) {
1204
        $received = time_str($result->received_time);
1205
    } else {
1206
        // result has not been received yet, so show report deadline either
1207
        // in green if in the future or in red if in the past.
1208
        $timenow=time();
1209
        if ($result->report_deadline==0)  {
1210
            // not sent -- show create time in purple
1211
            $received = "<font color=\"9900cc\">". time_str($result->create_time) . "</font>";
1212
        } else if ($result->report_deadline>=$timenow) {
1213
            // overdue -- show deadline in red
1214
            $received = "<font color=\"#33cc33\">". time_str($result->report_deadline) . "</font>";
1215
        } else {
1216
            // in progress and not overdue -- show deadline in green
1217
            $received = "<font color=\"#ff3333\">". time_str($result->report_deadline) . "</font>";
1218
        }
1219
    }
1220
    $version = app_version_string($result)." (<a href=\"db_action.php?table=app_version&id=$result->app_version_id\">$result->app_version_id</a>)";
1221
    $outcome_color = outcome_color($result->outcome);
1222
    $validate_color = validate_color($result->validate_state);
1223
    $host_user = host_user_link($result->hostid);
1224
    $cpu_hours = sprintf("%.1f",$result->cpu_time / 3600);
1225
    $granted_credit = "<a href=credit.php?wu_id=$result->workunitid>".credit_str($result->granted_credit)."</a>";
1226
    $delete_state = file_delete_state_str($result->file_delete_state);
1227
1228
    echo "
1229
        <tr>
1230
        <td><a href=\"db_action.php?table=result&id=$result->id\">$result->id</a></td>
1231
        <td><a href=\"db_action.php?table=workunit&id=$result->workunitid\">$result->workunitid</a></td>
1232
        <td>$ss</td>
1233
        <td bgcolor=$outcome_color>$oc</td>
1234
        <td>$cs2</td>
1235
        <td bgcolor=$validate_color>$vs</td>
1236
        <td>$delete_state</td>
1237
        <td>", exit_status_string($result->exit_status), "</td>
1238
        <td>$host_user</td>
1239
        <td>$version</td>
1240
        <td>$received</td>
1241
        <td>$cpu_hours</td>
1242
        <td>$granted_credit</td>
1243
        </tr>
1244
    ";
1245
}
1246
1247
function admin_show_user($user) {
1248
    start_table();
1249
    row("ID", $user->id);
1250
    row("Created", time_str($user->create_time));
1251
    row("Name", $user->name);
1252
    if(!in_rops()) {
1253
        row("Authenticator", $user->authenticator);
1254
    }
1255
    row("Email address", $user->email_addr);
1256
    row("Previous email address", $user->previous_email_addr);
1257
    row("Email change time", time_str($user->email_addr_change_time));
1258
    row("OK to send Email?", $user->send_email);
1259
    row("Country", $user->country);
1260
    row("Postal code", $user->postal_code);
1261
    row("Total credit", $user->total_credit);
1262
    row("Average credit", $user->expavg_credit);
1263
    row("Last average time", time_str($user->expavg_time));
1264
    row("Default venue", $user->venue);
1265
    row("Hosts", "<a href=\"db_action.php?table=host&userid=$user->id&detail=low\">click</a>");
1266
    row("Cross project ID", $user->cross_project_id);
1267
    if(!in_rops()) {
1268
        row("Password Hash", $user->passwd_hash);
1269
    }
1270
    row("Donated", $user->donated);
1271
    end_table();
1272
}
1273
1274
function admin_show_user_summary($maxuser) {
1275
    $top_country = array();
1276
    $top_language = array();
1277
    $db = BoincDb::get(true);
1278
    $stats_res = $db->do_query("select max(id) as maxuser,
1279
        SUM(case when has_profile = '1' then 1 else 0 end) as profuser,
1280
        SUM(case when teamid != '0' then 1 else 0 end) as teamuser
1281
        from user"
1282
    );
1283
    $stats = $stats_res->fetch_assoc();
1284
    if ($maxuser > $stats['maxuser']) {
1285
        $maxuser = $stats['maxuser'];
1286
    }
1287
    // TODO: what is in profile.posts? A user can post in the forums without a profile.
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
1288
    $users = BoincUser::enum(null, "order by posts desc limit ".$maxuser);
1289
    $profiles = BoincProfile::enum(null, "order by posts desc limit ".$maxuser);
1290
    foreach ($users as $user) {
1291
        $top10poster[$i] = $user;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $i seems to be never defined.
Loading history...
1292
        $top_country[$user->country] += 1;
1293
    }
1294
    foreach ($profiles as $profile) {
1295
        if ($profile->language != '') {
1296
            $top_language[$profile->language] += 1;
1297
        }
1298
    }
1299
    $stats_res->free();
1300
    echo "<table>
1301
          <tr valign=\"top\">
1302
            <td><h2>General</h2></td>
1303
            <td><h2>top10 Poster</h2></td>
1304
            <td><h2>top$maxuser Countries</h2></td>
1305
            <td><h2>top$maxuser Languages</h2></td>
1306
          </tr>
1307
    ";
1308
    echo "<tr valign=\"top\">";
1309
    echo "<td><table border=\"1\">
1310
          <tr><th>&nbsp;</th><th>&nbsp;</th></tr>
1311
    ";
1312
    row2_plain("Users:", $stats['maxuser']);
1313
    row2_plain("Profiles:", $stats['profuser']);
1314
    row2_plain("Team members:", $stats['teamuser']);
1315
    echo "</table></td>";
1316
    echo "<td><table border=\"2\">\n";
1317
    echo "<tr><th>User</th><th># posts</th></tr>\n";
1318
    for ($p=1; $p<=10; $p++) {
1319
        row2_plain(user_links_ops($top10poster[$p]), $top10poster[$p]->posts);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $top10poster seems to be defined by a foreach iteration on line 1290. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
1320
    }
1321
    echo "</table></td>";
1322
    echo "<td><table border=\"2\">\n";
1323
    echo "<tr><th>Country</th><th># users</th></tr>\n";
1324
    arsort($top_country);
1325
1326
    foreach ($top_country as $key => $value) {
1327
        row2_plain($key, $value);
1328
    }
1329
    echo "</table></td>";
1330
    echo "<td><table border=\"2\">\n";
1331
    echo "<tr><th>Language</th><th># users</th></tr>\n";
1332
    arsort($top_language);
1333
    foreach ($top_language as $key => $value) {
1334
        row2_plain($key, $value);
1335
    }
1336
    echo "</table></td>";
1337
1338
    echo "</tr></table></td></tr>";
1339
}
1340
1341
function team_type_string($s) {
1342
    switch ($s) {
1343
    case 1: return "Unclassified";
1344
    case 2: return "Company";
1345
    case 3: return "Primary school";
1346
    case 4: return "Secondary school";
1347
    case 5: return "Junior college";
1348
    case 6: return "University or department";
1349
    case 7: return "Government agency";
1350
    default: return "Unknown";
0 ignored issues
show
Coding Style introduced by
DEFAULT keyword must be indented 4 spaces from SWITCH keyword
Loading history...
Coding Style introduced by
Blank lines are not allowed after DEFAULT statements
Loading history...
1351
    }
1352
}
1353
1354
function admin_show_team($team) {
1355
    start_table();
1356
    row("ID", $team->id);
1357
    row("Team Founder", "<a href=\"db_action.php?table=user&id=$team->userid\">" . user_name_by_id($team->userid) . "</a>");
1358
    row("Name", $team->name);
1359
    row("Name (HTML Formatted)", "<pre>" . htmlspecialchars($team->name_html) . "</pre>" );
1360
    row("Url", "<a href=\"http://$team->url\">" . $team->url . "</a>");
1361
    row("Type", team_type_string($team->type));
1362
    row("Description", $team->description);
1363
    row("", "<a href=\"db_action.php?table=user&teamid=$team->id\">List All Members</a>");
1364
    end_table();
1365
}
1366
1367
function team_name_by_id($teamid) {
1368
    $team = BoincTeam::lookup_id($teamid);
1369
    if (!$team) return "No team";
1370
    return $team->name;
1371
}
1372
1373
function user_name_by_id($user_id) {
1374
    $user = BoincUser::lookup_id($user_id);
1375
    if (!$user) return "No user";
1376
    return $user->name;
1377
}
1378
1379
function app_name_by_id($appid) {
1380
    $app = BoincApp::lookup_id($appid);
1381
    if (!$app) return "No app";
1382
    return $app->name;
1383
}
1384
1385
function wu_name_by_id($workunitid) {
1386
    $wu = BoincWorkunit::lookup_id($workunitid);
1387
    if (!$wu) return "Missing workunit";
1388
    return $wu->name;
1389
}
1390
1391
function platform_name_by_id($platformid) {
1392
    $plat = BoincPlatform::lookup_id($platformid);
1393
    if (!$plat) return "Missing platform";
1394
    return $plat->name;
1395
}
1396
1397
function host_name_by_id($hostid) {
1398
    $host = BoincHost::lookup_id($hostid);
1399
    if (!$host) return "No host";
1400
    if (!strlen($host->domain_name) && !strlen($host->last_ip_addr)) {
1401
        return "(blank)";
1402
    } else {
1403
        return $host->domain_name . " (" . $host->last_ip_addr . ")";
1404
    }
1405
}
1406
1407
?>
1408