Annotation of loncom/interface/courseprefs.pm, revision 1.49.2.11
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.49.2.11! raeburn 4: # $Id: courseprefs.pm,v 1.49.2.10 2013/09/01 02:09:23 raeburn Exp $
1.1 raeburn 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA#
23: # /home/httpd/html/adm/gpl.txt
24: #
25: # http://www.lon-capa.org/
26: #
27: #
28: ###############################################################
29: ##############################################################
30:
1.23 raeburn 31: =pod
32:
33: =head1 NAME
34:
35: courseprefs- Handler to set/modify course configuration
36:
37: =head1 SYNOPSIS
38:
39: courseprefs provides an interface for setting general course configuration
40:
41: =head1 DESCRIPTION
42:
43: This module is used for configuration of a course
44:
45: =head1 INTERNAL SUBROUTINES
46:
47: =over
48:
49: =item get_allitems()
50:
51: =item print_config_box()
52:
53: =item process_changes()
54:
55: =item get_sec_str()
56:
57: =item check_clone()
58:
59: =item store_changes()
60:
61: =item update_env()
62:
63: =item display_disallowed()
64:
65: =item get_course()
66:
67: =item get_jscript()
68:
69: =item cloners_javascript()
70:
71: =item print_courseinfo()
72:
73: =item new_cloners_dom_row()
74:
75: =item can_modify_catsettings()
76:
77: =item assign_course_categories()
78:
79: =item print_localization()
80:
81: =item get_lang_choices()
82:
83: =item print_feedback()
84:
85: =item user_table()
86:
87: =item select_recipient()
88:
89: =item select_sections()
90:
91: =item print_discussion()
92:
93: =item role_checkboxes()
94:
95: =item print_classlists()
96:
97: =item print_appearance()
98:
99: =item print_grading()
100:
101: =item print_printouts()
102:
103: =item print_spreadsheet()
104:
105: =item print_bridgetasks()
106:
107: =item print_other()
108:
109: =item get_other_items()
110:
111: =item item_table_row_start()
112:
113: =item item_table_row_end()
114:
115: =item yes_no_radio()
116:
117: =item select_from_options()
118:
119: =item make_item_rows()
120:
121: Creates table used to display and set course configuration items.
122:
123: Inputs: $cdom,$items,$ordered,$settings,$rowtotal,$crstype
124: where $cdom is course's domain, $items is HASH ref for current config
125: item, $ordered is ARRAY ref of items to include in row in
126: display order, $settings is HASH ref of current values forrow,
127: $rowtotal is SCALAR ref used to accumulate row count, $crstype is
128: course type.
129:
130: Returns: $datatable
131: HTML mark-up of data table which accumulates individual rows.
132:
133: =item nothidepriv_row()
134:
135: Creates row containing form elements used to display and set
136: whether Domain coordinators who are currently included in
137: advanced course user .db file for a course are to be hidden (e.g.,
138: in syllabus, or from course user lists).
139:
140: Inputs: $cdom,$item,$settings,$crstype
141: where $cdom is course domain, item is nothideprivileged, $settings is
142: HASH ref of the current values for nothideprivileged, $crstype is
143: course type (Course or Community).
144:
145: Return: $datatable
146: HTML mark-up for Privileged users (Domain Coordinators) in staff listing.
147:
148: =item print_hdrfmt_row()
149:
150: Creates row containing form elements used to display and set
151: substitution items and text to be used in the header included
152: on printouts.
153:
154: Inputs: $item,$settings
155: where $item is print_header_format, and $settings is a HASH ref
156: of the current values stored for print_header_format.
157:
158: Returns: $output
159: HTML mark-up containing Javascript functions: reOrder() and getIndexByName()
160: used to dynamically update position selectboxes, and HTML table elements
161: for the "Print header format" row.
162:
163: =item position_selector()
164:
165: Creates a select box which can be used to reorder substitutions
166: and text included in a printout header.
167:
168: Inputs: $pos,$num,$maxnum
169: where $pos is current position, $num is the unique identifier,
170: and $maxnum is the total number of items (both substitutions
171: and text in the printout header.
172:
173: Returns: $output
174: HTML mark-up for the selectbox and a hidden form element containing
175: the current position.
176:
177: =item substitution_selector()
178:
179: Creates a combination of select box for choosing an item
180: (student name, course ID or assignment note) to substitute,
181: and a corresponding size limit in the header used for printouts.
182:
183: Inputs: $num,$subst,$limit,$crstype
184: where $num is the unique identifier, $subst is the current
185: substitution (n,c or a, for name, course or note respectively,
186: $limit is the current size limit (integer), and $crstype is
187: course type - course or community.
188:
189: Returns: $output
190: HTML mark-up for selectbox and textbox (separate table cells).
191:
192: =item change_clone()
193:
194: Modifies the list of courses a user can clone (stored
195: in the user's environment.db file), called when a
196: change is made to the list of users allowed to clone
197: a course.
198:
199: Inputs: $action,$cloner
200: where $action is add or drop, and $cloner is identity of
201: user for whom cloning ability is to be changed in course.
202:
203: Returns: nothing
204:
205: =back
206:
207: =cut
208:
209:
1.1 raeburn 210: package Apache::courseprefs;
211:
212: use strict;
213: use Apache::Constants qw(:common :http);
214: use Apache::lonnet;
215: use Apache::loncommon();
216: use Apache::lonhtmlcommon();
217: use Apache::lonconfigsettings;
1.36 raeburn 218: use Apache::lonparmset;
1.1 raeburn 219: use Apache::lonlocal;
220: use LONCAPA qw(:DEFAULT :match);
221:
222: sub handler {
223: my $r=shift;
224: if ($r->header_only) {
225: &Apache::loncommon::content_type($r,'text/html');
226: $r->send_http_header;
227: return OK;
228: }
229: my $context = 'course';
230: my $cid = $env{'request.course.id'};
231: my ($cnum,$cdom) = &get_course($cid);
232: my $crstype = &Apache::loncommon::course_type();
233: my $parm_permission = &Apache::lonnet::allowed('opa',$cid);
234: my $navmap = Apache::lonnavmaps::navmap->new();
235: if ($parm_permission && $navmap) {
236: &Apache::loncommon::content_type($r,'text/html');
237: $r->send_http_header;
238: } else {
239: if ($navmap) {
1.9 raeburn 240: if ($crstype eq 'Community') {
241: $env{'user.error.msg'}=
242: "/adm/courseprefs:opa:0:0:Cannot modify community settings";
243: } else {
244: $env{'user.error.msg'}=
245: "/adm/courseprefs:opa:0:0:Cannot modify course settings";
246: }
1.1 raeburn 247: } else {
1.9 raeburn 248: if ($crstype eq 'Community') {
249: $env{'user.error.msg'}=
250: "/adm/courseprefs::0:1:Course environment gone, reinitialize the community";
251: } else {
252: $env{'user.error.msg'}=
253: "/adm/courseprefs::0:1:Course environment gone, reinitialize the course";
254:
255: }
1.1 raeburn 256: }
257: return HTTP_NOT_ACCEPTABLE;
258: }
259:
1.4 raeburn 260: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
261: ['phase','actions','origin']);
1.1 raeburn 262: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.4 raeburn 263: if ($env{'form.origin'} eq 'params') {
264: &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset",
265: text=>"Parameter Manager"});
266: }
1.9 raeburn 267: my ($brtext,$brtitle,$crsinfotext,$crsinfodesc,$crscateg,$crshide);
268: my %lt;
269: if ($crstype eq 'Community') {
270: %lt = (
1.40 www 271: conf => 'Community Settings',
272: edit => 'Edit Community Settings',
1.9 raeburn 273: gens => 'General community settings',
274: idnu => 'Community ID or number',
275: desc => 'Community Description',
1.24 raeburn 276: ownr => 'Community Owner',
1.25 raeburn 277: cown => 'Community Co-owners',
1.9 raeburn 278: catg => 'Categorize community',
279: excc => 'Exclude from community catalog',
280: clon => 'Users allowed to clone community',
281: rept => 'Replacement titles for standard community roles',
282: time => 'Timezone where the community is located',
283: date => 'Locale used for community calendar',
284: coco => 'Community Content',
285: copo => 'Community Policy',
1.13 bisitz 286: priv => 'Domain Coordinators in community',
1.9 raeburn 287: defd => 'Default dates for member access',
288: stuv => 'Member-viewable membership list options',
289: stul => 'Member agreement needed to be listed',
1.42 www 290: clas => 'Membership and facilitator listing',
1.49.2.7 raeburn 291: prus => 'Privileged users (Domain Coordinators) in facilitator listing',
1.9 raeburn 292: defc => 'Default Community Spreadsheet',
293: defs => 'Default User Spreadsheet',
294: seme => 'Send message to member when clicking Done on Tasks'
295: );
296: } else {
297: %lt = (
1.40 www 298: conf => 'Course Settings',
299: edit => 'Edit Course Settings',
1.20 faziophi 300: gens => 'General course settings',
301: idnu => 'Course ID or number',
302: desc => 'Course Description',
1.49.2.6 raeburn 303: cred => 'Student credits',
1.24 raeburn 304: ownr => 'Course Owner',
1.25 raeburn 305: cown => 'Course Co-owners',
1.9 raeburn 306: catg => 'Categorize course',
307: excc => 'Exclude from course catalog',
308: clon => 'Users allowed to clone course',
309: rept => 'Replacement titles for standard course roles',
1.20 faziophi 310: time => 'Timezone in which the course takes place',
311: date => 'Locale used for course calendar',
1.9 raeburn 312: coco => 'Course Content',
313: copo => 'Course Policy',
1.13 bisitz 314: priv => 'Domain Coordinators in course',
1.9 raeburn 315: defd => 'Default dates for student access',
316: stuv => 'Student-viewable classlist options',
317: stul => 'Student agreement needed to be listed',
1.42 www 318: clas => 'Classlists and staff listing',
1.49.2.7 raeburn 319: prus => 'Privileged users (Domain Coordinators) in staff listing',
320: prdo => "Domains to check for privileged users (besides course's domain)",
1.9 raeburn 321: defc => 'Default Course Spreadsheet',
322: defs => 'Default Student Spreadsheet',
323: seme => 'Send message to student when clicking Done on Tasks',
324: );
325: }
1.35 raeburn 326: $lt{'lcrv'} = 'Required LON-CAPA version';
1.1 raeburn 327: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/courseprefs',
1.9 raeburn 328: text=>$lt{'conf'}});
1.1 raeburn 329: my $breadcrumbs =
1.9 raeburn 330: &Apache::lonhtmlcommon::breadcrumbs($lt{'edit'});
1.1 raeburn 331:
332: my $phase = 'pickactions';
333: if ( exists($env{'form.phase'}) ) {
334: $phase = $env{'form.phase'};
335: }
336:
337: if ($phase eq 'categorizecourse') {
1.9 raeburn 338: &assign_course_categories($r,$crstype);
1.1 raeburn 339: return OK;
340: }
341:
1.36 raeburn 342: if ($phase eq 'releaseinfo') {
343: my $loncaparev = $env{'course.'.$cid.'.internal.releaserequired'};
344: if ($loncaparev) {
345: &display_loncaparev_constraints($r,$navmap,$loncaparev,$crstype);
346: return OK;
347: }
348: }
349:
1.1 raeburn 350: my %values=&Apache::lonnet::dump('environment',$cdom,$cnum);
351: my @prefs_order = ('courseinfo','localization','feedback','discussion',
352: 'classlists','appearance','grading','printouts',
353: 'spreadsheet','bridgetasks','other');
354:
355: my %prefs = (
356: 'courseinfo' =>
1.9 raeburn 357: { text => $lt{'gens'},
1.44 www 358: help => 'Course_Prefs_General',
1.35 raeburn 359: ordered => ['owner','co-owners','loncaparev','description',
1.49.2.11! raeburn 360: 'clonedfrom','courseid','categories','hidefromcat',
1.35 raeburn 361: 'externalsyllabus','cloners','url','rolenames'],
1.3 raeburn 362: itemtext => {
1.25 raeburn 363: 'owner' => $lt{'ownr'},
364: 'co-owners' => $lt{'cown'},
365: 'description' => $lt{'desc'},
366: 'courseid' => $lt{'idnu'},
367: 'categories' => $lt{'catg'},
368: 'hidefromcat' => $lt{'excc'},
369: 'cloners' => $lt{'clon'},
1.49.2.10 raeburn 370: 'externalsyllabus' => 'Syllabus status',
1.25 raeburn 371: 'url' => 'Top Level Map',
372: 'rolenames' => $lt{'rept'},
1.35 raeburn 373: 'loncaparev' => $lt{'lcrv'},
1.49.2.11! raeburn 374: 'clonedfrom' => 'Cloned from',
1.3 raeburn 375: },
1.1 raeburn 376: },
377: 'localization' =>
1.42 www 378: { text => 'Language and time localization',
1.44 www 379: help => 'Course_Prefs_Language',
1.1 raeburn 380: ordered => ['languages','timezone','datelocale'],
1.3 raeburn 381: itemtext => {
1.20 faziophi 382: languages => 'Languages used',
1.9 raeburn 383: timezone => $lt{'time'},
384: datelocale => $lt{'date'},
1.3 raeburn 385: },
1.1 raeburn 386: },
387: 'feedback' =>
1.20 faziophi 388: { text => 'Feedback messages',
1.44 www 389: help => 'Course_Prefs_Feedback',
1.1 raeburn 390: header => [{col1 => 'Questions about:',
1.20 faziophi 391: col2 => 'Recipients'}],
1.3 raeburn 392: ordered => ['question.email','comment.email','policy.email'],
393: itemtext => {
394: 'question.email' => 'Resource Content',
1.9 raeburn 395: 'comment.email' => $lt{'coco'},
396: 'policy.email' => $lt{'copo'},
1.3 raeburn 397: },
1.1 raeburn 398: },
399: 'discussion' =>
400: { text => 'Discussion and Chat',
1.44 www 401: help => 'Course_Prefs_Discussions',
1.31 raeburn 402: ordered => ['pch.roles.denied','pch.users.denied',
403: 'plc.roles.denied','plc.users.denied',
1.1 raeburn 404: 'allow_limited_html_in_feedback',
1.49.2.3 raeburn 405: 'allow_discussion_post_editing',
406: 'discussion_post_fonts'],
1.3 raeburn 407: itemtext => {
1.31 raeburn 408: 'pch.roles.denied' => 'No Resource Discussion',
409: 'pch.users.denied' => 'No Resource Discussion',
410: 'plc.roles.denied' => 'No Chat room use',
411: 'plc.users.denied' => 'No Chat room use',
1.20 faziophi 412: allow_limited_html_in_feedback => 'Allow limited HTML in discussion',
413: allow_discussion_post_editing => 'Users can edit/delete own discussion posts',
1.49.2.3 raeburn 414: discussion_post_fonts => 'Discussion post fonts based on likes/unlikes',
1.3 raeburn 415: },
1.1 raeburn 416: },
417: 'classlists' =>
1.9 raeburn 418: { text => $lt{'clas'},
1.44 www 419: help => 'Course_Prefs_Classlists',
1.1 raeburn 420: header => [{col1 => 'Type',
1.9 raeburn 421: col2 => $lt{'defd'}},
1.1 raeburn 422: {col1 => 'Setting',
1.9 raeburn 423: col2 => $lt{'priv'}},
1.1 raeburn 424: {col1 => 'Setting',
1.9 raeburn 425: col2 => $lt{'stuv'}}],
1.1 raeburn 426: ordered => ['default_enrollment_start_date',
427: 'default_enrollment_end_date',
1.49.2.6 raeburn 428: 'defaultcredits',
1.49.2.7 raeburn 429: 'nothideprivileged','checkforpriv',
430: 'student_classlist_view',
1.26 raeburn 431: 'student_classlist_opt_in','student_classlist_portfiles'],
1.3 raeburn 432: itemtext => {
433: default_enrollment_start_date => 'Start date',
434: default_enrollment_end_date => 'End date',
1.49.2.7 raeburn 435: nothideprivileged => $lt{'prus'},
436: checkforpriv => $lt{'prdo'},
1.9 raeburn 437: student_classlist_view => $lt{'stuv'},
1.26 raeburn 438: student_classlist_opt_in => $lt{'stul'},
1.3 raeburn 439: student_classlist_portfiles => 'Include link to accessible portfolio files',
1.49.2.6 raeburn 440: defaultcredits => $lt{'cred'},
1.3 raeburn 441: },
1.1 raeburn 442: },
443: 'appearance' =>
1.20 faziophi 444: { text => 'Display of resources ',
1.44 www 445: help => 'Course_Prefs_Display',
1.1 raeburn 446: ordered => ['default_xml_style','pageseparators',
447: 'disable_receipt_display','texengine',
448: 'tthoptions'],
1.3 raeburn 449: itemtext => {
1.17 faziophi 450: default_xml_style => 'Default XML style file',
1.20 faziophi 451: pageseparators => 'Visibly Separate Items on Pages',
452: disable_receipt_display => 'Disable display of problem receipts',
453: texengine => 'Force use of a specific math rendering engine',
1.3 raeburn 454: tthoptions => 'Default set of options to pass to tth/m when converting TeX',
455: },
1.1 raeburn 456: },
457: 'grading' =>
458: { text => 'Grading',
1.44 www 459: help => 'Course_Prefs_Grading',
1.1 raeburn 460: ordered => ['grading','rndseed',
461: 'receiptalg','disablesigfigs'],
1.3 raeburn 462: itemtext => {
1.20 faziophi 463: grading => 'Grading',
464: rndseed => 'Randomization algorithm used',
465: receiptalg => 'Receipt algorithm used',
466: disablesigfigs => 'Disable checking of Significant Figures',
1.3 raeburn 467: },
468:
1.1 raeburn 469: },
470: 'printouts' =>
1.20 faziophi 471: { text => 'Printout generation',
1.44 www 472: help => 'Course_Prefs_Printouts',
1.1 raeburn 473: ordered => ['problem_stream_switch','suppress_tries',
474: 'default_paper_size','print_header_format',
1.49.2.1 raeburn 475: 'disableexampointprint'],
1.3 raeburn 476: itemtext => {
477: problem_stream_switch => 'Allow problems to be split over pages',
478: suppress_tries => 'Suppress number of tries in printing',
479: default_paper_size => 'Default paper type',
480: print_header_format => 'Print header format',
1.49.2.4 raeburn 481: disableexampointprint => 'Disable automatically printing point values on bubblesheet exams',
1.14 raeburn 482: canuse_pdfforms => 'Users can print problems as PDF forms and upload later for grading',
1.3 raeburn 483: },
1.1 raeburn 484: },
485: 'spreadsheet' =>
486: { text => 'Spreadsheets',
1.44 www 487: help => 'Course_Prefs_Spreadsheet',
1.1 raeburn 488: ordered => ['spreadsheet_default_classcalc',
489: 'spreadsheet_default_studentcalc',
490: 'spreadsheet_default_assesscalc','hideemptyrows'],
1.3 raeburn 491: itemtext => {
1.9 raeburn 492: spreadsheet_default_classcalc => $lt{'defc'},
493: spreadsheet_default_studentcalc => $lt{'defs'},
1.3 raeburn 494: spreadsheet_default_assesscalc => 'Default Assessment Spreadsheet',
495: hideemptyrows => 'Hide Empty Rows in Spreadsheets',
496: },
1.1 raeburn 497: },
498: 'bridgetasks' =>
499: { text => 'Bridge tasks',
1.44 www 500: help => 'Course_Prefs_Bridgetasks',
1.1 raeburn 501: ordered => ['task_messages','task_grading',
502: 'suppress_embed_prompt'],
1.3 raeburn 503: itemtext => {
1.9 raeburn 504: task_messages => $lt{'seme'},
1.3 raeburn 505: task_grading => 'Bridge Task grading by instructors and TAs in sections' ,
1.5 raeburn 506: suppress_embed_prompt => 'Hide upload references prompt if uploading file to portfolio',
1.3 raeburn 507: },
1.1 raeburn 508: },
509: 'other' =>
510: { text => 'Other settings',
1.44 www 511: help => 'Course_Prefs_Other',
1.1 raeburn 512: header => [ {col1 => 'Item',
513: col2 => 'Value',
514: }],
515: },
516: );
517: if ($phase eq 'process') {
1.3 raeburn 518: my @allitems = &get_allitems(%prefs);
1.1 raeburn 519: &Apache::lonconfigsettings::make_changes($r,$cdom,$phase,$context,
1.3 raeburn 520: \@prefs_order,\%prefs,\%values,
1.47 www 521: $cnum,undef,\@allitems,'coursepref');
1.1 raeburn 522: } elsif ($phase eq 'display') {
1.36 raeburn 523: my $jscript = &get_jscript($cid,$cdom,$phase,$crstype);
1.3 raeburn 524: my @allitems = &get_allitems(%prefs);
1.1 raeburn 525: &Apache::lonconfigsettings::display_settings($r,$cdom,$phase,$context,
1.47 www 526: \@prefs_order,\%prefs,\%values,undef,$jscript,\@allitems,$crstype,'coursepref');
1.1 raeburn 527: } else {
528: &Apache::lonconfigsettings::display_choices($r,$phase,$context,
1.47 www 529: \@prefs_order,\%prefs,'coursepref');
1.1 raeburn 530: }
531: return OK;
532: }
533:
1.3 raeburn 534: sub get_allitems {
535: my (%prefs) = @_;
536: my @allitems;
537: foreach my $item (keys(%prefs)) {
538: if (ref($prefs{$item}) eq 'HASH') {
539: if (ref($prefs{$item}{'ordered'}) eq 'ARRAY') {
540: push(@allitems,@{$prefs{$item}{'ordered'}});
541: if ($item eq 'feedback') {
542: push(@allitems,(map { $_.'.text'; } @{$prefs{$item}{'ordered'}}));
543: }
544: }
545: }
546: }
547: return @allitems;
548: }
549:
1.1 raeburn 550: sub print_config_box {
1.9 raeburn 551: my ($r,$cdom,$phase,$action,$item,$settings,$allitems,$crstype) = @_;
1.1 raeburn 552: my $ordered = $item->{'ordered'};
1.3 raeburn 553: my $itemtext = $item->{'itemtext'};
1.1 raeburn 554: my $rowtotal = 0;
555: my $output =
1.45 www 556: '<table class="LC_nested_outer">
557: <tr>
558: <th align="left" valign="middle"><span class="LC_nobreak" style="font-size: larger;" >'.
1.49.2.4 raeburn 559: &mt($item->{text});
560: if ($item->{'help'}) {
561: $output .= ' '.
562: &Apache::loncommon::help_open_topic($item->{'help'});
563: }
564: $output .= '</span></th>'."\n".
565: '</tr>';
1.1 raeburn 566: if (($action eq 'feedback') || ($action eq 'classlists')) {
567: $output .= '
1.45 www 568: <tr>
569: <td>
1.18 faziophi 570: <table class="LC_nested">';
571: if (exists $item->{'header'}->[0]->{'col1'} ||
572: exists $item->{'header'}->[0]->{'col2'}) {
573: $output .= '
574: <tr class="LC_info_row">
1.49.2.7 raeburn 575: <td class="LC_left_item">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
576: if ($action eq 'feedback') {
577: $output .= '
578: <td class="LC_right_item" colspan="2">';
579: } else {
580: $output .= '
581: <td class="LC_right_item">';
582: }
583: $output .= &mt($item->{'header'}->[0]->{'col2'}).'</td>
1.18 faziophi 584: </tr>';
585: }
1.1 raeburn 586: $rowtotal ++;
587: if ($action eq 'feedback') {
1.3 raeburn 588: $output .= &print_feedback('top',$cdom,$settings,$ordered,$itemtext,\$rowtotal);
1.1 raeburn 589: } elsif ($action eq 'classlists') {
1.9 raeburn 590: $output .= &print_classlists('top',$cdom,$settings,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 591: }
592: $output .= '
593: </table>
1.45 www 594: </td>
595: </tr>
596: <tr>
597: <td>
1.1 raeburn 598: <table class="LC_nested">
599: <tr class="LC_info_row">
600: <td class="LC_left_item">'.&mt($item->{'header'}->[1]->{'col1'}).'</td>';
1.49.2.7 raeburn 601: if ($action eq 'classlists') {
602: $output .= '
603: <td class="LC_right_item" colspan="2">';
604: } else {
605: $output .= '
606: <td class="LC_right_item">';
607: }
608: $output .= &mt($item->{'header'}->[1]->{'col2'}).'</td>
1.1 raeburn 609: </tr>';
610: if ($action eq 'classlists') {
1.9 raeburn 611: $output .= &print_classlists('middle',$cdom,$settings,$itemtext,\$rowtotal,$crstype).
1.1 raeburn 612: '
613: </table>
1.45 www 614: </td>
615: </tr>
616: <tr>
617: <td>
1.18 faziophi 618: <table class="LC_nested">';
1.43 www 619: if (exists $item->{'header'}->[2]->{'col1'} ||
620: exists $item->{'header'}->[2]->{'col2'}) {
1.18 faziophi 621: $output .= '
622: <tr class="LC_info_row">
1.43 www 623: <td class="LC_left_item">'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
624: <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
1.18 faziophi 625: </tr>';
626: }
1.1 raeburn 627: }
628: } else {
629: $output .= '
1.45 www 630: <tr>
631: <td>
1.18 faziophi 632: <table class="LC_nested">';
633: if (exists $item->{'header'}->[0]->{'col1'} ||
634: exists $item->{'header'}->[0]->{'col2'}) {
635: $output .= '
636: <tr class="LC_info_row">
1.49.2.7 raeburn 637: <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
638: if (($action eq 'courseinfo') || ($action eq 'localization') ||
639: ($action eq 'print_discussion')) {
640: $output .= '<td class="LC_right_item" valign="top" colspan="2">';
641: } else {
642: $output .= '<td class="LC_right_item" valign="top">';
643: }
644: $output .= &mt($item->{'header'}->[0]->{'col2'}).'</td>
1.18 faziophi 645: </tr>';
646: }
1.1 raeburn 647: }
648: $rowtotal ++;
649: if ($action eq 'courseinfo') {
1.9 raeburn 650: $output .= &print_courseinfo($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 651: } elsif ($action eq 'localization') {
1.3 raeburn 652: $output .= &print_localization($cdom,$settings,$ordered,$itemtext,\$rowtotal);
1.1 raeburn 653: } elsif ($action eq 'feedback') {
1.3 raeburn 654: $output .= &print_feedback('bottom',$cdom,$settings,$ordered,$itemtext,\$rowtotal);
1.1 raeburn 655: } elsif ($action eq 'discussion') {
1.3 raeburn 656: $output .= &print_discussion($cdom,$settings,$ordered,$itemtext,\$rowtotal);
1.49.2.4 raeburn 657: } elsif (($action eq 'classlists') || ($action eq 'viewableroster')) {
1.9 raeburn 658: $output .= &print_classlists('bottom',$cdom,$settings,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 659: } elsif ($action eq 'appearance') {
1.9 raeburn 660: $output .= &print_appearance($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 661: } elsif ($action eq 'grading') {
1.9 raeburn 662: $output .= &print_grading($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 663: } elsif ($action eq 'printouts') {
1.9 raeburn 664: $output .= &print_printouts($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 665: } elsif ($action eq 'spreadsheet') {
1.9 raeburn 666: $output .= &print_spreadsheet($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 667: } elsif ($action eq 'bridgetasks') {
1.9 raeburn 668: $output .= &print_bridgetasks($cdom,$settings,$ordered,$itemtext,\$rowtotal,$crstype);
1.1 raeburn 669: } elsif ($action eq 'other') {
1.9 raeburn 670: $output .= &print_other($cdom,$settings,$allitems,\$rowtotal,$crstype);
1.1 raeburn 671: }
672: $output .= '
673: </table>
1.45 www 674: </td>
675: </tr>
676: </table><br />';
1.1 raeburn 677: return ($output,$rowtotal);
678: }
679:
680: sub process_changes {
1.9 raeburn 681: my ($cdom,$action,$values,$item,$changes,$allitems,$disallowed,$crstype) = @_;
1.3 raeburn 682: my %newvalues;
683: if (ref($item) eq 'HASH') {
684: if (ref($changes) eq 'HASH') {
685: my @ordered;
686: if ($action eq 'other') {
687: @ordered = &get_other_items($cdom,$values,$allitems);
688: if ($env{'form.newp_name'} ne '') {
689: my $newp = $env{'form.newp_name'};
690: if ($env{'form.newp_value'} ne '') {
691: if (ref($allitems) eq 'ARRAY') {
692: unless ((grep(/^\Q$newp\E$/,@ordered)) ||
693: (grep(/^\Q$newp\E$/,@{$allitems}))) {
694: $changes->{$newp} = $env{'form.newp_value'};
695: }
696: }
697: }
698: }
699: } elsif (ref($item->{'ordered'}) eq 'ARRAY') {
1.49 raeburn 700: if ($action eq 'courseinfo') {
701: my ($can_toggle_cat,$can_categorize) =
702: &can_modify_catsettings($cdom,$crstype);
703: foreach my $entry (@{$item->{'ordered'}}) {
704: next if (($entry eq 'hidefromcat') &&
705: (!$can_toggle_cat));
706: next if (($entry eq 'categories') &&
707: (!$can_categorize));
708: next if (($entry eq 'loncaparev') ||
1.49.2.11! raeburn 709: ($entry eq 'owner') ||
! 710: ($entry eq 'clonedfrom'));
1.49 raeburn 711: push(@ordered,$entry);
712: }
1.49.2.6 raeburn 713: } elsif ($action eq 'classlists') {
714: foreach my $entry (@{$item->{'ordered'}}) {
715: next if ($entry eq 'defaultcredits');
716: push(@ordered,$entry);
717: }
1.49 raeburn 718: } else {
719: @ordered = @{$item->{'ordered'}};
720: }
1.3 raeburn 721: }
722: if (@ordered > 0) {
723: if ($action eq 'feedback') {
724: foreach my $entry (@ordered) {
725: my $userstr = '';
726: my $total = $env{'form.'.$entry.'_total'};
727: if ($total) {
728: my @deletes = &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
729: for (my $i=0; $i<$total; $i++) {
730: unless (grep(/^$i$/,@deletes)) {
731: $userstr .= $env{'form.'.$entry.'_user_'.$i}.
732: &get_sec_str($entry,$i).',';
733: }
734: }
735: } else {
736: $total = 0;
737: }
738: if ($env{'form.'.$entry.'_uname_'.$total} ne '') {
739: my $uname = $env{'form.'.$entry.'_uname_'.$total};
740: my $udom = $env{'form.'.$entry.'_udom_'.$total};
741: if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
742: $userstr =~ s/,$//;
743: $disallowed->{'feedback'}{$entry} = $uname.':'.$udom;
744: } else {
745: $userstr .= $uname.':'.$udom.&get_sec_str($entry,$total);
746: }
747: } else {
748: $userstr =~ s/,$//;
749: }
750: $newvalues{$entry} = $userstr;
751: if ($newvalues{$entry} ne $values->{$entry}) {
752: $changes->{$entry} = $newvalues{$entry};
753: }
754: my $ext_entry = $entry.'.text';
755: $newvalues{$ext_entry} = $env{'form.'.$ext_entry};
756: if ($newvalues{$ext_entry} ne $values->{$ext_entry}) {
757: $changes->{$ext_entry} = $newvalues{$ext_entry};
758: }
759: }
760: } else {
761: foreach my $entry (@ordered) {
762: if ($entry eq 'cloners') {
763: if ($env{'form.cloners_all'}) {
764: $newvalues{$entry} = '*';
765: } else {
766: my @clonedoms;
767: if (exists($env{'form.cloners_activate'})) {
768: my $actnum = $env{'form.cloners_activate'};
769: if ($actnum ne '') {
1.33 raeburn 770: if ($env{'form.cloners_dom_'.$actnum} ne '') {
771: my $clonedom = $env{'form.cloners_dom_'.$actnum};
1.3 raeburn 772: if (&check_clone($clonedom,$disallowed) eq 'ok') {
773: $newvalues{$entry} = '*:'.$clonedom;
774: push(@clonedoms,$newvalues{$entry});
775: }
776: }
777: }
778: } else {
779: my $num = $env{'form.cloners_total'};
780: my @deletes =
781: &Apache::loncommon::get_env_multiple('form.cloners_delete');
782: for (my $i=0; $i<$num; $i++) {
783: if (!grep(/^$i$/,@deletes)) {
784: my $clonedom = $env{'form.cloners_dom_'.$i};
785: if (&check_clone($clonedom,$disallowed) eq 'ok') {
786: if (!grep(/^\*:\Q$clonedom\E$/,@clonedoms)) {
787: push (@clonedoms,'*:'.$clonedom);
788: }
789: }
790: }
791: }
792: if (@clonedoms) {
793: $newvalues{$entry}=join(',',@clonedoms);
794: }
795: }
796: if ($env{'form.cloners_newdom'} ne '') {
797: my $clonedom = $env{'form.cloners_newdom'};
798: if (&check_clone($clonedom,$disallowed) eq 'ok') {
799: my $newdom = '*:'.$env{'form.cloners_newdom'};
800: if (@clonedoms) {
801: if (!grep(/^\Q$newdom\E$/,@clonedoms)) {
802: $newvalues{$entry} .= ','.$newdom;
803: }
804: } else {
805: $newvalues{$entry} = $newdom;
806: }
807: }
808: }
809: if ($env{'form.'.$entry} ne '') {
810: my @cloners = split(',',$env{'form.'.$entry});
811: my @okcloners;
812: foreach my $cloner (@cloners) {
1.23 raeburn 813: $cloner =~ s/^\s+//;
814: $cloner =~ s/\s+$//;
815: unless ($cloner eq '') {
816: my ($uname,$udom) = split(':',$cloner);
817: if (&check_clone($udom,$disallowed,$uname) eq 'ok') {
818: if (!grep(/^\Q$cloner\E$/,@okcloners)) {
819: push(@okcloners,$cloner);
820: }
1.3 raeburn 821: }
822: }
823: }
824: if (@okcloners) {
825: my $okclonestr = join(',',@okcloners);
826: if ($newvalues{$entry} ne '') {
827: $newvalues{$entry} .= ','.$okclonestr;
828: } else {
829: $newvalues{$entry} = $okclonestr;
830: }
831: }
832: }
833: }
834: if (ref($disallowed) eq 'HASH') {
835: if (ref($disallowed->{'cloners'}) eq 'HASH') {
836: foreach my $key (keys(%{$disallowed->{'cloners'}})) {
837: $disallowed->{'cloners'}{$key} =~ s/,$//;
838: }
839: }
840: }
1.25 raeburn 841: } elsif ($entry eq 'co-owners') {
842: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
843: my $coowners = $values->{'internal.co-owners'};
844: my @currcoown;
845: if ($coowners) {
846: @currcoown = split(',',$coowners);
847: }
848: if (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
849: my $autocoowner;
850: if (($crstype eq 'Course') &&
851: ($values->{'internal.coursecode'})) {
852: my %domconf =
853: &Apache::lonnet::get_dom('configuration',['autoenroll'],$cdom);
854: if (ref($domconf{'autoenroll'}) eq 'HASH') {
855: $autocoowner = $domconf{'autoenroll'}{'co-owners'};
856: }
857: }
858: unless ($autocoowner) {
859: my @keepcoowners = &Apache::loncommon::get_env_multiple('form.coowners');
860: my @pendingcoowners = &Apache::loncommon::get_env_multiple('form.pendingcoowners');
861: my @invitecoowners = &Apache::loncommon::get_env_multiple('form.invitecoowners');
862: if (@invitecoowners) {
863: push(@pendingcoowners,@invitecoowners);
864: }
865: $newvalues{'pendingco-owners'} = join(',',sort(@pendingcoowners));
866: $newvalues{'co-owners'} = join(',',sort(@keepcoowners));
867: if ($newvalues{'co-owners'} ne $values->{'internal.co-owners'}) {
868: $changes->{$entry}{'co-owners'} = $newvalues{'co-owners'};
869: push(@{$changes->{$entry}{'changed'}},'co-owners');
870: }
871: if ($newvalues{'pendingco-owners'} ne $values->{'internal.pendingco-owners'}) {
872: $changes->{$entry}{'pendingco-owners'} = $newvalues{'pendingco-owners'};
873: push(@{$changes->{$entry}{'changed'}},'pendingco-owners');
874: }
875: }
876: } else {
877: my (@newpending,@newcoown);
878: my $uname = $env{'user.name'};
879: my $udom = $env{'user.domain'};
880: my $pendingcoowners = $values->{'internal.pendingco-owners'};
881: my @pendingcoown = split(',',$pendingcoowners);
882: if ($env{'form.pending_coowoner'}) {
883: foreach my $item (@pendingcoown) {
884: unless ($item eq $uname.':'.$udom) {
885: push(@newpending,$item);
886: }
887: }
888: @newcoown = @currcoown;
889: if ($env{'form.pending_coowoner'} eq 'accept') {
890: unless (grep(/^\Q$uname\E:\Q$udom\E$/,@currcoown)) {
891: push(@newcoown,$uname.':'.$udom);
892: }
893: }
894: } elsif ($env{'form.remove_coowoner'}) {
895: foreach my $item (@currcoown) {
896: unless ($item eq $uname.':'.$udom) {
897: push(@newcoown,$item);
898: }
899: }
900: if ($pendingcoowners ne '') {
901: @newpending = @pendingcoown;
902: }
903: }
904: $newvalues{'pendingco-owners'} = join(',',sort(@newpending));
905: $newvalues{'co-owners'} = join(',',sort(@newcoown));
906: if ($newvalues{'co-owners'} ne $values->{'internal.co-owners'}) {
907: $changes->{$entry}{'co-owners'} = $newvalues{'co-owners'};
908: push(@{$changes->{$entry}{'changed'}},'co-owners');
909: }
910: if ($newvalues{'pendingco-owners'} ne $values->{'internal.pendingco-owners'}) {
911: $changes->{$entry}{'pendingco-owners'} = $newvalues{'pendingco-owners'};
912: push(@{$changes->{$entry}{'changed'}},'pendingco-owners');
913: }
914: }
1.3 raeburn 915: } elsif ($entry =~ /^default_enrollment_(start|end)_date$/) {
916: $newvalues{$entry}=&Apache::lonhtmlcommon::get_date_from_form($entry);
917: } elsif ($entry eq 'rolenames') {
918: my %adv_roles =
919: &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
1.9 raeburn 920: my @stds;
921: if ($crstype eq 'Community') {
922: @stds = ('co');
923: } else {
924: @stds = ('cc');
925: }
926: push(@stds,('in','ta','ep','ad','st'));
1.3 raeburn 927: my (@replacements,@regulars);
928: foreach my $role (@stds) {
929: if ($values->{$role.'.plaintext'} ne '') {
1.9 raeburn 930: push(@replacements,$role);
1.3 raeburn 931: } else {
932: push(@regulars,$role);
933: }
1.9 raeburn 934: }
1.3 raeburn 935: foreach my $stdrole (@stds) {
936: my $ext_entry = $entry.'_'.$stdrole;
937: my $stdname = &Apache::lonnet::plaintext($stdrole,$crstype,
938: $env{'request.course.id'},1);
939: if ($env{'form.'.$ext_entry} eq $stdname) {
940: $newvalues{$ext_entry} = '';
941: } else {
942: $newvalues{$ext_entry} = $env{'form.'.$ext_entry};
943: }
944: if ($newvalues{$ext_entry} ne $values->{$stdrole.'.plaintext'}) {
945: my $dupname = 0;
946: if ($newvalues{$ext_entry} ne '') {
947: if (grep(/^\Q$newvalues{$ext_entry}\E$/,@replacements)) {
948: $dupname = 1;
949: push(@{$disallowed->{'rolenames'}{'replacements'}},$newvalues{$ext_entry});
950: }
951: if (!$dupname) {
952: if (grep(/^\Q$newvalues{$ext_entry}\E$/,@regulars)) {
953: $dupname = 1;
954: push(@{$disallowed->{rolenames}{'regulars'}},$newvalues{$ext_entry});
955: }
956: }
957: if (!$dupname) {
958: foreach my $role (keys(%adv_roles)) {
959: if ($role =~ m{^cr/$match_domain/$match_name/\Q$newvalues{$ext_entry}\E$}) {
960: $dupname = 1;
961: push(@{$disallowed->{rolenames}{'customrole'}},$newvalues{$ext_entry});
962: last;
963: }
964: }
965: }
966: }
967: if (!$dupname) {
968: $changes->{$ext_entry} = $newvalues{$ext_entry};
969: }
970: }
971: }
972: } elsif (($entry eq 'plc.roles.denied') || ($entry eq 'pch.roles.denied')) {
973: my @denied = &Apache::loncommon::get_env_multiple('form.'.$entry);
974: @denied = sort(@denied);
975: my $deniedstr = '';
976: if (@denied > 0) {
977: $deniedstr = join(',',@denied);
978: }
979: $newvalues{$entry} = $deniedstr;
980: } elsif (($entry eq 'plc.users.denied') || ($entry eq 'pch.users.denied')) {
981: my $total = $env{'form.'.$entry.'_total'};
982: my $userstr = '';
983: my @denied;
984: if ($total > 0) {
985: my @deletes =
986: &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
987: for (my $i=0; $i<$total; $i++) {
988: unless (grep(/^$i$/,@deletes)) {
989: $userstr .= $env{'form.'.$entry.'_user_'.$i}.',';
990: push(@denied,$env{'form.'.$entry.'_user_'.$i});
991: }
992: }
993: } else {
994: $total = 0;
995: }
996: if ($env{'form.'.$entry.'_uname_'.$total} ne '') {
997: my $uname = $env{'form.'.$entry.'_uname_'.$total};
998: my $udom = $env{'form.'.$entry.'_udom_'.$total};
999: if (&Apache::lonnet::homeserver($uname,$udom) eq 'no_host') {
1000: $userstr =~ s/,$//;
1001: $disallowed->{'discussion'}{$entry} = $uname.':'.$udom;
1002: } else {
1003: my $newuser .= $uname.':'.$udom;
1004: if (grep(/^\Q$newuser\E$/,@denied)) {
1005: $userstr =~ s/,$//;
1006: } else {
1007: $userstr .= $newuser;
1008: }
1009: }
1010: } else {
1011: $userstr =~ s/,$//;
1012: }
1013: $newvalues{$entry} = $userstr;
1014: } elsif ($entry eq 'allow_discussion_post_editing') {
1015: my @canedit = &Apache::loncommon::get_env_multiple('form.'.$entry);
1016: @canedit = sort(@canedit);
1017: foreach my $role (@canedit) {
1018: my @secs = &Apache::loncommon::get_env_multiple('form.'.$entry.'_sections_'.$role);
1019: if ((grep(/^\s*$/,@secs)) || (@secs == 0)) {
1020: $newvalues{$entry} .= $role.',';
1021: } else {
1022: foreach my $sec (@secs) {
1023: $newvalues{$entry} .= $role.':'.$sec.',';
1024: }
1025: }
1026: }
1027: $newvalues{$entry} =~ s/,$//;
1.49.2.3 raeburn 1028: } elsif ($entry eq 'discussion_post_fonts') {
1029: my ($classorder,$classtitles) = &discussion_vote_classes();
1030: my $fontchange = 0;
1031: foreach my $class (@{$classorder}) {
1032: my $ext_entry = $entry.'_'.$class;
1033: my $size = $env{'form.'.$ext_entry.'_size'};
1034: my $unit = $env{'form.'.$ext_entry.'_unit'};
1035: my $weight = $env{'form.'.$ext_entry.'_weight'};
1036: my $style = $env{'form.'.$ext_entry.'_style'};
1037: my $other = $env{'form.'.$ext_entry.'_other'};
1038: $size =~ s/,//g;
1039: $unit =~ s/,//g;
1040: $weight =~ s/,//g;
1041: $style =~ s/,//g;
1042: $other =~ s/[^\w;:\s\-\%.]//g;
1043: $other =~ s/(^\s+|\s+$)//g;
1044: $newvalues{$ext_entry} = join(',',($size.$unit,$weight,$style,$other));
1045: my $current = $values->{$ext_entry};
1046: if ($values->{$ext_entry} eq '') {
1047: $current = ',,,';
1048: }
1049: if ($newvalues{$ext_entry} ne $current) {
1050: $changes->{$ext_entry} = $newvalues{$ext_entry};
1051: $fontchange ++;
1052: }
1053: }
1054: if ($fontchange) {
1055: $changes->{$entry} = 1;
1056: }
1.3 raeburn 1057: } elsif ($entry eq 'nothideprivileged') {
1058: my @curr_nothide;
1059: my @new_nothide;
1060: if ($values->{$entry} ne '') {
1061: foreach my $user (split(/\s*\,\s*/,$values->{$entry})) {
1062: my $nothide;
1063: if ($user !~ /:/) {
1064: $nothide = join(':',split(/[\@]/,$user));
1065: } else {
1066: $nothide = $user;
1067: }
1068: if ((defined($nothide)) &&
1069: (!grep(/^\Q$nothide\E$/,@curr_nothide))) {
1070: push(@curr_nothide,$nothide);
1071: }
1072: }
1073: }
1074: foreach my $key (keys(%env)) {
1075: if ($key =~ /^form\.\Q$entry\E_($match_username:$match_domain)$/) {
1.7 raeburn 1076: if ($env{$key}) {
1.3 raeburn 1077: my $nothide = $1;
1078: if (!grep(/^\Q$nothide\E$/,@new_nothide)) {
1079: push(@new_nothide,$nothide);
1080: }
1081: }
1082: }
1083: }
1084: @new_nothide = sort(@new_nothide);
1085: my @differences =
1086: &Apache::loncommon::compare_arrays(\@curr_nothide,
1087: \@new_nothide);
1088: if (@differences > 0) {
1089: if (@new_nothide > 0) {
1090: $newvalues{$entry} = join(',',@new_nothide);
1091: } else {
1092: $newvalues{$entry} = '';
1093: }
1094: } else {
1095: $newvalues{$entry} = $values->{$entry};
1096: }
1097: } elsif ($entry eq 'print_header_format') {
1098: my $maxnum = $env{'form.printfmthdr_maxnum'};
1099: my @newhdr;
1100: if ($maxnum > 2) {
1101: for (my $i=0; $i<$maxnum-2; $i++) {
1102: if ($env{'form.printfmthdr_del_'.$i}) {
1103: $newhdr[$env{'form.printfmthdr_pos_'.$i}] = '';
1104: } else {
1105: my $hdr;
1106: if ($env{'form.printfmthdr_sub_'.$i} =~ /^[nca]$/) {
1107: $hdr = '%';
1108: if ($env{'form.printfmthdr_limit_'.$i} =~ /^\d+$/) {
1109: $hdr .= $env{'form.printfmthdr_limit_'.$i};
1110: }
1111: $hdr .= $env{'form.printfmthdr_sub_'.$i};
1.29 raeburn 1112: } elsif ($env{'form.printfmthdr_text_'.$i} ne '') {
1113: $hdr = $env{'form.printfmthdr_text_'.$i};
1.3 raeburn 1114: }
1115: $newhdr[$env{'form.printfmthdr_pos_'.$i}] = $hdr;
1116: }
1117: }
1118: }
1119: my $newsub = $maxnum-2;
1120: if ($env{'form.printfmthdr_sub_'.$newsub} =~ /^[nca]$/) {
1121: my $hdr = '%';
1122: if ($env{'form.printfmthdr_limit_'.$newsub} =~ /^\d+$/) {
1123: $hdr .= $env{'form.printfmthdr_limit_'.$newsub};
1124: }
1125: $hdr .= $env{'form.printfmthdr_sub_'.$newsub};
1126: $newhdr[$env{'form.printfmthdr_pos_'.$newsub}] = $hdr;
1127: }
1128: my $newtext = $maxnum-1;
1129: $newhdr[$env{'form.printfmthdr_pos_'.$newtext}] = $env{'form.printfmthdr_text_'.$newtext};
1130: $newvalues{$entry} = join('',@newhdr);
1.49.2.7 raeburn 1131: } elsif (($entry eq 'languages') ||
1132: ($entry eq 'checkforpriv')) {
1133: my $settings;
1.3 raeburn 1134: my $total = $env{'form.'.$entry.'_total'};
1135: if ($total) {
1136: my @deletes = &Apache::loncommon::get_env_multiple('form.'.$entry.'_delete');
1137: for (my $i=0; $i<$total; $i++) {
1138: unless (grep(/^$i$/,@deletes)) {
1.49.2.7 raeburn 1139: $settings .= $env{'form.'.$entry.'_'.$i}.',';
1.3 raeburn 1140: }
1141: }
1142: } else {
1143: $total = 0;
1144: }
1145: if ($env{'form.'.$entry.'_'.$total} ne '') {
1.49.2.7 raeburn 1146: my $new = $env{'form.'.$entry.'_'.$total};
1147: if ($entry eq 'languages') {
1148: my %langchoices = &get_lang_choices();
1149: if ($langchoices{$new}) {
1150: $settings .= $new;
1151: } else {
1152: $settings =~ s/,$//;
1153: $disallowed->{'localization'}{$entry} = $new;
1154: }
1.3 raeburn 1155: } else {
1.49.2.7 raeburn 1156: my %domains=map { $_ => 1; } &Apache::lonnet::all_domains();
1157: if ($domains{$new}) {
1158: $settings .= $new;
1159: } else {
1160: $settings =~ s/,$//;
1161: $disallowed->{'classlists'}{$entry} = $new;
1162: }
1.3 raeburn 1163: }
1164: } else {
1.49.2.7 raeburn 1165: $settings =~ s/,$//;
1.3 raeburn 1166: }
1.49.2.7 raeburn 1167: $newvalues{$entry} = $settings;
1.3 raeburn 1168: } else {
1169: $newvalues{$entry} = $env{'form.'.$entry};
1170: }
1.49.2.3 raeburn 1171: unless (($entry eq 'co-owners') || ($entry eq 'discussion_post_fonts')) {
1.25 raeburn 1172: if ($newvalues{$entry} ne $values->{$entry}) {
1173: $changes->{$entry} = $newvalues{$entry};
1174: }
1.3 raeburn 1175: }
1176: }
1177: }
1178: }
1179: }
1180: }
1181: return;
1182: }
1183:
1184: sub get_sec_str {
1185: my ($entry,$num) = @_;
1186: my @secs = &Apache::loncommon::get_env_multiple('form.'.$entry.'_sections_'.$num);
1187: my $secstr;
1188: if (grep(/^\s*$/,@secs)) {
1189: $secstr = '';
1190: } elsif (@secs > 0) {
1191: $secstr = join(';',@secs);
1192: }
1193: if ($secstr ne '') {
1194: return '('.$secstr.')';
1195: }
1196: return;
1197: }
1198:
1199: sub check_clone {
1200: my ($clonedom,$disallowed,$clonename) = @_;
1201: return if (ref($disallowed) ne 'HASH');
1202: if ($clonedom !~ /^$match_domain$/) {
1203: $disallowed->{'cloners'}{'format'} .= $clonedom.',';
1204: return;
1205: } elsif (!&Apache::lonnet::domain($clonedom)) {
1206: $disallowed->{'cloners'}{'domain'} .= $clonedom.',';
1207: return;
1208: }
1209: if ($clonename ne '') {
1210: if ($clonename !~ /^$match_username$/) {
1211: $disallowed->{'cloners'}{'format'} .= $clonename.':'.$clonedom.',';
1212: return;
1213: } else {
1214: if (&Apache::lonnet::homeserver($clonename,$clonedom) eq 'no_host') {
1215: $disallowed->{'cloners'}{'newuser'} .= $clonename.':'.$clonedom.',';
1216: return;
1217: }
1218: }
1219: }
1220: return 'ok';
1221: }
1222:
1223: sub store_changes {
1.9 raeburn 1224: my ($cdom,$cnum,$prefs_order,$actions,$prefs,$values,$changes,$crstype) = @_;
1.3 raeburn 1225: my ($chome,$output);
1.23 raeburn 1226: my (%storehash,@delkeys,@need_env_update,@oldcloner);
1.3 raeburn 1227: if ((ref($values) eq 'HASH') && (ref($changes) eq 'HASH')) {
1228: %storehash = %{$values};
1229: } else {
1.9 raeburn 1230: if ($crstype eq 'Community') {
1231: $output = &mt('No changes made to community settings.');
1232: } else {
1233: $output = &mt('No changes made to course settings.');
1234: }
1235: return $output;
1.3 raeburn 1236: }
1237: my %yesno = (
1238: hidefromcat => '1',
1239: problem_stream_switch => '1',
1240: suppress_tries => '1',
1241: disableexampointprint => '1',
1242: hideemptyrows => '1',
1243: suppress_embed_prompt => '1',
1244: );
1245: foreach my $item (@{$prefs_order}) {
1246: if (grep(/^\Q$item\E$/,@{$actions})) {
1247: $output .= '<h3>'.&mt($prefs->{$item}{'text'}).'</h3>';
1248: if (ref($changes->{$item}) eq 'HASH') {
1249: if (keys(%{$changes->{$item}}) > 0) {
1.22 wenzelju 1250: $output .= &mt('Changes made:').'<ul style="list-style:none;">';
1.3 raeburn 1251: if ($item eq 'other') {
1252: foreach my $key (sort(keys(%{$changes->{$item}}))) {
1253: $storehash{$key} = $changes->{$item}{$key};
1254: if ($changes->{$item}{$key} eq '') {
1255: push(@delkeys,$key);
1.22 wenzelju 1256: $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]','<i>'.$key.'</i>')).'</li>';
1.3 raeburn 1257: } else {
1.22 wenzelju 1258: $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]','<i>'.$key.'</i>',
1259: "'$storehash{$key}'")).'</li>';
1.3 raeburn 1260: }
1261: }
1262: } else {
1263: if (ref($prefs->{$item}->{'ordered'}) eq 'ARRAY') {
1264: my @settings = @{$prefs->{$item}->{'ordered'}};
1265: if ($item eq 'feedback') {
1266: push(@settings,(map { $_.'.text'; } @settings));
1267: }
1268: foreach my $key (@settings) {
1269: if ($key eq 'rolenames') {
1270: my $displayname = $prefs->{$item}->{'itemtext'}{$key};
1271: my $msg;
1.9 raeburn 1272: my @roles;
1273: if ($crstype eq 'Community') {
1274: @roles = ('co');
1275: } else {
1276: @roles = ('cc');
1277: }
1278: push(@roles,('in','ta','ep','ad','st'));
1279: foreach my $role (@roles) {
1.3 raeburn 1280: next if (!exists($changes->{$item}{$key.'_'.$role}));
1281: my $stdname = &Apache::lonnet::plaintext($role,$crstype,undef,1);
1282: my $newname = $changes->{$item}{$key.'_'.$role};
1283: $storehash{$role.'.plaintext'} = $newname;
1284: if ($newname eq '') {
1285: $newname = $stdname;
1286: }
1287: $msg .= '<li>'.&mt('[_1] set to [_2]','<i>'.$stdname.'</i>',
1288: "'<b>".$newname."</b>'").'</li>';
1289: }
1290: if ($msg ne '') {
1.22 wenzelju 1291: $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt($displayname)).'<ul class="LC_success">'.$msg.'</ul></li>';
1.3 raeburn 1292: }
1293: } else {
1294: next if (!exists($changes->{$item}{$key}));
1295: my ($displayname,$text);
1296: $text = $prefs->{$item}->{'itemtext'}{$key};
1.25 raeburn 1297: my $displayval;
1.49.2.3 raeburn 1298: unless (($key eq 'co-owners') || ($key eq 'discussion_post_fonts')) {
1.25 raeburn 1299: $displayval = $changes->{$item}{$key};
1300: }
1.3 raeburn 1301: if ($item eq 'feedback') {
1302: if ($key =~ /^(question|policy|comment)(\.email)\.text$/) {
1303: $text = $prefs->{$item}->{'itemtext'}{$1.$2};
1304: $displayname = &mt('Custom text for '.$text.' questions');
1305: } else {
1306: $displayname = &mt('Recipients of '.$text.' questions');
1307: }
1308: } elsif ($item eq 'discussion') {
1309: if ($key =~ /^p(lc|ch)\.roles\.denied/) {
1310: $displayname = &mt("$text (role-based)");
1311: if ($displayval ne '') {
1312: my @roles = split(',',$displayval);
1313: @roles = map { &Apache::lonnet::plaintext($_); } @roles;
1314: $displayval = join(', ',@roles);
1315: }
1316: } elsif ($key =~ /^p(lc|ch)\.users\.denied/) {
1317: $displayname = &mt("$text (specific user(s))");
1318: } else {
1319: if ($key eq 'allow_discussion_post_editing') {
1320: if ($displayval ne '') {
1321: my @roles = split(',',$displayval);
1322: my @longroles;
1323: foreach my $role (@roles) {
1324: my ($trole,$sec) = split(':',$role);
1325: my $rolename =
1326: &Apache::lonnet::plaintext($trole);
1327: if ($sec ne '') {
1328: $rolename .= ':'.$sec;
1329: }
1330: push(@longroles,$rolename);
1331: }
1332: $displayval = join(', ',@longroles);
1333: }
1.49.2.3 raeburn 1334: } elsif ($key eq 'discussion_post_fonts') {
1335: my ($classorder,$classtitles)=&discussion_vote_classes();
1336: my ($styleorder,$styleitems)=&discussion_vote_styles();
1337: my $count = 1;
1338: my $total = scalar(keys(%{$changes->{$item}}));
1339: foreach my $class (@{$classorder}) {
1340: $count ++;
1341: next unless ($changes->{$item}{$key.'_'.$class});
1342: my @vals = split(/,/,$changes->{$item}{$key.'_'.$class});
1343: my $showval = '';
1344: for (my $i=0; $i<@{$styleorder}; $i++) {
1345: if ($vals[$i] ne '') {
1346: $showval .= 'font-'.$styleorder->[$i].': '.$vals[$i].'; ';
1347: }
1348: }
1349: if ($vals[3] ne '') {
1350: $showval .= $vals[3];
1351: }
1352: if ($showval ne '') {
1353: $displayval .= $classtitles->{$class}.':{ '.
1354: $showval.'}';
1355: $storehash{$key.'_'.$class} = $changes->{$item}{$key.'_'.$class};
1356: } else {
1357: $displayval .= $classtitles->{$class}.': '.&mt('None');
1358: push(@delkeys,$key.'_'.$class);
1359: }
1360: unless ($count == $total) {
1361: $displayval .= (' 'x2);
1362: }
1363: }
1.3 raeburn 1364: }
1365: $displayname = &mt($text);
1366: }
1367: } elsif ($item eq 'spreadsheet') {
1368: if ($key =~ /^spreadsheet_default_(studentcalc|assesscalc)$/x) {
1369: my $sheettype = $1;
1370: if ($sheettype eq 'studentcalc') {
1371: &Apache::lonnet::expirespread('','','studentcalc');
1372: } else {
1373: &Apache::lonnet::expirespread('','','assesscalc');
1374: &Apache::lonnet::expirespread('','','studentcalc');
1375: }
1376: }
1377: $displayname = &mt($text);
1378: } else {
1379: $displayname = &mt($text);
1380: }
1381: if (defined($yesno{$key})) {
1.14 raeburn 1382: $displayval = &mt('No');
1.3 raeburn 1383: if ($changes->{$item}{$key} eq 'yes') {
1.14 raeburn 1384: $displayval = &mt('Yes');
1.3 raeburn 1385: }
1386: } elsif (($key =~ /^default_enrollment_(start|end)_date$/) && ($displayval)) {
1387: $displayval = &Apache::lonlocal::locallocaltime($displayval);
1388: } elsif ($key eq 'categories') {
1389: $displayval = $env{'form.categories_display'};
1.14 raeburn 1390: } elsif ($key eq 'canuse_pdfforms') {
1391: if ($changes->{$item}{$key} eq '1') {
1392: $displayval = &mt('Yes');
1393: } elsif ($changes->{$item}{$key} eq '0') {
1394: $displayval = &mt('No');
1395: }
1396: }
1.25 raeburn 1397: if ($key eq 'co-owners') {
1398: if (ref($changes->{$item}{$key}) eq 'HASH') {
1399: if (ref($changes->{$item}{$key}{'changed'}) eq 'ARRAY') {
1400: foreach my $type ('co-owners','pendingco-owners') {
1401: next unless (grep(/^\Q$type\E$/,@{$changes->{$item}{$key}{'changed'}}));
1402: if ($type eq 'pendingco-owners') {
1403: if (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
1404: $displayname = &mt('Invited as co-owners, pending acceptance');
1405: }
1406: }
1407: if ($changes->{$item}{$key}{$type} eq '') {
1408: push(@delkeys,'internal.'.$type);
1409: if (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
1410: $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]',
1411: '<i>'.$displayname.'</i>')).'</li>';
1412: }
1413: } elsif (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
1414: $displayval = join(', ',map { &Apache::loncommon::plainname(split(':',$_)); } split(',',$changes->{$item}{$key}{$type}));
1415: $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]',
1416: '<i>'.$displayname.'</i>',
1417: "'<b>$displayval</b>'")).'</li>';
1418: }
1419: }
1420: }
1421: unless (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
1422: if ($env{'form.pending_coowoner'} eq 'accept') {
1423: $displayval = &mt('on');
1424: } elsif ($env{'form.pending_coowoner'} eq 'decline') {
1425: $displayval = '';
1426: $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Invitation to be co-owner declined')).'</li>';
1427: } elsif ($env{'form.remove_coowoner'}) {
1428: $displayval = &mt('off');
1429: }
1430: if ($displayval) {
1431: $displayname = &mt('Your co-ownership status');
1432: $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]',
1433: '<i>'.$displayname.'</i>',
1434: "'<b>$displayval</b>'")).'</li>';
1435: }
1436: }
1437: }
1438: } elsif ($changes->{$item}{$key} eq '') {
1.3 raeburn 1439: push(@delkeys,$key);
1.22 wenzelju 1440: $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]',
1441: '<i>'.$displayname.'</i>')).'</li>';
1.3 raeburn 1442: } else {
1.22 wenzelju 1443: $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('[_1] set to [_2]',
1.3 raeburn 1444: '<i>'.$displayname.'</i>',
1.22 wenzelju 1445: "'<b>$displayval</b>'"));
1.3 raeburn 1446: if ($key eq 'url') {
1447: my $bkuptime=time;
1448: $output .= (' 'x2).&mt('(Previous URL backed up)').': '.
1.32 raeburn 1449: $storehash{'top level map backup '.$bkuptime} = $values->{$key};
1.3 raeburn 1450: }
1451: $output .= '</li>';
1452: }
1.25 raeburn 1453: if ($key eq 'co-owners') {
1454: if (ref($changes->{$item}{$key}) eq 'HASH') {
1455: if (ref($changes->{$item}{$key}{'changed'}) eq 'ARRAY') {
1456: foreach my $type ('co-owners','pendingco-owners') {
1457: next unless (grep(/^\Q$type\E$/,@{$changes->{$item}{$key}{'changed'}}));
1458: $storehash{'internal.'.$type} = $changes->{$item}{$key}{$type};
1459: }
1460: }
1461: }
1462: } else {
1.49.2.3 raeburn 1463: unless ($key eq 'discussion_post_fonts') {
1464: $storehash{$key} = $changes->{$item}{$key};
1465: }
1.25 raeburn 1466: }
1.3 raeburn 1467: }
1.23 raeburn 1468: if ($key eq 'cloners') {
1469: # Get existing cloners
1470: my %clonenames =
1471: &Apache::lonnet::dump('environment',$cdom,$cnum,'cloners');
1472: if ($clonenames{'cloners'} =~ /,/) {
1473: @oldcloner = split(/\s*\,\s*/,$clonenames{'cloners'});
1474: } else {
1475: $oldcloner[0] = $clonenames{'cloners'};
1476: }
1477: }
1.3 raeburn 1478: if (($key eq 'description') || ($key eq 'cloners') ||
1.25 raeburn 1479: ($key eq 'hidefromcat') || ($key eq 'categories') ||
1480: ($key eq 'co-owners')) {
1.3 raeburn 1481: push(@need_env_update,$key);
1482: }
1483: }
1484: }
1485: }
1486: $output .= '</ul>';
1487: } else {
1.9 raeburn 1488: if ($crstype eq 'Community') {
1.46 raeburn 1489: $output .= &mt('No changes made to community settings.');
1.9 raeburn 1490: } else {
1.46 raeburn 1491: $output .= &mt('No changes made to course settings.');
1.9 raeburn 1492: }
1.3 raeburn 1493: }
1494: }
1495: }
1496: }
1497: if (&Apache::lonnet::put('environment',\%storehash,$cdom,$cnum) eq 'ok') {
1.23 raeburn 1498: if (ref($changes) eq 'HASH') {
1499: if (ref($changes->{'courseinfo'}) eq 'HASH') {
1500: if (exists($changes->{'courseinfo'}{'cloners'})) {
1501: &change_clone($cdom,$cnum,$changes->{'courseinfo'}{'cloners'},
1502: \@oldcloner);
1503: }
1504: }
1505: }
1.3 raeburn 1506: if (@delkeys) {
1507: if (&Apache::lonnet::del('environment',\@delkeys,$cdom,$cnum) ne 'ok') {
1.9 raeburn 1508: $output .= '<br /><span class="LC_error">';
1509: if ($crstype eq 'Community') {
1510: $output .= &mt('An error occurred when removing community settings which are no longer in use.');
1511: } else {
1512: $output .= &mt('An error occurred when removing course settings which are no longer in use.');
1513: }
1514: $output .= '</span>';
1.14 raeburn 1515: } else {
1516: foreach my $key (@delkeys) {
1517: &Apache::lonnet::delenv('course.'.$cdom.'_'.$cnum.'.'.$key);
1518: }
1.3 raeburn 1519: }
1520: }
1521: if (@need_env_update) {
1522: $chome = &Apache::lonnet::homeserver($cnum,$cdom);
1523: &update_env($cnum,$cdom,$chome,\@need_env_update,\%storehash);
1524: }
1525: &Apache::lonnet::coursedescription($env{'request.course.id'},
1526: {'freshen_cache' => 1});
1527: } else {
1.9 raeburn 1528: $output = '<span class="LC_error">';
1529: if ($crstype eq 'Community') {
1530: $output .= &mt('An error occurred when saving changes to community settings, which remain unchanged.');
1531: } else {
1532: $output .= &mt('An error occurred when saving changes to course settings, which remain unchanged.');
1533: }
1534: $output .= '</span>';
1.3 raeburn 1535: }
1536: return $output;
1537: }
1538:
1539: sub update_env {
1540: my ($cnum,$cdom,$chome,$need_env_update,$storehash) = @_;
1541: my $count = 0;
1542: if ((ref($need_env_update) eq 'ARRAY') && (ref($storehash) eq 'HASH')) {
1543: my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',$cnum,undef,undef,'.');
1544: if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') {
1545: foreach my $key (@{$need_env_update}) {
1546: if ($key eq 'description' && defined($storehash->{$key})) {
1547: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.description' => $storehash->{$key}});
1548: $crsinfo{$env{'request.course.id'}}{'description'} = $storehash->{$key};
1549: $count ++;
1550: } elsif (($key eq 'cloners') || ($key eq 'hidefromcat') || ($key eq 'categories')) {
1551: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.'.$key => $storehash->{$key}});
1552: $crsinfo{$env{'request.course.id'}}{$key} = $storehash->{$key};
1553: $count ++;
1.25 raeburn 1554: } elsif ($key eq 'co-owners') {
1555: if ($storehash->{'internal.co-owners'} ne '') {
1556: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.internal.co-owners' => $storehash->{'internal.co-owners'}});
1557: }
1558: if ($storehash->{'internal.pendingco-owners'} ne '') {
1559: &Apache::lonnet::appenv({'course.'.$env{'request.course.id'}.'.internal.pendingco-owners' => $storehash->{'internal.pendingco-owners'}});
1560: }
1561: my @coowners = split(',',$storehash->{'internal.'.$key});
1562: $crsinfo{$env{'request.course.id'}}{'co-owners'} = \@coowners;
1563: $count ++;
1.3 raeburn 1564: }
1565: }
1566: if ($count) {
1567: my $putresult = &Apache::lonnet::courseidput($cdom,\%crsinfo,$chome,'notime');
1568: }
1569: }
1570: }
1571: return;
1572: }
1573:
1574: sub display_disallowed {
1.9 raeburn 1575: my ($item,$disallowed,$prefs,$crstype) = @_;
1.3 raeburn 1576: my $output;
1577: if ((ref($disallowed) eq 'HASH') && (ref($prefs) eq 'HASH')) {
1578: if (keys(%{$disallowed})) {
1579: if ($item eq 'cloners') {
1580: my @fails;
1581: my %lt = &Apache::lonlocal::texthash (
1582: format => 'Invalid format',
1583: domain => 'Domain does not exist',
1584: newuser => 'LON-CAPA user(s) do(es) not exist.',
1585: );
1586: foreach my $error ('format','domain','newuser') {
1587: if (defined($disallowed->{$error})) {
1588: my $msg = '<b>'.$disallowed->{$error}.'</b>, '.&mt('reason').' - '.
1589: $lt{$error};
1590: if ($error eq 'newuser') {
1.9 raeburn 1591: $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 1592: }
1593: push(@fails,$msg);
1594: }
1595: }
1596: if (@fails) {
1597: $output .= '<span class="LC_warning">'.&mt('Unable to add to allowed cloners: ').
1598: '</span>'.join('; ',@fails).'.<br />';
1599: }
1600: } elsif ($item eq 'rolenames') {
1601: my %lt = &Apache::lonlocal::texthash (
1602: replacements => 'Name already used to replace a different standard role name',
1603: regulars => 'Name already used as a standard role name',
1604: customrole => 'Name already used as the name of a custom role',
1605: );
1606: my @fails;
1607: foreach my $error ('replacements','regulars','customrole') {
1608: if (ref($disallowed->{$error}) eq 'ARRAY') {
1609: push(@fails,'<b>'.join(', ',@{$disallowed->{$error}}).
1610: '</b>, '.&mt('reason').' - '.$lt{'error'});
1611: }
1612: }
1613: if (@fails) {
1614: $output .= '<span class="LC_warning">'.
1615: &mt('Unable to include amongst replacements for role names: ').
1616: '</span>'.join('; ',@fails).'.<br />';
1617: }
1618:
1619: } elsif (($item eq 'feedback') || ($item eq 'discussion') || ($item eq 'localization')) {
1620: $output .= '<span class="LC_warning">';
1621: if ($item eq 'feedback') {
1.9 raeburn 1622: if ($crstype eq 'Community') {
1623: $output .= &mt('Unable to include as a recipient of community feedback for:');
1624: } else {
1625: $output .= &mt('Unable to include as a recipient of course feedback for:');
1626: }
1.3 raeburn 1627: } elsif ($item eq 'discussion') {
1628: $output .= &mt('Unable to include in user-based access control for:');
1629: } elsif ($item eq 'localization') {
1.9 raeburn 1630: if ($crstype eq 'Community') {
1631: $output .= &mt('Unable to include in community localization:');
1632: } else {
1633: $output .= &mt('Unable to include in course localization:');
1634: }
1.3 raeburn 1635: }
1636: $output .= '</span><ul>';
1637: foreach my $key (sort(keys(%{$disallowed}))) {
1638: my $itemtext = $prefs->{$item}{'itemtext'}{$key};
1639: $output .= '<li><i>'.$itemtext.'</i> - ';
1640: if ($item eq 'localization') {
1641: $output .= &mt('reason - unsupported language: [_1]',
1642: '<b>'.$disallowed->{$key}.'</b>');
1643: } else {
1644: $output .= &mt('reason - invalid user: [_1]',
1645: '<b>'.$disallowed->{$key}.'</b>').'</li>';
1646: }
1647: }
1648: $output .= '</ul><br />';
1649: }
1650: }
1.1 raeburn 1651: }
1.3 raeburn 1652: return $output;
1.1 raeburn 1653: }
1654:
1655: sub get_course {
1656: my ($courseid) = @_;
1657: if (!defined($courseid)) {
1658: $courseid = $env{'request.course.id'};
1659: }
1660: my $cdom=$env{'course.'.$courseid.'.domain'};
1661: my $cnum=$env{'course.'.$courseid.'.num'};
1662: return ($cnum,$cdom);
1663: }
1664:
1665: sub get_jscript {
1.36 raeburn 1666: my ($cid,$cdom,$phase,$crstype) = @_;
1.12 raeburn 1667: my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype);
1.36 raeburn 1668: my ($jscript,$categorize_js,$loncaparev_js);
1.1 raeburn 1669: my $stubrowse_js = &Apache::loncommon::studentbrowser_javascript();
1670: my $browse_js = &Apache::loncommon::browser_and_searcher_javascript('parmset');
1.3 raeburn 1671: my $cloners_js = &cloners_javascript($phase);
1.1 raeburn 1672: if ($can_categorize) {
1673: $categorize_js = <<ENDSCRIPT;
1674: function catsbrowser() {
1675: var catswin = null;
1676: var url = '/adm/courseprefs?phase=categorizecourse';
1677: if (!catswin || catswin.closed) {
1678: catswin=window.open(url,'categorieswin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
1679: } else {
1680: catswin.focus();
1681: }
1682: }
1683: ENDSCRIPT
1684: }
1.36 raeburn 1685: my $loncaparev = $env{'course.'.$cid.'.internal.releaserequired'};
1686: if ($loncaparev) {
1687: $loncaparev_js = <<ENDSCRIPT;
1688: function loncaparevinfo() {
1689: var lcrevwin = null;
1690: var url = '/adm/courseprefs?phase=releaseinfo';
1691: if (!lcrevwin || lcrevwin.closed) {
1692: lcrevwin=window.open(url,'releasewin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
1693: } else {
1694: lcrevwin.focus();
1695: }
1696: }
1697: ENDSCRIPT
1698: }
1.49.2.10 raeburn 1699: my $cnum = $env{'course.'.$cid.'.num'};
1700: my $syllabus_js = <<ENDSCRIPT;
1701: function syllabusinfo() {
1702: var syllwin = null;
1703: var url = '/public/$cdom/$cnum/syllabus?only_body=1';
1704: if (!syllwin || syllwin.closed) {
1705: syllwin=window.open(url,'syllabuswin','height=480,width=600,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
1706: } else {
1707: syllwin.focus();
1708: }
1709: }
1710: ENDSCRIPT
1.1 raeburn 1711: $jscript = '<script type="text/javascript" language="Javascript">'."\n".
1.49.2.7 raeburn 1712: '// <![CDATA['."\n".
1.36 raeburn 1713: $browse_js."\n".$categorize_js."\n".$loncaparev_js."\n".
1.49.2.10 raeburn 1714: $cloners_js."\n".
1715: $syllabus_js."\n".'//]]>'."\n".
1.49.2.7 raeburn 1716: '</script>'."\n".$stubrowse_js."\n";
1.1 raeburn 1717: return $jscript;
1718: }
1719:
1.3 raeburn 1720: sub cloners_javascript {
1721: my ($formname) = @_;
1722: return <<"ENDSCRIPT";
1723:
1724: function update_cloners(caller,num) {
1725: var delidx = getIndexByName('cloners_delete');
1726: var actidx = getIndexByName('cloners_activate');
1727: if (caller == 'cloners_all') {
1728: var selall;
1729: for (var i=0; i<document.$formname.cloners_all.length; i++) {
1730: if (document.$formname.cloners_all[i].checked) {
1731: selall = document.$formname.cloners_all[i].value;
1732: }
1733: }
1734: if (selall == 1) {
1735: if (delidx != -1) {
1736: if (document.$formname.cloners_delete.length) {
1737: for (var j=0; j<document.$formname.cloners_delete.length; j++) {
1738: document.$formname.cloners_delete[j].checked = true;
1739: }
1740: } else {
1741: document.$formname.elements[delidx].checked = true;
1742: }
1743: }
1744: if (actidx != -1) {
1745: if (document.$formname.cloners_activate.length) {
1746: for (var i=0; i<document.$formname.cloners_activate.length; i++) {
1747: if (document.$formname.cloners_activate[i].value == '0') {
1748: document.$formname.cloners_activate[i].checked = false;
1749: }
1750: if (document.$formname.cloners_activate[i].value == '') {
1751: document.$formname.cloners_activate[i].checked = true;
1752: }
1753: }
1754: }
1755: }
1756: document.$formname.cloners_newdom.selectedIndex = 0;
1757: }
1758: }
1759: if (caller == 'cloners_activate') {
1760: if (document.$formname.cloners_activate.length) {
1761: for (var j=0; j<document.$formname.cloners_activate.length; j++) {
1762: if (document.$formname.cloners_activate[j].value == num) {
1763: if (document.$formname.cloners_activate[j].checked) {
1764: for (var i=0; i<document.$formname.cloners_all.length; i++) {
1765: if (document.$formname.cloners_all[i].value == '1') {
1766: document.$formname.cloners_all[i].checked = false;
1767: }
1768: if (document.$formname.cloners_all[i].value == '0') {
1769: document.$formname.cloners_all[i].checked = true;
1770: }
1771: }
1772: }
1773: }
1774: }
1775: } else {
1776: for (var i=0; i<document.$formname.cloners_all.length; i++) {
1777: if (document.$formname.cloners_all[i].value == '1') {
1778: document.$formname.cloners_all[i].checked = false;
1779: }
1780: if (document.$formname.cloners_all[i].value == '0') {
1781: document.$formname.cloners_all[i].checked = true;
1782: }
1783: }
1784: }
1785: }
1786: return;
1787: }
1788:
1789: function getIndexByName(item) {
1790: for (var i=0;i<document.$formname.elements.length;i++) {
1791: if (document.$formname.elements[i].name == item) {
1792: return i;
1793: }
1794: }
1795: return -1;
1796: }
1797:
1798: ENDSCRIPT
1799: }
1800:
1801:
1.1 raeburn 1802: sub print_courseinfo {
1.9 raeburn 1803: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 1804: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 1805: return;
1806: }
1.25 raeburn 1807: my ($cathash,$categoriesform,$autocoowner);
1.1 raeburn 1808: my %domconf =
1.25 raeburn 1809: &Apache::lonnet::get_dom('configuration',['coursecategories','autoenroll'],$cdom);
1.1 raeburn 1810: if (ref($domconf{'coursecategories'}) eq 'HASH') {
1811: $cathash = $domconf{'coursecategories'}{'cats'};
1812: if (ref($cathash) eq 'HASH') {
1813: $categoriesform =
1814: &Apache::loncommon::assign_categories_table($cathash,
1.12 raeburn 1815: $settings->{'categories'},$crstype)."\n";
1.1 raeburn 1816: }
1817: }
1.25 raeburn 1818: if (ref($domconf{'autoenroll'}) eq 'HASH') {
1819: $autocoowner = $domconf{'autoenroll'}{'co-owners'};
1820: }
1.1 raeburn 1821: if (!defined($categoriesform)) {
1.15 raeburn 1822: $categoriesform = &mt('No categories defined in this domain.');
1.1 raeburn 1823: }
1824:
1.12 raeburn 1825: my ($can_toggle_cat,$can_categorize) = &can_modify_catsettings($cdom,$crstype);
1.49.2.10 raeburn 1826: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
1.1 raeburn 1827:
1.9 raeburn 1828: my $replace;
1829: if ($crstype eq 'Community') {
1830: $replace = &mt('To replace the standard title for a course role, enter a title, otherwise leave blank');
1831: } else {
1832: $replace = &mt('To replace the standard title for a course role, enter a title, otherwise leave blank');
1833: }
1.1 raeburn 1834: my %items = (
1.3 raeburn 1835: 'url' => {
1836: text => '<b>'.&mt($itemtext->{'url'}).'</b>'.(' 'x2).
1.1 raeburn 1837: '<a href="javascript:openbrowser'.
1838: "('display','url','sequence')\">".
1839: &mt('Select Map').'</a><br /><span class="LC_warning"> '.
1840: &mt('Modification may make assessment data inaccessible!').
1841: '</span>',
1842: input => 'textbox',
1.49.2.6 raeburn 1843: size => '55',
1.19 faziophi 1844: advanced => 1
1.1 raeburn 1845: },
1846: 'description' => {
1.3 raeburn 1847: text => '<b>'.&mt($itemtext->{'description'}).'</b>',
1.1 raeburn 1848: input => 'textbox',
1.49.2.6 raeburn 1849: size => '55',
1.1 raeburn 1850: },
1.24 raeburn 1851: 'owner' => {
1852: text => '<b>'.&mt($itemtext->{'owner'}).'</b>',
1853: },
1.25 raeburn 1854: 'co-owners' => {
1855: text => '<b>'.&mt($itemtext->{'co-owners'}).'</b>',
1856: },
1.49.2.11! raeburn 1857: 'clonedfrom' => {
! 1858: text => '<b>'.&mt($itemtext->{'clonedfrom'}).'</b>',
! 1859: },
1.1 raeburn 1860: 'courseid' => {
1.3 raeburn 1861: text => '<b>'.&mt($itemtext->{'courseid'}).'</b><br />'.'('.
1862: &mt('internal, optional').')',
1.1 raeburn 1863: input => 'textbox',
1864: size => '25',
1865: },
1866: 'cloners' => {
1.3 raeburn 1867: text => '<b>'.&mt($itemtext->{'cloners'}).'</b><br />'.
1.24 raeburn 1868: &mt('Owner and Coordinators included automatically'),
1.1 raeburn 1869: input => 'textbox',
1.41 www 1870: size => '40'
1.1 raeburn 1871: },
1872: 'rolenames' => {
1.3 raeburn 1873: text => '<b>'.&mt($itemtext->{'rolenames'}).'</b><br />'.
1.9 raeburn 1874: '('.$replace.')',
1.1 raeburn 1875: input => 'textbox',
1876: size => '20',
1.19 faziophi 1877: advanced => 1
1.1 raeburn 1878: },
1879: 'externalsyllabus' => {
1.49.2.10 raeburn 1880: text => '<b>'.&mt($itemtext->{'externalsyllabus'}).'</b><br />'.
1881: &mt('(Syllabus type in use)').(' ' x2).
1882: &mt('[_1]Edit[_2]','<a href="/public/'.$cdom.'/'.$cnum.'/syllabus?forceedit=1">',
1883: '</a>'),
1.1 raeburn 1884: },
1885: 'hidefromcat' => {
1.3 raeburn 1886: text => '<b>'.&mt($itemtext->{'hidefromcat'}).'</b><br />'.
1.1 raeburn 1887: ' ('.&mt('included by default if assigned institutional code, or categorized').')',
1888: input => 'radio',
1889: },
1890: 'categories' => {
1.3 raeburn 1891: text => '<b>'.&mt($itemtext->{'categories'}).'</b> <a href="javascript:catsbrowser()">'.
1.1 raeburn 1892: &mt('Display Categories').'</a>',
1893: input => 'textbox',
1894: size => '25',
1895: },
1.35 raeburn 1896: 'loncaparev' => {
1897: text => '<b>'.&mt($itemtext->{'loncaparev'}).'</b>',
1898: },
1.49.2.6 raeburn 1899: 'defaultcredits' => {
1900: text => '<b>'.&mt($itemtext->{'defaultcredits'}).'</b>',
1901: },
1.1 raeburn 1902: );
1903: my $datatable;
1904: my $count = 0;
1905: foreach my $item (@{$ordered}) {
1.49.2.7 raeburn 1906: my $colspan;
1.1 raeburn 1907: if ($item eq 'hidefromcat') {
1908: next if (!$can_toggle_cat);
1909: } elsif ($item eq 'categories') {
1910: next if (!$can_categorize);
1911: }
1.49.2.7 raeburn 1912: unless (($item eq 'cloners') || ($item eq 'rolenames')) {
1913: $colspan = 2;
1914: }
1.1 raeburn 1915: $count ++;
1.19 faziophi 1916: if (exists $items{$item}{advanced} && $items{$item}{advanced} == 1) {
1.49.2.7 raeburn 1917: $datatable .= &item_table_row_start($items{$item}{text},$count,"advanced",$colspan);
1.19 faziophi 1918: } else {
1.49.2.7 raeburn 1919: $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
1.19 faziophi 1920: }
1.1 raeburn 1921: if ($items{$item}{input} eq 'radio') {
1922: $datatable .= &yesno_radio($item,$settings);
1923: } elsif ($item eq 'cloners') {
1924: my $includeempty = 1;
1925: my $num = 0;
1.49.2.7 raeburn 1926: $datatable .= '</td><td align="right">'.
1927: &Apache::loncommon::start_data_table().
1.1 raeburn 1928: &Apache::loncommon::start_data_table_row().
1929: '<td><span class="LC_nobreak"><label>'.
1930: &mt('Any user in any domain:').
1931: ' <input type="radio" name="cloners_all" value="1" ';
1932: if ($settings->{$item} eq '*') {
1933: $datatable .= ' checked="checked" ';
1934: }
1935: $datatable .= 'onchange="javascript:update_cloners('.
1936: "'cloners_all'".');" />'.&mt('Yes').'</label>'.
1937: (' 'x2).'<input type="radio" name="cloners_all" value="0" ';
1938: if ($settings->{$item} ne '*') {
1939: $datatable .= ' checked="checked" ';
1940: }
1941: $datatable .= ' onchange="javascript:update_cloners('.
1942: "'cloners_all'".');"/>'.&mt('No').'</label></td>'.
1943: &Apache::loncommon::end_data_table_row().
1944: &Apache::loncommon::end_data_table().
1.49.2.7 raeburn 1945: '<table><tr><td align="left"><b>'.&mt('Or').
1946: '</b></td></tr></table>'.
1.1 raeburn 1947: &Apache::loncommon::start_data_table();
1948: my @cloners;
1949: if ($settings->{$item} eq '') {
1950: $datatable .= &new_cloners_dom_row($cdom,'0');
1951: } elsif ($settings->{$item} ne '*') {
1952: my @entries = split(/,/,$settings->{$item});
1953: if (@entries > 0) {
1954: foreach my $entry (@entries) {
1955: my ($uname,$udom) = split(/:/,$entry);
1.23 raeburn 1956: if ($udom =~ /^$match_domain$/) {
1957: unless (&Apache::lonnet::domain($udom)) {
1958: next;
1959: }
1960: } else {
1961: next;
1962: }
1.1 raeburn 1963: if ($uname eq '*') {
1964: $datatable .=
1965: &Apache::loncommon::start_data_table_row().
1.3 raeburn 1966: '<td valign="top" align="left"><span class="LC_nobreak">'.
1.23 raeburn 1967: &mt('Any user in domain:').'<b> '.$udom.
1.1 raeburn 1968: '</b><input type="hidden" name="cloners_dom_'.$num.
1969: '" value="'.$udom.'" /></span><br />'.
1970: '<span class="LC_nobreak"><label><input type="checkbox" '.
1.3 raeburn 1971: 'name="cloners_delete" value="'.$num.'" onchange="javascript:update_cloners('."'cloners_delete','$num'".');" />'.
1.1 raeburn 1972: &mt('Delete').'</label></span></td>'.
1973: &Apache::loncommon::end_data_table_row();
1974: $num ++;
1.23 raeburn 1975: } elsif (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
1976: unless (grep(/^\Q$entry\E$/,@cloners)) {
1977: push(@cloners,$entry);
1978: }
1.1 raeburn 1979: }
1980: }
1981: }
1982: }
1983: my $add_domtitle = &mt('Any user in additional domain:');
1984: if ($settings->{$item} eq '*') {
1985: $add_domtitle = &mt('Any user in specific domain:');
1986: } elsif ($settings->{$item} eq '') {
1987: $add_domtitle = &mt('Any user in other domain:');
1988: }
1989: my $cloners_str = join(',',@cloners);
1990: $datatable .= &Apache::loncommon::start_data_table_row().
1991: '<td align="left"><span class="LC_nobreak">'.
1992: $add_domtitle.'</span><br />'.
1993: &Apache::loncommon::select_dom_form('','cloners_newdom',
1994: $includeempty).
1995: '<input type="hidden" name="cloners_total" value="'.$num.'" />'.
1996: '</td>'.&Apache::loncommon::end_data_table_row().
1.3 raeburn 1997: &Apache::loncommon::end_data_table().
1.49.2.7 raeburn 1998: '<table><tr><td align="left"><b>'.&mt('And').
1999: '</b></td></tr></table>'.
1.1 raeburn 2000: &Apache::loncommon::start_data_table().
2001: &Apache::loncommon::start_data_table_row().
2002: '<td align="left">'.
2003: &mt('Specific users').' (<tt>'.
2004: &mt('user:domain,user:domain').'</tt>)<br />'.
2005: &Apache::lonhtmlcommon::textbox($item,$cloners_str,
2006: $items{$item}{'size'}).
2007: '</td>'.&Apache::loncommon::end_data_table_row().
2008: &Apache::loncommon::end_data_table();
2009: } elsif ($item eq 'rolenames') {
1.49.2.7 raeburn 2010: $datatable .= '</td><td align="right">'.
2011: &Apache::loncommon::start_data_table();
1.9 raeburn 2012: my @roles;
2013: if ($crstype eq 'Community') {
2014: @roles = ('co');
2015: } else {
2016: @roles = ('cc');
2017: }
2018: push (@roles,('in','ta','ep','ad','st'));
2019: foreach my $role (@roles) {
1.1 raeburn 2020: $datatable .= &Apache::loncommon::start_data_table_row().
2021: '<td align="left"><span class="LC_nobreak">'.
2022: &Apache::lonnet::plaintext($role,$crstype,undef,1).
2023: '</span></td><td align="left">'.
2024: &Apache::lonhtmlcommon::textbox('rolenames_'.$role,
2025: $settings->{$role.'.plaintext'},
2026: $items{$item}{size}).'</td>'.
2027: &Apache::loncommon::end_data_table_row();
2028: }
2029: $datatable .= &Apache::loncommon::end_data_table().'</td>';
2030: } elsif ($item eq 'categories') {
1.49.2.7 raeburn 2031: my $launcher = 'onfocus="this.blur();javascript:catsbrowser();"';
1.3 raeburn 2032: $datatable .= '<input type="hidden" name="categories" value="'.$settings->{$item}.'" />'.
2033: &Apache::lonhtmlcommon::textbox($item.'_display',$settings->{$item},
2034: $items{$item}{size},$launcher);
1.24 raeburn 2035: } elsif ($item eq 'owner') {
2036: my $owner = $env{'course.'.$env{'request.course.id'}.'.internal.courseowner'};
2037: if ($owner =~ /:/) {
2038: my ($ownername,$ownerdom) = split(':',$owner);
2039: $owner = &Apache::loncommon::plainname($ownername,$ownerdom);
2040: } elsif ($owner ne '') {
2041: $owner = &Apache::loncommon::plainname($owner,$cdom);
2042: } else {
2043: $owner = &mt('None specified');
2044: }
2045: $datatable .= $owner;
1.49.2.11! raeburn 2046: } elsif ($item eq 'clonedfrom') {
! 2047: my $clonesrc = $env{'course.'.$env{'request.course.id'}.'.clonedfrom'};
! 2048: my $clonedfrom = &mt('None');
! 2049: if ($clonesrc =~ m{/$match_domain/$match_courseid}) {
! 2050: my %clonesrcinfo = &Apache::lonnet::coursedescription($cdom.'/'.$cnum);
! 2051: if ($clonesrcinfo{'description'}) {
! 2052: $clonedfrom = $clonesrcinfo{'description'}.' '.($clonesrc);
! 2053: }
! 2054: }
! 2055: $datatable .= $clonedfrom;
1.25 raeburn 2056: } elsif ($item eq 'co-owners') {
2057: my $coowners = $env{'course.'.$env{'request.course.id'}.'.internal.co-owners'};
2058: my @currcoown;
2059: if ($coowners) {
2060: @currcoown = split(',',$coowners);
2061: }
2062: if (&Apache::lonnet::is_course_owner($cdom,$cnum)) {
2063: if (($crstype eq 'Course') && ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) && ($autocoowner)) {
2064: $datatable .= &show_autocoowners(@currcoown);
2065: } else {
2066: $datatable .= &coowner_invitations($cnum,$cdom,@currcoown);
2067: }
2068: } else {
2069: if (($crstype eq 'Course') && ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) && ($autocoowner)) {
2070: $datatable .= &show_autocoowners(@currcoown);
2071: } else {
2072: $datatable .= &manage_coownership($cnum,$cdom,@currcoown);
2073: }
2074: }
1.49.2.10 raeburn 2075: } elsif ($item eq 'externalsyllabus') {
2076: my $external = $env{'course.'.$env{'request.course.id'}.'.externalsyllabus'};
2077: my $uploaded = $env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'};
2078: my $minimal = $env{'course.'.$env{'request.course.id'}.'.minimalsyllabus'};
2079: if (($minimal =~/\w/) || ($uploaded =~/\w/)) {
2080: if ($minimal =~/\w/) {
2081: if ($external =~ m{\Q$minimal\E$}) {
2082: undef($external);
2083: }
2084: } elsif ($uploaded =~/\w/) {
2085: if ($external =~ m{\Q$uploaded\E$}) {
2086: undef($external);
2087: }
2088: }
2089: } elsif ($external!~/\w/) {
2090: undef($external);
2091: }
2092: if ($external) {
2093: $datatable .= &mt('External URL');
2094: } elsif ($minimal) {
2095: $datatable .= &mt('Minimal template');
2096: } elsif ($uploaded) {
2097: $datatable .= &mt('Uploaded file');
2098: } else {
2099: $datatable .= &mt('Standard template');
2100: }
2101: $datatable .= (' ' x 2).
2102: &mt('[_1]View[_2]',
2103: '<a href="javascript:syllabusinfo();">',
2104: '</a>');
1.35 raeburn 2105: } elsif ($item eq 'loncaparev') {
2106: my $loncaparev = $env{'course.'.$env{'request.course.id'}.'.internal.releaserequired'};
2107: my $showreqd;
2108: if ($loncaparev) {
1.36 raeburn 2109: $showreqd = &mt('[_1] or newer',$loncaparev).' <a href="javascript:loncaparevinfo()">'.
1.37 raeburn 2110: &mt('Details').'</a>';
1.35 raeburn 2111: } else {
2112: $showreqd = &mt('No specific version required');
2113: }
2114: $datatable .= $showreqd;
1.1 raeburn 2115: } else {
2116: $datatable .= &Apache::lonhtmlcommon::textbox($item,$settings->{$item},$items{$item}{size});
2117: }
2118: $datatable .= &item_table_row_end();
2119: }
2120: $$rowtotal += scalar(@{$ordered});
2121: return $datatable;
2122: }
2123:
2124: sub new_cloners_dom_row {
2125: my ($newdom,$num) = @_;
2126: my $output;
2127: if ($newdom ne '') {
2128: $output .= &Apache::loncommon::start_data_table_row().
2129: '<td valign="top"><span class="LC_nobreak">'.
2130: &mt('Any user in domain:').' <b>'.$newdom.'</b>'.
2131: (' 'x2).'<label><input type="radio" '.
2132: 'name="cloners_activate" value="'.$num.'" '.
1.3 raeburn 2133: 'onchange="javascript:update_cloners('.
1.1 raeburn 2134: "'cloners_activate','$num'".');" />'.
2135: &mt('Yes').'</label>'.(' 'x2).
2136: '<label><input type="radio" '.
2137: 'name="cloners_activate" value="" checked="checked" '.
1.3 raeburn 2138: 'onchange="javascript:update_cloners('.
1.1 raeburn 2139: "'cloners_activate','$num'".');" />'.
1.3 raeburn 2140: &mt('No').'</label><input type="hidden" name="cloners_dom_'.
2141: $num.'" value="'.$newdom.'" /></span></td>'.
1.1 raeburn 2142: &Apache::loncommon::end_data_table_row();
2143: }
2144: return $output;
2145: }
2146:
2147: sub can_modify_catsettings {
1.12 raeburn 2148: my ($dom,$crstype) = @_;
1.1 raeburn 2149: my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom);
2150: my ($can_toggle_cat,$can_categorize);
2151: if (ref($domconf{'coursecategories'}) eq 'HASH') {
1.12 raeburn 2152: if ($crstype eq 'Community') {
2153: if ($domconf{'coursecategories'}{'togglecatscomm'} eq 'comm') {
2154: $can_toggle_cat = 1;
2155: }
2156: if ($domconf{'coursecategories'}{'categorizecomm'} eq 'comm') {
2157: $can_categorize = 1;
2158: }
2159: } else {
2160: if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') {
2161: $can_toggle_cat = 1;
2162: }
2163: if ($domconf{'coursecategories'}{'categorize'} eq 'crs') {
2164: $can_categorize = 1;
2165: }
1.1 raeburn 2166: }
2167: }
2168: return ($can_toggle_cat,$can_categorize);
2169: }
2170:
2171: sub assign_course_categories {
1.9 raeburn 2172: my ($r,$crstype) = @_;
1.1 raeburn 2173: my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
2174: my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
2175: my $hascats = 0;
2176: my $cathash;
2177: my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom);
2178: if (ref($domconf{'coursecategories'}) eq 'HASH') {
2179: $cathash = $domconf{'coursecategories'}{'cats'};
2180: if (ref($cathash) eq 'HASH') {
1.12 raeburn 2181: foreach my $cat (keys(%{$cathash})) {
2182: next if ($cat eq 'instcode::0');
2183: unless ($crstype eq 'Community') {
2184: next if ($cat eq 'communities::0');
2185: }
2186: $hascats ++;
2187: }
1.1 raeburn 2188: }
2189: }
2190: my $catwin_js;
2191: if ($hascats) {
1.9 raeburn 2192: my $alert;
2193: if ($crstype eq 'Community') {
2194: $alert = &mt("Use 'Save' in the main window to save community categories");
2195: } else {
2196: $alert = &mt("Use 'Save' in the main window to save course categories");
2197: }
1.1 raeburn 2198: $catwin_js = <<ENDSCRIPT;
2199: <script type="text/javascript">
2200:
2201: function updateCategories() {
2202: var newcategories = '';
2203: var unescapedcats = '';
2204: if (document.chgcats.usecategory.length) {
2205: for (var i=0; i<document.chgcats.usecategory.length; i++) {
2206: if (document.chgcats.usecategory[i].checked == true) {
2207: newcategories = newcategories + document.chgcats.usecategory[i].value + '&';
2208: unescapedcats = unescapedcats + document.chgcats.catname[i].value + ' & ';
2209: }
2210: }
2211: if (newcategories.length > 0) {
2212: newcategories = newcategories.slice(0,-1);
2213: }
2214: if (unescapedcats.length > 0) {
2215: unescapedcats = unescapedcats.slice(0,-3);
2216: }
2217: } else {
2218: if (document.chgcats.usecategory.checked == true) {
2219: newcategories = document.chgcats.usecategory.value;
2220: unescapedcats = document.chgcats.catname.value;
2221: }
2222: }
2223: opener.document.display.categories.value = newcategories;
2224: opener.document.display.categories_display.value = unescapedcats;
2225: alert("$alert");
2226: self.close();
2227: return;
2228: }
2229:
2230: </script>
2231: ENDSCRIPT
2232: } else {
2233: my $onload;
2234: }
1.9 raeburn 2235: my ($crscat,$catcrs,$assign);
2236: if ($crstype eq 'Community') {
2237: $crscat = 'Community Categories';
2238: $catcrs = &mt('Categorize Community');
2239: $assign = &mt('Assign one or more categories to this community.')
2240: } else {
2241: $crscat = 'Course Categories';
2242: $catcrs = &mt('Categorize Course');
2243: $assign = &mt('Assign one or more categories to this course.')
2244: }
1.1 raeburn 2245: my $start_page =
1.9 raeburn 2246: &Apache::loncommon::start_page($crscat,$catwin_js,
1.1 raeburn 2247: {'only_body' => 1,});
2248: my $end_page = &Apache::loncommon::end_page();
1.9 raeburn 2249: my $categoriesform = '<h3>'.$catcrs.'</h3>';
1.1 raeburn 2250: if ($hascats) {
2251: my %currsettings =
2252: &Apache::lonnet::get('environment',['hidefromcat','categories'],$cdom,$cnum);
1.12 raeburn 2253: my $cattable = &Apache::loncommon::assign_categories_table($cathash,
2254: $currsettings{'categories'},$crstype);
2255: if ($cattable eq '') {
2256: $categoriesform .= &mt('No suitable categories defined for this course type in this domain.');
2257: } else {
2258: $categoriesform .= $assign.'<br /><br />'.
2259: '<form name="chgcats" action="/adm/courseprefs" method="post">'."\n".
2260: $cattable."\n".
2261: '<br /><input type="button" name="changes" value="'.
2262: &mt('Copy to main window').'" '.
2263: 'onclick="javascript:updateCategories()" /></form><br />';
2264: }
1.1 raeburn 2265: } else {
1.12 raeburn 2266: $categoriesform .= &mt('No categories defined in this domain.');
1.1 raeburn 2267: }
2268: $r->print($start_page.$categoriesform.$end_page);
2269: return;
2270: }
2271:
1.36 raeburn 2272: sub display_loncaparev_constraints {
2273: my ($r,$navmap,$loncaparev,$crstype) = @_;
2274: my $cid = $env{'request.course.id'};
2275: my $cdom = $env{'course.'.$cid.'.domain'};
2276: my $cnum = $env{'course.'.$cid.'.num'};
2277: my $output;
1.39 raeburn 2278: my %lt = &Apache::lonlocal::texthash (
2279: 'all' => 'all',
2280: 'section/group' => 'section/group',
2281: 'user' => 'user',
2282: );
1.36 raeburn 2283: my (%checkparms,%checkresponsetypes,%checkcrstypes,%anonsurvey,%randomizetry);
2284: &Apache::loncommon::build_release_hashes(\%checkparms,\%checkresponsetypes,
2285: \%checkcrstypes,\%anonsurvey,\%randomizetry);
2286: if (defined($checkcrstypes{$crstype})) {
2287: $output .= '<h4>'.&mt('Course type: [_1] requires [_2] or newer',$crstype,
2288: $checkcrstypes{$crstype}).'</h4>';
2289: }
2290: my (%fromparam,%rowspan,%bymap,%byresource,@scopeorder,%toshow,%allmaps,
2291: %byresponsetype,%bysubmission);
1.39 raeburn 2292: @scopeorder = ('all','section/group','user');
1.36 raeburn 2293: my $resourcedata = &Apache::lonparmset::readdata($cnum,$cdom);
2294: if (ref($resourcedata) eq 'HASH') {
2295: foreach my $key (keys(%{$resourcedata})) {
2296: foreach my $item (keys(%checkparms)) {
2297: if ($key =~ /(\Q$item\E)$/) {
2298: if (ref($checkparms{$item}) eq 'ARRAY') {
2299: my $value = $resourcedata->{$key};
1.49.2.9 raeburn 2300: if ($item eq 'examcode') {
2301: if (&Apache::lonnet::validCODE($value)) {
2302: $value = 'valid';
2303: } else {
2304: $value = '';
2305: }
2306: }
1.36 raeburn 2307: my ($middle,$scope,$which,$level,$map,$resource);
2308: if (grep(/^\Q$value\E$/,@{$checkparms{$item}})) {
2309: my $stdtype = &Apache::lonparmset::standard_parameter_types($item);
2310: my $stdname = &Apache::lonparmset::standard_parameter_names($item);
2311: my $valname = &get_param_description($stdtype,$value);
2312: my $rev = $Apache::lonnet::needsrelease{'parameter:'.$item.':'.$value};
2313: my $start = $cid.'.';
2314: if ($key =~ /^\Q$start\E(\[useropt\:($match_username\:$match_domain)\]\.)/) {
2315: $middle = $1;
2316: $which = $2;
2317: $scope = 'user';
2318: } elsif ($key =~ /^\Q$start\E(\[(\w+)\]\.)/) {
2319: $middle = $1;
2320: $which = $2;
2321: $scope = 'section/group';
2322: } else {
1.39 raeburn 2323: $scope = 'all';
1.36 raeburn 2324: }
2325: my $what="$stdname=$valname";
2326: if ($key =~ /^\Q$start$middle\E\w+\.\Q$item\E$/) {
2327: $level = 'general';
1.39 raeburn 2328: if ($scope eq 'all') {
1.36 raeburn 2329: if (ref($fromparam{$rev}{$scope}) eq 'ARRAY') {
2330: unless(grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}})) {
2331: push(@{$fromparam{$rev}{$scope}},$what);
2332: }
2333: } else {
2334: push(@{$fromparam{$rev}{$scope}},$what);
2335: }
2336: } else {
2337: if (ref($fromparam{$rev}{$scope}{$which}) eq 'ARRAY') {
2338: unless (grep(/^\Q$what\E$/,@{$fromparam{$rev}{$scope}{$which}})) {
2339: push(@{$fromparam{$rev}{$scope}{$which}},$what);
2340: }
2341: } else {
2342: push(@{$fromparam{$rev}{$scope}{$which}},$what);
2343: }
2344: }
2345: $rowspan{$rev} ++;
2346: } elsif ($key =~ /^\Q$start$middle\E(.+)___\(all\).\w+\.\Q$item\E$/) {
2347: $level = 'folder';
2348: $map = $1;
1.39 raeburn 2349: if ($scope eq 'all') {
1.36 raeburn 2350: if (ref($bymap{$map}{$rev}{$scope}) eq 'ARRAY') {
2351: unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}})) {
2352: push(@{$bymap{$map}{$rev}{$scope}},$what);
2353: }
2354: } else {
2355: push(@{$bymap{$map}{$rev}{$scope}},$what);
2356: }
2357: } else {
2358: if (ref($bymap{$map}{$rev}{$scope}{$which}) eq 'ARRAY') {
2359: unless(grep(/^\Q$what\E$/,@{$bymap{$map}{$rev}{$scope}{$which}})) {
2360: push(@{$bymap{$map}{$rev}{$scope}{$which}},$what);
2361: }
2362: } else {
2363: push(@{$bymap{$map}{$rev}{$scope}{$which}},$what);
2364: }
2365: }
2366: } elsif ($key =~ /^\Q$start$middle\E(.+)\.\w+\.\Q$item\E$/) {
2367: $level = 'resource';
2368: $resource = $1;
1.39 raeburn 2369: if ($scope eq 'all') {
1.36 raeburn 2370: if (ref($byresource{$resource}{$rev}{$scope}) eq 'ARRAY') {
2371: unless(grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}})) {
2372: push(@{$byresource{$resource}{$rev}{$scope}},$what);
2373: }
2374: } else {
2375: push(@{$byresource{$resource}{$rev}{$scope}},$what);
2376: }
2377: } else {
2378: if (ref($byresource{$resource}{$rev}{$scope}{$which}) eq 'ARRAY') {
2379: unless (grep(/^\Q$what\E$/,@{$byresource{$resource}{$rev}{$scope}{$which}})) {
2380: push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what);
2381: }
2382: } else {
2383: push(@{$byresource{$resource}{$rev}{$scope}{$which}},$what);
2384: }
2385: }
2386: }
2387: }
2388: }
2389: }
2390: }
2391: }
2392: if (keys(%fromparam)) {
2393: $output .= '<h4>'.&mt('Requirements from general settings').'</h4>'.
2394: &Apache::loncommon::start_data_table().
2395: &Apache::loncommon::start_data_table_header_row().
2396: '<th>'.&mt('Release').'</th><th>'.&mt('Scope').'</th>'.
2397: '<th>'.&mt('Extent').'</th><th>'.&mt('Setting').'</th>'.
2398: &Apache::loncommon::end_data_table_header_row();
2399: foreach my $rev (keys(%fromparam)) {
2400: $output .= &Apache::loncommon::start_data_table_row().
2401: '<td rowspan="'.$rowspan{$rev}.'">'.$rev.'</td>';
2402: my $newrow;
2403: foreach my $scope (@scopeorder) {
2404: if (ref($fromparam{$rev}{$scope}) eq 'HASH') {
2405: if ($newrow) {
2406: $output .= &Apache::loncommon::continue_data_table_row();
2407: }
1.39 raeburn 2408: $output .= '<td>'.$lt{$scope}.'</td>';
1.36 raeburn 2409: foreach my $which (sort(keys(%{$fromparam{$rev}{$scope}}))) {
2410: $output .= '<td>'.$which.'</td><td>'.
2411: join('<br />',@{$fromparam{$rev}{$scope}{$which}}).'</td>';
2412: }
2413: $output .= &Apache::loncommon::end_data_table_row();
2414: $newrow = 1;
2415: } elsif (ref($fromparam{$rev}{$scope}) eq 'ARRAY') {
2416: if ($newrow) {
2417: $output .= &Apache::loncommon::continue_data_table_row();
2418: }
1.39 raeburn 2419: $output .= '<td>'.$lt{$scope}.'</td><td> </td><td>'.
1.36 raeburn 2420: join('<br />',@{$fromparam{$rev}{$scope}}).'</td>'.
2421: &Apache::loncommon::end_data_table_row();
2422: $newrow = 1;
2423: }
2424: }
2425: }
2426: $output .= &Apache::loncommon::end_data_table().'<br />';
2427: }
2428: }
2429:
2430: if (defined($navmap)) {
2431: my %anonsubms=&Apache::lonnet::dump('nohist_anonsurveys',$cdom,$cnum);
2432: my $rev_anonsurv=$Apache::lonnet::needsrelease{'parameter:type:anonsurvey'};
2433: my %randtrysubms=&Apache::lonnet::dump('nohist_randomizetry',$cdom,$cnum);
2434: my $rev_randtry=$Apache::lonnet::needsrelease{'parameter:type:randomizetry'};
2435: my $stdtype=&Apache::lonparmset::standard_parameter_types('type');
2436: my $stdname=&Apache::lonparmset::standard_parameter_names('type');
2437: my $valanon=&get_param_description($stdtype,'anonsurvey');
2438: my $valrandtry=&get_param_description($stdtype,'randomizetry');
2439:
2440: foreach my $res ($navmap->retrieveResources(undef,sub { $_[0]->is_problem() },1,0)) {
2441: my @parts = @{$res->parts()};
2442: my $symb = $res->symb();
2443: my $enclosing_map = &Apache::lonnet::declutter($res->enclosing_map_src());
2444: foreach my $part (@parts) {
2445: if (exists($anonsubms{$symb."\0".$part})) {
2446: my $rev = $rev_anonsurv;
2447: my $what="$stdname=$valanon";
2448: if (ref($bysubmission{$symb}{$rev}) eq 'ARRAY') {
2449: unless (grep(/^\Q$what\E/,@{$bysubmission{$symb}{$rev}})) {
2450: push(@{$bysubmission{$symb}{$rev}},$what);
2451: }
2452: } else {
2453: push(@{$bysubmission{$symb}{$rev}},$what);
2454: }
2455: $allmaps{$enclosing_map} = 1;
2456: }
2457: if (exists($randtrysubms{$symb."\0".$part})) {
2458: my $rev = $rev_randtry;
2459: my $what="$stdname=$valrandtry";
2460: if (ref($bysubmission{$symb}{$rev}) eq 'ARRAY') {
2461: unless (grep(/^\Q$what\E/,@{$bysubmission{$symb}{$rev}})) {
2462: push(@{$bysubmission{$symb}{$rev}},$what);
2463: }
2464: } else {
2465: push(@{$bysubmission{$symb}{$rev}},$what);
2466: }
2467: $allmaps{$enclosing_map} = 1;
2468: }
2469: }
2470: my %responses = $res->responseTypes();
2471: foreach my $key (keys(%responses)) {
2472: if (exists($checkresponsetypes{$key})) {
2473: push(@{$byresponsetype{$symb}{$checkresponsetypes{$key}}},$key);
2474: $allmaps{$enclosing_map} = 1;
2475: }
2476: }
2477: }
2478: if (keys(%byresource) > 0) {
2479: foreach my $symb (keys(%byresource)) {
2480: my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
2481: $allmaps{$map} = 1;
2482: }
2483: }
2484: if (keys(%bymap) > 0) {
2485: foreach my $map (keys(%bymap)) {
2486: $allmaps{$map} = 1;
2487: }
2488: }
2489: foreach my $map (keys(%allmaps)) {
2490: my $mapres = $navmap->getResourceByUrl($map);
2491: my $mapsymb = $mapres->symb();
2492: $toshow{$mapsymb} = 1;
2493: if (ref($mapres)) {
2494: my $pcslist = $mapres->map_hierarchy();
2495: if ($pcslist ne '') {
2496: foreach my $pc (split(/,/,$pcslist)) {
2497: my $res = $navmap->getByMapPc($pc);
2498: if (ref($res)) {
2499: my $symb = $res->symb();
2500: unless ($symb eq '______') {
2501: $toshow{$symb} = 1;
2502: }
2503: }
2504: }
2505: }
2506: }
2507: }
2508: }
2509: my $mapres_header = '<h4>'.
2510: &mt('Requirements for specific folders or resources').
2511: '</h4>';
2512: if ((keys(%toshow) > 0) || (keys(%byresource) > 0) ||
2513: (keys(%bysubmission) > 0) || (keys(%byresponsetype))) {
2514: $output .= $mapres_header;
2515: }
2516: my $top_header = '<h3>'.&mt('LON-CAPA version dependencies').'</h3>';
2517: my $title = 'Version Constraints';
2518: my $start_page =
2519: &Apache::loncommon::start_page($title,undef,{'only_body' => 1,});
2520: $r->print($start_page.$top_header);
2521: if ($output) {
2522: $r->print($output);
2523: if (defined($navmap)) {
2524: &show_contents_view($r,$navmap,$cid,\%toshow,\%bymap,\%byresource,\%bysubmission,
1.39 raeburn 2525: \%byresponsetype,\@scopeorder,\%lt);
1.36 raeburn 2526: }
2527: $r->print('<br /><br />');
2528: } else {
2529: $r->print('<p class="LC_info">'.
2530: &mt('No version requirements from resource content or settings.').
2531: '</p>');
2532: }
2533: $r->print(&Apache::loncommon::end_page());
2534: return;
2535: }
2536:
2537: sub show_contents_view {
1.39 raeburn 2538: my ($r,$navmap,$cid,$toshow,$bymap,$byresource,$bysubmission,$byresponsetype,
2539: $scopeorder,$lt) = @_;
1.36 raeburn 2540: if ((keys(%{$toshow}) > 0) || (keys(%{$byresource}) > 0) ||
2541: (keys(%{$bysubmission}) > 0) || (keys(%{$byresponsetype}) > 0)) {
2542: my $location=&Apache::loncommon::lonhttpdurl("/adm/lonIcons");
2543: my $whitespace = '<img src="'.$location.'/whitespace_21.gif" alt="" />';
2544: my $icon = '<img src="'.$location.'/navmap.folder.open.gif" alt="" />';
2545: my $topmap = $env{'course.'.$cid.'.url'};
2546: $r->print(&Apache::loncommon::start_data_table().
2547: &Apache::loncommon::start_data_table_header_row().
2548: '<th>'.&mt('Location').'</th><th>'.&mt('Release').'</th>'.
2549: '<th>'.&mt('Attribute/Setting').'</th>'.
2550: &Apache::loncommon::end_data_table_header_row().
2551: &Apache::loncommon::start_data_table_row().
1.49.2.8 raeburn 2552: '<td> '.$icon.' '.&mt('Main Content').'</td>');
1.39 raeburn 2553: &releases_by_map($r,$bymap,$topmap,$scopeorder,$lt);
1.36 raeburn 2554: $r->print(&Apache::loncommon::end_data_table_row());
2555: my $it=$navmap->getIterator(undef,undef,undef,1,1,undef);
2556: my $curRes;
2557: my $depth = 0;
2558: my %parent = ();
2559: my $startcount = 5;
2560: my $lastcontainer = $startcount;
2561: while ($curRes = $it->next()) {
2562: if ($curRes == $it->BEGIN_MAP()) {
2563: $depth++;
2564: $parent{$depth}= $lastcontainer;
2565: }
2566: if ($curRes == $it->END_MAP()) {
2567: $depth--;
2568: $lastcontainer = $parent{$depth};
2569: }
2570: my $indent;
2571: for (my $i=0; $i<$depth; $i++) {
2572: $indent.= $whitespace;
2573: }
2574: if (ref($curRes)) {
2575: my $symb = $curRes->symb();
2576: my $ressymb = $symb;
2577: my $srcf = $curRes->src();
2578: my $title = &Apache::lonnet::gettitle($srcf);
2579: if (($curRes->is_sequence()) || ($curRes->is_page())) {
2580: next unless($toshow->{$symb});
2581: my ($parent,$ind,$url) = &Apache::lonnet::decode_symb($symb);
2582: $icon = '<img src="'.$location.'/navmap.folder.open.gif" alt="" />';
2583: if ($curRes->is_page()) {
2584: $icon = '<img src="'.$location.'/navmap.page.open.gif" alt="" />';
2585: }
2586: my $rowspan = 1;
2587: if (ref($bymap->{$url}) eq 'HASH') {
2588: $rowspan = scalar(keys(%{$bymap->{$url}}));
2589: }
2590: $r->print(&Apache::loncommon::start_data_table_row().
2591: '<td rowspan="'.$rowspan.'">'.$indent.$icon.' '.$title.'</td>');
1.48 raeburn 2592: &releases_by_map($r,$bymap,$url,$scopeorder,$lt);
1.36 raeburn 2593: $r->print(&Apache::loncommon::end_data_table_row());
2594: } else {
2595: my $rowspan;
2596: if (ref($byresource->{$symb}) eq 'HASH') {
2597: $rowspan += scalar(keys(%{$byresource->{$symb}}));
2598: }
2599: if (ref($bysubmission->{$symb}) eq 'HASH') {
2600: $rowspan += scalar(keys(%{$bysubmission->{$symb}}));
2601: }
2602: if (ref($byresponsetype->{$symb}) eq 'HASH') {
2603: $rowspan += scalar(keys(%{$byresponsetype->{$symb}}));
2604: }
2605: next if (!$rowspan);
2606: $icon = '<img class="LC_contentImage" src="'.$location.'/problem.gif" alt="'.
2607: &mt('Problem').'" />';
2608: $r->print(&Apache::loncommon::start_data_table_row().
2609: '<td rowspan="'.$rowspan.'">'.$indent.$icon.' '.$title.'</td>');
2610: my $newrow;
2611: if (ref($byresource->{$symb}) eq 'HASH') {
2612: foreach my $rev (sort(keys(%{$byresource->{$symb}}))) {
2613: if ($newrow) {
2614: $r->print(&Apache::loncommon::continue_data_table_row());
2615: }
2616: $r->print('<td valign="middle">'.$rev.'</td><td>');
2617: if (ref($byresource->{$symb}{$rev}) eq 'HASH') {
2618: $r->print('<table border="0">');
2619: foreach my $scope (@{$scopeorder}) {
2620: if (ref($byresource->{$symb}{$rev}{$scope}) eq 'HASH') {
1.39 raeburn 2621: $r->print('<tr><td>'.&mt('Setting - scope: [_1]',$lt->{$scope}).'</td>');
1.36 raeburn 2622: foreach my $which (sort(keys(%{$byresource->{$symb}{$rev}{$scope}}))) {
2623: $r->print('<td>'.$which.'</td><td>'.
2624: join('<br />',@{$byresource->{$symb}{$rev}{$scope}{$which}}).
2625: '</td>');
2626: }
2627: $r->print('</tr>');
2628: } elsif (ref($byresource->{$symb}{$rev}{$scope}) eq 'ARRAY') {
1.39 raeburn 2629: $r->print('<tr><td>'.&mt('Setting - scope: [_1]',$lt->{$scope}).'</td>'.
1.36 raeburn 2630: '<td> </td><td>'.
2631: join('<br />',@{$byresource->{$symb}{$rev}{$scope}}).'</td></tr>');
2632: }
2633: }
2634: $r->print('</table>');
2635: }
2636: $r->print('</td>');
2637: $r->print(&Apache::loncommon::end_data_table_row());
2638: $newrow = 1;
2639: }
2640: }
2641: if (ref($bysubmission->{$symb}) eq 'HASH') {
2642: foreach my $rev (sort(keys(%{$bysubmission->{$symb}}))) {
2643: if ($newrow) {
2644: $r->print(&Apache::loncommon::continue_data_table_row());
2645: }
2646: $r->print('<td>'.$rev.'</td><td>');
2647: if (ref($bysubmission->{$symb}{$rev}) eq 'ARRAY') {
2648: $r->print(&mt('Submissions to: ').' '.
2649: join(', ',@{$bysubmission->{$symb}{$rev}}));
2650: }
2651: $r->print('</td>');
2652: $r->print(&Apache::loncommon::end_data_table_row());
2653: $newrow = 1;
2654: }
2655: }
2656: if (ref($byresponsetype->{$symb}) eq 'HASH') {
2657: foreach my $rev (sort(keys(%{$byresponsetype->{$symb}}))) {
2658: if ($newrow) {
2659: $r->print(&Apache::loncommon::continue_data_table_row());
2660: }
2661: $r->print('<td>'.$rev.'</td><td>');
2662: if (ref($byresponsetype->{$symb}{$rev}) eq 'ARRAY') {
2663: $r->print(&mt('Response Type(s): ').' '.
2664: join('<br />',@{$byresponsetype->{$symb}{$rev}}));
2665: }
2666: $r->print('</td>');
2667: }
2668: $r->print(&Apache::loncommon::end_data_table_row());
2669: }
2670: }
2671: }
2672: }
2673: $r->print(&Apache::loncommon::end_data_table());
2674: }
2675: }
2676:
2677: sub releases_by_map {
1.39 raeburn 2678: my ($r,$bymap,$url,$scopeorder,$lt) = @_;
1.36 raeburn 2679: return unless ((ref($bymap) eq 'HASH') && (ref($scopeorder) eq 'ARRAY'));
2680: if (ref($bymap->{$url}) eq 'HASH') {
2681: foreach my $rev (sort(keys(%{$bymap->{$url}}))) {
2682: $r->print('<td valign="middle">'.$rev.'</td><td>');
2683: if (ref($bymap->{$url}{$rev}) eq 'HASH') {
2684: $r->print('<table border="0">');
2685: foreach my $scope (@{$scopeorder}) {
2686: if (ref($bymap->{$url}{$rev}{$scope}) eq 'HASH') {
1.39 raeburn 2687: $r->print('<tr><td>'.&mt('Setting - scope: [_1]',$lt->{$scope}).'</td>');
1.36 raeburn 2688: foreach my $which (sort(keys(%{$bymap->{$url}{$rev}{$scope}}))) {
2689: $r->print('<td>'.$which.'</td><td>'.
2690: join('<br />',@{$bymap->{$url}{$rev}{$scope}{$which}}).
2691: '</td>');
2692: }
2693: $r->print('</tr>');
2694: } elsif (ref($bymap->{$url}{$rev}{$scope}) eq 'ARRAY') {
1.39 raeburn 2695: $r->print('<tr><td>'.&mt('Setting - scope: [_1]',$lt->{$scope}).
1.36 raeburn 2696: '</td><td> </td><td>'.
2697: join('<br />',@{$bymap->{$url}{$rev}{$scope}}).'</td></tr>');
2698: }
2699: }
2700: $r->print('</table>');
2701: }
2702: $r->print('</td>');
2703: }
2704: } else {
2705: $r->print('<td colspan="2"> </td>');
2706: }
2707: return;
2708: }
2709:
2710: sub get_param_description {
2711: my ($stdtype,$value) = @_;
2712: my $name = $value;
2713: my $paramstrings = &Apache::lonparmset::standard_string_options($stdtype);
2714: unless (ref($paramstrings) eq 'ARRAY') {
2715: return $name;
2716: }
2717: foreach my $possibilities (@{$paramstrings}) {
2718: next unless (ref($possibilities) eq 'ARRAY');
2719: my ($thing, $description) = @{ $possibilities };
2720: if ($thing eq $value) {
2721: $name = $description;
2722: last;
2723: }
2724: }
2725: return $name;
2726: }
2727:
1.25 raeburn 2728: sub show_autocoowners {
2729: my (@currcoown) = @_;
1.49.2.7 raeburn 2730: my $output = '<i><span class="LC_nobreak">'.&mt('Co-ownership is set automatically when a Course Coordinator role[_1] is assigned to official course personnel (from institutional data).','</span><br /><span class="LC_nobreak">').'</span></i>';
1.25 raeburn 2731: if (@currcoown > 0) {
2732: $output .= '<br />'.&mt('Current co-owners are:').' '.
2733: join(', ',map { &Apache::loncommon::plainname(split(':',$_)); } (@currcoown));
2734: } else {
2735: $output .= '<br />'.&mt('Currently no co-owners.');
2736: }
2737: return $output;
2738: }
2739:
2740: sub coowner_invitations {
2741: my ($cnum,$cdom,@currcoown) = @_;
2742: my ($output,@pendingcoown,@othercoords);
2743: my $pendingcoowners =
2744: $env{'course.'.$env{'request.course.id'}.'.internal.pendingco-owners'};
2745: if ($pendingcoowners) {
2746: @pendingcoown = split(',',$pendingcoowners);
2747: }
2748: my $ccrole = 'cc';
2749: my %ccroles = &Apache::lonnet::get_my_roles($cnum,$cdom,undef,undef,[$ccrole]);
2750: foreach my $key (sort(keys(%ccroles))) {
2751: my ($ccname,$ccdom,$role) = split(':',$key);
2752: next if ($key eq $env{'user.name'}.':'.$env{'user.domain'}.':'.$ccrole);
2753: unless (grep(/^\Q$ccname\E:\Q$ccdom\E$/,@currcoown,@pendingcoown)) {
2754: push(@othercoords,$ccname.':'.$ccdom);
2755: }
2756: }
2757: my $coowner_rows = @currcoown + @pendingcoown + @othercoords;
2758: if ($coowner_rows) {
2759: $output .= &Apache::loncommon::start_data_table();
2760: if (@currcoown) {
2761: $output .= &Apache::loncommon::start_data_table_row().
2762: '<td><i>'.&mt('Current co-owners').'</i></td><td>';
2763: foreach my $person (@currcoown) {
2764: my ($co_uname,$co_dom) = split(':',$person);
2765: $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="coowners" checked="checked" value="'.$person.'" />'.&Apache::loncommon::plainname($co_uname,$co_dom).'</label></span>'.(' 'x2).' ';
2766: }
2767: $output .= '</td>'.
2768: &Apache::loncommon::end_data_table_row();
2769: }
2770: if ($pendingcoowners) {
2771: $output .= &Apache::loncommon::start_data_table_row().
2772: '<td><i>'.&mt('Invited as co-owners [_1](agreement pending)','<br />').'</i></td><td>';
2773: foreach my $person (@pendingcoown) {
2774: my ($co_uname,$co_dom) = split(':',$person);
2775: $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="pendingcoowners" checked="checked" value="'.$person.'" />'.&Apache::loncommon::plainname($co_uname,$co_dom).'</label></span>'.(' 'x2).' ';
2776: }
2777: $output .= '</td>'.
2778: &Apache::loncommon::end_data_table_row();
2779: }
2780: if (@othercoords) {
2781: $output .= &Apache::loncommon::start_data_table_row().
2782: '<td><i>'.&mt('Invite other Coordinators [_1]to become co-owners','<br />').'</i></td><td>';
2783: foreach my $person (@othercoords) {
2784: my ($co_uname,$co_dom) = split(':',$person);
2785: $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="invitecoowners" value="'.$person.'" />'.&Apache::loncommon::plainname($co_uname,$co_dom).'</label></span>'.(' 'x2).' ';
2786: }
2787: $output .= '</td>'.
2788: &Apache::loncommon::end_data_table_row();
2789: }
2790: $output .= &Apache::loncommon::end_data_table();
2791: } else {
2792: $output = &mt('There are no coordinators to select as co-owners');
2793: }
2794: return $output;
2795: }
2796:
2797: sub manage_coownership {
2798: my ($cnum,$cdom,@currcoown) = @_;
2799: my (@pendingcoown);
2800: my $pendingcoowners =
2801: $env{'course.'.$env{'request.course.id'}.'.internal.pendingco-owners'};
2802: if ($pendingcoowners) {
2803: @pendingcoown = split(',',$pendingcoowners);
2804: }
2805: my ($is_coowner,$is_pending,$output);
2806: my $uname = $env{'user.name'};
2807: my $udom = $env{'user.domain'};
2808: if (grep(/^\Q$uname\E:\Q$udom\E$/,@currcoown)) {
2809: $is_coowner = 1;
2810: }
2811: if (grep(/^\Q$uname\E:\Q$udom\E$/,@pendingcoown)) {
2812: $is_pending = 1;
2813: }
2814: if (@currcoown && ($is_coowner || $is_pending)) {
2815: $output = &Apache::loncommon::start_data_table();
2816: }
2817: if (@currcoown) {
2818: if ($is_coowner || $is_pending) {
2819: $output .= &Apache::loncommon::start_data_table().
2820: &Apache::loncommon::start_data_table_row().'<td>';
2821: }
2822: $output .= &mt('Current co-owners are:').' '.
2823: join(', ', map { &Apache::loncommon::plainname(split(':',$_)); } (@currcoown));
2824: if ($is_coowner || $is_pending) {
2825: $output .= '</td>'.&Apache::loncommon::end_data_table_row();
2826: }
2827: }
2828: if ($is_coowner || $is_pending) {
2829: if (@currcoown) {
2830: $output .= &Apache::loncommon::start_data_table_row().'<td>';
2831: }
2832: $output .= '<span class="LC_nobreak">';
2833: if ($is_coowner) {
2834: $output .= &mt('You are currently a co-owner:').' <label><input type="checkbox" name="remove_coowoner" value="'.$uname.':'.$udom.'" />'.&mt('Discontinue?').'</label>';
2835: } else {
2836: $output .= &mt('The course owner has invited you to become a co-owner:').' <label><input type="radio" name="pending_coowoner" value="accept" />'.&mt('Accept?').'</label>'.(' 'x2).
2837: '<label><input type="radio" name=pending_coowoner" value="decline" />'.&mt('Decline?').'</label>';
2838: }
2839: $output .= '</span>';
2840: if (@currcoown) {
2841: $output .= '</td>'.&Apache::loncommon::end_data_table_row();
2842: }
2843: }
2844: if (@currcoown && ($is_coowner || $is_pending)) {
2845: $output .= &Apache::loncommon::end_data_table();
2846: }
2847: return $output;
2848: }
2849:
1.1 raeburn 2850: sub print_localization {
1.3 raeburn 2851: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
2852: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 2853: return;
2854: }
2855: my %items = (
2856: languages => {
1.17 faziophi 2857: text => '<b>'.&mt($itemtext->{'languages'}).'</b><br />'.
2858: &mt("(overrides individual user preference)"),
1.1 raeburn 2859: input => 'selectbox',
2860: },
2861: timezone => {
1.17 faziophi 2862: text => '<b>'.&mt($itemtext->{'timezone'}).'</b>',
1.1 raeburn 2863: input => 'selectbox',
2864: },
2865: datelocale => {
1.17 faziophi 2866: text => '<b>'.&mt($itemtext->{'datelocale'}).'</b>',
1.1 raeburn 2867: input => 'selectbox',
2868: },
2869: );
2870: my $datatable;
2871: my $count = 0;
2872: foreach my $item (@{$ordered}) {
2873: $count ++;
1.49.2.7 raeburn 2874: my $colspan;
2875: unless ($item eq 'languages') {
2876: $colspan = 2;
2877: }
2878: $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
1.1 raeburn 2879: if ($item eq 'timezone') {
2880: my $includeempty = 1;
2881: my $timezone = &Apache::lonlocal::gettimezone();
2882: $datatable .=
2883: &Apache::loncommon::select_timezone($item,$timezone,undef,
2884: $includeempty);
2885: } elsif ($item eq 'datelocale') {
2886: my $includeempty = 1;
2887: my $locale_obj = &Apache::lonlocal::getdatelocale();
2888: my $currdatelocale;
2889: if (ref($locale_obj)) {
2890: $currdatelocale = $locale_obj->id();
2891: }
2892: $datatable .=
2893: &Apache::loncommon::select_datelocale($item,$currdatelocale,
2894: undef,$includeempty);
2895: } else {
2896: if ($settings->{$item} eq '') {
1.49.2.7 raeburn 2897: $datatable .= '</td><td align="right">'.
1.3 raeburn 2898: &Apache::loncommon::select_language('languages_0','',1);
1.1 raeburn 2899: } else {
2900: my $num = 0;
1.3 raeburn 2901: my @languages = split(/\s*[,;:]\s*/,$settings->{$item});
1.49.2.7 raeburn 2902: $datatable .= '</td><td align="right"><br />'.
2903: &Apache::loncommon::start_data_table();
1.1 raeburn 2904: if (@languages > 0) {
1.3 raeburn 2905: my %langchoices = &get_lang_choices();
1.1 raeburn 2906: foreach my $lang (@languages) {
2907: my $showlang = $lang;
1.3 raeburn 2908: if (exists($langchoices{$lang})) {
2909: $showlang = $langchoices{$lang};
1.1 raeburn 2910: }
2911: $datatable .=
2912: &Apache::loncommon::start_data_table_row().
1.3 raeburn 2913: '<td align="left"><span class="LC_nobreak">'.
1.1 raeburn 2914: &mt('Language:').'<b> '.$showlang.
2915: '</b><input type="hidden" name="languages_'.$num.
2916: '" value="'.$lang.'" /></span><br />'.
2917: '<span class="LC_nobreak"><label><input type="checkbox" '.
2918: 'name="languages_delete" value="'.$num.'" />'.
2919: &mt('Delete').'</label></span></td>'.
1.3 raeburn 2920: &Apache::loncommon::end_data_table_row();
1.1 raeburn 2921: $num ++;
2922: }
2923: }
2924: $datatable .= &Apache::loncommon::start_data_table_row().
1.3 raeburn 2925: '<td align="left"><span class="LC_nobreak">'.
2926: &mt('Additional language:'). '</span><br />'.
2927: &Apache::loncommon::select_language('languages_'.$num,'',1).
1.1 raeburn 2928: '<input type="hidden" name="languages_total" value="'.$num.'" />'.
2929: '</td>'.&Apache::loncommon::end_data_table_row().
1.49.2.7 raeburn 2930: &Apache::loncommon::end_data_table().'<br />';
1.1 raeburn 2931: }
2932: }
2933: $datatable .= &item_table_row_end();
2934: }
2935: $$rowtotal += scalar(@{$ordered});
2936: return $datatable;
2937: }
2938:
1.3 raeburn 2939: sub get_lang_choices {
2940: my %langchoices;
2941: foreach my $id (&Apache::loncommon::languageids()) {
2942: my $code = &Apache::loncommon::supportedlanguagecode($id);
2943: if ($code) {
2944: $langchoices{$code} = &Apache::loncommon::plainlanguagedescription($id);
2945: }
2946: }
2947: return %langchoices;
2948: }
2949:
1.1 raeburn 2950: sub print_feedback {
1.3 raeburn 2951: my ($position,$cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
2952: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 2953: return;
2954: }
2955: my %items = (
1.3 raeburn 2956: 'question.email' => {
2957: text => '<b>'.&mt($itemtext->{'question.email'}).'</b>',
1.1 raeburn 2958: input => 'textbox',
2959: size => '50',
2960: },
2961:
1.3 raeburn 2962: 'comment.email' => {
2963: text => '<b>'.&mt($itemtext->{'comment.email'}).'</b>',
1.1 raeburn 2964: input => 'textbox',
2965: size => '50',
2966: },
2967:
1.3 raeburn 2968: 'policy.email' => {
2969: text => '<b>'.&mt($itemtext->{'policy.email'}).'</b>',
1.1 raeburn 2970: input => 'textbox',
2971: size => '50',
2972: },
2973: );
2974: my $datatable;
2975: my $count = 0;
2976: my ($cnum) = &get_course();
2977: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
2978: my @sections = sort( { $a <=> $b } keys(%sections));
2979: my %lt = &Apache::lonlocal::texthash (
1.21 raeburn 2980: currone => 'Current recipient:',
2981: currmult => 'Current recipients:',
2982: add => 'Additional recipient:',
2983: del => 'Delete?',
2984: sec => 'Sections:',
1.1 raeburn 2985: );
2986:
2987: foreach my $item (@{$ordered}) {
2988: $count ++;
1.20 faziophi 2989: if ($position eq 'top') {
2990: $datatable .= &item_table_row_start($items{$item}{text},$count);
2991: } else {
1.49.2.7 raeburn 2992: $datatable .= &item_table_row_start($items{$item}{text}."<br/>(Custom text)",$count, "advanced",2);
1.20 faziophi 2993: }
1.1 raeburn 2994: if ($position eq 'top') {
2995: my $includeempty = 0;
1.49.2.7 raeburn 2996: $datatable .= '</td><td align="right">'.
2997: &user_table($cdom,$item,\@sections,
1.3 raeburn 2998: $settings->{$item},\%lt);
1.1 raeburn 2999: } else {
1.3 raeburn 3000: $datatable .= &Apache::lonhtmlcommon::textbox($item.'.text',
3001: $settings->{$item.'.text'},$items{$item}{size});
1.1 raeburn 3002: }
3003: $datatable .= &item_table_row_end();
3004: }
3005: $$rowtotal += scalar(@{$ordered});
3006: return $datatable;
3007: }
3008:
3009: sub user_table {
3010: my ($cdom,$item,$sections,$currvalue,$lt) = @_;
3011: my $output;
3012: if ($currvalue eq '') {
3013: $output .= &select_recipient($item,'0',$cdom,$sections);
3014: } else {
3015: my $num = 0;
3016: my @curr = split(/,/,$currvalue);
1.49.2.7 raeburn 3017: $output .= '<table class="LC_data_table">';
1.1 raeburn 3018: my ($currusers);
3019: foreach my $val (@curr) {
3020: next if ($val eq '');
3021: my ($uname,$udom,$seclist) = ($val =~ /^($match_username):($match_domain)(\(?[^\)]*\)?)$/);
3022: my @selsec;
3023: if ($seclist) {
3024: $seclist =~ s/(^\(|\)$)//g;
3025: @selsec = split(/\s*;\s*/,$seclist);
3026: }
3027: $currusers .= '<tr>'.
3028: '<td valign="top"><span class="LC_nobreak">'.
3029: '<label><input type="checkbox" '.
3030: 'name="'.$item.'_delete" value="'.$num.'" />'.
3031: $lt->{'del'}.'</label>'.
3032: '<input type="hidden" name="'.$item.'_user_'.
1.3 raeburn 3033: $num.'" value="'.$uname.':'.$udom.'" />'.(' 'x2).
1.1 raeburn 3034: &Apache::loncommon::aboutmewrapper(
3035: &Apache::loncommon::plainname($uname,$udom,'firstname'),
3036: $uname,$udom,'aboutuser');
3037: if (ref($sections) eq 'ARRAY') {
3038: if (@{$sections}) {
3039: $currusers.= (' 'x3).$lt->{'sec'}.' '.
3040: &select_sections($item,$num,$sections,
3041: \@selsec);
3042: }
3043: }
3044: $currusers .= '</span></td></tr>';
3045: $num ++;
3046: }
3047: if ($num) {
1.10 raeburn 3048: $output .= '<tr>'.
1.1 raeburn 3049: '<td align="left"><i>';
1.20 faziophi 3050: if ($num == 1) {
1.1 raeburn 3051: $output .= $lt->{'currone'};
3052: } else {
1.21 raeburn 3053: $output .= $lt->{'currmult'};
1.1 raeburn 3054: }
3055: $output .= '</i><br />'.
3056: '<table>'.$currusers.'</table></td>'.
1.10 raeburn 3057: '</tr>';
1.1 raeburn 3058: }
1.10 raeburn 3059: $output .= '<tr>'.
1.1 raeburn 3060: '<td align="left"><span class="LC_nobreak"><i>'.
3061: $lt->{'add'}.'</i></span><br />'.
3062: &select_recipient($item,$num,$cdom,$sections).
3063: '<input type="hidden" name="'.$item.'_total" value="'.$num.'" />'.
1.10 raeburn 3064: '</td></tr></table>';
1.1 raeburn 3065: }
3066: return $output;
3067: }
3068:
3069: sub select_recipient {
3070: my ($item,$num,$cdom,$sections,$selected,$includeempty) = @_;
3071: my $domform = &Apache::loncommon::select_dom_form($cdom,$item.'_udom_'.$num,$includeempty);
3072: my $selectlink =
3073: &Apache::loncommon::selectstudent_link('display',$item.'_uname_'.$num,
3074: $item.'_udom_'.$num,1);
3075: my $output =
1.10 raeburn 3076: '<table><tr><td align="center">'.&mt('Username').'<br />'.
1.1 raeburn 3077: '<input type="text" name="'.$item.'_uname_'.$num.'" value="" /></td>'.
3078: '<td align="center">'.&mt('Domain').'<br />'.$domform.'</td>';
3079: if (ref($sections) eq 'ARRAY') {
3080: if (@{$sections}) {
3081: $output .= '<td align="center">'.&mt('Sections').'<br />'.
3082: &select_sections($item,$num,$sections,$selected).'</td>';
3083: }
3084: }
3085: $output .= '<td valign="top">'.
3086: $selectlink.'</td></tr></table>';
3087: return $output;
3088: }
3089:
3090: sub select_sections {
3091: my ($item,$num,$sections,$selected) = @_;
3092: my ($output,@currsecs,$allsec);
3093: if (ref($selected) eq 'ARRAY') {
3094: @currsecs = @{$selected};
3095: }
3096: if (!@currsecs) {
3097: $allsec = ' selected="selected"';
3098: }
3099: if (ref($sections) eq 'ARRAY') {
3100: if (@{$sections}) {
3101: my $mult;
3102: if (@{$sections} > 1) {
3103: $mult = ' multiple="multiple"';
3104: if (@{$sections} > 3) {
3105: $mult .= ' size="4"';
3106: }
3107: }
3108: $output = '<select name="'.$item.'_sections_'.$num.'"'.$mult.'>'.
3109: ' <option value=""'.$allsec.'>'.&mt('All').'</option>';
3110: foreach my $sec (@{$sections}) {
3111: my $is_sel;
3112: if ((@currsecs) && (grep(/^\Q$sec\E$/,@currsecs))) {
3113: $is_sel = 'selected="selected"';
3114: }
3115: $output .= '<option value="'.$sec.'"'.$is_sel.'>'.$sec.'</option>';
3116: }
3117: $output .= '</select>';
3118: }
3119: }
3120: return $output;
3121: }
3122:
3123: sub print_discussion {
1.3 raeburn 3124: my ($cdom,$settings,$ordered,$itemtext,$rowtotal) = @_;
3125: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 3126: return;
3127: }
3128: my %items = (
3129: 'plc.roles.denied' => {
1.10 raeburn 3130: text => '<span class="LC_nobreak"><b>'.&mt($itemtext->{'plc.roles.denied'}).'</b>'.
3131: &Apache::loncommon::help_open_topic("Course_Disable_Discussion").'</span><br />'.
1.5 raeburn 3132: &mt('(role-based)'),
1.1 raeburn 3133: input => 'checkbox',
3134: },
3135:
3136: 'plc.users.denied' => {
1.3 raeburn 3137: text => '<b>'.&mt($itemtext->{'plc.users.denied'}).'</b><br />'.
3138: &mt('(specific user(s))'),
1.1 raeburn 3139: input => 'checkbox',
3140: },
3141:
3142: 'pch.roles.denied' => {
1.10 raeburn 3143: text => '<span class="LC_nobreak"><b>'.&mt($itemtext->{'pch.roles.denied'}).'</b>'.
3144: &Apache::loncommon::help_open_topic("Course_Disable_Discussion").'</span><br />'.
1.3 raeburn 3145: &mt('(role-based)'),
1.1 raeburn 3146: input => 'checkbox',
3147: },
3148:
3149: 'pch.users.denied' => {
1.3 raeburn 3150: text => '<b>'.&mt($itemtext->{'pch.users.denied'}).'</b><br />'.
3151: &mt('(specific user(s))'),
1.1 raeburn 3152: input => 'checkbox',
3153: },
3154: 'allow_limited_html_in_feedback' => {
1.3 raeburn 3155: text => '<b>'.&mt($itemtext->{'allow_limited_html_in_feedback'}).'</b>',
1.1 raeburn 3156: input => 'radio',
3157: },
3158:
3159: 'allow_discussion_post_editing' => {
1.3 raeburn 3160: text => '<b>'.&mt($itemtext->{'allow_discussion_post_editing'}).'</b>',
1.1 raeburn 3161: input => 'checkbox',
3162: },
1.49.2.3 raeburn 3163: 'discussion_post_fonts' => {
3164: text => '<b>'.&mt($itemtext->{'discussion_post_fonts'}).'</b>',
3165: input => 'textbox',
3166: size => '20',
3167: },
1.1 raeburn 3168: );
3169: my $datatable;
3170: my $count;
3171: my ($cnum) = &get_course();
3172: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
3173: my @sections = sort( { $a <=> $b } keys(%sections));
3174: my %lt = &Apache::lonlocal::texthash (
1.21 raeburn 3175: currone => 'Disallowed:',
3176: currmult => 'Disallowed:',
3177: add => 'Disallow more:',
3178: del => 'Delete?',
3179: sec => 'Sections:',
1.1 raeburn 3180: );
3181: foreach my $item (@{$ordered}) {
3182: $count ++;
1.49.2.7 raeburn 3183: my $colspan;
3184: if ($item eq 'allow_limited_html_in_feedback') {
3185: $colspan = 2;
3186: }
3187: $datatable .= &item_table_row_start($items{$item}{text},$count,undef,$colspan);
1.1 raeburn 3188: if ($item eq 'plc.roles.denied') {
1.49.2.7 raeburn 3189: $datatable .= '</td><td align="right">'.
3190: '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).
1.1 raeburn 3191: '</table>';
3192: } elsif ($item eq 'plc.users.denied') {
1.49.2.7 raeburn 3193: $datatable .= '</td><td align="right">'.
3194: &user_table($cdom,$item,undef,
1.1 raeburn 3195: $settings->{$item},\%lt);
3196: } elsif ($item eq 'pch.roles.denied') {
1.49.2.7 raeburn 3197: $datatable .= '</td><td align="right">'.
3198: '<table>'.&role_checkboxes($cdom,$cnum,$item,$settings).
1.1 raeburn 3199: '</table>';
3200: } elsif ($item eq 'pch.users.denied') {
1.49.2.7 raeburn 3201: $datatable .= '</td><td align="right">'.
3202: &user_table($cdom,$item,undef,
1.1 raeburn 3203: $settings->{$item},\%lt);
3204: } elsif ($item eq 'allow_limited_html_in_feedback') {
3205: $datatable .= &yesno_radio($item,$settings);
3206: } elsif ($item eq 'allow_discussion_post_editing') {
1.49.2.7 raeburn 3207: $datatable .= '</td><td align="right"><br />'.
3208: &Apache::loncommon::start_data_table().
1.1 raeburn 3209: &Apache::loncommon::start_data_table_row().
3210: '<th align="left">'.&mt('Role').'</th><th>'.
3211: &mt('Sections').'</th>'.
3212: &Apache::loncommon::end_data_table_row().
3213: &role_checkboxes($cdom,$cnum,$item,$settings,1).
1.49.2.7 raeburn 3214: &Apache::loncommon::end_data_table().'<br />';
1.49.2.3 raeburn 3215: } elsif ($item eq 'discussion_post_fonts') {
1.49.2.7 raeburn 3216: $datatable .= '</td><td align="right"><br />'.
3217: &Apache::loncommon::start_data_table().
1.49.2.3 raeburn 3218: &Apache::loncommon::start_data_table_row().
3219: '<th align="center">'.&mt('Sum of likes/dislikes').'</th>'.
3220: '<th align="center">'.&mt('font-size').'</th>'.
3221: '<th align="center">'.&mt('font-weight').'</th>'.
3222: '<th align="center">'.&mt('font-style').'</th>'.
3223: '<th align="center">'.&mt('Other css').'</th>'.
3224: &Apache::loncommon::end_data_table_row().
3225: &set_discussion_fonts($cdom,$cnum,$item,$settings).
1.49.2.7 raeburn 3226: &Apache::loncommon::end_data_table().'<br />';
1.1 raeburn 3227: }
3228: $datatable .= &item_table_row_end();
3229: }
3230: $$rowtotal += scalar(@{$ordered});
3231: return $datatable;
3232: }
3233:
3234: sub role_checkboxes {
1.9 raeburn 3235: my ($cdom,$cnum,$item,$settings,$showsections,$crstype) = @_;
3236: my @roles = ('st','ad','ta','ep','in');
3237: if ($crstype eq 'Community') {
3238: push(@roles,'co');
3239: } else {
3240: push(@roles,'cc');
3241: }
1.1 raeburn 3242: my $output;
3243: my (@current,@curr_roles,%currsec,@sections);
3244: if ($showsections) {
3245: my %sections = &Apache::loncommon::get_sections($cdom,$cnum);
3246: @sections = sort( { $a <=> $b } keys(%sections));
3247: }
3248: if (ref($settings) eq 'HASH') {
3249: if ($settings->{$item}) {
3250: @current = split(',',$settings->{$item});
3251: if ($showsections) {
3252: foreach my $role (@current) {
3253: if ($role =~ /:/) {
3254: my ($trole,$sec) = split(':',$role);
3255: push(@curr_roles,$trole);
3256: if (ref($currsec{$trole}) eq 'ARRAY') {
3257: if (!grep(/^\Q$sec\E/,@{$currsec{$trole}})) {
3258: push(@{$currsec{$trole}},$sec);
3259: }
1.3 raeburn 3260: } else {
3261: $currsec{$trole} = [$sec];
1.1 raeburn 3262: }
3263: } else {
3264: push(@curr_roles,$role);
3265: }
3266: }
3267: @current = @curr_roles;
3268: }
3269: }
3270: }
3271: my $numinrow = 3;
3272: my $count = 0;
3273: foreach my $role (@roles) {
3274: my $checked = '';
3275: if (grep(/^\Q$role\E$/,@current)) {
3276: $checked = ' checked="checked" ';
3277: }
1.9 raeburn 3278: my $plrole=&Apache::lonnet::plaintext($role,$crstype);
1.1 raeburn 3279: if ($showsections) {
3280: $output .= &Apache::loncommon::start_data_table_row();
3281: } else {
3282: my $rem = $count%($numinrow);
3283: if ($rem == 0) {
3284: if ($count > 0) {
3285: $output .= '</tr>';
3286: }
3287: $output .= '<tr>';
3288: }
3289: }
1.30 raeburn 3290: $output .= '<td align="left"><span class="LC_nobreak"><label><input type="checkbox" name="'.
1.1 raeburn 3291: $item.'" value="'.$role.'"'.$checked.'/> '.
3292: $plrole.'</label></span></td>';
3293: if ($showsections) {
3294: $output .= '<td align="left">'.
3295: &select_sections($item,$role,\@sections,$currsec{$role}).
3296: '</td></tr>';
3297: }
3298: $count ++;
3299: }
3300: my %adv_roles =
3301: &Apache::lonnet::get_course_adv_roles($env{'request.course.id'},1);
3302: my $total = @roles;
3303: foreach my $role (sort(keys(%adv_roles))) {
3304: if ($role =~ m{^cr/($match_domain)/($match_name)/\w$}) {
3305: my $rolename = $3;
3306: my $value = 'cr_'.$1.'_'.$2.'_'.$rolename;
3307: my $checked = '';
3308: if (grep(/^\Q$value\E$/,@current)) {
3309: $checked = ' checked="checked" ';
3310: }
3311: if ($showsections) {
3312: $output .= &Apache::loncommon::start_data_table_row();
3313: } else {
3314: my $rem = $count%($numinrow);
3315: if ($rem == 0) {
3316: if ($count > 0) {
3317: $output .= '</tr>';
3318: }
3319: $output .= '<tr>';
3320: }
3321: }
1.30 raeburn 3322: $output .= '<td><span class="LC_nobreak"><label><input type="checkbox" name="'.
1.1 raeburn 3323: $item.'" value="'.$value.'"'.$checked.' /> '.$rolename.
3324: '</label></span></td>';
3325: if ($showsections) {
3326: $output .= '<td>'.
3327: &select_sections($item,$role,\@sections,$currsec{$role}).
3328: '</td>'.&Apache::loncommon::end_data_table_row();
3329: }
3330: $total ++;
3331: $count ++;
3332: }
3333: }
3334: if (!$showsections) {
3335: my $rem = $total%($numinrow);
3336: my $colsleft = $numinrow - $rem;
3337: if ($colsleft > 1 ) {
3338: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
3339: ' </td>';
3340: } elsif ($colsleft == 1) {
3341: $output .= '<td class="LC_left_item"> </td>';
3342: }
3343: $output .= '</tr>';
3344: }
3345: return $output;
3346: }
3347:
1.49.2.3 raeburn 3348: sub set_discussion_fonts {
3349: my ($cdom,$cnum,$item,$settings) = @_;
3350: my ($classorder,$classtitles) = &discussion_vote_classes();
3351: my ($styleorder,$styleitems) = &discussion_vote_styles();
3352: my $output;
3353: if (ref($classorder) eq 'ARRAY') {
3354: foreach my $cat (@{$classorder}) {
3355: my %curr = ();
3356: ($curr{'size'},$curr{'weight'},$curr{'style'},$curr{'other'}) =
3357: split(/,/,$settings->{'discussion_post_fonts_'.$cat});
3358: $output .= &Apache::loncommon::start_data_table_row().
3359: '<td>'.$classtitles->{$cat}.'</td>';
3360: if (ref($styleorder) eq 'ARRAY') {
3361: foreach my $item (@{$styleorder}) {
3362: $output .= '<td><span class="LC_nobreak">';
3363: my $selitem = $item;
3364: if ($item eq 'size') {
3365: my ($currsize,$currunit);
3366: if ($curr{'size'} =~ /^(\d+)(px|%)$/) {
3367: ($currsize,$currunit) = ($1,$2);
3368: $curr{'size'} = $currunit;
3369: }
3370: $output .= '<input type="textbox" name="discussion_post_fonts_'.$cat.'_'.$item.'" value="'.$currsize.'" size="5">'.
3371: ' ';
3372: $selitem = 'unit';
3373: }
3374: if ((ref($styleitems) eq 'HASH') && (ref($styleitems->{$item}) eq 'ARRAY')) {
3375: $output .= '<select name="discussion_post_fonts_'.$cat.'_'.$selitem.'">';
3376: foreach my $val (@{$styleitems->{$item}}) {
3377: my $sel;
3378: if ($val eq $curr{$item}) {
3379: $sel = ' selected="selected"';
3380: }
3381: $output .= '<option value="'.$val.'"'.$sel.'>'.$val.'</option>';
3382: }
3383: }
3384: }
3385: }
3386: $output .= '</span></td><td><input type="textbox" size="10" name="discussion_post_fonts_'.$cat.'_other" value="'.$curr{'other'}.'" /></td>';
3387: }
3388: $output .= &Apache::loncommon::end_data_table_row();
3389: }
3390: return $output;
3391: }
3392:
3393: sub discussion_vote_classes {
3394: my $classorder = ['twoplus','oneplus','zero','oneminus','twominus'];
3395: my %classtitles = &Apache::lonlocal::texthash(
3396: 'twoplus' => 'Two sigma above mean',
3397: 'oneplus' => 'One sigma above mean',
3398: 'zero' => 'Within one sigma of mean',
3399: 'oneminus' => 'One sigma below mean',
3400: 'twominus' => 'Two sigma below mean',
3401: );
3402: return ($classorder,\%classtitles);
3403: }
3404:
3405: sub discussion_vote_styles {
3406: my $styleorder = ['size','weight','style'];
3407: my $styleitems = {
3408: size => ['','px','%','xx-small','x-small','small','medium','large',
3409: 'x-large','xx-large','smaller','larger'],
3410: weight => ['','normal','bold','bolder','lighter','100','200','300','400',
3411: '500','600','700','800','900'],
3412: style => ['','normal','italic','oblique'],
3413: };
3414: return ($styleorder,$styleitems);
3415: }
3416:
1.1 raeburn 3417: sub print_classlists {
1.9 raeburn 3418: my ($position,$cdom,$settings,$itemtext,$rowtotal,$crstype) = @_;
1.1 raeburn 3419: my @ordered;
3420: if ($position eq 'top') {
3421: @ordered = ('default_enrollment_start_date',
3422: 'default_enrollment_end_date');
1.49.2.6 raeburn 3423: if ($crstype eq 'Course') {
3424: push(@ordered,'defaultcredits');
3425: }
1.1 raeburn 3426: } elsif ($position eq 'middle') {
1.49.2.7 raeburn 3427: @ordered = ('nothideprivileged','checkforpriv');
1.1 raeburn 3428: } else {
3429: @ordered = ('student_classlist_view',
1.26 raeburn 3430: 'student_classlist_opt_in',
3431: 'student_classlist_portfiles');
1.1 raeburn 3432: }
1.9 raeburn 3433: my %lt;
3434:
3435: if ($crstype eq 'Community') {
3436: %lt = &Apache::lonlocal::texthash (
3437: disabled => 'No viewable membership list',
3438: section => "Membership of viewer's section",
3439: all => 'List of all members',
3440: );
3441: } else {
3442: %lt = &Apache::lonlocal::texthash (
3443: disabled => 'No viewable classlist',
3444: section => "Classlist of viewer's section",
3445: all => 'Classlist of all students',
3446: );
3447: }
3448:
1.1 raeburn 3449: my %items = (
3450: 'default_enrollment_start_date' => {
1.3 raeburn 3451: text => '<b>'.&mt($itemtext->{'default_enrollment_start_date'}).'</b>',
1.1 raeburn 3452: input => 'dates',
3453: },
3454: 'default_enrollment_end_date' => {
1.3 raeburn 3455: text => '<b>'.&mt($itemtext->{'default_enrollment_end_date'}).'</b>',
1.1 raeburn 3456: input => 'dates',
3457: },
1.49.2.7 raeburn 3458: 'defaultcredits' => {
3459: text => '<b>'.&mt($itemtext->{'defaultcredits'}).'</b>',
3460: },
1.1 raeburn 3461:
3462: 'nothideprivileged' => {
1.3 raeburn 3463: text => '<b>'.&mt($itemtext->{'nothideprivileged'}).'</b>',
1.1 raeburn 3464: input => 'checkbox',
3465: },
3466:
1.49.2.7 raeburn 3467: 'checkforpriv' => {
3468: text => '<b>'.&mt($itemtext->{'checkforpriv'}).'</b>',
3469: input => 'selectbox',
3470: },
3471:
1.1 raeburn 3472: 'student_classlist_view' => {
1.3 raeburn 3473: text => '<b>'.&mt($itemtext->{'student_classlist_view'}).'</b>',
1.1 raeburn 3474: input => 'selectbox',
1.9 raeburn 3475: options => \%lt,
1.1 raeburn 3476: order => ['disabled','all','section'],
3477: },
1.26 raeburn 3478: 'student_classlist_opt_in' => {
3479: text => '<b>'.&mt($itemtext->{'student_classlist_opt_in'}).'</b>',
1.1 raeburn 3480: input => 'radio',
3481: },
3482:
3483: 'student_classlist_portfiles' => {
1.3 raeburn 3484: text => '<b>'.&mt($itemtext->{'student_classlist_portfiles'}).'</b>',
1.1 raeburn 3485: input => 'radio',
3486: },
3487: );
3488: unless (($settings->{'student_classlist_view'} eq 'all') ||
3489: ($settings->{'student_classlist_view'} eq 'section')) {
3490: $settings->{'student_classlist_view'} = 'disabled';
3491: }
1.49.2.7 raeburn 3492: return &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype,'classlists');
1.1 raeburn 3493: }
3494:
3495: sub print_appearance {
1.9 raeburn 3496: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 3497: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 3498: return;
3499: }
1.9 raeburn 3500: my $mathdef;
3501: if ($crstype eq 'Community') {
3502: $mathdef = &mt("None specified - use member's choice");
3503: } else {
3504: $mathdef = &mt("None specified - use student's choice");
3505: }
1.1 raeburn 3506: my %items = (
3507: 'default_xml_style' => {
1.3 raeburn 3508: text => '<b>'.&mt($itemtext->{'default_xml_style'}).'</b> '.
1.1 raeburn 3509: '<a href="javascript:openbrowser'.
3510: "('display','default_xml_style'".
3511: ",'sty')".'">'.&mt('Select Style File').'</a>',
3512: input => 'textbox',
3513: size => 35,
3514: },
3515:
3516: 'pageseparators' => {
1.3 raeburn 3517: text => '<b>'.&mt($itemtext->{'pageseparators'}).'</b>',
1.1 raeburn 3518: input => 'radio',
3519: },
3520: 'disable_receipt_display' => {
1.3 raeburn 3521: text => '<b>'.&mt($itemtext->{'disable_receipt_display'}).'</b>',
1.1 raeburn 3522: input => 'radio',
3523: },
3524: 'texengine' => {
1.3 raeburn 3525: text => '<b>'.&mt($itemtext->{'texengine'}).'</b>',
1.1 raeburn 3526: input => 'selectbox',
3527: options => {
1.49.2.11! raeburn 3528: MathJax => 'MathJax',
1.1 raeburn 3529: jsMath => 'jsMath',
3530: mimetex => &mt('Convert to Images'),
3531: tth => &mt('TeX to HTML'),
3532: },
1.49.2.11! raeburn 3533: order => ['MathJax','jsMath','mimetex','tth'],
1.9 raeburn 3534: nullval => $mathdef,
1.1 raeburn 3535: },
3536: 'tthoptions' => {
1.3 raeburn 3537: text => '<b>'.&mt($itemtext->{'tthoptions'}).'</b>',
1.1 raeburn 3538: input => 'textbox',
3539: size => 40,
3540: },
3541: );
1.49.2.7 raeburn 3542: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'appearance');
1.1 raeburn 3543: }
3544:
3545: sub print_grading {
1.9 raeburn 3546: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 3547: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 3548: return;
3549: }
3550: my %items = (
3551: 'grading' => {
1.3 raeburn 3552: text => '<b>'.&mt($itemtext->{'grading'}).'</b>'.
1.1 raeburn 3553: &Apache::loncommon::help_open_topic('GradingOptions'),
3554: input => 'selectbox',
3555: options => {
3556: standard => &mt('Standard: shows points'),
1.11 www 3557: external => &mt('External: shows number of completed parts and totals'),
3558: externalnototals => &mt('External: shows only number of completed parts'),
1.1 raeburn 3559: spreadsheet => &mt('Spreadsheet: (with link to detailed scores)'),
3560: },
1.49.2.2 raeburn 3561: order => ['standard','external','externalnototals','spreadsheet'],
1.1 raeburn 3562: },
3563: 'rndseed' => {
1.3 raeburn 3564: text => '<b>'.&mt($itemtext->{'rndseed'}).'</b>'.
1.17 faziophi 3565: '<span class="LC_warning">'.'<br />'.
1.1 raeburn 3566: &mt('Modifying this will make problems have different numbers and answers!').
3567: '</span>',
3568: input => 'selectbox',
3569: options => {
3570: '32bit' => '32bit',
3571: '64bit' => '64bit',
3572: '64bit2' => '64bit2',
3573: '64bit3' => '64bit3',
3574: '64bit4' => '64bit4',
3575: '64bit5' => '64bit5',
3576: },
3577: order => ['32bit','64bit','64bit2','64bit3','64bit4','64bit5'],
1.41 www 3578: advanced => 1
1.1 raeburn 3579: },
3580: 'receiptalg' => {
1.3 raeburn 3581: text => '<b>'.&mt($itemtext->{'receiptalg'}).'</b><br />'.
1.5 raeburn 3582: &mt('This controls how receipt numbers are generated'),
1.1 raeburn 3583: input => 'selectbox',
3584: options => {
3585: receipt => 'receipt',
3586: receipt2 => 'receipt2',
3587: receipt3 => 'receipt3',
3588: },
3589: order => ['receipt','receipt2','receipt3'],
1.41 www 3590: advanced => 1
1.1 raeburn 3591: },
3592: 'disablesigfigs' => {
1.3 raeburn 3593: text => '<b>'.&mt($itemtext->{'disablesigfigs'}).'</b>',
1.1 raeburn 3594: input => 'radio',
3595: },
3596: );
1.49.2.7 raeburn 3597: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'grading');
1.1 raeburn 3598: }
3599:
3600: sub print_printouts {
1.9 raeburn 3601: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 3602: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 3603: return;
3604: }
3605: my %items = (
3606: problem_stream_switch => {
1.3 raeburn 3607: text => '<b>'.&mt($itemtext->{'problem_stream_switch'}).'</b>',
1.1 raeburn 3608: input => 'radio',
3609: },
3610: suppress_tries => {
1.3 raeburn 3611: text => '<b>'.&mt($itemtext->{'suppress_tries'}).'</b>',
1.1 raeburn 3612: input => 'radio',
3613: },
3614: default_paper_size => {
1.3 raeburn 3615: text => '<b>'.&mt($itemtext->{'default_paper_size'}).'</b>',
1.1 raeburn 3616: input => 'selectbox',
3617: options => {
3618: Letter => &mt('Letter').' [8 1/2x11 in]',
3619: Legal => &mt('Legal').' [8 1/2x14 in]',
3620: Tabloid => &mt('Tabloid').' [11x17 in]',
3621: Executive => &mt('Executive').' [7 1/2x10 in]',
3622: A2 => &mt('A2').' [420x594 mm]',
3623: A3 => &mt('A3').' [297x420 mm]',
3624: A4 => &mt('A4').' [210x297 mm]',
3625: A5 => &mt('A5').' [148x210 mm]',
3626: A6 => &mt('A6').' [105x148 mm]',
3627: },
3628: order => ['Letter','Legal','Tabloid','Executive','A2','A3','A4','A5','A6'],
1.49.2.5 raeburn 3629: nullval => &mt('None specified'),
1.1 raeburn 3630: },
3631: print_header_format => {
1.3 raeburn 3632: text => '<b>'.&mt($itemtext->{'print_header_format'}).'</b>',
1.1 raeburn 3633: input => 'checkbox',
3634: },
3635: disableexampointprint => {
1.3 raeburn 3636: text => '<b>'.&mt($itemtext->{'disableexampointprint'}).'</b>',
1.1 raeburn 3637: input => 'radio',
3638: },
1.14 raeburn 3639: canuse_pdfforms => {
3640: text => '<b>'.&mt($itemtext->{'canuse_pdfforms'}).'</b>',
3641: input => 'selectbox',
3642: options => {
3643: 1 => &mt('Yes'),
3644: 0 => &mt('No'),
3645: },
3646: order => ['1','0'],
1.49.2.5 raeburn 3647: nullval => &mt('None specified - use domain default'),
1.14 raeburn 3648: }
1.1 raeburn 3649: );
1.49.2.7 raeburn 3650: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'printouts');
1.1 raeburn 3651: }
3652:
3653: sub print_spreadsheet {
1.9 raeburn 3654: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 3655: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 3656: return;
3657: }
3658: my $SelectSpreadsheetFile=&mt('Select Spreadsheet File');
3659: my %items = (
3660: spreadsheet_default_classcalc => {
1.3 raeburn 3661: text => '<b>'.&mt($itemtext->{'spreadsheet_default_classcalc'}).'</b> '.
1.1 raeburn 3662: '<span class="LC_nobreak"><a href="javascript:openbrowser'.
3663: "('display','spreadsheet_default_classcalc'".
3664: ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
3665: input => 'textbox',
3666: },
3667: spreadsheet_default_studentcalc => {
1.3 raeburn 3668: text => '<b>'.&mt($itemtext->{'spreadsheet_default_studentcalc'}).'</b> '.
1.1 raeburn 3669: '<span class="LC_nobreak"><a href="javascript:openbrowser'.
3670: "('display','spreadsheet_default_calc'".
3671: ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
3672: input => 'textbox',
3673: },
3674: spreadsheet_default_assesscalc => {
1.3 raeburn 3675: text => '<b>'.&mt($itemtext->{'spreadsheet_default_assesscalc'}).'</b> '.
1.1 raeburn 3676: '<span class="LC_nobreak"><a href="javascript:openbrowser'.
3677: "('display','spreadsheet_default_assesscalc'".
3678: ",'spreadsheet')".'">'.$SelectSpreadsheetFile.'</a></span>',
3679: input => 'textbox',
3680: },
3681: hideemptyrows => {
1.3 raeburn 3682: text => '<b>'.&mt($itemtext->{'hideemptyrows'}).'</b>',
1.1 raeburn 3683: input => 'radio',
3684: },
3685: );
1.49.2.7 raeburn 3686: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'spreadsheet');
1.9 raeburn 3687: }
1.1 raeburn 3688:
3689: sub print_bridgetasks {
1.9 raeburn 3690: my ($cdom,$settings,$ordered,$itemtext,$rowtotal,$crstype) = @_;
1.3 raeburn 3691: unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
1.1 raeburn 3692: return;
3693: }
1.9 raeburn 3694: my ($stumsg,$msgnote);
3695: if ($crstype eq 'Community') {
3696: $stumsg = &mt('Send message to member');
3697: $msgnote = &mt('Message to member and add to user notes');
3698: } else {
3699: $stumsg = &mt('Send message to student');
3700: $msgnote = &mt('Message to student and add to user notes');
3701: }
1.1 raeburn 3702: my %items = (
3703: task_messages => {
1.3 raeburn 3704: text => '<b>'.&mt($itemtext->{'task_messages'}).'</b>',
1.1 raeburn 3705: input => 'selectbox',
3706: options => {
1.9 raeburn 3707: only_student => $stumsg,
3708: student_and_user_notes_screen => $msgnote,
1.1 raeburn 3709: },
3710: order => ['only_student','student_and_user_notes_screen'],
3711: nullval => &mt('No message or record in user notes'),
3712: },
3713: task_grading => {
1.3 raeburn 3714: text => '<b>'.&mt($itemtext->{'task_grading'}).'</b>',
1.1 raeburn 3715: input => 'selectbox',
3716: options => {
3717: any => &mt('Grade BTs in any section'),
3718: section => &mt('Grade BTs only in own section')
3719: },
3720: order => ['any','section'],
3721: },
3722: suppress_embed_prompt => {
1.3 raeburn 3723: text => '<b>'.&mt($itemtext->{'suppress_embed_prompt'}).'</b><span class="LC_nobreak">'.
3724: ' '.&mt('(applies when current role is student)').'</span>',
1.1 raeburn 3725: input => 'radio',
3726: },
3727: );
1.49.2.7 raeburn 3728: return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'bridgetasks');
1.1 raeburn 3729: }
3730:
3731: sub print_other {
1.9 raeburn 3732: my ($cdom,$settings,$allitems,$rowtotal,$crstype) = @_;
1.1 raeburn 3733: unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {
3734: return;
3735: }
1.3 raeburn 3736: my @ordered = &get_other_items($cdom,$settings,$allitems);
3737: my %items;
3738: foreach my $parameter (@ordered) {
3739: $items{$parameter} = {
3740: text => '<b>'.$parameter.'</b>',
3741: input => 'textbox',
3742: size => '15',
3743: },
3744: }
3745: push (@ordered,'newp_value');
3746: $items{'newp_value'} = {
3747: text => '<b>'.&mt('Create New Environment Variable').'</b><br />'.
3748: '<input type="textbox" name="newp_name"'.
3749: ' value="" size="30" />',
3750: input => 'textbox',
3751: size => '30',
3752: };
1.49.2.7 raeburn 3753: my $output = &make_item_rows($cdom,\%items,\@ordered,$settings,$rowtotal,$crstype,'other');
1.3 raeburn 3754: }
3755:
3756: sub get_other_items {
3757: my ($cdom,$settings,$allitems) = @_;
3758: unless ((ref($settings) eq 'HASH') && (ref($allitems) eq 'ARRAY')) {
3759: return;
3760: }
1.1 raeburn 3761: my @ordered;
3762: if (ref($settings) eq 'HASH') {
3763: foreach my $parameter (sort(keys(%{$settings}))) {
3764: next if (grep/^\Q$parameter\E$/,@{$allitems});
1.3 raeburn 3765: next if (($parameter eq 'course.helper.not.run') &&
3766: (!exists($env{'user.role.dc./'.$env{'request.role.domain'}.'/'})));
1.1 raeburn 3767: unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./) ||
3768: ($parameter =~ m/^selfenroll_/) || ($parameter =~ /_selfenroll$/)
3769: || ($parameter eq 'type') ||
1.49.2.3 raeburn 3770: ($parameter =~ m/^(cc|co|in|ta|ep|ad|st)\.plaintext$/)
1.49.2.11! raeburn 3771: || ($parameter =~ m/^discussion_post_fonts/) ||
! 3772: ($parameter =~ m{^(minimal|updated|uploaded|external)syllabus$}) ||
! 3773: ($parameter eq 'clonedfrom')) {
1.1 raeburn 3774: push(@ordered,$parameter);
3775: }
3776: }
3777: }
1.3 raeburn 3778: return @ordered;
1.1 raeburn 3779: }
3780:
3781: sub item_table_row_start {
1.49.2.7 raeburn 3782: my ($text,$count,$add_class,$colspan) = @_;
1.1 raeburn 3783: my $output;
1.49.2.7 raeburn 3784: my $css_class = ($count % 2) ? 'LC_odd_row' : 'LC_even_row';
3785: $css_class = (join(' ',$css_class,$add_class)) unless ($add_class eq '');
3786: $output .= '<tr class="'.$css_class.'">'."\n".
3787: '<td class="LC_left_item">'.$text.
3788: '</td>';
3789: if ($colspan) {
3790: $output .= '<td class="LC_right_item" colspan="'.$colspan.'">';
3791: } else {
3792: $output .= '<td class="LC_right_item">';
3793: }
1.1 raeburn 3794: return $output;
3795: }
3796:
3797: sub item_table_row_end {
3798: return '</td></tr>';
3799: }
3800:
3801: sub yesno_radio {
3802: my ($item,$settings) = @_;
3803: my $itemon = ' ';
3804: my $itemoff = ' checked="checked" ';
3805: if (ref($settings) eq 'HASH') {
3806: if ($settings->{$item} eq 'yes') {
3807: $itemon = $itemoff;
3808: $itemoff = ' ';
3809: }
3810: }
3811: return '<span class="LC_nobreak"><label>'.
3812: '<input type="radio" name="'.$item.'"'.
3813: $itemon.' value="yes" />'.&mt('Yes').'</label> '.
3814: '<label><input type="radio" name="'.$item.'"'.
3815: $itemoff.' value="" />'.&mt('No').'</label></span>';
3816: }
3817:
3818: sub select_from_options {
3819: my ($item,$order,$options,$curr,$nullval,$multiple,$maxsize,$onchange) = @_;
3820: my $output;
3821: if ((ref($order) eq 'ARRAY') && (ref($options) eq 'HASH')) {
3822: $output='<select name="'.$item.'" '.$onchange;
3823: if ($multiple) {
3824: $output .= ' multiple="multiple"';
3825: my $num = @{$order};
3826: $num ++ if ($nullval ne '');
3827: if (($maxsize) && ($maxsize < $num)) {
3828: $output .= ' size="'.$maxsize.'"';
3829: }
3830: }
3831: $output .= '>'."\n";
3832: if ($nullval ne '') {
3833: $output .= '<option value=""';
3834: if (ref($curr) eq 'ARRAY') {
3835: if ((@{$curr} == 0) || (grep(/^$/,@{$curr}))) {
3836: $output .= ' selected="selected" ';
3837: }
3838: } else {
3839: if ($curr eq '') {
3840: $output .= ' selected="selected" ';
3841: }
3842: }
3843: $output .= '>'.$nullval.'</option>';
3844: }
3845: foreach my $option (@{$order}) {
3846: $output.= '<option value="'.$option.'"';
3847: if (ref($curr) eq 'ARRAY') {
3848: if (grep(/^\Q$option\E$/,@{$curr})) {
3849: $output .= ' selected="selected" ';
3850: }
3851: } else {
3852: if ($option eq $curr) {
3853: $output.=' selected="selected"';
3854: }
3855: }
3856: $output.=">$options->{$option}</option>\n";
3857: }
3858: $output.="</select>";
3859: }
3860: return $output;
3861: }
3862:
3863: sub make_item_rows {
1.49.2.7 raeburn 3864: my ($cdom,$items,$ordered,$settings,$rowtotal,$crstype,$caller) = @_;
1.1 raeburn 3865: my $datatable;
3866: if ((ref($items) eq 'HASH') && (ref($ordered) eq 'ARRAY')) {
3867: my $count = 0;
3868: foreach my $item (@{$ordered}) {
3869: $count ++;
1.49.2.7 raeburn 3870: my $colspan;
3871: if ((($caller eq 'classlists') && ($item eq 'nothideprivileged')) ||
3872: (($caller eq 'printouts') && ($item ne 'print_header_format'))) {
3873: $colspan = 2;
3874: }
1.41 www 3875: if (exists $items->{$item}{advanced} && $items->{$item}{advanced} == 1) {
1.49.2.7 raeburn 3876: $datatable .= &item_table_row_start($items->{$item}{text},$count,"advanced",$colspan);
1.41 www 3877: } else {
1.49.2.7 raeburn 3878: $datatable .= &item_table_row_start($items->{$item}{text},$count,undef,$colspan);
1.41 www 3879: }
1.49.2.6 raeburn 3880: if ($item eq 'defaultcredits') {
3881: my $defaultcredits = $env{'course.'.$env{'request.course.id'}.'.internal.defaultcredits'};
3882: my $showcredits;
3883: if ($defaultcredits ne '') {
3884: $showcredits = &mt('Default is [quant,_1,credit]',$defaultcredits);
3885: } else {
3886: $showcredits = &mt('No default set');
3887: }
3888: $datatable .= $showcredits;
3889: } elsif ($item eq 'nothideprivileged') {
1.9 raeburn 3890: $datatable .= ¬hidepriv_row($cdom,$item,$settings,$crstype);
1.49.2.7 raeburn 3891: } elsif ($item eq 'checkforpriv') {
3892: $datatable .= &checkforpriv_row($cdom,$item,$settings,$crstype);
1.1 raeburn 3893: } elsif ($item eq 'print_header_format') {
3894: $datatable .= &print_hdrfmt_row($item,$settings);
3895: } elsif ($items->{$item}{input} eq 'dates') {
3896: $datatable .=
3897: &Apache::lonhtmlcommon::date_setter('display',$item,
3898: $settings->{$item});
3899: } elsif ($items->{$item}{input} eq 'radio') {
3900: $datatable .= &yesno_radio($item,$settings);
3901: } elsif ($items->{$item}{input} eq 'selectbox') {
3902: my $curr = $settings->{$item};
3903: $datatable .=
3904: &select_from_options($item,$items->{$item}{'order'},
3905: $items->{$item}{'options'},$curr,
3906: $items->{$item}{'nullval'});
3907: } elsif ($items->{$item}{input} eq 'textbox') {
3908: $datatable .=
3909: &Apache::lonhtmlcommon::textbox($item,$settings->{$item},
3910: $items->{$item}{size});
3911: }
3912: $datatable .= &item_table_row_end();
3913: }
3914: if (ref($rowtotal)) {
3915: $$rowtotal += scalar(@{$ordered});
3916: }
3917: }
3918: return $datatable;
3919: }
3920:
3921: sub nothidepriv_row {
1.9 raeburn 3922: my ($cdom,$item,$settings,$crstype) = @_;
1.1 raeburn 3923: my ($cnum) = &get_course();
1.49.2.7 raeburn 3924: my ($datatable,%nothide,@checkdoms);
1.1 raeburn 3925: if (ref($settings) eq 'HASH') {
3926: if ($settings->{$item} ne '') {
3927: foreach my $user (split(/\s*\,\s*/,$settings->{$item})) {
3928: if ($user !~ /:/) {
3929: $nothide{join(':',split(/[\@]/,$user))}=1;
3930: } else {
3931: $nothide{$user} = 1;
3932: }
3933: }
3934: }
1.49.2.7 raeburn 3935: if ($settings->{'checkforpriv'}) {
3936: @checkdoms = split(/,/,$settings->{'checkforpriv'});
3937: }
1.1 raeburn 3938: }
1.49.2.7 raeburn 3939: push(@checkdoms,$cdom);
3940: my %coursepersonnel =
3941: &Apache::lonnet::get_my_roles($cnum,$cdom,'',['previous','future','active']);
1.1 raeburn 3942: my @privusers;
3943: foreach my $person (keys(%coursepersonnel)) {
1.49.2.7 raeburn 3944: my ($uname,$udom,$role) = split(/:/,$person);
3945: my $user = $uname.':'.$udom;
3946: my ($start,$end) = split(/:/,$coursepersonnel{$person});
1.1 raeburn 3947: if ($end == -1 || $start == -1) {
3948: next;
3949: }
1.49.2.7 raeburn 3950: foreach my $dom (@checkdoms) {
3951: if (&Apache::lonnet::privileged($uname,$udom,\@checkdoms,['dc','su'])) {
3952: unless (grep(/^\Q$user\E$/,@privusers)) {
3953: push(@privusers,$user);
1.3 raeburn 3954: }
3955: }
3956: }
1.1 raeburn 3957: }
1.49.2.7 raeburn 3958: if (@privusers > 0) {
1.1 raeburn 3959: $datatable .= '<table align="right">';
3960: foreach my $user (sort(@privusers)) {
3961: my $hideon = ' checked="checked" ';
3962: my $hideoff = '';
3963: if ($nothide{$user}) {
3964: $hideoff = $hideon;
3965: $hideon = '';
3966: }
3967: my ($uname,$udom) = split(':',$user);
3968: $datatable .= '<tr><td align="left">'.
3969: &Apache::loncommon::aboutmewrapper(
3970: &Apache::loncommon::plainname($uname,$udom,'firstname'),
3971: $uname,$udom,'aboutuser').
3972: '</td><td align="left">'.
3973: '<span class="LC_nobreak"><label>'.
3974: '<input type="radio" name="'.$item.'_'.$user.'"'.
1.7 raeburn 3975: $hideon.' value="" />'.&mt('Hidden').'</label> '.
3976: '<label><input type="radio" name="'.$item.'_'.$user.'"'. $hideoff.' value="yes" />'.&mt('Shown').'</label></span></td>'.
1.1 raeburn 3977: '</tr>';
3978: }
3979: $datatable .= '</table>';
3980: } else {
1.9 raeburn 3981: if ($crstype eq 'Community') {
3982: $datatable .= &mt('No Domain Coordinators have community roles');
3983: } else {
3984: $datatable .= &mt('No Domain Coordinators have course roles');
3985: }
1.1 raeburn 3986: }
3987: return $datatable;
3988: }
3989:
1.49.2.7 raeburn 3990: sub checkforpriv_row {
3991: my ($cdom,$item,$settings,$crstype) = @_;
3992: my $datatable;
3993: my %domains=map { $_ => 1; } &Apache::lonnet::all_domains();
3994: if (keys(%domains) == 1) {
3995: $datatable = '</td><td align="right">'.
3996: &mt("Course's domain is only domain");
3997: return $datatable;
3998: }
3999: my @excdoms = ($cdom);
4000: my $num = 0;
4001: if ($settings->{$item} eq '') {
4002: $datatable = '</td><td align="right">'.
4003: &Apache::loncommon::select_dom_form('','checkforpriv_'.$num,
4004: 1,1,undef,undef,\@excdoms);
4005: } else {
4006: my @privdoms = split(/,/,$settings->{$item});
4007: my %domains=map { $_ => 1; } &Apache::lonnet::all_domains();
4008: $datatable = '</td><td align="right"><br />'.
4009: &Apache::loncommon::start_data_table();
4010: if (@privdoms > 0) {
4011: foreach my $currdom (@privdoms) {
4012: next unless ($domains{$currdom});
4013: my $domdesc = &Apache::lonnet::domain($currdom,'description');
4014: if ($domdesc eq '') {
4015: $domdesc = $currdom;
4016: }
4017: $datatable .=
4018: &Apache::loncommon::start_data_table_row().
4019: '<td align="left"><span class="LC_nobreak">'.
4020: &mt('Domain:').'<b> '.$domdesc.
4021: '</b><input type="hidden" name="checkforpriv_'.$num.
4022: '" value="'.$currdom.'" /></span><br />'.
4023: '<span class="LC_nobreak"><label><input type="checkbox" '.
4024: 'name="checkforpriv_delete" value="'.$num.'" />'.
4025: &mt('Delete').'</label></span></td>'.
4026: &Apache::loncommon::end_data_table_row();
4027: $num ++;
4028: unless (grep(/^\Q$currdom\E$/,@excdoms)) {
4029: push(@excdoms,$currdom);
4030: }
4031: }
4032: }
4033: if ((scalar(keys(%domains)) - scalar(@excdoms)) > 0) {
4034: $datatable .=
4035: &Apache::loncommon::start_data_table_row().
4036: '<td align="left"><span class="LC_nobreak">'.
4037: &mt('Additional domain:'). '</span><br />'.
4038: &Apache::loncommon::select_dom_form('','checkforpriv_'.$num,1,
4039: 1,undef,undef,\@excdoms).
4040: '</td>'.&Apache::loncommon::end_data_table_row();
4041: }
4042: $datatable .= &Apache::loncommon::end_data_table().
4043: '<input type="hidden" name="checkforpriv_total" value="'.$num.'" />'.
4044: '<br />';
4045: }
4046: return $datatable;
4047: }
4048:
1.1 raeburn 4049: sub print_hdrfmt_row {
4050: my ($item,$settings) = @_;
4051: my @curr;
4052: my $currnum = 0;
4053: my $maxnum = 2;
4054: my $currstr;
4055: if ($settings->{$item} ne '') {
4056: $currstr .= '<b>'.&mt('Current print header:').' <span class="LC_warning"><tt>'.
4057: $settings->{$item}.'</tt></span></b><br />';
4058: my @current = split(/(%\d*[nca])/,$settings->{$item});
1.23 raeburn 4059: foreach my $val (@current) {
4060: unless ($val eq '') {
4061: push(@curr,$val);
1.1 raeburn 4062: }
4063: }
4064: $currnum = @curr;
4065: $maxnum += $currnum;
4066: }
4067:
4068: my $output = <<ENDJS;
4069:
4070: <script type="text/javascript" language="Javascript">
4071:
4072: function reOrder(chgnum) {
4073: var maxnum = $maxnum;
4074: var oldidx = 'printfmthdr_oldpos_'+chgnum;
4075: var newidx = 'printfmthdr_pos_'+chgnum;
4076: oldidx = getIndexByName(oldidx);
4077: newidx = getIndexByName(newidx);
4078: var oldpos = document.display.elements[oldidx].value;
4079: var newpos = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
4080: document.display.elements[oldidx].value = newpos;
4081: var chgtype = 'up';
4082: if (newpos < oldpos) {
4083: chgtype = 'down';
4084: }
4085: for (var j=0; j<maxnum; j++) {
4086: if (j != chgnum) {
4087: oldidx = 'printfmthdr_oldpos_'+j;
4088: newidx = 'printfmthdr_pos_'+j;
4089: oldidx = getIndexByName(oldidx);
4090: newidx = getIndexByName(newidx);
4091: var currpos = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
4092: var currsel = document.display.elements[newidx].selectedIndex;
4093: if (chgtype == 'up') {
4094: if ((currpos > oldpos) && (currpos <= newpos)) {
4095: document.display.elements[newidx].selectedIndex = currsel-1;
4096: document.display.elements[oldidx].value = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
4097: }
4098: } else {
4099: if ((currpos >= newpos) && (currpos < oldpos)) {
4100: document.display.elements[newidx].selectedIndex = currsel+1;
4101: document.display.elements[oldidx].value = document.display.elements[newidx].options[document.display.elements[newidx].selectedIndex].value;
4102: }
4103: }
4104: }
4105: }
4106: return;
4107: }
4108:
4109: function getIndexByName(item) {
4110: for (var i=0;i<document.display.elements.length;i++) {
4111: if (document.display.elements[i].name == item) {
4112: return i;
4113: }
4114: }
4115: return -1;
4116: }
4117:
4118: </script>
4119:
4120: ENDJS
1.49.2.7 raeburn 4121: $output .= '</td><td align="right"><br />'.
4122: $currstr.'<table class="LC_data_table">';
1.1 raeburn 4123: if (@curr > 0) {
4124: for (my $i=0; $i<@curr; $i++) {
4125: my $pos = $i+1;
1.10 raeburn 4126: $output .= '<tr>'.
1.1 raeburn 4127: '<td align="left"><span class="LC_nobreak">'.
4128: &position_selector($pos,$i,$maxnum).&mt('Delete:').
4129: '<input type="checkbox" name="printfmthdr_del_'.$i.
4130: '" /></span></td>';
4131: if ($curr[$i] =~ /^%\d*[nca]$/) {
4132: my ($limit,$subst) = ($curr[$i] =~ /^%(\d*)([nca])$/);
4133: $output .= '<td align="left">'.
4134: &substitution_selector($i,$subst,$limit).'</td>';
4135: } else {
4136: $output .= '<td colspan="2" align="left">'.&mt('Text').'<br />'.
4137: '<input type="textbox" name="printfmthdr_text_'.$i.'"'.
4138: ' value="'.$curr[$i].'" size="25" /></td>';
4139: }
1.10 raeburn 4140: $output .= '</tr>';
1.1 raeburn 4141: }
4142: }
4143: my $pos = $currnum+1;
1.10 raeburn 4144: $output .= '<tr>'.
1.1 raeburn 4145: '<td align="left"><span class="LC_nobreak">'.
4146: &position_selector($pos,$currnum,$maxnum).
4147: '<b>'.&mt('New').'</b></span></td><td align="left">'.
4148: &substitution_selector($currnum).'</td>'.
1.10 raeburn 4149: '</tr>';
1.1 raeburn 4150: $pos ++;
4151: $currnum ++;
1.10 raeburn 4152: $output .= '<tr>'.
1.1 raeburn 4153: '<td align="left"><span class="LC_nobreak">'.
4154: &position_selector($pos,$currnum,$maxnum).
4155: '<b>'.&mt('New').'</b></span></td>'.
4156: '<td colspan="2" align="left">'.&mt('Text').'<br />'.
4157: '<input type="textbox" name="printfmthdr_text_'.$currnum.
1.3 raeburn 4158: '" value="" size ="25" />'.
4159: '<input type="hidden" name="printfmthdr_maxnum" value="'.
4160: $maxnum.'" /></td>'.
1.10 raeburn 4161: '</tr>'.
1.49.2.7 raeburn 4162: '</table><br />';
1.1 raeburn 4163: return $output;
4164: }
4165:
4166: sub position_selector {
4167: my ($pos,$num,$maxnum) = @_;
4168: my $output = '<select name="printfmthdr_pos_'.$num.'" onchange="reOrder('."'$num'".');">';
4169: for (my $j=1; $j<=$maxnum; $j++) {
4170: my $sel = '';
4171: if ($pos == $j) {
4172: $sel = ' selected="selected"';
4173: }
4174: $output .= '<option value="'.$j.'"'.$sel.'">'.$j.'</option>';
4175: }
4176: $output .= '</select><input type="hidden" name="printfmthdr_oldpos_'.$num.
4177: '" value="'.$pos.'" />';
4178: return $output;
4179: }
4180:
4181: sub substitution_selector {
1.9 raeburn 4182: my ($num,$subst,$limit,$crstype) = @_;
4183: my ($stunametxt,$crsidtxt);
4184: if ($crstype eq 'Community') {
4185: $stunametxt = 'member name';
4186: $crsidtxt = 'community ID',
4187: } else {
4188: $stunametxt = 'student name';
4189: $crsidtxt = 'course ID',
4190: }
1.1 raeburn 4191: my %lt = &Apache::lonlocal::texthash(
1.9 raeburn 4192: n => $stunametxt,
4193: c => $crsidtxt,
1.1 raeburn 4194: a => 'assignment note',
4195: );
4196: my $output .= &mt('Substitution').'<br />'.
1.29 raeburn 4197: '<select name="printfmthdr_sub_'.$num.'">';
1.1 raeburn 4198: if ($subst eq '') {
4199: $output .= '<option value="" selected="selected"> </option>';
4200: }
4201: foreach my $field ('n','c','a') {
4202: my $sel ='';
4203: if ($subst eq $field) {
4204: $sel = ' selected="selected"';
4205: }
4206: $output .= '<option value="'.$field.'"'.$sel.'>'.
4207: $lt{$field}.'</option>';
4208: }
4209: $output .= '</select></td><td align="left">'.&mt('Size limit').'<br />'.
4210: '<input type="textbox" name="printfmthdr_limit_'.$num.
4211: '" value="'.$limit.'" size="5" /></span>';
4212: return $output;
4213: }
4214:
1.23 raeburn 4215: sub change_clone {
4216: my ($cdom,$cnum,$clonelist,$oldcloner) = @_;
4217: my $clone_crs = $cnum.':'.$cdom;
4218: if ($cnum && $cdom) {
4219: my $clone_crs = $cnum.':'.$cdom;
4220: my @allowclone;
4221: if ($clonelist =~ /,/) {
4222: @allowclone = split(',',$clonelist);
4223: } else {
4224: $allowclone[0] = $clonelist;
4225: }
4226: foreach my $currclone (@allowclone) {
4227: if (!grep(/^$currclone$/,@$oldcloner)) {
4228: if ($currclone ne '*') {
4229: my ($uname,$udom) = split(/:/,$currclone);
4230: if ($uname && $udom && $uname ne '*') {
4231: if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
4232: my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
4233: if ($currclonecrs{'cloneable'} !~ /\Q$clone_crs\E/) {
4234: if ($currclonecrs{'cloneable'} eq '') {
4235: $currclonecrs{'cloneable'} = $clone_crs;
4236: } else {
4237: $currclonecrs{'cloneable'} .= ','.$clone_crs;
4238: }
4239: &Apache::lonnet::put('environment',\%currclonecrs,$udom,$uname);
4240: }
4241: }
4242: }
4243: }
4244: }
4245: }
4246: foreach my $oldclone (@$oldcloner) {
4247: if (!grep(/^\Q$oldclone\E$/,@allowclone)) {
4248: if ($oldclone ne '*') {
4249: my ($uname,$udom) = split(/:/,$oldclone);
4250: if ($uname && $udom && $uname ne '*' ) {
4251: if (&Apache::lonnet::homeserver($uname,$udom) ne 'no_host') {
4252: my %currclonecrs = &Apache::lonnet::dump('environment',$udom,$uname,'cloneable');
4253: my %newclonecrs = ();
4254: if ($currclonecrs{'cloneable'} =~ /\Q$clone_crs\E/) {
4255: if ($currclonecrs{'cloneable'} =~ /,/) {
4256: my @currclonecrs = split/,/,$currclonecrs{'cloneable'};
4257: foreach my $crs (@currclonecrs) {
4258: if ($crs ne $clone_crs) {
4259: $newclonecrs{'cloneable'} .= $crs.',';
4260: }
4261: }
4262: $newclonecrs{'cloneable'} =~ s/,$//;
4263: } else {
4264: $newclonecrs{'cloneable'} = '';
4265: }
4266: &Apache::lonnet::put('environment',\%newclonecrs,$udom,$uname);
4267: }
4268: }
4269: }
4270: }
4271: }
4272: }
4273: }
4274: return;
4275: }
4276:
1.1 raeburn 4277: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>