Passed
Pull Request — master (#5918)
by David
13:04
created

handle_query_batch()   F

Complexity

Conditions 16
Paths 3584

Size

Total Lines 107
Code Lines 81

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 81
nc 3584
nop 1
dl 0
loc 107
rs 1.5345
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
    $first = true;
62
    $n = 0;
63
    foreach ($batches as $batch) {
64
        if ($batch->state != BATCH_STATE_IN_PROGRESS) continue;
65
        if ($limit && $n == $limit) break;
66
        $n++;
67
        if ($first) {
68
            $first = false;
69
            echo "<h2>Batches in progress</h2>\n";
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>No in-progress batches.\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
function check_admin_access($user, $app_id) {
277
    $user_submit = BoincUserSubmit::lookup_userid($user->id);
278
    if (!$user_submit) error_page("no access");
279
    if ($app_id) {
280
        if (!$user_submit->manage_all) {
281
            $usa = BoincUserSubmitApp::lookup("user_id = $user->id and app_id=$app_id");
282
            if (!$usa) error_page("no access");
283
        }
284
    } else {
285
        if (!$user_submit->manage_all) error_page("no access");
286
    }
287
}
288
289
function handle_admin() {
290
    page_head("Administer job submission");
291
    if ($user_submit->manage_all) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $user_submit seems to be never defined.
Loading history...
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
        foreach ($usas as $usa) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $usas seems to be never defined.
Loading history...
312
            $app = BoincApp::lookup_id($usa->app_id);
313
            echo "<li>$app->user_friendly_name<br>
314
                <a href=submit.php?action=admin_app&app_id=$app->id>Batches</a>
315
            ";
316
            if ($usa->manage) {
317
                echo "&middot;
318
                    <a href=manage_app.php?app_id=$app->id&action=app_version_form>Versions</a>
319
                ";
320
            }
321
        }
322
    }
323
    echo "</ul>\n";
324
    page_tail();
325
}
326
327
function handle_admin_app($user) {
328
    $app_id = get_int("app_id");
329
    check_admin_access($user, $app_id);
330
    $app = BoincApp::lookup_id($app_id);
331
    if (!$app) error_page("no such app");
332
333
    page_head("Administer batches for $app->user_friendly_name");
334
    $batches = BoincBatch::enum("app_id = $app_id order by id desc");
335
    show_batches($batches, PAGE_SIZE, null, $app);
336
    page_tail();
337
}
338
function handle_admin_all($user) {
339
    page_head("Administer batches (all apps)");
340
    $batches = BoincBatch::enum("true order by id desc");
341
    show_batches($batches, PAGE_SIZE, null, null);
342
    page_tail();
343
}
344
345
346
// show the statics of mem/disk usage of jobs in a batch
347
//
348
function handle_batch_stats($user) {
349
    $batch_id = get_int('batch_id');
350
    $batch = BoincBatch::lookup_id($batch_id);
351
    $results = BoincResult::enum("batch = $batch->id");
352
    page_head("Statistics for batch $batch_id");
353
    $n = 0;
354
    $wss_sum = 0;
355
    $swap_sum = 0;
356
    $disk_sum = 0;
357
    $wss_max = 0;
358
    $swap_max = 0;
359
    $disk_max = 0;
360
    foreach ($results as $r) {
361
        if ($r->outcome != RESULT_OUTCOME_SUCCESS) {
362
            continue;
363
        }
364
        // pre-7.3.16 clients don't report usage info
365
        //
366
        if ($r->peak_working_set_size == 0) {
367
            continue;
368
        }
369
        $n++;
370
        $wss_sum += $r->peak_working_set_size;
371
        if ($r->peak_working_set_size > $wss_max) {
372
            $wss_max = $r->peak_working_set_size;
373
        }
374
        $swap_sum += $r->peak_swap_size;
375
        if ($r->peak_swap_size > $swap_max) {
376
            $swap_max = $r->peak_swap_size;
377
        }
378
        $disk_sum += $r->peak_disk_usage;
379
        if ($r->peak_disk_usage > $disk_max) {
380
            $disk_max = $r->peak_disk_usage;
381
        }
382
    }
383
    if ($n == 0) {
384
        echo "No qualifying results.";
385
        page_tail();
386
        return;
387
    }
388
    text_start();
389
    start_table('table-striped');
390
    row2("qualifying results", $n);
391
    row2("mean WSS", size_string($wss_sum/$n));
392
    row2("max WSS", size_string($wss_max));
393
    row2("mean swap", size_string($swap_sum/$n));
394
    row2("max swap", size_string($swap_max));
395
    row2("mean disk usage", size_string($disk_sum/$n));
396
    row2("max disk usage", size_string($disk_max));
397
    end_table();
398
    text_end();
399
    page_tail();
400
}
401
402
// return HTML for a color-coded batch progress bar
403
// green: successfully completed jobs
404
// red: failed
405
// light green: in progress
406
// light gray: unsent
407
//
408
function progress_bar($batch, $wus, $width) {
409
    $w_success = $width*$batch->fraction_done;
410
    $w_fail = $width*$batch->nerror_jobs/$batch->njobs;
411
    $nsuccess = $batch->njobs * $batch->fraction_done;
412
    $nsent = wus_nsent($wus);
413
    $nprog = $nsent - $nsuccess - $batch->nerror_jobs;
414
    $w_prog = $width*$nprog/$batch->njobs;
415
    $nunsent = $batch->njobs-$nsent;
416
    $w_unsent = $width*$nunsent/$batch->njobs;
417
    $x = '<table height=20><tr>';
418
    if ($w_fail) {
419
        $x .= "<td width=$w_fail bgcolor=red></td>";
420
    }
421
    if ($w_success) {
422
        $x .= "<td width=$w_success bgcolor=green></td>";
423
    }
424
    if ($w_prog) {
425
        $x .= "<td width=$w_prog bgcolor=lightgreen></td>";
426
    }
427
    if ($w_unsent) {
428
        $x .= "<td width=$w_unsent bgcolor=lightgray></td>";
429
    }
430
    $x .= "</tr></table>
431
        <strong>
432
        <font color=red>$batch->nerror_jobs fail</font> &middot;
433
        <font color=green>$nsuccess success</font> &middot;
434
        <font color=lightgreen>$nprog in progress</font> &middot;
435
        <font color=lightgray>$nunsent unsent</font>
436
        </strong>
437
    ";
438
    return $x;
439
}
440
441
// show the details of an existing batch
442
//
443
function handle_query_batch($user) {
444
    global $web_apps;
445
446
    $batch_id = get_int('batch_id');
447
    $batch = BoincBatch::lookup_id($batch_id);
448
    $app = BoincApp::lookup_id($batch->app_id);
449
    $wus = BoincWorkunit::enum("batch = $batch->id");
450
    $batch = get_batch_params($batch, $wus);
451
    if ($batch->user_id == $user->id) {
452
        $owner = $user;
453
    } else {
454
        $owner = BoincUser::lookup_id($batch->user_id);
455
    }
456
457
    $web_app = $web_apps[$app->name];
458
459
    page_head("Batch $batch_id");
460
    text_start();
461
    start_table();
462
    row2("name", $batch->name);
463
    if ($batch->description) {
464
        row2('description', $batch->description);
465
    }
466
    if ($owner) {
467
        row2('submitter', $owner->name);
468
    }
469
    row2("application", $app?$app->name:'---');
470
    row2("state", batch_state_string($batch->state));
471
    //row2("# jobs", $batch->njobs);
472
    //row2("# error jobs", $batch->nerror_jobs);
473
    //row2("logical end time", time_str($batch->logical_end_time));
474
    if ($batch->expire_time) {
475
        row2("expiration time", time_str($batch->expire_time));
476
    }
477
    row2("progress", progress_bar($batch, $wus, 600));
478
    if ($batch->completion_time) {
479
        row2("completed", local_time_str($batch->completion_time));
480
    }
481
    row2("GFLOP/hours, estimated", number_format(credit_to_gflop_hours($batch->credit_estimate), 2));
482
    row2("GFLOP/hours, actual", number_format(credit_to_gflop_hours($batch->credit_canonical), 2));
483
    row2("Output File Size", size_string(batch_output_file_size($batch->id)));
484
    end_table();
485
486
    if ($web_app->assim_move) {
487
        $url = "get_output3.php?action=get_batch&batch_id=$batch->id";
488
    } else {
489
        $url = "get_output2.php?cmd=batch&batch_id=$batch->id";
490
    }
491
    echo "<p>";
492
    show_button($url, "Get zipped output files");
493
    echo "<p>";
494
    switch ($batch->state) {
495
    case BATCH_STATE_IN_PROGRESS:
496
        show_button(
497
            "submit.php?action=abort_batch_confirm&batch_id=$batch_id",
498
            "Abort batch"
499
        );
500
        break;
501
    case BATCH_STATE_COMPLETE:
502
    case BATCH_STATE_ABORTED:
503
        show_button(
504
            "submit.php?action=retire_batch_confirm&batch_id=$batch_id",
505
            "Retire batch"
506
        );
507
        break;
508
    }
509
    echo "<p>";
510
    show_button("submit.php?action=batch_stats&batch_id=$batch_id",
511
        "Show memory/disk usage statistics"
512
    );
513
514
    echo "<h2>Jobs</h2>\n";
515
    start_table();
516
    $x = [
517
        "Name <br><small>click for details</small>",
518
        "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...
519
    ];
520
    if (!$web_app->assim_move) {
521
        $x[] = "Download Results";
522
    }
523
    row_heading_array($x);
524
    foreach($wus as $wu) {
525
        $resultid = $wu->canonical_resultid;
526
        if ($resultid) {
527
            $y = '<font color="green">completed</font>';
528
            $text = "<a href=get_output2.php?cmd=workunit&wu_id=$wu->id>Download output files</a>";
529
        } else {
530
            $text = "---";
531
            if ($batch->state == BATCH_STATE_COMPLETE) {
532
                $y = '<font color="red">failed</font>';
533
            }   else {
534
                $y = "in progress";
535
            }
536
        }
537
        $x = [
538
            "<a href=submit.php?action=query_job&wuid=$wu->id>$wu->name</a>",
539
            $y,
540
        ];
541
        if (!$web_app->assim_move) {
542
            $x[] = $text;
543
        }
544
        row_array($x);
545
    }
546
    end_table();
547
    echo "<p><a href=submit.php>Return to job control page</a>\n";
548
    text_end();
549
    page_tail();
550
}
551
552
// show the details of a job, including links to see the output files
553
//
554
function handle_query_job($user) {
555
    global $web_apps;
556
557
    $wuid = get_int('wuid');
558
    $wu = BoincWorkunit::lookup_id($wuid);
559
    if (!$wu) error_page("no such job");
560
561
    $app = BoincApp::lookup_id($wu->appid);
562
    $web_app = $web_apps[$app->name];
563
564
    page_head("Job $wu->name");
565
    text_start();
566
567
    echo "
568
        <a href=workunit.php?wuid=$wuid>Workunit details</a>
569
        <p>
570
        <a href=submit.php?action=query_batch&batch_id=$wu->batch>Batch $wu->batch</a>
571
    ";
572
573
    echo "<h2>Instances</h2>\n";
574
    start_table();
575
    table_header(
576
        "ID<br><small>click for result page</small>",
577
        "State",
578
        "Output files"
579
    );
580
    $results = BoincResult::enum("workunitid=$wuid");
581
    $upload_dir = parse_config(get_config(), "<upload_dir>");
582
    $fanout = parse_config(get_config(), "<uldl_dir_fanout>");
583
    foreach($results as $result) {
584
        $x = [
585
            "<a href=result.php?resultid=$result->id>$result->id</a>",
586
            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...
587
        ];
588
        $i = 0;
589
        if ($result->server_state == RESULT_SERVER_STATE_OVER) {
590
            $phys_names = get_outfile_names($result);
591
            $log_names = get_outfile_log_names($result);
592
            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...
593
                if ($web_app->assim_move) {
594
                    // file is in
595
                    // project/results/<batchid>/<wu_name>__file_<log_name>
596
                    $path = sprintf('results/%s/%s__file_%s',
597
                        $wu->batch, $wu->name, $log_names[$i]
598
                    );
599
                    $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>";
600
                } else {
601
                    // file is in upload hier
602
                    $url = sprintf(
603
                        'get_output2.php?cmd=result&result_id=%d&file_num=%d',
604
                        $result->id, $i
605
                    );
606
                    $path = dir_hier_path($phys_names[$i], $upload_dir, $fanout);
607
                    $s = stat($path);
608
                    $size = $s['size'];
609
                    $x[] = sprintf('<a href=%s>%s</a> (%s bytes)<br/>',
610
                        $url,
611
                        $log_names[$i],
612
                        number_format($size)
613
                    );
614
                }
615
            }
616
        } else {
617
            $x[] = '---';
618
        }
619
        row_array($x);
620
    }
621
    end_table();
622
623
    // show input files
624
    //
625
    echo "<h2>Input files</h2>\n";
626
    $x = "<in>".$wu->xml_doc."</in>";
627
    $x = simplexml_load_string($x);
628
    start_table();
629
    table_header("Name<br><small>(click to view)</small>",
630
        "Size (bytes)", "MD5"
631
    );
632
    foreach ($x->workunit->file_ref as $fr) {
633
        $pname = (string)$fr->file_name;
634
        $lname = (string)$fr->open_name;
635
        foreach ($x->file_info as $fi) {
636
            if ((string)$fi->name == $pname) {
637
                table_row(
638
                    "<a href=$fi->url>$lname</a>",
639
                    $fi->nbytes,
640
                    $fi->md5_cksum
641
                );
642
                break;
643
            }
644
        }
645
    }
646
647
    end_table();
648
    text_end();
649
    echo "<p><a href=submit.php>Return to job control page</a>\n";
650
    page_tail();
651
}
652
653
function handle_abort_batch_confirm() {
654
    $batch_id = get_int('batch_id');
655
    page_head("Confirm abort batch");
656
    echo "
657
        Aborting a batch will cancel all unstarted jobs.
658
        Are you sure you want to do this?
659
        <p>
660
    ";
661
    show_button(
662
        "submit.php?action=abort_batch&batch_id=$batch_id",
663
        "Yes - abort batch"
664
    );
665
    echo "<p><a href=submit.php>Return to job control page</a>\n";
666
    page_tail();
667
}
668
669
function check_access($user, $batch) {
670
    if ($user->id == $batch->user_id) return;
671
    $user_submit = BoincUserSubmit::lookup_userid($user->id);
672
    if ($user_submit->manage_all) return;
673
    $usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$batch->app_id");
674
    if ($usa->manage) return;
675
    error_page("no access");
676
}
677
678
function handle_abort_batch($user) {
679
    $batch_id = get_int('batch_id');
680
    $batch = BoincBatch::lookup_id($batch_id);
681
    if (!$batch) error_page("no such batch");
682
    check_access($user, $batch);
683
    abort_batch($batch);
684
    page_head("Batch aborted");
685
    echo "<p><a href=submit.php>Return to job control page</a>\n";
686
    page_tail();
687
}
688
689
function handle_retire_batch_confirm() {
690
    $batch_id = get_int('batch_id');
691
    page_head("Confirm retire batch");
692
    echo "
693
        Retiring a batch will remove all of its output files.
694
        Are you sure you want to do this?
695
        <p>
696
    ";
697
    show_button(
698
        "submit.php?action=retire_batch&batch_id=$batch_id",
699
        "Yes - retire batch"
700
    );
701
    echo "<p><a href=submit.php>Return to job control page</a>\n";
702
    page_tail();
703
}
704
705
function handle_retire_batch($user) {
706
    $batch_id = get_int('batch_id');
707
    $batch = BoincBatch::lookup_id($batch_id);
708
    if (!$batch) error_page("no such batch");
709
    check_access($user, $batch);
710
    retire_batch($batch);
711
    page_head("Batch retired");
712
    echo "<p><a href=submit.php>Return to job control page</a>\n";
713
    page_tail();
714
}
715
716
function show_batches_in_state($batches, $state) {
717
    switch ($state) {
718
    case BATCH_STATE_IN_PROGRESS:
719
        page_head("Batches in progress");
720
        show_in_progress($batches, 0, null, null);
721
        break;
722
    case BATCH_STATE_COMPLETE:
723
        page_head("Completed batches");
724
        show_complete($batches, 0, null, null);
725
        break;
726
    case BATCH_STATE_ABORTED:
727
        page_head("Aborted batches");
728
        show_aborted($batches, 0, null, null);
729
        break;
730
    }
731
    page_tail();
732
}
733
734
function handle_show_all($user) {
735
    $userid = get_int("userid");
736
    $appid = get_int("appid");
737
    $state = get_int("state");
738
    if ($userid) {
739
        // user looking at their own batches
740
        //
741
        if ($userid != $user->id) error_page("wrong user");
742
        $batches = BoincBatch::enum("user_id = $user->id and state=$state order by id desc");
743
        fill_in_app_and_user_names($batches);
744
        show_batches_in_state($batches, $state);
745
    } else {
746
        // admin looking at batches
747
        //
748
        check_admin_access($user, $appid);
749
        if ($appid) {
750
            $app = BoincApp::lookup_id($appid);
751
            if (!$app) error_page("no such app");
752
            $batches = BoincBatch::enum("app_id = $appid and state=$state order by id desc");
753
        } else {
754
            $batches = BoincBatch::enum("state=$state order by id desc");
755
        }
756
        fill_in_app_and_user_names($batches);
757
        show_batches_in_state($batches, $state);
758
    }
759
}
760
761
$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...
762
763
$action = get_str('action', true);
764
765
switch ($action) {
766
case '': handle_main($user); break;
767
case 'abort_batch': handle_abort_batch($user); break;
768
case 'abort_batch_confirm': handle_abort_batch_confirm(); break;
769
case 'admin': handle_admin($user); break;
0 ignored issues
show
Unused Code introduced by
The call to handle_admin() 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

769
case 'admin': /** @scrutinizer ignore-call */ handle_admin($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...
770
case 'admin_app': handle_admin_app($user); break;
771
case 'admin_all': handle_admin_all($user); break;
772
case 'batch_stats': handle_batch_stats($user); break;
773
case 'query_batch': handle_query_batch($user); break;
774
case 'query_job': handle_query_job($user); break;
775
case 'retire_batch': handle_retire_batch($user); break;
776
case 'retire_batch_confirm': handle_retire_batch_confirm(); break;
777
case 'show_all': handle_show_all($user); break;
778
case 'toggle_loc': handle_toggle_loc($user); break;
779
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...
780
    error_page("no such action $action");
781
}
782
783
?>
784