--- loncom/interface/domainprefs.pm 2007/12/11 00:44:23 1.33 +++ loncom/interface/domainprefs.pm 2018/07/06 04:03:31 1.328 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.33 2007/12/11 00:44:23 raeburn Exp $ +# $Id: domainprefs.pm,v 1.328 2018/07/06 04:03:31 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -19,14 +19,141 @@ # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA# +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # # ############################################################### -############################################################## +############################################################### + +=pod + +=head1 NAME + +Apache::domainprefs.pm + +=head1 SYNOPSIS + +Handles configuration of a LON-CAPA domain. + +This is part of the LearningOnline Network with CAPA project +described at http://www.lon-capa.org. + + +=head1 OVERVIEW + +Each institution using LON-CAPA will typically have a single domain designated +for use by individuals affiliated with the institution. Accordingly, each domain +may define a default set of logos and a color scheme which can be used to "brand" +the LON-CAPA instance. In addition, an institution will typically have a language +and timezone which are used for the majority of courses. + +LON-CAPA provides a mechanism to display and modify these defaults, as well as a +host of other domain-wide settings which determine the types of functionality +available to users and courses in the domain. + +There is also a mechanism to configure cataloging of courses in the domain, and +controls on the operation of automated processes which govern such things as +roster updates, user directory updates and processing of course requests. + +The domain coordination manual which is built dynamically on install/update of +LON-CAPA from the relevant help items provides more information about domain +configuration. + +Most of the domain settings are stored in the configuration.db GDBM file which is +housed on the primary library server for the domain in /home/httpd/lonUsers/$dom, +where $dom is the domain. The configuration.db stores settings in a number of +frozen hashes of hashes. In a few cases, domain information must be uploaded to +the domain as files (e.g., image files for logos etc., or plain text files for +bubblesheet formats). In this case the domainprefs.pm must be running in a user +session hosted on the primary library server in the domain, as these files are +stored in author space belonging to a special $dom-domainconfig user. + +domainprefs.pm in combination with lonconfigsettings.pm will retrieve and display +the current settings, and provides an interface to make modifications. + +=head1 SUBROUTINES + +=over + +=item print_quotas() + +Inputs: 4 + +$dom,$settings,$rowtotal,$action. + +$dom is the domain, $settings is a reference to a hash of current settings for +the current context, $rowtotal is a reference to the scalar used to record the +number of rows displayed on the page, and $action is the context (quotas, +requestcourses or requestauthor). + +The print_quotas routine was orginally created to display/store information +about default quota sizes for portfolio spaces for the different types of +institutional affiliation in the domain (e.g., Faculty, Staff, Student etc.), +but is now also used to manage availability of user tools: +i.e., blogs, aboutme page, and portfolios, and the course request tool, +used by course owners to request creation of a course, and to display/store +default quota sizes for Authoring Spaces. + +Outputs: 1 + +$datatable - HTML containing form elements which allow settings to be changed. + +In the case of course requests, radio buttons are displayed for each institutional +affiliate type (and also default, and _LC_adv) for each of the course types +(official, unofficial, community, textbook, placement, and lti). +In each case the radio buttons allow the selection of one of four values: + +0, approval, validate, autolimit=N (where N is blank, or a positive integer). +which have the following effects: + +0 + +=over + +- course requests are not allowed for this course types/affiliation + +=back + +approval + +=over + +- course requests must be approved by a Doman Coordinator in the +course's domain + +=back + +validate + +=over + +- an institutional validation (e.g., check requestor is instructor +of record) needs to be passed before the course will be created. The required +validation is in localenroll.pm on the primary library server for the course +domain. + +=back + +autolimit + +=over + +- course requests will be processed automatically up to a limit of +N requests for the course type for the particular requestor. +If N is undefined, there is no limit to the number of course requests +which a course owner may submit and have processed automatically. + +=back + +=item modify_quotas() + +=back + +=cut package Apache::domainprefs; @@ -36,9 +163,22 @@ use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::lonlocal; -use LONCAPA(); +use Apache::lonmsg(); +use Apache::lonconfigsettings; +use Apache::lonuserutils(); +use Apache::loncoursequeueadmin(); +use LONCAPA qw(:DEFAULT :match); use LONCAPA::Enrollment; +use LONCAPA::lonauthcgi(); +use LONCAPA::SSL; use File::Copy; +use Locale::Language; +use DateTime::TimeZone; +use DateTime::Locale; +use Time::HiRes qw( sleep ); + +my $registered_cleanup; +my $modified_urls; sub handler { my $r=shift; @@ -48,6 +188,7 @@ sub handler { return OK; } + my $context = 'domain'; my $dom = $env{'request.role.domain'}; my $domdesc = &Apache::lonnet::domain($dom,'description'); if (&Apache::lonnet::allowed('mau',$dom)) { @@ -58,24 +199,70 @@ sub handler { "/adm/domainprefs:mau:0:0:Cannot modify domain settings"; return HTTP_NOT_ACCEPTABLE; } + + $registered_cleanup=0; + @{$modified_urls}=(); + &Apache::lonhtmlcommon::clear_breadcrumbs(); &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, - ['phase']); + ['phase','actions']); my $phase = 'pickactions'; if ( exists($env{'form.phase'}) ) { $phase = $env{'form.phase'}; } + my %servers = &Apache::lonnet::internet_dom_servers($dom); my %domconfig = &Apache::lonnet::get_dom('configuration',['login','rolecolors', - 'quotas','autoenroll','autoupdate','directorysrch', - 'usercreation','usermodification','contacts'],$dom); - my @prefs_order = ('rolecolors','login','quotas','autoenroll', - 'autoupdate','directorysrch','contacts', - 'usercreation','usermodification'); + 'quotas','autoenroll','autoupdate','autocreate', + 'directorysrch','usercreation','usermodification', + 'contacts','defaults','scantron','coursecategories', + 'serverstatuses','requestcourses','helpsettings', + 'coursedefaults','usersessions','loadbalancing', + 'requestauthor','selfenrollment','inststatus', + 'ltitools','ssl','trust','lti'],$dom); + my %encconfig = + &Apache::lonnet::get_dom('encconfig',['ltitools','lti'],$dom); + if (ref($domconfig{'ltitools'}) eq 'HASH') { + if (ref($encconfig{'ltitools'}) eq 'HASH') { + foreach my $id (keys(%{$domconfig{'ltitools'}})) { + if ((ref($domconfig{'ltitools'}{$id}) eq 'HASH') && + (ref($encconfig{'ltitools'}{$id}) eq 'HASH')) { + foreach my $item ('key','secret') { + $domconfig{'ltitools'}{$id}{$item} = $encconfig{'ltitools'}{$id}{$item}; + } + } + } + } + } + if (ref($domconfig{'lti'}) eq 'HASH') { + if (ref($encconfig{'lti'}) eq 'HASH') { + foreach my $id (keys(%{$domconfig{'lti'}})) { + if ((ref($domconfig{'lti'}{$id}) eq 'HASH') && + (ref($encconfig{'lti'}{$id}) eq 'HASH')) { + foreach my $item ('key','secret') { + $domconfig{'lti'}{$id}{$item} = $encconfig{'lti'}{$id}{$item}; + } + } + } + } + } + my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll', + 'autoupdate','autocreate','directorysrch','contacts', + 'usercreation','selfcreation','usermodification','scantron', + 'requestcourses','requestauthor','coursecategories', + 'serverstatuses','helpsettings','coursedefaults', + 'ltitools','selfenrollment','usersessions','ssl','trust','lti'); + my %existing; + if (ref($domconfig{'loadbalancing'}) eq 'HASH') { + %existing = %{$domconfig{'loadbalancing'}}; + } + if ((keys(%servers) > 1) || (keys(%existing) > 0)) { + push(@prefs_order,'loadbalancing'); + } my %prefs = ( 'rolecolors' => { text => 'Default color schemes', - help => 'Default_Color_Schemes', + help => 'Domain_Configuration_Color_Schemes', header => [{col1 => 'Student Settings', col2 => '',}, {col1 => 'Coordinator Settings', @@ -84,168 +271,396 @@ sub handler { col2 => '',}, {col1 => 'Administrator Settings', col2 => '',}], + print => \&print_rolecolors, + modify => \&modify_rolecolors, }, - 'login' => + 'login' => { text => 'Log-in page options', - help => 'Domain_Log-in_Page', - header => [{col1 => 'Item', - col2 => '',}], + help => 'Domain_Configuration_Login_Page', + header => [{col1 => 'Log-in Page Items', + col2 => '',}, + {col1 => 'Log-in Help', + col2 => 'Value'}, + {col1 => 'Custom HTML in document head', + col2 => 'Value'}], + print => \&print_login, + modify => \&modify_login, + }, + 'defaults' => + { text => 'Default authentication/language/timezone/portal/types', + help => 'Domain_Configuration_LangTZAuth', + header => [{col1 => 'Setting', + col2 => 'Value'}, + {col1 => 'Internal Authentication', + col2 => 'Value'}, + {col1 => 'Institutional user types', + col2 => 'Name displayed'}], + print => \&print_defaults, + modify => \&modify_defaults, }, 'quotas' => - { text => 'Default quotas for user portfolios', - help => 'Default_User_Quota', - header => [{col1 => 'User type', - col2 => 'Default quota'}], + { text => 'Blogs, personal web pages, webDAV/quotas, portfolios', + help => 'Domain_Configuration_Quotas', + header => [{col1 => 'User affiliation', + col2 => 'Available tools', + col3 => 'Quotas, MB; (Authoring requires role)',}], + print => \&print_quotas, + modify => \&modify_quotas, }, 'autoenroll' => { text => 'Auto-enrollment settings', - help => 'Domain_Auto_Enrollment', + help => 'Domain_Configuration_Auto_Enrollment', header => [{col1 => 'Configuration setting', col2 => 'Value(s)'}], + print => \&print_autoenroll, + modify => \&modify_autoenroll, }, 'autoupdate' => { text => 'Auto-update settings', - help => 'Domain_Auto_Update', + help => 'Domain_Configuration_Auto_Updates', header => [{col1 => 'Setting', col2 => 'Value',}, - {col1 => 'User Population', - col2 => 'Updataeable user data'}], + {col1 => 'Setting', + col2 => 'Affiliation'}, + {col1 => 'User population', + col2 => 'Updatable user data'}], + print => \&print_autoupdate, + modify => \&modify_autoupdate, + }, + 'autocreate' => + { text => 'Auto-course creation settings', + help => 'Domain_Configuration_Auto_Creation', + header => [{col1 => 'Configuration Setting', + col2 => 'Value',}], + print => \&print_autocreate, + modify => \&modify_autocreate, }, 'directorysrch' => - { text => 'Institutional directory searches', - help => 'Domain_Directory_Search', - header => [{col1 => 'Setting', + { text => 'Directory searches', + help => 'Domain_Configuration_InstDirectory_Search', + header => [{col1 => 'Institutional Directory Setting', + col2 => 'Value',}, + {col1 => 'LON-CAPA Directory Setting', col2 => 'Value',}], + print => \&print_directorysrch, + modify => \&modify_directorysrch, }, 'contacts' => - { text => 'Contact Information', - help => 'Domain_Contact_Information', - header => [{col1 => 'Setting', - col2 => 'Value',}], + { text => 'E-mail addresses and helpform', + help => 'Domain_Configuration_Contact_Info', + header => [{col1 => 'Default e-mail addresses', + col2 => 'Value',}, + {col1 => 'Recipient(s) for notifications', + col2 => 'Value',}, + {col1 => 'Ask helpdesk form settings', + col2 => 'Value',},], + print => \&print_contacts, + modify => \&modify_contacts, }, - 'usercreation' => { text => 'User creation', - help => 'Domain_User_Creation', - header => [{col1 => 'Setting', - col2 => 'Value',}, + help => 'Domain_Configuration_User_Creation', + header => [{col1 => 'Format rule type', + col2 => 'Format rules in force'}, + {col1 => 'User account creation', + col2 => 'Usernames which may be created',}, {col1 => 'Context', - col2 => 'Assignable Authentication Types'}], + col2 => 'Assignable authentication types'}], + print => \&print_usercreation, + modify => \&modify_usercreation, + }, + 'selfcreation' => + { text => 'Users self-creating accounts', + help => 'Domain_Configuration_Self_Creation', + header => [{col1 => 'Self-creation with institutional username', + col2 => 'Enabled?'}, + {col1 => 'Institutional user type (login/SSO self-creation)', + col2 => 'Information user can enter'}, + {col1 => 'Self-creation with e-mail verification', + col2 => 'Settings'}], + print => \&print_selfcreation, + modify => \&modify_selfcreation, }, - 'usermodification' => + 'usermodification' => { text => 'User modification', - help => 'Domain_User_Modification', + help => 'Domain_Configuration_User_Modification', header => [{col1 => 'Target user has role', - col2 => 'User information updateable in author context'}, + col2 => 'User information updatable in author context'}, {col1 => 'Target user has role', - col2 => 'User information updateable in course context'}], + col2 => 'User information updatable in course context'}], + print => \&print_usermodification, + modify => \&modify_usermodification, }, + 'scantron' => + { text => 'Bubblesheet format file', + help => 'Domain_Configuration_Scantron_Format', + header => [ {col1 => 'Item', + col2 => '', + }], + print => \&print_scantron, + modify => \&modify_scantron, + }, + 'requestcourses' => + {text => 'Request creation of courses', + help => 'Domain_Configuration_Request_Courses', + header => [{col1 => 'User affiliation', + col2 => 'Availability/Processing of requests',}, + {col1 => 'Setting', + col2 => 'Value'}, + {col1 => 'Available textbooks', + col2 => ''}, + {col1 => 'Available templates', + col2 => ''}, + {col1 => 'Validation (not official courses)', + col2 => 'Value'},], + print => \&print_quotas, + modify => \&modify_quotas, + }, + 'requestauthor' => + {text => 'Request Authoring Space', + help => 'Domain_Configuration_Request_Author', + header => [{col1 => 'User affiliation', + col2 => 'Availability/Processing of requests',}, + {col1 => 'Setting', + col2 => 'Value'}], + print => \&print_quotas, + modify => \&modify_quotas, + }, + 'coursecategories' => + { text => 'Cataloging of courses/communities', + help => 'Domain_Configuration_Cataloging_Courses', + header => [{col1 => 'Catalog type/availability', + col2 => '',}, + {col1 => 'Category settings for standard catalog', + col2 => '',}, + {col1 => 'Categories', + col2 => '', + }], + print => \&print_coursecategories, + modify => \&modify_coursecategories, + }, + 'serverstatuses' => + {text => 'Access to server status pages', + help => 'Domain_Configuration_Server_Status', + header => [{col1 => 'Status Page', + col2 => 'Other named users', + col3 => 'Specific IPs', + }], + print => \&print_serverstatuses, + modify => \&modify_serverstatuses, + }, + 'helpsettings' => + {text => 'Support settings', + help => 'Domain_Configuration_Help_Settings', + header => [{col1 => 'Help Page Settings (logged-in users)', + col2 => 'Value'}, + {col1 => 'Helpdesk Roles', + col2 => 'Settings'},], + print => \&print_helpsettings, + modify => \&modify_helpsettings, + }, + 'coursedefaults' => + {text => 'Course/Community defaults', + help => 'Domain_Configuration_Course_Defaults', + header => [{col1 => 'Defaults which can be overridden in each course by a CC', + col2 => 'Value',}, + {col1 => 'Defaults which can be overridden for each course by a DC', + col2 => 'Value',},], + print => \&print_coursedefaults, + modify => \&modify_coursedefaults, + }, + 'selfenrollment' => + {text => 'Self-enrollment in Course/Community', + help => 'Domain_Configuration_Selfenrollment', + header => [{col1 => 'Configuration Rights', + col2 => 'Configured by Course Personnel or Domain Coordinator?'}, + {col1 => 'Defaults', + col2 => 'Value'}, + {col1 => 'Self-enrollment validation (optional)', + col2 => 'Value'},], + print => \&print_selfenrollment, + modify => \&modify_selfenrollment, + }, + 'privacy' => + {text => 'User Privacy', + help => 'Domain_Configuration_User_Privacy', + header => [{col1 => 'Setting', + col2 => 'Value',}], + print => \&print_privacy, + modify => \&modify_privacy, + }, + 'usersessions' => + {text => 'User session hosting/offloading', + help => 'Domain_Configuration_User_Sessions', + header => [{col1 => 'Domain server', + col2 => 'Servers to offload sessions to when busy'}, + {col1 => 'Hosting of users from other domains', + col2 => 'Rules'}, + {col1 => "Hosting domain's own users elsewhere", + col2 => 'Rules'}], + print => \&print_usersessions, + modify => \&modify_usersessions, + }, + 'loadbalancing' => + {text => 'Dedicated Load Balancer(s)', + help => 'Domain_Configuration_Load_Balancing', + header => [{col1 => 'Balancers', + col2 => 'Default destinations', + col3 => 'User affiliation', + col4 => 'Overrides'}, + ], + print => \&print_loadbalancing, + modify => \&modify_loadbalancing, + }, + 'ltitools' => + {text => 'External Tools (LTI)', + help => 'Domain_Configuration_LTI_Tools', + header => [{col1 => 'Setting', + col2 => 'Value',}], + print => \&print_ltitools, + modify => \&modify_ltitools, + }, + 'ssl' => + {text => 'LON-CAPA Network (SSL)', + help => 'Domain_Configuration_Network_SSL', + header => [{col1 => 'Server', + col2 => 'Certificate Status'}, + {col1 => 'Connections to other servers', + col2 => 'Rules'}, + {col1 => 'Connections from other servers', + col2 => 'Rules'}, + {col1 => "Replicating domain's published content", + col2 => 'Rules'}], + print => \&print_ssl, + modify => \&modify_ssl, + }, + 'trust' => + {text => 'Trust Settings', + help => 'Domain_Configuration_Trust', + header => [{col1 => "Access to this domain's content by others", + col2 => 'Rules'}, + {col1 => "Access to other domain's content by this domain", + col2 => 'Rules'}, + {col1 => "Enrollment in this domain's courses by others", + col2 => 'Rules',}, + {col1 => "Co-author roles in this domain for others", + col2 => 'Rules',}, + {col1 => "Co-author roles for this domain's users elsewhere", + col2 => 'Rules',}, + {col1 => "Domain roles in this domain assignable to others", + col2 => 'Rules'}, + {col1 => "Course catalog for this domain displayed elsewhere", + col2 => 'Rules'}, + {col1 => "Requests for creation of courses in this domain by others", + col2 => 'Rules'}, + {col1 => "Users in other domains can send messages to this domain", + col2 => 'Rules'},], + print => \&print_trust, + modify => \&modify_trust, + }, + 'lti' => + {text => 'LTI Provider', + help => 'Domain_Configuration_LTI_Provider', + header => [{col1 => 'Setting', + col2 => 'Value',}], + print => \&print_lti, + modify => \&modify_lti, + }, ); + if (keys(%servers) > 1) { + $prefs{'login'} = { text => 'Log-in page options', + help => 'Domain_Configuration_Login_Page', + header => [{col1 => 'Log-in Service', + col2 => 'Server Setting',}, + {col1 => 'Log-in Page Items', + col2 => ''}, + {col1 => 'Log-in Help', + col2 => 'Value'}, + {col1 => 'Custom HTML in document head', + col2 => 'Value'}], + print => \&print_login, + modify => \&modify_login, + }; + } + my @roles = ('student','coordinator','author','admin'); my @actions = &Apache::loncommon::get_env_multiple('form.actions'); &Apache::lonhtmlcommon::add_breadcrumb ({href=>"javascript:changePage(document.$phase,'pickactions')", - text=>"Pick functionality"}); + text=>"Settings to display/modify"}); my $confname = $dom.'-domainconfig'; + if ($phase eq 'process') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:changePage(document.$phase,'display')", - text=>"Domain Configuration"}, - {href=>"javascript:changePage(document.$phase,'$phase')", - text=>"Updated"}); - &print_header($r,$phase); - foreach my $item (@prefs_order) { - if (grep(/^\Q$item\E$/,@actions)) { - $r->print('
'); - &print_footer($r,$phase,'display','Back to configuration display', - \@actions); - $r->print('
'); + my $result = &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order, + \%prefs,\%domconfig,$confname,\@roles); + if ((ref($result) eq 'HASH') && (keys(%{$result}))) { + $r->rflush(); + &devalidate_remote_domconfs($dom,$result); + } } elsif ($phase eq 'display') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:changePage(document.$phase,'display')", - text=>"Domain Configuration"}); - &print_header($r,$phase); - if (@actions > 0) { - my $rowsum = 0; - my (%output,%rowtotal,@items); - my $halfway = @actions/2; - foreach my $item (@prefs_order) { - if (grep(/^\Q$item\E$/,@actions)) { - push(@items,$item); - ($output{$item},$rowtotal{$item}) = - &print_config_box($r,$dom,$confname,$phase, - $item,$prefs{$item}, - $domconfig{$item}); - $rowsum += $rowtotal{$item}; - } - } - my $colend; - my $halfway = $rowsum/2; - my $aggregate = 0; - my $sumleft = 0; - my $sumright = 0; - my $crossover; - for (my $i=0; $i<@items; $i++) { - $aggregate += $rowtotal{$items[$i]}; - if ($aggregate > $halfway) { - $crossover = $i; - last; - } - } - for (my $i=0; $i<$crossover; $i++) { - $sumleft += $rowtotal{$items[$i]}; - } - for (my $i=$crossover+1; $i<@items; $i++) { - $sumright += $rowtotal{$items[$i]}; - } - if ((@items > 1) && ($env{'form.numcols'} == 2)) { - my $sumdiff = $sumright - $sumleft; - if ($sumdiff > 0) { - $colend = $crossover + 1; - } else { - $colend = $crossover; - } - } else { - $colend = @items; - } - $r->print(''); - for (my $i=0; $i<$colend; $i++) { - $r->print($output{$items[$i]}); - } - $r->print(' | '); - if ($colend < @items) { - for (my $i=$colend; $i<@items; $i++) { - $r->print($output{$items[$i]}); - } - } - $r->print(' |
'. - '
'); - foreach my $item (@prefs_order) { - $r->print(''); - } - $r->print(''.&mt('Display using: ')."\n". - ' '. - ''. - &mt('two columns').'
'); - $r->print(&print_footer($r,$phase,'display','Go')); - $r->print(''); - $r->print(&Apache::loncommon::end_page()); + &Apache::lonconfigsettings::display_choices($r,$phase,$context,\@prefs_order,\%prefs); } return OK; } sub process_changes { - my ($r,$dom,$confname,$action,$roles,%domconfig) = @_; + my ($r,$dom,$confname,$action,$roles,$values,$lastactref) = @_; + my %domconfig; + if (ref($values) eq 'HASH') { + %domconfig = %{$values}; + } my $output; if ($action eq 'login') { - $output = &modify_login($r,$dom,$confname,%domconfig); + $output = &modify_login($r,$dom,$confname,$lastactref,%domconfig); } elsif ($action eq 'rolecolors') { $output = &modify_rolecolors($r,$dom,$confname,$roles, - %domconfig); + $lastactref,%domconfig); } elsif ($action eq 'quotas') { - $output = &modify_quotas($dom,%domconfig); + $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); } elsif ($action eq 'autoenroll') { - $output = &modify_autoenroll($dom,%domconfig); + $output = &modify_autoenroll($dom,$lastactref,%domconfig); } elsif ($action eq 'autoupdate') { $output = &modify_autoupdate($dom,%domconfig); + } elsif ($action eq 'autocreate') { + $output = &modify_autocreate($dom,%domconfig); } elsif ($action eq 'directorysrch') { - $output = &modify_directorysrch($dom,%domconfig); + $output = &modify_directorysrch($dom,$lastactref,%domconfig); } elsif ($action eq 'usercreation') { $output = &modify_usercreation($dom,%domconfig); + } elsif ($action eq 'selfcreation') { + $output = &modify_selfcreation($dom,$lastactref,%domconfig); } elsif ($action eq 'usermodification') { $output = &modify_usermodification($dom,%domconfig); } elsif ($action eq 'contacts') { - $output = &modify_contacts($dom,%domconfig); + $output = &modify_contacts($dom,$lastactref,%domconfig); + } elsif ($action eq 'defaults') { + $output = &modify_defaults($dom,$lastactref,%domconfig); + } elsif ($action eq 'scantron') { + $output = &modify_scantron($r,$dom,$confname,$lastactref,%domconfig); + } elsif ($action eq 'coursecategories') { + $output = &modify_coursecategories($dom,$lastactref,%domconfig); + } elsif ($action eq 'serverstatuses') { + $output = &modify_serverstatuses($dom,%domconfig); + } elsif ($action eq 'requestcourses') { + $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); + } elsif ($action eq 'requestauthor') { + $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); + } elsif ($action eq 'helpsettings') { + $output = &modify_helpsettings($r,$dom,$confname,$lastactref,%domconfig); + } elsif ($action eq 'coursedefaults') { + $output = &modify_coursedefaults($dom,$lastactref,%domconfig); + } elsif ($action eq 'selfenrollment') { + $output = &modify_selfenrollment($dom,$lastactref,%domconfig) + } elsif ($action eq 'usersessions') { + $output = &modify_usersessions($dom,$lastactref,%domconfig); + } elsif ($action eq 'loadbalancing') { + $output = &modify_loadbalancing($dom,%domconfig); + } elsif ($action eq 'ltitools') { + $output = &modify_ltitools($r,$dom,$action,$lastactref,%domconfig); + } elsif ($action eq 'ssl') { + $output = &modify_ssl($dom,$lastactref,%domconfig); + } elsif ($action eq 'trust') { + $output = &modify_trust($dom,$lastactref,%domconfig); + } elsif ($action eq 'lti') { + $output = &modify_lti($r,$dom,$action,$lastactref,%domconfig); } return $output; } @@ -325,36 +760,78 @@ sub process_changes { sub print_config_box { my ($r,$dom,$confname,$phase,$action,$item,$settings) = @_; my $rowtotal = 0; - my $output = + my $output; + if ($action eq 'coursecategories') { + $output = &coursecategories_javascript($settings); + } elsif ($action eq 'defaults') { + $output = &defaults_javascript($settings); + } elsif ($action eq 'helpsettings') { + my (%privs,%levelscurrent); + my %full=(); + my %levels=( + course => {}, + domain => {}, + system => {}, + ); + my $context = 'domain'; + my $crstype = 'Course'; + my $formname = 'display'; + &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent); + my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); + $output = + &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, + \@templateroles); + } + $output .= ''.&mt($item->{text}). - ' | '.&mt($item->{text}).' '. -# &Apache::loncommon::help_open_topic($item->{'help'}).' | -# '); +'. + &mt($item->{text}).' '. + &Apache::loncommon::help_open_topic($item->{'help'}).' | '."\n". + ''; $rowtotal ++; - if (($action eq 'autoupdate') || ($action eq 'rolecolors') || - ($action eq 'usercreation') || ($action eq 'usermodification')) { - my $colspan = ($action eq 'rolecolors')?' colspan="2"':''; + my $numheaders = 1; + if (ref($item->{'header'}) eq 'ARRAY') { + $numheaders = scalar(@{$item->{'header'}}); + } + if ($numheaders > 1) { + my $colspan = ''; + my $rightcolspan = ''; + if (($action eq 'rolecolors') || ($action eq 'defaults') || + ($action eq 'directorysrch') || + (($action eq 'login') && ($numheaders < 4))) { + $colspan = ' colspan="2"'; + } + if ($action eq 'usersessions') { + $rightcolspan = ' colspan="3"'; + } $output .= '||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'.$choices->{'font'}.' | '; @@ -750,20 +1600,47 @@ sub display_color_options { } else { $datatable .= ''; } - my $fontlink = &color_pick($phase,$role,'font',$choices->{'font'},$designs->{'font'}); + my $current_color = $designs->{'font'} ? $designs->{'font'} : $defaults->{'font'}; + $datatable .= ' | '. - ' '.$fontlink. - ' '. - ' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'.$choices->{'fontmenu'}.' | '; + if (!$is_custom->{'fontmenu'}) { + $datatable .= ''.&mt('Default in use:').' '.$defaults->{'fontmenu'}.' | '; + } else { + $datatable .= ''; + } + $current_color = $designs->{'fontmenu'} ? + $designs->{'fontmenu'} : $defaults->{'fontmenu'}; + $datatable .= ' | '. + ' '. + ' | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'.$choices->{$img}.' | '; - my ($imgfile, $img_import); + ''.$choices->{$img}; + my ($imgfile,$img_import,$login_hdr_pick,$logincolors); + if ($role eq 'login') { + if ($img eq 'login') { + $login_hdr_pick = + &login_header_options($img,$role,$defaults,$is_custom,$choices); + $logincolors = + &login_text_colors($img,$role,$logintext,$phase,$choices, + $designs,$defaults); + } elsif ($img ne 'domlogo') { + $datatable.= &logo_display_options($img,$defaults,$designs); + } + } + $datatable .= ' | '; if ($designs->{$img} ne '') { $imgfile = $designs->{$img}; $img_import = ($imgfile =~ m{^/adm/}); @@ -791,56 +1668,66 @@ sub display_color_options { $showfile = $imgfile; my $imgdir = $1; my $filename = $2; - if (-e "/home/httpd/html/$imgdir/tn-".$filename) { + if (-e "$londocroot/$imgdir/tn-".$filename) { $showfile = "/$imgdir/tn-".$filename; } else { - my $input = "/home/httpd/html".$imgfile; - my $output = '/home/httpd/html/'.$imgdir.'/tn-'.$filename; + my $input = $londocroot.$imgfile; + my $output = "$londocroot/$imgdir/tn-".$filename; if (!-e $output) { my ($width,$height) = &thumb_dimensions(); my ($fullwidth,$fullheight) = &check_dimensions($input); if ($fullwidth ne '' && $fullheight ne '') { if ($fullwidth > $width && $fullheight > $height) { my $size = $width.'x'.$height; - system("convert -sample $size $input $output"); - $showfile = '/'.$imgdir.'/tn-'.$filename; + my @args = ('convert','-sample',$size,$input,$output); + system({$args[0]} @args); + $showfile = "/$imgdir/tn-".$filename; } } } } } if ($showfile) { - $showfile = &Apache::loncommon::lonhttpdurl($showfile); - $fullsize = &Apache::loncommon::lonhttpdurl($imgfile); - $datatable.= '';
- if (!$is_custom->{$img}) {
- $datatable .= &mt('Default in use:').' '; - } - if ($img_import) { - $datatable.= ''; - } - $datatable.= ' | ';
- if ($is_custom->{$img}) {
- $datatable.=' '.&mt('Replace:').' '; - } else { - $datatable.=' | '.&mt('Upload:').' '; + if ($showfile =~ m{^/(adm|res)/}) { + if ($showfile =~ m{^/res/}) { + my $local_showfile = + &Apache::lonnet::filelocation('',$showfile); + &Apache::lonnet::repcopy($local_showfile); + } + $showfile = &Apache::loncommon::lonhttpdurl($showfile); } + if ($imgfile) { + if ($imgfile =~ m{^/(adm|res)/}) { + if ($imgfile =~ m{^/res/}) { + my $local_imgfile = + &Apache::lonnet::filelocation('',$imgfile); + &Apache::lonnet::repcopy($local_imgfile); + } + $fullsize = &Apache::loncommon::lonhttpdurl($imgfile); + } else { + $fullsize = $imgfile; + } + } + $datatable .= ' | '; + if ($img eq 'login') { + $datatable .= $login_hdr_pick; + } + $datatable .= &image_changes($is_custom->{$img},$alt_text->{$img},$img_import, + $showfile,$fullsize,$role,$img,$imgfile,$logincolors); } else { - $datatable .= ' | '. - &mt('Upload:'); + $datatable .= ' | '.
+ &mt('Upload:').' '; } } else { - $datatable .= ' | '. - &mt('Upload:'); + $datatable .= ' | '.
+ &mt('Upload:').' '; } if ($switchserver) { $datatable .= &mt('Upload to library server: [_1]',$switchserver); } else { - $datatable .=' '; + if ($img ne 'login') { # suppress file selection for Log-in header + $datatable .=' '; + } } $datatable .= ' | '.$choices->{$item}.' '.$defaults->{'bgs'}{$item}.' | ';
+ $bgs_def .= ''.$choices->{$item}.' '.$defaults->{'bgs'}{$item}.' | ';
}
}
if ($bgs_def) {
@@ -861,14 +1748,15 @@ sub display_color_options {
}
$datatable .= ''.
'
| ';
$itemcount ++;
@@ -889,95 +1777,1180 @@ sub display_color_options {
$datatable .= ''.
'
'; + return $color_menu; +} - function psub() { - pclose(); - if (document.parmform.pres_marker.value!='') { - if (document.parmform.pres_type.value!='') { - eval('document.display.'+ - document.parmform.pres_marker.value+ - '.value=document.parmform.pres_value.value;'); - } +sub image_changes { + my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_; + my $output; + if ($img eq 'login') { + # suppress image for Log-in header + } elsif (!$is_custom) { + if ($img ne 'domlogo') { + $output .= &mt('Default image:').' '; } else { - document.parmform.pres_value.value=''; - document.parmform.pres_marker.value=''; + $output .= &mt('Default in use:').' '; + } + } + if ($img eq 'login') { # suppress image for Log-in header + $output .= ' '.$logincolors;
+ } else {
+ if ($img_import) {
+ $output .= '';
+ }
+ $output .= ' | ';
+ if ($is_custom) {
+ $output .= ''.$logincolors.' '.&mt('Replace:').' | '; + } else { + $output .= ' '.$logincolors.&mt('Upload:').' | '; } } -ENDCOL return $output; } sub print_quotas { - my ($dom,$settings,$rowtotal) = @_; - my $datatable; - my ($othertitle,$usertypes,$types) = &sorted_inst_types($dom); + my ($dom,$settings,$rowtotal,$action) = @_; + my $context; + if ($action eq 'quotas') { + $context = 'tools'; + } else { + $context = $action; + } + my ($datatable,$defaultquota,$authorquota,@usertools,@options,%validations); + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); my $typecount = 0; - my $css_class; + my ($css_class,%titles); + if ($context eq 'requestcourses') { + @usertools = ('official','unofficial','community','textbook','placement','lti'); + @options =('norequest','approval','validate','autolimit'); + %validations = &Apache::lonnet::auto_courserequest_checks($dom); + %titles = &courserequest_titles(); + } elsif ($context eq 'requestauthor') { + @usertools = ('author'); + @options = ('norequest','approval','automatic'); + %titles = &authorrequest_titles(); + } else { + @usertools = ('aboutme','blog','webdav','portfolio'); + %titles = &tool_titles(); + } if (ref($types) eq 'ARRAY') { foreach my $type (@{$types}) { + my ($currdefquota,$currauthorquota); + unless (($context eq 'requestcourses') || + ($context eq 'requestauthor')) { + if (ref($settings) eq 'HASH') { + if (ref($settings->{defaultquota}) eq 'HASH') { + $currdefquota = $settings->{defaultquota}->{$type}; + } else { + $currdefquota = $settings->{$type}; + } + if (ref($settings->{authorquota}) eq 'HASH') { + $currauthorquota = $settings->{authorquota}->{$type}; + } + } + } if (defined($usertypes->{$type})) { $typecount ++; $css_class = $typecount%2?' class="LC_odd_row"':''; - $datatable .= ' '.$usertypes->{$type}.' | '.
- ''.
+ ' | ';
+ if ($context eq 'requestcourses') {
+ $datatable .= ' | ';
+ unless (($context eq 'requestcourses') ||
+ ($context eq 'requestauthor')) {
+ $datatable .=
+ '
'.
+ ''.&mt('Portfolio').': '.
' Mb | '.$othertitle.' | '.
- ''.
- ' Mb | ';
+ if ($context eq 'requestcourses') {
+ $datatable .= ' | ';
+ unless (($context eq 'requestcourses') || ($context eq 'requestauthor')) {
+ $datatable .= '
'.
+ ''.&mt('Portfolio').': '.
+ ''.(' ' x2).
+ ''.&mt('Authoring').': '.
+ ' | ';
+ }
+ $datatable .= '';
+ $typecount ++;
+ $css_class = $typecount%2?' class="LC_odd_row"':'';
+ $datatable .= ''.&mt('LON-CAPA Advanced Users').' | '.
+ ''; + if ($context eq 'requestcourses') { + $datatable .= &mt('(overrides affiliation, if set)'). + ' '.
+ ' |
'.$text.' | '.
+ ' ';
+ my ($numdc,$table,$rows) = &active_dc_picker($dom,$numinrow,'checkbox',
+ $action.'notifyapproval',%currapp);
+ if ($numdc > 0) {
+ $datatable .= $table;
+ } else {
+ $datatable .= &mt('There are no active Domain Coordinators');
+ }
+ $datatable .=' | '.&mt('Generate unique six character code as course identifier?').' | '.
+ '';
+ foreach my $type (@crstypes) {
+ my $check = ' ';
+ if ($current{$type}) {
+ $check = ' checked="checked" ';
+ }
+ $output .= ''.(' 'x2).' ';
+ }
+ $output .= ' | '
+ .''.(' 'x2).
+ ' | '.
+ ''.
+ ''.&mt('Subject:').' '.
+ (' 'x2).
+ ''.&mt('Title:').' ';
+ if ($type eq 'textbooks') {
+ $datatable .= (' 'x2).
+ ''.&mt('Publisher:').' '.
+ (' 'x2).
+ ''.&mt('Author(s):').' '.
+ (' 'x2).
+ ''.&mt('Thumbnail:');
+ if ($image) {
+ $datatable .= $imgsrc.
+ ' '.
+ ' '.&mt('Replace:').' ';
+ }
+ if ($switchserver) {
+ $datatable .= &mt('Upload to library server: [_1]',$switchserver);
+ } else {
+ $datatable .= '';
+ }
+ }
+ $datatable .= ' '.
+ ''.&mt('LON-CAPA course:').' '.
+ $coursetitle.' | '."\n".
+ ''."\n".
+ ' '."\n".
+ ''.&mt('Add').' | '."\n".
+ ''.
+ ''.&mt('Subject:').' '."\n".
+ (' 'x2).
+ ''.&mt('Title:').' '."\n".
+ (' 'x2);
+ if ($type eq 'textbooks') {
+ $datatable .= ''.&mt('Publisher:').' '."\n".
+ (' 'x2).
+ ''.&mt('Author(s):').' '."\n".
+ (' 'x2).
+ ''.&mt('Image:').' ';
+ if ($switchserver) {
+ $datatable .= &mt('Upload to library server: [_1]',$switchserver);
+ } else {
+ $datatable .= '';
+ }
+ }
+ $datatable .= ''."\n".
+ ''.&mt('LON-CAPA course:').' '.
+ &Apache::loncommon::select_dom_form($env{'request.role.domain'},$type.'_addbook_cdom').
+ ''.
+ &Apache::loncommon::selectcourse_link
+ ('display',$type.'_addbook_cnum',$type.'_addbook_cdom',undef,undef,undef,'Course');
+ ' | '."\n".
+ ''.&mt('Auto-enrollment active?').' | '.
''.
&mt('username').': '.
' '.&mt('domain').
- ': '.$domform.' | '.&mt('Automatically assign co-ownership').' | '.
+ ' '.
+ ' | '.
+ ''.&mt('Failsafe for no drops when institutional data missing').' | '.
+ ''.
+ ' | '.&mt('Directory search available?').' | '.
+ ''.&mt('Create pending official courses from XML files').' | '.
' '.
- ' | '.
- ''.&mt('Other domains can search?').' | '.
+ ''.&mt('Yes').' '.
+ ''.
+ ''.&mt('Create pending requests for official courses (if validated)').' | '.
' '.
- ' | '.
- '';
+ if ($numdc > 1) {
+ $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)').
+ ' | ';
} else {
- $datatable .= ' | ';
}
- $datatable .= ' | '.&mt('Supported search methods').
- ' |
'.&mt('Institutional directory search available?').' | '.
+ ' '.
+ ' | '.
+ ''.&mt('Other domains can search institution?').' | '.
+ ' '.
+ ' | '.
+ ''.&mt('Supported search methods').
+ ' |
'.&mt('Search latitude').' | '.
+ ''.
+ ' '.
+ ' '.
+ ' | '.&mt('LON-CAPA directory search available?').' | '.
+ ' '.
+ ' | '.
+ ''.&mt('Other domains can search LON-CAPA domain?').' | '.
+ ' '.
+ ' | '.
+ ''.&mt('Search latitude').' | '.
- ''.
- ' '.
- ' '.
- ' | ';
- $$rowtotal ++;
return $datatable;
}
sub print_contacts {
- my ($dom,$settings,$rowtotal) = @_;
+ my ($position,$dom,$settings,$rowtotal) = @_;
my $datatable;
my @contacts = ('adminemail','supportemail');
- my (%checked,%to,%otheremails);
- my @mailings = ('errormail','packagesmail','helpdeskmail');
- foreach my $type (@mailings) {
- $otheremails{$type} = '';
+ my (%checked,%to,%otheremails,%bccemails,%includestr,%includeloc,%currfield,
+ $maxsize,$fields,$fieldtitles,$fieldoptions,$possoptions,@mailings);
+ if ($position eq 'top') {
+ if (ref($settings) eq 'HASH') {
+ foreach my $item (@contacts) {
+ if (exists($settings->{$item})) {
+ $to{$item} = $settings->{$item};
+ }
+ }
+ }
+ } elsif ($position eq 'middle') {
+ @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail',
+ 'updatesmail','idconflictsmail');
+ foreach my $type (@mailings) {
+ $otheremails{$type} = '';
+ }
+ } else {
+ @mailings = ('helpdeskmail','otherdomsmail');
+ foreach my $type (@mailings) {
+ $otheremails{$type} = '';
+ }
+ $bccemails{'helpdeskmail'} = '';
+ $bccemails{'otherdomsmail'} = '';
+ $includestr{'helpdeskmail'} = '';
+ $includestr{'otherdomsmail'} = '';
+ ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields();
}
if (ref($settings) eq 'HASH') {
+ unless ($position eq 'top') {
+ foreach my $type (@mailings) {
+ if (exists($settings->{$type})) {
+ if (ref($settings->{$type}) eq 'HASH') {
+ foreach my $item (@contacts) {
+ if ($settings->{$type}{$item}) {
+ $checked{$type}{$item} = ' checked="checked" ';
+ }
+ }
+ $otheremails{$type} = $settings->{$type}{'others'};
+ if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
+ $bccemails{$type} = $settings->{$type}{'bcc'};
+ if ($settings->{$type}{'include'} ne '') {
+ ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);
+ $includestr{$type} = &unescape($includestr{$type});
+ }
+ }
+ }
+ } elsif ($type eq 'lonstatusmail') {
+ $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
+ }
+ }
+ }
+ if ($position eq 'bottom') {
+ foreach my $type (@mailings) {
+ $bccemails{$type} = $settings->{$type}{'bcc'};
+ if ($settings->{$type}{'include'} ne '') {
+ ($includeloc{$type},$includestr{$type}) = split(/:/,$settings->{$type}{'include'},2);
+ $includestr{$type} = &unescape($includestr{$type});
+ }
+ }
+ if (ref($settings->{'helpform'}) eq 'HASH') {
+ if (ref($fields) eq 'ARRAY') {
+ foreach my $field (@{$fields}) {
+ $currfield{$field} = $settings->{'helpform'}{$field};
+ }
+ }
+ if (exists($settings->{'helpform'}{'maxsize'})) {
+ $maxsize = $settings->{'helpform'}{'maxsize'};
+ } else {
+ $maxsize = '1.0';
+ }
+ } else {
+ if (ref($fields) eq 'ARRAY') {
+ foreach my $field (@{$fields}) {
+ $currfield{$field} = 'yes';
+ }
+ }
+ $maxsize = '1.0';
+ }
+ }
+ } else {
+ if ($position eq 'top') {
+ $to{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'};
+ $to{'adminemail'} = $Apache::lonnet::perlvar{'lonAdmEMail'};
+ $checked{'errormail'}{'adminemail'} = ' checked="checked" ';
+ $checked{'packagesmail'}{'adminemail'} = ' checked="checked" ';
+ $checked{'lonstatusmail'}{'adminemail'} = ' checked="checked" ';
+ $checked{'requestsmail'}{'adminemail'} = ' checked="checked" ';
+ $checked{'updatesmail'}{'adminemail'} = ' checked="checked" ';
+ $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" ';
+ } elsif ($position eq 'bottom') {
+ $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" ';
+ $checked{'otherdomsmail'}{'supportemail'} = ' checked="checked" ';
+ if (ref($fields) eq 'ARRAY') {
+ foreach my $field (@{$fields}) {
+ $currfield{$field} = 'yes';
+ }
+ }
+ $maxsize = '1.0';
+ }
+ }
+ my ($titles,$short_titles) = &contact_titles();
+ my $rownum = 0;
+ my $css_class;
+ if ($position eq 'top') {
foreach my $item (@contacts) {
- if (exists($settings->{$item})) {
- $to{$item} = $settings->{$item};
+ $css_class = $rownum%2?' class="LC_odd_row"':'';
+ $datatable .= ''.$titles->{$item}.
+ ' | '.
+ ' | '.&mt('Extra helpdesk form fields:').' | '. + &mt('(e-mail, subject, and description always shown)'). + ' ';
+ if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') &&
+ (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) {
+ $datatable .= ' |
'.
+ $titles->{$type}.': | '.
+ '';
+ if (($type eq 'helpdeskmail') || ($type eq 'otherdomsmail')) {
+ $datatable .= ''.
+ '';
+ }
+ $datatable .= ' | $description | \n".
+ ''.
+ ''.
+ ''.
+ ' | '.$role.' | '.
+ ''. + ''.(' 'x2). + ''. + ' '.
+ &helpdeskroles_access($dom,$prefix,$num,$add_class,$current{$role},\@accesstypes,
+ $othertitle,$usertypes,$types,\%domhelpdesk).
+ ' | ';
+ $itemcount ++;
+ }
+ $css_class = $itemcount%2?' class="LC_odd_row"':'';
+ my $newcust = 'custhelp'.$count;
+ my (%privs,%levelscurrent);
+ my %full=();
+ my %levels= (
+ course => {},
+ domain => {},
+ system => {},
+ );
+ &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent);
+ my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype);
+ my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$count."_pos'".');"';
+ $datatable .= ''.
+ ' | '.
+ &helpdeskroles_access($dom,$prefix,$count,'',undef,\@accesstypes,$othertitle,
+ $usertypes,$types,\%domhelpdesk).
+ ' | '.
+ ''.$choices->{$item}.
+ ' | ';
+ if ($align eq 'left') {
+ $datatable .= '';
+ } else {
+ $datatable .= ' | ';
+ }
+ $datatable .=
+ ''.
+ ' '.
+ ''.$additional.
+ ' | '.
+ ''
+ .''.(' 'x2).
+ ' | '.
+ ''.
+ ''.
+ '';
+ my (%checkedfields,%rolemaps,$userincdom);
+ if (ref($settings->{$item}) eq 'HASH') {
+ if (ref($settings->{$item}->{'fields'}) eq 'HASH') {
+ %checkedfields = %{$settings->{$item}->{'fields'}};
+ }
+ $userincdom = $settings->{$item}->{'incdom'};
+ if (ref($settings->{$item}->{'roles'}) eq 'HASH') {
+ %rolemaps = %{$settings->{$item}->{'roles'}};
+ $checkedfields{'roles'} = 1;
+ }
+ }
+ $datatable .= ''.
+ '';
+ my %courseconfig;
+ if (ref($settings->{$item}) eq 'HASH') {
+ if (ref($settings->{$item}->{'crsconf'}) eq 'HASH') {
+ %courseconfig = %{$settings->{$item}->{'crsconf'}};
+ }
+ }
+ $datatable .= ''.
+ ' | '."\n".
+ ''."\n".
+ ' '."\n".
+ ''.&mt('Add').' | '."\n".
+ ''.
+ ''.
+ ''.
+ '';
+ $datatable .= ''.
+ ''.
+ ' | '.$titles->{$item}.
- ' | '.
- ' | '
+ .''.(' 'x2).
+ ' | '.
+ ''.
+ ''.<i_options($i,$current,$itemcount,%lt).' | '."\n".
+ ''."\n".
+ ' '."\n".
+ ''.&mt('Add').' | '."\n".
+ ''.
+ ''.<i_options('add',undef,$itemcount,%lt).
+ ' | '."\n".
+ ''.
- $titles->{$type}.': | '.
- ''.
- '';
- foreach my $item (@contacts) {
- $datatable .= ' ';
- }
- $datatable .= ' | '.&mt('Others').': '. - ''. - ' |