Passed
Pull Request — master (#5920)
by David
10:15
created

handle_admin()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 23
c 0
b 0
f 0
nc 8
nop 1
dl 0
loc 38
rs 8.9297
1
<?php
2
3
// This file is part of BOINC.
4
// http://boinc.berkeley.edu
5
// Copyright (C) 2024 University of California
6
//
7
// BOINC is free software; you can redistribute it and/or modify it
8
// under the terms of the GNU Lesser General Public License
9
// as published by the Free Software Foundation,
10
// either version 3 of the License, or (at your option) any later version.
11
//
12
// BOINC is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
// See the GNU Lesser General Public License for more details.
16
//
17
// You should have received a copy of the GNU Lesser General Public License
18
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
19
20
// web interface for remote job submission:
21
// - links to job-submission pages
22
// - Admin (if privileged user)
23
// - manage batches
24
//      view status, get output files, abort, retire
25
// - toggle 'use only my computers'
26
27
require_once("../inc/submit_db.inc");
28
require_once("../inc/util.inc");
29
require_once("../inc/result.inc");
30
require_once("../inc/submit_util.inc");
31
require_once("../project/project.inc");
32
33
display_errors();
34
35
define("PAGE_SIZE", 20);
36
37
function state_count($batches, $state) {
38
    $n = 0;
39
    foreach ($batches as $batch) {
40
        if ($batch->state == $state) $n++;
41
    }
42
    return $n;
43
}
44
45
function show_all_link($batches, $state, $limit, $user, $app) {
46
    $n = state_count($batches, $state);
47
    if ($n > $limit) {
48
        if ($user) $userid = $user->id;
49
        else $userid = 0;
50
        if ($app) $appid = $app->id;
51
        else $appid = 0;
52
53
        echo "Showing the most recent $limit of $n batches.
54
            <a href=submit.php?action=show_all&state=$state&userid=$userid&appid=$appid>Show all $n</a>
55
            <p>
56
        ";
57
    }
58
}
59
60
function show_in_progress($batches, $limit, $user, $app) {
61
    echo "<h3>Batches in progress</h3>\n";
62
    $first = true;
63
    $n = 0;
64
    foreach ($batches as $batch) {
65
        if ($batch->state != BATCH_STATE_IN_PROGRESS) continue;
66
        if ($limit && $n == $limit) break;
67
        $n++;
68
        if ($first) {
69
            $first = false;
70
            if ($limit) {
71
                show_all_link($batches, BATCH_STATE_IN_PROGRESS, $limit, $user, $app);
72
            }
73
            start_table();
74
            table_header(
75
                "Name",
76
                "ID",
77
                "User",
78
                "App",
79
                "# jobs",
80
                "Progress",
81
                "Submitted",
82
                "Logical end time<br><small>Determines priority</small>"
83
            );
84
        }
85
        $pct_done = (int)($batch->fraction_done*100);
86
        table_row(
87
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->name</a>",
88
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->id</a>",
89
            $batch->user_name,
90
            $batch->app_name,
91
            $batch->njobs,
92
            "$pct_done%",
93
            local_time_str($batch->create_time),
94
            local_time_str($batch->logical_end_time)
95
        );
96
    }
97
    if ($first) {
98
        echo "<p>None.\n";
99
    } else {
100
        end_table();
101
    }
102
}
103
104
function show_complete($batches, $limit, $user, $app) {
105
    $first = true;
106
    $n = 0;
107
    foreach ($batches as $batch) {
108
        if ($batch->state != BATCH_STATE_COMPLETE) continue;
109
        if ($limit && $n == $limit) break;
110
        $n++;
111
        if ($first) {
112
            $first = false;
113
            echo "<h3>Completed batches</h3>\n";
114
            if ($limit) {
115
                show_all_link($batches, BATCH_STATE_COMPLETE, $limit, $user, $app);
116
            }
117
            start_table();
118
            table_header("name", "ID", "user", "app", "# jobs", "submitted");
119
        }
120
        table_row(
121
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->name</a>",
122
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->id</a>",
123
            $batch->user_name,
124
            $batch->app_name,
125
            $batch->njobs,
126
            local_time_str($batch->create_time)
127
        );
128
    }
129
    if ($first) {
130
        echo "<p>No completed batches.\n";
131
    } else {
132
        end_table();
133
    }
134
}
135
136
function show_aborted($batches, $limit, $user, $app) {
137
    $first = true;
138
    $n = 0;
139
    foreach ($batches as $batch) {
140
        if ($batch->state != BATCH_STATE_ABORTED) continue;
141
        if ($limit && $n == $limit) break;
142
        $n++;
143
        if ($first) {
144
            $first = false;
145
            echo "<h2>Aborted batches</h2>\n";
146
            if ($limit) {
147
                show_all_link($batches, BATCH_STATE_ABORTED, $limit, $user, $app);
148
            }
149
            start_table();
150
            table_header("name", "ID", "user", "app", "# jobs", "submitted");
151
        }
152
        table_row(
153
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->name</a>",
154
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->id</a>",
155
            $batch->user_name,
156
            $batch->app_name,
157
            $batch->njobs,
158
            local_time_str($batch->create_time)
159
        );
160
    }
161
    if (!$first) {
162
        end_table();
163
    }
164
}
165
166
// fill in the app and user names in list of batches
167
//
168
function fill_in_app_and_user_names(&$batches) {
169
    foreach ($batches as $batch) {
170
        $app = BoincApp::lookup_id($batch->app_id);
171
        if ($app) {
172
            $batch->app_name = $app->name;
173
        } else {
174
            $batch->app_name = "unknown";
175
        }
176
        $user = BoincUser::lookup_id($batch->user_id);
177
        if ($user) {
178
            $batch->user_name = $user->name;
179
        } else {
180
            $batch->user_name = "missing user $batch->user_id";
181
        }
182
    }
183
}
184
185
// show a set of batches
186
//
187
function show_batches($batches, $limit, $user, $app) {
188
    fill_in_app_and_user_names($batches);
189
    show_in_progress($batches, $limit, $user, $app);
190
    show_complete($batches, $limit, $user, $app);
191
    show_aborted($batches, $limit, $user, $app);
192
}
193
194
// the job submission "home page":
195
// show the user's in-progress and completed batches,
196
// and a button for creating a new batch
197
//
198
function handle_main($user) {
199
    global $web_apps;
200
    $user_submit = BoincUserSubmit::lookup_userid($user->id);
201
    if (!$user_submit) {
202
        error_page("Ask the project admins for permission to submit jobs");
203
    }
204
205
    page_head("Job submission");
206
207
    if (isset($web_apps) && $web_apps) {
208
        // show links to per-app job submission pages
209
        //
210
        echo "<h3>Submit jobs</h3>
211
            <ul>
212
        ";
213
        foreach ($web_apps as $appname => $web_app) {
214
            $appname = BoincDb::escape_string($appname);
215
            $app = BoincApp::lookup("name='$appname'");
216
            if (!$app) error_page("bad web app name: $appname");
217
            $usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$app->id");
218
            if ($usa || $user_submit->submit_all) {
219
                echo "<li> <a href=$web_app->submit_url> $app->user_friendly_name </a>";
220
            }
221
        }
222
        echo "</ul>\n";
223
    }
224
225
    echo '<h3>Where your jobs run</h3>';
226
    if ($user->seti_id) {
227
        echo "<p>
228
            Jobs you submit can run only on your computers.
229
            <p>
230
        ";
231
        show_button(
232
            'submit.php?action=toggle_loc',
233
            'Allow them to run on any computer.'
234
        );
235
    } else {
236
        echo "<p>
237
            Jobs you submit can run on any computer.
238
            <p>
239
        ";
240
        show_button(
241
            'submit.php?action=toggle_loc',
242
            'Allow them to run only on your computers.'
243
        );
244
    }
245
246
    // show links to admin pages if relevant
247
    //
248
    $usas = BoincUserSubmitApp::enum("user_id=$user->id");
249
    $app_admin = false;
250
    foreach ($usas as $usa) {
251
        if ($usa->manage) {
252
            $app_admin = true;
253
            break;
254
        }
255
    }
256
    if ($user_submit->manage_all || $app_admin) {
257
        echo "<h3>Administer job submission</h3>\n";
258
        show_button('submit.php?action=admin', 'Administer');
259
    }
260
261
    $batches = BoincBatch::enum("user_id = $user->id order by id desc");
262
    show_batches($batches, PAGE_SIZE, $user, null);
263
264
    page_tail();
265
}
266
267
function handle_toggle_loc($user) {
268
    if ($user->seti_id) {
269
        $user->update('seti_id=0');
270
    } else {
271
        $user->update('seti_id=1');
272
    }
273
    handle_main($user);
274
}
275
276
// show links for everything the user has admin access to
277
//
278
function handle_admin($user) {
279
    $user_submit = BoincUserSubmit::lookup_userid($user->id);
280
    if (!$user_submit) error_page('no access');
281
    page_head("Administer job submission");
282
    if ($user_submit->manage_all) {
283
        echo "<li>All applications<br>
284
            <ul>
285
            <li> <a href=submit.php?action=admin_all>View all batches</a>
286
            <li> <a href=manage_project.php>Manage user permissions</a>
287
            </ul>
288
        ";
289
        $apps = BoincApp::enum("deprecated=0");
290
        foreach ($apps as $app) {
291
            echo "
292
                <li>$app->user_friendly_name<br>
293
                <ul>
294
                <li><a href=submit.php?action=admin_app&app_id=$app->id>View batches</a>
295
                <li> <a href=manage_app.php?app_id=$app->id&amp;action=app_version_form>Manage app versions</a>
296
                <li> <a href=manage_app.php?app_id=$app->id&amp;action=permissions_form>Manage user permissions</a>
297
                <li> <a href=manage_app.php?app_id=$app->id&amp;action=batches_form>Manage batches</a>
298
                </ul>
299
            ";
300
        }
301
    } else {
302
        foreach ($usas as $usa) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $usas seems to be never defined.
Loading history...
303
            $app = BoincApp::lookup_id($usa->app_id);
304
            echo "<li>$app->user_friendly_name<br>
305
                <a href=submit.php?action=admin_app&app_id=$app->id>Batches</a>
306
            ";
307
            if ($usa->manage) {
308
                echo "&middot;
309
                    <a href=manage_app.php?app_id=$app->id&action=app_version_form>Versions</a>
310
                ";
311
            }
312
        }
313
    }
314
    echo "</ul>\n";
315
    page_tail();
316
}
317
318
function handle_admin_app($user) {
319
    $app_id = get_int("app_id");
320
    $app = BoincApp::lookup_id($app_id);
321
    if (!$app) error_page("no such app");
322
    if (!has_admin_access($user, $app_id)) {
323
        error_page('no access');
324
    }
325
326
    page_head("Administer batches for $app->user_friendly_name");
327
    $batches = BoincBatch::enum("app_id = $app_id order by id desc");
328
    show_batches($batches, PAGE_SIZE, null, $app);
329
    page_tail();
330
}
331
function handle_admin_all($user) {
332
    page_head("Administer batches (all apps)");
333
    $batches = BoincBatch::enum("true order by id desc");
334
    show_batches($batches, PAGE_SIZE, null, null);
335
    page_tail();
336
}
337
338
339
// show the statics of mem/disk usage of jobs in a batch
340
//
341
function handle_batch_stats($user) {
342
    $batch_id = get_int('batch_id');
343
    $batch = BoincBatch::lookup_id($batch_id);
344
    $results = BoincResult::enum("batch = $batch->id");
345
    page_head("Statistics for batch $batch_id");
346
    $n = 0;
347
    $wss_sum = 0;
348
    $swap_sum = 0;
349
    $disk_sum = 0;
350
    $wss_max = 0;
351
    $swap_max = 0;
352
    $disk_max = 0;
353
    foreach ($results as $r) {
354
        if ($r->outcome != RESULT_OUTCOME_SUCCESS) {
355
            continue;
356
        }
357
        // pre-7.3.16 clients don't report usage info
358
        //
359
        if ($r->peak_working_set_size == 0) {
360
            continue;
361
        }
362
        $n++;
363
        $wss_sum += $r->peak_working_set_size;
364
        if ($r->peak_working_set_size > $wss_max) {
365
            $wss_max = $r->peak_working_set_size;
366
        }
367
        $swap_sum += $r->peak_swap_size;
368
        if ($r->peak_swap_size > $swap_max) {
369
            $swap_max = $r->peak_swap_size;
370
        }
371
        $disk_sum += $r->peak_disk_usage;
372
        if ($r->peak_disk_usage > $disk_max) {
373
            $disk_max = $r->peak_disk_usage;
374
        }
375
    }
376
    if ($n == 0) {
377
        echo "No qualifying results.";
378
        page_tail();
379
        return;
380
    }
381
    text_start();
382
    start_table('table-striped');
383
    row2("qualifying results", $n);
384
    row2("mean WSS", size_string($wss_sum/$n));
385
    row2("max WSS", size_string($wss_max));
386
    row2("mean swap", size_string($swap_sum/$n));
387
    row2("max swap", size_string($swap_max));
388
    row2("mean disk usage", size_string($disk_sum/$n));
389
    row2("max disk usage", size_string($disk_max));
390
    end_table();
391
    text_end();
392
    page_tail();
393
}
394
395
// return HTML for a color-coded batch progress bar
396
// green: successfully completed jobs
397
// red: failed
398
// light green: in progress
399
// light gray: unsent
400
//
401
function progress_bar($batch, $wus, $width) {
402
    $w_success = $width*$batch->fraction_done;
403
    $w_fail = $width*$batch->nerror_jobs/$batch->njobs;
404
    $nsuccess = $batch->njobs * $batch->fraction_done;
405
    $nsent = wus_nsent($wus);
406
    $nprog = $nsent - $nsuccess - $batch->nerror_jobs;
407
    $w_prog = $width*$nprog/$batch->njobs;
408
    $nunsent = $batch->njobs-$nsent;
409
    $w_unsent = $width*$nunsent/$batch->njobs;
410
    $x = '<table height=20><tr>';
411
    if ($w_fail) {
412
        $x .= "<td width=$w_fail bgcolor=red></td>";
413
    }
414
    if ($w_success) {
415
        $x .= "<td width=$w_success bgcolor=green></td>";
416
    }
417
    if ($w_prog) {
418
        $x .= "<td width=$w_prog bgcolor=lightgreen></td>";
419
    }
420
    if ($w_unsent) {
421
        $x .= "<td width=$w_unsent bgcolor=lightgray></td>";
422
    }
423
    $x .= "</tr></table>
424
        <strong>
425
        <font color=red>$batch->nerror_jobs fail</font> &middot;
426
        <font color=green>$nsuccess success</font> &middot;
427
        <font color=lightgreen>$nprog in progress</font> &middot;
428
        <font color=lightgray>$nunsent unsent</font>
429
        </strong>
430
    ";
431
    return $x;
432
}
433
434
// show the details of an existing batch
435
//
436
function handle_query_batch($user) {
437
    global $web_apps;
438
439
    $batch_id = get_int('batch_id');
440
    $batch = BoincBatch::lookup_id($batch_id);
441
    $app = BoincApp::lookup_id($batch->app_id);
442
    $wus = BoincWorkunit::enum("batch = $batch->id");
443
    $batch = get_batch_params($batch, $wus);
444
    if ($batch->user_id == $user->id) {
445
        $owner = $user;
446
    } else {
447
        $owner = BoincUser::lookup_id($batch->user_id);
448
    }
449
450
    $web_app = $web_apps[$app->name];
451
452
    page_head("Batch $batch_id");
453
    text_start();
454
    start_table();
455
    row2("name", $batch->name);
456
    if ($batch->description) {
457
        row2('description', $batch->description);
458
    }
459
    if ($owner) {
460
        row2('submitter', $owner->name);
461
    }
462
    row2("application", $app?$app->name:'---');
463
    row2("state", batch_state_string($batch->state));
464
    //row2("# jobs", $batch->njobs);
465
    //row2("# error jobs", $batch->nerror_jobs);
466
    //row2("logical end time", time_str($batch->logical_end_time));
467
    if ($batch->expire_time) {
468
        row2("expiration time", time_str($batch->expire_time));
469
    }
470
    row2("progress", progress_bar($batch, $wus, 600));
471
    if ($batch->completion_time) {
472
        row2("completed", local_time_str($batch->completion_time));
473
    }
474
    row2("GFLOP/hours, estimated", number_format(credit_to_gflop_hours($batch->credit_estimate), 2));
475
    row2("GFLOP/hours, actual", number_format(credit_to_gflop_hours($batch->credit_canonical), 2));
476
    row2("Output File Size", size_string(batch_output_file_size($batch->id)));
477
    end_table();
478
479
    if ($web_app->assim_move) {
480
        $url = "get_output3.php?action=get_batch&batch_id=$batch->id";
481
    } else {
482
        $url = "get_output2.php?cmd=batch&batch_id=$batch->id";
483
    }
484
    echo "<p>";
485
    show_button($url, "Get zipped output files");
486
    echo "<p>";
487
    switch ($batch->state) {
488
    case BATCH_STATE_IN_PROGRESS:
489
        show_button(
490
            "submit.php?action=abort_batch_confirm&batch_id=$batch_id",
491
            "Abort batch"
492
        );
493
        break;
494
    case BATCH_STATE_COMPLETE:
495
    case BATCH_STATE_ABORTED:
496
        show_button(
497
            "submit.php?action=retire_batch_confirm&batch_id=$batch_id",
498
            "Retire batch"
499
        );
500
        break;
501
    }
502
    echo "<p>";
503
    show_button("submit.php?action=batch_stats&batch_id=$batch_id",
504
        "Show memory/disk usage statistics"
505
    );
506
507
    echo "<h2>Jobs</h2>\n";
508
    start_table();
509
    $x = [
510
        "Name <br><small>click for details</small>",
511
        "status"
0 ignored issues
show
Coding Style introduced by
There should be a trailing comma after the last value of an array declaration.
Loading history...
512
    ];
513
    if (!$web_app->assim_move) {
514
        $x[] = "Download Results";
515
    }
516
    row_heading_array($x);
517
    foreach($wus as $wu) {
518
        $resultid = $wu->canonical_resultid;
519
        if ($resultid) {
520
            $y = '<font color="green">completed</font>';
521
            $text = "<a href=get_output2.php?cmd=workunit&wu_id=$wu->id>Download output files</a>";
522
        } else {
523
            $text = "---";
524
            if ($batch->state == BATCH_STATE_COMPLETE) {
525
                $y = '<font color="red">failed</font>';
526
            }   else {
527
                $y = "in progress";
528
            }
529
        }
530
        $x = [
531
            "<a href=submit.php?action=query_job&wuid=$wu->id>$wu->name</a>",
532
            $y,
533
        ];
534
        if (!$web_app->assim_move) {
535
            $x[] = $text;
536
        }
537
        row_array($x);
538
    }
539
    end_table();
540
    echo "<p><a href=submit.php>Return to job control page</a>\n";
541
    text_end();
542
    page_tail();
543
}
544
545
// show the details of a job, including links to see the output files
546
//
547
function handle_query_job($user) {
548
    global $web_apps;
549
550
    $wuid = get_int('wuid');
551
    $wu = BoincWorkunit::lookup_id($wuid);
552
    if (!$wu) error_page("no such job");
553
554
    $app = BoincApp::lookup_id($wu->appid);
555
    $web_app = $web_apps[$app->name];
556
557
    page_head("Job $wu->name");
558
    text_start();
559
560
    echo "
561
        <a href=workunit.php?wuid=$wuid>Workunit details</a>
562
        <p>
563
        <a href=submit.php?action=query_batch&batch_id=$wu->batch>Batch $wu->batch</a>
564
    ";
565
566
    echo "<h2>Instances</h2>\n";
567
    start_table();
568
    table_header(
569
        "ID<br><small>click for result page</small>",
570
        "State",
571
        "Output files"
572
    );
573
    $results = BoincResult::enum("workunitid=$wuid");
574
    $upload_dir = parse_config(get_config(), "<upload_dir>");
575
    $fanout = parse_config(get_config(), "<uldl_dir_fanout>");
576
    foreach($results as $result) {
577
        $x = [
578
            "<a href=result.php?resultid=$result->id>$result->id</a>",
579
            state_string($result)
0 ignored issues
show
Coding Style introduced by
There should be a trailing comma after the last value of an array declaration.
Loading history...
580
        ];
581
        $i = 0;
582
        if ($result->server_state == RESULT_SERVER_STATE_OVER) {
583
            $phys_names = get_outfile_names($result);
584
            $log_names = get_outfile_log_names($result);
585
            for ($i=0; $i<count($phys_names); $i++) {
0 ignored issues
show
Coding Style Performance introduced by
The use of count() inside a loop condition is not allowed; assign the return value to a variable and use the variable in the loop condition instead
Loading history...
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
586
                if ($web_app->assim_move) {
587
                    // file is in
588
                    // project/results/<batchid>/<wu_name>__file_<log_name>
589
                    $path = sprintf('results/%s/%s__file_%s',
590
                        $wu->batch, $wu->name, $log_names[$i]
591
                    );
592
                    $x[] = "<a href=get_output3.php?action=get_file&path=$path>view</a> &middot; <a href=get_output3.php?action=get_file&path=$path&download=1>download</a>";
593
                } else {
594
                    // file is in upload hier
595
                    $url = sprintf(
596
                        'get_output2.php?cmd=result&result_id=%d&file_num=%d',
597
                        $result->id, $i
598
                    );
599
                    $path = dir_hier_path($phys_names[$i], $upload_dir, $fanout);
600
                    $s = stat($path);
601
                    $size = $s['size'];
602
                    $x[] = sprintf('<a href=%s>%s</a> (%s bytes)<br/>',
603
                        $url,
604
                        $log_names[$i],
605
                        number_format($size)
606
                    );
607
                }
608
            }
609
        } else {
610
            $x[] = '---';
611
        }
612
        row_array($x);
613
    }
614
    end_table();
615
616
    // show input files
617
    //
618
    echo "<h2>Input files</h2>\n";
619
    $x = "<in>".$wu->xml_doc."</in>";
620
    $x = simplexml_load_string($x);
621
    start_table();
622
    table_header("Name<br><small>(click to view)</small>",
623
        "Size (bytes)", "MD5"
624
    );
625
    foreach ($x->workunit->file_ref as $fr) {
626
        $pname = (string)$fr->file_name;
627
        $lname = (string)$fr->open_name;
628
        foreach ($x->file_info as $fi) {
629
            if ((string)$fi->name == $pname) {
630
                table_row(
631
                    "<a href=$fi->url>$lname</a>",
632
                    $fi->nbytes,
633
                    $fi->md5_cksum
634
                );
635
                break;
636
            }
637
        }
638
    }
639
640
    end_table();
641
    text_end();
642
    echo "<p><a href=submit.php>Return to job control page</a>\n";
643
    page_tail();
644
}
645
646
function handle_abort_batch_confirm() {
647
    $batch_id = get_int('batch_id');
648
    page_head("Confirm abort batch");
649
    echo "
650
        Aborting a batch will cancel all unstarted jobs.
651
        Are you sure you want to do this?
652
        <p>
653
    ";
654
    show_button(
655
        "submit.php?action=abort_batch&batch_id=$batch_id",
656
        "Yes - abort batch"
657
    );
658
    echo "<p><a href=submit.php>Return to job control page</a>\n";
659
    page_tail();
660
}
661
662
function check_access($user, $batch) {
663
    if ($user->id == $batch->user_id) return;
664
    $user_submit = BoincUserSubmit::lookup_userid($user->id);
665
    if ($user_submit->manage_all) return;
666
    $usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$batch->app_id");
667
    if ($usa->manage) return;
668
    error_page("no access");
669
}
670
671
function handle_abort_batch($user) {
672
    $batch_id = get_int('batch_id');
673
    $batch = BoincBatch::lookup_id($batch_id);
674
    if (!$batch) error_page("no such batch");
675
    check_access($user, $batch);
676
    abort_batch($batch);
677
    page_head("Batch aborted");
678
    echo "<p><a href=submit.php>Return to job control page</a>\n";
679
    page_tail();
680
}
681
682
function handle_retire_batch_confirm() {
683
    $batch_id = get_int('batch_id');
684
    page_head("Confirm retire batch");
685
    echo "
686
        Retiring a batch will remove all of its output files.
687
        Are you sure you want to do this?
688
        <p>
689
    ";
690
    show_button(
691
        "submit.php?action=retire_batch&batch_id=$batch_id",
692
        "Yes - retire batch"
693
    );
694
    echo "<p><a href=submit.php>Return to job control page</a>\n";
695
    page_tail();
696
}
697
698
function handle_retire_batch($user) {
699
    $batch_id = get_int('batch_id');
700
    $batch = BoincBatch::lookup_id($batch_id);
701
    if (!$batch) error_page("no such batch");
702
    check_access($user, $batch);
703
    retire_batch($batch);
704
    page_head("Batch retired");
705
    echo "<p><a href=submit.php>Return to job control page</a>\n";
706
    page_tail();
707
}
708
709
function show_batches_in_state($batches, $state) {
710
    switch ($state) {
711
    case BATCH_STATE_IN_PROGRESS:
712
        page_head("Batches in progress");
713
        show_in_progress($batches, 0, null, null);
714
        break;
715
    case BATCH_STATE_COMPLETE:
716
        page_head("Completed batches");
717
        show_complete($batches, 0, null, null);
718
        break;
719
    case BATCH_STATE_ABORTED:
720
        page_head("Aborted batches");
721
        show_aborted($batches, 0, null, null);
722
        break;
723
    }
724
    page_tail();
725
}
726
727
function handle_show_all($user) {
728
    $userid = get_int("userid");
729
    $appid = get_int("appid");
730
    $state = get_int("state");
731
    if ($userid) {
732
        // user looking at their own batches
733
        //
734
        if ($userid != $user->id) error_page("wrong user");
735
        $batches = BoincBatch::enum("user_id = $user->id and state=$state order by id desc");
736
        fill_in_app_and_user_names($batches);
737
        show_batches_in_state($batches, $state);
738
    } else {
739
        // admin looking at batches
740
        //
741
        if (!has_admin_access($user, $appid)) {
742
            error_page('no access');
743
        }
744
        if ($appid) {
745
            $app = BoincApp::lookup_id($appid);
746
            if (!$app) error_page("no such app");
747
            $batches = BoincBatch::enum("app_id = $appid and state=$state order by id desc");
748
        } else {
749
            $batches = BoincBatch::enum("state=$state order by id desc");
750
        }
751
        fill_in_app_and_user_names($batches);
752
        show_batches_in_state($batches, $state);
753
    }
754
}
755
756
$user = get_logged_in_user();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $user is correct as get_logged_in_user() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
757
758
$action = get_str('action', true);
759
760
switch ($action) {
761
case '': handle_main($user); break;
762
case 'abort_batch': handle_abort_batch($user); break;
763
case 'abort_batch_confirm': handle_abort_batch_confirm(); break;
764
case 'admin': handle_admin($user); break;
765
case 'admin_app': handle_admin_app($user); break;
766
case 'admin_all': handle_admin_all($user); break;
767
case 'batch_stats': handle_batch_stats($user); break;
768
case 'query_batch': handle_query_batch($user); break;
769
case 'query_job': handle_query_job($user); break;
770
case 'retire_batch': handle_retire_batch($user); break;
771
case 'retire_batch_confirm': handle_retire_batch_confirm(); break;
772
case 'show_all': handle_show_all($user); break;
773
case 'toggle_loc': handle_toggle_loc($user); break;
774
default:
0 ignored issues
show
Coding Style introduced by
DEFAULT keyword must be indented 4 spaces from SWITCH keyword
Loading history...
Coding Style introduced by
DEFAULT case must have a breaking statement
Loading history...
775
    error_page("no such action $action");
776
}
777
778
?>
779