File:
[LON-CAPA] /
loncom /
interface /
domainprefs.pm
Revision
1.341:
download - view:
text,
annotated -
select for diffs
Sun Nov 18 22:50:52 2018 UTC (5 years, 9 months ago) by
raeburn
Branches:
MAIN
CVS tags:
HEAD
- Scanning of lonnet.perm.log by loncron
- Information about which nodes have unsent update transactions is logged.
- Specific nodes can be excluded from unsend count (for delayed updates)
via domain configuration.
- Weight for unsend count (before adding to "warnings") is configurable.
1: # The LearningOnline Network with CAPA
2: # Handler to set domain-wide configuration settings
3: #
4: # $Id: domainprefs.pm,v 1.341 2018/11/18 22:50:52 raeburn Exp $
5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28: #
29: ###############################################################
30: ###############################################################
31:
32: =pod
33:
34: =head1 NAME
35:
36: Apache::domainprefs.pm
37:
38: =head1 SYNOPSIS
39:
40: Handles configuration of a LON-CAPA domain.
41:
42: This is part of the LearningOnline Network with CAPA project
43: described at http://www.lon-capa.org.
44:
45:
46: =head1 OVERVIEW
47:
48: Each institution using LON-CAPA will typically have a single domain designated
49: for use by individuals affiliated with the institution. Accordingly, each domain
50: may define a default set of logos and a color scheme which can be used to "brand"
51: the LON-CAPA instance. In addition, an institution will typically have a language
52: and timezone which are used for the majority of courses.
53:
54: LON-CAPA provides a mechanism to display and modify these defaults, as well as a
55: host of other domain-wide settings which determine the types of functionality
56: available to users and courses in the domain.
57:
58: There is also a mechanism to configure cataloging of courses in the domain, and
59: controls on the operation of automated processes which govern such things as
60: roster updates, user directory updates and processing of course requests.
61:
62: The domain coordination manual which is built dynamically on install/update of
63: LON-CAPA from the relevant help items provides more information about domain
64: configuration.
65:
66: Most of the domain settings are stored in the configuration.db GDBM file which is
67: housed on the primary library server for the domain in /home/httpd/lonUsers/$dom,
68: where $dom is the domain. The configuration.db stores settings in a number of
69: frozen hashes of hashes. In a few cases, domain information must be uploaded to
70: the domain as files (e.g., image files for logos etc., or plain text files for
71: bubblesheet formats). In this case the domainprefs.pm must be running in a user
72: session hosted on the primary library server in the domain, as these files are
73: stored in author space belonging to a special $dom-domainconfig user.
74:
75: domainprefs.pm in combination with lonconfigsettings.pm will retrieve and display
76: the current settings, and provides an interface to make modifications.
77:
78: =head1 SUBROUTINES
79:
80: =over
81:
82: =item print_quotas()
83:
84: Inputs: 4
85:
86: $dom,$settings,$rowtotal,$action.
87:
88: $dom is the domain, $settings is a reference to a hash of current settings for
89: the current context, $rowtotal is a reference to the scalar used to record the
90: number of rows displayed on the page, and $action is the context (quotas,
91: requestcourses or requestauthor).
92:
93: The print_quotas routine was orginally created to display/store information
94: about default quota sizes for portfolio spaces for the different types of
95: institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.),
96: but is now also used to manage availability of user tools:
97: i.e., blogs, aboutme page, and portfolios, and the course request tool,
98: used by course owners to request creation of a course, and to display/store
99: default quota sizes for Authoring Spaces.
100:
101: Outputs: 1
102:
103: $datatable - HTML containing form elements which allow settings to be changed.
104:
105: In the case of course requests, radio buttons are displayed for each institutional
106: affiliate type (and also default, and _LC_adv) for each of the course types
107: (official, unofficial, community, textbook, placement, and lti).
108: In each case the radio buttons allow the selection of one of four values:
109:
110: 0, approval, validate, autolimit=N (where N is blank, or a positive integer).
111: which have the following effects:
112:
113: 0
114:
115: =over
116:
117: - course requests are not allowed for this course types/affiliation
118:
119: =back
120:
121: approval
122:
123: =over
124:
125: - course requests must be approved by a Doman Coordinator in the
126: course's domain
127:
128: =back
129:
130: validate
131:
132: =over
133:
134: - an institutional validation (e.g., check requestor is instructor
135: of record) needs to be passed before the course will be created. The required
136: validation is in localenroll.pm on the primary library server for the course
137: domain.
138:
139: =back
140:
141: autolimit
142:
143: =over
144:
145: - course requests will be processed automatically up to a limit of
146: N requests for the course type for the particular requestor.
147: If N is undefined, there is no limit to the number of course requests
148: which a course owner may submit and have processed automatically.
149:
150: =back
151:
152: =item modify_quotas()
153:
154: =back
155:
156: =cut
157:
158: package Apache::domainprefs;
159:
160: use strict;
161: use Apache::Constants qw(:common :http);
162: use Apache::lonnet;
163: use Apache::loncommon();
164: use Apache::lonhtmlcommon();
165: use Apache::lonlocal;
166: use Apache::lonmsg();
167: use Apache::lonconfigsettings;
168: use Apache::lonuserutils();
169: use Apache::loncoursequeueadmin();
170: use LONCAPA qw(:DEFAULT :match);
171: use LONCAPA::Enrollment;
172: use LONCAPA::lonauthcgi();
173: use LONCAPA::SSL;
174: use File::Copy;
175: use Locale::Language;
176: use DateTime::TimeZone;
177: use DateTime::Locale;
178: use Time::HiRes qw( sleep );
179:
180: my $registered_cleanup;
181: my $modified_urls;
182:
183: sub handler {
184: my $r=shift;
185: if ($r->header_only) {
186: &Apache::loncommon::content_type($r,'text/html');
187: $r->send_http_header;
188: return OK;
189: }
190:
191: my $context = 'domain';
192: my $dom = $env{'request.role.domain'};
193: my $domdesc = &Apache::lonnet::domain($dom,'description');
194: if (&Apache::lonnet::allowed('mau',$dom)) {
195: &Apache::loncommon::content_type($r,'text/html');
196: $r->send_http_header;
197: } else {
198: $env{'user.error.msg'}=
199: "/adm/domainprefs:mau:0:0:Cannot modify domain settings";
200: return HTTP_NOT_ACCEPTABLE;
201: }
202:
203: $registered_cleanup=0;
204: @{$modified_urls}=();
205:
206: &Apache::lonhtmlcommon::clear_breadcrumbs();
207: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
208: ['phase','actions']);
209: my $phase = 'pickactions';
210: if ( exists($env{'form.phase'}) ) {
211: $phase = $env{'form.phase'};
212: }
213: my %servers = &Apache::lonnet::internet_dom_servers($dom);
214: my %domconfig =
215: &Apache::lonnet::get_dom('configuration',['login','rolecolors',
216: 'quotas','autoenroll','autoupdate','autocreate',
217: 'directorysrch','usercreation','usermodification',
218: 'contacts','defaults','scantron','coursecategories',
219: 'serverstatuses','requestcourses','helpsettings',
220: 'coursedefaults','usersessions','loadbalancing',
221: 'requestauthor','selfenrollment','inststatus',
222: 'ltitools','ssl','trust','lti'],$dom);
223: my %encconfig =
224: &Apache::lonnet::get_dom('encconfig',['ltitools','lti'],$dom);
225: if (ref($domconfig{'ltitools'}) eq 'HASH') {
226: if (ref($encconfig{'ltitools'}) eq 'HASH') {
227: foreach my $id (keys(%{$domconfig{'ltitools'}})) {
228: if ((ref($domconfig{'ltitools'}{$id}) eq 'HASH') &&
229: (ref($encconfig{'ltitools'}{$id}) eq 'HASH')) {
230: foreach my $item ('key','secret') {
231: $domconfig{'ltitools'}{$id}{$item} = $encconfig{'ltitools'}{$id}{$item};
232: }
233: }
234: }
235: }
236: }
237: if (ref($domconfig{'lti'}) eq 'HASH') {
238: if (ref($encconfig{'lti'}) eq 'HASH') {
239: foreach my $id (keys(%{$domconfig{'lti'}})) {
240: if ((ref($domconfig{'lti'}{$id}) eq 'HASH') &&
241: (ref($encconfig{'lti'}{$id}) eq 'HASH')) {
242: foreach my $item ('key','secret') {
243: $domconfig{'lti'}{$id}{$item} = $encconfig{'lti'}{$id}{$item};
244: }
245: }
246: }
247: }
248: }
249: my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
250: 'autoupdate','autocreate','directorysrch','contacts',
251: 'usercreation','selfcreation','usermodification','scantron',
252: 'requestcourses','requestauthor','coursecategories',
253: 'serverstatuses','helpsettings','coursedefaults',
254: 'ltitools','selfenrollment','usersessions','ssl','trust','lti');
255: my %existing;
256: if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
257: %existing = %{$domconfig{'loadbalancing'}};
258: }
259: if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
260: push(@prefs_order,'loadbalancing');
261: }
262: my %prefs = (
263: 'rolecolors' =>
264: { text => 'Default color schemes',
265: help => 'Domain_Configuration_Color_Schemes',
266: header => [{col1 => 'Student Settings',
267: col2 => '',},
268: {col1 => 'Coordinator Settings',
269: col2 => '',},
270: {col1 => 'Author Settings',
271: col2 => '',},
272: {col1 => 'Administrator Settings',
273: col2 => '',}],
274: print => \&print_rolecolors,
275: modify => \&modify_rolecolors,
276: },
277: 'login' =>
278: { text => 'Log-in page options',
279: help => 'Domain_Configuration_Login_Page',
280: header => [{col1 => 'Log-in Page Items',
281: col2 => '',},
282: {col1 => 'Log-in Help',
283: col2 => 'Value'},
284: {col1 => 'Custom HTML in document head',
285: col2 => 'Value'}],
286: print => \&print_login,
287: modify => \&modify_login,
288: },
289: 'defaults' =>
290: { text => 'Default authentication/language/timezone/portal/types',
291: help => 'Domain_Configuration_LangTZAuth',
292: header => [{col1 => 'Setting',
293: col2 => 'Value'},
294: {col1 => 'Internal Authentication',
295: col2 => 'Value'},
296: {col1 => 'Institutional user types',
297: col2 => 'Name displayed'}],
298: print => \&print_defaults,
299: modify => \&modify_defaults,
300: },
301: 'quotas' =>
302: { text => 'Blogs, personal web pages, webDAV/quotas, portfolios',
303: help => 'Domain_Configuration_Quotas',
304: header => [{col1 => 'User affiliation',
305: col2 => 'Available tools',
306: col3 => 'Quotas, MB; (Authoring requires role)',}],
307: print => \&print_quotas,
308: modify => \&modify_quotas,
309: },
310: 'autoenroll' =>
311: { text => 'Auto-enrollment settings',
312: help => 'Domain_Configuration_Auto_Enrollment',
313: header => [{col1 => 'Configuration setting',
314: col2 => 'Value(s)'}],
315: print => \&print_autoenroll,
316: modify => \&modify_autoenroll,
317: },
318: 'autoupdate' =>
319: { text => 'Auto-update settings',
320: help => 'Domain_Configuration_Auto_Updates',
321: header => [{col1 => 'Setting',
322: col2 => 'Value',},
323: {col1 => 'Setting',
324: col2 => 'Affiliation'},
325: {col1 => 'User population',
326: col2 => 'Updatable user data'}],
327: print => \&print_autoupdate,
328: modify => \&modify_autoupdate,
329: },
330: 'autocreate' =>
331: { text => 'Auto-course creation settings',
332: help => 'Domain_Configuration_Auto_Creation',
333: header => [{col1 => 'Configuration Setting',
334: col2 => 'Value',}],
335: print => \&print_autocreate,
336: modify => \&modify_autocreate,
337: },
338: 'directorysrch' =>
339: { text => 'Directory searches',
340: help => 'Domain_Configuration_InstDirectory_Search',
341: header => [{col1 => 'Institutional Directory Setting',
342: col2 => 'Value',},
343: {col1 => 'LON-CAPA Directory Setting',
344: col2 => 'Value',}],
345: print => \&print_directorysrch,
346: modify => \&modify_directorysrch,
347: },
348: 'contacts' =>
349: { text => 'E-mail addresses and helpform',
350: help => 'Domain_Configuration_Contact_Info',
351: header => [{col1 => 'Default e-mail addresses',
352: col2 => 'Value',},
353: {col1 => 'Recipient(s) for notifications',
354: col2 => 'Value',},
355: {col1 => 'Nightly status check e-mail',
356: col2 => 'Settings',},
357: {col1 => 'Ask helpdesk form settings',
358: col2 => 'Value',},],
359: print => \&print_contacts,
360: modify => \&modify_contacts,
361: },
362: 'usercreation' =>
363: { text => 'User creation',
364: help => 'Domain_Configuration_User_Creation',
365: header => [{col1 => 'Format rule type',
366: col2 => 'Format rules in force'},
367: {col1 => 'User account creation',
368: col2 => 'Usernames which may be created',},
369: {col1 => 'Context',
370: col2 => 'Assignable authentication types'}],
371: print => \&print_usercreation,
372: modify => \&modify_usercreation,
373: },
374: 'selfcreation' =>
375: { text => 'Users self-creating accounts',
376: help => 'Domain_Configuration_Self_Creation',
377: header => [{col1 => 'Self-creation with institutional username',
378: col2 => 'Enabled?'},
379: {col1 => 'Institutional user type (login/SSO self-creation)',
380: col2 => 'Information user can enter'},
381: {col1 => 'Self-creation with e-mail verification',
382: col2 => 'Settings'}],
383: print => \&print_selfcreation,
384: modify => \&modify_selfcreation,
385: },
386: 'usermodification' =>
387: { text => 'User modification',
388: help => 'Domain_Configuration_User_Modification',
389: header => [{col1 => 'Target user has role',
390: col2 => 'User information updatable in author context'},
391: {col1 => 'Target user has role',
392: col2 => 'User information updatable in course context'}],
393: print => \&print_usermodification,
394: modify => \&modify_usermodification,
395: },
396: 'scantron' =>
397: { text => 'Bubblesheet format file',
398: help => 'Domain_Configuration_Scantron_Format',
399: header => [ {col1 => 'Item',
400: col2 => '',
401: }],
402: print => \&print_scantron,
403: modify => \&modify_scantron,
404: },
405: 'requestcourses' =>
406: {text => 'Request creation of courses',
407: help => 'Domain_Configuration_Request_Courses',
408: header => [{col1 => 'User affiliation',
409: col2 => 'Availability/Processing of requests',},
410: {col1 => 'Setting',
411: col2 => 'Value'},
412: {col1 => 'Available textbooks',
413: col2 => ''},
414: {col1 => 'Available templates',
415: col2 => ''},
416: {col1 => 'Validation (not official courses)',
417: col2 => 'Value'},],
418: print => \&print_quotas,
419: modify => \&modify_quotas,
420: },
421: 'requestauthor' =>
422: {text => 'Request Authoring Space',
423: help => 'Domain_Configuration_Request_Author',
424: header => [{col1 => 'User affiliation',
425: col2 => 'Availability/Processing of requests',},
426: {col1 => 'Setting',
427: col2 => 'Value'}],
428: print => \&print_quotas,
429: modify => \&modify_quotas,
430: },
431: 'coursecategories' =>
432: { text => 'Cataloging of courses/communities',
433: help => 'Domain_Configuration_Cataloging_Courses',
434: header => [{col1 => 'Catalog type/availability',
435: col2 => '',},
436: {col1 => 'Category settings for standard catalog',
437: col2 => '',},
438: {col1 => 'Categories',
439: col2 => '',
440: }],
441: print => \&print_coursecategories,
442: modify => \&modify_coursecategories,
443: },
444: 'serverstatuses' =>
445: {text => 'Access to server status pages',
446: help => 'Domain_Configuration_Server_Status',
447: header => [{col1 => 'Status Page',
448: col2 => 'Other named users',
449: col3 => 'Specific IPs',
450: }],
451: print => \&print_serverstatuses,
452: modify => \&modify_serverstatuses,
453: },
454: 'helpsettings' =>
455: {text => 'Support settings',
456: help => 'Domain_Configuration_Help_Settings',
457: header => [{col1 => 'Help Page Settings (logged-in users)',
458: col2 => 'Value'},
459: {col1 => 'Helpdesk Roles',
460: col2 => 'Settings'},],
461: print => \&print_helpsettings,
462: modify => \&modify_helpsettings,
463: },
464: 'coursedefaults' =>
465: {text => 'Course/Community defaults',
466: help => 'Domain_Configuration_Course_Defaults',
467: header => [{col1 => 'Defaults which can be overridden in each course by a CC',
468: col2 => 'Value',},
469: {col1 => 'Defaults which can be overridden for each course by a DC',
470: col2 => 'Value',},],
471: print => \&print_coursedefaults,
472: modify => \&modify_coursedefaults,
473: },
474: 'selfenrollment' =>
475: {text => 'Self-enrollment in Course/Community',
476: help => 'Domain_Configuration_Selfenrollment',
477: header => [{col1 => 'Configuration Rights',
478: col2 => 'Configured by Course Personnel or Domain Coordinator?'},
479: {col1 => 'Defaults',
480: col2 => 'Value'},
481: {col1 => 'Self-enrollment validation (optional)',
482: col2 => 'Value'},],
483: print => \&print_selfenrollment,
484: modify => \&modify_selfenrollment,
485: },
486: 'privacy' =>
487: {text => 'User Privacy',
488: help => 'Domain_Configuration_User_Privacy',
489: header => [{col1 => 'Setting',
490: col2 => 'Value',}],
491: print => \&print_privacy,
492: modify => \&modify_privacy,
493: },
494: 'usersessions' =>
495: {text => 'User session hosting/offloading',
496: help => 'Domain_Configuration_User_Sessions',
497: header => [{col1 => 'Domain server',
498: col2 => 'Servers to offload sessions to when busy'},
499: {col1 => 'Hosting of users from other domains',
500: col2 => 'Rules'},
501: {col1 => "Hosting domain's own users elsewhere",
502: col2 => 'Rules'}],
503: print => \&print_usersessions,
504: modify => \&modify_usersessions,
505: },
506: 'loadbalancing' =>
507: {text => 'Dedicated Load Balancer(s)',
508: help => 'Domain_Configuration_Load_Balancing',
509: header => [{col1 => 'Balancers',
510: col2 => 'Default destinations',
511: col3 => 'User affiliation',
512: col4 => 'Overrides'},
513: ],
514: print => \&print_loadbalancing,
515: modify => \&modify_loadbalancing,
516: },
517: 'ltitools' =>
518: {text => 'External Tools (LTI)',
519: help => 'Domain_Configuration_LTI_Tools',
520: header => [{col1 => 'Setting',
521: col2 => 'Value',}],
522: print => \&print_ltitools,
523: modify => \&modify_ltitools,
524: },
525: 'ssl' =>
526: {text => 'LON-CAPA Network (SSL)',
527: help => 'Domain_Configuration_Network_SSL',
528: header => [{col1 => 'Server',
529: col2 => 'Certificate Status'},
530: {col1 => 'Connections to other servers',
531: col2 => 'Rules'},
532: {col1 => 'Connections from other servers',
533: col2 => 'Rules'},
534: {col1 => "Replicating domain's published content",
535: col2 => 'Rules'}],
536: print => \&print_ssl,
537: modify => \&modify_ssl,
538: },
539: 'trust' =>
540: {text => 'Trust Settings',
541: help => 'Domain_Configuration_Trust',
542: header => [{col1 => "Access to this domain's content by others",
543: col2 => 'Rules'},
544: {col1 => "Access to other domain's content by this domain",
545: col2 => 'Rules'},
546: {col1 => "Enrollment in this domain's courses by others",
547: col2 => 'Rules',},
548: {col1 => "Co-author roles in this domain for others",
549: col2 => 'Rules',},
550: {col1 => "Co-author roles for this domain's users elsewhere",
551: col2 => 'Rules',},
552: {col1 => "Domain roles in this domain assignable to others",
553: col2 => 'Rules'},
554: {col1 => "Course catalog for this domain displayed elsewhere",
555: col2 => 'Rules'},
556: {col1 => "Requests for creation of courses in this domain by others",
557: col2 => 'Rules'},
558: {col1 => "Users in other domains can send messages to this domain",
559: col2 => 'Rules'},],
560: print => \&print_trust,
561: modify => \&modify_trust,
562: },
563: 'lti' =>
564: {text => 'LTI Provider',
565: help => 'Domain_Configuration_LTI_Provider',
566: header => [{col1 => 'Setting',
567: col2 => 'Value',}],
568: print => \&print_lti,
569: modify => \&modify_lti,
570: },
571: );
572: if (keys(%servers) > 1) {
573: $prefs{'login'} = { text => 'Log-in page options',
574: help => 'Domain_Configuration_Login_Page',
575: header => [{col1 => 'Log-in Service',
576: col2 => 'Server Setting',},
577: {col1 => 'Log-in Page Items',
578: col2 => ''},
579: {col1 => 'Log-in Help',
580: col2 => 'Value'},
581: {col1 => 'Custom HTML in document head',
582: col2 => 'Value'}],
583: print => \&print_login,
584: modify => \&modify_login,
585: };
586: }
587:
588: my @roles = ('student','coordinator','author','admin');
589: my @actions = &Apache::loncommon::get_env_multiple('form.actions');
590: &Apache::lonhtmlcommon::add_breadcrumb
591: ({href=>"javascript:changePage(document.$phase,'pickactions')",
592: text=>"Settings to display/modify"});
593: my $confname = $dom.'-domainconfig';
594:
595: if ($phase eq 'process') {
596: my $result = &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,
597: \%prefs,\%domconfig,$confname,\@roles);
598: if ((ref($result) eq 'HASH') && (keys(%{$result}))) {
599: $r->rflush();
600: &devalidate_remote_domconfs($dom,$result);
601: }
602: } elsif ($phase eq 'display') {
603: my $js = &recaptcha_js().
604: &toggle_display_js();
605: if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
606: my ($othertitle,$usertypes,$types) =
607: &Apache::loncommon::sorted_inst_types($dom);
608: $js .= &lonbalance_targets_js($dom,$types,\%servers,
609: $domconfig{'loadbalancing'}).
610: &new_spares_js().
611: &common_domprefs_js().
612: &Apache::loncommon::javascript_array_indexof();
613: }
614: if (grep(/^requestcourses$/,@actions)) {
615: my $javascript_validations;
616: my $coursebrowserjs=&Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'});
617: $js .= <<END;
618: <script type="text/javascript">
619: $javascript_validations
620: </script>
621: $coursebrowserjs
622: END
623: }
624: if (grep(/^selfcreation$/,@actions)) {
625: $js .= &selfcreate_javascript();
626: }
627: if (grep(/^contacts$/,@actions)) {
628: $js .= &contacts_javascript();
629: }
630: &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);
631: } else {
632: # check if domconfig user exists for the domain.
633: my $servadm = $r->dir_config('lonAdmEMail');
634: my ($configuserok,$author_ok,$switchserver) =
635: &config_check($dom,$confname,$servadm);
636: unless ($configuserok eq 'ok') {
637: &Apache::lonconfigsettings::print_header($r,$phase,$context);
638: $r->print(&mt('The domain configuration user "[_1]" has yet to be created.',
639: $confname).
640: '<br />'
641: );
642: if ($switchserver) {
643: $r->print(&mt('Ordinarily, that domain configuration user is created when the ./UPDATE script is run to install LON-CAPA for the first time.').
644: '<br />'.
645: &mt('However, that does not apply when new domains are added to a multi-domain server, and ./UPDATE has not been run recently.').
646: '<br />'.
647: &mt('The "[_1]" user can be created automatically when a Domain Coordinator visits the web-based "Set domain configuration" screen, in a session hosted on the primary library server.',$confname).
648: '<br />'.
649: &mt('To do that now, use the following link: [_1]',$switchserver)
650: );
651: } else {
652: $r->print(&mt('To create that user from the command line run the ./UPDATE script found in the top level directory of the extracted LON-CAPA tarball.').
653: '<br />'.
654: &mt('Once that is done, you will be able to use the web-based "Set domain configuration" to configure the domain')
655: );
656: }
657: $r->print(&Apache::loncommon::end_page());
658: return OK;
659: }
660: if (keys(%domconfig) == 0) {
661: my $primarylibserv = &Apache::lonnet::domain($dom,'primary');
662: my @ids=&Apache::lonnet::current_machine_ids();
663: if (!grep(/^\Q$primarylibserv\E$/,@ids)) {
664: my %designhash = &Apache::loncommon::get_domainconf($dom);
665: my @loginimages = ('img','logo','domlogo','login');
666: my $custom_img_count = 0;
667: foreach my $img (@loginimages) {
668: if ($designhash{$dom.'.login.'.$img} ne '') {
669: $custom_img_count ++;
670: }
671: }
672: foreach my $role (@roles) {
673: if ($designhash{$dom.'.'.$role.'.img'} ne '') {
674: $custom_img_count ++;
675: }
676: }
677: if ($custom_img_count > 0) {
678: &Apache::lonconfigsettings::print_header($r,$phase,$context);
679: my $switch_server = &check_switchserver($dom,$confname);
680: $r->print(
681: &mt('Domain configuration settings have yet to be saved for this domain via the web-based domain preferences interface.').'<br />'.
682: &mt("While this remains so, you must switch to the domain's primary library server in order to update settings.").'<br /><br />'.
683: &mt("Thereafter, (with a Domain Coordinator role selected in the domain) you will be able to update settings when logged in to any server in the LON-CAPA network.").'<br />'.
684: &mt("However, you will still need to switch to the domain's primary library server to upload new images or logos.").'<br /><br />');
685: if ($switch_server) {
686: $r->print($switch_server.' '.&mt('to primary library server for domain: [_1]',$dom));
687: }
688: $r->print(&Apache::loncommon::end_page());
689: return OK;
690: }
691: }
692: }
693: &Apache::lonconfigsettings::display_choices($r,$phase,$context,\@prefs_order,\%prefs);
694: }
695: return OK;
696: }
697:
698: sub process_changes {
699: my ($r,$dom,$confname,$action,$roles,$values,$lastactref) = @_;
700: my %domconfig;
701: if (ref($values) eq 'HASH') {
702: %domconfig = %{$values};
703: }
704: my $output;
705: if ($action eq 'login') {
706: $output = &modify_login($r,$dom,$confname,$lastactref,%domconfig);
707: } elsif ($action eq 'rolecolors') {
708: $output = &modify_rolecolors($r,$dom,$confname,$roles,
709: $lastactref,%domconfig);
710: } elsif ($action eq 'quotas') {
711: $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);
712: } elsif ($action eq 'autoenroll') {
713: $output = &modify_autoenroll($dom,$lastactref,%domconfig);
714: } elsif ($action eq 'autoupdate') {
715: $output = &modify_autoupdate($dom,%domconfig);
716: } elsif ($action eq 'autocreate') {
717: $output = &modify_autocreate($dom,%domconfig);
718: } elsif ($action eq 'directorysrch') {
719: $output = &modify_directorysrch($dom,$lastactref,%domconfig);
720: } elsif ($action eq 'usercreation') {
721: $output = &modify_usercreation($dom,%domconfig);
722: } elsif ($action eq 'selfcreation') {
723: $output = &modify_selfcreation($dom,$lastactref,%domconfig);
724: } elsif ($action eq 'usermodification') {
725: $output = &modify_usermodification($dom,%domconfig);
726: } elsif ($action eq 'contacts') {
727: $output = &modify_contacts($dom,$lastactref,%domconfig);
728: } elsif ($action eq 'defaults') {
729: $output = &modify_defaults($dom,$lastactref,%domconfig);
730: } elsif ($action eq 'scantron') {
731: $output = &modify_scantron($r,$dom,$confname,$lastactref,%domconfig);
732: } elsif ($action eq 'coursecategories') {
733: $output = &modify_coursecategories($dom,$lastactref,%domconfig);
734: } elsif ($action eq 'serverstatuses') {
735: $output = &modify_serverstatuses($dom,%domconfig);
736: } elsif ($action eq 'requestcourses') {
737: $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);
738: } elsif ($action eq 'requestauthor') {
739: $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig);
740: } elsif ($action eq 'helpsettings') {
741: $output = &modify_helpsettings($r,$dom,$confname,$lastactref,%domconfig);
742: } elsif ($action eq 'coursedefaults') {
743: $output = &modify_coursedefaults($dom,$lastactref,%domconfig);
744: } elsif ($action eq 'selfenrollment') {
745: $output = &modify_selfenrollment($dom,$lastactref,%domconfig)
746: } elsif ($action eq 'usersessions') {
747: $output = &modify_usersessions($dom,$lastactref,%domconfig);
748: } elsif ($action eq 'loadbalancing') {
749: $output = &modify_loadbalancing($dom,%domconfig);
750: } elsif ($action eq 'ltitools') {
751: $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig);
752: } elsif ($action eq 'ssl') {
753: $output = &modify_ssl($dom,$lastactref,%domconfig);
754: } elsif ($action eq 'trust') {
755: $output = &modify_trust($dom,$lastactref,%domconfig);
756: } elsif ($action eq 'lti') {
757: $output = &modify_lti($r,$dom,$action,$lastactref,%domconfig);
758: }
759: return $output;
760: }
761:
762: sub print_config_box {
763: my ($r,$dom,$confname,$phase,$action,$item,$settings) = @_;
764: my $rowtotal = 0;
765: my $output;
766: if ($action eq 'coursecategories') {
767: $output = &coursecategories_javascript($settings);
768: } elsif ($action eq 'defaults') {
769: $output = &defaults_javascript($settings);
770: } elsif ($action eq 'helpsettings') {
771: my (%privs,%levelscurrent);
772: my %full=();
773: my %levels=(
774: course => {},
775: domain => {},
776: system => {},
777: );
778: my $context = 'domain';
779: my $crstype = 'Course';
780: my $formname = 'display';
781: &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);
782: my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
783: $output =
784: &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full,
785: \@templateroles);
786: } elsif ($action eq 'ltitools') {
787: $output .= <itools_javascript($settings);
788: } elsif ($action eq 'lti') {
789: $output .= <i_javascript($settings);
790: }
791: $output .=
792: '<table class="LC_nested_outer">
793: <tr>
794: <th class="LC_left_item LC_middle"><span class="LC_nobreak">'.
795: &mt($item->{text}).' '.
796: &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n".
797: '</tr>';
798: $rowtotal ++;
799: my $numheaders = 1;
800: if (ref($item->{'header'}) eq 'ARRAY') {
801: $numheaders = scalar(@{$item->{'header'}});
802: }
803: if ($numheaders > 1) {
804: my $colspan = '';
805: my $rightcolspan = '';
806: if (($action eq 'rolecolors') || ($action eq 'defaults') ||
807: ($action eq 'directorysrch') ||
808: (($action eq 'login') && ($numheaders < 4))) {
809: $colspan = ' colspan="2"';
810: }
811: if ($action eq 'usersessions') {
812: $rightcolspan = ' colspan="3"';
813: }
814: $output .= '
815: <tr>
816: <td>
817: <table class="LC_nested">
818: <tr class="LC_info_row">
819: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[0]->{'col1'}).'</td>
820: <td class="LC_right_item"'.$rightcolspan.'>'.&mt($item->{'header'}->[0]->{'col2'}).'</td>
821: </tr>';
822: $rowtotal ++;
823: if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') ||
824: ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') ||
825: ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') ||
826: ($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') ||
827: ($action eq 'contacts')) {
828: $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal);
829: } elsif ($action eq 'coursecategories') {
830: $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal);
831: } elsif ($action eq 'login') {
832: if ($numheaders == 4) {
833: $colspan = ' colspan="2"';
834: $output .= &print_login('service',$dom,$confname,$phase,$settings,\$rowtotal);
835: } else {
836: $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal);
837: }
838: } elsif (($action eq 'requestcourses') || ($action eq 'requestauthor')) {
839: $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
840: } elsif ($action eq 'rolecolors') {
841: $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal);
842: }
843: $output .= '
844: </table>
845: </td>
846: </tr>
847: <tr>
848: <td>
849: <table class="LC_nested">
850: <tr class="LC_info_row">
851: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col1'}).'</td>
852: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col2'}).'</td>
853: </tr>';
854: $rowtotal ++;
855: if (($action eq 'autoupdate') || ($action eq 'usercreation') ||
856: ($action eq 'selfcreation') || ($action eq 'selfenrollment') ||
857: ($action eq 'usersessions') || ($action eq 'coursecategories') ||
858: ($action eq 'trust') || ($action eq 'contacts') || ($action eq 'defaults')) {
859: if ($action eq 'coursecategories') {
860: $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal);
861: $colspan = ' colspan="2"';
862: } elsif ($action eq 'trust') {
863: $output .= $item->{'print'}->('shared',$dom,$settings,\$rowtotal);
864: } else {
865: $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal);
866: }
867: if ($action eq 'trust') {
868: $output .= '
869: </table>
870: </td>
871: </tr>';
872: my @trusthdrs = qw(2 3 4 5 6 7);
873: my @prefixes = qw(enroll othcoau coaurem domroles catalog reqcrs);
874: for (my $i=0; $i<@trusthdrs; $i++) {
875: $output .= '
876: <tr>
877: <td>
878: <table class="LC_nested">
879: <tr class="LC_info_row">
880: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col1'}).'</td>
881: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col2'}).'</td></tr>'.
882: $item->{'print'}->($prefixes[$i],$dom,$settings,\$rowtotal).'
883: </table>
884: </td>
885: </tr>';
886: }
887: $output .= '
888: <tr>
889: <td>
890: <table class="LC_nested">
891: <tr class="LC_info_row">
892: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col1'}).'</td>
893: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col2'}).'</td></tr>'.
894: $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
895: } else {
896: $output .= '
897: </table>
898: </td>
899: </tr>
900: <tr>
901: <td>
902: <table class="LC_nested">
903: <tr class="LC_info_row">
904: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
905: <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
906: </tr>'."\n";
907: if ($action eq 'coursecategories') {
908: $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal);
909: } elsif ($action eq 'contacts') {
910: $output .= $item->{'print'}->('lower',$dom,$settings,\$rowtotal).'
911: </tr>
912: </table>
913: </td>
914: </tr>
915: <tr>
916: <td>
917: <table class="LC_nested">
918: <tr class="LC_info_row">
919: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
920: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'.
921: $item->{'print'}->('bottom',$dom,$settings,\$rowtotal).'
922: </table>
923: </td>
924: </tr>
925: <tr>';
926: } else {
927: $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
928: }
929: }
930: $rowtotal ++;
931: } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') ||
932: ($action eq 'defaults') || ($action eq 'directorysrch') ||
933: ($action eq 'helpsettings')) {
934: $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
935: } elsif ($action eq 'ssl') {
936: $output .= $item->{'print'}->('connto',$dom,$settings,\$rowtotal).'
937: </table>
938: </td>
939: </tr>
940: <tr>
941: <td>
942: <table class="LC_nested">
943: <tr class="LC_info_row">
944: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
945: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td></tr>'.
946: $item->{'print'}->('connfrom',$dom,$settings,\$rowtotal).'
947: </table>
948: </td>
949: </tr>
950: <tr>
951: <td>
952: <table class="LC_nested">
953: <tr class="LC_info_row">
954: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
955: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'.
956: $item->{'print'}->('bottom',$dom,$settings,\$rowtotal);
957: } elsif ($action eq 'login') {
958: if ($numheaders == 4) {
959: $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).'
960: </table>
961: </td>
962: </tr>
963: <tr>
964: <td>
965: <table class="LC_nested">
966: <tr class="LC_info_row">
967: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
968: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td></tr>'.
969: &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);
970: $rowtotal ++;
971: } else {
972: $output .= &print_login('help',$dom,$confname,$phase,$settings,\$rowtotal);
973: }
974: $output .= '
975: </table>
976: </td>
977: </tr>
978: <tr>
979: <td>
980: <table class="LC_nested">
981: <tr class="LC_info_row">';
982: if ($numheaders == 4) {
983: $output .= '
984: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
985: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td>
986: </tr>';
987: } else {
988: $output .= '
989: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
990: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td>
991: </tr>';
992: }
993: $rowtotal ++;
994: $output .= &print_login('headtag',$dom,$confname,$phase,$settings,\$rowtotal);
995: } elsif ($action eq 'requestcourses') {
996: $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);
997: $rowtotal ++;
998: $output .= &print_studentcode($settings,\$rowtotal).'
999: </table>
1000: </td>
1001: </tr>
1002: <tr>
1003: <td>
1004: <table class="LC_nested">
1005: <tr class="LC_info_row">
1006: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td>
1007: <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td> </tr>'.
1008: &textbookcourses_javascript($settings).
1009: &print_textbookcourses($dom,'textbooks',$settings,\$rowtotal).'
1010: </table>
1011: </td>
1012: </tr>
1013: <tr>
1014: <td>
1015: <table class="LC_nested">
1016: <tr class="LC_info_row">
1017: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
1018: <td class="LC_right_item">'.&mt($item->{'header'}->[3]->{'col2'}).'</td> </tr>'.
1019: &print_textbookcourses($dom,'templates',$settings,\$rowtotal).'
1020: </table>
1021: </td>
1022: </tr>
1023: <tr>
1024: <td>
1025: <table class="LC_nested">
1026: <tr class="LC_info_row">
1027: <td class="LC_left_item"'.$colspan.' style="vertical-align: top">'.&mt($item->{'header'}->[4]->{'col1'}).'</td>
1028: <td class="LC_right_item" style="vertical-align: top">'.&mt($item->{'header'}->[4]->{'col2'}).'</td>
1029: </tr>'.
1030: &print_validation_rows('requestcourses',$dom,$settings,\$rowtotal);
1031: } elsif ($action eq 'requestauthor') {
1032: $output .= &print_requestmail($dom,$action,$settings,\$rowtotal);
1033: $rowtotal ++;
1034: } elsif ($action eq 'rolecolors') {
1035: $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).'
1036: </table>
1037: </td>
1038: </tr>
1039: <tr>
1040: <td>
1041: <table class="LC_nested">
1042: <tr class="LC_info_row">
1043: <td class="LC_left_item"'.$colspan.' style="vertical-align: top">'.
1044: &mt($item->{'header'}->[2]->{'col1'}).'</td>
1045: <td class="LC_right_item" style="vertical-align: top">'.
1046: &mt($item->{'header'}->[2]->{'col2'}).'</td>
1047: </tr>'.
1048: &print_rolecolors($phase,'author',$dom,$confname,$settings,\$rowtotal).'
1049: </table>
1050: </td>
1051: </tr>
1052: <tr>
1053: <td>
1054: <table class="LC_nested">
1055: <tr class="LC_info_row">
1056: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td>
1057: <td class="LC_right_item">'.&mt($item->{'header'}->[3]->{'col2'}).'</td>
1058: </tr>'.
1059: &print_rolecolors($phase,'admin',$dom,$confname,$settings,\$rowtotal);
1060: $rowtotal += 2;
1061: }
1062: } else {
1063: $output .= '
1064: <tr>
1065: <td>
1066: <table class="LC_nested">
1067: <tr class="LC_info_row">';
1068: if ($action eq 'login') {
1069: $output .= '
1070: <td class="LC_left_item" colspan="2">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
1071: } elsif ($action eq 'serverstatuses') {
1072: $output .= '
1073: <td class="LC_left_item" style="vertical-align: top">'.&mt($item->{'header'}->[0]->{'col1'}).
1074: '<br />('.&mt('Automatic access for Dom. Coords.').')</td>';
1075:
1076: } else {
1077: $output .= '
1078: <td class="LC_left_item" style="vertical-align: top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>';
1079: }
1080: if (defined($item->{'header'}->[0]->{'col3'})) {
1081: $output .= '<td class="LC_left_item" style="vertical-align: top">'.
1082: &mt($item->{'header'}->[0]->{'col2'});
1083: if ($action eq 'serverstatuses') {
1084: $output .= '<br />(<tt>'.&mt('user1:domain1,user2:domain2 etc.').'</tt>)';
1085: }
1086: } else {
1087: $output .= '<td class="LC_right_item" style="vertical-align: top">'.
1088: &mt($item->{'header'}->[0]->{'col2'});
1089: }
1090: $output .= '</td>';
1091: if ($item->{'header'}->[0]->{'col3'}) {
1092: if (defined($item->{'header'}->[0]->{'col4'})) {
1093: $output .= '<td class="LC_left_item" style="vertical-align: top">'.
1094: &mt($item->{'header'}->[0]->{'col3'});
1095: } else {
1096: $output .= '<td class="LC_right_item" style="vertical-align: top">'.
1097: &mt($item->{'header'}->[0]->{'col3'});
1098: }
1099: if ($action eq 'serverstatuses') {
1100: $output .= '<br />(<tt>'.&mt('IP1,IP2 etc.').'</tt>)';
1101: }
1102: $output .= '</td>';
1103: }
1104: if ($item->{'header'}->[0]->{'col4'}) {
1105: $output .= '<td class="LC_right_item" style="vertical-align: top">'.
1106: &mt($item->{'header'}->[0]->{'col4'});
1107: }
1108: $output .= '</tr>';
1109: $rowtotal ++;
1110: if ($action eq 'quotas') {
1111: $output .= &print_quotas($dom,$settings,\$rowtotal,$action);
1112: } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') ||
1113: ($action eq 'serverstatuses') || ($action eq 'loadbalancing') ||
1114: ($action eq 'ltitools') || ($action eq 'lti')) {
1115: $output .= $item->{'print'}->($dom,$settings,\$rowtotal);
1116: } elsif ($action eq 'scantron') {
1117: $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal);
1118: }
1119: }
1120: $output .= '
1121: </table>
1122: </td>
1123: </tr>
1124: </table><br />';
1125: return ($output,$rowtotal);
1126: }
1127:
1128: sub print_login {
1129: my ($caller,$dom,$confname,$phase,$settings,$rowtotal) = @_;
1130: my ($css_class,$datatable);
1131: my %choices = &login_choices();
1132:
1133: if ($caller eq 'service') {
1134: my %servers = &Apache::lonnet::internet_dom_servers($dom);
1135: my $choice = $choices{'disallowlogin'};
1136: $css_class = ' class="LC_odd_row"';
1137: $datatable .= '<tr'.$css_class.'><td>'.$choice.'</td>'.
1138: '<td style="text-align: right"><table><tr><th>'.$choices{'hostid'}.'</th>'.
1139: '<th>'.$choices{'server'}.'</th>'.
1140: '<th>'.$choices{'serverpath'}.'</th>'.
1141: '<th>'.$choices{'custompath'}.'</th>'.
1142: '<th><span class="LC_nobreak">'.$choices{'exempt'}.'</span></th></tr>'."\n";
1143: my %disallowed;
1144: if (ref($settings) eq 'HASH') {
1145: if (ref($settings->{'loginvia'}) eq 'HASH') {
1146: %disallowed = %{$settings->{'loginvia'}};
1147: }
1148: }
1149: foreach my $lonhost (sort(keys(%servers))) {
1150: my $direct = 'selected="selected"';
1151: if (ref($disallowed{$lonhost}) eq 'HASH') {
1152: if ($disallowed{$lonhost}{'server'} ne '') {
1153: $direct = '';
1154: }
1155: }
1156: $datatable .= '<tr><td>'.$servers{$lonhost}.'</td>'.
1157: '<td><select name="'.$lonhost.'_server">'.
1158: '<option value=""'.$direct.'>'.$choices{'directlogin'}.
1159: '</option>';
1160: foreach my $hostid (sort(keys(%servers))) {
1161: next if ($servers{$hostid} eq $servers{$lonhost});
1162: my $selected = '';
1163: if (ref($disallowed{$lonhost}) eq 'HASH') {
1164: if ($hostid eq $disallowed{$lonhost}{'server'}) {
1165: $selected = 'selected="selected"';
1166: }
1167: }
1168: $datatable .= '<option value="'.$hostid.'"'.$selected.'>'.
1169: $servers{$hostid}.'</option>';
1170: }
1171: $datatable .= '</select></td>'.
1172: '<td><select name="'.$lonhost.'_serverpath">';
1173: foreach my $path ('','/','/adm/login','/adm/roles','custom') {
1174: my $pathname = $path;
1175: if ($path eq 'custom') {
1176: $pathname = &mt('Custom Path').' ->';
1177: }
1178: my $selected = '';
1179: if (ref($disallowed{$lonhost}) eq 'HASH') {
1180: if ($path eq $disallowed{$lonhost}{'serverpath'}) {
1181: $selected = 'selected="selected"';
1182: }
1183: } elsif ($path eq '') {
1184: $selected = 'selected="selected"';
1185: }
1186: $datatable .= '<option value="'.$path.'"'.$selected.'>'.$pathname.'</option>';
1187: }
1188: $datatable .= '</select></td>';
1189: my ($custom,$exempt);
1190: if (ref($disallowed{$lonhost}) eq 'HASH') {
1191: $custom = $disallowed{$lonhost}{'custompath'};
1192: $exempt = $disallowed{$lonhost}{'exempt'};
1193: }
1194: $datatable .= '<td><input type="text" name="'.$lonhost.'_custompath" size="6" value="'.$custom.'" /></td>'.
1195: '<td><input type="text" name="'.$lonhost.'_exempt" size="8" value="'.$exempt.'" /></td>'.
1196: '</tr>';
1197: }
1198: $datatable .= '</table></td></tr>';
1199: return $datatable;
1200: } elsif ($caller eq 'page') {
1201: my %defaultchecked = (
1202: 'coursecatalog' => 'on',
1203: 'helpdesk' => 'on',
1204: 'adminmail' => 'off',
1205: 'newuser' => 'off',
1206: );
1207: my @toggles = ('coursecatalog','adminmail','helpdesk','newuser');
1208: my (%checkedon,%checkedoff);
1209: foreach my $item (@toggles) {
1210: if ($defaultchecked{$item} eq 'on') {
1211: $checkedon{$item} = ' checked="checked" ';
1212: $checkedoff{$item} = ' ';
1213: } elsif ($defaultchecked{$item} eq 'off') {
1214: $checkedoff{$item} = ' checked="checked" ';
1215: $checkedon{$item} = ' ';
1216: }
1217: }
1218: my @images = ('img','logo','domlogo','login');
1219: my @logintext = ('textcol','bgcol');
1220: my @bgs = ('pgbg','mainbg','sidebg');
1221: my @links = ('link','alink','vlink');
1222: my %designhash = &Apache::loncommon::get_domainconf($dom);
1223: my %defaultdesign = %Apache::loncommon::defaultdesign;
1224: my (%is_custom,%designs);
1225: my %defaults = (
1226: font => $defaultdesign{'login.font'},
1227: );
1228: foreach my $item (@images) {
1229: $defaults{$item} = $defaultdesign{'login.'.$item};
1230: $defaults{'showlogo'}{$item} = 1;
1231: }
1232: foreach my $item (@bgs) {
1233: $defaults{'bgs'}{$item} = $defaultdesign{'login.'.$item};
1234: }
1235: foreach my $item (@logintext) {
1236: $defaults{'logintext'}{$item} = $defaultdesign{'login.'.$item};
1237: }
1238: foreach my $item (@links) {
1239: $defaults{'links'}{$item} = $defaultdesign{'login.'.$item};
1240: }
1241: if (ref($settings) eq 'HASH') {
1242: foreach my $item (@toggles) {
1243: if ($settings->{$item} eq '1') {
1244: $checkedon{$item} = ' checked="checked" ';
1245: $checkedoff{$item} = ' ';
1246: } elsif ($settings->{$item} eq '0') {
1247: $checkedoff{$item} = ' checked="checked" ';
1248: $checkedon{$item} = ' ';
1249: }
1250: }
1251: foreach my $item (@images) {
1252: if (defined($settings->{$item})) {
1253: $designs{$item} = $settings->{$item};
1254: $is_custom{$item} = 1;
1255: }
1256: if (defined($settings->{'showlogo'}{$item})) {
1257: $designs{'showlogo'}{$item} = $settings->{'showlogo'}{$item};
1258: }
1259: }
1260: foreach my $item (@logintext) {
1261: if ($settings->{$item} ne '') {
1262: $designs{'logintext'}{$item} = $settings->{$item};
1263: $is_custom{$item} = 1;
1264: }
1265: }
1266: if ($settings->{'font'} ne '') {
1267: $designs{'font'} = $settings->{'font'};
1268: $is_custom{'font'} = 1;
1269: }
1270: foreach my $item (@bgs) {
1271: if ($settings->{$item} ne '') {
1272: $designs{'bgs'}{$item} = $settings->{$item};
1273: $is_custom{$item} = 1;
1274: }
1275: }
1276: foreach my $item (@links) {
1277: if ($settings->{$item} ne '') {
1278: $designs{'links'}{$item} = $settings->{$item};
1279: $is_custom{$item} = 1;
1280: }
1281: }
1282: } else {
1283: if ($designhash{$dom.'.login.font'} ne '') {
1284: $designs{'font'} = $designhash{$dom.'.login.font'};
1285: $is_custom{'font'} = 1;
1286: }
1287: foreach my $item (@images) {
1288: if ($designhash{$dom.'.login.'.$item} ne '') {
1289: $designs{$item} = $designhash{$dom.'.login.'.$item};
1290: $is_custom{$item} = 1;
1291: }
1292: }
1293: foreach my $item (@bgs) {
1294: if ($designhash{$dom.'.login.'.$item} ne '') {
1295: $designs{'bgs'}{$item} = $designhash{$dom.'.login.'.$item};
1296: $is_custom{$item} = 1;
1297: }
1298: }
1299: foreach my $item (@links) {
1300: if ($designhash{$dom.'.login.'.$item} ne '') {
1301: $designs{'links'}{$item} = $designhash{$dom.'.login.'.$item};
1302: $is_custom{$item} = 1;
1303: }
1304: }
1305: }
1306: my %alt_text = &Apache::lonlocal::texthash ( img => 'Log-in banner',
1307: logo => 'Institution Logo',
1308: domlogo => 'Domain Logo',
1309: login => 'Login box');
1310: my $itemcount = 1;
1311: foreach my $item (@toggles) {
1312: $css_class = $itemcount%2?' class="LC_odd_row"':'';
1313: $datatable .=
1314: '<tr'.$css_class.'><td colspan="2">'.$choices{$item}.
1315: '</td><td>'.
1316: '<span class="LC_nobreak"><label><input type="radio" name="'.
1317: $item.'"'.$checkedon{$item}.' value="1" />'.&mt('Yes').
1318: '</label> <label><input type="radio" name="'.$item.'"'.
1319: $checkedoff{$item}.' value="0" />'.&mt('No').'</label></span></td>'.
1320: '</tr>';
1321: $itemcount ++;
1322: }
1323: $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal,\@logintext);
1324: $datatable .= '</tr></table></td></tr>';
1325: } elsif ($caller eq 'help') {
1326: my ($defaulturl,$defaulttype,%url,%type,%lt,%langchoices);
1327: my $switchserver = &check_switchserver($dom,$confname);
1328: my $itemcount = 1;
1329: $defaulturl = '/adm/loginproblems.html';
1330: $defaulttype = 'default';
1331: %lt = &Apache::lonlocal::texthash (
1332: del => 'Delete?',
1333: rep => 'Replace:',
1334: upl => 'Upload:',
1335: default => 'Default',
1336: custom => 'Custom',
1337: );
1338: %langchoices = &Apache::lonlocal::texthash(&get_languages_hash());
1339: my @currlangs;
1340: if (ref($settings) eq 'HASH') {
1341: if (ref($settings->{'helpurl'}) eq 'HASH') {
1342: foreach my $key (sort(keys(%{$settings->{'helpurl'}}))) {
1343: next if ($settings->{'helpurl'}{$key} eq '');
1344: $url{$key} = $settings->{'helpurl'}{$key}.'?inhibitmenu=yes';
1345: $type{$key} = 'custom';
1346: unless ($key eq 'nolang') {
1347: push(@currlangs,$key);
1348: }
1349: }
1350: } elsif ($settings->{'helpurl'} ne '') {
1351: $type{'nolang'} = 'custom';
1352: $url{'nolang'} = $settings->{'helpurl'}.'?inhibitmenu=yes';
1353: }
1354: }
1355: foreach my $lang ('nolang',sort(@currlangs)) {
1356: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
1357: $datatable .= '<tr'.$css_class.'>';
1358: if ($url{$lang} eq '') {
1359: $url{$lang} = $defaulturl;
1360: }
1361: if ($type{$lang} eq '') {
1362: $type{$lang} = $defaulttype;
1363: }
1364: $datatable .= '<td colspan="2"><span class="LC_nobreak">';
1365: if ($lang eq 'nolang') {
1366: $datatable .= &mt('Log-in help page if no specific language file: [_1]',
1367: &Apache::loncommon::modal_link($url{$lang},$lt{$type{$lang}},600,500));
1368: } else {
1369: $datatable .= &mt('Log-in help page for language: [_1] is [_2]',
1370: $langchoices{$lang},
1371: &Apache::loncommon::modal_link($url{$lang},$lt{$type{$lang}},600,500));
1372: }
1373: $datatable .= '</span></td>'."\n".
1374: '<td class="LC_left_item">';
1375: if ($type{$lang} eq 'custom') {
1376: $datatable .= '<span class="LC_nobreak"><label>'.
1377: '<input type="checkbox" name="loginhelpurl_del" value="'.$lang.'" />'.
1378: $lt{'del'}.'</label> '.$lt{'rep'}.'</span>';
1379: } else {
1380: $datatable .= $lt{'upl'};
1381: }
1382: $datatable .='<br />';
1383: if ($switchserver) {
1384: $datatable .= &mt('Upload to library server: [_1]',$switchserver);
1385: } else {
1386: $datatable .= '<input type="file" name="loginhelpurl_'.$lang.'" />';
1387: }
1388: $datatable .= '</td></tr>';
1389: $itemcount ++;
1390: }
1391: my @addlangs;
1392: foreach my $lang (sort(keys(%langchoices))) {
1393: next if ((grep(/^\Q$lang\E$/,@currlangs)) || ($lang eq 'x_chef'));
1394: push(@addlangs,$lang);
1395: }
1396: if (@addlangs > 0) {
1397: my %toadd;
1398: map { $toadd{$_} = $langchoices{$_} ; } @addlangs;
1399: $toadd{''} = &mt('Select');
1400: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
1401: $datatable .= '<tr'.$css_class.'><td class="LC_left_item" colspan="2">'.
1402: &mt('Add log-in help page for a specific language:').' '.
1403: &Apache::loncommon::select_form('','loginhelpurl_add_lang',\%toadd).
1404: '</td><td class="LC_left_item">'.$lt{'upl'}.'<br />';
1405: if ($switchserver) {
1406: $datatable .= &mt('Upload to library server: [_1]',$switchserver);
1407: } else {
1408: $datatable .= '<input type="file" name="loginhelpurl_add_file" />';
1409: }
1410: $datatable .= '</td></tr>';
1411: $itemcount ++;
1412: }
1413: $datatable .= &captcha_choice('login',$settings,$itemcount);
1414: } elsif ($caller eq 'headtag') {
1415: my %domservers = &Apache::lonnet::get_servers($dom);
1416: my $choice = $choices{'headtag'};
1417: $css_class = ' class="LC_odd_row"';
1418: $datatable .= '<tr'.$css_class.'><td colspan="2">'.$choice.'</td>'.
1419: '<td style="text-align: left"><table><tr><th>'.$choices{'hostid'}.'</th>'.
1420: '<th>'.$choices{'current'}.'</th>'.
1421: '<th>'.$choices{'action'}.'</th>'.
1422: '<th>'.$choices{'exempt'}.'</th></tr>'."\n";
1423: my (%currurls,%currexempt);
1424: if (ref($settings) eq 'HASH') {
1425: if (ref($settings->{'headtag'}) eq 'HASH') {
1426: foreach my $lonhost (keys(%{$settings->{'headtag'}})) {
1427: if (ref($settings->{'headtag'}{$lonhost}) eq 'HASH') {
1428: $currurls{$lonhost} = $settings->{'headtag'}{$lonhost}{'url'};
1429: $currexempt{$lonhost} = $settings->{'headtag'}{$lonhost}{'exempt'};
1430: }
1431: }
1432: }
1433: }
1434: my %lt = &Apache::lonlocal::texthash(
1435: del => 'Delete?',
1436: rep => 'Replace:',
1437: upl => 'Upload:',
1438: curr => 'View contents',
1439: none => 'None',
1440: );
1441: my $switchserver = &check_switchserver($dom,$confname);
1442: foreach my $lonhost (sort(keys(%domservers))) {
1443: my $exempt = &check_exempt_addresses($currexempt{$lonhost});
1444: $datatable .= '<tr><td>'.$domservers{$lonhost}.'</td>';
1445: if ($currurls{$lonhost}) {
1446: $datatable .= '<td class="LC_right_item"><a href="'.
1447: "javascript:void(open('$currurls{$lonhost}?inhibitmenu=yes','Custom_HeadTag',
1448: 'menubar=0,toolbar=1,scrollbars=1,width=600,height=500,resizable=yes'))".
1449: '">'.$lt{'curr'}.'</a></td>'.
1450: '<td><span class="LC_nobreak"><label>'.
1451: '<input type="checkbox" name="loginheadtag_del" value="'.$lonhost.'" />'.
1452: $lt{'del'}.'</label> '.$lt{'rep'}.'</span>';
1453: } else {
1454: $datatable .= '<td class="LC_right_item">'.$lt{'none'}.'</td><td>'.$lt{'upl'};
1455: }
1456: $datatable .='<br />';
1457: if ($switchserver) {
1458: $datatable .= &mt('Upload to library server: [_1]',$switchserver);
1459: } else {
1460: $datatable .= '<input type="file" name="loginheadtag_'.$lonhost.'" />';
1461: }
1462: $datatable .= '</td><td><input type="text" name="loginheadtagexempt_'.$lonhost.'" value="'.$exempt.'" /></td></tr>';
1463: }
1464: $datatable .= '</table></td></tr>';
1465: }
1466: return $datatable;
1467: }
1468:
1469: sub login_choices {
1470: my %choices =
1471: &Apache::lonlocal::texthash (
1472: coursecatalog => 'Display Course/Community Catalog link?',
1473: adminmail => "Display Administrator's E-mail Address?",
1474: helpdesk => 'Display "Contact Helpdesk" link',
1475: disallowlogin => "Login page requests redirected",
1476: hostid => "Server",
1477: server => "Redirect to:",
1478: serverpath => "Path",
1479: custompath => "Custom",
1480: exempt => "Exempt IP(s)",
1481: directlogin => "No redirect",
1482: newuser => "Link to create a user account",
1483: img => "Header",
1484: logo => "Main Logo",
1485: domlogo => "Domain Logo",
1486: login => "Log-in Header",
1487: textcol => "Text color",
1488: bgcol => "Box color",
1489: bgs => "Background colors",
1490: links => "Link colors",
1491: font => "Font color",
1492: pgbg => "Header",
1493: mainbg => "Page",
1494: sidebg => "Login box",
1495: link => "Link",
1496: alink => "Active link",
1497: vlink => "Visited link",
1498: headtag => "Custom markup",
1499: action => "Action",
1500: current => "Current",
1501: );
1502: return %choices;
1503: }
1504:
1505: sub print_rolecolors {
1506: my ($phase,$role,$dom,$confname,$settings,$rowtotal) = @_;
1507: my %choices = &color_font_choices();
1508: my @bgs = ('pgbg','tabbg','sidebg');
1509: my @links = ('link','alink','vlink');
1510: my @images = ('img');
1511: my %alt_text = &Apache::lonlocal::texthash(img => "Banner for $role role");
1512: my %designhash = &Apache::loncommon::get_domainconf($dom);
1513: my %defaultdesign = %Apache::loncommon::defaultdesign;
1514: my (%is_custom,%designs);
1515: my %defaults = &role_defaults($role,\@bgs,\@links,\@images);
1516: if (ref($settings) eq 'HASH') {
1517: if (ref($settings->{$role}) eq 'HASH') {
1518: if ($settings->{$role}->{'img'} ne '') {
1519: $designs{'img'} = $settings->{$role}->{'img'};
1520: $is_custom{'img'} = 1;
1521: }
1522: if ($settings->{$role}->{'font'} ne '') {
1523: $designs{'font'} = $settings->{$role}->{'font'};
1524: $is_custom{'font'} = 1;
1525: }
1526: if ($settings->{$role}->{'fontmenu'} ne '') {
1527: $designs{'fontmenu'} = $settings->{$role}->{'fontmenu'};
1528: $is_custom{'fontmenu'} = 1;
1529: }
1530: foreach my $item (@bgs) {
1531: if ($settings->{$role}->{$item} ne '') {
1532: $designs{'bgs'}{$item} = $settings->{$role}->{$item};
1533: $is_custom{$item} = 1;
1534: }
1535: }
1536: foreach my $item (@links) {
1537: if ($settings->{$role}->{$item} ne '') {
1538: $designs{'links'}{$item} = $settings->{$role}->{$item};
1539: $is_custom{$item} = 1;
1540: }
1541: }
1542: }
1543: } else {
1544: if ($designhash{$dom.'.'.$role.'.img'} ne '') {
1545: $designs{img} = $designhash{$dom.'.'.$role.'.img'};
1546: $is_custom{'img'} = 1;
1547: }
1548: if ($designhash{$dom.'.'.$role.'.fontmenu'} ne '') {
1549: $designs{fontmenu} = $designhash{$dom.'.'.$role.'.fontmenu'};
1550: $is_custom{'fontmenu'} = 1;
1551: }
1552: if ($designhash{$dom.'.'.$role.'.font'} ne '') {
1553: $designs{font} = $designhash{$dom.'.'.$role.'.font'};
1554: $is_custom{'font'} = 1;
1555: }
1556: foreach my $item (@bgs) {
1557: if ($designhash{$dom.'.'.$role.'.'.$item} ne '') {
1558: $designs{'bgs'}{$item} = $designhash{$dom.'.'.$role.'.'.$item};
1559: $is_custom{$item} = 1;
1560:
1561: }
1562: }
1563: foreach my $item (@links) {
1564: if ($designhash{$dom.'.'.$role.'.'.$item} ne '') {
1565: $designs{'links'}{$item} = $designhash{$dom.'.'.$role.'.'.$item};
1566: $is_custom{$item} = 1;
1567: }
1568: }
1569: }
1570: my $itemcount = 1;
1571: my $datatable = &display_color_options($dom,$confname,$phase,$role,$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal);
1572: $datatable .= '</tr></table></td></tr>';
1573: return $datatable;
1574: }
1575:
1576: sub role_defaults {
1577: my ($role,$bgs,$links,$images,$logintext) = @_;
1578: my %defaults;
1579: unless ((ref($bgs) eq 'ARRAY') && (ref($links) eq 'ARRAY') && (ref($images) eq 'ARRAY')) {
1580: return %defaults;
1581: }
1582: my %defaultdesign = %Apache::loncommon::defaultdesign;
1583: if ($role eq 'login') {
1584: %defaults = (
1585: font => $defaultdesign{$role.'.font'},
1586: );
1587: if (ref($logintext) eq 'ARRAY') {
1588: foreach my $item (@{$logintext}) {
1589: $defaults{'logintext'}{$item} = $defaultdesign{$role.'.'.$item};
1590: }
1591: }
1592: foreach my $item (@{$images}) {
1593: $defaults{'showlogo'}{$item} = 1;
1594: }
1595: } else {
1596: %defaults = (
1597: img => $defaultdesign{$role.'.img'},
1598: font => $defaultdesign{$role.'.font'},
1599: fontmenu => $defaultdesign{$role.'.fontmenu'},
1600: );
1601: }
1602: foreach my $item (@{$bgs}) {
1603: $defaults{'bgs'}{$item} = $defaultdesign{$role.'.'.$item};
1604: }
1605: foreach my $item (@{$links}) {
1606: $defaults{'links'}{$item} = $defaultdesign{$role.'.'.$item};
1607: }
1608: foreach my $item (@{$images}) {
1609: $defaults{$item} = $defaultdesign{$role.'.'.$item};
1610: }
1611: return %defaults;
1612: }
1613:
1614: sub display_color_options {
1615: my ($dom,$confname,$phase,$role,$itemcount,$choices,$is_custom,$defaults,$designs,
1616: $images,$bgs,$links,$alt_text,$rowtotal,$logintext) = @_;
1617: my $londocroot = $Apache::lonnet::perlvar{'lonDocRoot'};
1618: my $css_class = $itemcount%2?' class="LC_odd_row"':'';
1619: my $datatable = '<tr'.$css_class.'>'.
1620: '<td>'.$choices->{'font'}.'</td>';
1621: if (!$is_custom->{'font'}) {
1622: $datatable .= '<td>'.&mt('Default in use:').' <span class="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>';
1623: } else {
1624: $datatable .= '<td> </td>';
1625: }
1626: my $current_color = $designs->{'font'} ? $designs->{'font'} : $defaults->{'font'};
1627:
1628: $datatable .= '<td><span class="LC_nobreak">'.
1629: '<input type="text" class="colorchooser" size="10" name="'.$role.'_font"'.
1630: ' value="'.$current_color.'" /> '.
1631: ' </span></td></tr>';
1632: unless ($role eq 'login') {
1633: $datatable .= '<tr'.$css_class.'>'.
1634: '<td>'.$choices->{'fontmenu'}.'</td>';
1635: if (!$is_custom->{'fontmenu'}) {
1636: $datatable .= '<td>'.&mt('Default in use:').' <span class="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>';
1637: } else {
1638: $datatable .= '<td> </td>';
1639: }
1640: $current_color = $designs->{'fontmenu'} ?
1641: $designs->{'fontmenu'} : $defaults->{'fontmenu'};
1642: $datatable .= '<td><span class="LC_nobreak">'.
1643: '<input class="colorchooser" type="text" size="10" name="'
1644: .$role.'_fontmenu"'.
1645: ' value="'.$current_color.'" /> '.
1646: ' </span></td></tr>';
1647: }
1648: my $switchserver = &check_switchserver($dom,$confname);
1649: foreach my $img (@{$images}) {
1650: $itemcount ++;
1651: $css_class = $itemcount%2?' class="LC_odd_row"':'';
1652: $datatable .= '<tr'.$css_class.'>'.
1653: '<td>'.$choices->{$img};
1654: my ($imgfile,$img_import,$login_hdr_pick,$logincolors);
1655: if ($role eq 'login') {
1656: if ($img eq 'login') {
1657: $login_hdr_pick =
1658: &login_header_options($img,$role,$defaults,$is_custom,$choices);
1659: $logincolors =
1660: &login_text_colors($img,$role,$logintext,$phase,$choices,
1661: $designs,$defaults);
1662: } elsif ($img ne 'domlogo') {
1663: $datatable.= &logo_display_options($img,$defaults,$designs);
1664: }
1665: }
1666: $datatable .= '</td>';
1667: if ($designs->{$img} ne '') {
1668: $imgfile = $designs->{$img};
1669: $img_import = ($imgfile =~ m{^/adm/});
1670: } else {
1671: $imgfile = $defaults->{$img};
1672: }
1673: if ($imgfile) {
1674: my ($showfile,$fullsize);
1675: if ($imgfile =~ m-^(/res/\Q$dom\E/\Q$confname\E/\Q$img\E)/([^/]+)$-) {
1676: my $urldir = $1;
1677: my $filename = $2;
1678: my @info = &Apache::lonnet::stat_file($designs->{$img});
1679: if (@info) {
1680: my $thumbfile = 'tn-'.$filename;
1681: my @thumb=&Apache::lonnet::stat_file($urldir.'/'.$thumbfile);
1682: if (@thumb) {
1683: $showfile = $urldir.'/'.$thumbfile;
1684: } else {
1685: $showfile = $imgfile;
1686: }
1687: } else {
1688: $showfile = '';
1689: }
1690: } elsif ($imgfile =~ m-^/(adm/[^/]+)/([^/]+)$-) {
1691: $showfile = $imgfile;
1692: my $imgdir = $1;
1693: my $filename = $2;
1694: if (-e "$londocroot/$imgdir/tn-".$filename) {
1695: $showfile = "/$imgdir/tn-".$filename;
1696: } else {
1697: my $input = $londocroot.$imgfile;
1698: my $output = "$londocroot/$imgdir/tn-".$filename;
1699: if (!-e $output) {
1700: my ($width,$height) = &thumb_dimensions();
1701: my ($fullwidth,$fullheight) = &check_dimensions($input);
1702: if ($fullwidth ne '' && $fullheight ne '') {
1703: if ($fullwidth > $width && $fullheight > $height) {
1704: my $size = $width.'x'.$height;
1705: my @args = ('convert','-sample',$size,$input,$output);
1706: system({$args[0]} @args);
1707: $showfile = "/$imgdir/tn-".$filename;
1708: }
1709: }
1710: }
1711: }
1712: }
1713: if ($showfile) {
1714: if ($showfile =~ m{^/(adm|res)/}) {
1715: if ($showfile =~ m{^/res/}) {
1716: my $local_showfile =
1717: &Apache::lonnet::filelocation('',$showfile);
1718: &Apache::lonnet::repcopy($local_showfile);
1719: }
1720: $showfile = &Apache::loncommon::lonhttpdurl($showfile);
1721: }
1722: if ($imgfile) {
1723: if ($imgfile =~ m{^/(adm|res)/}) {
1724: if ($imgfile =~ m{^/res/}) {
1725: my $local_imgfile =
1726: &Apache::lonnet::filelocation('',$imgfile);
1727: &Apache::lonnet::repcopy($local_imgfile);
1728: }
1729: $fullsize = &Apache::loncommon::lonhttpdurl($imgfile);
1730: } else {
1731: $fullsize = $imgfile;
1732: }
1733: }
1734: $datatable .= '<td>';
1735: if ($img eq 'login') {
1736: $datatable .= $login_hdr_pick;
1737: }
1738: $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import,
1739: $showfile,$fullsize,$role,$img,$imgfile,$logincolors);
1740: } else {
1741: $datatable .= '<td> </td><td class="LC_left_item">'.
1742: &mt('Upload:').'<br />';
1743: }
1744: } else {
1745: $datatable .= '<td> </td><td class="LC_left_item">'.
1746: &mt('Upload:').'<br />';
1747: }
1748: if ($switchserver) {
1749: $datatable .= &mt('Upload to library server: [_1]',$switchserver);
1750: } else {
1751: if ($img ne 'login') { # suppress file selection for Log-in header
1752: $datatable .=' <input type="file" name="'.$role.'_'.$img.'" />';
1753: }
1754: }
1755: $datatable .= '</td></tr>';
1756: }
1757: $itemcount ++;
1758: $css_class = $itemcount%2?' class="LC_odd_row"':'';
1759: $datatable .= '<tr'.$css_class.'>'.
1760: '<td>'.$choices->{'bgs'}.'</td>';
1761: my $bgs_def;
1762: foreach my $item (@{$bgs}) {
1763: if (!$is_custom->{$item}) {
1764: $bgs_def .= '<td><span class="LC_nobreak">'.$choices->{$item}.'</span> <span class="css_default_'.$role.'_'.$item.'" style="background-color: '.$defaults->{'bgs'}{$item}.';"> </span><br />'.$defaults->{'bgs'}{$item}.'</td>';
1765: }
1766: }
1767: if ($bgs_def) {
1768: $datatable .= '<td>'.&mt('Default(s) in use:').'<br /><table border="0"><tr>'.$bgs_def.'</tr></table></td>';
1769: } else {
1770: $datatable .= '<td> </td>';
1771: }
1772: $datatable .= '<td class="LC_right_item">'.
1773: '<table border="0"><tr>';
1774:
1775: foreach my $item (@{$bgs}) {
1776: $datatable .= '<td style="text-align: center">'.$choices->{$item};
1777: my $color = $designs->{'bgs'}{$item} ? $designs->{'bgs'}{$item} : $defaults->{'bgs'}{$item};
1778: if ($designs->{'bgs'}{$item}) {
1779: $datatable .= ' ';
1780: }
1781: $datatable .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color.
1782: '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';
1783: }
1784: $datatable .= '</tr></table></td></tr>';
1785: $itemcount ++;
1786: $css_class = $itemcount%2?' class="LC_odd_row"':'';
1787: $datatable .= '<tr'.$css_class.'>'.
1788: '<td>'.$choices->{'links'}.'</td>';
1789: my $links_def;
1790: foreach my $item (@{$links}) {
1791: if (!$is_custom->{$item}) {
1792: $links_def .= '<td>'.$choices->{$item}.'<br /><span class="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>';
1793: }
1794: }
1795: if ($links_def) {
1796: $datatable .= '<td>'.&mt('Default(s) in use:').'<br /><table border="0"><tr>'.$links_def.'</tr></table></td>';
1797: } else {
1798: $datatable .= '<td> </td>';
1799: }
1800: $datatable .= '<td class="LC_right_item">'.
1801: '<table border="0"><tr>';
1802: foreach my $item (@{$links}) {
1803: my $color = $designs->{'links'}{$item} ? $designs->{'links'}{$item} : $defaults->{'links'}{$item};
1804: $datatable .= '<td style="text-align: center">'.$choices->{$item}."\n";
1805: if ($designs->{'links'}{$item}) {
1806: $datatable.=' ';
1807: }
1808: $datatable .= '<br /><input type="text" size="8" class="colorchooser" name="'.$role.'_'.$item.'" value="'.$color.
1809: '" /></td>';
1810: }
1811: $$rowtotal += $itemcount;
1812: return $datatable;
1813: }
1814:
1815: sub logo_display_options {
1816: my ($img,$defaults,$designs) = @_;
1817: my $checkedon;
1818: if (ref($defaults) eq 'HASH') {
1819: if (ref($defaults->{'showlogo'}) eq 'HASH') {
1820: if ($defaults->{'showlogo'}{$img}) {
1821: $checkedon = 'checked="checked" ';
1822: }
1823: }
1824: }
1825: if (ref($designs) eq 'HASH') {
1826: if (ref($designs->{'showlogo'}) eq 'HASH') {
1827: if (defined($designs->{'showlogo'}{$img})) {
1828: if ($designs->{'showlogo'}{$img} == 0) {
1829: $checkedon = '';
1830: } elsif ($designs->{'showlogo'}{$img} == 1) {
1831: $checkedon = 'checked="checked" ';
1832: }
1833: }
1834: }
1835: }
1836: return '<br /><label> <input type="checkbox" name="'.
1837: 'login_showlogo_'.$img.'" value="1" '.$checkedon.'/>'.
1838: &mt('show').'</label>'."\n";
1839: }
1840:
1841: sub login_header_options {
1842: my ($img,$role,$defaults,$is_custom,$choices) = @_;
1843: my $output = '';
1844: if ((!$is_custom->{'textcol'}) || (!$is_custom->{'bgcol'})) {
1845: $output .= &mt('Text default(s):').'<br />';
1846: if (!$is_custom->{'textcol'}) {
1847: $output .= $choices->{'textcol'}.': '.$defaults->{'logintext'}{'textcol'}.
1848: ' ';
1849: }
1850: if (!$is_custom->{'bgcol'}) {
1851: $output .= $choices->{'bgcol'}.': '.
1852: '<span id="css_'.$role.'_font" style="background-color: '.
1853: $defaults->{'logintext'}{'bgcol'}.';"> </span>';
1854: }
1855: $output .= '<br />';
1856: }
1857: $output .='<br />';
1858: return $output;
1859: }
1860:
1861: sub login_text_colors {
1862: my ($img,$role,$logintext,$phase,$choices,$designs,$defaults) = @_;
1863: my $color_menu = '<table border="0"><tr>';
1864: foreach my $item (@{$logintext}) {
1865: $color_menu .= '<td style="text-align: center">'.$choices->{$item};
1866: my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item};
1867: $color_menu .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color.
1868: '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>';
1869: }
1870: $color_menu .= '</tr></table><br />';
1871: return $color_menu;
1872: }
1873:
1874: sub image_changes {
1875: my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_;
1876: my $output;
1877: if ($img eq 'login') {
1878: $output = '</td><td>'.$logincolors; # suppress image for Log-in header
1879: } elsif (!$is_custom) {
1880: if ($img ne 'domlogo') {
1881: $output = &mt('Default image:').'<br />';
1882: } else {
1883: $output = &mt('Default in use:').'<br />';
1884: }
1885: }
1886: if ($img ne 'login') {
1887: if ($img_import) {
1888: $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />';
1889: }
1890: $output .= '<a href="'.$fullsize.'" target="_blank"><img src="'.
1891: $showfile.'" alt="'.$alt_text.'" border="0" /></a></td>';
1892: if ($is_custom) {
1893: $output .= '<td>'.$logincolors.'<span class="LC_nobreak"><label>'.
1894: '<input type="checkbox" name="'.
1895: $role.'_del_'.$img.'" value="1" />'.&mt('Delete?').
1896: '</label> '.&mt('Replace:').'</span><br />';
1897: } else {
1898: $output .= '<td class="LC_middle">'.$logincolors.&mt('Upload:').'<br />';
1899: }
1900: }
1901: return $output;
1902: }
1903:
1904: sub print_quotas {
1905: my ($dom,$settings,$rowtotal,$action) = @_;
1906: my $context;
1907: if ($action eq 'quotas') {
1908: $context = 'tools';
1909: } else {
1910: $context = $action;
1911: }
1912: my ($datatable,$defaultquota,$authorquota,@usertools,@options,%validations);
1913: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
1914: my $typecount = 0;
1915: my ($css_class,%titles);
1916: if ($context eq 'requestcourses') {
1917: @usertools = ('official','unofficial','community','textbook','placement','lti');
1918: @options =('norequest','approval','validate','autolimit');
1919: %validations = &Apache::lonnet::auto_courserequest_checks($dom);
1920: %titles = &courserequest_titles();
1921: } elsif ($context eq 'requestauthor') {
1922: @usertools = ('author');
1923: @options = ('norequest','approval','automatic');
1924: %titles = &authorrequest_titles();
1925: } else {
1926: @usertools = ('aboutme','blog','webdav','portfolio');
1927: %titles = &tool_titles();
1928: }
1929: if (ref($types) eq 'ARRAY') {
1930: foreach my $type (@{$types}) {
1931: my ($currdefquota,$currauthorquota);
1932: unless (($context eq 'requestcourses') ||
1933: ($context eq 'requestauthor')) {
1934: if (ref($settings) eq 'HASH') {
1935: if (ref($settings->{defaultquota}) eq 'HASH') {
1936: $currdefquota = $settings->{defaultquota}->{$type};
1937: } else {
1938: $currdefquota = $settings->{$type};
1939: }
1940: if (ref($settings->{authorquota}) eq 'HASH') {
1941: $currauthorquota = $settings->{authorquota}->{$type};
1942: }
1943: }
1944: }
1945: if (defined($usertypes->{$type})) {
1946: $typecount ++;
1947: $css_class = $typecount%2?' class="LC_odd_row"':'';
1948: $datatable .= '<tr'.$css_class.'>'.
1949: '<td>'.$usertypes->{$type}.'</td>'.
1950: '<td class="LC_left_item">';
1951: if ($context eq 'requestcourses') {
1952: $datatable .= '<table><tr>';
1953: }
1954: my %cell;
1955: foreach my $item (@usertools) {
1956: if ($context eq 'requestcourses') {
1957: my ($curroption,$currlimit);
1958: if (ref($settings) eq 'HASH') {
1959: if (ref($settings->{$item}) eq 'HASH') {
1960: $curroption = $settings->{$item}->{$type};
1961: if ($curroption =~ /^autolimit=(\d*)$/) {
1962: $currlimit = $1;
1963: }
1964: }
1965: }
1966: if (!$curroption) {
1967: $curroption = 'norequest';
1968: }
1969: $datatable .= '<th>'.$titles{$item}.'</th>';
1970: foreach my $option (@options) {
1971: my $val = $option;
1972: if ($option eq 'norequest') {
1973: $val = 0;
1974: }
1975: if ($option eq 'validate') {
1976: my $canvalidate = 0;
1977: if (ref($validations{$item}) eq 'HASH') {
1978: if ($validations{$item}{$type}) {
1979: $canvalidate = 1;
1980: }
1981: }
1982: next if (!$canvalidate);
1983: }
1984: my $checked = '';
1985: if ($option eq $curroption) {
1986: $checked = ' checked="checked"';
1987: } elsif ($option eq 'autolimit') {
1988: if ($curroption =~ /^autolimit/) {
1989: $checked = ' checked="checked"';
1990: }
1991: }
1992: $cell{$item} .= '<span class="LC_nobreak"><label>'.
1993: '<input type="radio" name="crsreq_'.$item.
1994: '_'.$type.'" value="'.$val.'"'.$checked.' />'.
1995: $titles{$option}.'</label>';
1996: if ($option eq 'autolimit') {
1997: $cell{$item} .= ' <input type="text" name="crsreq_'.
1998: $item.'_limit_'.$type.'" size="1" '.
1999: 'value="'.$currlimit.'" />';
2000: }
2001: $cell{$item} .= '</span> ';
2002: if ($option eq 'autolimit') {
2003: $cell{$item} .= $titles{'unlimited'};
2004: }
2005: }
2006: } elsif ($context eq 'requestauthor') {
2007: my $curroption;
2008: if (ref($settings) eq 'HASH') {
2009: $curroption = $settings->{$type};
2010: }
2011: if (!$curroption) {
2012: $curroption = 'norequest';
2013: }
2014: foreach my $option (@options) {
2015: my $val = $option;
2016: if ($option eq 'norequest') {
2017: $val = 0;
2018: }
2019: my $checked = '';
2020: if ($option eq $curroption) {
2021: $checked = ' checked="checked"';
2022: }
2023: $datatable .= '<span class="LC_nobreak"><label>'.
2024: '<input type="radio" name="authorreq_'.$type.
2025: '" value="'.$val.'"'.$checked.' />'.
2026: $titles{$option}.'</label></span> ';
2027: }
2028: } else {
2029: my $checked = 'checked="checked" ';
2030: if (ref($settings) eq 'HASH') {
2031: if (ref($settings->{$item}) eq 'HASH') {
2032: if ($settings->{$item}->{$type} == 0) {
2033: $checked = '';
2034: } elsif ($settings->{$item}->{$type} == 1) {
2035: $checked = 'checked="checked" ';
2036: }
2037: }
2038: }
2039: $datatable .= '<span class="LC_nobreak"><label>'.
2040: '<input type="checkbox" name="'.$context.'_'.$item.
2041: '" value="'.$type.'" '.$checked.'/>'.$titles{$item}.
2042: '</label></span> ';
2043: }
2044: }
2045: if ($context eq 'requestcourses') {
2046: $datatable .= '</tr><tr>';
2047: foreach my $item (@usertools) {
2048: $datatable .= '<td style="vertical-align: top">'.$cell{$item}.'</td>';
2049: }
2050: $datatable .= '</tr></table>';
2051: }
2052: $datatable .= '</td>';
2053: unless (($context eq 'requestcourses') ||
2054: ($context eq 'requestauthor')) {
2055: $datatable .=
2056: '<td class="LC_right_item">'.
2057: '<span class="LC_nobreak">'.&mt('Portfolio').': '.
2058: '<input type="text" name="quota_'.$type.
2059: '" value="'.$currdefquota.
2060: '" size="5" /></span>'.(' ' x 2).
2061: '<span class="LC_nobreak">'.&mt('Authoring').': '.
2062: '<input type="text" name="authorquota_'.$type.
2063: '" value="'.$currauthorquota.
2064: '" size="5" /></span></td>';
2065: }
2066: $datatable .= '</tr>';
2067: }
2068: }
2069: }
2070: unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
2071: $defaultquota = '20';
2072: $authorquota = '500';
2073: if (ref($settings) eq 'HASH') {
2074: if (ref($settings->{'defaultquota'}) eq 'HASH') {
2075: $defaultquota = $settings->{'defaultquota'}->{'default'};
2076: } elsif (defined($settings->{'default'})) {
2077: $defaultquota = $settings->{'default'};
2078: }
2079: if (ref($settings->{'authorquota'}) eq 'HASH') {
2080: $authorquota = $settings->{'authorquota'}->{'default'};
2081: }
2082: }
2083: }
2084: $typecount ++;
2085: $css_class = $typecount%2?' class="LC_odd_row"':'';
2086: $datatable .= '<tr'.$css_class.'>'.
2087: '<td>'.$othertitle.'</td>'.
2088: '<td class="LC_left_item">';
2089: if ($context eq 'requestcourses') {
2090: $datatable .= '<table><tr>';
2091: }
2092: my %defcell;
2093: foreach my $item (@usertools) {
2094: if ($context eq 'requestcourses') {
2095: my ($curroption,$currlimit);
2096: if (ref($settings) eq 'HASH') {
2097: if (ref($settings->{$item}) eq 'HASH') {
2098: $curroption = $settings->{$item}->{'default'};
2099: if ($curroption =~ /^autolimit=(\d*)$/) {
2100: $currlimit = $1;
2101: }
2102: }
2103: }
2104: if (!$curroption) {
2105: $curroption = 'norequest';
2106: }
2107: $datatable .= '<th>'.$titles{$item}.'</th>';
2108: foreach my $option (@options) {
2109: my $val = $option;
2110: if ($option eq 'norequest') {
2111: $val = 0;
2112: }
2113: if ($option eq 'validate') {
2114: my $canvalidate = 0;
2115: if (ref($validations{$item}) eq 'HASH') {
2116: if ($validations{$item}{'default'}) {
2117: $canvalidate = 1;
2118: }
2119: }
2120: next if (!$canvalidate);
2121: }
2122: my $checked = '';
2123: if ($option eq $curroption) {
2124: $checked = ' checked="checked"';
2125: } elsif ($option eq 'autolimit') {
2126: if ($curroption =~ /^autolimit/) {
2127: $checked = ' checked="checked"';
2128: }
2129: }
2130: $defcell{$item} .= '<span class="LC_nobreak"><label>'.
2131: '<input type="radio" name="crsreq_'.$item.
2132: '_default" value="'.$val.'"'.$checked.' />'.
2133: $titles{$option}.'</label>';
2134: if ($option eq 'autolimit') {
2135: $defcell{$item} .= ' <input type="text" name="crsreq_'.
2136: $item.'_limit_default" size="1" '.
2137: 'value="'.$currlimit.'" />';
2138: }
2139: $defcell{$item} .= '</span> ';
2140: if ($option eq 'autolimit') {
2141: $defcell{$item} .= $titles{'unlimited'};
2142: }
2143: }
2144: } elsif ($context eq 'requestauthor') {
2145: my $curroption;
2146: if (ref($settings) eq 'HASH') {
2147: $curroption = $settings->{'default'};
2148: }
2149: if (!$curroption) {
2150: $curroption = 'norequest';
2151: }
2152: foreach my $option (@options) {
2153: my $val = $option;
2154: if ($option eq 'norequest') {
2155: $val = 0;
2156: }
2157: my $checked = '';
2158: if ($option eq $curroption) {
2159: $checked = ' checked="checked"';
2160: }
2161: $datatable .= '<span class="LC_nobreak"><label>'.
2162: '<input type="radio" name="authorreq_default"'.
2163: ' value="'.$val.'"'.$checked.' />'.
2164: $titles{$option}.'</label></span> ';
2165: }
2166: } else {
2167: my $checked = 'checked="checked" ';
2168: if (ref($settings) eq 'HASH') {
2169: if (ref($settings->{$item}) eq 'HASH') {
2170: if ($settings->{$item}->{'default'} == 0) {
2171: $checked = '';
2172: } elsif ($settings->{$item}->{'default'} == 1) {
2173: $checked = 'checked="checked" ';
2174: }
2175: }
2176: }
2177: $datatable .= '<span class="LC_nobreak"><label>'.
2178: '<input type="checkbox" name="'.$context.'_'.$item.
2179: '" value="default" '.$checked.'/>'.$titles{$item}.
2180: '</label></span> ';
2181: }
2182: }
2183: if ($context eq 'requestcourses') {
2184: $datatable .= '</tr><tr>';
2185: foreach my $item (@usertools) {
2186: $datatable .= '<td style="vertical-align: top">'.$defcell{$item}.'</td>';
2187: }
2188: $datatable .= '</tr></table>';
2189: }
2190: $datatable .= '</td>';
2191: unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
2192: $datatable .= '<td class="LC_right_item">'.
2193: '<span class="LC_nobreak">'.&mt('Portfolio').': '.
2194: '<input type="text" name="defaultquota" value="'.
2195: $defaultquota.'" size="5" /></span>'.(' ' x2).
2196: '<span class="LC_nobreak">'.&mt('Authoring').': '.
2197: '<input type="text" name="authorquota" value="'.
2198: $authorquota.'" size="5" /></span></td>';
2199: }
2200: $datatable .= '</tr>';
2201: $typecount ++;
2202: $css_class = $typecount%2?' class="LC_odd_row"':'';
2203: $datatable .= '<tr'.$css_class.'>'.
2204: '<td>'.&mt('LON-CAPA Advanced Users').'<br />';
2205: if ($context eq 'requestcourses') {
2206: $datatable .= &mt('(overrides affiliation, if set)').
2207: '</td>'.
2208: '<td class="LC_left_item">'.
2209: '<table><tr>';
2210: } else {
2211: $datatable .= &mt('(overrides affiliation, if checked)').
2212: '</td>'.
2213: '<td class="LC_left_item" colspan="2">'.
2214: '<br />';
2215: }
2216: my %advcell;
2217: foreach my $item (@usertools) {
2218: if ($context eq 'requestcourses') {
2219: my ($curroption,$currlimit);
2220: if (ref($settings) eq 'HASH') {
2221: if (ref($settings->{$item}) eq 'HASH') {
2222: $curroption = $settings->{$item}->{'_LC_adv'};
2223: if ($curroption =~ /^autolimit=(\d*)$/) {
2224: $currlimit = $1;
2225: }
2226: }
2227: }
2228: $datatable .= '<th>'.$titles{$item}.'</th>';
2229: my $checked = '';
2230: if ($curroption eq '') {
2231: $checked = ' checked="checked"';
2232: }
2233: $advcell{$item} .= '<span class="LC_nobreak"><label>'.
2234: '<input type="radio" name="crsreq_'.$item.
2235: '__LC_adv" value=""'.$checked.' />'.
2236: &mt('No override set').'</label></span> ';
2237: foreach my $option (@options) {
2238: my $val = $option;
2239: if ($option eq 'norequest') {
2240: $val = 0;
2241: }
2242: if ($option eq 'validate') {
2243: my $canvalidate = 0;
2244: if (ref($validations{$item}) eq 'HASH') {
2245: if ($validations{$item}{'_LC_adv'}) {
2246: $canvalidate = 1;
2247: }
2248: }
2249: next if (!$canvalidate);
2250: }
2251: my $checked = '';
2252: if ($val eq $curroption) {
2253: $checked = ' checked="checked"';
2254: } elsif ($option eq 'autolimit') {
2255: if ($curroption =~ /^autolimit/) {
2256: $checked = ' checked="checked"';
2257: }
2258: }
2259: $advcell{$item} .= '<span class="LC_nobreak"><label>'.
2260: '<input type="radio" name="crsreq_'.$item.
2261: '__LC_adv" value="'.$val.'"'.$checked.' />'.
2262: $titles{$option}.'</label>';
2263: if ($option eq 'autolimit') {
2264: $advcell{$item} .= ' <input type="text" name="crsreq_'.
2265: $item.'_limit__LC_adv" size="1" '.
2266: 'value="'.$currlimit.'" />';
2267: }
2268: $advcell{$item} .= '</span> ';
2269: if ($option eq 'autolimit') {
2270: $advcell{$item} .= $titles{'unlimited'};
2271: }
2272: }
2273: } elsif ($context eq 'requestauthor') {
2274: my $curroption;
2275: if (ref($settings) eq 'HASH') {
2276: $curroption = $settings->{'_LC_adv'};
2277: }
2278: my $checked = '';
2279: if ($curroption eq '') {
2280: $checked = ' checked="checked"';
2281: }
2282: $datatable .= '<span class="LC_nobreak"><label>'.
2283: '<input type="radio" name="authorreq__LC_adv"'.
2284: ' value=""'.$checked.' />'.
2285: &mt('No override set').'</label></span> ';
2286: foreach my $option (@options) {
2287: my $val = $option;
2288: if ($option eq 'norequest') {
2289: $val = 0;
2290: }
2291: my $checked = '';
2292: if ($val eq $curroption) {
2293: $checked = ' checked="checked"';
2294: }
2295: $datatable .= '<span class="LC_nobreak"><label>'.
2296: '<input type="radio" name="authorreq__LC_adv"'.
2297: ' value="'.$val.'"'.$checked.' />'.
2298: $titles{$option}.'</label></span> ';
2299: }
2300: } else {
2301: my $checked = 'checked="checked" ';
2302: if (ref($settings) eq 'HASH') {
2303: if (ref($settings->{$item}) eq 'HASH') {
2304: if ($settings->{$item}->{'_LC_adv'} == 0) {
2305: $checked = '';
2306: } elsif ($settings->{$item}->{'_LC_adv'} == 1) {
2307: $checked = 'checked="checked" ';
2308: }
2309: }
2310: }
2311: $datatable .= '<span class="LC_nobreak"><label>'.
2312: '<input type="checkbox" name="'.$context.'_'.$item.
2313: '" value="_LC_adv" '.$checked.'/>'.$titles{$item}.
2314: '</label></span> ';
2315: }
2316: }
2317: if ($context eq 'requestcourses') {
2318: $datatable .= '</tr><tr>';
2319: foreach my $item (@usertools) {
2320: $datatable .= '<td style="vertical-align: top">'.$advcell{$item}.'</td>';
2321: }
2322: $datatable .= '</tr></table>';
2323: }
2324: $datatable .= '</td></tr>';
2325: $$rowtotal += $typecount;
2326: return $datatable;
2327: }
2328:
2329: sub print_requestmail {
2330: my ($dom,$action,$settings,$rowtotal,$customcss,$rowstyle) = @_;
2331: my ($now,$datatable,%currapp);
2332: $now = time;
2333: if (ref($settings) eq 'HASH') {
2334: if (ref($settings->{'notify'}) eq 'HASH') {
2335: if ($settings->{'notify'}{'approval'} ne '') {
2336: map {$currapp{$_}=1;} split(/,/,$settings->{'notify'}{'approval'});
2337: }
2338: }
2339: }
2340: my $numinrow = 2;
2341: my $css_class;
2342: if ($$rowtotal%2) {
2343: $css_class = 'LC_odd_row';
2344: }
2345: if ($customcss) {
2346: $css_class .= " $customcss";
2347: }
2348: $css_class =~ s/^\s+//;
2349: if ($css_class) {
2350: $css_class = ' class="'.$css_class.'"';
2351: }
2352: if ($rowstyle) {
2353: $css_class .= ' style="'.$rowstyle.'"';
2354: }
2355: my $text;
2356: if ($action eq 'requestcourses') {
2357: $text = &mt('Receive notification of course requests requiring approval');
2358: } elsif ($action eq 'requestauthor') {
2359: $text = &mt('Receive notification of Authoring Space requests requiring approval');
2360: } else {
2361: $text = &mt('Receive notification of queued requests for self-created user accounts requiring approval');
2362: }
2363: $datatable = '<tr'.$css_class.'>'.
2364: ' <td>'.$text.'</td>'.
2365: ' <td class="LC_left_item">';
2366: my ($numdc,$table,$rows) = &active_dc_picker($dom,$numinrow,'checkbox',
2367: $action.'notifyapproval',%currapp);
2368: if ($numdc > 0) {
2369: $datatable .= $table;
2370: } else {
2371: $datatable .= &mt('There are no active Domain Coordinators');
2372: }
2373: $datatable .='</td></tr>';
2374: return $datatable;
2375: }
2376:
2377: sub print_studentcode {
2378: my ($settings,$rowtotal) = @_;
2379: my $rownum = 0;
2380: my ($output,%current);
2381: my @crstypes = ('official','unofficial','community','textbook','placement','lti');
2382: if (ref($settings) eq 'HASH') {
2383: if (ref($settings->{'uniquecode'}) eq 'HASH') {
2384: foreach my $type (@crstypes) {
2385: $current{$type} = $settings->{'uniquecode'}{$type};
2386: }
2387: }
2388: }
2389: $output .= '<tr>'.
2390: '<td class="LC_left_item">'.&mt('Generate unique six character code as course identifier?').'</td>'.
2391: '<td class="LC_left_item">';
2392: foreach my $type (@crstypes) {
2393: my $check = ' ';
2394: if ($current{$type}) {
2395: $check = ' checked="checked" ';
2396: }
2397: $output .= '<span class="LC_nobreak"><label>'.
2398: '<input type="checkbox" name="uniquecode" value="'.$type.'"'.$check.'/>'.
2399: &mt($type).'</label></span>'.(' 'x2).' ';
2400: }
2401: $output .= '</td></tr>';
2402: $$rowtotal ++;
2403: return $output;
2404: }
2405:
2406: sub print_textbookcourses {
2407: my ($dom,$type,$settings,$rowtotal) = @_;
2408: my $rownum = 0;
2409: my $css_class;
2410: my $itemcount = 1;
2411: my $maxnum = 0;
2412: my $bookshash;
2413: if (ref($settings) eq 'HASH') {
2414: $bookshash = $settings->{$type};
2415: }
2416: my %ordered;
2417: if (ref($bookshash) eq 'HASH') {
2418: foreach my $item (keys(%{$bookshash})) {
2419: if (ref($bookshash->{$item}) eq 'HASH') {
2420: my $num = $bookshash->{$item}{'order'};
2421: $ordered{$num} = $item;
2422: }
2423: }
2424: }
2425: my $confname = $dom.'-domainconfig';
2426: my $switchserver = &check_switchserver($dom,$confname);
2427: my $maxnum = scalar(keys(%ordered));
2428: my $datatable;
2429: if (keys(%ordered)) {
2430: my @items = sort { $a <=> $b } keys(%ordered);
2431: for (my $i=0; $i<@items; $i++) {
2432: $css_class = $itemcount%2?' class="LC_odd_row"':'';
2433: my $key = $ordered{$items[$i]};
2434: my %coursehash=&Apache::lonnet::coursedescription($key);
2435: my $coursetitle = $coursehash{'description'};
2436: my ($subject,$title,$author,$publisher,$image,$imgsrc,$cdom,$cnum);
2437: if (ref($bookshash->{$key}) eq 'HASH') {
2438: $subject = $bookshash->{$key}->{'subject'};
2439: $title = $bookshash->{$key}->{'title'};
2440: if ($type eq 'textbooks') {
2441: $publisher = $bookshash->{$key}->{'publisher'};
2442: $author = $bookshash->{$key}->{'author'};
2443: $image = $bookshash->{$key}->{'image'};
2444: if ($image ne '') {
2445: my ($path,$imagefile) = ($image =~ m{^(.+)/([^/]+)$});
2446: my $imagethumb = "$path/tn-".$imagefile;
2447: $imgsrc = '<img src="'.$imagethumb.'" alt="'.&mt('Textbook image').'" />';
2448: }
2449: }
2450: }
2451: my $chgstr = ' onchange="javascript:reorderBooks(this.form,'."'$type".'_'."$key','$type'".');"';
2452: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
2453: .'<select name="'.$type.'_'.$key.'"'.$chgstr.'>';
2454: for (my $k=0; $k<=$maxnum; $k++) {
2455: my $vpos = $k+1;
2456: my $selstr;
2457: if ($k == $i) {
2458: $selstr = ' selected="selected" ';
2459: }
2460: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
2461: }
2462: $datatable .= '</select>'.(' 'x2).
2463: '<label><input type="checkbox" name="'.$type.'_del" value="'.$key.'" />'.
2464: &mt('Delete?').'</label></span></td>'.
2465: '<td colspan="2">'.
2466: '<span class="LC_nobreak">'.&mt('Subject:').'<input type="text" size="15" name="'.$type.'_subject_'.$i.'" value="'.$subject.'" /></span> '.
2467: (' 'x2).
2468: '<span class="LC_nobreak">'.&mt('Title:').'<input type="text" size="30" name="'.$type.'_title_'.$i.'" value="'.$title.'" /></span> ';
2469: if ($type eq 'textbooks') {
2470: $datatable .= (' 'x2).
2471: '<span class="LC_nobreak">'.&mt('Publisher:').'<input type="text" size="10" name="'.$type.'_publisher_'.$i.'" value="'.$publisher.'" /></span> '.
2472: (' 'x2).
2473: '<span class="LC_nobreak">'.&mt('Author(s):').'<input type="text" size="25" name="'.$type.'_author_'.$i.'" value="'.$author.'" /></span> '.
2474: (' 'x2).
2475: '<span class="LC_nobreak">'.&mt('Thumbnail:');
2476: if ($image) {
2477: $datatable .= $imgsrc.
2478: '<label><input type="checkbox" name="'.$type.'_image_del"'.
2479: ' value="'.$key.'" />'.&mt('Delete?').'</label></span> '.
2480: '<span class="LC_nobreak"> '.&mt('Replace:').' ';
2481: }
2482: if ($switchserver) {
2483: $datatable .= &mt('Upload to library server: [_1]',$switchserver);
2484: } else {
2485: $datatable .= '<input type="file" name="'.$type.'_image_'.$i.'" value="" />';
2486: }
2487: }
2488: $datatable .= '<input type="hidden" name="'.$type.'_id_'.$i.'" value="'.$type.'_'.$key.'" /></span> '.
2489: '<span class="LC_nobreak">'.&mt('LON-CAPA course:').' '.
2490: $coursetitle.'</span></td></tr>'."\n";
2491: $itemcount ++;
2492: }
2493: }
2494: $css_class = $itemcount%2?' class="LC_odd_row"':'';
2495: my $chgstr = ' onchange="javascript:reorderBooks(this.form,'."'$type"."_addbook_pos','$type'".');"';
2496: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
2497: '<input type="hidden" name="'.$type.'_maxnum" value="'.$maxnum.'" />'."\n".
2498: '<select name="'.$type.'_addbook_pos"'.$chgstr.'>';
2499: for (my $k=0; $k<$maxnum+1; $k++) {
2500: my $vpos = $k+1;
2501: my $selstr;
2502: if ($k == $maxnum) {
2503: $selstr = ' selected="selected" ';
2504: }
2505: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
2506: }
2507: $datatable .= '</select> '."\n".
2508: '<input type="checkbox" name="'.$type.'_addbook" value="1" />'.&mt('Add').'</span></td>'."\n".
2509: '<td colspan="2">'.
2510: '<span class="LC_nobreak">'.&mt('Subject:').'<input type="text" size="15" name="'.$type.'_addbook_subject" value="" /></span> '."\n".
2511: (' 'x2).
2512: '<span class="LC_nobreak">'.&mt('Title:').'<input type="text" size="30" name="'.$type.'_addbook_title" value="" /></span> '."\n".
2513: (' 'x2);
2514: if ($type eq 'textbooks') {
2515: $datatable .= '<span class="LC_nobreak">'.&mt('Publisher:').'<input type="text" size="10" name="'.$type.'_addbook_publisher" value="" /></span> '."\n".
2516: (' 'x2).
2517: '<span class="LC_nobreak">'.&mt('Author(s):').'<input type="text" size="25" name="'.$type.'_addbook_author" value="" /></span> '."\n".
2518: (' 'x2).
2519: '<span class="LC_nobreak">'.&mt('Image:').' ';
2520: if ($switchserver) {
2521: $datatable .= &mt('Upload to library server: [_1]',$switchserver);
2522: } else {
2523: $datatable .= '<input type="file" name="'.$type.'_addbook_image" value="" />';
2524: }
2525: $datatable .= '</span>'."\n";
2526: }
2527: $datatable .= '<span class="LC_nobreak">'.&mt('LON-CAPA course:').' '.
2528: &Apache::loncommon::select_dom_form($env{'request.role.domain'},$type.'_addbook_cdom').
2529: '<input type="text" size="25" name="'.$type.'_addbook_cnum" value="" />'.
2530: &Apache::loncommon::selectcourse_link
2531: ('display',$type.'_addbook_cnum',$type.'_addbook_cdom',undef,undef,undef,'Course').
2532: '</span></td>'."\n".
2533: '</tr>'."\n";
2534: $itemcount ++;
2535: return $datatable;
2536: }
2537:
2538: sub textbookcourses_javascript {
2539: my ($settings) = @_;
2540: return unless(ref($settings) eq 'HASH');
2541: my (%ordered,%total,%jstext);
2542: foreach my $type ('textbooks','templates') {
2543: $total{$type} = 0;
2544: if (ref($settings->{$type}) eq 'HASH') {
2545: foreach my $item (keys(%{$settings->{$type}})) {
2546: if (ref($settings->{$type}->{$item}) eq 'HASH') {
2547: my $num = $settings->{$type}->{$item}{'order'};
2548: $ordered{$type}{$num} = $item;
2549: }
2550: }
2551: $total{$type} = scalar(keys(%{$settings->{$type}}));
2552: }
2553: my @jsarray = ();
2554: foreach my $item (sort {$a <=> $b } (keys(%{$ordered{$type}}))) {
2555: push(@jsarray,$ordered{$type}{$item});
2556: }
2557: $jstext{$type} = ' var '.$type.' = Array('."'".join("','",@jsarray)."'".');'."\n";
2558: }
2559: return <<"ENDSCRIPT";
2560: <script type="text/javascript">
2561: // <![CDATA[
2562: function reorderBooks(form,item,caller) {
2563: var changedVal;
2564: $jstext{'textbooks'};
2565: $jstext{'templates'};
2566: var newpos;
2567: var maxh;
2568: if (caller == 'textbooks') {
2569: newpos = 'textbooks_addbook_pos';
2570: maxh = 1 + $total{'textbooks'};
2571: } else {
2572: newpos = 'templates_addbook_pos';
2573: maxh = 1 + $total{'templates'};
2574: }
2575: var current = new Array;
2576: var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
2577: if (item == newpos) {
2578: changedVal = newitemVal;
2579: } else {
2580: changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;
2581: current[newitemVal] = newpos;
2582: }
2583: if (caller == 'textbooks') {
2584: for (var i=0; i<textbooks.length; i++) {
2585: var elementName = 'textbooks_'+textbooks[i];
2586: if (elementName != item) {
2587: if (form.elements[elementName]) {
2588: var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
2589: current[currVal] = elementName;
2590: }
2591: }
2592: }
2593: }
2594: if (caller == 'templates') {
2595: for (var i=0; i<templates.length; i++) {
2596: var elementName = 'templates_'+templates[i];
2597: if (elementName != item) {
2598: if (form.elements[elementName]) {
2599: var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
2600: current[currVal] = elementName;
2601: }
2602: }
2603: }
2604: }
2605: var oldVal;
2606: for (var j=0; j<maxh; j++) {
2607: if (current[j] == undefined) {
2608: oldVal = j;
2609: }
2610: }
2611: if (oldVal < changedVal) {
2612: for (var k=oldVal+1; k<=changedVal ; k++) {
2613: var elementName = current[k];
2614: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
2615: }
2616: } else {
2617: for (var k=changedVal; k<oldVal; k++) {
2618: var elementName = current[k];
2619: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
2620: }
2621: }
2622: return;
2623: }
2624:
2625: // ]]>
2626: </script>
2627:
2628: ENDSCRIPT
2629: }
2630:
2631: sub ltitools_javascript {
2632: my ($settings) = @_;
2633: my $togglejs = <itools_toggle_js();
2634: unless (ref($settings) eq 'HASH') {
2635: return $togglejs;
2636: }
2637: my (%ordered,$total,%jstext);
2638: $total = 0;
2639: foreach my $item (keys(%{$settings})) {
2640: if (ref($settings->{$item}) eq 'HASH') {
2641: my $num = $settings->{$item}{'order'};
2642: $ordered{$num} = $item;
2643: }
2644: }
2645: $total = scalar(keys(%{$settings}));
2646: my @jsarray = ();
2647: foreach my $item (sort {$a <=> $b } (keys(%ordered))) {
2648: push(@jsarray,$ordered{$item});
2649: }
2650: my $jstext = ' var ltitools = Array('."'".join("','",@jsarray)."'".');'."\n";
2651: return <<"ENDSCRIPT";
2652: <script type="text/javascript">
2653: // <![CDATA[
2654: function reorderLTITools(form,item) {
2655: var changedVal;
2656: $jstext
2657: var newpos = 'ltitools_add_pos';
2658: var maxh = 1 + $total;
2659: var current = new Array;
2660: var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
2661: if (item == newpos) {
2662: changedVal = newitemVal;
2663: } else {
2664: changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;
2665: current[newitemVal] = newpos;
2666: }
2667: for (var i=0; i<ltitools.length; i++) {
2668: var elementName = 'ltitools_'+ltitools[i];
2669: if (elementName != item) {
2670: if (form.elements[elementName]) {
2671: var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
2672: current[currVal] = elementName;
2673: }
2674: }
2675: }
2676: var oldVal;
2677: for (var j=0; j<maxh; j++) {
2678: if (current[j] == undefined) {
2679: oldVal = j;
2680: }
2681: }
2682: if (oldVal < changedVal) {
2683: for (var k=oldVal+1; k<=changedVal ; k++) {
2684: var elementName = current[k];
2685: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
2686: }
2687: } else {
2688: for (var k=changedVal; k<oldVal; k++) {
2689: var elementName = current[k];
2690: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
2691: }
2692: }
2693: return;
2694: }
2695:
2696: // ]]>
2697: </script>
2698:
2699: $togglejs
2700:
2701: ENDSCRIPT
2702: }
2703:
2704: sub ltitools_toggle_js {
2705: return <<"ENDSCRIPT";
2706: <script type="text/javascript">
2707: // <![CDATA[
2708:
2709: function toggleLTITools(form,setting,item) {
2710: var radioname = '';
2711: var divid = '';
2712: if ((setting == 'passback') || (setting == 'roster')) {
2713: radioname = 'ltitools_'+setting+'_'+item;
2714: divid = 'ltitools_'+setting+'time_'+item;
2715: var num = form.elements[radioname].length;
2716: if (num) {
2717: var setvis = '';
2718: for (var i=0; i<num; i++) {
2719: if (form.elements[radioname][i].checked) {
2720: if (form.elements[radioname][i].value == '1') {
2721: if (document.getElementById(divid)) {
2722: document.getElementById(divid).style.display = 'inline-block';
2723: }
2724: setvis = 1;
2725: }
2726: break;
2727: }
2728: }
2729: }
2730: if (!setvis) {
2731: if (document.getElementById(divid)) {
2732: document.getElementById(divid).style.display = 'none';
2733: }
2734: }
2735: }
2736: if (setting == 'user') {
2737: divid = 'ltitools_'+setting+'_div_'+item;
2738: var checkid = 'ltitools_'+setting+'_field_'+item;
2739: if (document.getElementById(divid)) {
2740: if (document.getElementById(checkid)) {
2741: if (document.getElementById(checkid).checked) {
2742: document.getElementById(divid).style.display = 'inline-block';
2743: } else {
2744: document.getElementById(divid).style.display = 'none';
2745: }
2746: }
2747: }
2748: }
2749: return;
2750: }
2751: // ]]>
2752: </script>
2753:
2754: ENDSCRIPT
2755: }
2756:
2757: sub lti_javascript {
2758: my ($settings) = @_;
2759: my $togglejs = <i_toggle_js();
2760: unless (ref($settings) eq 'HASH') {
2761: return $togglejs;
2762: }
2763: my (%ordered,$total,%jstext);
2764: $total = 0;
2765: foreach my $item (keys(%{$settings})) {
2766: if (ref($settings->{$item}) eq 'HASH') {
2767: my $num = $settings->{$item}{'order'};
2768: $ordered{$num} = $item;
2769: }
2770: }
2771: $total = scalar(keys(%{$settings}));
2772: my @jsarray = ();
2773: foreach my $item (sort {$a <=> $b } (keys(%ordered))) {
2774: push(@jsarray,$ordered{$item});
2775: }
2776: my $jstext = ' var lti = Array('."'".join("','",@jsarray)."'".');'."\n";
2777: return <<"ENDSCRIPT";
2778: <script type="text/javascript">
2779: // <![CDATA[
2780: function reorderLTI(form,item) {
2781: var changedVal;
2782: $jstext
2783: var newpos = 'lti_pos_add';
2784: var maxh = 1 + $total;
2785: var current = new Array;
2786: var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
2787: if (item == newpos) {
2788: changedVal = newitemVal;
2789: } else {
2790: changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;
2791: current[newitemVal] = newpos;
2792: }
2793: for (var i=0; i<lti.length; i++) {
2794: var elementName = 'lti_pos_'+lti[i];
2795: if (elementName != item) {
2796: if (form.elements[elementName]) {
2797: var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
2798: current[currVal] = elementName;
2799: }
2800: }
2801: }
2802: var oldVal;
2803: for (var j=0; j<maxh; j++) {
2804: if (current[j] == undefined) {
2805: oldVal = j;
2806: }
2807: }
2808: if (oldVal < changedVal) {
2809: for (var k=oldVal+1; k<=changedVal ; k++) {
2810: var elementName = current[k];
2811: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
2812: }
2813: } else {
2814: for (var k=changedVal; k<oldVal; k++) {
2815: var elementName = current[k];
2816: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
2817: }
2818: }
2819: return;
2820: }
2821: // ]]>
2822: </script>
2823:
2824: $togglejs
2825:
2826: ENDSCRIPT
2827: }
2828:
2829: sub lti_toggle_js {
2830: my %lcauthparmtext = &Apache::lonlocal::texthash (
2831: localauth => 'Local auth argument',
2832: krb => 'Kerberos domain',
2833: );
2834: return <<"ENDSCRIPT";
2835: <script type="text/javascript">
2836: // <![CDATA[
2837:
2838: function toggleLTI(form,setting,item) {
2839: if ((setting == 'user') || (setting == 'crs') || (setting == 'passback')) {
2840: var radioname = '';
2841: var divid = '';
2842: if (setting == 'user') {
2843: radioname = 'lti_mapuser_'+item;
2844: divid = 'lti_userfield_'+item;
2845: } else if (settings == 'crs') {
2846: radioname = 'lti_mapcrs_'+item;
2847: divid = 'lti_crsfield_'+item;
2848: } else {
2849: radioname = 'lti_passbackformat_'+item;
2850: divid = 'lti_passback_'+item;
2851: }
2852: var num = form.elements[radioname].length;
2853: if (num) {
2854: var setvis = '';
2855: for (var i=0; i<num; i++) {
2856: if (form.elements[radioname][i].checked) {
2857: if (setting == 'passback') {
2858: if (form.elements[radioname][i].value == '1') {
2859: if (document.getElementById(divid)) {
2860: document.getElementById(divid).style.display = 'inline-block';
2861: }
2862: setvis = 1;
2863: break;
2864: }
2865: } else {
2866: if (form.elements[radioname][i].value == 'other') {
2867: if (document.getElementById(divid)) {
2868: document.getElementById(divid).style.display = 'inline-block';
2869: }
2870: setvis = 1;
2871: break;
2872: }
2873: }
2874: }
2875: }
2876: if (!setvis) {
2877: if (document.getElementById(divid)) {
2878: document.getElementById(divid).style.display = 'none';
2879: }
2880: }
2881: }
2882: } else if ((setting == 'sec') || (setting == 'secsrc')) {
2883: var numsec = form.elements['lti_crssec_'+item].length;
2884: if (numsec) {
2885: var setvis = '';
2886: for (var i=0; i<numsec; i++) {
2887: if (form.elements['lti_crssec_'+item][i].checked) {
2888: if (form.elements['lti_crssec_'+item][i].value == '1') {
2889: if (document.getElementById('lti_crssecfield_'+item)) {
2890: document.getElementById('lti_crssecfield_'+item).style.display = 'inline-block';
2891: setvis = 1;
2892: var numsrcsec = form.elements['lti_crssecsrc_'+item].length;
2893: if (numsrcsec) {
2894: var setsrcvis = '';
2895: for (var j=0; j<numsrcsec; j++) {
2896: if (form.elements['lti_crssecsrc_'+item][j].checked) {
2897: if (form.elements['lti_crssecsrc_'+item][j].value == 'other') {
2898: if (document.getElementById('lti_secsrcfield_'+item)) {
2899: document.getElementById('lti_secsrcfield_'+item).style.display = 'inline-block';
2900: setsrcvis = 1;
2901: }
2902: }
2903: }
2904: }
2905: if (!setsrcvis) {
2906: if (document.getElementById('lti_secsrcfield_'+item)) {
2907: document.getElementById('lti_secsrcfield_'+item).style.display = 'none';
2908: }
2909: }
2910: }
2911: }
2912: }
2913: }
2914: }
2915: if (!setvis) {
2916: if (document.getElementById('lti_crssecfield_'+item)) {
2917: document.getElementById('lti_crssecfield_'+item).style.display = 'none';
2918: }
2919: if (document.getElementById('lti_secsrcfield_'+item)) {
2920: document.getElementById('lti_secsrcfield_'+item).style.display = 'none';
2921: }
2922: }
2923: }
2924: } else if (setting == 'lcauth') {
2925: var numauth = form.elements['lti_lcauth_'+item].length;
2926: if (numauth) {
2927: for (var i=0; i<numauth; i++) {
2928: if (form.elements['lti_lcauth_'+item][i].checked) {
2929: if (document.getElementById('lti_'+setting+'_parmrow_'+item)) {
2930: if ((form.elements['lti_'+setting+'_'+item][i].value == 'internal') || (form.elements['lti_'+setting+'_'+item][i].value == 'lti')) {
2931: document.getElementById('lti_'+setting+'_parmrow_'+item).style.display = 'none';
2932: } else {
2933: document.getElementById('lti_'+setting+'_parmrow_'+item).style.display = 'table-row';
2934: if (document.getElementById('lti_'+setting+'_parmtext_'+item)) {
2935: if (form.elements['lti_'+setting+'_'+item][i].value == 'localauth') {
2936: document.getElementById('lti_'+setting+'_parmtext_'+item).innerHTML = "$lcauthparmtext{'localauth'}";
2937: } else {
2938: document.getElementById('lti_'+setting+'_parmtext_'+item).innerHTML = "$lcauthparmtext{'krb'}";
2939: }
2940: }
2941: }
2942: }
2943: }
2944: }
2945: }
2946: } else if (setting == 'lcmenu') {
2947: var menus = new Array('lti_topmenu_'+item,'lti_inlinemenu_'+item);
2948: var divid = 'lti_menufield_'+item;
2949: var setvis = '';
2950: for (var i=0; i<menus.length; i++) {
2951: var radioname = menus[i];
2952: var num = form.elements[radioname].length;
2953: if (num) {
2954: for (var j=0; j<num; j++) {
2955: if (form.elements[radioname][j].checked) {
2956: if (form.elements[radioname][j].value == '1') {
2957: if (document.getElementById(divid)) {
2958: document.getElementById(divid).style.display = 'inline-block';
2959: }
2960: setvis = 1;
2961: break;
2962: }
2963: }
2964: }
2965: }
2966: if (setvis == 1) {
2967: break;
2968: }
2969: }
2970: if (!setvis) {
2971: if (document.getElementById(divid)) {
2972: document.getElementById(divid).style.display = 'none';
2973: }
2974: }
2975: }
2976: return;
2977: }
2978: // ]]>
2979: </script>
2980:
2981: ENDSCRIPT
2982: }
2983:
2984: sub print_autoenroll {
2985: my ($dom,$settings,$rowtotal) = @_;
2986: my $autorun = &Apache::lonnet::auto_run(undef,$dom),
2987: my ($defdom,$runon,$runoff,$coownerson,$coownersoff,$failsafe);
2988: if (ref($settings) eq 'HASH') {
2989: if (exists($settings->{'run'})) {
2990: if ($settings->{'run'} eq '0') {
2991: $runoff = ' checked="checked" ';
2992: $runon = ' ';
2993: } else {
2994: $runon = ' checked="checked" ';
2995: $runoff = ' ';
2996: }
2997: } else {
2998: if ($autorun) {
2999: $runon = ' checked="checked" ';
3000: $runoff = ' ';
3001: } else {
3002: $runoff = ' checked="checked" ';
3003: $runon = ' ';
3004: }
3005: }
3006: if (exists($settings->{'co-owners'})) {
3007: if ($settings->{'co-owners'} eq '0') {
3008: $coownersoff = ' checked="checked" ';
3009: $coownerson = ' ';
3010: } else {
3011: $coownerson = ' checked="checked" ';
3012: $coownersoff = ' ';
3013: }
3014: } else {
3015: $coownersoff = ' checked="checked" ';
3016: $coownerson = ' ';
3017: }
3018: if (exists($settings->{'sender_domain'})) {
3019: $defdom = $settings->{'sender_domain'};
3020: }
3021: if (exists($settings->{'autofailsafe'})) {
3022: $failsafe = $settings->{'autofailsafe'};
3023: }
3024: } else {
3025: if ($autorun) {
3026: $runon = ' checked="checked" ';
3027: $runoff = ' ';
3028: } else {
3029: $runoff = ' checked="checked" ';
3030: $runon = ' ';
3031: }
3032: }
3033: my $domform = &Apache::loncommon::select_dom_form($defdom,'sender_domain',1);
3034: my $notif_sender;
3035: if (ref($settings) eq 'HASH') {
3036: $notif_sender = $settings->{'sender_uname'};
3037: }
3038: my $datatable='<tr class="LC_odd_row">'.
3039: '<td>'.&mt('Auto-enrollment active?').'</td>'.
3040: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
3041: '<input type="radio" name="autoenroll_run"'.
3042: $runon.' value="1" />'.&mt('Yes').'</label> '.
3043: '<label><input type="radio" name="autoenroll_run"'.
3044: $runoff.' value="0" />'.&mt('No').'</label></span></td>'.
3045: '</tr><tr>'.
3046: '<td>'.&mt('Notification messages - sender').
3047: '</td><td class="LC_right_item"><span class="LC_nobreak">'.
3048: &mt('username').': '.
3049: '<input type="text" name="sender_uname" value="'.
3050: $notif_sender.'" size="10" /> '.&mt('domain').
3051: ': '.$domform.'</span></td></tr>'.
3052: '<tr class="LC_odd_row">'.
3053: '<td>'.&mt('Automatically assign co-ownership').'</td>'.
3054: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
3055: '<input type="radio" name="autoassign_coowners"'.
3056: $coownerson.' value="1" />'.&mt('Yes').'</label> '.
3057: '<label><input type="radio" name="autoassign_coowners"'.
3058: $coownersoff.' value="0" />'.&mt('No').'</label></span></td>'.
3059: '</tr><tr>'.
3060: '<td>'.&mt('Failsafe for no drops when institutional data missing').'</td>'.
3061: '<td class="LC_right_item"><span class="LC_nobreak">'.
3062: '<input type="text" name="autoenroll_failsafe"'.
3063: ' value="'.$failsafe.'" size="4" /></span></td></tr>';
3064: $$rowtotal += 4;
3065: return $datatable;
3066: }
3067:
3068: sub print_autoupdate {
3069: my ($position,$dom,$settings,$rowtotal) = @_;
3070: my $datatable;
3071: if ($position eq 'top') {
3072: my $updateon = ' ';
3073: my $updateoff = ' checked="checked" ';
3074: my $classlistson = ' ';
3075: my $classlistsoff = ' checked="checked" ';
3076: if (ref($settings) eq 'HASH') {
3077: if ($settings->{'run'} eq '1') {
3078: $updateon = $updateoff;
3079: $updateoff = ' ';
3080: }
3081: if ($settings->{'classlists'} eq '1') {
3082: $classlistson = $classlistsoff;
3083: $classlistsoff = ' ';
3084: }
3085: }
3086: my %title = (
3087: run => 'Auto-update active?',
3088: classlists => 'Update information in classlists?',
3089: );
3090: $datatable = '<tr class="LC_odd_row">'.
3091: '<td>'.&mt($title{'run'}).'</td>'.
3092: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
3093: '<input type="radio" name="autoupdate_run"'.
3094: $updateon.' value="1" />'.&mt('Yes').'</label> '.
3095: '<label><input type="radio" name="autoupdate_run"'.
3096: $updateoff.'value="0" />'.&mt('No').'</label></span></td>'.
3097: '</tr><tr>'.
3098: '<td>'.&mt($title{'classlists'}).'</td>'.
3099: '<td class="LC_right_item"><span class="LC_nobreak">'.
3100: '<label><input type="radio" name="classlists"'.
3101: $classlistson.' value="1" />'.&mt('Yes').'</label> '.
3102: '<label><input type="radio" name="classlists"'.
3103: $classlistsoff.'value="0" />'.&mt('No').'</label></span></td>'.
3104: '</tr>';
3105: $$rowtotal += 2;
3106: } elsif ($position eq 'middle') {
3107: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
3108: my $numinrow = 3;
3109: my $locknamesettings;
3110: $datatable .= &insttypes_row($settings,$types,$usertypes,
3111: $dom,$numinrow,$othertitle,
3112: 'lockablenames',$rowtotal);
3113: $$rowtotal ++;
3114: } else {
3115: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
3116: my @fields = ('lastname','firstname','middlename','generation',
3117: 'permanentemail','id');
3118: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
3119: my $numrows = 0;
3120: if (ref($types) eq 'ARRAY') {
3121: if (@{$types} > 0) {
3122: $datatable =
3123: &usertype_update_row($settings,$usertypes,\%fieldtitles,
3124: \@fields,$types,\$numrows);
3125: $$rowtotal += @{$types};
3126: }
3127: }
3128: $datatable .=
3129: &usertype_update_row($settings,{'default' => $othertitle},
3130: \%fieldtitles,\@fields,['default'],
3131: \$numrows);
3132: $$rowtotal ++;
3133: }
3134: return $datatable;
3135: }
3136:
3137: sub print_autocreate {
3138: my ($dom,$settings,$rowtotal) = @_;
3139: my (%createon,%createoff,%currhash);
3140: my @types = ('xml','req');
3141: if (ref($settings) eq 'HASH') {
3142: foreach my $item (@types) {
3143: $createoff{$item} = ' checked="checked" ';
3144: $createon{$item} = ' ';
3145: if (exists($settings->{$item})) {
3146: if ($settings->{$item}) {
3147: $createon{$item} = ' checked="checked" ';
3148: $createoff{$item} = ' ';
3149: }
3150: }
3151: }
3152: if ($settings->{'xmldc'} ne '') {
3153: $currhash{$settings->{'xmldc'}} = 1;
3154: }
3155: } else {
3156: foreach my $item (@types) {
3157: $createoff{$item} = ' checked="checked" ';
3158: $createon{$item} = ' ';
3159: }
3160: }
3161: $$rowtotal += 2;
3162: my $numinrow = 2;
3163: my $datatable='<tr class="LC_odd_row">'.
3164: '<td>'.&mt('Create pending official courses from XML files').'</td>'.
3165: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
3166: '<input type="radio" name="autocreate_xml"'.
3167: $createon{'xml'}.' value="1" />'.&mt('Yes').'</label> '.
3168: '<label><input type="radio" name="autocreate_xml"'.
3169: $createoff{'xml'}.' value="0" />'.&mt('No').'</label></span>'.
3170: '</td></tr><tr>'.
3171: '<td>'.&mt('Create pending requests for official courses (if validated)').'</td>'.
3172: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
3173: '<input type="radio" name="autocreate_req"'.
3174: $createon{'req'}.' value="1" />'.&mt('Yes').'</label> '.
3175: '<label><input type="radio" name="autocreate_req"'.
3176: $createoff{'req'}.' value="0" />'.&mt('No').'</label></span>';
3177: my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',
3178: 'autocreate_xmldc',%currhash);
3179: $datatable .= '</td></tr><tr class="LC_odd_row"><td>';
3180: if ($numdc > 1) {
3181: $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)').
3182: '</td><td class="LC_left_item">';
3183: } else {
3184: $datatable .= &mt('Course creation processed as:').
3185: '</td><td class="LC_right_item">';
3186: }
3187: $datatable .= $dctable.'</td></tr>';
3188: $$rowtotal += $rows;
3189: return $datatable;
3190: }
3191:
3192: sub print_directorysrch {
3193: my ($position,$dom,$settings,$rowtotal) = @_;
3194: my $datatable;
3195: if ($position eq 'top') {
3196: my $instsrchon = ' ';
3197: my $instsrchoff = ' checked="checked" ';
3198: my ($exacton,$containson,$beginson);
3199: my $instlocalon = ' ';
3200: my $instlocaloff = ' checked="checked" ';
3201: if (ref($settings) eq 'HASH') {
3202: if ($settings->{'available'} eq '1') {
3203: $instsrchon = $instsrchoff;
3204: $instsrchoff = ' ';
3205: }
3206: if ($settings->{'localonly'} eq '1') {
3207: $instlocalon = $instlocaloff;
3208: $instlocaloff = ' ';
3209: }
3210: if (ref($settings->{'searchtypes'}) eq 'ARRAY') {
3211: foreach my $type (@{$settings->{'searchtypes'}}) {
3212: if ($type eq 'exact') {
3213: $exacton = ' checked="checked" ';
3214: } elsif ($type eq 'contains') {
3215: $containson = ' checked="checked" ';
3216: } elsif ($type eq 'begins') {
3217: $beginson = ' checked="checked" ';
3218: }
3219: }
3220: } else {
3221: if ($settings->{'searchtypes'} eq 'exact') {
3222: $exacton = ' checked="checked" ';
3223: } elsif ($settings->{'searchtypes'} eq 'contains') {
3224: $containson = ' checked="checked" ';
3225: } elsif ($settings->{'searchtypes'} eq 'specify') {
3226: $exacton = ' checked="checked" ';
3227: $containson = ' checked="checked" ';
3228: }
3229: }
3230: }
3231: my ($searchtitles,$titleorder) = &sorted_searchtitles();
3232: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
3233:
3234: my $numinrow = 4;
3235: my $cansrchrow = 0;
3236: $datatable='<tr class="LC_odd_row">'.
3237: '<td colspan="2"><span class ="LC_nobreak">'.&mt('Institutional directory search available?').'</span></td>'.
3238: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
3239: '<input type="radio" name="dirsrch_available"'.
3240: $instsrchon.' value="1" />'.&mt('Yes').'</label> '.
3241: '<label><input type="radio" name="dirsrch_available"'.
3242: $instsrchoff.' value="0" />'.&mt('No').'</label></span></td>'.
3243: '</tr><tr>'.
3244: '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search institution?').'</span></td>'.
3245: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
3246: '<input type="radio" name="dirsrch_instlocalonly"'.
3247: $instlocaloff.' value="0" />'.&mt('Yes').'</label> '.
3248: '<label><input type="radio" name="dirsrch_instlocalonly"'.
3249: $instlocalon.' value="1" />'.&mt('No').'</label></span></td>'.
3250: '</tr>';
3251: $$rowtotal += 2;
3252: if (ref($usertypes) eq 'HASH') {
3253: if (keys(%{$usertypes}) > 0) {
3254: $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
3255: $numinrow,$othertitle,'cansearch',
3256: $rowtotal);
3257: $cansrchrow = 1;
3258: }
3259: }
3260: if ($cansrchrow) {
3261: $$rowtotal ++;
3262: $datatable .= '<tr>';
3263: } else {
3264: $datatable .= '<tr class="LC_odd_row">';
3265: }
3266: $datatable .= '<td><span class ="LC_nobreak">'.&mt('Supported search methods').
3267: '</span></td><td class="LC_left_item" colspan="2"><table><tr>';
3268: foreach my $title (@{$titleorder}) {
3269: if (defined($searchtitles->{$title})) {
3270: my $check = ' ';
3271: if (ref($settings) eq 'HASH') {
3272: if (ref($settings->{'searchby'}) eq 'ARRAY') {
3273: if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) {
3274: $check = ' checked="checked" ';
3275: }
3276: }
3277: }
3278: $datatable .= '<td class="LC_left_item">'.
3279: '<span class="LC_nobreak"><label>'.
3280: '<input type="checkbox" name="searchby" '.
3281: 'value="'.$title.'"'.$check.'/>'.
3282: $searchtitles->{$title}.'</label></span></td>';
3283: }
3284: }
3285: $datatable .= '</tr></table></td></tr>';
3286: $$rowtotal ++;
3287: if ($cansrchrow) {
3288: $datatable .= '<tr class="LC_odd_row">';
3289: } else {
3290: $datatable .= '<tr>';
3291: }
3292: $datatable .= '<td><span class ="LC_nobreak">'.&mt('Search latitude').'</span></td>'.
3293: '<td class="LC_left_item" colspan="2">'.
3294: '<span class="LC_nobreak"><label>'.
3295: '<input type="checkbox" name="searchtypes" '.
3296: $exacton.' value="exact" />'.&mt('Exact match').
3297: '</label> '.
3298: '<label><input type="checkbox" name="searchtypes" '.
3299: $beginson.' value="begins" />'.&mt('Begins with').
3300: '</label> '.
3301: '<label><input type="checkbox" name="searchtypes" '.
3302: $containson.' value="contains" />'.&mt('Contains').
3303: '</label></span></td></tr>';
3304: $$rowtotal ++;
3305: } else {
3306: my $domsrchon = ' checked="checked" ';
3307: my $domsrchoff = ' ';
3308: my $domlocalon = ' ';
3309: my $domlocaloff = ' checked="checked" ';
3310: if (ref($settings) eq 'HASH') {
3311: if ($settings->{'lclocalonly'} eq '1') {
3312: $domlocalon = $domlocaloff;
3313: $domlocaloff = ' ';
3314: }
3315: if ($settings->{'lcavailable'} eq '0') {
3316: $domsrchoff = $domsrchon;
3317: $domsrchon = ' ';
3318: }
3319: }
3320: $datatable='<tr class="LC_odd_row">'.
3321: '<td colspan="2"><span class ="LC_nobreak">'.&mt('LON-CAPA directory search available?').'</span></td>'.
3322: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
3323: '<input type="radio" name="dirsrch_domavailable"'.
3324: $domsrchon.' value="1" />'.&mt('Yes').'</label> '.
3325: '<label><input type="radio" name="dirsrch_domavailable"'.
3326: $domsrchoff.' value="0" />'.&mt('No').'</label></span></td>'.
3327: '</tr><tr>'.
3328: '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search LON-CAPA domain?').'</span></td>'.
3329: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
3330: '<input type="radio" name="dirsrch_domlocalonly"'.
3331: $domlocaloff.' value="0" />'.&mt('Yes').'</label> '.
3332: '<label><input type="radio" name="dirsrch_domlocalonly"'.
3333: $domlocalon.' value="1" />'.&mt('No').'</label></span></td>'.
3334: '</tr>';
3335: $$rowtotal += 2;
3336: }
3337: return $datatable;
3338: }
3339:
3340: sub print_contacts {
3341: my ($position,$dom,$settings,$rowtotal) = @_;
3342: my $datatable;
3343: my @contacts = ('adminemail','supportemail');
3344: my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield,
3345: $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings,%lonstatus);
3346: if ($position eq 'top') {
3347: if (ref($settings) eq 'HASH') {
3348: foreach my $item (@contacts) {
3349: if (exists($settings->{$item})) {
3350: $to{$item} = $settings->{$item};
3351: }
3352: }
3353: }
3354: } elsif ($position eq 'middle') {
3355: @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail',
3356: 'updatesmail','idconflictsmail');
3357: foreach my $type (@mailings) {
3358: $otheremails{$type} = '';
3359: }
3360: } elsif ($position eq 'lower') {
3361: if (ref($settings) eq 'HASH') {
3362: if (ref($settings->{'lonstatus'}) eq 'HASH') {
3363: %lonstatus = %{$settings->{'lonstatus'}};
3364: }
3365: }
3366: } else {
3367: @mailings = ('helpdeskmail','otherdomsmail');
3368: foreach my $type (@mailings) {
3369: $otheremails{$type} = '';
3370: }
3371: $bccemails{'helpdeskmail'} = '';
3372: $bccemails{'otherdomsmail'} = '';
3373: $includestr{'helpdeskmail'} = '';
3374: $includestr{'otherdomsmail'} = '';
3375: ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();
3376: }
3377: if (ref($settings) eq 'HASH') {
3378: unless (($position eq 'top') || ($position eq 'lower')) {
3379: foreach my $type (@mailings) {
3380: if (exists($settings->{$type})) {
3381: if (ref($settings->{$type}) eq 'HASH') {
3382: foreach my $item (@contacts) {
3383: if ($settings->{$type}{$item}) {
3384: $checked{$type}{$item} = ' checked="checked" ';
3385: }
3386: }
3387: $otheremails{$type} = $settings->{$type}{'others'};
3388: if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
3389: $bccemails{$type} = $settings->{$type}{'bcc'};
3390: if ($settings->{$type}{'include'} ne '') {
3391: ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);
3392: $includestr{$type} = &unescape($includestr{$type});
3393: }
3394: }
3395: }
3396: } elsif ($type eq 'lonstatusmail') {
3397: $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
3398: }
3399: }
3400: }
3401: if ($position eq 'bottom') {
3402: foreach my $type (@mailings) {
3403: $bccemails{$type} = $settings->{$type}{'bcc'};
3404: if ($settings->{$type}{'include'} ne '') {
3405: ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);
3406: $includestr{$type} = &unescape($includestr{$type});
3407: }
3408: }
3409: if (ref($settings->{'helpform'}) eq 'HASH') {
3410: if (ref($fields) eq 'ARRAY') {
3411: foreach my $field (@{$fields}) {
3412: $currfield{$field} = $settings->{'helpform'}{$field};
3413: }
3414: }
3415: if (exists($settings->{'helpform'}{'maxsize'})) {
3416: $maxsize = $settings->{'helpform'}{'maxsize'};
3417: } else {
3418: $maxsize = '1.0';
3419: }
3420: } else {
3421: if (ref($fields) eq 'ARRAY') {
3422: foreach my $field (@{$fields}) {
3423: $currfield{$field} = 'yes';
3424: }
3425: }
3426: $maxsize = '1.0';
3427: }
3428: }
3429: } else {
3430: if ($position eq 'top') {
3431: $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
3432: $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};
3433: $checked{'errormail'}{'adminemail'} = ' checked="checked" ';
3434: $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';
3435: $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
3436: $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
3437: $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';
3438: $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';
3439: } elsif ($position eq 'bottom') {
3440: $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';
3441: $checked{'otherdomsmail'}{'supportemail'} = ' checked="checked" ';
3442: if (ref($fields) eq 'ARRAY') {
3443: foreach my $field (@{$fields}) {
3444: $currfield{$field} = 'yes';
3445: }
3446: }
3447: $maxsize = '1.0';
3448: }
3449: }
3450: my ($titles,$short_titles) = &contact_titles();
3451: my $rownum = 0;
3452: my $css_class;
3453: if ($position eq 'top') {
3454: foreach my $item (@contacts) {
3455: $css_class = $rownum%2?' class="LC_odd_row"':'';
3456: $datatable .= '<tr'.$css_class.'>'.
3457: '<td><span class="LC_nobreak">'.$titles->{$item}.
3458: '</span></td><td class="LC_right_item">'.
3459: '<input type="text" name="'.$item.'" value="'.
3460: $to{$item}.'" /></td></tr>';
3461: $rownum ++;
3462: }
3463: } elsif ($position eq 'bottom') {
3464: $css_class = $rownum%2?' class="LC_odd_row"':'';
3465: $datatable .= '<tr'.$css_class.'>'.
3466: '<td>'.&mt('Extra helpdesk form fields:').'<br />'.
3467: &mt('(e-mail, subject, and description always shown)').
3468: '</td><td class="LC_left_item">';
3469: if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') &&
3470: (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) {
3471: $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>';
3472: foreach my $field (@{$fields}) {
3473: $datatable .= '<tr><td>'.$fieldtitles->{$field};
3474: if (($field eq 'screenshot') || ($field eq 'cc')) {
3475: $datatable .= ' '.&mt('(logged-in users)');
3476: }
3477: $datatable .='</td><td>';
3478: my $clickaction;
3479: if ($field eq 'screenshot') {
3480: $clickaction = ' onclick="screenshotSize(this);"';
3481: }
3482: if (ref($possoptions->{$field}) eq 'ARRAY') {
3483: foreach my $option (@{$possoptions->{$field}}) {
3484: my $checked;
3485: if ($currfield{$field} eq $option) {
3486: $checked = ' checked="checked"';
3487: }
3488: $datatable .= '<span class="LC_nobreak"><label>'.
3489: '<input type="radio" name="helpform_'.$field.'" '.
3490: 'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}.
3491: '</label></span>'.(' 'x2);
3492: }
3493: }
3494: if ($field eq 'screenshot') {
3495: my $display;
3496: if ($currfield{$field} eq 'no') {
3497: $display = ' style="display:none"';
3498: }
3499: $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.'>'.
3500: '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'.
3501: '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />';
3502: }
3503: $datatable .= '</td></tr>';
3504: }
3505: $datatable .= '</table>';
3506: }
3507: $datatable .= '</td></tr>'."\n";
3508: $rownum ++;
3509: }
3510: unless (($position eq 'top') || ($position eq 'lower')) {
3511: foreach my $type (@mailings) {
3512: $css_class = $rownum%2?' class="LC_odd_row"':'';
3513: $datatable .= '<tr'.$css_class.'>'.
3514: '<td><span class="LC_nobreak">'.
3515: $titles->{$type}.': </span></td>'.
3516: '<td class="LC_left_item">';
3517: if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
3518: $datatable .= '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>';
3519: }
3520: $datatable .= '<span class="LC_nobreak">';
3521: foreach my $item (@contacts) {
3522: $datatable .= '<label>'.
3523: '<input type="checkbox" name="'.$type.'"'.
3524: $checked{$type}{$item}.
3525: ' value="'.$item.'" />'.$short_titles->{$item}.
3526: '</label> ';
3527: }
3528: $datatable .= '</span><br />'.&mt('Others').': '.
3529: '<input type="text" name="'.$type.'_others" '.
3530: 'value="'.$otheremails{$type}.'" />';
3531: my %locchecked;
3532: if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
3533: foreach my $loc ('s','b') {
3534: if ($includeloc{$type} eq $loc) {
3535: $locchecked{$loc} = ' checked="checked"';
3536: last;
3537: }
3538: }
3539: $datatable .= '<br />'.&mt('Bcc:').(' 'x6).
3540: '<input type="text" name="'.$type.'_bcc" '.
3541: 'value="'.$bccemails{$type}.'" /></fieldset>'.
3542: '<fieldset><legend>'.&mt('Optional added text').'</legend>'.
3543: &mt('Text automatically added to e-mail:').' '.
3544: '<input type="text" name="'.$type.'_includestr" value="'.$includestr{$type}.'" /><br />'.
3545: '<span class="LC_nobreak">'.&mt('Location:').' '.
3546: '<label><input type="radio" name="'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.
3547: (' 'x2).
3548: '<label><input type="radio" name="'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'.
3549: '</span></fieldset>';
3550: }
3551: $datatable .= '</td></tr>'."\n";
3552: $rownum ++;
3553: }
3554: }
3555: if ($position eq 'middle') {
3556: my %choices;
3557: my $corelink = &core_link_msu();
3558: $choices{'reporterrors'} = &mt('E-mail error reports to [_1]',$corelink);
3559: $choices{'reportupdates'} = &mt('E-mail record of completed LON-CAPA updates to [_1]',
3560: $corelink);
3561: $choices{'reportstatus'} = &mt('E-mail status if errors above threshold to [_1]',$corelink);
3562: my @toggles = ('reporterrors','reportupdates','reportstatus');
3563: my %defaultchecked = ('reporterrors' => 'on',
3564: 'reportupdates' => 'on',
3565: 'reportstatus' => 'on');
3566: (my $reports,$rownum) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
3567: \%choices,$rownum);
3568: $datatable .= $reports;
3569: } elsif ($position eq 'lower') {
3570: $css_class = $rownum%2?' class="LC_odd_row"':'';
3571: my ($threshold,$sysmail,%excluded,%weights);
3572: my ($defaults,$names) = &Apache::loncommon::lon_status_items();
3573: if ($lonstatus{'threshold'} =~ /^\d+$/) {
3574: $threshold = $lonstatus{'threshold'};
3575: } else {
3576: $threshold = $defaults->{'threshold'};
3577: }
3578: if ($lonstatus{'sysmail'} =~ /^\d+$/) {
3579: $sysmail = $lonstatus{'sysmail'};
3580: } else {
3581: $sysmail = $defaults->{'sysmail'};
3582: }
3583: if (ref($lonstatus{'weights'}) eq 'HASH') {
3584: foreach my $type ('E','W','N','U') {
3585: if ($lonstatus{'weights'}{$type} =~ /^\d+$/) {
3586: $weights{$type} = $lonstatus{'weights'}{$type};
3587: } else {
3588: $weights{$type} = $defaults->{$type};
3589: }
3590: }
3591: } else {
3592: foreach my $type ('E','W','N','U') {
3593: $weights{$type} = $defaults->{$type};
3594: }
3595: }
3596: if (ref($lonstatus{'excluded'}) eq 'ARRAY') {
3597: if (@{$lonstatus{'excluded'}} > 0) {
3598: map {$excluded{$_} = 1; } @{$lonstatus{'excluded'}};
3599: }
3600: }
3601: $datatable .= '<tr'.$css_class.'>'.
3602: '<td class="LC_left_item"><span class="LC_nobreak">'.
3603: $titles->{'errorthreshold'}.
3604: '</span></td><td class="LC_left_item">'.
3605: '<input type="text" name="errorthreshold" value="'.
3606: $threshold.'" size="5" /></td></tr>';
3607: $rownum ++;
3608: $css_class = $rownum%2?' class="LC_odd_row"':'';
3609: $datatable .= '<tr'.$css_class.'>'.
3610: '<td class="LC_left_item">'.
3611: '<span class="LC_nobreak">'.$titles->{'errorweights'}.
3612: '</span></td><td class="LC_left_item"><table><tr>';
3613: foreach my $type ('E','W','N','U') {
3614: $datatable .= '<td>'.$names->{$type}.'<br />'.
3615: '<input type="text" name="errorweights_'.$type.'" value="'.
3616: $weights{$type}.'" size="5" /></td>';
3617: }
3618: $datatable .= '</tr></table></tr>';
3619: $rownum ++;
3620: $css_class = $rownum%2?' class="LC_odd_row"':'';
3621: $datatable .= '<tr'.$css_class.'><td class="LC_left_item">'.
3622: $titles->{'errorexcluded'}.'</td>'.
3623: '<td class="LC_left_item"><table>';
3624: my $numinrow = 4;
3625: my @ids = sort(values(%Apache::lonnet::serverhomeIDs));
3626: for (my $i=0; $i<@ids; $i++) {
3627: my $rem = $i%($numinrow);
3628: if ($rem == 0) {
3629: if ($i > 0) {
3630: $datatable .= '</tr>';
3631: }
3632: $datatable .= '<tr>';
3633: }
3634: my $check;
3635: if ($excluded{$ids[$i]}) {
3636: $check = ' checked="checked" ';
3637: }
3638: $datatable .= '<td class="LC_left_item">'.
3639: '<span class="LC_nobreak"><label>'.
3640: '<input type="checkbox" name="errorexcluded" '.
3641: 'value="'.$ids[$i].'"'.$check.' />'.
3642: $ids[$i].'</label></span></td>';
3643: }
3644: my $colsleft = $numinrow - @ids%($numinrow);
3645: if ($colsleft > 1 ) {
3646: $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
3647: ' </td>';
3648: } elsif ($colsleft == 1) {
3649: $datatable .= '<td class="LC_left_item"> </td>';
3650: }
3651: $datatable .= '</tr></table></td></tr>';
3652: $rownum ++;
3653: $css_class = $rownum%2?' class="LC_odd_row"':'';
3654: $datatable .= '<tr'.$css_class.'>'.
3655: '<td class="LC_left_item"><span class="LC_nobreak">'.
3656: $titles->{'errorsysmail'}.
3657: '</span></td><td class="LC_left_item">'.
3658: '<input type="text" name="errorsysmail" value="'.
3659: $sysmail.'" size="5" /></td></tr>';
3660: $rownum ++;
3661: } elsif ($position eq 'bottom') {
3662: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
3663: my (@posstypes,%usertypeshash);
3664: if (ref($types) eq 'ARRAY') {
3665: @posstypes = @{$types};
3666: }
3667: if (@posstypes) {
3668: if (ref($usertypes) eq 'HASH') {
3669: %usertypeshash = %{$usertypes};
3670: }
3671: my @overridden;
3672: my $numinrow = 4;
3673: if (ref($settings) eq 'HASH') {
3674: if (ref($settings->{'overrides'}) eq 'HASH') {
3675: foreach my $key (sort(keys(%{$settings->{'overrides'}}))) {
3676: if (ref($settings->{'overrides'}{$key}) eq 'HASH') {
3677: push(@overridden,$key);
3678: foreach my $item (@contacts) {
3679: if ($settings->{'overrides'}{$key}{$item}) {
3680: $checked{'override_'.$key}{$item} = ' checked="checked" ';
3681: }
3682: }
3683: $otheremails{'override_'.$key} = $settings->{'overrides'}{$key}{'others'};
3684: $bccemails{'override_'.$key} = $settings->{'overrides'}{$key}{'bcc'};
3685: $includeloc{'override_'.$key} = '';
3686: $includestr{'override_'.$key} = '';
3687: if ($settings->{'overrides'}{$key}{'include'} ne '') {
3688: ($includeloc{'override_'.$key},$includestr{'override_'.$key}) =
3689: split(/:/,$settings->{'overrides'}{$key}{'include'},2);
3690: $includestr{'override_'.$key} = &unescape($includestr{'override_'.$key});
3691: }
3692: }
3693: }
3694: }
3695: }
3696: my $customclass = 'LC_helpdesk_override';
3697: my $optionsprefix = 'LC_options_helpdesk_';
3698:
3699: my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');";
3700:
3701: $datatable .= &insttypes_row($settings,$types,$usertypes,$dom,
3702: $numinrow,$othertitle,'overrides',
3703: \$rownum,$onclicktypes,$customclass);
3704: $rownum ++;
3705: $usertypeshash{'default'} = $othertitle;
3706: foreach my $status (@posstypes) {
3707: my $css_class;
3708: if ($rownum%2) {
3709: $css_class = 'LC_odd_row ';
3710: }
3711: $css_class .= $customclass;
3712: my $rowid = $optionsprefix.$status;
3713: my $hidden = 1;
3714: my $currstyle = 'display:none';
3715: if (grep(/^\Q$status\E$/,@overridden)) {
3716: $currstyle = 'display:table-row';
3717: $hidden = 0;
3718: }
3719: my $key = 'override_'.$status;
3720: $datatable .= &overridden_helpdesk($checked{$key},$otheremails{$key},$bccemails{$key},
3721: $includeloc{$key},$includestr{$key},$status,$rowid,
3722: $usertypeshash{$status},$css_class,$currstyle,
3723: \@contacts,$short_titles);
3724: unless ($hidden) {
3725: $rownum ++;
3726: }
3727: }
3728: }
3729: }
3730: $$rowtotal += $rownum;
3731: return $datatable;
3732: }
3733:
3734: sub core_link_msu {
3735: return &Apache::loncommon::modal_link('http://loncapa.org/core.html',
3736: &mt('LON-CAPA core group - MSU'),600,500);
3737: }
3738:
3739: sub overridden_helpdesk {
3740: my ($checked,$otheremails,$bccemails,$includeloc,$includestr,$type,$rowid,
3741: $typetitle,$css_class,$rowstyle,$contacts,$short_titles) = @_;
3742: my $class = 'LC_left_item';
3743: if ($css_class) {
3744: $css_class = ' class="'.$css_class.'"';
3745: }
3746: if ($rowid) {
3747: $rowid = ' id="'.$rowid.'"';
3748: }
3749: if ($rowstyle) {
3750: $rowstyle = ' style="'.$rowstyle.'"';
3751: }
3752: my ($output,$description);
3753: $description = &mt('Helpdesk requests from: [_1] in this domain (overrides default)',"<b>$typetitle</b>");
3754: $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.
3755: "<td>$description</td>\n".
3756: '<td class="'.$class.'" colspan="2">'.
3757: '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>'.
3758: '<span class="LC_nobreak">';
3759: if (ref($contacts) eq 'ARRAY') {
3760: foreach my $item (@{$contacts}) {
3761: my $check;
3762: if (ref($checked) eq 'HASH') {
3763: $check = $checked->{$item};
3764: }
3765: my $title;
3766: if (ref($short_titles) eq 'HASH') {
3767: $title = $short_titles->{$item};
3768: }
3769: $output .= '<label>'.
3770: '<input type="checkbox" name="override_'.$type.'"'.$check.
3771: ' value="'.$item.'" />'.$title.'</label> ';
3772: }
3773: }
3774: $output .= '</span><br />'.&mt('Others').': '.
3775: '<input type="text" name="override_'.$type.'_others" '.
3776: 'value="'.$otheremails.'" />';
3777: my %locchecked;
3778: foreach my $loc ('s','b') {
3779: if ($includeloc eq $loc) {
3780: $locchecked{$loc} = ' checked="checked"';
3781: last;
3782: }
3783: }
3784: $output .= '<br />'.&mt('Bcc:').(' 'x6).
3785: '<input type="text" name="override_'.$type.'_bcc" '.
3786: 'value="'.$bccemails.'" /></fieldset>'.
3787: '<fieldset><legend>'.&mt('Optional added text').'</legend>'.
3788: &mt('Text automatically added to e-mail:').' '.
3789: '<input type="text" name="override_'.$type.'_includestr" value="'.$includestr.'" /><br />'.
3790: '<span class="LC_nobreak">'.&mt('Location:').' '.
3791: '<label><input type="radio" name="override_'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'.
3792: (' 'x2).
3793: '<label><input type="radio" name="override_'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'.
3794: '</span></fieldset>'.
3795: '</td></tr>'."\n";
3796: return $output;
3797: }
3798:
3799: sub contacts_javascript {
3800: return <<"ENDSCRIPT";
3801:
3802: <script type="text/javascript">
3803: // <![CDATA[
3804:
3805: function screenshotSize(field) {
3806: if (document.getElementById('help_screenshotsize')) {
3807: if (field.value == 'no') {
3808: document.getElementById('help_screenshotsize').style.display="none";
3809: } else {
3810: document.getElementById('help_screenshotsize').style.display="";
3811: }
3812: }
3813: return;
3814: }
3815:
3816: function toggleHelpdeskRow(form,checkbox,target,prefix,docount) {
3817: if (form.elements[checkbox].length != undefined) {
3818: var count = 0;
3819: if (docount) {
3820: for (var i=0; i<form.elements[checkbox].length; i++) {
3821: if (form.elements[checkbox][i].checked) {
3822: count ++;
3823: }
3824: }
3825: }
3826: for (var i=0; i<form.elements[checkbox].length; i++) {
3827: var type = form.elements[checkbox][i].value;
3828: if (document.getElementById(prefix+type)) {
3829: if (form.elements[checkbox][i].checked) {
3830: document.getElementById(prefix+type).style.display = 'table-row';
3831: if (count % 2 == 1) {
3832: document.getElementById(prefix+type).className = target+' LC_odd_row';
3833: } else {
3834: document.getElementById(prefix+type).className = target;
3835: }
3836: count ++;
3837: } else {
3838: document.getElementById(prefix+type).style.display = 'none';
3839: }
3840: }
3841: }
3842: }
3843: return;
3844: }
3845:
3846:
3847: // ]]>
3848: </script>
3849:
3850: ENDSCRIPT
3851: }
3852:
3853: sub print_helpsettings {
3854: my ($position,$dom,$settings,$rowtotal) = @_;
3855: my $confname = $dom.'-domainconfig';
3856: my $formname = 'display';
3857: my ($datatable,$itemcount);
3858: if ($position eq 'top') {
3859: $itemcount = 1;
3860: my (%choices,%defaultchecked,@toggles);
3861: $choices{'submitbugs'} = &mt('Display link to: [_1]?',
3862: &Apache::loncommon::modal_link('http://bugs.loncapa.org',
3863: &mt('LON-CAPA bug tracker'),600,500));
3864: %defaultchecked = ('submitbugs' => 'on');
3865: @toggles = ('submitbugs');
3866: ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
3867: \%choices,$itemcount);
3868: $$rowtotal ++;
3869: } else {
3870: my $css_class;
3871: my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');
3872: my (%customroles,%ordered,%current);
3873: if (ref($settings) eq 'HASH') {
3874: if (ref($settings->{'adhoc'}) eq 'HASH') {
3875: %current = %{$settings->{'adhoc'}};
3876: }
3877: }
3878: my $count = 0;
3879: foreach my $key (sort(keys(%existing))) {
3880: if ($key=~/^rolesdef\_(\w+)$/) {
3881: my $rolename = $1;
3882: my (%privs,$order);
3883: ($privs{'system'},$privs{'domain'},$privs{'course'}) = split(/\_/,$existing{$key});
3884: $customroles{$rolename} = \%privs;
3885: if (ref($current{$rolename}) eq 'HASH') {
3886: $order = $current{$rolename}{'order'};
3887: }
3888: if ($order eq '') {
3889: $order = $count;
3890: }
3891: $ordered{$order} = $rolename;
3892: $count++;
3893: }
3894: }
3895: my $maxnum = scalar(keys(%ordered));
3896: my @roles_by_num = ();
3897: foreach my $item (sort {$a <=> $b } (keys(%ordered))) {
3898: push(@roles_by_num,$item);
3899: }
3900: my $context = 'domprefs';
3901: my $crstype = 'Course';
3902: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
3903: my @accesstypes = ('all','dh','da','none');
3904: my ($numstatustypes,@jsarray);
3905: if (ref($types) eq 'ARRAY') {
3906: if (@{$types} > 0) {
3907: $numstatustypes = scalar(@{$types});
3908: push(@accesstypes,'status');
3909: @jsarray = ('bystatus');
3910: }
3911: }
3912: my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);
3913: if (keys(%domhelpdesk)) {
3914: push(@accesstypes,('inc','exc'));
3915: push(@jsarray,('notinc','notexc'));
3916: }
3917: my $hiddenstr = join("','",@jsarray);
3918: my $context = 'domprefs';
3919: my $crstype = 'Course';
3920: my $prefix = 'helproles_';
3921: my $add_class = 'LC_hidden';
3922: foreach my $num (@roles_by_num) {
3923: my $role = $ordered{$num};
3924: my ($desc,$access,@statuses);
3925: if (ref($current{$role}) eq 'HASH') {
3926: $desc = $current{$role}{'desc'};
3927: $access = $current{$role}{'access'};
3928: if (ref($current{$role}{'insttypes'}) eq 'ARRAY') {
3929: @statuses = @{$current{$role}{'insttypes'}};
3930: }
3931: }
3932: if ($desc eq '') {
3933: $desc = $role;
3934: }
3935: my $identifier = 'custhelp'.$num;
3936: my %full=();
3937: my %levels= (
3938: course => {},
3939: domain => {},
3940: system => {},
3941: );
3942: my %levelscurrent=(
3943: course => {},
3944: domain => {},
3945: system => {},
3946: );
3947: &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent);
3948: my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
3949: $css_class = $itemcount%2?' class="LC_odd_row"':'';
3950: my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"';
3951: $datatable .= '<tr '.$css_class.'><td style="vertical-align: top"><b>'.$role.'</b><br />'.
3952: '<select name="helproles_'.$num.'_pos"'.$chgstr.'>';
3953: for (my $k=0; $k<=$maxnum; $k++) {
3954: my $vpos = $k+1;
3955: my $selstr;
3956: if ($k == $num) {
3957: $selstr = ' selected="selected" ';
3958: }
3959: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
3960: }
3961: $datatable .= '</select>'.(' 'x2).
3962: '<input type="hidden" name="helproles_'.$num.'" value="'.$role.'" />'.
3963: '</td>'.
3964: '<td><fieldset><legend>'.&mt('Role name').'</legend>'.
3965: &mt('Name shown to users:').
3966: '<input type="text" name="helproles_'.$num.'_desc" value="'.$desc.'" />'.
3967: '</fieldset>'.
3968: &helpdeskroles_access($dom,$prefix,$num,$add_class,$current{$role},\@accesstypes,
3969: $othertitle,$usertypes,$types,\%domhelpdesk).
3970: '<fieldset>'.
3971: '<legend>'.&mt('Role privileges').&adhocbutton($prefix,$num,'privs','show').'</legend>'.
3972: &Apache::lonuserutils::custom_role_table($crstype,\%full,\%levels,
3973: \%levelscurrent,$identifier,
3974: 'LC_hidden',$prefix.$num.'_privs').
3975: '</fieldset></td>';
3976: $itemcount ++;
3977: }
3978: $css_class = $itemcount%2?' class="LC_odd_row"':'';
3979: my $newcust = 'custhelp'.$count;
3980: my (%privs,%levelscurrent);
3981: my %full=();
3982: my %levels= (
3983: course => {},
3984: domain => {},
3985: system => {},
3986: );
3987: &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);
3988: my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
3989: my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$count."_pos'".');"';
3990: $datatable .= '<tr '.$css_class.'><td style="vertical-align: top"><span class="LC_nobreak"><label>'.
3991: '<input type="hidden" name="helproles_maxnum" value="'.$maxnum.'" />'."\n".
3992: '<select name="helproles_'.$count.'_pos"'.$chgstr.'>';
3993: for (my $k=0; $k<$maxnum+1; $k++) {
3994: my $vpos = $k+1;
3995: my $selstr;
3996: if ($k == $maxnum) {
3997: $selstr = ' selected="selected" ';
3998: }
3999: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
4000: }
4001: $datatable .= '</select> '."\n".
4002: '<input type="checkbox" name="newcusthelp" value="'.$count.'" />'. &mt('Add').
4003: '</label></span></td>'.
4004: '<td><fieldset><legend>'.&mt('Role name').'</legend>'.
4005: '<span class="LC_nobreak">'.
4006: &mt('Internal name:').
4007: '<input type="text" size="10" name="custhelpname'.$count.'" value="" />'.
4008: '</span>'.(' 'x4).
4009: '<span class="LC_nobreak">'.
4010: &mt('Name shown to users:').
4011: '<input type="text" size="20" name="helproles_'.$count.'_desc" value="" />'.
4012: '</span></fieldset>'.
4013: &helpdeskroles_access($dom,$prefix,$count,'',undef,\@accesstypes,$othertitle,
4014: $usertypes,$types,\%domhelpdesk).
4015: '<fieldset><legend>'.&mt('Role privileges').'</legend>'.
4016: &Apache::lonuserutils::custom_role_header($context,$crstype,
4017: \@templateroles,$newcust).
4018: &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels,
4019: \%levelscurrent,$newcust).
4020: '</fieldset>'.
4021: &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname).
4022: '</td></tr>';
4023: $count ++;
4024: $$rowtotal += $count;
4025: }
4026: return $datatable;
4027: }
4028:
4029: sub adhocbutton {
4030: my ($prefix,$num,$field,$visibility) = @_;
4031: my %lt = &Apache::lonlocal::texthash(
4032: show => 'Show details',
4033: hide => 'Hide details',
4034: );
4035: return '<span style="text-decoration:line-through; font-weight: normal;">'.(' 'x10).
4036: '</span>'.(' 'x2).'<input type="button" id="'.$prefix.$num.'_'.$field.'_vis"'.
4037: ' value="'.$lt{$visibility}.'" style="height:20px;" '.
4038: 'onclick="toggleHelpdeskItem('."'$num','$field'".');" />'.(' 'x2);
4039: }
4040:
4041: sub helpsettings_javascript {
4042: my ($roles_by_num,$total,$hiddenstr,$formname) = @_;
4043: return unless(ref($roles_by_num) eq 'ARRAY');
4044: my %html_js_lt = &Apache::lonlocal::texthash(
4045: show => 'Show details',
4046: hide => 'Hide details',
4047: );
4048: &html_escape(\%html_js_lt);
4049: my $jstext = ' var helproles = Array('."'".join("','",@{$roles_by_num})."'".');'."\n";
4050: return <<"ENDSCRIPT";
4051: <script type="text/javascript">
4052: // <![CDATA[
4053:
4054: function reorderHelpRoles(form,item) {
4055: var changedVal;
4056: $jstext
4057: var newpos = 'helproles_${total}_pos';
4058: var maxh = 1 + $total;
4059: var current = new Array();
4060: var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
4061: if (item == newpos) {
4062: changedVal = newitemVal;
4063: } else {
4064: changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;
4065: current[newitemVal] = newpos;
4066: }
4067: for (var i=0; i<helproles.length; i++) {
4068: var elementName = 'helproles_'+helproles[i]+'_pos';
4069: if (elementName != item) {
4070: if (form.elements[elementName]) {
4071: var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
4072: current[currVal] = elementName;
4073: }
4074: }
4075: }
4076: var oldVal;
4077: for (var j=0; j<maxh; j++) {
4078: if (current[j] == undefined) {
4079: oldVal = j;
4080: }
4081: }
4082: if (oldVal < changedVal) {
4083: for (var k=oldVal+1; k<=changedVal ; k++) {
4084: var elementName = current[k];
4085: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
4086: }
4087: } else {
4088: for (var k=changedVal; k<oldVal; k++) {
4089: var elementName = current[k];
4090: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
4091: }
4092: }
4093: return;
4094: }
4095:
4096: function helpdeskAccess(num) {
4097: var curraccess = null;
4098: if (document.$formname.elements['helproles_'+num+'_access'].length) {
4099: for (var i=0; i<document.$formname.elements['helproles_'+num+'_access'].length; i++) {
4100: if (document.$formname.elements['helproles_'+num+'_access'][i].checked) {
4101: curraccess = document.$formname.elements['helproles_'+num+'_access'][i].value;
4102: }
4103: }
4104: }
4105: var shown = Array();
4106: var hidden = Array();
4107: if (curraccess == 'none') {
4108: hidden = Array('$hiddenstr');
4109: } else {
4110: if (curraccess == 'status') {
4111: shown = Array('bystatus');
4112: hidden = Array('notinc','notexc');
4113: } else {
4114: if (curraccess == 'exc') {
4115: shown = Array('notexc');
4116: hidden = Array('notinc','bystatus');
4117: }
4118: if (curraccess == 'inc') {
4119: shown = Array('notinc');
4120: hidden = Array('notexc','bystatus');
4121: }
4122: if ((curraccess == 'all') || (curraccess == 'dh') || (curraccess == 'da')) {
4123: hidden = Array('notinc','notexc','bystatus');
4124: }
4125: }
4126: }
4127: if (hidden.length > 0) {
4128: for (var i=0; i<hidden.length; i++) {
4129: if (document.getElementById('helproles_'+num+'_'+hidden[i])) {
4130: document.getElementById('helproles_'+num+'_'+hidden[i]).style.display = 'none';
4131: }
4132: }
4133: }
4134: if (shown.length > 0) {
4135: for (var i=0; i<shown.length; i++) {
4136: if (document.getElementById('helproles_'+num+'_'+shown[i])) {
4137: if (shown[i] == 'privs') {
4138: document.getElementById('helproles_'+num+'_'+shown[i]).style.display = 'block';
4139: } else {
4140: document.getElementById('helproles_'+num+'_'+shown[i]).style.display = 'inline-block';
4141: }
4142: }
4143: }
4144: }
4145: return;
4146: }
4147:
4148: function toggleHelpdeskItem(num,field) {
4149: if (document.getElementById('helproles_'+num+'_'+field)) {
4150: if (document.getElementById('helproles_'+num+'_'+field).className.match(/(?:^|\\s)LC_hidden(?!\\S)/)) {
4151: document.getElementById('helproles_'+num+'_'+field).className =
4152: document.getElementById('helproles_'+num+'_'+field).className.replace(/(?:^|\\s)LC_hidden(?!\\S)/g ,'');
4153: if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {
4154: document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{hide}';
4155: }
4156: } else {
4157: document.getElementById('helproles_'+num+'_'+field).className += ' LC_hidden';
4158: if (document.getElementById('helproles_'+num+'_'+field+'_vis')) {
4159: document.getElementById('helproles_'+num+'_'+field+'_vis').value = '$html_js_lt{show}';
4160: }
4161: }
4162: }
4163: return;
4164: }
4165:
4166: // ]]>
4167: </script>
4168:
4169: ENDSCRIPT
4170: }
4171:
4172: sub helpdeskroles_access {
4173: my ($dom,$prefix,$num,$add_class,$current,$accesstypes,$othertitle,
4174: $usertypes,$types,$domhelpdesk) = @_;
4175: return unless ((ref($accesstypes) eq 'ARRAY') && (ref($domhelpdesk) eq 'HASH'));
4176: my %lt = &Apache::lonlocal::texthash(
4177: 'rou' => 'Role usage',
4178: 'whi' => 'Which helpdesk personnel may use this role?',
4179: 'all' => 'All with domain helpdesk or helpdesk assistant role',
4180: 'dh' => 'All with domain helpdesk role',
4181: 'da' => 'All with domain helpdesk assistant role',
4182: 'none' => 'None',
4183: 'status' => 'Determined based on institutional status',
4184: 'inc' => 'Include all, but exclude specific personnel',
4185: 'exc' => 'Exclude all, but include specific personnel',
4186: );
4187: my %usecheck = (
4188: all => ' checked="checked"',
4189: );
4190: my %displaydiv = (
4191: status => 'none',
4192: inc => 'none',
4193: exc => 'none',
4194: priv => 'block',
4195: );
4196: my $output;
4197: if (ref($current) eq 'HASH') {
4198: if (($current->{'access'} ne '') && ($current->{'access'} ne 'all')) {
4199: if (grep(/^\Q$current->{access}\E$/,@{$accesstypes})) {
4200: $usecheck{$current->{access}} = $usecheck{'all'};
4201: delete($usecheck{'all'});
4202: if ($current->{access} =~ /^(status|inc|exc)$/) {
4203: my $access = $1;
4204: $displaydiv{$access} = 'inline';
4205: } elsif ($current->{access} eq 'none') {
4206: $displaydiv{'priv'} = 'none';
4207: }
4208: }
4209: }
4210: }
4211: $output = '<fieldset id="'.$prefix.$num.'_usage"><legend>'.$lt{'rou'}.'</legend>'.
4212: '<p>'.$lt{'whi'}.'</p>';
4213: foreach my $access (@{$accesstypes}) {
4214: $output .= '<p><label><input type="radio" name="'.$prefix.$num.'_access" value="'.$access.'" '.$usecheck{$access}.
4215: ' onclick="helpdeskAccess('."'$num'".');" />'.
4216: $lt{$access}.'</label>';
4217: if ($access eq 'status') {
4218: $output .= '<div id="'.$prefix.$num.'_bystatus" style="display:'.$displaydiv{$access}.'">'.
4219: &Apache::lonuserutils::adhoc_status_types($dom,$prefix,$num,$current->{$access},
4220: $othertitle,$usertypes,$types).
4221: '</div>';
4222: } elsif (($access eq 'inc') && (keys(%{$domhelpdesk}) > 0)) {
4223: $output .= '<div id="'.$prefix.$num.'_notinc" style="display:'.$displaydiv{$access}.'">'.
4224: &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk).
4225: '</div>';
4226: } elsif (($access eq 'exc') && (keys(%{$domhelpdesk}) > 0)) {
4227: $output .= '<div id="'.$prefix.$num.'_notexc" style="display:'.$displaydiv{$access}.'">'.
4228: &Apache::lonuserutils::adhoc_staff($access,$prefix,$num,$current->{$access},$domhelpdesk).
4229: '</div>';
4230: }
4231: $output .= '</p>';
4232: }
4233: $output .= '</fieldset>';
4234: return $output;
4235: }
4236:
4237: sub radiobutton_prefs {
4238: my ($settings,$toggles,$defaultchecked,$choices,$itemcount,$onclick,
4239: $additional,$align) = @_;
4240: return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') &&
4241: (ref($choices) eq 'HASH'));
4242:
4243: my (%checkedon,%checkedoff,$datatable,$css_class);
4244:
4245: foreach my $item (@{$toggles}) {
4246: if ($defaultchecked->{$item} eq 'on') {
4247: $checkedon{$item} = ' checked="checked" ';
4248: $checkedoff{$item} = ' ';
4249: } elsif ($defaultchecked->{$item} eq 'off') {
4250: $checkedoff{$item} = ' checked="checked" ';
4251: $checkedon{$item} = ' ';
4252: }
4253: }
4254: if (ref($settings) eq 'HASH') {
4255: foreach my $item (@{$toggles}) {
4256: if ($settings->{$item} eq '1') {
4257: $checkedon{$item} = ' checked="checked" ';
4258: $checkedoff{$item} = ' ';
4259: } elsif ($settings->{$item} eq '0') {
4260: $checkedoff{$item} = ' checked="checked" ';
4261: $checkedon{$item} = ' ';
4262: }
4263: }
4264: }
4265: if ($onclick) {
4266: $onclick = ' onclick="'.$onclick.'"';
4267: }
4268: foreach my $item (@{$toggles}) {
4269: $css_class = $itemcount%2?' class="LC_odd_row"':'';
4270: $datatable .=
4271: '<tr'.$css_class.'><td style="vertical-align: top">'.
4272: '<span class="LC_nobreak">'.$choices->{$item}.
4273: '</span></td>';
4274: if ($align eq 'left') {
4275: $datatable .= '<td class="LC_left_item">';
4276: } else {
4277: $datatable .= '<td class="LC_right_item">';
4278: }
4279: $datatable .=
4280: '<span class="LC_nobreak">'.
4281: '<label><input type="radio" name="'.
4282: $item.'" '.$checkedon{$item}.' value="1"'.$onclick.' />'.&mt('Yes').
4283: '</label> <label><input type="radio" name="'.$item.'" '.
4284: $checkedoff{$item}.' value="0"'.$onclick.' />'.&mt('No').'</label>'.
4285: '</span>'.$additional.
4286: '</td>'.
4287: '</tr>';
4288: $itemcount ++;
4289: }
4290: return ($datatable,$itemcount);
4291: }
4292:
4293: sub print_ltitools {
4294: my ($dom,$settings,$rowtotal) = @_;
4295: my $rownum = 0;
4296: my $css_class;
4297: my $itemcount = 1;
4298: my $maxnum = 0;
4299: my %ordered;
4300: if (ref($settings) eq 'HASH') {
4301: foreach my $item (keys(%{$settings})) {
4302: if (ref($settings->{$item}) eq 'HASH') {
4303: my $num = $settings->{$item}{'order'};
4304: $ordered{$num} = $item;
4305: }
4306: }
4307: }
4308: my $confname = $dom.'-domainconfig';
4309: my $switchserver = &check_switchserver($dom,$confname);
4310: my $maxnum = scalar(keys(%ordered));
4311: my $datatable;
4312: my %lt = <itools_names();
4313: my @courseroles = ('cc','in','ta','ep','st');
4314: my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);
4315: my @fields = ('fullname','firstname','lastname','email','roles','user');
4316: if (keys(%ordered)) {
4317: my @items = sort { $a <=> $b } keys(%ordered);
4318: for (my $i=0; $i<@items; $i++) {
4319: $css_class = $itemcount%2?' class="LC_odd_row"':'';
4320: my $item = $ordered{$items[$i]};
4321: my ($title,$key,$secret,$url,$lifetime,$imgsrc,%sigsel);
4322: if (ref($settings->{$item}) eq 'HASH') {
4323: $title = $settings->{$item}->{'title'};
4324: $url = $settings->{$item}->{'url'};
4325: $key = $settings->{$item}->{'key'};
4326: $secret = $settings->{$item}->{'secret'};
4327: $lifetime = $settings->{$item}->{'lifetime'};
4328: my $image = $settings->{$item}->{'image'};
4329: if ($image ne '') {
4330: $imgsrc = '<img src="'.$image.'" alt="'.&mt('Tool Provider icon').'" />';
4331: }
4332: if ($settings->{$item}->{'sigmethod'} eq 'HMAC-256') {
4333: $sigsel{'HMAC-256'} = ' selected="selected"';
4334: } else {
4335: $sigsel{'HMAC-SHA1'} = ' selected="selected"';
4336: }
4337: }
4338: my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_".$item."'".');"';
4339: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
4340: .'<select name="ltitools_'.$item.'"'.$chgstr.'>';
4341: for (my $k=0; $k<=$maxnum; $k++) {
4342: my $vpos = $k+1;
4343: my $selstr;
4344: if ($k == $i) {
4345: $selstr = ' selected="selected" ';
4346: }
4347: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
4348: }
4349: $datatable .= '</select>'.(' 'x2).
4350: '<label><input type="checkbox" name="ltitools_del" value="'.$item.'" />'.
4351: &mt('Delete?').'</label></span></td>'.
4352: '<td colspan="2">'.
4353: '<fieldset><legend>'.&mt('Required settings').'</legend>'.
4354: '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="20" name="ltitools_title_'.$i.'" value="'.$title.'" /></span> '.
4355: (' 'x2).
4356: '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_version_'.$i.'">'.
4357: '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '.
4358: (' 'x2).
4359: '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_msgtype_'.$i.'">'.
4360: '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
4361: (' 'x2).
4362: '<span class="LC_nobreak">'.$lt{'sigmethod'}.':<select name="ltitools_sigmethod_'.$i.'">'.
4363: '<option value="HMAC-SHA1"'.$sigsel{'HMAC-SHA1'}.'>HMAC-SHA1</option>'.
4364: '<option value="HMAC-SHA256"'.$sigsel{'HMAC-SHA256'}.'>HMAC-SHA256</option></select></span>'.
4365: '<br /><br />'.
4366: '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="40" name="ltitools_url_'.$i.'"'.
4367: ' value="'.$url.'" /></span>'.
4368: (' 'x2).
4369: '<span class="LC_nobreak">'.$lt{'key'}.':'.
4370: '<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" /></span> '.
4371: (' 'x2).
4372: '<span class="LC_nobreak">'.$lt{'lifetime'}.':'.
4373: '<input type="text" size="5" name="ltitools_lifetime_'.$i.'" value="'.$lifetime.'" /></span> '.
4374: (' 'x2).
4375: '<span class="LC_nobreak">'.$lt{'secret'}.':'.
4376: '<input type="password" size="20" name="ltitools_secret_'.$i.'" value="'.$secret.'" />'.
4377: '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_secret_'.$i.'.type='."'text'".' } else { this.form.ltitools_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'.
4378: '<input type="hidden" name="ltitools_id_'.$i.'" value="'.$item.'" /></span>'.
4379: '</fieldset>'.
4380: '<fieldset><legend>'.&mt('Optional settings').'</legend>'.
4381: '<span class="LC_nobreak">'.&mt('Display target:');
4382: my %currdisp;
4383: if (ref($settings->{$item}->{'display'}) eq 'HASH') {
4384: if ($settings->{$item}->{'display'}->{'target'} eq 'window') {
4385: $currdisp{'window'} = ' checked="checked"';
4386: } elsif ($settings->{$item}->{'display'}->{'target'} eq 'tab') {
4387: $currdisp{'tab'} = ' checked="checked"';
4388: } else {
4389: $currdisp{'iframe'} = ' checked="checked"';
4390: }
4391: if ($settings->{$item}->{'display'}->{'width'} =~ /^(\d+)$/) {
4392: $currdisp{'width'} = $1;
4393: }
4394: if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) {
4395: $currdisp{'height'} = $1;
4396: }
4397: $currdisp{'linktext'} = $settings->{$item}->{'display'}->{'linktext'};
4398: $currdisp{'explanation'} = $settings->{$item}->{'display'}->{'explanation'};
4399: } else {
4400: $currdisp{'iframe'} = ' checked="checked"';
4401: }
4402: foreach my $disp ('iframe','tab','window') {
4403: $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'.
4404: $lt{$disp}.'</label>'.(' 'x2);
4405: }
4406: $datatable .= (' 'x4);
4407: foreach my $dimen ('width','height') {
4408: $datatable .= '<label>'.$lt{$dimen}.' '.
4409: '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'.
4410: (' 'x2);
4411: }
4412: $datatable .= '</span><br />'.
4413: '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'.
4414: '<input type="text" name="ltitools_linktext_'.$i.'" size="25" value="'.$currdisp{'linktext'}.'" /></div>'.
4415: '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.
4416: '<textarea name="ltitools_explanation_'.$i.'" rows="5" cols="40">'.$currdisp{'explanation'}.
4417: '</textarea></div><div style=""></div><br />';
4418: my %units = (
4419: 'passback' => 'days',
4420: 'roster' => 'seconds',
4421: );
4422: foreach my $extra ('passback','roster') {
4423: my $validsty = 'none';
4424: my $currvalid;
4425: my $checkedon = '';
4426: my $checkedoff = ' checked="checked"';
4427: if ($settings->{$item}->{$extra}) {
4428: $checkedon = $checkedoff;
4429: $checkedoff = '';
4430: $validsty = 'inline-block';
4431: if ($settings->{$item}->{$extra.'valid'} =~ /^\d+\.?\d*$/) {
4432: $currvalid = $settings->{$item}->{$extra.'valid'};
4433: }
4434: }
4435: my $onclick = ' onclick="toggleLTITools(this.form,'."'$extra','$i'".');"';
4436: $datatable .= '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{$extra}.' '.
4437: '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="0"'.$checkedoff.$onclick.' />'.
4438: &mt('No').'</label>'.(' 'x2).
4439: '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="1"'.$checkedon.$onclick.' />'.
4440: &mt('Yes').'</label></span></div>'.
4441: '<div class="LC_floatleft" style="display:'.$validsty.';" id="ltitools_'.$extra.'time_'.$i.'">'.
4442: '<span class="LC_nobreak">'.
4443: &mt("at least [_1] $units{$extra} after launch",
4444: '<input type="text" name="ltitools_'.$extra.'valid_'.$i.'" value="'.$currvalid.'" />').
4445: '</span></div><div style="padding:0;clear:both;margin:0;border:0"></div>';
4446: }
4447: $datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.': ';
4448: if ($imgsrc) {
4449: $datatable .= $imgsrc.
4450: '<label><input type="checkbox" name="ltitools_image_del"'.
4451: ' value="'.$item.'" />'.&mt('Delete?').'</label></span> '.
4452: '<span class="LC_nobreak"> '.&mt('Replace:').' ';
4453: } else {
4454: $datatable .= '('.&mt('if larger than 21x21 pixels, image will be scaled').') ';
4455: }
4456: if ($switchserver) {
4457: $datatable .= &mt('Upload to library server: [_1]',$switchserver);
4458: } else {
4459: $datatable .= '<input type="file" name="ltitools_image_'.$i.'" value="" />';
4460: }
4461: $datatable .= '</span></fieldset>';
4462: my (%checkedfields,%rolemaps,$userincdom);
4463: if (ref($settings->{$item}) eq 'HASH') {
4464: if (ref($settings->{$item}->{'fields'}) eq 'HASH') {
4465: %checkedfields = %{$settings->{$item}->{'fields'}};
4466: }
4467: $userincdom = $settings->{$item}->{'incdom'};
4468: if (ref($settings->{$item}->{'roles'}) eq 'HASH') {
4469: %rolemaps = %{$settings->{$item}->{'roles'}};
4470: $checkedfields{'roles'} = 1;
4471: }
4472: }
4473: $datatable .= '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.
4474: '<span class="LC_nobreak">';
4475: my $userfieldstyle = 'display:none;';
4476: my $seluserdom = '';
4477: my $unseluserdom = ' selected="selected"';
4478: foreach my $field (@fields) {
4479: my ($checked,$onclick,$id,$spacer);
4480: if ($checkedfields{$field}) {
4481: $checked = ' checked="checked"';
4482: }
4483: if ($field eq 'user') {
4484: $id = ' id="ltitools_user_field_'.$i.'"';
4485: $onclick = ' onclick="toggleLTITools(this.form,'."'$field','$i'".')"';
4486: if ($checked) {
4487: $userfieldstyle = 'display:inline-block';
4488: if ($userincdom) {
4489: $seluserdom = $unseluserdom;
4490: $unseluserdom = '';
4491: }
4492: }
4493: } else {
4494: $spacer = (' ' x2);
4495: }
4496: $datatable .= '<label>'.
4497: '<input type="checkbox" name="ltitools_fields_'.$i.'" value="'.$field.'"'.$id.$checked.$onclick.' />'.
4498: $lt{$field}.'</label>'.$spacer;
4499: }
4500: $datatable .= '</span>';
4501: $datatable .= '<div style="'.$userfieldstyle.'" id="ltitools_user_div_'.$i.'">'.
4502: '<span class="LC_nobreak"> : '.
4503: '<select name="ltitools_userincdom_'.$i.'">'.
4504: '<option value="">'.&mt('Select').'</option>'.
4505: '<option value="0"'.$unseluserdom.'>'.&mt('username').'</option>'.
4506: '<option value="1"'.$seluserdom.'>'.&mt('username:domain').'</option>'.
4507: '</select></span></div>';
4508: $datatable .= '</fieldset>'.
4509: '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';
4510: foreach my $role (@courseroles) {
4511: my ($selected,$selectnone);
4512: if (!$rolemaps{$role}) {
4513: $selectnone = ' selected="selected"';
4514: }
4515: $datatable .= '<td style="text-align: center">'.
4516: &Apache::lonnet::plaintext($role,'Course').'<br />'.
4517: '<select name="ltitools_roles_'.$role.'_'.$i.'">'.
4518: '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';
4519: foreach my $ltirole (@ltiroles) {
4520: unless ($selectnone) {
4521: if ($rolemaps{$role} eq $ltirole) {
4522: $selected = ' selected="selected"';
4523: } else {
4524: $selected = '';
4525: }
4526: }
4527: $datatable .= '<option value="'.$ltirole.'"'.$selected.'>'.$ltirole.'</option>';
4528: }
4529: $datatable .= '</select></td>';
4530: }
4531: $datatable .= '</tr></table></fieldset>';
4532: my %courseconfig;
4533: if (ref($settings->{$item}) eq 'HASH') {
4534: if (ref($settings->{$item}->{'crsconf'}) eq 'HASH') {
4535: %courseconfig = %{$settings->{$item}->{'crsconf'}};
4536: }
4537: }
4538: $datatable .= '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';
4539: foreach my $item ('label','title','target','linktext','explanation','append') {
4540: my $checked;
4541: if ($courseconfig{$item}) {
4542: $checked = ' checked="checked"';
4543: }
4544: $datatable .= '<label>'.
4545: '<input type="checkbox" name="ltitools_courseconfig_'.$i.'" value="'.$item.'"'.$checked.' />'.
4546: $lt{'crs'.$item}.'</label>'.(' ' x2)."\n";
4547: }
4548: $datatable .= '</span></fieldset>'.
4549: '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
4550: '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>';
4551: if (ref($settings->{$item}->{'custom'}) eq 'HASH') {
4552: my %custom = %{$settings->{$item}->{'custom'}};
4553: if (keys(%custom) > 0) {
4554: foreach my $key (sort(keys(%custom))) {
4555: $datatable .= '<tr><td><span class="LC_nobreak">'.
4556: '<label><input type="checkbox" name="ltitools_customdel_'.$i.'" value="'.
4557: $key.'" />'.&mt('Delete').'</label></span></td><td>'.$key.'</td>'.
4558: '<td><input type="text" name="ltitools_customval_'.$key.'_'.$i.'"'.
4559: ' value="'.$custom{$key}.'" /></td></tr>';
4560: }
4561: }
4562: }
4563: $datatable .= '<tr><td><span class="LC_nobreak">'.
4564: '<label><input type="checkbox" name="ltitools_customadd" value="'.$i.'" />'.
4565: &mt('Add').'</label></span></td><td><input type="text" name="ltitools_custom_name_'.$i.'" />'.
4566: '</td><td><input type="text" name="ltitools_custom_value_'.$i.'" /></td></tr>';
4567: $datatable .= '</table></fieldset></td></tr>'."\n";
4568: $itemcount ++;
4569: }
4570: }
4571: $css_class = $itemcount%2?' class="LC_odd_row"':'';
4572: my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_add_pos'".');"';
4573: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
4574: '<input type="hidden" name="ltitools_maxnum" value="'.$maxnum.'" />'."\n".
4575: '<select name="ltitools_add_pos"'.$chgstr.'>';
4576: for (my $k=0; $k<$maxnum+1; $k++) {
4577: my $vpos = $k+1;
4578: my $selstr;
4579: if ($k == $maxnum) {
4580: $selstr = ' selected="selected" ';
4581: }
4582: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
4583: }
4584: $datatable .= '</select> '."\n".
4585: '<input type="checkbox" name="ltitools_add" value="1" />'.&mt('Add').'</span></td>'."\n".
4586: '<td colspan="2">'.
4587: '<fieldset><legend>'.&mt('Required settings').'</legend>'.
4588: '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="20" name="ltitools_add_title" value="" /></span> '."\n".
4589: (' 'x2).
4590: '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_add_version">'.
4591: '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
4592: (' 'x2).
4593: '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_add_msgtype">'.
4594: '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '.
4595: '<span class="LC_nobreak">'.$lt{'sigmethod'}.':<select name="ltitools_add_sigmethod">'.
4596: '<option value="HMAC-SHA1" selected="selected">HMAC-SHA1</option>'.
4597: '<option value="HMAC-SHA256">HMAC-SHA256</option></select></span>'.
4598: '<br />'.
4599: '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="40" name="ltitools_add_url" value="" /></span> '."\n".
4600: (' 'x2).
4601: '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="ltitools_add_key" value="" /></span> '."\n".
4602: (' 'x2).
4603: '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="5" name="ltitools_add_lifetime" value="300" /></span> '."\n".
4604: (' 'x2).
4605: '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="ltitools_add_secret" value="" />'.
4606: '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_add_secret.type='."'text'".' } else { this.form.ltitools_add_secret.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n".
4607: '</fieldset>'.
4608: '<fieldset><legend>'.&mt('Optional settings').'</legend>'.
4609: '<span class="LC_nobreak">'.&mt('Display target:');
4610: my %defaultdisp;
4611: $defaultdisp{'iframe'} = ' checked="checked"';
4612: foreach my $disp ('iframe','tab','window') {
4613: $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'.
4614: $lt{$disp}.'</label>'.(' 'x2);
4615: }
4616: $datatable .= (' 'x4);
4617: foreach my $dimen ('width','height') {
4618: $datatable .= '<label>'.$lt{$dimen}.' '.
4619: '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'.
4620: (' 'x2);
4621: }
4622: $datatable .= '</span><br />'.
4623: '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'.
4624: '<input type="text" name="ltitools_add_linktext" size="5" /></div>'.
4625: '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'.
4626: '<textarea name="ltitools_add_explanation" rows="5" cols="40"></textarea>'.
4627: '</div><div style=""></div><br />';
4628: my %units = (
4629: 'passback' => 'days',
4630: 'roster' => 'seconds',
4631: );
4632: my %defaulttimes = (
4633: 'passback' => '7',
4634: 'roster' => '300',
4635: );
4636: foreach my $extra ('passback','roster') {
4637: my $onclick = ' onclick="toggleLTITools(this.form,'."'$extra','add'".');"';
4638: $datatable .= '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{$extra}.' '.
4639: '<label><input type="radio" name="ltitools_'.$extra.'_add" value="0" checked="checked"'.$onclick.' />'.
4640: &mt('No').'</label></span>'.(' 'x2).'<span class="LC_nobreak">'.
4641: '<label><input type="radio" name="ltitools_'.$extra.'_add" value="1"'.$onclick.' />'.
4642: &mt('Yes').'</label></span></div>'.
4643: '<div class="LC_floatleft" style="display:none;" id="ltitools_'.$extra.'time_add">'.
4644: '<span class="LC_nobreak">'.
4645: &mt("at least [_1] $units{$extra} after launch",
4646: '<input type="text" name="ltitools_'.$extra.'valid_add" value="'.$defaulttimes{$extra}.'" />').
4647: '</span></div><div style="padding:0;clear:both;margin:0;border:0"></div>';
4648: }
4649: $datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.': '.
4650: '('.&mt('if larger than 21x21 pixels, image will be scaled').') ';
4651: if ($switchserver) {
4652: $datatable .= &mt('Upload to library server: [_1]',$switchserver);
4653: } else {
4654: $datatable .= '<input type="file" name="ltitools_add_image" value="" />';
4655: }
4656: $datatable .= '</span></fieldset>'.
4657: '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'.
4658: '<span class="LC_nobreak">';
4659: foreach my $field (@fields) {
4660: my ($id,$onclick,$spacer);
4661: if ($field eq 'user') {
4662: $id = ' id="ltitools_user_field_add"';
4663: $onclick = ' onclick="toggleLTITools(this.form,'."'$field','add'".')"';
4664: } else {
4665: $spacer = (' ' x2);
4666: }
4667: $datatable .= '<label>'.
4668: '<input type="checkbox" name="ltitools_add_fields" value="'.$field.'"'.$id.$onclick.' />'.
4669: $lt{$field}.'</label>'.$spacer;
4670: }
4671: $datatable .= '</span>'.
4672: '<div style="display:none;" id="ltitools_user_div_add">'.
4673: '<span class="LC_nobreak"> : '.
4674: '<select name="ltitools_userincdom_add">'.
4675: '<option value="" selected="selected">'.&mt('Select').'</option>'.
4676: '<option value="0">'.&mt('username').'</option>'.
4677: '<option value="1">'.&mt('username:domain').'</option>'.
4678: '</select></span></div></fieldset>';
4679: $datatable .= '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>';
4680: foreach my $role (@courseroles) {
4681: my ($checked,$checkednone);
4682: $datatable .= '<td style="text-align: center">'.
4683: &Apache::lonnet::plaintext($role,'Course').'<br />'.
4684: '<select name="ltitools_add_roles_'.$role.'">'.
4685: '<option value="" selected="selected">'.&mt('Select').'</option>';
4686: foreach my $ltirole (@ltiroles) {
4687: $datatable .= '<option value="'.$ltirole.'">'.$ltirole.'</option>';
4688: }
4689: $datatable .= '</select></td>';
4690: }
4691: $datatable .= '</tr></table></fieldset>'.
4692: '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">';
4693: foreach my $item ('label','title','target','linktext','explanation','append') {
4694: $datatable .= '<label>'.
4695: '<input type="checkbox" name="ltitools_courseconfig" value="'.$item.'" checked="checked" />'.
4696: $lt{'crs'.$item}.'</label>'.(' ' x2)."\n";
4697: }
4698: $datatable .= '</span></fieldset>'.
4699: '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'.
4700: '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>'.
4701: '<tr><td><span class="LC_nobreak">'.
4702: '<label><input type="checkbox" name="ltitools_add_custom" value="1" />'.
4703: &mt('Add').'</label></span></td><td><input type="text" name="ltitools_add_custom_name" />'.
4704: '</td><td><input type="text" name="ltitools_add_custom_value" /></td></tr>'.
4705: '</table></fieldset>'."\n".
4706: '</td>'."\n".
4707: '</tr>'."\n";
4708: $itemcount ++;
4709: return $datatable;
4710: }
4711:
4712: sub ltitools_names {
4713: my %lt = &Apache::lonlocal::texthash(
4714: 'title' => 'Title',
4715: 'version' => 'Version',
4716: 'msgtype' => 'Message Type',
4717: 'sigmethod' => 'Signature Method',
4718: 'url' => 'URL',
4719: 'key' => 'Key',
4720: 'lifetime' => 'Nonce lifetime (s)',
4721: 'secret' => 'Secret',
4722: 'icon' => 'Icon',
4723: 'user' => 'User',
4724: 'fullname' => 'Full Name',
4725: 'firstname' => 'First Name',
4726: 'lastname' => 'Last Name',
4727: 'email' => 'E-mail',
4728: 'roles' => 'Role',
4729: 'window' => 'Window',
4730: 'tab' => 'Tab',
4731: 'iframe' => 'iFrame',
4732: 'height' => 'Height',
4733: 'width' => 'Width',
4734: 'linktext' => 'Default Link Text',
4735: 'explanation' => 'Default Explanation',
4736: 'passback' => 'Tool can return grades:',
4737: 'roster' => 'Tool can retrieve roster:',
4738: 'crstarget' => 'Display target',
4739: 'crslabel' => 'Course label',
4740: 'crstitle' => 'Course title',
4741: 'crslinktext' => 'Link Text',
4742: 'crsexplanation' => 'Explanation',
4743: 'crsappend' => 'Provider URL',
4744: );
4745: return %lt;
4746: }
4747:
4748: sub print_lti {
4749: my ($dom,$settings,$rowtotal) = @_;
4750: my $itemcount = 1;
4751: my $maxnum = 0;
4752: my $css_class;
4753: my %ordered;
4754: if (ref($settings) eq 'HASH') {
4755: foreach my $item (keys(%{$settings})) {
4756: if (ref($settings->{$item}) eq 'HASH') {
4757: my $num = $settings->{$item}{'order'};
4758: $ordered{$num} = $item;
4759: }
4760: }
4761: }
4762: my $maxnum = scalar(keys(%ordered));
4763: my $datatable;
4764: my %lt = <i_names();
4765: if (keys(%ordered)) {
4766: my @items = sort { $a <=> $b } keys(%ordered);
4767: for (my $i=0; $i<@items; $i++) {
4768: $css_class = $itemcount%2?' class="LC_odd_row"':'';
4769: my $item = $ordered{$items[$i]};
4770: my ($key,$secret,$lifetime,$consumer,$current);
4771: if (ref($settings->{$item}) eq 'HASH') {
4772: $key = $settings->{$item}->{'key'};
4773: $secret = $settings->{$item}->{'secret'};
4774: $lifetime = $settings->{$item}->{'lifetime'};
4775: $consumer = $settings->{$item}->{'consumer'};
4776: $current = $settings->{$item};
4777: }
4778: my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'lti_pos_".$item."'".');"';
4779: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
4780: .'<select name="lti_pos_'.$item.'"'.$chgstr.'>';
4781: for (my $k=0; $k<=$maxnum; $k++) {
4782: my $vpos = $k+1;
4783: my $selstr;
4784: if ($k == $i) {
4785: $selstr = ' selected="selected" ';
4786: }
4787: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
4788: }
4789: $datatable .= '</select>'.(' 'x2).
4790: '<label><input type="checkbox" name="lti_del" value="'.$item.'" />'.
4791: &mt('Delete?').'</label></span></td>'.
4792: '<td colspan="2">'.
4793: '<fieldset><legend>'.&mt('Required settings').'</legend>'.
4794: '<span class="LC_nobreak">'.$lt{'consumer'}.
4795: ':<input type="text" size="20" name="lti_consumer_'.$i.'" value="'.$consumer.'" /></span> '.
4796: (' 'x2).
4797: '<span class="LC_nobreak">'.$lt{'version'}.':<select name="lti_version_'.$i.'">'.
4798: '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '.
4799: (' 'x2).
4800: '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" name="lti_lifetime_'.$i.'"'.
4801: 'value="'.$lifetime.'" size="5" /></span>'.
4802: '<br /><br />'.
4803: '<span class="LC_nobreak">'.$lt{'key'}.
4804: ':<input type="text" size="25" name="lti_key_'.$i.'" value="'.$key.'" /></span> '.
4805: (' 'x2).
4806: '<span class="LC_nobreak">'.$lt{'secret'}.':'.
4807: '<input type="password" size="20" name="lti_secret_'.$i.'" value="'.$secret.'" />'.
4808: '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.lti_secret_'.$i.'.type='."'text'".' } else { this.form.lti_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'.
4809: '<input type="hidden" name="lti_id_'.$i.'" value="'.$item.'" /></span>'.
4810: '</fieldset>'.<i_options($i,$current,$itemcount,%lt).'</td></tr>';
4811: $itemcount ++;
4812: }
4813: }
4814: $css_class = $itemcount%2?' class="LC_odd_row"':'';
4815: my $chgstr = ' onchange="javascript:reorderLTI(this.form,'."'lti_pos_add'".');"';
4816: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n".
4817: '<input type="hidden" name="lti_maxnum" value="'.$maxnum.'" />'."\n".
4818: '<select name="lti_pos_add"'.$chgstr.'>';
4819: for (my $k=0; $k<$maxnum+1; $k++) {
4820: my $vpos = $k+1;
4821: my $selstr;
4822: if ($k == $maxnum) {
4823: $selstr = ' selected="selected" ';
4824: }
4825: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
4826: }
4827: $datatable .= '</select> '."\n".
4828: '<input type="checkbox" name="lti_add" value="1" />'.&mt('Add').'</span></td>'."\n".
4829: '<td colspan="2">'.
4830: '<fieldset><legend>'.&mt('Required settings').'</legend>'.
4831: '<span class="LC_nobreak">'.$lt{'consumer'}.
4832: ':<input type="text" size="20" name="lti_consumer_add" value="" /></span> '."\n".
4833: (' 'x2).
4834: '<span class="LC_nobreak">'.$lt{'version'}.':<select name="lti_version_add">'.
4835: '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n".
4836: (' 'x2).
4837: '<span class="LC_nobreak">'.$lt{'lifetime'}.':<input type="text" size="5" name="lti_lifetime_add" value="300" /></span> '."\n".
4838: '<br /><br />'.
4839: '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="lti_key_add" value="" /></span> '."\n".
4840: (' 'x2).
4841: '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="lti_secret_add" value="" />'.
4842: '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.lti_secret_add.type='."'text'".' } else { this.form.lti_secret_add.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n".
4843: '</fieldset>'.<i_options('add',undef,$itemcount,%lt).
4844: '</td>'."\n".
4845: '</tr>'."\n";
4846: $$rowtotal ++;
4847: return $datatable;;
4848: }
4849:
4850: sub lti_names {
4851: my %lt = &Apache::lonlocal::texthash(
4852: 'version' => 'LTI Version',
4853: 'url' => 'URL',
4854: 'key' => 'Key',
4855: 'lifetime' => 'Nonce lifetime (s)',
4856: 'consumer' => 'LTI Consumer',
4857: 'secret' => 'Secret',
4858: 'email' => 'Email address',
4859: 'sourcedid' => 'User ID',
4860: 'other' => 'Other',
4861: 'passback' => 'Can return grades to Consumer:',
4862: 'roster' => 'Can retrieve roster from Consumer:',
4863: 'topmenu' => 'Display LON-CAPA page header',
4864: 'inlinemenu'=> 'Display LON-CAPA inline menu',
4865: );
4866: return %lt;
4867: }
4868:
4869: sub lti_options {
4870: my ($num,$current,$itemcount,%lt) = @_;
4871: my (%checked,%rolemaps,$crssecsrc,$userfield,$cidfield);
4872: $checked{'mapuser'}{'sourcedid'} = ' checked="checked"';
4873: $checked{'mapcrs'}{'course_offering_sourcedid'} = ' checked="checked"';
4874: $checked{'makecrs'}{'N'} = ' checked="checked"';
4875: $checked{'mapcrstype'} = {};
4876: $checked{'makeuser'} = {};
4877: $checked{'selfenroll'} = {};
4878: $checked{'crssec'} = {};
4879: $checked{'crssecsrc'} = {};
4880: $checked{'lcauth'} = {};
4881: $checked{'menuitem'} = {};
4882: if ($num eq 'add') {
4883: $checked{'lcauth'}{'lti'} = ' checked="checked"';
4884: }
4885: my $userfieldsty = 'none';
4886: my $crsfieldsty = 'none';
4887: my $crssecfieldsty = 'none';
4888: my $secsrcfieldsty = 'none';
4889: my $passbacksty = 'none';
4890: my $lcauthparm;
4891: my $lcauthparmstyle = 'display:none';
4892: my $lcauthparmtext;
4893: my $menusty;
4894: my $numinrow = 4;
4895: my %menutitles = <imenu_titles();
4896:
4897: if (ref($current) eq 'HASH') {
4898: if (($current->{'mapuser'} ne '') && ($current->{'mapuser'} ne 'lis_person_sourcedid')) {
4899: $checked{'mapuser'}{'sourcedid'} = '';
4900: if ($current->{'mapuser'} eq 'lis_person_contact_email_primary') {
4901: $checked{'mapuser'}{'email'} = ' checked="checked"';
4902: } else {
4903: $checked{'mapuser'}{'other'} = ' checked="checked"';
4904: $userfield = $current->{'mapuser'};
4905: $userfieldsty = 'inline-block';
4906: }
4907: }
4908: if (($current->{'mapcrs'} ne '') && ($current->{'mapcrs'} ne 'course_offering_sourcedid')) {
4909: $checked{'mapcrs'}{'course_offering_sourcedid'} = '';
4910: if ($current->{'mapcrs'} eq 'context_id') {
4911: $checked{'mapcrs'}{'context_id'} = ' checked="checked"';
4912: } else {
4913: $checked{'mapcrs'}{'other'} = ' checked="checked"';
4914: $cidfield = $current->{'mapcrs'};
4915: $crsfieldsty = 'inline-block';
4916: }
4917: }
4918: if (ref($current->{'mapcrstype'}) eq 'ARRAY') {
4919: foreach my $type (@{$current->{'mapcrstype'}}) {
4920: $checked{'mapcrstype'}{$type} = ' checked="checked"';
4921: }
4922: }
4923: if ($current->{'makecrs'}) {
4924: $checked{'makecrs'}{'Y'} = ' checked="checked"';
4925: }
4926: if (ref($current->{'makeuser'}) eq 'ARRAY') {
4927: foreach my $role (@{$current->{'makeuser'}}) {
4928: $checked{'makeuser'}{$role} = ' checked="checked"';
4929: }
4930: }
4931: if ($current->{'lcauth'} =~ /^(internal|localauth|krb4|krb5|lti)$/) {
4932: $checked{'lcauth'}{$1} = ' checked="checked"';
4933: unless (($current->{'lcauth'} eq 'lti') || ($current->{'lcauth'} eq 'internal')) {
4934: $lcauthparm = $current->{'lcauthparm'};
4935: $lcauthparmstyle = 'display:table-row';
4936: if ($current->{'lcauth'} eq 'localauth') {
4937: $lcauthparmtext = &mt('Local auth argument');
4938: } else {
4939: $lcauthparmtext = &mt('Kerberos domain');
4940: }
4941: }
4942: }
4943: if (ref($current->{'selfenroll'}) eq 'ARRAY') {
4944: foreach my $role (@{$current->{'selfenroll'}}) {
4945: $checked{'selfenroll'}{$role} = ' checked="checked"';
4946: }
4947: }
4948: if (ref($current->{'maproles'}) eq 'HASH') {
4949: %rolemaps = %{$current->{'maproles'}};
4950: }
4951: if ($current->{'section'} ne '') {
4952: $checked{'crssec'}{'Y'} = ' checked="checked"';
4953: $crssecfieldsty = 'inline-block';
4954: if ($current->{'section'} eq 'course_section_sourcedid') {
4955: $checked{'crssecsrc'}{'sourcedid'} = ' checked="checked"';
4956: } else {
4957: $checked{'crssecsrc'}{'other'} = ' checked="checked"';
4958: $crssecsrc = $current->{'section'};
4959: $secsrcfieldsty = 'inline-block';
4960: }
4961: } else {
4962: $checked{'crssec'}{'N'} = ' checked="checked"';
4963: }
4964: if ($current->{'topmenu'}) {
4965: $checked{'topmenu'}{'Y'} = ' checked="checked"';
4966: } else {
4967: $checked{'topmenu'}{'N'} = ' checked="checked"';
4968: }
4969: if ($current->{'inlinemenu'}) {
4970: $checked{'inlinemenu'}{'Y'} = ' checked="checked"';
4971: } else {
4972: $checked{'inlinemenu'}{'N'} = ' checked="checked"';
4973: }
4974: if (($current->{'topmenu'}) || ($current->{'inlinemenu'})) {
4975: $menusty = 'inline-block';
4976: if (ref($current->{'lcmenu'}) eq 'ARRAY') {
4977: foreach my $item (@{$current->{'lcmenu'}}) {
4978: if (exists($menutitles{$item})) {
4979: $checked{'menuitem'}{$item} = ' checked="checked"';
4980: }
4981: }
4982: }
4983: } else {
4984: $menusty = 'none';
4985: }
4986: } else {
4987: $checked{'makecrs'}{'N'} = ' checked="checked"';
4988: $checked{'crssec'}{'N'} = ' checked="checked"';
4989: $checked{'topmenu'}{'N'} = ' checked="checked"';
4990: $checked{'inlinemenu'}{'Y'} = ' checked="checked"';
4991: $checked{'menuitem'}{'grades'} = ' checked="checked"';
4992: $menusty = 'inline-block';
4993: }
4994: my @coursetypes = ('official','unofficial','community','textbook','placement','lti');
4995: my %coursetypetitles = &Apache::lonlocal::texthash (
4996: official => 'Official',
4997: unofficial => 'Unofficial',
4998: community => 'Community',
4999: textbook => 'Textbook',
5000: placement => 'Placement Test',
5001: lti => 'LTI Provider',
5002: );
5003: my @authtypes = ('internal','krb4','krb5','localauth');
5004: my %shortauth = (
5005: internal => 'int',
5006: krb4 => 'krb4',
5007: krb5 => 'krb5',
5008: localauth => 'loc'
5009: );
5010: my %authnames = &authtype_names();
5011: my @ltiroles = qw(Learner Instructor ContentDeveloper TeachingAssistant Mentor Member Manager Administrator);
5012: my @lticourseroles = qw(Learner Instructor TeachingAssistant Mentor);
5013: my @courseroles = ('cc','in','ta','ep','st');
5014: my $onclickuser = ' onclick="toggleLTI(this.form,'."'user','$num'".');"';
5015: my $onclickcrs = ' onclick="toggleLTI(this.form,'."'crs','$num'".');"';
5016: my $onclicksec = ' onclick="toggleLTI(this.form,'."'sec','$num'".');"';
5017: my $onclicksecsrc = ' onclick="toggleLTI(this.form,'."'secsrc','$num'".')"';
5018: my $onclicklcauth = ' onclick="toggleLTI(this.form,'."'lcauth','$num'".')"';
5019: my $onclickmenu = ' onclick="toggleLTI(this.form,'."'lcmenu','$num'".');"';
5020: my $output = '<fieldset><legend>'.&mt('Mapping users').'</legend>'.
5021: '<div class="LC_floatleft"><span class="LC_nobreak">'.&mt('LON-CAPA username').': ';
5022: foreach my $option ('sourcedid','email','other') {
5023: $output .= '<label><input type="radio" name="lti_mapuser_'.$num.'" value="'.$option.'"'.
5024: $checked{'mapuser'}{$option}.$onclickuser.' />'.$lt{$option}.'</label>'.
5025: ($option eq 'other' ? '' : (' 'x2) );
5026: }
5027: $output .= '</span></div>'.
5028: '<div class="LC_floatleft" style="display:'.$userfieldsty.';" id="lti_userfield_'.$num.'">'.
5029: '<input type="text" name="lti_customuser_'.$num.'" '.
5030: 'value="'.$userfield.'" /></div></fieldset>'.
5031: '<fieldset><legend>'.&mt('Mapping course roles').'</legend><table><tr>';
5032: foreach my $ltirole (@lticourseroles) {
5033: my ($selected,$selectnone);
5034: if ($rolemaps{$ltirole} eq '') {
5035: $selectnone = ' selected="selected"';
5036: }
5037: $output .= '<td style="text-align: center">'.$ltirole.'<br />'.
5038: '<select name="lti_maprole_'.$ltirole.'_'.$num.'">'.
5039: '<option value=""'.$selectnone.'>'.&mt('Select').'</option>';
5040: foreach my $role (@courseroles) {
5041: unless ($selectnone) {
5042: if ($rolemaps{$ltirole} eq $role) {
5043: $selected = ' selected="selected"';
5044: } else {
5045: $selected = '';
5046: }
5047: }
5048: $output .= '<option value="'.$role.'"'.$selected.'>'.
5049: &Apache::lonnet::plaintext($role,'Course').
5050: '</option>';
5051: }
5052: $output .= '</select></td>';
5053: }
5054: $output .= '</tr></table></fieldset>'.
5055: '<fieldset><legend>'.&mt('Roles which may create user accounts').'</legend>';
5056: foreach my $ltirole (@ltiroles) {
5057: $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="lti_makeuser_'.$num.'" value="'.$ltirole.'"'.
5058: $checked{'makeuser'}{$ltirole}.' />'.$ltirole.'</label> </span> ';
5059: }
5060: $output .= '</fieldset>'.
5061: '<fieldset><legend>'.&mt('New user accounts created for LTI users').'</legend>'.
5062: '<table>'.
5063: &modifiable_userdata_row('lti','instdata_'.$num,$current,$numinrow,$itemcount).
5064: '</table>'.
5065: '<table class="LC_nested"><tr><td class="LC_left_item">LON-CAPA Authentication</td>'.
5066: '<td class="LC_left_item">';
5067: foreach my $auth ('lti',@authtypes) {
5068: my $authtext;
5069: if ($auth eq 'lti') {
5070: $authtext = &mt('None');
5071: } else {
5072: $authtext = $authnames{$shortauth{$auth}};
5073: }
5074: $output .= '<span class="LC_nobreak"><label><input type="radio" name="lti_lcauth_'.$num.
5075: '" value="'.$auth.'"'.$checked{'lcauth'}{$auth}.$onclicklcauth.' />'.
5076: $authtext.'</label></span> ';
5077: }
5078: $output .= '</td></tr>'.
5079: '<tr id="lti_lcauth_parmrow_'.$num.'" style="'.$lcauthparmstyle.'">'.
5080: '<td class="LC_right_item" colspan="2"><span class="LC_nobreak">'.
5081: '<span id="lti_lcauth_parmtext_'.$num.'">'.$lcauthparmtext.'</span>'.
5082: '<input type="text" name="lti_lcauthparm_'.$num.'" value="" /></span></td></tr>'.
5083: '</table></fieldset>'.
5084: '<fieldset><legend>'.&mt('Mapping courses').'</legend>'.
5085: '<div class="LC_floatleft"><span class="LC_nobreak">'.
5086: &mt('Unique course identifier').': ';
5087: foreach my $option ('course_offering_sourcedid','context_id','other') {
5088: $output .= '<label><input type="radio" name="lti_mapcrs_'.$num.'" value="'.$option.'"'.
5089: $checked{'mapcrs'}{$option}.$onclickcrs.' />'.$option.'</label>'.
5090: ($option eq 'other' ? '' : (' 'x2) );
5091: }
5092: $output .= '</span></div><div class="LC_floatleft" style="display:'.$crsfieldsty.';" id="lti_crsfield_'.$num.'">'.
5093: '<input type="text" name="lti_mapcrsfield_'.$num.'" value="'.$cidfield.'" />'.
5094: '</div><div style="padding:0;clear:both;margin:0;border:0"></div>'.
5095: '<span class="LC_nobreak">'.&mt('LON-CAPA course type(s)').': ';
5096: foreach my $type (@coursetypes) {
5097: $output .= '<label><input type="checkbox" name="lti_mapcrstype_'.$num.'" value="'.$type.'"'.
5098: $checked{'mapcrstype'}{$type}.' />'.$coursetypetitles{$type}.'</label>'.
5099: (' 'x2);
5100: }
5101: $output .= '</span></fieldset>'.
5102: '<fieldset><legend>'.&mt('Creating courses').'</legend>'.
5103: '<span class="LC_nobreak">'.&mt('Course created (if absent) on Instructor access').': '.
5104: '<label><input type="radio" name="lti_makecrs_'.$num.'" value="0"'.
5105: $checked{'makecrs'}{'N'}.' />'.&mt('No').'</label>'.(' 'x2).
5106: '<label><input type="radio" name="lti_makecrs_'.$num.'" value="1"'.
5107: $checked{'makecrs'}{'Y'}.' />'.&mt('Yes').'</label></span>'.
5108: '</fieldset>'.
5109: '<fieldset><legend>'.&mt('Roles which may self-enroll').'</legend>';
5110: foreach my $lticrsrole (@lticourseroles) {
5111: $output .= '<span class="LC_nobreak"><label><input type="checkbox" name="lti_selfenroll_'.$num.'" value="'.$lticrsrole.'"'.
5112: $checked{'selfenroll'}{$lticrsrole}.' />'.$lticrsrole.'</label> </span> ';
5113: }
5114: $output .= '</fieldset>'.
5115: '<fieldset><legend>'.&mt('Course options').'</legend>'.
5116: '<div class="LC_floatleft"><span class="LC_nobreak">'.&mt('Assign users to sections').': '.
5117: '<label><input type="radio" name="lti_crssec_'.$num.'" value="0"'.
5118: $checked{'crssec'}{'N'}.$onclicksec.' />'.&mt('No').'</label>'.(' 'x2).
5119: '<label><input type="radio" name="lti_crssec_'.$num.'" value="1"'.
5120: $checked{'crssec'}{'Y'}.$onclicksec.' />'.&mt('Yes').'</label></span></div>'.
5121: '<div class="LC_floatleft" style="display:'.$crssecfieldsty.';" id="lti_crssecfield_'.$num.'">'.
5122: '<span class="LC_nobreak">'.&mt('From').':<label>'.
5123: '<input type="radio" name="lti_crssecsrc_'.$num.'" value="course_section_sourcedid"'.
5124: $checked{'crssecsrc'}{'sourcedid'}.$onclicksecsrc.' />'.
5125: &mt('Standard field').'</label>'.(' 'x2).
5126: '<label><input type="radio" name="lti_crssecsrc_'.$num.'" value="other"'.
5127: $checked{'crssecsrc'}{'other'}.$onclicksecsrc.' />'.&mt('Other').
5128: '</label></span></div><div class="LC_floatleft" style="display:'.$secsrcfieldsty.';" id="lti_secsrcfield_'.$num.'">'.
5129: '<input type="text" name="lti_customsection_'.$num.'" value="'.$crssecsrc.'" />'.
5130: '</div><div style="padding:0;clear:both;margin:0;border:0"></div>';
5131: my ($pb1p1chk,$pb1p0chk,$onclickpb);
5132: foreach my $extra ('roster','passback') {
5133: my $checkedon = '';
5134: my $checkedoff = ' checked="checked"';
5135: if ($extra eq 'passback') {
5136: $pb1p1chk = ' checked="checked"';
5137: $pb1p0chk = '';
5138: $onclickpb = ' onclick="toggleLTI(this.form,'."'passback','$num'".');"';
5139: } else {
5140: $onclickpb = '';
5141: }
5142: if (ref($current) eq 'HASH') {
5143: if (($current->{$extra})) {
5144: $checkedon = $checkedoff;
5145: $checkedoff = '';
5146: if ($extra eq 'passback') {
5147: $passbacksty = 'inline-block';
5148: }
5149: if ($current->{'passbackformat'} eq '1.0') {
5150: $pb1p0chk = ' checked="checked"';
5151: $pb1p1chk = '';
5152: }
5153: }
5154: }
5155: $output .= $lt{$extra}.' '.
5156: '<label><input type="radio" name="lti_'.$extra.'_'.$num.'" value="0"'.$checkedoff.$onclickpb.' />'.
5157: &mt('No').'</label>'.(' 'x2).
5158: '<label><input type="radio" name="lti_'.$extra.'_'.$num.'" value="1"'.$checkedon.$onclickpb.' />'.
5159: &mt('Yes').'</label><br />';
5160: }
5161: $output .= '<div class="LC_floatleft" style="display:'.$passbacksty.';" id="lti_passback_'.$num.'">'.
5162: '<span class="LC_nobreak">'.&mt('Grade format').
5163: '<label><input type="radio" name="lti_passbackformat_'.$num.'" value="1.1"'.$pb1p1chk.' />'.
5164: &mt('Outcomes Service (1.1)').'</label>'.(' 'x2).
5165: '<label><input type="radio" name="lti_passbackformat_'.$num.'" value="1.0"'.$pb1p0chk.'/>'.
5166: &mt('Outcomes Extension (1.0)').'</label></span></div></fieldset>'.
5167: '<fieldset><legend>'.&mt('Course defaults (Course Coordinator can override)').'</legend>'.
5168: '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{'topmenu'}.': '.
5169: '<label><input type="radio" name="lti_topmenu_'.$num.'" value="0"'.
5170: $checked{'topmenu'}{'N'}.$onclickmenu.' />'.&mt('No').'</label>'.(' 'x2).
5171: '<label><input type="radio" name="lti_topmenu_'.$num.'" value="1"'.
5172: $checked{'topmenu'}{'Y'}.$onclickmenu.' />'.&mt('Yes').'</label></span></div>'.
5173: '<div style="padding:0;clear:both;margin:0;border:0"></div>'.
5174: '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{'inlinemenu'}.': '.
5175: '<label><input type="radio" name="lti_inlinemenu_'.$num.'" value="0"'.
5176: $checked{'inlinemenu'}{'N'}.$onclickmenu.' />'.&mt('No').'</label>'.(' 'x2).
5177: '<label><input type="radio" name="lti_inlinemenu_'.$num.'" value="1"'.
5178: $checked{'inlinemenu'}{'Y'}.$onclickmenu.' />'.&mt('Yes').'</label></span></div>';
5179: $output .='<div style="padding:0;clear:both;margin:0;border:0"></div>'.
5180: '<div class="LC_floatleft" style="display:'.$menusty.';" id="lti_menufield_'.$num.'">'.
5181: '<span class="LC_nobreak">'.&mt('Menu items').': ';
5182: foreach my $type ('fullname','coursetitle','role','logout','grades') {
5183: $output .= '<label><input type="checkbox" name="lti_menuitem_'.$num.'" value="'.$type.'"'.
5184: $checked{'menuitem'}{$type}.' />'.$menutitles{$type}.'</label>'.
5185: (' 'x2);
5186: }
5187: $output .= '</span></div></fieldset>';
5188: # '<fieldset><legend>'.&mt('Assigning author roles').'</legend>';
5189: #
5190: # $output .= '</fieldset>'.
5191: # '<fieldset><legend>'.&mt('Assigning domain roles').'</legend>';
5192: return $output;
5193: }
5194:
5195: sub ltimenu_titles {
5196: return &Apache::lonlocal::texthash(
5197: fullname => 'Full name',
5198: coursetitle => 'Course title',
5199: role => 'Role',
5200: logout => 'Logout',
5201: grades => 'Grades',
5202: );
5203: }
5204:
5205: sub print_coursedefaults {
5206: my ($position,$dom,$settings,$rowtotal) = @_;
5207: my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles);
5208: my $itemcount = 1;
5209: my %choices = &Apache::lonlocal::texthash (
5210: canuse_pdfforms => 'Course/Community users can create/upload PDF forms',
5211: uploadquota => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',
5212: anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',
5213: coursecredits => 'Credits can be specified for courses',
5214: uselcmath => 'Math preview uses LON-CAPA previewer (javascript) in place of DragMath (Java)',
5215: usejsme => 'Molecule editor uses JSME (HTML5) in place of JME (Java)',
5216: texengine => 'Default method to display mathematics',
5217: postsubmit => 'Disable submit button/keypress following student submission',
5218: canclone => "People who may clone a course (besides course's owner and coordinators)",
5219: mysqltables => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver',
5220: );
5221: my %staticdefaults = (
5222: texengine => 'MathJax',
5223: anonsurvey_threshold => 10,
5224: uploadquota => 500,
5225: postsubmit => 60,
5226: mysqltables => 172800,
5227: );
5228: if ($position eq 'top') {
5229: %defaultchecked = (
5230: 'canuse_pdfforms' => 'off',
5231: 'uselcmath' => 'on',
5232: 'usejsme' => 'on',
5233: 'canclone' => 'none',
5234: );
5235: @toggles = ('canuse_pdfforms','uselcmath','usejsme');
5236: my $deftex = $staticdefaults{'texengine'};
5237: if (ref($settings) eq 'HASH') {
5238: if ($settings->{'texengine'}) {
5239: if ($settings->{'texengine'} =~ /^(MathJax|mimetex|tth)$/) {
5240: $deftex = $settings->{'texengine'};
5241: }
5242: }
5243: }
5244: $css_class = $itemcount%2?' class="LC_odd_row"':'';
5245: my $mathdisp = '<tr'.$css_class.'><td style="vertical-align: top">'.
5246: '<span class="LC_nobreak">'.$choices{'texengine'}.
5247: '</span></td><td class="LC_right_item">'.
5248: '<select name="texengine">'."\n";
5249: my %texoptions = (
5250: MathJax => 'MathJax',
5251: mimetex => &mt('Convert to Images'),
5252: tth => &mt('TeX to HTML'),
5253: );
5254: foreach my $renderer ('MathJax','mimetex','tth') {
5255: my $selected = '';
5256: if ($renderer eq $deftex) {
5257: $selected = ' selected="selected"';
5258: }
5259: $mathdisp .= '<option value="'.$renderer.'"'.$selected.'>'.$texoptions{$renderer}.'</option>'."\n";
5260: }
5261: $mathdisp .= '</select></td></tr>'."\n";
5262: $itemcount ++;
5263: ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
5264: \%choices,$itemcount);
5265: $datatable = $mathdisp.$datatable;
5266: $css_class = $itemcount%2?' class="LC_odd_row"':'';
5267: $datatable .=
5268: '<tr'.$css_class.'><td style="vertical-align: top">'.
5269: '<span class="LC_nobreak">'.$choices{'canclone'}.
5270: '</span></td><td class="LC_left_item">';
5271: my $currcanclone = 'none';
5272: my $onclick;
5273: my @cloneoptions = ('none','domain');
5274: my %clonetitles = (
5275: none => 'No additional course requesters',
5276: domain => "Any course requester in course's domain",
5277: instcode => 'Course requests for official courses ...',
5278: );
5279: my (%codedefaults,@code_order,@posscodes);
5280: if (&Apache::lonnet::auto_instcode_defaults($dom,\%codedefaults,
5281: \@code_order) eq 'ok') {
5282: if (@code_order > 0) {
5283: push(@cloneoptions,'instcode');
5284: $onclick = ' onclick="toggleDisplay(this.form,'."'cloneinstcode'".');"';
5285: }
5286: }
5287: if (ref($settings) eq 'HASH') {
5288: if ($settings->{'canclone'}) {
5289: if (ref($settings->{'canclone'}) eq 'HASH') {
5290: if (ref($settings->{'canclone'}{'instcode'}) eq 'ARRAY') {
5291: if (@code_order > 0) {
5292: $currcanclone = 'instcode';
5293: @posscodes = @{$settings->{'canclone'}{'instcode'}};
5294: }
5295: }
5296: } elsif ($settings->{'canclone'} eq 'domain') {
5297: $currcanclone = $settings->{'canclone'};
5298: }
5299: }
5300: }
5301: foreach my $option (@cloneoptions) {
5302: my ($checked,$additional);
5303: if ($currcanclone eq $option) {
5304: $checked = ' checked="checked"';
5305: }
5306: if ($option eq 'instcode') {
5307: if (@code_order) {
5308: my $show = 'none';
5309: if ($checked) {
5310: $show = 'block';
5311: }
5312: $additional = '<div id="cloneinstcode" style="display:'.$show.';" />'.
5313: &mt('Institutional codes for new and cloned course have identical:').
5314: '<br />';
5315: foreach my $item (@code_order) {
5316: my $codechk;
5317: if ($checked) {
5318: if (grep(/^\Q$item\E$/,@posscodes)) {
5319: $codechk = ' checked="checked"';
5320: }
5321: }
5322: $additional .= '<label>'.
5323: '<input type="checkbox" name="clonecode" value="'.$item.'"'.$codechk.' />'.
5324: $item.'</label>';
5325: }
5326: $additional .= (' 'x2).'('.&mt('check as many as needed').')</div>';
5327: }
5328: }
5329: $datatable .=
5330: '<span class="LC_nobreak"><label><input type="radio" name="canclone"'.$checked.
5331: ' value="'.$option.'"'.$onclick.' />'.$clonetitles{$option}.
5332: '</label> '.$additional.'</span><br />';
5333: }
5334: $datatable .= '</td>'.
5335: '</tr>';
5336: $itemcount ++;
5337: } else {
5338: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
5339: my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql);
5340: my $currusecredits = 0;
5341: my $postsubmitclient = 1;
5342: my @types = ('official','unofficial','community','textbook','placement');
5343: if (ref($settings) eq 'HASH') {
5344: $currdefresponder = $settings->{'anonsurvey_threshold'};
5345: if (ref($settings->{'uploadquota'}) eq 'HASH') {
5346: foreach my $type (keys(%{$settings->{'uploadquota'}})) {
5347: $curruploadquota{$type} = $settings->{'uploadquota'}{$type};
5348: }
5349: }
5350: if (ref($settings->{'coursecredits'}) eq 'HASH') {
5351: foreach my $type (@types) {
5352: next if ($type eq 'community');
5353: $defcredits{$type} = $settings->{'coursecredits'}->{$type};
5354: if ($defcredits{$type} ne '') {
5355: $currusecredits = 1;
5356: }
5357: }
5358: }
5359: if (ref($settings->{'postsubmit'}) eq 'HASH') {
5360: if ($settings->{'postsubmit'}->{'client'} eq 'off') {
5361: $postsubmitclient = 0;
5362: foreach my $type (@types) {
5363: $deftimeout{$type} = $staticdefaults{'postsubmit'};
5364: }
5365: } else {
5366: foreach my $type (@types) {
5367: if (ref($settings->{'postsubmit'}->{'timeout'}) eq 'HASH') {
5368: if ($settings->{'postsubmit'}->{'timeout'}->{$type} =~ /^\d+$/) {
5369: $deftimeout{$type} = $settings->{'postsubmit'}->{'timeout'}->{$type};
5370: } else {
5371: $deftimeout{$type} = $staticdefaults{'postsubmit'};
5372: }
5373: } else {
5374: $deftimeout{$type} = $staticdefaults{'postsubmit'};
5375: }
5376: }
5377: }
5378: } else {
5379: foreach my $type (@types) {
5380: $deftimeout{$type} = $staticdefaults{'postsubmit'};
5381: }
5382: }
5383: if (ref($settings->{'mysqltables'}) eq 'HASH') {
5384: foreach my $type (keys(%{$settings->{'mysqltables'}})) {
5385: $currmysql{$type} = $settings->{'mysqltables'}{$type};
5386: }
5387: } else {
5388: foreach my $type (@types) {
5389: $currmysql{$type} = $staticdefaults{'mysqltables'};
5390: }
5391: }
5392: } else {
5393: foreach my $type (@types) {
5394: $deftimeout{$type} = $staticdefaults{'postsubmit'};
5395: }
5396: }
5397: if (!$currdefresponder) {
5398: $currdefresponder = $staticdefaults{'anonsurvey_threshold'};
5399: } elsif ($currdefresponder < 1) {
5400: $currdefresponder = 1;
5401: }
5402: foreach my $type (@types) {
5403: if ($curruploadquota{$type} eq '') {
5404: $curruploadquota{$type} = $staticdefaults{'uploadquota'};
5405: }
5406: }
5407: $datatable .=
5408: '<tr'.$css_class.'><td><span class="LC_nobreak">'.
5409: $choices{'anonsurvey_threshold'}.
5410: '</span></td>'.
5411: '<td class="LC_right_item"><span class="LC_nobreak">'.
5412: '<input type="text" name="anonsurvey_threshold"'.
5413: ' value="'.$currdefresponder.'" size="5" /></span>'.
5414: '</td></tr>'."\n";
5415: $itemcount ++;
5416: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
5417: $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
5418: $choices{'uploadquota'}.
5419: '</span></td>'.
5420: '<td style="text-align: right" class="LC_right_item">'.
5421: '<table><tr>';
5422: foreach my $type (@types) {
5423: $datatable .= '<td style="text-align: center">'.&mt($type).'<br />'.
5424: '<input type="text" name="uploadquota_'.$type.'"'.
5425: ' value="'.$curruploadquota{$type}.'" size="5" /></td>';
5426: }
5427: $datatable .= '</tr></table></td></tr>'."\n";
5428: $itemcount ++;
5429: my $onclick = "toggleDisplay(this.form,'credits');";
5430: my $display = 'none';
5431: if ($currusecredits) {
5432: $display = 'block';
5433: }
5434: my $additional = '<div id="credits" style="display: '.$display.'">'.
5435: '<i>'.&mt('Default credits').'</i><br /><table><tr>';
5436: foreach my $type (@types) {
5437: next if ($type eq 'community');
5438: $additional .= '<td style="text-align: center">'.&mt($type).'<br />'.
5439: '<input type="text" name="'.$type.'_credits"'.
5440: ' value="'.$defcredits{$type}.'" size="3" /></td>';
5441: }
5442: $additional .= '</tr></table></div>'."\n";
5443: %defaultchecked = ('coursecredits' => 'off');
5444: @toggles = ('coursecredits');
5445: my $current = {
5446: 'coursecredits' => $currusecredits,
5447: };
5448: (my $table,$itemcount) =
5449: &radiobutton_prefs($current,\@toggles,\%defaultchecked,
5450: \%choices,$itemcount,$onclick,$additional,'left');
5451: $datatable .= $table;
5452: $onclick = "toggleDisplay(this.form,'studentsubmission');";
5453: my $display = 'none';
5454: if ($postsubmitclient) {
5455: $display = 'block';
5456: }
5457: $additional = '<div id="studentsubmission" style="display: '.$display.'">'.
5458: &mt('Number of seconds submit is disabled').'<br />'.
5459: '<i>'.&mt('Enter 0 to remain disabled until page reload.').'</i><br />'.
5460: '<table><tr>';
5461: foreach my $type (@types) {
5462: $additional .= '<td style="text-align: center">'.&mt($type).'<br />'.
5463: '<input type="text" name="'.$type.'_timeout" value="'.
5464: $deftimeout{$type}.'" size="5" /></td>';
5465: }
5466: $additional .= '</tr></table></div>'."\n";
5467: %defaultchecked = ('postsubmit' => 'on');
5468: @toggles = ('postsubmit');
5469: $current = {
5470: 'postsubmit' => $postsubmitclient,
5471: };
5472: ($table,$itemcount) =
5473: &radiobutton_prefs($current,\@toggles,\%defaultchecked,
5474: \%choices,$itemcount,$onclick,$additional,'left');
5475: $datatable .= $table;
5476: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
5477: $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
5478: $choices{'mysqltables'}.
5479: '</span></td>'.
5480: '<td style="text-align: right" class="LC_right_item">'.
5481: '<table><tr>';
5482: foreach my $type (@types) {
5483: $datatable .= '<td style="text-align: center">'.&mt($type).'<br />'.
5484: '<input type="text" name="mysqltables_'.$type.'"'.
5485: ' value="'.$currmysql{$type}.'" size="8" /></td>';
5486: }
5487: $datatable .= '</tr></table></td></tr>'."\n";
5488: $itemcount ++;
5489:
5490: }
5491: $$rowtotal += $itemcount;
5492: return $datatable;
5493: }
5494:
5495: sub print_selfenrollment {
5496: my ($position,$dom,$settings,$rowtotal) = @_;
5497: my ($css_class,$datatable);
5498: my $itemcount = 1;
5499: my @types = ('official','unofficial','community','textbook','placement');
5500: if (($position eq 'top') || ($position eq 'middle')) {
5501: my ($rowsref,$titlesref) = &Apache::lonuserutils::get_selfenroll_titles();
5502: my %descs = &Apache::lonuserutils::selfenroll_default_descs();
5503: my @rows;
5504: my $key;
5505: if ($position eq 'top') {
5506: $key = 'admin';
5507: if (ref($rowsref) eq 'ARRAY') {
5508: @rows = @{$rowsref};
5509: }
5510: } elsif ($position eq 'middle') {
5511: $key = 'default';
5512: @rows = ('types','registered','approval','limit');
5513: }
5514: foreach my $row (@rows) {
5515: if (defined($titlesref->{$row})) {
5516: $itemcount ++;
5517: $css_class = $itemcount%2?' class="LC_odd_row"':'';
5518: $datatable .= '<tr'.$css_class.'>'.
5519: '<td>'.$titlesref->{$row}.'</td>'.
5520: '<td class="LC_left_item">'.
5521: '<table><tr>';
5522: my (%current,%currentcap);
5523: if (ref($settings) eq 'HASH') {
5524: if (ref($settings->{$key}) eq 'HASH') {
5525: foreach my $type (@types) {
5526: if (ref($settings->{$key}->{$type}) eq 'HASH') {
5527: $current{$type} = $settings->{$key}->{$type}->{$row};
5528: }
5529: if (($row eq 'limit') && ($key eq 'default')) {
5530: if (ref($settings->{$key}->{$type}) eq 'HASH') {
5531: $currentcap{$type} = $settings->{$key}->{$type}->{'cap'};
5532: }
5533: }
5534: }
5535: }
5536: }
5537: my %roles = (
5538: '0' => &Apache::lonnet::plaintext('dc'),
5539: );
5540:
5541: foreach my $type (@types) {
5542: unless (($row eq 'registered') && ($key eq 'default')) {
5543: $datatable .= '<th>'.&mt($type).'</th>';
5544: }
5545: }
5546: unless (($row eq 'registered') && ($key eq 'default')) {
5547: $datatable .= '</tr><tr>';
5548: }
5549: foreach my $type (@types) {
5550: if ($type eq 'community') {
5551: $roles{'1'} = &mt('Community personnel');
5552: } else {
5553: $roles{'1'} = &mt('Course personnel');
5554: }
5555: $datatable .= '<td style="vertical-align: top">';
5556: if ($position eq 'top') {
5557: my %checked;
5558: if ($current{$type} eq '0') {
5559: $checked{'0'} = ' checked="checked"';
5560: } else {
5561: $checked{'1'} = ' checked="checked"';
5562: }
5563: foreach my $role ('1','0') {
5564: $datatable .= '<span class="LC_nobreak"><label>'.
5565: '<input type="radio" name="selfenrolladmin_'.$row.'_'.$type.'" '.
5566: 'value="'.$role.'"'.$checked{$role}.' />'.
5567: $roles{$role}.'</label></span> ';
5568: }
5569: } else {
5570: if ($row eq 'types') {
5571: my %checked;
5572: if ($current{$type} =~ /^(all|dom)$/) {
5573: $checked{$1} = ' checked="checked"';
5574: } else {
5575: $checked{''} = ' checked="checked"';
5576: }
5577: foreach my $val ('','dom','all') {
5578: $datatable .= '<span class="LC_nobreak"><label>'.
5579: '<input type ="radio" name="selfenrolldefault_'.$row.'_'.$type.'" '.
5580: 'value="'.$val.'"'.$checked{$val}.' />'.$descs{$row}{$val}.'</label></span> ';
5581: }
5582: } elsif ($row eq 'registered') {
5583: my %checked;
5584: if ($current{$type} eq '1') {
5585: $checked{'1'} = ' checked="checked"';
5586: } else {
5587: $checked{'0'} = ' checked="checked"';
5588: }
5589: foreach my $val ('0','1') {
5590: $datatable .= '<span class="LC_nobreak"><label>'.
5591: '<input type ="radio" name="selfenrolldefault_'.$row.'_'.$type.'" '.
5592: 'value="'.$val.'"'.$checked{$val}.' />'.$descs{$row}{$val}.'</label></span> ';
5593: }
5594: } elsif ($row eq 'approval') {
5595: my %checked;
5596: if ($current{$type} =~ /^([12])$/) {
5597: $checked{$1} = ' checked="checked"';
5598: } else {
5599: $checked{'0'} = ' checked="checked"';
5600: }
5601: for my $val (0..2) {
5602: $datatable .= '<span class="LC_nobreak"><label>'.
5603: '<input type="radio" name="selfenrolldefault_'.$row.'_'.$type.'" '.
5604: 'value="'.$val.'"'.$checked{$val}.' />'.$descs{$row}{$val}.'</label></span> ';
5605: }
5606: } elsif ($row eq 'limit') {
5607: my %checked;
5608: if ($current{$type} =~ /^(allstudents|selfenrolled)$/) {
5609: $checked{$1} = ' checked="checked"';
5610: } else {
5611: $checked{'none'} = ' checked="checked"';
5612: }
5613: my $cap;
5614: if ($currentcap{$type} =~ /^\d+$/) {
5615: $cap = $currentcap{$type};
5616: }
5617: foreach my $val ('none','allstudents','selfenrolled') {
5618: $datatable .= '<span class="LC_nobreak"><label>'.
5619: '<input type="radio" name="selfenrolldefault_'.$row.'_'.$type.'" '.
5620: 'value="'.$val.'"'.$checked{$val}.' />'.$descs{$row}{$val}.'</label></span> ';
5621: }
5622: $datatable .= '<br />'.
5623: '<span class="LC_nobreak">'.&mt('Maximum allowed: ').
5624: '<input type="text" name="selfenrolldefault_cap_'.$type.'" size = "5" value="'.$cap.'" />'.
5625: '</span>';
5626: }
5627: }
5628: $datatable .= '</td>';
5629: }
5630: $datatable .= '</tr>';
5631: }
5632: $datatable .= '</table></td></tr>';
5633: }
5634: } elsif ($position eq 'bottom') {
5635: $datatable .= &print_validation_rows('selfenroll',$dom,$settings,\$itemcount);
5636: }
5637: $$rowtotal += $itemcount;
5638: return $datatable;
5639: }
5640:
5641: sub print_validation_rows {
5642: my ($caller,$dom,$settings,$rowtotal) = @_;
5643: my ($itemsref,$namesref,$fieldsref);
5644: if ($caller eq 'selfenroll') {
5645: ($itemsref,$namesref,$fieldsref) = &Apache::lonuserutils::selfenroll_validation_types();
5646: } elsif ($caller eq 'requestcourses') {
5647: ($itemsref,$namesref,$fieldsref) = &Apache::loncoursequeueadmin::requestcourses_validation_types();
5648: }
5649: my %currvalidation;
5650: if (ref($settings) eq 'HASH') {
5651: if (ref($settings->{'validation'}) eq 'HASH') {
5652: %currvalidation = %{$settings->{'validation'}};
5653: }
5654: }
5655: my $datatable;
5656: my $itemcount = 0;
5657: foreach my $item (@{$itemsref}) {
5658: my $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
5659: $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
5660: $namesref->{$item}.
5661: '</span></td>'.
5662: '<td class="LC_left_item">';
5663: if (($item eq 'url') || ($item eq 'button')) {
5664: $datatable .= '<span class="LC_nobreak">'.
5665: '<input type="text" name="'.$caller.'_validation_'.$item.'"'.
5666: ' value="'.$currvalidation{$item}.'" size="50" /></span>';
5667: } elsif ($item eq 'fields') {
5668: my @currfields;
5669: if (ref($currvalidation{$item}) eq 'ARRAY') {
5670: @currfields = @{$currvalidation{$item}};
5671: }
5672: foreach my $field (@{$fieldsref}) {
5673: my $check = '';
5674: if (grep(/^\Q$field\E$/,@currfields)) {
5675: $check = ' checked="checked"';
5676: }
5677: $datatable .= '<span class="LC_nobreak"><label>'.
5678: '<input type="checkbox" name="'.$caller.'_validation_fields"'.
5679: ' value="'.$field.'"'.$check.' />'.$field.
5680: '</label></span> ';
5681: }
5682: } elsif ($item eq 'markup') {
5683: $datatable .= '<textarea name="'.$caller.'_validation_markup" cols="50" rows="5">'.
5684: $currvalidation{$item}.
5685: '</textarea>';
5686: }
5687: $datatable .= '</td></tr>'."\n";
5688: if (ref($rowtotal)) {
5689: $itemcount ++;
5690: }
5691: }
5692: if ($caller eq 'requestcourses') {
5693: my %currhash;
5694: if (ref($settings) eq 'HASH') {
5695: if (ref($settings->{'validation'}) eq 'HASH') {
5696: if ($settings->{'validation'}{'dc'} ne '') {
5697: $currhash{$settings->{'validation'}{'dc'}} = 1;
5698: }
5699: }
5700: }
5701: my $numinrow = 2;
5702: my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio',
5703: 'validationdc',%currhash);
5704: my $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
5705: $datatable .= '<tr'.$css_class.'><td>';
5706: if ($numdc > 1) {
5707: $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)');
5708: } else {
5709: $datatable .= &mt('Course creation processed as: ');
5710: }
5711: $datatable .= '</td><td class="LC_left_item">'.$dctable.'</td></tr>';
5712: $itemcount ++;
5713: }
5714: if (ref($rowtotal)) {
5715: $$rowtotal += $itemcount;
5716: }
5717: return $datatable;
5718: }
5719:
5720: sub print_usersessions {
5721: my ($position,$dom,$settings,$rowtotal) = @_;
5722: my ($css_class,$datatable,$itemcount,%checked,%choices);
5723: my (%by_ip,%by_location,@intdoms,@instdoms);
5724: &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
5725:
5726: my @alldoms = &Apache::lonnet::all_domains();
5727: my %serverhomes = %Apache::lonnet::serverhomeIDs;
5728: my %servers = &Apache::lonnet::internet_dom_servers($dom);
5729: my %altids = &id_for_thisdom(%servers);
5730: if ($position eq 'top') {
5731: if (keys(%serverhomes) > 1) {
5732: my %spareid = ¤t_offloads_to($dom,$settings,\%servers);
5733: my $curroffloadnow;
5734: if (ref($settings) eq 'HASH') {
5735: if (ref($settings->{'offloadnow'}) eq 'HASH') {
5736: $curroffloadnow = $settings->{'offloadnow'};
5737: }
5738: }
5739: $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal);
5740: } else {
5741: $datatable .= '<tr'.$css_class.'><td colspan="2">'.
5742: &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.').
5743: '</td></tr>';
5744: }
5745: } else {
5746: my %titles = &usersession_titles();
5747: my ($prefix,@types);
5748: if ($position eq 'bottom') {
5749: $prefix = 'remote';
5750: @types = ('version','excludedomain','includedomain');
5751: } else {
5752: $prefix = 'hosted';
5753: @types = ('excludedomain','includedomain');
5754: }
5755: ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
5756: }
5757: $$rowtotal += $itemcount;
5758: return $datatable;
5759: }
5760:
5761: sub rules_by_location {
5762: my ($settings,$prefix,$by_location,$by_ip,$types,$titles) = @_;
5763: my ($datatable,$itemcount,$css_class);
5764: if (keys(%{$by_location}) == 0) {
5765: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
5766: $datatable = '<tr'.$css_class.'><td colspan="2">'.
5767: &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.').
5768: '</td></tr>';
5769: $itemcount = 1;
5770: } else {
5771: $itemcount = 0;
5772: my $numinrow = 5;
5773: my (%current,%checkedon,%checkedoff);
5774: my @locations = sort(keys(%{$by_location}));
5775: foreach my $type (@{$types}) {
5776: $checkedon{$type} = '';
5777: $checkedoff{$type} = ' checked="checked"';
5778: }
5779: if (ref($settings) eq 'HASH') {
5780: if (ref($settings->{$prefix}) eq 'HASH') {
5781: foreach my $key (keys(%{$settings->{$prefix}})) {
5782: $current{$key} = $settings->{$prefix}{$key};
5783: if ($key eq 'version') {
5784: if ($current{$key} ne '') {
5785: $checkedon{$key} = ' checked="checked"';
5786: $checkedoff{$key} = '';
5787: }
5788: } elsif (ref($current{$key}) eq 'ARRAY') {
5789: $checkedon{$key} = ' checked="checked"';
5790: $checkedoff{$key} = '';
5791: }
5792: }
5793: }
5794: }
5795: foreach my $type (@{$types}) {
5796: next if ($type ne 'version' && !@locations);
5797: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
5798: $datatable .= '<tr'.$css_class.'>
5799: <td><span class="LC_nobreak">'.$titles->{$type}.'</span><br />
5800: <span class="LC_nobreak">
5801: <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label>
5802: <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>';
5803: if ($type eq 'version') {
5804: my @lcversions = &Apache::lonnet::all_loncaparevs();
5805: my $selector = '<select name="'.$prefix.'_version">';
5806: foreach my $version (@lcversions) {
5807: my $selected = '';
5808: if ($current{'version'} eq $version) {
5809: $selected = ' selected="selected"';
5810: }
5811: $selector .= ' <option value="'.$version.'"'.
5812: $selected.'>'.$version.'</option>';
5813: }
5814: $selector .= '</select> ';
5815: $datatable .= &mt('remote server must be version: [_1] or later',$selector);
5816: } else {
5817: $datatable.= '<div><input type="button" value="'.&mt('check all').'" '.
5818: 'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'.
5819: ' />'.(' 'x2).
5820: '<input type="button" value="'.&mt('uncheck all').'" '.
5821: 'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'.
5822: "\n".
5823: '</div><div><table>';
5824: my $rem;
5825: for (my $i=0; $i<@locations; $i++) {
5826: my ($showloc,$value,$checkedtype);
5827: if (ref($by_location->{$locations[$i]}) eq 'ARRAY') {
5828: my $ip = $by_location->{$locations[$i]}->[0];
5829: if (ref($by_ip->{$ip}) eq 'ARRAY') {
5830: $value = join(':',@{$by_ip->{$ip}});
5831: $showloc = join(', ',@{$by_ip->{$ip}});
5832: if (ref($current{$type}) eq 'ARRAY') {
5833: foreach my $loc (@{$by_ip->{$ip}}) {
5834: if (grep(/^\Q$loc\E$/,@{$current{$type}})) {
5835: $checkedtype = ' checked="checked"';
5836: last;
5837: }
5838: }
5839: }
5840: }
5841: }
5842: $rem = $i%($numinrow);
5843: if ($rem == 0) {
5844: if ($i > 0) {
5845: $datatable .= '</tr>';
5846: }
5847: $datatable .= '<tr>';
5848: }
5849: $datatable .= '<td class="LC_left_item">'.
5850: '<span class="LC_nobreak"><label>'.
5851: '<input type="checkbox" name="'.$prefix.'_'.$type.
5852: '" value="'.$value.'"'.$checkedtype.' />'.$showloc.
5853: '</label></span></td>';
5854: }
5855: $rem = @locations%($numinrow);
5856: my $colsleft = $numinrow - $rem;
5857: if ($colsleft > 1 ) {
5858: $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
5859: ' </td>';
5860: } elsif ($colsleft == 1) {
5861: $datatable .= '<td class="LC_left_item"> </td>';
5862: }
5863: $datatable .= '</tr></table>';
5864: }
5865: $datatable .= '</td></tr>';
5866: $itemcount ++;
5867: }
5868: }
5869: return ($datatable,$itemcount);
5870: }
5871:
5872: sub print_ssl {
5873: my ($position,$dom,$settings,$rowtotal) = @_;
5874: my ($css_class,$datatable);
5875: my $itemcount = 1;
5876: if ($position eq 'top') {
5877: my $primary_id = &Apache::lonnet::domain($dom,'primary');
5878: my $intdom = &Apache::lonnet::internet_dom($primary_id);
5879: my $same_institution;
5880: if ($intdom ne '') {
5881: my $internet_names = &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'});
5882: if (ref($internet_names) eq 'ARRAY') {
5883: if (grep(/^\Q$intdom\E$/,@{$internet_names})) {
5884: $same_institution = 1;
5885: }
5886: }
5887: }
5888: $css_class = $itemcount%2?' class="LC_odd_row"':'';
5889: $datatable = '<tr'.$css_class.'><td colspan="2">';
5890: if ($same_institution) {
5891: my %domservers = &Apache::lonnet::get_servers($dom);
5892: $datatable .= &LONCAPA::SSL::print_certstatus(\%domservers,'web','domprefs');
5893: } else {
5894: $datatable .= &mt("You need to be logged into one of your own domain's servers to display information about the status of LON-CAPA SSL certificates.");
5895: }
5896: $datatable .= '</td></tr>';
5897: $itemcount ++;
5898: } else {
5899: my %titles = &ssl_titles();
5900: my (%by_ip,%by_location,@intdoms,@instdoms);
5901: &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
5902: my @alldoms = &Apache::lonnet::all_domains();
5903: my %serverhomes = %Apache::lonnet::serverhomeIDs;
5904: my @domservers = &Apache::lonnet::get_servers($dom);
5905: my %servers = &Apache::lonnet::internet_dom_servers($dom);
5906: my %altids = &id_for_thisdom(%servers);
5907: if (($position eq 'connto') || ($position eq 'connfrom')) {
5908: my $legacy;
5909: unless (ref($settings) eq 'HASH') {
5910: my $name;
5911: if ($position eq 'connto') {
5912: $name = 'loncAllowInsecure';
5913: } else {
5914: $name = 'londAllowInsecure';
5915: }
5916: my $primarylibserv = &Apache::lonnet::domain($dom,'primary');
5917: my @ids=&Apache::lonnet::current_machine_ids();
5918: if (($primarylibserv ne '') && (!grep(/^\Q$primarylibserv\E$/,@ids))) {
5919: my %what = (
5920: $name => 1,
5921: );
5922: my ($result,$returnhash) =
5923: &Apache::lonnet::get_remote_globals($primarylibserv,\%what);
5924: if ($result eq 'ok') {
5925: if (ref($returnhash) eq 'HASH') {
5926: $legacy = $returnhash->{$name};
5927: }
5928: }
5929: } else {
5930: $legacy = $Apache::lonnet::perlvar{$name};
5931: }
5932: }
5933: foreach my $type ('dom','intdom','other') {
5934: my %checked;
5935: $css_class = $itemcount%2?' class="LC_odd_row"':'';
5936: $datatable .= '<tr'.$css_class.'><td>'.$titles{$type}.'</td>'.
5937: '<td class="LC_right_item">';
5938: my $skip;
5939: if ($type eq 'dom') {
5940: unless (keys(%servers) > 1) {
5941: $datatable .= &mt('Nothing to set here, as there are no other servers/VMs');
5942: $skip = 1;
5943: }
5944: }
5945: if ($type eq 'intdom') {
5946: unless (@instdoms > 1) {
5947: $datatable .= &mt('Nothing to set here, as there are no other domains for this institution');
5948: $skip = 1;
5949: }
5950: } elsif ($type eq 'other') {
5951: if (keys(%by_location) == 0) {
5952: $datatable .= &mt('Nothing to set here, as there are no other institutions');
5953: $skip = 1;
5954: }
5955: }
5956: unless ($skip) {
5957: $checked{'yes'} = ' checked="checked"';
5958: if (ref($settings) eq 'HASH') {
5959: if (ref($settings->{$position}) eq 'HASH') {
5960: if ($settings->{$position}->{$type} =~ /^(no|req)$/) {
5961: $checked{$1} = $checked{'yes'};
5962: delete($checked{'yes'});
5963: }
5964: }
5965: } else {
5966: if ($legacy == 0) {
5967: $checked{'req'} = $checked{'yes'};
5968: delete($checked{'yes'});
5969: }
5970: }
5971: foreach my $option ('no','yes','req') {
5972: $datatable .= '<span class="LC_nobreak"><label>'.
5973: '<input type="radio" name="'.$position.'_'.$type.'" '.
5974: 'value="'.$option.'"'.$checked{$option}.' />'.$titles{$option}.
5975: '</label></span>'.(' 'x2);
5976: }
5977: }
5978: $datatable .= '</td></tr>';
5979: $itemcount ++;
5980: }
5981: } else {
5982: my $prefix = 'replication';
5983: my @types = ('certreq','nocertreq');
5984: if (keys(%by_location) == 0) {
5985: $datatable .= '<tr'.$css_class.'><td>'.
5986: &mt('Nothing to set here, as there are no other institutions').
5987: '</td></tr>';
5988: $itemcount ++;
5989: } else {
5990: ($datatable,$itemcount) =
5991: &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
5992: }
5993: }
5994: }
5995: $$rowtotal += $itemcount;
5996: return $datatable;
5997: }
5998:
5999: sub ssl_titles {
6000: return &Apache::lonlocal::texthash (
6001: dom => 'LON-CAPA servers/VMs from same domain',
6002: intdom => 'LON-CAPA servers/VMs from same "internet" domain',
6003: other => 'External LON-CAPA servers/VMs',
6004: connto => 'Connections to other servers',
6005: connfrom => 'Connections from other servers',
6006: replication => 'Replicating content to other institutions',
6007: certreq => 'Client certificate required, but specific domains exempt',
6008: nocertreq => 'No client certificate required, except for specific domains',
6009: no => 'SSL not used',
6010: yes => 'SSL Optional (used if available)',
6011: req => 'SSL Required',
6012: );
6013: }
6014:
6015: sub print_trust {
6016: my ($prefix,$dom,$settings,$rowtotal) = @_;
6017: my ($css_class,$datatable,%checked,%choices);
6018: my (%by_ip,%by_location,@intdoms,@instdoms);
6019: &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
6020: my $itemcount = 1;
6021: my %titles = &trust_titles();
6022: my @types = ('exc','inc');
6023: if ($prefix eq 'top') {
6024: $prefix = 'content';
6025: } elsif ($prefix eq 'bottom') {
6026: $prefix = 'msg';
6027: }
6028: ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles);
6029: $$rowtotal += $itemcount;
6030: return $datatable;
6031: }
6032:
6033: sub trust_titles {
6034: return &Apache::lonlocal::texthash(
6035: content => "Access to this domain's content by others",
6036: shared => "Access to other domain's content by this domain",
6037: enroll => "Enrollment in this domain's courses by others",
6038: othcoau => "Co-author roles in this domain for others",
6039: coaurem => "Co-author roles for this domain's users elsewhere",
6040: domroles => "Domain roles in this domain assignable to others",
6041: catalog => "Course Catalog for this domain displayed elsewhere",
6042: reqcrs => "Requests for creation of courses in this domain by others",
6043: msg => "Users in other domains can send messages to this domain",
6044: exc => "Allow all, but exclude specific domains",
6045: inc => "Deny all, but include specific domains",
6046: );
6047: }
6048:
6049: sub build_location_hashes {
6050: my ($intdoms,$by_ip,$by_location,$instdoms) = @_;
6051: return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') &&
6052: (ref($by_location) eq 'HASH') && (ref($instdoms) eq 'ARRAY'));
6053: my %iphost = &Apache::lonnet::get_iphost();
6054: my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary');
6055: my $primary_ip = &Apache::lonnet::get_host_ip($primary_id);
6056: if (ref($iphost{$primary_ip}) eq 'ARRAY') {
6057: foreach my $id (@{$iphost{$primary_ip}}) {
6058: my $intdom = &Apache::lonnet::internet_dom($id);
6059: unless(grep(/^\Q$intdom\E$/,@{$intdoms})) {
6060: push(@{$intdoms},$intdom);
6061: }
6062: }
6063: }
6064: foreach my $ip (keys(%iphost)) {
6065: if (ref($iphost{$ip}) eq 'ARRAY') {
6066: foreach my $id (@{$iphost{$ip}}) {
6067: my $location = &Apache::lonnet::internet_dom($id);
6068: if ($location) {
6069: if (grep(/^\Q$location\E$/,@{$intdoms})) {
6070: my $dom = &Apache::lonnet::host_domain($id);
6071: unless (grep(/^\Q$dom\E/,@{$instdoms})) {
6072: push(@{$instdoms},$dom);
6073: }
6074: next;
6075: }
6076: if (ref($by_ip->{$ip}) eq 'ARRAY') {
6077: unless(grep(/^\Q$location\E$/,@{$by_ip->{$ip}})) {
6078: push(@{$by_ip->{$ip}},$location);
6079: }
6080: } else {
6081: $by_ip->{$ip} = [$location];
6082: }
6083: }
6084: }
6085: }
6086: }
6087: foreach my $ip (sort(keys(%{$by_ip}))) {
6088: if (ref($by_ip->{$ip}) eq 'ARRAY') {
6089: @{$by_ip->{$ip}} = sort(@{$by_ip->{$ip}});
6090: my $first = $by_ip->{$ip}->[0];
6091: if (ref($by_location->{$first}) eq 'ARRAY') {
6092: unless (grep(/^\Q$ip\E$/,@{$by_location->{$first}})) {
6093: push(@{$by_location->{$first}},$ip);
6094: }
6095: } else {
6096: $by_location->{$first} = [$ip];
6097: }
6098: }
6099: }
6100: return;
6101: }
6102:
6103: sub current_offloads_to {
6104: my ($dom,$settings,$servers) = @_;
6105: my (%spareid,%otherdomconfigs);
6106: if (ref($servers) eq 'HASH') {
6107: foreach my $lonhost (sort(keys(%{$servers}))) {
6108: my $gotspares;
6109: if (ref($settings) eq 'HASH') {
6110: if (ref($settings->{'spares'}) eq 'HASH') {
6111: if (ref($settings->{'spares'}{$lonhost}) eq 'HASH') {
6112: $spareid{$lonhost}{'primary'} = $settings->{'spares'}{$lonhost}{'primary'};
6113: $spareid{$lonhost}{'default'} = $settings->{'spares'}{$lonhost}{'default'};
6114: $gotspares = 1;
6115: }
6116: }
6117: }
6118: unless ($gotspares) {
6119: my $gotspares;
6120: my $serverhomeID =
6121: &Apache::lonnet::get_server_homeID($servers->{$lonhost});
6122: my $serverhomedom =
6123: &Apache::lonnet::host_domain($serverhomeID);
6124: if ($serverhomedom ne $dom) {
6125: if (ref($otherdomconfigs{$serverhomedom} eq 'HASH')) {
6126: if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}) eq 'HASH') {
6127: if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}) eq 'HASH') {
6128: $spareid{$lonhost}{'primary'} = $otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{'primary'};
6129: $spareid{$lonhost}{'default'} = $otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{'default'};
6130: $gotspares = 1;
6131: }
6132: }
6133: } else {
6134: $otherdomconfigs{$serverhomedom} =
6135: &Apache::lonnet::get_dom('configuration',['usersessions'],$serverhomedom);
6136: if (ref($otherdomconfigs{$serverhomedom}) eq 'HASH') {
6137: if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}) eq 'HASH') {
6138: if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}) eq 'HASH') {
6139: if (ref($otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{$lonhost}) eq 'HASH') {
6140: $spareid{$lonhost}{'primary'} = $otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{'primary'};
6141: $spareid{$lonhost}{'default'} = $otherdomconfigs{$serverhomedom}{'usersessions'}{'spares'}{'default'};
6142: $gotspares = 1;
6143: }
6144: }
6145: }
6146: }
6147: }
6148: }
6149: }
6150: unless ($gotspares) {
6151: if ($lonhost eq $Apache::lonnet::perlvar{'lonHostID'}) {
6152: $spareid{$lonhost}{'primary'} = $Apache::lonnet::spareid{'primary'};
6153: $spareid{$lonhost}{'default'} = $Apache::lonnet::spareid{'default'};
6154: } else {
6155: my $server_hostname = &Apache::lonnet::hostname($lonhost);
6156: my $server_homeID = &Apache::lonnet::get_server_homeID($server_hostname);
6157: if ($server_homeID eq $Apache::lonnet::perlvar{'lonHostID'}) {
6158: $spareid{$lonhost}{'primary'} = $Apache::lonnet::spareid{'primary'};
6159: $spareid{$lonhost}{'default'} = $Apache::lonnet::spareid{'default'};
6160: } else {
6161: my %what = (
6162: spareid => 1,
6163: );
6164: my ($result,$returnhash) =
6165: &Apache::lonnet::get_remote_globals($lonhost,\%what);
6166: if ($result eq 'ok') {
6167: if (ref($returnhash) eq 'HASH') {
6168: if (ref($returnhash->{'spareid'}) eq 'HASH') {
6169: $spareid{$lonhost}{'primary'} = $returnhash->{'spareid'}->{'primary'};
6170: $spareid{$lonhost}{'default'} = $returnhash->{'spareid'}->{'default'};
6171: }
6172: }
6173: }
6174: }
6175: }
6176: }
6177: }
6178: }
6179: return %spareid;
6180: }
6181:
6182: sub spares_row {
6183: my ($dom,$servers,$spareid,$serverhomes,$altids,$curroffloadnow,$rowtotal) = @_;
6184: my $css_class;
6185: my $numinrow = 4;
6186: my $itemcount = 1;
6187: my $datatable;
6188: my %typetitles = &sparestype_titles();
6189: if ((ref($servers) eq 'HASH') && (ref($spareid) eq 'HASH') && (ref($altids) eq 'HASH')) {
6190: foreach my $server (sort(keys(%{$servers}))) {
6191: my $serverhome = &Apache::lonnet::get_server_homeID($servers->{$server});
6192: my ($othercontrol,$serverdom);
6193: if ($serverhome ne $server) {
6194: $serverdom = &Apache::lonnet::host_domain($serverhome);
6195: $othercontrol = &mt('Session offloading controlled by domain: [_1]','<b>'.$serverdom.'</b>');
6196: } else {
6197: $serverdom = &Apache::lonnet::host_domain($server);
6198: if ($serverdom ne $dom) {
6199: $othercontrol = &mt('Session offloading controlled by domain: [_1]','<b>'.$serverdom.'</b>');
6200: }
6201: }
6202: next unless (ref($spareid->{$server}) eq 'HASH');
6203: my $checkednow;
6204: if (ref($curroffloadnow) eq 'HASH') {
6205: if ($curroffloadnow->{$server}) {
6206: $checkednow = ' checked="checked"';
6207: }
6208: }
6209: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
6210: $datatable .= '<tr'.$css_class.'>
6211: <td rowspan="2">
6212: <span class="LC_nobreak">'.
6213: &mt('[_1] when busy, offloads to:'
6214: ,'<b>'.$server.'</b>').'</span><br />'.
6215: '<span class="LC_nobreak">'."\n".
6216: '<label><input type="checkbox" name="offloadnow" value="'.$server.'"'.$checkednow.' />'.
6217: ' '.&mt('Switch active users on next access').'</label></span>'.
6218: "\n";
6219: my (%current,%canselect);
6220: my @choices =
6221: &possible_newspares($server,$spareid->{$server},$serverhomes,$altids);
6222: foreach my $type ('primary','default') {
6223: if (ref($spareid->{$server}) eq 'HASH') {
6224: if (ref($spareid->{$server}{$type}) eq 'ARRAY') {
6225: my @spares = @{$spareid->{$server}{$type}};
6226: if (@spares > 0) {
6227: if ($othercontrol) {
6228: $current{$type} = join(', ',@spares);
6229: } else {
6230: $current{$type} .= '<table>';
6231: my $numspares = scalar(@spares);
6232: for (my $i=0; $i<@spares; $i++) {
6233: my $rem = $i%($numinrow);
6234: if ($rem == 0) {
6235: if ($i > 0) {
6236: $current{$type} .= '</tr>';
6237: }
6238: $current{$type} .= '<tr>';
6239: }
6240: $current{$type} .= '<td><label><input type="checkbox" name="spare_'.$type.'_'.$server.'" id="spare_'.$type.'_'.$server.'_'.$i.'" checked="checked" value="'.$spareid->{$server}{$type}[$i].'" onclick="updateNewSpares(this.form,'."'$server'".');" /> '.
6241: $spareid->{$server}{$type}[$i].
6242: '</label></td>'."\n";
6243: }
6244: my $rem = @spares%($numinrow);
6245: my $colsleft = $numinrow - $rem;
6246: if ($colsleft > 1 ) {
6247: $current{$type} .= '<td colspan="'.$colsleft.
6248: '" class="LC_left_item">'.
6249: ' </td>';
6250: } elsif ($colsleft == 1) {
6251: $current{$type} .= '<td class="LC_left_item"> </td>'."\n";
6252: }
6253: $current{$type} .= '</tr></table>';
6254: }
6255: }
6256: }
6257: if ($current{$type} eq '') {
6258: $current{$type} = &mt('None specified');
6259: }
6260: if ($othercontrol) {
6261: if ($type eq 'primary') {
6262: $canselect{$type} = $othercontrol;
6263: }
6264: } else {
6265: $canselect{$type} =
6266: &mt('Add new [_1]'.$type.'[_2]:','<i>','</i>').' '.
6267: '<select name="newspare_'.$type.'_'.$server.'" '.
6268: 'id="newspare_'.$type.'_'.$server.'" onchange="checkNewSpares('."'$server','$type'".');">'."\n".
6269: '<option value="" selected ="selected">'.&mt('Select').'</option>'."\n";
6270: if (@choices > 0) {
6271: foreach my $lonhost (@choices) {
6272: $canselect{$type} .= '<option value="'.$lonhost.'">'.$lonhost.'</option>'."\n";
6273: }
6274: }
6275: $canselect{$type} .= '</select>'."\n";
6276: }
6277: } else {
6278: $current{$type} = &mt('Could not be determined');
6279: if ($type eq 'primary') {
6280: $canselect{$type} = $othercontrol;
6281: }
6282: }
6283: if ($type eq 'default') {
6284: $datatable .= '<tr'.$css_class.'>';
6285: }
6286: $datatable .= '<td><i>'.$typetitles{$type}.'</i></td>'."\n".
6287: '<td>'.$current{$type}.'</td>'."\n".
6288: '<td>'.$canselect{$type}.'</td></tr>'."\n";
6289: }
6290: $itemcount ++;
6291: }
6292: }
6293: $$rowtotal += $itemcount;
6294: return $datatable;
6295: }
6296:
6297: sub possible_newspares {
6298: my ($server,$currspares,$serverhomes,$altids) = @_;
6299: my $serverhostname = &Apache::lonnet::hostname($server);
6300: my %excluded;
6301: if ($serverhostname ne '') {
6302: %excluded = (
6303: $serverhostname => 1,
6304: );
6305: }
6306: if (ref($currspares) eq 'HASH') {
6307: foreach my $type (keys(%{$currspares})) {
6308: if (ref($currspares->{$type}) eq 'ARRAY') {
6309: if (@{$currspares->{$type}} > 0) {
6310: foreach my $curr (@{$currspares->{$type}}) {
6311: my $hostname = &Apache::lonnet::hostname($curr);
6312: $excluded{$hostname} = 1;
6313: }
6314: }
6315: }
6316: }
6317: }
6318: my @choices;
6319: if ((ref($serverhomes) eq 'HASH') && (ref($altids) eq 'HASH')) {
6320: if (keys(%{$serverhomes}) > 1) {
6321: foreach my $name (sort(keys(%{$serverhomes}))) {
6322: unless ($excluded{$name}) {
6323: if (exists($altids->{$serverhomes->{$name}})) {
6324: push(@choices,$altids->{$serverhomes->{$name}});
6325: } else {
6326: push(@choices,$serverhomes->{$name});
6327: }
6328: }
6329: }
6330: }
6331: }
6332: return sort(@choices);
6333: }
6334:
6335: sub print_loadbalancing {
6336: my ($dom,$settings,$rowtotal) = @_;
6337: my $primary_id = &Apache::lonnet::domain($dom,'primary');
6338: my $intdom = &Apache::lonnet::internet_dom($primary_id);
6339: my $numinrow = 1;
6340: my $datatable;
6341: my %servers = &Apache::lonnet::internet_dom_servers($dom);
6342: my (%currbalancer,%currtargets,%currrules,%existing);
6343: if (ref($settings) eq 'HASH') {
6344: %existing = %{$settings};
6345: }
6346: if ((keys(%servers) > 1) || (keys(%existing) > 0)) {
6347: &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,
6348: \%currtargets,\%currrules);
6349: } else {
6350: return;
6351: }
6352: my ($othertitle,$usertypes,$types) =
6353: &Apache::loncommon::sorted_inst_types($dom);
6354: my $rownum = 8;
6355: if (ref($types) eq 'ARRAY') {
6356: $rownum += scalar(@{$types});
6357: }
6358: my @css_class = ('LC_odd_row','LC_even_row');
6359: my $balnum = 0;
6360: my $islast;
6361: my (@toshow,$disabledtext);
6362: if (keys(%currbalancer) > 0) {
6363: @toshow = sort(keys(%currbalancer));
6364: if (scalar(@toshow) < scalar(keys(%servers)) + 1) {
6365: push(@toshow,'');
6366: }
6367: } else {
6368: @toshow = ('');
6369: $disabledtext = &mt('No existing load balancer');
6370: }
6371: foreach my $lonhost (@toshow) {
6372: if ($balnum == scalar(@toshow)-1) {
6373: $islast = 1;
6374: } else {
6375: $islast = 0;
6376: }
6377: my $cssidx = $balnum%2;
6378: my $targets_div_style = 'display: none';
6379: my $disabled_div_style = 'display: block';
6380: my $homedom_div_style = 'display: none';
6381: $datatable .= '<tr class="'.$css_class[$cssidx].'">'.
6382: '<td rowspan="'.$rownum.'" style="vertical-align: top">'.
6383: '<p>';
6384: if ($lonhost eq '') {
6385: $datatable .= '<span class="LC_nobreak">';
6386: if (keys(%currbalancer) > 0) {
6387: $datatable .= &mt('Add balancer:');
6388: } else {
6389: $datatable .= &mt('Enable balancer:');
6390: }
6391: $datatable .= ' '.
6392: '<select name="loadbalancing_lonhost_'.$balnum.'"'.
6393: ' id="loadbalancing_lonhost_'.$balnum.'"'.
6394: ' onchange="toggleTargets('."'$balnum'".');">'."\n".
6395: '<option value="" selected="selected">'.&mt('None').
6396: '</option>'."\n";
6397: foreach my $server (sort(keys(%servers))) {
6398: next if ($currbalancer{$server});
6399: $datatable .= '<option value="'.$server.'">'.$server.'</option>'."\n";
6400: }
6401: $datatable .=
6402: '</select>'."\n".
6403: '<input type="hidden" name="loadbalancing_prevlonhost_'.$balnum.'" id="loadbalancing_prevlonhost_'.$balnum.'" value="" /> </span>'."\n";
6404: } else {
6405: $datatable .= '<i>'.$lonhost.'</i><br /><span class="LC_nobreak">'.
6406: '<label><input type="checkbox" name="loadbalancing_delete" value="'.$balnum.'" id="loadbalancing_delete_'.$balnum.'" onclick="javascript:balancerDeleteChange('."'$balnum'".');" /> '.
6407: &mt('Stop balancing').'</label>'.
6408: '<input type="hidden" name="loadbalancing_lonhost_'.$balnum.'" value="'.$lonhost.'" id="loadbalancing_lonhost_'.$balnum.'" /></span>';
6409: $targets_div_style = 'display: block';
6410: $disabled_div_style = 'display: none';
6411: if ($dom eq &Apache::lonnet::host_domain($lonhost)) {
6412: $homedom_div_style = 'display: block';
6413: }
6414: }
6415: $datatable .= '</p></td><td rowspan="'.$rownum.'" style="vertical-align: top">'.
6416: '<div id="loadbalancing_disabled_'.$balnum.'" style="'.
6417: $disabled_div_style.'">'.$disabledtext.'</div>'."\n".
6418: '<div id="loadbalancing_targets_'.$balnum.'" style="'.$targets_div_style.'">'.&mt('Offloads to:').'<br />';
6419: my ($numspares,@spares) = &count_servers($lonhost,%servers);
6420: my @sparestypes = ('primary','default');
6421: my %typetitles = &sparestype_titles();
6422: my %hostherechecked = (
6423: no => ' checked="checked"',
6424: );
6425: foreach my $sparetype (@sparestypes) {
6426: my $targettable;
6427: for (my $i=0; $i<$numspares; $i++) {
6428: my $checked;
6429: if (ref($currtargets{$lonhost}) eq 'HASH') {
6430: if (ref($currtargets{$lonhost}{$sparetype}) eq 'ARRAY') {
6431: if (grep(/^\Q$spares[$i]\E$/,@{$currtargets{$lonhost}{$sparetype}})) {
6432: $checked = ' checked="checked"';
6433: }
6434: }
6435: }
6436: my ($chkboxval,$disabled);
6437: if (($lonhost ne '') && (exists($servers{$lonhost}))) {
6438: $chkboxval = $spares[$i];
6439: }
6440: if (exists($currbalancer{$spares[$i]})) {
6441: $disabled = ' disabled="disabled"';
6442: }
6443: $targettable .=
6444: '<td><span class="LC_nobreak"><label>'.
6445: '<input type="checkbox" name="loadbalancing_target_'.$balnum.'_'.$sparetype.'"'.
6446: $checked.$disabled.' value="'.$chkboxval.'" id="loadbalancing_target_'.$balnum.'_'.$sparetype.'_'.$i.'" onclick="checkOffloads('."this,'$balnum','$sparetype'".');" /><span id="loadbalancing_targettxt_'.$balnum.'_'.$sparetype.'_'.$i.'"> '.$chkboxval.
6447: '</span></label></span></td>';
6448: my $rem = $i%($numinrow);
6449: if ($rem == 0) {
6450: if (($i > 0) && ($i < $numspares-1)) {
6451: $targettable .= '</tr>';
6452: }
6453: if ($i < $numspares-1) {
6454: $targettable .= '<tr>';
6455: }
6456: }
6457: }
6458: if ($targettable ne '') {
6459: my $rem = $numspares%($numinrow);
6460: my $colsleft = $numinrow - $rem;
6461: if ($colsleft > 1 ) {
6462: $targettable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
6463: ' </td>';
6464: } elsif ($colsleft == 1) {
6465: $targettable .= '<td class="LC_left_item"> </td>';
6466: }
6467: $datatable .= '<i>'.$typetitles{$sparetype}.'</i><br />'.
6468: '<table><tr>'.$targettable.'</tr></table><br />';
6469: }
6470: $hostherechecked{$sparetype} = '';
6471: if (ref($currtargets{$lonhost}) eq 'HASH') {
6472: if (ref($currtargets{$lonhost}{$sparetype}) eq 'ARRAY') {
6473: if (grep(/^\Q$lonhost\E$/,@{$currtargets{$lonhost}{$sparetype}})) {
6474: $hostherechecked{$sparetype} = ' checked="checked"';
6475: $hostherechecked{'no'} = '';
6476: }
6477: }
6478: }
6479: }
6480: $datatable .= &mt('Hosting on balancer itself').'<br />'.
6481: '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" value="no"'.
6482: $hostherechecked{'no'}.' />'.&mt('No').'</label><br />';
6483: foreach my $sparetype (@sparestypes) {
6484: $datatable .= '<label><input type="radio" name="loadbalancing_target_'.$balnum.'_hosthere" '.
6485: 'value="'.$sparetype.'"'.$hostherechecked{$sparetype}.' /><i>'.$typetitles{$sparetype}.
6486: '</i></label><br />';
6487: }
6488: $datatable .= '</div></td></tr>'.
6489: &loadbalancing_rules($dom,$intdom,$currrules{$lonhost},
6490: $othertitle,$usertypes,$types,\%servers,
6491: \%currbalancer,$lonhost,
6492: $targets_div_style,$homedom_div_style,
6493: $css_class[$cssidx],$balnum,$islast);
6494: $$rowtotal += $rownum;
6495: $balnum ++;
6496: }
6497: $datatable .= '<input type="hidden" name="loadbalancing_total" id="loadbalancing_total" value="'.$balnum.'" />';
6498: return $datatable;
6499: }
6500:
6501: sub get_loadbalancers_config {
6502: my ($servers,$existing,$currbalancer,$currtargets,$currrules) = @_;
6503: return unless ((ref($servers) eq 'HASH') &&
6504: (ref($existing) eq 'HASH') && (ref($currbalancer) eq 'HASH') &&
6505: (ref($currtargets) eq 'HASH') && (ref($currrules) eq 'HASH'));
6506: if (keys(%{$existing}) > 0) {
6507: my $oldlonhost;
6508: foreach my $key (sort(keys(%{$existing}))) {
6509: if ($key eq 'lonhost') {
6510: $oldlonhost = $existing->{'lonhost'};
6511: $currbalancer->{$oldlonhost} = 1;
6512: } elsif ($key eq 'targets') {
6513: if ($oldlonhost) {
6514: $currtargets->{$oldlonhost} = $existing->{'targets'};
6515: }
6516: } elsif ($key eq 'rules') {
6517: if ($oldlonhost) {
6518: $currrules->{$oldlonhost} = $existing->{'rules'};
6519: }
6520: } elsif (ref($existing->{$key}) eq 'HASH') {
6521: $currbalancer->{$key} = 1;
6522: $currtargets->{$key} = $existing->{$key}{'targets'};
6523: $currrules->{$key} = $existing->{$key}{'rules'};
6524: }
6525: }
6526: } else {
6527: my ($balancerref,$targetsref) =
6528: &Apache::lonnet::get_lonbalancer_config($servers);
6529: if ((ref($balancerref) eq 'HASH') && (ref($targetsref) eq 'HASH')) {
6530: foreach my $server (sort(keys(%{$balancerref}))) {
6531: $currbalancer->{$server} = 1;
6532: $currtargets->{$server} = $targetsref->{$server};
6533: }
6534: }
6535: }
6536: return;
6537: }
6538:
6539: sub loadbalancing_rules {
6540: my ($dom,$intdom,$currrules,$othertitle,$usertypes,$types,$servers,
6541: $currbalancer,$lonhost,$targets_div_style,$homedom_div_style,
6542: $css_class,$balnum,$islast) = @_;
6543: my $output;
6544: my $num = 0;
6545: my ($alltypes,$othertypes,$titles) =
6546: &loadbalancing_titles($dom,$intdom,$usertypes,$types);
6547: if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH')) {
6548: foreach my $type (@{$alltypes}) {
6549: $num ++;
6550: my $current;
6551: if (ref($currrules) eq 'HASH') {
6552: $current = $currrules->{$type};
6553: }
6554: if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {
6555: if ($dom ne &Apache::lonnet::host_domain($lonhost)) {
6556: $current = '';
6557: }
6558: }
6559: $output .= &loadbalance_rule_row($type,$titles->{$type},$current,
6560: $servers,$currbalancer,$lonhost,$dom,
6561: $targets_div_style,$homedom_div_style,
6562: $css_class,$balnum,$num,$islast);
6563: }
6564: }
6565: return $output;
6566: }
6567:
6568: sub loadbalancing_titles {
6569: my ($dom,$intdom,$usertypes,$types) = @_;
6570: my %othertypes = (
6571: '_LC_adv' => &mt('Advanced users from [_1]',$dom),
6572: '_LC_author' => &mt('Users from [_1] with author role',$dom),
6573: '_LC_internetdom' => &mt('Users not from [_1], but from [_2]',$dom,$intdom),
6574: '_LC_external' => &mt('Users not from [_1]',$intdom),
6575: '_LC_ipchangesso' => &mt('SSO users from [_1], with IP mismatch',$dom),
6576: '_LC_ipchange' => &mt('Non-SSO users with IP mismatch'),
6577: );
6578: my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange');
6579: my @available;
6580: if (ref($types) eq 'ARRAY') {
6581: @available = @{$types};
6582: }
6583: unless (grep(/^default$/,@available)) {
6584: push(@available,'default');
6585: }
6586: unshift(@alltypes,@available);
6587: my %titles;
6588: foreach my $type (@alltypes) {
6589: if ($type =~ /^_LC_/) {
6590: $titles{$type} = $othertypes{$type};
6591: } elsif ($type eq 'default') {
6592: $titles{$type} = &mt('All users from [_1]',$dom);
6593: if (ref($types) eq 'ARRAY') {
6594: if (@{$types} > 0) {
6595: $titles{$type} = &mt('Other users from [_1]',$dom);
6596: }
6597: }
6598: } elsif (ref($usertypes) eq 'HASH') {
6599: $titles{$type} = $usertypes->{$type};
6600: }
6601: }
6602: return (\@alltypes,\%othertypes,\%titles);
6603: }
6604:
6605: sub loadbalance_rule_row {
6606: my ($type,$title,$current,$servers,$currbalancer,$lonhost,$dom,
6607: $targets_div_style,$homedom_div_style,$css_class,$balnum,$num,$islast) = @_;
6608: my @rulenames;
6609: my %ruletitles = &offloadtype_text();
6610: if (($type eq '_LC_ipchangesso') || ($type eq '_LC_ipchange')) {
6611: @rulenames = ('balancer','offloadedto','specific');
6612: } else {
6613: @rulenames = ('default','homeserver');
6614: if ($type eq '_LC_external') {
6615: push(@rulenames,'externalbalancer');
6616: } else {
6617: push(@rulenames,'specific');
6618: }
6619: push(@rulenames,'none');
6620: }
6621: my $style = $targets_div_style;
6622: if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {
6623: $style = $homedom_div_style;
6624: }
6625: my $space;
6626: if ($islast && $num == 1) {
6627: $space = '<div style="display:inline-block;"> </div>';
6628: }
6629: my $output =
6630: '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td style="vertical-align: top">'.$space.
6631: '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".
6632: '<td valaign="top">'.$space.
6633: '<div id="balancerule_'.$balnum.'_'.$type.'" style="'.$style.'">'."\n";
6634: for (my $i=0; $i<@rulenames; $i++) {
6635: my $rule = $rulenames[$i];
6636: my ($checked,$extra);
6637: if ($rulenames[$i] eq 'default') {
6638: $rule = '';
6639: }
6640: if ($rulenames[$i] eq 'specific') {
6641: if (ref($servers) eq 'HASH') {
6642: my $default;
6643: if (($current ne '') && (exists($servers->{$current}))) {
6644: $checked = ' checked="checked"';
6645: }
6646: unless ($checked) {
6647: $default = ' selected="selected"';
6648: }
6649: $extra =
6650: ': <select name="loadbalancing_singleserver_'.$balnum.'_'.$type.
6651: '" id="loadbalancing_singleserver_'.$balnum.'_'.$type.
6652: '" onchange="singleServerToggle('."'$balnum','$type'".')">'."\n".
6653: '<option value=""'.$default.'></option>'."\n";
6654: foreach my $server (sort(keys(%{$servers}))) {
6655: if (ref($currbalancer) eq 'HASH') {
6656: next if (exists($currbalancer->{$server}));
6657: }
6658: my $selected;
6659: if ($server eq $current) {
6660: $selected = ' selected="selected"';
6661: }
6662: $extra .= '<option value="'.$server.'"'.$selected.'>'.$server.'</option>';
6663: }
6664: $extra .= '</select>';
6665: }
6666: } elsif ($rule eq $current) {
6667: $checked = ' checked="checked"';
6668: }
6669: $output .= '<span class="LC_nobreak"><label>'.
6670: '<input type="radio" name="loadbalancing_rules_'.$balnum.'_'.$type.
6671: '" id="loadbalancing_rules_'.$balnum.'_'.$type.'_'.$i.'" value="'.
6672: $rule.'" onclick="balanceruleChange('."this.form,'$balnum','$type'".
6673: ')"'.$checked.' /> ';
6674: if (($rulenames[$i] eq 'specific') && ($type =~ /^_LC_ipchange/)) {
6675: $output .= $ruletitles{'particular'};
6676: } else {
6677: $output .= $ruletitles{$rulenames[$i]};
6678: }
6679: $output .= '</label>'.$extra.'</span><br />'."\n";
6680: }
6681: $output .= '</div></td></tr>'."\n";
6682: return $output;
6683: }
6684:
6685: sub offloadtype_text {
6686: my %ruletitles = &Apache::lonlocal::texthash (
6687: 'default' => 'Offloads to default destinations',
6688: 'homeserver' => "Offloads to user's home server",
6689: 'externalbalancer' => "Offloads to Load Balancer in user's domain",
6690: 'specific' => 'Offloads to specific server',
6691: 'none' => 'No offload',
6692: 'balancer' => 'Session hosted on Load Balancer, after re-authentication',
6693: 'offloadedto' => 'Session hosted on offload server, after re-authentication',
6694: 'particular' => 'Session hosted (after re-auth) on server:',
6695: );
6696: return %ruletitles;
6697: }
6698:
6699: sub sparestype_titles {
6700: my %typestitles = &Apache::lonlocal::texthash (
6701: 'primary' => 'primary',
6702: 'default' => 'default',
6703: );
6704: return %typestitles;
6705: }
6706:
6707: sub contact_titles {
6708: my %titles = &Apache::lonlocal::texthash (
6709: 'supportemail' => 'Support E-mail address',
6710: 'adminemail' => 'Default Server Admin E-mail address',
6711: 'errormail' => 'Error reports to be e-mailed to',
6712: 'packagesmail' => 'Package update alerts to be e-mailed to',
6713: 'helpdeskmail' => "Helpdesk requests from all users in this domain",
6714: 'otherdomsmail' => 'Helpdesk requests from users in other (unconfigured) domains',
6715: 'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)',
6716: 'requestsmail' => 'E-mail from course requests requiring approval',
6717: 'updatesmail' => 'E-mail from nightly check of LON-CAPA module integrity/updates',
6718: 'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID',
6719: 'errorthreshold' => 'Error/warning threshold for status e-mail',
6720: 'errorsysmail' => 'Error threshold for e-mail to core group',
6721: 'errorweights' => 'Weights used to compute error count',
6722: 'errorexcluded' => 'Servers with unsent updates excluded from count',
6723: );
6724: my %short_titles = &Apache::lonlocal::texthash (
6725: adminemail => 'Admin E-mail address',
6726: supportemail => 'Support E-mail',
6727: );
6728: return (\%titles,\%short_titles);
6729: }
6730:
6731: sub helpform_fields {
6732: my %titles = &Apache::lonlocal::texthash (
6733: 'username' => 'Name',
6734: 'user' => 'Username/domain',
6735: 'phone' => 'Phone',
6736: 'cc' => 'Cc e-mail',
6737: 'course' => 'Course Details',
6738: 'section' => 'Sections',
6739: 'screenshot' => 'File upload',
6740: );
6741: my @fields = ('username','phone','user','course','section','cc','screenshot');
6742: my %possoptions = (
6743: username => ['yes','no','req'],
6744: phone => ['yes','no','req'],
6745: user => ['yes','no'],
6746: cc => ['yes','no'],
6747: course => ['yes','no'],
6748: section => ['yes','no'],
6749: screenshot => ['yes','no'],
6750: );
6751: my %fieldoptions = &Apache::lonlocal::texthash (
6752: 'yes' => 'Optional',
6753: 'req' => 'Required',
6754: 'no' => "Not shown",
6755: );
6756: return (\@fields,\%titles,\%fieldoptions,\%possoptions);
6757: }
6758:
6759: sub tool_titles {
6760: my %titles = &Apache::lonlocal::texthash (
6761: aboutme => 'Personal web page',
6762: blog => 'Blog',
6763: webdav => 'WebDAV',
6764: portfolio => 'Portfolio',
6765: official => 'Official courses (with institutional codes)',
6766: unofficial => 'Unofficial courses',
6767: community => 'Communities',
6768: textbook => 'Textbook courses',
6769: placement => 'Placement tests',
6770: );
6771: return %titles;
6772: }
6773:
6774: sub courserequest_titles {
6775: my %titles = &Apache::lonlocal::texthash (
6776: official => 'Official',
6777: unofficial => 'Unofficial',
6778: community => 'Communities',
6779: textbook => 'Textbook',
6780: placement => 'Placement tests',
6781: lti => 'LTI Provider',
6782: norequest => 'Not allowed',
6783: approval => 'Approval by DC',
6784: validate => 'With validation',
6785: autolimit => 'Numerical limit',
6786: unlimited => '(blank for unlimited)',
6787: );
6788: return %titles;
6789: }
6790:
6791: sub authorrequest_titles {
6792: my %titles = &Apache::lonlocal::texthash (
6793: norequest => 'Not allowed',
6794: approval => 'Approval by Dom. Coord.',
6795: automatic => 'Automatic approval',
6796: );
6797: return %titles;
6798: }
6799:
6800: sub courserequest_conditions {
6801: my %conditions = &Apache::lonlocal::texthash (
6802: approval => '(Processing of request subject to approval by Domain Coordinator).',
6803: validate => '(Processing of request subject to institutional validation).',
6804: );
6805: return %conditions;
6806: }
6807:
6808:
6809: sub print_usercreation {
6810: my ($position,$dom,$settings,$rowtotal) = @_;
6811: my $numinrow = 4;
6812: my $datatable;
6813: if ($position eq 'top') {
6814: $$rowtotal ++;
6815: my $rowcount = 0;
6816: my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($dom,'username');
6817: if (ref($rules) eq 'HASH') {
6818: if (keys(%{$rules}) > 0) {
6819: $datatable .= &user_formats_row('username',$settings,$rules,
6820: $ruleorder,$numinrow,$rowcount);
6821: $$rowtotal ++;
6822: $rowcount ++;
6823: }
6824: }
6825: my ($idrules,$idruleorder) = &Apache::lonnet::inst_userrules($dom,'id');
6826: if (ref($idrules) eq 'HASH') {
6827: if (keys(%{$idrules}) > 0) {
6828: $datatable .= &user_formats_row('id',$settings,$idrules,
6829: $idruleorder,$numinrow,$rowcount);
6830: $$rowtotal ++;
6831: $rowcount ++;
6832: }
6833: }
6834: if ($rowcount == 0) {
6835: $datatable .= '<tr><td colspan="2">'.&mt('No format rules have been defined for usernames or IDs in this domain.').'</td></tr>';
6836: $$rowtotal ++;
6837: $rowcount ++;
6838: }
6839: } elsif ($position eq 'middle') {
6840: my @creators = ('author','course','requestcrs');
6841: my ($rules,$ruleorder) =
6842: &Apache::lonnet::inst_userrules($dom,'username');
6843: my %lt = &usercreation_types();
6844: my %checked;
6845: if (ref($settings) eq 'HASH') {
6846: if (ref($settings->{'cancreate'}) eq 'HASH') {
6847: foreach my $item (@creators) {
6848: $checked{$item} = $settings->{'cancreate'}{$item};
6849: }
6850: } elsif (ref($settings->{'cancreate'}) eq 'ARRAY') {
6851: foreach my $item (@creators) {
6852: if (grep(/^\Q$item\E$/,@{$settings->{'cancreate'}})) {
6853: $checked{$item} = 'none';
6854: }
6855: }
6856: }
6857: }
6858: my $rownum = 0;
6859: foreach my $item (@creators) {
6860: $rownum ++;
6861: if ($checked{$item} eq '') {
6862: $checked{$item} = 'any';
6863: }
6864: my $css_class;
6865: if ($rownum%2) {
6866: $css_class = '';
6867: } else {
6868: $css_class = ' class="LC_odd_row" ';
6869: }
6870: $datatable .= '<tr'.$css_class.'>'.
6871: '<td><span class="LC_nobreak">'.$lt{$item}.
6872: '</span></td><td style="text-align: right">';
6873: my @options = ('any');
6874: if (ref($rules) eq 'HASH') {
6875: if (keys(%{$rules}) > 0) {
6876: push(@options,('official','unofficial'));
6877: }
6878: }
6879: push(@options,'none');
6880: foreach my $option (@options) {
6881: my $type = 'radio';
6882: my $check = ' ';
6883: if ($checked{$item} eq $option) {
6884: $check = ' checked="checked" ';
6885: }
6886: $datatable .= '<span class="LC_nobreak"><label>'.
6887: '<input type="'.$type.'" name="can_createuser_'.
6888: $item.'" value="'.$option.'"'.$check.'/> '.
6889: $lt{$option}.'</label> </span>';
6890: }
6891: $datatable .= '</td></tr>';
6892: }
6893: } else {
6894: my @contexts = ('author','course','domain');
6895: my @authtypes = ('int','krb4','krb5','loc','lti');
6896: my %checked;
6897: if (ref($settings) eq 'HASH') {
6898: if (ref($settings->{'authtypes'}) eq 'HASH') {
6899: foreach my $item (@contexts) {
6900: if (ref($settings->{'authtypes'}{$item}) eq 'HASH') {
6901: foreach my $auth (@authtypes) {
6902: if ($settings->{'authtypes'}{$item}{$auth}) {
6903: $checked{$item}{$auth} = ' checked="checked" ';
6904: }
6905: }
6906: }
6907: }
6908: }
6909: } else {
6910: foreach my $item (@contexts) {
6911: foreach my $auth (@authtypes) {
6912: $checked{$item}{$auth} = ' checked="checked" ';
6913: }
6914: }
6915: }
6916: my %title = &context_names();
6917: my %authname = &authtype_names();
6918: my $rownum = 0;
6919: my $css_class;
6920: foreach my $item (@contexts) {
6921: if ($rownum%2) {
6922: $css_class = '';
6923: } else {
6924: $css_class = ' class="LC_odd_row" ';
6925: }
6926: $datatable .= '<tr'.$css_class.'>'.
6927: '<td>'.$title{$item}.
6928: '</td><td class="LC_left_item">'.
6929: '<span class="LC_nobreak">';
6930: foreach my $auth (@authtypes) {
6931: $datatable .= '<label>'.
6932: '<input type="checkbox" name="'.$item.'_auth" '.
6933: $checked{$item}{$auth}.' value="'.$auth.'" />'.
6934: $authname{$auth}.'</label> ';
6935: }
6936: $datatable .= '</span></td></tr>';
6937: $rownum ++;
6938: }
6939: $$rowtotal += $rownum;
6940: }
6941: return $datatable;
6942: }
6943:
6944: sub print_selfcreation {
6945: my ($position,$dom,$settings,$rowtotal) = @_;
6946: my (@selfcreate,$createsettings,$processing,$emailoptions,$emailverified,
6947: $emaildomain,$datatable);
6948: if (ref($settings) eq 'HASH') {
6949: if (ref($settings->{'cancreate'}) eq 'HASH') {
6950: $createsettings = $settings->{'cancreate'};
6951: if (ref($createsettings) eq 'HASH') {
6952: if (ref($createsettings->{'selfcreate'}) eq 'ARRAY') {
6953: @selfcreate = @{$createsettings->{'selfcreate'}};
6954: } elsif ($createsettings->{'selfcreate'} ne '') {
6955: if ($settings->{'cancreate'}{'selfcreate'} eq 'any') {
6956: @selfcreate = ('email','login','sso');
6957: } elsif ($createsettings->{'selfcreate'} ne 'none') {
6958: @selfcreate = ($createsettings->{'selfcreate'});
6959: }
6960: }
6961: if (ref($createsettings->{'selfcreateprocessing'}) eq 'HASH') {
6962: $processing = $createsettings->{'selfcreateprocessing'};
6963: }
6964: if (ref($createsettings->{'emailoptions'}) eq 'HASH') {
6965: $emailoptions = $createsettings->{'emailoptions'};
6966: }
6967: if (ref($createsettings->{'emailverified'}) eq 'HASH') {
6968: $emailverified = $createsettings->{'emailverified'};
6969: }
6970: if (ref($createsettings->{'emaildomain'}) eq 'HASH') {
6971: $emaildomain = $createsettings->{'emaildomain'};
6972: }
6973: }
6974: }
6975: }
6976: my %radiohash;
6977: my $numinrow = 4;
6978: map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate;
6979: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
6980: if ($position eq 'top') {
6981: my %choices = &Apache::lonlocal::texthash (
6982: cancreate_login => 'Institutional Login',
6983: cancreate_sso => 'Institutional Single Sign On',
6984: );
6985: my @toggles = sort(keys(%choices));
6986: my %defaultchecked = (
6987: 'cancreate_login' => 'off',
6988: 'cancreate_sso' => 'off',
6989: );
6990: my ($onclick,$itemcount);
6991: ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,
6992: \%choices,$itemcount,$onclick);
6993: $$rowtotal += $itemcount;
6994:
6995: if (ref($usertypes) eq 'HASH') {
6996: if (keys(%{$usertypes}) > 0) {
6997: $datatable .= &insttypes_row($createsettings,$types,$usertypes,
6998: $dom,$numinrow,$othertitle,
6999: 'statustocreate',$rowtotal);
7000: $$rowtotal ++;
7001: }
7002: }
7003: my @fields = ('lastname','firstname','middlename','permanentemail','id','inststatus');
7004: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
7005: $fieldtitles{'inststatus'} = &mt('Institutional status');
7006: my $rem;
7007: my $numperrow = 2;
7008: my $css_class = $$rowtotal%2?' class="LC_odd_row"':'';
7009: $datatable .= '<tr'.$css_class.'>'.
7010: '<td class="LC_left_item">'.&mt('Mapping of Shibboleth environment variable names to user data fields (SSO auth)').'</td>'.
7011: '<td class="LC_left_item">'."\n".
7012: '<table>'."\n";
7013: for (my $i=0; $i<@fields; $i++) {
7014: $rem = $i%($numperrow);
7015: if ($rem == 0) {
7016: if ($i > 0) {
7017: $datatable .= '</tr>';
7018: }
7019: $datatable .= '<tr>';
7020: }
7021: my $currval;
7022: if (ref($createsettings) eq 'HASH') {
7023: if (ref($createsettings->{'shibenv'}) eq 'HASH') {
7024: $currval = $createsettings->{'shibenv'}{$fields[$i]};
7025: }
7026: }
7027: $datatable .= '<td class="LC_left_item">'.
7028: '<span class="LC_nobreak">'.
7029: '<input type="text" name="shibenv_'.$fields[$i].'" '.
7030: 'value="'.$currval.'" size="10" /> '.
7031: $fieldtitles{$fields[$i]}.'</span></td>';
7032: }
7033: my $colsleft = $numperrow - $rem;
7034: if ($colsleft > 1 ) {
7035: $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
7036: ' </td>';
7037: } elsif ($colsleft == 1) {
7038: $datatable .= '<td class="LC_left_item"> </td>';
7039: }
7040: $datatable .= '</tr></table></td></tr>';
7041: $$rowtotal ++;
7042: } elsif ($position eq 'middle') {
7043: my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom);
7044: my @posstypes;
7045: if (ref($types) eq 'ARRAY') {
7046: @posstypes = @{$types};
7047: }
7048: unless (grep(/^default$/,@posstypes)) {
7049: push(@posstypes,'default');
7050: }
7051: my %usertypeshash;
7052: if (ref($usertypes) eq 'HASH') {
7053: %usertypeshash = %{$usertypes};
7054: }
7055: $usertypeshash{'default'} = $othertitle;
7056: foreach my $status (@posstypes) {
7057: $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'},
7058: $numinrow,$$rowtotal,\%usertypeshash);
7059: $$rowtotal ++;
7060: }
7061: } else {
7062: my %choices = &Apache::lonlocal::texthash (
7063: 'cancreate_email' => 'Non-institutional username (via e-mail verification)',
7064: );
7065: my @toggles = sort(keys(%choices));
7066: my %defaultchecked = (
7067: 'cancreate_email' => 'off',
7068: );
7069: my $customclass = 'LC_selfcreate_email';
7070: my $classprefix = 'LC_canmodify_emailusername_';
7071: my $optionsprefix = 'LC_options_emailusername_';
7072: my $display = 'none';
7073: my $rowstyle = 'display:none';
7074: if (grep(/^\Qemail\E$/,@selfcreate)) {
7075: $display = 'block';
7076: $rowstyle = 'display:table-row';
7077: }
7078: my $onclick = "toggleRows(this.form,'cancreate_email','selfassign','$customclass','$classprefix','$optionsprefix');";
7079: ($datatable,$$rowtotal) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked,
7080: \%choices,$$rowtotal,$onclick);
7081: $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal,$customclass,
7082: $rowstyle);
7083: $$rowtotal ++;
7084: $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal,$customclass,
7085: $rowstyle);
7086: $$rowtotal ++;
7087: my (@ordered,@posstypes,%usertypeshash);
7088: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
7089: my ($emailrules,$emailruleorder) =
7090: &Apache::lonnet::inst_userrules($dom,'email');
7091: my $primary_id = &Apache::lonnet::domain($dom,'primary');
7092: my $intdom = &Apache::lonnet::internet_dom($primary_id);
7093: if (ref($types) eq 'ARRAY') {
7094: @posstypes = @{$types};
7095: }
7096: if (@posstypes) {
7097: unless (grep(/^default$/,@posstypes)) {
7098: push(@posstypes,'default');
7099: }
7100: if (ref($usertypes) eq 'HASH') {
7101: %usertypeshash = %{$usertypes};
7102: }
7103: my $currassign;
7104: if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') {
7105: $currassign = {
7106: selfassign => $domdefaults{'inststatusguest'},
7107: };
7108: @ordered = @{$domdefaults{'inststatusguest'}};
7109: } else {
7110: $currassign = { selfassign => [] };
7111: }
7112: my $onclicktypes = "toggleDataRow(this.form,'selfassign','$customclass','$optionsprefix',);".
7113: "toggleDataRow(this.form,'selfassign','$customclass','$classprefix',1);";
7114: $datatable .= &insttypes_row($currassign,$types,$usertypes,$dom,
7115: $numinrow,$othertitle,'selfassign',
7116: $rowtotal,$onclicktypes,$customclass,
7117: $rowstyle);
7118: $$rowtotal ++;
7119: $usertypeshash{'default'} = $othertitle;
7120: foreach my $status (@posstypes) {
7121: my $css_class;
7122: if ($$rowtotal%2) {
7123: $css_class = 'LC_odd_row ';
7124: }
7125: $css_class .= $customclass;
7126: my $rowid = $optionsprefix.$status;
7127: my $hidden = 1;
7128: my $currstyle = 'display:none';
7129: if (grep(/^\Q$status\E$/,@ordered)) {
7130: $currstyle = $rowstyle;
7131: $hidden = 0;
7132: }
7133: $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,
7134: $emailrules,$emailruleorder,$settings,$status,$rowid,
7135: $usertypeshash{$status},$css_class,$currstyle,$intdom);
7136: unless ($hidden) {
7137: $$rowtotal ++;
7138: }
7139: }
7140: } else {
7141: my $css_class;
7142: if ($$rowtotal%2) {
7143: $css_class = 'LC_odd_row ';
7144: }
7145: $css_class .= $customclass;
7146: $usertypeshash{'default'} = $othertitle;
7147: $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain,
7148: $emailrules,$emailruleorder,$settings,'default','',
7149: $othertitle,$css_class,$rowstyle,$intdom);
7150: $$rowtotal ++;
7151: }
7152: my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
7153: $numinrow = 1;
7154: if (@posstypes) {
7155: foreach my $status (@posstypes) {
7156: my $rowid = $classprefix.$status;
7157: my $datarowstyle = 'display:none';
7158: if (grep(/^\Q$status\E$/,@ordered)) {
7159: $datarowstyle = $rowstyle;
7160: }
7161: $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings,
7162: $numinrow,$$rowtotal,\%usertypeshash,$infofields,
7163: $infotitles,$rowid,$customclass,$datarowstyle);
7164: unless ($datarowstyle eq 'display:none') {
7165: $$rowtotal ++;
7166: }
7167: }
7168: } else {
7169: $datatable .= &modifiable_userdata_row('cancreate','emailusername_default',$settings,
7170: $numinrow,$$rowtotal,\%usertypeshash,$infofields,
7171: $infotitles,'',$customclass,$rowstyle);
7172: }
7173: }
7174: return $datatable;
7175: }
7176:
7177: sub selfcreate_javascript {
7178: return <<"ENDSCRIPT";
7179:
7180: <script type="text/javascript">
7181: // <![CDATA[
7182:
7183: function toggleRows(form,radio,checkbox,target,prefix,altprefix) {
7184: var x = document.getElementsByClassName(target);
7185: var insttypes = 0;
7186: var insttypeRegExp = new RegExp(prefix);
7187: if ((x.length != undefined) && (x.length > 0)) {
7188: if (form.elements[radio].length != undefined) {
7189: for (var i=0; i<form.elements[radio].length; i++) {
7190: if (form.elements[radio][i].checked) {
7191: if (form.elements[radio][i].value == 1) {
7192: for (var j=0; j<x.length; j++) {
7193: if (x[j].id == 'undefined') {
7194: x[j].style.display = 'table-row';
7195: } else if (insttypeRegExp.test(x[j].id)) {
7196: insttypes ++;
7197: } else {
7198: x[j].style.display = 'table-row';
7199: }
7200: }
7201: } else {
7202: for (var j=0; j<x.length; j++) {
7203: x[j].style.display = 'none';
7204: }
7205: }
7206: break;
7207: }
7208: }
7209: if (insttypes > 0) {
7210: toggleDataRow(form,checkbox,target,altprefix);
7211: toggleDataRow(form,checkbox,target,prefix,1);
7212: }
7213: }
7214: }
7215: return;
7216: }
7217:
7218: function toggleDataRow(form,checkbox,target,prefix,docount) {
7219: if (form.elements[checkbox].length != undefined) {
7220: var count = 0;
7221: if (docount) {
7222: for (var i=0; i<form.elements[checkbox].length; i++) {
7223: if (form.elements[checkbox][i].checked) {
7224: count ++;
7225: }
7226: }
7227: }
7228: for (var i=0; i<form.elements[checkbox].length; i++) {
7229: var type = form.elements[checkbox][i].value;
7230: if (document.getElementById(prefix+type)) {
7231: if (form.elements[checkbox][i].checked) {
7232: document.getElementById(prefix+type).style.display = 'table-row';
7233: if (count % 2 == 1) {
7234: document.getElementById(prefix+type).className = target+' LC_odd_row';
7235: } else {
7236: document.getElementById(prefix+type).className = target;
7237: }
7238: count ++;
7239: } else {
7240: document.getElementById(prefix+type).style.display = 'none';
7241: }
7242: }
7243: }
7244: }
7245: return;
7246: }
7247:
7248: function toggleEmailOptions(form,radio,prefix,altprefix,status) {
7249: var caller = radio+'_'+status;
7250: if (form.elements[caller].length != undefined) {
7251: for (var i=0; i<form.elements[caller].length; i++) {
7252: if (form.elements[caller][i].checked) {
7253: if (document.getElementById(altprefix+'_inst_'+status)) {
7254: var curr = form.elements[caller][i].value;
7255: if (prefix) {
7256: document.getElementById(prefix+'_'+status).style.display = 'none';
7257: }
7258: document.getElementById(altprefix+'_inst_'+status).style.display = 'none';
7259: document.getElementById(altprefix+'_noninst_'+status).style.display = 'none';
7260: if (curr == 'custom') {
7261: if (prefix) {
7262: document.getElementById(prefix+'_'+status).style.display = 'inline';
7263: }
7264: } else if (curr == 'inst') {
7265: document.getElementById(altprefix+'_inst_'+status).style.display = 'inline';
7266: } else if (curr == 'noninst') {
7267: document.getElementById(altprefix+'_noninst_'+status).style.display = 'inline';
7268: }
7269: break;
7270: }
7271: }
7272: }
7273: }
7274: }
7275:
7276: // ]]>
7277: </script>
7278:
7279: ENDSCRIPT
7280: }
7281:
7282: sub noninst_users {
7283: my ($processing,$emailverified,$emailoptions,$emaildomain,$emailrules,
7284: $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_;
7285: my $class = 'LC_left_item';
7286: if ($css_class) {
7287: $css_class = ' class="'.$css_class.'"';
7288: }
7289: if ($rowid) {
7290: $rowid = ' id="'.$rowid.'"';
7291: }
7292: if ($rowstyle) {
7293: $rowstyle = ' style="'.$rowstyle.'"';
7294: }
7295: my ($output,$description);
7296: if ($type eq 'default') {
7297: $description = &mt('Requests for: [_1]',$typetitle);
7298: } else {
7299: $description = &mt('Requests for: [_1] (status self-reported)',$typetitle);
7300: }
7301: $output = '<tr'.$css_class.$rowid.$rowstyle.'>'.
7302: "<td>$description</td>\n".
7303: '<td class="'.$class.'" colspan="2">'.
7304: '<table><tr>';
7305: my %headers = &Apache::lonlocal::texthash(
7306: approve => 'Processing',
7307: email => 'E-mail',
7308: username => 'Username',
7309: );
7310: foreach my $item ('approve','email','username') {
7311: $output .= '<th>'.$headers{$item}.'</th>';
7312: }
7313: $output .= '</tr><tr>';
7314: foreach my $item ('approve','email','username') {
7315: $output .= '<td style="vertical-align: top">';
7316: my (%choices,@options,$hashref,$defoption,$name,$onclick,$hascustom);
7317: if ($item eq 'approve') {
7318: %choices = &Apache::lonlocal::texthash (
7319: automatic => 'Automatically approved',
7320: approval => 'Queued for approval',
7321: );
7322: @options = ('automatic','approval');
7323: $hashref = $processing;
7324: $defoption = 'automatic';
7325: $name = 'cancreate_emailprocess_'.$type;
7326: } elsif ($item eq 'email') {
7327: %choices = &Apache::lonlocal::texthash (
7328: any => 'Any e-mail',
7329: inst => 'Institutional only',
7330: noninst => 'Non-institutional only',
7331: custom => 'Custom restrictions',
7332: );
7333: @options = ('any','inst','noninst');
7334: my $showcustom;
7335: if (ref($emailrules) eq 'HASH') {
7336: if (keys(%{$emailrules}) > 0) {
7337: push(@options,'custom');
7338: $showcustom = 'cancreate_emailrule';
7339: if (ref($settings) eq 'HASH') {
7340: if (ref($settings->{'email_rule'}) eq 'ARRAY') {
7341: foreach my $rule (@{$settings->{'email_rule'}}) {
7342: if (exists($emailrules->{$rule})) {
7343: $hascustom ++;
7344: }
7345: }
7346: } elsif (ref($settings->{'email_rule'}) eq 'HASH') {
7347: if (ref($settings->{'email_rule'}{$type}) eq 'ARRAY') {
7348: foreach my $rule (@{$settings->{'email_rule'}{$type}}) {
7349: if (exists($emailrules->{$rule})) {
7350: $hascustom ++;
7351: }
7352: }
7353: }
7354: }
7355: }
7356: }
7357: }
7358: $onclick = ' onclick="toggleEmailOptions(this.form,'."'cancreate_emailoptions','$showcustom',".
7359: "'cancreate_emaildomain','$type'".');"';
7360: $hashref = $emailoptions;
7361: $defoption = 'any';
7362: $name = 'cancreate_emailoptions_'.$type;
7363: } elsif ($item eq 'username') {
7364: %choices = &Apache::lonlocal::texthash (
7365: all => 'Same as e-mail',
7366: first => 'Omit @domain',
7367: free => 'Free to choose',
7368: );
7369: @options = ('all','first','free');
7370: $hashref = $emailverified;
7371: $defoption = 'all';
7372: $name = 'cancreate_usernameoptions_'.$type;
7373: }
7374: foreach my $option (@options) {
7375: my $checked;
7376: if (ref($hashref) eq 'HASH') {
7377: if ($type eq '') {
7378: if (!exists($hashref->{'default'})) {
7379: if ($option eq $defoption) {
7380: $checked = ' checked="checked"';
7381: }
7382: } else {
7383: if ($hashref->{'default'} eq $option) {
7384: $checked = ' checked="checked"';
7385: }
7386: }
7387: } else {
7388: if (!exists($hashref->{$type})) {
7389: if ($option eq $defoption) {
7390: $checked = ' checked="checked"';
7391: }
7392: } else {
7393: if ($hashref->{$type} eq $option) {
7394: $checked = ' checked="checked"';
7395: }
7396: }
7397: }
7398: } elsif (($item eq 'email') && ($hascustom)) {
7399: if ($option eq 'custom') {
7400: $checked = ' checked="checked"';
7401: }
7402: } elsif ($option eq $defoption) {
7403: $checked = ' checked="checked"';
7404: }
7405: $output .= '<span class="LC_nobreak"><label>'.
7406: '<input type="radio" name="'.$name.'"'.
7407: $checked.' value="'.$option.'"'.$onclick.' />'.
7408: $choices{$option}.'</label></span><br />';
7409: if ($item eq 'email') {
7410: if ($option eq 'custom') {
7411: my $id = 'cancreate_emailrule_'.$type;
7412: my $display = 'none';
7413: if ($checked) {
7414: $display = 'inline';
7415: }
7416: my $numinrow = 2;
7417: $output .= '<fieldset id="'.$id.'" style="display:'.$display.';">'.
7418: '<legend>'.&mt('Disallow').'</legend><table>'.
7419: &user_formats_row('email',$settings,$emailrules,
7420: $emailruleorder,$numinrow,'',$type);
7421: '</table></fieldset>';
7422: } elsif (($option eq 'inst') || ($option eq 'noninst')) {
7423: my %text = &Apache::lonlocal::texthash (
7424: inst => 'must end:',
7425: noninst => 'cannot end:',
7426: );
7427: my $value;
7428: if (ref($emaildomain) eq 'HASH') {
7429: if (ref($emaildomain->{$type}) eq 'HASH') {
7430: $value = $emaildomain->{$type}->{$option};
7431: }
7432: }
7433: if ($value eq '') {
7434: $value = '@'.$intdom;
7435: }
7436: my $condition = 'cancreate_emaildomain_'.$option.'_'.$type;
7437: my $display = 'none';
7438: if ($checked) {
7439: $display = 'inline';
7440: }
7441: $output .= '<div id="'.$condition.'" style="display:'.$display.';">'.
7442: '<span class="LC_domprefs_email">'.$text{$option}.'</span> '.
7443: '<input type="text" name="'.$condition.'" value="'.$value.'" size="10" />'.
7444: '</div>';
7445: }
7446: }
7447: }
7448: $output .= '</td>'."\n";
7449: }
7450: $output .= "</tr></table></td></tr>\n";
7451: return $output;
7452: }
7453:
7454: sub captcha_choice {
7455: my ($context,$settings,$itemcount,$customcss,$rowstyle) = @_;
7456: my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext,
7457: $vertext,$currver);
7458: my %lt = &captcha_phrases();
7459: $keyentry = 'hidden';
7460: if ($context eq 'cancreate') {
7461: $rowname = &mt('CAPTCHA validation');
7462: } elsif ($context eq 'login') {
7463: $rowname = &mt('"Contact helpdesk" CAPTCHA validation');
7464: }
7465: if (ref($settings) eq 'HASH') {
7466: if ($settings->{'captcha'}) {
7467: $checked{$settings->{'captcha'}} = ' checked="checked"';
7468: } else {
7469: $checked{'original'} = ' checked="checked"';
7470: }
7471: if ($settings->{'captcha'} eq 'recaptcha') {
7472: $pubtext = $lt{'pub'};
7473: $privtext = $lt{'priv'};
7474: $keyentry = 'text';
7475: $vertext = $lt{'ver'};
7476: $currver = $settings->{'recaptchaversion'};
7477: if ($currver ne '2') {
7478: $currver = 1;
7479: }
7480: }
7481: if (ref($settings->{'recaptchakeys'}) eq 'HASH') {
7482: $currpub = $settings->{'recaptchakeys'}{'public'};
7483: $currpriv = $settings->{'recaptchakeys'}{'private'};
7484: }
7485: } else {
7486: $checked{'original'} = ' checked="checked"';
7487: }
7488: my $css_class;
7489: if ($itemcount%2) {
7490: $css_class = 'LC_odd_row';
7491: }
7492: if ($customcss) {
7493: $css_class .= " $customcss";
7494: }
7495: $css_class =~ s/^\s+//;
7496: if ($css_class) {
7497: $css_class = ' class="'.$css_class.'"';
7498: }
7499: if ($rowstyle) {
7500: $css_class .= ' style="'.$rowstyle.'"';
7501: }
7502: my $output = '<tr'.$css_class.'>'.
7503: '<td class="LC_left_item">'.$rowname.'</td><td class="LC_left_item" colspan="2">'."\n".
7504: '<table><tr><td>'."\n";
7505: foreach my $option ('original','recaptcha','notused') {
7506: $output .= '<span class="LC_nobreak"><label><input type="radio" name="'.$context.'_captcha" value="'.
7507: $option.'" '.$checked{$option}.' onchange="javascript:updateCaptcha('."this,'$context'".');" />'.
7508: $lt{$option}.'</label></span>';
7509: unless ($option eq 'notused') {
7510: $output .= (' 'x2)."\n";
7511: }
7512: }
7513: #
7514: # Note: If reCAPTCHA is to be used for LON-CAPA servers in a domain, a domain coordinator should visit:
7515: # https://www.google.com/recaptcha and generate a Public and Private key. For domains with multiple
7516: # servers a single key pair will be used for all servers, so the internet domain (e.g., yourcollege.edu)
7517: # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain.
7518: #
7519: $output .= '</td></tr>'."\n".
7520: '<tr><td class="LC_zero_height">'."\n".
7521: '<span class="LC_nobreak"><span id="'.$context.'_recaptchapubtxt">'.$pubtext.'</span> '."\n".
7522: '<input type="'.$keyentry.'" id="'.$context.'_recaptchapub" name="'.$context.'_recaptchapub" value="'.
7523: $currpub.'" size="40" /></span><br />'."\n".
7524: '<span class="LC_nobreak"><span id="'.$context.'_recaptchaprivtxt">'.$privtext.'</span> '."\n".
7525: '<input type="'.$keyentry.'" id="'.$context.'_recaptchapriv" name="'.$context.'_recaptchapriv" value="'.
7526: $currpriv.'" size="40" /></span><br />'.
7527: '<span class="LC_nobreak"><span id="'.$context.'_recaptchavertxt">'.$vertext.'</span> '."\n".
7528: '<input type="'.$keyentry.'" id="'.$context.'_recaptchaversion" name="'.$context.'_recaptchaversion" value="'.
7529: $currver.'" size="3" /></span><br />'.
7530: '</td></tr></table>'."\n".
7531: '</td></tr>';
7532: return $output;
7533: }
7534:
7535: sub user_formats_row {
7536: my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount,$status) = @_;
7537: my $output;
7538: my %text = (
7539: 'username' => 'new usernames',
7540: 'id' => 'IDs',
7541: );
7542: unless ($type eq 'email') {
7543: my $css_class = $rowcount%2?' class="LC_odd_row"':'';
7544: $output = '<tr '.$css_class.'>'.
7545: '<td><span class="LC_nobreak">'.
7546: &mt("Format rules to check for $text{$type}: ").
7547: '</td><td class="LC_left_item" colspan="2"><table>';
7548: }
7549: my $rem;
7550: if (ref($ruleorder) eq 'ARRAY') {
7551: for (my $i=0; $i<@{$ruleorder}; $i++) {
7552: if (ref($rules->{$ruleorder->[$i]}) eq 'HASH') {
7553: my $rem = $i%($numinrow);
7554: if ($rem == 0) {
7555: if ($i > 0) {
7556: $output .= '</tr>';
7557: }
7558: $output .= '<tr>';
7559: }
7560: my $check = ' ';
7561: if (ref($settings) eq 'HASH') {
7562: if (ref($settings->{$type.'_rule'}) eq 'ARRAY') {
7563: if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) {
7564: $check = ' checked="checked" ';
7565: }
7566: } elsif ((ref($settings->{$type.'_rule'}) eq 'HASH') && ($status ne '')) {
7567: if (ref($settings->{$type.'_rule'}->{$status}) eq 'ARRAY') {
7568: if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}->{$status}})) {
7569: $check = ' checked="checked" ';
7570: }
7571: }
7572: }
7573: }
7574: my $name = $type.'_rule';
7575: if ($type eq 'email') {
7576: $name .= '_'.$status;
7577: }
7578: $output .= '<td class="LC_left_item">'.
7579: '<span class="LC_nobreak"><label>'.
7580: '<input type="checkbox" name="'.$name.'" '.
7581: 'value="'.$ruleorder->[$i].'"'.$check.'/>'.
7582: $rules->{$ruleorder->[$i]}{'name'}.'</label></span></td>';
7583: }
7584: }
7585: $rem = @{$ruleorder}%($numinrow);
7586: }
7587: my $colsleft;
7588: if ($rem) {
7589: $colsleft = $numinrow - $rem;
7590: }
7591: if ($colsleft > 1 ) {
7592: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
7593: ' </td>';
7594: } elsif ($colsleft == 1) {
7595: $output .= '<td class="LC_left_item"> </td>';
7596: }
7597: $output .= '</tr></table>';
7598: unless ($type eq 'email') {
7599: $output .= '</td></tr>';
7600: }
7601: return $output;
7602: }
7603:
7604: sub usercreation_types {
7605: my %lt = &Apache::lonlocal::texthash (
7606: author => 'When adding a co-author',
7607: course => 'When adding a user to a course',
7608: requestcrs => 'When requesting a course',
7609: any => 'Any',
7610: official => 'Institutional only ',
7611: unofficial => 'Non-institutional only',
7612: none => 'None',
7613: );
7614: return %lt;
7615: }
7616:
7617: sub selfcreation_types {
7618: my %lt = &Apache::lonlocal::texthash (
7619: selfcreate => 'User creates own account',
7620: any => 'Any',
7621: official => 'Institutional only ',
7622: unofficial => 'Non-institutional only',
7623: email => 'E-mail address',
7624: login => 'Institutional Login',
7625: sso => 'SSO',
7626: );
7627: }
7628:
7629: sub authtype_names {
7630: my %lt = &Apache::lonlocal::texthash(
7631: int => 'Internal',
7632: krb4 => 'Kerberos 4',
7633: krb5 => 'Kerberos 5',
7634: loc => 'Local',
7635: lti => 'LTI',
7636: );
7637: return %lt;
7638: }
7639:
7640: sub context_names {
7641: my %context_title = &Apache::lonlocal::texthash(
7642: author => 'Creating users when an Author',
7643: course => 'Creating users when in a course',
7644: domain => 'Creating users when a Domain Coordinator',
7645: );
7646: return %context_title;
7647: }
7648:
7649: sub print_usermodification {
7650: my ($position,$dom,$settings,$rowtotal) = @_;
7651: my $numinrow = 4;
7652: my ($context,$datatable,$rowcount);
7653: if ($position eq 'top') {
7654: $rowcount = 0;
7655: $context = 'author';
7656: foreach my $role ('ca','aa') {
7657: $datatable .= &modifiable_userdata_row($context,$role,$settings,
7658: $numinrow,$rowcount);
7659: $$rowtotal ++;
7660: $rowcount ++;
7661: }
7662: } elsif ($position eq 'bottom') {
7663: $context = 'course';
7664: $rowcount = 0;
7665: foreach my $role ('st','ep','ta','in','cr') {
7666: $datatable .= &modifiable_userdata_row($context,$role,$settings,
7667: $numinrow,$rowcount);
7668: $$rowtotal ++;
7669: $rowcount ++;
7670: }
7671: }
7672: return $datatable;
7673: }
7674:
7675: sub print_defaults {
7676: my ($position,$dom,$settings,$rowtotal) = @_;
7677: my $rownum = 0;
7678: my ($datatable,$css_class,$titles);
7679: unless ($position eq 'bottom') {
7680: $titles = &defaults_titles($dom);
7681: }
7682: if ($position eq 'top') {
7683: my @items = ('auth_def','auth_arg_def','lang_def','timezone_def',
7684: 'datelocale_def','portal_def');
7685: my %defaults;
7686: if (ref($settings) eq 'HASH') {
7687: %defaults = %{$settings};
7688: } else {
7689: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
7690: foreach my $item (@items) {
7691: $defaults{$item} = $domdefaults{$item};
7692: }
7693: }
7694: foreach my $item (@items) {
7695: if ($rownum%2) {
7696: $css_class = '';
7697: } else {
7698: $css_class = ' class="LC_odd_row" ';
7699: }
7700: $datatable .= '<tr'.$css_class.'>'.
7701: '<td><span class="LC_nobreak">'.$titles->{$item}.
7702: '</span></td><td class="LC_right_item" colspan="3">';
7703: if ($item eq 'auth_def') {
7704: my @authtypes = ('internal','krb4','krb5','localauth','lti');
7705: my %shortauth = (
7706: internal => 'int',
7707: krb4 => 'krb4',
7708: krb5 => 'krb5',
7709: localauth => 'loc',
7710: lti => 'lti',
7711: );
7712: my %authnames = &authtype_names();
7713: foreach my $auth (@authtypes) {
7714: my $checked = ' ';
7715: if ($defaults{$item} eq $auth) {
7716: $checked = ' checked="checked" ';
7717: }
7718: $datatable .= '<label><input type="radio" name="'.$item.
7719: '" value="'.$auth.'"'.$checked.'/>'.
7720: $authnames{$shortauth{$auth}}.'</label> ';
7721: }
7722: } elsif ($item eq 'timezone_def') {
7723: my $includeempty = 1;
7724: $datatable .= &Apache::loncommon::select_timezone($item,$defaults{$item},undef,$includeempty);
7725: } elsif ($item eq 'datelocale_def') {
7726: my $includeempty = 1;
7727: $datatable .= &Apache::loncommon::select_datelocale($item,$defaults{$item},undef,$includeempty);
7728: } elsif ($item eq 'lang_def') {
7729: my $includeempty = 1;
7730: $datatable .= &Apache::loncommon::select_language($item,$defaults{$item},$includeempty);
7731: } else {
7732: my $size;
7733: if ($item eq 'portal_def') {
7734: $size = ' size="25"';
7735: }
7736: $datatable .= '<input type="text" name="'.$item.'" value="'.
7737: $defaults{$item}.'"'.$size.' />';
7738: }
7739: $datatable .= '</td></tr>';
7740: $rownum ++;
7741: }
7742: } elsif ($position eq 'middle') {
7743: my @items = ('intauth_cost','intauth_check','intauth_switch');
7744: my %defaults;
7745: if (ref($settings) eq 'HASH') {
7746: %defaults = %{$settings};
7747: if ($defaults{'intauth_cost'} !~ /^\d+$/) {
7748: $defaults{'intauth_cost'} = 10;
7749: }
7750: if ($defaults{'intauth_check'} !~ /^(0|1|2)$/) {
7751: $defaults{'intauth_check'} = 0;
7752: }
7753: if ($defaults{'intauth_switch'} !~ /^(0|1|2)$/) {
7754: $defaults{'intauth_switch'} = 0;
7755: }
7756: } else {
7757: %defaults = (
7758: 'intauth_cost' => 10,
7759: 'intauth_check' => 0,
7760: 'intauth_switch' => 0,
7761: );
7762: }
7763: foreach my $item (@items) {
7764: if ($rownum%2) {
7765: $css_class = '';
7766: } else {
7767: $css_class = ' class="LC_odd_row" ';
7768: }
7769: $datatable .= '<tr'.$css_class.'>'.
7770: '<td><span class="LC_nobreak">'.$titles->{$item}.
7771: '</span></td><td class="LC_left_item" colspan="3">';
7772: if ($item eq 'intauth_switch') {
7773: my @options = (0,1,2);
7774: my %optiondesc = &Apache::lonlocal::texthash (
7775: 0 => 'No',
7776: 1 => 'Yes',
7777: 2 => 'Yes, and copy existing passwd file to passwd.bak file',
7778: );
7779: $datatable .= '<table width="100%">';
7780: foreach my $option (@options) {
7781: my $checked = ' ';
7782: if ($defaults{$item} eq $option) {
7783: $checked = ' checked="checked"';
7784: }
7785: $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.
7786: '<label><input type="radio" name="'.$item.
7787: '" value="'.$option.'"'.$checked.' />'.
7788: $optiondesc{$option}.'</label></span></td></tr>';
7789: }
7790: $datatable .= '</table>';
7791: } elsif ($item eq 'intauth_check') {
7792: my @options = (0,1,2);
7793: my %optiondesc = &Apache::lonlocal::texthash (
7794: 0 => 'No',
7795: 1 => 'Yes, allow login then update passwd file using default cost (if higher)',
7796: 2 => 'Yes, disallow login if stored cost is less than domain default',
7797: );
7798: $datatable .= '<table width="100%">';
7799: foreach my $option (@options) {
7800: my $checked = ' ';
7801: my $onclick;
7802: if ($defaults{$item} eq $option) {
7803: $checked = ' checked="checked"';
7804: }
7805: if ($option == 2) {
7806: $onclick = ' onclick="javascript:warnIntAuth(this);"';
7807: }
7808: $datatable .= '<tr><td class="LC_left_item"><span class="LC_nobreak">'.
7809: '<label><input type="radio" name="'.$item.
7810: '" value="'.$option.'"'.$checked.$onclick.' />'.
7811: $optiondesc{$option}.'</label></span></td></tr>';
7812: }
7813: $datatable .= '</table>';
7814: } else {
7815: $datatable .= '<input type="text" name="'.$item.'" value="'.
7816: $defaults{$item}.'" size="3" onblur="javascript:warnIntAuth(this);" />';
7817: }
7818: $datatable .= '</td></tr>';
7819: $rownum ++;
7820: }
7821: } else {
7822: my %defaults;
7823: if (ref($settings) eq 'HASH') {
7824: if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {
7825: my $maxnum = @{$settings->{'inststatusorder'}};
7826: for (my $i=0; $i<$maxnum; $i++) {
7827: $css_class = $rownum%2?' class="LC_odd_row"':'';
7828: my $item = $settings->{'inststatusorder'}->[$i];
7829: my $title = $settings->{'inststatustypes'}->{$item};
7830: my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'$item'".');"';
7831: $datatable .= '<tr'.$css_class.'>'.
7832: '<td><span class="LC_nobreak">'.
7833: '<select name="inststatus_pos_'.$item.'"'.$chgstr.'>';
7834: for (my $k=0; $k<=$maxnum; $k++) {
7835: my $vpos = $k+1;
7836: my $selstr;
7837: if ($k == $i) {
7838: $selstr = ' selected="selected" ';
7839: }
7840: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
7841: }
7842: $datatable .= '</select> '.&mt('Internal ID:').' <b>'.$item.'</b> '.
7843: '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'.
7844: &mt('delete').'</span></td>'.
7845: '<td class="LC_left_item" colspan="2"><span class="LC_nobreak">'.&mt('Name displayed:').
7846: '<input type="text" size="20" name="inststatus_title_'.$item.'" value="'.$title.'" />'.
7847: '</span></td></tr>';
7848: }
7849: $css_class = $rownum%2?' class="LC_odd_row"':'';
7850: my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"';
7851: $datatable .= '<tr '.$css_class.'>'.
7852: '<td><span class="LC_nobreak"><select name="addinststatus_pos"'.$chgstr.'>';
7853: for (my $k=0; $k<=$maxnum; $k++) {
7854: my $vpos = $k+1;
7855: my $selstr;
7856: if ($k == $maxnum) {
7857: $selstr = ' selected="selected" ';
7858: }
7859: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
7860: }
7861: $datatable .= '</select> '.&mt('Internal ID:').
7862: '<input type="text" size="10" name="addinststatus" value="" />'.
7863: ' '.&mt('(new)').
7864: '</span></td><td class="LC_left_item" colspan="2"><span class="LC_nobreak">'.
7865: &mt('Name displayed:').
7866: '<input type="text" size="20" name="addinststatus_title" value="" /></span></td>'.
7867: '</tr>'."\n";
7868: $rownum ++;
7869: }
7870: }
7871: }
7872: $$rowtotal += $rownum;
7873: return $datatable;
7874: }
7875:
7876: sub get_languages_hash {
7877: my %langchoices;
7878: foreach my $id (&Apache::loncommon::languageids()) {
7879: my $code = &Apache::loncommon::supportedlanguagecode($id);
7880: if ($code ne '') {
7881: $langchoices{$code} = &Apache::loncommon::plainlanguagedescription($id);
7882: }
7883: }
7884: return %langchoices;
7885: }
7886:
7887: sub defaults_titles {
7888: my ($dom) = @_;
7889: my %titles = &Apache::lonlocal::texthash (
7890: 'auth_def' => 'Default authentication type',
7891: 'auth_arg_def' => 'Default authentication argument',
7892: 'lang_def' => 'Default language',
7893: 'timezone_def' => 'Default timezone',
7894: 'datelocale_def' => 'Default locale for dates',
7895: 'portal_def' => 'Portal/Default URL',
7896: 'intauth_cost' => 'Encryption cost for bcrypt (positive integer)',
7897: 'intauth_check' => 'Check bcrypt cost if authenticated',
7898: 'intauth_switch' => 'Existing crypt-based switched to bcrypt on authentication',
7899: );
7900: if ($dom) {
7901: my $uprimary_id = &Apache::lonnet::domain($dom,'primary');
7902: my $uint_dom = &Apache::lonnet::internet_dom($uprimary_id);
7903: my $protocol = $Apache::lonnet::protocol{$uprimary_id};
7904: $protocol = 'http' if ($protocol ne 'https');
7905: if ($uint_dom) {
7906: $titles{'portal_def'} .= ' '.&mt('(for example: [_1])',$protocol.'://loncapa.'.
7907: $uint_dom);
7908: }
7909: }
7910: return (\%titles);
7911: }
7912:
7913: sub print_scantronformat {
7914: my ($r,$dom,$confname,$settings,$rowtotal) = @_;
7915: my $itemcount = 1;
7916: my ($datatable,$css_class,$scantronurl,$is_custom,%error,%scantronurls,
7917: %confhash);
7918: my $switchserver = &check_switchserver($dom,$confname);
7919: my %lt = &Apache::lonlocal::texthash (
7920: default => 'Default bubblesheet format file error',
7921: custom => 'Custom bubblesheet format file error',
7922: );
7923: my %scantronfiles = (
7924: default => 'default.tab',
7925: custom => 'custom.tab',
7926: );
7927: foreach my $key (keys(%scantronfiles)) {
7928: $scantronurls{$key} = '/res/'.$dom.'/'.$confname.'/scantron/'
7929: .$scantronfiles{$key};
7930: }
7931: my @defaultinfo = &Apache::lonnet::stat_file($scantronurls{'default'});
7932: if ((!@defaultinfo) || ($defaultinfo[0] eq 'no_such_dir')) {
7933: if (!$switchserver) {
7934: my $servadm = $r->dir_config('lonAdmEMail');
7935: my ($configuserok,$author_ok) = &config_check($dom,$confname,$servadm);
7936: if ($configuserok eq 'ok') {
7937: if ($author_ok eq 'ok') {
7938: my %legacyfile = (
7939: default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab',
7940: custom => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab',
7941: );
7942: my %md5chk;
7943: foreach my $type (keys(%legacyfile)) {
7944: ($md5chk{$type}) = split(/ /,`md5sum $legacyfile{$type}`);
7945: chomp($md5chk{$type});
7946: }
7947: if ($md5chk{'default'} ne $md5chk{'custom'}) {
7948: foreach my $type (keys(%legacyfile)) {
7949: ($scantronurls{$type},my $error) =
7950: &legacy_scantronformat($r,$dom,$confname,
7951: $type,$legacyfile{$type},
7952: $scantronurls{$type},
7953: $scantronfiles{$type});
7954: if ($error ne '') {
7955: $error{$type} = $error;
7956: }
7957: }
7958: if (keys(%error) == 0) {
7959: $is_custom = 1;
7960: $confhash{'scantron'}{'scantronformat'} =
7961: $scantronurls{'custom'};
7962: my $putresult =
7963: &Apache::lonnet::put_dom('configuration',
7964: \%confhash,$dom);
7965: if ($putresult ne 'ok') {
7966: $error{'custom'} =
7967: '<span class="LC_error">'.
7968: &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>';
7969: }
7970: }
7971: } else {
7972: ($scantronurls{'default'},my $error) =
7973: &legacy_scantronformat($r,$dom,$confname,
7974: 'default',$legacyfile{'default'},
7975: $scantronurls{'default'},
7976: $scantronfiles{'default'});
7977: if ($error eq '') {
7978: $confhash{'scantron'}{'scantronformat'} = '';
7979: my $putresult =
7980: &Apache::lonnet::put_dom('configuration',
7981: \%confhash,$dom);
7982: if ($putresult ne 'ok') {
7983: $error{'default'} =
7984: '<span class="LC_error">'.
7985: &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>';
7986: }
7987: } else {
7988: $error{'default'} = $error;
7989: }
7990: }
7991: }
7992: }
7993: } else {
7994: $error{'default'} = &mt("Unable to copy default bubblesheet formatfile to domain's RES space: [_1]",$switchserver);
7995: }
7996: }
7997: if (ref($settings) eq 'HASH') {
7998: if ($settings->{'scantronformat'} eq "/res/$dom/$confname/scantron/custom.tab") {
7999: my @info = &Apache::lonnet::stat_file($settings->{'scantronformat'});
8000: if ((!@info) || ($info[0] eq 'no_such_dir')) {
8001: $scantronurl = '';
8002: } else {
8003: $scantronurl = $settings->{'scantronformat'};
8004: }
8005: $is_custom = 1;
8006: } else {
8007: $scantronurl = $scantronurls{'default'};
8008: }
8009: } else {
8010: if ($is_custom) {
8011: $scantronurl = $scantronurls{'custom'};
8012: } else {
8013: $scantronurl = $scantronurls{'default'};
8014: }
8015: }
8016: $css_class = $itemcount%2?' class="LC_odd_row"':'';
8017: $datatable .= '<tr'.$css_class.'>';
8018: if (!$is_custom) {
8019: $datatable .= '<td>'.&mt('Default in use:').'<br />'.
8020: '<span class="LC_nobreak">';
8021: if ($scantronurl) {
8022: $datatable .= &Apache::loncommon::modal_link($scantronurl,&mt('Default bubblesheet format file'),600,500,
8023: undef,undef,undef,undef,'background-color:#ffffff');
8024: } else {
8025: $datatable = &mt('File unavailable for display');
8026: }
8027: $datatable .= '</span></td>';
8028: if (keys(%error) == 0) {
8029: $datatable .= '<td style="vertical-align: bottom">';
8030: if (!$switchserver) {
8031: $datatable .= &mt('Upload:').'<br />';
8032: }
8033: } else {
8034: my $errorstr;
8035: foreach my $key (sort(keys(%error))) {
8036: $errorstr .= $lt{$key}.': '.$error{$key}.'<br />';
8037: }
8038: $datatable .= '<td>'.$errorstr;
8039: }
8040: } else {
8041: if (keys(%error) > 0) {
8042: my $errorstr;
8043: foreach my $key (sort(keys(%error))) {
8044: $errorstr .= $lt{$key}.': '.$error{$key}.'<br />';
8045: }
8046: $datatable .= '<td>'.$errorstr.'</td><td> ';
8047: } elsif ($scantronurl) {
8048: my $link = &Apache::loncommon::modal_link($scantronurl,&mt('Custom bubblesheet format file'),600,500,
8049: undef,undef,undef,undef,'background-color:#ffffff');
8050: $datatable .= '<td><span class="LC_nobreak">'.
8051: $link.
8052: '<label><input type="checkbox" name="scantronformat_del"'.
8053: ' value="1" />'.&mt('Delete?').'</label></span></td>'.
8054: '<td><span class="LC_nobreak"> '.
8055: &mt('Replace:').'</span><br />';
8056: }
8057: }
8058: if (keys(%error) == 0) {
8059: if ($switchserver) {
8060: $datatable .= &mt('Upload to library server: [_1]',$switchserver);
8061: } else {
8062: $datatable .='<span class="LC_nobreak"> '.
8063: '<input type="file" name="scantronformat" /></span>';
8064: }
8065: }
8066: $datatable .= '</td></tr>';
8067: $$rowtotal ++;
8068: return $datatable;
8069: }
8070:
8071: sub legacy_scantronformat {
8072: my ($r,$dom,$confname,$file,$legacyfile,$newurl,$newfile) = @_;
8073: my ($url,$error);
8074: my @statinfo = &Apache::lonnet::stat_file($newurl);
8075: if ((!@statinfo) || ($statinfo[0] eq 'no_such_dir')) {
8076: (my $result,$url) =
8077: &publishlogo($r,'copy',$legacyfile,$dom,$confname,'scantron',
8078: '','',$newfile);
8079: if ($result ne 'ok') {
8080: $error = &mt("An error occurred publishing the [_1] bubblesheet format file in RES space. Error was: [_2].",$newfile,$result);
8081: }
8082: }
8083: return ($url,$error);
8084: }
8085:
8086: sub print_coursecategories {
8087: my ($position,$dom,$hdritem,$settings,$rowtotal) = @_;
8088: my $datatable;
8089: if ($position eq 'top') {
8090: my (%checked);
8091: my @catitems = ('unauth','auth');
8092: my @cattypes = ('std','domonly','codesrch','none');
8093: $checked{'unauth'} = 'std';
8094: $checked{'auth'} = 'std';
8095: if (ref($settings) eq 'HASH') {
8096: foreach my $type (@cattypes) {
8097: if ($type eq $settings->{'unauth'}) {
8098: $checked{'unauth'} = $type;
8099: }
8100: if ($type eq $settings->{'auth'}) {
8101: $checked{'auth'} = $type;
8102: }
8103: }
8104: }
8105: my %lt = &Apache::lonlocal::texthash (
8106: unauth => 'Catalog type for unauthenticated users',
8107: auth => 'Catalog type for authenticated users',
8108: none => 'No catalog',
8109: std => 'Standard catalog',
8110: domonly => 'Domain-only catalog',
8111: codesrch => "Code search form",
8112: );
8113: my $itemcount = 0;
8114: foreach my $item (@catitems) {
8115: my $css_class = $itemcount%2? ' class="LC_odd_row"':'';
8116: $datatable .= '<tr '.$css_class.'>'.
8117: '<td>'.$lt{$item}.'</td>'.
8118: '<td class="LC_right_item"><span class="LC_nobreak">';
8119: foreach my $type (@cattypes) {
8120: my $ischecked;
8121: if ($checked{$item} eq $type) {
8122: $ischecked=' checked="checked"';
8123: }
8124: $datatable .= '<label>'.
8125: '<input type="radio" name="coursecat_'.$item.'" value="'.$type.'"'.$ischecked.
8126: ' />'.$lt{$type}.'</label> ';
8127: }
8128: $datatable .= '</span></td></tr>';
8129: $itemcount ++;
8130: }
8131: $$rowtotal += $itemcount;
8132: } elsif ($position eq 'middle') {
8133: my $toggle_cats_crs = ' ';
8134: my $toggle_cats_dom = ' checked="checked" ';
8135: my $can_cat_crs = ' ';
8136: my $can_cat_dom = ' checked="checked" ';
8137: my $toggle_catscomm_comm = ' ';
8138: my $toggle_catscomm_dom = ' checked="checked" ';
8139: my $can_catcomm_comm = ' ';
8140: my $can_catcomm_dom = ' checked="checked" ';
8141: my $toggle_catsplace_place = ' ';
8142: my $toggle_catsplace_dom = ' checked="checked" ';
8143: my $can_catplace_place = ' ';
8144: my $can_catplace_dom = ' checked="checked" ';
8145:
8146: if (ref($settings) eq 'HASH') {
8147: if ($settings->{'togglecats'} eq 'crs') {
8148: $toggle_cats_crs = $toggle_cats_dom;
8149: $toggle_cats_dom = ' ';
8150: }
8151: if ($settings->{'categorize'} eq 'crs') {
8152: $can_cat_crs = $can_cat_dom;
8153: $can_cat_dom = ' ';
8154: }
8155: if ($settings->{'togglecatscomm'} eq 'comm') {
8156: $toggle_catscomm_comm = $toggle_catscomm_dom;
8157: $toggle_catscomm_dom = ' ';
8158: }
8159: if ($settings->{'categorizecomm'} eq 'comm') {
8160: $can_catcomm_comm = $can_catcomm_dom;
8161: $can_catcomm_dom = ' ';
8162: }
8163: if ($settings->{'togglecatsplace'} eq 'place') {
8164: $toggle_catsplace_place = $toggle_catsplace_dom;
8165: $toggle_catsplace_dom = ' ';
8166: }
8167: if ($settings->{'categorizeplace'} eq 'place') {
8168: $can_catplace_place = $can_catplace_dom;
8169: $can_catplace_dom = ' ';
8170: }
8171: }
8172: my %title = &Apache::lonlocal::texthash (
8173: togglecats => 'Show/Hide a course in catalog',
8174: togglecatscomm => 'Show/Hide a community in catalog',
8175: togglecatsplace => 'Show/Hide a placement test in catalog',
8176: categorize => 'Assign a category to a course',
8177: categorizecomm => 'Assign a category to a community',
8178: categorizeplace => 'Assign a category to a placement test',
8179: );
8180: my %level = &Apache::lonlocal::texthash (
8181: dom => 'Set in Domain',
8182: crs => 'Set in Course',
8183: comm => 'Set in Community',
8184: place => 'Set in Placement Test',
8185: );
8186: $datatable = '<tr class="LC_odd_row">'.
8187: '<td>'.$title{'togglecats'}.'</td>'.
8188: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
8189: '<input type="radio" name="togglecats"'.
8190: $toggle_cats_dom.' value="dom" />'.$level{'dom'}.'</label> '.
8191: '<label><input type="radio" name="togglecats"'.
8192: $toggle_cats_crs.' value="crs" />'.$level{'crs'}.'</label></span></td>'.
8193: '</tr><tr>'.
8194: '<td>'.$title{'categorize'}.'</td>'.
8195: '<td class="LC_right_item"><span class="LC_nobreak">'.
8196: '<label><input type="radio" name="categorize"'.
8197: $can_cat_dom.' value="dom" />'.$level{'dom'}.'</label> '.
8198: '<label><input type="radio" name="categorize"'.
8199: $can_cat_crs.'value="crs" />'.$level{'crs'}.'</label></span></td>'.
8200: '</tr><tr class="LC_odd_row">'.
8201: '<td>'.$title{'togglecatscomm'}.'</td>'.
8202: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
8203: '<input type="radio" name="togglecatscomm"'.
8204: $toggle_catscomm_dom.' value="dom" />'.$level{'dom'}.'</label> '.
8205: '<label><input type="radio" name="togglecatscomm"'.
8206: $toggle_catscomm_comm.' value="comm" />'.$level{'comm'}.'</label></span></td>'.
8207: '</tr><tr>'.
8208: '<td>'.$title{'categorizecomm'}.'</td>'.
8209: '<td class="LC_right_item"><span class="LC_nobreak">'.
8210: '<label><input type="radio" name="categorizecomm"'.
8211: $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label> '.
8212: '<label><input type="radio" name="categorizecomm"'.
8213: $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'.
8214: '</tr><tr class="LC_odd_row">'.
8215: '<td>'.$title{'togglecatsplace'}.'</td>'.
8216: '<td class="LC_right_item"><span class="LC_nobreak"><label>'.
8217: '<input type="radio" name="togglecatsplace"'.
8218: $toggle_catsplace_dom.' value="dom" />'.$level{'dom'}.'</label> '.
8219: '<label><input type="radio" name="togglecatscomm"'.
8220: $toggle_catsplace_place.' value="comm" />'.$level{'place'}.'</label></span></td>'.
8221: '</tr><tr>'.
8222: '<td>'.$title{'categorizeplace'}.'</td>'.
8223: '<td class="LC_right_item"><span class="LC_nobreak">'.
8224: '<label><input type="radio" name="categorizeplace"'.
8225: $can_catplace_dom.' value="dom" />'.$level{'dom'}.'</label> '.
8226: '<label><input type="radio" name="categorizeplace"'.
8227: $can_catplace_place.'value="place" />'.$level{'place'}.'</label></span></td>'.
8228: '</tr>';
8229: $$rowtotal += 6;
8230: } else {
8231: my $css_class;
8232: my $itemcount = 1;
8233: my $cathash;
8234: if (ref($settings) eq 'HASH') {
8235: $cathash = $settings->{'cats'};
8236: }
8237: if (ref($cathash) eq 'HASH') {
8238: my (@cats,@trails,%allitems,%idx,@jsarray);
8239: &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,
8240: \%allitems,\%idx,\@jsarray);
8241: my $maxdepth = scalar(@cats);
8242: my $colattrib = '';
8243: if ($maxdepth > 2) {
8244: $colattrib = ' colspan="2" ';
8245: }
8246: my @path;
8247: if (@cats > 0) {
8248: if (ref($cats[0]) eq 'ARRAY') {
8249: my $numtop = @{$cats[0]};
8250: my $maxnum = $numtop;
8251: my %default_names = (
8252: instcode => &mt('Official courses'),
8253: communities => &mt('Communities'),
8254: placement => &mt('Placement Tests'),
8255: );
8256:
8257: if ((!grep(/^instcode$/,@{$cats[0]})) ||
8258: ($cathash->{'instcode::0'} eq '') ||
8259: (!grep(/^communities$/,@{$cats[0]})) ||
8260: ($cathash->{'communities::0'} eq '') ||
8261: (!grep(/^placement$/,@{$cats[0]})) ||
8262: ($cathash->{'placement::0'} eq '')) {
8263: $maxnum ++;
8264: }
8265: my $lastidx;
8266: for (my $i=0; $i<$numtop; $i++) {
8267: my $parent = $cats[0][$i];
8268: $css_class = $itemcount%2?' class="LC_odd_row"':'';
8269: my $item = &escape($parent).'::0';
8270: my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$item','$idx{$item}'".');"';
8271: $lastidx = $idx{$item};
8272: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
8273: .'<select name="'.$item.'"'.$chgstr.'>';
8274: for (my $k=0; $k<=$maxnum; $k++) {
8275: my $vpos = $k+1;
8276: my $selstr;
8277: if ($k == $i) {
8278: $selstr = ' selected="selected" ';
8279: }
8280: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
8281: }
8282: $datatable .= '</select></span></td><td>';
8283: if ($parent eq 'instcode' || $parent eq 'communities' || $parent eq 'placement') {
8284: $datatable .= '<span class="LC_nobreak">'
8285: .$default_names{$parent}.'</span>';
8286: if ($parent eq 'instcode') {
8287: $datatable .= '<br /><span class="LC_nobreak">('
8288: .&mt('with institutional codes')
8289: .')</span></td><td'.$colattrib.'>';
8290: } else {
8291: $datatable .= '<table><tr><td>';
8292: }
8293: $datatable .= '<span class="LC_nobreak">'
8294: .'<label><input type="radio" name="'
8295: .$parent.'" value="1" checked="checked" />'
8296: .&mt('Display').'</label>';
8297: if ($parent eq 'instcode') {
8298: $datatable .= ' ';
8299: } else {
8300: $datatable .= '</span></td></tr><tr><td>'
8301: .'<span class="LC_nobreak">';
8302: }
8303: $datatable .= '<label><input type="radio" name="'
8304: .$parent.'" value="0" />'
8305: .&mt('Do not display').'</label></span>';
8306: if (($parent eq 'communities') || ($parent eq 'placement')) {
8307: $datatable .= '</td></tr></table>';
8308: }
8309: $datatable .= '</td>';
8310: } else {
8311: $datatable .= $parent
8312: .' <span class="LC_nobreak"><label>'
8313: .'<input type="checkbox" name="deletecategory" '
8314: .'value="'.$item.'" />'.&mt('Delete').'</label></span></td>';
8315: }
8316: my $depth = 1;
8317: push(@path,$parent);
8318: $datatable .= &build_category_rows($itemcount,\@cats,$depth,$parent,\@path,\%idx);
8319: pop(@path);
8320: $datatable .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>';
8321: $itemcount ++;
8322: }
8323: $css_class = $itemcount%2?' class="LC_odd_row"':'';
8324: my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','$lastidx'".');"';
8325: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="addcategory_pos"'.$chgstr.'>';
8326: for (my $k=0; $k<=$maxnum; $k++) {
8327: my $vpos = $k+1;
8328: my $selstr;
8329: if ($k == $numtop) {
8330: $selstr = ' selected="selected" ';
8331: }
8332: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
8333: }
8334: $datatable .= '</select></span></td><td colspan="2">'.&mt('Add category:').' '
8335: .'<input type="text" size="20" name="addcategory_name" value="" /></td>'
8336: .'</tr>'."\n";
8337: $itemcount ++;
8338: foreach my $default ('instcode','communities','placement') {
8339: if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) {
8340: $css_class = $itemcount%2?' class="LC_odd_row"':'';
8341: my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"';
8342: $datatable .= '<tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr><tr '.$css_class.'><td>'.
8343: '<span class="LC_nobreak"><select name="'.$default.'_pos"'.$chgstr.'>';
8344: for (my $k=0; $k<=$maxnum; $k++) {
8345: my $vpos = $k+1;
8346: my $selstr;
8347: if ($k == $maxnum) {
8348: $selstr = ' selected="selected" ';
8349: }
8350: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>';
8351: }
8352: $datatable .= '</select></span></td>'.
8353: '<td><span class="LC_nobreak">'.
8354: $default_names{$default}.'</span>';
8355: if ($default eq 'instcode') {
8356: $datatable .= '<br /><span class="LC_nobreak">('
8357: .&mt('with institutional codes').')</span>';
8358: }
8359: $datatable .= '</td>'
8360: .'<td><span class="LC_nobreak"><label><input type="radio" name="'.$default.'" value="1" />'
8361: .&mt('Display').'</label> '
8362: .'<label><input type="radio" name="'.$default.'" value="0" checked="checked"/>'
8363: .&mt('Do not display').'</label></span></td></tr>';
8364: }
8365: }
8366: }
8367: } else {
8368: $datatable .= &initialize_categories($itemcount);
8369: }
8370: } else {
8371: $datatable .= '<tr><td class="LC_right_item">'.$hdritem->{'header'}->[1]->{'col2'}.'</td></tr>'
8372: .&initialize_categories($itemcount);
8373: }
8374: $$rowtotal += $itemcount;
8375: }
8376: return $datatable;
8377: }
8378:
8379: sub print_serverstatuses {
8380: my ($dom,$settings,$rowtotal) = @_;
8381: my $datatable;
8382: my @pages = &serverstatus_pages();
8383: my (%namedaccess,%machineaccess);
8384: foreach my $type (@pages) {
8385: $namedaccess{$type} = '';
8386: $machineaccess{$type}= '';
8387: }
8388: if (ref($settings) eq 'HASH') {
8389: foreach my $type (@pages) {
8390: if (exists($settings->{$type})) {
8391: if (ref($settings->{$type}) eq 'HASH') {
8392: foreach my $key (keys(%{$settings->{$type}})) {
8393: if ($key eq 'namedusers') {
8394: $namedaccess{$type} = $settings->{$type}->{$key};
8395: } elsif ($key eq 'machines') {
8396: $machineaccess{$type} = $settings->{$type}->{$key};
8397: }
8398: }
8399: }
8400: }
8401: }
8402: }
8403: my $titles= &LONCAPA::lonauthcgi::serverstatus_titles();
8404: my $rownum = 0;
8405: my $css_class;
8406: foreach my $type (@pages) {
8407: $rownum ++;
8408: $css_class = $rownum%2?' class="LC_odd_row"':'';
8409: $datatable .= '<tr'.$css_class.'>'.
8410: '<td><span class="LC_nobreak">'.
8411: $titles->{$type}.'</span></td>'.
8412: '<td class="LC_left_item">'.
8413: '<input type="text" name="'.$type.'_namedusers" '.
8414: 'value="'.$namedaccess{$type}.'" size="30" /></td>'.
8415: '<td class="LC_right_item">'.
8416: '<span class="LC_nobreak">'.
8417: '<input type="text" name="'.$type.'_machines" '.
8418: 'value="'.$machineaccess{$type}.'" size="10" />'.
8419: '</span></td></tr>'."\n";
8420: }
8421: $$rowtotal += $rownum;
8422: return $datatable;
8423: }
8424:
8425: sub serverstatus_pages {
8426: return ('userstatus','lonstatus','loncron','server-status','codeversions',
8427: 'checksums','clusterstatus','certstatus','metadata_keywords',
8428: 'metadata_harvest','takeoffline','takeonline','showenv','toggledebug',
8429: 'ping','domconf','uniquecodes','diskusage','coursecatalog');
8430: }
8431:
8432: sub defaults_javascript {
8433: my ($settings) = @_;
8434: my $intauthcheck = &mt('Warning: disallowing login for an authenticated user if the stored cost is less than the default will require a password reset by/for the user.');
8435: my $intauthcost = &mt('Warning: bcrypt encryption cost for internal authentication must be an integer.');
8436: &js_escape(\$intauthcheck);
8437: &js_escape(\$intauthcost);
8438: my $intauthjs = <<"ENDSCRIPT";
8439:
8440: function warnIntAuth(field) {
8441: if (field.name == 'intauth_check') {
8442: if (field.value == '2') {
8443: alert('$intauthcheck');
8444: }
8445: }
8446: if (field.name == 'intauth_cost') {
8447: field.value.replace(/\s/g,'');
8448: if (field.value != '') {
8449: var regexdigit=/^\\d+\$/;
8450: if (!regexdigit.test(field.value)) {
8451: alert('$intauthcost');
8452: }
8453: }
8454: }
8455: return;
8456: }
8457:
8458: ENDSCRIPT
8459:
8460: if (ref($settings) ne 'HASH') {
8461: return &Apache::lonhtmlcommon::scripttag($intauthjs);
8462: }
8463: if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) {
8464: my $maxnum = scalar(@{$settings->{'inststatusorder'}});
8465: if ($maxnum eq '') {
8466: $maxnum = 0;
8467: }
8468: $maxnum ++;
8469: my $jstext = ' var inststatuses = Array('."'".join("','",@{$settings->{'inststatusorder'}})."'".');';
8470: return <<"ENDSCRIPT";
8471: <script type="text/javascript">
8472: // <![CDATA[
8473: function reorderTypes(form,caller) {
8474: var changedVal;
8475: $jstext
8476: var newpos = 'addinststatus_pos';
8477: var current = new Array;
8478: var maxh = $maxnum;
8479: var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
8480: var oldVal;
8481: if (caller == newpos) {
8482: changedVal = newitemVal;
8483: } else {
8484: var curritem = 'inststatus_pos_'+caller;
8485: changedVal = form.elements[curritem].options[form.elements[curritem].selectedIndex].value;
8486: current[newitemVal] = newpos;
8487: }
8488: for (var i=0; i<inststatuses.length; i++) {
8489: if (inststatuses[i] != caller) {
8490: var elementName = 'inststatus_pos_'+inststatuses[i];
8491: if (form.elements[elementName]) {
8492: var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
8493: current[currVal] = elementName;
8494: }
8495: }
8496: }
8497: for (var j=0; j<maxh; j++) {
8498: if (current[j] == undefined) {
8499: oldVal = j;
8500: }
8501: }
8502: if (oldVal < changedVal) {
8503: for (var k=oldVal+1; k<=changedVal ; k++) {
8504: var elementName = current[k];
8505: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
8506: }
8507: } else {
8508: for (var k=changedVal; k<oldVal; k++) {
8509: var elementName = current[k];
8510: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
8511: }
8512: }
8513: return;
8514: }
8515:
8516: $intauthjs
8517:
8518: // ]]>
8519: </script>
8520:
8521: ENDSCRIPT
8522: } else {
8523: return &Apache::lonhtmlcommon::scripttag($intauthjs);
8524: }
8525: }
8526:
8527: sub coursecategories_javascript {
8528: my ($settings) = @_;
8529: my ($output,$jstext,$cathash);
8530: if (ref($settings) eq 'HASH') {
8531: $cathash = $settings->{'cats'};
8532: }
8533: if (ref($cathash) eq 'HASH') {
8534: my (@cats,@jsarray,%idx);
8535: &Apache::loncommon::gather_categories($cathash,\@cats,\%idx,\@jsarray);
8536: if (@jsarray > 0) {
8537: $jstext = ' var categories = Array('.scalar(@jsarray).');'."\n";
8538: for (my $i=0; $i<@jsarray; $i++) {
8539: if (ref($jsarray[$i]) eq 'ARRAY') {
8540: my $catstr = join('","',@{$jsarray[$i]});
8541: $jstext .= ' categories['.$i.'] = Array("'.$catstr.'");'."\n";
8542: }
8543: }
8544: }
8545: } else {
8546: $jstext = ' var categories = Array(1);'."\n".
8547: ' categories[0] = Array("instcode_pos");'."\n";
8548: }
8549: my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"');
8550: my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"');
8551: my $placement_reserved = &mt('The name: [_1] is a reserved category.','"placement"');
8552: my $choose_again = "\n".&mt('Please use a different name for the new top level category.');
8553: &js_escape(\$instcode_reserved);
8554: &js_escape(\$communities_reserved);
8555: &js_escape(\$placement_reserved);
8556: &js_escape(\$choose_again);
8557: $output = <<"ENDSCRIPT";
8558: <script type="text/javascript">
8559: // <![CDATA[
8560: function reorderCats(form,parent,item,idx) {
8561: var changedVal;
8562: $jstext
8563: var newpos = 'addcategory_pos';
8564: if (parent == '') {
8565: var has_instcode = 0;
8566: var maxtop = categories[idx].length;
8567: for (var j=0; j<maxtop; j++) {
8568: if (categories[idx][j] == 'instcode::0') {
8569: has_instcode == 1;
8570: }
8571: }
8572: if (has_instcode == 0) {
8573: categories[idx][maxtop] = 'instcode_pos';
8574: }
8575: } else {
8576: newpos += '_'+parent;
8577: }
8578: var maxh = 1 + categories[idx].length;
8579: var current = new Array;
8580: var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value;
8581: if (item == newpos) {
8582: changedVal = newitemVal;
8583: } else {
8584: changedVal = form.elements[item].options[form.elements[item].selectedIndex].value;
8585: current[newitemVal] = newpos;
8586: }
8587: for (var i=0; i<categories[idx].length; i++) {
8588: var elementName = categories[idx][i];
8589: if (elementName != item) {
8590: if (form.elements[elementName]) {
8591: var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value;
8592: current[currVal] = elementName;
8593: }
8594: }
8595: }
8596: var oldVal;
8597: for (var j=0; j<maxh; j++) {
8598: if (current[j] == undefined) {
8599: oldVal = j;
8600: }
8601: }
8602: if (oldVal < changedVal) {
8603: for (var k=oldVal+1; k<=changedVal ; k++) {
8604: var elementName = current[k];
8605: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1;
8606: }
8607: } else {
8608: for (var k=changedVal; k<oldVal; k++) {
8609: var elementName = current[k];
8610: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1;
8611: }
8612: }
8613: return;
8614: }
8615:
8616: function categoryCheck(form) {
8617: if (form.elements['addcategory_name'].value == 'instcode') {
8618: alert('$instcode_reserved\\n$choose_again');
8619: return false;
8620: }
8621: if (form.elements['addcategory_name'].value == 'communities') {
8622: alert('$communities_reserved\\n$choose_again');
8623: return false;
8624: }
8625: if (form.elements['addcategory_name'].value == 'placement') {
8626: alert('$placement_reserved\\n$choose_again');
8627: return false;
8628: }
8629: return true;
8630: }
8631:
8632: // ]]>
8633: </script>
8634:
8635: ENDSCRIPT
8636: return $output;
8637: }
8638:
8639: sub initialize_categories {
8640: my ($itemcount) = @_;
8641: my ($datatable,$css_class,$chgstr);
8642: my %default_names = (
8643: instcode => 'Official courses (with institutional codes)',
8644: communities => 'Communities',
8645: placement => 'Placement Tests',
8646: );
8647: my %selnum = (
8648: instcode => '0',
8649: communities => '1',
8650: placement => '2',
8651: );
8652: my %selected;
8653: foreach my $default ('instcode','communities','placement') {
8654: $css_class = $itemcount%2?' class="LC_odd_row"':'';
8655: $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','0'".');"';
8656: map { $selected{$selnum{$_}} = '' } keys(%selnum);
8657: $selected{$selnum{$default}} = ' selected="selected"';
8658: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
8659: .'<select name="'.$default.'_pos"'.$chgstr.'>'
8660: .'<option value="0"'.$selected{'0'}.'>1</option>'
8661: .'<option value="1"'.$selected{'1'}.'>2</option>'
8662: .'<option value="2"'.$selected{'2'}.'>3</option>'
8663: .'<option value="3">4</option></select> '
8664: .$default_names{$default}
8665: .'</span></td><td><span class="LC_nobreak">'
8666: .'<label><input type="radio" name="'.$default.'" value="1" checked="checked" />'
8667: .&mt('Display').'</label> <label>'
8668: .'<input type="radio" name="'.$default.'" value="0" />'.&mt('Do not display')
8669: .'</label></span></td></tr>';
8670: $itemcount ++;
8671: }
8672: $css_class = $itemcount%2?' class="LC_odd_row"':'';
8673: $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','0'".');"';
8674: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'
8675: .'<select name="addcategory_pos"'.$chgstr.'>'
8676: .'<option value="0">1</option>'
8677: .'<option value="1">2</option>'
8678: .'<option value="2">3</option>'
8679: .'<option value="3" selected="selected">4</option></select> '
8680: .&mt('Add category').'</span></td><td><span class="LC_nobreak">'.&mt('Name:')
8681: .' <input type="text" size="20" name="addcategory_name" value="" /></span>'
8682: .'</td></tr>';
8683: return $datatable;
8684: }
8685:
8686: sub build_category_rows {
8687: my ($itemcount,$cats,$depth,$parent,$path,$idx) = @_;
8688: my ($text,$name,$item,$chgstr);
8689: if (ref($cats) eq 'ARRAY') {
8690: my $maxdepth = scalar(@{$cats});
8691: if (ref($cats->[$depth]) eq 'HASH') {
8692: if (ref($cats->[$depth]{$parent}) eq 'ARRAY') {
8693: my $numchildren = @{$cats->[$depth]{$parent}};
8694: my $css_class = $itemcount%2?' class="LC_odd_row"':'';
8695: $text .= '<td><table class="LC_data_table">';
8696: my ($idxnum,$parent_name,$parent_item);
8697: my $higher = $depth - 1;
8698: if ($higher == 0) {
8699: $parent_name = &escape($parent).'::'.$higher;
8700: } else {
8701: if (ref($path) eq 'ARRAY') {
8702: $parent_name = &escape($parent).':'.&escape($path->[-2]).':'.$higher;
8703: }
8704: }
8705: $parent_item = 'addcategory_pos_'.$parent_name;
8706: for (my $j=0; $j<=$numchildren; $j++) {
8707: if ($j < $numchildren) {
8708: $name = $cats->[$depth]{$parent}[$j];
8709: $item = &escape($name).':'.&escape($parent).':'.$depth;
8710: $idxnum = $idx->{$item};
8711: } else {
8712: $name = $parent_name;
8713: $item = $parent_item;
8714: }
8715: $chgstr = ' onchange="javascript:reorderCats(this.form,'."'$parent_name','$item','$idxnum'".');"';
8716: $text .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="'.$item.'"'.$chgstr.'>';
8717: for (my $i=0; $i<=$numchildren; $i++) {
8718: my $vpos = $i+1;
8719: my $selstr;
8720: if ($j == $i) {
8721: $selstr = ' selected="selected" ';
8722: }
8723: $text .= '<option value="'.$i.'"'.$selstr.'>'.$vpos.'</option>';
8724: }
8725: $text .= '</select> ';
8726: if ($j < $numchildren) {
8727: my $deeper = $depth+1;
8728: $text .= $name.' '
8729: .'<label><input type="checkbox" name="deletecategory" value="'
8730: .$item.'" />'.&mt('Delete').'</label></span></td><td>';
8731: if(ref($path) eq 'ARRAY') {
8732: push(@{$path},$name);
8733: $text .= &build_category_rows($itemcount,$cats,$deeper,$name,$path,$idx);
8734: pop(@{$path});
8735: }
8736: } else {
8737: $text .= &mt('Add subcategory:').' </span><input type="text" size="20" name="addcategory_name_';
8738: if ($j == $numchildren) {
8739: $text .= $name;
8740: } else {
8741: $text .= $item;
8742: }
8743: $text .= '" value="" />';
8744: }
8745: $text .= '</td></tr>';
8746: }
8747: $text .= '</table></td>';
8748: } else {
8749: my $higher = $depth-1;
8750: if ($higher == 0) {
8751: $name = &escape($parent).'::'.$higher;
8752: } else {
8753: if (ref($path) eq 'ARRAY') {
8754: $name = &escape($parent).':'.&escape($path->[-2]).':'.$higher;
8755: }
8756: }
8757: my $colspan;
8758: if ($parent ne 'instcode') {
8759: $colspan = $maxdepth - $depth - 1;
8760: $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="text" size="20" name="subcat_'.$name.'" value="" /></td>';
8761: }
8762: }
8763: }
8764: }
8765: return $text;
8766: }
8767:
8768: sub modifiable_userdata_row {
8769: my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref,
8770: $rowid,$customcss,$rowstyle) = @_;
8771: my ($role,$rolename,$statustype);
8772: $role = $item;
8773: if ($context eq 'cancreate') {
8774: if ($item =~ /^(emailusername)_(.+)$/) {
8775: $role = $1;
8776: $statustype = $2;
8777: if (ref($usertypes) eq 'HASH') {
8778: if ($usertypes->{$statustype}) {
8779: $rolename = &mt('Data provided by [_1]',$usertypes->{$statustype});
8780: } else {
8781: $rolename = &mt('Data provided by user');
8782: }
8783: }
8784: }
8785: } elsif ($context eq 'selfcreate') {
8786: if (ref($usertypes) eq 'HASH') {
8787: $rolename = $usertypes->{$role};
8788: } else {
8789: $rolename = $role;
8790: }
8791: } elsif ($context eq 'lti') {
8792: $rolename = &mt('Institutional data used (if available)');
8793: } else {
8794: if ($role eq 'cr') {
8795: $rolename = &mt('Custom role');
8796: } else {
8797: $rolename = &Apache::lonnet::plaintext($role);
8798: }
8799: }
8800: my (@fields,%fieldtitles);
8801: if (ref($fieldsref) eq 'ARRAY') {
8802: @fields = @{$fieldsref};
8803: } else {
8804: @fields = ('lastname','firstname','middlename','generation',
8805: 'permanentemail','id');
8806: }
8807: if ((ref($titlesref) eq 'HASH')) {
8808: %fieldtitles = %{$titlesref};
8809: } else {
8810: %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
8811: }
8812: my $output;
8813: my $css_class;
8814: if ($rowcount%2) {
8815: $css_class = 'LC_odd_row';
8816: }
8817: if ($customcss) {
8818: $css_class .= " $customcss";
8819: }
8820: $css_class =~ s/^\s+//;
8821: if ($css_class) {
8822: $css_class = ' class="'.$css_class.'"';
8823: }
8824: if ($rowstyle) {
8825: $css_class .= ' style="'.$rowstyle.'"';
8826: }
8827: if ($rowid) {
8828: $rowid = ' id="'.$rowid.'"';
8829: }
8830: $output = '<tr '.$css_class.$rowid.'>'.
8831: '<td><span class="LC_nobreak">'.$rolename.'</span></td>'.
8832: '<td class="LC_left_item" colspan="2"><table>';
8833: my $rem;
8834: my %checks;
8835: my %current;
8836: if (ref($settings) eq 'HASH') {
8837: my $hashref;
8838: if ($context eq 'lti') {
8839: if (ref($settings) eq 'HASH') {
8840: $hashref = $settings->{'instdata'};
8841: }
8842: } elsif (ref($settings->{$context}) eq 'HASH') {
8843: if (ref($settings->{$context}->{$role}) eq 'HASH') {
8844: $hashref = $settings->{'lti_instdata'};
8845: }
8846: if ($role eq 'emailusername') {
8847: if ($statustype) {
8848: if (ref($settings->{$context}->{$role}->{$statustype}) eq 'HASH') {
8849: $hashref = $settings->{$context}->{$role}->{$statustype};
8850: }
8851: }
8852: }
8853: }
8854: if (ref($hashref) eq 'HASH') {
8855: foreach my $field (@fields) {
8856: if ($hashref->{$field}) {
8857: if ($role eq 'emailusername') {
8858: $checks{$field} = $hashref->{$field};
8859: } else {
8860: $checks{$field} = ' checked="checked" ';
8861: }
8862: }
8863: }
8864: }
8865: }
8866:
8867: my $total = scalar(@fields);
8868: for (my $i=0; $i<$total; $i++) {
8869: $rem = $i%($numinrow);
8870: if ($rem == 0) {
8871: if ($i > 0) {
8872: $output .= '</tr>';
8873: }
8874: $output .= '<tr>';
8875: }
8876: my $check = ' ';
8877: unless ($role eq 'emailusername') {
8878: if (exists($checks{$fields[$i]})) {
8879: $check = $checks{$fields[$i]}
8880: } elsif ($context ne 'lti') {
8881: if ($role eq 'st') {
8882: if (ref($settings) ne 'HASH') {
8883: $check = ' checked="checked" ';
8884: }
8885: }
8886: }
8887: }
8888: $output .= '<td class="LC_left_item">'.
8889: '<span class="LC_nobreak">';
8890: my $prefix = 'canmodify';
8891: if ($role eq 'emailusername') {
8892: unless ($checks{$fields[$i]} =~ /^(required|optional)$/) {
8893: $checks{$fields[$i]} = 'omit';
8894: }
8895: foreach my $option ('required','optional','omit') {
8896: my $checked='';
8897: if ($checks{$fields[$i]} eq $option) {
8898: $checked='checked="checked" ';
8899: }
8900: $output .= '<label>'.
8901: '<input type="radio" name="'.$prefix.'_'.$item.'_'.$fields[$i].'" value="'.$option.'" '.$checked.'/>'.
8902: &mt($option).'</label>'.(' ' x2);
8903: }
8904: $output .= '<i>'.$fieldtitles{$fields[$i]}.'</i>';
8905: } else {
8906: if ($context eq 'lti') {
8907: $prefix = 'lti';
8908: }
8909: $output .= '<label>'.
8910: '<input type="checkbox" name="'.$prefix.'_'.$role.'" '.
8911: 'value="'.$fields[$i].'"'.$check.'/>'.$fieldtitles{$fields[$i]}.
8912: '</label>';
8913: }
8914: $output .= '</span></td>';
8915: }
8916: $rem = $total%$numinrow;
8917: my $colsleft;
8918: if ($rem) {
8919: $colsleft = $numinrow - $rem;
8920: }
8921: if ($colsleft > 1) {
8922: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
8923: ' </td>';
8924: } elsif ($colsleft == 1) {
8925: $output .= '<td class="LC_left_item"> </td>';
8926: }
8927: $output .= '</tr></table></td></tr>';
8928: return $output;
8929: }
8930:
8931: sub insttypes_row {
8932: my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick,
8933: $customcss,$rowstyle) = @_;
8934: my %lt = &Apache::lonlocal::texthash (
8935: cansearch => 'Users allowed to search',
8936: statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)',
8937: lockablenames => 'User preference to lock name',
8938: selfassign => 'Self-reportable affiliations',
8939: overrides => "Override domain's helpdesk settings based on requester's affiliation",
8940: );
8941: my $showdom;
8942: if ($context eq 'cansearch') {
8943: $showdom = ' ('.$dom.')';
8944: }
8945: my $class = 'LC_left_item';
8946: if ($context eq 'statustocreate') {
8947: $class = 'LC_right_item';
8948: }
8949: my $css_class;
8950: if ($$rowtotal%2) {
8951: $css_class = 'LC_odd_row';
8952: }
8953: if ($customcss) {
8954: $css_class .= ' '.$customcss;
8955: }
8956: $css_class =~ s/^\s+//;
8957: if ($css_class) {
8958: $css_class = ' class="'.$css_class.'"';
8959: }
8960: if ($rowstyle) {
8961: $css_class .= ' style="'.$rowstyle.'"';
8962: }
8963: if ($onclick) {
8964: $onclick = 'onclick="'.$onclick.'" ';
8965: }
8966: my $output = '<tr'.$css_class.'>'.
8967: '<td>'.$lt{$context}.$showdom.
8968: '</td><td class="'.$class.'" colspan="2"><table>';
8969: my $rem;
8970: if (ref($types) eq 'ARRAY') {
8971: for (my $i=0; $i<@{$types}; $i++) {
8972: if (defined($usertypes->{$types->[$i]})) {
8973: my $rem = $i%($numinrow);
8974: if ($rem == 0) {
8975: if ($i > 0) {
8976: $output .= '</tr>';
8977: }
8978: $output .= '<tr>';
8979: }
8980: my $check = ' ';
8981: if (ref($settings) eq 'HASH') {
8982: if (ref($settings->{$context}) eq 'ARRAY') {
8983: if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) {
8984: $check = ' checked="checked" ';
8985: }
8986: } elsif (ref($settings->{$context}) eq 'HASH') {
8987: if (ref($settings->{$context}->{$types->[$i]}) eq 'HASH') {
8988: $check = ' checked="checked" ';
8989: }
8990: } elsif ($context eq 'statustocreate') {
8991: $check = ' checked="checked" ';
8992: }
8993: }
8994: $output .= '<td class="LC_left_item">'.
8995: '<span class="LC_nobreak"><label>'.
8996: '<input type="checkbox" name="'.$context.'" '.
8997: 'value="'.$types->[$i].'"'.$check.$onclick.' />'.
8998: $usertypes->{$types->[$i]}.'</label></span></td>';
8999: }
9000: }
9001: $rem = @{$types}%($numinrow);
9002: }
9003: my $colsleft = $numinrow - $rem;
9004: if ($context eq 'overrides') {
9005: if ($colsleft > 1) {
9006: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
9007: } else {
9008: $output .= '<td class="LC_left_item">';
9009: }
9010: $output .= ' ';
9011: } else {
9012: if ($rem == 0) {
9013: $output .= '<tr>';
9014: }
9015: if ($colsleft > 1) {
9016: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">';
9017: } else {
9018: $output .= '<td class="LC_left_item">';
9019: }
9020: my $defcheck = ' ';
9021: if (ref($settings) eq 'HASH') {
9022: if (ref($settings->{$context}) eq 'ARRAY') {
9023: if (grep(/^default$/,@{$settings->{$context}})) {
9024: $defcheck = ' checked="checked" ';
9025: }
9026: } elsif ($context eq 'statustocreate') {
9027: $defcheck = ' checked="checked" ';
9028: }
9029: }
9030: $output .= '<span class="LC_nobreak"><label>'.
9031: '<input type="checkbox" name="'.$context.'" '.
9032: 'value="default"'.$defcheck.$onclick.' />'.
9033: $othertitle.'</label></span>';
9034: }
9035: $output .= '</td></tr></table></td></tr>';
9036: return $output;
9037: }
9038:
9039: sub sorted_searchtitles {
9040: my %searchtitles = &Apache::lonlocal::texthash(
9041: 'uname' => 'username',
9042: 'lastname' => 'last name',
9043: 'lastfirst' => 'last name, first name',
9044: );
9045: my @titleorder = ('uname','lastname','lastfirst');
9046: return (\%searchtitles,\@titleorder);
9047: }
9048:
9049: sub sorted_searchtypes {
9050: my %srchtypes_desc = (
9051: exact => 'is exact match',
9052: contains => 'contains ..',
9053: begins => 'begins with ..',
9054: );
9055: my @srchtypeorder = ('exact','begins','contains');
9056: return (\%srchtypes_desc,\@srchtypeorder);
9057: }
9058:
9059: sub usertype_update_row {
9060: my ($settings,$usertypes,$fieldtitles,$fields,$types,$rownums) = @_;
9061: my $datatable;
9062: my $numinrow = 4;
9063: foreach my $type (@{$types}) {
9064: if (defined($usertypes->{$type})) {
9065: $$rownums ++;
9066: my $css_class = $$rownums%2?' class="LC_odd_row"':'';
9067: $datatable .= '<tr'.$css_class.'><td>'.$usertypes->{$type}.
9068: '</td><td class="LC_left_item"><table>';
9069: for (my $i=0; $i<@{$fields}; $i++) {
9070: my $rem = $i%($numinrow);
9071: if ($rem == 0) {
9072: if ($i > 0) {
9073: $datatable .= '</tr>';
9074: }
9075: $datatable .= '<tr>';
9076: }
9077: my $check = ' ';
9078: if (ref($settings) eq 'HASH') {
9079: if (ref($settings->{'fields'}) eq 'HASH') {
9080: if (ref($settings->{'fields'}{$type}) eq 'ARRAY') {
9081: if (grep(/^\Q$fields->[$i]\E$/,@{$settings->{'fields'}{$type}})) {
9082: $check = ' checked="checked" ';
9083: }
9084: }
9085: }
9086: }
9087:
9088: if ($i == @{$fields}-1) {
9089: my $colsleft = $numinrow - $rem;
9090: if ($colsleft > 1) {
9091: $datatable .= '<td colspan="'.$colsleft.'">';
9092: } else {
9093: $datatable .= '<td>';
9094: }
9095: } else {
9096: $datatable .= '<td>';
9097: }
9098: $datatable .= '<span class="LC_nobreak"><label>'.
9099: '<input type="checkbox" name="updateable_'.$type.
9100: '_'.$fields->[$i].'" value="1"'.$check.'/>'.
9101: $fieldtitles->{$fields->[$i]}.'</label></span></td>';
9102: }
9103: $datatable .= '</tr></table></td></tr>';
9104: }
9105: }
9106: return $datatable;
9107: }
9108:
9109: sub modify_login {
9110: my ($r,$dom,$confname,$lastactref,%domconfig) = @_;
9111: my ($resulttext,$errors,$colchgtext,%changes,%colchanges,%newfile,%newurl,
9112: %curr_loginvia,%loginhash,@currlangs,@newlangs,$addedfile,%title,@offon);
9113: %title = ( coursecatalog => 'Display course catalog',
9114: adminmail => 'Display administrator E-mail address',
9115: helpdesk => 'Display "Contact Helpdesk" link',
9116: newuser => 'Link for visitors to create a user account',
9117: loginheader => 'Log-in box header');
9118: @offon = ('off','on');
9119: if (ref($domconfig{login}) eq 'HASH') {
9120: if (ref($domconfig{login}{loginvia}) eq 'HASH') {
9121: foreach my $lonhost (keys(%{$domconfig{login}{loginvia}})) {
9122: $curr_loginvia{$lonhost} = $domconfig{login}{loginvia}{$lonhost};
9123: }
9124: }
9125: }
9126: ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'],
9127: \%domconfig,\%loginhash);
9128: my @toggles = ('coursecatalog','adminmail','helpdesk','newuser');
9129: foreach my $item (@toggles) {
9130: $loginhash{login}{$item} = $env{'form.'.$item};
9131: }
9132: $loginhash{login}{loginheader} = $env{'form.loginheader'};
9133: if (ref($colchanges{'login'}) eq 'HASH') {
9134: $colchgtext = &display_colorchgs($dom,\%colchanges,['login'],
9135: \%loginhash);
9136: }
9137:
9138: my %servers = &Apache::lonnet::internet_dom_servers($dom);
9139: my %domservers = &Apache::lonnet::get_servers($dom);
9140: my @loginvia_attribs = ('serverpath','custompath','exempt');
9141: if (keys(%servers) > 1) {
9142: foreach my $lonhost (keys(%servers)) {
9143: next if ($env{'form.'.$lonhost.'_server'} eq $lonhost);
9144: if (ref($curr_loginvia{$lonhost}) eq 'HASH') {
9145: if ($env{'form.'.$lonhost.'_server'} eq $curr_loginvia{$lonhost}{'server'}) {
9146: $loginhash{login}{loginvia}{$lonhost}{'server'} = $curr_loginvia{$lonhost}{'server'};
9147: } elsif ($curr_loginvia{$lonhost}{'server'} ne '') {
9148: if (defined($servers{$env{'form.'.$lonhost.'_server'}})) {
9149: $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'};
9150: $changes{'loginvia'}{$lonhost} = 1;
9151: } else {
9152: $loginhash{login}{loginvia}{$lonhost}{'server'} = '';
9153: $changes{'loginvia'}{$lonhost} = 1;
9154: }
9155: } else {
9156: if (defined($servers{$env{'form.'.$lonhost.'_server'}})) {
9157: $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'};
9158: $changes{'loginvia'}{$lonhost} = 1;
9159: }
9160: }
9161: if ($loginhash{login}{loginvia}{$lonhost}{'server'} eq '') {
9162: foreach my $item (@loginvia_attribs) {
9163: $loginhash{login}{loginvia}{$lonhost}{$item} = '';
9164: }
9165: } else {
9166: foreach my $item (@loginvia_attribs) {
9167: my $new = $env{'form.'.$lonhost.'_'.$item};
9168: if (($item eq 'serverpath') && ($new eq 'custom')) {
9169: $env{'form.'.$lonhost.'_custompath'} =~ s/\s+//g;
9170: if ($env{'form.'.$lonhost.'_custompath'} eq '') {
9171: $new = '/';
9172: }
9173: }
9174: if (($item eq 'custompath') &&
9175: ($env{'form.'.$lonhost.'_serverpath'} ne 'custom')) {
9176: $new = '';
9177: }
9178: if ($new ne $curr_loginvia{$lonhost}{$item}) {
9179: $changes{'loginvia'}{$lonhost} = 1;
9180: }
9181: if ($item eq 'exempt') {
9182: $new = &check_exempt_addresses($new);
9183: }
9184: $loginhash{login}{loginvia}{$lonhost}{$item} = $new;
9185: }
9186: }
9187: } else {
9188: if (defined($servers{$env{'form.'.$lonhost.'_server'}})) {
9189: $loginhash{login}{loginvia}{$lonhost}{'server'} = $env{'form.'.$lonhost.'_server'};
9190: $changes{'loginvia'}{$lonhost} = 1;
9191: foreach my $item (@loginvia_attribs) {
9192: my $new = $env{'form.'.$lonhost.'_'.$item};
9193: if (($item eq 'serverpath') && ($new eq 'custom')) {
9194: if ($env{'form.'.$lonhost.'_custompath'} eq '') {
9195: $new = '/';
9196: }
9197: }
9198: if (($item eq 'custompath') &&
9199: ($env{'form.'.$lonhost.'_serverpath'} ne 'custom')) {
9200: $new = '';
9201: }
9202: $loginhash{login}{loginvia}{$lonhost}{$item} = $new;
9203: }
9204: }
9205: }
9206: }
9207: }
9208:
9209: my $servadm = $r->dir_config('lonAdmEMail');
9210: my %langchoices = &Apache::lonlocal::texthash(&get_languages_hash());
9211: if (ref($domconfig{'login'}) eq 'HASH') {
9212: if (ref($domconfig{'login'}{'helpurl'}) eq 'HASH') {
9213: foreach my $lang (sort(keys(%{$domconfig{'login'}{'helpurl'}}))) {
9214: if ($lang eq 'nolang') {
9215: push(@currlangs,$lang);
9216: } elsif (defined($langchoices{$lang})) {
9217: push(@currlangs,$lang);
9218: } else {
9219: next;
9220: }
9221: }
9222: }
9223: }
9224: my @delurls = &Apache::loncommon::get_env_multiple('form.loginhelpurl_del');
9225: if (@currlangs > 0) {
9226: foreach my $lang (@currlangs) {
9227: if (grep(/^\Q$lang\E$/,@delurls)) {
9228: $changes{'helpurl'}{$lang} = 1;
9229: } elsif ($env{'form.loginhelpurl_'.$lang.'.filename'}) {
9230: $changes{'helpurl'}{$lang} = 1;
9231: $newfile{$lang} = $env{'form.loginhelpurl_'.$lang.'.filename'};
9232: push(@newlangs,$lang);
9233: } else {
9234: $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};
9235: }
9236: }
9237: }
9238: unless (grep(/^nolang$/,@currlangs)) {
9239: if ($env{'form.loginhelpurl_nolang.filename'}) {
9240: $changes{'helpurl'}{'nolang'} = 1;
9241: $newfile{'nolang'} = $env{'form.loginhelpurl_nolang.filename'};
9242: push(@newlangs,'nolang');
9243: }
9244: }
9245: if ($env{'form.loginhelpurl_add_lang'}) {
9246: if ((defined($langchoices{$env{'form.loginhelpurl_add_lang'}})) &&
9247: ($env{'form.loginhelpurl_add_file.filename'})) {
9248: $newfile{$env{'form.loginhelpurl_add_lang'}} = $env{'form.loginhelpurl_add_file.filename'};
9249: $addedfile = $env{'form.loginhelpurl_add_lang'};
9250: }
9251: }
9252: if ((@newlangs > 0) || ($addedfile)) {
9253: my $error;
9254: my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
9255: if ($configuserok eq 'ok') {
9256: if ($switchserver) {
9257: $error = &mt("Upload of custom help file is not permitted to this server: [_1]",$switchserver);
9258: } elsif ($author_ok eq 'ok') {
9259: my @allnew = @newlangs;
9260: if ($addedfile ne '') {
9261: push(@allnew,$addedfile);
9262: }
9263: foreach my $lang (@allnew) {
9264: my $formelem = 'loginhelpurl_'.$lang;
9265: if ($lang eq $env{'form.loginhelpurl_add_lang'}) {
9266: $formelem = 'loginhelpurl_add_file';
9267: }
9268: (my $result,$newurl{$lang}) = &publishlogo($r,'upload',$formelem,$dom,$confname,
9269: "help/$lang",'','',$newfile{$lang});
9270: if ($result eq 'ok') {
9271: $loginhash{'login'}{'helpurl'}{$lang} = $newurl{$lang};
9272: $changes{'helpurl'}{$lang} = 1;
9273: } else {
9274: my $puberror = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$newfile{$lang},$result);
9275: $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';
9276: if ((grep(/^\Q$lang\E$/,@currlangs)) &&
9277: (!grep(/^\Q$lang\E$/,@delurls))) {
9278: $loginhash{'login'}{'helpurl'}{$lang} = $domconfig{'login'}{'helpurl'}{$lang};
9279: }
9280: }
9281: }
9282: } else {
9283: $error = &mt("Upload of custom log-in help file(s) failed because an author role could not be assigned to a Domain Configuration user ([_1]) in domain: [_2]. Error was: [_3].",$confname,$dom,$author_ok);
9284: }
9285: } else {
9286: $error = &mt("Upload of custom log-in help file(s) failed because a Domain Configuration user ([_1]) could not be created in domain: [_2]. Error was: [_3].",$confname,$dom,$configuserok);
9287: }
9288: if ($error) {
9289: &Apache::lonnet::logthis($error);
9290: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
9291: }
9292: }
9293:
9294: my (%currheadtagurls,%currexempt,@newhosts,%newheadtagurls,%possexempt);
9295: if (ref($domconfig{'login'}) eq 'HASH') {
9296: if (ref($domconfig{'login'}{'headtag'}) eq 'HASH') {
9297: foreach my $lonhost (keys(%{$domconfig{'login'}{'headtag'}})) {
9298: if ($domservers{$lonhost}) {
9299: if (ref($domconfig{'login'}{'headtag'}{$lonhost}) eq 'HASH') {
9300: $currheadtagurls{$lonhost} = $domconfig{'login'}{'headtag'}{$lonhost}{'url'};
9301: $currexempt{$lonhost} = $domconfig{'login'}{'headtag'}{$lonhost}{'exempt'};
9302: }
9303: }
9304: }
9305: }
9306: }
9307: my @delheadtagurls = &Apache::loncommon::get_env_multiple('form.loginheadtag_del');
9308: foreach my $lonhost (sort(keys(%domservers))) {
9309: if (grep(/^\Q$lonhost\E$/,@delheadtagurls)) {
9310: $changes{'headtag'}{$lonhost} = 1;
9311: } else {
9312: if ($env{'form.loginheadtagexempt_'.$lonhost}) {
9313: $possexempt{$lonhost} = &check_exempt_addresses($env{'form.loginheadtagexempt_'.$lonhost});
9314: }
9315: if ($env{'form.loginheadtag_'.$lonhost.'.filename'}) {
9316: push(@newhosts,$lonhost);
9317: } elsif ($currheadtagurls{$lonhost}) {
9318: $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $currheadtagurls{$lonhost};
9319: if ($currexempt{$lonhost}) {
9320: if ((!exists($possexempt{$lonhost})) || ($possexempt{$lonhost} ne $currexempt{$lonhost})) {
9321: $changes{'headtag'}{$lonhost} = 1;
9322: }
9323: } elsif ($possexempt{$lonhost}) {
9324: $changes{'headtag'}{$lonhost} = 1;
9325: }
9326: if ($possexempt{$lonhost}) {
9327: $loginhash{'login'}{'headtag'}{$lonhost}{'exempt'} = $possexempt{$lonhost};
9328: }
9329: }
9330: }
9331: }
9332: if (@newhosts) {
9333: my $error;
9334: my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
9335: if ($configuserok eq 'ok') {
9336: if ($switchserver) {
9337: $error = &mt("Upload of custom markup is not permitted to this server: [_1]",$switchserver);
9338: } elsif ($author_ok eq 'ok') {
9339: foreach my $lonhost (@newhosts) {
9340: my $formelem = 'loginheadtag_'.$lonhost;
9341: (my $result,$newheadtagurls{$lonhost}) = &publishlogo($r,'upload',$formelem,$dom,$confname,
9342: "login/headtag/$lonhost",'','',
9343: $env{'form.loginheadtag_'.$lonhost.'.filename'});
9344: if ($result eq 'ok') {
9345: $loginhash{'login'}{'headtag'}{$lonhost}{'url'} = $newheadtagurls{$lonhost};
9346: $changes{'headtag'}{$lonhost} = 1;
9347: if ($possexempt{$lonhost}) {
9348: $loginhash{'login'}{'headtag'}{$lonhost}{'exempt'} = $possexempt{$lonhost};
9349: }
9350: } else {
9351: my $puberror = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",
9352: $newheadtagurls{$lonhost},$result);
9353: $errors .= '<li><span class="LC_error">'.$puberror.'</span></li>';
9354: if ((grep(/^\Q$lonhost\E$/,keys(%currheadtagurls))) &&
9355: (!grep(/^\Q$lonhost\E$/,@delheadtagurls))) {
9356: $loginhash{'login'}{'headtag'}{$lonhost} = $currheadtagurls{$lonhost};
9357: }
9358: }
9359: }
9360: } else {
9361: $error = &mt("Upload of custom markup file(s) failed because an author role could not be assigned to a Domain Configuration user ([_1]) in domain: [_2]. Error was: [_3].",$confname,$dom,$author_ok);
9362: }
9363: } else {
9364: $error = &mt("Upload of custom markup file(s) failed because a Domain Configuration user ([_1]) could not be created in domain: [_2]. Error was: [_3].",$confname,$dom,$configuserok);
9365: }
9366: if ($error) {
9367: &Apache::lonnet::logthis($error);
9368: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
9369: }
9370: }
9371: &process_captcha('login',\%changes,$loginhash{'login'},$domconfig{'login'});
9372:
9373: my $defaulthelpfile = '/adm/loginproblems.html';
9374: my $defaulttext = &mt('Default in use');
9375:
9376: my $putresult = &Apache::lonnet::put_dom('configuration',\%loginhash,
9377: $dom);
9378: if ($putresult eq 'ok') {
9379: my @toggles = ('coursecatalog','adminmail','helpdesk','newuser');
9380: my %defaultchecked = (
9381: 'coursecatalog' => 'on',
9382: 'helpdesk' => 'on',
9383: 'adminmail' => 'off',
9384: 'newuser' => 'off',
9385: );
9386: if (ref($domconfig{'login'}) eq 'HASH') {
9387: foreach my $item (@toggles) {
9388: if ($defaultchecked{$item} eq 'on') {
9389: if (($domconfig{'login'}{$item} eq '0') &&
9390: ($env{'form.'.$item} eq '1')) {
9391: $changes{$item} = 1;
9392: } elsif (($domconfig{'login'}{$item} eq '' ||
9393: $domconfig{'login'}{$item} eq '1') &&
9394: ($env{'form.'.$item} eq '0')) {
9395: $changes{$item} = 1;
9396: }
9397: } elsif ($defaultchecked{$item} eq 'off') {
9398: if (($domconfig{'login'}{$item} eq '1') &&
9399: ($env{'form.'.$item} eq '0')) {
9400: $changes{$item} = 1;
9401: } elsif (($domconfig{'login'}{$item} eq '' ||
9402: $domconfig{'login'}{$item} eq '0') &&
9403: ($env{'form.'.$item} eq '1')) {
9404: $changes{$item} = 1;
9405: }
9406: }
9407: }
9408: }
9409: if (keys(%changes) > 0 || $colchgtext) {
9410: &Apache::loncommon::devalidate_domconfig_cache($dom);
9411: if (ref($lastactref) eq 'HASH') {
9412: $lastactref->{'domainconfig'} = 1;
9413: }
9414: $resulttext = &mt('Changes made:').'<ul>';
9415: foreach my $item (sort(keys(%changes))) {
9416: if ($item eq 'loginvia') {
9417: if (ref($changes{$item}) eq 'HASH') {
9418: $resulttext .= '<li>'.&mt('Log-in page availability:').'<ul>';
9419: foreach my $lonhost (sort(keys(%{$changes{$item}}))) {
9420: if (defined($servers{$loginhash{login}{loginvia}{$lonhost}{'server'}})) {
9421: if (ref($loginhash{login}{loginvia}{$lonhost}) eq 'HASH') {
9422: my $protocol = $Apache::lonnet::protocol{$env{'form.'.$lonhost.'_server'}};
9423: $protocol = 'http' if ($protocol ne 'https');
9424: my $target = $protocol.'://'.$servers{$env{'form.'.$lonhost.'_server'}};
9425:
9426: if ($loginhash{login}{loginvia}{$lonhost}{'serverpath'} eq 'custom') {
9427: $target .= $loginhash{login}{loginvia}{$lonhost}{'custompath'};
9428: } else {
9429: $target .= $loginhash{login}{loginvia}{$lonhost}{'serverpath'};
9430: }
9431: $resulttext .= '<li>'.&mt('Server: [_1] log-in page redirects to [_2].',$servers{$lonhost},'<a href="'.$target.'">'.$target.'</a>');
9432: if ($loginhash{login}{loginvia}{$lonhost}{'exempt'} ne '') {
9433: $resulttext .= ' '.&mt('No redirection for clients from following IPs:').' '.$loginhash{login}{loginvia}{$lonhost}{'exempt'};
9434: }
9435: $resulttext .= '</li>';
9436: } else {
9437: $resulttext .= '<li>'.&mt('Server: [_1] has standard log-in page.',$lonhost).'</li>';
9438: }
9439: } else {
9440: $resulttext .= '<li>'.&mt('Server: [_1] has standard log-in page.',$servers{$lonhost}).'</li>';
9441: }
9442: }
9443: $resulttext .= '</ul></li>';
9444: }
9445: } elsif ($item eq 'helpurl') {
9446: if (ref($changes{$item}) eq 'HASH') {
9447: foreach my $lang (sort(keys(%{$changes{$item}}))) {
9448: if (grep(/^\Q$lang\E$/,@delurls)) {
9449: my ($chg,$link);
9450: $link = &Apache::loncommon::modal_link($defaulthelpfile,$defaulttext,600,500);
9451: if ($lang eq 'nolang') {
9452: $chg = &mt('custom log-in help file removed for no preferred language; [_1]',$link);
9453: } else {
9454: $chg = &mt('custom log-in help file removed for specific language: [_1]; [_2]',$langchoices{$lang},$link);
9455: }
9456: $resulttext .= '<li>'.$chg.'</li>';
9457: } else {
9458: my $chg;
9459: if ($lang eq 'nolang') {
9460: $chg = &mt('custom log-in help file for no preferred language');
9461: } else {
9462: $chg = &mt('custom log-in help file for specific language: [_1]',$langchoices{$lang});
9463: }
9464: $resulttext .= '<li>'.&Apache::loncommon::modal_link(
9465: $loginhash{'login'}{'helpurl'}{$lang}.
9466: '?inhibitmenu=yes',$chg,600,500).
9467: '</li>';
9468: }
9469: }
9470: }
9471: } elsif ($item eq 'headtag') {
9472: if (ref($changes{$item}) eq 'HASH') {
9473: foreach my $lonhost (sort(keys(%{$changes{$item}}))) {
9474: if (grep(/^\Q$lonhost\E$/,@delheadtagurls)) {
9475: $resulttext .= '<li>'.&mt('custom markup file removed for [_1]',$domservers{$lonhost}).'</li>';
9476: } elsif (ref($loginhash{'login'}{'headtag'}{$lonhost}) eq 'HASH') {
9477: $resulttext .= '<li><a href="'.
9478: "javascript:void(open('$loginhash{'login'}{'headtag'}{$lonhost}{'url'}?inhibitmenu=yes','Custom_HeadTag',
9479: 'menubar=0,toolbar=1,scrollbars=1,width=600,height=500,resizable=yes'))".
9480: '">'.&mt('custom markup').'</a> '.&mt('(for [_1])',$servers{$lonhost}).' ';
9481: if ($possexempt{$lonhost}) {
9482: $resulttext .= &mt('not included for client IP(s): [_1]',$possexempt{$lonhost});
9483: } else {
9484: $resulttext .= &mt('included for any client IP');
9485: }
9486: $resulttext .= '</li>';
9487: }
9488: }
9489: }
9490: } elsif ($item eq 'captcha') {
9491: if (ref($loginhash{'login'}) eq 'HASH') {
9492: my $chgtxt;
9493: if ($loginhash{'login'}{$item} eq 'notused') {
9494: $chgtxt .= &mt('No CAPTCHA validation in use for helpdesk form.');
9495: } else {
9496: my %captchas = &captcha_phrases();
9497: if ($captchas{$loginhash{'login'}{$item}}) {
9498: $chgtxt .= &mt("Validation for helpdesk form set to $captchas{$loginhash{'login'}{$item}}.");
9499: } else {
9500: $chgtxt .= &mt('Validation for helpdesk form set to unknown type.');
9501: }
9502: }
9503: $resulttext .= '<li>'.$chgtxt.'</li>';
9504: }
9505: } elsif ($item eq 'recaptchakeys') {
9506: if (ref($loginhash{'login'}) eq 'HASH') {
9507: my ($privkey,$pubkey);
9508: if (ref($loginhash{'login'}{$item}) eq 'HASH') {
9509: $pubkey = $loginhash{'login'}{$item}{'public'};
9510: $privkey = $loginhash{'login'}{$item}{'private'};
9511: }
9512: my $chgtxt .= &mt('ReCAPTCHA keys changes').'<ul>';
9513: if (!$pubkey) {
9514: $chgtxt .= '<li>'.&mt('Public key deleted').'</li>';
9515: } else {
9516: $chgtxt .= '<li>'.&mt('Public key set to [_1]',$pubkey).'</li>';
9517: }
9518: if (!$privkey) {
9519: $chgtxt .= '<li>'.&mt('Private key deleted').'</li>';
9520: } else {
9521: $chgtxt .= '<li>'.&mt('Private key set to [_1]',$privkey).'</li>';
9522: }
9523: $chgtxt .= '</ul>';
9524: $resulttext .= '<li>'.$chgtxt.'</li>';
9525: }
9526: } elsif ($item eq 'recaptchaversion') {
9527: if (ref($loginhash{'login'}) eq 'HASH') {
9528: if ($loginhash{'login'}{'captcha'} eq 'recaptcha') {
9529: $resulttext .= '<li>'.&mt('ReCAPTCHA for helpdesk form set to version [_1]',$loginhash{'login'}{'recaptchaversion'}).
9530: '</li>';
9531: }
9532: }
9533: } else {
9534: $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>';
9535: }
9536: }
9537: $resulttext .= $colchgtext.'</ul>';
9538: } else {
9539: $resulttext = &mt('No changes made to log-in page settings');
9540: }
9541: } else {
9542: $resulttext = '<span class="LC_error">'.
9543: &mt('An error occurred: [_1]',$putresult).'</span>';
9544: }
9545: if ($errors) {
9546: $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.
9547: $errors.'</ul>';
9548: }
9549: return $resulttext;
9550: }
9551:
9552: sub check_exempt_addresses {
9553: my ($iplist) = @_;
9554: $iplist =~ s/^\s+//;
9555: $iplist =~ s/\s+$//;
9556: my @poss_ips = split(/\s*[,:]\s*/,$iplist);
9557: my (@okips,$new);
9558: foreach my $ip (@poss_ips) {
9559: if ($ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
9560: if (($1 <= 255) && ($2 <= 255) && ($3 <= 255) && ($4 <= 255)) {
9561: push(@okips,$ip);
9562: }
9563: }
9564: }
9565: if (@okips > 0) {
9566: $new = join(',',@okips);
9567: } else {
9568: $new = '';
9569: }
9570: return $new;
9571: }
9572:
9573: sub color_font_choices {
9574: my %choices =
9575: &Apache::lonlocal::texthash (
9576: img => "Header",
9577: bgs => "Background colors",
9578: links => "Link colors",
9579: images => "Images",
9580: font => "Font color",
9581: fontmenu => "Font menu",
9582: pgbg => "Page",
9583: tabbg => "Header",
9584: sidebg => "Border",
9585: link => "Link",
9586: alink => "Active link",
9587: vlink => "Visited link",
9588: );
9589: return %choices;
9590: }
9591:
9592: sub modify_rolecolors {
9593: my ($r,$dom,$confname,$roles,$lastactref,%domconfig) = @_;
9594: my ($resulttext,%rolehash);
9595: $rolehash{'rolecolors'} = {};
9596: if (ref($domconfig{'rolecolors'}) ne 'HASH') {
9597: if ($domconfig{'rolecolors'} eq '') {
9598: $domconfig{'rolecolors'} = {};
9599: }
9600: }
9601: my ($errors,%changes) = &modify_colors($r,$dom,$confname,$roles,
9602: $domconfig{'rolecolors'},$rolehash{'rolecolors'});
9603: my $putresult = &Apache::lonnet::put_dom('configuration',\%rolehash,
9604: $dom);
9605: if ($putresult eq 'ok') {
9606: if (keys(%changes) > 0) {
9607: &Apache::loncommon::devalidate_domconfig_cache($dom);
9608: if (ref($lastactref) eq 'HASH') {
9609: $lastactref->{'domainconfig'} = 1;
9610: }
9611: $resulttext = &display_colorchgs($dom,\%changes,$roles,
9612: $rolehash{'rolecolors'});
9613: } else {
9614: $resulttext = &mt('No changes made to default color schemes');
9615: }
9616: } else {
9617: $resulttext = '<span class="LC_error">'.
9618: &mt('An error occurred: [_1]',$putresult).'</span>';
9619: }
9620: if ($errors) {
9621: $resulttext .= &mt('The following errors occurred: ').'<ul>'.
9622: $errors.'</ul>';
9623: }
9624: return $resulttext;
9625: }
9626:
9627: sub modify_colors {
9628: my ($r,$dom,$confname,$roles,$domconfig,$confhash) = @_;
9629: my (%changes,%choices);
9630: my @bgs;
9631: my @links = ('link','alink','vlink');
9632: my @logintext;
9633: my @images;
9634: my $servadm = $r->dir_config('lonAdmEMail');
9635: my $errors;
9636: my %defaults;
9637: foreach my $role (@{$roles}) {
9638: if ($role eq 'login') {
9639: %choices = &login_choices();
9640: @logintext = ('textcol','bgcol');
9641: } else {
9642: %choices = &color_font_choices();
9643: }
9644: if ($role eq 'login') {
9645: @images = ('img','logo','domlogo','login');
9646: @bgs = ('pgbg','mainbg','sidebg');
9647: } else {
9648: @images = ('img');
9649: @bgs = ('pgbg','tabbg','sidebg');
9650: }
9651: my %defaults = &role_defaults($role,\@bgs,\@links,\@images,\@logintext);
9652: unless ($env{'form.'.$role.'_font'} eq $defaults{'font'}) {
9653: $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'};
9654: }
9655: if ($role eq 'login') {
9656: foreach my $item (@logintext) {
9657: $env{'form.'.$role.'_'.$item} = lc($env{'form.'.$role.'_'.$item});
9658: if ($env{'form.'.$role.'_'.$item} =~ /^\w+/) {
9659: $env{'form.'.$role.'_'.$item} = '#'.$env{'form.'.$role.'_'.$item};
9660: }
9661: unless ($env{'form.'.$role.'_'.$item} eq lc($defaults{'logintext'}{$item})) {
9662: $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};
9663: }
9664: }
9665: } else {
9666: $env{'form.'.$role.'_fontmenu'} = lc($env{'form.'.$role.'_fontmenu'});
9667: if ($env{'form.'.$role.'_fontmenu'} =~ /^\w+/) {
9668: $env{'form.'.$role.'_fontmenu'} = '#'.$env{'form.'.$role.'_fontmenu'};
9669: }
9670: unless($env{'form.'.$role.'_fontmenu'} eq lc($defaults{'fontmenu'})) {
9671: $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'};
9672: }
9673: }
9674: foreach my $item (@bgs) {
9675: $env{'form.'.$role.'_'.$item} = lc($env{'form.'.$role.'_'.$item});
9676: if ($env{'form.'.$role.'_'.$item} =~ /^\w+/) {
9677: $env{'form.'.$role.'_'.$item} = '#'.$env{'form.'.$role.'_'.$item};
9678: }
9679: unless ($env{'form.'.$role.'_'.$item} eq lc($defaults{'bgs'}{$item})) {
9680: $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};
9681: }
9682: }
9683: foreach my $item (@links) {
9684: $env{'form.'.$role.'_'.$item} = lc($env{'form.'.$role.'_'.$item});
9685: if ($env{'form.'.$role.'_'.$item} =~ /^\w+/) {
9686: $env{'form.'.$role.'_'.$item} = '#'.$env{'form.'.$role.'_'.$item};
9687: }
9688: unless ($env{'form.'.$role.'_'.$item} eq lc($defaults{'links'}{$item})) {
9689: $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item};
9690: }
9691: }
9692: my ($configuserok,$author_ok,$switchserver) =
9693: &config_check($dom,$confname,$servadm);
9694: my ($width,$height) = &thumb_dimensions();
9695: if (ref($domconfig->{$role}) ne 'HASH') {
9696: $domconfig->{$role} = {};
9697: }
9698: foreach my $img (@images) {
9699: if (($role eq 'login') && (($img eq 'img') || ($img eq 'logo'))) {
9700: if (defined($env{'form.login_showlogo_'.$img})) {
9701: $confhash->{$role}{'showlogo'}{$img} = 1;
9702: } else {
9703: $confhash->{$role}{'showlogo'}{$img} = 0;
9704: }
9705: }
9706: if ( ! $env{'form.'.$role.'_'.$img.'.filename'}
9707: && !defined($domconfig->{$role}{$img})
9708: && !$env{'form.'.$role.'_del_'.$img}
9709: && $env{'form.'.$role.'_import_'.$img}) {
9710: # import the old configured image from the .tab setting
9711: # if they haven't provided a new one
9712: $domconfig->{$role}{$img} =
9713: $env{'form.'.$role.'_import_'.$img};
9714: }
9715: if ($env{'form.'.$role.'_'.$img.'.filename'} ne '') {
9716: my $error;
9717: if ($configuserok eq 'ok') {
9718: if ($switchserver) {
9719: $error = &mt("Upload of [_1] image for $role page(s) is not permitted to this server: [_2]",$choices{$img},$switchserver);
9720: } else {
9721: if ($author_ok eq 'ok') {
9722: my ($result,$logourl) =
9723: &publishlogo($r,'upload',$role.'_'.$img,
9724: $dom,$confname,$img,$width,$height);
9725: if ($result eq 'ok') {
9726: $confhash->{$role}{$img} = $logourl;
9727: $changes{$role}{'images'}{$img} = 1;
9728: } else {
9729: $error = &mt("Upload of [_1] image for $role page(s) failed because an error occurred publishing the file in RES space. Error was: [_2].",$choices{img},$result);
9730: }
9731: } else {
9732: $error = &mt("Upload of [_1] image for $role page(s) failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$choices{$img},$confname,$dom,$author_ok);
9733: }
9734: }
9735: } else {
9736: $error = &mt("Upload of [_1] image for $role page(s) failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$choices{$img},$confname,$dom,$configuserok);
9737: }
9738: if ($error) {
9739: &Apache::lonnet::logthis($error);
9740: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
9741: }
9742: } elsif ($domconfig->{$role}{$img} ne '') {
9743: if ($domconfig->{$role}{$img} !~ m-^(/res/\Q$dom\E/\Q$confname\E/\Q$img\E)/([^/]+)$-) {
9744: my $error;
9745: if ($configuserok eq 'ok') {
9746: # is confname an author?
9747: if ($switchserver eq '') {
9748: if ($author_ok eq 'ok') {
9749: my ($result,$logourl) =
9750: &publishlogo($r,'copy',$domconfig->{$role}{$img},
9751: $dom,$confname,$img,$width,$height);
9752: if ($result eq 'ok') {
9753: $confhash->{$role}{$img} = $logourl;
9754: $changes{$role}{'images'}{$img} = 1;
9755: }
9756: }
9757: }
9758: }
9759: }
9760: }
9761: }
9762: if (ref($domconfig) eq 'HASH') {
9763: if (ref($domconfig->{$role}) eq 'HASH') {
9764: foreach my $img (@images) {
9765: if ($domconfig->{$role}{$img} ne '') {
9766: if ($env{'form.'.$role.'_del_'.$img}) {
9767: $confhash->{$role}{$img} = '';
9768: $changes{$role}{'images'}{$img} = 1;
9769: } else {
9770: if ($confhash->{$role}{$img} eq '') {
9771: $confhash->{$role}{$img} = $domconfig->{$role}{$img};
9772: }
9773: }
9774: } else {
9775: if ($env{'form.'.$role.'_del_'.$img}) {
9776: $confhash->{$role}{$img} = '';
9777: $changes{$role}{'images'}{$img} = 1;
9778: }
9779: }
9780: if (($role eq 'login') && (($img eq 'logo') || ($img eq 'img'))) {
9781: if (ref($domconfig->{'login'}{'showlogo'}) eq 'HASH') {
9782: if ($confhash->{$role}{'showlogo'}{$img} ne
9783: $domconfig->{$role}{'showlogo'}{$img}) {
9784: $changes{$role}{'showlogo'}{$img} = 1;
9785: }
9786: } else {
9787: if ($confhash->{$role}{'showlogo'}{$img} == 0) {
9788: $changes{$role}{'showlogo'}{$img} = 1;
9789: }
9790: }
9791: }
9792: }
9793: if ($domconfig->{$role}{'font'} ne '') {
9794: if ($confhash->{$role}{'font'} ne $domconfig->{$role}{'font'}) {
9795: $changes{$role}{'font'} = 1;
9796: }
9797: } else {
9798: if ($confhash->{$role}{'font'}) {
9799: $changes{$role}{'font'} = 1;
9800: }
9801: }
9802: if ($role ne 'login') {
9803: if ($domconfig->{$role}{'fontmenu'} ne '') {
9804: if ($confhash->{$role}{'fontmenu'} ne $domconfig->{$role}{'fontmenu'}) {
9805: $changes{$role}{'fontmenu'} = 1;
9806: }
9807: } else {
9808: if ($confhash->{$role}{'fontmenu'}) {
9809: $changes{$role}{'fontmenu'} = 1;
9810: }
9811: }
9812: }
9813: foreach my $item (@bgs) {
9814: if ($domconfig->{$role}{$item} ne '') {
9815: if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) {
9816: $changes{$role}{'bgs'}{$item} = 1;
9817: }
9818: } else {
9819: if ($confhash->{$role}{$item}) {
9820: $changes{$role}{'bgs'}{$item} = 1;
9821: }
9822: }
9823: }
9824: foreach my $item (@links) {
9825: if ($domconfig->{$role}{$item} ne '') {
9826: if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) {
9827: $changes{$role}{'links'}{$item} = 1;
9828: }
9829: } else {
9830: if ($confhash->{$role}{$item}) {
9831: $changes{$role}{'links'}{$item} = 1;
9832: }
9833: }
9834: }
9835: foreach my $item (@logintext) {
9836: if ($domconfig->{$role}{$item} ne '') {
9837: if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) {
9838: $changes{$role}{'logintext'}{$item} = 1;
9839: }
9840: } else {
9841: if ($confhash->{$role}{$item}) {
9842: $changes{$role}{'logintext'}{$item} = 1;
9843: }
9844: }
9845: }
9846: } else {
9847: &default_change_checker($role,\@images,\@links,\@bgs,
9848: \@logintext,$confhash,\%changes);
9849: }
9850: } else {
9851: &default_change_checker($role,\@images,\@links,\@bgs,
9852: \@logintext,$confhash,\%changes);
9853: }
9854: }
9855: return ($errors,%changes);
9856: }
9857:
9858: sub config_check {
9859: my ($dom,$confname,$servadm) = @_;
9860: my ($configuserok,$author_ok,$switchserver,%currroles);
9861: my $uhome = &Apache::lonnet::homeserver($confname,$dom,1);
9862: ($configuserok,%currroles) = &check_configuser($uhome,$dom,
9863: $confname,$servadm);
9864: if ($configuserok eq 'ok') {
9865: $switchserver = &check_switchserver($dom,$confname);
9866: if ($switchserver eq '') {
9867: $author_ok = &check_authorstatus($dom,$confname,%currroles);
9868: }
9869: }
9870: return ($configuserok,$author_ok,$switchserver);
9871: }
9872:
9873: sub default_change_checker {
9874: my ($role,$images,$links,$bgs,$logintext,$confhash,$changes) = @_;
9875: foreach my $item (@{$links}) {
9876: if ($confhash->{$role}{$item}) {
9877: $changes->{$role}{'links'}{$item} = 1;
9878: }
9879: }
9880: foreach my $item (@{$bgs}) {
9881: if ($confhash->{$role}{$item}) {
9882: $changes->{$role}{'bgs'}{$item} = 1;
9883: }
9884: }
9885: foreach my $item (@{$logintext}) {
9886: if ($confhash->{$role}{$item}) {
9887: $changes->{$role}{'logintext'}{$item} = 1;
9888: }
9889: }
9890: foreach my $img (@{$images}) {
9891: if ($env{'form.'.$role.'_del_'.$img}) {
9892: $confhash->{$role}{$img} = '';
9893: $changes->{$role}{'images'}{$img} = 1;
9894: }
9895: if ($role eq 'login') {
9896: if ($confhash->{$role}{'showlogo'}{$img} == 0) {
9897: $changes->{$role}{'showlogo'}{$img} = 1;
9898: }
9899: }
9900: }
9901: if ($confhash->{$role}{'font'}) {
9902: $changes->{$role}{'font'} = 1;
9903: }
9904: }
9905:
9906: sub display_colorchgs {
9907: my ($dom,$changes,$roles,$confhash) = @_;
9908: my (%choices,$resulttext);
9909: if (!grep(/^login$/,@{$roles})) {
9910: $resulttext = &mt('Changes made:').'<br />';
9911: }
9912: foreach my $role (@{$roles}) {
9913: if ($role eq 'login') {
9914: %choices = &login_choices();
9915: } else {
9916: %choices = &color_font_choices();
9917: }
9918: if (ref($changes->{$role}) eq 'HASH') {
9919: if ($role ne 'login') {
9920: $resulttext .= '<h4>'.&mt($role).'</h4>';
9921: }
9922: foreach my $key (sort(keys(%{$changes->{$role}}))) {
9923: if ($role ne 'login') {
9924: $resulttext .= '<ul>';
9925: }
9926: if (ref($changes->{$role}{$key}) eq 'HASH') {
9927: if ($role ne 'login') {
9928: $resulttext .= '<li>'.&mt($choices{$key}).':<ul>';
9929: }
9930: foreach my $item (sort(keys(%{$changes->{$role}{$key}}))) {
9931: if (($role eq 'login') && ($key eq 'showlogo')) {
9932: if ($confhash->{$role}{$key}{$item}) {
9933: $resulttext .= '<li>'.&mt("$choices{$item} set to be displayed").'</li>';
9934: } else {
9935: $resulttext .= '<li>'.&mt("$choices{$item} set to not be displayed").'</li>';
9936: }
9937: } elsif ($confhash->{$role}{$item} eq '') {
9938: $resulttext .= '<li>'.&mt("$choices{$item} set to default").'</li>';
9939: } else {
9940: my $newitem = $confhash->{$role}{$item};
9941: if ($key eq 'images') {
9942: $newitem = '<img src="'.$confhash->{$role}{$item}.'" alt="'.$choices{$item}.'" style="vertical-align: bottom" />';
9943: }
9944: $resulttext .= '<li>'.&mt("$choices{$item} set to [_1]",$newitem).'</li>';
9945: }
9946: }
9947: if ($role ne 'login') {
9948: $resulttext .= '</ul></li>';
9949: }
9950: } else {
9951: if ($confhash->{$role}{$key} eq '') {
9952: $resulttext .= '<li>'.&mt("$choices{$key} set to default").'</li>';
9953: } else {
9954: $resulttext .= '<li>'.&mt("$choices{$key} set to [_1]",$confhash->{$role}{$key}).'</li>';
9955: }
9956: }
9957: if ($role ne 'login') {
9958: $resulttext .= '</ul>';
9959: }
9960: }
9961: }
9962: }
9963: return $resulttext;
9964: }
9965:
9966: sub thumb_dimensions {
9967: return ('200','50');
9968: }
9969:
9970: sub check_dimensions {
9971: my ($inputfile) = @_;
9972: my ($fullwidth,$fullheight);
9973: if ($inputfile =~ m|^[/\w.\-]+$|) {
9974: if (open(PIPE,"identify $inputfile 2>&1 |")) {
9975: my $imageinfo = <PIPE>;
9976: if (!close(PIPE)) {
9977: &Apache::lonnet::logthis("Failed to close PIPE opened to retrieve image information for $inputfile");
9978: }
9979: chomp($imageinfo);
9980: my ($fullsize) =
9981: ($imageinfo =~ /^\Q$inputfile\E\s+\w+\s+(\d+x\d+)/);
9982: if ($fullsize) {
9983: ($fullwidth,$fullheight) = split(/x/,$fullsize);
9984: }
9985: }
9986: }
9987: return ($fullwidth,$fullheight);
9988: }
9989:
9990: sub check_configuser {
9991: my ($uhome,$dom,$confname,$servadm) = @_;
9992: my ($configuserok,%currroles);
9993: if ($uhome eq 'no_host') {
9994: srand( time() ^ ($$ + ($$ << 15)) ); # Seed rand.
9995: my $configpass = &LONCAPA::Enrollment::create_password();
9996: $configuserok =
9997: &Apache::lonnet::modifyuser($dom,$confname,'','internal',
9998: $configpass,'','','','','',undef,$servadm);
9999: } else {
10000: $configuserok = 'ok';
10001: %currroles =
10002: &Apache::lonnet::get_my_roles($confname,$dom,'userroles');
10003: }
10004: return ($configuserok,%currroles);
10005: }
10006:
10007: sub check_authorstatus {
10008: my ($dom,$confname,%currroles) = @_;
10009: my $author_ok;
10010: if (!$currroles{':'.$dom.':au'}) {
10011: my $start = time;
10012: my $end = 0;
10013: $author_ok =
10014: &Apache::lonnet::assignrole($dom,$confname,'/'.$dom.'/',
10015: 'au',$end,$start,'','','domconfig');
10016: } else {
10017: $author_ok = 'ok';
10018: }
10019: return $author_ok;
10020: }
10021:
10022: sub publishlogo {
10023: my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_;
10024: my ($output,$fname,$logourl,$madethumb);
10025: if ($action eq 'upload') {
10026: $fname=$env{'form.'.$formname.'.filename'};
10027: chop($env{'form.'.$formname});
10028: } else {
10029: ($fname) = ($formname =~ /([^\/]+)$/);
10030: }
10031: if ($savefileas ne '') {
10032: $fname = $savefileas;
10033: }
10034: $fname=&Apache::lonnet::clean_filename($fname);
10035: # See if there is anything left
10036: unless ($fname) { return ('error: no uploaded file'); }
10037: $fname="$subdir/$fname";
10038: my $docroot=$r->dir_config('lonDocRoot');
10039: my $filepath="$docroot/priv";
10040: my $relpath = "$dom/$confname";
10041: my ($fnamepath,$file,$fetchthumb);
10042: $file=$fname;
10043: if ($fname=~m|/|) {
10044: ($fnamepath,$file) = ($fname =~ m|^(.*)/([^/]+)$|);
10045: }
10046: my @parts=split(/\//,"$filepath/$relpath/$fnamepath");
10047: my $count;
10048: for ($count=5;$count<=$#parts;$count++) {
10049: $filepath.="/$parts[$count]";
10050: if ((-e $filepath)!=1) {
10051: mkdir($filepath,02770);
10052: }
10053: }
10054: # Check for bad extension and disallow upload
10055: if ($file=~/\.(\w+)$/ &&
10056: (&Apache::loncommon::fileembstyle($1) eq 'hdn')) {
10057: $output =
10058: &mt('Invalid file extension ([_1]) - reserved for internal use.',$1);
10059: } elsif ($file=~/\.(\w+)$/ &&
10060: !defined(&Apache::loncommon::fileembstyle($1))) {
10061: $output = &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1);
10062: } elsif ($file=~/\.(\d+)\.(\w+)$/) {
10063: $output = &mt('Filename not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2);
10064: } elsif (-d "$filepath/$file") {
10065: $output = &mt('Filename is a directory name - rename the file and re-upload');
10066: } else {
10067: my $source = $filepath.'/'.$file;
10068: my $logfile;
10069: if (!open($logfile,">>",$source.'.log')) {
10070: return (&mt('No write permission to Authoring Space'));
10071: }
10072: print $logfile
10073: "\n================= Publish ".localtime()." ================\n".
10074: $env{'user.name'}.':'.$env{'user.domain'}."\n";
10075: # Save the file
10076: if (!open(FH,">",$source)) {
10077: &Apache::lonnet::logthis('Failed to create '.$source);
10078: return (&mt('Failed to create file'));
10079: }
10080: if ($action eq 'upload') {
10081: if (!print FH ($env{'form.'.$formname})) {
10082: &Apache::lonnet::logthis('Failed to write to '.$source);
10083: return (&mt('Failed to write file'));
10084: }
10085: } else {
10086: my $original = &Apache::lonnet::filelocation('',$formname);
10087: if(!copy($original,$source)) {
10088: &Apache::lonnet::logthis('Failed to copy '.$original.' to '.$source);
10089: return (&mt('Failed to write file'));
10090: }
10091: }
10092: close(FH);
10093: chmod(0660, $source); # Permissions to rw-rw---.
10094:
10095: my $targetdir=$docroot.'/res/'.$dom.'/'.$confname .'/'.$fnamepath;
10096: my $copyfile=$targetdir.'/'.$file;
10097:
10098: my @parts=split(/\//,$targetdir);
10099: my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]";
10100: for (my $count=5;$count<=$#parts;$count++) {
10101: $path.="/$parts[$count]";
10102: if (!-e $path) {
10103: print $logfile "\nCreating directory ".$path;
10104: mkdir($path,02770);
10105: }
10106: }
10107: my $versionresult;
10108: if (-e $copyfile) {
10109: $versionresult = &logo_versioning($targetdir,$file,$logfile);
10110: } else {
10111: $versionresult = 'ok';
10112: }
10113: if ($versionresult eq 'ok') {
10114: if (copy($source,$copyfile)) {
10115: print $logfile "\nCopied original source to ".$copyfile."\n";
10116: $output = 'ok';
10117: $logourl = '/res/'.$dom.'/'.$confname.'/'.$fname;
10118: push(@{$modified_urls},[$copyfile,$source]);
10119: my $metaoutput =
10120: &write_metadata($dom,$confname,$formname,$targetdir,$file,$logfile);
10121: unless ($registered_cleanup) {
10122: my $handlers = $r->get_handlers('PerlCleanupHandler');
10123: $r->set_handlers('PerlCleanupHandler' => [\¬ifysubscribed,@{$handlers}]);
10124: $registered_cleanup=1;
10125: }
10126: } else {
10127: print $logfile "\nUnable to write ".$copyfile.':'.$!."\n";
10128: $output = &mt('Failed to copy file to RES space').", $!";
10129: }
10130: if (($thumbwidth =~ /^\d+$/) && ($thumbheight =~ /^\d+$/)) {
10131: my $inputfile = $filepath.'/'.$file;
10132: my $outfile = $filepath.'/'.'tn-'.$file;
10133: my ($fullwidth,$fullheight) = &check_dimensions($inputfile);
10134: if ($fullwidth ne '' && $fullheight ne '') {
10135: if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) {
10136: my $thumbsize = $thumbwidth.'x'.$thumbheight;
10137: my @args = ('convert','-sample',$thumbsize,$inputfile,$outfile);
10138: system({$args[0]} @args);
10139: chmod(0660, $filepath.'/tn-'.$file);
10140: if (-e $outfile) {
10141: my $copyfile=$targetdir.'/tn-'.$file;
10142: if (copy($outfile,$copyfile)) {
10143: print $logfile "\nCopied source to ".$copyfile."\n";
10144: my $thumb_metaoutput =
10145: &write_metadata($dom,$confname,$formname,
10146: $targetdir,'tn-'.$file,$logfile);
10147: push(@{$modified_urls},[$copyfile,$outfile]);
10148: unless ($registered_cleanup) {
10149: my $handlers = $r->get_handlers('PerlCleanupHandler');
10150: $r->set_handlers('PerlCleanupHandler' => [\¬ifysubscribed,@{$handlers}]);
10151: $registered_cleanup=1;
10152: }
10153: $madethumb = 1;
10154: } else {
10155: print $logfile "\nUnable to write ".$copyfile.
10156: ':'.$!."\n";
10157: }
10158: }
10159: }
10160: }
10161: }
10162: } else {
10163: $output = $versionresult;
10164: }
10165: }
10166: return ($output,$logourl,$madethumb);
10167: }
10168:
10169: sub logo_versioning {
10170: my ($targetdir,$file,$logfile) = @_;
10171: my $target = $targetdir.'/'.$file;
10172: my ($maxversion,$fn,$extn,$output);
10173: $maxversion = 0;
10174: if ($file =~ /^(.+)\.(\w+)$/) {
10175: $fn=$1;
10176: $extn=$2;
10177: }
10178: opendir(DIR,$targetdir);
10179: while (my $filename=readdir(DIR)) {
10180: if ($filename=~/\Q$fn\E\.(\d+)\.\Q$extn\E$/) {
10181: $maxversion=($1>$maxversion)?$1:$maxversion;
10182: }
10183: }
10184: $maxversion++;
10185: print $logfile "\nCreating old version ".$maxversion."\n";
10186: my $copyfile=$targetdir.'/'.$fn.'.'.$maxversion.'.'.$extn;
10187: if (copy($target,$copyfile)) {
10188: print $logfile "Copied old target to ".$copyfile."\n";
10189: $copyfile=$copyfile.'.meta';
10190: if (copy($target.'.meta',$copyfile)) {
10191: print $logfile "Copied old target metadata to ".$copyfile."\n";
10192: $output = 'ok';
10193: } else {
10194: print $logfile "Unable to write metadata ".$copyfile.':'.$!."\n";
10195: $output = &mt('Failed to copy old meta').", $!, ";
10196: }
10197: } else {
10198: print $logfile "Unable to write ".$copyfile.':'.$!."\n";
10199: $output = &mt('Failed to copy old target').", $!, ";
10200: }
10201: return $output;
10202: }
10203:
10204: sub write_metadata {
10205: my ($dom,$confname,$formname,$targetdir,$file,$logfile) = @_;
10206: my (%metadatafields,%metadatakeys,$output);
10207: $metadatafields{'title'}=$formname;
10208: $metadatafields{'creationdate'}=time;
10209: $metadatafields{'lastrevisiondate'}=time;
10210: $metadatafields{'copyright'}='public';
10211: $metadatafields{'modifyinguser'}=$env{'user.name'}.':'.
10212: $env{'user.domain'};
10213: $metadatafields{'authorspace'}=$confname.':'.$dom;
10214: $metadatafields{'domain'}=$dom;
10215: {
10216: print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file;
10217: my $mfh;
10218: if (open($mfh,">",$targetdir.'/'.$file.'.meta')) {
10219: foreach (sort(keys(%metadatafields))) {
10220: unless ($_=~/\./) {
10221: my $unikey=$_;
10222: $unikey=~/^([A-Za-z]+)/;
10223: my $tag=$1;
10224: $tag=~tr/A-Z/a-z/;
10225: print $mfh "\n\<$tag";
10226: foreach (split(/\,/,$metadatakeys{$unikey})) {
10227: my $value=$metadatafields{$unikey.'.'.$_};
10228: $value=~s/\"/\'\'/g;
10229: print $mfh ' '.$_.'="'.$value.'"';
10230: }
10231: print $mfh '>'.
10232: &HTML::Entities::encode($metadatafields{$unikey},'<>&"')
10233: .'</'.$tag.'>';
10234: }
10235: }
10236: $output = 'ok';
10237: print $logfile "\nWrote metadata";
10238: close($mfh);
10239: } else {
10240: print $logfile "\nFailed to open metadata file";
10241: $output = &mt('Could not write metadata');
10242: }
10243: }
10244: return $output;
10245: }
10246:
10247: sub notifysubscribed {
10248: foreach my $targetsource (@{$modified_urls}){
10249: next unless (ref($targetsource) eq 'ARRAY');
10250: my ($target,$source)=@{$targetsource};
10251: if ($source ne '') {
10252: if (open(my $logfh,">>",$source.'.log')) {
10253: print $logfh "\nCleanup phase: Notifications\n";
10254: my @subscribed=&subscribed_hosts($target);
10255: foreach my $subhost (@subscribed) {
10256: print $logfh "\nNotifying host ".$subhost.':';
10257: my $reply=&Apache::lonnet::critical('update:'.$target,$subhost);
10258: print $logfh $reply;
10259: }
10260: my @subscribedmeta=&subscribed_hosts("$target.meta");
10261: foreach my $subhost (@subscribedmeta) {
10262: print $logfh "\nNotifying host for metadata only ".$subhost.':';
10263: my $reply=&Apache::lonnet::critical('update:'.$target.'.meta',
10264: $subhost);
10265: print $logfh $reply;
10266: }
10267: print $logfh "\n============ Done ============\n";
10268: close($logfh);
10269: }
10270: }
10271: }
10272: return OK;
10273: }
10274:
10275: sub subscribed_hosts {
10276: my ($target) = @_;
10277: my @subscribed;
10278: if (open(my $fh,"<","$target.subscription")) {
10279: while (my $subline=<$fh>) {
10280: if ($subline =~ /^($match_lonid):/) {
10281: my $host = $1;
10282: if ($host ne $Apache::lonnet::perlvar{'lonHostID'}) {
10283: unless (grep(/^\Q$host\E$/,@subscribed)) {
10284: push(@subscribed,$host);
10285: }
10286: }
10287: }
10288: }
10289: }
10290: return @subscribed;
10291: }
10292:
10293: sub check_switchserver {
10294: my ($dom,$confname) = @_;
10295: my ($allowed,$switchserver);
10296: my $home = &Apache::lonnet::homeserver($confname,$dom);
10297: if ($home eq 'no_host') {
10298: $home = &Apache::lonnet::domain($dom,'primary');
10299: }
10300: my @ids=&Apache::lonnet::current_machine_ids();
10301: foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } }
10302: if (!$allowed) {
10303: $switchserver='<a href="/adm/switchserver?otherserver='.$home.'&role=dc./'.$dom.'/&destinationurl=/adm/domainprefs">'.&mt('Switch Server').'</a>';
10304: }
10305: return $switchserver;
10306: }
10307:
10308: sub modify_quotas {
10309: my ($r,$dom,$action,$lastactref,%domconfig) = @_;
10310: my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash,
10311: %limithash,$toolregexp,%conditions,$resulttext,%changes,$confname,$configuserok,
10312: $author_ok,$switchserver,$errors,$validationitemsref,$validationnamesref,
10313: $validationfieldsref);
10314: if ($action eq 'quotas') {
10315: $context = 'tools';
10316: } else {
10317: $context = $action;
10318: }
10319: if ($context eq 'requestcourses') {
10320: @usertools = ('official','unofficial','community','textbook','placement','lti');
10321: @options =('norequest','approval','validate','autolimit');
10322: %validations = &Apache::lonnet::auto_courserequest_checks($dom);
10323: %titles = &courserequest_titles();
10324: $toolregexp = join('|',@usertools);
10325: %conditions = &courserequest_conditions();
10326: $confname = $dom.'-domainconfig';
10327: my $servadm = $r->dir_config('lonAdmEMail');
10328: ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
10329: ($validationitemsref,$validationnamesref,$validationfieldsref) =
10330: &Apache::loncoursequeueadmin::requestcourses_validation_types();
10331: } elsif ($context eq 'requestauthor') {
10332: @usertools = ('author');
10333: %titles = &authorrequest_titles();
10334: } else {
10335: @usertools = ('aboutme','blog','webdav','portfolio');
10336: %titles = &tool_titles();
10337: }
10338: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
10339: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
10340: foreach my $key (keys(%env)) {
10341: if ($context eq 'requestcourses') {
10342: if ($key =~ /^form\.crsreq_($toolregexp)_(.+)$/) {
10343: my $item = $1;
10344: my $type = $2;
10345: if ($type =~ /^limit_(.+)/) {
10346: $limithash{$item}{$1} = $env{$key};
10347: } else {
10348: $confhash{$item}{$type} = $env{$key};
10349: }
10350: }
10351: } elsif ($context eq 'requestauthor') {
10352: if ($key =~ /^\Qform.authorreq_\E(.+)$/) {
10353: $confhash{$1} = $env{$key};
10354: }
10355: } else {
10356: if ($key =~ /^form\.quota_(.+)$/) {
10357: $confhash{'defaultquota'}{$1} = $env{$key};
10358: } elsif ($key =~ /^form\.authorquota_(.+)$/) {
10359: $confhash{'authorquota'}{$1} = $env{$key};
10360: } elsif ($key =~ /^form\.\Q$context\E_(.+)$/) {
10361: @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key);
10362: }
10363: }
10364: }
10365: if (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
10366: my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval');
10367: @approvalnotify = sort(@approvalnotify);
10368: $confhash{'notify'}{'approval'} = join(',',@approvalnotify);
10369: my @crstypes = ('official','unofficial','community','textbook','placement','lti');
10370: my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode');
10371: foreach my $type (@hasuniquecode) {
10372: if (grep(/^\Q$type\E$/,@crstypes)) {
10373: $confhash{'uniquecode'}{$type} = 1;
10374: }
10375: }
10376: my (%newbook,%allpos);
10377: if ($context eq 'requestcourses') {
10378: foreach my $type ('textbooks','templates') {
10379: @{$allpos{$type}} = ();
10380: my $invalid;
10381: if ($type eq 'textbooks') {
10382: $invalid = &mt('Invalid LON-CAPA course for textbook');
10383: } else {
10384: $invalid = &mt('Invalid LON-CAPA course for template');
10385: }
10386: if ($env{'form.'.$type.'_addbook'}) {
10387: if (($env{'form.'.$type.'_addbook_cnum'} =~ /^$match_courseid$/) &&
10388: ($env{'form.'.$type.'_addbook_cdom'} =~ /^$match_domain$/)) {
10389: if (&Apache::lonnet::homeserver($env{'form.'.$type.'_addbook_cnum'},
10390: $env{'form.'.$type.'_addbook_cdom'}) eq 'no_host') {
10391: $errors .= '<li><span class="LC_error">'.$invalid.'</span></li>';
10392: } else {
10393: $newbook{$type} = $env{'form.'.$type.'_addbook_cdom'}.'_'.$env{'form.'.$type.'_addbook_cnum'};
10394: my $position = $env{'form.'.$type.'_addbook_pos'};
10395: $position =~ s/\D+//g;
10396: if ($position ne '') {
10397: $allpos{$type}[$position] = $newbook{$type};
10398: }
10399: }
10400: } else {
10401: $errors .= '<li><span class="LC_error">'.$invalid.'</span></li>';
10402: }
10403: }
10404: }
10405: }
10406: if (ref($domconfig{$action}) eq 'HASH') {
10407: if (ref($domconfig{$action}{'notify'}) eq 'HASH') {
10408: if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) {
10409: $changes{'notify'}{'approval'} = 1;
10410: }
10411: } else {
10412: if ($confhash{'notify'}{'approval'}) {
10413: $changes{'notify'}{'approval'} = 1;
10414: }
10415: }
10416: if (ref($domconfig{$action}{'uniquecode'}) eq 'HASH') {
10417: if (ref($confhash{'uniquecode'}) eq 'HASH') {
10418: foreach my $crstype (keys(%{$domconfig{$action}{'uniquecode'}})) {
10419: unless ($confhash{'uniquecode'}{$crstype}) {
10420: $changes{'uniquecode'} = 1;
10421: }
10422: }
10423: unless ($changes{'uniquecode'}) {
10424: foreach my $crstype (keys(%{$confhash{'uniquecode'}})) {
10425: unless ($domconfig{$action}{'uniquecode'}{$crstype}) {
10426: $changes{'uniquecode'} = 1;
10427: }
10428: }
10429: }
10430: } else {
10431: $changes{'uniquecode'} = 1;
10432: }
10433: } elsif (ref($confhash{'uniquecode'}) eq 'HASH') {
10434: $changes{'uniquecode'} = 1;
10435: }
10436: if ($context eq 'requestcourses') {
10437: foreach my $type ('textbooks','templates') {
10438: if (ref($domconfig{$action}{$type}) eq 'HASH') {
10439: my %deletions;
10440: my @todelete = &Apache::loncommon::get_env_multiple('form.'.$type.'_del');
10441: if (@todelete) {
10442: map { $deletions{$_} = 1; } @todelete;
10443: }
10444: my %imgdeletions;
10445: my @todeleteimages = &Apache::loncommon::get_env_multiple('form.'.$type.'_image_del');
10446: if (@todeleteimages) {
10447: map { $imgdeletions{$_} = 1; } @todeleteimages;
10448: }
10449: my $maxnum = $env{'form.'.$type.'_maxnum'};
10450: for (my $i=0; $i<=$maxnum; $i++) {
10451: my $itemid = $env{'form.'.$type.'_id_'.$i};
10452: my ($key) = ($itemid =~ /^\Q$type\E_(\w+)$/);
10453: if (ref($domconfig{$action}{$type}{$key}) eq 'HASH') {
10454: if ($deletions{$key}) {
10455: if ($domconfig{$action}{$type}{$key}{'image'}) {
10456: #FIXME need to obsolete item in RES space
10457: }
10458: next;
10459: } else {
10460: my $newpos = $env{'form.'.$itemid};
10461: $newpos =~ s/\D+//g;
10462: foreach my $item ('subject','title','publisher','author') {
10463: next if ((($item eq 'author') || ($item eq 'publisher')) &&
10464: ($type eq 'templates'));
10465: $confhash{$type}{$key}{$item} = $env{'form.'.$type.'_'.$item.'_'.$i};
10466: if ($domconfig{$action}{$type}{$key}{$item} ne $confhash{$type}{$key}{$item}) {
10467: $changes{$type}{$key} = 1;
10468: }
10469: }
10470: $allpos{$type}[$newpos] = $key;
10471: }
10472: if ($imgdeletions{$key}) {
10473: $changes{$type}{$key} = 1;
10474: #FIXME need to obsolete item in RES space
10475: } elsif ($env{'form.'.$type.'_image_'.$i.'.filename'}) {
10476: my ($cdom,$cnum) = split(/_/,$key);
10477: if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
10478: $errors .= '<li><span class="LC_error">'.&mt('Image not saved: could not find textbook course').'</li>';
10479: } else {
10480: my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i,
10481: $cdom,$cnum,$type,$configuserok,
10482: $switchserver,$author_ok);
10483: if ($imgurl) {
10484: $confhash{$type}{$key}{'image'} = $imgurl;
10485: $changes{$type}{$key} = 1;
10486: }
10487: if ($error) {
10488: &Apache::lonnet::logthis($error);
10489: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
10490: }
10491: }
10492: } elsif ($domconfig{$action}{$type}{$key}{'image'}) {
10493: $confhash{$type}{$key}{'image'} =
10494: $domconfig{$action}{$type}{$key}{'image'};
10495: }
10496: }
10497: }
10498: }
10499: }
10500: }
10501: } else {
10502: if ($confhash{'notify'}{'approval'}) {
10503: $changes{'notify'}{'approval'} = 1;
10504: }
10505: if (ref($confhash{'uniquecode'} eq 'HASH')) {
10506: $changes{'uniquecode'} = 1;
10507: }
10508: }
10509: if ($context eq 'requestcourses') {
10510: foreach my $type ('textbooks','templates') {
10511: if ($newbook{$type}) {
10512: $changes{$type}{$newbook{$type}} = 1;
10513: foreach my $item ('subject','title','publisher','author') {
10514: next if ((($item eq 'author') || ($item eq 'publisher')) &&
10515: ($type eq 'template'));
10516: $env{'form.'.$type.'_addbook_'.$item} =~ s/(`)/'/g;
10517: if ($env{'form.'.$type.'_addbook_'.$item}) {
10518: $confhash{$type}{$newbook{$type}}{$item} = $env{'form.'.$type.'_addbook_'.$item};
10519: }
10520: }
10521: if ($type eq 'textbooks') {
10522: if ($env{'form.'.$type.'_addbook_image.filename'} ne '') {
10523: my ($cdom,$cnum) = split(/_/,$newbook{$type});
10524: if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') {
10525: $errors .= '<li><span class="LC_error">'.&mt('Image not saved: could not find textbook course').'</li>';
10526: } else {
10527: my ($imageurl,$error) =
10528: &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type,
10529: $configuserok,$switchserver,$author_ok);
10530: if ($imageurl) {
10531: $confhash{$type}{$newbook{$type}}{'image'} = $imageurl;
10532: }
10533: if ($error) {
10534: &Apache::lonnet::logthis($error);
10535: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
10536: }
10537: }
10538: }
10539: }
10540: }
10541: if (@{$allpos{$type}} > 0) {
10542: my $idx = 0;
10543: foreach my $item (@{$allpos{$type}}) {
10544: if ($item ne '') {
10545: $confhash{$type}{$item}{'order'} = $idx;
10546: if (ref($domconfig{$action}) eq 'HASH') {
10547: if (ref($domconfig{$action}{$type}) eq 'HASH') {
10548: if (ref($domconfig{$action}{$type}{$item}) eq 'HASH') {
10549: if ($domconfig{$action}{$type}{$item}{'order'} ne $idx) {
10550: $changes{$type}{$item} = 1;
10551: }
10552: }
10553: }
10554: }
10555: $idx ++;
10556: }
10557: }
10558: }
10559: }
10560: if (ref($validationitemsref) eq 'ARRAY') {
10561: foreach my $item (@{$validationitemsref}) {
10562: if ($item eq 'fields') {
10563: my @changed;
10564: @{$confhash{'validation'}{$item}} = &Apache::loncommon::get_env_multiple('form.requestcourses_validation_'.$item);
10565: if (@{$confhash{'validation'}{$item}} > 0) {
10566: @{$confhash{'validation'}{$item}} = sort(@{$confhash{'validation'}{$item}});
10567: }
10568: if (ref($domconfig{'requestcourses'}) eq 'HASH') {
10569: if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
10570: if (ref($domconfig{'requestcourses'}{'validation'}{$item}) eq 'ARRAY') {
10571: @changed = &Apache::loncommon::compare_arrays($confhash{'validation'}{$item},
10572: $domconfig{'requestcourses'}{'validation'}{$item});
10573: } else {
10574: @changed = @{$confhash{'validation'}{$item}};
10575: }
10576: } else {
10577: @changed = @{$confhash{'validation'}{$item}};
10578: }
10579: } else {
10580: @changed = @{$confhash{'validation'}{$item}};
10581: }
10582: if (@changed) {
10583: if ($confhash{'validation'}{$item}) {
10584: $changes{'validation'}{$item} = join(', ',@{$confhash{'validation'}{$item}});
10585: } else {
10586: $changes{'validation'}{$item} = &mt('None');
10587: }
10588: }
10589: } else {
10590: $confhash{'validation'}{$item} = $env{'form.requestcourses_validation_'.$item};
10591: if ($item eq 'markup') {
10592: if ($env{'form.requestcourses_validation_'.$item}) {
10593: $env{'form.requestcourses_validation_'.$item} =~ s/[\n\r\f]+/\s/gs;
10594: }
10595: }
10596: if (ref($domconfig{'requestcourses'}) eq 'HASH') {
10597: if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
10598: if ($domconfig{'requestcourses'}{'validation'}{$item} ne $confhash{'validation'}{$item}) {
10599: $changes{'validation'}{$item} = $confhash{'validation'}{$item};
10600: }
10601: } else {
10602: if ($confhash{'validation'}{$item} ne '') {
10603: $changes{'validation'}{$item} = $confhash{'validation'}{$item};
10604: }
10605: }
10606: } else {
10607: if ($confhash{'validation'}{$item} ne '') {
10608: $changes{'validation'}{$item} = $confhash{'validation'}{$item};
10609: }
10610: }
10611: }
10612: }
10613: }
10614: if ($env{'form.validationdc'}) {
10615: my $newval = $env{'form.validationdc'};
10616: my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);
10617: if (exists($domcoords{$newval})) {
10618: $confhash{'validation'}{'dc'} = $newval;
10619: }
10620: }
10621: if (ref($confhash{'validation'}) eq 'HASH') {
10622: if (ref($domconfig{'requestcourses'}) eq 'HASH') {
10623: if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
10624: if ($domconfig{'requestcourses'}{'validation'}{'dc'}) {
10625: unless ($confhash{'validation'}{'dc'} eq $domconfig{'requestcourses'}{'validation'}{'dc'}) {
10626: if ($confhash{'validation'}{'dc'} eq '') {
10627: $changes{'validation'}{'dc'} = &mt('None');
10628: } else {
10629: $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
10630: }
10631: }
10632: } elsif ($confhash{'validation'}{'dc'} ne '') {
10633: $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
10634: }
10635: } elsif ($confhash{'validation'}{'dc'} ne '') {
10636: $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
10637: }
10638: } elsif ($confhash{'validation'}{'dc'} ne '') {
10639: $changes{'validation'}{'dc'} = $confhash{'validation'}{'dc'};
10640: }
10641: } else {
10642: if (ref($domconfig{'requestcourses'}) eq 'HASH') {
10643: if (ref($domconfig{'requestcourses'}{'validation'}) eq 'HASH') {
10644: if ($domconfig{'requestcourses'}{'validation'}{'dc'}) {
10645: $changes{'validation'}{'dc'} = &mt('None');
10646: }
10647: }
10648: }
10649: }
10650: }
10651: } else {
10652: $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'};
10653: $confhash{'authorquota'}{'default'} = $env{'form.authorquota'};
10654: }
10655: foreach my $item (@usertools) {
10656: foreach my $type (@{$types},'default','_LC_adv') {
10657: my $unset;
10658: if ($context eq 'requestcourses') {
10659: $unset = '0';
10660: if ($type eq '_LC_adv') {
10661: $unset = '';
10662: }
10663: if ($confhash{$item}{$type} eq 'autolimit') {
10664: $confhash{$item}{$type} .= '=';
10665: unless ($limithash{$item}{$type} =~ /\D/) {
10666: $confhash{$item}{$type} .= $limithash{$item}{$type};
10667: }
10668: }
10669: } elsif ($context eq 'requestauthor') {
10670: $unset = '0';
10671: if ($type eq '_LC_adv') {
10672: $unset = '';
10673: }
10674: } else {
10675: if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) {
10676: $confhash{$item}{$type} = 1;
10677: } else {
10678: $confhash{$item}{$type} = 0;
10679: }
10680: }
10681: if (ref($domconfig{$action}) eq 'HASH') {
10682: if ($action eq 'requestauthor') {
10683: if ($domconfig{$action}{$type} ne $confhash{$type}) {
10684: $changes{$type} = 1;
10685: }
10686: } elsif (ref($domconfig{$action}{$item}) eq 'HASH') {
10687: if ($domconfig{$action}{$item}{$type} ne $confhash{$item}{$type}) {
10688: $changes{$item}{$type} = 1;
10689: }
10690: } else {
10691: if ($context eq 'requestcourses') {
10692: if ($confhash{$item}{$type} ne $unset) {
10693: $changes{$item}{$type} = 1;
10694: }
10695: } else {
10696: if (!$confhash{$item}{$type}) {
10697: $changes{$item}{$type} = 1;
10698: }
10699: }
10700: }
10701: } else {
10702: if ($context eq 'requestcourses') {
10703: if ($confhash{$item}{$type} ne $unset) {
10704: $changes{$item}{$type} = 1;
10705: }
10706: } elsif ($context eq 'requestauthor') {
10707: if ($confhash{$type} ne $unset) {
10708: $changes{$type} = 1;
10709: }
10710: } else {
10711: if (!$confhash{$item}{$type}) {
10712: $changes{$item}{$type} = 1;
10713: }
10714: }
10715: }
10716: }
10717: }
10718: unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
10719: if (ref($domconfig{'quotas'}) eq 'HASH') {
10720: if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') {
10721: foreach my $key (keys(%{$domconfig{'quotas'}{'defaultquota'}})) {
10722: if (exists($confhash{'defaultquota'}{$key})) {
10723: if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{'defaultquota'}{$key}) {
10724: $changes{'defaultquota'}{$key} = 1;
10725: }
10726: } else {
10727: $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{'defaultquota'}{$key};
10728: }
10729: }
10730: } else {
10731: foreach my $key (keys(%{$domconfig{'quotas'}})) {
10732: if (exists($confhash{'defaultquota'}{$key})) {
10733: if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{$key}) {
10734: $changes{'defaultquota'}{$key} = 1;
10735: }
10736: } else {
10737: $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{$key};
10738: }
10739: }
10740: }
10741: if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') {
10742: foreach my $key (keys(%{$domconfig{'quotas'}{'authorquota'}})) {
10743: if (exists($confhash{'authorquota'}{$key})) {
10744: if ($confhash{'authorquota'}{$key} ne $domconfig{'quotas'}{'authorquota'}{$key}) {
10745: $changes{'authorquota'}{$key} = 1;
10746: }
10747: } else {
10748: $confhash{'authorquota'}{$key} = $domconfig{'quotas'}{'authorquota'}{$key};
10749: }
10750: }
10751: }
10752: }
10753: if (ref($confhash{'defaultquota'}) eq 'HASH') {
10754: foreach my $key (keys(%{$confhash{'defaultquota'}})) {
10755: if (ref($domconfig{'quotas'}) eq 'HASH') {
10756: if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') {
10757: if (!exists($domconfig{'quotas'}{'defaultquota'}{$key})) {
10758: $changes{'defaultquota'}{$key} = 1;
10759: }
10760: } else {
10761: if (!exists($domconfig{'quotas'}{$key})) {
10762: $changes{'defaultquota'}{$key} = 1;
10763: }
10764: }
10765: } else {
10766: $changes{'defaultquota'}{$key} = 1;
10767: }
10768: }
10769: }
10770: if (ref($confhash{'authorquota'}) eq 'HASH') {
10771: foreach my $key (keys(%{$confhash{'authorquota'}})) {
10772: if (ref($domconfig{'quotas'}) eq 'HASH') {
10773: if (ref($domconfig{'quotas'}{'authorquota'}) eq 'HASH') {
10774: if (!exists($domconfig{'quotas'}{'authorquota'}{$key})) {
10775: $changes{'authorquota'}{$key} = 1;
10776: }
10777: } else {
10778: $changes{'authorquota'}{$key} = 1;
10779: }
10780: } else {
10781: $changes{'authorquota'}{$key} = 1;
10782: }
10783: }
10784: }
10785: }
10786:
10787: if ($context eq 'requestauthor') {
10788: $domdefaults{'requestauthor'} = \%confhash;
10789: } else {
10790: foreach my $key (keys(%confhash)) {
10791: unless (($context eq 'requestcourses') && (($key eq 'textbooks') || ($key eq 'templates'))) {
10792: $domdefaults{$key} = $confhash{$key};
10793: }
10794: }
10795: }
10796:
10797: my %quotahash = (
10798: $action => { %confhash }
10799: );
10800: my $putresult = &Apache::lonnet::put_dom('configuration',\%quotahash,
10801: $dom);
10802: if ($putresult eq 'ok') {
10803: if (keys(%changes) > 0) {
10804: my $cachetime = 24*60*60;
10805: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
10806: if (ref($lastactref) eq 'HASH') {
10807: $lastactref->{'domdefaults'} = 1;
10808: }
10809: $resulttext = &mt('Changes made:').'<ul>';
10810: unless (($context eq 'requestcourses') ||
10811: ($context eq 'requestauthor')) {
10812: if (ref($changes{'defaultquota'}) eq 'HASH') {
10813: $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>';
10814: foreach my $type (@{$types},'default') {
10815: if (defined($changes{'defaultquota'}{$type})) {
10816: my $typetitle = $usertypes->{$type};
10817: if ($type eq 'default') {
10818: $typetitle = $othertitle;
10819: }
10820: $resulttext .= '<li>'.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'defaultquota'}{$type}).'</li>';
10821: }
10822: }
10823: $resulttext .= '</ul></li>';
10824: }
10825: if (ref($changes{'authorquota'}) eq 'HASH') {
10826: $resulttext .= '<li>'.&mt('Authoring Space default quotas').'<ul>';
10827: foreach my $type (@{$types},'default') {
10828: if (defined($changes{'authorquota'}{$type})) {
10829: my $typetitle = $usertypes->{$type};
10830: if ($type eq 'default') {
10831: $typetitle = $othertitle;
10832: }
10833: $resulttext .= '<li>'.&mt('[_1] set to [_2] MB',$typetitle,$confhash{'authorquota'}{$type}).'</li>';
10834: }
10835: }
10836: $resulttext .= '</ul></li>';
10837: }
10838: }
10839: my %newenv;
10840: foreach my $item (@usertools) {
10841: my (%haschgs,%inconf);
10842: if ($context eq 'requestauthor') {
10843: %haschgs = %changes;
10844: %inconf = %confhash;
10845: } else {
10846: if (ref($changes{$item}) eq 'HASH') {
10847: %haschgs = %{$changes{$item}};
10848: }
10849: if (ref($confhash{$item}) eq 'HASH') {
10850: %inconf = %{$confhash{$item}};
10851: }
10852: }
10853: if (keys(%haschgs) > 0) {
10854: my $newacc =
10855: &Apache::lonnet::usertools_access($env{'user.name'},
10856: $env{'user.domain'},
10857: $item,'reload',$context);
10858: if (($context eq 'requestcourses') ||
10859: ($context eq 'requestauthor')) {
10860: if ($env{'environment.canrequest.'.$item} ne $newacc) {
10861: $newenv{'environment.canrequest.'.$item} = $newacc;
10862: }
10863: } else {
10864: if ($env{'environment.availabletools.'.$item} ne $newacc) {
10865: $newenv{'environment.availabletools.'.$item} = $newacc;
10866: }
10867: }
10868: unless ($context eq 'requestauthor') {
10869: $resulttext .= '<li>'.$titles{$item}.'<ul>';
10870: }
10871: foreach my $type (@{$types},'default','_LC_adv') {
10872: if ($haschgs{$type}) {
10873: my $typetitle = $usertypes->{$type};
10874: if ($type eq 'default') {
10875: $typetitle = $othertitle;
10876: } elsif ($type eq '_LC_adv') {
10877: $typetitle = 'LON-CAPA Advanced Users';
10878: }
10879: if ($inconf{$type}) {
10880: if ($context eq 'requestcourses') {
10881: my $cond;
10882: if ($inconf{$type} =~ /^autolimit=(\d*)$/) {
10883: if ($1 eq '') {
10884: $cond = &mt('(Automatic processing of any request).');
10885: } else {
10886: $cond = &mt('(Automatic processing of requests up to limit of [quant,_1,request] per user).',$1);
10887: }
10888: } else {
10889: $cond = $conditions{$inconf{$type}};
10890: }
10891: $resulttext .= '<li>'.&mt('Set to be available to [_1].',$typetitle).' '.$cond.'</li>';
10892: } elsif ($context eq 'requestauthor') {
10893: $resulttext .= '<li>'.&mt('Set to "[_1]" for "[_2]".',
10894: $titles{$inconf{$type}},$typetitle);
10895:
10896: } else {
10897: $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>';
10898: }
10899: } else {
10900: if ($type eq '_LC_adv') {
10901: if ($inconf{$type} eq '0') {
10902: $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>';
10903: } else {
10904: $resulttext .= '<li>'.&mt('No override set for [_1]',$typetitle).'</li>';
10905: }
10906: } else {
10907: $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>';
10908: }
10909: }
10910: }
10911: }
10912: unless ($context eq 'requestauthor') {
10913: $resulttext .= '</ul></li>';
10914: }
10915: }
10916: }
10917: if (($action eq 'requestcourses') || ($action eq 'requestauthor')) {
10918: if (ref($changes{'notify'}) eq 'HASH') {
10919: if ($changes{'notify'}{'approval'}) {
10920: if (ref($confhash{'notify'}) eq 'HASH') {
10921: if ($confhash{'notify'}{'approval'}) {
10922: $resulttext .= '<li>'.&mt('Notification of requests requiring approval will be sent to: ').$confhash{'notify'}{'approval'}.'</li>';
10923: } else {
10924: $resulttext .= '<li>'.&mt('No Domain Coordinators will receive notification of requests requiring approval.').'</li>';
10925: }
10926: }
10927: }
10928: }
10929: }
10930: if ($action eq 'requestcourses') {
10931: my @offon = ('off','on');
10932: if ($changes{'uniquecode'}) {
10933: if (ref($confhash{'uniquecode'}) eq 'HASH') {
10934: my $codestr = join(' ',map{ &mt($_); } sort(keys(%{$confhash{'uniquecode'}})));
10935: $resulttext .= '<li>'.
10936: &mt('Generation of six character code as course identifier for distribution to students set to on for: [_1].','<b>'.$codestr.'</b>').
10937: '</li>';
10938: } else {
10939: $resulttext .= '<li>'.&mt('Generation of six character code as course identifier for distribution to students set to off.').
10940: '</li>';
10941: }
10942: }
10943: foreach my $type ('textbooks','templates') {
10944: if (ref($changes{$type}) eq 'HASH') {
10945: $resulttext .= '<li>'.&mt("Available $type updated").'<ul>';
10946: foreach my $key (sort(keys(%{$changes{$type}}))) {
10947: my %coursehash = &Apache::lonnet::coursedescription($key);
10948: my $coursetitle = $coursehash{'description'};
10949: my $position = $confhash{$type}{$key}{'order'} + 1;
10950: $resulttext .= '<li>';
10951: foreach my $item ('subject','title','publisher','author') {
10952: next if ((($item eq 'author') || ($item eq 'publisher')) &&
10953: ($type eq 'templates'));
10954: my $name = $item.':';
10955: $name =~ s/^(\w)/\U$1/;
10956: $resulttext .= &mt($name).' '.$confhash{$type}{$key}{$item}.'<br />';
10957: }
10958: $resulttext .= ' '.&mt('Order: [_1]',$position).'<br />';
10959: if ($type eq 'textbooks') {
10960: if ($confhash{$type}{$key}{'image'}) {
10961: $resulttext .= ' '.&mt('Image: [_1]',
10962: '<img src="'.$confhash{$type}{$key}{'image'}.'"'.
10963: ' alt="Textbook cover" />').'<br />';
10964: }
10965: }
10966: $resulttext .= ' '.&mt('LON-CAPA Course: [_1]',$coursetitle).'</li>';
10967: }
10968: $resulttext .= '</ul></li>';
10969: }
10970: }
10971: if (ref($changes{'validation'}) eq 'HASH') {
10972: if ((ref($validationitemsref) eq 'ARRAY') && (ref($validationnamesref) eq 'HASH')) {
10973: $resulttext .= '<li>'.&mt('Validation of courses/communities updated').'<ul>';
10974: foreach my $item (@{$validationitemsref}) {
10975: if (exists($changes{'validation'}{$item})) {
10976: if ($item eq 'markup') {
10977: $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$validationnamesref->{$item},
10978: '<br /><pre>'.$changes{'validation'}{$item}.'</pre>').'</li>';
10979: } else {
10980: $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$validationnamesref->{$item},
10981: '<b>'.$changes{'validation'}{$item}.'</b>').'</li>';
10982: }
10983: }
10984: }
10985: if (exists($changes{'validation'}{'dc'})) {
10986: $resulttext .= '<li>'.&mt('Validated course requests identified as processed by: [_1]',
10987: '<b>'.$changes{'validation'}{'dc'}.'</b>').'</li>';
10988: }
10989: }
10990: }
10991: }
10992: $resulttext .= '</ul>';
10993: if (keys(%newenv)) {
10994: &Apache::lonnet::appenv(\%newenv);
10995: }
10996: } else {
10997: if ($context eq 'requestcourses') {
10998: $resulttext = &mt('No changes made to rights to request creation of courses.');
10999: } elsif ($context eq 'requestauthor') {
11000: $resulttext = &mt('No changes made to rights to request author space.');
11001: } else {
11002: $resulttext = &mt('No changes made to availability of personal information pages, blogs, portfolios or default quotas');
11003: }
11004: }
11005: } else {
11006: $resulttext = '<span class="LC_error">'.
11007: &mt('An error occurred: [_1]',$putresult).'</span>';
11008: }
11009: if ($errors) {
11010: $resulttext .= '<p>'.&mt('The following errors occurred when modifying Textbook settings.').
11011: '<ul>'.$errors.'</ul></p>';
11012: }
11013: return $resulttext;
11014: }
11015:
11016: sub process_textbook_image {
11017: my ($r,$dom,$confname,$caller,$cdom,$cnum,$type,$configuserok,$switchserver,$author_ok) = @_;
11018: my $filename = $env{'form.'.$caller.'.filename'};
11019: my ($error,$url);
11020: my ($width,$height) = (50,50);
11021: if ($configuserok eq 'ok') {
11022: if ($switchserver) {
11023: $error = &mt('Upload of textbook image is not permitted to this server: [_1]',
11024: $switchserver);
11025: } elsif ($author_ok eq 'ok') {
11026: my ($result,$imageurl) =
11027: &publishlogo($r,'upload',$caller,$dom,$confname,
11028: "$type/$cdom/$cnum/cover",$width,$height);
11029: if ($result eq 'ok') {
11030: $url = $imageurl;
11031: } else {
11032: $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$filename,$result);
11033: }
11034: } else {
11035: $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$author_ok);
11036: }
11037: } else {
11038: $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$configuserok);
11039: }
11040: return ($url,$error);
11041: }
11042:
11043: sub modify_ltitools {
11044: my ($r,$dom,$action,$lastactref,%domconfig) = @_;
11045: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
11046: my ($newid,@allpos,%changes,%confhash,%encconfig,$errors,$resulttext);
11047: my $confname = $dom.'-domainconfig';
11048: my $servadm = $r->dir_config('lonAdmEMail');
11049: my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm);
11050: my (%posslti,%possfield);
11051: my @courseroles = ('cc','in','ta','ep','st');
11052: my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner);
11053: map { $posslti{$_} = 1; } @ltiroles;
11054: my @allfields = ('fullname','firstname','lastname','email','user','roles');
11055: map { $possfield{$_} = 1; } @allfields;
11056: my %lt = <itools_names();
11057: if ($env{'form.ltitools_add'}) {
11058: my $title = $env{'form.ltitools_add_title'};
11059: $title =~ s/(`)/'/g;
11060: ($newid,my $error) = &get_ltitools_id($dom,$title);
11061: if ($newid) {
11062: my $position = $env{'form.ltitools_add_pos'};
11063: $position =~ s/\D+//g;
11064: if ($position ne '') {
11065: $allpos[$position] = $newid;
11066: }
11067: $changes{$newid} = 1;
11068: foreach my $item ('title','url','key','secret','lifetime') {
11069: $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g;
11070: if ($item eq 'lifetime') {
11071: $env{'form.ltitools_add_'.$item} =~ s/[^\d.]//g;
11072: }
11073: if ($env{'form.ltitools_add_'.$item}) {
11074: if (($item eq 'key') || ($item eq 'secret')) {
11075: $encconfig{$newid}{$item} = $env{'form.ltitools_add_'.$item};
11076: } else {
11077: $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item};
11078: }
11079: }
11080: }
11081: if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') {
11082: $confhash{$newid}{'version'} = $env{'form.ltitools_add_version'};
11083: }
11084: if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') {
11085: $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'};
11086: }
11087: if ($env{'form.ltitools_add_sigmethod'} eq 'HMAC-SHA256') {
11088: $confhash{$newid}{'sigmethod'} = $env{'form.ltitools_add_sigmethod'};
11089: } else {
11090: $confhash{$newid}{'sigmethod'} = 'HMAC-SHA1';
11091: }
11092: foreach my $item ('width','height','linktext','explanation') {
11093: $env{'form.ltitools_add_'.$item} =~ s/^\s+//;
11094: $env{'form.ltitools_add_'.$item} =~ s/\s+$//;
11095: if (($item eq 'width') || ($item eq 'height')) {
11096: if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) {
11097: $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
11098: }
11099: } else {
11100: if ($env{'form.ltitools_add_'.$item} ne '') {
11101: $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item};
11102: }
11103: }
11104: }
11105: if ($env{'form.ltitools_add_target'} eq 'window') {
11106: $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
11107: } elsif ($env{'form.ltitools_add_target'} eq 'tab') {
11108: $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'};
11109: } else {
11110: $confhash{$newid}{'display'}{'target'} = 'iframe';
11111: }
11112: foreach my $item ('passback','roster') {
11113: if ($env{'form.ltitools_'.$item.'_add'}) {
11114: $confhash{$newid}{$item} = 1;
11115: if ($env{'form.ltitools_'.$item.'valid_add'} ne '') {
11116: my $lifetime = $env{'form.ltitools_'.$item.'valid_add'};
11117: $lifetime =~ s/^\s+|\s+$//g;
11118: if ($lifetime =~ /^\d+\.?\d*$/) {
11119: $confhash{$newid}{$item.'valid'} = $lifetime;
11120: }
11121: }
11122: }
11123: }
11124: if ($env{'form.ltitools_add_image.filename'} ne '') {
11125: my ($imageurl,$error) =
11126: &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$newid,
11127: $configuserok,$switchserver,$author_ok);
11128: if ($imageurl) {
11129: $confhash{$newid}{'image'} = $imageurl;
11130: }
11131: if ($error) {
11132: &Apache::lonnet::logthis($error);
11133: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
11134: }
11135: }
11136: my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_add_fields');
11137: foreach my $field (@fields) {
11138: if ($possfield{$field}) {
11139: if ($field eq 'roles') {
11140: foreach my $role (@courseroles) {
11141: my $choice = $env{'form.ltitools_add_roles_'.$role};
11142: if (($choice ne '') && ($posslti{$choice})) {
11143: $confhash{$newid}{'roles'}{$role} = $choice;
11144: if ($role eq 'cc') {
11145: $confhash{$newid}{'roles'}{'co'} = $choice;
11146: }
11147: }
11148: }
11149: } else {
11150: $confhash{$newid}{'fields'}{$field} = 1;
11151: }
11152: }
11153: }
11154: if (ref($confhash{$newid}{'fields'}) eq 'HASH') {
11155: if ($confhash{$newid}{'fields'}{'user'}) {
11156: if ($env{'form.ltitools_userincdom_add'}) {
11157: $confhash{$newid}{'incdom'} = 1;
11158: }
11159: }
11160: }
11161: my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig');
11162: foreach my $item (@courseconfig) {
11163: $confhash{$newid}{'crsconf'}{$item} = 1;
11164: }
11165: if ($env{'form.ltitools_add_custom'}) {
11166: my $name = $env{'form.ltitools_add_custom_name'};
11167: my $value = $env{'form.ltitools_add_custom_value'};
11168: $value =~ s/(`)/'/g;
11169: $name =~ s/(`)/'/g;
11170: $confhash{$newid}{'custom'}{$name} = $value;
11171: }
11172: } else {
11173: my $error = &mt('Failed to acquire unique ID for new external tool');
11174: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
11175: }
11176: }
11177: if (ref($domconfig{$action}) eq 'HASH') {
11178: my %deletions;
11179: my @todelete = &Apache::loncommon::get_env_multiple('form.ltitools_del');
11180: if (@todelete) {
11181: map { $deletions{$_} = 1; } @todelete;
11182: }
11183: my %customadds;
11184: my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd');
11185: if (@newcustom) {
11186: map { $customadds{$_} = 1; } @newcustom;
11187: }
11188: my %imgdeletions;
11189: my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del');
11190: if (@todeleteimages) {
11191: map { $imgdeletions{$_} = 1; } @todeleteimages;
11192: }
11193: my $maxnum = $env{'form.ltitools_maxnum'};
11194: for (my $i=0; $i<=$maxnum; $i++) {
11195: my $itemid = $env{'form.ltitools_id_'.$i};
11196: $itemid =~ s/\D+//g;
11197: if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
11198: if ($deletions{$itemid}) {
11199: if ($domconfig{$action}{$itemid}{'image'}) {
11200: #FIXME need to obsolete item in RES space
11201: }
11202: $changes{$itemid} = $domconfig{$action}{$itemid}{'title'};
11203: next;
11204: } else {
11205: my $newpos = $env{'form.ltitools_'.$itemid};
11206: $newpos =~ s/\D+//g;
11207: foreach my $item ('title','url','lifetime') {
11208: $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
11209: if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
11210: $changes{$itemid} = 1;
11211: }
11212: }
11213: foreach my $item ('key','secret') {
11214: $encconfig{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
11215: if ($domconfig{$action}{$itemid}{$item} ne $encconfig{$itemid}{$item}) {
11216: $changes{$itemid} = 1;
11217: }
11218: }
11219: if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') {
11220: $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i};
11221: }
11222: if ($env{'form.ltitools_msgtype_'.$i} eq 'basic-lti-launch-request') {
11223: $confhash{$itemid}{'msgtype'} = $env{'form.ltitools_msgtype_'.$i};
11224: }
11225: if ($env{'form.ltitools_sigmethod_'.$i} eq 'HMAC-SHA256') {
11226: $confhash{$itemid}{'sigmethod'} = $env{'form.ltitools_sigmethod_'.$i};
11227: } else {
11228: $confhash{$itemid}{'sigmethod'} = 'HMAC-SHA1';
11229: }
11230: if ($domconfig{$action}{$itemid}{'sigmethod'} eq '') {
11231: if ($confhash{$itemid}{'sigmethod'} ne 'HMAC-SHA1') {
11232: $changes{$itemid} = 1;
11233: }
11234: } elsif ($domconfig{$action}{$itemid}{'sigmethod'} ne $confhash{$itemid}{'sigmethod'}) {
11235: $changes{$itemid} = 1;
11236: }
11237: foreach my $size ('width','height') {
11238: $env{'form.ltitools_'.$size.'_'.$i} =~ s/^\s+//;
11239: $env{'form.ltitools_'.$size.'_'.$i} =~ s/\s+$//;
11240: if ($env{'form.ltitools_'.$size.'_'.$i} =~ /^\d+$/) {
11241: $confhash{$itemid}{'display'}{$size} = $env{'form.ltitools_'.$size.'_'.$i};
11242: if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
11243: if ($domconfig{$action}{$itemid}{'display'}{$size} ne $confhash{$itemid}{'display'}{$size}) {
11244: $changes{$itemid} = 1;
11245: }
11246: } else {
11247: $changes{$itemid} = 1;
11248: }
11249: } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
11250: if ($domconfig{$action}{$itemid}{'display'}{$size} ne '') {
11251: $changes{$itemid} = 1;
11252: }
11253: }
11254: }
11255: foreach my $item ('linktext','explanation') {
11256: $env{'form.ltitools_'.$item.'_'.$i} =~ s/^\s+//;
11257: $env{'form.ltitools_'.$item.'_'.$i} =~ s/\s+$//;
11258: if ($env{'form.ltitools_'.$item.'_'.$i} ne '') {
11259: $confhash{$itemid}{'display'}{$item} = $env{'form.ltitools_'.$item.'_'.$i};
11260: if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
11261: if ($domconfig{$action}{$itemid}{'display'}{$item} ne $confhash{$itemid}{'display'}{$item}) {
11262: $changes{$itemid} = 1;
11263: }
11264: } else {
11265: $changes{$itemid} = 1;
11266: }
11267: } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
11268: if ($domconfig{$action}{$itemid}{'display'}{$item} ne '') {
11269: $changes{$itemid} = 1;
11270: }
11271: }
11272: }
11273: if ($env{'form.ltitools_target_'.$i} eq 'window') {
11274: $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
11275: } elsif ($env{'form.ltitools_target_'.$i} eq 'tab') {
11276: $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i};
11277: } else {
11278: $confhash{$itemid}{'display'}{'target'} = 'iframe';
11279: }
11280: if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') {
11281: if ($domconfig{$action}{$itemid}{'display'}{'target'} ne $confhash{$itemid}{'display'}{'target'}) {
11282: $changes{$itemid} = 1;
11283: }
11284: } else {
11285: $changes{$itemid} = 1;
11286: }
11287: foreach my $extra ('passback','roster') {
11288: if ($env{'form.ltitools_'.$extra.'_'.$i}) {
11289: $confhash{$itemid}{$extra} = 1;
11290: if ($env{'form.ltitools_'.$extra.'valid_'.$i} ne '') {
11291: my $lifetime = $env{'form.ltitools_'.$extra.'valid_'.$i};
11292: $lifetime =~ s/^\s+|\s+$//g;
11293: if ($lifetime =~ /^\d+\.?\d*$/) {
11294: $confhash{$itemid}{$extra.'valid'} = $lifetime;
11295: }
11296: }
11297: }
11298: if ($domconfig{$action}{$itemid}{$extra} ne $confhash{$itemid}{$extra}) {
11299: $changes{$itemid} = 1;
11300: }
11301: if ($domconfig{$action}{$itemid}{$extra.'valid'} ne $confhash{$itemid}{$extra.'valid'}) {
11302: $changes{$itemid} = 1;
11303: }
11304: }
11305: my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i);
11306: foreach my $item ('label','title','target','linktext','explanation','append') {
11307: if (grep(/^\Q$item\E$/,@courseconfig)) {
11308: $confhash{$itemid}{'crsconf'}{$item} = 1;
11309: if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') {
11310: if ($domconfig{$action}{$itemid}{'crsconf'}{$item} ne $confhash{$itemid}{'crsconf'}{$item}) {
11311: $changes{$itemid} = 1;
11312: }
11313: } else {
11314: $changes{$itemid} = 1;
11315: }
11316: }
11317: }
11318: my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_fields_'.$i);
11319: foreach my $field (@fields) {
11320: if ($possfield{$field}) {
11321: if ($field eq 'roles') {
11322: foreach my $role (@courseroles) {
11323: my $choice = $env{'form.ltitools_roles_'.$role.'_'.$i};
11324: if (($choice ne '') && ($posslti{$choice})) {
11325: $confhash{$itemid}{'roles'}{$role} = $choice;
11326: if ($role eq 'cc') {
11327: $confhash{$itemid}{'roles'}{'co'} = $choice;
11328: }
11329: }
11330: if (ref($domconfig{$action}{$itemid}{'roles'}) eq 'HASH') {
11331: if ($domconfig{$action}{$itemid}{'roles'}{$role} ne $confhash{$itemid}{'roles'}{$role}) {
11332: $changes{$itemid} = 1;
11333: }
11334: } elsif ($confhash{$itemid}{'roles'}{$role}) {
11335: $changes{$itemid} = 1;
11336: }
11337: }
11338: } else {
11339: $confhash{$itemid}{'fields'}{$field} = 1;
11340: if (ref($domconfig{$action}{$itemid}{'fields'}) eq 'HASH') {
11341: if ($domconfig{$action}{$itemid}{'fields'}{$field} ne $confhash{$itemid}{'fields'}{$field}) {
11342: $changes{$itemid} = 1;
11343: }
11344: } else {
11345: $changes{$itemid} = 1;
11346: }
11347: }
11348: }
11349: }
11350: if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
11351: if ($confhash{$itemid}{'fields'}{'user'}) {
11352: if ($env{'form.ltitools_userincdom_'.$i}) {
11353: $confhash{$itemid}{'incdom'} = 1;
11354: }
11355: if ($domconfig{$action}{$itemid}{'incdom'} ne $confhash{$itemid}{'incdom'}) {
11356: $changes{$itemid} = 1;
11357: }
11358: }
11359: }
11360: $allpos[$newpos] = $itemid;
11361: }
11362: if ($imgdeletions{$itemid}) {
11363: $changes{$itemid} = 1;
11364: #FIXME need to obsolete item in RES space
11365: } elsif ($env{'form.ltitools_image_'.$i.'.filename'}) {
11366: my ($imgurl,$error) = &process_ltitools_image($r,$dom,$confname,'ltitools_image_'.$i,
11367: $itemid,$configuserok,$switchserver,
11368: $author_ok);
11369: if ($imgurl) {
11370: $confhash{$itemid}{'image'} = $imgurl;
11371: $changes{$itemid} = 1;
11372: }
11373: if ($error) {
11374: &Apache::lonnet::logthis($error);
11375: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
11376: }
11377: } elsif ($domconfig{$action}{$itemid}{'image'}) {
11378: $confhash{$itemid}{'image'} =
11379: $domconfig{$action}{$itemid}{'image'};
11380: }
11381: if ($customadds{$i}) {
11382: my $name = $env{'form.ltitools_custom_name_'.$i};
11383: $name =~ s/(`)/'/g;
11384: $name =~ s/^\s+//;
11385: $name =~ s/\s+$//;
11386: my $value = $env{'form.ltitools_custom_value_'.$i};
11387: $value =~ s/(`)/'/g;
11388: $value =~ s/^\s+//;
11389: $value =~ s/\s+$//;
11390: if ($name ne '') {
11391: $confhash{$itemid}{'custom'}{$name} = $value;
11392: $changes{$itemid} = 1;
11393: }
11394: }
11395: my %customdels;
11396: my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i);
11397: if (@customdeletions) {
11398: $changes{$itemid} = 1;
11399: }
11400: map { $customdels{$_} = 1; } @customdeletions;
11401: if (ref($domconfig{$action}{$itemid}{'custom'}) eq 'HASH') {
11402: foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) {
11403: unless ($customdels{$key}) {
11404: if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') {
11405: $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i};
11406: }
11407: if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) {
11408: $changes{$itemid} = 1;
11409: }
11410: }
11411: }
11412: }
11413: unless ($changes{$itemid}) {
11414: foreach my $key (keys(%{$domconfig{$action}{$itemid}})) {
11415: if (ref($domconfig{$action}{$itemid}{$key}) eq 'HASH') {
11416: if (ref($confhash{$itemid}{$key}) eq 'HASH') {
11417: foreach my $innerkey (keys(%{$domconfig{$action}{$itemid}{$key}})) {
11418: unless (exists($confhash{$itemid}{$key}{$innerkey})) {
11419: $changes{$itemid} = 1;
11420: last;
11421: }
11422: }
11423: } elsif (keys(%{$domconfig{$action}{$itemid}{$key}}) > 0) {
11424: $changes{$itemid} = 1;
11425: }
11426: }
11427: last if ($changes{$itemid});
11428: }
11429: }
11430: }
11431: }
11432: }
11433: if (@allpos > 0) {
11434: my $idx = 0;
11435: foreach my $itemid (@allpos) {
11436: if ($itemid ne '') {
11437: $confhash{$itemid}{'order'} = $idx;
11438: if (ref($domconfig{$action}) eq 'HASH') {
11439: if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
11440: if ($domconfig{$action}{$itemid}{'order'} ne $idx) {
11441: $changes{$itemid} = 1;
11442: }
11443: }
11444: }
11445: $idx ++;
11446: }
11447: }
11448: }
11449: my %ltitoolshash = (
11450: $action => { %confhash }
11451: );
11452: my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash,
11453: $dom);
11454: if ($putresult eq 'ok') {
11455: my %ltienchash = (
11456: $action => { %encconfig }
11457: );
11458: &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom);
11459: if (keys(%changes) > 0) {
11460: my $cachetime = 24*60*60;
11461: my %ltiall = %confhash;
11462: foreach my $id (keys(%ltiall)) {
11463: if (ref($encconfig{$id}) eq 'HASH') {
11464: foreach my $item ('key','secret') {
11465: $ltiall{$id}{$item} = $encconfig{$id}{$item};
11466: }
11467: }
11468: }
11469: &Apache::lonnet::do_cache_new('ltitools',$dom,\%ltiall,$cachetime);
11470: if (ref($lastactref) eq 'HASH') {
11471: $lastactref->{'ltitools'} = 1;
11472: }
11473: $resulttext = &mt('Changes made:').'<ul>';
11474: my %bynum;
11475: foreach my $itemid (sort(keys(%changes))) {
11476: my $position = $confhash{$itemid}{'order'};
11477: $bynum{$position} = $itemid;
11478: }
11479: foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
11480: my $itemid = $bynum{$pos};
11481: if (ref($confhash{$itemid}) ne 'HASH') {
11482: $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';
11483: } else {
11484: $resulttext .= '<li><b>'.$confhash{$itemid}{'title'}.'</b>';
11485: if ($confhash{$itemid}{'image'}) {
11486: $resulttext .= ' '.
11487: '<img src="'.$confhash{$itemid}{'image'}.'"'.
11488: ' alt="'.&mt('Tool Provider icon').'" />';
11489: }
11490: $resulttext .= '</li><ul>';
11491: my $position = $pos + 1;
11492: $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';
11493: foreach my $item ('version','msgtype','sigmethod','url','lifetime') {
11494: if ($confhash{$itemid}{$item} ne '') {
11495: $resulttext .= '<li>'.$lt{$item}.': '.$confhash{$itemid}{$item}.'</li>';
11496: }
11497: }
11498: if ($encconfig{$itemid}{'key'} ne '') {
11499: $resulttext .= '<li>'.$lt{'key'}.': '.$encconfig{$itemid}{'key'}.'</li>';
11500: }
11501: if ($encconfig{$itemid}{'secret'} ne '') {
11502: $resulttext .= '<li>'.$lt{'secret'}.': ';
11503: my $num = length($encconfig{$itemid}{'secret'});
11504: $resulttext .= ('*'x$num).'</li>';
11505: }
11506: $resulttext .= '<li>'.&mt('Configurable in course:');
11507: my @possconfig = ('label','title','target','linktext','explanation','append');
11508: my $numconfig = 0;
11509: if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') {
11510: foreach my $item (@possconfig) {
11511: if ($confhash{$itemid}{'crsconf'}{$item}) {
11512: $numconfig ++;
11513: $resulttext .= ' "'.$lt{'crs'.$item}.'"';
11514: }
11515: }
11516: }
11517: if (!$numconfig) {
11518: $resulttext .= &mt('None');
11519: }
11520: $resulttext .= '</li>';
11521: foreach my $item ('passback','roster') {
11522: $resulttext .= '<li>'.$lt{$item}.' ';
11523: if ($confhash{$itemid}{$item}) {
11524: $resulttext .= &mt('Yes');
11525: if ($confhash{$itemid}{$item.'valid'}) {
11526: if ($item eq 'passback') {
11527: $resulttext .= ' '.&mt('valid for at least [quant,_1,day] after launch',
11528: $confhash{$itemid}{$item.'valid'});
11529: } else {
11530: $resulttext .= ' '.&mt('valid for at least [quant,_1,second] after launch',
11531: $confhash{$itemid}{$item.'valid'});
11532: }
11533: }
11534: } else {
11535: $resulttext .= &mt('No');
11536: }
11537: $resulttext .= '</li>';
11538: }
11539: if (ref($confhash{$itemid}{'display'}) eq 'HASH') {
11540: my $displaylist;
11541: if ($confhash{$itemid}{'display'}{'target'}) {
11542: $displaylist = &mt('Display target').': '.
11543: $confhash{$itemid}{'display'}{'target'}.',';
11544: }
11545: foreach my $size ('width','height') {
11546: if ($confhash{$itemid}{'display'}{$size}) {
11547: $displaylist .= (' 'x2).$lt{$size}.': '.
11548: $confhash{$itemid}{'display'}{$size}.',';
11549: }
11550: }
11551: if ($displaylist) {
11552: $displaylist =~ s/,$//;
11553: $resulttext .= '<li>'.$displaylist.'</li>';
11554: }
11555: foreach my $item ('linktext','explanation') {
11556: if ($confhash{$itemid}{'display'}{$item}) {
11557: $resulttext .= '<li>'.$lt{$item}.': '.$confhash{$itemid}{'display'}{$item}.'</li>';
11558: }
11559: }
11560: }
11561: if (ref($confhash{$itemid}{'fields'}) eq 'HASH') {
11562: my $fieldlist;
11563: foreach my $field (@allfields) {
11564: if ($confhash{$itemid}{'fields'}{$field}) {
11565: $fieldlist .= (' 'x2).$lt{$field}.',';
11566: }
11567: }
11568: if ($fieldlist) {
11569: $fieldlist =~ s/,$//;
11570: if ($confhash{$itemid}{'fields'}{'user'}) {
11571: if ($confhash{$itemid}{'incdom'}) {
11572: $fieldlist .= ' ('.&mt('username:domain').')';
11573: } else {
11574: $fieldlist .= ' ('.&mt('username').')';
11575: }
11576: }
11577: $resulttext .= '<li>'.&mt('Data sent').':'.$fieldlist.'</li>';
11578: }
11579: }
11580: if (ref($confhash{$itemid}{'roles'}) eq 'HASH') {
11581: my $rolemaps;
11582: foreach my $role (@courseroles) {
11583: if ($confhash{$itemid}{'roles'}{$role}) {
11584: $rolemaps .= (' 'x2).&Apache::lonnet::plaintext($role,'Course').'='.
11585: $confhash{$itemid}{'roles'}{$role}.',';
11586: }
11587: }
11588: if ($rolemaps) {
11589: $rolemaps =~ s/,$//;
11590: $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
11591: }
11592: }
11593: if (ref($confhash{$itemid}{'custom'}) eq 'HASH') {
11594: my $customlist;
11595: if (keys(%{$confhash{$itemid}{'custom'}})) {
11596: foreach my $key (sort(keys(%{$confhash{$itemid}{'custom'}}))) {
11597: $customlist .= $key.':'.$confhash{$itemid}{'custom'}{$key}.(' 'x2);
11598: }
11599: }
11600: if ($customlist) {
11601: $resulttext .= '<li>'.&mt('Custom items').': '.$customlist.'</li>';
11602: }
11603: }
11604: $resulttext .= '</ul></li>';
11605: }
11606: }
11607: $resulttext .= '</ul>';
11608: } else {
11609: $resulttext = &mt('No changes made.');
11610: }
11611: } else {
11612: $errors .= '<li><span class="LC_error">'.&mt('Failed to save changes').'</span></li>';
11613: }
11614: if ($errors) {
11615: $resulttext .= &mt('The following errors occurred: ').'<ul>'.
11616: $errors.'</ul>';
11617: }
11618: return $resulttext;
11619: }
11620:
11621: sub process_ltitools_image {
11622: my ($r,$dom,$confname,$caller,$itemid,$configuserok,$switchserver,$author_ok) = @_;
11623: my $filename = $env{'form.'.$caller.'.filename'};
11624: my ($error,$url);
11625: my ($width,$height) = (21,21);
11626: if ($configuserok eq 'ok') {
11627: if ($switchserver) {
11628: $error = &mt('Upload of Tool Provider (LTI) icon is not permitted to this server: [_1]',
11629: $switchserver);
11630: } elsif ($author_ok eq 'ok') {
11631: my ($result,$imageurl,$madethumb) =
11632: &publishlogo($r,'upload',$caller,$dom,$confname,
11633: "ltitools/$itemid/icon",$width,$height);
11634: if ($result eq 'ok') {
11635: if ($madethumb) {
11636: my ($path,$imagefile) = ($imageurl =~ m{^(.+)/([^/]+)$});
11637: my $imagethumb = "$path/tn-".$imagefile;
11638: $url = $imagethumb;
11639: } else {
11640: $url = $imageurl;
11641: }
11642: } else {
11643: $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$filename,$result);
11644: }
11645: } else {
11646: $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$author_ok);
11647: }
11648: } else {
11649: $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$configuserok);
11650: }
11651: return ($url,$error);
11652: }
11653:
11654: sub get_ltitools_id {
11655: my ($cdom,$title) = @_;
11656: # get lock on ltitools db
11657: my $lockhash = {
11658: lock => $env{'user.name'}.
11659: ':'.$env{'user.domain'},
11660: };
11661: my $tries = 0;
11662: my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
11663: my ($id,$error);
11664:
11665: while (($gotlock ne 'ok') && ($tries<10)) {
11666: $tries ++;
11667: sleep (0.1);
11668: $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom);
11669: }
11670: if ($gotlock eq 'ok') {
11671: my %currids = &Apache::lonnet::dump_dom('ltitools',$cdom);
11672: if ($currids{'lock'}) {
11673: delete($currids{'lock'});
11674: if (keys(%currids)) {
11675: my @curr = sort { $a <=> $b } keys(%currids);
11676: if ($curr[-1] =~ /^\d+$/) {
11677: $id = 1 + $curr[-1];
11678: }
11679: } else {
11680: $id = 1;
11681: }
11682: if ($id) {
11683: unless (&Apache::lonnet::newput_dom('ltitools',{ $id => $title },$cdom) eq 'ok') {
11684: $error = 'nostore';
11685: }
11686: } else {
11687: $error = 'nonumber';
11688: }
11689: }
11690: my $dellockoutcome = &Apache::lonnet::del_dom('ltitools',['lock'],$cdom);
11691: } else {
11692: $error = 'nolock';
11693: }
11694: return ($id,$error);
11695: }
11696:
11697: sub modify_lti {
11698: my ($r,$dom,$action,$lastactref,%domconfig) = @_;
11699: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
11700: my ($newid,@allpos,%changes,%confhash,%encconfig,$errors,$resulttext);
11701: my (%posslti,%posslticrs,%posscrstype);
11702: my @courseroles = ('cc','in','ta','ep','st');
11703: my @ltiroles = qw(Learner Instructor ContentDeveloper TeachingAssistant Mentor Member Manager Administrator);
11704: my @lticourseroles = qw(Instructor TeachingAssistant Mentor Learner);
11705: my @coursetypes = ('official','unofficial','community','textbook','placement');
11706: my %coursetypetitles = &Apache::lonlocal::texthash (
11707: official => 'Official',
11708: unofficial => 'Unofficial',
11709: community => 'Community',
11710: textbook => 'Textbook',
11711: placement => 'Placement Test',
11712: );
11713: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
11714: my %lt = <i_names();
11715: map { $posslti{$_} = 1; } @ltiroles;
11716: map { $posslticrs{$_} = 1; } @lticourseroles;
11717: map { $posscrstype{$_} = 1; } @coursetypes;
11718:
11719: my %menutitles = <imenu_titles();
11720:
11721: my (@items,%deletions,%itemids);
11722: if ($env{'form.lti_add'}) {
11723: my $consumer = $env{'form.lti_consumer_add'};
11724: $consumer =~ s/(`)/'/g;
11725: ($newid,my $error) = &get_lti_id($dom,$consumer);
11726: if ($newid) {
11727: $itemids{'add'} = $newid;
11728: push(@items,'add');
11729: $changes{$newid} = 1;
11730: } else {
11731: my $error = &mt('Failed to acquire unique ID for new LTI configuration');
11732: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
11733: }
11734: }
11735: if (ref($domconfig{$action}) eq 'HASH') {
11736: my @todelete = &Apache::loncommon::get_env_multiple('form.lti_del');
11737: if (@todelete) {
11738: map { $deletions{$_} = 1; } @todelete;
11739: }
11740: my $maxnum = $env{'form.lti_maxnum'};
11741: for (my $i=0; $i<=$maxnum; $i++) {
11742: my $itemid = $env{'form.lti_id_'.$i};
11743: $itemid =~ s/\D+//g;
11744: if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
11745: if ($deletions{$itemid}) {
11746: $changes{$itemid} = $domconfig{$action}{$itemid}{'consumer'};
11747: } else {
11748: push(@items,$i);
11749: $itemids{$i} = $itemid;
11750: }
11751: }
11752: }
11753: }
11754: foreach my $idx (@items) {
11755: my $itemid = $itemids{$idx};
11756: next unless ($itemid);
11757: my $position = $env{'form.lti_pos_'.$idx};
11758: $position =~ s/\D+//g;
11759: if ($position ne '') {
11760: $allpos[$position] = $itemid;
11761: }
11762: foreach my $item ('consumer','key','secret','lifetime') {
11763: my $formitem = 'form.lti_'.$item.'_'.$idx;
11764: $env{$formitem} =~ s/(`)/'/g;
11765: if ($item eq 'lifetime') {
11766: $env{$formitem} =~ s/[^\d.]//g;
11767: }
11768: if ($env{$formitem} ne '') {
11769: if (($item eq 'key') || ($item eq 'secret')) {
11770: $encconfig{$itemid}{$item} = $env{$formitem};
11771: } else {
11772: $confhash{$itemid}{$item} = $env{$formitem};
11773: unless (($idx eq 'add') || ($changes{$itemid})) {
11774: if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) {
11775: $changes{$itemid} = 1;
11776: }
11777: }
11778: }
11779: }
11780: }
11781: if ($env{'form.lti_version_'.$idx} eq 'LTI-1p0') {
11782: $confhash{$itemid}{'version'} = $env{'form.lti_version_'.$idx};
11783: }
11784: if ($env{'form.lti_mapuser_'.$idx} eq 'sourcedid') {
11785: $confhash{$itemid}{'mapuser'} = 'lis_person_sourcedid';
11786: } elsif ($env{'form.lti_mapuser_'.$idx} eq 'email') {
11787: $confhash{$itemid}{'mapuser'} = 'lis_person_contact_email_primary';
11788: } elsif ($env{'form.lti_mapuser_'.$idx} eq 'other') {
11789: my $mapuser = $env{'form.lti_customuser_'.$idx};
11790: $mapuser =~ s/(`)/'/g;
11791: $mapuser =~ s/^\s+|\s+$//g;
11792: $confhash{$itemid}{'mapuser'} = $mapuser;
11793: }
11794: foreach my $ltirole (@lticourseroles) {
11795: my $possrole = $env{'form.lti_maprole_'.$ltirole.'_'.$idx};
11796: if (grep(/^\Q$possrole\E$/,@courseroles)) {
11797: $confhash{$itemid}{'maproles'}{$ltirole} = $possrole;
11798: }
11799: }
11800: my @possmakeuser = &Apache::loncommon::get_env_multiple('form.lti_makeuser_'.$idx);
11801: my @makeuser;
11802: foreach my $ltirole (sort(@possmakeuser)) {
11803: if ($posslti{$ltirole}) {
11804: push(@makeuser,$ltirole);
11805: }
11806: }
11807: $confhash{$itemid}{'makeuser'} = \@makeuser;
11808: if (@makeuser) {
11809: my $lcauth = $env{'form.lti_lcauth_'.$idx};
11810: if ($lcauth =~ /^(internal|krb4|krb5|localauth)$/) {
11811: $confhash{$itemid}{'lcauth'} = $lcauth;
11812: if ($lcauth ne 'internal') {
11813: my $lcauthparm = $env{'form.lti_lcauthparm_'.$idx};
11814: $lcauthparm =~ s/^(\s+|\s+)$//g;
11815: $lcauthparm =~ s/`//g;
11816: if ($lcauthparm ne '') {
11817: $confhash{$itemid}{'lcauthparm'} = $lcauthparm;
11818: }
11819: }
11820: } else {
11821: $confhash{$itemid}{'lcauth'} = 'lti';
11822: }
11823: }
11824: my @possinstdata = &Apache::loncommon::get_env_multiple('form.lti_instdata_'.$idx);
11825: if (@possinstdata) {
11826: foreach my $field (@possinstdata) {
11827: if (exists($fieldtitles{$field})) {
11828: push(@{$confhash{$itemid}{'instdata'}});
11829: }
11830: }
11831: }
11832: if (($env{'form.lti_mapcrs_'.$idx} eq 'course_offering_sourcedid') ||
11833: ($env{'form.lti_mapcrs_'.$idx} eq 'context_id')) {
11834: $confhash{$itemid}{'mapcrs'} = $env{'form.lti_mapcrs_'.$idx};
11835: } elsif ($env{'form.lti_mapcrs_'.$idx} eq 'other') {
11836: my $mapcrs = $env{'form.lti_mapcrsfield_'.$idx};
11837: $mapcrs =~ s/(`)/'/g;
11838: $mapcrs =~ s/^\s+|\s+$//g;
11839: $confhash{$itemid}{'mapcrs'} = $mapcrs;
11840: }
11841: my @posstypes = &Apache::loncommon::get_env_multiple('form.lti_mapcrstype_'.$idx);
11842: my @crstypes;
11843: foreach my $type (sort(@posstypes)) {
11844: if ($posscrstype{$type}) {
11845: push(@crstypes,$type);
11846: }
11847: }
11848: $confhash{$itemid}{'mapcrstype'} = \@crstypes;
11849: if ($env{'form.lti_makecrs_'.$idx}) {
11850: $confhash{$itemid}{'makecrs'} = 1;
11851: }
11852: my @possenroll = &Apache::loncommon::get_env_multiple('form.lti_selfenroll_'.$idx);
11853: my @selfenroll;
11854: foreach my $type (sort(@possenroll)) {
11855: if ($posslticrs{$type}) {
11856: push(@selfenroll,$type);
11857: }
11858: }
11859: $confhash{$itemid}{'selfenroll'} = \@selfenroll;
11860: if ($env{'form.lti_crssec_'.$idx}) {
11861: if ($env{'form.lti_crssecsrc_'.$idx} eq 'course_section_sourcedid') {
11862: $confhash{$itemid}{'section'} = $env{'form.lti_crssecsrc_'.$idx};
11863: } elsif ($env{'form.lti_crssecsrc_'.$idx} eq 'other') {
11864: my $section = $env{'form.lti_customsection_'.$idx};
11865: $section =~ s/(`)/'/g;
11866: $section =~ s/^\s+|\s+$//g;
11867: if ($section ne '') {
11868: $confhash{$itemid}{'section'} = $section;
11869: }
11870: }
11871: }
11872: foreach my $field ('passback','roster','topmenu','inlinemenu') {
11873: if ($env{'form.lti_'.$field.'_'.$idx}) {
11874: $confhash{$itemid}{$field} = 1;
11875: }
11876: }
11877: if ($env{'form.lti_passback_'.$idx}) {
11878: if ($env{'form.lti_passbackformat_'.$idx} eq '1.0') {
11879: $confhash{$itemid}{'passbackformat'} = '1.0';
11880: } else {
11881: $confhash{$itemid}{'passbackformat'} = '1.1';
11882: }
11883: }
11884: if ($env{'form.lti_topmenu_'.$idx} || $env{'form.lti_inlinemenu_'.$idx}) {
11885: $confhash{$itemid}{lcmenu} = [];
11886: my @possmenu = &Apache::loncommon::get_env_multiple('form.lti_menuitem_'.$idx);
11887: foreach my $field (@possmenu) {
11888: if (exists($menutitles{$field})) {
11889: if ($field eq 'grades') {
11890: next unless ($env{'form.lti_inlinemenu_'.$idx});
11891: }
11892: push(@{$confhash{$itemid}{lcmenu}},$field);
11893: }
11894: }
11895: }
11896: unless (($idx eq 'add') || ($changes{$itemid})) {
11897: foreach my $field ('mapuser','mapcrs','makecrs','section','passback','roster','lcauth','lcauthparm','topmenu','inlinemenu') {
11898: if ($domconfig{$action}{$itemid}{$field} ne $confhash{$itemid}{$field}) {
11899: $changes{$itemid} = 1;
11900: }
11901: }
11902: unless ($changes{$itemid}) {
11903: if ($domconfig{$action}{$itemid}{'passback'} eq $confhash{$itemid}{'passback'}) {
11904: if ($domconfig{$action}{$itemid}{'passbackformat'} ne $confhash{$itemid}{'passbackformat'}) {
11905: $changes{$itemid} = 1;
11906: }
11907: }
11908: }
11909: foreach my $field ('makeuser','mapcrstype','selfenroll','instdata','lcmenu') {
11910: unless ($changes{$itemid}) {
11911: if (ref($domconfig{$action}{$itemid}{$field}) eq 'ARRAY') {
11912: if (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
11913: my @diffs = &Apache::loncommon::compare_arrays($domconfig{$action}{$itemid}{$field},
11914: $confhash{$itemid}{$field});
11915: if (@diffs) {
11916: $changes{$itemid} = 1;
11917: }
11918: } elsif (@{$domconfig{$action}{$itemid}{$field}} > 0) {
11919: $changes{$itemid} = 1;
11920: }
11921: } elsif (ref($confhash{$itemid}{$field}) eq 'ARRAY') {
11922: if (@{$confhash{$itemid}{$field}} > 0) {
11923: $changes{$itemid} = 1;
11924: }
11925: }
11926: }
11927: }
11928: unless ($changes{$itemid}) {
11929: if (ref($domconfig{$action}{$itemid}{'maproles'}) eq 'HASH') {
11930: if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
11931: foreach my $ltirole (keys(%{$domconfig{$action}{$itemid}{'maproles'}})) {
11932: if ($domconfig{$action}{$itemid}{'maproles'}{$ltirole} ne
11933: $confhash{$itemid}{'maproles'}{$ltirole}) {
11934: $changes{$itemid} = 1;
11935: last;
11936: }
11937: }
11938: unless ($changes{$itemid}) {
11939: foreach my $ltirole (keys(%{$confhash{$itemid}{'maproles'}})) {
11940: if ($confhash{$itemid}{'maproles'}{$ltirole} ne
11941: $domconfig{$action}{$itemid}{'maproles'}{$ltirole}) {
11942: $changes{$itemid} = 1;
11943: last;
11944: }
11945: }
11946: }
11947: } elsif (keys(%{$domconfig{$action}{$itemid}{'maproles'}}) > 0) {
11948: $changes{$itemid} = 1;
11949: }
11950: } elsif (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
11951: unless ($changes{$itemid}) {
11952: if (keys(%{$confhash{$itemid}{'maproles'}}) > 0) {
11953: $changes{$itemid} = 1;
11954: }
11955: }
11956: }
11957: }
11958: }
11959: }
11960: if (@allpos > 0) {
11961: my $idx = 0;
11962: foreach my $itemid (@allpos) {
11963: if ($itemid ne '') {
11964: $confhash{$itemid}{'order'} = $idx;
11965: if (ref($domconfig{$action}) eq 'HASH') {
11966: if (ref($domconfig{$action}{$itemid}) eq 'HASH') {
11967: if ($domconfig{$action}{$itemid}{'order'} ne $idx) {
11968: $changes{$itemid} = 1;
11969: }
11970: }
11971: }
11972: $idx ++;
11973: }
11974: }
11975: }
11976: my %ltihash = (
11977: $action => { %confhash }
11978: );
11979: my $putresult = &Apache::lonnet::put_dom('configuration',\%ltihash,
11980: $dom);
11981: if ($putresult eq 'ok') {
11982: my %ltienchash = (
11983: $action => { %encconfig }
11984: );
11985: &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom);
11986: if (keys(%changes) > 0) {
11987: my $cachetime = 24*60*60;
11988: my %ltiall = %confhash;
11989: foreach my $id (keys(%ltiall)) {
11990: if (ref($encconfig{$id}) eq 'HASH') {
11991: foreach my $item ('key','secret') {
11992: $ltiall{$id}{$item} = $encconfig{$id}{$item};
11993: }
11994: }
11995: }
11996: &Apache::lonnet::do_cache_new('lti',$dom,\%ltiall,$cachetime);
11997: if (ref($lastactref) eq 'HASH') {
11998: $lastactref->{'lti'} = 1;
11999: }
12000: $resulttext = &mt('Changes made:').'<ul>';
12001: my %bynum;
12002: foreach my $itemid (sort(keys(%changes))) {
12003: my $position = $confhash{$itemid}{'order'};
12004: $bynum{$position} = $itemid;
12005: }
12006: foreach my $pos (sort { $a <=> $b } keys(%bynum)) {
12007: my $itemid = $bynum{$pos};
12008: if (ref($confhash{$itemid}) ne 'HASH') {
12009: $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>';
12010: } else {
12011: $resulttext .= '<li><b>'.$confhash{$itemid}{'consumer'}.'</b></li><ul>';
12012: my $position = $pos + 1;
12013: $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>';
12014: foreach my $item ('version','lifetime') {
12015: if ($confhash{$itemid}{$item} ne '') {
12016: $resulttext .= '<li>'.$lt{$item}.': '.$confhash{$itemid}{$item}.'</li>';
12017: }
12018: }
12019: if ($encconfig{$itemid}{'key'} ne '') {
12020: $resulttext .= '<li>'.$lt{'key'}.': '.$encconfig{$itemid}{'key'}.'</li>';
12021: }
12022: if ($encconfig{$itemid}{'secret'} ne '') {
12023: $resulttext .= '<li>'.$lt{'secret'}.': ';
12024: my $num = length($encconfig{$itemid}{'secret'});
12025: $resulttext .= ('*'x$num).'</li>';
12026: }
12027: if ($confhash{$itemid}{'mapuser'}) {
12028: my $shownmapuser;
12029: if ($confhash{$itemid}{'mapuser'} eq 'lis_person_sourcedid') {
12030: $shownmapuser = $lt{'sourcedid'}.' (lis_person_sourcedid)';
12031: } elsif ($confhash{$itemid}{'mapuser'} eq 'lis_person_contact_email_primary') {
12032: $shownmapuser = $lt{'email'}.' (lis_person_contact_email_primary)';
12033: } else {
12034: $shownmapuser = &mt('Other').' ('.$confhash{$itemid}{'mapuser'}.')';
12035: }
12036: $resulttext .= '<li>'.&mt('LON-CAPA username').': '.$shownmapuser.'</li>';
12037: }
12038: if (ref($confhash{$itemid}{'maproles'}) eq 'HASH') {
12039: my $rolemaps;
12040: foreach my $role (@ltiroles) {
12041: if ($confhash{$itemid}{'maproles'}{$role}) {
12042: $rolemaps .= (' 'x2).$role.'='.
12043: &Apache::lonnet::plaintext($confhash{$itemid}{'maproles'}{$role},
12044: 'Course').',';
12045: }
12046: }
12047: if ($rolemaps) {
12048: $rolemaps =~ s/,$//;
12049: $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>';
12050: }
12051: }
12052: if (ref($confhash{$itemid}{'makeuser'}) eq 'ARRAY') {
12053: if (@{$confhash{$itemid}{'makeuser'}} > 0) {
12054: $resulttext .= '<li>'.&mt('Following roles may create user accounts: [_1]',
12055: join(', ',@{$confhash{$itemid}{'makeuser'}})).'<br />';
12056: if ($confhash{$itemid}{'lcauth'} eq 'lti') {
12057: $resulttext .= &mt('New users will only be able to authenticate via LTI').'</li>';
12058: } else {
12059: $resulttext .= &mt('New users will be assigned LON-CAPA authentication: [_1]',
12060: $confhash{$itemid}{'lcauth'});
12061: if ($confhash{$itemid}{'lcauth'} eq 'internal') {
12062: $resulttext .= '; '.&mt('a randomly generated password will be created');
12063: } elsif ($confhash{$itemid}{'lcauth'} eq 'localauth') {
12064: if ($confhash{$itemid}{'lcauthparm'} ne '') {
12065: $resulttext .= ' '.&mt('with argument: [_1]',$confhash{$itemid}{'lcauthparm'});
12066: }
12067: } else {
12068: $resulttext .= '; '.&mt('Kerberos domain: [_1]',$confhash{$itemid}{'lcauthparm'});
12069: }
12070: }
12071: $resulttext .= '</li>';
12072: } else {
12073: $resulttext .= '<li>'.&mt('User account creation not permitted.').'</li>';
12074: }
12075: }
12076: if (ref($confhash{$itemid}{'instdata'}) eq 'ARRAY') {
12077: if (@{$confhash{$itemid}{'instdata'}} > 0) {
12078: $resulttext .= '<li>'.&mt('Institutional data will be used when creating a new user for: [_1]',
12079: join(', ',map { $fieldtitles{$_}; } @{$confhash{$itemid}{'instdata'}})).'</li>';
12080: } else {
12081: $resulttext .= '<li>'.&mt('No institutional data used when creating a new user.').'</li>';
12082: }
12083: }
12084: if ($confhash{$itemid}{'mapcrs'}) {
12085: $resulttext .= '<li>'.&mt('Unique course identifier').': '.$confhash{$itemid}{'mapcrs'}.'</li>';
12086: }
12087: if (ref($confhash{$itemid}{'mapcrstype'}) eq 'ARRAY') {
12088: if (@{$confhash{$itemid}{'mapcrstype'}} > 0) {
12089: $resulttext .= '<li>'.&mt('Mapping for the following LON-CAPA course types: [_1]',
12090: join(', ',map { $coursetypetitles{$_}; } @coursetypes)).
12091: '</li>';
12092: } else {
12093: $resulttext .= '<li>'.&mt('No mapping to LON-CAPA courses').'</li>';
12094: }
12095: }
12096: if ($confhash{$itemid}{'makecrs'}) {
12097: $resulttext .= '<li>'.&mt('Instructor may create course (if absent).').'</li>';
12098: } else {
12099: $resulttext .= '<li>'.&mt('Instructor may not create course (if absent).').'</li>';
12100: }
12101: if (ref($confhash{$itemid}{'selfenroll'}) eq 'ARRAY') {
12102: if (@{$confhash{$itemid}{'selfenroll'}} > 0) {
12103: $resulttext .= '<li>'.&mt('Self-enrollment for following roles: [_1]',
12104: join(', ',@{$confhash{$itemid}{'selfenroll'}})).
12105: '</li>';
12106: } else {
12107: $resulttext .= '<li>'.&mt('Self-enrollment not permitted').'</li>';
12108: }
12109: }
12110: if ($confhash{$itemid}{'section'}) {
12111: if ($confhash{$itemid}{'section'} eq 'course_section_sourcedid') {
12112: $resulttext .= '<li>'.&mt('User section from standard field:').
12113: ' (course_section_sourcedid)'.'</li>';
12114: } else {
12115: $resulttext .= '<li>'.&mt('User section from:').' '.
12116: $confhash{$itemid}{'section'}.'</li>';
12117: }
12118: } else {
12119: $resulttext .= '<li>'.&mt('No section assignment').'</li>';
12120: }
12121: foreach my $item ('passback','roster','topmenu','inlinemenu') {
12122: $resulttext .= '<li>'.$lt{$item}.': ';
12123: if ($confhash{$itemid}{$item}) {
12124: $resulttext .= &mt('Yes');
12125: if ($item eq 'passback') {
12126: if ($confhash{$itemid}{'passbackformat'} eq '1.0') {
12127: $resulttext .= ' ('.&mt('Outcomes Extension (1.0)').')';
12128: } elsif ($confhash{$itemid}{'passbackformat'} eq '1.1') {
12129: $resulttext .= ' ('.&mt('Outcomes Service (1.1)').')';
12130: }
12131: }
12132: } else {
12133: $resulttext .= &mt('No');
12134: }
12135: $resulttext .= '</li>';
12136: }
12137: if (ref($confhash{$itemid}{'lcmenu'}) eq 'ARRAY') {
12138: if (@{$confhash{$itemid}{'lcmenu'}} > 0) {
12139: $resulttext .= '<li>'.&mt('Menu items:').' '.
12140: join(', ', map { $menutitles{$_}; } (@{$confhash{$itemid}{'lcmenu'}})).'</li>';
12141: } else {
12142: $resulttext .= '<li>'.&mt('No menu items displayed in header or online menu').'</li>';
12143: }
12144: }
12145: $resulttext .= '</ul></li>';
12146: }
12147: }
12148: $resulttext .= '</ul>';
12149: } else {
12150: $resulttext = &mt('No changes made.');
12151: }
12152: } else {
12153: $errors .= '<li><span class="LC_error">'.&mt('Failed to save changes').'</span></li>';
12154: }
12155: if ($errors) {
12156: $resulttext .= &mt('The following errors occurred: ').'<ul>'.
12157: $errors.'</ul>';
12158: }
12159: return $resulttext;
12160: }
12161:
12162: sub get_lti_id {
12163: my ($domain,$consumer) = @_;
12164: # get lock on lti db
12165: my $lockhash = {
12166: lock => $env{'user.name'}.
12167: ':'.$env{'user.domain'},
12168: };
12169: my $tries = 0;
12170: my $gotlock = &Apache::lonnet::newput_dom('lti',$lockhash,$domain);
12171: my ($id,$error);
12172:
12173: while (($gotlock ne 'ok') && ($tries<10)) {
12174: $tries ++;
12175: sleep (0.1);
12176: $gotlock = &Apache::lonnet::newput_dom('lti',$lockhash,$domain);
12177: }
12178: if ($gotlock eq 'ok') {
12179: my %currids = &Apache::lonnet::dump_dom('lti',$domain);
12180: if ($currids{'lock'}) {
12181: delete($currids{'lock'});
12182: if (keys(%currids)) {
12183: my @curr = sort { $a <=> $b } keys(%currids);
12184: if ($curr[-1] =~ /^\d+$/) {
12185: $id = 1 + $curr[-1];
12186: }
12187: } else {
12188: $id = 1;
12189: }
12190: if ($id) {
12191: unless (&Apache::lonnet::newput_dom('lti',{ $id => $consumer },$domain) eq 'ok') {
12192: $error = 'nostore';
12193: }
12194: } else {
12195: $error = 'nonumber';
12196: }
12197: }
12198: my $dellockoutcome = &Apache::lonnet::del_dom('lti',['lock'],$domain);
12199: } else {
12200: $error = 'nolock';
12201: }
12202: return ($id,$error);
12203: }
12204:
12205: sub modify_autoenroll {
12206: my ($dom,$lastactref,%domconfig) = @_;
12207: my ($resulttext,%changes);
12208: my %currautoenroll;
12209: if (ref($domconfig{'autoenroll'}) eq 'HASH') {
12210: foreach my $key (keys(%{$domconfig{'autoenroll'}})) {
12211: $currautoenroll{$key} = $domconfig{'autoenroll'}{$key};
12212: }
12213: }
12214: my $autorun = &Apache::lonnet::auto_run(undef,$dom),
12215: my %title = ( run => 'Auto-enrollment active',
12216: sender => 'Sender for notification messages',
12217: coowners => 'Automatic assignment of co-ownership to instructors of record (institutional data)',
12218: failsafe => 'Failsafe for no drops if institutional data missing for a section');
12219: my @offon = ('off','on');
12220: my $sender_uname = $env{'form.sender_uname'};
12221: my $sender_domain = $env{'form.sender_domain'};
12222: if ($sender_domain eq '') {
12223: $sender_uname = '';
12224: } elsif ($sender_uname eq '') {
12225: $sender_domain = '';
12226: }
12227: my $coowners = $env{'form.autoassign_coowners'};
12228: my $failsafe = $env{'form.autoenroll_failsafe'};
12229: $failsafe =~ s{^\s+|\s+$}{}g;
12230: if ($failsafe =~ /\D/) {
12231: undef($failsafe);
12232: }
12233: my %autoenrollhash = (
12234: autoenroll => { 'run' => $env{'form.autoenroll_run'},
12235: 'sender_uname' => $sender_uname,
12236: 'sender_domain' => $sender_domain,
12237: 'co-owners' => $coowners,
12238: 'autofailsafe' => $failsafe,
12239: }
12240: );
12241: my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash,
12242: $dom);
12243: if ($putresult eq 'ok') {
12244: if (exists($currautoenroll{'run'})) {
12245: if ($currautoenroll{'run'} ne $env{'form.autoenroll_run'}) {
12246: $changes{'run'} = 1;
12247: }
12248: } elsif ($autorun) {
12249: if ($env{'form.autoenroll_run'} ne '1') {
12250: $changes{'run'} = 1;
12251: }
12252: }
12253: if ($currautoenroll{'sender_uname'} ne $sender_uname) {
12254: $changes{'sender'} = 1;
12255: }
12256: if ($currautoenroll{'sender_domain'} ne $sender_domain) {
12257: $changes{'sender'} = 1;
12258: }
12259: if ($currautoenroll{'co-owners'} ne '') {
12260: if ($currautoenroll{'co-owners'} ne $coowners) {
12261: $changes{'coowners'} = 1;
12262: }
12263: } elsif ($coowners) {
12264: $changes{'coowners'} = 1;
12265: }
12266: if ($currautoenroll{'autofailsafe'} ne $failsafe) {
12267: $changes{'autofailsafe'} = 1;
12268: }
12269: if (keys(%changes) > 0) {
12270: $resulttext = &mt('Changes made:').'<ul>';
12271: if ($changes{'run'}) {
12272: $resulttext .= '<li>'.&mt("$title{'run'} set to $offon[$env{'form.autoenroll_run'}]").'</li>';
12273: }
12274: if ($changes{'sender'}) {
12275: if ($sender_uname eq '' || $sender_domain eq '') {
12276: $resulttext .= '<li>'.&mt("$title{'sender'} set to default (course owner).").'</li>';
12277: } else {
12278: $resulttext .= '<li>'.&mt("$title{'sender'} set to [_1]",$sender_uname.':'.$sender_domain).'</li>';
12279: }
12280: }
12281: if ($changes{'coowners'}) {
12282: $resulttext .= '<li>'.&mt("$title{'coowners'} set to $offon[$env{'form.autoassign_coowners'}]").'</li>';
12283: &Apache::loncommon::devalidate_domconfig_cache($dom);
12284: if (ref($lastactref) eq 'HASH') {
12285: $lastactref->{'domainconfig'} = 1;
12286: }
12287: }
12288: if ($changes{'autofailsafe'}) {
12289: if ($failsafe ne '') {
12290: $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section set to: [_1]',$failsafe).'</li>';
12291: } else {
12292: $resulttext .= '<li>'.&mt('Failsafe for no drops if institutional data missing for a section: deleted');
12293: }
12294: &Apache::lonnet::get_domain_defaults($dom,1);
12295: if (ref($lastactref) eq 'HASH') {
12296: $lastactref->{'domdefaults'} = 1;
12297: }
12298: }
12299: $resulttext .= '</ul>';
12300: } else {
12301: $resulttext = &mt('No changes made to auto-enrollment settings');
12302: }
12303: } else {
12304: $resulttext = '<span class="LC_error">'.
12305: &mt('An error occurred: [_1]',$putresult).'</span>';
12306: }
12307: return $resulttext;
12308: }
12309:
12310: sub modify_autoupdate {
12311: my ($dom,%domconfig) = @_;
12312: my ($resulttext,%currautoupdate,%fields,%changes);
12313: if (ref($domconfig{'autoupdate'}) eq 'HASH') {
12314: foreach my $key (keys(%{$domconfig{'autoupdate'}})) {
12315: $currautoupdate{$key} = $domconfig{'autoupdate'}{$key};
12316: }
12317: }
12318: my @offon = ('off','on');
12319: my %title = &Apache::lonlocal::texthash (
12320: run => 'Auto-update:',
12321: classlists => 'Updates to user information in classlists?'
12322: );
12323: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
12324: my %fieldtitles = &Apache::lonlocal::texthash (
12325: id => 'Student/Employee ID',
12326: permanentemail => 'E-mail address',
12327: lastname => 'Last Name',
12328: firstname => 'First Name',
12329: middlename => 'Middle Name',
12330: generation => 'Generation',
12331: );
12332: $othertitle = &mt('All users');
12333: if (keys(%{$usertypes}) > 0) {
12334: $othertitle = &mt('Other users');
12335: }
12336: foreach my $key (keys(%env)) {
12337: if ($key =~ /^form\.updateable_(.+)_([^_]+)$/) {
12338: my ($usertype,$item) = ($1,$2);
12339: if (grep(/^\Q$item\E$/,keys(%fieldtitles))) {
12340: if ($usertype eq 'default') {
12341: push(@{$fields{$1}},$2);
12342: } elsif (ref($types) eq 'ARRAY') {
12343: if (grep(/^\Q$usertype\E$/,@{$types})) {
12344: push(@{$fields{$1}},$2);
12345: }
12346: }
12347: }
12348: }
12349: }
12350: my @lockablenames = &Apache::loncommon::get_env_multiple('form.lockablenames');
12351: @lockablenames = sort(@lockablenames);
12352: if (ref($currautoupdate{'lockablenames'}) eq 'ARRAY') {
12353: my @changed = &Apache::loncommon::compare_arrays($currautoupdate{'lockablenames'},\@lockablenames);
12354: if (@changed) {
12355: $changes{'lockablenames'} = 1;
12356: }
12357: } else {
12358: if (@lockablenames) {
12359: $changes{'lockablenames'} = 1;
12360: }
12361: }
12362: my %updatehash = (
12363: autoupdate => { run => $env{'form.autoupdate_run'},
12364: classlists => $env{'form.classlists'},
12365: fields => {%fields},
12366: lockablenames => \@lockablenames,
12367: }
12368: );
12369: foreach my $key (keys(%currautoupdate)) {
12370: if (($key eq 'run') || ($key eq 'classlists')) {
12371: if (exists($updatehash{autoupdate}{$key})) {
12372: if ($currautoupdate{$key} ne $updatehash{autoupdate}{$key}) {
12373: $changes{$key} = 1;
12374: }
12375: }
12376: } elsif ($key eq 'fields') {
12377: if (ref($currautoupdate{$key}) eq 'HASH') {
12378: foreach my $item (@{$types},'default') {
12379: if (ref($currautoupdate{$key}{$item}) eq 'ARRAY') {
12380: my $change = 0;
12381: foreach my $type (@{$currautoupdate{$key}{$item}}) {
12382: if (!exists($fields{$item})) {
12383: $change = 1;
12384: last;
12385: } elsif (ref($fields{$item}) eq 'ARRAY') {
12386: if (!grep(/^\Q$type\E$/,@{$fields{$item}})) {
12387: $change = 1;
12388: last;
12389: }
12390: }
12391: }
12392: if ($change) {
12393: push(@{$changes{$key}},$item);
12394: }
12395: }
12396: }
12397: }
12398: } elsif ($key eq 'lockablenames') {
12399: if (ref($currautoupdate{$key}) eq 'ARRAY') {
12400: my @changed = &Apache::loncommon::compare_arrays($currautoupdate{'lockablenames'},\@lockablenames);
12401: if (@changed) {
12402: $changes{'lockablenames'} = 1;
12403: }
12404: } else {
12405: if (@lockablenames) {
12406: $changes{'lockablenames'} = 1;
12407: }
12408: }
12409: }
12410: }
12411: unless (grep(/^\Qlockablenames\E$/,keys(%currautoupdate))) {
12412: if (@lockablenames) {
12413: $changes{'lockablenames'} = 1;
12414: }
12415: }
12416: foreach my $item (@{$types},'default') {
12417: if (defined($fields{$item})) {
12418: if (ref($currautoupdate{'fields'}) eq 'HASH') {
12419: if (ref($currautoupdate{'fields'}{$item}) eq 'ARRAY') {
12420: my $change = 0;
12421: if (ref($fields{$item}) eq 'ARRAY') {
12422: foreach my $type (@{$fields{$item}}) {
12423: if (!grep(/^\Q$type\E$/,@{$currautoupdate{'fields'}{$item}})) {
12424: $change = 1;
12425: last;
12426: }
12427: }
12428: }
12429: if ($change) {
12430: push(@{$changes{'fields'}},$item);
12431: }
12432: } else {
12433: push(@{$changes{'fields'}},$item);
12434: }
12435: } else {
12436: push(@{$changes{'fields'}},$item);
12437: }
12438: }
12439: }
12440: my $putresult = &Apache::lonnet::put_dom('configuration',\%updatehash,
12441: $dom);
12442: if ($putresult eq 'ok') {
12443: if (keys(%changes) > 0) {
12444: $resulttext = &mt('Changes made:').'<ul>';
12445: foreach my $key (sort(keys(%changes))) {
12446: if ($key eq 'lockablenames') {
12447: $resulttext .= '<li>';
12448: if (@lockablenames) {
12449: $usertypes->{'default'} = $othertitle;
12450: $resulttext .= &mt("User preference to disable replacement of user's name with institutional data (by auto-update), available for the following affiliations:").' '.
12451: join(', ', map { $usertypes->{$_}; } @lockablenames).'</li>';
12452: } else {
12453: $resulttext .= &mt("User preference to disable replacement of user's name with institutional data (by auto-update) is unavailable.");
12454: }
12455: $resulttext .= '</li>';
12456: } elsif (ref($changes{$key}) eq 'ARRAY') {
12457: foreach my $item (@{$changes{$key}}) {
12458: my @newvalues;
12459: foreach my $type (@{$fields{$item}}) {
12460: push(@newvalues,$fieldtitles{$type});
12461: }
12462: my $newvaluestr;
12463: if (@newvalues > 0) {
12464: $newvaluestr = join(', ',@newvalues);
12465: } else {
12466: $newvaluestr = &mt('none');
12467: }
12468: if ($item eq 'default') {
12469: $resulttext .= '<li>'.&mt("Updates for '[_1]' set to: '[_2]'",$othertitle,$newvaluestr).'</li>';
12470: } else {
12471: $resulttext .= '<li>'.&mt("Updates for '[_1]' set to: '[_2]'",$usertypes->{$item},$newvaluestr).'</li>';
12472: }
12473: }
12474: } else {
12475: my $newvalue;
12476: if ($key eq 'run') {
12477: $newvalue = $offon[$env{'form.autoupdate_run'}];
12478: } else {
12479: $newvalue = $offon[$env{'form.'.$key}];
12480: }
12481: $resulttext .= '<li>'.&mt("[_1] set to $newvalue",$title{$key}).'</li>';
12482: }
12483: }
12484: $resulttext .= '</ul>';
12485: } else {
12486: $resulttext = &mt('No changes made to autoupdates');
12487: }
12488: } else {
12489: $resulttext = '<span class="LC_error">'.
12490: &mt('An error occurred: [_1]',$putresult).'</span>';
12491: }
12492: return $resulttext;
12493: }
12494:
12495: sub modify_autocreate {
12496: my ($dom,%domconfig) = @_;
12497: my ($resulttext,%changes,%currautocreate,%newvals,%autocreatehash);
12498: if (ref($domconfig{'autocreate'}) eq 'HASH') {
12499: foreach my $key (keys(%{$domconfig{'autocreate'}})) {
12500: $currautocreate{$key} = $domconfig{'autocreate'}{$key};
12501: }
12502: }
12503: my %title= ( xml => 'Auto-creation of courses in XML course description files',
12504: req => 'Auto-creation of validated requests for official courses',
12505: xmldc => 'Identity of course creator of courses from XML files',
12506: );
12507: my @types = ('xml','req');
12508: foreach my $item (@types) {
12509: $newvals{$item} = $env{'form.autocreate_'.$item};
12510: $newvals{$item} =~ s/\D//g;
12511: $newvals{$item} = 0 if ($newvals{$item} eq '');
12512: }
12513: $newvals{'xmldc'} = $env{'form.autocreate_xmldc'};
12514: my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);
12515: unless (exists($domcoords{$newvals{'xmldc'}})) {
12516: $newvals{'xmldc'} = '';
12517: }
12518: %autocreatehash = (
12519: autocreate => { xml => $newvals{'xml'},
12520: req => $newvals{'req'},
12521: }
12522: );
12523: if ($newvals{'xmldc'} ne '') {
12524: $autocreatehash{'autocreate'}{'xmldc'} = $newvals{'xmldc'};
12525: }
12526: my $putresult = &Apache::lonnet::put_dom('configuration',\%autocreatehash,
12527: $dom);
12528: if ($putresult eq 'ok') {
12529: my @items = @types;
12530: if ($newvals{'xml'}) {
12531: push(@items,'xmldc');
12532: }
12533: foreach my $item (@items) {
12534: if (exists($currautocreate{$item})) {
12535: if ($currautocreate{$item} ne $newvals{$item}) {
12536: $changes{$item} = 1;
12537: }
12538: } elsif ($newvals{$item}) {
12539: $changes{$item} = 1;
12540: }
12541: }
12542: if (keys(%changes) > 0) {
12543: my @offon = ('off','on');
12544: $resulttext = &mt('Changes made:').'<ul>';
12545: foreach my $item (@types) {
12546: if ($changes{$item}) {
12547: my $newtxt = $offon[$newvals{$item}];
12548: $resulttext .= '<li>'.
12549: &mt("$title{$item} set to [_1]$newtxt [_2]",
12550: '<b>','</b>').
12551: '</li>';
12552: }
12553: }
12554: if ($changes{'xmldc'}) {
12555: my ($dcname,$dcdom) = split(':',$newvals{'xmldc'});
12556: my $newtxt = &Apache::loncommon::plainname($dcname,$dcdom);
12557: $resulttext .= '<li>'.&mt("$title{'xmldc'} set to [_1]",'<b>'.$newtxt.'</b>').'</li>';
12558: }
12559: $resulttext .= '</ul>';
12560: } else {
12561: $resulttext = &mt('No changes made to auto-creation settings');
12562: }
12563: } else {
12564: $resulttext = '<span class="LC_error">'.
12565: &mt('An error occurred: [_1]',$putresult).'</span>';
12566: }
12567: return $resulttext;
12568: }
12569:
12570: sub modify_directorysrch {
12571: my ($dom,$lastactref,%domconfig) = @_;
12572: my ($resulttext,%changes);
12573: my %currdirsrch;
12574: if (ref($domconfig{'directorysrch'}) eq 'HASH') {
12575: foreach my $key (keys(%{$domconfig{'directorysrch'}})) {
12576: $currdirsrch{$key} = $domconfig{'directorysrch'}{$key};
12577: }
12578: }
12579: my %title = ( available => 'Institutional directory search available',
12580: localonly => 'Other domains can search institution',
12581: lcavailable => 'LON-CAPA directory search available',
12582: lclocalonly => 'Other domains can search LON-CAPA domain',
12583: searchby => 'Search types',
12584: searchtypes => 'Search latitude');
12585: my @offon = ('off','on');
12586: my @otherdoms = ('Yes','No');
12587:
12588: my @searchtypes = &Apache::loncommon::get_env_multiple('form.searchtypes');
12589: my @cansearch = &Apache::loncommon::get_env_multiple('form.cansearch');
12590: my @searchby = &Apache::loncommon::get_env_multiple('form.searchby');
12591:
12592: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
12593: if (keys(%{$usertypes}) == 0) {
12594: @cansearch = ('default');
12595: } else {
12596: if (ref($currdirsrch{'cansearch'}) eq 'ARRAY') {
12597: foreach my $type (@{$currdirsrch{'cansearch'}}) {
12598: if (!grep(/^\Q$type\E$/,@cansearch)) {
12599: push(@{$changes{'cansearch'}},$type);
12600: }
12601: }
12602: foreach my $type (@cansearch) {
12603: if (!grep(/^\Q$type\E$/,@{$currdirsrch{'cansearch'}})) {
12604: push(@{$changes{'cansearch'}},$type);
12605: }
12606: }
12607: } else {
12608: push(@{$changes{'cansearch'}},@cansearch);
12609: }
12610: }
12611:
12612: if (ref($currdirsrch{'searchby'}) eq 'ARRAY') {
12613: foreach my $by (@{$currdirsrch{'searchby'}}) {
12614: if (!grep(/^\Q$by\E$/,@searchby)) {
12615: push(@{$changes{'searchby'}},$by);
12616: }
12617: }
12618: foreach my $by (@searchby) {
12619: if (!grep(/^\Q$by\E$/,@{$currdirsrch{'searchby'}})) {
12620: push(@{$changes{'searchby'}},$by);
12621: }
12622: }
12623: } else {
12624: push(@{$changes{'searchby'}},@searchby);
12625: }
12626:
12627: if (ref($currdirsrch{'searchtypes'}) eq 'ARRAY') {
12628: foreach my $type (@{$currdirsrch{'searchtypes'}}) {
12629: if (!grep(/^\Q$type\E$/,@searchtypes)) {
12630: push(@{$changes{'searchtypes'}},$type);
12631: }
12632: }
12633: foreach my $type (@searchtypes) {
12634: if (!grep(/^\Q$type\E$/,@{$currdirsrch{'searchtypes'}})) {
12635: push(@{$changes{'searchtypes'}},$type);
12636: }
12637: }
12638: } else {
12639: if (exists($currdirsrch{'searchtypes'})) {
12640: foreach my $type (@searchtypes) {
12641: if ($type ne $currdirsrch{'searchtypes'}) {
12642: push(@{$changes{'searchtypes'}},$type);
12643: }
12644: }
12645: if (!grep(/^\Q$currdirsrch{'searchtypes'}\E/,@searchtypes)) {
12646: push(@{$changes{'searchtypes'}},$currdirsrch{'searchtypes'});
12647: }
12648: } else {
12649: push(@{$changes{'searchtypes'}},@searchtypes);
12650: }
12651: }
12652:
12653: my %dirsrch_hash = (
12654: directorysrch => { available => $env{'form.dirsrch_available'},
12655: cansearch => \@cansearch,
12656: localonly => $env{'form.dirsrch_instlocalonly'},
12657: lclocalonly => $env{'form.dirsrch_domlocalonly'},
12658: lcavailable => $env{'form.dirsrch_domavailable'},
12659: searchby => \@searchby,
12660: searchtypes => \@searchtypes,
12661: }
12662: );
12663: my $putresult = &Apache::lonnet::put_dom('configuration',\%dirsrch_hash,
12664: $dom);
12665: if ($putresult eq 'ok') {
12666: if (exists($currdirsrch{'available'})) {
12667: if ($currdirsrch{'available'} ne $env{'form.dirsrch_available'}) {
12668: $changes{'available'} = 1;
12669: }
12670: } else {
12671: if ($env{'form.dirsrch_available'} eq '1') {
12672: $changes{'available'} = 1;
12673: }
12674: }
12675: if (exists($currdirsrch{'lcavailable'})) {
12676: if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) {
12677: $changes{'lcavailable'} = 1;
12678: }
12679: } else {
12680: if ($env{'form.dirsrch_lcavailable'} eq '1') {
12681: $changes{'lcavailable'} = 1;
12682: }
12683: }
12684: if (exists($currdirsrch{'localonly'})) {
12685: if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) {
12686: $changes{'localonly'} = 1;
12687: }
12688: } else {
12689: if ($env{'form.dirsrch_instlocalonly'} eq '1') {
12690: $changes{'localonly'} = 1;
12691: }
12692: }
12693: if (exists($currdirsrch{'lclocalonly'})) {
12694: if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) {
12695: $changes{'lclocalonly'} = 1;
12696: }
12697: } else {
12698: if ($env{'form.dirsrch_domlocalonly'} eq '1') {
12699: $changes{'lclocalonly'} = 1;
12700: }
12701: }
12702: if (keys(%changes) > 0) {
12703: $resulttext = &mt('Changes made:').'<ul>';
12704: if ($changes{'available'}) {
12705: $resulttext .= '<li>'.&mt("$title{'available'} set to: $offon[$env{'form.dirsrch_available'}]").'</li>';
12706: }
12707: if ($changes{'lcavailable'}) {
12708: $resulttext .= '<li>'.&mt("$title{'lcavailable'} set to: $offon[$env{'form.dirsrch_domavailable'}]").'</li>';
12709: }
12710: if ($changes{'localonly'}) {
12711: $resulttext .= '<li>'.&mt("$title{'localonly'} set to: $otherdoms[$env{'form.dirsrch_instlocalonly'}]").'</li>';
12712: }
12713: if ($changes{'lclocalonly'}) {
12714: $resulttext .= '<li>'.&mt("$title{'lclocalonly'} set to: $otherdoms[$env{'form.dirsrch_domlocalonly'}]").'</li>';
12715: }
12716: if (ref($changes{'cansearch'}) eq 'ARRAY') {
12717: my $chgtext;
12718: if (ref($usertypes) eq 'HASH') {
12719: if (keys(%{$usertypes}) > 0) {
12720: foreach my $type (@{$types}) {
12721: if (grep(/^\Q$type\E$/,@cansearch)) {
12722: $chgtext .= $usertypes->{$type}.'; ';
12723: }
12724: }
12725: if (grep(/^default$/,@cansearch)) {
12726: $chgtext .= $othertitle;
12727: } else {
12728: $chgtext =~ s/\; $//;
12729: }
12730: $resulttext .=
12731: '<li>'.
12732: &mt("Users from domain '[_1]' permitted to search the institutional directory set to: [_2]",
12733: '<span class="LC_cusr_emph">'.$dom.'</span>',$chgtext).
12734: '</li>';
12735: }
12736: }
12737: }
12738: if (ref($changes{'searchby'}) eq 'ARRAY') {
12739: my ($searchtitles,$titleorder) = &sorted_searchtitles();
12740: my $chgtext;
12741: foreach my $type (@{$titleorder}) {
12742: if (grep(/^\Q$type\E$/,@searchby)) {
12743: if (defined($searchtitles->{$type})) {
12744: $chgtext .= $searchtitles->{$type}.'; ';
12745: }
12746: }
12747: }
12748: $chgtext =~ s/\; $//;
12749: $resulttext .= '<li>'.&mt("$title{'searchby'} set to: [_1]",$chgtext).'</li>';
12750: }
12751: if (ref($changes{'searchtypes'}) eq 'ARRAY') {
12752: my ($srchtypes_desc,$srchtypeorder) = &sorted_searchtypes();
12753: my $chgtext;
12754: foreach my $type (@{$srchtypeorder}) {
12755: if (grep(/^\Q$type\E$/,@searchtypes)) {
12756: if (defined($srchtypes_desc->{$type})) {
12757: $chgtext .= $srchtypes_desc->{$type}.'; ';
12758: }
12759: }
12760: }
12761: $chgtext =~ s/\; $//;
12762: $resulttext .= '<li>'.&mt($title{'searchtypes'}.' set to: "[_1]"',$chgtext).'</li>';
12763: }
12764: $resulttext .= '</ul>';
12765: &Apache::lonnet::do_cache_new('directorysrch',$dom,$dirsrch_hash{'directorysrch'},3600);
12766: if (ref($lastactref) eq 'HASH') {
12767: $lastactref->{'directorysrch'} = 1;
12768: }
12769: } else {
12770: $resulttext = &mt('No changes made to directory search settings');
12771: }
12772: } else {
12773: $resulttext = '<span class="LC_error">'.
12774: &mt('An error occurred: [_1]',$putresult).'</span>';
12775: }
12776: return $resulttext;
12777: }
12778:
12779: sub modify_contacts {
12780: my ($dom,$lastactref,%domconfig) = @_;
12781: my ($resulttext,%currsetting,%newsetting,%changes,%contacts_hash);
12782: if (ref($domconfig{'contacts'}) eq 'HASH') {
12783: foreach my $key (keys(%{$domconfig{'contacts'}})) {
12784: $currsetting{$key} = $domconfig{'contacts'}{$key};
12785: }
12786: }
12787: my (%others,%to,%bcc,%includestr,%includeloc);
12788: my @contacts = ('supportemail','adminemail');
12789: my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail',
12790: 'lonstatusmail','requestsmail','updatesmail','idconflictsmail');
12791: my @toggles = ('reporterrors','reportupdates','reportstatus');
12792: my @lonstatus = ('threshold','sysmail','weights','excluded');
12793: my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();
12794: foreach my $type (@mailings) {
12795: @{$newsetting{$type}} =
12796: &Apache::loncommon::get_env_multiple('form.'.$type);
12797: foreach my $item (@contacts) {
12798: if (grep(/^\Q$item\E$/,@{$newsetting{$type}})) {
12799: $contacts_hash{contacts}{$type}{$item} = 1;
12800: } else {
12801: $contacts_hash{contacts}{$type}{$item} = 0;
12802: }
12803: }
12804: $others{$type} = $env{'form.'.$type.'_others'};
12805: $contacts_hash{contacts}{$type}{'others'} = $others{$type};
12806: if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
12807: $bcc{$type} = $env{'form.'.$type.'_bcc'};
12808: $contacts_hash{contacts}{$type}{'bcc'} = $bcc{$type};
12809: if (($env{'form.'.$type.'_includestr'} ne '') && ($env{'form.'.$type.'_includeloc'} =~ /^s|b$/)) {
12810: $includestr{$type} = $env{'form.'.$type.'_includestr'};
12811: $includeloc{$type} = $env{'form.'.$type.'_includeloc'};
12812: $contacts_hash{contacts}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});
12813: }
12814: }
12815: }
12816: foreach my $item (@contacts) {
12817: $to{$item} = $env{'form.'.$item};
12818: $contacts_hash{'contacts'}{$item} = $to{$item};
12819: }
12820: foreach my $item (@toggles) {
12821: if ($env{'form.'.$item} =~ /^(0|1)$/) {
12822: $contacts_hash{'contacts'}{$item} = $env{'form.'.$item};
12823: }
12824: }
12825: my ($lonstatus_defs,$lonstatus_names) = &Apache::loncommon::lon_status_items();
12826: foreach my $item (@lonstatus) {
12827: if ($item eq 'excluded') {
12828: my (%serverhomes,@excluded);
12829: map { $serverhomes{$_} = 1; } values(%Apache::lonnet::serverhomeIDs);
12830: my @possexcluded = &Apache::loncommon::get_env_multiple('form.errorexcluded');
12831: if (@possexcluded) {
12832: foreach my $id (sort(@possexcluded)) {
12833: if ($serverhomes{$id}) {
12834: push(@excluded,$id);
12835: }
12836: }
12837: }
12838: if (@excluded) {
12839: $contacts_hash{'contacts'}{'lonstatus'}{$item} = \@excluded;
12840: }
12841: } elsif ($item eq 'weights') {
12842: foreach my $type ('E','W','N') {
12843: $env{'form.error'.$item.'_'.$type} =~ s/^\s+|\s+$//g;
12844: if ($env{'form.error'.$item.'_'.$type} =~ /^\d+$/) {
12845: unless ($env{'form.error'.$item.'_'.$type} == $lonstatus_defs->{$type}) {
12846: $contacts_hash{'contacts'}{'lonstatus'}{$item}{$type} =
12847: $env{'form.error'.$item.'_'.$type};
12848: }
12849: }
12850: }
12851: } elsif (($item eq 'threshold') || ($item eq 'sysmail')) {
12852: $env{'form.error'.$item} =~ s/^\s+|\s+$//g;
12853: if ($env{'form.error'.$item} =~ /^\d+$/) {
12854: unless ($env{'form.error'.$item} == $lonstatus_defs->{$item}) {
12855: $contacts_hash{'contacts'}{'lonstatus'}{$item} = $env{'form.error'.$item};
12856: }
12857: }
12858: }
12859: }
12860: if ((ref($fields) eq 'ARRAY') && (ref($possoptions) eq 'HASH')) {
12861: foreach my $field (@{$fields}) {
12862: if (ref($possoptions->{$field}) eq 'ARRAY') {
12863: my $value = $env{'form.helpform_'.$field};
12864: $value =~ s/^\s+|\s+$//g;
12865: if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) {
12866: $contacts_hash{'contacts'}{'helpform'}{$field} = $value;
12867: if ($field eq 'screenshot') {
12868: $env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g;
12869: if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) {
12870: $contacts_hash{'contacts'}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'};
12871: }
12872: }
12873: }
12874: }
12875: }
12876: }
12877: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
12878: my (@statuses,%usertypeshash,@overrides);
12879: if ((ref($types) eq 'ARRAY') && (@{$types} > 0)) {
12880: @statuses = @{$types};
12881: if (ref($usertypes) eq 'HASH') {
12882: %usertypeshash = %{$usertypes};
12883: }
12884: }
12885: if (@statuses) {
12886: my @possoverrides = &Apache::loncommon::get_env_multiple('form.overrides');
12887: foreach my $type (@possoverrides) {
12888: if (($type ne '') && (grep(/^\Q$type\E$/,@statuses))) {
12889: push(@overrides,$type);
12890: }
12891: }
12892: if (@overrides) {
12893: foreach my $type (@overrides) {
12894: my @standard = &Apache::loncommon::get_env_multiple('form.override_'.$type);
12895: foreach my $item (@contacts) {
12896: if (grep(/^\Q$item\E$/,@standard)) {
12897: $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 1;
12898: $newsetting{'override_'.$type}{$item} = 1;
12899: } else {
12900: $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 0;
12901: $newsetting{'override_'.$type}{$item} = 0;
12902: }
12903: }
12904: $contacts_hash{'contacts'}{'overrides'}{$type}{'others'} = $env{'form.override_'.$type.'_others'};
12905: $contacts_hash{'contacts'}{'overrides'}{$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};
12906: $newsetting{'override_'.$type}{'others'} = $env{'form.override_'.$type.'_others'};
12907: $newsetting{'override_'.$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'};
12908: if (($env{'form.override_'.$type.'_includestr'} ne '') && ($env{'form.override_'.$type.'_includeloc'} =~ /^s|b$/)) {
12909: $includestr{$type} = $env{'form.override_'.$type.'_includestr'};
12910: $includeloc{$type} = $env{'form.override_'.$type.'_includeloc'};
12911: $contacts_hash{'contacts'}{'overrides'}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type});
12912: $newsetting{'override_'.$type}{'include'} = $contacts_hash{'contacts'}{'overrides'}{$type}{'include'};
12913: }
12914: }
12915: }
12916: }
12917: if (keys(%currsetting) > 0) {
12918: foreach my $item (@contacts) {
12919: if ($to{$item} ne $currsetting{$item}) {
12920: $changes{$item} = 1;
12921: }
12922: }
12923: foreach my $type (@mailings) {
12924: foreach my $item (@contacts) {
12925: if (ref($currsetting{$type}) eq 'HASH') {
12926: if ($currsetting{$type}{$item} ne $contacts_hash{contacts}{$type}{$item}) {
12927: push(@{$changes{$type}},$item);
12928: }
12929: } else {
12930: push(@{$changes{$type}},@{$newsetting{$type}});
12931: }
12932: }
12933: if ($others{$type} ne $currsetting{$type}{'others'}) {
12934: push(@{$changes{$type}},'others');
12935: }
12936: if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
12937: if ($bcc{$type} ne $currsetting{$type}{'bcc'}) {
12938: push(@{$changes{$type}},'bcc');
12939: }
12940: my ($currloc,$currstr) = split(/:/,$currsetting{$type}{'include'},2);
12941: if (($includeloc{$type} ne $currloc) || (&escape($includestr{$type}) ne $currstr)) {
12942: push(@{$changes{$type}},'include');
12943: }
12944: }
12945: }
12946: if (ref($fields) eq 'ARRAY') {
12947: if (ref($currsetting{'helpform'}) eq 'HASH') {
12948: foreach my $field (@{$fields}) {
12949: if ($currsetting{'helpform'}{$field} ne $contacts_hash{'contacts'}{'helpform'}{$field}) {
12950: push(@{$changes{'helpform'}},$field);
12951: }
12952: if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {
12953: if ($currsetting{'helpform'}{'maxsize'} ne $contacts_hash{'contacts'}{'helpform'}{'maxsize'}) {
12954: push(@{$changes{'helpform'}},'maxsize');
12955: }
12956: }
12957: }
12958: } else {
12959: foreach my $field (@{$fields}) {
12960: if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') {
12961: push(@{$changes{'helpform'}},$field);
12962: }
12963: if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {
12964: if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) {
12965: push(@{$changes{'helpform'}},'maxsize');
12966: }
12967: }
12968: }
12969: }
12970: }
12971: if (@statuses) {
12972: if (ref($currsetting{'overrides'}) eq 'HASH') {
12973: foreach my $key (keys(%{$currsetting{'overrides'}})) {
12974: if (ref($currsetting{'overrides'}{$key}) eq 'HASH') {
12975: if (ref($newsetting{'override_'.$key}) eq 'HASH') {
12976: foreach my $item (@contacts,'bcc','others','include') {
12977: if ($currsetting{'overrides'}{$key}{$item} ne $newsetting{'override_'.$key}{$item}) {
12978: push(@{$changes{'overrides'}},$key);
12979: last;
12980: }
12981: }
12982: } else {
12983: push(@{$changes{'overrides'}},$key);
12984: }
12985: }
12986: }
12987: foreach my $key (@overrides) {
12988: unless (exists($currsetting{'overrides'}{$key})) {
12989: push(@{$changes{'overrides'}},$key);
12990: }
12991: }
12992: } else {
12993: foreach my $key (@overrides) {
12994: push(@{$changes{'overrides'}},$key);
12995: }
12996: }
12997: }
12998: if (ref($currsetting{'lonstatus'}) eq 'HASH') {
12999: foreach my $key ('excluded','weights','threshold','sysmail') {
13000: if ($key eq 'excluded') {
13001: if ((ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') &&
13002: (ref($contacts_hash{contacts}{lonstatus}{excluded}) eq 'ARRAY')) {
13003: if ((ref($currsetting{'lonstatus'}{$key}) eq 'ARRAY') &&
13004: (@{$currsetting{'lonstatus'}{$key}})) {
13005: my @diffs =
13006: &Apache::loncommon::compare_arrays($contacts_hash{contacts}{lonstatus}{excluded},
13007: $currsetting{'lonstatus'}{$key});
13008: if (@diffs) {
13009: push(@{$changes{'lonstatus'}},$key);
13010: }
13011: } elsif (@{$contacts_hash{contacts}{lonstatus}{excluded}}) {
13012: push(@{$changes{'lonstatus'}},$key);
13013: }
13014: } elsif ((ref($currsetting{'lonstatus'}{$key}) eq 'ARRAY') &&
13015: (@{$currsetting{'lonstatus'}{$key}})) {
13016: push(@{$changes{'lonstatus'}},$key);
13017: }
13018: } elsif ($key eq 'weights') {
13019: if ((ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') &&
13020: (ref($contacts_hash{contacts}{lonstatus}{$key}) eq 'HASH')) {
13021: if (ref($currsetting{'lonstatus'}{$key}) eq 'HASH') {
13022: foreach my $type ('E','W','N','U') {
13023: unless ($contacts_hash{contacts}{lonstatus}{$key}{$type} eq
13024: $currsetting{'lonstatus'}{$key}{$type}) {
13025: push(@{$changes{'lonstatus'}},$key);
13026: last;
13027: }
13028: }
13029: } else {
13030: foreach my $type ('E','W','N','U') {
13031: if ($contacts_hash{contacts}{lonstatus}{$key}{$type} ne '') {
13032: push(@{$changes{'lonstatus'}},$key);
13033: last;
13034: }
13035: }
13036: }
13037: } elsif (ref($currsetting{'lonstatus'}{$key}) eq 'HASH') {
13038: foreach my $type ('E','W','N','U') {
13039: if ($currsetting{'lonstatus'}{$key}{$type} ne '') {
13040: push(@{$changes{'lonstatus'}},$key);
13041: last;
13042: }
13043: }
13044: }
13045: } elsif (($key eq 'threshold') || ($key eq 'sysmail')) {
13046: if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') {
13047: if ($currsetting{'lonstatus'}{$key} =~ /^\d+$/) {
13048: if ($currsetting{'lonstatus'}{$key} != $contacts_hash{contacts}{lonstatus}{$key}) {
13049: push(@{$changes{'lonstatus'}},$key);
13050: }
13051: } elsif ($contacts_hash{contacts}{lonstatus}{$key} =~ /^\d+$/) {
13052: push(@{$changes{'lonstatus'}},$key);
13053: }
13054: } elsif ($currsetting{'lonstatus'}{$key} =~ /^\d+$/) {
13055: push(@{$changes{'lonstatus'}},$key);
13056: }
13057: }
13058: }
13059: } else {
13060: if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') {
13061: foreach my $key ('excluded','weights','threshold','sysmail') {
13062: if (exists($contacts_hash{contacts}{lonstatus}{$key})) {
13063: push(@{$changes{'lonstatus'}},$key);
13064: }
13065: }
13066: }
13067: }
13068: } else {
13069: my %default;
13070: $default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
13071: $default{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};
13072: $default{'errormail'} = 'adminemail';
13073: $default{'packagesmail'} = 'adminemail';
13074: $default{'helpdeskmail'} = 'supportemail';
13075: $default{'otherdomsmail'} = 'supportemail';
13076: $default{'lonstatusmail'} = 'adminemail';
13077: $default{'requestsmail'} = 'adminemail';
13078: $default{'updatesmail'} = 'adminemail';
13079: foreach my $item (@contacts) {
13080: if ($to{$item} ne $default{$item}) {
13081: $changes{$item} = 1;
13082: }
13083: }
13084: foreach my $type (@mailings) {
13085: if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) {
13086: push(@{$changes{$type}},@{$newsetting{$type}});
13087: }
13088: if ($others{$type} ne '') {
13089: push(@{$changes{$type}},'others');
13090: }
13091: if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
13092: if ($bcc{$type} ne '') {
13093: push(@{$changes{$type}},'bcc');
13094: }
13095: if (($includeloc{$type} =~ /^b|s$/) && ($includestr{$type} ne '')) {
13096: push(@{$changes{$type}},'include');
13097: }
13098: }
13099: }
13100: if (ref($fields) eq 'ARRAY') {
13101: foreach my $field (@{$fields}) {
13102: if ($contacts_hash{'contacts'}{'helpform'}{$field} ne 'yes') {
13103: push(@{$changes{'helpform'}},$field);
13104: }
13105: if (($field eq 'screenshot') && ($contacts_hash{'contacts'}{'helpform'}{'screenshot'} ne 'no')) {
13106: if ($contacts_hash{'contacts'}{'helpform'}{'maxsize'} != 1) {
13107: push(@{$changes{'helpform'}},'maxsize');
13108: }
13109: }
13110: }
13111: }
13112: if (ref($contacts_hash{contacts}{lonstatus}) eq 'HASH') {
13113: foreach my $key ('excluded','weights','threshold','sysmail') {
13114: if (exists($contacts_hash{contacts}{lonstatus}{$key})) {
13115: push(@{$changes{'lonstatus'}},$key);
13116: }
13117: }
13118: }
13119: }
13120: foreach my $item (@toggles) {
13121: if (($env{'form.'.$item} == 1) && ($currsetting{$item} == 0)) {
13122: $changes{$item} = 1;
13123: } elsif ((!$env{'form.'.$item}) &&
13124: (($currsetting{$item} eq '') || ($currsetting{$item} == 1))) {
13125: $changes{$item} = 1;
13126: }
13127: }
13128: my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash,
13129: $dom);
13130: if ($putresult eq 'ok') {
13131: if (keys(%changes) > 0) {
13132: &Apache::loncommon::devalidate_domconfig_cache($dom);
13133: if (ref($lastactref) eq 'HASH') {
13134: $lastactref->{'domainconfig'} = 1;
13135: }
13136: my ($titles,$short_titles) = &contact_titles();
13137: $resulttext = &mt('Changes made:').'<ul>';
13138: foreach my $item (@contacts) {
13139: if ($changes{$item}) {
13140: $resulttext .= '<li>'.$titles->{$item}.
13141: &mt(' set to: ').
13142: '<span class="LC_cusr_emph">'.
13143: $to{$item}.'</span></li>';
13144: }
13145: }
13146: foreach my $type (@mailings) {
13147: if (ref($changes{$type}) eq 'ARRAY') {
13148: if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
13149: $resulttext .= '<li>'.$titles->{$type}.' -- '.&mt('sent to').': ';
13150: } else {
13151: $resulttext .= '<li>'.$titles->{$type}.': ';
13152: }
13153: my @text;
13154: foreach my $item (@{$newsetting{$type}}) {
13155: push(@text,$short_titles->{$item});
13156: }
13157: if ($others{$type} ne '') {
13158: push(@text,$others{$type});
13159: }
13160: if (@text) {
13161: $resulttext .= '<span class="LC_cusr_emph">'.
13162: join(', ',@text).'</span>';
13163: }
13164: if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
13165: if ($bcc{$type} ne '') {
13166: my $bcctext;
13167: if (@text) {
13168: $bcctext = ' '.&mt('with Bcc to');
13169: } else {
13170: $bcctext = '(Bcc)';
13171: }
13172: $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>';
13173: } elsif (!@text) {
13174: $resulttext .= &mt('No one');
13175: }
13176: if ($includestr{$type} ne '') {
13177: if ($includeloc{$type} eq 'b') {
13178: $resulttext .= '<br />'.&mt('Text automatically added to e-mail body:').' '.$includestr{$type};
13179: } elsif ($includeloc{$type} eq 's') {
13180: $resulttext .= '<br />'.&mt('Text automatically added to e-mail subject:').' '.$includestr{$type};
13181: }
13182: }
13183: } elsif (!@text) {
13184: $resulttext .= &mt('No recipients');
13185: }
13186: $resulttext .= '</li>';
13187: }
13188: }
13189: if (ref($changes{'overrides'}) eq 'ARRAY') {
13190: my @deletions;
13191: foreach my $type (@{$changes{'overrides'}}) {
13192: if ($usertypeshash{$type}) {
13193: if (grep(/^\Q$type\E/,@overrides)) {
13194: $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation set for [_1]",
13195: $usertypeshash{$type}).'<ul><li>';
13196: if (ref($newsetting{'override_'.$type}) eq 'HASH') {
13197: my @text;
13198: foreach my $item (@contacts) {
13199: if ($newsetting{'override_'.$type}{$item}) {
13200: push(@text,$short_titles->{$item});
13201: }
13202: }
13203: if ($newsetting{'override_'.$type}{'others'} ne '') {
13204: push(@text,$newsetting{'override_'.$type}{'others'});
13205: }
13206:
13207: if (@text) {
13208: $resulttext .= &mt('Helpdesk e-mail sent to: [_1]',
13209: '<span class="LC_cusr_emph">'.join(', ',@text).'</span>');
13210: }
13211: if ($newsetting{'override_'.$type}{'bcc'} ne '') {
13212: my $bcctext;
13213: if (@text) {
13214: $bcctext = ' '.&mt('with Bcc to');
13215: } else {
13216: $bcctext = '(Bcc)';
13217: }
13218: $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$newsetting{'override_'.$type}{'bcc'}.'</span>';
13219: } elsif (!@text) {
13220: $resulttext .= &mt('Helpdesk e-mail sent to no one');
13221: }
13222: $resulttext .= '</li>';
13223: if ($newsetting{'override_'.$type}{'include'} ne '') {
13224: my ($loc,$str) = split(/:/,$newsetting{'override_'.$type}{'include'});
13225: if ($loc eq 'b') {
13226: $resulttext .= '<li>'.&mt('Text automatically added to e-mail body:').' '.&unescape($str).'</li>';
13227: } elsif ($loc eq 's') {
13228: $resulttext .= '<li>'.&mt('Text automatically added to e-mail subject:').' '.&unescape($str).'</li>';
13229: }
13230: }
13231: }
13232: $resulttext .= '</li></ul></li>';
13233: } else {
13234: push(@deletions,$usertypeshash{$type});
13235: }
13236: }
13237: }
13238: if (@deletions) {
13239: $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation discontinued for: [_1]",
13240: join(', ',@deletions)).'</li>';
13241: }
13242: }
13243: my @offon = ('off','on');
13244: my $corelink = &core_link_msu();
13245: if ($changes{'reporterrors'}) {
13246: $resulttext .= '<li>'.
13247: &mt('E-mail error reports to [_1] set to "'.
13248: $offon[$env{'form.reporterrors'}].'".',
13249: $corelink).
13250: '</li>';
13251: }
13252: if ($changes{'reportupdates'}) {
13253: $resulttext .= '<li>'.
13254: &mt('E-mail record of completed LON-CAPA updates to [_1] set to "'.
13255: $offon[$env{'form.reportupdates'}].'".',
13256: $corelink).
13257: '</li>';
13258: }
13259: if ($changes{'reportstatus'}) {
13260: $resulttext .= '<li>'.
13261: &mt('E-mail status if errors above threshold to [_1] set to "'.
13262: $offon[$env{'form.reportstatus'}].'".',
13263: $corelink).
13264: '</li>';
13265: }
13266: if (ref($changes{'lonstatus'}) eq 'ARRAY') {
13267: $resulttext .= '<li>'.
13268: &mt('Nightly status check e-mail settings').':<ul>';
13269: my (%defval,%use_def,%shown);
13270: $defval{'threshold'} = $lonstatus_defs->{'threshold'};
13271: $defval{'sysmail'} = $lonstatus_defs->{'sysmail'};
13272: $defval{'weights'} =
13273: join(', ',map { $lonstatus_names->{$_}.'='.$lonstatus_defs->{$_}; } ('E','W','N','U'));
13274: $defval{'excluded'} = &mt('None');
13275: if (ref($contacts_hash{'contacts'}{'lonstatus'}) eq 'HASH') {
13276: foreach my $item ('threshold','sysmail','weights','excluded') {
13277: if (exists($contacts_hash{'contacts'}{'lonstatus'}{$item})) {
13278: if (($item eq 'threshold') || ($item eq 'sysmail')) {
13279: $shown{$item} = $contacts_hash{'contacts'}{'lonstatus'}{$item};
13280: } elsif ($item eq 'weights') {
13281: if (ref($contacts_hash{'contacts'}{'lonstatus'}{$item}) eq 'HASH') {
13282: foreach my $type ('E','W','N','U') {
13283: $shown{$item} .= $lonstatus_names->{$type}.'=';
13284: if (exists($contacts_hash{'contacts'}{'lonstatus'}{$item}{$type})) {
13285: $shown{$item} .= $contacts_hash{'contacts'}{'lonstatus'}{$item}{$type};
13286: } else {
13287: $shown{$item} .= $lonstatus_defs->{$type};
13288: }
13289: $shown{$item} .= ', ';
13290: }
13291: $shown{$item} =~ s/, $//;
13292: } else {
13293: $shown{$item} = $defval{$item};
13294: }
13295: } elsif ($item eq 'excluded') {
13296: if (ref($contacts_hash{'contacts'}{'lonstatus'}{$item}) eq 'ARRAY') {
13297: $shown{$item} = join(', ',@{$contacts_hash{'contacts'}{'lonstatus'}{$item}});
13298: } else {
13299: $shown{$item} = $defval{$item};
13300: }
13301: }
13302: } else {
13303: $shown{$item} = $defval{$item};
13304: }
13305: }
13306: } else {
13307: foreach my $item ('threshold','weights','excluded','sysmail') {
13308: $shown{$item} = $defval{$item};
13309: }
13310: }
13311: foreach my $item ('threshold','weights','excluded','sysmail') {
13312: $resulttext .= '<li>'.&mt($titles->{'error'.$item}.' -- [_1]',
13313: $shown{$item}).'</li>';
13314: }
13315: $resulttext .= '</ul></li>';
13316: }
13317: if ((ref($changes{'helpform'}) eq 'ARRAY') && (ref($fields) eq 'ARRAY')) {
13318: my (@optional,@required,@unused,$maxsizechg);
13319: foreach my $field (@{$changes{'helpform'}}) {
13320: if ($field eq 'maxsize') {
13321: $maxsizechg = 1;
13322: next;
13323: }
13324: if ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'yes') {
13325: push(@optional,$field);
13326: } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'no') {
13327: push(@unused,$field);
13328: } elsif ($contacts_hash{'contacts'}{'helpform'}{$field} eq 'req') {
13329: push(@required,$field);
13330: }
13331: }
13332: if (@optional) {
13333: $resulttext .= '<li>'.
13334: &mt('Help form fields changed to "Optional": [_1].',
13335: '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @optional)).'</span>'.
13336: '</li>';
13337: }
13338: if (@required) {
13339: $resulttext .= '<li>'.
13340: &mt('Help form fields changed to "Required": [_1].',
13341: '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @required)).'</span>'.
13342: '</li>';
13343: }
13344: if (@unused) {
13345: $resulttext .= '<li>'.
13346: &mt('Help form fields changed to "Not shown": [_1].',
13347: '<span class="LC_cusr_emph">'.join(', ',map { $fieldtitles->{$_}; } @unused)).'</span>'.
13348: '</li>';
13349: }
13350: if ($maxsizechg) {
13351: $resulttext .= '<li>'.
13352: &mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.',
13353: $contacts_hash{'contacts'}{'helpform'}{'maxsize'}).
13354: '</li>';
13355: }
13356: }
13357: $resulttext .= '</ul>';
13358: } else {
13359: $resulttext = &mt('No changes made to contacts and form settings');
13360: }
13361: } else {
13362: $resulttext = '<span class="LC_error">'.
13363: &mt('An error occurred: [_1].',$putresult).'</span>';
13364: }
13365: return $resulttext;
13366: }
13367:
13368: sub modify_usercreation {
13369: my ($dom,%domconfig) = @_;
13370: my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate,%save_usercreate);
13371: my $warningmsg;
13372: if (ref($domconfig{'usercreation'}) eq 'HASH') {
13373: foreach my $key (keys(%{$domconfig{'usercreation'}})) {
13374: if ($key eq 'cancreate') {
13375: if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
13376: foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
13377: if (($item eq 'requestcrs') || ($item eq 'course') || ($item eq 'author')) {
13378: $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
13379: } else {
13380: $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
13381: }
13382: }
13383: }
13384: } elsif ($key eq 'email_rule') {
13385: $save_usercreate{$key} = $domconfig{'usercreation'}{$key};
13386: } else {
13387: $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};
13388: }
13389: }
13390: }
13391: my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule');
13392: my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule');
13393: my @contexts = ('author','course','requestcrs');
13394: foreach my $item(@contexts) {
13395: $cancreate{$item} = $env{'form.can_createuser_'.$item};
13396: }
13397: if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {
13398: foreach my $item (@contexts) {
13399: if ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) {
13400: push(@{$changes{'cancreate'}},$item);
13401: }
13402: }
13403: } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') {
13404: foreach my $item (@contexts) {
13405: if (!grep(/^\Q$item\E$/,@{$curr_usercreation{'cancreate'}})) {
13406: if ($cancreate{$item} ne 'any') {
13407: push(@{$changes{'cancreate'}},$item);
13408: }
13409: } else {
13410: if ($cancreate{$item} ne 'none') {
13411: push(@{$changes{'cancreate'}},$item);
13412: }
13413: }
13414: }
13415: } else {
13416: foreach my $item (@contexts) {
13417: push(@{$changes{'cancreate'}},$item);
13418: }
13419: }
13420:
13421: if (ref($curr_usercreation{'username_rule'}) eq 'ARRAY') {
13422: foreach my $type (@{$curr_usercreation{'username_rule'}}) {
13423: if (!grep(/^\Q$type\E$/,@username_rule)) {
13424: push(@{$changes{'username_rule'}},$type);
13425: }
13426: }
13427: foreach my $type (@username_rule) {
13428: if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'username_rule'}})) {
13429: push(@{$changes{'username_rule'}},$type);
13430: }
13431: }
13432: } else {
13433: push(@{$changes{'username_rule'}},@username_rule);
13434: }
13435:
13436: if (ref($curr_usercreation{'id_rule'}) eq 'ARRAY') {
13437: foreach my $type (@{$curr_usercreation{'id_rule'}}) {
13438: if (!grep(/^\Q$type\E$/,@id_rule)) {
13439: push(@{$changes{'id_rule'}},$type);
13440: }
13441: }
13442: foreach my $type (@id_rule) {
13443: if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'id_rule'}})) {
13444: push(@{$changes{'id_rule'}},$type);
13445: }
13446: }
13447: } else {
13448: push(@{$changes{'id_rule'}},@id_rule);
13449: }
13450:
13451: my @authen_contexts = ('author','course','domain');
13452: my @authtypes = ('int','krb4','krb5','loc','lti');
13453: my %authhash;
13454: foreach my $item (@authen_contexts) {
13455: my @authallowed = &Apache::loncommon::get_env_multiple('form.'.$item.'_auth');
13456: foreach my $auth (@authtypes) {
13457: if (grep(/^\Q$auth\E$/,@authallowed)) {
13458: $authhash{$item}{$auth} = 1;
13459: } else {
13460: $authhash{$item}{$auth} = 0;
13461: }
13462: }
13463: }
13464: if (ref($curr_usercreation{'authtypes'}) eq 'HASH') {
13465: foreach my $item (@authen_contexts) {
13466: if (ref($curr_usercreation{'authtypes'}{$item}) eq 'HASH') {
13467: foreach my $auth (@authtypes) {
13468: if ($authhash{$item}{$auth} ne $curr_usercreation{'authtypes'}{$item}{$auth}) {
13469: push(@{$changes{'authtypes'}},$item);
13470: last;
13471: }
13472: }
13473: }
13474: }
13475: } else {
13476: foreach my $item (@authen_contexts) {
13477: push(@{$changes{'authtypes'}},$item);
13478: }
13479: }
13480:
13481: $save_usercreate{'cancreate'}{'course'} = $cancreate{'course'};
13482: $save_usercreate{'cancreate'}{'author'} = $cancreate{'author'};
13483: $save_usercreate{'cancreate'}{'requestcrs'} = $cancreate{'requestcrs'};
13484: $save_usercreate{'id_rule'} = \@id_rule;
13485: $save_usercreate{'username_rule'} = \@username_rule,
13486: $save_usercreate{'authtypes'} = \%authhash;
13487:
13488: my %usercreation_hash = (
13489: usercreation => \%save_usercreate,
13490: );
13491:
13492: my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash,
13493: $dom);
13494:
13495: if ($putresult eq 'ok') {
13496: if (keys(%changes) > 0) {
13497: $resulttext = &mt('Changes made:').'<ul>';
13498: if (ref($changes{'cancreate'}) eq 'ARRAY') {
13499: my %lt = &usercreation_types();
13500: foreach my $type (@{$changes{'cancreate'}}) {
13501: my $chgtext = $lt{$type}.', ';
13502: if ($cancreate{$type} eq 'none') {
13503: $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.');
13504: } elsif ($cancreate{$type} eq 'any') {
13505: $chgtext .= &mt('creation of new users is permitted for both institutional and non-institutional usernames.');
13506: } elsif ($cancreate{$type} eq 'official') {
13507: $chgtext .= &mt('creation of new users is only permitted for institutional usernames.');
13508: } elsif ($cancreate{$type} eq 'unofficial') {
13509: $chgtext .= &mt('creation of new users is only permitted for non-institutional usernames.');
13510: }
13511: $resulttext .= '<li>'.$chgtext.'</li>';
13512: }
13513: }
13514: if (ref($changes{'username_rule'}) eq 'ARRAY') {
13515: my ($rules,$ruleorder) =
13516: &Apache::lonnet::inst_userrules($dom,'username');
13517: my $chgtext = '<ul>';
13518: foreach my $type (@username_rule) {
13519: if (ref($rules->{$type}) eq 'HASH') {
13520: $chgtext .= '<li>'.$rules->{$type}{'name'}.'</li>';
13521: }
13522: }
13523: $chgtext .= '</ul>';
13524: if (@username_rule > 0) {
13525: $resulttext .= '<li>'.&mt('Usernames with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';
13526: } else {
13527: $resulttext .= '<li>'.&mt('There are now no username formats restricted to verified users in the institutional directory.').'</li>';
13528: }
13529: }
13530: if (ref($changes{'id_rule'}) eq 'ARRAY') {
13531: my ($idrules,$idruleorder) =
13532: &Apache::lonnet::inst_userrules($dom,'id');
13533: my $chgtext = '<ul>';
13534: foreach my $type (@id_rule) {
13535: if (ref($idrules->{$type}) eq 'HASH') {
13536: $chgtext .= '<li>'.$idrules->{$type}{'name'}.'</li>';
13537: }
13538: }
13539: $chgtext .= '</ul>';
13540: if (@id_rule > 0) {
13541: $resulttext .= '<li>'.&mt('IDs with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>';
13542: } else {
13543: $resulttext .= '<li>'.&mt('There are now no ID formats restricted to verified users in the institutional directory.').'</li>';
13544: }
13545: }
13546: my %authname = &authtype_names();
13547: my %context_title = &context_names();
13548: if (ref($changes{'authtypes'}) eq 'ARRAY') {
13549: my $chgtext = '<ul>';
13550: foreach my $type (@{$changes{'authtypes'}}) {
13551: my @allowed;
13552: $chgtext .= '<li><span class="LC_cusr_emph">'.$context_title{$type}.'</span> - '.&mt('assignable authentication types: ');
13553: foreach my $auth (@authtypes) {
13554: if ($authhash{$type}{$auth}) {
13555: push(@allowed,$authname{$auth});
13556: }
13557: }
13558: if (@allowed > 0) {
13559: $chgtext .= join(', ',@allowed).'</li>';
13560: } else {
13561: $chgtext .= &mt('none').'</li>';
13562: }
13563: }
13564: $chgtext .= '</ul>';
13565: $resulttext .= '<li>'.&mt('Authentication types available for assignment to new users').'<br />'.$chgtext;
13566: $resulttext .= '</li>';
13567: }
13568: $resulttext .= '</ul>';
13569: } else {
13570: $resulttext = &mt('No changes made to user creation settings');
13571: }
13572: } else {
13573: $resulttext = '<span class="LC_error">'.
13574: &mt('An error occurred: [_1]',$putresult).'</span>';
13575: }
13576: if ($warningmsg ne '') {
13577: $resulttext .= '<br /><span class="LC_warning">'.$warningmsg.'</span><br />';
13578: }
13579: return $resulttext;
13580: }
13581:
13582: sub modify_selfcreation {
13583: my ($dom,$lastactref,%domconfig) = @_;
13584: my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%curr_inststatus,%changes,%cancreate);
13585: my (%save_usercreate,%save_usermodify,%save_inststatus,@types,%usertypes);
13586: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
13587: my ($othertitle,$usertypesref,$typesref) = &Apache::loncommon::sorted_inst_types($dom);
13588: if (ref($typesref) eq 'ARRAY') {
13589: @types = @{$typesref};
13590: }
13591: if (ref($usertypesref) eq 'HASH') {
13592: %usertypes = %{$usertypesref};
13593: }
13594: $usertypes{'default'} = $othertitle;
13595: #
13596: # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}.
13597: #
13598: if (ref($domconfig{'usercreation'}) eq 'HASH') {
13599: foreach my $key (keys(%{$domconfig{'usercreation'}})) {
13600: if ($key eq 'cancreate') {
13601: if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') {
13602: foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) {
13603: if (($item eq 'selfcreate') || ($item eq 'statustocreate') ||
13604: ($item eq 'captcha') || ($item eq 'recaptchakeys') ||
13605: ($item eq 'recaptchaversion') || ($item eq 'notify') ||
13606: ($item eq 'emailusername') || ($item eq 'shibenv') ||
13607: ($item eq 'selfcreateprocessing') || ($item eq 'emailverified') ||
13608: ($item eq 'emailoptions') || ($item eq 'emaildomain')) {
13609: $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
13610: } else {
13611: $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item};
13612: }
13613: }
13614: }
13615: } elsif ($key eq 'email_rule') {
13616: $curr_usercreation{$key} = $domconfig{'usercreation'}{$key};
13617: } else {
13618: $save_usercreate{$key} = $domconfig{'usercreation'}{$key};
13619: }
13620: }
13621: }
13622: #
13623: # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usermodification'}.
13624: #
13625: if (ref($domconfig{'usermodification'}) eq 'HASH') {
13626: foreach my $key (keys(%{$domconfig{'usermodification'}})) {
13627: if ($key eq 'selfcreate') {
13628: $curr_usermodify{$key} = $domconfig{'usermodification'}{$key};
13629: } else {
13630: $save_usermodify{$key} = $domconfig{'usermodification'}{$key};
13631: }
13632: }
13633: }
13634: #
13635: # Retrieve current domain configuration for institutional status types from $domconfig{'inststatus'}.
13636: #
13637: if (ref($domconfig{'inststatus'}) eq 'HASH') {
13638: foreach my $key (keys(%{$domconfig{'inststatus'}})) {
13639: if ($key eq 'inststatusguest') {
13640: $curr_inststatus{$key} = $domconfig{'inststatus'}{$key};
13641: } else {
13642: $save_inststatus{$key} = $domconfig{'inststatus'}{$key};
13643: }
13644: }
13645: }
13646:
13647: my @contexts = ('selfcreate');
13648: @{$cancreate{'selfcreate'}} = ();
13649: %{$cancreate{'emailusername'}} = ();
13650: if (@types) {
13651: @{$cancreate{'statustocreate'}} = ();
13652: }
13653: %{$cancreate{'selfcreateprocessing'}} = ();
13654: %{$cancreate{'shibenv'}} = ();
13655: %{$cancreate{'emailverified'}} = ();
13656: %{$cancreate{'emailoptions'}} = ();
13657: %{$cancreate{'emaildomain'}} = ();
13658: my %selfcreatetypes = (
13659: sso => 'users authenticated by institutional single sign on',
13660: login => 'users authenticated by institutional log-in',
13661: email => 'users verified by e-mail',
13662: );
13663: #
13664: # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts
13665: # is permitted.
13666: #
13667: my ($emailrules,$emailruleorder) = &Apache::lonnet::inst_userrules($dom,'email');
13668:
13669: my (@statuses,%email_rule);
13670: foreach my $item ('login','sso','email') {
13671: if ($item eq 'email') {
13672: if ($env{'form.cancreate_email'}) {
13673: if (@types) {
13674: my @poss_statuses = &Apache::loncommon::get_env_multiple('form.selfassign');
13675: foreach my $status (@poss_statuses) {
13676: if (grep(/^\Q$status\E$/,(@types,'default'))) {
13677: push(@statuses,$status);
13678: }
13679: }
13680: $save_inststatus{'inststatusguest'} = \@statuses;
13681: } else {
13682: push(@statuses,'default');
13683: }
13684: if (@statuses) {
13685: my %curr_rule;
13686: if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') {
13687: foreach my $type (@statuses) {
13688: $curr_rule{$type} = $curr_usercreation{'email_rule'};
13689: }
13690: } elsif (ref($curr_usercreation{'email_rule'}) eq 'HASH') {
13691: foreach my $type (@statuses) {
13692: $curr_rule{$type} = $curr_usercreation{'email_rule'}{$type};
13693: }
13694: }
13695: push(@{$cancreate{'selfcreate'}},'email');
13696: push(@contexts,('selfcreateprocessing','emailverified','emailoptions'));
13697: my %curremaildom;
13698: if (ref($curr_usercreation{'cancreate'}{'emaildomain'}) eq 'HASH') {
13699: %curremaildom = %{$curr_usercreation{'cancreate'}{'emaildomain'}};
13700: }
13701: foreach my $type (@statuses) {
13702: if ($env{'form.cancreate_emailprocess_'.$type} =~ /^(?:approval|automatic)$/) {
13703: $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type};
13704: }
13705: if ($env{'form.cancreate_usernameoptions_'.$type} =~ /^(?:all|first|free)$/) {
13706: $cancreate{'emailverified'}{$type} = $env{'form.cancreate_usernameoptions_'.$type};
13707: }
13708: if ($env{'form.cancreate_emailoptions_'.$type} =~ /^(any|inst|noninst|custom)$/) {
13709: #
13710: # Retrieve rules (if any) governing types of e-mail address which may be used to verify a username.
13711: #
13712: my $chosen = $1;
13713: if (($chosen eq 'inst') || ($chosen eq 'noninst')) {
13714: my $emaildom;
13715: if ($env{'form.cancreate_emaildomain_'.$chosen.'_'.$type} =~ /^\@[^\@]+$/) {
13716: $emaildom = $env{'form.cancreate_emaildomain_'.$chosen.'_'.$type};
13717: $cancreate{'emaildomain'}{$type}{$chosen} = $emaildom;
13718: if (ref($curremaildom{$type}) eq 'HASH') {
13719: if (exists($curremaildom{$type}{$chosen})) {
13720: if ($curremaildom{$type}{$chosen} ne $emaildom) {
13721: push(@{$changes{'cancreate'}},'emaildomain');
13722: }
13723: } elsif ($emaildom ne '') {
13724: push(@{$changes{'cancreate'}},'emaildomain');
13725: }
13726: } elsif ($emaildom ne '') {
13727: push(@{$changes{'cancreate'}},'emaildomain');
13728: }
13729: }
13730: $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};
13731: } elsif ($chosen eq 'custom') {
13732: my @possemail_rules = &Apache::loncommon::get_env_multiple('form.email_rule_'.$type);
13733: $email_rule{$type} = [];
13734: if (ref($emailrules) eq 'HASH') {
13735: foreach my $rule (@possemail_rules) {
13736: if (exists($emailrules->{$rule})) {
13737: push(@{$email_rule{$type}},$rule);
13738: }
13739: }
13740: }
13741: if (@{$email_rule{$type}}) {
13742: $cancreate{'emailoptions'}{$type} = 'custom';
13743: if (ref($curr_rule{$type}) eq 'ARRAY') {
13744: if (@{$curr_rule{$type}} > 0) {
13745: foreach my $rule (@{$curr_rule{$type}}) {
13746: if (!grep(/^\Q$rule\E$/,@{$email_rule{$type}})) {
13747: push(@{$changes{'email_rule'}},$type);
13748: }
13749: }
13750: }
13751: foreach my $type (@{$email_rule{$type}}) {
13752: if (!grep(/^\Q$type\E$/,@{$curr_rule{$type}})) {
13753: push(@{$changes{'email_rule'}},$type);
13754: }
13755: }
13756: } else {
13757: push(@{$changes{'email_rule'}},$type);
13758: }
13759: }
13760: } else {
13761: $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type};
13762: }
13763: }
13764: }
13765: if (@types) {
13766: if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {
13767: my @changed = &Apache::loncommon::compare_arrays(\@statuses,$curr_inststatus{'inststatusguest'});
13768: if (@changed) {
13769: push(@{$changes{'inststatus'}},'inststatusguest');
13770: }
13771: } else {
13772: push(@{$changes{'inststatus'}},'inststatusguest');
13773: }
13774: }
13775: } else {
13776: delete($env{'form.cancreate_email'});
13777: if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {
13778: if (@{$curr_inststatus{'inststatusguest'}} > 0) {
13779: push(@{$changes{'inststatus'}},'inststatusguest');
13780: }
13781: }
13782: }
13783: } else {
13784: $save_inststatus{'inststatusguest'} = [];
13785: if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') {
13786: if (@{$curr_inststatus{'inststatusguest'}} > 0) {
13787: push(@{$changes{'inststatus'}},'inststatusguest');
13788: }
13789: }
13790: }
13791: } else {
13792: if ($env{'form.cancreate_'.$item}) {
13793: push(@{$cancreate{'selfcreate'}},$item);
13794: }
13795: }
13796: }
13797: my (%userinfo,%savecaptcha);
13798: my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info();
13799: #
13800: # Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data
13801: # value set to one), if self-creation with e-mail address permitted, where $type is user type: faculty, staff, student etc.
13802: #
13803:
13804: if ($env{'form.cancreate_email'}) {
13805: push(@contexts,'emailusername');
13806: if (@statuses) {
13807: foreach my $type (@statuses) {
13808: if (ref($infofields) eq 'ARRAY') {
13809: foreach my $field (@{$infofields}) {
13810: if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) {
13811: $cancreate{'emailusername'}{$type}{$field} = $1;
13812: }
13813: }
13814: }
13815: }
13816: }
13817: #
13818: # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of
13819: # queued requests for self-creation of account verified by e-mail.
13820: #
13821:
13822: my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval');
13823: @approvalnotify = sort(@approvalnotify);
13824: $cancreate{'notify'}{'approval'} = join(',',@approvalnotify);
13825: if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {
13826: if (ref($curr_usercreation{'cancreate'}{'notify'}) eq 'HASH') {
13827: if ($curr_usercreation{'cancreate'}{'notify'}{'approval'} ne $cancreate{'notify'}{'approval'}) {
13828: push(@{$changes{'cancreate'}},'notify');
13829: }
13830: } else {
13831: if ($cancreate{'notify'}{'approval'}) {
13832: push(@{$changes{'cancreate'}},'notify');
13833: }
13834: }
13835: } elsif ($cancreate{'notify'}{'approval'}) {
13836: push(@{$changes{'cancreate'}},'notify');
13837: }
13838:
13839: &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'});
13840: }
13841: #
13842: # Check if domain default is set appropriately, if self-creation of accounts is to be available for
13843: # institutional log-in.
13844: #
13845: if (grep(/^login$/,@{$cancreate{'selfcreate'}})) {
13846: if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) ||
13847: ($domdefaults{'auth_def'} eq 'localauth'))) {
13848: $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '.
13849: &mt('You need to set the default authentication type to Kerberos 4 or 5 (with a Kerberos domain specified), or to Local authentication, if the localauth module has been customized in your domain to authenticate institutional logins.');
13850: }
13851: }
13852: my @fields = ('lastname','firstname','middlename','generation',
13853: 'permanentemail','id');
13854: my @shibfields = (@fields,'inststatus');
13855: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
13856: #
13857: # Where usernames may created for institutional log-in and/or institutional single sign on:
13858: # (a) populate $cancreate{'statustocreate'} array reference with institutional status types who
13859: # may self-create accounts
13860: # (b) populate $save_usermodify{'selfcreate'} hash reference with status types, and information fields
13861: # which the user may supply, if institutional data is unavailable.
13862: #
13863: if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) {
13864: if (@types) {
13865: @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate');
13866: push(@contexts,'statustocreate');
13867: foreach my $type (@types) {
13868: my @modifiable = &Apache::loncommon::get_env_multiple('form.canmodify_'.$type);
13869: foreach my $field (@fields) {
13870: if (grep(/^\Q$field\E$/,@modifiable)) {
13871: $save_usermodify{'selfcreate'}{$type}{$field} = 1;
13872: } else {
13873: $save_usermodify{'selfcreate'}{$type}{$field} = 0;
13874: }
13875: }
13876: }
13877: if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') {
13878: foreach my $type (@types) {
13879: if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') {
13880: foreach my $field (@fields) {
13881: if ($save_usermodify{'selfcreate'}{$type}{$field} ne
13882: $curr_usermodify{'selfcreate'}{$type}{$field}) {
13883: push(@{$changes{'selfcreate'}},$type);
13884: last;
13885: }
13886: }
13887: }
13888: }
13889: } else {
13890: foreach my $type (@types) {
13891: push(@{$changes{'selfcreate'}},$type);
13892: }
13893: }
13894: }
13895: foreach my $field (@shibfields) {
13896: if ($env{'form.shibenv_'.$field} ne '') {
13897: $cancreate{'shibenv'}{$field} = $env{'form.shibenv_'.$field};
13898: }
13899: }
13900: if (ref($curr_usercreation{'cancreate'}) eq 'HASH') {
13901: if (ref($curr_usercreation{'cancreate'}{'shibenv'}) eq 'HASH') {
13902: foreach my $field (@shibfields) {
13903: if ($env{'form.shibenv_'.$field} ne $curr_usercreation{'cancreate'}{'shibenv'}{$field}) {
13904: push(@{$changes{'cancreate'}},'shibenv');
13905: }
13906: }
13907: } else {
13908: foreach my $field (@shibfields) {
13909: if ($env{'form.shibenv_'.$field}) {
13910: push(@{$changes{'cancreate'}},'shibenv');
13911: last;
13912: }
13913: }
13914: }
13915: }
13916: }
13917: foreach my $item (@contexts) {
13918: if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') {
13919: foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) {
13920: if (ref($cancreate{$item}) eq 'ARRAY') {
13921: if (!grep(/^$curr$/,@{$cancreate{$item}})) {
13922: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
13923: push(@{$changes{'cancreate'}},$item);
13924: }
13925: }
13926: }
13927: }
13928: if (ref($cancreate{$item}) eq 'ARRAY') {
13929: foreach my $type (@{$cancreate{$item}}) {
13930: if (!grep(/^$type$/,@{$curr_usercreation{'cancreate'}{$item}})) {
13931: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
13932: push(@{$changes{'cancreate'}},$item);
13933: }
13934: }
13935: }
13936: }
13937: } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') {
13938: if (ref($cancreate{$item}) eq 'HASH') {
13939: foreach my $type (keys(%{$curr_usercreation{'cancreate'}{$item}})) {
13940: if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {
13941: foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$type}})) {
13942: unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {
13943: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
13944: push(@{$changes{'cancreate'}},$item);
13945: }
13946: }
13947: }
13948: } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {
13949: if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {
13950: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
13951: push(@{$changes{'cancreate'}},$item);
13952: }
13953: }
13954: }
13955: }
13956: foreach my $type (keys(%{$cancreate{$item}})) {
13957: if (ref($cancreate{$item}{$type}) eq 'HASH') {
13958: foreach my $field (keys(%{$cancreate{$item}{$type}})) {
13959: if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') {
13960: unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) {
13961: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
13962: push(@{$changes{'cancreate'}},$item);
13963: }
13964: }
13965: } else {
13966: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
13967: push(@{$changes{'cancreate'}},$item);
13968: }
13969: }
13970: }
13971: } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {
13972: if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) {
13973: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
13974: push(@{$changes{'cancreate'}},$item);
13975: }
13976: }
13977: }
13978: }
13979: }
13980: } elsif ($curr_usercreation{'cancreate'}{$item}) {
13981: if (ref($cancreate{$item}) eq 'ARRAY') {
13982: if (!grep(/^\Q$curr_usercreation{'cancreate'}{$item}\E$/,@{$cancreate{$item}})) {
13983: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
13984: push(@{$changes{'cancreate'}},$item);
13985: }
13986: }
13987: }
13988: } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) {
13989: if (ref($cancreate{$item}) eq 'HASH') {
13990: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
13991: push(@{$changes{'cancreate'}},$item);
13992: }
13993: }
13994: } elsif ($item eq 'emailusername') {
13995: if (ref($cancreate{$item}) eq 'HASH') {
13996: foreach my $type (keys(%{$cancreate{$item}})) {
13997: if (ref($cancreate{$item}{$type}) eq 'HASH') {
13998: foreach my $field (keys(%{$cancreate{$item}{$type}})) {
13999: if ($cancreate{$item}{$type}{$field}) {
14000: if (!grep(/^$item$/,@{$changes{'cancreate'}})) {
14001: push(@{$changes{'cancreate'}},$item);
14002: }
14003: last;
14004: }
14005: }
14006: }
14007: }
14008: }
14009: }
14010: }
14011: #
14012: # Populate %save_usercreate hash with updates to self-creation configuration.
14013: #
14014: $save_usercreate{'cancreate'}{'captcha'} = $savecaptcha{'captcha'};
14015: $save_usercreate{'cancreate'}{'recaptchakeys'} = $savecaptcha{'recaptchakeys'};
14016: $save_usercreate{'cancreate'}{'recaptchaversion'} = $savecaptcha{'recaptchaversion'};
14017: $save_usercreate{'cancreate'}{'selfcreate'} = $cancreate{'selfcreate'};
14018: if (ref($cancreate{'notify'}) eq 'HASH') {
14019: $save_usercreate{'cancreate'}{'notify'} = $cancreate{'notify'};
14020: }
14021: if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') {
14022: $save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'};
14023: }
14024: if (ref($cancreate{'emailverified'}) eq 'HASH') {
14025: $save_usercreate{'cancreate'}{'emailverified'} = $cancreate{'emailverified'};
14026: }
14027: if (ref($cancreate{'emailoptions'}) eq 'HASH') {
14028: $save_usercreate{'cancreate'}{'emailoptions'} = $cancreate{'emailoptions'};
14029: }
14030: if (ref($cancreate{'emaildomain'}) eq 'HASH') {
14031: $save_usercreate{'cancreate'}{'emaildomain'} = $cancreate{'emaildomain'};
14032: }
14033: if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
14034: $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'};
14035: }
14036: if (ref($cancreate{'shibenv'}) eq 'HASH') {
14037: $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'};
14038: }
14039: $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'};
14040: $save_usercreate{'email_rule'} = \%email_rule;
14041:
14042: my %userconfig_hash = (
14043: usercreation => \%save_usercreate,
14044: usermodification => \%save_usermodify,
14045: inststatus => \%save_inststatus,
14046: );
14047:
14048: my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash,
14049: $dom);
14050: #
14051: # Accumulate details of changes to domain configuration for self-creation of usernames in $resulttext
14052: #
14053: if ($putresult eq 'ok') {
14054: if (keys(%changes) > 0) {
14055: $resulttext = &mt('Changes made:').'<ul>';
14056: if (ref($changes{'cancreate'}) eq 'ARRAY') {
14057: my %lt = &selfcreation_types();
14058: foreach my $type (@{$changes{'cancreate'}}) {
14059: my $chgtext = '';
14060: if ($type eq 'selfcreate') {
14061: if (@{$cancreate{$type}} == 0) {
14062: $chgtext .= &mt('Self creation of a new user account is not permitted.');
14063: } else {
14064: $chgtext .= &mt('Self-creation of a new account is permitted for:').
14065: '<ul>';
14066: foreach my $case (@{$cancreate{$type}}) {
14067: $chgtext .= '<li>'.$selfcreatetypes{$case}.'</li>';
14068: }
14069: $chgtext .= '</ul>';
14070: if (ref($cancreate{$type}) eq 'ARRAY') {
14071: if (grep(/^(login|sso)$/,@{$cancreate{$type}})) {
14072: if (ref($cancreate{'statustocreate'}) eq 'ARRAY') {
14073: if (@{$cancreate{'statustocreate'}} == 0) {
14074: $chgtext .= '<span class="LC_warning">'.
14075: &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts via log-in or single sign-on.").
14076: '</span><br />';
14077: }
14078: }
14079: }
14080: if (grep(/^email$/,@{$cancreate{$type}})) {
14081: if (!@statuses) {
14082: $chgtext .= '<span class="LC_warning">'.
14083: &mt("However, e-mail verification is currently set to 'unavailable' for all user types (including 'other'), so self-creation of accounts is not possible for non-institutional log-in.").
14084: '</span><br />';
14085:
14086: }
14087: }
14088: }
14089: }
14090: } elsif ($type eq 'shibenv') {
14091: if (keys(%{$cancreate{$type}}) == 0) {
14092: $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information').'<br />';
14093: } else {
14094: $chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:').
14095: '<ul>';
14096: foreach my $field (@shibfields) {
14097: next if ($cancreate{$type}{$field} eq '');
14098: if ($field eq 'inststatus') {
14099: $chgtext .= '<li>'.&mt('Institutional status').' -- '.$cancreate{$type}{$field}.'</li>';
14100: } else {
14101: $chgtext .= '<li>'.$fieldtitles{$field}.' -- '.$cancreate{$type}{$field}.'</li>';
14102: }
14103: }
14104: $chgtext .= '</ul>';
14105: }
14106: } elsif ($type eq 'statustocreate') {
14107: if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') &&
14108: (ref($cancreate{'statustocreate'}) eq 'ARRAY')) {
14109: if (@{$cancreate{'selfcreate'}} > 0) {
14110: if (@{$cancreate{'statustocreate'}} == 0) {
14111: $chgtext .= &mt("Institutional affiliations permitted to create accounts set to 'None'.");
14112: if (!grep(/^email$/,@{$cancreate{'selfcreate'}})) {
14113: $chgtext .= '<br />'.
14114: '<span class="LC_warning">'.
14115: &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").
14116: '</span>';
14117: }
14118: } elsif (keys(%usertypes) > 0) {
14119: if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
14120: $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):');
14121: } else {
14122: $chgtext .= &mt('Institutional affiliations permitted to create accounts with institutional authentication were set as follows:');
14123: }
14124: $chgtext .= '<ul>';
14125: foreach my $case (@{$cancreate{$type}}) {
14126: if ($case eq 'default') {
14127: $chgtext .= '<li>'.$othertitle.'</li>';
14128: } else {
14129: $chgtext .= '<li>'.$usertypes{$case}.'</li>';
14130: }
14131: }
14132: $chgtext .= '</ul>';
14133: if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) {
14134: $chgtext .= '<span class="LC_warning">'.
14135: &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').
14136: '</span>';
14137: }
14138: }
14139: } else {
14140: if (@{$cancreate{$type}} == 0) {
14141: $chgtext .= &mt("Institutional affiliations permitted to create accounts were set to 'none'.");
14142: } else {
14143: $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.');
14144: }
14145: }
14146: $chgtext .= '<br />';
14147: }
14148: } elsif ($type eq 'selfcreateprocessing') {
14149: my %choices = &Apache::lonlocal::texthash (
14150: automatic => 'Automatic approval',
14151: approval => 'Queued for approval',
14152: );
14153: if (@types) {
14154: if (@statuses) {
14155: $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:').
14156: '<ul>';
14157: foreach my $status (@statuses) {
14158: if ($status eq 'default') {
14159: $chgtext .= '<li>'.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'</li>';
14160: } else {
14161: $chgtext .= '<li>'.$usertypes{$status}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'</li>';
14162: }
14163: }
14164: $chgtext .= '</ul>';
14165: }
14166: } else {
14167: $chgtext .= &mt('Processing of requests to create account with e-mail verification set to: "[_1]"',
14168: $choices{$cancreate{'selfcreateprocessing'}{'default'}});
14169: }
14170: } elsif ($type eq 'emailverified') {
14171: my %options = &Apache::lonlocal::texthash (
14172: all => 'Same as e-mail',
14173: first => 'Omit @domain',
14174: free => 'Free to choose',
14175: );
14176: if (@types) {
14177: if (@statuses) {
14178: $chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:').
14179: '<ul>';
14180: foreach my $status (@statuses) {
14181: if ($type eq 'default') {
14182: $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';
14183: } else {
14184: $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>';
14185: }
14186: }
14187: $chgtext .= '</ul>';
14188: }
14189: } else {
14190: $chgtext .= &mt("For self-created accounts verified by e-mail address, user's username is: '[_1]'",
14191: $options{$cancreate{'emailverified'}{'default'}});
14192: }
14193: } elsif ($type eq 'emailoptions') {
14194: my %options = &Apache::lonlocal::texthash (
14195: any => 'Any e-mail',
14196: inst => 'Institutional only',
14197: noninst => 'Non-institutional only',
14198: custom => 'Custom restrictions',
14199: );
14200: if (@types) {
14201: if (@statuses) {
14202: $chgtext .= &mt('For self-created accounts verified by e-mail address, requirements for e-mail address are as follows:').
14203: '<ul>';
14204: foreach my $status (@statuses) {
14205: if ($type eq 'default') {
14206: $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'</li>';
14207: } else {
14208: $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'</li>';
14209: }
14210: }
14211: $chgtext .= '</ul>';
14212: }
14213: } else {
14214: if ($cancreate{'emailoptions'}{'default'} eq 'any') {
14215: $chgtext .= &mt('For self-created accounts verified by e-mail address, any e-mail may be used');
14216: } else {
14217: $chgtext .= &mt('For self-created accounts verified by e-mail address, e-mail restricted to: "[_1]"',
14218: $options{$cancreate{'emailoptions'}{'default'}});
14219: }
14220: }
14221: } elsif ($type eq 'emaildomain') {
14222: my $output;
14223: if (@statuses) {
14224: foreach my $type (@statuses) {
14225: if (ref($cancreate{'emaildomain'}{$type}) eq 'HASH') {
14226: if ($cancreate{'emailoptions'}{$type} eq 'inst') {
14227: if ($type eq 'default') {
14228: if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
14229: ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {
14230: $output = '<li>'.$othertitle.' -- '.&mt('No restriction on e-mail domain').'</li>';
14231: } else {
14232: $output = '<li>'.$othertitle.' -- '.&mt("User's e-mail address needs to end: [_1]",
14233: $cancreate{'emaildomain'}{$type}{'inst'}).'</li>';
14234: }
14235: } else {
14236: if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
14237: ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) {
14238: $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';
14239: } else {
14240: $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address needs to end: [_1]",
14241: $cancreate{'emaildomain'}{$type}{'inst'}).'</li>';
14242: }
14243: }
14244: } elsif ($cancreate{'emailoptions'}{$type} eq 'noninst') {
14245: if ($type eq 'default') {
14246: if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
14247: ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {
14248: $output = '<li>'.$othertitle.' -- '.&mt('No restriction on e-mail domain').'</li>';
14249: } else {
14250: $output = '<li>'.$othertitle.' -- '.&mt("User's e-mail address must not end: [_1]",
14251: $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';
14252: }
14253: } else {
14254: if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') ||
14255: ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) {
14256: $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>';
14257: } else {
14258: $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address must not end: [_1]",
14259: $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>';
14260: }
14261: }
14262: }
14263: }
14264: }
14265: }
14266: if ($output ne '') {
14267: $chgtext .= &mt('For self-created accounts verified by e-mail address:').
14268: '<ul>'.$output.'</ul>';
14269: }
14270: } elsif ($type eq 'captcha') {
14271: if ($savecaptcha{$type} eq 'notused') {
14272: $chgtext .= &mt('No CAPTCHA validation in use for self-creation screen.');
14273: } else {
14274: my %captchas = &captcha_phrases();
14275: if ($captchas{$savecaptcha{$type}}) {
14276: $chgtext .= &mt("Validation for self-creation screen set to $captchas{$savecaptcha{$type}}.");
14277: } else {
14278: $chgtext .= &mt('Validation for self-creation screen set to unknown type.');
14279: }
14280: }
14281: } elsif ($type eq 'recaptchakeys') {
14282: my ($privkey,$pubkey);
14283: if (ref($savecaptcha{$type}) eq 'HASH') {
14284: $pubkey = $savecaptcha{$type}{'public'};
14285: $privkey = $savecaptcha{$type}{'private'};
14286: }
14287: $chgtext .= &mt('ReCAPTCHA keys changes').'<ul>';
14288: if (!$pubkey) {
14289: $chgtext .= '<li>'.&mt('Public key deleted').'</li>';
14290: } else {
14291: $chgtext .= '<li>'.&mt('Public key set to [_1]',$pubkey).'</li>';
14292: }
14293: if (!$privkey) {
14294: $chgtext .= '<li>'.&mt('Private key deleted').'</li>';
14295: } else {
14296: $chgtext .= '<li>'.&mt('Private key set to [_1]',$pubkey).'</li>';
14297: }
14298: $chgtext .= '</ul>';
14299: } elsif ($type eq 'recaptchaversion') {
14300: if ($savecaptcha{'captcha'} eq 'recaptcha') {
14301: $chgtext .= &mt('ReCAPTCHA set to version [_1]',$savecaptcha{$type});
14302: }
14303: } elsif ($type eq 'emailusername') {
14304: if (ref($cancreate{'emailusername'}) eq 'HASH') {
14305: if (@statuses) {
14306: foreach my $type (@statuses) {
14307: if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') {
14308: if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) {
14309: $chgtext .= &mt('When self-creating account with e-mail verification, the following information will be provided by [_1]:',"'$usertypes{$type}'").
14310: '<ul>';
14311: foreach my $field (@{$infofields}) {
14312: if ($cancreate{'emailusername'}{$type}{$field}) {
14313: $chgtext .= '<li>'.$infotitles->{$field}.'</li>';
14314: }
14315: }
14316: $chgtext .= '</ul>';
14317: } else {
14318: $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").'<br />';
14319: }
14320: } else {
14321: $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").'<br />';
14322: }
14323: }
14324: }
14325: }
14326: } elsif ($type eq 'notify') {
14327: my $numapprove = 0;
14328: if (ref($changes{'cancreate'}) eq 'ARRAY') {
14329: if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) {
14330: if ($cancreate{'notify'}{'approval'}) {
14331: $chgtext .= &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'};
14332: $numapprove ++;
14333: }
14334: }
14335: }
14336: unless ($numapprove) {
14337: $chgtext .= &mt('No Domain Coordinators will receive notification of username requests requiring approval.');
14338: }
14339: }
14340: if ($chgtext) {
14341: $resulttext .= '<li>'.$chgtext.'</li>';
14342: }
14343: }
14344: }
14345: if ((ref($changes{'email_rule'}) eq 'ARRAY') && (@{$changes{'email_rule'}} > 0)) {
14346: my ($emailrules,$emailruleorder) =
14347: &Apache::lonnet::inst_userrules($dom,'email');
14348: foreach my $type (@{$changes{'email_rule'}}) {
14349: if (ref($email_rule{$type}) eq 'ARRAY') {
14350: my $chgtext = '<ul>';
14351: foreach my $rule (@{$email_rule{$type}}) {
14352: if (ref($emailrules->{$rule}) eq 'HASH') {
14353: $chgtext .= '<li>'.$emailrules->{$rule}{'name'}.'</li>';
14354: }
14355: }
14356: $chgtext .= '</ul>';
14357: my $typename;
14358: if (@types) {
14359: if ($type eq 'default') {
14360: $typename = $othertitle;
14361: } else {
14362: $typename = $usertypes{$type};
14363: }
14364: $chgtext .= &mt('(Affiliation: [_1])',$typename);
14365: }
14366: if (@{$email_rule{$type}} > 0) {
14367: $resulttext .= '<li>'.
14368: &mt('Accounts may not be created by users verified by e-mail, for e-mail addresses of the following types: ',
14369: $usertypes{$type}).
14370: $chgtext.
14371: '</li>';
14372: } else {
14373: $resulttext .= '<li>'.
14374: &mt('There are now no restrictions on e-mail addresses which may be used for verification when a user requests an account.').
14375: '</li>'.
14376: &mt('(Affiliation: [_1])',$typename);
14377: }
14378: }
14379: }
14380: }
14381: if (ref($changes{'inststatus'}) eq 'ARRAY') {
14382: if (ref($save_inststatus{'inststatusguest'}) eq 'ARRAY') {
14383: if (@{$save_inststatus{'inststatusguest'}} > 0) {
14384: my $chgtext = '<ul>';
14385: foreach my $type (@{$save_inststatus{'inststatusguest'}}) {
14386: $chgtext .= '<li>'.$usertypes{$type}.'</li>';
14387: }
14388: $chgtext .= '</ul>';
14389: $resulttext .= '<li>'.
14390: &mt('A user will self-report one of the following affiliations when requesting an account verified by e-mail: ').
14391: $chgtext.
14392: '</li>';
14393: } else {
14394: $resulttext .= '<li>'.
14395: &mt('No affiliations available for self-reporting when requesting an account verified by e-mail.').
14396: '</li>';
14397: }
14398: }
14399: }
14400: if (ref($changes{'selfcreate'}) eq 'ARRAY') {
14401: $resulttext .= '<li>'.&mt('When self-creating institutional account:').'<ul>';
14402: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
14403: foreach my $type (@{$changes{'selfcreate'}}) {
14404: my $typename = $type;
14405: if (keys(%usertypes) > 0) {
14406: if ($usertypes{$type} ne '') {
14407: $typename = $usertypes{$type};
14408: }
14409: }
14410: my @modifiable;
14411: $resulttext .= '<li>'.
14412: &mt('Self-creation of account by users with status: [_1]',
14413: '<span class="LC_cusr_emph">'.$typename.'</span>').
14414: ' - '.&mt('modifiable fields (if institutional data blank): ');
14415: foreach my $field (@fields) {
14416: if ($save_usermodify{'selfcreate'}{$type}{$field}) {
14417: push(@modifiable,'<b>'.$fieldtitles{$field}.'</b>');
14418: }
14419: }
14420: if (@modifiable > 0) {
14421: $resulttext .= join(', ',@modifiable);
14422: } else {
14423: $resulttext .= &mt('none');
14424: }
14425: $resulttext .= '</li>';
14426: }
14427: $resulttext .= '</ul></li>';
14428: }
14429: $resulttext .= '</ul>';
14430: my $cachetime = 24*60*60;
14431: $domdefaults{'inststatusguest'} = $save_inststatus{'inststatusguest'};
14432: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
14433: if (ref($lastactref) eq 'HASH') {
14434: $lastactref->{'domdefaults'} = 1;
14435: }
14436: } else {
14437: $resulttext = &mt('No changes made to self-creation settings');
14438: }
14439: } else {
14440: $resulttext = '<span class="LC_error">'.
14441: &mt('An error occurred: [_1]',$putresult).'</span>';
14442: }
14443: if ($warningmsg ne '') {
14444: $resulttext .= '<br /><span class="LC_warning">'.$warningmsg.'</span><br />';
14445: }
14446: return $resulttext;
14447: }
14448:
14449: sub process_captcha {
14450: my ($container,$changes,$newsettings,$current) = @_;
14451: return unless ((ref($changes) eq 'HASH') && (ref($newsettings) eq 'HASH') || (ref($current) eq 'HASH'));
14452: $newsettings->{'captcha'} = $env{'form.'.$container.'_captcha'};
14453: unless ($newsettings->{'captcha'} eq 'recaptcha' || $newsettings->{'captcha'} eq 'notused') {
14454: $newsettings->{'captcha'} = 'original';
14455: }
14456: if ($current->{'captcha'} ne $newsettings->{'captcha'}) {
14457: if ($container eq 'cancreate') {
14458: if (ref($changes->{'cancreate'}) eq 'ARRAY') {
14459: push(@{$changes->{'cancreate'}},'captcha');
14460: } elsif (!defined($changes->{'cancreate'})) {
14461: $changes->{'cancreate'} = ['captcha'];
14462: }
14463: } else {
14464: $changes->{'captcha'} = 1;
14465: }
14466: }
14467: my ($newpub,$newpriv,$currpub,$currpriv,$newversion,$currversion);
14468: if ($newsettings->{'captcha'} eq 'recaptcha') {
14469: $newpub = $env{'form.'.$container.'_recaptchapub'};
14470: $newpriv = $env{'form.'.$container.'_recaptchapriv'};
14471: $newpub =~ s/[^\w\-]//g;
14472: $newpriv =~ s/[^\w\-]//g;
14473: $newsettings->{'recaptchakeys'} = {
14474: public => $newpub,
14475: private => $newpriv,
14476: };
14477: $newversion = $env{'form.'.$container.'_recaptchaversion'};
14478: $newversion =~ s/\D//g;
14479: if ($newversion ne '2') {
14480: $newversion = 1;
14481: }
14482: $newsettings->{'recaptchaversion'} = $newversion;
14483: }
14484: if (ref($current->{'recaptchakeys'}) eq 'HASH') {
14485: $currpub = $current->{'recaptchakeys'}{'public'};
14486: $currpriv = $current->{'recaptchakeys'}{'private'};
14487: unless ($newsettings->{'captcha'} eq 'recaptcha') {
14488: $newsettings->{'recaptchakeys'} = {
14489: public => '',
14490: private => '',
14491: }
14492: }
14493: }
14494: if ($current->{'captcha'} eq 'recaptcha') {
14495: $currversion = $current->{'recaptchaversion'};
14496: if ($currversion ne '2') {
14497: $currversion = 1;
14498: }
14499: }
14500: if ($currversion ne $newversion) {
14501: if ($container eq 'cancreate') {
14502: if (ref($changes->{'cancreate'}) eq 'ARRAY') {
14503: push(@{$changes->{'cancreate'}},'recaptchaversion');
14504: } elsif (!defined($changes->{'cancreate'})) {
14505: $changes->{'cancreate'} = ['recaptchaversion'];
14506: }
14507: } else {
14508: $changes->{'recaptchaversion'} = 1;
14509: }
14510: }
14511: if (($newpub ne $currpub) || ($newpriv ne $currpriv)) {
14512: if ($container eq 'cancreate') {
14513: if (ref($changes->{'cancreate'}) eq 'ARRAY') {
14514: push(@{$changes->{'cancreate'}},'recaptchakeys');
14515: } elsif (!defined($changes->{'cancreate'})) {
14516: $changes->{'cancreate'} = ['recaptchakeys'];
14517: }
14518: } else {
14519: $changes->{'recaptchakeys'} = 1;
14520: }
14521: }
14522: return;
14523: }
14524:
14525: sub modify_usermodification {
14526: my ($dom,%domconfig) = @_;
14527: my ($resulttext,%curr_usermodification,%changes,%modifyhash);
14528: if (ref($domconfig{'usermodification'}) eq 'HASH') {
14529: foreach my $key (keys(%{$domconfig{'usermodification'}})) {
14530: if ($key eq 'selfcreate') {
14531: $modifyhash{$key} = $domconfig{'usermodification'}{$key};
14532: } else {
14533: $curr_usermodification{$key} = $domconfig{'usermodification'}{$key};
14534: }
14535: }
14536: }
14537: my @contexts = ('author','course');
14538: my %context_title = (
14539: author => 'In author context',
14540: course => 'In course context',
14541: );
14542: my @fields = ('lastname','firstname','middlename','generation',
14543: 'permanentemail','id');
14544: my %roles = (
14545: author => ['ca','aa'],
14546: course => ['st','ep','ta','in','cr'],
14547: );
14548: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles();
14549: foreach my $context (@contexts) {
14550: foreach my $role (@{$roles{$context}}) {
14551: my @modifiable = &Apache::loncommon::get_env_multiple('form.canmodify_'.$role);
14552: foreach my $item (@fields) {
14553: if (grep(/^\Q$item\E$/,@modifiable)) {
14554: $modifyhash{$context}{$role}{$item} = 1;
14555: } else {
14556: $modifyhash{$context}{$role}{$item} = 0;
14557: }
14558: }
14559: }
14560: if (ref($curr_usermodification{$context}) eq 'HASH') {
14561: foreach my $role (@{$roles{$context}}) {
14562: if (ref($curr_usermodification{$context}{$role}) eq 'HASH') {
14563: foreach my $field (@fields) {
14564: if ($modifyhash{$context}{$role}{$field} ne
14565: $curr_usermodification{$context}{$role}{$field}) {
14566: push(@{$changes{$context}},$role);
14567: last;
14568: }
14569: }
14570: }
14571: }
14572: } else {
14573: foreach my $context (@contexts) {
14574: foreach my $role (@{$roles{$context}}) {
14575: push(@{$changes{$context}},$role);
14576: }
14577: }
14578: }
14579: }
14580: my %usermodification_hash = (
14581: usermodification => \%modifyhash,
14582: );
14583: my $putresult = &Apache::lonnet::put_dom('configuration',
14584: \%usermodification_hash,$dom);
14585: if ($putresult eq 'ok') {
14586: if (keys(%changes) > 0) {
14587: $resulttext = &mt('Changes made: ').'<ul>';
14588: foreach my $context (@contexts) {
14589: if (ref($changes{$context}) eq 'ARRAY') {
14590: $resulttext .= '<li>'.$context_title{$context}.':<ul>';
14591: if (ref($changes{$context}) eq 'ARRAY') {
14592: foreach my $role (@{$changes{$context}}) {
14593: my $rolename;
14594: if ($role eq 'cr') {
14595: $rolename = &mt('Custom');
14596: } else {
14597: $rolename = &Apache::lonnet::plaintext($role);
14598: }
14599: my @modifiable;
14600: $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Target user with [_1] role',$rolename).'</span> - '.&mt('modifiable fields: ');
14601: foreach my $field (@fields) {
14602: if ($modifyhash{$context}{$role}{$field}) {
14603: push(@modifiable,$fieldtitles{$field});
14604: }
14605: }
14606: if (@modifiable > 0) {
14607: $resulttext .= join(', ',@modifiable);
14608: } else {
14609: $resulttext .= &mt('none');
14610: }
14611: $resulttext .= '</li>';
14612: }
14613: $resulttext .= '</ul></li>';
14614: }
14615: }
14616: }
14617: $resulttext .= '</ul>';
14618: } else {
14619: $resulttext = &mt('No changes made to user modification settings');
14620: }
14621: } else {
14622: $resulttext = '<span class="LC_error">'.
14623: &mt('An error occurred: [_1]',$putresult).'</span>';
14624: }
14625: return $resulttext;
14626: }
14627:
14628: sub modify_defaults {
14629: my ($dom,$lastactref,%domconfig) = @_;
14630: my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors);
14631: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
14632: my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def',
14633: 'portal_def','intauth_cost','intauth_check','intauth_switch');
14634: my @authtypes = ('internal','krb4','krb5','localauth','lti');
14635: foreach my $item (@items) {
14636: $newvalues{$item} = $env{'form.'.$item};
14637: if ($item eq 'auth_def') {
14638: if ($newvalues{$item} ne '') {
14639: if (!grep(/^\Q$newvalues{$item}\E$/,@authtypes)) {
14640: push(@errors,$item);
14641: }
14642: }
14643: } elsif ($item eq 'lang_def') {
14644: if ($newvalues{$item} ne '') {
14645: if ($newvalues{$item} =~ /^(\w+)/) {
14646: my $langcode = $1;
14647: if ($langcode ne 'x_chef') {
14648: if (code2language($langcode) eq '') {
14649: push(@errors,$item);
14650: }
14651: }
14652: } else {
14653: push(@errors,$item);
14654: }
14655: }
14656: } elsif ($item eq 'timezone_def') {
14657: if ($newvalues{$item} ne '') {
14658: if (!DateTime::TimeZone->is_valid_name($newvalues{$item})) {
14659: push(@errors,$item);
14660: }
14661: }
14662: } elsif ($item eq 'datelocale_def') {
14663: if ($newvalues{$item} ne '') {
14664: my @datelocale_ids = DateTime::Locale->ids();
14665: if (!grep(/^\Q$newvalues{$item}\E$/,@datelocale_ids)) {
14666: push(@errors,$item);
14667: }
14668: }
14669: } elsif ($item eq 'portal_def') {
14670: if ($newvalues{$item} ne '') {
14671: unless ($newvalues{$item} =~ /^https?\:\/\/(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])\/?$/) {
14672: push(@errors,$item);
14673: }
14674: }
14675: } elsif ($item eq 'intauth_cost') {
14676: if ($newvalues{$item} ne '') {
14677: if ($newvalues{$item} =~ /\D/) {
14678: push(@errors,$item);
14679: }
14680: }
14681: } elsif ($item eq 'intauth_check') {
14682: if ($newvalues{$item} ne '') {
14683: unless ($newvalues{$item} =~ /^(0|1|2)$/) {
14684: push(@errors,$item);
14685: }
14686: }
14687: } elsif ($item eq 'intauth_switch') {
14688: if ($newvalues{$item} ne '') {
14689: unless ($newvalues{$item} =~ /^(0|1|2)$/) {
14690: push(@errors,$item);
14691: }
14692: }
14693: }
14694: if (grep(/^\Q$item\E$/,@errors)) {
14695: $newvalues{$item} = $domdefaults{$item};
14696: } elsif ($domdefaults{$item} ne $newvalues{$item}) {
14697: $changes{$item} = 1;
14698: }
14699: $domdefaults{$item} = $newvalues{$item};
14700: }
14701: my %defaults_hash = (
14702: defaults => \%newvalues,
14703: );
14704: my $title = &defaults_titles();
14705:
14706: my $currinststatus;
14707: if (ref($domconfig{'inststatus'}) eq 'HASH') {
14708: $currinststatus = $domconfig{'inststatus'};
14709: } else {
14710: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
14711: $currinststatus = {
14712: inststatustypes => $usertypes,
14713: inststatusorder => $types,
14714: inststatusguest => [],
14715: };
14716: }
14717: my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete');
14718: my @allpos;
14719: my %alltypes;
14720: my @inststatusguest;
14721: if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') {
14722: foreach my $type (@{$currinststatus->{'inststatusguest'}}) {
14723: unless (grep(/^\Q$type\E$/,@todelete)) {
14724: push(@inststatusguest,$type);
14725: }
14726: }
14727: }
14728: my ($currtitles,$currorder);
14729: if (ref($currinststatus) eq 'HASH') {
14730: if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') {
14731: foreach my $type (@{$currinststatus->{'inststatusorder'}}) {
14732: if (ref($currinststatus->{inststatustypes}) eq 'HASH') {
14733: if ($currinststatus->{inststatustypes}->{$type} ne '') {
14734: $currtitles .= $currinststatus->{inststatustypes}->{$type}.',';
14735: }
14736: }
14737: unless (grep(/^\Q$type\E$/,@todelete)) {
14738: my $position = $env{'form.inststatus_pos_'.$type};
14739: $position =~ s/\D+//g;
14740: $allpos[$position] = $type;
14741: $alltypes{$type} = $env{'form.inststatus_title_'.$type};
14742: $alltypes{$type} =~ s/`//g;
14743: }
14744: }
14745: $currorder = join(',',@{$currinststatus->{'inststatusorder'}});
14746: $currtitles =~ s/,$//;
14747: }
14748: }
14749: if ($env{'form.addinststatus'}) {
14750: my $newtype = $env{'form.addinststatus'};
14751: $newtype =~ s/\W//g;
14752: unless (exists($alltypes{$newtype})) {
14753: $alltypes{$newtype} = $env{'form.addinststatus_title'};
14754: $alltypes{$newtype} =~ s/`//g;
14755: my $position = $env{'form.addinststatus_pos'};
14756: $position =~ s/\D+//g;
14757: if ($position ne '') {
14758: $allpos[$position] = $newtype;
14759: }
14760: }
14761: }
14762: my @orderedstatus;
14763: foreach my $type (@allpos) {
14764: unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) {
14765: push(@orderedstatus,$type);
14766: }
14767: }
14768: foreach my $type (keys(%alltypes)) {
14769: unless (grep(/^\Q$type\E$/,@orderedstatus)) {
14770: delete($alltypes{$type});
14771: }
14772: }
14773: $defaults_hash{'inststatus'} = {
14774: inststatustypes => \%alltypes,
14775: inststatusorder => \@orderedstatus,
14776: inststatusguest => \@inststatusguest,
14777: };
14778: if (ref($defaults_hash{'inststatus'}) eq 'HASH') {
14779: foreach my $item ('inststatustypes','inststatusorder','inststatusguest') {
14780: $domdefaults{$item} = $defaults_hash{'inststatus'}{$item};
14781: }
14782: }
14783: if ($currorder ne join(',',@orderedstatus)) {
14784: $changes{'inststatus'}{'inststatusorder'} = 1;
14785: }
14786: my $newtitles;
14787: foreach my $item (@orderedstatus) {
14788: $newtitles .= $alltypes{$item}.',';
14789: }
14790: $newtitles =~ s/,$//;
14791: if ($currtitles ne $newtitles) {
14792: $changes{'inststatus'}{'inststatustypes'} = 1;
14793: }
14794: my $putresult = &Apache::lonnet::put_dom('configuration',\%defaults_hash,
14795: $dom);
14796: if ($putresult eq 'ok') {
14797: if (keys(%changes) > 0) {
14798: $resulttext = &mt('Changes made:').'<ul>';
14799: my $version = &Apache::lonnet::get_server_loncaparev($dom);
14800: my $mailmsgtext = "Changes made to domain settings in a LON-CAPA installation - domain: $dom (running version: $version) - dns_domain.tab needs to be updated with the following changes, to support legacy 2.4, 2.5 and 2.6 versions of LON-CAPA.\n\n";
14801: foreach my $item (sort(keys(%changes))) {
14802: if ($item eq 'inststatus') {
14803: if (ref($changes{'inststatus'}) eq 'HASH') {
14804: if (@orderedstatus) {
14805: $resulttext .= '<li>'.&mt('Institutional user status types set to:').' ';
14806: foreach my $type (@orderedstatus) {
14807: $resulttext .= $alltypes{$type}.', ';
14808: }
14809: $resulttext =~ s/, $//;
14810: $resulttext .= '</li>';
14811: } else {
14812: $resulttext .= '<li>'.&mt('Institutional user status types deleted').'</li>';
14813: }
14814: }
14815: } else {
14816: my $value = $env{'form.'.$item};
14817: if ($value eq '') {
14818: $value = &mt('none');
14819: } elsif ($item eq 'auth_def') {
14820: my %authnames = &authtype_names();
14821: my %shortauth = (
14822: internal => 'int',
14823: krb4 => 'krb4',
14824: krb5 => 'krb5',
14825: localauth => 'loc',
14826: lti => 'lti',
14827: );
14828: $value = $authnames{$shortauth{$value}};
14829: } elsif ($item eq 'intauth_switch') {
14830: my %optiondesc = &Apache::lonlocal::texthash (
14831: 0 => 'No',
14832: 1 => 'Yes',
14833: 2 => 'Yes, and copy existing passwd file to passwd.bak file',
14834: );
14835: if ($value =~ /^(0|1|2)$/) {
14836: $value = $optiondesc{$value};
14837: } else {
14838: $value = &mt('none -- defaults to No');
14839: }
14840: } elsif ($item eq 'intauth_check') {
14841: my %optiondesc = &Apache::lonlocal::texthash (
14842: 0 => 'No',
14843: 1 => 'Yes, allow login then update passwd file using default cost (if higher)',
14844: 2 => 'Yes, disallow login if stored cost is less than domain default',
14845: );
14846: if ($value =~ /^(0|1|2)$/) {
14847: $value = $optiondesc{$value};
14848: } else {
14849: $value = &mt('none -- defaults to No');
14850: }
14851: }
14852: $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>';
14853: $mailmsgtext .= "$title->{$item} set to $value\n";
14854: }
14855: }
14856: $resulttext .= '</ul>';
14857: $mailmsgtext .= "\n";
14858: my $cachetime = 24*60*60;
14859: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
14860: if (ref($lastactref) eq 'HASH') {
14861: $lastactref->{'domdefaults'} = 1;
14862: }
14863: if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) {
14864: my $notify = 1;
14865: if (ref($domconfig{'contacts'}) eq 'HASH') {
14866: if ($domconfig{'contacts'}{'reportupdates'} == 0) {
14867: $notify = 0;
14868: }
14869: }
14870: if ($notify) {
14871: &Apache::lonmsg::sendemail('installrecord@loncapa.org',
14872: "LON-CAPA Domain Settings Change - $dom",
14873: $mailmsgtext);
14874: }
14875: }
14876: } else {
14877: $resulttext = &mt('No changes made to default authentication/language/timezone settings');
14878: }
14879: } else {
14880: $resulttext = '<span class="LC_error">'.
14881: &mt('An error occurred: [_1]',$putresult).'</span>';
14882: }
14883: if (@errors > 0) {
14884: $resulttext .= '<br />'.&mt('The following were left unchanged because the values entered were invalid:');
14885: foreach my $item (@errors) {
14886: $resulttext .= ' "'.$title->{$item}.'",';
14887: }
14888: $resulttext =~ s/,$//;
14889: }
14890: return $resulttext;
14891: }
14892:
14893: sub modify_scantron {
14894: my ($r,$dom,$confname,$lastactref,%domconfig) = @_;
14895: my ($resulttext,%confhash,%changes,$errors);
14896: my $custom = 'custom.tab';
14897: my $default = 'default.tab';
14898: my $servadm = $r->dir_config('lonAdmEMail');
14899: my ($configuserok,$author_ok,$switchserver) =
14900: &config_check($dom,$confname,$servadm);
14901: if ($env{'form.scantronformat.filename'} ne '') {
14902: my $error;
14903: if ($configuserok eq 'ok') {
14904: if ($switchserver) {
14905: $error = &mt("Upload of bubblesheet format file is not permitted to this server: [_1]",$switchserver);
14906: } else {
14907: if ($author_ok eq 'ok') {
14908: my ($result,$scantronurl) =
14909: &publishlogo($r,'upload','scantronformat',$dom,
14910: $confname,'scantron','','',$custom);
14911: if ($result eq 'ok') {
14912: $confhash{'scantron'}{'scantronformat'} = $scantronurl;
14913: $changes{'scantronformat'} = 1;
14914: } else {
14915: $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$custom,$result);
14916: }
14917: } else {
14918: $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$custom,$confname,$dom,$author_ok);
14919: }
14920: }
14921: } else {
14922: $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$custom,$confname,$dom,$configuserok);
14923: }
14924: if ($error) {
14925: &Apache::lonnet::logthis($error);
14926: $errors .= '<li><span class="LC_error">'.$error.'</span></li>';
14927: }
14928: }
14929: if (ref($domconfig{'scantron'}) eq 'HASH') {
14930: if ($domconfig{'scantron'}{'scantronformat'} ne '') {
14931: if ($env{'form.scantronformat_del'}) {
14932: $confhash{'scantron'}{'scantronformat'} = '';
14933: $changes{'scantronformat'} = 1;
14934: }
14935: }
14936: }
14937: if (keys(%confhash) > 0) {
14938: my $putresult = &Apache::lonnet::put_dom('configuration',\%confhash,
14939: $dom);
14940: if ($putresult eq 'ok') {
14941: if (keys(%changes) > 0) {
14942: if (ref($confhash{'scantron'}) eq 'HASH') {
14943: $resulttext = &mt('Changes made:').'<ul>';
14944: if ($confhash{'scantron'}{'scantronformat'} eq '') {
14945: $resulttext .= '<li>'.&mt('[_1] bubblesheet format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>';
14946: } else {
14947: $resulttext .= '<li>'.&mt('Custom bubblesheet format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>';
14948: }
14949: $resulttext .= '</ul>';
14950: } else {
14951: $resulttext = &mt('Changes made to bubblesheet format file.');
14952: }
14953: $resulttext .= '</ul>';
14954: &Apache::loncommon::devalidate_domconfig_cache($dom);
14955: if (ref($lastactref) eq 'HASH') {
14956: $lastactref->{'domainconfig'} = 1;
14957: }
14958: } else {
14959: $resulttext = &mt('No changes made to bubblesheet format file');
14960: }
14961: } else {
14962: $resulttext = '<span class="LC_error">'.
14963: &mt('An error occurred: [_1]',$putresult).'</span>';
14964: }
14965: } else {
14966: $resulttext = &mt('No changes made to bubblesheet format file');
14967: }
14968: if ($errors) {
14969: $resulttext .= &mt('The following errors occurred: ').'<ul>'.
14970: $errors.'</ul>';
14971: }
14972: return $resulttext;
14973: }
14974:
14975: sub modify_coursecategories {
14976: my ($dom,$lastactref,%domconfig) = @_;
14977: my ($resulttext,%deletions,%reorderings,%needreordering,%adds,%changes,$errors,
14978: $cathash);
14979: my @deletecategory = &Apache::loncommon::get_env_multiple('form.deletecategory');
14980: my @catitems = ('unauth','auth');
14981: my @cattypes = ('std','domonly','codesrch','none');
14982: if (ref($domconfig{'coursecategories'}) eq 'HASH') {
14983: $cathash = $domconfig{'coursecategories'}{'cats'};
14984: if ($domconfig{'coursecategories'}{'togglecats'} ne $env{'form.togglecats'}) {
14985: $changes{'togglecats'} = 1;
14986: $domconfig{'coursecategories'}{'togglecats'} = $env{'form.togglecats'};
14987: }
14988: if ($domconfig{'coursecategories'}{'categorize'} ne $env{'form.categorize'}) {
14989: $changes{'categorize'} = 1;
14990: $domconfig{'coursecategories'}{'categorize'} = $env{'form.categorize'};
14991: }
14992: if ($domconfig{'coursecategories'}{'togglecatscomm'} ne $env{'form.togglecatscomm'}) {
14993: $changes{'togglecatscomm'} = 1;
14994: $domconfig{'coursecategories'}{'togglecatscomm'} = $env{'form.togglecatscomm'};
14995: }
14996: if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) {
14997: $changes{'categorizecomm'} = 1;
14998: $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'};
14999:
15000: }
15001: if ($domconfig{'coursecategories'}{'togglecatsplace'} ne $env{'form.togglecatsplace'}) {
15002: $changes{'togglecatsplace'} = 1;
15003: $domconfig{'coursecategories'}{'togglecatsplace'} = $env{'form.togglecatsplace'};
15004: }
15005: if ($domconfig{'coursecategories'}{'categorizeplace'} ne $env{'form.categorizeplace'}) {
15006: $changes{'categorizeplace'} = 1;
15007: $domconfig{'coursecategories'}{'categorizeplace'} = $env{'form.categorizeplace'};
15008: }
15009: foreach my $item (@catitems) {
15010: if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) {
15011: if ($domconfig{'coursecategories'}{$item} ne $env{'form.coursecat_'.$item}) {
15012: $changes{$item} = 1;
15013: $domconfig{'coursecategories'}{$item} = $env{'form.coursecat_'.$item};
15014: }
15015: }
15016: }
15017: } else {
15018: $changes{'togglecats'} = 1;
15019: $changes{'categorize'} = 1;
15020: $changes{'togglecatscomm'} = 1;
15021: $changes{'categorizecomm'} = 1;
15022: $changes{'togglecatsplace'} = 1;
15023: $changes{'categorizeplace'} = 1;
15024: $domconfig{'coursecategories'} = {
15025: togglecats => $env{'form.togglecats'},
15026: categorize => $env{'form.categorize'},
15027: togglecatscomm => $env{'form.togglecatscomm'},
15028: categorizecomm => $env{'form.categorizecomm'},
15029: togglecatsplace => $env{'form.togglecatsplace'},
15030: categorizeplace => $env{'form.categorizeplace'},
15031: };
15032: foreach my $item (@catitems) {
15033: if ($env{'form.coursecat_'.$item} ne 'std') {
15034: $changes{$item} = 1;
15035: }
15036: if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) {
15037: $domconfig{'coursecategories'}{$item} = $env{'form.coursecat_'.$item};
15038: }
15039: }
15040: }
15041: if (ref($cathash) eq 'HASH') {
15042: if (($domconfig{'coursecategories'}{'cats'}{'instcode::0'} ne '') && ($env{'form.instcode'} == 0)) {
15043: push (@deletecategory,'instcode::0');
15044: }
15045: if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '') && ($env{'form.communities'} == 0)) {
15046: push(@deletecategory,'communities::0');
15047: }
15048: if (($domconfig{'coursecategories'}{'cats'}{'placement::0'} ne '') && ($env{'form.placement'} == 0)) {
15049: push(@deletecategory,'placement::0');
15050: }
15051: }
15052: my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail);
15053: if (ref($cathash) eq 'HASH') {
15054: if (@deletecategory > 0) {
15055: #FIXME Need to remove category from all courses using a deleted category
15056: &Apache::loncommon::extract_categories($cathash,\@predelcats,\@predeltrails,\%predelallitems);
15057: foreach my $item (@deletecategory) {
15058: if ($domconfig{'coursecategories'}{'cats'}{$item} ne '') {
15059: delete($domconfig{'coursecategories'}{'cats'}{$item});
15060: $deletions{$item} = 1;
15061: &recurse_cat_deletes($item,$cathash,\%deletions);
15062: }
15063: }
15064: }
15065: foreach my $item (keys(%{$cathash})) {
15066: my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$item);
15067: if ($cathash->{$item} ne $env{'form.'.$item}) {
15068: $reorderings{$item} = 1;
15069: $domconfig{'coursecategories'}{'cats'}{$item} = $env{'form.'.$item};
15070: }
15071: if ($env{'form.addcategory_name_'.$item} ne '') {
15072: my $newcat = $env{'form.addcategory_name_'.$item};
15073: my $newdepth = $depth+1;
15074: my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth;
15075: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos_'.$item};
15076: $adds{$newitem} = 1;
15077: }
15078: if ($env{'form.subcat_'.$item} ne '') {
15079: my $newcat = $env{'form.subcat_'.$item};
15080: my $newdepth = $depth+1;
15081: my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth;
15082: $domconfig{'coursecategories'}{'cats'}{$newitem} = 0;
15083: $adds{$newitem} = 1;
15084: }
15085: }
15086: }
15087: if ($env{'form.instcode'} eq '1') {
15088: if (ref($cathash) eq 'HASH') {
15089: my $newitem = 'instcode::0';
15090: if ($cathash->{$newitem} eq '') {
15091: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.instcode_pos'};
15092: $adds{$newitem} = 1;
15093: }
15094: } else {
15095: my $newitem = 'instcode::0';
15096: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.instcode_pos'};
15097: $adds{$newitem} = 1;
15098: }
15099: }
15100: if ($env{'form.communities'} eq '1') {
15101: if (ref($cathash) eq 'HASH') {
15102: my $newitem = 'communities::0';
15103: if ($cathash->{$newitem} eq '') {
15104: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'};
15105: $adds{$newitem} = 1;
15106: }
15107: } else {
15108: my $newitem = 'communities::0';
15109: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'};
15110: $adds{$newitem} = 1;
15111: }
15112: }
15113: if ($env{'form.placement'} eq '1') {
15114: if (ref($cathash) eq 'HASH') {
15115: my $newitem = 'placement::0';
15116: if ($cathash->{$newitem} eq '') {
15117: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'};
15118: $adds{$newitem} = 1;
15119: }
15120: } else {
15121: my $newitem = 'placement::0';
15122: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'};
15123: $adds{$newitem} = 1;
15124: }
15125: }
15126: if ($env{'form.addcategory_name'} ne '') {
15127: if (($env{'form.addcategory_name'} ne 'instcode') &&
15128: ($env{'form.addcategory_name'} ne 'communities') &&
15129: ($env{'form.addcategory_name'} ne 'placement')) {
15130: my $newitem = &escape($env{'form.addcategory_name'}).'::0';
15131: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'};
15132: $adds{$newitem} = 1;
15133: }
15134: }
15135: my $putresult;
15136: if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) {
15137: if (keys(%deletions) > 0) {
15138: foreach my $key (keys(%deletions)) {
15139: if ($predelallitems{$key} ne '') {
15140: $sort_by_deltrail{$predelallitems{$key}} = $predeltrails[$predelallitems{$key}];
15141: }
15142: }
15143: }
15144: my (@chkcats,@chktrails,%chkallitems);
15145: &Apache::loncommon::extract_categories($domconfig{'coursecategories'}{'cats'},\@chkcats,\@chktrails,\%chkallitems);
15146: if (ref($chkcats[0]) eq 'ARRAY') {
15147: my $depth = 0;
15148: my $chg = 0;
15149: for (my $i=0; $i<@{$chkcats[0]}; $i++) {
15150: my $name = $chkcats[0][$i];
15151: my $item;
15152: if ($name eq '') {
15153: $chg ++;
15154: } else {
15155: $item = &escape($name).'::0';
15156: if ($chg) {
15157: $domconfig{'coursecategories'}{'cats'}{$item} -= $chg;
15158: }
15159: $depth ++;
15160: &recurse_check(\@chkcats,$domconfig{'coursecategories'}{'cats'},$depth,$name);
15161: $depth --;
15162: }
15163: }
15164: }
15165: }
15166: if ((keys(%changes) > 0) || (keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) {
15167: $putresult = &Apache::lonnet::put_dom('configuration',\%domconfig,$dom);
15168: if ($putresult eq 'ok') {
15169: my %title = (
15170: togglecats => 'Show/Hide a course in catalog',
15171: categorize => 'Assign a category to a course',
15172: togglecatscomm => 'Show/Hide a community in catalog',
15173: categorizecomm => 'Assign a category to a community',
15174: );
15175: my %level = (
15176: dom => 'set in Domain ("Modify Course/Community")',
15177: crs => 'set in Course ("Course Configuration")',
15178: comm => 'set in Community ("Community Configuration")',
15179: none => 'No catalog',
15180: std => 'Standard catalog',
15181: domonly => 'Domain-only catalog',
15182: codesrch => 'Code search form',
15183: );
15184: $resulttext = &mt('Changes made:').'<ul>';
15185: if ($changes{'togglecats'}) {
15186: $resulttext .= '<li>'.&mt("$title{'togglecats'} $level{$env{'form.togglecats'}}").'</li>';
15187: }
15188: if ($changes{'categorize'}) {
15189: $resulttext .= '<li>'.&mt("$title{'categorize'} $level{$env{'form.categorize'}}").'</li>';
15190: }
15191: if ($changes{'togglecatscomm'}) {
15192: $resulttext .= '<li>'.&mt("$title{'togglecatscomm'} $level{$env{'form.togglecatscomm'}}").'</li>';
15193: }
15194: if ($changes{'categorizecomm'}) {
15195: $resulttext .= '<li>'.&mt("$title{'categorizecomm'} $level{$env{'form.categorizecomm'}}").'</li>';
15196: }
15197: if ($changes{'unauth'}) {
15198: $resulttext .= '<li>'.&mt('Catalog type for unauthenticated users set to "'.$level{$env{'form.coursecat_unauth'}}.'"').'</li>';
15199: }
15200: if ($changes{'auth'}) {
15201: $resulttext .= '<li>'.&mt('Catalog type for authenticated users set to "'.$level{$env{'form.coursecat_auth'}}.'"').'</li>';
15202: }
15203: if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) {
15204: my $cathash;
15205: if (ref($domconfig{'coursecategories'}) eq 'HASH') {
15206: $cathash = $domconfig{'coursecategories'}{'cats'};
15207: } else {
15208: $cathash = {};
15209: }
15210: my (@cats,@trails,%allitems);
15211: &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems);
15212: if (keys(%deletions) > 0) {
15213: $resulttext .= '<li>'.&mt('Deleted categories:').'<ul>';
15214: foreach my $predeltrail (sort {$a <=> $b } (keys(%sort_by_deltrail))) {
15215: $resulttext .= '<li>'.$predeltrails[$predeltrail].'</li>';
15216: }
15217: $resulttext .= '</ul></li>';
15218: }
15219: if (keys(%reorderings) > 0) {
15220: my %sort_by_trail;
15221: $resulttext .= '<li>'.&mt('Reordered categories:').'<ul>';
15222: foreach my $key (keys(%reorderings)) {
15223: if ($allitems{$key} ne '') {
15224: $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}];
15225: }
15226: }
15227: foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) {
15228: $resulttext .= '<li>'.$trails[$trail].'</li>';
15229: }
15230: $resulttext .= '</ul></li>';
15231: }
15232: if (keys(%adds) > 0) {
15233: my %sort_by_trail;
15234: $resulttext .= '<li>'.&mt('Added categories:').'<ul>';
15235: foreach my $key (keys(%adds)) {
15236: if ($allitems{$key} ne '') {
15237: $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}];
15238: }
15239: }
15240: foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) {
15241: $resulttext .= '<li>'.$trails[$trail].'</li>';
15242: }
15243: $resulttext .= '</ul></li>';
15244: }
15245: }
15246: $resulttext .= '</ul>';
15247: if ($changes{'unauth'} || $changes{'auth'}) {
15248: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom);
15249: if ($changes{'auth'}) {
15250: $domdefaults{'catauth'} = $domconfig{'coursecategories'}{'auth'};
15251: }
15252: if ($changes{'unauth'}) {
15253: $domdefaults{'catunauth'} = $domconfig{'coursecategories'}{'unauth'};
15254: }
15255: my $cachetime = 24*60*60;
15256: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
15257: if (ref($lastactref) eq 'HASH') {
15258: $lastactref->{'domdefaults'} = 1;
15259: }
15260: }
15261: } else {
15262: $resulttext = '<span class="LC_error">'.
15263: &mt('An error occurred: [_1]',$putresult).'</span>';
15264: }
15265: } else {
15266: $resulttext = &mt('No changes made to course and community categories');
15267: }
15268: return $resulttext;
15269: }
15270:
15271: sub modify_serverstatuses {
15272: my ($dom,%domconfig) = @_;
15273: my ($resulttext,%changes,%currserverstatus,%newserverstatus);
15274: if (ref($domconfig{'serverstatuses'}) eq 'HASH') {
15275: %currserverstatus = %{$domconfig{'serverstatuses'}};
15276: }
15277: my @pages = &serverstatus_pages();
15278: foreach my $type (@pages) {
15279: $newserverstatus{$type}{'namedusers'} = '';
15280: $newserverstatus{$type}{'machines'} = '';
15281: if (defined($env{'form.'.$type.'_namedusers'})) {
15282: my @users = split(/,/,$env{'form.'.$type.'_namedusers'});
15283: my @okusers;
15284: foreach my $user (@users) {
15285: my ($uname,$udom) = split(/:/,$user);
15286: if (($udom =~ /^$match_domain$/) &&
15287: (&Apache::lonnet::domain($udom)) &&
15288: ($uname =~ /^$match_username$/)) {
15289: if (!grep(/^\Q$user\E/,@okusers)) {
15290: push(@okusers,$user);
15291: }
15292: }
15293: }
15294: if (@okusers > 0) {
15295: @okusers = sort(@okusers);
15296: $newserverstatus{$type}{'namedusers'} = join(',',@okusers);
15297: }
15298: }
15299: if (defined($env{'form.'.$type.'_machines'})) {
15300: my @machines = split(/,/,$env{'form.'.$type.'_machines'});
15301: my @okmachines;
15302: foreach my $ip (@machines) {
15303: my @parts = split(/\./,$ip);
15304: next if (@parts < 4);
15305: my $badip = 0;
15306: for (my $i=0; $i<4; $i++) {
15307: if (!(($parts[$i] >= 0) && ($parts[$i] <= 255))) {
15308: $badip = 1;
15309: last;
15310: }
15311: }
15312: if (!$badip) {
15313: push(@okmachines,$ip);
15314: }
15315: }
15316: @okmachines = sort(@okmachines);
15317: $newserverstatus{$type}{'machines'} = join(',',@okmachines);
15318: }
15319: }
15320: my %serverstatushash = (
15321: serverstatuses => \%newserverstatus,
15322: );
15323: foreach my $type (@pages) {
15324: foreach my $setting ('namedusers','machines') {
15325: my (@current,@new);
15326: if (ref($currserverstatus{$type}) eq 'HASH') {
15327: if ($currserverstatus{$type}{$setting} ne '') {
15328: @current = split(/,/,$currserverstatus{$type}{$setting});
15329: }
15330: }
15331: if ($newserverstatus{$type}{$setting} ne '') {
15332: @new = split(/,/,$newserverstatus{$type}{$setting});
15333: }
15334: if (@current > 0) {
15335: if (@new > 0) {
15336: foreach my $item (@current) {
15337: if (!grep(/^\Q$item\E$/,@new)) {
15338: $changes{$type}{$setting} = 1;
15339: last;
15340: }
15341: }
15342: foreach my $item (@new) {
15343: if (!grep(/^\Q$item\E$/,@current)) {
15344: $changes{$type}{$setting} = 1;
15345: last;
15346: }
15347: }
15348: } else {
15349: $changes{$type}{$setting} = 1;
15350: }
15351: } elsif (@new > 0) {
15352: $changes{$type}{$setting} = 1;
15353: }
15354: }
15355: }
15356: if (keys(%changes) > 0) {
15357: my $titles= &LONCAPA::lonauthcgi::serverstatus_titles();
15358: my $putresult = &Apache::lonnet::put_dom('configuration',
15359: \%serverstatushash,$dom);
15360: if ($putresult eq 'ok') {
15361: $resulttext .= &mt('Changes made:').'<ul>';
15362: foreach my $type (@pages) {
15363: if (ref($changes{$type}) eq 'HASH') {
15364: $resulttext .= '<li>'.$titles->{$type}.'<ul>';
15365: if ($changes{$type}{'namedusers'}) {
15366: if ($newserverstatus{$type}{'namedusers'} eq '') {
15367: $resulttext .= '<li>'.&mt("Access terminated for all specific (named) users").'</li>'."\n";
15368: } else {
15369: $resulttext .= '<li>'.&mt("Access available for the following specified users: ").$newserverstatus{$type}{'namedusers'}.'</li>'."\n";
15370: }
15371: }
15372: if ($changes{$type}{'machines'}) {
15373: if ($newserverstatus{$type}{'machines'} eq '') {
15374: $resulttext .= '<li>'.&mt("Access terminated for all specific IP addresses").'</li>'."\n";
15375: } else {
15376: $resulttext .= '<li>'.&mt("Access available for the following specified IP addresses: ").$newserverstatus{$type}{'machines'}.'</li>'."\n";
15377: }
15378:
15379: }
15380: $resulttext .= '</ul></li>';
15381: }
15382: }
15383: $resulttext .= '</ul>';
15384: } else {
15385: $resulttext = '<span class="LC_error">'.
15386: &mt('An error occurred saving access settings for server status pages: [_1].',$putresult).'</span>';
15387:
15388: }
15389: } else {
15390: $resulttext = &mt('No changes made to access to server status pages');
15391: }
15392: return $resulttext;
15393: }
15394:
15395: sub modify_helpsettings {
15396: my ($r,$dom,$confname,$lastactref,%domconfig) = @_;
15397: my ($resulttext,$errors,%changes,%helphash);
15398: my %defaultchecked = ('submitbugs' => 'on');
15399: my @offon = ('off','on');
15400: my @toggles = ('submitbugs');
15401: my %current = ('submitbugs' => '',
15402: 'adhoc' => {},
15403: );
15404: if (ref($domconfig{'helpsettings'}) eq 'HASH') {
15405: %current = %{$domconfig{'helpsettings'}};
15406: }
15407: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
15408: foreach my $item (@toggles) {
15409: if ($defaultchecked{$item} eq 'on') {
15410: if ($current{$item} eq '') {
15411: if ($env{'form.'.$item} eq '0') {
15412: $changes{$item} = 1;
15413: }
15414: } elsif ($current{$item} ne $env{'form.'.$item}) {
15415: $changes{$item} = 1;
15416: }
15417: } elsif ($defaultchecked{$item} eq 'off') {
15418: if ($current{$item} eq '') {
15419: if ($env{'form.'.$item} eq '1') {
15420: $changes{$item} = 1;
15421: }
15422: } elsif ($current{$item} ne $env{'form.'.$item}) {
15423: $changes{$item} = 1;
15424: }
15425: }
15426: if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) {
15427: $helphash{'helpsettings'}{$item} = $env{'form.'.$item};
15428: }
15429: }
15430: my $maxnum = $env{'form.helproles_maxnum'};
15431: my $confname = $dom.'-domainconfig';
15432: my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_');
15433: my (@allpos,%newsettings,%changedprivs,$newrole);
15434: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom);
15435: my @accesstypes = ('all','dh','da','none','status','inc','exc');
15436: my %domhelpdesk = &Apache::lonnet::get_active_domroles($dom,['dh','da']);
15437: my %lt = &Apache::lonlocal::texthash(
15438: s => 'system',
15439: d => 'domain',
15440: order => 'Display order',
15441: access => 'Role usage',
15442: all => 'All with domain helpdesk or helpdesk assistant role',
15443: dh => 'All with domain helpdesk role',
15444: da => 'All with domain helpdesk assistant role',
15445: none => 'None',
15446: status => 'Determined based on institutional status',
15447: inc => 'Include all, but exclude specific personnel',
15448: exc => 'Exclude all, but include specific personnel',
15449: );
15450: for (my $num=0; $num<=$maxnum; $num++) {
15451: my ($prefix,$identifier,$rolename,%curr);
15452: if ($num == $maxnum) {
15453: next unless ($env{'form.newcusthelp'} == $maxnum);
15454: $identifier = 'custhelp'.$num;
15455: $prefix = 'helproles_'.$num;
15456: $rolename = $env{'form.custhelpname'.$num};
15457: $rolename=~s/[^A-Za-z0-9]//gs;
15458: next if ($rolename eq '');
15459: next if (exists($existing{'rolesdef_'.$rolename}));
15460: my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);
15461: my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},
15462: $newprivs{'c'},$confname,$dom);
15463: if ($result ne 'ok') {
15464: $errors .= '<li><span class="LC_error">'.
15465: &mt('An error occurred storing the new custom role: [_1]',
15466: $result).'</span></li>';
15467: next;
15468: } else {
15469: $changedprivs{$rolename} = \%newprivs;
15470: $newrole = $rolename;
15471: }
15472: } else {
15473: $prefix = 'helproles_'.$num;
15474: $rolename = $env{'form.'.$prefix};
15475: next if ($rolename eq '');
15476: next unless (exists($existing{'rolesdef_'.$rolename}));
15477: $identifier = 'custhelp'.$num;
15478: my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$identifier);
15479: my %currprivs;
15480: ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) =
15481: split(/\_/,$existing{'rolesdef_'.$rolename});
15482: foreach my $level ('c','d','s') {
15483: if ($newprivs{$level} ne $currprivs{$level}) {
15484: my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'},
15485: $newprivs{'c'},$confname,$dom);
15486: if ($result ne 'ok') {
15487: $errors .= '<li><span class="LC_error">'.
15488: &mt('An error occurred storing privileges for existing role [_1]: [_2]',
15489: $rolename,$result).'</span></li>';
15490: } else {
15491: $changedprivs{$rolename} = \%newprivs;
15492: }
15493: last;
15494: }
15495: }
15496: if (ref($current{'adhoc'}) eq 'HASH') {
15497: if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {
15498: %curr = %{$current{'adhoc'}{$rolename}};
15499: }
15500: }
15501: }
15502: my $newpos = $env{'form.'.$prefix.'_pos'};
15503: $newpos =~ s/\D+//g;
15504: $allpos[$newpos] = $rolename;
15505: my $newdesc = $env{'form.'.$prefix.'_desc'};
15506: $helphash{'helpsettings'}{'adhoc'}{$rolename}{'desc'} = $newdesc;
15507: if ($curr{'desc'}) {
15508: if ($curr{'desc'} ne $newdesc) {
15509: $changes{'customrole'}{$rolename}{'desc'} = 1;
15510: $newsettings{$rolename}{'desc'} = $newdesc;
15511: }
15512: } elsif ($newdesc ne '') {
15513: $changes{'customrole'}{$rolename}{'desc'} = 1;
15514: $newsettings{$rolename}{'desc'} = $newdesc;
15515: }
15516: my $access = $env{'form.'.$prefix.'_access'};
15517: if (grep(/^\Q$access\E$/,@accesstypes)) {
15518: $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = $access;
15519: if ($access eq 'status') {
15520: my @statuses = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_status');
15521: if (scalar(@statuses) == 0) {
15522: $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'none';
15523: } else {
15524: my (@shownstatus,$numtypes);
15525: $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];
15526: if (ref($types) eq 'ARRAY') {
15527: $numtypes = scalar(@{$types});
15528: foreach my $type (sort(@statuses)) {
15529: if ($type eq 'default') {
15530: push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);
15531: } elsif (grep(/^\Q$type\E$/,@{$types})) {
15532: push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$type);
15533: push(@shownstatus,$usertypes->{$type});
15534: }
15535: }
15536: }
15537: if (grep(/^default$/,@statuses)) {
15538: push(@shownstatus,$othertitle);
15539: }
15540: if (scalar(@shownstatus) == 1+$numtypes) {
15541: $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'} = 'all';
15542: delete($helphash{'helpsettings'}{'adhoc'}{$rolename}{'status'});
15543: } else {
15544: $newsettings{$rolename}{'status'} = join(' '.&mt('or').' ',@shownstatus);
15545: if (ref($curr{'status'}) eq 'ARRAY') {
15546: my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});
15547: if (@diffs) {
15548: $changes{'customrole'}{$rolename}{$access} = 1;
15549: }
15550: } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {
15551: $changes{'customrole'}{$rolename}{$access} = 1;
15552: }
15553: }
15554: }
15555: } elsif (($access eq 'inc') || ($access eq 'exc')) {
15556: my @personnel = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_staff_'.$access);
15557: my @newspecstaff;
15558: $helphash{'helpsettings'}{'adhoc'}{$rolename}{$access} = [];
15559: foreach my $person (sort(@personnel)) {
15560: if ($domhelpdesk{$person}) {
15561: push(@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}},$person);
15562: }
15563: }
15564: if (ref($curr{$access}) eq 'ARRAY') {
15565: my @diffs = &Apache::loncommon::compare_arrays($helphash{'helpsettings'}{'adhoc'}{$rolename}{$access},$curr{$access});
15566: if (@diffs) {
15567: $changes{'customrole'}{$rolename}{$access} = 1;
15568: }
15569: } elsif (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {
15570: $changes{'customrole'}{$rolename}{$access} = 1;
15571: }
15572: foreach my $person (@{$helphash{'helpsettings'}{'adhoc'}{$rolename}{$access}}) {
15573: my ($uname,$udom) = split(/:/,$person);
15574: push(@newspecstaff,&Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom,'lastname'),$uname,$udom));
15575: }
15576: $newsettings{$rolename}{$access} = join(', ',sort(@newspecstaff));
15577: }
15578: } else {
15579: $helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}= 'all';
15580: }
15581: unless ($curr{'access'} eq $access) {
15582: $changes{'customrole'}{$rolename}{'access'} = 1;
15583: $newsettings{$rolename}{'access'} = $lt{$helphash{'helpsettings'}{'adhoc'}{$rolename}{'access'}};
15584: }
15585: }
15586: if (@allpos > 0) {
15587: my $idx = 0;
15588: foreach my $rolename (@allpos) {
15589: if ($rolename ne '') {
15590: $helphash{'helpsettings'}{'adhoc'}{$rolename}{'order'} = $idx;
15591: if (ref($current{'adhoc'}) eq 'HASH') {
15592: if (ref($current{'adhoc'}{$rolename}) eq 'HASH') {
15593: if ($current{'adhoc'}{$rolename}{'order'} ne $idx) {
15594: $changes{'customrole'}{$rolename}{'order'} = 1;
15595: $newsettings{$rolename}{'order'} = $idx+1;
15596: }
15597: }
15598: }
15599: $idx ++;
15600: }
15601: }
15602: }
15603: my $putresult;
15604: if (keys(%changes) > 0) {
15605: $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom);
15606: if ($putresult eq 'ok') {
15607: if (ref($helphash{'helpsettings'}) eq 'HASH') {
15608: $domdefaults{'submitbugs'} = $helphash{'helpsettings'}{'submitbugs'};
15609: if (ref($helphash{'helpsettings'}{'adhoc'}) eq 'HASH') {
15610: $domdefaults{'adhocroles'} = $helphash{'helpsettings'}{'adhoc'};
15611: }
15612: }
15613: my $cachetime = 24*60*60;
15614: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
15615: if (ref($lastactref) eq 'HASH') {
15616: $lastactref->{'domdefaults'} = 1;
15617: }
15618: } else {
15619: $errors .= '<li><span class="LC_error">'.
15620: &mt('An error occurred storing the settings: [_1]',
15621: $putresult).'</span></li>';
15622: }
15623: }
15624: if ((keys(%changes) && ($putresult eq 'ok')) || (keys(%changedprivs))) {
15625: $resulttext = &mt('Changes made:').'<ul>';
15626: my (%shownprivs,@levelorder);
15627: @levelorder = ('c','d','s');
15628: if ((keys(%changes)) && ($putresult eq 'ok')) {
15629: foreach my $item (sort(keys(%changes))) {
15630: if ($item eq 'submitbugs') {
15631: $resulttext .= '<li>'.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".',
15632: &Apache::loncommon::modal_link('http://bugs.loncapa.org',
15633: &mt('LON-CAPA bug tracker'),600,500)).'</li>';
15634: } elsif ($item eq 'customrole') {
15635: if (ref($changes{'customrole'}) eq 'HASH') {
15636: my @keyorder = ('order','desc','access','status','exc','inc');
15637: my %keytext = &Apache::lonlocal::texthash(
15638: order => 'Order',
15639: desc => 'Role description',
15640: access => 'Role usage',
15641: status => 'Allowed institutional types',
15642: exc => 'Allowed personnel',
15643: inc => 'Disallowed personnel',
15644: );
15645: foreach my $role (sort(keys(%{$changes{'customrole'}}))) {
15646: if (ref($changes{'customrole'}{$role}) eq 'HASH') {
15647: if ($role eq $newrole) {
15648: $resulttext .= '<li>'.&mt('New custom role added: [_1]',
15649: $role).'<ul>';
15650: } else {
15651: $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',
15652: $role).'<ul>';
15653: }
15654: foreach my $key (@keyorder) {
15655: if ($changes{'customrole'}{$role}{$key}) {
15656: $resulttext .= '<li>'.&mt("[_1] set to: [_2]",
15657: $keytext{$key},$newsettings{$role}{$key}).
15658: '</li>';
15659: }
15660: }
15661: if (ref($changedprivs{$role}) eq 'HASH') {
15662: $shownprivs{$role} = 1;
15663: $resulttext .= '<li>'.&mt('Privileges set to :').'<ul>';
15664: foreach my $level (@levelorder) {
15665: foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {
15666: next if ($item eq '');
15667: my ($priv) = split(/\&/,$item,2);
15668: if (&Apache::lonnet::plaintext($priv)) {
15669: $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);
15670: unless ($level eq 'c') {
15671: $resulttext .= ' ('.$lt{$level}.')';
15672: }
15673: $resulttext .= '</li>';
15674: }
15675: }
15676: }
15677: $resulttext .= '</ul>';
15678: }
15679: $resulttext .= '</ul></li>';
15680: }
15681: }
15682: }
15683: }
15684: }
15685: }
15686: if (keys(%changedprivs)) {
15687: foreach my $role (sort(keys(%changedprivs))) {
15688: unless ($shownprivs{$role}) {
15689: $resulttext .= '<li>'.&mt('Existing custom role modified: [_1]',
15690: $role).'<ul>'.
15691: '<li>'.&mt('Privileges set to :').'<ul>';
15692: foreach my $level (@levelorder) {
15693: foreach my $item (split(/\:/,$changedprivs{$role}{$level})) {
15694: next if ($item eq '');
15695: my ($priv) = split(/\&/,$item,2);
15696: if (&Apache::lonnet::plaintext($priv)) {
15697: $resulttext .= '<li>'.&Apache::lonnet::plaintext($priv);
15698: unless ($level eq 'c') {
15699: $resulttext .= ' ('.$lt{$level}.')';
15700: }
15701: $resulttext .= '</li>';
15702: }
15703: }
15704: }
15705: $resulttext .= '</ul></li></ul></li>';
15706: }
15707: }
15708: }
15709: $resulttext .= '</ul>';
15710: } else {
15711: $resulttext = &mt('No changes made to help settings');
15712: }
15713: if ($errors) {
15714: $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'.
15715: $errors.'</ul>';
15716: }
15717: return $resulttext;
15718: }
15719:
15720: sub modify_coursedefaults {
15721: my ($dom,$lastactref,%domconfig) = @_;
15722: my ($resulttext,$errors,%changes,%defaultshash);
15723: my %defaultchecked = (
15724: 'canuse_pdfforms' => 'off',
15725: 'uselcmath' => 'on',
15726: 'usejsme' => 'on'
15727: );
15728: my @toggles = ('canuse_pdfforms','uselcmath','usejsme');
15729: my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
15730: 'uploadquota_community','uploadquota_textbook','uploadquota_placement',
15731: 'mysqltables_official','mysqltables_unofficial','mysqltables_community',
15732: 'mysqltables_textbook','mysqltables_placement');
15733: my @types = ('official','unofficial','community','textbook','placement');
15734: my %staticdefaults = (
15735: anonsurvey_threshold => 10,
15736: uploadquota => 500,
15737: postsubmit => 60,
15738: mysqltables => 172800,
15739: );
15740: my %texoptions = (
15741: MathJax => 'MathJax',
15742: mimetex => &mt('Convert to Images'),
15743: tth => &mt('TeX to HTML'),
15744: );
15745: $defaultshash{'coursedefaults'} = {};
15746:
15747: if (ref($domconfig{'coursedefaults'}) ne 'HASH') {
15748: if ($domconfig{'coursedefaults'} eq '') {
15749: $domconfig{'coursedefaults'} = {};
15750: }
15751: }
15752:
15753: if (ref($domconfig{'coursedefaults'}) eq 'HASH') {
15754: foreach my $item (@toggles) {
15755: if ($defaultchecked{$item} eq 'on') {
15756: if (($domconfig{'coursedefaults'}{$item} eq '') &&
15757: ($env{'form.'.$item} eq '0')) {
15758: $changes{$item} = 1;
15759: } elsif ($domconfig{'coursedefaults'}{$item} ne $env{'form.'.$item}) {
15760: $changes{$item} = 1;
15761: }
15762: } elsif ($defaultchecked{$item} eq 'off') {
15763: if (($domconfig{'coursedefaults'}{$item} eq '') &&
15764: ($env{'form.'.$item} eq '1')) {
15765: $changes{$item} = 1;
15766: } elsif ($domconfig{'coursedefaults'}{$item} ne $env{'form.'.$item}) {
15767: $changes{$item} = 1;
15768: }
15769: }
15770: $defaultshash{'coursedefaults'}{$item} = $env{'form.'.$item};
15771: }
15772: foreach my $item (@numbers) {
15773: my ($currdef,$newdef);
15774: $newdef = $env{'form.'.$item};
15775: if ($item eq 'anonsurvey_threshold') {
15776: $currdef = $domconfig{'coursedefaults'}{$item};
15777: $newdef =~ s/\D//g;
15778: if ($newdef eq '' || $newdef < 1) {
15779: $newdef = 1;
15780: }
15781: $defaultshash{'coursedefaults'}{$item} = $newdef;
15782: } else {
15783: my ($setting,$type) = ($item =~ /^(uploadquota|mysqltables)_(\w+)$/);
15784: if (ref($domconfig{'coursedefaults'}{$setting}) eq 'HASH') {
15785: $currdef = $domconfig{'coursedefaults'}{$setting}{$type};
15786: }
15787: $newdef =~ s/[^\w.\-]//g;
15788: $defaultshash{'coursedefaults'}{$setting}{$type} = $newdef;
15789: }
15790: if ($currdef ne $newdef) {
15791: my $staticdef;
15792: if ($item eq 'anonsurvey_threshold') {
15793: unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) {
15794: $changes{$item} = 1;
15795: }
15796: } elsif ($item =~ /^(uploadquota|mysqltables)_/) {
15797: my $setting = $1;
15798: unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) {
15799: $changes{$setting} = 1;
15800: }
15801: }
15802: }
15803: }
15804: my $texengine;
15805: if ($env{'form.texengine'} =~ /^(MathJax|mimetex|tth)$/) {
15806: $texengine = $env{'form.texengine'};
15807: if ($defaultshash{'coursedefaults'}{'texengine'} eq '') {
15808: unless ($texengine eq 'MathJax') {
15809: $changes{'texengine'} = 1;
15810: }
15811: } elsif ($defaultshash{'coursedefaults'}{'texengine'} ne $texengine) {
15812: $changes{'texengine'} = 1;
15813: }
15814: }
15815: if ($texengine ne '') {
15816: $defaultshash{'coursedefaults'}{'texengine'} = $texengine;
15817: }
15818: my $currclone = $domconfig{'coursedefaults'}{'canclone'};
15819: my @currclonecode;
15820: if (ref($currclone) eq 'HASH') {
15821: if (ref($currclone->{'instcode'}) eq 'ARRAY') {
15822: @currclonecode = @{$currclone->{'instcode'}};
15823: }
15824: }
15825: my $newclone;
15826: if ($env{'form.canclone'} =~ /^(none|domain|instcode)$/) {
15827: $newclone = $env{'form.canclone'};
15828: }
15829: if ($newclone eq 'instcode') {
15830: my @newcodes = &Apache::loncommon::get_env_multiple('form.clonecode');
15831: my (%codedefaults,@code_order,@clonecode);
15832: &Apache::lonnet::auto_instcode_defaults($dom,\%codedefaults,
15833: \@code_order);
15834: foreach my $item (@code_order) {
15835: if (grep(/^\Q$item\E$/,@newcodes)) {
15836: push(@clonecode,$item);
15837: }
15838: }
15839: if (@clonecode) {
15840: $defaultshash{'coursedefaults'}{'canclone'} = { $newclone => \@clonecode };
15841: my @diffs = &Apache::loncommon::compare_arrays(\@currclonecode,\@clonecode);
15842: if (@diffs) {
15843: $changes{'canclone'} = 1;
15844: }
15845: } else {
15846: $newclone eq '';
15847: }
15848: } elsif ($newclone ne '') {
15849: $defaultshash{'coursedefaults'}{'canclone'} = $newclone;
15850: }
15851: if ($newclone ne $currclone) {
15852: $changes{'canclone'} = 1;
15853: }
15854: my %credits;
15855: foreach my $type (@types) {
15856: unless ($type eq 'community') {
15857: $credits{$type} = $env{'form.'.$type.'_credits'};
15858: $credits{$type} =~ s/[^\d.]+//g;
15859: }
15860: }
15861: if ((ref($domconfig{'coursedefaults'}{'coursecredits'}) ne 'HASH') &&
15862: ($env{'form.coursecredits'} eq '1')) {
15863: $changes{'coursecredits'} = 1;
15864: foreach my $type (keys(%credits)) {
15865: $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
15866: }
15867: } else {
15868: if ($env{'form.coursecredits'} eq '1') {
15869: foreach my $type (@types) {
15870: unless ($type eq 'community') {
15871: if ($domconfig{'coursedefaults'}{'coursecredits'}{$type} ne $credits{$type}) {
15872: $changes{'coursecredits'} = 1;
15873: }
15874: $defaultshash{'coursedefaults'}{'coursecredits'}{$type} = $credits{$type};
15875: }
15876: }
15877: } elsif (ref($domconfig{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
15878: foreach my $type (@types) {
15879: unless ($type eq 'community') {
15880: if ($domconfig{'coursedefaults'}{'coursecredits'}{$type}) {
15881: $changes{'coursecredits'} = 1;
15882: last;
15883: }
15884: }
15885: }
15886: }
15887: }
15888: if ($env{'form.postsubmit'} eq '1') {
15889: $defaultshash{'coursedefaults'}{'postsubmit'}{'client'} = 'on';
15890: my %currtimeout;
15891: if (ref($domconfig{'coursedefaults'}{'postsubmit'}) eq 'HASH') {
15892: if ($domconfig{'coursedefaults'}{'postsubmit'}{'client'} eq 'off') {
15893: $changes{'postsubmit'} = 1;
15894: }
15895: if (ref($domconfig{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') {
15896: %currtimeout = %{$domconfig{'coursedefaults'}{'postsubmit'}{'timeout'}};
15897: }
15898: } else {
15899: $changes{'postsubmit'} = 1;
15900: }
15901: foreach my $type (@types) {
15902: my $timeout = $env{'form.'.$type.'_timeout'};
15903: $timeout =~ s/\D//g;
15904: if ($timeout == $staticdefaults{'postsubmit'}) {
15905: $timeout = '';
15906: } elsif (($timeout eq '') || ($timeout =~ /^0+$/)) {
15907: $timeout = '0';
15908: }
15909: unless ($timeout eq '') {
15910: $defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}{$type} = $timeout;
15911: }
15912: if (exists($currtimeout{$type})) {
15913: if ($timeout ne $currtimeout{$type}) {
15914: $changes{'postsubmit'} = 1;
15915: }
15916: } elsif ($timeout ne '') {
15917: $changes{'postsubmit'} = 1;
15918: }
15919: }
15920: } else {
15921: $defaultshash{'coursedefaults'}{'postsubmit'}{'client'} = 'off';
15922: if (ref($domconfig{'coursedefaults'}{'postsubmit'}) eq 'HASH') {
15923: if ($domconfig{'coursedefaults'}{'postsubmit'}{'client'} eq 'on') {
15924: $changes{'postsubmit'} = 1;
15925: }
15926: } else {
15927: $changes{'postsubmit'} = 1;
15928: }
15929: }
15930: }
15931: my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
15932: $dom);
15933: if ($putresult eq 'ok') {
15934: if (keys(%changes) > 0) {
15935: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
15936: if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
15937: ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
15938: ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'})) {
15939: foreach my $item ('canuse_pdfforms','uselcmath','usejsme','texengine') {
15940: if ($changes{$item}) {
15941: $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
15942: }
15943: }
15944: if ($changes{'coursecredits'}) {
15945: if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
15946: foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'coursecredits'}})) {
15947: $domdefaults{$type.'credits'} =
15948: $defaultshash{'coursedefaults'}{'coursecredits'}{$type};
15949: }
15950: }
15951: }
15952: if ($changes{'postsubmit'}) {
15953: if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {
15954: $domdefaults{'postsubmit'} = $defaultshash{'coursedefaults'}{'postsubmit'}{'client'};
15955: if (ref($defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') {
15956: foreach my $type (keys(%{$defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}})) {
15957: $domdefaults{$type.'postsubtimeout'} =
15958: $defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}{$type};
15959: }
15960: }
15961: }
15962: }
15963: if ($changes{'uploadquota'}) {
15964: if (ref($defaultshash{'coursedefaults'}{'uploadquota'}) eq 'HASH') {
15965: foreach my $type (@types) {
15966: $domdefaults{$type.'quota'}=$defaultshash{'coursedefaults'}{'uploadquota'}{$type};
15967: }
15968: }
15969: }
15970: if ($changes{'canclone'}) {
15971: if (ref($defaultshash{'coursedefaults'}{'canclone'}) eq 'HASH') {
15972: if (ref($defaultshash{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') {
15973: my @clonecodes = @{$defaultshash{'coursedefaults'}{'canclone'}{'instcode'}};
15974: if (@clonecodes) {
15975: $domdefaults{'canclone'} = join('+',@clonecodes);
15976: }
15977: }
15978: } else {
15979: $domdefaults{'canclone'}=$defaultshash{'coursedefaults'}{'canclone'};
15980: }
15981: }
15982: my $cachetime = 24*60*60;
15983: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
15984: if (ref($lastactref) eq 'HASH') {
15985: $lastactref->{'domdefaults'} = 1;
15986: }
15987: }
15988: $resulttext = &mt('Changes made:').'<ul>';
15989: foreach my $item (sort(keys(%changes))) {
15990: if ($item eq 'canuse_pdfforms') {
15991: if ($env{'form.'.$item} eq '1') {
15992: $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>';
15993: } else {
15994: $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';
15995: }
15996: } elsif ($item eq 'uselcmath') {
15997: if ($env{'form.'.$item} eq '1') {
15998: $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';
15999: } else {
16000: $resulttext .= '<li>'.&mt('Math preview uses DragMath (Java), if supported by client OS.').'</li>';
16001: }
16002: } elsif ($item eq 'usejsme') {
16003: if ($env{'form.'.$item} eq '1') {
16004: $resulttext .= '<li>'.&mt('Molecule editor uses JSME (HTML5), if supported by browser.').'</li>';
16005: } else {
16006: $resulttext .= '<li>'.&mt('Molecule editor uses JME (Java), if supported by client OS.').'</li>';
16007: }
16008: } elsif ($item eq 'texengine') {
16009: if ($defaultshash{'coursedefaults'}{'texengine'} ne '') {
16010: $resulttext .= '<li>'.&mt('Default method to display mathematics set to: "[_1]"',
16011: $texoptions{$defaultshash{'coursedefaults'}{'texengine'}}).'</li>';
16012: }
16013: } elsif ($item eq 'anonsurvey_threshold') {
16014: $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>';
16015: } elsif ($item eq 'uploadquota') {
16016: if (ref($defaultshash{'coursedefaults'}{'uploadquota'}) eq 'HASH') {
16017: $resulttext .= '<li>'.&mt('Default quota for content uploaded to a course/community via Course Editor set as follows:').'<ul>'.
16018: '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'.
16019: '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'.
16020: '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'.
16021: '<li>'.&mt('Placement tests: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'placement'}.'</b>').'</li>'.
16022: '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'.
16023: '</ul>'.
16024: '</li>';
16025: } else {
16026: $resulttext .= '<li>'.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'</li>';
16027: }
16028: } elsif ($item eq 'mysqltables') {
16029: if (ref($defaultshash{'coursedefaults'}{'mysqltables'}) eq 'HASH') {
16030: $resulttext .= '<li>'.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver').'<ul>'.
16031: '<li>'.&mt('Official courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'</b>').'</li>'.
16032: '<li>'.&mt('Unofficial courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'</b>').'</li>'.
16033: '<li>'.&mt('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'.
16034: '<li>'.&mt('Placement tests: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'placement'}.'</b>').'</li>'.
16035: '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'.
16036: '</ul>'.
16037: '</li>';
16038: } else {
16039: $resulttext .= '<li>'.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver remains default: [_1] s',$staticdefaults{'uploadquota'}).'</li>';
16040: }
16041: } elsif ($item eq 'postsubmit') {
16042: if ($domdefaults{'postsubmit'} eq 'off') {
16043: $resulttext .= '<li>'.&mt('Submit button(s) remain enabled on page after student makes submission.');
16044: } else {
16045: $resulttext .= '<li>'.&mt('Submit button(s) disabled on page after student makes submission').'; ';
16046: if (ref($defaultshash{'coursedefaults'}{'postsubmit'}) eq 'HASH') {
16047: $resulttext .= &mt('durations:').'<ul>';
16048: foreach my $type (@types) {
16049: $resulttext .= '<li>';
16050: my $timeout;
16051: if (ref($defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') {
16052: $timeout = $defaultshash{'coursedefaults'}{'postsubmit'}{'timeout'}{$type};
16053: }
16054: my $display;
16055: if ($timeout eq '0') {
16056: $display = &mt('unlimited');
16057: } elsif ($timeout eq '') {
16058: $display = &mt('[quant,_1,second] (default)',$staticdefaults{'postsubmit'});
16059: } else {
16060: $display = &mt('[quant,_1,second]',$timeout);
16061: }
16062: if ($type eq 'community') {
16063: $resulttext .= &mt('Communities');
16064: } elsif ($type eq 'official') {
16065: $resulttext .= &mt('Official courses');
16066: } elsif ($type eq 'unofficial') {
16067: $resulttext .= &mt('Unofficial courses');
16068: } elsif ($type eq 'textbook') {
16069: $resulttext .= &mt('Textbook courses');
16070: } elsif ($type eq 'placement') {
16071: $resulttext .= &mt('Placement tests');
16072: }
16073: $resulttext .= ' -- '.$display.'</li>';
16074: }
16075: $resulttext .= '</ul>';
16076: }
16077: $resulttext .= '</li>';
16078: }
16079: } elsif ($item eq 'coursecredits') {
16080: if (ref($defaultshash{'coursedefaults'}{'coursecredits'}) eq 'HASH') {
16081: if (($domdefaults{'officialcredits'} eq '') &&
16082: ($domdefaults{'unofficialcredits'} eq '') &&
16083: ($domdefaults{'textbookcredits'} eq '')) {
16084: $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';
16085: } else {
16086: $resulttext .= '<li>'.&mt('Student credits can be set per course by a Domain Coordinator, with the following defaults applying:').'<ul>'.
16087: '<li>'.&mt('Official courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'official'}).'</li>'.
16088: '<li>'.&mt('Unofficial courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'unofficial'}).'</li>'.
16089: '<li>'.&mt('Textbook courses: [_1]',$defaultshash{'coursedefaults'}{'coursecredits'}{'textbook'}).'</li>'.
16090: '</ul>'.
16091: '</li>';
16092: }
16093: } else {
16094: $resulttext .= '<li>'.&mt('Student credits not in use for courses in this domain').'</li>';
16095: }
16096: } elsif ($item eq 'canclone') {
16097: if (ref($defaultshash{'coursedefaults'}{'canclone'}) eq 'HASH') {
16098: if (ref($defaultshash{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') {
16099: my $clonecodes = join(' '.&mt('and').' ',@{$defaultshash{'coursedefaults'}{'canclone'}{'instcode'}});
16100: $resulttext .= '<li>'.&mt('By default, official courses can be cloned from existing courses with the same: [_1]','<b>'.$clonecodes.'</b>').'</li>';
16101: }
16102: } elsif ($defaultshash{'coursedefaults'}{'canclone'} eq 'domain') {
16103: $resulttext .= '<li>'.&mt('By default, a course requester can clone any course from his/her domain.').'</li>';
16104: } else {
16105: $resulttext .= '<li>'.&mt('By default, only course owner and coordinators may clone a course.').'</li>';
16106: }
16107: }
16108: }
16109: $resulttext .= '</ul>';
16110: } else {
16111: $resulttext = &mt('No changes made to course defaults');
16112: }
16113: } else {
16114: $resulttext = '<span class="LC_error">'.
16115: &mt('An error occurred: [_1]',$putresult).'</span>';
16116: }
16117: return $resulttext;
16118: }
16119:
16120: sub modify_selfenrollment {
16121: my ($dom,$lastactref,%domconfig) = @_;
16122: my ($resulttext,$errors,%changes,%selfenrollhash,%ordered);
16123: my @types = ('official','unofficial','community','textbook','placement');
16124: my %titles = &tool_titles();
16125: my %descs = &Apache::lonuserutils::selfenroll_default_descs();
16126: ($ordered{'admin'},my $titlesref) = &Apache::lonuserutils::get_selfenroll_titles();
16127: $ordered{'default'} = ['types','registered','approval','limit'];
16128:
16129: my (%roles,%shown,%toplevel);
16130: $roles{'0'} = &Apache::lonnet::plaintext('dc');
16131:
16132: if (ref($domconfig{'selfenrollment'}) ne 'HASH') {
16133: if ($domconfig{'selfenrollment'} eq '') {
16134: $domconfig{'selfenrollment'} = {};
16135: }
16136: }
16137: %toplevel = (
16138: admin => 'Configuration Rights',
16139: default => 'Default settings',
16140: validation => 'Validation of self-enrollment requests',
16141: );
16142: my ($itemsref,$namesref,$fieldsref) = &Apache::lonuserutils::selfenroll_validation_types();
16143:
16144: if (ref($ordered{'admin'}) eq 'ARRAY') {
16145: foreach my $item (@{$ordered{'admin'}}) {
16146: foreach my $type (@types) {
16147: if ($env{'form.selfenrolladmin_'.$item.'_'.$type}) {
16148: $selfenrollhash{'admin'}{$type}{$item} = 1;
16149: } else {
16150: $selfenrollhash{'admin'}{$type}{$item} = 0;
16151: }
16152: if (ref($domconfig{'selfenrollment'}{'admin'}) eq 'HASH') {
16153: if (ref($domconfig{'selfenrollment'}{'admin'}{$type}) eq 'HASH') {
16154: if ($selfenrollhash{'admin'}{$type}{$item} ne
16155: $domconfig{'selfenrollment'}{'admin'}{$type}{$item}) {
16156: push(@{$changes{'admin'}{$type}},$item);
16157: }
16158: } else {
16159: if (!$selfenrollhash{'admin'}{$type}{$item}) {
16160: push(@{$changes{'admin'}{$type}},$item);
16161: }
16162: }
16163: } elsif (!$selfenrollhash{'admin'}{$type}{$item}) {
16164: push(@{$changes{'admin'}{$type}},$item);
16165: }
16166: }
16167: }
16168: }
16169:
16170: foreach my $item (@{$ordered{'default'}}) {
16171: foreach my $type (@types) {
16172: my $value = $env{'form.selfenrolldefault_'.$item.'_'.$type};
16173: if ($item eq 'types') {
16174: unless (($value eq 'all') || ($value eq 'dom')) {
16175: $value = '';
16176: }
16177: } elsif ($item eq 'registered') {
16178: unless ($value eq '1') {
16179: $value = 0;
16180: }
16181: } elsif ($item eq 'approval') {
16182: unless ($value =~ /^[012]$/) {
16183: $value = 0;
16184: }
16185: } else {
16186: unless (($value eq 'allstudents') || ($value eq 'selfenrolled')) {
16187: $value = 'none';
16188: }
16189: }
16190: $selfenrollhash{'default'}{$type}{$item} = $value;
16191: if (ref($domconfig{'selfenrollment'}{'default'}) eq 'HASH') {
16192: if (ref($domconfig{'selfenrollment'}{'default'}{$type}) eq 'HASH') {
16193: if ($selfenrollhash{'default'}{$type}{$item} ne
16194: $domconfig{'selfenrollment'}{'default'}{$type}{$item}) {
16195: push(@{$changes{'default'}{$type}},$item);
16196: }
16197: } else {
16198: push(@{$changes{'default'}{$type}},$item);
16199: }
16200: } else {
16201: push(@{$changes{'default'}{$type}},$item);
16202: }
16203: if ($item eq 'limit') {
16204: if (($value eq 'allstudents') || ($value eq 'selfenrolled')) {
16205: $env{'form.selfenrolldefault_cap_'.$type} =~ s/\D//g;
16206: if ($env{'form.selfenrolldefault_cap_'.$type} ne '') {
16207: $selfenrollhash{'default'}{$type}{'cap'} = $env{'form.selfenrolldefault_cap_'.$type};
16208: }
16209: } else {
16210: $selfenrollhash{'default'}{$type}{'cap'} = '';
16211: }
16212: if (ref($domconfig{'selfenrollment'}{'default'}{$type}) eq 'HASH') {
16213: if ($selfenrollhash{'default'}{$type}{'cap'} ne
16214: $domconfig{'selfenrollment'}{'admin'}{$type}{'cap'}) {
16215: push(@{$changes{'default'}{$type}},'cap');
16216: }
16217: } elsif ($selfenrollhash{'default'}{$type}{'cap'} ne '') {
16218: push(@{$changes{'default'}{$type}},'cap');
16219: }
16220: }
16221: }
16222: }
16223:
16224: foreach my $item (@{$itemsref}) {
16225: if ($item eq 'fields') {
16226: my @changed;
16227: @{$selfenrollhash{'validation'}{$item}} = &Apache::loncommon::get_env_multiple('form.selfenroll_validation_'.$item);
16228: if (@{$selfenrollhash{'validation'}{$item}} > 0) {
16229: @{$selfenrollhash{'validation'}{$item}} = sort(@{$selfenrollhash{'validation'}{$item}});
16230: }
16231: if (ref($domconfig{'selfenrollment'}{'validation'}) eq 'HASH') {
16232: if (ref($domconfig{'selfenrollment'}{'validation'}{$item}) eq 'ARRAY') {
16233: @changed = &Apache::loncommon::compare_arrays($selfenrollhash{'validation'}{$item},
16234: $domconfig{'selfenrollment'}{'validation'}{$item});
16235: } else {
16236: @changed = @{$selfenrollhash{'validation'}{$item}};
16237: }
16238: } else {
16239: @changed = @{$selfenrollhash{'validation'}{$item}};
16240: }
16241: if (@changed) {
16242: if ($selfenrollhash{'validation'}{$item}) {
16243: $changes{'validation'}{$item} = join(', ',@{$selfenrollhash{'validation'}{$item}});
16244: } else {
16245: $changes{'validation'}{$item} = &mt('None');
16246: }
16247: }
16248: } else {
16249: $selfenrollhash{'validation'}{$item} = $env{'form.selfenroll_validation_'.$item};
16250: if ($item eq 'markup') {
16251: if ($env{'form.selfenroll_validation_'.$item}) {
16252: $env{'form.selfenroll_validation_'.$item} =~ s/[\n\r\f]+/\s/gs;
16253: }
16254: }
16255: if (ref($domconfig{'selfenrollment'}{'validation'}) eq 'HASH') {
16256: if ($domconfig{'selfenrollment'}{'validation'}{$item} ne $selfenrollhash{'validation'}{$item}) {
16257: $changes{'validation'}{$item} = $selfenrollhash{'validation'}{$item};
16258: }
16259: }
16260: }
16261: }
16262:
16263: my $putresult = &Apache::lonnet::put_dom('configuration',{'selfenrollment' => \%selfenrollhash},
16264: $dom);
16265: if ($putresult eq 'ok') {
16266: if (keys(%changes) > 0) {
16267: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
16268: $resulttext = &mt('Changes made:').'<ul>';
16269: foreach my $key ('admin','default','validation') {
16270: if (ref($changes{$key}) eq 'HASH') {
16271: $resulttext .= '<li>'.$toplevel{$key}.'<ul>';
16272: if ($key eq 'validation') {
16273: foreach my $item (@{$itemsref}) {
16274: if (exists($changes{$key}{$item})) {
16275: if ($item eq 'markup') {
16276: $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$namesref->{$item},
16277: '<br /><pre>'.$changes{$key}{$item}.'</pre>').'</li>';
16278: } else {
16279: $resulttext .= '<li>'.&mt('[_1] set to: [_2]',$namesref->{$item},
16280: '<b>'.$changes{$key}{$item}.'</b>').'</li>';
16281: }
16282: }
16283: }
16284: } else {
16285: foreach my $type (@types) {
16286: if ($type eq 'community') {
16287: $roles{'1'} = &mt('Community personnel');
16288: } else {
16289: $roles{'1'} = &mt('Course personnel');
16290: }
16291: if (ref($changes{$key}{$type}) eq 'ARRAY') {
16292: if (ref($selfenrollhash{$key}{$type}) eq 'HASH') {
16293: if ($key eq 'admin') {
16294: my @mgrdc = ();
16295: if (ref($ordered{$key}) eq 'ARRAY') {
16296: foreach my $item (@{$ordered{'admin'}}) {
16297: if (ref($selfenrollhash{$key}{$type}) eq 'HASH') {
16298: if ($selfenrollhash{$key}{$type}{$item} eq '0') {
16299: push(@mgrdc,$item);
16300: }
16301: }
16302: }
16303: if (@mgrdc) {
16304: $domdefaults{$type.'selfenrolladmdc'} = join(',',@mgrdc);
16305: } else {
16306: delete($domdefaults{$type.'selfenrolladmdc'});
16307: }
16308: }
16309: } else {
16310: if (ref($ordered{$key}) eq 'ARRAY') {
16311: foreach my $item (@{$ordered{$key}}) {
16312: if (grep(/^\Q$item\E$/,@{$changes{$key}{$type}})) {
16313: $domdefaults{$type.'selfenroll'.$item} =
16314: $selfenrollhash{$key}{$type}{$item};
16315: }
16316: }
16317: }
16318: }
16319: }
16320: $resulttext .= '<li>'.$titles{$type}.'<ul>';
16321: foreach my $item (@{$ordered{$key}}) {
16322: if (grep(/^\Q$item\E$/,@{$changes{$key}{$type}})) {
16323: $resulttext .= '<li>';
16324: if ($key eq 'admin') {
16325: $resulttext .= &mt('[_1] -- management by: [_2]',$titlesref->{$item},
16326: '<b>'.$roles{$selfenrollhash{'admin'}{$type}{$item}}.'</b>');
16327: } else {
16328: $resulttext .= &mt('[_1] set to: [_2]',$titlesref->{$item},
16329: '<b>'.$descs{$item}{$selfenrollhash{'default'}{$type}{$item}}.'</b>');
16330: }
16331: $resulttext .= '</li>';
16332: }
16333: }
16334: $resulttext .= '</ul></li>';
16335: }
16336: }
16337: $resulttext .= '</ul></li>';
16338: }
16339: }
16340: }
16341: if ((exists($changes{'admin'})) || (exists($changes{'default'}))) {
16342: my $cachetime = 24*60*60;
16343: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
16344: if (ref($lastactref) eq 'HASH') {
16345: $lastactref->{'domdefaults'} = 1;
16346: }
16347: }
16348: $resulttext .= '</ul>';
16349: } else {
16350: $resulttext = &mt('No changes made to self-enrollment settings');
16351: }
16352: } else {
16353: $resulttext = '<span class="LC_error">'.
16354: &mt('An error occurred: [_1]',$putresult).'</span>';
16355: }
16356: return $resulttext;
16357: }
16358:
16359: sub modify_usersessions {
16360: my ($dom,$lastactref,%domconfig) = @_;
16361: my @hostingtypes = ('version','excludedomain','includedomain');
16362: my @offloadtypes = ('primary','default');
16363: my %types = (
16364: remote => \@hostingtypes,
16365: hosted => \@hostingtypes,
16366: spares => \@offloadtypes,
16367: );
16368: my @prefixes = ('remote','hosted','spares');
16369: my @lcversions = &Apache::lonnet::all_loncaparevs();
16370: my (%by_ip,%by_location,@intdoms,@instdoms);
16371: &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
16372: my @locations = sort(keys(%by_location));
16373: my (%defaultshash,%changes);
16374: foreach my $prefix (@prefixes) {
16375: $defaultshash{'usersessions'}{$prefix} = {};
16376: }
16377: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
16378: my $resulttext;
16379: my %iphost = &Apache::lonnet::get_iphost();
16380: foreach my $prefix (@prefixes) {
16381: next if ($prefix eq 'spares');
16382: foreach my $type (@{$types{$prefix}}) {
16383: my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
16384: if ($type eq 'version') {
16385: my $value = $env{'form.'.$prefix.'_'.$type};
16386: my $okvalue;
16387: if ($value ne '') {
16388: if (grep(/^\Q$value\E$/,@lcversions)) {
16389: $okvalue = $value;
16390: }
16391: }
16392: if (ref($domconfig{'usersessions'}) eq 'HASH') {
16393: if (ref($domconfig{'usersessions'}{$prefix}) eq 'HASH') {
16394: if ($domconfig{'usersessions'}{$prefix}{$type} ne '') {
16395: if ($inuse == 0) {
16396: $changes{$prefix}{$type} = 1;
16397: } else {
16398: if ($okvalue ne $domconfig{'usersessions'}{$prefix}{$type}) {
16399: $changes{$prefix}{$type} = 1;
16400: }
16401: if ($okvalue ne '') {
16402: $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue;
16403: }
16404: }
16405: } else {
16406: if (($inuse == 1) && ($okvalue ne '')) {
16407: $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue;
16408: $changes{$prefix}{$type} = 1;
16409: }
16410: }
16411: } else {
16412: if (($inuse == 1) && ($okvalue ne '')) {
16413: $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue;
16414: $changes{$prefix}{$type} = 1;
16415: }
16416: }
16417: } else {
16418: if (($inuse == 1) && ($okvalue ne '')) {
16419: $defaultshash{'usersessions'}{$prefix}{$type} = $okvalue;
16420: $changes{$prefix}{$type} = 1;
16421: }
16422: }
16423: } else {
16424: my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
16425: my @okvals;
16426: foreach my $val (@vals) {
16427: if ($val =~ /:/) {
16428: my @items = split(/:/,$val);
16429: foreach my $item (@items) {
16430: if (ref($by_location{$item}) eq 'ARRAY') {
16431: push(@okvals,$item);
16432: }
16433: }
16434: } else {
16435: if (ref($by_location{$val}) eq 'ARRAY') {
16436: push(@okvals,$val);
16437: }
16438: }
16439: }
16440: @okvals = sort(@okvals);
16441: if (ref($domconfig{'usersessions'}) eq 'HASH') {
16442: if (ref($domconfig{'usersessions'}{$prefix}) eq 'HASH') {
16443: if (ref($domconfig{'usersessions'}{$prefix}{$type}) eq 'ARRAY') {
16444: if ($inuse == 0) {
16445: $changes{$prefix}{$type} = 1;
16446: } else {
16447: $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals;
16448: my @changed = &Apache::loncommon::compare_arrays($domconfig{'usersessions'}{$prefix}{$type},$defaultshash{'usersessions'}{$prefix}{$type});
16449: if (@changed > 0) {
16450: $changes{$prefix}{$type} = 1;
16451: }
16452: }
16453: } else {
16454: if ($inuse == 1) {
16455: $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals;
16456: $changes{$prefix}{$type} = 1;
16457: }
16458: }
16459: } else {
16460: if ($inuse == 1) {
16461: $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals;
16462: $changes{$prefix}{$type} = 1;
16463: }
16464: }
16465: } else {
16466: if ($inuse == 1) {
16467: $defaultshash{'usersessions'}{$prefix}{$type} = \@okvals;
16468: $changes{$prefix}{$type} = 1;
16469: }
16470: }
16471: }
16472: }
16473: }
16474:
16475: my @alldoms = &Apache::lonnet::all_domains();
16476: my %servers = &Apache::lonnet::internet_dom_servers($dom);
16477: my %spareid = ¤t_offloads_to($dom,$domconfig{'usersessions'},\%servers);
16478: my $savespares;
16479:
16480: foreach my $lonhost (sort(keys(%servers))) {
16481: my $serverhomeID =
16482: &Apache::lonnet::get_server_homeID($servers{$lonhost});
16483: my $serverhostname = &Apache::lonnet::hostname($lonhost);
16484: $defaultshash{'usersessions'}{'spares'}{$lonhost} = {};
16485: my %spareschg;
16486: foreach my $type (@{$types{'spares'}}) {
16487: my @okspares;
16488: my @checked = &Apache::loncommon::get_env_multiple('form.spare_'.$type.'_'.$lonhost);
16489: foreach my $server (@checked) {
16490: if (&Apache::lonnet::hostname($server) ne '') {
16491: unless (&Apache::lonnet::hostname($server) eq $serverhostname) {
16492: unless (grep(/^\Q$server\E$/,@okspares)) {
16493: push(@okspares,$server);
16494: }
16495: }
16496: }
16497: }
16498: my $new = $env{'form.newspare_'.$type.'_'.$lonhost};
16499: my $newspare;
16500: if (($new ne '') && (&Apache::lonnet::hostname($new))) {
16501: unless (&Apache::lonnet::hostname($new) eq $serverhostname) {
16502: $newspare = $new;
16503: }
16504: }
16505: my @spares;
16506: if (($newspare ne '') && (!grep(/^\Q$newspare\E$/,@okspares))) {
16507: @spares = sort(@okspares,$newspare);
16508: } else {
16509: @spares = sort(@okspares);
16510: }
16511: $defaultshash{'usersessions'}{'spares'}{$lonhost}{$type} = \@spares;
16512: if (ref($spareid{$lonhost}) eq 'HASH') {
16513: if (ref($spareid{$lonhost}{$type}) eq 'ARRAY') {
16514: my @diffs = &Apache::loncommon::compare_arrays($spareid{$lonhost}{$type},\@spares);
16515: if (@diffs > 0) {
16516: $spareschg{$type} = 1;
16517: }
16518: }
16519: }
16520: }
16521: if (keys(%spareschg) > 0) {
16522: $changes{'spares'}{$lonhost} = \%spareschg;
16523: }
16524: }
16525: $defaultshash{'usersessions'}{'offloadnow'} = {};
16526: my @offloadnow = &Apache::loncommon::get_env_multiple('form.offloadnow');
16527: my @okoffload;
16528: if (@offloadnow) {
16529: foreach my $server (@offloadnow) {
16530: if (&Apache::lonnet::hostname($server) ne '') {
16531: unless (grep(/^\Q$server\E$/,@okoffload)) {
16532: push(@okoffload,$server);
16533: }
16534: }
16535: }
16536: if (@okoffload) {
16537: foreach my $lonhost (@okoffload) {
16538: $defaultshash{'usersessions'}{'offloadnow'}{$lonhost} = 1;
16539: }
16540: }
16541: }
16542: if (ref($domconfig{'usersessions'}) eq 'HASH') {
16543: if (ref($domconfig{'usersessions'}{'spares'}) eq 'HASH') {
16544: if (ref($changes{'spares'}) eq 'HASH') {
16545: if (keys(%{$changes{'spares'}}) > 0) {
16546: $savespares = 1;
16547: }
16548: }
16549: } else {
16550: $savespares = 1;
16551: }
16552: if (ref($domconfig{'usersessions'}{'offloadnow'}) eq 'HASH') {
16553: foreach my $lonhost (keys(%{$domconfig{'usersessions'}{'offloadnow'}})) {
16554: unless ($defaultshash{'usersessions'}{'offloadnow'}{$lonhost}) {
16555: $changes{'offloadnow'} = 1;
16556: last;
16557: }
16558: }
16559: unless ($changes{'offloadnow'}) {
16560: foreach my $lonhost (keys(%{$defaultshash{'usersessions'}{'offloadnow'}})) {
16561: unless ($domconfig{'usersessions'}{'offloadnow'}{$lonhost}) {
16562: $changes{'offloadnow'} = 1;
16563: last;
16564: }
16565: }
16566: }
16567: } elsif (@okoffload) {
16568: $changes{'offloadnow'} = 1;
16569: }
16570: } elsif (@okoffload) {
16571: $changes{'offloadnow'} = 1;
16572: }
16573: my $nochgmsg = &mt('No changes made to settings for user session hosting/offloading.');
16574: if ((keys(%changes) > 0) || ($savespares)) {
16575: my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
16576: $dom);
16577: if ($putresult eq 'ok') {
16578: if (ref($defaultshash{'usersessions'}) eq 'HASH') {
16579: if (ref($defaultshash{'usersessions'}{'remote'}) eq 'HASH') {
16580: $domdefaults{'remotesessions'} = $defaultshash{'usersessions'}{'remote'};
16581: }
16582: if (ref($defaultshash{'usersessions'}{'hosted'}) eq 'HASH') {
16583: $domdefaults{'hostedsessions'} = $defaultshash{'usersessions'}{'hosted'};
16584: }
16585: if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') {
16586: $domdefaults{'offloadnow'} = $defaultshash{'usersessions'}{'offloadnow'};
16587: }
16588: }
16589: my $cachetime = 24*60*60;
16590: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
16591: &Apache::lonnet::do_cache_new('usersessions',$dom,$defaultshash{'usersessions'},3600);
16592: if (ref($lastactref) eq 'HASH') {
16593: $lastactref->{'domdefaults'} = 1;
16594: $lastactref->{'usersessions'} = 1;
16595: }
16596: if (keys(%changes) > 0) {
16597: my %lt = &usersession_titles();
16598: $resulttext = &mt('Changes made:').'<ul>';
16599: foreach my $prefix (@prefixes) {
16600: if (ref($changes{$prefix}) eq 'HASH') {
16601: $resulttext .= '<li>'.$lt{$prefix}.'<ul>';
16602: if ($prefix eq 'spares') {
16603: if (ref($changes{$prefix}) eq 'HASH') {
16604: foreach my $lonhost (sort(keys(%{$changes{$prefix}}))) {
16605: $resulttext .= '<li><b>'.$lonhost.'</b> ';
16606: my $lonhostdom = &Apache::lonnet::host_domain($lonhost);
16607: my $cachekey = &escape('spares').':'.&escape($lonhostdom);
16608: &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]);
16609: if (ref($changes{$prefix}{$lonhost}) eq 'HASH') {
16610: foreach my $type (@{$types{$prefix}}) {
16611: if ($changes{$prefix}{$lonhost}{$type}) {
16612: my $offloadto = &mt('None');
16613: if (ref($defaultshash{'usersessions'}{'spares'}{$lonhost}{$type}) eq 'ARRAY') {
16614: if (@{$defaultshash{'usersessions'}{'spares'}{$lonhost}{$type}} > 0) {
16615: $offloadto = join(', ',@{$defaultshash{'usersessions'}{'spares'}{$lonhost}{$type}});
16616: }
16617: }
16618: $resulttext .= &mt('[_1] set to: [_2].','<i>'.$lt{$type}.'</i>',$offloadto).(' 'x3);
16619: }
16620: }
16621: }
16622: $resulttext .= '</li>';
16623: }
16624: }
16625: } else {
16626: foreach my $type (@{$types{$prefix}}) {
16627: if (defined($changes{$prefix}{$type})) {
16628: my $newvalue;
16629: if (ref($defaultshash{'usersessions'}) eq 'HASH') {
16630: if (ref($defaultshash{'usersessions'}{$prefix})) {
16631: if ($type eq 'version') {
16632: $newvalue = $defaultshash{'usersessions'}{$prefix}{$type};
16633: } elsif (ref($defaultshash{'usersessions'}{$prefix}{$type}) eq 'ARRAY') {
16634: if (@{$defaultshash{'usersessions'}{$prefix}{$type}} > 0) {
16635: $newvalue = join(', ',@{$defaultshash{'usersessions'}{$prefix}{$type}});
16636: }
16637: }
16638: }
16639: }
16640: if ($newvalue eq '') {
16641: if ($type eq 'version') {
16642: $resulttext .= '<li>'.&mt('[_1] set to: off',$lt{$type}).'</li>';
16643: } else {
16644: $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';
16645: }
16646: } else {
16647: if ($type eq 'version') {
16648: $newvalue .= ' '.&mt('(or later)');
16649: }
16650: $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';
16651: }
16652: }
16653: }
16654: }
16655: $resulttext .= '</ul>';
16656: }
16657: }
16658: if ($changes{'offloadnow'}) {
16659: if (ref($defaultshash{'usersessions'}{'offloadnow'}) eq 'HASH') {
16660: if (keys(%{$defaultshash{'usersessions'}{'offloadnow'}}) > 0) {
16661: $resulttext .= '<li>'.&mt('Switch active users on next access, for server(s):').'<ul>';
16662: foreach my $lonhost (sort(keys(%{$defaultshash{'usersessions'}{'offloadnow'}}))) {
16663: $resulttext .= '<li>'.$lonhost.'</li>';
16664: }
16665: $resulttext .= '</ul>';
16666: } else {
16667: $resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.');
16668: }
16669: } else {
16670: $resulttext .= '<li>'.&mt('No servers now set to switch active users on next access.').'</li>';
16671: }
16672: }
16673: $resulttext .= '</ul>';
16674: } else {
16675: $resulttext = $nochgmsg;
16676: }
16677: } else {
16678: $resulttext = '<span class="LC_error">'.
16679: &mt('An error occurred: [_1]',$putresult).'</span>';
16680: }
16681: } else {
16682: $resulttext = $nochgmsg;
16683: }
16684: return $resulttext;
16685: }
16686:
16687: sub modify_ssl {
16688: my ($dom,$lastactref,%domconfig) = @_;
16689: my (%by_ip,%by_location,@intdoms,@instdoms);
16690: &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
16691: my @locations = sort(keys(%by_location));
16692: my %servers = &Apache::lonnet::internet_dom_servers($dom);
16693: my (%defaultshash,%changes);
16694: my $action = 'ssl';
16695: my @prefixes = ('connto','connfrom','replication');
16696: foreach my $prefix (@prefixes) {
16697: $defaultshash{$action}{$prefix} = {};
16698: }
16699: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
16700: my $resulttext;
16701: my %iphost = &Apache::lonnet::get_iphost();
16702: my @reptypes = ('certreq','nocertreq');
16703: my @connecttypes = ('dom','intdom','other');
16704: my %types = (
16705: connto => \@connecttypes,
16706: connfrom => \@connecttypes,
16707: replication => \@reptypes,
16708: );
16709: foreach my $prefix (sort(keys(%types))) {
16710: foreach my $type (@{$types{$prefix}}) {
16711: if (($prefix eq 'connto') || ($prefix eq 'connfrom')) {
16712: my $value = 'yes';
16713: if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) {
16714: $value = $env{'form.'.$prefix.'_'.$type};
16715: }
16716: if (ref($domconfig{$action}) eq 'HASH') {
16717: if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
16718: if ($domconfig{$action}{$prefix}{$type} ne '') {
16719: if ($value ne $domconfig{$action}{$prefix}{$type}) {
16720: $changes{$prefix}{$type} = 1;
16721: }
16722: $defaultshash{$action}{$prefix}{$type} = $value;
16723: } else {
16724: $defaultshash{$action}{$prefix}{$type} = $value;
16725: $changes{$prefix}{$type} = 1;
16726: }
16727: } else {
16728: $defaultshash{$action}{$prefix}{$type} = $value;
16729: $changes{$prefix}{$type} = 1;
16730: }
16731: } else {
16732: $defaultshash{$action}{$prefix}{$type} = $value;
16733: $changes{$prefix}{$type} = 1;
16734: }
16735: if (($type eq 'dom') && (keys(%servers) == 1)) {
16736: delete($changes{$prefix}{$type});
16737: } elsif (($type eq 'intdom') && (@instdoms == 1)) {
16738: delete($changes{$prefix}{$type});
16739: } elsif (($type eq 'other') && (keys(%by_location) == 0)) {
16740: delete($changes{$prefix}{$type});
16741: }
16742: } elsif ($prefix eq 'replication') {
16743: if (@locations > 0) {
16744: my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
16745: my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
16746: my @okvals;
16747: foreach my $val (@vals) {
16748: if ($val =~ /:/) {
16749: my @items = split(/:/,$val);
16750: foreach my $item (@items) {
16751: if (ref($by_location{$item}) eq 'ARRAY') {
16752: push(@okvals,$item);
16753: }
16754: }
16755: } else {
16756: if (ref($by_location{$val}) eq 'ARRAY') {
16757: push(@okvals,$val);
16758: }
16759: }
16760: }
16761: @okvals = sort(@okvals);
16762: if (ref($domconfig{$action}) eq 'HASH') {
16763: if (ref($domconfig{$action}{$prefix}) eq 'HASH') {
16764: if (ref($domconfig{$action}{$prefix}{$type}) eq 'ARRAY') {
16765: if ($inuse == 0) {
16766: $changes{$prefix}{$type} = 1;
16767: } else {
16768: $defaultshash{$action}{$prefix}{$type} = \@okvals;
16769: my @changed = &Apache::loncommon::compare_arrays($domconfig{$action}{$prefix}{$type},$defaultshash{$action}{$prefix}{$type});
16770: if (@changed > 0) {
16771: $changes{$prefix}{$type} = 1;
16772: }
16773: }
16774: } else {
16775: if ($inuse == 1) {
16776: $defaultshash{$action}{$prefix}{$type} = \@okvals;
16777: $changes{$prefix}{$type} = 1;
16778: }
16779: }
16780: } else {
16781: if ($inuse == 1) {
16782: $defaultshash{$action}{$prefix}{$type} = \@okvals;
16783: $changes{$prefix}{$type} = 1;
16784: }
16785: }
16786: } else {
16787: if ($inuse == 1) {
16788: $defaultshash{$action}{$prefix}{$type} = \@okvals;
16789: $changes{$prefix}{$type} = 1;
16790: }
16791: }
16792: }
16793: }
16794: }
16795: }
16796: if (keys(%changes)) {
16797: foreach my $prefix (keys(%changes)) {
16798: if (ref($changes{$prefix}) eq 'HASH') {
16799: if (scalar(keys(%{$changes{$prefix}})) == 0) {
16800: delete($changes{$prefix});
16801: }
16802: } else {
16803: delete($changes{$prefix});
16804: }
16805: }
16806: }
16807: my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings');
16808: if (keys(%changes) > 0) {
16809: my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
16810: $dom);
16811: if ($putresult eq 'ok') {
16812: if (ref($defaultshash{$action}) eq 'HASH') {
16813: if (ref($defaultshash{$action}{'replication'}) eq 'HASH') {
16814: $domdefaults{'replication'} = $defaultshash{$action}{'replication'};
16815: }
16816: if (ref($defaultshash{$action}{'connto'}) eq 'HASH') {
16817: $domdefaults{'connto'} = $defaultshash{$action}{'connto'};
16818: }
16819: if (ref($defaultshash{$action}{'connfrom'}) eq 'HASH') {
16820: $domdefaults{'connfrom'} = $defaultshash{$action}{'connfrom'};
16821: }
16822: }
16823: my $cachetime = 24*60*60;
16824: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
16825: if (ref($lastactref) eq 'HASH') {
16826: $lastactref->{'domdefaults'} = 1;
16827: }
16828: if (keys(%changes) > 0) {
16829: my %titles = &ssl_titles();
16830: $resulttext = &mt('Changes made:').'<ul>';
16831: foreach my $prefix (@prefixes) {
16832: if (ref($changes{$prefix}) eq 'HASH') {
16833: $resulttext .= '<li>'.$titles{$prefix}.'<ul>';
16834: foreach my $type (@{$types{$prefix}}) {
16835: if (defined($changes{$prefix}{$type})) {
16836: my $newvalue;
16837: if (ref($defaultshash{$action}) eq 'HASH') {
16838: if (ref($defaultshash{$action}{$prefix})) {
16839: if (($prefix eq 'connto') || ($prefix eq 'connfrom')) {
16840: $newvalue = $titles{$defaultshash{$action}{$prefix}{$type}};
16841: } elsif (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') {
16842: if (@{$defaultshash{$action}{$prefix}{$type}} > 0) {
16843: $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}});
16844: }
16845: }
16846: }
16847: if ($newvalue eq '') {
16848: $resulttext .= '<li>'.&mt('[_1] set to: none',$titles{$type}).'</li>';
16849: } else {
16850: $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'</li>';
16851: }
16852: }
16853: }
16854: }
16855: $resulttext .= '</ul>';
16856: }
16857: }
16858: } else {
16859: $resulttext = $nochgmsg;
16860: }
16861: } else {
16862: $resulttext = '<span class="LC_error">'.
16863: &mt('An error occurred: [_1]',$putresult).'</span>';
16864: }
16865: } else {
16866: $resulttext = $nochgmsg;
16867: }
16868: return $resulttext;
16869: }
16870:
16871: sub modify_trust {
16872: my ($dom,$lastactref,%domconfig) = @_;
16873: my (%by_ip,%by_location,@intdoms,@instdoms);
16874: &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms);
16875: my @locations = sort(keys(%by_location));
16876: my @prefixes = qw(content shared enroll othcoau coaurem domroles catalog reqcrs msg);
16877: my @types = ('exc','inc');
16878: my (%defaultshash,%changes);
16879: foreach my $prefix (@prefixes) {
16880: $defaultshash{'trust'}{$prefix} = {};
16881: }
16882: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1);
16883: my $resulttext;
16884: foreach my $prefix (@prefixes) {
16885: foreach my $type (@types) {
16886: my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'};
16887: my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type);
16888: my @okvals;
16889: foreach my $val (@vals) {
16890: if ($val =~ /:/) {
16891: my @items = split(/:/,$val);
16892: foreach my $item (@items) {
16893: if (ref($by_location{$item}) eq 'ARRAY') {
16894: push(@okvals,$item);
16895: }
16896: }
16897: } else {
16898: if (ref($by_location{$val}) eq 'ARRAY') {
16899: push(@okvals,$val);
16900: }
16901: }
16902: }
16903: @okvals = sort(@okvals);
16904: if (ref($domconfig{'trust'}) eq 'HASH') {
16905: if (ref($domconfig{'trust'}{$prefix}) eq 'HASH') {
16906: if (ref($domconfig{'trust'}{$prefix}{$type}) eq 'ARRAY') {
16907: if ($inuse == 0) {
16908: $changes{$prefix}{$type} = 1;
16909: } else {
16910: $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
16911: my @changed = &Apache::loncommon::compare_arrays($domconfig{'trust'}{$prefix}{$type},$defaultshash{'trust'}{$prefix}{$type});
16912: if (@changed > 0) {
16913: $changes{$prefix}{$type} = 1;
16914: }
16915: }
16916: } else {
16917: if ($inuse == 1) {
16918: $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
16919: $changes{$prefix}{$type} = 1;
16920: }
16921: }
16922: } else {
16923: if ($inuse == 1) {
16924: $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
16925: $changes{$prefix}{$type} = 1;
16926: }
16927: }
16928: } else {
16929: if ($inuse == 1) {
16930: $defaultshash{'trust'}{$prefix}{$type} = \@okvals;
16931: $changes{$prefix}{$type} = 1;
16932: }
16933: }
16934: }
16935: }
16936: my $nochgmsg = &mt('No changes made to trust settings.');
16937: if (keys(%changes) > 0) {
16938: my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
16939: $dom);
16940: if ($putresult eq 'ok') {
16941: if (ref($defaultshash{'trust'}) eq 'HASH') {
16942: foreach my $prefix (@prefixes) {
16943: if (ref($defaultshash{'trust'}{$prefix}) eq 'HASH') {
16944: $domdefaults{'trust'.$prefix} = $defaultshash{'trust'}{$prefix};
16945: }
16946: }
16947: }
16948: my $cachetime = 24*60*60;
16949: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
16950: if (ref($lastactref) eq 'HASH') {
16951: $lastactref->{'domdefaults'} = 1;
16952: }
16953: if (keys(%changes) > 0) {
16954: my %lt = &trust_titles();
16955: $resulttext = &mt('Changes made:').'<ul>';
16956: foreach my $prefix (@prefixes) {
16957: if (ref($changes{$prefix}) eq 'HASH') {
16958: $resulttext .= '<li>'.$lt{$prefix}.'<ul>';
16959: foreach my $type (@types) {
16960: if (defined($changes{$prefix}{$type})) {
16961: my $newvalue;
16962: if (ref($defaultshash{'trust'}) eq 'HASH') {
16963: if (ref($defaultshash{'trust'}{$prefix})) {
16964: if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') {
16965: if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) {
16966: $newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}});
16967: }
16968: }
16969: }
16970: }
16971: if ($newvalue eq '') {
16972: $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>';
16973: } else {
16974: $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>';
16975: }
16976: }
16977: }
16978: $resulttext .= '</ul>';
16979: }
16980: }
16981: $resulttext .= '</ul>';
16982: } else {
16983: $resulttext = $nochgmsg;
16984: }
16985: } else {
16986: $resulttext = '<span class="LC_error">'.
16987: &mt('An error occurred: [_1]',$putresult).'</span>';
16988: }
16989: } else {
16990: $resulttext = $nochgmsg;
16991: }
16992: return $resulttext;
16993: }
16994:
16995: sub modify_loadbalancing {
16996: my ($dom,%domconfig) = @_;
16997: my $primary_id = &Apache::lonnet::domain($dom,'primary');
16998: my $intdom = &Apache::lonnet::internet_dom($primary_id);
16999: my ($othertitle,$usertypes,$types) =
17000: &Apache::loncommon::sorted_inst_types($dom);
17001: my %servers = &Apache::lonnet::internet_dom_servers($dom);
17002: my %libraryservers = &Apache::lonnet::get_servers($dom,'library');
17003: my @sparestypes = ('primary','default');
17004: my %typetitles = &sparestype_titles();
17005: my $resulttext;
17006: my (%currbalancer,%currtargets,%currrules,%existing);
17007: if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
17008: %existing = %{$domconfig{'loadbalancing'}};
17009: }
17010: &get_loadbalancers_config(\%servers,\%existing,\%currbalancer,
17011: \%currtargets,\%currrules);
17012: my ($saveloadbalancing,%defaultshash,%changes);
17013: my ($alltypes,$othertypes,$titles) =
17014: &loadbalancing_titles($dom,$intdom,$usertypes,$types);
17015: my %ruletitles = &offloadtype_text();
17016: my @deletions = &Apache::loncommon::get_env_multiple('form.loadbalancing_delete');
17017: for (my $i=0; $i<$env{'form.loadbalancing_total'}; $i++) {
17018: my $balancer = $env{'form.loadbalancing_lonhost_'.$i};
17019: if ($balancer eq '') {
17020: next;
17021: }
17022: if (!exists($servers{$balancer})) {
17023: if (exists($currbalancer{$balancer})) {
17024: push(@{$changes{'delete'}},$balancer);
17025: }
17026: next;
17027: }
17028: if ((@deletions > 0) && (grep(/^\Q$i\E$/,@deletions))) {
17029: push(@{$changes{'delete'}},$balancer);
17030: next;
17031: }
17032: if (!exists($currbalancer{$balancer})) {
17033: push(@{$changes{'add'}},$balancer);
17034: }
17035: $defaultshash{'loadbalancing'}{$balancer}{'targets'}{'primary'} = [];
17036: $defaultshash{'loadbalancing'}{$balancer}{'targets'}{'default'} = [];
17037: $defaultshash{'loadbalancing'}{$balancer}{'rules'} = {};
17038: unless (ref($domconfig{'loadbalancing'}) eq 'HASH') {
17039: $saveloadbalancing = 1;
17040: }
17041: foreach my $sparetype (@sparestypes) {
17042: my @targets = &Apache::loncommon::get_env_multiple('form.loadbalancing_target_'.$i.'_'.$sparetype);
17043: my @offloadto;
17044: foreach my $target (@targets) {
17045: if (($servers{$target}) && ($target ne $balancer)) {
17046: if ($sparetype eq 'default') {
17047: if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{'primary'}) eq 'ARRAY') {
17048: next if (grep(/^\Q$target\E$/,@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{'primary'}}));
17049: }
17050: }
17051: unless(grep(/^\Q$target\E$/,@offloadto)) {
17052: push(@offloadto,$target);
17053: }
17054: }
17055: }
17056: if ($env{'form.loadbalancing_target_'.$i.'_hosthere'} eq $sparetype) {
17057: unless(grep(/^\Q$balancer\E$/,@offloadto)) {
17058: push(@offloadto,$balancer);
17059: }
17060: }
17061: $defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype} = \@offloadto;
17062: }
17063: if (ref($currtargets{$balancer}) eq 'HASH') {
17064: foreach my $sparetype (@sparestypes) {
17065: if (ref($currtargets{$balancer}{$sparetype}) eq 'ARRAY') {
17066: my @targetdiffs = &Apache::loncommon::compare_arrays($currtargets{$balancer}{$sparetype},$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype});
17067: if (@targetdiffs > 0) {
17068: $changes{'curr'}{$balancer}{'targets'} = 1;
17069: }
17070: } elsif (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
17071: if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
17072: $changes{'curr'}{$balancer}{'targets'} = 1;
17073: }
17074: }
17075: }
17076: } else {
17077: if (ref($defaultshash{'loadbalancing'}{$balancer}) eq 'HASH') {
17078: foreach my $sparetype (@sparestypes) {
17079: if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
17080: if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
17081: $changes{'curr'}{$balancer}{'targets'} = 1;
17082: }
17083: }
17084: }
17085: }
17086: }
17087: my $ishomedom;
17088: if (&Apache::lonnet::host_domain($balancer) eq $dom) {
17089: $ishomedom = 1;
17090: }
17091: if (ref($alltypes) eq 'ARRAY') {
17092: foreach my $type (@{$alltypes}) {
17093: my $rule;
17094: unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) &&
17095: (!$ishomedom)) {
17096: $rule = $env{'form.loadbalancing_rules_'.$i.'_'.$type};
17097: }
17098: if ($rule eq 'specific') {
17099: my $specifiedhost = $env{'form.loadbalancing_singleserver_'.$i.'_'.$type};
17100: if (exists($servers{$specifiedhost})) {
17101: $rule = $specifiedhost;
17102: }
17103: }
17104: $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type} = $rule;
17105: if (ref($currrules{$balancer}) eq 'HASH') {
17106: if ($rule ne $currrules{$balancer}{$type}) {
17107: $changes{'curr'}{$balancer}{'rules'}{$type} = 1;
17108: }
17109: } elsif ($rule ne '') {
17110: $changes{'curr'}{$balancer}{'rules'}{$type} = 1;
17111: }
17112: }
17113: }
17114: }
17115: my $nochgmsg = &mt('No changes made to Load Balancer settings.');
17116: if ((keys(%changes) > 0) || ($saveloadbalancing)) {
17117: unless (ref($defaultshash{'loadbalancing'}) eq 'HASH') {
17118: $defaultshash{'loadbalancing'} = {};
17119: }
17120: my $putresult = &Apache::lonnet::put_dom('configuration',
17121: \%defaultshash,$dom);
17122: if ($putresult eq 'ok') {
17123: if (keys(%changes) > 0) {
17124: my %toupdate;
17125: if (ref($changes{'delete'}) eq 'ARRAY') {
17126: foreach my $balancer (sort(@{$changes{'delete'}})) {
17127: $resulttext .= '<li>'.&mt('Load Balancing discontinued for: [_1]',$balancer).'</li>';
17128: $toupdate{$balancer} = 1;
17129: }
17130: }
17131: if (ref($changes{'add'}) eq 'ARRAY') {
17132: foreach my $balancer (sort(@{$changes{'add'}})) {
17133: $resulttext .= '<li>'.&mt('Load Balancing enabled for: [_1]',$balancer);
17134: $toupdate{$balancer} = 1;
17135: }
17136: }
17137: if (ref($changes{'curr'}) eq 'HASH') {
17138: foreach my $balancer (sort(keys(%{$changes{'curr'}}))) {
17139: $toupdate{$balancer} = 1;
17140: if (ref($changes{'curr'}{$balancer}) eq 'HASH') {
17141: if ($changes{'curr'}{$balancer}{'targets'}) {
17142: my %offloadstr;
17143: foreach my $sparetype (@sparestypes) {
17144: if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
17145: if (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}} > 0) {
17146: $offloadstr{$sparetype} = join(', ',@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}});
17147: }
17148: }
17149: }
17150: if (keys(%offloadstr) == 0) {
17151: $resulttext .= '<li>'.&mt("Servers to which Load Balance server offloads set to 'None', by default").'</li>';
17152: } else {
17153: my $showoffload;
17154: foreach my $sparetype (@sparestypes) {
17155: $showoffload .= '<i>'.$typetitles{$sparetype}.'</i>: ';
17156: if (defined($offloadstr{$sparetype})) {
17157: $showoffload .= $offloadstr{$sparetype};
17158: } else {
17159: $showoffload .= &mt('None');
17160: }
17161: $showoffload .= (' 'x3);
17162: }
17163: $resulttext .= '<li>'.&mt('By default, Load Balancer: [_1] set to offload to - [_2]',$balancer,$showoffload).'</li>';
17164: }
17165: }
17166: }
17167: if (ref($changes{'curr'}{$balancer}{'rules'}) eq 'HASH') {
17168: if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH')) {
17169: foreach my $type (@{$alltypes}) {
17170: if ($changes{'curr'}{$balancer}{'rules'}{$type}) {
17171: my $rule = $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type};
17172: my $balancetext;
17173: if ($rule eq '') {
17174: $balancetext = $ruletitles{'default'};
17175: } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer') ||
17176: ($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {
17177: if (($type eq '_LC_ipchange') || ($type eq '_LC_ipchangesso')) {
17178: foreach my $sparetype (@sparestypes) {
17179: if (ref($defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}) eq 'ARRAY') {
17180: map { $toupdate{$_} = 1; } (@{$defaultshash{'loadbalancing'}{$balancer}{'targets'}{$sparetype}});
17181: }
17182: }
17183: foreach my $item (@{$alltypes}) {
17184: next if ($item =~ /^_LC_ipchange/);
17185: my $hasrule = $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$item};
17186: if ($hasrule eq 'homeserver') {
17187: map { $toupdate{$_} = 1; } (keys(%libraryservers));
17188: } else {
17189: unless (($hasrule eq 'default') || ($hasrule eq 'none') || ($hasrule eq 'externalbalancer')) {
17190: if ($servers{$hasrule}) {
17191: $toupdate{$hasrule} = 1;
17192: }
17193: }
17194: }
17195: }
17196: if (($rule eq 'balancer') || ($rule eq 'offloadedto')) {
17197: $balancetext = $ruletitles{$rule};
17198: } else {
17199: my $receiver = $defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type};
17200: $balancetext = $ruletitles{'particular'}.' '.$receiver;
17201: if ($receiver) {
17202: $toupdate{$receiver};
17203: }
17204: }
17205: } else {
17206: $balancetext = $ruletitles{$rule};
17207: }
17208: } else {
17209: $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{$balancer}{'rules'}{$type});
17210: }
17211: $resulttext .= '<li>'.&mt('Load Balancer: [_1] -- balancing for [_2] set to - "[_3]"',$balancer,$titles->{$type},$balancetext).'</li>';
17212: }
17213: }
17214: }
17215: }
17216: if (keys(%toupdate)) {
17217: my %thismachine;
17218: my $updatedhere;
17219: my $cachetime = 60*60*24;
17220: map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
17221: foreach my $lonhost (keys(%toupdate)) {
17222: if ($thismachine{$lonhost}) {
17223: unless ($updatedhere) {
17224: &Apache::lonnet::do_cache_new('loadbalancing',$dom,
17225: $defaultshash{'loadbalancing'},
17226: $cachetime);
17227: $updatedhere = 1;
17228: }
17229: } else {
17230: my $cachekey = &escape('loadbalancing').':'.&escape($dom);
17231: &Apache::lonnet::remote_devalidate_cache($lonhost,[$cachekey]);
17232: }
17233: }
17234: }
17235: }
17236: }
17237: if ($resulttext ne '') {
17238: $resulttext = &mt('Changes made:').'<ul>'.$resulttext.'</ul>';
17239: } else {
17240: $resulttext = $nochgmsg;
17241: }
17242: } else {
17243: $resulttext = $nochgmsg;
17244: }
17245: } else {
17246: $resulttext = '<span class="LC_error">'.
17247: &mt('An error occurred: [_1]',$putresult).'</span>';
17248: }
17249: } else {
17250: $resulttext = $nochgmsg;
17251: }
17252: return $resulttext;
17253: }
17254:
17255: sub recurse_check {
17256: my ($chkcats,$categories,$depth,$name) = @_;
17257: if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') {
17258: my $chg = 0;
17259: for (my $j=0; $j<@{$chkcats->[$depth]{$name}}; $j++) {
17260: my $category = $chkcats->[$depth]{$name}[$j];
17261: my $item;
17262: if ($category eq '') {
17263: $chg ++;
17264: } else {
17265: my $deeper = $depth + 1;
17266: $item = &escape($category).':'.&escape($name).':'.$depth;
17267: if ($chg) {
17268: $categories->{$item} -= $chg;
17269: }
17270: &recurse_check($chkcats,$categories,$deeper,$category);
17271: $deeper --;
17272: }
17273: }
17274: }
17275: return;
17276: }
17277:
17278: sub recurse_cat_deletes {
17279: my ($item,$coursecategories,$deletions) = @_;
17280: my ($deleted,$container,$depth) = map { &unescape($_); } split(/:/,$item);
17281: my $subdepth = $depth + 1;
17282: if (ref($coursecategories) eq 'HASH') {
17283: foreach my $subitem (keys(%{$coursecategories})) {
17284: my ($child,$parent,$itemdepth) = map { &unescape($_); } split(/:/,$subitem);
17285: if (($parent eq $deleted) && ($itemdepth == $subdepth)) {
17286: delete($coursecategories->{$subitem});
17287: $deletions->{$subitem} = 1;
17288: &recurse_cat_deletes($subitem,$coursecategories,$deletions);
17289: }
17290: }
17291: }
17292: return;
17293: }
17294:
17295: sub active_dc_picker {
17296: my ($dom,$numinrow,$inputtype,$name,%currhash) = @_;
17297: my %domcoords = &Apache::lonnet::get_active_domroles($dom,['dc']);
17298: my @domcoord = keys(%domcoords);
17299: if (keys(%currhash)) {
17300: foreach my $dc (keys(%currhash)) {
17301: unless (exists($domcoords{$dc})) {
17302: push(@domcoord,$dc);
17303: }
17304: }
17305: }
17306: @domcoord = sort(@domcoord);
17307: my $numdcs = scalar(@domcoord);
17308: my $rows = 0;
17309: my $table;
17310: if ($numdcs > 1) {
17311: $table = '<table>';
17312: for (my $i=0; $i<@domcoord; $i++) {
17313: my $rem = $i%($numinrow);
17314: if ($rem == 0) {
17315: if ($i > 0) {
17316: $table .= '</tr>';
17317: }
17318: $table .= '<tr>';
17319: $rows ++;
17320: }
17321: my $check = '';
17322: if ($inputtype eq 'radio') {
17323: if (keys(%currhash) == 0) {
17324: if (!$i) {
17325: $check = ' checked="checked"';
17326: }
17327: } elsif (exists($currhash{$domcoord[$i]})) {
17328: $check = ' checked="checked"';
17329: }
17330: } else {
17331: if (exists($currhash{$domcoord[$i]})) {
17332: $check = ' checked="checked"';
17333: }
17334: }
17335: if ($i == @domcoord - 1) {
17336: my $colsleft = $numinrow - $rem;
17337: if ($colsleft > 1) {
17338: $table .= '<td class="LC_left_item" colspan="'.$colsleft.'">';
17339: } else {
17340: $table .= '<td class="LC_left_item">';
17341: }
17342: } else {
17343: $table .= '<td class="LC_left_item">';
17344: }
17345: my ($dcname,$dcdom) = split(':',$domcoord[$i]);
17346: my $user = &Apache::loncommon::plainname($dcname,$dcdom);
17347: $table .= '<span class="LC_nobreak"><label>'.
17348: '<input type="'.$inputtype.'" name="'.$name.'"'.
17349: ' value="'.$domcoord[$i].'"'.$check.' />'.$user;
17350: if ($user ne $dcname.':'.$dcdom) {
17351: $table .= ' ('.$dcname.':'.$dcdom.')';
17352: }
17353: $table .= '</label></span></td>';
17354: }
17355: $table .= '</tr></table>';
17356: } elsif ($numdcs == 1) {
17357: my ($dcname,$dcdom) = split(':',$domcoord[0]);
17358: my $user = &Apache::loncommon::plainname($dcname,$dcdom);
17359: if ($inputtype eq 'radio') {
17360: $table = '<input type="hidden" name="'.$name.'" value="'.$domcoord[0].'" />'.$user;
17361: if ($user ne $dcname.':'.$dcdom) {
17362: $table .= ' ('.$dcname.':'.$dcdom.')';
17363: }
17364: } else {
17365: my $check;
17366: if (exists($currhash{$domcoord[0]})) {
17367: $check = ' checked="checked"';
17368: }
17369: $table = '<span class="LC_nobreak"><label>'.
17370: '<input type="checkbox" name="'.$name.'" '.
17371: 'value="'.$domcoord[0].'"'.$check.' />'.$user;
17372: if ($user ne $dcname.':'.$dcdom) {
17373: $table .= ' ('.$dcname.':'.$dcdom.')';
17374: }
17375: $table .= '</label></span>';
17376: $rows ++;
17377: }
17378: }
17379: return ($numdcs,$table,$rows);
17380: }
17381:
17382: sub usersession_titles {
17383: return &Apache::lonlocal::texthash(
17384: hosted => 'Hosting of sessions for users from other domains on servers in this domain',
17385: remote => 'Hosting of sessions for users in this domain on servers in other domains',
17386: spares => 'Servers offloaded to, when busy',
17387: version => 'LON-CAPA version requirement',
17388: excludedomain => 'Allow all, but exclude specific domains',
17389: includedomain => 'Deny all, but include specific domains',
17390: primary => 'Primary (checked first)',
17391: default => 'Default',
17392: );
17393: }
17394:
17395: sub id_for_thisdom {
17396: my (%servers) = @_;
17397: my %altids;
17398: foreach my $server (keys(%servers)) {
17399: my $serverhome = &Apache::lonnet::get_server_homeID($servers{$server});
17400: if ($serverhome ne $server) {
17401: $altids{$serverhome} = $server;
17402: }
17403: }
17404: return %altids;
17405: }
17406:
17407: sub count_servers {
17408: my ($currbalancer,%servers) = @_;
17409: my (@spares,$numspares);
17410: foreach my $lonhost (sort(keys(%servers))) {
17411: next if ($currbalancer eq $lonhost);
17412: push(@spares,$lonhost);
17413: }
17414: if ($currbalancer) {
17415: $numspares = scalar(@spares);
17416: } else {
17417: $numspares = scalar(@spares) - 1;
17418: }
17419: return ($numspares,@spares);
17420: }
17421:
17422: sub lonbalance_targets_js {
17423: my ($dom,$types,$servers,$settings) = @_;
17424: my $select = &mt('Select');
17425: my ($alltargets,$allishome,$allinsttypes,@alltypes);
17426: if (ref($servers) eq 'HASH') {
17427: $alltargets = join("','",sort(keys(%{$servers})));
17428: my @homedoms;
17429: foreach my $server (sort(keys(%{$servers}))) {
17430: if (&Apache::lonnet::host_domain($server) eq $dom) {
17431: push(@homedoms,'1');
17432: } else {
17433: push(@homedoms,'0');
17434: }
17435: }
17436: $allishome = join("','",@homedoms);
17437: }
17438: if (ref($types) eq 'ARRAY') {
17439: if (@{$types} > 0) {
17440: @alltypes = @{$types};
17441: }
17442: }
17443: push(@alltypes,'default','_LC_adv','_LC_author','_LC_internetdom','_LC_external');
17444: $allinsttypes = join("','",@alltypes);
17445: my (%currbalancer,%currtargets,%currrules,%existing);
17446: if (ref($settings) eq 'HASH') {
17447: %existing = %{$settings};
17448: }
17449: &get_loadbalancers_config($servers,\%existing,\%currbalancer,
17450: \%currtargets,\%currrules);
17451: my $balancers = join("','",sort(keys(%currbalancer)));
17452: return <<"END";
17453:
17454: <script type="text/javascript">
17455: // <![CDATA[
17456:
17457: currBalancers = new Array('$balancers');
17458:
17459: function toggleTargets(balnum) {
17460: var lonhostitem = document.getElementById('loadbalancing_lonhost_'+balnum);
17461: var prevhostitem = document.getElementById('loadbalancing_prevlonhost_'+balnum);
17462: var balancer = lonhostitem.options[lonhostitem.selectedIndex].value;
17463: var prevbalancer = prevhostitem.value;
17464: var baltotal = document.getElementById('loadbalancing_total').value;
17465: prevhostitem.value = balancer;
17466: if (prevbalancer != '') {
17467: var prevIdx = currBalancers.indexOf(prevbalancer);
17468: if (prevIdx != -1) {
17469: currBalancers.splice(prevIdx,1);
17470: }
17471: }
17472: if (balancer == '') {
17473: hideSpares(balnum);
17474: } else {
17475: var currIdx = currBalancers.indexOf(balancer);
17476: if (currIdx == -1) {
17477: currBalancers.push(balancer);
17478: }
17479: var homedoms = new Array('$allishome');
17480: var ishomedom = homedoms[lonhostitem.selectedIndex];
17481: showSpares(balancer,ishomedom,balnum);
17482: }
17483: balancerChange(balnum,baltotal,'change',prevbalancer,balancer);
17484: return;
17485: }
17486:
17487: function showSpares(balancer,ishomedom,balnum) {
17488: var alltargets = new Array('$alltargets');
17489: var insttypes = new Array('$allinsttypes');
17490: var offloadtypes = new Array('primary','default');
17491:
17492: document.getElementById('loadbalancing_targets_'+balnum).style.display='block';
17493: document.getElementById('loadbalancing_disabled_'+balnum).style.display='none';
17494:
17495: for (var i=0; i<offloadtypes.length; i++) {
17496: var count = 0;
17497: for (var j=0; j<alltargets.length; j++) {
17498: if (alltargets[j] != balancer) {
17499: var item = document.getElementById('loadbalancing_target_'+balnum+'_'+offloadtypes[i]+'_'+count);
17500: item.value = alltargets[j];
17501: item.style.textAlign='left';
17502: item.style.textFace='normal';
17503: document.getElementById('loadbalancing_targettxt_'+balnum+'_'+offloadtypes[i]+'_'+count).innerHTML = alltargets[j];
17504: if (currBalancers.indexOf(alltargets[j]) == -1) {
17505: item.disabled = '';
17506: } else {
17507: item.disabled = 'disabled';
17508: item.checked = false;
17509: }
17510: count ++;
17511: }
17512: }
17513: }
17514: for (var k=0; k<insttypes.length; k++) {
17515: if ((insttypes[k] == '_LC_external') || (insttypes[k] == '_LC_internetdom')) {
17516: if (ishomedom == 1) {
17517: document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';
17518: document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='block';
17519: } else {
17520: document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';
17521: document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';
17522: }
17523: } else {
17524: document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='block';
17525: document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='block';
17526: }
17527: if ((insttypes[k] != '_LC_external') &&
17528: ((insttypes[k] != '_LC_internetdom') ||
17529: ((insttypes[k] == '_LC_internetdom') && (ishomedom == 1)))) {
17530: var item = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]);
17531: item.options.length = 0;
17532: item.options[0] = new Option("","",true,true);
17533: var idx = 0;
17534: for (var m=0; m<alltargets.length; m++) {
17535: if ((currBalancers.indexOf(alltargets[m]) == -1) && (alltargets[m] != balancer)) {
17536: idx ++;
17537: item.options[idx] = new Option(alltargets[m],alltargets[m],false,false);
17538: }
17539: }
17540: }
17541: }
17542: return;
17543: }
17544:
17545: function hideSpares(balnum) {
17546: var alltargets = new Array('$alltargets');
17547: var insttypes = new Array('$allinsttypes');
17548: var offloadtypes = new Array('primary','default');
17549:
17550: document.getElementById('loadbalancing_targets_'+balnum).style.display='none';
17551: document.getElementById('loadbalancing_disabled_'+balnum).style.display='block';
17552:
17553: var total = alltargets.length - 1;
17554: for (var i=0; i<offloadtypes; i++) {
17555: for (var j=0; j<total; j++) {
17556: document.getElementById('loadbalancing_target_'+balnum+'_'+offloadtypes[i]+'_'+j).checked = false;
17557: document.getElementById('loadbalancing_target_'+balnum+'_'+offloadtypes[i]+'_'+j).value = '';
17558: document.getElementById('loadbalancing_targettxt_'+balnum+'_'+offloadtypes[i]+'_'+j).innerHTML = '';
17559: }
17560: }
17561: for (var k=0; k<insttypes.length; k++) {
17562: document.getElementById('balanceruletitle_'+balnum+'_'+insttypes[k]).style.display='none';
17563: document.getElementById('balancerule_'+balnum+'_'+insttypes[k]).style.display='none';
17564: if (insttypes[k] != '_LC_external') {
17565: document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]).length = 0;
17566: document.getElementById('loadbalancing_singleserver_'+balnum+'_'+insttypes[k]).options[0] = new Option("","",true,true);
17567: }
17568: }
17569: return;
17570: }
17571:
17572: function checkOffloads(item,balnum,type) {
17573: var alltargets = new Array('$alltargets');
17574: var offloadtypes = new Array('primary','default');
17575: if (item.checked) {
17576: var total = alltargets.length - 1;
17577: var other;
17578: if (type == offloadtypes[0]) {
17579: other = offloadtypes[1];
17580: } else {
17581: other = offloadtypes[0];
17582: }
17583: for (var i=0; i<total; i++) {
17584: var server = document.getElementById('loadbalancing_target_'+balnum+'_'+other+'_'+i).value;
17585: if (server == item.value) {
17586: if (document.getElementById('loadbalancing_target_'+balnum+'_'+other+'_'+i).checked) {
17587: document.getElementById('loadbalancing_target_'+balnum+'_'+other+'_'+i).checked = false;
17588: }
17589: }
17590: }
17591: }
17592: return;
17593: }
17594:
17595: function singleServerToggle(balnum,type) {
17596: var offloadtoSelIdx = document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).selectedIndex;
17597: if (offloadtoSelIdx == 0) {
17598: document.getElementById('loadbalancing_rules_'+balnum+'_'+type+'_0').checked = true;
17599: document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '';
17600:
17601: } else {
17602: document.getElementById('loadbalancing_rules_'+balnum+'_'+type+'_2').checked = true;
17603: document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '$select';
17604: }
17605: return;
17606: }
17607:
17608: function balanceruleChange(formname,balnum,type) {
17609: if (type == '_LC_external') {
17610: return;
17611: }
17612: var typesRules = getIndicesByName(formname,'loadbalancing_rules_'+balnum+'_'+type);
17613: for (var i=0; i<typesRules.length; i++) {
17614: if (formname.elements[typesRules[i]].checked) {
17615: if (formname.elements[typesRules[i]].value != 'specific') {
17616: document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).selectedIndex = 0;
17617: document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '';
17618: } else {
17619: document.getElementById('loadbalancing_singleserver_'+balnum+'_'+type).options[0].text = '$select';
17620: }
17621: }
17622: }
17623: return;
17624: }
17625:
17626: function balancerDeleteChange(balnum) {
17627: var hostitem = document.getElementById('loadbalancing_lonhost_'+balnum);
17628: var baltotal = document.getElementById('loadbalancing_total').value;
17629: var addtarget;
17630: var removetarget;
17631: var action = 'delete';
17632: if (document.getElementById('loadbalancing_delete_'+balnum)) {
17633: var lonhost = hostitem.value;
17634: var currIdx = currBalancers.indexOf(lonhost);
17635: if (document.getElementById('loadbalancing_delete_'+balnum).checked) {
17636: if (currIdx != -1) {
17637: currBalancers.splice(currIdx,1);
17638: }
17639: addtarget = lonhost;
17640: } else {
17641: if (currIdx == -1) {
17642: currBalancers.push(lonhost);
17643: }
17644: removetarget = lonhost;
17645: action = 'undelete';
17646: }
17647: balancerChange(balnum,baltotal,action,addtarget,removetarget);
17648: }
17649: return;
17650: }
17651:
17652: function balancerChange(balnum,baltotal,action,addtarget,removetarget) {
17653: if (baltotal > 1) {
17654: var offloadtypes = new Array('primary','default');
17655: var alltargets = new Array('$alltargets');
17656: var insttypes = new Array('$allinsttypes');
17657: for (var i=0; i<baltotal; i++) {
17658: if (i != balnum) {
17659: for (var j=0; j<offloadtypes.length; j++) {
17660: var total = alltargets.length - 1;
17661: for (var k=0; k<total; k++) {
17662: var serveritem = document.getElementById('loadbalancing_target_'+i+'_'+offloadtypes[j]+'_'+k);
17663: var server = serveritem.value;
17664: if ((action == 'delete') || (action == 'change' && addtarget != '')) {
17665: if (server == addtarget) {
17666: serveritem.disabled = '';
17667: }
17668: }
17669: if ((action == 'undelete') || (action == 'change' && removetarget != '')) {
17670: if (server == removetarget) {
17671: serveritem.disabled = 'disabled';
17672: serveritem.checked = false;
17673: }
17674: }
17675: }
17676: }
17677: for (var j=0; j<insttypes.length; j++) {
17678: if (insttypes[j] != '_LC_external') {
17679: if (document.getElementById('loadbalancing_singleserver_'+i+'_'+insttypes[j])) {
17680: var singleserver = document.getElementById('loadbalancing_singleserver_'+i+'_'+insttypes[j]);
17681: var currSel = singleserver.selectedIndex;
17682: var currVal = singleserver.options[currSel].value;
17683: if ((action == 'delete') || (action == 'change' && addtarget != '')) {
17684: var numoptions = singleserver.options.length;
17685: var needsnew = 1;
17686: for (var k=0; k<numoptions; k++) {
17687: if (singleserver.options[k] == addtarget) {
17688: needsnew = 0;
17689: break;
17690: }
17691: }
17692: if (needsnew == 1) {
17693: singleserver.options[numoptions] = new Option(addtarget,addtarget,false,false);
17694: }
17695: }
17696: if ((action == 'undelete') || (action == 'change' && removetarget != '')) {
17697: singleserver.options.length = 0;
17698: if ((currVal) && (currVal != removetarget)) {
17699: singleserver.options[0] = new Option("","",false,false);
17700: } else {
17701: singleserver.options[0] = new Option("","",true,true);
17702: }
17703: var idx = 0;
17704: for (var m=0; m<alltargets.length; m++) {
17705: if (currBalancers.indexOf(alltargets[m]) == -1) {
17706: idx ++;
17707: if (currVal == alltargets[m]) {
17708: singleserver.options[idx] = new Option(alltargets[m],alltargets[m],true,true);
17709: } else {
17710: singleserver.options[idx] = new Option(alltargets[m],alltargets[m],false,false);
17711: }
17712: }
17713: }
17714: }
17715: }
17716: }
17717: }
17718: }
17719: }
17720: }
17721: return;
17722: }
17723:
17724: // ]]>
17725: </script>
17726:
17727: END
17728: }
17729:
17730: sub new_spares_js {
17731: my @sparestypes = ('primary','default');
17732: my $types = join("','",@sparestypes);
17733: my $select = &mt('Select');
17734: return <<"END";
17735:
17736: <script type="text/javascript">
17737: // <![CDATA[
17738:
17739: function updateNewSpares(formname,lonhost) {
17740: var types = new Array('$types');
17741: var include = new Array();
17742: var exclude = new Array();
17743: for (var i=0; i<types.length; i++) {
17744: var spareboxes = getIndicesByName(formname,'spare_'+types[i]+'_'+lonhost);
17745: for (var j=0; j<spareboxes.length; j++) {
17746: if (formname.elements[spareboxes[j]].checked) {
17747: exclude.push(formname.elements[spareboxes[j]].value);
17748: } else {
17749: include.push(formname.elements[spareboxes[j]].value);
17750: }
17751: }
17752: }
17753: for (var i=0; i<types.length; i++) {
17754: var newSpare = document.getElementById('newspare_'+types[i]+'_'+lonhost);
17755: var selIdx = newSpare.selectedIndex;
17756: var currnew = newSpare.options[selIdx].value;
17757: var okSpares = new Array();
17758: for (var j=0; j<newSpare.options.length; j++) {
17759: var possible = newSpare.options[j].value;
17760: if (possible != '') {
17761: if (exclude.indexOf(possible) == -1) {
17762: okSpares.push(possible);
17763: } else {
17764: if (currnew == possible) {
17765: selIdx = 0;
17766: }
17767: }
17768: }
17769: }
17770: for (var k=0; k<include.length; k++) {
17771: if (okSpares.indexOf(include[k]) == -1) {
17772: okSpares.push(include[k]);
17773: }
17774: }
17775: okSpares.sort();
17776: newSpare.options.length = 0;
17777: if (selIdx == 0) {
17778: newSpare.options[0] = new Option("$select","",true,true);
17779: } else {
17780: newSpare.options[0] = new Option("$select","",false,false);
17781: }
17782: for (var m=0; m<okSpares.length; m++) {
17783: var idx = m+1;
17784: var selThis = 0;
17785: if (selIdx != 0) {
17786: if (okSpares[m] == currnew) {
17787: selThis = 1;
17788: }
17789: }
17790: if (selThis == 1) {
17791: newSpare.options[idx] = new Option(okSpares[m],okSpares[m],true,true);
17792: } else {
17793: newSpare.options[idx] = new Option(okSpares[m],okSpares[m],false,false);
17794: }
17795: }
17796: }
17797: return;
17798: }
17799:
17800: function checkNewSpares(lonhost,type) {
17801: var newSpare = document.getElementById('newspare_'+type+'_'+lonhost);
17802: var chosen = newSpare.options[newSpare.selectedIndex].value;
17803: if (chosen != '') {
17804: var othertype;
17805: var othernewSpare;
17806: if (type == 'primary') {
17807: othernewSpare = document.getElementById('newspare_default_'+lonhost);
17808: }
17809: if (type == 'default') {
17810: othernewSpare = document.getElementById('newspare_primary_'+lonhost);
17811: }
17812: if (othernewSpare.options[othernewSpare.selectedIndex].value == chosen) {
17813: othernewSpare.selectedIndex = 0;
17814: }
17815: }
17816: return;
17817: }
17818:
17819: // ]]>
17820: </script>
17821:
17822: END
17823:
17824: }
17825:
17826: sub common_domprefs_js {
17827: return <<"END";
17828:
17829: <script type="text/javascript">
17830: // <![CDATA[
17831:
17832: function getIndicesByName(formname,item) {
17833: var group = new Array();
17834: for (var i=0;i<formname.elements.length;i++) {
17835: if (formname.elements[i].name == item) {
17836: group.push(formname.elements[i].id);
17837: }
17838: }
17839: return group;
17840: }
17841:
17842: // ]]>
17843: </script>
17844:
17845: END
17846:
17847: }
17848:
17849: sub recaptcha_js {
17850: my %lt = &captcha_phrases();
17851: return <<"END";
17852:
17853: <script type="text/javascript">
17854: // <![CDATA[
17855:
17856: function updateCaptcha(caller,context) {
17857: var privitem;
17858: var pubitem;
17859: var privtext;
17860: var pubtext;
17861: var versionitem;
17862: var versiontext;
17863: if (document.getElementById(context+'_recaptchapub')) {
17864: pubitem = document.getElementById(context+'_recaptchapub');
17865: } else {
17866: return;
17867: }
17868: if (document.getElementById(context+'_recaptchapriv')) {
17869: privitem = document.getElementById(context+'_recaptchapriv');
17870: } else {
17871: return;
17872: }
17873: if (document.getElementById(context+'_recaptchapubtxt')) {
17874: pubtext = document.getElementById(context+'_recaptchapubtxt');
17875: } else {
17876: return;
17877: }
17878: if (document.getElementById(context+'_recaptchaprivtxt')) {
17879: privtext = document.getElementById(context+'_recaptchaprivtxt');
17880: } else {
17881: return;
17882: }
17883: if (document.getElementById(context+'_recaptchaversion')) {
17884: versionitem = document.getElementById(context+'_recaptchaversion');
17885: } else {
17886: return;
17887: }
17888: if (document.getElementById(context+'_recaptchavertxt')) {
17889: versiontext = document.getElementById(context+'_recaptchavertxt');
17890: } else {
17891: return;
17892: }
17893: if (caller.checked) {
17894: if (caller.value == 'recaptcha') {
17895: pubitem.type = 'text';
17896: privitem.type = 'text';
17897: pubitem.size = '40';
17898: privitem.size = '40';
17899: pubtext.innerHTML = "$lt{'pub'}";
17900: privtext.innerHTML = "$lt{'priv'}";
17901: versionitem.type = 'text';
17902: versionitem.size = '3';
17903: versiontext.innerHTML = "$lt{'ver'}";
17904: } else {
17905: pubitem.type = 'hidden';
17906: privitem.type = 'hidden';
17907: versionitem.type = 'hidden';
17908: pubtext.innerHTML = '';
17909: privtext.innerHTML = '';
17910: versiontext.innerHTML = '';
17911: }
17912: }
17913: return;
17914: }
17915:
17916: // ]]>
17917: </script>
17918:
17919: END
17920:
17921: }
17922:
17923: sub toggle_display_js {
17924: return <<"END";
17925:
17926: <script type="text/javascript">
17927: // <![CDATA[
17928:
17929: function toggleDisplay(domForm,caller) {
17930: if (document.getElementById(caller)) {
17931: var divitem = document.getElementById(caller);
17932: var optionsElement = domForm.coursecredits;
17933: var checkval = 1;
17934: var dispval = 'block';
17935: var selfcreateRegExp = /^cancreate_emailverified/;
17936: if (caller == 'emailoptions') {
17937: optionsElement = domForm.cancreate_email;
17938: }
17939: if (caller == 'studentsubmission') {
17940: optionsElement = domForm.postsubmit;
17941: }
17942: if (caller == 'cloneinstcode') {
17943: optionsElement = domForm.canclone;
17944: checkval = 'instcode';
17945: }
17946: if (selfcreateRegExp.test(caller)) {
17947: optionsElement = domForm.elements[caller];
17948: checkval = 'other';
17949: dispval = 'inline'
17950: }
17951: if (optionsElement.length) {
17952: var currval;
17953: for (var i=0; i<optionsElement.length; i++) {
17954: if (optionsElement[i].checked) {
17955: currval = optionsElement[i].value;
17956: }
17957: }
17958: if (currval == checkval) {
17959: divitem.style.display = dispval;
17960: } else {
17961: divitem.style.display = 'none';
17962: }
17963: }
17964: }
17965: return;
17966: }
17967:
17968: // ]]>
17969: </script>
17970:
17971: END
17972:
17973: }
17974:
17975: sub captcha_phrases {
17976: return &Apache::lonlocal::texthash (
17977: priv => 'Private key',
17978: pub => 'Public key',
17979: original => 'original (CAPTCHA)',
17980: recaptcha => 'successor (ReCAPTCHA)',
17981: notused => 'unused',
17982: ver => 'ReCAPTCHA version (1 or 2)',
17983: );
17984: }
17985:
17986: sub devalidate_remote_domconfs {
17987: my ($dom,$cachekeys) = @_;
17988: return unless (ref($cachekeys) eq 'HASH');
17989: my %servers = &Apache::lonnet::internet_dom_servers($dom);
17990: my %thismachine;
17991: map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids();
17992: my @posscached = ('domainconfig','domdefaults','ltitools','usersessions','directorysrch');
17993: if (keys(%servers)) {
17994: foreach my $server (keys(%servers)) {
17995: next if ($thismachine{$server});
17996: my @cached;
17997: foreach my $name (@posscached) {
17998: if ($cachekeys->{$name}) {
17999: push(@cached,&escape($name).':'.&escape($dom));
18000: }
18001: }
18002: if (@cached) {
18003: &Apache::lonnet::remote_devalidate_cache($server,\@cached);
18004: }
18005: }
18006: }
18007: return;
18008: }
18009:
18010: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>