Passed
Push — client_release/8/8.2 ( 0798cc...523f15 )
by Vitalii
08:48
created

app_form()   B

Complexity

Conditions 6
Paths 2

Size

Total Lines 34
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 26
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 34
rs 8.8817
1
<?php
2
// This file is part of BOINC.
3
// https://boinc.berkeley.edu
4
// Copyright (C) 2024 University of California
5
//
6
// BOINC is free software; you can redistribute it and/or modify it
7
// under the terms of the GNU Lesser General Public License
8
// as published by the Free Software Foundation,
9
// either version 3 of the License, or (at your option) any later version.
10
//
11
// BOINC is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
// See the GNU Lesser General Public License for more details.
15
//
16
// You should have received a copy of the GNU Lesser General Public License
17
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
18
19
// web interface for managing BUDA science apps
20
//
21
// in the following, 'app' means BUDA science app
22
// and 'variant' means a variant of one of these (e.g. CPU, GPU)
23
24
require_once('../inc/util.inc');
25
require_once('../inc/sandbox.inc');
26
require_once('../inc/submit_util.inc');
27
28
display_errors();
29
30
$buda_root = "../../buda_apps";
31
32
// scan BUDA apps and variants, and write a file 'buda_plan_classes'
33
// in the project dir with list of plan classes
34
//
35
function write_plan_class_file() {
36
    $pcs = [];
37
    global $buda_root;
38
    if (is_dir($buda_root)) {
39
        $apps = scandir($buda_root);
40
        foreach ($apps as $app) {
41
            if ($app[0] == '.') continue;
42
            if (!is_dir("$buda_root/$app")) continue;
43
            $vars = scandir("$buda_root/$app");
44
            foreach ($vars as $var) {
45
                if ($var[0] == '.') continue;
46
                if (!is_dir("$buda_root/$app/$var")) continue;
47
                $pcs[] = $var;
48
            }
49
        }
50
    }
51
    $pcs = array_unique($pcs);
52
    file_put_contents(
53
        "../../buda_plan_classes",
54
        implode("\n", $pcs)."\n"
55
    );
56
}
57
58
// show list of BUDA apps and variants,
59
// w/ buttons for adding and deleting
60
//
61
function app_list($notice=null) {
62
    global $buda_root;
63
    if (!is_dir($buda_root)) {
64
        mkdir($buda_root);
65
    }
66
    page_head('BOINC Universal Docker App (BUDA)');
67
    if ($notice) {
68
        echo "$notice <p>\n";
69
    }
70
    text_start();
71
    echo "
72
        <p>BUDA lets you submit Docker jobs using a web interface.
73
        <a href=https://github.com/BOINC/boinc/wiki/BUDA-overview>Learn more</a>.
74
        <p>
75
        <h3>BUDA science apps</h3>
76
    ";
77
78
    $dirs = scandir($buda_root);
79
    foreach ($dirs as $dir) {
80
        if ($dir[0] == '.') continue;
81
        panel("$dir",
82
            function() use ($dir) {
83
                show_app($dir);
84
            }
85
        );
86
    }
87
    show_button_small('buda.php?action=app_form', 'Add science app');
88
    text_end();
89
    page_tail();
90
}
91
92
function show_app($dir) {
93
    global $buda_root;
94
    $desc = null;
95
    $desc_path = "$buda_root/$dir/desc.json";
96
    $desc = json_decode(file_get_contents($desc_path));
97
    echo '<hr>';
98
    echo sprintf('<h3>%s</h3>', $desc->long_name);
99
    echo sprintf('<a href=buda.php?action=app_details&name=%s>Details</a>',
100
        $desc->name
101
    );
102
    $vars = get_buda_variants($dir);
103
    if ($vars) {
104
        echo "<p>Variants:<ul>";
105
        foreach ($vars as $var) {
106
            echo sprintf(
107
                '<li><a href=buda.php?action=variant_view&app=%s&variant=%s>%s</a>',
108
                $dir, $var, $var
109
            );
110
        }
111
        echo '</ul>';
112
    } else {
113
        echo '<p>No variants';
114
    }
115
    end_table();
116
    echo "<p>";
117
    show_button_small("buda.php?action=variant_form&app=$dir", 'Add variant');
118
    if (!$have_var) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $have_var seems to be never defined.
Loading history...
119
        echo "<p>";
120
        show_button(
121
            "buda.php?action=app_delete&app=$dir",
122
            "Delete app",
123
            null,
124
            'btn btn-xs btn-warning'
125
        );
126
    }
127
}
128
129
function variant_view() {
130
    global $buda_root;
131
    $app = get_str('app');
132
    if (!is_valid_filename($app)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
133
    $variant = get_str('variant');
134
    if (!is_valid_filename($variant)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
135
    page_head("BUDA: variant '$variant' of science app '$app'");
136
    $dir = "$buda_root/$app/$variant";
137
    $desc = json_decode(file_get_contents("$dir/variant.json"));
138
    echo "<h3>Files</h3>";
139
    start_table();
140
    table_header('Dockerfile', 'size', 'md5');
141
    file_row($app, $variant, $dir, $desc->dockerfile);
142
    table_header('App files', '', '');
143
    foreach ($desc->app_files as $f) {
144
        file_row($app, $variant, $dir, $f);
145
    }
146
    table_header('Auto-generated files', '', '');
147
    file_row($app, $variant, $dir, 'template_in');
148
    file_row($app, $variant, $dir, 'template_out');
149
    file_row($app, $variant, $dir, 'variant.json');
150
    end_table();
151
    echo '<hr>';
152
153
    start_table();
154
    row2(
155
        'Input filenames:',
156
        implode(',', $desc->input_file_names)
157
    );
158
    row2(
159
        'Output filenames:',
160
        implode(',', $desc->output_file_names)
161
    );
162
    if (!empty($desc->max_total)) {
163
        row2('Max total instances per job:', $desc->max_total);
164
    } else {
165
        row2('Max total instances per job:', '1');
166
    }
167
    if (!empty($desc->min_nsuccess)) {
168
        row2('Target successful instances per job:', $desc->min_nsuccess);
169
    } else {
170
        row2('Target successful instances per job:', '1');
171
    }
172
    if (!empty($desc->max_delay_days)) {
173
        row2('Max job turnaround time, days:', $desc->max_delay_days);
174
    } else {
175
        row2('Max job turnaround time, days:', '7');
176
    }
177
    end_table();
178
179
    if ($manage_access) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $manage_access seems to be never defined.
Loading history...
180
        echo '<p>';
181
        show_button_small(
182
            "buda.php?action=variant_form&app=$app&variant=$variant",
183
            'Edit variant'
184
        );
185
        echo '<p>';
186
        show_button(
187
            "buda.php?action=variant_delete&app=$app&variant=$variant",
188
            'Delete variant',
189
            null,
190
            'btn btn-xs btn-warning'
191
        );
192
    }
193
    end_table();
194
    show_button(
195
        "buda.php?action=variant_delete&app=$app&variant=$variant",
196
        'Delete variant',
197
        null,
198
        'btn btn-xs btn-warning'
199
    );
200
    page_tail();
201
}
202
203
// form for creating/editing app variant.
204
//
205
function variant_form($user) {
206
    $sbitems = sandbox_select_items($user);
207
    $app = get_str('app');
208
    if (!is_valid_filename($app)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
209
    $variant = get_str('variant', true);
210
211
    if ($variant) {
212
        global $buda_root;
213
        $variant_dir = "$buda_root/$app/$variant";
214
        $variant_desc = json_decode(
215
            file_get_contents("$variant_dir/variant.json")
216
        );
217
        if (!$variant_desc) error_page('no such variant');
218
        page_head_select2("Edit variant $variant of BUDA app $app");
219
    } else {
220
        $variant_desc = new StdClass;
221
        $variant_desc->dockerfile = '';
222
        $variant_desc->app_files = [];
223
        $variant_desc->input_file_names = [];
224
        $variant_desc->output_file_names = [];
225
        $variant_desc->min_nsuccess = 1;
226
        $variant_desc->max_total = 1;
227
        $variant_desc->max_delay_days = 7;
228
        page_head_select2("Create a variant of BUDA app $app");
229
    }
230
    echo "
231
        Details are <a href=https://github.com/BOINC/boinc/wiki/BUDA-job-submission#adding-a-variant>here</a>.
232
    ";
233
    $sb = '<br><small>From your <a href=sandbox.php>file sandbox</a></small>';
234
    $pc = '<br><small>Specify
235
    <a href=https://github.com/BOINC/boinc/wiki/AppPlan>GPU and other requirements</a>';
236
    form_start('buda.php');
237
    form_input_hidden('app', $app);
238
    form_input_hidden('action', 'variant_action');
239
    if ($variant) {
240
        form_input_hidden('variant', $variant);
241
        form_input_hidden('edit', 'true');
242
    } else {
243
        form_input_text("Plan class$pc", 'variant', $variant);
244
    }
245
    form_select("Dockerfile$sb", 'dockerfile', $sbitems, $variant_desc->dockerfile);
246
    form_select2_multi("Application files$sb", 'app_files', $sbitems, $variant_desc->app_files);
247
    form_input_text(
248
        'Input file names<br><small>Space-separated</small>',
249
        'input_file_names',
250
        implode(' ', $variant_desc->input_file_names)
251
    );
252
    form_input_text(
253
        'Output file names<br><small>Space-separated</small>',
254
        'output_file_names',
255
        implode(' ', $variant_desc->output_file_names)
256
    );
257
    form_input_text(
258
        'Run at most this many total instances of each job',
259
        'max_total',
260
        $variant_desc->max_total
261
    );
262
    form_input_text(
263
        'Get this many successful instances of each job
264
            <br><small>(subject to the above limit)</small>
265
        ',
266
        'min_nsuccess',
267
        $variant_desc->min_nsuccess
268
    );
269
    form_input_text(
270
        'Max job turnaround time, days',
271
        'max_delay_days',
272
        $variant_desc->max_delay_days
273
    );
274
    form_submit('OK');
275
    form_end();
276
    page_tail();
277
}
278
279
function buda_file_phys_name($app, $variant, $md5) {
280
    return sprintf('buda_%s_%s_%s', $app, $variant, $md5);
281
}
282
283
// copy file from sandbox to variant dir, and stage to download hier
284
//
285
function copy_and_stage_file($user, $fname, $dir, $app, $variant) {
286
    copy_sandbox_file($user, $fname, $dir);
287
    [$md5, $size] = parse_info_file("$dir/.md5/$fname");
288
    $phys_name = buda_file_phys_name($app, $variant, $md5);
289
    stage_file_aux("$dir/$fname", $md5, $size, $phys_name);
290
    return $phys_name;
291
}
292
293
// create templates and put them in variant dir
294
//
295
function create_templates($variant, $variant_desc, $dir) {
296
    // input template
297
    //
298
    $x = "<input_template>\n";
299
    $ninfiles = 1 + count($variant_desc->input_file_names) + count($variant_desc->app_files);
300
    for ($i=0; $i<$ninfiles; $i++) {
301
        $x .= "   <file_info>\n      <sticky/>\n      <no_delete/>\n      <executable/>\n   </file_info>\n";
302
    }
303
    $x .= "   <workunit>\n";
304
    $x .= file_ref_in($variant_desc->dockerfile);
305
    foreach ($variant_desc->app_files as $fname) {
306
        $x .= file_ref_in($fname);
307
    }
308
    foreach ($variant_desc->input_file_names as $fname) {
309
        $x .= file_ref_in($fname);
310
    }
311
    if ($variant == 'cpu') {
312
        $x .= "      <plan_class></plan_class>\n";
313
    } else {
314
        $x .= "      <plan_class>$variant</plan_class>\n";
315
    }
316
317
    // replication params
318
    //
319
    $x .= sprintf("      <target_nresults>%d</target_nresults>\n",
320
        $variant_desc->min_nsuccess
321
    );
322
    $x .= sprintf("      <min_quorum>%d</min_quorum>\n",
323
        $variant_desc->min_nsuccess
324
    );
325
    $x .= sprintf("      <max_total_results>%d</max_total_results>\n",
326
        $variant_desc->max_total
327
    );
328
329
    $x .= sprintf("      <max_delay>%f</max_delay>\n",
330
        $variant_desc->max_delay_days * 86400.
331
    );
332
333
    $x .= "   </workunit>\n<input_template>\n";
334
    file_put_contents("$dir/template_in", $x);
335
336
    // output template
337
    //
338
    $x = "<output_template>\n";
339
    $i = 0;
340
    foreach ($variant_desc->output_file_names as $fname) {
341
        $x .= file_info_out($i++);
342
    }
343
    $x .= "   <result>\n";
344
    $i = 0;
345
    foreach ($variant_desc->output_file_names as $fname) {
346
        $x .= file_ref_out($i++, $fname);
347
    }
348
    $x .= "   </result>\n</output_template>\n";
349
    file_put_contents("$dir/template_out", $x);
350
}
351
352
// create variant
353
//
354
function variant_action($user) {
355
    global $buda_root;
356
    $variant = get_str('variant');
357
    if (!$variant) $variant = 'cpu';
358
    if (!is_valid_filename($variant)) {
359
        error_page(filename_rules());
360
    }
361
    $app = get_str('app');
362
    if (!is_valid_filename($app)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
363
    $dockerfile = get_str('dockerfile');
364
    if (!is_valid_filename($dockerfile)) {
365
        error_page("Invalid dockerfile name: ".filename_rules());
366
    }
367
    $app_files = get_array('app_files');
368
    foreach ($app_files as $fname) {
369
        if (!is_valid_filename($fname)) {
370
            error_page("Invalid app file name: ".filename_rules());
371
        }
372
    }
373
    $min_nsuccess = get_int('min_nsuccess');
374
    if ($min_nsuccess <= 0) {
375
        error_page('Must specify a positive number of successful instances.');
376
    }
377
    $max_total = get_int('max_total');
378
    if ($max_total <= 0) {
379
        error_page('Must specify a positive max number of instances.');
380
    }
381
    if ($min_nsuccess > $max_total) {
382
        error_page('Target # of successful instances must be <= max total');
383
    }
384
    $max_delay_days = get_str('max_delay_days');
385
    if (!is_numeric($max_delay_days)) {
386
        error_page('Must specify max delay');
387
    }
388
    $max_delay_days = floatval($max_delay_days);
389
    if ($max_delay_days <= 0) {
390
        error_page('Must specify positive max delay');
391
    }
392
393
    $input_file_names = get_str('input_file_names', true);
394
    if ($input_file_names) {
395
        $input_file_names = explode(' ', $input_file_names);
396
        foreach ($input_file_names as $fname) {
397
            if (!is_valid_filename($fname)) {
398
                error_page("Invalid input file name: ".filename_rules());
399
            }
400
        }
401
    } else {
402
        $input_file_names = [];
403
    }
404
405
    $output_file_names = get_str('output_file_names', true);
406
    if ($output_file_names) {
407
        $output_file_names = explode(' ', $output_file_names);
408
        foreach ($output_file_names as $fname) {
409
            if (!is_valid_filename($fname)) {
410
                error_page("Invalid output file name: ".filename_rules());
411
            }
412
        }
413
    } else {
414
        $output_file_names = [];
415
    }
416
417
    $dir = "$buda_root/$app/$variant";
418
    if (get_str('edit', true)) {
419
        system("rm -r $dir");
420
    } else {
421
        if (file_exists($dir)) {
422
            error_page("Variant '$variant' already exists.");
423
        }
424
    }
425
    mkdir($dir);
426
    mkdir("$dir/.md5");
427
428
    // create variant description JSON file
429
    //
430
    $desc = new StdClass;
431
    $desc->dockerfile = $dockerfile;
432
    $desc->app_files = $app_files;
433
    $desc->input_file_names = $input_file_names;
434
    $desc->output_file_names = $output_file_names;
435
    $desc->min_nsuccess = $min_nsuccess;
436
    $desc->max_total = $max_total;
437
    $desc->max_delay_days = $max_delay_days;
438
439
    // copy files from sandbox to variant dir
440
    //
441
    $pname = copy_and_stage_file($user, $dockerfile, $dir, $app, $variant);
442
    $desc->dockerfile_phys = $pname;
443
    $desc->app_files_phys = [];
444
    foreach ($app_files as $fname) {
445
        $pname = copy_and_stage_file($user, $fname, $dir, $app, $variant);
446
        $desc->app_files_phys[] = $pname;
447
    }
448
449
    file_put_contents(
450
        "$dir/variant.json",
451
        json_encode($desc, JSON_PRETTY_PRINT)
452
    );
453
454
    create_templates($variant, $desc, $dir);
455
456
    // Note: we don't currently allow indirect file access.
457
    // If we did, we'd need to create job.toml to mount project dir
458
459
    app_list("Variant $variant added for app $app.");
460
}
461
462
function variant_delete() {
463
    global $buda_root;
464
    $app = get_str('app');
465
    if (!is_valid_filename($app)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
466
    $variant = get_str('variant');
467
    if (!is_valid_filename($variant)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
468
    $confirmed = get_str('confirmed', true);
469
    if ($confirmed) {
470
        $dir = "$buda_root/$app/$variant";
471
        if (!file_exists($dir)) error_page('no such variant');
472
        // delete staged files
473
        //
474
        foreach (scandir("$dir/.md5") as $fname) {
475
            if ($fname[0] == '.') continue;
476
            [$md5, $size] = parse_info_file("$dir/.md5/$fname");
477
            $phys_name = buda_file_phys_name($app, $variant, $md5);
478
            $phys_path = download_hier_path($phys_name);
479
            unlink($phys_path);
480
            unlink("$phys_path.md5");
481
        }
482
        system("rm -r $buda_root/$app/$variant", $ret);
483
        if ($ret) {
484
            error_page("delete failed");
485
        }
486
        $notice = "Variant $variant of app $app removed.";
487
        app_list($notice);
488
    } else {
489
        page_head("Confirm");
490
        echo "<p>Are you sure you want to delete variant $variant of BUDA app $app?  <p>";
491
        show_button(
492
            "buda.php?action=variant_delete&app=$app&variant=$variant&confirmed=yes",
493
            "Yes"
494
        );
495
        page_tail();
496
    }
497
}
498
499
function app_delete() {
500
    global $buda_root;
501
    $app = get_str('app');
502
    if (!is_valid_filename($app)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
503
    $confirmed = get_str('confirmed', true);
504
    if ($confirmed) {
505
        $dir = "$buda_root/$app";
506
        if (!file_exists($dir)) error_page('no such app');
507
        foreach (scandir($dir) as $fname) {
508
            if ($fname[0] == '.') continue;
509
            error_page("You must delete all variants first.");
510
        }
511
        system("rmdir $buda_root/$app", $ret);
512
        if ($ret) {
513
            error_page('delete failed');
514
        }
515
        $notice = "App $app removed.";
516
        app_list($notice);
517
    } else {
518
        page_head('Confirm');
519
        echo "<p>Are you sure you want to delete BUDA science app $app?  <p>";
520
        show_button(
521
            "buda.php?action=app_delete&app=$app&confirmed=yes",
522
            "Yes"
523
        );
524
        page_tail();
525
    }
526
}
527
528
function app_form() {
529
    page_head('Create Docker app');
530
    form_start('buda.php');
531
    form_input_hidden('action', 'app_action');
532
    if ($desc) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $desc seems to be never defined.
Loading history...
533
        form_input_hidden('edit_name', $desc->name);
534
        form_input_hidden('user_id', $desc->user_id);
535
        form_input_hidden('create_time', $desc->create_time);
536
    } else {
537
        form_input_text('Internal name<br><small>No spaces</small>', 'name');
538
    }
539
    form_input_text('User-visible name', 'long_name',
540
        $desc?$desc->long_name:null
541
    );
542
    form_input_textarea(
543
        'Description<br><small>... of what the app does and of the research goals</small>',
544
        'description',
545
        $desc?$desc->description:null
546
    );
547
    form_select2_multi('Science keywords',
548
        'sci_kw',
549
        keyword_select_options(KW_CATEGORY_SCIENCE),
550
        $desc?$desc->sci_kw:null
551
    );
552
    form_input_text(
553
        'URL of web page describing app',
554
        'url',
555
        !empty($desc->url)?$desc->url:''
556
    );
557
    // don't include location keywords;
558
    // various people may submit jobs to this app
559
    form_submit('OK');
560
    form_end();
561
    page_tail();
562
}
563
564
function app_action() {
565
    global $buda_root;
566
    $name = get_str('name');
567
    if (!is_valid_filename($name)) {
568
        error_page(filename_rules());
569
    }
570
    $dir = "$buda_root/$name";
571
    if (file_exists($dir)) {
572
        error_page("App $name already exists.");
573
    }
574
    mkdir($dir);
575
    header("Location: buda.php");
576
}
577
578
function view_file() {
579
    global $buda_root;
580
    $app = get_str('app');
581
    if (!is_valid_filename($app)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
582
    $variant = get_str('variant');
583
    if (!is_valid_filename($variant)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
584
    $fname = get_str('fname');
585
    if (!is_valid_filename($fname)) die('bad arg');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
586
    echo "<pre>\n";
587
    $x = file_get_contents("$buda_root/$app/$variant/$fname");
588
    echo htmlspecialchars($x);
589
    echo "</pre>\n";
590
}
591
592
// check access.
593
// Anyone with submit access to BUDA can add/delete apps and variants.
594
// Might want to refine this at some point
595
596
$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...
597
$buda_app = BoincApp::lookup("name='buda'");
598
if (!$buda_app) error_page('no buda app');
599
if (!has_submit_access($user, $buda_app->id)) {
600
    error_page('no access');
601
}
602
603
$action = get_str('action', true);
604
switch ($action) {
605
case 'app_form':
606
    app_form(); break;
607
case 'app_action':
608
    app_action(); break;
609
case 'app_delete':
610
    app_delete(); break;
611
case 'variant_view':
612
    variant_view($user); break;
0 ignored issues
show
Unused Code introduced by
The call to variant_view() 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

612
    /** @scrutinizer ignore-call */ 
613
    variant_view($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...
613
case 'variant_form':
614
    variant_form($user); break;
615
case 'variant_action':
616
    variant_action($user);
617
    write_plan_class_file();
618
    break;
619
case 'variant_delete':
620
    variant_delete();
621
    write_plan_class_file();
622
    break;
623
case 'view_file':
624
    view_file(); break;
625
case null:
626
    app_list(); break;
627
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...
628
    error_page("unknown action");
629
}
630
631
?>
632