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