Issues (1963)

html/inc/prefs.inc (9 issues)

1
<?php
2
// This file is part of BOINC.
3
// http://boinc.berkeley.edu
4
// Copyright (C) 2022 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
20
// functions for display and editing global preferences.
21
// Preferences are represented in two ways:
22
// - As a PHP structure (usually called $prefs)
23
//   This has fields run_if_user_active, etc.
24
// - As XML (usually called $prefs_xml)
25
//
26
// This XML has the general structure
27
// <global_preferences>
28
//    <mod_time>...</mod_time>
29
//    <run_if_user_active/>
30
//    <work_buf_min_days>1.3</work_buf_min_days>
31
//    ...
32
//    <venue name="home">
33
//       <run_if_user_active/>
34
//       ...
35
//    </venue>
36
// </global_preferences>
37
//
38
39
// Various functions are defined below for converting between these forms,
40
// and also to/from HTML form elements
41
42
include_once("../inc/prefs_util.inc");
43
include_once("../inc/translation.inc");
44
45
global $in_use_prefs;
46
global $not_in_use_prefs;
47
global $job_prefs;
48
global $disk_prefs;
49
global $net_prefs;
50
51
$in_use_prefs = [
52
    new PREF_NUM(
53
        tra("'In use' means mouse/keyboard input in last"),
54
        tra("This determines when the computer is considered 'in use'."),
55
        "idle_time_to_run",
56
        new NUM_SPEC(tra("minutes"), 1, 9999, 3),
57
        true
0 ignored issues
show
The call to PREF_NUM::__construct() has too many arguments starting with true. ( Ignorable by Annotation )

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

57
    /** @scrutinizer ignore-call */ 
58
    new PREF_NUM(

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...
58
    ),
59
    new PREF_BOOL(
60
        tra("Suspend all computing"),
61
        tra("Check this to suspend computing and file transfers when you're using the computer."),
62
        "run_if_user_active",
63
        true, true
64
    ),
65
    new PREF_BOOL(
66
        tra("Suspend GPU computing"),
67
        tra("Check this to suspend GPU computing when you're using the computer."),
68
        "run_gpu_if_user_active",
69
        false, true
70
    ),
71
    new PREF_NUM(
72
        tra("Use at most"),
73
        // xgettext:no-php-format
74
        tra("Keep some CPUs free for other applications. Example: 75% means use 6 cores on an 8-core CPU."),
75
        "max_ncpus_pct",
76
        // xgettext:no-php-format
77
        new NUM_SPEC(tra("% of the CPUs"), 1, 100, 100)
78
    ),
79
    new PREF_NUM(
80
        tra("Use at most"),
81
        // xgettext:no-php-format
82
        tra("Suspend/resume computing every few seconds to reduce CPU temperature and energy usage. Example: 75% means compute for 3 seconds, wait for 1 second, and repeat."),
83
        "cpu_usage_limit",
84
        // xgettext:no-php-format
85
        new NUM_SPEC(tra("% of CPU time"), 1, 100, 100)
86
    ),
87
    new PREF_OPT_NUM(
88
        tra("Suspend when non-BOINC CPU usage is above"),
89
        tra("Suspend computing when your computer is busy running other programs."),
90
        "suspend_cpu_usage",
91
        new NUM_SPEC("%", 0, 100, 25)
92
    ),
93
    new PREF_NUM(
94
        tra("Use at most"),
95
        tra("Limit the memory used by BOINC when you're using the computer."),
96
        "ram_max_used_busy_pct",
97
        // xgettext:no-php-format
98
        new NUM_SPEC(tra("% of memory"), 1, 100, 50)
99
    ),
100
];
101
$not_in_use_prefs = [
102
    new PREF_NUM(
103
        tra("Use at most")."<br><font size=-2>Requires BOINC 7.20.3+</font>",
104
        // xgettext:no-php-format
105
        tra("Keep some CPUs free for other applications. Example: 75% means use 6 cores on an 8-core CPU."),
106
        "niu_max_ncpus_pct",
107
        // xgettext:no-php-format
108
        new NUM_SPEC(tra("% of the CPUs"), 1, 100, 0)
109
    ),
110
    new PREF_NUM(
111
        tra("Use at most") ."<br><font size=-2>Requires BOINC 7.20.3+</font>",
112
        // xgettext:no-php-format
113
        tra("Suspend/resume computing every few seconds to reduce CPU temperature and energy usage. Example: 75% means compute for 3 seconds, wait for 1 second, and repeat."),
114
        "niu_cpu_usage_limit",
115
        // xgettext:no-php-format
116
        new NUM_SPEC(tra("% of CPU time"), 1, 100, 0)
117
    ),
118
    new PREF_OPT_NUM(
119
        tra("Suspend when non-BOINC CPU usage is above")."<br><font size=-2>Requires BOINC 7.20.3+</font>",
120
        tra("Suspend computing when your computer is busy running other programs."),
121
        "niu_suspend_cpu_usage",
122
        new NUM_SPEC("%", 0, 100, 0)
123
    ),
124
    new PREF_NUM(
125
        tra("Use at most"),
126
        tra("Limit the memory used by BOINC when you're not using the computer."),
127
        "ram_max_used_idle_pct",
128
        // xgettext:no-php-format
129
        new NUM_SPEC(tra("% of memory"), 1, 100, 90)
130
    ),
131
    new PREF_OPT_NUM(
132
        tra("Suspend when no mouse/keyboard input in last"),
133
        tra("This allows some computers to enter low-power mode when not in use."),
134
        "suspend_if_no_recent_input",
135
        new NUM_SPEC(tra("minutes"), 0, 9999, 0, 1, 60)
136
    ),
137
];
138
$job_prefs = [
139
    new PREF_BOOL(
140
        tra("Suspend when computer is on battery"),
141
        tra("Check this to suspend computing on portables when running on battery power."),
142
        "run_on_batteries",
143
        false, true
144
    ),
145
    new PREF_NUM(
146
        tra("Switch between tasks every"),
147
        tra("If you run several projects, BOINC may switch between them this often."),
148
        "cpu_scheduling_period_minutes",
149
        new NUM_SPEC(tra("minutes"), 1, 9999, 60)
150
    ),
151
    new PREF_NUM(
152
        tra("Request tasks to checkpoint at most every"),
153
        tra("This controls how often tasks save their state to disk, so that later they can be continued from that point."),
154
        "disk_interval",
155
        new NUM_SPEC(tra("seconds"), 0, 9999999, 60)
156
    ),
157
    new PREF_BOOL(
158
        tra("Leave non-GPU tasks in memory while suspended"),
159
        tra("If checked, suspended tasks stay in memory, and resume with no work lost. If unchecked, suspended tasks are removed from memory, and resume from their last checkpoint."),
160
        "leave_apps_in_memory",
161
        false
162
    ),
163
    new PREF_NUM(
164
        tra("Store at least"),
165
        tra("Store at least enough tasks to keep the computer busy for this long."),
166
        "work_buf_min_days",
167
        new NUM_SPEC(tra("days of work"), 0, 10, .1)
168
    ),
169
    new PREF_NUM(
170
        tra("Store up to an additional"),
171
        tra("Store additional tasks above the minimum level.  Determines how much work is requested when contacting a project."),
172
        "work_buf_additional_days",
173
        new NUM_SPEC(tra("days of work"), 0, 10, .5)
174
    ),
175
    new PREF_HOUR_RANGE(
176
        tra("Compute only between"),
177
        tra("Compute only during a particular period each day."),
178
        "start_hour", "end_hour"
179
    ),
180
];
181
182
$dp = get_disk_space_config();
183
184
$disk_prefs = array(
185
    new PREF_OPT_NUM(
186
        tra("Use no more than"),
187
        tra("Limit the total amount of disk space used by BOINC."),
188
        "disk_max_used_gb",
189
        new NUM_SPEC(tra("GB"), 0, 9999999, $dp->disk_max_used_gb, 1, 100)
190
    ),
191
    new PREF_OPT_NUM(
192
        tra("Leave at least"),
193
        tra("Limit disk usage to leave this much free space on the volume where BOINC stores data."),
194
        "disk_min_free_gb",
195
        new NUM_SPEC(tra("GB free"), 0, 9999999, $dp->disk_min_free_gb, 1, 1)
196
    ),
197
    new PREF_OPT_NUM(
198
        tra("Use no more than"),
199
        tra("Limit the percentage of disk space used by BOINC on the volume where it stores data."),
200
        "disk_max_used_pct",
201
        // xgettext:no-php-format
202
        new NUM_SPEC(tra("% of total"), 0, 100, $dp->disk_max_used_pct)
203
    ),
204
    new PREF_NUM(
205
        tra("Page/swap file: use at most"),
206
        tra("Limit the swap space (page file) used by BOINC."),
207
        "vm_max_used_pct",
208
        // xgettext:no-php-format
209
        new NUM_SPEC(tra("%"), 1, 100, 75)
210
    ),
211
);
212
213
$net_prefs = array(
214
    new PREF_OPT_NUM(
215
        tra("Limit download rate to"),
216
        tra("Limit the download rate of file transfers."),
217
        "max_bytes_sec_down",
218
        new NUM_SPEC(tra("KB/second"), 0, 9999999, 0, 1024, 100)
219
    ),
220
    new PREF_OPT_NUM(
221
        tra("Limit upload rate to"),
222
        tra("Limit the upload rate of file transfers."),
223
        "max_bytes_sec_up",
224
        new NUM_SPEC(tra("KB/second"), 0, 9999999, 0, 1024, 100)
225
    ),
226
    new PREF_NUM2(
227
        tra("Limit usage to"),
228
        tra("Example: BOINC should transfer at most 2000 MB of data every 30 days."),
229
        "daily_xfer_limit_mb",
230
        "daily_xfer_period_days",
231
        new NUM_SPEC(tra("MB every"), 0, 9999999, 0, 1, 10000),
232
        new NUM_SPEC(tra("days"), 0, 9999999, 0, 1, 30)
233
    ),
234
    new PREF_HOUR_RANGE(
235
        tra("Transfer files only between"),
236
        tra("Transfer files only during a particular period each day."),
237
        "net_start_hour", "net_end_hour"
238
    ),
239
    new PREF_BOOL(
240
        tra("Skip data verification for image files"),
241
        tra("Check this only if your Internet provider modifies image files. Skipping verification reduces the security of BOINC."),
242
        "dont_verify_images",
243
        false
244
    ),
245
    new PREF_BOOL(
246
        tra("Confirm before connecting to Internet"),
247
        tra("Useful only if you have a modem, ISDN or VPN connection."),
248
        "confirm_before_connecting",
249
        false
250
    ),
251
    new PREF_BOOL(
252
        tra("Disconnect when done"),
253
        tra("Useful only if you have a modem, ISDN or VPN connection."),
254
        "hangup_if_dialed",
255
        false
256
    ),
257
);
258
259
define("IN_USE_DESC", tra("When computer is in use"));
260
define("NOT_IN_USE_DESC", tra("When computer is not in use"));
261
define("JOBS_DESC", tra("General"));
262
define("DISK_DESC", tra("Disk"));
263
define("NET_DESC", tra("Network"));
264
265
// These texts are used in multiple places in prefs_edit.php and add_venue.php
266
define("PREFS_FORM_DESC1", tra("These preferences apply to all the BOINC projects in which you participate.")."<br><br>");
267
define("PREFS_FORM_ERROR_DESC",
268
    tra(
269
        "%1 Unable to update preferences. %2 The values marked in red below were out of range or not numeric.",
270
        "<strong>",
271
        "</strong>"
272
    ).
273
    "<br><br>"
274
);
275
276
global $text;
277
global $parse_result;
278
global $top_parse_result;
279
global $venue_name;
280
281
// get default settings for disk space usage so the default user
282
// preferences match the settings used by the scheduler.
283
// Defaults are set if the tags are missing, they depend on
284
// which scheduler is running:
285
// - 'old' has the default hardcoded
286
// - 'new' uses config settings
287
// if running the old scheduler, set <scheduler_disk_space_check_hardcoded>
288
// in config.xml so the right default is set for minimum free disk space
289
//
290
function get_disk_space_config() {
291
    $config = get_config();
292
    $dp = new StdClass;
293
    $dp->disk_max_used_gb = parse_config($config, "<default_disk_max_used_gb>");
294
    $dp->disk_max_used_pct = parse_config($config, "<default_disk_max_used_pct>");
295
    $dp->disk_min_free_gb = parse_config($config, "<default_disk_min_free_gb>");
296
    // set some defaults if not found
297
    if (!$dp->disk_max_used_gb) $dp->disk_max_used_gb = 0;  // no limit
298
    if (!$dp->disk_max_used_pct) $dp->disk_max_used_pct = 90; // 90 percent
299
    if (!$dp->disk_min_free_gb) $dp->disk_min_free_gb = 1;   // 1 GB
300
    // set mininimum free space scheduler allows
301
    // - depends on which scheduler is running
302
    $dp->new_sched_flag = 1;
303
    $dp->sched_disk_min_free_gb = $dp->disk_min_free_gb;
304
    if (parse_config($config, "scheduler_disk_space_check_hardcoded>")) {
305
        $dp->new_sched_flag = 0;
306
        $dp->sched_disk_min_free_gb = 0;
307
    }
308
309
    return $dp;
310
}
311
312
function group_header($t) {
313
    echo "<tr><th class=\"bg-info\">$t</th><td class=\"bg-info\" colspan=4><br></td></tr>\n";
314
}
315
316
// functions to parse preferences XML into a struct
317
//
318
319
function element_start_global($parser, $name, $attrs) {
320
    global $top_parse_result;
321
    global $parse_result;
322
    global $text;
323
    global $venue_name;
324
325
    switch($name) {
326
    case "venue":
327
        if (array_key_exists("name", $attrs)) {
328
            $venue_name = $attrs["name"];
329
        } else {
330
            $venue_name = "home";
331
        }
332
        $top_parse_result = $parse_result;
333
        $parse_result = default_prefs_global();
334
        break;
335
    }
336
    $text = "";
337
}
338
339
function element_end_global($parser, $name) {
340
    global $text;
341
    global $parse_result;
342
    global $top_parse_result;
343
    global $venue_name;
344
    global $in_use_prefs;
345
    global $not_in_use_prefs;
346
    global $job_prefs;
347
    global $disk_prefs;
348
    global $net_prefs;
349
350
    foreach ($in_use_prefs as $p) {
351
        if ($p->xml_parse($parse_result, $name, $text)) {
352
            return;
353
        }
354
    }
355
    foreach ($not_in_use_prefs as $p) {
356
        if ($p->xml_parse($parse_result, $name, $text)) {
357
            return;
358
        }
359
    }
360
    foreach ($job_prefs as $p) {
361
        if ($p->xml_parse($parse_result, $name, $text)) {
362
            return;
363
        }
364
    }
365
    foreach ($disk_prefs as $p) {
366
        if ($p->xml_parse($parse_result, $name, $text)) {
367
            return;
368
        }
369
    }
370
    foreach ($net_prefs as $p) {
371
        if ($p->xml_parse($parse_result, $name, $text)) {
372
            return;
373
        }
374
    }
375
    switch($name) {
376
    case "venue":
377
        $top_parse_result->$venue_name = $parse_result;
378
        $parse_result = $top_parse_result;
379
        break;
380
    case "mod_time":
381
        $parse_result->mod_time = $text;
382
        break;
383
    case "global_preferences":
0 ignored issues
show
Empty CASE statements are not allowed
Loading history...
384
        break;
385
    default:
0 ignored issues
show
DEFAULT keyword must be indented 4 spaces from SWITCH keyword
Loading history...
DEFAULT case must have a breaking statement
Loading history...
386
        //echo "Unknown tag: $name\n";
387
    }
388
}
389
390
function char_handler($parser, $x) {
391
    global $text;
392
    $text = $text.$x;
393
}
394
395
396
// state of prefs before parsing; defines prefs for new users
397
//
398
function default_prefs_global() {
399
    global $in_use_prefs;
400
    global $not_in_use_prefs;
401
    global $job_prefs;
402
    global $disk_prefs;
403
    global $net_prefs;
404
405
    $p = new StdClass;
406
    foreach ($in_use_prefs as $pref) {
407
        $pref->set_default($p);
408
    }
409
    foreach ($not_in_use_prefs as $pref) {
410
        $pref->set_default($p);
411
    }
412
    foreach ($job_prefs as $pref) {
413
        $pref->set_default($p);
414
    }
415
    foreach ($disk_prefs as $pref) {
416
        $pref->set_default($p);
417
    }
418
    foreach ($net_prefs as $pref) {
419
        $pref->set_default($p);
420
    }
421
    return $p;
422
}
423
424
// if not-in-use prefs undefined, copy from in-use
425
//
426
function set_niu_prefs($prefs) {
427
    if (!$prefs->niu_max_ncpus_pct) {
428
        $prefs->niu_max_ncpus_pct = $prefs->max_ncpus_pct;
429
    }
430
    if (!$prefs->niu_cpu_usage_limit) {
431
        $prefs->niu_cpu_usage_limit = $prefs->cpu_usage_limit;
432
    }
433
    if (!$prefs->niu_suspend_cpu_usage) {
434
        $prefs->niu_suspend_cpu_usage = $prefs->suspend_cpu_usage;
435
    }
436
}
437
438
// parse prefs from XML to a struct
439
//
440
function prefs_parse_global($prefs_xml) {
441
    global $parse_result;
442
    $parse_result = default_prefs_global();
443
    $xml_parser = xml_parser_create();
444
    xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
445
    xml_set_element_handler($xml_parser, "element_start_global", "element_end_global");
446
    xml_set_character_data_handler($xml_parser, "char_handler");
447
    xml_parse($xml_parser, $prefs_xml, 1);
448
    set_niu_prefs($parse_result);
449
    return $parse_result;
450
}
451
452
// Display all venues as columns next to descriptions
453
//
454
function prefs_show_columns_global($prefs) {
455
    global $in_use_prefs;
456
    global $not_in_use_prefs;
457
    global $job_prefs;
458
    global $disk_prefs;
459
    global $net_prefs;
460
461
    row_top(IN_USE_DESC);
462
    foreach ($in_use_prefs as $p) {
463
        $p->show_cols($prefs);
464
    }
465
    row_top(NOT_IN_USE_DESC);
466
    foreach ($not_in_use_prefs as $p) {
467
        $p->show_cols($prefs);
468
    }
469
    row_top(JOBS_DESC);
470
    foreach ($job_prefs as $p) {
471
        $p->show_cols($prefs);
472
    }
473
    row_top(DISK_DESC);
474
    foreach ($disk_prefs as $p) {
475
        $p->show_cols($prefs);
476
    }
477
    row_top(NET_DESC);
478
    foreach ($net_prefs as $p) {
479
        $p->show_cols($prefs);
480
    }
481
    row_links("global", $prefs);
482
}
483
484
function prefs_show_global($prefs) {
485
    global $in_use_prefs;
486
    global $not_in_use_prefs;
487
    global $job_prefs;
488
    global $disk_prefs;
489
    global $net_prefs;
490
491
    row1(IN_USE_DESC);
492
    foreach ($in_use_prefs as $p) {
493
        $p->show($prefs);
494
    }
495
    row1(NOT_IN_USE_DESC);
496
    foreach ($not_in_use_prefs as $p) {
497
        $p->show($prefs);
498
    }
499
    row1(JOBS_DESC);
500
    foreach ($job_prefs as $p) {
501
        $p->show($prefs);
502
    }
503
    row1(DISK_DESC);
504
    foreach ($disk_prefs as $p) {
505
        $p->show($prefs);
506
    }
507
    row1(NET_DESC);
508
    foreach ($net_prefs as $p) {
509
        $p->show($prefs);
510
    }
511
}
512
513
function subset_name($subset) {
514
    if ($subset == "global") return tra("Computing");
515
    return PROJECT;
516
}
517
518
function prefs_display_venue($prefs, $venue, $subset) {
519
    global $g_logged_in_user;
520
    $tokens = url_tokens($g_logged_in_user->authenticator);
521
    $x = false;
522
    if (isset($prefs->$venue)) $x = $prefs->$venue;
523
524
    if ($x) {
525
        start_table();
526
        row_heading(tra("Separate preferences for %1", $venue), 'bg-info');
527
        if ($subset == "global") {
528
            prefs_show_global($x);
529
        } else {
530
            prefs_show_project($x);
531
            prefs_show_project_specific($x);
532
        }
533
        row2("<br>",
534
            "<a href=prefs_edit.php?venue=$venue&subset=$subset$tokens>".tra("Edit preferences")."</a>
535
            | <a href=prefs_remove.php?venue=$venue&subset=$subset$tokens>".tra("Remove")."</a>
536
        ");
537
        end_table();
538
        echo "</td></tr>\n";
539
    } else {
540
        echo "<p>";
541
        show_button("add_venue.php?venue=$venue&subset=$subset$tokens",
542
            tra("Add separate preferences for %1", $venue),
543
            tra("Add separate preferences for %1", $venue),
544
            "btn-primary btn-sm"
545
        );
546
    }
547
}
548
549
function print_prefs_display_global($user, $columns=false) {
550
    $global_prefs = prefs_parse_global($user->global_prefs);
551
552
    echo tra("These settings apply to all computers using this account except")
553
        ."<ul><li>"
554
        .tra("computers where you have set preferences locally using the BOINC Manager")
555
        ."<li>"
556
        .tra("Android devices")
557
        ."</ul>
558
    ";
559
    $switch_link = " <font size=\"-1\"><a href=prefs.php?subset=global&cols=". (int)!$columns .">".tra("(Switch view)")."</a></font>";
560
    if ($columns) {
561
        echo "<h3>".tra("Combined preferences").$switch_link."</h3>";
562
        start_table();
563
        prefs_show_columns_global($global_prefs);
564
        end_table();
565
566
    } else {
567
        if (isset($global_prefs->home) || isset($global_prefs->work) || isset($global_prefs->school)) {
568
            echo "<h3>".tra("Primary (default) preferences").$switch_link."</h3>";
569
        }
570
        start_table();
571
        prefs_show_global($global_prefs);
572
        $tokens = url_tokens($user->authenticator);
573
        row2("<br>",
574
            button_text("prefs_edit.php?subset=global$tokens",
575
                tra("Edit preferences")
576
            )
577
        );
578
        end_table();
579
580
        prefs_display_venue($global_prefs, "home", "global");
581
        prefs_display_venue($global_prefs, "school", "global");
582
        prefs_display_venue($global_prefs, "work", "global");
583
    }
584
    if (isset($global_prefs->mod_time)) {
585
        echo "<p>".tra("Preferences last modified:")." ".pretty_time_str($global_prefs->mod_time)."<p>\n";
586
    }
587
}
588
589
// This functions is used in prefs_edit.php to be able to display
590
// the prefs form in case of an error again.
591
// $error and $project_error should be an object of the form:
592
// $error->idle_time_to_run=true if an error occurred
593
// otherwise false
594
//
595
function print_prefs_form(
596
    $action, $subset, $venue, $user, $prefs, $cols, $error=false,
0 ignored issues
show
Multi-line function declarations must define one parameter per line
Loading history...
597
    $project_error=false
598
){
0 ignored issues
show
There must be a single space between the closing parenthesis and the opening brace of a multi-line function declaration; found 0 spaces
Loading history...
599
    if ($action == "add") {
600
        $script = "add_venue.php";
601
        $submit_value = tra("Add preferences");
602
    }
603
    if ($action == "edit") {
604
        $script = "prefs_edit.php";
605
        $submit_value = tra("Update preferences");
606
    }
607
    echo "<form class=\"form-inline\" action=$script><input type=hidden name=subset value=$subset>
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $script does not seem to be defined for all execution paths leading up to this point.
Loading history...
608
        ".form_tokens($user->authenticator);
609
    if ($venue) {
610
        echo "<input type=hidden name=venue value=$venue>\n";
611
    }
612
    if ($cols) {
613
        echo "<input type=hidden name=cols value=$cols>\n";
614
    }
615
616
    start_table();
617
    if ($subset == "global") {
618
        prefs_form_global($user, $prefs, $error);
619
    } else {
620
        prefs_form_project($prefs, $error);
621
        if (!$venue) {
622
            prefs_form_privacy($user);
623
            prefs_form_consent($user);
624
            venue_form($user);
625
        }
626
        prefs_form_project_specific($prefs->project_specific, $project_error);
627
    }
628
629
    row2("",
630
        sprintf(
631
            '<input class="btn" %s type=submit value="%s" name="action">',
632
            button_style(),
633
            $submit_value
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $submit_value does not seem to be defined for all execution paths leading up to this point.
Loading history...
634
        )
635
    );
636
    end_table();
637
    echo "</form>\n";
638
}
639
640
////////////////////////////////////////////
641
//
642
// Functions to display preference subsets as forms
643
//
644
function prefs_form_global($user, $prefs, $error=false) {
645
    global $in_use_prefs;
646
    global $not_in_use_prefs;
647
    global $job_prefs;
648
    global $disk_prefs;
649
    global $net_prefs;
650
651
    row1(IN_USE_DESC);
652
    foreach ($in_use_prefs as $p) {
653
        $p->show_form_row($prefs, $error);
654
    }
655
    row1(NOT_IN_USE_DESC);
656
    foreach ($not_in_use_prefs as $p) {
657
        $p->show_form_row($prefs, $error);
658
    }
659
    row1(JOBS_DESC);
660
    foreach ($job_prefs as $p) {
661
        $p->show_form_row($prefs, $error);
662
    }
663
    row1(DISK_DESC);
664
    foreach ($disk_prefs as $p) {
665
        $p->show_form_row($prefs, $error);
666
    }
667
    row1(NET_DESC);
668
    foreach ($net_prefs as $p) {
669
        $p->show_form_row($prefs, $error);
670
    }
671
}
672
673
// returns a set of translated yes/no radio buttons for editing prefs forms
674
// Example: prefs_form_radio_buttons("allow_beta_work", $user->allow_beta_work);
675
//
676
// @param string $name name of the radio buttons
677
// @param bool $yesno toggles the preset of the buttons; true=yes, false=no
678
//
679
function prefs_form_radio_buttons($name, $yesno) {
680
    $rb = tra("yes")." <input type=radio name=$name value=yes "
681
        .($yesno?"checked":"")
682
        ."> ".tra("no")." <input type=radio name=$name value=no "
683
        .($yesno?"":"checked")
684
        .">\n";
685
    return $rb;
686
}
687
688
// TODO: make this a subclass of PREF
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...
689
//
690
define('VENUE_DESC', tra('Default computer location'));
691
define('VENUE_TOOLTIP', tra('New computers will use this location for computing and project preferences.'));
692
693
function tooltip_row2($t, $x, $y) {
694
    echo "<tr title=\"$t\">
695
        <td ".NAME_ATTRS.">$x</td>
696
        <td ".VALUE_ATTRS.">$y</td>
697
        </tr>
698
    ";
699
}
700
function venue_show($user) {
701
    $venue = $user->venue;
702
    if ($venue =='') $venue = '---';
703
    tooltip_row2(VENUE_TOOLTIP, VENUE_DESC, $venue);
704
}
705
706
function venue_form($user) {
707
    $n=$h=$w=$s=$m='';
708
    if ($user->venue == '') $n = 'selected';
709
    if ($user->venue == 'home') $h = 'selected';
710
    if ($user->venue == 'work') $w = 'selected';
711
    if ($user->venue == 'school') $s = 'selected';
712
    tooltip_row2(
713
        VENUE_TOOLTIP,
714
        VENUE_DESC,
715
        "<select class=\"form-control input-sm\" name=default_venue>
716
        <option value=\"\" $n>---
717
        <option value=home $h>".tra("Home")."
718
        <option value=work $w>".tra("Work")."
719
        <option value=school $s>".tra("School")."
720
        </select>
721
    ");
722
}
723
724
function venue_parse_form(&$user) {
725
    $user->venue = $_GET['default_venue'];
726
}
727
728
////////////////////////////////////////////
729
//
730
// Functions to parse form elements, modifying a preferences structure
731
// prefs is preferences object to modify
732
// returns an object with errorvalues or false in success case
733
//
734
function prefs_global_parse_form(&$prefs) {
735
    global $in_use_prefs;
736
    global $not_in_use_prefs;
737
    global $job_prefs;
738
    global $disk_prefs;
739
    global $net_prefs;
740
741
    $error = false;
742
    foreach ($in_use_prefs as $p) {
743
        $p->parse_form($prefs, $error);
744
    }
745
    foreach ($not_in_use_prefs as $p) {
746
        $p->parse_form($prefs, $error);
747
    }
748
    foreach ($job_prefs as $p) {
749
        $p->parse_form($prefs, $error);
750
    }
751
    foreach ($disk_prefs as $p) {
752
        $p->parse_form($prefs, $error);
753
    }
754
    foreach ($net_prefs as $p) {
755
        $p->parse_form($prefs, $error);
756
    }
757
    return $error;
758
}
759
760
761
////////////////////////////////////////////
762
//
763
// convert prefs from structure to XML
764
//
765
function global_prefs_make_xml($prefs, $primary=true) {
766
    global $in_use_prefs;
767
    global $not_in_use_prefs;
768
    global $job_prefs;
769
    global $disk_prefs;
770
    global $net_prefs;
771
772
    $xml = "";
773
    if ($primary) {
774
        $xml = "<global_preferences>\n";
775
        $now = time();
776
        $xml = $xml."<mod_time>$now</mod_time>\n";
777
    }
778
779
    foreach ($in_use_prefs as $p) {
780
        $xml .= $p->xml_string($prefs);
781
    }
782
    foreach ($not_in_use_prefs as $p) {
783
        $xml .= $p->xml_string($prefs);
784
    }
785
    foreach ($job_prefs as $p) {
786
        $xml .= $p->xml_string($prefs);
787
    }
788
    foreach ($disk_prefs as $p) {
789
        $xml .= $p->xml_string($prefs);
790
    }
791
    foreach ($net_prefs as $p) {
792
        $xml .= $p->xml_string($prefs);
793
    }
794
795
    if (isset($prefs->home)) {
796
        $xml = $xml."<venue name=\"home\">\n".global_prefs_make_xml($prefs->home, false)."</venue>\n";
797
    }
798
    if (isset($prefs->work)) {
799
        $xml = $xml."<venue name=\"work\">\n".global_prefs_make_xml($prefs->work, false)."</venue>\n";
800
    }
801
    if (isset($prefs->school)) {
802
        $xml = $xml."<venue name=\"school\">\n".global_prefs_make_xml($prefs->school, false)."</venue>\n";
803
    }
804
    if ($primary) {
805
        $xml = $xml."</global_preferences>\n";
806
    }
807
    return $xml;
808
}
809
810
////////////////////////////////////////////
811
//
812
// Update user's prefs in database, from a given structure
813
//
814
function global_prefs_update(&$user, $prefs) {
815
    $prefs_xml = BoincDb::escape_string(global_prefs_make_xml($prefs));
816
    $retval = $user->update("global_prefs='$prefs_xml'");
817
    if (!$retval) {
818
        return 1;
819
    }
820
    $user->global_prefs = $prefs_xml;
821
    return 0;
822
}
823
824
?>
825