![]() ![]() | ![]() |
- Customization for GCI_3 - Backport 1.141.
1: # The LearningOnline Network with CAPA 2: # Handler to set domain-wide configuration settings 3: # 4: # $Id: domainprefs.pm,v 1.123.2.5 2010/12/08 04:22:16 raeburn Exp $ 5: # 6: # Copyright Michigan State University Board of Trustees 7: # 8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA). 9: # 10: # LON-CAPA is free software; you can redistribute it and/or modify 11: # it under the terms of the GNU General Public License as published by 12: # the Free Software Foundation; either version 2 of the License, or 13: # (at your option) any later version. 14: # 15: # LON-CAPA is distributed in the hope that it will be useful, 16: # but WITHOUT ANY WARRANTY; without even the implied warranty of 17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18: # GNU General Public License for more details. 19: # 20: # You should have received a copy of the GNU General Public License 21: # along with LON-CAPA; if not, write to the Free Software 22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA# 23: # /home/httpd/html/adm/gpl.txt 24: # 25: # http://www.lon-capa.org/ 26: # 27: # 28: ############################################################### 29: ############################################################## 30: 31: =pod 32: 33: =head1 NAME 34: 35: Apache::domainprefs.pm 36: 37: =head1 SYNOPSIS 38: 39: Handles configuration of a LON-CAPA domain. 40: 41: This is part of the LearningOnline Network with CAPA project 42: described at http://www.lon-capa.org. 43: 44: 45: =head1 OVERVIEW 46: 47: Each institution using LON-CAPA will typically have a single domain designated 48: for use by individuals affliated with the institution. Accordingly, each domain 49: may define a default set of logos and a color scheme which can be used to "brand" 50: the LON-CAPA instance. In addition, an institution will typically have a language 51: and timezone which are used for the majority of courses. 52: 53: LON-CAPA provides a mechanism to display and modify these defaults, as well as a 54: host of other domain-wide settings which determine the types of functionality 55: available to users and courses in the domain. 56: 57: There is also a mechanism to configure cataloging of courses in the domain, and 58: controls on the operation of automated processes which govern such things as 59: roster updates, user directory updates and processing of course requests. 60: 61: The domain coordination manual which is built dynamically on install/update of 62: LON-CAPA from the relevant help items provides more information about domain 63: configuration. 64: 65: Most of the domain settings are stored in the configuration.db GDBM file which is 66: housed on the primary library server for the domain in /home/httpd/lonUsers/$dom, 67: where $dom is the domain. The configuration.db stores settings in a number of 68: frozen hashes of hashes. In a few cases, domain information must be uploaded to 69: the domain as files (e.g., image files for logos etc., or plain text files for 70: bubblesheet formats). In this case the domainprefs.pm must be running in a user 71: session hosted on the primary library server in the domain, as these files are 72: stored in author space belonging to a special $dom-domainconfig user. 73: 74: domainprefs.pm in combination with lonconfigsettings.pm will retrieve and display 75: the current settings, and provides an interface to make modifications. 76: 77: =head1 SUBROUTINES 78: 79: =over 80: 81: =item print_quotas() 82: 83: Inputs: 4 84: 85: $dom,$settings,$rowtotal,$action. 86: 87: $dom is the domain, $settings is a reference to a hash of current settings for 88: the current context, $rowtotal is a reference to the scalar used to record the 89: number of rows displayed on the page, and $action is the context (either quotas 90: or requestcourses). 91: 92: The print_quotas routine was orginally created to display/store information 93: about default quota sizes for portfolio spaces for the different types of 94: institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.), 95: but is now also used to manage availability of user tools: 96: i.e., blogs, aboutme page, and portfolios, and the course request tool, 97: used by course owners to request creation of a course. 98: 99: Outputs: 1 100: 101: $datatable - HTML containing form elements which allow settings to be changed. 102: 103: In the case of course requests, radio buttons are displayed for each institutional 104: affiliate type (and also default, and _LC_adv) for each of the course types 105: (official, unofficial and community). In each case the radio buttons allow the 106: selection of one of four values: 107: 108: 0, approval, validate, autolimit=N (where N is blank, or a positive integer). 109: which have the following effects: 110: 111: 0 112: 113: =over 114: 115: - course requests are not allowed for this course types/affiliation 116: 117: =back 118: 119: approval 120: 121: =over 122: 123: - course requests must be approved by a Doman Coordinator in the 124: course's domain 125: 126: =back 127: 128: validate 129: 130: =over 131: 132: - an institutional validation (e.g., check requestor is instructor 133: of record) needs to be passed before the course will be created. The required 134: validation is in localenroll.pm on the primary library server for the course 135: domain. 136: 137: =back 138: 139: autolimit 140: 141: =over 142: 143: - course requests will be processed autoatically up to a limit of 144: N requests for the course type for the particular requestor. 145: If N is undefined, there is no limit to the number of course requests 146: which a course owner may submit and have processed automatically. 147: 148: =back 149: 150: =item modify_quotas() 151: 152: =back 153: 154: =cut 155: 156: package Apache::domainprefs; 157: 158: use strict; 159: use Apache::Constants qw(:common :http); 160: use Apache::lonnet; 161: use Apache::loncommon(); 162: use Apache::lonhtmlcommon(); 163: use Apache::lonlocal; 164: use Apache::lonmsg(); 165: use Apache::lonconfigsettings; 166: use LONCAPA qw(:DEFAULT :match); 167: use LONCAPA::Enrollment; 168: use LONCAPA::lonauthcgi(); 169: use File::Copy; 170: use Locale::Language; 171: use DateTime::TimeZone; 172: use DateTime::Locale; 173: 174: sub handler { 175: my $r=shift; 176: if ($r->header_only) { 177: &Apache::loncommon::content_type($r,'text/html'); 178: $r->send_http_header; 179: return OK; 180: } 181: 182: my $context = 'domain'; 183: my $dom = $env{'request.role.domain'}; 184: my $domdesc = &Apache::lonnet::domain($dom,'description'); 185: if (&Apache::lonnet::allowed('mau',$dom)) { 186: &Apache::loncommon::content_type($r,'text/html'); 187: $r->send_http_header; 188: } else { 189: $env{'user.error.msg'}= 190: "/adm/domainprefs:mau:0:0:Cannot modify domain settings"; 191: return HTTP_NOT_ACCEPTABLE; 192: } 193: &Apache::lonhtmlcommon::clear_breadcrumbs(); 194: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, 195: ['phase','actions']); 196: my $phase = 'pickactions'; 197: if ( exists($env{'form.phase'}) ) { 198: $phase = $env{'form.phase'}; 199: } 200: my %domconfig = 201: &Apache::lonnet::get_dom('configuration',['login','rolecolors', 202: 'quotas','autoenroll','autoupdate','directorysrch', 203: 'usercreation','usermodification','contacts','defaults', 204: 'scantron','coursecategories','serverstatuses', 205: 'requestcourses','helpsettings','coursedefaults'],$dom); 206: my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll', 207: 'autoupdate','directorysrch','contacts', 208: 'usercreation','usermodification','scantron', 209: 'requestcourses','coursecategories','serverstatuses','helpsettings', 210: 'coursedefaults'); 211: my %prefs = ( 212: 'rolecolors' => 213: { text => 'Default color schemes', 214: help => 'Domain_Configuration_Color_Schemes', 215: header => [{col1 => 'Student Settings', 216: col2 => '',}, 217: {col1 => 'Coordinator Settings', 218: col2 => '',}, 219: {col1 => 'Author Settings', 220: col2 => '',}, 221: {col1 => 'Administrator Settings', 222: col2 => '',}], 223: }, 224: 'login' => 225: { text => 'Log-in page options', 226: help => 'Domain_Configuration_Login_Page', 227: header => [{col1 => 'Item', 228: col2 => '',}], 229: }, 230: 231: 'defaults' => 232: { text => 'Default authentication/language/timezone/portal', 233: help => 'Domain_Configuration_LangTZAuth', 234: header => [{col1 => 'Setting', 235: col2 => 'Value'}], 236: }, 237: 'quotas' => 238: { text => 'User blogs, personal information pages and portfolios', 239: help => 'Domain_Configuration_Quotas', 240: header => [{col1 => 'User affiliation', 241: col2 => 'Available tools', 242: col3 => 'Portfolio quota',}], 243: }, 244: 'autoenroll' => 245: { text => 'Auto-enrollment settings', 246: help => 'Domain_Configuration_Auto_Enrollment', 247: header => [{col1 => 'Configuration setting', 248: col2 => 'Value(s)'}], 249: }, 250: 'autoupdate' => 251: { text => 'Auto-update settings', 252: help => 'Domain_Configuration_Auto_Updates', 253: header => [{col1 => 'Setting', 254: col2 => 'Value',}, 255: {col1 => 'User population', 256: col2 => 'Updataeable user data'}], 257: }, 258: 'directorysrch' => 259: { text => 'Institutional directory searches', 260: help => 'Domain_Configuration_InstDirectory_Search', 261: header => [{col1 => 'Setting', 262: col2 => 'Value',}], 263: }, 264: 'contacts' => 265: { text => 'Contact Information', 266: help => 'Domain_Configuration_Contact_Info', 267: header => [{col1 => 'Setting', 268: col2 => 'Value',}], 269: }, 270: 271: 'usercreation' => 272: { text => 'User creation', 273: help => 'Domain_Configuration_User_Creation', 274: header => [{col1 => 'Format rule type', 275: col2 => 'Format rules in force'}, 276: {col1 => 'User account creation', 277: col2 => 'Usernames which may be created',}, 278: {col1 => 'Context', 279: col2 => 'Assignable authentication types'}], 280: }, 281: 'usermodification' => 282: { text => 'User modification', 283: help => 'Domain_Configuration_User_Modification', 284: header => [{col1 => 'Target user has role', 285: col2 => 'User information updateable in author context'}, 286: {col1 => 'Target user has role', 287: col2 => 'User information updateable in course context'}, 288: {col1 => "Status of user", 289: col2 => 'Information settable when self-creating account (if directory data blank)'}], 290: }, 291: 'scantron' => 292: { text => 'Bubblesheet format file', 293: help => 'Domain_Configuration_Scantron_Format', 294: header => [ {col1 => 'Item', 295: col2 => '', 296: }], 297: }, 298: 'requestcourses' => 299: {text => 'Request creation of courses', 300: help => 'Domain_Configuration_Request_Courses', 301: header => [{col1 => 'User affiliation', 302: col2 => 'Availability/Processing of requests',}, 303: {col1 => 'Setting', 304: col2 => 'Value'}], 305: }, 306: 'coursecategories' => 307: { text => 'Cataloging of courses/communities', 308: help => 'Domain_Configuration_Cataloging_Courses', 309: header => [{col1 => 'Category settings', 310: col2 => '',}, 311: {col1 => 'Categories', 312: col2 => '', 313: }], 314: }, 315: 'serverstatuses' => 316: {text => 'Access to server status pages', 317: help => 'Domain_Configuration_Server_Status', 318: header => [{col1 => 'Status Page', 319: col2 => 'Other named users', 320: col3 => 'Specific IPs', 321: }], 322: }, 323: 'helpsettings' => 324: {text => 'Help page settings', 325: help => 'Domain_Configuration_Help_Settings', 326: header => [{col1 => 'Authenticated Help Settings', 327: col2 => ''}, 328: {col1 => 'Unauthenticated Help Settings', 329: col2 => ''}], 330: }, 331: 'coursedefaults' => 332: {text => 'Course/Community defaults', 333: help => 'Domain_Configuration_Course_Defaults', 334: header => [{col1 => 'Defaults which can be overridden for each course by a DC', 335: col2 => 'Value',}], 336: }, 337: 'privacy' => 338: {text => 'User Privacy', 339: help => 'Domain_Configuration_User_Privacy', 340: header => [{col1 => 'Setting', 341: col2 => 'Value',}], 342: }, 343: ); 344: my %servers = &dom_servers($dom); 345: if (keys(%servers) > 1) { 346: $prefs{'login'} = { text => 'Log-in page options', 347: help => 'Domain_Configuration_Login_Page', 348: header => [{col1 => 'Log-in Service', 349: col2 => 'Server Setting',}, 350: {col1 => 'Log-in Page Items', 351: col2 => ''}], 352: }; 353: } 354: my @roles = ('student','coordinator','author','admin'); 355: my @actions = &Apache::loncommon::get_env_multiple('form.actions'); 356: &Apache::lonhtmlcommon::add_breadcrumb 357: ({href=>"javascript:changePage(document.$phase,'pickactions')", 358: text=>"Pick functionality"}); 359: my $confname = $dom.'-domainconfig'; 360: if ($phase eq 'process') { 361: &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,\@roles); 362: } elsif ($phase eq 'display') { 363: &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname); 364: } else { 365: if (keys(%domconfig) == 0) { 366: my $primarylibserv = &Apache::lonnet::domain($dom,'primary'); 367: my @ids=&Apache::lonnet::current_machine_ids(); 368: if (!grep(/^\Q$primarylibserv\E$/,@ids)) { 369: my %designhash = &Apache::loncommon::get_domainconf($dom); 370: my @loginimages = ('img','logo','domlogo','login'); 371: my $custom_img_count = 0; 372: foreach my $img (@loginimages) { 373: if ($designhash{$dom.'.login.'.$img} ne '') { 374: $custom_img_count ++; 375: } 376: } 377: foreach my $role (@roles) { 378: if ($designhash{$dom.'.'.$role.'.img'} ne '') { 379: $custom_img_count ++; 380: } 381: } 382: if ($custom_img_count > 0) { 383: &Apache::lonconfigsettings::print_header($r,$phase,$context); 384: my $switch_server = &check_switchserver($dom,$confname); 385: $r->print( 386: &mt('Domain configuration settings have yet to be saved for this domain via the web-based domain preferences interface.').'<br />'. 387: &mt("While this remains so, you must switch to the domain's primary library server in order to update settings.").'<br /><br />'. 388: &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 />'. 389: &mt("However, you will still need to switch to the domain's primary library server to upload new images or logos.").'<br /><br />'); 390: if ($switch_server) { 391: $r->print($switch_server.' '.&mt('to primary library server for domain: [_1]',$dom)); 392: } 393: $r->print(&Apache::loncommon::end_page()); 394: return OK; 395: } 396: } 397: } 398: &Apache::lonconfigsettings::display_choices($r,$phase,$context,\@prefs_order,\%prefs); 399: } 400: return OK; 401: } 402: 403: sub process_changes { 404: my ($r,$dom,$confname,$action,$roles,$values) = @_; 405: my %domconfig; 406: if (ref($values) eq 'HASH') { 407: %domconfig = %{$values}; 408: } 409: my $output; 410: if ($action eq 'login') { 411: $output = &modify_login($r,$dom,$confname,%domconfig); 412: } elsif ($action eq 'rolecolors') { 413: $output = &modify_rolecolors($r,$dom,$confname,$roles, 414: %domconfig); 415: } elsif ($action eq 'quotas') { 416: $output = &modify_quotas($dom,$action,%domconfig); 417: } elsif ($action eq 'autoenroll') { 418: $output = &modify_autoenroll($dom,%domconfig); 419: } elsif ($action eq 'autoupdate') { 420: $output = &modify_autoupdate($dom,%domconfig); 421: } elsif ($action eq 'directorysrch') { 422: $output = &modify_directorysrch($dom,%domconfig); 423: } elsif ($action eq 'usercreation') { 424: $output = &modify_usercreation($dom,%domconfig); 425: } elsif ($action eq 'usermodification') { 426: $output = &modify_usermodification($dom,%domconfig); 427: } elsif ($action eq 'contacts') { 428: $output = &modify_contacts($dom,%domconfig); 429: } elsif ($action eq 'defaults') { 430: $output = &modify_defaults($dom,$r); 431: } elsif ($action eq 'scantron') { 432: $output = &modify_scantron($r,$dom,$confname,%domconfig); 433: } elsif ($action eq 'coursecategories') { 434: $output = &modify_coursecategories($dom,%domconfig); 435: } elsif ($action eq 'serverstatuses') { 436: $output = &modify_serverstatuses($dom,%domconfig); 437: } elsif ($action eq 'requestcourses') { 438: $output = &modify_quotas($dom,$action,%domconfig); 439: } elsif ($action eq 'helpsettings') { 440: $output = &modify_helpsettings($r,$dom,$confname,%domconfig); 441: } elsif ($action eq 'coursedefaults') { 442: $output = &modify_coursedefaults($dom,%domconfig); 443: } 444: return $output; 445: } 446: 447: sub print_config_box { 448: my ($r,$dom,$confname,$phase,$action,$item,$settings) = @_; 449: my $rowtotal = 0; 450: my $output; 451: if ($action eq 'coursecategories') { 452: $output = &coursecategories_javascript($settings); 453: } 454: $output .= 455: '<table class="LC_nested_outer"> 456: <tr> 457: <th align="left" valign="middle"><span class="LC_nobreak">'. 458: &mt($item->{text}).' '. 459: &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n". 460: '</tr>'; 461: $rowtotal ++; 462: my $numheaders = 1; 463: if (ref($item->{'header'}) eq 'ARRAY') { 464: $numheaders = scalar(@{$item->{'header'}}); 465: } 466: if ($numheaders > 1) { 467: my $colspan = ''; 468: if (($action eq 'rolecolors') || ($action eq 'coursecategories') || ($action eq 'helpsettings')) { 469: $colspan = ' colspan="2"'; 470: } 471: $output .= ' 472: <tr> 473: <td> 474: <table class="LC_nested"> 475: <tr class="LC_info_row"> 476: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[0]->{'col1'}).'</td> 477: <td class="LC_right_item">'.&mt($item->{'header'}->[0]->{'col2'}).'</td> 478: </tr>'; 479: $rowtotal ++; 480: if ($action eq 'autoupdate') { 481: $output .= &print_autoupdate('top',$dom,$settings,\$rowtotal); 482: } elsif ($action eq 'usercreation') { 483: $output .= &print_usercreation('top',$dom,$settings,\$rowtotal); 484: } elsif ($action eq 'usermodification') { 485: $output .= &print_usermodification('top',$dom,$settings,\$rowtotal); 486: } elsif ($action eq 'coursecategories') { 487: $output .= &print_coursecategories('top',$dom,$item,$settings,\$rowtotal); 488: } elsif ($action eq 'login') { 489: $output .= &print_login('top',$dom,$confname,$phase,$settings,\$rowtotal); 490: $colspan = ' colspan="2"'; 491: } elsif ($action eq 'requestcourses') { 492: $output .= &print_quotas($dom,$settings,\$rowtotal,$action); 493: } elsif ($action eq 'helpsettings') { 494: $output .= &print_helpsettings('top',$dom,$confname,$settings,\$rowtotal); 495: } elsif ($action eq 'rolecolors') { 496: $output .= &print_rolecolors($phase,'student',$dom,$confname,$settings,\$rowtotal); 497: } 498: $output .= ' 499: </table> 500: </td> 501: </tr> 502: <tr> 503: <td> 504: <table class="LC_nested"> 505: <tr class="LC_info_row"> 506: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col1'}).'</td>'; 507: $output .= ' 508: <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[1]->{'col2'}).'</td> 509: </tr>'; 510: $rowtotal ++; 511: if ($action eq 'autoupdate') { 512: $output .= &print_autoupdate('bottom',$dom,$settings,\$rowtotal); 513: } elsif ($action eq 'usercreation') { 514: $output .= &print_usercreation('middle',$dom,$settings,\$rowtotal).' 515: </table> 516: </td> 517: </tr> 518: <tr> 519: <td> 520: <table class="LC_nested"> 521: <tr class="LC_info_row"> 522: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td> 523: <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td> </tr>'. 524: &print_usercreation('bottom',$dom,$settings,\$rowtotal); 525: $rowtotal ++; 526: } elsif ($action eq 'usermodification') { 527: $output .= &print_usermodification('middle',$dom,$settings,\$rowtotal).' 528: </table> 529: </td> 530: </tr> 531: <tr> 532: <td> 533: <table class="LC_nested"> 534: <tr class="LC_info_row"> 535: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td> 536: <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td> </tr>'. 537: 538: &print_usermodification('bottom',$dom,$settings,\$rowtotal); 539: $rowtotal ++; 540: } elsif ($action eq 'coursecategories') { 541: $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal); 542: } elsif ($action eq 'login') { 543: $output .= &print_login('bottom',$dom,$confname,$phase,$settings,\$rowtotal); 544: } elsif ($action eq 'requestcourses') { 545: $output .= &print_courserequestmail($dom,$settings,\$rowtotal); 546: } elsif ($action eq 'helpsettings') { 547: $output .= &print_helpsettings('bottom',$dom,$confname,$settings,\$rowtotal); 548: } elsif ($action eq 'rolecolors') { 549: $output .= &print_rolecolors($phase,'coordinator',$dom,$confname,$settings,\$rowtotal).' 550: </table> 551: </td> 552: </tr> 553: <tr> 554: <td> 555: <table class="LC_nested"> 556: <tr class="LC_info_row"> 557: <td class="LC_left_item"'.$colspan.' valign="top">'. 558: &mt($item->{'header'}->[2]->{'col1'}).'</td> 559: <td class="LC_right_item" valign="top">'. 560: &mt($item->{'header'}->[2]->{'col2'}).'</td> 561: </tr>'. 562: &print_rolecolors($phase,'author',$dom,$confname,$settings,\$rowtotal).' 563: </table> 564: </td> 565: </tr> 566: <tr> 567: <td> 568: <table class="LC_nested"> 569: <tr class="LC_info_row"> 570: <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td> 571: <td class="LC_right_item">'.&mt($item->{'header'}->[3]->{'col2'}).'</td> 572: </tr>'. 573: &print_rolecolors($phase,'admin',$dom,$confname,$settings,\$rowtotal); 574: $rowtotal += 2; 575: } 576: } else { 577: $output .= ' 578: <tr> 579: <td> 580: <table class="LC_nested"> 581: <tr class="LC_info_row">'; 582: if (($action eq 'login') || ($action eq 'directorysrch')) { 583: $output .= ' 584: <td class="LC_left_item" colspan="2">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>'; 585: } elsif ($action eq 'serverstatuses') { 586: $output .= ' 587: <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}). 588: '<br />('.&mt('Automatic access for Dom. Coords.').')</td>'; 589: 590: } else { 591: $output .= ' 592: <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>'; 593: } 594: if (defined($item->{'header'}->[0]->{'col3'})) { 595: $output .= '<td class="LC_left_item" valign="top">'. 596: &mt($item->{'header'}->[0]->{'col2'}); 597: if ($action eq 'serverstatuses') { 598: $output .= '<br />(<tt>'.&mt('user1:domain1,user2:domain2 etc.').'</tt>)'; 599: } 600: } else { 601: $output .= '<td class="LC_right_item" valign="top">'. 602: &mt($item->{'header'}->[0]->{'col2'}); 603: } 604: $output .= '</td>'; 605: if ($item->{'header'}->[0]->{'col3'}) { 606: $output .= '<td class="LC_right_item" valign="top">'. 607: &mt($item->{'header'}->[0]->{'col3'}); 608: if ($action eq 'serverstatuses') { 609: $output .= '<br />(<tt>'.&mt('IP1,IP2 etc.').'</tt>)'; 610: } 611: $output .= '</td>'; 612: } 613: $output .= '</tr>'; 614: $rowtotal ++; 615: if ($action eq 'login') { 616: $output .= &print_login('bottom',$dom,$confname,$phase,$settings, 617: \$rowtotal); 618: } elsif ($action eq 'quotas') { 619: $output .= &print_quotas($dom,$settings,\$rowtotal,$action); 620: } elsif ($action eq 'autoenroll') { 621: $output .= &print_autoenroll($dom,$settings,\$rowtotal); 622: } elsif ($action eq 'directorysrch') { 623: $output .= &print_directorysrch($dom,$settings,\$rowtotal); 624: } elsif ($action eq 'contacts') { 625: $output .= &print_contacts($dom,$settings,\$rowtotal); 626: } elsif ($action eq 'defaults') { 627: $output .= &print_defaults($dom,\$rowtotal); 628: } elsif ($action eq 'scantron') { 629: $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal); 630: } elsif ($action eq 'serverstatuses') { 631: $output .= &print_serverstatuses($dom,$settings,\$rowtotal); 632: } elsif ($action eq 'helpsettings') { 633: $output .= &print_helpsettings('top',$dom,$confname,$settings,\$rowtotal); 634: } elsif ($action eq 'coursedefaults') { 635: $output .= &print_coursedefaults($dom,$settings,\$rowtotal); 636: } 637: } 638: $output .= ' 639: </table> 640: </td> 641: </tr> 642: </table><br />'; 643: return ($output,$rowtotal); 644: } 645: 646: sub print_login { 647: my ($position,$dom,$confname,$phase,$settings,$rowtotal) = @_; 648: my ($css_class,$datatable); 649: my %choices = &login_choices(); 650: my $itemcount = 1; 651: 652: if ($position eq 'top') { 653: my %servers = &dom_servers($dom); 654: my $choice = $choices{'disallowlogin'}; 655: $css_class = ' class="LC_odd_row"'; 656: $datatable .= '<tr'.$css_class.'><td>'.$choices{'disallowlogin'}.'</td>'. 657: '<td align="right"><table><tr><th>'.$choices{'hostid'}.'</th>'. 658: '<th>'.$choices{'serverurl'}.'</th></tr>'."\n"; 659: my %disallowed; 660: if (ref($settings) eq 'HASH') { 661: if (ref($settings->{'loginvia'}) eq 'HASH') { 662: %disallowed = %{$settings->{'loginvia'}}; 663: } 664: } 665: foreach my $lonhost (sort(keys(%servers))) { 666: my $direct = 'selected="selected"'; 667: if ($disallowed{$lonhost} eq '') { 668: $direct = ''; 669: } 670: $datatable .= '<tr><td>'.$servers{$lonhost}.'</td>'. 671: '<td><select name="'.$lonhost.'_serverurl">'. 672: '<option value=""'.$direct.'>'.$choices{'directlogin'}. 673: '</option>'; 674: foreach my $hostid (keys(%servers)) { 675: next if ($servers{$hostid} eq $servers{$lonhost}); 676: my $selected = ''; 677: if ($hostid eq $disallowed{$lonhost}) { 678: $selected = 'selected="selected"'; 679: } 680: $datatable .= '<option value="'.$hostid.'"'.$selected.'>'. 681: $servers{$hostid}.'</option>'; 682: } 683: $datatable .= '</select></td></tr>'; 684: } 685: $datatable .= '</table></td></tr>'; 686: return $datatable; 687: } 688: 689: my %defaultchecked = ( 690: 'coursecatalog' => 'on', 691: 'adminmail' => 'off', 692: 'newuser' => 'off', 693: ); 694: my @toggles = ('coursecatalog','adminmail','newuser'); 695: my (%checkedon,%checkedoff); 696: foreach my $item (@toggles) { 697: if ($defaultchecked{$item} eq 'on') { 698: $checkedon{$item} = ' checked="checked" '; 699: $checkedoff{$item} = ' '; 700: } elsif ($defaultchecked{$item} eq 'off') { 701: $checkedoff{$item} = ' checked="checked" '; 702: $checkedon{$item} = ' '; 703: } 704: } 705: my $loginheader = 'image'; 706: my @images = ('img','logo','domlogo','login'); 707: my @logintext = ('textcol','bgcol'); 708: my @bgs = ('pgbg','mainbg','sidebg'); 709: my @links = ('link','alink','vlink'); 710: my %designhash = &Apache::loncommon::get_domainconf($dom); 711: my %defaultdesign = %Apache::loncommon::defaultdesign; 712: my (%is_custom,%designs); 713: my %defaults = ( 714: font => $defaultdesign{'login.font'}, 715: ); 716: foreach my $item (@images) { 717: $defaults{$item} = $defaultdesign{'login.'.$item}; 718: $defaults{'showlogo'}{$item} = 1; 719: } 720: foreach my $item (@bgs) { 721: $defaults{'bgs'}{$item} = $defaultdesign{'login.'.$item}; 722: } 723: foreach my $item (@logintext) { 724: $defaults{'logintext'}{$item} = $defaultdesign{'login.'.$item}; 725: } 726: foreach my $item (@links) { 727: $defaults{'links'}{$item} = $defaultdesign{'login.'.$item}; 728: } 729: if (ref($settings) eq 'HASH') { 730: foreach my $item (@toggles) { 731: if ($settings->{$item} eq '1') { 732: $checkedon{$item} = ' checked="checked" '; 733: $checkedoff{$item} = ' '; 734: } elsif ($settings->{$item} eq '0') { 735: $checkedoff{$item} = ' checked="checked" '; 736: $checkedon{$item} = ' '; 737: } 738: } 739: foreach my $item (@images) { 740: if (defined($settings->{$item})) { 741: $designs{$item} = $settings->{$item}; 742: $is_custom{$item} = 1; 743: } 744: if (defined($settings->{'showlogo'}{$item})) { 745: $designs{'showlogo'}{$item} = $settings->{'showlogo'}{$item}; 746: } 747: } 748: foreach my $item (@logintext) { 749: if ($settings->{$item} ne '') { 750: $designs{'logintext'}{$item} = $settings->{$item}; 751: $is_custom{$item} = 1; 752: } 753: } 754: if ($settings->{'loginheader'} ne '') { 755: $loginheader = $settings->{'loginheader'}; 756: } 757: if ($settings->{'font'} ne '') { 758: $designs{'font'} = $settings->{'font'}; 759: $is_custom{'font'} = 1; 760: } 761: foreach my $item (@bgs) { 762: if ($settings->{$item} ne '') { 763: $designs{'bgs'}{$item} = $settings->{$item}; 764: $is_custom{$item} = 1; 765: } 766: } 767: foreach my $item (@links) { 768: if ($settings->{$item} ne '') { 769: $designs{'links'}{$item} = $settings->{$item}; 770: $is_custom{$item} = 1; 771: } 772: } 773: } else { 774: if ($designhash{$dom.'.login.font'} ne '') { 775: $designs{'font'} = $designhash{$dom.'.login.font'}; 776: $is_custom{'font'} = 1; 777: } 778: foreach my $item (@images) { 779: if ($designhash{$dom.'.login.'.$item} ne '') { 780: $designs{$item} = $designhash{$dom.'.login.'.$item}; 781: $is_custom{$item} = 1; 782: } 783: } 784: foreach my $item (@bgs) { 785: if ($designhash{$dom.'.login.'.$item} ne '') { 786: $designs{'bgs'}{$item} = $designhash{$dom.'.login.'.$item}; 787: $is_custom{$item} = 1; 788: } 789: } 790: foreach my $item (@links) { 791: if ($designhash{$dom.'.login.'.$item} ne '') { 792: $designs{'links'}{$item} = $designhash{$dom.'.login.'.$item}; 793: $is_custom{$item} = 1; 794: } 795: } 796: } 797: my %alt_text = &Apache::lonlocal::texthash ( img => 'Log-in banner', 798: logo => 'Institution Logo', 799: domlogo => 'Domain Logo', 800: login => 'Login box'); 801: my $itemcount = 1; 802: my ($css_class,$datatable); 803: foreach my $item (@toggles) { 804: $css_class = $itemcount%2?' class="LC_odd_row"':''; 805: $datatable .= 806: '<tr'.$css_class.'><td colspan="2">'.$choices{$item}. 807: '</td><td>'. 808: '<span class="LC_nobreak"><label><input type="radio" name="'. 809: $item.'"'.$checkedon{$item}.' value="1" />'.&mt('Yes'). 810: '</label> <label><input type="radio" name="'.$item.'"'. 811: $checkedoff{$item}.' value="0" />'.&mt('No').'</label></span></td>'. 812: '</tr>'; 813: $itemcount ++; 814: } 815: $datatable .= &display_color_options($dom,$confname,$phase,'login',$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal,\@logintext,$loginheader); 816: $datatable .= '</tr></table></td></tr>'; 817: return $datatable; 818: } 819: 820: sub login_choices { 821: my %choices = 822: &Apache::lonlocal::texthash ( 823: coursecatalog => 'Display Course/Community Catalog link?', 824: adminmail => "Display Administrator's E-mail Address?", 825: disallowlogin => "Login page requests redirected", 826: hostid => "Server", 827: serverurl => "Redirect to log-in via:", 828: directlogin => "No redirect", 829: newuser => "Link to create a user account", 830: img => "Header", 831: logo => "Main Logo", 832: domlogo => "Domain Logo", 833: login => "Log-in Header", 834: textcol => "Text color", 835: bgcol => "Box color", 836: bgs => "Background colors", 837: links => "Link colors", 838: font => "Font color", 839: pgbg => "Header", 840: mainbg => "Page", 841: sidebg => "Login box", 842: link => "Link", 843: alink => "Active link", 844: vlink => "Visited link", 845: ); 846: return %choices; 847: } 848: 849: sub print_rolecolors { 850: my ($phase,$role,$dom,$confname,$settings,$rowtotal) = @_; 851: my %choices = &color_font_choices(); 852: my @bgs = ('pgbg','tabbg','sidebg'); 853: my @links = ('link','alink','vlink'); 854: my @images = ('img'); 855: my %alt_text = &Apache::lonlocal::texthash(img => "Banner for $role role"); 856: my %designhash = &Apache::loncommon::get_domainconf($dom); 857: my %defaultdesign = %Apache::loncommon::defaultdesign; 858: my (%is_custom,%designs); 859: my %defaults = ( 860: img => $defaultdesign{$role.'.img'}, 861: font => $defaultdesign{$role.'.font'}, 862: fontmenu => $defaultdesign{$role.'.fontmenu'}, 863: ); 864: foreach my $item (@bgs) { 865: $defaults{'bgs'}{$item} = $defaultdesign{$role.'.'.$item}; 866: } 867: foreach my $item (@links) { 868: $defaults{'links'}{$item} = $defaultdesign{$role.'.'.$item}; 869: } 870: if (ref($settings) eq 'HASH') { 871: if (ref($settings->{$role}) eq 'HASH') { 872: if ($settings->{$role}->{'img'} ne '') { 873: $designs{'img'} = $settings->{$role}->{'img'}; 874: $is_custom{'img'} = 1; 875: } 876: if ($settings->{$role}->{'font'} ne '') { 877: $designs{'font'} = $settings->{$role}->{'font'}; 878: $is_custom{'font'} = 1; 879: } 880: if ($settings->{$role}->{'fontmenu'} ne '') { 881: $designs{'fontmenu'} = $settings->{$role}->{'fontmenu'}; 882: $is_custom{'fontmenu'} = 1; 883: } 884: foreach my $item (@bgs) { 885: if ($settings->{$role}->{$item} ne '') { 886: $designs{'bgs'}{$item} = $settings->{$role}->{$item}; 887: $is_custom{$item} = 1; 888: } 889: } 890: foreach my $item (@links) { 891: if ($settings->{$role}->{$item} ne '') { 892: $designs{'links'}{$item} = $settings->{$role}->{$item}; 893: $is_custom{$item} = 1; 894: } 895: } 896: } 897: } else { 898: if ($designhash{$dom.'.'.$role.'.img'} ne '') { 899: $designs{img} = $designhash{$dom.'.'.$role.'.img'}; 900: $is_custom{'img'} = 1; 901: } 902: if ($designhash{$dom.'.'.$role.'.fontmenu'} ne '') { 903: $designs{fontmenu} = $designhash{$dom.'.'.$role.'.fontmenu'}; 904: $is_custom{'fontmenu'} = 1; 905: } 906: if ($designhash{$dom.'.'.$role.'.font'} ne '') { 907: $designs{font} = $designhash{$dom.'.'.$role.'.font'}; 908: $is_custom{'font'} = 1; 909: } 910: foreach my $item (@bgs) { 911: if ($designhash{$dom.'.'.$role.'.'.$item} ne '') { 912: $designs{'bgs'}{$item} = $designhash{$dom.'.'.$role.'.'.$item}; 913: $is_custom{$item} = 1; 914: 915: } 916: } 917: foreach my $item (@links) { 918: if ($designhash{$dom.'.'.$role.'.'.$item} ne '') { 919: $designs{'links'}{$item} = $designhash{$dom.'.'.$role.'.'.$item}; 920: $is_custom{$item} = 1; 921: } 922: } 923: } 924: my $itemcount = 1; 925: my $datatable = &display_color_options($dom,$confname,$phase,$role,$itemcount,\%choices,\%is_custom,\%defaults,\%designs,\@images,\@bgs,\@links,\%alt_text,$rowtotal); 926: $datatable .= '</tr></table></td></tr>'; 927: return $datatable; 928: } 929: 930: sub display_color_options { 931: my ($dom,$confname,$phase,$role,$itemcount,$choices,$is_custom,$defaults,$designs, 932: $images,$bgs,$links,$alt_text,$rowtotal,$logintext,$loginheader) = @_; 933: my $css_class = $itemcount%2?' class="LC_odd_row"':''; 934: my $datatable = '<tr>'. 935: '<td>'.$choices->{'font'}.'</td>'; 936: if (!$is_custom->{'font'}) { 937: $datatable .= '<td>'.&mt('Default in use:').' <span id="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>'; 938: } else { 939: $datatable .= '<td> </td>'; 940: } 941: my $fontlink = &color_pick($phase,$role,'font',$choices->{'font'},$designs->{'font'}); 942: $datatable .= '<td><span class="LC_nobreak">'. 943: '<input type="text" size="10" name="'.$role.'_font"'. 944: ' value="'.$designs->{'font'}.'" /> '.$fontlink. 945: ' <span id="css_'.$role.'_font" style="background-color: '. 946: $designs->{'font'}.';"> </span>'. 947: '</span></td></tr>'; 948: unless ($role eq 'login') { 949: $datatable .= '<tr'.$css_class.'>'. 950: '<td>'.$choices->{'fontmenu'}.'</td>'; 951: if (!$is_custom->{'fontmenu'}) { 952: $datatable .= '<td>'.&mt('Default in use:').' <span id="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>'; 953: } else { 954: $datatable .= '<td> </td>'; 955: } 956: $fontlink = &color_pick($phase,$role,'fontmenu',$choices->{'fontmenu'},$designs->{'fontmenu'}); 957: $datatable .= '<td><span class="LC_nobreak">'. 958: '<input type="text" size="10" name="'.$role.'_fontmenu"'. 959: ' value="'.$designs->{'fontmenu'}.'" /> '.$fontlink. 960: ' <span id="css_'.$role.'_fontmenu" style="background-color: '. 961: $designs->{'fontmenu'}.';"> </span>'. 962: '</span></td></tr>'; 963: } 964: my $switchserver = &check_switchserver($dom,$confname); 965: foreach my $img (@{$images}) { 966: $itemcount ++; 967: $css_class = $itemcount%2?' class="LC_odd_row"':''; 968: $datatable .= '<tr'.$css_class.'>'. 969: '<td>'.$choices->{$img}; 970: my ($imgfile,$img_import,$login_hdr_pick,$logincolors); 971: if ($role eq 'login') { 972: if ($img eq 'login') { 973: $login_hdr_pick = 974: &login_header_options($img,$role,$defaults,$is_custom,$choices, 975: $loginheader); 976: $logincolors = 977: &login_text_colors($img,$role,$logintext,$phase,$choices, 978: $designs); 979: } elsif ($img ne 'domlogo') { 980: $datatable.= &logo_display_options($img,$defaults,$designs); 981: } 982: } 983: $datatable .= '</td>'; 984: if ($designs->{$img} ne '') { 985: $imgfile = $designs->{$img}; 986: $img_import = ($imgfile =~ m{^/adm/}); 987: } else { 988: $imgfile = $defaults->{$img}; 989: } 990: if ($imgfile) { 991: my ($showfile,$fullsize); 992: if ($imgfile =~ m-^(/res/\Q$dom\E/\Q$confname\E/\Q$img\E)/([^/]+)$-) { 993: my $urldir = $1; 994: my $filename = $2; 995: my @info = &Apache::lonnet::stat_file($designs->{$img}); 996: if (@info) { 997: my $thumbfile = 'tn-'.$filename; 998: my @thumb=&Apache::lonnet::stat_file($urldir.'/'.$thumbfile); 999: if (@thumb) { 1000: $showfile = $urldir.'/'.$thumbfile; 1001: } else { 1002: $showfile = $imgfile; 1003: } 1004: } else { 1005: $showfile = ''; 1006: } 1007: } elsif ($imgfile =~ m-^/(adm/[^/]+)/([^/]+)$-) { 1008: $showfile = $imgfile; 1009: my $imgdir = $1; 1010: my $filename = $2; 1011: if (-e "/home/httpd/html/$imgdir/tn-".$filename) { 1012: $showfile = "/$imgdir/tn-".$filename; 1013: } else { 1014: my $input = "/home/httpd/html".$imgfile; 1015: my $output = '/home/httpd/html/'.$imgdir.'/tn-'.$filename; 1016: if (!-e $output) { 1017: my ($width,$height) = &thumb_dimensions(); 1018: my ($fullwidth,$fullheight) = &check_dimensions($input); 1019: if ($fullwidth ne '' && $fullheight ne '') { 1020: if ($fullwidth > $width && $fullheight > $height) { 1021: my $size = $width.'x'.$height; 1022: system("convert -sample $size $input $output"); 1023: $showfile = '/'.$imgdir.'/tn-'.$filename; 1024: } 1025: } 1026: } 1027: } 1028: } 1029: if ($showfile) { 1030: if ($showfile =~ m{^/(adm|res)/}) { 1031: if ($showfile =~ m{^/res/}) { 1032: my $local_showfile = 1033: &Apache::lonnet::filelocation('',$showfile); 1034: &Apache::lonnet::repcopy($local_showfile); 1035: } 1036: $showfile = &Apache::loncommon::lonhttpdurl($showfile); 1037: } 1038: if ($imgfile) { 1039: if ($imgfile =~ m{^/(adm|res)/}) { 1040: if ($imgfile =~ m{^/res/}) { 1041: my $local_imgfile = 1042: &Apache::lonnet::filelocation('',$imgfile); 1043: &Apache::lonnet::repcopy($local_imgfile); 1044: } 1045: $fullsize = &Apache::loncommon::lonhttpdurl($imgfile); 1046: } else { 1047: $fullsize = $imgfile; 1048: } 1049: } 1050: $datatable .= '<td>'; 1051: if ($img eq 'login') { 1052: $datatable .= $login_hdr_pick; 1053: } 1054: $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import, 1055: $showfile,$fullsize,$role,$img,$imgfile,$logincolors); 1056: } else { 1057: $datatable .= '<td colspan="2" class="LC_right_item"><br />'. 1058: &mt('Upload:'); 1059: } 1060: } else { 1061: $datatable .= '<td colspan="2" class="LC_right_item"><br />'. 1062: &mt('Upload:'); 1063: } 1064: if ($switchserver) { 1065: $datatable .= &mt('Upload to library server: [_1]',$switchserver); 1066: } else { 1067: $datatable .=' <input type="file" name="'.$role.'_'.$img.'" />'; 1068: } 1069: $datatable .= '</td></tr>'; 1070: } 1071: $itemcount ++; 1072: $css_class = $itemcount%2?' class="LC_odd_row"':''; 1073: $datatable .= '<tr'.$css_class.'>'. 1074: '<td>'.$choices->{'bgs'}.'</td>'; 1075: my $bgs_def; 1076: foreach my $item (@{$bgs}) { 1077: if (!$is_custom->{$item}) { 1078: $bgs_def .= '<td><span class="LC_nobreak">'.$choices->{$item}.'</span> <span id="css_default_'.$role.'_'.$item.'" style="background-color: '.$defaults->{'bgs'}{$item}.';"> </span><br />'.$defaults->{'bgs'}{$item}.'</td>'; 1079: } 1080: } 1081: if ($bgs_def) { 1082: $datatable .= '<td>'.&mt('Default(s) in use:').'<br /><table border="0"><tr>'.$bgs_def.'</tr></table></td>'; 1083: } else { 1084: $datatable .= '<td> </td>'; 1085: } 1086: $datatable .= '<td class="LC_right_item">'. 1087: '<table border="0"><tr>'; 1088: foreach my $item (@{$bgs}) { 1089: my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'bgs'}{$item}); 1090: $datatable .= '<td align="center">'.$link; 1091: if ($designs->{'bgs'}{$item}) { 1092: $datatable .= ' <span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'bgs'}{$item}.';"> </span>'; 1093: } 1094: $datatable .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.$designs->{'bgs'}{$item}. 1095: '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>'; 1096: } 1097: $datatable .= '</tr></table></td></tr>'; 1098: $itemcount ++; 1099: $css_class = $itemcount%2?' class="LC_odd_row"':''; 1100: $datatable .= '<tr'.$css_class.'>'. 1101: '<td>'.$choices->{'links'}.'</td>'; 1102: my $links_def; 1103: foreach my $item (@{$links}) { 1104: if (!$is_custom->{$item}) { 1105: $links_def .= '<td>'.$choices->{$item}.'<br /><span id="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>'; 1106: } 1107: } 1108: if ($links_def) { 1109: $datatable .= '<td>'.&mt('Default(s) in use:').'<br /><table border="0"><tr>'.$links_def.'</tr></table></td>'; 1110: } else { 1111: $datatable .= '<td> </td>'; 1112: } 1113: $datatable .= '<td class="LC_right_item">'. 1114: '<table border="0"><tr>'; 1115: foreach my $item (@{$links}) { 1116: $datatable .= '<td align="center">'."\n". 1117: &color_pick($phase,$role,$item,$choices->{$item}, 1118: $designs->{'links'}{$item}); 1119: if ($designs->{'links'}{$item}) { 1120: $datatable.=' <span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'links'}{$item}.';"> </span>'; 1121: } 1122: $datatable .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'.$designs->{'links'}{$item}. 1123: '" /></td>'; 1124: } 1125: $$rowtotal += $itemcount; 1126: return $datatable; 1127: } 1128: 1129: sub logo_display_options { 1130: my ($img,$defaults,$designs) = @_; 1131: my $checkedon; 1132: if (ref($defaults) eq 'HASH') { 1133: if (ref($defaults->{'showlogo'}) eq 'HASH') { 1134: if ($defaults->{'showlogo'}{$img}) { 1135: $checkedon = 'checked="checked" '; 1136: } 1137: } 1138: } 1139: if (ref($designs) eq 'HASH') { 1140: if (ref($designs->{'showlogo'}) eq 'HASH') { 1141: if (defined($designs->{'showlogo'}{$img})) { 1142: if ($designs->{'showlogo'}{$img} == 0) { 1143: $checkedon = ''; 1144: } elsif ($designs->{'showlogo'}{$img} == 1) { 1145: $checkedon = 'checked="checked" '; 1146: } 1147: } 1148: } 1149: } 1150: return '<br /><label> <input type="checkbox" name="'. 1151: 'login_showlogo_'.$img.'" value="1" '.$checkedon.'/>'. 1152: &mt('show').'</label>'."\n"; 1153: } 1154: 1155: sub login_header_options { 1156: my ($img,$role,$defaults,$is_custom,$choices,$loginheader) = @_; 1157: my $image_checked = ' checked="checked" '; 1158: my $text_checked = ' '; 1159: if ($loginheader eq 'text') { 1160: $image_checked = ' '; 1161: $text_checked = ' checked="checked" '; 1162: } 1163: my $output = '<span class="LC_nobreak"><label><input type="radio" name="'. 1164: 'loginheader" value="image" '.$image_checked.'/>'. 1165: &mt('use image').'</label> '. 1166: '<label><input type="radio" name="loginheader" value="text"'. 1167: $text_checked.'/>'.&mt('use text').'</label><br />'."\n"; 1168: if ((!$is_custom->{'textcol'}) || (!$is_custom->{'bgcol'})) { 1169: $output .= &mt('Text default(s)').':<br />'; 1170: if (!$is_custom->{'textcol'}) { 1171: $output .= $choices->{'textcol'}.': '.$defaults->{'logintext'}{'textcol'}. 1172: ' '; 1173: } 1174: if (!$is_custom->{'bgcol'}) { 1175: $output .= $choices->{'bgcol'}.': '. 1176: '<span id="css_'.$role.'_font" style="background-color: '. 1177: $defaults->{'logintext'}{'bgcol'}.';"> </span>'; 1178: } 1179: $output .= '<br />'; 1180: } 1181: $output .='<br />'; 1182: return $output; 1183: } 1184: 1185: sub login_text_colors { 1186: my ($img,$role,$logintext,$phase,$choices,$designs) = @_; 1187: my $color_menu = '<table border="0"><tr>'; 1188: foreach my $item (@{$logintext}) { 1189: my $link = &color_pick($phase,$role,$item,$choices->{$item},$designs->{'logintext'}{$item}); 1190: $color_menu .= '<td align="center">'.$link; 1191: if ($designs->{'logintext'}{$item}) { 1192: $color_menu .= ' <span id="css_'.$role.'_'.$item.'" style="background-color: '.$designs->{'logintext'}{$item}.';"> </span>'; 1193: } 1194: $color_menu .= '<br /><input type="text" size="8" name="'.$role.'_'.$item.'" value="'. 1195: $designs->{'logintext'}{$item}.'" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>'. 1196: '<td> </td>'; 1197: } 1198: $color_menu .= '</tr></table><br />'; 1199: return $color_menu; 1200: } 1201: 1202: sub image_changes { 1203: my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_; 1204: my $output; 1205: if (!$is_custom) { 1206: if ($img ne 'domlogo') { 1207: $output .= &mt('Default image:').'<br />'; 1208: } else { 1209: $output .= &mt('Default in use:').'<br />'; 1210: } 1211: } 1212: if ($img_import) { 1213: $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />'; 1214: } 1215: $output .= '<a href="'.$fullsize.'" target="_blank"><img src="'. 1216: $showfile.'" alt="'.$alt_text.'" border="0" /></a></td>'; 1217: if ($is_custom) { 1218: $output .= '<td>'.$logincolors.'<span class="LC_nobreak"><label>'. 1219: '<input type="checkbox" name="'. 1220: $role.'_del_'.$img.'" value="1" />'.&mt('Delete?'). 1221: '</label> '.&mt('Replace:').'</span><br />'; 1222: } else { 1223: $output .= '<td valign="bottom">'.$logincolors.&mt('Upload:').'<br />'; 1224: } 1225: return $output; 1226: } 1227: 1228: sub color_pick { 1229: my ($phase,$role,$item,$desc,$curcol) = @_; 1230: my $link = '<a href="javascript:pjump('."'color_custom','".$desc. 1231: "','".$curcol."','".$role.'_'.$item."','parmform.pres','psub'". 1232: ');">'.$desc.'</a>'; 1233: return $link; 1234: } 1235: 1236: sub print_quotas { 1237: my ($dom,$settings,$rowtotal,$action) = @_; 1238: my $context; 1239: if ($action eq 'quotas') { 1240: $context = 'tools'; 1241: } else { 1242: $context = $action; 1243: } 1244: my ($datatable,$defaultquota,@usertools,@options,%validations); 1245: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 1246: my $typecount = 0; 1247: my ($css_class,%titles); 1248: if ($context eq 'requestcourses') { 1249: @usertools = ('official','unofficial','community'); 1250: @options =('norequest','approval','validate','autolimit'); 1251: %validations = &Apache::lonnet::auto_courserequest_checks($dom); 1252: %titles = &courserequest_titles(); 1253: } else { 1254: @usertools = ('aboutme','blog','portfolio'); 1255: %titles = &tool_titles(); 1256: } 1257: if (ref($types) eq 'ARRAY') { 1258: foreach my $type (@{$types}) { 1259: my $currdefquota; 1260: unless ($context eq 'requestcourses') { 1261: if (ref($settings) eq 'HASH') { 1262: if (ref($settings->{defaultquota}) eq 'HASH') { 1263: $currdefquota = $settings->{defaultquota}->{$type}; 1264: } else { 1265: $currdefquota = $settings->{$type}; 1266: } 1267: } 1268: } 1269: if (defined($usertypes->{$type})) { 1270: $typecount ++; 1271: $css_class = $typecount%2?' class="LC_odd_row"':''; 1272: $datatable .= '<tr'.$css_class.'>'. 1273: '<td>'.$usertypes->{$type}.'</td>'. 1274: '<td class="LC_left_item">'; 1275: if ($context eq 'requestcourses') { 1276: $datatable .= '<table><tr>'; 1277: } 1278: my %cell; 1279: foreach my $item (@usertools) { 1280: if ($context eq 'requestcourses') { 1281: my ($curroption,$currlimit); 1282: if (ref($settings) eq 'HASH') { 1283: if (ref($settings->{$item}) eq 'HASH') { 1284: $curroption = $settings->{$item}->{$type}; 1285: if ($curroption =~ /^autolimit=(\d*)$/) { 1286: $currlimit = $1; 1287: } 1288: } 1289: } 1290: if (!$curroption) { 1291: $curroption = 'norequest'; 1292: } 1293: $datatable .= '<th>'.$titles{$item}.'</th>'; 1294: foreach my $option (@options) { 1295: my $val = $option; 1296: if ($option eq 'norequest') { 1297: $val = 0; 1298: } 1299: if ($option eq 'validate') { 1300: my $canvalidate = 0; 1301: if (ref($validations{$item}) eq 'HASH') { 1302: if ($validations{$item}{$type}) { 1303: $canvalidate = 1; 1304: } 1305: } 1306: next if (!$canvalidate); 1307: } 1308: my $checked = ''; 1309: if ($option eq $curroption) { 1310: $checked = ' checked="checked"'; 1311: } elsif ($option eq 'autolimit') { 1312: if ($curroption =~ /^autolimit/) { 1313: $checked = ' checked="checked"'; 1314: } 1315: } 1316: $cell{$item} .= '<span class="LC_nobreak"><label>'. 1317: '<input type="radio" name="crsreq_'.$item. 1318: '_'.$type.'" value="'.$val.'"'.$checked.' />'. 1319: $titles{$option}.'</label> '; 1320: if ($option eq 'autolimit') { 1321: $cell{$item} .= '<input type="text" name="crsreq_'. 1322: $item.'_limit_'.$type.'" size="1" '. 1323: 'value="'.$currlimit.'" />'; 1324: } 1325: $cell{$item} .= '</span> '; 1326: if ($option eq 'autolimit') { 1327: $cell{$item} .= $titles{'unlimited'} 1328: } 1329: } 1330: } else { 1331: my $checked = 'checked="checked" '; 1332: if (ref($settings) eq 'HASH') { 1333: if (ref($settings->{$item}) eq 'HASH') { 1334: if ($settings->{$item}->{$type} == 0) { 1335: $checked = ''; 1336: } elsif ($settings->{$item}->{$type} == 1) { 1337: $checked = 'checked="checked" '; 1338: } 1339: } 1340: } 1341: $datatable .= '<span class="LC_nobreak"><label>'. 1342: '<input type="checkbox" name="'.$context.'_'.$item. 1343: '" value="'.$type.'" '.$checked.'/>'.$titles{$item}. 1344: '</label></span> '; 1345: } 1346: } 1347: if ($context eq 'requestcourses') { 1348: $datatable .= '</tr><tr>'; 1349: foreach my $item (@usertools) { 1350: $datatable .= '<td style="vertical-align: top">'.$cell{$item}.'</td>'; 1351: } 1352: $datatable .= '</tr></table>'; 1353: } 1354: $datatable .= '</td>'; 1355: unless ($context eq 'requestcourses') { 1356: $datatable .= 1357: '<td class="LC_right_item"><span class="LC_nobreak">'. 1358: '<input type="text" name="quota_'.$type. 1359: '" value="'.$currdefquota. 1360: '" size="5" /> Mb</span></td>'; 1361: } 1362: $datatable .= '</tr>'; 1363: } 1364: } 1365: } 1366: unless ($context eq 'requestcourses') { 1367: $defaultquota = '20'; 1368: if (ref($settings) eq 'HASH') { 1369: if (ref($settings->{'defaultquota'}) eq 'HASH') { 1370: $defaultquota = $settings->{'defaultquota'}->{'default'}; 1371: } elsif (defined($settings->{'default'})) { 1372: $defaultquota = $settings->{'default'}; 1373: } 1374: } 1375: } 1376: $typecount ++; 1377: $css_class = $typecount%2?' class="LC_odd_row"':''; 1378: $datatable .= '<tr'.$css_class.'>'. 1379: '<td>'.$othertitle.'</td>'. 1380: '<td class="LC_left_item">'; 1381: if ($context eq 'requestcourses') { 1382: $datatable .= '<table><tr>'; 1383: } 1384: my %defcell; 1385: foreach my $item (@usertools) { 1386: if ($context eq 'requestcourses') { 1387: my ($curroption,$currlimit); 1388: if (ref($settings) eq 'HASH') { 1389: if (ref($settings->{$item}) eq 'HASH') { 1390: $curroption = $settings->{$item}->{'default'}; 1391: if ($curroption =~ /^autolimit=(\d*)$/) { 1392: $currlimit = $1; 1393: } 1394: } 1395: } 1396: if (!$curroption) { 1397: $curroption = 'norequest'; 1398: } 1399: $datatable .= '<th>'.$titles{$item}.'</th>'; 1400: foreach my $option (@options) { 1401: my $val = $option; 1402: if ($option eq 'norequest') { 1403: $val = 0; 1404: } 1405: if ($option eq 'validate') { 1406: my $canvalidate = 0; 1407: if (ref($validations{$item}) eq 'HASH') { 1408: if ($validations{$item}{'default'}) { 1409: $canvalidate = 1; 1410: } 1411: } 1412: next if (!$canvalidate); 1413: } 1414: my $checked = ''; 1415: if ($option eq $curroption) { 1416: $checked = ' checked="checked"'; 1417: } elsif ($option eq 'autolimit') { 1418: if ($curroption =~ /^autolimit/) { 1419: $checked = ' checked="checked"'; 1420: } 1421: } 1422: $defcell{$item} .= '<span class="LC_nobreak"><label>'. 1423: '<input type="radio" name="crsreq_'.$item. 1424: '_default" value="'.$val.'"'.$checked.' />'. 1425: $titles{$option}.'</label>'; 1426: if ($option eq 'autolimit') { 1427: $defcell{$item} .= '<input type="text" name="crsreq_'. 1428: $item.'_limit_default" size="1" '. 1429: 'value="'.$currlimit.'" />'; 1430: } 1431: $defcell{$item} .= '</span> '; 1432: if ($option eq 'autolimit') { 1433: $defcell{$item} .= $titles{'unlimited'} 1434: } 1435: } 1436: } else { 1437: my $checked = 'checked="checked" '; 1438: if (ref($settings) eq 'HASH') { 1439: if (ref($settings->{$item}) eq 'HASH') { 1440: if ($settings->{$item}->{'default'} == 0) { 1441: $checked = ''; 1442: } elsif ($settings->{$item}->{'default'} == 1) { 1443: $checked = 'checked="checked" '; 1444: } 1445: } 1446: } 1447: $datatable .= '<span class="LC_nobreak"><label>'. 1448: '<input type="checkbox" name="'.$context.'_'.$item. 1449: '" value="default" '.$checked.'/>'.$titles{$item}. 1450: '</label></span> '; 1451: } 1452: } 1453: if ($context eq 'requestcourses') { 1454: $datatable .= '</tr><tr>'; 1455: foreach my $item (@usertools) { 1456: $datatable .= '<td style="vertical-align: top">'.$defcell{$item}.'</td>'; 1457: } 1458: $datatable .= '</tr></table>'; 1459: } 1460: $datatable .= '</td>'; 1461: unless ($context eq 'requestcourses') { 1462: $datatable .= '<td class="LC_right_item"><span class="LC_nobreak">'. 1463: '<input type="text" name="defaultquota" value="'. 1464: $defaultquota.'" size="5" /> Mb</span></td>'; 1465: } 1466: $datatable .= '</tr>'; 1467: $typecount ++; 1468: $css_class = $typecount%2?' class="LC_odd_row"':''; 1469: $datatable .= '<tr'.$css_class.'>'. 1470: '<td>'.&mt('LON-CAPA Advanced Users').' '; 1471: if ($context eq 'requestcourses') { 1472: $datatable .= &mt('(overrides affiliation, if set)'). 1473: '</td>'. 1474: '<td class="LC_left_item">'. 1475: '<table><tr>'; 1476: } else { 1477: $datatable .= &mt('(overrides affiliation, if checked)'). 1478: '</td>'. 1479: '<td class="LC_left_item" colspan="2">'. 1480: '<br />'; 1481: } 1482: my %advcell; 1483: foreach my $item (@usertools) { 1484: if ($context eq 'requestcourses') { 1485: my ($curroption,$currlimit); 1486: if (ref($settings) eq 'HASH') { 1487: if (ref($settings->{$item}) eq 'HASH') { 1488: $curroption = $settings->{$item}->{'_LC_adv'}; 1489: if ($curroption =~ /^autolimit=(\d*)$/) { 1490: $currlimit = $1; 1491: } 1492: } 1493: } 1494: $datatable .= '<th>'.$titles{$item}.'</th>'; 1495: my $checked = ''; 1496: if ($curroption eq '') { 1497: $checked = ' checked="checked"'; 1498: } 1499: $advcell{$item} .= '<span class="LC_nobreak"><label>'. 1500: '<input type="radio" name="crsreq_'.$item. 1501: '__LC_adv" value=""'.$checked.' />'. 1502: &mt('No override set').'</label></span> '; 1503: foreach my $option (@options) { 1504: my $val = $option; 1505: if ($option eq 'norequest') { 1506: $val = 0; 1507: } 1508: if ($option eq 'validate') { 1509: my $canvalidate = 0; 1510: if (ref($validations{$item}) eq 'HASH') { 1511: if ($validations{$item}{'_LC_adv'}) { 1512: $canvalidate = 1; 1513: } 1514: } 1515: next if (!$canvalidate); 1516: } 1517: my $checked = ''; 1518: if ($val eq $curroption) { 1519: $checked = ' checked="checked"'; 1520: } elsif ($option eq 'autolimit') { 1521: if ($curroption =~ /^autolimit/) { 1522: $checked = ' checked="checked"'; 1523: } 1524: } 1525: $advcell{$item} .= '<span class="LC_nobreak"><label>'. 1526: '<input type="radio" name="crsreq_'.$item. 1527: '__LC_adv" value="'.$val.'"'.$checked.' />'. 1528: $titles{$option}.'</label>'; 1529: if ($option eq 'autolimit') { 1530: $advcell{$item} .= '<input type="text" name="crsreq_'. 1531: $item.'_limit__LC_adv" size="1" '. 1532: 'value="'.$currlimit.'" />'; 1533: } 1534: $advcell{$item} .= '</span> '; 1535: if ($option eq 'autolimit') { 1536: $advcell{$item} .= $titles{'unlimited'} 1537: } 1538: } 1539: } else { 1540: my $checked = 'checked="checked" '; 1541: if (ref($settings) eq 'HASH') { 1542: if (ref($settings->{$item}) eq 'HASH') { 1543: if ($settings->{$item}->{'_LC_adv'} == 0) { 1544: $checked = ''; 1545: } elsif ($settings->{$item}->{'_LC_adv'} == 1) { 1546: $checked = 'checked="checked" '; 1547: } 1548: } 1549: } 1550: $datatable .= '<span class="LC_nobreak"><label>'. 1551: '<input type="checkbox" name="'.$context.'_'.$item. 1552: '" value="_LC_adv" '.$checked.'/>'.$titles{$item}. 1553: '</label></span> '; 1554: } 1555: } 1556: if ($context eq 'requestcourses') { 1557: $datatable .= '</tr><tr>'; 1558: foreach my $item (@usertools) { 1559: $datatable .= '<td style="vertical-align: top">'.$advcell{$item}.'</td>'; 1560: } 1561: $datatable .= '</tr></table>'; 1562: } 1563: $datatable .= '</td></tr>'; 1564: $$rowtotal += $typecount; 1565: return $datatable; 1566: } 1567: 1568: sub print_courserequestmail { 1569: my ($dom,$settings,$rowtotal) = @_; 1570: my ($now,$datatable,%dompersonnel,@domcoord,@currapproval,$rows); 1571: $now = time; 1572: $rows = 0; 1573: %dompersonnel = &Apache::lonnet::get_domain_roles($dom,['dc'],$now,$now); 1574: foreach my $server (keys(%dompersonnel)) { 1575: foreach my $user (sort(keys(%{$dompersonnel{$server}}))) { 1576: my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user); 1577: if (!grep(/^$uname:$udom$/,@domcoord)) { 1578: push(@domcoord,$uname.':'.$udom); 1579: } 1580: } 1581: } 1582: if (ref($settings) eq 'HASH') { 1583: if (ref($settings->{'notify'}) eq 'HASH') { 1584: if ($settings->{'notify'}{'approval'} ne '') { 1585: @currapproval = split(',',$settings->{'notify'}{'approval'}); 1586: } 1587: } 1588: } 1589: if (@currapproval) { 1590: foreach my $dc (@currapproval) { 1591: unless (grep(/^\Q$dc\E$/,@domcoord)) { 1592: push(@domcoord,$dc); 1593: } 1594: } 1595: } 1596: @domcoord = sort(@domcoord); 1597: my $numinrow = 4; 1598: my $numdc = @domcoord; 1599: my $css_class = 'class="LC_odd_row"'; 1600: $datatable = '<tr'.$css_class.'>'. 1601: ' <td>'.&mt('Receive notification of course requests requiring approval.'). 1602: ' </td>'. 1603: ' <td class="LC_left_item">'; 1604: if (@domcoord > 0) { 1605: $datatable .= '<table>'; 1606: for (my $i=0; $i<$numdc; $i++) { 1607: my $rem = $i%($numinrow); 1608: if ($rem == 0) { 1609: if ($i > 0) { 1610: $datatable .= '</tr>'; 1611: } 1612: $datatable .= '<tr>'; 1613: $rows ++; 1614: } 1615: my $check = ' '; 1616: if (grep(/^\Q$domcoord[$i]\E$/,@currapproval)) { 1617: $check = ' checked="checked" '; 1618: } 1619: my ($uname,$udom) = split(':',$domcoord[$i]); 1620: my $fullname = &Apache::loncommon::plainname($uname,$udom); 1621: if ($i == $numdc-1) { 1622: my $colsleft = $numinrow-$rem; 1623: if ($colsleft > 1) { 1624: $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; 1625: } else { 1626: $datatable .= '<td class="LC_left_item">'; 1627: } 1628: } else { 1629: $datatable .= '<td class="LC_left_item">'; 1630: } 1631: $datatable .= '<span class="LC_nobreak"><label>'. 1632: '<input type="checkbox" name="reqapprovalnotify" '. 1633: 'value="'.$domcoord[$i].'"'.$check.'/>'. 1634: $fullname.'</label></span></td>'; 1635: } 1636: $datatable .= '</tr></table>'; 1637: } else { 1638: $datatable .= &mt('There are no active Domain Coordinators'); 1639: $rows ++; 1640: } 1641: $datatable .='</td></tr>'; 1642: $$rowtotal += $rows; 1643: return $datatable; 1644: } 1645: 1646: sub print_autoenroll { 1647: my ($dom,$settings,$rowtotal) = @_; 1648: my $autorun = &Apache::lonnet::auto_run(undef,$dom), 1649: my ($defdom,$runon,$runoff); 1650: if (ref($settings) eq 'HASH') { 1651: if (exists($settings->{'run'})) { 1652: if ($settings->{'run'} eq '0') { 1653: $runoff = ' checked="checked" '; 1654: $runon = ' '; 1655: } else { 1656: $runon = ' checked="checked" '; 1657: $runoff = ' '; 1658: } 1659: } else { 1660: if ($autorun) { 1661: $runon = ' checked="checked" '; 1662: $runoff = ' '; 1663: } else { 1664: $runoff = ' checked="checked" '; 1665: $runon = ' '; 1666: } 1667: } 1668: if (exists($settings->{'sender_domain'})) { 1669: $defdom = $settings->{'sender_domain'}; 1670: } 1671: } else { 1672: if ($autorun) { 1673: $runon = ' checked="checked" '; 1674: $runoff = ' '; 1675: } else { 1676: $runoff = ' checked="checked" '; 1677: $runon = ' '; 1678: } 1679: } 1680: my $domform = &Apache::loncommon::select_dom_form($defdom,'sender_domain',1); 1681: my $notif_sender; 1682: if (ref($settings) eq 'HASH') { 1683: $notif_sender = $settings->{'sender_uname'}; 1684: } 1685: my $datatable='<tr class="LC_odd_row">'. 1686: '<td>'.&mt('Auto-enrollment active?').'</td>'. 1687: '<td class="LC_right_item"><span class="LC_nobreak"><label>'. 1688: '<input type="radio" name="autoenroll_run"'. 1689: $runon.' value="1" />'.&mt('Yes').'</label> '. 1690: '<label><input type="radio" name="autoenroll_run"'. 1691: $runoff.' value="0" />'.&mt('No').'</label></span></td>'. 1692: '</tr><tr>'. 1693: '<td>'.&mt('Notification messages - sender'). 1694: '</td><td class="LC_right_item"><span class="LC_nobreak">'. 1695: &mt('username').': '. 1696: '<input type="text" name="sender_uname" value="'. 1697: $notif_sender.'" size="10" /> '.&mt('domain'). 1698: ': '.$domform.'</span></td></tr>'; 1699: $$rowtotal += 2; 1700: return $datatable; 1701: } 1702: 1703: sub print_autoupdate { 1704: my ($position,$dom,$settings,$rowtotal) = @_; 1705: my $datatable; 1706: if ($position eq 'top') { 1707: my $updateon = ' '; 1708: my $updateoff = ' checked="checked" '; 1709: my $classlistson = ' '; 1710: my $classlistsoff = ' checked="checked" '; 1711: if (ref($settings) eq 'HASH') { 1712: if ($settings->{'run'} eq '1') { 1713: $updateon = $updateoff; 1714: $updateoff = ' '; 1715: } 1716: if ($settings->{'classlists'} eq '1') { 1717: $classlistson = $classlistsoff; 1718: $classlistsoff = ' '; 1719: } 1720: } 1721: my %title = ( 1722: run => 'Auto-update active?', 1723: classlists => 'Update information in classlists?', 1724: ); 1725: $datatable = '<tr class="LC_odd_row">'. 1726: '<td>'.&mt($title{'run'}).'</td>'. 1727: '<td class="LC_right_item"><span class="LC_nobreak"><label>'. 1728: '<input type="radio" name="autoupdate_run"'. 1729: $updateon.' value="1" />'.&mt('Yes').'</label> '. 1730: '<label><input type="radio" name="autoupdate_run"'. 1731: $updateoff.'value="0" />'.&mt('No').'</label></span></td>'. 1732: '</tr><tr>'. 1733: '<td>'.&mt($title{'classlists'}).'</td>'. 1734: '<td class="LC_right_item"><span class="LC_nobreak">'. 1735: '<label><input type="radio" name="classlists"'. 1736: $classlistson.' value="1" />'.&mt('Yes').'</label> '. 1737: '<label><input type="radio" name="classlists"'. 1738: $classlistsoff.'value="0" />'.&mt('No').'</label></span></td>'. 1739: '</tr>'; 1740: $$rowtotal += 2; 1741: } else { 1742: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 1743: my @fields = ('lastname','firstname','middlename','gen', 1744: 'permanentemail','id'); 1745: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); 1746: my $numrows = 0; 1747: if (ref($types) eq 'ARRAY') { 1748: if (@{$types} > 0) { 1749: $datatable = 1750: &usertype_update_row($settings,$usertypes,\%fieldtitles, 1751: \@fields,$types,\$numrows); 1752: $$rowtotal += @{$types}; 1753: } 1754: } 1755: $datatable .= 1756: &usertype_update_row($settings,{'default' => $othertitle}, 1757: \%fieldtitles,\@fields,['default'], 1758: \$numrows); 1759: $$rowtotal ++; 1760: } 1761: return $datatable; 1762: } 1763: 1764: sub print_directorysrch { 1765: my ($dom,$settings,$rowtotal) = @_; 1766: my $srchon = ' '; 1767: my $srchoff = ' checked="checked" '; 1768: my ($exacton,$containson,$beginson); 1769: my $localon = ' '; 1770: my $localoff = ' checked="checked" '; 1771: if (ref($settings) eq 'HASH') { 1772: if ($settings->{'available'} eq '1') { 1773: $srchon = $srchoff; 1774: $srchoff = ' '; 1775: } 1776: if ($settings->{'localonly'} eq '1') { 1777: $localon = $localoff; 1778: $localoff = ' '; 1779: } 1780: if (ref($settings->{'searchtypes'}) eq 'ARRAY') { 1781: foreach my $type (@{$settings->{'searchtypes'}}) { 1782: if ($type eq 'exact') { 1783: $exacton = ' checked="checked" '; 1784: } elsif ($type eq 'contains') { 1785: $containson = ' checked="checked" '; 1786: } elsif ($type eq 'begins') { 1787: $beginson = ' checked="checked" '; 1788: } 1789: } 1790: } else { 1791: if ($settings->{'searchtypes'} eq 'exact') { 1792: $exacton = ' checked="checked" '; 1793: } elsif ($settings->{'searchtypes'} eq 'contains') { 1794: $containson = ' checked="checked" '; 1795: } elsif ($settings->{'searchtypes'} eq 'specify') { 1796: $exacton = ' checked="checked" '; 1797: $containson = ' checked="checked" '; 1798: } 1799: } 1800: } 1801: my ($searchtitles,$titleorder) = &sorted_searchtitles(); 1802: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 1803: 1804: my $numinrow = 4; 1805: my $cansrchrow = 0; 1806: my $datatable='<tr class="LC_odd_row">'. 1807: '<td colspan="2"><span class ="LC_nobreak">'.&mt('Directory search available?').'</span></td>'. 1808: '<td class="LC_right_item"><span class="LC_nobreak"><label>'. 1809: '<input type="radio" name="dirsrch_available"'. 1810: $srchon.' value="1" />'.&mt('Yes').'</label> '. 1811: '<label><input type="radio" name="dirsrch_available"'. 1812: $srchoff.' value="0" />'.&mt('No').'</label></span></td>'. 1813: '</tr><tr>'. 1814: '<td colspan="2"><span class ="LC_nobreak">'.&mt('Other domains can search?').'</span></td>'. 1815: '<td class="LC_right_item"><span class="LC_nobreak"><label>'. 1816: '<input type="radio" name="dirsrch_localonly"'. 1817: $localoff.' value="0" />'.&mt('Yes').'</label> '. 1818: '<label><input type="radio" name="dirsrch_localonly"'. 1819: $localon.' value="1" />'.&mt('No').'</label></span></td>'. 1820: '</tr>'; 1821: $$rowtotal += 2; 1822: if (ref($usertypes) eq 'HASH') { 1823: if (keys(%{$usertypes}) > 0) { 1824: $datatable .= &insttypes_row($settings,$types,$usertypes,$dom, 1825: $numinrow,$othertitle,'cansearch'); 1826: $cansrchrow = 1; 1827: } 1828: } 1829: if ($cansrchrow) { 1830: $$rowtotal ++; 1831: $datatable .= '<tr>'; 1832: } else { 1833: $datatable .= '<tr class="LC_odd_row">'; 1834: } 1835: $datatable .= '<td><span class ="LC_nobreak">'.&mt('Supported search methods'). 1836: '</span></td><td class="LC_left_item" colspan="2"><table><tr>'; 1837: foreach my $title (@{$titleorder}) { 1838: if (defined($searchtitles->{$title})) { 1839: my $check = ' '; 1840: if (ref($settings) eq 'HASH') { 1841: if (ref($settings->{'searchby'}) eq 'ARRAY') { 1842: if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) { 1843: $check = ' checked="checked" '; 1844: } 1845: } 1846: } 1847: $datatable .= '<td class="LC_left_item">'. 1848: '<span class="LC_nobreak"><label>'. 1849: '<input type="checkbox" name="searchby" '. 1850: 'value="'.$title.'"'.$check.'/>'. 1851: $searchtitles->{$title}.'</label></span></td>'; 1852: } 1853: } 1854: $datatable .= '</tr></table></td></tr>'; 1855: $$rowtotal ++; 1856: if ($cansrchrow) { 1857: $datatable .= '<tr class="LC_odd_row">'; 1858: } else { 1859: $datatable .= '<tr>'; 1860: } 1861: $datatable .= '<td><span class ="LC_nobreak">'.&mt('Search latitude').'</span></td>'. 1862: '<td class="LC_left_item" colspan="2">'. 1863: '<span class="LC_nobreak"><label>'. 1864: '<input type="checkbox" name="searchtypes" '. 1865: $exacton.' value="exact" />'.&mt('Exact match'). 1866: '</label> '. 1867: '<label><input type="checkbox" name="searchtypes" '. 1868: $beginson.' value="begins" />'.&mt('Begins with'). 1869: '</label> '. 1870: '<label><input type="checkbox" name="searchtypes" '. 1871: $containson.' value="contains" />'.&mt('Contains'). 1872: '</label></span></td></tr>'; 1873: $$rowtotal ++; 1874: return $datatable; 1875: } 1876: 1877: sub print_contacts { 1878: my ($dom,$settings,$rowtotal) = @_; 1879: my $datatable; 1880: my @contacts = ('adminemail','supportemail'); 1881: my (%checked,%to,%otheremails); 1882: my @mailings = ('errormail','packagesmail','lonstatusmail','helpdeskmail', 1883: 'requestsmail'); 1884: foreach my $type (@mailings) { 1885: $otheremails{$type} = ''; 1886: } 1887: if (ref($settings) eq 'HASH') { 1888: foreach my $item (@contacts) { 1889: if (exists($settings->{$item})) { 1890: $to{$item} = $settings->{$item}; 1891: } 1892: } 1893: foreach my $type (@mailings) { 1894: if (exists($settings->{$type})) { 1895: if (ref($settings->{$type}) eq 'HASH') { 1896: foreach my $item (@contacts) { 1897: if ($settings->{$type}{$item}) { 1898: $checked{$type}{$item} = ' checked="checked" '; 1899: } 1900: } 1901: $otheremails{$type} = $settings->{$type}{'others'}; 1902: } 1903: } elsif ($type eq 'lonstatusmail') { 1904: $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; 1905: } 1906: } 1907: } else { 1908: $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'}; 1909: $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'}; 1910: $checked{'errormail'}{'adminemail'} = ' checked="checked" '; 1911: $checked{'packagesmail'}{'adminemail'} = ' checked="checked" '; 1912: $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" '; 1913: $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" '; 1914: $checked{'requestsmail'}{'adminemail'} = ' checked="checked" '; 1915: } 1916: my ($titles,$short_titles) = &contact_titles(); 1917: my $rownum = 0; 1918: my $css_class; 1919: foreach my $item (@contacts) { 1920: $rownum ++; 1921: $css_class = $rownum%2?' class="LC_odd_row"':''; 1922: $datatable .= '<tr'.$css_class.'>'. 1923: '<td><span class="LC_nobreak">'.$titles->{$item}. 1924: '</span></td><td class="LC_right_item">'. 1925: '<input type="text" name="'.$item.'" value="'. 1926: $to{$item}.'" /></td></tr>'; 1927: } 1928: foreach my $type (@mailings) { 1929: $rownum ++; 1930: $css_class = $rownum%2?' class="LC_odd_row"':''; 1931: $datatable .= '<tr'.$css_class.'>'. 1932: '<td><span class="LC_nobreak">'. 1933: $titles->{$type}.': </span></td>'. 1934: '<td class="LC_left_item">'. 1935: '<span class="LC_nobreak">'; 1936: foreach my $item (@contacts) { 1937: $datatable .= '<label>'. 1938: '<input type="checkbox" name="'.$type.'"'. 1939: $checked{$type}{$item}. 1940: ' value="'.$item.'" />'.$short_titles->{$item}. 1941: '</label> '; 1942: } 1943: $datatable .= '</span><br />'.&mt('Others').': '. 1944: '<input type="text" name="'.$type.'_others" '. 1945: 'value="'.$otheremails{$type}.'" />'. 1946: '</td></tr>'."\n"; 1947: } 1948: $$rowtotal += $rownum; 1949: return $datatable; 1950: } 1951: 1952: sub print_helpsettings { 1953: 1954: my ($position,$dom,$confname,$settings,$rowtotal) = @_; 1955: my ($css_class,$datatable); 1956: 1957: my $switchserver = &check_switchserver($dom,$confname); 1958: 1959: my $itemcount = 1; 1960: 1961: if ($position eq 'top') { 1962: 1963: my (%checkedon,%checkedoff,%choices,%defaultchecked,@toggles); 1964: 1965: %choices = 1966: &Apache::lonlocal::texthash ( 1967: submitbugs => 'Display "Submit a bug" link?', 1968: ); 1969: 1970: %defaultchecked = ('submitbugs' => 'on'); 1971: 1972: @toggles = ('submitbugs',); 1973: 1974: foreach my $item (@toggles) { 1975: if ($defaultchecked{$item} eq 'on') { 1976: $checkedon{$item} = ' checked="checked" '; 1977: $checkedoff{$item} = ' '; 1978: } elsif ($defaultchecked{$item} eq 'off') { 1979: $checkedoff{$item} = ' checked="checked" '; 1980: $checkedon{$item} = ' '; 1981: } 1982: } 1983: 1984: if (ref($settings) eq 'HASH') { 1985: foreach my $item (@toggles) { 1986: if ($settings->{$item} eq '1') { 1987: $checkedon{$item} = ' checked="checked" '; 1988: $checkedoff{$item} = ' '; 1989: } elsif ($settings->{$item} eq '0') { 1990: $checkedoff{$item} = ' checked="checked" '; 1991: $checkedon{$item} = ' '; 1992: } 1993: } 1994: } 1995: 1996: foreach my $item (@toggles) { 1997: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; 1998: $datatable .= 1999: '<tr'.$css_class.'> 2000: <td><span class="LC_nobreak">'.$choices{$item}.'</span></td> 2001: <td><span class="LC_nobreak"> </span></td> 2002: <td class="LC_right_item"><span class="LC_nobreak"> 2003: <label><input type="radio" name="'.$item.'" '.$checkedon{$item}.' value="1" />'.&mt('Yes').'</label> 2004: <label><input type="radio" name="'.$item.'" '.$checkedoff{$item}.' value="0" />'.&mt('No').'</label>'. 2005: '</span></td>'. 2006: '</tr>'; 2007: $itemcount ++; 2008: } 2009: 2010: } else { 2011: 2012: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; 2013: 2014: $datatable .= '<tr'.$css_class.'>'; 2015: 2016: if (ref($settings) eq 'HASH') { 2017: if ($settings->{'loginhelpurl'} ne '') { 2018: my($directory, $filename) = $settings->{'loginhelpurl'} =~ m/(.*\/)(.*)$/; 2019: $datatable .= '<td width="33%"><span class="LC_left_item"><label><a href="'.$settings->{'loginhelpurl'}.'" target="_blank">'.&mt('Custom Login Page Help File In Use').'</a></label></span></td>'; 2020: $datatable .= '<td width="33%"><span class="LC_right_item"><label><input type="checkbox" name="loginhelpurl_del" value="1" />'.&mt('Delete?').'</label></span></td>' 2021: } else { 2022: $datatable .= '<td width="33%"><span class="LC_left_item"><label>'.&mt('Default Login Page Help File In Use').'</label></span></td>'; 2023: $datatable .= '<td width="33%"><span class="LC_right_item"> </span></td>'; 2024: } 2025: } else { 2026: $datatable .= '<td><span class="LC_left_item"> </span></td>'; 2027: $datatable .= '<td><span class="LC_right_item"> </span></td>'; 2028: } 2029: 2030: $datatable .= '<td width="33%"><span class="LC_right_item">'; 2031: if ($switchserver) { 2032: $datatable .= &mt('Upload to library server: [_1]',$switchserver); 2033: } else { 2034: $datatable .= &mt('Upload Custom Login Page Help File:'); 2035: $datatable .='<input type="file" name="loginhelpurl" />'; 2036: } 2037: $datatable .= '</span></td></tr>'; 2038: 2039: } 2040: 2041: return $datatable; 2042: 2043: } 2044: 2045: 2046: sub radiobutton_prefs { 2047: my ($settings,$toggles,$defaultchecked,$choices,$itemcount) = @_; 2048: return unless ((ref($toggles) eq 'ARRAY') && (ref($defaultchecked) eq 'HASH') && 2049: (ref($choices) eq 'HASH')); 2050: 2051: my (%checkedon,%checkedoff,$datatable,$css_class); 2052: 2053: foreach my $item (@{$toggles}) { 2054: if ($defaultchecked->{$item} eq 'on') { 2055: $checkedon{$item} = ' checked="checked" '; 2056: $checkedoff{$item} = ' '; 2057: } elsif ($defaultchecked->{$item} eq 'off') { 2058: $checkedoff{$item} = ' checked="checked" '; 2059: $checkedon{$item} = ' '; 2060: } 2061: } 2062: if (ref($settings) eq 'HASH') { 2063: foreach my $item (@{$toggles}) { 2064: if ($settings->{$item} eq '1') { 2065: $checkedon{$item} = ' checked="checked" '; 2066: $checkedoff{$item} = ' '; 2067: } elsif ($settings->{$item} eq '0') { 2068: $checkedoff{$item} = ' checked="checked" '; 2069: $checkedon{$item} = ' '; 2070: } 2071: } 2072: } 2073: foreach my $item (@{$toggles}) { 2074: $css_class = $itemcount%2?' class="LC_odd_row"':''; 2075: $datatable .= 2076: '<tr'.$css_class.'><td><span class="LC_nobreak">'.$choices->{$item}. 2077: '</span></td>'. 2078: '<td class="LC_right_item"><span class="LC_nobreak">'. 2079: '<label><input type="radio" name="'. 2080: $item.'" '.$checkedon{$item}.' value="1" />'.&mt('Yes'). 2081: '</label> <label><input type="radio" name="'.$item.'" '. 2082: $checkedoff{$item}.' value="0" />'.&mt('No').'</label>'. 2083: '</span></td>'. 2084: '</tr>'; 2085: $itemcount ++; 2086: } 2087: return ($datatable,$itemcount); 2088: } 2089: 2090: sub print_coursedefaults { 2091: my ($dom,$settings,$rowtotal) = @_; 2092: my ($css_class,$datatable); 2093: my $itemcount = 1; 2094: my (%checkedon,%checkedoff,%choices,%defaultchecked,@toggles); 2095: $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; 2096: my %choices = 2097: &Apache::lonlocal::texthash ( 2098: anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys', 2099: ); 2100: my $currdefresponder; 2101: if (ref($settings) eq 'HASH') { 2102: $currdefresponder = $settings->{'anonsurvey_threshold'}; 2103: } 2104: if (!$currdefresponder) { 2105: $currdefresponder = 10; 2106: } elsif ($currdefresponder < 1) { 2107: $currdefresponder = 1; 2108: } 2109: $datatable .= 2110: '<tr'.$css_class.'><td><span class="LC_nobreak">'.$choices{'anonsurvey_threshold'}. 2111: '</span></td>'. 2112: '<td class="LC_right_item"><span class="LC_nobreak">'. 2113: '<input type="text" name="anonsurvey_threshold"'. 2114: ' value="'.$currdefresponder.'" size="5" /></span>'. 2115: '</td></tr>'; 2116: $$rowtotal += $itemcount; 2117: return $datatable; 2118: } 2119: 2120: sub contact_titles { 2121: my %titles = &Apache::lonlocal::texthash ( 2122: 'supportemail' => 'Support E-mail address', 2123: 'adminemail' => 'Default Server Admin E-mail address', 2124: 'errormail' => 'Error reports to be e-mailed to', 2125: 'packagesmail' => 'Package update alerts to be e-mailed to', 2126: 'helpdeskmail' => 'Helpdesk requests to be e-mailed to', 2127: 'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)', 2128: 'requestsmail' => 'E-mail from course requests requiring approval', 2129: ); 2130: my %short_titles = &Apache::lonlocal::texthash ( 2131: adminemail => 'Admin E-mail address', 2132: supportemail => 'Support E-mail', 2133: ); 2134: return (\%titles,\%short_titles); 2135: } 2136: 2137: sub tool_titles { 2138: my %titles = &Apache::lonlocal::texthash ( 2139: aboutme => 'Personal Information Page', 2140: blog => 'Blog', 2141: portfolio => 'Portfolio', 2142: official => 'Official courses (with institutional codes)', 2143: unofficial => 'Unofficial courses', 2144: community => 'Communities', 2145: ); 2146: return %titles; 2147: } 2148: 2149: sub courserequest_titles { 2150: my %titles = &Apache::lonlocal::texthash ( 2151: official => 'Official', 2152: unofficial => 'Unofficial', 2153: community => 'Communities', 2154: norequest => 'Not allowed', 2155: approval => 'Approval by Dom. Coord.', 2156: validate => 'With validation', 2157: autolimit => 'Numerical limit', 2158: unlimited => '(blank for unlimited)', 2159: ); 2160: return %titles; 2161: } 2162: 2163: sub courserequest_conditions { 2164: my %conditions = &Apache::lonlocal::texthash ( 2165: approval => '(Processing of request subject to approval by Domain Coordinator).', 2166: validate => '(Processing of request subject to instittutional validation).', 2167: ); 2168: return %conditions; 2169: } 2170: 2171: 2172: sub print_usercreation { 2173: my ($position,$dom,$settings,$rowtotal) = @_; 2174: my $numinrow = 4; 2175: my $datatable; 2176: if ($position eq 'top') { 2177: $$rowtotal ++; 2178: my $rowcount = 0; 2179: my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($dom,'username'); 2180: if (ref($rules) eq 'HASH') { 2181: if (keys(%{$rules}) > 0) { 2182: $datatable .= &user_formats_row('username',$settings,$rules, 2183: $ruleorder,$numinrow,$rowcount); 2184: $$rowtotal ++; 2185: $rowcount ++; 2186: } 2187: } 2188: my ($idrules,$idruleorder) = &Apache::lonnet::inst_userrules($dom,'id'); 2189: if (ref($idrules) eq 'HASH') { 2190: if (keys(%{$idrules}) > 0) { 2191: $datatable .= &user_formats_row('id',$settings,$idrules, 2192: $idruleorder,$numinrow,$rowcount); 2193: $$rowtotal ++; 2194: $rowcount ++; 2195: } 2196: } 2197: my ($emailrules,$emailruleorder) = 2198: &Apache::lonnet::inst_userrules($dom,'email'); 2199: if (ref($emailrules) eq 'HASH') { 2200: if (keys(%{$emailrules}) > 0) { 2201: $datatable .= &user_formats_row('email',$settings,$emailrules, 2202: $emailruleorder,$numinrow,$rowcount); 2203: $$rowtotal ++; 2204: $rowcount ++; 2205: } 2206: } 2207: if ($rowcount == 0) { 2208: $datatable .= '<tr><td colspan="2">'.&mt('No format rules have been defined for usernames or IDs in this domain.').'</td></tr>'; 2209: $$rowtotal ++; 2210: $rowcount ++; 2211: } 2212: } elsif ($position eq 'middle') { 2213: my @creators = ('author','course','requestcrs','selfcreate'); 2214: my ($rules,$ruleorder) = 2215: &Apache::lonnet::inst_userrules($dom,'username'); 2216: my %lt = &usercreation_types(); 2217: my %checked; 2218: my @selfcreate; 2219: if (ref($settings) eq 'HASH') { 2220: if (ref($settings->{'cancreate'}) eq 'HASH') { 2221: foreach my $item (@creators) { 2222: $checked{$item} = $settings->{'cancreate'}{$item}; 2223: } 2224: if (ref($settings->{'cancreate'}{'selfcreate'}) eq 'ARRAY') { 2225: @selfcreate = @{$settings->{'cancreate'}{'selfcreate'}}; 2226: } elsif ($settings->{'cancreate'}{'selfcreate'} ne '') { 2227: if ($settings->{'cancreate'}{'selfcreate'} eq 'any') { 2228: @selfcreate = ('email','login','sso'); 2229: } elsif ($settings->{'cancreate'}{'selfcreate'} ne 'none') { 2230: @selfcreate = ($settings->{'cancreate'}{'selfcreate'}); 2231: } 2232: } 2233: } elsif (ref($settings->{'cancreate'}) eq 'ARRAY') { 2234: foreach my $item (@creators) { 2235: if (grep(/^\Q$item\E$/,@{$settings->{'cancreate'}})) { 2236: $checked{$item} = 'none'; 2237: } 2238: } 2239: } 2240: } 2241: my $rownum = 0; 2242: foreach my $item (@creators) { 2243: $rownum ++; 2244: if ($item ne 'selfcreate') { 2245: if ($checked{$item} eq '') { 2246: $checked{$item} = 'any'; 2247: } 2248: } 2249: my $css_class; 2250: if ($rownum%2) { 2251: $css_class = ''; 2252: } else { 2253: $css_class = ' class="LC_odd_row" '; 2254: } 2255: $datatable .= '<tr'.$css_class.'>'. 2256: '<td><span class="LC_nobreak">'.$lt{$item}. 2257: '</span></td><td align="right">'; 2258: my @options; 2259: if ($item eq 'selfcreate') { 2260: push(@options,('email','login','sso')); 2261: } else { 2262: @options = ('any'); 2263: if (ref($rules) eq 'HASH') { 2264: if (keys(%{$rules}) > 0) { 2265: push(@options,('official','unofficial')); 2266: } 2267: } 2268: push(@options,'none'); 2269: } 2270: foreach my $option (@options) { 2271: my $type = 'radio'; 2272: my $check = ' '; 2273: if ($item eq 'selfcreate') { 2274: $type = 'checkbox'; 2275: if (grep(/^\Q$option\E$/,@selfcreate)) { 2276: $check = ' checked="checked" '; 2277: } 2278: } else { 2279: if ($checked{$item} eq $option) { 2280: $check = ' checked="checked" '; 2281: } 2282: } 2283: $datatable .= '<span class="LC_nobreak"><label>'. 2284: '<input type="'.$type.'" name="can_createuser_'. 2285: $item.'" value="'.$option.'"'.$check.'/> '. 2286: $lt{$option}.'</label> </span>'; 2287: } 2288: $datatable .= '</td></tr>'; 2289: } 2290: my ($othertitle,$usertypes,$types) = 2291: &Apache::loncommon::sorted_inst_types($dom); 2292: if (ref($usertypes) eq 'HASH') { 2293: if (keys(%{$usertypes}) > 0) { 2294: my $createsettings; 2295: if (ref($settings) eq 'HASH') { 2296: $createsettings = $settings->{cancreate}; 2297: } 2298: $datatable .= &insttypes_row($createsettings,$types,$usertypes, 2299: $dom,$numinrow,$othertitle, 2300: 'statustocreate'); 2301: $$rowtotal ++; 2302: } 2303: } 2304: } else { 2305: my @contexts = ('author','course','domain'); 2306: my @authtypes = ('int','krb4','krb5','loc'); 2307: my %checked; 2308: if (ref($settings) eq 'HASH') { 2309: if (ref($settings->{'authtypes'}) eq 'HASH') { 2310: foreach my $item (@contexts) { 2311: if (ref($settings->{'authtypes'}{$item}) eq 'HASH') { 2312: foreach my $auth (@authtypes) { 2313: if ($settings->{'authtypes'}{$item}{$auth}) { 2314: $checked{$item}{$auth} = ' checked="checked" '; 2315: } 2316: } 2317: } 2318: } 2319: } 2320: } else { 2321: foreach my $item (@contexts) { 2322: foreach my $auth (@authtypes) { 2323: $checked{$item}{$auth} = ' checked="checked" '; 2324: } 2325: } 2326: } 2327: my %title = &context_names(); 2328: my %authname = &authtype_names(); 2329: my $rownum = 0; 2330: my $css_class; 2331: foreach my $item (@contexts) { 2332: if ($rownum%2) { 2333: $css_class = ''; 2334: } else { 2335: $css_class = ' class="LC_odd_row" '; 2336: } 2337: $datatable .= '<tr'.$css_class.'>'. 2338: '<td>'.$title{$item}. 2339: '</td><td class="LC_left_item">'. 2340: '<span class="LC_nobreak">'; 2341: foreach my $auth (@authtypes) { 2342: $datatable .= '<label>'. 2343: '<input type="checkbox" name="'.$item.'_auth" '. 2344: $checked{$item}{$auth}.' value="'.$auth.'" />'. 2345: $authname{$auth}.'</label> '; 2346: } 2347: $datatable .= '</span></td></tr>'; 2348: $rownum ++; 2349: } 2350: $$rowtotal += $rownum; 2351: } 2352: return $datatable; 2353: } 2354: 2355: sub user_formats_row { 2356: my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount) = @_; 2357: my $output; 2358: my %text = ( 2359: 'username' => 'new usernames', 2360: 'id' => 'IDs', 2361: 'email' => 'self-created accounts (e-mail)', 2362: ); 2363: my $css_class = $rowcount%2?' class="LC_odd_row"':''; 2364: $output = '<tr '.$css_class.'>'. 2365: '<td><span class="LC_nobreak">'; 2366: if ($type eq 'email') { 2367: $output .= &mt("Formats disallowed for $text{$type}: "); 2368: } else { 2369: $output .= &mt("Format rules to check for $text{$type}: "); 2370: } 2371: $output .= '</span></td>'. 2372: '<td class="LC_left_item" colspan="2"><table>'; 2373: my $rem; 2374: if (ref($ruleorder) eq 'ARRAY') { 2375: for (my $i=0; $i<@{$ruleorder}; $i++) { 2376: if (ref($rules->{$ruleorder->[$i]}) eq 'HASH') { 2377: my $rem = $i%($numinrow); 2378: if ($rem == 0) { 2379: if ($i > 0) { 2380: $output .= '</tr>'; 2381: } 2382: $output .= '<tr>'; 2383: } 2384: my $check = ' '; 2385: if (ref($settings) eq 'HASH') { 2386: if (ref($settings->{$type.'_rule'}) eq 'ARRAY') { 2387: if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) { 2388: $check = ' checked="checked" '; 2389: } 2390: } 2391: } 2392: $output .= '<td class="LC_left_item">'. 2393: '<span class="LC_nobreak"><label>'. 2394: '<input type="checkbox" name="'.$type.'_rule" '. 2395: 'value="'.$ruleorder->[$i].'"'.$check.'/>'. 2396: $rules->{$ruleorder->[$i]}{'name'}.'</label></span></td>'; 2397: } 2398: } 2399: $rem = @{$ruleorder}%($numinrow); 2400: } 2401: my $colsleft = $numinrow - $rem; 2402: if ($colsleft > 1 ) { 2403: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'. 2404: ' </td>'; 2405: } elsif ($colsleft == 1) { 2406: $output .= '<td class="LC_left_item"> </td>'; 2407: } 2408: $output .= '</tr></table></td></tr>'; 2409: return $output; 2410: } 2411: 2412: sub usercreation_types { 2413: my %lt = &Apache::lonlocal::texthash ( 2414: author => 'When adding a co-author', 2415: course => 'When adding a user to a course', 2416: requestcrs => 'When requesting a course', 2417: selfcreate => 'User creates own account', 2418: any => 'Any', 2419: official => 'Institutional only ', 2420: unofficial => 'Non-institutional only', 2421: email => 'E-mail address', 2422: login => 'Institutional Login', 2423: sso => 'SSO', 2424: none => 'None', 2425: ); 2426: return %lt; 2427: } 2428: 2429: sub authtype_names { 2430: my %lt = &Apache::lonlocal::texthash( 2431: int => 'Internal', 2432: krb4 => 'Kerberos 4', 2433: krb5 => 'Kerberos 5', 2434: loc => 'Local', 2435: ); 2436: return %lt; 2437: } 2438: 2439: sub context_names { 2440: my %context_title = &Apache::lonlocal::texthash( 2441: author => 'Creating users when an Author', 2442: course => 'Creating users when in a course', 2443: domain => 'Creating users when a Domain Coordinator', 2444: ); 2445: return %context_title; 2446: } 2447: 2448: sub print_usermodification { 2449: my ($position,$dom,$settings,$rowtotal) = @_; 2450: my $numinrow = 4; 2451: my ($context,$datatable,$rowcount); 2452: if ($position eq 'top') { 2453: $rowcount = 0; 2454: $context = 'author'; 2455: foreach my $role ('ca','aa') { 2456: $datatable .= &modifiable_userdata_row($context,$role,$settings, 2457: $numinrow,$rowcount); 2458: $$rowtotal ++; 2459: $rowcount ++; 2460: } 2461: } elsif ($position eq 'middle') { 2462: $context = 'course'; 2463: $rowcount = 0; 2464: foreach my $role ('st','ep','ta','in','cr') { 2465: $datatable .= &modifiable_userdata_row($context,$role,$settings, 2466: $numinrow,$rowcount); 2467: $$rowtotal ++; 2468: $rowcount ++; 2469: } 2470: } elsif ($position eq 'bottom') { 2471: $context = 'selfcreate'; 2472: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 2473: $usertypes->{'default'} = $othertitle; 2474: if (ref($types) eq 'ARRAY') { 2475: push(@{$types},'default'); 2476: $usertypes->{'default'} = $othertitle; 2477: foreach my $status (@{$types}) { 2478: $datatable .= &modifiable_userdata_row($context,$status,$settings, 2479: $numinrow,$rowcount,$usertypes); 2480: $$rowtotal ++; 2481: $rowcount ++; 2482: } 2483: } 2484: } 2485: return $datatable; 2486: } 2487: 2488: sub print_defaults { 2489: my ($dom,$rowtotal) = @_; 2490: my @items = ('auth_def','auth_arg_def','lang_def','timezone_def', 2491: 'datelocale_def','portal_def'); 2492: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 2493: my $titles = &defaults_titles($dom); 2494: my $rownum = 0; 2495: my ($datatable,$css_class); 2496: foreach my $item (@items) { 2497: if ($rownum%2) { 2498: $css_class = ''; 2499: } else { 2500: $css_class = ' class="LC_odd_row" '; 2501: } 2502: $datatable .= '<tr'.$css_class.'>'. 2503: '<td><span class="LC_nobreak">'.$titles->{$item}. 2504: '</span></td><td class="LC_right_item">'; 2505: if ($item eq 'auth_def') { 2506: my @authtypes = ('internal','krb4','krb5','localauth'); 2507: my %shortauth = ( 2508: internal => 'int', 2509: krb4 => 'krb4', 2510: krb5 => 'krb5', 2511: localauth => 'loc' 2512: ); 2513: my %authnames = &authtype_names(); 2514: foreach my $auth (@authtypes) { 2515: my $checked = ' '; 2516: if ($domdefaults{$item} eq $auth) { 2517: $checked = ' checked="checked" '; 2518: } 2519: $datatable .= '<label><input type="radio" name="'.$item. 2520: '" value="'.$auth.'"'.$checked.'/>'. 2521: $authnames{$shortauth{$auth}}.'</label> '; 2522: } 2523: } elsif ($item eq 'timezone_def') { 2524: my $includeempty = 1; 2525: $datatable .= &Apache::loncommon::select_timezone($item,$domdefaults{$item},undef,$includeempty); 2526: } elsif ($item eq 'datelocale_def') { 2527: my $includeempty = 1; 2528: $datatable .= &Apache::loncommon::select_datelocale($item,$domdefaults{$item},undef,$includeempty); 2529: } else { 2530: my $size; 2531: if ($item eq 'portal_def') { 2532: $size = ' size="25"'; 2533: } 2534: $datatable .= '<input type="text" name="'.$item.'" value="'. 2535: $domdefaults{$item}.'"'.$size.' />'; 2536: } 2537: $datatable .= '</td></tr>'; 2538: $rownum ++; 2539: } 2540: $$rowtotal += $rownum; 2541: return $datatable; 2542: } 2543: 2544: sub defaults_titles { 2545: my ($dom) = @_; 2546: my %titles = &Apache::lonlocal::texthash ( 2547: 'auth_def' => 'Default authentication type', 2548: 'auth_arg_def' => 'Default authentication argument', 2549: 'lang_def' => 'Default language', 2550: 'timezone_def' => 'Default timezone', 2551: 'datelocale_def' => 'Default locale for dates', 2552: 'portal_def' => 'Portal/Default URL', 2553: ); 2554: if ($dom) { 2555: my $uprimary_id = &Apache::lonnet::domain($dom,'primary'); 2556: my $uint_dom = &Apache::lonnet::internet_dom($uprimary_id); 2557: my $protocol = $Apache::lonnet::protocol{$uprimary_id}; 2558: $protocol = 'http' if ($protocol ne 'https'); 2559: if ($uint_dom) { 2560: $titles{'portal_def'} .= ' '.&mt('(for example: [_1])',$protocol.'://loncapa.'. 2561: $uint_dom); 2562: } 2563: } 2564: return (\%titles); 2565: } 2566: 2567: sub print_scantronformat { 2568: my ($r,$dom,$confname,$settings,$rowtotal) = @_; 2569: my $itemcount = 1; 2570: my ($datatable,$css_class,$scantronurl,$is_custom,%error,%scantronurls, 2571: %confhash); 2572: my $switchserver = &check_switchserver($dom,$confname); 2573: my %lt = &Apache::lonlocal::texthash ( 2574: default => 'Default bubblesheet format file error', 2575: custom => 'Custom bubblesheet format file error', 2576: ); 2577: my %scantronfiles = ( 2578: default => 'default.tab', 2579: custom => 'custom.tab', 2580: ); 2581: foreach my $key (keys(%scantronfiles)) { 2582: $scantronurls{$key} = '/res/'.$dom.'/'.$confname.'/scantron/' 2583: .$scantronfiles{$key}; 2584: } 2585: my @defaultinfo = &Apache::lonnet::stat_file($scantronurls{'default'}); 2586: if ((!@defaultinfo) || ($defaultinfo[0] eq 'no_such_dir')) { 2587: if (!$switchserver) { 2588: my $servadm = $r->dir_config('lonAdmEMail'); 2589: my ($configuserok,$author_ok) = &config_check($dom,$confname,$servadm); 2590: if ($configuserok eq 'ok') { 2591: if ($author_ok eq 'ok') { 2592: my %legacyfile = ( 2593: default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab', 2594: custom => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab', 2595: ); 2596: my %md5chk; 2597: foreach my $type (keys(%legacyfile)) { 2598: ($md5chk{$type}) = split(/ /,`md5sum $legacyfile{$type}`); 2599: chomp($md5chk{$type}); 2600: } 2601: if ($md5chk{'default'} ne $md5chk{'custom'}) { 2602: foreach my $type (keys(%legacyfile)) { 2603: ($scantronurls{$type},my $error) = 2604: &legacy_scantronformat($r,$dom,$confname, 2605: $type,$legacyfile{$type}, 2606: $scantronurls{$type}, 2607: $scantronfiles{$type}); 2608: if ($error ne '') { 2609: $error{$type} = $error; 2610: } 2611: } 2612: if (keys(%error) == 0) { 2613: $is_custom = 1; 2614: $confhash{'scantron'}{'scantronformat'} = 2615: $scantronurls{'custom'}; 2616: my $putresult = 2617: &Apache::lonnet::put_dom('configuration', 2618: \%confhash,$dom); 2619: if ($putresult ne 'ok') { 2620: $error{'custom'} = 2621: '<span class="LC_error">'. 2622: &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>'; 2623: } 2624: } 2625: } else { 2626: ($scantronurls{'default'},my $error) = 2627: &legacy_scantronformat($r,$dom,$confname, 2628: 'default',$legacyfile{'default'}, 2629: $scantronurls{'default'}, 2630: $scantronfiles{'default'}); 2631: if ($error eq '') { 2632: $confhash{'scantron'}{'scantronformat'} = ''; 2633: my $putresult = 2634: &Apache::lonnet::put_dom('configuration', 2635: \%confhash,$dom); 2636: if ($putresult ne 'ok') { 2637: $error{'default'} = 2638: '<span class="LC_error">'. 2639: &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>'; 2640: } 2641: } else { 2642: $error{'default'} = $error; 2643: } 2644: } 2645: } 2646: } 2647: } else { 2648: $error{'default'} = &mt("Unable to copy default bubblesheet formatfile to domain's RES space: [_1]",$switchserver); 2649: } 2650: } 2651: if (ref($settings) eq 'HASH') { 2652: if ($settings->{'scantronformat'} eq "/res/$dom/$confname/scantron/custom.tab") { 2653: my @info = &Apache::lonnet::stat_file($settings->{'scantronformat'}); 2654: if ((!@info) || ($info[0] eq 'no_such_dir')) { 2655: $scantronurl = ''; 2656: } else { 2657: $scantronurl = $settings->{'scantronformat'}; 2658: } 2659: $is_custom = 1; 2660: } else { 2661: $scantronurl = $scantronurls{'default'}; 2662: } 2663: } else { 2664: if ($is_custom) { 2665: $scantronurl = $scantronurls{'custom'}; 2666: } else { 2667: $scantronurl = $scantronurls{'default'}; 2668: } 2669: } 2670: $css_class = $itemcount%2?' class="LC_odd_row"':''; 2671: $datatable .= '<tr'.$css_class.'>'; 2672: if (!$is_custom) { 2673: $datatable .= '<td>'.&mt('Default in use:').'<br />'. 2674: '<span class="LC_nobreak">'; 2675: if ($scantronurl) { 2676: $datatable .= '<a href="'.$scantronurl.'" target="_blank">'. 2677: &mt('Default scantron format file').'</a>'; 2678: } else { 2679: $datatable = &mt('File unavailable for display'); 2680: } 2681: $datatable .= '</span></td>'; 2682: if (keys(%error) == 0) { 2683: $datatable .= '<td valign="bottom">'; 2684: if (!$switchserver) { 2685: $datatable .= &mt('Upload:').'<br />'; 2686: } 2687: } else { 2688: my $errorstr; 2689: foreach my $key (sort(keys(%error))) { 2690: $errorstr .= $lt{$key}.': '.$error{$key}.'<br />'; 2691: } 2692: $datatable .= '<td>'.$errorstr; 2693: } 2694: } else { 2695: if (keys(%error) > 0) { 2696: my $errorstr; 2697: foreach my $key (sort(keys(%error))) { 2698: $errorstr .= $lt{$key}.': '.$error{$key}.'<br />'; 2699: } 2700: $datatable .= '<td>'.$errorstr.'</td><td> '; 2701: } elsif ($scantronurl) { 2702: $datatable .= '<td><span class="LC_nobreak">'. 2703: '<a href="'.$scantronurl.'" target="_blank">'. 2704: &mt('Custom scantron format file').'</a><label>'. 2705: '<input type="checkbox" name="scantronformat_del"'. 2706: '" value="1" />'.&mt('Delete?').'</label></span></td>'. 2707: '<td><span class="LC_nobreak"> '. 2708: &mt('Replace:').'</span><br />'; 2709: } 2710: } 2711: if (keys(%error) == 0) { 2712: if ($switchserver) { 2713: $datatable .= &mt('Upload to library server: [_1]',$switchserver); 2714: } else { 2715: $datatable .='<span class="LC_nobreak"> '. 2716: '<input type="file" name="scantronformat" /></span>'; 2717: } 2718: } 2719: $datatable .= '</td></tr>'; 2720: $$rowtotal ++; 2721: return $datatable; 2722: } 2723: 2724: sub legacy_scantronformat { 2725: my ($r,$dom,$confname,$file,$legacyfile,$newurl,$newfile) = @_; 2726: my ($url,$error); 2727: my @statinfo = &Apache::lonnet::stat_file($newurl); 2728: if ((!@statinfo) || ($statinfo[0] eq 'no_such_dir')) { 2729: (my $result,$url) = 2730: &publishlogo($r,'copy',$legacyfile,$dom,$confname,'scantron', 2731: '','',$newfile); 2732: if ($result ne 'ok') { 2733: $error = &mt("An error occurred publishing the [_1] scantron format file in RES space. Error was: [_2].",$newfile,$result); 2734: } 2735: } 2736: return ($url,$error); 2737: } 2738: 2739: sub print_coursecategories { 2740: my ($position,$dom,$hdritem,$settings,$rowtotal) = @_; 2741: my $datatable; 2742: if ($position eq 'top') { 2743: my $toggle_cats_crs = ' '; 2744: my $toggle_cats_dom = ' checked="checked" '; 2745: my $can_cat_crs = ' '; 2746: my $can_cat_dom = ' checked="checked" '; 2747: my $toggle_catscomm_comm = ' '; 2748: my $toggle_catscomm_dom = ' checked="checked" '; 2749: my $can_catcomm_comm = ' '; 2750: my $can_catcomm_dom = ' checked="checked" '; 2751: 2752: if (ref($settings) eq 'HASH') { 2753: if ($settings->{'togglecats'} eq 'crs') { 2754: $toggle_cats_crs = $toggle_cats_dom; 2755: $toggle_cats_dom = ' '; 2756: } 2757: if ($settings->{'categorize'} eq 'crs') { 2758: $can_cat_crs = $can_cat_dom; 2759: $can_cat_dom = ' '; 2760: } 2761: if ($settings->{'togglecatscomm'} eq 'comm') { 2762: $toggle_catscomm_comm = $toggle_catscomm_dom; 2763: $toggle_catscomm_dom = ' '; 2764: } 2765: if ($settings->{'categorizecomm'} eq 'comm') { 2766: $can_catcomm_comm = $can_catcomm_dom; 2767: $can_catcomm_dom = ' '; 2768: } 2769: } 2770: my %title = &Apache::lonlocal::texthash ( 2771: togglecats => 'Show/Hide a course in catalog', 2772: togglecatscomm => 'Show/Hide a community in catalog', 2773: categorize => 'Assign a category to a course', 2774: categorizecomm => 'Assign a category to a community', 2775: ); 2776: my %level = &Apache::lonlocal::texthash ( 2777: dom => 'Set in Domain', 2778: crs => 'Set in Course', 2779: comm => 'Set in Community', 2780: ); 2781: $datatable = '<tr class="LC_odd_row">'. 2782: '<td>'.$title{'togglecats'}.'</td>'. 2783: '<td class="LC_right_item"><span class="LC_nobreak"><label>'. 2784: '<input type="radio" name="togglecats"'. 2785: $toggle_cats_dom.' value="dom" />'.$level{'dom'}.'</label> '. 2786: '<label><input type="radio" name="togglecats"'. 2787: $toggle_cats_crs.' value="crs" />'.$level{'crs'}.'</label></span></td>'. 2788: '</tr><tr>'. 2789: '<td>'.$title{'categorize'}.'</td>'. 2790: '<td class="LC_right_item"><span class="LC_nobreak">'. 2791: '<label><input type="radio" name="categorize"'. 2792: $can_cat_dom.' value="dom" />'.$level{'dom'}.'</label> '. 2793: '<label><input type="radio" name="categorize"'. 2794: $can_cat_crs.'value="crs" />'.$level{'crs'}.'</label></span></td>'. 2795: '</tr><tr class="LC_odd_row">'. 2796: '<td>'.$title{'togglecatscomm'}.'</td>'. 2797: '<td class="LC_right_item"><span class="LC_nobreak"><label>'. 2798: '<input type="radio" name="togglecatscomm"'. 2799: $toggle_catscomm_dom.' value="dom" />'.$level{'dom'}.'</label> '. 2800: '<label><input type="radio" name="togglecatscomm"'. 2801: $toggle_catscomm_comm.' value="comm" />'.$level{'comm'}.'</label></span></td>'. 2802: '</tr><tr>'. 2803: '<td>'.$title{'categorizecomm'}.'</td>'. 2804: '<td class="LC_right_item"><span class="LC_nobreak">'. 2805: '<label><input type="radio" name="categorizecomm"'. 2806: $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label> '. 2807: '<label><input type="radio" name="categorizecomm"'. 2808: $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'. 2809: '</tr>'; 2810: $$rowtotal += 4; 2811: } else { 2812: my $css_class; 2813: my $itemcount = 1; 2814: my $cathash; 2815: if (ref($settings) eq 'HASH') { 2816: $cathash = $settings->{'cats'}; 2817: } 2818: if (ref($cathash) eq 'HASH') { 2819: my (@cats,@trails,%allitems,%idx,@jsarray); 2820: &Apache::loncommon::extract_categories($cathash,\@cats,\@trails, 2821: \%allitems,\%idx,\@jsarray); 2822: my $maxdepth = scalar(@cats); 2823: my $colattrib = ''; 2824: if ($maxdepth > 2) { 2825: $colattrib = ' colspan="2" '; 2826: } 2827: my @path; 2828: if (@cats > 0) { 2829: if (ref($cats[0]) eq 'ARRAY') { 2830: my $numtop = @{$cats[0]}; 2831: my $maxnum = $numtop; 2832: my %default_names = ( 2833: instcode => &mt('Official courses'), 2834: communities => &mt('Communities'), 2835: ); 2836: 2837: if ((!grep(/^instcode$/,@{$cats[0]})) || 2838: ($cathash->{'instcode::0'} eq '') || 2839: (!grep(/^communities$/,@{$cats[0]})) || 2840: ($cathash->{'communities::0'} eq '')) { 2841: $maxnum ++; 2842: } 2843: my $lastidx; 2844: for (my $i=0; $i<$numtop; $i++) { 2845: my $parent = $cats[0][$i]; 2846: $css_class = $itemcount%2?' class="LC_odd_row"':''; 2847: my $item = &escape($parent).'::0'; 2848: my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$item','$idx{$item}'".');"'; 2849: $lastidx = $idx{$item}; 2850: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' 2851: .'<select name="'.$item.'"'.$chgstr.'>'; 2852: for (my $k=0; $k<=$maxnum; $k++) { 2853: my $vpos = $k+1; 2854: my $selstr; 2855: if ($k == $i) { 2856: $selstr = ' selected="selected" '; 2857: } 2858: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; 2859: } 2860: $datatable .= '</select></td><td>'; 2861: if ($parent eq 'instcode' || $parent eq 'communities') { 2862: $datatable .= '<span class="LC_nobreak">' 2863: .$default_names{$parent}.'</span>'; 2864: if ($parent eq 'instcode') { 2865: $datatable .= '<br /><span class="LC_nobreak">(' 2866: .&mt('with institutional codes') 2867: .')</span></td><td'.$colattrib.'>'; 2868: } else { 2869: $datatable .= '<table><tr><td>'; 2870: } 2871: $datatable .= '<span class="LC_nobreak">' 2872: .'<label><input type="radio" name="' 2873: .$parent.'" value="1" checked="checked" />' 2874: .&mt('Display').'</label>'; 2875: if ($parent eq 'instcode') { 2876: $datatable .= ' '; 2877: } else { 2878: $datatable .= '</span></td></tr><tr><td>' 2879: .'<span class="LC_nobreak">'; 2880: } 2881: $datatable .= '<label><input type="radio" name="' 2882: .$parent.'" value="0" />' 2883: .&mt('Do not display').'</label></span>'; 2884: if ($parent eq 'communities') { 2885: $datatable .= '</td></tr></table>'; 2886: } 2887: $datatable .= '</td>'; 2888: } else { 2889: $datatable .= $parent 2890: .' <label><input type="checkbox" name="deletecategory" ' 2891: .'value="'.$item.'" />'.&mt('Delete').'</label></span></td>'; 2892: } 2893: my $depth = 1; 2894: push(@path,$parent); 2895: $datatable .= &build_category_rows($itemcount,\@cats,$depth,$parent,\@path,\%idx); 2896: pop(@path); 2897: $datatable .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>'; 2898: $itemcount ++; 2899: } 2900: $css_class = $itemcount%2?' class="LC_odd_row"':''; 2901: my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','$lastidx'".');"'; 2902: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="addcategory_pos"'.$chgstr.'>'; 2903: for (my $k=0; $k<=$maxnum; $k++) { 2904: my $vpos = $k+1; 2905: my $selstr; 2906: if ($k == $numtop) { 2907: $selstr = ' selected="selected" '; 2908: } 2909: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; 2910: } 2911: $datatable .= '</select></span></td><td colspan="2">'.&mt('Add category:').' ' 2912: .'<input type="text" size="20" name="addcategory_name" value="" /></td>' 2913: .'</tr>'."\n"; 2914: $itemcount ++; 2915: foreach my $default ('instcode','communities') { 2916: if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) { 2917: $css_class = $itemcount%2?' class="LC_odd_row"':''; 2918: my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"'; 2919: $datatable .= '<tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr><tr '.$css_class.'><td>'. 2920: '<span class="LC_nobreak"><select name="'.$default.'_pos"'.$chgstr.'>'; 2921: for (my $k=0; $k<=$maxnum; $k++) { 2922: my $vpos = $k+1; 2923: my $selstr; 2924: if ($k == $maxnum) { 2925: $selstr = ' selected="selected" '; 2926: } 2927: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; 2928: } 2929: $datatable .= '</select></span></td>'. 2930: '<td><span class="LC_nobreak">'. 2931: $default_names{$default}.'</span>'; 2932: if ($default eq 'instcode') { 2933: $datatable .= '<br /><span class="LC_nobreak">(' 2934: .&mt('with institutional codes').')</span>'; 2935: } 2936: $datatable .= '</td>' 2937: .'<td><span class="LC_nobreak"><label><input type="radio" name="'.$default.'" value="1" />' 2938: .&mt('Display').'</label> ' 2939: .'<label><input type="radio" name="'.$default.'" value="0" checked="checked"/>' 2940: .&mt('Do not display').'</label></span></td></tr>'; 2941: } 2942: } 2943: } 2944: } else { 2945: $datatable .= &initialize_categories($itemcount); 2946: } 2947: } else { 2948: $datatable .= '<td class="LC_right_item">'.$hdritem->{'header'}->[0]->{'col2'}.'</td>' 2949: .&initialize_categories($itemcount); 2950: } 2951: $$rowtotal += $itemcount; 2952: } 2953: return $datatable; 2954: } 2955: 2956: sub print_serverstatuses { 2957: my ($dom,$settings,$rowtotal) = @_; 2958: my $datatable; 2959: my @pages = &serverstatus_pages(); 2960: my (%namedaccess,%machineaccess); 2961: foreach my $type (@pages) { 2962: $namedaccess{$type} = ''; 2963: $machineaccess{$type}= ''; 2964: } 2965: if (ref($settings) eq 'HASH') { 2966: foreach my $type (@pages) { 2967: if (exists($settings->{$type})) { 2968: if (ref($settings->{$type}) eq 'HASH') { 2969: foreach my $key (keys(%{$settings->{$type}})) { 2970: if ($key eq 'namedusers') { 2971: $namedaccess{$type} = $settings->{$type}->{$key}; 2972: } elsif ($key eq 'machines') { 2973: $machineaccess{$type} = $settings->{$type}->{$key}; 2974: } 2975: } 2976: } 2977: } 2978: } 2979: } 2980: my $titles= &LONCAPA::lonauthcgi::serverstatus_titles(); 2981: my $rownum = 0; 2982: my $css_class; 2983: foreach my $type (@pages) { 2984: $rownum ++; 2985: $css_class = $rownum%2?' class="LC_odd_row"':''; 2986: $datatable .= '<tr'.$css_class.'>'. 2987: '<td><span class="LC_nobreak">'. 2988: $titles->{$type}.'</span></td>'. 2989: '<td class="LC_left_item">'. 2990: '<input type="text" name="'.$type.'_namedusers" '. 2991: 'value="'.$namedaccess{$type}.'" size="30" /></td>'. 2992: '<td class="LC_right_item">'. 2993: '<span class="LC_nobreak">'. 2994: '<input type="text" name="'.$type.'_machines" '. 2995: 'value="'.$machineaccess{$type}.'" size="10" />'. 2996: '</td></tr>'."\n"; 2997: } 2998: $$rowtotal += $rownum; 2999: return $datatable; 3000: } 3001: 3002: sub serverstatus_pages { 3003: return ('userstatus','lonstatus','loncron','server-status','codeversions', 3004: 'clusterstatus','metadata_keywords','metadata_harvest', 3005: 'takeoffline','takeonline','showenv','toggledebug'); 3006: } 3007: 3008: sub coursecategories_javascript { 3009: my ($settings) = @_; 3010: my ($output,$jstext,$cathash); 3011: if (ref($settings) eq 'HASH') { 3012: $cathash = $settings->{'cats'}; 3013: } 3014: if (ref($cathash) eq 'HASH') { 3015: my (@cats,@jsarray,%idx); 3016: &Apache::loncommon::gather_categories($cathash,\@cats,\%idx,\@jsarray); 3017: if (@jsarray > 0) { 3018: $jstext = ' var categories = Array('.scalar(@jsarray).');'."\n"; 3019: for (my $i=0; $i<@jsarray; $i++) { 3020: if (ref($jsarray[$i]) eq 'ARRAY') { 3021: my $catstr = join('","',@{$jsarray[$i]}); 3022: $jstext .= ' categories['.$i.'] = Array("'.$catstr.'");'."\n"; 3023: } 3024: } 3025: } 3026: } else { 3027: $jstext = ' var categories = Array(1);'."\n". 3028: ' categories[0] = Array("instcode_pos");'."\n"; 3029: } 3030: my $instcode_reserved = &mt('The name: "instcode" is a reserved category'); 3031: my $communities_reserved = &mt('The name: "communities" is a reserved category'); 3032: my $choose_again = '\\n'.&mt('Please use a different name for the new top level category'); 3033: $output = <<"ENDSCRIPT"; 3034: <script type="text/javascript"> 3035: // <![CDATA[ 3036: function reorderCats(form,parent,item,idx) { 3037: var changedVal; 3038: $jstext 3039: var newpos = 'addcategory_pos'; 3040: var current = new Array; 3041: if (parent == '') { 3042: var has_instcode = 0; 3043: var maxtop = categories[idx].length; 3044: for (var j=0; j<maxtop; j++) { 3045: if (categories[idx][j] == 'instcode::0') { 3046: has_instcode == 1; 3047: } 3048: } 3049: if (has_instcode == 0) { 3050: categories[idx][maxtop] = 'instcode_pos'; 3051: } 3052: } else { 3053: newpos += '_'+parent; 3054: } 3055: var maxh = 1 + categories[idx].length; 3056: var current = new Array; 3057: var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value; 3058: if (item == newpos) { 3059: changedVal = newitemVal; 3060: } else { 3061: changedVal = form.elements[item].options[form.elements[item].selectedIndex].value; 3062: current[newitemVal] = newpos; 3063: } 3064: for (var i=0; i<categories[idx].length; i++) { 3065: var elementName = categories[idx][i]; 3066: if (elementName != item) { 3067: if (form.elements[elementName]) { 3068: var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value; 3069: current[currVal] = elementName; 3070: } 3071: } 3072: } 3073: var oldVal; 3074: for (var j=0; j<maxh; j++) { 3075: if (current[j] == undefined) { 3076: oldVal = j; 3077: } 3078: } 3079: if (oldVal < changedVal) { 3080: for (var k=oldVal+1; k<=changedVal ; k++) { 3081: var elementName = current[k]; 3082: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1; 3083: } 3084: } else { 3085: for (var k=changedVal; k<oldVal; k++) { 3086: var elementName = current[k]; 3087: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1; 3088: } 3089: } 3090: return; 3091: } 3092: 3093: function categoryCheck(form) { 3094: if (form.elements['addcategory_name'].value == 'instcode') { 3095: alert('$instcode_reserved\\n$choose_again'); 3096: return false; 3097: } 3098: if (form.elements['addcategory_name'].value == 'communities') { 3099: alert('$communities_reserved\\n$choose_again'); 3100: return false; 3101: } 3102: return true; 3103: } 3104: 3105: // ]]> 3106: </script> 3107: 3108: ENDSCRIPT 3109: return $output; 3110: } 3111: 3112: sub initialize_categories { 3113: my ($itemcount) = @_; 3114: my ($datatable,$css_class,$chgstr); 3115: my %default_names = ( 3116: instcode => 'Official courses (with institutional codes)', 3117: communities => 'Communities', 3118: ); 3119: my $select0 = ' selected="selected"'; 3120: my $select1 = ''; 3121: foreach my $default ('instcode','communities') { 3122: $css_class = $itemcount%2?' class="LC_odd_row"':''; 3123: $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"'; 3124: if ($default eq 'communities') { 3125: $select1 = $select0; 3126: $select0 = ''; 3127: } 3128: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' 3129: .'<select name="'.$default.'_pos">' 3130: .'<option value="0"'.$select0.'>1</option>' 3131: .'<option value="1"'.$select1.'>2</option>' 3132: .'<option value="2">3</option></select> ' 3133: .$default_names{$default} 3134: .'</span></td><td><span class="LC_nobreak">' 3135: .'<label><input type="radio" name="'.$default.'" value="1" checked="checked" />' 3136: .&mt('Display').'</label> <label>' 3137: .'<input type="radio" name="'.$default.'" value="0" />'.&mt('Do not display') 3138: .'</label></span></td></tr>'; 3139: $itemcount ++; 3140: } 3141: $css_class = $itemcount%2?' class="LC_odd_row"':''; 3142: $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','0'".');"'; 3143: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' 3144: .'<select name="addcategory_pos"'.$chgstr.'>' 3145: .'<option value="0">1</option>' 3146: .'<option value="1">2</option>' 3147: .'<option value="2" selected="selected">3</option></select> ' 3148: .&mt('Add category').'</td><td>'.&mt('Name:') 3149: .' <input type="text" size="20" name="addcategory_name" value="" /></td></tr>'; 3150: return $datatable; 3151: } 3152: 3153: sub build_category_rows { 3154: my ($itemcount,$cats,$depth,$parent,$path,$idx) = @_; 3155: my ($text,$name,$item,$chgstr); 3156: if (ref($cats) eq 'ARRAY') { 3157: my $maxdepth = scalar(@{$cats}); 3158: if (ref($cats->[$depth]) eq 'HASH') { 3159: if (ref($cats->[$depth]{$parent}) eq 'ARRAY') { 3160: my $numchildren = @{$cats->[$depth]{$parent}}; 3161: my $css_class = $itemcount%2?' class="LC_odd_row"':''; 3162: $text .= '<td><table class="LC_datatable">'; 3163: my ($idxnum,$parent_name,$parent_item); 3164: my $higher = $depth - 1; 3165: if ($higher == 0) { 3166: $parent_name = &escape($parent).'::'.$higher; 3167: } else { 3168: if (ref($path) eq 'ARRAY') { 3169: $parent_name = &escape($parent).':'.&escape($path->[-2]).':'.$higher; 3170: } 3171: } 3172: $parent_item = 'addcategory_pos_'.$parent_name; 3173: for (my $j=0; $j<=$numchildren; $j++) { 3174: if ($j < $numchildren) { 3175: $name = $cats->[$depth]{$parent}[$j]; 3176: $item = &escape($name).':'.&escape($parent).':'.$depth; 3177: $idxnum = $idx->{$item}; 3178: } else { 3179: $name = $parent_name; 3180: $item = $parent_item; 3181: } 3182: $chgstr = ' onchange="javascript:reorderCats(this.form,'."'$parent_name','$item','$idxnum'".');"'; 3183: $text .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="'.$item.'"'.$chgstr.'>'; 3184: for (my $i=0; $i<=$numchildren; $i++) { 3185: my $vpos = $i+1; 3186: my $selstr; 3187: if ($j == $i) { 3188: $selstr = ' selected="selected" '; 3189: } 3190: $text .= '<option value="'.$i.'"'.$selstr.'>'.$vpos.'</option>'; 3191: } 3192: $text .= '</select> '; 3193: if ($j < $numchildren) { 3194: my $deeper = $depth+1; 3195: $text .= $name.' ' 3196: .'<label><input type="checkbox" name="deletecategory" value="' 3197: .$item.'" />'.&mt('Delete').'</label></span></td><td>'; 3198: if(ref($path) eq 'ARRAY') { 3199: push(@{$path},$name); 3200: $text .= &build_category_rows($itemcount,$cats,$deeper,$name,$path,$idx); 3201: pop(@{$path}); 3202: } 3203: } else { 3204: $text .= &mt('Add subcategory:').' </span><input type="textbox" size="20" name="addcategory_name_'; 3205: if ($j == $numchildren) { 3206: $text .= $name; 3207: } else { 3208: $text .= $item; 3209: } 3210: $text .= '" value="" />'; 3211: } 3212: $text .= '</td></tr>'; 3213: } 3214: $text .= '</table></td>'; 3215: } else { 3216: my $higher = $depth-1; 3217: if ($higher == 0) { 3218: $name = &escape($parent).'::'.$higher; 3219: } else { 3220: if (ref($path) eq 'ARRAY') { 3221: $name = &escape($parent).':'.&escape($path->[-2]).':'.$higher; 3222: } 3223: } 3224: my $colspan; 3225: if ($parent ne 'instcode') { 3226: $colspan = $maxdepth - $depth - 1; 3227: $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="textbox" size="20" name="subcat_'.$name.'" value="" /></td>'; 3228: } 3229: } 3230: } 3231: } 3232: return $text; 3233: } 3234: 3235: sub modifiable_userdata_row { 3236: my ($context,$role,$settings,$numinrow,$rowcount,$usertypes) = @_; 3237: my $rolename; 3238: if ($context eq 'selfcreate') { 3239: if (ref($usertypes) eq 'HASH') { 3240: $rolename = $usertypes->{$role}; 3241: } else { 3242: $rolename = $role; 3243: } 3244: } else { 3245: if ($role eq 'cr') { 3246: $rolename = &mt('Custom role'); 3247: } else { 3248: $rolename = &Apache::lonnet::plaintext($role); 3249: } 3250: } 3251: my @fields = ('lastname','firstname','middlename','generation', 3252: 'permanentemail','id'); 3253: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); 3254: my $output; 3255: my $css_class = $rowcount%2?' class="LC_odd_row"':''; 3256: $output = '<tr '.$css_class.'>'. 3257: '<td><span class="LC_nobreak">'.$rolename.'</span></td>'. 3258: '<td class="LC_left_item" colspan="2"><table>'; 3259: my $rem; 3260: my %checks; 3261: if (ref($settings) eq 'HASH') { 3262: if (ref($settings->{$context}) eq 'HASH') { 3263: if (ref($settings->{$context}->{$role}) eq 'HASH') { 3264: foreach my $field (@fields) { 3265: if ($settings->{$context}->{$role}->{$field}) { 3266: $checks{$field} = ' checked="checked" '; 3267: } 3268: } 3269: } 3270: } 3271: } 3272: for (my $i=0; $i<@fields; $i++) { 3273: my $rem = $i%($numinrow); 3274: if ($rem == 0) { 3275: if ($i > 0) { 3276: $output .= '</tr>'; 3277: } 3278: $output .= '<tr>'; 3279: } 3280: my $check = ' '; 3281: if (exists($checks{$fields[$i]})) { 3282: $check = $checks{$fields[$i]} 3283: } else { 3284: if ($role eq 'st') { 3285: if (ref($settings) ne 'HASH') { 3286: $check = ' checked="checked" '; 3287: } 3288: } 3289: } 3290: $output .= '<td class="LC_left_item">'. 3291: '<span class="LC_nobreak"><label>'. 3292: '<input type="checkbox" name="canmodify_'.$role.'" '. 3293: 'value="'.$fields[$i].'"'.$check.'/>'.$fieldtitles{$fields[$i]}. 3294: '</label></span></td>'; 3295: $rem = @fields%($numinrow); 3296: } 3297: my $colsleft = $numinrow - $rem; 3298: if ($colsleft > 1 ) { 3299: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'. 3300: ' </td>'; 3301: } elsif ($colsleft == 1) { 3302: $output .= '<td class="LC_left_item"> </td>'; 3303: } 3304: $output .= '</tr></table></td></tr>'; 3305: return $output; 3306: } 3307: 3308: sub insttypes_row { 3309: my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context) = @_; 3310: my %lt = &Apache::lonlocal::texthash ( 3311: cansearch => 'Users allowed to search', 3312: statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)', 3313: ); 3314: my $showdom; 3315: if ($context eq 'cansearch') { 3316: $showdom = ' ('.$dom.')'; 3317: } 3318: my $output = '<tr class="LC_odd_row">'. 3319: '<td>'.$lt{$context}.$showdom. 3320: '</td><td class="LC_left_item" colspan="2"><table>'; 3321: my $rem; 3322: if (ref($types) eq 'ARRAY') { 3323: for (my $i=0; $i<@{$types}; $i++) { 3324: if (defined($usertypes->{$types->[$i]})) { 3325: my $rem = $i%($numinrow); 3326: if ($rem == 0) { 3327: if ($i > 0) { 3328: $output .= '</tr>'; 3329: } 3330: $output .= '<tr>'; 3331: } 3332: my $check = ' '; 3333: if (ref($settings) eq 'HASH') { 3334: if (ref($settings->{$context}) eq 'ARRAY') { 3335: if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) { 3336: $check = ' checked="checked" '; 3337: } 3338: } elsif ($context eq 'statustocreate') { 3339: $check = ' checked="checked" '; 3340: } 3341: } 3342: $output .= '<td class="LC_left_item">'. 3343: '<span class="LC_nobreak"><label>'. 3344: '<input type="checkbox" name="'.$context.'" '. 3345: 'value="'.$types->[$i].'"'.$check.'/>'. 3346: $usertypes->{$types->[$i]}.'</label></span></td>'; 3347: } 3348: } 3349: 3350: $rem = @{$types}%($numinrow); 3351: } 3352: my $colsleft = $numinrow - $rem; 3353: if ($colsleft > 1) { 3354: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; 3355: } else { 3356: $output .= '<td class="LC_left_item">'; 3357: } 3358: my $defcheck = ' '; 3359: if (ref($settings) eq 'HASH') { 3360: if (ref($settings->{$context}) eq 'ARRAY') { 3361: if (grep(/^default$/,@{$settings->{$context}})) { 3362: $defcheck = ' checked="checked" '; 3363: } 3364: } elsif ($context eq 'statustocreate') { 3365: $defcheck = ' checked="checked" '; 3366: } 3367: } 3368: $output .= '<span class="LC_nobreak"><label>'. 3369: '<input type="checkbox" name="'.$context.'" '. 3370: 'value="default"'.$defcheck.'/>'. 3371: $othertitle.'</label></span></td>'. 3372: '</tr></table></td></tr>'; 3373: return $output; 3374: } 3375: 3376: sub sorted_searchtitles { 3377: my %searchtitles = &Apache::lonlocal::texthash( 3378: 'uname' => 'username', 3379: 'lastname' => 'last name', 3380: 'lastfirst' => 'last name, first name', 3381: ); 3382: my @titleorder = ('uname','lastname','lastfirst'); 3383: return (\%searchtitles,\@titleorder); 3384: } 3385: 3386: sub sorted_searchtypes { 3387: my %srchtypes_desc = ( 3388: exact => 'is exact match', 3389: contains => 'contains ..', 3390: begins => 'begins with ..', 3391: ); 3392: my @srchtypeorder = ('exact','begins','contains'); 3393: return (\%srchtypes_desc,\@srchtypeorder); 3394: } 3395: 3396: sub usertype_update_row { 3397: my ($settings,$usertypes,$fieldtitles,$fields,$types,$rownums) = @_; 3398: my $datatable; 3399: my $numinrow = 4; 3400: foreach my $type (@{$types}) { 3401: if (defined($usertypes->{$type})) { 3402: $$rownums ++; 3403: my $css_class = $$rownums%2?' class="LC_odd_row"':''; 3404: $datatable .= '<tr'.$css_class.'><td>'.$usertypes->{$type}. 3405: '</td><td class="LC_left_item"><table>'; 3406: for (my $i=0; $i<@{$fields}; $i++) { 3407: my $rem = $i%($numinrow); 3408: if ($rem == 0) { 3409: if ($i > 0) { 3410: $datatable .= '</tr>'; 3411: } 3412: $datatable .= '<tr>'; 3413: } 3414: my $check = ' '; 3415: if (ref($settings) eq 'HASH') { 3416: if (ref($settings->{'fields'}) eq 'HASH') { 3417: if (ref($settings->{'fields'}{$type}) eq 'ARRAY') { 3418: if (grep(/^\Q$fields->[$i]\E$/,@{$settings->{'fields'}{$type}})) { 3419: $check = ' checked="checked" '; 3420: } 3421: } 3422: } 3423: } 3424: 3425: if ($i == @{$fields}-1) { 3426: my $colsleft = $numinrow - $rem; 3427: if ($colsleft > 1) { 3428: $datatable .= '<td colspan="'.$colsleft.'">'; 3429: } else { 3430: $datatable .= '<td>'; 3431: } 3432: } else { 3433: $datatable .= '<td>'; 3434: } 3435: $datatable .= '<span class="LC_nobreak"><label>'. 3436: '<input type="checkbox" name="updateable_'.$type. 3437: '_'.$fields->[$i].'" value="1"'.$check.'/>'. 3438: $fieldtitles->{$fields->[$i]}.'</label></span></td>'; 3439: } 3440: $datatable .= '</tr></table></td></tr>'; 3441: } 3442: } 3443: return $datatable; 3444: } 3445: 3446: sub modify_login { 3447: my ($r,$dom,$confname,%domconfig) = @_; 3448: my ($resulttext,$errors,$colchgtext,%changes,%colchanges); 3449: my %title = ( coursecatalog => 'Display course catalog', 3450: adminmail => 'Display administrator E-mail address', 3451: newuser => 'Link for visitors to create a user account', 3452: loginheader => 'Log-in box header'); 3453: my @offon = ('off','on'); 3454: my %curr_loginvia; 3455: if (ref($domconfig{login}) eq 'HASH') { 3456: if (ref($domconfig{login}{loginvia}) eq 'HASH') { 3457: foreach my $lonhost (keys(%{$domconfig{login}{loginvia}})) { 3458: $curr_loginvia{$lonhost} = $domconfig{login}{loginvia}{$lonhost}; 3459: } 3460: } 3461: } 3462: my %loginhash; 3463: ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'], 3464: \%domconfig,\%loginhash); 3465: my @toggles = ('coursecatalog','adminmail','newuser'); 3466: foreach my $item (@toggles) { 3467: $loginhash{login}{$item} = $env{'form.'.$item}; 3468: } 3469: $loginhash{login}{loginheader} = $env{'form.loginheader'}; 3470: if (ref($colchanges{'login'}) eq 'HASH') { 3471: $colchgtext = &display_colorchgs($dom,\%colchanges,['login'], 3472: \%loginhash); 3473: } 3474: 3475: my %servers = &dom_servers($dom); 3476: if (keys(%servers) > 1) { 3477: foreach my $lonhost (keys(%servers)) { 3478: next if ($env{'form.'.$lonhost.'_serverurl'} eq $lonhost); 3479: if ($env{'form.'.$lonhost.'_serverurl'} eq $curr_loginvia{$lonhost}) { 3480: $loginhash{login}{loginvia}{$lonhost} = $curr_loginvia{$lonhost}; next; 3481: } 3482: if ($curr_loginvia{$lonhost} ne '') { 3483: $loginhash{login}{loginvia}{$lonhost} = $env{'form.'.$lonhost.'_serverurl'}; 3484: $changes{'loginvia'}{$lonhost} = 1; 3485: } else { 3486: if (defined($servers{$env{'form.'.$lonhost.'_serverurl'}})) { 3487: $loginhash{login}{loginvia}{$lonhost} = $env{'form.'.$lonhost.'_serverurl'}; 3488: $changes{'loginvia'}{$lonhost} = 1; 3489: } 3490: } 3491: } 3492: } 3493: 3494: my $putresult = &Apache::lonnet::put_dom('configuration',\%loginhash, 3495: $dom); 3496: if ($putresult eq 'ok') { 3497: my @toggles = ('coursecatalog','adminmail','newuser'); 3498: my %defaultchecked = ( 3499: 'coursecatalog' => 'on', 3500: 'adminmail' => 'off', 3501: 'newuser' => 'off', 3502: ); 3503: if (ref($domconfig{'login'}) eq 'HASH') { 3504: foreach my $item (@toggles) { 3505: if ($defaultchecked{$item} eq 'on') { 3506: if (($domconfig{'login'}{$item} eq '0') && 3507: ($env{'form.'.$item} eq '1')) { 3508: $changes{$item} = 1; 3509: } elsif (($domconfig{'login'}{$item} eq '' || 3510: $domconfig{'login'}{$item} eq '1') && 3511: ($env{'form.'.$item} eq '0')) { 3512: $changes{$item} = 1; 3513: } 3514: } elsif ($defaultchecked{$item} eq 'off') { 3515: if (($domconfig{'login'}{$item} eq '1') && 3516: ($env{'form.'.$item} eq '0')) { 3517: $changes{$item} = 1; 3518: } elsif (($domconfig{'login'}{$item} eq '' || 3519: $domconfig{'login'}{$item} eq '0') && 3520: ($env{'form.'.$item} eq '1')) { 3521: $changes{$item} = 1; 3522: } 3523: } 3524: } 3525: if (($domconfig{'login'}{'loginheader'} eq 'text') && 3526: ($env{'form.loginheader'} eq 'image')) { 3527: $changes{'loginheader'} = 1; 3528: } elsif (($domconfig{'login'}{'loginheader'} eq '' || 3529: $domconfig{'login'}{'loginheader'} eq 'image') && 3530: ($env{'form.loginheader'} eq 'text')) { 3531: $changes{'loginheader'} = 1; 3532: } 3533: } 3534: if (keys(%changes) > 0 || $colchgtext) { 3535: &Apache::loncommon::devalidate_domconfig_cache($dom); 3536: $resulttext = &mt('Changes made:').'<ul>'; 3537: foreach my $item (sort(keys(%changes))) { 3538: if ($item eq 'loginheader') { 3539: $resulttext .= '<li>'.&mt("$title{$item} set to $env{'form.loginheader'}").'</li>'; 3540: } elsif ($item eq 'loginvia') { 3541: if (ref($changes{$item}) eq 'HASH') { 3542: $resulttext .= '<li>'.&mt('Log-in page availability:').'<ul>'; 3543: foreach my $lonhost (sort(keys(%{$changes{$item}}))) { 3544: if ($servers{$env{'form.'.$lonhost.'_serverurl'}} ne '') { 3545: $resulttext .= '<li>'.&mt('Server: [_1] log-in page now redirects to [_2]',$lonhost,$servers{$env{'form.'.$lonhost.'_serverurl'}}).'</li>'; 3546: } else { 3547: $resulttext .= '<li>'.&mt('Server: [_1] now has standard log-in page.',$lonhost).'</li>'; 3548: } 3549: } 3550: $resulttext .= '</ul></li>'; 3551: } 3552: } else { 3553: $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>'; 3554: } 3555: } 3556: $resulttext .= $colchgtext.'</ul>'; 3557: } else { 3558: $resulttext = &mt('No changes made to log-in page settings'); 3559: } 3560: } else { 3561: $resulttext = '<span class="LC_error">'. 3562: &mt('An error occurred: [_1]',$putresult).'</span>'; 3563: } 3564: if ($errors) { 3565: $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'. 3566: $errors.'</ul>'; 3567: } 3568: return $resulttext; 3569: } 3570: 3571: sub color_font_choices { 3572: my %choices = 3573: &Apache::lonlocal::texthash ( 3574: img => "Header", 3575: bgs => "Background colors", 3576: links => "Link colors", 3577: images => "Images", 3578: font => "Font color", 3579: fontmenu => "Font Menu", 3580: pgbg => "Page", 3581: tabbg => "Header", 3582: sidebg => "Border", 3583: link => "Link", 3584: alink => "Active link", 3585: vlink => "Visited link", 3586: ); 3587: return %choices; 3588: } 3589: 3590: sub modify_rolecolors { 3591: my ($r,$dom,$confname,$roles,%domconfig) = @_; 3592: my ($resulttext,%rolehash); 3593: $rolehash{'rolecolors'} = {}; 3594: if (ref($domconfig{'rolecolors'}) ne 'HASH') { 3595: if ($domconfig{'rolecolors'} eq '') { 3596: $domconfig{'rolecolors'} = {}; 3597: } 3598: } 3599: my ($errors,%changes) = &modify_colors($r,$dom,$confname,$roles, 3600: $domconfig{'rolecolors'},$rolehash{'rolecolors'}); 3601: my $putresult = &Apache::lonnet::put_dom('configuration',\%rolehash, 3602: $dom); 3603: if ($putresult eq 'ok') { 3604: if (keys(%changes) > 0) { 3605: &Apache::loncommon::devalidate_domconfig_cache($dom); 3606: $resulttext = &display_colorchgs($dom,\%changes,$roles, 3607: $rolehash{'rolecolors'}); 3608: } else { 3609: $resulttext = &mt('No changes made to default color schemes'); 3610: } 3611: } else { 3612: $resulttext = '<span class="LC_error">'. 3613: &mt('An error occurred: [_1]',$putresult).'</span>'; 3614: } 3615: if ($errors) { 3616: $resulttext .= &mt('The following errors occurred: ').'<ul>'. 3617: $errors.'</ul>'; 3618: } 3619: return $resulttext; 3620: } 3621: 3622: sub modify_colors { 3623: my ($r,$dom,$confname,$roles,$domconfig,$confhash) = @_; 3624: my (%changes,%choices); 3625: my @bgs; 3626: my @links = ('link','alink','vlink'); 3627: my @logintext; 3628: my @images; 3629: my $servadm = $r->dir_config('lonAdmEMail'); 3630: my $errors; 3631: foreach my $role (@{$roles}) { 3632: if ($role eq 'login') { 3633: %choices = &login_choices(); 3634: @logintext = ('textcol','bgcol'); 3635: } else { 3636: %choices = &color_font_choices(); 3637: $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'}; 3638: } 3639: if ($role eq 'login') { 3640: @images = ('img','logo','domlogo','login'); 3641: @bgs = ('pgbg','mainbg','sidebg'); 3642: } else { 3643: @images = ('img'); 3644: @bgs = ('pgbg','tabbg','sidebg'); 3645: } 3646: $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'}; 3647: foreach my $item (@bgs,@links,@logintext) { 3648: $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item}; 3649: } 3650: my ($configuserok,$author_ok,$switchserver) = 3651: &config_check($dom,$confname,$servadm); 3652: my ($width,$height) = &thumb_dimensions(); 3653: if (ref($domconfig->{$role}) ne 'HASH') { 3654: $domconfig->{$role} = {}; 3655: } 3656: foreach my $img (@images) { 3657: if (($role eq 'login') && (($img eq 'img') || ($img eq 'logo'))) { 3658: if (defined($env{'form.login_showlogo_'.$img})) { 3659: $confhash->{$role}{'showlogo'}{$img} = 1; 3660: } else { 3661: $confhash->{$role}{'showlogo'}{$img} = 0; 3662: } 3663: } 3664: if ( ! $env{'form.'.$role.'_'.$img.'.filename'} 3665: && !defined($domconfig->{$role}{$img}) 3666: && !$env{'form.'.$role.'_del_'.$img} 3667: && $env{'form.'.$role.'_import_'.$img}) { 3668: # import the old configured image from the .tab setting 3669: # if they haven't provided a new one 3670: $domconfig->{$role}{$img} = 3671: $env{'form.'.$role.'_import_'.$img}; 3672: } 3673: if ($env{'form.'.$role.'_'.$img.'.filename'} ne '') { 3674: my $error; 3675: if ($configuserok eq 'ok') { 3676: if ($switchserver) { 3677: $error = &mt("Upload of [_1] image for $role page(s) is not permitted to this server: [_2]",$choices{$img},$switchserver); 3678: } else { 3679: if ($author_ok eq 'ok') { 3680: my ($result,$logourl) = 3681: &publishlogo($r,'upload',$role.'_'.$img, 3682: $dom,$confname,$img,$width,$height); 3683: if ($result eq 'ok') { 3684: $confhash->{$role}{$img} = $logourl; 3685: $changes{$role}{'images'}{$img} = 1; 3686: } else { 3687: $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); 3688: } 3689: } else { 3690: $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); 3691: } 3692: } 3693: } else { 3694: $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); 3695: } 3696: if ($error) { 3697: &Apache::lonnet::logthis($error); 3698: $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; 3699: } 3700: } elsif ($domconfig->{$role}{$img} ne '') { 3701: if ($domconfig->{$role}{$img} !~ m-^(/res/\Q$dom\E/\Q$confname\E/\Q$img\E)/([^/]+)$-) { 3702: my $error; 3703: if ($configuserok eq 'ok') { 3704: # is confname an author? 3705: if ($switchserver eq '') { 3706: if ($author_ok eq 'ok') { 3707: my ($result,$logourl) = 3708: &publishlogo($r,'copy',$domconfig->{$role}{$img}, 3709: $dom,$confname,$img,$width,$height); 3710: if ($result eq 'ok') { 3711: $confhash->{$role}{$img} = $logourl; 3712: $changes{$role}{'images'}{$img} = 1; 3713: } 3714: } 3715: } 3716: } 3717: } 3718: } 3719: } 3720: if (ref($domconfig) eq 'HASH') { 3721: if (ref($domconfig->{$role}) eq 'HASH') { 3722: foreach my $img (@images) { 3723: if ($domconfig->{$role}{$img} ne '') { 3724: if ($env{'form.'.$role.'_del_'.$img}) { 3725: $confhash->{$role}{$img} = ''; 3726: $changes{$role}{'images'}{$img} = 1; 3727: } else { 3728: if ($confhash->{$role}{$img} eq '') { 3729: $confhash->{$role}{$img} = $domconfig->{$role}{$img}; 3730: } 3731: } 3732: } else { 3733: if ($env{'form.'.$role.'_del_'.$img}) { 3734: $confhash->{$role}{$img} = ''; 3735: $changes{$role}{'images'}{$img} = 1; 3736: } 3737: } 3738: if (($role eq 'login') && (($img eq 'logo') || ($img eq 'img'))) { 3739: if (ref($domconfig->{'login'}{'showlogo'}) eq 'HASH') { 3740: if ($confhash->{$role}{'showlogo'}{$img} ne 3741: $domconfig->{$role}{'showlogo'}{$img}) { 3742: $changes{$role}{'showlogo'}{$img} = 1; 3743: } 3744: } else { 3745: if ($confhash->{$role}{'showlogo'}{$img} == 0) { 3746: $changes{$role}{'showlogo'}{$img} = 1; 3747: } 3748: } 3749: } 3750: } 3751: if ($domconfig->{$role}{'font'} ne '') { 3752: if ($confhash->{$role}{'font'} ne $domconfig->{$role}{'font'}) { 3753: $changes{$role}{'font'} = 1; 3754: } 3755: } else { 3756: if ($confhash->{$role}{'font'}) { 3757: $changes{$role}{'font'} = 1; 3758: } 3759: } 3760: if ($role ne 'login') { 3761: if ($domconfig->{$role}{'fontmenu'} ne '') { 3762: if ($confhash->{$role}{'fontmenu'} ne $domconfig->{$role}{'fontmenu'}) { 3763: $changes{$role}{'fontmenu'} = 1; 3764: } 3765: } else { 3766: if ($confhash->{$role}{'fontmenu'}) { 3767: $changes{$role}{'fontmenu'} = 1; 3768: } 3769: } 3770: } 3771: foreach my $item (@bgs) { 3772: if ($domconfig->{$role}{$item} ne '') { 3773: if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) { 3774: $changes{$role}{'bgs'}{$item} = 1; 3775: } 3776: } else { 3777: if ($confhash->{$role}{$item}) { 3778: $changes{$role}{'bgs'}{$item} = 1; 3779: } 3780: } 3781: } 3782: foreach my $item (@links) { 3783: if ($domconfig->{$role}{$item} ne '') { 3784: if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) { 3785: $changes{$role}{'links'}{$item} = 1; 3786: } 3787: } else { 3788: if ($confhash->{$role}{$item}) { 3789: $changes{$role}{'links'}{$item} = 1; 3790: } 3791: } 3792: } 3793: foreach my $item (@logintext) { 3794: if ($domconfig->{$role}{$item} ne '') { 3795: if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) { 3796: $changes{$role}{'logintext'}{$item} = 1; 3797: } 3798: } else { 3799: if ($confhash->{$role}{$item}) { 3800: $changes{$role}{'logintext'}{$item} = 1; 3801: } 3802: } 3803: } 3804: } else { 3805: &default_change_checker($role,\@images,\@links,\@bgs, 3806: \@logintext,$confhash,\%changes); 3807: } 3808: } else { 3809: &default_change_checker($role,\@images,\@links,\@bgs, 3810: \@logintext,$confhash,\%changes); 3811: } 3812: } 3813: return ($errors,%changes); 3814: } 3815: 3816: sub config_check { 3817: my ($dom,$confname,$servadm) = @_; 3818: my ($configuserok,$author_ok,$switchserver,%currroles); 3819: my $uhome = &Apache::lonnet::homeserver($confname,$dom,1); 3820: ($configuserok,%currroles) = &check_configuser($uhome,$dom, 3821: $confname,$servadm); 3822: if ($configuserok eq 'ok') { 3823: $switchserver = &check_switchserver($dom,$confname); 3824: if ($switchserver eq '') { 3825: $author_ok = &check_authorstatus($dom,$confname,%currroles); 3826: } 3827: } 3828: return ($configuserok,$author_ok,$switchserver); 3829: } 3830: 3831: sub default_change_checker { 3832: my ($role,$images,$links,$bgs,$logintext,$confhash,$changes) = @_; 3833: foreach my $item (@{$links}) { 3834: if ($confhash->{$role}{$item}) { 3835: $changes->{$role}{'links'}{$item} = 1; 3836: } 3837: } 3838: foreach my $item (@{$bgs}) { 3839: if ($confhash->{$role}{$item}) { 3840: $changes->{$role}{'bgs'}{$item} = 1; 3841: } 3842: } 3843: foreach my $item (@{$logintext}) { 3844: if ($confhash->{$role}{$item}) { 3845: $changes->{$role}{'logintext'}{$item} = 1; 3846: } 3847: } 3848: foreach my $img (@{$images}) { 3849: if ($env{'form.'.$role.'_del_'.$img}) { 3850: $confhash->{$role}{$img} = ''; 3851: $changes->{$role}{'images'}{$img} = 1; 3852: } 3853: if ($role eq 'login') { 3854: if ($confhash->{$role}{'showlogo'}{$img} == 0) { 3855: $changes->{$role}{'showlogo'}{$img} = 1; 3856: } 3857: } 3858: } 3859: if ($confhash->{$role}{'font'}) { 3860: $changes->{$role}{'font'} = 1; 3861: } 3862: } 3863: 3864: sub display_colorchgs { 3865: my ($dom,$changes,$roles,$confhash) = @_; 3866: my (%choices,$resulttext); 3867: if (!grep(/^login$/,@{$roles})) { 3868: $resulttext = &mt('Changes made:').'<br />'; 3869: } 3870: foreach my $role (@{$roles}) { 3871: if ($role eq 'login') { 3872: %choices = &login_choices(); 3873: } else { 3874: %choices = &color_font_choices(); 3875: } 3876: if (ref($changes->{$role}) eq 'HASH') { 3877: if ($role ne 'login') { 3878: $resulttext .= '<h4>'.&mt($role).'</h4>'; 3879: } 3880: foreach my $key (sort(keys(%{$changes->{$role}}))) { 3881: if ($role ne 'login') { 3882: $resulttext .= '<ul>'; 3883: } 3884: if (ref($changes->{$role}{$key}) eq 'HASH') { 3885: if ($role ne 'login') { 3886: $resulttext .= '<li>'.&mt($choices{$key}).':<ul>'; 3887: } 3888: foreach my $item (sort(keys(%{$changes->{$role}{$key}}))) { 3889: if (($role eq 'login') && ($key eq 'showlogo')) { 3890: if ($confhash->{$role}{$key}{$item}) { 3891: $resulttext .= '<li>'.&mt("$choices{$item} set to be displayed").'</li>'; 3892: } else { 3893: $resulttext .= '<li>'.&mt("$choices{$item} set to not be displayed").'</li>'; 3894: } 3895: } elsif ($confhash->{$role}{$item} eq '') { 3896: $resulttext .= '<li>'.&mt("$choices{$item} set to default").'</li>'; 3897: } else { 3898: my $newitem = $confhash->{$role}{$item}; 3899: if ($key eq 'images') { 3900: $newitem = '<img src="'.$confhash->{$role}{$item}.'" alt="'.$choices{$item}.'" valign="bottom" />'; 3901: } 3902: $resulttext .= '<li>'.&mt("$choices{$item} set to [_1]",$newitem).'</li>'; 3903: } 3904: } 3905: if ($role ne 'login') { 3906: $resulttext .= '</ul></li>'; 3907: } 3908: } else { 3909: if ($confhash->{$role}{$key} eq '') { 3910: $resulttext .= '<li>'.&mt("$choices{$key} set to default").'</li>'; 3911: } else { 3912: $resulttext .= '<li>'.&mt("$choices{$key} set to [_1]",$confhash->{$role}{$key}).'</li>'; 3913: } 3914: } 3915: if ($role ne 'login') { 3916: $resulttext .= '</ul>'; 3917: } 3918: } 3919: } 3920: } 3921: return $resulttext; 3922: } 3923: 3924: sub thumb_dimensions { 3925: return ('200','50'); 3926: } 3927: 3928: sub check_dimensions { 3929: my ($inputfile) = @_; 3930: my ($fullwidth,$fullheight); 3931: if ($inputfile =~ m|^[/\w.\-]+$|) { 3932: if (open(PIPE,"identify $inputfile 2>&1 |")) { 3933: my $imageinfo = <PIPE>; 3934: if (!close(PIPE)) { 3935: &Apache::lonnet::logthis("Failed to close PIPE opened to retrieve image information for $inputfile"); 3936: } 3937: chomp($imageinfo); 3938: my ($fullsize) = 3939: ($imageinfo =~ /^\Q$inputfile\E\s+\w+\s+(\d+x\d+)/); 3940: if ($fullsize) { 3941: ($fullwidth,$fullheight) = split(/x/,$fullsize); 3942: } 3943: } 3944: } 3945: return ($fullwidth,$fullheight); 3946: } 3947: 3948: sub check_configuser { 3949: my ($uhome,$dom,$confname,$servadm) = @_; 3950: my ($configuserok,%currroles); 3951: if ($uhome eq 'no_host') { 3952: srand( time() ^ ($$ + ($$ << 15)) ); # Seed rand. 3953: my $configpass = &LONCAPA::Enrollment::create_password(); 3954: $configuserok = 3955: &Apache::lonnet::modifyuser($dom,$confname,'','internal', 3956: $configpass,'','','','','',undef,$servadm); 3957: } else { 3958: $configuserok = 'ok'; 3959: %currroles = 3960: &Apache::lonnet::get_my_roles($confname,$dom,'userroles'); 3961: } 3962: return ($configuserok,%currroles); 3963: } 3964: 3965: sub check_authorstatus { 3966: my ($dom,$confname,%currroles) = @_; 3967: my $author_ok; 3968: if (!$currroles{':'.$dom.':au'}) { 3969: my $start = time; 3970: my $end = 0; 3971: $author_ok = 3972: &Apache::lonnet::assignrole($dom,$confname,'/'.$dom.'/', 3973: 'au',$end,$start,'','','domconfig'); 3974: } else { 3975: $author_ok = 'ok'; 3976: } 3977: return $author_ok; 3978: } 3979: 3980: sub publishlogo { 3981: my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_; 3982: my ($output,$fname,$logourl); 3983: if ($action eq 'upload') { 3984: $fname=$env{'form.'.$formname.'.filename'}; 3985: chop($env{'form.'.$formname}); 3986: } else { 3987: ($fname) = ($formname =~ /([^\/]+)$/); 3988: } 3989: if ($savefileas ne '') { 3990: $fname = $savefileas; 3991: } 3992: $fname=&Apache::lonnet::clean_filename($fname); 3993: # See if there is anything left 3994: unless ($fname) { return ('error: no uploaded file'); } 3995: $fname="$subdir/$fname"; 3996: my $filepath='/home/'.$confname.'/public_html'; 3997: my ($fnamepath,$file,$fetchthumb); 3998: $file=$fname; 3999: if ($fname=~m|/|) { 4000: ($fnamepath,$file) = ($fname =~ m|^(.*)/([^/]+)$|); 4001: } 4002: my @parts=split(/\//,$filepath.'/'.$fnamepath); 4003: my $count; 4004: for ($count=4;$count<=$#parts;$count++) { 4005: $filepath.="/$parts[$count]"; 4006: if ((-e $filepath)!=1) { 4007: mkdir($filepath,02770); 4008: } 4009: } 4010: # Check for bad extension and disallow upload 4011: if ($file=~/\.(\w+)$/ && 4012: (&Apache::loncommon::fileembstyle($1) eq 'hdn')) { 4013: $output = 4014: &mt('Invalid file extension ([_1]) - reserved for LONCAPA use.',$1); 4015: } elsif ($file=~/\.(\w+)$/ && 4016: !defined(&Apache::loncommon::fileembstyle($1))) { 4017: $output = &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1); 4018: } elsif ($file=~/\.(\d+)\.(\w+)$/) { 4019: $output = &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2); 4020: } elsif (-d "$filepath/$file") { 4021: $output = &mt('File name is a directory name - rename the file and re-upload'); 4022: } else { 4023: my $source = $filepath.'/'.$file; 4024: my $logfile; 4025: if (!open($logfile,">>$source".'.log')) { 4026: return (&mt('No write permission to Construction Space')); 4027: } 4028: print $logfile 4029: "\n================= Publish ".localtime()." ================\n". 4030: $env{'user.name'}.':'.$env{'user.domain'}."\n"; 4031: # Save the file 4032: if (!open(FH,'>'.$source)) { 4033: &Apache::lonnet::logthis('Failed to create '.$source); 4034: return (&mt('Failed to create file')); 4035: } 4036: if ($action eq 'upload') { 4037: if (!print FH ($env{'form.'.$formname})) { 4038: &Apache::lonnet::logthis('Failed to write to '.$source); 4039: return (&mt('Failed to write file')); 4040: } 4041: } else { 4042: my $original = &Apache::lonnet::filelocation('',$formname); 4043: if(!copy($original,$source)) { 4044: &Apache::lonnet::logthis('Failed to copy '.$original.' to '.$source); 4045: return (&mt('Failed to write file')); 4046: } 4047: } 4048: close(FH); 4049: chmod(0660, $source); # Permissions to rw-rw---. 4050: 4051: my $docroot=$r->dir_config('lonDocRoot'); 4052: my $targetdir=$docroot.'/res/'.$dom.'/'.$confname .'/'.$fnamepath; 4053: my $copyfile=$targetdir.'/'.$file; 4054: 4055: my @parts=split(/\//,$targetdir); 4056: my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]"; 4057: for (my $count=5;$count<=$#parts;$count++) { 4058: $path.="/$parts[$count]"; 4059: if (!-e $path) { 4060: print $logfile "\nCreating directory ".$path; 4061: mkdir($path,02770); 4062: } 4063: } 4064: my $versionresult; 4065: if (-e $copyfile) { 4066: $versionresult = &logo_versioning($targetdir,$file,$logfile); 4067: } else { 4068: $versionresult = 'ok'; 4069: } 4070: if ($versionresult eq 'ok') { 4071: if (copy($source,$copyfile)) { 4072: print $logfile "\nCopied original source to ".$copyfile."\n"; 4073: $output = 'ok'; 4074: &write_metadata($dom,$confname,$formname,$targetdir,$file,$logfile); 4075: $logourl = '/res/'.$dom.'/'.$confname.'/'.$fname; 4076: } else { 4077: print $logfile "\nUnable to write ".$copyfile.':'.$!."\n"; 4078: $output = &mt('Failed to copy file to RES space').", $!"; 4079: } 4080: if (($thumbwidth =~ /^\d+$/) && ($thumbheight =~ /^\d+$/)) { 4081: my $inputfile = $filepath.'/'.$file; 4082: my $outfile = $filepath.'/'.'tn-'.$file; 4083: my ($fullwidth,$fullheight) = &check_dimensions($inputfile); 4084: if ($fullwidth ne '' && $fullheight ne '') { 4085: if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) { 4086: my $thumbsize = $thumbwidth.'x'.$thumbheight; 4087: system("convert -sample $thumbsize $inputfile $outfile"); 4088: chmod(0660, $filepath.'/tn-'.$file); 4089: if (-e $outfile) { 4090: my $copyfile=$targetdir.'/tn-'.$file; 4091: if (copy($outfile,$copyfile)) { 4092: print $logfile "\nCopied source to ".$copyfile."\n"; 4093: &write_metadata($dom,$confname,$formname, 4094: $targetdir,'tn-'.$file,$logfile); 4095: } else { 4096: print $logfile "\nUnable to write ".$copyfile. 4097: ':'.$!."\n"; 4098: } 4099: } 4100: } 4101: } 4102: } 4103: } else { 4104: $output = $versionresult; 4105: } 4106: } 4107: return ($output,$logourl); 4108: } 4109: 4110: sub logo_versioning { 4111: my ($targetdir,$file,$logfile) = @_; 4112: my $target = $targetdir.'/'.$file; 4113: my ($maxversion,$fn,$extn,$output); 4114: $maxversion = 0; 4115: if ($file =~ /^(.+)\.(\w+)$/) { 4116: $fn=$1; 4117: $extn=$2; 4118: } 4119: opendir(DIR,$targetdir); 4120: while (my $filename=readdir(DIR)) { 4121: if ($filename=~/\Q$fn\E\.(\d+)\.\Q$extn\E$/) { 4122: $maxversion=($1>$maxversion)?$1:$maxversion; 4123: } 4124: } 4125: $maxversion++; 4126: print $logfile "\nCreating old version ".$maxversion."\n"; 4127: my $copyfile=$targetdir.'/'.$fn.'.'.$maxversion.'.'.$extn; 4128: if (copy($target,$copyfile)) { 4129: print $logfile "Copied old target to ".$copyfile."\n"; 4130: $copyfile=$copyfile.'.meta'; 4131: if (copy($target.'.meta',$copyfile)) { 4132: print $logfile "Copied old target metadata to ".$copyfile."\n"; 4133: $output = 'ok'; 4134: } else { 4135: print $logfile "Unable to write metadata ".$copyfile.':'.$!."\n"; 4136: $output = &mt('Failed to copy old meta').", $!, "; 4137: } 4138: } else { 4139: print $logfile "Unable to write ".$copyfile.':'.$!."\n"; 4140: $output = &mt('Failed to copy old target').", $!, "; 4141: } 4142: return $output; 4143: } 4144: 4145: sub write_metadata { 4146: my ($dom,$confname,$formname,$targetdir,$file,$logfile) = @_; 4147: my (%metadatafields,%metadatakeys,$output); 4148: $metadatafields{'title'}=$formname; 4149: $metadatafields{'creationdate'}=time; 4150: $metadatafields{'lastrevisiondate'}=time; 4151: $metadatafields{'copyright'}='public'; 4152: $metadatafields{'modifyinguser'}=$env{'user.name'}.':'. 4153: $env{'user.domain'}; 4154: $metadatafields{'authorspace'}=$confname.':'.$dom; 4155: $metadatafields{'domain'}=$dom; 4156: { 4157: print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file; 4158: my $mfh; 4159: unless (open($mfh,'>'.$targetdir.'/'.$file.'.meta')) { 4160: $output = &mt('Could not write metadata'); 4161: } 4162: foreach (sort keys %metadatafields) { 4163: unless ($_=~/\./) { 4164: my $unikey=$_; 4165: $unikey=~/^([A-Za-z]+)/; 4166: my $tag=$1; 4167: $tag=~tr/A-Z/a-z/; 4168: print $mfh "\n\<$tag"; 4169: foreach (split(/\,/,$metadatakeys{$unikey})) { 4170: my $value=$metadatafields{$unikey.'.'.$_}; 4171: $value=~s/\"/\'\'/g; 4172: print $mfh ' '.$_.'="'.$value.'"'; 4173: } 4174: print $mfh '>'. 4175: &HTML::Entities::encode($metadatafields{$unikey},'<>&"') 4176: .'</'.$tag.'>'; 4177: } 4178: } 4179: $output = 'ok'; 4180: print $logfile "\nWrote metadata"; 4181: close($mfh); 4182: } 4183: } 4184: 4185: sub check_switchserver { 4186: my ($dom,$confname) = @_; 4187: my ($allowed,$switchserver); 4188: my $home = &Apache::lonnet::homeserver($confname,$dom); 4189: if ($home eq 'no_host') { 4190: $home = &Apache::lonnet::domain($dom,'primary'); 4191: } 4192: my @ids=&Apache::lonnet::current_machine_ids(); 4193: foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } 4194: if (!$allowed) { 4195: $switchserver='<a href="/adm/switchserver?otherserver='.$home.'&role=dc./'.$dom.'/">'.&mt('Switch Server').'</a>'; 4196: } 4197: return $switchserver; 4198: } 4199: 4200: sub modify_quotas { 4201: my ($dom,$action,%domconfig) = @_; 4202: my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash, 4203: %limithash,$toolregexp,%conditions,$resulttext,%changes); 4204: if ($action eq 'quotas') { 4205: $context = 'tools'; 4206: } else { 4207: $context = $action; 4208: } 4209: if ($context eq 'requestcourses') { 4210: @usertools = ('official','unofficial','community'); 4211: @options =('norequest','approval','validate','autolimit'); 4212: %validations = &Apache::lonnet::auto_courserequest_checks($dom); 4213: %titles = &courserequest_titles(); 4214: $toolregexp = join('|',@usertools); 4215: %conditions = &courserequest_conditions(); 4216: } else { 4217: @usertools = ('aboutme','blog','portfolio'); 4218: %titles = &tool_titles(); 4219: } 4220: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 4221: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 4222: foreach my $key (keys(%env)) { 4223: if ($context eq 'requestcourses') { 4224: if ($key =~ /^form\.crsreq_($toolregexp)_(.+)$/) { 4225: my $item = $1; 4226: my $type = $2; 4227: if ($type =~ /^limit_(.+)/) { 4228: $limithash{$item}{$1} = $env{$key}; 4229: } else { 4230: $confhash{$item}{$type} = $env{$key}; 4231: } 4232: } 4233: } else { 4234: if ($key =~ /^form\.quota_(.+)$/) { 4235: $confhash{'defaultquota'}{$1} = $env{$key}; 4236: } 4237: if ($key =~ /^form\.\Q$context\E_(.+)$/) { 4238: @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key); 4239: } 4240: } 4241: } 4242: if ($context eq 'requestcourses') { 4243: my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify'); 4244: @approvalnotify = sort(@approvalnotify); 4245: $confhash{'notify'}{'approval'} = join(',',@approvalnotify); 4246: if (ref($domconfig{$action}) eq 'HASH') { 4247: if (ref($domconfig{$action}{'notify'}) eq 'HASH') { 4248: if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) { 4249: $changes{'notify'}{'approval'} = 1; 4250: } 4251: } else { 4252: if ($domconfig{$action}{'notify'}{'approval'}) { 4253: $changes{'notify'}{'approval'} = 1; 4254: } 4255: } 4256: } else { 4257: if ($domconfig{$action}{'notify'}{'approval'}) { 4258: $changes{'notify'}{'approval'} = 1; 4259: } 4260: } 4261: } else { 4262: $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'}; 4263: } 4264: foreach my $item (@usertools) { 4265: foreach my $type (@{$types},'default','_LC_adv') { 4266: my $unset; 4267: if ($context eq 'requestcourses') { 4268: $unset = '0'; 4269: if ($type eq '_LC_adv') { 4270: $unset = ''; 4271: } 4272: if ($confhash{$item}{$type} eq 'autolimit') { 4273: $confhash{$item}{$type} .= '='; 4274: unless ($limithash{$item}{$type} =~ /\D/) { 4275: $confhash{$item}{$type} .= $limithash{$item}{$type}; 4276: } 4277: } 4278: } else { 4279: if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) { 4280: $confhash{$item}{$type} = 1; 4281: } else { 4282: $confhash{$item}{$type} = 0; 4283: } 4284: } 4285: if (ref($domconfig{$action}) eq 'HASH') { 4286: if (ref($domconfig{$action}{$item}) eq 'HASH') { 4287: if ($domconfig{$action}{$item}{$type} ne $confhash{$item}{$type}) { 4288: $changes{$item}{$type} = 1; 4289: } 4290: } else { 4291: if ($context eq 'requestcourses') { 4292: if ($confhash{$item}{$type} ne $unset) { 4293: $changes{$item}{$type} = 1; 4294: } 4295: } else { 4296: if (!$confhash{$item}{$type}) { 4297: $changes{$item}{$type} = 1; 4298: } 4299: } 4300: } 4301: } else { 4302: if ($context eq 'requestcourses') { 4303: if ($confhash{$item}{$type} ne $unset) { 4304: $changes{$item}{$type} = 1; 4305: } 4306: } else { 4307: if (!$confhash{$item}{$type}) { 4308: $changes{$item}{$type} = 1; 4309: } 4310: } 4311: } 4312: } 4313: } 4314: unless ($context eq 'requestcourses') { 4315: if (ref($domconfig{'quotas'}) eq 'HASH') { 4316: if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') { 4317: foreach my $key (keys(%{$domconfig{'quotas'}{'defaultquota'}})) { 4318: if (exists($confhash{'defaultquota'}{$key})) { 4319: if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{'defaultquota'}{$key}) { 4320: $changes{'defaultquota'}{$key} = 1; 4321: } 4322: } else { 4323: $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{'defaultquota'}{$key}; 4324: } 4325: } 4326: } else { 4327: foreach my $key (keys(%{$domconfig{'quotas'}})) { 4328: if (exists($confhash{'defaultquota'}{$key})) { 4329: if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{$key}) { 4330: $changes{'defaultquota'}{$key} = 1; 4331: } 4332: } else { 4333: $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{$key}; 4334: } 4335: } 4336: } 4337: } 4338: if (ref($confhash{'defaultquota'}) eq 'HASH') { 4339: foreach my $key (keys(%{$confhash{'defaultquota'}})) { 4340: if (ref($domconfig{'quotas'}) eq 'HASH') { 4341: if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') { 4342: if (!exists($domconfig{'quotas'}{'defaultquota'}{$key})) { 4343: $changes{'defaultquota'}{$key} = 1; 4344: } 4345: } else { 4346: if (!exists($domconfig{'quotas'}{$key})) { 4347: $changes{'defaultquota'}{$key} = 1; 4348: } 4349: } 4350: } else { 4351: $changes{'defaultquota'}{$key} = 1; 4352: } 4353: } 4354: } 4355: } 4356: 4357: foreach my $key (keys(%confhash)) { 4358: $domdefaults{$key} = $confhash{$key}; 4359: } 4360: 4361: my %quotahash = ( 4362: $action => { %confhash } 4363: ); 4364: my $putresult = &Apache::lonnet::put_dom('configuration',\%quotahash, 4365: $dom); 4366: if ($putresult eq 'ok') { 4367: if (keys(%changes) > 0) { 4368: my $cachetime = 24*60*60; 4369: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); 4370: 4371: $resulttext = &mt('Changes made:').'<ul>'; 4372: unless ($context eq 'requestcourses') { 4373: if (ref($changes{'defaultquota'}) eq 'HASH') { 4374: $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>'; 4375: foreach my $type (@{$types},'default') { 4376: if (defined($changes{'defaultquota'}{$type})) { 4377: my $typetitle = $usertypes->{$type}; 4378: if ($type eq 'default') { 4379: $typetitle = $othertitle; 4380: } 4381: $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'defaultquota'}{$type}).'</li>'; 4382: } 4383: } 4384: $resulttext .= '</ul></li>'; 4385: } 4386: } 4387: my %newenv; 4388: foreach my $item (@usertools) { 4389: if (ref($changes{$item}) eq 'HASH') { 4390: my $newacc = 4391: &Apache::lonnet::usertools_access($env{'user.name'}, 4392: $env{'user.domain'}, 4393: $item,'reload',$context); 4394: if ($context eq 'requestcourses') { 4395: if ($env{'environment.canrequest.'.$item} ne $newacc) { 4396: $newenv{'environment.canrequest.'.$item} = $newacc; 4397: } 4398: } else { 4399: if ($env{'environment.availabletools.'.$item} ne $newacc) { 4400: $newenv{'environment.availabletools.'.$item} = $newacc; 4401: } 4402: } 4403: $resulttext .= '<li>'.$titles{$item}.'<ul>'; 4404: foreach my $type (@{$types},'default','_LC_adv') { 4405: if ($changes{$item}{$type}) { 4406: my $typetitle = $usertypes->{$type}; 4407: if ($type eq 'default') { 4408: $typetitle = $othertitle; 4409: } elsif ($type eq '_LC_adv') { 4410: $typetitle = 'LON-CAPA Advanced Users'; 4411: } 4412: if ($confhash{$item}{$type}) { 4413: if ($context eq 'requestcourses') { 4414: my $cond; 4415: if ($confhash{$item}{$type} =~ /^autolimit=(\d*)$/) { 4416: if ($1 eq '') { 4417: $cond = &mt('(Automatic processing of any request).'); 4418: } else { 4419: $cond = &mt('(Automatic processing of requests up to limit of [quant,_1,request] per user).',$1); 4420: } 4421: } else { 4422: $cond = $conditions{$confhash{$item}{$type}}; 4423: } 4424: $resulttext .= '<li>'.&mt('Set to be available to [_1].',$typetitle).' '.$cond.'</li>'; 4425: } else { 4426: $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>'; 4427: } 4428: } else { 4429: if ($type eq '_LC_adv') { 4430: if ($confhash{$item}{$type} eq '0') { 4431: $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>'; 4432: } else { 4433: $resulttext .= '<li>'.&mt('No override set for [_1]',$typetitle).'</li>'; 4434: } 4435: } else { 4436: $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>'; 4437: } 4438: } 4439: } 4440: } 4441: $resulttext .= '</ul></li>'; 4442: } 4443: } 4444: if ($action eq 'requestcourses') { 4445: if (ref($changes{'notify'}) eq 'HASH') { 4446: if ($changes{'notify'}{'approval'}) { 4447: if (ref($confhash{'notify'}) eq 'HASH') { 4448: if ($confhash{'notify'}{'approval'}) { 4449: $resulttext .= '<li>'.&mt('Notification of requests requiring approval will be sent to: ').$confhash{'notify'}{'approval'}.'</li>'; 4450: } else { 4451: $resulttext .= '<li>'.&mt('No Domain Coordinators will receive notification of course requests requiring approval.').'</li>'; 4452: } 4453: } 4454: } 4455: } 4456: } 4457: $resulttext .= '</ul>'; 4458: if (keys(%newenv)) { 4459: &Apache::lonnet::appenv(\%newenv); 4460: } 4461: } else { 4462: if ($context eq 'requestcourses') { 4463: $resulttext = &mt('No changes made to rights to request creation of courses.'); 4464: } else { 4465: $resulttext = &mt('No changes made to availability of personal information pages, blogs, portfolios or default quotas'); 4466: } 4467: } 4468: } else { 4469: $resulttext = '<span class="LC_error">'. 4470: &mt('An error occurred: [_1]',$putresult).'</span>'; 4471: } 4472: return $resulttext; 4473: } 4474: 4475: sub modify_autoenroll { 4476: my ($dom,%domconfig) = @_; 4477: my ($resulttext,%changes); 4478: my %currautoenroll; 4479: if (ref($domconfig{'autoenroll'}) eq 'HASH') { 4480: foreach my $key (keys(%{$domconfig{'autoenroll'}})) { 4481: $currautoenroll{$key} = $domconfig{'autoenroll'}{$key}; 4482: } 4483: } 4484: my $autorun = &Apache::lonnet::auto_run(undef,$dom), 4485: my %title = ( run => 'Auto-enrollment active', 4486: sender => 'Sender for notification messages'); 4487: my @offon = ('off','on'); 4488: my $sender_uname = $env{'form.sender_uname'}; 4489: my $sender_domain = $env{'form.sender_domain'}; 4490: if ($sender_domain eq '') { 4491: $sender_uname = ''; 4492: } elsif ($sender_uname eq '') { 4493: $sender_domain = ''; 4494: } 4495: my %autoenrollhash = ( 4496: autoenroll => { run => $env{'form.autoenroll_run'}, 4497: sender_uname => $sender_uname, 4498: sender_domain => $sender_domain, 4499: 4500: } 4501: ); 4502: my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash, 4503: $dom); 4504: if ($putresult eq 'ok') { 4505: if (exists($currautoenroll{'run'})) { 4506: if ($currautoenroll{'run'} ne $env{'form.autoenroll_run'}) { 4507: $changes{'run'} = 1; 4508: } 4509: } elsif ($autorun) { 4510: if ($env{'form.autoenroll_run'} ne '1') { 4511: $changes{'run'} = 1; 4512: } 4513: } 4514: if ($currautoenroll{'sender_uname'} ne $sender_uname) { 4515: $changes{'sender'} = 1; 4516: } 4517: if ($currautoenroll{'sender_domain'} ne $sender_domain) { 4518: $changes{'sender'} = 1; 4519: } 4520: if (keys(%changes) > 0) { 4521: $resulttext = &mt('Changes made:').'<ul>'; 4522: if ($changes{'run'}) { 4523: $resulttext .= '<li>'.&mt("$title{'run'} set to $offon[$env{'form.autoenroll_run'}]").'</li>'; 4524: } 4525: if ($changes{'sender'}) { 4526: if ($sender_uname eq '' || $sender_domain eq '') { 4527: $resulttext .= '<li>'.&mt("$title{'sender'} set to default (course owner).").'</li>'; 4528: } else { 4529: $resulttext .= '<li>'.&mt("$title{'sender'} set to [_1]",$sender_uname.':'.$sender_domain).'</li>'; 4530: } 4531: } 4532: $resulttext .= '</ul>'; 4533: } else { 4534: $resulttext = &mt('No changes made to auto-enrollment settings'); 4535: } 4536: } else { 4537: $resulttext = '<span class="LC_error">'. 4538: &mt('An error occurred: [_1]',$putresult).'</span>'; 4539: } 4540: return $resulttext; 4541: } 4542: 4543: sub modify_autoupdate { 4544: my ($dom,%domconfig) = @_; 4545: my ($resulttext,%currautoupdate,%fields,%changes); 4546: if (ref($domconfig{'autoupdate'}) eq 'HASH') { 4547: foreach my $key (keys(%{$domconfig{'autoupdate'}})) { 4548: $currautoupdate{$key} = $domconfig{'autoupdate'}{$key}; 4549: } 4550: } 4551: my @offon = ('off','on'); 4552: my %title = &Apache::lonlocal::texthash ( 4553: run => 'Auto-update:', 4554: classlists => 'Updates to user information in classlists?' 4555: ); 4556: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 4557: my %fieldtitles = &Apache::lonlocal::texthash ( 4558: id => 'Student/Employee ID', 4559: permanentemail => 'E-mail address', 4560: lastname => 'Last Name', 4561: firstname => 'First Name', 4562: middlename => 'Middle Name', 4563: gen => 'Generation', 4564: ); 4565: my $othertitle = &mt('All users'); 4566: if (keys(%{$usertypes}) > 0) { 4567: $othertitle = &mt('Other users'); 4568: } 4569: foreach my $key (keys(%env)) { 4570: if ($key =~ /^form\.updateable_(.+)_([^_]+)$/) { 4571: push(@{$fields{$1}},$2); 4572: } 4573: } 4574: my %updatehash = ( 4575: autoupdate => { run => $env{'form.autoupdate_run'}, 4576: classlists => $env{'form.classlists'}, 4577: fields => {%fields}, 4578: } 4579: ); 4580: foreach my $key (keys(%currautoupdate)) { 4581: if (($key eq 'run') || ($key eq 'classlists')) { 4582: if (exists($updatehash{autoupdate}{$key})) { 4583: if ($currautoupdate{$key} ne $updatehash{autoupdate}{$key}) { 4584: $changes{$key} = 1; 4585: } 4586: } 4587: } elsif ($key eq 'fields') { 4588: if (ref($currautoupdate{$key}) eq 'HASH') { 4589: foreach my $item (@{$types},'default') { 4590: if (ref($currautoupdate{$key}{$item}) eq 'ARRAY') { 4591: my $change = 0; 4592: foreach my $type (@{$currautoupdate{$key}{$item}}) { 4593: if (!exists($fields{$item})) { 4594: $change = 1; 4595: } elsif (ref($fields{$item}) eq 'ARRAY') { 4596: if (!grep(/^\Q$type\E$/,@{$fields{$item}})) { 4597: $change = 1; 4598: } 4599: } 4600: } 4601: if ($change) { 4602: push(@{$changes{$key}},$item); 4603: } 4604: } 4605: } 4606: } 4607: } 4608: } 4609: foreach my $item (@{$types},'default') { 4610: if (defined($fields{$item})) { 4611: if (ref($currautoupdate{'fields'}) eq 'HASH') { 4612: if (!exists($currautoupdate{'fields'}{$item})) { 4613: push(@{$changes{'fields'}},$item); 4614: } 4615: } else { 4616: push(@{$changes{'fields'}},$item); 4617: } 4618: } 4619: } 4620: my $putresult = &Apache::lonnet::put_dom('configuration',\%updatehash, 4621: $dom); 4622: if ($putresult eq 'ok') { 4623: if (keys(%changes) > 0) { 4624: $resulttext = &mt('Changes made:').'<ul>'; 4625: foreach my $key (sort(keys(%changes))) { 4626: if (ref($changes{$key}) eq 'ARRAY') { 4627: foreach my $item (@{$changes{$key}}) { 4628: my @newvalues; 4629: foreach my $type (@{$fields{$item}}) { 4630: push(@newvalues,$fieldtitles{$type}); 4631: } 4632: my $newvaluestr; 4633: if (@newvalues > 0) { 4634: $newvaluestr = join(', ',@newvalues); 4635: } else { 4636: $newvaluestr = &mt('none'); 4637: } 4638: if ($item eq 'default') { 4639: $resulttext .= '<li>'.&mt("Updates for '[_1]' set to: '[_2]'",$othertitle,$newvaluestr).'</li>'; 4640: } else { 4641: $resulttext .= '<li>'.&mt("Updates for '[_1]' set to: '[_2]'",$usertypes->{$item},$newvaluestr).'</li>'; 4642: } 4643: } 4644: } else { 4645: my $newvalue; 4646: if ($key eq 'run') { 4647: $newvalue = $offon[$env{'form.autoupdate_run'}]; 4648: } else { 4649: $newvalue = $offon[$env{'form.'.$key}]; 4650: } 4651: $resulttext .= '<li>'.&mt("[_1] set to $newvalue",$title{$key}).'</li>'; 4652: } 4653: } 4654: $resulttext .= '</ul>'; 4655: } else { 4656: $resulttext = &mt('No changes made to autoupdates'); 4657: } 4658: } else { 4659: $resulttext = '<span class="LC_error">'. 4660: &mt('An error occurred: [_1]',$putresult).'</span>'; 4661: } 4662: return $resulttext; 4663: } 4664: 4665: sub modify_directorysrch { 4666: my ($dom,%domconfig) = @_; 4667: my ($resulttext,%changes); 4668: my %currdirsrch; 4669: if (ref($domconfig{'directorysrch'}) eq 'HASH') { 4670: foreach my $key (keys(%{$domconfig{'directorysrch'}})) { 4671: $currdirsrch{$key} = $domconfig{'directorysrch'}{$key}; 4672: } 4673: } 4674: my %title = ( available => 'Directory search available', 4675: localonly => 'Other domains can search', 4676: searchby => 'Search types', 4677: searchtypes => 'Search latitude'); 4678: my @offon = ('off','on'); 4679: my @otherdoms = ('Yes','No'); 4680: 4681: my @searchtypes = &Apache::loncommon::get_env_multiple('form.searchtypes'); 4682: my @cansearch = &Apache::loncommon::get_env_multiple('form.cansearch'); 4683: my @searchby = &Apache::loncommon::get_env_multiple('form.searchby'); 4684: 4685: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 4686: if (keys(%{$usertypes}) == 0) { 4687: @cansearch = ('default'); 4688: } else { 4689: if (ref($currdirsrch{'cansearch'}) eq 'ARRAY') { 4690: foreach my $type (@{$currdirsrch{'cansearch'}}) { 4691: if (!grep(/^\Q$type\E$/,@cansearch)) { 4692: push(@{$changes{'cansearch'}},$type); 4693: } 4694: } 4695: foreach my $type (@cansearch) { 4696: if (!grep(/^\Q$type\E$/,@{$currdirsrch{'cansearch'}})) { 4697: push(@{$changes{'cansearch'}},$type); 4698: } 4699: } 4700: } else { 4701: push(@{$changes{'cansearch'}},@cansearch); 4702: } 4703: } 4704: 4705: if (ref($currdirsrch{'searchby'}) eq 'ARRAY') { 4706: foreach my $by (@{$currdirsrch{'searchby'}}) { 4707: if (!grep(/^\Q$by\E$/,@searchby)) { 4708: push(@{$changes{'searchby'}},$by); 4709: } 4710: } 4711: foreach my $by (@searchby) { 4712: if (!grep(/^\Q$by\E$/,@{$currdirsrch{'searchby'}})) { 4713: push(@{$changes{'searchby'}},$by); 4714: } 4715: } 4716: } else { 4717: push(@{$changes{'searchby'}},@searchby); 4718: } 4719: 4720: if (ref($currdirsrch{'searchtypes'}) eq 'ARRAY') { 4721: foreach my $type (@{$currdirsrch{'searchtypes'}}) { 4722: if (!grep(/^\Q$type\E$/,@searchtypes)) { 4723: push(@{$changes{'searchtypes'}},$type); 4724: } 4725: } 4726: foreach my $type (@searchtypes) { 4727: if (!grep(/^\Q$type\E$/,@{$currdirsrch{'searchtypes'}})) { 4728: push(@{$changes{'searchtypes'}},$type); 4729: } 4730: } 4731: } else { 4732: if (exists($currdirsrch{'searchtypes'})) { 4733: foreach my $type (@searchtypes) { 4734: if ($type ne $currdirsrch{'searchtypes'}) { 4735: push(@{$changes{'searchtypes'}},$type); 4736: } 4737: } 4738: if (!grep(/^\Q$currdirsrch{'searchtypes'}\E/,@searchtypes)) { 4739: push(@{$changes{'searchtypes'}},$currdirsrch{'searchtypes'}); 4740: } 4741: } else { 4742: push(@{$changes{'searchtypes'}},@searchtypes); 4743: } 4744: } 4745: 4746: my %dirsrch_hash = ( 4747: directorysrch => { available => $env{'form.dirsrch_available'}, 4748: cansearch => \@cansearch, 4749: localonly => $env{'form.dirsrch_localonly'}, 4750: searchby => \@searchby, 4751: searchtypes => \@searchtypes, 4752: } 4753: ); 4754: my $putresult = &Apache::lonnet::put_dom('configuration',\%dirsrch_hash, 4755: $dom); 4756: if ($putresult eq 'ok') { 4757: if (exists($currdirsrch{'available'})) { 4758: if ($currdirsrch{'available'} ne $env{'form.dirsrch_available'}) { 4759: $changes{'available'} = 1; 4760: } 4761: } else { 4762: if ($env{'form.dirsrch_available'} eq '1') { 4763: $changes{'available'} = 1; 4764: } 4765: } 4766: if (exists($currdirsrch{'localonly'})) { 4767: if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_localonly'}) { 4768: $changes{'localonly'} = 1; 4769: } 4770: } else { 4771: if ($env{'form.dirsrch_localonly'} eq '1') { 4772: $changes{'localonly'} = 1; 4773: } 4774: } 4775: if (keys(%changes) > 0) { 4776: $resulttext = &mt('Changes made:').'<ul>'; 4777: if ($changes{'available'}) { 4778: $resulttext .= '<li>'.&mt("$title{'available'} set to: $offon[$env{'form.dirsrch_available'}]").'</li>'; 4779: } 4780: if ($changes{'localonly'}) { 4781: $resulttext .= '<li>'.&mt("$title{'localonly'} set to: $otherdoms[$env{'form.dirsrch_localonly'}]").'</li>'; 4782: } 4783: 4784: if (ref($changes{'cansearch'}) eq 'ARRAY') { 4785: my $chgtext; 4786: if (ref($usertypes) eq 'HASH') { 4787: if (keys(%{$usertypes}) > 0) { 4788: foreach my $type (@{$types}) { 4789: if (grep(/^\Q$type\E$/,@cansearch)) { 4790: $chgtext .= $usertypes->{$type}.'; '; 4791: } 4792: } 4793: if (grep(/^default$/,@cansearch)) { 4794: $chgtext .= $othertitle; 4795: } else { 4796: $chgtext =~ s/\; $//; 4797: } 4798: $resulttext .= '<li>'.&mt("Users from domain '<span class=\"LC_cusr_emph\">[_1]</span>' permitted to search the institutional directory set to: [_2]",$dom,$chgtext).'</li>'; 4799: } 4800: } 4801: } 4802: if (ref($changes{'searchby'}) eq 'ARRAY') { 4803: my ($searchtitles,$titleorder) = &sorted_searchtitles(); 4804: my $chgtext; 4805: foreach my $type (@{$titleorder}) { 4806: if (grep(/^\Q$type\E$/,@searchby)) { 4807: if (defined($searchtitles->{$type})) { 4808: $chgtext .= $searchtitles->{$type}.'; '; 4809: } 4810: } 4811: } 4812: $chgtext =~ s/\; $//; 4813: $resulttext .= '<li>'.&mt("$title{'searchby'} set to: [_1]",$chgtext).'</li>'; 4814: } 4815: if (ref($changes{'searchtypes'}) eq 'ARRAY') { 4816: my ($srchtypes_desc,$srchtypeorder) = &sorted_searchtypes(); 4817: my $chgtext; 4818: foreach my $type (@{$srchtypeorder}) { 4819: if (grep(/^\Q$type\E$/,@searchtypes)) { 4820: if (defined($srchtypes_desc->{$type})) { 4821: $chgtext .= $srchtypes_desc->{$type}.'; '; 4822: } 4823: } 4824: } 4825: $chgtext =~ s/\; $//; 4826: $resulttext .= '<li>'.&mt("$title{'searchtypes'} set to: \"[_1]\"",$chgtext).'</li>'; 4827: } 4828: $resulttext .= '</ul>'; 4829: } else { 4830: $resulttext = &mt('No changes made to institution directory search settings'); 4831: } 4832: } else { 4833: $resulttext = '<span class="LC_error">'. 4834: &mt('An error occurred: [_1]',$putresult).'</span>'; 4835: } 4836: return $resulttext; 4837: } 4838: 4839: sub modify_contacts { 4840: my ($dom,%domconfig) = @_; 4841: my ($resulttext,%currsetting,%newsetting,%changes,%contacts_hash); 4842: if (ref($domconfig{'contacts'}) eq 'HASH') { 4843: foreach my $key (keys(%{$domconfig{'contacts'}})) { 4844: $currsetting{$key} = $domconfig{'contacts'}{$key}; 4845: } 4846: } 4847: my (%others,%to); 4848: my @contacts = ('supportemail','adminemail'); 4849: my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail', 4850: 'requestsmail'); 4851: foreach my $type (@mailings) { 4852: @{$newsetting{$type}} = 4853: &Apache::loncommon::get_env_multiple('form.'.$type); 4854: foreach my $item (@contacts) { 4855: if (grep(/^\Q$item\E$/,@{$newsetting{$type}})) { 4856: $contacts_hash{contacts}{$type}{$item} = 1; 4857: } else { 4858: $contacts_hash{contacts}{$type}{$item} = 0; 4859: } 4860: } 4861: $others{$type} = $env{'form.'.$type.'_others'}; 4862: $contacts_hash{contacts}{$type}{'others'} = $others{$type}; 4863: } 4864: foreach my $item (@contacts) { 4865: $to{$item} = $env{'form.'.$item}; 4866: $contacts_hash{'contacts'}{$item} = $to{$item}; 4867: } 4868: if (keys(%currsetting) > 0) { 4869: foreach my $item (@contacts) { 4870: if ($to{$item} ne $currsetting{$item}) { 4871: $changes{$item} = 1; 4872: } 4873: } 4874: foreach my $type (@mailings) { 4875: foreach my $item (@contacts) { 4876: if (ref($currsetting{$type}) eq 'HASH') { 4877: if ($currsetting{$type}{$item} ne $contacts_hash{contacts}{$type}{$item}) { 4878: push(@{$changes{$type}},$item); 4879: } 4880: } else { 4881: push(@{$changes{$type}},@{$newsetting{$type}}); 4882: } 4883: } 4884: if ($others{$type} ne $currsetting{$type}{'others'}) { 4885: push(@{$changes{$type}},'others'); 4886: } 4887: } 4888: } else { 4889: my %default; 4890: $default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'}; 4891: $default{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'}; 4892: $default{'errormail'} = 'adminemail'; 4893: $default{'packagesmail'} = 'adminemail'; 4894: $default{'helpdeskmail'} = 'supportemail'; 4895: $default{'lonstatusmail'} = 'adminemail'; 4896: $default{'requestsmail'} = 'adminemail'; 4897: foreach my $item (@contacts) { 4898: if ($to{$item} ne $default{$item}) { 4899: $changes{$item} = 1; 4900: } 4901: } 4902: foreach my $type (@mailings) { 4903: if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) { 4904: 4905: push(@{$changes{$type}},@{$newsetting{$type}}); 4906: } 4907: if ($others{$type} ne '') { 4908: push(@{$changes{$type}},'others'); 4909: } 4910: } 4911: } 4912: my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash, 4913: $dom); 4914: if ($putresult eq 'ok') { 4915: if (keys(%changes) > 0) { 4916: my ($titles,$short_titles) = &contact_titles(); 4917: $resulttext = &mt('Changes made:').'<ul>'; 4918: foreach my $item (@contacts) { 4919: if ($changes{$item}) { 4920: $resulttext .= '<li>'.$titles->{$item}. 4921: &mt(' set to: '). 4922: '<span class="LC_cusr_emph">'. 4923: $to{$item}.'</span></li>'; 4924: } 4925: } 4926: foreach my $type (@mailings) { 4927: if (ref($changes{$type}) eq 'ARRAY') { 4928: $resulttext .= '<li>'.$titles->{$type}.': '; 4929: my @text; 4930: foreach my $item (@{$newsetting{$type}}) { 4931: push(@text,$short_titles->{$item}); 4932: } 4933: if ($others{$type} ne '') { 4934: push(@text,$others{$type}); 4935: } 4936: $resulttext .= '<span class="LC_cusr_emph">'. 4937: join(', ',@text).'</span></li>'; 4938: } 4939: } 4940: $resulttext .= '</ul>'; 4941: } else { 4942: $resulttext = &mt('No changes made to contact information'); 4943: } 4944: } else { 4945: $resulttext = '<span class="LC_error">'. 4946: &mt('An error occurred: [_1].',$putresult).'</span>'; 4947: } 4948: return $resulttext; 4949: } 4950: 4951: sub modify_usercreation { 4952: my ($dom,%domconfig) = @_; 4953: my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate); 4954: my $warningmsg; 4955: if (ref($domconfig{'usercreation'}) eq 'HASH') { 4956: foreach my $key (keys(%{$domconfig{'usercreation'}})) { 4957: $curr_usercreation{$key} = $domconfig{'usercreation'}{$key}; 4958: } 4959: } 4960: my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule'); 4961: my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule'); 4962: my @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule'); 4963: my @contexts = ('author','course','requestcrs','selfcreate'); 4964: foreach my $item(@contexts) { 4965: if ($item eq 'selfcreate') { 4966: @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item); 4967: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 4968: if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) { 4969: if (ref($cancreate{$item}) eq 'ARRAY') { 4970: if (grep(/^login$/,@{$cancreate{$item}})) { 4971: $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.').' '.&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.'); 4972: } 4973: } 4974: } 4975: } else { 4976: $cancreate{$item} = $env{'form.can_createuser_'.$item}; 4977: } 4978: } 4979: my ($othertitle,$usertypes,$types) = 4980: &Apache::loncommon::sorted_inst_types($dom); 4981: if (ref($types) eq 'ARRAY') { 4982: if (@{$types} > 0) { 4983: @{$cancreate{'statustocreate'}} = 4984: &Apache::loncommon::get_env_multiple('form.statustocreate'); 4985: } else { 4986: @{$cancreate{'statustocreate'}} = (); 4987: } 4988: push(@contexts,'statustocreate'); 4989: } 4990: if (ref($curr_usercreation{'cancreate'}) eq 'HASH') { 4991: foreach my $item (@contexts) { 4992: if (($item eq 'selfcreate') || ($item eq 'statustocreate')) { 4993: if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') { 4994: foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) { 4995: if (ref($cancreate{$item}) eq 'ARRAY') { 4996: if (!grep(/^$curr$/,@{$cancreate{$item}})) { 4997: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 4998: push(@{$changes{'cancreate'}},$item); 4999: } 5000: } 5001: } 5002: } 5003: } else { 5004: if ($curr_usercreation{'cancreate'}{$item} eq '') { 5005: if (@{$cancreate{$item}} > 0) { 5006: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5007: push(@{$changes{'cancreate'}},$item); 5008: } 5009: } 5010: } else { 5011: if ($curr_usercreation{'cancreate'}{$item} eq 'any') { 5012: if (@{$cancreate{$item}} < 3) { 5013: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5014: push(@{$changes{'cancreate'}},$item); 5015: } 5016: } 5017: } elsif ($curr_usercreation{'cancreate'}{$item} eq 'none') { 5018: if (@{$cancreate{$item}} > 0) { 5019: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5020: push(@{$changes{'cancreate'}},$item); 5021: } 5022: } 5023: } elsif (!grep(/^$curr_usercreation{'cancreate'}{$item}$/,@{$cancreate{$item}})) { 5024: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5025: push(@{$changes{'cancreate'}},$item); 5026: } 5027: } 5028: } 5029: } 5030: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5031: foreach my $type (@{$cancreate{$item}}) { 5032: if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') { 5033: if (!grep(/^$type$/,@{$curr_usercreation{'cancreate'}{$item}})) { 5034: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5035: push(@{$changes{'cancreate'}},$item); 5036: } 5037: } 5038: } elsif (($curr_usercreation{'cancreate'}{$item} ne 'any') && 5039: ($curr_usercreation{'cancreate'}{$item} ne 'none')) { 5040: if ($curr_usercreation{'cancreate'}{$item} ne $type) { 5041: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5042: push(@{$changes{'cancreate'}},$item); 5043: } 5044: } 5045: } 5046: } 5047: } 5048: } else { 5049: if ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) { 5050: push(@{$changes{'cancreate'}},$item); 5051: } 5052: } 5053: } 5054: } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') { 5055: foreach my $item (@contexts) { 5056: if (!grep(/^\Q$item\E$/,@{$curr_usercreation{'cancreate'}})) { 5057: if ($cancreate{$item} ne 'any') { 5058: push(@{$changes{'cancreate'}},$item); 5059: } 5060: } else { 5061: if ($cancreate{$item} ne 'none') { 5062: push(@{$changes{'cancreate'}},$item); 5063: } 5064: } 5065: } 5066: } else { 5067: foreach my $item (@contexts) { 5068: push(@{$changes{'cancreate'}},$item); 5069: } 5070: } 5071: 5072: if (ref($curr_usercreation{'username_rule'}) eq 'ARRAY') { 5073: foreach my $type (@{$curr_usercreation{'username_rule'}}) { 5074: if (!grep(/^\Q$type\E$/,@username_rule)) { 5075: push(@{$changes{'username_rule'}},$type); 5076: } 5077: } 5078: foreach my $type (@username_rule) { 5079: if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'username_rule'}})) { 5080: push(@{$changes{'username_rule'}},$type); 5081: } 5082: } 5083: } else { 5084: push(@{$changes{'username_rule'}},@username_rule); 5085: } 5086: 5087: if (ref($curr_usercreation{'id_rule'}) eq 'ARRAY') { 5088: foreach my $type (@{$curr_usercreation{'id_rule'}}) { 5089: if (!grep(/^\Q$type\E$/,@id_rule)) { 5090: push(@{$changes{'id_rule'}},$type); 5091: } 5092: } 5093: foreach my $type (@id_rule) { 5094: if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'id_rule'}})) { 5095: push(@{$changes{'id_rule'}},$type); 5096: } 5097: } 5098: } else { 5099: push(@{$changes{'id_rule'}},@id_rule); 5100: } 5101: 5102: if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') { 5103: foreach my $type (@{$curr_usercreation{'email_rule'}}) { 5104: if (!grep(/^\Q$type\E$/,@email_rule)) { 5105: push(@{$changes{'email_rule'}},$type); 5106: } 5107: } 5108: foreach my $type (@email_rule) { 5109: if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) { 5110: push(@{$changes{'email_rule'}},$type); 5111: } 5112: } 5113: } else { 5114: push(@{$changes{'email_rule'}},@email_rule); 5115: } 5116: 5117: my @authen_contexts = ('author','course','domain'); 5118: my @authtypes = ('int','krb4','krb5','loc'); 5119: my %authhash; 5120: foreach my $item (@authen_contexts) { 5121: my @authallowed = &Apache::loncommon::get_env_multiple('form.'.$item.'_auth'); 5122: foreach my $auth (@authtypes) { 5123: if (grep(/^\Q$auth\E$/,@authallowed)) { 5124: $authhash{$item}{$auth} = 1; 5125: } else { 5126: $authhash{$item}{$auth} = 0; 5127: } 5128: } 5129: } 5130: if (ref($curr_usercreation{'authtypes'}) eq 'HASH') { 5131: foreach my $item (@authen_contexts) { 5132: if (ref($curr_usercreation{'authtypes'}{$item}) eq 'HASH') { 5133: foreach my $auth (@authtypes) { 5134: if ($authhash{$item}{$auth} ne $curr_usercreation{'authtypes'}{$item}{$auth}) { 5135: push(@{$changes{'authtypes'}},$item); 5136: last; 5137: } 5138: } 5139: } 5140: } 5141: } else { 5142: foreach my $item (@authen_contexts) { 5143: push(@{$changes{'authtypes'}},$item); 5144: } 5145: } 5146: 5147: my %usercreation_hash = ( 5148: usercreation => { 5149: cancreate => \%cancreate, 5150: username_rule => \@username_rule, 5151: id_rule => \@id_rule, 5152: email_rule => \@email_rule, 5153: authtypes => \%authhash, 5154: } 5155: ); 5156: 5157: my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash, 5158: $dom); 5159: 5160: my %selfcreatetypes = ( 5161: sso => 'users authenticated by institutional single sign on', 5162: login => 'users authenticated by institutional log-in', 5163: email => 'users who provide a valid e-mail address for use as the username', 5164: ); 5165: if ($putresult eq 'ok') { 5166: if (keys(%changes) > 0) { 5167: $resulttext = &mt('Changes made:').'<ul>'; 5168: if (ref($changes{'cancreate'}) eq 'ARRAY') { 5169: my %lt = &usercreation_types(); 5170: foreach my $type (@{$changes{'cancreate'}}) { 5171: my $chgtext; 5172: unless ($type eq 'statustocreate') { 5173: $chgtext = $lt{$type}.', '; 5174: } 5175: if ($type eq 'selfcreate') { 5176: if (@{$cancreate{$type}} == 0) { 5177: $chgtext .= &mt('creation of a new user account is not permitted.'); 5178: } else { 5179: $chgtext .= &mt('creation of a new account is permitted for:').'<ul>'; 5180: foreach my $case (@{$cancreate{$type}}) { 5181: $chgtext .= '<li>'.$selfcreatetypes{$case}.'</li>'; 5182: } 5183: $chgtext .= '</ul>'; 5184: if (ref($cancreate{$type}) eq 'ARRAY') { 5185: if (grep(/^(login|sso)$/,@{$cancreate{$type}})) { 5186: if (ref($cancreate{'statustocreate'}) eq 'ARRAY') { 5187: if (@{$cancreate{'statustocreate'}} == 0) { 5188: $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>'; 5189: } 5190: } 5191: } 5192: } 5193: } 5194: } elsif ($type eq 'statustocreate') { 5195: if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') && 5196: (ref($cancreate{'statustocreate'}) eq 'ARRAY')) { 5197: if (@{$cancreate{'selfcreate'}} > 0) { 5198: if (@{$cancreate{'statustocreate'}} == 0) { 5199: 5200: $chgtext .= &mt("Institutional affiliations permitted to create accounts set to 'None'."); 5201: if (!grep(/^email$/,@{$cancreate{'selfcreate'}})) { 5202: $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>'; 5203: } 5204: } elsif (ref($usertypes) eq 'HASH') { 5205: if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) { 5206: $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):'); 5207: } else { 5208: $chgtext .= &mt('Institutional affiliations permitted to create accounts with institutional authentication were set as follows:'); 5209: } 5210: $chgtext .= '<ul>'; 5211: foreach my $case (@{$cancreate{$type}}) { 5212: if ($case eq 'default') { 5213: $chgtext .= '<li>'.$othertitle.'</li>'; 5214: } else { 5215: $chgtext .= '<li>'.$usertypes->{$case}.'</li>'; 5216: } 5217: } 5218: $chgtext .= '</ul>'; 5219: if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) { 5220: $chgtext .= '<br /><span class="LC_warning">'.&mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').'</span>'; 5221: } 5222: } 5223: } else { 5224: if (@{$cancreate{$type}} == 0) { 5225: $chgtext .= &mt("Institutional affiliations permitted to create accounts were set to 'none'."); 5226: } else { 5227: $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.'); 5228: } 5229: } 5230: } 5231: } else { 5232: if ($cancreate{$type} eq 'none') { 5233: $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.'); 5234: } elsif ($cancreate{$type} eq 'any') { 5235: $chgtext .= &mt('creation of new users is permitted for both institutional and non-institutional usernames.'); 5236: } elsif ($cancreate{$type} eq 'official') { 5237: $chgtext .= &mt('creation of new users is only permitted for institutional usernames.'); 5238: } elsif ($cancreate{$type} eq 'unofficial') { 5239: $chgtext .= &mt('creation of new users is only permitted for non-institutional usernames.'); 5240: } 5241: } 5242: $resulttext .= '<li>'.$chgtext.'</li>'; 5243: } 5244: } 5245: if (ref($changes{'username_rule'}) eq 'ARRAY') { 5246: my ($rules,$ruleorder) = 5247: &Apache::lonnet::inst_userrules($dom,'username'); 5248: my $chgtext = '<ul>'; 5249: foreach my $type (@username_rule) { 5250: if (ref($rules->{$type}) eq 'HASH') { 5251: $chgtext .= '<li>'.$rules->{$type}{'name'}.'</li>'; 5252: } 5253: } 5254: $chgtext .= '</ul>'; 5255: if (@username_rule > 0) { 5256: $resulttext .= '<li>'.&mt('Usernames with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>'; 5257: } else { 5258: $resulttext .= '<li>'.&mt('There are now no username formats restricted to verified users in the institutional directory.').'</li>'; 5259: } 5260: } 5261: if (ref($changes{'id_rule'}) eq 'ARRAY') { 5262: my ($idrules,$idruleorder) = 5263: &Apache::lonnet::inst_userrules($dom,'id'); 5264: my $chgtext = '<ul>'; 5265: foreach my $type (@id_rule) { 5266: if (ref($idrules->{$type}) eq 'HASH') { 5267: $chgtext .= '<li>'.$idrules->{$type}{'name'}.'</li>'; 5268: } 5269: } 5270: $chgtext .= '</ul>'; 5271: if (@id_rule > 0) { 5272: $resulttext .= '<li>'.&mt('IDs with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>'; 5273: } else { 5274: $resulttext .= '<li>'.&mt('There are now no ID formats restricted to verified users in the institutional directory.').'</li>'; 5275: } 5276: } 5277: if (ref($changes{'email_rule'}) eq 'ARRAY') { 5278: my ($emailrules,$emailruleorder) = 5279: &Apache::lonnet::inst_userrules($dom,'email'); 5280: my $chgtext = '<ul>'; 5281: foreach my $type (@email_rule) { 5282: if (ref($emailrules->{$type}) eq 'HASH') { 5283: $chgtext .= '<li>'.$emailrules->{$type}{'name'}.'</li>'; 5284: } 5285: } 5286: $chgtext .= '</ul>'; 5287: if (@email_rule > 0) { 5288: $resulttext .= '<li>'.&mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').$chgtext.'</li>'; 5289: } else { 5290: $resulttext .= '<li>'.&mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').'</li>'; 5291: } 5292: } 5293: 5294: my %authname = &authtype_names(); 5295: my %context_title = &context_names(); 5296: if (ref($changes{'authtypes'}) eq 'ARRAY') { 5297: my $chgtext = '<ul>'; 5298: foreach my $type (@{$changes{'authtypes'}}) { 5299: my @allowed; 5300: $chgtext .= '<li><span class="LC_cusr_emph">'.$context_title{$type}.'</span> - '.&mt('assignable authentication types: '); 5301: foreach my $auth (@authtypes) { 5302: if ($authhash{$type}{$auth}) { 5303: push(@allowed,$authname{$auth}); 5304: } 5305: } 5306: if (@allowed > 0) { 5307: $chgtext .= join(', ',@allowed).'</li>'; 5308: } else { 5309: $chgtext .= &mt('none').'</li>'; 5310: } 5311: } 5312: $chgtext .= '</ul>'; 5313: $resulttext .= '<li>'.&mt('Authentication types available for assignment to new users').'<br />'.$chgtext; 5314: $resulttext .= '</li>'; 5315: } 5316: $resulttext .= '</ul>'; 5317: } else { 5318: $resulttext = &mt('No changes made to user creation settings'); 5319: } 5320: } else { 5321: $resulttext = '<span class="LC_error">'. 5322: &mt('An error occurred: [_1]',$putresult).'</span>'; 5323: } 5324: if ($warningmsg ne '') { 5325: $resulttext .= '<br /><span class="LC_warning">'.$warningmsg.'</span><br />'; 5326: } 5327: return $resulttext; 5328: } 5329: 5330: sub modify_usermodification { 5331: my ($dom,%domconfig) = @_; 5332: my ($resulttext,%curr_usermodification,%changes); 5333: if (ref($domconfig{'usermodification'}) eq 'HASH') { 5334: foreach my $key (keys(%{$domconfig{'usermodification'}})) { 5335: $curr_usermodification{$key} = $domconfig{'usermodification'}{$key}; 5336: } 5337: } 5338: my @contexts = ('author','course','selfcreate'); 5339: my %context_title = ( 5340: author => 'In author context', 5341: course => 'In course context', 5342: selfcreate => 'When self creating account', 5343: ); 5344: my @fields = ('lastname','firstname','middlename','generation', 5345: 'permanentemail','id'); 5346: my %roles = ( 5347: author => ['ca','aa'], 5348: course => ['st','ep','ta','in','cr'], 5349: ); 5350: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 5351: if (ref($types) eq 'ARRAY') { 5352: push(@{$types},'default'); 5353: $usertypes->{'default'} = $othertitle; 5354: } 5355: $roles{'selfcreate'} = $types; 5356: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); 5357: my %modifyhash; 5358: foreach my $context (@contexts) { 5359: foreach my $role (@{$roles{$context}}) { 5360: my @modifiable = &Apache::loncommon::get_env_multiple('form.canmodify_'.$role); 5361: foreach my $item (@fields) { 5362: if (grep(/^\Q$item\E$/,@modifiable)) { 5363: $modifyhash{$context}{$role}{$item} = 1; 5364: } else { 5365: $modifyhash{$context}{$role}{$item} = 0; 5366: } 5367: } 5368: } 5369: if (ref($curr_usermodification{$context}) eq 'HASH') { 5370: foreach my $role (@{$roles{$context}}) { 5371: if (ref($curr_usermodification{$context}{$role}) eq 'HASH') { 5372: foreach my $field (@fields) { 5373: if ($modifyhash{$context}{$role}{$field} ne 5374: $curr_usermodification{$context}{$role}{$field}) { 5375: push(@{$changes{$context}},$role); 5376: last; 5377: } 5378: } 5379: } 5380: } 5381: } else { 5382: foreach my $context (@contexts) { 5383: foreach my $role (@{$roles{$context}}) { 5384: push(@{$changes{$context}},$role); 5385: } 5386: } 5387: } 5388: } 5389: my %usermodification_hash = ( 5390: usermodification => \%modifyhash, 5391: ); 5392: my $putresult = &Apache::lonnet::put_dom('configuration', 5393: \%usermodification_hash,$dom); 5394: if ($putresult eq 'ok') { 5395: if (keys(%changes) > 0) { 5396: $resulttext = &mt('Changes made: ').'<ul>'; 5397: foreach my $context (@contexts) { 5398: if (ref($changes{$context}) eq 'ARRAY') { 5399: $resulttext .= '<li>'.$context_title{$context}.':<ul>'; 5400: if (ref($changes{$context}) eq 'ARRAY') { 5401: foreach my $role (@{$changes{$context}}) { 5402: my $rolename; 5403: if ($context eq 'selfcreate') { 5404: $rolename = $role; 5405: if (ref($usertypes) eq 'HASH') { 5406: if ($usertypes->{$role} ne '') { 5407: $rolename = $usertypes->{$role}; 5408: } 5409: } 5410: } else { 5411: if ($role eq 'cr') { 5412: $rolename = &mt('Custom'); 5413: } else { 5414: $rolename = &Apache::lonnet::plaintext($role); 5415: } 5416: } 5417: my @modifiable; 5418: if ($context eq 'selfcreate') { 5419: $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Self-creation of account by users with status: [_1] ',$rolename).'</span> - '.&mt('modifiable fields (if institutional data blank): '); 5420: } else { 5421: $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Target user with [_1] role',$rolename).'</span> - '.&mt('modifiable fields: '); 5422: } 5423: foreach my $field (@fields) { 5424: if ($modifyhash{$context}{$role}{$field}) { 5425: push(@modifiable,$fieldtitles{$field}); 5426: } 5427: } 5428: if (@modifiable > 0) { 5429: $resulttext .= join(', ',@modifiable); 5430: } else { 5431: $resulttext .= &mt('none'); 5432: } 5433: $resulttext .= '</li>'; 5434: } 5435: $resulttext .= '</ul></li>'; 5436: } 5437: } 5438: } 5439: $resulttext .= '</ul>'; 5440: } else { 5441: $resulttext = &mt('No changes made to user modification settings'); 5442: } 5443: } else { 5444: $resulttext = '<span class="LC_error">'. 5445: &mt('An error occurred: [_1]',$putresult).'</span>'; 5446: } 5447: return $resulttext; 5448: } 5449: 5450: sub modify_defaults { 5451: my ($dom,$r) = @_; 5452: my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors); 5453: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 5454: my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def', 5455: 'portal_def'); 5456: my @authtypes = ('internal','krb4','krb5','localauth'); 5457: my @doms = &Apache::lonnet::current_machine_domains(); 5458: my @langs; 5459: foreach my $dom (@doms) { 5460: if ($dom =~ /^(\w{2})\w?itest$/) { 5461: push (@langs,$1.'t'); 5462: } elsif ($dom =~ /^(\w{2})\w?i$/) { 5463: push(@langs,$1.'i'); 5464: } 5465: } 5466: foreach my $item (@items) { 5467: $newvalues{$item} = $env{'form.'.$item}; 5468: if ($item eq 'auth_def') { 5469: if ($newvalues{$item} ne '') { 5470: if (!grep(/^\Q$newvalues{$item}\E$/,@authtypes)) { 5471: push(@errors,$item); 5472: } 5473: } 5474: } elsif ($item eq 'lang_def') { 5475: if ($newvalues{$item} ne '') { 5476: if ($newvalues{$item} =~ /^(\w+)/) { 5477: my $langcode = $1; 5478: if ((!grep(/^\Q$langcode\E/,@langs)) && 5479: ($langcode ne 'x_chef')) { 5480: if (code2language($langcode) eq '') { 5481: push(@errors,$item); 5482: } 5483: } 5484: } else { 5485: push(@errors,$item); 5486: } 5487: } 5488: } elsif ($item eq 'timezone_def') { 5489: if ($newvalues{$item} ne '') { 5490: if (!DateTime::TimeZone->is_valid_name($newvalues{$item})) { 5491: push(@errors,$item); 5492: } 5493: } 5494: } elsif ($item eq 'datelocale_def') { 5495: if ($newvalues{$item} ne '') { 5496: my @datelocale_ids = DateTime::Locale->ids(); 5497: if (!grep(/^\Q$newvalues{$item}\E$/,@datelocale_ids)) { 5498: push(@errors,$item); 5499: } 5500: } 5501: } elsif ($item eq 'portal_def') { 5502: if ($newvalues{$item} ne '') { 5503: 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])\/?$/) { 5504: push(@errors,$item); 5505: } 5506: } 5507: } 5508: if (grep(/^\Q$item\E$/,@errors)) { 5509: $newvalues{$item} = $domdefaults{$item}; 5510: } elsif ($domdefaults{$item} ne $newvalues{$item}) { 5511: $changes{$item} = 1; 5512: } 5513: $domdefaults{$item} = $newvalues{$item}; 5514: } 5515: my %defaults_hash = ( 5516: defaults => \%newvalues, 5517: ); 5518: my $title = &defaults_titles(); 5519: my $putresult = &Apache::lonnet::put_dom('configuration',\%defaults_hash, 5520: $dom); 5521: if ($putresult eq 'ok') { 5522: if (keys(%changes) > 0) { 5523: $resulttext = &mt('Changes made:').'<ul>'; 5524: my $version = $r->dir_config('lonVersion'); 5525: 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"; 5526: foreach my $item (sort(keys(%changes))) { 5527: my $value = $env{'form.'.$item}; 5528: if ($value eq '') { 5529: $value = &mt('none'); 5530: } elsif ($item eq 'auth_def') { 5531: my %authnames = &authtype_names(); 5532: my %shortauth = ( 5533: internal => 'int', 5534: krb4 => 'krb4', 5535: krb5 => 'krb5', 5536: localauth => 'loc', 5537: ); 5538: $value = $authnames{$shortauth{$value}}; 5539: } 5540: $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>'; 5541: $mailmsgtext .= "$title->{$item} set to $value\n"; 5542: } 5543: $resulttext .= '</ul>'; 5544: $mailmsgtext .= "\n"; 5545: my $cachetime = 24*60*60; 5546: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); 5547: if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) { 5548: my $sysmail = $r->dir_config('lonSysEMail'); 5549: &Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext); 5550: } 5551: } else { 5552: $resulttext = &mt('No changes made to default authentication/language/timezone settings'); 5553: } 5554: } else { 5555: $resulttext = '<span class="LC_error">'. 5556: &mt('An error occurred: [_1]',$putresult).'</span>'; 5557: } 5558: if (@errors > 0) { 5559: $resulttext .= '<br />'.&mt('The following were left unchanged because the values entered were invalid:'); 5560: foreach my $item (@errors) { 5561: $resulttext .= ' "'.$title->{$item}.'",'; 5562: } 5563: $resulttext =~ s/,$//; 5564: } 5565: return $resulttext; 5566: } 5567: 5568: sub modify_scantron { 5569: my ($r,$dom,$confname,%domconfig) = @_; 5570: my ($resulttext,%confhash,%changes,$errors); 5571: my $custom = 'custom.tab'; 5572: my $default = 'default.tab'; 5573: my $servadm = $r->dir_config('lonAdmEMail'); 5574: my ($configuserok,$author_ok,$switchserver) = 5575: &config_check($dom,$confname,$servadm); 5576: if ($env{'form.scantronformat.filename'} ne '') { 5577: my $error; 5578: if ($configuserok eq 'ok') { 5579: if ($switchserver) { 5580: $error = &mt("Upload of scantron format file is not permitted to this server: [_1]",$switchserver); 5581: } else { 5582: if ($author_ok eq 'ok') { 5583: my ($result,$scantronurl) = 5584: &publishlogo($r,'upload','scantronformat',$dom, 5585: $confname,'scantron','','',$custom); 5586: if ($result eq 'ok') { 5587: $confhash{'scantron'}{'scantronformat'} = $scantronurl; 5588: $changes{'scantronformat'} = 1; 5589: } else { 5590: $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$custom,$result); 5591: } 5592: } else { 5593: $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); 5594: } 5595: } 5596: } else { 5597: $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); 5598: } 5599: if ($error) { 5600: &Apache::lonnet::logthis($error); 5601: $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; 5602: } 5603: } 5604: if (ref($domconfig{'scantron'}) eq 'HASH') { 5605: if ($domconfig{'scantron'}{'scantronformat'} ne '') { 5606: if ($env{'form.scantronformat_del'}) { 5607: $confhash{'scantron'}{'scantronformat'} = ''; 5608: $changes{'scantronformat'} = 1; 5609: } 5610: } 5611: } 5612: if (keys(%confhash) > 0) { 5613: my $putresult = &Apache::lonnet::put_dom('configuration',\%confhash, 5614: $dom); 5615: if ($putresult eq 'ok') { 5616: if (keys(%changes) > 0) { 5617: if (ref($confhash{'scantron'}) eq 'HASH') { 5618: $resulttext = &mt('Changes made:').'<ul>'; 5619: if ($confhash{'scantron'}{'scantronformat'} eq '') { 5620: $resulttext .= '<li>'.&mt('[_1] scantron format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>'; 5621: } else { 5622: $resulttext .= '<li>'.&mt('Custom scantron format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>'; 5623: } 5624: $resulttext .= '</ul>'; 5625: } else { 5626: $resulttext = &mt('Changes made to scantron format file.'); 5627: } 5628: $resulttext .= '</ul>'; 5629: &Apache::loncommon::devalidate_domconfig_cache($dom); 5630: } else { 5631: $resulttext = &mt('No changes made to scantron format file'); 5632: } 5633: } else { 5634: $resulttext = '<span class="LC_error">'. 5635: &mt('An error occurred: [_1]',$putresult).'</span>'; 5636: } 5637: } else { 5638: $resulttext = &mt('No changes made to scantron format file'); 5639: } 5640: if ($errors) { 5641: $resulttext .= &mt('The following errors occurred: ').'<ul>'. 5642: $errors.'</ul>'; 5643: } 5644: return $resulttext; 5645: } 5646: 5647: sub modify_coursecategories { 5648: my ($dom,%domconfig) = @_; 5649: my ($resulttext,%deletions,%reorderings,%needreordering,%adds,%changes,$errors, 5650: $cathash); 5651: my @deletecategory = &Apache::loncommon::get_env_multiple('form.deletecategory'); 5652: if (ref($domconfig{'coursecategories'}) eq 'HASH') { 5653: $cathash = $domconfig{'coursecategories'}{'cats'}; 5654: if ($domconfig{'coursecategories'}{'togglecats'} ne $env{'form.togglecats'}) { 5655: $changes{'togglecats'} = 1; 5656: $domconfig{'coursecategories'}{'togglecats'} = $env{'form.togglecats'}; 5657: } 5658: if ($domconfig{'coursecategories'}{'categorize'} ne $env{'form.categorize'}) { 5659: $changes{'categorize'} = 1; 5660: $domconfig{'coursecategories'}{'categorize'} = $env{'form.categorize'}; 5661: } 5662: if ($domconfig{'coursecategories'}{'togglecatscomm'} ne $env{'form.togglecatscomm'}) { 5663: $changes{'togglecatscomm'} = 1; 5664: $domconfig{'coursecategories'}{'togglecatscomm'} = $env{'form.togglecatscomm'}; 5665: } 5666: if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) { 5667: $changes{'categorizecomm'} = 1; 5668: $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'}; 5669: } 5670: } else { 5671: $changes{'togglecats'} = 1; 5672: $changes{'categorize'} = 1; 5673: $domconfig{'coursecategories'} = { 5674: togglecats => $env{'form.togglecats'}, 5675: categorize => $env{'form.categorize'}, 5676: }; 5677: $changes{'togglecatscomm'} = 1; 5678: $changes{'categorizecomm'} = 1; 5679: $domconfig{'coursecategories'} = { 5680: togglecats => $env{'form.togglecatscomm'}, 5681: categorize => $env{'form.categorizecomm'}, 5682: }; 5683: } 5684: if (ref($cathash) eq 'HASH') { 5685: if (($domconfig{'coursecategories'}{'cats'}{'instcode::0'} ne '') && ($env{'form.instcode'} == 0)) { 5686: push (@deletecategory,'instcode::0'); 5687: } 5688: if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '') && ($env{'form.communities'} == 0)) { 5689: push(@deletecategory,'communities::0'); 5690: } 5691: } 5692: my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail); 5693: if (ref($cathash) eq 'HASH') { 5694: if (@deletecategory > 0) { 5695: #FIXME Need to remove category from all courses using a deleted category 5696: &Apache::loncommon::extract_categories($cathash,\@predelcats,\@predeltrails,\%predelallitems); 5697: foreach my $item (@deletecategory) { 5698: if ($domconfig{'coursecategories'}{'cats'}{$item} ne '') { 5699: delete($domconfig{'coursecategories'}{'cats'}{$item}); 5700: $deletions{$item} = 1; 5701: &recurse_cat_deletes($item,$cathash,\%deletions); 5702: } 5703: } 5704: } 5705: foreach my $item (keys(%{$cathash})) { 5706: my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$item); 5707: if ($cathash->{$item} ne $env{'form.'.$item}) { 5708: $reorderings{$item} = 1; 5709: $domconfig{'coursecategories'}{'cats'}{$item} = $env{'form.'.$item}; 5710: } 5711: if ($env{'form.addcategory_name_'.$item} ne '') { 5712: my $newcat = $env{'form.addcategory_name_'.$item}; 5713: my $newdepth = $depth+1; 5714: my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth; 5715: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos_'.$item}; 5716: $adds{$newitem} = 1; 5717: } 5718: if ($env{'form.subcat_'.$item} ne '') { 5719: my $newcat = $env{'form.subcat_'.$item}; 5720: my $newdepth = $depth+1; 5721: my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth; 5722: $domconfig{'coursecategories'}{'cats'}{$newitem} = 0; 5723: $adds{$newitem} = 1; 5724: } 5725: } 5726: } 5727: if ($env{'form.instcode'} eq '1') { 5728: if (ref($cathash) eq 'HASH') { 5729: my $newitem = 'instcode::0'; 5730: if ($cathash->{$newitem} eq '') { 5731: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.instcode_pos'}; 5732: $adds{$newitem} = 1; 5733: } 5734: } else { 5735: my $newitem = 'instcode::0'; 5736: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.instcode_pos'}; 5737: $adds{$newitem} = 1; 5738: } 5739: } 5740: if ($env{'form.communities'} eq '1') { 5741: if (ref($cathash) eq 'HASH') { 5742: my $newitem = 'communities::0'; 5743: if ($cathash->{$newitem} eq '') { 5744: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'}; 5745: $adds{$newitem} = 1; 5746: } 5747: } else { 5748: my $newitem = 'communities::0'; 5749: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'}; 5750: $adds{$newitem} = 1; 5751: } 5752: } 5753: if ($env{'form.addcategory_name'} ne '') { 5754: if (($env{'form.addcategory_name'} ne 'instcode') && 5755: ($env{'form.addcategory_name'} ne 'communities')) { 5756: my $newitem = &escape($env{'form.addcategory_name'}).'::0'; 5757: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'}; 5758: $adds{$newitem} = 1; 5759: } 5760: } 5761: my $putresult; 5762: if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) { 5763: if (keys(%deletions) > 0) { 5764: foreach my $key (keys(%deletions)) { 5765: if ($predelallitems{$key} ne '') { 5766: $sort_by_deltrail{$predelallitems{$key}} = $predeltrails[$predelallitems{$key}]; 5767: } 5768: } 5769: } 5770: my (@chkcats,@chktrails,%chkallitems); 5771: &Apache::loncommon::extract_categories($domconfig{'coursecategories'}{'cats'},\@chkcats,\@chktrails,\%chkallitems); 5772: if (ref($chkcats[0]) eq 'ARRAY') { 5773: my $depth = 0; 5774: my $chg = 0; 5775: for (my $i=0; $i<@{$chkcats[0]}; $i++) { 5776: my $name = $chkcats[0][$i]; 5777: my $item; 5778: if ($name eq '') { 5779: $chg ++; 5780: } else { 5781: $item = &escape($name).'::0'; 5782: if ($chg) { 5783: $domconfig{'coursecategories'}{'cats'}{$item} -= $chg; 5784: } 5785: $depth ++; 5786: &recurse_check(\@chkcats,$domconfig{'coursecategories'}{'cats'},$depth,$name); 5787: $depth --; 5788: } 5789: } 5790: } 5791: } 5792: if ((keys(%changes) > 0) || (keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) { 5793: $putresult = &Apache::lonnet::put_dom('configuration',\%domconfig,$dom); 5794: if ($putresult eq 'ok') { 5795: my %title = ( 5796: togglecats => 'Show/Hide a course in catalog', 5797: categorize => 'Assign a category to a course', 5798: togglecatscomm => 'Show/Hide a community in catalog', 5799: categorizecomm => 'Assign a category to a community', 5800: ); 5801: my %level = ( 5802: dom => 'set in Domain ("Modify Course/Community")', 5803: crs => 'set in Course ("Course Configuration")', 5804: comm => 'set in Community ("Community Configuration")', 5805: ); 5806: $resulttext = &mt('Changes made:').'<ul>'; 5807: if ($changes{'togglecats'}) { 5808: $resulttext .= '<li>'.&mt("$title{'togglecats'} $level{$env{'form.togglecats'}}").'</li>'; 5809: } 5810: if ($changes{'categorize'}) { 5811: $resulttext .= '<li>'.&mt("$title{'categorize'} $level{$env{'form.categorize'}}").'</li>'; 5812: } 5813: if ($changes{'togglecatscomm'}) { 5814: $resulttext .= '<li>'.&mt("$title{'togglecatscomm'} $level{$env{'form.togglecatscomm'}}").'</li>'; 5815: } 5816: if ($changes{'categorizecomm'}) { 5817: $resulttext .= '<li>'.&mt("$title{'categorizecomm'} $level{$env{'form.categorizecomm'}}").'</li>'; 5818: } 5819: if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) { 5820: my $cathash; 5821: if (ref($domconfig{'coursecategories'}) eq 'HASH') { 5822: $cathash = $domconfig{'coursecategories'}{'cats'}; 5823: } else { 5824: $cathash = {}; 5825: } 5826: my (@cats,@trails,%allitems); 5827: &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems); 5828: if (keys(%deletions) > 0) { 5829: $resulttext .= '<li>'.&mt('Deleted categories:').'<ul>'; 5830: foreach my $predeltrail (sort {$a <=> $b } (keys(%sort_by_deltrail))) { 5831: $resulttext .= '<li>'.$predeltrails[$predeltrail].'</li>'; 5832: } 5833: $resulttext .= '</ul></li>'; 5834: } 5835: if (keys(%reorderings) > 0) { 5836: my %sort_by_trail; 5837: $resulttext .= '<li>'.&mt('Reordered categories:').'<ul>'; 5838: foreach my $key (keys(%reorderings)) { 5839: if ($allitems{$key} ne '') { 5840: $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}]; 5841: } 5842: } 5843: foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) { 5844: $resulttext .= '<li>'.$trails[$trail].'</li>'; 5845: } 5846: $resulttext .= '</ul></li>'; 5847: } 5848: if (keys(%adds) > 0) { 5849: my %sort_by_trail; 5850: $resulttext .= '<li>'.&mt('Added categories:').'<ul>'; 5851: foreach my $key (keys(%adds)) { 5852: if ($allitems{$key} ne '') { 5853: $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}]; 5854: } 5855: } 5856: foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) { 5857: $resulttext .= '<li>'.$trails[$trail].'</li>'; 5858: } 5859: $resulttext .= '</ul></li>'; 5860: } 5861: } 5862: $resulttext .= '</ul>'; 5863: } else { 5864: $resulttext = '<span class="LC_error">'. 5865: &mt('An error occurred: [_1]',$putresult).'</span>'; 5866: } 5867: } else { 5868: $resulttext = &mt('No changes made to course and community categories'); 5869: } 5870: return $resulttext; 5871: } 5872: 5873: sub modify_serverstatuses { 5874: my ($dom,%domconfig) = @_; 5875: my ($resulttext,%changes,%currserverstatus,%newserverstatus); 5876: if (ref($domconfig{'serverstatuses'}) eq 'HASH') { 5877: %currserverstatus = %{$domconfig{'serverstatuses'}}; 5878: } 5879: my @pages = &serverstatus_pages(); 5880: foreach my $type (@pages) { 5881: $newserverstatus{$type}{'namedusers'} = ''; 5882: $newserverstatus{$type}{'machines'} = ''; 5883: if (defined($env{'form.'.$type.'_namedusers'})) { 5884: my @users = split(/,/,$env{'form.'.$type.'_namedusers'}); 5885: my @okusers; 5886: foreach my $user (@users) { 5887: my ($uname,$udom) = split(/:/,$user); 5888: if (($udom =~ /^$match_domain$/) && 5889: (&Apache::lonnet::domain($udom)) && 5890: ($uname =~ /^$match_username$/)) { 5891: if (!grep(/^\Q$user\E/,@okusers)) { 5892: push(@okusers,$user); 5893: } 5894: } 5895: } 5896: if (@okusers > 0) { 5897: @okusers = sort(@okusers); 5898: $newserverstatus{$type}{'namedusers'} = join(',',@okusers); 5899: } 5900: } 5901: if (defined($env{'form.'.$type.'_machines'})) { 5902: my @machines = split(/,/,$env{'form.'.$type.'_machines'}); 5903: my @okmachines; 5904: foreach my $ip (@machines) { 5905: my @parts = split(/\./,$ip); 5906: next if (@parts < 4); 5907: my $badip = 0; 5908: for (my $i=0; $i<4; $i++) { 5909: if (!(($parts[$i] >= 0) && ($parts[$i] <= 255))) { 5910: $badip = 1; 5911: last; 5912: } 5913: } 5914: if (!$badip) { 5915: push(@okmachines,$ip); 5916: } 5917: } 5918: @okmachines = sort(@okmachines); 5919: $newserverstatus{$type}{'machines'} = join(',',@okmachines); 5920: } 5921: } 5922: my %serverstatushash = ( 5923: serverstatuses => \%newserverstatus, 5924: ); 5925: my %changes; 5926: foreach my $type (@pages) { 5927: foreach my $setting ('namedusers','machines') { 5928: my (@current,@new); 5929: if (ref($currserverstatus{$type}) eq 'HASH') { 5930: if ($currserverstatus{$type}{$setting} ne '') { 5931: @current = split(/,/,$currserverstatus{$type}{$setting}); 5932: } 5933: } 5934: if ($newserverstatus{$type}{$setting} ne '') { 5935: @new = split(/,/,$newserverstatus{$type}{$setting}); 5936: } 5937: if (@current > 0) { 5938: if (@new > 0) { 5939: foreach my $item (@current) { 5940: if (!grep(/^\Q$item\E$/,@new)) { 5941: $changes{$type}{$setting} = 1; 5942: last; 5943: } 5944: } 5945: foreach my $item (@new) { 5946: if (!grep(/^\Q$item\E$/,@current)) { 5947: $changes{$type}{$setting} = 1; 5948: last; 5949: } 5950: } 5951: } else { 5952: $changes{$type}{$setting} = 1; 5953: } 5954: } elsif (@new > 0) { 5955: $changes{$type}{$setting} = 1; 5956: } 5957: } 5958: } 5959: if (keys(%changes) > 0) { 5960: my $titles= &LONCAPA::lonauthcgi::serverstatus_titles(); 5961: my $putresult = &Apache::lonnet::put_dom('configuration', 5962: \%serverstatushash,$dom); 5963: if ($putresult eq 'ok') { 5964: $resulttext .= &mt('Changes made:').'<ul>'; 5965: foreach my $type (@pages) { 5966: if (ref($changes{$type}) eq 'HASH') { 5967: $resulttext .= '<li>'.$titles->{$type}.'<ul>'; 5968: if ($changes{$type}{'namedusers'}) { 5969: if ($newserverstatus{$type}{'namedusers'} eq '') { 5970: $resulttext .= '<li>'.&mt("Access terminated for all specific (named) users").'</li>'."\n"; 5971: } else { 5972: $resulttext .= '<li>'.&mt("Access available for the following specified users: ").$newserverstatus{$type}{'namedusers'}.'</li>'."\n"; 5973: } 5974: } 5975: if ($changes{$type}{'machines'}) { 5976: if ($newserverstatus{$type}{'machines'} eq '') { 5977: $resulttext .= '<li>'.&mt("Access terminated for all specific IP addresses").'</li>'."\n"; 5978: } else { 5979: $resulttext .= '<li>'.&mt("Access available for the following specified IP addresses: ").$newserverstatus{$type}{'machines'}.'</li>'."\n"; 5980: } 5981: 5982: } 5983: $resulttext .= '</ul></li>'; 5984: } 5985: } 5986: $resulttext .= '</ul>'; 5987: } else { 5988: $resulttext = '<span class="LC_error">'. 5989: &mt('An error occurred saving access settings for server status pages: [_1].',$putresult).'</span>'; 5990: 5991: } 5992: } else { 5993: $resulttext = &mt('No changes made to access to server status pages'); 5994: } 5995: return $resulttext; 5996: } 5997: 5998: sub modify_helpsettings { 5999: my ($r,$dom,$confname,%domconfig) = @_; 6000: my ($resulttext,$errors,%changes,%helphash); 6001: 6002: my $customhelpfile = $env{'form.loginhelpurl.filename'}; 6003: my $defaulthelpfile = 'defaulthelp.html'; 6004: my $servadm = $r->dir_config('lonAdmEMail'); 6005: my ($configuserok,$author_ok,$switchserver) = 6006: &config_check($dom,$confname,$servadm); 6007: 6008: my %defaultchecked = ('submitbugs' => 'on'); 6009: my @offon = ('off','on'); 6010: my %title = ( submitbugs => 'Display link for users to submit a bug', 6011: loginhelpurl => 'Unauthenticated login help page set to custom file'); 6012: 6013: my @toggles = ('submitbugs'); 6014: 6015: $helphash{'helpsettings'} = {}; 6016: 6017: if (ref($domconfig{'helpsettings'}) ne 'HASH') { 6018: if ($domconfig{'helpsettings'} eq '') { 6019: $domconfig{'helpsettings'} = {}; 6020: } 6021: } 6022: 6023: if (ref($domconfig{'helpsettings'}) eq 'HASH') { 6024: 6025: foreach my $item (@toggles) { 6026: 6027: if ($defaultchecked{$item} eq 'on') { 6028: if (($domconfig{'helpsettings'}{$item} eq '') && 6029: ($env{'form.'.$item} eq '0')) { 6030: $changes{$item} = 1; 6031: } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { 6032: $changes{$item} = 1; 6033: } 6034: } elsif ($defaultchecked{$item} eq 'off') { 6035: if (($domconfig{'helpsettings'}{$item} eq '') && 6036: ($env{'form.'.$item} eq '1')) { 6037: $changes{$item} = 1; 6038: } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { 6039: $changes{$item} = 1; 6040: } 6041: } 6042: $helphash{'helpsettings'}{$item} = $env{'form.'.$item}; 6043: } 6044: 6045: if ($customhelpfile ne '') { 6046: my $error; 6047: if ($configuserok eq 'ok') { 6048: if ($switchserver) { 6049: $error = &mt("Upload of custom help file is not permitted to this server: [_1]",$switchserver); 6050: } else { 6051: if ($author_ok eq 'ok') { 6052: my ($result,$loginhelpurl) = 6053: &publishlogo($r,'upload','loginhelpurl',$dom, 6054: $confname,'help','','',$customhelpfile); 6055: if ($result eq 'ok') { 6056: $helphash{'helpsettings'}{'loginhelpurl'} = $loginhelpurl; 6057: $changes{'loginhelpurl'} = 1; 6058: } else { 6059: $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$customhelpfile,$result); 6060: } 6061: } else { 6062: $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].",$customhelpfile,$confname,$dom,$author_ok); 6063: } 6064: } 6065: } else { 6066: $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$customhelpfile,$confname,$dom,$configuserok); 6067: } 6068: if ($error) { 6069: &Apache::lonnet::logthis($error); 6070: $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; 6071: } 6072: } 6073: 6074: if ($domconfig{'helpsettings'}{'loginhelpurl'} ne '') { 6075: if ($env{'form.loginhelpurl_del'}) { 6076: $helphash{'helpsettings'}{'loginhelpurl'} = ''; 6077: $changes{'loginhelpurl'} = 1; 6078: } 6079: } 6080: } 6081: 6082: 6083: my $putresult; 6084: 6085: if (keys(%changes) > 0) { 6086: $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom); 6087: } else { 6088: $putresult = 'ok'; 6089: } 6090: 6091: if ($putresult eq 'ok') { 6092: if (keys(%changes) > 0) { 6093: $resulttext = &mt('Changes made:').'<ul>'; 6094: foreach my $item (sort(keys(%changes))) { 6095: if ($item eq 'submitbugs') { 6096: $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>'; 6097: } 6098: if ($item eq 'loginhelpurl') { 6099: if ($helphash{'helpsettings'}{'loginhelpurl'} eq '') { 6100: $resulttext .= '<li>'.&mt('[_1] help file removed; [_2] file will be used for the unathorized help page in this domain.',$customhelpfile,$defaulthelpfile).'</li>'; 6101: } else { 6102: $resulttext .= '<li>'.&mt("$title{$item} [_1]",$customhelpfile).'</li>'; 6103: } 6104: } 6105: } 6106: $resulttext .= '</ul>'; 6107: } else { 6108: $resulttext = &mt('No changes made to help settings'); 6109: } 6110: } else { 6111: $resulttext = '<span class="LC_error">'. 6112: &mt('An error occurred: [_1]',$putresult).'</span>'; 6113: } 6114: if ($errors) { 6115: $resulttext .= &mt('The following errors occurred: ').'<ul>'. 6116: $errors.'</ul>'; 6117: } 6118: return $resulttext; 6119: } 6120: 6121: sub modify_coursedefaults { 6122: my ($dom,%domconfig) = @_; 6123: my ($resulttext,$errors,%changes,%defaultshash); 6124: my %defaultchecked = ('canuse_pdfforms' => 'off'); 6125: my @offon = ('off','on'); 6126: my @toggles = ('canuse_pdfforms'); 6127: 6128: $defaultshash{'coursedefaults'} = {}; 6129: 6130: if (ref($domconfig{'coursedefaults'}) ne 'HASH') { 6131: if ($domconfig{'coursedefaults'} eq '') { 6132: $domconfig{'coursedefaults'} = {}; 6133: } 6134: } 6135: 6136: if (ref($domconfig{'coursedefaults'}) eq 'HASH') { 6137: foreach my $item (@toggles) { 6138: if ($defaultchecked{$item} eq 'on') { 6139: if (($domconfig{'coursedefaults'}{$item} eq '') && 6140: ($env{'form.'.$item} eq '0')) { 6141: $changes{$item} = 1; 6142: } elsif ($domconfig{'coursdefaults'}{$item} ne $env{'form.'.$item}) { 6143: $changes{$item} = 1; 6144: } 6145: } elsif ($defaultchecked{$item} eq 'off') { 6146: if (($domconfig{'coursedefaults'}{$item} eq '') && 6147: ($env{'form.'.$item} eq '1')) { 6148: $changes{$item} = 1; 6149: } elsif ($domconfig{'coursedefaults'}{$item} ne $env{'form.'.$item}) { 6150: $changes{$item} = 1; 6151: } 6152: } 6153: $defaultshash{'coursedefaults'}{$item} = $env{'form.'.$item}; 6154: } 6155: my $currdefresponder = $domconfig{'coursedefaults'}{'anonsurvey_threshold'}; 6156: my $newdefresponder = $env{'form.anonsurvey_threshold'}; 6157: $newdefresponder =~ s/\D//g; 6158: if ($newdefresponder eq '' || $newdefresponder < 1) { 6159: $newdefresponder = 1; 6160: } 6161: $defaultshash{'coursedefaults'}{'anonsurvey_threshold'} = $newdefresponder; 6162: if ($currdefresponder ne $newdefresponder) { 6163: unless ($currdefresponder eq '' && $newdefresponder == 10) { 6164: $changes{'anonsurvey_threshold'} = 1; 6165: } 6166: } 6167: } 6168: my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, 6169: $dom); 6170: if ($putresult eq 'ok') { 6171: if (keys(%changes) > 0) { 6172: if ($changes{'canuse_pdfforms'}) { 6173: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 6174: $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'}; 6175: my $cachetime = 24*60*60; 6176: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); 6177: } 6178: $resulttext = &mt('Changes made:').'<ul>'; 6179: foreach my $item (sort(keys(%changes))) { 6180: if ($item eq 'canuse_pdfforms') { 6181: if ($env{'form.'.$item} eq '1') { 6182: $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>'; 6183: } else { 6184: $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>'; 6185: } 6186: } elsif ($item eq 'anonsurvey_threshold') { 6187: $resulttext .= '<li>'.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'</li>'; 6188: } 6189: 6190: } 6191: $resulttext .= '</ul>'; 6192: } else { 6193: $resulttext = &mt('No changes made to course defaults'); 6194: } 6195: } else { 6196: $resulttext = '<span class="LC_error">'. 6197: &mt('An error occurred: [_1]',$putresult).'</span>'; 6198: } 6199: return $resulttext; 6200: } 6201: 6202: sub recurse_check { 6203: my ($chkcats,$categories,$depth,$name) = @_; 6204: if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') { 6205: my $chg = 0; 6206: for (my $j=0; $j<@{$chkcats->[$depth]{$name}}; $j++) { 6207: my $category = $chkcats->[$depth]{$name}[$j]; 6208: my $item; 6209: if ($category eq '') { 6210: $chg ++; 6211: } else { 6212: my $deeper = $depth + 1; 6213: $item = &escape($category).':'.&escape($name).':'.$depth; 6214: if ($chg) { 6215: $categories->{$item} -= $chg; 6216: } 6217: &recurse_check($chkcats,$categories,$deeper,$category); 6218: $deeper --; 6219: } 6220: } 6221: } 6222: return; 6223: } 6224: 6225: sub recurse_cat_deletes { 6226: my ($item,$coursecategories,$deletions) = @_; 6227: my ($deleted,$container,$depth) = map { &unescape($_); } split(/:/,$item); 6228: my $subdepth = $depth + 1; 6229: if (ref($coursecategories) eq 'HASH') { 6230: foreach my $subitem (keys(%{$coursecategories})) { 6231: my ($child,$parent,$itemdepth) = map { &unescape($_); } split(/:/,$subitem); 6232: if (($parent eq $deleted) && ($itemdepth == $subdepth)) { 6233: delete($coursecategories->{$subitem}); 6234: $deletions->{$subitem} = 1; 6235: &recurse_cat_deletes($subitem,$coursecategories,$deletions); 6236: } 6237: } 6238: } 6239: return; 6240: } 6241: 6242: sub dom_servers { 6243: my ($dom) = @_; 6244: my (%uniqservers,%servers); 6245: my $primaryserver = &Apache::lonnet::hostname(&Apache::lonnet::domain($dom,'primary')); 6246: my @machinedoms = &Apache::lonnet::machine_domains($primaryserver); 6247: foreach my $mdom (@machinedoms) { 6248: my %currservers = %servers; 6249: my %server = &Apache::lonnet::get_servers($mdom); 6250: %servers = (%currservers,%server); 6251: } 6252: my %by_hostname; 6253: foreach my $id (keys(%servers)) { 6254: push(@{$by_hostname{$servers{$id}}},$id); 6255: } 6256: foreach my $hostname (sort(keys(%by_hostname))) { 6257: if (@{$by_hostname{$hostname}} > 1) { 6258: my $match = 0; 6259: foreach my $id (@{$by_hostname{$hostname}}) { 6260: if (&Apache::lonnet::host_domain($id) eq $dom) { 6261: $uniqservers{$id} = $hostname; 6262: $match = 1; 6263: } 6264: } 6265: unless ($match) { 6266: $uniqservers{$by_hostname{$hostname}[0]} = $hostname; 6267: } 6268: } else { 6269: $uniqservers{$by_hostname{$hostname}[0]} = $hostname; 6270: } 6271: } 6272: return %uniqservers; 6273: } 6274: 6275: 1;