Issues (1839)

html/inc/prefs.inc (3 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
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
    global $config;
292
    $config = get_config();
293
    $dp = new StdClass;
294
    $dp->disk_max_used_gb = parse_config($config, "<default_disk_max_used_gb>");
295
    $dp->disk_max_used_pct = parse_config($config, "<default_disk_max_used_pct>");
296
    $dp->disk_min_free_gb = parse_config($config, "<default_disk_min_free_gb>");
297
    // set some defaults if not found
298
    if (!$dp->disk_max_used_gb) $dp->disk_max_used_gb = 0;  // no limit
299
    if (!$dp->disk_max_used_pct) $dp->disk_max_used_pct = 90; // 90 percent
300
    if (!$dp->disk_min_free_gb) $dp->disk_min_free_gb = 1;   // 1 GB
301
    // set mininimum free space scheduler allows
302
    // - depends on which scheduler is running
303
    $dp->new_sched_flag = 1;
304
    $dp->sched_disk_min_free_gb = $dp->disk_min_free_gb;
305
    if (parse_config($config, "scheduler_disk_space_check_hardcoded>")) {
306
        $dp->new_sched_flag = 0;
307
        $dp->sched_disk_min_free_gb = 0;
308
    }
309
310
    return $dp;
311
}
312
313
function group_header($t) {
314
    echo "<tr><th class=\"bg-info\">$t</th><td class=\"bg-info\" colspan=4><br></td></tr>\n";
315
}
316
317
// functions to parse preferences XML into a struct
318
//
319
320
function element_start_global($parser, $name, $attrs) {
321
    global $top_parse_result;
322
    global $parse_result;
323
    global $text;
324
    global $venue_name;
325
326
    switch($name) {
327
    case "venue":
328
        if (array_key_exists("name", $attrs)) {
329
            $venue_name = $attrs["name"];
330
        } else {
331
            $venue_name = "home";
332
        }
333
        $top_parse_result = $parse_result;
334
        $parse_result = default_prefs_global();
335
        break;
336
    }
337
    $text = "";
338
}
339
340
function element_end_global($parser, $name) {
341
    global $text;
342
    global $parse_result;
343
    global $top_parse_result;
344
    global $venue_name;
345
    global $in_use_prefs;
346
    global $not_in_use_prefs;
347
    global $job_prefs;
348
    global $disk_prefs;
349
    global $net_prefs;
350
351
    foreach ($in_use_prefs as $p) {
352
        if ($p->xml_parse($parse_result, $name, $text)) {
353
            return;
354
        }
355
    }
356
    foreach ($not_in_use_prefs as $p) {
357
        if ($p->xml_parse($parse_result, $name, $text)) {
358
            return;
359
        }
360
    }
361
    foreach ($job_prefs as $p) {
362
        if ($p->xml_parse($parse_result, $name, $text)) {
363
            return;
364
        }
365
    }
366
    foreach ($disk_prefs as $p) {
367
        if ($p->xml_parse($parse_result, $name, $text)) {
368
            return;
369
        }
370
    }
371
    foreach ($net_prefs as $p) {
372
        if ($p->xml_parse($parse_result, $name, $text)) {
373
            return;
374
        }
375
    }
376
    switch($name) {
377
    case "venue":
378
        $top_parse_result->$venue_name = $parse_result;
379
        $parse_result = $top_parse_result;
380
        break;
381
    case "mod_time":
382
        $parse_result->mod_time = $text;
383
        break;
384
    case "global_preferences":
0 ignored issues
show
Empty CASE statements are not allowed
Loading history...
385
        break;
386
    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...
387
        //echo "Unknown tag: $name\n";
388
    }
389
}
390
391
function char_handler($parser, $x) {
392
    global $text;
393
    $text = $text.$x;
394
}
395
396
397
// state of prefs before parsing; defines prefs for new users
398
//
399
function default_prefs_global() {
400
    global $in_use_prefs;
401
    global $not_in_use_prefs;
402
    global $job_prefs;
403
    global $disk_prefs;
404
    global $net_prefs;
405
406
    $p = new StdClass;
407
    foreach ($in_use_prefs as $pref) {
408
        $pref->set_default($p);
409
    }
410
    foreach ($not_in_use_prefs as $pref) {
411
        $pref->set_default($p);
412
    }
413
    foreach ($job_prefs as $pref) {
414
        $pref->set_default($p);
415
    }
416
    foreach ($disk_prefs as $pref) {
417
        $pref->set_default($p);
418
    }
419
    foreach ($net_prefs as $pref) {
420
        $pref->set_default($p);
421
    }
422
    return $p;
423
}
424
425
// if not-in-use prefs undefined, copy from in-use
426
//
427
function set_niu_prefs($prefs) {
428
    if (!$prefs->niu_max_ncpus_pct) {
429
        $prefs->niu_max_ncpus_pct = $prefs->max_ncpus_pct;
430
    }
431
    if (!$prefs->niu_cpu_usage_limit) {
432
        $prefs->niu_cpu_usage_limit = $prefs->cpu_usage_limit;
433
    }
434
    if (!$prefs->niu_suspend_cpu_usage) {
435
        $prefs->niu_suspend_cpu_usage = $prefs->suspend_cpu_usage;
436
    }
437
}
438
439
// parse prefs from XML to a struct
440
//
441
function prefs_parse_global($prefs_xml) {
442
    global $parse_result;
443
    $parse_result = default_prefs_global();
444
    $xml_parser = xml_parser_create();
445
    xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
446
    xml_set_element_handler($xml_parser, "element_start_global", "element_end_global");
447
    xml_set_character_data_handler($xml_parser, "char_handler");
448
    xml_parse($xml_parser, $prefs_xml, 1);
449
    set_niu_prefs($parse_result);
450
    return $parse_result;
451
}
452
453
// Display all venues as columns next to descriptions
454
//
455
function prefs_show_columns_global($prefs) {
456
    global $in_use_prefs;
457
    global $not_in_use_prefs;
458
    global $job_prefs;
459
    global $disk_prefs;
460
    global $net_prefs;
461
462
    row_top(IN_USE_DESC);
463
    foreach ($in_use_prefs as $p) {
464
        $p->show_cols($prefs);
465
    }
466
    row_top(NOT_IN_USE_DESC);
467
    foreach ($not_in_use_prefs as $p) {
468
        $p->show_cols($prefs);
469
    }
470
    row_top(JOBS_DESC);
471
    foreach ($job_prefs as $p) {
472
        $p->show_cols($prefs);
473
    }
474
    row_top(DISK_DESC);
475
    foreach ($disk_prefs as $p) {
476
        $p->show_cols($prefs);
477
    }
478
    row_top(NET_DESC);
479
    foreach ($net_prefs as $p) {
480
        $p->show_cols($prefs);
481
    }
482
    row_links("global", $prefs);
483
}
484
485
function prefs_show_global($prefs) {
486
    global $in_use_prefs;
487
    global $not_in_use_prefs;
488
    global $job_prefs;
489
    global $disk_prefs;
490
    global $net_prefs;
491
492
    row1(IN_USE_DESC);
493
    foreach ($in_use_prefs as $p) {
494
        $p->show($prefs);
495
    }
496
    row1(NOT_IN_USE_DESC);
497
    foreach ($not_in_use_prefs as $p) {
498
        $p->show($prefs);
499
    }
500
    row1(JOBS_DESC);
501
    foreach ($job_prefs as $p) {
502
        $p->show($prefs);
503
    }
504
    row1(DISK_DESC);
505
    foreach ($disk_prefs as $p) {
506
        $p->show($prefs);
507
    }
508
    row1(NET_DESC);
509
    foreach ($net_prefs as $p) {
510
        $p->show($prefs);
511
    }
512
}
513
514
function subset_name($subset) {
515
    if ($subset == "global") return tra("Computing");
516
    return PROJECT;
517
}
518
519
function prefs_display_venue($prefs, $venue, $subset) {
520
    global $g_logged_in_user;
521
    $tokens = url_tokens($g_logged_in_user->authenticator);
522
    $x = false;
523
    if (isset($prefs->$venue)) $x = $prefs->$venue;
524
525
    if ($x) {
526
        start_table();
527
        row_heading(tra("Separate preferences for %1", $venue), 'bg-info');
528
        if ($subset == "global") {
529
            prefs_show_global($x);
530
        } else {
531
            prefs_show_project($x);
532
            prefs_show_project_specific($x);
533
        }
534
        row2("<br>",
535
            "<a href=prefs_edit.php?venue=$venue&subset=$subset$tokens>".tra("Edit preferences")."</a>
536
            | <a href=prefs_remove.php?venue=$venue&subset=$subset$tokens>".tra("Remove")."</a>
537
        ");
538
        end_table();
539
        echo "</td></tr>\n";
540
    } else {
541
        echo "<p>";
542
        show_button("add_venue.php?venue=$venue&subset=$subset$tokens",
543
            tra("Add separate preferences for %1", $venue),
544
            tra("Add separate preferences for %1", $venue),
545
            "btn-primary btn-sm"
546
        );
547
    }
548
}
549
550
function print_prefs_display_global($user, $columns=false) {
551
    $global_prefs = prefs_parse_global($user->global_prefs);
552
553
    echo tra("These settings apply to all computers using this account except")
554
        ."<ul><li>"
555
        .tra("computers where you have set preferences locally using the BOINC Manager")
556
        ."<li>"
557
        .tra("Android devices")
558
        ."</ul>
559
    ";
560
    $switch_link = " <font size=\"-1\"><a href=prefs.php?subset=global&cols=". (int)!$columns .">".tra("(Switch view)")."</a></font>";
561
    if ($columns) {
562
        echo "<h3>".tra("Combined preferences").$switch_link."</h3>";
563
        start_table();
564
        prefs_show_columns_global($global_prefs);
565
        end_table();
566
567
    } else {
568
        if (isset($global_prefs->home) || isset($global_prefs->work) || isset($global_prefs->school)) {
569
            echo "<h3>".tra("Primary (default) preferences").$switch_link."</h3>";
570
        }
571
        start_table();
572
        prefs_show_global($global_prefs);
573
        $tokens = url_tokens($user->authenticator);
574
        row2("<br>",
575
            button_text("prefs_edit.php?subset=global$tokens",
576
                tra("Edit preferences")
577
            )
578
        );
579
        end_table();
580
581
        prefs_display_venue($global_prefs, "home", "global");
582
        prefs_display_venue($global_prefs, "school", "global");
583
        prefs_display_venue($global_prefs, "work", "global");
584
    }
585
    if (isset($global_prefs->mod_time)) {
586
        echo "<p>".tra("Preferences last modified:")." ".pretty_time_str($global_prefs->mod_time)."<p>\n";
587
    }
588
}
589
590
// This functions is used in prefs_edit.php to be able to display
591
// the prefs form in case of an error again.
592
// $error and $project_error should be an object of the form:
593
// $error->idle_time_to_run=true if an error occurred
594
// otherwise false
595
//
596
function print_prefs_form(
597
    $action, $subset, $venue, $user, $prefs, $cols, $error=false,
598
    $project_error=false
599
){
600
    if ($action == "add") {
601
        $script = "add_venue.php";
602
        $submit_value = tra("Add preferences");
603
    }
604
    if ($action == "edit") {
605
        $script = "prefs_edit.php";
606
        $submit_value = tra("Update preferences");
607
    }
608
    echo "<form class=\"form-inline\" action=$script><input type=hidden name=subset value=$subset>
609
        ".form_tokens($user->authenticator);
610
    if ($venue) {
611
        echo "<input type=hidden name=venue value=$venue>\n";
612
    }
613
    if ($cols) {
614
        echo "<input type=hidden name=cols value=$cols>\n";
615
    }
616
617
    start_table();
618
    if ($subset == "global") {
619
        prefs_form_global($user, $prefs, $error);
620
    } else {
621
        prefs_form_project($prefs, $error);
622
        if (!$venue) {
623
            prefs_form_privacy($user);
624
            prefs_form_consent($user);
625
            venue_form($user);
626
        }
627
        prefs_form_project_specific($prefs->project_specific, $project_error);
628
    }
629
630
    row2("", "<input class=\"btn btn-success\" type=submit value=\"$submit_value\" name=\"action\">");
631
    end_table();
632
    echo "</form>\n";
633
}
634
635
////////////////////////////////////////////
636
//
637
// Functions to display preference subsets as forms
638
//
639
function prefs_form_global($user, $prefs, $error=false) {
640
    global $in_use_prefs;
641
    global $not_in_use_prefs;
642
    global $job_prefs;
643
    global $disk_prefs;
644
    global $net_prefs;
645
646
    row1(IN_USE_DESC);
647
    foreach ($in_use_prefs as $p) {
648
        $p->show_form_row($prefs, $error);
649
    }
650
    row1(NOT_IN_USE_DESC);
651
    foreach ($not_in_use_prefs as $p) {
652
        $p->show_form_row($prefs, $error);
653
    }
654
    row1(JOBS_DESC);
655
    foreach ($job_prefs as $p) {
656
        $p->show_form_row($prefs, $error);
657
    }
658
    row1(DISK_DESC);
659
    foreach ($disk_prefs as $p) {
660
        $p->show_form_row($prefs, $error);
661
    }
662
    row1(NET_DESC);
663
    foreach ($net_prefs as $p) {
664
        $p->show_form_row($prefs, $error);
665
    }
666
}
667
668
// returns a set of translated yes/no radio buttons for editing prefs forms
669
// Example: prefs_form_radio_buttons("allow_beta_work", $user->allow_beta_work);
670
//
671
// @param string $name name of the radio buttons
672
// @param bool $yesno toggles the preset of the buttons; true=yes, false=no
673
//
674
function prefs_form_radio_buttons($name, $yesno) {
675
    $rb = tra("yes")." <input type=radio name=$name value=yes "
676
        .($yesno?"checked":"")
677
        ."> ".tra("no")." <input type=radio name=$name value=no "
678
        .($yesno?"":"checked")
679
        .">\n";
680
    return $rb;
681
}
682
683
// TODO: make this a subclass of PREF
684
//
685
define('VENUE_DESC', tra('Default computer location'));
686
define('VENUE_TOOLTIP', tra('New computers will use this location for computing and project preferences.'));
687
688
function tooltip_row2($t, $x, $y) {
689
    echo "<tr title=\"$t\">
690
        <td ".NAME_ATTRS.">$x</td>
691
        <td ".VALUE_ATTRS.">$y</td>
692
        </tr>
693
    ";
694
}
695
function venue_show($user) {
696
    $venue = $user->venue;
697
    if ($venue =='') $venue = '---';
698
    tooltip_row2(VENUE_TOOLTIP, VENUE_DESC, $venue);
699
}
700
701
function venue_form($user) {
702
    $n=$h=$w=$s=$m='';
703
    if ($user->venue == '') $n = 'selected';
704
    if ($user->venue == 'home') $h = 'selected';
705
    if ($user->venue == 'work') $w = 'selected';
706
    if ($user->venue == 'school') $s = 'selected';
707
    tooltip_row2(
708
        VENUE_TOOLTIP,
709
        VENUE_DESC,
710
        "<select class=\"form-control input-sm\" name=default_venue>
711
        <option value=\"\" $n>---
712
        <option value=home $h>".tra("Home")."
713
        <option value=work $w>".tra("Work")."
714
        <option value=school $s>".tra("School")."
715
        </select>
716
    ");
717
}
718
719
function venue_parse_form(&$user) {
720
    $user->venue = $_GET['default_venue'];
721
}
722
723
////////////////////////////////////////////
724
//
725
// Functions to parse form elements, modifying a preferences structure
726
// prefs is preferences object to modify
727
// returns an object with errorvalues or false in success case
728
//
729
function prefs_global_parse_form(&$prefs) {
730
    global $in_use_prefs;
731
    global $not_in_use_prefs;
732
    global $job_prefs;
733
    global $disk_prefs;
734
    global $net_prefs;
735
736
    $error = false;
737
    foreach ($in_use_prefs as $p) {
738
        $p->parse_form($prefs, $error);
739
    }
740
    foreach ($not_in_use_prefs as $p) {
741
        $p->parse_form($prefs, $error);
742
    }
743
    foreach ($job_prefs as $p) {
744
        $p->parse_form($prefs, $error);
745
    }
746
    foreach ($disk_prefs as $p) {
747
        $p->parse_form($prefs, $error);
748
    }
749
    foreach ($net_prefs as $p) {
750
        $p->parse_form($prefs, $error);
751
    }
752
    return $error;
753
}
754
755
756
////////////////////////////////////////////
757
//
758
// convert prefs from structure to XML
759
//
760
function global_prefs_make_xml($prefs, $primary=true) {
761
    global $in_use_prefs;
762
    global $not_in_use_prefs;
763
    global $job_prefs;
764
    global $disk_prefs;
765
    global $net_prefs;
766
767
    $xml = "";
768
    if ($primary) {
769
        $xml = "<global_preferences>\n";
770
        $now = time();
771
        $xml = $xml."<mod_time>$now</mod_time>\n";
772
    }
773
774
    foreach ($in_use_prefs as $p) {
775
        $xml .= $p->xml_string($prefs);
776
    }
777
    foreach ($not_in_use_prefs as $p) {
778
        $xml .= $p->xml_string($prefs);
779
    }
780
    foreach ($job_prefs as $p) {
781
        $xml .= $p->xml_string($prefs);
782
    }
783
    foreach ($disk_prefs as $p) {
784
        $xml .= $p->xml_string($prefs);
785
    }
786
    foreach ($net_prefs as $p) {
787
        $xml .= $p->xml_string($prefs);
788
    }
789
790
    if (isset($prefs->home)) {
791
        $xml = $xml."<venue name=\"home\">\n".global_prefs_make_xml($prefs->home, false)."</venue>\n";
792
    }
793
    if (isset($prefs->work)) {
794
        $xml = $xml."<venue name=\"work\">\n".global_prefs_make_xml($prefs->work, false)."</venue>\n";
795
    }
796
    if (isset($prefs->school)) {
797
        $xml = $xml."<venue name=\"school\">\n".global_prefs_make_xml($prefs->school, false)."</venue>\n";
798
    }
799
    if ($primary) {
800
        $xml = $xml."</global_preferences>\n";
801
    }
802
    return $xml;
803
}
804
805
////////////////////////////////////////////
806
//
807
// Update user's prefs in database, from a given structure
808
//
809
function global_prefs_update(&$user, $prefs) {
810
    $prefs_xml = BoincDb::escape_string(global_prefs_make_xml($prefs));
811
    $retval = $user->update("global_prefs='$prefs_xml'");
812
    if (!$retval) {
813
        return 1;
814
    }
815
    $user->global_prefs = $prefs_xml;
816
    return 0;
817
}
818
819
?>
820