Issues (1963)

html/inc/prefs_project.inc (7 issues)

1
<?php
2
// This file is part of BOINC.
3
// http://boinc.berkeley.edu
4
// Copyright (C) 2014 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
// functions for display and editing project preferences
20
// Preferences are represented in two ways:
21
// - As a PHP structure (usually called $prefs)
22
//   The field "project_specific" is plain XML
23
// - As XML (usually called $prefs_xml)
24
//
25
// This XML has the general structure
26
//
27
// <project_preferences>
28
//    <resource_share>4</resource_share>
29
//    [ <allow_beta_work>0|1</allow_beta_work> ]
30
//    [ <no_cpu>1</no_cpu> ]
31
//    [ <no_cuda>1</no_cuda> ]
32
//    [ <no_ati>1</no_ati> ]
33
//    [ <no_intel_gpu>1</no_intel_gpu> ]
34
//    [ <no_apple_gpu>1</no_apple_gpu> ]
35
//    <project-specific>
36
//            ... (arbitrary project-specific XML)
37
//    </project-specific>
38
//    <venue name="home">
39
//       ...
40
//    </venue>
41
// </project_preferences>
42
//
43
// In addition there are some fields of the user table
44
// (send_email and show_hosts) that are treated as project preferences
45
46
include_once("../inc/prefs_util.inc");
47
include_once("../inc/app_types.inc");
48
include_once("../project/project_specific_prefs.inc");
49
50
global $app_types;
51
$app_types = get_app_types();
52
53
global $project_pref_descs;
54
$project_pref_descs = array(
55
    new PREF_NUM(
56
        tra("Resource share"),
57
        tra("Determines the proportion of your computer's resources allocated to this project. For example, if you participate in two BOINC projects with resource shares of 100 and 200, the first will get 1/3 of your resources and the second will get 2/3."),
58
        "resource_share",
59
        new NUM_SPEC("", 0, 9999999, 100)
60
    ),
61
);
62
63
if (!empty($accelerate_gpu_apps_pref)) {
64
    $project_pref_descs[] = new PREF_BOOL(
65
        tra("Accelerate GPU tasks by dedicating a CPU to each one?"),
66
        "",
67
        "accelerate_gpu_apps",
68
        false
69
    );
70
}
71
72
if ($app_types->cpu) {
73
    $project_pref_descs[] = new PREF_BOOL (
74
        tra("Allow CPU-only tasks"),
75
        "Request CPU-only tasks from this project.",
76
        "no_cpu",
77
        false,
78
        true
79
    );
80
}
81
if ($app_types->ati) {
82
    $project_pref_descs[] = new PREF_BOOL (
83
        tra("Use AMD GPU"),
84
        "Request AMD GPU tasks from this project.",
85
        "no_ati",
86
        false,
87
        true
88
    );
89
}
90
if ($app_types->cuda) {
91
    $project_pref_descs[] = new PREF_BOOL (
92
        tra("Use NVIDIA GPU"),
93
        "Request NVIDIA GPU tasks from this project.",
94
        "no_cuda",
95
        false,
96
        true
97
    );
98
}
99
if ($app_types->intel_gpu) {
100
    $project_pref_descs[] = new PREF_BOOL (
101
        tra("Use Intel GPU"),
102
        "Request Intel GPU tasks from this project.",
103
        "no_intel_gpu",
104
        false,
105
        true
106
    );
107
}
108
if ($app_types->apple_gpu) {
109
    $project_pref_descs[] = new PREF_BOOL (
110
        tra("Use Apple GPU"),
111
        "Request Apple GPU tasks from this project.",
112
        "no_apple_gpu",
113
        false,
114
        true
115
    );
116
}
117
118
if (project_has_beta()) {
119
    $project_pref_descs[] = new PREF_BOOL(
120
        tra("Run test applications?"),
121
        tra("This helps us develop applications, but may cause jobs to fail on your computer"),
122
        "allow_beta_work",
123
        false
124
    );
125
}
126
if (defined("EMAIL_FROM")) {
127
    $x = "<br><small>"
128
        .tra("Emails will be sent from %1; make sure your spam filter accepts this address.", EMAIL_FROM)
129
        ."</small>";
130
} else {
131
    $x = "";
132
}
133
134
$privacy_pref_descs = array (
0 ignored issues
show
There must be no space between the "array" keyword and the opening parenthesis
Loading history...
135
    new PREF_BOOL(
136
        tra("Is it OK for %1 and your team (if any) to email you?", PROJECT).$x,
137
        "",
138
        "send_email",
139
        true,
140
        false
141
    ),
142
    new PREF_BOOL(
143
        tra("Should %1 show your computers on its web site?", PROJECT),
144
        "Allows other users to see your computers and tasks. Useful to troubleshoot issues or to compare computers.",
145
        "show_hosts",
146
        true,
147
        false
148
    ),
149
);
150
151
// Privacy preferences located in consent_type table. Loop over the
152
// table and extract those consent types with enabled=1 and
153
// privacypref=1.
154
$privacy_consent_descs = array();
155
$_consenttypes = BoincConsentType::enum("enabled=1 AND privacypref=1", "ORDER BY project_specific ASC");
156
foreach ($_consenttypes as $ct) {
157
    $privacy_consent_descs[] = new PREF_CONSENT(
158
        tra($ct->description),
159
        tra($ct->description),
160
        "consent_".urlencode($ct->shortname),
161
        $ct->id,
162
        $ct->shortname,
163
        0
164
    );
165
}
166
167
global $text;
168
global $parse_result;
169
global $top_parse_result;
170
global $in_project_specific;
171
global $venue_name;
172
173
// functions to parse preferences XML into a struct
174
//
175
function element_start_project($parser, $name, $attrs) {
176
    global $top_parse_result;
177
    global $parse_result;
178
    global $text;
179
    global $in_project_specific;
180
    global $venue_name;
181
182
    switch($name) {
183
    case "venue":
184
        $venue_name = $attrs["name"];
185
        $top_parse_result = $parse_result;
186
        $parse_result = default_prefs_project();
187
        break;
188
    case "project_specific":
189
        $in_project_specific = 1;
190
        $text = "";
191
        break;
192
    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...
193
        if ($in_project_specific) {
194
            $text= $text."<$name>";
195
        } else {
196
            $text = "";
197
        }
198
    }
199
}
200
201
function element_end_project($parser, $name) {
202
    global $text;
203
    global $parse_result;
204
    global $in_project_specific;
205
    global $top_parse_result;
206
    global $venue_name;
207
    global $project_pref_descs;
208
209
    foreach($project_pref_descs as $p) {
210
        if ($p->xml_parse($parse_result, $name, $text)) {
211
            return;
212
        }
213
    }
214
    switch($name) {
215
    case "venue":
216
        $top_parse_result->$venue_name = $parse_result;
217
        $parse_result = $top_parse_result;
218
        break;
219
    case "project_specific":
220
        $parse_result->project_specific = $text;
221
        $in_project_specific = false;
222
        break;
223
    case "project_preferences":
0 ignored issues
show
Empty CASE statements are not allowed
Loading history...
224
        break;
225
    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...
226
        if ($in_project_specific) {
227
            $text = $text."</$name>";
228
        } else {
0 ignored issues
show
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
229
            //echo "Unknown tag: $name\n";
230
        }
231
    }
232
}
233
234
function default_prefs_project() {
235
    global $project_pref_descs;
236
237
    $p = new StdClass;
238
    foreach ($project_pref_descs as $pref) {
239
        $pref->set_default($p);
240
    }
241
    $p->project_specific = project_specific_prefs_default();
242
    return $p;
243
}
244
245
// parse prefs from XML to a struct
246
//
247
function prefs_parse_project($prefs_xml) {
248
    global $parse_result;
249
    $parse_result = default_prefs_project();
250
    $xml_parser = xml_parser_create();
251
    xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
252
    xml_set_element_handler($xml_parser, "element_start_project", "element_end_project");
253
    xml_set_character_data_handler($xml_parser, "char_handler");
254
    xml_parse($xml_parser, $prefs_xml, 1);
255
    return $parse_result;
256
}
257
258
function prefs_show_project($prefs, $columns=false) {
259
    global $project_pref_descs;
260
    if ($columns) {
261
        foreach ($project_pref_descs as $p) {
262
            $p->show_cols($prefs);
263
        }
264
    } else {
265
        foreach ($project_pref_descs as $p) {
266
            $p->show($prefs);
267
        }
268
    }
269
}
270
271
function prefs_show_privacy($user, $columns) {
272
    global $privacy_pref_descs;
273
    if ($columns) {
274
        foreach ($privacy_pref_descs as $p) {
275
            $p->show_cols($user);
276
        }
277
    } else {
278
        foreach ($privacy_pref_descs as $p) {
279
            $p->show($user);
280
        }
281
    }
282
}
283
284
function prefs_show_consent($user, $columns) {
285
    global $privacy_consent_descs;
286
    if ($columns) {
287
        foreach ($privacy_consent_descs as $p) {
288
            $p->consent_show_cols($user);
289
        }
290
    } else {
291
        foreach ($privacy_consent_descs as $p) {
292
            $p->consent_show($user);
293
        }
294
    }
295
}
296
297
function prefs_show_project_specific($prefs, $columns=false) {
298
    if ($columns) {
299
        $project_specific_prefs = project_specific_prefs_parse($prefs->project_specific);
300
        $project_specific_prefs->home = isset($prefs->home) ? project_specific_prefs_parse($prefs->home->project_specific) : "";
301
        $project_specific_prefs->work = isset($prefs->work) ? project_specific_prefs_parse($prefs->work->project_specific) : "";
302
        $project_specific_prefs->school = isset($prefs->school) ? project_specific_prefs_parse($prefs->school->project_specific) : "";
303
    } else {
304
        $project_specific_prefs = project_specific_prefs_parse($prefs->project_specific);
305
    }
306
    project_specific_prefs_show($project_specific_prefs, $columns);
307
}
308
309
function print_prefs_display_project($user, $columns=false) {
310
    $project_prefs = prefs_parse_project($user->project_prefs);
311
312
    $switch_link = " <font size=\"-1\"><a href=prefs.php?subset=project&cols=". (int)!$columns .">".tra("(Switch View)")."</a></font>";
313
    if ($columns) {
314
        start_table();
315
        row_heading(tra("Combined preferences").$switch_link);
316
        prefs_show_privacy($user, true);
317
        prefs_show_consent($user, true);
318
        venue_show($user);
319
        row_top(tra("Project specific settings"));
320
        prefs_show_project($project_prefs, true);
321
        prefs_show_project_specific($project_prefs, true);
322
        row_links("project", $project_prefs);
323
        end_table();
324
    } else {
325
        start_table();
326
        if (isset($project_prefs->home) || isset($project_prefs->work) || isset($project_prefs->school)) {
327
            row_heading(tra("Primary (default) preferences").$switch_link);
328
        }
329
        prefs_show_project($project_prefs, false);
330
        prefs_show_privacy($user, false);
331
        prefs_show_consent($user, false);
332
        venue_show($user);
333
        prefs_show_project_specific($project_prefs, false);
334
        $tokens = url_tokens($user->authenticator);
335
        row2("", "<a href=prefs_edit.php?subset=project$tokens>".tra("Edit preferences")."</a>");
336
        end_table();
337
338
        prefs_display_venue($project_prefs, "home", "project");
339
        prefs_display_venue($project_prefs, "school", "project");
340
        prefs_display_venue($project_prefs, "work", "project");
341
    }
342
}
343
344
////////////////////////////////////////////
345
//
346
// Functions to display preference subsets as forms
347
//
348
349
function prefs_form_privacy($user) {
350
    global $privacy_pref_descs;
351
    foreach ($privacy_pref_descs as $p) {
352
        $p->show_form_row($user, false);
353
    }
354
}
355
356
function prefs_form_consent($user) {
357
    global $privacy_consent_descs;
358
    foreach ($privacy_consent_descs as $p) {
359
        $p->consent_show_form_row($user, false);
360
    }
361
}
362
363
function prefs_form_project($prefs, $error=false) {
364
    global $project_pref_descs;
365
    foreach ($project_pref_descs as $p) {
366
        $p->show_form_row($prefs, $error);
367
    }
368
}
369
370
function prefs_form_project_specific($prefs_xml, $error=false) {
371
    $prefs = project_specific_prefs_parse($prefs_xml);
372
    project_specific_prefs_edit($prefs, $error);
373
}
374
375
function prefs_resource_parse_form(&$prefs) {
376
    global $project_pref_descs;
377
    $error = false;
378
    foreach ($project_pref_descs as $p) {
379
        $p->parse_form($prefs, $error);
380
    }
381
    return $error;
382
}
383
384
function prefs_privacy_parse_form(&$user) {
385
    global $privacy_pref_descs;
386
    $error = false;
387
    foreach ($privacy_pref_descs as $p) {
388
        $p->parse_form($user, $error);
389
    }
390
    return $error;
391
}
392
393
function prefs_consent_parse_update(&$user) {
394
    global $privacy_consent_descs;
395
    $error = false;
396
    foreach ($privacy_consent_descs as $p) {
397
        $p->parse_form($user, $error);
398
    }
399
    return $error;
400
}
401
402
// Parse the project specific prefs form.
403
// For details see project/project_specific_prefs.inc
404
//
405
function prefs_project_parse_form(&$prefs) {
406
    $error = false;
407
    $prefs->project_specific = project_specific_prefs_parse_form($error);
408
    return $error;
409
}
410
411
////////////////////////////////////////////
412
//
413
// convert prefs from structure to XML
414
//
415
416
// given a prefs structure, return the corresponding XML string
417
//
418
function project_prefs_make_xml($prefs, $primary=true) {
419
    global $project_pref_descs;
420
    $xml = "";
421
    if ($primary) {
422
        $xml = "<project_preferences>\n";
423
    }
424
    foreach ($project_pref_descs as $p) {
425
        $xml .= $p->xml_string($prefs);
426
    }
427
    if ($prefs->project_specific) {
428
        $x = trim($prefs->project_specific);
429
        $xml = $xml
430
            ."<project_specific>\n$x\n</project_specific>\n";
431
    }
432
    if (isset($prefs->home)) {
433
        $xml = $xml."<venue name=\"home\">\n".project_prefs_make_xml($prefs->home, false)."</venue>\n";
434
    }
435
    if (isset($prefs->work)) {
436
        $xml = $xml."<venue name=\"work\">\n".project_prefs_make_xml($prefs->work, false)."</venue>\n";
437
    }
438
    if (isset($prefs->school)) {
439
        $xml = $xml."<venue name=\"school\">\n".project_prefs_make_xml($prefs->school, false)."</venue>\n";
440
    }
441
    if ($primary) {
442
        $xml = $xml."</project_preferences>\n";
443
    }
444
    return $xml;
445
}
446
447
////////////////////////////////////////////
448
//
449
// Update user's prefs in database, from a given structure
450
//
451
function project_prefs_update(&$user, $prefs) {
452
    $prefs_xml = BoincDb::escape_string(project_prefs_make_xml($prefs));
453
    $send_email = $user->send_email?1:0;
454
    $show_hosts = $user->show_hosts?1:0;
455
    $retval = $user->update("project_prefs='$prefs_xml', send_email=$send_email, show_hosts=$show_hosts");
456
    if (!$retval) {
457
        return 1;
458
    }
459
    $user->project_prefs = $prefs_xml;
460
    return 0;
461
}
462
463
?>
464