File:
[LON-CAPA] /
loncom /
interface /
courseprefs.pm
Revision
1.3:
download - view:
text,
annotated -
select for diffs
Tue May 12 21:20:42 2009 UTC (15 years, 3 months ago) by
raeburn
Branches:
MAIN
CVS tags:
HEAD,
BZ5434-fox
Usability improvements for course configuration screen.
lonconfigsettings.pm
- Wording change in breadcrumbs: "Display/Edit Settings" replaces "Course Settings".
- Changes in args passed to courseprefs::process_changes().
- Added call to courseprefs::store_changes to save to environment.db
- Added call to courseprefs::display_disallowed().
courseprefs.pm
- Moved code to generate array of names of all course configuration settings to &get_allitems() routine to facilitate reuse.
- Text descriptions of config settings moved to hash within entry for each category.
- Hash ref $disallowed passed as additional arg to process_changes() to accumulate requested changes that are not permitted.
- &process_changes() routine used to populate %changes hash with settings that have changed (and their new values).
- &check_clone() used to check requested cloners have valid username/domain.
- &store_changes() used to populate %storehash with change settings so they can be written to environment.db and also generates output to show what has been changed.
- Ability to create (new) custom course setting added tp print_other().
- Replace use of &Apache::lonnet::privileged() with retrieval of &Apache::lonnet::get_domain_roles() for dc roles.
- &get_lang_choices() routine added to retrieve hash of supported languages.
- &cloners_javascript() added to provide update_cloners() javascript function which will toggle radio buttons appropriately for any domain, any user from specified domain etc.
- &update_env() to append certain course config changes to current %env, and also update nohist_courseids.db
- &display_disallowed() to display information about requested setting changes which did not occur because they were disallowed.
- course environment settings are deleted from environment.db if they are changed to undef.
- Work in progess - logging (and logging interface) still needed.
1: # The LearningOnline Network with CAPA
2: # Handler to set configuration settings for a course
3: #
4: # $Id: courseprefs.pm,v 1.3 2009/05/12 21:20:42 raeburn Exp $
5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#
23: # /home/httpd/html/adm/gpl.txt
24: #
25: # http://www.lon-capa.org/
26: #
27: #
28: ###############################################################
29: ##############################################################
30:
31: package Apache::courseprefs;
32:
33: use strict;
34: use Apache::Constants qw(:common :http);
35: use Apache::lonnet;
36: use Apache::loncommon();
37: use Apache::lonhtmlcommon();
38: use Apache::lonconfigsettings;
39: use Apache::lonlocal;
40: use LONCAPA qw(:DEFAULT :match);
41:
42: sub handler {
43: my $r=shift;
44: if ($r->header_only) {
45: &Apache::loncommon::content_type($r,'text/html');
46: $r->send_http_header;
47: return OK;
48: }
49: my $context = 'course';
50: my $cid = $env{'request.course.id'};
51: my ($cnum,$cdom) = &get_course($cid);
52: my $crstype = &Apache::loncommon::course_type();
53: my $parm_permission = &Apache::lonnet::allowed('opa',$cid);
54: my $navmap = Apache::lonnavmaps::navmap->new();
55: if ($parm_permission && $navmap) {
56: &Apache::loncommon::content_type($r,'text/html');
57: $r->send_http_header;
58: } else {
59: if ($navmap) {
60: $env{'user.error.msg'}=
61: "/adm/courseprefs:opa:0:0:Cannot modify course settings";
62: } else {
63: $env{'user.error.msg'}=
64: "/adm/courseprefs::0:1:Course environment gone, reinitialize the course";
65: }
66: return HTTP_NOT_ACCEPTABLE;
67: }
68:
69: &Apache::lonhtmlcommon::clear_breadcrumbs();
70: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/courseprefs',
71: text=>"Course Configuration"});
72: my $breadcrumbs =
73: &Apache::lonhtmlcommon::breadcrumbs('Edit Course Configuration');
74:
75: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
76: ['phase','actions']);
77:
78: my $phase = 'pickactions';
79: if ( exists($env{'form.phase'}) ) {
80: $phase = $env{'form.phase'};
81: }
82:
83: if ($phase eq 'categorizecourse') {
84: &assign_course_categories($r);
85: return OK;
86: }
87:
88: my %values=&Apache::lonnet::dump('environment',$cdom,$cnum);
89: my @prefs_order = ('courseinfo','localization','feedback','discussion',
90: 'classlists','appearance','grading','printouts',
91: 'spreadsheet','bridgetasks','other');
92:
93: my %prefs = (
94: 'courseinfo' =>
95: { text => 'General course settings',
96: help => 'Course_Environment',
97: header => [{col1 => 'Setting',
98: col2 => 'Value'}],
99: ordered => ['description','courseid','categories',
100: 'hidefromcat','cloners','externalsyllabus',
101: 'url','rolenames'],
102: itemtext => {
103: description => 'Course Description',
104: courseid => 'Course ID or number',
105: categories => 'Categorize course',
106: hidefromcat => 'Exclude from course catalog',
107: cloners => 'Users allowed to clone course',
108: externalsyllabus => 'URL of Syllabus',
109: url => 'Top Level Map',
110: rolenames => 'Replacement titles for standard course roles',
111: },
112: },
113: 'localization' =>
114: { text => 'Language/TimeZone/Locale',
115: help => 'Course_Environment',
116: header => [{col1 => 'Setting',
117: col2 => 'Value',}],
118: ordered => ['languages','timezone','datelocale'],
119: itemtext => {
120: languages => 'Languages used',
121: timezone => 'Timezone in which the course takes place',
122: datelocale => 'Locale used for course calendar',
123: },
124: },
125: 'feedback' =>
126: { text => 'Feedback messages',
127: help => 'Course_Environment',
128: header => [{col1 => 'Questions about:',
129: col2 => 'Recipients'},
130: {col1 => 'Questions about:',
131: col2 => 'Custom Text'}],
132: ordered => ['question.email','comment.email','policy.email'],
133: itemtext => {
134: 'question.email' => 'Resource Content',
135: 'comment.email' => 'Course Content',
136: 'policy.email' => 'Course Policy',
137: },
138: },
139: 'discussion' =>
140: { text => 'Discussion and Chat',
141: help => 'Course_Environment',
142: header => [{col1 => 'Setting',
143: col2 => 'Value',}],
144: ordered => ['plc.roles.denied','plc.users.denied',
145: 'pch.roles.denied','pch.users.denied',
146: 'allow_limited_html_in_feedback',
147: 'allow_discussion_post_editing'],
148: itemtext => {
149: 'plc.roles.denied' => 'No Resource Discussion',
150: 'plc.users.denied' => 'No Resource Discussion',
151: 'pch.roles.denied' => 'No Chat room use',
152: 'pch.users.denied' => 'No Chat room use',
153: allow_limited_html_in_feedback => 'Allow limited HTML in discussion posts',
154: allow_discussion_post_editing => 'Users can edit/delete own discussion posts',
155: },
156: },
157: 'classlists' =>
158: { text => 'Classlists and Staff Listing',
159: help => 'Course_Environment',
160: header => [{col1 => 'Type',
161: col2 => 'Default dates for student access'},
162: {col1 => 'Setting',
163: col2 => 'Privileged users (Domain Coordinators) in staff listing'},
164: {col1 => 'Setting',
165: col2 => 'Student-viewable classlist options'}],
166: ordered => ['default_enrollment_start_date',
167: 'default_enrollment_end_date',
168: 'nothideprivileged','student_classlist_view',
169: 'student_opt_in','student_classlist_portfiles'],
170: itemtext => {
171: default_enrollment_start_date => 'Start date',
172: default_enrollment_end_date => 'End date',
173: nothideprivileged => 'Domain Coodinators in course',
174: student_classlist_view => 'Student-viewable classlist',
175: student_opt_in => 'Student agreement needed to be listed',
176: student_classlist_portfiles => 'Include link to accessible portfolio files',
177: },
178: },
179: 'appearance' =>
180: { text => 'Display of resources ',
181: help => 'Course_Environment',
182: header => [{col1 => 'Setting',
183: col2 => 'Value'}],
184: ordered => ['default_xml_style','pageseparators',
185: 'disable_receipt_display','texengine',
186: 'tthoptions'],
187: itemtext => {
188: default_xml_style => 'Default XML Style File',
189: pageseparators => 'Visibly Separate Items on Pages',
190: disable_receipt_display => 'Disable display of problem receipts',
191: texengine => 'Force use of a specific math rendering engine.',
192: tthoptions => 'Default set of options to pass to tth/m when converting TeX',
193: },
194: },
195: 'grading' =>
196: { text => 'Grading',
197: help => 'Course_Environment',
198: header => [{col1 => 'Setting',
199: col2 => 'Value',}],
200: ordered => ['grading','rndseed',
201: 'receiptalg','disablesigfigs'],
202: itemtext => {
203: grading => 'Grading',
204: rndseed => 'Randomization algorithm used',
205: receiptalg => 'Receipt algorithm used',
206: disablesigfigs => 'Disable checking of Significant Figures',
207: },
208:
209: },
210: 'printouts' =>
211: { text => 'Printout generation',
212: help => 'Course_Environment',
213: header => [{col1 => 'Setting',
214: col2 => 'Value',}],
215: ordered => ['problem_stream_switch','suppress_tries',
216: 'default_paper_size','print_header_format',
217: 'disableexampointprint'],
218: itemtext => {
219: problem_stream_switch => 'Allow problems to be split over pages',
220: suppress_tries => 'Suppress number of tries in printing',
221: default_paper_size => 'Default paper type',
222: print_header_format => 'Print header format',
223: disableexampointprint => 'Disable automatically printing point values on exams',
224: },
225: },
226: 'spreadsheet' =>
227: { text => 'Spreadsheets',
228: help => 'Course_Environment',
229: header => [{col1 => 'Setting',
230: col2 => 'Value'}],
231: ordered => ['spreadsheet_default_classcalc',
232: 'spreadsheet_default_studentcalc',
233: 'spreadsheet_default_assesscalc','hideemptyrows'],
234: itemtext => {
235: spreadsheet_default_classcalc => 'Default Course Spreadsheet',
236: spreadsheet_default_studentcalc => 'Default Student Spreadsheet',
237: spreadsheet_default_assesscalc => 'Default Assessment Spreadsheet',
238: hideemptyrows => 'Hide Empty Rows in Spreadsheets',
239: },
240: },
241: 'bridgetasks' =>
242: { text => 'Bridge tasks',
243: help => 'Course_Environment',
244: header => [{col1 => 'Setting',
245: col2 => 'Value'}],
246: ordered => ['task_messages','task_grading',
247: 'suppress_embed_prompt'],
248: itemtext => {
249: task_messages => 'Send message to student when clicking Done on Tasks',
250: task_grading => 'Bridge Task grading by instructors and TAs in sections' ,
251: suppress_embed_prompt => 'Hi$de upload references prompt if uploading file to portfolio',
252: },
253: },
254: 'other' =>
255: { text => 'Other settings',
256: help => 'Course_Environment',
257: header => [ {col1 => 'Item',
258: col2 => 'Value',
259: }],
260: },
261: );
262: if ($phase eq 'process') {
263: my @allitems = &get_allitems(%prefs);
264: &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context,
265: \@prefs_order,\%prefs,\%values,
266: $cnum,undef,\@allitems);
267: } elsif ($phase eq 'display') {
268: my $jscript = &get_jscript($cdom,$phase);
269: my @allitems = &get_allitems(%prefs);
270: &Apache::lonconfigsettings::display_settings($r,$cdom,$phase,$context,
271: \@prefs_order,\%prefs,\%values,undef,$jscript,\@allitems);
272: } else {
273: &Apache::lonconfigsettings::display_choices($r,$phase,$context,
274: \@prefs_order,\%prefs);
275: }
276: return OK;
277: }
278:
279: sub get_allitems {
280: my (%prefs) = @_;
281: my @allitems;
282: foreach my $item (keys(%prefs)) {
283: if (ref($prefs{$item}) eq 'HASH') {
284: if (ref($prefs{$item}{'ordered'}) eq 'ARRAY') {
285: push(@allitems,@{$prefs{$item}{'ordered'}});
286: if ($item eq 'feedback') {
287: push(@allitems,(map { $_.'.text'; } @{$prefs{$item}{'ordered'}}));
288: }
289: }
290: }
291: }
292: return @allitems;
293: }
294:
295: sub print_config_box {
296: my ($r,$cdom,$phase,$action,$item,$settings,$allitems) = @_;
297: my $ordered = $item->{'ordered'};
298: my $itemtext = $item->{'itemtext'};
299: my $rowtotal = 0;
300: my $output =
301: '<table class="LC_nested_outer">
302: <tr>
303: <th align="left" valign="middle"><span class="LC_font_larger">'.
304: &mt($item->{text}).' '.
305: &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n".
306: '</tr>';
307: if (($action eq 'feedback') || ($action eq 'classlists')) {
308: $output .= '
309: <tr>
310: <td>
311: <table class="LC_nested">
312: <tr class="LC_info_row">
313: <td class="LC_left_item">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>
314: <td class="LC_right_item">'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
315: </tr>';
316: $rowtotal ++;
317: if ($action eq 'feedback') {
318: $output .= &print_feedback('top',$cdom,$settings,$ordered,$itemtext,\$rowtotal);
319: } elsif ($action eq 'classlists') {
320: $output .= &print_classlists('top',$cdom,$settings,$itemtext,\$rowtotal);
321: }
322: $output .= '
323: </table>
324: </td>
325: </tr>
326: <tr>
327: <td>
328: <table class="LC_nested">
329: <tr class="LC_info_row">
330: <td class="LC_left_item">'.&mt($item->{'header'}->[1]->{'col1'}).'</td>';
331: $output .= '
332: <td class="LC_right_item">'.&mt($item->{'header'}->[1]->{'col2'}).'</td>
333: </tr>';
334: if ($action eq 'classlists') {
335: $output .= &print_classlists('middle',$cdom,$settings,$itemtext,\$rowtotal).
336: '
337: </table>
338: </td>
339: </tr>
340: <tr>
341: <td>
342: <table class="LC_nested">
343: <tr class="LC_info_row">
344: <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
345: <td class="LC_right_item" valign="top">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
346: </tr>';
347: }
348: } else {
349: $output .= '
350: <tr>
351: <td>
352: <table class="LC_nested">
353: <tr class="LC_info_row">
354: <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>
355: <td class="LC_right_item" valign="top">'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
356: </tr>';
357: }
358: $rowtotal ++;
359: if ($action eq 'courseinfo') {
360: $output .= &print_courseinfo($cdom,$settings,$ordered,$itemtext,\$rowtotal);
361: } elsif ($action eq 'localization') {
362: $output .= &print_localization($cdom,$settings,$ordered,$itemtext,\$rowtotal);
363: } elsif ($action eq 'feedback') {
364: $output .= &print_feedback('bottom',$cdom,$settings,$ordered,$itemtext,\$rowtotal);
365: } elsif ($action eq 'discussion') {
366: $output .= &print_discussion($cdom,$settings,$ordered,$itemtext,\$rowtotal);
367: } elsif ($action eq 'classlists') {
368: $output .= &print_classlists('bottom',$cdom,$settings,$itemtext,\$rowtotal);
369: } elsif ($action eq 'appearance') {
370: $output .= &print_appearance($cdom,$settings,$ordered,$itemtext,\$rowtotal);
371: } elsif ($action eq 'grading') {
372: $output .= &print_grading($cdom,$settings,$ordered,$itemtext,\$rowtotal);
373: } elsif ($action eq 'printouts') {
374: $output .= &print_printouts($cdom,$settings,$ordered,$itemtext,\$rowtotal);
375: } elsif ($action eq 'spreadsheet') {
376: $output .= &print_spreadsheet($cdom,$settings,$ordered,$itemtext,\$rowtotal);
377: } elsif ($action eq 'bridgetasks') {
378: $output .= &print_bridgetasks($cdom,$settings,$ordered,$itemtext,\$rowtotal);
379: } elsif ($action eq 'other') {
380: $output .= &print_other($cdom,$settings,$allitems,\$rowtotal);
381: }
382: $output .= '
383: </table>
384: </td>
385: </tr>
386: </table><br />';
387: return ($output,$rowtotal);
388: }
389:
390: sub process_changes {
391: my ($cdom,$action,$values,$item,$changes,$allitems,$disallowed) = @_;
392: my %newvalues;
393: if (ref($item) eq 'HASH') {
394: if (ref($changes) eq 'HASH') {
395: my @ordered;
396: if ($action eq 'other') {
397: @ordered = &get_other_items($cdom,$values,$allitems);
398: if ($env{'form.newp_name'} ne '') {
399: my $newp = $env{'form.newp_name'};
400: if ($env{'form.newp_value'} ne '') {
401: if (ref($allitems) eq 'ARRAY') {
402: unless ((grep(/^\Q$newp\E$/,@ordered)) ||
403: (grep(/^\Q$newp\E$/,@{$allitems}))) {
404: $changes->{$newp} = $env{'form.newp_value'};
405: }
406: }
407: }
408: }
409: } elsif (ref($item->{'ordered'}) eq 'ARRAY') {
410: @ordered = @{$item->{'ordered'}};
411: }
412: if (@ordered > 0) {
413: if ($action eq 'feedback') {
414: foreach my $entry (@ordered) {
415: my $userstr = '';
416: my $total = $env{'form.'.$entry.'_total'};
417: if ($total) {
418: my @deletes = &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
419: for (my $i=0; $i<$total; $i++) {
420: unless (grep(/^$i$/,@deletes)) {
421: $userstr .= $env{'form.'.$entry.'_user_'.$i}.
422: &get_sec_str($entry,$i).',';
423: }
424: }
425: } else {
426: $total = 0;
427: }
428: if ($env{'form.'.$entry.'_uname_'.$total} ne '') {
429: my $uname = $env{'form.'.$entry.'_uname_'.$total};
430: my $udom = $env{'form.'.$entry.'_udom_'.$total};
431: if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
432: $userstr =~ s/,$//;
433: $disallowed->{'feedback'}{$entry} = $uname.':'.$udom;
434: } else {
435: $userstr .= $uname.':'.$udom.&get_sec_str($entry,$total);
436: }
437: } else {
438: $userstr =~ s/,$//;
439: }
440: $newvalues{$entry} = $userstr;
441: if ($newvalues{$entry} ne $values->{$entry}) {
442: $changes->{$entry} = $newvalues{$entry};
443: }
444: my $ext_entry = $entry.'.text';
445: $newvalues{$ext_entry} = $env{'form.'.$ext_entry};
446: if ($newvalues{$ext_entry} ne $values->{$ext_entry}) {
447: $changes->{$ext_entry} = $newvalues{$ext_entry};
448: }
449: }
450: } else {
451: foreach my $entry (@ordered) {
452: if ($entry eq 'cloners') {
453: if ($env{'form.cloners_all'}) {
454: $newvalues{$entry} = '*';
455: } else {
456: my @clonedoms;
457: if (exists($env{'form.cloners_activate'})) {
458: my $actnum = $env{'form.cloners_activate'};
459: if ($actnum ne '') {
460: if ($env{'form.clonersdom_'.$actnum} ne '') {
461: my $clonedom = $env{'form.clonersdom_'.$actnum};
462: if (&check_clone($clonedom,$disallowed) eq 'ok') {
463: $newvalues{$entry} = '*:'.$clonedom;
464: push(@clonedoms,$newvalues{$entry});
465: }
466: }
467: }
468: } else {
469: my $num = $env{'form.cloners_total'};
470: my @deletes =
471: &Apache::loncommon::get_env_multiple('form.cloners_delete');
472: for (my $i=0; $i<$num; $i++) {
473: if (!grep(/^$i$/,@deletes)) {
474: my $clonedom = $env{'form.cloners_dom_'.$i};
475: if (&check_clone($clonedom,$disallowed) eq 'ok') {
476: if (!grep(/^\*:\Q$clonedom\E$/,@clonedoms)) {
477: push (@clonedoms,'*:'.$clonedom);
478: }
479: }
480: }
481: }
482: if (@clonedoms) {
483: $newvalues{$entry}=join(',',@clonedoms);
484: }
485: }
486: if ($env{'form.cloners_newdom'} ne '') {
487: my $clonedom = $env{'form.cloners_newdom'};
488: if (&check_clone($clonedom,$disallowed) eq 'ok') {
489: my $newdom = '*:'.$env{'form.cloners_newdom'};
490: if (@clonedoms) {
491: if (!grep(/^\Q$newdom\E$/,@clonedoms)) {
492: $newvalues{$entry} .= ','.$newdom;
493: }
494: } else {
495: $newvalues{$entry} = $newdom;
496: }
497: }
498: }
499: if ($env{'form.'.$entry} ne '') {
500: my @cloners = split(',',$env{'form.'.$entry});
501: my @okcloners;
502: foreach my $cloner (@cloners) {
503: my ($uname,$udom) = split(':',$cloner);
504: if (&check_clone($udom,$disallowed,$uname) eq 'ok') {
505: if (!grep(/^\Q$cloner\E$/,@okcloners)) {
506: push(@okcloners,$cloner);
507: }
508: }
509: }
510: if (@okcloners) {
511: my $okclonestr = join(',',@okcloners);
512: if ($newvalues{$entry} ne '') {
513: $newvalues{$entry} .= ','.$okclonestr;
514: } else {
515: $newvalues{$entry} = $okclonestr;
516: }
517: }
518: }
519: }
520: if (ref($disallowed) eq 'HASH') {
521: if (ref($disallowed->{'cloners'}) eq 'HASH') {
522: foreach my $key (keys(%{$disallowed->{'cloners'}})) {
523: $disallowed->{'cloners'}{$key} =~ s/,$//;
524: }
525: }
526: }
527: } elsif ($entry =~ /^default_enrollment_(start|end)_date$/) {
528: $newvalues{$entry}=&Apache::lonhtmlcommon::get_date_from_form($entry);
529: } elsif ($entry eq 'rolenames') {
530: my $crstype = &Apache::loncommon::course_type();
531: my %adv_roles =
532: &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
533: my @stds = ('cc','in','ta','ep','ad','st');
534: my (@replacements,@regulars);
535: foreach my $role (@stds) {
536: if ($values->{$role.'.plaintext'} ne '') {
537: push(@replacements,$role);
538: } else {
539: push(@regulars,$role);
540: }
541: }
542: foreach my $stdrole (@stds) {
543: my $ext_entry = $entry.'_'.$stdrole;
544: my $stdname = &Apache::lonnet::plaintext($stdrole,$crstype,
545: $env{'request.course.id'},1);
546: if ($env{'form.'.$ext_entry} eq $stdname) {
547: $newvalues{$ext_entry} = '';
548: } else {
549: $newvalues{$ext_entry} = $env{'form.'.$ext_entry};
550: }
551: if ($newvalues{$ext_entry} ne $values->{$stdrole.'.plaintext'}) {
552: my $dupname = 0;
553: if ($newvalues{$ext_entry} ne '') {
554: my $dupname = 0;
555: if (grep(/^\Q$newvalues{$ext_entry}\E$/,@replacements)) {
556: $dupname = 1;
557: push(@{$disallowed->{'rolenames'}{'replacements'}},$newvalues{$ext_entry});
558: }
559: if (!$dupname) {
560: if (grep(/^\Q$newvalues{$ext_entry}\E$/,@regulars)) {
561: $dupname = 1;
562: push(@{$disallowed->{rolenames}{'regulars'}},$newvalues{$ext_entry});
563: }
564: }
565: if (!$dupname) {
566: foreach my $role (keys(%adv_roles)) {
567: if ($role =~ m{^cr/$match_domain/$match_name/\Q$newvalues{$ext_entry}\E$}) {
568: $dupname = 1;
569: push(@{$disallowed->{rolenames}{'customrole'}},$newvalues{$ext_entry});
570: last;
571: }
572: }
573: }
574: }
575: if (!$dupname) {
576: $changes->{$ext_entry} = $newvalues{$ext_entry};
577: }
578: }
579: }
580: } elsif (($entry eq 'plc.roles.denied') || ($entry eq 'pch.roles.denied')) {
581: my @denied = &Apache::loncommon::get_env_multiple('form.'.$entry);
582: @denied = sort(@denied);
583: my $deniedstr = '';
584: if (@denied > 0) {
585: $deniedstr = join(',',@denied);
586: }
587: $newvalues{$entry} = $deniedstr;
588: } elsif (($entry eq 'plc.users.denied') || ($entry eq 'pch.users.denied')) {
589: my $total = $env{'form.'.$entry.'_total'};
590: my $userstr = '';
591: my @denied;
592: if ($total > 0) {
593: my @deletes =
594: &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
595: for (my $i=0; $i<$total; $i++) {
596: unless (grep(/^$i$/,@deletes)) {
597: $userstr .= $env{'form.'.$entry.'_user_'.$i}.',';
598: push(@denied,$env{'form.'.$entry.'_user_'.$i});
599: }
600: }
601: } else {
602: $total = 0;
603: }
604: if ($env{'form.'.$entry.'_uname_'.$total} ne '') {
605: my $uname = $env{'form.'.$entry.'_uname_'.$total};
606: my $udom = $env{'form.'.$entry.'_udom_'.$total};
607: if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
608: $userstr =~ s/,$//;
609: $disallowed->{'discussion'}{$entry} = $uname.':'.$udom;
610: } else {
611: my $newuser .= $uname.':'.$udom;
612: if (grep(/^\Q$newuser\E$/,@denied)) {
613: $userstr =~ s/,$//;
614: } else {
615: $userstr .= $newuser;
616: }
617: }
618: } else {
619: $userstr =~ s/,$//;
620: }
621: $newvalues{$entry} = $userstr;
622: } elsif ($entry eq 'allow_discussion_post_editing') {
623: my @canedit = &Apache::loncommon::get_env_multiple('form.'.$entry);
624: @canedit = sort(@canedit);
625: foreach my $role (@canedit) {
626: my @secs = &Apache::loncommon::get_env_multiple('form.'.$entry.'_sections_'.$role);
627: if ((grep(/^\s*$/,@secs)) || (@secs == 0)) {
628: $newvalues{$entry} .= $role.',';
629: } else {
630: foreach my $sec (@secs) {
631: $newvalues{$entry} .= $role.':'.$sec.',';
632: }
633: }
634: }
635: $newvalues{$entry} =~ s/,$//;
636: } elsif ($entry eq 'nothideprivileged') {
637: my @curr_nothide;
638: my @new_nothide;
639: if ($values->{$entry} ne '') {
640: foreach my $user (split(/\s*\,\s*/,$values->{$entry})) {
641: my $nothide;
642: if ($user !~ /:/) {
643: $nothide = join(':',split(/[\@]/,$user));
644: } else {
645: $nothide = $user;
646: }
647: if ((defined($nothide)) &&
648: (!grep(/^\Q$nothide\E$/,@curr_nothide))) {
649: push(@curr_nothide,$nothide);
650: }
651: }
652: }
653: foreach my $key (keys(%env)) {
654: if ($key =~ /^form\.\Q$entry\E_($match_username:$match_domain)$/) {
655: if ($env{'form.'.$key}) {
656: my $nothide = $1;
657: if (!grep(/^\Q$nothide\E$/,@new_nothide)) {
658: push(@new_nothide,$nothide);
659: }
660: }
661: }
662: }
663: @new_nothide = sort(@new_nothide);
664: my @differences =
665: &Apache::loncommon::compare_arrays(\@curr_nothide,
666: \@new_nothide);
667: if (@differences > 0) {
668: if (@new_nothide > 0) {
669: $newvalues{$entry} = join(',',@new_nothide);
670: } else {
671: $newvalues{$entry} = '';
672: }
673: } else {
674: $newvalues{$entry} = $values->{$entry};
675: }
676: } elsif ($entry eq 'print_header_format') {
677: my $maxnum = $env{'form.printfmthdr_maxnum'};
678: my @newhdr;
679: if ($maxnum > 2) {
680: for (my $i=0; $i<$maxnum-2; $i++) {
681: if ($env{'form.printfmthdr_del_'.$i}) {
682: $newhdr[$env{'form.printfmthdr_pos_'.$i}] = '';
683: } else {
684: my $hdr;
685: if ($env{'form.printfmthdr_sub_'.$i} =~ /^[nca]$/) {
686: $hdr = '%';
687: if ($env{'form.printfmthdr_limit_'.$i} =~ /^\d+$/) {
688: $hdr .= $env{'form.printfmthdr_limit_'.$i};
689: }
690: $hdr .= $env{'form.printfmthdr_sub_'.$i};
691: } elsif ($env{'form.printfmthdr_sub_'.$i} ne '') {
692: $hdr = $env{'form.printfmthdr_sub_'.$i};
693: }
694: $newhdr[$env{'form.printfmthdr_pos_'.$i}] = $hdr;
695: }
696: }
697: }
698: my $newsub = $maxnum-2;
699: if ($env{'form.printfmthdr_sub_'.$newsub} =~ /^[nca]$/) {
700: my $hdr = '%';
701: if ($env{'form.printfmthdr_limit_'.$newsub} =~ /^\d+$/) {
702: $hdr .= $env{'form.printfmthdr_limit_'.$newsub};
703: }
704: $hdr .= $env{'form.printfmthdr_sub_'.$newsub};
705: $newhdr[$env{'form.printfmthdr_pos_'.$newsub}] = $hdr;
706: }
707: my $newtext = $maxnum-1;
708: $newhdr[$env{'form.printfmthdr_pos_'.$newtext}] = $env{'form.printfmthdr_text_'.$newtext};
709: $newvalues{$entry} = join('',@newhdr);
710: } elsif ($entry eq 'languages') {
711: my $langstr;
712: my $total = $env{'form.'.$entry.'_total'};
713: if ($total) {
714: my @deletes = &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
715: for (my $i=0; $i<$total; $i++) {
716: unless (grep(/^$i$/,@deletes)) {
717: $langstr .= $env{'form.'.$entry.'_'.$i}.',';
718: }
719: }
720: } else {
721: $total = 0;
722: }
723: if ($env{'form.'.$entry.'_'.$total} ne '') {
724: my $newlang = $env{'form.'.$entry.'_'.$total};
725: my %langchoices = &get_lang_choices();
726: if ($langchoices{$newlang}) {
727: $langstr .= $newlang;
728: } else {
729: $langstr =~ s/,$//;
730: $disallowed->{'localization'}{$entry} = $newlang;
731: }
732: } else {
733: $langstr =~ s/,$//;
734: }
735: $newvalues{$entry} = $langstr;
736: } else {
737: $newvalues{$entry} = $env{'form.'.$entry};
738: }
739: if ($newvalues{$entry} ne $values->{$entry}) {
740: $changes->{$entry} = $newvalues{$entry};
741: }
742: }
743: }
744: }
745: }
746: }
747: return;
748: }
749:
750: sub get_sec_str {
751: my ($entry,$num) = @_;
752: my @secs = &Apache::loncommon::get_env_multiple('form.'.$entry.'_sections_'.$num);
753: my $secstr;
754: if (grep(/^\s*$/,@secs)) {
755: $secstr = '';
756: } elsif (@secs > 0) {
757: $secstr = join(';',@secs);
758: }
759: if ($secstr ne '') {
760: return '('.$secstr.')';
761: }
762: return;
763: }
764:
765: sub check_clone {
766: my ($clonedom,$disallowed,$clonename) = @_;
767: return if (ref($disallowed) ne 'HASH');
768: if ($clonedom !~ /^$match_domain$/) {
769: $disallowed->{'cloners'}{'format'} .= $clonedom.',';
770: return;
771: } elsif (!&Apache::lonnet::domain($clonedom)) {
772: $disallowed->{'cloners'}{'domain'} .= $clonedom.',';
773: return;
774: }
775: if ($clonename ne '') {
776: if ($clonename !~ /^$match_username$/) {
777: $disallowed->{'cloners'}{'format'} .= $clonename.':'.$clonedom.',';
778: return;
779: } else {
780: if (&Apache::lonnet::homeserver($clonename,$clonedom) eq 'no_host') {
781: $disallowed->{'cloners'}{'newuser'} .= $clonename.':'.$clonedom.',';
782: return;
783: }
784: }
785: }
786: return 'ok';
787: }
788:
789: sub store_changes {
790: my ($cdom,$cnum,$prefs_order,$actions,$prefs,$values,$changes) = @_;
791: my ($chome,$output);
792: my (%storehash,@delkeys,@need_env_update);
793: if ((ref($values) eq 'HASH') && (ref($changes) eq 'HASH')) {
794: %storehash = %{$values};
795: } else {
796: $output = &mt('No changes made to course settings.');
797: return;
798: }
799: my %yesno = (
800: hidefromcat => '1',
801: problem_stream_switch => '1',
802: suppress_tries => '1',
803: disableexampointprint => '1',
804: hideemptyrows => '1',
805: suppress_embed_prompt => '1',
806: );
807: foreach my $item (@{$prefs_order}) {
808: if (grep(/^\Q$item\E$/,@{$actions})) {
809: $output .= '<h3>'.&mt($prefs->{$item}{'text'}).'</h3>';
810: if (ref($changes->{$item}) eq 'HASH') {
811: if (keys(%{$changes->{$item}}) > 0) {
812: $output .= &mt('Changes made:').'<ul>';
813: if ($item eq 'other') {
814: foreach my $key (sort(keys(%{$changes->{$item}}))) {
815: $storehash{$key} = $changes->{$item}{$key};
816: if ($changes->{$item}{$key} eq '') {
817: push(@delkeys,$key);
818: $output .= '<li>'.&mt('Deleted setting for [_1]','<i>'.$key.'</i>').'</li>';
819: } else {
820: $output .= '<li>'.&mt('[_1] set to [_2]','<i>'.$key.'</i>',
821: "'$storehash{$key}'").'</li>';
822: }
823: }
824: } else {
825: if (ref($prefs->{$item}->{'ordered'}) eq 'ARRAY') {
826: my @settings = @{$prefs->{$item}->{'ordered'}};
827: if ($item eq 'feedback') {
828: push(@settings,(map { $_.'.text'; } @settings));
829: }
830: foreach my $key (@settings) {
831: if ($key eq 'rolenames') {
832: my $displayname = $prefs->{$item}->{'itemtext'}{$key};
833: my $crstype = &Apache::loncommon::course_type();
834: my $msg;
835: foreach my $role ('cc','in','ta','ep','ad','st') {
836: next if (!exists($changes->{$item}{$key.'_'.$role}));
837: my $stdname = &Apache::lonnet::plaintext($role,$crstype,undef,1);
838: my $newname = $changes->{$item}{$key.'_'.$role};
839: $storehash{$role.'.plaintext'} = $newname;
840: if ($newname eq '') {
841: $newname = $stdname;
842: }
843: $msg .= '<li>'.&mt('[_1] set to [_2]','<i>'.$stdname.'</i>',
844: "'<b>".$newname."</b>'").'</li>';
845: }
846: if ($msg ne '') {
847: $output .= '<li>'.&mt($displayname).'<ul>'.$msg.'</ul></li>';
848: }
849: } else {
850: next if (!exists($changes->{$item}{$key}));
851: my ($displayname,$text);
852: $text = $prefs->{$item}->{'itemtext'}{$key};
853: my $displayval = $changes->{$item}{$key};
854: if ($item eq 'feedback') {
855: if ($key =~ /^(question|policy|comment)(\.email)\.text$/) {
856: $text = $prefs->{$item}->{'itemtext'}{$1.$2};
857: $displayname = &mt('Custom text for '.$text.' questions');
858: } else {
859: $displayname = &mt('Recipients of '.$text.' questions');
860: }
861: } elsif ($item eq 'discussion') {
862: if ($key =~ /^p(lc|ch)\.roles\.denied/) {
863: $displayname = &mt("$text (role-based)");
864: if ($displayval ne '') {
865: my @roles = split(',',$displayval);
866: @roles = map { &Apache::lonnet::plaintext($_); } @roles;
867: $displayval = join(', ',@roles);
868: }
869: } elsif ($key =~ /^p(lc|ch)\.users\.denied/) {
870: $displayname = &mt("$text (specific user(s))");
871: } else {
872: if ($key eq 'allow_discussion_post_editing') {
873: if ($displayval ne '') {
874: my @roles = split(',',$displayval);
875: my @longroles;
876: foreach my $role (@roles) {
877: my ($trole,$sec) = split(':',$role);
878: my $rolename =
879: &Apache::lonnet::plaintext($trole);
880: if ($sec ne '') {
881: $rolename .= ':'.$sec;
882: }
883: push(@longroles,$rolename);
884: }
885: $displayval = join(', ',@longroles);
886: }
887: }
888: $displayname = &mt($text);
889: }
890: } elsif ($item eq 'spreadsheet') {
891: if ($key =~ /^spreadsheet_default_(studentcalc|assesscalc)$/x) {
892: my $sheettype = $1;
893: if ($sheettype eq 'studentcalc') {
894: &Apache::lonnet::expirespread('','','studentcalc');
895: } else {
896: &Apache::lonnet::expirespread('','','assesscalc');
897: &Apache::lonnet::expirespread('','','studentcalc');
898: }
899: }
900: $displayname = &mt($text);
901: } else {
902: $displayname = &mt($text);
903: }
904: if (defined($yesno{$key})) {
905: $displayval = 'no';
906: if ($changes->{$item}{$key} eq 'yes') {
907: $displayval = 'yes';
908: }
909: } elsif (($key =~ /^default_enrollment_(start|end)_date$/) && ($displayval)) {
910: $displayval = &Apache::lonlocal::locallocaltime($displayval);
911: } elsif ($key eq 'categories') {
912: $displayval = $env{'form.categories_display'};
913: }
914: if ($changes->{$item}{$key} eq '') {
915: push(@delkeys,$key);
916: $output .= '<li>'.&mt('Deleted setting for [_1]',
917: '<i>'.$displayname.'</i>').'</li>';
918: } else {
919: $output .= '<li>'.&mt('[_1] set to [_2]',
920: '<i>'.$displayname.'</i>',
921: "'<b>$displayval</b>'");
922: if ($key eq 'url') {
923: my $bkuptime=time;
924: $output .= (' 'x2).&mt('(Previous URL backed up)').': '.
925: $storehash{'top level map backup '.$bkuptime} => $values->{$key};
926: }
927: $output .= '</li>';
928: }
929: $storehash{$key} = $changes->{$item}{$key};
930: }
931: if (($key eq 'description') || ($key eq 'cloners') ||
932: ($key eq 'hidefromcat') || ($key eq 'categories')) {
933: push(@need_env_update,$key);
934: }
935: }
936: }
937: }
938: $output .= '</ul>';
939: } else {
940: $output = &mt('No changes made to course settings.');
941: }
942: }
943: }
944: }
945: if (&Apache::lonnet::put('environment',\%storehash,$cdom,$cnum) eq 'ok') {
946: if (@delkeys) {
947: if (&Apache::lonnet::del('environment',\@delkeys,$cdom,$cnum) ne 'ok') {
948: $output .= '<br /><span class="LC_error">'.
949: &mt('An error occurred when removing course settings which are no longer in use.').'</span>';
950: }
951: }
952: if (@need_env_update) {
953: $chome = &Apache::lonnet::homeserver($cnum,$cdom);
954: &update_env($cnum,$cdom,$chome,\@need_env_update,\%storehash);
955: }
956: &Apache::lonnet::coursedescription($env{'request.course.id'},
957: {'freshen_cache' => 1});
958: } else {
959: $output = '<span class="LC_error">'.
960: &mt('An error occurred when saving changes to course settings, which remain unchanged.').'</span>';
961: }
962: return $output;
963: }
964:
965: sub update_env {
966: my ($cnum,$cdom,$chome,$need_env_update,$storehash) = @_;
967: my $count = 0;
968: if ((ref($need_env_update) eq 'ARRAY') && (ref($storehash) eq 'HASH')) {
969: my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',$cnum,undef,undef,'.');
970: if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
971: foreach my $key (@{$need_env_update}) {
972: if ($key eq 'description' && defined($storehash->{$key})) {
973: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.description' => $storehash->{$key}});
974: $crsinfo{$env{'request.course.id'}}{'description'} = $storehash->{$key};
975: $count ++;
976: } elsif (($key eq 'cloners') || ($key eq 'hidefromcat') || ($key eq 'categories')) {
977: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$key => $storehash->{$key}});
978: $crsinfo{$env{'request.course.id'}}{$key} = $storehash->{$key};
979: $count ++;
980: }
981: }
982: if ($count) {
983: my $putresult = &Apache::lonnet::courseidput($cdom,\%crsinfo,$chome,'notime');
984: }
985: }
986: }
987: return;
988: }
989:
990: sub display_disallowed {
991: my ($item,$disallowed,$prefs) = @_;
992: my $output;
993: if ((ref($disallowed) eq 'HASH') && (ref($prefs) eq 'HASH')) {
994: if (keys(%{$disallowed})) {
995: if ($item eq 'cloners') {
996: my @fails;
997: my %lt = &Apache::lonlocal::texthash (
998: format => 'Invalid format',
999: domain => 'Domain does not exist',
1000: newuser => 'LON-CAPA user(s) do(es) not exist.',
1001: );
1002: foreach my $error ('format','domain','newuser') {
1003: if (defined($disallowed->{$error})) {
1004: my $msg = '<b>'.$disallowed->{$error}.'</b>, '.&mt('reason').' - '.
1005: $lt{$error};
1006: if ($error eq 'newuser') {
1007: $msg .= '<br />'.&mt('Please [_1]add the user(s)[_2] before returning to the [_3]Course Configuration[_2] to add as potential cloners.','<a href="/adm/createuser">','</a>','<a href="/adm/courseprefs">');
1008: }
1009: push(@fails,$msg);
1010: }
1011: }
1012: if (@fails) {
1013: $output .= '<span class="LC_warning">'.&mt('Unable to add to allowed cloners: ').
1014: '</span>'.join('; ',@fails).'.<br />';
1015: }
1016: } elsif ($item eq 'rolenames') {
1017: my %lt = &Apache::lonlocal::texthash (
1018: replacements => 'Name already used to replace a different standard role name',
1019: regulars => 'Name already used as a standard role name',
1020: customrole => 'Name already used as the name of a custom role',
1021: );
1022: my @fails;
1023: foreach my $error ('replacements','regulars','customrole') {
1024: if (ref($disallowed->{$error}) eq 'ARRAY') {
1025: push(@fails,'<b>'.join(', ',@{$disallowed->{$error}}).
1026: '</b>, '.&mt('reason').' - '.$lt{'error'});
1027: }
1028: }
1029: if (@fails) {
1030: $output .= '<span class="LC_warning">'.
1031: &mt('Unable to include amongst replacements for role names: ').
1032: '</span>'.join('; ',@fails).'.<br />';
1033: }
1034:
1035: } elsif (($item eq 'feedback') || ($item eq 'discussion') || ($item eq 'localization')) {
1036: $output .= '<span class="LC_warning">';
1037: if ($item eq 'feedback') {
1038: $output .= &mt('Unable to include as a recipient of course feedback for:');
1039: } elsif ($item eq 'discussion') {
1040: $output .= &mt('Unable to include in user-based access control for:');
1041: } elsif ($item eq 'localization') {
1042: $output .= &mt('Unable to include in course localization:');
1043: }
1044: $output .= '</span><ul>';
1045: foreach my $key (sort(keys(%{$disallowed}))) {
1046: my $itemtext = $prefs->{$item}{'itemtext'}{$key};
1047: $output .= '<li><i>'.$itemtext.'</i> - ';
1048: if ($item eq 'localization') {
1049: $output .= &mt('reason - unsupported language: [_1]',
1050: '<b>'.$disallowed->{$key}.'</b>');
1051: } else {
1052: $output .= &mt('reason - invalid user: [_1]',
1053: '<b>'.$disallowed->{$key}.'</b>').'</li>';
1054: }
1055: }
1056: $output .= '</ul><br />';
1057: }
1058: }
1059: }
1060: return $output;
1061: }
1062:
1063: sub get_course {
1064: my ($courseid) = @_;
1065: if (!defined($courseid)) {
1066: $courseid = $env{'request.course.id'};
1067: }
1068: my $cdom=$env{'course.'.$courseid.'.domain'};
1069: my $cnum=$env{'course.'.$courseid.'.num'};
1070: return ($cnum,$cdom);
1071: }
1072:
1073: sub get_jscript {
1074: my ($cdom,$phase) = @_;
1075: my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom);
1076: my ($jscript,$categorize_js);
1077: my $stubrowse_js = &Apache::loncommon::studentbrowser_javascript();
1078: my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset');
1079: my $cloners_js = &cloners_javascript($phase);
1080: if ($can_categorize) {
1081: $categorize_js = <<ENDSCRIPT;
1082: function catsbrowser() {
1083: var catswin = null;
1084: var url = '/adm/courseprefs?phase=categorizecourse';
1085: if (!catswin || catswin.closed) {
1086: catswin=window.open(url,'categorieswin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
1087: } else {
1088: catswin.focus();
1089: }
1090: }
1091: ENDSCRIPT
1092: }
1093: $jscript = '<script type="text/javascript" language="Javascript">'."\n".
1094: $browse_js."\n".$categorize_js."\n".$cloners_js."\n".'</script>'.
1095: "\n".$stubrowse_js."\n";
1096: return $jscript;
1097: }
1098:
1099: sub cloners_javascript {
1100: my ($formname) = @_;
1101: return <<"ENDSCRIPT";
1102:
1103: function update_cloners(caller,num) {
1104: var delidx = getIndexByName('cloners_delete');
1105: var actidx = getIndexByName('cloners_activate');
1106: if (caller == 'cloners_all') {
1107: var selall;
1108: for (var i=0; i<document.$formname.cloners_all.length; i++) {
1109: if (document.$formname.cloners_all[i].checked) {
1110: selall = document.$formname.cloners_all[i].value;
1111: }
1112: }
1113: if (selall == 1) {
1114: if (delidx != -1) {
1115: if (document.$formname.cloners_delete.length) {
1116: for (var j=0; j<document.$formname.cloners_delete.length; j++) {
1117: document.$formname.cloners_delete[j].checked = true;
1118: }
1119: } else {
1120: document.$formname.elements[delidx].checked = true;
1121: }
1122: }
1123: if (actidx != -1) {
1124: if (document.$formname.cloners_activate.length) {
1125: for (var i=0; i<document.$formname.cloners_activate.length; i++) {
1126: if (document.$formname.cloners_activate[i].value == '0') {
1127: document.$formname.cloners_activate[i].checked = false;
1128: }
1129: if (document.$formname.cloners_activate[i].value == '') {
1130: document.$formname.cloners_activate[i].checked = true;
1131: }
1132: }
1133: }
1134: }
1135: document.$formname.cloners_newdom.selectedIndex = 0;
1136: }
1137: }
1138: if (caller == 'cloners_activate') {
1139: if (document.$formname.cloners_activate.length) {
1140: for (var j=0; j<document.$formname.cloners_activate.length; j++) {
1141: if (document.$formname.cloners_activate[j].value == num) {
1142: if (document.$formname.cloners_activate[j].checked) {
1143: for (var i=0; i<document.$formname.cloners_all.length; i++) {
1144: if (document.$formname.cloners_all[i].value == '1') {
1145: document.$formname.cloners_all[i].checked = false;
1146: }
1147: if (document.$formname.cloners_all[i].value == '0') {
1148: document.$formname.cloners_all[i].checked = true;
1149: }
1150: }
1151: }
1152: }
1153: }
1154: } else {
1155: for (var i=0; i<document.$formname.cloners_all.length; i++) {
1156: if (document.$formname.cloners_all[i].value == '1') {
1157: document.$formname.cloners_all[i].checked = false;
1158: }
1159: if (document.$formname.cloners_all[i].value == '0') {
1160: document.$formname.cloners_all[i].checked = true;
1161: }
1162: }
1163: }
1164: }
1165: return;
1166: }
1167:
1168: function getIndexByName(item) {
1169: for (var i=0;i<document.$formname.elements.length;i++) {
1170: if (document.$formname.elements[i].name == item) {
1171: return i;
1172: }
1173: }
1174: return -1;
1175: }
1176:
1177: ENDSCRIPT
1178: }
1179:
1180:
1181: sub print_courseinfo {
1182: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
1183: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1184: return;
1185: }
1186: my ($cathash,$categoriesform);
1187: my $crstype = &Apache::loncommon::course_type();
1188: my %domconf =
1189: &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
1190: if (ref($domconf{'coursecategories'}) eq 'HASH') {
1191: $cathash = $domconf{'coursecategories'}{'cats'};
1192: if (ref($cathash) eq 'HASH') {
1193: $categoriesform =
1194: &Apache::loncommon::assign_categories_table($cathash,
1195: $settings->{'categories'})."\n";
1196: }
1197: }
1198: if (!defined($categoriesform)) {
1199: $categoriesform = &mt('No categories defined for this domain');
1200: }
1201:
1202: my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom);
1203:
1204: my %items = (
1205: 'url' => {
1206: text => '<b>'.&mt($itemtext->{'url'}).'</b>'.(' 'x2).
1207: '<a href="javascript:openbrowser'.
1208: "('display','url','sequence')\">".
1209: &mt('Select Map').'</a><br /><span class="LC_warning"> '.
1210: &mt('Modification may make assessment data inaccessible!').
1211: '</span>',
1212: input => 'textbox',
1213: size => '40',
1214: },
1215: 'description' => {
1216: text => '<b>'.&mt($itemtext->{'description'}).'</b>',
1217: input => 'textbox',
1218: size => '25',
1219: },
1220: 'courseid' => {
1221: text => '<b>'.&mt($itemtext->{'courseid'}).'</b><br />'.'('.
1222: &mt('internal, optional').')',
1223: input => 'textbox',
1224: size => '25',
1225: },
1226: 'cloners' => {
1227: text => '<b>'.&mt($itemtext->{'cloners'}).'</b><br />'.
1228: &mt('Course Coordinators included automatically'),
1229: input => 'textbox',
1230: size => '40',
1231: },
1232: 'rolenames' => {
1233: text => '<b>'.&mt($itemtext->{'rolenames'}).'</b><br />'.
1234: '('.&mt('To replace the standard title for a course role, enter a title, otherwise leave blank').')',
1235: input => 'textbox',
1236: size => '20',
1237: },
1238: 'externalsyllabus' => {
1239: text => '<b>'.&mt($itemtext->{'externalsyllabus'}).'</b><br />('.
1240: &mt('not using syllabus template)'),
1241: input => 'textbox',
1242: size => '40',
1243: },
1244: 'hidefromcat' => {
1245: text => '<b>'.&mt($itemtext->{'hidefromcat'}).'</b><br />'.
1246: ' ('.&mt('included by default if assigned institutional code, or categorized').')',
1247: input => 'radio',
1248: },
1249: 'categories' => {
1250: text => '<b>'.&mt($itemtext->{'categories'}).'</b> <a href="javascript:catsbrowser()">'.
1251: &mt('Display Categories').'</a>',
1252: input => 'textbox',
1253: size => '25',
1254: },
1255: );
1256: my $datatable;
1257: my $count = 0;
1258: foreach my $item (@{$ordered}) {
1259: if ($item eq 'hidefromcat') {
1260: next if (!$can_toggle_cat);
1261: } elsif ($item eq 'categories') {
1262: next if (!$can_categorize);
1263: }
1264: $count ++;
1265: $datatable .= &item_table_row_start($items{$item}{text},$count);
1266: if ($items{$item}{input} eq 'radio') {
1267: $datatable .= &yesno_radio($item,$settings);
1268: } elsif ($item eq 'cloners') {
1269: my $includeempty = 1;
1270: my $num = 0;
1271: $datatable .= &Apache::loncommon::start_data_table().
1272: &Apache::loncommon::start_data_table_row().
1273: '<td><span class="LC_nobreak"><label>'.
1274: &mt('Any user in any domain:').
1275: ' <input type="radio" name="cloners_all" value="1" ';
1276: if ($settings->{$item} eq '*') {
1277: $datatable .= ' checked="checked" ';
1278: }
1279: $datatable .= 'onchange="javascript:update_cloners('.
1280: "'cloners_all'".');" />'.&mt('Yes').'</label>'.
1281: (' 'x2).'<input type="radio" name="cloners_all" value="0" ';
1282: if ($settings->{$item} ne '*') {
1283: $datatable .= ' checked="checked" ';
1284: }
1285: $datatable .= ' onchange="javascript:update_cloners('.
1286: "'cloners_all'".');"/>'.&mt('No').'</label></td>'.
1287: &Apache::loncommon::end_data_table_row().
1288: &Apache::loncommon::end_data_table().
1289: '<table><tr><td align="left">'.&mt('Or').
1290: '</td></tr></table>'.
1291: &Apache::loncommon::start_data_table();
1292: my @cloners;
1293: if ($settings->{$item} eq '') {
1294: $datatable .= &new_cloners_dom_row($cdom,'0');
1295: } elsif ($settings->{$item} ne '*') {
1296: my @entries = split(/,/,$settings->{$item});
1297: if (@entries > 0) {
1298: foreach my $entry (@entries) {
1299: my ($uname,$udom) = split(/:/,$entry);
1300: if ($uname eq '*') {
1301: $datatable .=
1302: &Apache::loncommon::start_data_table_row().
1303: '<td valign="top" align="left"><span class="LC_nobreak">'.
1304: &mt('Domain:').'<b> '.$udom.
1305: '</b><input type="hidden" name="cloners_dom_'.$num.
1306: '" value="'.$udom.'" /></span><br />'.
1307: '<span class="LC_nobreak"><label><input type="checkbox" '.
1308: 'name="cloners_delete" value="'.$num.'" onchange="javascript:update_cloners('."'cloners_delete','$num'".');" />'.
1309: &mt('Delete').'</label></span></td>'.
1310: &Apache::loncommon::end_data_table_row();
1311: $num ++;
1312: } else {
1313: push(@cloners,$entry);
1314: }
1315: }
1316: }
1317: }
1318: my $add_domtitle = &mt('Any user in additional domain:');
1319: if ($settings->{$item} eq '*') {
1320: $add_domtitle = &mt('Any user in specific domain:');
1321: } elsif ($settings->{$item} eq '') {
1322: $add_domtitle = &mt('Any user in other domain:');
1323: }
1324: my $cloners_str = join(',',@cloners);
1325: $datatable .= &Apache::loncommon::start_data_table_row().
1326: '<td align="left"><span class="LC_nobreak">'.
1327: $add_domtitle.'</span><br />'.
1328: &Apache::loncommon::select_dom_form('','cloners_newdom',
1329: $includeempty).
1330: '<input type="hidden" name="cloners_total" value="'.$num.'" />'.
1331: '</td>'.&Apache::loncommon::end_data_table_row().
1332: &Apache::loncommon::end_data_table().
1333: '<table><tr><td align="left">'.&mt('And').
1334: '</td></tr></table>'.
1335: &Apache::loncommon::start_data_table().
1336: &Apache::loncommon::start_data_table_row().
1337: '<td align="left">'.
1338: &mt('Specific users').' (<tt>'.
1339: &mt('user:domain,user:domain').'</tt>)<br />'.
1340: &Apache::lonhtmlcommon::textbox($item,$cloners_str,
1341: $items{$item}{'size'}).
1342: '</td>'.&Apache::loncommon::end_data_table_row().
1343: &Apache::loncommon::end_data_table();
1344: } elsif ($item eq 'rolenames') {
1345: $datatable .= &Apache::loncommon::start_data_table();
1346: foreach my $role ('cc','in','ta','ep','ad','st') {
1347: $datatable .= &Apache::loncommon::start_data_table_row().
1348: '<td align="left"><span class="LC_nobreak">'.
1349: &Apache::lonnet::plaintext($role,$crstype,undef,1).
1350: '</span></td><td align="left">'.
1351: &Apache::lonhtmlcommon::textbox('rolenames_'.$role,
1352: $settings->{$role.'.plaintext'},
1353: $items{$item}{size}).'</td>'.
1354: &Apache::loncommon::end_data_table_row();
1355: }
1356: $datatable .= &Apache::loncommon::end_data_table().'</td>';
1357: } elsif ($item eq 'categories') {
1358: my $launcher = 'onFocus="this.blur();javascript:catsbrowser();";';
1359: $datatable .= '<input type="hidden" name="categories" value="'.$settings->{$item}.'" />'.
1360: &Apache::lonhtmlcommon::textbox($item.'_display',$settings->{$item},
1361: $items{$item}{size},$launcher);
1362: } else {
1363: $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size});
1364: }
1365: $datatable .= &item_table_row_end();
1366: }
1367: $$rowtotal += scalar(@{$ordered});
1368: return $datatable;
1369: }
1370:
1371: sub new_cloners_dom_row {
1372: my ($newdom,$num) = @_;
1373: my $output;
1374: if ($newdom ne '') {
1375: $output .= &Apache::loncommon::start_data_table_row().
1376: '<td valign="top"><span class="LC_nobreak">'.
1377: &mt('Any user in domain:').' <b>'.$newdom.'</b>'.
1378: (' 'x2).'<label><input type="radio" '.
1379: 'name="cloners_activate" value="'.$num.'" '.
1380: 'onchange="javascript:update_cloners('.
1381: "'cloners_activate','$num'".');" />'.
1382: &mt('Yes').'</label>'.(' 'x2).
1383: '<label><input type="radio" '.
1384: 'name="cloners_activate" value="" checked="checked" '.
1385: 'onchange="javascript:update_cloners('.
1386: "'cloners_activate','$num'".');" />'.
1387: &mt('No').'</label><input type="hidden" name="cloners_dom_'.
1388: $num.'" value="'.$newdom.'" /></span></td>'.
1389: &Apache::loncommon::end_data_table_row();
1390: }
1391: return $output;
1392: }
1393:
1394: sub can_modify_catsettings {
1395: my ($dom) = @_;
1396: my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom);
1397: my ($can_toggle_cat,$can_categorize);
1398: if (ref($domconf{'coursecategories'}) eq 'HASH') {
1399: if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') {
1400: $can_toggle_cat = 1;
1401: }
1402: if ($domconf{'coursecategories'}{'categorize'} eq 'crs') {
1403: $can_categorize = 1;
1404: }
1405: }
1406: return ($can_toggle_cat,$can_categorize);
1407: }
1408:
1409: sub assign_course_categories {
1410: my ($r) = @_;
1411: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
1412: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1413: my $hascats = 0;
1414: my $cathash;
1415: my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
1416: if (ref($domconf{'coursecategories'}) eq 'HASH') {
1417: $cathash = $domconf{'coursecategories'}{'cats'};
1418: if (ref($cathash) eq 'HASH') {
1419: $hascats = 1;
1420: }
1421: }
1422: my $catwin_js;
1423: if ($hascats) {
1424: my $alert = &mt('Use \"Save\" in the main window to save course categories');
1425: $catwin_js = <<ENDSCRIPT;
1426: <script type="text/javascript">
1427:
1428: function updateCategories() {
1429: var newcategories = '';
1430: var unescapedcats = '';
1431: if (document.chgcats.usecategory.length) {
1432: for (var i=0; i<document.chgcats.usecategory.length; i++) {
1433: if (document.chgcats.usecategory[i].checked == true) {
1434: newcategories = newcategories + document.chgcats.usecategory[i].value + '&';
1435: unescapedcats = unescapedcats + document.chgcats.catname[i].value + ' & ';
1436: }
1437: }
1438: if (newcategories.length > 0) {
1439: newcategories = newcategories.slice(0,-1);
1440: }
1441: if (unescapedcats.length > 0) {
1442: unescapedcats = unescapedcats.slice(0,-3);
1443: }
1444: } else {
1445: if (document.chgcats.usecategory.checked == true) {
1446: newcategories = document.chgcats.usecategory.value;
1447: unescapedcats = document.chgcats.catname.value;
1448: }
1449: }
1450: opener.document.display.categories.value = newcategories;
1451: opener.document.display.categories_display.value = unescapedcats;
1452: alert("$alert");
1453: self.close();
1454: return;
1455: }
1456:
1457: </script>
1458: ENDSCRIPT
1459: } else {
1460: my $onload;
1461: }
1462: my $start_page =
1463: &Apache::loncommon::start_page('Course Categories',$catwin_js,
1464: {'only_body' => 1,});
1465: my $end_page = &Apache::loncommon::end_page();
1466: my $categoriesform = '<h3>'.&mt('Categorize Course').'</h3>';
1467: if ($hascats) {
1468: my %currsettings =
1469: &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum);
1470: $categoriesform .= &mt('Assign one or more categories to this course.').'<br /><br />'.
1471: '<form name="chgcats" action="/adm/courseprefs" method="post">'."\n".
1472: &Apache::loncommon::assign_categories_table($cathash,
1473: $currsettings{'categories'})."\n".
1474: '<br /><input type="button" name="changes" value="'.
1475: &mt('Copy to main window').'" '.
1476: 'onclick="javascript:updateCategories()" /></form><br />';
1477: } else {
1478: $categoriesform .= &mt('No categories defined for this domain');
1479: }
1480: $r->print($start_page.$categoriesform.$end_page);
1481: return;
1482: }
1483:
1484: sub print_localization {
1485: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
1486: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1487: return;
1488: }
1489: my %items = (
1490: languages => {
1491: text => &mt($itemtext->{'languages'}).'<br />'.
1492: &mt("(will override user's preference)"),
1493: input => 'selectbox',
1494: },
1495: timezone => {
1496: text => &mt($itemtext->{'timezone'}),
1497: input => 'selectbox',
1498: },
1499: datelocale => {
1500: text => &mt($itemtext->{'datelocale'}),
1501: input => 'selectbox',
1502: },
1503: );
1504: my $datatable;
1505: my $count = 0;
1506: foreach my $item (@{$ordered}) {
1507: $count ++;
1508: $datatable .= &item_table_row_start($items{$item}{text},$count);
1509: if ($item eq 'timezone') {
1510: my $includeempty = 1;
1511: my $timezone = &Apache::lonlocal::gettimezone();
1512: $datatable .=
1513: &Apache::loncommon::select_timezone($item,$timezone,undef,
1514: $includeempty);
1515: } elsif ($item eq 'datelocale') {
1516: my $includeempty = 1;
1517: my $locale_obj = &Apache::lonlocal::getdatelocale();
1518: my $currdatelocale;
1519: if (ref($locale_obj)) {
1520: $currdatelocale = $locale_obj->id();
1521: }
1522: $datatable .=
1523: &Apache::loncommon::select_datelocale($item,$currdatelocale,
1524: undef,$includeempty);
1525: } else {
1526: if ($settings->{$item} eq '') {
1527: $datatable .=
1528: &Apache::loncommon::select_language('languages_0','',1);
1529: } else {
1530: my $num = 0;
1531: my @languages = split(/\s*[,;:]\s*/,$settings->{$item});
1532: $datatable .= &Apache::loncommon::start_data_table();
1533: if (@languages > 0) {
1534: my %langchoices = &get_lang_choices();
1535: foreach my $lang (@languages) {
1536: my $showlang = $lang;
1537: if (exists($langchoices{$lang})) {
1538: $showlang = $langchoices{$lang};
1539: }
1540: $datatable .=
1541: &Apache::loncommon::start_data_table_row().
1542: '<td align="left"><span class="LC_nobreak">'.
1543: &mt('Language:').'<b> '.$showlang.
1544: '</b><input type="hidden" name="languages_'.$num.
1545: '" value="'.$lang.'" /></span><br />'.
1546: '<span class="LC_nobreak"><label><input type="checkbox" '.
1547: 'name="languages_delete" value="'.$num.'" />'.
1548: &mt('Delete').'</label></span></td>'.
1549: &Apache::loncommon::end_data_table_row();
1550: $num ++;
1551: }
1552: }
1553: $datatable .= &Apache::loncommon::start_data_table_row().
1554: '<td align="left"><span class="LC_nobreak">'.
1555: &mt('Additional language:'). '</span><br />'.
1556: &Apache::loncommon::select_language('languages_'.$num,'',1).
1557: '<input type="hidden" name="languages_total" value="'.$num.'" />'.
1558: '</td>'.&Apache::loncommon::end_data_table_row().
1559: &Apache::loncommon::end_data_table();
1560: }
1561: }
1562: $datatable .= &item_table_row_end();
1563: }
1564: $$rowtotal += scalar(@{$ordered});
1565: return $datatable;
1566: }
1567:
1568: sub get_lang_choices {
1569: my %langchoices;
1570: foreach my $id (&Apache::loncommon::languageids()) {
1571: my $code = &Apache::loncommon::supportedlanguagecode($id);
1572: if ($code) {
1573: $langchoices{$code} = &Apache::loncommon::plainlanguagedescription($id);
1574: }
1575: }
1576: return %langchoices;
1577: }
1578:
1579: sub print_feedback {
1580: my ($position,$cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
1581: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1582: return;
1583: }
1584: my %items = (
1585: 'question.email' => {
1586: text => '<b>'.&mt($itemtext->{'question.email'}).'</b>',
1587: input => 'textbox',
1588: size => '50',
1589: },
1590:
1591: 'comment.email' => {
1592: text => '<b>'.&mt($itemtext->{'comment.email'}).'</b>',
1593: input => 'textbox',
1594: size => '50',
1595: },
1596:
1597: 'policy.email' => {
1598: text => '<b>'.&mt($itemtext->{'policy.email'}).'</b>',
1599: input => 'textbox',
1600: size => '50',
1601: },
1602: );
1603: my $datatable;
1604: my $count = 0;
1605: my ($cnum) = &get_course();
1606: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
1607: my @sections = sort( { $a <=> $b } keys(%sections));
1608: my %lt = &Apache::lonlocal::texthash (
1609: currone => 'Current recipient:',
1610: curmult => 'Current recipients:',
1611: add => 'Additional recipient:',
1612: del => 'Delete?',
1613: sec => 'Sections:',
1614: );
1615:
1616: foreach my $item (@{$ordered}) {
1617: $count ++;
1618: $datatable .= &item_table_row_start($items{$item}{text},$count);
1619: if ($position eq 'top') {
1620: my $includeempty = 0;
1621: $datatable .= &user_table($cdom,$item,\@sections,
1622: $settings->{$item},\%lt);
1623: } else {
1624: $datatable .= &Apache::lonhtmlcommon::textbox($item.'.text',
1625: $settings->{$item.'.text'},$items{$item}{size});
1626: }
1627: $datatable .= &item_table_row_end();
1628: }
1629: $$rowtotal += scalar(@{$ordered});
1630: return $datatable;
1631: }
1632:
1633: sub user_table {
1634: my ($cdom,$item,$sections,$currvalue,$lt) = @_;
1635: my $output;
1636: if ($currvalue eq '') {
1637: $output .= &select_recipient($item,'0',$cdom,$sections);
1638: } else {
1639: my $num = 0;
1640: my @curr = split(/,/,$currvalue);
1641: $output .= &Apache::loncommon::start_data_table();
1642: my ($currusers);
1643: foreach my $val (@curr) {
1644: next if ($val eq '');
1645: my ($uname,$udom,$seclist) = ($val =~ /^($match_username):($match_domain)(\(?[^\)]*\)?)$/);
1646: my @selsec;
1647: if ($seclist) {
1648: $seclist =~ s/(^\(|\)$)//g;
1649: @selsec = split(/\s*;\s*/,$seclist);
1650: }
1651: $currusers .= '<tr>'.
1652: '<td valign="top"><span class="LC_nobreak">'.
1653: '<label><input type="checkbox" '.
1654: 'name="'.$item.'_delete" value="'.$num.'" />'.
1655: $lt->{'del'}.'</label>'.
1656: '<input type="hidden" name="'.$item.'_user_'.
1657: $num.'" value="'.$uname.':'.$udom.'" />'.(' 'x2).
1658: &Apache::loncommon::aboutmewrapper(
1659: &Apache::loncommon::plainname($uname,$udom,'firstname'),
1660: $uname,$udom,'aboutuser');
1661: if (ref($sections) eq 'ARRAY') {
1662: if (@{$sections}) {
1663: $currusers.= (' 'x3).$lt->{'sec'}.' '.
1664: &select_sections($item,$num,$sections,
1665: \@selsec);
1666: }
1667: }
1668: $currusers .= '</span></td></tr>';
1669: $num ++;
1670: }
1671: if ($num) {
1672: $output .= &Apache::loncommon::start_data_table_row().
1673: '<td align="left"><i>';
1674: if ($num > 1) {
1675: $output .= $lt->{'currone'};
1676: } else {
1677: $output .= $lt->{'currmult'};
1678: }
1679: $output .= '</i><br />'.
1680: '<table>'.$currusers.'</table></td>'.
1681: &Apache::loncommon::end_data_table_row();
1682: }
1683: $output .= &Apache::loncommon::start_data_table_row().
1684: '<td align="left"><span class="LC_nobreak"><i>'.
1685: $lt->{'add'}.'</i></span><br />'.
1686: &select_recipient($item,$num,$cdom,$sections).
1687: '<input type="hidden" name="'.$item.'_total" value="'.$num.'" />'.
1688: '</td>'.&Apache::loncommon::end_data_table_row().
1689: &Apache::loncommon::end_data_table();
1690: }
1691: return $output;
1692: }
1693:
1694: sub select_recipient {
1695: my ($item,$num,$cdom,$sections,$selected,$includeempty) = @_;
1696: my $domform = &Apache::loncommon::select_dom_form($cdom,$item.'_udom_'.$num,$includeempty);
1697: my $selectlink =
1698: &Apache::loncommon::selectstudent_link('display',$item.'_uname_'.$num,
1699: $item.'_udom_'.$num,1);
1700: my $css_class = ($num % 2)?'LC_even_row':'LC_odd_row';
1701: my $output =
1702: '<table><tr class="'.$css_class.'"><td align="center">'.&mt('Username').'<br />'.
1703: '<input type="text" name="'.$item.'_uname_'.$num.'" value="" /></td>'.
1704: '<td align="center">'.&mt('Domain').'<br />'.$domform.'</td>';
1705: if (ref($sections) eq 'ARRAY') {
1706: if (@{$sections}) {
1707: $output .= '<td align="center">'.&mt('Sections').'<br />'.
1708: &select_sections($item,$num,$sections,$selected).'</td>';
1709: }
1710: }
1711: $output .= '<td valign="top">'.
1712: $selectlink.'</td></tr></table>';
1713: return $output;
1714: }
1715:
1716: sub select_sections {
1717: my ($item,$num,$sections,$selected) = @_;
1718: my ($output,@currsecs,$allsec);
1719: if (ref($selected) eq 'ARRAY') {
1720: @currsecs = @{$selected};
1721: }
1722: if (!@currsecs) {
1723: $allsec = ' selected="selected"';
1724: }
1725: if (ref($sections) eq 'ARRAY') {
1726: if (@{$sections}) {
1727: my $mult;
1728: if (@{$sections} > 1) {
1729: $mult = ' multiple="multiple"';
1730: if (@{$sections} > 3) {
1731: $mult .= ' size="4"';
1732: }
1733: }
1734: $output = '<select name="'.$item.'_sections_'.$num.'"'.$mult.'>'.
1735: ' <option value=""'.$allsec.'>'.&mt('All').'</option>';
1736: foreach my $sec (@{$sections}) {
1737: my $is_sel;
1738: if ((@currsecs) && (grep(/^\Q$sec\E$/,@currsecs))) {
1739: $is_sel = 'selected="selected"';
1740: }
1741: $output .= '<option value="'.$sec.'"'.$is_sel.'>'.$sec.'</option>';
1742: }
1743: $output .= '</select>';
1744: }
1745: }
1746: return $output;
1747: }
1748:
1749: sub print_discussion {
1750: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
1751: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1752: return;
1753: }
1754: my %items = (
1755: 'plc.roles.denied' => {
1756: text => '<b>'.&mt($itemtext->{'plc.roles.denied'}).'</b>'.
1757: &Apache::loncommon::help_open_topic("Course_Disable_Discussion").
1758: &mt('(roles-based)'),
1759: input => 'checkbox',
1760: },
1761:
1762: 'plc.users.denied' => {
1763: text => '<b>'.&mt($itemtext->{'plc.users.denied'}).'</b><br />'.
1764: &mt('(specific user(s))'),
1765: input => 'checkbox',
1766: },
1767:
1768: 'pch.roles.denied' => {
1769: text => '<b>'.&mt($itemtext->{'pch.roles.denied'}).'</b>'.
1770: &Apache::loncommon::help_open_topic("Course_Disable_Discussion").'<br />'.
1771: &mt('(role-based)'),
1772: input => 'checkbox',
1773: },
1774:
1775: 'pch.users.denied' => {
1776: text => '<b>'.&mt($itemtext->{'pch.users.denied'}).'</b><br />'.
1777: &mt('(specific user(s))'),
1778: input => 'checkbox',
1779: },
1780: 'allow_limited_html_in_feedback' => {
1781: text => '<b>'.&mt($itemtext->{'allow_limited_html_in_feedback'}).'</b>',
1782: input => 'radio',
1783: },
1784:
1785: 'allow_discussion_post_editing' => {
1786: text => '<b>'.&mt($itemtext->{'allow_discussion_post_editing'}).'</b>',
1787: input => 'checkbox',
1788: },
1789: );
1790: my $datatable;
1791: my $count;
1792: my ($cnum) = &get_course();
1793: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
1794: my @sections = sort( { $a <=> $b } keys(%sections));
1795: my %lt = &Apache::lonlocal::texthash (
1796: currone => 'Disallowed:',
1797: curmult => 'Disallowed:',
1798: add => 'Disallow more:',
1799: del => 'Delete?',
1800: sec => 'Sections:',
1801: );
1802:
1803: foreach my $item (@{$ordered}) {
1804: $count ++;
1805: $datatable .= &item_table_row_start($items{$item}{text},$count);
1806: if ($item eq 'plc.roles.denied') {
1807: $datatable .= '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).
1808: '</table>';
1809: } elsif ($item eq 'plc.users.denied') {
1810: $datatable .= &user_table($cdom,$item,undef,
1811: $settings->{$item},\%lt);
1812: } elsif ($item eq 'pch.roles.denied') {
1813: $datatable .= '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).
1814: '</table>';
1815: } elsif ($item eq 'pch.users.denied') {
1816: $datatable .= &user_table($cdom,$item,undef,
1817: $settings->{$item},\%lt);
1818: } elsif ($item eq 'allow_limited_html_in_feedback') {
1819: $datatable .= &yesno_radio($item,$settings);
1820: } elsif ($item eq 'allow_discussion_post_editing') {
1821: $datatable .= &Apache::loncommon::start_data_table().
1822: &Apache::loncommon::start_data_table_row().
1823: '<th align="left">'.&mt('Role').'</th><th>'.
1824: &mt('Sections').'</th>'.
1825: &Apache::loncommon::end_data_table_row().
1826: &role_checkboxes($cdom,$cnum,$item,$settings,1).
1827: &Apache::loncommon::end_data_table();
1828: }
1829: $datatable .= &item_table_row_end();
1830: }
1831: $$rowtotal += scalar(@{$ordered});
1832: return $datatable;
1833: }
1834:
1835: sub role_checkboxes {
1836: my ($cdom,$cnum,$item,$settings,$showsections) = @_;
1837: my @roles = ('st','ad','ta','ep','in','cc');
1838: my $output;
1839: my (@current,@curr_roles,%currsec,@sections);
1840: if ($showsections) {
1841: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
1842: @sections = sort( { $a <=> $b } keys(%sections));
1843: }
1844: if (ref($settings) eq 'HASH') {
1845: if ($settings->{$item}) {
1846: @current = split(',',$settings->{$item});
1847: if ($showsections) {
1848: foreach my $role (@current) {
1849: if ($role =~ /:/) {
1850: my ($trole,$sec) = split(':',$role);
1851: push(@curr_roles,$trole);
1852: if (ref($currsec{$trole}) eq 'ARRAY') {
1853: if (!grep(/^\Q$sec\E/,@{$currsec{$trole}})) {
1854: push(@{$currsec{$trole}},$sec);
1855: }
1856: } else {
1857: $currsec{$trole} = [$sec];
1858: }
1859: } else {
1860: push(@curr_roles,$role);
1861: }
1862: }
1863: @current = @curr_roles;
1864: }
1865: }
1866: }
1867: my $numinrow = 3;
1868: my $count = 0;
1869: foreach my $role (@roles) {
1870: my $checked = '';
1871: if (grep(/^\Q$role\E$/,@current)) {
1872: $checked = ' checked="checked" ';
1873: }
1874: my $plrole=&Apache::lonnet::plaintext($role);
1875: if ($showsections) {
1876: $output .= &Apache::loncommon::start_data_table_row();
1877: } else {
1878: my $rem = $count%($numinrow);
1879: if ($rem == 0) {
1880: if ($count > 0) {
1881: $output .= '</tr>';
1882: }
1883: $output .= '<tr>';
1884: }
1885: }
1886: $output .= '<td align="left"><span class="LC_nobreak"><label><input type="checkbox" name='.
1887: $item.'" value="'.$role.'"'.$checked.'/> '.
1888: $plrole.'</label></span></td>';
1889: if ($showsections) {
1890: $output .= '<td align="left">'.
1891: &select_sections($item,$role,\@sections,$currsec{$role}).
1892: '</td></tr>';
1893: }
1894: $count ++;
1895: }
1896: my %adv_roles =
1897: &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
1898: my $total = @roles;
1899: foreach my $role (sort(keys(%adv_roles))) {
1900: if ($role =~ m{^cr/($match_domain)/($match_name)/\w$}) {
1901: my $rolename = $3;
1902: my $value = 'cr_'.$1.'_'.$2.'_'.$rolename;
1903: my $checked = '';
1904: if (grep(/^\Q$value\E$/,@current)) {
1905: $checked = ' checked="checked" ';
1906: }
1907: if ($showsections) {
1908: $output .= &Apache::loncommon::start_data_table_row();
1909: } else {
1910: my $rem = $count%($numinrow);
1911: if ($rem == 0) {
1912: if ($count > 0) {
1913: $output .= '</tr>';
1914: }
1915: $output .= '<tr>';
1916: }
1917: }
1918: $output .= '<td><span class="LC_nobreak"><label><input type="checkbox" name='.
1919: $item.'" value="'.$value.'"'.$checked.' /> '.$rolename.
1920: '</label></span></td>';
1921: if ($showsections) {
1922: $output .= '<td>'.
1923: &select_sections($item,$role,\@sections,$currsec{$role}).
1924: '</td>'.&Apache::loncommon::end_data_table_row();
1925: }
1926: $total ++;
1927: $count ++;
1928: }
1929: }
1930: if (!$showsections) {
1931: my $rem = $total%($numinrow);
1932: my $colsleft = $numinrow - $rem;
1933: if ($colsleft > 1 ) {
1934: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
1935: ' </td>';
1936: } elsif ($colsleft == 1) {
1937: $output .= '<td class="LC_left_item"> </td>';
1938: }
1939: $output .= '</tr>';
1940: }
1941: return $output;
1942: }
1943:
1944: sub print_classlists {
1945: my ($position,$cdom,$settings,$itemtext,$rowtotal) = @_;
1946: my @ordered;
1947: if ($position eq 'top') {
1948: @ordered = ('default_enrollment_start_date',
1949: 'default_enrollment_end_date');
1950: } elsif ($position eq 'middle') {
1951: @ordered = ('nothideprivileged');
1952: } else {
1953: @ordered = ('student_classlist_view',
1954: 'student_opt_in','student_classlist_portfiles');
1955: }
1956: my %items = (
1957: 'default_enrollment_start_date' => {
1958: text => '<b>'.&mt($itemtext->{'default_enrollment_start_date'}).'</b>',
1959: input => 'dates',
1960: },
1961: 'default_enrollment_end_date' => {
1962: text => '<b>'.&mt($itemtext->{'default_enrollment_end_date'}).'</b>',
1963: input => 'dates',
1964: },
1965:
1966: 'nothideprivileged' => {
1967: text => '<b>'.&mt($itemtext->{'nothideprivileged'}).'</b>',
1968: input => 'checkbox',
1969: },
1970:
1971: 'student_classlist_view' => {
1972: text => '<b>'.&mt($itemtext->{'student_classlist_view'}).'</b>',
1973: input => 'selectbox',
1974: options => {
1975: disabled => &mt('No viewable classlist'),
1976: section => &mt("Classlist of viewer's section"),
1977: all => &mt('Classlist of all students'),
1978: },
1979: order => ['disabled','all','section'],
1980: },
1981: 'student_opt_in' => {
1982: text => '<b>'.&mt($itemtext->{'student_opt_in'}).'</b>',
1983: input => 'radio',
1984: },
1985:
1986: 'student_classlist_portfiles' => {
1987: text => '<b>'.&mt($itemtext->{'student_classlist_portfiles'}).'</b>',
1988: input => 'radio',
1989: },
1990: );
1991: unless (($settings->{'student_classlist_view'} eq 'all') ||
1992: ($settings->{'student_classlist_view'} eq 'section')) {
1993: $settings->{'student_classlist_view'} = 'disabled';
1994: }
1995: return &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal);
1996: }
1997:
1998: sub print_appearance {
1999: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
2000: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
2001: return;
2002: }
2003: my %items = (
2004: 'default_xml_style' => {
2005: text => '<b>'.&mt($itemtext->{'default_xml_style'}).'</b> '.
2006: '<a href="javascript:openbrowser'.
2007: "('display','default_xml_style'".
2008: ",'sty')".'">'.&mt('Select Style File').'</a>',
2009: input => 'textbox',
2010: size => 35,
2011: },
2012:
2013: 'pageseparators' => {
2014: text => '<b>'.&mt($itemtext->{'pageseparators'}).'</b>',
2015: input => 'radio',
2016: },
2017: 'disable_receipt_display' => {
2018: text => '<b>'.&mt($itemtext->{'disable_receipt_display'}).'</b>',
2019: input => 'radio',
2020: },
2021: 'texengine' => {
2022: text => '<b>'.&mt($itemtext->{'texengine'}).'</b>',
2023: input => 'selectbox',
2024: options => {
2025: jsMath => 'jsMath',
2026: mimetex => &mt('Convert to Images'),
2027: tth => &mt('TeX to HTML'),
2028: },
2029: order => ['jsMath','mimetex','tth'],
2030: nullval => &mt("None specified - use student's choice"),
2031: },
2032: 'tthoptions' => {
2033: text => '<b>'.&mt($itemtext->{'tthoptions'}).'</b>',
2034: input => 'textbox',
2035: size => 40,
2036: },
2037: );
2038: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
2039: }
2040:
2041: sub print_grading {
2042: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
2043: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
2044: return;
2045: }
2046: my %items = (
2047: 'grading' => {
2048: text => '<b>'.&mt($itemtext->{'grading'}).'</b>'.
2049: &Apache::loncommon::help_open_topic('GradingOptions'),
2050: input => 'selectbox',
2051: options => {
2052: standard => &mt('Standard: shows points'),
2053: external => &mt('External: shows number of completed parts'),
2054: spreadsheet => &mt('Spreadsheet: (with link to detailed scores)'),
2055: },
2056: order => ['standard','external','spreadsheet'],
2057: },
2058: 'rndseed' => {
2059: text => '<b>'.&mt($itemtext->{'rndseed'}).'</b>'.
2060: '<span class="LC_error">'.'<br />'.
2061: &mt('Modifying this will make problems have different numbers and answers!').
2062: '</span>',
2063: input => 'selectbox',
2064: options => {
2065: '32bit' => '32bit',
2066: '64bit' => '64bit',
2067: '64bit2' => '64bit2',
2068: '64bit3' => '64bit3',
2069: '64bit4' => '64bit4',
2070: '64bit5' => '64bit5',
2071: },
2072: order => ['32bit','64bit','64bit2','64bit3','64bit4','64bit5'],
2073: },
2074: 'receiptalg' => {
2075: text => '<b>'.&mt($itemtext->{'receiptalg'}).'</b><br />'.
2076: &mt('This controls how receipt numbers are generated.'),
2077: input => 'selectbox',
2078: options => {
2079: receipt => 'receipt',
2080: receipt2 => 'receipt2',
2081: receipt3 => 'receipt3',
2082: },
2083: order => ['receipt','receipt2','receipt3'],
2084: },
2085: 'disablesigfigs' => {
2086: text => '<b>'.&mt($itemtext->{'disablesigfigs'}).'</b>',
2087: input => 'radio',
2088: },
2089: );
2090: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
2091: }
2092:
2093: sub print_printouts {
2094: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
2095: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
2096: return;
2097: }
2098: my %items = (
2099: problem_stream_switch => {
2100: text => '<b>'.&mt($itemtext->{'problem_stream_switch'}).'</b>',
2101: input => 'radio',
2102: },
2103: suppress_tries => {
2104: text => '<b>'.&mt($itemtext->{'suppress_tries'}).'</b>',
2105: input => 'radio',
2106: },
2107: default_paper_size => {
2108: text => '<b>'.&mt($itemtext->{'default_paper_size'}).'</b>',
2109: input => 'selectbox',
2110: options => {
2111: Letter => &mt('Letter').' [8 1/2x11 in]',
2112: Legal => &mt('Legal').' [8 1/2x14 in]',
2113: Tabloid => &mt('Tabloid').' [11x17 in]',
2114: Executive => &mt('Executive').' [7 1/2x10 in]',
2115: A2 => &mt('A2').' [420x594 mm]',
2116: A3 => &mt('A3').' [297x420 mm]',
2117: A4 => &mt('A4').' [210x297 mm]',
2118: A5 => &mt('A5').' [148x210 mm]',
2119: A6 => &mt('A6').' [105x148 mm]',
2120: },
2121: order => ['Letter','Legal','Tabloid','Executive','A2','A3','A4','A5','A6'],
2122: nullval => 'None specified',
2123: },
2124: print_header_format => {
2125: text => '<b>'.&mt($itemtext->{'print_header_format'}).'</b>',
2126: input => 'checkbox',
2127: },
2128: disableexampointprint => {
2129: text => '<b>'.&mt($itemtext->{'disableexampointprint'}).'</b>',
2130: input => 'radio',
2131: },
2132: );
2133: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
2134: }
2135:
2136: sub print_spreadsheet {
2137: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
2138: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
2139: return;
2140: }
2141: my $SelectSpreadsheetFile=&mt('Select Spreadsheet File');
2142: my %items = (
2143: spreadsheet_default_classcalc => {
2144: text => '<b>'.&mt($itemtext->{'spreadsheet_default_classcalc'}).'</b> '.
2145: '<span class="LC_nobreak"><a href="javascript:openbrowser'.
2146: "('display','spreadsheet_default_classcalc'".
2147: ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
2148: input => 'textbox',
2149: },
2150: spreadsheet_default_studentcalc => {
2151: text => '<b>'.&mt($itemtext->{'spreadsheet_default_studentcalc'}).'</b> '.
2152: '<span class="LC_nobreak"><a href="javascript:openbrowser'.
2153: "('display','spreadsheet_default_calc'".
2154: ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
2155: input => 'textbox',
2156: },
2157: spreadsheet_default_assesscalc => {
2158: text => '<b>'.&mt($itemtext->{'spreadsheet_default_assesscalc'}).'</b> '.
2159: '<span class="LC_nobreak"><a href="javascript:openbrowser'.
2160: "('display','spreadsheet_default_assesscalc'".
2161: ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
2162: input => 'textbox',
2163: },
2164: hideemptyrows => {
2165: text => '<b>'.&mt($itemtext->{'hideemptyrows'}).'</b>',
2166: input => 'radio',
2167: },
2168: );
2169: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
2170: }
2171:
2172: sub print_bridgetasks {
2173: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
2174: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
2175: return;
2176: }
2177: my %items = (
2178: task_messages => {
2179: text => '<b>'.&mt($itemtext->{'task_messages'}).'</b>',
2180: input => 'selectbox',
2181: options => {
2182: only_student => &mt('Send message to student'),
2183: student_and_user_notes_screen => &mt('Message to student and add to user notes'),
2184: },
2185: order => ['only_student','student_and_user_notes_screen'],
2186: nullval => &mt('No message or record in user notes'),
2187: },
2188: task_grading => {
2189: text => '<b>'.&mt($itemtext->{'task_grading'}).'</b>',
2190: input => 'selectbox',
2191: options => {
2192: any => &mt('Grade BTs in any section'),
2193: section => &mt('Grade BTs only in own section')
2194: },
2195: order => ['any','section'],
2196: },
2197: suppress_embed_prompt => {
2198: text => '<b>'.&mt($itemtext->{'suppress_embed_prompt'}).'</b><span class="LC_nobreak">'.
2199: ' '.&mt('(applies when current role is student)').'</span>',
2200: input => 'radio',
2201: },
2202: );
2203: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal);
2204: }
2205:
2206: sub print_other {
2207: my ($cdom,$settings,$allitems,$rowtotal) = @_;
2208: unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {
2209: return;
2210: }
2211: my @ordered = &get_other_items($cdom,$settings,$allitems);
2212: my %items;
2213: foreach my $parameter (@ordered) {
2214: $items{$parameter} = {
2215: text => '<b>'.$parameter.'</b>',
2216: input => 'textbox',
2217: size => '15',
2218: },
2219: }
2220: push (@ordered,'newp_value');
2221: $items{'newp_value'} = {
2222: text => '<b>'.&mt('Create New Environment Variable').'</b><br />'.
2223: '<input type="textbox" name="newp_name"'.
2224: ' value="" size="30" />',
2225: input => 'textbox',
2226: size => '30',
2227: };
2228: my $output = &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal);
2229: }
2230:
2231: sub get_other_items {
2232: my ($cdom,$settings,$allitems) = @_;
2233: unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {
2234: return;
2235: }
2236: my @ordered;
2237: if (ref($settings) eq 'HASH') {
2238: foreach my $parameter (sort(keys(%{$settings}))) {
2239: next if (grep/^\Q$parameter\E$/,@{$allitems});
2240: next if (($parameter eq 'course.helper.not.run') &&
2241: (!exists($env{'user.role.dc./'.$env{'request.role.domain'}.'/'})));
2242: unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) ||
2243: ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/)
2244: || ($parameter eq 'type') ||
2245: ($parameter =~ m/^(cc|in|ta|ep|ad|st)\.plaintext$/)) {
2246: push(@ordered,$parameter);
2247: }
2248: }
2249: }
2250: return @ordered;
2251: }
2252:
2253: sub item_table_row_start {
2254: my ($text,$count) = @_;
2255: my $output;
2256: if ($count%2) {
2257: $output .= '<tr class="LC_odd_row">';
2258: } else {
2259: $output .= '<tr>';
2260: }
2261: $output .= '<td class="LC_left_item">'.$text.
2262: '</td><td class="LC_right_item" align="right">';
2263: return $output;
2264: }
2265:
2266: sub item_table_row_end {
2267: return '</td></tr>';
2268: }
2269:
2270: sub yesno_radio {
2271: my ($item,$settings) = @_;
2272: my $itemon = ' ';
2273: my $itemoff = ' checked="checked" ';
2274: if (ref($settings) eq 'HASH') {
2275: if ($settings->{$item} eq 'yes') {
2276: $itemon = $itemoff;
2277: $itemoff = ' ';
2278: }
2279: }
2280: return '<span class="LC_nobreak"><label>'.
2281: '<input type="radio" name="'.$item.'"'.
2282: $itemon.' value="yes" />'.&mt('Yes').'</label> '.
2283: '<label><input type="radio" name="'.$item.'"'.
2284: $itemoff.' value="" />'.&mt('No').'</label></span>';
2285: }
2286:
2287: sub select_from_options {
2288: my ($item,$order,$options,$curr,$nullval,$multiple,$maxsize,$onchange) = @_;
2289: my $output;
2290: if ((ref($order) eq 'ARRAY') && (ref($options) eq 'HASH')) {
2291: $output='<select name="'.$item.'" '.$onchange;
2292: if ($multiple) {
2293: $output .= ' multiple="multiple"';
2294: my $num = @{$order};
2295: $num ++ if ($nullval ne '');
2296: if (($maxsize) && ($maxsize < $num)) {
2297: $output .= ' size="'.$maxsize.'"';
2298: }
2299: }
2300: $output .= '>'."\n";
2301: if ($nullval ne '') {
2302: $output .= '<option value=""';
2303: if (ref($curr) eq 'ARRAY') {
2304: if ((@{$curr} == 0) || (grep(/^$/,@{$curr}))) {
2305: $output .= ' selected="selected" ';
2306: }
2307: } else {
2308: if ($curr eq '') {
2309: $output .= ' selected="selected" ';
2310: }
2311: }
2312: $output .= '>'.$nullval.'</option>';
2313: }
2314: foreach my $option (@{$order}) {
2315: $output.= '<option value="'.$option.'"';
2316: if (ref($curr) eq 'ARRAY') {
2317: if (grep(/^\Q$option\E$/,@{$curr})) {
2318: $output .= ' selected="selected" ';
2319: }
2320: } else {
2321: if ($option eq $curr) {
2322: $output.=' selected="selected"';
2323: }
2324: }
2325: $output.=">$options->{$option}</option>\n";
2326: }
2327: $output.="</select>";
2328: }
2329: return $output;
2330: }
2331:
2332: sub make_item_rows {
2333: my ($cdom,$items,$ordered,$settings,$rowtotal) = @_;
2334: my $datatable;
2335: if ((ref($items) eq 'HASH') && (ref($ordered) eq 'ARRAY')) {
2336: my $count = 0;
2337: foreach my $item (@{$ordered}) {
2338: $count ++;
2339: $datatable .= &item_table_row_start($items->{$item}{text},$count);
2340: if ($item eq 'nothideprivileged') {
2341: $datatable .= ¬hidepriv_row($cdom,$item,$settings);
2342: } elsif ($item eq 'print_header_format') {
2343: $datatable .= &print_hdrfmt_row($item,$settings);
2344: } elsif ($items->{$item}{input} eq 'dates') {
2345: $datatable .=
2346: &Apache::lonhtmlcommon::date_setter('display',$item,
2347: $settings->{$item});
2348: } elsif ($items->{$item}{input} eq 'radio') {
2349: $datatable .= &yesno_radio($item,$settings);
2350: } elsif ($items->{$item}{input} eq 'selectbox') {
2351: my $curr = $settings->{$item};
2352: $datatable .=
2353: &select_from_options($item,$items->{$item}{'order'},
2354: $items->{$item}{'options'},$curr,
2355: $items->{$item}{'nullval'});
2356: } elsif ($items->{$item}{input} eq 'textbox') {
2357: $datatable .=
2358: &Apache::lonhtmlcommon::textbox($item,$settings->{$item},
2359: $items->{$item}{size});
2360: }
2361: $datatable .= &item_table_row_end();
2362: }
2363: if (ref($rowtotal)) {
2364: $$rowtotal += scalar(@{$ordered});
2365: }
2366: }
2367: return $datatable;
2368: }
2369:
2370: sub nothidepriv_row {
2371: my ($cdom,$item,$settings) = @_;
2372: my ($cnum) = &get_course();
2373: my %nothide;
2374: my $datatable;
2375: if (ref($settings) eq 'HASH') {
2376: if ($settings->{$item} ne '') {
2377: foreach my $user (split(/\s*\,\s*/,$settings->{$item})) {
2378: if ($user !~ /:/) {
2379: $nothide{join(':',split(/[\@]/,$user))}=1;
2380: } else {
2381: $nothide{$user} = 1;
2382: }
2383: }
2384: }
2385: }
2386: my %coursepersonnel = &Apache::lonnet::dump('nohist_userroles',$cdom,$cnum);
2387: my $now = time;
2388: my @privusers;
2389: my %privileged;
2390: foreach my $person (keys(%coursepersonnel)) {
2391: my ($role,$user,$usec) = ($person =~ /^([^:]*):([^:]+:[^:]+):([^:]*)/);
2392: $user =~ s/:$//;
2393: my ($end,$start) = split(/:/,$coursepersonnel{$person});
2394: if ($end == -1 || $start == -1) {
2395: next;
2396: }
2397: my ($uname,$udom) = split(':',$user);
2398: unless (ref($privileged{$udom}) eq 'HASH') {
2399: my %dompersonnel = &Apache::lonnet::get_domain_roles($udom,['dc'],undef,$now);
2400: $privileged{$udom} = {};
2401: if (keys(%dompersonnel)) {
2402: foreach my $server (keys(%dompersonnel)) {
2403: foreach my $user (sort(keys(%{$dompersonnel{$server}}))) {
2404: my ($trole,$uname,$udom) = split(/:/,$user);
2405: $privileged{$udom}{$uname} = $trole;
2406: }
2407: }
2408: }
2409: }
2410: if (exists($privileged{$udom}{$uname})) {
2411: push(@privusers,$user);
2412: }
2413: }
2414: if (@privusers) {
2415: $datatable .= '<table align="right">';
2416: foreach my $user (sort(@privusers)) {
2417: my $hideon = ' checked="checked" ';
2418: my $hideoff = '';
2419: if ($nothide{$user}) {
2420: $hideoff = $hideon;
2421: $hideon = '';
2422: }
2423: my ($uname,$udom) = split(':',$user);
2424: $datatable .= '<tr><td align="left">'.
2425: &Apache::loncommon::aboutmewrapper(
2426: &Apache::loncommon::plainname($uname,$udom,'firstname'),
2427: $uname,$udom,'aboutuser').
2428: '</td><td align="left">'.
2429: '<span class="LC_nobreak"><label>'.
2430: '<input type="radio" name="'.$item.'_'.$user.'"'.
2431: $hideon.' value="yes" />'.&mt('Hidden').'</label> '.
2432: '<label><input type="radio" name="'.$item.'_'.$user.'"'. $hideoff.' value="" />'.&mt('Shown').'</label></span></td>'.
2433: '</tr>';
2434: }
2435: $datatable .= '</table>';
2436: } else {
2437: $datatable .= &mt('No Domain Coordinators have course roles');
2438: }
2439: return $datatable;
2440: }
2441:
2442: sub print_hdrfmt_row {
2443: my ($item,$settings) = @_;
2444: my @curr;
2445: my $currnum = 0;
2446: my $maxnum = 2;
2447: my $currstr;
2448: if ($settings->{$item} ne '') {
2449: $currstr .= '<b>'.&mt('Current print header:').' <span class="LC_warning"><tt>'.
2450: $settings->{$item}.'</tt></span></b><br />';
2451: my @current = split(/(%\d*[nca])/,$settings->{$item});
2452: foreach my $item (@current) {
2453: unless ($item eq '') {
2454: push(@curr,$item);
2455: }
2456: }
2457: $currnum = @curr;
2458: $maxnum += $currnum;
2459: }
2460:
2461: my $output = <<ENDJS;
2462:
2463: <script type="text/javascript" language="Javascript">
2464:
2465: function reOrder(chgnum) {
2466: var maxnum = $maxnum;
2467: var oldidx = 'printfmthdr_oldpos_'+chgnum;
2468: var newidx = 'printfmthdr_pos_'+chgnum;
2469: oldidx = getIndexByName(oldidx);
2470: newidx = getIndexByName(newidx);
2471: var oldpos = document.display.elements[oldidx].value;
2472: var newpos = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
2473: document.display.elements[oldidx].value = newpos;
2474: var chgtype = 'up';
2475: if (newpos < oldpos) {
2476: chgtype = 'down';
2477: }
2478: for (var j=0; j<maxnum; j++) {
2479: if (j != chgnum) {
2480: oldidx = 'printfmthdr_oldpos_'+j;
2481: newidx = 'printfmthdr_pos_'+j;
2482: oldidx = getIndexByName(oldidx);
2483: newidx = getIndexByName(newidx);
2484: var currpos = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
2485: var currsel = document.display.elements[newidx].selectedIndex;
2486: if (chgtype == 'up') {
2487: if ((currpos > oldpos) && (currpos <= newpos)) {
2488: document.display.elements[newidx].selectedIndex = currsel-1;
2489: document.display.elements[oldidx].value = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
2490: }
2491: } else {
2492: if ((currpos >= newpos) && (currpos < oldpos)) {
2493: document.display.elements[newidx].selectedIndex = currsel+1;
2494: document.display.elements[oldidx].value = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
2495: }
2496: }
2497: }
2498: }
2499: return;
2500: }
2501:
2502: function getIndexByName(item) {
2503: for (var i=0;i<document.display.elements.length;i++) {
2504: if (document.display.elements[i].name == item) {
2505: return i;
2506: }
2507: }
2508: return -1;
2509: }
2510:
2511: </script>
2512:
2513: ENDJS
2514: $output .= $currstr.&Apache::loncommon::start_data_table();
2515: if (@curr > 0) {
2516: for (my $i=0; $i<@curr; $i++) {
2517: my $pos = $i+1;
2518: $output .= &Apache::loncommon::start_data_table_row().
2519: '<td align="left"><span class="LC_nobreak">'.
2520: &position_selector($pos,$i,$maxnum).&mt('Delete:').
2521: '<input type="checkbox" name="printfmthdr_del_'.$i.
2522: '" /></span></td>';
2523: if ($curr[$i] =~ /^%\d*[nca]$/) {
2524: my ($limit,$subst) = ($curr[$i] =~ /^%(\d*)([nca])$/);
2525: $output .= '<td align="left">'.
2526: &substitution_selector($i,$subst,$limit).'</td>';
2527: } else {
2528: $output .= '<td colspan="2" align="left">'.&mt('Text').'<br />'.
2529: '<input type="textbox" name="printfmthdr_text_'.$i.'"'.
2530: ' value="'.$curr[$i].'" size="25" /></td>';
2531: }
2532: $output .= &Apache::loncommon::end_data_table_row();
2533: }
2534: }
2535: my $pos = $currnum+1;
2536: $output .= &Apache::loncommon::start_data_table_row().
2537: '<td align="left"><span class="LC_nobreak">'.
2538: &position_selector($pos,$currnum,$maxnum).
2539: '<b>'.&mt('New').'</b></span></td><td align="left">'.
2540: &substitution_selector($currnum).'</td>'.
2541: &Apache::loncommon::end_data_table_row();
2542: $pos ++;
2543: $currnum ++;
2544: $output .= &Apache::loncommon::start_data_table_row().
2545: '<td align="left"><span class="LC_nobreak">'.
2546: &position_selector($pos,$currnum,$maxnum).
2547: '<b>'.&mt('New').'</b></span></td>'.
2548: '<td colspan="2" align="left">'.&mt('Text').'<br />'.
2549: '<input type="textbox" name="printfmthdr_text_'.$currnum.
2550: '" value="" size ="25" />'.
2551: '<input type="hidden" name="printfmthdr_maxnum" value="'.
2552: $maxnum.'" /></td>'.
2553: &Apache::loncommon::end_data_table_row().
2554: &Apache::loncommon::end_data_table();
2555: return $output;
2556: }
2557:
2558: sub position_selector {
2559: my ($pos,$num,$maxnum) = @_;
2560: my $output = '<select name="printfmthdr_pos_'.$num.'" onchange="reOrder('."'$num'".');">';
2561: for (my $j=1; $j<=$maxnum; $j++) {
2562: my $sel = '';
2563: if ($pos == $j) {
2564: $sel = ' selected="selected"';
2565: }
2566: $output .= '<option value="'.$j.'"'.$sel.'">'.$j.'</option>';
2567: }
2568: $output .= '</select><input type="hidden" name="printfmthdr_oldpos_'.$num.
2569: '" value="'.$pos.'" />';
2570: return $output;
2571: }
2572:
2573: sub substitution_selector {
2574: my ($num,$subst,$limit) = @_;
2575: my %lt = &Apache::lonlocal::texthash(
2576: n => 'student name',
2577: c => 'course ID',
2578: a => 'assignment note',
2579: );
2580: my $output .= &mt('Substitution').'<br />'.
2581: '<select name=""printfmthdr_sub__'.$num.'">';
2582: if ($subst eq '') {
2583: $output .= '<option value="" selected="selected"> </option>';
2584: }
2585: foreach my $field ('n','c','a') {
2586: my $sel ='';
2587: if ($subst eq $field) {
2588: $sel = ' selected="selected"';
2589: }
2590: $output .= '<option value="'.$field.'"'.$sel.'>'.
2591: $lt{$field}.'</option>';
2592: }
2593: $output .= '</select></td><td align="left">'.&mt('Size limit').'<br />'.
2594: '<input type="textbox" name="printfmthdr_limit_'.$num.
2595: '" value="'.$limit.'" size="5" /></span>';
2596: return $output;
2597: }
2598:
2599: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>