Passed
Push — client_release/8/8.2 ( 7f5819...dcfd1e )
by Vitalii
08:31
created

handle_update_only_own()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
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
// - set '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 return_link() {
38
    echo "<p><a href=submit.php>Return to job submission page</a>\n";
39
}
40
41
// get params of in-progress batches; they might not be in progress anymore.
42
//
43
function get_batches_params($batches) {
44
    $b = [];
45
    foreach ($batches as $batch) {
46
        if ($batch->state == BATCH_STATE_IN_PROGRESS) {
47
            $wus = BoincWorkunit::enum("batch = $batch->id");
48
            $b[] = get_batch_params($batch, $wus);
49
        } else {
50
            $b[] = $batch;
51
        }
52
    }
53
    return $b;
54
}
55
56
function state_count($batches, $state) {
57
    $n = 0;
58
    foreach ($batches as $batch) {
59
        if ($batch->state == $state) $n++;
60
    }
61
    return $n;
62
}
63
64
function show_all_link($batches, $state, $limit, $user, $app) {
65
    $n = state_count($batches, $state);
66
    if ($n > $limit) {
67
        if ($user) $userid = $user->id;
68
        else $userid = 0;
69
        if ($app) $appid = $app->id;
70
        else $appid = 0;
71
72
        echo "Showing the most recent $limit of $n batches.
73
            <a href=submit.php?action=show_all&state=$state&userid=$userid&appid=$appid>Show all $n</a>
74
            <p>
75
        ";
76
    }
77
}
78
79
function show_in_progress($batches, $limit, $user, $app) {
80
    echo "<h3>Batches in progress</h3>\n";
81
    $first = true;
82
    $n = 0;
83
    foreach ($batches as $batch) {
84
        if ($batch->state != BATCH_STATE_IN_PROGRESS) continue;
85
        if ($limit && $n == $limit) break;
86
        $n++;
87
        if ($first) {
88
            $first = false;
89
            if ($limit) {
90
                show_all_link($batches, BATCH_STATE_IN_PROGRESS, $limit, $user, $app);
91
            }
92
            start_table('table-striped');
93
            table_header(
94
                "Name",
95
                "ID",
96
                "User",
97
                "App",
98
                "# jobs",
99
                "Progress",
100
                "Submitted"
101
                //"Logical end time<br><small>Determines priority</small>"
102
            );
103
        }
104
        $pct_done = (int)($batch->fraction_done*100);
105
        table_row(
106
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->name</a>",
107
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->id</a>",
108
            $batch->user_name,
109
            $batch->app_name,
110
            $batch->njobs,
111
            "$pct_done%",
112
            local_time_str($batch->create_time)
113
            //local_time_str($batch->logical_end_time)
114
        );
115
    }
116
    if ($first) {
117
        echo "<p>None.\n";
118
    } else {
119
        end_table();
120
    }
121
}
122
123
function show_complete($batches, $limit, $user, $app) {
124
    $first = true;
125
    $n = 0;
126
    foreach ($batches as $batch) {
127
        if ($batch->state != BATCH_STATE_COMPLETE) continue;
128
        if ($limit && $n == $limit) break;
129
        $n++;
130
        if ($first) {
131
            $first = false;
132
            echo "<h3>Completed batches</h3>\n";
133
            if ($limit) {
134
                show_all_link($batches, BATCH_STATE_COMPLETE, $limit, $user, $app);
135
            }
136
            form_start('submit.php', 'get');
137
            form_input_hidden('action', 'retire_multi');
138
            start_table('table-striped');
139
            table_header(
140
                "Name", "ID", "User", "App", "# Jobs", "Submitted", "Select"
141
            );
142
        }
143
        table_row(
144
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->name</a>",
145
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->id</a>",
146
            $batch->user_name,
147
            $batch->app_name,
148
            $batch->njobs,
149
            local_time_str($batch->create_time),
150
            sprintf('<input type=checkbox name=retire_%d>', $batch->id)
151
        );
152
    }
153
    if ($first) {
154
        echo "<p>No completed batches.\n";
155
    } else {
156
        end_table();
157
        form_submit('Retire selected batches');
158
    }
159
}
160
161
function show_aborted($batches, $limit, $user, $app) {
162
    $first = true;
163
    $n = 0;
164
    foreach ($batches as $batch) {
165
        if ($batch->state != BATCH_STATE_ABORTED) continue;
166
        if ($limit && $n == $limit) break;
167
        $n++;
168
        if ($first) {
169
            $first = false;
170
            echo "<h2>Aborted batches</h2>\n";
171
            if ($limit) {
172
                show_all_link($batches, BATCH_STATE_ABORTED, $limit, $user, $app);
173
            }
174
            start_table();
175
            table_header("name", "ID", "user", "app", "# jobs", "submitted");
176
        }
177
        table_row(
178
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->name</a>",
179
            "<a href=submit.php?action=query_batch&batch_id=$batch->id>$batch->id</a>",
180
            $batch->user_name,
181
            $batch->app_name,
182
            $batch->njobs,
183
            local_time_str($batch->create_time)
184
        );
185
    }
186
    if (!$first) {
187
        end_table();
188
    }
189
}
190
191
// fill in the app and user names in list of batches
192
// TODO: speed this up by making list of app and user IDs
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...
193
// and doing lookup just once.
194
//
195
function fill_in_app_and_user_names(&$batches) {
196
    foreach ($batches as $batch) {
197
        $app = BoincApp::lookup_id($batch->app_id);
198
        if ($app) {
199
            $batch->app_name = $app->name;
200
            if ($batch->description) {
201
                $batch->app_name .= ": $batch->description";
202
            }
203
        } else {
204
            $batch->app_name = "unknown";
205
        }
206
        $user = BoincUser::lookup_id($batch->user_id);
207
        if ($user) {
208
            $batch->user_name = $user->name;
209
        } else {
210
            $batch->user_name = "missing user $batch->user_id";
211
        }
212
    }
213
}
214
215
// show a set of batches
216
//
217
function show_batches($batches, $limit, $user, $app) {
218
    fill_in_app_and_user_names($batches);
219
    $batches = get_batches_params($batches);
220
    show_in_progress($batches, $limit, $user, $app);
221
    show_complete($batches, $limit, $user, $app);
222
    show_aborted($batches, $limit, $user, $app);
223
}
224
225
// show links to per-app job submission forms
226
//
227
function handle_main($user) {
228
    global $web_apps;
229
    $user_submit = BoincUserSubmit::lookup_userid($user->id);
230
    if (!$user_submit) {
231
        error_page("Ask the project admins for permission to submit jobs");
232
    }
233
234
    page_head("Submit jobs");
235
236
    if (!empty($web_apps)) {
237
        // show links to per-app job submission pages
238
        //
239
        foreach ($web_apps as $area => $apps) {
240
            panel($area,
241
                function() use ($apps) {
242
                    foreach ($apps as $app) {
243
                        echo sprintf(
244
                            '<a href=%s><img width=100 src=%s></a>&nbsp;',
245
                            $app[1], $app[2]
246
                        );
247
                    }
248
                }
249
            );
250
        }
251
    }
252
253
    form_start('submit.php');
254
    form_input_hidden('action', 'update_only_own');
255
    form_radio_buttons(
256
        'Jobs you submit can run', 'only_own',
257
        [
258
            [0, 'on any computer'],
259
            [1, 'only on your computers']
0 ignored issues
show
Coding Style introduced by
There should be a trailing comma after the last value of an array declaration.
Loading history...
260
        ],
261
        $user->seti_id
262
    );
263
    form_submit('Update');
264
    form_end();
265
    page_tail();
266
}
267
268
function handle_show_status($user) {
269
    page_head("Job status");
270
    $batches = BoincBatch::enum("user_id = $user->id order by id desc");
271
    get_batches_params($batches);
272
    show_batches($batches, PAGE_SIZE, $user, null);
273
274
    page_tail();
275
}
276
277
function handle_update_only_own($user) {
278
    $val = get_int('only_own');
279
    $user->update("seti_id=$val");
280
    header("Location: submit.php");
281
}
282
283
// show links for everything the user has admin access to
284
//
285
function handle_admin($user) {
286
    $user_submit = BoincUserSubmit::lookup_userid($user->id);
287
    if (!$user_submit) error_page('no access');
288
    page_head("Administer job submission");
289
    if ($user_submit->manage_all) {
290
        // user can administer all apps
291
        //
292
        echo "<li>All applications<br>
293
            <ul>
294
            <li> <a href=submit.php?action=admin_all>View all batches</a>
295
            <li> <a href=manage_project.php>Manage user permissions</a>
296
            </ul>
297
        ";
298
        $apps = BoincApp::enum("deprecated=0");
299
        foreach ($apps as $app) {
300
            echo "
301
                <li>$app->user_friendly_name<br>
302
                <ul>
303
                <li><a href=submit.php?action=admin_app&app_id=$app->id>View batches</a>
304
                <li> <a href=manage_app.php?app_id=$app->id&amp;action=app_version_form>Manage app versions</a>
305
                <li> <a href=manage_app.php?app_id=$app->id&amp;action=permissions_form>Manage user permissions</a>
306
                <li> <a href=manage_app.php?app_id=$app->id&amp;action=batches_form>Manage batches</a>
307
                </ul>
308
            ";
309
        }
310
    } else {
311
        // see if user can administer specific apps
312
        //
313
        $usas = BoincUserSubmitApp::enum("user_id=$user->id");
314
        foreach ($usas as $usa) {
315
            $app = BoincApp::lookup_id($usa->app_id);
316
            echo "<li>$app->user_friendly_name<br>
317
                <a href=submit.php?action=admin_app&app_id=$app->id>Batches</a>
318
            ";
319
            if ($usa->manage) {
320
                echo "&middot;
321
                    <a href=manage_app.php?app_id=$app->id&action=app_version_form>Versions</a>
322
                ";
323
            }
324
        }
325
    }
326
    echo "</ul>\n";
327
    page_tail();
328
}
329
330
function handle_admin_app($user) {
331
    $app_id = get_int("app_id");
332
    $app = BoincApp::lookup_id($app_id);
333
    if (!$app) error_page("no such app");
334
    if (!has_admin_access($user, $app_id)) {
335
        error_page('no access');
336
    }
337
338
    page_head("Administer batches for $app->user_friendly_name");
339
    $batches = BoincBatch::enum("app_id = $app_id order by id desc");
340
    show_batches($batches, PAGE_SIZE, null, $app);
341
    page_tail();
342
}
343
function handle_admin_all($user) {
344
    page_head("Administer batches (all apps)");
345
    $batches = BoincBatch::enum("true order by id desc");
346
    show_batches($batches, PAGE_SIZE, null, null);
347
    page_tail();
348
}
349
350
351
// show the statics of mem/disk usage of jobs in a batch
352
//
353
function handle_batch_stats($user) {
354
    $batch_id = get_int('batch_id');
355
    $batch = BoincBatch::lookup_id($batch_id);
356
    $results = BoincResult::enum("batch = $batch->id");
357
    page_head("Statistics for batch $batch_id");
358
    $n = 0;
359
    $wss_sum = 0;
360
    $swap_sum = 0;
361
    $disk_sum = 0;
362
    $wss_max = 0;
363
    $swap_max = 0;
364
    $disk_max = 0;
365
    foreach ($results as $r) {
366
        if ($r->outcome != RESULT_OUTCOME_SUCCESS) {
367
            continue;
368
        }
369
        // pre-7.3.16 clients don't report usage info
370
        //
371
        if ($r->peak_working_set_size == 0) {
372
            continue;
373
        }
374
        $n++;
375
        $wss_sum += $r->peak_working_set_size;
376
        if ($r->peak_working_set_size > $wss_max) {
377
            $wss_max = $r->peak_working_set_size;
378
        }
379
        $swap_sum += $r->peak_swap_size;
380
        if ($r->peak_swap_size > $swap_max) {
381
            $swap_max = $r->peak_swap_size;
382
        }
383
        $disk_sum += $r->peak_disk_usage;
384
        if ($r->peak_disk_usage > $disk_max) {
385
            $disk_max = $r->peak_disk_usage;
386
        }
387
    }
388
    if ($n == 0) {
389
        echo "No qualifying results.";
390
        page_tail();
391
        return;
392
    }
393
    text_start(800);
394
    start_table('table-striped');
395
    row2("qualifying results", $n);
396
    row2("mean WSS", size_string($wss_sum/$n));
397
    row2("max WSS", size_string($wss_max));
398
    row2("mean swap", size_string($swap_sum/$n));
399
    row2("max swap", size_string($swap_max));
400
    row2("mean disk usage", size_string($disk_sum/$n));
401
    row2("max disk usage", size_string($disk_max));
402
    end_table();
403
    text_end();
404
    page_tail();
405
}
406
407
// return HTML for a color-coded batch progress bar
408
// green: successfully completed jobs
409
// red: failed
410
// light green: in progress
411
// light gray: unsent
412
//
413
function progress_bar($batch, $wus, $width) {
414
    $nsuccess = $batch->njobs_success;
415
    $nerror = $batch->nerror_jobs;
416
    $nin_prog = $batch->njobs_in_prog;
417
    $nunsent = $batch->njobs - $nsuccess - $nerror - $nin_prog;
418
    $w_success = $width*$nsuccess/$batch->njobs;
419
    $w_fail = $width*$nerror/$batch->njobs;
420
    $w_prog = $width*$nin_prog/$batch->njobs;
421
    $w_unsent = $width*$nunsent/$batch->njobs;
422
    $x = '<table height=20><tr>';
423
    if ($w_fail) {
424
        $x .= "<td width=$w_fail bgcolor=red></td>";
425
    }
426
    if ($w_success) {
427
        $x .= "<td width=$w_success bgcolor=green></td>";
428
    }
429
    if ($w_prog) {
430
        $x .= "<td width=$w_prog bgcolor=lightgreen></td>";
431
    }
432
    if ($w_unsent) {
433
        $x .= "<td width=$w_unsent bgcolor=lightgray></td>";
434
    }
435
    $x .= "</tr></table>
436
        <strong>
437
        <font color=red>$nerror fail</font> &middot;
438
        <font color=green>$nsuccess success</font> &middot;
439
        <font color=lightgreen>$nin_prog in progress</font> &middot;
440
        <font color=lightgray>$nunsent unsent</font>
441
        </strong>
442
    ";
443
    return $x;
444
}
445
446
// show the details of an existing batch
447
//
448
function handle_query_batch($user) {
449
    $batch_id = get_int('batch_id');
450
    $batch = BoincBatch::lookup_id($batch_id);
451
    $app = BoincApp::lookup_id($batch->app_id);
452
    $wus = BoincWorkunit::enum("batch = $batch->id");
453
    $batch = get_batch_params($batch, $wus);
454
    if ($batch->user_id == $user->id) {
455
        $owner = $user;
456
    } else {
457
        $owner = BoincUser::lookup_id($batch->user_id);
458
    }
459
460
    $is_assim_move = is_assim_move($app);
461
462
    page_head("Batch $batch_id");
463
    text_start(800);
464
    start_table();
465
    row2("name", $batch->name);
466
    if ($batch->description) {
467
        row2('description', $batch->description);
468
    }
469
    if ($owner) {
470
        row2('submitter', $owner->name);
471
    }
472
    row2("application", $app?$app->name:'---');
473
    row2("state", batch_state_string($batch->state));
474
    //row2("# jobs", $batch->njobs);
475
    //row2("# error jobs", $batch->nerror_jobs);
476
    //row2("logical end time", time_str($batch->logical_end_time));
477
    if ($batch->expire_time) {
478
        row2("expiration time", time_str($batch->expire_time));
479
    }
480
    if ($batch->njobs) {
481
        row2("progress", progress_bar($batch, $wus, 600));
482
    }
483
    if ($batch->completion_time) {
484
        row2("completed", local_time_str($batch->completion_time));
485
    }
486
    row2("GFLOP/hours, estimated", number_format(credit_to_gflop_hours($batch->credit_estimate), 2));
487
    row2("GFLOP/hours, actual", number_format(credit_to_gflop_hours($batch->credit_canonical), 2));
488
    if (!$is_assim_move) {
489
        row2("Total size of output files",
490
            size_string(batch_output_file_size($batch->id))
491
        );
492
    }
493
    end_table();
494
    echo "<p>";
495
496
    if ($is_assim_move) {
497
        $url = "get_output3.php?action=get_batch&batch_id=$batch->id";
498
    } else {
499
        $url = "get_output2.php?cmd=batch&batch_id=$batch->id";
500
    }
501
    echo "<p>";
502
    show_button($url, "Get zipped output files");
503
    echo "<p>";
504
    switch ($batch->state) {
505
    case BATCH_STATE_IN_PROGRESS:
506
        show_button(
507
            "submit.php?action=abort_batch&batch_id=$batch_id",
508
            "Abort batch"
509
        );
510
        break;
511
    case BATCH_STATE_COMPLETE:
512
    case BATCH_STATE_ABORTED:
513
        show_button(
514
            "submit.php?action=retire_batch&batch_id=$batch_id",
515
            "Retire batch"
516
        );
517
        break;
518
    }
519
    echo "<p>";
520
    show_button("submit.php?action=batch_stats&batch_id=$batch_id",
521
        "Show memory/disk usage statistics"
522
    );
523
524
    echo "<h2>Jobs</h2>\n";
525
    start_table();
526
    $x = [
527
        "Name <br><small>click for details</small>",
528
        "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...
529
    ];
530
    if (!$is_assim_move) {
531
        $x[] = "Download Results";
532
    }
533
    row_heading_array($x);
534
    foreach($wus as $wu) {
535
        $resultid = $wu->canonical_resultid;
536
        if ($resultid) {
537
            $y = '<font color="green">completed</font>';
538
            $text = "<a href=get_output2.php?cmd=workunit&wu_id=$wu->id>Download output files</a>";
539
        } else {
540
            $text = "---";
541
            if ($batch->state == BATCH_STATE_COMPLETE) {
542
                $y = '<font color="red">failed</font>';
543
            }   else {
544
                $y = "in progress";
545
            }
546
        }
547
        $x = [
548
            "<a href=submit.php?action=query_job&wuid=$wu->id>$wu->name</a>",
549
            $y,
550
        ];
551
        if (!$is_assim_move) {
552
            $x[] = $text;
553
        }
554
        row_array($x);
555
    }
556
    end_table();
557
    return_link();
558
    text_end();
559
    page_tail();
560
}
561
562
// Does the assimilator for the given app move output files
563
// to a results/<batchid>/ directory?
564
// This info is stored in the $web_apps data structure in project.inc
565
//
566
function is_assim_move($app) {
567
    global $web_apps;
568
    if (empty($web_apps)) return false;
569
    foreach ($web_apps as $name => $apps) {
570
        foreach ($apps as $web_app) {
571
            if ($web_app[0] == $app->name) {
572
                return $web_app[3];
573
            }
574
        }
575
    }
576
    return false;
577
}
578
579
// show the details of a job, including links to see the output files
580
//
581
function handle_query_job($user) {
582
    $wuid = get_int('wuid');
583
    $wu = BoincWorkunit::lookup_id($wuid);
584
    if (!$wu) error_page("no such job");
585
586
    $app = BoincApp::lookup_id($wu->appid);
587
    $is_assim_move = is_assim_move($app);
588
589
    page_head("Job '$wu->name'");
590
    text_start(800);
591
592
    echo "
593
        <li><a href=workunit.php?wuid=$wuid>Workunit details</a>
594
        <p>
595
        <li><a href=submit.php?action=query_batch&batch_id=$wu->batch>Batch details</a>
596
    ";
597
598
    echo "<h2>Job instances</h2>\n";
599
    start_table('table-striped');
600
    table_header(
601
        "ID<br><small>click for details and stderr</small>",
602
        "State",
603
        "Output files"
604
    );
605
    $results = BoincResult::enum("workunitid=$wuid");
606
    $upload_dir = parse_config(get_config(), "<upload_dir>");
607
    $fanout = parse_config(get_config(), "<uldl_dir_fanout>");
608
    foreach($results as $result) {
609
        $x = [
610
            "<a href=result.php?resultid=$result->id>$result->id</a>",
611
            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...
612
        ];
613
        $i = 0;
614
        if ($result->server_state == RESULT_SERVER_STATE_OVER) {
615
            $phys_names = get_outfile_phys_names($result);
616
            $log_names = get_outfile_log_names($result);
617
            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...
618
                if ($is_assim_move) {
619
                    // file is in
620
                    // project/results/<batchid>/<wu_name>__file_<log_name>
621
                    $path = sprintf('results/%s/%s__file_%s',
622
                        $wu->batch, $wu->name, $log_names[$i]
623
                    );
624
                    $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>";
625
                } else {
626
                    $path = dir_hier_path(
627
                        $phys_names[$i], $upload_dir, $fanout
628
                    );
629
                    if (file_exists($path)) {
630
                        $url = sprintf(
631
                            'get_output2.php?cmd=result&result_id=%d&file_num=%d',
632
                            $result->id, $i
633
                        );
634
                        $s = stat($path);
635
                        $size = $s['size'];
636
                        $x[] = sprintf('<a href=%s>%s</a> (%s bytes)<br/>',
637
                            $url,
638
                            $log_names[$i],
639
                            number_format($size)
640
                        );
641
                    } else {
642
                        $x[] = sprintf("file '%s' is missing", $log_names[$i]);
643
                    }
644
                }
645
            }
646
        } else {
647
            $x[] = '---';
648
        }
649
        row_array($x);
650
    }
651
    end_table();
652
653
    // show input files
654
    //
655
    echo "<h2>Input files</h2>\n";
656
    $x = "<in>".$wu->xml_doc."</in>";
657
    $x = simplexml_load_string($x);
658
    start_table('table-striped');
659
    table_header("Name<br><small>(click to view)</small>", "Size (bytes)");
660
    foreach ($x->workunit->file_ref as $fr) {
661
        $pname = (string)$fr->file_name;
662
        $lname = (string)$fr->open_name;
663
        foreach ($x->file_info as $fi) {
664
            if ((string)$fi->name == $pname) {
665
                table_row(
666
                    "<a href=$fi->url>$lname</a>",
667
                    $fi->nbytes
668
                );
669
                break;
670
            }
671
        }
672
    }
673
674
    end_table();
675
    text_end();
676
    return_link();
677
    page_tail();
678
}
679
680
// is user allowed to retire or abort this batch?
681
//
682
function check_access($user, $batch) {
683
    if ($user->id == $batch->user_id) return;
684
    $user_submit = BoincUserSubmit::lookup_userid($user->id);
685
    if ($user_submit->manage_all) return;
686
    $usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$batch->app_id");
687
    if ($usa->manage) return;
688
    error_page("no access");
689
}
690
691
function handle_abort_batch() {
692
    $batch_id = get_int('batch_id');
693
    $batch = BoincBatch::lookup_id($batch_id);
694
    if (!$batch) error_page("no such batch");
695
    check_access($user, $batch);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $user seems to be never defined.
Loading history...
696
697
    if (get_int('confirmed', true)) {
698
        abort_batch($batch);
699
        page_head("Batch aborted");
700
        return_link();
701
        page_tail();
702
    } else {
703
        page_head("Confirm abort batch");
704
        echo "
705
            Aborting a batch will cancel all unstarted jobs.
706
            Are you sure you want to do this?
707
            <p>
708
        ";
709
        show_button(
710
            "submit.php?action=abort_batch&batch_id=$batch_id&confirmed=1",
711
            "Yes - abort batch"
712
        );
713
        return_link();
714
        page_tail();
715
    }
716
}
717
718
function handle_retire_batch($user) {
719
    $batch_id = get_int('batch_id');
720
    $batch = BoincBatch::lookup_id($batch_id);
721
    if (!$batch) error_page("no such batch");
722
    check_access($user, $batch);
723
724
    if (get_int('confirmed', true)) {
725
        retire_batch($batch);
726
        page_head("Batch retired");
727
        return_link();
728
        page_tail();
729
    } else {
730
        page_head("Confirm retire batch");
731
        echo "
732
            Retiring a batch will remove all of its output files.
733
            Are you sure you want to do this?
734
            <p>
735
        ";
736
        show_button(
737
            "submit.php?action=retire_batch&batch_id=$batch_id&confirmed=1",
738
            "Yes - retire batch"
739
        );
740
        return_link();
741
        page_tail();
742
    }
743
}
744
745
function handle_retire_multi($user) {
746
    $batches = BoincBatch::enum(
747
        sprintf('user_id=%d and state=%d', $user->id, BATCH_STATE_COMPLETE)
748
    );
749
    page_head('Retiring batches');
750
    foreach ($batches as $batch) {
751
        $x = sprintf('retire_%d', $batch->id);
752
        if (get_str($x, true) == 'on') {
753
            retire_batch($batch);
754
            echo "<p>retired batch $batch->name\n";
755
        }
756
    }
757
    return_link();
758
    page_tail();
759
}
760
761
function show_batches_in_state($batches, $state) {
762
    switch ($state) {
763
    case BATCH_STATE_IN_PROGRESS:
764
        page_head("Batches in progress");
765
        show_in_progress($batches, 0, null, null);
766
        break;
767
    case BATCH_STATE_COMPLETE:
768
        page_head("Completed batches");
769
        show_complete($batches, 0, null, null);
770
        break;
771
    case BATCH_STATE_ABORTED:
772
        page_head("Aborted batches");
773
        show_aborted($batches, 0, null, null);
774
        break;
775
    }
776
    page_tail();
777
}
778
779
function handle_show_all($user) {
780
    $userid = get_int("userid");
781
    $appid = get_int("appid");
782
    $state = get_int("state");
783
    if ($userid) {
784
        // user looking at their own batches
785
        //
786
        if ($userid != $user->id) error_page("wrong user");
787
        $batches = BoincBatch::enum("user_id = $user->id and state=$state order by id desc");
788
        fill_in_app_and_user_names($batches);
789
        show_batches_in_state($batches, $state);
790
    } else {
791
        // admin looking at batches
792
        //
793
        if (!has_admin_access($user, $appid)) {
794
            error_page('no access');
795
        }
796
        if ($appid) {
797
            $app = BoincApp::lookup_id($appid);
798
            if (!$app) error_page("no such app");
799
            $batches = BoincBatch::enum("app_id = $appid and state=$state order by id desc");
800
        } else {
801
            $batches = BoincBatch::enum("state=$state order by id desc");
802
        }
803
        fill_in_app_and_user_names($batches);
804
        show_batches_in_state($batches, $state);
805
    }
806
}
807
808
$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...
809
810
$action = get_str('action', true);
811
812
switch ($action) {
813
case '': handle_main($user); break;
814
case 'abort_batch': handle_abort_batch($user); break;
0 ignored issues
show
Unused Code introduced by
The call to handle_abort_batch() has too many arguments starting with $user. ( Ignorable by Annotation )

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

814
case 'abort_batch': /** @scrutinizer ignore-call */ handle_abort_batch($user); break;

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
815
case 'admin': handle_admin($user); break;
816
case 'admin_app': handle_admin_app($user); break;
817
case 'admin_all': handle_admin_all($user); break;
818
case 'batch_stats': handle_batch_stats($user); break;
819
case 'query_batch': handle_query_batch($user); break;
820
case 'query_job': handle_query_job($user); break;
821
case 'retire_batch': handle_retire_batch($user); break;
822
case 'retire_multi': handle_retire_multi($user); break;
823
case 'show_all': handle_show_all($user); break;
824
case 'status': handle_show_status($user); break;
825
case 'update_only_own': handle_update_only_own($user); break;
826
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...
827
    error_page("no such action $action");
828
}
829
830
?>
831