![]() ![]() | ![]() |
Added ability to customize Log-in Help link
1: # The LearningOnline Network with CAPA 2: # Handler to set domain-wide configuration settings 3: # 4: # $Id: domainprefs.pm,v 1.122 2009/12/04 14:17:38 jms 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', 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 => 'Setting', 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: %choices = 2096: &Apache::lonlocal::texthash ( 2097: canuse_pdfforms => 'Course/Community users can create/upload PDF forms', 2098: ); 2099: %defaultchecked = ('canuse_pdfforms' => 'off'); 2100: @toggles = ('canuse_pdfforms',); 2101: ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, 2102: \%choices,$itemcount); 2103: $$rowtotal += $itemcount; 2104: return $datatable; 2105: } 2106: 2107: sub contact_titles { 2108: my %titles = &Apache::lonlocal::texthash ( 2109: 'supportemail' => 'Support E-mail address', 2110: 'adminemail' => 'Default Server Admin E-mail address', 2111: 'errormail' => 'Error reports to be e-mailed to', 2112: 'packagesmail' => 'Package update alerts to be e-mailed to', 2113: 'helpdeskmail' => 'Helpdesk requests to be e-mailed to', 2114: 'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)', 2115: 'requestsmail' => 'E-mail from course requests requiring approval', 2116: ); 2117: my %short_titles = &Apache::lonlocal::texthash ( 2118: adminemail => 'Admin E-mail address', 2119: supportemail => 'Support E-mail', 2120: ); 2121: return (\%titles,\%short_titles); 2122: } 2123: 2124: sub tool_titles { 2125: my %titles = &Apache::lonlocal::texthash ( 2126: aboutme => 'Personal Information Page', 2127: blog => 'Blog', 2128: portfolio => 'Portfolio', 2129: official => 'Official courses (with institutional codes)', 2130: unofficial => 'Unofficial courses', 2131: community => 'Communities', 2132: ); 2133: return %titles; 2134: } 2135: 2136: sub courserequest_titles { 2137: my %titles = &Apache::lonlocal::texthash ( 2138: official => 'Official', 2139: unofficial => 'Unofficial', 2140: community => 'Communities', 2141: norequest => 'Not allowed', 2142: approval => 'Approval by Dom. Coord.', 2143: validate => 'With validation', 2144: autolimit => 'Numerical limit', 2145: unlimited => '(blank for unlimited)', 2146: ); 2147: return %titles; 2148: } 2149: 2150: sub courserequest_conditions { 2151: my %conditions = &Apache::lonlocal::texthash ( 2152: approval => '(Processing of request subject to approval by Domain Coordinator).', 2153: validate => '(Processing of request subject to instittutional validation).', 2154: ); 2155: return %conditions; 2156: } 2157: 2158: 2159: sub print_usercreation { 2160: my ($position,$dom,$settings,$rowtotal) = @_; 2161: my $numinrow = 4; 2162: my $datatable; 2163: if ($position eq 'top') { 2164: $$rowtotal ++; 2165: my $rowcount = 0; 2166: my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($dom,'username'); 2167: if (ref($rules) eq 'HASH') { 2168: if (keys(%{$rules}) > 0) { 2169: $datatable .= &user_formats_row('username',$settings,$rules, 2170: $ruleorder,$numinrow,$rowcount); 2171: $$rowtotal ++; 2172: $rowcount ++; 2173: } 2174: } 2175: my ($idrules,$idruleorder) = &Apache::lonnet::inst_userrules($dom,'id'); 2176: if (ref($idrules) eq 'HASH') { 2177: if (keys(%{$idrules}) > 0) { 2178: $datatable .= &user_formats_row('id',$settings,$idrules, 2179: $idruleorder,$numinrow,$rowcount); 2180: $$rowtotal ++; 2181: $rowcount ++; 2182: } 2183: } 2184: my ($emailrules,$emailruleorder) = 2185: &Apache::lonnet::inst_userrules($dom,'email'); 2186: if (ref($emailrules) eq 'HASH') { 2187: if (keys(%{$emailrules}) > 0) { 2188: $datatable .= &user_formats_row('email',$settings,$emailrules, 2189: $emailruleorder,$numinrow,$rowcount); 2190: $$rowtotal ++; 2191: $rowcount ++; 2192: } 2193: } 2194: if ($rowcount == 0) { 2195: $datatable .= '<tr><td colspan="2">'.&mt('No format rules have been defined for usernames or IDs in this domain.').'</td></tr>'; 2196: $$rowtotal ++; 2197: $rowcount ++; 2198: } 2199: } elsif ($position eq 'middle') { 2200: my @creators = ('author','course','requestcrs','selfcreate'); 2201: my ($rules,$ruleorder) = 2202: &Apache::lonnet::inst_userrules($dom,'username'); 2203: my %lt = &usercreation_types(); 2204: my %checked; 2205: my @selfcreate; 2206: if (ref($settings) eq 'HASH') { 2207: if (ref($settings->{'cancreate'}) eq 'HASH') { 2208: foreach my $item (@creators) { 2209: $checked{$item} = $settings->{'cancreate'}{$item}; 2210: } 2211: if (ref($settings->{'cancreate'}{'selfcreate'}) eq 'ARRAY') { 2212: @selfcreate = @{$settings->{'cancreate'}{'selfcreate'}}; 2213: } elsif ($settings->{'cancreate'}{'selfcreate'} ne '') { 2214: if ($settings->{'cancreate'}{'selfcreate'} eq 'any') { 2215: @selfcreate = ('email','login','sso'); 2216: } elsif ($settings->{'cancreate'}{'selfcreate'} ne 'none') { 2217: @selfcreate = ($settings->{'cancreate'}{'selfcreate'}); 2218: } 2219: } 2220: } elsif (ref($settings->{'cancreate'}) eq 'ARRAY') { 2221: foreach my $item (@creators) { 2222: if (grep(/^\Q$item\E$/,@{$settings->{'cancreate'}})) { 2223: $checked{$item} = 'none'; 2224: } 2225: } 2226: } 2227: } 2228: my $rownum = 0; 2229: foreach my $item (@creators) { 2230: $rownum ++; 2231: if ($item ne 'selfcreate') { 2232: if ($checked{$item} eq '') { 2233: $checked{$item} = 'any'; 2234: } 2235: } 2236: my $css_class; 2237: if ($rownum%2) { 2238: $css_class = ''; 2239: } else { 2240: $css_class = ' class="LC_odd_row" '; 2241: } 2242: $datatable .= '<tr'.$css_class.'>'. 2243: '<td><span class="LC_nobreak">'.$lt{$item}. 2244: '</span></td><td align="right">'; 2245: my @options; 2246: if ($item eq 'selfcreate') { 2247: push(@options,('email','login','sso')); 2248: } else { 2249: @options = ('any'); 2250: if (ref($rules) eq 'HASH') { 2251: if (keys(%{$rules}) > 0) { 2252: push(@options,('official','unofficial')); 2253: } 2254: } 2255: push(@options,'none'); 2256: } 2257: foreach my $option (@options) { 2258: my $type = 'radio'; 2259: my $check = ' '; 2260: if ($item eq 'selfcreate') { 2261: $type = 'checkbox'; 2262: if (grep(/^\Q$option\E$/,@selfcreate)) { 2263: $check = ' checked="checked" '; 2264: } 2265: } else { 2266: if ($checked{$item} eq $option) { 2267: $check = ' checked="checked" '; 2268: } 2269: } 2270: $datatable .= '<span class="LC_nobreak"><label>'. 2271: '<input type="'.$type.'" name="can_createuser_'. 2272: $item.'" value="'.$option.'"'.$check.'/> '. 2273: $lt{$option}.'</label> </span>'; 2274: } 2275: $datatable .= '</td></tr>'; 2276: } 2277: my ($othertitle,$usertypes,$types) = 2278: &Apache::loncommon::sorted_inst_types($dom); 2279: if (ref($usertypes) eq 'HASH') { 2280: if (keys(%{$usertypes}) > 0) { 2281: my $createsettings; 2282: if (ref($settings) eq 'HASH') { 2283: $createsettings = $settings->{cancreate}; 2284: } 2285: $datatable .= &insttypes_row($createsettings,$types,$usertypes, 2286: $dom,$numinrow,$othertitle, 2287: 'statustocreate'); 2288: $$rowtotal ++; 2289: } 2290: } 2291: } else { 2292: my @contexts = ('author','course','domain'); 2293: my @authtypes = ('int','krb4','krb5','loc'); 2294: my %checked; 2295: if (ref($settings) eq 'HASH') { 2296: if (ref($settings->{'authtypes'}) eq 'HASH') { 2297: foreach my $item (@contexts) { 2298: if (ref($settings->{'authtypes'}{$item}) eq 'HASH') { 2299: foreach my $auth (@authtypes) { 2300: if ($settings->{'authtypes'}{$item}{$auth}) { 2301: $checked{$item}{$auth} = ' checked="checked" '; 2302: } 2303: } 2304: } 2305: } 2306: } 2307: } else { 2308: foreach my $item (@contexts) { 2309: foreach my $auth (@authtypes) { 2310: $checked{$item}{$auth} = ' checked="checked" '; 2311: } 2312: } 2313: } 2314: my %title = &context_names(); 2315: my %authname = &authtype_names(); 2316: my $rownum = 0; 2317: my $css_class; 2318: foreach my $item (@contexts) { 2319: if ($rownum%2) { 2320: $css_class = ''; 2321: } else { 2322: $css_class = ' class="LC_odd_row" '; 2323: } 2324: $datatable .= '<tr'.$css_class.'>'. 2325: '<td>'.$title{$item}. 2326: '</td><td class="LC_left_item">'. 2327: '<span class="LC_nobreak">'; 2328: foreach my $auth (@authtypes) { 2329: $datatable .= '<label>'. 2330: '<input type="checkbox" name="'.$item.'_auth" '. 2331: $checked{$item}{$auth}.' value="'.$auth.'" />'. 2332: $authname{$auth}.'</label> '; 2333: } 2334: $datatable .= '</span></td></tr>'; 2335: $rownum ++; 2336: } 2337: $$rowtotal += $rownum; 2338: } 2339: return $datatable; 2340: } 2341: 2342: sub user_formats_row { 2343: my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount) = @_; 2344: my $output; 2345: my %text = ( 2346: 'username' => 'new usernames', 2347: 'id' => 'IDs', 2348: 'email' => 'self-created accounts (e-mail)', 2349: ); 2350: my $css_class = $rowcount%2?' class="LC_odd_row"':''; 2351: $output = '<tr '.$css_class.'>'. 2352: '<td><span class="LC_nobreak">'; 2353: if ($type eq 'email') { 2354: $output .= &mt("Formats disallowed for $text{$type}: "); 2355: } else { 2356: $output .= &mt("Format rules to check for $text{$type}: "); 2357: } 2358: $output .= '</span></td>'. 2359: '<td class="LC_left_item" colspan="2"><table>'; 2360: my $rem; 2361: if (ref($ruleorder) eq 'ARRAY') { 2362: for (my $i=0; $i<@{$ruleorder}; $i++) { 2363: if (ref($rules->{$ruleorder->[$i]}) eq 'HASH') { 2364: my $rem = $i%($numinrow); 2365: if ($rem == 0) { 2366: if ($i > 0) { 2367: $output .= '</tr>'; 2368: } 2369: $output .= '<tr>'; 2370: } 2371: my $check = ' '; 2372: if (ref($settings) eq 'HASH') { 2373: if (ref($settings->{$type.'_rule'}) eq 'ARRAY') { 2374: if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) { 2375: $check = ' checked="checked" '; 2376: } 2377: } 2378: } 2379: $output .= '<td class="LC_left_item">'. 2380: '<span class="LC_nobreak"><label>'. 2381: '<input type="checkbox" name="'.$type.'_rule" '. 2382: 'value="'.$ruleorder->[$i].'"'.$check.'/>'. 2383: $rules->{$ruleorder->[$i]}{'name'}.'</label></span></td>'; 2384: } 2385: } 2386: $rem = @{$ruleorder}%($numinrow); 2387: } 2388: my $colsleft = $numinrow - $rem; 2389: if ($colsleft > 1 ) { 2390: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'. 2391: ' </td>'; 2392: } elsif ($colsleft == 1) { 2393: $output .= '<td class="LC_left_item"> </td>'; 2394: } 2395: $output .= '</tr></table></td></tr>'; 2396: return $output; 2397: } 2398: 2399: sub usercreation_types { 2400: my %lt = &Apache::lonlocal::texthash ( 2401: author => 'When adding a co-author', 2402: course => 'When adding a user to a course', 2403: requestcrs => 'When requesting a course', 2404: selfcreate => 'User creates own account', 2405: any => 'Any', 2406: official => 'Institutional only ', 2407: unofficial => 'Non-institutional only', 2408: email => 'E-mail address', 2409: login => 'Institutional Login', 2410: sso => 'SSO', 2411: none => 'None', 2412: ); 2413: return %lt; 2414: } 2415: 2416: sub authtype_names { 2417: my %lt = &Apache::lonlocal::texthash( 2418: int => 'Internal', 2419: krb4 => 'Kerberos 4', 2420: krb5 => 'Kerberos 5', 2421: loc => 'Local', 2422: ); 2423: return %lt; 2424: } 2425: 2426: sub context_names { 2427: my %context_title = &Apache::lonlocal::texthash( 2428: author => 'Creating users when an Author', 2429: course => 'Creating users when in a course', 2430: domain => 'Creating users when a Domain Coordinator', 2431: ); 2432: return %context_title; 2433: } 2434: 2435: sub print_usermodification { 2436: my ($position,$dom,$settings,$rowtotal) = @_; 2437: my $numinrow = 4; 2438: my ($context,$datatable,$rowcount); 2439: if ($position eq 'top') { 2440: $rowcount = 0; 2441: $context = 'author'; 2442: foreach my $role ('ca','aa') { 2443: $datatable .= &modifiable_userdata_row($context,$role,$settings, 2444: $numinrow,$rowcount); 2445: $$rowtotal ++; 2446: $rowcount ++; 2447: } 2448: } elsif ($position eq 'middle') { 2449: $context = 'course'; 2450: $rowcount = 0; 2451: foreach my $role ('st','ep','ta','in','cr') { 2452: $datatable .= &modifiable_userdata_row($context,$role,$settings, 2453: $numinrow,$rowcount); 2454: $$rowtotal ++; 2455: $rowcount ++; 2456: } 2457: } elsif ($position eq 'bottom') { 2458: $context = 'selfcreate'; 2459: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 2460: $usertypes->{'default'} = $othertitle; 2461: if (ref($types) eq 'ARRAY') { 2462: push(@{$types},'default'); 2463: $usertypes->{'default'} = $othertitle; 2464: foreach my $status (@{$types}) { 2465: $datatable .= &modifiable_userdata_row($context,$status,$settings, 2466: $numinrow,$rowcount,$usertypes); 2467: $$rowtotal ++; 2468: $rowcount ++; 2469: } 2470: } 2471: } 2472: return $datatable; 2473: } 2474: 2475: sub print_defaults { 2476: my ($dom,$rowtotal) = @_; 2477: my @items = ('auth_def','auth_arg_def','lang_def','timezone_def', 2478: 'datelocale_def'); 2479: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 2480: my $titles = &defaults_titles(); 2481: my $rownum = 0; 2482: my ($datatable,$css_class); 2483: foreach my $item (@items) { 2484: if ($rownum%2) { 2485: $css_class = ''; 2486: } else { 2487: $css_class = ' class="LC_odd_row" '; 2488: } 2489: $datatable .= '<tr'.$css_class.'>'. 2490: '<td><span class="LC_nobreak">'.$titles->{$item}. 2491: '</span></td><td class="LC_right_item">'; 2492: if ($item eq 'auth_def') { 2493: my @authtypes = ('internal','krb4','krb5','localauth'); 2494: my %shortauth = ( 2495: internal => 'int', 2496: krb4 => 'krb4', 2497: krb5 => 'krb5', 2498: localauth => 'loc' 2499: ); 2500: my %authnames = &authtype_names(); 2501: foreach my $auth (@authtypes) { 2502: my $checked = ' '; 2503: if ($domdefaults{$item} eq $auth) { 2504: $checked = ' checked="checked" '; 2505: } 2506: $datatable .= '<label><input type="radio" name="'.$item. 2507: '" value="'.$auth.'"'.$checked.'/>'. 2508: $authnames{$shortauth{$auth}}.'</label> '; 2509: } 2510: } elsif ($item eq 'timezone_def') { 2511: my $includeempty = 1; 2512: $datatable .= &Apache::loncommon::select_timezone($item,$domdefaults{$item},undef,$includeempty); 2513: } elsif ($item eq 'datelocale_def') { 2514: my $includeempty = 1; 2515: $datatable .= &Apache::loncommon::select_datelocale($item,$domdefaults{$item},undef,$includeempty); 2516: } else { 2517: $datatable .= '<input type="text" name="'.$item.'" value="'. 2518: $domdefaults{$item}.'" />'; 2519: } 2520: $datatable .= '</td></tr>'; 2521: $rownum ++; 2522: } 2523: $$rowtotal += $rownum; 2524: return $datatable; 2525: } 2526: 2527: sub defaults_titles { 2528: my %titles = &Apache::lonlocal::texthash ( 2529: 'auth_def' => 'Default authentication type', 2530: 'auth_arg_def' => 'Default authentication argument', 2531: 'lang_def' => 'Default language', 2532: 'timezone_def' => 'Default timezone', 2533: 'datelocale_def' => 'Default locale for dates', 2534: ); 2535: return (\%titles); 2536: } 2537: 2538: sub print_scantronformat { 2539: my ($r,$dom,$confname,$settings,$rowtotal) = @_; 2540: my $itemcount = 1; 2541: my ($datatable,$css_class,$scantronurl,$is_custom,%error,%scantronurls, 2542: %confhash); 2543: my $switchserver = &check_switchserver($dom,$confname); 2544: my %lt = &Apache::lonlocal::texthash ( 2545: default => 'Default bubblesheet format file error', 2546: custom => 'Custom bubblesheet format file error', 2547: ); 2548: my %scantronfiles = ( 2549: default => 'default.tab', 2550: custom => 'custom.tab', 2551: ); 2552: foreach my $key (keys(%scantronfiles)) { 2553: $scantronurls{$key} = '/res/'.$dom.'/'.$confname.'/scantron/' 2554: .$scantronfiles{$key}; 2555: } 2556: my @defaultinfo = &Apache::lonnet::stat_file($scantronurls{'default'}); 2557: if ((!@defaultinfo) || ($defaultinfo[0] eq 'no_such_dir')) { 2558: if (!$switchserver) { 2559: my $servadm = $r->dir_config('lonAdmEMail'); 2560: my ($configuserok,$author_ok) = &config_check($dom,$confname,$servadm); 2561: if ($configuserok eq 'ok') { 2562: if ($author_ok eq 'ok') { 2563: my %legacyfile = ( 2564: default => $Apache::lonnet::perlvar{'lonTabDir'}.'/default_scantronformat.tab', 2565: custom => $Apache::lonnet::perlvar{'lonTabDir'}.'/scantronformat.tab', 2566: ); 2567: my %md5chk; 2568: foreach my $type (keys(%legacyfile)) { 2569: ($md5chk{$type}) = split(/ /,`md5sum $legacyfile{$type}`); 2570: chomp($md5chk{$type}); 2571: } 2572: if ($md5chk{'default'} ne $md5chk{'custom'}) { 2573: foreach my $type (keys(%legacyfile)) { 2574: ($scantronurls{$type},my $error) = 2575: &legacy_scantronformat($r,$dom,$confname, 2576: $type,$legacyfile{$type}, 2577: $scantronurls{$type}, 2578: $scantronfiles{$type}); 2579: if ($error ne '') { 2580: $error{$type} = $error; 2581: } 2582: } 2583: if (keys(%error) == 0) { 2584: $is_custom = 1; 2585: $confhash{'scantron'}{'scantronformat'} = 2586: $scantronurls{'custom'}; 2587: my $putresult = 2588: &Apache::lonnet::put_dom('configuration', 2589: \%confhash,$dom); 2590: if ($putresult ne 'ok') { 2591: $error{'custom'} = 2592: '<span class="LC_error">'. 2593: &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>'; 2594: } 2595: } 2596: } else { 2597: ($scantronurls{'default'},my $error) = 2598: &legacy_scantronformat($r,$dom,$confname, 2599: 'default',$legacyfile{'default'}, 2600: $scantronurls{'default'}, 2601: $scantronfiles{'default'}); 2602: if ($error eq '') { 2603: $confhash{'scantron'}{'scantronformat'} = ''; 2604: my $putresult = 2605: &Apache::lonnet::put_dom('configuration', 2606: \%confhash,$dom); 2607: if ($putresult ne 'ok') { 2608: $error{'default'} = 2609: '<span class="LC_error">'. 2610: &mt('An error occurred updating the domain configuration: [_1]',$putresult).'</span>'; 2611: } 2612: } else { 2613: $error{'default'} = $error; 2614: } 2615: } 2616: } 2617: } 2618: } else { 2619: $error{'default'} = &mt("Unable to copy default bubblesheet formatfile to domain's RES space: [_1]",$switchserver); 2620: } 2621: } 2622: if (ref($settings) eq 'HASH') { 2623: if ($settings->{'scantronformat'} eq "/res/$dom/$confname/scantron/custom.tab") { 2624: my @info = &Apache::lonnet::stat_file($settings->{'scantronformat'}); 2625: if ((!@info) || ($info[0] eq 'no_such_dir')) { 2626: $scantronurl = ''; 2627: } else { 2628: $scantronurl = $settings->{'scantronformat'}; 2629: } 2630: $is_custom = 1; 2631: } else { 2632: $scantronurl = $scantronurls{'default'}; 2633: } 2634: } else { 2635: if ($is_custom) { 2636: $scantronurl = $scantronurls{'custom'}; 2637: } else { 2638: $scantronurl = $scantronurls{'default'}; 2639: } 2640: } 2641: $css_class = $itemcount%2?' class="LC_odd_row"':''; 2642: $datatable .= '<tr'.$css_class.'>'; 2643: if (!$is_custom) { 2644: $datatable .= '<td>'.&mt('Default in use:').'<br />'. 2645: '<span class="LC_nobreak">'; 2646: if ($scantronurl) { 2647: $datatable .= '<a href="'.$scantronurl.'" target="_blank">'. 2648: &mt('Default scantron format file').'</a>'; 2649: } else { 2650: $datatable = &mt('File unavailable for display'); 2651: } 2652: $datatable .= '</span></td>'; 2653: if (keys(%error) == 0) { 2654: $datatable .= '<td valign="bottom">'; 2655: if (!$switchserver) { 2656: $datatable .= &mt('Upload:').'<br />'; 2657: } 2658: } else { 2659: my $errorstr; 2660: foreach my $key (sort(keys(%error))) { 2661: $errorstr .= $lt{$key}.': '.$error{$key}.'<br />'; 2662: } 2663: $datatable .= '<td>'.$errorstr; 2664: } 2665: } else { 2666: if (keys(%error) > 0) { 2667: my $errorstr; 2668: foreach my $key (sort(keys(%error))) { 2669: $errorstr .= $lt{$key}.': '.$error{$key}.'<br />'; 2670: } 2671: $datatable .= '<td>'.$errorstr.'</td><td> '; 2672: } elsif ($scantronurl) { 2673: $datatable .= '<td><span class="LC_nobreak">'. 2674: '<a href="'.$scantronurl.'" target="_blank">'. 2675: &mt('Custom scantron format file').'</a><label>'. 2676: '<input type="checkbox" name="scantronformat_del"'. 2677: '" value="1" />'.&mt('Delete?').'</label></span></td>'. 2678: '<td><span class="LC_nobreak"> '. 2679: &mt('Replace:').'</span><br />'; 2680: } 2681: } 2682: if (keys(%error) == 0) { 2683: if ($switchserver) { 2684: $datatable .= &mt('Upload to library server: [_1]',$switchserver); 2685: } else { 2686: $datatable .='<span class="LC_nobreak"> '. 2687: '<input type="file" name="scantronformat" /></span>'; 2688: } 2689: } 2690: $datatable .= '</td></tr>'; 2691: $$rowtotal ++; 2692: return $datatable; 2693: } 2694: 2695: sub legacy_scantronformat { 2696: my ($r,$dom,$confname,$file,$legacyfile,$newurl,$newfile) = @_; 2697: my ($url,$error); 2698: my @statinfo = &Apache::lonnet::stat_file($newurl); 2699: if ((!@statinfo) || ($statinfo[0] eq 'no_such_dir')) { 2700: (my $result,$url) = 2701: &publishlogo($r,'copy',$legacyfile,$dom,$confname,'scantron', 2702: '','',$newfile); 2703: if ($result ne 'ok') { 2704: $error = &mt("An error occurred publishing the [_1] scantron format file in RES space. Error was: [_2].",$newfile,$result); 2705: } 2706: } 2707: return ($url,$error); 2708: } 2709: 2710: sub print_coursecategories { 2711: my ($position,$dom,$hdritem,$settings,$rowtotal) = @_; 2712: my $datatable; 2713: if ($position eq 'top') { 2714: my $toggle_cats_crs = ' '; 2715: my $toggle_cats_dom = ' checked="checked" '; 2716: my $can_cat_crs = ' '; 2717: my $can_cat_dom = ' checked="checked" '; 2718: my $toggle_catscomm_comm = ' '; 2719: my $toggle_catscomm_dom = ' checked="checked" '; 2720: my $can_catcomm_comm = ' '; 2721: my $can_catcomm_dom = ' checked="checked" '; 2722: 2723: if (ref($settings) eq 'HASH') { 2724: if ($settings->{'togglecats'} eq 'crs') { 2725: $toggle_cats_crs = $toggle_cats_dom; 2726: $toggle_cats_dom = ' '; 2727: } 2728: if ($settings->{'categorize'} eq 'crs') { 2729: $can_cat_crs = $can_cat_dom; 2730: $can_cat_dom = ' '; 2731: } 2732: if ($settings->{'togglecatscomm'} eq 'comm') { 2733: $toggle_catscomm_comm = $toggle_catscomm_dom; 2734: $toggle_catscomm_dom = ' '; 2735: } 2736: if ($settings->{'categorizecomm'} eq 'comm') { 2737: $can_catcomm_comm = $can_catcomm_dom; 2738: $can_catcomm_dom = ' '; 2739: } 2740: } 2741: my %title = &Apache::lonlocal::texthash ( 2742: togglecats => 'Show/Hide a course in catalog', 2743: togglecatscomm => 'Show/Hide a community in catalog', 2744: categorize => 'Assign a category to a course', 2745: categorizecomm => 'Assign a category to a community', 2746: ); 2747: my %level = &Apache::lonlocal::texthash ( 2748: dom => 'Set in Domain', 2749: crs => 'Set in Course', 2750: comm => 'Set in Community', 2751: ); 2752: $datatable = '<tr class="LC_odd_row">'. 2753: '<td>'.$title{'togglecats'}.'</td>'. 2754: '<td class="LC_right_item"><span class="LC_nobreak"><label>'. 2755: '<input type="radio" name="togglecats"'. 2756: $toggle_cats_dom.' value="dom" />'.$level{'dom'}.'</label> '. 2757: '<label><input type="radio" name="togglecats"'. 2758: $toggle_cats_crs.' value="crs" />'.$level{'crs'}.'</label></span></td>'. 2759: '</tr><tr>'. 2760: '<td>'.$title{'categorize'}.'</td>'. 2761: '<td class="LC_right_item"><span class="LC_nobreak">'. 2762: '<label><input type="radio" name="categorize"'. 2763: $can_cat_dom.' value="dom" />'.$level{'dom'}.'</label> '. 2764: '<label><input type="radio" name="categorize"'. 2765: $can_cat_crs.'value="crs" />'.$level{'crs'}.'</label></span></td>'. 2766: '</tr><tr class="LC_odd_row">'. 2767: '<td>'.$title{'togglecatscomm'}.'</td>'. 2768: '<td class="LC_right_item"><span class="LC_nobreak"><label>'. 2769: '<input type="radio" name="togglecatscomm"'. 2770: $toggle_catscomm_dom.' value="dom" />'.$level{'dom'}.'</label> '. 2771: '<label><input type="radio" name="togglecatscomm"'. 2772: $toggle_catscomm_comm.' value="comm" />'.$level{'comm'}.'</label></span></td>'. 2773: '</tr><tr>'. 2774: '<td>'.$title{'categorizecomm'}.'</td>'. 2775: '<td class="LC_right_item"><span class="LC_nobreak">'. 2776: '<label><input type="radio" name="categorizecomm"'. 2777: $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label> '. 2778: '<label><input type="radio" name="categorizecomm"'. 2779: $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'. 2780: '</tr>'; 2781: $$rowtotal += 4; 2782: } else { 2783: my $css_class; 2784: my $itemcount = 1; 2785: my $cathash; 2786: if (ref($settings) eq 'HASH') { 2787: $cathash = $settings->{'cats'}; 2788: } 2789: if (ref($cathash) eq 'HASH') { 2790: my (@cats,@trails,%allitems,%idx,@jsarray); 2791: &Apache::loncommon::extract_categories($cathash,\@cats,\@trails, 2792: \%allitems,\%idx,\@jsarray); 2793: my $maxdepth = scalar(@cats); 2794: my $colattrib = ''; 2795: if ($maxdepth > 2) { 2796: $colattrib = ' colspan="2" '; 2797: } 2798: my @path; 2799: if (@cats > 0) { 2800: if (ref($cats[0]) eq 'ARRAY') { 2801: my $numtop = @{$cats[0]}; 2802: my $maxnum = $numtop; 2803: my %default_names = ( 2804: instcode => &mt('Official courses'), 2805: communities => &mt('Communities'), 2806: ); 2807: 2808: if ((!grep(/^instcode$/,@{$cats[0]})) || 2809: ($cathash->{'instcode::0'} eq '') || 2810: (!grep(/^communities$/,@{$cats[0]})) || 2811: ($cathash->{'communities::0'} eq '')) { 2812: $maxnum ++; 2813: } 2814: my $lastidx; 2815: for (my $i=0; $i<$numtop; $i++) { 2816: my $parent = $cats[0][$i]; 2817: $css_class = $itemcount%2?' class="LC_odd_row"':''; 2818: my $item = &escape($parent).'::0'; 2819: my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$item','$idx{$item}'".');"'; 2820: $lastidx = $idx{$item}; 2821: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' 2822: .'<select name="'.$item.'"'.$chgstr.'>'; 2823: for (my $k=0; $k<=$maxnum; $k++) { 2824: my $vpos = $k+1; 2825: my $selstr; 2826: if ($k == $i) { 2827: $selstr = ' selected="selected" '; 2828: } 2829: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; 2830: } 2831: $datatable .= '</select></td><td>'; 2832: if ($parent eq 'instcode' || $parent eq 'communities') { 2833: $datatable .= '<span class="LC_nobreak">' 2834: .$default_names{$parent}.'</span>'; 2835: if ($parent eq 'instcode') { 2836: $datatable .= '<br /><span class="LC_nobreak">(' 2837: .&mt('with institutional codes') 2838: .')</span></td><td'.$colattrib.'>'; 2839: } else { 2840: $datatable .= '<table><tr><td>'; 2841: } 2842: $datatable .= '<span class="LC_nobreak">' 2843: .'<label><input type="radio" name="' 2844: .$parent.'" value="1" checked="checked" />' 2845: .&mt('Display').'</label>'; 2846: if ($parent eq 'instcode') { 2847: $datatable .= ' '; 2848: } else { 2849: $datatable .= '</span></td></tr><tr><td>' 2850: .'<span class="LC_nobreak">'; 2851: } 2852: $datatable .= '<label><input type="radio" name="' 2853: .$parent.'" value="0" />' 2854: .&mt('Do not display').'</label></span>'; 2855: if ($parent eq 'communities') { 2856: $datatable .= '</td></tr></table>'; 2857: } 2858: $datatable .= '</td>'; 2859: } else { 2860: $datatable .= $parent 2861: .' <label><input type="checkbox" name="deletecategory" ' 2862: .'value="'.$item.'" />'.&mt('Delete').'</label></span></td>'; 2863: } 2864: my $depth = 1; 2865: push(@path,$parent); 2866: $datatable .= &build_category_rows($itemcount,\@cats,$depth,$parent,\@path,\%idx); 2867: pop(@path); 2868: $datatable .= '</tr><tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr>'; 2869: $itemcount ++; 2870: } 2871: $css_class = $itemcount%2?' class="LC_odd_row"':''; 2872: my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','$lastidx'".');"'; 2873: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="addcategory_pos"'.$chgstr.'>'; 2874: for (my $k=0; $k<=$maxnum; $k++) { 2875: my $vpos = $k+1; 2876: my $selstr; 2877: if ($k == $numtop) { 2878: $selstr = ' selected="selected" '; 2879: } 2880: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; 2881: } 2882: $datatable .= '</select></span></td><td colspan="2">'.&mt('Add category:').' ' 2883: .'<input type="text" size="20" name="addcategory_name" value="" /></td>' 2884: .'</tr>'."\n"; 2885: $itemcount ++; 2886: foreach my $default ('instcode','communities') { 2887: if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) { 2888: $css_class = $itemcount%2?' class="LC_odd_row"':''; 2889: my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"'; 2890: $datatable .= '<tr><td colspan="'.$maxdepth.'" class="LC_row_separator"></td></tr><tr '.$css_class.'><td>'. 2891: '<span class="LC_nobreak"><select name="'.$default.'_pos"'.$chgstr.'>'; 2892: for (my $k=0; $k<=$maxnum; $k++) { 2893: my $vpos = $k+1; 2894: my $selstr; 2895: if ($k == $maxnum) { 2896: $selstr = ' selected="selected" '; 2897: } 2898: $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; 2899: } 2900: $datatable .= '</select></span></td>'. 2901: '<td><span class="LC_nobreak">'. 2902: $default_names{$default}.'</span>'; 2903: if ($default eq 'instcode') { 2904: $datatable .= '<br /><span class="LC_nobreak">(' 2905: .&mt('with institutional codes').')</span>'; 2906: } 2907: $datatable .= '</td>' 2908: .'<td><span class="LC_nobreak"><label><input type="radio" name="'.$default.'" value="1" />' 2909: .&mt('Display').'</label> ' 2910: .'<label><input type="radio" name="'.$default.'" value="0" checked="checked"/>' 2911: .&mt('Do not display').'</label></span></td></tr>'; 2912: } 2913: } 2914: } 2915: } else { 2916: $datatable .= &initialize_categories($itemcount); 2917: } 2918: } else { 2919: $datatable .= '<td class="LC_right_item">'.$hdritem->{'header'}->[0]->{'col2'}.'</td>' 2920: .&initialize_categories($itemcount); 2921: } 2922: $$rowtotal += $itemcount; 2923: } 2924: return $datatable; 2925: } 2926: 2927: sub print_serverstatuses { 2928: my ($dom,$settings,$rowtotal) = @_; 2929: my $datatable; 2930: my @pages = &serverstatus_pages(); 2931: my (%namedaccess,%machineaccess); 2932: foreach my $type (@pages) { 2933: $namedaccess{$type} = ''; 2934: $machineaccess{$type}= ''; 2935: } 2936: if (ref($settings) eq 'HASH') { 2937: foreach my $type (@pages) { 2938: if (exists($settings->{$type})) { 2939: if (ref($settings->{$type}) eq 'HASH') { 2940: foreach my $key (keys(%{$settings->{$type}})) { 2941: if ($key eq 'namedusers') { 2942: $namedaccess{$type} = $settings->{$type}->{$key}; 2943: } elsif ($key eq 'machines') { 2944: $machineaccess{$type} = $settings->{$type}->{$key}; 2945: } 2946: } 2947: } 2948: } 2949: } 2950: } 2951: my $titles= &LONCAPA::lonauthcgi::serverstatus_titles(); 2952: my $rownum = 0; 2953: my $css_class; 2954: foreach my $type (@pages) { 2955: $rownum ++; 2956: $css_class = $rownum%2?' class="LC_odd_row"':''; 2957: $datatable .= '<tr'.$css_class.'>'. 2958: '<td><span class="LC_nobreak">'. 2959: $titles->{$type}.'</span></td>'. 2960: '<td class="LC_left_item">'. 2961: '<input type="text" name="'.$type.'_namedusers" '. 2962: 'value="'.$namedaccess{$type}.'" size="30" /></td>'. 2963: '<td class="LC_right_item">'. 2964: '<span class="LC_nobreak">'. 2965: '<input type="text" name="'.$type.'_machines" '. 2966: 'value="'.$machineaccess{$type}.'" size="10" />'. 2967: '</td></tr>'."\n"; 2968: } 2969: $$rowtotal += $rownum; 2970: return $datatable; 2971: } 2972: 2973: sub serverstatus_pages { 2974: return ('userstatus','lonstatus','loncron','server-status','codeversions', 2975: 'clusterstatus','metadata_keywords','metadata_harvest', 2976: 'takeoffline','takeonline','showenv','toggledebug'); 2977: } 2978: 2979: sub coursecategories_javascript { 2980: my ($settings) = @_; 2981: my ($output,$jstext,$cathash); 2982: if (ref($settings) eq 'HASH') { 2983: $cathash = $settings->{'cats'}; 2984: } 2985: if (ref($cathash) eq 'HASH') { 2986: my (@cats,@jsarray,%idx); 2987: &Apache::loncommon::gather_categories($cathash,\@cats,\%idx,\@jsarray); 2988: if (@jsarray > 0) { 2989: $jstext = ' var categories = Array('.scalar(@jsarray).');'."\n"; 2990: for (my $i=0; $i<@jsarray; $i++) { 2991: if (ref($jsarray[$i]) eq 'ARRAY') { 2992: my $catstr = join('","',@{$jsarray[$i]}); 2993: $jstext .= ' categories['.$i.'] = Array("'.$catstr.'");'."\n"; 2994: } 2995: } 2996: } 2997: } else { 2998: $jstext = ' var categories = Array(1);'."\n". 2999: ' categories[0] = Array("instcode_pos");'."\n"; 3000: } 3001: my $instcode_reserved = &mt('The name: "instcode" is a reserved category'); 3002: my $communities_reserved = &mt('The name: "communities" is a reserved category'); 3003: my $choose_again = '\\n'.&mt('Please use a different name for the new top level category'); 3004: $output = <<"ENDSCRIPT"; 3005: <script type="text/javascript"> 3006: // <![CDATA[ 3007: function reorderCats(form,parent,item,idx) { 3008: var changedVal; 3009: $jstext 3010: var newpos = 'addcategory_pos'; 3011: var current = new Array; 3012: if (parent == '') { 3013: var has_instcode = 0; 3014: var maxtop = categories[idx].length; 3015: for (var j=0; j<maxtop; j++) { 3016: if (categories[idx][j] == 'instcode::0') { 3017: has_instcode == 1; 3018: } 3019: } 3020: if (has_instcode == 0) { 3021: categories[idx][maxtop] = 'instcode_pos'; 3022: } 3023: } else { 3024: newpos += '_'+parent; 3025: } 3026: var maxh = 1 + categories[idx].length; 3027: var current = new Array; 3028: var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value; 3029: if (item == newpos) { 3030: changedVal = newitemVal; 3031: } else { 3032: changedVal = form.elements[item].options[form.elements[item].selectedIndex].value; 3033: current[newitemVal] = newpos; 3034: } 3035: for (var i=0; i<categories[idx].length; i++) { 3036: var elementName = categories[idx][i]; 3037: if (elementName != item) { 3038: if (form.elements[elementName]) { 3039: var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value; 3040: current[currVal] = elementName; 3041: } 3042: } 3043: } 3044: var oldVal; 3045: for (var j=0; j<maxh; j++) { 3046: if (current[j] == undefined) { 3047: oldVal = j; 3048: } 3049: } 3050: if (oldVal < changedVal) { 3051: for (var k=oldVal+1; k<=changedVal ; k++) { 3052: var elementName = current[k]; 3053: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1; 3054: } 3055: } else { 3056: for (var k=changedVal; k<oldVal; k++) { 3057: var elementName = current[k]; 3058: form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1; 3059: } 3060: } 3061: return; 3062: } 3063: 3064: function categoryCheck(form) { 3065: if (form.elements['addcategory_name'].value == 'instcode') { 3066: alert('$instcode_reserved\\n$choose_again'); 3067: return false; 3068: } 3069: if (form.elements['addcategory_name'].value == 'communities') { 3070: alert('$communities_reserved\\n$choose_again'); 3071: return false; 3072: } 3073: return true; 3074: } 3075: 3076: // ]]> 3077: </script> 3078: 3079: ENDSCRIPT 3080: return $output; 3081: } 3082: 3083: sub initialize_categories { 3084: my ($itemcount) = @_; 3085: my ($datatable,$css_class,$chgstr); 3086: my %default_names = ( 3087: instcode => 'Official courses (with institutional codes)', 3088: communities => 'Communities', 3089: ); 3090: my $select0 = ' selected="selected"'; 3091: my $select1 = ''; 3092: foreach my $default ('instcode','communities') { 3093: $css_class = $itemcount%2?' class="LC_odd_row"':''; 3094: $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"'; 3095: if ($default eq 'communities') { 3096: $select1 = $select0; 3097: $select0 = ''; 3098: } 3099: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' 3100: .'<select name="'.$default.'_pos">' 3101: .'<option value="0"'.$select0.'>1</option>' 3102: .'<option value="1"'.$select1.'>2</option>' 3103: .'<option value="2">3</option></select> ' 3104: .$default_names{$default} 3105: .'</span></td><td><span class="LC_nobreak">' 3106: .'<label><input type="radio" name="'.$default.'" value="1" checked="checked" />' 3107: .&mt('Display').'</label> <label>' 3108: .'<input type="radio" name="'.$default.'" value="0" />'.&mt('Do not display') 3109: .'</label></span></td></tr>'; 3110: $itemcount ++; 3111: } 3112: $css_class = $itemcount%2?' class="LC_odd_row"':''; 3113: $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','addcategory_pos','0'".');"'; 3114: $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' 3115: .'<select name="addcategory_pos"'.$chgstr.'>' 3116: .'<option value="0">1</option>' 3117: .'<option value="1">2</option>' 3118: .'<option value="2" selected="selected">3</option></select> ' 3119: .&mt('Add category').'</td><td>'.&mt('Name:') 3120: .' <input type="text" size="20" name="addcategory_name" value="" /></td></tr>'; 3121: return $datatable; 3122: } 3123: 3124: sub build_category_rows { 3125: my ($itemcount,$cats,$depth,$parent,$path,$idx) = @_; 3126: my ($text,$name,$item,$chgstr); 3127: if (ref($cats) eq 'ARRAY') { 3128: my $maxdepth = scalar(@{$cats}); 3129: if (ref($cats->[$depth]) eq 'HASH') { 3130: if (ref($cats->[$depth]{$parent}) eq 'ARRAY') { 3131: my $numchildren = @{$cats->[$depth]{$parent}}; 3132: my $css_class = $itemcount%2?' class="LC_odd_row"':''; 3133: $text .= '<td><table class="LC_datatable">'; 3134: my ($idxnum,$parent_name,$parent_item); 3135: my $higher = $depth - 1; 3136: if ($higher == 0) { 3137: $parent_name = &escape($parent).'::'.$higher; 3138: } else { 3139: if (ref($path) eq 'ARRAY') { 3140: $parent_name = &escape($parent).':'.&escape($path->[-2]).':'.$higher; 3141: } 3142: } 3143: $parent_item = 'addcategory_pos_'.$parent_name; 3144: for (my $j=0; $j<=$numchildren; $j++) { 3145: if ($j < $numchildren) { 3146: $name = $cats->[$depth]{$parent}[$j]; 3147: $item = &escape($name).':'.&escape($parent).':'.$depth; 3148: $idxnum = $idx->{$item}; 3149: } else { 3150: $name = $parent_name; 3151: $item = $parent_item; 3152: } 3153: $chgstr = ' onchange="javascript:reorderCats(this.form,'."'$parent_name','$item','$idxnum'".');"'; 3154: $text .= '<tr '.$css_class.'><td><span class="LC_nobreak"><select name="'.$item.'"'.$chgstr.'>'; 3155: for (my $i=0; $i<=$numchildren; $i++) { 3156: my $vpos = $i+1; 3157: my $selstr; 3158: if ($j == $i) { 3159: $selstr = ' selected="selected" '; 3160: } 3161: $text .= '<option value="'.$i.'"'.$selstr.'>'.$vpos.'</option>'; 3162: } 3163: $text .= '</select> '; 3164: if ($j < $numchildren) { 3165: my $deeper = $depth+1; 3166: $text .= $name.' ' 3167: .'<label><input type="checkbox" name="deletecategory" value="' 3168: .$item.'" />'.&mt('Delete').'</label></span></td><td>'; 3169: if(ref($path) eq 'ARRAY') { 3170: push(@{$path},$name); 3171: $text .= &build_category_rows($itemcount,$cats,$deeper,$name,$path,$idx); 3172: pop(@{$path}); 3173: } 3174: } else { 3175: $text .= &mt('Add subcategory:').' </span><input type="textbox" size="20" name="addcategory_name_'; 3176: if ($j == $numchildren) { 3177: $text .= $name; 3178: } else { 3179: $text .= $item; 3180: } 3181: $text .= '" value="" />'; 3182: } 3183: $text .= '</td></tr>'; 3184: } 3185: $text .= '</table></td>'; 3186: } else { 3187: my $higher = $depth-1; 3188: if ($higher == 0) { 3189: $name = &escape($parent).'::'.$higher; 3190: } else { 3191: if (ref($path) eq 'ARRAY') { 3192: $name = &escape($parent).':'.&escape($path->[-2]).':'.$higher; 3193: } 3194: } 3195: my $colspan; 3196: if ($parent ne 'instcode') { 3197: $colspan = $maxdepth - $depth - 1; 3198: $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="textbox" size="20" name="subcat_'.$name.'" value="" /></td>'; 3199: } 3200: } 3201: } 3202: } 3203: return $text; 3204: } 3205: 3206: sub modifiable_userdata_row { 3207: my ($context,$role,$settings,$numinrow,$rowcount,$usertypes) = @_; 3208: my $rolename; 3209: if ($context eq 'selfcreate') { 3210: if (ref($usertypes) eq 'HASH') { 3211: $rolename = $usertypes->{$role}; 3212: } else { 3213: $rolename = $role; 3214: } 3215: } else { 3216: if ($role eq 'cr') { 3217: $rolename = &mt('Custom role'); 3218: } else { 3219: $rolename = &Apache::lonnet::plaintext($role); 3220: } 3221: } 3222: my @fields = ('lastname','firstname','middlename','generation', 3223: 'permanentemail','id'); 3224: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); 3225: my $output; 3226: my $css_class = $rowcount%2?' class="LC_odd_row"':''; 3227: $output = '<tr '.$css_class.'>'. 3228: '<td><span class="LC_nobreak">'.$rolename.'</span></td>'. 3229: '<td class="LC_left_item" colspan="2"><table>'; 3230: my $rem; 3231: my %checks; 3232: if (ref($settings) eq 'HASH') { 3233: if (ref($settings->{$context}) eq 'HASH') { 3234: if (ref($settings->{$context}->{$role}) eq 'HASH') { 3235: foreach my $field (@fields) { 3236: if ($settings->{$context}->{$role}->{$field}) { 3237: $checks{$field} = ' checked="checked" '; 3238: } 3239: } 3240: } 3241: } 3242: } 3243: for (my $i=0; $i<@fields; $i++) { 3244: my $rem = $i%($numinrow); 3245: if ($rem == 0) { 3246: if ($i > 0) { 3247: $output .= '</tr>'; 3248: } 3249: $output .= '<tr>'; 3250: } 3251: my $check = ' '; 3252: if (exists($checks{$fields[$i]})) { 3253: $check = $checks{$fields[$i]} 3254: } else { 3255: if ($role eq 'st') { 3256: if (ref($settings) ne 'HASH') { 3257: $check = ' checked="checked" '; 3258: } 3259: } 3260: } 3261: $output .= '<td class="LC_left_item">'. 3262: '<span class="LC_nobreak"><label>'. 3263: '<input type="checkbox" name="canmodify_'.$role.'" '. 3264: 'value="'.$fields[$i].'"'.$check.'/>'.$fieldtitles{$fields[$i]}. 3265: '</label></span></td>'; 3266: $rem = @fields%($numinrow); 3267: } 3268: my $colsleft = $numinrow - $rem; 3269: if ($colsleft > 1 ) { 3270: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'. 3271: ' </td>'; 3272: } elsif ($colsleft == 1) { 3273: $output .= '<td class="LC_left_item"> </td>'; 3274: } 3275: $output .= '</tr></table></td></tr>'; 3276: return $output; 3277: } 3278: 3279: sub insttypes_row { 3280: my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context) = @_; 3281: my %lt = &Apache::lonlocal::texthash ( 3282: cansearch => 'Users allowed to search', 3283: statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)', 3284: ); 3285: my $showdom; 3286: if ($context eq 'cansearch') { 3287: $showdom = ' ('.$dom.')'; 3288: } 3289: my $output = '<tr class="LC_odd_row">'. 3290: '<td>'.$lt{$context}.$showdom. 3291: '</td><td class="LC_left_item" colspan="2"><table>'; 3292: my $rem; 3293: if (ref($types) eq 'ARRAY') { 3294: for (my $i=0; $i<@{$types}; $i++) { 3295: if (defined($usertypes->{$types->[$i]})) { 3296: my $rem = $i%($numinrow); 3297: if ($rem == 0) { 3298: if ($i > 0) { 3299: $output .= '</tr>'; 3300: } 3301: $output .= '<tr>'; 3302: } 3303: my $check = ' '; 3304: if (ref($settings) eq 'HASH') { 3305: if (ref($settings->{$context}) eq 'ARRAY') { 3306: if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) { 3307: $check = ' checked="checked" '; 3308: } 3309: } elsif ($context eq 'statustocreate') { 3310: $check = ' checked="checked" '; 3311: } 3312: } 3313: $output .= '<td class="LC_left_item">'. 3314: '<span class="LC_nobreak"><label>'. 3315: '<input type="checkbox" name="'.$context.'" '. 3316: 'value="'.$types->[$i].'"'.$check.'/>'. 3317: $usertypes->{$types->[$i]}.'</label></span></td>'; 3318: } 3319: } 3320: 3321: $rem = @{$types}%($numinrow); 3322: } 3323: my $colsleft = $numinrow - $rem; 3324: if ($colsleft > 1) { 3325: $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; 3326: } else { 3327: $output .= '<td class="LC_left_item">'; 3328: } 3329: my $defcheck = ' '; 3330: if (ref($settings) eq 'HASH') { 3331: if (ref($settings->{$context}) eq 'ARRAY') { 3332: if (grep(/^default$/,@{$settings->{$context}})) { 3333: $defcheck = ' checked="checked" '; 3334: } 3335: } elsif ($context eq 'statustocreate') { 3336: $defcheck = ' checked="checked" '; 3337: } 3338: } 3339: $output .= '<span class="LC_nobreak"><label>'. 3340: '<input type="checkbox" name="'.$context.'" '. 3341: 'value="default"'.$defcheck.'/>'. 3342: $othertitle.'</label></span></td>'. 3343: '</tr></table></td></tr>'; 3344: return $output; 3345: } 3346: 3347: sub sorted_searchtitles { 3348: my %searchtitles = &Apache::lonlocal::texthash( 3349: 'uname' => 'username', 3350: 'lastname' => 'last name', 3351: 'lastfirst' => 'last name, first name', 3352: ); 3353: my @titleorder = ('uname','lastname','lastfirst'); 3354: return (\%searchtitles,\@titleorder); 3355: } 3356: 3357: sub sorted_searchtypes { 3358: my %srchtypes_desc = ( 3359: exact => 'is exact match', 3360: contains => 'contains ..', 3361: begins => 'begins with ..', 3362: ); 3363: my @srchtypeorder = ('exact','begins','contains'); 3364: return (\%srchtypes_desc,\@srchtypeorder); 3365: } 3366: 3367: sub usertype_update_row { 3368: my ($settings,$usertypes,$fieldtitles,$fields,$types,$rownums) = @_; 3369: my $datatable; 3370: my $numinrow = 4; 3371: foreach my $type (@{$types}) { 3372: if (defined($usertypes->{$type})) { 3373: $$rownums ++; 3374: my $css_class = $$rownums%2?' class="LC_odd_row"':''; 3375: $datatable .= '<tr'.$css_class.'><td>'.$usertypes->{$type}. 3376: '</td><td class="LC_left_item"><table>'; 3377: for (my $i=0; $i<@{$fields}; $i++) { 3378: my $rem = $i%($numinrow); 3379: if ($rem == 0) { 3380: if ($i > 0) { 3381: $datatable .= '</tr>'; 3382: } 3383: $datatable .= '<tr>'; 3384: } 3385: my $check = ' '; 3386: if (ref($settings) eq 'HASH') { 3387: if (ref($settings->{'fields'}) eq 'HASH') { 3388: if (ref($settings->{'fields'}{$type}) eq 'ARRAY') { 3389: if (grep(/^\Q$fields->[$i]\E$/,@{$settings->{'fields'}{$type}})) { 3390: $check = ' checked="checked" '; 3391: } 3392: } 3393: } 3394: } 3395: 3396: if ($i == @{$fields}-1) { 3397: my $colsleft = $numinrow - $rem; 3398: if ($colsleft > 1) { 3399: $datatable .= '<td colspan="'.$colsleft.'">'; 3400: } else { 3401: $datatable .= '<td>'; 3402: } 3403: } else { 3404: $datatable .= '<td>'; 3405: } 3406: $datatable .= '<span class="LC_nobreak"><label>'. 3407: '<input type="checkbox" name="updateable_'.$type. 3408: '_'.$fields->[$i].'" value="1"'.$check.'/>'. 3409: $fieldtitles->{$fields->[$i]}.'</label></span></td>'; 3410: } 3411: $datatable .= '</tr></table></td></tr>'; 3412: } 3413: } 3414: return $datatable; 3415: } 3416: 3417: sub modify_login { 3418: my ($r,$dom,$confname,%domconfig) = @_; 3419: my ($resulttext,$errors,$colchgtext,%changes,%colchanges); 3420: my %title = ( coursecatalog => 'Display course catalog', 3421: adminmail => 'Display administrator E-mail address', 3422: newuser => 'Link for visitors to create a user account', 3423: loginheader => 'Log-in box header'); 3424: my @offon = ('off','on'); 3425: my %curr_loginvia; 3426: if (ref($domconfig{login}) eq 'HASH') { 3427: if (ref($domconfig{login}{loginvia}) eq 'HASH') { 3428: foreach my $lonhost (keys(%{$domconfig{login}{loginvia}})) { 3429: $curr_loginvia{$lonhost} = $domconfig{login}{loginvia}{$lonhost}; 3430: } 3431: } 3432: } 3433: my %loginhash; 3434: ($errors,%colchanges) = &modify_colors($r,$dom,$confname,['login'], 3435: \%domconfig,\%loginhash); 3436: my @toggles = ('coursecatalog','adminmail','newuser'); 3437: foreach my $item (@toggles) { 3438: $loginhash{login}{$item} = $env{'form.'.$item}; 3439: } 3440: $loginhash{login}{loginheader} = $env{'form.loginheader'}; 3441: if (ref($colchanges{'login'}) eq 'HASH') { 3442: $colchgtext = &display_colorchgs($dom,\%colchanges,['login'], 3443: \%loginhash); 3444: } 3445: 3446: my %servers = &dom_servers($dom); 3447: if (keys(%servers) > 1) { 3448: foreach my $lonhost (keys(%servers)) { 3449: next if ($env{'form.'.$lonhost.'_serverurl'} eq $lonhost); 3450: if ($env{'form.'.$lonhost.'_serverurl'} eq $curr_loginvia{$lonhost}) { 3451: $loginhash{login}{loginvia}{$lonhost} = $curr_loginvia{$lonhost}; next; 3452: } 3453: if ($curr_loginvia{$lonhost} ne '') { 3454: $loginhash{login}{loginvia}{$lonhost} = $env{'form.'.$lonhost.'_serverurl'}; 3455: $changes{'loginvia'}{$lonhost} = 1; 3456: } else { 3457: if (defined($servers{$env{'form.'.$lonhost.'_serverurl'}})) { 3458: $loginhash{login}{loginvia}{$lonhost} = $env{'form.'.$lonhost.'_serverurl'}; 3459: $changes{'loginvia'}{$lonhost} = 1; 3460: } 3461: } 3462: } 3463: } 3464: 3465: my $putresult = &Apache::lonnet::put_dom('configuration',\%loginhash, 3466: $dom); 3467: if ($putresult eq 'ok') { 3468: my @toggles = ('coursecatalog','adminmail','newuser'); 3469: my %defaultchecked = ( 3470: 'coursecatalog' => 'on', 3471: 'adminmail' => 'off', 3472: 'newuser' => 'off', 3473: ); 3474: if (ref($domconfig{'login'}) eq 'HASH') { 3475: foreach my $item (@toggles) { 3476: if ($defaultchecked{$item} eq 'on') { 3477: if (($domconfig{'login'}{$item} eq '0') && 3478: ($env{'form.'.$item} eq '1')) { 3479: $changes{$item} = 1; 3480: } elsif (($domconfig{'login'}{$item} eq '' || 3481: $domconfig{'login'}{$item} eq '1') && 3482: ($env{'form.'.$item} eq '0')) { 3483: $changes{$item} = 1; 3484: } 3485: } elsif ($defaultchecked{$item} eq 'off') { 3486: if (($domconfig{'login'}{$item} eq '1') && 3487: ($env{'form.'.$item} eq '0')) { 3488: $changes{$item} = 1; 3489: } elsif (($domconfig{'login'}{$item} eq '' || 3490: $domconfig{'login'}{$item} eq '0') && 3491: ($env{'form.'.$item} eq '1')) { 3492: $changes{$item} = 1; 3493: } 3494: } 3495: } 3496: if (($domconfig{'login'}{'loginheader'} eq 'text') && 3497: ($env{'form.loginheader'} eq 'image')) { 3498: $changes{'loginheader'} = 1; 3499: } elsif (($domconfig{'login'}{'loginheader'} eq '' || 3500: $domconfig{'login'}{'loginheader'} eq 'image') && 3501: ($env{'form.loginheader'} eq 'text')) { 3502: $changes{'loginheader'} = 1; 3503: } 3504: } 3505: if (keys(%changes) > 0 || $colchgtext) { 3506: &Apache::loncommon::devalidate_domconfig_cache($dom); 3507: $resulttext = &mt('Changes made:').'<ul>'; 3508: foreach my $item (sort(keys(%changes))) { 3509: if ($item eq 'loginheader') { 3510: $resulttext .= '<li>'.&mt("$title{$item} set to $env{'form.loginheader'}").'</li>'; 3511: } elsif ($item eq 'loginvia') { 3512: if (ref($changes{$item}) eq 'HASH') { 3513: $resulttext .= '<li>'.&mt('Log-in page availability:').'<ul>'; 3514: foreach my $lonhost (sort(keys(%{$changes{$item}}))) { 3515: if ($servers{$env{'form.'.$lonhost.'_serverurl'}} ne '') { 3516: $resulttext .= '<li>'.&mt('Server: [_1] log-in page now redirects to [_2]',$lonhost,$servers{$env{'form.'.$lonhost.'_serverurl'}}).'</li>'; 3517: } else { 3518: $resulttext .= '<li>'.&mt('Server: [_1] now has standard log-in page.',$lonhost).'</li>'; 3519: } 3520: } 3521: $resulttext .= '</ul></li>'; 3522: } 3523: } else { 3524: $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>'; 3525: } 3526: } 3527: $resulttext .= $colchgtext.'</ul>'; 3528: } else { 3529: $resulttext = &mt('No changes made to log-in page settings'); 3530: } 3531: } else { 3532: $resulttext = '<span class="LC_error">'. 3533: &mt('An error occurred: [_1]',$putresult).'</span>'; 3534: } 3535: if ($errors) { 3536: $resulttext .= '<br />'.&mt('The following errors occurred: ').'<ul>'. 3537: $errors.'</ul>'; 3538: } 3539: return $resulttext; 3540: } 3541: 3542: sub color_font_choices { 3543: my %choices = 3544: &Apache::lonlocal::texthash ( 3545: img => "Header", 3546: bgs => "Background colors", 3547: links => "Link colors", 3548: images => "Images", 3549: font => "Font color", 3550: fontmenu => "Font Menu", 3551: pgbg => "Page", 3552: tabbg => "Header", 3553: sidebg => "Border", 3554: link => "Link", 3555: alink => "Active link", 3556: vlink => "Visited link", 3557: ); 3558: return %choices; 3559: } 3560: 3561: sub modify_rolecolors { 3562: my ($r,$dom,$confname,$roles,%domconfig) = @_; 3563: my ($resulttext,%rolehash); 3564: $rolehash{'rolecolors'} = {}; 3565: if (ref($domconfig{'rolecolors'}) ne 'HASH') { 3566: if ($domconfig{'rolecolors'} eq '') { 3567: $domconfig{'rolecolors'} = {}; 3568: } 3569: } 3570: my ($errors,%changes) = &modify_colors($r,$dom,$confname,$roles, 3571: $domconfig{'rolecolors'},$rolehash{'rolecolors'}); 3572: my $putresult = &Apache::lonnet::put_dom('configuration',\%rolehash, 3573: $dom); 3574: if ($putresult eq 'ok') { 3575: if (keys(%changes) > 0) { 3576: &Apache::loncommon::devalidate_domconfig_cache($dom); 3577: $resulttext = &display_colorchgs($dom,\%changes,$roles, 3578: $rolehash{'rolecolors'}); 3579: } else { 3580: $resulttext = &mt('No changes made to default color schemes'); 3581: } 3582: } else { 3583: $resulttext = '<span class="LC_error">'. 3584: &mt('An error occurred: [_1]',$putresult).'</span>'; 3585: } 3586: if ($errors) { 3587: $resulttext .= &mt('The following errors occurred: ').'<ul>'. 3588: $errors.'</ul>'; 3589: } 3590: return $resulttext; 3591: } 3592: 3593: sub modify_colors { 3594: my ($r,$dom,$confname,$roles,$domconfig,$confhash) = @_; 3595: my (%changes,%choices); 3596: my @bgs; 3597: my @links = ('link','alink','vlink'); 3598: my @logintext; 3599: my @images; 3600: my $servadm = $r->dir_config('lonAdmEMail'); 3601: my $errors; 3602: foreach my $role (@{$roles}) { 3603: if ($role eq 'login') { 3604: %choices = &login_choices(); 3605: @logintext = ('textcol','bgcol'); 3606: } else { 3607: %choices = &color_font_choices(); 3608: $confhash->{$role}{'fontmenu'} = $env{'form.'.$role.'_fontmenu'}; 3609: } 3610: if ($role eq 'login') { 3611: @images = ('img','logo','domlogo','login'); 3612: @bgs = ('pgbg','mainbg','sidebg'); 3613: } else { 3614: @images = ('img'); 3615: @bgs = ('pgbg','tabbg','sidebg'); 3616: } 3617: $confhash->{$role}{'font'} = $env{'form.'.$role.'_font'}; 3618: foreach my $item (@bgs,@links,@logintext) { 3619: $confhash->{$role}{$item} = $env{'form.'.$role.'_'.$item}; 3620: } 3621: my ($configuserok,$author_ok,$switchserver) = 3622: &config_check($dom,$confname,$servadm); 3623: my ($width,$height) = &thumb_dimensions(); 3624: if (ref($domconfig->{$role}) ne 'HASH') { 3625: $domconfig->{$role} = {}; 3626: } 3627: foreach my $img (@images) { 3628: if (($role eq 'login') && (($img eq 'img') || ($img eq 'logo'))) { 3629: if (defined($env{'form.login_showlogo_'.$img})) { 3630: $confhash->{$role}{'showlogo'}{$img} = 1; 3631: } else { 3632: $confhash->{$role}{'showlogo'}{$img} = 0; 3633: } 3634: } 3635: if ( ! $env{'form.'.$role.'_'.$img.'.filename'} 3636: && !defined($domconfig->{$role}{$img}) 3637: && !$env{'form.'.$role.'_del_'.$img} 3638: && $env{'form.'.$role.'_import_'.$img}) { 3639: # import the old configured image from the .tab setting 3640: # if they haven't provided a new one 3641: $domconfig->{$role}{$img} = 3642: $env{'form.'.$role.'_import_'.$img}; 3643: } 3644: if ($env{'form.'.$role.'_'.$img.'.filename'} ne '') { 3645: my $error; 3646: if ($configuserok eq 'ok') { 3647: if ($switchserver) { 3648: $error = &mt("Upload of [_1] image for $role page(s) is not permitted to this server: [_2]",$choices{$img},$switchserver); 3649: } else { 3650: if ($author_ok eq 'ok') { 3651: my ($result,$logourl) = 3652: &publishlogo($r,'upload',$role.'_'.$img, 3653: $dom,$confname,$img,$width,$height); 3654: if ($result eq 'ok') { 3655: $confhash->{$role}{$img} = $logourl; 3656: $changes{$role}{'images'}{$img} = 1; 3657: } else { 3658: $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); 3659: } 3660: } else { 3661: $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); 3662: } 3663: } 3664: } else { 3665: $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); 3666: } 3667: if ($error) { 3668: &Apache::lonnet::logthis($error); 3669: $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; 3670: } 3671: } elsif ($domconfig->{$role}{$img} ne '') { 3672: if ($domconfig->{$role}{$img} !~ m-^(/res/\Q$dom\E/\Q$confname\E/\Q$img\E)/([^/]+)$-) { 3673: my $error; 3674: if ($configuserok eq 'ok') { 3675: # is confname an author? 3676: if ($switchserver eq '') { 3677: if ($author_ok eq 'ok') { 3678: my ($result,$logourl) = 3679: &publishlogo($r,'copy',$domconfig->{$role}{$img}, 3680: $dom,$confname,$img,$width,$height); 3681: if ($result eq 'ok') { 3682: $confhash->{$role}{$img} = $logourl; 3683: $changes{$role}{'images'}{$img} = 1; 3684: } 3685: } 3686: } 3687: } 3688: } 3689: } 3690: } 3691: if (ref($domconfig) eq 'HASH') { 3692: if (ref($domconfig->{$role}) eq 'HASH') { 3693: foreach my $img (@images) { 3694: if ($domconfig->{$role}{$img} ne '') { 3695: if ($env{'form.'.$role.'_del_'.$img}) { 3696: $confhash->{$role}{$img} = ''; 3697: $changes{$role}{'images'}{$img} = 1; 3698: } else { 3699: if ($confhash->{$role}{$img} eq '') { 3700: $confhash->{$role}{$img} = $domconfig->{$role}{$img}; 3701: } 3702: } 3703: } else { 3704: if ($env{'form.'.$role.'_del_'.$img}) { 3705: $confhash->{$role}{$img} = ''; 3706: $changes{$role}{'images'}{$img} = 1; 3707: } 3708: } 3709: if (($role eq 'login') && (($img eq 'logo') || ($img eq 'img'))) { 3710: if (ref($domconfig->{'login'}{'showlogo'}) eq 'HASH') { 3711: if ($confhash->{$role}{'showlogo'}{$img} ne 3712: $domconfig->{$role}{'showlogo'}{$img}) { 3713: $changes{$role}{'showlogo'}{$img} = 1; 3714: } 3715: } else { 3716: if ($confhash->{$role}{'showlogo'}{$img} == 0) { 3717: $changes{$role}{'showlogo'}{$img} = 1; 3718: } 3719: } 3720: } 3721: } 3722: if ($domconfig->{$role}{'font'} ne '') { 3723: if ($confhash->{$role}{'font'} ne $domconfig->{$role}{'font'}) { 3724: $changes{$role}{'font'} = 1; 3725: } 3726: } else { 3727: if ($confhash->{$role}{'font'}) { 3728: $changes{$role}{'font'} = 1; 3729: } 3730: } 3731: if ($role ne 'login') { 3732: if ($domconfig->{$role}{'fontmenu'} ne '') { 3733: if ($confhash->{$role}{'fontmenu'} ne $domconfig->{$role}{'fontmenu'}) { 3734: $changes{$role}{'fontmenu'} = 1; 3735: } 3736: } else { 3737: if ($confhash->{$role}{'fontmenu'}) { 3738: $changes{$role}{'fontmenu'} = 1; 3739: } 3740: } 3741: } 3742: foreach my $item (@bgs) { 3743: if ($domconfig->{$role}{$item} ne '') { 3744: if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) { 3745: $changes{$role}{'bgs'}{$item} = 1; 3746: } 3747: } else { 3748: if ($confhash->{$role}{$item}) { 3749: $changes{$role}{'bgs'}{$item} = 1; 3750: } 3751: } 3752: } 3753: foreach my $item (@links) { 3754: if ($domconfig->{$role}{$item} ne '') { 3755: if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) { 3756: $changes{$role}{'links'}{$item} = 1; 3757: } 3758: } else { 3759: if ($confhash->{$role}{$item}) { 3760: $changes{$role}{'links'}{$item} = 1; 3761: } 3762: } 3763: } 3764: foreach my $item (@logintext) { 3765: if ($domconfig->{$role}{$item} ne '') { 3766: if ($confhash->{$role}{$item} ne $domconfig->{$role}{$item}) { 3767: $changes{$role}{'logintext'}{$item} = 1; 3768: } 3769: } else { 3770: if ($confhash->{$role}{$item}) { 3771: $changes{$role}{'logintext'}{$item} = 1; 3772: } 3773: } 3774: } 3775: } else { 3776: &default_change_checker($role,\@images,\@links,\@bgs, 3777: \@logintext,$confhash,\%changes); 3778: } 3779: } else { 3780: &default_change_checker($role,\@images,\@links,\@bgs, 3781: \@logintext,$confhash,\%changes); 3782: } 3783: } 3784: return ($errors,%changes); 3785: } 3786: 3787: sub config_check { 3788: my ($dom,$confname,$servadm) = @_; 3789: my ($configuserok,$author_ok,$switchserver,%currroles); 3790: my $uhome = &Apache::lonnet::homeserver($confname,$dom,1); 3791: ($configuserok,%currroles) = &check_configuser($uhome,$dom, 3792: $confname,$servadm); 3793: if ($configuserok eq 'ok') { 3794: $switchserver = &check_switchserver($dom,$confname); 3795: if ($switchserver eq '') { 3796: $author_ok = &check_authorstatus($dom,$confname,%currroles); 3797: } 3798: } 3799: return ($configuserok,$author_ok,$switchserver); 3800: } 3801: 3802: sub default_change_checker { 3803: my ($role,$images,$links,$bgs,$logintext,$confhash,$changes) = @_; 3804: foreach my $item (@{$links}) { 3805: if ($confhash->{$role}{$item}) { 3806: $changes->{$role}{'links'}{$item} = 1; 3807: } 3808: } 3809: foreach my $item (@{$bgs}) { 3810: if ($confhash->{$role}{$item}) { 3811: $changes->{$role}{'bgs'}{$item} = 1; 3812: } 3813: } 3814: foreach my $item (@{$logintext}) { 3815: if ($confhash->{$role}{$item}) { 3816: $changes->{$role}{'logintext'}{$item} = 1; 3817: } 3818: } 3819: foreach my $img (@{$images}) { 3820: if ($env{'form.'.$role.'_del_'.$img}) { 3821: $confhash->{$role}{$img} = ''; 3822: $changes->{$role}{'images'}{$img} = 1; 3823: } 3824: if ($role eq 'login') { 3825: if ($confhash->{$role}{'showlogo'}{$img} == 0) { 3826: $changes->{$role}{'showlogo'}{$img} = 1; 3827: } 3828: } 3829: } 3830: if ($confhash->{$role}{'font'}) { 3831: $changes->{$role}{'font'} = 1; 3832: } 3833: } 3834: 3835: sub display_colorchgs { 3836: my ($dom,$changes,$roles,$confhash) = @_; 3837: my (%choices,$resulttext); 3838: if (!grep(/^login$/,@{$roles})) { 3839: $resulttext = &mt('Changes made:').'<br />'; 3840: } 3841: foreach my $role (@{$roles}) { 3842: if ($role eq 'login') { 3843: %choices = &login_choices(); 3844: } else { 3845: %choices = &color_font_choices(); 3846: } 3847: if (ref($changes->{$role}) eq 'HASH') { 3848: if ($role ne 'login') { 3849: $resulttext .= '<h4>'.&mt($role).'</h4>'; 3850: } 3851: foreach my $key (sort(keys(%{$changes->{$role}}))) { 3852: if ($role ne 'login') { 3853: $resulttext .= '<ul>'; 3854: } 3855: if (ref($changes->{$role}{$key}) eq 'HASH') { 3856: if ($role ne 'login') { 3857: $resulttext .= '<li>'.&mt($choices{$key}).':<ul>'; 3858: } 3859: foreach my $item (sort(keys(%{$changes->{$role}{$key}}))) { 3860: if (($role eq 'login') && ($key eq 'showlogo')) { 3861: if ($confhash->{$role}{$key}{$item}) { 3862: $resulttext .= '<li>'.&mt("$choices{$item} set to be displayed").'</li>'; 3863: } else { 3864: $resulttext .= '<li>'.&mt("$choices{$item} set to not be displayed").'</li>'; 3865: } 3866: } elsif ($confhash->{$role}{$item} eq '') { 3867: $resulttext .= '<li>'.&mt("$choices{$item} set to default").'</li>'; 3868: } else { 3869: my $newitem = $confhash->{$role}{$item}; 3870: if ($key eq 'images') { 3871: $newitem = '<img src="'.$confhash->{$role}{$item}.'" alt="'.$choices{$item}.'" valign="bottom" />'; 3872: } 3873: $resulttext .= '<li>'.&mt("$choices{$item} set to [_1]",$newitem).'</li>'; 3874: } 3875: } 3876: if ($role ne 'login') { 3877: $resulttext .= '</ul></li>'; 3878: } 3879: } else { 3880: if ($confhash->{$role}{$key} eq '') { 3881: $resulttext .= '<li>'.&mt("$choices{$key} set to default").'</li>'; 3882: } else { 3883: $resulttext .= '<li>'.&mt("$choices{$key} set to [_1]",$confhash->{$role}{$key}).'</li>'; 3884: } 3885: } 3886: if ($role ne 'login') { 3887: $resulttext .= '</ul>'; 3888: } 3889: } 3890: } 3891: } 3892: return $resulttext; 3893: } 3894: 3895: sub thumb_dimensions { 3896: return ('200','50'); 3897: } 3898: 3899: sub check_dimensions { 3900: my ($inputfile) = @_; 3901: my ($fullwidth,$fullheight); 3902: if ($inputfile =~ m|^[/\w.\-]+$|) { 3903: if (open(PIPE,"identify $inputfile 2>&1 |")) { 3904: my $imageinfo = <PIPE>; 3905: if (!close(PIPE)) { 3906: &Apache::lonnet::logthis("Failed to close PIPE opened to retrieve image information for $inputfile"); 3907: } 3908: chomp($imageinfo); 3909: my ($fullsize) = 3910: ($imageinfo =~ /^\Q$inputfile\E\s+\w+\s+(\d+x\d+)/); 3911: if ($fullsize) { 3912: ($fullwidth,$fullheight) = split(/x/,$fullsize); 3913: } 3914: } 3915: } 3916: return ($fullwidth,$fullheight); 3917: } 3918: 3919: sub check_configuser { 3920: my ($uhome,$dom,$confname,$servadm) = @_; 3921: my ($configuserok,%currroles); 3922: if ($uhome eq 'no_host') { 3923: srand( time() ^ ($$ + ($$ << 15)) ); # Seed rand. 3924: my $configpass = &LONCAPA::Enrollment::create_password(); 3925: $configuserok = 3926: &Apache::lonnet::modifyuser($dom,$confname,'','internal', 3927: $configpass,'','','','','',undef,$servadm); 3928: } else { 3929: $configuserok = 'ok'; 3930: %currroles = 3931: &Apache::lonnet::get_my_roles($confname,$dom,'userroles'); 3932: } 3933: return ($configuserok,%currroles); 3934: } 3935: 3936: sub check_authorstatus { 3937: my ($dom,$confname,%currroles) = @_; 3938: my $author_ok; 3939: if (!$currroles{':'.$dom.':au'}) { 3940: my $start = time; 3941: my $end = 0; 3942: $author_ok = 3943: &Apache::lonnet::assignrole($dom,$confname,'/'.$dom.'/', 3944: 'au',$end,$start,'','','domconfig'); 3945: } else { 3946: $author_ok = 'ok'; 3947: } 3948: return $author_ok; 3949: } 3950: 3951: sub publishlogo { 3952: my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_; 3953: my ($output,$fname,$logourl); 3954: if ($action eq 'upload') { 3955: $fname=$env{'form.'.$formname.'.filename'}; 3956: chop($env{'form.'.$formname}); 3957: } else { 3958: ($fname) = ($formname =~ /([^\/]+)$/); 3959: } 3960: if ($savefileas ne '') { 3961: $fname = $savefileas; 3962: } 3963: $fname=&Apache::lonnet::clean_filename($fname); 3964: # See if there is anything left 3965: unless ($fname) { return ('error: no uploaded file'); } 3966: $fname="$subdir/$fname"; 3967: my $filepath='/home/'.$confname.'/public_html'; 3968: my ($fnamepath,$file,$fetchthumb); 3969: $file=$fname; 3970: if ($fname=~m|/|) { 3971: ($fnamepath,$file) = ($fname =~ m|^(.*)/([^/]+)$|); 3972: } 3973: my @parts=split(/\//,$filepath.'/'.$fnamepath); 3974: my $count; 3975: for ($count=4;$count<=$#parts;$count++) { 3976: $filepath.="/$parts[$count]"; 3977: if ((-e $filepath)!=1) { 3978: mkdir($filepath,02770); 3979: } 3980: } 3981: # Check for bad extension and disallow upload 3982: if ($file=~/\.(\w+)$/ && 3983: (&Apache::loncommon::fileembstyle($1) eq 'hdn')) { 3984: $output = 3985: &mt('Invalid file extension ([_1]) - reserved for LONCAPA use.',$1); 3986: } elsif ($file=~/\.(\w+)$/ && 3987: !defined(&Apache::loncommon::fileembstyle($1))) { 3988: $output = &mt('Unrecognized file extension ([_1]) - rename the file with a proper extension and re-upload.',$1); 3989: } elsif ($file=~/\.(\d+)\.(\w+)$/) { 3990: $output = &mt('File name not allowed - rename the file to remove the number immediately before the file extension([_1]) and re-upload.',$2); 3991: } elsif (-d "$filepath/$file") { 3992: $output = &mt('File name is a directory name - rename the file and re-upload'); 3993: } else { 3994: my $source = $filepath.'/'.$file; 3995: my $logfile; 3996: if (!open($logfile,">>$source".'.log')) { 3997: return (&mt('No write permission to Construction Space')); 3998: } 3999: print $logfile 4000: "\n================= Publish ".localtime()." ================\n". 4001: $env{'user.name'}.':'.$env{'user.domain'}."\n"; 4002: # Save the file 4003: if (!open(FH,'>'.$source)) { 4004: &Apache::lonnet::logthis('Failed to create '.$source); 4005: return (&mt('Failed to create file')); 4006: } 4007: if ($action eq 'upload') { 4008: if (!print FH ($env{'form.'.$formname})) { 4009: &Apache::lonnet::logthis('Failed to write to '.$source); 4010: return (&mt('Failed to write file')); 4011: } 4012: } else { 4013: my $original = &Apache::lonnet::filelocation('',$formname); 4014: if(!copy($original,$source)) { 4015: &Apache::lonnet::logthis('Failed to copy '.$original.' to '.$source); 4016: return (&mt('Failed to write file')); 4017: } 4018: } 4019: close(FH); 4020: chmod(0660, $source); # Permissions to rw-rw---. 4021: 4022: my $docroot=$r->dir_config('lonDocRoot'); 4023: my $targetdir=$docroot.'/res/'.$dom.'/'.$confname .'/'.$fnamepath; 4024: my $copyfile=$targetdir.'/'.$file; 4025: 4026: my @parts=split(/\//,$targetdir); 4027: my $path="/$parts[1]/$parts[2]/$parts[3]/$parts[4]"; 4028: for (my $count=5;$count<=$#parts;$count++) { 4029: $path.="/$parts[$count]"; 4030: if (!-e $path) { 4031: print $logfile "\nCreating directory ".$path; 4032: mkdir($path,02770); 4033: } 4034: } 4035: my $versionresult; 4036: if (-e $copyfile) { 4037: $versionresult = &logo_versioning($targetdir,$file,$logfile); 4038: } else { 4039: $versionresult = 'ok'; 4040: } 4041: if ($versionresult eq 'ok') { 4042: if (copy($source,$copyfile)) { 4043: print $logfile "\nCopied original source to ".$copyfile."\n"; 4044: $output = 'ok'; 4045: &write_metadata($dom,$confname,$formname,$targetdir,$file,$logfile); 4046: $logourl = '/res/'.$dom.'/'.$confname.'/'.$fname; 4047: } else { 4048: print $logfile "\nUnable to write ".$copyfile.':'.$!."\n"; 4049: $output = &mt('Failed to copy file to RES space').", $!"; 4050: } 4051: if (($thumbwidth =~ /^\d+$/) && ($thumbheight =~ /^\d+$/)) { 4052: my $inputfile = $filepath.'/'.$file; 4053: my $outfile = $filepath.'/'.'tn-'.$file; 4054: my ($fullwidth,$fullheight) = &check_dimensions($inputfile); 4055: if ($fullwidth ne '' && $fullheight ne '') { 4056: if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) { 4057: my $thumbsize = $thumbwidth.'x'.$thumbheight; 4058: system("convert -sample $thumbsize $inputfile $outfile"); 4059: chmod(0660, $filepath.'/tn-'.$file); 4060: if (-e $outfile) { 4061: my $copyfile=$targetdir.'/tn-'.$file; 4062: if (copy($outfile,$copyfile)) { 4063: print $logfile "\nCopied source to ".$copyfile."\n"; 4064: &write_metadata($dom,$confname,$formname, 4065: $targetdir,'tn-'.$file,$logfile); 4066: } else { 4067: print $logfile "\nUnable to write ".$copyfile. 4068: ':'.$!."\n"; 4069: } 4070: } 4071: } 4072: } 4073: } 4074: } else { 4075: $output = $versionresult; 4076: } 4077: } 4078: return ($output,$logourl); 4079: } 4080: 4081: sub logo_versioning { 4082: my ($targetdir,$file,$logfile) = @_; 4083: my $target = $targetdir.'/'.$file; 4084: my ($maxversion,$fn,$extn,$output); 4085: $maxversion = 0; 4086: if ($file =~ /^(.+)\.(\w+)$/) { 4087: $fn=$1; 4088: $extn=$2; 4089: } 4090: opendir(DIR,$targetdir); 4091: while (my $filename=readdir(DIR)) { 4092: if ($filename=~/\Q$fn\E\.(\d+)\.\Q$extn\E$/) { 4093: $maxversion=($1>$maxversion)?$1:$maxversion; 4094: } 4095: } 4096: $maxversion++; 4097: print $logfile "\nCreating old version ".$maxversion."\n"; 4098: my $copyfile=$targetdir.'/'.$fn.'.'.$maxversion.'.'.$extn; 4099: if (copy($target,$copyfile)) { 4100: print $logfile "Copied old target to ".$copyfile."\n"; 4101: $copyfile=$copyfile.'.meta'; 4102: if (copy($target.'.meta',$copyfile)) { 4103: print $logfile "Copied old target metadata to ".$copyfile."\n"; 4104: $output = 'ok'; 4105: } else { 4106: print $logfile "Unable to write metadata ".$copyfile.':'.$!."\n"; 4107: $output = &mt('Failed to copy old meta').", $!, "; 4108: } 4109: } else { 4110: print $logfile "Unable to write ".$copyfile.':'.$!."\n"; 4111: $output = &mt('Failed to copy old target').", $!, "; 4112: } 4113: return $output; 4114: } 4115: 4116: sub write_metadata { 4117: my ($dom,$confname,$formname,$targetdir,$file,$logfile) = @_; 4118: my (%metadatafields,%metadatakeys,$output); 4119: $metadatafields{'title'}=$formname; 4120: $metadatafields{'creationdate'}=time; 4121: $metadatafields{'lastrevisiondate'}=time; 4122: $metadatafields{'copyright'}='public'; 4123: $metadatafields{'modifyinguser'}=$env{'user.name'}.':'. 4124: $env{'user.domain'}; 4125: $metadatafields{'authorspace'}=$confname.':'.$dom; 4126: $metadatafields{'domain'}=$dom; 4127: { 4128: print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file; 4129: my $mfh; 4130: unless (open($mfh,'>'.$targetdir.'/'.$file.'.meta')) { 4131: $output = &mt('Could not write metadata'); 4132: } 4133: foreach (sort keys %metadatafields) { 4134: unless ($_=~/\./) { 4135: my $unikey=$_; 4136: $unikey=~/^([A-Za-z]+)/; 4137: my $tag=$1; 4138: $tag=~tr/A-Z/a-z/; 4139: print $mfh "\n\<$tag"; 4140: foreach (split(/\,/,$metadatakeys{$unikey})) { 4141: my $value=$metadatafields{$unikey.'.'.$_}; 4142: $value=~s/\"/\'\'/g; 4143: print $mfh ' '.$_.'="'.$value.'"'; 4144: } 4145: print $mfh '>'. 4146: &HTML::Entities::encode($metadatafields{$unikey},'<>&"') 4147: .'</'.$tag.'>'; 4148: } 4149: } 4150: $output = 'ok'; 4151: print $logfile "\nWrote metadata"; 4152: close($mfh); 4153: } 4154: } 4155: 4156: sub check_switchserver { 4157: my ($dom,$confname) = @_; 4158: my ($allowed,$switchserver); 4159: my $home = &Apache::lonnet::homeserver($confname,$dom); 4160: if ($home eq 'no_host') { 4161: $home = &Apache::lonnet::domain($dom,'primary'); 4162: } 4163: my @ids=&Apache::lonnet::current_machine_ids(); 4164: foreach my $id (@ids) { if ($id eq $home) { $allowed=1; } } 4165: if (!$allowed) { 4166: $switchserver='<a href="/adm/switchserver?otherserver='.$home.'&role=dc./'.$dom.'/">'.&mt('Switch Server').'</a>'; 4167: } 4168: return $switchserver; 4169: } 4170: 4171: sub modify_quotas { 4172: my ($dom,$action,%domconfig) = @_; 4173: my ($context,@usertools,@options,%validations,%titles,%confhash,%toolshash, 4174: %limithash,$toolregexp,%conditions,$resulttext,%changes); 4175: if ($action eq 'quotas') { 4176: $context = 'tools'; 4177: } else { 4178: $context = $action; 4179: } 4180: if ($context eq 'requestcourses') { 4181: @usertools = ('official','unofficial','community'); 4182: @options =('norequest','approval','validate','autolimit'); 4183: %validations = &Apache::lonnet::auto_courserequest_checks($dom); 4184: %titles = &courserequest_titles(); 4185: $toolregexp = join('|',@usertools); 4186: %conditions = &courserequest_conditions(); 4187: } else { 4188: @usertools = ('aboutme','blog','portfolio'); 4189: %titles = &tool_titles(); 4190: } 4191: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 4192: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 4193: foreach my $key (keys(%env)) { 4194: if ($context eq 'requestcourses') { 4195: if ($key =~ /^form\.crsreq_($toolregexp)_(.+)$/) { 4196: my $item = $1; 4197: my $type = $2; 4198: if ($type =~ /^limit_(.+)/) { 4199: $limithash{$item}{$1} = $env{$key}; 4200: } else { 4201: $confhash{$item}{$type} = $env{$key}; 4202: } 4203: } 4204: } else { 4205: if ($key =~ /^form\.quota_(.+)$/) { 4206: $confhash{'defaultquota'}{$1} = $env{$key}; 4207: } 4208: if ($key =~ /^form\.\Q$context\E_(.+)$/) { 4209: @{$toolshash{$1}} = &Apache::loncommon::get_env_multiple($key); 4210: } 4211: } 4212: } 4213: if ($context eq 'requestcourses') { 4214: my @approvalnotify = &Apache::loncommon::get_env_multiple('form.reqapprovalnotify'); 4215: @approvalnotify = sort(@approvalnotify); 4216: $confhash{'notify'}{'approval'} = join(',',@approvalnotify); 4217: if (ref($domconfig{$action}) eq 'HASH') { 4218: if (ref($domconfig{$action}{'notify'}) eq 'HASH') { 4219: if ($domconfig{$action}{'notify'}{'approval'} ne $confhash{'notify'}{'approval'}) { 4220: $changes{'notify'}{'approval'} = 1; 4221: } 4222: } else { 4223: if ($domconfig{$action}{'notify'}{'approval'}) { 4224: $changes{'notify'}{'approval'} = 1; 4225: } 4226: } 4227: } else { 4228: if ($domconfig{$action}{'notify'}{'approval'}) { 4229: $changes{'notify'}{'approval'} = 1; 4230: } 4231: } 4232: } else { 4233: $confhash{'defaultquota'}{'default'} = $env{'form.defaultquota'}; 4234: } 4235: foreach my $item (@usertools) { 4236: foreach my $type (@{$types},'default','_LC_adv') { 4237: my $unset; 4238: if ($context eq 'requestcourses') { 4239: $unset = '0'; 4240: if ($type eq '_LC_adv') { 4241: $unset = ''; 4242: } 4243: if ($confhash{$item}{$type} eq 'autolimit') { 4244: $confhash{$item}{$type} .= '='; 4245: unless ($limithash{$item}{$type} =~ /\D/) { 4246: $confhash{$item}{$type} .= $limithash{$item}{$type}; 4247: } 4248: } 4249: } else { 4250: if (grep(/^\Q$type\E$/,@{$toolshash{$item}})) { 4251: $confhash{$item}{$type} = 1; 4252: } else { 4253: $confhash{$item}{$type} = 0; 4254: } 4255: } 4256: if (ref($domconfig{$action}) eq 'HASH') { 4257: if (ref($domconfig{$action}{$item}) eq 'HASH') { 4258: if ($domconfig{$action}{$item}{$type} ne $confhash{$item}{$type}) { 4259: $changes{$item}{$type} = 1; 4260: } 4261: } else { 4262: if ($context eq 'requestcourses') { 4263: if ($confhash{$item}{$type} ne $unset) { 4264: $changes{$item}{$type} = 1; 4265: } 4266: } else { 4267: if (!$confhash{$item}{$type}) { 4268: $changes{$item}{$type} = 1; 4269: } 4270: } 4271: } 4272: } else { 4273: if ($context eq 'requestcourses') { 4274: if ($confhash{$item}{$type} ne $unset) { 4275: $changes{$item}{$type} = 1; 4276: } 4277: } else { 4278: if (!$confhash{$item}{$type}) { 4279: $changes{$item}{$type} = 1; 4280: } 4281: } 4282: } 4283: } 4284: } 4285: unless ($context eq 'requestcourses') { 4286: if (ref($domconfig{'quotas'}) eq 'HASH') { 4287: if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') { 4288: foreach my $key (keys(%{$domconfig{'quotas'}{'defaultquota'}})) { 4289: if (exists($confhash{'defaultquota'}{$key})) { 4290: if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{'defaultquota'}{$key}) { 4291: $changes{'defaultquota'}{$key} = 1; 4292: } 4293: } else { 4294: $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{'defaultquota'}{$key}; 4295: } 4296: } 4297: } else { 4298: foreach my $key (keys(%{$domconfig{'quotas'}})) { 4299: if (exists($confhash{'defaultquota'}{$key})) { 4300: if ($confhash{'defaultquota'}{$key} ne $domconfig{'quotas'}{$key}) { 4301: $changes{'defaultquota'}{$key} = 1; 4302: } 4303: } else { 4304: $confhash{'defaultquota'}{$key} = $domconfig{'quotas'}{$key}; 4305: } 4306: } 4307: } 4308: } 4309: if (ref($confhash{'defaultquota'}) eq 'HASH') { 4310: foreach my $key (keys(%{$confhash{'defaultquota'}})) { 4311: if (ref($domconfig{'quotas'}) eq 'HASH') { 4312: if (ref($domconfig{'quotas'}{'defaultquota'}) eq 'HASH') { 4313: if (!exists($domconfig{'quotas'}{'defaultquota'}{$key})) { 4314: $changes{'defaultquota'}{$key} = 1; 4315: } 4316: } else { 4317: if (!exists($domconfig{'quotas'}{$key})) { 4318: $changes{'defaultquota'}{$key} = 1; 4319: } 4320: } 4321: } else { 4322: $changes{'defaultquota'}{$key} = 1; 4323: } 4324: } 4325: } 4326: } 4327: 4328: foreach my $key (keys(%confhash)) { 4329: $domdefaults{$key} = $confhash{$key}; 4330: } 4331: 4332: my %quotahash = ( 4333: $action => { %confhash } 4334: ); 4335: my $putresult = &Apache::lonnet::put_dom('configuration',\%quotahash, 4336: $dom); 4337: if ($putresult eq 'ok') { 4338: if (keys(%changes) > 0) { 4339: my $cachetime = 24*60*60; 4340: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); 4341: 4342: $resulttext = &mt('Changes made:').'<ul>'; 4343: unless ($context eq 'requestcourses') { 4344: if (ref($changes{'defaultquota'}) eq 'HASH') { 4345: $resulttext .= '<li>'.&mt('Portfolio default quotas').'<ul>'; 4346: foreach my $type (@{$types},'default') { 4347: if (defined($changes{'defaultquota'}{$type})) { 4348: my $typetitle = $usertypes->{$type}; 4349: if ($type eq 'default') { 4350: $typetitle = $othertitle; 4351: } 4352: $resulttext .= '<li>'.&mt('[_1] set to [_2] Mb',$typetitle,$confhash{'defaultquota'}{$type}).'</li>'; 4353: } 4354: } 4355: $resulttext .= '</ul></li>'; 4356: } 4357: } 4358: my %newenv; 4359: foreach my $item (@usertools) { 4360: if (ref($changes{$item}) eq 'HASH') { 4361: my $newacc = 4362: &Apache::lonnet::usertools_access($env{'user.name'}, 4363: $env{'user.domain'}, 4364: $item,'reload',$context); 4365: if ($context eq 'requestcourses') { 4366: if ($env{'environment.canrequest.'.$item} ne $newacc) { 4367: $newenv{'environment.canrequest.'.$item} = $newacc; 4368: } 4369: } else { 4370: if ($env{'environment.availabletools.'.$item} ne $newacc) { 4371: $newenv{'environment.availabletools.'.$item} = $newacc; 4372: } 4373: } 4374: $resulttext .= '<li>'.$titles{$item}.'<ul>'; 4375: foreach my $type (@{$types},'default','_LC_adv') { 4376: if ($changes{$item}{$type}) { 4377: my $typetitle = $usertypes->{$type}; 4378: if ($type eq 'default') { 4379: $typetitle = $othertitle; 4380: } elsif ($type eq '_LC_adv') { 4381: $typetitle = 'LON-CAPA Advanced Users'; 4382: } 4383: if ($confhash{$item}{$type}) { 4384: if ($context eq 'requestcourses') { 4385: my $cond; 4386: if ($confhash{$item}{$type} =~ /^autolimit=(\d*)$/) { 4387: if ($1 eq '') { 4388: $cond = &mt('(Automatic processing of any request).'); 4389: } else { 4390: $cond = &mt('(Automatic processing of requests up to limit of [quant,_1,request] per user).',$1); 4391: } 4392: } else { 4393: $cond = $conditions{$confhash{$item}{$type}}; 4394: } 4395: $resulttext .= '<li>'.&mt('Set to be available to [_1].',$typetitle).' '.$cond.'</li>'; 4396: } else { 4397: $resulttext .= '<li>'.&mt('Set to be available to [_1]',$typetitle).'</li>'; 4398: } 4399: } else { 4400: if ($type eq '_LC_adv') { 4401: if ($confhash{$item}{$type} eq '0') { 4402: $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>'; 4403: } else { 4404: $resulttext .= '<li>'.&mt('No override set for [_1]',$typetitle).'</li>'; 4405: } 4406: } else { 4407: $resulttext .= '<li>'.&mt('Set to be unavailable to [_1]',$typetitle).'</li>'; 4408: } 4409: } 4410: } 4411: } 4412: $resulttext .= '</ul></li>'; 4413: } 4414: } 4415: if ($action eq 'requestcourses') { 4416: if (ref($changes{'notify'}) eq 'HASH') { 4417: if ($changes{'notify'}{'approval'}) { 4418: if (ref($confhash{'notify'}) eq 'HASH') { 4419: if ($confhash{'notify'}{'approval'}) { 4420: $resulttext .= '<li>'.&mt('Notification of requests requiring approval will be sent to: ').$confhash{'notify'}{'approval'}.'</li>'; 4421: } else { 4422: $resulttext .= '<li>'.&mt('No Domain Coordinators will receive notification of course requests requiring approval.').'</li>'; 4423: } 4424: } 4425: } 4426: } 4427: } 4428: $resulttext .= '</ul>'; 4429: if (keys(%newenv)) { 4430: &Apache::lonnet::appenv(\%newenv); 4431: } 4432: } else { 4433: if ($context eq 'requestcourses') { 4434: $resulttext = &mt('No changes made to rights to request creation of courses.'); 4435: } else { 4436: $resulttext = &mt('No changes made to availability of personal information pages, blogs, portfolios or default quotas'); 4437: } 4438: } 4439: } else { 4440: $resulttext = '<span class="LC_error">'. 4441: &mt('An error occurred: [_1]',$putresult).'</span>'; 4442: } 4443: return $resulttext; 4444: } 4445: 4446: sub modify_autoenroll { 4447: my ($dom,%domconfig) = @_; 4448: my ($resulttext,%changes); 4449: my %currautoenroll; 4450: if (ref($domconfig{'autoenroll'}) eq 'HASH') { 4451: foreach my $key (keys(%{$domconfig{'autoenroll'}})) { 4452: $currautoenroll{$key} = $domconfig{'autoenroll'}{$key}; 4453: } 4454: } 4455: my $autorun = &Apache::lonnet::auto_run(undef,$dom), 4456: my %title = ( run => 'Auto-enrollment active', 4457: sender => 'Sender for notification messages'); 4458: my @offon = ('off','on'); 4459: my $sender_uname = $env{'form.sender_uname'}; 4460: my $sender_domain = $env{'form.sender_domain'}; 4461: if ($sender_domain eq '') { 4462: $sender_uname = ''; 4463: } elsif ($sender_uname eq '') { 4464: $sender_domain = ''; 4465: } 4466: my %autoenrollhash = ( 4467: autoenroll => { run => $env{'form.autoenroll_run'}, 4468: sender_uname => $sender_uname, 4469: sender_domain => $sender_domain, 4470: 4471: } 4472: ); 4473: my $putresult = &Apache::lonnet::put_dom('configuration',\%autoenrollhash, 4474: $dom); 4475: if ($putresult eq 'ok') { 4476: if (exists($currautoenroll{'run'})) { 4477: if ($currautoenroll{'run'} ne $env{'form.autoenroll_run'}) { 4478: $changes{'run'} = 1; 4479: } 4480: } elsif ($autorun) { 4481: if ($env{'form.autoenroll_run'} ne '1') { 4482: $changes{'run'} = 1; 4483: } 4484: } 4485: if ($currautoenroll{'sender_uname'} ne $sender_uname) { 4486: $changes{'sender'} = 1; 4487: } 4488: if ($currautoenroll{'sender_domain'} ne $sender_domain) { 4489: $changes{'sender'} = 1; 4490: } 4491: if (keys(%changes) > 0) { 4492: $resulttext = &mt('Changes made:').'<ul>'; 4493: if ($changes{'run'}) { 4494: $resulttext .= '<li>'.&mt("$title{'run'} set to $offon[$env{'form.autoenroll_run'}]").'</li>'; 4495: } 4496: if ($changes{'sender'}) { 4497: if ($sender_uname eq '' || $sender_domain eq '') { 4498: $resulttext .= '<li>'.&mt("$title{'sender'} set to default (course owner).").'</li>'; 4499: } else { 4500: $resulttext .= '<li>'.&mt("$title{'sender'} set to [_1]",$sender_uname.':'.$sender_domain).'</li>'; 4501: } 4502: } 4503: $resulttext .= '</ul>'; 4504: } else { 4505: $resulttext = &mt('No changes made to auto-enrollment settings'); 4506: } 4507: } else { 4508: $resulttext = '<span class="LC_error">'. 4509: &mt('An error occurred: [_1]',$putresult).'</span>'; 4510: } 4511: return $resulttext; 4512: } 4513: 4514: sub modify_autoupdate { 4515: my ($dom,%domconfig) = @_; 4516: my ($resulttext,%currautoupdate,%fields,%changes); 4517: if (ref($domconfig{'autoupdate'}) eq 'HASH') { 4518: foreach my $key (keys(%{$domconfig{'autoupdate'}})) { 4519: $currautoupdate{$key} = $domconfig{'autoupdate'}{$key}; 4520: } 4521: } 4522: my @offon = ('off','on'); 4523: my %title = &Apache::lonlocal::texthash ( 4524: run => 'Auto-update:', 4525: classlists => 'Updates to user information in classlists?' 4526: ); 4527: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 4528: my %fieldtitles = &Apache::lonlocal::texthash ( 4529: id => 'Student/Employee ID', 4530: permanentemail => 'E-mail address', 4531: lastname => 'Last Name', 4532: firstname => 'First Name', 4533: middlename => 'Middle Name', 4534: gen => 'Generation', 4535: ); 4536: my $othertitle = &mt('All users'); 4537: if (keys(%{$usertypes}) > 0) { 4538: $othertitle = &mt('Other users'); 4539: } 4540: foreach my $key (keys(%env)) { 4541: if ($key =~ /^form\.updateable_(.+)_([^_]+)$/) { 4542: push(@{$fields{$1}},$2); 4543: } 4544: } 4545: my %updatehash = ( 4546: autoupdate => { run => $env{'form.autoupdate_run'}, 4547: classlists => $env{'form.classlists'}, 4548: fields => {%fields}, 4549: } 4550: ); 4551: foreach my $key (keys(%currautoupdate)) { 4552: if (($key eq 'run') || ($key eq 'classlists')) { 4553: if (exists($updatehash{autoupdate}{$key})) { 4554: if ($currautoupdate{$key} ne $updatehash{autoupdate}{$key}) { 4555: $changes{$key} = 1; 4556: } 4557: } 4558: } elsif ($key eq 'fields') { 4559: if (ref($currautoupdate{$key}) eq 'HASH') { 4560: foreach my $item (@{$types},'default') { 4561: if (ref($currautoupdate{$key}{$item}) eq 'ARRAY') { 4562: my $change = 0; 4563: foreach my $type (@{$currautoupdate{$key}{$item}}) { 4564: if (!exists($fields{$item})) { 4565: $change = 1; 4566: } elsif (ref($fields{$item}) eq 'ARRAY') { 4567: if (!grep(/^\Q$type\E$/,@{$fields{$item}})) { 4568: $change = 1; 4569: } 4570: } 4571: } 4572: if ($change) { 4573: push(@{$changes{$key}},$item); 4574: } 4575: } 4576: } 4577: } 4578: } 4579: } 4580: foreach my $item (@{$types},'default') { 4581: if (defined($fields{$item})) { 4582: if (ref($currautoupdate{'fields'}) eq 'HASH') { 4583: if (!exists($currautoupdate{'fields'}{$item})) { 4584: push(@{$changes{'fields'}},$item); 4585: } 4586: } else { 4587: push(@{$changes{'fields'}},$item); 4588: } 4589: } 4590: } 4591: my $putresult = &Apache::lonnet::put_dom('configuration',\%updatehash, 4592: $dom); 4593: if ($putresult eq 'ok') { 4594: if (keys(%changes) > 0) { 4595: $resulttext = &mt('Changes made:').'<ul>'; 4596: foreach my $key (sort(keys(%changes))) { 4597: if (ref($changes{$key}) eq 'ARRAY') { 4598: foreach my $item (@{$changes{$key}}) { 4599: my @newvalues; 4600: foreach my $type (@{$fields{$item}}) { 4601: push(@newvalues,$fieldtitles{$type}); 4602: } 4603: my $newvaluestr; 4604: if (@newvalues > 0) { 4605: $newvaluestr = join(', ',@newvalues); 4606: } else { 4607: $newvaluestr = &mt('none'); 4608: } 4609: if ($item eq 'default') { 4610: $resulttext .= '<li>'.&mt("Updates for '[_1]' set to: '[_2]'",$othertitle,$newvaluestr).'</li>'; 4611: } else { 4612: $resulttext .= '<li>'.&mt("Updates for '[_1]' set to: '[_2]'",$usertypes->{$item},$newvaluestr).'</li>'; 4613: } 4614: } 4615: } else { 4616: my $newvalue; 4617: if ($key eq 'run') { 4618: $newvalue = $offon[$env{'form.autoupdate_run'}]; 4619: } else { 4620: $newvalue = $offon[$env{'form.'.$key}]; 4621: } 4622: $resulttext .= '<li>'.&mt("[_1] set to $newvalue",$title{$key}).'</li>'; 4623: } 4624: } 4625: $resulttext .= '</ul>'; 4626: } else { 4627: $resulttext = &mt('No changes made to autoupdates'); 4628: } 4629: } else { 4630: $resulttext = '<span class="LC_error">'. 4631: &mt('An error occurred: [_1]',$putresult).'</span>'; 4632: } 4633: return $resulttext; 4634: } 4635: 4636: sub modify_directorysrch { 4637: my ($dom,%domconfig) = @_; 4638: my ($resulttext,%changes); 4639: my %currdirsrch; 4640: if (ref($domconfig{'directorysrch'}) eq 'HASH') { 4641: foreach my $key (keys(%{$domconfig{'directorysrch'}})) { 4642: $currdirsrch{$key} = $domconfig{'directorysrch'}{$key}; 4643: } 4644: } 4645: my %title = ( available => 'Directory search available', 4646: localonly => 'Other domains can search', 4647: searchby => 'Search types', 4648: searchtypes => 'Search latitude'); 4649: my @offon = ('off','on'); 4650: my @otherdoms = ('Yes','No'); 4651: 4652: my @searchtypes = &Apache::loncommon::get_env_multiple('form.searchtypes'); 4653: my @cansearch = &Apache::loncommon::get_env_multiple('form.cansearch'); 4654: my @searchby = &Apache::loncommon::get_env_multiple('form.searchby'); 4655: 4656: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 4657: if (keys(%{$usertypes}) == 0) { 4658: @cansearch = ('default'); 4659: } else { 4660: if (ref($currdirsrch{'cansearch'}) eq 'ARRAY') { 4661: foreach my $type (@{$currdirsrch{'cansearch'}}) { 4662: if (!grep(/^\Q$type\E$/,@cansearch)) { 4663: push(@{$changes{'cansearch'}},$type); 4664: } 4665: } 4666: foreach my $type (@cansearch) { 4667: if (!grep(/^\Q$type\E$/,@{$currdirsrch{'cansearch'}})) { 4668: push(@{$changes{'cansearch'}},$type); 4669: } 4670: } 4671: } else { 4672: push(@{$changes{'cansearch'}},@cansearch); 4673: } 4674: } 4675: 4676: if (ref($currdirsrch{'searchby'}) eq 'ARRAY') { 4677: foreach my $by (@{$currdirsrch{'searchby'}}) { 4678: if (!grep(/^\Q$by\E$/,@searchby)) { 4679: push(@{$changes{'searchby'}},$by); 4680: } 4681: } 4682: foreach my $by (@searchby) { 4683: if (!grep(/^\Q$by\E$/,@{$currdirsrch{'searchby'}})) { 4684: push(@{$changes{'searchby'}},$by); 4685: } 4686: } 4687: } else { 4688: push(@{$changes{'searchby'}},@searchby); 4689: } 4690: 4691: if (ref($currdirsrch{'searchtypes'}) eq 'ARRAY') { 4692: foreach my $type (@{$currdirsrch{'searchtypes'}}) { 4693: if (!grep(/^\Q$type\E$/,@searchtypes)) { 4694: push(@{$changes{'searchtypes'}},$type); 4695: } 4696: } 4697: foreach my $type (@searchtypes) { 4698: if (!grep(/^\Q$type\E$/,@{$currdirsrch{'searchtypes'}})) { 4699: push(@{$changes{'searchtypes'}},$type); 4700: } 4701: } 4702: } else { 4703: if (exists($currdirsrch{'searchtypes'})) { 4704: foreach my $type (@searchtypes) { 4705: if ($type ne $currdirsrch{'searchtypes'}) { 4706: push(@{$changes{'searchtypes'}},$type); 4707: } 4708: } 4709: if (!grep(/^\Q$currdirsrch{'searchtypes'}\E/,@searchtypes)) { 4710: push(@{$changes{'searchtypes'}},$currdirsrch{'searchtypes'}); 4711: } 4712: } else { 4713: push(@{$changes{'searchtypes'}},@searchtypes); 4714: } 4715: } 4716: 4717: my %dirsrch_hash = ( 4718: directorysrch => { available => $env{'form.dirsrch_available'}, 4719: cansearch => \@cansearch, 4720: localonly => $env{'form.dirsrch_localonly'}, 4721: searchby => \@searchby, 4722: searchtypes => \@searchtypes, 4723: } 4724: ); 4725: my $putresult = &Apache::lonnet::put_dom('configuration',\%dirsrch_hash, 4726: $dom); 4727: if ($putresult eq 'ok') { 4728: if (exists($currdirsrch{'available'})) { 4729: if ($currdirsrch{'available'} ne $env{'form.dirsrch_available'}) { 4730: $changes{'available'} = 1; 4731: } 4732: } else { 4733: if ($env{'form.dirsrch_available'} eq '1') { 4734: $changes{'available'} = 1; 4735: } 4736: } 4737: if (exists($currdirsrch{'localonly'})) { 4738: if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_localonly'}) { 4739: $changes{'localonly'} = 1; 4740: } 4741: } else { 4742: if ($env{'form.dirsrch_localonly'} eq '1') { 4743: $changes{'localonly'} = 1; 4744: } 4745: } 4746: if (keys(%changes) > 0) { 4747: $resulttext = &mt('Changes made:').'<ul>'; 4748: if ($changes{'available'}) { 4749: $resulttext .= '<li>'.&mt("$title{'available'} set to: $offon[$env{'form.dirsrch_available'}]").'</li>'; 4750: } 4751: if ($changes{'localonly'}) { 4752: $resulttext .= '<li>'.&mt("$title{'localonly'} set to: $otherdoms[$env{'form.dirsrch_localonly'}]").'</li>'; 4753: } 4754: 4755: if (ref($changes{'cansearch'}) eq 'ARRAY') { 4756: my $chgtext; 4757: if (ref($usertypes) eq 'HASH') { 4758: if (keys(%{$usertypes}) > 0) { 4759: foreach my $type (@{$types}) { 4760: if (grep(/^\Q$type\E$/,@cansearch)) { 4761: $chgtext .= $usertypes->{$type}.'; '; 4762: } 4763: } 4764: if (grep(/^default$/,@cansearch)) { 4765: $chgtext .= $othertitle; 4766: } else { 4767: $chgtext =~ s/\; $//; 4768: } 4769: $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>'; 4770: } 4771: } 4772: } 4773: if (ref($changes{'searchby'}) eq 'ARRAY') { 4774: my ($searchtitles,$titleorder) = &sorted_searchtitles(); 4775: my $chgtext; 4776: foreach my $type (@{$titleorder}) { 4777: if (grep(/^\Q$type\E$/,@searchby)) { 4778: if (defined($searchtitles->{$type})) { 4779: $chgtext .= $searchtitles->{$type}.'; '; 4780: } 4781: } 4782: } 4783: $chgtext =~ s/\; $//; 4784: $resulttext .= '<li>'.&mt("$title{'searchby'} set to: [_1]",$chgtext).'</li>'; 4785: } 4786: if (ref($changes{'searchtypes'}) eq 'ARRAY') { 4787: my ($srchtypes_desc,$srchtypeorder) = &sorted_searchtypes(); 4788: my $chgtext; 4789: foreach my $type (@{$srchtypeorder}) { 4790: if (grep(/^\Q$type\E$/,@searchtypes)) { 4791: if (defined($srchtypes_desc->{$type})) { 4792: $chgtext .= $srchtypes_desc->{$type}.'; '; 4793: } 4794: } 4795: } 4796: $chgtext =~ s/\; $//; 4797: $resulttext .= '<li>'.&mt("$title{'searchtypes'} set to: \"[_1]\"",$chgtext).'</li>'; 4798: } 4799: $resulttext .= '</ul>'; 4800: } else { 4801: $resulttext = &mt('No changes made to institution directory search settings'); 4802: } 4803: } else { 4804: $resulttext = '<span class="LC_error">'. 4805: &mt('An error occurred: [_1]',$putresult).'</span>'; 4806: } 4807: return $resulttext; 4808: } 4809: 4810: sub modify_contacts { 4811: my ($dom,%domconfig) = @_; 4812: my ($resulttext,%currsetting,%newsetting,%changes,%contacts_hash); 4813: if (ref($domconfig{'contacts'}) eq 'HASH') { 4814: foreach my $key (keys(%{$domconfig{'contacts'}})) { 4815: $currsetting{$key} = $domconfig{'contacts'}{$key}; 4816: } 4817: } 4818: my (%others,%to); 4819: my @contacts = ('supportemail','adminemail'); 4820: my @mailings = ('errormail','packagesmail','helpdeskmail','lonstatusmail', 4821: 'requestsmail'); 4822: foreach my $type (@mailings) { 4823: @{$newsetting{$type}} = 4824: &Apache::loncommon::get_env_multiple('form.'.$type); 4825: foreach my $item (@contacts) { 4826: if (grep(/^\Q$item\E$/,@{$newsetting{$type}})) { 4827: $contacts_hash{contacts}{$type}{$item} = 1; 4828: } else { 4829: $contacts_hash{contacts}{$type}{$item} = 0; 4830: } 4831: } 4832: $others{$type} = $env{'form.'.$type.'_others'}; 4833: $contacts_hash{contacts}{$type}{'others'} = $others{$type}; 4834: } 4835: foreach my $item (@contacts) { 4836: $to{$item} = $env{'form.'.$item}; 4837: $contacts_hash{'contacts'}{$item} = $to{$item}; 4838: } 4839: if (keys(%currsetting) > 0) { 4840: foreach my $item (@contacts) { 4841: if ($to{$item} ne $currsetting{$item}) { 4842: $changes{$item} = 1; 4843: } 4844: } 4845: foreach my $type (@mailings) { 4846: foreach my $item (@contacts) { 4847: if (ref($currsetting{$type}) eq 'HASH') { 4848: if ($currsetting{$type}{$item} ne $contacts_hash{contacts}{$type}{$item}) { 4849: push(@{$changes{$type}},$item); 4850: } 4851: } else { 4852: push(@{$changes{$type}},@{$newsetting{$type}}); 4853: } 4854: } 4855: if ($others{$type} ne $currsetting{$type}{'others'}) { 4856: push(@{$changes{$type}},'others'); 4857: } 4858: } 4859: } else { 4860: my %default; 4861: $default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'}; 4862: $default{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'}; 4863: $default{'errormail'} = 'adminemail'; 4864: $default{'packagesmail'} = 'adminemail'; 4865: $default{'helpdeskmail'} = 'supportemail'; 4866: $default{'lonstatusmail'} = 'adminemail'; 4867: $default{'requestsmail'} = 'adminemail'; 4868: foreach my $item (@contacts) { 4869: if ($to{$item} ne $default{$item}) { 4870: $changes{$item} = 1; 4871: } 4872: } 4873: foreach my $type (@mailings) { 4874: if ((@{$newsetting{$type}} != 1) || ($newsetting{$type}[0] ne $default{$type})) { 4875: 4876: push(@{$changes{$type}},@{$newsetting{$type}}); 4877: } 4878: if ($others{$type} ne '') { 4879: push(@{$changes{$type}},'others'); 4880: } 4881: } 4882: } 4883: my $putresult = &Apache::lonnet::put_dom('configuration',\%contacts_hash, 4884: $dom); 4885: if ($putresult eq 'ok') { 4886: if (keys(%changes) > 0) { 4887: my ($titles,$short_titles) = &contact_titles(); 4888: $resulttext = &mt('Changes made:').'<ul>'; 4889: foreach my $item (@contacts) { 4890: if ($changes{$item}) { 4891: $resulttext .= '<li>'.$titles->{$item}. 4892: &mt(' set to: '). 4893: '<span class="LC_cusr_emph">'. 4894: $to{$item}.'</span></li>'; 4895: } 4896: } 4897: foreach my $type (@mailings) { 4898: if (ref($changes{$type}) eq 'ARRAY') { 4899: $resulttext .= '<li>'.$titles->{$type}.': '; 4900: my @text; 4901: foreach my $item (@{$newsetting{$type}}) { 4902: push(@text,$short_titles->{$item}); 4903: } 4904: if ($others{$type} ne '') { 4905: push(@text,$others{$type}); 4906: } 4907: $resulttext .= '<span class="LC_cusr_emph">'. 4908: join(', ',@text).'</span></li>'; 4909: } 4910: } 4911: $resulttext .= '</ul>'; 4912: } else { 4913: $resulttext = &mt('No changes made to contact information'); 4914: } 4915: } else { 4916: $resulttext = '<span class="LC_error">'. 4917: &mt('An error occurred: [_1].',$putresult).'</span>'; 4918: } 4919: return $resulttext; 4920: } 4921: 4922: sub modify_usercreation { 4923: my ($dom,%domconfig) = @_; 4924: my ($resulttext,%curr_usercreation,%changes,%authallowed,%cancreate); 4925: my $warningmsg; 4926: if (ref($domconfig{'usercreation'}) eq 'HASH') { 4927: foreach my $key (keys(%{$domconfig{'usercreation'}})) { 4928: $curr_usercreation{$key} = $domconfig{'usercreation'}{$key}; 4929: } 4930: } 4931: my @username_rule = &Apache::loncommon::get_env_multiple('form.username_rule'); 4932: my @id_rule = &Apache::loncommon::get_env_multiple('form.id_rule'); 4933: my @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule'); 4934: my @contexts = ('author','course','requestcrs','selfcreate'); 4935: foreach my $item(@contexts) { 4936: if ($item eq 'selfcreate') { 4937: @{$cancreate{$item}} = &Apache::loncommon::get_env_multiple('form.can_createuser_'.$item); 4938: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 4939: if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) { 4940: if (ref($cancreate{$item}) eq 'ARRAY') { 4941: if (grep(/^login$/,@{$cancreate{$item}})) { 4942: $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.'); 4943: } 4944: } 4945: } 4946: } else { 4947: $cancreate{$item} = $env{'form.can_createuser_'.$item}; 4948: } 4949: } 4950: my ($othertitle,$usertypes,$types) = 4951: &Apache::loncommon::sorted_inst_types($dom); 4952: if (ref($types) eq 'ARRAY') { 4953: if (@{$types} > 0) { 4954: @{$cancreate{'statustocreate'}} = 4955: &Apache::loncommon::get_env_multiple('form.statustocreate'); 4956: } else { 4957: @{$cancreate{'statustocreate'}} = (); 4958: } 4959: push(@contexts,'statustocreate'); 4960: } 4961: if (ref($curr_usercreation{'cancreate'}) eq 'HASH') { 4962: foreach my $item (@contexts) { 4963: if (($item eq 'selfcreate') || ($item eq 'statustocreate')) { 4964: if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') { 4965: foreach my $curr (@{$curr_usercreation{'cancreate'}{$item}}) { 4966: if (ref($cancreate{$item}) eq 'ARRAY') { 4967: if (!grep(/^$curr$/,@{$cancreate{$item}})) { 4968: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 4969: push(@{$changes{'cancreate'}},$item); 4970: } 4971: } 4972: } 4973: } 4974: } else { 4975: if ($curr_usercreation{'cancreate'}{$item} eq '') { 4976: if (@{$cancreate{$item}} > 0) { 4977: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 4978: push(@{$changes{'cancreate'}},$item); 4979: } 4980: } 4981: } else { 4982: if ($curr_usercreation{'cancreate'}{$item} eq 'any') { 4983: if (@{$cancreate{$item}} < 3) { 4984: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 4985: push(@{$changes{'cancreate'}},$item); 4986: } 4987: } 4988: } elsif ($curr_usercreation{'cancreate'}{$item} eq 'none') { 4989: if (@{$cancreate{$item}} > 0) { 4990: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 4991: push(@{$changes{'cancreate'}},$item); 4992: } 4993: } 4994: } elsif (!grep(/^$curr_usercreation{'cancreate'}{$item}$/,@{$cancreate{$item}})) { 4995: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 4996: push(@{$changes{'cancreate'}},$item); 4997: } 4998: } 4999: } 5000: } 5001: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5002: foreach my $type (@{$cancreate{$item}}) { 5003: if (ref($curr_usercreation{'cancreate'}{$item}) eq 'ARRAY') { 5004: if (!grep(/^$type$/,@{$curr_usercreation{'cancreate'}{$item}})) { 5005: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5006: push(@{$changes{'cancreate'}},$item); 5007: } 5008: } 5009: } elsif (($curr_usercreation{'cancreate'}{$item} ne 'any') && 5010: ($curr_usercreation{'cancreate'}{$item} ne 'none')) { 5011: if ($curr_usercreation{'cancreate'}{$item} ne $type) { 5012: if (!grep(/^$item$/,@{$changes{'cancreate'}})) { 5013: push(@{$changes{'cancreate'}},$item); 5014: } 5015: } 5016: } 5017: } 5018: } 5019: } else { 5020: if ($curr_usercreation{'cancreate'}{$item} ne $cancreate{$item}) { 5021: push(@{$changes{'cancreate'}},$item); 5022: } 5023: } 5024: } 5025: } elsif (ref($curr_usercreation{'cancreate'}) eq 'ARRAY') { 5026: foreach my $item (@contexts) { 5027: if (!grep(/^\Q$item\E$/,@{$curr_usercreation{'cancreate'}})) { 5028: if ($cancreate{$item} ne 'any') { 5029: push(@{$changes{'cancreate'}},$item); 5030: } 5031: } else { 5032: if ($cancreate{$item} ne 'none') { 5033: push(@{$changes{'cancreate'}},$item); 5034: } 5035: } 5036: } 5037: } else { 5038: foreach my $item (@contexts) { 5039: push(@{$changes{'cancreate'}},$item); 5040: } 5041: } 5042: 5043: if (ref($curr_usercreation{'username_rule'}) eq 'ARRAY') { 5044: foreach my $type (@{$curr_usercreation{'username_rule'}}) { 5045: if (!grep(/^\Q$type\E$/,@username_rule)) { 5046: push(@{$changes{'username_rule'}},$type); 5047: } 5048: } 5049: foreach my $type (@username_rule) { 5050: if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'username_rule'}})) { 5051: push(@{$changes{'username_rule'}},$type); 5052: } 5053: } 5054: } else { 5055: push(@{$changes{'username_rule'}},@username_rule); 5056: } 5057: 5058: if (ref($curr_usercreation{'id_rule'}) eq 'ARRAY') { 5059: foreach my $type (@{$curr_usercreation{'id_rule'}}) { 5060: if (!grep(/^\Q$type\E$/,@id_rule)) { 5061: push(@{$changes{'id_rule'}},$type); 5062: } 5063: } 5064: foreach my $type (@id_rule) { 5065: if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'id_rule'}})) { 5066: push(@{$changes{'id_rule'}},$type); 5067: } 5068: } 5069: } else { 5070: push(@{$changes{'id_rule'}},@id_rule); 5071: } 5072: 5073: if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') { 5074: foreach my $type (@{$curr_usercreation{'email_rule'}}) { 5075: if (!grep(/^\Q$type\E$/,@email_rule)) { 5076: push(@{$changes{'email_rule'}},$type); 5077: } 5078: } 5079: foreach my $type (@email_rule) { 5080: if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) { 5081: push(@{$changes{'email_rule'}},$type); 5082: } 5083: } 5084: } else { 5085: push(@{$changes{'email_rule'}},@email_rule); 5086: } 5087: 5088: my @authen_contexts = ('author','course','domain'); 5089: my @authtypes = ('int','krb4','krb5','loc'); 5090: my %authhash; 5091: foreach my $item (@authen_contexts) { 5092: my @authallowed = &Apache::loncommon::get_env_multiple('form.'.$item.'_auth'); 5093: foreach my $auth (@authtypes) { 5094: if (grep(/^\Q$auth\E$/,@authallowed)) { 5095: $authhash{$item}{$auth} = 1; 5096: } else { 5097: $authhash{$item}{$auth} = 0; 5098: } 5099: } 5100: } 5101: if (ref($curr_usercreation{'authtypes'}) eq 'HASH') { 5102: foreach my $item (@authen_contexts) { 5103: if (ref($curr_usercreation{'authtypes'}{$item}) eq 'HASH') { 5104: foreach my $auth (@authtypes) { 5105: if ($authhash{$item}{$auth} ne $curr_usercreation{'authtypes'}{$item}{$auth}) { 5106: push(@{$changes{'authtypes'}},$item); 5107: last; 5108: } 5109: } 5110: } 5111: } 5112: } else { 5113: foreach my $item (@authen_contexts) { 5114: push(@{$changes{'authtypes'}},$item); 5115: } 5116: } 5117: 5118: my %usercreation_hash = ( 5119: usercreation => { 5120: cancreate => \%cancreate, 5121: username_rule => \@username_rule, 5122: id_rule => \@id_rule, 5123: email_rule => \@email_rule, 5124: authtypes => \%authhash, 5125: } 5126: ); 5127: 5128: my $putresult = &Apache::lonnet::put_dom('configuration',\%usercreation_hash, 5129: $dom); 5130: 5131: my %selfcreatetypes = ( 5132: sso => 'users authenticated by institutional single sign on', 5133: login => 'users authenticated by institutional log-in', 5134: email => 'users who provide a valid e-mail address for use as the username', 5135: ); 5136: if ($putresult eq 'ok') { 5137: if (keys(%changes) > 0) { 5138: $resulttext = &mt('Changes made:').'<ul>'; 5139: if (ref($changes{'cancreate'}) eq 'ARRAY') { 5140: my %lt = &usercreation_types(); 5141: foreach my $type (@{$changes{'cancreate'}}) { 5142: my $chgtext; 5143: unless ($type eq 'statustocreate') { 5144: $chgtext = $lt{$type}.', '; 5145: } 5146: if ($type eq 'selfcreate') { 5147: if (@{$cancreate{$type}} == 0) { 5148: $chgtext .= &mt('creation of a new user account is not permitted.'); 5149: } else { 5150: $chgtext .= &mt('creation of a new account is permitted for:').'<ul>'; 5151: foreach my $case (@{$cancreate{$type}}) { 5152: $chgtext .= '<li>'.$selfcreatetypes{$case}.'</li>'; 5153: } 5154: $chgtext .= '</ul>'; 5155: if (ref($cancreate{$type}) eq 'ARRAY') { 5156: if (grep(/^(login|sso)$/,@{$cancreate{$type}})) { 5157: if (ref($cancreate{'statustocreate'}) eq 'ARRAY') { 5158: if (@{$cancreate{'statustocreate'}} == 0) { 5159: $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>'; 5160: } 5161: } 5162: } 5163: } 5164: } 5165: } elsif ($type eq 'statustocreate') { 5166: if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') && 5167: (ref($cancreate{'statustocreate'}) eq 'ARRAY')) { 5168: if (@{$cancreate{'selfcreate'}} > 0) { 5169: if (@{$cancreate{'statustocreate'}} == 0) { 5170: 5171: $chgtext .= &mt("Institutional affiliations permitted to create accounts set to 'None'."); 5172: if (!grep(/^email$/,@{$cancreate{'selfcreate'}})) { 5173: $chgtext .= '<br /><span class="LC_warning">'.&mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts.").'</span>'; 5174: } 5175: } elsif (ref($usertypes) eq 'HASH') { 5176: if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) { 5177: $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):'); 5178: } else { 5179: $chgtext .= &mt('Institutional affiliations permitted to create accounts with institutional authentication were set as follows:'); 5180: } 5181: $chgtext .= '<ul>'; 5182: foreach my $case (@{$cancreate{$type}}) { 5183: if ($case eq 'default') { 5184: $chgtext .= '<li>'.$othertitle.'</li>'; 5185: } else { 5186: $chgtext .= '<li>'.$usertypes->{$case}.'</li>'; 5187: } 5188: } 5189: $chgtext .= '</ul>'; 5190: if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) { 5191: $chgtext .= '<br /><span class="LC_warning">'.&mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.').'</span>'; 5192: } 5193: } 5194: } else { 5195: if (@{$cancreate{$type}} == 0) { 5196: $chgtext .= &mt("Institutional affiliations permitted to create accounts were set to 'none'."); 5197: } else { 5198: $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.'); 5199: } 5200: } 5201: } 5202: } else { 5203: if ($cancreate{$type} eq 'none') { 5204: $chgtext .= &mt('creation of new users is not permitted, except by a Domain Coordinator.'); 5205: } elsif ($cancreate{$type} eq 'any') { 5206: $chgtext .= &mt('creation of new users is permitted for both institutional and non-institutional usernames.'); 5207: } elsif ($cancreate{$type} eq 'official') { 5208: $chgtext .= &mt('creation of new users is only permitted for institutional usernames.'); 5209: } elsif ($cancreate{$type} eq 'unofficial') { 5210: $chgtext .= &mt('creation of new users is only permitted for non-institutional usernames.'); 5211: } 5212: } 5213: $resulttext .= '<li>'.$chgtext.'</li>'; 5214: } 5215: } 5216: if (ref($changes{'username_rule'}) eq 'ARRAY') { 5217: my ($rules,$ruleorder) = 5218: &Apache::lonnet::inst_userrules($dom,'username'); 5219: my $chgtext = '<ul>'; 5220: foreach my $type (@username_rule) { 5221: if (ref($rules->{$type}) eq 'HASH') { 5222: $chgtext .= '<li>'.$rules->{$type}{'name'}.'</li>'; 5223: } 5224: } 5225: $chgtext .= '</ul>'; 5226: if (@username_rule > 0) { 5227: $resulttext .= '<li>'.&mt('Usernames with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>'; 5228: } else { 5229: $resulttext .= '<li>'.&mt('There are now no username formats restricted to verified users in the institutional directory.').'</li>'; 5230: } 5231: } 5232: if (ref($changes{'id_rule'}) eq 'ARRAY') { 5233: my ($idrules,$idruleorder) = 5234: &Apache::lonnet::inst_userrules($dom,'id'); 5235: my $chgtext = '<ul>'; 5236: foreach my $type (@id_rule) { 5237: if (ref($idrules->{$type}) eq 'HASH') { 5238: $chgtext .= '<li>'.$idrules->{$type}{'name'}.'</li>'; 5239: } 5240: } 5241: $chgtext .= '</ul>'; 5242: if (@id_rule > 0) { 5243: $resulttext .= '<li>'.&mt('IDs with the following formats are restricted to verified users in the institutional directory: ').$chgtext.'</li>'; 5244: } else { 5245: $resulttext .= '<li>'.&mt('There are now no ID formats restricted to verified users in the institutional directory.').'</li>'; 5246: } 5247: } 5248: if (ref($changes{'email_rule'}) eq 'ARRAY') { 5249: my ($emailrules,$emailruleorder) = 5250: &Apache::lonnet::inst_userrules($dom,'email'); 5251: my $chgtext = '<ul>'; 5252: foreach my $type (@email_rule) { 5253: if (ref($emailrules->{$type}) eq 'HASH') { 5254: $chgtext .= '<li>'.$emailrules->{$type}{'name'}.'</li>'; 5255: } 5256: } 5257: $chgtext .= '</ul>'; 5258: if (@email_rule > 0) { 5259: $resulttext .= '<li>'.&mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: ').$chgtext.'</li>'; 5260: } else { 5261: $resulttext .= '<li>'.&mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.').'</li>'; 5262: } 5263: } 5264: 5265: my %authname = &authtype_names(); 5266: my %context_title = &context_names(); 5267: if (ref($changes{'authtypes'}) eq 'ARRAY') { 5268: my $chgtext = '<ul>'; 5269: foreach my $type (@{$changes{'authtypes'}}) { 5270: my @allowed; 5271: $chgtext .= '<li><span class="LC_cusr_emph">'.$context_title{$type}.'</span> - '.&mt('assignable authentication types: '); 5272: foreach my $auth (@authtypes) { 5273: if ($authhash{$type}{$auth}) { 5274: push(@allowed,$authname{$auth}); 5275: } 5276: } 5277: if (@allowed > 0) { 5278: $chgtext .= join(', ',@allowed).'</li>'; 5279: } else { 5280: $chgtext .= &mt('none').'</li>'; 5281: } 5282: } 5283: $chgtext .= '</ul>'; 5284: $resulttext .= '<li>'.&mt('Authentication types available for assignment to new users').'<br />'.$chgtext; 5285: $resulttext .= '</li>'; 5286: } 5287: $resulttext .= '</ul>'; 5288: } else { 5289: $resulttext = &mt('No changes made to user creation settings'); 5290: } 5291: } else { 5292: $resulttext = '<span class="LC_error">'. 5293: &mt('An error occurred: [_1]',$putresult).'</span>'; 5294: } 5295: if ($warningmsg ne '') { 5296: $resulttext .= '<br /><span class="LC_warning">'.$warningmsg.'</span><br />'; 5297: } 5298: return $resulttext; 5299: } 5300: 5301: sub modify_usermodification { 5302: my ($dom,%domconfig) = @_; 5303: my ($resulttext,%curr_usermodification,%changes); 5304: if (ref($domconfig{'usermodification'}) eq 'HASH') { 5305: foreach my $key (keys(%{$domconfig{'usermodification'}})) { 5306: $curr_usermodification{$key} = $domconfig{'usermodification'}{$key}; 5307: } 5308: } 5309: my @contexts = ('author','course','selfcreate'); 5310: my %context_title = ( 5311: author => 'In author context', 5312: course => 'In course context', 5313: selfcreate => 'When self creating account', 5314: ); 5315: my @fields = ('lastname','firstname','middlename','generation', 5316: 'permanentemail','id'); 5317: my %roles = ( 5318: author => ['ca','aa'], 5319: course => ['st','ep','ta','in','cr'], 5320: ); 5321: my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); 5322: if (ref($types) eq 'ARRAY') { 5323: push(@{$types},'default'); 5324: $usertypes->{'default'} = $othertitle; 5325: } 5326: $roles{'selfcreate'} = $types; 5327: my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); 5328: my %modifyhash; 5329: foreach my $context (@contexts) { 5330: foreach my $role (@{$roles{$context}}) { 5331: my @modifiable = &Apache::loncommon::get_env_multiple('form.canmodify_'.$role); 5332: foreach my $item (@fields) { 5333: if (grep(/^\Q$item\E$/,@modifiable)) { 5334: $modifyhash{$context}{$role}{$item} = 1; 5335: } else { 5336: $modifyhash{$context}{$role}{$item} = 0; 5337: } 5338: } 5339: } 5340: if (ref($curr_usermodification{$context}) eq 'HASH') { 5341: foreach my $role (@{$roles{$context}}) { 5342: if (ref($curr_usermodification{$context}{$role}) eq 'HASH') { 5343: foreach my $field (@fields) { 5344: if ($modifyhash{$context}{$role}{$field} ne 5345: $curr_usermodification{$context}{$role}{$field}) { 5346: push(@{$changes{$context}},$role); 5347: last; 5348: } 5349: } 5350: } 5351: } 5352: } else { 5353: foreach my $context (@contexts) { 5354: foreach my $role (@{$roles{$context}}) { 5355: push(@{$changes{$context}},$role); 5356: } 5357: } 5358: } 5359: } 5360: my %usermodification_hash = ( 5361: usermodification => \%modifyhash, 5362: ); 5363: my $putresult = &Apache::lonnet::put_dom('configuration', 5364: \%usermodification_hash,$dom); 5365: if ($putresult eq 'ok') { 5366: if (keys(%changes) > 0) { 5367: $resulttext = &mt('Changes made: ').'<ul>'; 5368: foreach my $context (@contexts) { 5369: if (ref($changes{$context}) eq 'ARRAY') { 5370: $resulttext .= '<li>'.$context_title{$context}.':<ul>'; 5371: if (ref($changes{$context}) eq 'ARRAY') { 5372: foreach my $role (@{$changes{$context}}) { 5373: my $rolename; 5374: if ($context eq 'selfcreate') { 5375: $rolename = $role; 5376: if (ref($usertypes) eq 'HASH') { 5377: if ($usertypes->{$role} ne '') { 5378: $rolename = $usertypes->{$role}; 5379: } 5380: } 5381: } else { 5382: if ($role eq 'cr') { 5383: $rolename = &mt('Custom'); 5384: } else { 5385: $rolename = &Apache::lonnet::plaintext($role); 5386: } 5387: } 5388: my @modifiable; 5389: if ($context eq 'selfcreate') { 5390: $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): '); 5391: } else { 5392: $resulttext .= '<li><span class="LC_cusr_emph">'.&mt('Target user with [_1] role',$rolename).'</span> - '.&mt('modifiable fields: '); 5393: } 5394: foreach my $field (@fields) { 5395: if ($modifyhash{$context}{$role}{$field}) { 5396: push(@modifiable,$fieldtitles{$field}); 5397: } 5398: } 5399: if (@modifiable > 0) { 5400: $resulttext .= join(', ',@modifiable); 5401: } else { 5402: $resulttext .= &mt('none'); 5403: } 5404: $resulttext .= '</li>'; 5405: } 5406: $resulttext .= '</ul></li>'; 5407: } 5408: } 5409: } 5410: $resulttext .= '</ul>'; 5411: } else { 5412: $resulttext = &mt('No changes made to user modification settings'); 5413: } 5414: } else { 5415: $resulttext = '<span class="LC_error">'. 5416: &mt('An error occurred: [_1]',$putresult).'</span>'; 5417: } 5418: return $resulttext; 5419: } 5420: 5421: sub modify_defaults { 5422: my ($dom,$r) = @_; 5423: my ($resulttext,$mailmsgtxt,%newvalues,%changes,@errors); 5424: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 5425: my @items = ('auth_def','auth_arg_def','lang_def','timezone_def','datelocale_def'); 5426: my @authtypes = ('internal','krb4','krb5','localauth'); 5427: foreach my $item (@items) { 5428: $newvalues{$item} = $env{'form.'.$item}; 5429: if ($item eq 'auth_def') { 5430: if ($newvalues{$item} ne '') { 5431: if (!grep(/^\Q$newvalues{$item}\E$/,@authtypes)) { 5432: push(@errors,$item); 5433: } 5434: } 5435: } elsif ($item eq 'lang_def') { 5436: if ($newvalues{$item} ne '') { 5437: if ($newvalues{$item} =~ /^(\w+)/) { 5438: my $langcode = $1; 5439: if ($langcode ne 'x_chef') { 5440: if (code2language($langcode) eq '') { 5441: push(@errors,$item); 5442: } 5443: } 5444: } else { 5445: push(@errors,$item); 5446: } 5447: } 5448: } elsif ($item eq 'timezone_def') { 5449: if ($newvalues{$item} ne '') { 5450: if (!DateTime::TimeZone->is_valid_name($newvalues{$item})) { 5451: push(@errors,$item); 5452: } 5453: } 5454: } elsif ($item eq 'datelocale_def') { 5455: if ($newvalues{$item} ne '') { 5456: my @datelocale_ids = DateTime::Locale->ids(); 5457: if (!grep(/^\Q$newvalues{$item}\E$/,@datelocale_ids)) { 5458: push(@errors,$item); 5459: } 5460: } 5461: } 5462: if (grep(/^\Q$item\E$/,@errors)) { 5463: $newvalues{$item} = $domdefaults{$item}; 5464: } elsif ($domdefaults{$item} ne $newvalues{$item}) { 5465: $changes{$item} = 1; 5466: } 5467: $domdefaults{$item} = $newvalues{$item}; 5468: } 5469: my %defaults_hash = ( 5470: defaults => \%newvalues, 5471: ); 5472: my $title = &defaults_titles(); 5473: my $putresult = &Apache::lonnet::put_dom('configuration',\%defaults_hash, 5474: $dom); 5475: if ($putresult eq 'ok') { 5476: if (keys(%changes) > 0) { 5477: $resulttext = &mt('Changes made:').'<ul>'; 5478: my $version = $r->dir_config('lonVersion'); 5479: 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"; 5480: foreach my $item (sort(keys(%changes))) { 5481: my $value = $env{'form.'.$item}; 5482: if ($value eq '') { 5483: $value = &mt('none'); 5484: } elsif ($item eq 'auth_def') { 5485: my %authnames = &authtype_names(); 5486: my %shortauth = ( 5487: internal => 'int', 5488: krb4 => 'krb4', 5489: krb5 => 'krb5', 5490: localauth => 'loc', 5491: ); 5492: $value = $authnames{$shortauth{$value}}; 5493: } 5494: $resulttext .= '<li>'.&mt('[_1] set to "[_2]"',$title->{$item},$value).'</li>'; 5495: $mailmsgtext .= "$title->{$item} set to $value\n"; 5496: } 5497: $resulttext .= '</ul>'; 5498: $mailmsgtext .= "\n"; 5499: my $cachetime = 24*60*60; 5500: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); 5501: if ($changes{'auth_def'} || $changes{'auth_arg_def'} || $changes{'lang_def'} || $changes{'datelocale_def'}) { 5502: my $sysmail = $r->dir_config('lonSysEMail'); 5503: &Apache::lonmsg::sendemail($sysmail,"LON-CAPA Domain Settings Change - $dom",$mailmsgtext); 5504: } 5505: } else { 5506: $resulttext = &mt('No changes made to default authentication/language/timezone settings'); 5507: } 5508: } else { 5509: $resulttext = '<span class="LC_error">'. 5510: &mt('An error occurred: [_1]',$putresult).'</span>'; 5511: } 5512: if (@errors > 0) { 5513: $resulttext .= '<br />'.&mt('The following were left unchanged because the values entered were invalid:'); 5514: foreach my $item (@errors) { 5515: $resulttext .= ' "'.$title->{$item}.'",'; 5516: } 5517: $resulttext =~ s/,$//; 5518: } 5519: return $resulttext; 5520: } 5521: 5522: sub modify_scantron { 5523: my ($r,$dom,$confname,%domconfig) = @_; 5524: my ($resulttext,%confhash,%changes,$errors); 5525: my $custom = 'custom.tab'; 5526: my $default = 'default.tab'; 5527: my $servadm = $r->dir_config('lonAdmEMail'); 5528: my ($configuserok,$author_ok,$switchserver) = 5529: &config_check($dom,$confname,$servadm); 5530: if ($env{'form.scantronformat.filename'} ne '') { 5531: my $error; 5532: if ($configuserok eq 'ok') { 5533: if ($switchserver) { 5534: $error = &mt("Upload of scantron format file is not permitted to this server: [_1]",$switchserver); 5535: } else { 5536: if ($author_ok eq 'ok') { 5537: my ($result,$scantronurl) = 5538: &publishlogo($r,'upload','scantronformat',$dom, 5539: $confname,'scantron','','',$custom); 5540: if ($result eq 'ok') { 5541: $confhash{'scantron'}{'scantronformat'} = $scantronurl; 5542: $changes{'scantronformat'} = 1; 5543: } else { 5544: $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$custom,$result); 5545: } 5546: } else { 5547: $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); 5548: } 5549: } 5550: } else { 5551: $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); 5552: } 5553: if ($error) { 5554: &Apache::lonnet::logthis($error); 5555: $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; 5556: } 5557: } 5558: if (ref($domconfig{'scantron'}) eq 'HASH') { 5559: if ($domconfig{'scantron'}{'scantronformat'} ne '') { 5560: if ($env{'form.scantronformat_del'}) { 5561: $confhash{'scantron'}{'scantronformat'} = ''; 5562: $changes{'scantronformat'} = 1; 5563: } 5564: } 5565: } 5566: if (keys(%confhash) > 0) { 5567: my $putresult = &Apache::lonnet::put_dom('configuration',\%confhash, 5568: $dom); 5569: if ($putresult eq 'ok') { 5570: if (keys(%changes) > 0) { 5571: if (ref($confhash{'scantron'}) eq 'HASH') { 5572: $resulttext = &mt('Changes made:').'<ul>'; 5573: if ($confhash{'scantron'}{'scantronformat'} eq '') { 5574: $resulttext .= '<li>'.&mt('[_1] scantron format file removed; [_2] file will be used for courses in this domain.',$custom,$default).'</li>'; 5575: } else { 5576: $resulttext .= '<li>'.&mt('Custom scantron format file ([_1]) uploaded for use with courses in this domain.',$custom).'</li>'; 5577: } 5578: $resulttext .= '</ul>'; 5579: } else { 5580: $resulttext = &mt('Changes made to scantron format file.'); 5581: } 5582: $resulttext .= '</ul>'; 5583: &Apache::loncommon::devalidate_domconfig_cache($dom); 5584: } else { 5585: $resulttext = &mt('No changes made to scantron format file'); 5586: } 5587: } else { 5588: $resulttext = '<span class="LC_error">'. 5589: &mt('An error occurred: [_1]',$putresult).'</span>'; 5590: } 5591: } else { 5592: $resulttext = &mt('No changes made to scantron format file'); 5593: } 5594: if ($errors) { 5595: $resulttext .= &mt('The following errors occurred: ').'<ul>'. 5596: $errors.'</ul>'; 5597: } 5598: return $resulttext; 5599: } 5600: 5601: sub modify_coursecategories { 5602: my ($dom,%domconfig) = @_; 5603: my ($resulttext,%deletions,%reorderings,%needreordering,%adds,%changes,$errors, 5604: $cathash); 5605: my @deletecategory = &Apache::loncommon::get_env_multiple('form.deletecategory'); 5606: if (ref($domconfig{'coursecategories'}) eq 'HASH') { 5607: $cathash = $domconfig{'coursecategories'}{'cats'}; 5608: if ($domconfig{'coursecategories'}{'togglecats'} ne $env{'form.togglecats'}) { 5609: $changes{'togglecats'} = 1; 5610: $domconfig{'coursecategories'}{'togglecats'} = $env{'form.togglecats'}; 5611: } 5612: if ($domconfig{'coursecategories'}{'categorize'} ne $env{'form.categorize'}) { 5613: $changes{'categorize'} = 1; 5614: $domconfig{'coursecategories'}{'categorize'} = $env{'form.categorize'}; 5615: } 5616: if ($domconfig{'coursecategories'}{'togglecatscomm'} ne $env{'form.togglecatscomm'}) { 5617: $changes{'togglecatscomm'} = 1; 5618: $domconfig{'coursecategories'}{'togglecatscomm'} = $env{'form.togglecatscomm'}; 5619: } 5620: if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) { 5621: $changes{'categorizecomm'} = 1; 5622: $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'}; 5623: } 5624: } else { 5625: $changes{'togglecats'} = 1; 5626: $changes{'categorize'} = 1; 5627: $domconfig{'coursecategories'} = { 5628: togglecats => $env{'form.togglecats'}, 5629: categorize => $env{'form.categorize'}, 5630: }; 5631: $changes{'togglecatscomm'} = 1; 5632: $changes{'categorizecomm'} = 1; 5633: $domconfig{'coursecategories'} = { 5634: togglecats => $env{'form.togglecatscomm'}, 5635: categorize => $env{'form.categorizecomm'}, 5636: }; 5637: } 5638: if (ref($cathash) eq 'HASH') { 5639: if (($domconfig{'coursecategories'}{'cats'}{'instcode::0'} ne '') && ($env{'form.instcode'} == 0)) { 5640: push (@deletecategory,'instcode::0'); 5641: } 5642: if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '') && ($env{'form.communities'} == 0)) { 5643: push(@deletecategory,'communities::0'); 5644: } 5645: } 5646: my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail); 5647: if (ref($cathash) eq 'HASH') { 5648: if (@deletecategory > 0) { 5649: #FIXME Need to remove category from all courses using a deleted category 5650: &Apache::loncommon::extract_categories($cathash,\@predelcats,\@predeltrails,\%predelallitems); 5651: foreach my $item (@deletecategory) { 5652: if ($domconfig{'coursecategories'}{'cats'}{$item} ne '') { 5653: delete($domconfig{'coursecategories'}{'cats'}{$item}); 5654: $deletions{$item} = 1; 5655: &recurse_cat_deletes($item,$cathash,\%deletions); 5656: } 5657: } 5658: } 5659: foreach my $item (keys(%{$cathash})) { 5660: my ($cat,$container,$depth) = map { &unescape($_); } split(/:/,$item); 5661: if ($cathash->{$item} ne $env{'form.'.$item}) { 5662: $reorderings{$item} = 1; 5663: $domconfig{'coursecategories'}{'cats'}{$item} = $env{'form.'.$item}; 5664: } 5665: if ($env{'form.addcategory_name_'.$item} ne '') { 5666: my $newcat = $env{'form.addcategory_name_'.$item}; 5667: my $newdepth = $depth+1; 5668: my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth; 5669: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos_'.$item}; 5670: $adds{$newitem} = 1; 5671: } 5672: if ($env{'form.subcat_'.$item} ne '') { 5673: my $newcat = $env{'form.subcat_'.$item}; 5674: my $newdepth = $depth+1; 5675: my $newitem = &escape($newcat).':'.&escape($cat).':'.$newdepth; 5676: $domconfig{'coursecategories'}{'cats'}{$newitem} = 0; 5677: $adds{$newitem} = 1; 5678: } 5679: } 5680: } 5681: if ($env{'form.instcode'} eq '1') { 5682: if (ref($cathash) eq 'HASH') { 5683: my $newitem = 'instcode::0'; 5684: if ($cathash->{$newitem} eq '') { 5685: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.instcode_pos'}; 5686: $adds{$newitem} = 1; 5687: } 5688: } else { 5689: my $newitem = 'instcode::0'; 5690: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.instcode_pos'}; 5691: $adds{$newitem} = 1; 5692: } 5693: } 5694: if ($env{'form.communities'} eq '1') { 5695: if (ref($cathash) eq 'HASH') { 5696: my $newitem = 'communities::0'; 5697: if ($cathash->{$newitem} eq '') { 5698: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'}; 5699: $adds{$newitem} = 1; 5700: } 5701: } else { 5702: my $newitem = 'communities::0'; 5703: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.communities_pos'}; 5704: $adds{$newitem} = 1; 5705: } 5706: } 5707: if ($env{'form.addcategory_name'} ne '') { 5708: if (($env{'form.addcategory_name'} ne 'instcode') && 5709: ($env{'form.addcategory_name'} ne 'communities')) { 5710: my $newitem = &escape($env{'form.addcategory_name'}).'::0'; 5711: $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'}; 5712: $adds{$newitem} = 1; 5713: } 5714: } 5715: my $putresult; 5716: if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) { 5717: if (keys(%deletions) > 0) { 5718: foreach my $key (keys(%deletions)) { 5719: if ($predelallitems{$key} ne '') { 5720: $sort_by_deltrail{$predelallitems{$key}} = $predeltrails[$predelallitems{$key}]; 5721: } 5722: } 5723: } 5724: my (@chkcats,@chktrails,%chkallitems); 5725: &Apache::loncommon::extract_categories($domconfig{'coursecategories'}{'cats'},\@chkcats,\@chktrails,\%chkallitems); 5726: if (ref($chkcats[0]) eq 'ARRAY') { 5727: my $depth = 0; 5728: my $chg = 0; 5729: for (my $i=0; $i<@{$chkcats[0]}; $i++) { 5730: my $name = $chkcats[0][$i]; 5731: my $item; 5732: if ($name eq '') { 5733: $chg ++; 5734: } else { 5735: $item = &escape($name).'::0'; 5736: if ($chg) { 5737: $domconfig{'coursecategories'}{'cats'}{$item} -= $chg; 5738: } 5739: $depth ++; 5740: &recurse_check(\@chkcats,$domconfig{'coursecategories'}{'cats'},$depth,$name); 5741: $depth --; 5742: } 5743: } 5744: } 5745: } 5746: if ((keys(%changes) > 0) || (keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) { 5747: $putresult = &Apache::lonnet::put_dom('configuration',\%domconfig,$dom); 5748: if ($putresult eq 'ok') { 5749: my %title = ( 5750: togglecats => 'Show/Hide a course in catalog', 5751: categorize => 'Assign a category to a course', 5752: togglecatscomm => 'Show/Hide a community in catalog', 5753: categorizecomm => 'Assign a category to a community', 5754: ); 5755: my %level = ( 5756: dom => 'set in Domain ("Modify Course/Community")', 5757: crs => 'set in Course ("Course Configuration")', 5758: comm => 'set in Community ("Community Configuration")', 5759: ); 5760: $resulttext = &mt('Changes made:').'<ul>'; 5761: if ($changes{'togglecats'}) { 5762: $resulttext .= '<li>'.&mt("$title{'togglecats'} $level{$env{'form.togglecats'}}").'</li>'; 5763: } 5764: if ($changes{'categorize'}) { 5765: $resulttext .= '<li>'.&mt("$title{'categorize'} $level{$env{'form.categorize'}}").'</li>'; 5766: } 5767: if ($changes{'togglecatscomm'}) { 5768: $resulttext .= '<li>'.&mt("$title{'togglecatscomm'} $level{$env{'form.togglecatscomm'}}").'</li>'; 5769: } 5770: if ($changes{'categorizecomm'}) { 5771: $resulttext .= '<li>'.&mt("$title{'categorizecomm'} $level{$env{'form.categorizecomm'}}").'</li>'; 5772: } 5773: if ((keys(%deletions) > 0) || (keys(%reorderings) > 0) || (keys(%adds) > 0)) { 5774: my $cathash; 5775: if (ref($domconfig{'coursecategories'}) eq 'HASH') { 5776: $cathash = $domconfig{'coursecategories'}{'cats'}; 5777: } else { 5778: $cathash = {}; 5779: } 5780: my (@cats,@trails,%allitems); 5781: &Apache::loncommon::extract_categories($cathash,\@cats,\@trails,\%allitems); 5782: if (keys(%deletions) > 0) { 5783: $resulttext .= '<li>'.&mt('Deleted categories:').'<ul>'; 5784: foreach my $predeltrail (sort {$a <=> $b } (keys(%sort_by_deltrail))) { 5785: $resulttext .= '<li>'.$predeltrails[$predeltrail].'</li>'; 5786: } 5787: $resulttext .= '</ul></li>'; 5788: } 5789: if (keys(%reorderings) > 0) { 5790: my %sort_by_trail; 5791: $resulttext .= '<li>'.&mt('Reordered categories:').'<ul>'; 5792: foreach my $key (keys(%reorderings)) { 5793: if ($allitems{$key} ne '') { 5794: $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}]; 5795: } 5796: } 5797: foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) { 5798: $resulttext .= '<li>'.$trails[$trail].'</li>'; 5799: } 5800: $resulttext .= '</ul></li>'; 5801: } 5802: if (keys(%adds) > 0) { 5803: my %sort_by_trail; 5804: $resulttext .= '<li>'.&mt('Added categories:').'<ul>'; 5805: foreach my $key (keys(%adds)) { 5806: if ($allitems{$key} ne '') { 5807: $sort_by_trail{$allitems{$key}} = $trails[$allitems{$key}]; 5808: } 5809: } 5810: foreach my $trail (sort {$a <=> $b } (keys(%sort_by_trail))) { 5811: $resulttext .= '<li>'.$trails[$trail].'</li>'; 5812: } 5813: $resulttext .= '</ul></li>'; 5814: } 5815: } 5816: $resulttext .= '</ul>'; 5817: } else { 5818: $resulttext = '<span class="LC_error">'. 5819: &mt('An error occurred: [_1]',$putresult).'</span>'; 5820: } 5821: } else { 5822: $resulttext = &mt('No changes made to course and community categories'); 5823: } 5824: return $resulttext; 5825: } 5826: 5827: sub modify_serverstatuses { 5828: my ($dom,%domconfig) = @_; 5829: my ($resulttext,%changes,%currserverstatus,%newserverstatus); 5830: if (ref($domconfig{'serverstatuses'}) eq 'HASH') { 5831: %currserverstatus = %{$domconfig{'serverstatuses'}}; 5832: } 5833: my @pages = &serverstatus_pages(); 5834: foreach my $type (@pages) { 5835: $newserverstatus{$type}{'namedusers'} = ''; 5836: $newserverstatus{$type}{'machines'} = ''; 5837: if (defined($env{'form.'.$type.'_namedusers'})) { 5838: my @users = split(/,/,$env{'form.'.$type.'_namedusers'}); 5839: my @okusers; 5840: foreach my $user (@users) { 5841: my ($uname,$udom) = split(/:/,$user); 5842: if (($udom =~ /^$match_domain$/) && 5843: (&Apache::lonnet::domain($udom)) && 5844: ($uname =~ /^$match_username$/)) { 5845: if (!grep(/^\Q$user\E/,@okusers)) { 5846: push(@okusers,$user); 5847: } 5848: } 5849: } 5850: if (@okusers > 0) { 5851: @okusers = sort(@okusers); 5852: $newserverstatus{$type}{'namedusers'} = join(',',@okusers); 5853: } 5854: } 5855: if (defined($env{'form.'.$type.'_machines'})) { 5856: my @machines = split(/,/,$env{'form.'.$type.'_machines'}); 5857: my @okmachines; 5858: foreach my $ip (@machines) { 5859: my @parts = split(/\./,$ip); 5860: next if (@parts < 4); 5861: my $badip = 0; 5862: for (my $i=0; $i<4; $i++) { 5863: if (!(($parts[$i] >= 0) && ($parts[$i] <= 255))) { 5864: $badip = 1; 5865: last; 5866: } 5867: } 5868: if (!$badip) { 5869: push(@okmachines,$ip); 5870: } 5871: } 5872: @okmachines = sort(@okmachines); 5873: $newserverstatus{$type}{'machines'} = join(',',@okmachines); 5874: } 5875: } 5876: my %serverstatushash = ( 5877: serverstatuses => \%newserverstatus, 5878: ); 5879: my %changes; 5880: foreach my $type (@pages) { 5881: foreach my $setting ('namedusers','machines') { 5882: my (@current,@new); 5883: if (ref($currserverstatus{$type}) eq 'HASH') { 5884: if ($currserverstatus{$type}{$setting} ne '') { 5885: @current = split(/,/,$currserverstatus{$type}{$setting}); 5886: } 5887: } 5888: if ($newserverstatus{$type}{$setting} ne '') { 5889: @new = split(/,/,$newserverstatus{$type}{$setting}); 5890: } 5891: if (@current > 0) { 5892: if (@new > 0) { 5893: foreach my $item (@current) { 5894: if (!grep(/^\Q$item\E$/,@new)) { 5895: $changes{$type}{$setting} = 1; 5896: last; 5897: } 5898: } 5899: foreach my $item (@new) { 5900: if (!grep(/^\Q$item\E$/,@current)) { 5901: $changes{$type}{$setting} = 1; 5902: last; 5903: } 5904: } 5905: } else { 5906: $changes{$type}{$setting} = 1; 5907: } 5908: } elsif (@new > 0) { 5909: $changes{$type}{$setting} = 1; 5910: } 5911: } 5912: } 5913: if (keys(%changes) > 0) { 5914: my $titles= &LONCAPA::lonauthcgi::serverstatus_titles(); 5915: my $putresult = &Apache::lonnet::put_dom('configuration', 5916: \%serverstatushash,$dom); 5917: if ($putresult eq 'ok') { 5918: $resulttext .= &mt('Changes made:').'<ul>'; 5919: foreach my $type (@pages) { 5920: if (ref($changes{$type}) eq 'HASH') { 5921: $resulttext .= '<li>'.$titles->{$type}.'<ul>'; 5922: if ($changes{$type}{'namedusers'}) { 5923: if ($newserverstatus{$type}{'namedusers'} eq '') { 5924: $resulttext .= '<li>'.&mt("Access terminated for all specific (named) users").'</li>'."\n"; 5925: } else { 5926: $resulttext .= '<li>'.&mt("Access available for the following specified users: ").$newserverstatus{$type}{'namedusers'}.'</li>'."\n"; 5927: } 5928: } 5929: if ($changes{$type}{'machines'}) { 5930: if ($newserverstatus{$type}{'machines'} eq '') { 5931: $resulttext .= '<li>'.&mt("Access terminated for all specific IP addresses").'</li>'."\n"; 5932: } else { 5933: $resulttext .= '<li>'.&mt("Access available for the following specified IP addresses: ").$newserverstatus{$type}{'machines'}.'</li>'."\n"; 5934: } 5935: 5936: } 5937: $resulttext .= '</ul></li>'; 5938: } 5939: } 5940: $resulttext .= '</ul>'; 5941: } else { 5942: $resulttext = '<span class="LC_error">'. 5943: &mt('An error occurred saving access settings for server status pages: [_1].',$putresult).'</span>'; 5944: 5945: } 5946: } else { 5947: $resulttext = &mt('No changes made to access to server status pages'); 5948: } 5949: return $resulttext; 5950: } 5951: 5952: sub modify_helpsettings { 5953: my ($r,$dom,$confname,%domconfig) = @_; 5954: my ($resulttext,$errors,%changes,%helphash); 5955: 5956: my $customhelpfile = $env{'form.loginhelpurl.filename'}; 5957: my $defaulthelpfile = 'defaulthelp.html'; 5958: my $servadm = $r->dir_config('lonAdmEMail'); 5959: my ($configuserok,$author_ok,$switchserver) = 5960: &config_check($dom,$confname,$servadm); 5961: 5962: my %defaultchecked = ('submitbugs' => 'on'); 5963: my @offon = ('off','on'); 5964: my %title = ( submitbugs => 'Display link for users to submit a bug', 5965: loginhelpurl => 'Unauthenticated login help page set to custom file'); 5966: 5967: my @toggles = ('submitbugs'); 5968: 5969: $helphash{'helpsettings'} = {}; 5970: 5971: if (ref($domconfig{'helpsettings'}) ne 'HASH') { 5972: if ($domconfig{'helpsettings'} eq '') { 5973: $domconfig{'helpsettings'} = {}; 5974: } 5975: } 5976: 5977: if (ref($domconfig{'helpsettings'}) eq 'HASH') { 5978: 5979: foreach my $item (@toggles) { 5980: 5981: if ($defaultchecked{$item} eq 'on') { 5982: if (($domconfig{'helpsettings'}{$item} eq '') && 5983: ($env{'form.'.$item} eq '0')) { 5984: $changes{$item} = 1; 5985: } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { 5986: $changes{$item} = 1; 5987: } 5988: } elsif ($defaultchecked{$item} eq 'off') { 5989: if (($domconfig{'helpsettings'}{$item} eq '') && 5990: ($env{'form.'.$item} eq '1')) { 5991: $changes{$item} = 1; 5992: } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { 5993: $changes{$item} = 1; 5994: } 5995: } 5996: $helphash{'helpsettings'}{$item} = $env{'form.'.$item}; 5997: } 5998: 5999: if ($customhelpfile ne '') { 6000: my $error; 6001: if ($configuserok eq 'ok') { 6002: if ($switchserver) { 6003: $error = &mt("Upload of custom help file is not permitted to this server: [_1]",$switchserver); 6004: } else { 6005: if ($author_ok eq 'ok') { 6006: my ($result,$loginhelpurl) = 6007: &publishlogo($r,'upload','loginhelpurl',$dom, 6008: $confname,'help','','',$customhelpfile); 6009: if ($result eq 'ok') { 6010: $helphash{'helpsettings'}{'loginhelpurl'} = $loginhelpurl; 6011: $changes{'loginhelpurl'} = 1; 6012: } else { 6013: $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$customhelpfile,$result); 6014: } 6015: } else { 6016: $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); 6017: } 6018: } 6019: } else { 6020: $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); 6021: } 6022: if ($error) { 6023: &Apache::lonnet::logthis($error); 6024: $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; 6025: } 6026: } 6027: 6028: if ($domconfig{'helpsettings'}{'loginhelpurl'} ne '') { 6029: if ($env{'form.loginhelpurl_del'}) { 6030: $helphash{'helpsettings'}{'loginhelpurl'} = ''; 6031: $changes{'loginhelpurl'} = 1; 6032: } 6033: } 6034: } 6035: 6036: my $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom); 6037: 6038: if ($putresult eq 'ok') { 6039: if (keys(%changes) > 0) { 6040: $resulttext = &mt('Changes made:').'<ul>'; 6041: foreach my $item (sort(keys(%changes))) { 6042: if ($item eq 'submitbugs') { 6043: $resulttext .= '<li>'.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'</li>'; 6044: } 6045: if ($item eq 'loginhelpurl') { 6046: if ($helphash{'helpsettings'}{'loginhelpurl'} eq '') { 6047: $resulttext .= '<li>'.&mt('[_1] help file removed; [_2] file will be used for the unathorized help page in this domain.',$customhelpfile,$defaulthelpfile).'</li>'; 6048: } else { 6049: $resulttext .= '<li>'.&mt("$title{$item} [_1]",$customhelpfile).'</li>'; 6050: } 6051: } 6052: } 6053: $resulttext .= '</ul>'; 6054: } else { 6055: $resulttext = &mt('No changes made to help settings'); 6056: } 6057: } else { 6058: $resulttext = '<span class="LC_error">'. 6059: &mt('An error occurred: [_1]',$putresult).'</span>'; 6060: } 6061: if ($errors) { 6062: $resulttext .= &mt('The following errors occurred: ').'<ul>'. 6063: $errors.'</ul>'; 6064: } 6065: return $resulttext; 6066: } 6067: 6068: sub modify_coursedefaults { 6069: my ($dom,%domconfig) = @_; 6070: my ($resulttext,$errors,%changes,%defaultshash); 6071: my %defaultchecked = ('canuse_pdfforms' => 'off'); 6072: my @offon = ('off','on'); 6073: my @toggles = ('canuse_pdfforms'); 6074: 6075: $defaultshash{'coursedefaults'} = {}; 6076: 6077: if (ref($domconfig{'coursedefaults'}) ne 'HASH') { 6078: if ($domconfig{'coursedefaults'} eq '') { 6079: $domconfig{'coursedefaults'} = {}; 6080: } 6081: } 6082: 6083: if (ref($domconfig{'coursedefaults'}) eq 'HASH') { 6084: foreach my $item (@toggles) { 6085: if ($defaultchecked{$item} eq 'on') { 6086: if (($domconfig{'coursedefaults'}{$item} eq '') && 6087: ($env{'form.'.$item} eq '0')) { 6088: $changes{$item} = 1; 6089: } elsif ($domconfig{'coursdefaults'}{$item} ne $env{'form.'.$item}) { 6090: $changes{$item} = 1; 6091: } 6092: } elsif ($defaultchecked{$item} eq 'off') { 6093: if (($domconfig{'coursedefaults'}{$item} eq '') && 6094: ($env{'form.'.$item} eq '1')) { 6095: $changes{$item} = 1; 6096: } elsif ($domconfig{'coursedefaults'}{$item} ne $env{'form.'.$item}) { 6097: $changes{$item} = 1; 6098: } 6099: } 6100: $defaultshash{'coursedefaults'}{$item} = $env{'form.'.$item}; 6101: } 6102: } 6103: my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, 6104: $dom); 6105: if ($putresult eq 'ok') { 6106: if (keys(%changes) > 0) { 6107: if ($changes{'canuse_pdfforms'}) { 6108: my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); 6109: $domdefaults{'canuse_pdfforms'}=$defaultshash{'coursedefaults'}{'canuse_pdfforms'}; 6110: my $cachetime = 24*60*60; 6111: &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); 6112: } 6113: $resulttext = &mt('Changes made:').'<ul>'; 6114: foreach my $item (sort(keys(%changes))) { 6115: if ($item eq 'canuse_pdfforms') { 6116: if ($env{'form.'.$item} eq '1') { 6117: $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>'; 6118: } else { 6119: $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>'; 6120: } 6121: } 6122: } 6123: $resulttext .= '</ul>'; 6124: } else { 6125: $resulttext = &mt('No changes made to course defaults'); 6126: } 6127: } else { 6128: $resulttext = '<span class="LC_error">'. 6129: &mt('An error occurred: [_1]',$putresult).'</span>'; 6130: } 6131: return $resulttext; 6132: } 6133: 6134: sub recurse_check { 6135: my ($chkcats,$categories,$depth,$name) = @_; 6136: if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') { 6137: my $chg = 0; 6138: for (my $j=0; $j<@{$chkcats->[$depth]{$name}}; $j++) { 6139: my $category = $chkcats->[$depth]{$name}[$j]; 6140: my $item; 6141: if ($category eq '') { 6142: $chg ++; 6143: } else { 6144: my $deeper = $depth + 1; 6145: $item = &escape($category).':'.&escape($name).':'.$depth; 6146: if ($chg) { 6147: $categories->{$item} -= $chg; 6148: } 6149: &recurse_check($chkcats,$categories,$deeper,$category); 6150: $deeper --; 6151: } 6152: } 6153: } 6154: return; 6155: } 6156: 6157: sub recurse_cat_deletes { 6158: my ($item,$coursecategories,$deletions) = @_; 6159: my ($deleted,$container,$depth) = map { &unescape($_); } split(/:/,$item); 6160: my $subdepth = $depth + 1; 6161: if (ref($coursecategories) eq 'HASH') { 6162: foreach my $subitem (keys(%{$coursecategories})) { 6163: my ($child,$parent,$itemdepth) = map { &unescape($_); } split(/:/,$subitem); 6164: if (($parent eq $deleted) && ($itemdepth == $subdepth)) { 6165: delete($coursecategories->{$subitem}); 6166: $deletions->{$subitem} = 1; 6167: &recurse_cat_deletes($subitem,$coursecategories,$deletions); 6168: } 6169: } 6170: } 6171: return; 6172: } 6173: 6174: sub dom_servers { 6175: my ($dom) = @_; 6176: my (%uniqservers,%servers); 6177: my $primaryserver = &Apache::lonnet::hostname(&Apache::lonnet::domain($dom,'primary')); 6178: my @machinedoms = &Apache::lonnet::machine_domains($primaryserver); 6179: foreach my $mdom (@machinedoms) { 6180: my %currservers = %servers; 6181: my %server = &Apache::lonnet::get_servers($mdom); 6182: %servers = (%currservers,%server); 6183: } 6184: my %by_hostname; 6185: foreach my $id (keys(%servers)) { 6186: push(@{$by_hostname{$servers{$id}}},$id); 6187: } 6188: foreach my $hostname (sort(keys(%by_hostname))) { 6189: if (@{$by_hostname{$hostname}} > 1) { 6190: my $match = 0; 6191: foreach my $id (@{$by_hostname{$hostname}}) { 6192: if (&Apache::lonnet::host_domain($id) eq $dom) { 6193: $uniqservers{$id} = $hostname; 6194: $match = 1; 6195: } 6196: } 6197: unless ($match) { 6198: $uniqservers{$by_hostname{$hostname}[0]} = $hostname; 6199: } 6200: } else { 6201: $uniqservers{$by_hostname{$hostname}[0]} = $hostname; 6202: } 6203: } 6204: return %uniqservers; 6205: } 6206: 6207: 1;