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